1 /*
2  * Copyright (c) 2006-2025, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2021-08-23     Mr.Tiger     first version
9  * 2021-11-04     Sherman      ADD complete_event
10  * 2022-12-7      Vandoul      ADD sci spi support
11  */
12 /**< Note : Turn on any DMA mode and all SPIs will turn on DMA */
13 
14 #include "drv_spi.h"
15 
16 #ifdef BSP_USING_SPI
17 
18 //#define DRV_DEBUG
19 #define DBG_TAG              "drv.spi"
20 #ifdef DRV_DEBUG
21     #define DBG_LVL               DBG_LOG
22 #else
23     #define DBG_LVL               DBG_INFO
24 #endif /* DRV_DEBUG */
25 #include <rtdbg.h>
26 
27 #if defined(BSP_USING_SPI0) || defined(BSP_USING_SPI1) || defined(BSP_USING_SPI2)
28 #define RA_SPI0_EVENT 0x01
29 #define RA_SPI1_EVENT 0x02
30 #define RA_SPI2_EVENT 0x03
31 static struct rt_event complete_event = {0};
32 
33 #ifdef SOC_SERIES_R7FA8M85
34 #define R_SPI_Write R_SPI_B_Write
35 #define R_SPI_Read  R_SPI_B_Read
36 #define R_SPI_WriteRead R_SPI_B_WriteRead
37 #define R_SPI_Open R_SPI_B_Open
38 #define spi_extended_cfg_t spi_b_extended_cfg_t
39 #endif
40 
41 static struct ra_spi_handle spi_handle[] =
42 {
43 #ifdef BSP_USING_SPI0
44     {.bus_name = "spi0", .spi_ctrl_t = &g_spi0_ctrl, .spi_cfg_t = &g_spi0_cfg,},
45 #endif
46 
47 #ifdef BSP_USING_SPI1
48     {.bus_name = "spi1", .spi_ctrl_t = &g_spi1_ctrl, .spi_cfg_t = &g_spi1_cfg,},
49 #endif
50 
51 #ifdef BSP_USING_SPI2
52     {.bus_name = "spi2", .spi_ctrl_t = &g_spi2_ctrl, .spi_cfg_t = &g_spi2_cfg,},
53 #endif
54 };
55 
56 static struct ra_spi spi_config[sizeof(spi_handle) / sizeof(spi_handle[0])] = {0};
57 
spi0_callback(spi_callback_args_t * p_args)58 void spi0_callback(spi_callback_args_t *p_args)
59 {
60     rt_interrupt_enter();
61     if (SPI_EVENT_TRANSFER_COMPLETE == p_args->event)
62     {
63         rt_event_send(&complete_event, RA_SPI0_EVENT);
64     }
65     rt_interrupt_leave();
66 }
67 
spi1_callback(spi_callback_args_t * p_args)68 void spi1_callback(spi_callback_args_t *p_args)
69 {
70     rt_interrupt_enter();
71     if (SPI_EVENT_TRANSFER_COMPLETE == p_args->event)
72     {
73         rt_event_send(&complete_event, RA_SPI1_EVENT);
74     }
75     rt_interrupt_leave();
76 }
77 
spi2_callback(spi_callback_args_t * p_args)78 void spi2_callback(spi_callback_args_t *p_args)
79 {
80     rt_interrupt_enter();
81     if (SPI_EVENT_TRANSFER_COMPLETE == p_args->event)
82     {
83         rt_event_send(&complete_event, RA_SPI2_EVENT);
84     }
85     rt_interrupt_leave();
86 }
87 
ra_wait_complete(rt_event_t event,const char bus_name[RT_NAME_MAX])88 static rt_err_t ra_wait_complete(rt_event_t event, const char bus_name[RT_NAME_MAX])
89 {
90     rt_uint32_t recved = 0x00;
91 
92     if (bus_name[3] == '0')
93     {
94         return rt_event_recv(event,
95                              RA_SPI0_EVENT,
96                              RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
97                              (rt_int32_t)rt_tick_from_millisecond(200),
98                              &recved);
99     }
100     else if (bus_name[3] == '1')
101     {
102         return rt_event_recv(event,
103                              RA_SPI1_EVENT,
104                              RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
105                              (rt_int32_t)rt_tick_from_millisecond(200),
106                              &recved);
107     }
108     else if (bus_name[3] == '2')
109     {
110         return rt_event_recv(event,
111                              RA_SPI2_EVENT,
112                              RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
113                              (rt_int32_t)rt_tick_from_millisecond(200),
114                              &recved);
115     }
116     return -RT_EINVAL;
117 }
118 
ra_width_shift(rt_uint8_t data_width)119 static spi_bit_width_t ra_width_shift(rt_uint8_t data_width)
120 {
121     spi_bit_width_t bit_width = SPI_BIT_WIDTH_8_BITS;
122     if (data_width == 1)
123         bit_width = SPI_BIT_WIDTH_8_BITS;
124     else if (data_width == 2)
125         bit_width = SPI_BIT_WIDTH_16_BITS;
126     else if (data_width == 4)
127         bit_width = SPI_BIT_WIDTH_32_BITS;
128 
129     return bit_width;
130 }
131 
ra_write_message(struct rt_spi_device * device,const void * send_buf,const rt_size_t len)132 static rt_err_t ra_write_message(struct rt_spi_device *device, const void *send_buf, const rt_size_t len)
133 {
134     RT_ASSERT(device != NULL);
135     RT_ASSERT(send_buf != NULL);
136     RT_ASSERT(len > 0);
137     rt_err_t err = RT_EOK;
138     struct ra_spi *spi_dev =  rt_container_of(device->bus, struct ra_spi, bus);
139 
140     spi_bit_width_t bit_width = ra_width_shift(spi_dev->rt_spi_cfg_t->data_width);
141     /**< send msessage */
142     err = R_SPI_Write((spi_ctrl_t *)spi_dev->ra_spi_handle_t->spi_ctrl_t, send_buf, len, bit_width);
143     if (RT_EOK != err)
144     {
145         LOG_E("%s write failed.", spi_dev->ra_spi_handle_t->bus_name);
146         return -RT_ERROR;
147     }
148     /* Wait for SPI_EVENT_TRANSFER_COMPLETE callback event. */
149     ra_wait_complete(&complete_event, spi_dev->ra_spi_handle_t->bus_name);
150     return len;
151 }
152 
ra_read_message(struct rt_spi_device * device,void * recv_buf,const rt_size_t len)153 static rt_err_t ra_read_message(struct rt_spi_device *device, void *recv_buf, const rt_size_t len)
154 {
155     RT_ASSERT(device != NULL);
156     RT_ASSERT(recv_buf != NULL);
157     RT_ASSERT(len > 0);
158     rt_err_t err = RT_EOK;
159     struct ra_spi *spi_dev =  rt_container_of(device->bus, struct ra_spi, bus);
160 
161     spi_bit_width_t bit_width = ra_width_shift(spi_dev->rt_spi_cfg_t->data_width);
162     /**< receive message */
163     err = R_SPI_Read((spi_ctrl_t *)spi_dev->ra_spi_handle_t->spi_ctrl_t, recv_buf, len, bit_width);
164     if (RT_EOK != err)
165     {
166         LOG_E("\n%s write failed.\n", spi_dev->ra_spi_handle_t->bus_name);
167         return -RT_ERROR;
168     }
169     /* Wait for SPI_EVENT_TRANSFER_COMPLETE callback event. */
170     ra_wait_complete(&complete_event, spi_dev->ra_spi_handle_t->bus_name);
171     return len;
172 }
173 
ra_write_read_message(struct rt_spi_device * device,struct rt_spi_message * message)174 static rt_err_t ra_write_read_message(struct rt_spi_device *device, struct rt_spi_message *message)
175 {
176     RT_ASSERT(device != NULL);
177     RT_ASSERT(message != NULL);
178     RT_ASSERT(message->length > 0);
179     rt_err_t err = RT_EOK;
180     struct ra_spi *spi_dev =  rt_container_of(device->bus, struct ra_spi, bus);
181 
182     spi_bit_width_t bit_width = ra_width_shift(spi_dev->rt_spi_cfg_t->data_width);
183     /**< write and receive message */
184     err = R_SPI_WriteRead((spi_ctrl_t *)spi_dev->ra_spi_handle_t->spi_ctrl_t, message->send_buf, message->recv_buf, message->length, bit_width);
185     if (RT_EOK != err)
186     {
187         LOG_E("%s write and read failed.", spi_dev->ra_spi_handle_t->bus_name);
188         return -RT_ERROR;
189     }
190 #if defined(SOC_SERIES_R9A07G0)
191     R_BSP_CacheCleanInvalidateAll();
192 #endif
193 
194     /* Wait for SPI_EVENT_TRANSFER_COMPLETE callback event. */
195     ra_wait_complete(&complete_event, spi_dev->ra_spi_handle_t->bus_name);
196     return message->length;
197 }
198 
199 /**< init spi TODO : MSB does not support modification */
ra_hw_spi_configure(struct rt_spi_device * device,struct rt_spi_configuration * configuration)200 static rt_err_t ra_hw_spi_configure(struct rt_spi_device *device,
201                                     struct rt_spi_configuration *configuration)
202 {
203     RT_ASSERT(device != NULL);
204     RT_ASSERT(configuration != NULL);
205     rt_err_t err = RT_EOK;
206 
207     struct ra_spi *spi_dev =  rt_container_of(device->bus, struct ra_spi, bus);
208 
209     /**< data_width : 1 -> 8 bits , 2 -> 16 bits, 4 -> 32 bits, default 32 bits*/
210     rt_uint8_t data_width = configuration->data_width / 8;
211     RT_ASSERT(data_width == 1 || data_width == 2 || data_width == 4);
212     configuration->data_width = configuration->data_width / 8;
213     spi_dev->rt_spi_cfg_t = configuration;
214 
215     spi_extended_cfg_t spi_cfg = *(spi_extended_cfg_t *)spi_dev->ra_spi_handle_t->spi_cfg_t->p_extend;
216 
217     /**< Configure Select Line */
218     rt_pin_write(device->cs_pin, PIN_HIGH);
219 
220     /**< config bitrate */
221 #ifdef SOC_SERIES_R7FA8M85
222     R_SPI_B_CalculateBitrate(spi_dev->rt_spi_cfg_t->max_hz, SPI_B_CLOCK_SOURCE_PCLK, &spi_cfg.spck_div);
223 #elif defined(SOC_SERIES_R9A07G0)
224     R_SPI_CalculateBitrate(spi_dev->rt_spi_cfg_t->max_hz, SPI_CLOCK_SOURCE_PCLKM, &spi_cfg.spck_div);
225 #else
226     R_SPI_CalculateBitrate(spi_dev->rt_spi_cfg_t->max_hz, &spi_cfg.spck_div);
227 #endif
228 
229     /**< init */
230     err = R_SPI_Open((spi_ctrl_t *)spi_dev->ra_spi_handle_t->spi_ctrl_t, (spi_cfg_t const * const)spi_dev->ra_spi_handle_t->spi_cfg_t);
231     /* handle error */
232     if (RT_EOK != err)
233     {
234         LOG_E("%s init failed.", spi_dev->ra_spi_handle_t->bus_name);
235         return -RT_ERROR;
236     }
237     return RT_EOK;
238 }
239 
ra_spixfer(struct rt_spi_device * device,struct rt_spi_message * message)240 static rt_ssize_t ra_spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
241 {
242     RT_ASSERT(device != RT_NULL);
243     RT_ASSERT(device->bus != RT_NULL);
244     RT_ASSERT(message != RT_NULL);
245 
246     rt_err_t err = RT_EOK;
247 
248     if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE))
249     {
250         if (device->config.mode & RT_SPI_CS_HIGH)
251             rt_pin_write(device->cs_pin, PIN_HIGH);
252         else
253             rt_pin_write(device->cs_pin, PIN_LOW);
254     }
255 
256     if (message->length > 0)
257     {
258         if (message->send_buf == RT_NULL && message->recv_buf != RT_NULL)
259         {
260             /**< receive message */
261             err = ra_read_message(device, (void *)message->recv_buf, (const rt_size_t)message->length);
262         }
263         else if (message->send_buf != RT_NULL && message->recv_buf == RT_NULL)
264         {
265             /**< send message */
266             err = ra_write_message(device, (const void *)message->send_buf, (const rt_size_t)message->length);
267         }
268         else if (message->send_buf != RT_NULL && message->recv_buf != RT_NULL)
269         {
270             /**< send and receive message */
271             err =  ra_write_read_message(device, message);
272         }
273     }
274 
275     if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE))
276     {
277         if (device->config.mode & RT_SPI_CS_HIGH)
278             rt_pin_write(device->cs_pin, PIN_LOW);
279         else
280             rt_pin_write(device->cs_pin, PIN_HIGH);
281     }
282     return err;
283 }
284 
285 static const struct rt_spi_ops ra_spi_ops =
286 {
287     .configure = ra_hw_spi_configure,
288     .xfer = ra_spixfer,
289 };
290 
ra_hw_spi_init(void)291 int ra_hw_spi_init(void)
292 {
293     for (rt_uint8_t spi_index = 0; spi_index < sizeof(spi_handle) / sizeof(spi_handle[0]); spi_index++)
294     {
295         spi_config[spi_index].ra_spi_handle_t = &spi_handle[spi_index];
296 
297         /**< register spi bus */
298         rt_err_t err = rt_spi_bus_register(&spi_config[spi_index].bus, spi_handle[spi_index].bus_name, &ra_spi_ops);
299         if (RT_EOK != err)
300         {
301             LOG_E("%s bus register failed.", spi_config[spi_index].ra_spi_handle_t->bus_name);
302             return -RT_ERROR;
303         }
304     }
305 
306     if (RT_EOK != rt_event_init(&complete_event, "ra_spi", RT_IPC_FLAG_PRIO))
307     {
308         LOG_E("SPI transfer event init fail!");
309         return -RT_ERROR;
310     }
311     return RT_EOK;
312 }
313 INIT_DEVICE_EXPORT(ra_hw_spi_init);
314 #endif
315 /**
316   * Attach the spi device to SPI bus, this function must be used after initialization.
317   */
rt_hw_spi_device_attach(const char * bus_name,const char * device_name,rt_base_t cs_pin)318 rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin)
319 {
320     RT_ASSERT(bus_name != RT_NULL);
321     RT_ASSERT(device_name != RT_NULL);
322 
323     rt_err_t result;
324     struct rt_spi_device *spi_device;
325 
326     /* attach the device to spi bus*/
327     spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
328     RT_ASSERT(spi_device != RT_NULL);
329 
330     result = rt_spi_bus_attach_device_cspin(spi_device, device_name, bus_name, cs_pin, RT_NULL);
331     if (result != RT_EOK)
332     {
333         LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result);
334     }
335 
336     RT_ASSERT(result == RT_EOK);
337 
338     LOG_D("%s attach to %s done", device_name, bus_name);
339 
340     return result;
341 }
342 #endif /* BSP_USING_SPI */
343