diff options
Diffstat (limited to 'tmk_core/protocol/arm_atsam/d51_util.c')
-rw-r--r-- | tmk_core/protocol/arm_atsam/d51_util.c | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/tmk_core/protocol/arm_atsam/d51_util.c b/tmk_core/protocol/arm_atsam/d51_util.c new file mode 100644 index 0000000000..ea42258575 --- /dev/null +++ b/tmk_core/protocol/arm_atsam/d51_util.c @@ -0,0 +1,227 @@ +#include "d51_util.h" + +static volatile uint32_t w; + +//Display unsigned 32-bit number by port toggling DBG_1 (to view on a scope) +//Read as follows: 1230 = | | | | | | || (note zero is fast double toggle) +#define DBG_PAUSE 5 +void dbg_print(uint32_t x) +{ + int8_t t; + uint32_t n; + uint32_t p, p2; + + if (x < 10) t = 0; + else if (x < 100) t = 1; + else if (x < 1000) t = 2; + else if (x < 10000) t = 3; + else if (x < 100000) t = 4; + else if (x < 1000000) t = 5; + else if (x < 10000000) t = 6; + else if (x < 100000000) t = 7; + else if (x < 1000000000) t = 8; + else t = 9; + + while (t >= 0) + { + p2 = t; + p = 1; + while (p2--) p *= 10; + n = x / p; + x -= n * p; + if (!n) + { + DBG_1_ON; + DBG_1_OFF; + DBG_1_ON; + DBG_1_OFF; + n--; + } + else + { + while (n > 0) + { + DBG_1_ON; + DBG_1_OFF; + n--; + } + } + + t--; + } + + for (w = DBG_PAUSE; w; w--); //Long pause after number is complete +} + +//Display unsigned 32-bit number through debug led +//Read as follows: 1230 = [*] [* *] [* * *] [**] (note zero is fast double flash) +#define DLED_ONTIME 1000000 +#define DLED_PAUSE 1500000 +void dled_print(uint32_t x, uint8_t long_pause) +{ + int8_t t; + uint32_t n; + uint32_t p, p2; + + if (x < 10) t = 0; + else if (x < 100) t = 1; + else if (x < 1000) t = 2; + else if (x < 10000) t = 3; + else if (x < 100000) t = 4; + else if (x < 1000000) t = 5; + else if (x < 10000000) t = 6; + else if (x < 100000000) t = 7; + else if (x < 1000000000) t = 8; + else t = 9; + + while (t >= 0) + { + p2 = t; + p = 1; + while (p2--) p *= 10; + n = x / p; + x -= n * p; + if (!n) + { + DBG_LED_ON; + for (w = DLED_ONTIME / 4; w; w--); + DBG_LED_OFF; + for (w = DLED_ONTIME / 4; w; w--); + DBG_LED_ON; + for (w = DLED_ONTIME / 4; w; w--); + DBG_LED_OFF; + for (w = DLED_ONTIME / 4; w; w--); + n--; + } + else + { + while (n > 0) + { + DBG_LED_ON; + for (w = DLED_ONTIME; w; w--); + DBG_LED_OFF; + for (w = DLED_ONTIME / 2; w; w--); + n--; + } + } + + for (w = DLED_PAUSE; w; w--); + t--; + } + + if (long_pause) + { + for (w = DLED_PAUSE * 4; w; w--); + } +} + +#ifdef DEBUG_BOOT_TRACING_ENABLE + +volatile uint32_t debug_code; + +//These macros are for compile time substitution +#define DEBUG_BOOT_TRACING_EXTINTn (DEBUG_BOOT_TRACING_PIN % _U_(0x10)) +#define DEBUG_BOOT_TRACING_EXTINTb (_U_(0x1) << DEBUG_BOOT_TRACING_EXTINTn) +#define DEBUG_BOOT_TRACING_CONFIG_INDn (DEBUG_BOOT_TRACING_EXTINTn / _U_(0x8)) +#define DEBUG_BOOT_TRACING_CONFIG_SENSEn (DEBUG_BOOT_TRACING_EXTINTn % _U_(0x8)) +#define DEBUG_BOOT_TRACING_CONFIG_SENSEb (DEBUG_BOOT_TRACING_CONFIG_SENSEn * _U_(0x4)) +#define DEBUG_BOOT_TRACING_IRQn (EIC_0_IRQn + DEBUG_BOOT_TRACING_EXTINTn) + +//These macros perform PORT+PIN definition translation to IRQn in the preprocessor +#define PORTPIN_TO_IRQn_EXPAND(def) def +#define PORTPIN_TO_IRQn_DEF(def) PORTPIN_TO_IRQn_EXPAND(def) +#if DEBUG_BOOT_TRACING_PIN < 10 +#define PORTPIN_TO_IRQn_TODEF(port, pin) PORTPIN_TO_IRQn_DEF(PIN_ ## port ## 0 ## pin ## A_EIC_EXTINT_NUM) +#else +#define PORTPIN_TO_IRQn_TODEF(port, pin) PORTPIN_TO_IRQn_DEF(PIN_ ## port ## pin ## A_EIC_EXTINT_NUM) +#endif +#define PORTPIN_TO_IRQn(port, pin) PORTPIN_TO_IRQn_TODEF(port, pin) + +//These macros perform function name output in the preprocessor +#define DEBUG_BOOT_TRACING_HANDLER_CONCAT(irq) void EIC_ ## irq ## _Handler(void) +#define DEBUG_BOOT_TRACING_HANDLER(irq) DEBUG_BOOT_TRACING_HANDLER_CONCAT(irq) + +//To generate the function name of the IRQ handler catching boot tracing, +// certain macros must be undefined, so save their current values to macro stack +#pragma push_macro("PA") +#pragma push_macro("PB") +#pragma push_macro("_L_") + +//Undefine / redefine pushed macros +#undef PA +#undef PB +#undef _L_ +#define _L_(x) x + +//Perform the work and output +//Ex: PORT PB, PIN 31 = void EIC_15_Handler(void) +DEBUG_BOOT_TRACING_HANDLER(PORTPIN_TO_IRQn(DEBUG_BOOT_TRACING_PORT, DEBUG_BOOT_TRACING_PIN)) + +//Restore macros +#pragma pop_macro("PA") +#pragma pop_macro("PB") +#pragma pop_macro("_L_") +{ + //This is only for non-functional keyboard troubleshooting and should be disabled after boot + //Intention is to lock up the keyboard here with repeating debug led code + while (1) + { + dled_print(debug_code, 1); + } +} + +void debug_code_init(void) +{ + DBGC(DC_UNSET); + + //Configure Ports for EIC + PORT->Group[DEBUG_BOOT_TRACING_PORT].DIRCLR.reg = 1 << DEBUG_BOOT_TRACING_PIN; //Input + PORT->Group[DEBUG_BOOT_TRACING_PORT].OUTSET.reg = 1 << DEBUG_BOOT_TRACING_PIN; //High + PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.INEN = 1; //Input Enable + PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PULLEN = 1; //Pull Enable + PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PMUXEN = 1; //Mux Enable + PORT->Group[DEBUG_BOOT_TRACING_PORT].PMUX[DEBUG_BOOT_TRACING_PIN / 2].bit.PMUXO = 0; //Mux A + + //Enable CLK_EIC_APB + MCLK->APBAMASK.bit.EIC_ = 1; + + //Configure EIC + EIC->CTRLA.bit.SWRST = 1; + while (EIC->SYNCBUSY.bit.SWRST) {} + EIC->ASYNCH.reg = DEBUG_BOOT_TRACING_EXTINTb; + EIC->INTENSET.reg = DEBUG_BOOT_TRACING_EXTINTb; + EIC->CONFIG[DEBUG_BOOT_TRACING_CONFIG_INDn].reg |= (EIC_CONFIG_SENSE0_FALL_Val << DEBUG_BOOT_TRACING_CONFIG_SENSEb); + EIC->CTRLA.bit.ENABLE = 1; + while (EIC->SYNCBUSY.bit.ENABLE) {} + + //Enable EIC IRQ + NVIC_EnableIRQ(DEBUG_BOOT_TRACING_IRQn); +} + +void debug_code_disable(void) +{ + //Disable EIC IRQ + NVIC_DisableIRQ(DEBUG_BOOT_TRACING_IRQn); + + //Disable EIC + EIC->CTRLA.bit.ENABLE = 0; + while (EIC->SYNCBUSY.bit.ENABLE) {} + + //Default port configuration + PORT->Group[DEBUG_BOOT_TRACING_PORT].DIRCLR.reg = 1 << DEBUG_BOOT_TRACING_PIN; //Input + PORT->Group[DEBUG_BOOT_TRACING_PORT].OUTCLR.reg = 1 << DEBUG_BOOT_TRACING_PIN; //Low + PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.INEN = 0; //Input Disable + PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PULLEN = 0; //Pull Disable + PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PMUXEN = 0; //Mux Disable + PORT->Group[DEBUG_BOOT_TRACING_PORT].PMUX[DEBUG_BOOT_TRACING_PIN / 2].bit.PMUXO = 0; //Mux A + + //Disable CLK_EIC_APB + MCLK->APBAMASK.bit.EIC_ = 0; +} + +#else + +void debug_code_init(void) {} +void debug_code_disable(void) {} + +#endif //DEBUG_BOOT_TRACING_ENABLE |