1 /* 2 * Copyright (C) 2016 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__ "btstack_em9304_spi_embedded.c" 39 40 /* 41 * btstack_em9304_spi_embedded.c 42 * Integrate hal_em9304_spi.h with BTstack Run Loop 43 */ 44 45 #include "btstack_debug.h" 46 #include "btstack_run_loop.h" 47 #include "btstack_em9304_spi.h" 48 #include "hal_em9304_spi.h" 49 #include <stddef.h> // NULL 50 51 // data source for integration with BTstack Runloop 52 static btstack_data_source_t btstack_em9304_spi_embedded_data_source; 53 54 static void (*btstack_em9304_spi_embedded_ready_callback)(void); 55 static void (*btstack_em9304_spi_embedded_transfer_done_callback)(void); 56 57 static int btstack_em9304_spi_embedded_notify_ready; 58 static int btstack_em9304_spi_embedded_notify_transfer_done; 59 60 static void btstack_em9304_spi_embedded_ready(void){ 61 btstack_em9304_spi_embedded_notify_ready = 1; 62 btstack_run_loop_poll_data_sources_from_irq(); 63 } 64 65 static void btstack_em9304_spi_transfer_done(void){ 66 btstack_em9304_spi_embedded_notify_transfer_done = 1; 67 btstack_run_loop_poll_data_sources_from_irq(); 68 } 69 70 static void btstack_em9304_spi_embedded_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) { 71 UNUSED(ds); 72 switch (callback_type){ 73 case DATA_SOURCE_CALLBACK_POLL: 74 if (btstack_em9304_spi_embedded_notify_ready){ 75 btstack_em9304_spi_embedded_notify_ready = 0; 76 if (btstack_em9304_spi_embedded_ready_callback){ 77 (*btstack_em9304_spi_embedded_ready_callback)(); 78 } 79 } 80 if (btstack_em9304_spi_embedded_notify_transfer_done){ 81 btstack_em9304_spi_embedded_notify_transfer_done = 0; 82 if (btstack_em9304_spi_embedded_transfer_done_callback){ 83 (*btstack_em9304_spi_embedded_transfer_done_callback)(); 84 } 85 } 86 break; 87 default: 88 break; 89 } 90 } 91 92 /** 93 * @brief Initialize SPI 94 */ 95 static int btstack_em9304_spi_embedded_open(void){ 96 // set up polling data_source 97 btstack_run_loop_set_data_source_handler(&btstack_em9304_spi_embedded_data_source, &btstack_em9304_spi_embedded_process); 98 btstack_run_loop_enable_data_source_callbacks(&btstack_em9304_spi_embedded_data_source, DATA_SOURCE_CALLBACK_POLL); 99 btstack_run_loop_add_data_source(&btstack_em9304_spi_embedded_data_source); 100 101 // reset ready callback handler 102 btstack_em9304_spi_embedded_ready_callback = NULL; 103 104 // setup lower layer 105 hal_em9304_spi_init(); 106 107 // setup callbacks with lower layer 108 hal_em9304_spi_set_ready_callback(&btstack_em9304_spi_embedded_ready); 109 hal_em9304_spi_set_transfer_done_callback(&btstack_em9304_spi_transfer_done); 110 return 0; 111 } 112 113 /** 114 * @brief Deinitialize SPI 115 */ 116 static int btstack_em9304_spi_embedded_close(void){ 117 // remove data source 118 btstack_run_loop_disable_data_source_callbacks(&btstack_em9304_spi_embedded_data_source, DATA_SOURCE_CALLBACK_POLL); 119 btstack_run_loop_remove_data_source(&btstack_em9304_spi_embedded_data_source); 120 121 // stop lower layer 122 hal_em9304_spi_deinit(); 123 return 0; 124 } 125 126 /** 127 * @brief Set callback for RDY - can be called from ISR context 128 * @param callback 129 */ 130 static void btstack_em9304_spi_embedded_set_ready_callback(void (*callback)(void)){ 131 if (callback){ 132 hal_em9304_spi_enable_ready_interrupt(); 133 } else { 134 hal_em9304_spi_disable_ready_interrupt(); 135 } 136 btstack_em9304_spi_embedded_ready_callback = callback; 137 } 138 139 /** 140 * @brief Set callback for transfer complete - can be called from ISR context 141 * @param callback 142 */ 143 static void btstack_em9304_spi_embedded_set_transfer_done_callback(void (*callback)(void)){ 144 btstack_em9304_spi_embedded_transfer_done_callback = callback; 145 } 146 147 /** 148 * @brief Poll READY state 149 */ 150 static int btstack_em9304_spi_embedded_get_ready(){ 151 return hal_em9304_spi_get_ready(); 152 } 153 154 /** 155 * @brief Set Chip Selet 156 * @param enable 157 */ 158 static void btstack_em9304_spi_embedded_set_chip_select(int enable){ 159 hal_em9304_spi_set_chip_select(enable); 160 } 161 162 /** 163 * @brief Check if full duplex operation via btstack_em9304_spi_transceive is supported 164 */ 165 static int btstack_em9304_spi_embedded_get_fullduplex_support(void){ 166 return hal_em9304_spi_get_fullduplex_support(); 167 } 168 169 /** 170 * @brief Transmit and Receive bytes via SPI 171 * @param tx_data buffer to transmit 172 * @param rx_data buffer to receive into 173 * @param len 174 */ 175 static void btstack_em9304_spi_embedded_transceive(const uint8_t * tx_data, uint8_t * rx_data, uint16_t len){ 176 hal_em9304_spi_transceive(tx_data, rx_data, len); 177 } 178 179 /** 180 * @brief Transmit bytes via SPI 181 * @param tx_data buffer to transmit 182 * @param len 183 */ 184 static void btstack_em9304_spi_embedded_transmit(const uint8_t * tx_data, uint16_t len){ 185 hal_em9304_spi_transmit(tx_data, len); 186 } 187 188 /** 189 * @brief Receive bytes via SPI 190 * @param rx_data buffer to receive into 191 * @param len 192 */ 193 static void btstack_em9304_spi_embedded_receive(uint8_t * rx_data, uint16_t len){ 194 hal_em9304_spi_receive(rx_data, len); 195 } 196 197 static const btstack_em9304_spi_t btstack_em9304_spi_embedded = { 198 /* void (open)(void); */ &btstack_em9304_spi_embedded_open, 199 /* void (close)(void); */ &btstack_em9304_spi_embedded_close, 200 /* int (get_fullduplex_support)(void); */ &btstack_em9304_spi_embedded_get_fullduplex_support, 201 /* void (set_ready_callback)(..); */ &btstack_em9304_spi_embedded_set_ready_callback, 202 /* void (set_transfer_done_callback)(..); */ &btstack_em9304_spi_embedded_set_transfer_done_callback, 203 /* void (set_chip_select)(int enable); */ &btstack_em9304_spi_embedded_set_chip_select, 204 /* int (get_ready)(); */ &btstack_em9304_spi_embedded_get_ready, 205 /* void (transceive)(..); */ &btstack_em9304_spi_embedded_transceive, 206 /* void (transmit)(..); */ &btstack_em9304_spi_embedded_transmit, 207 /* void (receive)(..); */ &btstack_em9304_spi_embedded_receive, 208 }; 209 210 const btstack_em9304_spi_t * btstack_em9304_spi_embedded_instance(void){ 211 return &btstack_em9304_spi_embedded; 212 } 213