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:
Diffstat (limited to 'firmware/targets/f7/furi-hal/furi-hal-spi.c')
-rw-r--r--firmware/targets/f7/furi-hal/furi-hal-spi.c196
1 files changed, 67 insertions, 129 deletions
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;
}