@@ -117,48 +117,50 @@ size_t Uart::write(const uint8_t data)
117117
118118size_t Uart::write (const uint8_t *buffer, size_t size)
119119{
120- uint32_t ui32BytesWritten = 0 ;
121- uint32_t remaining = size ;
120+ uint32_t ui32TransferBytesWritten = 0 ;
121+ uint32_t ui32TotalBytesWritten = 0 ;
122122
123- // FIFO on Apollo3 is 32 bytes
124-
125- // If TX UART is sitting idle, load it. This will start the ISR TX handler as well.
126- uint32_t uartFlags;
127- am_hal_uart_flags_get (_handle, &uartFlags);
128- if (uartFlags & AM_HAL_UART_FR_TX_EMPTY)
123+ //
124+ // Print the string via the UART.
125+ //
126+ am_hal_uart_transfer_t sUartWrite =
127+ {
128+ .ui32Direction = AM_HAL_UART_WRITE,
129+ .pui8Data = NULL ,
130+ .ui32NumBytes = 0 ,
131+ .ui32TimeoutMs = 0 ,
132+ .pui32BytesTransferred = &ui32TransferBytesWritten,
133+ };
134+
135+ do
129136 {
130- uint32_t amtToSend = remaining;
131- if (amtToSend > AM_HAL_UART_FIFO_MAX)
132- amtToSend = AM_HAL_UART_FIFO_MAX;
137+ while (!_tx_idle)
138+ {
139+ }; // wait for tx to become idle
133140
134- remaining -= amtToSend;
141+ sUartWrite .pui8Data = (uint8_t *)((uint8_t *)buffer + ui32TotalBytesWritten);
142+ sUartWrite .ui32NumBytes = (size > AP3_UART_LINBUFF_SIZE) ? AP3_UART_LINBUFF_SIZE : size;
143+ am_hal_uart_transfer (_handle, &sUartWrite );
135144
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] = buffer[x];
145+ ui32TotalBytesWritten += ui32TransferBytesWritten;
140146
141- const am_hal_uart_transfer_t sUartWrite =
142- {
143- .ui32Direction = AM_HAL_UART_WRITE,
144- .pui8Data = (uint8_t *)tempTX,
145- .ui32NumBytes = amtToSend,
146- .ui32TimeoutMs = AM_HAL_UART_WAIT_FOREVER,
147- .pui32BytesTransferred = (uint32_t *)&ui32BytesWritten,
148- };
149- am_hal_uart_transfer (_handle, &sUartWrite );
150- }
147+ } while (ui32TotalBytesWritten < size);
151148
152- // Transfer any remaining bytes into ring buffer
153- for (int x = size - remaining; x < size; x++)
149+ if (ui32TotalBytesWritten != size)
154150 {
155- // If TX ring buffer is full, begin blocking
156- while (_tx_buffer.availableForStore () == 0 )
157- delay (1 );
158- _tx_buffer.store_char (buffer[x]);
151+ //
152+ // Couldn't send the whole string!!
153+ //
154+ while (1 )
155+ {
156+ digitalWrite (LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
157+ delay (50 ); // wait for a second
158+ digitalWrite (LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
159+ delay (50 );
160+ }
159161 }
160162
161- return ui32BytesWritten ; // Return number of bytes pushed to UART hardware
163+ return ui32TotalBytesWritten ; // Return number of bytes pushed to UART hardware
162164}
163165
164166// Stop Bits
@@ -303,6 +305,12 @@ ap3_err_t Uart::_begin(void)
303305 am_hal_gpio_pincfg_t pincfg = AP3_GPIO_DEFAULT_PINCFG;
304306 uint8_t funcsel = 0 ;
305307
308+ // Link in the buffers for the HAL
309+ _config.pui8RxBuffer = _rx_linbuff;
310+ _config.pui8TxBuffer = _tx_linbuff;
311+ _config.ui32RxBufferSize = sizeof (_rx_linbuff);
312+ _config.ui32TxBufferSize = sizeof (_tx_linbuff);
313+
306314 // Check for a valid instance
307315 // Check pins for compatibility with the selcted instance
308316
@@ -403,6 +411,9 @@ ap3_err_t Uart::_begin(void)
403411 am_hal_uart_interrupt_enable (_handle, (AM_HAL_UART_INT_RX | AM_HAL_UART_INT_TX));
404412 am_hal_interrupt_master_enable ();
405413
414+ // Service interrupts to determine idle state
415+ am_hal_uart_interrupt_service (_handle, 0 , (uint32_t *)&_tx_idle);
416+
406417 // Register the class into the local list
407418 ap3_uart_handles[_instance] = this ;
408419
@@ -517,13 +528,12 @@ ap3_err_t ap3_uart_pad_funcsel(uint8_t instance, ap3_uart_pad_type_e type, ap3_g
517528// *****************************************************************************
518529inline void Uart::uart_isr (void )
519530{
520-
521531 uint32_t ui32Status;
522532
523- // Read the masked interrupt status from the UART .
533+ // Service the FIFOs as necessary, and clear the interrupts .
524534 am_hal_uart_interrupt_status_get (_handle, &ui32Status, true );
525535 am_hal_uart_interrupt_clear (_handle, ui32Status);
526- am_hal_uart_interrupt_service (_handle, ui32Status, 0 );
536+ am_hal_uart_interrupt_service (_handle, ui32Status, ( uint32_t *)&_tx_idle );
527537
528538 if (ui32Status & AM_HAL_UART_INT_RX)
529539 {
@@ -538,40 +548,15 @@ inline void Uart::uart_isr(void)
538548 .ui32TimeoutMs = 0 ,
539549 .pui32BytesTransferred = &ui32BytesRead,
540550 };
541- am_hal_uart_transfer (_handle, &sRead );
542551
543- if (ui32BytesRead)
552+ do
544553 {
545- _rx_buffer.store_char (rx_c);
546- }
547- }
548-
549- if (ui32Status & AM_HAL_UART_INT_TX)
550- {
551- // If bytes are sitting in TX buffer, load them into UART buffer for transfer
552- if (_tx_buffer.available ())
553- {
554- uint32_t ui32BytesWritten = 0 ;
555-
556- uint32_t amtToSend = _tx_buffer.available ();
557- if (amtToSend > AM_HAL_UART_FIFO_MAX)
558- amtToSend = AM_HAL_UART_FIFO_MAX;
559-
560- // Transfer to local buffer
561- uint8_t tempTX[AM_HAL_UART_FIFO_MAX];
562- for (int x = 0 ; x < amtToSend; x++)
563- tempTX[x] = _tx_buffer.read_char ();
564-
565- const am_hal_uart_transfer_t sUartWrite =
566- {
567- .ui32Direction = AM_HAL_UART_WRITE,
568- .pui8Data = (uint8_t *)tempTX,
569- .ui32NumBytes = (uint32_t )amtToSend,
570- .ui32TimeoutMs = AM_HAL_UART_WAIT_FOREVER,
571- .pui32BytesTransferred = (uint32_t *)&ui32BytesWritten,
572- };
573- am_hal_uart_transfer (_handle, &sUartWrite );
574- }
554+ am_hal_uart_transfer (_handle, &sRead );
555+ if (ui32BytesRead)
556+ {
557+ _rx_buffer.store_char (rx_c);
558+ }
559+ } while (ui32BytesRead);
575560 }
576561}
577562
0 commit comments