| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- #include "furi_hal_spi.h"
- #include "furi_hal_resources.h"
- #include <stdbool.h>
- #include <string.h>
- #include <assert.h>
- #include <stm32wbxx_ll_spi.h>
- #include <stm32wbxx_ll_utils.h>
- #include <stm32wbxx_ll_cortex.h>
- void furi_hal_spi_init() {
- furi_hal_spi_bus_init(&furi_hal_spi_bus_r);
- furi_hal_spi_bus_init(&furi_hal_spi_bus_d);
- furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_subghz);
- furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_nfc);
- furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_display);
- furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_fast);
- furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_slow);
- }
- void furi_hal_spi_bus_init(FuriHalSpiBus* bus) {
- assert(bus);
- bus->callback(bus, FuriHalSpiBusEventInit);
- }
- void furi_hal_spi_bus_deinit(FuriHalSpiBus* bus) {
- assert(bus);
- bus->callback(bus, FuriHalSpiBusEventDeinit);
- }
- void furi_hal_spi_bus_handle_init(FuriHalSpiBusHandle* handle) {
- assert(handle);
- handle->callback(handle, FuriHalSpiBusHandleEventInit);
- }
- void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle) {
- assert(handle);
- handle->callback(handle, FuriHalSpiBusHandleEventDeinit);
- }
- void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle) {
- assert(handle);
- handle->bus->callback(handle->bus, FuriHalSpiBusEventLock);
- handle->bus->callback(handle->bus, FuriHalSpiBusEventActivate);
- assert(handle->bus->current_handle == NULL);
- handle->bus->current_handle = handle;
- handle->callback(handle, FuriHalSpiBusHandleEventActivate);
- }
- void furi_hal_spi_release(FuriHalSpiBusHandle* handle) {
- assert(handle);
- assert(handle->bus->current_handle == handle);
- // Handle event and unset handle
- handle->callback(handle, FuriHalSpiBusHandleEventDeactivate);
- handle->bus->current_handle = NULL;
- // Bus events
- handle->bus->callback(handle->bus, FuriHalSpiBusEventDeactivate);
- handle->bus->callback(handle->bus, FuriHalSpiBusEventUnlock);
- }
- static void furi_hal_spi_bus_end_txrx(FuriHalSpiBusHandle* handle, uint32_t timeout) {
- while(LL_SPI_GetTxFIFOLevel(handle->bus->spi) != LL_SPI_TX_FIFO_EMPTY)
- ;
- while(LL_SPI_IsActiveFlag_BSY(handle->bus->spi))
- ;
- while(LL_SPI_GetRxFIFOLevel(handle->bus->spi) != LL_SPI_RX_FIFO_EMPTY) {
- LL_SPI_ReceiveData8(handle->bus->spi);
- }
- }
- bool furi_hal_spi_bus_rx(
- FuriHalSpiBusHandle* handle,
- uint8_t* buffer,
- size_t size,
- uint32_t timeout) {
- assert(handle);
- assert(handle->bus->current_handle == handle);
- assert(buffer);
- assert(size > 0);
- return furi_hal_spi_bus_trx(handle, buffer, buffer, size, timeout);
- }
- bool furi_hal_spi_bus_tx(
- FuriHalSpiBusHandle* handle,
- uint8_t* buffer,
- size_t size,
- uint32_t timeout) {
- assert(handle);
- assert(handle->bus->current_handle == handle);
- assert(buffer);
- assert(size > 0);
- bool ret = true;
- while(size > 0) {
- if(LL_SPI_IsActiveFlag_TXE(handle->bus->spi)) {
- LL_SPI_TransmitData8(handle->bus->spi, *buffer);
- buffer++;
- size--;
- }
- }
- furi_hal_spi_bus_end_txrx(handle, timeout);
- LL_SPI_ClearFlag_OVR(handle->bus->spi);
- return ret;
- }
- bool furi_hal_spi_bus_trx(
- FuriHalSpiBusHandle* handle,
- uint8_t* tx_buffer,
- uint8_t* rx_buffer,
- size_t size,
- uint32_t timeout) {
- assert(handle);
- assert(handle->bus->current_handle == handle);
- assert(tx_buffer);
- assert(rx_buffer);
- assert(size > 0);
- bool ret = true;
- size_t tx_size = size;
- bool tx_allowed = true;
- while(size > 0) {
- if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE(handle->bus->spi) && tx_allowed) {
- LL_SPI_TransmitData8(handle->bus->spi, *tx_buffer);
- tx_buffer++;
- tx_size--;
- tx_allowed = false;
- }
- if(LL_SPI_IsActiveFlag_RXNE(handle->bus->spi)) {
- *rx_buffer = LL_SPI_ReceiveData8(handle->bus->spi);
- rx_buffer++;
- size--;
- tx_allowed = true;
- }
- }
- furi_hal_spi_bus_end_txrx(handle, timeout);
- return ret;
- }
|