api-hal-spi.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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. }
  23. void api_hal_spi_bus_lock(const ApiHalSpiBus* bus) {
  24. furi_assert(bus);
  25. if (bus->mutex) {
  26. osMutexAcquire(*bus->mutex, osWaitForever);
  27. }
  28. }
  29. void api_hal_spi_bus_unlock(const ApiHalSpiBus* bus) {
  30. furi_assert(bus);
  31. if (bus->mutex) {
  32. osMutexRelease(*bus->mutex);
  33. }
  34. }
  35. void api_hal_spi_bus_configure(const ApiHalSpiBus* bus, const SPI_InitTypeDef* config) {
  36. furi_assert(bus);
  37. if(memcmp(&bus->spi->Init, config, sizeof(SPI_InitTypeDef))) {
  38. memcpy((SPI_InitTypeDef*)&bus->spi->Init, config, sizeof(SPI_InitTypeDef));
  39. if(HAL_SPI_Init((SPI_HandleTypeDef*)bus->spi) != HAL_OK) {
  40. Error_Handler();
  41. }
  42. Enable_SPI((SPI_HandleTypeDef*)bus->spi);
  43. }
  44. }
  45. void api_hal_spi_bus_reset(const ApiHalSpiBus* bus) {
  46. furi_assert(bus);
  47. HAL_SPI_DeInit((SPI_HandleTypeDef*)bus->spi);
  48. HAL_SPI_Init((SPI_HandleTypeDef*)bus->spi);
  49. Enable_SPI((SPI_HandleTypeDef*)bus->spi);
  50. }
  51. bool api_hal_spi_bus_rx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) {
  52. furi_assert(bus);
  53. furi_assert(buffer);
  54. furi_assert(size > 0);
  55. HAL_StatusTypeDef ret = HAL_SPI_Receive((SPI_HandleTypeDef *)bus->spi, buffer, size, HAL_MAX_DELAY);
  56. return ret == HAL_OK;
  57. }
  58. bool api_hal_spi_bus_tx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) {
  59. furi_assert(bus);
  60. furi_assert(buffer);
  61. furi_assert(size > 0);
  62. HAL_StatusTypeDef ret = HAL_SPI_Transmit((SPI_HandleTypeDef *)bus->spi, buffer, size, HAL_MAX_DELAY);
  63. return ret == HAL_OK;
  64. }
  65. bool api_hal_spi_bus_trx(const ApiHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) {
  66. furi_assert(bus);
  67. furi_assert(tx_buffer);
  68. furi_assert(rx_buffer);
  69. furi_assert(size > 0);
  70. HAL_StatusTypeDef ret = HAL_SPI_TransmitReceive((SPI_HandleTypeDef *)bus->spi, tx_buffer, rx_buffer, size, HAL_MAX_DELAY);
  71. return ret == HAL_OK;
  72. }
  73. const ApiHalSpiDevice* api_hal_spi_device_get(ApiHalSpiDeviceId device_id) {
  74. furi_assert(device_id < ApiHalSpiDeviceIdMax);
  75. const ApiHalSpiDevice* device = &api_hal_spi_devices[device_id];
  76. assert(device);
  77. api_hal_spi_bus_lock(device->bus);
  78. if (device->config) {
  79. memcpy((SPI_InitTypeDef*)&device->bus->spi->Init, device->config, sizeof(SPI_InitTypeDef));
  80. if(HAL_SPI_Init((SPI_HandleTypeDef *)device->bus->spi) != HAL_OK) {
  81. Error_Handler();
  82. }
  83. Enable_SPI((SPI_HandleTypeDef *)device->bus->spi);
  84. }
  85. return device;
  86. }
  87. void api_hal_spi_device_return(const ApiHalSpiDevice* device) {
  88. api_hal_spi_bus_unlock(device->bus);
  89. }
  90. bool api_hal_spi_device_rx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) {
  91. furi_assert(device);
  92. furi_assert(buffer);
  93. furi_assert(size > 0);
  94. if (device->chip_select) {
  95. hal_gpio_write(device->chip_select, false);
  96. }
  97. bool ret = api_hal_spi_bus_rx(device->bus, buffer, size, HAL_MAX_DELAY);
  98. if (device->chip_select) {
  99. hal_gpio_write(device->chip_select, true);
  100. }
  101. return ret;
  102. }
  103. bool api_hal_spi_device_tx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) {
  104. furi_assert(device);
  105. furi_assert(buffer);
  106. furi_assert(size > 0);
  107. if (device->chip_select) {
  108. hal_gpio_write(device->chip_select, false);
  109. }
  110. bool ret = api_hal_spi_bus_tx(device->bus, buffer, size, HAL_MAX_DELAY);
  111. if (device->chip_select) {
  112. hal_gpio_write(device->chip_select, true);
  113. }
  114. return ret;
  115. }
  116. bool api_hal_spi_device_trx(const ApiHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) {
  117. furi_assert(device);
  118. furi_assert(tx_buffer);
  119. furi_assert(rx_buffer);
  120. furi_assert(size > 0);
  121. if (device->chip_select) {
  122. hal_gpio_write(device->chip_select, false);
  123. }
  124. bool ret = api_hal_spi_bus_trx(device->bus, tx_buffer, rx_buffer, size, HAL_MAX_DELAY);
  125. if (device->chip_select) {
  126. hal_gpio_write(device->chip_select, true);
  127. }
  128. return ret;
  129. }