1 /*
2 * Copyright (c) 2006-2024 RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2012-11-23 Bernard Add extern "C"
9 * 2020-06-13 armink fix the 3 wires issue
10 * 2022-09-01 liYony fix api rt_spi_sendrecv16 about MSB and LSB bug
11 */
12
13 #ifndef __DEV_SPI_H__
14 #define __DEV_SPI_H__
15
16 #include <stdlib.h>
17 #include <rtthread.h>
18 #include <drivers/dev_pin.h>
19 #include <drivers/core/driver.h>
20
21 /**
22 * @defgroup group_drivers_spi SPI
23 * @brief SPI driver api
24 * @ingroup group_device_driver
25 *
26 * <b>Example</b>
27 * @code {.c}
28 * #include <rtthread.h>
29 * #include <rtdevice.h>
30 *
31 * #define W25Q_SPI_DEVICE_NAME "qspi10"
32 *
33 * static void spi_w25q_sample(int argc, char *argv[])
34 * {
35 * struct rt_spi_device *spi_dev_w25q;
36 * char name[RT_NAME_MAX];
37 * rt_uint8_t w25x_read_id = 0x90;
38 * rt_uint8_t id[5] = {0};
39 *
40 * if (argc == 2)
41 * {
42 * rt_strncpy(name, argv[1], RT_NAME_MAX);
43 * }
44 * else
45 * {
46 * rt_strncpy(name, W25Q_SPI_DEVICE_NAME, RT_NAME_MAX);
47 * }
48 *
49 * // 查找 spi 设备获取设备句柄
50 * spi_dev_w25q = (struct rt_spi_device *)rt_device_find(name);
51 * if (!spi_dev_w25q)
52 * {
53 * rt_kprintf("spi sample run failed! can't find %s device!\n", name);
54 * }
55 * else
56 * {
57 * // 方式1:使用 rt_spi_send_then_recv()发送命令读取ID
58 * rt_spi_send_then_recv(spi_dev_w25q, &w25x_read_id, 1, id, 5);
59 * rt_kprintf("use rt_spi_send_then_recv() read w25q ID is:%x%x\n", id[3], id[4]);
60 *
61 * // 方式2:使用 rt_spi_transfer_message()发送命令读取ID
62 * struct rt_spi_message msg1, msg2;
63 *
64 * msg1.send_buf = &w25x_read_id;
65 * msg1.recv_buf = RT_NULL;
66 * msg1.length = 1;
67 * msg1.cs_take = 1;
68 * msg1.cs_release = 0;
69 * msg1.next = &msg2;
70 *
71 * msg2.send_buf = RT_NULL;
72 * msg2.recv_buf = id;
73 * msg2.length = 5;
74 * msg2.cs_take = 0;
75 * msg2.cs_release = 1;
76 * msg2.next = RT_NULL;
77 *
78 * rt_spi_transfer_message(spi_dev_w25q, &msg1);
79 * rt_kprintf("use rt_spi_transfer_message() read w25q ID is:%x%x\n", id[3], id[4]);
80 *
81 * }
82 * }
83 * // 导出到 msh 命令列表中
84 * MSH_CMD_EXPORT(spi_w25q_sample, spi w25q sample);
85 * @endcode
86 */
87
88 /*!
89 * @addtogroup group_drivers_spi
90 * @{
91 */
92 #ifdef __cplusplus
93 extern "C"{
94 #endif
95
96 /**
97 * At CPOL=0 the base value of the clock is zero
98 * - For CPHA=0, data are captured on the clock's rising edge (low->high transition)
99 * and data are propagated on a falling edge (high->low clock transition).
100 * - For CPHA=1, data are captured on the clock's falling edge and data are
101 * propagated on a rising edge.
102 * At CPOL=1 the base value of the clock is one (inversion of CPOL=0)
103 * - For CPHA=0, data are captured on clock's falling edge and data are propagated
104 * on a rising edge.
105 * - For CPHA=1, data are captured on clock's rising edge and data are propagated
106 * on a falling edge.
107 */
108 #define RT_SPI_CPHA (1<<0) /*!< bit[0]:CPHA, clock phase */
109 #define RT_SPI_CPOL (1<<1) /*!< bit[1]:CPOL, clock polarity */
110
111 #define RT_SPI_LSB (0<<2) /*!< bit[2]: 0-LSB */
112 #define RT_SPI_MSB (1<<2) /*!< bit[2]: 1-MSB */
113
114 #define RT_SPI_MASTER (0<<3) /*!< SPI master device */
115 #define RT_SPI_SLAVE (1<<3) /*!< SPI slave device */
116
117 #define RT_SPI_CS_HIGH (1<<4) /*!< Chipselect active high */
118 #define RT_SPI_NO_CS (1<<5) /*!< No chipselect */
119 #define RT_SPI_3WIRE (1<<6) /*!< SI/SO pin shared */
120 #define RT_SPI_READY (1<<7) /*!< Slave pulls low to pause */
121
122 #define RT_SPI_MODE_MASK (RT_SPI_CPHA | RT_SPI_CPOL | RT_SPI_MSB | RT_SPI_SLAVE | RT_SPI_CS_HIGH | RT_SPI_NO_CS | RT_SPI_3WIRE | RT_SPI_READY)
123
124 #define RT_SPI_MODE_0 (0 | 0) /*!< CPOL = 0, CPHA = 0 */
125 #define RT_SPI_MODE_1 (0 | RT_SPI_CPHA) /*!< CPOL = 0, CPHA = 1 */
126 #define RT_SPI_MODE_2 (RT_SPI_CPOL | 0) /*!< CPOL = 1, CPHA = 0 */
127 #define RT_SPI_MODE_3 (RT_SPI_CPOL | RT_SPI_CPHA) /*!< CPOL = 1, CPHA = 1 */
128
129 #define RT_SPI_BUS_MODE_SPI (1<<0)
130 #define RT_SPI_BUS_MODE_QSPI (1<<1)
131
132 #define RT_SPI_CS_CNT_MAX 16
133
134 /**
135 * @brief SPI message structure
136 */
137 struct rt_spi_message
138 {
139 const void *send_buf;
140 void *recv_buf;
141 rt_size_t length;
142 struct rt_spi_message *next;
143
144 unsigned cs_take : 1;
145 unsigned cs_release : 1;
146 };
147
148 /**
149 * @brief SPI configuration structure
150 */
151 struct rt_spi_configuration
152 {
153 rt_uint8_t mode;
154 rt_uint8_t data_width;
155 #ifdef RT_USING_DM
156 rt_uint8_t data_width_tx;
157 rt_uint8_t data_width_rx;
158 #else
159 rt_uint16_t reserved;
160 #endif
161
162 rt_uint32_t max_hz;
163 };
164
165 struct rt_spi_ops;
166
167 /**
168 * @brief SPI bus structure
169 */
170 struct rt_spi_bus
171 {
172 struct rt_device parent;
173 rt_uint8_t mode;
174 const struct rt_spi_ops *ops;
175
176 #ifdef RT_USING_DM
177 rt_base_t cs_pins[RT_SPI_CS_CNT_MAX];
178 rt_uint8_t cs_active_vals[RT_SPI_CS_CNT_MAX];
179 rt_bool_t slave;
180 int num_chipselect;
181 #endif /* RT_USING_DM */
182
183 struct rt_mutex lock;
184 struct rt_spi_device *owner;
185 };
186
187 /**
188 * @brief SPI operators
189 */
190 struct rt_spi_ops
191 {
192 rt_err_t (*configure)(struct rt_spi_device *device, struct rt_spi_configuration *configuration);
193 rt_ssize_t (*xfer)(struct rt_spi_device *device, struct rt_spi_message *message);
194 };
195
196 #ifdef RT_USING_DM
197 /**
198 * @brief SPI delay info
199 */
200 struct rt_spi_delay
201 {
202 #define RT_SPI_DELAY_UNIT_USECS 0
203 #define RT_SPI_DELAY_UNIT_NSECS 1
204 #define RT_SPI_DELAY_UNIT_SCK 2
205 rt_uint16_t value;
206 rt_uint8_t unit;
207 };
208 #endif /* RT_USING_DM */
209
210 /**
211 * @brief SPI Virtual BUS, one device must connected to a virtual BUS
212 */
213 struct rt_spi_device
214 {
215 struct rt_device parent;
216 struct rt_spi_bus *bus;
217
218 #ifdef RT_USING_DM
219 const char *name;
220 const struct rt_spi_device_id *id;
221 const struct rt_ofw_node_id *ofw_id;
222
223 rt_uint8_t chip_select[RT_SPI_CS_CNT_MAX];
224 struct rt_spi_delay cs_setup;
225 struct rt_spi_delay cs_hold;
226 struct rt_spi_delay cs_inactive;
227 #endif
228
229 struct rt_spi_configuration config;
230 rt_base_t cs_pin;
231 void *user_data;
232 };
233
234 /**
235 * @brief QSPI message structure
236 */
237 struct rt_qspi_message
238 {
239 struct rt_spi_message parent;
240
241 /* instruction stage */
242 struct
243 {
244 rt_uint8_t content;
245 rt_uint8_t qspi_lines;
246 } instruction;
247
248 /* address and alternate_bytes stage */
249 struct
250 {
251 rt_uint32_t content;
252 rt_uint8_t size;
253 rt_uint8_t qspi_lines;
254 } address, alternate_bytes;
255
256 /* dummy_cycles stage */
257 rt_uint32_t dummy_cycles;
258
259 /* number of lines in qspi data stage, the other configuration items are in parent */
260 rt_uint8_t qspi_data_lines;
261 };
262
263 /**
264 * @brief QSPI configuration structure
265 */
266 struct rt_qspi_configuration
267 {
268 struct rt_spi_configuration parent;
269 /* The size of medium */
270 rt_uint32_t medium_size;
271 /* double data rate mode */
272 rt_uint8_t ddr_mode;
273 /* the data lines max width which QSPI bus supported, such as 1, 2, 4 */
274 rt_uint8_t qspi_dl_width ;
275 };
276
277 /**
278 * @brief QSPI operators
279 */
280 struct rt_qspi_device
281 {
282 struct rt_spi_device parent;
283
284 struct rt_qspi_configuration config;
285
286 void (*enter_qspi_mode)(struct rt_qspi_device *device);
287
288 void (*exit_qspi_mode)(struct rt_qspi_device *device);
289 };
290
291 #define SPI_DEVICE(dev) ((struct rt_spi_device *)(dev))
292
293 #ifdef RT_USING_DM
294 struct rt_spi_device_id
295 {
296 char name[20];
297 void *data;
298 };
299
300 struct rt_spi_driver
301 {
302 struct rt_driver parent;
303
304 const struct rt_spi_device_id *ids;
305 const struct rt_ofw_node_id *ofw_ids;
306
307 rt_err_t (*probe)(struct rt_spi_device *device);
308 rt_err_t (*remove)(struct rt_spi_device *device);
309 rt_err_t (*shutdown)(struct rt_spi_device *device);
310 };
311
312 rt_err_t rt_spi_driver_register(struct rt_spi_driver *driver);
313 rt_err_t rt_spi_device_register(struct rt_spi_device *device);
314
315 #define RT_SPI_DRIVER_EXPORT(driver) RT_DRIVER_EXPORT(driver, spi, BUILIN)
316
rt_spi_device_id_data(struct rt_spi_device * device)317 rt_inline const void *rt_spi_device_id_data(struct rt_spi_device *device)
318 {
319 return device->id ? device->id->data : (device->ofw_id ? device->ofw_id->data : RT_NULL);
320 }
321 #endif /* RT_USING_DM */
322
323 /**
324 * @brief register a SPI bus
325 *
326 * @param bus the SPI bus
327 * @param name the name of SPI bus
328 * @param ops the operations of SPI bus
329 *
330 * @return rt_err_t error code
331 */
332 rt_err_t rt_spi_bus_register(struct rt_spi_bus *bus,
333 const char *name,
334 const struct rt_spi_ops *ops);
335
336
337 /**
338 * @brief attach a device on SPI bus
339 *
340 * @param device the SPI device
341 * @param name the name of SPI device
342 * @param bus_name the name of SPI bus
343 * @param user_data the user data of SPI device
344 *
345 * @return rt_err_t error code
346 */
347 rt_err_t rt_spi_bus_attach_device(struct rt_spi_device *device,
348 const char *name,
349 const char *bus_name,
350 void *user_data);
351
352
353 /**
354 * @brief attach a device on SPI bus with CS pin
355 *
356 * @param device the SPI device
357 * @param name the name of SPI device
358 * @param bus_name the name of SPI bus
359 * @param cs_pin the CS pin of SPI device
360 * @param user_data the user data of SPI device
361 *
362 * @return rt_err_t error code
363 */
364 rt_err_t rt_spi_bus_attach_device_cspin(struct rt_spi_device *device,
365 const char *name,
366 const char *bus_name,
367 rt_base_t cs_pin,
368 void *user_data);
369
370 /**
371 * @brief Reconfigure the SPI bus for the specified device.
372 *
373 * @param device: Pointer to the SPI device attached to the SPI bus.
374 * @retval RT_EOK if the SPI device was successfully released and the bus was configured.
375 * RT_EBUSY if the SPI bus is currently in use; the new configuration will take effect once the device releases the bus.
376 * Other return values indicate failure to configure the SPI bus due to various reasons.
377 * @note If the configuration of the SPI device has been updated and requires bus re-initialization,
378 * call this function directly. This function will reconfigure the SPI bus for the specified device.
379 * If this is the first time to initialize the SPI device, please call rt_spi_configure or rt_qspi_configure.
380 * This function is used to reconfigure the SPI bus when the SPI device is already in use.
381 * For further details, refer to:
382 * https://github.com/RT-Thread/rt-thread/pull/8528
383 */
384 rt_err_t rt_spi_bus_configure(struct rt_spi_device *device);
385
386 /**
387 * @brief This function takes SPI bus.
388 *
389 * @param device the SPI device attached to SPI bus
390 *
391 * @return RT_EOK on taken SPI bus successfully. others on taken SPI bus failed.
392 */
393 rt_err_t rt_spi_take_bus(struct rt_spi_device *device);
394
395 /**
396 * @brief This function releases SPI bus.
397 *
398 * @param device the SPI device attached to SPI bus
399 *
400 * @return RT_EOK on release SPI bus successfully.
401 */
402 rt_err_t rt_spi_release_bus(struct rt_spi_device *device);
403
404 /**
405 * @brief This function take SPI device (takes CS of SPI device).
406 *
407 * @param device the SPI device attached to SPI bus
408 *
409 * @return RT_EOK on release SPI bus successfully. others on taken SPI bus failed.
410 */
411 rt_err_t rt_spi_take(struct rt_spi_device *device);
412
413 /**
414 * @brief This function releases SPI device (releases CS of SPI device).
415 *
416 * @param device the SPI device attached to SPI bus
417 *
418 * @return RT_EOK on release SPI device successfully.
419 */
420 rt_err_t rt_spi_release(struct rt_spi_device *device);
421
422 /**
423 * @brief This function can set configuration on SPI device.
424 *
425 * @param device: the SPI device attached to SPI bus
426 * @param cfg: the configuration pointer.
427 *
428 * @retval RT_EOK on release SPI device successfully.
429 * RT_EBUSY is not an error condition and the configuration will take effect once the device has the bus
430 * others on taken SPI bus failed.
431 */
432 rt_err_t rt_spi_configure(struct rt_spi_device *device,
433 struct rt_spi_configuration *cfg);
434
435
436 /**
437 * @brief This function can send data then receive data from SPI device.
438 *
439 * @param device the SPI device attached to SPI bus
440 * @param send_buf the buffer to be transmitted to SPI device.
441 * @param send_length the number of data to be transmitted.
442 * @param recv_buf the buffer to be recivied from SPI device.
443 * @param recv_length the data to be recivied.
444 *
445 * @return rt_err_t error code
446 */
447 rt_err_t rt_spi_send_then_recv(struct rt_spi_device *device,
448 const void *send_buf,
449 rt_size_t send_length,
450 void *recv_buf,
451 rt_size_t recv_length);
452
453 /**
454 * @brief This function can send data then send data from SPI device.
455 *
456 * @param device the SPI device attached to SPI bus
457 * @param send_buf1 the buffer to be transmitted to SPI device.
458 * @param send_length1 the number of data to be transmitted.
459 * @param send_buf2 the buffer to be transmitted to SPI device.
460 * @param send_length2 the number of data to be transmitted.
461 *
462 * @return the status of transmit.
463 */
464 rt_err_t rt_spi_send_then_send(struct rt_spi_device *device,
465 const void *send_buf1,
466 rt_size_t send_length1,
467 const void *send_buf2,
468 rt_size_t send_length2);
469
470 /**
471 * @brief This function transmits data to SPI device.
472 *
473 * @param device the SPI device attached to SPI bus
474 * @param send_buf the buffer to be transmitted to SPI device.
475 * @param recv_buf the buffer to save received data from SPI device.
476 * @param length the length of transmitted data.
477 *
478 * @return the actual length of transmitted.
479 */
480 rt_ssize_t rt_spi_transfer(struct rt_spi_device *device,
481 const void *send_buf,
482 void *recv_buf,
483 rt_size_t length);
484
485 /**
486 * @brief The SPI device transmits 8 bytes of data
487 *
488 * @param device the SPI device attached to SPI bus
489 * @param senddata send data buffer
490 * @param recvdata receive data buffer
491 *
492 * @return rt_err_t error code
493 */
494 rt_err_t rt_spi_sendrecv8(struct rt_spi_device *device,
495 rt_uint8_t senddata,
496 rt_uint8_t *recvdata);
497
498 /**
499 * @brief The SPI device transmits 16 bytes of data
500 *
501 * @param device the SPI device attached to SPI bus
502 * @param senddata send data buffer
503 * @param recvdata receive data buffer
504 *
505 * @return rt_err_t error code
506 */
507 rt_err_t rt_spi_sendrecv16(struct rt_spi_device *device,
508 rt_uint16_t senddata,
509 rt_uint16_t *recvdata);
510
511 /**
512 * @brief This function transfers a message list to the SPI device.
513 *
514 * @param device the SPI device attached to SPI bus
515 * @param message the message list to be transmitted to SPI device
516 *
517 * @return RT_NULL if transmits message list successfully,
518 * SPI message which be transmitted failed.
519 */
520 struct rt_spi_message *rt_spi_transfer_message(struct rt_spi_device *device,
521 struct rt_spi_message *message);
522
523 /**
524 * @brief This function receives data from SPI device.
525 *
526 * @param device the SPI device attached to SPI bus
527 * @param recv_buf the buffer to be recivied from SPI device.
528 * @param length the data to be recivied.
529 *
530 * @return the actual length of received.
531 */
rt_spi_recv(struct rt_spi_device * device,void * recv_buf,rt_size_t length)532 rt_inline rt_size_t rt_spi_recv(struct rt_spi_device *device,
533 void *recv_buf,
534 rt_size_t length)
535 {
536 return rt_spi_transfer(device, RT_NULL, recv_buf, length);
537 }
538
539 /**
540 * @brief This function sends data to SPI device.
541 *
542 * @param device the SPI device attached to SPI bus
543 * @param send_buf the buffer to be transmitted to SPI device.
544 * @param length the number of data to be transmitted.
545 *
546 * @return the actual length of send.
547 */
rt_spi_send(struct rt_spi_device * device,const void * send_buf,rt_size_t length)548 rt_inline rt_size_t rt_spi_send(struct rt_spi_device *device,
549 const void *send_buf,
550 rt_size_t length)
551 {
552 return rt_spi_transfer(device, send_buf, RT_NULL, length);
553 }
554
555 /**
556 * @brief This function appends a message to the SPI message list.
557 *
558 * @param list the SPI message list header.
559 * @param message the message pointer to be appended to the message list.
560 */
rt_spi_message_append(struct rt_spi_message * list,struct rt_spi_message * message)561 rt_inline void rt_spi_message_append(struct rt_spi_message *list,
562 struct rt_spi_message *message)
563 {
564 RT_ASSERT(list != RT_NULL);
565 if (message == RT_NULL)
566 return; /* not append */
567
568 while (list->next != RT_NULL)
569 {
570 list = list->next;
571 }
572
573 list->next = message;
574 message->next = RT_NULL;
575 }
576
577 /**
578 * @brief This function can set configuration on QSPI device.
579 *
580 * @param device the QSPI device attached to QSPI bus.
581 * @param cfg the configuration pointer.
582 *
583 * @return the actual length of transmitted.
584 */
585 rt_err_t rt_qspi_configure(struct rt_qspi_device *device, struct rt_qspi_configuration *cfg);
586
587 /**
588 * @brief This function can register a SPI bus for QSPI mode.
589 *
590 * @param bus the SPI bus for QSPI mode.
591 * @param name The name of the spi bus.
592 * @param ops the SPI bus instance to be registered.
593 *
594 * @return the actual length of transmitted.
595 */
596 rt_err_t rt_qspi_bus_register(struct rt_spi_bus *bus, const char *name, const struct rt_spi_ops *ops);
597
598 /**
599 * @brief This function transmits data to QSPI device.
600 *
601 * @param device the QSPI device attached to QSPI bus.
602 * @param message the message pointer.
603 *
604 * @return the actual length of transmitted.
605 */
606 rt_ssize_t rt_qspi_transfer_message(struct rt_qspi_device *device, struct rt_qspi_message *message);
607
608 /**
609 * @brief This function can send data then receive data from QSPI device
610 *
611 * @param device the QSPI device attached to QSPI bus.
612 * @param send_buf the buffer to be transmitted to QSPI device.
613 * @param send_length the number of data to be transmitted.
614 * @param recv_buf the buffer to be recivied from QSPI device.
615 * @param recv_length the data to be recivied.
616 *
617 * @return the status of transmit.
618 */
619 rt_ssize_t rt_qspi_send_then_recv(struct rt_qspi_device *device, const void *send_buf, rt_size_t send_length,void *recv_buf, rt_size_t recv_length);
620
621 /**
622 * @brief This function can send data to QSPI device
623 *
624 * @param device the QSPI device attached to QSPI bus.
625 * @param send_buf the buffer to be transmitted to QSPI device.
626 * @param length the number of data to be transmitted.
627 *
628 * @return the status of transmit.
629 */
630 rt_ssize_t rt_qspi_send(struct rt_qspi_device *device, const void *send_buf, rt_size_t length);
631
632 #ifdef __cplusplus
633 }
634 #endif
635
636 /*! @}*/
637
638 #endif
639