diff options
Diffstat (limited to 'firmware/targets/f7/furi-hal/furi-hal-spi.c')
-rw-r--r-- | firmware/targets/f7/furi-hal/furi-hal-spi.c | 196 |
1 files changed, 67 insertions, 129 deletions
diff --git a/firmware/targets/f7/furi-hal/furi-hal-spi.c b/firmware/targets/f7/furi-hal/furi-hal-spi.c index da7c63df..a0ce7166 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-spi.c +++ b/firmware/targets/f7/furi-hal/furi-hal-spi.c @@ -12,89 +12,104 @@ #define TAG "FuriHalSpi" void furi_hal_spi_init() { - // Spi structure is const, but mutex is not - // Need some hell-ish casting to make it work - *(osMutexId_t*)spi_r.mutex = osMutexNew(NULL); - *(osMutexId_t*)spi_d.mutex = osMutexNew(NULL); - // - for (size_t i=0; i<FuriHalSpiDeviceIdMax; ++i) { - hal_gpio_write(furi_hal_spi_devices[i].chip_select, true); - hal_gpio_init( - furi_hal_spi_devices[i].chip_select, - GpioModeOutputPushPull, - GpioPullNo, - GpioSpeedVeryHigh - ); - } - - hal_gpio_init_ex(&gpio_spi_r_miso, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); - hal_gpio_init_ex(&gpio_spi_r_mosi, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); - hal_gpio_init_ex(&gpio_spi_r_sck, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); + furi_hal_spi_bus_init(&furi_hal_spi_bus_r); + furi_hal_spi_bus_init(&furi_hal_spi_bus_d); - hal_gpio_init_ex(&gpio_spi_d_miso, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); - hal_gpio_init_ex(&gpio_spi_d_mosi, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); - hal_gpio_init_ex(&gpio_spi_d_sck, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); + 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); FURI_LOG_I(TAG, "Init OK"); } -void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus) { +void furi_hal_spi_bus_init(FuriHalSpiBus* bus) { furi_assert(bus); - furi_check(osMutexAcquire(*bus->mutex, osWaitForever) == osOK); + bus->callback(bus, FuriHalSpiBusEventInit); } -void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus) { +void furi_hal_spi_bus_deinit(FuriHalSpiBus* bus) { furi_assert(bus); - furi_check(osMutexRelease(*bus->mutex) == osOK); + bus->callback(bus, FuriHalSpiBusEventDeinit); } -void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config) { - furi_assert(bus); +void furi_hal_spi_bus_handle_init(FuriHalSpiBusHandle* handle) { + furi_assert(handle); + handle->callback(handle, FuriHalSpiBusHandleEventInit); +} - LL_SPI_DeInit((SPI_TypeDef*)bus->spi); - LL_SPI_Init((SPI_TypeDef*)bus->spi, (LL_SPI_InitTypeDef*)config); - LL_SPI_SetRxFIFOThreshold((SPI_TypeDef*)bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); - LL_SPI_Enable((SPI_TypeDef*)bus->spi); +void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle) { + furi_assert(handle); + handle->callback(handle, FuriHalSpiBusHandleEventDeinit); } -void furi_hal_spi_bus_end_txrx(const FuriHalSpiBus* bus, uint32_t timeout) { - while(LL_SPI_GetTxFIFOLevel((SPI_TypeDef *)bus->spi) != LL_SPI_TX_FIFO_EMPTY); - while(LL_SPI_IsActiveFlag_BSY((SPI_TypeDef *)bus->spi)); - while(LL_SPI_GetRxFIFOLevel((SPI_TypeDef *)bus->spi) != LL_SPI_RX_FIFO_EMPTY) { - LL_SPI_ReceiveData8((SPI_TypeDef *)bus->spi); +void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle) { + furi_assert(handle); + + handle->bus->callback(handle->bus, FuriHalSpiBusEventLock); + handle->bus->callback(handle->bus, FuriHalSpiBusEventActivate); + + furi_assert(handle->bus->current_handle == NULL); + + handle->bus->current_handle = handle; + handle->callback(handle, FuriHalSpiBusHandleEventActivate); +} + +void furi_hal_spi_release(FuriHalSpiBusHandle* handle) { + furi_assert(handle); + furi_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(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { - furi_assert(bus); +bool furi_hal_spi_bus_rx(FuriHalSpiBusHandle* handle, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(handle); + furi_assert(handle->bus->current_handle == handle); furi_assert(buffer); furi_assert(size > 0); - return furi_hal_spi_bus_trx(bus, buffer, buffer, size, timeout); + return furi_hal_spi_bus_trx(handle, buffer, buffer, size, timeout); } -bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { - furi_assert(bus); +bool furi_hal_spi_bus_tx(FuriHalSpiBusHandle* handle, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(handle); + furi_assert(handle->bus->current_handle == handle); furi_assert(buffer); furi_assert(size > 0); bool ret = true; while(size > 0) { - if (LL_SPI_IsActiveFlag_TXE((SPI_TypeDef *)bus->spi)) { - LL_SPI_TransmitData8((SPI_TypeDef *)bus->spi, *buffer); + if (LL_SPI_IsActiveFlag_TXE(handle->bus->spi)) { + LL_SPI_TransmitData8(handle->bus->spi, *buffer); buffer++; size--; } } - furi_hal_spi_bus_end_txrx(bus, timeout); - LL_SPI_ClearFlag_OVR((SPI_TypeDef *)bus->spi); + furi_hal_spi_bus_end_txrx(handle, timeout); + LL_SPI_ClearFlag_OVR(handle->bus->spi); return ret; } -bool furi_hal_spi_bus_trx(const FuriHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { - furi_assert(bus); +bool furi_hal_spi_bus_trx(FuriHalSpiBusHandle* handle, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { + furi_assert(handle); + furi_assert(handle->bus->current_handle == handle); furi_assert(tx_buffer); furi_assert(rx_buffer); furi_assert(size > 0); @@ -104,99 +119,22 @@ bool furi_hal_spi_bus_trx(const FuriHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* bool tx_allowed = true; while(size > 0) { - if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE((SPI_TypeDef *)bus->spi) && tx_allowed) { - LL_SPI_TransmitData8((SPI_TypeDef *)bus->spi, *tx_buffer); + 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((SPI_TypeDef *)bus->spi)) { - *rx_buffer = LL_SPI_ReceiveData8((SPI_TypeDef *)bus->spi); + 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(bus, timeout); - - return ret; -} - -void furi_hal_spi_device_configure(const FuriHalSpiDevice* device) { - furi_assert(device); - furi_assert(device->config); - - furi_hal_spi_bus_configure(device->bus, device->config); -} - -const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id) { - furi_assert(device_id < FuriHalSpiDeviceIdMax); - - const FuriHalSpiDevice* device = &furi_hal_spi_devices[device_id]; - furi_assert(device); - furi_hal_spi_bus_lock(device->bus); - furi_hal_spi_device_configure(device); - - return device; -} - -void furi_hal_spi_device_return(const FuriHalSpiDevice* device) { - furi_hal_spi_bus_unlock(device->bus); -} - -bool furi_hal_spi_device_rx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) { - furi_assert(device); - furi_assert(buffer); - furi_assert(size > 0); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, false); - } - - bool ret = furi_hal_spi_bus_rx(device->bus, buffer, size, timeout); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, true); - } - - return ret; -} - -bool furi_hal_spi_device_tx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) { - furi_assert(device); - furi_assert(buffer); - furi_assert(size > 0); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, false); - } - - bool ret = furi_hal_spi_bus_tx(device->bus, buffer, size, timeout); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, true); - } - - return ret; -} - -bool furi_hal_spi_device_trx(const FuriHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { - furi_assert(device); - furi_assert(tx_buffer); - furi_assert(rx_buffer); - furi_assert(size > 0); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, false); - } - - bool ret = furi_hal_spi_bus_trx(device->bus, tx_buffer, rx_buffer, size, timeout); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, true); - } + furi_hal_spi_bus_end_txrx(handle, timeout); return ret; } |