X-Git-Url: https://git.karo-electronics.de/?p=oswald.git;a=blobdiff_plain;f=metawatch%2Fmw_bt.c;h=d5c7d26bbd29821fa7ebff3adc7b6b3de8077699;hp=8138b1ef4414e7d77d13707a22b751c0e7098259;hb=1b5790095c23913d02531727e47b79af3568e0b1;hpb=3e320aaa4175a0ed469581f1dea2eac35b390878 diff --git a/metawatch/mw_bt.c b/metawatch/mw_bt.c index 8138b1e..d5c7d26 100644 --- a/metawatch/mw_bt.c +++ b/metawatch/mw_bt.c @@ -19,16 +19,30 @@ static unsigned char bt_rx_buf_wpos = 0; static unsigned char bt_rx_buf_rpos = 0; static uint8_t mw_bt_enabled = 0; +int mw_bt_get_rxbuf_len(void) +{ + if (bt_rx_buf_rpos > bt_rx_buf_wpos) + return (BT_RX_MAX_SIZE - bt_rx_buf_rpos) + bt_rx_buf_wpos; + else + return bt_rx_buf_wpos - bt_rx_buf_rpos; +} + const unsigned char *mw_bt_get_rx_buf(unsigned char **rpos, unsigned char *len) { *rpos = &bt_rx_buf_rpos; + if (bt_rx_buf_rpos > bt_rx_buf_wpos) *len = (BT_RX_MAX_SIZE - bt_rx_buf_rpos) + bt_rx_buf_wpos; else *len = bt_rx_buf_wpos - bt_rx_buf_rpos; - if (*len > (BT_RX_MAX_SIZE-(BT_RX_MAX_SIZE/10))) + // if we reach high water mark raise RTS to stop more data + if (*len > (BT_RX_MAX_SIZE-(BT_RX_MAX_SIZE/10))) { + debug_uart_tx("BT UART RTS\n"); BT_IO_POUT |= BT_IO_RTS; // low == ready, high == !ready + } else { + BT_IO_POUT &= ~BT_IO_RTS; // low == ready, high == !ready + } return (unsigned char *)bt_rx_buf; } @@ -38,15 +52,25 @@ __interrupt void UCA1_ISR (void) { switch (UCA1IV) { case 2: // RXIFG + /* clear IRQ flag */ + //UCA1IFG &= ~UCRXIFG; /* wake up to handle the received char */ - LPM3_EXIT; + if (UCA1STAT & UCRXERR) { + debug_uart_tx("BT UART RXERR: "); + if (UCA1STAT & UCOE) + debug_uart_tx("overrun\n"); + if (UCA1STAT & UCPE) + debug_uart_tx("parity err\n"); + if (UCA1STAT & UCFE) + debug_uart_tx("frm-err\n"); + } bt_rx_buf[bt_rx_buf_wpos++] = UCA1RXBUF; - /* clear IRQ flag */ - UCA1IFG &= ~UCRXIFG; bt_rx_buf_wpos %= BT_RX_MAX_SIZE; + LPM3_EXIT; _event_src |= BT_UART_RCV_EVENT; break; case 4: // TXIFG + debug_uart_tx("BT UART TX IRQ - huh?\n"); break; default: break; @@ -56,7 +80,9 @@ __interrupt void UCA1_ISR (void) void mw_init_bt_uart(const bt_uart_baud_t baud) { UCA1CTL1 = UCSWRST; + UCA1CTL1 |= UCSSEL__SMCLK; + switch (baud) { case BT_UART_BD115200: default: @@ -65,13 +91,14 @@ void mw_init_bt_uart(const bt_uart_baud_t baud) break; }; UCA1STAT = 0; - UCA1CTL0 = UCMODE_0; // UART mode - UCA1CTL0 &= ~UC7BIT; // 8bit char + // UCA1CTL0 = UCMODE_0; // UART mode + // UCA1CTL0 &= ~UC7BIT; // 8bit char + //UCA1CTL0 |= UCRXEIE; UCA1CTL1 &= ~UCSWRST; /* clear interrup flags */ - UCA1IFG = 0; UCA1IE = UCRXIE; + UCA1IFG = 0; } #if 0 // Does never finish, presumably trigger does not trigger, unknown :( @@ -102,7 +129,12 @@ void mw_bt_uart_tx(const void *buf, const unsigned int len) pos = 0; // debug_uart_tx("BT tx: "); while (pos < len) { - while ((BT_IO_PIN & BT_IO_CTS)) // wait for CTS to go low + // wait for CTS to go low + while ((BT_IO_PIN & BT_IO_CTS)) + nop(); + + // do not start a transfer if UART is busy, e.g. rx-ing + while (UCA1STAT & UCBUSY) nop(); UCA1TXBUF = *(unsigned char *) (buf+pos); @@ -115,7 +147,6 @@ void mw_bt_uart_tx(const void *buf, const unsigned int len) } while (UCA1STAT & UCBUSY) nop(); - // debug_uart_tx("\n"); } #endif @@ -163,6 +194,9 @@ void mw_enable_bt(void) mw_init_bt_uart(BT_UART_BD115200); + bt_rx_buf_wpos = 0; + bt_rx_buf_rpos = 0; + /* release BT reset pin */ BT_ENABLE(); @@ -181,10 +215,13 @@ void mw_enable_bt(void) load_cc256x_init_script(); debug_uart_tx("init uploaded\n"); } + P1IE &= ~BT_IO_CTS; P1IES &= ~BT_IO_CTS; + bt_hci_init(); init_l2cap(); + mw_bt_enabled = 1; }