~ruther/qmk_firmware

4a5e68f4f29b0c4c75a68b5958dff197f4ac0f53 — patrickmt 6 years ago e99615b
Bringing Massdrop keyboard hardware configuration to keyboard level (#4593)

MCU Pins for debugging, LED, boot tracing, and shift registers are now configurable at keyboard level.
Macros led_* replaced by DBG_LED_*
Macros m15_* replaced by DBG_1_*
Macros m27_* replaced by DBG_2_*
Macros m28_* replaced by DBG_3_*
For CTRL and ALT keyboards, debug boot tracing pin default now set to pad M27 instead of M28 since although M28 is not being used, it is technically a signal for USB port detection.
m15_print(...) renamed to dbg_print(...) to get away from hard coded port names.
dbg_print function now follows similar pattern to debug led output.
M keyboards/massdrop/alt/config.h => keyboards/massdrop/alt/config.h +49 -2
@@ 32,17 32,64 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
#define MATRIX_ROWS 5
#define MATRIX_COLS 15

/* MCU Port name definitions */
#define PA 0
#define PB 1

/* Port and Pin definition of key row hardware configuration */
#define MATRIX_ROW_PORTS PA, PA, PA, PA, PA
#define MATRIX_ROW_PINS   0,  1,  2,  3,  4

/* Port and Pin definition of key column hardware configuration */
#define MATRIX_COL_PORTS PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PA, PA, PA, PA, PA
#define MATRIX_COL_PINS   4,  5,  6,  7,  8,  9, 10, 11, 12, 13,  5,  6,  7, 10, 11

/* Print boot debug codes using debug LED when M28 and M30 shorted */
#define DEBUG_BOOT_TRACING
/* This Shift Register expands available hardware output lines to control additional peripherals */
/* It uses four lines from the MCU to provide 16 output lines */
/* Shift Register Clock configuration (MCU to ShiftRegister.RCLK) */
#define SR_EXP_RCLK_PORT            PB
#define SR_EXP_RCLK_PIN             14
/* Shift Register Output Enable configuration (MCU to ShiftRegister.OE_N) */
#define SR_EXP_OE_N_PORT            PB
#define SR_EXP_OE_N_PIN             15
/* SERCOM port to use for Shift Register SPI */
/* DATAOUT and SCLK must be configured to use hardware pins of this port */
#define SR_EXP_SERCOM               SERCOM2
/* Shift Register SPI Data Out configuration (MCU.SERCOMx.PAD[0] to ShiftRegister.SER) */
#define SR_EXP_DATAOUT_PORT         PA
#define SR_EXP_DATAOUT_PIN          12
#define SR_EXP_DATAOUT_MUX          2
/* Shift Register SPI Serial Clock configuration (MCU.SERCOMx.PAD[1] to ShiftRegister.SRCLK) */
#define SR_EXP_SCLK_PORT            PA
#define SR_EXP_SCLK_PIN             13
#define SR_EXP_SCLK_MUX             2

/* Debug LED (Small LED Located near MCU) */
#define DEBUG_LED_ENABLE            1
#define DEBUG_LED_PORT              PA
#define DEBUG_LED_PIN               27

/* Additional debugging ports */
/* PCB M21 */
#define DEBUG_PORT1_ENABLE          1
#define DEBUG_PORT1_PORT            PB
#define DEBUG_PORT1_PIN             3
/* PCB M23 */
#define DEBUG_PORT2_ENABLE          1
#define DEBUG_PORT2_PORT            PB
#define DEBUG_PORT2_PIN             17
/* PCB M25 */
#define DEBUG_PORT3_ENABLE          1
#define DEBUG_PORT3_PORT            PA
#define DEBUG_PORT3_PIN             20

/* Debug Boot Tracing - During boot sequence, ground this pin to halt and display debug code using Debug LED */
/* This is useful in determining which hardware device may have malfunctioned or is improperly configured */
/* Feature is automatically disabled after successful boot */
/* PCB M27 */
#define DEBUG_BOOT_TRACING_ENABLE   1
#define DEBUG_BOOT_TRACING_PORT     PB
#define DEBUG_BOOT_TRACING_PIN      23

/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCING_DELAY 5

M keyboards/massdrop/alt/matrix.c => keyboards/massdrop/alt/matrix.c +3 -3
@@ 75,7 75,7 @@ void matrix_init(void)
        PORT->Group[col_ports[col]].DIRSET.reg = 1 << col_pins[col]; //Output
        PORT->Group[col_ports[col]].OUTCLR.reg = 1 << col_pins[col]; //Low
    }
    

    matrix_init_quantum();
}



@@ 91,7 91,7 @@ uint8_t matrix_scan(void)

    if (CLK_get_ms() < mdebouncing) return 1; //mdebouncing == 0 when no debouncing active

    //m15_off; //Profiling scans
    //DBG_1_OFF; //Profiling scans

    memset(mlatest, 0, MATRIX_ROWS * sizeof(matrix_row_t)); //Zero the result buffer



