xref: /btstack/port/msp432p401lp-cc256x/main.c (revision 31437b52049f7a1b5a54d9c71f935fe16cc0e09d)
1 /*
2  ******************************************************************************/
3 /* DriverLib Includes */
4 #include "driverlib.h"
5 
6 /* Standard Includes */
7 #include <stdint.h>
8 
9 #include <stdbool.h>
10 #include <string.h>
11 #include <stdio.h>
12 
13 #include "btstack_config.h"
14 
15 #include "bluetooth_company_id.h"
16 #include "btstack_chipset_cc256x.h"
17 #include "btstack_defines.h"
18 #include "btstack_event.h"
19 #include "btstack_debug.h"
20 #include "btstack_memory.h"
21 #include "btstack_tlv.h"
22 #include "btstack_run_loop.h"
23 #include "btstack_run_loop_embedded.h"
24 #include "hci_dump.h"
25 #include "btstack_tlv_flash_bank.h"
26 #include "hal_flash_bank_msp432.h"
27 #include "classic/btstack_link_key_db_tlv.h"
28 #include "ble/le_device_db_tlv.h"
29 
30 #ifdef ENABLE_SEGGER_RTT
31 #include "hci_dump_segger_rtt_stdout.h"
32 #else
33 #include "hci_dump_embedded_stdout.h"
34 #endif
35 
36 static void delay_ms(uint32_t ms);
37 
38 static hci_transport_config_uart_t config = {
39     HCI_TRANSPORT_CONFIG_UART,
40     115200,
41     3000000,      // main baudrate
42     1,      // flow control
43     NULL,
44 };
45 
46 static hal_flash_bank_msp432_t   hal_flash_bank_context;
47 static btstack_tlv_flash_bank_t btstack_tlv_flash_bank_context;
48 
49 #ifndef ENABLE_SEGGER_RTT
50 
51 /**
52  * Use USART_CONSOLE as a console.
53  * This is a syscall for newlib
54  * @param file
55  * @param ptr
56  * @param len
57  * @return
58  */
59 #include <stdio.h>
60 #include <unistd.h>
61 #include <errno.h>
62 int _write(int file, char *ptr, int len);
63 int _write(int file, char *ptr, int len){
64     uint8_t cr = '\r';
65     int i;
66 
67     if (file == STDOUT_FILENO || file == STDERR_FILENO) {
68         for (i = 0; i < len; i++) {
69             if (ptr[i] == '\n') {
70                 HAL_UART_Transmit( &huart2, &cr, 1, HAL_MAX_DELAY );
71             }
72             HAL_UART_Transmit( &huart2, (uint8_t *) &ptr[i], 1, HAL_MAX_DELAY );
73         }
74         return i;
75     }
76     errno = EIO;
77     return -1;
78 }
79 
80 #endif
81 
82 int _read(int file, char * ptr, int len){
83     UNUSED(file);
84     UNUSED(ptr);
85     UNUSED(len);
86     return -1;
87 }
88 
89 
90 int _close(int file){
91     UNUSED(file);
92     return -1;
93 }
94 
95 int _isatty(int file){
96     UNUSED(file);
97     return -1;
98 }
99 
100 int _lseek(int file){
101     UNUSED(file);
102     return -1;
103 }
104 
105 int _fstat(int file){
106     UNUSED(file);
107     return -1;
108 }
109 
110 // end of bss, start of heap
111 extern int _end;
112 void * _sbrk(int incr){
113     static unsigned char *heap = NULL;
114     unsigned char *prev_heap;
115 
116     if (heap == NULL) {
117         heap = (unsigned char *)&_end;
118     }
119     prev_heap = heap;
120     heap += incr;
121     return prev_heap;
122 }
123 
124 void abort(void){
125     btstack_assert(false);
126     while (1);
127 }
128 
129 #ifdef ENABLE_SEGGER_RTT
130 
131 #include "SEGGER_RTT.h"
132 
133 int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList);
134 
135 // gcc/clang map printf to puts or putchar for printf("...\n"), or printf("%c", c) respectively
136 
137 int puts(const char * s){
138     SEGGER_RTT_WriteString(0, s);
139     SEGGER_RTT_PutChar(0, '\n');
140 }
141 
142 int putchar(int c){
143     SEGGER_RTT_PutChar(0, c);
144 }
145 
146 int printf(const char * format, ...){
147     va_list argptr;
148     va_start(argptr, format);
149     SEGGER_RTT_vprintf(0, format, &argptr);
150     va_end(argptr);
151 }
152 
153 int vprintf(const char * format,  va_list argptr){
154     SEGGER_RTT_vprintf(0, format, &argptr);
155 }
156 #endif
157 
158 
159 // HAL CPU
160 #include "hal_cpu.h"
161 
162 void hal_cpu_disable_irqs(void){
163     __disable_irq();
164 }
165 
166 void hal_cpu_enable_irqs(void){
167     __enable_irq();
168 }
169 
170 void hal_cpu_enable_irqs_and_sleep(void){
171     __enable_irq();
172     __asm__("wfe"); // go to sleep if event flag isn't set. if set, just clear it. IRQs set event flag
173 }
174 
175 // HAL LED
176 #include "hal_led.h"
177 void hal_led_toggle(void){
178     static bool on = false;
179     if (on){
180         on = false;
181         GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
182    } else {
183         on = true;
184         GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0);
185     }
186 }
187 
188 // HAL UART DMA
189 #include "hal_uart_dma.h"
190 
191 // DMA Control Table
192 // 8 channels are implemented => 16 channel control data structures (a 16 bytes) are needed
193 // GCC
194 __attribute__ ((aligned (256)))
195 static DMA_ControlTable MSP_EXP432P401RLP_DMAControlTable[16];
196 
197 // RX Ping Pong Buffer - similar to circular buffer on other MCUs
198 #define HAL_DMA_RX_BUFFER_SIZE 64
199 static uint8_t hal_dma_rx_ping_pong_buffer[2 * HAL_DMA_RX_BUFFER_SIZE];
200 
201 // active buffer and position to read from
202 static uint8_t  hal_dma_rx_active_buffer = 0;
203 static uint16_t hal_dma_rx_offset;
204 
205 // rx state
206 static uint16_t  bytes_to_read = 0;
207 static uint8_t * rx_buffer_ptr = 0;
208 
209 // tx state
210 static uint16_t  bytes_to_write = 0;
211 static uint8_t * tx_buffer_ptr = 0;
212 
213 // handlers
214 static void (*rx_done_handler)(void);
215 static void (*tx_done_handler)(void);
216 
217 // #define BLUETOOTH_DEBUG_PORT     GPIO_PORT_P5
218 // #define BLUETOOTH_DEBUG_PIN      GPIO_PIN0
219 
220 #define BLUETOOTH_TX_PORT        GPIO_PORT_P3
221 #define BLUETOOTH_TX_PIN         GPIO_PIN2
222 #define BLUETOOTH_RX_PORT        GPIO_PORT_P3
223 #define BLUETOOTH_RX_PIN         GPIO_PIN3
224 
225 #if 0
226 // BOOST-CC2564MODA (CC2564B BoosterPack)
227 #define BLUETOOTH_RTS_PORT       GPIO_PORT_P6
228 #define BLUETOOTH_RTS_PIN        GPIO_PIN6
229 #define BLUETOOTH_CTS_PORT       GPIO_PORT_P5
230 #define BLUETOOTH_CTS_PIN        GPIO_PIN6
231 #define BLUETOOTH_nSHUTDOWN_PORT GPIO_PORT_P2
232 #define BLUETOOTH_nSHUTDOWN_PIN  GPIO_PIN5
233 #else
234 // EM Wireless BoosterPack with CC256x module
235 #define BLUETOOTH_RTS_PORT       GPIO_PORT_P3
236 #define BLUETOOTH_RTS_PIN        GPIO_PIN6
237 #define BLUETOOTH_CTS_PORT       GPIO_PORT_P5
238 #define BLUETOOTH_CTS_PIN        GPIO_PIN2
239 #define BLUETOOTH_nSHUTDOWN_PORT GPIO_PORT_P6
240 #define BLUETOOTH_nSHUTDOWN_PIN  GPIO_PIN4
241 #endif
242 
243 /* UART Configuration Parameter. These are the configuration parameters to
244  * make the eUSCI A UART module to operate with a 115200 baud rate. These
245  * values were calculated using the online calculator that TI provides
246  * at:
247  * http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430BaudRateConverter/index.html
248  */
249 static eUSCI_UART_ConfigV1 uartConfig =
250 {
251         EUSCI_A_UART_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
252         0 ,                                      // BRDIV  (template)
253         0,                                       // UCxBRF (template)
254         0 ,                                      // UCxBRS (template)
255         EUSCI_A_UART_NO_PARITY,                  // No Parity
256         EUSCI_A_UART_LSB_FIRST,                  // MSB First
257         EUSCI_A_UART_ONE_STOP_BIT,               // One stop bit
258         EUSCI_A_UART_MODE,                       // UART mode: normal
259         0,                                       // Oversampling (template)
260         EUSCI_A_UART_8_BIT_LEN,                  // 8 bit
261 };
262 
263 // table
264 static struct baudrate_config {
265     uint32_t baudrate;
266     uint8_t  clock_prescalar;
267     uint8_t  first_mod_reg;
268     uint8_t  second_mod_reg;
269     uint8_t  oversampling;
270 } baudrate_configs[] = {
271     // Config for 48 Mhz
272     {   57600, 52,  1,   37, 1},
273     {  115200, 26,  1,  111, 1},
274     {  230400, 13,  0,   37, 1},
275     {  460800,  6,  8,   32, 1},
276     {  921600,  3,  4,    2, 1},
277     { 1000000,  3,  0,    0, 1},
278     { 2000000,  1,  8,    0, 1},
279     { 3000000,  1,  0,    0, 1},
280     { 4000000, 12,  0,    0, 0},
281 };
282 
283 #ifdef TEST_LOOPBACK
284 static uint8_t test_tx[16];
285 static uint8_t test_rx[16];
286 static uint8_t test_rx_flag;
287 static void test_tx_complete(void){
288 }
289 static void test_rx_complete(void){
290     test_rx_flag = 1;
291 }
292 #endif
293 
294 // return true if ok
295 static bool hal_uart_dma_config(uint32_t baud){
296     int index = -1;
297     int i;
298     for (i=0;i<sizeof(baudrate_configs)/sizeof(struct baudrate_config);i++){
299         if (baudrate_configs[i].baudrate == baud){
300             index = i;
301             break;
302         }
303     }
304     if (index < 0) return false;
305 
306     uartConfig.clockPrescalar = baudrate_configs[index].clock_prescalar;
307     uartConfig.firstModReg    = baudrate_configs[index].first_mod_reg;
308     uartConfig.secondModReg   = baudrate_configs[index].second_mod_reg;
309     uartConfig.overSampling   = baudrate_configs[index].oversampling ? EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION : EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION;
310     return true;
311 }
312 
313 static void hal_dma_rx_start_transfer(uint8_t buffer){
314     uint32_t channel = DMA_CH5_EUSCIA2RX | (buffer == 0 ? UDMA_PRI_SELECT : UDMA_ALT_SELECT);
315     MAP_DMA_setChannelTransfer(channel, UDMA_MODE_PINGPONG, (void *) UART_getReceiveBufferAddressForDMA(EUSCI_A2_BASE),
316        (uint8_t *) &hal_dma_rx_ping_pong_buffer[buffer * HAL_DMA_RX_BUFFER_SIZE], HAL_DMA_RX_BUFFER_SIZE);
317 }
318 
319 static uint16_t hal_dma_rx_bytes_avail(uint8_t buffer, uint16_t offset){
320     uint32_t channel = DMA_CH5_EUSCIA2RX | (buffer == 0 ? UDMA_PRI_SELECT : UDMA_ALT_SELECT);
321     return HAL_DMA_RX_BUFFER_SIZE - MAP_DMA_getChannelSize(channel) - offset;
322 }
323 
324 static void hal_uart_dma_update_rts(void){
325     // get active transfer
326     uint32_t attribute = MAP_DMA_getChannelAttribute(DMA_CH5_EUSCIA2RX & 0x0F);
327     uint8_t  active_transfer_buffer = (attribute & UDMA_ATTR_ALTSELECT) ? 1 : 0;
328     if (hal_dma_rx_active_buffer == active_transfer_buffer){
329         GPIO_setOutputLowOnPin(BLUETOOTH_CTS_PORT, BLUETOOTH_CTS_PIN);
330     } else {
331         GPIO_setOutputHighOnPin(BLUETOOTH_CTS_PORT, BLUETOOTH_CTS_PIN);
332     }
333 }
334 
335 // directly called from timer or similar interrupt. to call from non-isr context, interrupts must be disabled
336 static void hal_uart_dma_harvest(void){
337     if (bytes_to_read == 0) {
338         return;
339     }
340 
341     uint16_t bytes_avail = hal_dma_rx_bytes_avail(hal_dma_rx_active_buffer, hal_dma_rx_offset);
342     if (bytes_avail == 0) {
343         return;
344     }
345 
346     // fetch bytes from current buffer
347     uint16_t bytes_to_copy = btstack_min(bytes_avail, bytes_to_read);
348     memcpy(rx_buffer_ptr, &hal_dma_rx_ping_pong_buffer[hal_dma_rx_active_buffer * HAL_DMA_RX_BUFFER_SIZE + hal_dma_rx_offset], bytes_to_copy);
349     rx_buffer_ptr     += bytes_to_copy;
350     hal_dma_rx_offset += bytes_to_copy;
351     bytes_to_read     -= bytes_to_copy;
352 
353     // if current buffer fully processed, restart DMA transfer and switch to next buffer
354     if (hal_dma_rx_offset == HAL_DMA_RX_BUFFER_SIZE){
355         hal_dma_rx_offset = 0;
356         hal_dma_rx_start_transfer(hal_dma_rx_active_buffer);
357         hal_dma_rx_active_buffer = 1 - hal_dma_rx_active_buffer;
358         hal_uart_dma_update_rts();
359     }
360 
361     if (bytes_to_read == 0){
362         (*rx_done_handler)();
363     }
364 }
365 
366 void DMA_INT1_IRQHandler(void){
367     MAP_DMA_clearInterruptFlag(DMA_CH4_EUSCIA2TX & 0x0F);
368     MAP_DMA_disableChannel(DMA_CH4_EUSCIA2TX & 0x0F);
369     (*tx_done_handler)();
370 }
371 
372 void DMA_INT2_IRQHandler(void){
373     MAP_DMA_clearInterruptFlag(DMA_CH5_EUSCIA2RX & 0x0F);
374     // update RTS
375     hal_uart_dma_update_rts();
376     // process data
377 #ifdef BLUETOOTH_DEBUG_PORT
378     MAP_GPIO_setOutputHighOnPin(BLUETOOTH_DEBUG_PIN, BLUETOOTH_DEBUG_PORT);
379 #endif
380     hal_uart_dma_harvest();
381 #ifdef BLUETOOTH_DEBUG_PORT
382     MAP_GPIO_setOutputLowOnPin(BLUETOOTH_DEBUG_PIN, BLUETOOTH_DEBUG_PORT);
383 #endif
384 }
385 
386 
387 void hal_uart_dma_init(void){
388     // nShutdown
389     MAP_GPIO_setAsOutputPin(BLUETOOTH_nSHUTDOWN_PORT, BLUETOOTH_nSHUTDOWN_PIN);
390     // BT-CTS
391     MAP_GPIO_setAsOutputPin(BLUETOOTH_CTS_PORT, BLUETOOTH_CTS_PIN);
392     GPIO_setOutputHighOnPin(BLUETOOTH_CTS_PORT, BLUETOOTH_CTS_PIN);
393     // BT-RTS
394     MAP_GPIO_setAsInputPinWithPullDownResistor(BLUETOOTH_RTS_PORT, BLUETOOTH_RTS_PIN);
395     // UART pins
396     MAP_GPIO_setAsPeripheralModuleFunctionInputPin(BLUETOOTH_TX_PORT, BLUETOOTH_TX_PIN, GPIO_PRIMARY_MODULE_FUNCTION);
397     MAP_GPIO_setAsPeripheralModuleFunctionInputPin(BLUETOOTH_RX_PORT, BLUETOOTH_RX_PIN, GPIO_PRIMARY_MODULE_FUNCTION);
398 
399 #ifdef BLUETOOTH_DEBUG_PORT
400     // debug pin
401     MAP_GPIO_setAsOutputPin(BLUETOOTH_DEBUG_PIN, BLUETOOTH_DEBUG_PORT);
402     MAP_GPIO_setOutputLowOnPin(BLUETOOTH_DEBUG_PIN, BLUETOOTH_DEBUG_PORT);
403 #endif
404 
405     // UART
406 
407     /* Configuring and enable UART Module */
408     hal_uart_dma_config(115200);
409     MAP_UART_initModule(EUSCI_A2_BASE, &uartConfig);
410     MAP_UART_enableModule(EUSCI_A2_BASE);
411 
412     // DMA
413 
414     /* Configuring DMA module */
415     MAP_DMA_enableModule();
416     MAP_DMA_setControlBase(MSP_EXP432P401RLP_DMAControlTable);
417 
418     /* Assign DMA channel 4 to EUSCI_A2_TX, channel 5 to EUSCI_A2_RX */
419     MAP_DMA_assignChannel(DMA_CH4_EUSCIA2TX);
420     MAP_DMA_assignChannel(DMA_CH5_EUSCIA2RX);
421 
422     /* Setup the RX and TX transfer characteristics */
423     MAP_DMA_setChannelControl(DMA_CH4_EUSCIA2TX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
424     MAP_DMA_setChannelControl(DMA_CH5_EUSCIA2RX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
425     MAP_DMA_setChannelControl(DMA_CH5_EUSCIA2RX | UDMA_ALT_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
426 
427     /* Enable DMA interrupt for both channels */
428     MAP_DMA_assignInterrupt(INT_DMA_INT1, DMA_CH4_EUSCIA2TX & 0x0f);
429     MAP_DMA_assignInterrupt(INT_DMA_INT2, DMA_CH5_EUSCIA2RX & 0x0f);
430 
431     /* Clear interrupt flags */
432     MAP_DMA_clearInterruptFlag(DMA_CH4_EUSCIA2TX & 0x0F);
433     MAP_DMA_clearInterruptFlag(DMA_CH5_EUSCIA2RX & 0x0F);
434 
435     /* Enable Interrupts */
436     MAP_Interrupt_enableInterrupt(INT_DMA_INT1);
437     MAP_Interrupt_enableInterrupt(INT_DMA_INT2);
438     MAP_DMA_enableInterrupt(INT_DMA_INT1);
439     MAP_DMA_enableInterrupt(INT_DMA_INT2);
440 
441     // power cycle
442     MAP_GPIO_setOutputLowOnPin(BLUETOOTH_nSHUTDOWN_PORT, BLUETOOTH_nSHUTDOWN_PIN);
443     delay_ms(10);
444     MAP_GPIO_setOutputHighOnPin(BLUETOOTH_nSHUTDOWN_PORT, BLUETOOTH_nSHUTDOWN_PIN);
445     delay_ms(200);
446 
447     // setup ping pong rx
448     hal_dma_rx_start_transfer(0);
449     hal_dma_rx_start_transfer(1);
450 
451     hal_dma_rx_active_buffer = 0;
452     hal_dma_rx_offset = 0;
453 
454     MAP_DMA_enableChannel(DMA_CH5_EUSCIA2RX & 0x0F);
455 
456     // ready
457     GPIO_setOutputLowOnPin(BLUETOOTH_CTS_PORT, BLUETOOTH_CTS_PIN);
458 
459 #ifdef TEST_LOOPBACK
460     // test code
461     rx_done_handler = &test_rx_complete;
462     tx_done_handler = &test_tx_complete;
463     uint8_t value = 0;
464     uint8_t block_size = 6;
465     while(true){
466         // prepare data
467         uint8_t pos;
468         for (pos=0;pos<block_size;pos++){
469             test_tx[pos] = value++;
470         }
471         // trigger receive
472         hal_uart_dma_receive_block(test_rx, block_size);
473         // trigger send
474         printf_hexdump(test_tx, block_size);
475         hal_uart_dma_send_block(test_tx, block_size);
476         while (test_rx_flag == 0){
477             hal_cpu_disable_irqs();
478             hal_uart_dma_harvest();
479             hal_cpu_enable_irqs();
480         };
481         test_rx_flag = 0;
482         printf_hexdump(test_rx, block_size);
483         printf("\n");
484         if (memcmp(test_rx, test_tx, block_size) != 0) break;
485     }
486     while (1);
487 #endif
488 }
489 
490 int  hal_uart_dma_set_baud(uint32_t baud){
491     hal_uart_dma_config(baud);
492     MAP_UART_disableModule(EUSCI_A2_BASE);
493     /* BaudRate Control Register */
494     uint32_t moduleInstance = EUSCI_A2_BASE;
495     const eUSCI_UART_ConfigV1 *config = &uartConfig;
496     EUSCI_A_CMSIS(moduleInstance)->BRW = config->clockPrescalar;
497     EUSCI_A_CMSIS(moduleInstance)->MCTLW = ((config->secondModReg << 8) + (config->firstModReg << 4) + config->overSampling);
498     MAP_UART_enableModule(EUSCI_A2_BASE);
499     return 0;
500 }
501 
502 void hal_uart_dma_set_sleep(uint8_t sleep){
503     UNUSED(sleep);
504 }
505 
506 void hal_uart_dma_set_csr_irq_handler( void (*the_irq_handler)(void)){
507     UNUSED(the_irq_handler);
508 }
509 
510 void hal_uart_dma_set_block_received( void (*the_block_handler)(void)){
511     rx_done_handler = the_block_handler;
512 }
513 
514 void hal_uart_dma_set_block_sent( void (*the_block_handler)(void)){
515     tx_done_handler = the_block_handler;
516 }
517 
518 void hal_uart_dma_send_block(const uint8_t * data, uint16_t len){
519     MAP_DMA_setChannelTransfer(DMA_CH4_EUSCIA2TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (uint8_t *) data,
520                                (void *) MAP_UART_getTransmitBufferAddressForDMA(EUSCI_A2_BASE),
521                                len);
522     MAP_DMA_enableChannel(DMA_CH4_EUSCIA2TX & 0x0F);
523 }
524 
525 // int used to indicate a request for more new data
526 void hal_uart_dma_receive_block(uint8_t *buffer, uint16_t len){
527     rx_buffer_ptr = buffer;
528     bytes_to_read = len;
529     hal_cpu_disable_irqs();
530     hal_uart_dma_harvest();
531     hal_cpu_enable_irqs();
532 }
533 
534 // HAL TIME MS Implementation
535 #include "hal_time_ms.h"
536 static volatile uint32_t systick;
537 
538 void SysTick_Handler(void){
539     systick++;
540     // process received data
541 #ifdef BLUETOOTH_DEBUG_PORT
542     MAP_GPIO_setOutputHighOnPin(BLUETOOTH_DEBUG_PIN, BLUETOOTH_DEBUG_PORT);
543 #endif
544     hal_uart_dma_harvest();
545 #ifdef BLUETOOTH_DEBUG_PORT
546     MAP_GPIO_setOutputLowOnPin(BLUETOOTH_DEBUG_PIN, BLUETOOTH_DEBUG_PORT);
547 #endif
548 }
549 
550 
551 static void init_systick(void){
552     // Configuring SysTick to trigger every ms (48 Mhz / 48000 = 1 ms)
553     MAP_SysTick_enableModule();
554     MAP_SysTick_setPeriod(48000);
555     // MAP_Interrupt_enableSleepOnIsrExit();
556     MAP_SysTick_enableInterrupt();
557 }
558 
559 static void delay_ms(uint32_t ms){
560     uint32_t delay_until = systick + ms;
561     // assumes mcu runs fast enough to check once every ms
562     while (systick != delay_until);
563 }
564 
565 uint32_t hal_time_ms(void){
566     return systick;
567 }
568 
569 // btstack assert
570 void btstack_assert_failed(const char * file, uint16_t line_nr){
571     printf("ASSERT failed in %s, line %u\n", file, line_nr);
572     while (1);
573 }
574 
575 // main.c
576 #include "SEGGER_RTT.h"
577 
578 // HAL FLASH MSP432 Configuration - use two last 4kB sectors
579 #define HAL_FLASH_BANK_SIZE      4096
580 #define HAL_FLASH_BANK_0_SECTOR  FLASH_SECTOR30
581 #define HAL_FLASH_BANK_1_SECTOR  FLASH_SECTOR31
582 #define HAL_FLASH_BANK_0_ADDR    0x3E000
583 #define HAL_FLASH_BANK_1_ADDR    0x3F000
584 
585 int btstack_main(const int argc, const char * argvp[]);
586 
587 static btstack_packet_callback_registration_t hci_event_callback_registration;
588 
589 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
590     UNUSED(size);
591     UNUSED(channel);
592     bd_addr_t local_addr;
593     if (packet_type != HCI_EVENT_PACKET) return;
594     switch(hci_event_packet_get_type(packet)){
595         case BTSTACK_EVENT_STATE:
596             if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return;
597             gap_local_bd_addr(local_addr);
598             printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr));
599             break;
600         case HCI_EVENT_COMMAND_COMPLETE:
601             if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_version_information)){
602                 uint16_t manufacturer   = little_endian_read_16(packet, 10);
603                 uint16_t lmp_subversion = little_endian_read_16(packet, 12);
604                 // assert manufacturer is TI
605                 if (manufacturer != BLUETOOTH_COMPANY_ID_TEXAS_INSTRUMENTS_INC){
606                     printf("ERROR: Expected Bluetooth Chipset from TI but got manufacturer 0x%04x\n", manufacturer);
607                     break;
608                 }
609                 // assert correct init script is used based on expected lmp_subversion
610                 if (lmp_subversion != btstack_chipset_cc256x_lmp_subversion()){
611                     printf("Error: LMP Subversion does not match initscript!\n");
612                     printf("Your initscripts is for %s chipset\n", btstack_chipset_cc256x_lmp_subversion() < lmp_subversion ? "an older" : "a newer");
613                     printf("Please update Makefile to include the appropriate bluetooth_init_cc256???.c file\n");
614                     btstack_assert(false);
615                     break;
616                 }
617             }
618             break;
619         default:
620             break;
621     }
622 }
623 
624 int main(void)
625 {
626     /* Halting the Watchdog */
627     MAP_WDT_A_holdTimer();
628 
629     init_systick();
630 
631     // init led
632     MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
633     hal_led_toggle();
634 
635     // start with BTstack init - especially configure HCI Transport
636     btstack_memory_init();
637     btstack_run_loop_init(btstack_run_loop_embedded_get_instance());
638 
639     // uncomment to enable packet logger
640 #ifdef ENABLE_SEGGER_RTT
641     // hci_dump_init(hci_dump_segger_rtt_stdout_get_instance());
642 #else
643     // hci_dump_init(hci_dump_embedded_stdout_get_instance());
644 #endif
645 
646     // init HCI
647     hci_init(hci_transport_h4_instance(btstack_uart_block_embedded_instance()), (void*) &config);
648     hci_set_chipset(btstack_chipset_cc256x_instance());
649 
650     // setup TLV Flash Sector implementation
651     const hal_flash_bank_t * hal_flash_bank_impl = hal_flash_bank_msp432_init_instance(
652             &hal_flash_bank_context,
653             HAL_FLASH_BANK_SIZE,
654             HAL_FLASH_BANK_0_SECTOR,
655             HAL_FLASH_BANK_1_SECTOR,
656             HAL_FLASH_BANK_0_ADDR,
657             HAL_FLASH_BANK_1_ADDR);
658 
659     const btstack_tlv_t * btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(
660             &btstack_tlv_flash_bank_context,
661             hal_flash_bank_impl,
662             &hal_flash_bank_context);
663 
664     // setup global tlv
665     btstack_tlv_set_instance(btstack_tlv_impl, &btstack_tlv_flash_bank_context);
666 
667     // setup Link Key DB using TLV
668     const btstack_link_key_db_t * btstack_link_key_db = btstack_link_key_db_tlv_get_instance(btstack_tlv_impl, &btstack_tlv_flash_bank_context);
669     hci_set_link_key_db(btstack_link_key_db);
670 
671     // setup LE Device DB using TLV
672     le_device_db_tlv_configure(btstack_tlv_impl, &btstack_tlv_flash_bank_context);
673 
674     // inform about BTstack state
675     hci_event_callback_registration.callback = &packet_handler;
676     hci_add_event_handler(&hci_event_callback_registration);
677 
678     // hand over to btstack embedded code
679     btstack_main(0, NULL);
680 
681     // go
682     btstack_run_loop_execute();
683 }
684 
685 
686