diff --git a/bootloader/targets/f6/furi-hal/furi-hal-spi-config.c b/bootloader/targets/f6/furi-hal/furi-hal-spi-config.c index 00b06a4f..1d2d0186 100644 --- a/bootloader/targets/f6/furi-hal/furi-hal-spi-config.c +++ b/bootloader/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,40 +68,223 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = { .CRCPoly = 7, }; -const FuriHalSpiBus spi_r = { - .spi = SPI_R, +/* SPI Buses */ + +static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { + if(event == FuriHalSpiBusEventInit) { + 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) { + } else if(event == FuriHalSpiBusEventLock) { + } else if(event == FuriHalSpiBusEventUnlock) { + } 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, +}; + +static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { + if(event == FuriHalSpiBusEventInit) { + 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) { + } else if(event == FuriHalSpiBusEventLock) { + } else if(event == FuriHalSpiBusEventUnlock) { + } 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, +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/bootloader/targets/f6/furi-hal/furi-hal-spi-config.h b/bootloader/targets/f6/furi-hal/furi-hal-spi-config.h index dea1cd65..d483e625 100644 --- a/bootloader/targets/f6/furi-hal/furi-hal-spi-config.h +++ b/bootloader/targets/f6/furi-hal/furi-hal-spi-config.h @@ -1,60 +1,60 @@ #pragma once -#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 +/** 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 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 + * */ -typedef struct { - const SPI_TypeDef* spi; - const GpioPin* miso; - const GpioPin* mosi; - const GpioPin* clk; -} FuriHalSpiBus; +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_external; -/** 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; +/** ST7567(Display) on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_display; -/** 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 */ +/** SdCard in fast mode on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast; - FuriHalSpiDeviceIdMax, /** Service Value, do not use */ -} FuriHalSpiDeviceId; - -/** Furi Hal Spi Bus R - * CC1101, Nfc - */ -extern const FuriHalSpiBus spi_r; - -/** Furi Hal Spi Bus D - * Display, SdCard - */ -extern const FuriHalSpiBus spi_d; - -/** 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/bootloader/targets/f6/furi-hal/furi-hal-spi-types.h b/bootloader/targets/f6/furi-hal/furi-hal-spi-types.h new file mode 100644 index 00000000..7bff3d26 --- /dev/null +++ b/bootloader/targets/f6/furi-hal/furi-hal-spi-types.h @@ -0,0 +1,64 @@ +#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/bootloader/targets/f6/furi-hal/furi-hal-spi.c b/bootloader/targets/f6/furi-hal/furi-hal-spi.c index e36e9230..e3f894b6 100644 --- a/bootloader/targets/f6/furi-hal/furi-hal-spi.c +++ b/bootloader/targets/f6/furi-hal/furi-hal-spi.c @@ -2,239 +2,150 @@ #include "furi-hal-resources.h" #include +#include #include #include #include #include -extern void Enable_SPI(SPI_TypeDef* spi); - void furi_hal_spi_init() { - for(size_t i = 0; i < FuriHalSpiDeviceIdMax; ++i) { - hal_gpio_write(furi_hal_spi_devices[i].chip_select, true); - hal_gpio_init( - furi_hal_spi_devices[i].chip_select, - GpioModeOutputPushPull, - GpioPullNo, - GpioSpeedVeryHigh); - } + furi_hal_spi_bus_init(&furi_hal_spi_bus_r); + furi_hal_spi_bus_init(&furi_hal_spi_bus_d); - hal_gpio_init_ex( - &gpio_spi_r_miso, - GpioModeAltFunctionPushPull, - GpioPullNo, - GpioSpeedVeryHigh, - GpioAltFn5SPI1); - hal_gpio_init_ex( - &gpio_spi_r_mosi, - GpioModeAltFunctionPushPull, - GpioPullNo, - GpioSpeedVeryHigh, - GpioAltFn5SPI1); - hal_gpio_init_ex( - &gpio_spi_r_sck, - GpioModeAltFunctionPushPull, - GpioPullNo, - GpioSpeedVeryHigh, - GpioAltFn5SPI1); - - hal_gpio_init_ex( - &gpio_spi_d_miso, - GpioModeAltFunctionPushPull, - GpioPullUp, - GpioSpeedVeryHigh, - GpioAltFn5SPI2); - hal_gpio_init_ex( - &gpio_spi_d_mosi, - GpioModeAltFunctionPushPull, - GpioPullUp, - GpioSpeedVeryHigh, - GpioAltFn5SPI2); - hal_gpio_init_ex( - &gpio_spi_d_sck, - GpioModeAltFunctionPushPull, - GpioPullUp, - GpioSpeedVeryHigh, - GpioAltFn5SPI2); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_nfc); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_display); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_slow); } -void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus) { +void furi_hal_spi_bus_init(FuriHalSpiBus* bus) { assert(bus); + bus->callback(bus, FuriHalSpiBusEventInit); } -void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus) { +void furi_hal_spi_bus_deinit(FuriHalSpiBus* bus) { assert(bus); + bus->callback(bus, FuriHalSpiBusEventDeinit); } -void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config) { - assert(bus); - 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_init(FuriHalSpiBusHandle* handle) { + assert(handle); + handle->callback(handle, FuriHalSpiBusHandleEventInit); } -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) +void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle) { + assert(handle); + handle->callback(handle, FuriHalSpiBusHandleEventDeinit); +} + +void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle) { + assert(handle); + + handle->bus->callback(handle->bus, FuriHalSpiBusEventLock); + handle->bus->callback(handle->bus, FuriHalSpiBusEventActivate); + + assert(handle->bus->current_handle == NULL); + + handle->bus->current_handle = handle; + handle->callback(handle, FuriHalSpiBusHandleEventActivate); +} + +void furi_hal_spi_release(FuriHalSpiBusHandle* handle) { + assert(handle); + assert(handle->bus->current_handle == handle); + + // Handle event and unset handle + handle->callback(handle, FuriHalSpiBusHandleEventDeactivate); + handle->bus->current_handle = NULL; + + // Bus events + handle->bus->callback(handle->bus, FuriHalSpiBusEventDeactivate); + handle->bus->callback(handle->bus, FuriHalSpiBusEventUnlock); +} + +static void furi_hal_spi_bus_end_txrx(FuriHalSpiBusHandle* handle, uint32_t timeout) { + while(LL_SPI_GetTxFIFOLevel(handle->bus->spi) != LL_SPI_TX_FIFO_EMPTY) ; - while(LL_SPI_IsActiveFlag_BSY((SPI_TypeDef*)bus->spi)) + while(LL_SPI_IsActiveFlag_BSY(handle->bus->spi)) ; - while(LL_SPI_GetRxFIFOLevel((SPI_TypeDef*)bus->spi) != LL_SPI_RX_FIFO_EMPTY) { - LL_SPI_ReceiveData8((SPI_TypeDef*)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) { - assert(bus); +bool furi_hal_spi_bus_rx( + FuriHalSpiBusHandle* handle, + uint8_t* buffer, + size_t size, + uint32_t timeout) { + assert(handle); + assert(handle->bus->current_handle == handle); assert(buffer); assert(size > 0); - return furi_hal_spi_bus_trx(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) { - assert(bus); +bool furi_hal_spi_bus_tx( + FuriHalSpiBusHandle* handle, + uint8_t* buffer, + size_t size, + uint32_t timeout) { + assert(handle); + assert(handle->bus->current_handle == handle); assert(buffer); assert(size > 0); bool ret = true; while(size > 0) { - if(LL_SPI_IsActiveFlag_TXE((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, + FuriHalSpiBusHandle* handle, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { - assert(bus); + assert(handle); + assert(handle->bus->current_handle == handle); assert(tx_buffer); assert(rx_buffer); assert(size > 0); + bool ret = true; size_t tx_size = size; bool tx_allowed = true; while(size > 0) { - if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE((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) { - assert(device); - assert(device->config); - - furi_hal_spi_bus_configure(device->bus, device->config); -} - -const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id) { - assert(device_id < FuriHalSpiDeviceIdMax); - - const FuriHalSpiDevice* device = &furi_hal_spi_devices[device_id]; - 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) { - assert(device); - assert(buffer); - 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) { - assert(device); - assert(buffer); - 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) { - assert(device); - assert(tx_buffer); - assert(rx_buffer); - 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/bootloader/targets/f6/furi-hal/furi-hal-spi.h b/bootloader/targets/f6/furi-hal/furi-hal-spi.h deleted file mode 100644 index 8027eb5d..00000000 --- a/bootloader/targets/f6/furi-hal/furi-hal-spi.h +++ /dev/null @@ -1,129 +0,0 @@ -#pragma once - -#include "main.h" - -#include "furi-hal-spi-config.h" -#include - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Init SPI API - */ -void furi_hal_spi_init(); - -/* Bus Level API */ - -/** Lock SPI bus - * Takes bus mutex, if used - */ -void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus); - -/** Unlock SPI bus - * Releases BUS mutex, if used - */ -void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus); - -/** - * Configure SPI bus - * @param bus - spi bus handler - * @param config - spi configuration structure - */ -void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config); - -/** SPI Receive - * @param bus - spi bus handler - * @param buffer - receive buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); - -/** SPI Transmit - * @param bus - spi bus handler - * @param buffer - transmit buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); - -/** 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 - */ -bool furi_hal_spi_bus_trx( - const FuriHalSpiBus* bus, - uint8_t* tx_buffer, - uint8_t* rx_buffer, - size_t size, - uint32_t timeout); - -/* 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 - */ -bool furi_hal_spi_device_rx( - const FuriHalSpiDevice* device, - 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 - */ -bool furi_hal_spi_device_tx( - const FuriHalSpiDevice* device, - 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 - */ -bool furi_hal_spi_device_trx( - const FuriHalSpiDevice* device, - uint8_t* tx_buffer, - uint8_t* rx_buffer, - size_t size, - uint32_t timeout); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/bootloader/targets/f7/furi-hal/furi-hal-spi-config.c b/bootloader/targets/f7/furi-hal/furi-hal-spi-config.c index 00b06a4f..1d2d0186 100644 --- a/bootloader/targets/f7/furi-hal/furi-hal-spi-config.c +++ b/bootloader/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,40 +68,223 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = { .CRCPoly = 7, }; -const FuriHalSpiBus spi_r = { - .spi = SPI_R, +/* SPI Buses */ + +static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { + if(event == FuriHalSpiBusEventInit) { + 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) { + } else if(event == FuriHalSpiBusEventLock) { + } else if(event == FuriHalSpiBusEventUnlock) { + } 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, +}; + +static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { + if(event == FuriHalSpiBusEventInit) { + 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) { + } else if(event == FuriHalSpiBusEventLock) { + } else if(event == FuriHalSpiBusEventUnlock) { + } 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, +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/bootloader/targets/f7/furi-hal/furi-hal-spi-config.h b/bootloader/targets/f7/furi-hal/furi-hal-spi-config.h index dea1cd65..d483e625 100644 --- a/bootloader/targets/f7/furi-hal/furi-hal-spi-config.h +++ b/bootloader/targets/f7/furi-hal/furi-hal-spi-config.h @@ -1,60 +1,60 @@ #pragma once -#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 +/** 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 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 + * */ -typedef struct { - const SPI_TypeDef* spi; - const GpioPin* miso; - const GpioPin* mosi; - const GpioPin* clk; -} FuriHalSpiBus; +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_external; -/** 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; +/** ST7567(Display) on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_display; -/** 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 */ +/** SdCard in fast mode on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast; - FuriHalSpiDeviceIdMax, /** Service Value, do not use */ -} FuriHalSpiDeviceId; - -/** Furi Hal Spi Bus R - * CC1101, Nfc - */ -extern const FuriHalSpiBus spi_r; - -/** Furi Hal Spi Bus D - * Display, SdCard - */ -extern const FuriHalSpiBus spi_d; - -/** 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/bootloader/targets/f7/furi-hal/furi-hal-spi-types.h b/bootloader/targets/f7/furi-hal/furi-hal-spi-types.h new file mode 100644 index 00000000..7bff3d26 --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal-spi-types.h @@ -0,0 +1,64 @@ +#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/bootloader/targets/f7/furi-hal/furi-hal-spi.c b/bootloader/targets/f7/furi-hal/furi-hal-spi.c index e36e9230..e3f894b6 100644 --- a/bootloader/targets/f7/furi-hal/furi-hal-spi.c +++ b/bootloader/targets/f7/furi-hal/furi-hal-spi.c @@ -2,239 +2,150 @@ #include "furi-hal-resources.h" #include +#include #include #include #include #include -extern void Enable_SPI(SPI_TypeDef* spi); - void furi_hal_spi_init() { - for(size_t i = 0; i < FuriHalSpiDeviceIdMax; ++i) { - hal_gpio_write(furi_hal_spi_devices[i].chip_select, true); - hal_gpio_init( - furi_hal_spi_devices[i].chip_select, - GpioModeOutputPushPull, - GpioPullNo, - GpioSpeedVeryHigh); - } + furi_hal_spi_bus_init(&furi_hal_spi_bus_r); + furi_hal_spi_bus_init(&furi_hal_spi_bus_d); - hal_gpio_init_ex( - &gpio_spi_r_miso, - GpioModeAltFunctionPushPull, - GpioPullNo, - GpioSpeedVeryHigh, - GpioAltFn5SPI1); - hal_gpio_init_ex( - &gpio_spi_r_mosi, - GpioModeAltFunctionPushPull, - GpioPullNo, - GpioSpeedVeryHigh, - GpioAltFn5SPI1); - hal_gpio_init_ex( - &gpio_spi_r_sck, - GpioModeAltFunctionPushPull, - GpioPullNo, - GpioSpeedVeryHigh, - GpioAltFn5SPI1); - - hal_gpio_init_ex( - &gpio_spi_d_miso, - GpioModeAltFunctionPushPull, - GpioPullUp, - GpioSpeedVeryHigh, - GpioAltFn5SPI2); - hal_gpio_init_ex( - &gpio_spi_d_mosi, - GpioModeAltFunctionPushPull, - GpioPullUp, - GpioSpeedVeryHigh, - GpioAltFn5SPI2); - hal_gpio_init_ex( - &gpio_spi_d_sck, - GpioModeAltFunctionPushPull, - GpioPullUp, - GpioSpeedVeryHigh, - GpioAltFn5SPI2); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_nfc); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_display); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_slow); } -void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus) { +void furi_hal_spi_bus_init(FuriHalSpiBus* bus) { assert(bus); + bus->callback(bus, FuriHalSpiBusEventInit); } -void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus) { +void furi_hal_spi_bus_deinit(FuriHalSpiBus* bus) { assert(bus); + bus->callback(bus, FuriHalSpiBusEventDeinit); } -void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config) { - assert(bus); - 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_init(FuriHalSpiBusHandle* handle) { + assert(handle); + handle->callback(handle, FuriHalSpiBusHandleEventInit); } -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) +void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle) { + assert(handle); + handle->callback(handle, FuriHalSpiBusHandleEventDeinit); +} + +void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle) { + assert(handle); + + handle->bus->callback(handle->bus, FuriHalSpiBusEventLock); + handle->bus->callback(handle->bus, FuriHalSpiBusEventActivate); + + assert(handle->bus->current_handle == NULL); + + handle->bus->current_handle = handle; + handle->callback(handle, FuriHalSpiBusHandleEventActivate); +} + +void furi_hal_spi_release(FuriHalSpiBusHandle* handle) { + assert(handle); + assert(handle->bus->current_handle == handle); + + // Handle event and unset handle + handle->callback(handle, FuriHalSpiBusHandleEventDeactivate); + handle->bus->current_handle = NULL; + + // Bus events + handle->bus->callback(handle->bus, FuriHalSpiBusEventDeactivate); + handle->bus->callback(handle->bus, FuriHalSpiBusEventUnlock); +} + +static void furi_hal_spi_bus_end_txrx(FuriHalSpiBusHandle* handle, uint32_t timeout) { + while(LL_SPI_GetTxFIFOLevel(handle->bus->spi) != LL_SPI_TX_FIFO_EMPTY) ; - while(LL_SPI_IsActiveFlag_BSY((SPI_TypeDef*)bus->spi)) + while(LL_SPI_IsActiveFlag_BSY(handle->bus->spi)) ; - while(LL_SPI_GetRxFIFOLevel((SPI_TypeDef*)bus->spi) != LL_SPI_RX_FIFO_EMPTY) { - LL_SPI_ReceiveData8((SPI_TypeDef*)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) { - assert(bus); +bool furi_hal_spi_bus_rx( + FuriHalSpiBusHandle* handle, + uint8_t* buffer, + size_t size, + uint32_t timeout) { + assert(handle); + assert(handle->bus->current_handle == handle); assert(buffer); assert(size > 0); - return furi_hal_spi_bus_trx(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) { - assert(bus); +bool furi_hal_spi_bus_tx( + FuriHalSpiBusHandle* handle, + uint8_t* buffer, + size_t size, + uint32_t timeout) { + assert(handle); + assert(handle->bus->current_handle == handle); assert(buffer); assert(size > 0); bool ret = true; while(size > 0) { - if(LL_SPI_IsActiveFlag_TXE((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, + FuriHalSpiBusHandle* handle, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { - assert(bus); + assert(handle); + assert(handle->bus->current_handle == handle); assert(tx_buffer); assert(rx_buffer); assert(size > 0); + bool ret = true; size_t tx_size = size; bool tx_allowed = true; while(size > 0) { - if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE((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) { - assert(device); - assert(device->config); - - furi_hal_spi_bus_configure(device->bus, device->config); -} - -const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id) { - assert(device_id < FuriHalSpiDeviceIdMax); - - const FuriHalSpiDevice* device = &furi_hal_spi_devices[device_id]; - 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) { - assert(device); - assert(buffer); - 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) { - assert(device); - assert(buffer); - 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) { - assert(device); - assert(tx_buffer); - assert(rx_buffer); - 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/bootloader/targets/f7/furi-hal/furi-hal-spi.h b/bootloader/targets/f7/furi-hal/furi-hal-spi.h deleted file mode 100644 index 8027eb5d..00000000 --- a/bootloader/targets/f7/furi-hal/furi-hal-spi.h +++ /dev/null @@ -1,129 +0,0 @@ -#pragma once - -#include "main.h" - -#include "furi-hal-spi-config.h" -#include - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Init SPI API - */ -void furi_hal_spi_init(); - -/* Bus Level API */ - -/** Lock SPI bus - * Takes bus mutex, if used - */ -void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus); - -/** Unlock SPI bus - * Releases BUS mutex, if used - */ -void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus); - -/** - * Configure SPI bus - * @param bus - spi bus handler - * @param config - spi configuration structure - */ -void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config); - -/** SPI Receive - * @param bus - spi bus handler - * @param buffer - receive buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); - -/** SPI Transmit - * @param bus - spi bus handler - * @param buffer - transmit buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); - -/** 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 - */ -bool furi_hal_spi_bus_trx( - const FuriHalSpiBus* bus, - uint8_t* tx_buffer, - uint8_t* rx_buffer, - size_t size, - uint32_t timeout); - -/* 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 - */ -bool furi_hal_spi_device_rx( - const FuriHalSpiDevice* device, - 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 - */ -bool furi_hal_spi_device_tx( - const FuriHalSpiDevice* device, - 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 - */ -bool furi_hal_spi_device_trx( - const FuriHalSpiDevice* device, - uint8_t* tx_buffer, - uint8_t* rx_buffer, - size_t size, - uint32_t timeout); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/bootloader/targets/furi-hal-include/furi-hal-spi.h b/bootloader/targets/furi-hal-include/furi-hal-spi.h new file mode 100644 index 00000000..b097bdd9 --- /dev/null +++ b/bootloader/targets/furi-hal-include/furi-hal-spi.h @@ -0,0 +1,102 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Initialize SPI HAL */ +void furi_hal_spi_init(); + +/** Initialize SPI Bus + * + * @param handle pointer to FuriHalSpiBus instance + */ +void furi_hal_spi_bus_init(FuriHalSpiBus* bus); + +/** Deinitialize SPI Bus + * + * @param handle pointer to FuriHalSpiBus instance + */ +void furi_hal_spi_bus_deinit(FuriHalSpiBus* bus); + +/** Initialize SPI Bus Handle + * + * @param handle pointer to FuriHalSpiBusHandle instance + */ +void furi_hal_spi_bus_handle_init(FuriHalSpiBusHandle* handle); + +/** Deinitialize SPI Bus Handle + * + * @param handle pointer to FuriHalSpiBusHandle instance + */ +void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle); + +/** 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 + */ +void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle); + +/** Release SPI bus + * + * @warning calls `furi_crash` on programming error, CS transition is up to handler event routine + * + * @param handle pointer to FuriHalSpiBusHandle instance + */ +void furi_hal_spi_release(FuriHalSpiBusHandle* handle); + +/** 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_bus_rx( + FuriHalSpiBusHandle* handle, + uint8_t* buffer, + size_t size, + uint32_t timeout); + +/** SPI Transmit + * + * @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_bus_tx( + FuriHalSpiBusHandle* handle, + uint8_t* buffer, + size_t size, + uint32_t timeout); + +/** SPI Transmit and Receive + * + * @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_bus_trx( + FuriHalSpiBusHandle* handle, + uint8_t* tx_buffer, + uint8_t* rx_buffer, + size_t size, + uint32_t timeout); + +#ifdef __cplusplus +} +#endif \ No newline at end of file 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_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(&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_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 +/** 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 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 + * */ -typedef struct { - const SPI_TypeDef* spi; - const osMutexId_t* mutex; - const GpioPin* miso; - const GpioPin* mosi; - const GpioPin* clk; -} FuriHalSpiBus; +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_external; -/** 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; +/** ST7567(Display) on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_display; -/** 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 */ +/** SdCard in fast mode on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast; - FuriHalSpiDeviceIdMax, /** Service Value, do not use */ -} FuriHalSpiDeviceId; - -/** Furi Hal Spi Bus R - * CC1101, Nfc - */ -extern const FuriHalSpiBus spi_r; - -/** Furi Hal Spi Bus D - * Display, SdCard - */ -extern const FuriHalSpiBus spi_d; - -/** 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); - - 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_init(FuriHalSpiBusHandle* handle) { + furi_assert(handle); + handle->callback(handle, FuriHalSpiBusHandleEventInit); } -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_bus_handle_deinit(FuriHalSpiBusHandle* handle) { + furi_assert(handle); + handle->callback(handle, FuriHalSpiBusHandleEventDeinit); +} + +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_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(&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_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 +/** 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 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 + * */ -typedef struct { - const SPI_TypeDef* spi; - const osMutexId_t* mutex; - const GpioPin* miso; - const GpioPin* mosi; - const GpioPin* clk; -} FuriHalSpiBus; +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_external; -/** 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; +/** ST7567(Display) on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_display; -/** 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 */ +/** SdCard in fast mode on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast; - FuriHalSpiDeviceIdMax, /** Service Value, do not use */ -} FuriHalSpiDeviceId; - -/** Furi Hal Spi Bus R - * CC1101, Nfc - */ -extern const FuriHalSpiBus spi_r; - -/** Furi Hal Spi Bus D - * Display, SdCard - */ -extern const FuriHalSpiBus spi_d; - -/** 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); - - 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_init(FuriHalSpiBusHandle* handle) { + furi_assert(handle); + handle->callback(handle, FuriHalSpiBusHandleEventInit); } -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_bus_handle_deinit(FuriHalSpiBusHandle* handle) { + furi_assert(handle); + handle->callback(handle, FuriHalSpiBusHandleEventDeinit); +} + +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); + +/** Deinitialize SPI Bus Handle + * + * @param handle pointer to FuriHalSpiBusHandle instance + */ +void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle); + +/** 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 + */ +void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle); + +/** Release SPI bus + * + * @warning calls `furi_crash` on programming error, CS transition is up to handler event routine + * + * @param handle pointer to FuriHalSpiBusHandle instance + */ +void furi_hal_spi_release(FuriHalSpiBusHandle* handle); /** SPI Receive - * @param bus - spi bus handler - * @param buffer - receive buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms + * + * @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_bus_rx(const FuriHalSpiBus* bus, 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 bus - spi bus handler - * @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_bus_tx(const FuriHalSpiBus* bus, 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 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 + * + * @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_bus_trx(const FuriHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); - -/* 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 - */ -bool furi_hal_spi_device_rx(const FuriHalSpiDevice* device, 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 - */ -bool furi_hal_spi_device_tx(const FuriHalSpiDevice* device, 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 - */ -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" diff --git a/lib/ST25RFAL002/platform.c b/lib/ST25RFAL002/platform.c index 58363cac..5e9dd5d2 100644 --- a/lib/ST25RFAL002/platform.c +++ b/lib/ST25RFAL002/platform.c @@ -7,7 +7,6 @@ static osThreadAttr_t platform_irq_thread_attr; static volatile osThreadId_t platform_irq_thread_id = NULL; static volatile PlatformIrqCallback platform_irq_callback = NULL; -static FuriHalSpiDevice* platform_st25r3916 = NULL; static const GpioPin pin = {ST25R_INT_PORT, ST25R_INT_PIN}; void nfc_isr(void* _ctx) { @@ -49,14 +48,13 @@ void platformSetIrqCallback(PlatformIrqCallback callback) { } HAL_StatusTypeDef platformSpiTxRx(const uint8_t *txBuf, uint8_t *rxBuf, uint16_t len) { - furi_assert(platform_st25r3916); bool ret = false; if (txBuf && rxBuf) { - ret = furi_hal_spi_bus_trx(platform_st25r3916->bus, (uint8_t*)txBuf, rxBuf, len, 1000); + ret = furi_hal_spi_bus_trx(&furi_hal_spi_bus_handle_nfc, (uint8_t*)txBuf, rxBuf, len, 1000); } else if (txBuf) { - ret = furi_hal_spi_bus_tx(platform_st25r3916->bus, (uint8_t*)txBuf, len, 1000); + ret = furi_hal_spi_bus_tx(&furi_hal_spi_bus_handle_nfc, (uint8_t*)txBuf, len, 1000); } else if (rxBuf) { - ret = furi_hal_spi_bus_rx(platform_st25r3916->bus, (uint8_t*)rxBuf, len, 1000); + ret = furi_hal_spi_bus_rx(&furi_hal_spi_bus_handle_nfc, (uint8_t*)rxBuf, len, 1000); } if(!ret) { @@ -68,15 +66,9 @@ HAL_StatusTypeDef platformSpiTxRx(const uint8_t *txBuf, uint8_t *rxBuf, uint16_t } void platformProtectST25RComm() { - // Don't check platform_st25r3916 since spi device is used simultaneously from nfc worker - // thread and platformIrqWorker thread with the highest priority - - // furi_assert(platform_st25r3916 == NULL); - platform_st25r3916 = (FuriHalSpiDevice*)furi_hal_spi_device_get(FuriHalSpiDeviceIdNfc); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_nfc); } void platformUnprotectST25RComm() { - // furi_assert(platform_st25r3916); - furi_hal_spi_device_return(platform_st25r3916); - // platform_st25r3916 = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_nfc); } diff --git a/lib/drivers/cc1101.c b/lib/drivers/cc1101.c index 0d5a23df..af37dea9 100644 --- a/lib/drivers/cc1101.c +++ b/lib/drivers/cc1101.c @@ -4,180 +4,164 @@ #include #include -CC1101Status cc1101_strobe(const FuriHalSpiDevice* device, uint8_t strobe) { +CC1101Status cc1101_strobe(FuriHalSpiBusHandle* handle, uint8_t strobe) { uint8_t tx[1] = { strobe }; CC1101Status rx[1] = { 0 }; - hal_gpio_write(device->chip_select, false); - while(hal_gpio_read(device->bus->miso)); - furi_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 1, CC1101_TIMEOUT); - hal_gpio_write(device->chip_select, true); + while(hal_gpio_read(handle->miso)); + furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, 1, CC1101_TIMEOUT); assert(rx[0].CHIP_RDYn == 0); return rx[0]; } -CC1101Status cc1101_write_reg(const FuriHalSpiDevice* device, uint8_t reg, uint8_t data) { +CC1101Status cc1101_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data) { uint8_t tx[2] = { reg, data }; CC1101Status rx[2] = { 0 }; - hal_gpio_write(device->chip_select, false); - while(hal_gpio_read(device->bus->miso)); - furi_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); - hal_gpio_write(device->chip_select, true); + while(hal_gpio_read(handle->miso)); + furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); assert((rx[0].CHIP_RDYn|rx[1].CHIP_RDYn) == 0); return rx[1]; } -CC1101Status cc1101_read_reg(const FuriHalSpiDevice* device, uint8_t reg, uint8_t* data) { +CC1101Status cc1101_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data) { assert(sizeof(CC1101Status) == 1); uint8_t tx[2] = { reg|CC1101_READ, 0}; CC1101Status rx[2] = { 0 }; - hal_gpio_write(device->chip_select, false); - while(hal_gpio_read(device->bus->miso)); - furi_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); - hal_gpio_write(device->chip_select, true); + while(hal_gpio_read(handle->miso)); + furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); assert((rx[0].CHIP_RDYn) == 0); *data = *(uint8_t*)&rx[1]; return rx[0]; } -uint8_t cc1101_get_partnumber(const FuriHalSpiDevice* device) { +uint8_t cc1101_get_partnumber(FuriHalSpiBusHandle* handle) { uint8_t partnumber=0; - cc1101_read_reg(device, CC1101_STATUS_PARTNUM|CC1101_BURST, &partnumber); + cc1101_read_reg(handle, CC1101_STATUS_PARTNUM|CC1101_BURST, &partnumber); return partnumber; } -uint8_t cc1101_get_version(const FuriHalSpiDevice* device) { +uint8_t cc1101_get_version(FuriHalSpiBusHandle* handle) { uint8_t version=0; - cc1101_read_reg(device, CC1101_STATUS_VERSION|CC1101_BURST, &version); + cc1101_read_reg(handle, CC1101_STATUS_VERSION|CC1101_BURST, &version); return version; } -uint8_t cc1101_get_rssi(const FuriHalSpiDevice* device) { +uint8_t cc1101_get_rssi(FuriHalSpiBusHandle* handle) { uint8_t rssi=0; - cc1101_read_reg(device, CC1101_STATUS_RSSI|CC1101_BURST, &rssi); + cc1101_read_reg(handle, CC1101_STATUS_RSSI|CC1101_BURST, &rssi); return rssi; } -void cc1101_reset(const FuriHalSpiDevice* device) { - hal_gpio_write(device->chip_select, false); +void cc1101_reset(FuriHalSpiBusHandle* handle) { delay_us(1000); - hal_gpio_write(device->chip_select, true); delay_us(1000); - cc1101_strobe(device, CC1101_STROBE_SRES); + cc1101_strobe(handle, CC1101_STROBE_SRES); } -CC1101Status cc1101_get_status(const FuriHalSpiDevice* device) { - return cc1101_strobe(device, CC1101_STROBE_SNOP); +CC1101Status cc1101_get_status(FuriHalSpiBusHandle* handle) { + return cc1101_strobe(handle, CC1101_STROBE_SNOP); } -void cc1101_shutdown(const FuriHalSpiDevice* device) { - cc1101_strobe(device, CC1101_STROBE_SPWD); +void cc1101_shutdown(FuriHalSpiBusHandle* handle) { + cc1101_strobe(handle, CC1101_STROBE_SPWD); } -void cc1101_calibrate(const FuriHalSpiDevice* device) { - cc1101_strobe(device, CC1101_STROBE_SCAL); +void cc1101_calibrate(FuriHalSpiBusHandle* handle) { + cc1101_strobe(handle, CC1101_STROBE_SCAL); } -void cc1101_switch_to_idle(const FuriHalSpiDevice* device) { - cc1101_strobe(device, CC1101_STROBE_SIDLE); +void cc1101_switch_to_idle(FuriHalSpiBusHandle* handle) { + cc1101_strobe(handle, CC1101_STROBE_SIDLE); } -void cc1101_switch_to_rx(const FuriHalSpiDevice* device) { - cc1101_strobe(device, CC1101_STROBE_SRX); +void cc1101_switch_to_rx(FuriHalSpiBusHandle* handle) { + cc1101_strobe(handle, CC1101_STROBE_SRX); } -void cc1101_switch_to_tx(const FuriHalSpiDevice* device) { - cc1101_strobe(device, CC1101_STROBE_STX); +void cc1101_switch_to_tx(FuriHalSpiBusHandle* handle) { + cc1101_strobe(handle, CC1101_STROBE_STX); } -void cc1101_flush_rx(const FuriHalSpiDevice* device) { - cc1101_strobe(device, CC1101_STROBE_SFRX); +void cc1101_flush_rx(FuriHalSpiBusHandle* handle) { + cc1101_strobe(handle, CC1101_STROBE_SFRX); } -void cc1101_flush_tx(const FuriHalSpiDevice* device) { - cc1101_strobe(device, CC1101_STROBE_SFTX); +void cc1101_flush_tx(FuriHalSpiBusHandle* handle) { + cc1101_strobe(handle, CC1101_STROBE_SFTX); } -uint32_t cc1101_set_frequency(const FuriHalSpiDevice* device, uint32_t value) { +uint32_t cc1101_set_frequency(FuriHalSpiBusHandle* handle, uint32_t value) { uint64_t real_value = (uint64_t)value * CC1101_FDIV / CC1101_QUARTZ; // Sanity check assert((real_value & CC1101_FMASK) == real_value); - cc1101_write_reg(device, CC1101_FREQ2, (real_value >> 16) & 0xFF); - cc1101_write_reg(device, CC1101_FREQ1, (real_value >> 8 ) & 0xFF); - cc1101_write_reg(device, CC1101_FREQ0, (real_value >> 0 ) & 0xFF); + cc1101_write_reg(handle, CC1101_FREQ2, (real_value >> 16) & 0xFF); + cc1101_write_reg(handle, CC1101_FREQ1, (real_value >> 8 ) & 0xFF); + cc1101_write_reg(handle, CC1101_FREQ0, (real_value >> 0 ) & 0xFF); uint64_t real_frequency = real_value * CC1101_QUARTZ / CC1101_FDIV; return (uint32_t)real_frequency; } -uint32_t cc1101_set_intermediate_frequency(const FuriHalSpiDevice* device, uint32_t value) { +uint32_t cc1101_set_intermediate_frequency(FuriHalSpiBusHandle* handle, uint32_t value) { uint64_t real_value = value * CC1101_IFDIV / CC1101_QUARTZ; assert((real_value & 0xFF) == real_value); - cc1101_write_reg(device, CC1101_FSCTRL0, (real_value >> 0 ) & 0xFF); + cc1101_write_reg(handle, CC1101_FSCTRL0, (real_value >> 0 ) & 0xFF); uint64_t real_frequency = real_value * CC1101_QUARTZ / CC1101_IFDIV; return (uint32_t)real_frequency; } -void cc1101_set_pa_table(const FuriHalSpiDevice* device, const uint8_t value[8]) { +void cc1101_set_pa_table(FuriHalSpiBusHandle* handle, const uint8_t value[8]) { uint8_t tx[9] = { CC1101_PATABLE | CC1101_BURST }; CC1101Status rx[9] = { 0 }; memcpy(&tx[1], &value[0], 8); - hal_gpio_write(device->chip_select, false); - while(hal_gpio_read(device->bus->miso)); - furi_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, sizeof(rx), CC1101_TIMEOUT); - hal_gpio_write(device->chip_select, true); + while(hal_gpio_read(handle->miso)); + furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, sizeof(rx), CC1101_TIMEOUT); assert((rx[0].CHIP_RDYn|rx[8].CHIP_RDYn) == 0); } -uint8_t cc1101_write_fifo(const FuriHalSpiDevice* device, const uint8_t* data, uint8_t size) { +uint8_t cc1101_write_fifo(FuriHalSpiBusHandle* handle, const uint8_t* data, uint8_t size) { uint8_t buff_tx[64]; uint8_t buff_rx[64]; buff_tx[0] = CC1101_FIFO | CC1101_BURST; memcpy(&buff_tx[1], data, size); // Start transaction - hal_gpio_write(device->chip_select, false); // Wait IC to become ready - while(hal_gpio_read(device->bus->miso)); + while(hal_gpio_read(handle->miso)); // Tell IC what we want - furi_hal_spi_bus_trx(device->bus, buff_tx, (uint8_t*) buff_rx, size + 1, CC1101_TIMEOUT); - - // Finish transaction - hal_gpio_write(device->chip_select, true); + furi_hal_spi_bus_trx(handle, buff_tx, (uint8_t*) buff_rx, size + 1, CC1101_TIMEOUT); return size; } -uint8_t cc1101_read_fifo(const FuriHalSpiDevice* device, uint8_t* data, uint8_t* size) { +uint8_t cc1101_read_fifo(FuriHalSpiBusHandle* handle, uint8_t* data, uint8_t* size) { uint8_t buff_tx[64]; buff_tx[0] = CC1101_FIFO | CC1101_READ | CC1101_BURST; uint8_t buff_rx[2]; // Start transaction - hal_gpio_write(device->chip_select, false); // Wait IC to become ready - while(hal_gpio_read(device->bus->miso)); + while(hal_gpio_read(handle->miso)); // First byte - packet length - furi_hal_spi_bus_trx(device->bus, buff_tx, buff_rx, 2, CC1101_TIMEOUT); + furi_hal_spi_bus_trx(handle, buff_tx, buff_rx, 2, CC1101_TIMEOUT); *size = buff_rx[1]; - furi_hal_spi_bus_trx(device->bus, &buff_tx[1], data, *size, CC1101_TIMEOUT); - cc1101_flush_rx(device); + furi_hal_spi_bus_trx(handle, &buff_tx[1], data, *size, CC1101_TIMEOUT); + cc1101_flush_rx(handle); - hal_gpio_write(device->chip_select, true); return *size; } diff --git a/lib/drivers/cc1101.h b/lib/drivers/cc1101.h index 295e4b61..f51373d6 100644 --- a/lib/drivers/cc1101.h +++ b/lib/drivers/cc1101.h @@ -13,131 +13,167 @@ extern "C" { /* Low level API */ /** Strobe command to the device - * @param device - pointer to FuriHalSpiDevice - * @param strobe - command to execute - * @return device status + * + * @param handle - pointer to FuriHalSpiHandle + * @param strobe - command to execute + * + * @return device status */ -CC1101Status cc1101_strobe(const FuriHalSpiDevice* device, uint8_t strobe); +CC1101Status cc1101_strobe(FuriHalSpiBusHandle* handle, uint8_t strobe); /** Write device register - * @param device - pointer to FuriHalSpiDevice - * @param reg - register - * @param data - data to write - * @return device status + * + * @param handle - pointer to FuriHalSpiHandle + * @param reg - register + * @param data - data to write + * + * @return device status */ -CC1101Status cc1101_write_reg(const FuriHalSpiDevice* device, uint8_t reg, uint8_t data); +CC1101Status cc1101_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data); /** Read device register - * @param device - pointer to FuriHalSpiDevice - * @param reg - register - * @param[out] data - pointer to data - * @return device status + * + * @param handle - pointer to FuriHalSpiHandle + * @param reg - register + * @param[out] data - pointer to data + * + * @return device status */ -CC1101Status cc1101_read_reg(const FuriHalSpiDevice* device, uint8_t reg, uint8_t* data); +CC1101Status cc1101_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data); /* High level API */ /** Reset - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle */ -void cc1101_reset(const FuriHalSpiDevice* device); +void cc1101_reset(FuriHalSpiBusHandle* handle); /** Get status - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle + * + * @return CC1101Status structure */ -CC1101Status cc1101_get_status(const FuriHalSpiDevice* device); +CC1101Status cc1101_get_status(FuriHalSpiBusHandle* handle); /** Enable shutdown mode - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle */ -void cc1101_shutdown(const FuriHalSpiDevice* device); +void cc1101_shutdown(FuriHalSpiBusHandle* handle); /** Get Partnumber - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle + * + * @return part number id */ -uint8_t cc1101_get_partnumber(const FuriHalSpiDevice* device); +uint8_t cc1101_get_partnumber(FuriHalSpiBusHandle* handle); /** Get Version - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle + * + * @return version */ -uint8_t cc1101_get_version(const FuriHalSpiDevice* device); +uint8_t cc1101_get_version(FuriHalSpiBusHandle* handle); /** Get raw RSSI value - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle + * + * @return rssi value */ -uint8_t cc1101_get_rssi(const FuriHalSpiDevice* device); +uint8_t cc1101_get_rssi(FuriHalSpiBusHandle* handle); /** Calibrate oscillator - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle */ -void cc1101_calibrate(const FuriHalSpiDevice* device); +void cc1101_calibrate(FuriHalSpiBusHandle* handle); /** Switch to idle - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle */ -void cc1101_switch_to_idle(const FuriHalSpiDevice* device); +void cc1101_switch_to_idle(FuriHalSpiBusHandle* handle); /** Switch to RX - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle */ -void cc1101_switch_to_rx(const FuriHalSpiDevice* device); +void cc1101_switch_to_rx(FuriHalSpiBusHandle* handle); /** Switch to TX - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle */ -void cc1101_switch_to_tx(const FuriHalSpiDevice* device); +void cc1101_switch_to_tx(FuriHalSpiBusHandle* handle); /** Flush RX FIFO - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle */ -void cc1101_flush_rx(const FuriHalSpiDevice* device); +void cc1101_flush_rx(FuriHalSpiBusHandle* handle); /** Flush TX FIFO - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle */ -void cc1101_flush_tx(const FuriHalSpiDevice* device); +void cc1101_flush_tx(FuriHalSpiBusHandle* handle); /** Set Frequency - * @param device - pointer to FuriHalSpiDevice - * @param value - frequency in herz - * @return real frequency that were synthesized + * + * @param handle - pointer to FuriHalSpiHandle + * @param value - frequency in herz + * + * @return real frequency that were synthesized */ -uint32_t cc1101_set_frequency(const FuriHalSpiDevice* device, uint32_t value); +uint32_t cc1101_set_frequency(FuriHalSpiBusHandle* handle, uint32_t value); /** Set Intermediate Frequency - * @param device - pointer to FuriHalSpiDevice - * @param value - frequency in herz - * @return real inermediate frequency that were synthesized + * + * @param handle - pointer to FuriHalSpiHandle + * @param value - frequency in herz + * + * @return real inermediate frequency that were synthesized */ -uint32_t cc1101_set_intermediate_frequency(const FuriHalSpiDevice* device, uint32_t value); +uint32_t cc1101_set_intermediate_frequency(FuriHalSpiBusHandle* handle, uint32_t value); /** Set Power Amplifier level table, ramp - * @param device - pointer to FuriHalSpiDevice - * @param value - array of power level values + * + * @param handle - pointer to FuriHalSpiHandle + * @param value - array of power level values */ -void cc1101_set_pa_table(const FuriHalSpiDevice* device, const uint8_t value[8]); +void cc1101_set_pa_table(FuriHalSpiBusHandle* handle, const uint8_t value[8]); /** Set Power Amplifier level table, ramp - * @param device - pointer to FuriHalSpiDevice - * @param value - array of power level values + * + * @param handle - pointer to FuriHalSpiHandle + * @param value - array of power level values */ -void cc1101_set_pa_table(const FuriHalSpiDevice* device, const uint8_t value[8]); +void cc1101_set_pa_table(FuriHalSpiBusHandle* handle, const uint8_t value[8]); /** Write FIFO - * @param device - pointer to FuriHalSpiDevice - * @param data, pointer to byte array - * @param size, write bytes count - * @return size, written bytes count + * + * @param handle - pointer to FuriHalSpiHandle + * @param data pointer to byte array + * @param size write bytes count + * + * @return size, written bytes count */ -uint8_t cc1101_write_fifo(const FuriHalSpiDevice* device, const uint8_t* data, uint8_t size); +uint8_t cc1101_write_fifo(FuriHalSpiBusHandle* handle, const uint8_t* data, uint8_t size); /** Read FIFO - * @param device - pointer to FuriHalSpiDevice - * @param data, pointer to byte array - * @param size, bytes to read from fifo - * @return size, read bytes count + * + * @param handle - pointer to FuriHalSpiHandle + * @param data pointer to byte array + * @param size bytes to read from fifo + * + * @return size, read bytes count */ -uint8_t cc1101_read_fifo(const FuriHalSpiDevice* device, uint8_t* data, uint8_t* size); +uint8_t cc1101_read_fifo(FuriHalSpiBusHandle* handle, uint8_t* data, uint8_t* size); #ifdef __cplusplus } diff --git a/lib/u8g2/u8g2_glue.c b/lib/u8g2/u8g2_glue.c index e2ca8a9d..7d45a03e 100644 --- a/lib/u8g2/u8g2_glue.c +++ b/lib/u8g2/u8g2_glue.c @@ -2,8 +2,6 @@ #include -static FuriHalSpiDevice* u8g2_periphery_display = NULL; - uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) { switch(msg) { case U8X8_MSG_GPIO_AND_DELAY_INIT: @@ -31,7 +29,7 @@ uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, vo uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) { switch(msg) { case U8X8_MSG_BYTE_SEND: - furi_hal_spi_bus_tx(u8g2_periphery_display->bus, (uint8_t*)arg_ptr, arg_int, 10000); + furi_hal_spi_bus_tx(&furi_hal_spi_bus_handle_display, (uint8_t*)arg_ptr, arg_int, 10000); break; case U8X8_MSG_BYTE_SET_DC: hal_gpio_write(&gpio_display_di, arg_int); @@ -39,16 +37,10 @@ uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ case U8X8_MSG_BYTE_INIT: break; case U8X8_MSG_BYTE_START_TRANSFER: - furi_assert(u8g2_periphery_display == NULL); - u8g2_periphery_display = - (FuriHalSpiDevice*)furi_hal_spi_device_get(FuriHalSpiDeviceIdDisplay); - hal_gpio_write(u8g2_periphery_display->chip_select, false); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_display); break; case U8X8_MSG_BYTE_END_TRANSFER: - furi_assert(u8g2_periphery_display); - hal_gpio_write(u8g2_periphery_display->chip_select, true); - furi_hal_spi_device_return(u8g2_periphery_display); - u8g2_periphery_display = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_display); break; default: return 0;