X-Git-Url: https://git.karo-electronics.de/?p=oswald.git;a=blobdiff_plain;f=metawatch%2Fmw_bt.c;fp=metawatch%2Fmw_bt.c;h=ace18e9a5e0dff740734fe31248e1c68613f0cbb;hp=d5c7d26bbd29821fa7ebff3adc7b6b3de8077699;hb=81da03661f51061203889cb115142217230d6a76;hpb=f9c26e3f61a2d9bc1070cef0f6f08bd6f6240849 diff --git a/metawatch/mw_bt.c b/metawatch/mw_bt.c index d5c7d26..ace18e9 100644 --- a/metawatch/mw_bt.c +++ b/metawatch/mw_bt.c @@ -58,15 +58,17 @@ __interrupt void UCA1_ISR (void) if (UCA1STAT & UCRXERR) { debug_uart_tx("BT UART RXERR: "); if (UCA1STAT & UCOE) - debug_uart_tx("overrun\n"); + debug_uart_tx("overrun "); if (UCA1STAT & UCPE) - debug_uart_tx("parity err\n"); + debug_uart_tx("parity err "); if (UCA1STAT & UCFE) - debug_uart_tx("frm-err\n"); + debug_uart_tx("frm-err "); + debug_uart_tx("\n"); } bt_rx_buf[bt_rx_buf_wpos++] = UCA1RXBUF; bt_rx_buf_wpos %= BT_RX_MAX_SIZE; - LPM3_EXIT; + // LPM3_EXIT; + LPM3_EXIT_ISR(); _event_src |= BT_UART_RCV_EVENT; break; case 4: // TXIFG @@ -96,9 +98,10 @@ void mw_init_bt_uart(const bt_uart_baud_t baud) //UCA1CTL0 |= UCRXEIE; UCA1CTL1 &= ~UCSWRST; + /* clear interrup flags */ - UCA1IE = UCRXIE; UCA1IFG = 0; + UCA1IE = UCRXIE; } #if 0 // Does never finish, presumably trigger does not trigger, unknown :( @@ -121,17 +124,23 @@ void mw_bt_uart_tx(const void *buf, const unsigned int len) nop(); } #else -void mw_bt_uart_tx(const void *buf, const unsigned int len) +int mw_bt_uart_tx(const void *buf, const unsigned int len) { - unsigned int pos; + unsigned int pos, i; // char txstr[8]; pos = 0; // debug_uart_tx("BT tx: "); while (pos < len) { - // wait for CTS to go low - while ((BT_IO_PIN & BT_IO_CTS)) - nop(); + // watch for CTS to be low + i = 0; + while ((BT_IO_PIN & BT_IO_CTS) && (i < 1000)) { + __delay_cycles(16000); + i++; + if (i >= 1000) + return -1; + // nop(); + } // do not start a transfer if UART is busy, e.g. rx-ing while (UCA1STAT & UCBUSY) @@ -147,25 +156,31 @@ void mw_bt_uart_tx(const void *buf, const unsigned int len) } while (UCA1STAT & UCBUSY) nop(); + + return len; } #endif -static void load_cc256x_init_script(void) +static int load_cc256x_init_script(void) { uint32_t pos; unsigned char *tptr; + int tlen; pos = 0; while (pos < cc256x_init_script_size) { if (_event_src != 0) handle_event(); tptr = (unsigned char *)(cc256x_init_script + pos); - mw_bt_uart_tx(tptr, 4 + tptr[3]); - pos += 4 + tptr[3]; + tlen = mw_bt_uart_tx(tptr, 4 + tptr[3]); + if (tlen < 0) + return -1; + pos += tlen /*4 + tptr[3]*/; // each init script part is one HCI command so wait for reply if (_event_src != 0) handle_event(); } + return 0; } void mw_enable_bt(void) @@ -174,6 +189,7 @@ void mw_enable_bt(void) /* make sure it resets */ BT_SHUTDOWN(); + __delay_cycles(16000); /* enable 32kHz ACLK output to BT module */ P11DIR |= BIT0; @@ -182,11 +198,19 @@ void mw_enable_bt(void) // wait for clock to stabilize __delay_cycles(16000); + // disable the IRQ on CTS, later used to get a wakeup IRQ from eHCILL + // will be enabled when going to sleep + P1IE &= ~BT_IO_CTS; + P1IES &= ~BT_IO_CTS; + BT_IO_PDIR &= ~(BT_IO_CTS | BT_IO_PIN1 | BT_IO_PIN2 | BT_IO_CLKREQ); BT_IO_PDIR |= BT_IO_RTS; + BT_IO_POUT &= ~(BT_IO_CTS | BT_IO_PIN1 | BT_IO_PIN2 | BT_IO_CLKREQ); BT_IO_POUT &= ~BT_IO_RTS; // low == ready, high == !ready + BT_IO_REN |= BT_IO_CTS; // enable pull-down on CTS, POUT-CTS is 0 already + /* setup UART pins */ BT_UART_PSEL |= BT_UART_TX_PIN | BT_UART_RX_PIN; // P5OUT |= BT_UART_TX_PIN | BT_UART_RX_PIN; @@ -207,28 +231,45 @@ void mw_enable_bt(void) } if (i>=1000) { debug_uart_tx("Timeout waiting for CC256x to lower CTS\n"); + mw_bt_enabled = 0; } else { debug_uart_tx("CC256x CTS low - uploading init\n"); - for (i=0; i<100; i++) { - __delay_cycles(16000); // give it some more before anyone sends data + + // the init script consists of HCI cmds so HCI must be setup before + bt_hci_init(); + + // give it some more time before anyone sends data + for (i=0; i<10; i++) { + __delay_cycles(16000); + } + if (load_cc256x_init_script() < 0) { + debug_uart_tx("init upload failed!\n"); + return; } - load_cc256x_init_script(); + + __delay_cycles(32000); + debug_uart_tx("init uploaded\n"); - } - P1IE &= ~BT_IO_CTS; - P1IES &= ~BT_IO_CTS; + init_l2cap(); - bt_hci_init(); - init_l2cap(); + if (_event_src != 0) + handle_event(); - mw_bt_enabled = 1; + mw_bt_enabled = 1; + } } void mw_disable_bt(void) { mw_bt_enabled = 0; + // disable the IRQ on CTS + P1IE &= ~BT_IO_CTS; + P1IES &= ~BT_IO_CTS; + // BT_IO_REN &= ~BT_IO_CTS; // disable pull-down on CTS + P1IFG &= ~BT_IO_CTS; + /* disable UART RX interrupt */ UCA1IE &= ~UCRXIE;