Hi everyone,
I am trying to send data trough UART and since I have a lot of data I tam trying to use a buffered UART.
I attached the code. For this example I transmit ASCII characters 1-20 to a terminal. Only 0,1 and 3 are sent and the Tx interrupt stops after even if the TXFFINT Flag is set.
If I increase the TXFFIL to 3 I 0,1,2,3,4 and 5 will be sent and stop after
Thank you for your help
Hamid
#define FIFO_BUFFER_SIZE 128 // software buffer size (in bytes)
void uart_send_byte(Uint8 byte);
typedef struct {
Uint8 data_buf[FIFO_BUFFER_SIZE]; // FIFO buffer
Uint16 i_first; // index of oldest data byte in buffer
Uint16 i_last; // index of newest data byte in buffer
Uint16 num_bytes; // number of bytes currently in buffer
}sw_fifo_typedef;
sw_fifo_typedef rx_fifo = { {0}, 0, 0, 0 }; // declare a receive software buffer
sw_fifo_typedef tx_fifo = { {0}, 0, 0, 0 }; // declare a transmit software buffer
volatile Uint8 uart_rx_fifo_not_empty_flag = 0;
volatile Uint8 uart_rx_fifo_full_flag = 0;
volatile Uint8 uart_rx_fifo_ovf_flag = 0;
volatile Uint8 uart_tx_fifo_full_flag = 0;
volatile Uint8 uart_tx_fifo_ovf_flag = 0;
volatile Uint8 uart_tx_fifo_not_empty_flag = 0;
main
{
/*
Init code
*/
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.SCIRXINTA = &sciaRxFifoIsr;
PieVectTable.SCITXINTA = &sciaTxFifoIsr;
EDIS; // This is needed to disable write to EALLOW protected registers
scia_fifo_init(); // Init SCI-A
// Enable interrupts required for this example
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
PieCtrlRegs.PIEIER9.bit.INTx1=1; // PIE Group 9, INT1
PieCtrlRegs.PIEIER9.bit.INTx2=1; // PIE Group 9, INT2
IER = 0x100; // Enable CPU INT
EINT;
SciaRegs.SCIFFTX.bit.TXFFIENA=1;
// transmit ASCII characters 1-20
for(i=0; i<20; i++) {
while(uart_tx_fifo_full_flag);
uart_send_byte(i+48);
}
while(1);
}
void scia_fifo_init()
{
SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
SciaRegs.SCICTL2.bit.TXINTENA =1;
SciaRegs.SCICTL2.bit.RXBKINTENA =0;
SciaRegs.SCIHBAUD = 0x0000;
SciaRegs.SCILBAUD = SCI_PRD;
SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back
SciaRegs.SCIFFTX.all=0xC040;
// SciaRegs.SCIFFRX.all=0x0022;
SciaRegs.SCIFFRX.all=0x0022;
SciaRegs.SCIFFCT.all=0x00;
SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1;
SciaRegs.SCIFFRX.bit.RXFIFORESET=1;
}
//////////////////////////////////////////////
__interrupt void sciaTxFifoIsr(void) {
//////////////////////////////////////////////
if(tx_fifo.num_bytes == FIFO_BUFFER_SIZE) { // if the sw buffer is full
uart_tx_fifo_full_flag = 0; // clear the buffer full flag because we are about to make room
}
if(tx_fifo.num_bytes > 0) { // if data exists in the sw buffer
SciaRegs.SCITXBUF = tx_fifo.data_buf[tx_fifo.i_first]; // place oldest data element in the TX hardware buffer
tx_fifo.i_first++; // increment the index of the oldest element
tx_fifo.num_bytes--; // decrement the bytes counter
}
if(tx_fifo.i_first == FIFO_BUFFER_SIZE) { // if the index has reached the end of the buffer,
tx_fifo.i_first = 0; // roll over the index counter
}
if(tx_fifo.num_bytes == 0) { // if no more data exists
uart_tx_fifo_not_empty_flag = 0; // clear flag
SciaRegs.SCIFFTX.bit.TXFFIENA = 0; // disable FIFO interrupts
SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1; // clear TX FIFO interrupts
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK
}
}
/***************************************************************************************************************/
void uart_send_byte(Uint8 byte) {
///////////////////////////////////////////////////////////
/* disable interrupts while manipulating buffer pointers */
///////////////////////////////////////////////////////////
DINT; // Dnable Global interrupt INTM
if(tx_fifo.num_bytes == FIFO_BUFFER_SIZE) { // no room in the sw buffer
uart_tx_fifo_ovf_flag = 1; // set the overflow flag
}else if(tx_fifo.num_bytes < FIFO_BUFFER_SIZE) { // if there's room in the sw buffer
tx_fifo.data_buf[tx_fifo.i_last] = byte; // transfer data byte to sw buffer
tx_fifo.i_last++; // increment the index of the most recently added element
tx_fifo.num_bytes++; // increment the bytes counter
}
if(tx_fifo.num_bytes == FIFO_BUFFER_SIZE) { // if sw buffer is full
uart_tx_fifo_full_flag = 1; // set the TX FIFO full flag
}
if(tx_fifo.i_last == FIFO_BUFFER_SIZE) { // if the "new data" index has reached the end of the buffer,
tx_fifo.i_last = 0; // roll over the index counter
}
///////////////////////
/* enable interrupts */
///////////////////////
EINT; // Enable Global interrupt INTM
if(tx_fifo.num_bytes > 0) { // if there is data in the buffer
uart_tx_fifo_not_empty_flag = 1; // set flag
/* enable UART "TX hw buffer empty" interrupt here */
SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1; // Try and clear the TX FIFO interrupt that gets flagged...
SciaRegs.SCIFFTX.bit.TXFFIENA=1;
}
}