Skip to content

Commit 827720a

Browse files
committed
Adding buffering of TX chars
1 parent b253f71 commit 827720a

File tree

1 file changed

+65
-12
lines changed

1 file changed

+65
-12
lines changed

cores/arduino/ard_sup/uart/ap3_uart.cpp

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -119,17 +119,42 @@ size_t Uart::write(const uint8_t *buffer, size_t size)
119119
{
120120
uint32_t ui32BytesWritten = 0;
121121

122-
// todo: use a local buffer to guarantee lifespan of data (maybe txbuffer, but maybe not a ring buffer? b/c of efficiency + not breaking up transfers)
122+
//FIFO on Apollo3 is 32 bytes
123123

124-
const am_hal_uart_transfer_t sUartWrite =
125-
{
126-
.ui32Direction = AM_HAL_UART_WRITE,
127-
.pui8Data = (uint8_t *)buffer,
128-
.ui32NumBytes = size,
129-
.ui32TimeoutMs = AM_HAL_UART_WAIT_FOREVER,
130-
.pui32BytesTransferred = (uint32_t *)&ui32BytesWritten,
131-
};
132-
am_hal_uart_transfer(_handle, &sUartWrite);
124+
//If TX UART is sitting idle, load it. This will start the ISR TX handler as well.
125+
uint32_t uartFlags = 0;
126+
am_hal_uart_flags_get(_handle, &uartFlags);
127+
128+
// am_hal_uart_tx_flush(_handle);
129+
if (uartFlags & AM_HAL_UART_FR_TX_EMPTY)
130+
//if (1)
131+
{
132+
uint32_t amtToSend = size;
133+
if (amtToSend > AM_HAL_UART_FIFO_MAX)
134+
amtToSend = AM_HAL_UART_FIFO_MAX;
135+
136+
//Transfer to local buffer
137+
uint8_t tempTX[AM_HAL_UART_FIFO_MAX];
138+
for (int x = 0; x < amtToSend; x++)
139+
tempTX[x] = _tx_buffer.read_char();
140+
141+
const am_hal_uart_transfer_t sUartWrite =
142+
{
143+
.ui32Direction = AM_HAL_UART_WRITE,
144+
.pui8Data = (uint8_t *)buffer,
145+
.ui32NumBytes = size,
146+
.ui32TimeoutMs = 0, //Use non-blocking xfer
147+
.pui32BytesTransferred = (uint32_t *)&ui32BytesWritten,
148+
};
149+
am_hal_uart_transfer(_handle, &sUartWrite);
150+
}
151+
else
152+
{
153+
//UART is already sending bytes so load the ring buffer instead
154+
for (int x = 0; x < size; x++)
155+
_tx_buffer.store_char(buffer[x]);
156+
ui32BytesWritten = size;
157+
}
133158
return ui32BytesWritten;
134159
}
135160

@@ -370,9 +395,9 @@ ap3_err_t Uart::_begin(void)
370395

371396
UARTn(_instance)->LCRH_b.FEN = 0; // Disable that pesky FIFO
372397

373-
// Enable RX interrupts
398+
// Enable TX and RX interrupts
374399
NVIC_EnableIRQ((IRQn_Type)(UART0_IRQn + _instance));
375-
am_hal_uart_interrupt_enable(_handle, (AM_HAL_UART_INT_RX));
400+
am_hal_uart_interrupt_enable(_handle, (AM_HAL_UART_INT_RX | AM_HAL_UART_INT_TX));
376401
am_hal_interrupt_master_enable();
377402

378403
// Register the class into the local list
@@ -517,6 +542,34 @@ inline void Uart::rx_isr(void)
517542
_rx_buffer.store_char(rx_c);
518543
}
519544
}
545+
546+
if (ui32Status & AM_HAL_UART_INT_TX)
547+
{
548+
//If bytes are sitting in TX buffer, load them into UART buffer for transfer
549+
if (_tx_buffer.available())
550+
{
551+
uint32_t ui32BytesWritten = 0;
552+
553+
uint32_t amtToSend = _tx_buffer.available();
554+
if (amtToSend > AM_HAL_UART_FIFO_MAX)
555+
amtToSend = AM_HAL_UART_FIFO_MAX;
556+
557+
//Transfer to local buffer
558+
uint8_t tempTX[AM_HAL_UART_FIFO_MAX];
559+
for (int x = 0; x < amtToSend; x++)
560+
tempTX[x] = _tx_buffer.read_char();
561+
562+
const am_hal_uart_transfer_t sUartWrite =
563+
{
564+
.ui32Direction = AM_HAL_UART_WRITE,
565+
.pui8Data = (uint8_t *)tempTX,
566+
.ui32NumBytes = (uint32_t)amtToSend,
567+
.ui32TimeoutMs = AM_HAL_UART_WAIT_FOREVER,
568+
.pui32BytesTransferred = (uint32_t *)&ui32BytesWritten,
569+
};
570+
am_hal_uart_transfer(_handle, &sUartWrite);
571+
}
572+
}
520573
}
521574

522575
// Individual ISR implementations for the two UART peripherals on the Apollo3

0 commit comments

Comments
 (0)