Skip to content

Commit 03f919f

Browse files
cyliangtwkartben
authored andcommitted
drivers: spi: fix numaker spi driver bug of frame size
Set right frame size in spi_context_buffers_setup and fetch the right rx size based on frame size. Also clear SPI control register before set mode & data width in spi configure routine. Signed-off-by: cyliang tw <cyliang@nuvoton.com>
1 parent ce95b70 commit 03f919f

File tree

1 file changed

+53
-46
lines changed

1 file changed

+53
-46
lines changed

drivers/spi/spi_numaker.c

Lines changed: 53 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ LOG_MODULE_REGISTER(spi_numaker, CONFIG_SPI_LOG_LEVEL);
2121
#include <NuMicro.h>
2222

2323
#define SPI_NUMAKER_TX_NOP 0x00
24+
#define SPI_NUMAKER_CTL_MSK (SPI_CTL_DWIDTH_Msk | SPI_CTL_SLAVE_Msk | \
25+
SPI_CTL_CLKPOL_Msk | SPI_CTL_RXNEG_Msk | \
26+
SPI_CTL_TXNEG_Msk)
2427

2528
struct spi_numaker_config {
2629
SPI_T *spi;
@@ -91,6 +94,8 @@ static int spi_numaker_configure(const struct device *dev, const struct spi_conf
9194
qsmode_tbl[mode],
9295
SPI_WORD_SIZE_GET(config->operation), config->frequency);
9396
} else {
97+
/* Clear SPI CTL before set */
98+
dev_cfg->spi->CTL &= ~SPI_NUMAKER_CTL_MSK;
9499
SPI_Open(dev_cfg->spi,
95100
(SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) ? SPI_SLAVE
96101
: SPI_MASTER,
@@ -137,80 +142,58 @@ static int spi_numaker_configure(const struct device *dev, const struct spi_conf
137142
return 0;
138143
}
139144

140-
static int spi_numaker_txrx(const struct device *dev)
145+
static int spi_numaker_txrx(const struct device *dev, uint8_t spi_dfs)
141146
{
142147
struct spi_numaker_data *data = dev->data;
143148
const struct spi_numaker_config *dev_cfg = dev->config;
144149
struct spi_context *ctx = &data->ctx;
145150
uint32_t tx_frame, rx_frame;
146-
uint8_t word_size, spi_dfs;
147151
uint32_t time_out_cnt;
148152

149153
LOG_DBG("%s", __func__);
150-
word_size = SPI_WORD_SIZE_GET(ctx->config->operation);
151-
152-
switch (word_size) {
153-
case 8:
154-
spi_dfs = 1;
155-
break;
156-
case 16:
157-
spi_dfs = 2;
158-
break;
159-
case 24:
160-
spi_dfs = 3;
161-
break;
162-
case 32:
163-
spi_dfs = 4;
164-
break;
165-
default:
166-
spi_dfs = 0;
167-
LOG_ERR("Not support SPI WORD size as [%d] bits", word_size);
168-
return -EIO;
169-
}
170-
171-
LOG_DBG("%s -->word_size [%d]", __func__, word_size);
172154

173155
if (spi_context_tx_on(ctx)) {
174156
tx_frame = ((ctx->tx_buf == NULL) ? SPI_NUMAKER_TX_NOP
175-
: UNALIGNED_GET((uint8_t *)(data->ctx.tx_buf)));
157+
: UNALIGNED_GET((uint32_t *)data->ctx.tx_buf));
176158
/* Write to TX register */
177159
SPI_WRITE_TX(dev_cfg->spi, tx_frame);
178160
spi_context_update_tx(ctx, spi_dfs, 1);
179-
180-
/* Check SPI busy status */
181-
time_out_cnt = SystemCoreClock; /* 1 second time-out */
182-
while (SPI_IS_BUSY(dev_cfg->spi)) {
183-
if (--time_out_cnt == 0) {
184-
LOG_ERR("Wait for SPI time-out");
185-
return -EIO;
186-
}
187-
}
188-
189161
LOG_DBG("%s --> TX [0x%x] done", __func__, tx_frame);
190162
} else {
191163
/* Write dummy data to TX register */
192164
SPI_WRITE_TX(dev_cfg->spi, 0x00U);
193-
time_out_cnt = SystemCoreClock; /* 1 second time-out */
194-
while (SPI_IS_BUSY(dev_cfg->spi)) {
195-
if (--time_out_cnt == 0) {
196-
LOG_ERR("Wait for SPI time-out");
197-
return -EIO;
198-
}
199-
}
200165
}
201166

202167
/* Read received data */
203168
if (spi_context_rx_on(ctx)) {
204169
if (SPI_GET_RX_FIFO_COUNT(dev_cfg->spi) > 0) {
205170
rx_frame = SPI_READ_RX(dev_cfg->spi);
206171
if (ctx->rx_buf != NULL) {
207-
UNALIGNED_PUT(rx_frame, (uint8_t *)data->ctx.rx_buf);
172+
if (spi_dfs > 2) {
173+
UNALIGNED_PUT(rx_frame,
174+
(uint32_t *)data->ctx.rx_buf);
175+
} else if (spi_dfs > 1) {
176+
UNALIGNED_PUT(rx_frame,
177+
(uint16_t *)data->ctx.rx_buf);
178+
} else {
179+
UNALIGNED_PUT(rx_frame,
180+
(uint8_t *)data->ctx.rx_buf);
181+
}
208182
}
209183
spi_context_update_rx(ctx, spi_dfs, 1);
210184
LOG_DBG("%s --> RX [0x%x] done", __func__, rx_frame);
211185
}
212186
}
213187

188+
/* Check SPI busy status */
189+
time_out_cnt = SystemCoreClock; /* 1 second time-out */
190+
while (SPI_IS_BUSY(dev_cfg->spi)) {
191+
if (--time_out_cnt == 0) {
192+
LOG_ERR("Wait for SPI time-out");
193+
return -EIO;
194+
}
195+
}
196+
214197
LOG_DBG("%s --> exit", __func__);
215198
return 0;
216199
}
@@ -229,19 +212,43 @@ static int spi_numaker_transceive(const struct device *dev, const struct spi_con
229212
struct spi_context *ctx = &data->ctx;
230213
const struct spi_numaker_config *dev_cfg = dev->config;
231214
int ret;
215+
uint8_t word_size, spi_dfs;
232216

233217
LOG_DBG("%s", __func__);
234218
spi_context_lock(ctx, false, NULL, NULL, config);
235-
ctx->config = config;
236219

237220
ret = spi_numaker_configure(dev, config);
238221
if (ret < 0) {
239222
goto done;
240223
}
241224

225+
word_size = SPI_WORD_SIZE_GET(ctx->config->operation);
226+
227+
switch (word_size) {
228+
case 8:
229+
spi_dfs = 1;
230+
break;
231+
case 16:
232+
spi_dfs = 2;
233+
break;
234+
case 24:
235+
spi_dfs = 3;
236+
break;
237+
case 32:
238+
spi_dfs = 4;
239+
break;
240+
default:
241+
spi_dfs = 0;
242+
LOG_ERR("Not support SPI WORD size as [%d] bits", word_size);
243+
ret = -ENOTSUP;
244+
goto done;
245+
}
246+
247+
LOG_DBG("%s -->word_size [%d]", __func__, word_size);
248+
242249
SPI_ENABLE(dev_cfg->spi);
243250

244-
spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1);
251+
spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, spi_dfs);
245252

246253
/* if cs is defined: software cs control, set active true */
247254
if (spi_cs_is_gpio(config)) {
@@ -250,7 +257,7 @@ static int spi_numaker_transceive(const struct device *dev, const struct spi_con
250257

251258
/* transceive tx/rx data */
252259
do {
253-
ret = spi_numaker_txrx(dev);
260+
ret = spi_numaker_txrx(dev, spi_dfs);
254261
if (ret < 0) {
255262
break;
256263
}

0 commit comments

Comments
 (0)