Browse code

Use strutils instead of snprintf (to save some bytes), set default year to 2014, partial revamp of the stopwatch

Dario Rodriguez authored on 14/01/2014 22:59:59
Showing 1 changed files
... ...
@@ -11,6 +11,8 @@
11 11
 #include "bt_hci.h"
12 12
 #include "bt_l2cap.h"
13 13
 
14
+#include "strutils.h"
15
+
14 16
 
15 17
 static uint8_t local_bdaddr[6];
16 18
 
... ...
@@ -26,7 +28,7 @@ static void bt_print_bd_addr(uint8_t *bd_addr)
26 28
 	char nums[4];
27 29
 
28 30
 	for (i=5; i>=0; i--) {
29
-		snprintf(nums, 4, "%02x", bd_addr[i]);
31
+		hexnum2str(bd_addr[i],nums,4);
30 32
 		debug_uart_tx(nums);
31 33
 		if (i>0)
32 34
 			debug_uart_tx_char(':');
... ...
@@ -48,16 +50,23 @@ void bt_hci_process_acl_packet(unsigned char *packet)
48 50
 
49 51
 //	debug_uart_tx("ACL packet, ");
50 52
 	handle = packet[0] | ((packet[1] & 0x0f) << 8);
51
-//	snprintf(tstr, 32, "handle 0x%04x ", handle);
53
+//	debug_uart_tx("handle 0x");
54
+//	hexnum2str(handle,tstr,4);
52 55
 //	debug_uart_tx(tstr);
53 56
 	PB = (packet[1] >> 4) & 0x03;
54 57
 	BC = (packet[1] >> 6) & 0x03;
55
-//	snprintf(tstr, 32, "PB 0x%02x BC 0x%02x ", PB, BC);
58
+//	debug_uart_tx(" PB 0x");
59
+//	hexnum2str(PB,tstr,2);
60
+//	debug_uart_tx(tstr);
61
+//	debug_uart_tx(" BC 0x");
62
+//	hexnum2str(BC,tstr,2);
56 63
 //	debug_uart_tx(tstr);
57 64
 
58 65
 	dlen = packet[2] | ((uint16_t)packet[3] << 8);
59
-//	snprintf(tstr, 32, "len 0x%04x \n", dlen);
66
+//	debug_uart_tx(" len 0x");
67
+//	hexnum2str(dlen,tstr,4);
60 68
 //	debug_uart_tx(tstr);
69
+//	debug_uart_tx("\n");
61 70
 //	debug_dump_hex(dlen+4, packet);
62 71
 
63 72
 	channel = packet[4+2] | (packet[4+3] << 8);
... ...
@@ -81,8 +90,10 @@ void bt_hci_process_acl_packet(unsigned char *packet)
81 90
 				bt_l2cap_proc_dyn_channel(channel, handle, (packet+8), mlen);
82 91
 			} else {
83 92
 #if defined MW_DEVBOARD_V2
84
-				snprintf(tstr, 32, "L2CAP unhandled CID 0x%04x\n", channel);
93
+				debug_uart_tx("L2CAP unhandled CID 0x");
94
+				hexnum2str(channel,tstr,4);
85 95
 				debug_uart_tx(tstr);
96
+				debug_uart_tx("\n");
86 97
 #endif
87 98
 			}
88 99
 			break;
... ...
@@ -98,9 +109,10 @@ void bt_hci_process_event_packet(unsigned char *packet)
98 109
 	// uint8_t bd_addr[6];
99 110
 	uint32_t dev_type;
100 111
 
101
-//	debug_uart_tx("Event packet, ");
102
-//	snprintf(tstr, 32, "evt 0x%02x: ", packet[0]);
112
+//	debug_uart_tx("Event packet, evt 0x");
113
+//	hexnum2str(packet[0],tstr,2);
103 114
 //	debug_uart_tx(tstr);
115
+//	debug_uart_tx(": ");
104 116
 
