@@ -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