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