xref: /btstack/port/stm32-l073rz-nucleo-em9304/port/port.c (revision bc6a318f2177319997f3b7da7b6f161b4ec94fed)
1 /*
2  * Copyright (C) 2017 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 #define BTSTACK_FILE__ "hci_transport_h4.c"
39 
40 /*
41  *  port.c
42  *
43  *  BTstack port for the EM9304 Development Kit consisting of an
44  *  - STM32 Nucleo L053 Board with an
45  *  - EM9304 Bluetooth Controller in the default SPI Slave configuration
46  */
47 
48 #include <string.h>
49 #include "stm32l0xx_hal.h"
50 #include "port.h"
51 #include "main.h"   // pin definitions
52 
53 #include "bluetooth.h"
54 #include "btstack_run_loop.h"
55 #include "btstack_run_loop_embedded.h"
56 #include "btstack_defines.h"
57 #include "btstack_event.h"
58 #include "btstack_memory.h"
59 #include "btstack_ring_buffer.h"
60 #include "hci_dump.h"
61 #include "hci_transport.h"
62 #include "hci_transport_h4.h"
63 #include "hci_transport_em9304_spi.h"
64 #include "btstack_debug.h"
65 #include "btstack_chipset_em9301.h"
66 
67 #ifdef ENABLE_SEGGER_RTT
68 #include "SEGGER_RTT.h"
69 #include "hci_dump_segger_rtt_stdout.h"
70 #else
71 #include "hci_dump_embedded_stdout.h"
72 #endif
73 
74 // retarget printf
75 #include <stdio.h>
76 #include <unistd.h>
77 #include <errno.h>
78 
79 #ifndef ENABLE_SEGGER_RTT
80 
_write(int file,char * ptr,int len)81 int _write(int file, char *ptr, int len){
82     uint8_t cr = '\r';
83     if (file == STDOUT_FILENO || file == STDERR_FILENO) {
84         int i;
85         for (i = 0; i < len; i++) {
86             if (ptr[i] == '\n') {
87                 HAL_UART_Transmit( &huart2, &cr, 1, HAL_MAX_DELAY );
88             }
89             HAL_UART_Transmit( &huart2, (uint8_t *) &ptr[i], 1, HAL_MAX_DELAY );
90         }
91         return i;
92     }
93     errno = EIO;
94     return -1;
95 }
96 
97 #endif
98 
_read(int file,char * ptr,int len)99 int _read(int file, char * ptr, int len){
100     (void)(file);
101     (void)(ptr);
102     (void)(len);
103     return -1;
104 }
105 
_close(int file)106 int _close(int file){
107     (void)(file);
108     return -1;
109 }
110 
_isatty(int file)111 int _isatty(int file){
112     (void)(file);
113     return -1;
114 }
115 
_lseek(int file)116 int _lseek(int file){
117     (void)(file);
118     return -1;
119 }
120 
_fstat(int file)121 int _fstat(int file){
122     (void)(file);
123     return -1;
124 }
125 
126 // hal_time_ms.h
127 #include "hal_time_ms.h"
hal_time_ms(void)128 uint32_t hal_time_ms(void){
129     return HAL_GetTick();
130 }
131 
132 // hal_cpu.h implementation
133 #include "hal_cpu.h"
134 
hal_cpu_disable_irqs(void)135 void hal_cpu_disable_irqs(void){
136     __disable_irq();
137 }
138 
hal_cpu_enable_irqs(void)139 void hal_cpu_enable_irqs(void){
140     __enable_irq();
141 }
142 
hal_cpu_enable_irqs_and_sleep(void)143 void hal_cpu_enable_irqs_and_sleep(void){
144     __enable_irq();
145     __asm__("wfe"); // go to sleep if event flag isn't set. if set, just clear it. IRQs set event flag
146 }
147 
148 // EM 9304 SPI Master HCI Implementation
149 
150 #define STS_SLAVE_READY 0xc0
151 
152 // SPI Write Command
153 static const uint8_t hal_spi_em9304_write_command[] = {
154     0x42,
155     0x00,
156 };
157 
158 // SPI Read Command
159 static const uint8_t hal_spi_em9304_read_command[] = {
160     0x81,
161     0x00,
162 };
163 
164 const uint8_t hci_reset_2[] = { 0x01, 0x03, 0x0c, 0x00 };
165 
166 static volatile enum {
167     SPI_EM9304_IDLE,
168     SPI_EM9304_RX_W4_READ_COMMAND_SENT,
169     SPI_EM9304_RX_READ_COMMAND_SENT,
170     SPI_EM9304_RX_W4_DATA_RECEIVED,
171     SPI_EM9304_RX_DATA_RECEIVED,
172     SPI_EM9304_TX_W4_RDY,
173     SPI_EM9304_TX_W4_WRITE_COMMAND_SENT,
174     SPI_EM9304_TX_WRITE_COMMAND_SENT,
175     SPI_EM9304_TX_W4_DATA_SENT,
176     SPI_EM9304_TX_DATA_SENT,
177 } hal_spi_em9304_state;
178 
179 #define SPI_EM9304_RX_BUFFER_SIZE     64
180 #define SPI_EM9304_TX_BUFFER_SIZE     64
181 #define SPI_EM9304_RING_BUFFER_SIZE  128
182 
183 static uint8_t  hal_spi_em9304_slave_status[2];
184 
185 static const uint8_t hal_spi_em9304_zeros[SPI_EM9304_TX_BUFFER_SIZE];
186 
187 static uint8_t  hal_spi_em9304_rx_buffer[SPI_EM9304_RX_BUFFER_SIZE];
188 static uint16_t hal_spi_em9304_rx_request_len;
189 static uint16_t hal_spi_em9304_tx_request_len;
190 
191 static btstack_ring_buffer_t hal_uart_dma_rx_ring_buffer;
192 static uint8_t hal_uart_dma_rx_ring_buffer_storage[SPI_EM9304_RING_BUFFER_SIZE];
193 
194 static const uint8_t  * hal_uart_dma_tx_data;
195 static uint16_t         hal_uart_dma_tx_size;
196 
197 static uint8_t  * hal_uart_dma_rx_buffer;
198 static uint16_t   hal_uart_dma_rx_len;
199 
200 static void dummy_handler(void);
201 
202 // handlers
203 static void (*rx_done_handler)(void) = &dummy_handler;
204 static void (*tx_done_handler)(void) = &dummy_handler;
205 
hal_spi_em9304_trigger_run_loop(void)206 static inline void hal_spi_em9304_trigger_run_loop(void){
207     btstack_run_loop_poll_data_sources_from_irq();
208 }
209 
hal_spi_em9304_rdy(void)210 static inline int hal_spi_em9304_rdy(void){
211     return HAL_GPIO_ReadPin(SPI1_RDY_GPIO_Port, SPI1_RDY_Pin) == GPIO_PIN_SET;
212 }
213 
hal_spi_em9304_reset(void)214 static void hal_spi_em9304_reset(void){
215     btstack_ring_buffer_init(&hal_uart_dma_rx_ring_buffer, &hal_uart_dma_rx_ring_buffer_storage[0], SPI_EM9304_RING_BUFFER_SIZE);
216 }
217 
HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef * hspi)218 void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi){
219     switch (hal_spi_em9304_state){
220         case SPI_EM9304_RX_W4_READ_COMMAND_SENT:
221             hal_spi_em9304_state = SPI_EM9304_RX_READ_COMMAND_SENT;
222             hal_spi_em9304_trigger_run_loop();
223             break;
224         case SPI_EM9304_TX_W4_WRITE_COMMAND_SENT:
225             hal_spi_em9304_state = SPI_EM9304_TX_WRITE_COMMAND_SENT;
226             hal_spi_em9304_trigger_run_loop();
227             break;
228         case SPI_EM9304_RX_W4_DATA_RECEIVED:
229             hal_spi_em9304_state = SPI_EM9304_RX_DATA_RECEIVED;
230             hal_spi_em9304_trigger_run_loop();
231             break;
232         default:
233             break;
234     }
235 }
236 
HAL_SPI_RxCpltCallback(SPI_HandleTypeDef * hspi)237 void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi){
238     switch (hal_spi_em9304_state){
239         case SPI_EM9304_RX_W4_DATA_RECEIVED:
240             hal_spi_em9304_state = SPI_EM9304_RX_DATA_RECEIVED;
241             hal_spi_em9304_trigger_run_loop();
242             break;
243         default:
244             break;
245     }
246 }
247 
HAL_SPI_TxCpltCallback(SPI_HandleTypeDef * hspi)248 void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi){
249     switch (hal_spi_em9304_state){
250         case SPI_EM9304_TX_W4_DATA_SENT:
251             hal_spi_em9304_state = SPI_EM9304_TX_DATA_SENT;
252             hal_spi_em9304_trigger_run_loop();
253             break;
254         default:
255             break;
256     }
257 }
258 
HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)259 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
260     if (hal_spi_em9304_rdy()){
261         hal_spi_em9304_trigger_run_loop();
262     }
263 }
264 
hal_spi_em9304_transfer_rx_data(void)265 static void hal_spi_em9304_transfer_rx_data(void){
266     while (1){
267         int bytes_available = btstack_ring_buffer_bytes_available(&hal_uart_dma_rx_ring_buffer);
268         log_debug("transfer_rx_data: ring buffer has %u -> hci buffer needs %u", bytes_available, hal_uart_dma_rx_len);
269 
270         if (!bytes_available) return;
271         if (!hal_uart_dma_rx_len) return;
272 
273         int bytes_to_copy = btstack_min(bytes_available, hal_uart_dma_rx_len);
274         uint32_t bytes_read;
275         btstack_ring_buffer_read(&hal_uart_dma_rx_ring_buffer, hal_uart_dma_rx_buffer, bytes_to_copy, &bytes_read);
276         hal_uart_dma_rx_buffer += bytes_read;
277         hal_uart_dma_rx_len    -= bytes_read;
278 
279         if (hal_uart_dma_rx_len == 0){
280             (*rx_done_handler)();
281         }
282     }
283 }
284 
hal_spi_em9304_start_tx_transaction(void)285 static void hal_spi_em9304_start_tx_transaction(void){
286     // wait for RDY
287     hal_spi_em9304_state = SPI_EM9304_TX_W4_RDY;
288 
289     // chip select
290     HAL_GPIO_WritePin(SPI1_CSN_GPIO_Port, SPI1_CSN_Pin, GPIO_PIN_RESET);
291 }
292 
hal_spi_em9304_process(btstack_data_source_t * ds,btstack_data_source_callback_type_t callback_type)293 static void hal_spi_em9304_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type){
294     (void) ds;
295     (void) callback_type;
296 
297     uint16_t max_bytes_to_send;
298 
299     switch (hal_spi_em9304_state){
300         case SPI_EM9304_IDLE:
301             // RDY && space in RX Buffer
302             if (hal_spi_em9304_rdy()
303             && (btstack_ring_buffer_bytes_free(&hal_uart_dma_rx_ring_buffer) >= SPI_EM9304_RX_BUFFER_SIZE) ){
304 
305                 // chip select
306                 HAL_GPIO_WritePin(SPI1_CSN_GPIO_Port, SPI1_CSN_Pin, GPIO_PIN_RESET);
307 
308                 // send read command
309                 hal_spi_em9304_state = SPI_EM9304_RX_W4_READ_COMMAND_SENT;
310                 HAL_SPI_TransmitReceive_DMA(&hspi1, (uint8_t*) hal_spi_em9304_read_command, hal_spi_em9304_slave_status, sizeof(hal_spi_em9304_read_command));
311 
312             } else if (hal_uart_dma_tx_size){
313                 hal_spi_em9304_start_tx_transaction();
314             }
315             break;
316 
317         case SPI_EM9304_RX_READ_COMMAND_SENT:
318             // check slave status
319             log_debug("RX: STS1 0x%02X, STS2 0x%02X", hal_spi_em9304_slave_status[0], hal_spi_em9304_slave_status[1]);
320 
321             // check if ready
322             if ((hal_spi_em9304_slave_status[0] != STS_SLAVE_READY)){
323                 // chip deselect & retry
324                 HAL_GPIO_WritePin(SPI1_CSN_GPIO_Port, SPI1_CSN_Pin, GPIO_PIN_SET);
325                 hal_spi_em9304_state = SPI_EM9304_IDLE;
326                 break;
327             }
328 
329             // read data and send '0's
330             hal_spi_em9304_state = SPI_EM9304_RX_W4_DATA_RECEIVED;
331             hal_spi_em9304_rx_request_len = hal_spi_em9304_slave_status[1];
332             HAL_SPI_TransmitReceive_DMA(&hspi1, (uint8_t*) hal_spi_em9304_zeros, &hal_spi_em9304_rx_buffer[0], hal_spi_em9304_rx_request_len);
333             break;
334 
335         case SPI_EM9304_RX_DATA_RECEIVED:
336 
337             // chip deselect & done
338             HAL_GPIO_WritePin(SPI1_CSN_GPIO_Port, SPI1_CSN_Pin, GPIO_PIN_SET);
339             hal_spi_em9304_state = SPI_EM9304_IDLE;
340 
341             // move data into ring buffer
342             btstack_ring_buffer_write(&hal_uart_dma_rx_ring_buffer, hal_spi_em9304_rx_buffer, hal_spi_em9304_rx_request_len);
343             hal_spi_em9304_rx_request_len = 0;
344 
345             // deliver new data
346             hal_spi_em9304_transfer_rx_data();
347             break;
348 
349         case SPI_EM9304_TX_W4_RDY:
350             // check if ready
351             if (!hal_spi_em9304_rdy()) break;
352 
353             // send write command
354             hal_spi_em9304_state = SPI_EM9304_TX_W4_WRITE_COMMAND_SENT;
355             HAL_SPI_TransmitReceive_DMA(&hspi1, (uint8_t*) hal_spi_em9304_write_command, hal_spi_em9304_slave_status, sizeof(hal_spi_em9304_write_command));
356             break;
357 
358         case SPI_EM9304_TX_WRITE_COMMAND_SENT:
359 
360             // check slave status and em9304 rx buffer space
361             log_debug("TX: STS1 0x%02X, STS2 0x%02X", hal_spi_em9304_slave_status[0], hal_spi_em9304_slave_status[1]);
362             max_bytes_to_send = hal_spi_em9304_slave_status[1];
363             if ((hal_spi_em9304_slave_status[0] != STS_SLAVE_READY) || (max_bytes_to_send == 0)){
364                 // chip deselect & retry
365                 HAL_GPIO_WritePin(SPI1_CSN_GPIO_Port, SPI1_CSN_Pin, GPIO_PIN_SET);
366                 hal_spi_em9304_state = SPI_EM9304_IDLE;
367                 break;
368             }
369 
370             // number bytes to send
371             hal_spi_em9304_tx_request_len = btstack_min(hal_uart_dma_tx_size, max_bytes_to_send);
372 
373             // send command
374             hal_spi_em9304_state = SPI_EM9304_TX_W4_DATA_SENT;
375             HAL_SPI_Transmit_DMA(&hspi1, (uint8_t*) hal_uart_dma_tx_data, hal_spi_em9304_tx_request_len);
376             break;
377 
378         case SPI_EM9304_TX_DATA_SENT:
379 
380             // chip deselect & done
381             HAL_GPIO_WritePin(SPI1_CSN_GPIO_Port, SPI1_CSN_Pin, GPIO_PIN_SET);
382             hal_spi_em9304_state = SPI_EM9304_IDLE;
383 
384             // chunk processed
385             hal_uart_dma_tx_size -= hal_spi_em9304_tx_request_len;
386             hal_uart_dma_tx_data += hal_spi_em9304_tx_request_len;
387             hal_spi_em9304_tx_request_len = 0;
388 
389             // handle TX Complete
390             if (hal_uart_dma_tx_size){
391                 // more data to send
392                 hal_spi_em9304_start_tx_transaction();
393             } else {
394                 // notify higher layer
395                 (*tx_done_handler)();
396             }
397             break;
398 
399         default:
400             break;
401     }
402 }
403 
404 //
405 // #include "hal_uart_dma.h"
406 
dummy_handler(void)407 static void dummy_handler(void){};
408 
hal_spi_em9304_power_cycle(void)409 void hal_spi_em9304_power_cycle(void){
410     HAL_GPIO_WritePin(EN_GPIO_Port, EN_Pin, GPIO_PIN_RESET);
411     HAL_Delay(10);
412     HAL_GPIO_WritePin(EN_GPIO_Port, EN_Pin, GPIO_PIN_SET);
413 }
414 
hal_uart_dma_init(void)415 void hal_uart_dma_init(void){
416     hal_spi_em9304_power_cycle();
417     hal_spi_em9304_reset();
418 }
419 
hal_uart_dma_set_block_received(void (* the_block_handler)(void))420 void hal_uart_dma_set_block_received( void (*the_block_handler)(void)){
421     rx_done_handler = the_block_handler;
422 }
423 
hal_uart_dma_set_block_sent(void (* the_block_handler)(void))424 void hal_uart_dma_set_block_sent( void (*the_block_handler)(void)){
425     tx_done_handler = the_block_handler;
426 }
427 
hal_uart_dma_set_baud(uint32_t baud)428 int  hal_uart_dma_set_baud(uint32_t baud){
429     return 0;
430 }
431 
hal_uart_dma_send_block(const uint8_t * buffer,uint16_t length)432 void hal_uart_dma_send_block(const uint8_t *buffer, uint16_t length){
433     hal_uart_dma_tx_data = buffer;
434     hal_uart_dma_tx_size = length;
435     hal_spi_em9304_process(NULL, 0);
436 }
437 
hal_uart_dma_receive_block(uint8_t * buffer,uint16_t length)438 void hal_uart_dma_receive_block(uint8_t *buffer, uint16_t length){
439     log_debug("hal_uart_dma_receive_block: len %u, ring buffer has %u, UART_RX_LEN %u", length, btstack_ring_buffer_bytes_available(&hal_uart_dma_rx_ring_buffer), hal_uart_dma_rx_len);
440     hal_uart_dma_rx_buffer = buffer;
441     hal_uart_dma_rx_len    = length;
442     hal_spi_em9304_transfer_rx_data();
443     hal_spi_em9304_process(NULL, 0);
444 }
445 
hal_uart_dma_set_csr_irq_handler(void (* csr_irq_handler)(void))446 void hal_uart_dma_set_csr_irq_handler( void (*csr_irq_handler)(void)){
447 }
448 
hal_uart_dma_set_sleep(uint8_t sleep)449 void hal_uart_dma_set_sleep(uint8_t sleep){
450 }
451 
452 // dummy config
453 static const hci_transport_config_uart_t config = {
454     HCI_TRANSPORT_CONFIG_UART,
455     115200,
456     4000000,
457     1,
458     NULL
459 };
460 
461 static btstack_packet_callback_registration_t hci_event_callback_registration;
462 int btstack_main(int argc, char ** argv);
463 
464 // main.c
packet_handler(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)465 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
466     UNUSED(size);
467     UNUSED(channel);
468     if (packet_type != HCI_EVENT_PACKET) return;
469     switch(hci_event_packet_get_type(packet)){
470         case BTSTACK_EVENT_STATE:
471             if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return;
472             printf("BTstack up and running.\n");
473             break;
474         default:
475             break;
476     }
477 }
478 
479 // data source to keep SPI transport working
480 static btstack_data_source_t transport_data_source;
481 
port_main(void)482 void port_main(void){
483 
484     // start with BTstack init - especially configure HCI Transport
485     btstack_memory_init();
486     btstack_run_loop_init(btstack_run_loop_embedded_get_instance());
487 
488     // uncomment to enable packet logger
489 #ifdef ENABLE_SEGGER_RTT
490     // hci_dump_init(hci_dump_segger_rtt_stdout_get_instance());
491 #else
492     // hci_dump_init(hci_dump_embedded_stdout_get_instance());
493 #endif
494 
495     // set up polling data_source
496     btstack_run_loop_set_data_source_handler(&transport_data_source, &hal_spi_em9304_process);
497     btstack_run_loop_enable_data_source_callbacks(&transport_data_source, DATA_SOURCE_CALLBACK_POLL);
498     btstack_run_loop_add_data_source(&transport_data_source);
499 
500     // init HCI
501     hci_init(hci_transport_h4_instance(btstack_uart_block_embedded_instance()), &config);
502     hci_set_chipset(btstack_chipset_em9301_instance());
503 
504 #if 0
505     // setup Link Key DB
506     const hal_flash_sector_t * hal_flash_sector_impl = hal_flash_sector_stm32_init_instance(
507             &hal_flash_sector_context,
508             HAL_FLASH_SECTOR_SIZE,
509             HAL_FLASH_SECTOR_BANK_0_SECTOR,
510             HAL_FLASH_SECTOR_BANK_1_SECTOR,
511             HAL_FLASH_SECTOR_BANK_0_ADDR,
512             HAL_FLASH_SECTOR_BANK_1_ADDR);
513     const btstack_tlv_t * btstack_tlv_impl = btstack_tlv_flash_sector_init_instance(
514             &btstack_tlv_flash_sector_context,
515             hal_flash_sector_impl,
516             &hal_flash_sector_context);
517     const btstack_link_key_db_t * btstack_link_key_db = btstack_link_key_db_tlv_get_instance(btstack_tlv_impl, &btstack_tlv_flash_sector_context);
518     hci_set_link_key_db(btstack_link_key_db);
519 #endif
520 
521     // inform about BTstack state
522     hci_event_callback_registration.callback = &packet_handler;
523     hci_add_event_handler(&hci_event_callback_registration);
524 
525     // hand over to btstack embedded code
526     btstack_main(0, NULL);
527 
528     // go
529     btstack_run_loop_execute();
530 }
531