Skip to content

Commit 997c652

Browse files
authored
Merge pull request #3624 from ShermanShao/master
[BSP]Add nrf5x SPI BSP
2 parents a6a8b90 + a178678 commit 997c652

File tree

5 files changed

+442
-7
lines changed

5 files changed

+442
-7
lines changed

bsp/nrf5x/libraries/drivers/SConscript

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ if GetDepend(['BSP_USING_ON_CHIP_FLASH']):
1717
if GetDepend(['BSP_USING_QSPI_FLASH']):
1818
src += ['drv_qspi_flash.c']
1919

20+
if GetDepend(['BSP_USING_SPI']):
21+
src += ['drv_spi.c']
22+
2023
path = [cwd]
2124

2225
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)
Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
/*
2+
* Copyright (c) 2006-2018, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2020-05-22 Sherman first version
9+
*/
10+
11+
#include <stdint.h>
12+
#include <string.h>
13+
#include "board.h"
14+
#include "drv_spi.h"
15+
16+
#define DBG_LEVEL DBG_LOG
17+
#include <rtdbg.h>
18+
#define LOG_TAG "drv.spi"
19+
20+
#ifdef BSP_USING_SPI
21+
22+
static struct nrfx_drv_spi_config spi_config[] =
23+
{
24+
#ifdef BSP_USING_SPI0
25+
NRFX_SPI0_CONFIG,
26+
#endif
27+
28+
#ifdef BSP_USING_SPI1
29+
NRFX_SPI1_CONFIG,
30+
#endif
31+
32+
#ifdef BSP_USING_SPI2
33+
NRFX_SPI2_CONFIG,
34+
#endif
35+
36+
};
37+
38+
static struct nrfx_drv_spi spi_bus_obj[sizeof(spi_config) / sizeof(spi_config[0])];
39+
40+
//Configure SPI bus pins using the menuconfig
41+
static struct nrfx_drv_spi_pin_config bsp_spi_pin[] =
42+
{
43+
#ifdef BSP_USING_SPI0
44+
{
45+
.sck_pin = BSP_SPI0_SCK_PIN,
46+
.mosi_pin = BSP_SPI0_MOSI_PIN,
47+
.miso_pin = BSP_SPI0_MISO_PIN,
48+
.ss_pin = BSP_SPI0_SS_PIN
49+
},
50+
#endif
51+
52+
#ifdef BSP_USING_SPI1
53+
{
54+
.sck_pin = BSP_SPI1_SCK_PIN,
55+
.mosi_pin = BSP_SPI1_MOSI_PIN,
56+
.miso_pin = BSP_SPI1_MISO_PIN,
57+
.ss_pin = BSP_SPI1_SS_PIN
58+
},
59+
#endif
60+
61+
#ifdef BSP_USING_SPI2
62+
{
63+
.sck_pin = BSP_SPI2_SCK_PIN,
64+
.mosi_pin = BSP_SPI2_MOSI_PIN,
65+
.miso_pin = BSP_SPI2_MISO_PIN,
66+
.ss_pin = BSP_SPI2_SS_PIN
67+
},
68+
#endif
69+
};
70+
71+
72+
static rt_uint8_t spi_index_find(struct rt_spi_bus *spi_bus)
73+
{
74+
for (int i = 0; i < sizeof(spi_config) / sizeof(spi_config[0]); i++)
75+
{
76+
if(spi_bus == &spi_bus_obj[i].spi_bus)
77+
return i;
78+
}
79+
return 0xFF;
80+
}
81+
82+
/**
83+
* spi event handler function
84+
*/
85+
static void spi0_handler(const nrfx_spi_evt_t *p_event, void *p_context)
86+
{
87+
LOG_I("\nspi0_handler");
88+
}
89+
90+
static void spi1_handler(const nrfx_spi_evt_t *p_event, void *p_context)
91+
{
92+
LOG_I("\nspi1_handler");
93+
}
94+
95+
static void spi2_handler(const nrfx_spi_evt_t *p_event, void *p_context)
96+
{
97+
LOG_I("\nspi2_handler");
98+
}
99+
nrfx_spi_evt_handler_t spi_handler[] = {spi0_handler, spi1_handler, spi2_handler};
100+
101+
/**
102+
* @brief This function config spi bus
103+
* @param device
104+
* @param configuration
105+
* @retval RT_EOK / RT_ERROR
106+
*/
107+
static rt_err_t spi_configure(struct rt_spi_device *device,
108+
struct rt_spi_configuration *configuration)
109+
{
110+
RT_ASSERT(device != RT_NULL);
111+
RT_ASSERT(device->bus != RT_NULL);
112+
RT_ASSERT(device->bus->parent.user_data != RT_NULL);
113+
RT_ASSERT(configuration != RT_NULL);
114+
115+
rt_uint8_t index = spi_index_find(device->bus);
116+
RT_ASSERT(index != 0xFF);
117+
118+
nrfx_spi_t spi = spi_bus_obj[index].spi;
119+
nrfx_spi_config_t config = NRFX_SPI_DEFAULT_CONFIG(bsp_spi_pin[index].sck_pin,
120+
bsp_spi_pin[index].mosi_pin, bsp_spi_pin[index].miso_pin, bsp_spi_pin[index].ss_pin);
121+
122+
/* spi config ss pin */
123+
if(device->user_data != RT_NULL)
124+
{
125+
config.ss_pin = (rt_uint8_t)device->user_data;
126+
}
127+
/* spi config bit order */
128+
if(configuration->mode & RT_SPI_MSB)
129+
{
130+
config.bit_order = NRF_SPI_BIT_ORDER_MSB_FIRST;
131+
}
132+
else
133+
{
134+
config.bit_order = NRF_SPI_BIT_ORDER_LSB_FIRST;
135+
}
136+
/* spi mode config */
137+
switch (configuration->mode & RT_SPI_MODE_3 )
138+
{
139+
case RT_SPI_MODE_0/* RT_SPI_CPOL:0 , RT_SPI_CPHA:0 */:
140+
config.mode = NRF_SPI_MODE_0;
141+
break;
142+
case RT_SPI_MODE_1/* RT_SPI_CPOL:0 , RT_SPI_CPHA:1 */:
143+
config.mode = NRF_SPI_MODE_1;
144+
break;
145+
case RT_SPI_MODE_2/* RT_SPI_CPOL:1 , RT_SPI_CPHA:0 */:
146+
config.mode = NRF_SPI_MODE_2;
147+
break;
148+
case RT_SPI_MODE_3/* RT_SPI_CPOL:1 , RT_SPI_CPHA:1 */:
149+
config.mode = NRF_SPI_MODE_3;
150+
break;
151+
default:
152+
LOG_E("spi_configure mode error %x\n",configuration->mode);
153+
return RT_ERROR;
154+
}
155+
/* spi frequency config */
156+
switch (configuration->max_hz / 1000)
157+
{
158+
case 125:
159+
config.frequency = NRF_SPI_FREQ_125K;
160+
break;
161+
case 250:
162+
config.frequency = NRF_SPI_FREQ_250K;
163+
break;
164+
case 500:
165+
config.frequency = NRF_SPI_FREQ_500K;
166+
break;
167+
case 1000:
168+
config.frequency = NRF_SPI_FREQ_1M;
169+
break;
170+
case 2000:
171+
config.frequency = NRF_SPI_FREQ_2M;
172+
break;
173+
case 4000:
174+
config.frequency = NRF_SPI_FREQ_4M;
175+
break;
176+
case 8000:
177+
config.frequency = NRF_SPI_FREQ_8M;
178+
break;
179+
default:
180+
LOG_E("spi_configure rate error %d\n",configuration->max_hz);
181+
break;
182+
}
183+
184+
rt_memcpy((void*)&spi_bus_obj[index].spi_config, (void*)&config, sizeof(nrfx_spi_config_t));
185+
nrfx_spi_evt_handler_t handler = RT_NULL; //spi send callback handler ,default NULL
186+
void * context = RT_NULL;
187+
nrfx_err_t nrf_ret = nrfx_spi_init(&spi, &config, handler, context);
188+
if(NRFX_SUCCESS == nrf_ret)
189+
return RT_EOK;
190+
191+
return RT_ERROR;
192+
}
193+
194+
static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
195+
{
196+
RT_ASSERT(device != RT_NULL);
197+
RT_ASSERT(device->bus != RT_NULL);
198+
RT_ASSERT(device->bus->parent.user_data != RT_NULL);
199+
200+
rt_uint8_t index = spi_index_find(device->bus);
201+
RT_ASSERT(index != 0xFF);
202+
203+
nrfx_spi_t * p_instance = &spi_bus_obj[index].spi;
204+
nrfx_spi_xfer_desc_t p_xfer_desc;
205+
if(message->send_buf == RT_NULL)
206+
{
207+
p_xfer_desc.p_rx_buffer = message->recv_buf;
208+
p_xfer_desc.rx_length = message->length;
209+
210+
p_xfer_desc.p_tx_buffer = RT_NULL;
211+
p_xfer_desc.tx_length = 0;
212+
}
213+
else
214+
{
215+
p_xfer_desc.p_tx_buffer = message->send_buf;
216+
p_xfer_desc.tx_length = message->length ;
217+
218+
p_xfer_desc.p_rx_buffer = RT_NULL;
219+
p_xfer_desc.rx_length = 0;
220+
}
221+
222+
nrfx_err_t nrf_ret = nrfx_spi_xfer(p_instance, &p_xfer_desc, 0);
223+
if( NRFX_SUCCESS == nrf_ret)
224+
return message->length;
225+
else
226+
return 0;
227+
}
228+
229+
/* spi bus callback function */
230+
static const struct rt_spi_ops nrfx_spi_ops =
231+
{
232+
.configure = spi_configure,
233+
.xfer = spixfer,
234+
};
235+
236+
/*spi bus init*/
237+
static int rt_hw_spi_bus_init(void)
238+
{
239+
rt_err_t result = RT_ERROR;
240+
for (int i = 0; i < sizeof(spi_config) / sizeof(spi_config[0]); i++)
241+
{
242+
spi_bus_obj[i].spi = spi_config[i].spi;
243+
spi_bus_obj[i].spi_bus.parent.user_data = &spi_config[i]; //SPI INSTANCE
244+
result = rt_spi_bus_register(&spi_bus_obj[i].spi_bus, spi_config[i].bus_name, &nrfx_spi_ops);
245+
RT_ASSERT(result == RT_EOK);
246+
}
247+
return result;
248+
}
249+
250+
int rt_hw_spi_init(void)
251+
{
252+
return rt_hw_spi_bus_init();
253+
}
254+
INIT_BOARD_EXPORT(rt_hw_spi_init);
255+
256+
/**
257+
* Attach the spi device to SPI bus, this function must be used after initialization.
258+
*/
259+
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_uint32_t ss_pin)
260+
{
261+
RT_ASSERT(bus_name != RT_NULL);
262+
RT_ASSERT(device_name != RT_NULL);
263+
264+
rt_err_t result;
265+
struct rt_spi_device *spi_device;
266+
/* attach the device to spi bus*/
267+
spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
268+
RT_ASSERT(spi_device != RT_NULL);
269+
/* initialize the cs pin */
270+
spi_device->user_data = (void*)ss_pin;
271+
result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, RT_NULL);
272+
if (result != RT_EOK)
273+
{
274+
LOG_E("%s attach to %s faild, %d", device_name, bus_name, result);
275+
result = RT_ERROR;
276+
}
277+
RT_ASSERT(result == RT_EOK);
278+
return result;
279+
}
280+
281+
#endif /*BSP_USING_SPI*/
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright (c) 2006-2018, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2020-05-19 Sherman first version
9+
*/
10+
11+
#include <rtthread.h>
12+
#include <rtdevice.h>
13+
#include <rthw.h>
14+
15+
#ifndef __DRV_SPI_H_
16+
#define __DRV_SPI_H_
17+
18+
#ifdef BSP_USING_SPI
19+
#include "nrfx_spi.h"
20+
21+
/**
22+
* @brief Attach the spi device to SPI bus, this function must be used after initialization.
23+
* @param bus_name spi bus name "spi0"/"spi1"/"spi2"
24+
* @param device_name spi device name "spi0x"/"spi1x"/"spi2x"
25+
* @param ss_pin spi ss pin number
26+
* @retval RT_ERROR / RT_EOK
27+
*/
28+
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_uint32_t ss_pin);
29+
30+
//SPI bus config
31+
#ifdef BSP_USING_SPI0
32+
#define NRFX_SPI0_CONFIG \
33+
{ \
34+
.bus_name = "spi0", \
35+
.spi = NRFX_SPI_INSTANCE(0) \
36+
}
37+
#endif
38+
#ifdef BSP_USING_SPI1
39+
#define NRFX_SPI1_CONFIG \
40+
{ \
41+
.bus_name = "spi1", \
42+
.spi = NRFX_SPI_INSTANCE(1) \
43+
}
44+
#endif
45+
46+
#ifdef BSP_USING_SPI2
47+
#define NRFX_SPI2_CONFIG \
48+
{ \
49+
.bus_name = "spi2", \
50+
.spi = NRFX_SPI_INSTANCE(2) \
51+
}
52+
#endif
53+
54+
struct nrfx_drv_spi_config
55+
{
56+
char *bus_name;
57+
nrfx_spi_t spi;
58+
};
59+
60+
struct nrfx_drv_spi
61+
{
62+
nrfx_spi_t spi; /* nrfx spi driver instance. */
63+
nrfx_spi_config_t spi_config; /* nrfx spi config Configuration */
64+
struct rt_spi_configuration *cfg;
65+
struct rt_spi_bus spi_bus;
66+
};
67+
68+
struct nrfx_drv_spi_pin_config
69+
{
70+
rt_uint8_t sck_pin;
71+
rt_uint8_t mosi_pin;
72+
rt_uint8_t miso_pin;
73+
rt_uint8_t ss_pin;
74+
};
75+
76+
#endif /* BSP_USING_SPI */
77+
#endif /*__DRV_SPI_H_*/

0 commit comments

Comments
 (0)