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