15
15
*/
16
16
// ----------------------------------------------------------------------------
17
17
18
- #ifndef MODM_STM32_SPI_MASTER{{ id }}_HPP
19
- #define MODM_STM32_SPI_MASTER{{ id }}_HPP
18
+ #pragma once
20
19
21
20
#include <modm/architecture/interface/spi_master.hpp>
22
21
#include <modm/platform/gpio/connector.hpp>
23
22
#include <modm/math/algorithm/prescaler.hpp>
23
+ #include <modm/math/utils/binary.hpp>
24
24
#include "spi_hal_{{ id }}.hpp"
25
25
26
26
namespace modm
@@ -39,12 +39,27 @@ namespace platform
39
39
*/
40
40
class SpiMaster{{ id }} : public modm::SpiMaster
41
41
{
42
- static SpiBase::State_t state;
43
- static std::size_t index;
44
-
45
42
static uint8_t count;
46
43
static void *context;
47
44
static ConfigurationHandler configuration;
45
+
46
+ static Spi::State_t state;
47
+ static uint8_t shift;
48
+ static uint32_t temp;
49
+
50
+ union unsigned_types_const {
51
+ uint8_t const *u8;
52
+ uint16_t const *u16;
53
+ uint32_t const *u32;
54
+ uint16_t repeat;
55
+ };
56
+ static unsigned_types_const tx, tx_end;
57
+ union unsigned_types {
58
+ uint8_t *u8;
59
+ uint16_t *u16;
60
+ uint32_t *u32;
61
+ };
62
+ static unsigned_types rx, rx_end;
48
63
public:
49
64
using Hal = SpiHal{{ id }};
50
65
@@ -102,18 +117,19 @@ public:
102
117
state = SpiBase::State(0);
103
118
}
104
119
105
- static modm_always_inline void
120
+ static void
106
121
setDataMode(DataMode mode)
107
122
{
108
123
SpiHal{{ id }}::setDataMode(static_cast<SpiHal{{ id }}::DataMode>(mode));
109
124
}
110
125
111
- static modm_always_inline void
126
+ static void
112
127
setDataOrder(DataOrder order)
113
128
{
114
129
SpiHal{{ id }}::setDataOrder(static_cast<SpiHal{{ id }}::DataOrder>(order));
115
130
}
116
- static modm_always_inline void
131
+
132
+ static void
117
133
setDataSize(DataSize size)
118
134
{
119
135
SpiHal{{ id }}::setDataSize(static_cast<SpiHal{{ id }}::DataSize>(size));
@@ -126,86 +142,153 @@ public:
126
142
static uint8_t
127
143
release(void *ctx);
128
144
145
+ // TODO Complete the docs
146
+
147
+ /**
148
+ * @brief
149
+ *
150
+ * @param data
151
+ * @return modm::ResumableResult<T>
152
+ */
153
+ template <modm::unsigned_integral_max32 T>
154
+ static modm::ResumableResult<T>
155
+ transmit(const T data);
156
+
157
+ // OPTIMIZE specialize sole transmit(byte / halfword) without ISR overhead
158
+ // static modm::ResumableResult<uint8_t>
159
+ // transmit(const uint8_t data);
129
160
161
+ // static modm::ResumableResult<uint16_t>
162
+ // transmit(const uint16_t data);
163
+
164
+ /**
165
+ * @brief
166
+ *
167
+ * @param data
168
+ * @return modm::ResumableResult<T>
169
+ */
170
+ template <modm::unsigned_integral_max32 T>
171
+ static modm::ResumableResult<void>
172
+ transmit(const T data, std::size_t repeat);
173
+
174
+ /**
175
+ * @brief Send and optional receive data in range begin()->end().
176
+ * Works with C-array or std::array for tx / rx
177
+ *
178
+ * @param tx_first Pointer to first element to send. f.e. tx.begin() OR tx.begin() + 1
179
+ * @param tx_first Pointer to one after last element to send: f.e. tx.end() OR tx.end() - 4
180
+ * @param rx_first Pointer to first element to receive: f.e. rx_data.begin() OR rx_data.begin() + 1
181
+ */
182
+ template <modm::unsigned_integral_max32 T>
183
+ static modm::ResumableResult<void>
184
+ transmit(const T *tx_first, const T *tx_last, T *rx_first = nullptr);
185
+
186
+ /**
187
+ * @brief Send a std::array
188
+ *
189
+ * @param tx_array std::array with data to send
190
+ */
191
+ template <std::ranges::forward_range C>
192
+ static modm::ResumableResult<void>
193
+ transmit(const C &tx_arr)
194
+ { return transmit(tx_arr.begin(), tx_arr.end()); };
195
+
196
+ /**
197
+ * @brief Transmit and receive an std::array
198
+ *
199
+ * @param tx_arr std::array with data to send
200
+ * @param rx_arr std::array for received data
201
+ */
202
+ template <std::ranges::forward_range C>
203
+ static modm::ResumableResult<void>
204
+ transmit(const C &tx_arr, C &rx_arr)
205
+ { return transmit(tx_arr.begin(), tx_arr.end(), rx_arr.begin()); };
206
+
207
+ // -- Backwards compatible API --------------------------------------------------------
130
208
static uint8_t
131
209
transferBlocking(const uint8_t data)
132
- {
133
- return RF_CALL_BLOCKING(transmit<uint8_t>(data));
134
- }
210
+ { return RF_CALL_BLOCKING(transmit(data)); }
135
211
136
212
static uint16_t
137
213
transferBlocking16(const uint16_t data)
138
- {
139
- return RF_CALL_BLOCKING(transmit<uint16_t>(data));
140
- }
214
+ { return RF_CALL_BLOCKING(transmit(data)); }
215
+
216
+ static uint32_t
217
+ transferBlocking32(const uint32_t data)
218
+ { return RF_CALL_BLOCKING(transmit(data)); }
141
219
142
220
static void
143
- transferBlocking(const uint8_t *tx, std::size_t repeat)
144
- {
145
- RF_CALL_BLOCKING(transmit<uint8_t>(tx, repeat));
146
- }
221
+ transferBlocking(const uint8_t data, std::size_t repeat)
222
+ { RF_CALL_BLOCKING(transmit(data, repeat)); }
147
223
148
224
static void
149
- transferBlocking16(const uint16_t *tx, std::size_t repeat)
150
- {
151
- RF_CALL_BLOCKING(transmit<uint16_t>(tx, repeat));
152
- }
225
+ transferBlocking16(const uint16_t data, std::size_t repeat)
226
+ { RF_CALL_BLOCKING(transmit(data, repeat)); }
227
+
228
+ static void
229
+ transferBlocking32(const uint32_t data, std::size_t repeat)
230
+ { RF_CALL_BLOCKING(transmit(data, repeat)); }
153
231
154
232
static void
155
233
transferBlocking(const uint8_t *tx, uint8_t *rx, std::size_t length)
156
- {
157
- RF_CALL_BLOCKING(transmit<uint8_t>(tx, rx, length));
158
- }
234
+ { RF_CALL_BLOCKING(transmit(tx, tx + length, rx)); }
159
235
160
236
static void
161
237
transferBlocking16(const uint16_t *tx, uint16_t *rx, std::size_t length)
162
- {
163
- RF_CALL_BLOCKING(transmit<uint16_t>(tx, rx, length));
164
- }
238
+ { RF_CALL_BLOCKING(transmit(tx, tx + length, rx)); }
239
+
240
+ static void
241
+ transferBlocking32(const uint32_t *tx, uint32_t *rx, std::size_t length)
242
+ { RF_CALL_BLOCKING(transmit(tx, tx + length, rx)); }
165
243
166
244
static modm::ResumableResult<uint8_t>
167
245
transfer(const uint8_t data) {
168
- return transmit<uint8_t> (data);
246
+ return transmit(data);
169
247
}
170
248
171
249
static modm::ResumableResult<uint16_t>
172
250
transfer16(const uint16_t data) {
173
- return transmit<uint16_t> (data);
251
+ return transmit(data);
174
252
}
175
253
176
- static modm::ResumableResult<void >
177
- transfer (const uint8_t *tx, const std::size_t repeat ) {
178
- return transmit<uint8_t>(tx, repeat );
254
+ static modm::ResumableResult<uint32_t >
255
+ transfer32 (const uint32_t data ) {
256
+ return transmit(data );
179
257
}
180
258
181
259
static modm::ResumableResult<void>
182
- transfer16 (const uint16_t * tx, const std::size_t repeat) {
183
- return transmit<uint16_t> (tx, repeat);
260
+ transfer (const uint8_t tx, const std::size_t repeat) {
261
+ return transmit(tx, repeat);
184
262
}
185
263
186
264
static modm::ResumableResult<void>
187
- transfer (const uint8_t * tx, uint8_t *rx, const std::size_t length ) {
188
- return transmit<uint8_t> (tx, rx, length );
265
+ transfer16 (const uint16_t tx, const std::size_t repeat ) {
266
+ return transmit(tx, repeat );
189
267
}
190
268
191
269
static modm::ResumableResult<void>
192
- transfer16 (const uint16_t * tx, uint16_t *rx, const std::size_t length ) {
193
- return transmit<uint16_t> (tx, rx, length );
270
+ transfer32 (const uint32_t tx, const std::size_t repeat ) {
271
+ return transmit(tx, repeat );
194
272
}
195
273
196
- // TODO "transmit" == good?
197
- template < std::unsigned_integral T>
198
- static modm::ResumableResult<T>
199
- transmit(const T data);
274
+ static modm::ResumableResult<void>
275
+ transfer(const uint8_t *tx, uint8_t *rx, const std::size_t length) {
276
+ return transmit(tx, tx + length, rx);
277
+ }
200
278
201
- template <std::unsigned_integral T>
202
279
static modm::ResumableResult<void>
203
- transmit(const T *tx, const std::size_t repeat);
280
+ transfer16(const uint16_t *tx, uint16_t *rx, const std::size_t length) {
281
+ return transmit(tx, tx + length, rx);
282
+ }
204
283
205
- template <std::unsigned_integral T>
206
284
static modm::ResumableResult<void>
207
- transmit(const T *tx, T *rx, const std::size_t length);
285
+ transfer32(const uint32_t *tx, uint32_t *rx, const std::size_t length) {
286
+ return transmit(tx, tx + length, rx);
287
+ }
208
288
// end documentation inherited
289
+
290
+ // TODO friend with MODM_ISR(SPI_STC) possible?
291
+ static void isr_handler();
209
292
};
210
293
211
294
} // namespace platform
0 commit comments