30
30
SERCOM::SERCOM (Sercom* s)
31
31
{
32
32
sercom = s;
33
+
34
+ #if defined(__SAMD51__)
35
+ // A briefly-available but now deprecated feature had the SPI clock source
36
+ // set via a compile-time setting (MAX_SPI)...problem was this affected
37
+ // ALL SERCOMs, whereas some (anything read/write, e.g. SD cards) should
38
+ // not exceed the standard 24 MHz setting. Newer code, if it needs faster
39
+ // write-only SPI (e.g. to screen), should override the SERCOM clock on a
40
+ // per-peripheral basis. Nonetheless, we check SERCOM_SPI_FREQ_REF here
41
+ // (MAX_SPI * 2) to retain compatibility with any interim projects that
42
+ // might have relied on the compile-time setting. But please, don't.
43
+ #if SERCOM_SPI_FREQ_REF == F_CPU // F_CPU clock = GCLK0
44
+ clockSource = SERCOM_CLOCK_SOURCE_FCPU;
45
+ #elif SERCOM_SPI_FREQ_REF == 48000000 // 48 MHz clock = GCLK1 (standard)
46
+ clockSource = SERCOM_CLOCK_SOURCE_48M;
47
+ #elif SERCOM_SPI_FREQ_REF == 100000000 // 100 MHz clock = GCLK2
48
+ clockSource = SERCOM_CLOCK_SOURCE_100M;
49
+ #endif
50
+ #endif // end __SAMD51__
33
51
}
34
52
35
53
/* =========================
@@ -733,13 +751,17 @@ int8_t SERCOM::getSercomIndex(void) {
733
751
// This is currently for overriding an SPI SERCOM's clock source only --
734
752
// NOT for UART or WIRE SERCOMs, where it will have unintended consequences.
735
753
// It does not check.
736
- void SERCOM::setClockSource (int idx, SercomClockSource src, bool core) {
754
+ void SERCOM::setClockSource (int8_t idx, SercomClockSource src, bool core) {
755
+
756
+ if (src == SERCOM_CLOCK_SOURCE_NO_CHANGE) return ;
737
757
738
758
uint8_t clk_id = core ? sercomData[idx].id_core : sercomData[idx].id_slow ;
739
759
740
760
GCLK->PCHCTRL [clk_id].bit .CHEN = 0 ; // Disable timer
741
761
while (GCLK->PCHCTRL [clk_id].bit .CHEN ); // Wait for disable
742
762
763
+ if (core) clockSource = src; // Save SercomClockSource value
764
+
743
765
// From cores/arduino/startup.c:
744
766
// GCLK0 = F_CPU
745
767
// GCLK1 = 48 MHz
@@ -749,7 +771,7 @@ void SERCOM::setClockSource(int idx, SercomClockSource src, bool core) {
749
771
if (src == SERCOM_CLOCK_SOURCE_FCPU) {
750
772
GCLK->PCHCTRL [clk_id].reg =
751
773
GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
752
- if (core) freqRef = F_CPU;
774
+ if (core) freqRef = F_CPU; // Save clock frequency value
753
775
} else if (src == SERCOM_CLOCK_SOURCE_48M) {
754
776
GCLK->PCHCTRL [clk_id].reg =
755
777
GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
@@ -772,6 +794,7 @@ void SERCOM::setClockSource(int idx, SercomClockSource src, bool core) {
772
794
}
773
795
#endif
774
796
797
+
775
798
void SERCOM::initClockNVIC ( void )
776
799
{
777
800
int8_t idx = getSercomIndex ();
@@ -785,29 +808,12 @@ void SERCOM::initClockNVIC( void )
785
808
NVIC_EnableIRQ (sercomData[idx].irq [i]);
786
809
}
787
810
788
- // A briefly-availabe but now deprecated feature had the SPI clock source
789
- // set via a compile-time setting (MAX_SPI)...problem was this affected
790
- // ALL SERCOMs, whereas some (anything read/write, e.g. SD cards) should
791
- // not exceed the standard 24 MHz setting. Newer code, if it needs faster
792
- // write-only SPI (e.g. to screen), should override the SERCOM clock on a
793
- // per-peripheral basis. Nonetheless, we check SERCOM_SPI_FREQ_REF here
794
- // (MAX_SPI * 2) to retain compatibility with any interim projects that
795
- // might have relied on the compile-time setting. But please, don't.
796
-
797
811
// SPI DMA speed is dictated by the "slow clock," so BOTH are set to the
798
812
// same clock source (clk_slow isn't sourced from XOSC32K as before).
799
813
// This might have power implications for sleep code.
800
814
801
- #if SERCOM_SPI_FREQ_REF == F_CPU // F_CPU clock = GCLK0
802
- setClockSource (idx, SERCOM_CLOCK_SOURCE_FCPU, true ); // true = core clock
803
- setClockSource (idx, SERCOM_CLOCK_SOURCE_FCPU, false ); // false = slow clock
804
- #elif SERCOM_SPI_FREQ_REF == 48000000 // 48 MHz clock = GCLK1 (standard)
805
- setClockSource (idx, SERCOM_CLOCK_SOURCE_48M , true );
806
- setClockSource (idx, SERCOM_CLOCK_SOURCE_48M , false );
807
- #elif SERCOM_SPI_FREQ_REF == 100000000 // 100 MHz clock = GCLK2
808
- setClockSource (idx, SERCOM_CLOCK_SOURCE_100M, true );
809
- setClockSource (idx, SERCOM_CLOCK_SOURCE_100M, false );
810
- #endif
815
+ setClockSource (idx, clockSource, true ); // true = core clock
816
+ setClockSource (idx, clockSource, false ); // false = slow clock
811
817
812
818
#else // end if SAMD51 (prob SAMD21)
813
819
0 commit comments