Skip to content

Commit b75e3c1

Browse files
committed
fix SPI dynamic config not working
1 parent f84ac77 commit b75e3c1

File tree

1 file changed

+48
-15
lines changed
  • firmware/src/peripherals

1 file changed

+48
-15
lines changed

firmware/src/peripherals/spi.c

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,32 @@ LOG_MODULE_REGISTER(periph_spi, CONFIG_LOG_DEFAULT_LEVEL);
88

99
#if DT_NODE_HAS_PROP(JABI_PERIPH_NODE, spi)
1010

11-
#define GEN_SPI_DT_SPEC(node_id, prop, idx) \
11+
#define GEN_SPI_DEV_DATA(node_id, prop, idx) \
1212
{ \
1313
.bus = DEVICE_DT_GET(DT_PROP_BY_IDX(node_id, prop, idx)), \
14-
.config = { \
14+
.configs[0] = { \
1515
.frequency = 1000000, \
1616
.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_LINES_SINGLE, \
1717
.cs = NULL, \
1818
}, \
19+
.curr_cfg = 0, \
20+
.stale = false, \
1921
},
2022

21-
static struct spi_dt_spec spi_devs[] = {
22-
DT_FOREACH_PROP_ELEM(JABI_PERIPH_NODE, spi, GEN_SPI_DT_SPEC)
23+
// SPI API uses pointer comparison to know when to update the config
24+
typedef struct {
25+
const struct device *bus;
26+
struct spi_config configs[2];
27+
int curr_cfg;
28+
bool stale;
29+
} spi_dev_data_t;
30+
31+
static spi_dev_data_t spi_devs[] = {
32+
DT_FOREACH_PROP_ELEM(JABI_PERIPH_NODE, spi, GEN_SPI_DEV_DATA)
2333
};
2434

2535
static int spi_init(uint16_t idx) {
36+
spi_devs[idx].configs[1] = spi_devs[idx].configs[0];
2637
return JABI_NO_ERR;
2738
}
2839

@@ -37,7 +48,10 @@ PERIPH_FUNC_DEF(spi_set_freq) {
3748

3849
LOG_DBG("(freq=%d)", args->freq);
3950

40-
spi_devs[idx].config.frequency = args->freq;
51+
spi_devs[idx].configs[0].frequency = args->freq;
52+
53+
spi_devs[idx].configs[1].frequency = spi_devs[idx].configs[0].frequency;
54+
spi_devs[idx].stale = true;
4155
*resp_len = 0;
4256
return JABI_NO_ERR;
4357
}
@@ -48,24 +62,27 @@ PERIPH_FUNC_DEF(spi_set_mode) {
4862

4963
LOG_DBG("(mode=%d)", args->mode);
5064

51-
spi_devs[idx].config.operation &= ~SPI_MODE_MASK;
65+
spi_devs[idx].configs[0].operation &= ~SPI_MODE_MASK;
5266
switch (args->mode) {
5367
case 0:
5468
break;
5569
case 1:
56-
spi_devs[idx].config.operation |= SPI_MODE_CPHA;
70+
spi_devs[idx].configs[0].operation |= SPI_MODE_CPHA;
5771
break;
5872
case 2:
59-
spi_devs[idx].config.operation |= SPI_MODE_CPOL;
73+
spi_devs[idx].configs[0].operation |= SPI_MODE_CPOL;
6074
break;
6175
case 3:
62-
spi_devs[idx].config.operation |= SPI_MODE_CPOL;
63-
spi_devs[idx].config.operation |= SPI_MODE_CPHA;
76+
spi_devs[idx].configs[0].operation |= SPI_MODE_CPOL;
77+
spi_devs[idx].configs[0].operation |= SPI_MODE_CPHA;
6478
break;
6579
default:
6680
LOG_ERR("invalid mode");
6781
return JABI_INVALID_ARGS_ERR;
6882
}
83+
84+
spi_devs[idx].configs[1].operation = spi_devs[idx].configs[0].operation;
85+
spi_devs[idx].stale = true;
6986
*resp_len = 0;
7087
return JABI_NO_ERR;
7188
}
@@ -77,23 +94,35 @@ PERIPH_FUNC_DEF(spi_set_bitorder) {
7794
LOG_DBG("(order=%d)", args->order);
7895

7996
if (args->order) {
80-
spi_devs[idx].config.operation &= ~SPI_TRANSFER_LSB;
97+
spi_devs[idx].configs[0].operation &= ~SPI_TRANSFER_LSB;
8198
} else {
82-
spi_devs[idx].config.operation |= SPI_TRANSFER_LSB;
99+
spi_devs[idx].configs[0].operation |= SPI_TRANSFER_LSB;
83100
}
101+
102+
spi_devs[idx].configs[1].operation = spi_devs[idx].configs[0].operation;
103+
spi_devs[idx].stale = true;
84104
*resp_len = 0;
85105
return JABI_NO_ERR;
86106
}
87107

108+
static inline void spi_update_config(uint16_t idx) {
109+
if (spi_devs[idx].stale) {
110+
spi_devs[idx].curr_cfg = spi_devs[idx].curr_cfg == 0 ? 1 : 0;
111+
spi_devs[idx].stale = false;
112+
}
113+
}
114+
88115
PERIPH_FUNC_DEF(spi_write_j) {
89116
PERIPH_FUNC_GET_ARGS(spi, write_j);
90117

91118
LOG_DBG("()");
92119
LOG_HEXDUMP_DBG(args, req_len, "data=");
93120

121+
spi_update_config(idx);
122+
spi_dev_data_t *spi = &spi_devs[idx];
94123
struct spi_buf buf = { .buf = args, .len = req_len };
95124
struct spi_buf_set set = { .buffers = &buf, .count = 1};
96-
if (spi_write_dt(&spi_devs[idx], &set)) {
125+
if (spi_write(spi->bus, &spi->configs[spi->curr_cfg], &set)) {
97126
LOG_ERR("failed to write");
98127
return JABI_PERIPHERAL_ERR;
99128
}
@@ -114,9 +143,11 @@ PERIPH_FUNC_DEF(spi_read_j) {
114143

115144
LOG_DBG("(data_len=%d)", args->data_len);
116145

146+
spi_update_config(idx);
147+
spi_dev_data_t *spi = &spi_devs[idx];
117148
struct spi_buf buf = { .buf = ret, .len = args->data_len };
118149
struct spi_buf_set set = { .buffers = &buf, .count = 1 };
119-
if (spi_read_dt(&spi_devs[idx], &set)) {
150+
if (spi_read(spi->bus, &spi->configs[spi->curr_cfg], &set)) {
120151
LOG_ERR("failed to write");
121152
return JABI_PERIPHERAL_ERR;
122153
}
@@ -136,11 +167,13 @@ PERIPH_FUNC_DEF(spi_transceive_j) {
136167
LOG_DBG("()");
137168
LOG_HEXDUMP_DBG(args, req_len, "data=");
138169

170+
spi_update_config(idx);
171+
spi_dev_data_t *spi = &spi_devs[idx];
139172
struct spi_buf txbuf = { .buf = args, .len = req_len };
140173
struct spi_buf rxbuf = { .buf = ret, .len = req_len };
141174
struct spi_buf_set txset = { .buffers = &txbuf, .count = 1};
142175
struct spi_buf_set rxset = { .buffers = &rxbuf, .count = 1 };
143-
if (spi_transceive_dt(&spi_devs[idx], &txset, &rxset)) {
176+
if (spi_transceive(spi->bus, &spi->configs[spi->curr_cfg], &txset, &rxset)) {
144177
LOG_ERR("failed to write");
145178
return JABI_PERIPHERAL_ERR;
146179
}

0 commit comments

Comments
 (0)