3030SERCOM::SERCOM (Sercom* s)
3131{
3232 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__
3351}
3452
3553/* =========================
@@ -733,13 +751,17 @@ int8_t SERCOM::getSercomIndex(void) {
733751// This is currently for overriding an SPI SERCOM's clock source only --
734752// NOT for UART or WIRE SERCOMs, where it will have unintended consequences.
735753// 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 ;
737757
738758 uint8_t clk_id = core ? sercomData[idx].id_core : sercomData[idx].id_slow ;
739759
740760 GCLK->PCHCTRL [clk_id].bit .CHEN = 0 ; // Disable timer
741761 while (GCLK->PCHCTRL [clk_id].bit .CHEN ); // Wait for disable
742762
763+ if (core) clockSource = src; // Save SercomClockSource value
764+
743765 // From cores/arduino/startup.c:
744766 // GCLK0 = F_CPU
745767 // GCLK1 = 48 MHz
@@ -749,7 +771,7 @@ void SERCOM::setClockSource(int idx, SercomClockSource src, bool core) {
749771 if (src == SERCOM_CLOCK_SOURCE_FCPU) {
750772 GCLK->PCHCTRL [clk_id].reg =
751773 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
753775 } else if (src == SERCOM_CLOCK_SOURCE_48M) {
754776 GCLK->PCHCTRL [clk_id].reg =
755777 GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
@@ -772,6 +794,7 @@ void SERCOM::setClockSource(int idx, SercomClockSource src, bool core) {
772794}
773795#endif
774796
797+
775798void SERCOM::initClockNVIC ( void )
776799{
777800 int8_t idx = getSercomIndex ();
@@ -785,29 +808,12 @@ void SERCOM::initClockNVIC( void )
785808 NVIC_EnableIRQ (sercomData[idx].irq [i]);
786809 }
787810
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-
797811 // SPI DMA speed is dictated by the "slow clock," so BOTH are set to the
798812 // same clock source (clk_slow isn't sourced from XOSC32K as before).
799813 // This might have power implications for sleep code.
800814
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
811817
812818#else // end if SAMD51 (prob SAMD21)
813819
0 commit comments