This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC430 packet reception and UART connection problem

Other Parts Discussed in Thread: CC430F5137, CC1101

Hi, I try to use a CC430F5137 as a receiver which forwards the received data to a PC via a UART connection.
The CC430 is permanently in Rx-state waiting for incoming packets (up to 5 bytes). When a valid packet is detected (RFIFG9 + CRC_OK) the received data is written to a ringbuffer. To forward the data to the PC a Matlab-script is polling every two seconds by sending an'a' to the CC430.
My code works fine for some time (minutes to hours) till it fails.
Then either the CC430 stops receiving data, but the UART connection still works or the UART connection fails, so in Matlab there always occurs a timeout when data should be received.
For debugging I implemented the blinking of a led in the main() function. When I tried to debug the code (in the condition where the CC430 stopped receiving) I asserted that the direction of the led port was changed form output to input, which I can't explain.
I also implemented a watchdog timer (source XT2 interval 83 sec) which is reset when data is received either via the RF link or the UART connection. But the watchdog doesn't reset the CC430 when the UART connection fails. In this condition the led also stops blinking, so I the the watchdog timer isn't reset in the CC1101_ISR either. I also put a breakepoint in the main()-while loop when the failure of the UART connection occured which was never reached.

Can anybody tell me what's my problem?
Why does the reception of data via the Radio module or the UART connection fail at all?
And why does the CC430 behave like it does in the case of a faliure?

Thanks in advance.

#include <msp430.h>
#include <RF1A.h>

#define MAX_TX_PACKET_LEN     (500)
#define MAX_RX_PACKET_LEN     (55)
#define RINGBUF_SIZE          (252)
#define CRC_OK                (BIT7)
#define SUCCESS               (0)
#define EVENT                 (1)

#define MIN(n,m) (((n) < (m)) ? (n) : (m))

void ReadData(void);
void SendData(void);
void InitTimer(void);
void InitRadio(void);
void InitUart(void);
unsigned char ringbufferIn(unsigned char byte);
unsigned char ringbufferOut(unsigned char *buffer);

extern RF_SETTINGS rfSettings;

unsigned char read_data = 0;
unsigned char senddata = 0;
unsigned char ringbuffer[RINGBUF_SIZE];
unsigned int  write = 0;
unsigned int  read = 0;
unsigned char ringbuffull = 0;
unsigned long count = 0;

int main(void) {
  WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

  PMMCTL0 = PMMPW + PMMCOREV_3;

  P1OUT &= BIT0;
  P1DIR |= BIT0;

  InitRadio();
  InitTimer();
  InitUart();

  // Select ACLK as WDT clock, clear WDT counter and set WDT interval to 2^31/clock source ~ 83s
  WDTCTL = WDTPW | WDTSSEL__ACLK | WDTCNTCL | WDTIS_0;

  RF1AIES |= BIT9;                          // select negative edge for end of packet interrupt
  RF1AIFG = 0;                              // Clear pending RFIFG interrupts
  RF1AIE  |= BIT9;                          // Enable end of packet interrupt

  Strobe(RF_SIDLE);
  Strobe(RF_SRX);

  __enable_interrupt();

  while(1)
  {
    count++;
    if(count > 400000)
    {
      P1OUT ^= BIT0;
      count = 0;
    }
    if(read_data)
    {
      ReadData();
    }
    if(senddata)
    {
      SendData();
    }
  }

}

void ReadData(void)
{
  unsigned char RxBuffer[MAX_RX_PACKET_LEN+2] = {0};   // +2 for status bytes
  unsigned char RxBufferLength;
  unsigned char i;

  RF1AIFG &= 0;                             // Clear pending IFG

    RxBufferLength = ReadSingleReg( RXBYTES );
    ReadBurstReg(RF_RXFIFORD, RxBuffer, RxBufferLength);
//    RSSI_index = RxBufferLength-2;

    if(RxBuffer[RxBufferLength - 1] & CRC_OK)
    {
      for (i=1; i < RxBufferLength-2; i++)
      {
        ringbufferIn(RxBuffer[i]);
        if((i % 5) == 0)
          {
            ringbufferIn(0xFF);
          }
      }
    }

    read_data = 0;
    Strobe( RF_SIDLE );
    Strobe( RF_SFRX  );
    Strobe( RF_SRX   );
}

void SendData(void)
{
  unsigned int  bytes_in_ring_buffer = 0;
  unsigned char tx_count = 0;
  unsigned char txBuffer;

  if(read != write || (read == write && ringbuffull))
  {
    if(read < write)
    {
      bytes_in_ring_buffer = write - read;
    }
    else
    {
      bytes_in_ring_buffer = RINGBUF_SIZE + write - read;
    }
    tx_count = MIN(bytes_in_ring_buffer, MAX_TX_PACKET_LEN);
    while (!(UCA0IFG&UCTXIFG));               // USCI_A0 TX buffer ready?
    UCA0TXBUF = tx_count;
    while(tx_count)
    {
      while (!(UCA0IFG&UCTXIFG));             // USCI_A0 TX buffer ready?
      __delay_cycles(5000);
      ringbufferOut(&txBuffer);
      tx_count--;
      UCA0TXBUF = txBuffer;
    }
  }
  else
  {
    while (!(UCA0IFG&UCTXIFG));               // USCI_A0 TX buffer ready?
    UCA0TXBUF = 0x01;
    __delay_cycles(5000);
    while (!(UCA0IFG&UCTXIFG));               // USCI_A0 TX buffer ready?
    UCA0TXBUF = 0x00;
  }

  senddata = 0;
}

