libbase: blocking UART write if IRQs are enabled
This commit is contained in:
parent
73fce59631
commit
755079d7fa
|
@ -23,8 +23,6 @@
|
||||||
/*
|
/*
|
||||||
* Buffer sizes must be a power of 2 so that modulos can be computed
|
* Buffer sizes must be a power of 2 so that modulos can be computed
|
||||||
* with logical AND.
|
* with logical AND.
|
||||||
* RX functions are written in such a way that they do not require locking.
|
|
||||||
* TX functions already implement locking.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define UART_RINGBUFFER_SIZE_RX 128
|
#define UART_RINGBUFFER_SIZE_RX 128
|
||||||
|
@ -41,6 +39,7 @@ static char tx_buf[UART_RINGBUFFER_SIZE_TX];
|
||||||
static unsigned int tx_produce;
|
static unsigned int tx_produce;
|
||||||
static unsigned int tx_consume;
|
static unsigned int tx_consume;
|
||||||
static volatile int tx_cts;
|
static volatile int tx_cts;
|
||||||
|
static volatile int tx_level;
|
||||||
|
|
||||||
void uart_isr(void)
|
void uart_isr(void)
|
||||||
{
|
{
|
||||||
|
@ -54,9 +53,10 @@ void uart_isr(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(stat & UART_EV_TX) {
|
if(stat & UART_EV_TX) {
|
||||||
if(tx_produce != tx_consume) {
|
if(tx_level > 0) {
|
||||||
CSR_UART_RXTX = tx_buf[tx_consume];
|
CSR_UART_RXTX = tx_buf[tx_consume];
|
||||||
tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX;
|
tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX;
|
||||||
|
tx_level--;
|
||||||
} else
|
} else
|
||||||
tx_cts = 1;
|
tx_cts = 1;
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,10 @@ void uart_write(char c)
|
||||||
{
|
{
|
||||||
unsigned int oldmask;
|
unsigned int oldmask;
|
||||||
|
|
||||||
|
if(irq_getie()) {
|
||||||
|
while(tx_level == UART_RINGBUFFER_SIZE_TX);
|
||||||
|
}
|
||||||
|
|
||||||
oldmask = irq_getmask();
|
oldmask = irq_getmask();
|
||||||
irq_setmask(0);
|
irq_setmask(0);
|
||||||
|
|
||||||
|
@ -93,6 +97,7 @@ void uart_write(char c)
|
||||||
} else {
|
} else {
|
||||||
tx_buf[tx_produce] = c;
|
tx_buf[tx_produce] = c;
|
||||||
tx_produce = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX;
|
tx_produce = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX;
|
||||||
|
tx_level++;
|
||||||
}
|
}
|
||||||
irq_setmask(oldmask);
|
irq_setmask(oldmask);
|
||||||
}
|
}
|
||||||
|
@ -103,9 +108,11 @@ void uart_init(void)
|
||||||
|
|
||||||
rx_produce = 0;
|
rx_produce = 0;
|
||||||
rx_consume = 0;
|
rx_consume = 0;
|
||||||
|
|
||||||
tx_produce = 0;
|
tx_produce = 0;
|
||||||
tx_consume = 0;
|
tx_consume = 0;
|
||||||
tx_cts = 1;
|
tx_cts = 1;
|
||||||
|
tx_level = 0;
|
||||||
|
|
||||||
/* ack any events */
|
/* ack any events */
|
||||||
CSR_UART_EV_PENDING = CSR_UART_EV_PENDING;
|
CSR_UART_EV_PENDING = CSR_UART_EV_PENDING;
|
||||||
|
|
Loading…
Reference in New Issue