mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-12-17 18:31:36 +03:00
37d7870e52
* FuriHal: port spi to ll. Bootloader: add spi and display. * Makefile: rollback disabled freertos introspection * FuriHal: spi lock asserts. F6: minor cleanup port sdcard shenanigans to furi_hal_gpio. * SdCard: port missing bits to furi-hal-gpio * FuriHal: fix broken RX in SPI, update SPI API usage. RFAL: more asserts in SPI platform code. * GUI: clear canvas on start. FuriHal: no pullup on radio spi bus. * FuriHal: use check instead of assert in spi lock routines * FuriHal: remove timeouts * SdHal: add guard time to SDCARD CS PIN control. * FuriHal: proper name for SPI device reconfigure routine. SdHal: one more enterprise delay and better documentation. * Bootloader: update DFU text and add image. * FuriHal: drop unused ST HAL modules. * SdHal: fixed swapped hal_gpio_init_ex arguments * SpiHal: fixed swapped hal_gpio_init_ex arguments * IrdaHal: use hal_gpio_init instead of hal_gpio_init_ex * RfidHal: fixed swapped hal_gpio_init_ex arguments Co-authored-by: DrZlo13 <who.just.the.doctor@gmail.com>
241 lines
5.9 KiB
C
241 lines
5.9 KiB
C
#include "furi-hal-spi.h"
|
|
#include "furi-hal-resources.h"
|
|
|
|
#include <stdbool.h>
|
|
#include <assert.h>
|
|
|
|
#include <stm32wbxx_ll_spi.h>
|
|
#include <stm32wbxx_ll_utils.h>
|
|
#include <stm32wbxx_ll_cortex.h>
|
|
|
|
extern void Enable_SPI(SPI_TypeDef* spi);
|
|
|
|
void furi_hal_spi_init() {
|
|
for(size_t i = 0; i < FuriHalSpiDeviceIdMax; ++i) {
|
|
hal_gpio_write(furi_hal_spi_devices[i].chip_select, true);
|
|
hal_gpio_init(
|
|
furi_hal_spi_devices[i].chip_select,
|
|
GpioModeOutputPushPull,
|
|
GpioPullNo,
|
|
GpioSpeedVeryHigh);
|
|
}
|
|
|
|
hal_gpio_init_ex(
|
|
&gpio_spi_r_miso,
|
|
GpioModeAltFunctionPushPull,
|
|
GpioPullNo,
|
|
GpioSpeedVeryHigh,
|
|
GpioAltFn5SPI1);
|
|
hal_gpio_init_ex(
|
|
&gpio_spi_r_mosi,
|
|
GpioModeAltFunctionPushPull,
|
|
GpioPullNo,
|
|
GpioSpeedVeryHigh,
|
|
GpioAltFn5SPI1);
|
|
hal_gpio_init_ex(
|
|
&gpio_spi_r_sck,
|
|
GpioModeAltFunctionPushPull,
|
|
GpioPullNo,
|
|
GpioSpeedVeryHigh,
|
|
GpioAltFn5SPI1);
|
|
|
|
hal_gpio_init_ex(
|
|
&gpio_spi_d_miso,
|
|
GpioModeAltFunctionPushPull,
|
|
GpioPullUp,
|
|
GpioSpeedVeryHigh,
|
|
GpioAltFn5SPI2);
|
|
hal_gpio_init_ex(
|
|
&gpio_spi_d_mosi,
|
|
GpioModeAltFunctionPushPull,
|
|
GpioPullUp,
|
|
GpioSpeedVeryHigh,
|
|
GpioAltFn5SPI2);
|
|
hal_gpio_init_ex(
|
|
&gpio_spi_d_sck,
|
|
GpioModeAltFunctionPushPull,
|
|
GpioPullUp,
|
|
GpioSpeedVeryHigh,
|
|
GpioAltFn5SPI2);
|
|
}
|
|
|
|
void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus) {
|
|
assert(bus);
|
|
}
|
|
|
|
void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus) {
|
|
assert(bus);
|
|
}
|
|
|
|
void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config) {
|
|
assert(bus);
|
|
LL_SPI_DeInit((SPI_TypeDef*)bus->spi);
|
|
LL_SPI_Init((SPI_TypeDef*)bus->spi, (LL_SPI_InitTypeDef*)config);
|
|
LL_SPI_SetRxFIFOThreshold((SPI_TypeDef*)bus->spi, LL_SPI_RX_FIFO_TH_QUARTER);
|
|
LL_SPI_Enable((SPI_TypeDef*)bus->spi);
|
|
}
|
|
|
|
void furi_hal_spi_bus_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);
|
|
}
|
|
}
|
|
|
|
bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) {
|
|
assert(bus);
|
|
assert(buffer);
|
|
assert(size > 0);
|
|
|
|
return furi_hal_spi_bus_trx(bus, buffer, buffer, size, timeout);
|
|
}
|
|
|
|
bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) {
|
|
assert(bus);
|
|
assert(buffer);
|
|
assert(size > 0);
|
|
bool ret = true;
|
|
|
|
while(size > 0) {
|
|
if(LL_SPI_IsActiveFlag_TXE((SPI_TypeDef*)bus->spi)) {
|
|
LL_SPI_TransmitData8((SPI_TypeDef*)bus->spi, *buffer);
|
|
buffer++;
|
|
size--;
|
|
}
|
|
}
|
|
|
|
furi_hal_spi_bus_end_txrx(bus, timeout);
|
|
LL_SPI_ClearFlag_OVR((SPI_TypeDef*)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) {
|
|
assert(bus);
|
|
assert(tx_buffer);
|
|
assert(rx_buffer);
|
|
assert(size > 0);
|
|
bool ret = true;
|
|
size_t tx_size = size;
|
|
bool tx_allowed = true;
|
|
|
|
while(size > 0) {
|
|
if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE((SPI_TypeDef*)bus->spi) && tx_allowed) {
|
|
LL_SPI_TransmitData8((SPI_TypeDef*)bus->spi, *tx_buffer);
|
|
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);
|
|
rx_buffer++;
|
|
size--;
|
|
tx_allowed = true;
|
|
}
|
|
}
|
|
|
|
furi_hal_spi_bus_end_txrx(bus, timeout);
|
|
|
|
return ret;
|
|
}
|
|
|
|
void furi_hal_spi_device_configure(const FuriHalSpiDevice* device) {
|
|
assert(device);
|
|
assert(device->config);
|
|
|
|
furi_hal_spi_bus_configure(device->bus, device->config);
|
|
}
|
|
|
|
const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id) {
|
|
assert(device_id < FuriHalSpiDeviceIdMax);
|
|
|
|
const FuriHalSpiDevice* device = &furi_hal_spi_devices[device_id];
|
|
assert(device);
|
|
|
|
furi_hal_spi_bus_lock(device->bus);
|
|
furi_hal_spi_device_configure(device);
|
|
|
|
return device;
|
|
}
|
|
|
|
void furi_hal_spi_device_return(const FuriHalSpiDevice* device) {
|
|
furi_hal_spi_bus_unlock(device->bus);
|
|
}
|
|
|
|
bool furi_hal_spi_device_rx(
|
|
const FuriHalSpiDevice* device,
|
|
uint8_t* buffer,
|
|
size_t size,
|
|
uint32_t timeout) {
|
|
assert(device);
|
|
assert(buffer);
|
|
assert(size > 0);
|
|
|
|
if(device->chip_select) {
|
|
hal_gpio_write(device->chip_select, false);
|
|
}
|
|
|
|
bool ret = furi_hal_spi_bus_rx(device->bus, buffer, size, timeout);
|
|
|
|
if(device->chip_select) {
|
|
hal_gpio_write(device->chip_select, true);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool furi_hal_spi_device_tx(
|
|
const FuriHalSpiDevice* device,
|
|
uint8_t* buffer,
|
|
size_t size,
|
|
uint32_t timeout) {
|
|
assert(device);
|
|
assert(buffer);
|
|
assert(size > 0);
|
|
|
|
if(device->chip_select) {
|
|
hal_gpio_write(device->chip_select, false);
|
|
}
|
|
|
|
bool ret = furi_hal_spi_bus_tx(device->bus, buffer, size, timeout);
|
|
|
|
if(device->chip_select) {
|
|
hal_gpio_write(device->chip_select, true);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool furi_hal_spi_device_trx(
|
|
const FuriHalSpiDevice* device,
|
|
uint8_t* tx_buffer,
|
|
uint8_t* rx_buffer,
|
|
size_t size,
|
|
uint32_t timeout) {
|
|
assert(device);
|
|
assert(tx_buffer);
|
|
assert(rx_buffer);
|
|
assert(size > 0);
|
|
|
|
if(device->chip_select) {
|
|
hal_gpio_write(device->chip_select, false);
|
|
}
|
|
|
|
bool ret = furi_hal_spi_bus_trx(device->bus, tx_buffer, rx_buffer, size, timeout);
|
|
|
|
if(device->chip_select) {
|
|
hal_gpio_write(device->chip_select, true);
|
|
}
|
|
|
|
return ret;
|
|
}
|