Skip to content

Commit 755079d

Browse files
author
Sebastien Bourdeauducq
committedFeb 7, 2012
libbase: blocking UART write if IRQs are enabled
1 parent 73fce59 commit 755079d

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed
 

‎software/libbase/uart.c

+10-3
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
/*
2424
* Buffer sizes must be a power of 2 so that modulos can be computed
2525
* with logical AND.
26-
* RX functions are written in such a way that they do not require locking.
27-
* TX functions already implement locking.
2826
*/
2927

3028
#define UART_RINGBUFFER_SIZE_RX 128
@@ -41,6 +39,7 @@ static char tx_buf[UART_RINGBUFFER_SIZE_TX];
4139
static unsigned int tx_produce;
4240
static unsigned int tx_consume;
4341
static volatile int tx_cts;
42+
static volatile int tx_level;
4443

4544
void uart_isr(void)
4645
{
@@ -54,9 +53,10 @@ void uart_isr(void)
5453
}
5554

5655
if(stat & UART_EV_TX) {
57-
if(tx_produce != tx_consume) {
56+
if(tx_level > 0) {
5857
CSR_UART_RXTX = tx_buf[tx_consume];
5958
tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX;
59+
tx_level--;
6060
} else
6161
tx_cts = 1;
6262
}
@@ -84,6 +84,10 @@ void uart_write(char c)
8484
{
8585
unsigned int oldmask;
8686

87+
if(irq_getie()) {
88+
while(tx_level == UART_RINGBUFFER_SIZE_TX);
89+
}
90+
8791
oldmask = irq_getmask();
8892
irq_setmask(0);
8993

@@ -93,6 +97,7 @@ void uart_write(char c)
9397
} else {
9498
tx_buf[tx_produce] = c;
9599
tx_produce = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX;
100+
tx_level++;
96101
}
97102
irq_setmask(oldmask);
98103
}
@@ -103,9 +108,11 @@ void uart_init(void)
103108

104109
rx_produce = 0;
105110
rx_consume = 0;
111+
106112
tx_produce = 0;
107113
tx_consume = 0;
108114
tx_cts = 1;
115+
tx_level = 0;
109116

110117
/* ack any events */
111118
CSR_UART_EV_PENDING = CSR_UART_EV_PENDING;

0 commit comments

Comments
 (0)
Please sign in to comment.