105 117
 	switch (packet[0]) {
106 118
 		case HCI_EVENT_INQUIRY_COMPLETE:
... ...
@@ -113,10 +125,19 @@ void bt_hci_process_event_packet(unsigned char *packet)
113 125
 			debug_uart_tx("con complete from ");
114 126
 #if defined MW_DEVBOARD_V2
115 127
 			bt_print_bd_addr((packet+5));
116
-			snprintf(tstr, 32, " status 0x%02x handle 0x%02x", packet[2], packet[3]);
128
+			debug_uart_tx(" status 0x");
129
+			hexnum2str(packet[2],tstr,2);
130
+			debug_uart_tx(tstr);
131
+			debug_uart_tx(" handle 0x");
132
+			hexnum2str(packet[3],tstr,2);
117 133
 			debug_uart_tx(tstr);
118
-			snprintf(tstr, 32, " type 0x%02x enc 0x%02x\n", packet[11], packet[12]);
134
+			debug_uart_tx(" type 0x");
135
+			hexnum2str(packet[11],tstr,2);
119 136
 			debug_uart_tx(tstr);
137
+			debug_uart_tx(" enc 0x");
138
+			hexnum2str(packet[12],tstr,2);
139
+			debug_uart_tx(tstr);
140
+			debug_uart_tx("\n");
120 141
 			if (packet[2] == 0x00)
121 142
 				debug_uart_tx("connection established\n");
122 143
 			else
... ...
@@ -149,8 +170,11 @@ void bt_hci_process_event_packet(unsigned char *packet)
149 170
 			dev_type |= (uint32_t)packet[9] << 8;
150 171
 			dev_type |= packet[10];
151 172
 #if defined MW_DEVBOARD_V2
152
-			snprintf(tstr, 32, " rem. dtype 0x%06lx\n", dev_type);
173
+			debug_uart_tx(" rem. dtype 0x");
174
+			hexnum2str((dev_type>>16)&0xFF,tstr,2);
175
+			hexnum2str(dev_type&0xFFFF,tstr+2,4);
153 176
 			debug_uart_tx(tstr);
177
+			debug_uart_tx("\n");
154 178
 #endif
155 179
 			//memcpy(tstr, bd_addr, 6);
156 180
 			//tstr[6] = 0x01; /* remain slave */
... ...
@@ -185,7 +209,15 @@ void bt_hci_process_event_packet(unsigned char *packet)
185 209
 			debug_uart_tx("qos setup complete\n");
186 210
 			break;
187 211
 		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]);
212
+			// num2str(packet[2],tstr,1,5);
213
+			// debug_uart_tx(tstr);
214
+			// debug_uart_tx(" cmd(s) complete: 0x");
215
+			// hexnum2str(packet[3],str,2);
216
+			// debug_uart_tx(tstr);
217
+			// hexnum2str(packet[4],str,2);
218
+			// debug_uart_tx(tstr);
219
+			// debug_uart_tx("=");
220
+			// num2str(packet[5],tstr,1,5);
189 221
 			// debug_uart_tx(tstr);
190 222
 			if (packet[2] > 0 &&
191 223
 			    packet[3] == ((HCI_R_BD_ADDR_OCF | (HCI_INFO_PARAM_OGF << 10)) & 0xff) &&
... ...
@@ -203,9 +235,10 @@ void bt_hci_process_event_packet(unsigned char *packet)
203 235
 			break;
204 236
 		case HCI_EVENT_HARDWARE_ERROR:
205 237
 #if defined MW_DEVBOARD_V2
206
-			debug_uart_tx("hardw err");
207
-			snprintf(tstr, 32, " 0x%02x\n", packet[2]);
238
+			debug_uart_tx("hardw err 0x");
239
+			hexnum2str(packet[2],str,2);
208 240
 			debug_uart_tx(tstr);
241
+			debug_uart_tx("\n");
209 242
 #endif
210 243
 			break;
211 244
 		case HCI_EVENT_FLUSH_OCCURED:
... ...
@@ -278,7 +311,8 @@ void bt_hci_process_event_packet(unsigned char *packet)
278 311
 	}
279 312
 //	debug_uart_tx("\n");
280 313
 //	for (i=2; i<=(packet[1]+1); i++) {
281
-//		snprintf(tstr, 32, " 0x%02x", packet[i]);
314
+//		debug_uart_tx(" 0x");
315
+//		hexnum2str(packet[i],tstr,2);
282 316
 //		debug_uart_tx(tstr);
283 317
 //	}
284 318
 //	debug_uart_tx("\n");
... ...
@@ -305,8 +339,10 @@ unsigned char bt_feed_packet_data(unsigned char pdata)
305 339
 	static uint16_t bytes_left = 0;
306 340
 	static uint16_t pdata_pos = 0;
307 341
 
308
-//	snprintf(tstr, 32, "bt 0x%02x ", pdata);
342
+//	debug_uart_tx("bt 0x");
343
+//	hexnum2str(pdata,tstr,2);
309 344
 //	debug_uart_tx(tstr);
