Skip to content

Commit 196a6f4

Browse files
authored
[BSP][NS800RT7P65] Add SPI functionality (RT-Thread#11427)
* 添加 SPI 功能 * 默认不开启SPI * 添加SPI驱动编译看护 * 解决冲突文件
1 parent 99dcb22 commit 196a6f4

5 files changed

Lines changed: 406 additions & 1 deletion

File tree

bsp/novosns/ns800/libraries/HAL_Drivers/drivers/SConscript

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ if GetDepend('BSP_USING_ECAP'):
2222
if GetDepend('BSP_USING_TIM'):
2323
src += ['drv_timer.c']
2424

25+
if GetDepend('BSP_USING_SPI'):
26+
src += ['drv_spi.c']
27+
2528
group = DefineGroup('HAL_Drivers', src, depend = [''], CPPPATH = path)
2629

2730
Return('group')
Lines changed: 328 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
/*
2+
* Copyright (c) 2006-2026, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2026-05-12 lugl first version
9+
*/
10+
11+
#include "board.h"
12+
#include "drv_spi.h"
13+
#include "drv_config.h"
14+
15+
#ifdef RT_USING_SPI
16+
17+
#define DRV_DEBUG
18+
#define LOG_TAG "drv.spi"
19+
#include <drv_log.h>
20+
21+
#if !defined(BSP_USING_SPI1) && !defined(BSP_USING_SPI2) && !defined(BSP_USING_SPI3) && \
22+
!defined(BSP_USING_SPI4)
23+
#error "Please define at least one BSP_USING_SPIx"
24+
#endif
25+
26+
enum
27+
{
28+
#ifdef BSP_USING_SPI1
29+
SPI1_INDEX,
30+
#endif
31+
#ifdef BSP_USING_SPI2
32+
SPI2_INDEX,
33+
#endif
34+
#ifdef BSP_USING_SPI3
35+
SPI3_INDEX,
36+
#endif
37+
#ifdef BSP_USING_SPI4
38+
SPI4_INDEX,
39+
#endif
40+
};
41+
42+
static struct ns800_spi_config spi_config[] =
43+
{
44+
#ifdef BSP_USING_SPI1
45+
{
46+
.name = "spi1",
47+
.Instance = SPI1,
48+
.rx_irq_type = SPI1_RX_IRQn,
49+
.tx_irq_type = SPI1_TX_IRQn,
50+
.sck_port = GPIOA,
51+
.sck_pin = GPIO_PIN_18,
52+
.sck_mux = ALT1_FUNCTION,
53+
.mosi_port = GPIOA,
54+
.mosi_pin = GPIO_PIN_16,
55+
.mosi_mux = ALT1_FUNCTION,
56+
.miso_port = GPIOA,
57+
.miso_pin = GPIO_PIN_17,
58+
.miso_mux = ALT1_FUNCTION,
59+
},
60+
#endif
61+
#ifdef BSP_USING_SPI2
62+
{
63+
.name = "spi2",
64+
.Instance = SPI2,
65+
.rx_irq_type = SPI2_RX_IRQn,
66+
.tx_irq_type = SPI2_TX_IRQn,
67+
.sck_port = GPIOB,
68+
.sck_pin = GPIO_PIN_0,
69+
.sck_mux = ALT9_FUNCTION,
70+
.mosi_port = GPIOB,
71+
.mosi_pin = GPIO_PIN_1,
72+
.mosi_mux = ALT9_FUNCTION,
73+
.miso_port = GPIOB,
74+
.miso_pin = GPIO_PIN_2,
75+
.miso_mux = ALT9_FUNCTION,
76+
},
77+
#endif
78+
#ifdef BSP_USING_SPI3
79+
{
80+
.name = "spi3",
81+
.Instance = SPI3,
82+
.rx_irq_type = SPI3_RX_IRQn,
83+
.tx_irq_type = SPI3_TX_IRQn,
84+
.sck_port = GPIOC,
85+
.sck_pin = GPIO_PIN_0,
86+
.sck_mux = ALT7_FUNCTION,
87+
.mosi_port = GPIOC,
88+
.mosi_pin = GPIO_PIN_1,
89+
.mosi_mux = ALT7_FUNCTION,
90+
.miso_port = GPIOC,
91+
.miso_pin = GPIO_PIN_2,
92+
.miso_mux = ALT7_FUNCTION,
93+
},
94+
#endif
95+
#ifdef BSP_USING_SPI4
96+
{
97+
.name = "spi4",
98+
.Instance = SPI4,
99+
.rx_irq_type = SPI4_RX_IRQn,
100+
.tx_irq_type = SPI4_TX_IRQn,
101+
.sck_port = GPIOC,
102+
.sck_pin = GPIO_PIN_4,
103+
.sck_mux = ALT7_FUNCTION,
104+
.mosi_port = GPIOC,
105+
.mosi_pin = GPIO_PIN_5,
106+
.mosi_mux = ALT7_FUNCTION,
107+
.miso_port = GPIOC,
108+
.miso_pin = GPIO_PIN_6,
109+
.miso_mux = ALT7_FUNCTION,
110+
},
111+
#endif
112+
};
113+
114+
static struct ns800_spi spi_obj[sizeof(spi_config) / sizeof(spi_config[0])] = {0};
115+
116+
static void ns800_spi_gpio_init(const struct ns800_spi_config *config)
117+
{
118+
RT_ASSERT(config != RT_NULL);
119+
120+
GPIO_setPinConfig(config->sck_port, config->sck_pin, config->sck_mux);
121+
GPIO_setAnalogMode(config->sck_port, config->sck_pin, GPIO_ANALOG_DISABLED);
122+
GPIO_setPadConfig(config->sck_port, config->sck_pin, GPIO_PIN_TYPE_STD);
123+
GPIO_setQualificationMode(config->sck_port, config->sck_pin, GPIO_QUAL_SYNC);
124+
GPIO_setDirectionMode(config->sck_port, config->sck_pin, GPIO_DIR_MODE_OUT);
125+
126+
GPIO_setPinConfig(config->mosi_port, config->mosi_pin, config->mosi_mux);
127+
GPIO_setAnalogMode(config->mosi_port, config->mosi_pin, GPIO_ANALOG_DISABLED);
128+
GPIO_setPadConfig(config->mosi_port, config->mosi_pin, GPIO_PIN_TYPE_STD);
129+
GPIO_setQualificationMode(config->mosi_port, config->mosi_pin, GPIO_QUAL_SYNC);
130+
GPIO_setDirectionMode(config->mosi_port, config->mosi_pin, GPIO_DIR_MODE_OUT);
131+
132+
GPIO_setPinConfig(config->miso_port, config->miso_pin, config->miso_mux);
133+
GPIO_setAnalogMode(config->miso_port, config->miso_pin, GPIO_ANALOG_DISABLED);
134+
GPIO_setPadConfig(config->miso_port, config->miso_pin, GPIO_PIN_TYPE_PULLUP);
135+
GPIO_setQualificationMode(config->miso_port, config->miso_pin, GPIO_QUAL_SYNC);
136+
GPIO_setDirectionMode(config->miso_port, config->miso_pin, GPIO_DIR_MODE_IN);
137+
}
138+
139+
static rt_err_t ns800_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration)
140+
{
141+
struct ns800_spi *spi;
142+
SPI_TransferProtocol protocol;
143+
SPI_BitWidth data_width;
144+
145+
RT_ASSERT(device != RT_NULL);
146+
RT_ASSERT(configuration != RT_NULL);
147+
148+
spi = rt_container_of(device->bus, struct ns800_spi, spi_bus);
149+
150+
ns800_spi_gpio_init(spi->config);
151+
152+
switch (configuration->mode & RT_SPI_MODE_3)
153+
{
154+
case RT_SPI_MODE_0:
155+
protocol = SPI_PROT_POL0PHA0;
156+
break;
157+
case RT_SPI_MODE_1:
158+
protocol = SPI_PROT_POL0PHA1;
159+
break;
160+
case RT_SPI_MODE_2:
161+
protocol = SPI_PROT_POL1PHA0;
162+
break;
163+
case RT_SPI_MODE_3:
164+
protocol = SPI_PROT_POL1PHA1;
165+
break;
166+
default:
167+
protocol = SPI_PROT_POL0PHA0;
168+
break;
169+
}
170+
171+
switch (configuration->data_width)
172+
{
173+
case 8:
174+
data_width = SPI_BIT_WIDTH_8_BITS;
175+
break;
176+
case 16:
177+
data_width = SPI_BIT_WIDTH_16_BITS;
178+
break;
179+
default:
180+
data_width = SPI_BIT_WIDTH_8_BITS;
181+
break;
182+
}
183+
184+
SPI_disableModule(spi->config->Instance);
185+
186+
SPI_setConfig(spi->config->Instance,
187+
protocol,
188+
SPI_MASTER_MODE,
189+
SPI_FULL_DUPLEX_COMM_MODE,
190+
configuration->max_hz,
191+
data_width);
192+
193+
SPI_resetFifo(spi->config->Instance);
194+
SPI_enableModule(spi->config->Instance);
195+
196+
return RT_EOK;
197+
}
198+
199+
static rt_ssize_t ns800_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
200+
{
201+
struct ns800_spi *spi;
202+
SPI_TypeDef *instance;
203+
const rt_uint8_t *send_buf;
204+
rt_uint8_t *recv_buf;
205+
rt_size_t length;
206+
207+
RT_ASSERT(device != RT_NULL);
208+
RT_ASSERT(device->bus != RT_NULL);
209+
210+
spi = rt_container_of(device->bus, struct ns800_spi, spi_bus);
211+
instance = spi->config->Instance;
212+
length = message->length;
213+
send_buf = message->send_buf;
214+
recv_buf = message->recv_buf;
215+
216+
if (message->cs_take)
217+
{
218+
rt_pin_write(device->cs_pin, PIN_LOW);
219+
}
220+
221+
while (length)
222+
{
223+
if (send_buf)
224+
{
225+
if (recv_buf)
226+
{
227+
recv_buf[0] = SPI_transmitReceive(instance, send_buf[0]);
228+
recv_buf++;
229+
}
230+
else
231+
{
232+
SPI_transmitReceive(instance, send_buf[0]);
233+
}
234+
send_buf++;
235+
}
236+
else
237+
{
238+
if (recv_buf)
239+
{
240+
recv_buf[0] = SPI_transmitReceive(instance, 0xFF);
241+
recv_buf++;
242+
}
243+
else
244+
{
245+
SPI_transmitReceive(instance, 0xFF);
246+
}
247+
}
248+
length--;
249+
}
250+
251+
if (message->cs_release)
252+
{
253+
rt_pin_write(device->cs_pin, PIN_HIGH);
254+
}
255+
256+
return message->length;
257+
}
258+
259+
static const struct rt_spi_ops ns800_spi_ops =
260+
{
261+
.configure = ns800_spi_configure,
262+
.xfer = ns800_spi_xfer,
263+
};
264+
265+
static void ns800_spi_clock_init(SPI_TypeDef *Instance)
266+
{
267+
#ifdef BSP_USING_SPI1
268+
if (Instance == SPI1)
269+
{
270+
RCC_enableSpi1Clock();
271+
RCC_resetSpi1Module();
272+
RCC_releaseSpi1Module();
273+
}
274+
#endif
275+
#ifdef BSP_USING_SPI2
276+
if (Instance == SPI2)
277+
{
278+
RCC_enableSpi2Clock();
279+
RCC_resetSpi2Module();
280+
RCC_releaseSpi2Module();
281+
}
282+
#endif
283+
#ifdef BSP_USING_SPI3
284+
if (Instance == SPI3)
285+
{
286+
RCC_enableSpi3Clock();
287+
RCC_resetSpi3Module();
288+
RCC_releaseSpi3Module();
289+
}
290+
#endif
291+
#ifdef BSP_USING_SPI4
292+
if (Instance == SPI4)
293+
{
294+
RCC_enableSpi4Clock();
295+
RCC_resetSpi4Module();
296+
RCC_releaseSpi4Module();
297+
}
298+
#endif
299+
}
300+
301+
int rt_hw_spi_init(void)
302+
{
303+
rt_size_t i;
304+
rt_err_t result;
305+
306+
for (i = 0; i < sizeof(spi_config) / sizeof(spi_config[0]); i++)
307+
{
308+
ns800_spi_clock_init(spi_config[i].Instance);
309+
310+
spi_obj[i].config = &spi_config[i];
311+
spi_obj[i].spi_bus.parent.user_data = &spi_config[i];
312+
313+
result = rt_spi_bus_register(&spi_obj[i].spi_bus,
314+
spi_config[i].name,
315+
&ns800_spi_ops);
316+
if (result != RT_EOK)
317+
{
318+
LOG_E("rt_spi_bus_register(%s) failed: %d", spi_config[i].name, result);
319+
}
320+
}
321+
322+
return RT_EOK;
323+
}
324+
325+
INIT_BOARD_EXPORT(rt_hw_spi_init);
326+
327+
#endif
328+
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (c) 2006-2026, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2026-05-12 lugl first version
9+
*/
10+
11+
#ifndef __DRV_SPI_H__
12+
#define __DRV_SPI_H__
13+
14+
#include <rtthread.h>
15+
#include "rtdevice.h"
16+
#include <rthw.h>
17+
#include <drv_common.h>
18+
19+
#ifdef RT_USING_SPI
20+
21+
struct ns800_spi_config
22+
{
23+
const char *name;
24+
SPI_TypeDef *Instance;
25+
IRQn_Type rx_irq_type;
26+
IRQn_Type tx_irq_type;
27+
GPIO_TypeDef *sck_port;
28+
GPIO_PinNum sck_pin;
29+
GPIO_AltFunc sck_mux;
30+
GPIO_TypeDef *mosi_port;
31+
GPIO_PinNum mosi_pin;
32+
GPIO_AltFunc mosi_mux;
33+
GPIO_TypeDef *miso_port;
34+
GPIO_PinNum miso_pin;
35+
GPIO_AltFunc miso_mux;
36+
};
37+
38+
struct ns800_spi
39+
{
40+
SPI_TypeDef *Instance;
41+
struct rt_spi_bus spi_bus;
42+
struct ns800_spi_config *config;
43+
};
44+
45+
int rt_hw_spi_init(void);
46+
47+
#endif
48+
49+
#endif /* __DRV_SPI_H__ */
50+

bsp/novosns/ns800/ns800rt7p65-nssinepad/.ci/attachconfig/ci.attachconfig.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ devices.ecap:
55
<<: *scons
66
kconfig:
77
- CONFIG_BSP_USING_ECAP=y
8-
- CONFIG_BSP_USING_ECAP1=y
8+
- CONFIG_BSP_USING_ECAP1=y
9+
- CONFIG_BSP_USING_SPI=y
10+
- CONFIG_BSP_USING_SPI1=y

0 commit comments

Comments
 (0)