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 * 2024-09-04 Yilin Sun Initial version
9 */
10
11 #include <rtdevice.h>
12
13 #include "fsl_spi.h"
14
15 #include "drv_spi.h"
16
17 #define BSP_DEFAULT_SPI_FREQUENCY (500000U)
18
19 typedef struct
20 {
21 struct rt_spi_bus parent;
22 SPI_Type *instance;
23 uint32_t input_frequency;
24 } mcx_spi_obj_t;
25
26 typedef struct
27 {
28 SPI_Type *instance;
29 uint8_t id;
30 } mcx_spi_instance_t;
31
32 static const mcx_spi_instance_t mcx_spi_instances[] =
33 {
34 #ifdef BSP_USING_SPI0
35 {SPI0, 0},
36 #endif
37 #ifdef BSP_USING_SPI1
38 {SPI1, 1},
39 #endif
40 };
41
42 static mcx_spi_obj_t mcx_spi_list[ARRAY_SIZE(mcx_spi_instances)];
43
mcx_spi_xfer(struct rt_spi_device * device,struct rt_spi_message * message)44 static rt_ssize_t mcx_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
45 {
46 spi_transfer_t xfer =
47 {
48 .txData = message->send_buf,
49 .rxData = message->recv_buf,
50 .dataSize = message->length,
51 .flags = 0UL,
52 };
53
54 mcx_spi_obj_t *spi = device->bus->parent.user_data;
55
56 if (message->cs_take)
57 {
58 rt_pin_write(device->cs_pin, PIN_LOW);
59 }
60
61 SPI_MasterTransferBlocking(spi->instance, &xfer);
62
63 if (message->cs_release)
64 {
65 rt_pin_write(device->cs_pin, PIN_HIGH);
66 }
67
68 return message->length;
69 }
70
mcx_spi_configure(struct rt_spi_device * device,struct rt_spi_configuration * cfg)71 static rt_err_t mcx_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *cfg)
72 {
73 mcx_spi_obj_t *spi = device->bus->parent.user_data;
74
75 SPI_MasterSetBaudRate(spi->instance, cfg->max_hz, spi->input_frequency);
76
77 return RT_EOK;
78 }
79
80 static struct rt_spi_ops mcx_spi_ops =
81 {
82 .configure = mcx_spi_configure,
83 .xfer = mcx_spi_xfer,
84 };
85
rt_hw_spi_device_attach(const char * bus_name,const char * device_name,rt_uint32_t pin)86 rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_uint32_t pin)
87 {
88 struct rt_spi_device *spi_device = rt_malloc(sizeof(struct rt_spi_device));
89 if (!spi_device)
90 {
91 return -RT_ENOMEM;
92 }
93
94 return rt_spi_bus_attach_device_cspin(spi_device, device_name, bus_name, pin, NULL);
95 }
96
rt_hw_spi_init(void)97 int rt_hw_spi_init(void)
98 {
99 for (size_t i = 0; i < ARRAY_SIZE(mcx_spi_instances); i++)
100 {
101 char name_buf[16];
102
103 /* TODO: Initialize SPI interface here. */
104
105 mcx_spi_list[i].instance = mcx_spi_instances[i].instance;
106 mcx_spi_list[i].input_frequency = CLOCK_GetCoreSysClkFreq();
107
108 mcx_spi_list[i].parent.parent.user_data = &mcx_spi_list[i];
109
110 spi_master_config_t cfg;
111 SPI_MasterGetDefaultConfig(&cfg);
112
113 SPI_MasterInit(mcx_spi_list[i].instance, &cfg, mcx_spi_list[i].input_frequency);
114
115 rt_snprintf(name_buf, sizeof(name_buf), "spi%d", mcx_spi_instances[i].id);
116 rt_spi_bus_register(&mcx_spi_list[i].parent, name_buf, &mcx_spi_ops);
117 }
118
119 return 0;
120 }
121
122 INIT_DEVICE_EXPORT(rt_hw_spi_init);
123