Skip to content

Commit 127b613

Browse files
committed
clock setup are a mess and peripherals are wrong but it works!
1 parent c332f90 commit 127b613

File tree

3 files changed

+143
-0
lines changed

3 files changed

+143
-0
lines changed

boards.txt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,31 @@ adafruit_feather_m0.bootloader.file=feather/samd21_sam_ba.bin
9595
#adafruit_metro_m0.build.pid=0x8013
9696
#adafruit_metro_m0.bootloader.tool=openocd
9797
#adafruit_metro_m0.bootloader.file=metro/samd21_sam_ba.bin
98+
99+
100+
adafruit_trinket_m0.name=Adafruit Trinket M0
101+
adafruit_trinket_m0.vid.0=0x239A
102+
adafruit_trinket_m0.pid.0=0x8016
103+
adafruit_trinket_m0.vid.1=0x239A
104+
adafruit_trinket_m0.pid.1=0x0016
105+
adafruit_trinket_m0.upload.tool=bossac
106+
adafruit_trinket_m0.upload.protocol=sam-ba
107+
adafruit_trinket_m0.upload.maximum_size=262144
108+
adafruit_trinket_m0.upload.use_1200bps_touch=true
109+
adafruit_trinket_m0.upload.wait_for_upload_port=true
110+
adafruit_trinket_m0.upload.native_usb=true
111+
adafruit_trinket_m0.build.mcu=cortex-m0plus
112+
adafruit_trinket_m0.build.f_cpu=48000000L
113+
adafruit_trinket_m0.build.usb_product="Trinket M0"
114+
adafruit_trinket_m0.build.usb_manufacturer="Adafruit"
115+
adafruit_trinket_m0.build.board=SAMD_ZERO
116+
adafruit_trinket_m0.build.core=arduino
117+
adafruit_trinket_m0.build.extra_flags=-DCRYSTALLESS -D__SAMD21E18A__ {build.usb_flags}
118+
adafruit_trinket_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld
119+
adafruit_trinket_m0.build.openocdscript=openocd_scripts/arduino_zero.cfg
120+
adafruit_trinket_m0.build.variant=trinket_m0
121+
adafruit_trinket_m0.build.variant_system_lib=
122+
adafruit_trinket_m0.build.vid=0x239A
123+
adafruit_trinket_m0.build.pid=0x8016
124+
adafruit_trinket_m0.bootloader.tool=openocd
125+
adafruit_trinket_m0.bootloader.file=trinket/samd21_sam_ba.bin

cores/arduino/SERCOM.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,7 @@ void SERCOM::initClockNVIC( void )
665665
clockId = GCM_SERCOM3_CORE;
666666
IdNvic = SERCOM3_IRQn;
667667
}
668+
#if !defined(__SAMD21E18A__)
668669
else if(sercom == SERCOM4)
669670
{
670671
clockId = GCM_SERCOM4_CORE;
@@ -675,6 +676,7 @@ void SERCOM::initClockNVIC( void )
675676
clockId = GCM_SERCOM5_CORE;
676677
IdNvic = SERCOM5_IRQn;
677678
}
679+
#endif
678680

