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