345
+//	debug_uart_tx(" ");
310 346
 	switch (state) {
311 347
 		case HCI_PACKET_START:
312 348
 			switch (pdata) {
... ...
@@ -383,16 +419,26 @@ unsigned char bt_feed_packet_data(unsigned char pdata)
383 419
 				state = HCI_ACL_PACKET_DATA;
384 420
 				packet[pdata_pos] = pdata;
385 421
 				bytes_left = (packet[pdata_pos-1] | (packet[pdata_pos] << 8));
386
-//				snprintf(tstr, 32, "ACL data len 0x%04x\n", bytes_left);
387
-//				debug_uart_tx(tstr);
388
-//				snprintf(tstr, 32, "%d (0x%02x 0x%02x)\n", pdata_pos, packet[pdata_pos-1], packet[pdata_pos]);
422
+//				debug_uart_tx("ACL data len 0x");
423
+//				hexnum2str(bytes_left,tstr,4);
389 424
 //				debug_uart_tx(tstr);
425
+//				debug_uart_tx("\n");
426
+//				num2str(pdata_pos,tstr,1,5);
427
+//                              debug_uart_tx(tstr);
428
+//				debug_uart_tx(" (0x");
429
+//				hexnum2str(packet[pdata_pos-1],tstr,2);
430
+//                              debug_uart_tx(tstr);
431
+//                              debug_uart_tx(" 0x");
432
+//				hexnum2str(packet[pdata_pos],tstr,2);
433
+//                              debug_uart_tx(tstr);
434
+//				debug_uart_tx("\n");
390 435
 				pdata_pos++;
391 436
 			}
392 437
 			break;
393 438
 		case HCI_ACL_PACKET_DATA:
394
-//			snprintf(tstr, 32, "%02x ", pdata);
439
+//			hexnum2str(pdata,tstr,2);
395 440
 //			debug_uart_tx(tstr);
441
+//			debug_uart_tx(" ");
396 442
 			packet[pdata_pos++] = pdata;
397 443
 			bytes_left--;
398 444
 			if (bytes_left == 0) {
... ...
@@ -403,8 +449,12 @@ unsigned char bt_feed_packet_data(unsigned char pdata)
403 449
 			break;
404 450
 		default:
405 451
 			debug_uart_tx("hosed HCI state!\n");
406
-			snprintf(tstr, 32, "  state = %d\n", state);
452
+#if defined MW_DEVBOARD_V2
453
+			debug_uart_tx("  state= ");
454
+			num2str(state,tstr,1,5);
407 455
 			debug_uart_tx(tstr);
456
+			debug_uart_tx("\n");
457
+#endif
408 458
 			break;
409 459
 	};
410 460
 
Browse code

Sanity check for enabled BT

Nils Faerber authored on 06/07/2013 21:19:10
Showing 1 changed files
... ...
@@ -422,6 +422,10 @@ void bt_hci_cmd(const uint8_t OGF, const uint8_t OCF, const uint8_t data_len, co
422 422
 {
423 423
 	bt_hci_cmd_t packet;
424 424
 
425
+	// refuse any HCI if interface is not enabled
426
+	if (mw_bt_is_enabled() == 0)
427
+		return;
428
+
425 429
 	if (state == EHCILL_SLEEPING) {
426 430
 		uint8_t ehcill_p = EHCILL_WAKE_UP_IND;
427 431
 
... ...
@@ -472,6 +476,10 @@ void bt_acl_send(const uint16_t handle, const uint8_t PB, const uint8_t BC, cons
472 476
 {
473 477
 	bt_hci_acl_t packet;
474 478
 
479
+	// refuse any HCI if interface is not enabled
480
+	if (mw_bt_is_enabled() == 0)
481
+		return;
482
+
475 483
 	packet.type = HCI_ACL_DATA_PACKET;
476 484
 	packet.handle = handle | ((PB & 0x03) << 12) | ((BC & 0x03) << 14);
477 485
 	packet.total_length = dlen + 4;
Browse code

Power saving changes, add new fonts, bitmaps and screens

Nils Faerber authored on 19/05/2013 00:07:04
Showing 1 changed files
... ...
@@ -327,10 +327,14 @@ unsigned char bt_feed_packet_data(unsigned char pdata)
327 327
 					state = HCI_PACKET_START;
328 328
 					// disable BT UART?
329 329
 					// mabye UCA1CTL1 = UCSWRST ?
330
+
330 331
 					pdata = EHCILL_GO_TO_SLEEP_ACK;
331 332
 					mw_bt_uart_tx(&pdata, 0x01);
332
-					BT_IO_POUT |= BT_IO_RTS; // pull RTS -> stop data
333 333
 
334
+					// pull RTS -> stop data
335
+					BT_IO_POUT |= BT_IO_RTS;
336
+
337
+					// enable IRQ on CTS
334 338
 					P1IFG &= ~BT_IO_CTS;
335 339
 					P1IE |= BT_IO_CTS;
336 340
 
... ...
@@ -421,7 +425,7 @@ void bt_hci_cmd(const uint8_t OGF, const uint8_t OCF, const uint8_t data_len, co
421 425
 	if (state == EHCILL_SLEEPING) {
422 426
 		uint8_t ehcill_p = EHCILL_WAKE_UP_IND;
423 427
 
424
-		debug_uart_tx("HCILL wakeup\n");
428
+		debug_uart_tx("wakeup HCILL\n");
425 429
 		state = HCI_PACKET_START;
426 430
 		mw_bt_uart_tx(&ehcill_p, 1);
427 431
 		__delay_cycles(300000);
... ...
@@ -484,11 +488,12 @@ void bt_hci_init(void)
484 488
 
485 489
 void bt_hci_ehcill_wake(void)
486 490
 {
487
-	uint8_t ehcill_p = EHCILL_WAKE_UP_ACK;
491
+	const uint8_t ehcill_p = EHCILL_WAKE_UP_ACK;
488 492
 
489 493
 	debug_uart_tx("HCILL wakeup\n");
490 494
 
491 495
 	P1IE &= ~BT_IO_CTS;
496
+	P1IFG &= ~BT_IO_CTS;
492 497
 	state = HCI_PACKET_START;
493 498
 
494 499
 	BT_IO_POUT &= ~BT_IO_RTS; // drop RTS -> start data
Browse code

Maybe a little sniff mode, add ambient light adc (not working), fix accelerometer display orientation

Nils Faerber authored on 06/05/2013 23:39:18
Showing 1 changed files
... ...
@@ -435,6 +435,27 @@ void bt_hci_cmd(const uint8_t OGF, const uint8_t OCF, const uint8_t data_len, co
435 435
 		mw_bt_uart_tx(data, data_len);
436 436
 }
437 437
 
438
+typedef struct {
439
+	uint16_t acl_handle;
440
+	uint16_t max_interval;
441
+	uint16_t min_interval;
442
+	uint16_t sniff_attempt;
443
+	uint16_t sniff_timeout;
444
+} __attribute__((packed)) bt_hci_sniff_cmd_t;
445
+
446
+void bt_hci_set_sniff_mode(const uint16_t acl_handle, const uint16_t max_interval, const uint16_t min_interval, const uint16_t sniff_attempt, const uint16_t sniff_timeout)
447
+{
448
+	bt_hci_sniff_cmd_t sniff_cmd;
449
+
450
+	sniff_cmd.acl_handle = acl_handle;
451
+	sniff_cmd.max_interval = max_interval;
452
+	sniff_cmd.min_interval = min_interval;
453
+	sniff_cmd.sniff_attempt = sniff_attempt;
454
+	sniff_cmd.sniff_timeout = sniff_timeout;
455
+	
456
+	bt_hci_cmd(HCI_LINK_POLICY_OGF, HCI_SNIFF_MODE_OCF, sizeof(sniff_cmd), &sniff_cmd);
457
+}
458
+
438 459
 typedef struct {
439 460
 	uint8_t type;
440 461
 	uint16_t handle;
Browse code

Starting to get rid of borrowed code (LcdDisplay, Fonts), integrate new fonts and stuff

Nils Faerber authored on 28/04/2013 22:38:41
Showing 1 changed files
... ...
@@ -232,6 +232,7 @@ void bt_hci_process_event_packet(unsigned char *packet)
232 232
 #endif
233 233
 			memmove(packet, (packet+2), 6);
234 234
 			packet[6] = 0x04; // PIN has length of 4
235
+			memcpy((packet+7), BT_PIN, 4);
235 236
 			packet[7] = '4';
236 237
 			packet[8] = '3';
237 238
 			packet[9] = '1';
Browse code

Here we are! MetaWatch support in Oswald!

Nils Faerber authored on 27/04/2013 20:22:32
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,477 @@
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
+
15
+static uint8_t local_bdaddr[6];
16
+
17
+uint8_t *bt_hci_get_local_bdaddr(void)
18
+{
19
+	return local_bdaddr;
20
+}
21
+
22
+static void bt_print_bd_addr(uint8_t *bd_addr)
23
+{
24
+#if defined MW_DEVBOARD_V2
25
+	int i;
26
+	char nums[4];
27
+
28
+	for (i=5; i>=0; i--) {
29
+		snprintf(nums, 4, "%02x", bd_addr[i]);
30
+		debug_uart_tx(nums);
31
+		if (i>0)
32
+			debug_uart_tx_char(':');
33
+	}
34
+#endif
35
+}
36
+
37
+void bt_hci_process_acl_packet(unsigned char *packet)
38
+{
39
+#if defined MW_DEVBOARD_V2
40
+	char tstr[32];
41
+#endif
42
+	uint16_t dlen;
43
+	uint16_t handle;
44
+	L2CAP_PB_FLAG PB;
45
+	L2CAP_BC_FLAG BC;
46
+	uint16_t channel;
47
+	uint16_t mlen;
48
+
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);
57
+
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);
62
+
63
+	channel = packet[4+2] | (packet[4+3] << 8);
64
+	mlen = packet[4] | (packet[4+1] << 8);
65
+	switch (channel) {
66
+		case L2CAP_CID_SIGNALING:
67
+			bt_l2cap_proc_signalling(handle, (packet+8), mlen);
68
+			break;
69
+		case L2CAP_CID_CONNECTIONLESS_CHANNEL:
70
+			break;
71
+		case L2CAP_CID_ATTRIBUTE_PROTOCOL:
72
+			break;
73
+		case L2CAP_CID_SIGNALING_LE:
74
+			break;
75
+		case L2CAP_CID_SECURITY_MANAGER_PROTOCOL:
76
+			break;
77
+		default:
78
+			if (channel > 0x3f) {
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);
82
+			} else {
83
+#if defined MW_DEVBOARD_V2
84
+				snprintf(tstr, 32, "L2CAP unhandled CID 0x%04x\n", channel);
85
+				debug_uart_tx(tstr);
86
+#endif
87
+			}
88
+			break;
89
+	}
90
+}
91
+
92
+void bt_hci_process_event_packet(unsigned char *packet)
93
+{
94
+#if defined MW_DEVBOARD_V2
95
+	char tstr[32];
96
+#endif
97
+	int i;
98
+	// uint8_t bd_addr[6];
99
+	uint32_t dev_type;
100
+
101
+//	debug_uart_tx("Event packet, ");
102
+//	snprintf(tstr, 32, "evt 0x%02x: ", packet[0]);
103
+//	debug_uart_tx(tstr);
104
+
105
+	switch (packet[0]) {
106
+		case HCI_EVENT_INQUIRY_COMPLETE:
107
+			debug_uart_tx("inq complete\n");
108
+			break;
109
+		case HCI_EVENT_INQUIRY_RESULT:
110
+			debug_uart_tx("inq result\n");
111
+			break;
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]);
117
+			debug_uart_tx(tstr);
118
+			snprintf(tstr, 32, " type 0x%02x enc 0x%02x\n", packet[11], packet[12]);
119
+			debug_uart_tx(tstr);
120
+			if (packet[2] == 0x00)
121
+				debug_uart_tx("connection established\n");
122
+			else
123
+				debug_uart_tx("connection failed\n");
124
+#endif
125
+			break;
126
+		case HCI_EVENT_CONNECTION_REQUEST: {
127
+			uint8_t bd_addr[7];
128
+
129
+			switch (packet[11]) {
130
+				case HCI_LINK_TYPE_SCO:
131
+					debug_uart_tx("SCO");
132
+					break;
133
+				case HCI_LINK_TYPE_ACL:
134
+					debug_uart_tx("ACL");
135
+					break;
136
+				case HCI_LINK_TYPE_ESCO:
137
+					debug_uart_tx("eSCO");
138
+					break;
139
+				default:
140
+					debug_uart_tx("unknown type");
141
+					break;
142
+			}
143
+			debug_uart_tx(" con req from ");
144
+			for (i=0; i<6; i++) {
145
+				bd_addr[i] = packet[i+2];
146
+			}
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);
153
+			debug_uart_tx(tstr);
154
+#endif
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);
159
+			} break;
160
+		case HCI_EVENT_DISCONNECTION_COMPLETE:
161
+			debug_uart_tx("discon complete\n");
162
+			break;
163
+		case HCI_EVENT_AUTHENTICATION_COMPLETE_EVENT:
164
+			debug_uart_tx("auth complete\n");
165
+			break;
166
+		case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE:
167
+			debug_uart_tx("rem name req complete\n");
168
+			break;
169
+		case HCI_EVENT_ENCRYPTION_CHANGE:
170
+			debug_uart_tx("enc change\n");
171
+			break;
172
+		case HCI_EVENT_CHANGE_CONNECTION_LINK_KEY_COMPLETE:
173
+			debug_uart_tx("change con link key complete\n");
174
+			break;
175
+		case HCI_EVENT_MASTER_LINK_KEY_COMPLETE:
176
+			debug_uart_tx("master link key complete\n");
177
+			break;
178
+		case HCI_EVENT_READ_REMOTE_SUPPORTED_FEATURES_COMPLETE:
179
+			debug_uart_tx("read rem feat. complete\n");
180
+			break;
181
+		case HCI_EVENT_READ_REMOTE_VERSION_INFORMATION_COMPLETE:
182
+			debug_uart_tx("read rem version complete\n");
183
+			break;
184
+		case HCI_EVENT_QOS_SETUP_COMPLETE:
185
+			debug_uart_tx("qos setup complete\n");
186
+			break;
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);
190
+			if (packet[2] > 0 &&
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));
197
+				debug_uart_tx("\n");
198
+#endif
199
+			}
200
+			break;
201
+		case HCI_EVENT_COMMAND_STATUS:
202
+			debug_uart_tx("cmd status\n");
203
+			break;
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]);
208
+			debug_uart_tx(tstr);
209
+#endif
210
+			break;
211
+		case HCI_EVENT_FLUSH_OCCURED:
212
+			debug_uart_tx("flush occured\n");
213
+			break;
214
+		case HCI_EVENT_ROLE_CHANGE:
215
+			debug_uart_tx("role change\n");
216
+			break;
217
+		case HCI_EVENT_NUMBER_OF_COMPLETED_PACKETS:
218
+			debug_uart_tx("numb compl. packets\n");
219
+			break;
220
+		case HCI_EVENT_MODE_CHANGE_EVENT:
221
+			debug_uart_tx("mode change\n");
222
+			break;
223
+		case HCI_EVENT_RETURN_LINK_KEYS:
224
+			debug_uart_tx("return link keys\n");
225
+			break;
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));
231
+			debug_uart_tx("\n");
232
+#endif
233
+			memmove(packet, (packet+2), 6);
234
+			packet[6] = 0x04; // PIN has length of 4
235
+			packet[7] = '4';
236
+			packet[8] = '3';
237
+			packet[9] = '1';
238
+			packet[10] = '2';
239
+			bt_hci_cmd(HCI_LINK_CTRL_OGF, HCI_PIN_CODE_REQ_REP_OCF, 11, packet);
240
+			break;
241
+		case HCI_EVENT_LINK_KEY_REQUEST:
242
+			debug_uart_tx("link key request\n");
243
+			break;
244
+		case HCI_EVENT_LINK_KEY_NOTIFICATION:
245
+			debug_uart_tx("link key notify\n");
246
+			break;
247
+		case HCI_EVENT_DATA_BUFFER_OVERFLOW:
248
+			debug_uart_tx("evt data buf overflow\n");
249
+			break;
250
+		case HCI_EVENT_MAX_SLOTS_CHANGED:
251
+			debug_uart_tx("max slots changed\n");
252
+			break;
253
+		case HCI_EVENT_READ_CLOCK_OFFSET_COMPLETE:
254
+			debug_uart_tx("read clock offset compl.\n");
255
+			break;
256
+		case HCI_EVENT_PACKET_TYPE_CHANGED:
257
+			debug_uart_tx("packet type changed\n");
258
+			break;
259
+		case HCI_EVENT_PAGE_SCAN_REPETION_MODE_CHANGE:
260
+			debug_uart_tx("page scan repetition mode changed\n");
261
+			break;
262
+		case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:
263
+			debug_uart_tx("inq result with RSSI\n");
264
+			break;
265
+		case HCI_EVENT_EXTENDED_INQUIRY_RESPONSE:
266
+			debug_uart_tx("ext. inq. resp.\n");
267
+			break;
268
+		case HCI_EVENT_LE_META:
269
+			debug_uart_tx("LE meta\n");
270
+			break;
271
+		case HCI_EVENT_VENDOR_SPECIFIC:
272
+			debug_uart_tx("vend. spec.\n");
273
+			break;
274
+		default:
275
+			debug_uart_tx("unknown\n");
276
+			break;
277
+	}
278
+//	debug_uart_tx("\n");
279
+//	for (i=2; i<=(packet[1]+1); i++) {
280
+//		snprintf(tstr, 32, " 0x%02x", packet[i]);
281
+//		debug_uart_tx(tstr);
282
+//	}
283
+//	debug_uart_tx("\n");
284
+}
285
+
286
+typedef enum {
287
+	HCI_PACKET_START = 0,
288
+	HCI_CMD_PACKET,
289
+	HCI_ACL_PACKET_HEADER,
290
+	HCI_ACL_PACKET_DATA,
291
+	HCI_SCO_PACKET,
292
+	HCI_EVENT_PACKET_HEADER,
293
+	HCI_EVENT_PACKET_DATA,
294
+	HCI_EHCILL_PACKET,
295
+	EHCILL_SLEEPING
296
+} bt_hci_state_t;
297
+
298
+static bt_hci_state_t state = HCI_PACKET_START;
299
+
300
+unsigned char bt_feed_packet_data(unsigned char pdata)
301
+{
302
+	char tstr[32];
303
+	static unsigned char packet[255];
304
+	static uint16_t bytes_left = 0;
305
+	static uint16_t pdata_pos = 0;
306
+
307
+//	snprintf(tstr, 32, "bt 0x%02x ", pdata);
308
+//	debug_uart_tx(tstr);
309
+	switch (state) {
310
+		case HCI_PACKET_START:
311
+			switch (pdata) {
312
+				case HCI_EVENT_PACKET:
313
+					state = HCI_EVENT_PACKET_HEADER;
314
+					bytes_left = 1;
315
+					pdata_pos = 0;
316
+					memset(packet, 0, 64);
317
+					break;
318
+				case HCI_ACL_DATA_PACKET:
319
+					state = HCI_ACL_PACKET_HEADER;
320
+					bytes_left = 3;
321
+					pdata_pos = 0;
322
+					memset(packet, 0, 64);
323
+					break;
324
+				case EHCILL_GO_TO_SLEEP_IND:
325
+					debug_uart_tx("eHCILL go to sleep ind\n");
326
+					state = HCI_PACKET_START;
327
+					// disable BT UART?
328
+					// mabye UCA1CTL1 = UCSWRST ?
329
+					pdata = EHCILL_GO_TO_SLEEP_ACK;
330
+					mw_bt_uart_tx(&pdata, 0x01);
331
+					BT_IO_POUT |= BT_IO_RTS; // pull RTS -> stop data
332
+
333
+					P1IFG &= ~BT_IO_CTS;
334
+					P1IE |= BT_IO_CTS;
335
+
336
+					state = EHCILL_SLEEPING;
337
+					break;
338
+				case EHCILL_GO_TO_SLEEP_ACK:
339
+					debug_uart_tx("eHCILL go to sleep ack\n");
340
+					state = HCI_PACKET_START;
341
+					break;
342
+				case EHCILL_WAKE_UP_IND:
343
+					debug_uart_tx("eHCILL wake up ind\n");
344
+					state = HCI_PACKET_START;
345
+					break;
346
+				case EHCILL_WAKE_UP_ACK:
347
+					debug_uart_tx("eHCILL wake up ack\n");
348
+					state = HCI_PACKET_START;
349
+					break;
350
+				default:
351
+					debug_uart_tx("unexpected packet start\n");
352
+					break;
353
+			}
354
+			break;
355
+		case HCI_EVENT_PACKET_HEADER:
356
+			if (bytes_left != 0) {
357
+				packet[pdata_pos++] = pdata;
358
+				bytes_left--;
359
+			} else {
360
+				state = HCI_EVENT_PACKET_DATA;
361
+				packet[pdata_pos++] = pdata;
362
+				bytes_left = pdata;
363
+			}
364
+			break;
365
+		case HCI_EVENT_PACKET_DATA:
366
+			packet[pdata_pos++] = pdata;
367
+			bytes_left--;
368
+			if (bytes_left == 0) {
369
+				state = HCI_PACKET_START;
370
+				bt_hci_process_event_packet(packet);
371
+			}
372
+			break;
373
+		case HCI_ACL_PACKET_HEADER:
374
+			if (bytes_left != 0) {
375
+				packet[pdata_pos++] = pdata;
376
+				bytes_left--;
377
+			} else {
378
+				state = HCI_ACL_PACKET_DATA;
379
+				packet[pdata_pos] = pdata;
380
+				bytes_left = (packet[pdata_pos-1] | (packet[pdata_pos] << 8));
381
+//				snprintf(tstr, 32, "ACL data len 0x%04x\n", bytes_left);
382
+//				debug_uart_tx(tstr);
383
+//				snprintf(tstr, 32, "%d (0x%02x 0x%02x)\n", pdata_pos, packet[pdata_pos-1], packet[pdata_pos]);
384
+//				debug_uart_tx(tstr);
385
+				pdata_pos++;
386
+			}
387
+			break;
388
+		case HCI_ACL_PACKET_DATA:
389
+//			snprintf(tstr, 32, "%02x ", pdata);
390
+//			debug_uart_tx(tstr);
391
+			packet[pdata_pos++] = pdata;
392
+			bytes_left--;
393
+			if (bytes_left == 0) {
394
+//				debug_uart_tx("\n");
395
+				state = HCI_PACKET_START;
396
+				bt_hci_process_acl_packet(packet);
397
+			}
398
+			break;
399
+		default:
400
+			debug_uart_tx("hosed HCI state!\n");
401
+			snprintf(tstr, 32, "  state = %d\n", state);
402
+			debug_uart_tx(tstr);
403
+			break;
404
+	};
405
+
406
+	// one byte consumed
407
+	return 1;
408
+}
409
+
410
+typedef struct {
411
+	uint8_t type;
412
+	uint16_t cmd;
413
+	uint8_t length;
414
+} __attribute__((packed)) bt_hci_cmd_t;
415
+
416
+void bt_hci_cmd(const uint8_t OGF, const uint8_t OCF, const uint8_t data_len, const void *data)
417
+{
418
+	bt_hci_cmd_t packet;
419
+
420
+	if (state == EHCILL_SLEEPING) {
421
+		uint8_t ehcill_p = EHCILL_WAKE_UP_IND;
422
+
423
+		debug_uart_tx("HCILL wakeup\n");
424
+		state = HCI_PACKET_START;
425
+		mw_bt_uart_tx(&ehcill_p, 1);
426
+		__delay_cycles(300000);
427
+		BT_IO_POUT &= ~BT_IO_RTS; // drop RTS -> start data
428
+	}
429
+	packet.type = HCI_COMMAND_PACKET;
430
+	packet.cmd = OCF | (OGF<<10);
431
+	packet.length = data_len;
432
+	mw_bt_uart_tx(&packet, sizeof(bt_hci_cmd_t));
433
+	if (data_len > 0 && data != NULL)
434
+		mw_bt_uart_tx(data, data_len);
435
+}
436
+
437
+typedef struct {
438
+	uint8_t type;
439
+	uint16_t handle;
440
+	uint16_t total_length;
441
+	uint16_t data_length;
442
+	uint16_t channel;
443
+} __attribute__((packed)) bt_hci_acl_t;
444
+
445
+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)
446
+{
447
+	bt_hci_acl_t packet;
448
+
449
+	packet.type = HCI_ACL_DATA_PACKET;
450
+	packet.handle = handle | ((PB & 0x03) << 12) | ((BC & 0x03) << 14);
451
+	packet.total_length = dlen + 4;
452
+	packet.data_length = dlen;
453
+	packet.channel = channel;
454
+	mw_bt_uart_tx(&packet, sizeof(bt_hci_acl_t));
455
+	mw_bt_uart_tx(dat, dlen);
456
+}
457
+
458
+void bt_hci_init(void)
459
+{
460
+	state = HCI_PACKET_START;
461
+}
462
+
463
+void bt_hci_ehcill_wake(void)
464
+{
465
+	uint8_t ehcill_p = EHCILL_WAKE_UP_ACK;
466
+
467
+	debug_uart_tx("HCILL wakeup\n");
468
+
469
+	P1IE &= ~BT_IO_CTS;
470
+	state = HCI_PACKET_START;
471
+
472
+	BT_IO_POUT &= ~BT_IO_RTS; // drop RTS -> start data
473
+
474
+	mw_bt_uart_tx(&ehcill_p, 1);
475
+	//__delay_cycles(160000);
476
+}
477
+