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
dummy_handler(void)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
hal_cpu_disable_irqs(void)88 void hal_cpu_disable_irqs(void)
89 {
90 __disable_irq();
91 }
92
hal_cpu_enable_irqs(void)93 void hal_cpu_enable_irqs(void)
94 {
95 __enable_irq();
96 }
hal_cpu_enable_irqs_and_sleep(void)97 void hal_cpu_enable_irqs_and_sleep(void)
98 {
99 __enable_irq();
100 /* TODO: Add sleep mode */
101 }
102
hal_uart_dma_send_block(const uint8_t * buffer,uint16_t len)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
hal_uart_dma_receive_block(uint8_t * buffer,uint16_t len)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
hal_btstack_run_loop_execute_once(void)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
hal_uart_init(void)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
hal_uart_dma_set_baud(uint32_t baud)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
hal_uart_dma_init(void)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
hal_uart_dma_set_block_received(void (* block_handler)(void))226 void hal_uart_dma_set_block_received( void (*block_handler)(void)){
227 rx_done_handler = block_handler;
228 }
229
hal_uart_dma_set_block_sent(void (* block_handler)(void))230 void hal_uart_dma_set_block_sent( void (*block_handler)(void)){
231
232 tx_done_handler = block_handler;
233 }
234
hal_uart_dma_set_csr_irq_handler(void (* csr_irq_handler)(void))235 void hal_uart_dma_set_csr_irq_handler( void (*csr_irq_handler)(void)){
236
237 }
238
hal_uart_dma_set_sleep(uint8_t sleep)239 void hal_uart_dma_set_sleep(uint8_t sleep){
240
241 }
242
init_slow_clock(void)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
bt_comm_init()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"
hal_led_off(void)298 void hal_led_off(void){
299 LED_Off(LED_BLUE);
300 }
301
hal_led_on(void)302 void hal_led_on(void){
303 LED_On(LED_BLUE);
304 }
305
hal_led_toggle(void)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
uart_rx_handler(uart_req_t * request,int error)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
hal_stdin_setup(void (* handler)(char c))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_poll_data_sources_from_irq();
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 /******************************************************************************/
bluetooth_main(void)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