Jump to content
    

MSP430x44x + CC1101 (SPI)

Доброго времени суток!

Есть модуль ввода/вывода с MSP430x44x и радиомодуль CC1101. Обмен данными осуществляется с помощью интерфейса SPI.

Программа написана на основе примера от Texas Instruments. Режим SPI 3-проводной, MSP430 ведущий.

Проверку на корректность результата осуществляется с помощью светодиода. Но что ни делается, все равно, в результате "0" (светодиод мигает)

Буду благодарен, если у кого-то будут идеи в чем проблема! Спасибо за внимание

int main( void )
{
  
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

  FLL_CTL0=XCAP10PF;         // Configure load caps
   
  __delay_cycles(5000);
  
  
  unsigned char answer=0x08;
  TI_CC_SPISetup();                         // Initialize SPI port
  P1DIR |= LED_OFF;                        // Port 1.7 output

  TI_CC_PowerupResetCCxxxx();               // Reset CCxxxx
  __delay_cycles(5000);
  TI_CC_SPIStrobe(TI_CCxxx0_SIDLE);         // Send strobe SIDLE
  __delay_cycles(5000);
  TI_CC_SPIWriteReg(TI_CCxxx0_ADDR, 0x0F);  //ADDR =0x0F
  __delay_cycles(5000);
  answer=TI_CC_SPIReadReg(TI_CCxxx0_ADDR);  //answer = 0x0F

  volatile unsigned int i;

  for (;;) {
    if(answer==0x00) {
      P1OUT ^= LED_OFF; // on/off P1.7
      i = 50000; // delay
      do (i--);
      while (i != 0);
    
      }
      else {
      P1OUT &= ~LED_OFF;
      
    }
  }
}

 

SPI

// Delay function. # of CPU cycles delayed is similar to "cycles". Specifically,
// it's ((cycles-15) % 6) + 15.  Not exact, but gives a sense of the real-time
// delay.  Also, if MCLK ~1MHz, "cycles" is similar to # of useconds delayed.
void TI_CC_Wait(unsigned int cycles)
{
  while(cycles>15)                          // 15 cycles consumed by overhead
    cycles = cycles - 6;                    // 6 cycles consumed each iteration
}

void TI_CC_SPISetup(void)
{
// unsigned short m;
  P4OUT |= ECS_b;
  P4DIR |= ECS_b;                           // /ExternalCS disable
  ME1 |= USPIE0;                            // Enable USART0 SPI mode
  UCTL0 = SWRST;                            // Disable USART state machine
  UCTL0 |= CHAR + SYNC + MM;                // 8-bit SPI Master **SWRST**
  UTCTL0 |= CKPH + SSEL1 + SSEL0 + STC + TXEPT;     // SMCLK, 3-pin mode
  UBR00 = 0x08;                             // UCLK/8
  UBR10 = 0x00;                             // 0
  UMCTL0 = 0x00;                            // No modulation
  P3SEL |= SPI_O | SPI_I | SPI_C;           // SPI option select
  P3DIR |= SPI_O + SPI_C;
                                            // SPI TX out direction
  UCTL0 &= ~SWRST;                          // Initialize USART state machine
}

void TI_CC_SPIWriteReg(char addr, char value)
{
  P4OUT &= ~ECS_b;                          // /ExternalCS enable
  while (!(IFG1&UTXIFG0));                  // Wait for TX to finish
  U0TXBUF = addr;                           // Send address
  while (!(IFG1&UTXIFG0));                  // Wait for TX to finish
  __no_operation();
  __no_operation();
  U0TXBUF = value;                          // Send value
  while(!(UTCTL0&TXEPT));                   // Wait for TX complete
  P4OUT |= ECS_b;                           // /ExternalCS disable
}

char TI_CC_SPIReadReg(char addr)
{
  char x;

  P4OUT &= ~ECS_b;                           // /CS enable
  while (!(IFG1 & UTXIFG0));                // Wait for TX to finish
  U0TXBUF = (addr | TI_CCxxx0_READ_SINGLE); // Send address
  while (!(IFG1 & UTXIFG0));                // Wait for TX to finish
  __no_operation();
  __no_operation();
  U0TXBUF = 0;                              // Dummy write so we can read data
  while(!(UTCTL0 & TXEPT));                 // Wait for TX complete
  x = U0RXBUF;                              // Read data
  P4OUT |= ECS_b;                           // /CS disable

  return x;
}

