2 #include <msp430xgeneric.h>
14 #include "bluetooth_init_cc256x.h"
17 static char bt_rx_buf[BT_RX_MAX_SIZE];
18 static unsigned char bt_rx_buf_wpos = 0;
19 static unsigned char bt_rx_buf_rpos = 0;
20 static uint8_t mw_bt_enabled = 0;
22 int mw_bt_get_rxbuf_len(void)
24 if (bt_rx_buf_rpos > bt_rx_buf_wpos)
25 return (BT_RX_MAX_SIZE - bt_rx_buf_rpos) + bt_rx_buf_wpos;
27 return bt_rx_buf_wpos - bt_rx_buf_rpos;
30 const unsigned char *mw_bt_get_rx_buf(unsigned char **rpos, unsigned char *len)
32 *rpos = &bt_rx_buf_rpos;
34 if (bt_rx_buf_rpos > bt_rx_buf_wpos)
35 *len = (BT_RX_MAX_SIZE - bt_rx_buf_rpos) + bt_rx_buf_wpos;
37 *len = bt_rx_buf_wpos - bt_rx_buf_rpos;
39 // if we reach high water mark raise RTS to stop more data
40 if (*len > (BT_RX_MAX_SIZE-(BT_RX_MAX_SIZE/10))) {
41 debug_uart_tx("BT UART RTS\n");
42 BT_IO_POUT |= BT_IO_RTS; // low == ready, high == !ready
44 BT_IO_POUT &= ~BT_IO_RTS; // low == ready, high == !ready
47 return (unsigned char *)bt_rx_buf;
50 #pragma vector=USCI_A1_VECTOR
51 __interrupt void UCA1_ISR (void)
56 //UCA1IFG &= ~UCRXIFG;
57 /* wake up to handle the received char */
58 if (UCA1STAT & UCRXERR) {
59 debug_uart_tx("BT UART RXERR: ");
61 debug_uart_tx("overrun\n");
63 debug_uart_tx("parity err\n");
65 debug_uart_tx("frm-err\n");
67 bt_rx_buf[bt_rx_buf_wpos++] = UCA1RXBUF;
68 bt_rx_buf_wpos %= BT_RX_MAX_SIZE;
70 _event_src |= BT_UART_RCV_EVENT;
73 debug_uart_tx("BT UART TX IRQ - huh?\n");
80 void mw_init_bt_uart(const bt_uart_baud_t baud)
84 UCA1CTL1 |= UCSSEL__SMCLK;
87 case BT_UART_BD115200:
90 UCA1MCTL = UCBRS_7 + UCBRF_0;
94 // UCA1CTL0 = UCMODE_0; // UART mode
95 // UCA1CTL0 &= ~UC7BIT; // 8bit char
96 //UCA1CTL0 |= UCRXEIE;
99 /* clear interrup flags */
104 #if 0 // Does never finish, presumably trigger does not trigger, unknown :(
105 void mw_bt_uart_tx(const void *buf, const unsigned int len)
109 DMACTL0 = DMA0TSEL_21;
111 DMA0DA = (unsigned int) &UCA1TXBUF;
112 DMA0SA = (uint32_t) buf;
116 DMA0CTL = DMADT_1 | DMASRCINCR_3 | DMASBDB | DMALEVEL | DMAIE;
120 while ((DMA0CTL & DMAIFG) == 0 && (DMA0CTL & DMAABORT) == 0)
124 void mw_bt_uart_tx(const void *buf, const unsigned int len)
130 // debug_uart_tx("BT tx: ");
132 // wait for CTS to go low
133 while ((BT_IO_PIN & BT_IO_CTS))
136 // do not start a transfer if UART is busy, e.g. rx-ing
137 while (UCA1STAT & UCBUSY)
140 UCA1TXBUF = *(unsigned char *) (buf+pos);
141 // debug_uart_tx_char(*(unsigned char *) (buf+pos));
142 // snprintf(txstr, 8, "0x%02x ", *(unsigned char *) (buf+pos));
143 // debug_uart_tx(txstr);
145 while ((UCA1IFG & UCTXIFG) == 0)
148 while (UCA1STAT & UCBUSY)
153 static void load_cc256x_init_script(void)
159 while (pos < cc256x_init_script_size) {
162 tptr = (unsigned char *)(cc256x_init_script + pos);
163 mw_bt_uart_tx(tptr, 4 + tptr[3]);
165 // each init script part is one HCI command so wait for reply
171 void mw_enable_bt(void)
175 /* make sure it resets */
178 /* enable 32kHz ACLK output to BT module */
182 // wait for clock to stabilize
183 __delay_cycles(16000);
185 BT_IO_PDIR &= ~(BT_IO_CTS | BT_IO_PIN1 | BT_IO_PIN2 | BT_IO_CLKREQ);
186 BT_IO_PDIR |= BT_IO_RTS;
187 BT_IO_POUT &= ~(BT_IO_CTS | BT_IO_PIN1 | BT_IO_PIN2 | BT_IO_CLKREQ);
188 BT_IO_POUT &= ~BT_IO_RTS; // low == ready, high == !ready
190 /* setup UART pins */
191 BT_UART_PSEL |= BT_UART_TX_PIN | BT_UART_RX_PIN;
192 // P5OUT |= BT_UART_TX_PIN | BT_UART_RX_PIN;
193 // P5REN |= BT_UART_TX_PIN | BT_UART_RX_PIN;
195 mw_init_bt_uart(BT_UART_BD115200);
200 /* release BT reset pin */
203 for (i=0; i<1000; i++) {
204 __delay_cycles(16000);
205 if ((BT_IO_PIN & BT_IO_CTS) == 0) // when CTS goes low module is ready
209 debug_uart_tx("Timeout waiting for CC256x to lower CTS\n");
211 debug_uart_tx("CC256x CTS low - uploading init\n");
212 for (i=0; i<100; i++) {
213 __delay_cycles(16000); // give it some more before anyone sends data
215 load_cc256x_init_script();
216 debug_uart_tx("init uploaded\n");
228 void mw_disable_bt(void)
232 /* disable UART RX interrupt */
235 /* disable UART pins */
236 BT_UART_PSEL &= ~(BT_UART_TX_PIN | BT_UART_RX_PIN);
238 /* set BT reset pin */
241 /* disable 32kHz ACLK output to BT module */
245 /* make all I/O Pins inputs so we do not drive against a "deaf" module */
246 BT_IO_PDIR &= ~(BT_IO_RTS | BT_IO_CTS | BT_IO_PIN1 | BT_IO_PIN2 | BT_IO_CLKREQ);
247 BT_IO_POUT &= ~(BT_IO_RTS | BT_IO_CTS | BT_IO_PIN1 | BT_IO_PIN2 | BT_IO_CLKREQ);
250 uint8_t mw_bt_is_enabled(void)
252 return mw_bt_enabled;