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