forked from zephyrproject-rtos/ArduinoCore-zephyr
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSPI.cpp
More file actions
145 lines (120 loc) · 3.65 KB
/
SPI.cpp
File metadata and controls
145 lines (120 loc) · 3.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
* Copyright (c) 2024 Ayush Singh <ayush@beagleboard.org>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "SPI.h"
#include "zephyrInternal.h"
#include <zephyr/kernel.h>
arduino::ZephyrSPI::ZephyrSPI(const struct device *spi) : spi_dev(spi) {
}
uint8_t arduino::ZephyrSPI::transfer(uint8_t data) {
uint8_t rx = data;
if (transfer(&rx, sizeof(rx), &config) < 0) {
return 0;
}
return rx;
}
uint16_t arduino::ZephyrSPI::transfer16(uint16_t data) {
uint16_t rx = data;
if (transfer(&rx, sizeof(rx), &config16) < 0) {
return 0;
}
return rx;
}
void arduino::ZephyrSPI::transfer(void *buf, size_t count) {
int ret = transfer(buf, count, &config);
(void)ret;
}
int arduino::ZephyrSPI::transfer(void *buf, size_t len, const struct spi_config *config) {
int ret;
const struct spi_buf tx_buf = {.buf = buf, .len = len};
const struct spi_buf_set tx_buf_set = {
.buffers = &tx_buf,
.count = 1,
};
const struct spi_buf rx_buf = {.buf = buf, .len = len};
const struct spi_buf_set rx_buf_set = {
.buffers = &rx_buf,
.count = 1,
};
return spi_transceive(spi_dev, config, &tx_buf_set, &rx_buf_set);
}
void arduino::ZephyrSPI::usingInterrupt(int interruptNumber) {
}
void arduino::ZephyrSPI::notUsingInterrupt(int interruptNumber) {
}
void arduino::ZephyrSPI::beginTransaction(SPISettings settings) {
uint32_t mode = SPI_HOLD_ON_CS;
// Set bus mode
switch (settings.getBusMode()) {
case SPI_CONTROLLER:
break;
case SPI_PERIPHERAL:
mode |= SPI_OP_MODE_SLAVE;
break;
}
// Set data format
switch (settings.getBitOrder()) {
case LSBFIRST:
mode |= SPI_TRANSFER_LSB;
break;
case MSBFIRST:
mode |= SPI_TRANSFER_MSB;
break;
}
// Set data mode
switch (settings.getDataMode()) {
case SPI_MODE0:
break;
case SPI_MODE1:
mode |= SPI_MODE_CPHA;
break;
case SPI_MODE2:
mode |= SPI_MODE_CPOL;
break;
case SPI_MODE3:
mode |= SPI_MODE_CPOL | SPI_MODE_CPHA;
break;
}
// Set SPI configuration structure for 8-bit transfers
memset(&config, 0, sizeof(struct spi_config));
config.operation = mode | SPI_WORD_SET(8);
config.frequency = max(SPI_MIN_CLOCK_FREQUENCY, settings.getClockFreq());
// Set SPI configuration structure for 16-bit transfers
memset(&config16, 0, sizeof(struct spi_config));
config16.operation = mode | SPI_WORD_SET(16);
config16.frequency = max(SPI_MIN_CLOCK_FREQUENCY, settings.getClockFreq());
}
void arduino::ZephyrSPI::endTransaction(void) {
spi_release(spi_dev, &config);
}
void arduino::ZephyrSPI::attachInterrupt() {
}
void arduino::ZephyrSPI::detachInterrupt() {
}
void arduino::ZephyrSPI::begin() {
}
void arduino::ZephyrSPI::end() {
}
#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), spis)
#if (DT_PROP_LEN(DT_PATH(zephyr_user), spis) > 1)
#define ARDUINO_SPI_DEFINED_0 1
#define DECL_SPI_0(n, p, i) arduino::ZephyrSPI SPI(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(n, p, i)));
#define DECL_SPI_N(n, p, i) arduino::ZephyrSPI SPI##i(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(n, p, i)));
#define DECLARE_SPI_N(n, p, i) \
COND_CODE_1(ARDUINO_SPI_DEFINED_##i, (DECL_SPI_0(n, p, i)), (DECL_SPI_N(n, p, i)))
/* Declare SPI, SPI1, SPI2, ... */
DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), spis, DECLARE_SPI_N)
#undef DECLARE_SPI_N
#undef DECL_SPI_N
#undef DECL_SPI_0
#undef ARDUINO_SPI_DEFINED_0
#else // PROP_LEN(spis) > 1
/* When PROP_LEN(spis) == 1, DT_FOREACH_PROP_ELEM work not correctly. */
arduino::ZephyrSPI SPI(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), spis, 0)));
#endif // HAS_PORP(spis)
/* If spis node is not defined, tries to use arduino_spi */
#elif DT_NODE_EXISTS(DT_NODELABEL(arduino_spi))
arduino::ZephyrSPI SPI(DEVICE_DT_GET(DT_NODELABEL(arduino_spi)));
#endif