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.

TMS320F28034: SCI Interrupt Driver

Part Number: TMS320F28034


Hello All,

I am writing a interrupt driven, FIFO ring buffer fed SCI driver for a Matlab Embedded C2000 project.

The Matlab project has one other peripheral interrupt (for CAN RX) and a few timer interrupts. 

Currently, when I enable the PIE interrupts for the SCI TX and RX (lines 212 and 232), I seem to crash my app, preventing other normal external activity such as CAN traffic.

My suspicion is that the interrupts are not clearing, and blocking. 

Given that I based my interrupts on the datasheets and example code, I am struggling to find a difference that cause this issue, and also how to debug it. 

Attached is the current version of my driver (note the TX and RX_INTERRUPT defines are most definitely enabled). 

If anyone could recommend a path forward, I would be most appreciative,

Thank you

Neal O'Hara

sci_drv.h

/*! @file sci_drv.c
 *
 *  $Revision: 1303 $
 *  $Date: 2018-02-15 09:47:58 -0500 (Thu, 15 Feb 2018) $
 *  $Author: abraham_mathew $
 *  $HeadURL: https://emsredmine/svn/p121619/Software/SW_11340_1_APP_Embedded/branches/Sandbox_1122018/C_Functions/sci_drv.c $
 *
 *  @brief
 *           Driver Source Code for the Danfoss Serial Protocol 
 *        
 *  @par
 *
 *  (c) Copyright 2016-2018, LORD Corporation – LORD Confidential and Proprietary
 */

/*******************************************************************************
 ** Includes
 ******************************************************************************/
#include "sci_drv.h"
#include "utils_rb.h"

/*******************************************************************************
** Constants (exported only)
*******************************************************************************/

/*******************************************************************************
** Local Constants 
*******************************************************************************/
#define SCI_FE_PE_MASK    0xC000  //Mask the FIFO Framing & Parity Error Bits
#define SCI_RXFFOVF_MASK  0x2000  //Mask the RXFFOVF bit from RB 16b data
#define SCI_RXFFOVF_SHIFT 13      //Shift RXFFOVF to 13th bit
#define SCI_RXDT_MASK     0x00FF  //Mask the Received Character Bits of SCIRXBUF
#define SCI_TXDT_MASK     0x00FF  //Mask the Transmit Character Bits of SCITXBUF
#define MAX_TX_FIFO_SIZE  0x4     //Max size for the DSP2803x TX FIFO
#define MAX_RX_FIFO_SIZE  0x4     //Max size for the DSP2803x RX FIFO
#define TX_RB_BUF_SIZE    64      //
#define RX_RB_BUF_SIZE    64      //

#define PUT_
/*******************************************************************************
 ** External Global Variables
 ******************************************************************************/
extern Uint16 Drv_Put_Debug_Value;

extern Uint16 Drv_Put_Status;

extern Uint16 Drv_Tx_Isr_Call_Ctr;
extern Uint16 Drv_Put_Call_Ctr;
extern Uint16 Drv_Rx_Isr_Call_Ctr;
extern Uint16 Drv_Read_Call_Ctr;

extern Uint16 Drv_Read_Status;
extern Uint16 Drv_Read_Err_Ctr;

/*******************************************************************************
 ** Static data declarations
 ******************************************************************************/
_STATIC_ bool sci_port_initialized = false;
#ifdef TX_INTERRUPT
_STATIC_ utils_rb_data_t transmit_rb;
_STATIC_ uint8_t tx_data[TX_RB_BUF_SIZE];
_STATIC_ sci_drv_err_t transmit_isr_err = SCI_DRV_ERR_NONE;
#endif
#ifdef RX_INTERRUPT
_STATIC_ utils_rb_data_t recieve_rb;
_STATIC_ uint16_t rx_data[RX_RB_BUF_SIZE];
_STATIC_ sci_drv_err_t recieve_isr_err = SCI_DRV_ERR_NONE;
#endif

/*******************************************************************************
 ** Function bodies
 ******************************************************************************/
/*******************************************************************************
 * @name sci_drv_init
 *
 * @brief This function initializes the GPIO and serial control registers
 *       
 * @param none
 *
 * @return none  
 ******************************************************************************/
void sci_drv_init()  
{
   //initialize the GPIO pin registers associated with the serial bus module
   //Unlock the registers to allow modifications
   EALLOW;

   // Enable internal pull-up for the selected pins
   GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0; // Serial RX (SCIRXDA)
   GpioCtrlRegs.GPAPUD.bit.GPIO29 = 0; // Serial TX (SCITXDA)

   // Inputs are synchronized to SYSCLKOUT by default.
   // This will disable of synchronization for the selected pins
   GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3;  // Asynch input GPIO28 (SCIRXDA)

   // Configure pins to connect with the Serial module
   GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1;   // Serial RX (SCIRXDA)
   GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 1;   // Serial TX (SCITXDA)

   // enable SCI peripheral clock, in case it is not enabled elsewhere
   SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1;
   
   //lock the registers to re-enable protection
   EDIS;
   
   //configure the Serial Bus control registers
   SciaRegs.SCICCR.all =0x0007;  // 1 stop bit,  No loop-back
                                 // No parity,8 char bits,
                                 // async mode, idle-line protocol
    /*
    SciaRegs.SCICCR.bit.SCICHAR = 0x7;      // 2:0    Character length control  (8 chars)
    SciaRegs.SCICCR.bit.ADDRIDLE_MODE = 0;  // 3      ADDR/IDLE Mode control    (Idle mode)
    SciaRegs.SCICCR.bit.LOOPBKENA = 0;      // 4      Loop Back enable          (Disabled)
    SciaRegs.SCICCR.bit.PARITYENA = 0;      // 5      Parity enable             (Disabled)
    SciaRegs.SCICCR.bit.PARITY = 0;         // 6      Even or Odd Parity        (Odd)
    SciaRegs.SCICCR.bit.STOPBITS = 0;       // 7      Number of Stop Bits       (one)
    //SciaRegs.SCICCR.bit.rsvd1//           // 15:8   reserved
    */
    
   SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
                                 // Disable RX ERR, SLEEP, TXWAKE
    /*
    SciaRegs.SCICTL1.bit.RXENA = 1;         // 0      SCI receiver enable       (Enabled)
    SciaRegs.SCICTL1.bit.TXENA = 1;         // 1      SCI transmitter enable    (Enabled)
    SciaRegs.SCICTL1.bit.SLEEP = 0;         // 2      SCI sleep                 (Disabled)
    SciaRegs.SCICTL1.bit.TXWAKE = 0;        // 3      Transmitter wakeup method (Disabled)
    //SciaRegs.SCICTL1.bit.rsvd//           // 4      reserved
    SciaRegs.SCICTL1.bit.SWRESET = 0;       // 5      Software reset            (Clear Flags)
    SciaRegs.SCICTL1.bit.RXERRINTENA = 0;   // 6      Receive interrupt enable  (Disabled)
    //SciaRegs.SCICTL1.bit.rsvd1//          // 15:7   reserved
   */

   SciaRegs.SCICTL2.bit.TXINTENA = 0;     //disables serial TX
   SciaRegs.SCICTL2.bit.RXBKINTENA = 0;   //and RX interrupts
   /*
   SciaRegs.SCICTL2.bit.TXINTENA = 0;     // 0      Transmit interrupt enable     (Disabled)
   SciaRegs.SCICTL2.bit.RXBKINTENA = 0;   // 1      Receiver-buffer break enable  (Disabled)
   //SciaRegs.SCICTL2.bit.rsvd//          // 5:2    reserved
   //SciaRegs.SCICTL2.bit.TXEMPTY//       // 6      Transmitter empty flag         (Read Only)
   //SciaRegs.SCICTL2.bit.TXRDY//         // 7      Transmitter ready flag         (Read Only)
   //SciaRegs.SCICTL2.bit.rsvd1//         // 15:8   reserved
   */

   // Baud rate = LSPCLK/((BRR+1)*8)
   //SciaRegs.SCIHBAUD    =0x0000;  // 19200 baud @LSPCLK = 15MHz (60 MHz SYSCLK).
   SciaRegs.SCILBAUD    =0x0006;    // HDR_491: roughly 267860 baud @LSPCLK = 15MHz (60 MHz SYSCLK).   
                                    //267857 = (15*10^6)/(6+1)*8)

   SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 0;  // 13     FIFO reset                 (Clear FIFO)
   SciaRegs.SCIFFTX.all=0xE040;  //setup TX buffer and reset TX interrupt
   /*
   SciaRegs.SCIFFTX.bit.TXFFIL = 0x0;      // 4:0    Interrupt level            (Match zero bytes)
   SciaRegs.SCIFFTX.bit.TXFFIENA = 0;      // 5      Interrupt enable           (Disabled)
   SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1;    // 6      Clear INT flag             (Clear)
   SciaRegs.SCIFFTX.bit.TXFFINT = 0;       // 7      INT flag                   (Disabled)
   //SciaRegs.SCIFFTX.bit.TXFFST = 0x0;//  // 12:8   FIFO status                (Read Only)
   SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 1;  // 13     FIFO reset                 (Re-enable FIFO)  
   SciaRegs.SCIFFTX.bit.SCIFFENA = 1;      // 14     Enhancement enable         (Enabled)
   SciaRegs.SCIFFTX.bit.SCIRST = 1;        // 15     SCI reset rx/tx channels   (Enable SCI FIFO)
   */
   
   SciaRegs.SCIFFRX.bit.RXFIFORESET = 0;   // 13     FIFO reset             (Clear FIFO)
   SciaRegs.SCIFFRX.all=0x2044;  //setup RX buffer and reset RX interrupt
   /*
   SciaRegs.SCIFFRX.bit.RXFFIL = 0x4;      // 4:0    Interrupt level        (Match four bytes)
   SciaRegs.SCIFFRX.bit.RXFFIENA = 0;      // 5      Interrupt enable       (Disabled)
   SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;    // 6      Clear INT flag         (Clear)
   //SciaRegs.SCIFFRX.bit.RXFFINT = 0;//   // 7      INT flag               (Read Only)
   //SciaRegs.SCIFFRX.bit.RXFFST = 0x0;//  // 12:8   FIFO status            (Read Only)
   SciaRegs.SCIFFRX.bit.RXFIFORESET = 1;   // 13     FIFO reset             (Re-enable FIFO)
   SciaRegs.SCIFFRX.bit.RXFFOVRCLR = 0;    // 14     Clear overflow         (No clear)
   //SciaRegs.SCIFFRX.bit.RXFFOVF = 0;//   // 15     FIFO overflow          (Read Only)
   */
   
   SciaRegs.SCIFFCT.all=0x0;     //no delay between bits sent
   /*
   SciaRegs.SCIFFCT.bit.FFTXDLY = 0x0;     // 7:0    FIFO transmit delay    (No Delay)
   //SciaRegs.SCIFFCT.bit.rsvd = 0x0//     // 12:8   reserved   
   SciaRegs.SCIFFCT.bit.CDC = 0;           // 13     Auto baud mode enable  (Disabled)
   SciaRegs.SCIFFCT.bit.ABDCLR = 0;        // 14     Auto baud clear        (No Clear)
   //SciaRegs.SCIFFCT.bit.ABD = 0;//       // 15     Auto baud detect       (Read Only)
   */
   
   // SCIPRI left as default
   /*
   //SciaRegs.SCIPRI.bit.rsvd//          // 2:0    reserved
   SciaRegs.SCIPRI.bit.FREE = 0;         // 3      Free emulation suspend mode
   SciaRegs.SCIPRI.bit.SOFT = 0;         // 4      Soft emulation suspend mode (Immediate stop on suspend)
   //SciaRegs.SCIPRI.bit.rsvd1//         // 15:5    reserved
   */

   SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
    /*
    SciaRegs.SCICTL1.bit.RXENA = 1;         // 0      SCI receiver enable       (Enabled)
    SciaRegs.SCICTL1.bit.TXENA = 1;         // 1      SCI transmitter enable    (Enabled)
    SciaRegs.SCICTL1.bit.SLEEP = 0;         // 2      SCI sleep                 (Disabled)
    SciaRegs.SCICTL1.bit.TXWAKE = 0;        // 3      Transmitter wakeup method (Disabled)
    //SciaRegs.SCICTL1.bit.rsvd//           // 4      reserved
    SciaRegs.SCICTL1.bit.SWRESET = 1;       // 5      Software reset            (Re-Enable SCI) !!!
    SciaRegs.SCICTL1.bit.RXERRINTENA = 0;   // 6      Receive interrupt enable  (Disabled)
    //SciaRegs.SCICTL1.bit.rsvd1//          // 15:7   reserved
   */

   sci_port_initialized  = true;

#ifdef TX_INTERRUPT
	// Interrupts that are used in this driver are re-mapped to
	// ISR functions found within this file.
	EALLOW;  // This is needed to write to EALLOW protected registers
	PieVectTable.SCITXINTA = &sciTxFifoIsr;
	EDIS;   // This is needed to disable write to EALLOW protected registers
	PieCtrlRegs.PIEIER9.bit.INTx2 = 1;   /* Enable interrupt SCITXINTA*/
	IER |= M_INT9; //TODO: not sure about m_int9
   
    // Disable the TX buffer INT, Enable the TX FIFO INT
    SciaRegs.SCICTL2.bit.TXINTENA = 0;     // 0      Transmit interrupt enable     (Disabled)
    SciaRegs.SCIFFTX.bit.TXFFIENA = 1;      // 5      Interrupt enable           (Enabled)
    
    transmit_rb.data = tx_data;
    transmit_rb.max_size = TX_RB_BUF_SIZE;
    transmit_rb.head = 0U;
    transmit_rb.tail = 0U;
    transmit_rb.size = 0U;
#endif
   
#ifdef RX_INTERRUPT   
	// Interrupts that are used in this driver are re-mapped to
	// ISR functions found within this file.
	EALLOW;  // This is needed to write to EALLOW protected registers
	PieVectTable.SCIRXINTA = &sciRxFifoIsr;
	EDIS;   // This is needed to disable write to EALLOW protected registers
	PieCtrlRegs.PIEIER9.bit.INTx1 = 1;   /* Enable interrupt SCIRXINTA*/
	IER |= M_INT9; //TODO: not sure about m_int9
  
    SciaRegs.SCIFFRX.bit.RXFFIENA = 1;      // 5      Interrupt enable       (Enabled)
    SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;    // 6      Clear INT flag         (Clear)
    // Error interrupts disable, will be checked by sci_drv_read_data()
    SciaRegs.SCICTL1.bit.RXERRINTENA = 0;   // 6      Receive interrupt enable  (Disabled)
    SciaRegs.SCICTL2.bit.RXBKINTENA = 0;    // 1      Receiver-buffer break enable  (Enabled)
    
    recieve_rb.data = rx_data;
    recieve_rb.max_size = RX_RB_BUF_SIZE;
    recieve_rb.head = 0U;
    recieve_rb.tail = 0U;
    recieve_rb.size = 0U;
#endif

	Drv_Put_Status = 0;
	Drv_Tx_Isr_Call_Ctr = 0;
	Drv_Put_Call_Ctr = 0;
	Drv_Rx_Isr_Call_Ctr = 0;
	Drv_Read_Call_Ctr = 0;
	Drv_Read_Status = 0;
	Drv_Read_Err_Ctr = 0;
   
   return;
}

