From d76283b1a0022294eaaf466df6ce76a1fbae3fea Mon Sep 17 00:00:00 2001 From: gornekich Date: Wed, 26 May 2021 18:42:12 +0300 Subject: [PATCH] [FL-1111] SD card rework with SPI API (#496) * api-hal-spi: make fast and slow sd card devices * api-hal-spi: add configuration for spi bus * fatfs: rework sd card driver with api-hal-spi * api-hal-spi: enable spi in bus reset --- firmware/targets/f5/Src/fatfs/spi_sd_hal.c | 28 +++---- .../targets/f5/Src/fatfs/stm32_adafruit_sd.c | 9 +- firmware/targets/f5/Src/fatfs/user_diskio.c | 31 ++++--- .../targets/f5/api-hal/api-hal-spi-config.c | 84 +++++++++---------- .../targets/f5/api-hal/api-hal-spi-config.h | 16 ++-- firmware/targets/f5/api-hal/api-hal-spi.c | 53 +++++------- firmware/targets/f5/api-hal/api-hal-spi.h | 13 +++ firmware/targets/f6/Src/fatfs/spi_sd_hal.c | 28 +++---- .../targets/f6/Src/fatfs/stm32_adafruit_sd.c | 9 +- firmware/targets/f6/Src/fatfs/user_diskio.c | 31 ++++--- .../targets/f6/api-hal/api-hal-spi-config.c | 84 +++++++++---------- .../targets/f6/api-hal/api-hal-spi-config.h | 16 ++-- firmware/targets/f6/api-hal/api-hal-spi.c | 53 +++++------- firmware/targets/f6/api-hal/api-hal-spi.h | 13 +++ 14 files changed, 222 insertions(+), 246 deletions(-) diff --git a/firmware/targets/f5/Src/fatfs/spi_sd_hal.c b/firmware/targets/f5/Src/fatfs/spi_sd_hal.c index 0cad29f7..386c8081 100644 --- a/firmware/targets/f5/Src/fatfs/spi_sd_hal.c +++ b/firmware/targets/f5/Src/fatfs/spi_sd_hal.c @@ -1,12 +1,12 @@ #include "main.h" +#include "api-hal-spi.h" #define SD_DUMMY_BYTE 0xFF -#define SD_CS_LOW() HAL_GPIO_WritePin(SD_CS_GPIO_Port, SD_CS_Pin, GPIO_PIN_RESET) -#define SD_CS_HIGH() HAL_GPIO_WritePin(SD_CS_GPIO_Port, SD_CS_Pin, GPIO_PIN_SET) const uint32_t SpiTimeout = 1000; -extern SPI_HandleTypeDef SPI_SD_HANDLE; uint8_t SD_IO_WriteByte(uint8_t Data); +static const ApiHalSpiDevice* sd_spi_dev = &api_hal_spi_devices[ApiHalSpiDeviceIdSdCardFast]; + /****************************************************************************** BUS OPERATIONS @@ -17,11 +17,8 @@ uint8_t SD_IO_WriteByte(uint8_t Data); * @retval None */ static void SPIx_Error(void) { - /* De-initialize the SPI communication BUS */ - HAL_SPI_DeInit(&SPI_SD_HANDLE); - /* Re-Initiaize the SPI communication BUS */ - HAL_SPI_Init(&SPI_SD_HANDLE); + api_hal_spi_bus_reset(sd_spi_dev->bus); } /** @@ -32,12 +29,10 @@ static void SPIx_Error(void) { * @retval None */ static void SPIx_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t DataLength) { - HAL_StatusTypeDef status = HAL_OK; - status = - HAL_SPI_TransmitReceive(&SPI_SD_HANDLE, (uint8_t*)DataIn, DataOut, DataLength, SpiTimeout); + bool status = api_hal_spi_bus_trx(sd_spi_dev->bus, (uint8_t*)DataIn, DataOut, DataLength, SpiTimeout); /* Check the communication status */ - if(status != HAL_OK) { + if(!status) { /* Execute user timeout callback */ SPIx_Error(); } @@ -49,13 +44,12 @@ static void SPIx_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t * @retval None */ __attribute__((unused)) static void SPIx_Write(uint8_t Value) { - HAL_StatusTypeDef status = HAL_OK; uint8_t data; - status = HAL_SPI_TransmitReceive(&SPI_SD_HANDLE, (uint8_t*)&Value, &data, 1, SpiTimeout); + bool status = api_hal_spi_bus_trx(sd_spi_dev->bus, (uint8_t*)&Value, &data, 1, SpiTimeout); /* Check the communication status */ - if(status != HAL_OK) { + if(!status) { /* Execute user timeout callback */ SPIx_Error(); } @@ -75,7 +69,7 @@ void SD_IO_Init(void) { uint8_t counter = 0; /* SD chip select high */ - SD_CS_HIGH(); + hal_gpio_write(sd_spi_dev->chip_select, true); /* Send dummy byte 0xFF, 10 times with CS high */ /* Rise CS and MOSI for 80 clocks cycles */ @@ -92,9 +86,9 @@ void SD_IO_Init(void) { */ void SD_IO_CSState(uint8_t val) { if(val == 1) { - SD_CS_HIGH(); + hal_gpio_write(sd_spi_dev->chip_select, true); } else { - SD_CS_LOW(); + hal_gpio_write(sd_spi_dev->chip_select, false); } } diff --git a/firmware/targets/f5/Src/fatfs/stm32_adafruit_sd.c b/firmware/targets/f5/Src/fatfs/stm32_adafruit_sd.c index 21b3e9b3..c00ed04a 100644 --- a/firmware/targets/f5/Src/fatfs/stm32_adafruit_sd.c +++ b/firmware/targets/f5/Src/fatfs/stm32_adafruit_sd.c @@ -295,9 +295,9 @@ static uint8_t SD_ReadData(void); */ uint8_t BSP_SD_Init(bool reset_card) { /* Slow speed init */ - - /* TODO: SPI manager */ - api_hal_spi_lock_device(&sd_slow_spi); + const ApiHalSpiDevice* sd_spi_slow_dev = &api_hal_spi_devices[ApiHalSpiDeviceIdSdCardSlow]; + api_hal_spi_bus_lock(sd_spi_slow_dev->bus); + api_hal_spi_bus_configure(sd_spi_slow_dev->bus, sd_spi_slow_dev->config); /* We must reset card in spi_lock context */ if(reset_card) { @@ -326,8 +326,7 @@ uint8_t BSP_SD_Init(bool reset_card) { if(res == BSP_SD_OK) break; } - /* TODO: SPI manager */ - api_hal_spi_unlock_device(&sd_slow_spi); + api_hal_spi_bus_unlock(sd_spi_slow_dev->bus); /* SD initialized and set to SPI mode properly */ return res; diff --git a/firmware/targets/f5/Src/fatfs/user_diskio.c b/firmware/targets/f5/Src/fatfs/user_diskio.c index 7fb51e06..f0f03560 100644 --- a/firmware/targets/f5/Src/fatfs/user_diskio.c +++ b/firmware/targets/f5/Src/fatfs/user_diskio.c @@ -52,6 +52,8 @@ static DSTATUS User_CheckStatus(BYTE lun) { return Stat; } + +static const ApiHalSpiDevice* sd_spi_fast_dev = &api_hal_spi_devices[ApiHalSpiDeviceIdSdCardFast]; /* USER CODE END DECL */ /* Private function prototypes -----------------------------------------------*/ @@ -86,13 +88,13 @@ Diskio_drvTypeDef USER_Driver = { */ DSTATUS USER_initialize(BYTE pdrv) { /* USER CODE BEGIN INIT */ - // TODO: SPI manager - api_hal_spi_lock_device(&sd_fast_spi); + + api_hal_spi_bus_lock(sd_spi_fast_dev->bus); + api_hal_spi_bus_configure(sd_spi_fast_dev->bus, sd_spi_fast_dev->config); DSTATUS status = User_CheckStatus(pdrv); - // TODO: SPI manager - api_hal_spi_unlock_device(&sd_fast_spi); + api_hal_spi_bus_unlock(sd_spi_fast_dev->bus); return status; /* USER CODE END INIT */ @@ -121,8 +123,8 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { /* USER CODE BEGIN READ */ DRESULT res = RES_ERROR; - // TODO: SPI manager - api_hal_spi_lock_device(&sd_fast_spi); + api_hal_spi_bus_lock(sd_spi_fast_dev->bus); + api_hal_spi_bus_configure(sd_spi_fast_dev->bus, sd_spi_fast_dev->config); if(BSP_SD_ReadBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) { /* wait until the read operation is finished */ @@ -131,8 +133,7 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { res = RES_OK; } - // TODO: SPI manager - api_hal_spi_unlock_device(&sd_fast_spi); + api_hal_spi_bus_unlock(sd_spi_fast_dev->bus); return res; /* USER CODE END READ */ @@ -152,8 +153,8 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { /* USER CODE HERE */ DRESULT res = RES_ERROR; - // TODO: SPI manager - api_hal_spi_lock_device(&sd_fast_spi); + api_hal_spi_bus_lock(sd_spi_fast_dev->bus); + api_hal_spi_bus_configure(sd_spi_fast_dev->bus, sd_spi_fast_dev->config); if(BSP_SD_WriteBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) { /* wait until the Write operation is finished */ @@ -162,8 +163,7 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { res = RES_OK; } - // TODO: SPI manager - api_hal_spi_unlock_device(&sd_fast_spi); + api_hal_spi_bus_unlock(sd_spi_fast_dev->bus); return res; /* USER CODE END WRITE */ @@ -185,8 +185,8 @@ DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) { if(Stat & STA_NOINIT) return RES_NOTRDY; - // TODO: SPI manager - api_hal_spi_lock_device(&sd_fast_spi); + api_hal_spi_bus_lock(sd_spi_fast_dev->bus); + api_hal_spi_bus_configure(sd_spi_fast_dev->bus, sd_spi_fast_dev->config); switch(cmd) { /* Make sure that no pending write process */ @@ -219,8 +219,7 @@ DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) { res = RES_PARERR; } - // TODO: SPI manager - api_hal_spi_unlock_device(&sd_fast_spi); + api_hal_spi_bus_unlock(sd_spi_fast_dev->bus); return res; /* USER CODE END IOCTL */ diff --git a/firmware/targets/f5/api-hal/api-hal-spi-config.c b/firmware/targets/f5/api-hal/api-hal-spi-config.c index f9f795f7..51a1729e 100644 --- a/firmware/targets/f5/api-hal/api-hal-spi-config.c +++ b/firmware/targets/f5/api-hal/api-hal-spi-config.c @@ -52,6 +52,44 @@ const SPI_InitTypeDef api_hal_spi_config_display = { .NSSPMode = SPI_NSS_PULSE_ENABLE, }; +/** + * SD Card in fast mode (after init) + */ +const SPI_InitTypeDef api_hal_spi_config_sd_fast = { + .Mode = SPI_MODE_MASTER, + .Direction = SPI_DIRECTION_2LINES, + .DataSize = SPI_DATASIZE_8BIT, + .CLKPolarity = SPI_POLARITY_LOW, + .CLKPhase = SPI_PHASE_1EDGE, + .NSS = SPI_NSS_SOFT, + .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2, + .FirstBit = SPI_FIRSTBIT_MSB, + .TIMode = SPI_TIMODE_DISABLE, + .CRCCalculation = SPI_CRCCALCULATION_DISABLE, + .CRCPolynomial = 7, + .CRCLength = SPI_CRC_LENGTH_DATASIZE, + .NSSPMode = SPI_NSS_PULSE_ENABLE, +}; + +/** + * SD Card in slow mode (before init) + */ +const SPI_InitTypeDef api_hal_spi_config_sd_slow = { + .Mode = SPI_MODE_MASTER, + .Direction = SPI_DIRECTION_2LINES, + .DataSize = SPI_DATASIZE_8BIT, + .CLKPolarity = SPI_POLARITY_LOW, + .CLKPhase = SPI_PHASE_1EDGE, + .NSS = SPI_NSS_SOFT, + .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32, + .FirstBit = SPI_FIRSTBIT_MSB, + .TIMode = SPI_TIMODE_DISABLE, + .CRCCalculation = SPI_CRCCALCULATION_DISABLE, + .CRCPolynomial = 7, + .CRCLength = SPI_CRC_LENGTH_DATASIZE, + .NSSPMode = SPI_NSS_PULSE_ENABLE, +}; + osMutexId_t spi_mutex_d = NULL; osMutexId_t spi_mutex_r = NULL; @@ -74,49 +112,7 @@ const ApiHalSpiBus spi_d = { const ApiHalSpiDevice api_hal_spi_devices[ApiHalSpiDeviceIdMax] = { { .bus=&spi_r, .config=&api_hal_spi_config_subghz, .chip_select=&gpio_subghz_cs, }, { .bus=&spi_d, .config=&api_hal_spi_config_display, .chip_select=&gpio_display_cs, }, - { .bus=&spi_d, .config=NULL, .chip_select=&gpio_sdcard_cs, }, + { .bus=&spi_d, .config=&api_hal_spi_config_sd_fast, .chip_select=&gpio_sdcard_cs, }, + { .bus=&spi_d, .config=&api_hal_spi_config_sd_slow, .chip_select=&gpio_sdcard_cs, }, { .bus=&spi_r, .config=&api_hal_spi_config_nfc, .chip_select=&gpio_nfc_cs }, }; - - -/** - * SD Card in fast mode (after init) - */ -const SPIDevice sd_fast_spi = { - .bus= &spi_d, - .config = { - .Mode = SPI_MODE_MASTER, - .Direction = SPI_DIRECTION_2LINES, - .DataSize = SPI_DATASIZE_8BIT, - .CLKPolarity = SPI_POLARITY_LOW, - .CLKPhase = SPI_PHASE_1EDGE, - .NSS = SPI_NSS_SOFT, - .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2, - .FirstBit = SPI_FIRSTBIT_MSB, - .TIMode = SPI_TIMODE_DISABLE, - .CRCCalculation = SPI_CRCCALCULATION_DISABLE, - .CRCPolynomial = 7, - .CRCLength = SPI_CRC_LENGTH_DATASIZE, - .NSSPMode = SPI_NSS_PULSE_ENABLE, - }}; - -/** - * SD Card in slow mode (before init) - */ -const SPIDevice sd_slow_spi = { - .bus= &spi_d, - .config = { - .Mode = SPI_MODE_MASTER, - .Direction = SPI_DIRECTION_2LINES, - .DataSize = SPI_DATASIZE_8BIT, - .CLKPolarity = SPI_POLARITY_LOW, - .CLKPhase = SPI_PHASE_1EDGE, - .NSS = SPI_NSS_SOFT, - .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32, - .FirstBit = SPI_FIRSTBIT_MSB, - .TIMode = SPI_TIMODE_DISABLE, - .CRCCalculation = SPI_CRCCALCULATION_DISABLE, - .CRCPolynomial = 7, - .CRCLength = SPI_CRC_LENGTH_DATASIZE, - .NSSPMode = SPI_NSS_PULSE_ENABLE, - }}; diff --git a/firmware/targets/f5/api-hal/api-hal-spi-config.h b/firmware/targets/f5/api-hal/api-hal-spi-config.h index dd0b2215..c8a3da1b 100644 --- a/firmware/targets/f5/api-hal/api-hal-spi-config.h +++ b/firmware/targets/f5/api-hal/api-hal-spi-config.h @@ -10,6 +10,8 @@ extern "C" { extern const SPI_InitTypeDef api_hal_spi_config_nfc; extern const SPI_InitTypeDef api_hal_spi_config_subghz; extern const SPI_InitTypeDef api_hal_spi_config_display; +extern const SPI_InitTypeDef api_hal_spi_config_sd_fast; +extern const SPI_InitTypeDef api_hal_spi_config_sd_slow; /** API HAL SPI BUS handler * Structure content may change at some point @@ -33,12 +35,13 @@ typedef struct { /** API HAL SPI Standard Device IDs */ typedef enum { - ApiHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */ - ApiHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */ - ApiHalSpiDeviceIdSdCard, /** SDCARD: no default bus config, bus must explicitly be configured */ - ApiHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */ + ApiHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */ + ApiHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */ + ApiHalSpiDeviceIdSdCardFast, /** SDCARD: fast mode, after initialization */ + ApiHalSpiDeviceIdSdCardSlow, /** SDCARD: slow mode, before initialization */ + ApiHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */ - ApiHalSpiDeviceIdMax, /** Service Value, do not use */ + ApiHalSpiDeviceIdMax, /** Service Value, do not use */ } ApiHalSpiDeviceId; /** Api Hal Spi Bus R @@ -59,9 +62,6 @@ typedef struct { const SPI_InitTypeDef config; } SPIDevice; -extern const SPIDevice sd_fast_spi; -extern const SPIDevice sd_slow_spi; - #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/firmware/targets/f5/api-hal/api-hal-spi.c b/firmware/targets/f5/api-hal/api-hal-spi.c index 754e109c..6991e3a6 100644 --- a/firmware/targets/f5/api-hal/api-hal-spi.c +++ b/firmware/targets/f5/api-hal/api-hal-spi.c @@ -38,6 +38,26 @@ void api_hal_spi_bus_unlock(const ApiHalSpiBus* bus) { } } +void api_hal_spi_bus_configure(const ApiHalSpiBus* bus, const SPI_InitTypeDef* config) { + furi_assert(bus); + + if(memcmp(&bus->spi->Init, config, sizeof(SPI_InitTypeDef))) { + memcpy((SPI_InitTypeDef*)&bus->spi->Init, config, sizeof(SPI_InitTypeDef)); + if(HAL_SPI_Init((SPI_HandleTypeDef*)bus->spi) != HAL_OK) { + Error_Handler(); + } + Enable_SPI((SPI_HandleTypeDef*)bus->spi); + } +} + +void api_hal_spi_bus_reset(const ApiHalSpiBus* bus) { + furi_assert(bus); + + HAL_SPI_DeInit((SPI_HandleTypeDef*)bus->spi); + HAL_SPI_Init((SPI_HandleTypeDef*)bus->spi); + Enable_SPI((SPI_HandleTypeDef*)bus->spi); +} + bool api_hal_spi_bus_rx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { furi_assert(bus); furi_assert(buffer); @@ -145,36 +165,3 @@ bool api_hal_spi_device_trx(const ApiHalSpiDevice* device, uint8_t* tx_buffer, u return ret; } - -void api_hal_spi_apply_config(const SPIDevice* device) { - osKernelLock(); - - memcpy((SPI_InitTypeDef*)&device->bus->spi->Init, &device->config, sizeof(SPI_InitTypeDef)); - - if(HAL_SPI_Init((SPI_HandleTypeDef*)device->bus->spi) != HAL_OK) { - Error_Handler(); - } - - Enable_SPI((SPI_HandleTypeDef*)device->bus->spi); - - osKernelUnlock(); -} - -bool api_hal_spi_config_are_actual(const SPIDevice* device) { - return (memcmp(&device->config, &device->bus->spi->Init, sizeof(SPI_InitTypeDef)) == 0); -} - -void api_hal_spi_config_device(const SPIDevice* device) { - if(!api_hal_spi_config_are_actual(device)) { - api_hal_spi_apply_config(device); - } -} - -void api_hal_spi_lock_device(const SPIDevice* device) { - api_hal_spi_bus_lock(device->bus); - api_hal_spi_config_device(device); -} - -void api_hal_spi_unlock_device(const SPIDevice* device) { - api_hal_spi_bus_unlock(device->bus); -} diff --git a/firmware/targets/f5/api-hal/api-hal-spi.h b/firmware/targets/f5/api-hal/api-hal-spi.h index 21d319bb..849bcf5a 100644 --- a/firmware/targets/f5/api-hal/api-hal-spi.h +++ b/firmware/targets/f5/api-hal/api-hal-spi.h @@ -25,6 +25,19 @@ void api_hal_spi_bus_lock(const ApiHalSpiBus* bus); */ void api_hal_spi_bus_unlock(const ApiHalSpiBus* bus); +/** + * Configure SPI bus + * @param bus - spi bus handler + * @param config - spi configuration structure + */ +void api_hal_spi_bus_configure(const ApiHalSpiBus* bus, const SPI_InitTypeDef* config); + +/** + * Reset SPI bus + * @param bus - spi bus handler + */ +void api_hal_spi_bus_reset(const ApiHalSpiBus* bus); + /** SPI Receive * @param bus - spi bus handler * @param buffer - receive buffer diff --git a/firmware/targets/f6/Src/fatfs/spi_sd_hal.c b/firmware/targets/f6/Src/fatfs/spi_sd_hal.c index 0cad29f7..386c8081 100644 --- a/firmware/targets/f6/Src/fatfs/spi_sd_hal.c +++ b/firmware/targets/f6/Src/fatfs/spi_sd_hal.c @@ -1,12 +1,12 @@ #include "main.h" +#include "api-hal-spi.h" #define SD_DUMMY_BYTE 0xFF -#define SD_CS_LOW() HAL_GPIO_WritePin(SD_CS_GPIO_Port, SD_CS_Pin, GPIO_PIN_RESET) -#define SD_CS_HIGH() HAL_GPIO_WritePin(SD_CS_GPIO_Port, SD_CS_Pin, GPIO_PIN_SET) const uint32_t SpiTimeout = 1000; -extern SPI_HandleTypeDef SPI_SD_HANDLE; uint8_t SD_IO_WriteByte(uint8_t Data); +static const ApiHalSpiDevice* sd_spi_dev = &api_hal_spi_devices[ApiHalSpiDeviceIdSdCardFast]; + /****************************************************************************** BUS OPERATIONS @@ -17,11 +17,8 @@ uint8_t SD_IO_WriteByte(uint8_t Data); * @retval None */ static void SPIx_Error(void) { - /* De-initialize the SPI communication BUS */ - HAL_SPI_DeInit(&SPI_SD_HANDLE); - /* Re-Initiaize the SPI communication BUS */ - HAL_SPI_Init(&SPI_SD_HANDLE); + api_hal_spi_bus_reset(sd_spi_dev->bus); } /** @@ -32,12 +29,10 @@ static void SPIx_Error(void) { * @retval None */ static void SPIx_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t DataLength) { - HAL_StatusTypeDef status = HAL_OK; - status = - HAL_SPI_TransmitReceive(&SPI_SD_HANDLE, (uint8_t*)DataIn, DataOut, DataLength, SpiTimeout); + bool status = api_hal_spi_bus_trx(sd_spi_dev->bus, (uint8_t*)DataIn, DataOut, DataLength, SpiTimeout); /* Check the communication status */ - if(status != HAL_OK) { + if(!status) { /* Execute user timeout callback */ SPIx_Error(); } @@ -49,13 +44,12 @@ static void SPIx_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t * @retval None */ __attribute__((unused)) static void SPIx_Write(uint8_t Value) { - HAL_StatusTypeDef status = HAL_OK; uint8_t data; - status = HAL_SPI_TransmitReceive(&SPI_SD_HANDLE, (uint8_t*)&Value, &data, 1, SpiTimeout); + bool status = api_hal_spi_bus_trx(sd_spi_dev->bus, (uint8_t*)&Value, &data, 1, SpiTimeout); /* Check the communication status */ - if(status != HAL_OK) { + if(!status) { /* Execute user timeout callback */ SPIx_Error(); } @@ -75,7 +69,7 @@ void SD_IO_Init(void) { uint8_t counter = 0; /* SD chip select high */ - SD_CS_HIGH(); + hal_gpio_write(sd_spi_dev->chip_select, true); /* Send dummy byte 0xFF, 10 times with CS high */ /* Rise CS and MOSI for 80 clocks cycles */ @@ -92,9 +86,9 @@ void SD_IO_Init(void) { */ void SD_IO_CSState(uint8_t val) { if(val == 1) { - SD_CS_HIGH(); + hal_gpio_write(sd_spi_dev->chip_select, true); } else { - SD_CS_LOW(); + hal_gpio_write(sd_spi_dev->chip_select, false); } } diff --git a/firmware/targets/f6/Src/fatfs/stm32_adafruit_sd.c b/firmware/targets/f6/Src/fatfs/stm32_adafruit_sd.c index 21b3e9b3..c00ed04a 100644 --- a/firmware/targets/f6/Src/fatfs/stm32_adafruit_sd.c +++ b/firmware/targets/f6/Src/fatfs/stm32_adafruit_sd.c @@ -295,9 +295,9 @@ static uint8_t SD_ReadData(void); */ uint8_t BSP_SD_Init(bool reset_card) { /* Slow speed init */ - - /* TODO: SPI manager */ - api_hal_spi_lock_device(&sd_slow_spi); + const ApiHalSpiDevice* sd_spi_slow_dev = &api_hal_spi_devices[ApiHalSpiDeviceIdSdCardSlow]; + api_hal_spi_bus_lock(sd_spi_slow_dev->bus); + api_hal_spi_bus_configure(sd_spi_slow_dev->bus, sd_spi_slow_dev->config); /* We must reset card in spi_lock context */ if(reset_card) { @@ -326,8 +326,7 @@ uint8_t BSP_SD_Init(bool reset_card) { if(res == BSP_SD_OK) break; } - /* TODO: SPI manager */ - api_hal_spi_unlock_device(&sd_slow_spi); + api_hal_spi_bus_unlock(sd_spi_slow_dev->bus); /* SD initialized and set to SPI mode properly */ return res; diff --git a/firmware/targets/f6/Src/fatfs/user_diskio.c b/firmware/targets/f6/Src/fatfs/user_diskio.c index 7fb51e06..f0f03560 100644 --- a/firmware/targets/f6/Src/fatfs/user_diskio.c +++ b/firmware/targets/f6/Src/fatfs/user_diskio.c @@ -52,6 +52,8 @@ static DSTATUS User_CheckStatus(BYTE lun) { return Stat; } + +static const ApiHalSpiDevice* sd_spi_fast_dev = &api_hal_spi_devices[ApiHalSpiDeviceIdSdCardFast]; /* USER CODE END DECL */ /* Private function prototypes -----------------------------------------------*/ @@ -86,13 +88,13 @@ Diskio_drvTypeDef USER_Driver = { */ DSTATUS USER_initialize(BYTE pdrv) { /* USER CODE BEGIN INIT */ - // TODO: SPI manager - api_hal_spi_lock_device(&sd_fast_spi); + + api_hal_spi_bus_lock(sd_spi_fast_dev->bus); + api_hal_spi_bus_configure(sd_spi_fast_dev->bus, sd_spi_fast_dev->config); DSTATUS status = User_CheckStatus(pdrv); - // TODO: SPI manager - api_hal_spi_unlock_device(&sd_fast_spi); + api_hal_spi_bus_unlock(sd_spi_fast_dev->bus); return status; /* USER CODE END INIT */ @@ -121,8 +123,8 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { /* USER CODE BEGIN READ */ DRESULT res = RES_ERROR; - // TODO: SPI manager - api_hal_spi_lock_device(&sd_fast_spi); + api_hal_spi_bus_lock(sd_spi_fast_dev->bus); + api_hal_spi_bus_configure(sd_spi_fast_dev->bus, sd_spi_fast_dev->config); if(BSP_SD_ReadBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) { /* wait until the read operation is finished */ @@ -131,8 +133,7 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { res = RES_OK; } - // TODO: SPI manager - api_hal_spi_unlock_device(&sd_fast_spi); + api_hal_spi_bus_unlock(sd_spi_fast_dev->bus); return res; /* USER CODE END READ */ @@ -152,8 +153,8 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { /* USER CODE HERE */ DRESULT res = RES_ERROR; - // TODO: SPI manager - api_hal_spi_lock_device(&sd_fast_spi); + api_hal_spi_bus_lock(sd_spi_fast_dev->bus); + api_hal_spi_bus_configure(sd_spi_fast_dev->bus, sd_spi_fast_dev->config); if(BSP_SD_WriteBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) { /* wait until the Write operation is finished */ @@ -162,8 +163,7 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { res = RES_OK; } - // TODO: SPI manager - api_hal_spi_unlock_device(&sd_fast_spi); + api_hal_spi_bus_unlock(sd_spi_fast_dev->bus); return res; /* USER CODE END WRITE */ @@ -185,8 +185,8 @@ DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) { if(Stat & STA_NOINIT) return RES_NOTRDY; - // TODO: SPI manager - api_hal_spi_lock_device(&sd_fast_spi); + api_hal_spi_bus_lock(sd_spi_fast_dev->bus); + api_hal_spi_bus_configure(sd_spi_fast_dev->bus, sd_spi_fast_dev->config); switch(cmd) { /* Make sure that no pending write process */ @@ -219,8 +219,7 @@ DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) { res = RES_PARERR; } - // TODO: SPI manager - api_hal_spi_unlock_device(&sd_fast_spi); + api_hal_spi_bus_unlock(sd_spi_fast_dev->bus); return res; /* USER CODE END IOCTL */ diff --git a/firmware/targets/f6/api-hal/api-hal-spi-config.c b/firmware/targets/f6/api-hal/api-hal-spi-config.c index f9f795f7..51a1729e 100644 --- a/firmware/targets/f6/api-hal/api-hal-spi-config.c +++ b/firmware/targets/f6/api-hal/api-hal-spi-config.c @@ -52,6 +52,44 @@ const SPI_InitTypeDef api_hal_spi_config_display = { .NSSPMode = SPI_NSS_PULSE_ENABLE, }; +/** + * SD Card in fast mode (after init) + */ +const SPI_InitTypeDef api_hal_spi_config_sd_fast = { + .Mode = SPI_MODE_MASTER, + .Direction = SPI_DIRECTION_2LINES, + .DataSize = SPI_DATASIZE_8BIT, + .CLKPolarity = SPI_POLARITY_LOW, + .CLKPhase = SPI_PHASE_1EDGE, + .NSS = SPI_NSS_SOFT, + .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2, + .FirstBit = SPI_FIRSTBIT_MSB, + .TIMode = SPI_TIMODE_DISABLE, + .CRCCalculation = SPI_CRCCALCULATION_DISABLE, + .CRCPolynomial = 7, + .CRCLength = SPI_CRC_LENGTH_DATASIZE, + .NSSPMode = SPI_NSS_PULSE_ENABLE, +}; + +/** + * SD Card in slow mode (before init) + */ +const SPI_InitTypeDef api_hal_spi_config_sd_slow = { + .Mode = SPI_MODE_MASTER, + .Direction = SPI_DIRECTION_2LINES, + .DataSize = SPI_DATASIZE_8BIT, + .CLKPolarity = SPI_POLARITY_LOW, + .CLKPhase = SPI_PHASE_1EDGE, + .NSS = SPI_NSS_SOFT, + .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32, + .FirstBit = SPI_FIRSTBIT_MSB, + .TIMode = SPI_TIMODE_DISABLE, + .CRCCalculation = SPI_CRCCALCULATION_DISABLE, + .CRCPolynomial = 7, + .CRCLength = SPI_CRC_LENGTH_DATASIZE, + .NSSPMode = SPI_NSS_PULSE_ENABLE, +}; + osMutexId_t spi_mutex_d = NULL; osMutexId_t spi_mutex_r = NULL; @@ -74,49 +112,7 @@ const ApiHalSpiBus spi_d = { const ApiHalSpiDevice api_hal_spi_devices[ApiHalSpiDeviceIdMax] = { { .bus=&spi_r, .config=&api_hal_spi_config_subghz, .chip_select=&gpio_subghz_cs, }, { .bus=&spi_d, .config=&api_hal_spi_config_display, .chip_select=&gpio_display_cs, }, - { .bus=&spi_d, .config=NULL, .chip_select=&gpio_sdcard_cs, }, + { .bus=&spi_d, .config=&api_hal_spi_config_sd_fast, .chip_select=&gpio_sdcard_cs, }, + { .bus=&spi_d, .config=&api_hal_spi_config_sd_slow, .chip_select=&gpio_sdcard_cs, }, { .bus=&spi_r, .config=&api_hal_spi_config_nfc, .chip_select=&gpio_nfc_cs }, }; - - -/** - * SD Card in fast mode (after init) - */ -const SPIDevice sd_fast_spi = { - .bus= &spi_d, - .config = { - .Mode = SPI_MODE_MASTER, - .Direction = SPI_DIRECTION_2LINES, - .DataSize = SPI_DATASIZE_8BIT, - .CLKPolarity = SPI_POLARITY_LOW, - .CLKPhase = SPI_PHASE_1EDGE, - .NSS = SPI_NSS_SOFT, - .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2, - .FirstBit = SPI_FIRSTBIT_MSB, - .TIMode = SPI_TIMODE_DISABLE, - .CRCCalculation = SPI_CRCCALCULATION_DISABLE, - .CRCPolynomial = 7, - .CRCLength = SPI_CRC_LENGTH_DATASIZE, - .NSSPMode = SPI_NSS_PULSE_ENABLE, - }}; - -/** - * SD Card in slow mode (before init) - */ -const SPIDevice sd_slow_spi = { - .bus= &spi_d, - .config = { - .Mode = SPI_MODE_MASTER, - .Direction = SPI_DIRECTION_2LINES, - .DataSize = SPI_DATASIZE_8BIT, - .CLKPolarity = SPI_POLARITY_LOW, - .CLKPhase = SPI_PHASE_1EDGE, - .NSS = SPI_NSS_SOFT, - .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32, - .FirstBit = SPI_FIRSTBIT_MSB, - .TIMode = SPI_TIMODE_DISABLE, - .CRCCalculation = SPI_CRCCALCULATION_DISABLE, - .CRCPolynomial = 7, - .CRCLength = SPI_CRC_LENGTH_DATASIZE, - .NSSPMode = SPI_NSS_PULSE_ENABLE, - }}; diff --git a/firmware/targets/f6/api-hal/api-hal-spi-config.h b/firmware/targets/f6/api-hal/api-hal-spi-config.h index dd0b2215..c8a3da1b 100644 --- a/firmware/targets/f6/api-hal/api-hal-spi-config.h +++ b/firmware/targets/f6/api-hal/api-hal-spi-config.h @@ -10,6 +10,8 @@ extern "C" { extern const SPI_InitTypeDef api_hal_spi_config_nfc; extern const SPI_InitTypeDef api_hal_spi_config_subghz; extern const SPI_InitTypeDef api_hal_spi_config_display; +extern const SPI_InitTypeDef api_hal_spi_config_sd_fast; +extern const SPI_InitTypeDef api_hal_spi_config_sd_slow; /** API HAL SPI BUS handler * Structure content may change at some point @@ -33,12 +35,13 @@ typedef struct { /** API HAL SPI Standard Device IDs */ typedef enum { - ApiHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */ - ApiHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */ - ApiHalSpiDeviceIdSdCard, /** SDCARD: no default bus config, bus must explicitly be configured */ - ApiHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */ + ApiHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */ + ApiHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */ + ApiHalSpiDeviceIdSdCardFast, /** SDCARD: fast mode, after initialization */ + ApiHalSpiDeviceIdSdCardSlow, /** SDCARD: slow mode, before initialization */ + ApiHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */ - ApiHalSpiDeviceIdMax, /** Service Value, do not use */ + ApiHalSpiDeviceIdMax, /** Service Value, do not use */ } ApiHalSpiDeviceId; /** Api Hal Spi Bus R @@ -59,9 +62,6 @@ typedef struct { const SPI_InitTypeDef config; } SPIDevice; -extern const SPIDevice sd_fast_spi; -extern const SPIDevice sd_slow_spi; - #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/firmware/targets/f6/api-hal/api-hal-spi.c b/firmware/targets/f6/api-hal/api-hal-spi.c index 754e109c..6991e3a6 100644 --- a/firmware/targets/f6/api-hal/api-hal-spi.c +++ b/firmware/targets/f6/api-hal/api-hal-spi.c @@ -38,6 +38,26 @@ void api_hal_spi_bus_unlock(const ApiHalSpiBus* bus) { } } +void api_hal_spi_bus_configure(const ApiHalSpiBus* bus, const SPI_InitTypeDef* config) { + furi_assert(bus); + + if(memcmp(&bus->spi->Init, config, sizeof(SPI_InitTypeDef))) { + memcpy((SPI_InitTypeDef*)&bus->spi->Init, config, sizeof(SPI_InitTypeDef)); + if(HAL_SPI_Init((SPI_HandleTypeDef*)bus->spi) != HAL_OK) { + Error_Handler(); + } + Enable_SPI((SPI_HandleTypeDef*)bus->spi); + } +} + +void api_hal_spi_bus_reset(const ApiHalSpiBus* bus) { + furi_assert(bus); + + HAL_SPI_DeInit((SPI_HandleTypeDef*)bus->spi); + HAL_SPI_Init((SPI_HandleTypeDef*)bus->spi); + Enable_SPI((SPI_HandleTypeDef*)bus->spi); +} + bool api_hal_spi_bus_rx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { furi_assert(bus); furi_assert(buffer); @@ -145,36 +165,3 @@ bool api_hal_spi_device_trx(const ApiHalSpiDevice* device, uint8_t* tx_buffer, u return ret; } - -void api_hal_spi_apply_config(const SPIDevice* device) { - osKernelLock(); - - memcpy((SPI_InitTypeDef*)&device->bus->spi->Init, &device->config, sizeof(SPI_InitTypeDef)); - - if(HAL_SPI_Init((SPI_HandleTypeDef*)device->bus->spi) != HAL_OK) { - Error_Handler(); - } - - Enable_SPI((SPI_HandleTypeDef*)device->bus->spi); - - osKernelUnlock(); -} - -bool api_hal_spi_config_are_actual(const SPIDevice* device) { - return (memcmp(&device->config, &device->bus->spi->Init, sizeof(SPI_InitTypeDef)) == 0); -} - -void api_hal_spi_config_device(const SPIDevice* device) { - if(!api_hal_spi_config_are_actual(device)) { - api_hal_spi_apply_config(device); - } -} - -void api_hal_spi_lock_device(const SPIDevice* device) { - api_hal_spi_bus_lock(device->bus); - api_hal_spi_config_device(device); -} - -void api_hal_spi_unlock_device(const SPIDevice* device) { - api_hal_spi_bus_unlock(device->bus); -} diff --git a/firmware/targets/f6/api-hal/api-hal-spi.h b/firmware/targets/f6/api-hal/api-hal-spi.h index 21d319bb..849bcf5a 100644 --- a/firmware/targets/f6/api-hal/api-hal-spi.h +++ b/firmware/targets/f6/api-hal/api-hal-spi.h @@ -25,6 +25,19 @@ void api_hal_spi_bus_lock(const ApiHalSpiBus* bus); */ void api_hal_spi_bus_unlock(const ApiHalSpiBus* bus); +/** + * Configure SPI bus + * @param bus - spi bus handler + * @param config - spi configuration structure + */ +void api_hal_spi_bus_configure(const ApiHalSpiBus* bus, const SPI_InitTypeDef* config); + +/** + * Reset SPI bus + * @param bus - spi bus handler + */ +void api_hal_spi_bus_reset(const ApiHalSpiBus* bus); + /** SPI Receive * @param bus - spi bus handler * @param buffer - receive buffer