Skip to content

Commit 5810f4d

Browse files
authored
[components][drivers][spi]: 基于SPI总线驱动框架添加模拟SPI总线扩展 (#5656)
* add soft-spi * add spi-bit-ops.c/h to components/drivers/spi * add a drv_soft_spi example for gd32303e-eval Signed-off-by: kyle <[email protected]> * Fixed the format and the certificate. Signed-off-by: kyle <[email protected]> * Update the certificate data. Signed-off-by: kyle <[email protected]>
1 parent 0f2e9a3 commit 5810f4d

File tree

8 files changed

+931
-2
lines changed

8 files changed

+931
-2
lines changed

bsp/gd32303e-eval/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ config RT_USING_SPI2
6464
select RT_USING_SPI
6565
default n
6666

67+
config RT_USING_SPI3
68+
bool "Using SPI2 BUS (software simulation)"
69+
select RT_USING_SPI
70+
select RT_USING_SPI_BITOPS
71+
default n
72+
6773
config RT_USING_I2C0
6874
bool "Using I2C0"
6975
select RT_USING_I2C

bsp/gd32303e-eval/drivers/SConscript

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ CPPPATH = [cwd]
1515
# add spi drivers.
1616
if GetDepend('RT_USING_SPI'):
1717
src += ['drv_spi.c']
18-
18+
19+
# add softspi drivers.
20+
if GetDepend('RT_USING_SPI_BITOPS'):
21+
src += ['drv_soft_spi.c']
22+
1923
# add i2c drivers.
2024
if GetDepend('RT_USING_I2C'):
2125
src += ['drv_i2c.c']
Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
/*
2+
* Copyright (c) 2006-2021, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2021-10-11 kyle first implementation.
9+
*/
10+
11+
#include "drv_soft_spi.h"
12+
#include <board.h>
13+
#include <rtthread.h>
14+
15+
#if defined(RT_USING_SPI) && defined(RT_USING_SPI_BITOPS) && defined(RT_USING_PIN)
16+
#include <rtdevice.h>
17+
#include "spi-bit-ops.h"
18+
19+
#define DBG_TAG "drv.SPI"
20+
#ifdef RT_SPI_DEBUG
21+
#define DBG_LVL DBG_LOG
22+
#else
23+
#define DBG_LVL DBG_WARNING
24+
#endif
25+
#include <rtdbg.h>
26+
27+
#ifndef ITEM_NUM
28+
#define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
29+
#endif
30+
31+
struct gd32_spi_bit_data
32+
{
33+
struct
34+
{
35+
rcu_periph_enum clk;
36+
rt_uint32_t port;
37+
rt_uint32_t pin;
38+
} sclk, mosi, miso;
39+
};
40+
41+
42+
rt_inline FlagStatus GPIO_OUTPUT_BIT_GET(uint32_t gpio_periph, uint32_t pin)
43+
{
44+
if((uint32_t)RESET !=(GPIO_OCTL(gpio_periph)&(pin))){
45+
return SET;
46+
}else{
47+
return RESET;
48+
}
49+
}
50+
51+
rt_inline void GPIO_BIT_RESET(uint32_t gpio_periph, uint32_t pin)
52+
{
53+
GPIO_BC(gpio_periph) = (uint32_t)pin;
54+
}
55+
56+
rt_inline void GPIO_BIT_SET(uint32_t gpio_periph, uint32_t pin)
57+
{
58+
GPIO_BOP(gpio_periph) = (uint32_t)pin;
59+
}
60+
61+
rt_inline FlagStatus GPIO_INPUT_BIT_GET(uint32_t gpio_periph,uint32_t pin)
62+
{
63+
if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){
64+
return SET;
65+
}else{
66+
return RESET;
67+
}
68+
}
69+
70+
rt_inline void GPIO_INIT(uint32_t gpio_periph, uint32_t mode, uint32_t speed, uint32_t pin)
71+
{
72+
uint16_t i;
73+
uint32_t temp_mode = 0U;
74+
uint32_t reg = 0U;
75+
76+
/* GPIO mode configuration */
77+
temp_mode = (uint32_t)(mode & ((uint32_t)0x0FU));
78+
79+
/* GPIO speed configuration */
80+
if(((uint32_t)0x00U) != ((uint32_t)mode & ((uint32_t)0x10U))){
81+
/* output mode max speed:10MHz,2MHz,50MHz */
82+
temp_mode |= (uint32_t)speed;
83+
}
84+
85+
/* configure the eight low port pins with GPIO_CTL0 */
86+
for(i = 0U;i < 8U;i++){
87+
if((1U << i) & pin){
88+
reg = GPIO_CTL0(gpio_periph);
89+
90+
/* clear the specified pin mode bits */
91+
reg &= ~GPIO_MODE_MASK(i);
92+
/* set the specified pin mode bits */
93+
reg |= GPIO_MODE_SET(i, temp_mode);
94+
95+
/* set IPD or IPU */
96+
if(GPIO_MODE_IPD == mode){
97+
/* reset the corresponding OCTL bit */
98+
GPIO_BC(gpio_periph) = (uint32_t)((1U << i) & pin);
99+
}else{
100+
/* set the corresponding OCTL bit */
101+
if(GPIO_MODE_IPU == mode){
102+
GPIO_BOP(gpio_periph) = (uint32_t)((1U << i) & pin);
103+
}
104+
}
105+
/* set GPIO_CTL0 register */
106+
GPIO_CTL0(gpio_periph) = reg;
107+
}
108+
}
109+
/* configure the eight high port pins with GPIO_CTL1 */
110+
for(i = 8U;i < 16U;i++){
111+
if((1U << i) & pin){
112+
reg = GPIO_CTL1(gpio_periph);
113+
114+
/* clear the specified pin mode bits */
115+
reg &= ~GPIO_MODE_MASK(i - 8U);
116+
/* set the specified pin mode bits */
117+
reg |= GPIO_MODE_SET(i - 8U, temp_mode);
118+
119+
/* set IPD or IPU */
120+
if(GPIO_MODE_IPD == mode){
121+
/* reset the corresponding OCTL bit */
122+
GPIO_BC(gpio_periph) = (uint32_t)((1U << i) & pin);
123+
}else{
124+
/* set the corresponding OCTL bit */
125+
if(GPIO_MODE_IPU == mode){
126+
GPIO_BOP(gpio_periph) = (uint32_t)((1U << i) & pin);
127+
}
128+
}
129+
/* set GPIO_CTL1 register */
130+
GPIO_CTL1(gpio_periph) = reg;
131+
}
132+
}
133+
}
134+
135+
#define GPIO_SET_OUTPUT(port, pin) GPIO_INIT(port, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, pin)
136+
#define GPIO_SET_INPUT(port, pin) GPIO_INIT(port, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, pin)
137+
138+
139+
static void gpio_tog_sclk(void *data)
140+
{
141+
struct gd32_spi_bit_data *bd = data;
142+
143+
if (GPIO_OUTPUT_BIT_GET(bd->sclk.port, bd->sclk.pin) == SET)
144+
{
145+
GPIO_BIT_RESET(bd->sclk.port, bd->sclk.pin);
146+
}
147+
else
148+
{
149+
GPIO_BIT_SET(bd->sclk.port, bd->sclk.pin);
150+
}
151+
}
152+
153+
static void gpio_set_sclk(void *data, rt_int32_t state)
154+
{
155+
struct gd32_spi_bit_data *bd = data;
156+
157+
if (state)
158+
{
159+
GPIO_BIT_SET(bd->sclk.port, bd->sclk.pin);
160+
}
161+
else
162+
{
163+
GPIO_BIT_RESET(bd->sclk.port, bd->sclk.pin);
164+
}
165+
}
166+
167+
static void gpio_set_mosi(void *data, rt_int32_t state)
168+
{
169+
struct gd32_spi_bit_data *bd = data;
170+
171+
if (state)
172+
{
173+
GPIO_BIT_SET(bd->mosi.port, bd->mosi.pin);
174+
}
175+
else
176+
{
177+
GPIO_BIT_RESET(bd->mosi.port, bd->mosi.pin);
178+
}
179+
}
180+
181+
static void gpio_set_miso(void *data, rt_int32_t state)
182+
{
183+
struct gd32_spi_bit_data *bd = data;
184+
185+
if (state)
186+
{
187+
GPIO_BIT_SET(bd->miso.port, bd->miso.pin);
188+
}
189+
else
190+
{
191+
GPIO_BIT_RESET(bd->miso.port, bd->miso.pin);
192+
}
193+
}
194+
195+
static rt_int32_t gpio_get_sclk(void *data)
196+
{
197+
struct gd32_spi_bit_data *bd = data;
198+
199+
return GPIO_INPUT_BIT_GET(bd->sclk.port, bd->sclk.pin);
200+
}
201+
202+
static rt_int32_t gpio_get_mosi(void *data)
203+
{
204+
struct gd32_spi_bit_data *bd = data;
205+
206+
return GPIO_INPUT_BIT_GET(bd->mosi.port, bd->mosi.pin);
207+
}
208+
209+
static rt_int32_t gpio_get_miso(void *data)
210+
{
211+
struct gd32_spi_bit_data *bd = data;
212+
213+
return GPIO_INPUT_BIT_GET(bd->miso.port, bd->miso.pin);
214+
}
215+
216+
static void gpio_dir_mosi(void *data, rt_int32_t state)
217+
{
218+
struct gd32_spi_bit_data *bd = data;
219+
220+
if (state)
221+
{
222+
GPIO_SET_INPUT(bd->mosi.port, bd->mosi.pin);
223+
}
224+
else
225+
{
226+
GPIO_SET_OUTPUT(bd->mosi.port, bd->mosi.pin);
227+
}
228+
}
229+
230+
static void gpio_dir_miso(void *data, rt_int32_t state)
231+
{
232+
struct gd32_spi_bit_data *bd = data;
233+
234+
if (state)
235+
{
236+
GPIO_SET_INPUT(bd->miso.port, bd->miso.pin);
237+
}
238+
else
239+
{
240+
GPIO_SET_OUTPUT(bd->miso.port, bd->miso.pin);
241+
}
242+
}
243+
244+
static void gpio_udelay(rt_uint32_t us)
245+
{
246+
int i = ((rcu_clock_freq_get(CK_SYS) / 4000000) * us);
247+
248+
while (i)
249+
{
250+
i--;
251+
}
252+
}
253+
254+
static void soft_spi_gpio_init(const struct gd32_spi_bit_data *bd)
255+
{
256+
rcu_periph_clock_enable(bd->sclk.clk);
257+
rcu_periph_clock_enable(bd->mosi.clk);
258+
rcu_periph_clock_enable(bd->miso.clk);
259+
260+
gpio_init(bd->sclk.port, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, bd->sclk.pin);
261+
gpio_init(bd->mosi.port, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, bd->mosi.pin);
262+
gpio_init(bd->miso.port, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, bd->miso.pin);
263+
264+
GPIO_BIT_SET(bd->sclk.port, bd->sclk.pin);
265+
GPIO_BIT_SET(bd->mosi.port, bd->mosi.pin);
266+
GPIO_BIT_SET(bd->miso.port, bd->miso.pin);
267+
}
268+
269+
int rt_soft_spi_init(void)
270+
{
271+
int result = 0;
272+
273+
{
274+
static const struct gd32_spi_bit_data spi1_bdata =
275+
{
276+
.sclk = { RCU_GPIOB, GPIOB, GPIO_PIN_13},
277+
.mosi = { RCU_GPIOB, GPIOB, GPIO_PIN_15},
278+
.miso = { RCU_GPIOB, GPIOB, GPIO_PIN_14},
279+
};
280+
static struct rt_spi_bit_ops spi1_bops =
281+
{
282+
.data = (void *)&spi1_bdata,
283+
.tog_sclk = gpio_tog_sclk,
284+
.set_sclk = gpio_set_sclk,
285+
.set_mosi = gpio_set_mosi,
286+
.set_miso = gpio_set_miso,
287+
.get_sclk = gpio_get_sclk,
288+
.get_mosi = gpio_get_mosi,
289+
.get_miso = gpio_get_miso,
290+
.dir_mosi = gpio_dir_mosi,
291+
.dir_miso = gpio_dir_miso,
292+
.udelay = gpio_udelay,
293+
};
294+
struct rt_spi_bit_obj spi1_obj;
295+
296+
soft_spi_gpio_init(&spi1_bdata);
297+
rt_spi_bit_add_bus(&spi1_obj, "spi3", &spi1_bops);
298+
}
299+
300+
return result;
301+
}
302+
INIT_BOARD_EXPORT(rt_soft_spi_init);
303+
#endif
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (c) 2006-2021, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2021-10-11 kyle first implementation.
9+
*/
10+
11+
#ifndef __DRV_SOFT_SPI_H__
12+
#define __DRV_SOFT_SPI_H__
13+
14+
#ifdef __cplusplus
15+
extern "C" {
16+
#endif
17+
18+
int rt_soft_spi_init(void);
19+
20+
#ifdef __cplusplus
21+
}
22+
#endif
23+
24+
#endif // __DRV_SPI_H__

components/drivers/Kconfig

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,18 @@ config RT_USING_SPI
228228
bool "Using SPI Bus/Device device drivers"
229229
default n
230230

231-
if RT_USING_SPI
231+
if RT_USING_SPI
232+
config RT_USING_SPI_BITOPS
233+
select RT_USING_PIN
234+
bool "Use GPIO to simulate SPI"
235+
default n
236+
237+
if RT_USING_SPI_BITOPS
238+
config RT_SPI_BITOPS_DEBUG
239+
bool "Use simulate SPI debug message"
240+
default n
241+
endif
242+
232243
config RT_USING_QSPI
233244
bool "Enable QSPI mode"
234245
default n

components/drivers/spi/SConscript

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ src = ['spi_core.c', 'spi_dev.c']
66
CPPPATH = [cwd, cwd + '/../include']
77
LOCAL_CFLAGS = ''
88

9+
if GetDepend('RT_USING_SPI_BITOPS'):
10+
src += ['spi-bit-ops.c']
11+
912
if GetDepend('RT_USING_QSPI'):
1013
src += ['qspi_core.c']
1114

0 commit comments

Comments
 (0)