Skip to content

Commit d403c4c

Browse files
committed
libraries/SPI: Add support for peripheral mode
Signed-off-by: iabdalkader <[email protected]>
1 parent c1fea19 commit d403c4c

File tree

2 files changed

+53
-56
lines changed

2 files changed

+53
-56
lines changed

libraries/SPI/SPI.cpp

Lines changed: 44 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -12,66 +12,42 @@ arduino::ZephyrSPI::ZephyrSPI(const struct device *spi) : spi_dev(spi) {
1212
}
1313

1414
uint8_t arduino::ZephyrSPI::transfer(uint8_t data) {
15-
int ret;
16-
uint8_t rx;
17-
const struct spi_buf tx_buf = {.buf = &data, .len = sizeof(data)};
18-
const struct spi_buf_set tx_buf_set = {
19-
.buffers = &tx_buf,
20-
.count = 1,
21-
};
22-
const struct spi_buf rx_buf = {.buf = &rx, .len = sizeof(rx)};
23-
const struct spi_buf_set rx_buf_set = {
24-
.buffers = &rx_buf,
25-
.count = 1,
26-
};
27-
28-
ret = spi_transceive(spi_dev, &config, &tx_buf_set, &rx_buf_set);
29-
if (ret < 0) {
15+
uint8_t rx = data;
16+
if (transfer(&rx, sizeof(rx), &config) < 0) {
3017
return 0;
3118
}
32-
3319
return rx;
3420
}
3521

3622
uint16_t arduino::ZephyrSPI::transfer16(uint16_t data) {
37-
int ret;
38-
uint16_t rx;
39-
const struct spi_buf tx_buf = {.buf = &data, .len = sizeof(data)};
40-
const struct spi_buf_set tx_buf_set = {
41-
.buffers = &tx_buf,
42-
.count = 1,
43-
};
44-
const struct spi_buf rx_buf = {.buf = &rx, .len = sizeof(rx)};
45-
const struct spi_buf_set rx_buf_set = {
46-
.buffers = &rx_buf,
47-
.count = 1,
48-
};
49-
50-
ret = spi_transceive(spi_dev, &config16, &tx_buf_set, &rx_buf_set);
51-
if (ret < 0) {
23+
uint16_t rx = data;
24+
if (transfer(&rx, sizeof(rx), &config16) < 0) {
5225
return 0;
5326
}
54-
5527
return rx;
5628
}
5729

5830
void arduino::ZephyrSPI::transfer(void *buf, size_t count) {
31+
int ret = transfer(buf, count, &config);
32+
(void)ret;
33+
}
34+
35+
int arduino::ZephyrSPI::transfer(void *buf, size_t len, const struct spi_config *config) {
5936
int ret;
60-
const struct spi_buf tx_buf = {.buf = buf, .len = count};
37+
38+
const struct spi_buf tx_buf = {.buf = buf, .len = len};
6139
const struct spi_buf_set tx_buf_set = {
6240
.buffers = &tx_buf,
6341
.count = 1,
6442
};
6543

66-
uint8_t rx[count];
67-
const struct spi_buf rx_buf = {.buf = &rx, .len = count};
44+
const struct spi_buf rx_buf = {.buf = buf, .len = len};
6845
const struct spi_buf_set rx_buf_set = {
6946
.buffers = &rx_buf,
7047
.count = 1,
7148
};
7249

73-
spi_transceive(spi_dev, &config, &tx_buf_set, &rx_buf_set);
74-
memcpy(buf, rx, count);
50+
return spi_transceive(spi_dev, config, &tx_buf_set, &rx_buf_set);
7551
}
7652

7753
void arduino::ZephyrSPI::usingInterrupt(int interruptNumber) {
@@ -80,21 +56,31 @@ void arduino::ZephyrSPI::usingInterrupt(int interruptNumber) {
8056
void arduino::ZephyrSPI::notUsingInterrupt(int interruptNumber) {
8157
}
8258

83-
#ifndef SPI_MIN_CLOCK_FEQUENCY
84-
#define SPI_MIN_CLOCK_FEQUENCY 1000000
85-
#endif
86-
8759
void arduino::ZephyrSPI::beginTransaction(SPISettings settings) {
88-
memset(&config, 0, sizeof(config));
89-
memset(&config16, 0, sizeof(config16));
90-
config.frequency = settings.getClockFreq() > SPI_MIN_CLOCK_FEQUENCY ? settings.getClockFreq() :
91-
SPI_MIN_CLOCK_FEQUENCY;
92-
config16.frequency = config.frequency;
60+
uint32_t mode = 0;
61+
62+
// Set bus mode
63+
switch (settings.getBusMode()) {
64+
case SPI_CONTROLLER:
65+
break;
66+
case SPI_PERIPHERAL:
67+
mode |= SPI_OP_MODE_SLAVE;
68+
break;
69+
}
9370

94-
auto mode = SPI_MODE_CPOL | SPI_MODE_CPHA;
71+
// Set data format
72+
switch (settings.getBitOrder()) {
73+
case LSBFIRST:
74+
mode |= SPI_TRANSFER_LSB;
75+
break;
76+
case MSBFIRST:
77+
mode |= SPI_TRANSFER_MSB;
78+
break;
79+
}
80+
81+
// Set data mode
9582
switch (settings.getDataMode()) {
9683
case SPI_MODE0:
97-
mode = 0;
9884
break;
9985
case SPI_MODE1:
10086
mode = SPI_MODE_CPHA;
@@ -106,12 +92,16 @@ void arduino::ZephyrSPI::beginTransaction(SPISettings settings) {
10692
mode = SPI_MODE_CPOL | SPI_MODE_CPHA;
10793
break;
10894
}
109-
config.operation = SPI_WORD_SET(8) |
110-
(settings.getBitOrder() == MSBFIRST ? SPI_TRANSFER_MSB : SPI_TRANSFER_LSB) |
111-
mode;
112-
config16.operation =
113-
SPI_WORD_SET(16) |
114-
(settings.getBitOrder() == MSBFIRST ? SPI_TRANSFER_MSB : SPI_TRANSFER_LSB) | mode;
95+
96+
// Set SPI configuration structure for 8-bit transfers
97+
memset(&config, 0, sizeof(struct spi_config));
98+
config.operation = mode | SPI_WORD_SET(8);
99+
config.frequency = max(SPI_MIN_CLOCK_FEQUENCY, settings.getClockFreq());
100+
101+
// Set SPI configuration structure for 16-bit transfers
102+
memset(&config16, 0, sizeof(struct spi_config));
103+
config16.operation = mode | SPI_WORD_SET(16);
104+
config16.frequency = max(SPI_MIN_CLOCK_FEQUENCY, settings.getClockFreq());
115105
}
116106

117107
void arduino::ZephyrSPI::endTransaction(void) {
@@ -125,8 +115,6 @@ void arduino::ZephyrSPI::detachInterrupt() {
125115
}
126116

127117
void arduino::ZephyrSPI::begin() {
128-
beginTransaction(SPISettings());
129-
endTransaction();
130118
}
131119

132120
void arduino::ZephyrSPI::end() {

libraries/SPI/SPI.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@
2222
#define SPE 6
2323
#define SPIE 7
2424

25+
// TODO:
26+
// This depends on the clock settings, can't be used for all boards.
27+
#ifndef SPI_MIN_CLOCK_FEQUENCY
28+
#define SPI_MIN_CLOCK_FEQUENCY 1000000
29+
#endif
30+
2531
/* Count the number of GPIOs for limit of number of interrupts */
2632
#define INTERRUPT_HELPER(n, p, i) 1
2733
#define INTERRUPT_COUNT \
@@ -50,6 +56,9 @@ class ZephyrSPI : public HardwareSPI {
5056
virtual void begin();
5157
virtual void end();
5258

59+
private:
60+
int transfer(void *buf, size_t len, const struct spi_config *config);
61+
5362
protected:
5463
const struct device *spi_dev;
5564
struct spi_config config;

0 commit comments

Comments
 (0)