Skip to content

Commit e3f9ee8

Browse files
committed
Add frequency changing support to PWMOut.
You can either set it once up front, or set variable_frequency on custruction to indicate that the frequency must be able to change. This informs whether a timer can be shared amongst pins. This also adds persistent clock calibration on atmel-samd. Once the device has synced its clock frequency over USB it will remember that config value until USB is used again. This helps ensure the clock frequency is similar on and off USB. Lastly, this also corrects time.sleep() when on USB by correcting the tick counter.
1 parent 749d22b commit e3f9ee8

File tree

30 files changed

+701
-244
lines changed

30 files changed

+701
-244
lines changed

atmel-samd/asf/sam0/drivers/system/clock/clock_samd21_r21_da/clock.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,9 @@ static void _switch_peripheral_gclk(void)
772772
* the OSC8M default enable can be disabled after system_clock_init. Make sure the
773773
* clock switch successfully before disabling OSC8M.
774774
*/
775-
void system_clock_init(void)
775+
// Added dfll_fine_calibration as a parameter so that the user program can save
776+
// and restore it.
777+
void system_clock_init(uint16_t dfll_fine_calibration)
776778
{
777779
/* Various bits in the INTFLAG register can be set to one at startup.
778780
This will ensure that these bits are cleared */
@@ -904,7 +906,7 @@ void system_clock_init(void)
904906

905907
if (CONF_CLOCK_DFLL_LOOP_MODE == SYSTEM_CLOCK_DFLL_LOOP_MODE_USB_RECOVERY) {
906908
dfll_conf.fine_max_step = 10;
907-
dfll_conf.fine_value = 0x1ff;
909+
dfll_conf.fine_value = dfll_fine_calibration;
908910
dfll_conf.quick_lock = SYSTEM_CLOCK_DFLL_QUICK_LOCK_ENABLE;
909911
dfll_conf.stable_tracking = SYSTEM_CLOCK_DFLL_STABLE_TRACKING_TRACK_AFTER_LOCK;
910912
dfll_conf.wakeup_lock = SYSTEM_CLOCK_DFLL_WAKEUP_LOCK_KEEP;

atmel-samd/asf/sam0/drivers/system/clock/clock_samd21_r21_da/clock_feature.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1262,7 +1262,7 @@ void system_clock_source_dpll_set_config(
12621262
* @{
12631263
*/
12641264

1265-
void system_clock_init(void);
1265+
void system_clock_init(uint16_t dfll_fine_calibration);
12661266

12671267
/**
12681268
* @}

atmel-samd/asf/sam0/drivers/system/system.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@ void _system_dummy_init(void)
5959

6060
#if !defined(__DOXYGEN__)
6161
# if defined(__GNUC__)
62-
void system_clock_init(void) WEAK __attribute__((alias("_system_dummy_init")));
62+
void system_clock_init(uint16_t dfll_fine_calibration) WEAK __attribute__((alias("_system_dummy_init")));
6363
void system_board_init(void) WEAK __attribute__((alias("_system_dummy_init")));
6464
void _system_events_init(void) WEAK __attribute__((alias("_system_dummy_init")));
6565
void _system_extint_init(void) WEAK __attribute__((alias("_system_dummy_init")));
6666
void _system_divas_init(void) WEAK __attribute__((alias("_system_dummy_init")));
6767
# elif defined(__ICCARM__)
68-
void system_clock_init(void);
68+
void system_clock_init(uint16_t dfll_fine_calibration);
6969
void system_board_init(void);
7070
void _system_events_init(void);
7171
void _system_extint_init(void);
@@ -91,10 +91,10 @@ void _system_divas_init(void);
9191
* - Event system driver initialization (via the EVSYS module)
9292
* - External Interrupt driver initialization (via the EXTINT module)
9393
*/
94-
void system_init(void)
94+
void system_init(uint16_t dfll_fine_calibration)
9595
{
9696
/* Configure GCLK and clock sources according to conf_clocks.h */
97-
system_clock_init();
97+
system_clock_init(dfll_fine_calibration);
9898

9999
/* Initialize board hardware */
100100
system_board_init();
@@ -104,8 +104,7 @@ void system_init(void)
104104

105105
/* Initialize External hardware */
106106
_system_extint_init();
107-
107+
108108
/* Initialize DIVAS hardware */
109109
_system_divas_init();
110110
}
111-

atmel-samd/asf/sam0/drivers/system/system.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ static inline uint32_t system_get_device_id(void)
555555
* @{
556556
*/
557557

558-
void system_init(void);
558+
void system_init(uint16_t dfll_fine_calibration);
559559

560560
/**
561561
* @}
@@ -725,4 +725,3 @@ void system_init(void);
725725
#endif
726726

727727
#endif /* SYSTEM_H_INCLUDED */
728-

atmel-samd/asf/sam0/drivers/tc/tc_sam_d_r/tc.c

Lines changed: 82 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ enum status_code tc_init(
140140
/* Array of PM APBC mask bit position for different TC instances */
141141
uint16_t inst_pm_apbmask[] = TC_INST_PM_APBCMASK;
142142

143-
struct system_pinmux_config pin_config;
143+
//struct system_pinmux_config pin_config;
144144
struct system_gclk_chan_config gclk_chan_config;
145145

146146
#if TC_ASYNC == true
@@ -169,15 +169,15 @@ enum status_code tc_init(
169169
return STATUS_ERR_INVALID_ARG;
170170
}
171171
#else
172-
/* Check if odd numbered TC modules are being configured in 32-bit
173-
* counter size. Only even numbered counters are allowed to be
174-
* configured in 32-bit counter size.
175-
*/
176-
if ((config->counter_size == TC_COUNTER_SIZE_32BIT) &&
177-
((instance + TC_INSTANCE_OFFSET) & 0x01)) {
178-
Assert(false);
179-
return STATUS_ERR_INVALID_ARG;
180-
}
172+
// /* Check if odd numbered TC modules are being configured in 32-bit
173+
// * counter size. Only even numbered counters are allowed to be
174+
// * configured in 32-bit counter size.
175+
// */
176+
// if ((config->counter_size == TC_COUNTER_SIZE_32BIT) &&
177+
// ((instance + TC_INSTANCE_OFFSET) & 0x01)) {
178+
// Assert(false);
179+
// return STATUS_ERR_INVALID_ARG;
180+
// }
181181
#endif
182182

183183
/* Make the counter size variable in the module_inst struct reflect
@@ -200,35 +200,35 @@ enum status_code tc_init(
200200
return STATUS_ERR_DENIED;
201201
}
202202

203-
/* Set up the TC PWM out pin for channel 0 */
204-
if (config->pwm_channel[0].enabled) {
205-
system_pinmux_get_config_defaults(&pin_config);
206-
pin_config.mux_position = config->pwm_channel[0].pin_mux;
207-
pin_config.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT;
208-
system_pinmux_pin_set_config(
209-
config->pwm_channel[0].pin_out, &pin_config);
210-
}
211-
212-
/* Set up the TC PWM out pin for channel 1 */
213-
if (config->pwm_channel[1].enabled) {
214-
system_pinmux_get_config_defaults(&pin_config);
215-
pin_config.mux_position = config->pwm_channel[1].pin_mux;
216-
pin_config.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT;
217-
system_pinmux_pin_set_config(
218-
config->pwm_channel[1].pin_out, &pin_config);
219-
}
203+
// /* Set up the TC PWM out pin for channel 0 */
204+
// if (config->pwm_channel[0].enabled) {
205+
// system_pinmux_get_config_defaults(&pin_config);
206+
// pin_config.mux_position = config->pwm_channel[0].pin_mux;
207+
// pin_config.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT;
208+
// system_pinmux_pin_set_config(
209+
// config->pwm_channel[0].pin_out, &pin_config);
210+
// }
211+
//
212+
// /* Set up the TC PWM out pin for channel 1 */
213+
// if (config->pwm_channel[1].enabled) {
214+
// system_pinmux_get_config_defaults(&pin_config);
215+
// pin_config.mux_position = config->pwm_channel[1].pin_mux;
216+
// pin_config.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT;
217+
// system_pinmux_pin_set_config(
218+
// config->pwm_channel[1].pin_out, &pin_config);
219+
// }
220220

221221
/* Enable the user interface clock in the PM */
222222
system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC,
223223
inst_pm_apbmask[instance]);
224224

225-
/* Enable the slave counter if counter_size is 32-bit */
226-
if ((config->counter_size == TC_COUNTER_SIZE_32BIT))
227-
{
228-
/* Enable the user interface clock in the PM */
229-
system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC,
230-
inst_pm_apbmask[instance + 1]);
231-
}
225+
// /* Enable the slave counter if counter_size is 32-bit */
226+
// if ((config->counter_size == TC_COUNTER_SIZE_32BIT))
227+
// {
228+
// /* Enable the user interface clock in the PM */
229+
// system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC,
230+
// inst_pm_apbmask[instance + 1]);
231+
// }
232232

233233
/* Setup clock for module */
234234
system_gclk_chan_get_config_defaults(&gclk_chan_config);
@@ -299,34 +299,34 @@ enum status_code tc_init(
299299
/* Switch for TC counter size */
300300
switch (module_inst->counter_size) {
301301
case TC_COUNTER_SIZE_8BIT:
302-
while (tc_is_syncing(module_inst)) {
303-
/* Wait for sync */
304-
}
305-
306-
hw->COUNT8.COUNT.reg =
307-
config->counter_8_bit.value;
308-
309-
310-
while (tc_is_syncing(module_inst)) {
311-
/* Wait for sync */
312-
}
313-
314-
hw->COUNT8.PER.reg =
315-
config->counter_8_bit.period;
316-
317-
while (tc_is_syncing(module_inst)) {
318-
/* Wait for sync */
319-
}
320-
321-
hw->COUNT8.CC[0].reg =
322-
config->counter_8_bit.compare_capture_channel[0];
323-
324-
while (tc_is_syncing(module_inst)) {
325-
/* Wait for sync */
326-
}
327-
328-
hw->COUNT8.CC[1].reg =
329-
config->counter_8_bit.compare_capture_channel[1];
302+
// while (tc_is_syncing(module_inst)) {
303+
// /* Wait for sync */
304+
// }
305+
//
306+
// hw->COUNT8.COUNT.reg =
307+
// config->counter_8_bit.value;
308+
//
309+
//
310+
// while (tc_is_syncing(module_inst)) {
311+
// /* Wait for sync */
312+
// }
313+
//
314+
// hw->COUNT8.PER.reg =
315+
// config->counter_8_bit.period;
316+
//
317+
// while (tc_is_syncing(module_inst)) {
318+
// /* Wait for sync */
319+
// }
320+
//
321+
// hw->COUNT8.CC[0].reg =
322+
// config->counter_8_bit.compare_capture_channel[0];
323+
//
324+
// while (tc_is_syncing(module_inst)) {
325+
// /* Wait for sync */
326+
// }
327+
//
328+
// hw->COUNT8.CC[1].reg =
329+
// config->counter_8_bit.compare_capture_channel[1];
330330

331331
return STATUS_OK;
332332

@@ -355,26 +355,26 @@ enum status_code tc_init(
355355
return STATUS_OK;
356356

357357
case TC_COUNTER_SIZE_32BIT:
358-
while (tc_is_syncing(module_inst)) {
359-
/* Wait for sync */
360-
}
361-
362-
hw->COUNT32.COUNT.reg
363-
= config->counter_32_bit.value;
364-
365-
while (tc_is_syncing(module_inst)) {
366-
/* Wait for sync */
367-
}
368-
369-
hw->COUNT32.CC[0].reg =
370-
config->counter_32_bit.compare_capture_channel[0];
371-
372-
while (tc_is_syncing(module_inst)) {
373-
/* Wait for sync */
374-
}
375-
376-
hw->COUNT32.CC[1].reg =
377-
config->counter_32_bit.compare_capture_channel[1];
358+
// while (tc_is_syncing(module_inst)) {
359+
// /* Wait for sync */
360+
// }
361+
//
362+
// hw->COUNT32.COUNT.reg
363+
// = config->counter_32_bit.value;
364+
//
365+
// while (tc_is_syncing(module_inst)) {
366+
// /* Wait for sync */
367+
// }
368+
//
369+
// hw->COUNT32.CC[0].reg =
370+
// config->counter_32_bit.compare_capture_channel[0];
371+
//
372+
// while (tc_is_syncing(module_inst)) {
373+
// /* Wait for sync */
374+
// }
375+
//
376+
// hw->COUNT32.CC[1].reg =
377+
// config->counter_32_bit.compare_capture_channel[1];
378378

379379
return STATUS_OK;
380380
}

atmel-samd/asf/sam0/drivers/tcc/tcc.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -324,12 +324,12 @@ static inline void _tcc_build_ctrlb(
324324
{
325325
uint8_t ctrlb = 0;
326326

327-
if (config->counter.oneshot) {
328-
ctrlb |= TCC_CTRLBSET_ONESHOT;
329-
}
330-
if (config->counter.direction == TCC_COUNT_DIRECTION_DOWN) {
331-
ctrlb |= TCC_CTRLBSET_DIR;
332-
}
327+
// if (config->counter.oneshot) {
328+
// ctrlb |= TCC_CTRLBSET_ONESHOT;
329+
// }
330+
// if (config->counter.direction == TCC_COUNT_DIRECTION_DOWN) {
331+
// ctrlb |= TCC_CTRLBSET_DIR;
332+
// }
333333

334334
*value_buffer = ctrlb;
335335
}
@@ -606,18 +606,18 @@ enum status_code tcc_init(
606606
system_gclk_chan_enable(_tcc_gclk_ids[module_index]);
607607

608608
/* Initialize pins */
609-
struct system_pinmux_config pin_config;
610-
for (i = 0; i < _tcc_ow_nums[module_index]; i ++) {
611-
if (!config->pins.enable_wave_out_pin[i]) {
612-
continue;
613-
}
614-
615-
system_pinmux_get_config_defaults(&pin_config);
616-
pin_config.mux_position = config->pins.wave_out_pin_mux[i];
617-
pin_config.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT;
618-
system_pinmux_pin_set_config(
619-
config->pins.wave_out_pin[i], &pin_config);
620-
}
609+
// struct system_pinmux_config pin_config;
610+
// for (i = 0; i < _tcc_ow_nums[module_index]; i ++) {
611+
// if (!config->pins.enable_wave_out_pin[i]) {
612+
// continue;
613+
// }
614+
//
615+
// system_pinmux_get_config_defaults(&pin_config);
616+
// pin_config.mux_position = config->pins.wave_out_pin_mux[i];
617+
// pin_config.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT;
618+
// system_pinmux_pin_set_config(
619+
// config->pins.wave_out_pin[i], &pin_config);
620+
// }
621621

622622
/* Write to registers */
623623

atmel-samd/asf/sam0/utils/cmsis/samd21/source/gcc/startup_samd21.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
extern uint32_t _sfixed;
5050
extern uint32_t _efixed;
5151
extern uint32_t _etext;
52+
extern uint32_t _sidata;
5253
extern uint32_t _srelocate;
5354
extern uint32_t _erelocate;
5455
extern uint32_t _szero;
@@ -233,7 +234,7 @@ void Reset_Handler(void)
233234
uint32_t *pSrc, *pDest;
234235

235236
/* Initialize the relocate segment */
236-
pSrc = &_etext;
237+
pSrc = &_sidata;
237238
pDest = &_srelocate;
238239

239240
if (pSrc != pDest) {

atmel-samd/boards/gemma_m0/mpconfigboard.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#define USB_REPL
22

3-
#define MICROPY_HW_BOARD_NAME "Adafruit Gemma M0 (Experimental)"
3+
#define MICROPY_HW_BOARD_NAME "Adafruit Gemma M0"
44
#define MICROPY_HW_MCU_NAME "samd21e18"
55

66
#define MICROPY_HW_APA102_MOSI &pin_PA04

atmel-samd/boards/metro_m0_flash/mpconfigboard.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
LD_FILE = boards/samd21x18-bootloader-external-flash.ld
1+
LD_FILE = boards/samd21x18-external-flash.ld
22
USB_VID = 0x239A
33
USB_PID = 0x8015
44

atmel-samd/boards/samd21x18-bootloader-external-flash.ld

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/* Specify the memory areas */
66
MEMORY
77
{
8-
FLASH (rx) : ORIGIN = 0x00000000 + 0x2000, LENGTH = 0x00040000 - 0x2000 /* Leave 8KiB for the bootloader. */
8+
FLASH (rx) : ORIGIN = 0x00000000 + 0x2000, LENGTH = 0x00040000 - 0x2000 - 0x100 /* Leave 8KiB for the bootloader and 256b for config. */
99
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x008000 /* 32 KiB */
1010
}
1111

@@ -28,9 +28,14 @@ SECTIONS
2828

2929
. = ALIGN(4);
3030
_etext = .; /* define a global symbol at end of code */
31-
_sidata = _etext; /* This is used by the startup in order to initialize the .data secion */
3231
} >FLASH
3332

33+
.ARM.exidx :
34+
{
35+
*(.ARM.exidx*)
36+
*(.gnu.linkonce.armexidx.*)
37+
_sidata = .; /* This is used by the startup in order to initialize the .data section */
38+
} > FLASH
3439

3540
/* This is the initialized data section
3641
The program executes knowing that the data is in the RAM

0 commit comments

Comments
 (0)