@@ -117,48 +117,50 @@ size_t Uart::write(const uint8_t data)
117
117
118
118
size_t Uart::write (const uint8_t *buffer, size_t size)
119
119
{
120
- uint32_t ui32BytesWritten = 0 ;
121
- uint32_t remaining = size ;
120
+ uint32_t ui32TransferBytesWritten = 0 ;
121
+ uint32_t ui32TotalBytesWritten = 0 ;
122
122
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
129
136
{
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
133
140
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 );
135
144
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;
140
146
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);
151
148
152
- // Transfer any remaining bytes into ring buffer
153
- for (int x = size - remaining; x < size; x++)
149
+ if (ui32TotalBytesWritten != size)
154
150
{
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
+ }
159
161
}
160
162
161
- return ui32BytesWritten ; // Return number of bytes pushed to UART hardware
163
+ return ui32TotalBytesWritten ; // Return number of bytes pushed to UART hardware
162
164
}
163
165
164
166
// Stop Bits
@@ -303,6 +305,12 @@ ap3_err_t Uart::_begin(void)
303
305
am_hal_gpio_pincfg_t pincfg = AP3_GPIO_DEFAULT_PINCFG;
304
306
uint8_t funcsel = 0 ;
305
307
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
+
306
314
// Check for a valid instance
307
315
// Check pins for compatibility with the selcted instance
308
316
@@ -403,6 +411,9 @@ ap3_err_t Uart::_begin(void)
403
411
am_hal_uart_interrupt_enable (_handle, (AM_HAL_UART_INT_RX | AM_HAL_UART_INT_TX));
404
412
am_hal_interrupt_master_enable ();
405
413
414
+ // Service interrupts to determine idle state
415
+ am_hal_uart_interrupt_service (_handle, 0 , (uint32_t *)&_tx_idle);
416
+
406
417
// Register the class into the local list
407
418
ap3_uart_handles[_instance] = this ;
408
419
@@ -517,13 +528,12 @@ ap3_err_t ap3_uart_pad_funcsel(uint8_t instance, ap3_uart_pad_type_e type, ap3_g
517
528
// *****************************************************************************
518
529
inline void Uart::uart_isr (void )
519
530
{
520
-
521
531
uint32_t ui32Status;
522
532
523
- // Read the masked interrupt status from the UART .
533
+ // Service the FIFOs as necessary, and clear the interrupts .
524
534
am_hal_uart_interrupt_status_get (_handle, &ui32Status, true );
525
535
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 );
527
537
528
538
if (ui32Status & AM_HAL_UART_INT_RX)
529
539
{
@@ -538,40 +548,15 @@ inline void Uart::uart_isr(void)
538
548
.ui32TimeoutMs = 0 ,
539
549
.pui32BytesTransferred = &ui32BytesRead,
540
550
};
541
- am_hal_uart_transfer (_handle, &sRead );
542
551
543
- if (ui32BytesRead)
552
+ do
544
553
{
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);
575
560
}
576
561
}
577
562
0 commit comments