[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.
This commit is contained in:
あく
2021-11-30 15:09:43 +03:00
committed by GitHub
parent d86125c7f7
commit 9d27ef8901
36 changed files with 2057 additions and 1612 deletions

View File

@@ -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,40 +68,223 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = {
.CRCPoly = 7,
};
const FuriHalSpiBus spi_r = {
.spi = SPI_R,
/* SPI Buses */
static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) {
if(event == FuriHalSpiBusEventInit) {
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1);
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
bus->current_handle = NULL;
} else if(event == FuriHalSpiBusEventDeinit) {
} else if(event == FuriHalSpiBusEventLock) {
} else if(event == FuriHalSpiBusEventUnlock) {
} else if(event == FuriHalSpiBusEventActivate) {
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1);
} else if(event == FuriHalSpiBusEventDeactivate) {
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
}
}
FuriHalSpiBus furi_hal_spi_bus_r = {
.spi = SPI1,
.callback = furi_hal_spi_bus_r_event_callback,
};
static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) {
if(event == FuriHalSpiBusEventInit) {
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2);
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
bus->current_handle = NULL;
} else if(event == FuriHalSpiBusEventDeinit) {
} else if(event == FuriHalSpiBusEventLock) {
} else if(event == FuriHalSpiBusEventUnlock) {
} else if(event == FuriHalSpiBusEventActivate) {
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2);
} else if(event == FuriHalSpiBusEventDeactivate) {
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
}
}
FuriHalSpiBus furi_hal_spi_bus_d = {
.spi = SPI2,
.callback = furi_hal_spi_bus_d_event_callback,
};
/* SPI Bus Handles */
inline static void furi_hal_spi_bus_r_handle_event_callback(
FuriHalSpiBusHandle* handle,
FuriHalSpiBusHandleEvent event,
const LL_SPI_InitTypeDef* preset) {
if(event == FuriHalSpiBusHandleEventInit) {
hal_gpio_write(handle->cs, true);
hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
} else if(event == FuriHalSpiBusHandleEventDeinit) {
hal_gpio_write(handle->cs, true);
hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
} else if(event == FuriHalSpiBusHandleEventActivate) {
LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset);
LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER);
LL_SPI_Enable(handle->bus->spi);
hal_gpio_init_ex(
handle->miso,
GpioModeAltFunctionPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFn5SPI1);
hal_gpio_init_ex(
handle->mosi,
GpioModeAltFunctionPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFn5SPI1);
hal_gpio_init_ex(
handle->sck,
GpioModeAltFunctionPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFn5SPI1);
hal_gpio_write(handle->cs, false);
} else if(event == FuriHalSpiBusHandleEventDeactivate) {
hal_gpio_write(handle->cs, true);
hal_gpio_init(handle->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
hal_gpio_init(handle->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
hal_gpio_init(handle->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
LL_SPI_Disable(handle->bus->spi);
}
}
static void furi_hal_spi_bus_handle_subghz_event_callback(
FuriHalSpiBusHandle* handle,
FuriHalSpiBusHandleEvent event) {
furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_8m);
}
FuriHalSpiBusHandle furi_hal_spi_bus_handle_subghz = {
.bus = &furi_hal_spi_bus_r,
.callback = furi_hal_spi_bus_handle_subghz_event_callback,
.miso = &gpio_spi_r_miso,
.mosi = &gpio_spi_r_mosi,
.clk = &gpio_spi_r_sck,
.sck = &gpio_spi_r_sck,
.cs = &gpio_subghz_cs,
};
const FuriHalSpiBus spi_d = {
.spi = SPI_D,
static void furi_hal_spi_bus_handle_nfc_event_callback(
FuriHalSpiBusHandle* handle,
FuriHalSpiBusHandleEvent event) {
furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_2edge_low_8m);
}
FuriHalSpiBusHandle furi_hal_spi_bus_handle_nfc = {
.bus = &furi_hal_spi_bus_r,
.callback = furi_hal_spi_bus_handle_nfc_event_callback,
.miso = &gpio_spi_r_miso,
.mosi = &gpio_spi_r_mosi,
.sck = &gpio_spi_r_sck,
.cs = &gpio_nfc_cs,
};
static void furi_hal_spi_bus_handle_external_event_callback(
FuriHalSpiBusHandle* handle,
FuriHalSpiBusHandleEvent event) {
furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m);
}
FuriHalSpiBusHandle furi_hal_spi_bus_handle_external = {
.bus = &furi_hal_spi_bus_r,
.callback = furi_hal_spi_bus_handle_external_event_callback,
.miso = &gpio_ext_pa6,
.mosi = &gpio_ext_pa7,
.sck = &gpio_ext_pb3,
.cs = &gpio_ext_pa4,
};
inline static void furi_hal_spi_bus_d_handle_event_callback(
FuriHalSpiBusHandle* handle,
FuriHalSpiBusHandleEvent event,
const LL_SPI_InitTypeDef* preset) {
if(event == FuriHalSpiBusHandleEventInit) {
hal_gpio_write(handle->cs, true);
hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh);
hal_gpio_init_ex(
handle->miso,
GpioModeAltFunctionPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFn5SPI2);
hal_gpio_init_ex(
handle->mosi,
GpioModeAltFunctionPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFn5SPI2);
hal_gpio_init_ex(
handle->sck,
GpioModeAltFunctionPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFn5SPI2);
} else if(event == FuriHalSpiBusHandleEventDeinit) {
hal_gpio_write(handle->cs, true);
hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullUp, GpioSpeedLow);
} else if(event == FuriHalSpiBusHandleEventActivate) {
LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset);
LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER);
LL_SPI_Enable(handle->bus->spi);
hal_gpio_write(handle->cs, false);
} else if(event == FuriHalSpiBusHandleEventDeactivate) {
hal_gpio_write(handle->cs, true);
LL_SPI_Disable(handle->bus->spi);
}
}
static void furi_hal_spi_bus_handle_display_event_callback(
FuriHalSpiBusHandle* handle,
FuriHalSpiBusHandleEvent event) {
furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_4m);
}
FuriHalSpiBusHandle furi_hal_spi_bus_handle_display = {
.bus = &furi_hal_spi_bus_d,
.callback = furi_hal_spi_bus_handle_display_event_callback,
.miso = &gpio_spi_d_miso,
.mosi = &gpio_spi_d_mosi,
.clk = &gpio_spi_d_sck,
.sck = &gpio_spi_d_sck,
.cs = &gpio_display_cs,
};
const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax] = {
{
.bus = &spi_r,
.config = &furi_hal_spi_config_subghz,
.chip_select = &gpio_subghz_cs,
},
{
.bus = &spi_d,
.config = &furi_hal_spi_config_display,
.chip_select = &gpio_display_cs,
},
{
.bus = &spi_d,
.config = &furi_hal_spi_config_sd_fast,
.chip_select = &gpio_sdcard_cs,
},
{
.bus = &spi_d,
.config = &furi_hal_spi_config_sd_slow,
.chip_select = &gpio_sdcard_cs,
},
{.bus = &spi_r, .config = &furi_hal_spi_config_nfc, .chip_select = &gpio_nfc_cs},
static void furi_hal_spi_bus_handle_sd_fast_event_callback(
FuriHalSpiBusHandle* handle,
FuriHalSpiBusHandleEvent event) {
furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_16m);
}
FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast = {
.bus = &furi_hal_spi_bus_d,
.callback = furi_hal_spi_bus_handle_sd_fast_event_callback,
.miso = &gpio_spi_d_miso,
.mosi = &gpio_spi_d_mosi,
.sck = &gpio_spi_d_sck,
.cs = &gpio_sdcard_cs,
};
static void furi_hal_spi_bus_handle_sd_slow_event_callback(
FuriHalSpiBusHandle* handle,
FuriHalSpiBusHandleEvent event) {
furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m);
}
FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow = {
.bus = &furi_hal_spi_bus_d,
.callback = furi_hal_spi_bus_handle_sd_slow_event_callback,
.miso = &gpio_spi_d_miso,
.mosi = &gpio_spi_d_mosi,
.sck = &gpio_spi_d_sck,
.cs = &gpio_sdcard_cs,
};