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