Skip to content

Commit da9b932

Browse files
committed
Fix the UART change makes BLE library failed
1. The uart_fifo_fill doesn't check the FIFO's length and failed to send out all data 2. Check the FIFO status register before write data in FIFO
1 parent 01a9ae4 commit da9b932

File tree

3 files changed

+41
-19
lines changed

3 files changed

+41
-19
lines changed

cores/arduino/UARTClass.cpp

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ int UARTClass::read( void )
168168

169169
void UARTClass::flush( void )
170170
{
171-
while (_tx_buffer->_iHead != _tx_buffer->_iTail); //wait for transmit data to be sent
171+
while (_tx_buffer->_iHead != *(volatile int*)&(_tx_buffer->_iTail)); //wait for transmit data to be sent
172172
// Wait for transmission to complete
173173
while(!uart_tx_complete(CONFIG_UART_CONSOLE_INDEX));
174174
}
@@ -179,12 +179,11 @@ size_t UARTClass::write( const uint8_t uc_data )
179179
return(0);
180180

181181
// Is the hardware currently busy?
182-
if (_tx_buffer->_iTail != _tx_buffer->_iHead)
182+
if (_tx_buffer->_iTail != _tx_buffer->_iHead || !uart_tx_ready(CONFIG_UART_CONSOLE_INDEX))
183183
{
184184
// If busy we buffer
185185
int l = (_tx_buffer->_iHead + 1) % UART_BUFFER_SIZE;
186-
while (_tx_buffer->_iTail == l)
187-
; // Spin locks if we're about to overwrite the buffer. This continues once the data is sent
186+
while (*(volatile int*)&(_tx_buffer->_iTail) == l); // Spin locks if we're about to overwrite the buffer. This continues once the data is sent
188187

189188
_tx_buffer->_aucBuffer[_tx_buffer->_iHead] = uc_data;
190189
_tx_buffer->_iHead = l;
@@ -201,21 +200,29 @@ size_t UARTClass::write( const uint8_t uc_data )
201200

202201
void UARTClass::IrqHandler( void )
203202
{
204-
uint8_t uc_data;
205-
int ret;
206-
ret = uart_poll_in(CONFIG_UART_CONSOLE_INDEX, &uc_data);
207-
208-
while ( ret != -1 ) {
209-
_rx_buffer->store_char(uc_data);
203+
uart_irq_update(CONFIG_UART_CONSOLE_INDEX);
204+
// if irq is Receiver Data Available
205+
if(uart_irq_rx_ready(CONFIG_UART_CONSOLE_INDEX))
206+
{
207+
uint8_t uc_data;
208+
int ret;
210209
ret = uart_poll_in(CONFIG_UART_CONSOLE_INDEX, &uc_data);
210+
211+
while ( ret != -1 ) {
212+
_rx_buffer->store_char(uc_data);
213+
ret = uart_poll_in(CONFIG_UART_CONSOLE_INDEX, &uc_data);
214+
}
211215
}
212216

213-
// Do we need to keep sending data?
214-
if (!uart_irq_tx_ready(CONFIG_UART_CONSOLE_INDEX))
217+
// if irq is Transmitter Holding Register
218+
else if(uart_irq_tx_ready(CONFIG_UART_CONSOLE_INDEX))
215219
{
216-
if (_tx_buffer->_iTail != _tx_buffer->_iHead) {
217-
uart_poll_out(CONFIG_UART_CONSOLE_INDEX, _tx_buffer->_aucBuffer[_tx_buffer->_iTail]);
218-
_tx_buffer->_iTail = (unsigned int)(_tx_buffer->_iTail + 1) % UART_BUFFER_SIZE;
220+
if(_tx_buffer->_iTail != _tx_buffer->_iHead)
221+
{
222+
int end = (_tx_buffer->_iTail < _tx_buffer->_iHead) ? _tx_buffer->_iHead:UART_BUFFER_SIZE;
223+
int l = min(end - _tx_buffer->_iTail, UART_FIFO_SIZE);
224+
uart_fifo_fill(CONFIG_UART_CONSOLE_INDEX, _tx_buffer->_aucBuffer+_tx_buffer->_iTail, l);
225+
_tx_buffer->_iTail = (_tx_buffer->_iTail+l)%UART_BUFFER_SIZE;
219226
}
220227
else
221228
{

system/libarc32_arduino101/drivers/ns16550.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ unsigned char uart_poll_out(
340340
)
341341
{
342342
/* wait for transmitter to ready to accept a character */
343-
while ((INBYTE(LSR(which)) & LSR_TEMT) == 0)
343+
while ((INBYTE(LSR(which)) & LSR_THRE) == 0)
344344
;
345345

346346
OUTBYTE(THR(which), outChar);
@@ -352,6 +352,8 @@ unsigned char uart_poll_out(
352352
*
353353
* uart_fifo_fill - fill FIFO with data
354354
*
355+
* It is up to the caller to make sure that FIFO capcity is not exceeded
356+
*
355357
* RETURNS: number of bytes sent
356358
*/
357359

@@ -362,8 +364,9 @@ int uart_fifo_fill(int which, /* UART on which to send */
362364
{
363365
int i;
364366

365-
for (i = 0; i < size && (INBYTE(LSR(which)) &
366-
LSR_BOTH_EMPTY) != 0; i++) {
367+
for (i = 0; i < size && (INBYTE(LSR(which)) &
368+
LSR_BOTH_EMPTY) != 0; i++)
369+
{
367370
OUTBYTE(THR(which), txData[i]);
368371
}
369372
return i;
@@ -622,7 +625,6 @@ void uart_int_connect(int which, /* UART to which to connect */
622625
)
623626
{
624627
interrupt_connect((unsigned int)uart[which].irq, isr);
625-
interrupt_priority_set ((int)uart[which].irq, uart[which].intPri);
626628
interrupt_enable((unsigned int)uart[which].irq);
627629
/* set the Host Processor Interrupt Routing Mask */
628630
SOC_UNMASK_INTERRUPTS(INT_UART_0_MASK + (which * UART_REG_ADDR_INTERVAL));
@@ -641,6 +643,19 @@ uint8_t uart_tx_complete(int which)
641643
return INBYTE(LSR(which)) & LSR_TEMT;
642644
}
643645

646+
/*******************************************************************************
647+
*
648+
* uart_tx_complete - check if tx holding register is empty
649+
*
650+
* RETURNS: zero if register is non-empty,
651+
* non-zero if register is empty (ready to receive new data)
652+
*/
653+
654+
uint8_t uart_tx_ready(int which)
655+
{
656+
return INBYTE(LSR(which)) & LSR_THRE;
657+
}
658+
644659
/*******************************************************************************
645660
*
646661
* uart_loop_enable - enable loopback
534 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)