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 "hal_tick.h" 36 #include <stdio.h> 37 #include <string.h> 38 #include "lp.h" 39 #include "uart.h" 40 #include "board.h" 41 #include "led.h" 42 #include "btstack_debug.h" 43 44 #include "btstack.h" 45 #include "btstack_config.h" 46 #include "btstack_run_loop_embedded.h" 47 #include "btstack_chipset_cc256x.h" 48 #include "btstack_port.h" 49 50 #define CC256X_UART_ID 0 51 #define UART_RXFIFO_USABLE (MXC_UART_FIFO_DEPTH-3) 52 53 static uint32_t baud_rate; 54 55 // rx state 56 static int bytes_to_read = 0; 57 static uint8_t * rx_buffer_ptr = 0; 58 59 // tx state 60 static int bytes_to_write = 0; 61 static uint8_t * tx_buffer_ptr = 0; 62 63 const gpio_cfg_t PAN1326_SLOW_CLK = { PORT_1, PIN_7, GPIO_FUNC_GPIO, 64 GPIO_PAD_NORMAL }; 65 const gpio_cfg_t PAN1326_nSHUTD = { PORT_1, PIN_6, GPIO_FUNC_GPIO, 66 GPIO_PAD_NORMAL }; 67 const gpio_cfg_t PAN1326_HCIRTS = { PORT_0, PIN_3, GPIO_FUNC_GPIO, 68 GPIO_PAD_NORMAL }; 69 70 static void dummy_handler(void) {}; 71 static void (*rx_done_handler)(void) = dummy_handler; 72 static void (*tx_done_handler)(void) = dummy_handler; 73 74 75 76 void hal_cpu_disable_irqs(void) 77 { 78 __disable_irq(); 79 } 80 81 void hal_cpu_enable_irqs(void) 82 { 83 __enable_irq(); 84 } 85 void hal_cpu_enable_irqs_and_sleep(void) 86 { 87 88 } 89 90 void hal_uart_dma_send_block(const uint8_t *buffer, uint16_t len) 91 { 92 tx_buffer_ptr = (uint8_t *)buffer; 93 bytes_to_write = len; 94 } 95 96 void hal_uart_dma_receive_block(uint8_t *buffer, uint16_t len) 97 { 98 rx_buffer_ptr = buffer; 99 bytes_to_read = len; 100 } 101 102 void hal_btstack_run_loop_execute_once(void) 103 { 104 int rx_avail; 105 int num_rx_bytes; 106 int tx_avail; 107 int rx_bytes; 108 int tx_bytes; 109 int ret; 110 111 while (bytes_to_read) { 112 rx_avail = UART_NumReadAvail(MXC_UART_GET_UART(CC256X_UART_ID)); 113 if (!rx_avail) 114 break; 115 116 if (bytes_to_read > rx_avail) 117 num_rx_bytes = rx_avail; 118 else 119 num_rx_bytes = bytes_to_read; 120 121 ret = UART_Read(MXC_UART_GET_UART(CC256X_UART_ID), rx_buffer_ptr, num_rx_bytes, &rx_bytes); 122 if (ret < 0) 123 break; 124 125 rx_buffer_ptr += rx_bytes; 126 bytes_to_read -= rx_bytes; 127 128 if (bytes_to_read < 0) { 129 bytes_to_read = 0; 130 } 131 132 if (bytes_to_read == 0){ 133 (*rx_done_handler)(); 134 } 135 } 136 137 while (bytes_to_write) { 138 tx_avail = UART_NumWriteAvail(MXC_UART_GET_UART(CC256X_UART_ID)); 139 if (!tx_avail) 140 break; 141 142 if (bytes_to_write > tx_avail) 143 tx_bytes = tx_avail; 144 else 145 tx_bytes = bytes_to_write; 146 147 ret = UART_Write(MXC_UART_GET_UART(CC256X_UART_ID), tx_buffer_ptr, tx_bytes); 148 if (ret < 0) 149 break; 150 bytes_to_write -= tx_bytes; 151 tx_buffer_ptr += tx_bytes; 152 if (bytes_to_write < 0) { 153 bytes_to_write = 0; 154 } 155 156 if (bytes_to_write == 0){ 157 (*tx_done_handler)(); 158 } 159 } 160 161 btstack_run_loop_embedded_execute_once(); 162 } 163 164 void hal_uart_init(void) 165 { 166 int error = 0; 167 uart_cfg_t cfg; 168 169 cfg.parity = UART_PARITY_DISABLE; 170 cfg.size = UART_DATA_SIZE_8_BITS; 171 cfg.extra_stop = 0; 172 cfg.cts = 1; 173 cfg.rts = 1; 174 175 cfg.baud = baud_rate; 176 177 sys_cfg_uart_t sys_cfg; 178 sys_cfg.clk_scale = CLKMAN_SCALE_AUTO; 179 180 sys_cfg.io_cfg = (ioman_cfg_t )IOMAN_UART(0, 181 IOMAN_MAP_B, // io_map 182 IOMAN_MAP_B, // cts_map 183 IOMAN_MAP_B, // rts_map 184 1, // io_en 185 1, // cts_en 186 1); //rts_en 187 188 if ((error = UART_Init(MXC_UART_GET_UART(CC256X_UART_ID), &cfg, &sys_cfg)) != E_NO_ERROR) { 189 printf("Error initializing UART %d\n", error); 190 while (1); 191 } else { 192 printf("BTSTACK UART Initialized\n"); 193 } 194 195 MXC_UART_GET_UART(CC256X_UART_ID)->ctrl |= MXC_F_UART_CTRL_CTS_POLARITY | MXC_F_UART_CTRL_RTS_POLARITY; 196 MXC_UART_GET_UART(CC256X_UART_ID)->ctrl &= ~((MXC_UART_FIFO_DEPTH - 4) << (MXC_F_UART_CTRL_RTS_LEVEL_POS)); 197 MXC_UART_GET_UART(CC256X_UART_ID)->ctrl |= ((UART_RXFIFO_USABLE) << MXC_F_UART_CTRL_RTS_LEVEL_POS); 198 } 199 200 int hal_uart_dma_set_baud(uint32_t baud){ 201 baud_rate = baud; 202 printf("BAUD RATE IS = %d \n", baud); 203 hal_uart_init(); 204 return baud_rate; 205 } 206 207 void hal_uart_dma_init(void){ 208 bytes_to_write = 0; 209 bytes_to_read = 0; 210 hal_uart_dma_set_baud(115200); 211 } 212 213 void hal_uart_dma_set_block_received( void (*block_handler)(void)){ 214 rx_done_handler = block_handler; 215 } 216 217 void hal_uart_dma_set_block_sent( void (*block_handler)(void)){ 218 219 tx_done_handler = block_handler; 220 } 221 222 void hal_uart_dma_set_csr_irq_handler( void (*csr_irq_handler)(void)){ 223 224 } 225 226 void hal_uart_dma_set_sleep(uint8_t sleep){ 227 228 } 229 230 void init_slow_clock(void) 231 { 232 MXC_PWRSEQ->reg0 &= ~(MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN | MXC_F_PWRSEQ_REG0_PWR_RTCEN_SLP); 233 MXC_PWRSEQ->reg4 &= ~MXC_F_PWRSEQ_REG4_PWR_PSEQ_32K_EN; 234 MXC_PWRSEQ->reg0 |= MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN | MXC_F_PWRSEQ_REG0_PWR_RTCEN_SLP; // Enable RTC 235 hal_delay_us(1); 236 MXC_PWRSEQ->reg4 |= MXC_F_PWRSEQ_REG4_PWR_PSEQ_32K_EN; // Enable the RTC out of P1.7 237 } 238 239 int bt_comm_init() { 240 int error = 0; 241 int cnt = 0; 242 243 hal_tick_init(); 244 hal_delay_us(1); 245 if ((error = GPIO_Config(&PAN1326_HCIRTS)) != E_NO_ERROR) { 246 printf("Error setting PAN1326_HCIRTS %d\n", error); 247 } 248 GPIO_OutSet(&PAN1326_HCIRTS); 249 init_slow_clock(); 250 /* 251 * when enabling the P1.7 RTC output, P1.6 will be hardcoded to an input with 25k pullup enabled. 252 * There is an internal pullup, so when it is set as an input, it will float high. 253 * The PAN1326B data sheet says the NSHUTD pin is pulled down, but the input impedance is stated at 1Meg Ohm, 254 * The so the 25k pullup should be enough to reach the minimum 1.42V to enable the device. 255 * */ 256 while (GPIO_InGet(&PAN1326_HCIRTS)) { 257 cnt++; 258 } 259 260 printf("%s CC256X init completed. cnt: %d \n", __func__, cnt); 261 return 0; 262 } 263 264 static hci_transport_config_uart_t config = { 265 HCI_TRANSPORT_CONFIG_UART, 266 115200, 267 4000000, 268 1, // flow control 269 "max32630fthr", 270 }; 271 272 // hal_led.h implementation 273 #include "hal_led.h" 274 void hal_led_off(void){ 275 LED_Off(LED_BLUE); 276 } 277 278 void hal_led_on(void){ 279 LED_On(LED_BLUE); 280 } 281 282 void hal_led_toggle(void){ 283 LED_Toggle(LED_BLUE); 284 } 285 286 #include "hal_flash_bank_mxc.h" 287 #include "btstack_tlv.h" 288 #include "btstack_tlv_flash_bank.h" 289 #include "btstack_link_key_db_tlv.h" 290 #include "le_device_db_tlv.h" 291 292 #define HAL_FLASH_BANK_SIZE 0x2000 293 #define HAL_FLASH_BANK_0_ADDR 0x1FC000 294 #define HAL_FLASH_BANK_1_ADDR 0x1FE000 295 296 static hal_flash_bank_mxc_t hal_flash_bank_context; 297 static btstack_tlv_flash_bank_t btstack_tlv_flash_bank_context; 298 299 int bluetooth_main(void) 300 { 301 LED_Off(LED_GREEN); 302 LED_On(LED_RED); 303 LED_Off(LED_BLUE); 304 305 bt_comm_init(); 306 /* BT Stack Initialization */ 307 btstack_memory_init(); 308 btstack_run_loop_init(btstack_run_loop_embedded_get_instance()); 309 310 /* Init HCI */ 311 const hci_transport_t * transport = hci_transport_h4_instance(btstack_uart_block_embedded_instance()); 312 hci_init(transport, &config); 313 hci_set_chipset(btstack_chipset_cc256x_instance()); 314 315 // setup TLV Flash Bank implementation 316 const hal_flash_bank_t * hal_flash_bank_impl = hal_flash_bank_mxc_init_instance( 317 &hal_flash_bank_context, 318 HAL_FLASH_BANK_SIZE, 319 HAL_FLASH_BANK_0_ADDR, 320 HAL_FLASH_BANK_1_ADDR); 321 const btstack_tlv_t * btstack_tlv_impl = btstack_tlv_flash_bank_init_instance( 322 &btstack_tlv_flash_bank_context, 323 hal_flash_bank_impl, 324 &hal_flash_bank_context); 325 326 // setup Link Key DB using TLV 327 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); 328 hci_set_link_key_db(btstack_link_key_db); 329 330 // setup LE Device DB using TLV 331 le_device_db_tlv_configure(btstack_tlv_impl, &btstack_tlv_flash_bank_context); 332 333 // go 334 btstack_main(0, (void *)NULL); 335 336 return 0; 337 } 338