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 #include "hci_transport.h" 52 #include "hci_transport_h4.h" 53 54 // BTstack HALs 55 #include "hal_tick.h" 56 #include "hal_stdin.h" 57 58 #include "btstack_port.h" 59 60 #define CC256X_UART_ID 0 61 #define UART_RXFIFO_USABLE (MXC_UART_FIFO_DEPTH-3) 62 63 static uint32_t baud_rate; 64 65 // rx state 66 static int bytes_to_read = 0; 67 static uint8_t * rx_buffer_ptr = 0; 68 69 // tx state 70 static int bytes_to_write = 0; 71 static uint8_t * tx_buffer_ptr = 0; 72 73 const gpio_cfg_t PAN1326_SLOW_CLK = { PORT_1, PIN_7, GPIO_FUNC_GPIO, 74 GPIO_PAD_NORMAL }; 75 const gpio_cfg_t PAN1326_nSHUTD = { PORT_1, PIN_6, GPIO_FUNC_GPIO, 76 GPIO_PAD_NORMAL }; 77 const gpio_cfg_t PAN1326_HCIRTS = { PORT_0, PIN_3, GPIO_FUNC_GPIO, 78 GPIO_PAD_INPUT_PULLUP }; 79 const gpio_cfg_t PAN1326_HCICTS = { PORT_0, PIN_2, GPIO_FUNC_GPIO, 80 GPIO_PAD_NORMAL }; 81 82 static void dummy_handler(void) {}; 83 static void (*rx_done_handler)(void) = dummy_handler; 84 static void (*tx_done_handler)(void) = dummy_handler; 85 86 87 88 void hal_cpu_disable_irqs(void) 89 { 90 __disable_irq(); 91 } 92 93 void hal_cpu_enable_irqs(void) 94 { 95 __enable_irq(); 96 } 97 void hal_cpu_enable_irqs_and_sleep(void) 98 { 99 __enable_irq(); 100 /* TODO: Add sleep mode */ 101 } 102 103 void hal_uart_dma_send_block(const uint8_t *buffer, uint16_t len) 104 { 105 tx_buffer_ptr = (uint8_t *)buffer; 106 bytes_to_write = len; 107 } 108 109 void hal_uart_dma_receive_block(uint8_t *buffer, uint16_t len) 110 { 111 rx_buffer_ptr = buffer; 112 bytes_to_read = len; 113 } 114 115 void hal_btstack_run_loop_execute_once(void) 116 { 117 int rx_avail; 118 int num_rx_bytes; 119 int tx_avail; 120 int rx_bytes; 121 int tx_bytes; 122 int ret; 123 124 while (bytes_to_read) { 125 rx_avail = UART_NumReadAvail(MXC_UART_GET_UART(CC256X_UART_ID)); 126 if (!rx_avail) 127 break; 128 129 if (bytes_to_read > rx_avail) 130 num_rx_bytes = rx_avail; 131 else 132 num_rx_bytes = bytes_to_read; 133 134 ret = UART_Read(MXC_UART_GET_UART(CC256X_UART_ID), rx_buffer_ptr, num_rx_bytes, &rx_bytes); 135 if (ret < 0) 136 break; 137 138 rx_buffer_ptr += rx_bytes; 139 bytes_to_read -= rx_bytes; 140 141 if (bytes_to_read < 0) { 142 bytes_to_read = 0; 143 } 144 145 if (bytes_to_read == 0){ 146 (*rx_done_handler)(); 147 } 148 } 149 150 while (bytes_to_write) { 151 tx_avail = UART_NumWriteAvail(MXC_UART_GET_UART(CC256X_UART_ID)); 152 if (!tx_avail) 153 break; 154 155 if (bytes_to_write > tx_avail) 156 tx_bytes = tx_avail; 157 else 158 tx_bytes = bytes_to_write; 159 160 ret = UART_Write(MXC_UART_GET_UART(CC256X_UART_ID), tx_buffer_ptr, tx_bytes); 161 if (ret < 0) 162 break; 163 bytes_to_write -= tx_bytes; 164 tx_buffer_ptr += tx_bytes; 165 if (bytes_to_write < 0) { 166 bytes_to_write = 0; 167 } 168 169 if (bytes_to_write == 0){ 170 (*tx_done_handler)(); 171 } 172 } 173 174 btstack_run_loop_embedded_execute_once(); 175 } 176 177 void hal_uart_init(void) 178 { 179 int error = 0; 180 uart_cfg_t cfg; 181 182 cfg.parity = UART_PARITY_DISABLE; 183 cfg.size = UART_DATA_SIZE_8_BITS; 184 cfg.extra_stop = 0; 185 cfg.cts = 1; 186 cfg.rts = 1; 187 188 cfg.baud = baud_rate; 189 190 sys_cfg_uart_t sys_cfg; 191 sys_cfg.clk_scale = CLKMAN_SCALE_AUTO; 192 193 sys_cfg.io_cfg = (ioman_cfg_t )IOMAN_UART(0, 194 IOMAN_MAP_B, // io_map 195 IOMAN_MAP_B, // cts_map 196 IOMAN_MAP_B, // rts_map 197 1, // io_en 198 1, // cts_en 199 1); //rts_en 200 201 if ((error = UART_Init(MXC_UART_GET_UART(CC256X_UART_ID), &cfg, &sys_cfg)) != E_NO_ERROR) { 202 printf("Error initializing UART %d\n", error); 203 while (1); 204 } else { 205 printf("BTSTACK UART Initialized\n"); 206 } 207 208 MXC_UART_GET_UART(CC256X_UART_ID)->ctrl |= MXC_F_UART_CTRL_CTS_POLARITY | MXC_F_UART_CTRL_RTS_POLARITY; 209 MXC_UART_GET_UART(CC256X_UART_ID)->ctrl &= ~((MXC_UART_FIFO_DEPTH - 4) << (MXC_F_UART_CTRL_RTS_LEVEL_POS)); 210 MXC_UART_GET_UART(CC256X_UART_ID)->ctrl |= ((UART_RXFIFO_USABLE) << MXC_F_UART_CTRL_RTS_LEVEL_POS); 211 } 212 213 int hal_uart_dma_set_baud(uint32_t baud){ 214 baud_rate = baud; 215 printf("BAUD RATE IS = %d \n", baud); 216 hal_uart_init(); 217 return baud_rate; 218 } 219 220 void hal_uart_dma_init(void){ 221 bytes_to_write = 0; 222 bytes_to_read = 0; 223 hal_uart_dma_set_baud(115200); 224 } 225 226 void hal_uart_dma_set_block_received( void (*block_handler)(void)){ 227 rx_done_handler = block_handler; 228 } 229 230 void hal_uart_dma_set_block_sent( void (*block_handler)(void)){ 231 232 tx_done_handler = block_handler; 233 } 234 235 void hal_uart_dma_set_csr_irq_handler( void (*csr_irq_handler)(void)){ 236 237 } 238 239 void hal_uart_dma_set_sleep(uint8_t sleep){ 240 241 } 242 243 void init_slow_clock(void) 244 { 245 MXC_PWRSEQ->reg0 &= ~(MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN | MXC_F_PWRSEQ_REG0_PWR_RTCEN_SLP); 246 MXC_PWRSEQ->reg4 &= ~MXC_F_PWRSEQ_REG4_PWR_PSEQ_32K_EN; 247 MXC_PWRSEQ->reg0 |= MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN | MXC_F_PWRSEQ_REG0_PWR_RTCEN_SLP; // Enable RTC 248 hal_delay_us(1); 249 MXC_PWRSEQ->reg4 |= MXC_F_PWRSEQ_REG4_PWR_PSEQ_32K_EN; // Enable the RTC out of P1.7 250 } 251 252 int bt_comm_init() { 253 int error = 0; 254 int cnt = 0; 255 256 hal_tick_init(); 257 hal_delay_us(1); 258 259 /* HCI module RTS as input with 25k pullup */ 260 if ((error = GPIO_Config(&PAN1326_HCIRTS)) != E_NO_ERROR) { 261 printf("Error setting PAN1326_HCIRTS %d\n", error); 262 } 263 GPIO_OutSet(&PAN1326_HCIRTS); 264 265 init_slow_clock(); 266 /* 267 * when enabling the P1.7 RTC output, P1.6 will be hardcoded to an input with 25k pullup enabled. 268 * There is an internal pullup, so when it is set as an input, it will float high. 269 * The PAN1326B data sheet says the NSHUTD pin is pulled down, but the input impedance is stated at 1Meg Ohm, 270 * The so the 25k pullup should be enough to reach the minimum 1.42V to enable the device. 271 * */ 272 273 /* Force PAN1326 shutdown to be output and take it out of reset */ 274 if ((error = GPIO_Config(&PAN1326_nSHUTD)) != E_NO_ERROR) { 275 printf("Error setting PAN1326_nSHUTD %d\n", error); 276 } 277 GPIO_OutSet(&PAN1326_nSHUTD); 278 279 /*Check the module is ready to receive data */ 280 while (GPIO_InGet(&PAN1326_HCIRTS)) { 281 cnt++; 282 } 283 284 printf("%s CC256X init completed. cnt: %d \n", __func__, cnt); 285 return 0; 286 } 287 288 static hci_transport_config_uart_t config = { 289 HCI_TRANSPORT_CONFIG_UART, 290 115200, 291 4000000, 292 1, // flow control 293 "max32630fthr", 294 }; 295 296 // hal_led.h implementation 297 #include "hal_led.h" 298 void hal_led_off(void){ 299 LED_Off(LED_BLUE); 300 } 301 302 void hal_led_on(void){ 303 LED_On(LED_BLUE); 304 } 305 306 void hal_led_toggle(void){ 307 LED_Toggle(LED_BLUE); 308 } 309 310 // hal_stdin.h 311 static uint8_t stdin_buffer[1]; 312 static void (*stdin_handler)(char c); 313 314 static uart_req_t uart_byte_request; 315 316 static void uart_rx_handler(uart_req_t *request, int error) 317 { 318 if (stdin_handler){ 319 (*stdin_handler)(stdin_buffer[0]); 320 } 321 UART_ReadAsync(MXC_UART_GET_UART(CONSOLE_UART), &uart_byte_request); 322 } 323 324 void hal_stdin_setup(void (*handler)(char c)){ 325 // set handler 326 stdin_handler = handler; 327 328 /* set input handler */ 329 uart_byte_request.callback = uart_rx_handler; 330 uart_byte_request.data = stdin_buffer; 331 uart_byte_request.len = sizeof(uint8_t); 332 UART_ReadAsync(MXC_UART_GET_UART(CONSOLE_UART), &uart_byte_request); 333 } 334 335 #if 0 336 337 #include "btstack_stdin.h" 338 339 static btstack_data_source_t stdin_data_source; 340 static void (*stdin_handler)(char c); 341 342 static uart_req_t uart_byte_request; 343 static volatile int stdin_character_received; 344 static uint8_t stdin_buffer[1]; 345 346 static void stdin_rx_complete(void) { 347 stdin_character_received = 1; 348 } 349 350 static void uart_rx_handler(uart_req_t *request, int error) 351 { 352 stdin_rx_complete(); 353 } 354 355 static void stdin_process(struct btstack_data_source *ds, btstack_data_source_callback_type_t callback_type){ 356 if (!stdin_character_received) return; 357 if (stdin_handler){ 358 (*stdin_handler)(stdin_buffer[0]); 359 } 360 stdin_character_received = 0; 361 UART_ReadAsync(MXC_UART_GET_UART(CONSOLE_UART), &uart_byte_request); 362 } 363 364 static void btstack_stdin_handler(char c){ 365 stdin_character_received = 1; 366 btstack_run_loop_embedded_trigger(); 367 printf("Received: %c\n", c); 368 } 369 370 void btstack_stdin_setup(void (*handler)(char c)){ 371 // set handler 372 stdin_handler = handler; 373 374 // set up polling data_source 375 btstack_run_loop_set_data_source_handler(&stdin_data_source, &stdin_process); 376 btstack_run_loop_enable_data_source_callbacks(&stdin_data_source, DATA_SOURCE_CALLBACK_POLL); 377 btstack_run_loop_add_data_source(&stdin_data_source); 378 379 /* set input handler */ 380 uart_byte_request.callback = uart_rx_handler; 381 uart_byte_request.data = stdin_buffer; 382 uart_byte_request.len = sizeof(uint8_t); 383 UART_ReadAsync(MXC_UART_GET_UART(CONSOLE_UART), &uart_byte_request); 384 } 385 #endif 386 387 #include "hal_flash_bank_mxc.h" 388 #include "btstack_tlv.h" 389 #include "btstack_tlv_flash_bank.h" 390 #include "btstack_link_key_db_tlv.h" 391 #include "le_device_db_tlv.h" 392 393 #define HAL_FLASH_BANK_SIZE 0x2000 394 #define HAL_FLASH_BANK_0_ADDR 0x1FC000 395 #define HAL_FLASH_BANK_1_ADDR 0x1FE000 396 397 static hal_flash_bank_mxc_t hal_flash_bank_context; 398 static btstack_tlv_flash_bank_t btstack_tlv_flash_bank_context; 399 400 401 /******************************************************************************/ 402 int bluetooth_main(void) 403 { 404 LED_Off(LED_GREEN); 405 LED_On(LED_RED); 406 LED_Off(LED_BLUE); 407 408 bt_comm_init(); 409 /* BT Stack Initialization */ 410 btstack_memory_init(); 411 btstack_run_loop_init(btstack_run_loop_embedded_get_instance()); 412 413 // enable packet logger 414 // hci_dump_init(hci_dump_embedded_stdout_get_instance()); 415 416 /* Init HCI */ 417 const hci_transport_t * transport = hci_transport_h4_instance(btstack_uart_block_embedded_instance()); 418 hci_init(transport, &config); 419 hci_set_chipset(btstack_chipset_cc256x_instance()); 420 421 // setup TLV Flash Bank implementation 422 const hal_flash_bank_t * hal_flash_bank_impl = hal_flash_bank_mxc_init_instance( 423 &hal_flash_bank_context, 424 HAL_FLASH_BANK_SIZE, 425 HAL_FLASH_BANK_0_ADDR, 426 HAL_FLASH_BANK_1_ADDR); 427 const btstack_tlv_t * btstack_tlv_impl = btstack_tlv_flash_bank_init_instance( 428 &btstack_tlv_flash_bank_context, 429 hal_flash_bank_impl, 430 &hal_flash_bank_context); 431 432 // setup Link Key DB using TLV 433 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); 434 hci_set_link_key_db(btstack_link_key_db); 435 436 // setup LE Device DB using TLV 437 le_device_db_tlv_configure(btstack_tlv_impl, &btstack_tlv_flash_bank_context); 438 439 // go 440 btstack_main(0, (void *)NULL); 441 return 0; 442 } 443