Перейти к содержанию
    

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
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 TI_CC_PowerupResetCCxxxx();               // Reset CCxxxx

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Во-первЫх: не все так страшно - 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.

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

 

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

 

P4OUT &= ~ECS_b; // /CS enable

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Во-вторых: 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.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Регистры "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.

Изменено пользователем Obam

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

slaa465c.pdf + slac525a.zip

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

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

Пример - Variable_LT_FIFO.

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

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

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

 

 

 

 

. . . .

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

. . . .

 

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

slaa325a.pdf

 

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

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

 

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

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

 

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

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

 

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

Изменено пользователем Obam

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

 

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...