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.

LAUNCHXL-F28069M: Simple UART Receiving Program Problem.

Part Number: LAUNCHXL-F28069M
Other Parts Discussed in Thread: MSP430F5529

Hello! 

I'm trying to set-up a simple UART program which stores data sent to the C2000 into an array. I posted a similar question earlier, but I found I had with the answer! I revised my code and cleared-up some things.

Here's some functionality requirements:

- 9600 BAUD

- CPU-Interrupt when a message is received (RXBUF has a byte)

- Infrequent messages

- The messages will compose of 1-2 words such as 'Route 1', or 'Go' or 'Stop'.

- The C2000 will be interfaced to an HC06 which will receive data over bluetooth sent from an app. This has been tested and confirmed working on the MSP430F5529 @ 9600 BAUD

I've gone through the two example projects, but I've had some trouble with this application.

I have the TX of the HC06 going into Pin 3, which, if I understand correctly, is J1.3 which is also GPIO28 when the jumpers are shorting JP6 & JP7, is this right?

Here's my code for SCI (I know theres no includes and what not, this is because its part of a bigger project which has timers, epwm, ecap, etc.):

__interrupt void sciaRxFifoIsr(void);

volatile unsigned char RXParseData[256] = {}; // Array which stores the data received in RXBUF

void main(void)