// For status/strobe addresses, the BURST bit selects between status registers
// and command strobes.
void TI_CC_SPIStrobe(char strobe)
{
  P4OUT &= ~ECS_b;                          // /CS enable
  while (!(IFG1 & UTXIFG0));                // Wait for TX to finish
  U0TXBUF = strobe;                         // Send strobe
  // Strobe addr is now being TX'ed
  IFG1 &= ~URXIFG0;                         // Clear flag
  while(!(UTCTL0 & TXEPT));                 // Wait for TX complete
  P4OUT |= ECS_b;                           // /CS disable
}

void TI_CC_PowerupResetCCxxxx(void)
{
  P4OUT |= ECS_b;
  TI_CC_Wait(30);
  P4OUT &= ~ECS_b;
  TI_CC_Wait(30);
  P4OUT |= ECS_b;
  TI_CC_Wait(45);

  P4OUT &= ~ECS_b;                          // /CS enable
  while (!(IFG1 & UTXIFG0));                // Wait for TX to finish
  U0TXBUF = TI_CCxxx0_SRES;                 // Send strobe
  // Strobe addr is now being TX'ed
  while(!(UTCTL0 & TXEPT));                 // Wait for TX complete
  P4OUT |= ECS_b;                           // /CS disable
}

Share this post


Link to post
Share on other sites

 TI_CC_PowerupResetCCxxxx();               // Reset CCxxxx

После этого Вам надо внимательно читать даташит , это примерно ~500 страниц. Инициализация радио отсутствует. Понимание радиосвязи тоже отсутствует. RF Studio Вам поможет на первых порах.

Share this post


Link to post
Share on other sites

Во-первЫх: не все так страшно - datasheet на cc1101 всего 105 страниц и содержит всё что нужно.

Во-вторых: SPI у трансивера с особенностью - надо дожидаться когда MISO 1-->0 (When CSn is pulled low, the MCU must wait

until CC1101 SO pin goes low before starting to transfer the header byte.), байт состояния возвращается одновременно с передачей байта заголовка.

 

Ещё:

P4OUT &= ~ECS_b; // /CS enable

while (!(IFG1 & UTXIFG0)); // Wait for TX to finish

 

в чём логика изменеия состояния CS пока не закончена передача?

 

И кстати, для отработки интерфейса более наглядны регистры PARTNUM и VERSION.

Регистры для записи доступны и на чтение, что позволяет контролировать их содержимое.

 

По поводу инициализации и организации связи - справедливо, но для начала интерфейс должен работать чётко.

 

Share this post


Link to post
Share on other sites

Проблема заключается в интерфейсе SPI. Радио не инициализируется, тк проверяю работу по SPI. Пытаюсь записать данные только в регистры радиомодуля и пока что все на этом.

По факту: данные в радиомодуль записываются верно. При считывании по SPI идет корректный байт, но функция "TI_CC_SPIReadReg" присваивает переменной значение "0".

Регистры "PARTNUM" и "VERSION" SmartRF показывает, что доступны только для чтения.

 

P4OUT &= ~ECS_b; // /CS enable

while (!(IFG1 & UTXIFG0)); // Wait for TX to finish

для того, чтобы в буфер записать актуальные данные, а не те, которые могли быть туда записаны, но не переданы

Share this post


Link to post
Share on other sites

Во-вторых: SPI у трансивера с особенностью - надо дожидаться когда MISO 1-->0 (When CSn is pulled low, the MCU must wait
until CC1101 SO pin goes low before starting to transfer the header byte.), байт состояния возвращается одновременно с передачей байта заголовка.

Вам же сказали, что надо ждать когда кварц выйдет на режим.Тогда CC1101 будет работать по SPI . И

И кстати, для отработки интерфейса более наглядны регистры PARTNUM и VERSION.

Уточните точно в даташите,чего там должно быть.

Share this post


Link to post
Share on other sites

Регистры "PARTNUM" и "VERSION" SmartRF показывает, что доступны только для чтения.

 

Это-то и полезно: в отличие от каких-либо других RO-регистров, меняющих своё содержимое в процессе работы, эти всегда должны возвращать одно и то же.

 

P4OUT &= ~ECS_b; // /CS enable

