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.

MSP430I2040 EVM Serial Problem

Other Parts Discussed in Thread: MSP430I2040, CC3200

Hi, I am trying to program a CC3200 to read power measurements from the MSP430I2040 EVM.
I tried to communicate through the serial port (RS232) to the MSP430I2040 EVM that is loaded with the Out Of Box demo.

I have modified the CC3200 UART demo to send and recieve data through UARTA1 and display any results to my PC through UARTA0.
So far I am not receiving anything back from the MSP430I2040. My main thought is that I am not sending a command frame correctly and possibly calculating the checksum incorrectly. It would help to see an example of a command frame. Is it okay to send the frame one byte at a time as shown in my code? when receiving is it necessary to set up an interrupt on the receive so that i don't miss it?  Thanks

Here is my code.

//************************************************************************
// Command Frame
//************************************************************************

unsigned char ChecksumCMD = 0;
ChecksumCMD = (0x68+0x99+0x99+0x99+0x99+0x99+0x99+0x68+0x23+0x02+0x52+0x00);

UARTCharPut(UARTA1_BASE, 0x68);  //F_Start
UARTCharPut(UARTA1_BASE, 0x99);  //Address
UARTCharPut(UARTA1_BASE, 0x99);
UARTCharPut(UARTA1_BASE, 0x99);
UARTCharPut(UARTA1_BASE, 0x99);
UARTCharPut(UARTA1_BASE, 0x99);
UARTCharPut(UARTA1_BASE, 0x99);
UARTCharPut(UARTA1_BASE, 0x68);                   //F_Start
UARTCharPut(UARTA1_BASE, 0x23);                   //C_cod
UARTCharPut(UARTA1_BASE, 0x02);                   //Length
UARTCharPut(UARTA1_BASE, 0x52);                   //CMDH
UARTCharPut(UARTA1_BASE, 0x00);                   //CMDL
UARTCharPut(UARTA1_BASE, ChecksumCMD);  //Checksum
UARTCharPut(UARTA1_BASE, 0x16);                   //End

//************************************************************************
// Recieve from Power Meter
//************************************************************************

unsigned char recieveddata[34];
unsigned char recievedchar;
int i;

for (i = 0; i < 33; ++i)
{
recievedchar = UARTCharGet(UARTA1_BASE);
recieveddata[i] = recievedchar;
}

for (i = 0; i < 33; ++i)
{
UARTCharPut(UARTA0_BASE,recieveddata[i]);
}

  • Andrew,

    I don't know the functions UARTCharPut and UARTCharGet, so I don't know how they are working. In general you can, even have to send one byte at a time. It now depends on the function if your code works. If UARTCharPut has a wait function that checks if the transmit buffer is empty before writing another byte into it, then it is OK. If this check isn't integrated, then it will definitely not work because you are overwriting the previous byte again and again, never having one transmitted completely with exception of the last one.

    Same for the receive function. You are using a for-loop. If the UARTCharGet has a test-function for a received char, then it will work, otherwise you are returning the same byte over and over again. But: This method isn't a good one - on the one hand you waste a lot of time waiting for an incoming byte doing nothing. This means your program stucks in there until all 32 bytes were received and it cannot do anything else. On the other hand your program will stuck in there forever if only one byte gets lost because you won't reach the 32 anymore.

    So yes: Interrupts are made for that! So you should use them. How to set them up properly is shown in various code examples from TI. Create a receive buffer that is filled inside an ISR, setting a flag when 32 bytes were received. In addition think about timeouts for broken messages or things like that. Same for transmitting: Let interrupts send your data so your program can do other things in between the slow UART communication.

    Dennis

  • Thank you Dennis,

    The uart functions are directly from the CC3200 SDK uart_demo. They do wait for space to send and wait until a byte is received, I will post them below. You are correct about my method for receiving, I will modify this to show me any single byte that is received without waiting for the rest of the frame since at this stage I just wanted to prove that i could communicate with the MSP430I2040.

    In a datasheet for the MSP430I2040 EVM (SLAA638) the end of frame and checksum are described; "The end of the frame is a check sum byte, which is a modulus 256 byte sum of each byte from the beginning of the header to the end of the data field followed by an end of frame marker 0x16." Am I calculating this correctly? For the frame I tried to send I calculated the checksum as follows;

    unsigned char ChecksumCMD = 0;
    ChecksumCMD = (0x68+0x99+0x99+0x99+0x99+0x99+0x99+0x68+0x23+0x02+0x52+0x00);
    //This takes the lowest byte of the addition which should be the same as doing the modulus as below,

    unsigned int Checksum2CMD = 0;
    Checksum2CMD = (0x68+0x99+0x99+0x99+0x99+0x99+0x99+0x68+0x23+0x02+0x52+0x00)%256;

    Here are the UART functions

    //*****************************************************************************
    void
    UARTCharPut(unsigned long ulBase, unsigned char ucData)
    {
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Wait until space is available.
    //
    while(HWREG(ulBase + UART_O_FR) & UART_FR_TXFF)
    {
    }

    //
    // Send the char.
    //
    HWREG(ulBase + UART_O_DR) = ucData;
    }

    //*****************************************************************************
    long
    UARTCharGet(unsigned long ulBase)
    {
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Wait until a char is available.
    //
    while(HWREG(ulBase + UART_O_FR) & UART_FR_RXFE)
    {
    }

    //
    // Now get the char.
    //
    return(HWREG(ulBase + UART_O_DR));
    }

    //*****************************************************************************
  • A modulo 256 checksum is just adding all values together, storing the result into a 8 bit variable. The overflow does the rest for you.

    So you should check if

    UARTCharPut(UARTA1_BASE, 0x68); 104
    UARTCharPut(UARTA1_BASE, 0x99); 104 + 153 = 257 -> 1
    UARTCharPut(UARTA1_BASE, 0x99); 1   + 153 = 154
    UARTCharPut(UARTA1_BASE, 0x99); 154 + 153 = 307 -> 51
    UARTCharPut(UARTA1_BASE, 0x99); 51  + 153 = 204
    UARTCharPut(UARTA1_BASE, 0x99); 204 + 153 = 357 -> 101
    UARTCharPut(UARTA1_BASE, 0x99); 101 + 153 = 254
    UARTCharPut(UARTA1_BASE, 0x68); 254 + 104 = 358 -> 102
    UARTCharPut(UARTA1_BASE, 0x23); 102 + 35  = 137
    UARTCharPut(UARTA1_BASE, 0x02); 137 + 2   = 139
    UARTCharPut(UARTA1_BASE, 0x52); 139 + 82  = 221
    UARTCharPut(UARTA1_BASE, 0x00); 221 + 0   = 221

    results in

    Checksum2CMD = 221

    (I hope I didn't do a mistake)

    Your functions look like they are waiting for something, yes, although I don't know this style of register access

    while( HWREG(ulBase + UART_O_FR) & UART_FR_TXFF ) {}

    So does this one

    while( HWREG(ulBase + UART_O_FR) & UART_FR_RXFE ) {}

    mean it is waiting for the RX-flag to be set?

    Dennis

    Dennis

  • That is the correct checksum, I get the same value through both methods.
    I actually managed to find the solution to this problem. I cant see it mentioned in the Datasheet but the MSP430I2040 EVM uses the Data Terminal Ready pin of RS232 (pin4) for flow control. I discovered this by wiring in my own connectors and removing handshaking wires until I found what it was using. All it requires is for the DTR pin to be asserted high, that is between 5-12v for RS232. This allowed the device to send replies.

    Thank you for your suggestions, I will work on setting up my interrupts properly next.

**Attention** This is a public forum