summaryrefslogtreecommitdiff
path: root/src/stm
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2013-03-24 15:00:20 -0700
committerKeith Packard <keithp@keithp.com>2013-03-24 15:00:20 -0700
commitf3dc025a764ca6a2c44fb514ccaf22e6210f769d (patch)
tree05c0be2a58f2bfc84d2916d90baaea0f1609d890 /src/stm
parent0365df9ed5a638bfdefb29eec830e51301c13936 (diff)
altos: Do not release interrupts from any pollchar function
getchar relies on interrupts being blocked across the pollchar calls and into the sleep call or it may go to sleep with data pending. This prefixes all pollchar functions with _ to indicate that they are to be called with interrupts blocked and eliminates all interrupt manipulation calls from within the pollchar functions. Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/stm')
-rw-r--r--src/stm/ao_serial_stm.c45
-rw-r--r--src/stm/ao_usb_stm.c23
2 files changed, 30 insertions, 38 deletions
diff --git a/src/stm/ao_serial_stm.c b/src/stm/ao_serial_stm.c
index ce33f97e..2133c584 100644
--- a/src/stm/ao_serial_stm.c
+++ b/src/stm/ao_serial_stm.c
@@ -59,24 +59,11 @@ ao_usart_isr(struct ao_stm_usart *usart, int stdin)
}
}
-char
-ao_usart_getchar(struct ao_stm_usart *usart)
-{
- char c;
- ao_arch_block_interrupts();
- while (ao_fifo_empty(usart->rx_fifo))
- ao_sleep(&usart->rx_fifo);
- ao_fifo_remove(usart->rx_fifo, c);
- ao_arch_release_interrupts();
- return c;
-}
-
int
-ao_usart_pollchar(struct ao_stm_usart *usart)
+_ao_usart_pollchar(struct ao_stm_usart *usart)
{
int c;
- ao_arch_block_interrupts();
if (ao_fifo_empty(usart->rx_fifo))
c = AO_READ_AGAIN;
else {
@@ -84,10 +71,20 @@ ao_usart_pollchar(struct ao_stm_usart *usart)
ao_fifo_remove(usart->rx_fifo,u);
c = u;
}
- ao_arch_release_interrupts();
return c;
}
+char
+ao_usart_getchar(struct ao_stm_usart *usart)
+{
+ int c;
+ ao_arch_block_interrupts();
+ while ((c = _ao_usart_pollchar(usart)) == AO_READ_AGAIN)
+ ao_sleep(&usart->rx_fifo);
+ ao_arch_release_interrupts();
+ return (char) c;
+}
+
void
ao_usart_putchar(struct ao_stm_usart *usart, char c)
{
@@ -201,9 +198,9 @@ ao_serial1_putchar(char c)
}
int
-ao_serial1_pollchar(void)
+_ao_serial1_pollchar(void)
{
- return ao_usart_pollchar(&ao_stm_usart1);
+ return _ao_usart_pollchar(&ao_stm_usart1);
}
void
@@ -232,9 +229,9 @@ ao_serial2_putchar(char c)
}
int
-ao_serial2_pollchar(void)
+_ao_serial2_pollchar(void)
{
- return ao_usart_pollchar(&ao_stm_usart2);
+ return _ao_usart_pollchar(&ao_stm_usart2);
}
void
@@ -263,9 +260,9 @@ ao_serial3_putchar(char c)
}
int
-ao_serial3_pollchar(void)
+_ao_serial3_pollchar(void)
{
- return ao_usart_pollchar(&ao_stm_usart3);
+ return _ao_usart_pollchar(&ao_stm_usart3);
}
void
@@ -309,7 +306,7 @@ ao_serial_init(void)
stm_nvic_set_enable(STM_ISR_USART1_POS);
stm_nvic_set_priority(STM_ISR_USART1_POS, 4);
#if USE_SERIAL_1_STDIN
- ao_add_stdio(ao_serial1_pollchar,
+ ao_add_stdio(_ao_serial1_pollchar,
ao_serial1_putchar,
NULL);
#endif
@@ -346,7 +343,7 @@ ao_serial_init(void)
stm_nvic_set_enable(STM_ISR_USART2_POS);
stm_nvic_set_priority(STM_ISR_USART2_POS, 4);
#if USE_SERIAL_2_STDIN
- ao_add_stdio(ao_serial2_pollchar,
+ ao_add_stdio(_ao_serial2_pollchar,
ao_serial2_putchar,
NULL);
#endif
@@ -390,7 +387,7 @@ ao_serial_init(void)
stm_nvic_set_enable(STM_ISR_USART3_POS);
stm_nvic_set_priority(STM_ISR_USART3_POS, 4);
#if USE_SERIAL_3_STDIN
- ao_add_stdio(ao_serial3_pollchar,
+ ao_add_stdio(_ao_serial3_pollchar,
ao_serial3_putchar,
NULL);
#endif
diff --git a/src/stm/ao_usb_stm.c b/src/stm/ao_usb_stm.c
index 9379e5cd..dfa58c42 100644
--- a/src/stm/ao_usb_stm.c
+++ b/src/stm/ao_usb_stm.c
@@ -229,10 +229,9 @@ ao_usb_set_stat_tx(int ep, uint32_t stat_tx)
}
static void
-ao_usb_set_stat_rx(int ep, uint32_t stat_rx) {
+_ao_usb_set_stat_rx(int ep, uint32_t stat_rx) {
uint32_t epr_write, epr_old;
- ao_arch_block_interrupts();
epr_write = epr_old = stm_usb.epr[ep];
epr_write &= STM_USB_EPR_PRESERVE_MASK;
epr_write |= STM_USB_EPR_INVARIANT;
@@ -240,6 +239,12 @@ ao_usb_set_stat_rx(int ep, uint32_t stat_rx) {
STM_USB_EPR_STAT_RX_MASK << STM_USB_EPR_STAT_RX,
stat_rx << STM_USB_EPR_STAT_RX);
stm_usb.epr[ep] = epr_write;
+}
+
+static void
+ao_usb_set_stat_rx(int ep, uint32_t stat_rx) {
+ ao_arch_block_interrupts();
+ _ao_usb_set_stat_rx(ep, stat_rx);
ao_arch_release_interrupts();
}
@@ -870,10 +875,10 @@ _ao_usb_out_recv(void)
ao_usb_rx_pos = 0;
/* ACK the packet */
- ao_usb_set_stat_rx(AO_USB_OUT_EPR, STM_USB_EPR_STAT_RX_VALID);
+ _ao_usb_set_stat_rx(AO_USB_OUT_EPR, STM_USB_EPR_STAT_RX_VALID);
}
-static int
+int
_ao_usb_pollchar(void)
{
uint8_t c;
@@ -896,16 +901,6 @@ _ao_usb_pollchar(void)
return c;
}
-int
-ao_usb_pollchar(void)
-{
- int c;
- ao_arch_block_interrupts();
- c = _ao_usb_pollchar();
- ao_arch_release_interrupts();
- return c;
-}
-
char
ao_usb_getchar(void)
{