Skip to content

Commit 464ea7c

Browse files
committed
添加了spim的底层驱动和设备驱动
1 parent f05f344 commit 464ea7c

File tree

4 files changed

+1965
-0
lines changed

4 files changed

+1965
-0
lines changed
Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
#include <stdint.h>
2+
#include <string.h>
3+
#include "board.h"
4+
#include "drv_spim.h"
5+
#include "nrfx_spim.h"
6+
#include "rtconfig.h"
7+
#include <rtthread.h>
8+
#include <rtdevice.h>
9+
10+
#define DBG_LEVEL DBG_LOG
11+
#include <rtdbg.h>
12+
//#define LOG_TAG "drv.spim"
13+
14+
#ifdef BSP_USING_SPIM
15+
16+
#if defined(BSP_USING_SPIM0) || defined(BSP_USING_SPIM1) || defined(BSP_USING_SPIM2) || defined(BSP_USING_SPIM3)
17+
18+
static struct nrfx_drv_spim_config spim_config[] =
19+
{
20+
#ifdef BSP_USING_SPIM0
21+
NRFX_SPIM0_CONFIG,
22+
#endif
23+
24+
#ifdef BSP_USING_SPIM1
25+
NRFX_SPIM1_CONFIG,
26+
#endif
27+
28+
#ifdef BSP_USING_SPIM2
29+
NRFX_SPIM2_CONFIG,
30+
#endif
31+
32+
#ifdef BSP_USING_SPIM3
33+
NRFX_SPIM3_CONFIG,
34+
#endif
35+
36+
};
37+
38+
static struct nrfx_drv_spim spim_bus_obj[sizeof(spim_config) / sizeof(spim_config[0])];
39+
40+
//Configure SPIM bus pins using the menuconfig
41+
static struct nrfx_drv_spim_pin_config bsp_spim_pin[] =
42+
{
43+
#ifdef BSP_USING_SPIM0
44+
{
45+
.sck_pin = BSP_SPIM0_SCK_PIN,
46+
.mosi_pin = BSP_SPIM0_MOSI_PIN,
47+
.miso_pin = BSP_SPIM0_MISO_PIN,
48+
.ss_pin = BSP_SPIM0_SS_PIN
49+
},
50+
#endif
51+
52+
#ifdef BSP_USING_SPIM1
53+
{
54+
.sck_pin = BSP_SPIM1_SCK_PIN,
55+
.mosi_pin = BSP_SPIM1_MOSI_PIN,
56+
.miso_pin = BSP_SPIM1_MISO_PIN,
57+
.ss_pin = BSP_SPIM1_SS_PIN
58+
},
59+
#endif
60+
61+
#ifdef BSP_USING_SPIM2
62+
{
63+
.sck_pin = BSP_SPIM2_SCK_PIN,
64+
.mosi_pin = BSP_SPIM2_MOSI_PIN,
65+
.miso_pin = BSP_SPIM2_MISO_PIN,
66+
.ss_pin = BSP_SPIM2_SS_PIN
67+
},
68+
#endif
69+
70+
#ifdef BSP_USING_SPIM3
71+
{
72+
.sck_pin = BSP_SPIM3_SCK_PIN,
73+
.mosi_pin = BSP_SPIM3_MOSI_PIN,
74+
.miso_pin = BSP_SPIM3_MISO_PIN,
75+
.ss_pin = BSP_SPIM3_SS_PIN
76+
},
77+
#endif
78+
79+
};
80+
81+
static rt_uint8_t spim_index_find(struct rt_spi_bus *spi_bus)
82+
{
83+
for (int i = 0; i < sizeof(spim_config) / sizeof(spim_config[0]); i++)
84+
{
85+
if(spi_bus == &spim_bus_obj[i].spim_bus)
86+
return i;
87+
}
88+
return 0xFF;
89+
}
90+
91+
/**
92+
* spi event handler function
93+
*/
94+
#ifdef BSP_USING_SPIM0
95+
static void spim0_handler(const nrfx_spim_evt_t *p_event, void *p_context)
96+
{
97+
LOG_I("\nspim0_handler");
98+
}
99+
#endif
100+
101+
#ifdef BSP_USING_SPIM1
102+
static void spim1_handler(const nrfx_spim_evt_t *p_event, void *p_context)
103+
{
104+
LOG_I("\nspim1_handler");
105+
}
106+
#endif
107+
108+
#ifdef BSP_USING_SPIM2
109+
static void spim2_handler(const nrfx_spim_evt_t *p_event, void *p_context)
110+
{
111+
return;
112+
}
113+
#endif
114+
115+
#ifdef BSP_USING_SPIM3
116+
static void spim3_handler(const nrfx_spim_evt_t *p_event, void *p_context)
117+
{
118+
return;
119+
}
120+
#endif
121+
122+
nrfx_spim_evt_handler_t spim_handler[] = {
123+
#ifdef BSP_USING_SPIM0
124+
spim0_handler,
125+
#endif
126+
127+
#ifdef BSP_USING_SPIM1
128+
spim1_handler,
129+
#endif
130+
131+
#ifdef BSP_USING_SPIM2
132+
spim2_handler,
133+
#endif
134+
135+
#ifdef BSP_USING_SPIM3
136+
spim3_handler,
137+
#endif
138+
139+
};
140+
141+
/**
142+
* @brief This function config spi bus
143+
* @param device
144+
* @param configuration
145+
* @retval RT_EOK / -RT_ERROR
146+
*/
147+
static rt_err_t spim_configure(struct rt_spi_device *device,
148+
struct rt_spi_configuration *configuration)
149+
{
150+
RT_ASSERT(device != RT_NULL);
151+
RT_ASSERT(device->bus != RT_NULL);
152+
RT_ASSERT(device->bus->parent.user_data != RT_NULL);
153+
RT_ASSERT(configuration != RT_NULL);
154+
155+
rt_uint8_t index = spim_index_find(device->bus);
156+
RT_ASSERT(index != 0xFF);
157+
158+
nrfx_spim_t spim = spim_bus_obj[index].spim;
159+
nrfx_spim_config_t config = NRFX_SPIM_DEFAULT_CONFIG(bsp_spim_pin[index].sck_pin,
160+
bsp_spim_pin[index].mosi_pin,
161+
bsp_spim_pin[index].miso_pin,
162+
bsp_spim_pin[index].ss_pin);
163+
config.ss_active_high = false;
164+
165+
/* spi config ss pin */
166+
167+
/* spi config bit order */
168+
if(configuration->mode & RT_SPI_MSB)
169+
{
170+
config.bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST;
171+
}
172+
else
173+
{
174+
config.bit_order = NRF_SPIM_BIT_ORDER_LSB_FIRST;
175+
}
176+
/* spi mode config */
177+
switch (configuration->mode & NRF_SPIM_MODE_3)
178+
{
179+
case NRF_SPIM_MODE_0/* RT_SPI_CPOL:0 , RT_SPI_CPHA:0 */:
180+
config.mode = NRF_SPIM_MODE_0;
181+
break;
182+
case NRF_SPIM_MODE_1/* RT_SPI_CPOL:0 , RT_SPI_CPHA:1 */:
183+
config.mode = NRF_SPIM_MODE_1;
184+
break;
185+
case NRF_SPIM_MODE_2/* RT_SPI_CPOL:1 , RT_SPI_CPHA:0 */:
186+
config.mode = NRF_SPIM_MODE_2;
187+
break;
188+
case NRF_SPIM_MODE_3/* RT_SPI_CPOL:1 , RT_SPI_CPHA:1 */:
189+
config.mode = NRF_SPIM_MODE_3;
190+
break;
191+
default:
192+
LOG_E("spim_configure mode error %x\n",configuration->mode);
193+
return -RT_ERROR;
194+
}
195+
/* spi frequency config */
196+
switch (configuration->max_hz / 1000)
197+
{
198+
case 125:
199+
config.frequency = NRF_SPIM_FREQ_125K;
200+
break;
201+
case 250:
202+
config.frequency = NRF_SPIM_FREQ_250K;
203+
break;
204+
case 500:
205+
config.frequency = NRF_SPIM_FREQ_500K;
206+
break;
207+
case 1000:
208+
config.frequency = NRF_SPIM_FREQ_1M;
209+
break;
210+
case 2000:
211+
config.frequency = NRF_SPIM_FREQ_2M;
212+
break;
213+
case 4000:
214+
config.frequency = NRF_SPIM_FREQ_4M;
215+
break;
216+
case 8000:
217+
config.frequency = NRF_SPIM_FREQ_8M;
218+
break;
219+
case 16000:
220+
config.frequency = NRF_SPIM_FREQ_16M;
221+
break;
222+
case 32000:
223+
config.frequency = NRF_SPIM_FREQ_32M;
224+
break;
225+
226+
default:
227+
LOG_E("spim_configure rate error %d\n",configuration->max_hz);
228+
break;
229+
}
230+
231+
rt_memcpy((void*)&spim_bus_obj[index].spim_config, (void*)&config, sizeof(nrfx_spim_config_t));
232+
233+
void * context = RT_NULL;
234+
nrfx_spim_evt_handler_t handler = RT_NULL; //spi send callback handler ,default NULL
235+
236+
#if USING_SPI_DMA
237+
/* 创造、初始化完成量 */
238+
struct rt_completion *cpt = (struct rt_completion*)rt_malloc(sizeof(struct rt_completion));
239+
rt_completion_init(cpt);
240+
241+
/* 创造、初始化spi关于dma的信息体 */
242+
struct spi_dma_message *mess = (struct spi_dma_message*)rt_malloc(sizeof(struct spi_dma_message));
243+
//step 1
244+
mess->cs_pin = device->cs_pin;
245+
//step 2
246+
mess->cs_take = 0;
247+
mess->cs_release = 0;
248+
//step 3
249+
mess->use_hw_ss = config.use_hw_ss;
250+
//step 4
251+
mess->ss_active_high = config.ss_active_high;
252+
//step 6
253+
mess->cpt = cpt;
254+
255+
/* 赋值 */
256+
context = (void*)mess;
257+
handler = spim_handler[index];
258+
#endif
259+
260+
nrfx_err_t nrf_ret = nrfx_spim_init(&spim, &config, handler, context);
261+
if(NRFX_SUCCESS == nrf_ret)
262+
return RT_EOK;
263+
else
264+
LOG_E("spim configure fail. %x", nrf_ret);
265+
266+
return -RT_ERROR;
267+
}
268+
269+
270+
static rt_ssize_t spimxfer(struct rt_spi_device *device, struct rt_spi_message *message)
271+
{
272+
RT_ASSERT(device != RT_NULL);
273+
RT_ASSERT(device->bus != RT_NULL);
274+
RT_ASSERT(device->bus->parent.user_data != RT_NULL);
275+
276+
rt_uint8_t index = spim_index_find(device->bus);
277+
nrfx_err_t nrf_ret;
278+
RT_ASSERT(index != 0xFF);
279+
280+
nrfx_spim_t * p_instance = &(spim_bus_obj[index].spim);
281+
282+
nrfx_spim_xfer_desc_t p_xfer_desc = NRFX_SPIM_XFER_TRX(message->send_buf, message->length, message->recv_buf, message->length);
283+
284+
if(message->send_buf == RT_NULL)
285+
{
286+
p_xfer_desc.tx_length = 0;
287+
}
288+
if(message->recv_buf == RT_NULL)
289+
{
290+
p_xfer_desc.rx_length = 0;
291+
}
292+
293+
nrf_ret = rtt_nrfx_spim_xfer(p_instance, &p_xfer_desc, 0, message, device);
294+
295+
if( NRFX_SUCCESS != nrf_ret)
296+
{
297+
LOG_E("SPIM data transfer fail. %x", nrf_ret);
298+
return 0;
299+
}
300+
else
301+
{
302+
return message->length;
303+
}
304+
}
305+
306+
307+
/* spi bus callback function */
308+
static const struct rt_spi_ops nrfx_spim_ops =
309+
{
310+
.configure = spim_configure,
311+
.xfer = spimxfer,
312+
};
313+
314+
/*spim bus init*/
315+
static int rt_hw_spim_bus_init(void)
316+
{
317+
rt_err_t result = -RT_ERROR;
318+
for (int i = 0; i < sizeof(spim_config) / sizeof(spim_config[0]); i++)
319+
{
320+
spim_bus_obj[i].spim = spim_config[i].spi;
321+
spim_bus_obj[i].spim_bus.parent.user_data = &spim_config[i]; //SPI INSTANCE
322+
result = rt_spi_bus_register(&spim_bus_obj[i].spim_bus, spim_config[i].bus_name, &nrfx_spim_ops);
323+
RT_ASSERT(result == RT_EOK);
324+
}
325+
return result;
326+
}
327+
328+
int rt_hw_spim_init(void)
329+
{
330+
return rt_hw_spim_bus_init();
331+
}
332+
333+
INIT_BOARD_EXPORT(rt_hw_spim_init);
334+
335+
#endif /* BSP_USING_SPIM0 || BSP_USING_SPIM1 || BSP_USING_SPIM2 || BSP_USING_SPIM3 */
336+
#endif /*BSP_USING_SPIM*/
337+

0 commit comments

Comments
 (0)