@@ 135,7 135,7 @@ uint8_t matrix_scan(void)
        mdebouncing = CLK_get_ms() + DEBOUNCING_DELAY;
    }

    //m15_on; //Profiling scans
    //DBG_1_ON; //Profiling scans

    matrix_scan_quantum();


M keyboards/massdrop/ctrl/config.h => keyboards/massdrop/ctrl/config.h +49 -2
@@ 32,17 32,64 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
#define MATRIX_ROWS 11
#define MATRIX_COLS 8

/* MCU Port name definitions */
#define PA 0
#define PB 1

/* Port and Pin definition of key row hardware configuration */
#define MATRIX_ROW_PORTS PB, PB, PB, PB, PB, PB, PA, PA, PB, PB, PB
#define MATRIX_ROW_PINS   4,  5,  6,  7,  8,  9, 10, 11, 10, 11, 12

/* Port and Pin definition of key column hardware configuration */
#define MATRIX_COL_PORTS PA, PA, PA, PA, PA, PA, PA, PA
#define MATRIX_COL_PINS   0,  1,  2,  3,  4,  5,  6,  7

/* Print boot debug codes using debug LED when M28 and M30 shorted */
#define DEBUG_BOOT_TRACING
/* This Shift Register expands available hardware output lines to control additional peripherals */
/* It uses four lines from the MCU to provide 16 output lines */
/* Shift Register Clock configuration (MCU to ShiftRegister.RCLK) */
#define SR_EXP_RCLK_PORT            PB
#define SR_EXP_RCLK_PIN             14
/* Shift Register Output Enable configuration (MCU to ShiftRegister.OE_N) */
#define SR_EXP_OE_N_PORT            PB
#define SR_EXP_OE_N_PIN             15
/* SERCOM port to use for Shift Register SPI */
/* DATAOUT and SCLK must be configured to use hardware pins of this port */
#define SR_EXP_SERCOM               SERCOM2
/* Shift Register SPI Data Out configuration (MCU.SERCOMx.PAD[0] to ShiftRegister.SER) */
#define SR_EXP_DATAOUT_PORT         PA
#define SR_EXP_DATAOUT_PIN          12
#define SR_EXP_DATAOUT_MUX          2
/* Shift Register SPI Serial Clock configuration (MCU.SERCOMx.PAD[1] to ShiftRegister.SRCLK) */
#define SR_EXP_SCLK_PORT            PA
#define SR_EXP_SCLK_PIN             13
#define SR_EXP_SCLK_MUX             2

/* Debug LED (Small LED Located near MCU) */
#define DEBUG_LED_ENABLE            1
#define DEBUG_LED_PORT              PA
#define DEBUG_LED_PIN               27

/* Additional debugging ports */
/* PCB M21 */
#define DEBUG_PORT1_ENABLE          1
#define DEBUG_PORT1_PORT            PB
#define DEBUG_PORT1_PIN             3
/* PCB M23 */
#define DEBUG_PORT2_ENABLE          1
#define DEBUG_PORT2_PORT            PB
#define DEBUG_PORT2_PIN             17
/* PCB M25 */
#define DEBUG_PORT3_ENABLE          1
#define DEBUG_PORT3_PORT            PA
#define DEBUG_PORT3_PIN             20

/* Debug Boot Tracing - During boot sequence, ground this pin to halt and display debug code using Debug LED */
/* This is useful in determining which hardware device may have malfunctioned or is improperly configured */
/* Feature is automatically disabled after successful boot */
/* PCB M27 */
#define DEBUG_BOOT_TRACING_ENABLE   1
#define DEBUG_BOOT_TRACING_PORT     PB
#define DEBUG_BOOT_TRACING_PIN      23

/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCING_DELAY 5

M keyboards/massdrop/ctrl/matrix.c => keyboards/massdrop/ctrl/matrix.c +3 -3
@@ 75,7 75,7 @@ void matrix_init(void)
        PORT->Group[col_ports[col]].DIRSET.reg = 1 << col_pins[col]; //Output
        PORT->Group[col_ports[col]].OUTCLR.reg = 1 << col_pins[col]; //Low
    }
    

    matrix_init_quantum();
}



@@ 91,7 91,7 @@ uint8_t matrix_scan(void)

    if (CLK_get_ms() < mdebouncing) return 1; //mdebouncing == 0 when no debouncing active

    //m15_off; //Profiling scans
    //DBG_1_OFF; //Profiling scans

    memset(mlatest, 0, MATRIX_ROWS * sizeof(matrix_row_t)); //Zero the result buffer



@@ 135,7 135,7 @@ uint8_t matrix_scan(void)
        mdebouncing = CLK_get_ms() + DEBOUNCING_DELAY;
    }

    //m15_on; //Profiling scans
    //DBG_1_ON; //Profiling scans

    matrix_scan_quantum();


M tmk_core/protocol/arm_atsam/d51_util.c => tmk_core/protocol/arm_atsam/d51_util.c +93 -31
@@ 1,8 1,11 @@
#include "d51_util.h"

//Display unsigned 32-bit number through m15
//Read as follows: 1230 = || ||| |||| |  (note always ending toggle)
void m15_print(uint32_t x)
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;


