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/TMS320F28379D: Requesting information regarding data transfer in Code composer studio through SCI communication

Part Number: TMS320F28379D
Other Parts Discussed in Thread: CONTROLSUITE, C2000WARE

Tool/software: Code Composer Studio

Hi all,

            Myself Sumanta is trying to have data transfer in Code composer studio through SCI based communication in F2837X control card R1.3. The source code is as below:

[

USB to UART program

//###########################################################################

//

// FILE:   usb_dev_serial.c

//

// TITLE:  Main routines for the USB CDC serial example.

//

//###########################################################################

// $TI Release: F2837xD Support Library v200 $

// $Release Date: Tue Jun 21 13:00:02 CDT 2016 $

// $Copyright: Copyright (C) 2013-2016 Texas Instruments Incorporated -

//             http://www.ti.com/ ALL RIGHTS RESERVED $

//###########################################################################

 

//

// Included Files

//

#include "F28x_Project.h"

#include <stdbool.h>

#include <stdint.h>

#include "inc/hw_ints.h"

#include "inc/hw_memmap.h"

#include "inc/hw_types.h"

#include "inc/hw_uart.h"

#include "driverlib/debug.h"

#include "driverlib/interrupt.h"

#include "driverlib/sysctl.h"

#include "driverlib/systick.h"

#include "driverlib/uart.h"

#include "driverlib/usb.h"

#include "driverlib/usb_hal.h"

#include "driverlib/rom.h"

#include "usblib/usblib.h"

#include "usblib/usbcdc.h"

#include "usblib/usb-ids.h"

#include "usblib/device/usbdevice.h"

#include "usblib/device/usbdcdc.h"

#include "utils/ustdlib.h"

#include "usb_serial_structs.h"

 

//*****************************************************************************

//

//! \addtogroup cpu01_example_list

//! <h1>USB Serial Device (usb_dev_serial) </h1>

//!

//! This example application turns the evaluation kit into a virtual serial

//! port when connected to the USB host system.  The application supports the

//! USB Communication Device Class, Abstract Control Model to redirect UART0

//! traffic to and from the USB host system.

//!

//! Connect USB cables from your PC to both the mini and microUSB connectors on

//! the controlCARD. Figure out what COM ports your controlCARD is enumerating

//! (typically done using Device Manager in Windows) and open a serial terminal

//! to each of with the settings 115200 Baud 8-N-1. Characters typed in one

//! terminal should be echoed in the other and vice versa.

//!

//! A driver information (INF) file for use with Windows XP and

//! Windows 7 can be found in the windows_drivers directory.

//

//*****************************************************************************

 

//*****************************************************************************

//

// Configuration and tuning parameters.

//

//*****************************************************************************

 

//*****************************************************************************

//

// The system tick rate expressed both as ticks per second and a millisecond

// period.

//

//*****************************************************************************

#define SYSTICKS_PER_SECOND 100

#define SYSTICK_PERIOD_MS (1000 / SYSTICKS_PER_SECOND)

 

//*****************************************************************************

//

// Variables tracking transmit and receive counts.

//

//*****************************************************************************

volatile uint32_t g_ui32UARTTxCount = 0;

volatile uint32_t g_ui32UARTRxCount = 0;

#ifdef DEBUG

uint32_t g_ui32UARTRxErrors = 0;

#endif

 

//*****************************************************************************

//

// The base address, peripheral ID and interrupt ID of the UART that is to

// be redirected.

//

//*****************************************************************************

 

//*****************************************************************************

//

// Defines required to redirect UART0 via USB.

//

//*****************************************************************************

#define USB_UART_BASE           UARTA_BASE

#define USB_UART_PERIPH         SYSCTL_PERIPH_SCI1

#define USB_UART_INT            INT_SCIRXINTA

 

//*****************************************************************************

//

// Default line coding settings for the redirected UART.

//

//*****************************************************************************

#define DEFAULT_BIT_RATE        115200

#define DEFAULT_UART_CONFIG     (UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | \

                                 UART_CONFIG_STOP_ONE)

 

//*****************************************************************************

//

// GPIO peripherals and pins muxed with the redirected UART.  These will depend

// upon the IC in use and the UART selected in USB_UART_BASE.  Be careful that

// these settings all agree with the hardware you are using.

//

//*****************************************************************************

 

//*****************************************************************************

//

// Defines required to redirect UART0 via USB.

//

//*****************************************************************************

//#define TX_GPIO_BASE            GPIO_PORTA_BASE

//#define TX_GPIO_PERIPH          SYSCTL_PERIPH_GPIOA

//#define TX_GPIO_PIN             GPIO_PIN_1

//

//#define RX_GPIO_BASE            GPIO_PORTA_BASE

//#define RX_GPIO_PERIPH          SYSCTL_PERIPH_GPIOA

//#define RX_GPIO_PIN             GPIO_PIN_0

 

//*****************************************************************************

//

// Flag indicating whether or not we are currently sending a Break condition.

//

//*****************************************************************************

static bool g_bSendingBreak = false;

 

//*****************************************************************************

//

// Global system tick counter

//

//*****************************************************************************

volatile uint32_t g_ui32SysTickCount = 0;

 

//*****************************************************************************

//

// Flags used to pass commands from interrupt context to the main loop.

//

//*****************************************************************************

#define COMMAND_PACKET_RECEIVED 0x00000001

#define COMMAND_STATUS_UPDATE   0x00000002

 

volatile uint32_t g_ui32Flags = 0;

char *g_pcStatus;

 

//*****************************************************************************

//

// Global flag indicating that a USB configuration has been set.

//

//*****************************************************************************

static volatile bool g_bUSBConfigured = false;

 

//*****************************************************************************

//

// Internal function prototypes.

//

//*****************************************************************************

static void USBUARTPrimeTransmit(uint32_t ui32Base);

static void CheckForSerialStateChange(const tUSBDCDCDevice *psDevice,

                                      int32_t i32Errors);

static void SetControlLineState(uint16_t ui16State);

static bool SetLineCoding(tLineCoding *psLineCoding);

static void GetLineCoding(tLineCoding *psLineCoding);

static void SendBreak(bool bSend);

 

//*****************************************************************************

//

// The error routine that is called if the driver library encounters an error.

//

//*****************************************************************************

#ifdef DEBUG

void

__error__(char *pcFilename, uint32_t ui32Line)

{

    while(1)

    {

    }

}

#endif

 

//*****************************************************************************

//

// This function is called whenever serial data is received from the UART.

// It is passed the accumulated error flags from each character received in

// this interrupt and determines from them whether or not an interrupt

// notification to the host is required.

//

// If a notification is required and the control interrupt endpoint is idle,

// we send the notification immediately.  If the endpoint is not idle, we

// accumulate the errors in a global variable which will be checked on

// completion of the previous notification and used to send a second one

// if necessary.

//

//*****************************************************************************

static void

CheckForSerialStateChange(const tUSBDCDCDevice *psDevice, int32_t i32Errors)

{

    uint16_t ui16SerialState;

 

    //

    // Clear our USB serial state.  Since we are faking the handshakes, always

    // set the TXCARRIER (DSR) and RXCARRIER (DCD) bits.

    //

    ui16SerialState = USB_CDC_SERIAL_STATE_TXCARRIER |

                    USB_CDC_SERIAL_STATE_RXCARRIER;

 

    //

    // Are any error bits set?

    //

    if(i32Errors)

    {

        //

        // At least one error is being notified so translate from our hardware

        // error bits into the correct state markers for the USB notification.

        //

        if(i32Errors & UART_RXST_OE)

        {

            ui16SerialState |= USB_CDC_SERIAL_STATE_OVERRUN;

        }

 

        if(i32Errors & UART_RXST_PE)

        {

            ui16SerialState |= USB_CDC_SERIAL_STATE_PARITY;

        }

 

        if(i32Errors & UART_RXST_FE)

        {

            ui16SerialState |= USB_CDC_SERIAL_STATE_FRAMING;

        }

 

        if(i32Errors & UART_RXST_BRKDT)

        {

            ui16SerialState |= USB_CDC_SERIAL_STATE_BREAK;

        }

 

        // Call the CDC driver to notify the state change.

        USBDCDCSerialStateChange((void *)psDevice, ui16SerialState);

    }

}

 

//*****************************************************************************

//

// Read as many characters from the UART FIFO as we can and move them into

// the CDC transmit buffer.

//

// \return Returns UART error flags read during data reception.

//

//*****************************************************************************

static int32_t

ReadUARTData(void)