{

//--- CPU Initialization
InitSysCtrl(); // Initialize the CPU (FILE: SysCtrl.c)

InitPieCtrl(); // Initialize and enable the PIE (FILE: PieCtrl.c)
InitWatchdog(); // Initialize the Watchdog Timer (FILE: WatchDog.c)

//---- SCI -- SETUP
EALLOW;

/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled disabled by the user.
// This will enable the pullups for the specified pins.

GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0; // Enable pull-up for GPIO28 (SCIRXDA)

/* Set qualification for selected pins to asynch only */
// Inputs are synchronized to SYSCLKOUT by default.
// This will select asynch (no qualification) for the selected pins.

GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3; // Asynch input GPIO28 (SCIRXDA)

/* Configure SCI-A pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be SCI functional pins.

GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1; // Configure GPIO28 for SCIRXDA operation

EDIS;

// END SCI SETUP

// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;

// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the F2806x_PieCtrl.c file.
InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in F2806x_DefaultIsr.c.
// This function is found in F2806x_PieVect.c.
InitPieVectTable();

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.SCIRXINTA = &sciaRxFifoIsr;
EDIS; // This is needed to disable write to EALLOW protected registers

//FIFO SETUP
SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol

SciaRegs.SCICTL1.all =0x0001; // enable RX, internal SCICLK,
// Disable TX, RX ERR, SLEEP, TXWAKE
SciaRegs.SCICTL2.bit.RXBKINTENA =1;
SciaRegs.SCIHBAUD = 0x0000;
SciaRegs.SCILBAUD = 0x00C2; // 9600 BAUD -> Found in the common baud rates, BRR = 0xC2 or 194 (in decimal)

SciaRegs.SCIFFRX.all=0x0022;
SciaRegs.SCIFFCT.all=0x00;

SciaRegs.SCICTL1.all =0x0021; // Relinquish SCI from Reset
SciaRegs.SCIFFRX.bit.RXFIFORESET=1;

// Enable interrupts required for this example
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
PieCtrlRegs.PIEIER9.bit.INTx1=1; // PIE Group 9, INT1
PieCtrlRegs.PIEIER9.bit.INTx2=1; // PIE Group 9, INT2
IER = 0x100; // Enable CPU INT
EINT;

//--- Enable global interrupts
asm(" CLRC INTM, DBGM"); // Enable global interrupts and realtime debug

}

__interrupt void sciaRxFifoIsr(void)
{
Uint16 i = 0;
for(i=0;i<2;i++)
{
RXParseData[i]=SciaRegs.SCIRXBUF.all; // Read data

}

while (i != NULL)
{
RXParseData[i]=SciaRegs.SCIRXBUF.all; // Read data  ------------->The first characters ascii code doesnt match with whats being received. ie. 'S' in 'STOP' ended up being 0x87
i++; ///---------------------------------------------------------------------------------> i is incrementing forever
}

SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear Overflow flag
SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag

PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack
}

Just as a last note, when I changed the BAUD rate, I noticed RXBUF had different values in it. I believe I'm running at 90MHz (maybe Im not and thats the problem? How could I confirm this?). And I had this working on the MSP430, so the bluetooth module is fine! 

Thanks!

  • When you change the baud rate, the SCI will interpret the characters at that baud rate. This is likely why the characters are different.

    You need to configure your baud rate based on LSPCLK which is relative to SYSCLK.

    Regards,
    sal
  • Yes, I understand that. I believe I am running at 90MHz, and the code above is configured for 9600 BAUD. How could I confirm that I'm running at 90MHz? And if I find out i'm not at 90MHz, could you direct me to the guide of setting my chip to run at 90MHz, as i'm not dividing down my SYSCLK clock for  the LSPCLK.

    Also, would an innaccurate clock mess up the NULL thats being sent? In my ISR I'm getting stuck forever (while i != NULL).

  • Hi Andrew,

    Please see the TRM and Section 1 - System Controls and Interrupts.

    F2806x has an XCLKOUT feature in which you can drive an external GPIO pin with SYSCLK.

    Figure 1-42 in section 1.4.2.11 demonstrates this.

    Regards,
    sal
  • Will do! Would an innaccurate clock mess up the NULL thats being sent? In my ISR I'm getting stuck forever (while i != NULL).
  • Yes. All characters would likely be corrupted.

    sal
  • Hey Sal!

    I hate to be a hassle, but I'm very busy with school and I had a good look at the register configuration to output sysclk to a pin, but it seems like a bit of a hassle to get that working just to test the frequency of the clock. Is the default frequency 90MHz?

    The only thing I've done which might be changing the frequency is in my timer setup that I pulled from an example project:

    // Configure CPU-Timer 0 to interrupt:
    // 80MHz CPU Freq, 1 second Period (in uSeconds)
    ConfigCpuTimer(&CpuTimer0, 80, 100000); //100ms

    void ConfigCpuTimer(struct CPUTIMER_VARS *Timer, float Freq, float Period)
    {
    Uint32 PeriodInClocks;

    // Initialize timer period:
    Timer->CPUFreqInMHz = Freq;
    Timer->PeriodInUSec = Period;
    PeriodInClocks = (long) (Freq * Period);
    Timer->RegsAddr->PRD.all = PeriodInClocks - 1; // Counter decrements PRD+1 times each period

    // Set pre-scale counter to divide by 1 (SYSCLKOUT):
    Timer->RegsAddr->TPR.all = 0;
    Timer->RegsAddr->TPRH.all = 0;

    // Initialize timer control register:
    Timer->RegsAddr->TCR.bit.TSS = 1; // 1 = Stop timer, 0 = Start/Restart Timer
    Timer->RegsAddr->TCR.bit.TRB = 1; // 1 = reload timer
    Timer->RegsAddr->TCR.bit.SOFT = 1; 
    Timer->RegsAddr->TCR.bit.FREE = 0; // Timer Free Run Disabled
    Timer->RegsAddr->TCR.bit.TIE = 1; // 0 = Disable/ 1 = Enable Timer Interrupt

    // Reset interrupt counter:
    Timer->InterruptCount = 0;

    }

    Does this mean i'm at 80MHz?

  • The only thing that function is touching is CPU Timer registers. This will not effect the CPU or SYSCLK frequency.

    By default, I believe LSPCLK is SYSCLK/4. Your device should be running at 90MHz, that is what our examples are set to configure by default.

    Regards,
    sal
  • Alright cool! Thats what I was thinking. If this is the case, then I believe my configuration is correct.

    I think I see the problem!

    In the reference guide (13.1.1.9) it says LSPCLK is 15MHz, and I'd be running at the default 22.5MHz?

    The register values should be:

    ScibRegs.SCIHBAUD = 0x0000;
    ScibRegs.SCILBAUD = 0x0123; //9600 baud

    using: 22500000/(9600*8) - 1

  • It should be 22.5MHz. I believe the default is SYSCLK / 4.

    sal
  • Hey Sal, sorry for my incompetence, but I've set up my code as such, and I'm not receiving anything in my ISR which moves the value in the receive buffer to an array. Although, I am getting interrupted and getting into the ISR Do you think you see a mistake?

    I've tried a fair few BAUD rates, Ive had this working on the MSP430 at 9600 BAUD, I just dont see why this isn't working.

    __interrupt void sciaRxFifoIsr(void);
    char RXParseData[256] = {}; // Array which stores the data received in RXBUF

    void main(void)

    {

    //--- CPU Initialization
    InitSysCtrl(); // Initialize the CPU (FILE: SysCtrl.c)

    InitPieCtrl(); // Initialize and enable the PIE (FILE: PieCtrl.c)
    InitWatchdog(); // Initialize the Watchdog Timer (FILE: WatchDog.c)

    //---- SCI -- SETUP
    EALLOW;

    /* Enable internal pull-up for the selected pins */
    // Pull-ups can be enabled or disabled disabled by the user.
    // This will enable the pullups for the specified pins.

    GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0; // Enable pull-up for GPIO28 (SCIRXDA)

    /* Set qualification for selected pins to asynch only */
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.

    GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3; // Asynch input GPIO28 (SCIRXDA)


    /* Configure SCI-A pins using GPIO regs*/
    // This specifies which of the possible GPIO pins will be SCI functional pins.

    GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1; // Configure GPIO28 for SCIRXDA operation

    EDIS;

    // END SCI SETUP

    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    DINT;

    // Initialize PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the F2806x_PieCtrl.c file.
    InitPieCtrl();

    // Disable CPU interrupts and clear all CPU interrupt flags:
    IER = 0x0000;
    IFR = 0x0000;

    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example. This is useful for debug purposes.
    // The shell ISR routines are found in F2806x_DefaultIsr.c.
    // This function is found in F2806x_PieVect.c.
    InitPieVectTable();

    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    EALLOW; // This is needed to write to EALLOW protected registers
    PieVectTable.SCIRXINTA = &sciaRxFifoIsr;
    EDIS; // This is needed to disable write to EALLOW protected registers

    //FIFO SETUP
    SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
    // No parity,8 char bits,
    // async mode, idle-line protocol

    SciaRegs.SCICTL1.all =0x0001; // enable RX, internal SCICLK,
    // Disable TX, RX ERR, SLEEP, TXWAKE
    SciaRegs.SCICTL2.bit.RXBKINTENA =1;
    SciaRegs.SCIHBAUD = 0x0000;
    SciaRegs.SCILBAUD = 0x0492; // 9600 BAUD, ive also tried 0x0123.

    SciaRegs.SCIFFRX.all=0x0022;
    SciaRegs.SCIFFCT.all=0x00;

    SciaRegs.SCICTL1.all =0x0021; // Relinquish SCI from Reset
    SciaRegs.SCIFFRX.bit.RXFIFORESET=1;

    // Enable interrupts required for this example
    PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
    PieCtrlRegs.PIEIER9.bit.INTx1=1; // PIE Group 9, INT1
    PieCtrlRegs.PIEIER9.bit.INTx2=1; // PIE Group 9, INT2
    IER = 0x100; // Enable CPU INT
    EINT;

    //--- Enable global interrupts
    asm(" CLRC INTM, DBGM"); // Enable global interrupts and realtime debug

    }

    __interrupt void sciaRxFifoIsr(void)
    {
    Uint16 i = 0;

    while(1)
    {
    RXParseData[i]=SciaRegs.SCIRXBUF.all; // Read data 'STOP' ended up being 0x87
    i++;
    }


    SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear Overflow flag
    SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag

    PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack
    }