@@ 26,24 29,34 @@ void m15_print(uint32_t x)
        while (p2--) p *= 10;
        n = x / p;
        x -= n * p;
        while (n > 0)
        if (!n)
        {
            m15_on;
            DBG_1_ON;
            DBG_1_OFF;
            DBG_1_ON;
            DBG_1_OFF;
            n--;
            m15_off;
        }
        //Will always end with an extra toggle
        m15_on;
        else
        {
            while (n > 0)
            {
                DBG_1_ON;
                DBG_1_OFF;
                n--;
            }
        }

        t--;
        m15_off;
    }

    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
volatile uint32_t w;
void dled_print(uint32_t x, uint8_t long_pause)
{
    int8_t t;


@@ 70,13 83,13 @@ void dled_print(uint32_t x, uint8_t long_pause)
        x -= n * p;
        if (!n)
        {
            led_on;
            DBG_LED_ON;
            for (w = DLED_ONTIME / 4; w; w--);
            led_off;
            DBG_LED_OFF;
            for (w = DLED_ONTIME / 4; w; w--);
            led_on;
            DBG_LED_ON;
            for (w = DLED_ONTIME / 4; w; w--);
            led_off;
            DBG_LED_OFF;
            for (w = DLED_ONTIME / 4; w; w--);
            n--;
        }


@@ 84,9 97,9 @@ void dled_print(uint32_t x, uint8_t long_pause)
        {
            while (n > 0)
            {
                led_on;
                DBG_LED_ON;
                for (w = DLED_ONTIME; w; w--);
                led_off;
                DBG_LED_OFF;
                for (w = DLED_ONTIME / 2; w; w--);
                n--;
            }


@@ 102,11 115,52 @@ void dled_print(uint32_t x, uint8_t long_pause)
    }
}

#ifdef DEBUG_BOOT_TRACING
#ifdef DEBUG_BOOT_TRACING_ENABLE

volatile uint32_t debug_code;

void EIC_15_Handler()
//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


@@ 120,13 174,13 @@ void debug_code_init(void)
{
    DBGC(DC_UNSET);

    //Configure Ports for EIC on PB31
    PORT->Group[1].DIRCLR.reg = 1 << 31; //Input
    PORT->Group[1].OUTSET.reg = 1 << 31; //High
    PORT->Group[1].PINCFG[31].bit.INEN = 1; //Input Enable
    PORT->Group[1].PINCFG[31].bit.PULLEN = 1; //Pull Enable
    PORT->Group[1].PINCFG[31].bit.PMUXEN = 1; //Mux Enable
    PORT->Group[1].PMUX[15].bit.PMUXO = 0; //Mux A
    //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;


@@ 134,25 188,33 @@ void debug_code_init(void)
    //Configure EIC
    EIC->CTRLA.bit.SWRST = 1;
    while (EIC->SYNCBUSY.bit.SWRST) {}
    EIC->ASYNCH.reg = 1 << 15;
    EIC->INTENSET.reg = 1 << 15;
    EIC->CONFIG[1].bit.SENSE7 = 2;
    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(EIC_15_IRQn);
    NVIC_EnableIRQ(DEBUG_BOOT_TRACING_IRQn);
}

void debug_code_disable(void)
{
    //Disable EIC IRQ
    NVIC_DisableIRQ(EIC_15_IRQn);
    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;
}


@@ 162,4 224,4 @@ void debug_code_disable(void)
void debug_code_init(void) {}
void debug_code_disable(void) {}

#endif //DEBUG_BOOT_TRACING
#endif //DEBUG_BOOT_TRACING_ENABLE

M tmk_core/protocol/arm_atsam/d51_util.h => tmk_core/protocol/arm_atsam/d51_util.h +54 -26
@@ 20,37 20,65 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include "samd51j18a.h"

//TODO: PS: Should bring these ports out to keyboard level configuration

//Debug LED PA27
#define led_ena REG_PORT_DIRSET0 = 0x08000000 //PA27 Output
#define led_on  REG_PORT_OUTSET0 = 0x08000000 //PA27 High
#define led_off REG_PORT_OUTCLR0 = 0x08000000 //PA27 Low

//Debug Port PB30
#define m15_ena REG_PORT_DIRSET1 = 0x40000000 //PB30 Output
#define m15_on  REG_PORT_OUTSET1 = 0x40000000 //PB30 High
#define m15_off REG_PORT_OUTCLR1 = 0x40000000 //PB30 Low

//Debug Port PB23
#define m27_ena REG_PORT_DIRSET1 = 0x800000 //PB23 Output
#define m27_on  REG_PORT_OUTSET1 = 0x800000 //PB23 High
#define m27_off REG_PORT_OUTCLR1 = 0x800000 //PB23 Low

//Debug Port PB31
#define m28_ena REG_PORT_DIRSET1 = 0x80000000 //PB31 Output
#define m28_on  REG_PORT_OUTSET1 = 0x80000000 //PB31 High
#define m28_off REG_PORT_OUTCLR1 = 0x80000000 //PB31 Low

