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.

TMS320F28379D: Regarding UART Communication and LSPCLK setting

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE, TMDSCNCD28379D, LAUNCHXL-F28379D

I want to output a predefined data of ECG values to DAC as well as to the UART at the same time, for that I have used the "buffdac_sine_dma" and modified it for the same. I also have enabled the timer ISR and blink the LED on the launchpad board just to make sure that it is working properly (which does work!). Now, I also want to add the UART transmission part (by polling) in the timer ISR. How can I set the LSPCLK so that baudrate register value can be calculated (considering 19200 bps required baud rate).

Is there any reference code for the UART part and also for LSPCLK seting? I am attaching the code I am trying to develop.

//###########################################################################
//
// FILE:   buffdac_sine_dma_cpu01.c
//
// TITLE:  Buffered DAC Sine Wave Output Using DMA Example
//
//! \addtogroup cpu01_example_list
//! <h1> Buffered DAC Sine DMA (buffdac_sine_dma) </h1>
//!
//! This example generates a sine wave on the buffered DAC output using the DMA
//! to transfer sine values stored in a sine table in GSRAM to DACVALS,
//! DACOUTA/ADCINA0 (HSEC Pin 9) and uses the default DAC reference setting
//! of VDAC.
//!
//! When the DAC reference is set to VDAC, an external reference voltage
//! must be applied to the VDAC pin. This can accomplished by connecting a
//! jumper wire from 3.3V to ADCINB0 (HSEC pin 12).
//!
//! Run the included .js file to add the watch variables.
//!
//! outputFreq_hz = (samplingFreq_hz/SINE_TBL_SIZE)*tableStep
//!
//! The generated waveform can be adjusted with the following variables/macros
//! but require recompile:
//! - \b waveformGain \b : Adjust the magnitude of the waveform.
//! Range is from 0.0 to 1.0. The default value of 0.8003 centers the waveform
//! within the linear range of the DAC.
//! - \b waveformOffset \b : Adjust the offset of the waveform.
//! Range is from -1.0 to 1.0. The default value of 0 centers the waveform.
//! - \b samplingFreq_hz \b : Adjust the rate at which the DAC is updated.
//! Range - Bounded by cpu timer maximum interrupt rate.
//! - \b tableStep \b : The sine table step size.
//! Range - Bounded by sine table size, should be much less than sine table size
//! to have good resolution.
//! - \b REFERENCE \b : The reference for the DAC.
//! Range - REFERENCE_VDAC, REFERENCE_VREF
//! - \b CPUFREQ_MHZ \b : The cpu frequency. This does not set the cpu frequency.
//! Range - See device data manual
//! - \b DAC_NUM \b : The DAC to use.
//! Range - DACA, DACB, DACC
//!
//
//###########################################################################
// $TI Release: F2837xD Support Library v3.05.00.00 $
// $Release Date: Thu Oct 18 15:48:42 CDT 2018 $
// $Copyright:
// Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions 
// are met:
// 
//   Redistributions of source code must retain the above copyright 
//   notice, this list of conditions and the following disclaimer.
// 
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the 
//   documentation and/or other materials provided with the   
//   distribution.
// 
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//###########################################################################

//
// Included Files
//
#include "F28x_Project.h"
#include "math.h"
#include "ecgdataexternal.h"
//
// Defines
//`
#define REFERENCE_VDAC        0
#define REFERENCE_VREF        1
#define DACA                  1
#define DACB                  2
#define DACC                  3
#define REFERENCE             REFERENCE_VDAC
#define CPUFREQ_MHZ           200
#define DAC_NUM               DACA
#define PI                    3.14159265
#define ECG_TBL_SIZE          768

//
// Globals
//
Uint16 ECG_TBL[ECG_TBL_SIZE];
#pragma DATA_SECTION(ECG_TBL, "ramgs0");
volatile struct DAC_REGS* DAC_PTR[4] = {0x0,&DacaRegs,&DacbRegs,&DaccRegs};
Uint32 samplingFreq_hz = 256;
Uint16 tableStep = 1;
float waveformGain = 1; // Range 0.0 -> 1.0
float waveformOffset = 0;    // Range -1.0 -> 1.0