/*******************************************************************************
 * @name sci_drv_put_data()
 *
 * @brief Write the desired number of bytes to the SCI TX bus through TX FIFO
 *        Note: DSP2803x has max FIFO size of 4 bytes
 *       
 * @param p_buffer, byte buffer for write bytes
 * @param num_bytes, desired number of bytes for TX
 *
 * @return SCI_DRV_ERR_NONE when bytes written correctly
 * @return SCI_DRV_ERR_TX_INT_NONE interrupt occurred without MAX_TX_FIFO_SIZE bytes
 * @return SCI_DRV_ERR_RB ring buffer error during TX interrupt
 * @return SCI_DRV_ERR_TX_OVERFLOW if num_bytes greater than FIFO/Ring Buffer size
 * @return SCI_DRV_ERR_TX_NOT_NUM_BYTES if num_bytes greater than Ring Buffer space
 * @return SCI_DRV_ERR_RB error occurred with ring buffer
 * @return SCI_DRV_ERR_INVALID_PARAMS if called with null pointers
 * @return SCI_DRV_ERR_NOT_INITIALIZED if SCI not initialized 
 ******************************************************************************/
sci_drv_err_t sci_drv_put_data(uint8_t * p_buffer, uint16_t num_bytes)
{
    sci_drv_err_t err_code = SCI_DRV_ERR_NONE;
#ifndef TX_INTERRUPT
    uint8_t count = 0;
#endif
	Drv_Put_Status = 0;

    if(sci_port_initialized)
    {
		
        if (NULL != p_buffer)
        {
			Drv_Put_Call_Ctr++;
#ifdef TX_INTERRUPT
            
            if(num_bytes <= TX_RB_BUF_SIZE)
            {
				Drv_Put_Debug_Value = transmit_rb.size;
                if(num_bytes <= utils_rb_available_bytes(&transmit_rb))
                {
                    if (ERR_UTILS_RB_NONE == utils_rb_put_data(&transmit_rb,
                                                               p_buffer,
                                                               num_bytes))
                    {
                        //no action should be necessary. Maybe replace ifs with return code checks?
                        err_code = transmit_isr_err; // pass through any errors given by interrupt
                        transmit_isr_err = SCI_DRV_ERR_NONE;
                    }
                    else
                    {
                        err_code = SCI_DRV_ERR_RB;
                    }
                }
                else
                {
                    err_code = SCI_DRV_ERR_TX_NOT_NUM_BYTES;
                }
            }
            else 
            {
                err_code = SCI_DRV_ERR_TX_OVERFLOW;
            }
#else
            if(num_bytes <= MAX_TX_FIFO_SIZE)
            {
                DINT; //Disable Interrupts while reading/writing SCI
                for(count=0;count<num_bytes;count++)
                {
                    while(!SciaRegs.SCICTL2.bit.TXRDY); //wait until buffer is available
                    SciaRegs.SCITXBUF = (p_buffer[count] & SCI_TXDT_MASK);
                }
                EINT; //Re-enable    
            }
            else 
            {
                err_code = SCI_DRV_ERR_TX_OVERFLOW;
            }
#endif
        }
        else
        {
            err_code = SCI_DRV_ERR_INVALID_PARAMS;
        }        
    }
    else
    {
        err_code = SCI_DRV_ERR_NOT_INITIALIZED;
    }
	
	if(err_code != SCI_DRV_ERR_NONE)
	{
		Drv_Put_Status = (uint16_t) err_code;
		
	}
    return err_code;
}
 
/*******************************************************************************
 * @name sci_drv_TX_status()
 *
 * @brief Determine the availability of the TX buffer and FIFO
 *       
 * @param none
 *
 * @return SCI_DRV_ERR_NOT_INITIALIZED if SCI not initialized
 * @return SCI_DRV_ERR_TX_NOT_EMPTY if TX FIFO or buffer not empty
 * @return SCI_DRV_ERR_NONE if both FIFO and buffer are empty
 ******************************************************************************/
sci_drv_err_t sci_drv_TX_status()
{
    sci_drv_err_t err_code = SCI_DRV_ERR_NONE;
    if(sci_port_initialized)
    {
        DINT; //Disable Interrupts while reading/writing SCI
        if((SciaRegs.SCIFFTX.bit.TXFFST != 0) ||    //If FIFO
            (SciaRegs.SCICTL2.bit.TXEMPTY != 1))    //or buffer not empty
        {
            err_code = SCI_DRV_ERR_TX_NOT_EMPTY;
        }
        EINT; //Re-enable
    }
    else
    {
        err_code = SCI_DRV_ERR_NOT_INITIALIZED;
    }
    return err_code;    
}

/*******************************************************************************
 * @name sci_drv_get_read_size()
 *
 * @brief returns the number of bytes in the receive ring buffer
 *       
 * @param none
 *
 * @return number of bytes
 ******************************************************************************/
uint16_t sci_drv_get_read_size(void)
{
	return recieve_rb.size;
}

/*******************************************************************************
 * @name sci_drv_read_data()
 *
 * @brief Read the desired number of bytes from the SCI RX bus through RX FIFO
 *       
 * @param p_buffer, byte buffer for read bytes
 * @param num_bytes, desired number of bytes from RX
 * @param p_num_returned, actual number of bytes read
 *
 * @return SCI_DRV_ERR_NONE when bytes read correctly
 * @return SCI_DRV_ERR_RB when ring buffer returns error
 * @return SCI_DRV_ERR_RX_RB_OVERFLOW when interrupt occurs and no space in RB
 * @return SCI_DRV_ERR_RX_NOT_NUM_BYTES when FIFO less than num_bytes 
 * @return SCI_DRV_ERR_RX_FIFO_OVERFLOW when FIFO overflowed from RX bytes 
 * @return SCI_DRV_ERR_RX_FIFO_FE_PE when FIFO bytes Frame or Parity error
 * @return SCI_DRV_ERR_RX_OE when RX over wrote while reading
 * @return SCI_DRV_ERR_RX_FE when RX bus had Frame error
 * @return SCI_DRV_ERR_RX_BRKDT when RX bus has Break Detect error
 * @return SCI_DRV_ERR_INVALID_PARAMS if called with null pointers, or too large
 * @return SCI_DRV_ERR_NOT_INITIALIZED if SCI not initialized
 ******************************************************************************/