{

    int32_t i32Char, i32Errors;

    uint8_t ui8Char;

    uint32_t ui32Space;

 

    //

    // Clear our error indicator.

    //

    i32Errors = 0;

 

    //

    // How much space do we have in the buffer?

    //

    ui32Space = USBBufferSpaceAvailable((tUSBBuffer *)&g_sTxBuffer);

 

    //

    // Read data from the UART FIFO until there is none left or we run

    // out of space in our receive buffer.

    //

    while(ui32Space && UARTCharsAvail(USB_UART_BASE))

    {

        //

        // Read a character from the UART FIFO into the ring buffer if no

        // errors are reported.

        //

        i32Char = UARTCharGetNonBlocking(USB_UART_BASE);

 

        //

        // If the character did not contain any error notifications,

        // copy it to the output buffer.

        //

        if(!(i32Char & ~0xFF))

        {

            ui8Char = (uint8_t)(i32Char & 0xFF);

            USBBufferWrite((tUSBBuffer *)&g_sTxBuffer,

                           (uint8_t *)&ui8Char, 1);

 

            //

            // Decrement the number of bytes we know the buffer can accept.

            //

            ui32Space--;

        }

        else

        {

#ifdef DEBUG

            //

            // Increment our receive error counter.

            //

            g_ui32UARTRxErrors++;

#endif

            //

            // Update our error accumulator.

            //

            i32Errors |= i32Char;

        }

 

        //

        // Update our count of bytes received via the UART.

        //

        g_ui32UARTRxCount++;

    }

 

    //

    // Pass back the accumulated error indicators.

    //

    return(i32Errors);

}

 

//*****************************************************************************

//

// Take as many bytes from the transmit buffer as we have space for and move

// them into the USB UART's transmit FIFO.

//

//*****************************************************************************

static void

USBUARTPrimeTransmit(uint32_t ui32Base)

{

    uint32_t ui32Read;

    uint8_t ui8Char;

 

    //

    // If we are currently sending a break condition, don't receive any

    // more data. We will resume transmission once the break is turned off.

    //

    if(g_bSendingBreak)

    {

        return;

    }

 

    //

    // If there is space in the UART FIFO, try to read some characters

    // from the receive buffer to fill it again.

    //

    while(UARTSpaceAvail(ui32Base))

    {

        //

        // Get a character from the buffer.

        //

        ui32Read = USBBufferRead((tUSBBuffer *)&g_sRxBuffer, &ui8Char, 1);

 

        //

        // Did we get a character?

        //

        if(ui32Read)

        {

            //

            // Place the character in the UART transmit FIFO.

            //

            UARTCharPutNonBlocking(ui32Base, ui8Char);

 

            //

            // Update our count of bytes transmitted via the UART.

            //

            g_ui32UARTTxCount++;

        }

        else

        {

            //

            // We ran out of characters so exit the function.

            //

            return;

        }

    }

}

 

//*****************************************************************************

//

// Interrupt handler for the system tick counter.

//

//*****************************************************************************

__interrupt void

SysTickIntHandler(void)

{

    //

    // Update our system time.

    //

    g_ui32SysTickCount++;

    PieCtrlRegs.PIEACK.all |= 1;

}

 

//*****************************************************************************

//

// Interrupt handler for the UART TX which is being redirected via USB.

//

//*****************************************************************************

__interrupt void

USBUARTTXIntHandler(void)

{

    uint32_t ui32Ints;

 

    ui32Ints = UARTIntStatus(USB_UART_BASE, true);

    //

    // Handle transmit interrupts.

    //

    if(ui32Ints & UART_INT_TXRDY)

    {

        //

        // Move as many bytes as possible into the transmit FIFO.

        //

        USBUARTPrimeTransmit(USB_UART_BASE);

 

        //

        // If the output buffer is empty, turn off the transmit interrupt.

        //

        if(!USBBufferDataAvailable(&g_sRxBuffer))

        {

            UARTIntDisable(USB_UART_BASE, UART_INT_TXRDY);

        }

    }

 

    PieCtrlRegs.PIEACK.all = 0x100;

}

 

//*****************************************************************************

//

// Interrupt handler for the UART RX which is being redirected via USB.

//

//*****************************************************************************

__interrupt void

USBUARTRXIntHandler(void)

{

    uint32_t u3i2Ints;

 

    u3i2Ints = UARTIntStatus(USB_UART_BASE, true);

    //

    // Handle receive interrupts.

    //

    if(u3i2Ints & UART_INT_RXRDY_BRKDT)

    {

        //

        // Read the UART's characters into the buffer.

        //

        ReadUARTData();

 

    }

    else if(u3i2Ints & UART_INT_RXERR)

    {

        //

        //Notify Host of our error

        //

        CheckForSerialStateChange(&g_sCDCDevice, UARTRxErrorGet(USB_UART_BASE));

 

        //

        //Clear the error and continue

        //

        UARTRxErrorClear(USB_UART_BASE);

    }

 

    PieCtrlRegs.PIEACK.all = 0x100;

 

}

 

 

//*****************************************************************************

//

// Set the state of the RS232 RTS and DTR signals.

//

//*****************************************************************************

static void

SetControlLineState(uint16_t ui16State)

{

    //

    // TODO: If configured with GPIOs controlling the handshake lines,

    // set them appropriately depending upon the flags passed in the wValue

    // field of the request structure passed.

    //

}

 

//*****************************************************************************

//

// Set the communication parameters to use on the UART.

//

//*****************************************************************************

static bool

SetLineCoding(tLineCoding *psLineCoding)

{

    uint32_t ui32Config;

    bool bRetcode;

 

    //

    // Assume everything is OK until we detect any problem.

    //

    bRetcode = true;

 

    //

    // Word length.  For invalid values, the default is to set 8 bits per

    // character and return an error.

    //

    switch(psLineCoding->ui8Databits)

    {

        case 5:

        {

            ui32Config = UART_CONFIG_WLEN_5;

            break;

        }

 

        case 6:

        {

            ui32Config = UART_CONFIG_WLEN_6;

            break;

        }

 

        case 7:

        {

            ui32Config = UART_CONFIG_WLEN_7;

            break;

        }

 

        case 8:

        {

            ui32Config = UART_CONFIG_WLEN_8;

            break;

        }

 

        default:

        {

            ui32Config = UART_CONFIG_WLEN_8;

            bRetcode = false;

            break;

        }

    }

 

    //

    // Parity.  For any invalid values, we set no parity and return an error.

    //

    switch(psLineCoding->ui8Parity)

    {

        case USB_CDC_PARITY_NONE:

        {

            ui32Config |= UART_CONFIG_PAR_NONE;

            break;

        }

 

        case USB_CDC_PARITY_ODD:

        {

            ui32Config |= UART_CONFIG_PAR_ODD;

            break;

        }

 

        case USB_CDC_PARITY_EVEN:

        {

            ui32Config |= UART_CONFIG_PAR_EVEN;

            break;

        }

 

        case USB_CDC_PARITY_MARK:

        {

            ui32Config |= UART_CONFIG_PAR_ONE;

            break;

        }

 

        case USB_CDC_PARITY_SPACE:

        {

            ui32Config |= UART_CONFIG_PAR_ZERO;

            break;

        }

 

        default:

        {

            ui32Config |= UART_CONFIG_PAR_NONE;

            bRetcode = false;

            break;

        }

    }

 

    //

    // Stop bits.  Our hardware only supports 1 or 2 stop bits whereas CDC

    // allows the host to select 1.5 stop bits.  If passed 1.5 (or any other

    // invalid or unsupported value of ui8Stop, we set up for 1 stop bit but

    // return an error in case the caller needs to Stall or otherwise report

    // this back to the host.

    //

    switch(psLineCoding->ui8Stop)

    {

        //

        // One stop bit requested.

        //

        case USB_CDC_STOP_BITS_1:

        {

            ui32Config |= UART_CONFIG_STOP_ONE;

            break;

        }

 

        //

        // Two stop bits requested.

        //

        case USB_CDC_STOP_BITS_2:

        {

            ui32Config |= UART_CONFIG_STOP_TWO;

            break;

        }

 

        //

        // Other cases are either invalid values of ui8Stop or values that we

        // cannot support so set 1 stop bit but return an error.

        //

        default:

        {

            ui32Config = UART_CONFIG_STOP_ONE;

            bRetcode |= false;

            break;

        }

    }

 

    //

    // Set the UART mode appropriately.

    //

    UARTConfigSetExpClk(USB_UART_BASE, SysCtlLowSpeedClockGet(SYSTEM_CLOCK_SPEED),

                            readusb32_t(&(psLineCoding->ui32Rate)), ui32Config);

 

    //

    // Let the caller know if we had a problem or not.

    //

    return(bRetcode);

}

 

//*****************************************************************************

//