while (!(IFG1 & UTXIFG0)); // Wait for TX to finish

для того, чтобы в буфер записать актуальные данные, а не те, которые могли быть туда записаны, но не переданы

 

Это какая-то чушь: на каком основании CS может менять состояние пока полностью не завершён обмен?

 

О! Ещё вдогонку:

 

При считывании по SPI идет корректный байт, но функция "TI_CC_SPIReadReg" присваивает переменной значение "0".

 

Это как это? Осциллографом\анализатором данные "живьём" смотрите?

 

Ну и если уж занудствовать в полный рост :), то факт приема байта - это флаг URXIFG0 0 --> 1, а не TXEPT.

Edited by Obam

Share this post


Link to post
Share on other sites

Стартовать с даташита дело благородное, но тяжкое.

slaa465c.pdf + slac525a.zip

Это, правда, для CC430F5137.

Но. СС430F5137 содержит в себе, собственно, СС1101.

Пример - Variable_LT_FIFO.

Там все правильно и все работает. Если нужно будет Downgrade на 2 девайса (MSP + CC1101) - переделать ф-ии на SPI. (HAL)

RFстудия медленновать, туповата, глючновата (в терпимых пределах).

Но затенение кнопочек проработано очаровательно, а это главное.

 

 

 

 

. . . .

Программа написана на основе примера от Texas Instruments. Режим SPI 3-проводной, MSP430 ведущий.

. . . .

 

PS - а можно посмотреть на оригинал примера или ссылкна ихний slaXXXX ?

 

Share this post


Link to post
Share on other sites

PS - а можно посмотреть на оригинал примера или ссылкна ихний slaXXXX ?

slaa325a.pdf

 

Это какая-то чушь: на каком основании CS может менять состояние пока полностью не завершён обмен?

В регистр TXBUF может быть записано значение в любое время. Не имеет значение осуществляется сейчас передача по spi или будет осуществляться позже. Как только CSn становится низким, значение из TXBUF записывается в сдвиговый регистр и дальше передается по такту. Поэтому сначала ждут, когда TXBUF будет чист. К этому могут быть замечания, но в данном примере причина не в этом.

 

Это как это? Осциллографом\анализатором данные "живьём" смотрите?

Анализатором. По SPI на линии SO посылается ранее записанное в регистр значение.

 

Ну и если уж занудствовать в полный рост sm.gif, то факт приема байта - это флаг URXIFG0 0 --> 1, а не TXEPT.

Это верно, тоже обращал на это внимание. Так даже правильнее делать, но ничего не изменилось.

Share this post


Link to post
Share on other sites

В регистр TXBUF может быть записано значение в любое время.

 

НЕ МОЖЕТ и НЕ ДОЛЖНО!!! быть записано в TXBUF без CS 1-->0, ибо данные (почти) сразу пойдут по MOSI.

 

Анализатором. По SPI на линии SO посылается ранее записанное в регистр значение.

 

Так и смотрите под отдадчиком, что в RXBUF появляется. На всякий случай: может вывод у контроллера не пропаян?

Edited by Obam

Share this post


Link to post
Share on other sites

НЕ МОЖЕТ и НЕ ДОЛЖНО!!! быть записано в TXBUF без CS 1-->0, ибо данные (почти) сразу пойдут по MOSI.

Примечание: запись в UxTXBUF в режиме SPI

Запись данных в UxTXBUF, когда UTXIFGx=0 и USPIEx=1 может привести к ошибочной передаче данных.

Это из руководства по MSP430x4xx от Компэл.

 

Share this post


Link to post
Share on other sites

НЕ МОЖЕТ и НЕ ДОЛЖНО!!! быть записано в TXBUF без CS 1-->0, ибо данные (почти) сразу пойдут по MOSI.

 

 

 

Так и смотрите под отдадчиком, что в RXBUF появляется. На всякий случай: может вывод у контроллера не пропаян?

 

"НЕ МОЖЕТ и НЕ ДОЛЖНО!!!" относилось к фразе "…В регистр TXBUF может быть записано значение в любое время…" и особенно к "…в любое время…"

Share this post


Link to post
Share on other sites

SPI заработал. Проблема была в разомкнутой цепи на модуле ввода/вывода.

Всем большое спасибо за внимание к проблеме.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...