CHGame 0.3.0
Libraries for the CHGame handheld
Loading...
Searching...
No Matches
SPI.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010 by Cristian Maglie <c.maglie@arduino.cc>
3 * Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
4 * SPI Master library for arduino.
5 *
6 * This file is free software; you can redistribute it and/or modify
7 * it under the terms of either the GNU General Public License version 2
8 * or the GNU Lesser General Public License version 2.1, both as
9 * published by the Free Software Foundation.
10 *
11 * Modified 30 jurn 2023 by TempersLee to surpport wch's MCU
12 */
13
14/**
15 * @file
16 * @brief Arduino's SPI library (SPIClass, SPISettings), ported to WCH's
17 * chips: SPI master on the CH32X035's SPI1.
18 */
19
20/**
21 * @defgroup core_spi SPI
22 * @ingroup lib_core
23 * @brief The Arduino SPI API: SPI master on SPI1, the CH32X035's one SPI.
24 *
25 * @code
26 * #include <SPI.h>
27 *
28 * SPI.begin();
29 * SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
30 * digitalWrite(myCs, LOW);
31 * uint8_t answer = SPI.transfer(0x9F);
32 * digitalWrite(myCs, HIGH);
33 * SPI.endTransaction();
34 * @endcode
35 *
36 * The global @ref SPI is SPI1 on the board's PA5 (SCK), PA6 (MISO) and
37 * PA7 (MOSI), the only pins SPI1 has on this chip. Transfers are polled
38 * byte by byte (no DMA, no interrupts), and each call gives up after
39 * @ref SPI_TRANSFER_TIMEOUT ms. The clock is 48 MHz divided by 2, 4 ...
40 * 256: a requested clock gets the fastest of those that does not exceed
41 * it (24 MHz down to 187.5 kHz), so the default 4 MHz request runs at
42 * 3 MHz.
43 *
44 * Settings are remembered per chip-select pin, for up to
45 * @ref NB_SPI_SETTINGS pins. A transfer for a pin that has none (never given
46 * to begin() or beginTransaction(), or forgotten by endTransaction()) does
47 * nothing and returns 0.
48 *
49 * @note On the CHGame board SPI1 is shared by the LCD (CS `PIN_LCD_CS`,
50 * PA4, which is also the default `SS`) and the SD card (CS `PIN_SD_CS`,
51 * PB11), and CHGfx drives it directly by DMA. Use this class only for a
52 * device of your own on SPI1, only between `gfx_wait()` and the next flush,
53 * and keep the panel's and the card's CS high. For the card, use
54 * @ref lib_chsd "CHSd".
55 *
56 * @warning begin(), beginTransaction() and a transfer for another CS pin
57 * reset SPI1 and program it afresh (clock, mode, bit order), and end()
58 * switches SPI1's clock off. CHGfx sets SPI1 up only in `gfx_begin()` and
59 * `gfx_setSpiDiv()`, so hand it back before the next flush with
60 * `gfx_setSpiDiv(gfx_spiDiv())`, which programs all of SPI1 for the panel
61 * again (and switches its clock back on).
62 * @{
63 */
64
65#ifndef _SPI_H_INCLUDED
66#define _SPI_H_INCLUDED
67
68#include "Arduino.h"
69#include <stdio.h>
70extern "C" {
71#include "utility/spi_com.h"
72}
73
74
75/**
76 * @brief Defined to 1: this SPI has beginTransaction(), endTransaction(),
77 * usingInterrupt() and SPISettings(clock, bitOrder, dataMode).
78 */
79#define SPI_HAS_TRANSACTION 1
80
81/**
82 * @name Clock dividers for setClockDivider() (deprecated)
83 * Compatibility with sketches designed for AVR at 16 MHz cannot be ensured,
84 * as the SPI clock depends on the system clock: here the divider applies to
85 * 48 MHz, and the result is then rounded down to 48 MHz / 2^n. New code
86 * passes the clock in Hz to SPISettings with SPI.beginTransaction() instead.
87 * @{
88 */
89#define SPI_CLOCK_DIV2 2 /**< 48 MHz / 2 = 24 MHz */
90#define SPI_CLOCK_DIV4 4 /**< 48 MHz / 4 = 12 MHz */
91#define SPI_CLOCK_DIV8 8 /**< 48 MHz / 8 = 6 MHz */
92#define SPI_CLOCK_DIV16 16 /**< 48 MHz / 16 = 3 MHz */
93#define SPI_CLOCK_DIV32 32 /**< 48 MHz / 32 = 1.5 MHz */
94#define SPI_CLOCK_DIV64 64 /**< 48 MHz / 64 = 750 kHz */
95#define SPI_CLOCK_DIV128 128 /**< 48 MHz / 128 = 375 kHz */
96/** @} */
97
98/**
99 * @name SPI modes, for SPISettings and setDataMode()
100 * @{
101 */
102#define SPI_MODE0 0x00 /**< clock idles low, data sampled on the rising edge (CPOL 0, CPHA 0) */
103#define SPI_MODE1 0x01 /**< clock idles low, data sampled on the falling edge (CPOL 0, CPHA 1) */
104#define SPI_MODE2 0x02 /**< clock idles high, data sampled on the falling edge (CPOL 1, CPHA 0) */
105#define SPI_MODE3 0x03 /**< clock idles high, data sampled on the rising edge (CPOL 1, CPHA 1) */
106/** @} */
107
108/**
109 * @name Receive or not, for SPISettings' noRecv
110 * @{
111 */
112#define SPI_TRANSMITRECEIVE 0x0 /**< send and receive (the default) */
113#define SPI_TRANSMITONLY 0x1 /**< send only: what comes back is not read, and transfer() returns 0 */
114/** @} */
115
116/** @brief What a transfer does with a CS pin the class drives, once it is done. */
118 SPI_CONTINUE, /**< Transfer not finished: CS pin kept active (low) */
119 SPI_LAST /**< Transfer ended: CS pin released (high) */
121
122/**
123 * @brief The "CS pin" that means the sketch drives its chip select itself,
124 * outside the SPI class (the default for every method).
125 */
126#define CS_PIN_CONTROLLED_BY_USER NUM_DIGITAL_PINS
127
128/** @brief Indicates there is no configuration selected (internal). */
129#define NO_CONFIG ((int16_t)(-1))
130
131/**
132 * @brief How long one transfer call may take before it gives up, in ms
133 * (default 1000). SPI.cpp uses it, so a different value must be defined
134 * for the whole build (`build.extra_flags`), not just in the sketch.
135 */
136#ifndef SPI_TRANSFER_TIMEOUT
137 #define SPI_TRANSFER_TIMEOUT 1000
138#endif
139
140/**
141 * @brief The number of CS pins whose settings an SPIClass remembers, 1 to
142 * 254 (default 4). Can be redefined in variant.h.
143 */
144#ifndef NB_SPI_SETTINGS
145 #define NB_SPI_SETTINGS 4
146#endif
147
148/**
149 * @brief A device's SPI settings: its maximum clock, bit order and mode,
150 * for SPIClass::beginTransaction().
151 *
152 * @code
153 * SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0)); // runs at 6 MHz
154 * @endcode
155 */
157 public:
158 /**
159 * @brief Settings for a device.
160 * @param clock the device's maximum clock in Hz; the bus runs at the
161 * fastest 48 MHz / 2^n (n = 1..8) that does not exceed
162 * it, and at 187.5 kHz below that.
163 * @param bitOrder `MSBFIRST` or `LSBFIRST`.
164 * @param dataMode `SPI_MODE0` ... `SPI_MODE3`; any other value means
165 * `SPI_MODE0`.
166 * @param noRecv `SPI_TRANSMITRECEIVE` (the default) or
167 * `SPI_TRANSMITONLY`: send only, and do not read what
168 * comes back.
169 */
170 constexpr SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, bool noRecv = SPI_TRANSMITRECEIVE)
171 : pinCS(-1),
172 clk(clock),
173 bOrder(bitOrder),
174 dMode((spi_mode_e)(
175 (SPI_MODE0 == dataMode) ? SPI_MODE_0 :
176 (SPI_MODE1 == dataMode) ? SPI_MODE_1 :
177 (SPI_MODE2 == dataMode) ? SPI_MODE_2 :
178 (SPI_MODE3 == dataMode) ? SPI_MODE_3 :
180 )),
181 noReceive(noRecv)
182 { }
183 /**
184 * @brief The default settings: 4 MHz requested (3 MHz on the wire),
185 * MSB first, `SPI_MODE0`, send and receive.
186 */
187 constexpr SPISettings()
188 : pinCS(-1),
189 clk(SPI_SPEED_CLOCK_DEFAULT),
190 bOrder(MSBFIRST),
191 dMode(SPI_MODE_0),
192 noReceive(SPI_TRANSMITRECEIVE)
193 { }
194 private:
195 int16_t pinCS; //CS pin associated to the configuration
196 uint32_t clk; //specifies the spi bus maximum clock speed
197 BitOrder bOrder; //bit order (MSBFirst or LSBFirst)
198 spi_mode_e dMode; //one of the data mode
199 //Mode Clock Polarity (CPOL) Clock Phase (CPHA)
200 //SPI_MODE0 0 0
201 //SPI_MODE1 0 1
202 //SPI_MODE2 1 0
203 //SPI_MODE3 1 1
204 friend class SPIClass;
205 bool noReceive;
206};
207
208/**
209 * @brief An SPI master: the Arduino SPI API on one of the chip's SPI
210 * peripherals (the global @ref SPI on this board).
211 *
212 * Every method takes an optional CS pin first. Without it (or with
213 * @ref CS_PIN_CONTROLLED_BY_USER) the sketch drives its device's chip
214 * select itself; with it, the class drives that pin low for the transfer
215 * and high after it, and keeps settings for it apart from other pins'.
216 */
217class SPIClass {
218 public:
219 /**
220 * @brief An SPI on the variant's default pins: `MOSI`, `MISO` and `SCK`
221 * (PA7, PA6 and PA5 on this board), with no hardware chip select.
222 */
224 /**
225 * @brief An SPI on the given pins, which must all belong to the same SPI
226 * peripheral (on the CH32X035 only SPI1's PA7, PA6, PA5 and PA4 do).
227 * @param mosi the MOSI pin (`PA7`).
228 * @param miso the MISO pin (`PA6`).
229 * @param sclk the clock pin (`PA5`).
230 * @param ssel a hardware chip select the peripheral drives itself
231 * (`PA4`, the panel's CS on this board), or
232 * `PNUM_NOT_DEFINED` (the default) for none. With one, do
233 * not pass CS pins to the other methods.
234 */
235 SPIClass(uint32_t mosi, uint32_t miso, uint32_t sclk, uint32_t ssel = PNUM_NOT_DEFINED);
236
237 /**
238 * @name Pins (call before begin())
239 * On the CH32X035 SPI1 has one pin for each role, so these only matter
240 * for an SPIClass made with no pins at all.
241 * @{
242 */
243
244 // setMISO/MOSI/SCLK/SSEL have to be called before begin()
245 /** @brief Sets the MISO pin. @param miso the pin's Arduino number (`PA6`). */
246 void setMISO(uint32_t miso)
247 {
248 _spi.pin_miso = digitalPinToPinName(miso);
249 };
250 /** @brief Sets the MOSI pin. @param mosi the pin's Arduino number (`PA7`). */
251 void setMOSI(uint32_t mosi)
252 {
253 _spi.pin_mosi = digitalPinToPinName(mosi);
254 };
255 /** @brief Sets the clock pin. @param sclk the pin's Arduino number (`PA5`). */
256 void setSCLK(uint32_t sclk)
257 {
258 _spi.pin_sclk = digitalPinToPinName(sclk);
259 };
260 /**
261 * @brief Sets a hardware chip select, driven by the peripheral itself.
262 * @param ssel the pin's Arduino number (`PA4`, the panel's CS on this
263 * board).
264 */
265 void setSSEL(uint32_t ssel)
266 {
267 _spi.pin_ssel = digitalPinToPinName(ssel);
268 };
269
270 /** @brief Sets the MISO pin. @param miso the pin's name (`PA_6`). */
271 void setMISO(PinName miso)
272 {
273 _spi.pin_miso = (miso);
274 };
275 /** @brief Sets the MOSI pin. @param mosi the pin's name (`PA_7`). */
276 void setMOSI(PinName mosi)
277 {
278 _spi.pin_mosi = (mosi);
279 };
280 /** @brief Sets the clock pin. @param sclk the pin's name (`PA_5`). */
281 void setSCLK(PinName sclk)
282 {
283 _spi.pin_sclk = (sclk);
284 };
285 /** @brief Sets a hardware chip select. @param ssel the pin's name (`PA_4`). */
286 void setSSEL(PinName ssel)
287 {
288 _spi.pin_ssel = (ssel);
289 };
290 /** @} */
291
292 /**
293 * @brief Starts the SPI with the pin's settings (the defaults the first
294 * time: 3 MHz, MSB first, `SPI_MODE0`).
295 *
296 * Resets SPI1 and programs it afresh, and sets the SPI pins up.
297 * @param _pin a CS pin for the class to drive (made an output and set
298 * high here), or @ref CS_PIN_CONTROLLED_BY_USER (the
299 * default). Nothing happens if @ref NB_SPI_SETTINGS other
300 * pins already have settings.
301 */
302 virtual void begin(uint8_t _pin = CS_PIN_CONTROLLED_BY_USER);
303 /**
304 * @brief Stops the SPI: resets SPI1, switches its clock off and forgets
305 * every pin's settings.
306 */
307 void end(void);
308
309 /* This function should be used to configure the SPI instance in case you
310 * don't use default parameters.
311 * You can attach another CS pin to the SPI instance and each CS pin can be
312 * attach with specific SPI settings.
313 */
314 /**
315 * @brief Stores a device's settings for a CS pin and programs SPI1 with
316 * them.
317 *
318 * Resets SPI1 and programs it afresh. Unlike on AVR, nothing is
319 * locked and interrupts are left alone.
320 * @param pin a CS pin for the class to drive (made an output and
321 * set high here), or @ref CS_PIN_CONTROLLED_BY_USER.
322 * Nothing happens if @ref NB_SPI_SETTINGS other pins
323 * already have settings.
324 * @param settings the device's clock, bit order and mode.
325 */
326 virtual void beginTransaction(uint8_t pin, SPISettings settings);
327 /**
328 * @brief Programs SPI1 with a device's settings, for a device whose CS
329 * the sketch drives itself.
330 * @param settings the device's clock, bit order and mode.
331 */
333 {
335 }
336
337 /**
338 * @brief Forgets the pin's settings: transfers for it do nothing until
339 * the next begin() or beginTransaction() for it. SPI1 is left as it is.
340 * @param pin the CS pin given to beginTransaction().
341 */
342 void endTransaction(uint8_t pin);
343 /**
344 * @brief Forgets the settings of the sketch-driven CS: transfer() does
345 * nothing until the next begin() or beginTransaction().
346 */
351
352 /**
353 * @name Transfers
354 * Each one needs begin() or beginTransaction() for its pin first. With
355 * a CS pin other than the last transfer's, SPI1 is reset and programmed
356 * with that pin's settings first. The class drives the pin low for the
357 * transfer and, with `SPI_LAST`, high after it.
358 * @{
359 */
360
361 /* Transfer functions: must be called after initialization of the SPI
362 * instance with begin() or beginTransaction().
363 * You can specify the CS pin to use.
364 */
365 /**
366 * @brief Sends one byte and returns the byte received meanwhile.
367 * @param pin the device's CS pin.
368 * @param _data the byte to send.
369 * @param _mode `SPI_LAST` (the default) releases CS afterwards,
370 * `SPI_CONTINUE` keeps it low for the next transfer.
371 * @return the byte received; 0 if the pin has no settings or the
372 * settings are `SPI_TRANSMITONLY`.
373 */
374 virtual byte transfer(uint8_t pin, uint8_t _data, SPITransferMode _mode = SPI_LAST);
375 /**
376 * @brief Sends 16 bits as two bytes and returns the 16 bits received.
377 *
378 * With `MSBFIRST` the high byte goes first, with `LSBFIRST` the low
379 * byte, so the bits go out in the chosen order.
380 * @param pin the device's CS pin.
381 * @param _data the 16 bits to send.
382 * @param _mode `SPI_LAST` (the default) or `SPI_CONTINUE`.
383 * @return the 16 bits received; 0 if the pin has no settings or the
384 * settings are `SPI_TRANSMITONLY`.
385 */
386 virtual uint16_t transfer16(uint8_t pin, uint16_t _data, SPITransferMode _mode = SPI_LAST);
387 /**
388 * @brief Sends a buffer, replacing its bytes with the bytes received.
389 * @param pin the device's CS pin.
390 * @param _buf the bytes to send, overwritten with those received
391 * (left as sent with `SPI_TRANSMITONLY`).
392 * @param _count how many bytes (up to 65,535); 0 does nothing.
393 * @param _mode `SPI_LAST` (the default) or `SPI_CONTINUE`.
394 */
395 virtual void transfer(uint8_t pin, void *_buf, size_t _count, SPITransferMode _mode = SPI_LAST);
396 /**
397 * @brief Sends one buffer and receives into another.
398 * @param _pin the device's CS pin.
399 * @param _bufout the bytes to send.
400 * @param _bufin receives the bytes received (untouched with
401 * `SPI_TRANSMITONLY`); may be `_bufout`.
402 * @param _count how many bytes (up to 65,535); 0 does nothing.
403 * @param _mode `SPI_LAST` (the default) or `SPI_CONTINUE`.
404 */
405 virtual void transfer(byte _pin, void *_bufout, void *_bufin, size_t _count, SPITransferMode _mode = SPI_LAST);
406
407 // Transfer functions when user controls himself the CS pin.
408 /**
409 * @brief Sends one byte and returns the byte received meanwhile (CS
410 * driven by the sketch).
411 * @param _data the byte to send.
412 * @param _mode ignored without a CS pin.
413 * @return the byte received; 0 before begin() or with
414 * `SPI_TRANSMITONLY`.
415 */
416 byte transfer(uint8_t _data, SPITransferMode _mode = SPI_LAST)
417 {
418 return transfer(CS_PIN_CONTROLLED_BY_USER, _data, _mode);
419 }
420
421 /**
422 * @brief Sends 16 bits and returns the 16 bits received (CS driven by
423 * the sketch).
424 * @param _data the 16 bits to send, in the chosen bit order.
425 * @param _mode ignored without a CS pin.
426 * @return the 16 bits received; 0 before begin() or with
427 * `SPI_TRANSMITONLY`.
428 */
429 uint16_t transfer16(uint16_t _data, SPITransferMode _mode = SPI_LAST)
430 {
431 return transfer16(CS_PIN_CONTROLLED_BY_USER, _data, _mode);
432 }
433
434 /**
435 * @brief Sends a buffer, replacing its bytes with the bytes received (CS
436 * driven by the sketch).
437 * @param _buf the bytes to send, overwritten with those received.
438 * @param _count how many bytes (up to 65,535).
439 * @param _mode ignored without a CS pin.
440 */
441 void transfer(void *_buf, size_t _count, SPITransferMode _mode = SPI_LAST)
442 {
443 transfer(CS_PIN_CONTROLLED_BY_USER, _buf, _count, _mode);
444 }
445
446 /**
447 * @brief Sends one buffer and receives into another (CS driven by the
448 * sketch).
449 * @param _bufout the bytes to send.
450 * @param _bufin receives the bytes received.
451 * @param _count how many bytes (up to 65,535).
452 * @param _mode ignored without a CS pin.
453 */
454 void transfer(void *_bufout, void *_bufin, size_t _count, SPITransferMode _mode = SPI_LAST)
455 {
456 transfer(CS_PIN_CONTROLLED_BY_USER, _bufout, _bufin, _count, _mode);
457 }
458 /** @} */
459
460 /**
461 * @name Deprecated settings
462 * Kept for compatibility: use SPISettings with beginTransaction()
463 * instead. Each changes one of the pin's settings and then resets and
464 * programs SPI1 with them; for a pin with no settings it does nothing.
465 * @{
466 */
467
468 /* These methods are deprecated and kept for compatibility.
469 * Use SPISettings with SPI.beginTransaction() to configure SPI parameters.
470 */
471 /**
472 * @brief Sets the bit order for a CS pin.
473 * @param _pin the CS pin.
474 * @par Parameters
475 * - `_order`: `MSBFIRST` or `LSBFIRST`.
476 */
477 void setBitOrder(uint8_t _pin, BitOrder);
478 /** @brief Sets the bit order. @param _order `MSBFIRST` or `LSBFIRST`. */
479 void setBitOrder(BitOrder _order)
480 {
482 }
483
484 /**
485 * @brief Sets the mode for a CS pin.
486 * @param _pin the CS pin.
487 * @par Parameters
488 * - `_mode`: `SPI_MODE0` ... `SPI_MODE3`; any other value is ignored.
489 */
490 void setDataMode(uint8_t _pin, uint8_t);
491 /** @brief Sets the mode. @param _mode `SPI_MODE0` ... `SPI_MODE3`. */
492 void setDataMode(uint8_t _mode)
493 {
495 }
496
497 /**
498 * @brief Sets the clock for a CS pin as a divider of 48 MHz.
499 * @param _pin the CS pin.
500 * @par Parameters
501 * - `_div`: `SPI_CLOCK_DIV2` ... `SPI_CLOCK_DIV128` (any 1-255 works;
502 * the result is rounded down to 48 MHz / 2^n); 0 means the
503 * default clock (3 MHz).
504 */
505 void setClockDivider(uint8_t _pin, uint8_t);
506 /**
507 * @brief Sets the clock as a divider of 48 MHz.
508 * @param _div `SPI_CLOCK_DIV2` ... `SPI_CLOCK_DIV128`; 0 means the
509 * default clock (3 MHz).
510 */
511 void setClockDivider(uint8_t _div)
512 {
514 }
515 /** @} */
516
517 // Not implemented functions. Kept for backward compatibility.
518 /**
519 * @brief Does nothing (kept for compatibility): transfers are never
520 * guarded against interrupts.
521 * @param interruptNumber ignored.
522 */
523 void usingInterrupt(uint8_t interruptNumber);
524 /** @brief Does nothing (kept for compatibility). */
525 void attachInterrupt(void);
526 /** @brief Does nothing (kept for compatibility). */
527 void detachInterrupt(void);
528
529 // Could be used to mix Arduino API and STM32Cube HAL API (ex: DMA). Use at your own risk.
530 /**
531 * @brief The WCH peripheral library's view of this SPI: its instance
532 * and init structure, for mixing in WCH's own SPI functions. Use at
533 * your own risk.
534 * @return the handle, valid for the object's lifetime.
535 */
536 SPI_HandleTypeDef *getHandle(void)
537 {
538 return &(_spi.handle);
539 }
540
541 protected:
542 // spi instance
543 spi_t _spi; /**< the instance's pins, peripheral and WCH init structure */
544
545 private:
546 /* Contains various spiSettings for the same spi instance. Each spi spiSettings
547 is associated to a CS pin. */
548 SPISettings spiSettings[NB_SPI_SETTINGS];
549
550 // Use to know which configuration is selected.
551 int16_t _CSPinConfig;
552
553 typedef enum {
554 GET_IDX = 0,
555 ADD_NEW_PIN = 1
556 } pin_option_t;
557
558 uint8_t pinIdx(uint8_t _pin, pin_option_t option)
559 {
560 uint8_t i;
561
562 if ((_pin > NUM_DIGITAL_PINS) && (!digitalPinIsValid(_pin))) {
563 return NB_SPI_SETTINGS;
564 }
565
566 for (i = 0; i < NB_SPI_SETTINGS; i++) {
567 if (_pin == spiSettings[i].pinCS) {
568 return i;
569 }
570 }
571
572 if (option == ADD_NEW_PIN) {
573 for (i = 0; i < NB_SPI_SETTINGS; i++) {
574 if (spiSettings[i].pinCS == -1) {
575 spiSettings[i].pinCS = _pin;
576 return i;
577 }
578 }
579 }
580 return i;
581 }
582
583 void RemovePin(uint8_t _pin)
584 {
585 if ((_pin > NUM_DIGITAL_PINS) && (!digitalPinIsValid(_pin))) {
586 return;
587 }
588
589 for (uint8_t i = 0; i < NB_SPI_SETTINGS; i++) {
590 if (spiSettings[i].pinCS == _pin) {
591 spiSettings[i].pinCS = -1;
592 spiSettings[i].clk = SPI_SPEED_CLOCK_DEFAULT;
593 spiSettings[i].bOrder = MSBFIRST;
594 spiSettings[i].dMode = SPI_MODE_0;
595 }
596 }
597 }
598
599 void RemoveAllPin(void)
600 {
601 for (uint8_t i = 0; i < NB_SPI_SETTINGS; i++) {
602 spiSettings[i].pinCS = -1;
603 spiSettings[i].clk = SPI_SPEED_CLOCK_DEFAULT;
604 spiSettings[i].bOrder = MSBFIRST;
605 spiSettings[i].dMode = SPI_MODE_0;
606 }
607 }
608};
609
610/**
611 * @brief The SPI: SPI1 on PA5 (SCK), PA6 (MISO) and PA7 (MOSI), the bus the
612 * board's panel and SD card are on.
613 */
614extern SPIClass SPI;
615
616#if defined(SUBGHZSPI_BASE)
617class SUBGHZSPIClass : public SPIClass {
618 public:
619 SUBGHZSPIClass(): SPIClass{NC, NC, NC, NC}
620 {
621 _spi.spi = SUBGHZSPI;
622 }
623
624 void begin(uint8_t _pin = CS_PIN_CONTROLLED_BY_USER);
625 void beginTransaction(uint8_t pin, SPISettings settings);
626 byte transfer(uint8_t pin, uint8_t _data, SPITransferMode _mode = SPI_LAST);
627 uint16_t transfer16(uint8_t pin, uint16_t _data, SPITransferMode _mode = SPI_LAST);
628 void transfer(uint8_t pin, void *_buf, size_t _count, SPITransferMode _mode = SPI_LAST);
629 void transfer(byte _pin, void *_bufout, void *_bufin, size_t _count, SPITransferMode _mode = SPI_LAST);
630 void enableDebugPins(uint32_t mosi = DEBUG_SUBGHZSPI_MOSI, uint32_t miso = DEBUG_SUBGHZSPI_MISO, uint32_t sclk = DEBUG_SUBGHZSPI_SCLK, uint32_t ssel = DEBUG_SUBGHZSPI_SS);
631
633 using SPIClass::transfer;
635};
636
637#endif
638
639/** @} */
640
641#endif /* _SPI_H_INCLUDED */
An SPI master: the Arduino SPI API on one of the chip's SPI peripherals (the global SPI on this board...
Definition SPI.h:217
void setSCLK(uint32_t sclk)
Sets the clock pin.
Definition SPI.h:256
void transfer(void *_bufout, void *_bufin, size_t _count, SPITransferMode _mode=SPI_LAST)
Sends one buffer and receives into another (CS driven by the sketch).
Definition SPI.h:454
void setDataMode(uint8_t _pin, uint8_t)
Sets the mode for a CS pin.
void attachInterrupt(void)
Does nothing (kept for compatibility).
spi_t _spi
the instance's pins, peripheral and WCH init structure
Definition SPI.h:543
void usingInterrupt(uint8_t interruptNumber)
Does nothing (kept for compatibility): transfers are never guarded against interrupts.
byte transfer(uint8_t _data, SPITransferMode _mode=SPI_LAST)
Sends one byte and returns the byte received meanwhile (CS driven by the sketch).
Definition SPI.h:416
virtual byte transfer(uint8_t pin, uint8_t _data, SPITransferMode _mode=SPI_LAST)
Sends one byte and returns the byte received meanwhile.
uint16_t transfer16(uint16_t _data, SPITransferMode _mode=SPI_LAST)
Sends 16 bits and returns the 16 bits received (CS driven by the sketch).
Definition SPI.h:429
void transfer(void *_buf, size_t _count, SPITransferMode _mode=SPI_LAST)
Sends a buffer, replacing its bytes with the bytes received (CS driven by the sketch).
Definition SPI.h:441
void detachInterrupt(void)
Does nothing (kept for compatibility).
void end(void)
Stops the SPI: resets SPI1, switches its clock off and forgets every pin's settings.
SPIClass()
An SPI on the variant's default pins: MOSI, MISO and SCK (PA7, PA6 and PA5 on this board),...
virtual void transfer(uint8_t pin, void *_buf, size_t _count, SPITransferMode _mode=SPI_LAST)
Sends a buffer, replacing its bytes with the bytes received.
void setMOSI(uint32_t mosi)
Sets the MOSI pin.
Definition SPI.h:251
void endTransaction(uint8_t pin)
Forgets the pin's settings: transfers for it do nothing until the next begin() or beginTransaction() ...
virtual void begin(uint8_t _pin=CS_PIN_CONTROLLED_BY_USER)
Starts the SPI with the pin's settings (the defaults the first time: 3 MHz, MSB first,...
void setClockDivider(uint8_t _pin, uint8_t)
Sets the clock for a CS pin as a divider of 48 MHz.
void setMISO(PinName miso)
Sets the MISO pin.
Definition SPI.h:271
void setMISO(uint32_t miso)
Sets the MISO pin.
Definition SPI.h:246
virtual void beginTransaction(uint8_t pin, SPISettings settings)
Stores a device's settings for a CS pin and programs SPI1 with them.
void endTransaction(void)
Forgets the settings of the sketch-driven CS: transfer() does nothing until the next begin() or begin...
Definition SPI.h:347
void setSCLK(PinName sclk)
Sets the clock pin.
Definition SPI.h:281
SPI_HandleTypeDef * getHandle(void)
The WCH peripheral library's view of this SPI: its instance and init structure, for mixing in WCH's o...
Definition SPI.h:536
void setSSEL(uint32_t ssel)
Sets a hardware chip select, driven by the peripheral itself.
Definition SPI.h:265
void setBitOrder(BitOrder _order)
Sets the bit order.
Definition SPI.h:479
void setMOSI(PinName mosi)
Sets the MOSI pin.
Definition SPI.h:276
void setDataMode(uint8_t _mode)
Sets the mode.
Definition SPI.h:492
void beginTransaction(SPISettings settings)
Programs SPI1 with a device's settings, for a device whose CS the sketch drives itself.
Definition SPI.h:332
virtual uint16_t transfer16(uint8_t pin, uint16_t _data, SPITransferMode _mode=SPI_LAST)
Sends 16 bits as two bytes and returns the 16 bits received.
SPIClass(uint32_t mosi, uint32_t miso, uint32_t sclk, uint32_t ssel=PNUM_NOT_DEFINED)
An SPI on the given pins, which must all belong to the same SPI peripheral (on the CH32X035 only SPI1...
virtual void transfer(byte _pin, void *_bufout, void *_bufin, size_t _count, SPITransferMode _mode=SPI_LAST)
Sends one buffer and receives into another.
void setSSEL(PinName ssel)
Sets a hardware chip select.
Definition SPI.h:286
void setClockDivider(uint8_t _div)
Sets the clock as a divider of 48 MHz.
Definition SPI.h:511
void setBitOrder(uint8_t _pin, BitOrder)
Sets the bit order for a CS pin.
A device's SPI settings: its maximum clock, bit order and mode, for SPIClass::beginTransaction().
Definition SPI.h:156
constexpr SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, bool noRecv=SPI_TRANSMITRECEIVE)
Settings for a device.
Definition SPI.h:170
constexpr SPISettings()
The default settings: 4 MHz requested (3 MHz on the wire), MSB first, SPI_MODE0, send and receive.
Definition SPI.h:187
SPITransferMode
What a transfer does with a CS pin the class drives, once it is done.
Definition SPI.h:117
SPIClass SPI
The SPI: SPI1 on PA5 (SCK), PA6 (MISO) and PA7 (MOSI), the bus the board's panel and SD card are on.
#define NB_SPI_SETTINGS
The number of CS pins whose settings an SPIClass remembers, 1 to 254 (default 4).
Definition SPI.h:145
#define SPI_MODE3
clock idles high, data sampled on the rising edge (CPOL 1, CPHA 1)
Definition SPI.h:105
#define CS_PIN_CONTROLLED_BY_USER
The "CS pin" that means the sketch drives its chip select itself, outside the SPI class (the default ...
Definition SPI.h:126
#define SPI_MODE1
clock idles low, data sampled on the falling edge (CPOL 0, CPHA 1)
Definition SPI.h:103
#define SPI_MODE2
clock idles high, data sampled on the falling edge (CPOL 1, CPHA 0)
Definition SPI.h:104
#define SPI_MODE0
clock idles low, data sampled on the rising edge (CPOL 0, CPHA 0)
Definition SPI.h:102
#define SPI_TRANSMITRECEIVE
send and receive (the default)
Definition SPI.h:112
@ SPI_CONTINUE
Transfer not finished: CS pin kept active (low)
Definition SPI.h:118
@ SPI_LAST
Transfer ended: CS pin released (high)
Definition SPI.h:119