#define m15_loop(M15X) {uint8_t M15L=M15X; while(M15L--){m15_on;CLK_delay_us(1);m15_off;}}
/* Debug LED */
#if DEBUG_LED_ENABLE == 1
#define DBG_LED_ENA PORT->Group[DEBUG_LED_PORT].DIRSET.reg = (1 << DEBUG_LED_PIN)
#define DBG_LED_DIS PORT->Group[DEBUG_LED_PORT].DIRCLR.reg = (1 << DEBUG_LED_PIN)
#define DBG_LED_ON  PORT->Group[DEBUG_LED_PORT].OUTSET.reg = (1 << DEBUG_LED_PIN)
#define DBG_LED_OFF PORT->Group[DEBUG_LED_PORT].OUTCLR.reg = (1 << DEBUG_LED_PIN)
#else
#define DBG_LED_ENA
#define DBG_LED_DIS
#define DBG_LED_ON
#define DBG_LED_OFF
#endif

/* Debug Port 1 */
#if DEBUG_PORT1_ENABLE == 1
#define DBG_1_ENA PORT->Group[DEBUG_PORT1_PORT].DIRSET.reg = (1 << DEBUG_PORT1_PIN)
#define DBG_1_DIS PORT->Group[DEBUG_PORT1_PORT].DIRCLR.reg = (1 << DEBUG_PORT1_PIN)
#define DBG_1_ON  PORT->Group[DEBUG_PORT1_PORT].OUTSET.reg = (1 << DEBUG_PORT1_PIN)
#define DBG_1_OFF PORT->Group[DEBUG_PORT1_PORT].OUTCLR.reg = (1 << DEBUG_PORT1_PIN)
#else
#define DBG_1_ENA
#define DBG_1_DIS
#define DBG_1_ON 
#define DBG_1_OFF
#endif

/* Debug Port 2 */
#if DEBUG_PORT2_ENABLE == 1
#define DBG_2_ENA PORT->Group[DEBUG_PORT2_PORT].DIRSET.reg = (1 << DEBUG_PORT2_PIN)
#define DBG_2_DIS PORT->Group[DEBUG_PORT2_PORT].DIRCLR.reg = (1 << DEBUG_PORT2_PIN)
#define DBG_2_ON  PORT->Group[DEBUG_PORT2_PORT].OUTSET.reg = (1 << DEBUG_PORT2_PIN)
#define DBG_2_OFF PORT->Group[DEBUG_PORT2_PORT].OUTCLR.reg = (1 << DEBUG_PORT2_PIN)
#else
#define DBG_2_ENA
#define DBG_2_DIS
#define DBG_2_ON 
#define DBG_2_OFF
#endif

/* Debug Port 3 */
#if DEBUG_PORT3_ENABLE == 1
#define DBG_3_ENA PORT->Group[DEBUG_PORT3_PORT].DIRSET.reg = (1 << DEBUG_PORT3_PIN)
#define DBG_3_DIS PORT->Group[DEBUG_PORT3_PORT].DIRCLR.reg = (1 << DEBUG_PORT3_PIN)
#define DBG_3_ON  PORT->Group[DEBUG_PORT3_PORT].OUTSET.reg = (1 << DEBUG_PORT3_PIN)
#define DBG_3_OFF PORT->Group[DEBUG_PORT3_PORT].OUTCLR.reg = (1 << DEBUG_PORT3_PIN)
#else
#define DBG_3_ENA
#define DBG_3_DIS
#define DBG_3_ON 
#define DBG_3_OFF
#endif

void m15_print(uint32_t x);
void dbg_print(uint32_t x);
void dled_print(uint32_t x, uint8_t long_pause);

void debug_code_init(void);
void debug_code_disable(void);

#ifdef DEBUG_BOOT_TRACING
#ifdef DEBUG_BOOT_TRACING_ENABLE

#define DBGC(n) debug_code = n



