1 /* 2 * Copyright (C) 2022 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 * 17 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 21 * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 24 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 */ 31 32 /* 33 * hal_uart_dma_chibios.c 34 * 35 * hal_uart_dma implementation on top of ChibiOS/HAL 36 */ 37 38 #define BTSTACK_FILE__ "hal_uart_dma_chibios.c" 39 40 41 #include "btstack_config.h" 42 43 #ifdef HAL_CONTROLLER_UART 44 45 #include "btstack_debug.h" 46 #include "btstack_util.h" 47 48 #include "hal_uart_dma.h" 49 #include "hal.h" 50 51 #include <inttypes.h> 52 #include <string.h> // memcpy 53 54 55 static void dummy_handler(void); 56 static void tx_complete(UARTDriver *uartp); 57 static void rx_complete(UARTDriver *uartp); 58 59 // handlers 60 static void (*rx_done_handler)(void) = &dummy_handler; 61 static void (*tx_done_handler)(void) = &dummy_handler; 62 63 static UARTConfig uartConf = { 64 NULL, /* UART transmission buffer callback. */ 65 &tx_complete, /* UART physical end of transmission callback. */ 66 &rx_complete, /* UART Receiver receiver filled callback. */ 67 NULL, /* UART caracter received callback. */ 68 NULL, /* UART received error callback. */ 69 NULL, /* Receiver timeout callback */ 70 115200, /* UART baudrate. */ 71 0, /* CR 1 */ 72 0, /* CR 2 */ 73 (1<<8) | (1<<9) , /* CR 3 - enable RTS/CTS */ 74 }; 75 76 static void dummy_handler(void){}; 77 78 // reset Bluetooth using n_shutdown 79 static void bluetooth_power_cycle(void){ 80 #ifdef HAL_CONTROLLER_RESET_PIN 81 log_info("Bluetooth power cycle"); 82 palClearPad( HAL_CONTROLLER_RESET_PORT, HAL_CONTROLLER_RESET_PIN); 83 chThdSleepMilliseconds( 250 ); 84 palSetPad( HAL_CONTROLLER_RESET_PORT, HAL_CONTROLLER_RESET_PIN); 85 chThdSleepMilliseconds( 500 ); 86 #else 87 log_info("Bluetooth power cycle skipped, HAL_CONTROLLER_RESET_PIN not defined"); 88 #endif 89 } 90 91 static void rx_complete(UARTDriver *uartp){ 92 if (uartp == &HAL_CONTROLLER_UART){ 93 (*rx_done_handler)(); 94 } 95 } 96 97 static void tx_complete(UARTDriver *uartp){ 98 UNUSED(uartp); 99 if (uartp == &HAL_CONTROLLER_UART){ 100 (*tx_done_handler)(); 101 } 102 } 103 104 void hal_uart_dma_init(void){ 105 bluetooth_power_cycle(); 106 uartStart(&HAL_CONTROLLER_UART, &uartConf); 107 } 108 109 void hal_uart_dma_set_block_received( void (*the_block_handler)(void)){ 110 rx_done_handler = the_block_handler; 111 } 112 113 void hal_uart_dma_set_block_sent( void (*the_block_handler)(void)){ 114 tx_done_handler = the_block_handler; 115 } 116 117 void hal_uart_dma_set_sleep(uint8_t sleep){ 118 UNUSED(sleep); 119 } 120 121 void hal_uart_dma_set_csr_irq_handler( void (*the_irq_handler)(void)){ 122 UNUSED(the_irq_handler); 123 } 124 125 int hal_uart_dma_set_baud(uint32_t baud){ 126 // driver supports 'hot restart' 127 uartConf.speed = baud; 128 uartStart(&HAL_CONTROLLER_UART, &uartConf); 129 log_info("UART baud %" PRIu32, baud); 130 return 0; 131 } 132 133 void hal_uart_dma_send_block(const uint8_t *data, uint16_t size){ 134 uartStartSend(&HAL_CONTROLLER_UART, size, data); 135 } 136 137 void hal_uart_dma_receive_block(uint8_t *data, uint16_t size){ 138 uartStartReceive(&HAL_CONTROLLER_UART, size, data); 139 } 140 141 #endif 142