spi.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #include <string.h>
  2. #include "FreeRTOS.h"
  3. #include "chip.h"
  4. #include "errno.h"
  5. #define MAX_SPI_DEVICE_NUM 3
  6. static struct spi_slave *spi_devs[MAX_SPI_DEVICE_NUM] = {NULL};
  7. static int spi_devices_count = 0;
  8. int spi_add_slave(struct spi_slave *slave)
  9. {
  10. if (spi_devices_count >= MAX_SPI_DEVICE_NUM)
  11. return -1;
  12. spi_devs[spi_devices_count++] = slave;
  13. return 0;
  14. }
  15. struct spi_slave *spi_open(const char *spidev)
  16. {
  17. struct spi_slave *slave;
  18. int i;
  19. for (i = 0; i < spi_devices_count; i++) {
  20. slave = spi_devs[i];
  21. if (!strcmp(slave->name, spidev)) {
  22. slave->open_count++;
  23. if (slave->open_count == 1)
  24. slave->xMutex = xSemaphoreCreateMutex();
  25. return slave;
  26. }
  27. }
  28. return NULL;
  29. }
  30. void spi_close(struct spi_slave *slave)
  31. {
  32. if (slave && --slave->open_count == 0)
  33. vSemaphoreDelete(slave->xMutex);
  34. }
  35. int spi_send_then_recv(struct spi_slave *slave, const void *send_buf,
  36. size_t send_length, void *recv_buf,
  37. size_t recv_length)
  38. {
  39. int result;
  40. struct spi_message message = {0};
  41. /* send data */
  42. message.send_buf = send_buf;
  43. message.recv_buf = NULL;
  44. message.length = send_length;
  45. message.cs_take = 1;
  46. message.cs_release = 0;
  47. message.next = NULL;
  48. result = slave->xfer(slave, &message);
  49. if (result < 0)
  50. {
  51. result = -EIO;
  52. goto __exit;
  53. }
  54. /* recv data */
  55. message.send_buf = NULL;
  56. message.recv_buf = recv_buf;
  57. message.length = recv_length;
  58. message.cs_take = 0;
  59. message.cs_release = 1;
  60. message.next = NULL;
  61. result = slave->xfer(slave, &message);
  62. if (result < 0)
  63. {
  64. result = -EIO;
  65. goto __exit;
  66. }
  67. result = ENOERR;
  68. __exit:
  69. return result;
  70. }
  71. int spi_transfer(struct spi_slave *slave, const void *send_buf,
  72. void *recv_buf, size_t length)
  73. {
  74. int result;
  75. struct spi_message message = {0};
  76. configASSERT(slave != NULL);
  77. xSemaphoreTake(slave->xMutex, portMAX_DELAY);
  78. /* initial message */
  79. message.send_buf = send_buf;
  80. message.recv_buf = recv_buf;
  81. message.length = length;
  82. message.cs_take = 1;
  83. message.cs_release = 1;
  84. message.next = NULL;
  85. /* transfer message */
  86. result = slave->xfer(slave, &message);
  87. if (result < 0)
  88. {
  89. result = -EIO;
  90. goto __exit;
  91. }
  92. __exit:
  93. xSemaphoreGive(slave->xMutex);
  94. return result;
  95. }
  96. int spi_configure(struct spi_slave *slave, struct spi_configuration *cfg)
  97. {
  98. int ret;
  99. configASSERT(slave && cfg);
  100. xSemaphoreTake(slave->xMutex, portMAX_DELAY);
  101. ret = slave->configure(slave, cfg);
  102. xSemaphoreGive(slave->xMutex);
  103. return ret;
  104. }
  105. int spi_recv(struct spi_slave *slave, void *recv_buf, size_t length)
  106. {
  107. return spi_transfer(slave, NULL, recv_buf, length);
  108. }
  109. int spi_send(struct spi_slave *slave, const void *send_buf, size_t length)
  110. {
  111. return spi_transfer(slave, send_buf, NULL, length);
  112. }
  113. void spi_init(void)
  114. {
  115. #ifdef EC_SPI1_SUPPORT
  116. ecspi_init();
  117. #endif
  118. #if (defined(DW_SPI0_SUPPORT) || defined(DW_SPI2_SUPPORT))
  119. dwspi_init();
  120. #endif
  121. }