... | ... |
@@ -4,6 +4,7 @@ |
4 | 4 |
#include <stdio.h> |
5 | 5 |
#include <string.h> |
6 | 6 |
|
7 |
+#include "strutils.h" |
|
7 | 8 |
#include "mw_main.h" |
8 | 9 |
|
9 | 10 |
#include "mw_uart.h" |
... | ... |
@@ -148,8 +149,10 @@ int mw_bt_uart_tx(const void *buf, const unsigned int len) |
148 | 149 |
|
149 | 150 |
UCA1TXBUF = *(unsigned char *) (buf+pos); |
150 | 151 |
// debug_uart_tx_char(*(unsigned char *) (buf+pos)); |
151 |
- // snprintf(txstr, 8, "0x%02x ", *(unsigned char *) (buf+pos)); |
|
152 |
+ // debug_uart_tx("0x"); |
|
153 |
+ // hexnum2str(*(unsigned char *) (buf+pos),txstr,2); |
|
152 | 154 |
// debug_uart_tx(txstr); |
155 |
+ // debug_uart_tx(" "); |
|
153 | 156 |
pos++; |
154 | 157 |
while ((UCA1IFG & UCTXIFG) == 0) |
155 | 158 |
nop(); |
... | ... |
@@ -58,15 +58,17 @@ __interrupt void UCA1_ISR (void) |
58 | 58 |
if (UCA1STAT & UCRXERR) { |
59 | 59 |
debug_uart_tx("BT UART RXERR: "); |
60 | 60 |
if (UCA1STAT & UCOE) |
61 |
- debug_uart_tx("overrun\n"); |
|
61 |
+ debug_uart_tx("overrun "); |
|
62 | 62 |
if (UCA1STAT & UCPE) |
63 |
- debug_uart_tx("parity err\n"); |
|
63 |
+ debug_uart_tx("parity err "); |
|
64 | 64 |
if (UCA1STAT & UCFE) |
65 |
- debug_uart_tx("frm-err\n"); |
|
65 |
+ debug_uart_tx("frm-err "); |
|
66 |
+ debug_uart_tx("\n"); |
|
66 | 67 |
} |
67 | 68 |
bt_rx_buf[bt_rx_buf_wpos++] = UCA1RXBUF; |
68 | 69 |
bt_rx_buf_wpos %= BT_RX_MAX_SIZE; |
69 |
- LPM3_EXIT; |
|
70 |
+ // LPM3_EXIT; |
|
71 |
+ LPM3_EXIT_ISR(); |
|
70 | 72 |
_event_src |= BT_UART_RCV_EVENT; |
71 | 73 |
break; |
72 | 74 |
case 4: // TXIFG |
... | ... |
@@ -96,9 +98,10 @@ void mw_init_bt_uart(const bt_uart_baud_t baud) |
96 | 98 |
//UCA1CTL0 |= UCRXEIE; |
97 | 99 |
|
98 | 100 |
UCA1CTL1 &= ~UCSWRST; |
101 |
+ |
|
99 | 102 |
/* clear interrup flags */ |
100 |
- UCA1IE = UCRXIE; |
|
101 | 103 |
UCA1IFG = 0; |
104 |
+ UCA1IE = UCRXIE; |
|
102 | 105 |
} |
103 | 106 |
|
104 | 107 |
#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) |
121 | 124 |
nop(); |
122 | 125 |
} |
123 | 126 |
#else |
124 |
-void mw_bt_uart_tx(const void *buf, const unsigned int len) |
|
127 |
+int mw_bt_uart_tx(const void *buf, const unsigned int len) |
|
125 | 128 |
{ |
126 |
- unsigned int pos; |
|
129 |
+ unsigned int pos, i; |
|
127 | 130 |
// char txstr[8]; |
128 | 131 |
|
129 | 132 |
pos = 0; |
130 | 133 |
// debug_uart_tx("BT tx: "); |
131 | 134 |
while (pos < len) { |
132 |
- // wait for CTS to go low |
|
133 |
- while ((BT_IO_PIN & BT_IO_CTS)) |
|
134 |
- nop(); |
|
135 |
+ // watch for CTS to be low |
|
136 |
+ i = 0; |
|
137 |
+ while ((BT_IO_PIN & BT_IO_CTS) && (i < 1000)) { |
|
138 |
+ __delay_cycles(16000); |
|
139 |
+ i++; |
|
140 |
+ if (i >= 1000) |
|
141 |
+ return -1; |
|
142 |
+ // nop(); |
|
143 |
+ } |
|
135 | 144 |
|
136 | 145 |
// do not start a transfer if UART is busy, e.g. rx-ing |
137 | 146 |
while (UCA1STAT & UCBUSY) |
... | ... |
@@ -147,25 +156,31 @@ void mw_bt_uart_tx(const void *buf, const unsigned int len) |
147 | 156 |
} |
148 | 157 |
while (UCA1STAT & UCBUSY) |
149 | 158 |
nop(); |
159 |
+ |
|
160 |
+ return len; |
|
150 | 161 |
} |
151 | 162 |
#endif |
152 | 163 |
|
153 |
-static void load_cc256x_init_script(void) |
|
164 |
+static int load_cc256x_init_script(void) |
|
154 | 165 |
{ |
155 | 166 |
uint32_t pos; |
156 | 167 |
unsigned char *tptr; |
168 |
+ int tlen; |
|
157 | 169 |
|
158 | 170 |
pos = 0; |
159 | 171 |
while (pos < cc256x_init_script_size) { |
160 | 172 |
if (_event_src != 0) |
161 | 173 |
handle_event(); |
162 | 174 |
tptr = (unsigned char *)(cc256x_init_script + pos); |
163 |
- mw_bt_uart_tx(tptr, 4 + tptr[3]); |
|
164 |
- pos += 4 + tptr[3]; |
|
175 |
+ tlen = mw_bt_uart_tx(tptr, 4 + tptr[3]); |
|
176 |
+ if (tlen < 0) |
|
177 |
+ return -1; |
|
178 |
+ pos += tlen /*4 + tptr[3]*/; |
|
165 | 179 |
// each init script part is one HCI command so wait for reply |
166 | 180 |
if (_event_src != 0) |
167 | 181 |
handle_event(); |
168 | 182 |
} |
183 |
+ return 0; |
|
169 | 184 |
} |
170 | 185 |
|
171 | 186 |
void mw_enable_bt(void) |
... | ... |
@@ -174,6 +189,7 @@ void mw_enable_bt(void) |
174 | 189 |
|
175 | 190 |
/* make sure it resets */ |
176 | 191 |
BT_SHUTDOWN(); |
192 |
+ __delay_cycles(16000); |
|
177 | 193 |
|
178 | 194 |
/* enable 32kHz ACLK output to BT module */ |
179 | 195 |
P11DIR |= BIT0; |
... | ... |
@@ -182,11 +198,19 @@ void mw_enable_bt(void) |
182 | 198 |
// wait for clock to stabilize |
183 | 199 |
__delay_cycles(16000); |
184 | 200 |
|
201 |
+ // disable the IRQ on CTS, later used to get a wakeup IRQ from eHCILL |
|
202 |
+ // will be enabled when going to sleep |
|
203 |
+ P1IE &= ~BT_IO_CTS; |
|
204 |
+ P1IES &= ~BT_IO_CTS; |
|
205 |
+ |
|
185 | 206 |
BT_IO_PDIR &= ~(BT_IO_CTS | BT_IO_PIN1 | BT_IO_PIN2 | BT_IO_CLKREQ); |
186 | 207 |
BT_IO_PDIR |= BT_IO_RTS; |
208 |
+ |
|
187 | 209 |
BT_IO_POUT &= ~(BT_IO_CTS | BT_IO_PIN1 | BT_IO_PIN2 | BT_IO_CLKREQ); |
188 | 210 |
BT_IO_POUT &= ~BT_IO_RTS; // low == ready, high == !ready |
189 | 211 |
|
212 |
+ BT_IO_REN |= BT_IO_CTS; // enable pull-down on CTS, POUT-CTS is 0 already |
|
213 |
+ |
|
190 | 214 |
/* setup UART pins */ |
191 | 215 |
BT_UART_PSEL |= BT_UART_TX_PIN | BT_UART_RX_PIN; |
192 | 216 |
// P5OUT |= BT_UART_TX_PIN | BT_UART_RX_PIN; |
... | ... |
@@ -207,28 +231,45 @@ void mw_enable_bt(void) |
207 | 231 |
} |
208 | 232 |
if (i>=1000) { |
209 | 233 |
debug_uart_tx("Timeout waiting for CC256x to lower CTS\n"); |
234 |
+ mw_bt_enabled = 0; |
|
210 | 235 |
} else { |
211 | 236 |
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 |
|
237 |
+ |
|
238 |
+ // the init script consists of HCI cmds so HCI must be setup before |
|
239 |
+ bt_hci_init(); |
|
240 |
+ |
|
241 |
+ // give it some more time before anyone sends data |
|
242 |
+ for (i=0; i<10; i++) { |
|
243 |
+ __delay_cycles(16000); |
|
244 |
+ } |
|
245 |
+ if (load_cc256x_init_script() < 0) { |
|
246 |
+ debug_uart_tx("init upload failed!\n"); |
|
247 |
+ return; |
|
214 | 248 |
} |
215 |
- load_cc256x_init_script(); |
|
249 |
+ |
|
250 |
+ __delay_cycles(32000); |
|
251 |
+ |
|
216 | 252 |
debug_uart_tx("init uploaded\n"); |
217 |
- } |
|
218 | 253 |
|
219 |
- P1IE &= ~BT_IO_CTS; |
|
220 |
- P1IES &= ~BT_IO_CTS; |
|
254 |
+ init_l2cap(); |
|
221 | 255 |
|
222 |
- bt_hci_init(); |
|
223 |
- init_l2cap(); |
|
256 |
+ if (_event_src != 0) |
|
257 |
+ handle_event(); |
|
224 | 258 |
|
225 |
- mw_bt_enabled = 1; |
|
259 |
+ mw_bt_enabled = 1; |
|
260 |
+ } |
|
226 | 261 |
} |
227 | 262 |
|
228 | 263 |
void mw_disable_bt(void) |
229 | 264 |
{ |
230 | 265 |
mw_bt_enabled = 0; |
231 | 266 |
|
267 |
+ // disable the IRQ on CTS |
|
268 |
+ P1IE &= ~BT_IO_CTS; |
|
269 |
+ P1IES &= ~BT_IO_CTS; |
|
270 |
+ // BT_IO_REN &= ~BT_IO_CTS; // disable pull-down on CTS |
|
271 |
+ P1IFG &= ~BT_IO_CTS; |
|
272 |
+ |
|
232 | 273 |
/* disable UART RX interrupt */ |
233 | 274 |
UCA1IE &= ~UCRXIE; |
234 | 275 |
|
... | ... |
@@ -19,16 +19,30 @@ static unsigned char bt_rx_buf_wpos = 0; |
19 | 19 |
static unsigned char bt_rx_buf_rpos = 0; |
20 | 20 |
static uint8_t mw_bt_enabled = 0; |
21 | 21 |
|
22 |
+int mw_bt_get_rxbuf_len(void) |
|
23 |
+{ |
|
24 |
+ if (bt_rx_buf_rpos > bt_rx_buf_wpos) |
|
25 |
+ return (BT_RX_MAX_SIZE - bt_rx_buf_rpos) + bt_rx_buf_wpos; |
|
26 |
+ else |
|
27 |
+ return bt_rx_buf_wpos - bt_rx_buf_rpos; |
|
28 |
+} |
|
29 |
+ |
|
22 | 30 |
const unsigned char *mw_bt_get_rx_buf(unsigned char **rpos, unsigned char *len) |
23 | 31 |
{ |
24 | 32 |
*rpos = &bt_rx_buf_rpos; |
33 |
+ |
|
25 | 34 |
if (bt_rx_buf_rpos > bt_rx_buf_wpos) |
26 | 35 |
*len = (BT_RX_MAX_SIZE - bt_rx_buf_rpos) + bt_rx_buf_wpos; |
27 | 36 |
else |
28 | 37 |
*len = bt_rx_buf_wpos - bt_rx_buf_rpos; |
29 | 38 |
|
30 |
- if (*len > (BT_RX_MAX_SIZE-(BT_RX_MAX_SIZE/10))) |
|
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"); |
|
31 | 42 |
BT_IO_POUT |= BT_IO_RTS; // low == ready, high == !ready |
43 |
+ } else { |
|
44 |
+ BT_IO_POUT &= ~BT_IO_RTS; // low == ready, high == !ready |
|
45 |
+ } |
|
32 | 46 |
|
33 | 47 |
return (unsigned char *)bt_rx_buf; |
34 | 48 |
} |
... | ... |
@@ -38,15 +52,25 @@ __interrupt void UCA1_ISR (void) |
38 | 52 |
{ |
39 | 53 |
switch (UCA1IV) { |
40 | 54 |
case 2: // RXIFG |
55 |
+ /* clear IRQ flag */ |
|
56 |
+ //UCA1IFG &= ~UCRXIFG; |
|
41 | 57 |
/* wake up to handle the received char */ |
42 |
- LPM3_EXIT; |
|
58 |
+ if (UCA1STAT & UCRXERR) { |
|
59 |
+ debug_uart_tx("BT UART RXERR: "); |
|
60 |
+ if (UCA1STAT & UCOE) |
|
61 |
+ debug_uart_tx("overrun\n"); |
|
62 |
+ if (UCA1STAT & UCPE) |
|
63 |
+ debug_uart_tx("parity err\n"); |
|
64 |
+ if (UCA1STAT & UCFE) |
|
65 |
+ debug_uart_tx("frm-err\n"); |
|
66 |
+ } |
|
43 | 67 |
bt_rx_buf[bt_rx_buf_wpos++] = UCA1RXBUF; |
44 |
- /* clear IRQ flag */ |
|
45 |
- UCA1IFG &= ~UCRXIFG; |
|
46 | 68 |
bt_rx_buf_wpos %= BT_RX_MAX_SIZE; |
69 |
+ LPM3_EXIT; |
|
47 | 70 |
_event_src |= BT_UART_RCV_EVENT; |
48 | 71 |
break; |
49 | 72 |
case 4: // TXIFG |
73 |
+ debug_uart_tx("BT UART TX IRQ - huh?\n"); |
|
50 | 74 |
break; |
51 | 75 |
default: |
52 | 76 |
break; |
... | ... |
@@ -56,7 +80,9 @@ __interrupt void UCA1_ISR (void) |
56 | 80 |
void mw_init_bt_uart(const bt_uart_baud_t baud) |
57 | 81 |
{ |
58 | 82 |
UCA1CTL1 = UCSWRST; |
83 |
+ |
|
59 | 84 |
UCA1CTL1 |= UCSSEL__SMCLK; |
85 |
+ |
|
60 | 86 |
switch (baud) { |
61 | 87 |
case BT_UART_BD115200: |
62 | 88 |
default: |
... | ... |
@@ -65,13 +91,14 @@ void mw_init_bt_uart(const bt_uart_baud_t baud) |
65 | 91 |
break; |
66 | 92 |
}; |
67 | 93 |
UCA1STAT = 0; |
68 |
- UCA1CTL0 = UCMODE_0; // UART mode |
|
69 |
- UCA1CTL0 &= ~UC7BIT; // 8bit char |
|
94 |
+ // UCA1CTL0 = UCMODE_0; // UART mode |
|
95 |
+ // UCA1CTL0 &= ~UC7BIT; // 8bit char |
|
96 |
+ //UCA1CTL0 |= UCRXEIE; |
|
70 | 97 |
|
71 | 98 |
UCA1CTL1 &= ~UCSWRST; |
72 | 99 |
/* clear interrup flags */ |
73 |
- UCA1IFG = 0; |
|
74 | 100 |
UCA1IE = UCRXIE; |
101 |
+ UCA1IFG = 0; |
|
75 | 102 |
} |
76 | 103 |
|
77 | 104 |
#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) |
102 | 129 |
pos = 0; |
103 | 130 |
// debug_uart_tx("BT tx: "); |
104 | 131 |
while (pos < len) { |
105 |
- while ((BT_IO_PIN & BT_IO_CTS)) // wait for CTS to go low |
|
132 |
+ // wait for CTS to go low |
|
133 |
+ while ((BT_IO_PIN & BT_IO_CTS)) |
|
134 |
+ nop(); |
|
135 |
+ |
|
136 |
+ // do not start a transfer if UART is busy, e.g. rx-ing |
|
137 |
+ while (UCA1STAT & UCBUSY) |
|
106 | 138 |
nop(); |
107 | 139 |
|
108 | 140 |
UCA1TXBUF = *(unsigned char *) (buf+pos); |
... | ... |
@@ -115,7 +147,6 @@ void mw_bt_uart_tx(const void *buf, const unsigned int len) |
115 | 147 |
} |
116 | 148 |
while (UCA1STAT & UCBUSY) |
117 | 149 |
nop(); |
118 |
- // debug_uart_tx("\n"); |
|
119 | 150 |
} |
120 | 151 |
#endif |
121 | 152 |
|
... | ... |
@@ -163,6 +194,9 @@ void mw_enable_bt(void) |
163 | 194 |
|
164 | 195 |
mw_init_bt_uart(BT_UART_BD115200); |
165 | 196 |
|
197 |
+ bt_rx_buf_wpos = 0; |
|
198 |
+ bt_rx_buf_rpos = 0; |
|
199 |
+ |
|
166 | 200 |
/* release BT reset pin */ |
167 | 201 |
BT_ENABLE(); |
168 | 202 |
|
... | ... |
@@ -181,10 +215,13 @@ void mw_enable_bt(void) |
181 | 215 |
load_cc256x_init_script(); |
182 | 216 |
debug_uart_tx("init uploaded\n"); |
183 | 217 |
} |
218 |
+ |
|
184 | 219 |
P1IE &= ~BT_IO_CTS; |
185 | 220 |
P1IES &= ~BT_IO_CTS; |
221 |
+ |
|
186 | 222 |
bt_hci_init(); |
187 | 223 |
init_l2cap(); |
224 |
+ |
|
188 | 225 |
mw_bt_enabled = 1; |
189 | 226 |
} |
190 | 227 |
|
... | ... |
@@ -188,17 +188,6 @@ void mw_enable_bt(void) |
188 | 188 |
mw_bt_enabled = 1; |
189 | 189 |
} |
190 | 190 |
|
191 |
-#pragma vector=PORT1_VECTOR |
|
192 |
-__interrupt void BT_CTS_ISR (void) |
|
193 |
-{ |
|
194 |
- P1IFG &= ~BT_IO_CTS; |
|
195 |
- |
|
196 |
- debug_uart_tx("BTS CTS triggered\n"); |
|
197 |
- bt_hci_ehcill_wake(); |
|
198 |
- |
|
199 |
- LPM3_EXIT; |
|
200 |
-} |
|
201 |
- |
|
202 | 191 |
void mw_disable_bt(void) |
203 | 192 |
{ |
204 | 193 |
mw_bt_enabled = 0; |
1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,228 @@ |
1 |
+#include <msp430.h> |
|
2 |
+#include <msp430xgeneric.h> |
|
3 |
+#include <stdint.h> |
|
4 |
+#include <stdio.h> |
|
5 |
+#include <string.h> |
|
6 |
+ |
|
7 |
+#include "mw_main.h" |
|
8 |
+ |
|
9 |
+#include "mw_uart.h" |
|
10 |
+#include "mw_bt.h" |
|
11 |
+#include "bt_hci.h" |
|
12 |
+#include "bt_l2cap.h" |
|
13 |
+ |
|
14 |
+#include "bluetooth_init_cc256x.h" |
|
15 |
+ |
|
16 |
+ |
|
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; |
|
21 |
+ |
|
22 |
+const unsigned char *mw_bt_get_rx_buf(unsigned char **rpos, unsigned char *len) |
|
23 |
+{ |
|
24 |
+ *rpos = &bt_rx_buf_rpos; |
|
25 |
+ if (bt_rx_buf_rpos > bt_rx_buf_wpos) |
|
26 |
+ *len = (BT_RX_MAX_SIZE - bt_rx_buf_rpos) + bt_rx_buf_wpos; |
|
27 |
+ else |
|
28 |
+ *len = bt_rx_buf_wpos - bt_rx_buf_rpos; |
|
29 |
+ |
|
30 |
+ if (*len > (BT_RX_MAX_SIZE-(BT_RX_MAX_SIZE/10))) |
|
31 |
+ BT_IO_POUT |= BT_IO_RTS; // low == ready, high == !ready |
|
32 |
+ |
|
33 |
+ return (unsigned char *)bt_rx_buf; |
|
34 |
+} |
|
35 |
+ |
|
36 |
+#pragma vector=USCI_A1_VECTOR |
|
37 |
+__interrupt void UCA1_ISR (void) |
|
38 |
+{ |
|
39 |
+ switch (UCA1IV) { |
|
40 |
+ case 2: // RXIFG |
|
41 |
+ /* wake up to handle the received char */ |
|
42 |
+ LPM3_EXIT; |
|
43 |
+ bt_rx_buf[bt_rx_buf_wpos++] = UCA1RXBUF; |
|
44 |
+ /* clear IRQ flag */ |
|
45 |
+ UCA1IFG &= ~UCRXIFG; |
|
46 |
+ bt_rx_buf_wpos %= BT_RX_MAX_SIZE; |
|
47 |
+ _event_src |= BT_UART_RCV_EVENT; |
|
48 |
+ break; |
|
49 |
+ case 4: // TXIFG |
|
50 |
+ break; |
|
51 |
+ default: |
|
52 |
+ break; |
|
53 |
+ }; |
|
54 |
+} |
|
55 |
+ |
|
56 |
+void mw_init_bt_uart(const bt_uart_baud_t baud) |
|
57 |
+{ |
|
58 |
+ UCA1CTL1 = UCSWRST; |
|
59 |
+ UCA1CTL1 |= UCSSEL__SMCLK; |
|
60 |
+ switch (baud) { |
|
61 |
+ case BT_UART_BD115200: |
|
62 |
+ default: |
|
63 |
+ UCA1BR0 = 138; |
|
64 |
+ UCA1MCTL = UCBRS_7 + UCBRF_0; |
|
65 |
+ break; |
|
66 |
+ }; |
|
67 |
+ UCA1STAT = 0; |
|
68 |
+ UCA1CTL0 = UCMODE_0; // UART mode |
|
69 |
+ UCA1CTL0 &= ~UC7BIT; // 8bit char |
|
70 |
+ |
|
71 |
+ UCA1CTL1 &= ~UCSWRST; |
|
72 |
+ /* clear interrup flags */ |
|
73 |
+ UCA1IFG = 0; |
|
74 |
+ UCA1IE = UCRXIE; |
|
75 |
+} |
|
76 |
+ |
|
77 |
+#if 0 // Does never finish, presumably trigger does not trigger, unknown :( |
|
78 |
+void mw_bt_uart_tx(const void *buf, const unsigned int len) |
|
79 |
+{ |
|
80 |
+ UCA1IE &= UCTXIE; |
|
81 |
+ |
|
82 |
+ DMACTL0 = DMA0TSEL_21; |
|
83 |
+ |
|
84 |
+ DMA0DA = (unsigned int) &UCA1TXBUF; |
|
85 |
+ DMA0SA = (uint32_t) buf; |
|
86 |
+ DMA0SZ = len; |
|
87 |
+ |
|
88 |
+ //DMA0CTL = 0x03F0; |
|
89 |
+ DMA0CTL = DMADT_1 | DMASRCINCR_3 | DMASBDB | DMALEVEL | DMAIE; |
|
90 |
+ UCA1IFG &= ~UCTXIFG; |
|
91 |
+ DMA0CTL |= DMAEN; |
|
92 |
+ |
|
93 |
+ while ((DMA0CTL & DMAIFG) == 0 && (DMA0CTL & DMAABORT) == 0) |
|
94 |
+ nop(); |
|
95 |
+} |
|
96 |
+#else |
|
97 |
+void mw_bt_uart_tx(const void *buf, const unsigned int len) |
|
98 |
+{ |
|
99 |
+ unsigned int pos; |
|
100 |
+ // char txstr[8]; |
|
101 |
+ |
|
102 |
+ pos = 0; |
|
103 |
+ // debug_uart_tx("BT tx: "); |
|
104 |
+ while (pos < len) { |
|
105 |
+ while ((BT_IO_PIN & BT_IO_CTS)) // wait for CTS to go low |
|
106 |
+ nop(); |
|
107 |
+ |
|
108 |
+ UCA1TXBUF = *(unsigned char *) (buf+pos); |
|
109 |
+ // debug_uart_tx_char(*(unsigned char *) (buf+pos)); |
|
110 |
+ // snprintf(txstr, 8, "0x%02x ", *(unsigned char *) (buf+pos)); |
|
111 |
+ // debug_uart_tx(txstr); |
|
112 |
+ pos++; |
|
113 |
+ while ((UCA1IFG & UCTXIFG) == 0) |
|
114 |
+ nop(); |
|
115 |
+ } |
|
116 |
+ while (UCA1STAT & UCBUSY) |
|
117 |
+ nop(); |
|
118 |
+ // debug_uart_tx("\n"); |
|
119 |
+} |
|
120 |
+#endif |
|
121 |
+ |
|
122 |
+static void load_cc256x_init_script(void) |
|
123 |
+{ |
|
124 |
+ uint32_t pos; |
|
125 |
+ unsigned char *tptr; |
|
126 |
+ |
|
127 |
+ pos = 0; |
|
128 |
+ while (pos < cc256x_init_script_size) { |
|
129 |
+ if (_event_src != 0) |
|
130 |
+ handle_event(); |
|
131 |
+ tptr = (unsigned char *)(cc256x_init_script + pos); |
|
132 |
+ mw_bt_uart_tx(tptr, 4 + tptr[3]); |
|
133 |
+ pos += 4 + tptr[3]; |
|
134 |
+ // each init script part is one HCI command so wait for reply |
|
135 |
+ if (_event_src != 0) |
|
136 |
+ handle_event(); |
|
137 |
+ } |
|
138 |
+} |
|
139 |
+ |
|
140 |
+void mw_enable_bt(void) |
|
141 |
+{ |
|
142 |
+ int i; |
|
143 |
+ |
|
144 |
+ /* make sure it resets */ |
|
145 |
+ BT_SHUTDOWN(); |
|
146 |
+ |
|
147 |
+ /* enable 32kHz ACLK output to BT module */ |
|
148 |
+ P11DIR |= BIT0; |
|
149 |
+ P11SEL |= BIT0; |
|
150 |
+ |
|
151 |
+ // wait for clock to stabilize |
|
152 |
+ __delay_cycles(16000); |
|
153 |
+ |
|
154 |
+ BT_IO_PDIR &= ~(BT_IO_CTS | BT_IO_PIN1 | BT_IO_PIN2 | BT_IO_CLKREQ); |
|
155 |
+ BT_IO_PDIR |= BT_IO_RTS; |
|
156 |
+ BT_IO_POUT &= ~(BT_IO_CTS | BT_IO_PIN1 | BT_IO_PIN2 | BT_IO_CLKREQ); |
|
157 |
+ BT_IO_POUT &= ~BT_IO_RTS; // low == ready, high == !ready |
|
158 |
+ |
|
159 |
+ /* setup UART pins */ |
|
160 |
+ BT_UART_PSEL |= BT_UART_TX_PIN | BT_UART_RX_PIN; |
|
161 |
+ // P5OUT |= BT_UART_TX_PIN | BT_UART_RX_PIN; |
|
162 |
+ // P5REN |= BT_UART_TX_PIN | BT_UART_RX_PIN; |
|
163 |
+ |
|
164 |
+ mw_init_bt_uart(BT_UART_BD115200); |
|
165 |
+ |
|
166 |
+ /* release BT reset pin */ |
|
167 |
+ BT_ENABLE(); |
|
168 |
+ |
|
169 |
+ for (i=0; i<1000; i++) { |
|
170 |
+ __delay_cycles(16000); |
|
171 |
+ if ((BT_IO_PIN & BT_IO_CTS) == 0) // when CTS goes low module is ready |
|
172 |
+ break; |
|
173 |
+ } |
|
174 |
+ if (i>=1000) { |
|
175 |
+ debug_uart_tx("Timeout waiting for CC256x to lower CTS\n"); |
|
176 |
+ } else { |
|
177 |
+ debug_uart_tx("CC256x CTS low - uploading init\n"); |
|
178 |
+ for (i=0; i<100; i++) { |
|
179 |
+ __delay_cycles(16000); // give it some more before anyone sends data |
|
180 |
+ } |
|
181 |
+ load_cc256x_init_script(); |
|
182 |
+ debug_uart_tx("init uploaded\n"); |
|
183 |
+ } |
|
184 |
+ P1IE &= ~BT_IO_CTS; |
|
185 |
+ P1IES &= ~BT_IO_CTS; |
|
186 |
+ bt_hci_init(); |
|
187 |
+ init_l2cap(); |
|
188 |
+ mw_bt_enabled = 1; |
|
189 |
+} |
|
190 |
+ |
|
191 |
+#pragma vector=PORT1_VECTOR |
|
192 |
+__interrupt void BT_CTS_ISR (void) |
|
193 |
+{ |
|
194 |
+ P1IFG &= ~BT_IO_CTS; |
|
195 |
+ |
|
196 |
+ debug_uart_tx("BTS CTS triggered\n"); |
|
197 |
+ bt_hci_ehcill_wake(); |
|
198 |
+ |
|
199 |
+ LPM3_EXIT; |
|
200 |
+} |
|
201 |
+ |
|
202 |
+void mw_disable_bt(void) |
|
203 |
+{ |
|
204 |
+ mw_bt_enabled = 0; |
|
205 |
+ |
|
206 |
+ /* disable UART RX interrupt */ |
|
207 |
+ UCA1IE &= ~UCRXIE; |
|
208 |
+ |
|
209 |
+ /* disable UART pins */ |
|
210 |
+ BT_UART_PSEL &= ~(BT_UART_TX_PIN | BT_UART_RX_PIN); |
|
211 |
+ |
|
212 |
+ /* set BT reset pin */ |
|
213 |
+ BT_SHUTDOWN(); |
|
214 |
+ |
|
215 |
+ /* disable 32kHz ACLK output to BT module */ |
|
216 |
+ P11DIR &= ~BIT0; |
|
217 |
+ P11SEL &= ~BIT0; |
|
218 |
+ |
|
219 |
+ /* make all I/O Pins inputs so we do not drive against a "deaf" module */ |
|
220 |
+ BT_IO_PDIR &= ~(BT_IO_RTS | BT_IO_CTS | BT_IO_PIN1 | BT_IO_PIN2 | BT_IO_CLKREQ); |
|
221 |
+ BT_IO_POUT &= ~(BT_IO_RTS | BT_IO_CTS | BT_IO_PIN1 | BT_IO_PIN2 | BT_IO_CLKREQ); |
|
222 |
+} |
|
223 |
+ |
|
224 |
+uint8_t mw_bt_is_enabled(void) |
|
225 |
+{ |
|
226 |
+ return mw_bt_enabled; |
|
227 |
+} |
|
228 |
+ |