Skip to content

Commit 19b36ae

Browse files
Tomasz BursztykaAnas Nashif
authored andcommitted
drivers/spi: Adapt DW driver to new SPI API
Introducing as well a generic driver helper for CS gpio control and buffer management. Signed-off-by: Tomasz Bursztyka <[email protected]>
1 parent dd0c359 commit 19b36ae

File tree

7 files changed

+841
-203
lines changed

7 files changed

+841
-203
lines changed

drivers/spi/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
obj-$(CONFIG_SPI_INTEL) += spi_intel.o
2+
ifeq ($(CONFIG_SPI_LEGACY_API),y)
3+
obj-$(CONFIG_SPI_DW) += spi_dw_legacy.o
4+
else
25
obj-$(CONFIG_SPI_DW) += spi_dw.o
6+
endif
37
obj-$(CONFIG_SPI_MCUX_DSPI) += spi_mcux_dspi.o
48
obj-$(CONFIG_SPIM_NRF52) += spim_nrf52.o
59
obj-$(CONFIG_SPIS_NRF5) += spis_nrf5.o

drivers/spi/spi_context.h

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/*
2+
* Copyright (c) 2017 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/**
8+
* @file
9+
* @brief Private API for SPI drivers
10+
*/
11+
12+
#ifndef __SPI_DRIVER_COMMON_H__
13+
#define __SPI_DRIVER_COMMON_H__
14+
15+
#include <gpio.h>
16+
#include <spi.h>
17+
18+
#ifdef __cplusplus
19+
extern "C" {
20+
#endif
21+
22+
struct spi_context {
23+
struct spi_config *config;
24+
25+
const struct spi_buf **current_tx;
26+
struct spi_buf **current_rx;
27+
28+
void *tx_buf;
29+
u32_t tx_len;
30+
void *rx_buf;
31+
u32_t rx_len;
32+
};
33+
34+
static inline bool spi_context_configured(struct spi_context *ctx,
35+
struct spi_config *config)
36+
{
37+
return !!(ctx->config == config);
38+
}
39+
40+
static inline void spi_context_cs_configure(struct spi_context *ctx)
41+
{
42+
if (ctx->config->cs) {
43+
gpio_pin_configure(ctx->config->cs->gpio_dev,
44+
ctx->config->cs->gpio_pin, GPIO_DIR_OUT);
45+
gpio_pin_write(ctx->config->cs->gpio_dev,
46+
ctx->config->cs->gpio_pin, 1);
47+
}
48+
}
49+
50+
static inline void spi_context_cs_control(struct spi_context *ctx, bool on)
51+
{
52+
if (ctx->config->cs) {
53+
if (on) {
54+
gpio_pin_write(ctx->config->cs->gpio_dev,
55+
ctx->config->cs->gpio_pin, 0);
56+
k_busy_wait(ctx->config->cs->delay);
57+
} else {
58+
k_busy_wait(ctx->config->cs->delay);
59+
gpio_pin_write(ctx->config->cs->gpio_dev,
60+
ctx->config->cs->gpio_pin, 1);
61+
}
62+
}
63+
}
64+
65+
static inline void spi_context_buffers_setup(struct spi_context *ctx,
66+
const struct spi_buf **tx_bufs,
67+
struct spi_buf **rx_bufs,
68+
uint8_t dfs)
69+
{
70+
SYS_LOG_DBG("tx_bufs %p (%p) - rx_bufs %p (%p) - %u",
71+
tx_bufs, tx_bufs ? *tx_bufs : NULL,
72+
rx_bufs, rx_bufs ? *rx_bufs : NULL, dfs);
73+
74+
ctx->current_tx = tx_bufs;
75+
ctx->current_rx = rx_bufs;
76+
77+
if (*tx_bufs) {
78+
ctx->tx_buf = (*tx_bufs)->buf;
79+
ctx->tx_len = (*tx_bufs)->len/dfs;
80+
} else {
81+
ctx->tx_buf = NULL;
82+
ctx->tx_len = 0;
83+
}
84+
85+
if (*rx_bufs) {
86+
ctx->rx_buf = (*rx_bufs)->buf;
87+
ctx->rx_len = (*rx_bufs)->len/dfs;
88+
} else {
89+
ctx->rx_buf = NULL;
90+
ctx->rx_len = 0;
91+
}
92+
93+
SYS_LOG_DBG("current_tx %p, current_rx %p,"
94+
" tx buf/len %p/%u, rx buf/len %p/%u",
95+
ctx->current_tx, ctx->current_rx,
96+
ctx->tx_buf, ctx->tx_len, ctx->rx_buf, ctx->rx_len);
97+
}
98+
99+
static ALWAYS_INLINE
100+
void spi_context_update_tx(struct spi_context *ctx, uint8_t dfs)
101+
{
102+
if (!ctx->tx_len) {
103+
return;
104+
}
105+
106+
ctx->tx_len--;
107+
if (!ctx->tx_len) {
108+
ctx->current_tx++;
109+
if (*ctx->current_tx) {
110+
ctx->tx_buf = (*ctx->current_tx)->buf;
111+
ctx->tx_len = (*ctx->current_tx)->len/dfs;
112+
} else {
113+
ctx->tx_buf = NULL;
114+
}
115+
} else if (ctx->tx_buf) {
116+
ctx->tx_buf += dfs;
117+
}
118+
119+
SYS_LOG_DBG("tx buf/len %p/%u", ctx->tx_buf, ctx->tx_len);
120+
}
121+
122+
static ALWAYS_INLINE
123+
bool spi_context_tx_on(struct spi_context *ctx)
124+
{
125+
return !!(ctx->tx_buf || ctx->tx_len);
126+
}
127+
128+
static ALWAYS_INLINE
129+
void spi_context_update_rx(struct spi_context *ctx, uint8_t dfs)
130+
{
131+
if (!ctx->rx_len) {
132+
return;
133+
}
134+
135+
ctx->rx_len--;
136+
if (!ctx->rx_len) {
137+
ctx->current_rx++;
138+
if (*ctx->current_rx) {
139+
ctx->rx_buf = (*ctx->current_rx)->buf;
140+
ctx->rx_len = (*ctx->current_rx)->len/dfs;
141+
} else {
142+
ctx->rx_buf = NULL;
143+
}
144+
} else if (ctx->rx_buf) {
145+
ctx->rx_buf += dfs;
146+
}
147+
148+
SYS_LOG_DBG("rx buf/len %p/%u", ctx->rx_buf, ctx->rx_len);
149+
}
150+
151+
static ALWAYS_INLINE
152+
bool spi_context_rx_on(struct spi_context *ctx)
153+
{
154+
return !!(ctx->rx_buf || ctx->rx_len);
155+
}
156+
157+
#ifdef __cplusplus
158+
}
159+
#endif
160+
161+
#endif /* __SPI_DRIVER_COMMON_H__ */

0 commit comments

Comments
 (0)