From 9d27ef8901a07ed607d2d6e8cf680453be203601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Tue, 30 Nov 2021 15:09:43 +0300 Subject: [FL-2060] FuriHal: SPI refactoring, flexible bus reconfiguration on fly, same design as i2c. (#853) * FuriHal: SPI refactoring, flexible bus reconfigration on fly, same desiag as i2c. * Lib: update CC1101 driver documentation * FuriHal: update spi symbol names to match naming convention. --- firmware/targets/f6/fatfs/spi_sd_hal.c | 12 +- firmware/targets/f6/fatfs/stm32_adafruit_sd.c | 37 ++-- firmware/targets/f6/fatfs/user_diskio.c | 26 ++- firmware/targets/f6/furi-hal/furi-hal-sd.c | 4 +- firmware/targets/f6/furi-hal/furi-hal-spi-config.c | 209 ++++++++++++++++++--- firmware/targets/f6/furi-hal/furi-hal-spi-config.h | 94 +++++---- firmware/targets/f6/furi-hal/furi-hal-spi-types.h | 62 ++++++ firmware/targets/f6/furi-hal/furi-hal-spi.c | 196 +++++++------------ firmware/targets/f6/furi-hal/furi-hal-subghz.c | 132 ++++++------- firmware/targets/f7/fatfs/spi_sd_hal.c | 12 +- firmware/targets/f7/fatfs/stm32_adafruit_sd.c | 37 ++-- firmware/targets/f7/fatfs/user_diskio.c | 26 ++- firmware/targets/f7/furi-hal/furi-hal-sd.c | 4 +- firmware/targets/f7/furi-hal/furi-hal-spi-config.c | 209 ++++++++++++++++++--- firmware/targets/f7/furi-hal/furi-hal-spi-config.h | 94 +++++---- firmware/targets/f7/furi-hal/furi-hal-spi-types.h | 62 ++++++ firmware/targets/f7/furi-hal/furi-hal-spi.c | 196 +++++++------------ firmware/targets/f7/furi-hal/furi-hal-subghz.c | 132 ++++++------- firmware/targets/furi-hal-include/furi-hal-sd.h | 4 + firmware/targets/furi-hal-include/furi-hal-spi.h | 132 ++++++------- firmware/targets/furi-hal-include/furi-hal.h | 1 + 21 files changed, 988 insertions(+), 693 deletions(-) create mode 100644 firmware/targets/f6/furi-hal/furi-hal-spi-types.h create mode 100644 firmware/targets/f7/furi-hal/furi-hal-spi-types.h (limited to 'firmware') diff --git a/firmware/targets/f6/fatfs/spi_sd_hal.c b/firmware/targets/f6/fatfs/spi_sd_hal.c index 70e9bbf1..7e41799f 100644 --- a/firmware/targets/f6/fatfs/spi_sd_hal.c +++ b/firmware/targets/f6/fatfs/spi_sd_hal.c @@ -7,8 +7,6 @@ const uint32_t SpiTimeout = 1000; uint8_t SD_IO_WriteByte(uint8_t Data); -static const FuriHalSpiDevice* sd_spi_dev = &furi_hal_spi_devices[FuriHalSpiDeviceIdSdCardFast]; - /****************************************************************************** BUS OPERATIONS *******************************************************************************/ @@ -21,7 +19,7 @@ static const FuriHalSpiDevice* sd_spi_dev = &furi_hal_spi_devices[FuriHalSpiDevi * @retval None */ static void SPIx_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t DataLength) { - furi_check(furi_hal_spi_bus_trx(sd_spi_dev->bus, (uint8_t*)DataIn, DataOut, DataLength, SpiTimeout)); + furi_check(furi_hal_spi_bus_trx(furi_hal_sd_spi_handle, (uint8_t*)DataIn, DataOut, DataLength, SpiTimeout)); } /** @@ -30,7 +28,7 @@ static void SPIx_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t * @retval None */ __attribute__((unused)) static void SPIx_Write(uint8_t Value) { - furi_check(furi_hal_spi_bus_tx(sd_spi_dev->bus, (uint8_t*)&Value, 1, SpiTimeout)); + furi_check(furi_hal_spi_bus_tx(furi_hal_sd_spi_handle, (uint8_t*)&Value, 1, SpiTimeout)); } /****************************************************************************** @@ -47,7 +45,7 @@ void SD_IO_Init(void) { uint8_t counter = 0; /* SD chip select high */ - hal_gpio_write(sd_spi_dev->chip_select, true); + hal_gpio_write(furi_hal_sd_spi_handle->cs, true); delay_us(10); /* Send dummy byte 0xFF, 10 times with CS high */ @@ -67,9 +65,9 @@ void SD_IO_CSState(uint8_t val) { /* Some SD Cards are prone to fail if CLK-ed too soon after CS transition. Worst case found: 8us */ if(val == 1) { delay_us(10); // Exit guard time for some SD cards - hal_gpio_write(sd_spi_dev->chip_select, true); + hal_gpio_write(furi_hal_sd_spi_handle->cs, true); } else { - hal_gpio_write(sd_spi_dev->chip_select, false); + hal_gpio_write(furi_hal_sd_spi_handle->cs, false); delay_us(10); // Entry guard time for some SD cards } } diff --git a/firmware/targets/f6/fatfs/stm32_adafruit_sd.c b/firmware/targets/f6/fatfs/stm32_adafruit_sd.c index e90ebd62..0d7ff4c0 100644 --- a/firmware/targets/f6/fatfs/stm32_adafruit_sd.c +++ b/firmware/targets/f6/fatfs/stm32_adafruit_sd.c @@ -91,12 +91,7 @@ #include "stdlib.h" #include "string.h" #include "stdio.h" -#include -#include -#include -#include -#include -#include +#include /** @addtogroup BSP * @{ @@ -284,22 +279,22 @@ static uint8_t SD_ReadData(void); /* Private functions ---------------------------------------------------------*/ void SD_SPI_Bus_To_Down_State(){ - hal_gpio_init_ex(&gpio_spi_d_miso, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); - hal_gpio_init_ex(&gpio_spi_d_mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); - hal_gpio_init_ex(&gpio_spi_d_sck, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); - - hal_gpio_write(&gpio_sdcard_cs, false); - hal_gpio_write(&gpio_spi_d_miso, false); - hal_gpio_write(&gpio_spi_d_mosi, false); - hal_gpio_write(&gpio_spi_d_sck, false); + hal_gpio_init_ex(furi_hal_sd_spi_handle->miso, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); + hal_gpio_init_ex(furi_hal_sd_spi_handle->mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); + hal_gpio_init_ex(furi_hal_sd_spi_handle->sck, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); + + hal_gpio_write(furi_hal_sd_spi_handle->cs, false); + hal_gpio_write(furi_hal_sd_spi_handle->miso, false); + hal_gpio_write(furi_hal_sd_spi_handle->mosi, false); + hal_gpio_write(furi_hal_sd_spi_handle->sck, false); } void SD_SPI_Bus_To_Normal_State(){ - hal_gpio_write(&gpio_sdcard_cs, true); + hal_gpio_write(furi_hal_sd_spi_handle->cs, true); - 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); + hal_gpio_init_ex(furi_hal_sd_spi_handle->miso, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(furi_hal_sd_spi_handle->mosi, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(furi_hal_sd_spi_handle->sck, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); } /** @defgroup STM32_ADAFRUIT_SD_Private_Functions @@ -315,7 +310,8 @@ void SD_SPI_Bus_To_Normal_State(){ */ uint8_t BSP_SD_Init(bool reset_card) { /* Slow speed init */ - const FuriHalSpiDevice* sd_spi_slow_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardSlow); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_slow); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_slow; /* We must reset card in spi_lock context */ if(reset_card) { @@ -344,7 +340,8 @@ uint8_t BSP_SD_Init(bool reset_card) { if(res == BSP_SD_OK) break; } - furi_hal_spi_device_return(sd_spi_slow_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_slow); /* SD initialized and set to SPI mode properly */ return res; diff --git a/firmware/targets/f6/fatfs/user_diskio.c b/firmware/targets/f6/fatfs/user_diskio.c index ca3d60a5..df16245a 100644 --- a/firmware/targets/f6/fatfs/user_diskio.c +++ b/firmware/targets/f6/fatfs/user_diskio.c @@ -35,7 +35,7 @@ /* Includes ------------------------------------------------------------------*/ #include "user_diskio.h" -#include "furi-hal-spi.h" +#include /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ @@ -87,11 +87,13 @@ Diskio_drvTypeDef USER_Driver = { DSTATUS USER_initialize(BYTE pdrv) { /* USER CODE BEGIN INIT */ - const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; DSTATUS status = User_CheckStatus(pdrv); - furi_hal_spi_device_return(sd_spi_fast_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); return status; /* USER CODE END INIT */ @@ -120,7 +122,8 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { /* USER CODE BEGIN READ */ DRESULT res = RES_ERROR; - const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; if(BSP_SD_ReadBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) { /* wait until the read operation is finished */ @@ -129,7 +132,8 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { res = RES_OK; } - furi_hal_spi_device_return(sd_spi_fast_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); return res; /* USER CODE END READ */ @@ -149,7 +153,8 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { /* USER CODE HERE */ DRESULT res = RES_ERROR; - const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; if(BSP_SD_WriteBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) { /* wait until the Write operation is finished */ @@ -158,7 +163,8 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { res = RES_OK; } - furi_hal_spi_device_return(sd_spi_fast_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); return res; /* USER CODE END WRITE */ @@ -180,7 +186,8 @@ DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) { if(Stat & STA_NOINIT) return RES_NOTRDY; - const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; switch(cmd) { /* Make sure that no pending write process */ @@ -213,7 +220,8 @@ DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) { res = RES_PARERR; } - furi_hal_spi_device_return(sd_spi_fast_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); return res; /* USER CODE END IOCTL */ diff --git a/firmware/targets/f6/furi-hal/furi-hal-sd.c b/firmware/targets/f6/furi-hal/furi-hal-sd.c index 01cf9339..82549e16 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-sd.c +++ b/firmware/targets/f6/furi-hal/furi-hal-sd.c @@ -19,4 +19,6 @@ void hal_sd_detect_set_low(void) { bool hal_sd_detect(void) { bool result = !(LL_GPIO_IsInputPinSet(SD_CD_GPIO_Port, SD_CD_Pin)); return result; -} \ No newline at end of file +} + +FuriHalSpiBusHandle* furi_hal_sd_spi_handle = NULL; diff --git a/firmware/targets/f6/furi-hal/furi-hal-spi-config.c b/firmware/targets/f6/furi-hal/furi-hal-spi-config.c index 315d82a2..63253c90 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-spi-config.c +++ b/firmware/targets/f6/furi-hal/furi-hal-spi-config.c @@ -1,10 +1,9 @@ #include #include -#define SPI_R SPI1 -#define SPI_D SPI2 +/* SPI Presets */ -const LL_SPI_InitTypeDef furi_hal_spi_config_nfc = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_2edge_low_8m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -17,7 +16,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_nfc = { .CRCPoly = 7, }; -const LL_SPI_InitTypeDef furi_hal_spi_config_subghz = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_8m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -30,7 +29,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_subghz = { .CRCPoly = 7, }; -const LL_SPI_InitTypeDef furi_hal_spi_config_display = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_4m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -43,10 +42,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_display = { .CRCPoly = 7, }; -/** - * SD Card in fast mode (after init) - */ -const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_16m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -59,10 +55,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast = { .CRCPoly = 7, }; -/** - * SD Card in slow mode (before init) - */ -const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -75,29 +68,187 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = { .CRCPoly = 7, }; -osMutexId_t spi_mutex_d = NULL; -osMutexId_t spi_mutex_r = NULL; +/* SPI Buses */ -const FuriHalSpiBus spi_r = { - .spi=SPI_R, - .mutex=&spi_mutex_r, +osMutexId_t furi_hal_spi_bus_r_mutex = NULL; + +static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { + if (event == FuriHalSpiBusEventInit) { + furi_hal_spi_bus_r_mutex = osMutexNew(NULL); + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); + bus->current_handle = NULL; + } else if (event == FuriHalSpiBusEventDeinit) { + furi_check(osMutexDelete(furi_hal_spi_bus_r_mutex)); + } else if (event == FuriHalSpiBusEventLock) { + furi_check(osMutexAcquire(furi_hal_spi_bus_r_mutex, osWaitForever) == osOK); + } else if (event == FuriHalSpiBusEventUnlock) { + furi_check(osMutexRelease(furi_hal_spi_bus_r_mutex) == osOK); + } else if (event == FuriHalSpiBusEventActivate) { + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); + } else if (event == FuriHalSpiBusEventDeactivate) { + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); + } +} + +FuriHalSpiBus furi_hal_spi_bus_r = { + .spi=SPI1, + .callback = furi_hal_spi_bus_r_event_callback, +}; + +osMutexId_t furi_hal_spi_bus_d_mutex = NULL; + +static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { + if (event == FuriHalSpiBusEventInit) { + furi_hal_spi_bus_d_mutex = osMutexNew(NULL); + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); + bus->current_handle = NULL; + } else if (event == FuriHalSpiBusEventDeinit) { + furi_check(osMutexDelete(furi_hal_spi_bus_d_mutex)); + } else if (event == FuriHalSpiBusEventLock) { + furi_check(osMutexAcquire(furi_hal_spi_bus_d_mutex, osWaitForever) == osOK); + } else if (event == FuriHalSpiBusEventUnlock) { + furi_check(osMutexRelease(furi_hal_spi_bus_d_mutex) == osOK); + } else if (event == FuriHalSpiBusEventActivate) { + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); + } else if (event == FuriHalSpiBusEventDeactivate) { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); + } +} + +FuriHalSpiBus furi_hal_spi_bus_d = { + .spi=SPI2, + .callback = furi_hal_spi_bus_d_event_callback, +}; + +/* SPI Bus Handles */ + +inline static void furi_hal_spi_bus_r_handle_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event, const LL_SPI_InitTypeDef* preset) { + if (event == FuriHalSpiBusHandleEventInit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + } else if (event == FuriHalSpiBusHandleEventDeinit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + } else if (event == FuriHalSpiBusHandleEventActivate) { + LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); + LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); + LL_SPI_Enable(handle->bus->spi); + + hal_gpio_init_ex(handle->miso, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); + hal_gpio_init_ex(handle->mosi, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); + hal_gpio_init_ex(handle->sck, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); + + hal_gpio_write(handle->cs, false); + } else if (event == FuriHalSpiBusHandleEventDeactivate) { + hal_gpio_write(handle->cs, true); + + hal_gpio_init(handle->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + hal_gpio_init(handle->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + hal_gpio_init(handle->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + + LL_SPI_Disable(handle->bus->spi); + } +} + +static void furi_hal_spi_bus_handle_subghz_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_8m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_subghz = { + .bus=&furi_hal_spi_bus_r, + .callback=furi_hal_spi_bus_handle_subghz_event_callback, .miso=&gpio_spi_r_miso, .mosi=&gpio_spi_r_mosi, - .clk=&gpio_spi_r_sck, + .sck=&gpio_spi_r_sck, + .cs=&gpio_subghz_cs, }; -const FuriHalSpiBus spi_d = { - .spi=SPI_D, - .mutex=&spi_mutex_d, +static void furi_hal_spi_bus_handle_nfc_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_2edge_low_8m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_nfc = { + .bus=&furi_hal_spi_bus_r, + .callback=furi_hal_spi_bus_handle_nfc_event_callback, + .miso=&gpio_spi_r_miso, + .mosi=&gpio_spi_r_mosi, + .sck=&gpio_spi_r_sck, + .cs=&gpio_nfc_cs, +}; + +static void furi_hal_spi_bus_handle_external_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_external = { + .bus=&furi_hal_spi_bus_r, + .callback=furi_hal_spi_bus_handle_external_event_callback, + .miso=&gpio_ext_pa6, + .mosi=&gpio_ext_pa7, + .sck=&gpio_ext_pb3, + .cs=&gpio_ext_pa4, +}; + +inline static void furi_hal_spi_bus_d_handle_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event, const LL_SPI_InitTypeDef* preset) { + if (event == FuriHalSpiBusHandleEventInit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh); + + hal_gpio_init_ex(handle->miso, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(handle->mosi, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(handle->sck, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI2); + + } else if (event == FuriHalSpiBusHandleEventDeinit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullUp, GpioSpeedLow); + } else if (event == FuriHalSpiBusHandleEventActivate) { + LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); + LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); + LL_SPI_Enable(handle->bus->spi); + hal_gpio_write(handle->cs, false); + } else if (event == FuriHalSpiBusHandleEventDeactivate) { + hal_gpio_write(handle->cs, true); + LL_SPI_Disable(handle->bus->spi); + } +} + +static void furi_hal_spi_bus_handle_display_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_4m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_display = { + .bus=&furi_hal_spi_bus_d, + .callback=furi_hal_spi_bus_handle_display_event_callback, .miso=&gpio_spi_d_miso, .mosi=&gpio_spi_d_mosi, - .clk=&gpio_spi_d_sck, + .sck=&gpio_spi_d_sck, + .cs=&gpio_display_cs, }; -const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax] = { - { .bus=&spi_r, .config=&furi_hal_spi_config_subghz, .chip_select=&gpio_subghz_cs, }, - { .bus=&spi_d, .config=&furi_hal_spi_config_display, .chip_select=&gpio_display_cs, }, - { .bus=&spi_d, .config=&furi_hal_spi_config_sd_fast, .chip_select=&gpio_sdcard_cs, }, - { .bus=&spi_d, .config=&furi_hal_spi_config_sd_slow, .chip_select=&gpio_sdcard_cs, }, - { .bus=&spi_r, .config=&furi_hal_spi_config_nfc, .chip_select=&gpio_nfc_cs }, +static void furi_hal_spi_bus_handle_sd_fast_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_16m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast = { + .bus=&furi_hal_spi_bus_d, + .callback=furi_hal_spi_bus_handle_sd_fast_event_callback, + .miso=&gpio_spi_d_miso, + .mosi=&gpio_spi_d_mosi, + .sck=&gpio_spi_d_sck, + .cs=&gpio_sdcard_cs, +}; + +static void furi_hal_spi_bus_handle_sd_slow_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow = { + .bus=&furi_hal_spi_bus_d, + .callback=furi_hal_spi_bus_handle_sd_slow_event_callback, + .miso=&gpio_spi_d_miso, + .mosi=&gpio_spi_d_mosi, + .sck=&gpio_spi_d_sck, + .cs=&gpio_sdcard_cs, }; diff --git a/firmware/targets/f6/furi-hal/furi-hal-spi-config.h b/firmware/targets/f6/furi-hal/furi-hal-spi-config.h index 3398474a..d483e625 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-spi-config.h +++ b/firmware/targets/f6/furi-hal/furi-hal-spi-config.h @@ -1,62 +1,60 @@ #pragma once -#include -#include -#include +#include #ifdef __cplusplus extern "C" { #endif -extern const LL_SPI_InitTypeDef furi_hal_spi_config_nfc; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_subghz; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_display; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow; +/** Preset for ST25R916 */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_2edge_low_8m; -/** FURI HAL SPI BUS handler - * Structure content may change at some point - */ -typedef struct { - const SPI_TypeDef* spi; - const osMutexId_t* mutex; - const GpioPin* miso; - const GpioPin* mosi; - const GpioPin* clk; -} FuriHalSpiBus; - -/** FURI HAL SPI Device handler - * Structure content may change at some point - */ -typedef struct { - const FuriHalSpiBus* bus; - const LL_SPI_InitTypeDef* config; - const GpioPin* chip_select; -} FuriHalSpiDevice; - -/** FURI HAL SPI Standard Device IDs */ -typedef enum { - FuriHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */ - FuriHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */ - FuriHalSpiDeviceIdSdCardFast, /** SDCARD: fast mode, after initialization */ - FuriHalSpiDeviceIdSdCardSlow, /** SDCARD: slow mode, before initialization */ - FuriHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */ - - FuriHalSpiDeviceIdMax, /** Service Value, do not use */ -} FuriHalSpiDeviceId; - -/** Furi Hal Spi Bus R - * CC1101, Nfc - */ -extern const FuriHalSpiBus spi_r; +/** Preset for CC1101 */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_8m; + +/** Preset for ST7567 (Display) */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_4m; + +/** Preset for SdCard in fast mode */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_16m; + +/** Preset for SdCard in slow mode */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m; -/** Furi Hal Spi Bus D - * Display, SdCard +/** Furi Hal Spi Bus R (Radio: CC1101, Nfc, External)*/ +extern FuriHalSpiBus furi_hal_spi_bus_r; + +/** Furi Hal Spi Bus D (Display, SdCard) */ +extern FuriHalSpiBus furi_hal_spi_bus_d; + +/** CC1101 on `furi_hal_spi_bus_r` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_subghz; + +/** ST25R3916 on `furi_hal_spi_bus_r` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_nfc; + +/** External on `furi_hal_spi_bus_r` + * Preset: `furi_hal_spi_preset_1edge_low_2m` + * + * miso: pa6 + * mosi: pa7 + * sck: pb3 + * cs: pa4 (software controlled) + * + * @warning not initialized by default, call `furi_hal_spi_bus_handle_init` to initialize + * Bus pins are floating on inactive state, CS high after initialization + * */ -extern const FuriHalSpiBus spi_d; +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_external; + +/** ST7567(Display) on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_display; + +/** SdCard in fast mode on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast; -/** Furi Hal Spi devices */ -extern const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax]; +/** SdCard in slow mode on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow; #ifdef __cplusplus } diff --git a/firmware/targets/f6/furi-hal/furi-hal-spi-types.h b/firmware/targets/f6/furi-hal/furi-hal-spi-types.h new file mode 100644 index 00000000..c7520f4a --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-spi-types.h @@ -0,0 +1,62 @@ +#pragma once + +#include +#include + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct FuriHalSpiBus FuriHalSpiBus; +typedef struct FuriHalSpiBusHandle FuriHalSpiBusHandle; + +/** FuriHal spi bus states */ +typedef enum { + FuriHalSpiBusEventInit, /**< Bus initialization event, called on system start */ + FuriHalSpiBusEventDeinit, /**< Bus deinitialization event, called on system stop */ + FuriHalSpiBusEventLock, /**< Bus lock event, called before activation */ + FuriHalSpiBusEventUnlock, /**< Bus unlock event, called after deactivation */ + FuriHalSpiBusEventActivate, /**< Bus activation event, called before handle activation */ + FuriHalSpiBusEventDeactivate, /**< Bus deactivation event, called after handle deactivation */ +} FuriHalSpiBusEvent; + +/** FuriHal spi bus event callback */ +typedef void (*FuriHalSpiBusEventCallback)(FuriHalSpiBus* bus, FuriHalSpiBusEvent event); + +/** FuriHal spi bus */ +struct FuriHalSpiBus { + SPI_TypeDef* spi; + FuriHalSpiBusEventCallback callback; + FuriHalSpiBusHandle* current_handle; +}; + +/** FuriHal spi handle states */ +typedef enum { + FuriHalSpiBusHandleEventInit, /**< Handle init, called on system start, initialize gpio for idle state */ + FuriHalSpiBusHandleEventDeinit, /**< Handle deinit, called on system stop, deinitialize gpio for default state */ + FuriHalSpiBusHandleEventActivate, /**< Handle activate: connect gpio and apply bus config */ + FuriHalSpiBusHandleEventDeactivate, /**< Handle deactivate: disconnect gpio and reset bus config */ +} FuriHalSpiBusHandleEvent; + +/** FuriHal spi handle event callback */ +typedef void (*FuriHalSpiBusHandleEventCallback)(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event); + +/** FuriHal spi handle */ +struct FuriHalSpiBusHandle { + FuriHalSpiBus* bus; + FuriHalSpiBusHandleEventCallback callback; + const GpioPin* miso; + const GpioPin* mosi; + const GpioPin* sck; + const GpioPin* cs; +}; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/firmware/targets/f6/furi-hal/furi-hal-spi.c b/firmware/targets/f6/furi-hal/furi-hal-spi.c index da7c63df..a0ce7166 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-spi.c +++ b/firmware/targets/f6/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; imutex, 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; } diff --git a/firmware/targets/f6/furi-hal/furi-hal-subghz.c b/firmware/targets/f6/furi-hal/furi-hal-subghz.c index 25fa3b7a..dac4514e 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f6/furi-hal/furi-hal-subghz.c @@ -269,7 +269,7 @@ void furi_hal_subghz_init() { furi_assert(furi_hal_subghz_state == SubGhzStateInit); furi_hal_subghz_state = SubGhzStateIdle; - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); #ifdef FURI_HAL_SUBGHZ_TX_GPIO hal_gpio_init(&FURI_HAL_SUBGHZ_TX_GPIO, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); @@ -277,58 +277,58 @@ void furi_hal_subghz_init() { // Reset hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - cc1101_reset(device); - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); + cc1101_reset(&furi_hal_spi_bus_handle_subghz); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); // Prepare GD0 for power on self test hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); // GD0 low - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW); while(hal_gpio_read(&gpio_cc1101_g0) != false) ; // GD0 high - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); while(hal_gpio_read(&gpio_cc1101_g0) != true) ; // Reset GD0 to floating state - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); // RF switches hal_gpio_init(&gpio_rf_sw_0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); // Go to sleep - cc1101_shutdown(device); + cc1101_shutdown(&furi_hal_spi_bus_handle_subghz); - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); FURI_LOG_I(TAG, "Init OK"); } void furi_hal_subghz_sleep() { furi_assert(furi_hal_subghz_state == SubGhzStateIdle); - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); - cc1101_switch_to_idle(device); + cc1101_switch_to_idle(&furi_hal_spi_bus_handle_subghz); - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - cc1101_shutdown(device); + cc1101_shutdown(&furi_hal_spi_bus_handle_subghz); - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_dump_state() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); printf( "[furi_hal_subghz] cc1101 chip %d, version %d\r\n", - cc1101_get_partnumber(device), - cc1101_get_version(device)); - furi_hal_spi_device_return(device); + cc1101_get_partnumber(&furi_hal_spi_bus_handle_subghz), + cc1101_get_version(&furi_hal_spi_bus_handle_subghz)); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { @@ -350,81 +350,81 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { } void furi_hal_subghz_load_registers(const uint8_t data[][2]) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_reset(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_reset(&furi_hal_spi_bus_handle_subghz); uint32_t i = 0; while(data[i][0]) { - cc1101_write_reg(device, data[i][0], data[i][1]); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, data[i][0], data[i][1]); i++; } - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_load_patable(const uint8_t data[8]) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_set_pa_table(device, data); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_set_pa_table(&furi_hal_spi_bus_handle_subghz, data); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_write_packet(const uint8_t* data, uint8_t size) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_flush_tx(device); - cc1101_write_fifo(device, data, size); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_flush_tx(&furi_hal_spi_bus_handle_subghz); + cc1101_write_fifo(&furi_hal_spi_bus_handle_subghz, data, size); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_flush_rx() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_flush_rx(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_flush_rx(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_read_packet(uint8_t* data, uint8_t* size) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_read_fifo(device, data, size); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_read_fifo(&furi_hal_spi_bus_handle_subghz, data, size); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_shutdown() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); // Reset and shutdown - cc1101_shutdown(device); - furi_hal_spi_device_return(device); + cc1101_shutdown(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_reset() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - cc1101_switch_to_idle(device); - cc1101_reset(device); - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); - furi_hal_spi_device_return(device); + cc1101_switch_to_idle(&furi_hal_spi_bus_handle_subghz); + cc1101_reset(&furi_hal_spi_bus_handle_subghz); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_idle() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_switch_to_idle(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_switch_to_idle(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_rx() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_switch_to_rx(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_switch_to_rx(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } bool furi_hal_subghz_tx() { if(furi_hal_subghz_regulation != SubGhzRegulationTxRx) return false; - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_switch_to_tx(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_switch_to_tx(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); return true; } float furi_hal_subghz_get_rssi() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - int32_t rssi_dec = cc1101_get_rssi(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + int32_t rssi_dec = cc1101_get_rssi(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); float rssi = rssi_dec; if(rssi_dec >= 128) { @@ -461,7 +461,7 @@ uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value) { } uint32_t furi_hal_subghz_set_frequency(uint32_t value) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); //checking regional settings bool txrx = false; @@ -503,37 +503,37 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { furi_hal_subghz_regulation = SubGhzRegulationOnlyRx; } - uint32_t real_frequency = cc1101_set_frequency(device, value); - cc1101_calibrate(device); + uint32_t real_frequency = cc1101_set_frequency(&furi_hal_spi_bus_handle_subghz, value); + cc1101_calibrate(&furi_hal_spi_bus_handle_subghz); while(true) { - CC1101Status status = cc1101_get_status(device); + CC1101Status status = cc1101_get_status(&furi_hal_spi_bus_handle_subghz); if(status.STATE == CC1101StateIDLE) break; } - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); return real_frequency; } void furi_hal_subghz_set_path(FuriHalSubGhzPath path) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); if(path == FuriHalSubGhzPath433) { hal_gpio_write(&gpio_rf_sw_0, 0); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); } else if(path == FuriHalSubGhzPath315) { hal_gpio_write(&gpio_rf_sw_0, 1); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); } else if(path == FuriHalSubGhzPath868) { hal_gpio_write(&gpio_rf_sw_0, 1); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); } else if(path == FuriHalSubGhzPathIsolate) { hal_gpio_write(&gpio_rf_sw_0, 0); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); } else { furi_crash(NULL); } - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } volatile uint32_t furi_hal_subghz_capture_delta_duration = 0; diff --git a/firmware/targets/f7/fatfs/spi_sd_hal.c b/firmware/targets/f7/fatfs/spi_sd_hal.c index 70e9bbf1..7e41799f 100644 --- a/firmware/targets/f7/fatfs/spi_sd_hal.c +++ b/firmware/targets/f7/fatfs/spi_sd_hal.c @@ -7,8 +7,6 @@ const uint32_t SpiTimeout = 1000; uint8_t SD_IO_WriteByte(uint8_t Data); -static const FuriHalSpiDevice* sd_spi_dev = &furi_hal_spi_devices[FuriHalSpiDeviceIdSdCardFast]; - /****************************************************************************** BUS OPERATIONS *******************************************************************************/ @@ -21,7 +19,7 @@ static const FuriHalSpiDevice* sd_spi_dev = &furi_hal_spi_devices[FuriHalSpiDevi * @retval None */ static void SPIx_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t DataLength) { - furi_check(furi_hal_spi_bus_trx(sd_spi_dev->bus, (uint8_t*)DataIn, DataOut, DataLength, SpiTimeout)); + furi_check(furi_hal_spi_bus_trx(furi_hal_sd_spi_handle, (uint8_t*)DataIn, DataOut, DataLength, SpiTimeout)); } /** @@ -30,7 +28,7 @@ static void SPIx_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t * @retval None */ __attribute__((unused)) static void SPIx_Write(uint8_t Value) { - furi_check(furi_hal_spi_bus_tx(sd_spi_dev->bus, (uint8_t*)&Value, 1, SpiTimeout)); + furi_check(furi_hal_spi_bus_tx(furi_hal_sd_spi_handle, (uint8_t*)&Value, 1, SpiTimeout)); } /****************************************************************************** @@ -47,7 +45,7 @@ void SD_IO_Init(void) { uint8_t counter = 0; /* SD chip select high */ - hal_gpio_write(sd_spi_dev->chip_select, true); + hal_gpio_write(furi_hal_sd_spi_handle->cs, true); delay_us(10); /* Send dummy byte 0xFF, 10 times with CS high */ @@ -67,9 +65,9 @@ void SD_IO_CSState(uint8_t val) { /* Some SD Cards are prone to fail if CLK-ed too soon after CS transition. Worst case found: 8us */ if(val == 1) { delay_us(10); // Exit guard time for some SD cards - hal_gpio_write(sd_spi_dev->chip_select, true); + hal_gpio_write(furi_hal_sd_spi_handle->cs, true); } else { - hal_gpio_write(sd_spi_dev->chip_select, false); + hal_gpio_write(furi_hal_sd_spi_handle->cs, false); delay_us(10); // Entry guard time for some SD cards } } diff --git a/firmware/targets/f7/fatfs/stm32_adafruit_sd.c b/firmware/targets/f7/fatfs/stm32_adafruit_sd.c index e90ebd62..0d7ff4c0 100644 --- a/firmware/targets/f7/fatfs/stm32_adafruit_sd.c +++ b/firmware/targets/f7/fatfs/stm32_adafruit_sd.c @@ -91,12 +91,7 @@ #include "stdlib.h" #include "string.h" #include "stdio.h" -#include -#include -#include -#include -#include -#include +#include /** @addtogroup BSP * @{ @@ -284,22 +279,22 @@ static uint8_t SD_ReadData(void); /* Private functions ---------------------------------------------------------*/ void SD_SPI_Bus_To_Down_State(){ - hal_gpio_init_ex(&gpio_spi_d_miso, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); - hal_gpio_init_ex(&gpio_spi_d_mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); - hal_gpio_init_ex(&gpio_spi_d_sck, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); - - hal_gpio_write(&gpio_sdcard_cs, false); - hal_gpio_write(&gpio_spi_d_miso, false); - hal_gpio_write(&gpio_spi_d_mosi, false); - hal_gpio_write(&gpio_spi_d_sck, false); + hal_gpio_init_ex(furi_hal_sd_spi_handle->miso, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); + hal_gpio_init_ex(furi_hal_sd_spi_handle->mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); + hal_gpio_init_ex(furi_hal_sd_spi_handle->sck, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); + + hal_gpio_write(furi_hal_sd_spi_handle->cs, false); + hal_gpio_write(furi_hal_sd_spi_handle->miso, false); + hal_gpio_write(furi_hal_sd_spi_handle->mosi, false); + hal_gpio_write(furi_hal_sd_spi_handle->sck, false); } void SD_SPI_Bus_To_Normal_State(){ - hal_gpio_write(&gpio_sdcard_cs, true); + hal_gpio_write(furi_hal_sd_spi_handle->cs, true); - 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); + hal_gpio_init_ex(furi_hal_sd_spi_handle->miso, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(furi_hal_sd_spi_handle->mosi, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(furi_hal_sd_spi_handle->sck, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); } /** @defgroup STM32_ADAFRUIT_SD_Private_Functions @@ -315,7 +310,8 @@ void SD_SPI_Bus_To_Normal_State(){ */ uint8_t BSP_SD_Init(bool reset_card) { /* Slow speed init */ - const FuriHalSpiDevice* sd_spi_slow_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardSlow); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_slow); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_slow; /* We must reset card in spi_lock context */ if(reset_card) { @@ -344,7 +340,8 @@ uint8_t BSP_SD_Init(bool reset_card) { if(res == BSP_SD_OK) break; } - furi_hal_spi_device_return(sd_spi_slow_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_slow); /* SD initialized and set to SPI mode properly */ return res; diff --git a/firmware/targets/f7/fatfs/user_diskio.c b/firmware/targets/f7/fatfs/user_diskio.c index ca3d60a5..df16245a 100644 --- a/firmware/targets/f7/fatfs/user_diskio.c +++ b/firmware/targets/f7/fatfs/user_diskio.c @@ -35,7 +35,7 @@ /* Includes ------------------------------------------------------------------*/ #include "user_diskio.h" -#include "furi-hal-spi.h" +#include /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ @@ -87,11 +87,13 @@ Diskio_drvTypeDef USER_Driver = { DSTATUS USER_initialize(BYTE pdrv) { /* USER CODE BEGIN INIT */ - const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; DSTATUS status = User_CheckStatus(pdrv); - furi_hal_spi_device_return(sd_spi_fast_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); return status; /* USER CODE END INIT */ @@ -120,7 +122,8 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { /* USER CODE BEGIN READ */ DRESULT res = RES_ERROR; - const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; if(BSP_SD_ReadBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) { /* wait until the read operation is finished */ @@ -129,7 +132,8 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { res = RES_OK; } - furi_hal_spi_device_return(sd_spi_fast_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); return res; /* USER CODE END READ */ @@ -149,7 +153,8 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { /* USER CODE HERE */ DRESULT res = RES_ERROR; - const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; if(BSP_SD_WriteBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) { /* wait until the Write operation is finished */ @@ -158,7 +163,8 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { res = RES_OK; } - furi_hal_spi_device_return(sd_spi_fast_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); return res; /* USER CODE END WRITE */ @@ -180,7 +186,8 @@ DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) { if(Stat & STA_NOINIT) return RES_NOTRDY; - const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; switch(cmd) { /* Make sure that no pending write process */ @@ -213,7 +220,8 @@ DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) { res = RES_PARERR; } - furi_hal_spi_device_return(sd_spi_fast_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); return res; /* USER CODE END IOCTL */ diff --git a/firmware/targets/f7/furi-hal/furi-hal-sd.c b/firmware/targets/f7/furi-hal/furi-hal-sd.c index 01cf9339..82549e16 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-sd.c +++ b/firmware/targets/f7/furi-hal/furi-hal-sd.c @@ -19,4 +19,6 @@ void hal_sd_detect_set_low(void) { bool hal_sd_detect(void) { bool result = !(LL_GPIO_IsInputPinSet(SD_CD_GPIO_Port, SD_CD_Pin)); return result; -} \ No newline at end of file +} + +FuriHalSpiBusHandle* furi_hal_sd_spi_handle = NULL; diff --git a/firmware/targets/f7/furi-hal/furi-hal-spi-config.c b/firmware/targets/f7/furi-hal/furi-hal-spi-config.c index 315d82a2..63253c90 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-spi-config.c +++ b/firmware/targets/f7/furi-hal/furi-hal-spi-config.c @@ -1,10 +1,9 @@ #include #include -#define SPI_R SPI1 -#define SPI_D SPI2 +/* SPI Presets */ -const LL_SPI_InitTypeDef furi_hal_spi_config_nfc = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_2edge_low_8m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -17,7 +16,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_nfc = { .CRCPoly = 7, }; -const LL_SPI_InitTypeDef furi_hal_spi_config_subghz = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_8m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -30,7 +29,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_subghz = { .CRCPoly = 7, }; -const LL_SPI_InitTypeDef furi_hal_spi_config_display = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_4m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -43,10 +42,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_display = { .CRCPoly = 7, }; -/** - * SD Card in fast mode (after init) - */ -const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_16m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -59,10 +55,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast = { .CRCPoly = 7, }; -/** - * SD Card in slow mode (before init) - */ -const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -75,29 +68,187 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = { .CRCPoly = 7, }; -osMutexId_t spi_mutex_d = NULL; -osMutexId_t spi_mutex_r = NULL; +/* SPI Buses */ -const FuriHalSpiBus spi_r = { - .spi=SPI_R, - .mutex=&spi_mutex_r, +osMutexId_t furi_hal_spi_bus_r_mutex = NULL; + +static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { + if (event == FuriHalSpiBusEventInit) { + furi_hal_spi_bus_r_mutex = osMutexNew(NULL); + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); + bus->current_handle = NULL; + } else if (event == FuriHalSpiBusEventDeinit) { + furi_check(osMutexDelete(furi_hal_spi_bus_r_mutex)); + } else if (event == FuriHalSpiBusEventLock) { + furi_check(osMutexAcquire(furi_hal_spi_bus_r_mutex, osWaitForever) == osOK); + } else if (event == FuriHalSpiBusEventUnlock) { + furi_check(osMutexRelease(furi_hal_spi_bus_r_mutex) == osOK); + } else if (event == FuriHalSpiBusEventActivate) { + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); + } else if (event == FuriHalSpiBusEventDeactivate) { + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); + } +} + +FuriHalSpiBus furi_hal_spi_bus_r = { + .spi=SPI1, + .callback = furi_hal_spi_bus_r_event_callback, +}; + +osMutexId_t furi_hal_spi_bus_d_mutex = NULL; + +static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { + if (event == FuriHalSpiBusEventInit) { + furi_hal_spi_bus_d_mutex = osMutexNew(NULL); + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); + bus->current_handle = NULL; + } else if (event == FuriHalSpiBusEventDeinit) { + furi_check(osMutexDelete(furi_hal_spi_bus_d_mutex)); + } else if (event == FuriHalSpiBusEventLock) { + furi_check(osMutexAcquire(furi_hal_spi_bus_d_mutex, osWaitForever) == osOK); + } else if (event == FuriHalSpiBusEventUnlock) { + furi_check(osMutexRelease(furi_hal_spi_bus_d_mutex) == osOK); + } else if (event == FuriHalSpiBusEventActivate) { + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); + } else if (event == FuriHalSpiBusEventDeactivate) { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); + } +} + +FuriHalSpiBus furi_hal_spi_bus_d = { + .spi=SPI2, + .callback = furi_hal_spi_bus_d_event_callback, +}; + +/* SPI Bus Handles */ + +inline static void furi_hal_spi_bus_r_handle_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event, const LL_SPI_InitTypeDef* preset) { + if (event == FuriHalSpiBusHandleEventInit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + } else if (event == FuriHalSpiBusHandleEventDeinit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + } else if (event == FuriHalSpiBusHandleEventActivate) { + LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); + LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); + LL_SPI_Enable(handle->bus->spi); + + hal_gpio_init_ex(handle->miso, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); + hal_gpio_init_ex(handle->mosi, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); + hal_gpio_init_ex(handle->sck, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); + + hal_gpio_write(handle->cs, false); + } else if (event == FuriHalSpiBusHandleEventDeactivate) { + hal_gpio_write(handle->cs, true); + + hal_gpio_init(handle->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + hal_gpio_init(handle->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + hal_gpio_init(handle->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + + LL_SPI_Disable(handle->bus->spi); + } +} + +static void furi_hal_spi_bus_handle_subghz_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_8m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_subghz = { + .bus=&furi_hal_spi_bus_r, + .callback=furi_hal_spi_bus_handle_subghz_event_callback, .miso=&gpio_spi_r_miso, .mosi=&gpio_spi_r_mosi, - .clk=&gpio_spi_r_sck, + .sck=&gpio_spi_r_sck, + .cs=&gpio_subghz_cs, }; -const FuriHalSpiBus spi_d = { - .spi=SPI_D, - .mutex=&spi_mutex_d, +static void furi_hal_spi_bus_handle_nfc_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_2edge_low_8m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_nfc = { + .bus=&furi_hal_spi_bus_r, + .callback=furi_hal_spi_bus_handle_nfc_event_callback, + .miso=&gpio_spi_r_miso, + .mosi=&gpio_spi_r_mosi, + .sck=&gpio_spi_r_sck, + .cs=&gpio_nfc_cs, +}; + +static void furi_hal_spi_bus_handle_external_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_external = { + .bus=&furi_hal_spi_bus_r, + .callback=furi_hal_spi_bus_handle_external_event_callback, + .miso=&gpio_ext_pa6, + .mosi=&gpio_ext_pa7, + .sck=&gpio_ext_pb3, + .cs=&gpio_ext_pa4, +}; + +inline static void furi_hal_spi_bus_d_handle_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event, const LL_SPI_InitTypeDef* preset) { + if (event == FuriHalSpiBusHandleEventInit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh); + + hal_gpio_init_ex(handle->miso, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(handle->mosi, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(handle->sck, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI2); + + } else if (event == FuriHalSpiBusHandleEventDeinit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullUp, GpioSpeedLow); + } else if (event == FuriHalSpiBusHandleEventActivate) { + LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); + LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); + LL_SPI_Enable(handle->bus->spi); + hal_gpio_write(handle->cs, false); + } else if (event == FuriHalSpiBusHandleEventDeactivate) { + hal_gpio_write(handle->cs, true); + LL_SPI_Disable(handle->bus->spi); + } +} + +static void furi_hal_spi_bus_handle_display_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_4m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_display = { + .bus=&furi_hal_spi_bus_d, + .callback=furi_hal_spi_bus_handle_display_event_callback, .miso=&gpio_spi_d_miso, .mosi=&gpio_spi_d_mosi, - .clk=&gpio_spi_d_sck, + .sck=&gpio_spi_d_sck, + .cs=&gpio_display_cs, }; -const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax] = { - { .bus=&spi_r, .config=&furi_hal_spi_config_subghz, .chip_select=&gpio_subghz_cs, }, - { .bus=&spi_d, .config=&furi_hal_spi_config_display, .chip_select=&gpio_display_cs, }, - { .bus=&spi_d, .config=&furi_hal_spi_config_sd_fast, .chip_select=&gpio_sdcard_cs, }, - { .bus=&spi_d, .config=&furi_hal_spi_config_sd_slow, .chip_select=&gpio_sdcard_cs, }, - { .bus=&spi_r, .config=&furi_hal_spi_config_nfc, .chip_select=&gpio_nfc_cs }, +static void furi_hal_spi_bus_handle_sd_fast_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_16m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast = { + .bus=&furi_hal_spi_bus_d, + .callback=furi_hal_spi_bus_handle_sd_fast_event_callback, + .miso=&gpio_spi_d_miso, + .mosi=&gpio_spi_d_mosi, + .sck=&gpio_spi_d_sck, + .cs=&gpio_sdcard_cs, +}; + +static void furi_hal_spi_bus_handle_sd_slow_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow = { + .bus=&furi_hal_spi_bus_d, + .callback=furi_hal_spi_bus_handle_sd_slow_event_callback, + .miso=&gpio_spi_d_miso, + .mosi=&gpio_spi_d_mosi, + .sck=&gpio_spi_d_sck, + .cs=&gpio_sdcard_cs, }; diff --git a/firmware/targets/f7/furi-hal/furi-hal-spi-config.h b/firmware/targets/f7/furi-hal/furi-hal-spi-config.h index 3398474a..d483e625 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-spi-config.h +++ b/firmware/targets/f7/furi-hal/furi-hal-spi-config.h @@ -1,62 +1,60 @@ #pragma once -#include -#include -#include +#include #ifdef __cplusplus extern "C" { #endif -extern const LL_SPI_InitTypeDef furi_hal_spi_config_nfc; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_subghz; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_display; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow; +/** Preset for ST25R916 */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_2edge_low_8m; -/** FURI HAL SPI BUS handler - * Structure content may change at some point - */ -typedef struct { - const SPI_TypeDef* spi; - const osMutexId_t* mutex; - const GpioPin* miso; - const GpioPin* mosi; - const GpioPin* clk; -} FuriHalSpiBus; - -/** FURI HAL SPI Device handler - * Structure content may change at some point - */ -typedef struct { - const FuriHalSpiBus* bus; - const LL_SPI_InitTypeDef* config; - const GpioPin* chip_select; -} FuriHalSpiDevice; - -/** FURI HAL SPI Standard Device IDs */ -typedef enum { - FuriHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */ - FuriHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */ - FuriHalSpiDeviceIdSdCardFast, /** SDCARD: fast mode, after initialization */ - FuriHalSpiDeviceIdSdCardSlow, /** SDCARD: slow mode, before initialization */ - FuriHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */ - - FuriHalSpiDeviceIdMax, /** Service Value, do not use */ -} FuriHalSpiDeviceId; - -/** Furi Hal Spi Bus R - * CC1101, Nfc - */ -extern const FuriHalSpiBus spi_r; +/** Preset for CC1101 */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_8m; + +/** Preset for ST7567 (Display) */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_4m; + +/** Preset for SdCard in fast mode */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_16m; + +/** Preset for SdCard in slow mode */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m; -/** Furi Hal Spi Bus D - * Display, SdCard +/** Furi Hal Spi Bus R (Radio: CC1101, Nfc, External)*/ +extern FuriHalSpiBus furi_hal_spi_bus_r; + +/** Furi Hal Spi Bus D (Display, SdCard) */ +extern FuriHalSpiBus furi_hal_spi_bus_d; + +/** CC1101 on `furi_hal_spi_bus_r` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_subghz; + +/** ST25R3916 on `furi_hal_spi_bus_r` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_nfc; + +/** External on `furi_hal_spi_bus_r` + * Preset: `furi_hal_spi_preset_1edge_low_2m` + * + * miso: pa6 + * mosi: pa7 + * sck: pb3 + * cs: pa4 (software controlled) + * + * @warning not initialized by default, call `furi_hal_spi_bus_handle_init` to initialize + * Bus pins are floating on inactive state, CS high after initialization + * */ -extern const FuriHalSpiBus spi_d; +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_external; + +/** ST7567(Display) on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_display; + +/** SdCard in fast mode on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast; -/** Furi Hal Spi devices */ -extern const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax]; +/** SdCard in slow mode on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow; #ifdef __cplusplus } diff --git a/firmware/targets/f7/furi-hal/furi-hal-spi-types.h b/firmware/targets/f7/furi-hal/furi-hal-spi-types.h new file mode 100644 index 00000000..c7520f4a --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-spi-types.h @@ -0,0 +1,62 @@ +#pragma once + +#include +#include + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct FuriHalSpiBus FuriHalSpiBus; +typedef struct FuriHalSpiBusHandle FuriHalSpiBusHandle; + +/** FuriHal spi bus states */ +typedef enum { + FuriHalSpiBusEventInit, /**< Bus initialization event, called on system start */ + FuriHalSpiBusEventDeinit, /**< Bus deinitialization event, called on system stop */ + FuriHalSpiBusEventLock, /**< Bus lock event, called before activation */ + FuriHalSpiBusEventUnlock, /**< Bus unlock event, called after deactivation */ + FuriHalSpiBusEventActivate, /**< Bus activation event, called before handle activation */ + FuriHalSpiBusEventDeactivate, /**< Bus deactivation event, called after handle deactivation */ +} FuriHalSpiBusEvent; + +/** FuriHal spi bus event callback */ +typedef void (*FuriHalSpiBusEventCallback)(FuriHalSpiBus* bus, FuriHalSpiBusEvent event); + +/** FuriHal spi bus */ +struct FuriHalSpiBus { + SPI_TypeDef* spi; + FuriHalSpiBusEventCallback callback; + FuriHalSpiBusHandle* current_handle; +}; + +/** FuriHal spi handle states */ +typedef enum { + FuriHalSpiBusHandleEventInit, /**< Handle init, called on system start, initialize gpio for idle state */ + FuriHalSpiBusHandleEventDeinit, /**< Handle deinit, called on system stop, deinitialize gpio for default state */ + FuriHalSpiBusHandleEventActivate, /**< Handle activate: connect gpio and apply bus config */ + FuriHalSpiBusHandleEventDeactivate, /**< Handle deactivate: disconnect gpio and reset bus config */ +} FuriHalSpiBusHandleEvent; + +/** FuriHal spi handle event callback */ +typedef void (*FuriHalSpiBusHandleEventCallback)(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event); + +/** FuriHal spi handle */ +struct FuriHalSpiBusHandle { + FuriHalSpiBus* bus; + FuriHalSpiBusHandleEventCallback callback; + const GpioPin* miso; + const GpioPin* mosi; + const GpioPin* sck; + const GpioPin* cs; +}; + +#ifdef __cplusplus +} +#endif \ No newline at end of file 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; imutex, 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; } diff --git a/firmware/targets/f7/furi-hal/furi-hal-subghz.c b/firmware/targets/f7/furi-hal/furi-hal-subghz.c index 25fa3b7a..dac4514e 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f7/furi-hal/furi-hal-subghz.c @@ -269,7 +269,7 @@ void furi_hal_subghz_init() { furi_assert(furi_hal_subghz_state == SubGhzStateInit); furi_hal_subghz_state = SubGhzStateIdle; - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); #ifdef FURI_HAL_SUBGHZ_TX_GPIO hal_gpio_init(&FURI_HAL_SUBGHZ_TX_GPIO, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); @@ -277,58 +277,58 @@ void furi_hal_subghz_init() { // Reset hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - cc1101_reset(device); - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); + cc1101_reset(&furi_hal_spi_bus_handle_subghz); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); // Prepare GD0 for power on self test hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); // GD0 low - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW); while(hal_gpio_read(&gpio_cc1101_g0) != false) ; // GD0 high - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); while(hal_gpio_read(&gpio_cc1101_g0) != true) ; // Reset GD0 to floating state - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); // RF switches hal_gpio_init(&gpio_rf_sw_0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); // Go to sleep - cc1101_shutdown(device); + cc1101_shutdown(&furi_hal_spi_bus_handle_subghz); - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); FURI_LOG_I(TAG, "Init OK"); } void furi_hal_subghz_sleep() { furi_assert(furi_hal_subghz_state == SubGhzStateIdle); - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); - cc1101_switch_to_idle(device); + cc1101_switch_to_idle(&furi_hal_spi_bus_handle_subghz); - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - cc1101_shutdown(device); + cc1101_shutdown(&furi_hal_spi_bus_handle_subghz); - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_dump_state() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); printf( "[furi_hal_subghz] cc1101 chip %d, version %d\r\n", - cc1101_get_partnumber(device), - cc1101_get_version(device)); - furi_hal_spi_device_return(device); + cc1101_get_partnumber(&furi_hal_spi_bus_handle_subghz), + cc1101_get_version(&furi_hal_spi_bus_handle_subghz)); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { @@ -350,81 +350,81 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { } void furi_hal_subghz_load_registers(const uint8_t data[][2]) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_reset(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_reset(&furi_hal_spi_bus_handle_subghz); uint32_t i = 0; while(data[i][0]) { - cc1101_write_reg(device, data[i][0], data[i][1]); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, data[i][0], data[i][1]); i++; } - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_load_patable(const uint8_t data[8]) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_set_pa_table(device, data); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_set_pa_table(&furi_hal_spi_bus_handle_subghz, data); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_write_packet(const uint8_t* data, uint8_t size) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_flush_tx(device); - cc1101_write_fifo(device, data, size); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_flush_tx(&furi_hal_spi_bus_handle_subghz); + cc1101_write_fifo(&furi_hal_spi_bus_handle_subghz, data, size); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_flush_rx() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_flush_rx(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_flush_rx(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_read_packet(uint8_t* data, uint8_t* size) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_read_fifo(device, data, size); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_read_fifo(&furi_hal_spi_bus_handle_subghz, data, size); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_shutdown() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); // Reset and shutdown - cc1101_shutdown(device); - furi_hal_spi_device_return(device); + cc1101_shutdown(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_reset() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - cc1101_switch_to_idle(device); - cc1101_reset(device); - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); - furi_hal_spi_device_return(device); + cc1101_switch_to_idle(&furi_hal_spi_bus_handle_subghz); + cc1101_reset(&furi_hal_spi_bus_handle_subghz); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_idle() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_switch_to_idle(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_switch_to_idle(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_rx() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_switch_to_rx(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_switch_to_rx(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } bool furi_hal_subghz_tx() { if(furi_hal_subghz_regulation != SubGhzRegulationTxRx) return false; - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_switch_to_tx(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_switch_to_tx(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); return true; } float furi_hal_subghz_get_rssi() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - int32_t rssi_dec = cc1101_get_rssi(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + int32_t rssi_dec = cc1101_get_rssi(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); float rssi = rssi_dec; if(rssi_dec >= 128) { @@ -461,7 +461,7 @@ uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value) { } uint32_t furi_hal_subghz_set_frequency(uint32_t value) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); //checking regional settings bool txrx = false; @@ -503,37 +503,37 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { furi_hal_subghz_regulation = SubGhzRegulationOnlyRx; } - uint32_t real_frequency = cc1101_set_frequency(device, value); - cc1101_calibrate(device); + uint32_t real_frequency = cc1101_set_frequency(&furi_hal_spi_bus_handle_subghz, value); + cc1101_calibrate(&furi_hal_spi_bus_handle_subghz); while(true) { - CC1101Status status = cc1101_get_status(device); + CC1101Status status = cc1101_get_status(&furi_hal_spi_bus_handle_subghz); if(status.STATE == CC1101StateIDLE) break; } - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); return real_frequency; } void furi_hal_subghz_set_path(FuriHalSubGhzPath path) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); if(path == FuriHalSubGhzPath433) { hal_gpio_write(&gpio_rf_sw_0, 0); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); } else if(path == FuriHalSubGhzPath315) { hal_gpio_write(&gpio_rf_sw_0, 1); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); } else if(path == FuriHalSubGhzPath868) { hal_gpio_write(&gpio_rf_sw_0, 1); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); } else if(path == FuriHalSubGhzPathIsolate) { hal_gpio_write(&gpio_rf_sw_0, 0); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); } else { furi_crash(NULL); } - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } volatile uint32_t furi_hal_subghz_capture_delta_duration = 0; diff --git a/firmware/targets/furi-hal-include/furi-hal-sd.h b/firmware/targets/furi-hal-include/furi-hal-sd.h index 212ec3ee..9399726e 100644 --- a/firmware/targets/furi-hal-include/furi-hal-sd.h +++ b/firmware/targets/furi-hal-include/furi-hal-sd.h @@ -5,6 +5,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -24,6 +25,9 @@ void hal_sd_detect_set_low(void); */ bool hal_sd_detect(void); +/** Pointer to currently used SPI Handle */ +extern FuriHalSpiBusHandle* furi_hal_sd_spi_handle; + #ifdef __cplusplus } #endif diff --git a/firmware/targets/furi-hal-include/furi-hal-spi.h b/firmware/targets/furi-hal-include/furi-hal-spi.h index e42dcdc4..97913f63 100644 --- a/firmware/targets/furi-hal-include/furi-hal-spi.h +++ b/firmware/targets/furi-hal-include/furi-hal-spi.h @@ -1,106 +1,88 @@ #pragma once -#include "main.h" -#include "furi-hal-spi-config.h" -#include + +#include #include #ifdef __cplusplus extern "C" { #endif -/** - * Init SPI API - */ +/** Initialize SPI HAL */ void furi_hal_spi_init(); -/* Bus Level API */ - -/** Lock SPI bus - * Takes bus mutex, if used +/** Initialize SPI Bus + * + * @param handle pointer to FuriHalSpiBus instance */ -void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus); +void furi_hal_spi_bus_init(FuriHalSpiBus* bus); -/** Unlock SPI bus - * Releases BUS mutex, if used +/** Deinitialize SPI Bus + * + * @param handle pointer to FuriHalSpiBus instance */ -void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus); +void furi_hal_spi_bus_deinit(FuriHalSpiBus* bus); -/** Configure SPI bus - * @param bus - spi bus handler - * @param config - spi configuration structure +/** Initialize SPI Bus Handle + * + * @param handle pointer to FuriHalSpiBusHandle instance */ -void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config); +void furi_hal_spi_bus_handle_init(FuriHalSpiBusHandle* handle); -/** SPI Receive - * @param bus - spi bus handler - * @param buffer - receive buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms +/** Deinitialize SPI Bus Handle + * + * @param handle pointer to FuriHalSpiBusHandle instance */ -bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); +void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle); -/** SPI Transmit - * @param bus - spi bus handler - * @param buffer - transmit buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms +/** Acquire SPI bus + * + * @warning blocking, calls `furi_crash` on programming error, CS transition is up to handler event routine + * + * @param handle pointer to FuriHalSpiBusHandle instance */ -bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); +void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle); -/** SPI Transmit and Receive - * @param bus - spi bus handlere - * @param tx_buffer - device handle - * @param rx_buffer - device handle - * @param size - transaction size - * @param timeout - bus operation timeout in ms +/** Release SPI bus + * + * @warning calls `furi_crash` on programming error, CS transition is up to handler event routine + * + * @param handle pointer to FuriHalSpiBusHandle instance */ -bool furi_hal_spi_bus_trx(const FuriHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); +void furi_hal_spi_release(FuriHalSpiBusHandle* handle); -/* Device Level API */ - -/** Reconfigure SPI bus for device - * @param device - device description - */ -void furi_hal_spi_device_configure(const FuriHalSpiDevice* device); - -/** Get Device handle - * And lock access to the corresponding SPI BUS - * @param device_id - device identifier - * @return device handle - */ -const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id); - -/** Return Device handle - * And unlock access to the corresponding SPI BUS - * @param device - device handle - */ -void furi_hal_spi_device_return(const FuriHalSpiDevice* device); - -/** SPI Recieve - * @param device - device handle - * @param buffer - receive buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms +/** SPI Receive + * + * @param handle pointer to FuriHalSpiBusHandle instance + * @param buffer receive buffer + * @param size transaction size (buffer size) + * @param timeout operation timeout in ms + * + * @return true on sucess */ -bool furi_hal_spi_device_rx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout); +bool furi_hal_spi_bus_rx(FuriHalSpiBusHandle* handle, uint8_t* buffer, size_t size, uint32_t timeout); /** SPI Transmit - * @param device - device handle - * @param buffer - transmit buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms + * + * @param handle pointer to FuriHalSpiBusHandle instance + * @param buffer transmit buffer + * @param size transaction size (buffer size) + * @param timeout operation timeout in ms + * + * @return true on success */ -bool furi_hal_spi_device_tx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout); +bool furi_hal_spi_bus_tx(FuriHalSpiBusHandle* handle, uint8_t* buffer, size_t size, uint32_t timeout); /** SPI Transmit and Receive - * @param device - device handle - * @param tx_buffer - device handle - * @param rx_buffer - device handle - * @param size - transaction size - * @param timeout - bus operation timeout in ms + * + * @param handle pointer to FuriHalSpiBusHandle instance + * @param tx_buffer pointer to tx buffer + * @param rx_buffer pointer to rx buffer + * @param size transaction size (buffer size) + * @param timeout operation timeout in ms + * + * @return true on success */ -bool furi_hal_spi_device_trx(const FuriHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); - +bool furi_hal_spi_bus_trx(FuriHalSpiBusHandle* handle, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); #ifdef __cplusplus } diff --git a/firmware/targets/furi-hal-include/furi-hal.h b/firmware/targets/furi-hal-include/furi-hal.h index eb1fefeb..2357e7fe 100644 --- a/firmware/targets/furi-hal-include/furi-hal.h +++ b/firmware/targets/furi-hal-include/furi-hal.h @@ -14,6 +14,7 @@ template struct STOP_EXTERNING_ME {}; #include "furi-hal-crypto.h" #include "furi-hal-console.h" #include "furi-hal-os.h" +#include "furi-hal-sd.h" #include "furi-hal-i2c.h" #include "furi-hal-resources.h" #include "furi-hal-gpio.h" -- cgit v1.2.3