address review comments; avoid affecting double-click

This commit is contained in:
Dan Halbert 2020-04-01 17:15:54 -04:00
parent a346c82e2d
commit 291610433b
5 changed files with 56 additions and 22 deletions

View file

@ -290,6 +290,12 @@ void delay(uint32_t ms);
void hidHandoverLoop(int ep);
void handoverPrep(void);
// Useful for debugging.
#ifdef BLINK_DEBUG
void blink_n(uint32_t pin, uint32_t n, uint32_t interval);
void blink_n_forever(uint32_t pin, uint32_t n, uint32_t interval);
#endif
#define CONCAT_1(a, b) a##b
#define CONCAT_0(a, b) CONCAT_1(a, b)
#define STATIC_ASSERT(e) enum { CONCAT_0(_static_assert_, __LINE__) = 1 / ((e) ? 1 : 0) }

View file

@ -7,7 +7,7 @@
volatile bool g_interrupt_enabled = true;
// SAMD51 starts at 1MHz by default.
// SAMD21 starts at 1MHz by default.
uint32_t current_cpu_frequency_MHz = 1;
static void gclk_sync(void) {

View file

@ -82,7 +82,8 @@ void system_init(void) {
MCLK->CPUDIV.reg = MCLK_CPUDIV_DIV_DIV1;
SysTick_Config(1000);
current_cpu_frequency_MHz = 48;
// No change from initial frequency.
// current_cpu_frequency_MHz = 48;
}
void SysTick_Handler(void) { LED_TICK(); }

View file

@ -29,11 +29,11 @@
/**
* --------------------
* SAM-BA Implementation on SAMD21
* SAM-BA Implementation on SAMD21 and SAMD51
* --------------------
* Requirements to use SAM-BA :
*
* Supported communication interfaces :
* Supported communication interfaces (SAMD21):
* --------------------
*
* SERCOM5 : RX:PB23 TX:PB22
@ -68,8 +68,6 @@
*
* Applications compiled to be executed along with the bootloader will start at
* 0x2000 (samd21) or 0x4000 (samd51)
* The bootloader doesn't changes the VTOR register, application code is
* taking care of this.
*
*/
@ -110,7 +108,7 @@ static void check_start_application(void) {
if (RESET_CONTROLLER->RCAUSE.bit.POR || *DBL_TAP_PTR != DBL_TAP_MAGIC_QUICK_BOOT) {
// the second tap on reset will go into app
*DBL_TAP_PTR = DBL_TAP_MAGIC_QUICK_BOOT;
// this will be cleared after succesful USB enumeration
// this will be cleared after successful USB enumeration
// this is around 1.5s
resetHorizon = timerHigh + 50;
return;
@ -150,7 +148,7 @@ extern char _etext;
extern char _end;
/**
* \brief SAMD21 SAM-BA Main loop.
* \brief SAM-BA Main loop.
* \return Unused (ANSI-C compatibility).
*/
int main(void) {
@ -181,8 +179,17 @@ int main(void) {
while (SUPC->STATUS.bit.BOD33DET) {
// Wait for voltage to rise above BOD33 value.
}
// Wait 100ms for voltage to stabilize.
// If we are starting from a power-on or a brownout,
// wait for the voltage to stabilize. Don't do this on an
// external reset because it interferes with the timing of double-click.
// "BODVDD" means BOD33.
if (RSTC->RCAUSE.bit.POR || RSTC->RCAUSE.bit.BODVDD) {
do {
// Check again in 100ms.
delay(100);
} while (SUPC->STATUS.bit.BOD33DET);
}
// Now enable reset if voltage falls below minimum.
SUPC->BOD33.bit.ENABLE = 0;
@ -190,7 +197,6 @@ int main(void) {
SUPC->BOD33.bit.ENABLE = 1;
#endif
#if USB_VID == 0x239a && USB_PID == 0x0013 // Adafruit Metro M0
// Delay a bit so SWD programmer can have time to attach.
delay(15);

View file

@ -4,27 +4,48 @@
static uint32_t timerLow;
uint32_t timerHigh, resetHorizon;
void delay(uint32_t ms) {
void __attribute__ ((noinline)) delay(uint32_t ms) {
// These multipliers were determined empirically and are only approximate.
// After the pulsing LED is enabled (led_tick_on), the multipliers need to change
// due to the interrupt overhead of the pulsing.
// SAMD21 starts up at 1MHz by default.
#ifdef SAMD21
uint32_t count = ms * 167 * (current_cpu_frequency_MHz);
uint32_t count = ms * (current_cpu_frequency_MHz) * (led_tick_on ? 149: 167);
#endif
#ifdef SAMD51
// SAMD51 starts up at 48MHz by default, and we set the clock to
// 48MHz, so we don't need to adjust for current_cpu_frequency_MHz.
uint32_t count = ms * 6000;
// On SAMD51, before the 1ms SysTick interrupts are set up, the
// timing loop will run about twice as fast, so double the count.
if (led_tick_on) {
count *= 2;
}
uint32_t count = ms * (led_tick_on ? 6353 : 6826);
#endif
for (int i = 1; i < count; ++i) {
for (uint32_t i = 1; i < count; ++i) {
asm volatile("");
}
}
// Useful for debugging.
// PIN_PA19 is D12 on Metro M0, D11 on Metro M4
#ifdef BLINK_DEBUG
void blink_n(uint32_t pin, uint32_t n, uint32_t interval) {
// Start out off.
PINOP(pin, DIRSET);
PINOP(pin, OUTCLR);
delay(interval);
for (int i = 0; i < n; ++i) {
PINOP(pin, OUTSET);
delay(interval);
PINOP(pin, OUTCLR);
delay(interval);
}
}
void blink_n_forever(uint32_t pin, uint32_t n, uint32_t interval) {
while(1) {
blink_n(pin, n, interval);
delay(interval*5);
}
}
#endif
void timerTick(void) {
if (timerLow-- == 0) {
timerLow = TIMER_STEP;