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.

CCS/LAUNCHXL-F28379D: SCI Baud rate

Expert 1985 points
Part Number: LAUNCHXL-F28379D

Tool/software: Code Composer Studio

Hello,

By running the “Example_F28379D_LaunchPadDemo” example, the SCI baud rate is 115200:

void scia_init()
{
    //
    // Note: Clocks were turned on to the SCIA peripheral
    // in the InitSysCtrl() function
    //

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

    //
    // enable TX, RX, internal SCICLK, Disable RX ERR, SLEEP, TXWAKE
    //
    SciaRegs.SCICTL1.all =0x0003;

	SciaRegs.SCICTL2.bit.TXINTENA =1;
	SciaRegs.SCICTL2.bit.RXBKINTENA =1;

	//
    // 115200 baud @LSPCLK = 22.5MHz (90 MHz SYSCLK)
    //
    SciaRegs.SCIHBAUD.all    =0x0000;

    SciaRegs.SCILBAUD.all    =53;

	SciaRegs.SCICTL1.all =0x0023;  // Relinquish SCI from Reset

    return;
}

But with the integration of this program and the “2837x_rfft_adc_rt” example, the data transmission rate is 57,600. Why? How can I increase the baud rate?

main.c

#include "fpu_rfft.h"            // Main include file
#include "math.h"
#include "examples_setup.h"
#include "sci_io.h" 

//!
//! \addtogroup RFFT_EXAMPLES Real FFT of the ADC Input (Real-Time)

// @{
//*****************************************************************************
// defines
//*****************************************************************************
#define RFFT_STAGES     9
#define RFFT_SIZE       (1 << RFFT_STAGES) 
#define F_PER_SAMPLE    (ADC_SAMPLING_FREQ/(float)RFFT_SIZE)
#define USE_TEST_INPUT  1 // If not in test mode, be sure to exclude signal.asm
                          // from the build
#define EPSILON         0.1
//*****************************************************************************
// globals
//*****************************************************************************

#ifdef __cplusplus
#pragma DATA_SECTION("RFFTdata1")
#else
#pragma DATA_SECTION(RFFTin1Buff,"RFFTdata1")
#endif //__cplusplus

uint16_t RFFTin1Buff[2*RFFT_SIZE];

#ifdef __cplusplus
#pragma DATA_SECTION("RFFTdata2")
#else
#pragma DATA_SECTION(RFFTmagBuff,"RFFTdata2")
#endif //__cplusplus
//! \brief Magnitude Calculation Buffer
//!
float RFFTmagBuff[RFFT_SIZE/2+1];               

#ifdef __cplusplus
#pragma DATA_SECTION("RFFTdata2")
#else
#pragma DATA_SECTION(RFFTmagBuff,"RFFTdata2")
#endif //__cplusplus
//! \brief Phase Calculation Buffer
//!
float RFFTphaseBuff[RFFT_SIZE/2]; 

#ifdef __cplusplus
#pragma DATA_SECTION("RFFTdata3")
#else
#pragma DATA_SECTION(RFFToutBuff,"RFFTdata3")
#endif //__cplusplus
//! \brief FFT Calculation Buffer
//! \note If the number of FFT stages is even, the result of the FFT will
//! be written to this buffer
//!
float RFFToutBuff[RFFT_SIZE];

#ifdef __cplusplus
#pragma DATA_SECTION("RFFTdata4")
#else
#pragma DATA_SECTION(RFFTF32Coef,"RFFTdata4")
#endif //__cplusplus
//! \brief Twiddle Factors
//!
float RFFTF32Coef[RFFT_SIZE];

//! \brief RFFT_ADC_F32_STRUCT object
//!
RFFT_ADC_F32_STRUCT rfft_adc;

//! \brief Handle to the RFFT_ADC_F32_STRUCT object
//! 
RFFT_ADC_F32_STRUCT_Handle hnd_rfft_adc = &rfft_adc;

//! \brief RFFT_F32_STRUCT object
//!
RFFT_F32_STRUCT rfft;

//! \brief Handle to the RFFT_F32_STRUCT object
//!
RFFT_F32_STRUCT_Handle hnd_rfft = &rfft;

//! \brief Flag to signal the ADC has finished sampling, and storing, 
//! N points in the FFT input buffer
//!
volatile uint16_t flagInputReady = 0;

//! \brief Index into the FFT input buffer
//!
volatile uint16_t sampleIndex = 0;

//*****************************************************************************
// Function Prototypes
//*****************************************************************************
__interrupt void adcaIsr();

/////////////////////////////////////////////SCI/////////////////////////////////~
void scia_init(void);
void scia_fifo_init(void);
void scia_xmit(int a);
void scia_msg(char *msg);
/////////////////////////////////////////////////////////////////////////////////~