volatile Uint16 *DMADest;
volatile Uint16 *DMASource;

//
// Function Prototypes
//
void configureDAC(Uint16 dac_num);
void configureDMA(Uint16 dac_num);
void configureWaveform(void);


//
// Function Prototypes
//
__interrupt void cpu_timer0_isr(void);



//
// Main
//
void main(void)
{
//
// Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
//
    InitSysCtrl();

//
// Disable CPU interrupts
//
    DINT;

//
// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags are cleared.
//
    InitPieCtrl();

//
// Clear all interrupts and initialize PIE vector table:
//
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();

//
// Configure DAC
//
    configureDAC(DAC_NUM);

//
// Configure Waveform
//
    configureWaveform();

//
// 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.TIMER0_INT = &cpu_timer0_isr;
   EDIS;    // This is needed to disable write to EALLOW protected registers



//
// Initialize Cpu Timers
//
    InitCpuTimers();

//
// Configure Cpu Timer0 to interrupt at specified sampling frequency
//
    ConfigCpuTimer(&CpuTimer0, CPUFREQ_MHZ, 1000000.0/samplingFreq_hz);

//
// Configure DMA
//
    configureDMA(DAC_NUM);

//
// Start Cpu Timer0
//
    CpuTimer0Regs.TCR.all = 0x4000;

//
// Step 5. User specific code, enable __interrupts:
// Configure GPIO34 as a GPIO output pin
//
   EALLOW;
   GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;
   GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;
   EDIS;


//
// Enable CPU INT1 which is connected to CPU-Timer 0:
//
   IER |= M_INT1;

//
// Enable TINT0 in the PIE: Group 1 __interrupt 7
//
   PieCtrlRegs.PIEIER1.bit.INTx7 = 1;

//
// Enable global Interrupts and higher priority real-time debug events:
//
   EINT;   // Enable Global __interrupt INTM
   ERTM;   // Enable Global realtime __interrupt DBGM


   while(1);
}

//
// configureDAC - Enable and configure the requested DAC module
//
void configureDAC(Uint16 dac_num)
{
    EALLOW;

    DAC_PTR[dac_num]->DACCTL.bit.DACREFSEL = REFERENCE;
    DAC_PTR[dac_num]->DACOUTEN.bit.DACOUTEN = 1;
    DAC_PTR[dac_num]->DACVALS.all = 0;

    DELAY_US(10); // Delay for buffered DAC to power up

    EDIS;
}

//
// configureDMA - Configures the DMA to read from the SINE table and write to the DAC
//
void configureDMA(Uint16 dac_num)
{
    //
    // Ensure DMA is connected to Peripheral Frame 1 bridge which contains the DAC
    //
    EALLOW;
    CpuSysRegs.SECMSEL.bit.PF1SEL = 1;
    EDIS;

    //
    // Initialize DMA
    //
    DMAInitialize();

    DMASource = (volatile Uint16 *)&ECG_TBL[0];
    DMADest = (volatile Uint16 *)&DAC_PTR[dac_num]->DACVALS;

    //
    // Configure DMA CH1
    //
    DMACH1AddrConfig(DMADest,DMASource);
    DMACH1BurstConfig(0,0,0);
    DMACH1TransferConfig(ECG_TBL_SIZE/tableStep-1,tableStep,0);
    DMACH1WrapConfig(ECG_TBL_SIZE/tableStep-1,0,0,0);
    DMACH1ModeConfig(0,PERINT_ENABLE,ONESHOT_DISABLE,CONT_ENABLE,
                     SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT,
                     CHINT_END,CHINT_DISABLE);

    EALLOW;
    DmaClaSrcSelRegs.DMACHSRCSEL1.bit.CH1 = DMA_TINT0;    // Timer0 is DMA trigger
    EDIS;

    StartDMACH1(); // Start DMA channel
}

