Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/flipperzero-firmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorあく <alleteam@gmail.com>2021-11-30 15:09:43 +0300
committerGitHub <noreply@github.com>2021-11-30 15:09:43 +0300
commit9d27ef8901a07ed607d2d6e8cf680453be203601 (patch)
treeb3261310c8da7c3b73c0a0338bbeb1cd3a1fd2df /firmware
parentd86125c7f7b73330d75316f5996de94cee373bfd (diff)
[FL-2060] FuriHal: SPI refactoring, flexible bus reconfiguration on fly, same design as i2c. (#853)
* FuriHal: SPI refactoring, flexible bus reconfigration on fly, same desiag as i2c. * Lib: update CC1101 driver documentation * FuriHal: update spi symbol names to match naming convention.
Diffstat (limited to 'firmware')
-rw-r--r--firmware/targets/f6/fatfs/spi_sd_hal.c12
-rw-r--r--firmware/targets/f6/fatfs/stm32_adafruit_sd.c37
-rw-r--r--firmware/targets/f6/fatfs/user_diskio.c26
-rw-r--r--firmware/targets/f6/furi-hal/furi-hal-sd.c4
-rw-r--r--firmware/targets/f6/furi-hal/furi-hal-spi-config.c209
-rw-r--r--firmware/targets/f6/furi-hal/furi-hal-spi-config.h94
-rw-r--r--firmware/targets/f6/furi-hal/furi-hal-spi-types.h62
-rw-r--r--firmware/targets/f6/furi-hal/furi-hal-spi.c196
-rw-r--r--firmware/targets/f6/furi-hal/furi-hal-subghz.c132
-rw-r--r--firmware/targets/f7/fatfs/spi_sd_hal.c12
-rw-r--r--firmware/targets/f7/fatfs/stm32_adafruit_sd.c37
-rw-r--r--firmware/targets/f7/fatfs/user_diskio.c26
-rw-r--r--firmware/targets/f7/furi-hal/furi-hal-sd.c4
-rw-r--r--firmware/targets/f7/furi-hal/furi-hal-spi-config.c209
-rw-r--r--firmware/targets/f7/furi-hal/furi-hal-spi-config.h94
-rw-r--r--firmware/targets/f7/furi-hal/furi-hal-spi-types.h62
-rw-r--r--firmware/targets/f7/furi-hal/furi-hal-spi.c196
-rw-r--r--firmware/targets/f7/furi-hal/furi-hal-subghz.c132
-rw-r--r--firmware/targets/furi-hal-include/furi-hal-sd.h4
-rw-r--r--firmware/targets/furi-hal-include/furi-hal-spi.h132
-rw-r--r--firmware/targets/furi-hal-include/furi-hal.h1
21 files changed, 988 insertions, 693 deletions
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 <furi-hal-spi.h>
-#include <furi-hal-gpio.h>
-#include <furi-hal-resources.h>
-#include <furi-hal-power.h>
-#include <furi-hal-delay.h>
-#include <furi-hal-sd.h>
+#include <furi-hal.h>
/** @addtogroup BSP
* @{
@@ -284,22 +279,22 @@ static uint8_t SD_ReadData(void);
/* Private functions ---------------------------------------------------------*/
void SD_SPI_Bus_To_Down_State(){
- hal_gpio_init_ex(&gpio_spi_d_miso, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused);
- hal_gpio_init_ex(&gpio_spi_d_mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused);
- hal_gpio_init_ex(&gpio_spi_d_sck, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused);
-
- hal_gpio_write(&gpio_sdcard_cs, false);
- hal_gpio_write(&gpio_spi_d_miso, false);
- hal_gpio_write(&gpio_spi_d_mosi, false);
- hal_gpio_write(&gpio_spi_d_sck, false);
+ hal_gpio_init_ex(furi_hal_sd_spi_handle->miso, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused);
+ hal_gpio_init_ex(furi_hal_sd_spi_handle->mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused);
+ hal_gpio_init_ex(furi_hal_sd_spi_handle->sck, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused);
+
+ hal_gpio_write(furi_hal_sd_spi_handle->cs, false);
+ hal_gpio_write(furi_hal_sd_spi_handle->miso, false);
+ hal_gpio_write(furi_hal_sd_spi_handle->mosi, false);
+ hal_gpio_write(furi_hal_sd_spi_handle->sck, false);
}
void SD_SPI_Bus_To_Normal_State(){
- hal_gpio_write(&gpio_sdcard_cs, true);
+ hal_gpio_write(furi_hal_sd_spi_handle->cs, true);
- hal_gpio_init_ex(&gpio_spi_d_miso, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2);
- hal_gpio_init_ex(&gpio_spi_d_mosi, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2);
- hal_gpio_init_ex(&gpio_spi_d_sck, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2);
+ hal_gpio_init_ex(furi_hal_sd_spi_handle->miso, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2);
+ hal_gpio_init_ex(furi_hal_sd_spi_handle->mosi, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2);
+ hal_gpio_init_ex(furi_hal_sd_spi_handle->sck, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2);
}
/** @defgroup STM32_ADAFRUIT_SD_Private_Functions
@@ -315,7 +310,8 @@ void SD_SPI_Bus_To_Normal_State(){
*/
uint8_t BSP_SD_Init(bool reset_card) {
/* Slow speed init */
- const FuriHalSpiDevice* sd_spi_slow_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardSlow);
+ furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_slow);
+ furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_slow;
/* We must reset card in spi_lock context */
if(reset_card) {
@@ -344,7 +340,8 @@ uint8_t BSP_SD_Init(bool reset_card) {
if(res == BSP_SD_OK) break;
}
- furi_hal_spi_device_return(sd_spi_slow_dev);
+ furi_hal_sd_spi_handle = NULL;
+ furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_slow);
/* SD initialized and set to SPI mode properly */
return res;
diff --git a/firmware/targets/f6/fatfs/user_diskio.c b/firmware/targets/f6/fatfs/user_diskio.c
index ca3d60a5..df16245a 100644
--- a/firmware/targets/f6/fatfs/user_diskio.c
+++ b/firmware/targets/f6/fatfs/user_diskio.c
@@ -35,7 +35,7 @@
/* Includes ------------------------------------------------------------------*/
#include "user_diskio.h"
-#include "furi-hal-spi.h"
+#include <furi-hal.h>
/* 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 <furi-hal-spi-config.h>
#include <furi-hal-resources.h>
-#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 <furi-hal-gpio.h>
-#include <stm32wbxx_ll_spi.h>
-#include <cmsis_os2.h>
+#include <furi-hal-spi-types.h>
#ifdef __cplusplus
extern "C" {
#endif
-extern const LL_SPI_InitTypeDef furi_hal_spi_config_nfc;
-extern const LL_SPI_InitTypeDef furi_hal_spi_config_subghz;
-extern const LL_SPI_InitTypeDef furi_hal_spi_config_display;
-extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast;
-extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow;
+/** Preset for ST25R916 */
+extern const LL_SPI_InitTypeDef furi_hal_spi_preset_2edge_low_8m;
-/** FURI HAL SPI BUS handler
- * Structure content may change at some point
- */
-typedef struct {
- const SPI_TypeDef* spi;
- const osMutexId_t* mutex;
- const GpioPin* miso;
- const GpioPin* mosi;
- const GpioPin* clk;
-} FuriHalSpiBus;
-
-/** FURI HAL SPI Device handler
- * Structure content may change at some point
- */
-typedef struct {
- const FuriHalSpiBus* bus;
- const LL_SPI_InitTypeDef* config;
- const GpioPin* chip_select;
-} FuriHalSpiDevice;
-
-/** FURI HAL SPI Standard Device IDs */
-typedef enum {
- FuriHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */
- FuriHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */
- FuriHalSpiDeviceIdSdCardFast, /** SDCARD: fast mode, after initialization */
- FuriHalSpiDeviceIdSdCardSlow, /** SDCARD: slow mode, before initialization */
- FuriHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */
-
- FuriHalSpiDeviceIdMax, /** Service Value, do not use */
-} FuriHalSpiDeviceId;
-
-/** Furi Hal Spi Bus R
- * CC1101, Nfc
- */
-extern const FuriHalSpiBus spi_r;
+/** Preset for CC1101 */
+extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_8m;
+
+/** Preset for ST7567 (Display) */
+extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_4m;
+
+/** Preset for SdCard in fast mode */
+extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_16m;
+
+/** Preset for SdCard in slow mode */
+extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m;
-/** Furi Hal Spi Bus D
- * Display, SdCard
+/** Furi Hal Spi Bus R (Radio: CC1101, Nfc, External)*/
+extern FuriHalSpiBus furi_hal_spi_bus_r;
+
+/** Furi Hal Spi Bus D (Display, SdCard) */
+extern FuriHalSpiBus furi_hal_spi_bus_d;
+
+/** CC1101 on `furi_hal_spi_bus_r` */
+extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_subghz;
+
+/** ST25R3916 on `furi_hal_spi_bus_r` */
+extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_nfc;
+
+/** External on `furi_hal_spi_bus_r`
+ * Preset: `furi_hal_spi_preset_1edge_low_2m`
+ *
+ * miso: pa6
+ * mosi: pa7
+ * sck: pb3
+ * cs: pa4 (software controlled)
+ *
+ * @warning not initialized by default, call `furi_hal_spi_bus_handle_init` to initialize
+ * Bus pins are floating on inactive state, CS high after initialization
+ *
*/
-extern const FuriHalSpiBus spi_d;
+extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_external;
+
+/** ST7567(Display) on `furi_hal_spi_bus_d` */
+extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_display;
+
+/** SdCard in fast mode on `furi_hal_spi_bus_d` */
+extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast;
-/** Furi Hal Spi devices */
-extern const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax];
+/** SdCard in slow mode on `furi_hal_spi_bus_d` */
+extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow;
#ifdef __cplusplus
}
diff --git a/firmware/targets/f6/furi-hal/furi-hal-spi-types.h b/firmware/targets/f6/furi-hal/furi-hal-spi-types.h
new file mode 100644
index 00000000..c7520f4a
--- /dev/null
+++ b/firmware/targets/f6/furi-hal/furi-hal-spi-types.h
@@ -0,0 +1,62 @@
+#pragma once
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include <furi-hal-gpio.h>
+
+#include <stm32wbxx_ll_spi.h>
+#include <stm32wbxx_ll_rcc.h>
+#include <stm32wbxx_ll_bus.h>
+
+#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; i<FuriHalSpiDeviceIdMax; ++i) {
- hal_gpio_write(furi_hal_spi_devices[i].chip_select, true);
- hal_gpio_init(
- furi_hal_spi_devices[i].chip_select,
- GpioModeOutputPushPull,
- GpioPullNo,
- GpioSpeedVeryHigh
- );
- }
-
- hal_gpio_init_ex(&gpio_spi_r_miso, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1);
- hal_gpio_init_ex(&gpio_spi_r_mosi, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1);
- hal_gpio_init_ex(&gpio_spi_r_sck, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1);
+ furi_hal_spi_bus_init(&furi_hal_spi_bus_r);
+ furi_hal_spi_bus_init(&furi_hal_spi_bus_d);
- hal_gpio_init_ex(&gpio_spi_d_miso, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2);
- hal_gpio_init_ex(&gpio_spi_d_mosi, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2);
- hal_gpio_init_ex(&gpio_spi_d_sck, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2);
+ furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_subghz);
+ furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_nfc);
+ furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_display);
+ furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_fast);
+ furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_slow);
FURI_LOG_I(TAG, "Init OK");
}
-void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus) {
+void furi_hal_spi_bus_init(FuriHalSpiBus* bus) {
furi_assert(bus);
- furi_check(osMutexAcquire(*bus->mutex, osWaitForever) == osOK);
+ bus->callback(bus, FuriHalSpiBusEventInit);
}
-void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus) {
+void furi_hal_spi_bus_deinit(FuriHalSpiBus* bus) {
furi_assert(bus);
- furi_check(osMutexRelease(*bus->mutex) == osOK);
+ bus->callback(bus, FuriHalSpiBusEventDeinit);
}
-void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config) {
- furi_assert(bus);
+void furi_hal_spi_bus_handle_init(FuriHalSpiBusHandle* handle) {
+ furi_assert(handle);
+ handle->callback(handle, FuriHalSpiBusHandleEventInit);
+}
- LL_SPI_DeInit((SPI_TypeDef*)bus->spi);
- LL_SPI_Init((SPI_TypeDef*)bus->spi, (LL_SPI_InitTypeDef*)config);
- LL_SPI_SetRxFIFOThreshold((SPI_TypeDef*)bus->spi, LL_SPI_RX_FIFO_TH_QUARTER);
- LL_SPI_Enable((SPI_TypeDef*)bus->spi);
+void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle) {
+ furi_assert(handle);
+ handle->callback(handle, FuriHalSpiBusHandleEventDeinit);
}
-void furi_hal_spi_bus_end_txrx(const FuriHalSpiBus* bus, uint32_t timeout) {
- while(LL_SPI_GetTxFIFOLevel((SPI_TypeDef *)bus->spi) != LL_SPI_TX_FIFO_EMPTY);
- while(LL_SPI_IsActiveFlag_BSY((SPI_TypeDef *)bus->spi));
- while(LL_SPI_GetRxFIFOLevel((SPI_TypeDef *)bus->spi) != LL_SPI_RX_FIFO_EMPTY) {
- LL_SPI_ReceiveData8((SPI_TypeDef *)bus->spi);
+void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle) {
+ furi_assert(handle);
+
+ handle->bus->callback(handle->bus, FuriHalSpiBusEventLock);
+ handle->bus->callback(handle->bus, FuriHalSpiBusEventActivate);
+
+ furi_assert(handle->bus->current_handle == NULL);
+
+ handle->bus->current_handle = handle;
+ handle->callback(handle, FuriHalSpiBusHandleEventActivate);
+}
+
+void furi_hal_spi_release(FuriHalSpiBusHandle* handle) {
+ furi_assert(handle);
+ furi_assert(handle->bus->current_handle == handle);
+
+ // Handle event and unset handle
+ handle->callback(handle, FuriHalSpiBusHandleEventDeactivate);
+ handle->bus->current_handle = NULL;
+
+ // Bus events
+ handle->bus->callback(handle->bus, FuriHalSpiBusEventDeactivate);
+ handle->bus->callback(handle->bus, FuriHalSpiBusEventUnlock);
+}
+
+static void furi_hal_spi_bus_end_txrx(FuriHalSpiBusHandle* handle, uint32_t timeout) {
+ while(LL_SPI_GetTxFIFOLevel(handle->bus->spi) != LL_SPI_TX_FIFO_EMPTY);
+ while(LL_SPI_IsActiveFlag_BSY(handle->bus->spi));
+ while(LL_SPI_GetRxFIFOLevel(handle->bus->spi) != LL_SPI_RX_FIFO_EMPTY) {
+ LL_SPI_ReceiveData8(handle->bus->spi);
}
}
-bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) {
- furi_assert(bus);
+bool furi_hal_spi_bus_rx(FuriHalSpiBusHandle* handle, uint8_t* buffer, size_t size, uint32_t timeout) {
+ furi_assert(handle);
+ furi_assert(handle->bus->current_handle == handle);
furi_assert(buffer);
furi_assert(size > 0);
- return furi_hal_spi_bus_trx(bus, buffer, buffer, size, timeout);
+ return furi_hal_spi_bus_trx(handle, buffer, buffer, size, timeout);
}
-bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) {
- furi_assert(bus);
+bool furi_hal_spi_bus_tx(FuriHalSpiBusHandle* handle, uint8_t* buffer, size_t size, uint32_t timeout) {
+ furi_assert(handle);
+ furi_assert(handle->bus->current_handle == handle);
furi_assert(buffer);
furi_assert(size > 0);
bool ret = true;
while(size > 0) {
- if (LL_SPI_IsActiveFlag_TXE((SPI_TypeDef *)bus->spi)) {
- LL_SPI_TransmitData8((SPI_TypeDef *)bus->spi, *buffer);
+ if (LL_SPI_IsActiveFlag_TXE(handle->bus->spi)) {
+ LL_SPI_TransmitData8(handle->bus->spi, *buffer);
buffer++;
size--;
}
}
- furi_hal_spi_bus_end_txrx(bus, timeout);
- LL_SPI_ClearFlag_OVR((SPI_TypeDef *)bus->spi);
+ furi_hal_spi_bus_end_txrx(handle, timeout);
+ LL_SPI_ClearFlag_OVR(handle->bus->spi);
return ret;
}
-bool furi_hal_spi_bus_trx(const FuriHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) {
- furi_assert(bus);
+bool furi_hal_spi_bus_trx(FuriHalSpiBusHandle* handle, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) {
+ furi_assert(handle);
+ furi_assert(handle->bus->current_handle == handle);
furi_assert(tx_buffer);
furi_assert(rx_buffer);
furi_assert(size > 0);
@@ -104,99 +119,22 @@ bool furi_hal_spi_bus_trx(const FuriHalSpiBus* bus, uint8_t* tx_buffer, uint8_t*
bool tx_allowed = true;
while(size > 0) {
- if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE((SPI_TypeDef *)bus->spi) && tx_allowed) {
- LL_SPI_TransmitData8((SPI_TypeDef *)bus->spi, *tx_buffer);
+ if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE(handle->bus->spi) && tx_allowed) {
+ LL_SPI_TransmitData8(handle->bus->spi, *tx_buffer);
tx_buffer++;
tx_size--;
tx_allowed = false;
}
- if(LL_SPI_IsActiveFlag_RXNE((SPI_TypeDef *)bus->spi)) {
- *rx_buffer = LL_SPI_ReceiveData8((SPI_TypeDef *)bus->spi);
+ if(LL_SPI_IsActiveFlag_RXNE(handle->bus->spi)) {
+ *rx_buffer = LL_SPI_ReceiveData8(handle->bus->spi);
rx_buffer++;
size--;
tx_allowed = true;
}
}
- furi_hal_spi_bus_end_txrx(bus, timeout);
-
- return ret;
-}
-
-void furi_hal_spi_device_configure(const FuriHalSpiDevice* device) {
- furi_assert(device);
- furi_assert(device->config);
-
- furi_hal_spi_bus_configure(device->bus, device->config);
-}
-
-const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id) {
- furi_assert(device_id < FuriHalSpiDeviceIdMax);
-
- const FuriHalSpiDevice* device = &furi_hal_spi_devices[device_id];
- furi_assert(device);
- furi_hal_spi_bus_lock(device->bus);
- furi_hal_spi_device_configure(device);
-
- return device;
-}
-
-void furi_hal_spi_device_return(const FuriHalSpiDevice* device) {
- furi_hal_spi_bus_unlock(device->bus);
-}
-
-bool furi_hal_spi_device_rx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) {
- furi_assert(device);
- furi_assert(buffer);
- furi_assert(size > 0);
-
- if (device->chip_select) {
- hal_gpio_write(device->chip_select, false);
- }
-
- bool ret = furi_hal_spi_bus_rx(device->bus, buffer, size, timeout);
-
- if (device->chip_select) {
- hal_gpio_write(device->chip_select, true);
- }
-
- return ret;
-}
-
-bool furi_hal_spi_device_tx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) {
- furi_assert(device);
- furi_assert(buffer);
- furi_assert(size > 0);
-
- if (device->chip_select) {
- hal_gpio_write(device->chip_select, false);
- }
-
- bool ret = furi_hal_spi_bus_tx(device->bus, buffer, size, timeout);
-
- if (device->chip_select) {
- hal_gpio_write(device->chip_select, true);
- }
-
- return ret;
-}
-
-bool furi_hal_spi_device_trx(const FuriHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) {
- furi_assert(device);
- furi_assert(tx_buffer);
- furi_assert(rx_buffer);
- furi_assert(size > 0);
-
- if (device->chip_select) {
- hal_gpio_write(device->chip_select, false);
- }
-
- bool ret = furi_hal_spi_bus_trx(device->bus, tx_buffer, rx_buffer, size, timeout);
-
- if (device->chip_select) {
- hal_gpio_write(device->chip_select, true);
- }
+ furi_hal_spi_bus_end_txrx(handle, timeout);
return ret;
}
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 <furi-hal-spi.h>
-#include <furi-hal-gpio.h>
-#include <furi-hal-resources.h>
-#include <furi-hal-power.h>
-#include <furi-hal-delay.h>
-#include <furi-hal-sd.h>
+#include <furi-hal.h>
/** @addtogroup BSP
* @{
@@ -284,22 +279,22 @@ static uint8_t SD_ReadData(void);
/* Private functions ---------------------------------------------------------*/
void SD_SPI_Bus_To_Down_State(){
- hal_gpio_init_ex(&gpio_spi_d_miso, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused);
- hal_gpio_init_ex(&gpio_spi_d_mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused);
- hal_gpio_init_ex(&gpio_spi_d_sck, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused);
-
- hal_gpio_write(&gpio_sdcard_cs, false);
- hal_gpio_write(&gpio_spi_d_miso, false);
- hal_gpio_write(&gpio_spi_d_mosi, false);
- hal_gpio_write(&gpio_spi_d_sck, false);
+ hal_gpio_init_ex(furi_hal_sd_spi_handle->miso, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused);
+ hal_gpio_init_ex(furi_hal_sd_spi_handle->mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused);
+ hal_gpio_init_ex(furi_hal_sd_spi_handle->sck, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused);
+
+ hal_gpio_write(furi_hal_sd_spi_handle->cs, false);
+ hal_gpio_write(furi_hal_sd_spi_handle->miso, false);
+ hal_gpio_write(furi_hal_sd_spi_handle->mosi, false);
+ hal_gpio_write(furi_hal_sd_spi_handle->sck, false);
}
void SD_SPI_Bus_To_Normal_State(){
- hal_gpio_write(&gpio_sdcard_cs, true);
+ hal_gpio_write(furi_hal_sd_spi_handle->cs, true);
- hal_gpio_init_ex(&gpio_spi_d_miso, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2);
- hal_gpio_init_ex(&gpio_spi_d_mosi, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2);
- hal_gpio_init_ex(&gpio_spi_d_sck, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2);
+ hal_gpio_init_ex(furi_hal_sd_spi_handle->miso, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2);
+ hal_gpio_init_ex(furi_hal_sd_spi_handle->mosi, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2);
+ hal_gpio_init_ex(furi_hal_sd_spi_handle->sck, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2);
}
/** @defgroup STM32_ADAFRUIT_SD_Private_Functions
@@ -315,7 +310,8 @@ void SD_SPI_Bus_To_Normal_State(){
*/
uint8_t BSP_SD_Init(bool reset_card) {
/* Slow speed init */
- const FuriHalSpiDevice* sd_spi_slow_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardSlow);
+ furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_slow);
+ furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_slow;
/* We must reset card in spi_lock context */
if(reset_card) {
@@ -344,7 +340,8 @@ uint8_t BSP_SD_Init(bool reset_card) {
if(res == BSP_SD_OK) break;
}
- furi_hal_spi_device_return(sd_spi_slow_dev);
+ furi_hal_sd_spi_handle = NULL;
+ furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_slow);
/* SD initialized and set to SPI mode properly */
return res;
diff --git a/firmware/targets/f7/fatfs/user_diskio.c b/firmware/targets/f7/fatfs/user_diskio.c
index ca3d60a5..df16245a 100644
--- a/firmware/targets/f7/fatfs/user_diskio.c
+++ b/firmware/targets/f7/fatfs/user_diskio.c
@@ -35,7 +35,7 @@
/* Includes ------------------------------------------------------------------*/
#include "user_diskio.h"
-#include "furi-hal-spi.h"
+#include <furi-hal.h>
/* 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 <furi-hal-spi-config.h>
#include <furi-hal-resources.h>
-#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 <furi-hal-gpio.h>
-#include <stm32wbxx_ll_spi.h>
-#include <cmsis_os2.h>
+#include <furi-hal-spi-types.h>
#ifdef __cplusplus
extern "C" {
#endif
-extern const LL_SPI_InitTypeDef furi_hal_spi_config_nfc;
-extern const LL_SPI_InitTypeDef furi_hal_spi_config_subghz;
-extern const LL_SPI_InitTypeDef furi_hal_spi_config_display;
-extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast;
-extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow;
+/** Preset for ST25R916 */
+extern const LL_SPI_InitTypeDef furi_hal_spi_preset_2edge_low_8m;
-/** FURI HAL SPI BUS handler
- * Structure content may change at some point
- */
-typedef struct {
- const SPI_TypeDef* spi;
- const osMutexId_t* mutex;
- const GpioPin* miso;
- const GpioPin* mosi;
- const GpioPin* clk;
-} FuriHalSpiBus;
-
-/** FURI HAL SPI Device handler
- * Structure content may change at some point
- */
-typedef struct {
- const FuriHalSpiBus* bus;
- const LL_SPI_InitTypeDef* config;
- const GpioPin* chip_select;
-} FuriHalSpiDevice;
-
-/** FURI HAL SPI Standard Device IDs */
-typedef enum {
- FuriHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */
- FuriHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */
- FuriHalSpiDeviceIdSdCardFast, /** SDCARD: fast mode, after initialization */
- FuriHalSpiDeviceIdSdCardSlow, /** SDCARD: slow mode, before initialization */
- FuriHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */
-
- FuriHalSpiDeviceIdMax, /** Service Value, do not use */
-} FuriHalSpiDeviceId;
-
-/** Furi Hal Spi Bus R
- * CC1101, Nfc
- */
-extern const FuriHalSpiBus spi_r;
+/** Preset for CC1101 */
+extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_8m;
+
+/** Preset for ST7567 (Display) */
+extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_4m;
+
+/** Preset for SdCard in fast mode */
+extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_16m;
+
+/** Preset for SdCard in slow mode */
+extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m;
-/** Furi Hal Spi Bus D
- * Display, SdCard
+/** Furi Hal Spi Bus R (Radio: CC1101, Nfc, External)*/
+extern FuriHalSpiBus furi_hal_spi_bus_r;
+
+/** Furi Hal Spi Bus D (Display, SdCard) */
+extern FuriHalSpiBus furi_hal_spi_bus_d;
+
+/** CC1101 on `furi_hal_spi_bus_r` */
+extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_subghz;
+
+/** ST25R3916 on `furi_hal_spi_bus_r` */
+extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_nfc;
+
+/** External on `furi_hal_spi_bus_r`
+ * Preset: `furi_hal_spi_preset_1edge_low_2m`
+ *
+ * miso: pa6
+ * mosi: pa7
+ * sck: pb3
+ * cs: pa4 (software controlled)
+ *
+ * @warning not initialized by default, call `furi_hal_spi_bus_handle_init` to initialize
+ * Bus pins are floating on inactive state, CS high after initialization
+ *
*/
-extern const FuriHalSpiBus spi_d;
+extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_external;
+
+/** ST7567(Display) on `furi_hal_spi_bus_d` */
+extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_display;
+
+/** SdCard in fast mode on `furi_hal_spi_bus_d` */
+extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast;
-/** Furi Hal Spi devices */
-extern const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax];
+/** SdCard in slow mode on `furi_hal_spi_bus_d` */
+extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow;
#ifdef __cplusplus
}
diff --git a/firmware/targets/f7/furi-hal/furi-hal-spi-types.h b/firmware/targets/f7/furi-hal/furi-hal-spi-types.h
new file mode 100644
index 00000000..c7520f4a
--- /dev/null
+++ b/firmware/targets/f7/furi-hal/furi-hal-spi-types.h
@@ -0,0 +1,62 @@
+#pragma once
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include <furi-hal-gpio.h>
+
+#include <stm32wbxx_ll_spi.h>
+#include <stm32wbxx_ll_rcc.h>
+#include <stm32wbxx_ll_bus.h>
+
+#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; i<FuriHalSpiDeviceIdMax; ++i) {
- hal_gpio_write(furi_hal_spi_devices[i].chip_select, true);
- hal_gpio_init(
- furi_hal_spi_devices[i].chip_select,
- GpioModeOutputPushPull,
- GpioPullNo,
- GpioSpeedVeryHigh
- );
- }
-
- hal_gpio_init_ex(&gpio_spi_r_miso, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1);
- hal_gpio_init_ex(&gpio_spi_r_mosi, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1);
- hal_gpio_init_ex(&gpio_spi_r_sck, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1);
+ furi_hal_spi_bus_init(&furi_hal_spi_bus_r);
+ furi_hal_spi_bus_init(&furi_hal_spi_bus_d);
- hal_gpio_init_ex(&gpio_spi_d_miso, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2);
- hal_gpio_init_ex(&gpio_spi_d_mosi, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2);
- hal_gpio_init_ex(&gpio_spi_d_sck, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2);
+ furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_subghz);
+ furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_nfc);
+ furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_display);
+ furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_fast);
+ furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_slow);
FURI_LOG_I(TAG, "Init OK");
}
-void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus) {
+void furi_hal_spi_bus_init(FuriHalSpiBus* bus) {
furi_assert(bus);
- furi_check(osMutexAcquire(*bus->mutex, osWaitForever) == osOK);
+ bus->callback(bus, FuriHalSpiBusEventInit);
}
-void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus) {
+void furi_hal_spi_bus_deinit(FuriHalSpiBus* bus) {
furi_assert(bus);
- furi_check(osMutexRelease(*bus->mutex) == osOK);
+ bus->callback(bus, FuriHalSpiBusEventDeinit);
}
-void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config) {
- furi_assert(bus);
+void furi_hal_spi_bus_handle_init(FuriHalSpiBusHandle* handle) {
+ furi_assert(handle);
+ handle->callback(handle, FuriHalSpiBusHandleEventInit);
+}
- LL_SPI_DeInit((SPI_TypeDef*)bus->spi);
- LL_SPI_Init((SPI_TypeDef*)bus->spi, (LL_SPI_InitTypeDef*)config);
- LL_SPI_SetRxFIFOThreshold((SPI_TypeDef*)bus->spi, LL_SPI_RX_FIFO_TH_QUARTER);
- LL_SPI_Enable((SPI_TypeDef*)bus->spi);
+void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle) {
+ furi_assert(handle);
+ handle->callback(handle, FuriHalSpiBusHandleEventDeinit);
}
-void furi_hal_spi_bus_end_txrx(const FuriHalSpiBus* bus, uint32_t timeout) {
- while(LL_SPI_GetTxFIFOLevel((SPI_TypeDef *)bus->spi) != LL_SPI_TX_FIFO_EMPTY);
- while(LL_SPI_IsActiveFlag_BSY((SPI_TypeDef *)bus->spi));
- while(LL_SPI_GetRxFIFOLevel((SPI_TypeDef *)bus->spi) != LL_SPI_RX_FIFO_EMPTY) {
- LL_SPI_ReceiveData8((SPI_TypeDef *)bus->spi);
+void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle) {
+ furi_assert(handle);
+
+ handle->bus->callback(handle->bus, FuriHalSpiBusEventLock);
+ handle->bus->callback(handle->bus, FuriHalSpiBusEventActivate);
+
+ furi_assert(handle->bus->current_handle == NULL);
+
+ handle->bus->current_handle = handle;
+ handle->callback(handle, FuriHalSpiBusHandleEventActivate);
+}
+
+void furi_hal_spi_release(FuriHalSpiBusHandle* handle) {
+ furi_assert(handle);
+ furi_assert(handle->bus->current_handle == handle);
+
+ // Handle event and unset handle
+ handle->callback(handle, FuriHalSpiBusHandleEventDeactivate);
+ handle->bus->current_handle = NULL;
+
+ // Bus events
+ handle->bus->callback(handle->bus, FuriHalSpiBusEventDeactivate);
+ handle->bus->callback(handle->bus, FuriHalSpiBusEventUnlock);
+}
+
+static void furi_hal_spi_bus_end_txrx(FuriHalSpiBusHandle* handle, uint32_t timeout) {
+ while(LL_SPI_GetTxFIFOLevel(handle->bus->spi) != LL_SPI_TX_FIFO_EMPTY);
+ while(LL_SPI_IsActiveFlag_BSY(handle->bus->spi));
+ while(LL_SPI_GetRxFIFOLevel(handle->bus->spi) != LL_SPI_RX_FIFO_EMPTY) {
+ LL_SPI_ReceiveData8(handle->bus->spi);
}
}
-bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) {
- furi_assert(bus);
+bool furi_hal_spi_bus_rx(FuriHalSpiBusHandle* handle, uint8_t* buffer, size_t size, uint32_t timeout) {
+ furi_assert(handle);
+ furi_assert(handle->bus->current_handle == handle);
furi_assert(buffer);
furi_assert(size > 0);
- return furi_hal_spi_bus_trx(bus, buffer, buffer, size, timeout);
+ return furi_hal_spi_bus_trx(handle, buffer, buffer, size, timeout);
}
-bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) {
- furi_assert(bus);
+bool furi_hal_spi_bus_tx(FuriHalSpiBusHandle* handle, uint8_t* buffer, size_t size, uint32_t timeout) {
+ furi_assert(handle);
+ furi_assert(handle->bus->current_handle == handle);
furi_assert(buffer);
furi_assert(size > 0);
bool ret = true;
while(size > 0) {
- if (LL_SPI_IsActiveFlag_TXE((SPI_TypeDef *)bus->spi)) {
- LL_SPI_TransmitData8((SPI_TypeDef *)bus->spi, *buffer);
+ if (LL_SPI_IsActiveFlag_TXE(handle->bus->spi)) {
+ LL_SPI_TransmitData8(handle->bus->spi, *buffer);
buffer++;
size--;
}
}
- furi_hal_spi_bus_end_txrx(bus, timeout);
- LL_SPI_ClearFlag_OVR((SPI_TypeDef *)bus->spi);
+ furi_hal_spi_bus_end_txrx(handle, timeout);
+ LL_SPI_ClearFlag_OVR(handle->bus->spi);
return ret;
}
-bool furi_hal_spi_bus_trx(const FuriHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) {
- furi_assert(bus);
+bool furi_hal_spi_bus_trx(FuriHalSpiBusHandle* handle, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) {
+ furi_assert(handle);
+ furi_assert(handle->bus->current_handle == handle);
furi_assert(tx_buffer);
furi_assert(rx_buffer);
furi_assert(size > 0);
@@ -104,99 +119,22 @@ bool furi_hal_spi_bus_trx(const FuriHalSpiBus* bus, uint8_t* tx_buffer, uint8_t*
bool tx_allowed = true;
while(size > 0) {
- if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE((SPI_TypeDef *)bus->spi) && tx_allowed) {
- LL_SPI_TransmitData8((SPI_TypeDef *)bus->spi, *tx_buffer);
+ if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE(handle->bus->spi) && tx_allowed) {
+ LL_SPI_TransmitData8(handle->bus->spi, *tx_buffer);
tx_buffer++;
tx_size--;
tx_allowed = false;
}
- if(LL_SPI_IsActiveFlag_RXNE((SPI_TypeDef *)bus->spi)) {
- *rx_buffer = LL_SPI_ReceiveData8((SPI_TypeDef *)bus->spi);
+ if(LL_SPI_IsActiveFlag_RXNE(handle->bus->spi)) {
+ *rx_buffer = LL_SPI_ReceiveData8(handle->bus->spi);
rx_buffer++;
size--;
tx_allowed = true;
}
}
- furi_hal_spi_bus_end_txrx(bus, timeout);
-
- return ret;
-}
-
-void furi_hal_spi_device_configure(const FuriHalSpiDevice* device) {
- furi_assert(device);
- furi_assert(device->config);
-
- furi_hal_spi_bus_configure(device->bus, device->config);
-}
-
-const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id) {
- furi_assert(device_id < FuriHalSpiDeviceIdMax);
-
- const FuriHalSpiDevice* device = &furi_hal_spi_devices[device_id];
- furi_assert(device);
- furi_hal_spi_bus_lock(device->bus);
- furi_hal_spi_device_configure(device);
-
- return device;
-}
-
-void furi_hal_spi_device_return(const FuriHalSpiDevice* device) {
- furi_hal_spi_bus_unlock(device->bus);
-}
-
-bool furi_hal_spi_device_rx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) {
- furi_assert(device);
- furi_assert(buffer);
- furi_assert(size > 0);
-
- if (device->chip_select) {
- hal_gpio_write(device->chip_select, false);
- }
-
- bool ret = furi_hal_spi_bus_rx(device->bus, buffer, size, timeout);
-
- if (device->chip_select) {
- hal_gpio_write(device->chip_select, true);
- }
-
- return ret;
-}
-
-bool furi_hal_spi_device_tx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) {
- furi_assert(device);
- furi_assert(buffer);
- furi_assert(size > 0);
-
- if (device->chip_select) {
- hal_gpio_write(device->chip_select, false);
- }
-
- bool ret = furi_hal_spi_bus_tx(device->bus, buffer, size, timeout);
-
- if (device->chip_select) {
- hal_gpio_write(device->chip_select, true);
- }
-
- return ret;
-}
-
-bool furi_hal_spi_device_trx(const FuriHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) {
- furi_assert(device);
- furi_assert(tx_buffer);
- furi_assert(rx_buffer);
- furi_assert(size > 0);
-
- if (device->chip_select) {
- hal_gpio_write(device->chip_select, false);
- }
-
- bool ret = furi_hal_spi_bus_trx(device->bus, tx_buffer, rx_buffer, size, timeout);
-
- if (device->chip_select) {
- hal_gpio_write(device->chip_select, true);
- }
+ furi_hal_spi_bus_end_txrx(handle, timeout);
return ret;
}
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 <stdint.h>
#include <stdbool.h>
+#include <furi-hal-spi-types.h>
#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 <furi-hal-gpio.h>
+
+#include <furi-hal-spi-config.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
-/**
- * Init SPI API
- */
+/** Initialize SPI HAL */
void furi_hal_spi_init();
-/* Bus Level API */
-
-/** Lock SPI bus
- * Takes bus mutex, if used
+/** Initialize SPI Bus
+ *
+ * @param handle pointer to FuriHalSpiBus instance
*/
-void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus);
+void furi_hal_spi_bus_init(FuriHalSpiBus* bus);
-/** Unlock SPI bus
- * Releases BUS mutex, if used
+/** Deinitialize SPI Bus
+ *
+ * @param handle pointer to FuriHalSpiBus instance
*/
-void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus);
+void furi_hal_spi_bus_deinit(FuriHalSpiBus* bus);
-/** Configure SPI bus
- * @param bus - spi bus handler
- * @param config - spi configuration structure
+/** Initialize SPI Bus Handle
+ *
+ * @param handle pointer to FuriHalSpiBusHandle instance
*/
-void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config);
+void furi_hal_spi_bus_handle_init(FuriHalSpiBusHandle* handle);
-/** SPI Receive
- * @param bus - spi bus handler
- * @param buffer - receive buffer
- * @param size - transaction size
- * @param timeout - bus operation timeout in ms
+/** Deinitialize SPI Bus Handle
+ *
+ * @param handle pointer to FuriHalSpiBusHandle instance
*/
-bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout);
+void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle);
-/** SPI Transmit
- * @param bus - spi bus handler
- * @param buffer - transmit buffer
- * @param size - transaction size
- * @param timeout - bus operation timeout in ms
+/** Acquire SPI bus
+ *
+ * @warning blocking, calls `furi_crash` on programming error, CS transition is up to handler event routine
+ *
+ * @param handle pointer to FuriHalSpiBusHandle instance
*/
-bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout);
+void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle);
-/** SPI Transmit and Receive
- * @param bus - spi bus handlere
- * @param tx_buffer - device handle
- * @param rx_buffer - device handle
- * @param size - transaction size
- * @param timeout - bus operation timeout in ms
+/** Release SPI bus
+ *
+ * @warning calls `furi_crash` on programming error, CS transition is up to handler event routine
+ *
+ * @param handle pointer to FuriHalSpiBusHandle instance
*/
-bool furi_hal_spi_bus_trx(const FuriHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout);
+void furi_hal_spi_release(FuriHalSpiBusHandle* handle);
-/* Device Level API */
-
-/** Reconfigure SPI bus for device
- * @param device - device description
- */
-void furi_hal_spi_device_configure(const FuriHalSpiDevice* device);
-
-/** Get Device handle
- * And lock access to the corresponding SPI BUS
- * @param device_id - device identifier
- * @return device handle
- */
-const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id);
-
-/** Return Device handle
- * And unlock access to the corresponding SPI BUS
- * @param device - device handle
- */
-void furi_hal_spi_device_return(const FuriHalSpiDevice* device);
-
-/** SPI Recieve
- * @param device - device handle
- * @param buffer - receive buffer
- * @param size - transaction size
- * @param timeout - bus operation timeout in ms
+/** SPI Receive
+ *
+ * @param handle pointer to FuriHalSpiBusHandle instance
+ * @param buffer receive buffer
+ * @param size transaction size (buffer size)
+ * @param timeout operation timeout in ms
+ *
+ * @return true on sucess
*/
-bool furi_hal_spi_device_rx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout);
+bool furi_hal_spi_bus_rx(FuriHalSpiBusHandle* handle, uint8_t* buffer, size_t size, uint32_t timeout);
/** SPI Transmit
- * @param device - device handle
- * @param buffer - transmit buffer
- * @param size - transaction size
- * @param timeout - bus operation timeout in ms
+ *
+ * @param handle pointer to FuriHalSpiBusHandle instance
+ * @param buffer transmit buffer
+ * @param size transaction size (buffer size)
+ * @param timeout operation timeout in ms
+ *
+ * @return true on success
*/
-bool furi_hal_spi_device_tx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout);
+bool furi_hal_spi_bus_tx(FuriHalSpiBusHandle* handle, uint8_t* buffer, size_t size, uint32_t timeout);
/** SPI Transmit and Receive
- * @param device - device handle
- * @param tx_buffer - device handle
- * @param rx_buffer - device handle
- * @param size - transaction size
- * @param timeout - bus operation timeout in ms
+ *
+ * @param handle pointer to FuriHalSpiBusHandle instance
+ * @param tx_buffer pointer to tx buffer
+ * @param rx_buffer pointer to rx buffer
+ * @param size transaction size (buffer size)
+ * @param timeout operation timeout in ms
+ *
+ * @return true on success
*/
-bool furi_hal_spi_device_trx(const FuriHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout);
-
+bool furi_hal_spi_bus_trx(FuriHalSpiBusHandle* handle, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout);
#ifdef __cplusplus
}
diff --git a/firmware/targets/furi-hal-include/furi-hal.h b/firmware/targets/furi-hal-include/furi-hal.h
index eb1fefeb..2357e7fe 100644
--- a/firmware/targets/furi-hal-include/furi-hal.h
+++ b/firmware/targets/furi-hal-include/furi-hal.h
@@ -14,6 +14,7 @@ template <unsigned int N> 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"