int16_t main(void)
{
    // Locals
	  float freq = 0.0;
    uint16_t i, j;

    char *msg;//<------sci


#ifdef FLASH
    EALLOW;
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0;
    memcpy((uint32_t *)&RamfuncsRunStart, (uint32_t *)&RamfuncsLoadStart,
            (uint32_t)&RamfuncsLoadSize );
    FPU_initFlash();
#endif //FLASH
    
    FPU_initSystemClocks();
    
    FPU_initEpie();

    // Setup ADC-A
    FPU_initADCA();
    
    //Setup EPWM1A as the sampling clock, EPWM2A as the signal to be
    //sampled
    FPU_initEPWM(); 
    //////////////////////////////////////////SCI/////////////////////////////////////~
    InitGpio();

   //
   // For this example, only init the pins for the SCI-A port.
   //  GPIO_SetupPinMux() - Sets the GPxMUX1/2 and GPyMUX1/2 register bits
   //  GPIO_SetupPinOptions() - Sets the direction and configuration of the GPIOS
   // These functions are found in the F2837xD_Gpio.c file.
   //
    EALLOW;   
    GpioCtrlRegs.GPBMUX1.bit.GPIO42 = 3;
    GpioCtrlRegs.GPBMUX1.bit.GPIO43 = 3;
    GpioCtrlRegs.GPBGMUX1.bit.GPIO42 = 3;
    GpioCtrlRegs.GPBGMUX1.bit.GPIO43 = 3;
    EDIS;

   //
   // 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 F2837xD_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 F2837xD_DefaultIsr.c.
   // This function is found in F2837xD_PieVect.c.
   //
    //  InitPieVectTable();
      scia_init();
      scia_fifo_init();       // Initialize the SCI FIFO

    ///////////////////////////////////////////////////////////////////////////////////~

    //Map ISR functions
    EALLOW;
    PieVectTable.ADCA1_INT = &adcaIsr; //function for ADCA interrupt 1
    EDIS;
    //Enable global Interrupts and higher priority real-time debug events:
    PieCtrlRegs.PIEIER1.bit.INTx1 = 1; //Enable ADC1INT
    IER |= M_INT1;  //Enable group 1 interrupts
    EINT;           // Enable Global interrupt INTM
    ERTM;           // Enable Global realtime interrupt DBGM
    
    //Start up the EPWMs
    FPU_startEPWM();
    
    //Link the RFFT_ADC_F32_STRUCT to RFFT_F32_STRUCT. Tail pointer 
    //of RFFT_ADC_F32_STRUCT is passed to the OutBuf pointer of 
    //RFFT_F32_STRUCT 
    hnd_rfft_adc->Tail = &(hnd_rfft->OutBuf);
    
    hnd_rfft->FFTSize   = RFFT_SIZE;         //FFT size
    hnd_rfft->FFTStages = RFFT_STAGES;       //FFT stages

    hnd_rfft_adc->InBuf = &RFFTin1Buff[0];   //Input buffer (12-bit ADC input)
    hnd_rfft->OutBuf    = &RFFToutBuff[0];   //Output buffer
    hnd_rfft->CosSinBuf = &RFFTF32Coef[0];   //Twiddle factor 
    hnd_rfft->MagBuf    = &RFFTmagBuff[0];   //Magnitude output buffer
    hnd_rfft->PhaseBuf  = &RFFTphaseBuff[0]; //Phase output buffer
    
    RFFT_f32_sincostable(hnd_rfft);          //Calculate twiddle factor

    for (i=0; i < RFFT_SIZE; i++){
        RFFToutBuff[i] = 0;                  //Clean up output buffer
    }                                        
                                             
    for (i=0; i <= RFFT_SIZE/2; i++){        
        RFFTmagBuff[i] = 0;                  //Clean up magnitude buffer
    }                                        
                                             
    for (i=0; i < RFFT_SIZE/2; i++){         
        RFFTphaseBuff[i] = 0;                //Clean up phase buffer
    } 
    
    while(1){
    	   msg = "\r\n\n\nHello World!\0";
    	      scia_msg(msg);
        while(flagInputReady == 0){}; // Wait on ADC ISR to set the flag
                                      // before proceeding
        RFFT_adc_f32(hnd_rfft_adc);   // Calculate real FFT (12-bit ADC input)
        flagInputReady = 0;           // Reset the flag
        
#ifdef __TMS320C28XX_TMU__ //defined when --tmu_support=tmu0 in the project 
                           // properties
        RFFT_f32_mag_TMU0(hnd_rfft);        //Calculate magnitude
        RFFT_f32_phase_TMU0(hnd_rfft);      //Calculate phase
#else                                       
        RFFT_f32_mag(hnd_rfft);             //Calculate magnitude
        RFFT_f32_phase(hnd_rfft);           //Calculate phase
#endif //__TMS320C28XX_TMU__

        //Find out the maximum frequency component of signal frequency 
        //component signal. This algorithm is only used for finding frequency 
        //of one component frequency signal; in this example it gives the
        //fundamental frequency of the sampled square wave
        j = 1;
        freq = RFFTmagBuff[1];
        for(i=2;i<RFFT_SIZE/2+1;i++){
        //Looking for the maximum component of frequency spectrum
            if(RFFTmagBuff[i] > freq){
                j = i;
                freq = RFFTmagBuff[i];
            }
        }

        //Converting normalized digital frequency to real analog frequency
        //f = m * fs/N
        // where m is the bin with the maximum value, fs the sampling
        // frequency and N the number of points in the FFT
        freq = F_PER_SAMPLE * (float)j;

    // Execution never reaches this point
    return 1;
}

// End of main

//! \brief ADC Interrupt Service Routine
//! The ISR will store each sampled value in the FFT buffer, and
//! raise the flag once the buffer is full
//!
__interrupt void adcaIsr()
{
    RFFTin1Buff[sampleIndex++] = AdcaResultRegs.ADCRESULT0;  //sampleIndex++ for single channel
    if(sampleIndex == (RFFT_SIZE - 1) ){
        sampleIndex = 0;
        flagInputReady = 1;
    }

    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

// @} //addtogroup

// End of file
///////////////////////////////////////////////sci////////////////////////////////////////////~
//
// scia_xmit - Transmit a character from the SCI
//
void scia_xmit(int a)
{
    while (SciaRegs.SCIFFTX.bit.TXFFST != 0) {}
    SciaRegs.SCITXBUF.all =a;
}

//
// scia_msg - Transmit message via SCIA
//
void scia_msg(char * msg)
{
    int i;
    i = 0;
    while(msg[i] != '\0')
    {
        scia_xmit(msg[i]);
        i++;
    }
}

//
// scia_fifo_init - Initialize the SCI FIFO
//
void scia_fifo_init()
{
    SciaRegs.SCIFFTX.all = 0xE040;
    SciaRegs.SCIFFRX.all = 0x2044;
    SciaRegs.SCIFFCT.all = 0x0;
}
//
// scia_init - SCIA  8-bit word, baud rate 0x000F, default, 1 STOP bit,
// no parity
//
void scia_init()
{
    //
    // Note: Clocks were turned on to the SCIA peripheral
    // in the InitSysCtrl() function
    //

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

    //
    // enable TX, RX, internal SCICLK, Disable RX ERR, SLEEP, TXWAKE
    //
    SciaRegs.SCICTL1.all =0x0003;

	SciaRegs.SCICTL2.bit.TXINTENA =1;
	SciaRegs.SCICTL2.bit.RXBKINTENA =1;

	//
    // 115200 baud @LSPCLK = 22.5MHz (90 MHz SYSCLK)
    //
    SciaRegs.SCIHBAUD.all    =0x0000;

    SciaRegs.SCILBAUD.all    =53;

	SciaRegs.SCICTL1.all =0x0023;  // Relinquish SCI from Reset

    return;
}
///////////////////////////////////////////////////////////////////////////////////////////~

Thanks for your help.

Regards,

Amin

  • Hi Amin,

    I think you will want follow the clock through the device to the SCI baud.

    *Check the PLL settings to ensure the PLL is set as desired
    *Use the XCLKOUT pin to verify that SYSCLK is as expected
    *Verify LSPCLK divider settings
    *Verify SCI settings between your two different programs
  • Hello Devin,

    Thank you. Based on BRR formula, in the “2837x_rfft_adc_rt” project, LSPCLK=24883200 and I can change the buad rate to 115200 and 230400. But for 921600 and 460800 does not work properly. I can't find LSPCLK setting and PLL setting in this project!

    Regards,
    Amin
  • Hi Amin,

    You can actually check the settings in the expressions window once the code is running. Some of the registers of interest are:

    ClkCfgRegs.SYSPLLMULT
    ClkCfgRegs,SYSPLLCTL1
    ClkCfgRegs.SYSPLLSTS
    ClkCfgRegs.SYSCLKDIVSEL
    ClkCfgRegs.LOSPCP

    And it might be a good idea to enable XCLKOUT on a GPIO and check the system frequency. The divider from SYSCLK to XCLKOUT is in

    ClkCfgRegs.XCLKOUTDIVSEL
  • Hi Devin,

    ClkCfgRegs.SYSPLLMULT:0x00000014
    ClkCfgRegs,SYSPLLCTL1:0x00000003
    ClkCfgRegs.SYSPLLSTS:0x00000001
    ClkCfgRegs.SYSCLKDIVSEL:0x00000001
    ClkCfgRegs.LOSPCP:0x00000002
    ClkCfgRegs.XCLKOUTDIVSEL:0x00000003
    How can I enable XCLKOUT on a GPIO and check the system frequency? I need an example code to add the project.
    Thank you.

    Regards,
    Amin
  • Hi Amin,

    You should take the value of those registers and compare them to your expectations. Note that in the expressions window you can append ".bit" after the register name to see individually what is in each field of each register.

    You should use this along with the TRM section on the PLL to determine what the SYSCLK frequency *should* be based on your desired settings and code. You can then compare this to what you observe from the XCLKOUT pin.

    Similarly, you can then look at the settings of the low speed clock and SCI baud rate settings and compute what the baud rate should be based on the SCI section of the TRM. Compare this with the observed baud rate and adjust the registers accordingly.

    XCLKOUT is muxed onto GPIO73 in position 3. To see how to set the GPIO mux to enable this, "Table 4-3. GPIO Muxed Pins" in the datasheet is very helpful. Note that you should also configure (or at least look up the default behavior) for the XCLKOUTDIVSEL and XCLKOUTSEL registers.
  • Hi Devin,

    Thank for your help. I made changes to the project(2837x_rfft_adc_rt and SCI combined).
    By changing the following settings to the IMULT_40, I was able to transfer data at the 921600 baud.
    F2837xD_SysCtrl.c :
    “InitSysPll(XTAL_OSC,IMULT_20,FMULT_1,PLLCLK_BY_2);”

    But the measured frequency is half. For example, the true input signal of 6 kHz measured 3 kHz with this setting:

    examples_setup.h:
    #define CPU_FRQ_200MHZ 1
    #define ADC_SAMPLING_FREQ 100000.0L
    #define EPWM_CLK 100000000UL // EPWM_CLK starts off SYSCLK/2
    #define EPWM_CLKDIV 1
    #define EPWM_HSPCLKDIV 4
    #define EPWM1_PERIOD EPWM_CLK/(2*8*100000UL)
    #define EPWM1_DUTY_CYCLE EPWM1_PERIOD/2UL
    #define EPWM2_PERIOD (EPWM_CLK)/(2*8*100000UL)
    #define EPWM2_DUTY_CYCLE EPWM2_PERIOD/2UL

    Then, with the following changes, I could see the correct amount of frequency measurement(frequency measurement with the same actual value and baud rate is 921600):

    #define CPU_FRQ_200MHZ 1
    #define ADC_SAMPLING_FREQ 100000.0L
    #define EPWM_CLK 100000000UL // EPWM_CLK starts off SYSCLK/2
    #define EPWM_CLKDIV 1
    #define EPWM_HSPCLKDIV 4
    #define EPWM1_PERIOD EPWM_CLK/(1*8*100000UL)< ----
    #define EPWM1_DUTY_CYCLE EPWM1_PERIOD/2UL
    #define EPWM2_PERIOD (EPWM_CLK)/(1*8*100000UL)<-----
    #define EPWM2_DUTY_CYCLE EPWM2_PERIOD/2UL

    Is this the right way?
    How can I get the speed of CPU is maximum speed? How can I make sure?

    Best regards,
    Amin
  • Hi Amin,

    The XCLKOUT will tell you what speed the CPU is running at. If the PLL input clock is 10MHz, PLL multiplier is 40, and PLL divider is 2 then you would expect the CPU frequency to be: 10MHz*40/2 = 200MHz, which is the target frequency. Similarly, if the PLL input clock is 20MHz, then you probably want 20MHz*20/2 to get to 200MHz. You can check this using a scope or frequency counter on the XCLKOUT pin. The default divider is /8, so if you enable XCLKOUT and measure 25MHz on the pin then the CPU is running at the expected 200MHz. If you measure 12.5MHz then it is only running at 100MHz...etc.
  • Hi Devin,

    Thanks for your best help. Can you give me an example code to launch XCLKOUT pin? I need to see this pin using scope.

    Best regards,
    Amin
  • Hi Amin,

    Were you able to get the XCLKOUT on the pin or otherwise get the correct baud rate? You can enable the XCLKOUT on the pin using the following code:

    GpioCtrlRegs.GPCGMUX1.bit.GPIO73 = 0;
    GpioCtrlRegs.GPCMUX1.bit.GPIO73 = 3;
    GpioCtrlRegs.GPCDIR.bit.GPIO73 = 0;
  • Hi Devin,

    Thanks for your help.

    Best regards,
    Amin