api-hal-spi.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #include "api-hal-spi.h"
  2. #include <api-hal-resources.h>
  3. #include <stdbool.h>
  4. #include <string.h>
  5. #include <spi.h>
  6. #include <furi.h>
  7. extern void Enable_SPI(SPI_HandleTypeDef* spi);
  8. void api_hal_spi_init() {
  9. // Spi structure is const, but mutex is not
  10. // Need some hell-ish casting to make it work
  11. *(osMutexId_t*)spi_r.mutex = osMutexNew(NULL);
  12. *(osMutexId_t*)spi_d.mutex = osMutexNew(NULL);
  13. //
  14. for (size_t i=0; i<ApiHalSpiDeviceIdMax; ++i) {
  15. hal_gpio_init(
  16. api_hal_spi_devices[i].chip_select,
  17. GpioModeOutputPushPull,
  18. GpioPullNo,
  19. GpioSpeedVeryHigh
  20. );
  21. }
  22. FURI_LOG_I("FuriHalSpi", "Init OK");
  23. }
  24. void api_hal_spi_bus_lock(const ApiHalSpiBus* bus) {
  25. furi_assert(bus);
  26. if (bus->mutex) {
  27. osMutexAcquire(*bus->mutex, osWaitForever);
  28. }
  29. }
  30. void api_hal_spi_bus_unlock(const ApiHalSpiBus* bus) {
  31. furi_assert(bus);
  32. if (bus->mutex) {
  33. osMutexRelease(*bus->mutex);
  34. }
  35. }
  36. void api_hal_spi_bus_configure(const ApiHalSpiBus* bus, const SPI_InitTypeDef* config) {
  37. furi_assert(bus);
  38. if(memcmp(&bus->spi->Init, config, sizeof(SPI_InitTypeDef))) {
  39. memcpy((SPI_InitTypeDef*)&bus->spi->Init, config, sizeof(SPI_InitTypeDef));
  40. if(HAL_SPI_Init((SPI_HandleTypeDef*)bus->spi) != HAL_OK) {
  41. Error_Handler();
  42. }
  43. Enable_SPI((SPI_HandleTypeDef*)bus->spi);
  44. }
  45. }
  46. void api_hal_spi_bus_reset(const ApiHalSpiBus* bus) {
  47. furi_assert(bus);
  48. HAL_SPI_DeInit((SPI_HandleTypeDef*)bus->spi);
  49. HAL_SPI_Init((SPI_HandleTypeDef*)bus->spi);
  50. Enable_SPI((SPI_HandleTypeDef*)bus->spi);
  51. }
  52. bool api_hal_spi_bus_rx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) {
  53. furi_assert(bus);
  54. furi_assert(buffer);
  55. furi_assert(size > 0);
  56. HAL_StatusTypeDef ret = HAL_SPI_Receive((SPI_HandleTypeDef *)bus->spi, buffer, size, HAL_MAX_DELAY);
  57. return ret == HAL_OK;
  58. }
  59. bool api_hal_spi_bus_tx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) {
  60. furi_assert(bus);
  61. furi_assert(buffer);
  62. furi_assert(size > 0);
  63. HAL_StatusTypeDef ret = HAL_SPI_Transmit((SPI_HandleTypeDef *)bus->spi, buffer, size, HAL_MAX_DELAY);
  64. return ret == HAL_OK;
  65. }
  66. bool api_hal_spi_bus_trx(const ApiHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) {
  67. furi_assert(bus);
  68. furi_assert(tx_buffer);
  69. furi_assert(rx_buffer);
  70. furi_assert(size > 0);
  71. HAL_StatusTypeDef ret = HAL_SPI_TransmitReceive((SPI_HandleTypeDef *)bus->spi, tx_buffer, rx_buffer, size, HAL_MAX_DELAY);
  72. return ret == HAL_OK;
  73. }
  74. const ApiHalSpiDevice* api_hal_spi_device_get(ApiHalSpiDeviceId device_id) {
  75. furi_assert(device_id < ApiHalSpiDeviceIdMax);
  76. const ApiHalSpiDevice* device = &api_hal_spi_devices[device_id];
  77. assert(device);
  78. api_hal_spi_bus_lock(device->bus);
  79. if (device->config) {
  80. memcpy((SPI_InitTypeDef*)&device->bus->spi->Init, device->config, sizeof(SPI_InitTypeDef));
  81. if(HAL_SPI_Init((SPI_HandleTypeDef *)device->bus->spi) != HAL_OK) {
  82. Error_Handler();
  83. }
  84. Enable_SPI((SPI_HandleTypeDef *)device->bus->spi);
  85. }
  86. return device;
  87. }
  88. void api_hal_spi_device_return(const ApiHalSpiDevice* device) {
  89. api_hal_spi_bus_unlock(device->bus);
  90. }
  91. bool api_hal_spi_device_rx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) {
  92. furi_assert(device);
  93. furi_assert(buffer);
  94. furi_assert(size > 0);
  95. if (device->chip_select) {
  96. hal_gpio_write(device->chip_select, false);
  97. }
  98. bool ret = api_hal_spi_bus_rx(device->bus, buffer, size, HAL_MAX_DELAY);
  99. if (device->chip_select) {
  100. hal_gpio_write(device->chip_select, true);
  101. }
  102. return ret;
  103. }
  104. bool api_hal_spi_device_tx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) {
  105. furi_assert(device);
  106. furi_assert(buffer);
  107. furi_assert(size > 0);
  108. if (device->chip_select) {
  109. hal_gpio_write(device->chip_select, false);
  110. }
  111. bool ret = api_hal_spi_bus_tx(device->bus, buffer, size, HAL_MAX_DELAY);
  112. if (device->chip_select) {
  113. hal_gpio_write(device->chip_select, true);
  114. }
  115. return ret;
  116. }
  117. bool api_hal_spi_device_trx(const ApiHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) {
  118. furi_assert(device);
  119. furi_assert(tx_buffer);
  120. furi_assert(rx_buffer);
  121. furi_assert(size > 0);
  122. if (device->chip_select) {
  123. hal_gpio_write(device->chip_select, false);
  124. }
  125. bool ret = api_hal_spi_bus_trx(device->bus, tx_buffer, rx_buffer, size, HAL_MAX_DELAY);
  126. if (device->chip_select) {
  127. hal_gpio_write(device->chip_select, true);
  128. }
  129. return ret;
  130. }