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.

Interfacing MSP430AFE253 and MSP430F1611 using USART in UART mode

Other Parts Discussed in Thread: MSP430AFE253, MSP430F1611

Hi,

First of all, I apologize for the mistakes I could make, my english is not perfect.

I'm an engineering student and I'm getting started with the MSP430 family of MCUs. My goal is to do energy metering using the MSP430AFE253 MCU and to send the collected data via the USART interface in UART mode to a TelosB platform running Contiki OS which is actually using a MSP430F1611 MCU.

My first step in this project was to try sending random data from the AFE253 to the MSP430F1611, a really easy 8bit data exchange . To do so I downloaded the example code packages for both MCUs and wrote a similar code to initialize and communicate. 

Here's the code running on the MSP430AFE253 (which is basically the provided example code for UART @115200 baud rate + 2 lines to turn on a LED when the program reaches the interrupt) : 

#include "msp430afe253.h"


//******************************************************************************
int isRxIntrPending(){

if (IFG1 & URXIFG0){
IFG1 &= ~URXIFG0;
return 1;
}
return 0;
}
//******************************************************************************


void main(void)
{
volatile unsigned int i;

WDTCTL = WDTPW + WDTHOLD;              // Stop WDT
P1SEL |= BIT3+BIT4;                                     // P1.3,1.4 = USART0 TXD/RXD


do
{
IFG1 &= ~OFIFG;                                            // Clear OSCFault flag
for (i = 0x47FF; i > 0; i--);                               // Time for flag to set
}
while ((IFG1 & OFIFG));                                // OSCFault flag still set?

ME1 |= UTXE0 + URXE0;                          // Enable USART0 TXD/RXD
U0CTL |= CHAR;                                        // 8-bit character
U0TCTL |= SSEL1;                                    // UCLK= SMCLK
U0BR0 = 10;                                               // 1MHz 115200
U0BR1 = 0x00;                                          // 1MHz 115200
U0MCTL = 0x00;                                       // 1MHz 115200 modulation
U0CTL &= ~SWRST;                               // Initialize USART state machine
IE1 |= URXIE0;                                         // Enable USART0 RX interrupt
P1SEL2 |= BIT0;                                      // Set SMCLK at P1.0


if(isRxIntrPending()){
           _BIS_SR(GIE);                         // General Interrupt Enable set high
            IE1 |= BIT6;                             //Enter RX interrupt
}


}

#pragma vector=USART0RX_VECTOR
__interrupt void USART0_RX (void)
{
P1OUT |= 0x02;
P1DIR |= 0x02;
while (!(IFG1 & UTXIFG0));                             // USART0 TX buffer ready?
TXBUF0 = RXBUF0;                                       // RXBUF0 to TXBUF0
}

This code has been uploaded using the FET430UIF debugger and CCSv5.

Here's the code for the MSP430F1611 :

void
uart0_init(void)
{
/* Initalize ports for UART communication. */

U0CTL = CHAR + SWRST;                       /* SW reset,8-bit transfer, SPI master */
U0TCTL = BIT5;                                /* BRCLK = SMCLK = 800kHz */

U0BR0 = 0x07;                                   /* set baud rate. 800kHz 115200*/
U0BR1 = 0;
U0MCTL = 0;                                      /* Don't need modulation control. */

P3SEL |= BIT4 + BIT5;                    /* Select Peripheral functionality for 3.4 and 3.5 */
P3DIR |= BIT4  ;                                 /* Configure TX as output. */

ME1 |= BIT6 + BIT7;                 /* Enable RX et TX*/
U0CTL &= ~SWRST;                   /* Remove RESET */
}

/*---------------------------------------------------------------------------*/
PROCESS(uart, "UART process");
AUTOSTART_PROCESSES(&uart);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(uart, ev, data)
{
PROCESS_BEGIN();

uart0_init();
U0TXBUF = 0x01;

//printf("Process Ending\n");

PROCESS_END();
}

