Format code according to conventions (#16322)
This commit is contained in:
		
							parent
							
								
									afcdd7079c
								
							
						
					
					
						commit
						63646e8906
					
				
					 345 changed files with 4916 additions and 3229 deletions
				
			
		| 
						 | 
				
			
			@ -27,10 +27,10 @@ uint16_t v_con_2_boot;
 | 
			
		|||
void ADC0_clock_init(void) {
 | 
			
		||||
    DBGC(DC_ADC0_CLOCK_INIT_BEGIN);
 | 
			
		||||
 | 
			
		||||
    MCLK->APBDMASK.bit.ADC0_ = 1;  // ADC0 Clock Enable
 | 
			
		||||
    MCLK->APBDMASK.bit.ADC0_ = 1; // ADC0 Clock Enable
 | 
			
		||||
 | 
			
		||||
    GCLK->PCHCTRL[ADC0_GCLK_ID].bit.GEN  = GEN_OSC0;  // Select generator clock
 | 
			
		||||
    GCLK->PCHCTRL[ADC0_GCLK_ID].bit.CHEN = 1;         // Enable peripheral clock
 | 
			
		||||
    GCLK->PCHCTRL[ADC0_GCLK_ID].bit.GEN  = GEN_OSC0; // Select generator clock
 | 
			
		||||
    GCLK->PCHCTRL[ADC0_GCLK_ID].bit.CHEN = 1;        // Enable peripheral clock
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_ADC0_CLOCK_INIT_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -39,15 +39,15 @@ void ADC0_init(void) {
 | 
			
		|||
    DBGC(DC_ADC0_INIT_BEGIN);
 | 
			
		||||
 | 
			
		||||
    // MCU
 | 
			
		||||
    PORT->Group[1].DIRCLR.reg           = 1 << 0;  // PB00 as input 5V
 | 
			
		||||
    PORT->Group[1].DIRCLR.reg           = 1 << 1;  // PB01 as input CON2
 | 
			
		||||
    PORT->Group[1].DIRCLR.reg           = 1 << 2;  // PB02 as input CON1
 | 
			
		||||
    PORT->Group[1].PMUX[0].bit.PMUXE    = 1;       // PB00 mux select B ADC 5V
 | 
			
		||||
    PORT->Group[1].PMUX[0].bit.PMUXO    = 1;       // PB01 mux select B ADC CON2
 | 
			
		||||
    PORT->Group[1].PMUX[1].bit.PMUXE    = 1;       // PB02 mux select B ADC CON1
 | 
			
		||||
    PORT->Group[1].PINCFG[0].bit.PMUXEN = 1;       // PB01 mux ADC Enable 5V
 | 
			
		||||
    PORT->Group[1].PINCFG[1].bit.PMUXEN = 1;       // PB01 mux ADC Enable CON2
 | 
			
		||||
    PORT->Group[1].PINCFG[2].bit.PMUXEN = 1;       // PB02 mux ADC Enable CON1
 | 
			
		||||
    PORT->Group[1].DIRCLR.reg           = 1 << 0; // PB00 as input 5V
 | 
			
		||||
    PORT->Group[1].DIRCLR.reg           = 1 << 1; // PB01 as input CON2
 | 
			
		||||
    PORT->Group[1].DIRCLR.reg           = 1 << 2; // PB02 as input CON1
 | 
			
		||||
    PORT->Group[1].PMUX[0].bit.PMUXE    = 1;      // PB00 mux select B ADC 5V
 | 
			
		||||
    PORT->Group[1].PMUX[0].bit.PMUXO    = 1;      // PB01 mux select B ADC CON2
 | 
			
		||||
    PORT->Group[1].PMUX[1].bit.PMUXE    = 1;      // PB02 mux select B ADC CON1
 | 
			
		||||
    PORT->Group[1].PINCFG[0].bit.PMUXEN = 1;      // PB01 mux ADC Enable 5V
 | 
			
		||||
    PORT->Group[1].PINCFG[1].bit.PMUXEN = 1;      // PB01 mux ADC Enable CON2
 | 
			
		||||
    PORT->Group[1].PINCFG[2].bit.PMUXEN = 1;      // PB02 mux ADC Enable CON1
 | 
			
		||||
 | 
			
		||||
    // ADC
 | 
			
		||||
    ADC0->CTRLA.bit.SWRST = 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -81,7 +81,7 @@ void ADC0_init(void) {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    // Settling
 | 
			
		||||
    ADC0->SAMPCTRL.bit.SAMPLEN = 45;  // Sampling Time Length: 1-63, 1 ADC CLK per
 | 
			
		||||
    ADC0->SAMPCTRL.bit.SAMPLEN = 45; // Sampling Time Length: 1-63, 1 ADC CLK per
 | 
			
		||||
    while (ADC0->SYNCBUSY.bit.SAMPCTRL) {
 | 
			
		||||
        DBGC(DC_ADC0_SAMPCTRL_SYNCING_1);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,4 +34,4 @@ extern uint16_t v_con_2_boot;
 | 
			
		|||
void ADC0_clock_init(void);
 | 
			
		||||
void ADC0_init(void);
 | 
			
		||||
 | 
			
		||||
#endif  //_ADC_H_
 | 
			
		||||
#endif //_ADC_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,6 +42,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#    include "./usb/udc.h"
 | 
			
		||||
#    include "./usb/udi_cdc.h"
 | 
			
		||||
 | 
			
		||||
#endif  // MD_BOOTLOADER
 | 
			
		||||
#endif // MD_BOOTLOADER
 | 
			
		||||
 | 
			
		||||
#endif  //_ARM_ATSAM_PROTOCOL_H_
 | 
			
		||||
#endif //_ARM_ATSAM_PROTOCOL_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
volatile clk_t    system_clks;
 | 
			
		||||
volatile uint64_t ms_clk;
 | 
			
		||||
uint32_t          usec_delay_mult;
 | 
			
		||||
#define USEC_DELAY_LOOP_CYCLES 3  // Sum of instruction cycles in us delay loop
 | 
			
		||||
#define USEC_DELAY_LOOP_CYCLES 3 // Sum of instruction cycles in us delay loop
 | 
			
		||||
 | 
			
		||||
const uint32_t sercom_apbbase[] = {(uint32_t)SERCOM0, (uint32_t)SERCOM1, (uint32_t)SERCOM2, (uint32_t)SERCOM3, (uint32_t)SERCOM4, (uint32_t)SERCOM5};
 | 
			
		||||
const uint8_t  sercom_pchan[]   = {7, 8, 23, 24, 34, 35};
 | 
			
		||||
| 
						 | 
				
			
			@ -59,9 +59,9 @@ void CLK_oscctrl_init(void) {
 | 
			
		|||
    while (posctrl->Dpll[USE_DPLL_IND].DPLLSYNCBUSY.bit.ENABLE) {
 | 
			
		||||
        DBGC(DC_CLK_OSC_INIT_DPLL_SYNC_DISABLE);
 | 
			
		||||
    }
 | 
			
		||||
    posctrl->Dpll[USE_DPLL_IND].DPLLCTRLB.bit.REFCLK = 2;          // select XOSC0 (16MHz)
 | 
			
		||||
    posctrl->Dpll[USE_DPLL_IND].DPLLCTRLB.bit.DIV    = 7;          // 16 MHz / (2 * (7 + 1)) = 1 MHz
 | 
			
		||||
    posctrl->Dpll[USE_DPLL_IND].DPLLRATIO.bit.LDR    = PLL_RATIO;  // 1 MHz * (PLL_RATIO(47) + 1) = 48MHz
 | 
			
		||||
    posctrl->Dpll[USE_DPLL_IND].DPLLCTRLB.bit.REFCLK = 2;         // select XOSC0 (16MHz)
 | 
			
		||||
    posctrl->Dpll[USE_DPLL_IND].DPLLCTRLB.bit.DIV    = 7;         // 16 MHz / (2 * (7 + 1)) = 1 MHz
 | 
			
		||||
    posctrl->Dpll[USE_DPLL_IND].DPLLRATIO.bit.LDR    = PLL_RATIO; // 1 MHz * (PLL_RATIO(47) + 1) = 48MHz
 | 
			
		||||
    while (posctrl->Dpll[USE_DPLL_IND].DPLLSYNCBUSY.bit.DPLLRATIO) {
 | 
			
		||||
        DBGC(DC_CLK_OSC_INIT_DPLL_SYNC_RATIO);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -87,7 +87,7 @@ void CLK_oscctrl_init(void) {
 | 
			
		|||
    system_clks.freq_gclk[0] = system_clks.freq_dpll[0];
 | 
			
		||||
 | 
			
		||||
    usec_delay_mult = system_clks.freq_gclk[0] / (USEC_DELAY_LOOP_CYCLES * 1000000);
 | 
			
		||||
    if (usec_delay_mult < 1) usec_delay_mult = 1;  // Never allow a multiplier of zero
 | 
			
		||||
    if (usec_delay_mult < 1) usec_delay_mult = 1; // Never allow a multiplier of zero
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_OSC_INIT_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -240,7 +240,7 @@ uint32_t CLK_enable_timebase(void) {
 | 
			
		|||
    // ptc4->COUNT16.DBGCTRL.bit.DBGRUN = 1;
 | 
			
		||||
 | 
			
		||||
    // wave mode
 | 
			
		||||
    ptc4->COUNT16.WAVE.bit.WAVEGEN = 1;  // MFRQ match frequency mode, toggle each CC match
 | 
			
		||||
    ptc4->COUNT16.WAVE.bit.WAVEGEN = 1; // MFRQ match frequency mode, toggle each CC match
 | 
			
		||||
    // generate event for next stage
 | 
			
		||||
    ptc4->COUNT16.EVCTRL.bit.MCEO0 = 1;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -272,9 +272,9 @@ uint32_t CLK_enable_timebase(void) {
 | 
			
		|||
        DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_SWRST_2);
 | 
			
		||||
    }
 | 
			
		||||
    // CTRLA as default
 | 
			
		||||
    ptc0->COUNT32.CTRLA.bit.MODE   = 2;  // 32 bit mode
 | 
			
		||||
    ptc0->COUNT32.EVCTRL.bit.TCEI  = 1;  // enable incoming events
 | 
			
		||||
    ptc0->COUNT32.EVCTRL.bit.EVACT = 2;  // count events
 | 
			
		||||
    ptc0->COUNT32.CTRLA.bit.MODE   = 2; // 32 bit mode
 | 
			
		||||
    ptc0->COUNT32.EVCTRL.bit.TCEI  = 1; // enable incoming events
 | 
			
		||||
    ptc0->COUNT32.EVCTRL.bit.EVACT = 2; // count events
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_COMPLETE);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -284,10 +284,10 @@ uint32_t CLK_enable_timebase(void) {
 | 
			
		|||
    pmclk->APBBMASK.bit.EVSYS_               = 1;
 | 
			
		||||
    pgclk->PCHCTRL[EVSYS_GCLK_ID_0].bit.GEN  = GEN_TC45;
 | 
			
		||||
    pgclk->PCHCTRL[EVSYS_GCLK_ID_0].bit.CHEN = 1;
 | 
			
		||||
    pevsys->USER[44].reg                     = EVSYS_ID_USER_PORT_EV_0;               // TC0 will get event channel 0
 | 
			
		||||
    pevsys->Channel[0].CHANNEL.bit.EDGSEL    = EVSYS_CHANNEL_EDGSEL_RISING_EDGE_Val;  // Rising edge
 | 
			
		||||
    pevsys->Channel[0].CHANNEL.bit.PATH      = EVSYS_CHANNEL_PATH_SYNCHRONOUS_Val;    // Synchronous
 | 
			
		||||
    pevsys->Channel[0].CHANNEL.bit.EVGEN     = EVSYS_ID_GEN_TC4_MCX_0;                // TC4 MC0
 | 
			
		||||
    pevsys->USER[44].reg                     = EVSYS_ID_USER_PORT_EV_0;              // TC0 will get event channel 0
 | 
			
		||||
    pevsys->Channel[0].CHANNEL.bit.EDGSEL    = EVSYS_CHANNEL_EDGSEL_RISING_EDGE_Val; // Rising edge
 | 
			
		||||
    pevsys->Channel[0].CHANNEL.bit.PATH      = EVSYS_CHANNEL_PATH_SYNCHRONOUS_Val;   // Synchronous
 | 
			
		||||
    pevsys->Channel[0].CHANNEL.bit.EVGEN     = EVSYS_ID_GEN_TC4_MCX_0;               // TC4 MC0
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_ENABLE_TIMEBASE_EVSYS_COMPLETE);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -301,15 +301,15 @@ uint32_t CLK_enable_timebase(void) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void CLK_delay_us(uint32_t usec) {
 | 
			
		||||
    asm("CBZ R0, return\n\t"  // If usec == 0, branch to return label
 | 
			
		||||
    asm("CBZ R0, return\n\t" // If usec == 0, branch to return label
 | 
			
		||||
    );
 | 
			
		||||
    asm("MULS R0, %0\n\t"        // Multiply R0(usec) by usec_delay_mult and store in R0
 | 
			
		||||
        ".balign 16\n\t"         // Ensure loop is aligned for fastest performance
 | 
			
		||||
        "loop: SUBS R0, #1\n\t"  // Subtract 1 from R0 and update flags (1 cycle)
 | 
			
		||||
        "BNE loop\n\t"           // Branch if non-zero to loop label (2 cycles)  NOTE: USEC_DELAY_LOOP_CYCLES is the sum of loop cycles
 | 
			
		||||
        "return:\n\t"            // Return label
 | 
			
		||||
        :                        // No output registers
 | 
			
		||||
        : "r"(usec_delay_mult)   // For %0
 | 
			
		||||
    asm("MULS R0, %0\n\t"       // Multiply R0(usec) by usec_delay_mult and store in R0
 | 
			
		||||
        ".balign 16\n\t"        // Ensure loop is aligned for fastest performance
 | 
			
		||||
        "loop: SUBS R0, #1\n\t" // Subtract 1 from R0 and update flags (1 cycle)
 | 
			
		||||
        "BNE loop\n\t"          // Branch if non-zero to loop label (2 cycles)  NOTE: USEC_DELAY_LOOP_CYCLES is the sum of loop cycles
 | 
			
		||||
        "return:\n\t"           // Return label
 | 
			
		||||
        :                       // No output registers
 | 
			
		||||
        : "r"(usec_delay_mult)  // For %0
 | 
			
		||||
    );
 | 
			
		||||
    // Note: BX LR generated
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,14 +24,14 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#    include "config_led.h"
 | 
			
		||||
#    include "config.h"
 | 
			
		||||
 | 
			
		||||
#endif  // MD_BOOTLOADER
 | 
			
		||||
#endif // MD_BOOTLOADER
 | 
			
		||||
 | 
			
		||||
#define PLL_RATIO 47                // mcu frequency ((X+1)MHz)
 | 
			
		||||
#define FREQ_DFLL_DEFAULT 48000000  // DFLL frequency / usb clock
 | 
			
		||||
#define FREQ_SPI_DEFAULT 1000000    // spi to 595 shift regs
 | 
			
		||||
#define FREQ_I2C0_DEFAULT 100000    // i2c to hub
 | 
			
		||||
#define FREQ_I2C1_DEFAULT I2C_HZ    // i2c to LED drivers
 | 
			
		||||
#define FREQ_TC45_DEFAULT 1000000   // 1 usec resolution
 | 
			
		||||
#define PLL_RATIO 47               // mcu frequency ((X+1)MHz)
 | 
			
		||||
#define FREQ_DFLL_DEFAULT 48000000 // DFLL frequency / usb clock
 | 
			
		||||
#define FREQ_SPI_DEFAULT 1000000   // spi to 595 shift regs
 | 
			
		||||
#define FREQ_I2C0_DEFAULT 100000   // i2c to hub
 | 
			
		||||
#define FREQ_I2C1_DEFAULT I2C_HZ   // i2c to LED drivers
 | 
			
		||||
#define FREQ_TC45_DEFAULT 1000000  // 1 usec resolution
 | 
			
		||||
 | 
			
		||||
// I2C1 Set      ~Result     PWM Time (2x Drivers)
 | 
			
		||||
//     1000000  1090000
 | 
			
		||||
| 
						 | 
				
			
			@ -44,10 +44,10 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
 | 
			
		||||
#define FREQ_XOSC0 16000000
 | 
			
		||||
 | 
			
		||||
#define CHAN_SERCOM_SPI 2   // shift regs
 | 
			
		||||
#define CHAN_SERCOM_I2C0 0  // hub
 | 
			
		||||
#define CHAN_SERCOM_I2C1 1  // led drivers
 | 
			
		||||
#define CHAN_SERCOM_UART 3  // debug util
 | 
			
		||||
#define CHAN_SERCOM_SPI 2  // shift regs
 | 
			
		||||
#define CHAN_SERCOM_I2C0 0 // hub
 | 
			
		||||
#define CHAN_SERCOM_I2C1 1 // led drivers
 | 
			
		||||
#define CHAN_SERCOM_UART 3 // debug util
 | 
			
		||||
 | 
			
		||||
// Generator clock channels
 | 
			
		||||
#define GEN_DPLL0 0
 | 
			
		||||
| 
						 | 
				
			
			@ -86,4 +86,4 @@ uint32_t CLK_set_i2c0_freq(uint8_t sercomn, uint32_t freq);
 | 
			
		|||
uint32_t CLK_set_i2c1_freq(uint8_t sercomn, uint32_t freq);
 | 
			
		||||
void     CLK_init(void);
 | 
			
		||||
 | 
			
		||||
#endif  // _CLKS_H_
 | 
			
		||||
#endif // _CLKS_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,7 +34,8 @@ void dbg_print(uint32_t x) {
 | 
			
		|||
    while (t >= 0) {
 | 
			
		||||
        p2 = t;
 | 
			
		||||
        p  = 1;
 | 
			
		||||
        while (p2--) p *= 10;
 | 
			
		||||
        while (p2--)
 | 
			
		||||
            p *= 10;
 | 
			
		||||
        n = x / p;
 | 
			
		||||
        x -= n * p;
 | 
			
		||||
        if (!n) {
 | 
			
		||||
| 
						 | 
				
			
			@ -55,7 +56,7 @@ void dbg_print(uint32_t x) {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    for (w = DBG_PAUSE; w; w--)
 | 
			
		||||
        ;  // Long pause after number is complete
 | 
			
		||||
        ; // Long pause after number is complete
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Display unsigned 32-bit number through debug led
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +92,8 @@ void dled_print(uint32_t x, uint8_t long_pause) {
 | 
			
		|||
    while (t >= 0) {
 | 
			
		||||
        p2 = t;
 | 
			
		||||
        p  = 1;
 | 
			
		||||
        while (p2--) p *= 10;
 | 
			
		||||
        while (p2--)
 | 
			
		||||
            p *= 10;
 | 
			
		||||
        n = x / p;
 | 
			
		||||
        x -= n * p;
 | 
			
		||||
        if (!n) {
 | 
			
		||||
| 
						 | 
				
			
			@ -188,12 +190,12 @@ 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
 | 
			
		||||
    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;
 | 
			
		||||
| 
						 | 
				
			
			@ -223,12 +225,12 @@ void debug_code_disable(void) {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    // 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
 | 
			
		||||
    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;
 | 
			
		||||
| 
						 | 
				
			
			@ -239,4 +241,4 @@ void debug_code_disable(void) {
 | 
			
		|||
void debug_code_init(void) {}
 | 
			
		||||
void debug_code_disable(void) {}
 | 
			
		||||
 | 
			
		||||
#endif  // DEBUG_BOOT_TRACING_ENABLE
 | 
			
		||||
#endif // DEBUG_BOOT_TRACING_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -219,6 +219,6 @@ enum debug_code_list {
 | 
			
		|||
#    define DBGC(n) \
 | 
			
		||||
        {}
 | 
			
		||||
 | 
			
		||||
#endif  // DEBUG_BOOT_TRACING_ENABLE
 | 
			
		||||
#endif // DEBUG_BOOT_TRACING_ENABLE
 | 
			
		||||
 | 
			
		||||
#endif  //_D51_UTIL_H_
 | 
			
		||||
#endif //_D51_UTIL_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,21 +26,21 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#    include "config_led.h"
 | 
			
		||||
#    include "matrix.h"
 | 
			
		||||
 | 
			
		||||
#    define I2C_LED_USE_DMA 1  // Set 1 to use background DMA transfers for leds, Set 0 to use inline software transfers
 | 
			
		||||
#    define I2C_LED_USE_DMA 1 // Set 1 to use background DMA transfers for leds, Set 0 to use inline software transfers
 | 
			
		||||
 | 
			
		||||
DmacDescriptor dmac_desc;
 | 
			
		||||
DmacDescriptor dmac_desc_wb;
 | 
			
		||||
 | 
			
		||||
static uint8_t i2c_led_q[I2C_Q_SIZE];  // I2C queue circular buffer
 | 
			
		||||
static uint8_t i2c_led_q_s;            // Start of circular buffer
 | 
			
		||||
static uint8_t i2c_led_q_e;            // End of circular buffer
 | 
			
		||||
static uint8_t i2c_led_q_full;         // Queue full counter for reset
 | 
			
		||||
static uint8_t i2c_led_q[I2C_Q_SIZE]; // I2C queue circular buffer
 | 
			
		||||
static uint8_t i2c_led_q_s;           // Start of circular buffer
 | 
			
		||||
static uint8_t i2c_led_q_e;           // End of circular buffer
 | 
			
		||||
static uint8_t i2c_led_q_full;        // Queue full counter for reset
 | 
			
		||||
 | 
			
		||||
static uint8_t dma_sendbuf[I2C_DMA_MAX_SEND];  // Data being written to I2C
 | 
			
		||||
static uint8_t dma_sendbuf[I2C_DMA_MAX_SEND]; // Data being written to I2C
 | 
			
		||||
 | 
			
		||||
volatile uint8_t i2c_led_q_running;
 | 
			
		||||
 | 
			
		||||
#endif  // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
 | 
			
		||||
#endif // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
 | 
			
		||||
 | 
			
		||||
void i2c0_init(void) {
 | 
			
		||||
    DBGC(DC_I2C0_INIT_BEGIN);
 | 
			
		||||
| 
						 | 
				
			
			@ -56,23 +56,23 @@ void i2c0_init(void) {
 | 
			
		|||
    // I2C
 | 
			
		||||
    // Note: SW Reset handled in CLK_set_i2c0_freq clks.c
 | 
			
		||||
 | 
			
		||||
    SERCOM0->I2CM.CTRLA.bit.MODE = 5;  // Set master mode
 | 
			
		||||
    SERCOM0->I2CM.CTRLA.bit.MODE = 5; // Set master mode
 | 
			
		||||
 | 
			
		||||
    SERCOM0->I2CM.CTRLA.bit.SPEED    = 0;  // Set to 1 for Fast-mode Plus (FM+) up to 1 MHz
 | 
			
		||||
    SERCOM0->I2CM.CTRLA.bit.RUNSTDBY = 1;  // Enabled
 | 
			
		||||
    SERCOM0->I2CM.CTRLA.bit.SPEED    = 0; // Set to 1 for Fast-mode Plus (FM+) up to 1 MHz
 | 
			
		||||
    SERCOM0->I2CM.CTRLA.bit.RUNSTDBY = 1; // Enabled
 | 
			
		||||
 | 
			
		||||
    SERCOM0->I2CM.CTRLA.bit.ENABLE = 1;  // Enable the device
 | 
			
		||||
    SERCOM0->I2CM.CTRLA.bit.ENABLE = 1; // Enable the device
 | 
			
		||||
    while (SERCOM0->I2CM.SYNCBUSY.bit.ENABLE) {
 | 
			
		||||
        DBGC(DC_I2C0_INIT_SYNC_ENABLING);
 | 
			
		||||
    }  // Wait for SYNCBUSY.ENABLE to clear
 | 
			
		||||
    } // Wait for SYNCBUSY.ENABLE to clear
 | 
			
		||||
 | 
			
		||||
    SERCOM0->I2CM.STATUS.bit.BUSSTATE = 1;  // Force into IDLE state
 | 
			
		||||
    SERCOM0->I2CM.STATUS.bit.BUSSTATE = 1; // Force into IDLE state
 | 
			
		||||
    while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) {
 | 
			
		||||
        DBGC(DC_I2C0_INIT_SYNC_SYSOP);
 | 
			
		||||
    }
 | 
			
		||||
    while (SERCOM0->I2CM.STATUS.bit.BUSSTATE != 1) {
 | 
			
		||||
        DBGC(DC_I2C0_INIT_WAIT_IDLE);
 | 
			
		||||
    }  // Wait while not idle
 | 
			
		||||
    } // Wait while not idle
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_I2C0_INIT_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -139,27 +139,27 @@ void i2c1_init(void) {
 | 
			
		|||
    /* I2C */
 | 
			
		||||
    // Note: SW Reset handled in CLK_set_i2c1_freq clks.c
 | 
			
		||||
 | 
			
		||||
    SERCOM1->I2CM.CTRLA.bit.MODE     = 5;  // MODE: Set master mode (No sync)
 | 
			
		||||
    SERCOM1->I2CM.CTRLA.bit.SPEED    = 1;  // SPEED: Fm+ up to 1MHz (No sync)
 | 
			
		||||
    SERCOM1->I2CM.CTRLA.bit.RUNSTDBY = 1;  // RUNSTBY: Enabled (No sync)
 | 
			
		||||
    SERCOM1->I2CM.CTRLA.bit.MODE     = 5; // MODE: Set master mode (No sync)
 | 
			
		||||
    SERCOM1->I2CM.CTRLA.bit.SPEED    = 1; // SPEED: Fm+ up to 1MHz (No sync)
 | 
			
		||||
    SERCOM1->I2CM.CTRLA.bit.RUNSTDBY = 1; // RUNSTBY: Enabled (No sync)
 | 
			
		||||
 | 
			
		||||
    SERCOM1->I2CM.CTRLB.bit.SMEN = 1;  // SMEN: Smart mode enabled (For DMA)(No sync)
 | 
			
		||||
    SERCOM1->I2CM.CTRLB.bit.SMEN = 1; // SMEN: Smart mode enabled (For DMA)(No sync)
 | 
			
		||||
 | 
			
		||||
    NVIC_EnableIRQ(SERCOM1_0_IRQn);
 | 
			
		||||
    SERCOM1->I2CM.INTENSET.bit.ERROR = 1;
 | 
			
		||||
 | 
			
		||||
    SERCOM1->I2CM.CTRLA.bit.ENABLE = 1;  // ENABLE: Enable the device (sync SYNCBUSY.ENABLE)
 | 
			
		||||
    SERCOM1->I2CM.CTRLA.bit.ENABLE = 1; // ENABLE: Enable the device (sync SYNCBUSY.ENABLE)
 | 
			
		||||
    while (SERCOM1->I2CM.SYNCBUSY.bit.ENABLE) {
 | 
			
		||||
        DBGC(DC_I2C1_INIT_SYNC_ENABLING);
 | 
			
		||||
    }  // Wait for SYNCBUSY.ENABLE to clear
 | 
			
		||||
    } // Wait for SYNCBUSY.ENABLE to clear
 | 
			
		||||
 | 
			
		||||
    SERCOM1->I2CM.STATUS.bit.BUSSTATE = 1;  // BUSSTATE: Force into IDLE state (sync SYNCBUSY.SYSOP)
 | 
			
		||||
    SERCOM1->I2CM.STATUS.bit.BUSSTATE = 1; // BUSSTATE: Force into IDLE state (sync SYNCBUSY.SYSOP)
 | 
			
		||||
    while (SERCOM1->I2CM.SYNCBUSY.bit.SYSOP) {
 | 
			
		||||
        DBGC(DC_I2C1_INIT_SYNC_SYSOP);
 | 
			
		||||
    }
 | 
			
		||||
    while (SERCOM1->I2CM.STATUS.bit.BUSSTATE != 1) {
 | 
			
		||||
        DBGC(DC_I2C1_INIT_WAIT_IDLE);
 | 
			
		||||
    }  // Wait while not idle
 | 
			
		||||
    } // Wait while not idle
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_I2C1_INIT_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -240,7 +240,7 @@ void i2c_led_send_onoff(uint8_t drvid) {
 | 
			
		|||
    }
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    *issidrv[drvid].onoff = 0;  // Force start location offset to zero
 | 
			
		||||
    *issidrv[drvid].onoff = 0; // Force start location offset to zero
 | 
			
		||||
    i2c1_transmit(issidrv[drvid].addr, issidrv[drvid].onoff, ISSI3733_PG0_BYTES, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -265,7 +265,7 @@ void i2c_led_send_pwm(uint8_t drvid) {
 | 
			
		|||
    }
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    *issidrv[drvid].pwm = 0;  // Force start location offset to zero
 | 
			
		||||
    *issidrv[drvid].pwm = 0; // Force start location offset to zero
 | 
			
		||||
    i2c1_transmit(issidrv[drvid].addr, issidrv[drvid].pwm, ISSI3733_PG1_BYTES, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -300,12 +300,12 @@ uint8_t I2C3733_Init_Drivers(void) {
 | 
			
		|||
    // Set up master device
 | 
			
		||||
    i2c_led_send_CRWL(0);
 | 
			
		||||
    i2c_led_select_page(0, 3);
 | 
			
		||||
    i2c_led_send_mode_op_gcr(0, 0, ISSI3733_CR_SSD_NORMAL);  // No SYNC due to brightness mismatch with second driver
 | 
			
		||||
    i2c_led_send_mode_op_gcr(0, 0, ISSI3733_CR_SSD_NORMAL); // No SYNC due to brightness mismatch with second driver
 | 
			
		||||
 | 
			
		||||
    // Set up slave device
 | 
			
		||||
    i2c_led_send_CRWL(1);
 | 
			
		||||
    i2c_led_select_page(1, 3);
 | 
			
		||||
    i2c_led_send_mode_op_gcr(1, 0, ISSI3733_CR_SSD_NORMAL);  // No SYNC due to brightness mismatch with first driver and slight flicker at rgb values 1,2
 | 
			
		||||
    i2c_led_send_mode_op_gcr(1, 0, ISSI3733_CR_SSD_NORMAL); // No SYNC due to brightness mismatch with first driver and slight flicker at rgb values 1,2
 | 
			
		||||
 | 
			
		||||
    i2c_led_send_CRWL(0);
 | 
			
		||||
    i2c_led_select_page(0, 3);
 | 
			
		||||
| 
						 | 
				
			
			@ -326,41 +326,41 @@ void I2C_DMAC_LED_Init(void) {
 | 
			
		|||
    DBGC(DC_I2C_DMAC_LED_INIT_BEGIN);
 | 
			
		||||
 | 
			
		||||
    // Disable device
 | 
			
		||||
    dmac->CTRL.bit.DMAENABLE = 0;  // Disable DMAC
 | 
			
		||||
    dmac->CTRL.bit.DMAENABLE = 0; // Disable DMAC
 | 
			
		||||
    while (dmac->CTRL.bit.DMAENABLE) {
 | 
			
		||||
    }                          // Wait for disabled state in case of ongoing transfers
 | 
			
		||||
    dmac->CTRL.bit.SWRST = 1;  // Software Reset DMAC
 | 
			
		||||
    }                         // Wait for disabled state in case of ongoing transfers
 | 
			
		||||
    dmac->CTRL.bit.SWRST = 1; // Software Reset DMAC
 | 
			
		||||
    while (dmac->CTRL.bit.SWRST) {
 | 
			
		||||
    }  // Wait for software reset to complete
 | 
			
		||||
    } // Wait for software reset to complete
 | 
			
		||||
 | 
			
		||||
    // Configure device
 | 
			
		||||
    dmac->BASEADDR.reg = (uint32_t)&dmac_desc;     // Set descriptor base address
 | 
			
		||||
    dmac->WRBADDR.reg  = (uint32_t)&dmac_desc_wb;  // Set descriptor write back address
 | 
			
		||||
    dmac->CTRL.reg |= 0x0f00;                      // Handle all priorities (LVL0-3)
 | 
			
		||||
    dmac->BASEADDR.reg = (uint32_t)&dmac_desc;    // Set descriptor base address
 | 
			
		||||
    dmac->WRBADDR.reg  = (uint32_t)&dmac_desc_wb; // Set descriptor write back address
 | 
			
		||||
    dmac->CTRL.reg |= 0x0f00;                     // Handle all priorities (LVL0-3)
 | 
			
		||||
 | 
			
		||||
    // Disable channel
 | 
			
		||||
    dmac->Channel[0].CHCTRLA.bit.ENABLE = 0;  // Disable the channel
 | 
			
		||||
    dmac->Channel[0].CHCTRLA.bit.ENABLE = 0; // Disable the channel
 | 
			
		||||
    while (dmac->Channel[0].CHCTRLA.bit.ENABLE) {
 | 
			
		||||
    }                                        // Wait for disabled state in case of ongoing transfers
 | 
			
		||||
    dmac->Channel[0].CHCTRLA.bit.SWRST = 1;  // Software Reset the channel
 | 
			
		||||
    }                                       // Wait for disabled state in case of ongoing transfers
 | 
			
		||||
    dmac->Channel[0].CHCTRLA.bit.SWRST = 1; // Software Reset the channel
 | 
			
		||||
    while (dmac->Channel[0].CHCTRLA.bit.SWRST) {
 | 
			
		||||
    }  // Wait for software reset to complete
 | 
			
		||||
    } // Wait for software reset to complete
 | 
			
		||||
 | 
			
		||||
    // Configure channel
 | 
			
		||||
    dmac->Channel[0].CHCTRLA.bit.THRESHOLD = 0;                   // 1BEAT
 | 
			
		||||
    dmac->Channel[0].CHCTRLA.bit.BURSTLEN  = 0;                   // SINGLE
 | 
			
		||||
    dmac->Channel[0].CHCTRLA.bit.TRIGACT   = 2;                   // BURST
 | 
			
		||||
    dmac->Channel[0].CHCTRLA.bit.TRIGSRC   = SERCOM1_DMAC_ID_TX;  // Trigger source
 | 
			
		||||
    dmac->Channel[0].CHCTRLA.bit.RUNSTDBY  = 1;                   // Run in standby
 | 
			
		||||
    dmac->Channel[0].CHCTRLA.bit.THRESHOLD = 0;                  // 1BEAT
 | 
			
		||||
    dmac->Channel[0].CHCTRLA.bit.BURSTLEN  = 0;                  // SINGLE
 | 
			
		||||
    dmac->Channel[0].CHCTRLA.bit.TRIGACT   = 2;                  // BURST
 | 
			
		||||
    dmac->Channel[0].CHCTRLA.bit.TRIGSRC   = SERCOM1_DMAC_ID_TX; // Trigger source
 | 
			
		||||
    dmac->Channel[0].CHCTRLA.bit.RUNSTDBY  = 1;                  // Run in standby
 | 
			
		||||
 | 
			
		||||
    NVIC_EnableIRQ(DMAC_0_IRQn);
 | 
			
		||||
    dmac->Channel[0].CHINTENSET.bit.TCMPL = 1;
 | 
			
		||||
    dmac->Channel[0].CHINTENSET.bit.TERR  = 1;
 | 
			
		||||
 | 
			
		||||
    // Enable device
 | 
			
		||||
    dmac->CTRL.bit.DMAENABLE = 1;  // Enable DMAC
 | 
			
		||||
    dmac->CTRL.bit.DMAENABLE = 1; // Enable DMAC
 | 
			
		||||
    while (dmac->CTRL.bit.DMAENABLE == 0) {
 | 
			
		||||
    }  // Wait for enable state
 | 
			
		||||
    } // Wait for enable state
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_I2C_DMAC_LED_INIT_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -377,14 +377,14 @@ void I2C3733_Control_Set(uint8_t state) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_desc_defaults(void) {
 | 
			
		||||
    dmac_desc.BTCTRL.bit.STEPSIZE = 0;  // SRCINC used in favor for auto 1 inc
 | 
			
		||||
    dmac_desc.BTCTRL.bit.STEPSEL  = 0;  // SRCINC used in favor for auto 1 inc
 | 
			
		||||
    dmac_desc.BTCTRL.bit.DSTINC   = 0;  // The Destination Address Increment is disabled
 | 
			
		||||
    dmac_desc.BTCTRL.bit.SRCINC   = 1;  // The Source Address Increment is enabled (Inc by 1)
 | 
			
		||||
    dmac_desc.BTCTRL.bit.BEATSIZE = 0;  // 8-bit bus transfer
 | 
			
		||||
    dmac_desc.BTCTRL.bit.BLOCKACT = 0;  // Channel will be disabled if it is the last block transfer in the transaction
 | 
			
		||||
    dmac_desc.BTCTRL.bit.EVOSEL   = 0;  // Event generation disabled
 | 
			
		||||
    dmac_desc.BTCTRL.bit.VALID    = 1;  // Set dmac valid
 | 
			
		||||
    dmac_desc.BTCTRL.bit.STEPSIZE = 0; // SRCINC used in favor for auto 1 inc
 | 
			
		||||
    dmac_desc.BTCTRL.bit.STEPSEL  = 0; // SRCINC used in favor for auto 1 inc
 | 
			
		||||
    dmac_desc.BTCTRL.bit.DSTINC   = 0; // The Destination Address Increment is disabled
 | 
			
		||||
    dmac_desc.BTCTRL.bit.SRCINC   = 1; // The Source Address Increment is enabled (Inc by 1)
 | 
			
		||||
    dmac_desc.BTCTRL.bit.BEATSIZE = 0; // 8-bit bus transfer
 | 
			
		||||
    dmac_desc.BTCTRL.bit.BLOCKACT = 0; // Channel will be disabled if it is the last block transfer in the transaction
 | 
			
		||||
    dmac_desc.BTCTRL.bit.EVOSEL   = 0; // Event generation disabled
 | 
			
		||||
    dmac_desc.BTCTRL.bit.VALID    = 1; // Set dmac valid
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_prepare_send_dma(uint8_t *data, uint8_t len) {
 | 
			
		||||
| 
						 | 
				
			
			@ -397,9 +397,9 @@ void i2c_led_prepare_send_dma(uint8_t *data, uint8_t len) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_begin_dma(uint8_t drvid) {
 | 
			
		||||
    DMAC->Channel[0].CHCTRLA.bit.ENABLE = 1;  // Enable the channel
 | 
			
		||||
    DMAC->Channel[0].CHCTRLA.bit.ENABLE = 1; // Enable the channel
 | 
			
		||||
 | 
			
		||||
    SERCOM1->I2CM.ADDR.reg = (dmac_desc.BTCNT.reg << 16) | 0x2000 | issidrv[drvid].addr;  // Begin transfer
 | 
			
		||||
    SERCOM1->I2CM.ADDR.reg = (dmac_desc.BTCNT.reg << 16) | 0x2000 | issidrv[drvid].addr; // Begin transfer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_send_CRWL_dma(uint8_t drvid) {
 | 
			
		||||
| 
						 | 
				
			
			@ -429,7 +429,7 @@ void i2c_led_send_GCR_dma(uint8_t drvid) {
 | 
			
		|||
void i2c_led_send_pwm_dma(uint8_t drvid) {
 | 
			
		||||
    // Note: This copies the CURRENT pwm buffer, which may be getting modified
 | 
			
		||||
    memcpy(dma_sendbuf, issidrv[drvid].pwm, ISSI3733_PG1_BYTES);
 | 
			
		||||
    *dma_sendbuf = 0;  // Force start location offset to zero
 | 
			
		||||
    *dma_sendbuf = 0; // Force start location offset to zero
 | 
			
		||||
    i2c_led_prepare_send_dma(dma_sendbuf, ISSI3733_PG1_BYTES);
 | 
			
		||||
 | 
			
		||||
    i2c_led_begin_dma(drvid);
 | 
			
		||||
| 
						 | 
				
			
			@ -438,7 +438,7 @@ void i2c_led_send_pwm_dma(uint8_t drvid) {
 | 
			
		|||
void i2c_led_send_onoff_dma(uint8_t drvid) {
 | 
			
		||||
    // Note: This copies the CURRENT onoff buffer, which may be getting modified
 | 
			
		||||
    memcpy(dma_sendbuf, issidrv[drvid].onoff, ISSI3733_PG0_BYTES);
 | 
			
		||||
    *dma_sendbuf = 0;  // Force start location offset to zero
 | 
			
		||||
    *dma_sendbuf = 0; // Force start location offset to zero
 | 
			
		||||
    i2c_led_prepare_send_dma(dma_sendbuf, ISSI3733_PG0_BYTES);
 | 
			
		||||
 | 
			
		||||
    i2c_led_begin_dma(drvid);
 | 
			
		||||
| 
						 | 
				
			
			@ -452,12 +452,16 @@ void i2c_led_q_init(void) {
 | 
			
		|||
    i2c_led_q_full    = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t i2c_led_q_isempty(void) { return i2c_led_q_s == i2c_led_q_e; }
 | 
			
		||||
uint8_t i2c_led_q_isempty(void) {
 | 
			
		||||
    return i2c_led_q_s == i2c_led_q_e;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t i2c_led_q_size(void) { return (i2c_led_q_e - i2c_led_q_s) % I2C_Q_SIZE; }
 | 
			
		||||
uint8_t i2c_led_q_size(void) {
 | 
			
		||||
    return (i2c_led_q_e - i2c_led_q_s) % I2C_Q_SIZE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t i2c_led_q_available(void) {
 | 
			
		||||
    return I2C_Q_SIZE - i2c_led_q_size() - 1;  // Never allow end to meet start
 | 
			
		||||
    return I2C_Q_SIZE - i2c_led_q_size() - 1; // Never allow end to meet start
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_q_add(uint8_t cmd) {
 | 
			
		||||
| 
						 | 
				
			
			@ -466,11 +470,11 @@ void i2c_led_q_add(uint8_t cmd) {
 | 
			
		|||
    // Assign command
 | 
			
		||||
    i2c_led_q[i2c_led_q_e] = cmd;
 | 
			
		||||
 | 
			
		||||
    i2c_led_q_e = (i2c_led_q_e + 1) % I2C_Q_SIZE;  // Move end up one or wrap
 | 
			
		||||
    i2c_led_q_e = (i2c_led_q_e + 1) % I2C_Q_SIZE; // Move end up one or wrap
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_q_s_advance(void) {
 | 
			
		||||
    i2c_led_q_s = (i2c_led_q_s + 1) % I2C_Q_SIZE;  // Move start up one or wrap
 | 
			
		||||
    i2c_led_q_s = (i2c_led_q_s + 1) % I2C_Q_SIZE; // Move start up one or wrap
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Always request room before adding commands
 | 
			
		||||
| 
						 | 
				
			
			@ -480,7 +484,7 @@ uint8_t i2c_led_q_request_room(uint8_t request_size) {
 | 
			
		|||
    if (request_size > i2c_led_q_available()) {
 | 
			
		||||
        i2c_led_q_full++;
 | 
			
		||||
 | 
			
		||||
        if (i2c_led_q_full >= 100)  // Give the queue a chance to clear up
 | 
			
		||||
        if (i2c_led_q_full >= 100) // Give the queue a chance to clear up
 | 
			
		||||
        {
 | 
			
		||||
            DBG_LED_ON;
 | 
			
		||||
            I2C_DMAC_LED_Init();
 | 
			
		||||
| 
						 | 
				
			
			@ -554,7 +558,7 @@ uint8_t i2c_led_q_run(void) {
 | 
			
		|||
#    endif
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        i2c_led_q_s_advance();  // Advance last run command or if the command byte was not serviced
 | 
			
		||||
        i2c_led_q_s_advance(); // Advance last run command or if the command byte was not serviced
 | 
			
		||||
 | 
			
		||||
#    if I2C_LED_USE_DMA != 1
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -583,4 +587,4 @@ i2c_status_t i2c_transmit(uint8_t address, const uint8_t *data, uint16_t length,
 | 
			
		|||
    return ret ? I2C_STATUS_SUCCESS : I2C_STATUS_ERROR;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif  // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
 | 
			
		||||
#endif // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -95,7 +95,7 @@ void    i2c1_init(void);
 | 
			
		|||
uint8_t i2c1_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout);
 | 
			
		||||
void    i2c1_stop(void);
 | 
			
		||||
 | 
			
		||||
#endif  // MD_BOOTLOADER
 | 
			
		||||
#endif // MD_BOOTLOADER
 | 
			
		||||
 | 
			
		||||
void    i2c0_init(void);
 | 
			
		||||
uint8_t i2c0_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout);
 | 
			
		||||
| 
						 | 
				
			
			@ -110,4 +110,4 @@ typedef int16_t i2c_status_t;
 | 
			
		|||
void         i2c_init(void);
 | 
			
		||||
i2c_status_t i2c_transmit(uint8_t address, const uint8_t *data, uint16_t length, uint16_t timeout);
 | 
			
		||||
 | 
			
		||||
#endif  // _I2C_MASTER_H_
 | 
			
		||||
#endif // _I2C_MASTER_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,29 +20,29 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
 | 
			
		||||
// ISII3733 Registers
 | 
			
		||||
 | 
			
		||||
#define ISSI3733_CMDR 0xFD  // Command Register (Write Only)
 | 
			
		||||
#define ISSI3733_CMDR 0xFD // Command Register (Write Only)
 | 
			
		||||
 | 
			
		||||
#define ISSI3733_CMDRWL 0xFE                    // Command Register Write Lock (Read/Write)
 | 
			
		||||
#define ISSI3733_CMDRWL_WRITE_DISABLE 0x00      // Lock register
 | 
			
		||||
#define ISSI3733_CMDRWL_WRITE_ENABLE_ONCE 0xC5  // Enable one write to register then reset to locked
 | 
			
		||||
#define ISSI3733_CMDRWL 0xFE                   // Command Register Write Lock (Read/Write)
 | 
			
		||||
#define ISSI3733_CMDRWL_WRITE_DISABLE 0x00     // Lock register
 | 
			
		||||
#define ISSI3733_CMDRWL_WRITE_ENABLE_ONCE 0xC5 // Enable one write to register then reset to locked
 | 
			
		||||
 | 
			
		||||
#define ISSI3733_IMR 0xF0         // Interrupt Mask Register (Write Only)
 | 
			
		||||
#define ISSI3733_IMR_IAC_ON 0x08  // Auto Clear Interrupt Bit - Interrupt auto clear when INTB stay low exceeds 8ms
 | 
			
		||||
#define ISSI3733_IMR_IAB_ON 0x04  // Auto Breath Interrupt Bit - Enable auto breath loop finish interrupt
 | 
			
		||||
#define ISSI3733_IMR_IS_ON 0x02   // Dot Short Interrupt Bit - Enable dot short interrupt
 | 
			
		||||
#define ISSI3733_IMR_IO_ON 0x01   // Dot Open Interrupt Bit - Enable dot open interrupt
 | 
			
		||||
#define ISSI3733_IMR 0xF0        // Interrupt Mask Register (Write Only)
 | 
			
		||||
#define ISSI3733_IMR_IAC_ON 0x08 // Auto Clear Interrupt Bit - Interrupt auto clear when INTB stay low exceeds 8ms
 | 
			
		||||
#define ISSI3733_IMR_IAB_ON 0x04 // Auto Breath Interrupt Bit - Enable auto breath loop finish interrupt
 | 
			
		||||
#define ISSI3733_IMR_IS_ON 0x02  // Dot Short Interrupt Bit - Enable dot short interrupt
 | 
			
		||||
#define ISSI3733_IMR_IO_ON 0x01  // Dot Open Interrupt Bit - Enable dot open interrupt
 | 
			
		||||
 | 
			
		||||
#define ISSI3733_ISR 0xF1              // Interrupt Status Register (Read Only)
 | 
			
		||||
#define ISSI3733_ISR_ABM3_FINISH 0x10  // Auto Breath Mode 3 Finish Bit - ABM3 finished
 | 
			
		||||
#define ISSI3733_ISR_ABM2_FINISH 0x08  // Auto Breath Mode 2 Finish Bit - ABM2 finished
 | 
			
		||||
#define ISSI3733_ISR_ABM1_FINISH 0x04  // Auto Breath Mode 1 Finish Bit - ABM1 finished
 | 
			
		||||
#define ISSI3733_ISR_SB 0x02           // Short Bit - Shorted
 | 
			
		||||
#define ISSI3733_ISR_OB 0x01           // Open Bit - Opened
 | 
			
		||||
#define ISSI3733_ISR 0xF1             // Interrupt Status Register (Read Only)
 | 
			
		||||
#define ISSI3733_ISR_ABM3_FINISH 0x10 // Auto Breath Mode 3 Finish Bit - ABM3 finished
 | 
			
		||||
#define ISSI3733_ISR_ABM2_FINISH 0x08 // Auto Breath Mode 2 Finish Bit - ABM2 finished
 | 
			
		||||
#define ISSI3733_ISR_ABM1_FINISH 0x04 // Auto Breath Mode 1 Finish Bit - ABM1 finished
 | 
			
		||||
#define ISSI3733_ISR_SB 0x02          // Short Bit - Shorted
 | 
			
		||||
#define ISSI3733_ISR_OB 0x01          // Open Bit - Opened
 | 
			
		||||
 | 
			
		||||
#define ISSI3733_PG0 0x00  // LED Control Register
 | 
			
		||||
#define ISSI3733_PG1 0x01  // PWM Register
 | 
			
		||||
#define ISSI3733_PG2 0x02  // Auto Breath Mode Register
 | 
			
		||||
#define ISSI3733_PG3 0x03  // Function Register
 | 
			
		||||
#define ISSI3733_PG0 0x00 // LED Control Register
 | 
			
		||||
#define ISSI3733_PG1 0x01 // PWM Register
 | 
			
		||||
#define ISSI3733_PG2 0x02 // Auto Breath Mode Register
 | 
			
		||||
#define ISSI3733_PG3 0x03 // Function Register
 | 
			
		||||
 | 
			
		||||
#define ISSI3733_PG_ONOFF ISSI3733_PG0
 | 
			
		||||
#define ISSI3733_PG_OR ISSI3733_PG0
 | 
			
		||||
| 
						 | 
				
			
			@ -51,88 +51,88 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#define ISSI3733_PG_ABM ISSI3733_PG2
 | 
			
		||||
#define ISSI3733_PG_FN ISSI3733_PG3
 | 
			
		||||
 | 
			
		||||
#define ISSI3733_CR 0x00  // Configuration Register
 | 
			
		||||
#define ISSI3733_CR 0x00 // Configuration Register
 | 
			
		||||
 | 
			
		||||
// PG3: Configuration Register: Synchronize Configuration
 | 
			
		||||
#define ISSI3733_CR_SYNC_MASTER 0x40    // Master
 | 
			
		||||
#define ISSI3733_CR_SYNC_SLAVE 0x80     // Slave
 | 
			
		||||
#define ISSI3733_CR_SYNC_HIGH_IMP 0xC0  // High Impedance
 | 
			
		||||
#define ISSI3733_CR_SYNC_MASTER 0x40   // Master
 | 
			
		||||
#define ISSI3733_CR_SYNC_SLAVE 0x80    // Slave
 | 
			
		||||
#define ISSI3733_CR_SYNC_HIGH_IMP 0xC0 // High Impedance
 | 
			
		||||
 | 
			
		||||
// PG3: Configuration Register: Open/Short Detection Enable Bit
 | 
			
		||||
//#define ISSI3733_CR_OSD_DISABLE 0x00          //Disable open/short detection
 | 
			
		||||
#define ISSI3733_CR_OSD_ENABLE 0x04  // Enable open/short detection
 | 
			
		||||
#define ISSI3733_CR_OSD_ENABLE 0x04 // Enable open/short detection
 | 
			
		||||
 | 
			
		||||
// PG3: Configuration Register: Auto Breath Enable
 | 
			
		||||
//#define ISSI3733_CR_B_EN_PWM 0x00             //PWM Mode Enable
 | 
			
		||||
#define ISSI3733_CR_B_EN_AUTO 0x02  // Auto Breath Mode Enable
 | 
			
		||||
#define ISSI3733_CR_B_EN_AUTO 0x02 // Auto Breath Mode Enable
 | 
			
		||||
 | 
			
		||||
// PG3: Configuration Register: Software Shutdown Control
 | 
			
		||||
//#define ISSI3733_CR_SSD_SHUTDOWN 0x00         //Software shutdown
 | 
			
		||||
#define ISSI3733_CR_SSD_NORMAL 0x01  // Normal operation
 | 
			
		||||
#define ISSI3733_CR_SSD_NORMAL 0x01 // Normal operation
 | 
			
		||||
 | 
			
		||||
#define ISSI3733_GCCR 0x01  // Global Current Control Register
 | 
			
		||||
#define ISSI3733_GCCR 0x01 // Global Current Control Register
 | 
			
		||||
 | 
			
		||||
// 1 Byte, Iout = (GCC / 256) * (840 / Rext)
 | 
			
		||||
// TODO: Give user define for Rext
 | 
			
		||||
 | 
			
		||||
// PG3: Auto Breath Control Register 1
 | 
			
		||||
#define ISSI3733_ABCR1_ABM1 0x02  // Auto Breath Control Register 1 of ABM-1
 | 
			
		||||
#define ISSI3733_ABCR1_ABM2 0x06  // Auto Breath Control Register 1 of ABM-2
 | 
			
		||||
#define ISSI3733_ABCR1_ABM3 0x0A  // Auto Breath Control Register 1 of ABM-3
 | 
			
		||||
#define ISSI3733_ABCR1_ABM1 0x02 // Auto Breath Control Register 1 of ABM-1
 | 
			
		||||
#define ISSI3733_ABCR1_ABM2 0x06 // Auto Breath Control Register 1 of ABM-2
 | 
			
		||||
#define ISSI3733_ABCR1_ABM3 0x0A // Auto Breath Control Register 1 of ABM-3
 | 
			
		||||
 | 
			
		||||
// Rise time
 | 
			
		||||
#define ISSI3733_ABCR1_T1_0021 0x00  // 0.21s
 | 
			
		||||
#define ISSI3733_ABCR1_T1_0042 0x20  // 0.42s
 | 
			
		||||
#define ISSI3733_ABCR1_T1_0084 0x40  // 0.84s
 | 
			
		||||
#define ISSI3733_ABCR1_T1_0168 0x60  // 1.68s
 | 
			
		||||
#define ISSI3733_ABCR1_T1_0336 0x80  // 3.36s
 | 
			
		||||
#define ISSI3733_ABCR1_T1_0672 0xA0  // 6.72s
 | 
			
		||||
#define ISSI3733_ABCR1_T1_1344 0xC0  // 13.44s
 | 
			
		||||
#define ISSI3733_ABCR1_T1_2688 0xE0  // 26.88s
 | 
			
		||||
#define ISSI3733_ABCR1_T1_0021 0x00 // 0.21s
 | 
			
		||||
#define ISSI3733_ABCR1_T1_0042 0x20 // 0.42s
 | 
			
		||||
#define ISSI3733_ABCR1_T1_0084 0x40 // 0.84s
 | 
			
		||||
#define ISSI3733_ABCR1_T1_0168 0x60 // 1.68s
 | 
			
		||||
#define ISSI3733_ABCR1_T1_0336 0x80 // 3.36s
 | 
			
		||||
#define ISSI3733_ABCR1_T1_0672 0xA0 // 6.72s
 | 
			
		||||
#define ISSI3733_ABCR1_T1_1344 0xC0 // 13.44s
 | 
			
		||||
#define ISSI3733_ABCR1_T1_2688 0xE0 // 26.88s
 | 
			
		||||
 | 
			
		||||
// Max value time
 | 
			
		||||
#define ISSI3733_ABCR1_T2_0000 0x00  // 0s
 | 
			
		||||
#define ISSI3733_ABCR1_T2_0021 0x02  // 0.21s
 | 
			
		||||
#define ISSI3733_ABCR1_T2_0042 0x04  // 0.42s
 | 
			
		||||
#define ISSI3733_ABCR1_T2_0084 0x06  // 0.84s
 | 
			
		||||
#define ISSI3733_ABCR1_T2_0168 0x08  // 1.68s
 | 
			
		||||
#define ISSI3733_ABCR1_T2_0336 0x0A  // 3.36s
 | 
			
		||||
#define ISSI3733_ABCR1_T2_0672 0x0C  // 6.72s
 | 
			
		||||
#define ISSI3733_ABCR1_T2_1344 0x0E  // 13.44s
 | 
			
		||||
#define ISSI3733_ABCR1_T2_2688 0x10  // 26.88s
 | 
			
		||||
#define ISSI3733_ABCR1_T2_0000 0x00 // 0s
 | 
			
		||||
#define ISSI3733_ABCR1_T2_0021 0x02 // 0.21s
 | 
			
		||||
#define ISSI3733_ABCR1_T2_0042 0x04 // 0.42s
 | 
			
		||||
#define ISSI3733_ABCR1_T2_0084 0x06 // 0.84s
 | 
			
		||||
#define ISSI3733_ABCR1_T2_0168 0x08 // 1.68s
 | 
			
		||||
#define ISSI3733_ABCR1_T2_0336 0x0A // 3.36s
 | 
			
		||||
#define ISSI3733_ABCR1_T2_0672 0x0C // 6.72s
 | 
			
		||||
#define ISSI3733_ABCR1_T2_1344 0x0E // 13.44s
 | 
			
		||||
#define ISSI3733_ABCR1_T2_2688 0x10 // 26.88s
 | 
			
		||||
 | 
			
		||||
// PG3: Auto Breath Control Register 2
 | 
			
		||||
#define ISSI3733_ABCR2_ABM1 0x03  // Auto Breath Control Register 2 of ABM-1
 | 
			
		||||
#define ISSI3733_ABCR2_ABM2 0x07  // Auto Breath Control Register 2 of ABM-2
 | 
			
		||||
#define ISSI3733_ABCR2_ABM3 0x0B  // Auto Breath Control Register 2 of ABM-3
 | 
			
		||||
#define ISSI3733_ABCR2_ABM1 0x03 // Auto Breath Control Register 2 of ABM-1
 | 
			
		||||
#define ISSI3733_ABCR2_ABM2 0x07 // Auto Breath Control Register 2 of ABM-2
 | 
			
		||||
#define ISSI3733_ABCR2_ABM3 0x0B // Auto Breath Control Register 2 of ABM-3
 | 
			
		||||
 | 
			
		||||
// Fall time
 | 
			
		||||
#define ISSI3733_ABCR2_T3_0021 0x00  // 0.21s
 | 
			
		||||
#define ISSI3733_ABCR2_T3_0042 0x20  // 0.42s
 | 
			
		||||
#define ISSI3733_ABCR2_T3_0084 0x40  // 0.84s
 | 
			
		||||
#define ISSI3733_ABCR2_T3_0168 0x60  // 1.68s
 | 
			
		||||
#define ISSI3733_ABCR2_T3_0336 0x80  // 3.36s
 | 
			
		||||
#define ISSI3733_ABCR2_T3_0672 0xA0  // 6.72s
 | 
			
		||||
#define ISSI3733_ABCR2_T3_1344 0xC0  // 13.44s
 | 
			
		||||
#define ISSI3733_ABCR2_T3_2688 0xE0  // 26.88s
 | 
			
		||||
#define ISSI3733_ABCR2_T3_0021 0x00 // 0.21s
 | 
			
		||||
#define ISSI3733_ABCR2_T3_0042 0x20 // 0.42s
 | 
			
		||||
#define ISSI3733_ABCR2_T3_0084 0x40 // 0.84s
 | 
			
		||||
#define ISSI3733_ABCR2_T3_0168 0x60 // 1.68s
 | 
			
		||||
#define ISSI3733_ABCR2_T3_0336 0x80 // 3.36s
 | 
			
		||||
#define ISSI3733_ABCR2_T3_0672 0xA0 // 6.72s
 | 
			
		||||
#define ISSI3733_ABCR2_T3_1344 0xC0 // 13.44s
 | 
			
		||||
#define ISSI3733_ABCR2_T3_2688 0xE0 // 26.88s
 | 
			
		||||
 | 
			
		||||
// Min value time
 | 
			
		||||
#define ISSI3733_ABCR2_T4_0000 0x00   // 0s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_0021 0x02   // 0.21s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_0042 0x04   // 0.42s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_0084 0x06   // 0.84s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_0168 0x08   // 1.68s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_0336 0x0A   // 3.36s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_0672 0x0C   // 6.72s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_1344 0x0E   // 13.44s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_2688 0x10   // 26.88s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_5376 0x12   // 53.76s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_10752 0x14  // 107.52s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_0000 0x00  // 0s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_0021 0x02  // 0.21s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_0042 0x04  // 0.42s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_0084 0x06  // 0.84s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_0168 0x08  // 1.68s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_0336 0x0A  // 3.36s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_0672 0x0C  // 6.72s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_1344 0x0E  // 13.44s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_2688 0x10  // 26.88s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_5376 0x12  // 53.76s
 | 
			
		||||
#define ISSI3733_ABCR2_T4_10752 0x14 // 107.52s
 | 
			
		||||
 | 
			
		||||
// PG3: Auto Breath Control Register 3
 | 
			
		||||
#define ISSI3733_ABCR3_ABM1 0x04  // Auto Breath Control Register 3 of ABM-1
 | 
			
		||||
#define ISSI3733_ABCR3_ABM2 0x08  // Auto Breath Control Register 3 of ABM-2
 | 
			
		||||
#define ISSI3733_ABCR3_ABM3 0x0C  // Auto Breath Control Register 3 of ABM-3
 | 
			
		||||
#define ISSI3733_ABCR3_ABM1 0x04 // Auto Breath Control Register 3 of ABM-1
 | 
			
		||||
#define ISSI3733_ABCR3_ABM2 0x08 // Auto Breath Control Register 3 of ABM-2
 | 
			
		||||
#define ISSI3733_ABCR3_ABM3 0x0C // Auto Breath Control Register 3 of ABM-3
 | 
			
		||||
 | 
			
		||||
#define ISSI3733_ABCR3_LTA_LOOP_ENDLESS 0x00
 | 
			
		||||
#define ISSI3733_ABCR3_LTA_LOOP_1 0x01
 | 
			
		||||
| 
						 | 
				
			
			@ -158,44 +158,44 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#define ISSI3733_ABCR3_LB_T4 0x30
 | 
			
		||||
 | 
			
		||||
// Loop End
 | 
			
		||||
#define ISSI3733_ABCR3_LE_T3 0x00  // End at Off state
 | 
			
		||||
#define ISSI3733_ABCR3_LE_T1 0x40  // End at On State
 | 
			
		||||
#define ISSI3733_ABCR3_LE_T3 0x00 // End at Off state
 | 
			
		||||
#define ISSI3733_ABCR3_LE_T1 0x40 // End at On State
 | 
			
		||||
 | 
			
		||||
// PG3: Auto Breath Control Register 4
 | 
			
		||||
#define ISSI3733_ABCR4_ABM1 0x05  // Auto Breath Control Register 4 of ABM-1
 | 
			
		||||
#define ISSI3733_ABCR4_ABM2 0x09  // Auto Breath Control Register 4 of ABM-2
 | 
			
		||||
#define ISSI3733_ABCR4_ABM3 0x0D  // Auto Breath Control Register 4 of ABM-3
 | 
			
		||||
#define ISSI3733_ABCR4_ABM1 0x05 // Auto Breath Control Register 4 of ABM-1
 | 
			
		||||
#define ISSI3733_ABCR4_ABM2 0x09 // Auto Breath Control Register 4 of ABM-2
 | 
			
		||||
#define ISSI3733_ABCR4_ABM3 0x0D // Auto Breath Control Register 4 of ABM-3
 | 
			
		||||
 | 
			
		||||
#define ISSI3733_ABCR4_LTB_LOOP_ENDLESS 0x00
 | 
			
		||||
// Or 8bit loop times
 | 
			
		||||
 | 
			
		||||
// PG3: Time Update Register
 | 
			
		||||
#define ISSI3733_TUR 0x0E
 | 
			
		||||
#define ISSI3733_TUR_UPDATE 0x00  // Write to update 02h~0Dh time registers after configuring
 | 
			
		||||
#define ISSI3733_TUR_UPDATE 0x00 // Write to update 02h~0Dh time registers after configuring
 | 
			
		||||
 | 
			
		||||
// PG3: SWy Pull-Up Resistor Selection Register
 | 
			
		||||
#define ISSI3733_SWYR_PUR 0x0F
 | 
			
		||||
#define ISSI3733_SWYR_PUR_NONE 0x00   // No pull-up resistor
 | 
			
		||||
#define ISSI3733_SWYR_PUR_500 0x01    // 0.5k Ohm
 | 
			
		||||
#define ISSI3733_SWYR_PUR_1000 0x02   // 1.0k Ohm
 | 
			
		||||
#define ISSI3733_SWYR_PUR_2000 0x03   // 2.0k Ohm
 | 
			
		||||
#define ISSI3733_SWYR_PUR_4000 0x04   // 4.0k Ohm
 | 
			
		||||
#define ISSI3733_SWYR_PUR_8000 0x05   // 8.0k Ohm
 | 
			
		||||
#define ISSI3733_SWYR_PUR_16000 0x06  // 16k Ohm
 | 
			
		||||
#define ISSI3733_SWYR_PUR_32000 0x07  // 32k Ohm
 | 
			
		||||
#define ISSI3733_SWYR_PUR_NONE 0x00  // No pull-up resistor
 | 
			
		||||
#define ISSI3733_SWYR_PUR_500 0x01   // 0.5k Ohm
 | 
			
		||||
#define ISSI3733_SWYR_PUR_1000 0x02  // 1.0k Ohm
 | 
			
		||||
#define ISSI3733_SWYR_PUR_2000 0x03  // 2.0k Ohm
 | 
			
		||||
#define ISSI3733_SWYR_PUR_4000 0x04  // 4.0k Ohm
 | 
			
		||||
#define ISSI3733_SWYR_PUR_8000 0x05  // 8.0k Ohm
 | 
			
		||||
#define ISSI3733_SWYR_PUR_16000 0x06 // 16k Ohm
 | 
			
		||||
#define ISSI3733_SWYR_PUR_32000 0x07 // 32k Ohm
 | 
			
		||||
 | 
			
		||||
// PG3: CSx Pull-Down Resistor Selection Register
 | 
			
		||||
#define ISSI3733_CSXR_PDR 0x10
 | 
			
		||||
#define ISSI3733_CSXR_PDR_NONE 0x00   // No pull-down resistor
 | 
			
		||||
#define ISSI3733_CSXR_PDR_500 0x01    // 0.5k Ohm
 | 
			
		||||
#define ISSI3733_CSXR_PDR_1000 0x02   // 1.0k Ohm
 | 
			
		||||
#define ISSI3733_CSXR_PDR_2000 0x03   // 2.0k Ohm
 | 
			
		||||
#define ISSI3733_CSXR_PDR_4000 0x04   // 4.0k Ohm
 | 
			
		||||
#define ISSI3733_CSXR_PDR_8000 0x05   // 8.0k Ohm
 | 
			
		||||
#define ISSI3733_CSXR_PDR_16000 0x06  // 16k Ohm
 | 
			
		||||
#define ISSI3733_CSXR_PDR_32000 0x07  // 32k Ohm
 | 
			
		||||
#define ISSI3733_CSXR_PDR_NONE 0x00  // No pull-down resistor
 | 
			
		||||
#define ISSI3733_CSXR_PDR_500 0x01   // 0.5k Ohm
 | 
			
		||||
#define ISSI3733_CSXR_PDR_1000 0x02  // 1.0k Ohm
 | 
			
		||||
#define ISSI3733_CSXR_PDR_2000 0x03  // 2.0k Ohm
 | 
			
		||||
#define ISSI3733_CSXR_PDR_4000 0x04  // 4.0k Ohm
 | 
			
		||||
#define ISSI3733_CSXR_PDR_8000 0x05  // 8.0k Ohm
 | 
			
		||||
#define ISSI3733_CSXR_PDR_16000 0x06 // 16k Ohm
 | 
			
		||||
#define ISSI3733_CSXR_PDR_32000 0x07 // 32k Ohm
 | 
			
		||||
 | 
			
		||||
// PG3: Reset Register
 | 
			
		||||
#define ISSI3733_RR 0x11  // Read to reset all registers to default values
 | 
			
		||||
#define ISSI3733_RR 0x11 // Read to reset all registers to default values
 | 
			
		||||
 | 
			
		||||
#endif  //_ISSI3733_DRIVER_H_
 | 
			
		||||
#endif //_ISSI3733_DRIVER_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,7 +31,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
// From keyboard's directory
 | 
			
		||||
#include "config_led.h"
 | 
			
		||||
 | 
			
		||||
uint8_t g_usb_state = USB_FSMSTATUS_FSMSTATE_OFF_Val;  // Saved USB state from hardware value to detect changes
 | 
			
		||||
uint8_t g_usb_state = USB_FSMSTATUS_FSMSTATE_OFF_Val; // Saved USB state from hardware value to detect changes
 | 
			
		||||
 | 
			
		||||
void    main_subtasks(void);
 | 
			
		||||
uint8_t keyboard_leds(void);
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +42,7 @@ void    send_consumer(uint16_t data);
 | 
			
		|||
 | 
			
		||||
#ifdef DEFERRED_EXEC_ENABLE
 | 
			
		||||
void deferred_exec_task(void);
 | 
			
		||||
#endif  // DEFERRED_EXEC_ENABLE
 | 
			
		||||
#endif // DEFERRED_EXEC_ENABLE
 | 
			
		||||
 | 
			
		||||
host_driver_t arm_atsam_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +53,7 @@ uint8_t keyboard_leds(void) {
 | 
			
		|||
    if (keymap_config.nkro)
 | 
			
		||||
        return udi_hid_nkro_report_set;
 | 
			
		||||
    else
 | 
			
		||||
#endif  // NKRO_ENABLE
 | 
			
		||||
#endif // NKRO_ENABLE
 | 
			
		||||
        return udi_hid_kbd_report_set;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -62,10 +62,10 @@ void send_keyboard(report_keyboard_t *report) {
 | 
			
		|||
 | 
			
		||||
#ifdef NKRO_ENABLE
 | 
			
		||||
    if (!keymap_config.nkro) {
 | 
			
		||||
#endif  // NKRO_ENABLE
 | 
			
		||||
#endif // NKRO_ENABLE
 | 
			
		||||
        while (udi_hid_kbd_b_report_trans_ongoing) {
 | 
			
		||||
            main_subtasks();
 | 
			
		||||
        }  // Run other tasks while waiting for USB to be free
 | 
			
		||||
        } // Run other tasks while waiting for USB to be free
 | 
			
		||||
 | 
			
		||||
        irqflags = __get_PRIMASK();
 | 
			
		||||
        __disable_irq();
 | 
			
		||||
| 
						 | 
				
			
			@ -81,7 +81,7 @@ void send_keyboard(report_keyboard_t *report) {
 | 
			
		|||
    } else {
 | 
			
		||||
        while (udi_hid_nkro_b_report_trans_ongoing) {
 | 
			
		||||
            main_subtasks();
 | 
			
		||||
        }  // Run other tasks while waiting for USB to be free
 | 
			
		||||
        } // Run other tasks while waiting for USB to be free
 | 
			
		||||
 | 
			
		||||
        irqflags = __get_PRIMASK();
 | 
			
		||||
        __disable_irq();
 | 
			
		||||
| 
						 | 
				
			
			@ -94,7 +94,7 @@ void send_keyboard(report_keyboard_t *report) {
 | 
			
		|||
        __DMB();
 | 
			
		||||
        __set_PRIMASK(irqflags);
 | 
			
		||||
    }
 | 
			
		||||
#endif  // NKRO_ENABLE
 | 
			
		||||
#endif // NKRO_ENABLE
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void send_mouse(report_mouse_t *report) {
 | 
			
		||||
| 
						 | 
				
			
			@ -111,7 +111,7 @@ void send_mouse(report_mouse_t *report) {
 | 
			
		|||
 | 
			
		||||
    __DMB();
 | 
			
		||||
    __set_PRIMASK(irqflags);
 | 
			
		||||
#endif  // MOUSEKEY_ENABLE
 | 
			
		||||
#endif // MOUSEKEY_ENABLE
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef EXTRAKEY_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			@ -130,18 +130,18 @@ void send_extra(uint8_t report_id, uint16_t data) {
 | 
			
		|||
    __DMB();
 | 
			
		||||
    __set_PRIMASK(irqflags);
 | 
			
		||||
}
 | 
			
		||||
#endif  // EXTRAKEY_ENABLE
 | 
			
		||||
#endif // EXTRAKEY_ENABLE
 | 
			
		||||
 | 
			
		||||
void send_system(uint16_t data) {
 | 
			
		||||
#ifdef EXTRAKEY_ENABLE
 | 
			
		||||
    send_extra(REPORT_ID_SYSTEM, data);
 | 
			
		||||
#endif  // EXTRAKEY_ENABLE
 | 
			
		||||
#endif // EXTRAKEY_ENABLE
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void send_consumer(uint16_t data) {
 | 
			
		||||
#ifdef EXTRAKEY_ENABLE
 | 
			
		||||
    send_extra(REPORT_ID_CONSUMER, data);
 | 
			
		||||
#endif  // EXTRAKEY_ENABLE
 | 
			
		||||
#endif // EXTRAKEY_ENABLE
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			@ -158,81 +158,81 @@ int8_t sendchar(uint8_t c) {
 | 
			
		|||
 | 
			
		||||
void main_subtask_console_flush(void) {
 | 
			
		||||
    while (udi_hid_con_b_report_trans_ongoing) {
 | 
			
		||||
    }  // Wait for any previous transfers to complete
 | 
			
		||||
    } // Wait for any previous transfers to complete
 | 
			
		||||
 | 
			
		||||
    uint16_t result = console_printbuf_len;
 | 
			
		||||
    uint32_t irqflags;
 | 
			
		||||
    char *   pconbuf  = console_printbuf;  // Pointer to start send from
 | 
			
		||||
    int      send_out = CONSOLE_EPSIZE;    // Bytes to send per transfer
 | 
			
		||||
    char *   pconbuf  = console_printbuf; // Pointer to start send from
 | 
			
		||||
    int      send_out = CONSOLE_EPSIZE;   // Bytes to send per transfer
 | 
			
		||||
 | 
			
		||||
    while (result > 0) {  // While not error and bytes remain
 | 
			
		||||
    while (result > 0) { // While not error and bytes remain
 | 
			
		||||
        while (udi_hid_con_b_report_trans_ongoing) {
 | 
			
		||||
        }  // Wait for any previous transfers to complete
 | 
			
		||||
        } // Wait for any previous transfers to complete
 | 
			
		||||
 | 
			
		||||
        irqflags = __get_PRIMASK();
 | 
			
		||||
        __disable_irq();
 | 
			
		||||
        __DMB();
 | 
			
		||||
 | 
			
		||||
        if (result < CONSOLE_EPSIZE) {                      // If remaining bytes are less than console epsize
 | 
			
		||||
            memset(udi_hid_con_report, 0, CONSOLE_EPSIZE);  // Clear the buffer
 | 
			
		||||
            send_out = result;                              // Send remaining size
 | 
			
		||||
        if (result < CONSOLE_EPSIZE) {                     // If remaining bytes are less than console epsize
 | 
			
		||||
            memset(udi_hid_con_report, 0, CONSOLE_EPSIZE); // Clear the buffer
 | 
			
		||||
            send_out = result;                             // Send remaining size
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        memcpy(udi_hid_con_report, pconbuf, send_out);  // Copy data into the send buffer
 | 
			
		||||
        memcpy(udi_hid_con_report, pconbuf, send_out); // Copy data into the send buffer
 | 
			
		||||
 | 
			
		||||
        udi_hid_con_b_report_valid = 1;  // Set report valid
 | 
			
		||||
        udi_hid_con_send_report();       // Send report
 | 
			
		||||
        udi_hid_con_b_report_valid = 1; // Set report valid
 | 
			
		||||
        udi_hid_con_send_report();      // Send report
 | 
			
		||||
 | 
			
		||||
        __DMB();
 | 
			
		||||
        __set_PRIMASK(irqflags);
 | 
			
		||||
 | 
			
		||||
        result -= send_out;   // Decrement result by bytes sent
 | 
			
		||||
        pconbuf += send_out;  // Increment buffer point by bytes sent
 | 
			
		||||
        result -= send_out;  // Decrement result by bytes sent
 | 
			
		||||
        pconbuf += send_out; // Increment buffer point by bytes sent
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    console_printbuf_len = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif  // CONSOLE_ENABLE
 | 
			
		||||
#endif // CONSOLE_ENABLE
 | 
			
		||||
 | 
			
		||||
void main_subtask_usb_state(void) {
 | 
			
		||||
    static uint64_t fsmstate_on_delay = 0;                          // Delay timer to be sure USB is actually operating before bringing up hardware
 | 
			
		||||
    uint8_t         fsmstate_now      = USB->DEVICE.FSMSTATUS.reg;  // Current state from hardware register
 | 
			
		||||
    static uint64_t fsmstate_on_delay = 0;                         // Delay timer to be sure USB is actually operating before bringing up hardware
 | 
			
		||||
    uint8_t         fsmstate_now      = USB->DEVICE.FSMSTATUS.reg; // Current state from hardware register
 | 
			
		||||
 | 
			
		||||
    if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SUSPEND_Val)  // If USB SUSPENDED
 | 
			
		||||
    if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SUSPEND_Val) // If USB SUSPENDED
 | 
			
		||||
    {
 | 
			
		||||
        fsmstate_on_delay = 0;  // Clear ON delay timer
 | 
			
		||||
        fsmstate_on_delay = 0; // Clear ON delay timer
 | 
			
		||||
 | 
			
		||||
        if (g_usb_state != USB_FSMSTATUS_FSMSTATE_SUSPEND_Val)  // If previously not SUSPENDED
 | 
			
		||||
        if (g_usb_state != USB_FSMSTATUS_FSMSTATE_SUSPEND_Val) // If previously not SUSPENDED
 | 
			
		||||
        {
 | 
			
		||||
            suspend_power_down();        // Run suspend routine
 | 
			
		||||
            g_usb_state = fsmstate_now;  // Save current USB state
 | 
			
		||||
            suspend_power_down();       // Run suspend routine
 | 
			
		||||
            g_usb_state = fsmstate_now; // Save current USB state
 | 
			
		||||
        }
 | 
			
		||||
    } else if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SLEEP_Val)  // Else if USB SLEEPING
 | 
			
		||||
    } else if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SLEEP_Val) // Else if USB SLEEPING
 | 
			
		||||
    {
 | 
			
		||||
        fsmstate_on_delay = 0;  // Clear ON delay timer
 | 
			
		||||
        fsmstate_on_delay = 0; // Clear ON delay timer
 | 
			
		||||
 | 
			
		||||
        if (g_usb_state != USB_FSMSTATUS_FSMSTATE_SLEEP_Val)  // If previously not SLEEPING
 | 
			
		||||
        if (g_usb_state != USB_FSMSTATUS_FSMSTATE_SLEEP_Val) // If previously not SLEEPING
 | 
			
		||||
        {
 | 
			
		||||
            suspend_power_down();        // Run suspend routine
 | 
			
		||||
            g_usb_state = fsmstate_now;  // Save current USB state
 | 
			
		||||
            suspend_power_down();       // Run suspend routine
 | 
			
		||||
            g_usb_state = fsmstate_now; // Save current USB state
 | 
			
		||||
        }
 | 
			
		||||
    } else if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_ON_Val)  // Else if USB ON
 | 
			
		||||
    } else if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_ON_Val) // Else if USB ON
 | 
			
		||||
    {
 | 
			
		||||
        if (g_usb_state != USB_FSMSTATUS_FSMSTATE_ON_Val)  // If previously not ON
 | 
			
		||||
        if (g_usb_state != USB_FSMSTATUS_FSMSTATE_ON_Val) // If previously not ON
 | 
			
		||||
        {
 | 
			
		||||
            if (fsmstate_on_delay == 0)  // If ON delay timer is cleared
 | 
			
		||||
            if (fsmstate_on_delay == 0) // If ON delay timer is cleared
 | 
			
		||||
            {
 | 
			
		||||
                fsmstate_on_delay = timer_read64() + 250;   // Set ON delay timer
 | 
			
		||||
            } else if (timer_read64() > fsmstate_on_delay)  // Else if ON delay timer is active and timed out
 | 
			
		||||
                fsmstate_on_delay = timer_read64() + 250;  // Set ON delay timer
 | 
			
		||||
            } else if (timer_read64() > fsmstate_on_delay) // Else if ON delay timer is active and timed out
 | 
			
		||||
            {
 | 
			
		||||
                suspend_wakeup_init();       // Run wakeup routine
 | 
			
		||||
                g_usb_state = fsmstate_now;  // Save current USB state
 | 
			
		||||
                suspend_wakeup_init();      // Run wakeup routine
 | 
			
		||||
                g_usb_state = fsmstate_now; // Save current USB state
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else  // Else if USB is in a state not being tracked
 | 
			
		||||
    } else // Else if USB is in a state not being tracked
 | 
			
		||||
    {
 | 
			
		||||
        fsmstate_on_delay = 0;  // Clear ON delay timer
 | 
			
		||||
        fsmstate_on_delay = 0; // Clear ON delay timer
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -262,7 +262,9 @@ void main_subtask_usb_extra_device(void) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
#ifdef RAW_ENABLE
 | 
			
		||||
void main_subtask_raw(void) { udi_hid_raw_receive_report(); }
 | 
			
		||||
void main_subtask_raw(void) {
 | 
			
		||||
    udi_hid_raw_receive_report();
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void main_subtasks(void) {
 | 
			
		||||
| 
						 | 
				
			
			@ -296,7 +298,7 @@ int main(void) {
 | 
			
		|||
 | 
			
		||||
#ifdef RGB_MATRIX_ENABLE
 | 
			
		||||
    i2c1_init();
 | 
			
		||||
#endif  // RGB_MATRIX_ENABLE
 | 
			
		||||
#endif // RGB_MATRIX_ENABLE
 | 
			
		||||
 | 
			
		||||
    matrix_init();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -325,8 +327,9 @@ int main(void) {
 | 
			
		|||
 | 
			
		||||
    i2c_led_q_init();
 | 
			
		||||
 | 
			
		||||
    for (uint8_t drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++) I2C_LED_Q_ONOFF(drvid);  // Queue data
 | 
			
		||||
#endif                                                                                       // RGB_MATRIX_ENABLE
 | 
			
		||||
    for (uint8_t drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++)
 | 
			
		||||
        I2C_LED_Q_ONOFF(drvid); // Queue data
 | 
			
		||||
#endif                          // RGB_MATRIX_ENABLE
 | 
			
		||||
 | 
			
		||||
    keyboard_setup();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -336,18 +339,18 @@ int main(void) {
 | 
			
		|||
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
    uint64_t next_print = 0;
 | 
			
		||||
#endif  // CONSOLE_ENABLE
 | 
			
		||||
#endif // CONSOLE_ENABLE
 | 
			
		||||
 | 
			
		||||
    v_5v_avg = adc_get(ADC_5V);
 | 
			
		||||
 | 
			
		||||
    debug_code_disable();
 | 
			
		||||
 | 
			
		||||
    while (1) {
 | 
			
		||||
        main_subtasks();  // Note these tasks will also be run while waiting for USB keyboard polling intervals
 | 
			
		||||
        main_subtasks(); // Note these tasks will also be run while waiting for USB keyboard polling intervals
 | 
			
		||||
 | 
			
		||||
        if (g_usb_state == USB_FSMSTATUS_FSMSTATE_SUSPEND_Val || g_usb_state == USB_FSMSTATUS_FSMSTATE_SLEEP_Val) {
 | 
			
		||||
            if (suspend_wakeup_condition()) {
 | 
			
		||||
                udc_remotewakeup();  // Send remote wakeup signal
 | 
			
		||||
                udc_remotewakeup(); // Send remote wakeup signal
 | 
			
		||||
                wait_ms(50);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -362,12 +365,12 @@ int main(void) {
 | 
			
		|||
            // Add any debug information here that you want to see very often
 | 
			
		||||
            // dprintf("5v=%u 5vu=%u dlow=%u dhi=%u gca=%u gcd=%u\r\n", v_5v, v_5v_avg, v_5v_avg - V5_LOW, v_5v_avg - V5_HIGH, gcr_actual, gcr_desired);
 | 
			
		||||
        }
 | 
			
		||||
#endif  // CONSOLE_ENABLE
 | 
			
		||||
#endif // CONSOLE_ENABLE
 | 
			
		||||
 | 
			
		||||
#ifdef DEFERRED_EXEC_ENABLE
 | 
			
		||||
        // Run deferred executions
 | 
			
		||||
        deferred_exec_task();
 | 
			
		||||
#endif  // DEFERRED_EXEC_ENABLE
 | 
			
		||||
#endif // DEFERRED_EXEC_ENABLE
 | 
			
		||||
 | 
			
		||||
        // Run housekeeping
 | 
			
		||||
        housekeeping_task();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,4 +20,4 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
 | 
			
		||||
uint8_t keyboard_leds(void);
 | 
			
		||||
 | 
			
		||||
#endif  //_MAIN_ARM_ATSAM_H_
 | 
			
		||||
#endif //_MAIN_ARM_ATSAM_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,16 +53,20 @@ void eeconfig_update_md_led_default(void) {
 | 
			
		|||
    eeconfig_flush_md_led(true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void md_led_changed(void) { eeconfig_flag_md_led(true); }
 | 
			
		||||
void md_led_changed(void) {
 | 
			
		||||
    eeconfig_flag_md_led(true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// todo: use real task rather than this bodge
 | 
			
		||||
void housekeeping_task_kb(void) { eeconfig_flush_md_led_task(FLUSH_TIMEOUT); }
 | 
			
		||||
void housekeeping_task_kb(void) {
 | 
			
		||||
    eeconfig_flush_md_led_task(FLUSH_TIMEOUT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((weak)) led_instruction_t led_instructions[] = {{.end = 1}};
 | 
			
		||||
static void                             md_rgb_matrix_config_override(int i);
 | 
			
		||||
#    else
 | 
			
		||||
uint8_t gcr_desired;
 | 
			
		||||
#    endif  // USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
#    endif // USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
 | 
			
		||||
void SERCOM1_0_Handler(void) {
 | 
			
		||||
    if (SERCOM1->I2CM.INTFLAG.bit.ERROR) {
 | 
			
		||||
| 
						 | 
				
			
			@ -125,9 +129,9 @@ void gcr_compute(void) {
 | 
			
		|||
    if (v_5v < V5_CAT) {
 | 
			
		||||
        I2C3733_Control_Set(0);
 | 
			
		||||
        // CDC_print("USB: WARNING: 5V catastrophic level reached! Disabling LED drivers!\r\n"); //Blocking print is bad here!
 | 
			
		||||
        v_5v_cat_hit = 20;  //~100ms recover
 | 
			
		||||
        gcr_actual   = 0;   // Minimize GCR
 | 
			
		||||
        usb_gcr_auto = 1;   // Force auto mode enabled
 | 
			
		||||
        v_5v_cat_hit = 20; //~100ms recover
 | 
			
		||||
        gcr_actual   = 0;  // Minimize GCR
 | 
			
		||||
        usb_gcr_auto = 1;  // Force auto mode enabled
 | 
			
		||||
        return;
 | 
			
		||||
    } else if (v_5v_cat_hit > 1) {
 | 
			
		||||
        v_5v_cat_hit--;
 | 
			
		||||
| 
						 | 
				
			
			@ -157,24 +161,24 @@ void gcr_compute(void) {
 | 
			
		|||
        gcr_min_counter = 0;
 | 
			
		||||
    } else if (action == ACT_GCR_INC) {
 | 
			
		||||
        if (LED_GCR_STEP_AUTO > LED_GCR_MAX - gcr_actual)
 | 
			
		||||
            gcr_actual = LED_GCR_MAX;  // Obey max and prevent wrapping
 | 
			
		||||
            gcr_actual = LED_GCR_MAX; // Obey max and prevent wrapping
 | 
			
		||||
        else
 | 
			
		||||
            gcr_actual += LED_GCR_STEP_AUTO;
 | 
			
		||||
        gcr_min_counter = 0;
 | 
			
		||||
    } else if (action == ACT_GCR_DEC) {
 | 
			
		||||
        if (LED_GCR_STEP_AUTO > gcr_actual)  // Prevent wrapping
 | 
			
		||||
        if (LED_GCR_STEP_AUTO > gcr_actual) // Prevent wrapping
 | 
			
		||||
        {
 | 
			
		||||
            gcr_actual = 0;
 | 
			
		||||
            // At this point, power can no longer be cut from the LED drivers, so focus on cutting out extra port if active
 | 
			
		||||
            if (usb_extra_state != USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG)  // If not in a wait for replug state
 | 
			
		||||
            if (usb_extra_state != USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG) // If not in a wait for replug state
 | 
			
		||||
            {
 | 
			
		||||
                if (usb_extra_state == USB_EXTRA_STATE_ENABLED)  // If extra usb is enabled
 | 
			
		||||
                if (usb_extra_state == USB_EXTRA_STATE_ENABLED) // If extra usb is enabled
 | 
			
		||||
                {
 | 
			
		||||
                    gcr_min_counter++;
 | 
			
		||||
                    if (gcr_min_counter > 200)  // 5ms per check = 1s delay
 | 
			
		||||
                    if (gcr_min_counter > 200) // 5ms per check = 1s delay
 | 
			
		||||
                    {
 | 
			
		||||
                        USB_ExtraSetState(USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG);
 | 
			
		||||
                        usb_extra_manual = 0;  // Force disable manual mode of extra port
 | 
			
		||||
                        usb_extra_manual = 0; // Force disable manual mode of extra port
 | 
			
		||||
                        if (usb_extra_manual)
 | 
			
		||||
                            CDC_print("USB: Disabling extra port until replug and manual mode toggle!\r\n");
 | 
			
		||||
                        else
 | 
			
		||||
| 
						 | 
				
			
			@ -275,11 +279,11 @@ static void flush(void) {
 | 
			
		|||
#    ifdef USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
    if (!led_enabled) {
 | 
			
		||||
        return;
 | 
			
		||||
    }  // Prevent calculations and I2C traffic if LED drivers are not enabled
 | 
			
		||||
    } // Prevent calculations and I2C traffic if LED drivers are not enabled
 | 
			
		||||
#    else
 | 
			
		||||
    if (!sr_exp_data.bit.SDB_N) {
 | 
			
		||||
        return;
 | 
			
		||||
    }  // Prevent calculations and I2C traffic if LED drivers are not enabled
 | 
			
		||||
    } // Prevent calculations and I2C traffic if LED drivers are not enabled
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    // Wait for previous transfer to complete
 | 
			
		||||
| 
						 | 
				
			
			@ -319,17 +323,19 @@ static void flush(void) {
 | 
			
		|||
    pomod = (uint32_t)pomod % 10000;
 | 
			
		||||
    pomod /= 100.0f;
 | 
			
		||||
 | 
			
		||||
#    endif  // USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
#    endif // USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
 | 
			
		||||
    uint8_t drvid;
 | 
			
		||||
 | 
			
		||||
    // NOTE: GCR does not need to be timed with LED processing, but there is really no harm
 | 
			
		||||
    if (gcr_actual != gcr_actual_last) {
 | 
			
		||||
        for (drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++) I2C_LED_Q_GCR(drvid);  // Queue data
 | 
			
		||||
        for (drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++)
 | 
			
		||||
            I2C_LED_Q_GCR(drvid); // Queue data
 | 
			
		||||
        gcr_actual_last = gcr_actual;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++) I2C_LED_Q_PWM(drvid);  // Queue data
 | 
			
		||||
    for (drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++)
 | 
			
		||||
        I2C_LED_Q_PWM(drvid); // Queue data
 | 
			
		||||
 | 
			
		||||
    i2c_led_q_run();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -341,19 +347,19 @@ void md_rgb_matrix_indicators_advanced(uint8_t led_min, uint8_t led_max) {
 | 
			
		|||
            if (
 | 
			
		||||
#    if USB_LED_NUM_LOCK_SCANCODE != 255
 | 
			
		||||
                (led_map[i].scan == USB_LED_NUM_LOCK_SCANCODE && (kbled & (1 << USB_LED_NUM_LOCK))) ||
 | 
			
		||||
#    endif  // NUM LOCK
 | 
			
		||||
#    endif // NUM LOCK
 | 
			
		||||
#    if USB_LED_CAPS_LOCK_SCANCODE != 255
 | 
			
		||||
                (led_map[i].scan == USB_LED_CAPS_LOCK_SCANCODE && (kbled & (1 << USB_LED_CAPS_LOCK))) ||
 | 
			
		||||
#    endif  // CAPS LOCK
 | 
			
		||||
#    endif // CAPS LOCK
 | 
			
		||||
#    if USB_LED_SCROLL_LOCK_SCANCODE != 255
 | 
			
		||||
                (led_map[i].scan == USB_LED_SCROLL_LOCK_SCANCODE && (kbled & (1 << USB_LED_SCROLL_LOCK))) ||
 | 
			
		||||
#    endif  // SCROLL LOCK
 | 
			
		||||
#    endif // SCROLL LOCK
 | 
			
		||||
#    if USB_LED_COMPOSE_SCANCODE != 255
 | 
			
		||||
                (led_map[i].scan == USB_LED_COMPOSE_SCANCODE && (kbled & (1 << USB_LED_COMPOSE))) ||
 | 
			
		||||
#    endif  // COMPOSE
 | 
			
		||||
#    endif // COMPOSE
 | 
			
		||||
#    if USB_LED_KANA_SCANCODE != 255
 | 
			
		||||
                (led_map[i].scan == USB_LED_KANA_SCANCODE && (kbled & (1 << USB_LED_KANA))) ||
 | 
			
		||||
#    endif  // KANA
 | 
			
		||||
#    endif // KANA
 | 
			
		||||
                (0)) {
 | 
			
		||||
                if (rgb_matrix_get_flags() & LED_FLAG_INDICATOR) {
 | 
			
		||||
                    led_buffer[i].r = 255 - led_buffer[i].r;
 | 
			
		||||
| 
						 | 
				
			
			@ -378,7 +384,7 @@ static void led_run_pattern(led_setup_t* f, float* ro, float* go, float* bo, flo
 | 
			
		|||
    float po;
 | 
			
		||||
 | 
			
		||||
    while (f->end != 1) {
 | 
			
		||||
        po = pos;  // Reset po for new frame
 | 
			
		||||
        po = pos; // Reset po for new frame
 | 
			
		||||
 | 
			
		||||
        // Add in any moving effects
 | 
			
		||||
        if ((!led_animation_direction && f->ef & EF_SCR_R) || (led_animation_direction && (f->ef & EF_SCR_L))) {
 | 
			
		||||
| 
						 | 
				
			
			@ -413,17 +419,17 @@ static void led_run_pattern(led_setup_t* f, float* ro, float* go, float* bo, flo
 | 
			
		|||
 | 
			
		||||
        // Add in any color effects
 | 
			
		||||
        if (f->ef & EF_OVER) {
 | 
			
		||||
            *ro = (po * (f->re - f->rs)) + f->rs;  // + 0.5;
 | 
			
		||||
            *go = (po * (f->ge - f->gs)) + f->gs;  // + 0.5;
 | 
			
		||||
            *bo = (po * (f->be - f->bs)) + f->bs;  // + 0.5;
 | 
			
		||||
            *ro = (po * (f->re - f->rs)) + f->rs; // + 0.5;
 | 
			
		||||
            *go = (po * (f->ge - f->gs)) + f->gs; // + 0.5;
 | 
			
		||||
            *bo = (po * (f->be - f->bs)) + f->bs; // + 0.5;
 | 
			
		||||
        } else if (f->ef & EF_SUBTRACT) {
 | 
			
		||||
            *ro -= (po * (f->re - f->rs)) + f->rs;  // + 0.5;
 | 
			
		||||
            *go -= (po * (f->ge - f->gs)) + f->gs;  // + 0.5;
 | 
			
		||||
            *bo -= (po * (f->be - f->bs)) + f->bs;  // + 0.5;
 | 
			
		||||
            *ro -= (po * (f->re - f->rs)) + f->rs; // + 0.5;
 | 
			
		||||
            *go -= (po * (f->ge - f->gs)) + f->gs; // + 0.5;
 | 
			
		||||
            *bo -= (po * (f->be - f->bs)) + f->bs; // + 0.5;
 | 
			
		||||
        } else {
 | 
			
		||||
            *ro += (po * (f->re - f->rs)) + f->rs;  // + 0.5;
 | 
			
		||||
            *go += (po * (f->ge - f->gs)) + f->gs;  // + 0.5;
 | 
			
		||||
            *bo += (po * (f->be - f->bs)) + f->bs;  // + 0.5;
 | 
			
		||||
            *ro += (po * (f->re - f->rs)) + f->rs; // + 0.5;
 | 
			
		||||
            *go += (po * (f->ge - f->gs)) + f->gs; // + 0.5;
 | 
			
		||||
            *bo += (po * (f->be - f->bs)) + f->bs; // + 0.5;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        f++;
 | 
			
		||||
| 
						 | 
				
			
			@ -471,10 +477,10 @@ static void md_rgb_matrix_config_override(int i) {
 | 
			
		|||
 | 
			
		||||
            // Check if this applies to current index
 | 
			
		||||
            if (led_cur_instruction->flags & LED_FLAG_MATCH_ID) {
 | 
			
		||||
                uint8_t   modid    = i / 32;                             // Calculate which id# contains the led bit
 | 
			
		||||
                uint32_t  modidbit = 1 << (i % 32);                      // Calculate the bit within the id#
 | 
			
		||||
                uint32_t* bitfield = &led_cur_instruction->id0 + modid;  // Add modid as offset to id0 address. *bitfield is now idX of the led id
 | 
			
		||||
                if (~(*bitfield) & modidbit) {                           // Check if led bit is not set in idX
 | 
			
		||||
                uint8_t   modid    = i / 32;                            // Calculate which id# contains the led bit
 | 
			
		||||
                uint32_t  modidbit = 1 << (i % 32);                     // Calculate the bit within the id#
 | 
			
		||||
                uint32_t* bitfield = &led_cur_instruction->id0 + modid; // Add modid as offset to id0 address. *bitfield is now idX of the led id
 | 
			
		||||
                if (~(*bitfield) & modidbit) {                          // Check if led bit is not set in idX
 | 
			
		||||
                    goto next_iter;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -538,5 +544,5 @@ static void md_rgb_matrix_config_override(int i) {
 | 
			
		|||
    led_buffer[i].b = (uint8_t)bo;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#    endif  // USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
#endif      // RGB_MATRIX_ENABLE
 | 
			
		||||
#    endif // USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
#endif     // RGB_MATRIX_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,10 +31,10 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#define ISSI3733_SW_COUNT 12
 | 
			
		||||
 | 
			
		||||
#define ISSI3733_LED_RGB_COUNT ISSI3733_CS_COUNT *ISSI3733_SW_COUNT
 | 
			
		||||
#define ISSI3733_PG0_BYTES ISSI3733_LED_RGB_COUNT / 8 + 1  //+1 for first byte being memory start offset for I2C transfer
 | 
			
		||||
#define ISSI3733_PG1_BYTES ISSI3733_LED_RGB_COUNT + 1      //+1 for first byte being memory start offset for I2C transfer
 | 
			
		||||
#define ISSI3733_PG2_BYTES ISSI3733_LED_RGB_COUNT + 1      //+1 for first byte being memory start offset for I2C transfer
 | 
			
		||||
#define ISSI3733_PG3_BYTES 18 + 1                          //+1 for first byte being memory start offset for I2C transfer
 | 
			
		||||
#define ISSI3733_PG0_BYTES ISSI3733_LED_RGB_COUNT / 8 + 1 //+1 for first byte being memory start offset for I2C transfer
 | 
			
		||||
#define ISSI3733_PG1_BYTES ISSI3733_LED_RGB_COUNT + 1     //+1 for first byte being memory start offset for I2C transfer
 | 
			
		||||
#define ISSI3733_PG2_BYTES ISSI3733_LED_RGB_COUNT + 1     //+1 for first byte being memory start offset for I2C transfer
 | 
			
		||||
#define ISSI3733_PG3_BYTES 18 + 1                         //+1 for first byte being memory start offset for I2C transfer
 | 
			
		||||
 | 
			
		||||
#define ISSI3733_PG_ONOFF_BYTES ISSI3733_PG0_BYTES
 | 
			
		||||
#define ISSI3733_PG_OR_BYTES ISSI3733_PG0_BYTES
 | 
			
		||||
| 
						 | 
				
			
			@ -44,38 +44,38 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#define ISSI3733_PG_FN_BYTES ISSI3733_PG3_BYTES
 | 
			
		||||
 | 
			
		||||
typedef struct issi3733_driver_s {
 | 
			
		||||
    uint8_t addr;                            // Address of the driver according to wiring "ISSI3733: Table 1 Slave Address"
 | 
			
		||||
    uint8_t onoff[ISSI3733_PG_ONOFF_BYTES];  // PG0 - LED Control Register - LED On/Off Register
 | 
			
		||||
    uint8_t open[ISSI3733_PG_OR_BYTES];      // PG0 - LED Control Register - LED Open Register
 | 
			
		||||
    uint8_t shrt[ISSI3733_PG_SR_BYTES];      // PG0 - LED Control Register - LED Short Register
 | 
			
		||||
    uint8_t pwm[ISSI3733_PG_PWM_BYTES];      // PG1 - PWM Register
 | 
			
		||||
    uint8_t abm[ISSI3733_PG_ABM_BYTES];      // PG2 - Auto Breath Mode Register
 | 
			
		||||
    uint8_t conf[ISSI3733_PG_FN_BYTES];      // PG3 - Function Register
 | 
			
		||||
    uint8_t addr;                           // Address of the driver according to wiring "ISSI3733: Table 1 Slave Address"
 | 
			
		||||
    uint8_t onoff[ISSI3733_PG_ONOFF_BYTES]; // PG0 - LED Control Register - LED On/Off Register
 | 
			
		||||
    uint8_t open[ISSI3733_PG_OR_BYTES];     // PG0 - LED Control Register - LED Open Register
 | 
			
		||||
    uint8_t shrt[ISSI3733_PG_SR_BYTES];     // PG0 - LED Control Register - LED Short Register
 | 
			
		||||
    uint8_t pwm[ISSI3733_PG_PWM_BYTES];     // PG1 - PWM Register
 | 
			
		||||
    uint8_t abm[ISSI3733_PG_ABM_BYTES];     // PG2 - Auto Breath Mode Register
 | 
			
		||||
    uint8_t conf[ISSI3733_PG_FN_BYTES];     // PG3 - Function Register
 | 
			
		||||
} issi3733_driver_t;
 | 
			
		||||
 | 
			
		||||
typedef struct issi3733_rgb_s {
 | 
			
		||||
    uint8_t *r;  // Direct access into PWM data
 | 
			
		||||
    uint8_t *g;  // Direct access into PWM data
 | 
			
		||||
    uint8_t *b;  // Direct access into PWM data
 | 
			
		||||
    uint8_t *r; // Direct access into PWM data
 | 
			
		||||
    uint8_t *g; // Direct access into PWM data
 | 
			
		||||
    uint8_t *b; // Direct access into PWM data
 | 
			
		||||
} issi3733_rgb_t;
 | 
			
		||||
 | 
			
		||||
typedef struct issi3733_rgb_adr_s {
 | 
			
		||||
    uint8_t drv;  // Driver from given list
 | 
			
		||||
    uint8_t cs;   // CS
 | 
			
		||||
    uint8_t swr;  // SW Red
 | 
			
		||||
    uint8_t swg;  // SW Green
 | 
			
		||||
    uint8_t swb;  // SW Blue
 | 
			
		||||
    uint8_t drv; // Driver from given list
 | 
			
		||||
    uint8_t cs;  // CS
 | 
			
		||||
    uint8_t swr; // SW Red
 | 
			
		||||
    uint8_t swg; // SW Green
 | 
			
		||||
    uint8_t swb; // SW Blue
 | 
			
		||||
} issi3733_rgb_adr_t;
 | 
			
		||||
 | 
			
		||||
typedef struct issi3733_led_s {
 | 
			
		||||
    uint8_t            id;    // According to PCB ref
 | 
			
		||||
    issi3733_rgb_t     rgb;   // PWM settings of R G B
 | 
			
		||||
    issi3733_rgb_adr_t adr;   // Hardware addresses
 | 
			
		||||
    float              x;     // Physical position X
 | 
			
		||||
    float              y;     // Physical position Y
 | 
			
		||||
    float              px;    // Physical position X in percent
 | 
			
		||||
    float              py;    // Physical position Y in percent
 | 
			
		||||
    uint8_t            scan;  // Key scan code from wiring (set 0xFF if no key)
 | 
			
		||||
    uint8_t            id;   // According to PCB ref
 | 
			
		||||
    issi3733_rgb_t     rgb;  // PWM settings of R G B
 | 
			
		||||
    issi3733_rgb_adr_t adr;  // Hardware addresses
 | 
			
		||||
    float              x;    // Physical position X
 | 
			
		||||
    float              y;    // Physical position Y
 | 
			
		||||
    float              px;   // Physical position X in percent
 | 
			
		||||
    float              py;   // Physical position Y in percent
 | 
			
		||||
    uint8_t            scan; // Key scan code from wiring (set 0xFF if no key)
 | 
			
		||||
} issi3733_led_t;
 | 
			
		||||
 | 
			
		||||
extern issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT];
 | 
			
		||||
| 
						 | 
				
			
			@ -92,44 +92,44 @@ void md_rgb_matrix_indicators_advanced(uint8_t led_min, uint8_t led_max);
 | 
			
		|||
 | 
			
		||||
#ifdef USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
 | 
			
		||||
#    define EF_NONE 0x00000000      // No effect
 | 
			
		||||
#    define EF_OVER 0x00000001      // Overwrite any previous color information with new
 | 
			
		||||
#    define EF_SCR_L 0x00000002     // Scroll left
 | 
			
		||||
#    define EF_SCR_R 0x00000004     // Scroll right
 | 
			
		||||
#    define EF_SUBTRACT 0x00000008  // Subtract color values
 | 
			
		||||
#    define EF_NONE 0x00000000     // No effect
 | 
			
		||||
#    define EF_OVER 0x00000001     // Overwrite any previous color information with new
 | 
			
		||||
#    define EF_SCR_L 0x00000002    // Scroll left
 | 
			
		||||
#    define EF_SCR_R 0x00000004    // Scroll right
 | 
			
		||||
#    define EF_SUBTRACT 0x00000008 // Subtract color values
 | 
			
		||||
 | 
			
		||||
typedef struct led_setup_s {
 | 
			
		||||
    float    hs;   // Band begin at percent
 | 
			
		||||
    float    he;   // Band end at percent
 | 
			
		||||
    uint8_t  rs;   // Red start value
 | 
			
		||||
    uint8_t  re;   // Red end value
 | 
			
		||||
    uint8_t  gs;   // Green start value
 | 
			
		||||
    uint8_t  ge;   // Green end value
 | 
			
		||||
    uint8_t  bs;   // Blue start value
 | 
			
		||||
    uint8_t  be;   // Blue end value
 | 
			
		||||
    uint32_t ef;   // Animation and color effects
 | 
			
		||||
    uint8_t  end;  // Set to signal end of the setup
 | 
			
		||||
    float    hs;  // Band begin at percent
 | 
			
		||||
    float    he;  // Band end at percent
 | 
			
		||||
    uint8_t  rs;  // Red start value
 | 
			
		||||
    uint8_t  re;  // Red end value
 | 
			
		||||
    uint8_t  gs;  // Green start value
 | 
			
		||||
    uint8_t  ge;  // Green end value
 | 
			
		||||
    uint8_t  bs;  // Blue start value
 | 
			
		||||
    uint8_t  be;  // Blue end value
 | 
			
		||||
    uint32_t ef;  // Animation and color effects
 | 
			
		||||
    uint8_t  end; // Set to signal end of the setup
 | 
			
		||||
} led_setup_t;
 | 
			
		||||
 | 
			
		||||
extern const uint8_t led_setups_count;
 | 
			
		||||
extern void *        led_setups[];
 | 
			
		||||
 | 
			
		||||
// LED Extra Instructions
 | 
			
		||||
#    define LED_FLAG_NULL 0x00                // Matching and coloring not used (default)
 | 
			
		||||
#    define LED_FLAG_MATCH_ID 0x01            // Match on the ID of the LED (set id#'s to desired bit pattern, first LED is id 1)
 | 
			
		||||
#    define LED_FLAG_MATCH_LAYER 0x02         // Match on the current active layer (set layer to desired match layer)
 | 
			
		||||
#    define LED_FLAG_USE_RGB 0x10             // Use a specific RGB value (set r, g, b to desired output color values)
 | 
			
		||||
#    define LED_FLAG_USE_PATTERN 0x20         // Use a specific pattern ID (set pattern_id to desired output pattern)
 | 
			
		||||
#    define LED_FLAG_USE_ROTATE_PATTERN 0x40  // Use pattern the user has cycled to manually
 | 
			
		||||
#    define LED_FLAG_NULL 0x00               // Matching and coloring not used (default)
 | 
			
		||||
#    define LED_FLAG_MATCH_ID 0x01           // Match on the ID of the LED (set id#'s to desired bit pattern, first LED is id 1)
 | 
			
		||||
#    define LED_FLAG_MATCH_LAYER 0x02        // Match on the current active layer (set layer to desired match layer)
 | 
			
		||||
#    define LED_FLAG_USE_RGB 0x10            // Use a specific RGB value (set r, g, b to desired output color values)
 | 
			
		||||
#    define LED_FLAG_USE_PATTERN 0x20        // Use a specific pattern ID (set pattern_id to desired output pattern)
 | 
			
		||||
#    define LED_FLAG_USE_ROTATE_PATTERN 0x40 // Use pattern the user has cycled to manually
 | 
			
		||||
 | 
			
		||||
typedef struct led_instruction_s {
 | 
			
		||||
    uint16_t flags;  // Bitfield for LED instructions
 | 
			
		||||
    uint32_t id0;    // Bitwise id, IDs 0-31
 | 
			
		||||
    uint32_t id1;    // Bitwise id, IDs 32-63
 | 
			
		||||
    uint32_t id2;    // Bitwise id, IDs 64-95
 | 
			
		||||
    uint32_t id3;    // Bitwise id, IDs 96-127
 | 
			
		||||
    uint32_t id4;    // Bitwise id, IDs 128-159
 | 
			
		||||
    uint32_t id5;    // Bitwise id, IDs 160-191
 | 
			
		||||
    uint16_t flags; // Bitfield for LED instructions
 | 
			
		||||
    uint32_t id0;   // Bitwise id, IDs 0-31
 | 
			
		||||
    uint32_t id1;   // Bitwise id, IDs 32-63
 | 
			
		||||
    uint32_t id2;   // Bitwise id, IDs 64-95
 | 
			
		||||
    uint32_t id3;   // Bitwise id, IDs 96-127
 | 
			
		||||
    uint32_t id4;   // Bitwise id, IDs 128-159
 | 
			
		||||
    uint32_t id5;   // Bitwise id, IDs 160-191
 | 
			
		||||
    uint8_t  layer;
 | 
			
		||||
    uint8_t  r;
 | 
			
		||||
    uint8_t  g;
 | 
			
		||||
| 
						 | 
				
			
			@ -141,7 +141,7 @@ typedef struct led_instruction_s {
 | 
			
		|||
extern led_instruction_t led_instructions[];
 | 
			
		||||
 | 
			
		||||
typedef struct led_config_s {
 | 
			
		||||
    uint8_t ver;  // assumed to be zero on eeprom reset
 | 
			
		||||
    uint8_t ver; // assumed to be zero on eeprom reset
 | 
			
		||||
 | 
			
		||||
    uint8_t desired_gcr;
 | 
			
		||||
    uint8_t animation_breathing;
 | 
			
		||||
| 
						 | 
				
			
			@ -178,27 +178,27 @@ void md_led_changed(void);
 | 
			
		|||
#    define led_ratio_brightness md_led_config.ratio_brightness
 | 
			
		||||
#    define led_edge_mode md_led_config.edge_mode
 | 
			
		||||
 | 
			
		||||
#    define LED_MODE_NORMAL 0  // Must be 0
 | 
			
		||||
#    define LED_MODE_NORMAL 0 // Must be 0
 | 
			
		||||
#    define LED_MODE_KEYS_ONLY 1
 | 
			
		||||
#    define LED_MODE_NON_KEYS_ONLY 2
 | 
			
		||||
#    define LED_MODE_INDICATORS_ONLY 3
 | 
			
		||||
#    define LED_MODE_MAX_INDEX LED_MODE_INDICATORS_ONLY  // Must be highest value
 | 
			
		||||
#    define LED_MODE_MAX_INDEX LED_MODE_INDICATORS_ONLY // Must be highest value
 | 
			
		||||
 | 
			
		||||
#    define LED_EDGE_MODE_ALL 0                        // All edge LEDs are active (Must be 0)
 | 
			
		||||
#    define LED_EDGE_MODE_ALTERNATE 1                  // Alternate mode of edge LEDs are active (Intention is for 'only every other edge LED' to be active)
 | 
			
		||||
#    define LED_EDGE_MODE_MAX LED_EDGE_MODE_ALTERNATE  // Must be the highest valued LED edge mode
 | 
			
		||||
#    define LED_EDGE_MODE_ALL 0                       // All edge LEDs are active (Must be 0)
 | 
			
		||||
#    define LED_EDGE_MODE_ALTERNATE 1                 // Alternate mode of edge LEDs are active (Intention is for 'only every other edge LED' to be active)
 | 
			
		||||
#    define LED_EDGE_MODE_MAX LED_EDGE_MODE_ALTERNATE // Must be the highest valued LED edge mode
 | 
			
		||||
 | 
			
		||||
#    define LED_EDGE_FULL_MODE 255  // LEDs configured with this scan code will always be on for edge lighting modes
 | 
			
		||||
#    define LED_EDGE_ALT_MODE 254   // LEDs configured with this scan code will turn off in edge alternating mode
 | 
			
		||||
#    define LED_EDGE_MIN_SCAN 254   // LEDs configured with scan code >= to this are assigned as edge LEDs
 | 
			
		||||
#    define LED_INDICATOR_SCAN 253  // LEDs configured as dedicated indicators
 | 
			
		||||
#    define LED_EDGE_FULL_MODE 255 // LEDs configured with this scan code will always be on for edge lighting modes
 | 
			
		||||
#    define LED_EDGE_ALT_MODE 254  // LEDs configured with this scan code will turn off in edge alternating mode
 | 
			
		||||
#    define LED_EDGE_MIN_SCAN 254  // LEDs configured with scan code >= to this are assigned as edge LEDs
 | 
			
		||||
#    define LED_INDICATOR_SCAN 253 // LEDs configured as dedicated indicators
 | 
			
		||||
 | 
			
		||||
#    define LED_IS_KEY(scan) (scan < LED_INDICATOR_SCAN)         // Return true if an LED's scan value indicates it is a key LED
 | 
			
		||||
#    define LED_IS_EDGE(scan) (scan >= LED_EDGE_MIN_SCAN)        // Return true if an LED's scan value indicates an edge LED
 | 
			
		||||
#    define LED_IS_EDGE_ALT(scan) (scan == LED_EDGE_ALT_MODE)    // Return true if an LED's scan value indicates an alternate edge mode LED
 | 
			
		||||
#    define LED_IS_INDICATOR(scan) (scan == LED_INDICATOR_SCAN)  // Return true if an LED's scan value indicates it is a dedicated Indicator
 | 
			
		||||
#    define LED_IS_KEY(scan) (scan < LED_INDICATOR_SCAN)        // Return true if an LED's scan value indicates it is a key LED
 | 
			
		||||
#    define LED_IS_EDGE(scan) (scan >= LED_EDGE_MIN_SCAN)       // Return true if an LED's scan value indicates an edge LED
 | 
			
		||||
#    define LED_IS_EDGE_ALT(scan) (scan == LED_EDGE_ALT_MODE)   // Return true if an LED's scan value indicates an alternate edge mode LED
 | 
			
		||||
#    define LED_IS_INDICATOR(scan) (scan == LED_INDICATOR_SCAN) // Return true if an LED's scan value indicates it is a dedicated Indicator
 | 
			
		||||
#else
 | 
			
		||||
extern uint8_t gcr_desired;
 | 
			
		||||
#endif  // USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
#endif // USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
 | 
			
		||||
#endif  //_LED_MATRIX_H_
 | 
			
		||||
#endif //_LED_MATRIX_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -97,5 +97,5 @@ void *led_setups[] = {leds_rainbow_s, leds_rainbow_ns, leds_teal_salmon, leds_ye
 | 
			
		|||
 | 
			
		||||
const uint8_t led_setups_count = sizeof(led_setups) / sizeof(led_setups[0]);
 | 
			
		||||
 | 
			
		||||
#    endif  // USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
#endif      // RGB_MATRIX_ENABLE
 | 
			
		||||
#    endif // USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
#endif     // RGB_MATRIX_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			@ -54,7 +54,9 @@ void shift_out_impl(const uint8_t *data, uint16_t length) {
 | 
			
		|||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
void shift_init_impl(void) { spi_init(); }
 | 
			
		||||
void shift_init_impl(void) {
 | 
			
		||||
    spi_init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void shift_out_impl(const uint8_t *data, uint16_t length) {
 | 
			
		||||
    spi_start(SR_EXP_RCLK_PIN, true, 0, 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +69,9 @@ void shift_out_impl(const uint8_t *data, uint16_t length) {
 | 
			
		|||
 | 
			
		||||
// ***************************************************************
 | 
			
		||||
 | 
			
		||||
void shift_out(const uint8_t *data, uint16_t length) { shift_out_impl(data, length); }
 | 
			
		||||
void shift_out(const uint8_t *data, uint16_t length) {
 | 
			
		||||
    shift_out_impl(data, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void shift_enable(void) {
 | 
			
		||||
    setPinOutput(SR_EXP_OE_PIN);
 | 
			
		||||
| 
						 | 
				
			
			@ -90,8 +94,8 @@ sr_exp_t sr_exp_data;
 | 
			
		|||
 | 
			
		||||
void SR_EXP_WriteData(void) {
 | 
			
		||||
    uint8_t data[2] = {
 | 
			
		||||
        sr_exp_data.reg & 0xFF,         // Shift in bits 7-0
 | 
			
		||||
        (sr_exp_data.reg >> 8) & 0xFF,  // Shift in bits 15-8
 | 
			
		||||
        sr_exp_data.reg & 0xFF,        // Shift in bits 7-0
 | 
			
		||||
        (sr_exp_data.reg >> 8) & 0xFF, // Shift in bits 15-8
 | 
			
		||||
    };
 | 
			
		||||
    shift_out(data, 2);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,10 +45,10 @@ __attribute__((weak)) void spi_init(void) {
 | 
			
		|||
        CLK_set_spi_freq(CHAN_SERCOM_SPI, FREQ_SPI_DEFAULT);
 | 
			
		||||
 | 
			
		||||
        // Set up MCU SPI pins
 | 
			
		||||
        PORT->Group[SAMD_PORT(SPI_DATAOUT_PIN)].PMUX[SAMD_PIN(SPI_DATAOUT_PIN) / 2].bit.SPI_DATAOUT_MUX_SEL = SPI_DATAOUT_MUX;  // MUX select for sercom
 | 
			
		||||
        PORT->Group[SAMD_PORT(SPI_SCLK_PIN)].PMUX[SAMD_PIN(SPI_SCLK_PIN) / 2].bit.SPI_SCLK_MUX_SEL          = SPI_SCLK_MUX;     // MUX select for sercom
 | 
			
		||||
        PORT->Group[SAMD_PORT(SPI_DATAOUT_PIN)].PINCFG[SAMD_PIN(SPI_DATAOUT_PIN)].bit.PMUXEN                = 1;                // MUX Enable
 | 
			
		||||
        PORT->Group[SAMD_PORT(SPI_SCLK_PIN)].PINCFG[SAMD_PIN(SPI_SCLK_PIN)].bit.PMUXEN                      = 1;                // MUX Enable
 | 
			
		||||
        PORT->Group[SAMD_PORT(SPI_DATAOUT_PIN)].PMUX[SAMD_PIN(SPI_DATAOUT_PIN) / 2].bit.SPI_DATAOUT_MUX_SEL = SPI_DATAOUT_MUX; // MUX select for sercom
 | 
			
		||||
        PORT->Group[SAMD_PORT(SPI_SCLK_PIN)].PMUX[SAMD_PIN(SPI_SCLK_PIN) / 2].bit.SPI_SCLK_MUX_SEL          = SPI_SCLK_MUX;    // MUX select for sercom
 | 
			
		||||
        PORT->Group[SAMD_PORT(SPI_DATAOUT_PIN)].PINCFG[SAMD_PIN(SPI_DATAOUT_PIN)].bit.PMUXEN                = 1;               // MUX Enable
 | 
			
		||||
        PORT->Group[SAMD_PORT(SPI_SCLK_PIN)].PINCFG[SAMD_PIN(SPI_SCLK_PIN)].bit.PMUXEN                      = 1;               // MUX Enable
 | 
			
		||||
 | 
			
		||||
        DBGC(DC_SPI_INIT_COMPLETE);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -63,14 +63,14 @@ bool spi_start(pin_t csPin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
 | 
			
		|||
    setPinOutput(currentSelectPin);
 | 
			
		||||
    writePinLow(currentSelectPin);
 | 
			
		||||
 | 
			
		||||
    SPI_SERCOM->SPI.CTRLA.bit.DORD = lsbFirst;  // Data Order - LSB is transferred first
 | 
			
		||||
    SPI_SERCOM->SPI.CTRLA.bit.CPOL = 1;         // Clock Polarity - SCK high when idle. Leading edge of cycle is falling. Trailing rising.
 | 
			
		||||
    SPI_SERCOM->SPI.CTRLA.bit.CPHA = 1;         // Clock Phase - Leading Edge Falling, change, Trailing Edge - Rising, sample
 | 
			
		||||
    SPI_SERCOM->SPI.CTRLA.bit.DIPO = 3;         // Data In Pinout - SERCOM PAD[3] is used as data input (Configure away from DOPO. Not using input.)
 | 
			
		||||
    SPI_SERCOM->SPI.CTRLA.bit.DOPO = 0;         // Data Output PAD[0], Serial Clock PAD[1]
 | 
			
		||||
    SPI_SERCOM->SPI.CTRLA.bit.MODE = 3;         // Operating Mode - Master operation
 | 
			
		||||
    SPI_SERCOM->SPI.CTRLA.bit.DORD = lsbFirst; // Data Order - LSB is transferred first
 | 
			
		||||
    SPI_SERCOM->SPI.CTRLA.bit.CPOL = 1;        // Clock Polarity - SCK high when idle. Leading edge of cycle is falling. Trailing rising.
 | 
			
		||||
    SPI_SERCOM->SPI.CTRLA.bit.CPHA = 1;        // Clock Phase - Leading Edge Falling, change, Trailing Edge - Rising, sample
 | 
			
		||||
    SPI_SERCOM->SPI.CTRLA.bit.DIPO = 3;        // Data In Pinout - SERCOM PAD[3] is used as data input (Configure away from DOPO. Not using input.)
 | 
			
		||||
    SPI_SERCOM->SPI.CTRLA.bit.DOPO = 0;        // Data Output PAD[0], Serial Clock PAD[1]
 | 
			
		||||
    SPI_SERCOM->SPI.CTRLA.bit.MODE = 3;        // Operating Mode - Master operation
 | 
			
		||||
 | 
			
		||||
    SPI_SERCOM->SPI.CTRLA.bit.ENABLE = 1;  // Enable - Peripheral is enabled or being enabled
 | 
			
		||||
    SPI_SERCOM->SPI.CTRLA.bit.ENABLE = 1; // Enable - Peripheral is enabled or being enabled
 | 
			
		||||
    while (SPI_SERCOM->SPI.SYNCBUSY.bit.ENABLE) {
 | 
			
		||||
        DBGC(DC_SPI_SYNC_ENABLING);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -876,66 +876,66 @@ typedef struct {
 | 
			
		|||
// kmod #define LOW       0
 | 
			
		||||
// kmod #define HIGH      1
 | 
			
		||||
 | 
			
		||||
typedef int8_t   S8;   //!< 8-bit signed integer.
 | 
			
		||||
typedef uint8_t  U8;   //!< 8-bit unsigned integer.
 | 
			
		||||
typedef int16_t  S16;  //!< 16-bit signed integer.
 | 
			
		||||
typedef uint16_t U16;  //!< 16-bit unsigned integer.
 | 
			
		||||
typedef int32_t  S32;  //!< 32-bit signed integer.
 | 
			
		||||
typedef uint32_t U32;  //!< 32-bit unsigned integer.
 | 
			
		||||
typedef int64_t  S64;  //!< 64-bit signed integer.
 | 
			
		||||
typedef uint64_t U64;  //!< 64-bit unsigned integer.
 | 
			
		||||
typedef float    F32;  //!< 32-bit floating-point number.
 | 
			
		||||
typedef double   F64;  //!< 64-bit floating-point number.
 | 
			
		||||
typedef int8_t   S8;  //!< 8-bit signed integer.
 | 
			
		||||
typedef uint8_t  U8;  //!< 8-bit unsigned integer.
 | 
			
		||||
typedef int16_t  S16; //!< 16-bit signed integer.
 | 
			
		||||
typedef uint16_t U16; //!< 16-bit unsigned integer.
 | 
			
		||||
typedef int32_t  S32; //!< 32-bit signed integer.
 | 
			
		||||
typedef uint32_t U32; //!< 32-bit unsigned integer.
 | 
			
		||||
typedef int64_t  S64; //!< 64-bit signed integer.
 | 
			
		||||
typedef uint64_t U64; //!< 64-bit unsigned integer.
 | 
			
		||||
typedef float    F32; //!< 32-bit floating-point number.
 | 
			
		||||
typedef double   F64; //!< 64-bit floating-point number.
 | 
			
		||||
 | 
			
		||||
#    define MSB(u16) (((U8 *)&(u16))[1])  //!< Most significant byte of \a u16.
 | 
			
		||||
#    define LSB(u16) (((U8 *)&(u16))[0])  //!< Least significant byte of \a u16.
 | 
			
		||||
#    define MSB(u16) (((U8 *)&(u16))[1]) //!< Most significant byte of \a u16.
 | 
			
		||||
#    define LSB(u16) (((U8 *)&(u16))[0]) //!< Least significant byte of \a u16.
 | 
			
		||||
 | 
			
		||||
#    define MSH(u32) (((U16 *)&(u32))[1])   //!< Most significant half-word of \a u32.
 | 
			
		||||
#    define LSH(u32) (((U16 *)&(u32))[0])   //!< Least significant half-word of \a u32.
 | 
			
		||||
#    define MSB0W(u32) (((U8 *)&(u32))[3])  //!< Most significant byte of 1st rank of \a u32.
 | 
			
		||||
#    define MSB1W(u32) (((U8 *)&(u32))[2])  //!< Most significant byte of 2nd rank of \a u32.
 | 
			
		||||
#    define MSB2W(u32) (((U8 *)&(u32))[1])  //!< Most significant byte of 3rd rank of \a u32.
 | 
			
		||||
#    define MSB3W(u32) (((U8 *)&(u32))[0])  //!< Most significant byte of 4th rank of \a u32.
 | 
			
		||||
#    define LSB3W(u32) MSB0W(u32)           //!< Least significant byte of 4th rank of \a u32.
 | 
			
		||||
#    define LSB2W(u32) MSB1W(u32)           //!< Least significant byte of 3rd rank of \a u32.
 | 
			
		||||
#    define LSB1W(u32) MSB2W(u32)           //!< Least significant byte of 2nd rank of \a u32.
 | 
			
		||||
#    define LSB0W(u32) MSB3W(u32)           //!< Least significant byte of 1st rank of \a u32.
 | 
			
		||||
#    define MSH(u32) (((U16 *)&(u32))[1])  //!< Most significant half-word of \a u32.
 | 
			
		||||
#    define LSH(u32) (((U16 *)&(u32))[0])  //!< Least significant half-word of \a u32.
 | 
			
		||||
#    define MSB0W(u32) (((U8 *)&(u32))[3]) //!< Most significant byte of 1st rank of \a u32.
 | 
			
		||||
#    define MSB1W(u32) (((U8 *)&(u32))[2]) //!< Most significant byte of 2nd rank of \a u32.
 | 
			
		||||
#    define MSB2W(u32) (((U8 *)&(u32))[1]) //!< Most significant byte of 3rd rank of \a u32.
 | 
			
		||||
#    define MSB3W(u32) (((U8 *)&(u32))[0]) //!< Most significant byte of 4th rank of \a u32.
 | 
			
		||||
#    define LSB3W(u32) MSB0W(u32)          //!< Least significant byte of 4th rank of \a u32.
 | 
			
		||||
#    define LSB2W(u32) MSB1W(u32)          //!< Least significant byte of 3rd rank of \a u32.
 | 
			
		||||
#    define LSB1W(u32) MSB2W(u32)          //!< Least significant byte of 2nd rank of \a u32.
 | 
			
		||||
#    define LSB0W(u32) MSB3W(u32)          //!< Least significant byte of 1st rank of \a u32.
 | 
			
		||||
 | 
			
		||||
#    define MSW(u64) (((U32 *)&(u64))[1])   //!< Most significant word of \a u64.
 | 
			
		||||
#    define LSW(u64) (((U32 *)&(u64))[0])   //!< Least significant word of \a u64.
 | 
			
		||||
#    define MSH0(u64) (((U16 *)&(u64))[3])  //!< Most significant half-word of 1st rank of \a u64.
 | 
			
		||||
#    define MSH1(u64) (((U16 *)&(u64))[2])  //!< Most significant half-word of 2nd rank of \a u64.
 | 
			
		||||
#    define MSH2(u64) (((U16 *)&(u64))[1])  //!< Most significant half-word of 3rd rank of \a u64.
 | 
			
		||||
#    define MSH3(u64) (((U16 *)&(u64))[0])  //!< Most significant half-word of 4th rank of \a u64.
 | 
			
		||||
#    define LSH3(u64) MSH0(u64)             //!< Least significant half-word of 4th rank of \a u64.
 | 
			
		||||
#    define LSH2(u64) MSH1(u64)             //!< Least significant half-word of 3rd rank of \a u64.
 | 
			
		||||
#    define LSH1(u64) MSH2(u64)             //!< Least significant half-word of 2nd rank of \a u64.
 | 
			
		||||
#    define LSH0(u64) MSH3(u64)             //!< Least significant half-word of 1st rank of \a u64.
 | 
			
		||||
#    define MSB0D(u64) (((U8 *)&(u64))[7])  //!< Most significant byte of 1st rank of \a u64.
 | 
			
		||||
#    define MSB1D(u64) (((U8 *)&(u64))[6])  //!< Most significant byte of 2nd rank of \a u64.
 | 
			
		||||
#    define MSB2D(u64) (((U8 *)&(u64))[5])  //!< Most significant byte of 3rd rank of \a u64.
 | 
			
		||||
#    define MSB3D(u64) (((U8 *)&(u64))[4])  //!< Most significant byte of 4th rank of \a u64.
 | 
			
		||||
#    define MSB4D(u64) (((U8 *)&(u64))[3])  //!< Most significant byte of 5th rank of \a u64.
 | 
			
		||||
#    define MSB5D(u64) (((U8 *)&(u64))[2])  //!< Most significant byte of 6th rank of \a u64.
 | 
			
		||||
#    define MSB6D(u64) (((U8 *)&(u64))[1])  //!< Most significant byte of 7th rank of \a u64.
 | 
			
		||||
#    define MSB7D(u64) (((U8 *)&(u64))[0])  //!< Most significant byte of 8th rank of \a u64.
 | 
			
		||||
#    define LSB7D(u64) MSB0D(u64)           //!< Least significant byte of 8th rank of \a u64.
 | 
			
		||||
#    define LSB6D(u64) MSB1D(u64)           //!< Least significant byte of 7th rank of \a u64.
 | 
			
		||||
#    define LSB5D(u64) MSB2D(u64)           //!< Least significant byte of 6th rank of \a u64.
 | 
			
		||||
#    define LSB4D(u64) MSB3D(u64)           //!< Least significant byte of 5th rank of \a u64.
 | 
			
		||||
#    define LSB3D(u64) MSB4D(u64)           //!< Least significant byte of 4th rank of \a u64.
 | 
			
		||||
#    define LSB2D(u64) MSB5D(u64)           //!< Least significant byte of 3rd rank of \a u64.
 | 
			
		||||
#    define LSB1D(u64) MSB6D(u64)           //!< Least significant byte of 2nd rank of \a u64.
 | 
			
		||||
#    define LSB0D(u64) MSB7D(u64)           //!< Least significant byte of 1st rank of \a u64.
 | 
			
		||||
#    define MSW(u64) (((U32 *)&(u64))[1])  //!< Most significant word of \a u64.
 | 
			
		||||
#    define LSW(u64) (((U32 *)&(u64))[0])  //!< Least significant word of \a u64.
 | 
			
		||||
#    define MSH0(u64) (((U16 *)&(u64))[3]) //!< Most significant half-word of 1st rank of \a u64.
 | 
			
		||||
#    define MSH1(u64) (((U16 *)&(u64))[2]) //!< Most significant half-word of 2nd rank of \a u64.
 | 
			
		||||
#    define MSH2(u64) (((U16 *)&(u64))[1]) //!< Most significant half-word of 3rd rank of \a u64.
 | 
			
		||||
#    define MSH3(u64) (((U16 *)&(u64))[0]) //!< Most significant half-word of 4th rank of \a u64.
 | 
			
		||||
#    define LSH3(u64) MSH0(u64)            //!< Least significant half-word of 4th rank of \a u64.
 | 
			
		||||
#    define LSH2(u64) MSH1(u64)            //!< Least significant half-word of 3rd rank of \a u64.
 | 
			
		||||
#    define LSH1(u64) MSH2(u64)            //!< Least significant half-word of 2nd rank of \a u64.
 | 
			
		||||
#    define LSH0(u64) MSH3(u64)            //!< Least significant half-word of 1st rank of \a u64.
 | 
			
		||||
#    define MSB0D(u64) (((U8 *)&(u64))[7]) //!< Most significant byte of 1st rank of \a u64.
 | 
			
		||||
#    define MSB1D(u64) (((U8 *)&(u64))[6]) //!< Most significant byte of 2nd rank of \a u64.
 | 
			
		||||
#    define MSB2D(u64) (((U8 *)&(u64))[5]) //!< Most significant byte of 3rd rank of \a u64.
 | 
			
		||||
#    define MSB3D(u64) (((U8 *)&(u64))[4]) //!< Most significant byte of 4th rank of \a u64.
 | 
			
		||||
#    define MSB4D(u64) (((U8 *)&(u64))[3]) //!< Most significant byte of 5th rank of \a u64.
 | 
			
		||||
#    define MSB5D(u64) (((U8 *)&(u64))[2]) //!< Most significant byte of 6th rank of \a u64.
 | 
			
		||||
#    define MSB6D(u64) (((U8 *)&(u64))[1]) //!< Most significant byte of 7th rank of \a u64.
 | 
			
		||||
#    define MSB7D(u64) (((U8 *)&(u64))[0]) //!< Most significant byte of 8th rank of \a u64.
 | 
			
		||||
#    define LSB7D(u64) MSB0D(u64)          //!< Least significant byte of 8th rank of \a u64.
 | 
			
		||||
#    define LSB6D(u64) MSB1D(u64)          //!< Least significant byte of 7th rank of \a u64.
 | 
			
		||||
#    define LSB5D(u64) MSB2D(u64)          //!< Least significant byte of 6th rank of \a u64.
 | 
			
		||||
#    define LSB4D(u64) MSB3D(u64)          //!< Least significant byte of 5th rank of \a u64.
 | 
			
		||||
#    define LSB3D(u64) MSB4D(u64)          //!< Least significant byte of 4th rank of \a u64.
 | 
			
		||||
#    define LSB2D(u64) MSB5D(u64)          //!< Least significant byte of 3rd rank of \a u64.
 | 
			
		||||
#    define LSB1D(u64) MSB6D(u64)          //!< Least significant byte of 2nd rank of \a u64.
 | 
			
		||||
#    define LSB0D(u64) MSB7D(u64)          //!< Least significant byte of 1st rank of \a u64.
 | 
			
		||||
 | 
			
		||||
#    define LSB0(u32) LSB0W(u32)  //!< Least significant byte of 1st rank of \a u32.
 | 
			
		||||
#    define LSB1(u32) LSB1W(u32)  //!< Least significant byte of 2nd rank of \a u32.
 | 
			
		||||
#    define LSB2(u32) LSB2W(u32)  //!< Least significant byte of 3rd rank of \a u32.
 | 
			
		||||
#    define LSB3(u32) LSB3W(u32)  //!< Least significant byte of 4th rank of \a u32.
 | 
			
		||||
#    define MSB3(u32) MSB3W(u32)  //!< Most significant byte of 4th rank of \a u32.
 | 
			
		||||
#    define MSB2(u32) MSB2W(u32)  //!< Most significant byte of 3rd rank of \a u32.
 | 
			
		||||
#    define MSB1(u32) MSB1W(u32)  //!< Most significant byte of 2nd rank of \a u32.
 | 
			
		||||
#    define MSB0(u32) MSB0W(u32)  //!< Most significant byte of 1st rank of \a u32.
 | 
			
		||||
#    define LSB0(u32) LSB0W(u32) //!< Least significant byte of 1st rank of \a u32.
 | 
			
		||||
#    define LSB1(u32) LSB1W(u32) //!< Least significant byte of 2nd rank of \a u32.
 | 
			
		||||
#    define LSB2(u32) LSB2W(u32) //!< Least significant byte of 3rd rank of \a u32.
 | 
			
		||||
#    define LSB3(u32) LSB3W(u32) //!< Least significant byte of 4th rank of \a u32.
 | 
			
		||||
#    define MSB3(u32) MSB3W(u32) //!< Most significant byte of 4th rank of \a u32.
 | 
			
		||||
#    define MSB2(u32) MSB2W(u32) //!< Most significant byte of 3rd rank of \a u32.
 | 
			
		||||
#    define MSB1(u32) MSB1W(u32) //!< Most significant byte of 2nd rank of \a u32.
 | 
			
		||||
#    define MSB0(u32) MSB0W(u32) //!< Most significant byte of 1st rank of \a u32.
 | 
			
		||||
 | 
			
		||||
#    if defined(__ICCARM__)
 | 
			
		||||
#        define SHORTENUM __packed
 | 
			
		||||
| 
						 | 
				
			
			@ -1031,7 +1031,9 @@ static inline void convert_16_bit_to_byte_address(uint16_t value, uint8_t *data)
 | 
			
		|||
 * @return 16-Bit value
 | 
			
		||||
 * @ingroup apiPalApi
 | 
			
		||||
 */
 | 
			
		||||
static inline uint16_t convert_byte_array_to_16_bit(uint8_t *data) { return (data[0] | ((uint16_t)data[1] << 8)); }
 | 
			
		||||
static inline uint16_t convert_byte_array_to_16_bit(uint8_t *data) {
 | 
			
		||||
    return (data[0] | ((uint16_t)data[1] << 8));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Converts a 4 Byte array into a 32-Bit value */
 | 
			
		||||
static inline uint32_t convert_byte_array_to_32_bit(uint8_t *data) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,7 +59,7 @@
 | 
			
		|||
#define USB_DEVICE_VENDOR_ID VENDOR_ID
 | 
			
		||||
#define USB_DEVICE_PRODUCT_ID PRODUCT_ID
 | 
			
		||||
#define USB_DEVICE_VERSION DEVICE_VER
 | 
			
		||||
#define USB_DEVICE_POWER 500  // Consumption on Vbus line (mA)
 | 
			
		||||
#define USB_DEVICE_POWER 500 // Consumption on Vbus line (mA)
 | 
			
		||||
#define USB_DEVICE_ATTR (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_BUS_POWERED)
 | 
			
		||||
//                                      (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED)
 | 
			
		||||
//                                      (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_SELF_POWERED)
 | 
			
		||||
| 
						 | 
				
			
			@ -161,4 +161,4 @@
 | 
			
		|||
#include "usb_main.h"
 | 
			
		||||
#include "ui.h"
 | 
			
		||||
 | 
			
		||||
#endif  // _CONF_USB_H_
 | 
			
		||||
#endif // _CONF_USB_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,15 +25,25 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
 | 
			
		||||
uint8_t keyboard_protocol = 1;
 | 
			
		||||
 | 
			
		||||
void main_suspend_action(void) { ui_powerdown(); }
 | 
			
		||||
void main_suspend_action(void) {
 | 
			
		||||
    ui_powerdown();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_resume_action(void) { ui_wakeup(); }
 | 
			
		||||
void main_resume_action(void) {
 | 
			
		||||
    ui_wakeup();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_sof_action(void) { ui_process(udd_get_frame_number()); }
 | 
			
		||||
void main_sof_action(void) {
 | 
			
		||||
    ui_process(udd_get_frame_number());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_remotewakeup_enable(void) { ui_wakeup_enable(); }
 | 
			
		||||
void main_remotewakeup_enable(void) {
 | 
			
		||||
    ui_wakeup_enable();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_remotewakeup_disable(void) { ui_wakeup_disable(); }
 | 
			
		||||
void main_remotewakeup_disable(void) {
 | 
			
		||||
    ui_wakeup_disable();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
volatile bool main_b_kbd_enable = false;
 | 
			
		||||
bool          main_kbd_enable(void) {
 | 
			
		||||
| 
						 | 
				
			
			@ -41,7 +51,9 @@ bool          main_kbd_enable(void) {
 | 
			
		|||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_kbd_disable(void) { main_b_kbd_enable = false; }
 | 
			
		||||
void main_kbd_disable(void) {
 | 
			
		||||
    main_b_kbd_enable = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef NKRO_ENABLE
 | 
			
		||||
volatile bool main_b_nkro_enable = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +62,9 @@ bool          main_nkro_enable(void) {
 | 
			
		|||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_nkro_disable(void) { main_b_nkro_enable = false; }
 | 
			
		||||
void main_nkro_disable(void) {
 | 
			
		||||
    main_b_nkro_enable = false;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EXTRAKEY_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +74,9 @@ bool          main_exk_enable(void) {
 | 
			
		|||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_exk_disable(void) { main_b_exk_enable = false; }
 | 
			
		||||
void main_exk_disable(void) {
 | 
			
		||||
    main_b_exk_enable = false;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			@ -70,7 +86,9 @@ bool          main_con_enable(void) {
 | 
			
		|||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_con_disable(void) { main_b_con_enable = false; }
 | 
			
		||||
void main_con_disable(void) {
 | 
			
		||||
    main_b_con_enable = false;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MOUSE_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			@ -80,7 +98,9 @@ bool          main_mou_enable(void) {
 | 
			
		|||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_mou_disable(void) { main_b_mou_enable = false; }
 | 
			
		||||
void main_mou_disable(void) {
 | 
			
		||||
    main_b_mou_enable = false;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef RAW_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			@ -90,7 +110,11 @@ bool          main_raw_enable(void) {
 | 
			
		|||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_raw_disable(void) { main_b_raw_enable = false; }
 | 
			
		||||
void main_raw_disable(void) {
 | 
			
		||||
    main_b_raw_enable = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_raw_receive(uint8_t *buffer, uint8_t len) { raw_hid_receive(buffer, len); }
 | 
			
		||||
void main_raw_receive(uint8_t *buffer, uint8_t len) {
 | 
			
		||||
    raw_hid_receive(buffer, len);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -124,20 +124,20 @@ typedef enum status_code status_code_genare_t;
 | 
			
		|||
 */
 | 
			
		||||
enum status_code_wireless {
 | 
			
		||||
    // STATUS_OK               =  0, //!< Success
 | 
			
		||||
    ERR_IO_ERROR              = -1,   //!< I/O error
 | 
			
		||||
    ERR_FLUSHED               = -2,   //!< Request flushed from queue
 | 
			
		||||
    ERR_TIMEOUT               = -3,   //!< Operation timed out
 | 
			
		||||
    ERR_BAD_DATA              = -4,   //!< Data integrity check failed
 | 
			
		||||
    ERR_PROTOCOL              = -5,   //!< Protocol error
 | 
			
		||||
    ERR_UNSUPPORTED_DEV       = -6,   //!< Unsupported device
 | 
			
		||||
    ERR_NO_MEMORY             = -7,   //!< Insufficient memory
 | 
			
		||||
    ERR_INVALID_ARG           = -8,   //!< Invalid argument
 | 
			
		||||
    ERR_BAD_ADDRESS           = -9,   //!< Bad address
 | 
			
		||||
    ERR_BUSY                  = -10,  //!< Resource is busy
 | 
			
		||||
    ERR_BAD_FORMAT            = -11,  //!< Data format not recognized
 | 
			
		||||
    ERR_NO_TIMER              = -12,  //!< No timer available
 | 
			
		||||
    ERR_TIMER_ALREADY_RUNNING = -13,  //!< Timer already running
 | 
			
		||||
    ERR_TIMER_NOT_RUNNING     = -14,  //!< Timer not running
 | 
			
		||||
    ERR_IO_ERROR              = -1,  //!< I/O error
 | 
			
		||||
    ERR_FLUSHED               = -2,  //!< Request flushed from queue
 | 
			
		||||
    ERR_TIMEOUT               = -3,  //!< Operation timed out
 | 
			
		||||
    ERR_BAD_DATA              = -4,  //!< Data integrity check failed
 | 
			
		||||
    ERR_PROTOCOL              = -5,  //!< Protocol error
 | 
			
		||||
    ERR_UNSUPPORTED_DEV       = -6,  //!< Unsupported device
 | 
			
		||||
    ERR_NO_MEMORY             = -7,  //!< Insufficient memory
 | 
			
		||||
    ERR_INVALID_ARG           = -8,  //!< Invalid argument
 | 
			
		||||
    ERR_BAD_ADDRESS           = -9,  //!< Bad address
 | 
			
		||||
    ERR_BUSY                  = -10, //!< Resource is busy
 | 
			
		||||
    ERR_BAD_FORMAT            = -11, //!< Data format not recognized
 | 
			
		||||
    ERR_NO_TIMER              = -12, //!< No timer available
 | 
			
		||||
    ERR_TIMER_ALREADY_RUNNING = -13, //!< Timer already running
 | 
			
		||||
    ERR_TIMER_NOT_RUNNING     = -14, //!< Timer not running
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * \brief Operation in progress
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,7 +52,7 @@
 | 
			
		|||
#include "udi.h"
 | 
			
		||||
#include "udc.h"
 | 
			
		||||
 | 
			
		||||
#define BOOTLOADER_SERIAL_MAX_SIZE 20  // DO NOT MODIFY!
 | 
			
		||||
#define BOOTLOADER_SERIAL_MAX_SIZE 20 // DO NOT MODIFY!
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \ingroup udc_group
 | 
			
		||||
| 
						 | 
				
			
			@ -132,13 +132,13 @@ uint8_t     bootloader_serial_number[BOOTLOADER_SERIAL_MAX_SIZE + 1] = "";
 | 
			
		|||
static const uint8_t *udc_get_string_serial_name(void) {
 | 
			
		||||
#if defined           USB_DEVICE_SERIAL_USE_BOOTLOADER_SERIAL
 | 
			
		||||
    uint32_t serial_ptrloc  = (uint32_t)&_srom - 4;
 | 
			
		||||
    uint32_t serial_address = *(uint32_t *)serial_ptrloc;  // Address of bootloader's serial number if available
 | 
			
		||||
    uint32_t serial_address = *(uint32_t *)serial_ptrloc; // Address of bootloader's serial number if available
 | 
			
		||||
 | 
			
		||||
    if (serial_address != 0xFFFFFFFF && serial_address < serial_ptrloc)  // Check for factory programmed serial address
 | 
			
		||||
    if (serial_address != 0xFFFFFFFF && serial_address < serial_ptrloc) // Check for factory programmed serial address
 | 
			
		||||
    {
 | 
			
		||||
        if ((serial_address & 0xFF) % 4 == 0)  // Check alignment
 | 
			
		||||
        if ((serial_address & 0xFF) % 4 == 0) // Check alignment
 | 
			
		||||
        {
 | 
			
		||||
            uint16_t *serial_use    = (uint16_t *)(serial_address);  // Point to address of string in rom
 | 
			
		||||
            uint16_t *serial_use    = (uint16_t *)(serial_address); // Point to address of string in rom
 | 
			
		||||
            uint8_t   serial_length = 0;
 | 
			
		||||
 | 
			
		||||
            while ((*(serial_use + serial_length) > 32 && *(serial_use + serial_length) < 127) && serial_length < BOOTLOADER_SERIAL_MAX_SIZE) {
 | 
			
		||||
| 
						 | 
				
			
			@ -149,7 +149,7 @@ static const uint8_t *udc_get_string_serial_name(void) {
 | 
			
		|||
 | 
			
		||||
            usb_device_serial_name_size = serial_length;
 | 
			
		||||
 | 
			
		||||
            return bootloader_serial_number;  // Use serial programmed into bootloader rom
 | 
			
		||||
            return bootloader_serial_number; // Use serial programmed into bootloader rom
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -157,9 +157,9 @@ static const uint8_t *udc_get_string_serial_name(void) {
 | 
			
		|||
    usb_device_serial_name_size = USB_DEVICE_SERIAL_NAME_SIZE;
 | 
			
		||||
 | 
			
		||||
#if defined USB_DEVICE_SERIAL_NAME
 | 
			
		||||
    return (const uint8_t *)USB_DEVICE_SERIAL_NAME;  // Use serial supplied by keyboard's config.h
 | 
			
		||||
    return (const uint8_t *)USB_DEVICE_SERIAL_NAME; // Use serial supplied by keyboard's config.h
 | 
			
		||||
#else
 | 
			
		||||
    return 0;  // No serial supplied
 | 
			
		||||
    return 0; // No serial supplied
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -169,7 +169,7 @@ static const uint8_t *udc_get_string_serial_name(void) {
 | 
			
		|||
 */
 | 
			
		||||
#ifndef BOOTLOADER_SERIAL_MAX_SIZE
 | 
			
		||||
#    define BOOTLOADER_SERIAL_MAX_SIZE 0
 | 
			
		||||
#endif  // BOOTLOADER_SERIAL_MAX_SIZE
 | 
			
		||||
#endif // BOOTLOADER_SERIAL_MAX_SIZE
 | 
			
		||||
struct udc_string_desc_t {
 | 
			
		||||
    usb_str_desc_t header;
 | 
			
		||||
    le16_t         string[Max(Max(Max(USB_DEVICE_MANUFACTURE_NAME_SIZE, USB_DEVICE_PRODUCT_NAME_SIZE), USB_DEVICE_SERIAL_NAME_SIZE), BOOTLOADER_SERIAL_MAX_SIZE)];
 | 
			
		||||
| 
						 | 
				
			
			@ -178,14 +178,18 @@ COMPILER_WORD_ALIGNED
 | 
			
		|||
static UDC_DESC_STORAGE struct udc_string_desc_t udc_string_desc = {.header.bDescriptorType = USB_DT_STRING};
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void) { return udc_ptr_iface; }
 | 
			
		||||
usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void) {
 | 
			
		||||
    return udc_ptr_iface;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Returns a value to check the end of USB Configuration descriptor
 | 
			
		||||
 *
 | 
			
		||||
 * \return address after the last byte of USB Configuration descriptor
 | 
			
		||||
 */
 | 
			
		||||
static usb_conf_desc_t UDC_DESC_STORAGE *udc_get_eof_conf(void) { return (UDC_DESC_STORAGE usb_conf_desc_t *)((uint8_t *)udc_ptr_conf->desc + le16_to_cpu(udc_ptr_conf->desc->wTotalLength)); }
 | 
			
		||||
static usb_conf_desc_t UDC_DESC_STORAGE *udc_get_eof_conf(void) {
 | 
			
		||||
    return (UDC_DESC_STORAGE usb_conf_desc_t *)((uint8_t *)udc_ptr_conf->desc + le16_to_cpu(udc_ptr_conf->desc->wTotalLength));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if (0 != USB_DEVICE_MAX_EP)
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -209,15 +213,15 @@ static usb_conf_desc_t UDC_DESC_STORAGE *udc_next_desc_in_iface(usb_conf_desc_t
 | 
			
		|||
        // If new interface descriptor is found,
 | 
			
		||||
        // then it is the end of the current global interface descriptor
 | 
			
		||||
        if (USB_DT_INTERFACE == desc->bDescriptorType) {
 | 
			
		||||
            break;  // End of global interface descriptor
 | 
			
		||||
            break; // End of global interface descriptor
 | 
			
		||||
        }
 | 
			
		||||
        if (desc_id == desc->bDescriptorType) {
 | 
			
		||||
            return desc;  // Specific descriptor found
 | 
			
		||||
            return desc; // Specific descriptor found
 | 
			
		||||
        }
 | 
			
		||||
        // Go to next descriptor
 | 
			
		||||
        desc = (UDC_DESC_STORAGE usb_conf_desc_t *)((uint8_t *)desc + desc->bLength);
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;  // No specific descriptor found
 | 
			
		||||
    return NULL; // No specific descriptor found
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -251,13 +255,13 @@ static bool udc_update_iface_desc(uint8_t iface_num, uint8_t setting_num) {
 | 
			
		|||
            // A interface descriptor is found
 | 
			
		||||
            // Check interface and alternate setting number
 | 
			
		||||
            if ((iface_num == udc_ptr_iface->bInterfaceNumber) && (setting_num == udc_ptr_iface->bAlternateSetting)) {
 | 
			
		||||
                return true;  // Interface found
 | 
			
		||||
                return true; // Interface found
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // Go to next descriptor
 | 
			
		||||
        udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *)((uint8_t *)udc_ptr_iface + udc_ptr_iface->bLength);
 | 
			
		||||
    }
 | 
			
		||||
    return false;  // Interface not found
 | 
			
		||||
    return false; // Interface not found
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -343,7 +347,9 @@ static bool udc_iface_enable(uint8_t iface_num, uint8_t setting_num) {
 | 
			
		|||
 | 
			
		||||
/*! \brief Start the USB Device stack
 | 
			
		||||
 */
 | 
			
		||||
void udc_start(void) { udd_enable(); }
 | 
			
		||||
void udc_start(void) {
 | 
			
		||||
    udd_enable();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*! \brief Stop the USB Device stack
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -510,7 +516,7 @@ static bool udc_req_std_dev_set_feature(void) {
 | 
			
		|||
                    udd_g_ctrlreq.callback = udd_test_mode_packet;
 | 
			
		||||
                    return true;
 | 
			
		||||
 | 
			
		||||
                case USB_DEV_TEST_MODE_FORCE_ENABLE:  // Only for downstream facing hub ports
 | 
			
		||||
                case USB_DEV_TEST_MODE_FORCE_ENABLE: // Only for downstream facing hub ports
 | 
			
		||||
                default:
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -544,7 +550,9 @@ static bool udc_req_std_ep_set_feature(void) {
 | 
			
		|||
 * \brief Change the address of device
 | 
			
		||||
 * Callback called at the end of request set address
 | 
			
		||||
 */
 | 
			
		||||
static void udc_valid_address(void) { udd_set_address(udd_g_ctrlreq.req.wValue & 0x7F); }
 | 
			
		||||
static void udc_valid_address(void) {
 | 
			
		||||
    udd_set_address(udd_g_ctrlreq.req.wValue & 0x7F);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Standard device request to set device address
 | 
			
		||||
| 
						 | 
				
			
			@ -763,7 +771,7 @@ static bool udc_req_std_dev_set_configuration(void) {
 | 
			
		|||
    // Enable new configuration
 | 
			
		||||
    udc_num_configuration = udd_g_ctrlreq.req.wValue & 0xFF;
 | 
			
		||||
    if (udc_num_configuration == 0) {
 | 
			
		||||
        return true;  // Default empty configuration requested
 | 
			
		||||
        return true; // Default empty configuration requested
 | 
			
		||||
    }
 | 
			
		||||
    // Update pointer of the configuration descriptor
 | 
			
		||||
#ifdef USB_DEVICE_HS_SUPPORT
 | 
			
		||||
| 
						 | 
				
			
			@ -796,10 +804,10 @@ static bool udc_req_std_iface_get_setting(void) {
 | 
			
		|||
    udi_api_t UDC_DESC_STORAGE *udi_api;
 | 
			
		||||
 | 
			
		||||
    if (udd_g_ctrlreq.req.wLength != 1) {
 | 
			
		||||
        return false;  // Error in request
 | 
			
		||||
        return false; // Error in request
 | 
			
		||||
    }
 | 
			
		||||
    if (!udc_num_configuration) {
 | 
			
		||||
        return false;  // The device is not is configured state yet
 | 
			
		||||
        return false; // The device is not is configured state yet
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Check the interface number included in the request
 | 
			
		||||
| 
						 | 
				
			
			@ -832,10 +840,10 @@ static bool udc_req_std_iface_set_setting(void) {
 | 
			
		|||
    uint8_t iface_num, setting_num;
 | 
			
		||||
 | 
			
		||||
    if (udd_g_ctrlreq.req.wLength) {
 | 
			
		||||
        return false;  // Error in request
 | 
			
		||||
        return false; // Error in request
 | 
			
		||||
    }
 | 
			
		||||
    if (!udc_num_configuration) {
 | 
			
		||||
        return false;  // The device is not is configured state yet
 | 
			
		||||
        return false; // The device is not is configured state yet
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    iface_num   = udd_g_ctrlreq.req.wIndex & 0xFF;
 | 
			
		||||
| 
						 | 
				
			
			@ -859,7 +867,7 @@ static bool udc_reqstd(void) {
 | 
			
		|||
    if (Udd_setup_is_in()) {
 | 
			
		||||
        // GET Standard Requests
 | 
			
		||||
        if (udd_g_ctrlreq.req.wLength == 0) {
 | 
			
		||||
            return false;  // Error for USB host
 | 
			
		||||
            return false; // Error for USB host
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -953,7 +961,7 @@ static bool udc_req_iface(void) {
 | 
			
		|||
    udi_api_t UDC_DESC_STORAGE *udi_api;
 | 
			
		||||
 | 
			
		||||
    if (0 == udc_num_configuration) {
 | 
			
		||||
        return false;  // The device is not is configured state yet
 | 
			
		||||
        return false; // The device is not is configured state yet
 | 
			
		||||
    }
 | 
			
		||||
    // Check interface number
 | 
			
		||||
    iface_num = udd_g_ctrlreq.req.wIndex & 0xFF;
 | 
			
		||||
| 
						 | 
				
			
			@ -987,7 +995,7 @@ static bool udc_req_ep(void) {
 | 
			
		|||
    udi_api_t UDC_DESC_STORAGE *udi_api;
 | 
			
		||||
 | 
			
		||||
    if (0 == udc_num_configuration) {
 | 
			
		||||
        return false;  // The device is not is configured state yet
 | 
			
		||||
        return false; // The device is not is configured state yet
 | 
			
		||||
    }
 | 
			
		||||
    // Send this request on all enabled interfaces
 | 
			
		||||
    iface_num = udd_g_ctrlreq.req.wIndex & 0xFF;
 | 
			
		||||
| 
						 | 
				
			
			@ -1027,7 +1035,7 @@ bool udc_process_setup(void) {
 | 
			
		|||
 | 
			
		||||
    if (Udd_setup_is_in()) {
 | 
			
		||||
        if (udd_g_ctrlreq.req.wLength == 0) {
 | 
			
		||||
            return false;  // Error from USB host
 | 
			
		||||
            return false; // Error from USB host
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1055,7 +1063,7 @@ bool udc_process_setup(void) {
 | 
			
		|||
    // Here SETUP request unknown by UDC and UDIs
 | 
			
		||||
#ifdef USB_DEVICE_SPECIFIC_REQUEST
 | 
			
		||||
    // Try to decode it in specific callback
 | 
			
		||||
    return USB_DEVICE_SPECIFIC_REQUEST();  // Ex: Vendor request,...
 | 
			
		||||
    return USB_DEVICE_SPECIFIC_REQUEST(); // Ex: Vendor request,...
 | 
			
		||||
#else
 | 
			
		||||
    return false;
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -172,7 +172,9 @@ extern "C" {
 | 
			
		|||
    }
 | 
			
		||||
\endcode
 | 
			
		||||
 */
 | 
			
		||||
static inline bool udc_include_vbus_monitoring(void) { return udd_include_vbus_monitoring(); }
 | 
			
		||||
static inline bool udc_include_vbus_monitoring(void) {
 | 
			
		||||
    return udd_include_vbus_monitoring();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*! \brief Start the USB Device stack
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -189,19 +191,25 @@ void udc_stop(void);
 | 
			
		|||
 * then it will attach device when an acceptable Vbus
 | 
			
		||||
 * level from the host is detected.
 | 
			
		||||
 */
 | 
			
		||||
static inline void udc_attach(void) { udd_attach(); }
 | 
			
		||||
static inline void udc_attach(void) {
 | 
			
		||||
    udd_attach();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Detaches the device from the bus
 | 
			
		||||
 *
 | 
			
		||||
 * The driver must remove pull-up on USB line D- or D+.
 | 
			
		||||
 */
 | 
			
		||||
static inline void udc_detach(void) { udd_detach(); }
 | 
			
		||||
static inline void udc_detach(void) {
 | 
			
		||||
    udd_detach();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*! \brief The USB driver sends a resume signal called \e "Upstream Resume"
 | 
			
		||||
 * This is authorized only when the remote wakeup feature is enabled by host.
 | 
			
		||||
 */
 | 
			
		||||
inline void udc_remotewakeup(void) { udd_send_remotewakeup(); }
 | 
			
		||||
inline void udc_remotewakeup(void) {
 | 
			
		||||
    udd_send_remotewakeup();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Returns a pointer on the current interface descriptor
 | 
			
		||||
| 
						 | 
				
			
			@ -245,4 +253,4 @@ usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void);
 | 
			
		|||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // _UDC_H_
 | 
			
		||||
#endif // _UDC_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -129,4 +129,4 @@ extern UDC_DESC_STORAGE udc_config_t udc_config;
 | 
			
		|||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif  // _UDC_DESC_H_
 | 
			
		||||
#endif // _UDC_DESC_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -381,4 +381,4 @@ extern void udc_sof_notify(void);
 | 
			
		|||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif  // _UDD_H_
 | 
			
		||||
#endif // _UDD_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -130,4 +130,4 @@ typedef struct {
 | 
			
		|||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif  // _UDI_H_
 | 
			
		||||
#endif // _UDI_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -386,7 +386,7 @@ bool udi_cdc_comm_setup(void) {
 | 
			
		|||
            switch (udd_g_ctrlreq.req.bRequest) {
 | 
			
		||||
                case USB_REQ_CDC_GET_LINE_CODING:
 | 
			
		||||
                    // Get configuration of CDC line
 | 
			
		||||
                    if (sizeof(usb_cdc_line_coding_t) != udd_g_ctrlreq.req.wLength) return false;  // Error for USB host
 | 
			
		||||
                    if (sizeof(usb_cdc_line_coding_t) != udd_g_ctrlreq.req.wLength) return false; // Error for USB host
 | 
			
		||||
                    udd_g_ctrlreq.payload      = (uint8_t *)&udi_cdc_line_coding[port];
 | 
			
		||||
                    udd_g_ctrlreq.payload_size = sizeof(usb_cdc_line_coding_t);
 | 
			
		||||
                    return true;
 | 
			
		||||
| 
						 | 
				
			
			@ -400,7 +400,7 @@ bool udi_cdc_comm_setup(void) {
 | 
			
		|||
            switch (udd_g_ctrlreq.req.bRequest) {
 | 
			
		||||
                case USB_REQ_CDC_SET_LINE_CODING:
 | 
			
		||||
                    // Change configuration of CDC line
 | 
			
		||||
                    if (sizeof(usb_cdc_line_coding_t) != udd_g_ctrlreq.req.wLength) return false;  // Error for USB host
 | 
			
		||||
                    if (sizeof(usb_cdc_line_coding_t) != udd_g_ctrlreq.req.wLength) return false; // Error for USB host
 | 
			
		||||
                    udd_g_ctrlreq.callback     = udi_cdc_line_coding_received;
 | 
			
		||||
                    udd_g_ctrlreq.payload      = (uint8_t *)&udi_cdc_line_coding[port];
 | 
			
		||||
                    udd_g_ctrlreq.payload_size = sizeof(usb_cdc_line_coding_t);
 | 
			
		||||
| 
						 | 
				
			
			@ -417,15 +417,15 @@ bool udi_cdc_comm_setup(void) {
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return false;  // request Not supported
 | 
			
		||||
    return false; // request Not supported
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool udi_cdc_data_setup(void) {
 | 
			
		||||
    return false;  // request Not supported
 | 
			
		||||
    return false; // request Not supported
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t udi_cdc_getsetting(void) {
 | 
			
		||||
    return 0;  // CDC don't have multiple alternate setting
 | 
			
		||||
    return 0; // CDC don't have multiple alternate setting
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udi_cdc_data_sof_notify(void) {
 | 
			
		||||
| 
						 | 
				
			
			@ -476,7 +476,7 @@ static void udi_cdc_line_coding_received(void) {
 | 
			
		|||
 | 
			
		||||
static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask) {
 | 
			
		||||
    udd_ep_id_t ep_comm;
 | 
			
		||||
    uint32_t    irqflags;  // irqflags_t
 | 
			
		||||
    uint32_t    irqflags; // irqflags_t
 | 
			
		||||
 | 
			
		||||
    //#if UDI_CDC_PORT_NB == 1 // To optimize code
 | 
			
		||||
    port = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -514,7 +514,7 @@ static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep) {
 | 
			
		||||
#    if UDI_CDC_PORT_NB == 1  // To optimize code
 | 
			
		||||
#    if UDI_CDC_PORT_NB == 1 // To optimize code
 | 
			
		||||
    port = 0;
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -562,7 +562,7 @@ static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n,
 | 
			
		|||
//------- Internal routines to process data transfer
 | 
			
		||||
 | 
			
		||||
static bool udi_cdc_rx_start(uint8_t port) {
 | 
			
		||||
    uint32_t    irqflags;  // irqflags_t
 | 
			
		||||
    uint32_t    irqflags; // irqflags_t
 | 
			
		||||
    uint8_t     buf_sel_trans;
 | 
			
		||||
    udd_ep_id_t ep;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -685,7 +685,7 @@ static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static void udi_cdc_tx_send(uint8_t port) {
 | 
			
		||||
    uint32_t        irqflags;  // irqflags_t
 | 
			
		||||
    uint32_t        irqflags; // irqflags_t
 | 
			
		||||
    uint8_t         buf_sel_trans;
 | 
			
		||||
    bool            b_short_packet;
 | 
			
		||||
    udd_ep_id_t     ep;
 | 
			
		||||
| 
						 | 
				
			
			@ -696,15 +696,15 @@ static void udi_cdc_tx_send(uint8_t port) {
 | 
			
		|||
    //#endif
 | 
			
		||||
 | 
			
		||||
    if (udi_cdc_tx_trans_ongoing[port]) {
 | 
			
		||||
        return;  // Already on going or wait next SOF to send next data
 | 
			
		||||
        return; // Already on going or wait next SOF to send next data
 | 
			
		||||
    }
 | 
			
		||||
    if (udd_is_high_speed()) {
 | 
			
		||||
        if (udi_cdc_tx_sof_num[port] == udd_get_micro_frame_number()) {
 | 
			
		||||
            return;  // Wait next SOF to send next data
 | 
			
		||||
            return; // Wait next SOF to send next data
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        if (udi_cdc_tx_sof_num[port] == udd_get_frame_number()) {
 | 
			
		||||
            return;  // Wait next SOF to send next data
 | 
			
		||||
            return; // Wait next SOF to send next data
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -743,7 +743,7 @@ static void udi_cdc_tx_send(uint8_t port) {
 | 
			
		|||
            udi_cdc_tx_sof_num[port] = udd_get_frame_number();
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        udi_cdc_tx_sof_num[port] = 0;  // Force next transfer without wait SOF
 | 
			
		||||
        udi_cdc_tx_sof_num[port] = 0; // Force next transfer without wait SOF
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
| 
						 | 
				
			
			@ -768,28 +768,48 @@ static void udi_cdc_tx_send(uint8_t port) {
 | 
			
		|||
//---------------------------------------------
 | 
			
		||||
//------- Application interface
 | 
			
		||||
 | 
			
		||||
void udi_cdc_ctrl_signal_dcd(bool b_set) { udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DCD); }
 | 
			
		||||
void udi_cdc_ctrl_signal_dcd(bool b_set) {
 | 
			
		||||
    udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DCD);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udi_cdc_ctrl_signal_dsr(bool b_set) { udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DSR); }
 | 
			
		||||
void udi_cdc_ctrl_signal_dsr(bool b_set) {
 | 
			
		||||
    udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DSR);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udi_cdc_signal_framing_error(void) { udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_FRAMING); }
 | 
			
		||||
void udi_cdc_signal_framing_error(void) {
 | 
			
		||||
    udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_FRAMING);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udi_cdc_signal_parity_error(void) { udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_PARITY); }
 | 
			
		||||
void udi_cdc_signal_parity_error(void) {
 | 
			
		||||
    udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_PARITY);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udi_cdc_signal_overrun(void) { udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_OVERRUN); }
 | 
			
		||||
void udi_cdc_signal_overrun(void) {
 | 
			
		||||
    udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_OVERRUN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set) { udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DCD); }
 | 
			
		||||
void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set) {
 | 
			
		||||
    udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DCD);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set) { udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DSR); }
 | 
			
		||||
void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set) {
 | 
			
		||||
    udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DSR);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udi_cdc_multi_signal_framing_error(uint8_t port) { udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_FRAMING); }
 | 
			
		||||
void udi_cdc_multi_signal_framing_error(uint8_t port) {
 | 
			
		||||
    udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_FRAMING);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udi_cdc_multi_signal_parity_error(uint8_t port) { udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_PARITY); }
 | 
			
		||||
void udi_cdc_multi_signal_parity_error(uint8_t port) {
 | 
			
		||||
    udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_PARITY);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udi_cdc_multi_signal_overrun(uint8_t port) { udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_OVERRUN); }
 | 
			
		||||
void udi_cdc_multi_signal_overrun(uint8_t port) {
 | 
			
		||||
    udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_OVERRUN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
iram_size_t udi_cdc_multi_get_nb_received_data(uint8_t port) {
 | 
			
		||||
    uint32_t    irqflags;  // irqflags_t
 | 
			
		||||
    uint32_t    irqflags; // irqflags_t
 | 
			
		||||
    uint16_t    pos;
 | 
			
		||||
    iram_size_t nb_received;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -807,14 +827,20 @@ iram_size_t udi_cdc_multi_get_nb_received_data(uint8_t port) {
 | 
			
		|||
    return nb_received;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
iram_size_t udi_cdc_get_nb_received_data(void) { return udi_cdc_multi_get_nb_received_data(0); }
 | 
			
		||||
iram_size_t udi_cdc_get_nb_received_data(void) {
 | 
			
		||||
    return udi_cdc_multi_get_nb_received_data(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool udi_cdc_multi_is_rx_ready(uint8_t port) { return (udi_cdc_multi_get_nb_received_data(port) > 0); }
 | 
			
		||||
bool udi_cdc_multi_is_rx_ready(uint8_t port) {
 | 
			
		||||
    return (udi_cdc_multi_get_nb_received_data(port) > 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool udi_cdc_is_rx_ready(void) { return udi_cdc_multi_is_rx_ready(0); }
 | 
			
		||||
bool udi_cdc_is_rx_ready(void) {
 | 
			
		||||
    return udi_cdc_multi_is_rx_ready(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int udi_cdc_multi_getc(uint8_t port) {
 | 
			
		||||
    uint32_t irqflags;  // irqflags_t
 | 
			
		||||
    uint32_t irqflags; // irqflags_t
 | 
			
		||||
    int      rx_data = 0;
 | 
			
		||||
    bool     b_databit_9;
 | 
			
		||||
    uint16_t pos;
 | 
			
		||||
| 
						 | 
				
			
			@ -859,10 +885,12 @@ udi_cdc_getc_process_one_byte:
 | 
			
		|||
    return rx_data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int udi_cdc_getc(void) { return udi_cdc_multi_getc(0); }
 | 
			
		||||
int udi_cdc_getc(void) {
 | 
			
		||||
    return udi_cdc_multi_getc(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
iram_size_t udi_cdc_multi_read_buf(uint8_t port, void *buf, iram_size_t size) {
 | 
			
		||||
    uint32_t    irqflags;  // irqflags_t
 | 
			
		||||
    uint32_t    irqflags; // irqflags_t
 | 
			
		||||
    uint8_t *   ptr_buf = (uint8_t *)buf;
 | 
			
		||||
    iram_size_t copy_nb;
 | 
			
		||||
    uint16_t    pos;
 | 
			
		||||
| 
						 | 
				
			
			@ -912,7 +940,7 @@ static iram_size_t udi_cdc_multi_read_no_polling(uint8_t port, void *buf, iram_s
 | 
			
		|||
    iram_size_t nb_avail_data;
 | 
			
		||||
    uint16_t    pos;
 | 
			
		||||
    uint8_t     buf_sel;
 | 
			
		||||
    uint32_t    irqflags;  // irqflags_t
 | 
			
		||||
    uint32_t    irqflags; // irqflags_t
 | 
			
		||||
 | 
			
		||||
    //#if UDI_CDC_PORT_NB == 1 // To optimize code
 | 
			
		||||
    port = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -952,12 +980,16 @@ static iram_size_t udi_cdc_multi_read_no_polling(uint8_t port, void *buf, iram_s
 | 
			
		|||
    return (nb_avail_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
iram_size_t udi_cdc_read_no_polling(void *buf, iram_size_t size) { return udi_cdc_multi_read_no_polling(0, buf, size); }
 | 
			
		||||
iram_size_t udi_cdc_read_no_polling(void *buf, iram_size_t size) {
 | 
			
		||||
    return udi_cdc_multi_read_no_polling(0, buf, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
iram_size_t udi_cdc_read_buf(void *buf, iram_size_t size) { return udi_cdc_multi_read_buf(0, buf, size); }
 | 
			
		||||
iram_size_t udi_cdc_read_buf(void *buf, iram_size_t size) {
 | 
			
		||||
    return udi_cdc_multi_read_buf(0, buf, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
iram_size_t udi_cdc_multi_get_free_tx_buffer(uint8_t port) {
 | 
			
		||||
    uint32_t    irqflags;  // irqflags_t
 | 
			
		||||
    uint32_t    irqflags; // irqflags_t
 | 
			
		||||
    iram_size_t buf_sel_nb, retval;
 | 
			
		||||
    uint8_t     buf_sel;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -986,14 +1018,20 @@ iram_size_t udi_cdc_multi_get_free_tx_buffer(uint8_t port) {
 | 
			
		|||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
iram_size_t udi_cdc_get_free_tx_buffer(void) { return udi_cdc_multi_get_free_tx_buffer(0); }
 | 
			
		||||
iram_size_t udi_cdc_get_free_tx_buffer(void) {
 | 
			
		||||
    return udi_cdc_multi_get_free_tx_buffer(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool udi_cdc_multi_is_tx_ready(uint8_t port) { return (udi_cdc_multi_get_free_tx_buffer(port) != 0); }
 | 
			
		||||
bool udi_cdc_multi_is_tx_ready(uint8_t port) {
 | 
			
		||||
    return (udi_cdc_multi_get_free_tx_buffer(port) != 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool udi_cdc_is_tx_ready(void) { return udi_cdc_multi_is_tx_ready(0); }
 | 
			
		||||
bool udi_cdc_is_tx_ready(void) {
 | 
			
		||||
    return udi_cdc_multi_is_tx_ready(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int udi_cdc_multi_putc(uint8_t port, int value) {
 | 
			
		||||
    uint32_t irqflags;  // irqflags_t
 | 
			
		||||
    uint32_t irqflags; // irqflags_t
 | 
			
		||||
    bool     b_databit_9;
 | 
			
		||||
    uint8_t  buf_sel;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1030,10 +1068,12 @@ udi_cdc_putc_process_one_byte:
 | 
			
		|||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int udi_cdc_putc(int value) { return udi_cdc_multi_putc(0, value); }
 | 
			
		||||
int udi_cdc_putc(int value) {
 | 
			
		||||
    return udi_cdc_multi_putc(0, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void *buf, iram_size_t size) {
 | 
			
		||||
    uint32_t    irqflags;  // irqflags_t
 | 
			
		||||
    uint32_t    irqflags; // irqflags_t
 | 
			
		||||
    uint8_t     buf_sel;
 | 
			
		||||
    uint16_t    buf_nb;
 | 
			
		||||
    iram_size_t copy_nb;
 | 
			
		||||
| 
						 | 
				
			
			@ -1083,7 +1123,9 @@ udi_cdc_write_buf_loop_wait:
 | 
			
		|||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
iram_size_t udi_cdc_write_buf(const void *buf, iram_size_t size) { return udi_cdc_multi_write_buf(0, buf, size); }
 | 
			
		||||
iram_size_t udi_cdc_write_buf(const void *buf, iram_size_t size) {
 | 
			
		||||
    return udi_cdc_multi_write_buf(0, buf, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#    define MAX_PRINT 256
 | 
			
		||||
#    define CDC_SEND_INTERVAL 2
 | 
			
		||||
| 
						 | 
				
			
			@ -1121,10 +1163,10 @@ uint32_t CDC_print(char *printbuf) {
 | 
			
		|||
char printbuf[CDC_PRINTBUF_SIZE];
 | 
			
		||||
 | 
			
		||||
int CDC_printf(const char *_Format, ...) {
 | 
			
		||||
    va_list va;  // Variable argument list variable
 | 
			
		||||
    va_list va; // Variable argument list variable
 | 
			
		||||
    int     result;
 | 
			
		||||
 | 
			
		||||
    va_start(va, _Format);  // Initialize the variable argument list
 | 
			
		||||
    va_start(va, _Format); // Initialize the variable argument list
 | 
			
		||||
    result = vsnprintf(printbuf, CDC_PRINTBUF_SIZE, _Format, va);
 | 
			
		||||
    va_end(va);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1146,18 +1188,18 @@ uint32_t CDC_input_buf(inbuf_t inbuf, uint32_t inbuf_size) {
 | 
			
		|||
 | 
			
		||||
    if (RXChar) {
 | 
			
		||||
        switch (RXChar) {
 | 
			
		||||
            case '\t':  // tab - repeat last
 | 
			
		||||
            case '\t': // tab - repeat last
 | 
			
		||||
                inbuf.count                = inbuf.lastcount;
 | 
			
		||||
                inbuf.buf[inbuf.count + 1] = 0;
 | 
			
		||||
                CDC_print(inbuf.buf);
 | 
			
		||||
                break;
 | 
			
		||||
            case '\r':  // enter
 | 
			
		||||
            case '\r': // enter
 | 
			
		||||
                inbuf.buf[inbuf.count] = 0;
 | 
			
		||||
                inbuf.lastcount        = inbuf.count;
 | 
			
		||||
                inbuf.count            = 0;
 | 
			
		||||
                entered                = 1;
 | 
			
		||||
                break;
 | 
			
		||||
            case '\b':  // backspace
 | 
			
		||||
            case '\b': // backspace
 | 
			
		||||
                if (inbuf.count > 0) {
 | 
			
		||||
                    inbuf.count -= 1;
 | 
			
		||||
                    CDC_print("\b \b\0");
 | 
			
		||||
| 
						 | 
				
			
			@ -1181,7 +1223,9 @@ uint32_t CDC_input_buf(inbuf_t inbuf, uint32_t inbuf_size) {
 | 
			
		|||
    return entered;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t CDC_input() { return CDC_input_buf(inbuf, CDC_INBUF_SIZE); }
 | 
			
		||||
uint32_t CDC_input() {
 | 
			
		||||
    return CDC_input_buf(inbuf, CDC_INBUF_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CDC_init(void) {
 | 
			
		||||
    inbuf.count           = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1190,19 +1234,27 @@ void CDC_init(void) {
 | 
			
		|||
    cdc_tx_send_time_next = timer_read64() + CDC_SEND_INTERVAL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else  // CDC line 62
 | 
			
		||||
#else // CDC line 62
 | 
			
		||||
 | 
			
		||||
char printbuf[CDC_PRINTBUF_SIZE];
 | 
			
		||||
 | 
			
		||||
void CDC_send(void) { return; }
 | 
			
		||||
void CDC_send(void) {
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t CDC_print(char *printbuf) { return 0; }
 | 
			
		||||
uint32_t CDC_print(char *printbuf) {
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int CDC_printf(const char *_Format, ...) { return 0; }
 | 
			
		||||
int CDC_printf(const char *_Format, ...) {
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inbuf_t inbuf;
 | 
			
		||||
 | 
			
		||||
uint32_t CDC_input(void) { return 0; }
 | 
			
		||||
uint32_t CDC_input(void) {
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CDC_init(void) {
 | 
			
		||||
    inbuf.count     = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1210,6 +1262,6 @@ void CDC_init(void) {
 | 
			
		|||
    printbuf[0]     = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif  // CDC line 62
 | 
			
		||||
#endif // CDC line 62
 | 
			
		||||
 | 
			
		||||
//@}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -346,7 +346,7 @@ typedef struct {
 | 
			
		|||
    char     buf[CDC_INBUF_SIZE];
 | 
			
		||||
} inbuf_t;
 | 
			
		||||
 | 
			
		||||
#else  // VIRTSER_ENABLE
 | 
			
		||||
#else // VIRTSER_ENABLE
 | 
			
		||||
 | 
			
		||||
// keep these to accommodate calls if remaining
 | 
			
		||||
#    define CDC_PRINTBUF_SIZE 1
 | 
			
		||||
| 
						 | 
				
			
			@ -362,7 +362,7 @@ typedef struct {
 | 
			
		|||
 | 
			
		||||
extern inbuf_t inbuf;
 | 
			
		||||
 | 
			
		||||
#endif  // VIRTSER_ENABLE
 | 
			
		||||
#endif // VIRTSER_ENABLE
 | 
			
		||||
 | 
			
		||||
uint32_t CDC_print(char* printbuf);
 | 
			
		||||
int      CDC_printf(const char* _Format, ...);
 | 
			
		||||
| 
						 | 
				
			
			@ -373,4 +373,4 @@ void     CDC_init(void);
 | 
			
		|||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // _UDI_CDC_H_
 | 
			
		||||
#endif // _UDI_CDC_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,9 +59,9 @@
 | 
			
		|||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define UDI_CDC_DATA_EP_IN_0 ((CDC_TX_ENDPOINT) | (USB_EP_DIR_IN))    // TX
 | 
			
		||||
#define UDI_CDC_DATA_EP_OUT_0 ((CDC_RX_ENDPOINT) | (USB_EP_DIR_OUT))  // RX
 | 
			
		||||
#define UDI_CDC_COMM_EP_0 ((CDC_ACM_ENDPOINT) | (USB_EP_DIR_IN))      // Notify endpoint
 | 
			
		||||
#define UDI_CDC_DATA_EP_IN_0 ((CDC_TX_ENDPOINT) | (USB_EP_DIR_IN))   // TX
 | 
			
		||||
#define UDI_CDC_DATA_EP_OUT_0 ((CDC_RX_ENDPOINT) | (USB_EP_DIR_OUT)) // RX
 | 
			
		||||
#define UDI_CDC_COMM_EP_0 ((CDC_ACM_ENDPOINT) | (USB_EP_DIR_IN))     // Notify endpoint
 | 
			
		||||
 | 
			
		||||
#define UDI_CDC_COMM_IFACE_NUMBER_0 (CDC_STATUS_INTERFACE)
 | 
			
		||||
#define UDI_CDC_DATA_IFACE_NUMBER_0 (CDC_DATA_INTERFACE)
 | 
			
		||||
| 
						 | 
				
			
			@ -69,4 +69,4 @@ extern "C" {
 | 
			
		|||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif  // _UDI_CDC_CONF_H_
 | 
			
		||||
#endif // _UDI_CDC_CONF_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -220,7 +220,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#    define NEXT_OUT_EPNUM_4 (CDC_OUT_EPNUM + 1)
 | 
			
		||||
 | 
			
		||||
#    define CDC_ACM_SIZE CDC_NOTIFICATION_EPSIZE
 | 
			
		||||
#    define CDC_RX_SIZE CDC_EPSIZE  // KFSMOD was 64
 | 
			
		||||
#    define CDC_RX_SIZE CDC_EPSIZE // KFSMOD was 64
 | 
			
		||||
#    define CDC_TX_SIZE CDC_RX_SIZE
 | 
			
		||||
#    define CDC_ACM_POLLING_INTERVAL 255
 | 
			
		||||
#    define CDC_EP_INTERVAL_STATUS CDC_ACM_POLLING_INTERVAL
 | 
			
		||||
| 
						 | 
				
			
			@ -370,7 +370,7 @@ extern udi_hid_exk_report_t udi_hid_exk_report;
 | 
			
		|||
 | 
			
		||||
COMPILER_PACK_RESET()
 | 
			
		||||
 | 
			
		||||
#endif  // EXTRAKEY_ENABLE
 | 
			
		||||
#endif // EXTRAKEY_ENABLE
 | 
			
		||||
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
// NKRO Descriptor structure and content
 | 
			
		||||
| 
						 | 
				
			
			@ -433,7 +433,7 @@ extern uint8_t udi_hid_nkro_report[UDI_HID_NKRO_REPORT_SIZE];
 | 
			
		|||
 | 
			
		||||
COMPILER_PACK_RESET()
 | 
			
		||||
 | 
			
		||||
#endif  // NKRO_ENABLE
 | 
			
		||||
#endif // NKRO_ENABLE
 | 
			
		||||
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
// MOU Descriptor structure and content
 | 
			
		||||
| 
						 | 
				
			
			@ -449,7 +449,7 @@ typedef struct {
 | 
			
		|||
} udi_hid_mou_desc_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t array[77];  // MOU PDS
 | 
			
		||||
    uint8_t array[77]; // MOU PDS
 | 
			
		||||
} udi_hid_mou_report_desc_t;
 | 
			
		||||
 | 
			
		||||
// clang-format off
 | 
			
		||||
| 
						 | 
				
			
			@ -488,12 +488,12 @@ typedef struct {
 | 
			
		|||
// clang-format on
 | 
			
		||||
 | 
			
		||||
// report buffer
 | 
			
		||||
#    define UDI_HID_MOU_REPORT_SIZE 5  // MOU PDS
 | 
			
		||||
#    define UDI_HID_MOU_REPORT_SIZE 5 // MOU PDS
 | 
			
		||||
extern uint8_t udi_hid_mou_report[UDI_HID_MOU_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
COMPILER_PACK_RESET()
 | 
			
		||||
 | 
			
		||||
#endif  // MOUSE_ENABLE
 | 
			
		||||
#endif // MOUSE_ENABLE
 | 
			
		||||
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
// RAW Descriptor structure and content
 | 
			
		||||
| 
						 | 
				
			
			@ -565,7 +565,7 @@ extern uint8_t udi_hid_raw_report[UDI_HID_RAW_REPORT_SIZE];
 | 
			
		|||
 | 
			
		||||
COMPILER_PACK_RESET()
 | 
			
		||||
 | 
			
		||||
#endif  // RAW_ENABLE
 | 
			
		||||
#endif // RAW_ENABLE
 | 
			
		||||
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
// CON Descriptor structure and content
 | 
			
		||||
| 
						 | 
				
			
			@ -637,7 +637,7 @@ extern uint8_t udi_hid_con_report[UDI_HID_CON_REPORT_SIZE];
 | 
			
		|||
 | 
			
		||||
COMPILER_PACK_RESET()
 | 
			
		||||
 | 
			
		||||
#endif  // CONSOLE_ENABLE
 | 
			
		||||
#endif // CONSOLE_ENABLE
 | 
			
		||||
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
// CDC Descriptor structure and content
 | 
			
		||||
| 
						 | 
				
			
			@ -780,7 +780,7 @@ typedef struct {
 | 
			
		|||
 | 
			
		||||
COMPILER_PACK_RESET()
 | 
			
		||||
 | 
			
		||||
#endif  // VIRTSER_ENABLE
 | 
			
		||||
#endif // VIRTSER_ENABLE
 | 
			
		||||
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
// CONFIGURATION Descriptor structure and content
 | 
			
		||||
| 
						 | 
				
			
			@ -815,4 +815,4 @@ typedef struct {
 | 
			
		|||
 | 
			
		||||
COMPILER_PACK_RESET()
 | 
			
		||||
 | 
			
		||||
#endif  //_UDI_DEVICE_CONF_H_
 | 
			
		||||
#endif //_UDI_DEVICE_CONF_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,4 +28,4 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#define CDC_NOTIFICATION_EPSIZE 8
 | 
			
		||||
#define CDC_EPSIZE 16
 | 
			
		||||
 | 
			
		||||
#endif  //_UDI_DEVICE_EPSIZE_H_
 | 
			
		||||
#endif //_UDI_DEVICE_EPSIZE_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -110,7 +110,7 @@ bool udi_hid_setup(uint8_t *rate, uint8_t *protocol, uint8_t *report_desc, bool
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return false;  // Request not supported
 | 
			
		||||
    return false; // Request not supported
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//---------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,4 +82,4 @@ bool udi_hid_setup(uint8_t *rate, uint8_t *protocol, uint8_t *report_desc, bool
 | 
			
		|||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif  // _UDI_HID_H_
 | 
			
		||||
#endif // _UDI_HID_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -94,42 +94,42 @@ static uint8_t udi_hid_kbd_report_trans[UDI_HID_KBD_REPORT_SIZE];
 | 
			
		|||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
UDC_DESC_STORAGE udi_hid_kbd_report_desc_t udi_hid_kbd_report_desc = {{
 | 
			
		||||
    0x05, 0x01,  // Usage Page (Generic Desktop)
 | 
			
		||||
    0x09, 0x06,  // Usage (Keyboard)
 | 
			
		||||
    0xA1, 0x01,  // Collection (Application)
 | 
			
		||||
    0x05, 0x01, // Usage Page (Generic Desktop)
 | 
			
		||||
    0x09, 0x06, // Usage (Keyboard)
 | 
			
		||||
    0xA1, 0x01, // Collection (Application)
 | 
			
		||||
    // Modifiers (8 bits)
 | 
			
		||||
    0x05, 0x07,  //   Usage Page (Keyboard)
 | 
			
		||||
    0x19, 0xE0,  //   Usage Minimum (Keyboard Left Control)
 | 
			
		||||
    0x29, 0xE7,  //   Usage Maximum (Keyboard Right GUI)
 | 
			
		||||
    0x15, 0x00,  //   Logical Minimum (0)
 | 
			
		||||
    0x25, 0x01,  //   Logical Maximum (1)
 | 
			
		||||
    0x95, 0x08,  //   Report Count (8)
 | 
			
		||||
    0x75, 0x01,  //   Report Size (1)
 | 
			
		||||
    0x81, 0x02,  //   Input (Data, Variable, Absolute)
 | 
			
		||||
    0x05, 0x07, //   Usage Page (Keyboard)
 | 
			
		||||
    0x19, 0xE0, //   Usage Minimum (Keyboard Left Control)
 | 
			
		||||
    0x29, 0xE7, //   Usage Maximum (Keyboard Right GUI)
 | 
			
		||||
    0x15, 0x00, //   Logical Minimum (0)
 | 
			
		||||
    0x25, 0x01, //   Logical Maximum (1)
 | 
			
		||||
    0x95, 0x08, //   Report Count (8)
 | 
			
		||||
    0x75, 0x01, //   Report Size (1)
 | 
			
		||||
    0x81, 0x02, //   Input (Data, Variable, Absolute)
 | 
			
		||||
    // Reserved (1 byte)
 | 
			
		||||
    0x81, 0x01,  //   Input (Constant)
 | 
			
		||||
    0x81, 0x01, //   Input (Constant)
 | 
			
		||||
    // Keycodes (6 bytes)
 | 
			
		||||
    0x19, 0x00,  //   Usage Minimum (0)
 | 
			
		||||
    0x29, 0xFF,  //   Usage Maximum (255)
 | 
			
		||||
    0x15, 0x00,  //   Logical Minimum (0)
 | 
			
		||||
    0x25, 0xFF,  //   Logical Maximum (255)
 | 
			
		||||
    0x95, 0x06,  //   Report Count (6)
 | 
			
		||||
    0x75, 0x08,  //   Report Size (8)
 | 
			
		||||
    0x81, 0x00,  //   Input (Data, Array, Absolute)
 | 
			
		||||
    0x19, 0x00, //   Usage Minimum (0)
 | 
			
		||||
    0x29, 0xFF, //   Usage Maximum (255)
 | 
			
		||||
    0x15, 0x00, //   Logical Minimum (0)
 | 
			
		||||
    0x25, 0xFF, //   Logical Maximum (255)
 | 
			
		||||
    0x95, 0x06, //   Report Count (6)
 | 
			
		||||
    0x75, 0x08, //   Report Size (8)
 | 
			
		||||
    0x81, 0x00, //   Input (Data, Array, Absolute)
 | 
			
		||||
 | 
			
		||||
    // Status LEDs (5 bits)
 | 
			
		||||
    0x05, 0x08,  //   Usage Page (LED)
 | 
			
		||||
    0x19, 0x01,  //   Usage Minimum (Num Lock)
 | 
			
		||||
    0x29, 0x05,  //   Usage Maximum (Kana)
 | 
			
		||||
    0x15, 0x00,  //   Logical Minimum (0)
 | 
			
		||||
    0x25, 0x01,  //   Logical Maximum (1)
 | 
			
		||||
    0x95, 0x05,  //   Report Count (5)
 | 
			
		||||
    0x75, 0x01,  //   Report Size (1)
 | 
			
		||||
    0x91, 0x02,  //   Output (Data, Variable, Absolute)
 | 
			
		||||
    0x05, 0x08, //   Usage Page (LED)
 | 
			
		||||
    0x19, 0x01, //   Usage Minimum (Num Lock)
 | 
			
		||||
    0x29, 0x05, //   Usage Maximum (Kana)
 | 
			
		||||
    0x15, 0x00, //   Logical Minimum (0)
 | 
			
		||||
    0x25, 0x01, //   Logical Maximum (1)
 | 
			
		||||
    0x95, 0x05, //   Report Count (5)
 | 
			
		||||
    0x75, 0x01, //   Report Size (1)
 | 
			
		||||
    0x91, 0x02, //   Output (Data, Variable, Absolute)
 | 
			
		||||
    // LED padding (3 bits)
 | 
			
		||||
    0x95, 0x03,  //   Report Count (3)
 | 
			
		||||
    0x91, 0x01,  //   Output (Constant)
 | 
			
		||||
    0xC0         // End Collection
 | 
			
		||||
    0x95, 0x03, //   Report Count (3)
 | 
			
		||||
    0x91, 0x01, //   Output (Constant)
 | 
			
		||||
    0xC0        // End Collection
 | 
			
		||||
}};
 | 
			
		||||
 | 
			
		||||
static bool udi_hid_kbd_setreport(void);
 | 
			
		||||
| 
						 | 
				
			
			@ -148,11 +148,17 @@ bool udi_hid_kbd_enable(void) {
 | 
			
		|||
    return UDI_HID_KBD_ENABLE_EXT();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udi_hid_kbd_disable(void) { UDI_HID_KBD_DISABLE_EXT(); }
 | 
			
		||||
void udi_hid_kbd_disable(void) {
 | 
			
		||||
    UDI_HID_KBD_DISABLE_EXT();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool udi_hid_kbd_setup(void) { return udi_hid_setup(&udi_hid_kbd_rate, &udi_hid_kbd_protocol, (uint8_t *)&udi_hid_kbd_report_desc, udi_hid_kbd_setreport); }
 | 
			
		||||
bool udi_hid_kbd_setup(void) {
 | 
			
		||||
    return udi_hid_setup(&udi_hid_kbd_rate, &udi_hid_kbd_protocol, (uint8_t *)&udi_hid_kbd_report_desc, udi_hid_kbd_setreport);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t udi_hid_kbd_getsetting(void) { return 0; }
 | 
			
		||||
uint8_t udi_hid_kbd_getsetting(void) {
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool udi_hid_kbd_setreport(void) {
 | 
			
		||||
    if ((USB_HID_REPORT_TYPE_OUTPUT == (udd_g_ctrlreq.req.wValue >> 8)) && (0 == (0xFF & udd_g_ctrlreq.req.wValue)) && (1 == udd_g_ctrlreq.req.wLength)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -234,41 +240,41 @@ static uint8_t udi_hid_nkro_report_trans[UDI_HID_NKRO_REPORT_SIZE];
 | 
			
		|||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
UDC_DESC_STORAGE udi_hid_nkro_report_desc_t udi_hid_nkro_report_desc = {{
 | 
			
		||||
    0x05, 0x01,  // Usage Page (Generic Desktop)
 | 
			
		||||
    0x09, 0x06,  // Usage (Keyboard)
 | 
			
		||||
    0xA1, 0x01,  // Collection (Application)
 | 
			
		||||
    0x05, 0x01, // Usage Page (Generic Desktop)
 | 
			
		||||
    0x09, 0x06, // Usage (Keyboard)
 | 
			
		||||
    0xA1, 0x01, // Collection (Application)
 | 
			
		||||
 | 
			
		||||
    // Modifiers (8 bits)
 | 
			
		||||
    0x05, 0x07,  //   Usage Page (Keyboard/Keypad)
 | 
			
		||||
    0x19, 0xE0,  //   Usage Minimum (Keyboard Left Control)
 | 
			
		||||
    0x29, 0xE7,  //   Usage Maximum (Keyboard Right GUI)
 | 
			
		||||
    0x15, 0x00,  //   Logical Minimum (0)
 | 
			
		||||
    0x25, 0x01,  //   Logical Maximum (1)
 | 
			
		||||
    0x95, 0x08,  //   Report Count (8)
 | 
			
		||||
    0x75, 0x01,  //   Report Size (1)
 | 
			
		||||
    0x81, 0x02,  //   Input (Data, Variable, Absolute)
 | 
			
		||||
    0x05, 0x07, //   Usage Page (Keyboard/Keypad)
 | 
			
		||||
    0x19, 0xE0, //   Usage Minimum (Keyboard Left Control)
 | 
			
		||||
    0x29, 0xE7, //   Usage Maximum (Keyboard Right GUI)
 | 
			
		||||
    0x15, 0x00, //   Logical Minimum (0)
 | 
			
		||||
    0x25, 0x01, //   Logical Maximum (1)
 | 
			
		||||
    0x95, 0x08, //   Report Count (8)
 | 
			
		||||
    0x75, 0x01, //   Report Size (1)
 | 
			
		||||
    0x81, 0x02, //   Input (Data, Variable, Absolute)
 | 
			
		||||
    // Keycodes
 | 
			
		||||
    0x05, 0x07,  //   Usage Page (Keyboard/Keypad)
 | 
			
		||||
    0x19, 0x00,  //   Usage Minimum (0)
 | 
			
		||||
    0x29, 0xF7,  //   Usage Maximum (247)
 | 
			
		||||
    0x15, 0x00,  //   Logical Minimum (0)
 | 
			
		||||
    0x25, 0x01,  //   Logical Maximum (1)
 | 
			
		||||
    0x95, 0xF8,  //   Report Count (248)
 | 
			
		||||
    0x75, 0x01,  //   Report Size (1)
 | 
			
		||||
    0x81, 0x02,  //   Input (Data, Variable, Absolute, Bitfield)
 | 
			
		||||
    0x05, 0x07, //   Usage Page (Keyboard/Keypad)
 | 
			
		||||
    0x19, 0x00, //   Usage Minimum (0)
 | 
			
		||||
    0x29, 0xF7, //   Usage Maximum (247)
 | 
			
		||||
    0x15, 0x00, //   Logical Minimum (0)
 | 
			
		||||
    0x25, 0x01, //   Logical Maximum (1)
 | 
			
		||||
    0x95, 0xF8, //   Report Count (248)
 | 
			
		||||
    0x75, 0x01, //   Report Size (1)
 | 
			
		||||
    0x81, 0x02, //   Input (Data, Variable, Absolute, Bitfield)
 | 
			
		||||
 | 
			
		||||
    // Status LEDs (5 bits)
 | 
			
		||||
    0x05, 0x08,  //   Usage Page (LED)
 | 
			
		||||
    0x19, 0x01,  //   Usage Minimum (Num Lock)
 | 
			
		||||
    0x29, 0x05,  //   Usage Maximum (Kana)
 | 
			
		||||
    0x95, 0x05,  //   Report Count (5)
 | 
			
		||||
    0x75, 0x01,  //   Report Size (1)
 | 
			
		||||
    0x91, 0x02,  //   Output (Data, Variable, Absolute)
 | 
			
		||||
    0x05, 0x08, //   Usage Page (LED)
 | 
			
		||||
    0x19, 0x01, //   Usage Minimum (Num Lock)
 | 
			
		||||
    0x29, 0x05, //   Usage Maximum (Kana)
 | 
			
		||||
    0x95, 0x05, //   Report Count (5)
 | 
			
		||||
    0x75, 0x01, //   Report Size (1)
 | 
			
		||||
    0x91, 0x02, //   Output (Data, Variable, Absolute)
 | 
			
		||||
    // LED padding (3 bits)
 | 
			
		||||
    0x95, 0x01,  //   Report Count (1)
 | 
			
		||||
    0x75, 0x03,  //   Report Size (3)
 | 
			
		||||
    0x91, 0x03,  //   Output (Constant)
 | 
			
		||||
    0xC0         // End Collection
 | 
			
		||||
    0x95, 0x01, //   Report Count (1)
 | 
			
		||||
    0x75, 0x03, //   Report Size (3)
 | 
			
		||||
    0x91, 0x03, //   Output (Constant)
 | 
			
		||||
    0xC0        // End Collection
 | 
			
		||||
}};
 | 
			
		||||
 | 
			
		||||
static bool udi_hid_nkro_setreport(void);
 | 
			
		||||
| 
						 | 
				
			
			@ -285,18 +291,24 @@ bool udi_hid_nkro_enable(void) {
 | 
			
		|||
    return UDI_HID_NKRO_ENABLE_EXT();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udi_hid_nkro_disable(void) { UDI_HID_NKRO_DISABLE_EXT(); }
 | 
			
		||||
void udi_hid_nkro_disable(void) {
 | 
			
		||||
    UDI_HID_NKRO_DISABLE_EXT();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool udi_hid_nkro_setup(void) { return udi_hid_setup(&udi_hid_nkro_rate, &udi_hid_nkro_protocol, (uint8_t *)&udi_hid_nkro_report_desc, udi_hid_nkro_setreport); }
 | 
			
		||||
bool udi_hid_nkro_setup(void) {
 | 
			
		||||
    return udi_hid_setup(&udi_hid_nkro_rate, &udi_hid_nkro_protocol, (uint8_t *)&udi_hid_nkro_report_desc, udi_hid_nkro_setreport);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t udi_hid_nkro_getsetting(void) { return 0; }
 | 
			
		||||
uint8_t udi_hid_nkro_getsetting(void) {
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// keyboard receives LED report here
 | 
			
		||||
static bool udi_hid_nkro_setreport(void) {
 | 
			
		||||
    if ((USB_HID_REPORT_TYPE_OUTPUT == (udd_g_ctrlreq.req.wValue >> 8)) && (0 == (0xFF & udd_g_ctrlreq.req.wValue)) && (1 == udd_g_ctrlreq.req.wLength)) {
 | 
			
		||||
        // Report OUT type on report ID 0 from USB Host
 | 
			
		||||
        udd_g_ctrlreq.payload      = &udi_hid_nkro_report_set;
 | 
			
		||||
        udd_g_ctrlreq.callback     = udi_hid_nkro_setreport_valid;  // must call routine to transform setreport to LED state
 | 
			
		||||
        udd_g_ctrlreq.callback     = udi_hid_nkro_setreport_valid; // must call routine to transform setreport to LED state
 | 
			
		||||
        udd_g_ctrlreq.payload_size = 1;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -333,7 +345,7 @@ static void udi_hid_nkro_setreport_valid(void) {
 | 
			
		|||
    // UDI_HID_NKRO_CHANGE_LED(udi_hid_nkro_report_set);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif  // NKRO_ENABLE
 | 
			
		||||
#endif // NKRO_ENABLE
 | 
			
		||||
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
// EXK (extra-keys) SYS-CTRL  Keyboard
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -71,7 +71,7 @@ extern UDC_DESC_STORAGE udi_api_t udi_api_hid_nkro;
 | 
			
		|||
extern bool                       udi_hid_nkro_b_report_valid;
 | 
			
		||||
extern volatile bool              udi_hid_nkro_b_report_trans_ongoing;
 | 
			
		||||
bool                              udi_hid_nkro_send_report(void);
 | 
			
		||||
#endif  // NKRO_ENABLE
 | 
			
		||||
#endif // NKRO_ENABLE
 | 
			
		||||
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
// SYS-CTRL interface
 | 
			
		||||
| 
						 | 
				
			
			@ -81,7 +81,7 @@ extern UDC_DESC_STORAGE udi_api_t udi_api_hid_exk;
 | 
			
		|||
extern bool                       udi_hid_exk_b_report_valid;
 | 
			
		||||
extern uint8_t                    udi_hid_exk_report_set;
 | 
			
		||||
bool                              udi_hid_exk_send_report(void);
 | 
			
		||||
#endif  // EXTRAKEY_ENABLE
 | 
			
		||||
#endif // EXTRAKEY_ENABLE
 | 
			
		||||
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
// CON Console
 | 
			
		||||
| 
						 | 
				
			
			@ -92,7 +92,7 @@ extern bool                       udi_hid_con_b_report_valid;
 | 
			
		|||
extern uint8_t                    udi_hid_con_report_set[UDI_HID_CON_REPORT_SIZE];
 | 
			
		||||
extern volatile bool              udi_hid_con_b_report_trans_ongoing;
 | 
			
		||||
bool                              udi_hid_con_send_report(void);
 | 
			
		||||
#endif  // CONSOLE_ENABLE
 | 
			
		||||
#endif // CONSOLE_ENABLE
 | 
			
		||||
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
// MOU Mouse
 | 
			
		||||
| 
						 | 
				
			
			@ -101,7 +101,7 @@ bool                              udi_hid_con_send_report(void);
 | 
			
		|||
extern UDC_DESC_STORAGE udi_api_t udi_api_hid_mou;
 | 
			
		||||
extern bool                       udi_hid_mou_b_report_valid;
 | 
			
		||||
bool                              udi_hid_mou_send_report(void);
 | 
			
		||||
#endif  // MOUSE_ENABLE
 | 
			
		||||
#endif // MOUSE_ENABLE
 | 
			
		||||
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
// RAW Raw
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +110,7 @@ bool                              udi_hid_mou_send_report(void);
 | 
			
		|||
extern UDC_DESC_STORAGE udi_api_t udi_api_hid_raw;
 | 
			
		||||
bool                              udi_hid_raw_send_report(void);
 | 
			
		||||
bool                              udi_hid_raw_receive_report(void);
 | 
			
		||||
#endif  // RAW_ENABLE
 | 
			
		||||
#endif // RAW_ENABLE
 | 
			
		||||
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -118,4 +118,4 @@ bool                              udi_hid_raw_receive_report(void);
 | 
			
		|||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // _UDC_HID_KBD_H_
 | 
			
		||||
#endif // _UDC_HID_KBD_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,4 +57,4 @@
 | 
			
		|||
 | 
			
		||||
#include "udi_hid_kbd.h"
 | 
			
		||||
 | 
			
		||||
#endif  // _UDI_HID_KBD_CONF_H_
 | 
			
		||||
#endif // _UDI_HID_KBD_CONF_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -78,17 +78,17 @@ UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = {.bLength         = sizeof(usb
 | 
			
		|||
#ifdef USB_DEVICE_MANUFACTURE_NAME
 | 
			
		||||
                                                   .iManufacturer = 1,
 | 
			
		||||
#else
 | 
			
		||||
                                                   .iManufacturer = 0,  // No manufacture string
 | 
			
		||||
                                                   .iManufacturer = 0, // No manufacture string
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef USB_DEVICE_PRODUCT_NAME
 | 
			
		||||
                                                   .iProduct = 2,
 | 
			
		||||
#else
 | 
			
		||||
                                                   .iProduct      = 0,  // No product string
 | 
			
		||||
                                                   .iProduct      = 0, // No product string
 | 
			
		||||
#endif
 | 
			
		||||
#if (defined USB_DEVICE_SERIAL_NAME || defined USB_DEVICE_GET_SERIAL_NAME_POINTER)
 | 
			
		||||
                                                   .iSerialNumber = 3,
 | 
			
		||||
#else
 | 
			
		||||
                                                   .iSerialNumber = 0,  // No serial string
 | 
			
		||||
                                                   .iSerialNumber = 0, // No serial string
 | 
			
		||||
#endif
 | 
			
		||||
                                                   .bNumConfigurations = 1};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,7 +48,7 @@
 | 
			
		|||
#    define ARM_MATH_CM4
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#undef LITTLE_ENDIAN  // redefined in samd51j18a.h
 | 
			
		||||
#undef LITTLE_ENDIAN // redefined in samd51j18a.h
 | 
			
		||||
#include "samd51j18a.h"
 | 
			
		||||
#include "ui.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,4 +73,4 @@ void ui_process(uint16_t framenumber);
 | 
			
		|||
 */
 | 
			
		||||
void ui_kbd_led(uint8_t value);
 | 
			
		||||
 | 
			
		||||
#endif  // _UI_H_
 | 
			
		||||
#endif // _UI_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,7 +52,7 @@
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#include "compiler.h"
 | 
			
		||||
#undef LITTLE_ENDIAN  // redefined in samd51j18a.h
 | 
			
		||||
#undef LITTLE_ENDIAN // redefined in samd51j18a.h
 | 
			
		||||
#include "samd51j18a.h"
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -319,7 +319,7 @@ enum status_code usb_device_endpoint_enable_callback(struct usb_module *module_i
 | 
			
		|||
    module_inst->device_endpoint_enabled_callback_mask[ep_num] |= _usb_endpoint_irq_bits[callback_type];
 | 
			
		||||
 | 
			
		||||
    if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_TRCPT) {
 | 
			
		||||
        if (ep_num == 0) {  // control endpoint
 | 
			
		||||
        if (ep_num == 0) { // control endpoint
 | 
			
		||||
            module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRCPT0 | USB_DEVICE_EPINTENSET_TRCPT1;
 | 
			
		||||
        } else if (ep & USB_EP_DIR_IN) {
 | 
			
		||||
            module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRCPT1;
 | 
			
		||||
| 
						 | 
				
			
			@ -329,7 +329,7 @@ enum status_code usb_device_endpoint_enable_callback(struct usb_module *module_i
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_TRFAIL) {
 | 
			
		||||
        if (ep_num == 0) {  // control endpoint
 | 
			
		||||
        if (ep_num == 0) { // control endpoint
 | 
			
		||||
            module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRFAIL0 | USB_DEVICE_EPINTENSET_TRFAIL1;
 | 
			
		||||
        } else if (ep & USB_EP_DIR_IN) {
 | 
			
		||||
            module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRFAIL1;
 | 
			
		||||
| 
						 | 
				
			
			@ -377,7 +377,7 @@ enum status_code usb_device_endpoint_disable_callback(struct usb_module *module_
 | 
			
		|||
    module_inst->device_endpoint_enabled_callback_mask[ep_num] &= ~_usb_endpoint_irq_bits[callback_type];
 | 
			
		||||
 | 
			
		||||
    if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_TRCPT) {
 | 
			
		||||
        if (ep_num == 0) {  // control endpoint
 | 
			
		||||
        if (ep_num == 0) { // control endpoint
 | 
			
		||||
            module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRCPT0 | USB_DEVICE_EPINTENCLR_TRCPT1;
 | 
			
		||||
        } else if (ep & USB_EP_DIR_IN) {
 | 
			
		||||
            module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRCPT1;
 | 
			
		||||
| 
						 | 
				
			
			@ -387,7 +387,7 @@ enum status_code usb_device_endpoint_disable_callback(struct usb_module *module_
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_TRFAIL) {
 | 
			
		||||
        if (ep_num == 0) {  // control endpoint
 | 
			
		||||
        if (ep_num == 0) { // control endpoint
 | 
			
		||||
            module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRFAIL0 | USB_DEVICE_EPINTENCLR_TRFAIL1;
 | 
			
		||||
        } else if (ep & USB_EP_DIR_IN) {
 | 
			
		||||
            module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRFAIL1;
 | 
			
		||||
| 
						 | 
				
			
			@ -903,11 +903,17 @@ void USB_0_Handler(void) {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void USB_1_Handler(void) { _usb_device_interrupt_handler(); }
 | 
			
		||||
void USB_1_Handler(void) {
 | 
			
		||||
    _usb_device_interrupt_handler();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void USB_2_Handler(void) { _usb_device_interrupt_handler(); }
 | 
			
		||||
void USB_2_Handler(void) {
 | 
			
		||||
    _usb_device_interrupt_handler();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void USB_3_Handler(void) { _usb_device_interrupt_handler(); }
 | 
			
		||||
void USB_3_Handler(void) {
 | 
			
		||||
    _usb_device_interrupt_handler();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Get the default USB module settings
 | 
			
		||||
| 
						 | 
				
			
			@ -974,10 +980,10 @@ enum status_code usb_init(struct usb_module *module_inst, Usb *const hw, struct
 | 
			
		|||
    pmclk->APBBMASK.bit.USB_ = 1;
 | 
			
		||||
 | 
			
		||||
    /* Set up the USB DP/DN pins */
 | 
			
		||||
    pport->Group[0].PMUX[12].reg          = 0x77;  // PA24, PA25, function column H for USB D-, D+
 | 
			
		||||
    pport->Group[0].PMUX[12].reg          = 0x77; // PA24, PA25, function column H for USB D-, D+
 | 
			
		||||
    pport->Group[0].PINCFG[24].bit.PMUXEN = 1;
 | 
			
		||||
    pport->Group[0].PINCFG[25].bit.PMUXEN = 1;
 | 
			
		||||
    pport->Group[1].PMUX[11].bit.PMUXE    = 7;  // PB22, function column H for USB SOF_1KHz output
 | 
			
		||||
    pport->Group[1].PMUX[11].bit.PMUXE    = 7; // PB22, function column H for USB SOF_1KHz output
 | 
			
		||||
    pport->Group[1].PINCFG[22].bit.PMUXEN = 1;
 | 
			
		||||
 | 
			
		||||
    // configure and enable DFLL for USB clock recovery mode at 48MHz
 | 
			
		||||
| 
						 | 
				
			
			@ -996,7 +1002,7 @@ enum status_code usb_init(struct usb_module *module_inst, Usb *const hw, struct
 | 
			
		|||
    while (posc->DFLLSYNC.bit.DFLLCTRLB)
 | 
			
		||||
        ;
 | 
			
		||||
    posc->DFLLCTRLB.bit.CCDIS = 1;
 | 
			
		||||
    posc->DFLLMUL.bit.MUL     = 0xbb80;  // 4800 x 1KHz
 | 
			
		||||
    posc->DFLLMUL.bit.MUL     = 0xbb80; // 4800 x 1KHz
 | 
			
		||||
    while (posc->DFLLSYNC.bit.DFLLMUL)
 | 
			
		||||
        ;
 | 
			
		||||
    posc->DFLLCTRLA.bit.ENABLE = 1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -319,14 +319,18 @@ enum status_code usb_init(struct usb_module *module_inst, Usb *const hw, struct
 | 
			
		|||
 *
 | 
			
		||||
 * \param module_inst Pointer to USB device module instance
 | 
			
		||||
 */
 | 
			
		||||
static inline void usb_device_attach(struct usb_module *module_inst) { module_inst->hw->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_DETACH; }
 | 
			
		||||
static inline void usb_device_attach(struct usb_module *module_inst) {
 | 
			
		||||
    module_inst->hw->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_DETACH;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Detach USB device from the bus
 | 
			
		||||
 *
 | 
			
		||||
 * \param module_inst Pointer to USB device module instance
 | 
			
		||||
 */
 | 
			
		||||
static inline void usb_device_detach(struct usb_module *module_inst) { module_inst->hw->DEVICE.CTRLB.reg |= USB_DEVICE_CTRLB_DETACH; }
 | 
			
		||||
static inline void usb_device_detach(struct usb_module *module_inst) {
 | 
			
		||||
    module_inst->hw->DEVICE.CTRLB.reg |= USB_DEVICE_CTRLB_DETACH;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Get the speed mode of USB device
 | 
			
		||||
| 
						 | 
				
			
			@ -348,7 +352,9 @@ static inline enum usb_speed usb_device_get_speed(struct usb_module *module_inst
 | 
			
		|||
 * \param module_inst Pointer to USB device module instance
 | 
			
		||||
 * \return USB device address value.
 | 
			
		||||
 */
 | 
			
		||||
static inline uint8_t usb_device_get_address(struct usb_module *module_inst) { return ((uint8_t)(module_inst->hw->DEVICE.DADD.bit.DADD)); }
 | 
			
		||||
static inline uint8_t usb_device_get_address(struct usb_module *module_inst) {
 | 
			
		||||
    return ((uint8_t)(module_inst->hw->DEVICE.DADD.bit.DADD));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Set the speed mode of USB device
 | 
			
		||||
| 
						 | 
				
			
			@ -356,7 +362,9 @@ static inline uint8_t usb_device_get_address(struct usb_module *module_inst) { r
 | 
			
		|||
 * \param module_inst Pointer to USB device module instance
 | 
			
		||||
 * \param address     USB device address value
 | 
			
		||||
 */
 | 
			
		||||
static inline void usb_device_set_address(struct usb_module *module_inst, uint8_t address) { module_inst->hw->DEVICE.DADD.reg = USB_DEVICE_DADD_ADDEN | address; }
 | 
			
		||||
static inline void usb_device_set_address(struct usb_module *module_inst, uint8_t address) {
 | 
			
		||||
    module_inst->hw->DEVICE.DADD.reg = USB_DEVICE_DADD_ADDEN | address;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Get the frame number of USB device
 | 
			
		||||
| 
						 | 
				
			
			@ -364,7 +372,9 @@ static inline void usb_device_set_address(struct usb_module *module_inst, uint8_
 | 
			
		|||
 * \param module_inst Pointer to USB device module instance
 | 
			
		||||
 * \return USB device frame number value.
 | 
			
		||||
 */
 | 
			
		||||
static inline uint16_t usb_device_get_frame_number(struct usb_module *module_inst) { return ((uint16_t)(module_inst->hw->DEVICE.FNUM.bit.FNUM)); }
 | 
			
		||||
static inline uint16_t usb_device_get_frame_number(struct usb_module *module_inst) {
 | 
			
		||||
    return ((uint16_t)(module_inst->hw->DEVICE.FNUM.bit.FNUM));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Get the micro-frame number of USB device
 | 
			
		||||
| 
						 | 
				
			
			@ -372,14 +382,18 @@ static inline uint16_t usb_device_get_frame_number(struct usb_module *module_ins
 | 
			
		|||
 * \param module_inst Pointer to USB device module instance
 | 
			
		||||
 * \return USB device micro-frame number value.
 | 
			
		||||
 */
 | 
			
		||||
static inline uint16_t usb_device_get_micro_frame_number(struct usb_module *module_inst) { return ((uint16_t)(module_inst->hw->DEVICE.FNUM.reg)); }
 | 
			
		||||
static inline uint16_t usb_device_get_micro_frame_number(struct usb_module *module_inst) {
 | 
			
		||||
    return ((uint16_t)(module_inst->hw->DEVICE.FNUM.reg));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief USB device send the resume wakeup
 | 
			
		||||
 *
 | 
			
		||||
 * \param module_inst Pointer to USB device module instance
 | 
			
		||||
 */
 | 
			
		||||
static inline void usb_device_send_remote_wake_up(struct usb_module *module_inst) { module_inst->hw->DEVICE.CTRLB.reg |= USB_DEVICE_CTRLB_UPRSM; }
 | 
			
		||||
static inline void usb_device_send_remote_wake_up(struct usb_module *module_inst) {
 | 
			
		||||
    module_inst->hw->DEVICE.CTRLB.reg |= USB_DEVICE_CTRLB_UPRSM;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief USB device set the LPM mode
 | 
			
		||||
| 
						 | 
				
			
			@ -387,7 +401,9 @@ static inline void usb_device_send_remote_wake_up(struct usb_module *module_inst
 | 
			
		|||
 * \param module_inst Pointer to USB device module instance
 | 
			
		||||
 * \param lpm_mode    LPM mode
 | 
			
		||||
 */
 | 
			
		||||
static inline void usb_device_set_lpm_mode(struct usb_module *module_inst, enum usb_device_lpm_mode lpm_mode) { module_inst->hw->DEVICE.CTRLB.bit.LPMHDSK = lpm_mode; }
 | 
			
		||||
static inline void usb_device_set_lpm_mode(struct usb_module *module_inst, enum usb_device_lpm_mode lpm_mode) {
 | 
			
		||||
    module_inst->hw->DEVICE.CTRLB.bit.LPMHDSK = lpm_mode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \name USB Device Callback Management
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -109,7 +109,7 @@
 | 
			
		|||
#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID_MS 0x2306
 | 
			
		||||
#define USB_PID_ATMEL_UC3_CDC 0x2307
 | 
			
		||||
#define USB_PID_ATMEL_UC3_AUDIO_MICRO 0x2308
 | 
			
		||||
#define USB_PID_ATMEL_UC3_CDC_DEBUG 0x2310  // Virtual Com (debug interface) on EVK11xx
 | 
			
		||||
#define USB_PID_ATMEL_UC3_CDC_DEBUG 0x2310 // Virtual Com (debug interface) on EVK11xx
 | 
			
		||||
#define USB_PID_ATMEL_UC3_AUDIO_SPEAKER_MICRO 0x2311
 | 
			
		||||
#define USB_PID_ATMEL_UC3_CDC_MSC 0x2312
 | 
			
		||||
//! @}
 | 
			
		||||
| 
						 | 
				
			
			@ -186,4 +186,4 @@
 | 
			
		|||
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
#endif  // _USB_ATMEL_H_
 | 
			
		||||
#endif // _USB_ATMEL_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -127,12 +127,12 @@ uint8_t udd_ctrl_buffer[USB_DEVICE_EP_CTRL_SIZE];
 | 
			
		|||
 | 
			
		||||
/** Bit definitions about endpoint control state machine for udd_ep_control_state */
 | 
			
		||||
typedef enum {
 | 
			
		||||
    UDD_EPCTRL_SETUP                  = 0,  //!< Wait a SETUP packet
 | 
			
		||||
    UDD_EPCTRL_DATA_OUT               = 1,  //!< Wait a OUT data packet
 | 
			
		||||
    UDD_EPCTRL_DATA_IN                = 2,  //!< Wait a IN data packet
 | 
			
		||||
    UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP  = 3,  //!< Wait a IN ZLP packet
 | 
			
		||||
    UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP = 4,  //!< Wait a OUT ZLP packet
 | 
			
		||||
    UDD_EPCTRL_STALL_REQ              = 5,  //!< STALL enabled on IN & OUT packet
 | 
			
		||||
    UDD_EPCTRL_SETUP                  = 0, //!< Wait a SETUP packet
 | 
			
		||||
    UDD_EPCTRL_DATA_OUT               = 1, //!< Wait a OUT data packet
 | 
			
		||||
    UDD_EPCTRL_DATA_IN                = 2, //!< Wait a IN data packet
 | 
			
		||||
    UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP  = 3, //!< Wait a IN ZLP packet
 | 
			
		||||
    UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP = 4, //!< Wait a OUT ZLP packet
 | 
			
		||||
    UDD_EPCTRL_STALL_REQ              = 5, //!< STALL enabled on IN & OUT packet
 | 
			
		||||
} udd_ctrl_ep_state_t;
 | 
			
		||||
 | 
			
		||||
/** Global variable to give and record information of the set up request management */
 | 
			
		||||
| 
						 | 
				
			
			@ -363,11 +363,17 @@ void udd_ep_abort(udd_ep_id_t ep) {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool udd_is_high_speed(void) { return false; }
 | 
			
		||||
bool udd_is_high_speed(void) {
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t udd_get_frame_number(void) { return usb_device_get_frame_number(&usb_device); }
 | 
			
		||||
uint16_t udd_get_frame_number(void) {
 | 
			
		||||
    return usb_device_get_frame_number(&usb_device);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t udd_get_micro_frame_number(void) { return usb_device_get_micro_frame_number(&usb_device); }
 | 
			
		||||
uint16_t udd_get_micro_frame_number(void) {
 | 
			
		||||
    return usb_device_get_micro_frame_number(&usb_device);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udd_ep_free(udd_ep_id_t ep) {
 | 
			
		||||
    struct usb_device_endpoint_config config_ep;
 | 
			
		||||
| 
						 | 
				
			
			@ -436,7 +442,9 @@ bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, uint16_t MaxEndpointSize
 | 
			
		|||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool udd_ep_is_halted(udd_ep_id_t ep) { return usb_device_endpoint_is_halted(&usb_device, ep); }
 | 
			
		||||
bool udd_ep_is_halted(udd_ep_id_t ep) {
 | 
			
		||||
    return usb_device_endpoint_is_halted(&usb_device, ep);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool udd_ep_set_halt(udd_ep_id_t ep) {
 | 
			
		||||
    uint8_t ep_num = ep & USB_EP_ADDR_MASK;
 | 
			
		||||
| 
						 | 
				
			
			@ -591,9 +599,13 @@ bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, uint8_t *buf, iram_size_t bu
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udd_set_address(uint8_t address) { usb_device_set_address(&usb_device, address); }
 | 
			
		||||
void udd_set_address(uint8_t address) {
 | 
			
		||||
    usb_device_set_address(&usb_device, address);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t udd_getaddress(void) { return usb_device_get_address(&usb_device); }
 | 
			
		||||
uint8_t udd_getaddress(void) {
 | 
			
		||||
    return usb_device_get_address(&usb_device);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udd_send_remotewakeup(void) {
 | 
			
		||||
    uint32_t try
 | 
			
		||||
| 
						 | 
				
			
			@ -913,7 +925,7 @@ static void _usb_device_lpm_suspend(struct usb_module *module_inst, void *pointe
 | 
			
		|||
    usb_device_enable_callback(&usb_device, USB_DEVICE_CALLBACK_WAKEUP);
 | 
			
		||||
 | 
			
		||||
    //#warning Here the sleep mode must be choose to have a DFLL startup time < bmAttribut.HIRD
 | 
			
		||||
    udd_sleep_mode(UDD_STATE_SUSPEND_LPM);  // Enter in LPM SUSPEND mode
 | 
			
		||||
    udd_sleep_mode(UDD_STATE_SUSPEND_LPM); // Enter in LPM SUSPEND mode
 | 
			
		||||
    if ((*lpm_wakeup_enable)) {
 | 
			
		||||
        UDC_REMOTEWAKEUP_LPM_ENABLE();
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,7 +27,7 @@ uint8_t usb_extra_state;
 | 
			
		|||
uint8_t usb_extra_manual;
 | 
			
		||||
uint8_t usb_gcr_auto;
 | 
			
		||||
 | 
			
		||||
#endif  // MD_BOOTLOADER
 | 
			
		||||
#endif // MD_BOOTLOADER
 | 
			
		||||
 | 
			
		||||
uint16_t adc_extra;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -51,10 +51,10 @@ void USB_Hub_init(void) {
 | 
			
		|||
    pmclk->APBBMASK.bit.USB_    = 1;
 | 
			
		||||
 | 
			
		||||
    // setup port pins for D-, D+, and SOF_1KHZ
 | 
			
		||||
    pport->Group[0].PMUX[12].reg          = 0x77;  // PA24, PA25, function column H for USB D-, D+
 | 
			
		||||
    pport->Group[0].PMUX[12].reg          = 0x77; // PA24, PA25, function column H for USB D-, D+
 | 
			
		||||
    pport->Group[0].PINCFG[24].bit.PMUXEN = 1;
 | 
			
		||||
    pport->Group[0].PINCFG[25].bit.PMUXEN = 1;
 | 
			
		||||
    pport->Group[1].PMUX[11].bit.PMUXE    = 7;  // PB22, function column H for USB SOF_1KHz output
 | 
			
		||||
    pport->Group[1].PMUX[11].bit.PMUXE    = 7; // PB22, function column H for USB SOF_1KHz output
 | 
			
		||||
    pport->Group[1].PINCFG[22].bit.PMUXEN = 1;
 | 
			
		||||
 | 
			
		||||
    // configure and enable DFLL for USB clock recovery mode at 48MHz
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +78,7 @@ void USB_Hub_init(void) {
 | 
			
		|||
        DBGC(DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_4);
 | 
			
		||||
    }
 | 
			
		||||
    posc->DFLLCTRLB.bit.CCDIS = 1;
 | 
			
		||||
    posc->DFLLMUL.bit.MUL     = 0xBB80;  // 4800 x 1KHz
 | 
			
		||||
    posc->DFLLMUL.bit.MUL     = 0xBB80; // 4800 x 1KHz
 | 
			
		||||
    while (posc->DFLLSYNC.bit.DFLLMUL) {
 | 
			
		||||
        DBGC(DC_USB2422_INIT_OSC_SYNC_DFLLMUL);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -99,7 +99,7 @@ void USB_Hub_init(void) {
 | 
			
		|||
    pusb->DEVICE.PADCAL.bit.TRANSP = (USB_FUSES_TRANSP_ADDR >> USB_FUSES_TRANSP_Pos) & USB_FUSES_TRANSP_Msk;
 | 
			
		||||
    pusb->DEVICE.PADCAL.bit.TRIM   = (USB_FUSES_TRIM_ADDR >> USB_FUSES_TRIM_Pos) & USB_FUSES_TRIM_Msk;
 | 
			
		||||
    // device mode, enabled
 | 
			
		||||
    pusb->DEVICE.CTRLB.bit.SPDCONF = 0;  // full speed
 | 
			
		||||
    pusb->DEVICE.CTRLB.bit.SPDCONF = 0; // full speed
 | 
			
		||||
    pusb->DEVICE.CTRLA.bit.MODE    = 0;
 | 
			
		||||
    pusb->DEVICE.CTRLA.bit.ENABLE  = 1;
 | 
			
		||||
    while (pusb->DEVICE.SYNCBUSY.bit.ENABLE) {
 | 
			
		||||
| 
						 | 
				
			
			@ -111,8 +111,8 @@ void USB_Hub_init(void) {
 | 
			
		|||
 | 
			
		||||
    USB2422_init();
 | 
			
		||||
 | 
			
		||||
    sr_exp_data.bit.HUB_CONNECT = 1;  // connect signal
 | 
			
		||||
    sr_exp_data.bit.HUB_RESET_N = 1;  // reset high
 | 
			
		||||
    sr_exp_data.bit.HUB_CONNECT = 1; // connect signal
 | 
			
		||||
    sr_exp_data.bit.HUB_RESET_N = 1; // reset high
 | 
			
		||||
    SR_EXP_WriteData();
 | 
			
		||||
 | 
			
		||||
    wait_us(100);
 | 
			
		||||
| 
						 | 
				
			
			@ -122,7 +122,7 @@ void USB_Hub_init(void) {
 | 
			
		|||
    usb_extra_manual = 0;
 | 
			
		||||
    usb_gcr_auto     = 1;
 | 
			
		||||
 | 
			
		||||
#endif  // MD_BOOTLOADER
 | 
			
		||||
#endif // MD_BOOTLOADER
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_USB2422_INIT_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -131,10 +131,10 @@ void USB_reset(void) {
 | 
			
		|||
    DBGC(DC_USB_RESET_BEGIN);
 | 
			
		||||
 | 
			
		||||
    // pulse reset for at least 1 usec
 | 
			
		||||
    sr_exp_data.bit.HUB_RESET_N = 0;  // reset low
 | 
			
		||||
    sr_exp_data.bit.HUB_RESET_N = 0; // reset low
 | 
			
		||||
    SR_EXP_WriteData();
 | 
			
		||||
    wait_us(2);
 | 
			
		||||
    sr_exp_data.bit.HUB_RESET_N = 1;  // reset high to run
 | 
			
		||||
    sr_exp_data.bit.HUB_RESET_N = 1; // reset high to run
 | 
			
		||||
    SR_EXP_WriteData();
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_USB_RESET_COMPLETE);
 | 
			
		||||
| 
						 | 
				
			
			@ -150,7 +150,9 @@ void USB_configure(void) {
 | 
			
		|||
    DBGC(DC_USB_CONFIGURE_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t USB_active(void) { return USB2422_active(); }
 | 
			
		||||
uint16_t USB_active(void) {
 | 
			
		||||
    return USB2422_active();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void USB_set_host_by_voltage(void) {
 | 
			
		||||
    // UP is upstream device (HOST)
 | 
			
		||||
| 
						 | 
				
			
			@ -162,13 +164,13 @@ void USB_set_host_by_voltage(void) {
 | 
			
		|||
    usb_host_port = USB_HOST_PORT_UNKNOWN;
 | 
			
		||||
#ifndef MD_BOOTLOADER
 | 
			
		||||
    usb_extra_state = USB_EXTRA_STATE_UNKNOWN;
 | 
			
		||||
#endif                             // MD_BOOTLOADER
 | 
			
		||||
    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
 | 
			
		||||
#endif                            // MD_BOOTLOADER
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
    SR_EXP_WriteData();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -185,33 +187,33 @@ void USB_set_host_by_voltage(void) {
 | 
			
		|||
    v_con_2_boot = v_con_2;
 | 
			
		||||
 | 
			
		||||
    if (v_con_1 > v_con_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
 | 
			
		||||
        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
 | 
			
		||||
 | 
			
		||||
        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
 | 
			
		||||
        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
 | 
			
		||||
 | 
			
		||||
        SR_EXP_WriteData();
 | 
			
		||||
 | 
			
		||||
        sr_exp_data.bit.E_UP_N = 0;  // HOST enable
 | 
			
		||||
        sr_exp_data.bit.E_UP_N = 0; // HOST enable
 | 
			
		||||
 | 
			
		||||
        SR_EXP_WriteData();
 | 
			
		||||
 | 
			
		||||
        usb_host_port = USB_HOST_PORT_1;
 | 
			
		||||
    } else {
 | 
			
		||||
        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
 | 
			
		||||
        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
 | 
			
		||||
 | 
			
		||||
        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
 | 
			
		||||
        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
 | 
			
		||||
 | 
			
		||||
        SR_EXP_WriteData();
 | 
			
		||||
 | 
			
		||||
        sr_exp_data.bit.E_UP_N = 0;  // HOST enable
 | 
			
		||||
        sr_exp_data.bit.E_UP_N = 0; // HOST enable
 | 
			
		||||
 | 
			
		||||
        SR_EXP_WriteData();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -220,7 +222,7 @@ void USB_set_host_by_voltage(void) {
 | 
			
		|||
 | 
			
		||||
#ifndef MD_BOOTLOADER
 | 
			
		||||
    usb_extra_state = USB_EXTRA_STATE_DISABLED;
 | 
			
		||||
#endif  // MD_BOOTLOADER
 | 
			
		||||
#endif // MD_BOOTLOADER
 | 
			
		||||
 | 
			
		||||
    USB_reset();
 | 
			
		||||
    USB_configure();
 | 
			
		||||
| 
						 | 
				
			
			@ -241,7 +243,7 @@ uint8_t USB_Hub_Port_Detect_Init(void) {
 | 
			
		|||
    while (!USB_active()) {
 | 
			
		||||
        tmod = timer_read64() % PORT_DETECT_RETRY_INTERVAL;
 | 
			
		||||
 | 
			
		||||
        if (v_con_1 > v_con_2)  // Values updated from USB_set_host_by_voltage();
 | 
			
		||||
        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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -249,7 +251,7 @@ uint8_t USB_Hub_Port_Detect_Init(void) {
 | 
			
		|||
            } else {
 | 
			
		||||
                DBG_LED_OFF;
 | 
			
		||||
            }
 | 
			
		||||
        } else if (v_con_2 > v_con_1)  // Values updated from USB_set_host_by_voltage();
 | 
			
		||||
        } 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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -321,7 +323,7 @@ void USB_HandleExtraDevice(void) {
 | 
			
		|||
        // Detect unplug and reset state to disabled
 | 
			
		||||
        if (adc_extra > USB_EXTRA_ADC_THRESHOLD) usb_extra_state = USB_EXTRA_STATE_DISABLED;
 | 
			
		||||
 | 
			
		||||
        return;  // Return even if unplug detected
 | 
			
		||||
        return; // Return even if unplug detected
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (usb_extra_manual) {
 | 
			
		||||
| 
						 | 
				
			
			@ -337,4 +339,4 @@ void USB_HandleExtraDevice(void) {
 | 
			
		|||
        USB_ExtraSetState(USB_EXTRA_STATE_DISABLED);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif  // MD_BOOTLOADER
 | 
			
		||||
#endif // MD_BOOTLOADER
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,4 +48,4 @@ uint16_t adc_get(uint8_t muxpos);
 | 
			
		|||
void     USB_HandleExtraDevice(void);
 | 
			
		||||
void     USB_ExtraSetState(uint8_t state);
 | 
			
		||||
 | 
			
		||||
#endif  //_USB2422_H_
 | 
			
		||||
#endif //_USB2422_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -71,31 +71,31 @@ void                 main_kbd_disable(void);
 | 
			
		|||
extern volatile bool main_b_nkro_enable;
 | 
			
		||||
bool                 main_nkro_enable(void);
 | 
			
		||||
void                 main_nkro_disable(void);
 | 
			
		||||
#endif  // NKRO_ENABLE
 | 
			
		||||
#endif // NKRO_ENABLE
 | 
			
		||||
 | 
			
		||||
#ifdef EXTRAKEY_ENABLE
 | 
			
		||||
extern volatile bool main_b_exk_enable;
 | 
			
		||||
bool                 main_exk_enable(void);
 | 
			
		||||
void                 main_exk_disable(void);
 | 
			
		||||
#endif  // EXTRAKEY_ENABLE
 | 
			
		||||
#endif // EXTRAKEY_ENABLE
 | 
			
		||||
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
extern volatile bool main_b_con_enable;
 | 
			
		||||
bool                 main_con_enable(void);
 | 
			
		||||
void                 main_con_disable(void);
 | 
			
		||||
#endif  // CONSOLE_ENABLE
 | 
			
		||||
#endif // CONSOLE_ENABLE
 | 
			
		||||
 | 
			
		||||
#ifdef MOUSE_ENABLE
 | 
			
		||||
extern volatile bool main_b_mou_enable;
 | 
			
		||||
bool                 main_mou_enable(void);
 | 
			
		||||
void                 main_mou_disable(void);
 | 
			
		||||
#endif  // MOUSE_ENABLE
 | 
			
		||||
#endif // MOUSE_ENABLE
 | 
			
		||||
 | 
			
		||||
#ifdef RAW_ENABLE
 | 
			
		||||
extern volatile bool main_b_raw_enable;
 | 
			
		||||
bool                 main_raw_enable(void);
 | 
			
		||||
void                 main_raw_disable(void);
 | 
			
		||||
void                 main_raw_receive(uint8_t *buffer, uint8_t len);
 | 
			
		||||
#endif  // RAW_ENABLE
 | 
			
		||||
#endif // RAW_ENABLE
 | 
			
		||||
 | 
			
		||||
#endif  // _MAIN_H_
 | 
			
		||||
#endif // _MAIN_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,8 +63,8 @@
 | 
			
		|||
 */
 | 
			
		||||
 | 
			
		||||
//! Value for field bcdUSB
 | 
			
		||||
#define USB_V2_0 0x0200  //!< USB Specification version 2.00
 | 
			
		||||
#define USB_V2_1 0x0201  //!< USB Specification version 2.01
 | 
			
		||||
#define USB_V2_0 0x0200 //!< USB Specification version 2.00
 | 
			
		||||
#define USB_V2_1 0x0201 //!< USB Specification version 2.01
 | 
			
		||||
 | 
			
		||||
/*! \name Generic definitions (Class, subclass and protocol)
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -85,26 +85,26 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \brief USB request data transfer direction (bmRequestType)
 | 
			
		||||
 */
 | 
			
		||||
#define USB_REQ_DIR_OUT (0 << 7)   //!< Host to device
 | 
			
		||||
#define USB_REQ_DIR_IN (1 << 7)    //!< Device to host
 | 
			
		||||
#define USB_REQ_DIR_MASK (1 << 7)  //!< Mask
 | 
			
		||||
#define USB_REQ_DIR_OUT (0 << 7)  //!< Host to device
 | 
			
		||||
#define USB_REQ_DIR_IN (1 << 7)   //!< Device to host
 | 
			
		||||
#define USB_REQ_DIR_MASK (1 << 7) //!< Mask
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief USB request types (bmRequestType)
 | 
			
		||||
 */
 | 
			
		||||
#define USB_REQ_TYPE_STANDARD (0 << 5)  //!< Standard request
 | 
			
		||||
#define USB_REQ_TYPE_CLASS (1 << 5)     //!< Class-specific request
 | 
			
		||||
#define USB_REQ_TYPE_VENDOR (2 << 5)    //!< Vendor-specific request
 | 
			
		||||
#define USB_REQ_TYPE_MASK (3 << 5)      //!< Mask
 | 
			
		||||
#define USB_REQ_TYPE_STANDARD (0 << 5) //!< Standard request
 | 
			
		||||
#define USB_REQ_TYPE_CLASS (1 << 5)    //!< Class-specific request
 | 
			
		||||
#define USB_REQ_TYPE_VENDOR (2 << 5)   //!< Vendor-specific request
 | 
			
		||||
#define USB_REQ_TYPE_MASK (3 << 5)     //!< Mask
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief USB recipient codes (bmRequestType)
 | 
			
		||||
 */
 | 
			
		||||
#define USB_REQ_RECIP_DEVICE (0 << 0)     //!< Recipient device
 | 
			
		||||
#define USB_REQ_RECIP_INTERFACE (1 << 0)  //!< Recipient interface
 | 
			
		||||
#define USB_REQ_RECIP_ENDPOINT (2 << 0)   //!< Recipient endpoint
 | 
			
		||||
#define USB_REQ_RECIP_OTHER (3 << 0)      //!< Recipient other
 | 
			
		||||
#define USB_REQ_RECIP_MASK (0x1F)         //!< Mask
 | 
			
		||||
#define USB_REQ_RECIP_DEVICE (0 << 0)    //!< Recipient device
 | 
			
		||||
#define USB_REQ_RECIP_INTERFACE (1 << 0) //!< Recipient interface
 | 
			
		||||
#define USB_REQ_RECIP_ENDPOINT (2 << 0)  //!< Recipient endpoint
 | 
			
		||||
#define USB_REQ_RECIP_OTHER (3 << 0)     //!< Recipient other
 | 
			
		||||
#define USB_REQ_RECIP_MASK (0x1F)        //!< Mask
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Standard USB requests (bRequest)
 | 
			
		||||
| 
						 | 
				
			
			@ -149,8 +149,8 @@ enum usb_endpoint_status {
 | 
			
		|||
 * \note valid for SetFeature request.
 | 
			
		||||
 */
 | 
			
		||||
enum usb_device_feature {
 | 
			
		||||
    USB_DEV_FEATURE_REMOTE_WAKEUP         = 1,  //!< Remote wakeup enabled
 | 
			
		||||
    USB_DEV_FEATURE_TEST_MODE             = 2,  //!< USB test mode
 | 
			
		||||
    USB_DEV_FEATURE_REMOTE_WAKEUP         = 1, //!< Remote wakeup enabled
 | 
			
		||||
    USB_DEV_FEATURE_TEST_MODE             = 2, //!< USB test mode
 | 
			
		||||
    USB_DEV_FEATURE_OTG_B_HNP_ENABLE      = 3,
 | 
			
		||||
    USB_DEV_FEATURE_OTG_A_HNP_SUPPORT     = 4,
 | 
			
		||||
    USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT = 5
 | 
			
		||||
| 
						 | 
				
			
			@ -261,7 +261,7 @@ enum usb_ep_type {
 | 
			
		|||
 * \brief Standard USB language IDs for string descriptors
 | 
			
		||||
 */
 | 
			
		||||
enum usb_langid {
 | 
			
		||||
    USB_LANGID_EN_US = 0x0409,  //!< English (United States)
 | 
			
		||||
    USB_LANGID_EN_US = 0x0409, //!< English (United States)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -396,14 +396,14 @@ typedef struct {
 | 
			
		|||
 * \brief Standard USB Interface Association Descriptor structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t bLength;            //!< size of this descriptor in bytes
 | 
			
		||||
    uint8_t bDescriptorType;    //!< INTERFACE descriptor type
 | 
			
		||||
    uint8_t bFirstInterface;    //!< Number of interface
 | 
			
		||||
    uint8_t bInterfaceCount;    //!< value to select alternate setting
 | 
			
		||||
    uint8_t bFunctionClass;     //!< Class code assigned by the USB
 | 
			
		||||
    uint8_t bFunctionSubClass;  //!< Sub-class code assigned by the USB
 | 
			
		||||
    uint8_t bFunctionProtocol;  //!< Protocol code assigned by the USB
 | 
			
		||||
    uint8_t iFunction;          //!< Index of string descriptor
 | 
			
		||||
    uint8_t bLength;           //!< size of this descriptor in bytes
 | 
			
		||||
    uint8_t bDescriptorType;   //!< INTERFACE descriptor type
 | 
			
		||||
    uint8_t bFirstInterface;   //!< Number of interface
 | 
			
		||||
    uint8_t bInterfaceCount;   //!< value to select alternate setting
 | 
			
		||||
    uint8_t bFunctionClass;    //!< Class code assigned by the USB
 | 
			
		||||
    uint8_t bFunctionSubClass; //!< Sub-class code assigned by the USB
 | 
			
		||||
    uint8_t bFunctionProtocol; //!< Protocol code assigned by the USB
 | 
			
		||||
    uint8_t iFunction;         //!< Index of string descriptor
 | 
			
		||||
} usb_association_desc_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -420,25 +420,25 @@ typedef struct {
 | 
			
		|||
    uint8_t bMaxPower;
 | 
			
		||||
} usb_conf_desc_t;
 | 
			
		||||
 | 
			
		||||
#define USB_CONFIG_ATTR_MUST_SET (1 << 7)       //!< Must always be set
 | 
			
		||||
#define USB_CONFIG_ATTR_BUS_POWERED (0 << 6)    //!< Bus-powered
 | 
			
		||||
#define USB_CONFIG_ATTR_SELF_POWERED (1 << 6)   //!< Self-powered
 | 
			
		||||
#define USB_CONFIG_ATTR_REMOTE_WAKEUP (1 << 5)  //!< remote wakeup supported
 | 
			
		||||
#define USB_CONFIG_ATTR_MUST_SET (1 << 7)      //!< Must always be set
 | 
			
		||||
#define USB_CONFIG_ATTR_BUS_POWERED (0 << 6)   //!< Bus-powered
 | 
			
		||||
#define USB_CONFIG_ATTR_SELF_POWERED (1 << 6)  //!< Self-powered
 | 
			
		||||
#define USB_CONFIG_ATTR_REMOTE_WAKEUP (1 << 5) //!< remote wakeup supported
 | 
			
		||||
 | 
			
		||||
#define USB_CONFIG_MAX_POWER(ma) (((ma) + 1) / 2)  //!< Max power in mA
 | 
			
		||||
#define USB_CONFIG_MAX_POWER(ma) (((ma) + 1) / 2) //!< Max power in mA
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Standard USB association descriptor structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t bLength;            //!< Size of this descriptor in bytes
 | 
			
		||||
    uint8_t bDescriptorType;    //!< Interface descriptor type
 | 
			
		||||
    uint8_t bFirstInterface;    //!< Number of interface
 | 
			
		||||
    uint8_t bInterfaceCount;    //!< value to select alternate setting
 | 
			
		||||
    uint8_t bFunctionClass;     //!< Class code assigned by the USB
 | 
			
		||||
    uint8_t bFunctionSubClass;  //!< Sub-class code assigned by the USB
 | 
			
		||||
    uint8_t bFunctionProtocol;  //!< Protocol code assigned by the USB
 | 
			
		||||
    uint8_t iFunction;          //!< Index of string descriptor
 | 
			
		||||
    uint8_t bLength;           //!< Size of this descriptor in bytes
 | 
			
		||||
    uint8_t bDescriptorType;   //!< Interface descriptor type
 | 
			
		||||
    uint8_t bFirstInterface;   //!< Number of interface
 | 
			
		||||
    uint8_t bInterfaceCount;   //!< value to select alternate setting
 | 
			
		||||
    uint8_t bFunctionClass;    //!< Class code assigned by the USB
 | 
			
		||||
    uint8_t bFunctionSubClass; //!< Sub-class code assigned by the USB
 | 
			
		||||
    uint8_t bFunctionProtocol; //!< Protocol code assigned by the USB
 | 
			
		||||
    uint8_t iFunction;         //!< Index of string descriptor
 | 
			
		||||
} usb_iad_desc_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,41 +50,41 @@
 | 
			
		|||
 | 
			
		||||
#ifdef VIRTSER_ENABLE
 | 
			
		||||
 | 
			
		||||
#    define CDC_CLASS_DEVICE 0x02  //!< USB Communication Device Class
 | 
			
		||||
#    define CDC_CLASS_COMM 0x02    //!< CDC Communication Class Interface
 | 
			
		||||
#    define CDC_CLASS_DATA 0x0A    //!< CDC Data Class Interface
 | 
			
		||||
#    define CDC_CLASS_DEVICE 0x02 //!< USB Communication Device Class
 | 
			
		||||
#    define CDC_CLASS_COMM 0x02   //!< CDC Communication Class Interface
 | 
			
		||||
#    define CDC_CLASS_DATA 0x0A   //!< CDC Data Class Interface
 | 
			
		||||
 | 
			
		||||
#    define CDC_SUBCLASS_DLCM 0x01  //!< Direct Line Control Model
 | 
			
		||||
#    define CDC_SUBCLASS_ACM 0x02   //!< Abstract Control Model
 | 
			
		||||
#    define CDC_SUBCLASS_TCM 0x03   //!< Telephone Control Model
 | 
			
		||||
#    define CDC_SUBCLASS_MCCM 0x04  //!< Multi-Channel Control Model
 | 
			
		||||
#    define CDC_SUBCLASS_CCM 0x05   //!< CAPI Control Model
 | 
			
		||||
#    define CDC_SUBCLASS_ETH 0x06   //!< Ethernet Networking Control Model
 | 
			
		||||
#    define CDC_SUBCLASS_ATM 0x07   //!< ATM Networking Control Model
 | 
			
		||||
#    define CDC_SUBCLASS_DLCM 0x01 //!< Direct Line Control Model
 | 
			
		||||
#    define CDC_SUBCLASS_ACM 0x02  //!< Abstract Control Model
 | 
			
		||||
#    define CDC_SUBCLASS_TCM 0x03  //!< Telephone Control Model
 | 
			
		||||
#    define CDC_SUBCLASS_MCCM 0x04 //!< Multi-Channel Control Model
 | 
			
		||||
#    define CDC_SUBCLASS_CCM 0x05  //!< CAPI Control Model
 | 
			
		||||
#    define CDC_SUBCLASS_ETH 0x06  //!< Ethernet Networking Control Model
 | 
			
		||||
#    define CDC_SUBCLASS_ATM 0x07  //!< ATM Networking Control Model
 | 
			
		||||
 | 
			
		||||
#    define CDC_PROTOCOL_V25TER 0x01  //!< Common AT commands
 | 
			
		||||
#    define CDC_PROTOCOL_V25TER 0x01 //!< Common AT commands
 | 
			
		||||
 | 
			
		||||
#    define CDC_PROTOCOL_I430 0x30    //!< ISDN BRI
 | 
			
		||||
#    define CDC_PROTOCOL_HDLC 0x31    //!< HDLC
 | 
			
		||||
#    define CDC_PROTOCOL_TRANS 0x32   //!< Transparent
 | 
			
		||||
#    define CDC_PROTOCOL_Q921M 0x50   //!< Q.921 management protocol
 | 
			
		||||
#    define CDC_PROTOCOL_Q921 0x51    //!< Q.931 [sic] Data link protocol
 | 
			
		||||
#    define CDC_PROTOCOL_Q921TM 0x52  //!< Q.921 TEI-multiplexor
 | 
			
		||||
#    define CDC_PROTOCOL_V42BIS 0x90  //!< Data compression procedures
 | 
			
		||||
#    define CDC_PROTOCOL_Q931 0x91    //!< Euro-ISDN protocol control
 | 
			
		||||
#    define CDC_PROTOCOL_V120 0x92    //!< V.24 rate adaption to ISDN
 | 
			
		||||
#    define CDC_PROTOCOL_CAPI20 0x93  //!< CAPI Commands
 | 
			
		||||
#    define CDC_PROTOCOL_HOST 0xFD    //!< Host based driver
 | 
			
		||||
#    define CDC_PROTOCOL_I430 0x30   //!< ISDN BRI
 | 
			
		||||
#    define CDC_PROTOCOL_HDLC 0x31   //!< HDLC
 | 
			
		||||
#    define CDC_PROTOCOL_TRANS 0x32  //!< Transparent
 | 
			
		||||
#    define CDC_PROTOCOL_Q921M 0x50  //!< Q.921 management protocol
 | 
			
		||||
#    define CDC_PROTOCOL_Q921 0x51   //!< Q.931 [sic] Data link protocol
 | 
			
		||||
#    define CDC_PROTOCOL_Q921TM 0x52 //!< Q.921 TEI-multiplexor
 | 
			
		||||
#    define CDC_PROTOCOL_V42BIS 0x90 //!< Data compression procedures
 | 
			
		||||
#    define CDC_PROTOCOL_Q931 0x91   //!< Euro-ISDN protocol control
 | 
			
		||||
#    define CDC_PROTOCOL_V120 0x92   //!< V.24 rate adaption to ISDN
 | 
			
		||||
#    define CDC_PROTOCOL_CAPI20 0x93 //!< CAPI Commands
 | 
			
		||||
#    define CDC_PROTOCOL_HOST 0xFD   //!< Host based driver
 | 
			
		||||
 | 
			
		||||
#    define CDC_PROTOCOL_PUFD 0xFE
 | 
			
		||||
 | 
			
		||||
#    define CDC_CS_INTERFACE 0x24  //!< Interface Functional Descriptor
 | 
			
		||||
#    define CDC_CS_ENDPOINT 0x25   //!< Endpoint Functional Descriptor
 | 
			
		||||
#    define CDC_CS_INTERFACE 0x24 //!< Interface Functional Descriptor
 | 
			
		||||
#    define CDC_CS_ENDPOINT 0x25  //!< Endpoint Functional Descriptor
 | 
			
		||||
 | 
			
		||||
#    define CDC_SCS_HEADER 0x00     //!< Header Functional Descriptor
 | 
			
		||||
#    define CDC_SCS_CALL_MGMT 0x01  //!< Call Management
 | 
			
		||||
#    define CDC_SCS_ACM 0x02        //!< Abstract Control Management
 | 
			
		||||
#    define CDC_SCS_UNION 0x06      //!< Union Functional Descriptor
 | 
			
		||||
#    define CDC_SCS_HEADER 0x00    //!< Header Functional Descriptor
 | 
			
		||||
#    define CDC_SCS_CALL_MGMT 0x01 //!< Call Management
 | 
			
		||||
#    define CDC_SCS_ACM 0x02       //!< Abstract Control Management
 | 
			
		||||
#    define CDC_SCS_UNION 0x06     //!< Union Functional Descriptor
 | 
			
		||||
 | 
			
		||||
#    define USB_REQ_CDC_SEND_ENCAPSULATED_COMMAND 0x00
 | 
			
		||||
#    define USB_REQ_CDC_GET_ENCAPSULATED_RESPONSE 0x01
 | 
			
		||||
| 
						 | 
				
			
			@ -144,17 +144,17 @@ typedef struct {
 | 
			
		|||
#    pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
enum cdc_char_format {
 | 
			
		||||
    CDC_STOP_BITS_1   = 0,  //!< 1 stop bit
 | 
			
		||||
    CDC_STOP_BITS_1_5 = 1,  //!< 1.5 stop bits
 | 
			
		||||
    CDC_STOP_BITS_2   = 2,  //!< 2 stop bits
 | 
			
		||||
    CDC_STOP_BITS_1   = 0, //!< 1 stop bit
 | 
			
		||||
    CDC_STOP_BITS_1_5 = 1, //!< 1.5 stop bits
 | 
			
		||||
    CDC_STOP_BITS_2   = 2, //!< 2 stop bits
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum cdc_parity {
 | 
			
		||||
    CDC_PAR_NONE  = 0,  //!< No parity
 | 
			
		||||
    CDC_PAR_ODD   = 1,  //!< Odd parity
 | 
			
		||||
    CDC_PAR_EVEN  = 2,  //!< Even parity
 | 
			
		||||
    CDC_PAR_MARK  = 3,  //!< Parity forced to 0 (space)
 | 
			
		||||
    CDC_PAR_SPACE = 4,  //!< Parity forced to 1 (mark)
 | 
			
		||||
    CDC_PAR_NONE  = 0, //!< No parity
 | 
			
		||||
    CDC_PAR_ODD   = 1, //!< Odd parity
 | 
			
		||||
    CDC_PAR_EVEN  = 2, //!< Even parity
 | 
			
		||||
    CDC_PAR_MARK  = 3, //!< Parity forced to 0 (space)
 | 
			
		||||
    CDC_PAR_SPACE = 4, //!< Parity forced to 1 (mark)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -187,4 +187,4 @@ typedef struct {
 | 
			
		|||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // _USB_PROTOCOL_CDC_H_
 | 
			
		||||
#endif // _USB_PROTOCOL_CDC_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -121,13 +121,13 @@ COMPILER_PACK_SET(1)
 | 
			
		|||
 | 
			
		||||
//! \brief HID Descriptor
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t bLength;            //!< Size of this descriptor in bytes
 | 
			
		||||
    uint8_t bDescriptorType;    //!< HID descriptor type
 | 
			
		||||
    le16_t  bcdHID;             //!< Binary Coded Decimal Spec. release
 | 
			
		||||
    uint8_t bCountryCode;       //!< Hardware target country
 | 
			
		||||
    uint8_t bNumDescriptors;    //!< Number of HID class descriptors to follow
 | 
			
		||||
    uint8_t bRDescriptorType;   //!< Report descriptor type
 | 
			
		||||
    le16_t  wDescriptorLength;  //!< Total length of Report descriptor
 | 
			
		||||
    uint8_t bLength;           //!< Size of this descriptor in bytes
 | 
			
		||||
    uint8_t bDescriptorType;   //!< HID descriptor type
 | 
			
		||||
    le16_t  bcdHID;            //!< Binary Coded Decimal Spec. release
 | 
			
		||||
    uint8_t bCountryCode;      //!< Hardware target country
 | 
			
		||||
    uint8_t bNumDescriptors;   //!< Number of HID class descriptors to follow
 | 
			
		||||
    uint8_t bRDescriptorType;  //!< Report descriptor type
 | 
			
		||||
    le16_t  wDescriptorLength; //!< Total length of Report descriptor
 | 
			
		||||
} usb_hid_descriptor_t;
 | 
			
		||||
 | 
			
		||||
COMPILER_PACK_RESET()
 | 
			
		||||
| 
						 | 
				
			
			@ -151,45 +151,45 @@ COMPILER_PACK_RESET()
 | 
			
		|||
 | 
			
		||||
//! \name Country code
 | 
			
		||||
//! @{
 | 
			
		||||
#define USB_HID_NO_COUNTRY_CODE 0             // Not Supported
 | 
			
		||||
#define USB_HID_COUNTRY_ARABIC 1              // Arabic
 | 
			
		||||
#define USB_HID_COUNTRY_BELGIAN 2             // Belgian
 | 
			
		||||
#define USB_HID_COUNTRY_CANADIAN_BILINGUAL 3  // Canadian-Bilingual
 | 
			
		||||
#define USB_HID_COUNTRY_CANADIAN_FRENCH 4     // Canadian-French
 | 
			
		||||
#define USB_HID_COUNTRY_CZECH_REPUBLIC 5      // Czech Republic
 | 
			
		||||
#define USB_HID_COUNTRY_DANISH 6              // Danish
 | 
			
		||||
#define USB_HID_COUNTRY_FINNISH 7             // Finnish
 | 
			
		||||
#define USB_HID_COUNTRY_FRENCH 8              // French
 | 
			
		||||
#define USB_HID_COUNTRY_GERMAN 9              // German
 | 
			
		||||
#define USB_HID_COUNTRY_GREEK 10              // Greek
 | 
			
		||||
#define USB_HID_COUNTRY_HEBREW 11             // Hebrew
 | 
			
		||||
#define USB_HID_COUNTRY_HUNGARY 12            // Hungary
 | 
			
		||||
#define USB_HID_COUNTRY_INTERNATIONAL_ISO 13  // International (ISO)
 | 
			
		||||
#define USB_HID_COUNTRY_ITALIAN 14            // Italian
 | 
			
		||||
#define USB_HID_COUNTRY_JAPAN_KATAKANA 15     // Japan (Katakana)
 | 
			
		||||
#define USB_HID_COUNTRY_KOREAN 16             // Korean
 | 
			
		||||
#define USB_HID_COUNTRY_LATIN_AMERICAN 17     // Latin American
 | 
			
		||||
#define USB_HID_COUNTRY_NETHERLANDS_DUTCH 18  // Netherlands/Dutch
 | 
			
		||||
#define USB_HID_COUNTRY_NORWEGIAN 19          // Norwegian
 | 
			
		||||
#define USB_HID_COUNTRY_PERSIAN_FARSI 20      // Persian (Farsi)
 | 
			
		||||
#define USB_HID_COUNTRY_POLAND 21             // Poland
 | 
			
		||||
#define USB_HID_COUNTRY_PORTUGUESE 22         // Portuguese
 | 
			
		||||
#define USB_HID_COUNTRY_RUSSIA 23             // Russia
 | 
			
		||||
#define USB_HID_COUNTRY_SLOVAKIA 24           // Slovakia
 | 
			
		||||
#define USB_HID_COUNTRY_SPANISH 25            // Spanish
 | 
			
		||||
#define USB_HID_COUNTRY_SWEDISH 26            // Swedish
 | 
			
		||||
#define USB_HID_COUNTRY_SWISS_FRENCH 27       // Swiss/French
 | 
			
		||||
#define USB_HID_COUNTRY_SWISS_GERMAN 28       // Swiss/German
 | 
			
		||||
#define USB_HID_COUNTRY_SWITZERLAND 29        // Switzerland
 | 
			
		||||
#define USB_HID_COUNTRY_TAIWAN 30             // Taiwan
 | 
			
		||||
#define USB_HID_COUNTRY_TURKISH_Q 31          // Turkish-Q
 | 
			
		||||
#define USB_HID_COUNTRY_UK 32                 // UK
 | 
			
		||||
#define USB_HID_COUNTRY_US 33                 // US
 | 
			
		||||
#define USB_HID_COUNTRY_YUGOSLAVIA 34         // Yugoslavia
 | 
			
		||||
#define USB_HID_NO_COUNTRY_CODE 0            // Not Supported
 | 
			
		||||
#define USB_HID_COUNTRY_ARABIC 1             // Arabic
 | 
			
		||||
#define USB_HID_COUNTRY_BELGIAN 2            // Belgian
 | 
			
		||||
#define USB_HID_COUNTRY_CANADIAN_BILINGUAL 3 // Canadian-Bilingual
 | 
			
		||||
#define USB_HID_COUNTRY_CANADIAN_FRENCH 4    // Canadian-French
 | 
			
		||||
#define USB_HID_COUNTRY_CZECH_REPUBLIC 5     // Czech Republic
 | 
			
		||||
#define USB_HID_COUNTRY_DANISH 6             // Danish
 | 
			
		||||
#define USB_HID_COUNTRY_FINNISH 7            // Finnish
 | 
			
		||||
#define USB_HID_COUNTRY_FRENCH 8             // French
 | 
			
		||||
#define USB_HID_COUNTRY_GERMAN 9             // German
 | 
			
		||||
#define USB_HID_COUNTRY_GREEK 10             // Greek
 | 
			
		||||
#define USB_HID_COUNTRY_HEBREW 11            // Hebrew
 | 
			
		||||
#define USB_HID_COUNTRY_HUNGARY 12           // Hungary
 | 
			
		||||
#define USB_HID_COUNTRY_INTERNATIONAL_ISO 13 // International (ISO)
 | 
			
		||||
#define USB_HID_COUNTRY_ITALIAN 14           // Italian
 | 
			
		||||
#define USB_HID_COUNTRY_JAPAN_KATAKANA 15    // Japan (Katakana)
 | 
			
		||||
#define USB_HID_COUNTRY_KOREAN 16            // Korean
 | 
			
		||||
#define USB_HID_COUNTRY_LATIN_AMERICAN 17    // Latin American
 | 
			
		||||
#define USB_HID_COUNTRY_NETHERLANDS_DUTCH 18 // Netherlands/Dutch
 | 
			
		||||
#define USB_HID_COUNTRY_NORWEGIAN 19         // Norwegian
 | 
			
		||||
#define USB_HID_COUNTRY_PERSIAN_FARSI 20     // Persian (Farsi)
 | 
			
		||||
#define USB_HID_COUNTRY_POLAND 21            // Poland
 | 
			
		||||
#define USB_HID_COUNTRY_PORTUGUESE 22        // Portuguese
 | 
			
		||||
#define USB_HID_COUNTRY_RUSSIA 23            // Russia
 | 
			
		||||
#define USB_HID_COUNTRY_SLOVAKIA 24          // Slovakia
 | 
			
		||||
#define USB_HID_COUNTRY_SPANISH 25           // Spanish
 | 
			
		||||
#define USB_HID_COUNTRY_SWEDISH 26           // Swedish
 | 
			
		||||
#define USB_HID_COUNTRY_SWISS_FRENCH 27      // Swiss/French
 | 
			
		||||
#define USB_HID_COUNTRY_SWISS_GERMAN 28      // Swiss/German
 | 
			
		||||
#define USB_HID_COUNTRY_SWITZERLAND 29       // Switzerland
 | 
			
		||||
#define USB_HID_COUNTRY_TAIWAN 30            // Taiwan
 | 
			
		||||
#define USB_HID_COUNTRY_TURKISH_Q 31         // Turkish-Q
 | 
			
		||||
#define USB_HID_COUNTRY_UK 32                // UK
 | 
			
		||||
#define USB_HID_COUNTRY_US 33                // US
 | 
			
		||||
#define USB_HID_COUNTRY_YUGOSLAVIA 34        // Yugoslavia
 | 
			
		||||
#define USB_HID_COUNTRY_TURKISH_F \
 | 
			
		||||
    35  // Turkish-F
 | 
			
		||||
        //! @}
 | 
			
		||||
        //! @}
 | 
			
		||||
    35 // Turkish-F
 | 
			
		||||
       //! @}
 | 
			
		||||
       //! @}
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
//! \name HID KEYS values
 | 
			
		||||
| 
						 | 
				
			
			@ -237,12 +237,12 @@ COMPILER_PACK_RESET()
 | 
			
		|||
#define HID_SPACEBAR 44
 | 
			
		||||
#define HID_UNDERSCORE 45
 | 
			
		||||
#define HID_PLUS 46
 | 
			
		||||
#define HID_OPEN_BRACKET 47   // {
 | 
			
		||||
#define HID_CLOSE_BRACKET 48  // }
 | 
			
		||||
#define HID_OPEN_BRACKET 47  // {
 | 
			
		||||
#define HID_CLOSE_BRACKET 48 // }
 | 
			
		||||
#define HID_BACKSLASH 49
 | 
			
		||||
#define HID_ASH 50    // # ~
 | 
			
		||||
#define HID_COLON 51  // ; :
 | 
			
		||||
#define HID_QUOTE 52  // ' "
 | 
			
		||||
#define HID_ASH 50   // # ~
 | 
			
		||||
#define HID_COLON 51 // ; :
 | 
			
		||||
#define HID_QUOTE 52 // ' "
 | 
			
		||||
#define HID_TILDE 53
 | 
			
		||||
#define HID_COMMA 54
 | 
			
		||||
#define HID_DOT 55
 | 
			
		||||
| 
						 | 
				
			
			@ -314,4 +314,4 @@ COMPILER_PACK_RESET()
 | 
			
		|||
#define HID_LED_KANA (1 << 4)
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
#endif  // _USB_PROTOCOL_HID_H_
 | 
			
		||||
#endif // _USB_PROTOCOL_HID_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,17 +11,17 @@ char digit(int d, int radix) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
int UTIL_ltoa_radix(int64_t value, char *dest, int radix) {
 | 
			
		||||
    int64_t original = value;  // save original value
 | 
			
		||||
    int64_t original = value; // save original value
 | 
			
		||||
    char    buf[25]  = "";
 | 
			
		||||
    int     c        = sizeof(buf) - 1;
 | 
			
		||||
    int     last     = c;
 | 
			
		||||
    int     d;
 | 
			
		||||
    int     size;
 | 
			
		||||
 | 
			
		||||
    if (value < 0)  // if it's negative, take the absolute value
 | 
			
		||||
    if (value < 0) // if it's negative, take the absolute value
 | 
			
		||||
        value = -value;
 | 
			
		||||
 | 
			
		||||
    do  // write least significant digit of value that's left
 | 
			
		||||
    do // write least significant digit of value that's left
 | 
			
		||||
    {
 | 
			
		||||
        d        = (value % radix);
 | 
			
		||||
        buf[--c] = digit(d, radix);
 | 
			
		||||
| 
						 | 
				
			
			@ -30,14 +30,20 @@ int UTIL_ltoa_radix(int64_t value, char *dest, int radix) {
 | 
			
		|||
 | 
			
		||||
    if (original < 0) buf[--c] = '-';
 | 
			
		||||
 | 
			
		||||
    size = last - c + 1;  // includes null at end
 | 
			
		||||
    size = last - c + 1; // includes null at end
 | 
			
		||||
    memcpy(dest, &buf[c], last - c + 1);
 | 
			
		||||
 | 
			
		||||
    return (size - 1);  // without null termination
 | 
			
		||||
    return (size - 1); // without null termination
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int UTIL_ltoa(int64_t value, char *dest) { return UTIL_ltoa_radix(value, dest, 10); }
 | 
			
		||||
int UTIL_ltoa(int64_t value, char *dest) {
 | 
			
		||||
    return UTIL_ltoa_radix(value, dest, 10);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int UTIL_itoa(int value, char *dest) { return UTIL_ltoa_radix((int64_t)value, dest, 10); }
 | 
			
		||||
int UTIL_itoa(int value, char *dest) {
 | 
			
		||||
    return UTIL_ltoa_radix((int64_t)value, dest, 10);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int UTIL_utoa(uint32_t value, char *dest) { return UTIL_ltoa_radix((int64_t)value, dest, 10); }
 | 
			
		||||
int UTIL_utoa(uint32_t value, char *dest) {
 | 
			
		||||
    return UTIL_ltoa_radix((int64_t)value, dest, 10);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,4 +6,4 @@ int UTIL_ltoa(int64_t value, char *dest);
 | 
			
		|||
int UTIL_itoa(int value, char *dest);
 | 
			
		||||
int UTIL_utoa(uint32_t value, char *dest);
 | 
			
		||||
 | 
			
		||||
#endif  //_USB_UTIL_H_
 | 
			
		||||
#endif //_USB_UTIL_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,7 +107,7 @@ __attribute__((weak)) void early_hardware_init_pre(void) {
 | 
			
		|||
#if EARLY_INIT_PERFORM_BOOTLOADER_JUMP
 | 
			
		||||
    void enter_bootloader_mode_if_requested(void);
 | 
			
		||||
    enter_bootloader_mode_if_requested();
 | 
			
		||||
#endif  // EARLY_INIT_PERFORM_BOOTLOADER_JUMP
 | 
			
		||||
#endif // EARLY_INIT_PERFORM_BOOTLOADER_JUMP
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((weak)) void early_hardware_init_post(void) {}
 | 
			
		||||
| 
						 | 
				
			
			@ -176,7 +176,9 @@ void protocol_pre_init(void) {
 | 
			
		|||
    print("USB configured.\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void protocol_post_init(void) { host_set_driver(driver); }
 | 
			
		||||
void protocol_post_init(void) {
 | 
			
		||||
    host_set_driver(driver);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void protocol_pre_task(void) {
 | 
			
		||||
    usb_event_queue_task();
 | 
			
		||||
| 
						 | 
				
			
			@ -186,7 +188,7 @@ void protocol_pre_task(void) {
 | 
			
		|||
        print("[s]");
 | 
			
		||||
        while (USB_DRIVER.state == USB_SUSPENDED) {
 | 
			
		||||
            /* Do this in the suspended state */
 | 
			
		||||
            suspend_power_down();  // on AVR this deep sleeps for 15ms
 | 
			
		||||
            suspend_power_down(); // on AVR this deep sleeps for 15ms
 | 
			
		||||
            /* Remote wakeup */
 | 
			
		||||
            if (suspend_wakeup_condition()) {
 | 
			
		||||
                usbWakeupHost(&USB_DRIVER);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -80,21 +80,37 @@ static bool qmkusb_start_receive(QMKUSBDriver *qmkusbp) {
 | 
			
		|||
 * Interface implementation.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static size_t _write(void *ip, const uint8_t *bp, size_t n) { return obqWriteTimeout(&((QMKUSBDriver *)ip)->obqueue, bp, n, TIME_INFINITE); }
 | 
			
		||||
static size_t _write(void *ip, const uint8_t *bp, size_t n) {
 | 
			
		||||
    return obqWriteTimeout(&((QMKUSBDriver *)ip)->obqueue, bp, n, TIME_INFINITE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static size_t _read(void *ip, uint8_t *bp, size_t n) { return ibqReadTimeout(&((QMKUSBDriver *)ip)->ibqueue, bp, n, TIME_INFINITE); }
 | 
			
		||||
static size_t _read(void *ip, uint8_t *bp, size_t n) {
 | 
			
		||||
    return ibqReadTimeout(&((QMKUSBDriver *)ip)->ibqueue, bp, n, TIME_INFINITE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static msg_t _put(void *ip, uint8_t b) { return obqPutTimeout(&((QMKUSBDriver *)ip)->obqueue, b, TIME_INFINITE); }
 | 
			
		||||
static msg_t _put(void *ip, uint8_t b) {
 | 
			
		||||
    return obqPutTimeout(&((QMKUSBDriver *)ip)->obqueue, b, TIME_INFINITE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static msg_t _get(void *ip) { return ibqGetTimeout(&((QMKUSBDriver *)ip)->ibqueue, TIME_INFINITE); }
 | 
			
		||||
static msg_t _get(void *ip) {
 | 
			
		||||
    return ibqGetTimeout(&((QMKUSBDriver *)ip)->ibqueue, TIME_INFINITE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static msg_t _putt(void *ip, uint8_t b, sysinterval_t timeout) { return obqPutTimeout(&((QMKUSBDriver *)ip)->obqueue, b, timeout); }
 | 
			
		||||
static msg_t _putt(void *ip, uint8_t b, sysinterval_t timeout) {
 | 
			
		||||
    return obqPutTimeout(&((QMKUSBDriver *)ip)->obqueue, b, timeout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static msg_t _gett(void *ip, sysinterval_t timeout) { return ibqGetTimeout(&((QMKUSBDriver *)ip)->ibqueue, timeout); }
 | 
			
		||||
static msg_t _gett(void *ip, sysinterval_t timeout) {
 | 
			
		||||
    return ibqGetTimeout(&((QMKUSBDriver *)ip)->ibqueue, timeout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static size_t _writet(void *ip, const uint8_t *bp, size_t n, sysinterval_t timeout) { return obqWriteTimeout(&((QMKUSBDriver *)ip)->obqueue, bp, n, timeout); }
 | 
			
		||||
static size_t _writet(void *ip, const uint8_t *bp, size_t n, sysinterval_t timeout) {
 | 
			
		||||
    return obqWriteTimeout(&((QMKUSBDriver *)ip)->obqueue, bp, n, timeout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static size_t _readt(void *ip, uint8_t *bp, size_t n, sysinterval_t timeout) { return ibqReadTimeout(&((QMKUSBDriver *)ip)->ibqueue, bp, n, timeout); }
 | 
			
		||||
static size_t _readt(void *ip, uint8_t *bp, size_t n, sysinterval_t timeout) {
 | 
			
		||||
    return ibqReadTimeout(&((QMKUSBDriver *)ip)->ibqueue, bp, n, timeout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct QMKUSBDriverVMT vmt = {0, _write, _read, _put, _get, _putt, _gett, _writet, _readt};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -775,7 +775,9 @@ void kbd_in_cb(USBDriver *usbp, usbep_t ep) {
 | 
			
		|||
/* start-of-frame handler
 | 
			
		||||
 * TODO: i guess it would be better to re-implement using timers,
 | 
			
		||||
 *  so that this is not going to have to be checked every 1ms */
 | 
			
		||||
void kbd_sof_cb(USBDriver *usbp) { (void)usbp; }
 | 
			
		||||
void kbd_sof_cb(USBDriver *usbp) {
 | 
			
		||||
    (void)usbp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Idle requests timer code
 | 
			
		||||
 * callback (called from ISR, unlocked state) */
 | 
			
		||||
| 
						 | 
				
			
			@ -815,7 +817,9 @@ static void keyboard_idle_timer_cb(void *arg) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/* LED status */
 | 
			
		||||
uint8_t keyboard_leds(void) { return keyboard_led_state; }
 | 
			
		||||
uint8_t keyboard_leds(void) {
 | 
			
		||||
    return keyboard_led_state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* prepare and start sending a report IN
 | 
			
		||||
 * not callable from ISR or locked state */
 | 
			
		||||
| 
						 | 
				
			
			@ -915,7 +919,9 @@ void send_mouse(report_mouse_t *report) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
#else  /* MOUSE_ENABLE */
 | 
			
		||||
void send_mouse(report_mouse_t *report) { (void)report; }
 | 
			
		||||
void send_mouse(report_mouse_t *report) {
 | 
			
		||||
    (void)report;
 | 
			
		||||
}
 | 
			
		||||
#endif /* MOUSE_ENABLE */
 | 
			
		||||
 | 
			
		||||
/* ---------------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			@ -1107,7 +1113,9 @@ void raw_hid_task(void) {
 | 
			
		|||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
 | 
			
		||||
void send_midi_packet(MIDI_EventPacket_t *event) { chnWrite(&drivers.midi_driver.driver, (uint8_t *)event, sizeof(MIDI_EventPacket_t)); }
 | 
			
		||||
void send_midi_packet(MIDI_EventPacket_t *event) {
 | 
			
		||||
    chnWrite(&drivers.midi_driver.driver, (uint8_t *)event, sizeof(MIDI_EventPacket_t));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool recv_midi_packet(MIDI_EventPacket_t *const event) {
 | 
			
		||||
    size_t size = chnReadTimeout(&drivers.midi_driver.driver, (uint8_t *)event, sizeof(MIDI_EventPacket_t), TIME_IMMEDIATE);
 | 
			
		||||
| 
						 | 
				
			
			@ -1130,7 +1138,9 @@ void midi_ep_task(void) {
 | 
			
		|||
 | 
			
		||||
void virtser_init(void) {}
 | 
			
		||||
 | 
			
		||||
void virtser_send(const uint8_t byte) { chnWrite(&drivers.serial_driver.driver, &byte, 1); }
 | 
			
		||||
void virtser_send(const uint8_t byte) {
 | 
			
		||||
    chnWrite(&drivers.serial_driver.driver, &byte, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((weak)) void virtser_recv(uint8_t c) {
 | 
			
		||||
    // Ignore by default
 | 
			
		||||
| 
						 | 
				
			
			@ -1174,7 +1184,7 @@ void send_joystick_packet(joystick_t *joystick) {
 | 
			
		|||
          joystick->axes[5],
 | 
			
		||||
#        endif
 | 
			
		||||
        },
 | 
			
		||||
#    endif  // JOYSTICK_AXES_COUNT>0
 | 
			
		||||
#    endif // JOYSTICK_AXES_COUNT>0
 | 
			
		||||
 | 
			
		||||
#    if JOYSTICK_BUTTON_COUNT > 0
 | 
			
		||||
        .buttons = {
 | 
			
		||||
| 
						 | 
				
			
			@ -1190,7 +1200,7 @@ void send_joystick_packet(joystick_t *joystick) {
 | 
			
		|||
            joystick->buttons[3],
 | 
			
		||||
#        endif
 | 
			
		||||
        }
 | 
			
		||||
#    endif  // JOYSTICK_BUTTON_COUNT>0
 | 
			
		||||
#    endif // JOYSTICK_BUTTON_COUNT>0
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // chnWrite(&drivers.joystick_driver.driver, (uint8_t *)&rep, sizeof(rep));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,10 @@
 | 
			
		|||
#include <hal.h>
 | 
			
		||||
#include "usb_util.h"
 | 
			
		||||
 | 
			
		||||
void usb_disconnect(void) { usbStop(&USBD1); }
 | 
			
		||||
void usb_disconnect(void) {
 | 
			
		||||
    usbStop(&USBD1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool usb_connected_state(void) { return usbGetDriverStateI(&USBD1) == USB_ACTIVE; }
 | 
			
		||||
bool usb_connected_state(void) {
 | 
			
		||||
    return usbGetDriverStateI(&USBD1) == USB_ACTIVE;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,13 +34,19 @@ static uint16_t       last_system_report              = 0;
 | 
			
		|||
static uint16_t       last_consumer_report            = 0;
 | 
			
		||||
static uint32_t       last_programmable_button_report = 0;
 | 
			
		||||
 | 
			
		||||
void host_set_driver(host_driver_t *d) { driver = d; }
 | 
			
		||||
void host_set_driver(host_driver_t *d) {
 | 
			
		||||
    driver = d;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
host_driver_t *host_get_driver(void) { return driver; }
 | 
			
		||||
host_driver_t *host_get_driver(void) {
 | 
			
		||||
    return driver;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef SPLIT_KEYBOARD
 | 
			
		||||
uint8_t split_led_state = 0;
 | 
			
		||||
void    set_split_host_keyboard_leds(uint8_t led_state) { split_led_state = led_state; }
 | 
			
		||||
void    set_split_host_keyboard_leds(uint8_t led_state) {
 | 
			
		||||
    split_led_state = led_state;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
uint8_t host_keyboard_leds(void) {
 | 
			
		||||
| 
						 | 
				
			
			@ -51,7 +57,9 @@ uint8_t host_keyboard_leds(void) {
 | 
			
		|||
    return (*driver->keyboard_leds)();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
led_t host_keyboard_led_state(void) { return (led_t)host_keyboard_leds(); }
 | 
			
		||||
led_t host_keyboard_led_state(void) {
 | 
			
		||||
    return (led_t)host_keyboard_leds();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* send report */
 | 
			
		||||
void host_keyboard_send(report_keyboard_t *report) {
 | 
			
		||||
| 
						 | 
				
			
			@ -131,8 +139,14 @@ void host_programmable_button_send(uint32_t report) {
 | 
			
		|||
    (*driver->send_programmable_button)(report);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t host_last_system_report(void) { return last_system_report; }
 | 
			
		||||
uint16_t host_last_system_report(void) {
 | 
			
		||||
    return last_system_report;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t host_last_consumer_report(void) { return last_consumer_report; }
 | 
			
		||||
uint16_t host_last_consumer_report(void) {
 | 
			
		||||
    return last_consumer_report;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t host_last_programmable_button_report(void) { return last_programmable_button_report; }
 | 
			
		||||
uint32_t host_last_programmable_button_report(void) {
 | 
			
		||||
    return last_programmable_button_report;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -256,7 +256,8 @@ static void Console_Task(void) {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    // fill empty bank
 | 
			
		||||
    while (Endpoint_IsReadWriteAllowed()) Endpoint_Write_8(0);
 | 
			
		||||
    while (Endpoint_IsReadWriteAllowed())
 | 
			
		||||
        Endpoint_Write_8(0);
 | 
			
		||||
 | 
			
		||||
    // flush sendchar packet
 | 
			
		||||
    if (Endpoint_IsINReady()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -296,7 +297,7 @@ void send_joystick_packet(joystick_t *joystick) {
 | 
			
		|||
          joystick->axes[5],
 | 
			
		||||
#        endif
 | 
			
		||||
        },
 | 
			
		||||
#    endif  // JOYSTICK_AXES_COUNT>0
 | 
			
		||||
#    endif // JOYSTICK_AXES_COUNT>0
 | 
			
		||||
 | 
			
		||||
#    if JOYSTICK_BUTTON_COUNT > 0
 | 
			
		||||
        .buttons = {
 | 
			
		||||
| 
						 | 
				
			
			@ -312,14 +313,15 @@ void send_joystick_packet(joystick_t *joystick) {
 | 
			
		|||
            joystick->buttons[3],
 | 
			
		||||
#        endif
 | 
			
		||||
        }
 | 
			
		||||
#    endif  // JOYSTICK_BUTTON_COUNT>0
 | 
			
		||||
#    endif // JOYSTICK_BUTTON_COUNT>0
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /* Select the Joystick Report Endpoint */
 | 
			
		||||
    Endpoint_SelectEndpoint(JOYSTICK_IN_EPNUM);
 | 
			
		||||
 | 
			
		||||
    /* Check if write ready for a polling interval around 10ms */
 | 
			
		||||
    while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
 | 
			
		||||
    while (timeout-- && !Endpoint_IsReadWriteAllowed())
 | 
			
		||||
        _delay_us(40);
 | 
			
		||||
    if (!Endpoint_IsReadWriteAllowed()) return;
 | 
			
		||||
 | 
			
		||||
    /* Write Joystick Report Data */
 | 
			
		||||
| 
						 | 
				
			
			@ -414,9 +416,11 @@ void EVENT_USB_Device_WakeUp() {
 | 
			
		|||
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
static bool console_flush = false;
 | 
			
		||||
#    define CONSOLE_FLUSH_SET(b)                                     \
 | 
			
		||||
        do {                                                         \
 | 
			
		||||
            ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { console_flush = b; } \
 | 
			
		||||
#    define CONSOLE_FLUSH_SET(b)                \
 | 
			
		||||
        do {                                    \
 | 
			
		||||
            ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { \
 | 
			
		||||
                console_flush = b;              \
 | 
			
		||||
            }                                   \
 | 
			
		||||
        } while (0)
 | 
			
		||||
 | 
			
		||||
/** \brief Event USB Device Start Of Frame
 | 
			
		||||
| 
						 | 
				
			
			@ -634,7 +638,9 @@ void EVENT_USB_Device_ControlRequest(void) {
 | 
			
		|||
 *
 | 
			
		||||
 * FIXME: Needs doc
 | 
			
		||||
 */
 | 
			
		||||
static uint8_t keyboard_leds(void) { return keyboard_led_state; }
 | 
			
		||||
static uint8_t keyboard_leds(void) {
 | 
			
		||||
    return keyboard_led_state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** \brief Send Keyboard
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -665,7 +671,8 @@ static void send_keyboard(report_keyboard_t *report) {
 | 
			
		|||
#endif
 | 
			
		||||
    Endpoint_SelectEndpoint(ep);
 | 
			
		||||
    /* Check if write ready for a polling interval around 10ms */
 | 
			
		||||
    while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
 | 
			
		||||
    while (timeout-- && !Endpoint_IsReadWriteAllowed())
 | 
			
		||||
        _delay_us(40);
 | 
			
		||||
    if (!Endpoint_IsReadWriteAllowed()) return;
 | 
			
		||||
 | 
			
		||||
    /* If we're in Boot Protocol, don't send any report ID or other funky fields */
 | 
			
		||||
| 
						 | 
				
			
			@ -705,7 +712,8 @@ static void send_mouse(report_mouse_t *report) {
 | 
			
		|||
    Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
 | 
			
		||||
 | 
			
		||||
    /* Check if write ready for a polling interval around 10ms */
 | 
			
		||||
    while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
 | 
			
		||||
    while (timeout-- && !Endpoint_IsReadWriteAllowed())
 | 
			
		||||
        _delay_us(40);
 | 
			
		||||
    if (!Endpoint_IsReadWriteAllowed()) return;
 | 
			
		||||
 | 
			
		||||
    /* Write Mouse Report Data */
 | 
			
		||||
| 
						 | 
				
			
			@ -725,7 +733,8 @@ static void send_report(void *report, size_t size) {
 | 
			
		|||
    Endpoint_SelectEndpoint(SHARED_IN_EPNUM);
 | 
			
		||||
 | 
			
		||||
    /* Check if write ready for a polling interval around 10ms */
 | 
			
		||||
    while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
 | 
			
		||||
    while (timeout-- && !Endpoint_IsReadWriteAllowed())
 | 
			
		||||
        _delay_us(40);
 | 
			
		||||
    if (!Endpoint_IsReadWriteAllowed()) return;
 | 
			
		||||
 | 
			
		||||
    Endpoint_Write_Stream_LE(report, size, NULL);
 | 
			
		||||
| 
						 | 
				
			
			@ -876,9 +885,13 @@ USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface = {
 | 
			
		|||
 | 
			
		||||
// clang-format on
 | 
			
		||||
 | 
			
		||||
void send_midi_packet(MIDI_EventPacket_t *event) { MIDI_Device_SendEventPacket(&USB_MIDI_Interface, event); }
 | 
			
		||||
void send_midi_packet(MIDI_EventPacket_t *event) {
 | 
			
		||||
    MIDI_Device_SendEventPacket(&USB_MIDI_Interface, event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool recv_midi_packet(MIDI_EventPacket_t *const event) { return MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, event); }
 | 
			
		||||
bool recv_midi_packet(MIDI_EventPacket_t *const event) {
 | 
			
		||||
    return MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -934,7 +947,8 @@ void virtser_send(const uint8_t byte) {
 | 
			
		|||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
 | 
			
		||||
        while (timeout-- && !Endpoint_IsReadWriteAllowed())
 | 
			
		||||
            _delay_us(40);
 | 
			
		||||
 | 
			
		||||
        Endpoint_Write_8(byte);
 | 
			
		||||
        CDC_Device_Flush(&cdc_device);
 | 
			
		||||
| 
						 | 
				
			
			@ -957,7 +971,8 @@ void send_digitizer(report_digitizer_t *report) {
 | 
			
		|||
    Endpoint_SelectEndpoint(DIGITIZER_IN_EPNUM);
 | 
			
		||||
 | 
			
		||||
    /* Check if write ready for a polling interval around 10ms */
 | 
			
		||||
    while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
 | 
			
		||||
    while (timeout-- && !Endpoint_IsReadWriteAllowed())
 | 
			
		||||
        _delay_us(40);
 | 
			
		||||
    if (!Endpoint_IsReadWriteAllowed()) return;
 | 
			
		||||
 | 
			
		||||
    Endpoint_Write_Stream_LE(report, sizeof(report_digitizer_t), NULL);
 | 
			
		||||
| 
						 | 
				
			
			@ -1033,7 +1048,9 @@ void protocol_pre_init(void) {
 | 
			
		|||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void protocol_post_init(void) { host_set_driver(&lufa_driver); }
 | 
			
		||||
void protocol_post_init(void) {
 | 
			
		||||
    host_set_driver(&lufa_driver);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void protocol_pre_task(void) {
 | 
			
		||||
#if !defined(NO_USB_STARTUP_CHECK)
 | 
			
		||||
| 
						 | 
				
			
			@ -1084,4 +1101,6 @@ void protocol_post_task(void) {
 | 
			
		|||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint16_t wIndex, const void **const DescriptorAddress) { return get_usb_descriptor(wValue, wIndex, DescriptorAddress); }
 | 
			
		||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint16_t wIndex, const void **const DescriptorAddress) {
 | 
			
		||||
    return get_usb_descriptor(wValue, wIndex, DescriptorAddress);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,13 +22,15 @@ void usb_disconnect(void) {
 | 
			
		|||
    USB_DeviceState = DEVICE_STATE_Unattached;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool usb_connected_state(void) { return USB_Device_IsAddressSet(); }
 | 
			
		||||
bool usb_connected_state(void) {
 | 
			
		||||
    return USB_Device_IsAddressSet();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(OTGPADE)
 | 
			
		||||
bool usb_vbus_state(void) {
 | 
			
		||||
    USB_OTGPAD_On();  // enables VBUS pad
 | 
			
		||||
    USB_OTGPAD_On(); // enables VBUS pad
 | 
			
		||||
    wait_us(5);
 | 
			
		||||
 | 
			
		||||
    return USB_VBUS_GetStatus();  // checks state of VBUS
 | 
			
		||||
    return USB_VBUS_GetStatus(); // checks state of VBUS
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,7 +52,9 @@ byteQueueIndex_t bytequeue_length(byteQueue_t* queue) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// we don't need to avoid interrupts if there is only one reader
 | 
			
		||||
uint8_t bytequeue_get(byteQueue_t* queue, byteQueueIndex_t index) { return queue->data[(queue->start + index) % queue->length]; }
 | 
			
		||||
uint8_t bytequeue_get(byteQueue_t* queue, byteQueueIndex_t index) {
 | 
			
		||||
    return queue->data[(queue->start + index) % queue->length];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// we just update the start index to remove elements
 | 
			
		||||
void bytequeue_remove(byteQueue_t* queue, byteQueueIndex_t numToRemove) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,9 @@ interrupt_setting_t store_and_clear_interrupt(void) {
 | 
			
		|||
    return sreg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void restore_interrupt_setting(interrupt_setting_t setting) { SREG = setting; }
 | 
			
		||||
void restore_interrupt_setting(interrupt_setting_t setting) {
 | 
			
		||||
    SREG = setting;
 | 
			
		||||
}
 | 
			
		||||
#elif defined(__arm__)
 | 
			
		||||
#    include <ch.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -39,5 +41,7 @@ interrupt_setting_t store_and_clear_interrupt(void) {
 | 
			
		|||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void restore_interrupt_setting(interrupt_setting_t setting) { chSysUnlock(); }
 | 
			
		||||
void restore_interrupt_setting(interrupt_setting_t setting) {
 | 
			
		||||
    chSysUnlock();
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@
 | 
			
		|||
// along with avr-midi.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
#include "midi.h"
 | 
			
		||||
#include <string.h>  //for memcpy
 | 
			
		||||
#include <string.h> //for memcpy
 | 
			
		||||
 | 
			
		||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -25,9 +25,13 @@
 | 
			
		|||
#    define NULL 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
bool midi_is_statusbyte(uint8_t theByte) { return (bool)(theByte & MIDI_STATUSMASK); }
 | 
			
		||||
bool midi_is_statusbyte(uint8_t theByte) {
 | 
			
		||||
    return (bool)(theByte & MIDI_STATUSMASK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool midi_is_realtime(uint8_t theByte) { return (theByte >= MIDI_CLOCK); }
 | 
			
		||||
bool midi_is_realtime(uint8_t theByte) {
 | 
			
		||||
    return (theByte >= MIDI_CLOCK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
midi_packet_length_t midi_packet_length(uint8_t status) {
 | 
			
		||||
    switch (status & 0xF0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -83,7 +87,9 @@ void midi_send_noteoff(MidiDevice* device, uint8_t chan, uint8_t num, uint8_t ve
 | 
			
		|||
    device->send_func(device, 3, MIDI_NOTEOFF | (chan & MIDI_CHANMASK), num & 0x7F, vel & 0x7F);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_send_aftertouch(MidiDevice* device, uint8_t chan, uint8_t note_num, uint8_t amt) { device->send_func(device, 3, MIDI_AFTERTOUCH | (chan & MIDI_CHANMASK), note_num & 0x7F, amt & 0x7F); }
 | 
			
		||||
void midi_send_aftertouch(MidiDevice* device, uint8_t chan, uint8_t note_num, uint8_t amt) {
 | 
			
		||||
    device->send_func(device, 3, MIDI_AFTERTOUCH | (chan & MIDI_CHANMASK), note_num & 0x7F, amt & 0x7F);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// XXX does this work right?
 | 
			
		||||
// amt in range -0x2000, 0x1fff
 | 
			
		||||
| 
						 | 
				
			
			@ -102,34 +108,62 @@ void midi_send_pitchbend(MidiDevice* device, uint8_t chan, int16_t amt) {
 | 
			
		|||
    device->send_func(device, 3, MIDI_PITCHBEND | (chan & MIDI_CHANMASK), uAmt & 0x7F, (uAmt >> 7) & 0x7F);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_send_programchange(MidiDevice* device, uint8_t chan, uint8_t num) { device->send_func(device, 2, MIDI_PROGCHANGE | (chan & MIDI_CHANMASK), num & 0x7F, 0); }
 | 
			
		||||
void midi_send_programchange(MidiDevice* device, uint8_t chan, uint8_t num) {
 | 
			
		||||
    device->send_func(device, 2, MIDI_PROGCHANGE | (chan & MIDI_CHANMASK), num & 0x7F, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_send_channelpressure(MidiDevice* device, uint8_t chan, uint8_t amt) { device->send_func(device, 2, MIDI_CHANPRESSURE | (chan & MIDI_CHANMASK), amt & 0x7F, 0); }
 | 
			
		||||
void midi_send_channelpressure(MidiDevice* device, uint8_t chan, uint8_t amt) {
 | 
			
		||||
    device->send_func(device, 2, MIDI_CHANPRESSURE | (chan & MIDI_CHANMASK), amt & 0x7F, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_send_clock(MidiDevice* device) { device->send_func(device, 1, MIDI_CLOCK, 0, 0); }
 | 
			
		||||
void midi_send_clock(MidiDevice* device) {
 | 
			
		||||
    device->send_func(device, 1, MIDI_CLOCK, 0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_send_tick(MidiDevice* device) { device->send_func(device, 1, MIDI_TICK, 0, 0); }
 | 
			
		||||
void midi_send_tick(MidiDevice* device) {
 | 
			
		||||
    device->send_func(device, 1, MIDI_TICK, 0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_send_start(MidiDevice* device) { device->send_func(device, 1, MIDI_START, 0, 0); }
 | 
			
		||||
void midi_send_start(MidiDevice* device) {
 | 
			
		||||
    device->send_func(device, 1, MIDI_START, 0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_send_continue(MidiDevice* device) { device->send_func(device, 1, MIDI_CONTINUE, 0, 0); }
 | 
			
		||||
void midi_send_continue(MidiDevice* device) {
 | 
			
		||||
    device->send_func(device, 1, MIDI_CONTINUE, 0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_send_stop(MidiDevice* device) { device->send_func(device, 1, MIDI_STOP, 0, 0); }
 | 
			
		||||
void midi_send_stop(MidiDevice* device) {
 | 
			
		||||
    device->send_func(device, 1, MIDI_STOP, 0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_send_activesense(MidiDevice* device) { device->send_func(device, 1, MIDI_ACTIVESENSE, 0, 0); }
 | 
			
		||||
void midi_send_activesense(MidiDevice* device) {
 | 
			
		||||
    device->send_func(device, 1, MIDI_ACTIVESENSE, 0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_send_reset(MidiDevice* device) { device->send_func(device, 1, MIDI_RESET, 0, 0); }
 | 
			
		||||
void midi_send_reset(MidiDevice* device) {
 | 
			
		||||
    device->send_func(device, 1, MIDI_RESET, 0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_send_tcquarterframe(MidiDevice* device, uint8_t time) { device->send_func(device, 2, MIDI_TC_QUARTERFRAME, time & 0x7F, 0); }
 | 
			
		||||
void midi_send_tcquarterframe(MidiDevice* device, uint8_t time) {
 | 
			
		||||
    device->send_func(device, 2, MIDI_TC_QUARTERFRAME, time & 0x7F, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// XXX is this right?
 | 
			
		||||
void midi_send_songposition(MidiDevice* device, uint16_t pos) { device->send_func(device, 3, MIDI_SONGPOSITION, pos & 0x7F, (pos >> 7) & 0x7F); }
 | 
			
		||||
void midi_send_songposition(MidiDevice* device, uint16_t pos) {
 | 
			
		||||
    device->send_func(device, 3, MIDI_SONGPOSITION, pos & 0x7F, (pos >> 7) & 0x7F);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_send_songselect(MidiDevice* device, uint8_t song) { device->send_func(device, 2, MIDI_SONGSELECT, song & 0x7F, 0); }
 | 
			
		||||
void midi_send_songselect(MidiDevice* device, uint8_t song) {
 | 
			
		||||
    device->send_func(device, 2, MIDI_SONGSELECT, song & 0x7F, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_send_tunerequest(MidiDevice* device) { device->send_func(device, 1, MIDI_TUNEREQUEST, 0, 0); }
 | 
			
		||||
void midi_send_tunerequest(MidiDevice* device) {
 | 
			
		||||
    device->send_func(device, 1, MIDI_TUNEREQUEST, 0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_send_byte(MidiDevice* device, uint8_t b) { device->send_func(device, 1, b, 0, 0); }
 | 
			
		||||
void midi_send_byte(MidiDevice* device, uint8_t b) {
 | 
			
		||||
    device->send_func(device, 1, b, 0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_send_data(MidiDevice* device, uint16_t count, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
 | 
			
		||||
    // ensure that the count passed along is always 3 or lower
 | 
			
		||||
| 
						 | 
				
			
			@ -150,32 +184,62 @@ void midi_send_array(MidiDevice* device, uint16_t count, uint8_t* array) {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_register_cc_callback(MidiDevice* device, midi_three_byte_func_t func) { device->input_cc_callback = func; }
 | 
			
		||||
void midi_register_cc_callback(MidiDevice* device, midi_three_byte_func_t func) {
 | 
			
		||||
    device->input_cc_callback = func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_register_noteon_callback(MidiDevice* device, midi_three_byte_func_t func) { device->input_noteon_callback = func; }
 | 
			
		||||
void midi_register_noteon_callback(MidiDevice* device, midi_three_byte_func_t func) {
 | 
			
		||||
    device->input_noteon_callback = func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_register_noteoff_callback(MidiDevice* device, midi_three_byte_func_t func) { device->input_noteoff_callback = func; }
 | 
			
		||||
void midi_register_noteoff_callback(MidiDevice* device, midi_three_byte_func_t func) {
 | 
			
		||||
    device->input_noteoff_callback = func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_register_aftertouch_callback(MidiDevice* device, midi_three_byte_func_t func) { device->input_aftertouch_callback = func; }
 | 
			
		||||
void midi_register_aftertouch_callback(MidiDevice* device, midi_three_byte_func_t func) {
 | 
			
		||||
    device->input_aftertouch_callback = func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_register_pitchbend_callback(MidiDevice* device, midi_three_byte_func_t func) { device->input_pitchbend_callback = func; }
 | 
			
		||||
void midi_register_pitchbend_callback(MidiDevice* device, midi_three_byte_func_t func) {
 | 
			
		||||
    device->input_pitchbend_callback = func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_register_songposition_callback(MidiDevice* device, midi_three_byte_func_t func) { device->input_songposition_callback = func; }
 | 
			
		||||
void midi_register_songposition_callback(MidiDevice* device, midi_three_byte_func_t func) {
 | 
			
		||||
    device->input_songposition_callback = func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_register_progchange_callback(MidiDevice* device, midi_two_byte_func_t func) { device->input_progchange_callback = func; }
 | 
			
		||||
void midi_register_progchange_callback(MidiDevice* device, midi_two_byte_func_t func) {
 | 
			
		||||
    device->input_progchange_callback = func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_register_chanpressure_callback(MidiDevice* device, midi_two_byte_func_t func) { device->input_chanpressure_callback = func; }
 | 
			
		||||
void midi_register_chanpressure_callback(MidiDevice* device, midi_two_byte_func_t func) {
 | 
			
		||||
    device->input_chanpressure_callback = func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_register_songselect_callback(MidiDevice* device, midi_two_byte_func_t func) { device->input_songselect_callback = func; }
 | 
			
		||||
void midi_register_songselect_callback(MidiDevice* device, midi_two_byte_func_t func) {
 | 
			
		||||
    device->input_songselect_callback = func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_register_tc_quarterframe_callback(MidiDevice* device, midi_two_byte_func_t func) { device->input_tc_quarterframe_callback = func; }
 | 
			
		||||
void midi_register_tc_quarterframe_callback(MidiDevice* device, midi_two_byte_func_t func) {
 | 
			
		||||
    device->input_tc_quarterframe_callback = func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_register_realtime_callback(MidiDevice* device, midi_one_byte_func_t func) { device->input_realtime_callback = func; }
 | 
			
		||||
void midi_register_realtime_callback(MidiDevice* device, midi_one_byte_func_t func) {
 | 
			
		||||
    device->input_realtime_callback = func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_register_tunerequest_callback(MidiDevice* device, midi_one_byte_func_t func) { device->input_tunerequest_callback = func; }
 | 
			
		||||
void midi_register_tunerequest_callback(MidiDevice* device, midi_one_byte_func_t func) {
 | 
			
		||||
    device->input_tunerequest_callback = func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_register_sysex_callback(MidiDevice* device, midi_sysex_func_t func) { device->input_sysex_callback = func; }
 | 
			
		||||
void midi_register_sysex_callback(MidiDevice* device, midi_sysex_func_t func) {
 | 
			
		||||
    device->input_sysex_callback = func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_register_fallthrough_callback(MidiDevice* device, midi_var_byte_func_t func) { device->input_fallthrough_callback = func; }
 | 
			
		||||
void midi_register_fallthrough_callback(MidiDevice* device, midi_var_byte_func_t func) {
 | 
			
		||||
    device->input_fallthrough_callback = func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_register_catchall_callback(MidiDevice* device, midi_var_byte_func_t func) { device->input_catchall_callback = func; }
 | 
			
		||||
void midi_register_catchall_callback(MidiDevice* device, midi_var_byte_func_t func) {
 | 
			
		||||
    device->input_catchall_callback = func;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,7 +48,7 @@ extern "C" {
 | 
			
		|||
 *
 | 
			
		||||
 * @param device the device to initialize
 | 
			
		||||
 */
 | 
			
		||||
void midi_device_init(MidiDevice* device);  // [implementation in midi_device.c]
 | 
			
		||||
void midi_device_init(MidiDevice* device); // [implementation in midi_device.c]
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Process input data
 | 
			
		||||
| 
						 | 
				
			
			@ -58,7 +58,7 @@ void midi_device_init(MidiDevice* device);  // [implementation in midi_device.c]
 | 
			
		|||
 *
 | 
			
		||||
 * @param device the device to process
 | 
			
		||||
 */
 | 
			
		||||
void midi_device_process(MidiDevice* device);  // [implementation in midi_device.c]
 | 
			
		||||
void midi_device_process(MidiDevice* device); // [implementation in midi_device.c]
 | 
			
		||||
 | 
			
		||||
/**@}*/
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -115,7 +115,7 @@ void midi_send_aftertouch(MidiDevice* device, uint8_t chan, uint8_t note_num, ui
 | 
			
		|||
 * @param chan the channel to send on, 0-15
 | 
			
		||||
 * @param amt the bend amount range: -8192..8191, 0 means no bend
 | 
			
		||||
 */
 | 
			
		||||
void midi_send_pitchbend(MidiDevice* device, uint8_t chan, int16_t amt);  // range -8192, 8191
 | 
			
		||||
void midi_send_pitchbend(MidiDevice* device, uint8_t chan, int16_t amt); // range -8192, 8191
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Send a program change message via the given device.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,12 +60,17 @@ void midi_device_init(MidiDevice* device) {
 | 
			
		|||
 | 
			
		||||
void midi_device_input(MidiDevice* device, uint8_t cnt, uint8_t* input) {
 | 
			
		||||
    uint8_t i;
 | 
			
		||||
    for (i = 0; i < cnt; i++) bytequeue_enqueue(&device->input_queue, input[i]);
 | 
			
		||||
    for (i = 0; i < cnt; i++)
 | 
			
		||||
        bytequeue_enqueue(&device->input_queue, input[i]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_device_set_send_func(MidiDevice* device, midi_var_byte_func_t send_func) { device->send_func = send_func; }
 | 
			
		||||
void midi_device_set_send_func(MidiDevice* device, midi_var_byte_func_t send_func) {
 | 
			
		||||
    device->send_func = send_func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_device_set_pre_input_process_func(MidiDevice* device, midi_no_byte_func_t pre_process_func) { device->pre_input_process_callback = pre_process_func; }
 | 
			
		||||
void midi_device_set_pre_input_process_func(MidiDevice* device, midi_no_byte_func_t pre_process_func) {
 | 
			
		||||
    device->pre_input_process_callback = pre_process_func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_device_process(MidiDevice* device) {
 | 
			
		||||
    // call the pre_input_process_callback if there is one
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,7 +50,7 @@ static void usb_send_func(MidiDevice* device, uint16_t cnt, uint8_t byte0, uint8
 | 
			
		|||
                    event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                return;  // invalid cnt
 | 
			
		||||
                return; // invalid cnt
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        // deal with 'system common' messages
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ uint16_t sysex_decoded_length(uint16_t encoded_length) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
uint16_t sysex_encode(uint8_t *encoded, const uint8_t *source, const uint16_t length) {
 | 
			
		||||
    uint16_t encoded_full = length / 7;  // number of full 8 byte sections from 7 bytes of input
 | 
			
		||||
    uint16_t encoded_full = length / 7; // number of full 8 byte sections from 7 bytes of input
 | 
			
		||||
    uint16_t i, j;
 | 
			
		||||
 | 
			
		||||
    // fill out the fully encoded sections
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -200,7 +200,7 @@ enum usb_interfaces {
 | 
			
		|||
 * Endpoint numbers
 | 
			
		||||
 */
 | 
			
		||||
enum usb_endpoints {
 | 
			
		||||
    __unused_epnum__ = NEXT_EPNUM,  // Endpoint numbering starts at 1
 | 
			
		||||
    __unused_epnum__ = NEXT_EPNUM, // Endpoint numbering starts at 1
 | 
			
		||||
 | 
			
		||||
#ifndef KEYBOARD_SHARED_EP
 | 
			
		||||
    KEYBOARD_IN_EPNUM = NEXT_EPNUM,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,9 @@
 | 
			
		|||
 | 
			
		||||
enum usb_device_state usb_device_state = USB_DEVICE_STATE_NO_INIT;
 | 
			
		||||
 | 
			
		||||
__attribute__((weak)) void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state) { notify_usb_device_state_change_user(usb_device_state); }
 | 
			
		||||
__attribute__((weak)) void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state) {
 | 
			
		||||
    notify_usb_device_state_change_user(usb_device_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((weak)) void notify_usb_device_state_change_user(enum usb_device_state usb_device_state) {}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,10 +27,10 @@ void usb_device_state_set_reset(void);
 | 
			
		|||
void usb_device_state_init(void);
 | 
			
		||||
 | 
			
		||||
enum usb_device_state {
 | 
			
		||||
    USB_DEVICE_STATE_NO_INIT    = 0,  // We're in this state before calling usb_device_state_init()
 | 
			
		||||
    USB_DEVICE_STATE_INIT       = 1,  // Can consume up to 100mA
 | 
			
		||||
    USB_DEVICE_STATE_CONFIGURED = 2,  // Can consume up to what is specified in configuration descriptor, typically 500mA
 | 
			
		||||
    USB_DEVICE_STATE_SUSPEND    = 3   // Can consume only suspend current
 | 
			
		||||
    USB_DEVICE_STATE_NO_INIT    = 0, // We're in this state before calling usb_device_state_init()
 | 
			
		||||
    USB_DEVICE_STATE_INIT       = 1, // Can consume up to 100mA
 | 
			
		||||
    USB_DEVICE_STATE_CONFIGURED = 2, // Can consume up to what is specified in configuration descriptor, typically 500mA
 | 
			
		||||
    USB_DEVICE_STATE_SUSPEND    = 3  // Can consume only suspend current
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern enum usb_device_state usb_device_state;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,9 @@
 | 
			
		|||
#include "usb_util.h"
 | 
			
		||||
 | 
			
		||||
__attribute__((weak)) void usb_disconnect(void) {}
 | 
			
		||||
__attribute__((weak)) bool usb_connected_state(void) { return true; }
 | 
			
		||||
__attribute__((weak)) bool usb_connected_state(void) {
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
__attribute__((weak)) bool usb_vbus_state(void) {
 | 
			
		||||
#ifdef USB_VBUS_PIN
 | 
			
		||||
    setPinInput(USB_VBUS_PIN);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -97,7 +97,9 @@ static void vusb_wakeup(void) {
 | 
			
		|||
 *
 | 
			
		||||
 * FIXME: Needs doc
 | 
			
		||||
 */
 | 
			
		||||
static void setup_usb(void) { initForUsbConnectivity(); }
 | 
			
		||||
static void setup_usb(void) {
 | 
			
		||||
    initForUsbConnectivity();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t sof_timer = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,9 @@
 | 
			
		|||
#include <usbdrv/usbdrv.h>
 | 
			
		||||
#include "usb_util.h"
 | 
			
		||||
 | 
			
		||||
void usb_disconnect(void) { usbDeviceDisconnect(); }
 | 
			
		||||
void usb_disconnect(void) {
 | 
			
		||||
    usbDeviceDisconnect();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool usb_connected_state(void) {
 | 
			
		||||
    usbPoll();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -230,9 +230,13 @@ static void    send_programmable_button(uint32_t data);
 | 
			
		|||
 | 
			
		||||
static host_driver_t driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer, send_programmable_button};
 | 
			
		||||
 | 
			
		||||
host_driver_t *vusb_driver(void) { return &driver; }
 | 
			
		||||
host_driver_t *vusb_driver(void) {
 | 
			
		||||
    return &driver;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint8_t keyboard_leds(void) { return keyboard_led_state; }
 | 
			
		||||
static uint8_t keyboard_leds(void) {
 | 
			
		||||
    return keyboard_led_state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void send_keyboard(report_keyboard_t *report) {
 | 
			
		||||
    uint8_t next = (kbuf_head + 1) % KBUF_SIZE;
 | 
			
		||||
| 
						 | 
				
			
			@ -348,7 +352,7 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) {
 | 
			
		|||
                last_req.kind = SET_LED;
 | 
			
		||||
                last_req.len  = rq->wLength.word;
 | 
			
		||||
            }
 | 
			
		||||
            return USB_NO_MSG;  // to get data in usbFunctionWrite
 | 
			
		||||
            return USB_NO_MSG; // to get data in usbFunctionWrite
 | 
			
		||||
        } else {
 | 
			
		||||
            dprint("UNKNOWN:");
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -410,47 +414,47 @@ const PROGMEM uchar shared_hid_report[] = {
 | 
			
		|||
#else
 | 
			
		||||
const PROGMEM uchar keyboard_hid_report[] = {
 | 
			
		||||
#endif
 | 
			
		||||
    0x05, 0x01,  // Usage Page (Generic Desktop)
 | 
			
		||||
    0x09, 0x06,  // Usage (Keyboard)
 | 
			
		||||
    0xA1, 0x01,  // Collection (Application)
 | 
			
		||||
    0x05, 0x01, // Usage Page (Generic Desktop)
 | 
			
		||||
    0x09, 0x06, // Usage (Keyboard)
 | 
			
		||||
    0xA1, 0x01, // Collection (Application)
 | 
			
		||||
#ifdef KEYBOARD_SHARED_EP
 | 
			
		||||
    0x85, REPORT_ID_KEYBOARD,  // Report ID
 | 
			
		||||
    0x85, REPORT_ID_KEYBOARD, // Report ID
 | 
			
		||||
#endif
 | 
			
		||||
    // Modifiers (8 bits)
 | 
			
		||||
    0x05, 0x07,  //   Usage Page (Keyboard/Keypad)
 | 
			
		||||
    0x19, 0xE0,  //   Usage Minimum (Keyboard Left Control)
 | 
			
		||||
    0x29, 0xE7,  //   Usage Maximum (Keyboard Right GUI)
 | 
			
		||||
    0x15, 0x00,  //   Logical Minimum (0)
 | 
			
		||||
    0x25, 0x01,  //   Logical Maximum (1)
 | 
			
		||||
    0x95, 0x08,  //   Report Count (8)
 | 
			
		||||
    0x75, 0x01,  //   Report Size (1)
 | 
			
		||||
    0x81, 0x02,  //   Input (Data, Variable, Absolute)
 | 
			
		||||
    0x05, 0x07, //   Usage Page (Keyboard/Keypad)
 | 
			
		||||
    0x19, 0xE0, //   Usage Minimum (Keyboard Left Control)
 | 
			
		||||
    0x29, 0xE7, //   Usage Maximum (Keyboard Right GUI)
 | 
			
		||||
    0x15, 0x00, //   Logical Minimum (0)
 | 
			
		||||
    0x25, 0x01, //   Logical Maximum (1)
 | 
			
		||||
    0x95, 0x08, //   Report Count (8)
 | 
			
		||||
    0x75, 0x01, //   Report Size (1)
 | 
			
		||||
    0x81, 0x02, //   Input (Data, Variable, Absolute)
 | 
			
		||||
    // Reserved (1 byte)
 | 
			
		||||
    0x95, 0x01,  //   Report Count (1)
 | 
			
		||||
    0x75, 0x08,  //   Report Size (8)
 | 
			
		||||
    0x81, 0x03,  //   Input (Constant)
 | 
			
		||||
    0x95, 0x01, //   Report Count (1)
 | 
			
		||||
    0x75, 0x08, //   Report Size (8)
 | 
			
		||||
    0x81, 0x03, //   Input (Constant)
 | 
			
		||||
    // Keycodes (6 bytes)
 | 
			
		||||
    0x05, 0x07,        //   Usage Page (Keyboard/Keypad)
 | 
			
		||||
    0x19, 0x00,        //   Usage Minimum (0)
 | 
			
		||||
    0x29, 0xFF,        //   Usage Maximum (255)
 | 
			
		||||
    0x15, 0x00,        //   Logical Minimum (0)
 | 
			
		||||
    0x26, 0xFF, 0x00,  //   Logical Maximum (255)
 | 
			
		||||
    0x95, 0x06,        //   Report Count (6)
 | 
			
		||||
    0x75, 0x08,        //   Report Size (8)
 | 
			
		||||
    0x81, 0x00,        //   Input (Data, Array, Absolute)
 | 
			
		||||
    0x05, 0x07,       //   Usage Page (Keyboard/Keypad)
 | 
			
		||||
    0x19, 0x00,       //   Usage Minimum (0)
 | 
			
		||||
    0x29, 0xFF,       //   Usage Maximum (255)
 | 
			
		||||
    0x15, 0x00,       //   Logical Minimum (0)
 | 
			
		||||
    0x26, 0xFF, 0x00, //   Logical Maximum (255)
 | 
			
		||||
    0x95, 0x06,       //   Report Count (6)
 | 
			
		||||
    0x75, 0x08,       //   Report Size (8)
 | 
			
		||||
    0x81, 0x00,       //   Input (Data, Array, Absolute)
 | 
			
		||||
 | 
			
		||||
    // Status LEDs (5 bits)
 | 
			
		||||
    0x05, 0x08,  //   Usage Page (LED)
 | 
			
		||||
    0x19, 0x01,  //   Usage Minimum (Num Lock)
 | 
			
		||||
    0x29, 0x05,  //   Usage Maximum (Kana)
 | 
			
		||||
    0x95, 0x05,  //   Report Count (5)
 | 
			
		||||
    0x75, 0x01,  //   Report Size (1)
 | 
			
		||||
    0x91, 0x02,  //   Output (Data, Variable, Absolute)
 | 
			
		||||
    0x05, 0x08, //   Usage Page (LED)
 | 
			
		||||
    0x19, 0x01, //   Usage Minimum (Num Lock)
 | 
			
		||||
    0x29, 0x05, //   Usage Maximum (Kana)
 | 
			
		||||
    0x95, 0x05, //   Report Count (5)
 | 
			
		||||
    0x75, 0x01, //   Report Size (1)
 | 
			
		||||
    0x91, 0x02, //   Output (Data, Variable, Absolute)
 | 
			
		||||
    // LED padding (3 bits)
 | 
			
		||||
    0x95, 0x01,  //   Report Count (1)
 | 
			
		||||
    0x75, 0x03,  //   Report Size (3)
 | 
			
		||||
    0x91, 0x03,  //   Output (Constant)
 | 
			
		||||
    0xC0,        // End Collection
 | 
			
		||||
    0x95, 0x01, //   Report Count (1)
 | 
			
		||||
    0x75, 0x03, //   Report Size (3)
 | 
			
		||||
    0x91, 0x03, //   Output (Constant)
 | 
			
		||||
    0xC0,       // End Collection
 | 
			
		||||
#ifndef KEYBOARD_SHARED_EP
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -462,135 +466,135 @@ const PROGMEM uchar shared_hid_report[] = {
 | 
			
		|||
 | 
			
		||||
#ifdef MOUSE_ENABLE
 | 
			
		||||
    // Mouse report descriptor
 | 
			
		||||
    0x05, 0x01,             // Usage Page (Generic Desktop)
 | 
			
		||||
    0x09, 0x02,             // Usage (Mouse)
 | 
			
		||||
    0xA1, 0x01,             // Collection (Application)
 | 
			
		||||
    0x85, REPORT_ID_MOUSE,  //   Report ID
 | 
			
		||||
    0x09, 0x01,             //   Usage (Pointer)
 | 
			
		||||
    0xA1, 0x00,             //   Collection (Physical)
 | 
			
		||||
    0x05, 0x01,            // Usage Page (Generic Desktop)
 | 
			
		||||
    0x09, 0x02,            // Usage (Mouse)
 | 
			
		||||
    0xA1, 0x01,            // Collection (Application)
 | 
			
		||||
    0x85, REPORT_ID_MOUSE, //   Report ID
 | 
			
		||||
    0x09, 0x01,            //   Usage (Pointer)
 | 
			
		||||
    0xA1, 0x00,            //   Collection (Physical)
 | 
			
		||||
    // Buttons (8 bits)
 | 
			
		||||
    0x05, 0x09,  //     Usage Page (Button)
 | 
			
		||||
    0x19, 0x01,  //     Usage Minimum (Button 1)
 | 
			
		||||
    0x29, 0x08,  //     Usage Maximum (Button 8)
 | 
			
		||||
    0x15, 0x00,  //     Logical Minimum (0)
 | 
			
		||||
    0x25, 0x01,  //     Logical Maximum (1)
 | 
			
		||||
    0x95, 0x08,  //     Report Count (8)
 | 
			
		||||
    0x75, 0x01,  //     Report Size (1)
 | 
			
		||||
    0x81, 0x02,  //     Input (Data, Variable, Absolute)
 | 
			
		||||
    0x05, 0x09, //     Usage Page (Button)
 | 
			
		||||
    0x19, 0x01, //     Usage Minimum (Button 1)
 | 
			
		||||
    0x29, 0x08, //     Usage Maximum (Button 8)
 | 
			
		||||
    0x15, 0x00, //     Logical Minimum (0)
 | 
			
		||||
    0x25, 0x01, //     Logical Maximum (1)
 | 
			
		||||
    0x95, 0x08, //     Report Count (8)
 | 
			
		||||
    0x75, 0x01, //     Report Size (1)
 | 
			
		||||
    0x81, 0x02, //     Input (Data, Variable, Absolute)
 | 
			
		||||
 | 
			
		||||
    // X/Y position (2 bytes)
 | 
			
		||||
    0x05, 0x01,  //     Usage Page (Generic Desktop)
 | 
			
		||||
    0x09, 0x30,  //     Usage (X)
 | 
			
		||||
    0x09, 0x31,  //     Usage (Y)
 | 
			
		||||
    0x15, 0x81,  //     Logical Minimum (-127)
 | 
			
		||||
    0x25, 0x7F,  //     Logical Maximum (127)
 | 
			
		||||
    0x95, 0x02,  //     Report Count (2)
 | 
			
		||||
    0x75, 0x08,  //     Report Size (8)
 | 
			
		||||
    0x81, 0x06,  //     Input (Data, Variable, Relative)
 | 
			
		||||
    0x05, 0x01, //     Usage Page (Generic Desktop)
 | 
			
		||||
    0x09, 0x30, //     Usage (X)
 | 
			
		||||
    0x09, 0x31, //     Usage (Y)
 | 
			
		||||
    0x15, 0x81, //     Logical Minimum (-127)
 | 
			
		||||
    0x25, 0x7F, //     Logical Maximum (127)
 | 
			
		||||
    0x95, 0x02, //     Report Count (2)
 | 
			
		||||
    0x75, 0x08, //     Report Size (8)
 | 
			
		||||
    0x81, 0x06, //     Input (Data, Variable, Relative)
 | 
			
		||||
 | 
			
		||||
    // Vertical wheel (1 byte)
 | 
			
		||||
    0x09, 0x38,  //     Usage (Wheel)
 | 
			
		||||
    0x15, 0x81,  //     Logical Minimum (-127)
 | 
			
		||||
    0x25, 0x7F,  //     Logical Maximum (127)
 | 
			
		||||
    0x95, 0x01,  //     Report Count (1)
 | 
			
		||||
    0x75, 0x08,  //     Report Size (8)
 | 
			
		||||
    0x81, 0x06,  //     Input (Data, Variable, Relative)
 | 
			
		||||
    0x09, 0x38, //     Usage (Wheel)
 | 
			
		||||
    0x15, 0x81, //     Logical Minimum (-127)
 | 
			
		||||
    0x25, 0x7F, //     Logical Maximum (127)
 | 
			
		||||
    0x95, 0x01, //     Report Count (1)
 | 
			
		||||
    0x75, 0x08, //     Report Size (8)
 | 
			
		||||
    0x81, 0x06, //     Input (Data, Variable, Relative)
 | 
			
		||||
    // Horizontal wheel (1 byte)
 | 
			
		||||
    0x05, 0x0C,        //     Usage Page (Consumer)
 | 
			
		||||
    0x0A, 0x38, 0x02,  //     Usage (AC Pan)
 | 
			
		||||
    0x15, 0x81,        //     Logical Minimum (-127)
 | 
			
		||||
    0x25, 0x7F,        //     Logical Maximum (127)
 | 
			
		||||
    0x95, 0x01,        //     Report Count (1)
 | 
			
		||||
    0x75, 0x08,        //     Report Size (8)
 | 
			
		||||
    0x81, 0x06,        //     Input (Data, Variable, Relative)
 | 
			
		||||
    0xC0,              //   End Collection
 | 
			
		||||
    0xC0,              // End Collection
 | 
			
		||||
    0x05, 0x0C,       //     Usage Page (Consumer)
 | 
			
		||||
    0x0A, 0x38, 0x02, //     Usage (AC Pan)
 | 
			
		||||
    0x15, 0x81,       //     Logical Minimum (-127)
 | 
			
		||||
    0x25, 0x7F,       //     Logical Maximum (127)
 | 
			
		||||
    0x95, 0x01,       //     Report Count (1)
 | 
			
		||||
    0x75, 0x08,       //     Report Size (8)
 | 
			
		||||
    0x81, 0x06,       //     Input (Data, Variable, Relative)
 | 
			
		||||
    0xC0,             //   End Collection
 | 
			
		||||
    0xC0,             // End Collection
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EXTRAKEY_ENABLE
 | 
			
		||||
    // Extrakeys report descriptor
 | 
			
		||||
    0x05, 0x01,              // Usage Page (Generic Desktop)
 | 
			
		||||
    0x09, 0x80,              // Usage (System Control)
 | 
			
		||||
    0xA1, 0x01,              // Collection (Application)
 | 
			
		||||
    0x85, REPORT_ID_SYSTEM,  //   Report ID
 | 
			
		||||
    0x19, 0x01,              //   Usage Minimum (Pointer)
 | 
			
		||||
    0x2A, 0xB7, 0x00,        //   Usage Maximum (System Display LCD Autoscale)
 | 
			
		||||
    0x15, 0x01,              //   Logical Minimum
 | 
			
		||||
    0x26, 0xB7, 0x00,        //   Logical Maximum
 | 
			
		||||
    0x95, 0x01,              //   Report Count (1)
 | 
			
		||||
    0x75, 0x10,              //   Report Size (16)
 | 
			
		||||
    0x81, 0x00,              //   Input (Data, Array, Absolute)
 | 
			
		||||
    0xC0,                    // End Collection
 | 
			
		||||
    0x05, 0x01,             // Usage Page (Generic Desktop)
 | 
			
		||||
    0x09, 0x80,             // Usage (System Control)
 | 
			
		||||
    0xA1, 0x01,             // Collection (Application)
 | 
			
		||||
    0x85, REPORT_ID_SYSTEM, //   Report ID
 | 
			
		||||
    0x19, 0x01,             //   Usage Minimum (Pointer)
 | 
			
		||||
    0x2A, 0xB7, 0x00,       //   Usage Maximum (System Display LCD Autoscale)
 | 
			
		||||
    0x15, 0x01,             //   Logical Minimum
 | 
			
		||||
    0x26, 0xB7, 0x00,       //   Logical Maximum
 | 
			
		||||
    0x95, 0x01,             //   Report Count (1)
 | 
			
		||||
    0x75, 0x10,             //   Report Size (16)
 | 
			
		||||
    0x81, 0x00,             //   Input (Data, Array, Absolute)
 | 
			
		||||
    0xC0,                   // End Collection
 | 
			
		||||
 | 
			
		||||
    0x05, 0x0C,                // Usage Page (Consumer)
 | 
			
		||||
    0x09, 0x01,                // Usage (Consumer Control)
 | 
			
		||||
    0xA1, 0x01,                // Collection (Application)
 | 
			
		||||
    0x85, REPORT_ID_CONSUMER,  //   Report ID
 | 
			
		||||
    0x19, 0x01,                //   Usage Minimum (Consumer Control)
 | 
			
		||||
    0x2A, 0xA0, 0x02,          //   Usage Maximum (AC Desktop Show All Applications)
 | 
			
		||||
    0x15, 0x01,                //   Logical Minimum
 | 
			
		||||
    0x26, 0xA0, 0x02,          //   Logical Maximum
 | 
			
		||||
    0x95, 0x01,                //   Report Count (1)
 | 
			
		||||
    0x75, 0x10,                //   Report Size (16)
 | 
			
		||||
    0x81, 0x00,                //   Input (Data, Array, Absolute)
 | 
			
		||||
    0xC0,                      // End Collection
 | 
			
		||||
    0x05, 0x0C,               // Usage Page (Consumer)
 | 
			
		||||
    0x09, 0x01,               // Usage (Consumer Control)
 | 
			
		||||
    0xA1, 0x01,               // Collection (Application)
 | 
			
		||||
    0x85, REPORT_ID_CONSUMER, //   Report ID
 | 
			
		||||
    0x19, 0x01,               //   Usage Minimum (Consumer Control)
 | 
			
		||||
    0x2A, 0xA0, 0x02,         //   Usage Maximum (AC Desktop Show All Applications)
 | 
			
		||||
    0x15, 0x01,               //   Logical Minimum
 | 
			
		||||
    0x26, 0xA0, 0x02,         //   Logical Maximum
 | 
			
		||||
    0x95, 0x01,               //   Report Count (1)
 | 
			
		||||
    0x75, 0x10,               //   Report Size (16)
 | 
			
		||||
    0x81, 0x00,               //   Input (Data, Array, Absolute)
 | 
			
		||||
    0xC0,                     // End Collection
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef DIGITIZER_ENABLE
 | 
			
		||||
    // Digitizer report descriptor
 | 
			
		||||
    0x05, 0x0D,                 // Usage Page (Digitizers)
 | 
			
		||||
    0x09, 0x01,                 // Usage (Digitizer)
 | 
			
		||||
    0xA1, 0x01,                 // Collection (Application)
 | 
			
		||||
    0x85, REPORT_ID_DIGITIZER,  //   Report ID
 | 
			
		||||
    0x09, 0x22,                 //   Usage (Finger)
 | 
			
		||||
    0xA1, 0x00,                 //   Collection (Physical)
 | 
			
		||||
    0x05, 0x0D,                // Usage Page (Digitizers)
 | 
			
		||||
    0x09, 0x01,                // Usage (Digitizer)
 | 
			
		||||
    0xA1, 0x01,                // Collection (Application)
 | 
			
		||||
    0x85, REPORT_ID_DIGITIZER, //   Report ID
 | 
			
		||||
    0x09, 0x22,                //   Usage (Finger)
 | 
			
		||||
    0xA1, 0x00,                //   Collection (Physical)
 | 
			
		||||
    // Tip Switch (1 bit)
 | 
			
		||||
    0x09, 0x42,  //     Usage (Tip Switch)
 | 
			
		||||
    0x15, 0x00,  //     Logical Minimum
 | 
			
		||||
    0x25, 0x01,  //     Logical Maximum
 | 
			
		||||
    0x95, 0x01,  //     Report Count (1)
 | 
			
		||||
    0x75, 0x01,  //     Report Size (16)
 | 
			
		||||
    0x81, 0x02,  //     Input (Data, Variable, Absolute)
 | 
			
		||||
    0x09, 0x42, //     Usage (Tip Switch)
 | 
			
		||||
    0x15, 0x00, //     Logical Minimum
 | 
			
		||||
    0x25, 0x01, //     Logical Maximum
 | 
			
		||||
    0x95, 0x01, //     Report Count (1)
 | 
			
		||||
    0x75, 0x01, //     Report Size (16)
 | 
			
		||||
    0x81, 0x02, //     Input (Data, Variable, Absolute)
 | 
			
		||||
    // In Range (1 bit)
 | 
			
		||||
    0x09, 0x32,  //     Usage (In Range)
 | 
			
		||||
    0x81, 0x02,  //     Input (Data, Variable, Absolute)
 | 
			
		||||
    0x09, 0x32, //     Usage (In Range)
 | 
			
		||||
    0x81, 0x02, //     Input (Data, Variable, Absolute)
 | 
			
		||||
    // Padding (6 bits)
 | 
			
		||||
    0x95, 0x06,  //     Report Count (6)
 | 
			
		||||
    0x81, 0x03,  //     Input (Constant)
 | 
			
		||||
    0x95, 0x06, //     Report Count (6)
 | 
			
		||||
    0x81, 0x03, //     Input (Constant)
 | 
			
		||||
 | 
			
		||||
    // X/Y Position (4 bytes)
 | 
			
		||||
    0x05, 0x01,        //     Usage Page (Generic Desktop)
 | 
			
		||||
    0x26, 0xFF, 0x7F,  //     Logical Maximum (32767)
 | 
			
		||||
    0x95, 0x01,        //     Report Count (1)
 | 
			
		||||
    0x75, 0x10,        //     Report Size (16)
 | 
			
		||||
    0x65, 0x33,        //     Unit (Inch, English Linear)
 | 
			
		||||
    0x55, 0x0E,        //     Unit Exponent (-2)
 | 
			
		||||
    0x09, 0x30,        //     Usage (X)
 | 
			
		||||
    0x81, 0x02,        //     Input (Data, Variable, Absolute)
 | 
			
		||||
    0x09, 0x31,        //     Usage (Y)
 | 
			
		||||
    0x81, 0x02,        //     Input (Data, Variable, Absolute)
 | 
			
		||||
    0xC0,              //   End Collection
 | 
			
		||||
    0xC0,              // End Collection
 | 
			
		||||
    0x05, 0x01,       //     Usage Page (Generic Desktop)
 | 
			
		||||
    0x26, 0xFF, 0x7F, //     Logical Maximum (32767)
 | 
			
		||||
    0x95, 0x01,       //     Report Count (1)
 | 
			
		||||
    0x75, 0x10,       //     Report Size (16)
 | 
			
		||||
    0x65, 0x33,       //     Unit (Inch, English Linear)
 | 
			
		||||
    0x55, 0x0E,       //     Unit Exponent (-2)
 | 
			
		||||
    0x09, 0x30,       //     Usage (X)
 | 
			
		||||
    0x81, 0x02,       //     Input (Data, Variable, Absolute)
 | 
			
		||||
    0x09, 0x31,       //     Usage (Y)
 | 
			
		||||
    0x81, 0x02,       //     Input (Data, Variable, Absolute)
 | 
			
		||||
    0xC0,             //   End Collection
 | 
			
		||||
    0xC0,             // End Collection
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef PROGRAMMABLE_BUTTON_ENABLE
 | 
			
		||||
    // Programmable buttons report descriptor
 | 
			
		||||
    0x05, 0x0C,                           // Usage Page (Consumer)
 | 
			
		||||
    0x09, 0x01,                           // Usage (Consumer Control)
 | 
			
		||||
    0xA1, 0x01,                           // Collection (Application)
 | 
			
		||||
    0x85, REPORT_ID_PROGRAMMABLE_BUTTON,  //   Report ID
 | 
			
		||||
    0x09, 0x03,                           //   Usage (Programmable Buttons)
 | 
			
		||||
    0xA1, 0x04,                           //   Collection (Named Array)
 | 
			
		||||
    0x05, 0x09,                           //     Usage Page (Button)
 | 
			
		||||
    0x19, 0x01,                           //     Usage Minimum (Button 1)
 | 
			
		||||
    0x29, 0x20,                           //     Usage Maximum (Button 32)
 | 
			
		||||
    0x15, 0x00,                           //     Logical Minimum (0)
 | 
			
		||||
    0x25, 0x01,                           //     Logical Maximum (1)
 | 
			
		||||
    0x95, 0x20,                           //     Report Count (32)
 | 
			
		||||
    0x75, 0x01,                           //     Report Size (1)
 | 
			
		||||
    0x81, 0x02,                           //     Input (Data, Variable, Absolute)
 | 
			
		||||
    0xC0,                                 //   End Collection
 | 
			
		||||
    0xC0,                                 // End Collection
 | 
			
		||||
    0x05, 0x0C,                          // Usage Page (Consumer)
 | 
			
		||||
    0x09, 0x01,                          // Usage (Consumer Control)
 | 
			
		||||
    0xA1, 0x01,                          // Collection (Application)
 | 
			
		||||
    0x85, REPORT_ID_PROGRAMMABLE_BUTTON, //   Report ID
 | 
			
		||||
    0x09, 0x03,                          //   Usage (Programmable Buttons)
 | 
			
		||||
    0xA1, 0x04,                          //   Collection (Named Array)
 | 
			
		||||
    0x05, 0x09,                          //     Usage Page (Button)
 | 
			
		||||
    0x19, 0x01,                          //     Usage Minimum (Button 1)
 | 
			
		||||
    0x29, 0x20,                          //     Usage Maximum (Button 32)
 | 
			
		||||
    0x15, 0x00,                          //     Logical Minimum (0)
 | 
			
		||||
    0x25, 0x01,                          //     Logical Maximum (1)
 | 
			
		||||
    0x95, 0x20,                          //     Report Count (32)
 | 
			
		||||
    0x75, 0x01,                          //     Report Size (1)
 | 
			
		||||
    0x81, 0x02,                          //     Input (Data, Variable, Absolute)
 | 
			
		||||
    0xC0,                                //   End Collection
 | 
			
		||||
    0xC0,                                // End Collection
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef SHARED_EP_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			@ -599,47 +603,47 @@ const PROGMEM uchar shared_hid_report[] = {
 | 
			
		|||
 | 
			
		||||
#ifdef RAW_ENABLE
 | 
			
		||||
const PROGMEM uchar raw_hid_report[] = {
 | 
			
		||||
    0x06, RAW_USAGE_PAGE_LO, RAW_USAGE_PAGE_HI,  // Usage Page (Vendor Defined)
 | 
			
		||||
    0x09, RAW_USAGE_ID,                          // Usage (Vendor Defined)
 | 
			
		||||
    0xA1, 0x01,                                  // Collection (Application)
 | 
			
		||||
    0x06, RAW_USAGE_PAGE_LO, RAW_USAGE_PAGE_HI, // Usage Page (Vendor Defined)
 | 
			
		||||
    0x09, RAW_USAGE_ID,                         // Usage (Vendor Defined)
 | 
			
		||||
    0xA1, 0x01,                                 // Collection (Application)
 | 
			
		||||
    // Data to host
 | 
			
		||||
    0x09, 0x62,             //   Usage (Vendor Defined)
 | 
			
		||||
    0x15, 0x00,             //   Logical Minimum (0)
 | 
			
		||||
    0x26, 0xFF, 0x00,       //   Logical Maximum (255)
 | 
			
		||||
    0x95, RAW_BUFFER_SIZE,  //   Report Count
 | 
			
		||||
    0x75, 0x08,             //   Report Size (8)
 | 
			
		||||
    0x81, 0x02,             //   Input (Data, Variable, Absolute)
 | 
			
		||||
    0x09, 0x62,            //   Usage (Vendor Defined)
 | 
			
		||||
    0x15, 0x00,            //   Logical Minimum (0)
 | 
			
		||||
    0x26, 0xFF, 0x00,      //   Logical Maximum (255)
 | 
			
		||||
    0x95, RAW_BUFFER_SIZE, //   Report Count
 | 
			
		||||
    0x75, 0x08,            //   Report Size (8)
 | 
			
		||||
    0x81, 0x02,            //   Input (Data, Variable, Absolute)
 | 
			
		||||
    // Data from host
 | 
			
		||||
    0x09, 0x63,             //   Usage (Vendor Defined)
 | 
			
		||||
    0x15, 0x00,             //   Logical Minimum (0)
 | 
			
		||||
    0x26, 0xFF, 0x00,       //   Logical Maximum (255)
 | 
			
		||||
    0x95, RAW_BUFFER_SIZE,  //   Report Count
 | 
			
		||||
    0x75, 0x08,             //   Report Size (8)
 | 
			
		||||
    0x91, 0x02,             //   Output (Data, Variable, Absolute)
 | 
			
		||||
    0xC0                    // End Collection
 | 
			
		||||
    0x09, 0x63,            //   Usage (Vendor Defined)
 | 
			
		||||
    0x15, 0x00,            //   Logical Minimum (0)
 | 
			
		||||
    0x26, 0xFF, 0x00,      //   Logical Maximum (255)
 | 
			
		||||
    0x95, RAW_BUFFER_SIZE, //   Report Count
 | 
			
		||||
    0x75, 0x08,            //   Report Size (8)
 | 
			
		||||
    0x91, 0x02,            //   Output (Data, Variable, Absolute)
 | 
			
		||||
    0xC0                   // End Collection
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(CONSOLE_ENABLE)
 | 
			
		||||
const PROGMEM uchar console_hid_report[] = {
 | 
			
		||||
    0x06, 0x31, 0xFF,  // Usage Page (Vendor Defined - PJRC Teensy compatible)
 | 
			
		||||
    0x09, 0x74,        // Usage (Vendor Defined - PJRC Teensy compatible)
 | 
			
		||||
    0xA1, 0x01,        // Collection (Application)
 | 
			
		||||
    0x06, 0x31, 0xFF, // Usage Page (Vendor Defined - PJRC Teensy compatible)
 | 
			
		||||
    0x09, 0x74,       // Usage (Vendor Defined - PJRC Teensy compatible)
 | 
			
		||||
    0xA1, 0x01,       // Collection (Application)
 | 
			
		||||
    // Data to host
 | 
			
		||||
    0x09, 0x75,                 //   Usage (Vendor Defined)
 | 
			
		||||
    0x15, 0x00,                 //   Logical Minimum (0x00)
 | 
			
		||||
    0x26, 0xFF, 0x00,           //   Logical Maximum (0x00FF)
 | 
			
		||||
    0x95, CONSOLE_BUFFER_SIZE,  //   Report Count
 | 
			
		||||
    0x75, 0x08,                 //   Report Size (8)
 | 
			
		||||
    0x81, 0x02,                 //   Input (Data, Variable, Absolute)
 | 
			
		||||
    0x09, 0x75,                //   Usage (Vendor Defined)
 | 
			
		||||
    0x15, 0x00,                //   Logical Minimum (0x00)
 | 
			
		||||
    0x26, 0xFF, 0x00,          //   Logical Maximum (0x00FF)
 | 
			
		||||
    0x95, CONSOLE_BUFFER_SIZE, //   Report Count
 | 
			
		||||
    0x75, 0x08,                //   Report Size (8)
 | 
			
		||||
    0x81, 0x02,                //   Input (Data, Variable, Absolute)
 | 
			
		||||
    // Data from host
 | 
			
		||||
    0x09, 0x76,                 //   Usage (Vendor Defined)
 | 
			
		||||
    0x15, 0x00,                 //   Logical Minimum (0x00)
 | 
			
		||||
    0x26, 0xFF, 0x00,           //   Logical Maximum (0x00FF)
 | 
			
		||||
    0x95, CONSOLE_BUFFER_SIZE,  //   Report Count
 | 
			
		||||
    0x75, 0x08,                 //   Report Size (8)
 | 
			
		||||
    0x91, 0x02,                 //   Output (Data)
 | 
			
		||||
    0xC0                        // End Collection
 | 
			
		||||
    0x09, 0x76,                //   Usage (Vendor Defined)
 | 
			
		||||
    0x15, 0x00,                //   Logical Minimum (0x00)
 | 
			
		||||
    0x26, 0xFF, 0x00,          //   Logical Maximum (0x00FF)
 | 
			
		||||
    0x95, CONSOLE_BUFFER_SIZE, //   Report Count
 | 
			
		||||
    0x75, 0x08,                //   Report Size (8)
 | 
			
		||||
    0x91, 0x02,                //   Output (Data)
 | 
			
		||||
    0xC0                       // End Collection
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -939,16 +943,16 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) {
 | 
			
		|||
                    usbMsgPtr = (usbMsgPtr_t)&usbStringDescriptorZero;
 | 
			
		||||
                    len       = usbStringDescriptorZero.header.bLength;
 | 
			
		||||
                    break;
 | 
			
		||||
                case 1:  // iManufacturer
 | 
			
		||||
                case 1: // iManufacturer
 | 
			
		||||
                    usbMsgPtr = (usbMsgPtr_t)&usbStringDescriptorManufacturer;
 | 
			
		||||
                    len       = usbStringDescriptorManufacturer.header.bLength;
 | 
			
		||||
                    break;
 | 
			
		||||
                case 2:  // iProduct
 | 
			
		||||
                case 2: // iProduct
 | 
			
		||||
                    usbMsgPtr = (usbMsgPtr_t)&usbStringDescriptorProduct;
 | 
			
		||||
                    len       = usbStringDescriptorProduct.header.bLength;
 | 
			
		||||
                    break;
 | 
			
		||||
#if defined(SERIAL_NUMBER)
 | 
			
		||||
                case 3:  // iSerialNumber
 | 
			
		||||
                case 3: // iSerialNumber
 | 
			
		||||
                    usbMsgPtr = (usbMsgPtr_t)&usbStringDescriptorSerial;
 | 
			
		||||
                    len       = usbStringDescriptorSerial.header.bLength;
 | 
			
		||||
                    break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue