Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: MSP430x44x + CC1101 (SPI)
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
leningrib
Доброго времени суток!
Есть модуль ввода/вывода с 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
}
mcheb
Код
TI_CC_PowerupResetCCxxxx();               // Reset CCxxxx

После этого Вам надо внимательно читать даташит , это примерно ~500 страниц. Инициализация радио отсутствует. Понимание радиосвязи тоже отсутствует. RF Studio Вам поможет на первых порах.
Obam
Во-первЫх: не все так страшно - 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.
Регистры для записи доступны и на чтение, что позволяет контролировать их содержимое.

По поводу инициализации и организации связи - справедливо, но для начала интерфейс должен работать чётко.
leningrib
Проблема заключается в интерфейсе SPI. Радио не инициализируется, тк проверяю работу по SPI. Пытаюсь записать данные только в регистры радиомодуля и пока что все на этом.
По факту: данные в радиомодуль записываются верно. При считывании по SPI идет корректный байт, но функция "TI_CC_SPIReadReg" присваивает переменной значение "0".
Регистры "PARTNUM" и "VERSION" SmartRF показывает, что доступны только для чтения.

P4OUT &= ~ECS_b; // /CS enable
while (!(IFG1 & UTXIFG0)); // Wait for TX to finish
для того, чтобы в буфер записать актуальные данные, а не те, которые могли быть туда записаны, но не переданы
mcheb
Код
Во-вторых: 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.

Уточните точно в даташите,чего там должно быть.
Obam
Цитата(leningrib @ Apr 28 2015, 17:27) *
Регистры "PARTNUM" и "VERSION" SmartRF показывает, что доступны только для чтения.


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

Цитата
P4OUT &= ~ECS_b; // /CS enable
while (!(IFG1 & UTXIFG0)); // Wait for TX to finish
для того, чтобы в буфер записать актуальные данные, а не те, которые могли быть туда записаны, но не переданы


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

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

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


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

Ну и если уж занудствовать в полный рост sm.gif, то факт приема байта - это флаг URXIFG0 0 --> 1, а не TXEPT.
k155la3
Стартовать с даташита дело благородное, но тяжкое.
slaa465c.pdf + slac525a.zip
Это, правда, для CC430F5137.
Но. СС430F5137 содержит в себе, собственно, СС1101.
Пример - Variable_LT_FIFO.
Там все правильно и все работает. Если нужно будет Downgrade на 2 девайса (MSP + CC1101) - переделать ф-ии на SPI. (HAL)
RFстудия медленновать, туповата, глючновата (в терпимых пределах).
Но затенение кнопочек проработано очаровательно, а это главное.




Цитата(leningrib @ Apr 27 2015, 18:23) *
. . . .
Программа написана на основе примера от Texas Instruments. Режим SPI 3-проводной, MSP430 ведущий.
. . . .


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

slaa325a.pdf

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

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

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

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

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

Это верно, тоже обращал на это внимание. Так даже правильнее делать, но ничего не изменилось.
Obam
Цитата(leningrib @ Apr 30 2015, 01:42) *
В регистр TXBUF может быть записано значение в любое время.


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

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


Так и смотрите под отдадчиком, что в RXBUF появляется. На всякий случай: может вывод у контроллера не пропаян?
leningrib
Цитата
НЕ МОЖЕТ и НЕ ДОЛЖНО!!! быть записано в TXBUF без CS 1-->0, ибо данные (почти) сразу пойдут по MOSI.

Примечание: запись в UxTXBUF в режиме SPI
Запись данных в UxTXBUF, когда UTXIFGx=0 и USPIEx=1 может привести к ошибочной передаче данных.
Это из руководства по MSP430x4xx от Компэл.
Obam
Цитата(Obam @ Apr 30 2015, 10:46) *
НЕ МОЖЕТ и НЕ ДОЛЖНО!!! быть записано в TXBUF без CS 1-->0, ибо данные (почти) сразу пойдут по MOSI.



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


"НЕ МОЖЕТ и НЕ ДОЛЖНО!!!" относилось к фразе "…В регистр TXBUF может быть записано значение в любое время…" и особенно к "…в любое время…"
leningrib
SPI заработал. Проблема была в разомкнутой цепи на модуле ввода/вывода.
Всем большое спасибо за внимание к проблеме.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.