drv_spi.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-02-22 airm2m first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include "board.h"
  13. #ifdef RT_USING_SPI
  14. #if !defined(BSP_USING_HSPI0) && !defined(BSP_USING_SPI0) && !defined(BSP_USING_SPI1) && !defined(BSP_USING_SPI2) && !defined(BSP_USING_SPI0S)
  15. #error "Please define at least one BSP_USING_SPIx"
  16. /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
  17. #endif
  18. #include "drv_spi.h"
  19. #include "drv_config.h"
  20. //#define DRV_DEBUG
  21. #define LOG_TAG "drv.spi"
  22. #include <drv_log.h>
  23. static struct air_spi spi_config[] =
  24. {
  25. #ifdef BSP_USING_HSPI0
  26. HSPI0_BUS_CONFIG,
  27. #endif
  28. #ifdef BSP_USING_SPI0
  29. SPI0_BUS_CONFIG,
  30. #endif
  31. #ifdef BSP_USING_SPI1
  32. SPI1_BUS_CONFIG,
  33. #endif
  34. #ifdef BSP_USING_SPI2
  35. SPI2_BUS_CONFIG,
  36. #endif
  37. #ifdef BSP_USING_SPI0S
  38. SPI0S_BUS_CONFIG,
  39. #endif
  40. };
  41. static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
  42. {
  43. RT_ASSERT(device != RT_NULL);
  44. RT_ASSERT(device->bus != RT_NULL);
  45. RT_ASSERT(message != RT_NULL);
  46. rt_uint32_t spi_id = device->bus->parent.user_data;
  47. rt_uint32_t cs_pin = device->parent.user_data;
  48. if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS))
  49. {
  50. if (device->config.mode & RT_SPI_CS_HIGH)
  51. GPIO_Output(cs_pin, 1);
  52. else
  53. GPIO_Output(cs_pin, 0);
  54. }
  55. if (message->length)
  56. {
  57. LOG_D("spi%d 0x%X, 0x%X, %d",
  58. spi_id,
  59. (uint32_t)message->send_buf,
  60. (uint32_t)message->recv_buf, message->length);
  61. if (!message->send_buf)
  62. {
  63. SPI_BlockTransfer(spi_id, message->recv_buf, message->recv_buf, message->length);
  64. }
  65. else
  66. {
  67. SPI_BlockTransfer(spi_id, message->send_buf, message->recv_buf, message->length);
  68. }
  69. LOG_D("spi%d done", spi_id);
  70. }
  71. if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS))
  72. {
  73. if (device->config.mode & RT_SPI_CS_HIGH)
  74. GPIO_Output(cs_pin, 0);
  75. else
  76. GPIO_Output(cs_pin, 1);
  77. }
  78. return message->length;
  79. }
  80. static rt_err_t spi_configure(struct rt_spi_device *device,
  81. struct rt_spi_configuration *configuration)
  82. {
  83. RT_ASSERT(device != RT_NULL);
  84. RT_ASSERT(configuration != RT_NULL);
  85. rt_uint32_t spi_id = device->bus->parent.user_data;
  86. rt_uint8_t mode = configuration->mode & (RT_SPI_CPHA | RT_SPI_CPOL);
  87. if (configuration->mode & RT_SPI_SLAVE) return RT_EINVAL;
  88. switch(spi_id)
  89. {
  90. case 0:
  91. GPIO_Iomux(GPIOC_12,3);
  92. GPIO_Iomux(GPIOC_13,3);
  93. GPIO_Iomux(GPIOC_15,3);
  94. break;
  95. case 1:
  96. GPIO_Iomux(GPIOB_12, 0);
  97. GPIO_Iomux(GPIOB_14, 0);
  98. GPIO_Iomux(GPIOB_15, 0);
  99. break;
  100. case 2:
  101. GPIO_Iomux(GPIOA_06,3);
  102. GPIO_Iomux(GPIOA_08,3);
  103. GPIO_Iomux(GPIOA_09,3);
  104. break;
  105. case 3:
  106. GPIO_Iomux(GPIOB_02,0);
  107. GPIO_Iomux(GPIOB_04,0);
  108. GPIO_Iomux(GPIOB_05,0);
  109. break;
  110. }
  111. SPI_MasterInit(spi_id, configuration->data_width, mode, configuration->max_hz, RT_NULL, RT_NULL);
  112. return RT_EOK;
  113. }
  114. static const struct rt_spi_ops air105_spi_ops =
  115. {
  116. .configure = spi_configure,
  117. .xfer = spixfer,
  118. };
  119. /**
  120. * Attach the spi device to SPI bus, this function must be used after initialization.
  121. */
  122. rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_uint8_t cs_pin)
  123. {
  124. RT_ASSERT(bus_name != RT_NULL);
  125. RT_ASSERT(device_name != RT_NULL);
  126. rt_err_t result;
  127. struct rt_spi_device *spi_device;
  128. /* attach the device to spi bus*/
  129. spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
  130. RT_ASSERT(spi_device != RT_NULL);
  131. GPIO_Config(cs_pin, 0, 1);
  132. result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
  133. if (result != RT_EOK)
  134. {
  135. LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result);
  136. }
  137. RT_ASSERT(result == RT_EOK);
  138. LOG_D("%s attach to %s done", device_name, bus_name);
  139. return result;
  140. }
  141. int rt_hw_spi_init(void)
  142. {
  143. rt_err_t result;
  144. rt_size_t obj_num = sizeof(spi_config) / sizeof(struct air_spi);
  145. for (int spi_index = 0; spi_index < obj_num ; spi_index++)
  146. {
  147. result = rt_spi_bus_register(&(spi_config[spi_index].bus), spi_config[spi_index].bus_name, &air105_spi_ops);
  148. RT_ASSERT(result == RT_EOK);
  149. spi_config[spi_index].bus.parent.user_data = spi_config[spi_index].id;
  150. }
  151. return RT_EOK;
  152. }
  153. INIT_BOARD_EXPORT(rt_hw_spi_init);
  154. #endif /* RT_USING_SPI */