I have an application scenario on the F28069 Piccolo for using the SCI port in FIFO mode. I have been writing a new scistdio.c module (similar to the F28069 Mware uartstdio.c module) that makes use of the new Launchpad/ Motorware-style sci.c driver (sci_xxx apis) rather than the older uart.c driver (which would appear to have been ported from Mware for Concerto or MSP430) or the older F2806x_Sci.c controlSuite example SCI code.
I am not sure that the existing uartstdio.c code from F2806x Mware ever worked properly on the F2806x with SCI FIFO mode enabled (#define UART_BUFFERED 1). Has this been tested? This code seems to use the SCI TX Interrupt (enabled by TXINTENA) rather than the SCI TX FIFO interrupt (enabled by TXFFIENA), and it uses the SCI TXRDY flag rather than TXFFIL to see if there is FIFO space available. I think that TXRDY should only be used for non-fifo mode Tx interrupt operation. Another thing I notice is that the UARTStdioIntHandler() sometimes checks to see if the TX FIFO is empty before turning off the transmit interrupt TXINTENA in one case, but in another instance will unconditionally enable TXINTENA before exiting (even when the FIFO is not yet empty). I am concerned that when there is no data to send, the interrupt signal will be continuously active and the software will spend all its time servicing the interrupt.
The existing Mware uartstdio.c file has the following ISR:
void UARTStdioIntHandler(void)
{
. . .
// Are we being interrupted because the TX FIFO has space available?
if(ulInts & UART_INT_TX)
{
// Move as many bytes as we can into the transmit FIFO.
UARTPrimeTransmit(g_ulBase);
// If the output buffer is empty, turn off the transmit interrupt.
if(TX_BUFFER_EMPTY)
{
UARTIntDisable(g_ulBase, UART_INT_TX);
}
}
// Are we being interrupted due to a received character?
if(ulInts & (UART_INT_RX | UART_INT_RT))
{
. . .
// If we wrote anything to the Tx transmit buffer while handling Rx int (e.g. for echo),
// make sure it actually gets transmitted.
UARTPrimeTransmit(g_ulBase);
UARTIntEnable(g_ulBase, UART_INT_TX); // <-- I'm not sure Tx interrupt should be
// unconditionally enabled, rather
// than only enabling if
// !TX_BUFFER_EMPTY.
}
}
For my application needs (creating a buffered stdio layer on top of sci.c driver) the data will be sent via SCI only occasionally (read from a ring buffer and sent to the TX SCI-A FIFO). The software needs to get an interrupt from the transmitter only when the SCI is ready for data AND when there is available data to send from my output ring buffer. Otherwise, when there is no data to send, the interrupt signal will be continuously active and the software will spend all its time servicing the interrupt.
If I understand the SPRUH18D Piccolo TRM technical reference manual correctly in section 13, the SCI transmit Tx FIFO interrupt indicates when the SCI is ready to accept data when the FIFO status bits (TXFFST4−0) are less than or equal to the FIFO interrupt level bits TXFFIL4−0 (which identify the "low water level"). For most SCI FIFO applications (including the Example_2802xSci_FFDLB_int.c loopback example) I assume that when the interrupt is enabled and TXFFST <= TXFFIL, an interrupt will occur whether there is any data to be sent or not. Although this may not be an issue for the loopback example , for my case I don't want constant FIFO interrupts when there is no data to send.
Should the following code work or would could it be improved?
interrupt void sciTxFifoIsr(void)
{
// Disable the SCI Tx FIFO interrupt (if it isn't already disabled when TX SCI FIFO is empty)
SCI_disableTxFifoInt(mySci);
// While there is space available in SCI FIFO (not full) and there is data available from ring buffer
// take some characters out of the transmit ring buffer and feed them to SCI Tx FIFO
while ((SCI_getTxFifoStatus(mySci) < SCI_FifoLevel_4_Words) && // like UARTSpaceAvail()
!TX_BUFFER_EMPTY)
{
// Send next data byte from Tx ring buffer to SCI
SCI_write(mySci, pcSciTxBuffer[ulSciTxReadIndex]);
ADVANCE_TX_BUFFER_INDEX(ulSciTxReadIndex); // Macro advances ring buf index (wraps)
}
// If the ring buffer is still not empty (data available), then we exited the while loop above
// because the SCI FIFO is full. So reenable the SCI FIFO interrupt for next time FIFO is empty
if ( !TX_BUFFER_EMPTY)
{
SCI_enableTxFifoInt(mySci);
}
// Clear SCI Fifo Interrupt flag
SCI_clearTxFifoInt(mySci);
// Issue PIE ACAK
PIE_clearInt(myPie, PIE_GroupNumber_9);
return;
}
My task-time (non-ISR) code will also call SCI_enableTxFifoInt(mySci) when done writing to my ring buffer indicating that data is available.
Comments? Suggestions?