sci_drv_err_t sci_drv_read_data( uint16_t * p_buffer, 
                                uint16_t num_bytes,
                                uint16_t * p_num_returned)
{
    sci_drv_err_t err_code = SCI_DRV_ERR_NONE;
    uint8_t count = 0; 
#ifndef RX_INTERRUPT
    uint16_t data_bytes = 0;
#endif
	
    if(sci_port_initialized)
    {
        if ((NULL != p_buffer)||(NULL != p_num_returned))
        {
			Drv_Read_Call_Ctr++;
            DINT; //Disable Interrupts while reading/writing SCI
#ifdef RX_INTERRUPT
            if(num_bytes <= RX_RB_BUF_SIZE)
            {
                if(num_bytes <= recieve_rb.size)
                {
                    if (ERR_UTILS_RB_NONE == utils_rb_get_data(&recieve_rb,
                                                               p_buffer,
                                                               num_bytes,
                                                               p_num_returned))
                    {

                        for(count=0;count<num_bytes;count++)
                        {
                            //check for errors, and parse out just data bytes
                            if((p_buffer[count] & SCI_FE_PE_MASK) != 0)
                            {
                                err_code = SCI_DRV_ERR_RX_FIFO_FE_PE;
                            }
                            else if((p_buffer[count] & SCI_RXFFOVF_MASK) != 0)
                            {
                                err_code = SCI_DRV_ERR_RX_FIFO_OVERFLOW;
                            }
                            p_buffer[count] = ((p_buffer[count] & SCI_RXDT_MASK));
                        }                        
                        err_code = recieve_isr_err; // pass through any errors given by interrupt
                        recieve_isr_err = SCI_DRV_ERR_NONE; //clear isr error code
                    }
                    else
                    {
                        err_code = SCI_DRV_ERR_RB;
                    }
                }
                else
                {
                    err_code = SCI_DRV_ERR_RX_NOT_NUM_BYTES;
                }
            }
            else 
            {   // requested bytes too large for ring buffer
                err_code = SCI_DRV_ERR_INVALID_PARAMS;
            }

#else
            *p_num_returned = 0; //Initialize to none
            if(SciaRegs.SCIFFRX.bit.RXFFST >= num_bytes)
            {
                //Read, if possible, num_bytes from RX FIFO
                for(count=0;count<num_bytes;count++)
                {
                    if(SciaRegs.SCIFFRX.bit.RXFFST != 0 ) // while bytes in RX FIFO keep processing
                    {
                        data_bytes = SciaRegs.SCIRXBUF.all;
                        
                        if(SciaRegs.SCIFFRX.bit.RXFFOVF)
                        {   // FIFO Overflow, may still be able to parse bytes
                            err_code = SCI_DRV_ERR_RX_FIFO_OVERFLOW;
                        }
                        
                        if((data_bytes & SCI_FE_PE_MASK) != 0)
                        {   // Frame or Parity errors have higher priority than Overflow, 
                            // and corrupt bytes
                            
                            //Serial_Failure_Count++;   //TODO: Get protocol layer to do this !!!!!!!!
                            //SerialRxCtr |= 0x1000;
                            err_code = SCI_DRV_ERR_RX_FIFO_FE_PE;
                            break; //if error, stop reading bytes
                        }
                        else
                        {   // Desired correct action of reading bytes
                            p_buffer[count] = (uint8_t)(data_bytes & SCI_RXDT_MASK);
                            *p_num_returned = (count+1); // +1 for zero offset
                        }
                    }
                    else
                    {
                        //should not occur
                        err_code = SCI_DRV_ERR_RX_NOT_NUM_BYTES;
                        break; 
                    }  
                }
            }
            else
            {
                err_code = SCI_DRV_ERR_RX_NOT_NUM_BYTES;
            }
 
#endif      
            // These SCI Signal errors require FIFO bytes to be discarded
            if(SciaRegs.SCIRXST.bit.OE)  
            {
                err_code = SCI_DRV_ERR_RX_OE; //Needs SW Reset to clear
            }
            else if(SciaRegs.SCIRXST.bit.FE)  
            {
                err_code = SCI_DRV_ERR_RX_FE; //Needs SW Reset to clear
            }
            else if(SciaRegs.SCIRXST.bit.BRKDT)  
            {
                err_code = SCI_DRV_ERR_RX_BRKDT; //Needs SW Reset to clear
            }
            
            EINT; //Re-enable
        }
        else
        {
            err_code = SCI_DRV_ERR_INVALID_PARAMS;
        }
    }
    else
    {
        err_code = SCI_DRV_ERR_NOT_INITIALIZED;
    }
	
	if(err_code != SCI_DRV_ERR_NONE )
	{
		Drv_Read_Status = (uint16_t) err_code;
		Drv_Read_Err_Ctr++;
	}
    return err_code;    
}

/*******************************************************************************
 * @name sci_drv_RX_enable()
 *
 * @brief Enables the SCI RX read buffer, FIFO, and (if applicable) interrupts
 *       
 * @param none
 *
 * @return SCI_DRV_ERR_NOT_INITIALIZED if SCI not initialized
 * @return SCI_DRV_ERR_NONE after proper enable
 ******************************************************************************/ 
sci_drv_err_t sci_drv_RX_enable()
{
    sci_drv_err_t err_code = SCI_DRV_ERR_NONE;
    if(sci_port_initialized)
    {
        SciaRegs.SCIFFRX.bit.RXFFIL = 0x4;      // 4:0    Interrupt level        (Match four bytes)
#ifdef RX_INTERRUPT
        SciaRegs.SCIFFRX.bit.RXFFIENA = 1;      // 5      Interrupt enable       (Enabled)
        SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;    // 6      Clear INT flag         (Clear)
        //SciaRegs.SCIFFRX.bit.RXFFINT = 0;//   // 7      INT flag               (Read Only)
        SciaRegs.SCIFFTX.bit.SCIFFENA = 1;      // 14     Enhancement enable         (Enabled)
#endif
        //SciaRegs.SCIFFRX.bit.RXFFST = 0x0;//  // 12:8   FIFO status            (Read Only)
        SciaRegs.SCIFFRX.bit.RXFIFORESET = 1;   // 13     FIFO reset             (Enable FIFO)
        SciaRegs.SCIFFRX.bit.RXFFOVRCLR = 1;    // 14     Clear overflow         (Clear)
        //SciaRegs.SCIFFRX.bit.RXFFOVF = 0;//   // 15     FIFO overflow          (Read Only)

        SciaRegs.SCICTL1.bit.RXENA = 1;         // 0      SCI receiver enable       (Enabled)
#ifdef RX_INTERRUPT
        // Error interrupts disable, will be checked by sci_drv_read_data()
        SciaRegs.SCICTL1.bit.RXERRINTENA = 0;   // 6      Receive interrupt enable  (Disabled)
        SciaRegs.SCICTL2.bit.RXBKINTENA = 0;    // 1      Receiver-buffer break enable  (Disabled)
#endif            
    }
    else
    {
        err_code = SCI_DRV_ERR_NOT_INITIALIZED;
    }
    return err_code;    
}

/*******************************************************************************
 * @name sci_drv_RX_disable()
 *
 * @brief Disables the SCI RX read buffer, FIFO, and (if applicable) interrupts
 *       
 * @param none
 *
 * @return SCI_DRV_ERR_NOT_INITIALIZED if SCI not initialized
 * @return SCI_DRV_ERR_NONE after proper disable
 ******************************************************************************/ 
sci_drv_err_t sci_drv_RX_disable()
{
    sci_drv_err_t err_code = SCI_DRV_ERR_NONE;
    if(sci_port_initialized)
    {
        SciaRegs.SCIFFRX.bit.RXFFIL = 0x4;      // 4:0    Interrupt level        (Match four bytes)
#ifdef RX_INTERRUPT
        SciaRegs.SCIFFRX.bit.RXFFIENA = 0;      // 5      Interrupt enable       (Disabled)
        SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;    // 6      Clear INT flag         (Clear)
        //SciaRegs.SCIFFRX.bit.RXFFINT = 0;//   // 7      INT flag               (Read Only)
        
        //controls normal or FIFO interrupt
        SciaRegs.SCIFFTX.bit.SCIFFENA = 1;      // 14     Enhancement enable         (Enabled)
#endif
        //SciaRegs.SCIFFRX.bit.RXFFST = 0x0;//  // 12:8   FIFO status            (Read Only)
        SciaRegs.SCIFFRX.bit.RXFIFORESET = 0;   // 13     FIFO reset             (Disable FIFO)
        SciaRegs.SCIFFRX.bit.RXFFOVRCLR = 0;    // 14     Clear overflow         (No clear)
        //SciaRegs.SCIFFRX.bit.RXFFOVF = 0;//   // 15     FIFO overflow          (Read Only)

        SciaRegs.SCICTL1.bit.RXENA = 0;         // 0      SCI receiver enable       (Disabled)
#ifdef RX_INTERRUPT
        SciaRegs.SCICTL1.bit.RXERRINTENA = 0;   // 6      Receive interrupt enable  (Disabled)
        SciaRegs.SCICTL2.bit.RXBKINTENA = 0;   // 1      Receiver-buffer break enable  (Disabled)
#endif        
    }
    else
    {
        err_code = SCI_DRV_ERR_NOT_INITIALIZED;
    }
    return err_code;    
}

/*******************************************************************************
 * @name sci_drv_TX_enable()
 *
 * @brief Enables the SCI TX write buffer, FIFO, and (if applicable) interrupts
 *       
 * @param none
 *
 * @return SCI_DRV_ERR_NOT_INITIALIZED if SCI not initialized
 * @return SCI_DRV_ERR_NONE after proper enable
 ******************************************************************************/ 
sci_drv_err_t sci_drv_TX_enable()
{
    sci_drv_err_t err_code = SCI_DRV_ERR_NONE;
    if(sci_port_initialized)
    {
        SciaRegs.SCICTL1.bit.TXENA = 1;         // 1      SCI transmitter enable    (Enabled)
#ifdef TX_INTERRUPT        
        SciaRegs.SCICTL2.bit.TXINTENA = 0;     // 0      Transmit interrupt enable     (Disabled)
        SciaRegs.SCIFFTX.bit.TXFFIENA = 1;      // 5      FIFO Interrupt enable      (Enabled)
#endif        
        SciaRegs.SCIFFTX.bit.TXFFIL = 0x0;      // 4:0    Interrupt level            (Match zero bytes)
        
        SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1;    // 6      Clear INT flag             (Clear)
        //SciaRegs.SCIFFTX.bit.TXFFINT = 0;     // 7      INT flag                   (Read Only)
        //SciaRegs.SCIFFTX.bit.TXFFST = 0x0;//  // 12:8   FIFO status                (Read Only)
        SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 1;  // 13     FIFO reset                 (Re-enable FIFO)  
        SciaRegs.SCIFFTX.bit.SCIFFENA = 1;      // 14     Enhancement enable         (Enabled)
        // no SCIRST change
    }
    else
    {
        err_code = SCI_DRV_ERR_NOT_INITIALIZED;
    }
    return err_code;    
}

