diff options
| author | Keith Packard <keithp@keithp.com> | 2013-03-24 15:00:20 -0700 |
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2013-03-31 12:24:24 -0700 |
| commit | 4f1f3e836393304434130d362771a39f6f8f859a (patch) | |
| tree | 5655f7ae7aa252a96aa585e3aee47b1b57a8fc9a /src/drivers/ao_btm.c | |
| parent | 7afcec1a1dce140dfa569469df4ef42ed407a742 (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/drivers/ao_btm.c')
| -rw-r--r-- | src/drivers/ao_btm.c | 52 |
1 files changed, 33 insertions, 19 deletions
diff --git a/src/drivers/ao_btm.c b/src/drivers/ao_btm.c index c862200a..de1f31a3 100644 --- a/src/drivers/ao_btm.c +++ b/src/drivers/ao_btm.c @@ -19,9 +19,10 @@ #ifndef ao_serial_btm_getchar #define ao_serial_btm_putchar ao_serial1_putchar -#define ao_serial_btm_pollchar ao_serial1_pollchar +#define _ao_serial_btm_pollchar _ao_serial1_pollchar #define ao_serial_btm_set_speed ao_serial1_set_speed #define ao_serial_btm_drain ao_serial1_drain +#define ao_serial_btm_rx_fifo ao_serial1_rx_fifo #endif int8_t ao_btm_stdio; @@ -112,6 +113,30 @@ __code struct ao_cmds ao_btm_cmds[] = { __xdata char ao_btm_reply[AO_BTM_MAX_REPLY]; /* + * Read one bluetooth character. + * Returns AO_READ_AGAIN if no character arrives within 10ms + */ + +static int +ao_btm_getchar(void) +{ + int c; + + ao_arch_block_interrupts(); + while ((c = _ao_serial_btm_pollchar()) == AO_READ_AGAIN) { + ao_alarm(AO_MS_TO_TICKS(10)); + c = ao_sleep(&ao_serial_btm_rx_fifo); + ao_clear_alarm(); + if (c) { + c = AO_READ_AGAIN; + break; + } + } + ao_arch_release_interrupts(); + return c; +} + +/* * Read a line of data from the serial port, truncating * it after a few characters. */ @@ -122,24 +147,13 @@ ao_btm_get_line(void) uint8_t ao_btm_reply_len = 0; int c; - for (;;) { - - while ((c = ao_serial_btm_pollchar()) != AO_READ_AGAIN) { - ao_btm_log_in_char(c); - if (ao_btm_reply_len < sizeof (ao_btm_reply)) - ao_btm_reply[ao_btm_reply_len++] = c; - if (c == '\r' || c == '\n') - goto done; - } - for (c = 0; c < 10; c++) { - ao_delay(AO_MS_TO_TICKS(10)); - if (!ao_fifo_empty(ao_serial1_rx_fifo)) - break; - } - if (c == 10) - goto done; + while ((c = ao_btm_getchar()) != AO_READ_AGAIN) { + ao_btm_log_in_char(c); + if (ao_btm_reply_len < sizeof (ao_btm_reply)) + ao_btm_reply[ao_btm_reply_len++] = c; + if (c == '\r' || c == '\n') + break; } -done: for (c = ao_btm_reply_len; c < sizeof (ao_btm_reply);) ao_btm_reply[c++] = '\0'; return ao_btm_reply_len; @@ -279,7 +293,7 @@ ao_btm(void) /* Turn off status reporting */ ao_btm_cmd("ATQ1\r"); - ao_btm_stdio = ao_add_stdio(ao_serial_btm_pollchar, + ao_btm_stdio = ao_add_stdio(_ao_serial_btm_pollchar, ao_serial_btm_putchar, NULL); ao_btm_echo(0); |
