Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

libbase: blocking UART write if IRQs are enabled

  • Loading branch information...
commit 755079d7fafabbc6be7cc189ab326d1c777cb29c 1 parent 73fce59
Sébastien Bourdeauducq authored February 07, 2012

Showing 1 changed file with 10 additions and 3 deletions. Show diff stats Hide diff stats

  1. 13  software/libbase/uart.c
13  software/libbase/uart.c
@@ -23,8 +23,6 @@
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;

0 notes on commit 755079d

Please sign in to comment.
Something went wrong with that request. Please try again.