// Get the communication parameters in use on the UART.

//

//*****************************************************************************

static void

GetLineCoding(tLineCoding *psLineCoding)

{

    uint32_t ui32Config;

    uint32_t ui32Rate;

 

    //

    // Get the current line coding set in the UART.

    //

    UARTConfigGetExpClk(USB_UART_BASE, SysCtlLowSpeedClockGet(SYSTEM_CLOCK_SPEED),

                        &ui32Rate, &ui32Config);

    writeusb32_t(&(psLineCoding->ui32Rate), ui32Rate);

 

    //

    // Translate the configuration word length field into the format expected

    // by the host.

    //

    switch(ui32Config & UART_CONFIG_WLEN_MASK)

    {

        case UART_CONFIG_WLEN_8:

        {

            psLineCoding->ui8Databits = 8;

            break;

        }

 

        case UART_CONFIG_WLEN_7:

        {

            psLineCoding->ui8Databits = 7;

            break;

        }

 

        case UART_CONFIG_WLEN_6:

        {

            psLineCoding->ui8Databits = 6;

            break;

        }

 

        case UART_CONFIG_WLEN_5:

        {

            psLineCoding->ui8Databits = 5;

            break;

        }

    }

 

    //

    // Translate the configuration parity field into the format expected

    // by the host.

    //

    switch(ui32Config & UART_CONFIG_PAR_MASK)

    {

        case UART_CONFIG_PAR_NONE:

        {

            psLineCoding->ui8Parity = USB_CDC_PARITY_NONE;

            break;

        }

 

        case UART_CONFIG_PAR_ODD:

        {

            psLineCoding->ui8Parity = USB_CDC_PARITY_ODD;

            break;

        }

 

        case UART_CONFIG_PAR_EVEN:

        {

            psLineCoding->ui8Parity = USB_CDC_PARITY_EVEN;

            break;

        }

    }

 

    //

    // Translate the configuration stop bits field into the format expected

    // by the host.

    //

    switch(ui32Config & UART_CONFIG_STOP_MASK)

    {

        case UART_CONFIG_STOP_ONE:

        {

            psLineCoding->ui8Stop = USB_CDC_STOP_BITS_1;

            break;

        }

 

        case UART_CONFIG_STOP_TWO:

        {

            psLineCoding->ui8Stop = USB_CDC_STOP_BITS_2;

            break;

        }

    }

}

 

//*****************************************************************************

//

// This function sets or clears a break condition on the redirected UART RX

// line.  A break is started when the function is called with \e bSend set to

// \b true and persists until the function is called again with \e bSend set

// to \b false.

//

//*****************************************************************************

static void

SendBreak(bool bSend)

{

       //

       //C28x SCI cannot send break conditions

       //

       return;

}

 

//*****************************************************************************

//

// Handles CDC driver notifications related to control and setup of the device.

//

// \param pvCBData is the client-supplied callback pointer for this channel.

// \param ui32Event identifies the event we are being notified about.

// \param ui32MsgValue is an event-specific value.

// \param pvMsgData is an event-specific pointer.

//

// This function is called by the CDC driver to perform control-related

// operations on behalf of the USB host.  These functions include setting

// and querying the serial communication parameters, setting handshake line

// states and sending break conditions.

//

// \return The return value is event-specific.

//

//*****************************************************************************

uint32_t

ControlHandler(void *pvCBData, uint32_t ui32Event,

               uint32_t ui32MsgValue, void *pvMsgData)

{

    uint32_t ui32IntsOff;

 

    //

    // Which event are we being asked to process?

    //

    switch(ui32Event)

    {

        //

        // We are connected to a host and communication is now possible.

        //

        case USB_EVENT_CONNECTED:

            g_bUSBConfigured = true;

 

            //

            // Flush our buffers.

            //

            USBBufferFlush(&g_sTxBuffer);

            USBBufferFlush(&g_sRxBuffer);

 

            //

            // Tell the main loop to update the display.

            //

            ui32IntsOff = IntMasterDisable();

            g_pcStatus = "Connected";

            g_ui32Flags |= COMMAND_STATUS_UPDATE;

            if(!ui32IntsOff)

            {

                IntMasterEnable();

            }

            break;

 

        //

        // The host has disconnected.

        //

        case USB_EVENT_DISCONNECTED:

            g_bUSBConfigured = false;

            ui32IntsOff = IntMasterDisable();

            g_pcStatus = "Disconnected";

            g_ui32Flags |= COMMAND_STATUS_UPDATE;

            if(!ui32IntsOff)

            {

                IntMasterEnable();

            }

            break;

 

        //

        // Return the current serial communication parameters.

        //

        case USBD_CDC_EVENT_GET_LINE_CODING:

            GetLineCoding(pvMsgData);

            break;

 

        //

        // Set the current serial communication parameters.

        //

        case USBD_CDC_EVENT_SET_LINE_CODING:

            SetLineCoding(pvMsgData);

            break;

 

        //

        // Set the current serial communication parameters.

        //

        case USBD_CDC_EVENT_SET_CONTROL_LINE_STATE:

            SetControlLineState((uint16_t)ui32MsgValue);

            break;

 

        //

        // Send a break condition on the serial line.

        //

        case USBD_CDC_EVENT_SEND_BREAK:

            SendBreak(true);

            break;

 

        //

        // Clear the break condition on the serial line.

        //

        case USBD_CDC_EVENT_CLEAR_BREAK:

            SendBreak(false);

            break;

 

        //

        // Ignore SUSPEND and RESUME for now.

        //

        case USB_EVENT_SUSPEND:

        case USB_EVENT_RESUME:

            break;

 

        //

        // We don't expect to receive any other events.  Ignore any that show

        // up in a release build or hang in a debug build.

        //

        default:

#ifdef DEBUG

            while(1);

#else

            break;

#endif

 

    }

 

    return(0);

}

 

//*****************************************************************************

//

// Handles CDC driver notifications related to the transmit channel (data to

// the USB host).

//

// \param pvCBData is the client-supplied callback pointer for this channel.

// \param ui32Event identifies the event we are being notified about.

// \param ui32MsgValue is an event-specific value.

// \param pvMsgData is an event-specific pointer.

//

// This function is called by the CDC driver to notify us of any events

// related to operation of the transmit data channel (the IN channel carrying

// data to the USB host).

//

// \return The return value is event-specific.

//

//*****************************************************************************

uint32_t

TxHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue,

          void *pvMsgData)

{

    //

    // Which event have we been sent?

    //

    switch(ui32Event)

    {

        case USB_EVENT_TX_COMPLETE:

            //

            // Since we are using the USBBuffer, we don't need to do anything

            // here.

            //

            break;

 

        //

        // We don't expect to receive any other events.  Ignore any that show

        // up in a release build or hang in a debug build.

        //

        default:

#ifdef DEBUG

            while(1);

#else

            break;

#endif

 

    }

    return(0);

}

 

//*****************************************************************************

//

// Handles CDC driver notifications related to the receive channel (data from

// the USB host).

//

// \param pvCBData is the client-supplied callback data value for this channel.

// \param ui32Event identifies the event we are being notified about.

// \param ui32MsgValue is an event-specific value.

// \param pvMsgData is an event-specific pointer.

//

// This function is called by the CDC driver to notify us of any events

// related to operation of the receive data channel (the OUT channel carrying

// data from the USB host).

//

// \return The return value is event-specific.

//

//*****************************************************************************

uint32_t

RxHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue,

          void *pvMsgData)

{

    uint32_t ui32Count;

 

    //

    // Which event are we being sent?

    //

    switch(ui32Event)

    {

        //

        // A new packet has been received.

        //

        case USB_EVENT_RX_AVAILABLE:

        {

            //

            // Feed some characters into the UART TX FIFO and enable the

            // interrupt so we are told when there is more space.

            //

            USBUARTPrimeTransmit(USB_UART_BASE);

            UARTIntEnable(USB_UART_BASE, UART_INT_TXRDY);

            break;

        }

 

        //

        // We are being asked how much unprocessed data we have still to

        // process. We return 0 if the UART is currently idle or 1 if it is

        // in the process of transmitting something. The actual number of

        // bytes in the UART FIFO is not important here, merely whether or

        // not everything previously sent to us has been transmitted.

        //

        case USB_EVENT_DATA_REMAINING:

        {

            //

            // Get the number of bytes in the buffer and add 1 if some data

            // still has to clear the transmitter.

            //

            ui32Count = UARTBusy(USB_UART_BASE) ? 1 : 0;

            return(ui32Count);

        }

 

        //

        // We are being asked to provide a buffer into which the next packet

        // can be read. We do not support this mode of receiving data so let

        // the driver know by returning 0. The CDC driver should not be sending

        // this message but this is included just for illustration and

        // completeness.

        //

        case USB_EVENT_REQUEST_BUFFER:

        {

            return(0);

        }

 

        //

        // We don't expect to receive any other events.  Ignore any that show

        // up in a release build or hang in a debug build.

        //

        default:

#ifdef DEBUG

            while(1);

#else

            break;

#endif

    }

 

    return(0);

}

 