//
// configureWaveform - Configure the SINE waveform
//
void configureWaveform(void)
{
    Uint16 j;
    float offset;
    float waveformValue;

    //
    // Fill Sine Table
    //
    for(j=0;j<ECG_TBL_SIZE;j++)
    {
        ECG_TBL[j] = data[j];
    }

    //
    // Adjust for Gain and Offset
    //
    offset = (ECG_TBL[0] - (ECG_TBL[0]*waveformGain)) + (ECG_TBL[0]*waveformOffset);

    for(j=0;j<ECG_TBL_SIZE;j++)
    {
        waveformValue = (ECG_TBL[j]*waveformGain)+offset;
        ECG_TBL[j] = waveformValue < 0 ? 0 : waveformValue > 4095 ? 4095 : waveformValue;
    }
}

//
// cpu_timer0_isr - CPU Timer0 ISR that toggles GPIO32 once per 500ms
//
__interrupt void cpu_timer0_isr(void)
{
   CpuTimer0.InterruptCount++;
   GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1;

   //
   // Acknowledge this __interrupt to receive more __interrupts from group 1
   //
   PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

//
// End of file
//

  • You can find all examples for the SCI (UART) inside of C2000ware in the examples directory for the F2837xD. also, the LaunchPad example program uses the SCI to dump data to the Terminal.

    The TRM chapter for the SCI covers the baudrate settings. (http://www.ti.com/lit/sprumh8 )

    Regards,
    Mark
  • Thanks for the idea that I can find the UART transmission part in launchpad demo! I still have one question though that is the SYSCLK set to 200MHz or 90MHz in the demo code? Secondly, as I can see in the user guide of F28379D, PLLSYSCLK is the main clock and CPU1.SYSCLK and CPU2.SYSCLK are the other two clocks from CPUs ; are the default values viz. 200MHz, 90MHz and 90MHz respectively? And I also found the PERx.SYSCLK, is this clock 90MHz then by default? Because I didn't find any explicit setting of the frequencies in the main file atleast!

    I am confused because of the following comment in the launchpad example code:

    // 115200 baud @LSPCLK = 22.5MHz (90 MHz SYSCLK).
  • Hmm. That is a bug in the example code comments. we have carried this example through all of our LaunchPads.

    The PLLSYSCLK is configured to 200 MHz in the Init_SysCtrl() function. There are no dividers on PLLSYSCLK for the CPUx.SYSCLKs so the CPUx.SYSCLK will always be the same as PLLSYSCLK. Please refer to the Clocking System figure in the System Control chapter of the TRM. it shows the relationships between all of the clocks on the device.

    As the LSPCLK is never touched in this example, it is by default SYSCLK/4, so 50 MHz. base your equations for the SCI baud rate on 50 MHz.

    -Mark
  • I tried the UART part and it worked, but, the calculation of BRR= 325 is practically setting a baud rate of 9600 and not 19200. If I consider frequency as 50 MHz and required baudrate as 19200, I get a value of BRR=325., but the actual baudrate when checking with terminal comes to 9600. So, it implies that either my calculations are wrong or the frequency is 25MHz instead of 50MHz!
  • Chinmay,

    Please check the following:
    if using the buffdac_sine_dma_cpu01 example code, check to see if there are any predefined symbols set up.
    In CCS, right click on the Project, select Properties, then under Advanced Options is Predefined Symbols. check If "_LAUNCHXL_F28379D" is in the Pre-define NAME list. This project level # define is used by the InitSysCtrl function to set up the PLLSYSCLK to the right frequency base on if you are using the controlCard (TMDSCNCD28379D) or the LaunchPad (LAUNCHXL-F28379D). Unfortunately these boards use on-board clock sources with different frequencies. When that macro is not defined the pll will take the input source and multiply it by 20. With the macro defined, the input source is multiplied by 40.

    -Mark
  • This precisely was the problem! After adding the predefined symbol everything is working correctly!
  • Great! Please don't hesitate to post again in the future if you encounter any issues you are not able to figure out on your own.

    -Mark