/*******************************************************************************
 * @name sci_drv_TX_disable()
 *
 * @brief Disables the SCI TX write buffer, FIFO, and (if applicable) interrupts
 *       
 * @param none
 *
 * @return SCI_DRV_ERR_NOT_INITIALIZED if SCI not initialized
 * @return SCI_DRV_ERR_NONE after proper disable
 ******************************************************************************/ 
sci_drv_err_t sci_drv_TX_disable()
{
    sci_drv_err_t err_code = SCI_DRV_ERR_NONE;
    if(sci_port_initialized)
    {
        SciaRegs.SCICTL1.bit.TXENA = 1;         // 0      SCI transmitter enable    (Disabled)
#ifdef TX_INTERRUPT        
        SciaRegs.SCICTL2.bit.TXINTENA = 0;     // 0      Transmit interrupt enable     (Disabled)
        SciaRegs.SCIFFTX.bit.TXFFIENA = 0;      // 5      FIFO Interrupt enable      (Disabled)
#endif        
        SciaRegs.SCIFFTX.bit.TXFFIL = 0x0;      // 4:0    Interrupt level            (Match zero bytes)
        
        SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1;    // 6      Clear INT flag             (Clear)
        //SciaRegs.SCIFFTX.bit.TXFFINT = 0;     // 7      INT flag                   (Read Only)
        //SciaRegs.SCIFFTX.bit.TXFFST = 0x0;//  // 12:8   FIFO status                (Read Only)
        SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 0;  // 13     FIFO reset                 (Clear FIFO)  
        SciaRegs.SCIFFTX.bit.SCIFFENA = 1;      // 14     Enhancement enable         (Enabled)
        // no SCIRST change
    }
    else
    {
        err_code = SCI_DRV_ERR_NOT_INITIALIZED;
    }
    return err_code;    
}


#ifdef TX_INTERRUPT
/*******************************************************************************
 * @name sciTxFifoIsr()
 *
 * @brief This function is the ISR for the TX FIFO interrupt
 *       
 * @param none
 *
 * @return none  
 ******************************************************************************/
interrupt void sciTxFifoIsr(void)
{
    uint16_t data_bytes[MAX_TX_FIFO_SIZE] = {0U};
    uint16_t count = 0U;
    uint16_t num_bytes_used = 0U;
    Drv_Tx_Isr_Call_Ctr++;
	
    if(transmit_rb.size >= MAX_TX_FIFO_SIZE) //prevent underflow
    {   
        if(ERR_UTILS_RB_NONE == utils_rb_get_data(  &transmit_rb,
                                                    &(data_bytes[0]),
                                                    MAX_TX_FIFO_SIZE,
                                                    &num_bytes_used))
        {
            //no error, no action
        }
        else
        {   // no error should be possible, as null params and underflow prevented
            transmit_isr_err = SCI_DRV_ERR_RB;
        }
            
        for(count=0U;count<MAX_TX_FIFO_SIZE;count++)
        {
            while(!SciaRegs.SCICTL2.bit.TXRDY); //wait until buffer is available
            SciaRegs.SCITXBUF = (data_bytes[count] & SCI_TXDT_MASK);
        }
    }
    else
    {   // not enough bytes (full packet) available for TX FIFO
        transmit_isr_err = SCI_DRV_ERR_TX_INT_NONE;
    }
    
    SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;  // Clear SCI Interrupt flag
    PieCtrlRegs.PIEACK.all|=0x100;      // Issue PIE ACK
}
#endif

#ifdef RX_INTERRUPT 
/*******************************************************************************
 * @name sciRxFifoIsr()
 *
 * @brief This function is the ISR for the RX FIFO interrupt
 *       
 * @param none
 *
 * @return none  
 ******************************************************************************/
