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
//UCA1CTL0 |= UCRXEIE;
UCA1CTL1 &= ~UCSWRST;
+
/* clear interrup flags */
- UCA1IE = UCRXIE;
UCA1IFG = 0;
+ UCA1IE = UCRXIE;
}
#if 0 // Does never finish, presumably trigger does not trigger, unknown :(
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)
}
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)
/* make sure it resets */
BT_SHUTDOWN();
+ __delay_cycles(16000);
/* enable 32kHz ACLK output to BT module */
P11DIR |= BIT0;
// 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;
}
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;