File tree 1 file changed +10
-3
lines changed
1 file changed +10
-3
lines changed Original file line number Diff line number Diff line change 23
23
/*
24
24
* Buffer sizes must be a power of 2 so that modulos can be computed
25
25
* with logical AND.
26
- * RX functions are written in such a way that they do not require locking.
27
- * TX functions already implement locking.
28
26
*/
29
27
30
28
#define UART_RINGBUFFER_SIZE_RX 128
@@ -41,6 +39,7 @@ static char tx_buf[UART_RINGBUFFER_SIZE_TX];
41
39
static unsigned int tx_produce ;
42
40
static unsigned int tx_consume ;
43
41
static volatile int tx_cts ;
42
+ static volatile int tx_level ;
44
43
45
44
void uart_isr (void )
46
45
{
@@ -54,9 +53,10 @@ void uart_isr(void)
54
53
}
55
54
56
55
if (stat & UART_EV_TX ) {
57
- if (tx_produce != tx_consume ) {
56
+ if (tx_level > 0 ) {
58
57
CSR_UART_RXTX = tx_buf [tx_consume ];
59
58
tx_consume = (tx_consume + 1 ) & UART_RINGBUFFER_MASK_TX ;
59
+ tx_level -- ;
60
60
} else
61
61
tx_cts = 1 ;
62
62
}
@@ -84,6 +84,10 @@ void uart_write(char c)
84
84
{
85
85
unsigned int oldmask ;
86
86
87
+ if (irq_getie ()) {
88
+ while (tx_level == UART_RINGBUFFER_SIZE_TX );
89
+ }
90
+
87
91
oldmask = irq_getmask ();
88
92
irq_setmask (0 );
89
93
@@ -93,6 +97,7 @@ void uart_write(char c)
93
97
} else {
94
98
tx_buf [tx_produce ] = c ;
95
99
tx_produce = (tx_produce + 1 ) & UART_RINGBUFFER_MASK_TX ;
100
+ tx_level ++ ;
96
101
}
97
102
irq_setmask (oldmask );
98
103
}
@@ -103,9 +108,11 @@ void uart_init(void)
103
108
104
109
rx_produce = 0 ;
105
110
rx_consume = 0 ;
111
+
106
112
tx_produce = 0 ;
107
113
tx_consume = 0 ;
108
114
tx_cts = 1 ;
115
+ tx_level = 0 ;
109
116
110
117
/* ack any events */
111
118
CSR_UART_EV_PENDING = CSR_UART_EV_PENDING ;
You can’t perform that action at this time.
0 commit comments