Skip to content

Commit c992650

Browse files
authored
[BSP][NS800RT7P65] Add QSPI driver for NS800RT7xxx#11449
1 parent 9ed6154 commit c992650

5 files changed

Lines changed: 229 additions & 3 deletions

File tree

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ if GetDepend('BSP_USING_TIM'):
2727

2828
if GetDepend('BSP_USING_SPI'):
2929
src += ['drv_spi.c']
30+
if GetDepend('BSP_USING_QSPI'):
31+
src += ['drv_qspi.c']
3032

3133
group = DefineGroup('HAL_Drivers', src, depend = [''], CPPPATH = path)
3234

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
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-17 lugl first version
9+
*/
10+
11+
#include <rtthread.h>
12+
#include <rtdevice.h>
13+
#include "qspi.h"
14+
#include "board.h"
15+
16+
#ifdef RT_USING_QSPI
17+
18+
/*===========================================================================
19+
* GPIO initialization
20+
*===========================================================================*/
21+
static void qspi_pin_init(void)
22+
{
23+
GPIO_setPinConfig(GPIO_15_QSPI_NCS);
24+
GPIO_setAnalogMode(GPIO_15, GPIO_ANALOG_DISABLED);
25+
GPIO_setPadConfig(GPIO_15, GPIO_PIN_TYPE_PULLUP);
26+
GPIO_setQualificationMode(GPIO_15, GPIO_QUAL_ASYNC);
27+
28+
GPIO_setPinConfig(GPIO_16_QSPI_D0);
29+
GPIO_setAnalogMode(GPIO_16, GPIO_ANALOG_DISABLED);
30+
GPIO_setPadConfig(GPIO_16, GPIO_PIN_TYPE_PULLUP);
31+
GPIO_setQualificationMode(GPIO_16, GPIO_QUAL_ASYNC);
32+
GPIO_setDirectionMode(GPIO_16, GPIO_DIR_MODE_OUT);
33+
34+
GPIO_setPinConfig(GPIO_17_QSPI_D1);
35+
GPIO_setAnalogMode(GPIO_17, GPIO_ANALOG_DISABLED);
36+
GPIO_setPadConfig(GPIO_17, GPIO_PIN_TYPE_PULLUP);
37+
GPIO_setQualificationMode(GPIO_17, GPIO_QUAL_ASYNC);
38+
GPIO_setDirectionMode(GPIO_17, GPIO_DIR_MODE_IN);
39+
40+
GPIO_setPinConfig(GPIO_18_QSPI_D2);
41+
GPIO_setAnalogMode(GPIO_18, GPIO_ANALOG_DISABLED);
42+
GPIO_setPadConfig(GPIO_18, GPIO_PIN_TYPE_PULLUP);
43+
GPIO_setQualificationMode(GPIO_18, GPIO_QUAL_ASYNC);
44+
GPIO_setDirectionMode(GPIO_18, GPIO_DIR_MODE_IN);
45+
46+
GPIO_setPinConfig(GPIO_20_QSPI_D3);
47+
GPIO_setAnalogMode(GPIO_20, GPIO_ANALOG_DISABLED);
48+
GPIO_setPadConfig(GPIO_20, GPIO_PIN_TYPE_PULLUP);
49+
GPIO_setQualificationMode(GPIO_20, GPIO_QUAL_ASYNC);
50+
GPIO_setDirectionMode(GPIO_20, GPIO_DIR_MODE_IN);
51+
52+
GPIO_setPinConfig(GPIO_21_QSPI_SCLK);
53+
GPIO_setAnalogMode(GPIO_21, GPIO_ANALOG_DISABLED);
54+
GPIO_setPadConfig(GPIO_21, GPIO_PIN_TYPE_PULLUP);
55+
GPIO_setQualificationMode(GPIO_21, GPIO_QUAL_ASYNC);
56+
}
57+
58+
/*===========================================================================
59+
* QSPI clock & controller initialization
60+
*===========================================================================*/
61+
static void qspi_clock_enable(void)
62+
{
63+
RCC_unlockRccRegister();
64+
RCC_enableQspiClock();
65+
RCC_resetQspiModule();
66+
RCC_releaseQspiModule();
67+
RCC_lockRccRegister();
68+
}
69+
70+
static void qspi_controller_init(void)
71+
{
72+
QSPI_open(EXTENDED_SPI_PROTOCOL,
73+
HLCK_DIV_48,
74+
ADDRESS_3_BYTES,
75+
DEFAULT_DUMMY_CYCLE,
76+
HIGH_LVL_4_QSCK,
77+
FAST_READ_QUAD_IN_OUT);
78+
}
79+
80+
/*===========================================================================
81+
* RT-Thread QSPI device interface
82+
*===========================================================================*/
83+
static struct rt_spi_bus qspi_bus;
84+
static struct rt_qspi_device qspi_dev;
85+
static struct rt_qspi_configuration qspi_cfg;
86+
87+
static rt_err_t qspi_configure(struct rt_spi_device *device,
88+
struct rt_spi_configuration *cfg)
89+
{
90+
device->config = *cfg;
91+
return RT_EOK;
92+
}
93+
94+
static rt_ssize_t qspi_xfer(struct rt_spi_device *device,
95+
struct rt_spi_message *message)
96+
{
97+
struct rt_qspi_message *qspi_msg = rt_container_of(message, struct rt_qspi_message, parent);
98+
uint8_t *send_buf = (uint8_t *)message->send_buf;
99+
uint8_t *recv_buf = (uint8_t *)message->recv_buf;
100+
uint32_t send_len = (send_buf != NULL) ? message->length : 0;
101+
uint32_t recv_len = (recv_buf != NULL) ? message->length : 0;
102+
103+
/* Build command buffer (instruction + address + dummy) */
104+
uint8_t cmd_buf[260];
105+
uint8_t *ptr = cmd_buf;
106+
107+
if (qspi_msg->instruction.content)
108+
*ptr++ = qspi_msg->instruction.content;
109+
110+
if (qspi_msg->address.size)
111+
{
112+
uint32_t addr = qspi_msg->address.content;
113+
uint8_t addr_bytes = qspi_msg->address.size / 8;
114+
for (uint8_t i = addr_bytes; i > 0; i--)
115+
*ptr++ = (addr >> (8*(i-1))) & 0xFF;
116+
}
117+
118+
if (qspi_msg->dummy_cycles)
119+
{
120+
uint8_t dummy_bytes = qspi_msg->dummy_cycles / 8;
121+
for (uint8_t i = 0; i < dummy_bytes; i++)
122+
*ptr++ = 0xFF;
123+
}
124+
125+
uint32_t cmd_len = ptr - cmd_buf;
126+
127+
/* Execute transfer using direct API */
128+
if (send_len && recv_len)
129+
{
130+
/* Half-duplex not supported in this driver */
131+
return 0;
132+
}
133+
134+
if (send_len)
135+
{
136+
/* Append send data to command buffer */
137+
if (cmd_len + send_len <= sizeof(cmd_buf))
138+
{
139+
rt_memcpy(ptr, send_buf, send_len);
140+
QSPI_writeDirect(cmd_buf, cmd_len + send_len, 0);
141+
} else {
142+
/* Not enough buffer, split into two writes? Not needed for normal use */
143+
return 0;
144+
}
145+
} else if (recv_len)
146+
{
147+
/* Write command, keep CS active, then read data */
148+
QSPI_writeDirect(cmd_buf, cmd_len, 1);
149+
QSPI_readDirect(recv_buf, recv_len);
150+
} else {
151+
/* No data phase, just send command */
152+
QSPI_writeDirect(cmd_buf, cmd_len, 0);
153+
}
154+
155+
return message->length;
156+
}
157+
158+
static const struct rt_spi_ops qspi_ops = {
159+
.configure = qspi_configure,
160+
.xfer = qspi_xfer,
161+
};
162+
163+
/*===========================================================================
164+
* Initialization
165+
*===========================================================================*/
166+
int rt_hw_qspi_init(void)
167+
{
168+
rt_kprintf("Initializing QSPI...\n");
169+
qspi_clock_enable();
170+
qspi_pin_init();
171+
qspi_controller_init();
172+
173+
qspi_cfg.parent.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
174+
qspi_cfg.parent.max_hz = 25000000;
175+
qspi_cfg.parent.data_width = 8;
176+
qspi_cfg.medium_size = 0x1000000;
177+
qspi_cfg.ddr_mode = 0;
178+
qspi_cfg.qspi_dl_width = 0;
179+
180+
rt_qspi_bus_register(&qspi_bus, "qspi0", &qspi_ops);
181+
182+
qspi_dev.parent.bus = &qspi_bus;
183+
qspi_dev.parent.config = qspi_cfg.parent;
184+
qspi_dev.config = qspi_cfg;
185+
rt_spi_bus_attach_device(&qspi_dev.parent, "qspi_dev", "qspi0", NULL);
186+
187+
return 0;
188+
}
189+
190+
INIT_DEVICE_EXPORT(rt_hw_qspi_init);
191+
192+
#endif
193+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#ifndef __DRV_QSPI_H__
2+
#define __DRV_QSPI_H__
3+
4+
#ifdef RT_USING_QSPI
5+
6+
#include <rtthread.h>
7+
#include <rtdevice.h>
8+
9+
#ifdef __cplusplus
10+
extern "C" {
11+
#endif
12+
13+
int rt_hw_qspi_init(void);
14+
15+
#ifdef __cplusplus
16+
}
17+
#endif
18+
19+
#endif
20+
21+
#endif /* __DRV_QSPI_H__ */
22+

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ devices.ecap:
66
kconfig:
77
- CONFIG_BSP_USING_ECAP=y
88
- CONFIG_BSP_USING_ECAP1=y
9-
- CONFIG_BSP_USING_SPI=y
10-
- CONFIG_BSP_USING_SPI1=y
119
devices.adc:
1210
<<: *scons
1311
kconfig:
14-
- CONFIG_BSP_USING_ADC=y
12+
- CONFIG_BSP_USING_ADC=y
13+
devices.spi:
14+
<<: *scons
15+
kconfig:
16+
- CONFIG_BSP_USING_SPI=y
17+
- CONFIG_BSP_USING_SPI1=y
18+
- CONFIG_BSP_USING_QSPI=y

bsp/novosns/ns800/ns800rt7p65-nssinepad/board/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,5 +205,10 @@ menu "On-chip Peripheral Drivers"
205205
bool "Enable SPI4"
206206
default n
207207
endif
208+
209+
menuconfig BSP_USING_QSPI
210+
bool "Enable QSPI"
211+
select RT_USING_QSPI
212+
default n
208213

209214
endmenu

0 commit comments

Comments
 (0)