//*****************************************************************************

//

// This is the main application entry function.

//

//*****************************************************************************

int

main(void)

{

    uint32_t ui32TxCount;

    uint32_t ui32RxCount;

    char pcBuffer[16];

    volatile uint32_t ui32Fullness;

 

#ifdef _FLASH

// Copy time critical code and Flash setup code to RAM

// This includes the following functions:  InitFlash();

// The  RamfuncsLoadStart, RamfuncsLoadSize, and RamfuncsRunStart

// symbols are created by the linker. Refer to the device .cmd file.

    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);

#endif

 

    //

    // Set the clocking to run from the PLL at 50MHz

    //

    SysCtlClockSet(SYSCTL_OSCSRC_XTAL | SYSCTL_PLL_ENABLE | SYSCTL_IMULT(20) |

                   SYSCTL_SYSDIV(2));

    SysCtlAuxClockSet(SYSCTL_OSCSRC_XTAL | SYSCTL_PLL_ENABLE |

                      SYSCTL_IMULT(12) | SYSCTL_SYSDIV(4));

 

#ifdef _FLASH

// Call Flash Initialization to setup flash waitstates

// This function must reside in RAM

    InitFlash();

#endif

 

    //

    // Initialize interrupt controller and vector table

    //

    InitPieCtrl();

    InitPieVectTable();

 

    //

    // Configure the required pins for USB operation.

    //

    USBGPIOEnable();

    USBIntRegister(USB0_BASE, f28x_USB0DeviceIntHandler);

 

    //

    // Not configured initially.

    //

    g_bUSBConfigured = false;

 

    //

    // Enable the UART that we will be redirecting.

    //

    SysCtlPeripheralEnable(USB_UART_PERIPH);

 

    //

    // Configure GPIO Pins for UART mode.

    //

    EALLOW;

    GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1;

    GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0;

    GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3;

    GpioCtrlRegs.GPADIR.bit.GPIO28 = 0;

 

    GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 1;

    GpioCtrlRegs.GPAPUD.bit.GPIO29 = 0;

    GpioCtrlRegs.GPADIR.bit.GPIO29 = 1;

    EDIS;

 

    //

    // TODO: Add code to configure handshake GPIOs if required.

    //

 

    //

    // Set the default UART configuration.

    //

    UARTConfigSetExpClk(USB_UART_BASE, SysCtlLowSpeedClockGet(SYSTEM_CLOCK_SPEED),

                            DEFAULT_BIT_RATE, DEFAULT_UART_CONFIG);

    UARTFIFOIntLevelSet(USB_UART_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);

 

    //

    // Configure and enable UART interrupts.

    //

    UARTIntClear(USB_UART_BASE, UARTIntStatus(USB_UART_BASE, false));

       UARTIntEnable(USB_UART_BASE, (UART_INT_RXERR | UART_INT_RXRDY_BRKDT |

                                  UART_INT_TXRDY ));

       UARTTXIntRegister(USB_UART_BASE, USBUARTTXIntHandler);

       UARTRXIntRegister(USB_UART_BASE, USBUARTRXIntHandler);

 

    //

    // Enable the system tick.

    //

    SysTickInit();

    SysTickPeriodSet(SysCtlClockGet(SYSTEM_CLOCK_SPEED) / SYSTICKS_PER_SECOND);

    SysTickIntRegister(SysTickIntHandler);

    SysTickIntEnable();

    SysTickEnable();

 

    //

    // Initialize the transmit and receive buffers.

    //

    USBBufferInit(&g_sTxBuffer);

    USBBufferInit(&g_sRxBuffer);

 

    //

    // Set the USB stack mode to Device mode with VBUS monitoring.

    //

    USBStackModeSet(0, eUSBModeForceDevice, 0);

 

    //

    // Pass our device information to the USB library and place the device

    // on the bus.

    //

    USBDCDCInit(0, &g_sCDCDevice);

 

    //

    // Clear our local byte counters.

    //

    ui32RxCount = 0;

    ui32TxCount = 0;

 

    //

    // Enable interrupts now that the application is ready to start.

    //

    IntEnable(USB_UART_INT);

    IntMasterEnable();

 

    //

    // Main application loop.

    //

    while(1)

    {

        //

        // Have we been asked to update the status display?

        //

        if(g_ui32Flags & COMMAND_STATUS_UPDATE)

        {

            //

            // Clear the command flag

            //

            IntMasterDisable();

            g_ui32Flags &= ~COMMAND_STATUS_UPDATE;

            IntMasterEnable();

        }

 

        //

        // Has there been any transmit traffic since we last checked?

        //

        if(ui32TxCount != g_ui32UARTTxCount)

        {

            //

            // Take a snapshot of the latest transmit count.

            //

            ui32TxCount = g_ui32UARTTxCount;

 

            //

            // Update the display of bytes transmitted by the UART.

            //

            usnprintf(pcBuffer, 16, "%d ", ui32TxCount);

 

            //

            // Update the RX buffer fullness. Remember that the buffers are

            // named relative to the USB whereas the status display is from

            // the UART's perspective. The USB's receive buffer is the UART's

            // transmit buffer.

            //

            ui32Fullness = ((USBBufferDataAvailable(&g_sRxBuffer) * 100) /

                          UART_BUFFER_SIZE);

        }

 

        //

        // Has there been any receive traffic since we last checked?

        //

        if(ui32RxCount != g_ui32UARTRxCount)

        {

            //

            // Take a snapshot of the latest receive count.

            //

            ui32RxCount = g_ui32UARTRxCount;

 

            //

            // Update the display of bytes received by the UART.

            //

            usnprintf(pcBuffer, 16, "%d ", ui32RxCount);

 

            //

            // Update the TX buffer fullness. Remember that the buffers are

            // named relative to the USB whereas the status display is from

            // the UART's perspective. The USB's transmit buffer is the UART's

            // receive buffer.

            //

            ui32Fullness = ((USBBufferDataAvailable(&g_sTxBuffer) * 100) /

                          UART_BUFFER_SIZE);

        }

    }

}

 

//

// End of file

// ]

The mini and micro-USB connectors on the controlCARD are connected to PC via USB. I have made all the configuration settings as instructed in the program and operating using TERA TERM software. But the characters typed in one terminal window is not getting echoed in the other and vice-versa. Please suggest the necessary modifications in the source codes and the Terminal software as well if any changes is necessary in the Control Card switch settings.

Thanks & Regards

