1 /******************************************************************************* 2 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. 3 * Author: Ismail H. Kose <[email protected]> 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included 13 * in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 19 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21 * OTHER DEALINGS IN THE SOFTWARE. 22 * 23 * Except as contained in this notice, the name of Maxim Integrated 24 * Products, Inc. shall not be used except as stated in the Maxim Integrated 25 * Products, Inc. Branding Policy. 26 * 27 * The mere transfer of this software does not imply any licenses 28 * of trade secrets, proprietary technology, copyrights, patents, 29 * trademarks, maskwork rights, or any other form of intellectual 30 * property whatsoever. Maxim Integrated Products, Inc. retains all 31 * ownership rights. 32 ******************************************************************************* 33 */ 34 35 #include <stdio.h> 36 #include <string.h> 37 38 // MXC 39 #include "lp.h" 40 #include "uart.h" 41 #include "board.h" 42 #include "led.h" 43 44 // BTstack Core 45 #include "btstack_debug.h" 46 #include "btstack.h" 47 #include "btstack_config.h" 48 #include "btstack_run_loop_embedded.h" 49 #include "btstack_chipset_cc256x.h" 50 #include "hci_dump_embedded_stdout.h" 51 52 // BTstack HALs 53 #include "hal_tick.h" 54 #include "hal_stdin.h" 55 56 #include "btstack_port.h" 57 58 #define CC256X_UART_ID 0 59 #define UART_RXFIFO_USABLE (MXC_UART_FIFO_DEPTH-3) 60 61 static uint32_t baud_rate; 62 63 // rx state 64 static int bytes_to_read = 0; 65 static uint8_t * rx_buffer_ptr = 0; 66 67 // tx state 68 static int bytes_to_write = 0; 69 static uint8_t * tx_buffer_ptr = 0; 70 71 const gpio_cfg_t PAN1326_SLOW_CLK = { PORT_1, PIN_7, GPIO_FUNC_GPIO, 72 GPIO_PAD_NORMAL }; 73 const gpio_cfg_t PAN1326_nSHUTD = { PORT_1, PIN_6, GPIO_FUNC_GPIO, 74 GPIO_PAD_NORMAL }; 75 const gpio_cfg_t PAN1326_HCIRTS = { PORT_0, PIN_3, GPIO_FUNC_GPIO, 76 GPIO_PAD_INPUT_PULLUP }; 77 const gpio_cfg_t PAN1326_HCICTS = { PORT_0, PIN_2, GPIO_FUNC_GPIO, 78 GPIO_PAD_NORMAL }; 79 80 static void dummy_handler(void) {}; 81 static void (*rx_done_handler)(void) = dummy_handler; 82 static void (*tx_done_handler)(void) = dummy_handler; 83 84 85 86 void hal_cpu_disable_irqs(void) 87 { 88 __disable_irq(); 89 } 90 91 void hal_cpu_enable_irqs(void) 92 { 93 __enable_irq(); 94 } 95 void hal_cpu_enable_irqs_and_sleep(void) 96 { 97 __enable_irq(); 98 /* TODO: Add sleep mode */ 99 } 100 101 void hal_uart_dma_send_block(const uint8_t *buffer, uint16_t len) 102 { 103 tx_buffer_ptr = (uint8_t *)buffer; 104 bytes_to_write = len; 105 } 106 107 void hal_uart_dma_receive_block(uint8_t *buffer, uint16_t len) 108 { 109 rx_buffer_ptr = buffer; 110 bytes_to_read = len; 111 } 112 113 void hal_btstack_run_loop_execute_once(void) 114 { 115 int rx_avail; 116 int num_rx_bytes; 117 int tx_avail; 118 int rx_bytes; 119 int tx_bytes; 120 int ret; 121 122 while (bytes_to_read) { 123 rx_avail = UART_NumReadAvail(MXC_UART_GET_UART(CC256X_UART_ID)); 124 if (!rx_avail) 125 break; 126 127 if (bytes_to_read > rx_avail) 128 num_rx_bytes = rx_avail; 129 else 130 num_rx_bytes = bytes_to_read; 131 132 ret = UART_Read(MXC_UART_GET_UART(CC256X_UART_ID), rx_buffer_ptr, num_rx_bytes, &rx_bytes); 133 if (ret < 0) 134 break; 135 136 rx_buffer_ptr += rx_bytes; 137 bytes_to_read -= rx_bytes; 138 139 if (bytes_to_read < 0) { 140 bytes_to_read = 0; 141 } 142 143 if (bytes_to_read == 0){ 144 (*rx_done_handler)(); 145 } 146 } 147 148 while (bytes_to_write) { 149 tx_avail = UART_NumWriteAvail(MXC_UART_GET_UART(CC256X_UART_ID)); 150 if (!tx_avail) 151 break; 152 153 if (bytes_to_write > tx_avail) 154 tx_bytes = tx_avail; 155 else 156 tx_bytes = bytes_to_write; 157 158 ret = UART_Write(MXC_UART_GET_UART(CC256X_UART_ID), tx_buffer_ptr, tx_bytes); 159 if (ret < 0) 160 break; 161 bytes_to_write -= tx_bytes; 162 tx_buffer_ptr += tx_bytes; 163 if (bytes_to_write < 0) { 164 bytes_to_write = 0; 165 } 166 167 if (bytes_to_write == 0){ 168 (*tx_done_handler)(); 169 } 170 } 171 172 btstack_run_loop_embedded_execute_once(); 173 } 174 175 void hal_uart_init(void) 176 { 177 int error = 0; 178 uart_cfg_t cfg; 179 180 cfg.parity = UART_PARITY_DISABLE; 181 cfg.size = UART_DATA_SIZE_8_BITS; 182 cfg.extra_stop = 0; 183 cfg.cts = 1; 184 cfg.rts = 1; 185 186 cfg.baud = baud_rate; 187 188 sys_cfg_uart_t sys_cfg; 189 sys_cfg.clk_scale = CLKMAN_SCALE_AUTO; 190 191 sys_cfg.io_cfg = (ioman_cfg_t )IOMAN_UART(0, 192 IOMAN_MAP_B, // io_map 193 IOMAN_MAP_B, // cts_map 194 IOMAN_MAP_B, // rts_map 195 1, // io_en 196 1, // cts_en 197 1); //rts_en 198 199 if ((error = UART_Init(MXC_UART_GET_UART(CC256X_UART_ID), &cfg, &sys_cfg)) != E_NO_ERROR) { 200 printf("Error initializing UART %d\n", error); 201 while (1); 202 } else { 203 printf("BTSTACK UART Initialized\n"); 204 } 205 206 MXC_UART_GET_UART(CC256X_UART_ID)->ctrl |= MXC_F_UART_CTRL_CTS_POLARITY | MXC_F_UART_CTRL_RTS_POLARITY; 207 MXC_UART_GET_UART(CC256X_UART_ID)->ctrl &= ~((MXC_UART_FIFO_DEPTH - 4) << (MXC_F_UART_CTRL_RTS_LEVEL_POS)); 208 MXC_UART_GET_UART(CC256X_UART_ID)->ctrl |= ((UART_RXFIFO_USABLE) << MXC_F_UART_CTRL_RTS_LEVEL_POS); 209 } 210 211 int hal_uart_dma_set_baud(uint32_t baud){ 212 baud_rate = baud; 213 printf("BAUD RATE IS = %d \n", baud); 214 hal_uart_init(); 215 return baud_rate; 216 } 217 218 void hal_uart_dma_init(void){ 219 bytes_to_write = 0; 220 bytes_to_read = 0; 221 hal_uart_dma_set_baud(115200); 222 } 223 224 void hal_uart_dma_set_block_received( void (*block_handler)(void)){ 225 rx_done_handler = block_handler; 226 } 227 228 void hal_uart_dma_set_block_sent( void (*block_handler)(void)){ 229 230 tx_done_handler = block_handler; 231 } 232 233 void hal_uart_dma_set_csr_irq_handler( void (*csr_irq_handler)(void)){ 234 235 } 236 237 void hal_uart_dma_set_sleep(uint8_t sleep){ 238 239 } 240 241 void init_slow_clock(void) 242 { 243 MXC_PWRSEQ->reg0 &= ~(MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN | MXC_F_PWRSEQ_REG0_PWR_RTCEN_SLP); 244 MXC_PWRSEQ->reg4 &= ~MXC_F_PWRSEQ_REG4_PWR_PSEQ_32K_EN; 245 MXC_PWRSEQ->reg0 |= MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN | MXC_F_PWRSEQ_REG0_PWR_RTCEN_SLP; // Enable RTC 246 hal_delay_us(1); 247 MXC_PWRSEQ->reg4 |= MXC_F_PWRSEQ_REG4_PWR_PSEQ_32K_EN; // Enable the RTC out of P1.7 248 } 249 250 int bt_comm_init() { 251 int error = 0; 252 int cnt = 0; 253 254 hal_tick_init(); 255 hal_delay_us(1); 256 257 /* HCI module RTS as input with 25k pullup */ 258 if ((error = GPIO_Config(&PAN1326_HCIRTS)) != E_NO_ERROR) { 259 printf("Error setting PAN1326_HCIRTS %d\n", error); 260 } 261 GPIO_OutSet(&PAN1326_HCIRTS); 262 263 init_slow_clock(); 264 /* 265 * when enabling the P1.7 RTC output, P1.6 will be hardcoded to an input with 25k pullup enabled. 266 * There is an internal pullup, so when it is set as an input, it will float high. 267 * The PAN1326B data sheet says the NSHUTD pin is pulled down, but the input impedance is stated at 1Meg Ohm, 268 * The so the 25k pullup should be enough to reach the minimum 1.42V to enable the device. 269 * */ 270 271 /* Force PAN1326 shutdown to be output and take it out of reset */ 272 if ((error = GPIO_Config(&PAN1326_nSHUTD)) != E_NO_ERROR) { 273 printf("Error setting PAN1326_nSHUTD %d\n", error); 274 } 275 GPIO_OutSet(&PAN1326_nSHUTD); 276 277 /*Check the module is ready to receive data */ 278 while (GPIO_InGet(&PAN1326_HCIRTS)) { 279 cnt++; 280 } 281 282 printf("%s CC256X init completed. cnt: %d \n", __func__, cnt); 283 return 0; 284 } 285 286 static hci_transport_config_uart_t config = { 287 HCI_TRANSPORT_CONFIG_UART, 288 115200, 289 4000000, 290 1, // flow control 291 "max32630fthr", 292 }; 293 294 // hal_led.h implementation 295 #include "hal_led.h" 296 void hal_led_off(void){ 297 LED_Off(LED_BLUE); 298 } 299 300 void hal_led_on(void){ 301 LED_On(LED_BLUE); 302 } 303 304 void hal_led_toggle(void){ 305 LED_Toggle(LED_BLUE); 306 } 307 308 // hal_stdin.h 309 static uint8_t stdin_buffer[1]; 310 static void (*stdin_handler)(char c); 311 312 static uart_req_t uart_byte_request; 313 314 static void uart_rx_handler(uart_req_t *request, int error) 315 { 316 if (stdin_handler){ 317 (*stdin_handler)(stdin_buffer[0]); 318 } 319 UART_ReadAsync(MXC_UART_GET_UART(CONSOLE_UART), &uart_byte_request); 320 } 321 322 void hal_stdin_setup(void (*handler)(char c)){ 323 // set handler 324 stdin_handler = handler; 325 326 /* set input handler */ 327 uart_byte_request.callback = uart_rx_handler; 328 uart_byte_request.data = stdin_buffer; 329 uart_byte_request.len = sizeof(uint8_t); 330 UART_ReadAsync(MXC_UART_GET_UART(CONSOLE_UART), &uart_byte_request); 331 } 332 333 #if 0 334 335 #include "btstack_stdin.h" 336 337 static btstack_data_source_t stdin_data_source; 338 static void (*stdin_handler)(char c); 339 340 static uart_req_t uart_byte_request; 341 static volatile int stdin_character_received; 342 static uint8_t stdin_buffer[1]; 343 344 static void stdin_rx_complete(void) { 345 stdin_character_received = 1; 346 } 347 348 static void uart_rx_handler(uart_req_t *request, int error) 349 { 350 stdin_rx_complete(); 351 } 352 353 static void stdin_process(struct btstack_data_source *ds, btstack_data_source_callback_type_t callback_type){ 354 if (!stdin_character_received) return; 355 if (stdin_handler){ 356 (*stdin_handler)(stdin_buffer[0]); 357 } 358 stdin_character_received = 0; 359 UART_ReadAsync(MXC_UART_GET_UART(CONSOLE_UART), &uart_byte_request); 360 } 361 362 static void btstack_stdin_handler(char c){ 363 stdin_character_received = 1; 364 btstack_run_loop_embedded_trigger(); 365 printf("Received: %c\n", c); 366 } 367 368 void btstack_stdin_setup(void (*handler)(char c)){ 369 // set handler 370 stdin_handler = handler; 371 372 // set up polling data_source 373 btstack_run_loop_set_data_source_handler(&stdin_data_source, &stdin_process); 374 btstack_run_loop_enable_data_source_callbacks(&stdin_data_source, DATA_SOURCE_CALLBACK_POLL); 375 btstack_run_loop_add_data_source(&stdin_data_source); 376 377 /* set input handler */ 378 uart_byte_request.callback = uart_rx_handler; 379 uart_byte_request.data = stdin_buffer; 380 uart_byte_request.len = sizeof(uint8_t); 381 UART_ReadAsync(MXC_UART_GET_UART(CONSOLE_UART), &uart_byte_request); 382 } 383 #endif 384 385 #include "hal_flash_bank_mxc.h" 386 #include "btstack_tlv.h" 387 #include "btstack_tlv_flash_bank.h" 388 #include "btstack_link_key_db_tlv.h" 389 #include "le_device_db_tlv.h" 390 391 #define HAL_FLASH_BANK_SIZE 0x2000 392 #define HAL_FLASH_BANK_0_ADDR 0x1FC000 393 #define HAL_FLASH_BANK_1_ADDR 0x1FE000 394 395 static hal_flash_bank_mxc_t hal_flash_bank_context; 396 static btstack_tlv_flash_bank_t btstack_tlv_flash_bank_context; 397 398 399 /******************************************************************************/ 400 int bluetooth_main(void) 401 { 402 LED_Off(LED_GREEN); 403 LED_On(LED_RED); 404 LED_Off(LED_BLUE); 405 406 bt_comm_init(); 407 /* BT Stack Initialization */ 408 btstack_memory_init(); 409 btstack_run_loop_init(btstack_run_loop_embedded_get_instance()); 410 411 // enable packet logger 412 // hci_dump_init(hci_dump_embedded_stdout_get_instance()); 413 414 /* Init HCI */ 415 const hci_transport_t * transport = hci_transport_h4_instance(btstack_uart_block_embedded_instance()); 416 hci_init(transport, &config); 417 hci_set_chipset(btstack_chipset_cc256x_instance()); 418 419 // setup TLV Flash Bank implementation 420 const hal_flash_bank_t * hal_flash_bank_impl = hal_flash_bank_mxc_init_instance( 421 &hal_flash_bank_context, 422 HAL_FLASH_BANK_SIZE, 423 HAL_FLASH_BANK_0_ADDR, 424 HAL_FLASH_BANK_1_ADDR); 425 const btstack_tlv_t * btstack_tlv_impl = btstack_tlv_flash_bank_init_instance( 426 &btstack_tlv_flash_bank_context, 427 hal_flash_bank_impl, 428 &hal_flash_bank_context); 429 430 // setup Link Key DB using TLV 431 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); 432 hci_set_link_key_db(btstack_link_key_db); 433 434 // setup LE Device DB using TLV 435 le_device_db_tlv_configure(btstack_tlv_impl, &btstack_tlv_flash_bank_context); 436 437 // go 438 btstack_main(0, (void *)NULL); 439 return 0; 440 } 441