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