Skip to content

Commit 7616dab

Browse files
SERCOM stuff - simplify, cleanup, add SAMD21 dummy funcs
1 parent 651862f commit 7616dab

File tree

4 files changed

+39
-40
lines changed

4 files changed

+39
-40
lines changed

cores/arduino/SERCOM.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,9 @@ int8_t SERCOM::getSercomIndex(void) {
751751
// This is currently for overriding an SPI SERCOM's clock source only --
752752
// NOT for UART or WIRE SERCOMs, where it will have unintended consequences.
753753
// It does not check.
754+
// SERCOM clock source override is available only on SAMD51 (not 21).
755+
// A dummy function for SAMD21 (compiles to nothing) is present in SERCOM.h
756+
// so user code doesn't require a lot of conditional situations.
754757
void SERCOM::setClockSource(int8_t idx, SercomClockSource src, bool core) {
755758

756759
if(src == SERCOM_CLOCK_SOURCE_NO_CHANGE) return;
@@ -794,7 +797,6 @@ void SERCOM::setClockSource(int8_t idx, SercomClockSource src, bool core) {
794797
}
795798
#endif
796799

797-
798800
void SERCOM::initClockNVIC( void )
799801
{
800802
int8_t idx = getSercomIndex();
@@ -808,8 +810,9 @@ void SERCOM::initClockNVIC( void )
808810
NVIC_EnableIRQ(sercomData[idx].irq[i]);
809811
}
810812

811-
// SPI DMA speed is dictated by the "slow clock," so BOTH are set to the
812-
// same clock source (clk_slow isn't sourced from XOSC32K as before).
813+
// SPI DMA speed is dictated by the "slow clock" (I think...maybe) so
814+
// BOTH are set to the same clock source (clk_slow isn't sourced from
815+
// XOSC32K as in prior versions of SAMD core).
813816
// This might have power implications for sleep code.
814817

815818
setClockSource(idx, clockSource, true); // true = core clock

cores/arduino/SERCOM.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,10 @@ typedef enum
152152
WIRE_MASTER_NACK_ACTION
153153
} SercomMasterAckActionWire;
154154

155-
#if defined(__SAMD51__)
155+
// SERCOM clock source override is available only on SAMD51 (not 21)
156+
// but the enumeration is made regardless so user code doesn't need
157+
// ifdefs or lengthy comments explaining the different situations --
158+
// the clock-sourcing functions just compile to nothing on SAMD21.
156159
typedef enum SercomClockSource {
157160
SERCOM_CLOCK_SOURCE_FCPU, // F_CPU clock (GCLK0)
158161
SERCOM_CLOCK_SOURCE_48M, // 48 MHz peripheral clock (GCLK1) (standard)
@@ -161,7 +164,6 @@ typedef enum SercomClockSource {
161164
SERCOM_CLOCK_SOURCE_12M, // 12 MHz peripheral clock (GCLK4)
162165
SERCOM_CLOCK_SOURCE_NO_CHANGE // Leave clock source setting unchanged
163166
};
164-
#endif // end __SAMD51__
165167

166168
class SERCOM
167169
{
@@ -233,16 +235,26 @@ class SERCOM
233235
uint8_t readDataWIRE( void ) ;
234236
int8_t getSercomIndex(void);
235237
#if defined(__SAMD51__)
238+
// SERCOM clock source override is only available on
239+
// SAMD51 (not 21) ... but these functions are declared
240+
// regardless so user code doesn't need ifdefs or lengthy
241+
// comments explaining the different situations -- these
242+
// just compile to nothing on SAMD21.
236243
void setClockSource(int8_t idx, SercomClockSource src, bool core);
237244
SercomClockSource getClockSource(void) { return clockSource; };
238245
uint32_t getFreqRef(void) { return freqRef; };
246+
#else
247+
// The equivalent SAMD21 dummy functions...
248+
void setClockSource(int8_t idx, SercomClockSource src, bool core) { };
249+
SercomClockSource getClockSource(void) { return SERCOM_CLOCK_SOURCE_FCPU; };
250+
uint32_t getFreqRef(void) { return F_CPU; };
239251
#endif
240252

241253
private:
242254
Sercom* sercom;
243255
#if defined(__SAMD51__)
244256
SercomClockSource clockSource;
245-
uint32_t freqRef;
257+
uint32_t freqRef; // Frequency corresponding to clockSource
246258
#endif
247259
uint8_t calculateBaudrateSynchronous(uint32_t baudrate);
248260
uint32_t division(uint32_t dividend, uint32_t divisor) ;

libraries/SPI/SPI.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,6 @@ SPIClass::SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint
4242
// SERCOM pads
4343
_padTx=PadTx;
4444
_padRx=PadRx;
45-
46-
#if defined(__SAMD51__)
47-
maxBitrate = MAX_SPI; // Can override via setClockSource()
48-
#endif
4945
}
5046

5147
void SPIClass::begin()
@@ -247,7 +243,6 @@ void SPIClass::detachInterrupt() {
247243
// Should be disableInterrupt()
248244
}
249245

250-
#if defined(__SAMD21__) || defined(__SAMD51__)
251246
// SPI DMA lookup works on both SAMD21 and SAMD51
252247

253248
volatile uint32_t *SPIClass::getDataRegister(void) {
@@ -282,16 +277,17 @@ int SPIClass::getDMACID(void) {
282277
return (idx >= 0) ? DMACID[idx] : -1;
283278
}
284279

285-
#endif // end __SAMD21__ || __SAMD51__
286-
287280
#if defined(__SAMD51__)
288281

289-
// Set the SPI device's SERCOM clock CORE and/or SLOW clock source(s).
290-
// These are SercomClockSource values from an enumeration in SERCOM.h.
291-
void SPIClass::setClockSources(SercomClockSource core, SercomClockSource slow) {
282+
// Set the SPI device's SERCOM clock CORE and SLOW clock sources.
283+
// SercomClockSource values are an enumeration in SERCOM.h.
284+
// This works on SAMD51 only. On SAMD21, a dummy function is declared
285+
// in SPI.h which compiles to nothing, so user code doesn't need to check
286+
// and conditionally compile lines for different architectures.
287+
void SPIClass::setClockSource(SercomClockSource clk) {
292288
int8_t idx = _p_sercom->getSercomIndex();
293-
_p_sercom->setClockSource(idx, core, true); // true = set core clock
294-
_p_sercom->setClockSource(idx, slow, false); // false = set slow clock
289+
_p_sercom->setClockSource(idx, clk, true); // true = set core clock
290+
_p_sercom->setClockSource(idx, clk, false); // false = set slow clock
295291
}
296292

297293
#endif // end __SAMD51__

libraries/SPI/SPI.h

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
// SAMD51 has configurable MAX_SPI, else use peripheral clock default.
4242
// Update: changing MAX_SPI via compiler flags is DEPRECATED, because
4343
// this affects ALL SPI peripherals including some that should NOT be
44-
// changed (e.g. anything using SD card). Use the setClockSources()
44+
// changed (e.g. anything using SD card). Use the setClockSource()
4545
// function instead. This is left here for compatibility with interim code.
4646
#if !defined(MAX_SPI)
4747
#define MAX_SPI 24000000
@@ -107,17 +107,6 @@ class SPISettings {
107107
friend class SPIClass;
108108
};
109109

110-
#if defined(__SAMD51__)
111-
enum SPIClockSource {
112-
SPI_CLOCK_SOURCE_NO_CHANGE, // Leave clock source setting unchanged
113-
SPI_CLOCK_SOURCE_FCPU, // F_CPU clock (GCLK0)
114-
SPI_CLOCK_SOURCE_48M, // 48 MHz peripheral clock (GCLK1) (standard)
115-
SPI_CLOCK_SOURCE_100M, // 100 MHz peripheral clock (GCLK2)
116-
SPI_CLOCK_SOURCE_32K, // XOSC32K clock (GCLK3)
117-
SPI_CLOCK_SOURCE_12M // 12 MHz peripheral clock (GCLK4)
118-
};
119-
#endif // end __SAMD51__
120-
121110
class SPIClass {
122111
public:
123112
SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, SercomSpiTXPad, SercomRXPad);
@@ -143,15 +132,17 @@ class SPIClass {
143132
void setDataMode(uint8_t uc_mode);
144133
void setClockDivider(uint8_t uc_div);
145134

146-
#if defined(__SAMD21__) || defined(__SAMD51__)
135+
// SERCOM lookup functions are available on both SAMD51 and 21.
147136
volatile uint32_t *getDataRegister(void);
148-
int getDMACID(void);
149-
#endif
137+
int getDMACID(void);
138+
uint8_t getSercomIndex(void) { return _p_sercom->getSercomIndex(); };
150139
#if defined(__SAMD51__)
151-
void setClockSources(
152-
SercomClockSource core = SERCOM_CLOCK_SOURCE_NO_CHANGE,
153-
SercomClockSource slow = SERCOM_CLOCK_SOURCE_NO_CHANGE);
154-
uint32_t getMaxBitrate(void) { return maxBitrate; };
140+
// SERCOM clock source override is available only on SAMD51.
141+
void setClockSource(SercomClockSource clk);
142+
#else
143+
// On SAMD21, this compiles to nothing, so user code doesn't need to
144+
// check and conditionally compile lines for different architectures.
145+
void setClockSource(SercomClockSource clk) { };
155146
#endif // end __SAMD51__
156147

157148
private:
@@ -170,9 +161,6 @@ class SPIClass {
170161
uint8_t interruptMode;
171162
char interruptSave;
172163
uint32_t interruptMask;
173-
#if defined(__SAMD51__)
174-
uint32_t maxBitrate;
175-
#endif
176164
};
177165

178166
#if SPI_INTERFACES_COUNT > 0

0 commit comments

Comments
 (0)