xref: /btstack/port/max32630-fthr/src/btstack_port.c (revision 31437b52049f7a1b5a54d9c71f935fe16cc0e09d)
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