1 /* 2 * Copyright (C) 2014 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__ "hci_transport_em9304_spi.c" 39 40 #include "btstack_config.h" 41 #include "btstack_em9304_spi.h" 42 43 // EM9304 SPI Driver 44 static const btstack_em9304_spi_t * btstack_em9304_spi; 45 46 ///////////////////////// 47 // em9304 engine 48 #include "btstack_ring_buffer.h" 49 #include "btstack_debug.h" 50 #include "btstack_util.h" 51 #include "hci.h" 52 #include "hci_transport.h" 53 54 static void em9304_spi_engine_run(void); 55 56 #define STS_SLAVE_READY 0xc0 57 58 #define EM9304_SPI_HEADER_TX 0x42 59 #define EM9304_SPI_HEADER_RX 0x81 60 61 #define SPI_EM9304_BUFFER_SIZE 64 62 #define SPI_EM9304_RING_BUFFER_SIZE 128 63 64 // state 65 static volatile enum { 66 SPI_EM9304_READY_FOR_TX, 67 SPI_EM9304_READY_FOR_TX_AND_RX, 68 SPI_EM9304_RX_W4_READ_COMMAND_SENT, 69 SPI_EM9304_RX_READ_COMMAND_SENT, 70 SPI_EM9304_RX_W4_STS2_RECEIVED, 71 SPI_EM9304_RX_STS2_RECEIVED, 72 SPI_EM9304_RX_W4_DATA_RECEIVED, 73 SPI_EM9304_RX_DATA_RECEIVED, 74 SPI_EM9304_TX_W4_RDY, 75 SPI_EM9304_TX_W4_WRITE_COMMAND_SENT, 76 SPI_EM9304_TX_WRITE_COMMAND_SENT, 77 SPI_EM9304_TX_W4_STS2_RECEIVED, 78 SPI_EM9304_TX_STS2_RECEIVED, 79 SPI_EM9304_TX_W4_DATA_SENT, 80 SPI_EM9304_TX_DATA_SENT, 81 SPI_EM9304_DONE, 82 } em9304_spi_engine_state; 83 84 static uint16_t em9304_spi_engine_rx_request_len; 85 static uint16_t em9304_spi_engine_tx_request_len; 86 87 static btstack_ring_buffer_t em9304_spi_engine_rx_ring_buffer; 88 89 static uint8_t em9304_spi_engine_rx_ring_buffer_storage[SPI_EM9304_RING_BUFFER_SIZE]; 90 91 static const uint8_t * em9304_spi_engine_tx_data; 92 static uint16_t em9304_spi_engine_tx_size; 93 94 // handlers 95 static void (*em9304_spi_engine_rx_available_handler)(void); 96 static void (*em9304_spi_engine_tx_done_handler)(void); 97 98 // TODO: get rid of alignment requirement 99 union { 100 uint32_t words[1]; 101 uint8_t bytes[1]; 102 } sCommand; 103 104 union { 105 uint32_t words[1]; 106 uint8_t bytes[1]; 107 } sStas; 108 109 union { 110 uint32_t words[SPI_EM9304_BUFFER_SIZE/4]; 111 uint8_t bytes[SPI_EM9304_BUFFER_SIZE]; 112 } em9304_spi_engine_spi_buffer; 113 114 static void em9304_spi_engine_ready_callback(void){ 115 // TODO: collect states 116 em9304_spi_engine_run(); 117 } 118 119 static void em9304_spi_engine_transfer_done(void){ 120 switch (em9304_spi_engine_state){ 121 case SPI_EM9304_RX_W4_READ_COMMAND_SENT: 122 em9304_spi_engine_state = SPI_EM9304_RX_READ_COMMAND_SENT; 123 break; 124 case SPI_EM9304_RX_W4_STS2_RECEIVED: 125 em9304_spi_engine_state = SPI_EM9304_RX_STS2_RECEIVED; 126 break; 127 case SPI_EM9304_RX_W4_DATA_RECEIVED: 128 em9304_spi_engine_state = SPI_EM9304_RX_DATA_RECEIVED; 129 break; 130 case SPI_EM9304_TX_W4_WRITE_COMMAND_SENT: 131 em9304_spi_engine_state = SPI_EM9304_TX_WRITE_COMMAND_SENT; 132 break; 133 case SPI_EM9304_TX_W4_STS2_RECEIVED: 134 em9304_spi_engine_state = SPI_EM9304_TX_STS2_RECEIVED; 135 break; 136 case SPI_EM9304_TX_W4_DATA_SENT: 137 em9304_spi_engine_state = SPI_EM9304_TX_DATA_SENT; 138 break; 139 default: 140 return; 141 } 142 em9304_spi_engine_run(); 143 } 144 145 static void em9304_spi_engine_start_tx_transaction(void){ 146 // state = wait for RDY 147 em9304_spi_engine_state = SPI_EM9304_TX_W4_RDY; 148 149 // chip select 150 btstack_em9304_spi->set_chip_select(1); 151 152 // enable IRQ 153 btstack_em9304_spi->set_ready_callback(&em9304_spi_engine_ready_callback); 154 } 155 156 static void em9304_spi_engine_start_rx_transaction(void){ 157 // disable interrupt again 158 btstack_em9304_spi->set_ready_callback(NULL); 159 160 // enable chip select 161 btstack_em9304_spi->set_chip_select(1); 162 163 // send read command 164 em9304_spi_engine_state = SPI_EM9304_RX_W4_READ_COMMAND_SENT; 165 sCommand.bytes[0] = EM9304_SPI_HEADER_RX; 166 btstack_em9304_spi->transmit(sCommand.bytes, 1); 167 } 168 169 static inline int em9304_engine_space_in_rx_buffer(void){ 170 return btstack_ring_buffer_bytes_free(&em9304_spi_engine_rx_ring_buffer) >= SPI_EM9304_BUFFER_SIZE; 171 } 172 173 static void em9304_engine_receive_buffer_ready(void){ 174 // no data ready for receive or transmit, but space in rx ringbuffer -> enable READY IRQ 175 em9304_spi_engine_state = SPI_EM9304_READY_FOR_TX_AND_RX; 176 btstack_em9304_spi->set_ready_callback(&em9304_spi_engine_ready_callback); 177 // avoid dead lock, check READY again 178 if (btstack_em9304_spi->get_ready()){ 179 em9304_spi_engine_start_rx_transaction(); 180 } 181 } 182 183 static void em9304_engine_start_next_transaction(void){ 184 185 switch (em9304_spi_engine_state){ 186 case SPI_EM9304_READY_FOR_TX: 187 case SPI_EM9304_READY_FOR_TX_AND_RX: 188 case SPI_EM9304_DONE: 189 break; 190 default: 191 return; 192 } 193 194 if (btstack_em9304_spi->get_ready() && em9304_engine_space_in_rx_buffer()) { 195 em9304_spi_engine_start_rx_transaction(); 196 } else if (em9304_spi_engine_tx_size){ 197 em9304_spi_engine_start_tx_transaction(); 198 } else if (em9304_engine_space_in_rx_buffer()){ 199 em9304_engine_receive_buffer_ready(); 200 } 201 } 202 203 static void em9304_engine_action_done(void){ 204 // chip deselect & done 205 btstack_em9304_spi->set_chip_select(0); 206 em9304_spi_engine_state = SPI_EM9304_DONE; 207 } 208 209 static void em9304_spi_engine_run(void){ 210 uint16_t max_bytes_to_send; 211 switch (em9304_spi_engine_state){ 212 213 case SPI_EM9304_READY_FOR_TX_AND_RX: 214 // check if ready 215 if (!btstack_em9304_spi->get_ready()) break; 216 em9304_spi_engine_start_rx_transaction(); 217 break; 218 219 case SPI_EM9304_RX_READ_COMMAND_SENT: 220 em9304_spi_engine_state = SPI_EM9304_RX_W4_STS2_RECEIVED; 221 btstack_em9304_spi->receive(sStas.bytes, 1); 222 break; 223 224 case SPI_EM9304_RX_STS2_RECEIVED: 225 // check slave status 226 log_debug("RX: STS2 0x%02X", sStas.bytes[0]); 227 228 // read data 229 em9304_spi_engine_state = SPI_EM9304_RX_W4_DATA_RECEIVED; 230 em9304_spi_engine_rx_request_len = sStas.bytes[0]; 231 btstack_em9304_spi->receive(em9304_spi_engine_spi_buffer.bytes, em9304_spi_engine_rx_request_len); 232 break; 233 234 case SPI_EM9304_RX_DATA_RECEIVED: 235 // done 236 em9304_engine_action_done(); 237 238 // move data into ring buffer 239 btstack_ring_buffer_write(&em9304_spi_engine_rx_ring_buffer, em9304_spi_engine_spi_buffer.bytes, em9304_spi_engine_rx_request_len); 240 em9304_spi_engine_rx_request_len = 0; 241 242 // notify about new data available -- assume empty 243 (*em9304_spi_engine_rx_available_handler)(); 244 245 // next 246 em9304_engine_start_next_transaction(); 247 break; 248 249 case SPI_EM9304_TX_W4_RDY: 250 // check if ready 251 if (!btstack_em9304_spi->get_ready()) break; 252 253 // disable interrupt again 254 btstack_em9304_spi->set_ready_callback(NULL); 255 256 // send write command 257 em9304_spi_engine_state = SPI_EM9304_TX_W4_WRITE_COMMAND_SENT; 258 sCommand.bytes[0] = EM9304_SPI_HEADER_TX; 259 btstack_em9304_spi->transmit(sCommand.bytes, 1); 260 break; 261 262 case SPI_EM9304_TX_WRITE_COMMAND_SENT: 263 em9304_spi_engine_state = SPI_EM9304_TX_W4_STS2_RECEIVED; 264 btstack_em9304_spi->receive(sStas.bytes, 1); 265 break; 266 267 case SPI_EM9304_TX_STS2_RECEIVED: 268 // check slave status and em9304 rx buffer space 269 log_debug("TX: STS2 0x%02X", sStas.bytes[0]); 270 max_bytes_to_send = sStas.bytes[0]; 271 if (max_bytes_to_send == 0){ 272 // done 273 em9304_engine_action_done(); 274 // next 275 em9304_engine_start_next_transaction(); 276 break; 277 } 278 279 // number bytes to send 280 em9304_spi_engine_tx_request_len = btstack_min(em9304_spi_engine_tx_size, max_bytes_to_send); 281 282 // send command 283 em9304_spi_engine_state = SPI_EM9304_TX_W4_DATA_SENT; 284 if ( (((uintptr_t) em9304_spi_engine_tx_data) & 0x03) == 0){ 285 // 4-byte aligned 286 btstack_em9304_spi->transmit( (uint8_t*) em9304_spi_engine_tx_data, em9304_spi_engine_tx_request_len); 287 } else { 288 // TODO: get rid of alignment requirement 289 // enforce alignment by copying to spi buffer first 290 memcpy(em9304_spi_engine_spi_buffer.bytes, em9304_spi_engine_tx_data, em9304_spi_engine_tx_request_len); 291 btstack_em9304_spi->transmit( (uint8_t*) em9304_spi_engine_spi_buffer.bytes, em9304_spi_engine_tx_request_len); 292 } 293 break; 294 295 case SPI_EM9304_TX_DATA_SENT: 296 // done 297 em9304_engine_action_done(); 298 299 // chunk sent 300 em9304_spi_engine_tx_size -= em9304_spi_engine_tx_request_len; 301 em9304_spi_engine_tx_data += em9304_spi_engine_tx_request_len; 302 em9304_spi_engine_tx_request_len = 0; 303 304 // notify higher layer when complete 305 if (em9304_spi_engine_tx_size == 0){ 306 (*em9304_spi_engine_tx_done_handler)(); 307 } 308 309 // next 310 em9304_engine_start_next_transaction(); 311 break; 312 313 default: 314 break; 315 } 316 } 317 318 static void em9304_spi_engine_init(void){ 319 btstack_em9304_spi->open(); 320 btstack_em9304_spi->set_transfer_done_callback(&em9304_spi_engine_transfer_done); 321 btstack_ring_buffer_init(&em9304_spi_engine_rx_ring_buffer, &em9304_spi_engine_rx_ring_buffer_storage[0], SPI_EM9304_RING_BUFFER_SIZE); 322 em9304_spi_engine_state = SPI_EM9304_DONE; 323 em9304_engine_start_next_transaction(); 324 } 325 326 static void em9304_spi_engine_close(void){ 327 btstack_em9304_spi->close(); 328 } 329 330 static void em9304_spi_engine_set_data_available( void (*the_block_handler)(void)){ 331 em9304_spi_engine_rx_available_handler = the_block_handler; 332 } 333 334 static void em9304_spi_engine_set_block_sent( void (*the_block_handler)(void)){ 335 em9304_spi_engine_tx_done_handler = the_block_handler; 336 } 337 338 static void em9304_spi_engine_send_block(const uint8_t *buffer, uint16_t length){ 339 em9304_spi_engine_tx_data = buffer; 340 em9304_spi_engine_tx_size = length; 341 em9304_engine_start_next_transaction(); 342 } 343 344 static uint16_t em9304_engine_num_bytes_available(void){ 345 return btstack_ring_buffer_bytes_available(&em9304_spi_engine_rx_ring_buffer); 346 } 347 348 static void em9304_engine_get_bytes(uint8_t * buffer, uint16_t num_bytes){ 349 uint32_t bytes_read; 350 btstack_ring_buffer_read(&em9304_spi_engine_rx_ring_buffer, buffer, num_bytes, &bytes_read); 351 } 352 353 ////////////////////////////////////////////////////////////////////////////// 354 355 // assert pre-buffer for packet type is available 356 #if !defined(HCI_OUTGOING_PRE_BUFFER_SIZE) || (HCI_OUTGOING_PRE_BUFFER_SIZE == 0) 357 #error HCI_OUTGOING_PRE_BUFFER_SIZE not defined. Please update hci.h 358 #endif 359 360 static void dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size); 361 362 typedef enum { 363 H4_W4_PACKET_TYPE, 364 H4_W4_EVENT_HEADER, 365 H4_W4_ACL_HEADER, 366 H4_W4_PAYLOAD, 367 } H4_STATE; 368 369 typedef enum { 370 TX_IDLE = 1, 371 TX_W4_PACKET_SENT, 372 } TX_STATE; 373 374 // write state 375 static TX_STATE tx_state; 376 377 static uint8_t packet_sent_event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0}; 378 379 static void (*packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size) = dummy_handler; 380 381 // packet reader state machine 382 static H4_STATE hci_transport_em9304_h4_state; 383 static uint16_t hci_transport_em9304_spi_bytes_to_read; 384 static uint16_t hci_transport_em9304_spi_read_pos; 385 386 // incoming packet buffer 387 static uint8_t hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE + HCI_INCOMING_PACKET_BUFFER_SIZE + 1]; // packet type + max(acl header + acl payload, event header + event data) 388 static uint8_t * hci_packet = &hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE]; 389 390 static void hci_transport_em9304_spi_block_read(void); 391 392 static void hci_transport_em9304_spi_reset_statemachine(void){ 393 hci_transport_em9304_h4_state = H4_W4_PACKET_TYPE; 394 hci_transport_em9304_spi_read_pos = 0; 395 hci_transport_em9304_spi_bytes_to_read = 1; 396 } 397 398 static void hci_transport_em9304_spi_process_data(void){ 399 while (1){ 400 401 uint16_t bytes_available = em9304_engine_num_bytes_available(); 402 log_debug("transfer_rx_data: ring buffer has %u -> hci wants %u", bytes_available, hci_transport_em9304_spi_bytes_to_read); 403 404 if (!bytes_available) break; 405 if (!hci_transport_em9304_spi_bytes_to_read) break; 406 407 uint16_t bytes_to_copy = btstack_min(bytes_available, hci_transport_em9304_spi_bytes_to_read); 408 em9304_engine_get_bytes(&hci_packet[hci_transport_em9304_spi_read_pos], bytes_to_copy); 409 410 hci_transport_em9304_spi_read_pos += bytes_to_copy; 411 hci_transport_em9304_spi_bytes_to_read -= bytes_to_copy; 412 413 if (hci_transport_em9304_spi_bytes_to_read == 0){ 414 hci_transport_em9304_spi_block_read(); 415 } 416 } 417 } 418 419 static void hci_transport_em9304_spi_block_read(void){ 420 switch (hci_transport_em9304_h4_state) { 421 case H4_W4_PACKET_TYPE: 422 switch (hci_packet[0]){ 423 case HCI_EVENT_PACKET: 424 hci_transport_em9304_spi_bytes_to_read = HCI_EVENT_HEADER_SIZE; 425 hci_transport_em9304_h4_state = H4_W4_EVENT_HEADER; 426 break; 427 case HCI_ACL_DATA_PACKET: 428 hci_transport_em9304_spi_bytes_to_read = HCI_ACL_HEADER_SIZE; 429 hci_transport_em9304_h4_state = H4_W4_ACL_HEADER; 430 break; 431 default: 432 log_error("invalid packet type 0x%02x", hci_packet[0]); 433 hci_transport_em9304_spi_reset_statemachine(); 434 break; 435 } 436 break; 437 438 case H4_W4_EVENT_HEADER: 439 hci_transport_em9304_spi_bytes_to_read = hci_packet[2]; 440 // check ACL length 441 if (HCI_EVENT_HEADER_SIZE + hci_transport_em9304_spi_bytes_to_read > HCI_INCOMING_PACKET_BUFFER_SIZE){ 442 log_error("invalid Event len %d - only space for %u", hci_transport_em9304_spi_bytes_to_read, HCI_INCOMING_PACKET_BUFFER_SIZE - HCI_EVENT_HEADER_SIZE); 443 hci_transport_em9304_spi_reset_statemachine(); 444 break; 445 } 446 hci_transport_em9304_h4_state = H4_W4_PAYLOAD; 447 break; 448 449 case H4_W4_ACL_HEADER: 450 hci_transport_em9304_spi_bytes_to_read = little_endian_read_16( hci_packet, 3); 451 // check ACL length 452 if (HCI_ACL_HEADER_SIZE + hci_transport_em9304_spi_bytes_to_read > HCI_INCOMING_PACKET_BUFFER_SIZE){ 453 log_error("invalid ACL payload len %d - only space for %u", hci_transport_em9304_spi_bytes_to_read, HCI_INCOMING_PACKET_BUFFER_SIZE - HCI_ACL_HEADER_SIZE); 454 hci_transport_em9304_spi_reset_statemachine(); 455 break; 456 } 457 hci_transport_em9304_h4_state = H4_W4_PAYLOAD; 458 break; 459 460 case H4_W4_PAYLOAD: 461 packet_handler(hci_packet[0], &hci_packet[1], hci_transport_em9304_spi_read_pos-1); 462 hci_transport_em9304_spi_reset_statemachine(); 463 break; 464 default: 465 break; 466 } 467 } 468 469 static void hci_transport_em9304_spi_block_sent(void){ 470 switch (tx_state){ 471 case TX_W4_PACKET_SENT: 472 // packet fully sent, reset state 473 tx_state = TX_IDLE; 474 // notify upper stack that it can send again 475 packet_handler(HCI_EVENT_PACKET, &packet_sent_event[0], sizeof(packet_sent_event)); 476 break; 477 default: 478 break; 479 } 480 } 481 482 static int hci_transport_em9304_spi_can_send_now(uint8_t packet_type){ 483 return tx_state == TX_IDLE; 484 } 485 486 static int hci_transport_em9304_spi_send_packet(uint8_t packet_type, uint8_t * packet, int size){ 487 488 // store packet type before actual data and increase size 489 size++; 490 packet--; 491 *packet = packet_type; 492 493 // start sending 494 tx_state = TX_W4_PACKET_SENT; 495 em9304_spi_engine_send_block(packet, size); 496 return 0; 497 } 498 499 static void hci_transport_em9304_spi_init(const void * transport_config){ 500 } 501 502 static int hci_transport_em9304_spi_open(void){ 503 504 // setup UART driver 505 em9304_spi_engine_init(); 506 em9304_spi_engine_set_data_available(&hci_transport_em9304_spi_process_data); 507 em9304_spi_engine_set_block_sent(&hci_transport_em9304_spi_block_sent); 508 // setup H4 RX 509 hci_transport_em9304_spi_reset_statemachine(); 510 // setup H4 TX 511 tx_state = TX_IDLE; 512 return 0; 513 } 514 515 static int hci_transport_em9304_spi_close(void){ 516 em9304_spi_engine_close(); 517 return 0; 518 } 519 520 static void hci_transport_em9304_spi_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ 521 packet_handler = handler; 522 } 523 524 static void dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ 525 } 526 527 // --- end of eHCILL implementation --------- 528 529 static const hci_transport_t hci_transport_em9304_spi = { 530 /* const char * name; */ "H4", 531 /* void (*init) (const void *transport_config); */ &hci_transport_em9304_spi_init, 532 /* int (*open)(void); */ &hci_transport_em9304_spi_open, 533 /* int (*close)(void); */ &hci_transport_em9304_spi_close, 534 /* void (*register_packet_handler)(void (*handler)(...); */ &hci_transport_em9304_spi_register_packet_handler, 535 /* int (*can_send_packet_now)(uint8_t packet_type); */ &hci_transport_em9304_spi_can_send_now, 536 /* int (*send_packet)(...); */ &hci_transport_em9304_spi_send_packet, 537 /* int (*set_baudrate)(uint32_t baudrate); */ NULL, 538 /* void (*reset_link)(void); */ NULL, 539 /* void (*set_sco_config)(uint16_t voice_setting, int num_connections); */ NULL, 540 }; 541 542 // configure and return h4 singleton 543 const hci_transport_t * hci_transport_em9304_spi_instance(const btstack_em9304_spi_t * em9304_spi_driver) { 544 btstack_em9304_spi = em9304_spi_driver; 545 return &hci_transport_em9304_spi; 546 } 547