void InitTimer(void)
{
  UCSCTL6 &= ~XT2OFF;
  UCSCTL3 |= SELREF_2;

  UCSCTL4 = SELA__REFOCLK + SELS__DCOCLKDIV + SELM__DCOCLKDIV;
  do
  {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
    SFRIFG1 &= ~OFIFG;
  }while (SFRIFG1&OFIFG);

  UCSCTL4 |= SELA__XT2CLK + SELS__XT2CLK + SELM__XT2CLK;
  UCSCTL5 |= DIVS_1;
}

void InitRadio(void)
{
WriteRfSettings(&rfSettings);
}

void InitUart(void)
{
  PMAPPWD = 0x02D52;                        // Get write-access to port mapping regs
  P1MAP5 = PM_UCA0RXD;                      // Map UCA0RXD output to P1.5
  P1MAP6 = PM_UCA0TXD;                      // Map UCA0TXD output to P1.6
  PMAPPWD = 0;                              // Lock port mapping registers

  P1DIR |= BIT6;                            // Set P1.6 as TX output
  P1SEL |= BIT5 + BIT6;                     // Select P1.5 & P1.6 to UART function

  UCA0CTL1 |= UCSWRST;                      // **Put state machine in reset**
  UCA0CTL1 |= UCSSEL_2;                     // SMCLK
  UCA0BR0 = 112;                            // 26MHz 115200
  UCA0BR1 = 0;                              // 26MHz 115200
  UCA0MCTL |= UCBRS_7 + UCBRF_0;            // Modulation UCBRSx=7, UCBRFx=0
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  UCA0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt
}

unsigned char ringbufferIn(unsigned char byte)
{
  unsigned char retval = SUCCESS;

  if (ringbuffull)
  {
    read++;
    if(read >= RINGBUF_SIZE)
    {
      read = 0;
    }
    retval = EVENT;
  }

  ringbuffer[write] = byte;

  write++;
  if (write >= RINGBUF_SIZE)
  {
    write = 0;
  }

  if(write == read)
  {
    ringbuffull = 1;
  }

  return retval;
}

unsigned char ringbufferOut(unsigned char *buffer)
{

  if (((read == write) && !ringbuffull))
    return EVENT;

  *buffer = ringbuffer[read];
  read++;
  if (read >= RINGBUF_SIZE)
  {
    read = 0;
  }
  if(read == write)
  {
    ringbuffull = 0;
    P1OUT &= ~BIT0;
  }

  return SUCCESS;
}

#pragma vector=CC1101_VECTOR
__interrupt void CC1101_ISR(void)
{
  switch(__even_in_range(RF1AIV,32))        // Prioritizing Radio Core Interrupt
  {
    case  0: break;                         // No RF core interrupt pending
    case  2: break;                         // RFIFG0
    case  4: break;                         // RFIFG1
    case  6: break;                         // RFIFG2
    case  8: break;                         // RFIFG3
    case 10: break;                         // RFIFG4
    case 12: break;                         // RFIFG5
    case 14: break;                         // RFIFG6
    case 16: break;                         // RFIFG7
    case 18: break;                         // RFIFG8
    case 20:                                // RFIFG9
      read_data = 1;
      WDTCTL = WDTPW | WDTCNTCL;
      break;
    case 22: break;                         // RFIFG10
    case 24: break;                         // RFIFG11
    case 26: break;                         // RFIFG12
    case 28: break;                         // RFIFG13
    case 30: break;                         // RFIFG14
    case 32: break;                         // RFIFG15
  }
}

#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
  switch(__even_in_range(UCA0IV,4))
  {
  case 0:break;
  case 2:
    if (UCA0RXBUF == 0x61)
    {
      senddata = 1;
      WDTCTL = WDTPW | WDTCNTCL;
    }
    break;
  case 4:break;
  default: break;
  }
}

  • Some advice:

    - Clear the interrupt flags in the ISRs
    - Make sure you handle error conditions (error from radio)

  • Thank you for the advice.

    I enabeld the radio interface error interrupt by setting

    RF1AIFCTL1 |= RFERRIE;

    I added the handling of RF1AIFERRV to CC1101_ISR(), but RF1AIFERR never triggered an interrupt and I still get the two kinds of failure I described.

    By the way, when only the reception of data fails, I'm still able to suspend the execution of the programm, but when the UART connection fails I get the error 'No source available for "0x0" ' when I try to suspend the programm.