X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=src%2Fdrivers%2Fao_btm.c;h=71599fbd6665b11d7e1ec184b2f2477622a68a32;hp=9ea638ba58089581ad0e85bce7456b16fc208926;hb=HEAD;hpb=0e7d1c89fea98eabca738f10cbfebec631be3bb7 diff --git a/src/drivers/ao_btm.c b/src/drivers/ao_btm.c index 9ea638ba..b82fb999 100644 --- a/src/drivers/ao_btm.c +++ b/src/drivers/ao_btm.c @@ -3,7 +3,8 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,19 +24,19 @@ #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_sleep() ao_sleep((void *) &ao_serial1_rx_fifo) +#define _ao_serial_btm_sleep_for(timeout) ao_sleep_for((void *) &ao_serial1_rx_fifo, timeout) #define ao_serial_btm_set_speed ao_serial1_set_speed #define ao_serial_btm_drain ao_serial1_drain #endif -int8_t ao_btm_stdio; -__xdata uint8_t ao_btm_connected; +uint8_t ao_btm_stdio; +uint8_t ao_btm_connected; #define BT_DEBUG 0 #if BT_DEBUG -__xdata char ao_btm_buffer[256]; -int ao_btm_ptr; +char ao_btm_buffer[256]; +uint16_t ao_btm_ptr; char ao_btm_dir; static void @@ -75,6 +76,7 @@ ao_btm_dump(void) { int i; char c; + uint16_t r; for (i = 0; i < ao_btm_ptr; i++) { c = ao_btm_buffer[i]; @@ -84,23 +86,66 @@ ao_btm_dump(void) putchar(ao_btm_buffer[i]); } putchar('\n'); + r = ao_cmd_decimal(); + if (ao_cmd_status == ao_cmd_success && r) + ao_btm_ptr = 0; + ao_cmd_status = ao_cmd_success; } static void ao_btm_speed(void) { - ao_cmd_decimal(); - if (ao_cmd_lex_u32 == 57600) + switch (ao_cmd_decimal()) { + case 57600: ao_serial_btm_set_speed(AO_SERIAL_SPEED_57600); - else if (ao_cmd_lex_u32 == 19200) + break; + case 19200: ao_serial_btm_set_speed(AO_SERIAL_SPEED_19200); - else + break; + default: ao_cmd_status = ao_cmd_syntax_error; + break; + } +} + +static uint8_t ao_btm_enable; + +static void +ao_btm_do_echo(void) +{ + int c; + while (ao_btm_enable) { + ao_arch_block_interrupts(); + while ((c = _ao_serial_btm_pollchar()) == AO_READ_AGAIN && ao_btm_enable) + _ao_serial_btm_sleep_for(0); + ao_arch_release_interrupts(); + if (c != AO_READ_AGAIN) { + putchar(c); + flush(); + } + } + ao_exit(); +} + +static struct ao_task ao_btm_echo_task; + +static void +ao_btm_send(void) +{ + int c; + ao_btm_enable = 1; + ao_add_task(&ao_btm_echo_task, ao_btm_do_echo, "btm-echo"); + while ((c = getchar()) != '~') { + ao_serial_btm_putchar(c); + } + ao_btm_enable = 0; + ao_wakeup((void *) &ao_serial_btm_rx_fifo); } -__code struct ao_cmds ao_btm_cmds[] = { +const struct ao_cmds ao_btm_cmds[] = { { ao_btm_dump, "d\0Dump btm buffer." }, { ao_btm_speed, "s <19200,57600>\0Set btm serial speed." }, + { ao_btm_send, "S\0BTM interactive mode. ~ to exit." }, { 0, NULL }, }; @@ -113,7 +158,7 @@ __code struct ao_cmds ao_btm_cmds[] = { #endif #define AO_BTM_MAX_REPLY 16 -__xdata char ao_btm_reply[AO_BTM_MAX_REPLY]; +char ao_btm_reply[AO_BTM_MAX_REPLY]; /* * Read one bluetooth character. @@ -127,9 +172,7 @@ ao_btm_getchar(void) ao_arch_block_interrupts(); while ((c = _ao_serial_btm_pollchar()) == AO_READ_AGAIN) { - ao_alarm(AO_MS_TO_TICKS(10)); - c = _ao_serial_btm_sleep(); - ao_clear_alarm(); + c = _ao_serial_btm_sleep_for(AO_MS_TO_TICKS(10)); if (c) { c = AO_READ_AGAIN; break; @@ -144,7 +187,7 @@ ao_btm_getchar(void) * it after a few characters. */ -uint8_t +static uint8_t ao_btm_get_line(void) { uint8_t ao_btm_reply_len = 0; @@ -154,7 +197,7 @@ ao_btm_get_line(void) 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; + ao_btm_reply[ao_btm_reply_len++] = (char) c; if (c == '\r' || c == '\n') break; } @@ -166,8 +209,8 @@ ao_btm_get_line(void) /* * Drain the serial port completely */ -void -ao_btm_drain() +static void +ao_btm_drain(void) { while (ao_btm_get_line()) ; @@ -176,7 +219,7 @@ ao_btm_drain() /* * Set the stdio echo for the bluetooth link */ -void +static void ao_btm_echo(uint8_t echo) { ao_stdios[ao_btm_stdio].echo = echo; @@ -187,7 +230,7 @@ ao_btm_echo(uint8_t echo) * can't keep up with 57600 baud */ -void +static void ao_btm_putchar(char c) { ao_btm_log_out_char(c); @@ -199,7 +242,7 @@ ao_btm_putchar(char c) * Wait for the bluetooth device to return * status from the previously executed command */ -uint8_t +static int ao_btm_wait_reply(void) { for (;;) { @@ -213,8 +256,8 @@ ao_btm_wait_reply(void) } } -void -ao_btm_string(__code char *cmd) +static void +ao_btm_string(const char *cmd) { char c; @@ -222,15 +265,24 @@ ao_btm_string(__code char *cmd) ao_btm_putchar(c); } -uint8_t -ao_btm_cmd(__code char *cmd) +static int +ao_btm_cmd(const char *cmd) { ao_btm_drain(); + +#ifdef AO_BTM_INT_PORT + /* Trust that AltosDroid will eventually disconnect and let us + * get things set up. The BTM module doesn't appear to listen + * for +++, so we have no way to force a disconnect. + */ + while (ao_btm_connected) + ao_sleep(&ao_btm_connected); +#endif ao_btm_string(cmd); return ao_btm_wait_reply(); } -uint8_t +static int ao_btm_set_name(void) { char sn[8]; @@ -242,14 +294,14 @@ ao_btm_set_name(void) *--s = '\r'; n = ao_serial_number; do { - *--s = '0' + n % 10; + *--s = (uint8_t) ('0' + n % 10); } while (n /= 10); while ((c = *s++)) ao_btm_putchar(c); return ao_btm_wait_reply(); } -uint8_t +static uint8_t ao_btm_try_speed(uint8_t speed) { ao_serial_btm_set_speed(speed); @@ -260,17 +312,61 @@ ao_btm_try_speed(uint8_t speed) return 0; } +#if BT_LINK_ON_P2 +#define BT_PICTL_ICON PICTL_P2ICON +#define BT_PIFG P2IFG +#define BT_PDIR P2DIR +#define BT_PINP P2INP +#define BT_IEN2_PIE IEN2_P2IE +#define BT_CC1111 1 +#endif +#if BT_LINK_ON_P1 +#define BT_PICTL_ICON PICTL_P1ICON +#define BT_PIFG P1IFG +#define BT_PDIR P1DIR +#define BT_PINP P1INP +#define BT_IEN2_PIE IEN2_P1IE +#define BT_CC1111 1 +#endif + +static void +ao_btm_check_link(void) +{ +#if BT_CC1111 + ao_arch_critical( + /* Check the pin and configure the interrupt detector to wait for the + * pin to flip the other way + */ + if (BT_LINK_PIN) { + ao_btm_connected = 0; + PICTL |= BT_PICTL_ICON; + } else { + ao_btm_connected = 1; + PICTL &= ~BT_PICTL_ICON; + } + ); +#else + ao_arch_block_interrupts(); + if (ao_gpio_get(AO_BTM_INT_PORT, AO_BTM_INT_PIN) == 0) { + ao_btm_connected = 1; + } else { + ao_btm_connected = 0; + } + ao_arch_release_interrupts(); +#endif +} + +struct ao_task ao_btm_task; + /* * A thread to initialize the bluetooth device and * hang around to blink the LED when connected */ -void +static void ao_btm(void) { -#ifdef AO_BTM_RESET_PORT - ao_gpio_set(AO_BTM_RESET_PORT, AO_BTM_RESET_PIN, AO_BTM_RESET, 0); - ao_delay(AO_MS_TO_TICKS(20)); - ao_gpio_set(AO_BTM_RESET_PORT, AO_BTM_RESET_PIN, AO_BTM_RESET, 1); +#ifdef AO_BTM_INT_PORT + ao_exti_enable(AO_BTM_INT_PORT, AO_BTM_INT_PIN); #endif /* @@ -303,11 +399,16 @@ ao_btm(void) /* Turn off status reporting */ ao_btm_cmd("ATQ1\r"); + ao_btm_drain(); + ao_btm_stdio = ao_add_stdio(_ao_serial_btm_pollchar, ao_serial_btm_putchar, NULL); ao_btm_echo(0); + /* Check current pin state */ + ao_btm_check_link(); + for (;;) { while (!ao_btm_connected) ao_sleep(&ao_btm_connected); @@ -318,43 +419,6 @@ ao_btm(void) } } -__xdata struct ao_task ao_btm_task; - -#if BT_LINK_ON_P2 -#define BT_PICTL_ICON PICTL_P2ICON -#define BT_PIFG P2IFG -#define BT_PDIR P2DIR -#define BT_PINP P2INP -#define BT_IEN2_PIE IEN2_P2IE -#define BT_CC1111 1 -#endif -#if BT_LINK_ON_P1 -#define BT_PICTL_ICON PICTL_P1ICON -#define BT_PIFG P1IFG -#define BT_PDIR P1DIR -#define BT_PINP P1INP -#define BT_IEN2_PIE IEN2_P1IE -#define BT_CC1111 1 -#endif - -void -ao_btm_check_link() -{ -#if BT_CC1111 - ao_arch_critical( - /* Check the pin and configure the interrupt detector to wait for the - * pin to flip the other way - */ - if (BT_LINK_PIN) { - ao_btm_connected = 0; - PICTL |= BT_PICTL_ICON; - } else { - ao_btm_connected = 1; - PICTL &= ~BT_PICTL_ICON; - } - ); -#endif -} #if BT_CC1111 void @@ -391,7 +455,7 @@ ao_btm_init (void) ao_serial_btm_set_speed(AO_SERIAL_SPEED_19200); #ifdef AO_BTM_RESET_PORT - ao_enable_output(AO_BTM_RESET_PORT,AO_BTM_RESET_PIN,AO_BTM_RESET,0); + ao_enable_output(AO_BTM_RESET_PORT,AO_BTM_RESET_PIN,0); #endif #ifdef AO_BTM_INT_PORT @@ -425,13 +489,6 @@ ao_btm_init (void) IEN2 |= BT_IEN2_PIE; #endif - /* Check current pin state */ - ao_btm_check_link(); - -#ifdef AO_BTM_INT_PORT - ao_exti_enable(AO_BTM_INT_PORT, AO_BTM_INT_PIN); -#endif - #if BT_LINK_ON_P2 /* Eable the pin interrupt */ PICTL |= PICTL_P2IEN;