1515 */
1616// ----------------------------------------------------------------------------
1717
18- #ifndef MODM_STM32_SPI_MASTER{{ id }}_HPP
19- #define MODM_STM32_SPI_MASTER{{ id }}_HPP
18+ #pragma once
2019
2120#include <modm/architecture/interface/spi_master.hpp>
2221#include <modm/platform/gpio/connector.hpp>
2322#include <modm/math/algorithm/prescaler.hpp>
23+ #include <modm/math/utils/binary.hpp>
2424#include "spi_hal_{{ id }}.hpp"
2525
2626namespace modm
@@ -39,12 +39,27 @@ namespace platform
3939 */
4040class SpiMaster{{ id }} : public modm::SpiMaster
4141{
42- static SpiBase::State_t state;
43- static std::size_t index;
44-
4542 static uint8_t count;
4643 static void *context;
4744 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;
4863public:
4964 using Hal = SpiHal{{ id }};
5065
@@ -102,18 +117,19 @@ public:
102117 state = SpiBase::State(0);
103118 }
104119
105- static modm_always_inline void
120+ static void
106121 setDataMode(DataMode mode)
107122 {
108123 SpiHal{{ id }}::setDataMode(static_cast<SpiHal{{ id }}::DataMode>(mode));
109124 }
110125
111- static modm_always_inline void
126+ static void
112127 setDataOrder(DataOrder order)
113128 {
114129 SpiHal{{ id }}::setDataOrder(static_cast<SpiHal{{ id }}::DataOrder>(order));
115130 }
116- static modm_always_inline void
131+
132+ static void
117133 setDataSize(DataSize size)
118134 {
119135 SpiHal{{ id }}::setDataSize(static_cast<SpiHal{{ id }}::DataSize>(size));
@@ -126,86 +142,153 @@ public:
126142 static uint8_t
127143 release(void *ctx);
128144
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);
129160
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 --------------------------------------------------------
130208 static uint8_t
131209 transferBlocking(const uint8_t data)
132- {
133- return RF_CALL_BLOCKING(transmit<uint8_t>(data));
134- }
210+ { return RF_CALL_BLOCKING(transmit(data)); }
135211
136212 static uint16_t
137213 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)); }
141219
142220 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)); }
147223
148224 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)); }
153231
154232 static void
155233 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)); }
159235
160236 static void
161237 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)); }
165243
166244 static modm::ResumableResult<uint8_t>
167245 transfer(const uint8_t data) {
168- return transmit<uint8_t> (data);
246+ return transmit(data);
169247 }
170248
171249 static modm::ResumableResult<uint16_t>
172250 transfer16(const uint16_t data) {
173- return transmit<uint16_t> (data);
251+ return transmit(data);
174252 }
175253
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 );
179257 }
180258
181259 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);
184262 }
185263
186264 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 );
189267 }
190268
191269 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 );
194272 }
195273
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+ }
200278
201- template <std::unsigned_integral T>
202279 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+ }
204283
205- template <std::unsigned_integral T>
206284 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+ }
208288 // end documentation inherited
289+
290+ // TODO friend with MODM_ISR(SPI_STC) possible?
291+ static void isr_handler();
209292};
210293
211294} // namespace platform
0 commit comments