679681
if ( IdNvic == PendSV_IRQn )
680682
{

cores/arduino/startup.c

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ void SystemInit( void )
5151
/* Turn on the digital interface clock */
5252
PM->APBAMASK.reg |= PM_APBAMASK_GCLK ;
5353

54+
#if !defined(CRYSTALLESS)
5455
/* ----------------------------------------------------------------------------------------------
5556
* 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator)
5657
*/
@@ -193,6 +194,118 @@ void SystemInit( void )
193194
// GCLK_GENCTRL_OE | // Output clock to a pin for tests
194195
GCLK_GENCTRL_GENEN ;
195196

197+
#else
198+
199+
200+
/* Set OSC8M prescalar to divide by 1, now gclk0 is @ 8mhz */
201+
SYSCTRL->OSC8M.bit.PRESC = 0;
202+
203+
/* ----------------------------------------------------------------------------------------------
204+
* 1) Enable OSC32K clock (Internal 32.768Hz oscillator)
205+
*/
206+
207+
uint32_t calib = (*((uint32_t *) SYSCTRL_FUSES_OSC32K_ADDR) & SYSCTRL_FUSES_OSC32K_Msk) >> SYSCTRL_FUSES_OSC32K_Pos;
208+
209+
SYSCTRL->OSC32K.reg = SYSCTRL_OSC32K_CALIB(calib) | SYSCTRL_OSC32K_STARTUP( 0x6u ) | // cf table 15.10 of product datasheet in chapter 15.8.6
210+
SYSCTRL_OSC32K_EN32K | SYSCTRL_OSC32K_ENABLE;
211+
212+
while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_OSC32KRDY) == 0 ); // Wait for oscillator stabilization
213+
214+
/* ----------------------------------------------------------------------------------------------
215+
* 2) Put OSC32K as source of Generic Clock Generator 1
216+
*/
217+
218+
GCLK_GENCTRL_Type genctrl={0};
219+
uint32_t temp_genctrl;
220+
221+
GCLK->GENCTRL.bit.ID = 1; // Read GENERATOR_ID - GCLK_GEN_1
222+
223+
while(GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY); // wait for data to be ready
224+
225+
temp_genctrl = GCLK->GENCTRL.reg;
226+
genctrl.bit.SRC = GCLK_GENCTRL_SRC_OSC32K_Val; // gclk 1 is now = osc32k
227+
genctrl.bit.GENEN = 1;
228+
genctrl.bit.RUNSTDBY = 0;
229+
genctrl.bit.OE = 1; // output on GCLK_IO[1] pin for debugging
230+
231+
GCLK->GENCTRL.reg = (genctrl.reg | temp_genctrl); // set it!
232+
233+
while(GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
234+
235+
236+
/* Configure OSC8M as source for GCLK_GEN 2 */
237+
GCLK->GENCTRL.bit.ID = 2; // Read GENERATOR_ID - GCLK_GEN_2
238+
239+
while(GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY); // wait for data to be ready
240+
241+
temp_genctrl = GCLK->GENCTRL.reg;
242+
genctrl.bit.SRC = GCLK_GENCTRL_SRC_OSC8M_Val; // gclk 2 is now = osc8m
243+
genctrl.bit.GENEN = 1;
244+
genctrl.bit.RUNSTDBY = 0;
245+
genctrl.bit.OE = 1; // output on GCLK_IO[2] pin for debugging
246+
GCLK->GENCTRL.reg = (genctrl.reg | temp_genctrl); // set it!
247+
248+
while(GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
249+
250+
251+
#define NVM_SW_CALIB_DFLL48M_COARSE_VAL 58
252+
#define NVM_SW_CALIB_DFLL48M_FINE_VAL 64
253+
254+
// Turn on DFLL
255+
SYSCTRL_DFLLCTRL_Type dfllctrl_conf = {0};
256+
SYSCTRL_DFLLVAL_Type dfllval_conf = {0};
257+
uint32_t coarse =( *((uint32_t *)(NVMCTRL_OTP4)
258+
+ (NVM_SW_CALIB_DFLL48M_COARSE_VAL / 32))
259+
>> (NVM_SW_CALIB_DFLL48M_COARSE_VAL % 32))
260+
& ((1 << 6) - 1);
261+
if (coarse == 0x3f) {
262+
coarse = 0x1f;
263+
}
264+
uint32_t fine =( *((uint32_t *)(NVMCTRL_OTP4)
265+
+ (NVM_SW_CALIB_DFLL48M_FINE_VAL / 32))
266+
>> (NVM_SW_CALIB_DFLL48M_FINE_VAL % 32))
267+
& ((1 << 10) - 1);
268+
if (fine == 0x3ff) {
269+
fine = 0x1ff;
270+
}
271+
dfllval_conf.bit.COARSE = coarse;
272+
dfllval_conf.bit.FINE = fine;
273+
dfllctrl_conf.bit.USBCRM = 1; // usb correction
274+
dfllctrl_conf.bit.BPLCKC = 0;
275+
dfllctrl_conf.bit.QLDIS = 0;
276+
dfllctrl_conf.bit.CCDIS = 1;
277+
dfllctrl_conf.bit.ENABLE = 1;
278+
279+
SYSCTRL->DFLLCTRL.bit.ONDEMAND = 0;
280+
while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY));
281+
SYSCTRL->DFLLMUL.reg = 48000;
282+
SYSCTRL->DFLLVAL.reg = dfllval_conf.reg;
283+
SYSCTRL->DFLLCTRL.reg = dfllctrl_conf.reg;
284+
285+
//
286+
GCLK_CLKCTRL_Type clkctrl={0};
287+
uint16_t temp;
288+
GCLK->CLKCTRL.bit.ID = 2; // GCLK_ID - DFLL48M Reference
289+
temp = GCLK->CLKCTRL.reg;
290+
clkctrl.bit.CLKEN = 1;
291+
clkctrl.bit.WRTLOCK = 0;
292+
clkctrl.bit.GEN = GCLK_CLKCTRL_GEN_GCLK0_Val;
293+
GCLK->CLKCTRL.reg = (clkctrl.reg | temp);
294+
295+
// Configure DFLL48M as source for GCLK_GEN 0
296+
GCLK->GENCTRL.bit.ID = 0; // GENERATOR_ID - GCLK_GEN_0
297+
while(GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
298+
temp_genctrl = GCLK->GENCTRL.reg;
299+
genctrl.bit.SRC = GCLK_GENCTRL_SRC_DFLL48M_Val;
300+
genctrl.bit.GENEN = 1;
301+
genctrl.bit.RUNSTDBY = 0;
302+
genctrl.bit.OE = 1;
303+
GCLK->GENCTRL.reg = (genctrl.reg | temp_genctrl);
304+
while(GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
305+
306+
307+
#endif
308+
196309
while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
197310
{
198311
/* Wait for synchronization */

0 commit comments

Comments
 (0)