I just try to start a transmission by writing in U0TXBUF. Don't judge me if this seems stupid to you, as I told you i'm a student and still learning :)

The PROCESS_BEGIN and PROCESS_END could be assimilated to a void main() function. 

Well, the Contiki part is quite new to me as well. That operating system has been ported to the MSP430 MCUs as far as I know. It seemed to be straight forward since the drivers and librairies were already available so I just wrote the same code I would have written using CCSv5 or IAR.

To sum up, I try to send 0x01 and that turns on the LED I use in the first code which means I receive something. Well the value I receive changes everytime I run the code. Besides, when I echo what I received I check on the RXBUF of the MSP430F1611 and all i get is 0x40. That makes no sense to me and I can't figure out what's wrong.

I don't know yet if the problem comes from the code itself or from the the fact I'm trying to run it using Contiki.

All your tips, advices and ideas are welcome ! :)

Thanks a lot,

T.HOROZIAN

  • First thing that looks suspicious is the baudrate. A Baudrat emismatch would explain your observations.

    On the AFE, you don't set any clocks. That means the AFE runs on, well, an unknown clock speed, It is typically somewhere around 1.15MHz, but range is +-40%.
    The AFE has calibraiton values for 8MHz and 12MHz, whose precision is  +-6% over temperature and supply voltage range.

    If the AFE would run on exactly 1.152MHz, the used baudrate divider of 10 would be perfect. However, with an unknown clock speed, the baudrate divider to use is also unknwon, and in your case, the real baudrate could be somewhere between 70kBd and 160kBd

    On the 1611, which I use personally in a lot of projects, the default clock rate can be a low as 650kHz.  (The datasheets lists 750kHz as typical, ranging from 610 to 900kHz)

    As a first quick hack, you may enable the SMCLK output on a port pin, measure it and recalculate the baudrate dividers. (Since this is part specific, it must be done for each MSP, even of the same kind)

    For mass production, crystals should be used to provide a stable and precise clock base.

  • Hi,

    Thank you for your fast answer.

    What do you mean by "On the AFE you don't set any clocks" ? As far as I understood,     U0TCTL |= SSEL1;     // UCLK= SMCLK    this instruction was supposed to select the sub main clock as the source clock which is supposed to be around 1.1Mhz. I took this code from the example code in the file named "MSP430AFE_uart_115k.c" provided by TI.

    However, I didn't know about the +/- 40% range of the clock. I'll double check the actual speed and let you know :)

    T.HOROZIAN 

  • Tigran Horozian said:
    As far as I understood,     U0TCTL |= SSEL1;     // UCLK= SMCLK

    Yes, but what is SMCLK? The default power-on value is the current DCO speed. But the default DCO frequency is only known in a rather wide range.

    Tigran Horozian said:
    which is supposed to be around 1.1Mhz.

    'around' is +-40%. See the device datasheet. 1.1MHz is a typical but by far not a guaranteed value. The 'DCO frequency' chapter in the datasheet shows typical (and for some combinations min/max, from where I extrapolated the +-40%) clock frequencies for some DCOx/RSELx settings.

    Keep in mind that UART only allows an error of +-5%, and this is for combined sender and receiver error. Beyond this, you may get framing errors or shifted/skipped bits.

  • You were right, the problem came from the baudrate, I switched to an external osc with a 8Mhz frequency and assigned it to SMCLK. I checked SMCLK on P1.0 and had the correct frequency. I noticed that there is a misprint in the User's guide page 505. The SSELx bits to select SMCLK are 11 not 10 as printed in the datasheet.

    Thanks for your help ! :)

  • Tigran Horozian said:
    The SSELx bits to select SMCLK are 11 not 10 as printed in the datasheet.

    Actually both select SMCLK. The internal logic uses the higher bit to select whether SMCLK or not and the lower to switch between ACLK and external, if not SMCLK.

**Attention** This is a public forum