@@ -52,6 +52,7 @@ struct {
52
52
volatile uint32_t tx_size ;
53
53
54
54
uint8_t rx ;
55
+ uint8_t tx ;
55
56
} cb_buf ;
56
57
57
58
void uart_handler (uint32_t event );
@@ -207,41 +208,23 @@ int32_t uart_write_free(void)
207
208
return circ_buf_count_free (& write_buffer );
208
209
}
209
210
210
- // Start a new TX transfer if there are bytes pending to be transferred on the
211
- // write_buffer buffer. The transferred bytes are not removed from the circular
212
- // by this function, only the event handler will remove them once the transfer
213
- // is done.
214
- static void uart_start_tx_transfer () {
215
- uint32_t tx_size = 0 ;
216
- const uint8_t * buf = circ_buf_peek (& write_buffer , & tx_size );
217
- if (tx_size > BUFFER_SIZE / 4 ) {
218
- // The bytes being transferred remain on the circular buffer memory
219
- // until the transfer is done. Limiting the UART transfer size
220
- // allows the uart_handler to clear those bytes earlier.
221
- tx_size = BUFFER_SIZE / 4 ;
222
- }
223
- cb_buf .tx_size = tx_size ;
224
- if (tx_size ) {
225
- USART_INSTANCE .Send (buf , tx_size );
226
- }
227
- }
228
-
229
211
int32_t uart_write_data (uint8_t * data , uint16_t size )
230
212
{
231
213
if (size == 0 ) {
232
214
return 0 ;
233
215
}
234
216
217
+ // Disable interrupts to prevent the uart_handler from modifying the
218
+ // circular buffer at the same time.
219
+ NVIC_DisableIRQ (USART_IRQ );
235
220
uint32_t cnt = circ_buf_write (& write_buffer , data , size );
236
- if (cb_buf .tx_size == 0 ) {
237
- // There's no pending transfer and the value of cb_buf.tx_size will not
238
- // change to non-zero by the event handler once it is zero. Note that it
239
- // is entirely possible that we transferred all the bytes we added to
240
- // the circular buffer in this function by the time we are in this
241
- // branch, in that case uart_start_tx_transfer() would not schedule any
242
- // transfer.
243
- uart_start_tx_transfer ();
221
+ if (cb_buf .tx_size == 0 && circ_buf_count_used (& write_buffer ) > 0 ) {
222
+ // There's no pending transfer, so we need to start the process.
223
+ cb_buf .tx = circ_buf_pop (& write_buffer );
224
+ USART_INSTANCE .Send (& (cb_buf .tx ), 1 );
225
+ cb_buf .tx_size = 1 ;
244
226
}
227
+ NVIC_EnableIRQ (USART_IRQ );
245
228
246
229
return cnt ;
247
230
}
@@ -265,7 +248,13 @@ void uart_handler(uint32_t event) {
265
248
}
266
249
267
250
if (event & ARM_USART_EVENT_SEND_COMPLETE ) {
268
- circ_buf_pop_n (& write_buffer , cb_buf .tx_size );
269
- uart_start_tx_transfer ();
251
+ if (circ_buf_count_used (& write_buffer ) > 0 ) {
252
+ cb_buf .tx = circ_buf_pop (& write_buffer );
253
+ USART_INSTANCE .Send (& (cb_buf .tx ), 1 );
254
+ } else {
255
+ // Signals that next call to uart_write_data() should start a
256
+ // transfer.
257
+ cb_buf .tx_size = 0 ;
258
+ }
270
259
}
271
260
}
0 commit comments