interrupt void sciRxFifoIsr(void)
{
    uint16_t data_bytes[MAX_RX_FIFO_SIZE] = {0U};
    uint16_t count = 0U;
	Drv_Tx_Isr_Call_Ctr++;
    
    if(SciaRegs.SCIFFRX.bit.RXFFST != MAX_RX_FIFO_SIZE )
    {
        recieve_isr_err = SCI_DRV_ERR_RX_NOT_NUM_BYTES;
    }
    
    for(count=0U;count<MAX_RX_FIFO_SIZE;count++)
    {
        if(SciaRegs.SCIFFRX.bit.RXFFST != 0U ) // while bytes in RX FIFO keep processing
        {   //shift in RXFFOVF bit for later error checking
            data_bytes[count] =((SciaRegs.SCIRXBUF.all) &
                         (SciaRegs.SCIFFRX.bit.RXFFOVF << SCI_RXFFOVF_SHIFT));
        }
        //else condition bytes will show up as corrupted packet
    }
    
    if(ERR_UTILS_RB_NONE == utils_rb_put_data(  &recieve_rb,
                                                &(data_bytes[0]),
                                                MAX_RX_FIFO_SIZE))
    {
        //no error, no action
    }
    else
    {   // only ring buffer error possible is overflow
        recieve_isr_err = SCI_DRV_ERR_RX_RB_OVERFLOW;
    }
    
    SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1;   // Clear Overflow flag
    SciaRegs.SCIFFRX.bit.RXFFINTCLR=1;   // Clear Interrupt flag

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

  • Hi Neal,

    What is causing your app to crash? What do you mean by this?

    Note, that the SCI RX will interrupt when the RXFIFO has equal or more than the interrupt level in the FIFO. Note, that the SCI TX will interrupt when the TXFIFO has equal or less than the interrupt level in the FIFO. This causes the SCI TX interrupt to be triggered immediately after transmitting data from out of the FIFO if the FIFO level is less than or equal to the TXFFIL.

    If you were not clearing the interrupts in the PIE group propely, then the other interrupts in that PIE group would not be triggering. But it seems like you are not using other interrupts in group 9. So, that may not be the problem. ECAN, LIN, and SCI are in PIE Group 9.

    Hope this helps.

    sal
  • Thank you.
    My TXFFLL is set to 0 and my RXFFLL is set to 4 (so that they trigger when TX empty or RX Full, respectively).
    By app crashing, I mean that the normal activity, that is CAN traffic out, does not occur anymore once I enabled these interrupts.
    Like stated previously, I am worried I am not clearing things properly.
    Is there anyone I can contact to get a second opinion on my code, to verify I am or am not setting/clearing the interrupts correctly?
    Thank you,
    Neal
  • This may be your issue...

    If you are using the FIFOs, do not use TXRDY and RXRDY bit fields. Only using the FFST bit fields to check if here is room to write to the FIFO and if there is data to read from the FIFO. (see line 747)

    Otherwise, I think your handling of interrupts looks pretty good.

    sal
  • Thank you,

    removing the TXRDY may have helped a little bit, but does not seem to have fixed all my issues.

    Going off the basis that this app was running before I added this driver, and now I have an extra debug gpio toggle happening around my polling calls, something is still partially crashing the app (stopping some operations) after 290ms based on when my debug gpio stops toggling.

    Do you have any other advice for debugging the operation of the ISRs? 
    Short of it completely working, I'm a little stuck on how to confirm which parts of my driver might or might not be working.

    Thank you,

    Neal

  • If you can connect a debugger via CCS, then that will help you a lot.

    You can try enabling the TX portion and RX portions separately and see if one or the other is causing the issue.

    I cannot help much without knowing the details of your system and knowing which portions of your system cease to function properly and their behavior.

    If you provide some more details like this, then I may be able to give you some pointers for debugging the issue.

    Hope this helps.

    sal
  • Thank you for the help so far.

    I have made some progress, such as re-ordering some error handling that prevented further operation unnecessarily.

    My current issue has to to with RXFFST during the interrupt.

    On line 862 of the attached, at the beginning of the receive ISR I check that RXFFST == 4 like I expect.

    According to my error codes, I am getting false for this check frequently.

    If RXFFLV == 4, why does the RXFFST not equal 4 at this ISR, or how can I debug this?

    Secondly, my application is a paired partner serial device, where two partners are send/receiving data at the same rate as their partner (in this case, with the exact same serial driver).

    I have introduced a 4 bit delay to TX with FFTXDLY, but I am still getting semi-regular RXFFOVF errors on my receive side, even though my ISR should be emptying the FIFO before it can overflow.  Any thoughts on what could be causing this, or how to debug it?

    Thank you for any assistance!

    /*! @file sci_drv.c
     *
     *  $Revision: 1328 $
     *  $Date: 2018-02-23 12:05:08 -0500 (Fri, 23 Feb 2018) $
     *  $Author: abraham_mathew $
     *  $HeadURL: https://emsredmine/svn/p121619/Software/SW_11340_1_APP_Embedded/branches/Sandbox_2222018_neal/C_Functions/sci_drv.c $
     *
     *  @brief
     *           Driver Source Code for the Danfoss Serial Protocol 
     *        
     *  @par
     *
     *  (c) Copyright 2016-2018, LORD Corporation – LORD Confidential and Proprietary
     */
    
    /*******************************************************************************
     ** Includes
     ******************************************************************************/
    #include "sci_drv.h"
    #include "utils_rb.h"
    
    /*******************************************************************************
    ** Constants (exported only)
    *******************************************************************************/
    
    /*******************************************************************************
    ** Local Constants 
    *******************************************************************************/
    #define SCI_FE_PE_MASK    0xC000  //Mask the FIFO Framing & Parity Error Bits
    #define SCI_RXFFOVF_MASK  0x2000  //Mask the RXFFOVF bit from RB 16b data
    #define SCI_RXFFOVF_SHIFT 13      //Shift RXFFOVF to 13th bit
    #define SCI_RXDT_MASK     0x00FF  //Mask the Received Character Bits of SCIRXBUF
    #define SCI_TXDT_MASK     0x00FF  //Mask the Transmit Character Bits of SCITXBUF
    #define MAX_TX_FIFO_SIZE  0x4     //Max size for the DSP2803x TX FIFO
    #define MAX_RX_FIFO_SIZE  0x4     //Max size for the DSP2803x RX FIFO
    #define TX_RB_BUF_SIZE    64      //
    #define RX_RB_BUF_SIZE    64      //
    #define DEBUG_ARRAY_SIZE  10
    /*******************************************************************************
     ** External Global Variables
     ******************************************************************************/
    extern Uint16 Drv_Put_Debug_Value;
    extern Uint16 Drv_Put_Debug_Value2;
    extern Uint16 Drv_Put_Status;
    extern Uint16 Drv_Put_Err_Ctr;
    
    
    volatile Uint16 Drv_Tx_Isr_Call_Ctr_c;
    extern Uint16 Drv_Tx_Isr_Call_Ctr;
    volatile Uint16 Drv_Rx_Isr_Call_Ctr_c;
    extern  Uint16 Drv_Rx_Isr_Call_Ctr;
    
    extern Uint16 Drv_Put_Call_Ctr;
    extern Uint16 Drv_Read_Call_Ctr;
    
    extern Uint16 Drv_Read_Debug_Value;
    extern Uint16 Drv_Read_Debug_Value2;
    extern Uint16 Drv_Read_Status;
    extern Uint16 Drv_Read_Err_Ctr;
    
    extern Uint16 Drv_TX_isr_log_1[DEBUG_ARRAY_SIZE] = {0};
    extern Uint16 Drv_TX_isr_log_2[DEBUG_ARRAY_SIZE] = {0};
    extern Uint16 Drv_RX_isr_log_1[DEBUG_ARRAY_SIZE] = {0};
    extern Uint16 Drv_RX_isr_log_2[DEBUG_ARRAY_SIZE] = {0};
    
    extern  Uint16 Drv_Tx_Isr_Enabled;
    extern  Uint16 Drv_Rx_Isr_Enabled;
    
    /*******************************************************************************
     ** Static data declarations
     ******************************************************************************/
    _STATIC_ bool sci_port_initialized = false;
    #ifdef TX_INTERRUPT
    _STATIC_ utils_rb_data_t transmit_rb;
    _STATIC_ uint8_t tx_data[TX_RB_BUF_SIZE];
    _STATIC_ volatile sci_drv_err_t transmit_isr_err = SCI_DRV_ERR_NONE;
    #endif
    #ifdef RX_INTERRUPT
    _STATIC_ utils_rb_data_t recieve_rb;
    _STATIC_ uint16_t rx_data[RX_RB_BUF_SIZE];
    _STATIC_ volatile sci_drv_err_t recieve_isr_err = SCI_DRV_ERR_NONE;
    #endif
    
    /*******************************************************************************
     ** Function bodies
     ******************************************************************************/
    /*******************************************************************************
     * @name sci_drv_init
     *
     * @brief This function initializes the GPIO and serial control registers
     *       
     * @param none
     *
     * @return none  
     ******************************************************************************/
    void sci_drv_init()  
    {
       //initialize the GPIO pin registers associated with the serial bus module
       //Unlock the registers to allow modifications
       EALLOW;
    
       // Enable internal pull-up for the selected pins
       GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0; // Serial RX (SCIRXDA)
       GpioCtrlRegs.GPAPUD.bit.GPIO29 = 0; // Serial TX (SCITXDA)
    
       // Inputs are synchronized to SYSCLKOUT by default.
       // This will disable of synchronization for the selected pins
       GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3;  // Asynch input GPIO28 (SCIRXDA)
    
       // Configure pins to connect with the Serial module
       GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1;   // Serial RX (SCIRXDA)
       GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 1;   // Serial TX (SCITXDA)
    
       // enable SCI peripheral clock, in case it is not enabled elsewhere
       SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1;
       
       //lock the registers to re-enable protection
       EDIS;
       
       //configure the Serial Bus control registers
       SciaRegs.SCICCR.all =0x0007;  // 1 stop bit,  No loop-back
                                     // No parity,8 char bits,
                                     // async mode, idle-line protocol
        /*
        SciaRegs.SCICCR.bit.SCICHAR = 0x7;      // 2:0    Character length control  (8 chars)
        SciaRegs.SCICCR.bit.ADDRIDLE_MODE = 0;  // 3      ADDR/IDLE Mode control    (Idle mode)
        SciaRegs.SCICCR.bit.LOOPBKENA = 0;      // 4      Loop Back enable          (Disabled)
        SciaRegs.SCICCR.bit.PARITYENA = 0;      // 5      Parity enable             (Disabled)
        SciaRegs.SCICCR.bit.PARITY = 0;         // 6      Even or Odd Parity        (Odd)
        SciaRegs.SCICCR.bit.STOPBITS = 0;       // 7      Number of Stop Bits       (one)
        //SciaRegs.SCICCR.bit.rsvd1//           // 15:8   reserved
        */
        
       SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
                                     // Disable RX ERR, SLEEP, TXWAKE
        /*
        SciaRegs.SCICTL1.bit.RXENA = 1;         // 0      SCI receiver enable       (Enabled)
        SciaRegs.SCICTL1.bit.TXENA = 1;         // 1      SCI transmitter enable    (Enabled)
        SciaRegs.SCICTL1.bit.SLEEP = 0;         // 2      SCI sleep                 (Disabled)
        SciaRegs.SCICTL1.bit.TXWAKE = 0;        // 3      Transmitter wakeup method (Disabled)
        //SciaRegs.SCICTL1.bit.rsvd//           // 4      reserved
        SciaRegs.SCICTL1.bit.SWRESET = 0;       // 5      Software reset            (Clear Flags)
        SciaRegs.SCICTL1.bit.RXERRINTENA = 0;   // 6      Receive interrupt enable  (Disabled)
        //SciaRegs.SCICTL1.bit.rsvd1//          // 15:7   reserved
       */
    
       SciaRegs.SCICTL2.bit.TXINTENA = 0;     //disables serial TX
       SciaRegs.SCICTL2.bit.RXBKINTENA = 0;   //and RX interrupts
       /*
       SciaRegs.SCICTL2.bit.TXINTENA = 0;     // 0      Transmit interrupt enable     (Disabled)
       SciaRegs.SCICTL2.bit.RXBKINTENA = 0;   // 1      Receiver-buffer break enable  (Disabled)
       //SciaRegs.SCICTL2.bit.rsvd//          // 5:2    reserved
       //SciaRegs.SCICTL2.bit.TXEMPTY//       // 6      Transmitter empty flag         (Read Only)
       //SciaRegs.SCICTL2.bit.TXRDY//         // 7      Transmitter ready flag         (Read Only)
       //SciaRegs.SCICTL2.bit.rsvd1//         // 15:8   reserved
       */
    
       // Baud rate = LSPCLK/((BRR+1)*8)
       //SciaRegs.SCIHBAUD    =0x0000;  // 19200 baud @LSPCLK = 15MHz (60 MHz SYSCLK).
       SciaRegs.SCILBAUD    =0x0006;    // HDR_491: roughly 267860 baud @LSPCLK = 15MHz (60 MHz SYSCLK).   
                                        //267857 = (15*10^6)/(6+1)*8)
    
       SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 0;  // 13     FIFO reset                 (Clear FIFO)
       SciaRegs.SCIFFTX.all=0xE040;  //setup TX buffer and reset TX interrupt
       Drv_Tx_Isr_Enabled = 0;
       /*
       SciaRegs.SCIFFTX.bit.TXFFIL = 0x0;      // 4:0    Interrupt level            (Match zero bytes)
       SciaRegs.SCIFFTX.bit.TXFFIENA = 0;      // 5      Interrupt enable           (Disabled)
       SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1;    // 6      Clear INT flag             (Clear)
       SciaRegs.SCIFFTX.bit.TXFFINT = 0;       // 7      INT flag                   (Disabled)
       //SciaRegs.SCIFFTX.bit.TXFFST = 0x0;//  // 12:8   FIFO status                (Read Only)
       SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 1;  // 13     FIFO reset                 (Re-enable FIFO)  
       SciaRegs.SCIFFTX.bit.SCIFFENA = 1;      // 14     Enhancement enable         (Enabled)
       SciaRegs.SCIFFTX.bit.SCIRST = 1;        // 15     SCI reset rx/tx channels   (Enable SCI FIFO)
       */
       
       SciaRegs.SCIFFRX.bit.RXFIFORESET = 0;   // 13     FIFO reset             (Clear FIFO)
       SciaRegs.SCIFFRX.all=0x2044;  //setup RX buffer and reset RX interrupt
       Drv_Rx_Isr_Enabled = 0;
       /*
       SciaRegs.SCIFFRX.bit.RXFFIL = 0x4;      // 4:0    Interrupt level        (Match four bytes)
       SciaRegs.SCIFFRX.bit.RXFFIENA = 0;      // 5      Interrupt enable       (Disabled)
       SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;    // 6      Clear INT flag         (Clear)
       //SciaRegs.SCIFFRX.bit.RXFFINT = 0;//   // 7      INT flag               (Read Only)
       //SciaRegs.SCIFFRX.bit.RXFFST = 0x0;//  // 12:8   FIFO status            (Read Only)
       SciaRegs.SCIFFRX.bit.RXFIFORESET = 1;   // 13     FIFO reset             (Re-enable FIFO)
       SciaRegs.SCIFFRX.bit.RXFFOVRCLR = 0;    // 14     Clear overflow         (No clear)
       //SciaRegs.SCIFFRX.bit.RXFFOVF = 0;//   // 15     FIFO overflow          (Read Only)
       */
       
       SciaRegs.SCIFFCT.all=0x4;     //no delay between bits sent
       /*
       SciaRegs.SCIFFCT.bit.FFTXDLY = 0x4;     // 7:0    FIFO transmit delay    (4 bit Delay)
       //SciaRegs.SCIFFCT.bit.rsvd = 0x0//     // 12:8   reserved   
       SciaRegs.SCIFFCT.bit.CDC = 0;           // 13     Auto baud mode enable  (Disabled)
       SciaRegs.SCIFFCT.bit.ABDCLR = 0;        // 14     Auto baud clear        (No Clear)
       //SciaRegs.SCIFFCT.bit.ABD = 0;//       // 15     Auto baud detect       (Read Only)
       */
       
       // SCIPRI left as default
       /*
       //SciaRegs.SCIPRI.bit.rsvd//          // 2:0    reserved
       SciaRegs.SCIPRI.bit.FREE = 0;         // 3      Free emulation suspend mode
       SciaRegs.SCIPRI.bit.SOFT = 0;         // 4      Soft emulation suspend mode (Immediate stop on suspend)
       //SciaRegs.SCIPRI.bit.rsvd1//         // 15:5    reserved
       */
    
       SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
        /*
        SciaRegs.SCICTL1.bit.RXENA = 1;         // 0      SCI receiver enable       (Enabled)
        SciaRegs.SCICTL1.bit.TXENA = 1;         // 1      SCI transmitter enable    (Enabled)
        SciaRegs.SCICTL1.bit.SLEEP = 0;         // 2      SCI sleep                 (Disabled)
        SciaRegs.SCICTL1.bit.TXWAKE = 0;        // 3      Transmitter wakeup method (Disabled)
        //SciaRegs.SCICTL1.bit.rsvd//           // 4      reserved
        SciaRegs.SCICTL1.bit.SWRESET = 1;       // 5      Software reset            (Re-Enable SCI) !!!
        SciaRegs.SCICTL1.bit.RXERRINTENA = 0;   // 6      Receive interrupt enable  (Disabled)
        //SciaRegs.SCICTL1.bit.rsvd1//          // 15:7   reserved
       */
    
       sci_port_initialized  = true;
    
    #ifdef TX_INTERRUPT
    	// Interrupts that are used in this driver are re-mapped to
    	// ISR functions found within this file.
    	// EALLOW;  // This is needed to write to EALLOW protected registers
    	// PieVectTable.SCITXINTA = &sciTxFifoIsr;
    	// EDIS;   // This is needed to disable write to EALLOW protected registers
    	// PieCtrlRegs.PIEIER9.bit.INTx2 = 1;   /* Enable interrupt SCITXINTA*/
    	// IER |= M_INT9; //TODO: not sure about m_int9
       
        // Disable the TX buffer INT, Enable the TX FIFO INT durint put_data call only
        SciaRegs.SCICTL2.bit.TXINTENA = 0;     // 0      Transmit interrupt enable     (Disabled
        SciaRegs.SCIFFTX.bit.TXFFIENA = 0;      // 5      Interrupt enable           (Disabled)
    	Drv_Tx_Isr_Enabled = 0;
        
        transmit_rb.data = tx_data;
        transmit_rb.max_size = TX_RB_BUF_SIZE;
        transmit_rb.head = 0U;
        transmit_rb.tail = 0U;
        transmit_rb.size = 0U;
    #endif
       
    #ifdef RX_INTERRUPT   
    	// Interrupts that are used in this driver are re-mapped to
    	// ISR functions found within this file.
    	// EALLOW;  // This is needed to write to EALLOW protected registers
    	// PieVectTable.SCIRXINTA = &sciRxFifoIsr;
    	// EDIS;   // This is needed to disable write to EALLOW protected registers
    	// PieCtrlRegs.PIEIER9.bit.INTx1 = 1;   /* Enable interrupt SCIRXINTA*/
    	// IER |= M_INT9; //TODO: not sure about m_int9
      
        SciaRegs.SCIFFRX.bit.RXFFIENA = 1;      // 5      Interrupt enable       (Enabled)
    	Drv_Rx_Isr_Enabled = 1;
        SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;    // 6      Clear INT flag         (Clear)
        // Error interrupts disable, will be checked by sci_drv_read_data()
        SciaRegs.SCICTL1.bit.RXERRINTENA = 0;   // 6      Receive interrupt enable  (Disabled)
        SciaRegs.SCICTL2.bit.RXBKINTENA = 0;    // 1      Receiver-buffer break enable  (Disabled)
        
        recieve_rb.data = rx_data;
        recieve_rb.max_size = RX_RB_BUF_SIZE;
        recieve_rb.head = 0U;
        recieve_rb.tail = 0U;
        recieve_rb.size = 0U;
    #endif
    
    	Drv_Put_Debug_Value = 0;
    	Drv_Put_Debug_Value2 = 0;
    	Drv_Put_Status = 0;
    	Drv_Put_Err_Ctr = 0;
    	
    	Drv_Tx_Isr_Call_Ctr_c = 0;
    	Drv_Put_Call_Ctr = 0;
    	Drv_Rx_Isr_Call_Ctr_c = 0;
    	Drv_Read_Call_Ctr = 0;
    	
    	Drv_Read_Debug_Value = 0;
    	Drv_Read_Debug_Value2 = 0;
    	Drv_Read_Status = 0;
    	Drv_Read_Err_Ctr = 0;
       
       return;
    }
    
    /*******************************************************************************
     * @name sci_drv_put_data()
     *
     * @brief Write the desired number of bytes to the SCI TX bus through TX FIFO
     *        Note: DSP2803x has max FIFO size of 4 bytes
     *       
     * @param p_buffer, byte buffer for write bytes
     * @param num_bytes, desired number of bytes for TX
     *
     * @return SCI_DRV_ERR_NONE when bytes written correctly
     * @return SCI_DRV_ERR_TX_INT_NONE interrupt occurred without MAX_TX_FIFO_SIZE bytes
     * @return SCI_DRV_ERR_RB ring buffer error during TX interrupt
     * @return SCI_DRV_ERR_TX_OVERFLOW if num_bytes greater than FIFO/Ring Buffer size
     * @return SCI_DRV_ERR_TX_NOT_NUM_BYTES if num_bytes greater than Ring Buffer space
     * @return SCI_DRV_ERR_RB error occurred with ring buffer
     * @return SCI_DRV_ERR_INVALID_PARAMS if called with null pointers
     * @return SCI_DRV_ERR_NOT_INITIALIZED if SCI not initialized 
     ******************************************************************************/
    sci_drv_err_t sci_drv_put_data(uint8_t * p_buffer, uint16_t num_bytes)
    {
        sci_drv_err_t err_code = SCI_DRV_ERR_NONE;
    #ifndef TX_INTERRUPT
        uint8_t count = 0;
    #endif
    	Drv_Put_Status = 0;
    	uint16_t toggle_debug = 0U;
    	Drv_Tx_Isr_Call_Ctr = Drv_Tx_Isr_Call_Ctr_c;
    	
    	// if(toggle_debug){
    		// GpioDataRegs.GPACLEAR.bit.GPIO5=1;
    		// toggle_debug = 0U;
    	// }
    	// else 
    	// {
    		// GpioDataRegs.GPASET.bit.GPIO5=1;    
    		// toggle_debug = 1U;
    	// }
    	
        if(sci_port_initialized)
        {
    		
            if (NULL != p_buffer)
            {
    			if(Drv_Put_Err_Ctr==0)
    			{	//Get size of rb before error
    				Drv_Put_Debug_Value2 = transmit_rb.size;
    			}
    			
    #ifdef TX_INTERRUPT
                if(transmit_isr_err != SCI_DRV_ERR_NONE)
    			{
    				err_code = transmit_isr_err; // pass through any errors given by interrupt
                    transmit_isr_err = SCI_DRV_ERR_NONE;
    			}
                else if(num_bytes <= TX_RB_BUF_SIZE)
                {
    				Drv_Put_Debug_Value = transmit_rb.size;
                    if(num_bytes <= utils_rb_available_bytes(&transmit_rb))
                    {
                        if (ERR_UTILS_RB_NONE == utils_rb_put_data(&transmit_rb,
                                                                   p_buffer,
                                                                   num_bytes))
                        {
                            SciaRegs.SCIFFTX.bit.TXFFIENA = 1;      // 5      FIFO Interrupt enable      (Enabled)
                            Drv_Tx_Isr_Enabled = 1;
    						Drv_Put_Call_Ctr++;
                        }
                        else
                        {
                            err_code = SCI_DRV_ERR_RB;
                        }
                    }
                    else
                    {
                        err_code = SCI_DRV_ERR_TX_NOT_NUM_BYTES;
                    }
                }
                else 
                {
                    err_code = SCI_DRV_ERR_TX_OVERFLOW;
                }
    #else
                if(num_bytes <= MAX_TX_FIFO_SIZE)
                {
                    DINT; //Disable Interrupts while reading/writing SCI
                    for(count=0;count<num_bytes;count++)
                    {
                        while(!SciaRegs.SCICTL2.bit.TXRDY); //wait until buffer is available
                        SciaRegs.SCITXBUF = (p_buffer[count] & SCI_TXDT_MASK);
                    }
                    EINT; //Re-enable    
                }
                else 
                {
                    err_code = SCI_DRV_ERR_TX_OVERFLOW;
                }
    #endif
            }
            else
            {
                err_code = SCI_DRV_ERR_INVALID_PARAMS;
            }        
        }
        else
        {
            err_code = SCI_DRV_ERR_NOT_INITIALIZED;
        }
    	
    	if(err_code != SCI_DRV_ERR_NONE)
    	{
    		Drv_Put_Status = (uint16_t) err_code;
    		Drv_Put_Err_Ctr++;
    		
    	}
    	   
        return err_code;
    }
     
    /*******************************************************************************
     * @name sci_drv_TX_status()
     *
     * @brief Determine the availability of the TX buffer and FIFO
     *       
     * @param none
     *
     * @return SCI_DRV_ERR_NOT_INITIALIZED if SCI not initialized
     * @return SCI_DRV_ERR_TX_NOT_EMPTY if TX FIFO or buffer not empty
     * @return SCI_DRV_ERR_NONE if both FIFO and buffer are empty
     ******************************************************************************/
    sci_drv_err_t sci_drv_TX_status()
    {
        sci_drv_err_t err_code = SCI_DRV_ERR_NONE;
        if(sci_port_initialized)
        {
            DINT; //Disable Interrupts while reading/writing SCI
            if((SciaRegs.SCIFFTX.bit.TXFFST != 0) ||    //If FIFO
                (SciaRegs.SCICTL2.bit.TXEMPTY != 1))    //or buffer not empty
            {
                err_code = SCI_DRV_ERR_TX_NOT_EMPTY;
            }
            EINT; //Re-enable
        }
        else
        {
            err_code = SCI_DRV_ERR_NOT_INITIALIZED;
        }
        return err_code;    
    }
    
    /*******************************************************************************
     * @name sci_drv_get_read_size()
     *
     * @brief returns the number of bytes in the receive ring buffer
     *       
     * @param none
     *
     * @return number of bytes
     ******************************************************************************/
    uint16_t sci_drv_get_read_size(void)
    {
    	return recieve_rb.size;
    }
    
    /*******************************************************************************
     * @name sci_drv_read_data()
     *
     * @brief Read the desired number of bytes from the SCI RX bus through RX FIFO
     *       
     * @param p_buffer, byte buffer for read bytes
     * @param num_bytes, desired number of bytes from RX
     * @param p_num_returned, actual number of bytes read
     *
     * @return SCI_DRV_ERR_NONE when bytes read correctly
     * @return SCI_DRV_ERR_RB when ring buffer returns error
     * @return SCI_DRV_ERR_RX_RB_OVERFLOW when interrupt occurs and no space in RB
     * @return SCI_DRV_ERR_RX_NOT_NUM_BYTES when FIFO less than num_bytes 
     * @return SCI_DRV_ERR_RX_FIFO_OVERFLOW when FIFO overflowed from RX bytes 
     * @return SCI_DRV_ERR_RX_FIFO_FE_PE when FIFO bytes Frame or Parity error
     * @return SCI_DRV_ERR_RX_OE when RX over wrote while reading
     * @return SCI_DRV_ERR_RX_FE when RX bus had Frame error
     * @return SCI_DRV_ERR_RX_BRKDT when RX bus has Break Detect error
     * @return SCI_DRV_ERR_INVALID_PARAMS if called with null pointers, or too large
     * @return SCI_DRV_ERR_NOT_INITIALIZED if SCI not initialized
     ******************************************************************************/
    sci_drv_err_t sci_drv_read_data( uint16_t * p_buffer, 
                                    uint16_t num_bytes,
                                    uint16_t * p_num_returned)
    {
        sci_drv_err_t err_code = SCI_DRV_ERR_NONE;
        uint8_t count = 0; 
    #ifndef RX_INTERRUPT
        uint16_t data_bytes = 0;
    #endif
    	Drv_Rx_Isr_Call_Ctr = Drv_Rx_Isr_Call_Ctr_c;
    	
        if(sci_port_initialized)
        {
            if ((NULL != p_buffer)||(NULL != p_num_returned))
            {
    			
                DINT; //Disable Interrupts while reading/writing SCI
    #ifdef RX_INTERRUPT
                Drv_Read_Debug_Value2 = SciaRegs.SCIFFRX.all;
    			if(recieve_isr_err != SCI_DRV_ERR_NONE)
    			{
    				err_code = recieve_isr_err; // pass through any errors given by interrupt
                    recieve_isr_err = SCI_DRV_ERR_NONE; //clear isr error code
    				// none of the ISR errors should block read operation,
    				// nor are they higher priority than driver errors
    			} 
    			
    			if(num_bytes <= RX_RB_BUF_SIZE)
                {
    				//if(Drv_Read_Err_Ctr == 0)
    				//{ //get last rb size before err
    				//	Drv_Read_Debug_Value2 = recieve_rb.size;
    				//}
                    if(num_bytes <= recieve_rb.size)
                    {
    					Drv_Read_Debug_Value = recieve_rb.size;
                        if (ERR_UTILS_RB_NONE == utils_rb_get_data(&recieve_rb,
                                                                   p_buffer,
                                                                   num_bytes,
                                                                   p_num_returned))
                        {
    						Drv_Read_Call_Ctr++;
                            for(count=0;count<num_bytes;count++)
                            {
                                //check for errors, and parse out just data bytes
                                if((p_buffer[count] & SCI_FE_PE_MASK) != 0)
                                {
                                    err_code = SCI_DRV_ERR_RX_FIFO_FE_PE;
                                }
                                else if((p_buffer[count] & SCI_RXFFOVF_MASK) != 0)
                                {
                                    err_code = SCI_DRV_ERR_RX_FIFO_OVERFLOW;
                                }
                                p_buffer[count] = ((p_buffer[count] & SCI_RXDT_MASK));
                            }                        
                            
                        }
                        else
                        {
                            err_code = SCI_DRV_ERR_RB;
                        }
                    }
                    else
                    {
                        err_code = SCI_DRV_ERR_RX_NOT_NUM_BYTES;
                    }
    				
    				
                }
                else 
                {   // requested bytes too large for ring buffer
                    err_code = SCI_DRV_ERR_INVALID_PARAMS;
                }
    			
    			
    
    #else
                *p_num_returned = 0; //Initialize to none
                if(SciaRegs.SCIFFRX.bit.RXFFST >= num_bytes)
                {
                    //Read, if possible, num_bytes from RX FIFO
                    for(count=0;count<num_bytes;count++)
                    {
                        if(SciaRegs.SCIFFRX.bit.RXFFST != 0 ) // while bytes in RX FIFO keep processing
                        {
                            data_bytes = SciaRegs.SCIRXBUF.all;
                            
                            if(SciaRegs.SCIFFRX.bit.RXFFOVF)
                            {   // FIFO Overflow, may still be able to parse bytes
                                err_code = SCI_DRV_ERR_RX_FIFO_OVERFLOW;
                            }
                            
                            if((data_bytes & SCI_FE_PE_MASK) != 0)
                            {   // Frame or Parity errors have higher priority than Overflow, 
                                // and corrupt bytes
                                err_code = SCI_DRV_ERR_RX_FIFO_FE_PE;
                                break; //if error, stop reading bytes
                            }
                            else
                            {   // Desired correct action of reading bytes
                                p_buffer[count] = (uint8_t)(data_bytes & SCI_RXDT_MASK);
                                *p_num_returned = (count+1); // +1 for zero offset
                            }
                        }
                        else
                        {
                            //should not occur
                            err_code = SCI_DRV_ERR_RX_NOT_NUM_BYTES;
                            break; 
                        }  
                    }
                }
                else
                {
                    err_code = SCI_DRV_ERR_RX_NOT_NUM_BYTES;
                }
     
    #endif      
                // These SCI Signal errors require FIFO bytes to be discarded
                if(SciaRegs.SCIRXST.bit.OE)  
                {
                    err_code = SCI_DRV_ERR_RX_OE; //Needs SW Reset to clear
                }
                else if(SciaRegs.SCIRXST.bit.FE)  
                {
                    err_code = SCI_DRV_ERR_RX_FE; //Needs SW Reset to clear
                }
                else if(SciaRegs.SCIRXST.bit.BRKDT)  
                {
                    err_code = SCI_DRV_ERR_RX_BRKDT; //Needs SW Reset to clear
                }
                
                EINT; //Re-enable
            }
            else
            {
                err_code = SCI_DRV_ERR_INVALID_PARAMS;
            }
        }
        else
        {
            err_code = SCI_DRV_ERR_NOT_INITIALIZED;
        }
    	
    	if(err_code != SCI_DRV_ERR_NONE)
    	{
    		Drv_Read_Status = (uint16_t) err_code;
    		Drv_Read_Err_Ctr++;
    	}
        return err_code;    
    }
    
    /*******************************************************************************
     * @name sci_drv_RX_enable()
     *
     * @brief Enables the SCI RX read buffer, FIFO, and (if applicable) interrupts
     *       
     * @param none
     *
     * @return SCI_DRV_ERR_NOT_INITIALIZED if SCI not initialized
     * @return SCI_DRV_ERR_NONE after proper enable
     ******************************************************************************/ 
    sci_drv_err_t sci_drv_RX_enable()
    {
        sci_drv_err_t err_code = SCI_DRV_ERR_NONE;
        if(sci_port_initialized)
        {
            SciaRegs.SCIFFRX.bit.RXFFIL = 0x4;      // 4:0    Interrupt level        (Match four bytes)
    #ifdef RX_INTERRUPT
            SciaRegs.SCIFFRX.bit.RXFFIENA = 1;      // 5      Interrupt enable       (Enabled)
    		Drv_Rx_Isr_Enabled = 1;
            SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;    // 6      Clear INT flag         (Clear)
            //SciaRegs.SCIFFRX.bit.RXFFINT = 0;//   // 7      INT flag               (Read Only)
            SciaRegs.SCIFFTX.bit.SCIFFENA = 1;      // 14     Enhancement enable         (Enabled)
    #endif
            //SciaRegs.SCIFFRX.bit.RXFFST = 0x0;//  // 12:8   FIFO status            (Read Only)
            SciaRegs.SCIFFRX.bit.RXFIFORESET = 1;   // 13     FIFO reset             (Enable FIFO)
            SciaRegs.SCIFFRX.bit.RXFFOVRCLR = 1;    // 14     Clear overflow         (Clear)
            //SciaRegs.SCIFFRX.bit.RXFFOVF = 0;//   // 15     FIFO overflow          (Read Only)
    
            SciaRegs.SCICTL1.bit.RXENA = 1;         // 0      SCI receiver enable       (Enabled)
    #ifdef RX_INTERRUPT
            // Error interrupts disable, will be checked by sci_drv_read_data()
            SciaRegs.SCICTL1.bit.RXERRINTENA = 0;   // 6      Receive interrupt enable  (Disabled)
            SciaRegs.SCICTL2.bit.RXBKINTENA = 0;    // 1      Receiver-buffer break enable  (Disabled)
    #endif            
        }
        else
        {
            err_code = SCI_DRV_ERR_NOT_INITIALIZED;
        }
        return err_code;    
    }
    
    /*******************************************************************************
     * @name sci_drv_RX_disable()
     *
     * @brief Disables the SCI RX read buffer, FIFO, and (if applicable) interrupts
     *       
     * @param none
     *
     * @return SCI_DRV_ERR_NOT_INITIALIZED if SCI not initialized
     * @return SCI_DRV_ERR_NONE after proper disable
     ******************************************************************************/ 
    sci_drv_err_t sci_drv_RX_disable()
    {
        sci_drv_err_t err_code = SCI_DRV_ERR_NONE;
        if(sci_port_initialized)
        {
            SciaRegs.SCIFFRX.bit.RXFFIL = 0x4;      // 4:0    Interrupt level        (Match four bytes)
    #ifdef RX_INTERRUPT
            SciaRegs.SCIFFRX.bit.RXFFIENA = 0;      // 5      Interrupt enable       (Disabled)
    		Drv_Rx_Isr_Enabled = 0;
            SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;    // 6      Clear INT flag         (Clear)
            //SciaRegs.SCIFFRX.bit.RXFFINT = 0;//   // 7      INT flag               (Read Only)
            
            //controls normal or FIFO interrupt
            SciaRegs.SCIFFTX.bit.SCIFFENA = 1;      // 14     Enhancement enable         (Enabled)
    #endif
            //SciaRegs.SCIFFRX.bit.RXFFST = 0x0;//  // 12:8   FIFO status            (Read Only)
            SciaRegs.SCIFFRX.bit.RXFIFORESET = 0;   // 13     FIFO reset             (Disable FIFO)
            SciaRegs.SCIFFRX.bit.RXFFOVRCLR = 0;    // 14     Clear overflow         (No clear)
            //SciaRegs.SCIFFRX.bit.RXFFOVF = 0;//   // 15     FIFO overflow          (Read Only)
    
            SciaRegs.SCICTL1.bit.RXENA = 0;         // 0      SCI receiver enable       (Disabled)
    #ifdef RX_INTERRUPT
            SciaRegs.SCICTL1.bit.RXERRINTENA = 0;   // 6      Receive interrupt enable  (Disabled)
            SciaRegs.SCICTL2.bit.RXBKINTENA = 0;   // 1      Receiver-buffer break enable  (Disabled)
    #endif        
        }
        else
        {
            err_code = SCI_DRV_ERR_NOT_INITIALIZED;
        }
        return err_code;    
    }
    
    /*******************************************************************************
     * @name sci_drv_TX_enable()
     *
     * @brief Enables the SCI TX write buffer, FIFO, and (if applicable) interrupts
     *       
     * @param none
     *
     * @return SCI_DRV_ERR_NOT_INITIALIZED if SCI not initialized
     * @return SCI_DRV_ERR_NONE after proper enable
     ******************************************************************************/ 
    sci_drv_err_t sci_drv_TX_enable()
    {
        sci_drv_err_t err_code = SCI_DRV_ERR_NONE;
        if(sci_port_initialized)
        {
            SciaRegs.SCICTL1.bit.TXENA = 1;         // 1      SCI transmitter enable    (Enabled)
    #ifdef TX_INTERRUPT        
            SciaRegs.SCICTL2.bit.TXINTENA = 0;     // 0      Transmit interrupt enable     (Disabled)
            SciaRegs.SCIFFTX.bit.TXFFIENA = 1;      // 5      FIFO Interrupt enable      (Enabled)
    		Drv_Tx_Isr_Enabled = 1;
    #endif        
            SciaRegs.SCIFFTX.bit.TXFFIL = 0x0;      // 4:0    Interrupt level            (Match zero bytes)
            
            SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1;    // 6      Clear INT flag             (Clear)
            //SciaRegs.SCIFFTX.bit.TXFFINT = 0;     // 7      INT flag                   (Read Only)
            //SciaRegs.SCIFFTX.bit.TXFFST = 0x0;//  // 12:8   FIFO status                (Read Only)
            SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 1;  // 13     FIFO reset                 (Re-enable FIFO)  
            SciaRegs.SCIFFTX.bit.SCIFFENA = 1;      // 14     Enhancement enable         (Enabled)
            // no SCIRST change
        }
        else
        {
            err_code = SCI_DRV_ERR_NOT_INITIALIZED;
        }
        return err_code;    
    }
    
    /*******************************************************************************
     * @name sci_drv_TX_disable()
     *
     * @brief Disables the SCI TX write buffer, FIFO, and (if applicable) interrupts
     *       
     * @param none
     *
     * @return SCI_DRV_ERR_NOT_INITIALIZED if SCI not initialized
     * @return SCI_DRV_ERR_NONE after proper disable
     ******************************************************************************/ 
    sci_drv_err_t sci_drv_TX_disable()
    {
        sci_drv_err_t err_code = SCI_DRV_ERR_NONE;
        if(sci_port_initialized)
        {
            SciaRegs.SCICTL1.bit.TXENA = 1;         // 0      SCI transmitter enable    (Disabled)		 TODO: check logic
    #ifdef TX_INTERRUPT        
            SciaRegs.SCICTL2.bit.TXINTENA = 0;     // 0      Transmit interrupt enable     (Disabled)
            SciaRegs.SCIFFTX.bit.TXFFIENA = 0;      // 5      FIFO Interrupt enable      (Disabled)
    		Drv_Tx_Isr_Enabled = 0;
    #endif        
            SciaRegs.SCIFFTX.bit.TXFFIL = 0x0;      // 4:0    Interrupt level            (Match zero bytes)
            
            SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1;    // 6      Clear INT flag             (Clear)
            //SciaRegs.SCIFFTX.bit.TXFFINT = 0;     // 7      INT flag                   (Read Only)
            //SciaRegs.SCIFFTX.bit.TXFFST = 0x0;//  // 12:8   FIFO status                (Read Only)
            SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 0;  // 13     FIFO reset                 (Clear FIFO)  
            SciaRegs.SCIFFTX.bit.SCIFFENA = 1;      // 14     Enhancement enable         (Enabled)
            // no SCIRST change
        }
        else
        {
            err_code = SCI_DRV_ERR_NOT_INITIALIZED;
        }
        return err_code;    
    }
    
    
    #ifdef TX_INTERRUPT
    /*******************************************************************************
     * @name sciTxFifoIsr()
     *
     * @brief This function is the ISR for the TX FIFO interrupt
     *       
     * @param none
     *
     * @return none  
     ******************************************************************************/
    void sciTxFifoIsr(void)
    {
        uint16_t data_bytes[MAX_TX_FIFO_SIZE] = {0U};
        uint16_t count = 0U;
        uint16_t num_bytes_used = 0U;
        Drv_Tx_Isr_Call_Ctr_c++;
    	    
    	
    	if(Drv_Tx_Isr_Call_Ctr_c <= DEBUG_ARRAY_SIZE)
    	{
    		Drv_TX_isr_log_1[Drv_Tx_Isr_Call_Ctr_c-1] = SciaRegs.SCIFFTX.bit.TXFFST;
    		Drv_TX_isr_log_2[Drv_Tx_Isr_Call_Ctr_c-1] = transmit_rb.size;
    	}
    	
        if(SciaRegs.SCIFFTX.bit.TXFFST != 0U)
    	{
    		transmit_isr_err = SCI_DRV_ERR_TX_NOT_EMPTY;
    	}
    	else if(transmit_rb.size >= MAX_TX_FIFO_SIZE) //prevent underflow
        {   
            if(ERR_UTILS_RB_NONE == utils_rb_get_data(  &transmit_rb,
                                                        &(data_bytes[0]),
                                                        MAX_TX_FIFO_SIZE,
                                                        &num_bytes_used))
            {
                //no error, no action
            }
            else
            {   // no error should be possible, as null params and underflow prevented
                transmit_isr_err = SCI_DRV_ERR_RB;
            }
                
            for(count=0U;count<MAX_TX_FIFO_SIZE;count++)
            {
                //while(!SciaRegs.SCICTL2.bit.TXRDY); //wait until buffer is available
                SciaRegs.SCITXBUF = (data_bytes[count] & SCI_TXDT_MASK);
            }
    		
    		if(transmit_rb.size <= MAX_TX_FIFO_SIZE)
    		{	//if RB emptyish, stop interupts
    			SciaRegs.SCIFFTX.bit.TXFFIENA = 0;      // 5      FIFO Interrupt enable      (Disabled)
    			Drv_Tx_Isr_Enabled = 0;
    		}
        }
        else
        {   // not enough bytes (full packet) available for TX FIFO
            transmit_isr_err = SCI_DRV_ERR_TX_INT_NONE;
        }
        
        SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;  // Clear SCI Interrupt flag
        //PieCtrlRegs.PIEACK.all|=0x100;      // Issue PIE ACK
    }
    #endif
    
    #ifdef RX_INTERRUPT 
    /*******************************************************************************
     * @name sciRxFifoIsr()
     *
     * @brief This function is the ISR for the RX FIFO interrupt
     *       
     * @param none
     *
     * @return none  
     ******************************************************************************/
    void sciRxFifoIsr(void)
    {
        uint16_t data_bytes[MAX_RX_FIFO_SIZE] = {0U};
        uint16_t count = 0U;
    	static uint16_t debug_count = 0U;
    	
    	Drv_Rx_Isr_Call_Ctr_c++;
    	
        if(SciaRegs.SCIFFRX.bit.RXFFST != MAX_RX_FIFO_SIZE )
        {
            recieve_isr_err = SCI_DRV_ERR_RX_NOT_NUM_BYTES;
        }
        
        for(count=0U;count<MAX_RX_FIFO_SIZE;count++)
        {
            if(SciaRegs.SCIFFRX.bit.RXFFST != 0U ) // while bytes in RX FIFO keep processing
            {   //shift in RXFFOVF bit for later error checking
                data_bytes[count] =((SciaRegs.SCIRXBUF.all) |
                             (SciaRegs.SCIFFRX.bit.RXFFOVF << SCI_RXFFOVF_SHIFT));
            }
            //else condition bytes will show up as corrupted packet
        }
        
        if(ERR_UTILS_RB_NONE == utils_rb_put_data(  &recieve_rb,
                                                    &(data_bytes[0]),
                                                    MAX_RX_FIFO_SIZE))
        {
            //no error, no action
        }
        else
        {   // only ring buffer error possible is overflow
            recieve_isr_err = SCI_DRV_ERR_RX_RB_OVERFLOW;
        }
    	
    	
    	if((recieve_isr_err == SCI_DRV_ERR_NONE ) && (debug_count <= DEBUG_ARRAY_SIZE))
    	{
    		Drv_RX_isr_log_1[debug_count+0] = data_bytes[0];
    		Drv_RX_isr_log_1[debug_count+1] = data_bytes[1];
    		Drv_RX_isr_log_1[debug_count+2] = data_bytes[2];
    		Drv_RX_isr_log_1[debug_count+3] = data_bytes[3];
    		
    		Drv_RX_isr_log_2[debug_count] = recieve_rb.size;
    		Drv_RX_isr_log_2[debug_count+1] = 0;
    		Drv_RX_isr_log_2[debug_count+2] = 0;
    		Drv_RX_isr_log_2[debug_count+3] = 0;
    		
    		
    		debug_count=debug_count+4;
    	}
    	else 
    	{
    		debug_count = 0;
    	}
        
        SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1;   // Clear Overflow flag
        SciaRegs.SCIFFRX.bit.RXFFINTCLR=1;   // Clear Interrupt flag
    
        //PieCtrlRegs.PIEACK.all|=0x100;       // Issue PIE ack
    }
    #endif
    

  • Hi,

    If you are using the FIFO, do not use TXEMPTY (line 420).

    The only reason I can think that you are not seeing RXFFST ==4, is that by the time the interrupt has been triggered, one of the bytes has shifted into the RXBUF and is out of the FIFO and ready to be read from the receive buffer. This is likely why you are not seeing this every time, but only sometimes. It has to do with speed the data is being received.

    It sounds like your FIFO is overflowing on the received side. Are you loosing data? Depending on your system, your ISR may not be able to empty the FIFO in time. If this is the case, you can make system changes. For example, you can enable the RX interrupt to nest other interrupts.

    Regards,
    sal
  • I am a bit confused.
    We read the bytes from the FIFO by reading SCIRXBUF.
    If I trigger when RXFFLV is 4, and then RXFFST != 4, do I still read SCIRXBUF four times?
    How do I know actually how much data to read?

    Yes I'm definitely losing packets. I thought the FFTXDL = 4 would help me read the FIFO before the next byte came it, but its not much better, and do to timing requirements, I cannot fit a larger delay.
    I need to send a maximum of 20 bytes once a millisecond, so my current math is 20 bytes*(8+4)bits / 267857 baud = 0.896 milliseconds.
    I don't want to push the boundry much more than that.
    My RX FIFO should trigger every four bytes, for 5 times a millisecond, and similar math on my transmit side.
    I have a CAN Receive Interrupt (which receives human sent command infrequently), and one millisecond timer count interrupt.
    So, I'm not sure that nesting interrupts would change much about my RX FIFO.
    Is increasing my baud rate, and increasing the delays between, a way to help the TX FIFO read out before next byte? Or does that just introduce bus error?
  • I am having an expert look into the first part of the question.

    I have not tested SCI at such a high baud rate. The highest I have communicated was 115200. The baud rate you are using is more than double that.

    Can you try lowering your baud rate and seeing if you are experiencing the same issues?

    sal
  • Unfortunately, decreasing the baud rate would not allow me to send all my data in time.
    I am oscilloscope-ing the actual SCI bus with a oscilloscope protocol analyzer, and the signal itself is fine, the analyzer sees no errors with the signal or bytes.

    Is there a way for the RXFFINT flag to be high, and the interrupt routine not be called?
    By debugging has shown me that sometimes my sciRxFifoIsr function is called for a few thousand times, and then stops incremententing, even though I can see the RXFFINT flag is high.

    Any word about the RXFFST != 4 question?
  • I believe I have found and fixed the root of my problems. Another interrupt in the system that I was unaware of had a higher priority, and was interfering with receive timing.

    However, I am still interested in the question:
    "If I trigger when RXFFLV is 4, and then RXFFST != 4, do I still read SCIRXBUF four times?
    How do I know actually how much data to read?"

    Can I get an estimated response time for the expert help?
  • Firstly, this particular post did not resolve my issue.
    Secondly, I have outstanding questions that have not been resolved, and have not received further response for over a week.
  • Neal,

    if another ISR has preempted the RX ISR then the FIFO will likely have more that 4 values in it when you finally service the interrupt. The buffer will continue to fill normally even after RXFFIL causes an interrupt so you shouldn't have any issues because of this. If you want to read out all values in the buffer simply read RXFFST  register and then read that many words from the RX FIFO.

    Regards,
    Cody