@@ 190,6 218,6 @@ enum debug_code_list {

#define DBGC(n) {}

#endif //DEBUG_BOOT_TRACING
#endif //DEBUG_BOOT_TRACING_ENABLE

#endif //_D51_UTIL_H_

M tmk_core/protocol/arm_atsam/i2c_master.c => tmk_core/protocol/arm_atsam/i2c_master.c +5 -5
@@ 267,8 267,8 @@ uint8_t I2C3733_Init_Control(void)

    CLK_delay_ms(1);

    srdata.bit.IRST = 0;
    SPI_WriteSRData();
    sr_exp_data.bit.IRST = 0;
    SR_EXP_WriteData();

    CLK_delay_ms(1);



@@ 357,8 357,8 @@ void I2C3733_Control_Set(uint8_t state)
{
    DBGC(DC_I2C3733_CONTROL_SET_BEGIN);

    srdata.bit.SDB_N = (state == 1 ? 1 : 0);
    SPI_WriteSRData();
    sr_exp_data.bit.SDB_N = (state == 1 ? 1 : 0);
    SR_EXP_WriteData();

    DBGC(DC_I2C3733_CONTROL_SET_COMPLETE);
}


@@ 489,7 489,7 @@ uint8_t i2c_led_q_request_room(uint8_t request_size)

        if (i2c_led_q_full >= 100) //Give the queue a chance to clear up
        {
            led_on;
            DBG_LED_ON;
            I2C_DMAC_LED_Init();
            i2c_led_q_init();
            return 1;

M tmk_core/protocol/arm_atsam/led_matrix.c => tmk_core/protocol/arm_atsam/led_matrix.c +2 -2
@@ 520,9 520,9 @@ void led_matrix_task(void)
    //Process more data if not finished
    if (led_cur != lede)
    {
        //m15_off; //debug profiling
        //DBG_1_OFF; //debug profiling
        led_matrix_run();
        //m15_on; //debug profiling
        //DBG_1_ON; //debug profiling
    }
}


M tmk_core/protocol/arm_atsam/main_arm_atsam.c => tmk_core/protocol/arm_atsam/main_arm_atsam.c +9 -5
@@ 247,8 247,13 @@ void main_subtasks(void)

int main(void)
{
    led_ena;
    m15_ena;
    DBG_LED_ENA;
    DBG_1_ENA;
    DBG_1_OFF;
    DBG_2_ENA;
    DBG_2_OFF;
    DBG_3_ENA;
    DBG_3_OFF;

    debug_code_init();



@@ 256,7 261,7 @@ int main(void)

    ADC0_init();

    SPI_Init();
    SR_EXP_Init();

    i2c1_init();



@@ 274,8 279,7 @@ int main(void)

    while (USB2422_Port_Detect_Init() == 0) {}

    led_off;
    m15_off;
    DBG_LED_OFF;

    led_matrix_init();


M tmk_core/protocol/arm_atsam/spi.c => tmk_core/protocol/arm_atsam/spi.c +51 -54
@@ 17,73 17,70 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include "arm_atsam_protocol.h"

Srdata_t srdata;
sr_exp_t sr_exp_data;

void SPI_WriteSRData(void)
void SR_EXP_WriteData(void)
{
    uint16_t timeout;
    SR_EXP_RCLK_LO;

    SC2_RCLCK_LO;
    while (!(SR_EXP_SERCOM->SPI.INTFLAG.bit.DRE)) { DBGC(DC_SPI_WRITE_DRE); }

    timeout = 50000;
    while (!(SCSPI->SPI.INTFLAG.bit.DRE) && --timeout) { DBGC(DC_SPI_WRITE_DRE); }
    SR_EXP_SERCOM->SPI.DATA.bit.DATA = sr_exp_data.reg & 0xFF; //Shift in bits 7-0
    while (!(SR_EXP_SERCOM->SPI.INTFLAG.bit.TXC)) { DBGC(DC_SPI_WRITE_TXC_1); }

    SCSPI->SPI.DATA.bit.DATA = srdata.reg & 0xFF; //Shift in bits 7-0
    timeout = 50000;
    while (!(SCSPI->SPI.INTFLAG.bit.TXC) && --timeout) { DBGC(DC_SPI_WRITE_TXC_1); }
    SR_EXP_SERCOM->SPI.DATA.bit.DATA = (sr_exp_data.reg >> 8) & 0xFF; //Shift in bits 15-8
    while (!(SR_EXP_SERCOM->SPI.INTFLAG.bit.TXC)) { DBGC(DC_SPI_WRITE_TXC_2); }

    SCSPI->SPI.DATA.bit.DATA = (srdata.reg >> 8) & 0xFF; //Shift in bits 15-8
    timeout = 50000;
    while (!(SCSPI->SPI.INTFLAG.bit.TXC) && --timeout) { DBGC(DC_SPI_WRITE_TXC_2); }

    SC2_RCLCK_HI;
    SR_EXP_RCLK_HI;
}

void SPI_Init(void)
void SR_EXP_Init(void)
{
    uint32_t timeout;

    DBGC(DC_SPI_INIT_BEGIN);

    CLK_set_spi_freq(CHAN_SERCOM_SPI, FREQ_SPI_DEFAULT);

    PORT->Group[0].PMUX[6].bit.PMUXE = 2;
    PORT->Group[0].PMUX[6].bit.PMUXO = 2;
    PORT->Group[0].PINCFG[12].bit.PMUXEN = 1;
    PORT->Group[0].PINCFG[13].bit.PMUXEN = 1;

    //Configure Shift Registers
    SC2_DIRSET;
    SC2_RCLCK_HI;
    SC2_OE_DIS;

    SCSPI->SPI.CTRLA.bit.DORD = 1;
    SCSPI->SPI.CTRLA.bit.CPOL = 1;
    SCSPI->SPI.CTRLA.bit.CPHA = 1;
    SCSPI->SPI.CTRLA.bit.DIPO = 3;
    SCSPI->SPI.CTRLA.bit.MODE = 3; //master

    SCSPI->SPI.CTRLA.bit.ENABLE = 1;
    timeout = 50000;
    while (SCSPI->SPI.SYNCBUSY.bit.ENABLE && timeout--) { DBGC(DC_SPI_SYNC_ENABLING); }

    srdata.reg = 0;
    srdata.bit.HUB_CONNECT = 0;
    srdata.bit.HUB_RESET_N = 0;
    srdata.bit.S_UP = 0;
    srdata.bit.E_UP_N = 1;
    srdata.bit.S_DN1 = 1;
    srdata.bit.E_DN1_N = 1;
    srdata.bit.E_VBUS_1 = 0;
    srdata.bit.E_VBUS_2 = 0;
    srdata.bit.SRC_1 = 1;
    srdata.bit.SRC_2 = 1;
    srdata.bit.IRST = 1;
    srdata.bit.SDB_N = 0;
    SPI_WriteSRData();

    //Enable register output
    SC2_OE_ENA;
    //Set up MCU Shift Register pins
    PORT->Group[SR_EXP_RCLK_PORT].DIRSET.reg = (1 << SR_EXP_RCLK_PIN);
    PORT->Group[SR_EXP_OE_N_PORT].DIRSET.reg = (1 << SR_EXP_OE_N_PIN);
    
    //Set up MCU SPI pins
    PORT->Group[SR_EXP_DATAOUT_PORT].PMUX[SR_EXP_DATAOUT_PIN / 2].bit.SR_EXP_DATAOUT_MUX_SEL = SR_EXP_DATAOUT_MUX; //MUX select for sercom
    PORT->Group[SR_EXP_SCLK_PORT].PMUX[SR_EXP_SCLK_PIN / 2].bit.SR_EXP_SCLK_MUX_SEL = SR_EXP_SCLK_MUX; //MUX select for sercom
    PORT->Group[SR_EXP_DATAOUT_PORT].PINCFG[SR_EXP_DATAOUT_PIN].bit.PMUXEN = 1; //MUX Enable
    PORT->Group[SR_EXP_SCLK_PORT].PINCFG[SR_EXP_SCLK_PIN].bit.PMUXEN = 1; //MUX Enable

    //Initialize Shift Register
    SR_EXP_OE_N_DIS;
    SR_EXP_RCLK_HI;

    SR_EXP_SERCOM->SPI.CTRLA.bit.DORD = 1; //Data Order - LSB is transferred first
    SR_EXP_SERCOM->SPI.CTRLA.bit.CPOL = 1; //Clock Polarity - SCK high when idle. Leading edge of cycle is falling. Trailing rising.
    SR_EXP_SERCOM->SPI.CTRLA.bit.CPHA = 1; //Clock Phase - Leading Edge Falling, change, Trailing Edge - Rising, sample
    SR_EXP_SERCOM->SPI.CTRLA.bit.DIPO = 3; //Data In Pinout - SERCOM PAD[3] is used as data input (Configure away from DOPO. Not using input.)
    SR_EXP_SERCOM->SPI.CTRLA.bit.DOPO = 0; //Data Output PAD[0], Serial Clock PAD[1]
    SR_EXP_SERCOM->SPI.CTRLA.bit.MODE = 3; //Operating Mode - Master operation

    SR_EXP_SERCOM->SPI.CTRLA.bit.ENABLE = 1; //Enable - Peripheral is enabled or being enabled
    while (SR_EXP_SERCOM->SPI.SYNCBUSY.bit.ENABLE) { DBGC(DC_SPI_SYNC_ENABLING); }

    sr_exp_data.reg = 0;
    sr_exp_data.bit.HUB_CONNECT = 0;
    sr_exp_data.bit.HUB_RESET_N = 0;
    sr_exp_data.bit.S_UP = 0;
    sr_exp_data.bit.E_UP_N = 1;
    sr_exp_data.bit.S_DN1 = 1;
    sr_exp_data.bit.E_DN1_N = 1;
    sr_exp_data.bit.E_VBUS_1 = 0;
    sr_exp_data.bit.E_VBUS_2 = 0;
    sr_exp_data.bit.SRC_1 = 1;
    sr_exp_data.bit.SRC_2 = 1;
    sr_exp_data.bit.IRST = 1;
    sr_exp_data.bit.SDB_N = 0;
    SR_EXP_WriteData();

    //Enable Shift Register output
    SR_EXP_OE_N_ENA;

    DBGC(DC_SPI_INIT_COMPLETE);
}

M tmk_core/protocol/arm_atsam/spi.h => tmk_core/protocol/arm_atsam/spi.h +23 -16
@@ 18,21 18,28 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
#ifndef _SPI_H_
#define _SPI_H_

//TODO: PS: Should bring ports to keyboard configuration
/* Macros for Shift Register control */
#define SR_EXP_RCLK_LO PORT->Group[SR_EXP_RCLK_PORT].OUTCLR.reg = (1 << SR_EXP_RCLK_PIN)
#define SR_EXP_RCLK_HI PORT->Group[SR_EXP_RCLK_PORT].OUTSET.reg = (1 << SR_EXP_RCLK_PIN)
#define SR_EXP_OE_N_ENA PORT->Group[SR_EXP_OE_N_PORT].OUTCLR.reg = (1 << SR_EXP_OE_N_PIN)
#define SR_EXP_OE_N_DIS PORT->Group[SR_EXP_OE_N_PORT].OUTSET.reg = (1 << SR_EXP_OE_N_PIN)

#define SCSPI           SERCOM2
/* Determine bits to set for mux selection */
#if SR_EXP_DATAOUT_PIN % 2 == 0
#define SR_EXP_DATAOUT_MUX_SEL PMUXE
#else
#define SR_EXP_DATAOUT_MUX_SEL PMUXO
#endif

#define P14_DIR         0x00004000                             /* PIN14 DIR Bit */
#define P14_OUT         0x00004000                             /* PIN14 OUT Bit */
#define P15_DIR         0x00008000                             /* PIN15 DIR Bit */
#define P15_OUT         0x00008000                             /* PIN15 OUT Bit */

#define SC2_RCLCK_LO    REG_PORT_OUTCLR1 = P14_OUT             /* PB14 Low, SC2_RCLCK Low                            */
#define SC2_RCLCK_HI    REG_PORT_OUTSET1 = P14_OUT             /* PB14 High, SC2_RCLCK High                          */
#define SC2_OE_ENA      REG_PORT_OUTCLR1 = P15_OUT             /* PB15 Low, SC2_OE_N Low (Shift register enabled)    */
#define SC2_OE_DIS      REG_PORT_OUTSET1 = P15_OUT             /* PB15 High, SC2_OE_N High (Shift register disabled) */
#define SC2_DIRSET      REG_PORT_DIRSET1 = P14_DIR | P15_DIR;  /* PB14 PB15 OUT                                      */
/* Determine bits to set for mux selection */
#if SR_EXP_SCLK_PIN % 2 == 0
#define SR_EXP_SCLK_MUX_SEL PMUXE
#else
#define SR_EXP_SCLK_MUX_SEL PMUXO
#endif

/* Data structure to define Shift Register output expander hardware */
/* This structure gets shifted into registers LSB first */
typedef union {
  struct {
    uint16_t RSVD4:1;          /*!< bit:      0                                               */


@@ 53,11 60,11 @@ typedef union {
    uint16_t HUB_CONNECT:1;    /*!< bit:     15  SIGNAL VBUS CONNECT TO USB HUB WHEN 1        */
  } bit;                       /*!< Structure used for bit access                             */
  uint16_t reg;                /*!< Type      used for register access                        */
} Srdata_t;
} sr_exp_t;

extern Srdata_t srdata;
extern sr_exp_t sr_exp_data;

void SPI_WriteSRData(void);
void SPI_Init(void);
void SR_EXP_WriteData(void);
void SR_EXP_Init(void);

#endif //_SPI_H_

M tmk_core/protocol/arm_atsam/usb/usb2422.c => tmk_core/protocol/arm_atsam/usb/usb2422.c +41 -44
@@ 77,7 77,6 @@ void USB2422_init(void)
    Port *pport = PORT;
    Oscctrl *posc = OSCCTRL;
    Usb *pusb = USB;
    Srdata_t *pspi = &srdata;

    DBGC(DC_USB2422_INIT_BEGIN);



@@ 132,9 131,9 @@ void USB2422_init(void)

    i2c0_init(); //IC2 clk must be high at USB2422 reset release time to signal SMB configuration

    pspi->bit.HUB_CONNECT = 1; //connect signal
    pspi->bit.HUB_RESET_N = 1; //reset high
    SPI_WriteSRData();
    sr_exp_data.bit.HUB_CONNECT = 1; //connect signal
    sr_exp_data.bit.HUB_RESET_N = 1; //reset high
    SR_EXP_WriteData();

    CLK_delay_us(100);



@@ 150,16 149,14 @@ void USB2422_init(void)

void USB_reset(void)
{
    Srdata_t *pspi = &srdata;

    DBGC(DC_USB_RESET_BEGIN);

    //pulse reset for at least 1 usec
    pspi->bit.HUB_RESET_N = 0; //reset low
    SPI_WriteSRData();
    sr_exp_data.bit.HUB_RESET_N = 0; //reset low
    SR_EXP_WriteData();
    CLK_delay_us(1);
    pspi->bit.HUB_RESET_N = 1; //reset high to run
    SPI_WriteSRData();
    sr_exp_data.bit.HUB_RESET_N = 1; //reset high to run
    SR_EXP_WriteData();
    CLK_delay_us(1);

    DBGC(DC_USB_RESET_COMPLETE);


@@ 241,14 238,14 @@ void USB_set_host_by_voltage(void)
#ifndef MD_BOOTLOADER
    usb_extra_state = USB_EXTRA_STATE_UNKNOWN;
#endif //MD_BOOTLOADER
    srdata.bit.SRC_1 = 1;       //USBC-1 available for test
    srdata.bit.SRC_2 = 1;       //USBC-2 available for test
    srdata.bit.E_UP_N = 1;      //HOST disable
    srdata.bit.E_DN1_N = 1;     //EXTRA disable
    srdata.bit.E_VBUS_1 = 0;    //USBC-1 disable full power I/O
    srdata.bit.E_VBUS_2 = 0;    //USBC-2 disable full power I/O
    sr_exp_data.bit.SRC_1 = 1;       //USBC-1 available for test
    sr_exp_data.bit.SRC_2 = 1;       //USBC-2 available for test
    sr_exp_data.bit.E_UP_N = 1;      //HOST disable
    sr_exp_data.bit.E_DN1_N = 1;     //EXTRA disable
    sr_exp_data.bit.E_VBUS_1 = 0;    //USBC-1 disable full power I/O
    sr_exp_data.bit.E_VBUS_2 = 0;    //USBC-2 disable full power I/O

    SPI_WriteSRData();
    SR_EXP_WriteData();

    CLK_delay_ms(250);



@@ 262,37 259,37 @@ void USB_set_host_by_voltage(void)

    if (v_con_1 > v_con_2)
    {
        srdata.bit.S_UP = 0;        //HOST to USBC-1
        srdata.bit.S_DN1 = 1;       //EXTRA to USBC-2
        srdata.bit.SRC_1 = 1;       //HOST on USBC-1
        srdata.bit.SRC_2 = 0;       //EXTRA available on USBC-2
        sr_exp_data.bit.S_UP = 0;        //HOST to USBC-1
        sr_exp_data.bit.S_DN1 = 1;       //EXTRA to USBC-2
        sr_exp_data.bit.SRC_1 = 1;       //HOST on USBC-1
        sr_exp_data.bit.SRC_2 = 0;       //EXTRA available on USBC-2

        srdata.bit.E_VBUS_1 = 1;    //USBC-1 enable full power I/O
        srdata.bit.E_VBUS_2 = 0;    //USBC-2 disable full power I/O
        sr_exp_data.bit.E_VBUS_1 = 1;    //USBC-1 enable full power I/O
        sr_exp_data.bit.E_VBUS_2 = 0;    //USBC-2 disable full power I/O

        SPI_WriteSRData();
        SR_EXP_WriteData();

        srdata.bit.E_UP_N = 0;      //HOST enable
        sr_exp_data.bit.E_UP_N = 0;      //HOST enable

        SPI_WriteSRData();
        SR_EXP_WriteData();

        usb_host_port = USB_HOST_PORT_1;
    }
    else
    {
        srdata.bit.S_UP = 1;        //EXTRA to USBC-1
        srdata.bit.S_DN1 = 0;       //HOST to USBC-2
        srdata.bit.SRC_1 = 0;       //EXTRA available on USBC-1
        srdata.bit.SRC_2 = 1;       //HOST on USBC-2
        sr_exp_data.bit.S_UP = 1;        //EXTRA to USBC-1
        sr_exp_data.bit.S_DN1 = 0;       //HOST to USBC-2
        sr_exp_data.bit.SRC_1 = 0;       //EXTRA available on USBC-1
        sr_exp_data.bit.SRC_2 = 1;       //HOST on USBC-2

        srdata.bit.E_VBUS_1 = 0;    //USBC-1 disable full power I/O
        srdata.bit.E_VBUS_2 = 1;    //USBC-2 enable full power I/O
        sr_exp_data.bit.E_VBUS_1 = 0;    //USBC-1 disable full power I/O
        sr_exp_data.bit.E_VBUS_2 = 1;    //USBC-2 enable full power I/O

        SPI_WriteSRData();
        SR_EXP_WriteData();

        srdata.bit.E_UP_N = 0;      //HOST enable
        sr_exp_data.bit.E_UP_N = 0;      //HOST enable

        SPI_WriteSRData();
        SR_EXP_WriteData();

        usb_host_port = USB_HOST_PORT_2;
    }


@@ 325,15 322,15 @@ uint8_t USB2422_Port_Detect_Init(void)
        if (v_con_1 > v_con_2) //Values updated from USB_set_host_by_voltage();
        {
            //1 flash for port 1 detected
            if (tmod > 500 && tmod < 600) { led_on; }
            else { led_off; }
            if (tmod > 500 && tmod < 600) { DBG_LED_ON; }
            else { DBG_LED_OFF; }
        }
        else if (v_con_2 > v_con_1) //Values updated from USB_set_host_by_voltage();
        {
            //2 flash for port 2 detected
            if (tmod > 500 && tmod < 600) { led_on; }
            else if (tmod > 700 && tmod < 800) { led_on; }
            else { led_off; }
            if (tmod > 500 && tmod < 600) { DBG_LED_ON; }
            else if (tmod > 700 && tmod < 800) { DBG_LED_ON; }
            else { DBG_LED_OFF; }
        }

        if (CLK_get_ms() > port_detect_retry_ms)


@@ 357,12 354,12 @@ void USB_ExtraSetState(uint8_t state)
    if (state == USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG)
        state = USB_EXTRA_STATE_DISABLED;

    if (usb_host_port == USB_HOST_PORT_1) srdata.bit.E_VBUS_2 = state;
    else if (usb_host_port == USB_HOST_PORT_2) srdata.bit.E_VBUS_1 = state;
    if (usb_host_port == USB_HOST_PORT_1) sr_exp_data.bit.E_VBUS_2 = state;
    else if (usb_host_port == USB_HOST_PORT_2) sr_exp_data.bit.E_VBUS_1 = state;
    else return;

    srdata.bit.E_DN1_N = !state;
    SPI_WriteSRData();
    sr_exp_data.bit.E_DN1_N = !state;
    SR_EXP_WriteData();

    usb_extra_state = state_save;