2 #include <msp430xgeneric.h>
15 static uint8_t local_bdaddr[6];
17 uint8_t *bt_hci_get_local_bdaddr(void)
22 static void bt_print_bd_addr(uint8_t *bd_addr)
24 #if defined MW_DEVBOARD_V2
28 for (i=5; i>=0; i--) {
29 snprintf(nums, 4, "%02x", bd_addr[i]);
32 debug_uart_tx_char(':');
37 void bt_hci_process_acl_packet(unsigned char *packet)
39 #if defined MW_DEVBOARD_V2
49 // debug_uart_tx("ACL packet, ");
50 handle = packet[0] | ((packet[1] & 0x0f) << 8);
51 // snprintf(tstr, 32, "handle 0x%04x ", handle);
52 // debug_uart_tx(tstr);
53 PB = (packet[1] >> 4) & 0x03;
54 BC = (packet[1] >> 6) & 0x03;
55 // snprintf(tstr, 32, "PB 0x%02x BC 0x%02x ", PB, BC);
56 // debug_uart_tx(tstr);
58 dlen = packet[2] | ((uint16_t)packet[3] << 8);
59 // snprintf(tstr, 32, "len 0x%04x \n", dlen);
60 // debug_uart_tx(tstr);
61 // debug_dump_hex(dlen+4, packet);
63 channel = packet[4+2] | (packet[4+3] << 8);
64 mlen = packet[4] | (packet[4+1] << 8);
66 case L2CAP_CID_SIGNALING:
67 bt_l2cap_proc_signalling(handle, (packet+8), mlen);
69 case L2CAP_CID_CONNECTIONLESS_CHANNEL:
71 case L2CAP_CID_ATTRIBUTE_PROTOCOL:
73 case L2CAP_CID_SIGNALING_LE:
75 case L2CAP_CID_SECURITY_MANAGER_PROTOCOL:
79 // just for sure, add a 0 as string delimiter
80 packet[mlen+8] = 0x00;
81 bt_l2cap_proc_dyn_channel(channel, handle, (packet+8), mlen);
83 #if defined MW_DEVBOARD_V2
84 snprintf(tstr, 32, "L2CAP unhandled CID 0x%04x\n", channel);
92 void bt_hci_process_event_packet(unsigned char *packet)
94 #if defined MW_DEVBOARD_V2
98 // uint8_t bd_addr[6];
101 // debug_uart_tx("Event packet, ");
102 // snprintf(tstr, 32, "evt 0x%02x: ", packet[0]);
103 // debug_uart_tx(tstr);
106 case HCI_EVENT_INQUIRY_COMPLETE:
107 debug_uart_tx("inq complete\n");
109 case HCI_EVENT_INQUIRY_RESULT:
110 debug_uart_tx("inq result\n");
112 case HCI_EVENT_CONNECTION_COMPLETE:
113 debug_uart_tx("con complete from ");
114 #if defined MW_DEVBOARD_V2
115 bt_print_bd_addr((packet+5));
116 snprintf(tstr, 32, " status 0x%02x handle 0x%02x", packet[2], packet[3]);
118 snprintf(tstr, 32, " type 0x%02x enc 0x%02x\n", packet[11], packet[12]);
120 if (packet[2] == 0x00)
121 debug_uart_tx("connection established\n");
123 debug_uart_tx("connection failed\n");
126 case HCI_EVENT_CONNECTION_REQUEST: {
129 switch (packet[11]) {
130 case HCI_LINK_TYPE_SCO:
131 debug_uart_tx("SCO");
133 case HCI_LINK_TYPE_ACL:
134 debug_uart_tx("ACL");
136 case HCI_LINK_TYPE_ESCO:
137 debug_uart_tx("eSCO");
140 debug_uart_tx("unknown type");
143 debug_uart_tx(" con req from ");
144 for (i=0; i<6; i++) {
145 bd_addr[i] = packet[i+2];
147 bt_print_bd_addr(bd_addr);
148 dev_type = (uint32_t)packet[8] << 16;
149 dev_type |= (uint32_t)packet[9] << 8;
150 dev_type |= packet[10];
151 #if defined MW_DEVBOARD_V2
152 snprintf(tstr, 32, " rem. dtype 0x%06lx\n", dev_type);
155 //memcpy(tstr, bd_addr, 6);
156 //tstr[6] = 0x01; /* remain slave */
157 bd_addr[6] = 0x01; /* remain slave */
158 bt_hci_cmd(HCI_LINK_CTRL_OGF, HCI_ACCEPT_CONN_REQ_OCF, 7, bd_addr);
160 case HCI_EVENT_DISCONNECTION_COMPLETE:
161 debug_uart_tx("discon complete\n");
163 case HCI_EVENT_AUTHENTICATION_COMPLETE_EVENT:
164 debug_uart_tx("auth complete\n");
166 case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE:
167 debug_uart_tx("rem name req complete\n");
169 case HCI_EVENT_ENCRYPTION_CHANGE:
170 debug_uart_tx("enc change\n");
172 case HCI_EVENT_CHANGE_CONNECTION_LINK_KEY_COMPLETE:
173 debug_uart_tx("change con link key complete\n");
175 case HCI_EVENT_MASTER_LINK_KEY_COMPLETE:
176 debug_uart_tx("master link key complete\n");
178 case HCI_EVENT_READ_REMOTE_SUPPORTED_FEATURES_COMPLETE:
179 debug_uart_tx("read rem feat. complete\n");
181 case HCI_EVENT_READ_REMOTE_VERSION_INFORMATION_COMPLETE:
182 debug_uart_tx("read rem version complete\n");
184 case HCI_EVENT_QOS_SETUP_COMPLETE:
185 debug_uart_tx("qos setup complete\n");
187 case HCI_EVENT_COMMAND_COMPLETE:
188 // snprintf(tstr, 32, "%d cmd(s) complete: 0x%02x%02x=%d", packet[2], packet[3], packet[4], packet[5]);
189 // debug_uart_tx(tstr);
191 packet[3] == ((HCI_R_BD_ADDR_OCF | (HCI_INFO_PARAM_OGF << 10)) & 0xff) &&
192 packet[4] == (((HCI_R_BD_ADDR_OCF | (HCI_INFO_PARAM_OGF << 10)) & 0xff00) >> 8)) { // read local bdaddr
193 memcpy(local_bdaddr, (packet+6), 6);
194 #if defined MW_DEVBOARD_V2
195 debug_uart_tx("local bdaddr = ");
196 bt_print_bd_addr((uint8_t *)(packet+6));
201 case HCI_EVENT_COMMAND_STATUS:
202 debug_uart_tx("cmd status\n");
204 case HCI_EVENT_HARDWARE_ERROR:
205 #if defined MW_DEVBOARD_V2
206 debug_uart_tx("hardw err");
207 snprintf(tstr, 32, " 0x%02x\n", packet[2]);
211 case HCI_EVENT_FLUSH_OCCURED:
212 debug_uart_tx("flush occured\n");
214 case HCI_EVENT_ROLE_CHANGE:
215 debug_uart_tx("role change\n");
217 case HCI_EVENT_NUMBER_OF_COMPLETED_PACKETS:
218 debug_uart_tx("numb compl. packets\n");
220 case HCI_EVENT_MODE_CHANGE_EVENT:
221 debug_uart_tx("mode change\n");
223 case HCI_EVENT_RETURN_LINK_KEYS:
224 debug_uart_tx("return link keys\n");
226 case HCI_EVENT_PIN_CODE_REQUEST:
227 debug_uart_tx("pin code request\n");
228 #if defined MW_DEVBOARD_V2
229 debug_uart_tx("from ");
230 bt_print_bd_addr((uint8_t *)(packet+2));
233 memmove(packet, (packet+2), 6);
234 packet[6] = 0x04; // PIN has length of 4
235 memcpy((packet+7), BT_PIN, 4);
240 bt_hci_cmd(HCI_LINK_CTRL_OGF, HCI_PIN_CODE_REQ_REP_OCF, 11, packet);
242 case HCI_EVENT_LINK_KEY_REQUEST:
243 debug_uart_tx("link key request\n");
245 case HCI_EVENT_LINK_KEY_NOTIFICATION:
246 debug_uart_tx("link key notify\n");
248 case HCI_EVENT_DATA_BUFFER_OVERFLOW:
249 debug_uart_tx("evt data buf overflow\n");
251 case HCI_EVENT_MAX_SLOTS_CHANGED:
252 debug_uart_tx("max slots changed\n");
254 case HCI_EVENT_READ_CLOCK_OFFSET_COMPLETE:
255 debug_uart_tx("read clock offset compl.\n");
257 case HCI_EVENT_PACKET_TYPE_CHANGED:
258 debug_uart_tx("packet type changed\n");
260 case HCI_EVENT_PAGE_SCAN_REPETION_MODE_CHANGE:
261 debug_uart_tx("page scan repetition mode changed\n");
263 case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:
264 debug_uart_tx("inq result with RSSI\n");
266 case HCI_EVENT_EXTENDED_INQUIRY_RESPONSE:
267 debug_uart_tx("ext. inq. resp.\n");
269 case HCI_EVENT_LE_META:
270 debug_uart_tx("LE meta\n");
272 case HCI_EVENT_VENDOR_SPECIFIC:
273 debug_uart_tx("vend. spec.\n");
276 debug_uart_tx("unknown\n");
279 // debug_uart_tx("\n");
280 // for (i=2; i<=(packet[1]+1); i++) {
281 // snprintf(tstr, 32, " 0x%02x", packet[i]);
282 // debug_uart_tx(tstr);
284 // debug_uart_tx("\n");
288 HCI_PACKET_START = 0,
290 HCI_ACL_PACKET_HEADER,
293 HCI_EVENT_PACKET_HEADER,
294 HCI_EVENT_PACKET_DATA,
299 static bt_hci_state_t state = HCI_PACKET_START;
301 unsigned char bt_feed_packet_data(unsigned char pdata)
304 static unsigned char packet[255];
305 static uint16_t bytes_left = 0;
306 static uint16_t pdata_pos = 0;
308 // snprintf(tstr, 32, "bt 0x%02x ", pdata);
309 // debug_uart_tx(tstr);
311 case HCI_PACKET_START:
313 case HCI_EVENT_PACKET:
314 state = HCI_EVENT_PACKET_HEADER;
317 memset(packet, 0, 64);
319 case HCI_ACL_DATA_PACKET:
320 state = HCI_ACL_PACKET_HEADER;
323 memset(packet, 0, 64);
325 case EHCILL_GO_TO_SLEEP_IND:
326 debug_uart_tx("eHCILL go to sleep ind\n");
327 state = HCI_PACKET_START;
329 // mabye UCA1CTL1 = UCSWRST ?
330 pdata = EHCILL_GO_TO_SLEEP_ACK;
331 mw_bt_uart_tx(&pdata, 0x01);
332 BT_IO_POUT |= BT_IO_RTS; // pull RTS -> stop data
337 state = EHCILL_SLEEPING;
339 case EHCILL_GO_TO_SLEEP_ACK:
340 debug_uart_tx("eHCILL go to sleep ack\n");
341 state = HCI_PACKET_START;
343 case EHCILL_WAKE_UP_IND:
344 debug_uart_tx("eHCILL wake up ind\n");
345 state = HCI_PACKET_START;
347 case EHCILL_WAKE_UP_ACK:
348 debug_uart_tx("eHCILL wake up ack\n");
349 state = HCI_PACKET_START;
352 debug_uart_tx("unexpected packet start\n");
356 case HCI_EVENT_PACKET_HEADER:
357 if (bytes_left != 0) {
358 packet[pdata_pos++] = pdata;
361 state = HCI_EVENT_PACKET_DATA;
362 packet[pdata_pos++] = pdata;
366 case HCI_EVENT_PACKET_DATA:
367 packet[pdata_pos++] = pdata;
369 if (bytes_left == 0) {
370 state = HCI_PACKET_START;
371 bt_hci_process_event_packet(packet);
374 case HCI_ACL_PACKET_HEADER:
375 if (bytes_left != 0) {
376 packet[pdata_pos++] = pdata;
379 state = HCI_ACL_PACKET_DATA;
380 packet[pdata_pos] = pdata;
381 bytes_left = (packet[pdata_pos-1] | (packet[pdata_pos] << 8));
382 // snprintf(tstr, 32, "ACL data len 0x%04x\n", bytes_left);
383 // debug_uart_tx(tstr);
384 // snprintf(tstr, 32, "%d (0x%02x 0x%02x)\n", pdata_pos, packet[pdata_pos-1], packet[pdata_pos]);
385 // debug_uart_tx(tstr);
389 case HCI_ACL_PACKET_DATA:
390 // snprintf(tstr, 32, "%02x ", pdata);
391 // debug_uart_tx(tstr);
392 packet[pdata_pos++] = pdata;
394 if (bytes_left == 0) {
395 // debug_uart_tx("\n");
396 state = HCI_PACKET_START;
397 bt_hci_process_acl_packet(packet);
401 debug_uart_tx("hosed HCI state!\n");
402 snprintf(tstr, 32, " state = %d\n", state);
415 } __attribute__((packed)) bt_hci_cmd_t;
417 void bt_hci_cmd(const uint8_t OGF, const uint8_t OCF, const uint8_t data_len, const void *data)
421 if (state == EHCILL_SLEEPING) {
422 uint8_t ehcill_p = EHCILL_WAKE_UP_IND;
424 debug_uart_tx("HCILL wakeup\n");
425 state = HCI_PACKET_START;
426 mw_bt_uart_tx(&ehcill_p, 1);
427 __delay_cycles(300000);
428 BT_IO_POUT &= ~BT_IO_RTS; // drop RTS -> start data
430 packet.type = HCI_COMMAND_PACKET;
431 packet.cmd = OCF | (OGF<<10);
432 packet.length = data_len;
433 mw_bt_uart_tx(&packet, sizeof(bt_hci_cmd_t));
434 if (data_len > 0 && data != NULL)
435 mw_bt_uart_tx(data, data_len);
441 uint16_t total_length;
442 uint16_t data_length;
444 } __attribute__((packed)) bt_hci_acl_t;
446 void bt_acl_send(const uint16_t handle, const uint8_t PB, const uint8_t BC, const uint16_t channel, const uint16_t dlen, const void *dat)
450 packet.type = HCI_ACL_DATA_PACKET;
451 packet.handle = handle | ((PB & 0x03) << 12) | ((BC & 0x03) << 14);
452 packet.total_length = dlen + 4;
453 packet.data_length = dlen;
454 packet.channel = channel;
455 mw_bt_uart_tx(&packet, sizeof(bt_hci_acl_t));
456 mw_bt_uart_tx(dat, dlen);
459 void bt_hci_init(void)
461 state = HCI_PACKET_START;
464 void bt_hci_ehcill_wake(void)
466 uint8_t ehcill_p = EHCILL_WAKE_UP_ACK;
468 debug_uart_tx("HCILL wakeup\n");
471 state = HCI_PACKET_START;
473 BT_IO_POUT &= ~BT_IO_RTS; // drop RTS -> start data
475 mw_bt_uart_tx(&ehcill_p, 1);
476 //__delay_cycles(160000);