Sumanta

          

  • Make sure that on the controlCard SW1 has the UART enabled. Have the right switch of SW1 towards the top of the controlCARD.

    What baud rates are you using?

    sal
  • Hi Sal,

    You are right, the control card SW1 has the UART enabled as we have configured to the PIN28 and 29 which are having UART based Data transfer capability.

    1) The right switch of SW1 is towards the top of the control CARD.

    2) We have made the settings with a Baud rate of 115200.
  • Have you gotten this working yet?

    Are both directions not working? Which direction is not working in the echo-back?

    sal
  • Hi Sal,

    I tried with the source code for the program [usb_dev_serial_cpu01] where I connected 2 different windows of TeraTerm software to each COM ports and on simulating the program observed that no data is getting transferred in either direction between 2 COM ports. Pls suggest regarding the above issue.

    Sumanta
  • I will help you debug it, because this works on my board and my PC.

    When you send characters either way, is the USB interrupt being triggered? You can set a breakpoint in the USB interrupt handler to see if the interrupt is being triggered and serviced.

    sal
  • Hi Sal,

    Thanks for the reply. I am trying to have a data transmission between two serial communication ports which are as below:

    1) Communication Port (COM1) and

    2) USB Serial Port (COM4). But data sending is becoming possible only through COM4 and not via COM1.

    Please suggest.
  • Hi Sal,

    The data transfer is happening from DSP Terminal (Tera Term) to Code Composer Studio as it is getting displayed in Expression Window. But the reverse communication is not happening. Please suggest the possible error.


    Thanks & Regards
    Sumanta
  • Which version in controlSUITE are you using? v_XXX?

    sal
  • Hi Sal,

    I am using Control Suite V3.4.4.
  • sysctl.h

    //###########################################################################
    //
    // FILE:   sysctl.c
    //
    // TITLE:  Stellaris style wrapper driver for F2837x system control.
    //
    //###########################################################################
    // $TI Release: $
    // $Release Date: $
    // $Copyright: $
    //###########################################################################
    
    //*****************************************************************************
    //
    //! \addtogroup sysctl_api
    //! @{
    //
    //*****************************************************************************
    
    #include "F28x_Project.h"
    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_types.h"
    #include "driverlib/debug.h"
    #include "driverlib/sysctl.h"
    
    //*****************************************************************************
    //
    //! \internal
    //! Checks a peripheral identifier.
    //!
    //! \param ui32Peripheral is the peripheral identifier.
    //!
    //! This function determines if a peripheral identifier is valid.
    //!
    //! \return Returns \b true if the peripheral identifier is valid and \b false
    //! otherwise.
    //
    //*****************************************************************************
    #ifdef DEBUG
    static bool
    _SysCtlPeripheralValid(uint32_t ui32Peripheral)
    {
        return((ui32Peripheral == SYSCTL_PERIPH_CLA1) ||
               (ui32Peripheral == SYSCTL_PERIPH_DMA) ||
               (ui32Peripheral == SYSCTL_PERIPH_TIMER0) ||
               (ui32Peripheral == SYSCTL_PERIPH_TIMER1) ||
               (ui32Peripheral == SYSCTL_PERIPH_TIMER2) ||
               (ui32Peripheral == SYSCTL_PERIPH_HRPWM) ||
               (ui32Peripheral == SYSCTL_PERIPH_TBCLKSYNC) ||
               (ui32Peripheral == SYSCTL_PERIPH_GTBCLKSYNC) ||
               (ui32Peripheral == SYSCTL_PERIPH_EMIF1) ||
               (ui32Peripheral == SYSCTL_PERIPH_EMIF2) ||
               (ui32Peripheral == SYSCTL_PERIPH_EPWM1) ||
               (ui32Peripheral == SYSCTL_PERIPH_EPWM2) ||
               (ui32Peripheral == SYSCTL_PERIPH_EPWM3) ||
               (ui32Peripheral == SYSCTL_PERIPH_EPWM4) ||
               (ui32Peripheral == SYSCTL_PERIPH_EPWM5) ||
               (ui32Peripheral == SYSCTL_PERIPH_EPWM6) ||
               (ui32Peripheral == SYSCTL_PERIPH_EPWM7) ||
               (ui32Peripheral == SYSCTL_PERIPH_EPWM8) ||
               (ui32Peripheral == SYSCTL_PERIPH_EPWM9) ||
               (ui32Peripheral == SYSCTL_PERIPH_EPWM10) ||
               (ui32Peripheral == SYSCTL_PERIPH_EPWM11) ||
               (ui32Peripheral == SYSCTL_PERIPH_EPWM12) ||
               (ui32Peripheral == SYSCTL_PERIPH_ECAP1) ||
               (ui32Peripheral == SYSCTL_PERIPH_ECAP2) ||
               (ui32Peripheral == SYSCTL_PERIPH_ECAP3) ||
               (ui32Peripheral == SYSCTL_PERIPH_ECAP4) ||
               (ui32Peripheral == SYSCTL_PERIPH_ECAP5) ||
               (ui32Peripheral == SYSCTL_PERIPH_ECAP6) ||
               (ui32Peripheral == SYSCTL_PERIPH_EQEP1) ||
               (ui32Peripheral == SYSCTL_PERIPH_EQEP2) ||
               (ui32Peripheral == SYSCTL_PERIPH_EQEP3) ||
               (ui32Peripheral == SYSCTL_PERIPH_SD1) ||
               (ui32Peripheral == SYSCTL_PERIPH_SD2) ||
               (ui32Peripheral == SYSCTL_PERIPH_SCI1) ||
               (ui32Peripheral == SYSCTL_PERIPH_SCI2) ||
               (ui32Peripheral == SYSCTL_PERIPH_SCI3) ||
               (ui32Peripheral == SYSCTL_PERIPH_SCI4) ||
               (ui32Peripheral == SYSCTL_PERIPH_SPI1) ||
               (ui32Peripheral == SYSCTL_PERIPH_SPI2) ||
               (ui32Peripheral == SYSCTL_PERIPH_SPI3) ||
               (ui32Peripheral == SYSCTL_PERIPH_I2C1) ||
               (ui32Peripheral == SYSCTL_PERIPH_I2C2) ||
               (ui32Peripheral == SYSCTL_PERIPH_CAN1) ||
               (ui32Peripheral == SYSCTL_PERIPH_CAN2) ||
               (ui32Peripheral == SYSCTL_PERIPH_MCBSP1) ||
               (ui32Peripheral == SYSCTL_PERIPH_MCBSP2) ||
               (ui32Peripheral == SYSCTL_PERIPH_UPP1) ||
               (ui32Peripheral == SYSCTL_PERIPH_ADC1) ||
               (ui32Peripheral == SYSCTL_PERIPH_ADC2) ||
               (ui32Peripheral == SYSCTL_PERIPH_ADC3) ||
               (ui32Peripheral == SYSCTL_PERIPH_ADC4) ||
               (ui32Peripheral == SYSCTL_PERIPH_CMPSS1) ||
               (ui32Peripheral == SYSCTL_PERIPH_CMPSS2) ||
               (ui32Peripheral == SYSCTL_PERIPH_CMPSS3) ||
               (ui32Peripheral == SYSCTL_PERIPH_CMPSS4) ||
               (ui32Peripheral == SYSCTL_PERIPH_CMPSS5) ||
               (ui32Peripheral == SYSCTL_PERIPH_CMPSS6) ||
               (ui32Peripheral == SYSCTL_PERIPH_CMPSS7) ||
               (ui32Peripheral == SYSCTL_PERIPH_CMPSS8) ||
               (ui32Peripheral == SYSCTL_PERIPH_BUFFDAC1) ||
               (ui32Peripheral == SYSCTL_PERIPH_BUFFDAC2) ||
               (ui32Peripheral == SYSCTL_PERIPH_BUFFDAC3));
    }
    #endif
    
    
    
    //*****************************************************************************
    //
    //! Determines if a peripheral is present.
    //!
    //! \param ui32Peripheral is the peripheral in question.
    //!
    //! This function determines if a particular peripheral is present in the
    //! device.  Each member of the family has a different peripheral
    //! set; this function determines which peripherals are present on this device.
    //!
    //! \return Returns \b true if the specified peripheral is present and \b false
    //! if it is not.
    //
    //*****************************************************************************
    bool
    SysCtlPeripheralPresent(uint32_t ui32Peripheral)
    {
    
        uint16_t regIndex;
        uint16_t bitIndex;
    
        //
        // Check the arguments.
        //
        ASSERT(_SysCtlPeripheralValid(ui32Peripheral));
    
    
        regIndex = ui32Peripheral & SYSCTL_PERIPH_REG_M;
        bitIndex = (ui32Peripheral & SYSCTL_PERIPH_BIT_M) >> SYSCTL_PERIPH_BIT_S;
    
        if(HWREG(&(DevCfgRegs.DC0.all) + (2 * regIndex)) & (1 << bitIndex)){
            return true;
        }else{
            return false;
        }
    
    
    }
    
    //*****************************************************************************
    //
    //! Determines if a peripheral is ready.
    //!
    //! \param ui32Peripheral is the peripheral in question.
    //!
    //! This function determines if a particular peripheral is ready to be
    //! accessed.  The peripheral may be in a non-ready state if it is not enabled,
    //! is being held in reset, or is in the process of becoming ready after being
    //! enabled or taken out of reset.
    //!
    //! \note The ability to check for a peripheral being ready varies based on the
    //! part in use.  Please consult the data sheet for the part you are
    //! using to determine if this feature is available.
    //!
    //! \return Returns \b true if the specified peripheral is ready and \b false
    //! if it is not.
    //
    //*****************************************************************************
    bool
    SysCtlPeripheralReady(uint32_t ui32Peripheral)
    {
    
        uint16_t regIndex;
        uint16_t bitIndex;
    
        //
        // Check the arguments.
        //
        ASSERT(_SysCtlPeripheralValid(ui32Peripheral));
    
    
        regIndex = ui32Peripheral & SYSCTL_PERIPH_REG_M;
        bitIndex = (ui32Peripheral & SYSCTL_PERIPH_BIT_M) >> SYSCTL_PERIPH_BIT_S;
    
        // Is the peripheral there?
        if(HWREG((uint32_t)&(DevCfgRegs.DC0.all) + (2 * regIndex)) & ((uint32_t)1 << bitIndex)){
            // Is the peripheral enabled?
            if(HWREG((uint32_t)&(CpuSysRegs.PCLKCR0.all) + (2 * regIndex)) & ((uint32_t)1 << bitIndex)){
                // Is the peripheral in reset?
                if((HWREG((uint32_t)&(DevCfgRegs.SOFTPRES0.all) + (2 * regIndex)) & ((uint32_t)1 << bitIndex)) == 0){
                    // No?  Ok cool
                    return true;
                }
            }
        }else{
            return false;
        }
    
        return false;
    }
    //*****************************************************************************
    //
    //! Resets a peripheral
    //!
    //! \param ui32Peripheral is the peripheral to reset.
    //!
    //! The f2837x devices do not have a means of resetting peripherals via
    //! via software.  This is a dummy function that does nothing.
    //!
    //!
    //! \return None.
    //
    //*****************************************************************************
    void SysCtlPeripheralReset(uint32_t ui32Peripheral)
    {
        uint16_t regIndex;
        uint16_t bitIndex;
    
        regIndex = ui32Peripheral & SYSCTL_PERIPH_REG_M;
        bitIndex = (ui32Peripheral & SYSCTL_PERIPH_BIT_M) >> SYSCTL_PERIPH_BIT_S;
    
        EALLOW;
    
        HWREG((uint32_t)&(DevCfgRegs.SOFTPRES0.all) + (2 * regIndex)) |= ((uint32_t)1 << bitIndex);
        asm(" nop");
        asm(" nop");
        asm(" nop");
        asm(" nop");
        HWREG((uint32_t)&(DevCfgRegs.SOFTPRES0.all) + (2 * regIndex)) &= ~((uint32_t)1 << bitIndex);
        EDIS;
    }
    
    //*****************************************************************************
    //
    //! Enables a peripheral.
    //!
    //! \param ui32Peripheral is the peripheral to enable.
    //!
    //! Peripherals are enabled with this function.  At power-up, all peripherals
    //! are disabled; they must be enabled in order to operate or respond to
    //! register reads/writes.
    //!
    //! The \e ui32Peripheral parameter must be only one of the following values:
    //! \b SYSCTL_PERIPH_UART_A, \b SYSCTL_PERIPH_UART_B, \b SYSCTL_PERIPH_UART_C,
    //! \b SYSCTL_PERIPH_UART_D, \b SYSCTL_PERIPH_SPI_A, \b SYSCTL_PERIPH_SPI_B,
    //! \b SYSCTL_PERIPH_SPI_C, \b SYSCTL_PERIPH_MCBSP_A, \b SYSCTL_PERIPH_MCBSP_B,
    //! \b SYSCTL_PERIPH_DMA, \b SYSCTL_PERIPH_USB_A
    //!
    //! \return None.
    //
    //*****************************************************************************
    void
    SysCtlPeripheralEnable(uint32_t ui32Peripheral)
    {
        uint16_t regIndex;
        uint16_t bitIndex;
        volatile uint32_t test1, test2, test3, test4;
    
        regIndex = (ui32Peripheral & SYSCTL_PERIPH_REG_M);
        bitIndex = (ui32Peripheral & SYSCTL_PERIPH_BIT_M) >> SYSCTL_PERIPH_BIT_S;
    
        EALLOW;
        HWREG((uint32_t)&(CpuSysRegs.PCLKCR0.all) + (2 * regIndex)) |= ((uint32_t)1 << bitIndex);
    
        EDIS;
    }
    
    //*****************************************************************************
    //
    //! Disables a peripheral.
    //!
    //! \param ui32Peripheral is the peripheral to disable.
    //!
    //! Peripherals are disabled with this function.  Once disabled, they will not
    //! operate or respond to register reads/writes.
    //!
    //! The \e ui32Peripheral parameter must be only one of the following values:
    //! \b SYSCTL_PERIPH_UART_A, \b SYSCTL_PERIPH_UART_B, \b SYSCTL_PERIPH_UART_C,
    //! \b SYSCTL_PERIPH_UART_D, \b SYSCTL_PERIPH_SPI_A, \b SYSCTL_PERIPH_SPI_B,
    //! \b SYSCTL_PERIPH_SPI_C, \b SYSCTL_PERIPH_MCBSP_A, \b SYSCTL_PERIPH_MCBSP_B,
    //! \b SYSCTL_PERIPH_DMA, \b SYSCTL_PERIPH_USB_A
    //!
    //! \return None.
    //
    //*****************************************************************************
    void
    SysCtlPeripheralDisable(uint32_t ui32Peripheral)
    {
        uint16_t regIndex;
        uint16_t bitIndex;
    
        regIndex = ui32Peripheral & SYSCTL_PERIPH_REG_M;
        bitIndex = (ui32Peripheral & SYSCTL_PERIPH_BIT_M) >> SYSCTL_PERIPH_BIT_S;
    
        EALLOW;
    
        HWREG((uint32_t)&(CpuSysRegs.PCLKCR0.all) + (2 * regIndex)) &= ~((uint32_t)1 << bitIndex);
    
        EDIS;
    }
    
    //*****************************************************************************
    //
    //! Resets the device.
    //!
    //! This function performs a software reset of the entire device.  The
    //! processor and all peripherals are reset and all device registers are
    //! returned to their default values (with the exception of the reset cause
    //! register, which maintains its current value but has the software reset
    //! bit set as well).
    //!
    //! \return This function does not return.
    //
    //*****************************************************************************
    void
    SysCtlReset(void)
    {
        //
        // Write an incorrect check value to the watchdog control register
        // This will cause a device reset
        //
        EALLOW;
        // Enable the watchdog
        HWREG(&(WdRegs.WDCR.all)) = 0x0028;
        // Write a bad check value
        HWREG(&(WdRegs.WDCR.all)) = 0xFFFF;
        EDIS;
    
        //
        // The device should have reset, so this should never be reached.  Just in
        // case, loop forever.
        //
        while(1)
        {
        }
    }
    
    
    //*****************************************************************************
    //
    //! Provides a small delay.
    //!
    //! \param ulCount is the number of delay loop iterations to perform.
    //!
    //! This function provides a means of generating a constant length delay.  It
    //! is written in assembly to keep the delay consistent across tool chains,
    //! avoiding the need to tune the delay based on the tool chain in use.
    //!
    //! The loop takes 5 cycles/loop + 9.
    //!
    //! \return None.
    //
    //*****************************************************************************
    #ifdef __TI_COMPILER_VERSION__
        #if __TI_COMPILER_VERSION__ >= 15009000
        __asm(" .def _SysCtlDelay\n"
              " .sect \".TI.ramfunc\"\n"
              " .global  _SysCtlDelay\n"
              "_SysCtlDelay:\n"
              " SUB    ACC,#1\n"
              " BF     _SysCtlDelay,GEQ\n"
              " LRETR\n");    
        #else
        __asm(" .def _SysCtlDelay\n"
              " .sect \"ramfuncs\"\n"
              " .global  _SysCtlDelay\n"
              "_SysCtlDelay:\n"
              " SUB    ACC,#1\n"
              " BF     _SysCtlDelay,GEQ\n"
              " LRETR\n");        
        #endif
    #endif
    
    //*****************************************************************************
    //
    //! Gets the processor clock rate.
    //!
    //! This function determines the clock rate of the processor clock.
    //!
    //! \note Because of the many different clocking options available, this
    //!  function cannot determine the clock speed of the processor.  This function
    //!  should be modified to return the actual clock speed of the processor in
    //!  your specific application.
    //!
    //! \return The processor clock rate.
    //
    //*****************************************************************************
    uint32_t
    SysCtlClockGet(uint32_t u32ClockIn)
    {
    
        if((ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL == 0) ||
                (ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL == 2)){
            //10MHz Internal Clock
            u32ClockIn = 10000000;
        }
    
        //If the pll is enabled calculate its effect on the clock
    //    if((HWREG(SYSCTL_SYSPLLCTL) &
    //        (SYSCTL_SYSPLLCTL_SPLLEN | SYSCTL_SYSPLLCTL_SPLLCLKEN)) == 3)
        if(ClkCfgRegs.SYSPLLCTL1.bit.PLLEN && ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN)
        {
            //Calculate integer multiplier and fixed divide by 2
    //        ulClockIn = ulClockIn *
    //                    (HWREG(SYSCTL_SYSPLLMULT) & SYSCTL_SYSPLLMULT_SPLLIMULT_M);
            u32ClockIn = u32ClockIn * ClkCfgRegs.SYSPLLMULT.bit.IMULT;
    
    
            //Calculate fractional multiplier
    //        switch((HWREG(SYSCTL_SYSPLLMULT) & SYSCTL_SYSPLLMULT_SPLLFMULT_M) >>
    //                SYSCTL_SYSPLLMULT_SPLLFMULT_S)
            switch(ClkCfgRegs.SYSPLLMULT.bit.FMULT)
            {
            default:
            case 0:
                break;
    
            case 1:
                u32ClockIn += u32ClockIn / 4;
                break;
    
            case 2:
                u32ClockIn += u32ClockIn / 2;
                break;
    
            case 3:
                u32ClockIn += (u32ClockIn * 3) / 4;
                break;
            }
        }
    
        if(ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV != 0){
            u32ClockIn /= (2 * ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV);
        }
    
        return u32ClockIn;
    
    }
    
    //*****************************************************************************
    //
    //! Gets the low speed peripheral clock rate.
    //!
    //! This function determines the clock rate of the low speed peripherals.
    //!
    //! \note Because of the many different clocking options available, this
    //!  function cannot determine the clock speed of the processor.  This function
    //!  should be modified to return the actual clock speed of the processor in
    //!  your specific application.
    //!
    //! \return The low speed peripheral clock rate.
    //
    //*****************************************************************************
    uint32_t
    SysCtlLowSpeedClockGet(uint32_t u32ClockIn)
    {
    
        // Get the main system clock
        u32ClockIn = SysCtlClockGet(u32ClockIn);
    
        // Apply the divider to the main clock
        if(ClkCfgRegs.LOSPCP.bit.LSPCLKDIV != 0){
            u32ClockIn /= (2 * ClkCfgRegs.LOSPCP.bit.LSPCLKDIV);
        }
    
        return u32ClockIn;
    
    }
    
    //*****************************************************************************
    //
    //! Sets the clocking of the device.
    //!
    //! \param ui32Config is the required configuration of the device clocking.
    //!
    //! This function configures the clocking of the device.  The oscillator to be 
    //! used, SYSPLL fractional and integer multiplier, and the system clock
    //! divider are all configured with this function.
    //!
    //! The \e ui32Config parameter is the logical OR of four values:
    //! Clock divider, Integer multiplier, Fractional multiplier, and oscillator
    //! source. 
    //!
    //! The system clock divider is chosen with using the following macro:
    //! \b SYSCTL_SYSDIV(x) - "x" is an integer of value 1 or any even value
    //!                       up to 126
    //!
    //! The System PLL fractional multiplier is chosen with one of the following 
    //! values:
    //! \b SYSCTL_FMULT_0, \b SYSCTL_FMULT_1_4, \b SYSCTL_FMULT_1_2,
    //! \b SYSCTL_FMULT_3_4
    //!
    //! The System PLL integer multiplier is chosen with using the following macro:
    //! \b SYSCTL_IMULT(x) - "x" is an integer from 0 to 127
    //!
    //! The oscillator source is chosen with one of the following values:
    //! \b SYSCTL_OSCSRC_OSC2, \b SYSCTL_OSCSRC_XTAL, \b SYSCTL_OSCSRC_OSC1
    //!
    //! \note The external oscillator must be enabled in order to use an external 
    //! clock source.  Note that attempts to disable the oscillator used to clock 
    //! the device is prevented by the hardware.
    //!
    //! \return None.
    //
    //*****************************************************************************
    void
    SysCtlClockSet(uint32_t ui32Config)
    {
        uint32_t clock_source = (ui32Config & SYSCTL_OSCSRC_M) >> SYSCTL_OSCSRC_S;
        uint32_t imult = (ui32Config & SYSCTL_IMULT_M);
        uint32_t fmult = (ui32Config & SYSCTL_FMULT_M) >> SYSCTL_FMULT_S;
        uint32_t divsel = (ui32Config & SYSCTL_SYSDIV_M) >> SYSCTL_SYSDIV_S;
        
        if((clock_source == ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL)    &&
          (imult         == ClkCfgRegs.SYSPLLMULT.bit.IMULT)           &&
          (fmult         == ClkCfgRegs.SYSPLLMULT.bit.FMULT)           &&
          (divsel        == ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV))
        {
            //everything is set as required, so just return
            return;
        }    
     
        if(clock_source != ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL)
        {
            //Configure Oscillator
            EALLOW;
            switch (clock_source)
            {
                case ((uint32_t)SYSCTL_OSCSRC_OSC2 >> SYSCTL_OSCSRC_S):
                    ClkCfgRegs.CLKSRCCTL1.bit.INTOSC2OFF=0;     // Turn on INTOSC2
                    ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 0; // Clk Src = INTOSC2
    				ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=1;        // Turn off XTALOSC
                    break;
    
                case ((uint32_t)SYSCTL_OSCSRC_XTAL >> SYSCTL_OSCSRC_S):
                    ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=0;        // Turn on XTALOSC
                    ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 1; // Clk Src = XTAL
                    break;
    
                case ((uint32_t)SYSCTL_OSCSRC_OSC1 >> SYSCTL_OSCSRC_S):
                    ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 2; // Clk Src = INTOSC1
    				ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=1;        // Turn off XTALOSC
                    break;
            }
            EDIS; 
        }
        
        EALLOW;
        // first modify the PLL multipliers
        if(imult != ClkCfgRegs.SYSPLLMULT.bit.IMULT || 
           fmult != ClkCfgRegs.SYSPLLMULT.bit.FMULT)
        {
            // Bypass PLL and set dividers to /1
            ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0;
            ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = 0;
    
            // Program PLL multipliers
            uint32_t temp_syspllmult = ClkCfgRegs.SYSPLLMULT.all;
            ClkCfgRegs.SYSPLLMULT.all = ((temp_syspllmult & ~(0x37FU)) | 
                                         ((fmult << 8U) | imult));
                   
            ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 1;            // Enable SYSPLL
    
            // Wait for the SYSPLL lock
            while(ClkCfgRegs.SYSPLLSTS.bit.LOCKS != 1)
            {
                // Uncomment to service the watchdog
                //WdRegs.WDKEY.bit.WDKEY = 0x0055;
                //WdRegs.WDKEY.bit.WDKEY = 0x00AA;
            }
    
            // Write a multiplier again to ensure proper PLL initialization
            // This will force the PLL to lock a second time
            ClkCfgRegs.SYSPLLMULT.bit.IMULT = imult;        // Setting integer multiplier
    
            // Wait for the SYSPLL re-lock
            while(ClkCfgRegs.SYSPLLSTS.bit.LOCKS != 1)
            {
                // Uncomment to service the watchdog
                //WdRegs.WDKEY.bit.WDKEY = 0x0055;
                //WdRegs.WDKEY.bit.WDKEY = 0x00AA;
            }        
        }
        
        // Set divider to produce slower output frequency to limit current increase
        if(divsel != (126/2))
        {
            ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = divsel + 1;
        }
        else
        {
            ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = divsel;
        } 
    
        // Enable PLLSYSCLK is fed from system PLL clock
        ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 1;
    
        // Small 100 cycle delay
        asm(" RPT #100 || NOP");
    
        // Set the divider to user value
        ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = divsel;    
    
        EDIS;
    }
    
    //*****************************************************************************
    //
    //! Sets the clocking of the device.
    //!
    //! \param ui32Config is the required configuration of the device clocking.
    //!
    //! This function configures the clocking of the device.  The input crystal
    //! frequency, oscillator to be used, use of the PLL, and the system clock
    //! divider are all configured with this function.
    //!
    //! The \e ui32Config parameter is the logical OR of several different values,
    //! many of which are grouped into sets where only one can be chosen.
    //!
    //! The system clock divider is chosen with one of the following values:
    //! \b SYSCTL_SYSDIV_1, \b SYSCTL_SYSDIV_2, \b SYSCTL_SYSDIV_3, ...
    //! \b SYSCTL_SYSDIV_64.
    //!
    //! The use of the PLL is chosen with either \b SYSCTL_USE_PLL or
    //! \b SYSCTL_USE_OSC.
    //!
    //! The external crystal frequency is chosen with one of the following values:
    //! \b SYSCTL_XTAL_4MHZ, \b SYSCTL_XTAL_4_09MHZ, \b SYSCTL_XTAL_4_91MHZ,
    //! \b SYSCTL_XTAL_5MHZ, \b SYSCTL_XTAL_5_12MHZ, \b SYSCTL_XTAL_6MHZ,
    //! \b SYSCTL_XTAL_6_14MHZ, \b SYSCTL_XTAL_7_37MHZ, \b SYSCTL_XTAL_8MHZ,
    //! \b SYSCTL_XTAL_8_19MHZ, \b SYSCTL_XTAL_10MHZ, \b SYSCTL_XTAL_12MHZ,
    //! \b SYSCTL_XTAL_12_2MHZ, \b SYSCTL_XTAL_13_5MHZ, \b SYSCTL_XTAL_14_3MHZ,
    //! \b SYSCTL_XTAL_16MHZ, \b SYSCTL_XTAL_16_3MHZ, \b SYSCTL_XTAL_18MHZ,
    //! \b SYSCTL_XTAL_20MHZ, \b SYSCTL_XTAL_24MHZ, or \b SYSCTL_XTAL_25MHz.
    //! Values below \b SYSCTL_XTAL_5MHZ are not valid when the PLL is in
    //! operation.
    //!
    //! The oscillator source is chosen with one of the following values:
    //! \b SYSCTL_OSC_MAIN, \b SYSCTL_OSC_INT, \b SYSCTL_OSC_INT4,
    //! \b SYSCTL_OSC_INT30, or \b SYSCTL_OSC_EXT32.  \b SYSCTL_OSC_EXT32 is only
    //! available on devices with the hibernate module, and then only when the
    //! hibernate module has been enabled.
    //!
    //! The internal and main oscillators are disabled with the
    //! \b SYSCTL_INT_OSC_DIS and \b SYSCTL_MAIN_OSC_DIS flags, respectively.
    //! The external oscillator must be enabled in order to use an external clock
    //! source.  Note that attempts to disable the oscillator used to clock the
    //! device is prevented by the hardware.
    //!
    //! To clock the system from an external source (such as an external crystal
    //! oscillator), use \b SYSCTL_USE_OSC \b | \b SYSCTL_OSC_MAIN.  To clock the
    //! system from the main oscillator, use \b SYSCTL_USE_OSC \b |
    //! \b SYSCTL_OSC_MAIN.  To clock the system from the PLL, use
    //! \b SYSCTL_USE_PLL \b | \b SYSCTL_OSC_MAIN, and select the appropriate
    //! crystal with one of the \b SYSCTL_XTAL_xxx values.
    //!
    //! \note If selecting the PLL as the system clock source (that is, via
    //! \b SYSCTL_USE_PLL), this function polls the PLL lock interrupt to
    //! determine when the PLL has locked.  If an interrupt handler for the
    //! system control interrupt is in place, and it responds to and clears the
    //! PLL lock interrupt, this function delays until its timeout has occurred
    //! instead of completing as soon as PLL lock is achieved.
    //!
    //! \return None.
    //
    //*****************************************************************************
    void
    SysCtlAuxClockSet(uint32_t ui32Config)
    {
        uint16_t ui16TempDivsel;
    
        //Bypass PLL
        //Ensure the PLL is out of our clock tree
        EALLOW;
        ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 0;
        EDIS;
    
        __asm( " RPT #255 || NOP");
    
        //Configure Oscillator
        EALLOW;
        switch (ui32Config & SYSCTL_OSCSRC_M)
        {
            default:
            case SYSCTL_OSCSRC_OSC2:
                ClkCfgRegs.CLKSRCCTL1.bit.INTOSC2OFF=0;     // Turn on INTOSC2
                ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 0; // Clk Src = INTOSC2
    			ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=1;        // Turn off XTALOSC
                break;
    
            case SYSCTL_OSCSRC_XTAL:
                ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=0;        // Turn on XTALOSC
                ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 1; // Clk Src = XTAL
                break;
    
            case SYSCTL_OSCSRC_OSC1:
                ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 2; // Clk Src = INTOSC1
    			ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=1;        // Turn off XTALOSC
                break;
    
        }
        EDIS;
    
        __asm( " RPT #255 || NOP");
    
        //Configure PLL if enabled
        if(ui32Config & SYSCTL_PLL_ENABLE)
        {
            EALLOW;
            //modify dividers to maximum to reduce the inrush current
            //set the integer fractional multipliers in one single write
            ClkCfgRegs.AUXPLLMULT.all = ((ui32Config & SYSCTL_IMULT_M) >> SYSCTL_IMULT_S) |
            		                    (((ui32Config & SYSCTL_FMULT_M) >> SYSCTL_FMULT_S) << 8);
            EDIS;
    
            __asm( " RPT #255 || NOP");
    
            //Wait for the SYSPLL lock
            while(ClkCfgRegs.AUXPLLSTS.bit.LOCKS != 1)
            {
                // Uncomment to service the watchdog
                // ServiceDog();
            }
        }
    
        //Configure Dividers
        //increase the freq. of operation in steps to avoid any VDD fluctuations
        ui16TempDivsel = 3;
        while(ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV != ((ui32Config & SYSCTL_SYSDIV_M) >> SYSCTL_SYSDIV_S))
        {
            EALLOW;
            ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV = ui16TempDivsel;
            EDIS;
            ui16TempDivsel -= 1;
            if(ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV != ((ui32Config & SYSCTL_SYSDIV_M) >> SYSCTL_SYSDIV_S))
            {
                SysCtlDelay(15);
            }
        }
    
        //Enable PLLSYSCLK is fed from system PLL clock
        EALLOW;
        ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 1;
        EDIS;
    }
    
    //*****************************************************************************
    //
    //! Powers up the USB PLL.
    //!
    //! This function will enable the USB controller's PLL.
    //!
    //! \note Because every application is different, the user will likely have to
    //! modify this function to ensure the PLL multiplier is set correctly to
    //! achieve the 60 MHz required by the USB controller.
    //!
    //! \return None.
    //
    //*****************************************************************************
    void
    SysCtlUSBPLLEnable(void)
    {
    //    // Turn on INTOSC2
    //    ClkCfgRegs.CLKSRCCTL1.bit.INTOSC2OFF=0;
    //    //Select INTOSC2 as USB PLL Clk In
    //    ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 0;
    //    // Set Aux PLL divider
    //    ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV = 1;
    //    // Set Aux PLL multiplier
    //    ClkCfgRegs.AUXPLLMULT.bit.IMULT = 12;
    //    // Set Aux PLL fractional multiplier to 0.0
    //  ClkCfgRegs.AUXPLLMULT.bit.FMULT = 0;
    //    //Enable AUXPLL
    //  ClkCfgRegs.AUXPLLCTL1.bit.PLLEN = 1;
    //
    //    //Wait for the AUXPLL lock
    //  while(ClkCfgRegs.AUXPLLSTS.bit.LOCKS != 1)
    //  {
    //      // Uncomment to service the watchdog
    //      // ServiceDog();
    //  }
    //    // AUXPLLCLK is fed from the AUXPLL
    //  ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 1;
    
    }
    
    //*****************************************************************************
    //
    //! Powers down the USB PLL.
    //!
    //! This function will disable the USB controller's PLL.  The USB registers
    //! are still accessible, but the physical layer will no longer function.
    //!
    //! \return None.
    //
    //*****************************************************************************
    void
    SysCtlUSBPLLDisable(void)
    {
        //Disable the PLL
    //    ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 0;
    }
    
    //*****************************************************************************
    //
    // Close the Doxygen group.
    //! @}
    //
    //*****************************************************************************
    
    
    
    Can you update these files and see if this works?

    sal

  • Hi Sal,

    I am not able to locate the particular file (sysctl.hsysctl.c) inside installed control suite in location (C:\ti2_ctrlsuite3.4.4). Please specify the probable location and process of upgradation for the same file.


    Thanks & Regards
    Sumanta
  • Hi,

    Please find them at this location.

    C:\ti\controlSUITE\device_support\F2837xD\v210\F2837xD_common\driverlib

    Can you use XCLKOUT and please let me know what the frequencies of SYSCLK and AUXCLK are?

    Regards,
    sal
  • Hi Sal, Actually I got the file (sysctl.c) and (sysctl.h) but not finding the way for its updation. Pls suggest.
  • Hi Sumanta,

    I am not sure what the issue is?

    The sysctl.h/c files I sent you are an updated version from what you have. Please copy and replace them in the file path I specified above.

    Copy and paste sysctl.h/c into C:\ti\controlSUITE\device_support\F2837xD\v210\F2837xD_common\driverlib


    Regards,
    sal
  • Hi Sumanta,

    Have you gotten this to work?

    sal
  • Hi Sal,

                  I am able to locate the file (hsysctl.c and hsysctl.h) but not able to find its way for updation. Do I need to download those files from Internet, so please fwd the website links if available.

    Pls suggest. 

    Thanks & regards

    Sumanta

  • Please see my post from Jan 13. I inserted the files in my response for you to download.

    Additionally, we have a new software release available now. It is called C2000Ware. It is a replacement of controlSUITE and the files structure is different but better and more intuitive. You will find the same examples and files in this C2000Ware package.

    Here is a link for it. You should also see an E2E forum post about it in a few days.

    Please find it here. www.ti.com/.../c2000ware

    Regards,
    sal
  • Sumanta,

    Have you got this working?

    sal