4646 #define SPI_MIN_CLOCK_DIVIDER (uint8_t )(1 + ((F_CPU - 1 ) / 12000000 ))
4747#endif
4848
49+ class SPISettingsSAMD : public arduino ::SPISettings {
50+ public:
51+ SPISettingsSAMD (uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
52+ if (__builtin_constant_p (clock)) {
53+ init_AlwaysInline (clock, bitOrder, dataMode);
54+ } else {
55+ init_MightInline (clock, bitOrder, dataMode);
56+ }
57+ }
58+
59+ // Default speed set to 4MHz, SPI mode set to MODE 0 and Bit order set to MSB first.
60+ SPISettingsSAMD () { init_AlwaysInline (4000000 , MSBFIRST, SPI_MODE0); }
61+
62+ SPISettingsSAMD (SPISettings& x) { SPISettingsSAMD (x.getClockFreq (), x.getBitOrder (), x.getDataMode ()); }
63+
64+ private:
65+ void init_MightInline (uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
66+ init_AlwaysInline (clock, bitOrder, dataMode);
67+ }
68+
69+ void init_AlwaysInline (uint32_t clock, BitOrder bitOrder, uint8_t dataMode) __attribute__((__always_inline__)) {
70+ this ->clockFreq = (clock >= (F_CPU / SPI_MIN_CLOCK_DIVIDER) ? F_CPU / SPI_MIN_CLOCK_DIVIDER : clock);
71+
72+ this ->bitOrder = (bitOrder == MSBFIRST ? MSB_FIRST : LSB_FIRST);
73+
74+ switch (dataMode)
75+ {
76+ case SPI_MODE0:
77+ this ->dataMode = SERCOM_SPI_MODE_0; break ;
78+ case SPI_MODE1:
79+ this ->dataMode = SERCOM_SPI_MODE_1; break ;
80+ case SPI_MODE2:
81+ this ->dataMode = SERCOM_SPI_MODE_2; break ;
82+ case SPI_MODE3:
83+ this ->dataMode = SERCOM_SPI_MODE_3; break ;
84+ default :
85+ this ->dataMode = SERCOM_SPI_MODE_0; break ;
86+ }
87+ }
88+
89+ uint32_t clockFreq;
90+ SercomSpiClockMode dataMode;
91+ SercomDataOrder bitOrder;
92+
93+ friend class SPIClassSAMD ;
94+ };
95+
4996class SPIClassSAMD : public arduino ::HardwareSPI {
5097 public:
5198 SPIClassSAMD (SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, SercomSpiTXPad, SercomRXPad);
@@ -57,7 +104,10 @@ class SPIClassSAMD : public arduino::HardwareSPI {
57104 // Transaction Functions
58105 void usingInterrupt (int interruptNumber);
59106 void notUsingInterrupt (int interruptNumber);
60- void beginTransaction (SPISettings settings);
107+ void beginTransaction (SPISettingsSAMD settings);
108+ void beginTransaction (SPISettings settings) {
109+ beginTransaction (SPISettingsSAMD (settings));
110+ }
61111 void endTransaction (void );
62112
63113 // SPI Configuration methods
@@ -73,7 +123,10 @@ class SPIClassSAMD : public arduino::HardwareSPI {
73123
74124 private:
75125 void init ();
76- void config (SPISettings settings);
126+ void config (SPISettingsSAMD settings);
127+ void config (SPISettings settings) {
128+ config (SPISettingsSAMD (settings));
129+ }
77130
78131 SERCOM *_p_sercom;
79132 uint8_t _uc_pinMiso;
0 commit comments