Remove arm_atsam platform (#24337)
				
					
				
			This commit is contained in:
		
							parent
							
								
									096aca63c5
								
							
						
					
					
						commit
						3bd303f204
					
				
					 215 changed files with 3 additions and 73516 deletions
				
			
		| 
						 | 
				
			
			@ -1,115 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "arm_atsam_protocol.h"
 | 
			
		||||
 | 
			
		||||
uint16_t v_5v;
 | 
			
		||||
uint16_t v_5v_avg;
 | 
			
		||||
uint16_t v_con_1;
 | 
			
		||||
uint16_t v_con_2;
 | 
			
		||||
uint16_t v_con_1_boot;
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
    // ADC
 | 
			
		||||
    ADC0->CTRLA.bit.SWRST = 1;
 | 
			
		||||
    while (ADC0->SYNCBUSY.bit.SWRST) {
 | 
			
		||||
        DBGC(DC_ADC0_SWRST_SYNCING_1);
 | 
			
		||||
    }
 | 
			
		||||
    while (ADC0->CTRLA.bit.SWRST) {
 | 
			
		||||
        DBGC(DC_ADC0_SWRST_SYNCING_2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Clock divide
 | 
			
		||||
    ADC0->CTRLA.bit.PRESCALER = ADC_CTRLA_PRESCALER_DIV2_Val;
 | 
			
		||||
 | 
			
		||||
    // Averaging
 | 
			
		||||
    ADC0->AVGCTRL.bit.SAMPLENUM = ADC_AVGCTRL_SAMPLENUM_4_Val;
 | 
			
		||||
    while (ADC0->SYNCBUSY.bit.AVGCTRL) {
 | 
			
		||||
        DBGC(DC_ADC0_AVGCTRL_SYNCING_1);
 | 
			
		||||
    }
 | 
			
		||||
    if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_1_Val)
 | 
			
		||||
        ADC0->AVGCTRL.bit.ADJRES = 0;
 | 
			
		||||
    else if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_2_Val)
 | 
			
		||||
        ADC0->AVGCTRL.bit.ADJRES = 1;
 | 
			
		||||
    else if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_4_Val)
 | 
			
		||||
        ADC0->AVGCTRL.bit.ADJRES = 2;
 | 
			
		||||
    else if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_8_Val)
 | 
			
		||||
        ADC0->AVGCTRL.bit.ADJRES = 3;
 | 
			
		||||
    else
 | 
			
		||||
        ADC0->AVGCTRL.bit.ADJRES = 4;
 | 
			
		||||
    while (ADC0->SYNCBUSY.bit.AVGCTRL) {
 | 
			
		||||
        DBGC(DC_ADC0_AVGCTRL_SYNCING_2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Settling
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Load factory calibration data
 | 
			
		||||
    ADC0->CALIB.bit.BIASCOMP   = ((*(uint32_t *)ADC0_FUSES_BIASCOMP_ADDR) & ADC0_FUSES_BIASCOMP_Msk) >> ADC0_FUSES_BIASCOMP_Pos;
 | 
			
		||||
    ADC0->CALIB.bit.BIASR2R    = ((*(uint32_t *)ADC0_FUSES_BIASR2R_ADDR) & ADC0_FUSES_BIASR2R_Msk) >> ADC0_FUSES_BIASR2R_Pos;
 | 
			
		||||
    ADC0->CALIB.bit.BIASREFBUF = ((*(uint32_t *)ADC0_FUSES_BIASREFBUF_ADDR) & ADC0_FUSES_BIASREFBUF_Msk) >> ADC0_FUSES_BIASREFBUF_Pos;
 | 
			
		||||
 | 
			
		||||
    // Enable
 | 
			
		||||
    ADC0->CTRLA.bit.ENABLE = 1;
 | 
			
		||||
    while (ADC0->SYNCBUSY.bit.ENABLE) {
 | 
			
		||||
        DBGC(DC_ADC0_ENABLE_SYNCING_1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_ADC0_INIT_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t adc_get(uint8_t muxpos) {
 | 
			
		||||
    ADC0->INPUTCTRL.bit.MUXPOS = muxpos;
 | 
			
		||||
    while (ADC0->SYNCBUSY.bit.INPUTCTRL) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ADC0->SWTRIG.bit.START = 1;
 | 
			
		||||
    while (ADC0->SYNCBUSY.bit.SWTRIG) {
 | 
			
		||||
    }
 | 
			
		||||
    while (!ADC0->INTFLAG.bit.RESRDY) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ADC0->RESULT.reg;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,37 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _ADC_H_
 | 
			
		||||
#define _ADC_H_
 | 
			
		||||
 | 
			
		||||
#define ADC_5V_START_LEVEL 2365
 | 
			
		||||
 | 
			
		||||
#define ADC_5V ADC_INPUTCTRL_MUXPOS_AIN12_Val
 | 
			
		||||
#define ADC_CON1 ADC_INPUTCTRL_MUXPOS_AIN14_Val
 | 
			
		||||
#define ADC_CON2 ADC_INPUTCTRL_MUXPOS_AIN13_Val
 | 
			
		||||
 | 
			
		||||
extern uint16_t v_5v;
 | 
			
		||||
extern uint16_t v_5v_avg;
 | 
			
		||||
extern uint16_t v_con_1;
 | 
			
		||||
extern uint16_t v_con_2;
 | 
			
		||||
extern uint16_t v_con_1_boot;
 | 
			
		||||
extern uint16_t v_con_2_boot;
 | 
			
		||||
 | 
			
		||||
void ADC0_clock_init(void);
 | 
			
		||||
void ADC0_init(void);
 | 
			
		||||
 | 
			
		||||
#endif //_ADC_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,31 +0,0 @@
 | 
			
		|||
ARM_ATSAM_DIR = protocol/arm_atsam
 | 
			
		||||
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/adc.c
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/clks.c
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/d51_util.c
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/i2c_master.c
 | 
			
		||||
ifeq ($(RGB_MATRIX_DRIVER),custom)
 | 
			
		||||
  SRC += $(ARM_ATSAM_DIR)/md_rgb_matrix_programs.c
 | 
			
		||||
  SRC += $(ARM_ATSAM_DIR)/md_rgb_matrix.c
 | 
			
		||||
endif
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/main_arm_atsam.c
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/shift_register.c
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/spi_master.c
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/startup.c
 | 
			
		||||
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/usb/main_usb.c
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/usb/udc.c
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/usb/udi_cdc.c
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/usb/udi_hid.c
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/usb/udi_hid_kbd.c
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/usb/udi_hid_kbd_desc.c
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/usb/ui.c
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/usb/usb.c
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/usb/usb_device_udd.c
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/usb/usb_hub.c
 | 
			
		||||
SRC += $(ARM_ATSAM_DIR)/usb/usb_util.c
 | 
			
		||||
 | 
			
		||||
SRC += $(DRIVER_PATH)/usb2422.c
 | 
			
		||||
 | 
			
		||||
# Search Path
 | 
			
		||||
VPATH += $(TMK_DIR)/$(ARM_ATSAM_DIR)
 | 
			
		||||
| 
						 | 
				
			
			@ -1,47 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _ARM_ATSAM_PROTOCOL_H_
 | 
			
		||||
#define _ARM_ATSAM_PROTOCOL_H_
 | 
			
		||||
 | 
			
		||||
#include "samd51j18a.h"
 | 
			
		||||
 | 
			
		||||
#include "timer.h"
 | 
			
		||||
#include "d51_util.h"
 | 
			
		||||
#include "clks.h"
 | 
			
		||||
#include "wait.h"
 | 
			
		||||
#include "adc.h"
 | 
			
		||||
#include "i2c_master.h"
 | 
			
		||||
#include "shift_register.h"
 | 
			
		||||
 | 
			
		||||
#include "./usb/usb_hub.h"
 | 
			
		||||
 | 
			
		||||
#ifndef MD_BOOTLOADER
 | 
			
		||||
 | 
			
		||||
#    include "main_arm_atsam.h"
 | 
			
		||||
#    ifdef RGB_MATRIX_ENABLE
 | 
			
		||||
#        include "md_rgb_matrix.h"
 | 
			
		||||
#        include "rgb_matrix.h"
 | 
			
		||||
#    endif
 | 
			
		||||
#    include "issi3733_driver.h"
 | 
			
		||||
#    include "./usb/compiler.h"
 | 
			
		||||
#    include "./usb/udc.h"
 | 
			
		||||
#    include "./usb/udi_cdc.h"
 | 
			
		||||
 | 
			
		||||
#endif // MD_BOOTLOADER
 | 
			
		||||
 | 
			
		||||
#endif //_ARM_ATSAM_PROTOCOL_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,436 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "arm_atsam_protocol.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
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};
 | 
			
		||||
 | 
			
		||||
#define USE_DPLL_IND 0
 | 
			
		||||
#define USE_DPLL_DEF GCLK_SOURCE_DPLL0
 | 
			
		||||
 | 
			
		||||
void CLK_oscctrl_init(void) {
 | 
			
		||||
    Oscctrl *posctrl = OSCCTRL;
 | 
			
		||||
    Gclk *   pgclk   = GCLK;
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_OSC_INIT_BEGIN);
 | 
			
		||||
 | 
			
		||||
    // default setup on por
 | 
			
		||||
    system_clks.freq_dfll    = FREQ_DFLL_DEFAULT;
 | 
			
		||||
    system_clks.freq_gclk[0] = system_clks.freq_dfll;
 | 
			
		||||
 | 
			
		||||
    // configure and startup 16MHz xosc0
 | 
			
		||||
    posctrl->XOSCCTRL[0].bit.ENABLE   = 0;
 | 
			
		||||
    posctrl->XOSCCTRL[0].bit.STARTUP  = 0xD;
 | 
			
		||||
    posctrl->XOSCCTRL[0].bit.ENALC    = 1;
 | 
			
		||||
    posctrl->XOSCCTRL[0].bit.IMULT    = 5;
 | 
			
		||||
    posctrl->XOSCCTRL[0].bit.IPTAT    = 3;
 | 
			
		||||
    posctrl->XOSCCTRL[0].bit.ONDEMAND = 0;
 | 
			
		||||
    posctrl->XOSCCTRL[0].bit.XTALEN   = 1;
 | 
			
		||||
    posctrl->XOSCCTRL[0].bit.ENABLE   = 1;
 | 
			
		||||
    while (posctrl->STATUS.bit.XOSCRDY0 == 0) {
 | 
			
		||||
        DBGC(DC_CLK_OSC_INIT_XOSC0_SYNC);
 | 
			
		||||
    }
 | 
			
		||||
    system_clks.freq_xosc0 = FREQ_XOSC0;
 | 
			
		||||
 | 
			
		||||
    // configure and startup DPLL
 | 
			
		||||
    posctrl->Dpll[USE_DPLL_IND].DPLLCTRLA.bit.ENABLE = 0;
 | 
			
		||||
    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
 | 
			
		||||
    while (posctrl->Dpll[USE_DPLL_IND].DPLLSYNCBUSY.bit.DPLLRATIO) {
 | 
			
		||||
        DBGC(DC_CLK_OSC_INIT_DPLL_SYNC_RATIO);
 | 
			
		||||
    }
 | 
			
		||||
    posctrl->Dpll[USE_DPLL_IND].DPLLCTRLA.bit.ONDEMAND = 0;
 | 
			
		||||
    posctrl->Dpll[USE_DPLL_IND].DPLLCTRLA.bit.ENABLE   = 1;
 | 
			
		||||
    while (posctrl->Dpll[USE_DPLL_IND].DPLLSYNCBUSY.bit.ENABLE) {
 | 
			
		||||
        DBGC(DC_CLK_OSC_INIT_DPLL_SYNC_ENABLE);
 | 
			
		||||
    }
 | 
			
		||||
    while (posctrl->Dpll[USE_DPLL_IND].DPLLSTATUS.bit.LOCK == 0) {
 | 
			
		||||
        DBGC(DC_CLK_OSC_INIT_DPLL_WAIT_LOCK);
 | 
			
		||||
    }
 | 
			
		||||
    while (posctrl->Dpll[USE_DPLL_IND].DPLLSTATUS.bit.CLKRDY == 0) {
 | 
			
		||||
        DBGC(DC_CLK_OSC_INIT_DPLL_WAIT_CLKRDY);
 | 
			
		||||
    }
 | 
			
		||||
    system_clks.freq_dpll[0] = (system_clks.freq_xosc0 / 2 / (posctrl->Dpll[USE_DPLL_IND].DPLLCTRLB.bit.DIV + 1)) * (posctrl->Dpll[USE_DPLL_IND].DPLLRATIO.bit.LDR + 1);
 | 
			
		||||
 | 
			
		||||
    // change gclk0 to DPLL
 | 
			
		||||
    pgclk->GENCTRL[GEN_DPLL0].bit.SRC = USE_DPLL_DEF;
 | 
			
		||||
    while (pgclk->SYNCBUSY.bit.GENCTRL0) {
 | 
			
		||||
        DBGC(DC_CLK_OSC_INIT_GCLK_SYNC_GENCTRL0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_OSC_INIT_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// configure for 1MHz (1 usec timebase)
 | 
			
		||||
// call CLK_set_gclk_freq(GEN_TC45, FREQ_TC45_DEFAULT);
 | 
			
		||||
uint32_t CLK_set_gclk_freq(uint8_t gclkn, uint32_t freq) {
 | 
			
		||||
    Gclk *pgclk = GCLK;
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_SET_GCLK_FREQ_BEGIN);
 | 
			
		||||
 | 
			
		||||
    while (pgclk->SYNCBUSY.vec.GENCTRL) {
 | 
			
		||||
        DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_1);
 | 
			
		||||
    }
 | 
			
		||||
    pgclk->GENCTRL[gclkn].bit.SRC = USE_DPLL_DEF;
 | 
			
		||||
    while (pgclk->SYNCBUSY.vec.GENCTRL) {
 | 
			
		||||
        DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_2);
 | 
			
		||||
    }
 | 
			
		||||
    pgclk->GENCTRL[gclkn].bit.DIV = (uint8_t)(system_clks.freq_dpll[0] / freq);
 | 
			
		||||
    while (pgclk->SYNCBUSY.vec.GENCTRL) {
 | 
			
		||||
        DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_3);
 | 
			
		||||
    }
 | 
			
		||||
    pgclk->GENCTRL[gclkn].bit.DIVSEL = 0;
 | 
			
		||||
    while (pgclk->SYNCBUSY.vec.GENCTRL) {
 | 
			
		||||
        DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_4);
 | 
			
		||||
    }
 | 
			
		||||
    pgclk->GENCTRL[gclkn].bit.GENEN = 1;
 | 
			
		||||
    while (pgclk->SYNCBUSY.vec.GENCTRL) {
 | 
			
		||||
        DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_5);
 | 
			
		||||
    }
 | 
			
		||||
    system_clks.freq_gclk[gclkn] = system_clks.freq_dpll[0] / pgclk->GENCTRL[gclkn].bit.DIV;
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_SET_GCLK_FREQ_COMPLETE);
 | 
			
		||||
 | 
			
		||||
    return system_clks.freq_gclk[gclkn];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CLK_init_osc(void) {
 | 
			
		||||
    uint8_t gclkn = GEN_OSC0;
 | 
			
		||||
    Gclk *  pgclk = GCLK;
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_INIT_OSC_BEGIN);
 | 
			
		||||
 | 
			
		||||
    while (pgclk->SYNCBUSY.vec.GENCTRL) {
 | 
			
		||||
        DBGC(DC_CLK_INIT_OSC_SYNC_1);
 | 
			
		||||
    }
 | 
			
		||||
    pgclk->GENCTRL[gclkn].bit.SRC = GCLK_SOURCE_XOSC0;
 | 
			
		||||
    while (pgclk->SYNCBUSY.vec.GENCTRL) {
 | 
			
		||||
        DBGC(DC_CLK_INIT_OSC_SYNC_2);
 | 
			
		||||
    }
 | 
			
		||||
    pgclk->GENCTRL[gclkn].bit.DIV = 1;
 | 
			
		||||
    while (pgclk->SYNCBUSY.vec.GENCTRL) {
 | 
			
		||||
        DBGC(DC_CLK_INIT_OSC_SYNC_3);
 | 
			
		||||
    }
 | 
			
		||||
    pgclk->GENCTRL[gclkn].bit.DIVSEL = 0;
 | 
			
		||||
    while (pgclk->SYNCBUSY.vec.GENCTRL) {
 | 
			
		||||
        DBGC(DC_CLK_INIT_OSC_SYNC_4);
 | 
			
		||||
    }
 | 
			
		||||
    pgclk->GENCTRL[gclkn].bit.GENEN = 1;
 | 
			
		||||
    while (pgclk->SYNCBUSY.vec.GENCTRL) {
 | 
			
		||||
        DBGC(DC_CLK_INIT_OSC_SYNC_5);
 | 
			
		||||
    }
 | 
			
		||||
    system_clks.freq_gclk[gclkn] = system_clks.freq_xosc0;
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_INIT_OSC_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CLK_reset_time(void) {
 | 
			
		||||
    Tc *ptc4 = TC4;
 | 
			
		||||
    Tc *ptc0 = TC0;
 | 
			
		||||
 | 
			
		||||
    ms_clk = 0;
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_RESET_TIME_BEGIN);
 | 
			
		||||
 | 
			
		||||
    // stop counters
 | 
			
		||||
    ptc4->COUNT16.CTRLA.bit.ENABLE = 0;
 | 
			
		||||
    while (ptc4->COUNT16.SYNCBUSY.bit.ENABLE) {
 | 
			
		||||
    }
 | 
			
		||||
    ptc0->COUNT32.CTRLA.bit.ENABLE = 0;
 | 
			
		||||
    while (ptc0->COUNT32.SYNCBUSY.bit.ENABLE) {
 | 
			
		||||
    }
 | 
			
		||||
    // zero counters
 | 
			
		||||
    ptc4->COUNT16.COUNT.reg = 0;
 | 
			
		||||
    while (ptc4->COUNT16.SYNCBUSY.bit.COUNT) {
 | 
			
		||||
    }
 | 
			
		||||
    ptc0->COUNT32.COUNT.reg = 0;
 | 
			
		||||
    while (ptc0->COUNT32.SYNCBUSY.bit.COUNT) {
 | 
			
		||||
    }
 | 
			
		||||
    // start counters
 | 
			
		||||
    ptc0->COUNT32.CTRLA.bit.ENABLE = 1;
 | 
			
		||||
    while (ptc0->COUNT32.SYNCBUSY.bit.ENABLE) {
 | 
			
		||||
    }
 | 
			
		||||
    ptc4->COUNT16.CTRLA.bit.ENABLE = 1;
 | 
			
		||||
    while (ptc4->COUNT16.SYNCBUSY.bit.ENABLE) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_RESET_TIME_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TC4_Handler() {
 | 
			
		||||
    if (TC4->COUNT16.INTFLAG.bit.MC0) {
 | 
			
		||||
        TC4->COUNT16.INTFLAG.reg = TC_INTENCLR_MC0;
 | 
			
		||||
        ms_clk++;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t CLK_enable_timebase(void) {
 | 
			
		||||
    Gclk * pgclk  = GCLK;
 | 
			
		||||
    Mclk * pmclk  = MCLK;
 | 
			
		||||
    Tc *   ptc4   = TC4;
 | 
			
		||||
    Tc *   ptc0   = TC0;
 | 
			
		||||
    Evsys *pevsys = EVSYS;
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_ENABLE_TIMEBASE_BEGIN);
 | 
			
		||||
 | 
			
		||||
    // gclk2  highspeed time base
 | 
			
		||||
    CLK_set_gclk_freq(GEN_TC45, FREQ_TC45_DEFAULT);
 | 
			
		||||
    CLK_init_osc();
 | 
			
		||||
 | 
			
		||||
    // unmask TC4, sourcegclk2 to TC4
 | 
			
		||||
    pmclk->APBCMASK.bit.TC4_             = 1;
 | 
			
		||||
    pgclk->PCHCTRL[TC4_GCLK_ID].bit.GEN  = GEN_TC45;
 | 
			
		||||
    pgclk->PCHCTRL[TC4_GCLK_ID].bit.CHEN = 1;
 | 
			
		||||
 | 
			
		||||
    // configure TC4
 | 
			
		||||
    DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_BEGIN);
 | 
			
		||||
    ptc4->COUNT16.CTRLA.bit.ENABLE = 0;
 | 
			
		||||
    while (ptc4->COUNT16.SYNCBUSY.bit.ENABLE) {
 | 
			
		||||
        DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_DISABLE);
 | 
			
		||||
    }
 | 
			
		||||
    ptc4->COUNT16.CTRLA.bit.SWRST = 1;
 | 
			
		||||
    while (ptc4->COUNT16.SYNCBUSY.bit.SWRST) {
 | 
			
		||||
        DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_SWRST_1);
 | 
			
		||||
    }
 | 
			
		||||
    while (ptc4->COUNT16.CTRLA.bit.SWRST) {
 | 
			
		||||
        DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_SWRST_2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // CTRLA defaults
 | 
			
		||||
    // CTRLB as default, counting up
 | 
			
		||||
    ptc4->COUNT16.CTRLBCLR.reg = 5;
 | 
			
		||||
    while (ptc4->COUNT16.SYNCBUSY.bit.CTRLB) {
 | 
			
		||||
        DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_CLTRB);
 | 
			
		||||
    }
 | 
			
		||||
    ptc4->COUNT16.CC[0].reg = 999;
 | 
			
		||||
    while (ptc4->COUNT16.SYNCBUSY.bit.CC0) {
 | 
			
		||||
        DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_CC0);
 | 
			
		||||
    }
 | 
			
		||||
    // ptc4->COUNT16.DBGCTRL.bit.DBGRUN = 1;
 | 
			
		||||
 | 
			
		||||
    // wave mode
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    NVIC_EnableIRQ(TC4_IRQn);
 | 
			
		||||
    ptc4->COUNT16.INTENSET.bit.MC0 = 1;
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_COMPLETE);
 | 
			
		||||
 | 
			
		||||
    // unmask TC0,1, sourcegclk2 to TC0,1
 | 
			
		||||
    pmclk->APBAMASK.bit.TC0_             = 1;
 | 
			
		||||
    pgclk->PCHCTRL[TC0_GCLK_ID].bit.GEN  = GEN_TC45;
 | 
			
		||||
    pgclk->PCHCTRL[TC0_GCLK_ID].bit.CHEN = 1;
 | 
			
		||||
 | 
			
		||||
    pmclk->APBAMASK.bit.TC1_             = 1;
 | 
			
		||||
    pgclk->PCHCTRL[TC1_GCLK_ID].bit.GEN  = GEN_TC45;
 | 
			
		||||
    pgclk->PCHCTRL[TC1_GCLK_ID].bit.CHEN = 1;
 | 
			
		||||
 | 
			
		||||
    // configure TC0
 | 
			
		||||
    DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_BEGIN);
 | 
			
		||||
    ptc0->COUNT32.CTRLA.bit.ENABLE = 0;
 | 
			
		||||
    while (ptc0->COUNT32.SYNCBUSY.bit.ENABLE) {
 | 
			
		||||
        DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_DISABLE);
 | 
			
		||||
    }
 | 
			
		||||
    ptc0->COUNT32.CTRLA.bit.SWRST = 1;
 | 
			
		||||
    while (ptc0->COUNT32.SYNCBUSY.bit.SWRST) {
 | 
			
		||||
        DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_SWRST_1);
 | 
			
		||||
    }
 | 
			
		||||
    while (ptc0->COUNT32.CTRLA.bit.SWRST) {
 | 
			
		||||
        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
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_COMPLETE);
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_ENABLE_TIMEBASE_EVSYS_BEGIN);
 | 
			
		||||
 | 
			
		||||
    // configure event system
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_ENABLE_TIMEBASE_EVSYS_COMPLETE);
 | 
			
		||||
 | 
			
		||||
    CLK_reset_time();
 | 
			
		||||
 | 
			
		||||
    ADC0_clock_init();
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_ENABLE_TIMEBASE_COMPLETE);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CLK_delay_us(uint32_t usec) {
 | 
			
		||||
    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
 | 
			
		||||
    );
 | 
			
		||||
    // Note: BX LR generated
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CLK_delay_ms(uint64_t msec) {
 | 
			
		||||
    msec += timer_read64();
 | 
			
		||||
    while (msec > timer_read64()) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void clk_enable_sercom_apbmask(int sercomn) {
 | 
			
		||||
    Mclk *pmclk = MCLK;
 | 
			
		||||
    switch (sercomn) {
 | 
			
		||||
        case 0:
 | 
			
		||||
            pmclk->APBAMASK.bit.SERCOM0_ = 1;
 | 
			
		||||
            break;
 | 
			
		||||
        case 1:
 | 
			
		||||
            pmclk->APBAMASK.bit.SERCOM1_ = 1;
 | 
			
		||||
            break;
 | 
			
		||||
        case 2:
 | 
			
		||||
            pmclk->APBBMASK.bit.SERCOM2_ = 1;
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            pmclk->APBBMASK.bit.SERCOM3_ = 1;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// call CLK_oscctrl_init first
 | 
			
		||||
// call CLK_set_spi_freq(CHAN_SERCOM_SPI, FREQ_SPI_DEFAULT);
 | 
			
		||||
uint32_t CLK_set_spi_freq(uint8_t sercomn, uint32_t freq) {
 | 
			
		||||
    DBGC(DC_CLK_SET_SPI_FREQ_BEGIN);
 | 
			
		||||
 | 
			
		||||
    Gclk *  pgclk   = GCLK;
 | 
			
		||||
    Sercom *psercom = (Sercom *)sercom_apbbase[sercomn];
 | 
			
		||||
    clk_enable_sercom_apbmask(sercomn);
 | 
			
		||||
 | 
			
		||||
    // all gclk0 for now
 | 
			
		||||
    pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.GEN  = 0;
 | 
			
		||||
    pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.CHEN = 1;
 | 
			
		||||
 | 
			
		||||
    psercom->I2CM.CTRLA.bit.SWRST = 1;
 | 
			
		||||
    while (psercom->I2CM.SYNCBUSY.bit.SWRST) {
 | 
			
		||||
    }
 | 
			
		||||
    while (psercom->I2CM.CTRLA.bit.SWRST) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    psercom->SPI.BAUD.reg            = (uint8_t)(system_clks.freq_gclk[0] / 2 / freq - 1);
 | 
			
		||||
    system_clks.freq_spi             = system_clks.freq_gclk[0] / 2 / (psercom->SPI.BAUD.reg + 1);
 | 
			
		||||
    system_clks.freq_sercom[sercomn] = system_clks.freq_spi;
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_SET_SPI_FREQ_COMPLETE);
 | 
			
		||||
 | 
			
		||||
    return system_clks.freq_spi;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// call CLK_oscctrl_init first
 | 
			
		||||
// call CLK_set_i2c0_freq(CHAN_SERCOM_I2C0, FREQ_I2C0_DEFAULT);
 | 
			
		||||
uint32_t CLK_set_i2c0_freq(uint8_t sercomn, uint32_t freq) {
 | 
			
		||||
    DBGC(DC_CLK_SET_I2C0_FREQ_BEGIN);
 | 
			
		||||
 | 
			
		||||
    Gclk *  pgclk   = GCLK;
 | 
			
		||||
    Sercom *psercom = (Sercom *)sercom_apbbase[sercomn];
 | 
			
		||||
    clk_enable_sercom_apbmask(sercomn);
 | 
			
		||||
 | 
			
		||||
    // all gclk0 for now
 | 
			
		||||
    pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.GEN  = 0;
 | 
			
		||||
    pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.CHEN = 1;
 | 
			
		||||
 | 
			
		||||
    psercom->I2CM.CTRLA.bit.SWRST = 1;
 | 
			
		||||
    while (psercom->I2CM.SYNCBUSY.bit.SWRST) {
 | 
			
		||||
    }
 | 
			
		||||
    while (psercom->I2CM.CTRLA.bit.SWRST) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    psercom->I2CM.BAUD.bit.BAUD      = (uint8_t)(system_clks.freq_gclk[0] / 2 / freq - 1);
 | 
			
		||||
    system_clks.freq_i2c0            = system_clks.freq_gclk[0] / 2 / (psercom->I2CM.BAUD.bit.BAUD + 1);
 | 
			
		||||
    system_clks.freq_sercom[sercomn] = system_clks.freq_i2c0;
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_SET_I2C0_FREQ_COMPLETE);
 | 
			
		||||
 | 
			
		||||
    return system_clks.freq_i2c0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// call CLK_oscctrl_init first
 | 
			
		||||
// call CLK_set_i2c1_freq(CHAN_SERCOM_I2C1, FREQ_I2C1_DEFAULT);
 | 
			
		||||
uint32_t CLK_set_i2c1_freq(uint8_t sercomn, uint32_t freq) {
 | 
			
		||||
    DBGC(DC_CLK_SET_I2C1_FREQ_BEGIN);
 | 
			
		||||
 | 
			
		||||
    Gclk *  pgclk   = GCLK;
 | 
			
		||||
    Sercom *psercom = (Sercom *)sercom_apbbase[sercomn];
 | 
			
		||||
    clk_enable_sercom_apbmask(sercomn);
 | 
			
		||||
 | 
			
		||||
    // all gclk0 for now
 | 
			
		||||
    pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.GEN  = 0;
 | 
			
		||||
    pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.CHEN = 1;
 | 
			
		||||
 | 
			
		||||
    psercom->I2CM.CTRLA.bit.SWRST = 1;
 | 
			
		||||
    while (psercom->I2CM.SYNCBUSY.bit.SWRST) {
 | 
			
		||||
    }
 | 
			
		||||
    while (psercom->I2CM.CTRLA.bit.SWRST) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    psercom->I2CM.BAUD.bit.BAUD      = (uint8_t)(system_clks.freq_gclk[0] / 2 / freq - 10);
 | 
			
		||||
    system_clks.freq_i2c1            = system_clks.freq_gclk[0] / 2 / (psercom->I2CM.BAUD.bit.BAUD + 10);
 | 
			
		||||
    system_clks.freq_sercom[sercomn] = system_clks.freq_i2c1;
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_SET_I2C1_FREQ_COMPLETE);
 | 
			
		||||
 | 
			
		||||
    return system_clks.freq_i2c1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CLK_init(void) {
 | 
			
		||||
    DBGC(DC_CLK_INIT_BEGIN);
 | 
			
		||||
 | 
			
		||||
    memset((void *)&system_clks, 0, sizeof(system_clks));
 | 
			
		||||
 | 
			
		||||
    CLK_oscctrl_init();
 | 
			
		||||
    CLK_enable_timebase();
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_CLK_INIT_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,89 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _CLKS_H_
 | 
			
		||||
#define _CLKS_H_
 | 
			
		||||
 | 
			
		||||
#ifndef MD_BOOTLOADER
 | 
			
		||||
 | 
			
		||||
// From keyboard
 | 
			
		||||
#    include "config_led.h"
 | 
			
		||||
#    include "config.h"
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
// I2C1 Set      ~Result     PWM Time (2x Drivers)
 | 
			
		||||
//     1000000  1090000
 | 
			
		||||
//     900000   1000000     3.82ms
 | 
			
		||||
//     800000   860000
 | 
			
		||||
//     700000   750000
 | 
			
		||||
//     600000   630000
 | 
			
		||||
//     580000   615000      6.08ms
 | 
			
		||||
//     500000   522000
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
// Generator clock channels
 | 
			
		||||
#define GEN_DPLL0 0
 | 
			
		||||
#define GEN_OSC0 1
 | 
			
		||||
#define GEN_TC45 2
 | 
			
		||||
 | 
			
		||||
#define SERCOM_COUNT 5
 | 
			
		||||
#define GCLK_COUNT 12
 | 
			
		||||
 | 
			
		||||
typedef struct clk_s {
 | 
			
		||||
    uint32_t freq_dfll;
 | 
			
		||||
    uint32_t freq_dpll[2];
 | 
			
		||||
    uint32_t freq_sercom[SERCOM_COUNT];
 | 
			
		||||
    uint32_t freq_gclk[GCLK_COUNT];
 | 
			
		||||
    uint32_t freq_xosc0;
 | 
			
		||||
    uint32_t freq_spi;
 | 
			
		||||
    uint32_t freq_i2c0;
 | 
			
		||||
    uint32_t freq_i2c1;
 | 
			
		||||
    uint32_t freq_uart;
 | 
			
		||||
    uint32_t freq_adc0;
 | 
			
		||||
} clk_t;
 | 
			
		||||
 | 
			
		||||
extern volatile clk_t    system_clks;
 | 
			
		||||
extern volatile uint64_t ms_clk;
 | 
			
		||||
 | 
			
		||||
void     CLK_oscctrl_init(void);
 | 
			
		||||
void     CLK_reset_time(void);
 | 
			
		||||
uint32_t CLK_set_gclk_freq(uint8_t gclkn, uint32_t freq);
 | 
			
		||||
uint32_t CLK_enable_timebase(void);
 | 
			
		||||
uint64_t timer_read64(void);
 | 
			
		||||
void     CLK_delay_us(uint32_t usec);
 | 
			
		||||
void     CLK_delay_ms(uint64_t msec);
 | 
			
		||||
 | 
			
		||||
uint32_t CLK_set_spi_freq(uint8_t sercomn, uint32_t freq);
 | 
			
		||||
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_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,244 +0,0 @@
 | 
			
		|||
#include "d51_util.h"
 | 
			
		||||
 | 
			
		||||
static volatile uint32_t w;
 | 
			
		||||
 | 
			
		||||
// Display unsigned 32-bit number by port toggling DBG_1 (to view on a scope)
 | 
			
		||||
// Read as follows: 1230 = |    | |    | | |    ||  (note zero is fast double toggle)
 | 
			
		||||
#define DBG_PAUSE 5
 | 
			
		||||
void dbg_print(uint32_t x) {
 | 
			
		||||
    int8_t   t;
 | 
			
		||||
    uint32_t n;
 | 
			
		||||
    uint32_t p, p2;
 | 
			
		||||
 | 
			
		||||
    if (x < 10)
 | 
			
		||||
        t = 0;
 | 
			
		||||
    else if (x < 100)
 | 
			
		||||
        t = 1;
 | 
			
		||||
    else if (x < 1000)
 | 
			
		||||
        t = 2;
 | 
			
		||||
    else if (x < 10000)
 | 
			
		||||
        t = 3;
 | 
			
		||||
    else if (x < 100000)
 | 
			
		||||
        t = 4;
 | 
			
		||||
    else if (x < 1000000)
 | 
			
		||||
        t = 5;
 | 
			
		||||
    else if (x < 10000000)
 | 
			
		||||
        t = 6;
 | 
			
		||||
    else if (x < 100000000)
 | 
			
		||||
        t = 7;
 | 
			
		||||
    else if (x < 1000000000)
 | 
			
		||||
        t = 8;
 | 
			
		||||
    else
 | 
			
		||||
        t = 9;
 | 
			
		||||
 | 
			
		||||
    while (t >= 0) {
 | 
			
		||||
        p2 = t;
 | 
			
		||||
        p  = 1;
 | 
			
		||||
        while (p2--)
 | 
			
		||||
            p *= 10;
 | 
			
		||||
        n = x / p;
 | 
			
		||||
        x -= n * p;
 | 
			
		||||
        if (!n) {
 | 
			
		||||
            DBG_1_ON;
 | 
			
		||||
            DBG_1_OFF;
 | 
			
		||||
            DBG_1_ON;
 | 
			
		||||
            DBG_1_OFF;
 | 
			
		||||
            n--;
 | 
			
		||||
        } else {
 | 
			
		||||
            while (n > 0) {
 | 
			
		||||
                DBG_1_ON;
 | 
			
		||||
                DBG_1_OFF;
 | 
			
		||||
                n--;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        t--;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (w = DBG_PAUSE; w; w--)
 | 
			
		||||
        ; // Long pause after number is complete
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Display unsigned 32-bit number through debug led
 | 
			
		||||
// Read as follows: 1230 = [*]  [* *]  [* * *]  [**]  (note zero is fast double flash)
 | 
			
		||||
#define DLED_ONTIME 1000000
 | 
			
		||||
#define DLED_PAUSE 1500000
 | 
			
		||||
void dled_print(uint32_t x, uint8_t long_pause) {
 | 
			
		||||
    int8_t   t;
 | 
			
		||||
    uint32_t n;
 | 
			
		||||
    uint32_t p, p2;
 | 
			
		||||
 | 
			
		||||
    if (x < 10)
 | 
			
		||||
        t = 0;
 | 
			
		||||
    else if (x < 100)
 | 
			
		||||
        t = 1;
 | 
			
		||||
    else if (x < 1000)
 | 
			
		||||
        t = 2;
 | 
			
		||||
    else if (x < 10000)
 | 
			
		||||
        t = 3;
 | 
			
		||||
    else if (x < 100000)
 | 
			
		||||
        t = 4;
 | 
			
		||||
    else if (x < 1000000)
 | 
			
		||||
        t = 5;
 | 
			
		||||
    else if (x < 10000000)
 | 
			
		||||
        t = 6;
 | 
			
		||||
    else if (x < 100000000)
 | 
			
		||||
        t = 7;
 | 
			
		||||
    else if (x < 1000000000)
 | 
			
		||||
        t = 8;
 | 
			
		||||
    else
 | 
			
		||||
        t = 9;
 | 
			
		||||
 | 
			
		||||
    while (t >= 0) {
 | 
			
		||||
        p2 = t;
 | 
			
		||||
        p  = 1;
 | 
			
		||||
        while (p2--)
 | 
			
		||||
            p *= 10;
 | 
			
		||||
        n = x / p;
 | 
			
		||||
        x -= n * p;
 | 
			
		||||
        if (!n) {
 | 
			
		||||
            DBG_LED_ON;
 | 
			
		||||
            for (w = DLED_ONTIME / 4; w; w--)
 | 
			
		||||
                ;
 | 
			
		||||
            DBG_LED_OFF;
 | 
			
		||||
            for (w = DLED_ONTIME / 4; w; w--)
 | 
			
		||||
                ;
 | 
			
		||||
            DBG_LED_ON;
 | 
			
		||||
            for (w = DLED_ONTIME / 4; w; w--)
 | 
			
		||||
                ;
 | 
			
		||||
            DBG_LED_OFF;
 | 
			
		||||
            for (w = DLED_ONTIME / 4; w; w--)
 | 
			
		||||
                ;
 | 
			
		||||
            n--;
 | 
			
		||||
        } else {
 | 
			
		||||
            while (n > 0) {
 | 
			
		||||
                DBG_LED_ON;
 | 
			
		||||
                for (w = DLED_ONTIME; w; w--)
 | 
			
		||||
                    ;
 | 
			
		||||
                DBG_LED_OFF;
 | 
			
		||||
                for (w = DLED_ONTIME / 2; w; w--)
 | 
			
		||||
                    ;
 | 
			
		||||
                n--;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (w = DLED_PAUSE; w; w--)
 | 
			
		||||
            ;
 | 
			
		||||
        t--;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (long_pause) {
 | 
			
		||||
        for (w = DLED_PAUSE * 4; w; w--)
 | 
			
		||||
            ;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_BOOT_TRACING_ENABLE
 | 
			
		||||
 | 
			
		||||
volatile uint32_t debug_code;
 | 
			
		||||
 | 
			
		||||
// These macros are for compile time substitution
 | 
			
		||||
#    define DEBUG_BOOT_TRACING_EXTINTn (DEBUG_BOOT_TRACING_PIN % _U_(0x10))
 | 
			
		||||
#    define DEBUG_BOOT_TRACING_EXTINTb (_U_(0x1) << DEBUG_BOOT_TRACING_EXTINTn)
 | 
			
		||||
#    define DEBUG_BOOT_TRACING_CONFIG_INDn (DEBUG_BOOT_TRACING_EXTINTn / _U_(0x8))
 | 
			
		||||
#    define DEBUG_BOOT_TRACING_CONFIG_SENSEn (DEBUG_BOOT_TRACING_EXTINTn % _U_(0x8))
 | 
			
		||||
#    define DEBUG_BOOT_TRACING_CONFIG_SENSEb (DEBUG_BOOT_TRACING_CONFIG_SENSEn * _U_(0x4))
 | 
			
		||||
#    define DEBUG_BOOT_TRACING_IRQn (EIC_0_IRQn + DEBUG_BOOT_TRACING_EXTINTn)
 | 
			
		||||
 | 
			
		||||
// These macros perform PORT+PIN definition translation to IRQn in the preprocessor
 | 
			
		||||
#    define PORTPIN_TO_IRQn_EXPAND(def) def
 | 
			
		||||
#    define PORTPIN_TO_IRQn_DEF(def) PORTPIN_TO_IRQn_EXPAND(def)
 | 
			
		||||
#    if DEBUG_BOOT_TRACING_PIN < 10
 | 
			
		||||
#        define PORTPIN_TO_IRQn_TODEF(port, pin) PORTPIN_TO_IRQn_DEF(PIN_##port##0##pin##A_EIC_EXTINT_NUM)
 | 
			
		||||
#    else
 | 
			
		||||
#        define PORTPIN_TO_IRQn_TODEF(port, pin) PORTPIN_TO_IRQn_DEF(PIN_##port##pin##A_EIC_EXTINT_NUM)
 | 
			
		||||
#    endif
 | 
			
		||||
#    define PORTPIN_TO_IRQn(port, pin) PORTPIN_TO_IRQn_TODEF(port, pin)
 | 
			
		||||
 | 
			
		||||
// These macros perform function name output in the preprocessor
 | 
			
		||||
#    define DEBUG_BOOT_TRACING_HANDLER_CONCAT(irq) void EIC_##irq##_Handler(void)
 | 
			
		||||
#    define DEBUG_BOOT_TRACING_HANDLER(irq) DEBUG_BOOT_TRACING_HANDLER_CONCAT(irq)
 | 
			
		||||
 | 
			
		||||
// To generate the function name of the IRQ handler catching boot tracing,
 | 
			
		||||
//  certain macros must be undefined, so save their current values to macro stack
 | 
			
		||||
#    pragma push_macro("PA")
 | 
			
		||||
#    pragma push_macro("PB")
 | 
			
		||||
#    pragma push_macro("_L_")
 | 
			
		||||
 | 
			
		||||
// Undefine / redefine pushed macros
 | 
			
		||||
#    undef PA
 | 
			
		||||
#    undef PB
 | 
			
		||||
#    undef _L_
 | 
			
		||||
#    define _L_(x) x
 | 
			
		||||
 | 
			
		||||
// Perform the work and output
 | 
			
		||||
// Ex: PORT PB, PIN 31 = void EIC_15_Handler(void)
 | 
			
		||||
DEBUG_BOOT_TRACING_HANDLER(PORTPIN_TO_IRQn(DEBUG_BOOT_TRACING_PORT, DEBUG_BOOT_TRACING_PIN))
 | 
			
		||||
// Restore macros
 | 
			
		||||
#    pragma pop_macro("PA")
 | 
			
		||||
#    pragma pop_macro("PB")
 | 
			
		||||
#    pragma pop_macro("_L_")
 | 
			
		||||
{
 | 
			
		||||
    // This is only for non-functional keyboard troubleshooting and should be disabled after boot
 | 
			
		||||
    // Intention is to lock up the keyboard here with repeating debug led code
 | 
			
		||||
    while (1) {
 | 
			
		||||
        dled_print(debug_code, 1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void debug_code_init(void) {
 | 
			
		||||
    DBGC(DC_UNSET);
 | 
			
		||||
 | 
			
		||||
    // Configure Ports for EIC
 | 
			
		||||
    PORT->Group[DEBUG_BOOT_TRACING_PORT].DIRCLR.reg                                 = 1 << DEBUG_BOOT_TRACING_PIN; // Input
 | 
			
		||||
    PORT->Group[DEBUG_BOOT_TRACING_PORT].OUTSET.reg                                 = 1 << DEBUG_BOOT_TRACING_PIN; // High
 | 
			
		||||
    PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.INEN    = 1;                           // Input Enable
 | 
			
		||||
    PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PULLEN  = 1;                           // Pull Enable
 | 
			
		||||
    PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PMUXEN  = 1;                           // Mux Enable
 | 
			
		||||
    PORT->Group[DEBUG_BOOT_TRACING_PORT].PMUX[DEBUG_BOOT_TRACING_PIN / 2].bit.PMUXO = 0;                           // Mux A
 | 
			
		||||
 | 
			
		||||
    // Enable CLK_EIC_APB
 | 
			
		||||
    MCLK->APBAMASK.bit.EIC_ = 1;
 | 
			
		||||
 | 
			
		||||
    // Configure EIC
 | 
			
		||||
    EIC->CTRLA.bit.SWRST = 1;
 | 
			
		||||
    while (EIC->SYNCBUSY.bit.SWRST) {
 | 
			
		||||
    }
 | 
			
		||||
    EIC->ASYNCH.reg   = DEBUG_BOOT_TRACING_EXTINTb;
 | 
			
		||||
    EIC->INTENSET.reg = DEBUG_BOOT_TRACING_EXTINTb;
 | 
			
		||||
    EIC->CONFIG[DEBUG_BOOT_TRACING_CONFIG_INDn].reg |= (EIC_CONFIG_SENSE0_FALL_Val << DEBUG_BOOT_TRACING_CONFIG_SENSEb);
 | 
			
		||||
    EIC->CTRLA.bit.ENABLE = 1;
 | 
			
		||||
    while (EIC->SYNCBUSY.bit.ENABLE) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Enable EIC IRQ
 | 
			
		||||
    NVIC_EnableIRQ(DEBUG_BOOT_TRACING_IRQn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void debug_code_disable(void) {
 | 
			
		||||
    // Disable EIC IRQ
 | 
			
		||||
    NVIC_DisableIRQ(DEBUG_BOOT_TRACING_IRQn);
 | 
			
		||||
 | 
			
		||||
    // Disable EIC
 | 
			
		||||
    EIC->CTRLA.bit.ENABLE = 0;
 | 
			
		||||
    while (EIC->SYNCBUSY.bit.ENABLE) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Default port configuration
 | 
			
		||||
    PORT->Group[DEBUG_BOOT_TRACING_PORT].DIRCLR.reg                                 = 1 << DEBUG_BOOT_TRACING_PIN; // Input
 | 
			
		||||
    PORT->Group[DEBUG_BOOT_TRACING_PORT].OUTCLR.reg                                 = 1 << DEBUG_BOOT_TRACING_PIN; // Low
 | 
			
		||||
    PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.INEN    = 0;                           // Input Disable
 | 
			
		||||
    PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PULLEN  = 0;                           // Pull Disable
 | 
			
		||||
    PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PMUXEN  = 0;                           // Mux Disable
 | 
			
		||||
    PORT->Group[DEBUG_BOOT_TRACING_PORT].PMUX[DEBUG_BOOT_TRACING_PIN / 2].bit.PMUXO = 0;                           // Mux A
 | 
			
		||||
 | 
			
		||||
    // Disable CLK_EIC_APB
 | 
			
		||||
    MCLK->APBAMASK.bit.EIC_ = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
void debug_code_init(void) {}
 | 
			
		||||
void debug_code_disable(void) {}
 | 
			
		||||
 | 
			
		||||
#endif // DEBUG_BOOT_TRACING_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			@ -1,224 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _D51_UTIL_H_
 | 
			
		||||
#define _D51_UTIL_H_
 | 
			
		||||
 | 
			
		||||
#include "samd51j18a.h"
 | 
			
		||||
 | 
			
		||||
/* Debug LED */
 | 
			
		||||
#if DEBUG_LED_ENABLE == 1
 | 
			
		||||
#    define DBG_LED_ENA PORT->Group[DEBUG_LED_PORT].DIRSET.reg = (1 << DEBUG_LED_PIN)
 | 
			
		||||
#    define DBG_LED_DIS PORT->Group[DEBUG_LED_PORT].DIRCLR.reg = (1 << DEBUG_LED_PIN)
 | 
			
		||||
#    define DBG_LED_ON PORT->Group[DEBUG_LED_PORT].OUTSET.reg = (1 << DEBUG_LED_PIN)
 | 
			
		||||
#    define DBG_LED_OFF PORT->Group[DEBUG_LED_PORT].OUTCLR.reg = (1 << DEBUG_LED_PIN)
 | 
			
		||||
#else
 | 
			
		||||
#    define DBG_LED_ENA
 | 
			
		||||
#    define DBG_LED_DIS
 | 
			
		||||
#    define DBG_LED_ON
 | 
			
		||||
#    define DBG_LED_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Debug Port 1 */
 | 
			
		||||
#if DEBUG_PORT1_ENABLE == 1
 | 
			
		||||
#    define DBG_1_ENA PORT->Group[DEBUG_PORT1_PORT].DIRSET.reg = (1 << DEBUG_PORT1_PIN)
 | 
			
		||||
#    define DBG_1_DIS PORT->Group[DEBUG_PORT1_PORT].DIRCLR.reg = (1 << DEBUG_PORT1_PIN)
 | 
			
		||||
#    define DBG_1_ON PORT->Group[DEBUG_PORT1_PORT].OUTSET.reg = (1 << DEBUG_PORT1_PIN)
 | 
			
		||||
#    define DBG_1_OFF PORT->Group[DEBUG_PORT1_PORT].OUTCLR.reg = (1 << DEBUG_PORT1_PIN)
 | 
			
		||||
#else
 | 
			
		||||
#    define DBG_1_ENA
 | 
			
		||||
#    define DBG_1_DIS
 | 
			
		||||
#    define DBG_1_ON
 | 
			
		||||
#    define DBG_1_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Debug Port 2 */
 | 
			
		||||
#if DEBUG_PORT2_ENABLE == 1
 | 
			
		||||
#    define DBG_2_ENA PORT->Group[DEBUG_PORT2_PORT].DIRSET.reg = (1 << DEBUG_PORT2_PIN)
 | 
			
		||||
#    define DBG_2_DIS PORT->Group[DEBUG_PORT2_PORT].DIRCLR.reg = (1 << DEBUG_PORT2_PIN)
 | 
			
		||||
#    define DBG_2_ON PORT->Group[DEBUG_PORT2_PORT].OUTSET.reg = (1 << DEBUG_PORT2_PIN)
 | 
			
		||||
#    define DBG_2_OFF PORT->Group[DEBUG_PORT2_PORT].OUTCLR.reg = (1 << DEBUG_PORT2_PIN)
 | 
			
		||||
#else
 | 
			
		||||
#    define DBG_2_ENA
 | 
			
		||||
#    define DBG_2_DIS
 | 
			
		||||
#    define DBG_2_ON
 | 
			
		||||
#    define DBG_2_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Debug Port 3 */
 | 
			
		||||
#if DEBUG_PORT3_ENABLE == 1
 | 
			
		||||
#    define DBG_3_ENA PORT->Group[DEBUG_PORT3_PORT].DIRSET.reg = (1 << DEBUG_PORT3_PIN)
 | 
			
		||||
#    define DBG_3_DIS PORT->Group[DEBUG_PORT3_PORT].DIRCLR.reg = (1 << DEBUG_PORT3_PIN)
 | 
			
		||||
#    define DBG_3_ON PORT->Group[DEBUG_PORT3_PORT].OUTSET.reg = (1 << DEBUG_PORT3_PIN)
 | 
			
		||||
#    define DBG_3_OFF PORT->Group[DEBUG_PORT3_PORT].OUTCLR.reg = (1 << DEBUG_PORT3_PIN)
 | 
			
		||||
#else
 | 
			
		||||
#    define DBG_3_ENA
 | 
			
		||||
#    define DBG_3_DIS
 | 
			
		||||
#    define DBG_3_ON
 | 
			
		||||
#    define DBG_3_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void dbg_print(uint32_t x);
 | 
			
		||||
void dled_print(uint32_t x, uint8_t long_pause);
 | 
			
		||||
 | 
			
		||||
void debug_code_init(void);
 | 
			
		||||
void debug_code_disable(void);
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_BOOT_TRACING_ENABLE
 | 
			
		||||
 | 
			
		||||
#    define DBGC(n) debug_code = n
 | 
			
		||||
 | 
			
		||||
extern volatile uint32_t debug_code;
 | 
			
		||||
 | 
			
		||||
enum debug_code_list {
 | 
			
		||||
    DC_UNSET = 0,
 | 
			
		||||
    DC_CLK_INIT_BEGIN,
 | 
			
		||||
    DC_CLK_INIT_COMPLETE,
 | 
			
		||||
    DC_CLK_SET_I2C1_FREQ_BEGIN,
 | 
			
		||||
    DC_CLK_SET_I2C1_FREQ_COMPLETE,
 | 
			
		||||
    DC_CLK_SET_I2C0_FREQ_BEGIN,
 | 
			
		||||
    DC_CLK_SET_I2C0_FREQ_COMPLETE,
 | 
			
		||||
    DC_CLK_SET_SPI_FREQ_BEGIN,
 | 
			
		||||
    DC_CLK_SET_SPI_FREQ_COMPLETE,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_BEGIN,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_SYNC_ENABLE,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_SYNC_SWRST_1,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_SYNC_SWRST_2,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_TC4_BEGIN,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_DISABLE,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_SWRST_1,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_SWRST_2,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_CLTRB,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_CC0,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_TC4_COMPLETE,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_TC5_BEGIN,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_DISABLE,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_SWRST_1,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_SWRST_2,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_CLTRB,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_TC5_COMPLETE,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_TC0_BEGIN,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_DISABLE,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_SWRST_1,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_SWRST_2,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_TC0_COMPLETE,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_EVSYS_BEGIN,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_EVSYS_COMPLETE,
 | 
			
		||||
    DC_CLK_ENABLE_TIMEBASE_COMPLETE,
 | 
			
		||||
    DC_CLK_SET_GCLK_FREQ_BEGIN,
 | 
			
		||||
    DC_CLK_SET_GCLK_FREQ_SYNC_1,
 | 
			
		||||
    DC_CLK_SET_GCLK_FREQ_SYNC_2,
 | 
			
		||||
    DC_CLK_SET_GCLK_FREQ_SYNC_3,
 | 
			
		||||
    DC_CLK_SET_GCLK_FREQ_SYNC_4,
 | 
			
		||||
    DC_CLK_SET_GCLK_FREQ_SYNC_5,
 | 
			
		||||
    DC_CLK_SET_GCLK_FREQ_COMPLETE,
 | 
			
		||||
    DC_CLK_INIT_OSC_BEGIN,
 | 
			
		||||
    DC_CLK_INIT_OSC_SYNC_1,
 | 
			
		||||
    DC_CLK_INIT_OSC_SYNC_2,
 | 
			
		||||
    DC_CLK_INIT_OSC_SYNC_3,
 | 
			
		||||
    DC_CLK_INIT_OSC_SYNC_4,
 | 
			
		||||
    DC_CLK_INIT_OSC_SYNC_5,
 | 
			
		||||
    DC_CLK_INIT_OSC_COMPLETE,
 | 
			
		||||
    DC_CLK_RESET_TIME_BEGIN,
 | 
			
		||||
    DC_CLK_RESET_TIME_COMPLETE,
 | 
			
		||||
    DC_CLK_OSC_INIT_BEGIN,
 | 
			
		||||
    DC_CLK_OSC_INIT_XOSC0_SYNC,
 | 
			
		||||
    DC_CLK_OSC_INIT_DPLL_SYNC_DISABLE,
 | 
			
		||||
    DC_CLK_OSC_INIT_DPLL_SYNC_RATIO,
 | 
			
		||||
    DC_CLK_OSC_INIT_DPLL_SYNC_ENABLE,
 | 
			
		||||
    DC_CLK_OSC_INIT_DPLL_WAIT_LOCK,
 | 
			
		||||
    DC_CLK_OSC_INIT_DPLL_WAIT_CLKRDY,
 | 
			
		||||
    DC_CLK_OSC_INIT_GCLK_SYNC_GENCTRL0,
 | 
			
		||||
    DC_CLK_OSC_INIT_COMPLETE,
 | 
			
		||||
    DC_SPI_INIT_BEGIN,
 | 
			
		||||
    DC_SPI_WRITE_DRE,
 | 
			
		||||
    DC_SPI_WRITE_TXC_1,
 | 
			
		||||
    DC_SPI_WRITE_TXC_2,
 | 
			
		||||
    DC_SPI_SYNC_ENABLING,
 | 
			
		||||
    DC_SPI_INIT_COMPLETE,
 | 
			
		||||
    DC_PORT_DETECT_INIT_BEGIN,
 | 
			
		||||
    DC_PORT_DETECT_INIT_FAILED,
 | 
			
		||||
    DC_PORT_DETECT_INIT_COMPLETE,
 | 
			
		||||
    DC_USB_RESET_BEGIN,
 | 
			
		||||
    DC_USB_RESET_COMPLETE,
 | 
			
		||||
    DC_USB_SET_HOST_BY_VOLTAGE_BEGIN,
 | 
			
		||||
    DC_USB_SET_HOST_5V_LOW_WAITING,
 | 
			
		||||
    DC_USB_SET_HOST_BY_VOLTAGE_COMPLETE,
 | 
			
		||||
    DC_USB_CONFIGURE_BEGIN,
 | 
			
		||||
    DC_USB_CONFIGURE_GET_SERIAL,
 | 
			
		||||
    DC_USB_CONFIGURE_COMPLETE,
 | 
			
		||||
    DC_USB_WRITE2422_BLOCK_BEGIN,
 | 
			
		||||
    DC_USB_WRITE2422_BLOCK_SYNC_SYSOP,
 | 
			
		||||
    DC_USB_WRITE2422_BLOCK_COMPLETE,
 | 
			
		||||
    DC_ADC0_CLOCK_INIT_BEGIN,
 | 
			
		||||
    DC_ADC0_CLOCK_INIT_COMPLETE,
 | 
			
		||||
    DC_ADC0_INIT_BEGIN,
 | 
			
		||||
    DC_ADC0_SWRST_SYNCING_1,
 | 
			
		||||
    DC_ADC0_SWRST_SYNCING_2,
 | 
			
		||||
    DC_ADC0_AVGCTRL_SYNCING_1,
 | 
			
		||||
    DC_ADC0_AVGCTRL_SYNCING_2,
 | 
			
		||||
    DC_ADC0_SAMPCTRL_SYNCING_1,
 | 
			
		||||
    DC_ADC0_ENABLE_SYNCING_1,
 | 
			
		||||
    DC_ADC0_INIT_COMPLETE,
 | 
			
		||||
    DC_I2C0_INIT_BEGIN,
 | 
			
		||||
    DC_I2C0_INIT_SYNC_ENABLING,
 | 
			
		||||
    DC_I2C0_INIT_SYNC_SYSOP,
 | 
			
		||||
    DC_I2C0_INIT_WAIT_IDLE,
 | 
			
		||||
    DC_I2C0_INIT_COMPLETE,
 | 
			
		||||
    DC_I2C1_INIT_BEGIN,
 | 
			
		||||
    DC_I2C1_INIT_SYNC_ENABLING,
 | 
			
		||||
    DC_I2C1_INIT_SYNC_SYSOP,
 | 
			
		||||
    DC_I2C1_INIT_WAIT_IDLE,
 | 
			
		||||
    DC_I2C1_INIT_COMPLETE,
 | 
			
		||||
    DC_I2C3733_INIT_CONTROL_BEGIN,
 | 
			
		||||
    DC_I2C3733_INIT_CONTROL_COMPLETE,
 | 
			
		||||
    DC_I2C3733_INIT_DRIVERS_BEGIN,
 | 
			
		||||
    DC_I2C3733_INIT_DRIVERS_COMPLETE,
 | 
			
		||||
    DC_I2C_DMAC_LED_INIT_BEGIN,
 | 
			
		||||
    DC_I2C_DMAC_LED_INIT_COMPLETE,
 | 
			
		||||
    DC_I2C3733_CONTROL_SET_BEGIN,
 | 
			
		||||
    DC_I2C3733_CONTROL_SET_COMPLETE,
 | 
			
		||||
    DC_LED_MATRIX_INIT_BEGIN,
 | 
			
		||||
    DC_LED_MATRIX_INIT_COMPLETE,
 | 
			
		||||
    DC_USB2422_INIT_BEGIN,
 | 
			
		||||
    DC_USB2422_INIT_WAIT_5V_LOW,
 | 
			
		||||
    DC_USB2422_INIT_OSC_SYNC_DISABLING,
 | 
			
		||||
    DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_1,
 | 
			
		||||
    DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_2,
 | 
			
		||||
    DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_3,
 | 
			
		||||
    DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_4,
 | 
			
		||||
    DC_USB2422_INIT_OSC_SYNC_DFLLMUL,
 | 
			
		||||
    DC_USB2422_INIT_OSC_SYNC_ENABLING,
 | 
			
		||||
    DC_USB2422_INIT_USB_SYNC_SWRST,
 | 
			
		||||
    DC_USB2422_INIT_USB_WAIT_SWRST,
 | 
			
		||||
    DC_USB2422_INIT_USB_SYNC_ENABLING,
 | 
			
		||||
    DC_USB2422_INIT_COMPLETE,
 | 
			
		||||
    DC_MAIN_UDC_START_BEGIN,
 | 
			
		||||
    DC_MAIN_UDC_START_COMPLETE,
 | 
			
		||||
    DC_MAIN_CDC_INIT_BEGIN,
 | 
			
		||||
    DC_MAIN_CDC_INIT_COMPLETE,
 | 
			
		||||
    /* Never change the order of error codes! Only add codes to end! */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#    define DBGC(n) \
 | 
			
		||||
        {}
 | 
			
		||||
 | 
			
		||||
#endif // DEBUG_BOOT_TRACING_ENABLE
 | 
			
		||||
 | 
			
		||||
#endif //_D51_UTIL_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,593 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "arm_atsam_protocol.h"
 | 
			
		||||
 | 
			
		||||
#if !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
 | 
			
		||||
 | 
			
		||||
#    include <string.h>
 | 
			
		||||
 | 
			
		||||
// From keyboard
 | 
			
		||||
#    include "config.h"
 | 
			
		||||
#    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
 | 
			
		||||
 | 
			
		||||
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 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)
 | 
			
		||||
 | 
			
		||||
void i2c0_init(void) {
 | 
			
		||||
    DBGC(DC_I2C0_INIT_BEGIN);
 | 
			
		||||
 | 
			
		||||
    CLK_set_i2c0_freq(CHAN_SERCOM_I2C0, FREQ_I2C0_DEFAULT);
 | 
			
		||||
 | 
			
		||||
    // MCU
 | 
			
		||||
    PORT->Group[0].PMUX[4].bit.PMUXE    = 2;
 | 
			
		||||
    PORT->Group[0].PMUX[4].bit.PMUXO    = 2;
 | 
			
		||||
    PORT->Group[0].PINCFG[8].bit.PMUXEN = 1;
 | 
			
		||||
    PORT->Group[0].PINCFG[9].bit.PMUXEN = 1;
 | 
			
		||||
 | 
			
		||||
    // 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.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
 | 
			
		||||
    while (SERCOM0->I2CM.SYNCBUSY.bit.ENABLE) {
 | 
			
		||||
        DBGC(DC_I2C0_INIT_SYNC_ENABLING);
 | 
			
		||||
    } // Wait for SYNCBUSY.ENABLE to clear
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_I2C0_INIT_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t i2c0_start(uint8_t address) {
 | 
			
		||||
    SERCOM0->I2CM.ADDR.bit.ADDR = address;
 | 
			
		||||
    while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) {
 | 
			
		||||
    }
 | 
			
		||||
    while (SERCOM0->I2CM.INTFLAG.bit.MB == 0) {
 | 
			
		||||
    }
 | 
			
		||||
    while (SERCOM0->I2CM.STATUS.bit.RXNACK) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t i2c0_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout) {
 | 
			
		||||
    if (!length) return 0;
 | 
			
		||||
 | 
			
		||||
    i2c0_start(address);
 | 
			
		||||
 | 
			
		||||
    while (length) {
 | 
			
		||||
        SERCOM0->I2CM.DATA.bit.DATA = *data;
 | 
			
		||||
        while (SERCOM0->I2CM.INTFLAG.bit.MB == 0) {
 | 
			
		||||
        }
 | 
			
		||||
        while (SERCOM0->I2CM.STATUS.bit.RXNACK) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        data++;
 | 
			
		||||
        length--;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    i2c0_stop();
 | 
			
		||||
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c0_stop(void) {
 | 
			
		||||
    if (SERCOM0->I2CM.STATUS.bit.CLKHOLD || SERCOM0->I2CM.INTFLAG.bit.MB == 1 || SERCOM0->I2CM.STATUS.bit.BUSSTATE != 1) {
 | 
			
		||||
        SERCOM0->I2CM.CTRLB.bit.CMD = 3;
 | 
			
		||||
        while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP)
 | 
			
		||||
            ;
 | 
			
		||||
        while (SERCOM0->I2CM.STATUS.bit.CLKHOLD)
 | 
			
		||||
            ;
 | 
			
		||||
        while (SERCOM0->I2CM.INTFLAG.bit.MB)
 | 
			
		||||
            ;
 | 
			
		||||
        while (SERCOM0->I2CM.STATUS.bit.BUSSTATE != 1)
 | 
			
		||||
            ;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
 | 
			
		||||
void i2c1_init(void) {
 | 
			
		||||
    DBGC(DC_I2C1_INIT_BEGIN);
 | 
			
		||||
 | 
			
		||||
    CLK_set_i2c1_freq(CHAN_SERCOM_I2C1, FREQ_I2C1_DEFAULT);
 | 
			
		||||
 | 
			
		||||
    /* MCU */
 | 
			
		||||
    PORT->Group[0].PMUX[8].bit.PMUXE     = 2;
 | 
			
		||||
    PORT->Group[0].PMUX[8].bit.PMUXO     = 2;
 | 
			
		||||
    PORT->Group[0].PINCFG[16].bit.PMUXEN = 1;
 | 
			
		||||
    PORT->Group[0].PINCFG[17].bit.PMUXEN = 1;
 | 
			
		||||
 | 
			
		||||
    /* 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.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)
 | 
			
		||||
    while (SERCOM1->I2CM.SYNCBUSY.bit.ENABLE) {
 | 
			
		||||
        DBGC(DC_I2C1_INIT_SYNC_ENABLING);
 | 
			
		||||
    } // Wait for SYNCBUSY.ENABLE to clear
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_I2C1_INIT_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t i2c1_start(uint8_t address) {
 | 
			
		||||
    SERCOM1->I2CM.ADDR.bit.ADDR = address;
 | 
			
		||||
    while (SERCOM1->I2CM.SYNCBUSY.bit.SYSOP) {
 | 
			
		||||
    }
 | 
			
		||||
    while (SERCOM1->I2CM.INTFLAG.bit.MB == 0) {
 | 
			
		||||
    }
 | 
			
		||||
    while (SERCOM1->I2CM.STATUS.bit.RXNACK) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t i2c1_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout) {
 | 
			
		||||
    if (!length) return 0;
 | 
			
		||||
 | 
			
		||||
    i2c1_start(address);
 | 
			
		||||
 | 
			
		||||
    while (length) {
 | 
			
		||||
        SERCOM1->I2CM.DATA.bit.DATA = *data;
 | 
			
		||||
        while (SERCOM1->I2CM.INTFLAG.bit.MB == 0) {
 | 
			
		||||
        }
 | 
			
		||||
        while (SERCOM1->I2CM.STATUS.bit.RXNACK) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        data++;
 | 
			
		||||
        length--;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    i2c1_stop();
 | 
			
		||||
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c1_stop(void) {
 | 
			
		||||
    if (SERCOM1->I2CM.STATUS.bit.CLKHOLD || SERCOM1->I2CM.INTFLAG.bit.MB == 1 || SERCOM1->I2CM.STATUS.bit.BUSSTATE != 1) {
 | 
			
		||||
        SERCOM1->I2CM.CTRLB.bit.CMD = 3;
 | 
			
		||||
        while (SERCOM1->I2CM.SYNCBUSY.bit.SYSOP)
 | 
			
		||||
            ;
 | 
			
		||||
        while (SERCOM1->I2CM.STATUS.bit.CLKHOLD)
 | 
			
		||||
            ;
 | 
			
		||||
        while (SERCOM1->I2CM.INTFLAG.bit.MB)
 | 
			
		||||
            ;
 | 
			
		||||
        while (SERCOM1->I2CM.STATUS.bit.BUSSTATE != 1)
 | 
			
		||||
            ;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_send_CRWL(uint8_t drvid) {
 | 
			
		||||
    uint8_t i2cdata[] = {ISSI3733_CMDRWL, ISSI3733_CMDRWL_WRITE_ENABLE_ONCE};
 | 
			
		||||
    i2c1_transmit(issidrv[drvid].addr, i2cdata, sizeof(i2cdata), 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_select_page(uint8_t drvid, uint8_t pageno) {
 | 
			
		||||
    uint8_t i2cdata[] = {ISSI3733_CMDR, pageno};
 | 
			
		||||
    i2c1_transmit(issidrv[drvid].addr, i2cdata, sizeof(i2cdata), 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_send_GCR(uint8_t drvid) {
 | 
			
		||||
    uint8_t i2cdata[] = {ISSI3733_GCCR, 0x00};
 | 
			
		||||
 | 
			
		||||
    if (gcr_actual > LED_GCR_MAX) gcr_actual = LED_GCR_MAX;
 | 
			
		||||
    i2cdata[1] = gcr_actual;
 | 
			
		||||
 | 
			
		||||
    i2c1_transmit(issidrv[drvid].addr, i2cdata, sizeof(i2cdata), 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_send_onoff(uint8_t drvid) {
 | 
			
		||||
#    if I2C_LED_USE_DMA != 1
 | 
			
		||||
    if (!i2c_led_q_running) {
 | 
			
		||||
#    endif
 | 
			
		||||
        i2c_led_send_CRWL(drvid);
 | 
			
		||||
        i2c_led_select_page(drvid, 0);
 | 
			
		||||
#    if I2C_LED_USE_DMA != 1
 | 
			
		||||
    }
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    *issidrv[drvid].onoff = 0; // Force start location offset to zero
 | 
			
		||||
    i2c1_transmit(issidrv[drvid].addr, issidrv[drvid].onoff, ISSI3733_PG0_BYTES, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_send_mode_op_gcr(uint8_t drvid, uint8_t mode, uint8_t operation) {
 | 
			
		||||
    uint8_t i2cdata[] = {ISSI3733_CR, mode | operation, gcr_actual};
 | 
			
		||||
    i2c1_transmit(issidrv[drvid].addr, i2cdata, sizeof(i2cdata), 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_send_pur_pdr(uint8_t drvid, uint8_t pur, uint8_t pdr) {
 | 
			
		||||
    uint8_t i2cdata[] = {ISSI3733_SWYR_PUR, pur, pdr};
 | 
			
		||||
 | 
			
		||||
    i2c1_transmit(issidrv[drvid].addr, i2cdata, sizeof(i2cdata), 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_send_pwm(uint8_t drvid) {
 | 
			
		||||
#    if I2C_LED_USE_DMA != 1
 | 
			
		||||
    if (!i2c_led_q_running) {
 | 
			
		||||
#    endif
 | 
			
		||||
        i2c_led_send_CRWL(drvid);
 | 
			
		||||
        i2c_led_select_page(drvid, 0);
 | 
			
		||||
#    if I2C_LED_USE_DMA != 1
 | 
			
		||||
    }
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    *issidrv[drvid].pwm = 0; // Force start location offset to zero
 | 
			
		||||
    i2c1_transmit(issidrv[drvid].addr, issidrv[drvid].pwm, ISSI3733_PG1_BYTES, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t I2C3733_Init_Control(void) {
 | 
			
		||||
    DBGC(DC_I2C3733_INIT_CONTROL_BEGIN);
 | 
			
		||||
 | 
			
		||||
    // Hardware state shutdown on boot
 | 
			
		||||
    // USB state machine will enable driver when communication is ready
 | 
			
		||||
    I2C3733_Control_Set(0);
 | 
			
		||||
 | 
			
		||||
    wait_ms(1);
 | 
			
		||||
 | 
			
		||||
    sr_exp_data.bit.IRST = 0;
 | 
			
		||||
    SR_EXP_WriteData();
 | 
			
		||||
 | 
			
		||||
    wait_ms(1);
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_I2C3733_INIT_CONTROL_COMPLETE);
 | 
			
		||||
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t I2C3733_Init_Drivers(void) {
 | 
			
		||||
    DBGC(DC_I2C3733_INIT_DRIVERS_BEGIN);
 | 
			
		||||
 | 
			
		||||
    gcr_actual      = ISSI3733_GCR_DEFAULT;
 | 
			
		||||
    gcr_actual_last = gcr_actual;
 | 
			
		||||
 | 
			
		||||
    if (gcr_actual > LED_GCR_MAX) gcr_actual = LED_GCR_MAX;
 | 
			
		||||
    gcr_desired = gcr_actual;
 | 
			
		||||
 | 
			
		||||
    void issi3733_prepare_arrays(void);
 | 
			
		||||
    issi3733_prepare_arrays();
 | 
			
		||||
 | 
			
		||||
    // 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
 | 
			
		||||
 | 
			
		||||
    // 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_CRWL(0);
 | 
			
		||||
    i2c_led_select_page(0, 3);
 | 
			
		||||
    i2c_led_send_pur_pdr(0, ISSI3733_SWYR_PUR_8000, ISSI3733_CSXR_PDR_8000);
 | 
			
		||||
 | 
			
		||||
    i2c_led_send_CRWL(1);
 | 
			
		||||
    i2c_led_select_page(1, 3);
 | 
			
		||||
    i2c_led_send_pur_pdr(1, ISSI3733_SWYR_PUR_8000, ISSI3733_CSXR_PDR_8000);
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_I2C3733_INIT_DRIVERS_COMPLETE);
 | 
			
		||||
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void I2C_DMAC_LED_Init(void) {
 | 
			
		||||
    Dmac *dmac = DMAC;
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_I2C_DMAC_LED_INIT_BEGIN);
 | 
			
		||||
 | 
			
		||||
    // Disable device
 | 
			
		||||
    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
 | 
			
		||||
    while (dmac->CTRL.bit.SWRST) {
 | 
			
		||||
    } // 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)
 | 
			
		||||
 | 
			
		||||
    // Disable 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
 | 
			
		||||
    while (dmac->Channel[0].CHCTRLA.bit.SWRST) {
 | 
			
		||||
    } // 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
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
    while (dmac->CTRL.bit.DMAENABLE == 0) {
 | 
			
		||||
    } // Wait for enable state
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_I2C_DMAC_LED_INIT_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// state = 1 enable
 | 
			
		||||
// state = 0 disable
 | 
			
		||||
void I2C3733_Control_Set(uint8_t state) {
 | 
			
		||||
    DBGC(DC_I2C3733_CONTROL_SET_BEGIN);
 | 
			
		||||
 | 
			
		||||
    sr_exp_data.bit.SDB_N = (state == 1 ? 1 : 0);
 | 
			
		||||
    SR_EXP_WriteData();
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_I2C3733_CONTROL_SET_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_prepare_send_dma(uint8_t *data, uint8_t len) {
 | 
			
		||||
    i2c_led_desc_defaults();
 | 
			
		||||
 | 
			
		||||
    dmac_desc.BTCNT.reg    = len;
 | 
			
		||||
    dmac_desc.SRCADDR.reg  = (uint32_t)data + len;
 | 
			
		||||
    dmac_desc.DSTADDR.reg  = (uint32_t)&SERCOM1->I2CM.DATA.reg;
 | 
			
		||||
    dmac_desc.DESCADDR.reg = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_begin_dma(uint8_t drvid) {
 | 
			
		||||
    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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_send_CRWL_dma(uint8_t drvid) {
 | 
			
		||||
    *(dma_sendbuf + 0) = ISSI3733_CMDRWL;
 | 
			
		||||
    *(dma_sendbuf + 1) = ISSI3733_CMDRWL_WRITE_ENABLE_ONCE;
 | 
			
		||||
    i2c_led_prepare_send_dma(dma_sendbuf, 2);
 | 
			
		||||
 | 
			
		||||
    i2c_led_begin_dma(drvid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_select_page_dma(uint8_t drvid, uint8_t pageno) {
 | 
			
		||||
    *(dma_sendbuf + 0) = ISSI3733_CMDR;
 | 
			
		||||
    *(dma_sendbuf + 1) = pageno;
 | 
			
		||||
    i2c_led_prepare_send_dma(dma_sendbuf, 2);
 | 
			
		||||
 | 
			
		||||
    i2c_led_begin_dma(drvid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_send_GCR_dma(uint8_t drvid) {
 | 
			
		||||
    *(dma_sendbuf + 0) = ISSI3733_GCCR;
 | 
			
		||||
    *(dma_sendbuf + 1) = gcr_actual;
 | 
			
		||||
    i2c_led_prepare_send_dma(dma_sendbuf, 2);
 | 
			
		||||
 | 
			
		||||
    i2c_led_begin_dma(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
 | 
			
		||||
    i2c_led_prepare_send_dma(dma_sendbuf, ISSI3733_PG1_BYTES);
 | 
			
		||||
 | 
			
		||||
    i2c_led_begin_dma(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
 | 
			
		||||
    i2c_led_prepare_send_dma(dma_sendbuf, ISSI3733_PG0_BYTES);
 | 
			
		||||
 | 
			
		||||
    i2c_led_begin_dma(drvid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_q_init(void) {
 | 
			
		||||
    memset(i2c_led_q, 0, I2C_Q_SIZE);
 | 
			
		||||
    i2c_led_q_s       = 0;
 | 
			
		||||
    i2c_led_q_e       = 0;
 | 
			
		||||
    i2c_led_q_running = 0;
 | 
			
		||||
    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_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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_led_q_add(uint8_t cmd) {
 | 
			
		||||
    // WARNING: Always request room before adding commands!
 | 
			
		||||
 | 
			
		||||
    // 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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Always request room before adding commands
 | 
			
		||||
// PS: In case the queue somehow gets filled, it will reset if it can not clear up
 | 
			
		||||
// PS: Could only get this to happen through unrealistic timings to overload the I2C bus
 | 
			
		||||
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
 | 
			
		||||
        {
 | 
			
		||||
            DBG_LED_ON;
 | 
			
		||||
            I2C_DMAC_LED_Init();
 | 
			
		||||
            i2c_led_q_init();
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    i2c_led_q_full = 0;
 | 
			
		||||
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t i2c_led_q_run(void) {
 | 
			
		||||
    if (i2c_led_q_isempty()) {
 | 
			
		||||
        i2c_led_q_running = 0;
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (i2c_led_q_running) return 1;
 | 
			
		||||
 | 
			
		||||
    i2c_led_q_running = 1;
 | 
			
		||||
 | 
			
		||||
#    if I2C_LED_USE_DMA != 1
 | 
			
		||||
    while (!i2c_led_q_isempty()) {
 | 
			
		||||
#    endif
 | 
			
		||||
        // run command
 | 
			
		||||
        if (i2c_led_q[i2c_led_q_s] == I2C_Q_CRWL) {
 | 
			
		||||
            i2c_led_q_s_advance();
 | 
			
		||||
            uint8_t drvid = i2c_led_q[i2c_led_q_s];
 | 
			
		||||
#    if I2C_LED_USE_DMA == 1
 | 
			
		||||
            i2c_led_send_CRWL_dma(drvid);
 | 
			
		||||
#    else
 | 
			
		||||
        i2c_led_send_CRWL(drvid);
 | 
			
		||||
#    endif
 | 
			
		||||
        } else if (i2c_led_q[i2c_led_q_s] == I2C_Q_PAGE_SELECT) {
 | 
			
		||||
            i2c_led_q_s_advance();
 | 
			
		||||
            uint8_t drvid = i2c_led_q[i2c_led_q_s];
 | 
			
		||||
            i2c_led_q_s_advance();
 | 
			
		||||
            uint8_t page = i2c_led_q[i2c_led_q_s];
 | 
			
		||||
#    if I2C_LED_USE_DMA == 1
 | 
			
		||||
            i2c_led_select_page_dma(drvid, page);
 | 
			
		||||
#    else
 | 
			
		||||
        i2c_led_select_page(drvid, page);
 | 
			
		||||
#    endif
 | 
			
		||||
        } else if (i2c_led_q[i2c_led_q_s] == I2C_Q_PWM) {
 | 
			
		||||
            i2c_led_q_s_advance();
 | 
			
		||||
            uint8_t drvid = i2c_led_q[i2c_led_q_s];
 | 
			
		||||
#    if I2C_LED_USE_DMA == 1
 | 
			
		||||
            i2c_led_send_pwm_dma(drvid);
 | 
			
		||||
#    else
 | 
			
		||||
        i2c_led_send_pwm(drvid);
 | 
			
		||||
#    endif
 | 
			
		||||
        } else if (i2c_led_q[i2c_led_q_s] == I2C_Q_GCR) {
 | 
			
		||||
            i2c_led_q_s_advance();
 | 
			
		||||
            uint8_t drvid = i2c_led_q[i2c_led_q_s];
 | 
			
		||||
#    if I2C_LED_USE_DMA == 1
 | 
			
		||||
            i2c_led_send_GCR_dma(drvid);
 | 
			
		||||
#    else
 | 
			
		||||
        i2c_led_send_GCR(drvid);
 | 
			
		||||
#    endif
 | 
			
		||||
        } else if (i2c_led_q[i2c_led_q_s] == I2C_Q_ONOFF) {
 | 
			
		||||
            i2c_led_q_s_advance();
 | 
			
		||||
            uint8_t drvid = i2c_led_q[i2c_led_q_s];
 | 
			
		||||
#    if I2C_LED_USE_DMA == 1
 | 
			
		||||
            i2c_led_send_onoff_dma(drvid);
 | 
			
		||||
#    else
 | 
			
		||||
        i2c_led_send_onoff(drvid);
 | 
			
		||||
#    endif
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        i2c_led_q_s_advance(); // Advance last run command or if the command byte was not serviced
 | 
			
		||||
 | 
			
		||||
#    if I2C_LED_USE_DMA != 1
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    i2c_led_q_running = 0;
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((weak)) void i2c_init(void) {
 | 
			
		||||
    static bool is_initialised = false;
 | 
			
		||||
    if (!is_initialised) {
 | 
			
		||||
        is_initialised = true;
 | 
			
		||||
 | 
			
		||||
        i2c0_init();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
i2c_status_t i2c_transmit(uint8_t address, const uint8_t *data, uint16_t length, uint16_t timeout) {
 | 
			
		||||
    uint8_t ret                 = i2c0_transmit(address, (uint8_t *)data, length, timeout);
 | 
			
		||||
    SERCOM0->I2CM.CTRLB.bit.CMD = 0x03;
 | 
			
		||||
    while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) {
 | 
			
		||||
        DBGC(DC_USB_WRITE2422_BLOCK_SYNC_SYSOP);
 | 
			
		||||
    }
 | 
			
		||||
    return ret ? I2C_STATUS_SUCCESS : I2C_STATUS_ERROR;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
 | 
			
		||||
| 
						 | 
				
			
			@ -1,113 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _I2C_MASTER_H_
 | 
			
		||||
#define _I2C_MASTER_H_
 | 
			
		||||
 | 
			
		||||
#ifndef MD_BOOTLOADER
 | 
			
		||||
 | 
			
		||||
#    include "samd51j18a.h"
 | 
			
		||||
#    include "issi3733_driver.h"
 | 
			
		||||
#    include "config.h"
 | 
			
		||||
 | 
			
		||||
extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc;
 | 
			
		||||
extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb;
 | 
			
		||||
 | 
			
		||||
uint8_t I2C3733_Init_Control(void);
 | 
			
		||||
uint8_t I2C3733_Init_Drivers(void);
 | 
			
		||||
void    I2C3733_Control_Set(uint8_t state);
 | 
			
		||||
void    I2C_DMAC_LED_Init(void);
 | 
			
		||||
 | 
			
		||||
#    define I2C_Q_SIZE 100
 | 
			
		||||
 | 
			
		||||
#    define I2C_Q_NA 100
 | 
			
		||||
#    define I2C_Q_CRWL 101
 | 
			
		||||
#    define I2C_Q_PAGE_SELECT 102
 | 
			
		||||
#    define I2C_Q_PWM 103
 | 
			
		||||
#    define I2C_Q_GCR 104
 | 
			
		||||
#    define I2C_Q_ONOFF 105
 | 
			
		||||
 | 
			
		||||
#    define I2C_DMA_MAX_SEND 255
 | 
			
		||||
 | 
			
		||||
extern volatile uint8_t i2c_led_q_running;
 | 
			
		||||
 | 
			
		||||
#    define I2C_LED_Q_PWM(a)                      \
 | 
			
		||||
        {                                         \
 | 
			
		||||
            if (i2c_led_q_request_room(7)) {      \
 | 
			
		||||
                i2c_led_q_add(I2C_Q_CRWL);        \
 | 
			
		||||
                i2c_led_q_add(a);                 \
 | 
			
		||||
                i2c_led_q_add(I2C_Q_PAGE_SELECT); \
 | 
			
		||||
                i2c_led_q_add(a);                 \
 | 
			
		||||
                i2c_led_q_add(ISSI3733_PG_PWM);   \
 | 
			
		||||
                i2c_led_q_add(I2C_Q_PWM);         \
 | 
			
		||||
                i2c_led_q_add(a);                 \
 | 
			
		||||
            }                                     \
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#    define I2C_LED_Q_GCR(a)                      \
 | 
			
		||||
        {                                         \
 | 
			
		||||
            if (i2c_led_q_request_room(7)) {      \
 | 
			
		||||
                i2c_led_q_add(I2C_Q_CRWL);        \
 | 
			
		||||
                i2c_led_q_add(a);                 \
 | 
			
		||||
                i2c_led_q_add(I2C_Q_PAGE_SELECT); \
 | 
			
		||||
                i2c_led_q_add(a);                 \
 | 
			
		||||
                i2c_led_q_add(ISSI3733_PG_FN);    \
 | 
			
		||||
                i2c_led_q_add(I2C_Q_GCR);         \
 | 
			
		||||
                i2c_led_q_add(a);                 \
 | 
			
		||||
            }                                     \
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#    define I2C_LED_Q_ONOFF(a)                    \
 | 
			
		||||
        {                                         \
 | 
			
		||||
            if (i2c_led_q_request_room(7)) {      \
 | 
			
		||||
                i2c_led_q_add(I2C_Q_CRWL);        \
 | 
			
		||||
                i2c_led_q_add(a);                 \
 | 
			
		||||
                i2c_led_q_add(I2C_Q_PAGE_SELECT); \
 | 
			
		||||
                i2c_led_q_add(a);                 \
 | 
			
		||||
                i2c_led_q_add(ISSI3733_PG_ONOFF); \
 | 
			
		||||
                i2c_led_q_add(I2C_Q_ONOFF);       \
 | 
			
		||||
                i2c_led_q_add(a);                 \
 | 
			
		||||
            }                                     \
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
void    i2c_led_q_init(void);
 | 
			
		||||
void    i2c_led_q_add(uint8_t cmd);
 | 
			
		||||
void    i2c_led_q_s_advance(void);
 | 
			
		||||
uint8_t i2c_led_q_size(void);
 | 
			
		||||
uint8_t i2c_led_q_request_room(uint8_t request_size);
 | 
			
		||||
uint8_t i2c_led_q_run(void);
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
void    i2c0_init(void);
 | 
			
		||||
uint8_t i2c0_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout);
 | 
			
		||||
void    i2c0_stop(void);
 | 
			
		||||
 | 
			
		||||
// Terrible interface compatiblity...
 | 
			
		||||
#define I2C_STATUS_SUCCESS (0)
 | 
			
		||||
#define I2C_STATUS_ERROR (-1)
 | 
			
		||||
 | 
			
		||||
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_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,201 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _ISSI3733_DRIVER_H_
 | 
			
		||||
#define _ISSI3733_DRIVER_H_
 | 
			
		||||
 | 
			
		||||
// ISII3733 Registers
 | 
			
		||||
 | 
			
		||||
#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_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_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
 | 
			
		||||
#define ISSI3733_PG_SR ISSI3733_PG0
 | 
			
		||||
#define ISSI3733_PG_PWM ISSI3733_PG1
 | 
			
		||||
#define ISSI3733_PG_ABM ISSI3733_PG2
 | 
			
		||||
#define ISSI3733_PG_FN ISSI3733_PG3
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
// PG3: Configuration Register: Software Shutdown Control
 | 
			
		||||
//#define ISSI3733_CR_SSD_SHUTDOWN 0x00         //Software shutdown
 | 
			
		||||
#define ISSI3733_CR_SSD_NORMAL 0x01 // Normal operation
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
// 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_LTA_LOOP_ENDLESS 0x00
 | 
			
		||||
#define ISSI3733_ABCR3_LTA_LOOP_1 0x01
 | 
			
		||||
#define ISSI3733_ABCR3_LTA_LOOP_2 0x02
 | 
			
		||||
#define ISSI3733_ABCR3_LTA_LOOP_3 0x03
 | 
			
		||||
#define ISSI3733_ABCR3_LTA_LOOP_4 0x04
 | 
			
		||||
#define ISSI3733_ABCR3_LTA_LOOP_5 0x05
 | 
			
		||||
#define ISSI3733_ABCR3_LTA_LOOP_6 0x06
 | 
			
		||||
#define ISSI3733_ABCR3_LTA_LOOP_7 0x07
 | 
			
		||||
#define ISSI3733_ABCR3_LTA_LOOP_8 0x08
 | 
			
		||||
#define ISSI3733_ABCR3_LTA_LOOP_9 0x09
 | 
			
		||||
#define ISSI3733_ABCR3_LTA_LOOP_10 0x0A
 | 
			
		||||
#define ISSI3733_ABCR3_LTA_LOOP_11 0x0B
 | 
			
		||||
#define ISSI3733_ABCR3_LTA_LOOP_12 0x0C
 | 
			
		||||
#define ISSI3733_ABCR3_LTA_LOOP_13 0x0D
 | 
			
		||||
#define ISSI3733_ABCR3_LTA_LOOP_14 0x0E
 | 
			
		||||
#define ISSI3733_ABCR3_LTA_LOOP_15 0x0F
 | 
			
		||||
 | 
			
		||||
// Loop Begin
 | 
			
		||||
#define ISSI3733_ABCR3_LB_T1 0x00
 | 
			
		||||
#define ISSI3733_ABCR3_LB_T2 0x10
 | 
			
		||||
#define ISSI3733_ABCR3_LB_T3 0x20
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
// 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_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
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
// PG3: Reset Register
 | 
			
		||||
#define ISSI3733_RR 0x11 // Read to reset all registers to default values
 | 
			
		||||
 | 
			
		||||
#endif //_ISSI3733_DRIVER_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,381 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "samd51j18a.h"
 | 
			
		||||
#include "keyboard.h"
 | 
			
		||||
 | 
			
		||||
#include "report.h"
 | 
			
		||||
#include "host.h"
 | 
			
		||||
#include "host_driver.h"
 | 
			
		||||
#include "suspend.h"
 | 
			
		||||
#include "keycode_config.h"
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
// From protocol directory
 | 
			
		||||
#include "arm_atsam_protocol.h"
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
void    main_subtasks(void);
 | 
			
		||||
uint8_t keyboard_leds(void);
 | 
			
		||||
void    send_keyboard(report_keyboard_t *report);
 | 
			
		||||
void    send_nkro(report_nkro_t *report);
 | 
			
		||||
void    send_mouse(report_mouse_t *report);
 | 
			
		||||
void    send_extra(report_extra_t *report);
 | 
			
		||||
 | 
			
		||||
#ifdef DEFERRED_EXEC_ENABLE
 | 
			
		||||
void deferred_exec_task(void);
 | 
			
		||||
#endif // DEFERRED_EXEC_ENABLE
 | 
			
		||||
 | 
			
		||||
host_driver_t arm_atsam_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};
 | 
			
		||||
 | 
			
		||||
uint8_t led_states;
 | 
			
		||||
 | 
			
		||||
uint8_t keyboard_leds(void) {
 | 
			
		||||
#ifdef NKRO_ENABLE
 | 
			
		||||
    if (keymap_config.nkro)
 | 
			
		||||
        return udi_hid_nkro_report_set;
 | 
			
		||||
    else
 | 
			
		||||
#endif // NKRO_ENABLE
 | 
			
		||||
        return udi_hid_kbd_report_set;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void send_keyboard(report_keyboard_t *report) {
 | 
			
		||||
    uint32_t irqflags;
 | 
			
		||||
 | 
			
		||||
    while (udi_hid_kbd_b_report_trans_ongoing) {
 | 
			
		||||
        main_subtasks();
 | 
			
		||||
    } // Run other tasks while waiting for USB to be free
 | 
			
		||||
 | 
			
		||||
    irqflags = __get_PRIMASK();
 | 
			
		||||
    __disable_irq();
 | 
			
		||||
    __DMB();
 | 
			
		||||
 | 
			
		||||
    memcpy(udi_hid_kbd_report, report, UDI_HID_KBD_REPORT_SIZE);
 | 
			
		||||
    udi_hid_kbd_b_report_valid = 1;
 | 
			
		||||
    udi_hid_kbd_send_report();
 | 
			
		||||
 | 
			
		||||
    __DMB();
 | 
			
		||||
    __set_PRIMASK(irqflags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void send_nkro(report_nkro_t *report) {
 | 
			
		||||
#ifdef NKRO_ENABLE
 | 
			
		||||
    uint32_t irqflags;
 | 
			
		||||
 | 
			
		||||
    while (udi_hid_nkro_b_report_trans_ongoing) {
 | 
			
		||||
        main_subtasks();
 | 
			
		||||
    } // Run other tasks while waiting for USB to be free
 | 
			
		||||
 | 
			
		||||
    irqflags = __get_PRIMASK();
 | 
			
		||||
    __disable_irq();
 | 
			
		||||
    __DMB();
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
        Skipping ahead `sizeof(report->report_id)` bytes
 | 
			
		||||
        since `report_id` is not used by this driver
 | 
			
		||||
     */
 | 
			
		||||
    void *report_no_report_id = (void *)((char *)report + sizeof(report->report_id));
 | 
			
		||||
 | 
			
		||||
    memcpy(udi_hid_nkro_report, report_no_report_id, UDI_HID_NKRO_REPORT_SIZE);
 | 
			
		||||
    udi_hid_nkro_b_report_valid = 1;
 | 
			
		||||
    udi_hid_nkro_send_report();
 | 
			
		||||
 | 
			
		||||
    __DMB();
 | 
			
		||||
    __set_PRIMASK(irqflags);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void send_mouse(report_mouse_t *report) {
 | 
			
		||||
#ifdef MOUSEKEY_ENABLE
 | 
			
		||||
    uint32_t irqflags;
 | 
			
		||||
 | 
			
		||||
    irqflags = __get_PRIMASK();
 | 
			
		||||
    __disable_irq();
 | 
			
		||||
    __DMB();
 | 
			
		||||
 | 
			
		||||
#    ifdef MOUSE_SHARED_EP
 | 
			
		||||
    /*
 | 
			
		||||
        Skipping ahead `sizeof(report->report_id)` bytes
 | 
			
		||||
        since `report_id` is not used by this driver
 | 
			
		||||
     */
 | 
			
		||||
    void *report_no_report_id = (void *)((char *)report + sizeof(report->report_id));
 | 
			
		||||
 | 
			
		||||
    memcpy(udi_hid_mou_report, report_no_report_id, UDI_HID_MOU_REPORT_SIZE);
 | 
			
		||||
#    else
 | 
			
		||||
    memcpy(udi_hid_mou_report, report, UDI_HID_MOU_REPORT_SIZE);
 | 
			
		||||
#    endif
 | 
			
		||||
    udi_hid_mou_b_report_valid = 1;
 | 
			
		||||
    udi_hid_mou_send_report();
 | 
			
		||||
 | 
			
		||||
    __DMB();
 | 
			
		||||
    __set_PRIMASK(irqflags);
 | 
			
		||||
#endif // MOUSEKEY_ENABLE
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void send_extra(report_extra_t *report) {
 | 
			
		||||
#ifdef EXTRAKEY_ENABLE
 | 
			
		||||
    uint32_t irqflags;
 | 
			
		||||
 | 
			
		||||
    irqflags = __get_PRIMASK();
 | 
			
		||||
    __disable_irq();
 | 
			
		||||
    __DMB();
 | 
			
		||||
 | 
			
		||||
    memcpy(udi_hid_exk_report, report, UDI_HID_EXK_REPORT_SIZE);
 | 
			
		||||
    udi_hid_exk_b_report_valid = 1;
 | 
			
		||||
    udi_hid_exk_send_report();
 | 
			
		||||
 | 
			
		||||
    __DMB();
 | 
			
		||||
    __set_PRIMASK(irqflags);
 | 
			
		||||
#endif // EXTRAKEY_ENABLE
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
#    define CONSOLE_PRINTBUF_SIZE 512
 | 
			
		||||
static char     console_printbuf[CONSOLE_PRINTBUF_SIZE];
 | 
			
		||||
static uint16_t console_printbuf_len = 0;
 | 
			
		||||
 | 
			
		||||
int8_t sendchar(uint8_t c) {
 | 
			
		||||
    if (console_printbuf_len >= CONSOLE_PRINTBUF_SIZE) return -1;
 | 
			
		||||
 | 
			
		||||
    console_printbuf[console_printbuf_len++] = c;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_subtask_console_flush(void) {
 | 
			
		||||
    while (udi_hid_con_b_report_trans_ongoing) {
 | 
			
		||||
    } // 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
 | 
			
		||||
 | 
			
		||||
    while (result > 0) { // While not error and bytes remain
 | 
			
		||||
        while (udi_hid_con_b_report_trans_ongoing) {
 | 
			
		||||
        } // 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
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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
 | 
			
		||||
 | 
			
		||||
        __DMB();
 | 
			
		||||
        __set_PRIMASK(irqflags);
 | 
			
		||||
 | 
			
		||||
        result -= send_out;  // Decrement result by bytes sent
 | 
			
		||||
        pconbuf += send_out; // Increment buffer point by bytes sent
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    console_printbuf_len = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
    if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SUSPEND_Val) // If USB SUSPENDED
 | 
			
		||||
    {
 | 
			
		||||
        fsmstate_on_delay = 0; // Clear ON delay timer
 | 
			
		||||
 | 
			
		||||
        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
 | 
			
		||||
        }
 | 
			
		||||
    } else if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SLEEP_Val) // Else if USB SLEEPING
 | 
			
		||||
    {
 | 
			
		||||
        fsmstate_on_delay = 0; // Clear ON delay timer
 | 
			
		||||
 | 
			
		||||
        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
 | 
			
		||||
        }
 | 
			
		||||
    } 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 (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
 | 
			
		||||
            {
 | 
			
		||||
                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
 | 
			
		||||
    {
 | 
			
		||||
        fsmstate_on_delay = 0; // Clear ON delay timer
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_subtask_power_check(void) {
 | 
			
		||||
    static uint64_t next_5v_checkup = 0;
 | 
			
		||||
 | 
			
		||||
    if (timer_read64() > next_5v_checkup) {
 | 
			
		||||
        next_5v_checkup = timer_read64() + 5;
 | 
			
		||||
 | 
			
		||||
        v_5v     = adc_get(ADC_5V);
 | 
			
		||||
        v_5v_avg = 0.9 * v_5v_avg + 0.1 * v_5v;
 | 
			
		||||
 | 
			
		||||
#ifdef RGB_MATRIX_ENABLE
 | 
			
		||||
        gcr_compute();
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_subtask_usb_extra_device(void) {
 | 
			
		||||
    static uint64_t next_usb_checkup = 0;
 | 
			
		||||
 | 
			
		||||
    if (timer_read64() > next_usb_checkup) {
 | 
			
		||||
        next_usb_checkup = timer_read64() + 10;
 | 
			
		||||
 | 
			
		||||
        USB_HandleExtraDevice();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef RAW_ENABLE
 | 
			
		||||
void main_subtask_raw(void) {
 | 
			
		||||
    udi_hid_raw_receive_report();
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void main_subtasks(void) {
 | 
			
		||||
    main_subtask_usb_state();
 | 
			
		||||
    main_subtask_power_check();
 | 
			
		||||
    main_subtask_usb_extra_device();
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
    main_subtask_console_flush();
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef RAW_ENABLE
 | 
			
		||||
    main_subtask_raw();
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(void) {
 | 
			
		||||
    DBG_LED_ENA;
 | 
			
		||||
    DBG_1_ENA;
 | 
			
		||||
    DBG_1_OFF;
 | 
			
		||||
    DBG_2_ENA;
 | 
			
		||||
    DBG_2_OFF;
 | 
			
		||||
    DBG_3_ENA;
 | 
			
		||||
    DBG_3_OFF;
 | 
			
		||||
 | 
			
		||||
    debug_code_init();
 | 
			
		||||
 | 
			
		||||
    CLK_init();
 | 
			
		||||
 | 
			
		||||
    ADC0_init();
 | 
			
		||||
 | 
			
		||||
    SR_EXP_Init();
 | 
			
		||||
 | 
			
		||||
#ifdef RGB_MATRIX_ENABLE
 | 
			
		||||
    i2c1_init();
 | 
			
		||||
#endif // RGB_MATRIX_ENABLE
 | 
			
		||||
 | 
			
		||||
    USB_Hub_init();
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_MAIN_UDC_START_BEGIN);
 | 
			
		||||
    udc_start();
 | 
			
		||||
    DBGC(DC_MAIN_UDC_START_COMPLETE);
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_MAIN_CDC_INIT_BEGIN);
 | 
			
		||||
    CDC_init();
 | 
			
		||||
    DBGC(DC_MAIN_CDC_INIT_COMPLETE);
 | 
			
		||||
 | 
			
		||||
    while (USB_Hub_Port_Detect_Init() == 0) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DBG_LED_OFF;
 | 
			
		||||
 | 
			
		||||
#ifdef RGB_MATRIX_ENABLE
 | 
			
		||||
    while (I2C3733_Init_Control() != 1) {
 | 
			
		||||
    }
 | 
			
		||||
    while (I2C3733_Init_Drivers() != 1) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    I2C_DMAC_LED_Init();
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
    keyboard_setup();
 | 
			
		||||
 | 
			
		||||
    keyboard_init();
 | 
			
		||||
 | 
			
		||||
    host_set_driver(&arm_atsam_driver);
 | 
			
		||||
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
    uint64_t next_print = 0;
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
        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
 | 
			
		||||
                wait_ms(50);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        keyboard_task();
 | 
			
		||||
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
        if (timer_read64() > next_print) {
 | 
			
		||||
            next_print = timer_read64() + 250;
 | 
			
		||||
            // 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
 | 
			
		||||
 | 
			
		||||
#ifdef DEFERRED_EXEC_ENABLE
 | 
			
		||||
        // Run deferred executions
 | 
			
		||||
        deferred_exec_task();
 | 
			
		||||
#endif // DEFERRED_EXEC_ENABLE
 | 
			
		||||
 | 
			
		||||
        // Run housekeeping
 | 
			
		||||
        housekeeping_task();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,23 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _MAIN_ARM_ATSAM_H_
 | 
			
		||||
#define _MAIN_ARM_ATSAM_H_
 | 
			
		||||
 | 
			
		||||
uint8_t keyboard_leds(void);
 | 
			
		||||
 | 
			
		||||
#endif //_MAIN_ARM_ATSAM_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,556 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#define FLUSH_TIMEOUT 5000
 | 
			
		||||
#define EECONFIG_MD_LED ((uint8_t*)(EECONFIG_SIZE + 64))
 | 
			
		||||
#define MD_LED_CONFIG_VERSION 1
 | 
			
		||||
 | 
			
		||||
#ifdef RGB_MATRIX_ENABLE
 | 
			
		||||
#    include "arm_atsam_protocol.h"
 | 
			
		||||
#    include "led.h"
 | 
			
		||||
#    include "rgb_matrix.h"
 | 
			
		||||
#    include "eeprom.h"
 | 
			
		||||
#    include "host.h"
 | 
			
		||||
#    include <string.h>
 | 
			
		||||
#    include <math.h>
 | 
			
		||||
 | 
			
		||||
#    ifdef USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
// TODO?: wire these up to keymap.c
 | 
			
		||||
md_led_config_t md_led_config = {0};
 | 
			
		||||
 | 
			
		||||
EECONFIG_DEBOUNCE_HELPER(md_led, EECONFIG_MD_LED, md_led_config);
 | 
			
		||||
 | 
			
		||||
void eeconfig_update_md_led_default(void) {
 | 
			
		||||
    md_led_config.ver = MD_LED_CONFIG_VERSION;
 | 
			
		||||
 | 
			
		||||
    gcr_desired               = LED_GCR_MAX;
 | 
			
		||||
    led_animation_orientation = 0;
 | 
			
		||||
    led_animation_direction   = 0;
 | 
			
		||||
    led_animation_breathing   = 0;
 | 
			
		||||
    led_animation_id          = 0;
 | 
			
		||||
    led_animation_speed       = 4.0f;
 | 
			
		||||
    led_lighting_mode         = LED_MODE_NORMAL;
 | 
			
		||||
    led_enabled               = 1;
 | 
			
		||||
    led_animation_breathe_cur = BREATHE_MIN_STEP;
 | 
			
		||||
    breathe_dir               = 1;
 | 
			
		||||
    led_animation_circular    = 0;
 | 
			
		||||
    led_edge_brightness       = 1.0f;
 | 
			
		||||
    led_ratio_brightness      = 1.0f;
 | 
			
		||||
    led_edge_mode             = LED_EDGE_MODE_ALL;
 | 
			
		||||
 | 
			
		||||
    eeconfig_flush_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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__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
 | 
			
		||||
 | 
			
		||||
void SERCOM1_0_Handler(void) {
 | 
			
		||||
    if (SERCOM1->I2CM.INTFLAG.bit.ERROR) {
 | 
			
		||||
        SERCOM1->I2CM.INTFLAG.reg = SERCOM_I2CM_INTENCLR_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DMAC_0_Handler(void) {
 | 
			
		||||
    if (DMAC->Channel[0].CHINTFLAG.bit.TCMPL) {
 | 
			
		||||
        DMAC->Channel[0].CHINTFLAG.reg = DMAC_CHINTENCLR_TCMPL;
 | 
			
		||||
 | 
			
		||||
        i2c1_stop();
 | 
			
		||||
 | 
			
		||||
        i2c_led_q_running = 0;
 | 
			
		||||
 | 
			
		||||
        i2c_led_q_run();
 | 
			
		||||
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (DMAC->Channel[0].CHINTFLAG.bit.TERR) {
 | 
			
		||||
        DMAC->Channel[0].CHINTFLAG.reg = DMAC_CHINTENCLR_TERR;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT];
 | 
			
		||||
 | 
			
		||||
issi3733_led_t led_map[ISSI3733_LED_COUNT] = ISSI3733_LED_MAP;
 | 
			
		||||
RGB            led_buffer[ISSI3733_LED_COUNT];
 | 
			
		||||
 | 
			
		||||
uint8_t gcr_actual;
 | 
			
		||||
uint8_t gcr_actual_last;
 | 
			
		||||
#    ifdef USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
uint8_t gcr_breathe;
 | 
			
		||||
float   breathe_mult;
 | 
			
		||||
float   pomod;
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    define ACT_GCR_NONE 0
 | 
			
		||||
#    define ACT_GCR_INC 1
 | 
			
		||||
#    define ACT_GCR_DEC 2
 | 
			
		||||
 | 
			
		||||
#    define LED_GCR_STEP_AUTO 2
 | 
			
		||||
 | 
			
		||||
static uint8_t gcr_min_counter;
 | 
			
		||||
static uint8_t v_5v_cat_hit;
 | 
			
		||||
 | 
			
		||||
// WARNING: Automatic GCR is in place to prevent USB shutdown and LED driver overloading
 | 
			
		||||
void gcr_compute(void) {
 | 
			
		||||
    uint8_t action  = ACT_GCR_NONE;
 | 
			
		||||
    uint8_t gcr_use = gcr_desired;
 | 
			
		||||
 | 
			
		||||
#    ifdef USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
    if (led_animation_breathing) {
 | 
			
		||||
        gcr_use = gcr_breathe;
 | 
			
		||||
    }
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    // If the 5v takes a catastrophic hit, disable the LED drivers briefly, assert auto gcr mode, min gcr and let the auto take over
 | 
			
		||||
    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
 | 
			
		||||
        return;
 | 
			
		||||
    } else if (v_5v_cat_hit > 1) {
 | 
			
		||||
        v_5v_cat_hit--;
 | 
			
		||||
        return;
 | 
			
		||||
    } else if (v_5v_cat_hit == 1) {
 | 
			
		||||
        I2C3733_Control_Set(1);
 | 
			
		||||
        CDC_print("USB: WARNING: Re-enabling LED drivers\r\n");
 | 
			
		||||
        v_5v_cat_hit = 0;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (usb_gcr_auto) {
 | 
			
		||||
        if (v_5v_avg < V5_LOW)
 | 
			
		||||
            action = ACT_GCR_DEC;
 | 
			
		||||
        else if (v_5v_avg > V5_HIGH && gcr_actual < gcr_use)
 | 
			
		||||
            action = ACT_GCR_INC;
 | 
			
		||||
        else if (gcr_actual > gcr_use)
 | 
			
		||||
            action = ACT_GCR_DEC;
 | 
			
		||||
    } else {
 | 
			
		||||
        if (gcr_actual < gcr_use)
 | 
			
		||||
            action = ACT_GCR_INC;
 | 
			
		||||
        else if (gcr_actual > gcr_use)
 | 
			
		||||
            action = ACT_GCR_DEC;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (action == ACT_GCR_NONE) {
 | 
			
		||||
        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
 | 
			
		||||
        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
 | 
			
		||||
        {
 | 
			
		||||
            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_ENABLED) // If extra usb is enabled
 | 
			
		||||
                {
 | 
			
		||||
                    gcr_min_counter++;
 | 
			
		||||
                    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
 | 
			
		||||
                        if (usb_extra_manual)
 | 
			
		||||
                            CDC_print("USB: Disabling extra port until replug and manual mode toggle!\r\n");
 | 
			
		||||
                        else
 | 
			
		||||
                            CDC_print("USB: Disabling extra port until replug!\r\n");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            // Power successfully cut back from LED drivers
 | 
			
		||||
            gcr_actual -= LED_GCR_STEP_AUTO;
 | 
			
		||||
            gcr_min_counter = 0;
 | 
			
		||||
 | 
			
		||||
#    ifdef USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
            // If breathe mode is active, the top end can fluctuate if the host can not supply enough current
 | 
			
		||||
            // So set the breathe GCR to where it becomes stable
 | 
			
		||||
            if (led_animation_breathing == 1) {
 | 
			
		||||
                gcr_breathe = gcr_actual;
 | 
			
		||||
                // PS: At this point, setting breathing to exhale makes a noticebly shorter cycle
 | 
			
		||||
                //    and the same would happen maybe one or two more times. Therefore I'm favoring
 | 
			
		||||
                //    powering through one full breathe and letting gcr settle completely
 | 
			
		||||
            }
 | 
			
		||||
#    endif
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void issi3733_prepare_arrays(void) {
 | 
			
		||||
    static bool s_init = false;
 | 
			
		||||
    if (s_init) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    s_init = true;
 | 
			
		||||
 | 
			
		||||
    memset(issidrv, 0, sizeof(issi3733_driver_t) * ISSI3733_DRIVER_COUNT);
 | 
			
		||||
 | 
			
		||||
    int     i;
 | 
			
		||||
    uint8_t addrs[ISSI3733_DRIVER_COUNT] = ISSI3773_DRIVER_ADDRESSES;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < ISSI3733_DRIVER_COUNT; i++) {
 | 
			
		||||
        issidrv[i].addr = addrs[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
 | 
			
		||||
        // BYTE: 1 + (SW-1)*16 + (CS-1)
 | 
			
		||||
        led_map[i].rgb.g = issidrv[led_map[i].adr.drv - 1].pwm + 1 + ((led_map[i].adr.swg - 1) * 16 + (led_map[i].adr.cs - 1));
 | 
			
		||||
        led_map[i].rgb.r = issidrv[led_map[i].adr.drv - 1].pwm + 1 + ((led_map[i].adr.swr - 1) * 16 + (led_map[i].adr.cs - 1));
 | 
			
		||||
        led_map[i].rgb.b = issidrv[led_map[i].adr.drv - 1].pwm + 1 + ((led_map[i].adr.swb - 1) * 16 + (led_map[i].adr.cs - 1));
 | 
			
		||||
 | 
			
		||||
        // BYTE: 1 + (SW-1)*2 + (CS-1)/8
 | 
			
		||||
        // BIT: (CS-1)%8
 | 
			
		||||
        *(issidrv[led_map[i].adr.drv - 1].onoff + 1 + (led_map[i].adr.swg - 1) * 2 + (led_map[i].adr.cs - 1) / 8) |= (1 << ((led_map[i].adr.cs - 1) % 8));
 | 
			
		||||
        *(issidrv[led_map[i].adr.drv - 1].onoff + 1 + (led_map[i].adr.swr - 1) * 2 + (led_map[i].adr.cs - 1) / 8) |= (1 << ((led_map[i].adr.cs - 1) % 8));
 | 
			
		||||
        *(issidrv[led_map[i].adr.drv - 1].onoff + 1 + (led_map[i].adr.swb - 1) * 2 + (led_map[i].adr.cs - 1) / 8) |= (1 << ((led_map[i].adr.cs - 1) % 8));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void md_rgb_matrix_prepare(void) {
 | 
			
		||||
    for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
 | 
			
		||||
        *led_map[i].rgb.r = 0;
 | 
			
		||||
        *led_map[i].rgb.g = 0;
 | 
			
		||||
        *led_map[i].rgb.b = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void led_set_one(int i, uint8_t r, uint8_t g, uint8_t b) {
 | 
			
		||||
    if (i < ISSI3733_LED_COUNT) {
 | 
			
		||||
#    ifdef USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
        md_rgb_matrix_config_override(i);
 | 
			
		||||
#    else
 | 
			
		||||
        led_buffer[i].r = r;
 | 
			
		||||
        led_buffer[i].g = g;
 | 
			
		||||
        led_buffer[i].b = b;
 | 
			
		||||
#    endif
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void led_set_all(uint8_t r, uint8_t g, uint8_t b) {
 | 
			
		||||
    for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
 | 
			
		||||
        led_set_one(i, r, g, b);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void init(void) {
 | 
			
		||||
    DBGC(DC_LED_MATRIX_INIT_BEGIN);
 | 
			
		||||
 | 
			
		||||
#    ifdef USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
    eeconfig_init_md_led();
 | 
			
		||||
    if (md_led_config.ver != MD_LED_CONFIG_VERSION) {
 | 
			
		||||
        eeconfig_update_md_led_default();
 | 
			
		||||
    }
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    issi3733_prepare_arrays();
 | 
			
		||||
 | 
			
		||||
    md_rgb_matrix_prepare();
 | 
			
		||||
 | 
			
		||||
    gcr_min_counter = 0;
 | 
			
		||||
    v_5v_cat_hit    = 0;
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_LED_MATRIX_INIT_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void flush(void) {
 | 
			
		||||
#    ifdef USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
    if (!led_enabled) {
 | 
			
		||||
        return;
 | 
			
		||||
    } // 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
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    // Wait for previous transfer to complete
 | 
			
		||||
    while (i2c_led_q_running) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Copy buffer to live DMA region
 | 
			
		||||
    for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
 | 
			
		||||
        *led_map[i].rgb.r = led_buffer[i].r;
 | 
			
		||||
        *led_map[i].rgb.g = led_buffer[i].g;
 | 
			
		||||
        *led_map[i].rgb.b = led_buffer[i].b;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#    ifdef USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
    breathe_mult = 1;
 | 
			
		||||
 | 
			
		||||
    if (led_animation_breathing) {
 | 
			
		||||
        //+60us 119 LED
 | 
			
		||||
        led_animation_breathe_cur += BREATHE_STEP * breathe_dir;
 | 
			
		||||
 | 
			
		||||
        if (led_animation_breathe_cur >= BREATHE_MAX_STEP)
 | 
			
		||||
            breathe_dir = -1;
 | 
			
		||||
        else if (led_animation_breathe_cur <= BREATHE_MIN_STEP)
 | 
			
		||||
            breathe_dir = 1;
 | 
			
		||||
 | 
			
		||||
        // Brightness curve created for 256 steps, 0 - ~98%
 | 
			
		||||
        breathe_mult = 0.000015 * led_animation_breathe_cur * led_animation_breathe_cur;
 | 
			
		||||
        if (breathe_mult > 1)
 | 
			
		||||
            breathe_mult = 1;
 | 
			
		||||
        else if (breathe_mult < 0)
 | 
			
		||||
            breathe_mult = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // This should only be performed once per frame
 | 
			
		||||
    pomod = (float)((g_rgb_timer / 10) % (uint32_t)(1000.0f / led_animation_speed)) / 10.0f * led_animation_speed;
 | 
			
		||||
    pomod *= 100.0f;
 | 
			
		||||
    pomod = (uint32_t)pomod % 10000;
 | 
			
		||||
    pomod /= 100.0f;
 | 
			
		||||
 | 
			
		||||
#    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
 | 
			
		||||
        gcr_actual_last = gcr_actual;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++)
 | 
			
		||||
        I2C_LED_Q_PWM(drvid); // Queue data
 | 
			
		||||
 | 
			
		||||
    i2c_led_q_run();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void md_rgb_matrix_indicators_advanced(uint8_t led_min, uint8_t led_max) {
 | 
			
		||||
    led_t led_state = host_keyboard_led_state();
 | 
			
		||||
    if (led_state.raw && rgb_matrix_config.enable) {
 | 
			
		||||
        for (uint8_t i = led_min; i < led_max; i++) {
 | 
			
		||||
            if (
 | 
			
		||||
#    if USB_LED_NUM_LOCK_SCANCODE != 255
 | 
			
		||||
                (led_map[i].scan == USB_LED_NUM_LOCK_SCANCODE && led_state.num_lock) ||
 | 
			
		||||
#    endif // NUM LOCK
 | 
			
		||||
#    if USB_LED_CAPS_LOCK_SCANCODE != 255
 | 
			
		||||
                (led_map[i].scan == USB_LED_CAPS_LOCK_SCANCODE && led_state.caps_lock) ||
 | 
			
		||||
#    endif // CAPS LOCK
 | 
			
		||||
#    if USB_LED_SCROLL_LOCK_SCANCODE != 255
 | 
			
		||||
                (led_map[i].scan == USB_LED_SCROLL_LOCK_SCANCODE && led_state.scroll_lock) ||
 | 
			
		||||
#    endif // SCROLL LOCK
 | 
			
		||||
#    if USB_LED_COMPOSE_SCANCODE != 255
 | 
			
		||||
                (led_map[i].scan == USB_LED_COMPOSE_SCANCODE && led_state.compose) ||
 | 
			
		||||
#    endif // COMPOSE
 | 
			
		||||
#    if USB_LED_KANA_SCANCODE != 255
 | 
			
		||||
                (led_map[i].scan == USB_LED_KANA_SCANCODE && led_state.kana) ||
 | 
			
		||||
#    endif // KANA
 | 
			
		||||
                (0)) {
 | 
			
		||||
                if (rgb_matrix_get_flags() & LED_FLAG_INDICATOR) {
 | 
			
		||||
                    led_buffer[i].r = 255 - led_buffer[i].r;
 | 
			
		||||
                    led_buffer[i].g = 255 - led_buffer[i].g;
 | 
			
		||||
                    led_buffer[i].b = 255 - led_buffer[i].b;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const rgb_matrix_driver_t rgb_matrix_driver = {.init = init, .flush = flush, .set_color = led_set_one, .set_color_all = led_set_all};
 | 
			
		||||
 | 
			
		||||
/*==============================================================================
 | 
			
		||||
=                           Legacy Lighting Support                            =
 | 
			
		||||
==============================================================================*/
 | 
			
		||||
 | 
			
		||||
#    ifdef USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
// Ported from Massdrop QMK GitHub Repo
 | 
			
		||||
 | 
			
		||||
static void led_run_pattern(led_setup_t* f, float* ro, float* go, float* bo, float pos) {
 | 
			
		||||
    float po;
 | 
			
		||||
 | 
			
		||||
    while (f->end != 1) {
 | 
			
		||||
        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))) {
 | 
			
		||||
            po -= pomod;
 | 
			
		||||
 | 
			
		||||
            if (po > 100)
 | 
			
		||||
                po -= 100;
 | 
			
		||||
            else if (po < 0)
 | 
			
		||||
                po += 100;
 | 
			
		||||
        } else if ((!led_animation_direction && f->ef & EF_SCR_L) || (led_animation_direction && (f->ef & EF_SCR_R))) {
 | 
			
		||||
            po += pomod;
 | 
			
		||||
 | 
			
		||||
            if (po > 100)
 | 
			
		||||
                po -= 100;
 | 
			
		||||
            else if (po < 0)
 | 
			
		||||
                po += 100;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Check if LED's po is in current frame
 | 
			
		||||
        if (po < f->hs) {
 | 
			
		||||
            f++;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        if (po > f->he) {
 | 
			
		||||
            f++;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        // note: < 0 or > 100 continue
 | 
			
		||||
 | 
			
		||||
        // Calculate the po within the start-stop percentage for color blending
 | 
			
		||||
        po = (po - f->hs) / (f->he - f->hs);
 | 
			
		||||
 | 
			
		||||
        // 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;
 | 
			
		||||
        } 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;
 | 
			
		||||
        } 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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        f++;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#        define RGB_MAX_DISTANCE 232.9635f
 | 
			
		||||
 | 
			
		||||
static void md_rgb_matrix_config_override(int i) {
 | 
			
		||||
    float ro = 0;
 | 
			
		||||
    float go = 0;
 | 
			
		||||
    float bo = 0;
 | 
			
		||||
    float po;
 | 
			
		||||
 | 
			
		||||
    uint8_t highest_active_layer = get_highest_layer(layer_state);
 | 
			
		||||
 | 
			
		||||
    if (led_animation_circular) {
 | 
			
		||||
        // TODO: should use min/max values from LED configuration instead of
 | 
			
		||||
        // hard-coded 224, 64
 | 
			
		||||
        // po = sqrtf((powf(fabsf((disp.width / 2) - (led_cur->x - disp.left)), 2) + powf(fabsf((disp.height / 2) - (led_cur->y - disp.bottom)), 2))) / disp.max_distance * 100;
 | 
			
		||||
        po = sqrtf((powf(fabsf((224 / 2) - (float)g_led_config.point[i].x), 2) + powf(fabsf((64 / 2) - (float)g_led_config.point[i].y), 2))) / RGB_MAX_DISTANCE * 100;
 | 
			
		||||
    } else {
 | 
			
		||||
        if (led_animation_orientation) {
 | 
			
		||||
            po = (float)g_led_config.point[i].y / 64.f * 100;
 | 
			
		||||
        } else {
 | 
			
		||||
            po = (float)g_led_config.point[i].x / 224.f * 100;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (led_edge_mode == LED_EDGE_MODE_ALTERNATE && LED_IS_EDGE_ALT(led_map[i].scan)) {
 | 
			
		||||
        // Do not act on this LED (Edge alternate lighting mode)
 | 
			
		||||
    } else if (led_lighting_mode == LED_MODE_KEYS_ONLY && HAS_FLAGS(g_led_config.flags[i], LED_FLAG_UNDERGLOW)) {
 | 
			
		||||
        // Do not act on this LED
 | 
			
		||||
    } else if (led_lighting_mode == LED_MODE_NON_KEYS_ONLY && !HAS_FLAGS(g_led_config.flags[i], LED_FLAG_UNDERGLOW)) {
 | 
			
		||||
        // Do not act on this LED
 | 
			
		||||
    } else if (led_lighting_mode == LED_MODE_INDICATORS_ONLY) {
 | 
			
		||||
        // Do not act on this LED (Only show indicators)
 | 
			
		||||
    } else {
 | 
			
		||||
        led_instruction_t* led_cur_instruction = led_instructions;
 | 
			
		||||
        while (!led_cur_instruction->end) {
 | 
			
		||||
            // Check if this applies to current layer
 | 
			
		||||
            if ((led_cur_instruction->flags & LED_FLAG_MATCH_LAYER) && (led_cur_instruction->layer != highest_active_layer)) {
 | 
			
		||||
                goto next_iter;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 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
 | 
			
		||||
                    goto next_iter;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (led_cur_instruction->flags & LED_FLAG_USE_RGB) {
 | 
			
		||||
                ro = led_cur_instruction->r;
 | 
			
		||||
                go = led_cur_instruction->g;
 | 
			
		||||
                bo = led_cur_instruction->b;
 | 
			
		||||
            } else if (led_cur_instruction->flags & LED_FLAG_USE_PATTERN) {
 | 
			
		||||
                led_run_pattern(led_setups[led_cur_instruction->pattern_id], &ro, &go, &bo, po);
 | 
			
		||||
            } else if (led_cur_instruction->flags & LED_FLAG_USE_ROTATE_PATTERN) {
 | 
			
		||||
                led_run_pattern(led_setups[led_animation_id], &ro, &go, &bo, po);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        next_iter:
 | 
			
		||||
            led_cur_instruction++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (ro > 255)
 | 
			
		||||
            ro = 255;
 | 
			
		||||
        else if (ro < 0)
 | 
			
		||||
            ro = 0;
 | 
			
		||||
        if (go > 255)
 | 
			
		||||
            go = 255;
 | 
			
		||||
        else if (go < 0)
 | 
			
		||||
            go = 0;
 | 
			
		||||
        if (bo > 255)
 | 
			
		||||
            bo = 255;
 | 
			
		||||
        else if (bo < 0)
 | 
			
		||||
            bo = 0;
 | 
			
		||||
 | 
			
		||||
        if (led_animation_breathing) {
 | 
			
		||||
            ro *= breathe_mult;
 | 
			
		||||
            go *= breathe_mult;
 | 
			
		||||
            bo *= breathe_mult;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Adjust edge LED brightness
 | 
			
		||||
    if (led_edge_brightness != 1 && LED_IS_EDGE(led_map[i].scan)) {
 | 
			
		||||
        ro *= led_edge_brightness;
 | 
			
		||||
        go *= led_edge_brightness;
 | 
			
		||||
        bo *= led_edge_brightness;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Adjust ratio of key vs. underglow (edge) LED brightness
 | 
			
		||||
    if (LED_IS_EDGE(led_map[i].scan) && led_ratio_brightness > 1.0) {
 | 
			
		||||
        // Decrease edge (underglow) LEDs
 | 
			
		||||
        ro *= (2.0 - led_ratio_brightness);
 | 
			
		||||
        go *= (2.0 - led_ratio_brightness);
 | 
			
		||||
        bo *= (2.0 - led_ratio_brightness);
 | 
			
		||||
    } else if (LED_IS_KEY(led_map[i].scan) && led_ratio_brightness < 1.0) {
 | 
			
		||||
        // Decrease KEY LEDs
 | 
			
		||||
        ro *= led_ratio_brightness;
 | 
			
		||||
        go *= led_ratio_brightness;
 | 
			
		||||
        bo *= led_ratio_brightness;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    led_buffer[i].r = (uint8_t)ro;
 | 
			
		||||
    led_buffer[i].g = (uint8_t)go;
 | 
			
		||||
    led_buffer[i].b = (uint8_t)bo;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#    endif // USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
#endif     // RGB_MATRIX_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			@ -1,200 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
// From keyboard
 | 
			
		||||
#include "config_led.h"
 | 
			
		||||
 | 
			
		||||
// CS1-CS16 Current Source "Col"
 | 
			
		||||
#define ISSI3733_CS_COUNT 16
 | 
			
		||||
 | 
			
		||||
// SW1-SW12 Switch "Row"
 | 
			
		||||
#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_PG_ONOFF_BYTES ISSI3733_PG0_BYTES
 | 
			
		||||
#define ISSI3733_PG_OR_BYTES ISSI3733_PG0_BYTES
 | 
			
		||||
#define ISSI3733_PG_SR_BYTES ISSI3733_PG0_BYTES
 | 
			
		||||
#define ISSI3733_PG_PWM_BYTES ISSI3733_PG1_BYTES
 | 
			
		||||
#define ISSI3733_PG_ABM_BYTES ISSI3733_PG2_BYTES
 | 
			
		||||
#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
 | 
			
		||||
} 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
 | 
			
		||||
} 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
 | 
			
		||||
} 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)
 | 
			
		||||
} issi3733_led_t;
 | 
			
		||||
 | 
			
		||||
extern issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT];
 | 
			
		||||
 | 
			
		||||
extern uint8_t gcr_breathe;
 | 
			
		||||
extern uint8_t gcr_actual;
 | 
			
		||||
extern uint8_t gcr_actual_last;
 | 
			
		||||
 | 
			
		||||
void gcr_compute(void);
 | 
			
		||||
 | 
			
		||||
void md_rgb_matrix_indicators_advanced(uint8_t led_min, uint8_t led_max);
 | 
			
		||||
 | 
			
		||||
/*-------------------------  Legacy Lighting Support  ------------------------*/
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
} 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
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
    uint8_t  layer;
 | 
			
		||||
    uint8_t  r;
 | 
			
		||||
    uint8_t  g;
 | 
			
		||||
    uint8_t  b;
 | 
			
		||||
    uint8_t  pattern_id;
 | 
			
		||||
    uint8_t  end;
 | 
			
		||||
} led_instruction_t;
 | 
			
		||||
 | 
			
		||||
extern led_instruction_t led_instructions[];
 | 
			
		||||
 | 
			
		||||
typedef struct led_config_s {
 | 
			
		||||
    uint8_t ver; // assumed to be zero on eeprom reset
 | 
			
		||||
 | 
			
		||||
    uint8_t desired_gcr;
 | 
			
		||||
    uint8_t animation_breathing;
 | 
			
		||||
    uint8_t animation_id;
 | 
			
		||||
    float   animation_speed;
 | 
			
		||||
    uint8_t lighting_mode;
 | 
			
		||||
    uint8_t enabled;
 | 
			
		||||
    uint8_t animation_breathe_cur;
 | 
			
		||||
    uint8_t animation_direction;
 | 
			
		||||
    uint8_t animation_breathe_dir;
 | 
			
		||||
    uint8_t animation_orientation;
 | 
			
		||||
    uint8_t animation_circular;
 | 
			
		||||
    float   edge_brightness;
 | 
			
		||||
    float   ratio_brightness;
 | 
			
		||||
    uint8_t edge_mode;
 | 
			
		||||
} md_led_config_t;
 | 
			
		||||
 | 
			
		||||
extern md_led_config_t md_led_config;
 | 
			
		||||
 | 
			
		||||
void md_led_changed(void);
 | 
			
		||||
 | 
			
		||||
#    define gcr_desired md_led_config.desired_gcr
 | 
			
		||||
#    define led_animation_breathing md_led_config.animation_breathing
 | 
			
		||||
#    define led_animation_id md_led_config.animation_id
 | 
			
		||||
#    define led_animation_speed md_led_config.animation_speed
 | 
			
		||||
#    define led_lighting_mode md_led_config.lighting_mode
 | 
			
		||||
#    define led_enabled md_led_config.enabled
 | 
			
		||||
#    define led_animation_breathe_cur md_led_config.animation_breathe_cur
 | 
			
		||||
#    define led_animation_direction md_led_config.animation_direction
 | 
			
		||||
#    define breathe_dir md_led_config.animation_breathe_dir
 | 
			
		||||
#    define led_animation_orientation md_led_config.animation_orientation
 | 
			
		||||
#    define led_animation_circular md_led_config.animation_circular
 | 
			
		||||
#    define led_edge_brightness md_led_config.edge_brightness
 | 
			
		||||
#    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_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_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_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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,102 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifdef RGB_MATRIX_ENABLE
 | 
			
		||||
#    ifdef USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
 | 
			
		||||
#        include "md_rgb_matrix.h"
 | 
			
		||||
#        include "util.h"
 | 
			
		||||
 | 
			
		||||
// Teal <-> Salmon
 | 
			
		||||
led_setup_t leds_teal_salmon[] = {
 | 
			
		||||
    {.hs = 0, .he = 33, .rs = 24, .re = 24, .gs = 215, .ge = 215, .bs = 204, .be = 204, .ef = EF_NONE},
 | 
			
		||||
    {.hs = 33, .he = 66, .rs = 24, .re = 255, .gs = 215, .ge = 114, .bs = 204, .be = 118, .ef = EF_NONE},
 | 
			
		||||
    {.hs = 66, .he = 100, .rs = 255, .re = 255, .gs = 114, .ge = 114, .bs = 118, .be = 118, .ef = EF_NONE},
 | 
			
		||||
    {.end = 1},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Yellow
 | 
			
		||||
led_setup_t leds_yellow[] = {
 | 
			
		||||
    {.hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_NONE},
 | 
			
		||||
    {.end = 1},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Off
 | 
			
		||||
led_setup_t leds_off[] = {
 | 
			
		||||
    {.hs = 0, .he = 100, .rs = 0, .re = 0, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_NONE},
 | 
			
		||||
    {.end = 1},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Red
 | 
			
		||||
led_setup_t leds_red[] = {
 | 
			
		||||
    {.hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_NONE},
 | 
			
		||||
    {.end = 1},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Green
 | 
			
		||||
led_setup_t leds_green[] = {
 | 
			
		||||
    {.hs = 0, .he = 100, .rs = 0, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_NONE},
 | 
			
		||||
    {.end = 1},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Blue
 | 
			
		||||
led_setup_t leds_blue[] = {
 | 
			
		||||
    {.hs = 0, .he = 100, .rs = 0, .re = 0, .gs = 0, .ge = 0, .bs = 255, .be = 255, .ef = EF_NONE},
 | 
			
		||||
    {.end = 1},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// White
 | 
			
		||||
led_setup_t leds_white[] = {
 | 
			
		||||
    {.hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 255, .ge = 255, .bs = 255, .be = 255, .ef = EF_NONE},
 | 
			
		||||
    {.end = 1},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// White with moving red stripe
 | 
			
		||||
led_setup_t leds_white_with_red_stripe[] = {
 | 
			
		||||
    {.hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 255, .ge = 255, .bs = 255, .be = 255, .ef = EF_NONE},
 | 
			
		||||
    {.hs = 0, .he = 15, .rs = 0, .re = 0, .gs = 0, .ge = 255, .bs = 0, .be = 255, .ef = EF_SCR_R | EF_SUBTRACT},
 | 
			
		||||
    {.hs = 15, .he = 30, .rs = 0, .re = 0, .gs = 255, .ge = 0, .bs = 255, .be = 0, .ef = EF_SCR_R | EF_SUBTRACT},
 | 
			
		||||
    {.end = 1},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Black with moving red stripe
 | 
			
		||||
led_setup_t leds_black_with_red_stripe[] = {
 | 
			
		||||
    {.hs = 0, .he = 15, .rs = 0, .re = 255, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_SCR_R},
 | 
			
		||||
    {.hs = 15, .he = 30, .rs = 255, .re = 0, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_SCR_R},
 | 
			
		||||
    {.end = 1},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Rainbow no scrolling
 | 
			
		||||
led_setup_t leds_rainbow_ns[] = {
 | 
			
		||||
    {.hs = 0, .he = 16.67, .rs = 255, .re = 255, .gs = 0, .ge = 255, .bs = 0, .be = 0, .ef = EF_OVER}, {.hs = 16.67, .he = 33.33, .rs = 255, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_OVER}, {.hs = 33.33, .he = 50, .rs = 0, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 255, .ef = EF_OVER}, {.hs = 50, .he = 66.67, .rs = 0, .re = 0, .gs = 255, .ge = 0, .bs = 255, .be = 255, .ef = EF_OVER}, {.hs = 66.67, .he = 83.33, .rs = 0, .re = 255, .gs = 0, .ge = 0, .bs = 255, .be = 255, .ef = EF_OVER}, {.hs = 83.33, .he = 100, .rs = 255, .re = 255, .gs = 0, .ge = 0, .bs = 255, .be = 0, .ef = EF_OVER}, {.end = 1},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Rainbow scrolling
 | 
			
		||||
led_setup_t leds_rainbow_s[] = {
 | 
			
		||||
    {.hs = 0, .he = 16.67, .rs = 255, .re = 255, .gs = 0, .ge = 255, .bs = 0, .be = 0, .ef = EF_OVER | EF_SCR_R}, {.hs = 16.67, .he = 33.33, .rs = 255, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_OVER | EF_SCR_R}, {.hs = 33.33, .he = 50, .rs = 0, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 255, .ef = EF_OVER | EF_SCR_R}, {.hs = 50, .he = 66.67, .rs = 0, .re = 0, .gs = 255, .ge = 0, .bs = 255, .be = 255, .ef = EF_OVER | EF_SCR_R}, {.hs = 66.67, .he = 83.33, .rs = 0, .re = 255, .gs = 0, .ge = 0, .bs = 255, .be = 255, .ef = EF_OVER | EF_SCR_R}, {.hs = 83.33, .he = 100, .rs = 255, .re = 255, .gs = 0, .ge = 0, .bs = 255, .be = 0, .ef = EF_OVER | EF_SCR_R}, {.end = 1},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Add new LED animations here using one from above as example
 | 
			
		||||
// The last entry must be { .end = 1 }
 | 
			
		||||
// Add the new animation name to the list below following its format
 | 
			
		||||
 | 
			
		||||
void *led_setups[] = {leds_rainbow_s, leds_rainbow_ns, leds_teal_salmon, leds_yellow, leds_red, leds_green, leds_blue, leds_white, leds_white_with_red_stripe, leds_black_with_red_stripe, leds_off};
 | 
			
		||||
 | 
			
		||||
const uint8_t led_setups_count = ARRAY_SIZE(led_setups);
 | 
			
		||||
 | 
			
		||||
#    endif // USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
#endif     // RGB_MATRIX_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			@ -1,122 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "arm_atsam_protocol.h"
 | 
			
		||||
 | 
			
		||||
#include "spi_master.h"
 | 
			
		||||
#include "wait.h"
 | 
			
		||||
#include "gpio.h"
 | 
			
		||||
 | 
			
		||||
// #define SR_USE_BITBANG
 | 
			
		||||
 | 
			
		||||
// Bodge for when spi_master is not available
 | 
			
		||||
#ifdef SR_USE_BITBANG
 | 
			
		||||
#    define CLOCK_DELAY 10
 | 
			
		||||
 | 
			
		||||
void shift_init_impl(void) {
 | 
			
		||||
    gpio_set_pin_output(SR_EXP_RCLK_PIN);
 | 
			
		||||
    gpio_set_pin_output(SPI_DATAOUT_PIN);
 | 
			
		||||
    gpio_set_pin_output(SPI_SCLK_PIN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void shift_out_impl(const uint8_t *data, uint16_t length) {
 | 
			
		||||
    gpio_write_pin_low(SR_EXP_RCLK_PIN);
 | 
			
		||||
    for (uint16_t i = 0; i < length; i++) {
 | 
			
		||||
        uint8_t val = data[i];
 | 
			
		||||
 | 
			
		||||
        // shift out lsb first
 | 
			
		||||
        for (uint8_t bit = 0; bit < 8; bit++) {
 | 
			
		||||
            gpio_write_pin(SPI_DATAOUT_PIN, !!(val & (1 << bit)));
 | 
			
		||||
            gpio_write_pin(SPI_SCLK_PIN, true);
 | 
			
		||||
            wait_us(CLOCK_DELAY);
 | 
			
		||||
 | 
			
		||||
            gpio_write_pin(SPI_SCLK_PIN, false);
 | 
			
		||||
            wait_us(CLOCK_DELAY);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    gpio_write_pin_high(SR_EXP_RCLK_PIN);
 | 
			
		||||
    return SPI_STATUS_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
    spi_transmit(data, length);
 | 
			
		||||
 | 
			
		||||
    spi_stop();
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// ***************************************************************
 | 
			
		||||
 | 
			
		||||
void shift_out(const uint8_t *data, uint16_t length) {
 | 
			
		||||
    shift_out_impl(data, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void shift_enable(void) {
 | 
			
		||||
    gpio_set_pin_output(SR_EXP_OE_PIN);
 | 
			
		||||
    gpio_write_pin_low(SR_EXP_OE_PIN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void shift_disable(void) {
 | 
			
		||||
    gpio_set_pin_output(SR_EXP_OE_PIN);
 | 
			
		||||
    gpio_write_pin_high(SR_EXP_OE_PIN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void shift_init(void) {
 | 
			
		||||
    shift_disable();
 | 
			
		||||
    shift_init_impl();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ***************************************************************
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
    };
 | 
			
		||||
    shift_out(data, 2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SR_EXP_Init(void) {
 | 
			
		||||
    shift_init();
 | 
			
		||||
 | 
			
		||||
    sr_exp_data.reg             = 0;
 | 
			
		||||
    sr_exp_data.bit.HUB_CONNECT = 0;
 | 
			
		||||
    sr_exp_data.bit.HUB_RESET_N = 0;
 | 
			
		||||
    sr_exp_data.bit.S_UP        = 0;
 | 
			
		||||
    sr_exp_data.bit.E_UP_N      = 1;
 | 
			
		||||
    sr_exp_data.bit.S_DN1       = 1;
 | 
			
		||||
    sr_exp_data.bit.E_DN1_N     = 1;
 | 
			
		||||
    sr_exp_data.bit.E_VBUS_1    = 0;
 | 
			
		||||
    sr_exp_data.bit.E_VBUS_2    = 0;
 | 
			
		||||
    sr_exp_data.bit.SRC_1       = 1;
 | 
			
		||||
    sr_exp_data.bit.SRC_2       = 1;
 | 
			
		||||
    sr_exp_data.bit.IRST        = 1;
 | 
			
		||||
    sr_exp_data.bit.SDB_N       = 0;
 | 
			
		||||
    SR_EXP_WriteData();
 | 
			
		||||
 | 
			
		||||
    shift_enable();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,49 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
/* Data structure to define Shift Register output expander hardware */
 | 
			
		||||
/* This structure gets shifted into registers LSB first */
 | 
			
		||||
typedef union {
 | 
			
		||||
    struct {
 | 
			
		||||
        uint16_t RSVD4 : 1;       /*!< bit:      0                                               */
 | 
			
		||||
        uint16_t RSVD3 : 1;       /*!< bit:      1                                               */
 | 
			
		||||
        uint16_t RSVD2 : 1;       /*!< bit:      2                                               */
 | 
			
		||||
        uint16_t RSVD1 : 1;       /*!< bit:      3                                               */
 | 
			
		||||
        uint16_t SDB_N : 1;       /*!< bit:      4  SHUTDOWN THE CHIP WHEN 0, RUN WHEN 1         */
 | 
			
		||||
        uint16_t IRST : 1;        /*!< bit:      5  RESET THE IS3733 I2C WHEN 1, RUN WHEN 0      */
 | 
			
		||||
        uint16_t SRC_2 : 1;       /*!< bit:      6  ADVERTISE A SOURCE TO USBC-2 CC              */
 | 
			
		||||
        uint16_t SRC_1 : 1;       /*!< bit:      7  ADVERTISE A SOURCE TO USBC-1 CC              */
 | 
			
		||||
        uint16_t E_VBUS_2 : 1;    /*!< bit:      8  ENABLE 5V OUT TO USBC-2 WHEN 1               */
 | 
			
		||||
        uint16_t E_VBUS_1 : 1;    /*!< bit:      9  ENABLE 5V OUT TO USBC-1 WHEN 1               */
 | 
			
		||||
        uint16_t E_DN1_N : 1;     /*!< bit:     10  ENABLE DN1 1:2 MUX WHEN 0                    */
 | 
			
		||||
        uint16_t S_DN1 : 1;       /*!< bit:     11  SELECT DN1 PATH 0:USBC-1, 1:USBC-2           */
 | 
			
		||||
        uint16_t E_UP_N : 1;      /*!< bit:     12  ENABLE SUP 1:2 MUX WHEN 0                    */
 | 
			
		||||
        uint16_t S_UP : 1;        /*!< bit:     13  SELECT UP PATH 0:USBC-1, 1:USBC-2            */
 | 
			
		||||
        uint16_t HUB_RESET_N : 1; /*!< bit:     14  RESET USB HUB WHEN 0, RUN WHEN 1             */
 | 
			
		||||
        uint16_t HUB_CONNECT : 1; /*!< bit:     15  SIGNAL VBUS CONNECT TO USB HUB WHEN 1        */
 | 
			
		||||
    } bit;                        /*!< Structure used for bit access                             */
 | 
			
		||||
    uint16_t reg;                 /*!< Type      used for register access                        */
 | 
			
		||||
} sr_exp_t;
 | 
			
		||||
 | 
			
		||||
extern sr_exp_t sr_exp_data;
 | 
			
		||||
 | 
			
		||||
void SR_EXP_WriteData(void);
 | 
			
		||||
void SR_EXP_Init(void);
 | 
			
		||||
| 
						 | 
				
			
			@ -1,109 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "arm_atsam_protocol.h"
 | 
			
		||||
#include "spi_master.h"
 | 
			
		||||
#include "gpio.h"
 | 
			
		||||
 | 
			
		||||
/* Determine bits to set for mux selection */
 | 
			
		||||
#if SPI_DATAOUT_PIN % 2 == 0
 | 
			
		||||
#    define SPI_DATAOUT_MUX_SEL PMUXE
 | 
			
		||||
#else
 | 
			
		||||
#    define SPI_DATAOUT_MUX_SEL PMUXO
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Determine bits to set for mux selection */
 | 
			
		||||
#if SPI_SCLK_PIN % 2 == 0
 | 
			
		||||
#    define SPI_SCLK_MUX_SEL PMUXE
 | 
			
		||||
#else
 | 
			
		||||
#    define SPI_SCLK_MUX_SEL PMUXO
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static pin_t currentSelectPin = NO_PIN;
 | 
			
		||||
 | 
			
		||||
__attribute__((weak)) void spi_init(void) {
 | 
			
		||||
    static bool is_initialised = false;
 | 
			
		||||
    if (!is_initialised) {
 | 
			
		||||
        is_initialised = true;
 | 
			
		||||
 | 
			
		||||
        DBGC(DC_SPI_INIT_BEGIN);
 | 
			
		||||
 | 
			
		||||
        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
 | 
			
		||||
 | 
			
		||||
        DBGC(DC_SPI_INIT_COMPLETE);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool spi_start(pin_t csPin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
 | 
			
		||||
    if (currentSelectPin != NO_PIN || csPin == NO_PIN) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    currentSelectPin = csPin;
 | 
			
		||||
    gpio_set_pin_output(currentSelectPin);
 | 
			
		||||
    gpio_write_pin_low(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.ENABLE = 1; // Enable - Peripheral is enabled or being enabled
 | 
			
		||||
    while (SPI_SERCOM->SPI.SYNCBUSY.bit.ENABLE) {
 | 
			
		||||
        DBGC(DC_SPI_SYNC_ENABLING);
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
spi_status_t spi_transmit(const uint8_t *data, uint16_t length) {
 | 
			
		||||
    while (!(SPI_SERCOM->SPI.INTFLAG.bit.DRE)) {
 | 
			
		||||
        DBGC(DC_SPI_WRITE_DRE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (uint16_t i = 0; i < length; i++) {
 | 
			
		||||
        SPI_SERCOM->SPI.DATA.bit.DATA = data[i];
 | 
			
		||||
        while (!(SPI_SERCOM->SPI.INTFLAG.bit.TXC)) {
 | 
			
		||||
            DBGC(DC_SPI_WRITE_TXC_1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return SPI_STATUS_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void spi_stop(void) {
 | 
			
		||||
    if (currentSelectPin != NO_PIN) {
 | 
			
		||||
        gpio_set_pin_output(currentSelectPin);
 | 
			
		||||
        gpio_write_pin_high(currentSelectPin);
 | 
			
		||||
        currentSelectPin = NO_PIN;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Not implemented yet....
 | 
			
		||||
 | 
			
		||||
spi_status_t spi_write(uint8_t data);
 | 
			
		||||
 | 
			
		||||
spi_status_t spi_read(void);
 | 
			
		||||
 | 
			
		||||
spi_status_t spi_receive(uint8_t *data, uint16_t length);
 | 
			
		||||
| 
						 | 
				
			
			@ -1,50 +0,0 @@
 | 
			
		|||
/* Copyright 2021 QMK
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *  the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 *  (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *  GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *  You should have received a copy of the GNU General Public License
 | 
			
		||||
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include "gpio.h"
 | 
			
		||||
 | 
			
		||||
typedef int16_t spi_status_t;
 | 
			
		||||
 | 
			
		||||
#define SPI_STATUS_SUCCESS (0)
 | 
			
		||||
#define SPI_STATUS_ERROR (-1)
 | 
			
		||||
#define SPI_STATUS_TIMEOUT (-2)
 | 
			
		||||
 | 
			
		||||
#define SPI_TIMEOUT_IMMEDIATE (0)
 | 
			
		||||
#define SPI_TIMEOUT_INFINITE (0xFFFF)
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
void spi_init(void);
 | 
			
		||||
 | 
			
		||||
bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor);
 | 
			
		||||
 | 
			
		||||
spi_status_t spi_write(uint8_t data);
 | 
			
		||||
 | 
			
		||||
spi_status_t spi_read(void);
 | 
			
		||||
 | 
			
		||||
spi_status_t spi_transmit(const uint8_t *data, uint16_t length);
 | 
			
		||||
 | 
			
		||||
spi_status_t spi_receive(uint8_t *data, uint16_t length);
 | 
			
		||||
 | 
			
		||||
void spi_stop(void);
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,563 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief gcc starttup file for SAMD51
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2017 Microchip Technology Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 | 
			
		||||
 * not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the Licence at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "samd51.h"
 | 
			
		||||
 | 
			
		||||
/* Initialize segments */
 | 
			
		||||
extern uint32_t _sfixed;
 | 
			
		||||
extern uint32_t _efixed;
 | 
			
		||||
extern uint32_t _etext;
 | 
			
		||||
extern uint32_t _srelocate;
 | 
			
		||||
extern uint32_t _erelocate;
 | 
			
		||||
extern uint32_t _szero;
 | 
			
		||||
extern uint32_t _ezero;
 | 
			
		||||
extern uint32_t _sstack;
 | 
			
		||||
extern uint32_t _estack;
 | 
			
		||||
 | 
			
		||||
/** \cond DOXYGEN_SHOULD_SKIP_THIS */
 | 
			
		||||
int main(void);
 | 
			
		||||
/** \endcond */
 | 
			
		||||
 | 
			
		||||
void __libc_init_array(void);
 | 
			
		||||
 | 
			
		||||
/* Default empty handler */
 | 
			
		||||
void Dummy_Handler(void);
 | 
			
		||||
 | 
			
		||||
/* Cortex-M4 core handlers */
 | 
			
		||||
void NMI_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void HardFault_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void MemManage_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void BusFault_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void UsageFault_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void SVC_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void DebugMon_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void PendSV_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void SysTick_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
 | 
			
		||||
/* Peripherals handlers */
 | 
			
		||||
void PM_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void MCLK_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void OSCCTRL_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* OSCCTRL_XOSCFAIL_0, OSCCTRL_XOSCRDY_0 */
 | 
			
		||||
void OSCCTRL_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* OSCCTRL_XOSCFAIL_1, OSCCTRL_XOSCRDY_1 */
 | 
			
		||||
void OSCCTRL_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* OSCCTRL_DFLLLOCKC, OSCCTRL_DFLLLOCKF, OSCCTRL_DFLLOOB, OSCCTRL_DFLLRCS, OSCCTRL_DFLLRDY */
 | 
			
		||||
void OSCCTRL_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* OSCCTRL_DPLLLCKF_0, OSCCTRL_DPLLLCKR_0, OSCCTRL_DPLLLDRTO_0, OSCCTRL_DPLLLTO_0 */
 | 
			
		||||
void OSCCTRL_4_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* OSCCTRL_DPLLLCKF_1, OSCCTRL_DPLLLCKR_1, OSCCTRL_DPLLLDRTO_1, OSCCTRL_DPLLLTO_1 */
 | 
			
		||||
void OSC32KCTRL_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void SUPC_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SUPC_B12SRDY, SUPC_B33SRDY, SUPC_BOD12RDY, SUPC_BOD33RDY, SUPC_VCORERDY, SUPC_VREGRDY */
 | 
			
		||||
void SUPC_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SUPC_BOD12DET, SUPC_BOD33DET */
 | 
			
		||||
void WDT_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void RTC_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void EIC_0_Handler(void) __attribute__((weak, alias("Dummy_Handler")));  /* EIC_EXTINT_0 */
 | 
			
		||||
void EIC_1_Handler(void) __attribute__((weak, alias("Dummy_Handler")));  /* EIC_EXTINT_1 */
 | 
			
		||||
void EIC_2_Handler(void) __attribute__((weak, alias("Dummy_Handler")));  /* EIC_EXTINT_2 */
 | 
			
		||||
void EIC_3_Handler(void) __attribute__((weak, alias("Dummy_Handler")));  /* EIC_EXTINT_3 */
 | 
			
		||||
void EIC_4_Handler(void) __attribute__((weak, alias("Dummy_Handler")));  /* EIC_EXTINT_4 */
 | 
			
		||||
void EIC_5_Handler(void) __attribute__((weak, alias("Dummy_Handler")));  /* EIC_EXTINT_5 */
 | 
			
		||||
void EIC_6_Handler(void) __attribute__((weak, alias("Dummy_Handler")));  /* EIC_EXTINT_6 */
 | 
			
		||||
void EIC_7_Handler(void) __attribute__((weak, alias("Dummy_Handler")));  /* EIC_EXTINT_7 */
 | 
			
		||||
void EIC_8_Handler(void) __attribute__((weak, alias("Dummy_Handler")));  /* EIC_EXTINT_8 */
 | 
			
		||||
void EIC_9_Handler(void) __attribute__((weak, alias("Dummy_Handler")));  /* EIC_EXTINT_9 */
 | 
			
		||||
void EIC_10_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_10 */
 | 
			
		||||
void EIC_11_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_11 */
 | 
			
		||||
void EIC_12_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_12 */
 | 
			
		||||
void EIC_13_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_13 */
 | 
			
		||||
void EIC_14_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_14 */
 | 
			
		||||
void EIC_15_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_15 */
 | 
			
		||||
void FREQM_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void NVMCTRL_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* NVMCTRL_0, NVMCTRL_1, NVMCTRL_2, NVMCTRL_3, NVMCTRL_4, NVMCTRL_5, NVMCTRL_6, NVMCTRL_7 */
 | 
			
		||||
void NVMCTRL_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* NVMCTRL_10, NVMCTRL_8, NVMCTRL_9 */
 | 
			
		||||
void DMAC_0_Handler(void) __attribute__((weak, alias("Dummy_Handler")));    /* DMAC_SUSP_0, DMAC_TCMPL_0, DMAC_TERR_0 */
 | 
			
		||||
void DMAC_1_Handler(void) __attribute__((weak, alias("Dummy_Handler")));    /* DMAC_SUSP_1, DMAC_TCMPL_1, DMAC_TERR_1 */
 | 
			
		||||
void DMAC_2_Handler(void) __attribute__((weak, alias("Dummy_Handler")));    /* DMAC_SUSP_2, DMAC_TCMPL_2, DMAC_TERR_2 */
 | 
			
		||||
void DMAC_3_Handler(void) __attribute__((weak, alias("Dummy_Handler")));    /* DMAC_SUSP_3, DMAC_TCMPL_3, DMAC_TERR_3 */
 | 
			
		||||
void DMAC_4_Handler(void) __attribute__((weak, alias("Dummy_Handler")));    /* DMAC_SUSP_10, DMAC_SUSP_11, DMAC_SUSP_12, DMAC_SUSP_13, DMAC_SUSP_14, DMAC_SUSP_15, DMAC_SUSP_16, DMAC_SUSP_17, DMAC_SUSP_18, DMAC_SUSP_19, DMAC_SUSP_20, DMAC_SUSP_21, DMAC_SUSP_22, DMAC_SUSP_23, DMAC_SUSP_24, DMAC_SUSP_25, DMAC_SUSP_26, DMAC_SUSP_27, DMAC_SUSP_28, DMAC_SUSP_29, DMAC_SUSP_30, DMAC_SUSP_31, DMAC_SUSP_4, DMAC_SUSP_5, DMAC_SUSP_6, DMAC_SUSP_7, DMAC_SUSP_8, DMAC_SUSP_9, DMAC_TCMPL_10, DMAC_TCMPL_11, DMAC_TCMPL_12, DMAC_TCMPL_13, DMAC_TCMPL_14, DMAC_TCMPL_15, DMAC_TCMPL_16, DMAC_TCMPL_17, DMAC_TCMPL_18, DMAC_TCMPL_19, DMAC_TCMPL_20, DMAC_TCMPL_21, DMAC_TCMPL_22, DMAC_TCMPL_23, DMAC_TCMPL_24, DMAC_TCMPL_25, DMAC_TCMPL_26, DMAC_TCMPL_27, DMAC_TCMPL_28, DMAC_TCMPL_29, DMAC_TCMPL_30, DMAC_TCMPL_31, DMAC_TCMPL_4, DMAC_TCMPL_5, DMAC_TCMPL_6, DMAC_TCMPL_7, DMAC_TCMPL_8, DMAC_TCMPL_9, DMAC_TERR_10, DMAC_TERR_11, DMAC_TERR_12, DMAC_TERR_13, DMAC_TERR_14, DMAC_TERR_15, DMAC_TERR_16, DMAC_TERR_17,
 | 
			
		||||
                                                                               DMAC_TERR_18, DMAC_TERR_19, DMAC_TERR_20, DMAC_TERR_21, DMAC_TERR_22, DMAC_TERR_23, DMAC_TERR_24, DMAC_TERR_25, DMAC_TERR_26, DMAC_TERR_27, DMAC_TERR_28, DMAC_TERR_29, DMAC_TERR_30, DMAC_TERR_31, DMAC_TERR_4, DMAC_TERR_5, DMAC_TERR_6, DMAC_TERR_7, DMAC_TERR_8, DMAC_TERR_9 */
 | 
			
		||||
void EVSYS_0_Handler(void) __attribute__((weak, alias("Dummy_Handler")));   /* EVSYS_EVD_0, EVSYS_OVR_0 */
 | 
			
		||||
void EVSYS_1_Handler(void) __attribute__((weak, alias("Dummy_Handler")));   /* EVSYS_EVD_1, EVSYS_OVR_1 */
 | 
			
		||||
void EVSYS_2_Handler(void) __attribute__((weak, alias("Dummy_Handler")));   /* EVSYS_EVD_2, EVSYS_OVR_2 */
 | 
			
		||||
void EVSYS_3_Handler(void) __attribute__((weak, alias("Dummy_Handler")));   /* EVSYS_EVD_3, EVSYS_OVR_3 */
 | 
			
		||||
void EVSYS_4_Handler(void) __attribute__((weak, alias("Dummy_Handler")));   /* EVSYS_EVD_10, EVSYS_EVD_11, EVSYS_EVD_4, EVSYS_EVD_5, EVSYS_EVD_6, EVSYS_EVD_7, EVSYS_EVD_8, EVSYS_EVD_9, EVSYS_OVR_10, EVSYS_OVR_11, EVSYS_OVR_4, EVSYS_OVR_5, EVSYS_OVR_6, EVSYS_OVR_7, EVSYS_OVR_8, EVSYS_OVR_9 */
 | 
			
		||||
void PAC_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void TAL_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TAL_BRK */
 | 
			
		||||
void TAL_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TAL_IPS_0, TAL_IPS_1 */
 | 
			
		||||
void RAMECC_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void SERCOM0_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM0_0 */
 | 
			
		||||
void SERCOM0_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM0_1 */
 | 
			
		||||
void SERCOM0_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM0_2 */
 | 
			
		||||
void SERCOM0_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM0_3, SERCOM0_4, SERCOM0_5, SERCOM0_6 */
 | 
			
		||||
void SERCOM1_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM1_0 */
 | 
			
		||||
void SERCOM1_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM1_1 */
 | 
			
		||||
void SERCOM1_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM1_2 */
 | 
			
		||||
void SERCOM1_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM1_3, SERCOM1_4, SERCOM1_5, SERCOM1_6 */
 | 
			
		||||
void SERCOM2_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM2_0 */
 | 
			
		||||
void SERCOM2_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM2_1 */
 | 
			
		||||
void SERCOM2_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM2_2 */
 | 
			
		||||
void SERCOM2_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM2_3, SERCOM2_4, SERCOM2_5, SERCOM2_6 */
 | 
			
		||||
void SERCOM3_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM3_0 */
 | 
			
		||||
void SERCOM3_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM3_1 */
 | 
			
		||||
void SERCOM3_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM3_2 */
 | 
			
		||||
void SERCOM3_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM3_3, SERCOM3_4, SERCOM3_5, SERCOM3_6 */
 | 
			
		||||
#ifdef ID_SERCOM4
 | 
			
		||||
void SERCOM4_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM4_0 */
 | 
			
		||||
void SERCOM4_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM4_1 */
 | 
			
		||||
void SERCOM4_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM4_2 */
 | 
			
		||||
void SERCOM4_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM4_3, SERCOM4_4, SERCOM4_5, SERCOM4_6 */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_SERCOM5
 | 
			
		||||
void SERCOM5_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM5_0 */
 | 
			
		||||
void SERCOM5_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM5_1 */
 | 
			
		||||
void SERCOM5_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM5_2 */
 | 
			
		||||
void SERCOM5_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM5_3, SERCOM5_4, SERCOM5_5, SERCOM5_6 */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_SERCOM6
 | 
			
		||||
void SERCOM6_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM6_0 */
 | 
			
		||||
void SERCOM6_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM6_1 */
 | 
			
		||||
void SERCOM6_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM6_2 */
 | 
			
		||||
void SERCOM6_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM6_3, SERCOM6_4, SERCOM6_5, SERCOM6_6 */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_SERCOM7
 | 
			
		||||
void SERCOM7_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM7_0 */
 | 
			
		||||
void SERCOM7_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM7_1 */
 | 
			
		||||
void SERCOM7_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM7_2 */
 | 
			
		||||
void SERCOM7_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM7_3, SERCOM7_4, SERCOM7_5, SERCOM7_6 */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_CAN0
 | 
			
		||||
void CAN0_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_CAN1
 | 
			
		||||
void CAN1_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_USB
 | 
			
		||||
void USB_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* USB_EORSM_DNRSM, USB_EORST_RST, USB_LPMSUSP_DDISC, USB_LPM_DCONN, USB_MSOF, USB_RAMACER, USB_RXSTP_TXSTP_0, USB_RXSTP_TXSTP_1, USB_RXSTP_TXSTP_2, USB_RXSTP_TXSTP_3, USB_RXSTP_TXSTP_4, USB_RXSTP_TXSTP_5, USB_RXSTP_TXSTP_6, USB_RXSTP_TXSTP_7, USB_STALL0_STALL_0, USB_STALL0_STALL_1, USB_STALL0_STALL_2, USB_STALL0_STALL_3, USB_STALL0_STALL_4, USB_STALL0_STALL_5, USB_STALL0_STALL_6, USB_STALL0_STALL_7, USB_STALL1_0, USB_STALL1_1, USB_STALL1_2, USB_STALL1_3, USB_STALL1_4, USB_STALL1_5, USB_STALL1_6, USB_STALL1_7, USB_SUSPEND, USB_TRFAIL0_TRFAIL_0, USB_TRFAIL0_TRFAIL_1, USB_TRFAIL0_TRFAIL_2, USB_TRFAIL0_TRFAIL_3, USB_TRFAIL0_TRFAIL_4, USB_TRFAIL0_TRFAIL_5, USB_TRFAIL0_TRFAIL_6, USB_TRFAIL0_TRFAIL_7, USB_TRFAIL1_PERR_0, USB_TRFAIL1_PERR_1, USB_TRFAIL1_PERR_2, USB_TRFAIL1_PERR_3, USB_TRFAIL1_PERR_4, USB_TRFAIL1_PERR_5, USB_TRFAIL1_PERR_6, USB_TRFAIL1_PERR_7, USB_UPRSM, USB_WAKEUP */
 | 
			
		||||
void USB_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* USB_SOF_HSOF */
 | 
			
		||||
void USB_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* USB_TRCPT0_0, USB_TRCPT0_1, USB_TRCPT0_2, USB_TRCPT0_3, USB_TRCPT0_4, USB_TRCPT0_5, USB_TRCPT0_6, USB_TRCPT0_7 */
 | 
			
		||||
void USB_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* USB_TRCPT1_0, USB_TRCPT1_1, USB_TRCPT1_2, USB_TRCPT1_3, USB_TRCPT1_4, USB_TRCPT1_5, USB_TRCPT1_6, USB_TRCPT1_7 */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_GMAC
 | 
			
		||||
void GMAC_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
#endif
 | 
			
		||||
void TCC0_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_CNT_A, TCC0_DFS_A, TCC0_ERR_A, TCC0_FAULT0_A, TCC0_FAULT1_A, TCC0_FAULTA_A, TCC0_FAULTB_A, TCC0_OVF, TCC0_TRG, TCC0_UFS_A */
 | 
			
		||||
void TCC0_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_MC_0 */
 | 
			
		||||
void TCC0_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_MC_1 */
 | 
			
		||||
void TCC0_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_MC_2 */
 | 
			
		||||
void TCC0_4_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_MC_3 */
 | 
			
		||||
void TCC0_5_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_MC_4 */
 | 
			
		||||
void TCC0_6_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_MC_5 */
 | 
			
		||||
void TCC1_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC1_CNT_A, TCC1_DFS_A, TCC1_ERR_A, TCC1_FAULT0_A, TCC1_FAULT1_A, TCC1_FAULTA_A, TCC1_FAULTB_A, TCC1_OVF, TCC1_TRG, TCC1_UFS_A */
 | 
			
		||||
void TCC1_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC1_MC_0 */
 | 
			
		||||
void TCC1_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC1_MC_1 */
 | 
			
		||||
void TCC1_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC1_MC_2 */
 | 
			
		||||
void TCC1_4_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC1_MC_3 */
 | 
			
		||||
void TCC2_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC2_CNT_A, TCC2_DFS_A, TCC2_ERR_A, TCC2_FAULT0_A, TCC2_FAULT1_A, TCC2_FAULTA_A, TCC2_FAULTB_A, TCC2_OVF, TCC2_TRG, TCC2_UFS_A */
 | 
			
		||||
void TCC2_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC2_MC_0 */
 | 
			
		||||
void TCC2_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC2_MC_1 */
 | 
			
		||||
void TCC2_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC2_MC_2 */
 | 
			
		||||
#ifdef ID_TCC3
 | 
			
		||||
void TCC3_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC3_CNT_A, TCC3_DFS_A, TCC3_ERR_A, TCC3_FAULT0_A, TCC3_FAULT1_A, TCC3_FAULTA_A, TCC3_FAULTB_A, TCC3_OVF, TCC3_TRG, TCC3_UFS_A */
 | 
			
		||||
void TCC3_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC3_MC_0 */
 | 
			
		||||
void TCC3_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC3_MC_1 */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_TCC4
 | 
			
		||||
void TCC4_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC4_CNT_A, TCC4_DFS_A, TCC4_ERR_A, TCC4_FAULT0_A, TCC4_FAULT1_A, TCC4_FAULTA_A, TCC4_FAULTB_A, TCC4_OVF, TCC4_TRG, TCC4_UFS_A */
 | 
			
		||||
void TCC4_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC4_MC_0 */
 | 
			
		||||
void TCC4_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC4_MC_1 */
 | 
			
		||||
#endif
 | 
			
		||||
void TC0_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void TC1_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void TC2_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void TC3_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
#ifdef ID_TC4
 | 
			
		||||
void TC4_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_TC5
 | 
			
		||||
void TC5_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_TC6
 | 
			
		||||
void TC6_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_TC7
 | 
			
		||||
void TC7_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
#endif
 | 
			
		||||
void PDEC_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* PDEC_DIR_A, PDEC_ERR_A, PDEC_OVF, PDEC_VLC_A */
 | 
			
		||||
void PDEC_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* PDEC_MC_0 */
 | 
			
		||||
void PDEC_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* PDEC_MC_1 */
 | 
			
		||||
void ADC0_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* ADC0_OVERRUN, ADC0_WINMON */
 | 
			
		||||
void ADC0_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* ADC0_RESRDY */
 | 
			
		||||
void ADC1_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* ADC1_OVERRUN, ADC1_WINMON */
 | 
			
		||||
void ADC1_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* ADC1_RESRDY */
 | 
			
		||||
void AC_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void DAC_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DAC_OVERRUN_A_0, DAC_OVERRUN_A_1, DAC_UNDERRUN_A_0, DAC_UNDERRUN_A_1 */
 | 
			
		||||
void DAC_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DAC_EMPTY_0 */
 | 
			
		||||
void DAC_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DAC_EMPTY_1 */
 | 
			
		||||
void DAC_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DAC_RESRDY_0 */
 | 
			
		||||
void DAC_4_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DAC_RESRDY_1 */
 | 
			
		||||
#ifdef ID_I2S
 | 
			
		||||
void I2S_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
#endif
 | 
			
		||||
void PCC_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void AES_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
void TRNG_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
#ifdef ID_ICM
 | 
			
		||||
void ICM_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_PUKCC
 | 
			
		||||
void PUKCC_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
#endif
 | 
			
		||||
void QSPI_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
#ifdef ID_SDHC0
 | 
			
		||||
void SDHC0_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_SDHC1
 | 
			
		||||
void SDHC1_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Exception Table */
 | 
			
		||||
__attribute__((section(".vectors"))) const DeviceVectors exception_table = {
 | 
			
		||||
 | 
			
		||||
    /* Configure Initial Stack Pointer, using linker-generated symbols */
 | 
			
		||||
    .pvStack = (void *)(&_estack),
 | 
			
		||||
 | 
			
		||||
    .pfnReset_Handler      = (void *)Reset_Handler,
 | 
			
		||||
    .pfnNMI_Handler        = (void *)NMI_Handler,
 | 
			
		||||
    .pfnHardFault_Handler  = (void *)HardFault_Handler,
 | 
			
		||||
    .pfnMemManage_Handler  = (void *)MemManage_Handler,
 | 
			
		||||
    .pfnBusFault_Handler   = (void *)BusFault_Handler,
 | 
			
		||||
    .pfnUsageFault_Handler = (void *)UsageFault_Handler,
 | 
			
		||||
    .pvReservedM9          = (void *)(0UL), /* Reserved */
 | 
			
		||||
    .pvReservedM8          = (void *)(0UL), /* Reserved */
 | 
			
		||||
    .pvReservedM7          = (void *)(0UL), /* Reserved */
 | 
			
		||||
    .pvReservedM6          = (void *)(0UL), /* Reserved */
 | 
			
		||||
    .pfnSVC_Handler        = (void *)SVC_Handler,
 | 
			
		||||
    .pfnDebugMon_Handler   = (void *)DebugMon_Handler,
 | 
			
		||||
    .pvReservedM3          = (void *)(0UL), /* Reserved */
 | 
			
		||||
    .pfnPendSV_Handler     = (void *)PendSV_Handler,
 | 
			
		||||
    .pfnSysTick_Handler    = (void *)SysTick_Handler,
 | 
			
		||||
 | 
			
		||||
    /* Configurable interrupts */
 | 
			
		||||
    .pfnPM_Handler         = (void *)PM_Handler,         /*  0 Power Manager */
 | 
			
		||||
    .pfnMCLK_Handler       = (void *)MCLK_Handler,       /*  1 Main Clock */
 | 
			
		||||
    .pfnOSCCTRL_0_Handler  = (void *)OSCCTRL_0_Handler,  /*  2 OSCCTRL_XOSCFAIL_0, OSCCTRL_XOSCRDY_0 */
 | 
			
		||||
    .pfnOSCCTRL_1_Handler  = (void *)OSCCTRL_1_Handler,  /*  3 OSCCTRL_XOSCFAIL_1, OSCCTRL_XOSCRDY_1 */
 | 
			
		||||
    .pfnOSCCTRL_2_Handler  = (void *)OSCCTRL_2_Handler,  /*  4 OSCCTRL_DFLLLOCKC, OSCCTRL_DFLLLOCKF, OSCCTRL_DFLLOOB, OSCCTRL_DFLLRCS, OSCCTRL_DFLLRDY */
 | 
			
		||||
    .pfnOSCCTRL_3_Handler  = (void *)OSCCTRL_3_Handler,  /*  5 OSCCTRL_DPLLLCKF_0, OSCCTRL_DPLLLCKR_0, OSCCTRL_DPLLLDRTO_0, OSCCTRL_DPLLLTO_0 */
 | 
			
		||||
    .pfnOSCCTRL_4_Handler  = (void *)OSCCTRL_4_Handler,  /*  6 OSCCTRL_DPLLLCKF_1, OSCCTRL_DPLLLCKR_1, OSCCTRL_DPLLLDRTO_1, OSCCTRL_DPLLLTO_1 */
 | 
			
		||||
    .pfnOSC32KCTRL_Handler = (void *)OSC32KCTRL_Handler, /*  7 32kHz Oscillators Control */
 | 
			
		||||
    .pfnSUPC_0_Handler     = (void *)SUPC_0_Handler,     /*  8 SUPC_B12SRDY, SUPC_B33SRDY, SUPC_BOD12RDY, SUPC_BOD33RDY, SUPC_VCORERDY, SUPC_VREGRDY */
 | 
			
		||||
    .pfnSUPC_1_Handler     = (void *)SUPC_1_Handler,     /*  9 SUPC_BOD12DET, SUPC_BOD33DET */
 | 
			
		||||
    .pfnWDT_Handler        = (void *)WDT_Handler,        /* 10 Watchdog Timer */
 | 
			
		||||
    .pfnRTC_Handler        = (void *)RTC_Handler,        /* 11 Real-Time Counter */
 | 
			
		||||
    .pfnEIC_0_Handler      = (void *)EIC_0_Handler,      /* 12 EIC_EXTINT_0 */
 | 
			
		||||
    .pfnEIC_1_Handler      = (void *)EIC_1_Handler,      /* 13 EIC_EXTINT_1 */
 | 
			
		||||
    .pfnEIC_2_Handler      = (void *)EIC_2_Handler,      /* 14 EIC_EXTINT_2 */
 | 
			
		||||
    .pfnEIC_3_Handler      = (void *)EIC_3_Handler,      /* 15 EIC_EXTINT_3 */
 | 
			
		||||
    .pfnEIC_4_Handler      = (void *)EIC_4_Handler,      /* 16 EIC_EXTINT_4 */
 | 
			
		||||
    .pfnEIC_5_Handler      = (void *)EIC_5_Handler,      /* 17 EIC_EXTINT_5 */
 | 
			
		||||
    .pfnEIC_6_Handler      = (void *)EIC_6_Handler,      /* 18 EIC_EXTINT_6 */
 | 
			
		||||
    .pfnEIC_7_Handler      = (void *)EIC_7_Handler,      /* 19 EIC_EXTINT_7 */
 | 
			
		||||
    .pfnEIC_8_Handler      = (void *)EIC_8_Handler,      /* 20 EIC_EXTINT_8 */
 | 
			
		||||
    .pfnEIC_9_Handler      = (void *)EIC_9_Handler,      /* 21 EIC_EXTINT_9 */
 | 
			
		||||
    .pfnEIC_10_Handler     = (void *)EIC_10_Handler,     /* 22 EIC_EXTINT_10 */
 | 
			
		||||
    .pfnEIC_11_Handler     = (void *)EIC_11_Handler,     /* 23 EIC_EXTINT_11 */
 | 
			
		||||
    .pfnEIC_12_Handler     = (void *)EIC_12_Handler,     /* 24 EIC_EXTINT_12 */
 | 
			
		||||
    .pfnEIC_13_Handler     = (void *)EIC_13_Handler,     /* 25 EIC_EXTINT_13 */
 | 
			
		||||
    .pfnEIC_14_Handler     = (void *)EIC_14_Handler,     /* 26 EIC_EXTINT_14 */
 | 
			
		||||
    .pfnEIC_15_Handler     = (void *)EIC_15_Handler,     /* 27 EIC_EXTINT_15 */
 | 
			
		||||
    .pfnFREQM_Handler      = (void *)FREQM_Handler,      /* 28 Frequency Meter */
 | 
			
		||||
    .pfnNVMCTRL_0_Handler  = (void *)NVMCTRL_0_Handler,  /* 29 NVMCTRL_0, NVMCTRL_1, NVMCTRL_2, NVMCTRL_3, NVMCTRL_4, NVMCTRL_5, NVMCTRL_6, NVMCTRL_7 */
 | 
			
		||||
    .pfnNVMCTRL_1_Handler  = (void *)NVMCTRL_1_Handler,  /* 30 NVMCTRL_10, NVMCTRL_8, NVMCTRL_9 */
 | 
			
		||||
    .pfnDMAC_0_Handler     = (void *)DMAC_0_Handler,     /* 31 DMAC_SUSP_0, DMAC_TCMPL_0, DMAC_TERR_0 */
 | 
			
		||||
    .pfnDMAC_1_Handler     = (void *)DMAC_1_Handler,     /* 32 DMAC_SUSP_1, DMAC_TCMPL_1, DMAC_TERR_1 */
 | 
			
		||||
    .pfnDMAC_2_Handler     = (void *)DMAC_2_Handler,     /* 33 DMAC_SUSP_2, DMAC_TCMPL_2, DMAC_TERR_2 */
 | 
			
		||||
    .pfnDMAC_3_Handler     = (void *)DMAC_3_Handler,     /* 34 DMAC_SUSP_3, DMAC_TCMPL_3, DMAC_TERR_3 */
 | 
			
		||||
    .pfnDMAC_4_Handler     = (void *)DMAC_4_Handler,   /* 35 DMAC_SUSP_10, DMAC_SUSP_11, DMAC_SUSP_12, DMAC_SUSP_13, DMAC_SUSP_14, DMAC_SUSP_15, DMAC_SUSP_16, DMAC_SUSP_17, DMAC_SUSP_18, DMAC_SUSP_19, DMAC_SUSP_20, DMAC_SUSP_21, DMAC_SUSP_22, DMAC_SUSP_23, DMAC_SUSP_24, DMAC_SUSP_25, DMAC_SUSP_26, DMAC_SUSP_27, DMAC_SUSP_28, DMAC_SUSP_29, DMAC_SUSP_30, DMAC_SUSP_31, DMAC_SUSP_4, DMAC_SUSP_5, DMAC_SUSP_6, DMAC_SUSP_7, DMAC_SUSP_8, DMAC_SUSP_9, DMAC_TCMPL_10, DMAC_TCMPL_11, DMAC_TCMPL_12, DMAC_TCMPL_13, DMAC_TCMPL_14, DMAC_TCMPL_15, DMAC_TCMPL_16, DMAC_TCMPL_17, DMAC_TCMPL_18, DMAC_TCMPL_19, DMAC_TCMPL_20, DMAC_TCMPL_21, DMAC_TCMPL_22, DMAC_TCMPL_23, DMAC_TCMPL_24, DMAC_TCMPL_25, DMAC_TCMPL_26, DMAC_TCMPL_27, DMAC_TCMPL_28, DMAC_TCMPL_29, DMAC_TCMPL_30, DMAC_TCMPL_31, DMAC_TCMPL_4, DMAC_TCMPL_5, DMAC_TCMPL_6, DMAC_TCMPL_7, DMAC_TCMPL_8, DMAC_TCMPL_9, DMAC_TERR_10, DMAC_TERR_11, DMAC_TERR_12, DMAC_TERR_13, DMAC_TERR_14, DMAC_TERR_15, DMAC_TERR_16, DMAC_TERR_17, DMAC_TERR_18, DMAC_TERR_19,
 | 
			
		||||
                                                          DMAC_TERR_20, DMAC_TERR_21, DMAC_TERR_22, DMAC_TERR_23, DMAC_TERR_24, DMAC_TERR_25, DMAC_TERR_26, DMAC_TERR_27, DMAC_TERR_28, DMAC_TERR_29, DMAC_TERR_30, DMAC_TERR_31, DMAC_TERR_4, DMAC_TERR_5, DMAC_TERR_6, DMAC_TERR_7, DMAC_TERR_8, DMAC_TERR_9 */
 | 
			
		||||
    .pfnEVSYS_0_Handler   = (void *)EVSYS_0_Handler,   /* 36 EVSYS_EVD_0, EVSYS_OVR_0 */
 | 
			
		||||
    .pfnEVSYS_1_Handler   = (void *)EVSYS_1_Handler,   /* 37 EVSYS_EVD_1, EVSYS_OVR_1 */
 | 
			
		||||
    .pfnEVSYS_2_Handler   = (void *)EVSYS_2_Handler,   /* 38 EVSYS_EVD_2, EVSYS_OVR_2 */
 | 
			
		||||
    .pfnEVSYS_3_Handler   = (void *)EVSYS_3_Handler,   /* 39 EVSYS_EVD_3, EVSYS_OVR_3 */
 | 
			
		||||
    .pfnEVSYS_4_Handler   = (void *)EVSYS_4_Handler,   /* 40 EVSYS_EVD_10, EVSYS_EVD_11, EVSYS_EVD_4, EVSYS_EVD_5, EVSYS_EVD_6, EVSYS_EVD_7, EVSYS_EVD_8, EVSYS_EVD_9, EVSYS_OVR_10, EVSYS_OVR_11, EVSYS_OVR_4, EVSYS_OVR_5, EVSYS_OVR_6, EVSYS_OVR_7, EVSYS_OVR_8, EVSYS_OVR_9 */
 | 
			
		||||
    .pfnPAC_Handler       = (void *)PAC_Handler,       /* 41 Peripheral Access Controller */
 | 
			
		||||
    .pfnTAL_0_Handler     = (void *)TAL_0_Handler,     /* 42 TAL_BRK */
 | 
			
		||||
    .pfnTAL_1_Handler     = (void *)TAL_1_Handler,     /* 43 TAL_IPS_0, TAL_IPS_1 */
 | 
			
		||||
    .pvReserved44         = (void *)(0UL),             /* 44 Reserved */
 | 
			
		||||
    .pfnRAMECC_Handler    = (void *)RAMECC_Handler,    /* 45 RAM ECC */
 | 
			
		||||
    .pfnSERCOM0_0_Handler = (void *)SERCOM0_0_Handler, /* 46 SERCOM0_0 */
 | 
			
		||||
    .pfnSERCOM0_1_Handler = (void *)SERCOM0_1_Handler, /* 47 SERCOM0_1 */
 | 
			
		||||
    .pfnSERCOM0_2_Handler = (void *)SERCOM0_2_Handler, /* 48 SERCOM0_2 */
 | 
			
		||||
    .pfnSERCOM0_3_Handler = (void *)SERCOM0_3_Handler, /* 49 SERCOM0_3, SERCOM0_4, SERCOM0_5, SERCOM0_6 */
 | 
			
		||||
    .pfnSERCOM1_0_Handler = (void *)SERCOM1_0_Handler, /* 50 SERCOM1_0 */
 | 
			
		||||
    .pfnSERCOM1_1_Handler = (void *)SERCOM1_1_Handler, /* 51 SERCOM1_1 */
 | 
			
		||||
    .pfnSERCOM1_2_Handler = (void *)SERCOM1_2_Handler, /* 52 SERCOM1_2 */
 | 
			
		||||
    .pfnSERCOM1_3_Handler = (void *)SERCOM1_3_Handler, /* 53 SERCOM1_3, SERCOM1_4, SERCOM1_5, SERCOM1_6 */
 | 
			
		||||
    .pfnSERCOM2_0_Handler = (void *)SERCOM2_0_Handler, /* 54 SERCOM2_0 */
 | 
			
		||||
    .pfnSERCOM2_1_Handler = (void *)SERCOM2_1_Handler, /* 55 SERCOM2_1 */
 | 
			
		||||
    .pfnSERCOM2_2_Handler = (void *)SERCOM2_2_Handler, /* 56 SERCOM2_2 */
 | 
			
		||||
    .pfnSERCOM2_3_Handler = (void *)SERCOM2_3_Handler, /* 57 SERCOM2_3, SERCOM2_4, SERCOM2_5, SERCOM2_6 */
 | 
			
		||||
    .pfnSERCOM3_0_Handler = (void *)SERCOM3_0_Handler, /* 58 SERCOM3_0 */
 | 
			
		||||
    .pfnSERCOM3_1_Handler = (void *)SERCOM3_1_Handler, /* 59 SERCOM3_1 */
 | 
			
		||||
    .pfnSERCOM3_2_Handler = (void *)SERCOM3_2_Handler, /* 60 SERCOM3_2 */
 | 
			
		||||
    .pfnSERCOM3_3_Handler = (void *)SERCOM3_3_Handler, /* 61 SERCOM3_3, SERCOM3_4, SERCOM3_5, SERCOM3_6 */
 | 
			
		||||
#ifdef ID_SERCOM4
 | 
			
		||||
    .pfnSERCOM4_0_Handler = (void *)SERCOM4_0_Handler, /* 62 SERCOM4_0 */
 | 
			
		||||
    .pfnSERCOM4_1_Handler = (void *)SERCOM4_1_Handler, /* 63 SERCOM4_1 */
 | 
			
		||||
    .pfnSERCOM4_2_Handler = (void *)SERCOM4_2_Handler, /* 64 SERCOM4_2 */
 | 
			
		||||
    .pfnSERCOM4_3_Handler = (void *)SERCOM4_3_Handler, /* 65 SERCOM4_3, SERCOM4_4, SERCOM4_5, SERCOM4_6 */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved62  = (void *)(0UL), /* 62 Reserved */
 | 
			
		||||
    .pvReserved63  = (void *)(0UL), /* 63 Reserved */
 | 
			
		||||
    .pvReserved64  = (void *)(0UL), /* 64 Reserved */
 | 
			
		||||
    .pvReserved65  = (void *)(0UL), /* 65 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_SERCOM5
 | 
			
		||||
    .pfnSERCOM5_0_Handler = (void *)SERCOM5_0_Handler, /* 66 SERCOM5_0 */
 | 
			
		||||
    .pfnSERCOM5_1_Handler = (void *)SERCOM5_1_Handler, /* 67 SERCOM5_1 */
 | 
			
		||||
    .pfnSERCOM5_2_Handler = (void *)SERCOM5_2_Handler, /* 68 SERCOM5_2 */
 | 
			
		||||
    .pfnSERCOM5_3_Handler = (void *)SERCOM5_3_Handler, /* 69 SERCOM5_3, SERCOM5_4, SERCOM5_5, SERCOM5_6 */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved66  = (void *)(0UL), /* 66 Reserved */
 | 
			
		||||
    .pvReserved67  = (void *)(0UL), /* 67 Reserved */
 | 
			
		||||
    .pvReserved68  = (void *)(0UL), /* 68 Reserved */
 | 
			
		||||
    .pvReserved69  = (void *)(0UL), /* 69 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_SERCOM6
 | 
			
		||||
    .pfnSERCOM6_0_Handler = (void *)SERCOM6_0_Handler, /* 70 SERCOM6_0 */
 | 
			
		||||
    .pfnSERCOM6_1_Handler = (void *)SERCOM6_1_Handler, /* 71 SERCOM6_1 */
 | 
			
		||||
    .pfnSERCOM6_2_Handler = (void *)SERCOM6_2_Handler, /* 72 SERCOM6_2 */
 | 
			
		||||
    .pfnSERCOM6_3_Handler = (void *)SERCOM6_3_Handler, /* 73 SERCOM6_3, SERCOM6_4, SERCOM6_5, SERCOM6_6 */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved70  = (void *)(0UL), /* 70 Reserved */
 | 
			
		||||
    .pvReserved71  = (void *)(0UL), /* 71 Reserved */
 | 
			
		||||
    .pvReserved72  = (void *)(0UL), /* 72 Reserved */
 | 
			
		||||
    .pvReserved73  = (void *)(0UL), /* 73 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_SERCOM7
 | 
			
		||||
    .pfnSERCOM7_0_Handler = (void *)SERCOM7_0_Handler, /* 74 SERCOM7_0 */
 | 
			
		||||
    .pfnSERCOM7_1_Handler = (void *)SERCOM7_1_Handler, /* 75 SERCOM7_1 */
 | 
			
		||||
    .pfnSERCOM7_2_Handler = (void *)SERCOM7_2_Handler, /* 76 SERCOM7_2 */
 | 
			
		||||
    .pfnSERCOM7_3_Handler = (void *)SERCOM7_3_Handler, /* 77 SERCOM7_3, SERCOM7_4, SERCOM7_5, SERCOM7_6 */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved74  = (void *)(0UL), /* 74 Reserved */
 | 
			
		||||
    .pvReserved75  = (void *)(0UL), /* 75 Reserved */
 | 
			
		||||
    .pvReserved76  = (void *)(0UL), /* 76 Reserved */
 | 
			
		||||
    .pvReserved77  = (void *)(0UL), /* 77 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_CAN0
 | 
			
		||||
    .pfnCAN0_Handler = (void *)CAN0_Handler, /* 78 Control Area Network 0 */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved78  = (void *)(0UL), /* 78 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_CAN1
 | 
			
		||||
    .pfnCAN1_Handler = (void *)CAN1_Handler, /* 79 Control Area Network 1 */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved79  = (void *)(0UL), /* 79 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_USB
 | 
			
		||||
    .pfnUSB_0_Handler = (void *)USB_0_Handler, /* 80 USB_EORSM_DNRSM, USB_EORST_RST, USB_LPMSUSP_DDISC, USB_LPM_DCONN, USB_MSOF, USB_RAMACER, USB_RXSTP_TXSTP_0, USB_RXSTP_TXSTP_1, USB_RXSTP_TXSTP_2, USB_RXSTP_TXSTP_3, USB_RXSTP_TXSTP_4, USB_RXSTP_TXSTP_5, USB_RXSTP_TXSTP_6, USB_RXSTP_TXSTP_7, USB_STALL0_STALL_0, USB_STALL0_STALL_1, USB_STALL0_STALL_2, USB_STALL0_STALL_3, USB_STALL0_STALL_4, USB_STALL0_STALL_5, USB_STALL0_STALL_6, USB_STALL0_STALL_7, USB_STALL1_0, USB_STALL1_1, USB_STALL1_2, USB_STALL1_3, USB_STALL1_4, USB_STALL1_5, USB_STALL1_6, USB_STALL1_7, USB_SUSPEND, USB_TRFAIL0_TRFAIL_0, USB_TRFAIL0_TRFAIL_1, USB_TRFAIL0_TRFAIL_2, USB_TRFAIL0_TRFAIL_3, USB_TRFAIL0_TRFAIL_4, USB_TRFAIL0_TRFAIL_5, USB_TRFAIL0_TRFAIL_6, USB_TRFAIL0_TRFAIL_7, USB_TRFAIL1_PERR_0, USB_TRFAIL1_PERR_1, USB_TRFAIL1_PERR_2, USB_TRFAIL1_PERR_3, USB_TRFAIL1_PERR_4, USB_TRFAIL1_PERR_5, USB_TRFAIL1_PERR_6, USB_TRFAIL1_PERR_7, USB_UPRSM, USB_WAKEUP */
 | 
			
		||||
    .pfnUSB_1_Handler = (void *)USB_1_Handler, /* 81 USB_SOF_HSOF */
 | 
			
		||||
    .pfnUSB_2_Handler = (void *)USB_2_Handler, /* 82 USB_TRCPT0_0, USB_TRCPT0_1, USB_TRCPT0_2, USB_TRCPT0_3, USB_TRCPT0_4, USB_TRCPT0_5, USB_TRCPT0_6, USB_TRCPT0_7 */
 | 
			
		||||
    .pfnUSB_3_Handler = (void *)USB_3_Handler, /* 83 USB_TRCPT1_0, USB_TRCPT1_1, USB_TRCPT1_2, USB_TRCPT1_3, USB_TRCPT1_4, USB_TRCPT1_5, USB_TRCPT1_6, USB_TRCPT1_7 */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved80  = (void *)(0UL), /* 80 Reserved */
 | 
			
		||||
    .pvReserved81  = (void *)(0UL), /* 81 Reserved */
 | 
			
		||||
    .pvReserved82  = (void *)(0UL), /* 82 Reserved */
 | 
			
		||||
    .pvReserved83  = (void *)(0UL), /* 83 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_GMAC
 | 
			
		||||
    .pfnGMAC_Handler = (void *)GMAC_Handler, /* 84 Ethernet MAC */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved84  = (void *)(0UL), /* 84 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
    .pfnTCC0_0_Handler = (void *)TCC0_0_Handler, /* 85 TCC0_CNT_A, TCC0_DFS_A, TCC0_ERR_A, TCC0_FAULT0_A, TCC0_FAULT1_A, TCC0_FAULTA_A, TCC0_FAULTB_A, TCC0_OVF, TCC0_TRG, TCC0_UFS_A */
 | 
			
		||||
    .pfnTCC0_1_Handler = (void *)TCC0_1_Handler, /* 86 TCC0_MC_0 */
 | 
			
		||||
    .pfnTCC0_2_Handler = (void *)TCC0_2_Handler, /* 87 TCC0_MC_1 */
 | 
			
		||||
    .pfnTCC0_3_Handler = (void *)TCC0_3_Handler, /* 88 TCC0_MC_2 */
 | 
			
		||||
    .pfnTCC0_4_Handler = (void *)TCC0_4_Handler, /* 89 TCC0_MC_3 */
 | 
			
		||||
    .pfnTCC0_5_Handler = (void *)TCC0_5_Handler, /* 90 TCC0_MC_4 */
 | 
			
		||||
    .pfnTCC0_6_Handler = (void *)TCC0_6_Handler, /* 91 TCC0_MC_5 */
 | 
			
		||||
    .pfnTCC1_0_Handler = (void *)TCC1_0_Handler, /* 92 TCC1_CNT_A, TCC1_DFS_A, TCC1_ERR_A, TCC1_FAULT0_A, TCC1_FAULT1_A, TCC1_FAULTA_A, TCC1_FAULTB_A, TCC1_OVF, TCC1_TRG, TCC1_UFS_A */
 | 
			
		||||
    .pfnTCC1_1_Handler = (void *)TCC1_1_Handler, /* 93 TCC1_MC_0 */
 | 
			
		||||
    .pfnTCC1_2_Handler = (void *)TCC1_2_Handler, /* 94 TCC1_MC_1 */
 | 
			
		||||
    .pfnTCC1_3_Handler = (void *)TCC1_3_Handler, /* 95 TCC1_MC_2 */
 | 
			
		||||
    .pfnTCC1_4_Handler = (void *)TCC1_4_Handler, /* 96 TCC1_MC_3 */
 | 
			
		||||
    .pfnTCC2_0_Handler = (void *)TCC2_0_Handler, /* 97 TCC2_CNT_A, TCC2_DFS_A, TCC2_ERR_A, TCC2_FAULT0_A, TCC2_FAULT1_A, TCC2_FAULTA_A, TCC2_FAULTB_A, TCC2_OVF, TCC2_TRG, TCC2_UFS_A */
 | 
			
		||||
    .pfnTCC2_1_Handler = (void *)TCC2_1_Handler, /* 98 TCC2_MC_0 */
 | 
			
		||||
    .pfnTCC2_2_Handler = (void *)TCC2_2_Handler, /* 99 TCC2_MC_1 */
 | 
			
		||||
    .pfnTCC2_3_Handler = (void *)TCC2_3_Handler, /* 100 TCC2_MC_2 */
 | 
			
		||||
#ifdef ID_TCC3
 | 
			
		||||
    .pfnTCC3_0_Handler = (void *)TCC3_0_Handler, /* 101 TCC3_CNT_A, TCC3_DFS_A, TCC3_ERR_A, TCC3_FAULT0_A, TCC3_FAULT1_A, TCC3_FAULTA_A, TCC3_FAULTB_A, TCC3_OVF, TCC3_TRG, TCC3_UFS_A */
 | 
			
		||||
    .pfnTCC3_1_Handler = (void *)TCC3_1_Handler, /* 102 TCC3_MC_0 */
 | 
			
		||||
    .pfnTCC3_2_Handler = (void *)TCC3_2_Handler, /* 103 TCC3_MC_1 */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved101 = (void *)(0UL), /* 101 Reserved */
 | 
			
		||||
    .pvReserved102 = (void *)(0UL), /* 102 Reserved */
 | 
			
		||||
    .pvReserved103 = (void *)(0UL), /* 103 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_TCC4
 | 
			
		||||
    .pfnTCC4_0_Handler = (void *)TCC4_0_Handler, /* 104 TCC4_CNT_A, TCC4_DFS_A, TCC4_ERR_A, TCC4_FAULT0_A, TCC4_FAULT1_A, TCC4_FAULTA_A, TCC4_FAULTB_A, TCC4_OVF, TCC4_TRG, TCC4_UFS_A */
 | 
			
		||||
    .pfnTCC4_1_Handler = (void *)TCC4_1_Handler, /* 105 TCC4_MC_0 */
 | 
			
		||||
    .pfnTCC4_2_Handler = (void *)TCC4_2_Handler, /* 106 TCC4_MC_1 */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved104 = (void *)(0UL), /* 104 Reserved */
 | 
			
		||||
    .pvReserved105 = (void *)(0UL), /* 105 Reserved */
 | 
			
		||||
    .pvReserved106 = (void *)(0UL), /* 106 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
    .pfnTC0_Handler = (void *)TC0_Handler, /* 107 Basic Timer Counter 0 */
 | 
			
		||||
    .pfnTC1_Handler = (void *)TC1_Handler, /* 108 Basic Timer Counter 1 */
 | 
			
		||||
    .pfnTC2_Handler = (void *)TC2_Handler, /* 109 Basic Timer Counter 2 */
 | 
			
		||||
    .pfnTC3_Handler = (void *)TC3_Handler, /* 110 Basic Timer Counter 3 */
 | 
			
		||||
#ifdef ID_TC4
 | 
			
		||||
    .pfnTC4_Handler = (void *)TC4_Handler, /* 111 Basic Timer Counter 4 */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved111 = (void *)(0UL), /* 111 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_TC5
 | 
			
		||||
    .pfnTC5_Handler = (void *)TC5_Handler, /* 112 Basic Timer Counter 5 */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved112 = (void *)(0UL), /* 112 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_TC6
 | 
			
		||||
    .pfnTC6_Handler = (void *)TC6_Handler, /* 113 Basic Timer Counter 6 */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved113 = (void *)(0UL), /* 113 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_TC7
 | 
			
		||||
    .pfnTC7_Handler = (void *)TC7_Handler, /* 114 Basic Timer Counter 7 */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved114 = (void *)(0UL), /* 114 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
    .pfnPDEC_0_Handler = (void *)PDEC_0_Handler, /* 115 PDEC_DIR_A, PDEC_ERR_A, PDEC_OVF, PDEC_VLC_A */
 | 
			
		||||
    .pfnPDEC_1_Handler = (void *)PDEC_1_Handler, /* 116 PDEC_MC_0 */
 | 
			
		||||
    .pfnPDEC_2_Handler = (void *)PDEC_2_Handler, /* 117 PDEC_MC_1 */
 | 
			
		||||
    .pfnADC0_0_Handler = (void *)ADC0_0_Handler, /* 118 ADC0_OVERRUN, ADC0_WINMON */
 | 
			
		||||
    .pfnADC0_1_Handler = (void *)ADC0_1_Handler, /* 119 ADC0_RESRDY */
 | 
			
		||||
    .pfnADC1_0_Handler = (void *)ADC1_0_Handler, /* 120 ADC1_OVERRUN, ADC1_WINMON */
 | 
			
		||||
    .pfnADC1_1_Handler = (void *)ADC1_1_Handler, /* 121 ADC1_RESRDY */
 | 
			
		||||
    .pfnAC_Handler     = (void *)AC_Handler,     /* 122 Analog Comparators */
 | 
			
		||||
    .pfnDAC_0_Handler  = (void *)DAC_0_Handler,  /* 123 DAC_OVERRUN_A_0, DAC_OVERRUN_A_1, DAC_UNDERRUN_A_0, DAC_UNDERRUN_A_1 */
 | 
			
		||||
    .pfnDAC_1_Handler  = (void *)DAC_1_Handler,  /* 124 DAC_EMPTY_0 */
 | 
			
		||||
    .pfnDAC_2_Handler  = (void *)DAC_2_Handler,  /* 125 DAC_EMPTY_1 */
 | 
			
		||||
    .pfnDAC_3_Handler  = (void *)DAC_3_Handler,  /* 126 DAC_RESRDY_0 */
 | 
			
		||||
    .pfnDAC_4_Handler  = (void *)DAC_4_Handler,  /* 127 DAC_RESRDY_1 */
 | 
			
		||||
#ifdef ID_I2S
 | 
			
		||||
    .pfnI2S_Handler = (void *)I2S_Handler, /* 128 Inter-IC Sound Interface */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved128 = (void *)(0UL), /* 128 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
    .pfnPCC_Handler  = (void *)PCC_Handler,  /* 129 Parallel Capture Controller */
 | 
			
		||||
    .pfnAES_Handler  = (void *)AES_Handler,  /* 130 Advanced Encryption Standard */
 | 
			
		||||
    .pfnTRNG_Handler = (void *)TRNG_Handler, /* 131 True Random Generator */
 | 
			
		||||
#ifdef ID_ICM
 | 
			
		||||
    .pfnICM_Handler = (void *)ICM_Handler, /* 132 Integrity Check Monitor */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved132 = (void *)(0UL), /* 132 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_PUKCC
 | 
			
		||||
    .pfnPUKCC_Handler = (void *)PUKCC_Handler, /* 133 PUblic-Key Cryptography Controller */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved133 = (void *)(0UL), /* 133 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
    .pfnQSPI_Handler = (void *)QSPI_Handler, /* 134 Quad SPI interface */
 | 
			
		||||
#ifdef ID_SDHC0
 | 
			
		||||
    .pfnSDHC0_Handler = (void *)SDHC0_Handler, /* 135 SD/MMC Host Controller 0 */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved135 = (void *)(0UL), /* 135 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ID_SDHC1
 | 
			
		||||
    .pfnSDHC1_Handler = (void *)SDHC1_Handler /* 136 SD/MMC Host Controller 1 */
 | 
			
		||||
#else
 | 
			
		||||
    .pvReserved136 = (void *)(0UL)  /* 136 Reserved */
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// WARNING: These are only for CTRL bootloader release "v2.18Jun 22 2018 17:28:08" for bootloader_jump support
 | 
			
		||||
extern uint32_t _eram;
 | 
			
		||||
#define BOOTLOADER_MAGIC 0x3B9ACA00
 | 
			
		||||
#define MAGIC_ADDR (uint32_t *)((intptr_t)(&_eram) - 4)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief This is the code that gets called on processor reset.
 | 
			
		||||
 * To initialize the device, and call the main() routine.
 | 
			
		||||
 */
 | 
			
		||||
void Reset_Handler(void) {
 | 
			
		||||
#ifdef KEYBOARD_massdrop_ctrl
 | 
			
		||||
    /* WARNING: This is only for CTRL bootloader release "v2.18Jun 22 2018 17:28:08" for bootloader_jump support */
 | 
			
		||||
    if (*MAGIC_ADDR == BOOTLOADER_MAGIC) {
 | 
			
		||||
        /* At this point, the bootloader's memory is initialized properly, so undo the jump to here, then jump back */
 | 
			
		||||
        *MAGIC_ADDR = 0x00000000;       /* Change value to prevent potential bootloader entrance loop */
 | 
			
		||||
        __set_MSP(0x20008818);          /* MSP according to bootloader */
 | 
			
		||||
        SCB->VTOR = 0x00000000;         /* Vector table back to bootloader's */
 | 
			
		||||
        asm("bx %0" ::"r"(0x00001267)); /* Jump past bootloader RCAUSE check using THUMB */
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    uint32_t *pSrc, *pDest;
 | 
			
		||||
 | 
			
		||||
    /* Initialize the relocate segment */
 | 
			
		||||
    pSrc  = &_etext;
 | 
			
		||||
    pDest = &_srelocate;
 | 
			
		||||
 | 
			
		||||
    if (pSrc != pDest) {
 | 
			
		||||
        for (; pDest < &_erelocate;) {
 | 
			
		||||
            *pDest++ = *pSrc++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Clear the zero segment */
 | 
			
		||||
    for (pDest = &_szero; pDest < &_ezero;) {
 | 
			
		||||
        *pDest++ = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Set the vector table base address */
 | 
			
		||||
    pSrc      = (uint32_t *)&_sfixed;
 | 
			
		||||
    SCB->VTOR = ((uint32_t)pSrc & SCB_VTOR_TBLOFF_Msk);
 | 
			
		||||
 | 
			
		||||
#if __FPU_USED
 | 
			
		||||
    /* Enable FPU */
 | 
			
		||||
    SCB->CPACR |= (0xFu << 20);
 | 
			
		||||
    __DSB();
 | 
			
		||||
    __ISB();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* Initialize the C library */
 | 
			
		||||
    __libc_init_array();
 | 
			
		||||
 | 
			
		||||
    /* Branch to main function */
 | 
			
		||||
    main();
 | 
			
		||||
 | 
			
		||||
    /* Infinite loop */
 | 
			
		||||
    while (1)
 | 
			
		||||
        ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Default interrupt handler for unused IRQs.
 | 
			
		||||
 */
 | 
			
		||||
void Dummy_Handler(void) {
 | 
			
		||||
    while (1) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,164 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief USB configuration file
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _CONF_USB_H_
 | 
			
		||||
#define _CONF_USB_H_
 | 
			
		||||
 | 
			
		||||
#include "compiler.h"
 | 
			
		||||
#include "udi_device_conf.h"
 | 
			
		||||
 | 
			
		||||
#define UDI_CDC_DEFAULT_RATE 115200
 | 
			
		||||
#define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1
 | 
			
		||||
#define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE
 | 
			
		||||
#define UDI_CDC_DEFAULT_DATABITS 8
 | 
			
		||||
 | 
			
		||||
//! Device definition (mandatory)
 | 
			
		||||
#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_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)
 | 
			
		||||
//                                      (USB_CONFIG_ATTR_SELF_POWERED)
 | 
			
		||||
//                                      (USB_CONFIG_ATTR_BUS_POWERED)
 | 
			
		||||
 | 
			
		||||
//! USB Device string definitions (Optional)
 | 
			
		||||
#define USB_DEVICE_MANUFACTURE_NAME MANUFACTURER
 | 
			
		||||
#define USB_DEVICE_PRODUCT_NAME PRODUCT
 | 
			
		||||
#define USB_DEVICE_SERIAL_NAME SERIAL_NUM
 | 
			
		||||
 | 
			
		||||
// Comment out USB_DEVICE_SERIAL_USE_BOOTLOADER_SERIAL to prevent ROM lookup of factory programmed serial number
 | 
			
		||||
#define USB_DEVICE_SERIAL_USE_BOOTLOADER_SERIAL
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Device speeds support
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
//! To define a Low speed device
 | 
			
		||||
//#define  USB_DEVICE_LOW_SPEED
 | 
			
		||||
 | 
			
		||||
//! To authorize the High speed
 | 
			
		||||
#if (UC3A3 || UC3A4)
 | 
			
		||||
//#define  USB_DEVICE_HS_SUPPORT
 | 
			
		||||
#elif (SAM3XA || SAM3U)
 | 
			
		||||
//#define  USB_DEVICE_HS_SUPPORT
 | 
			
		||||
#endif
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * USB Device Callbacks definitions (Optional)
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
#define UDC_VBUS_EVENT(b_vbus_high)
 | 
			
		||||
#define UDC_SOF_EVENT() main_sof_action()
 | 
			
		||||
#define UDC_SUSPEND_EVENT() main_suspend_action()
 | 
			
		||||
#define UDC_RESUME_EVENT() main_resume_action()
 | 
			
		||||
//! Mandatory when USB_DEVICE_ATTR authorizes remote wakeup feature
 | 
			
		||||
#define UDC_REMOTEWAKEUP_ENABLE() main_remotewakeup_enable()
 | 
			
		||||
#define UDC_REMOTEWAKEUP_DISABLE() main_remotewakeup_disable()
 | 
			
		||||
//! When a extra string descriptor must be supported
 | 
			
		||||
//! other than manufacturer, product and serial string
 | 
			
		||||
// #define  UDC_GET_EXTRA_STRING()
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * USB Interface Configuration
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
/**
 | 
			
		||||
 * Configuration of HID Keyboard interface
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
//! Interface callback definition
 | 
			
		||||
#define UDI_HID_KBD_ENABLE_EXT() main_kbd_enable()
 | 
			
		||||
#define UDI_HID_KBD_DISABLE_EXT() main_kbd_disable()
 | 
			
		||||
//#define UDI_HID_KBD_CHANGE_LED(value) ui_kbd_led(value)
 | 
			
		||||
 | 
			
		||||
#ifdef NKRO_ENABLE
 | 
			
		||||
#    define UDI_HID_NKRO_ENABLE_EXT() main_nkro_enable()
 | 
			
		||||
#    define UDI_HID_NKRO_DISABLE_EXT() main_nkro_disable()
 | 
			
		||||
//#define UDI_HID_NKRO_CHANGE_LED(value) ui_kbd_led(value)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EXTRAKEY_ENABLE
 | 
			
		||||
#    define UDI_HID_EXK_ENABLE_EXT() main_exk_enable()
 | 
			
		||||
#    define UDI_HID_EXK_DISABLE_EXT() main_exk_disable()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
#    define UDI_HID_CON_ENABLE_EXT() main_con_enable()
 | 
			
		||||
#    define UDI_HID_CON_DISABLE_EXT() main_con_disable()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MOUSE_ENABLE
 | 
			
		||||
#    define UDI_HID_MOU_ENABLE_EXT() main_mou_enable()
 | 
			
		||||
#    define UDI_HID_MOU_DISABLE_EXT() main_mou_disable()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef RAW_ENABLE
 | 
			
		||||
#    define UDI_HID_RAW_ENABLE_EXT() main_raw_enable()
 | 
			
		||||
#    define UDI_HID_RAW_DISABLE_EXT() main_raw_disable()
 | 
			
		||||
#    define UDI_HID_RAW_RECEIVE(buffer, len) main_raw_receive(buffer, len)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//@}
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * USB Device Driver Configuration
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
//! The includes of classes and other headers must be done at the end of this file to avoid compile error
 | 
			
		||||
#include "udi_hid_kbd_conf.h"
 | 
			
		||||
#include "usb_main.h"
 | 
			
		||||
#include "ui.h"
 | 
			
		||||
 | 
			
		||||
#endif // _CONF_USB_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,120 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "samd51j18a.h"
 | 
			
		||||
#include "conf_usb.h"
 | 
			
		||||
#include "udd.h"
 | 
			
		||||
 | 
			
		||||
#ifdef RAW_ENABLE
 | 
			
		||||
#    include "raw_hid.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
uint8_t keyboard_protocol = 1;
 | 
			
		||||
 | 
			
		||||
void main_suspend_action(void) {
 | 
			
		||||
    ui_powerdown();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_resume_action(void) {
 | 
			
		||||
    ui_wakeup();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_sof_action(void) {
 | 
			
		||||
    ui_process(udd_get_frame_number());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_remotewakeup_enable(void) {
 | 
			
		||||
    ui_wakeup_enable();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_remotewakeup_disable(void) {
 | 
			
		||||
    ui_wakeup_disable();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
volatile bool main_b_kbd_enable = false;
 | 
			
		||||
bool          main_kbd_enable(void) {
 | 
			
		||||
    main_b_kbd_enable = true;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_kbd_disable(void) {
 | 
			
		||||
    main_b_kbd_enable = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef NKRO_ENABLE
 | 
			
		||||
volatile bool main_b_nkro_enable = false;
 | 
			
		||||
bool          main_nkro_enable(void) {
 | 
			
		||||
    main_b_nkro_enable = true;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_nkro_disable(void) {
 | 
			
		||||
    main_b_nkro_enable = false;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EXTRAKEY_ENABLE
 | 
			
		||||
volatile bool main_b_exk_enable = false;
 | 
			
		||||
bool          main_exk_enable(void) {
 | 
			
		||||
    main_b_exk_enable = true;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_exk_disable(void) {
 | 
			
		||||
    main_b_exk_enable = false;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
volatile bool main_b_con_enable = false;
 | 
			
		||||
bool          main_con_enable(void) {
 | 
			
		||||
    main_b_con_enable = true;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_con_disable(void) {
 | 
			
		||||
    main_b_con_enable = false;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MOUSE_ENABLE
 | 
			
		||||
volatile bool main_b_mou_enable = false;
 | 
			
		||||
bool          main_mou_enable(void) {
 | 
			
		||||
    main_b_mou_enable = true;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_mou_disable(void) {
 | 
			
		||||
    main_b_mou_enable = false;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef RAW_ENABLE
 | 
			
		||||
volatile bool main_b_raw_enable = false;
 | 
			
		||||
bool          main_raw_enable(void) {
 | 
			
		||||
    main_b_raw_enable = true;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,158 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief Status code definitions.
 | 
			
		||||
 *
 | 
			
		||||
 * This file defines various status codes returned by functions,
 | 
			
		||||
 * indicating success or failure as well as what kind of failure.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2012-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef STATUS_CODES_H_INCLUDED
 | 
			
		||||
#define STATUS_CODES_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \defgroup group_sam0_utils_status_codes Status Codes
 | 
			
		||||
 *
 | 
			
		||||
 * \ingroup group_sam0_utils
 | 
			
		||||
 *
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** Mask to retrieve the error category of a status code. */
 | 
			
		||||
#define STATUS_CATEGORY_MASK 0xF0
 | 
			
		||||
 | 
			
		||||
/** Mask to retrieve the error code within the category of a status code. */
 | 
			
		||||
#define STATUS_ERROR_MASK 0x0F
 | 
			
		||||
 | 
			
		||||
/** Status code error categories. */
 | 
			
		||||
enum status_categories {
 | 
			
		||||
    STATUS_CATEGORY_OK     = 0x00,
 | 
			
		||||
    STATUS_CATEGORY_COMMON = 0x10,
 | 
			
		||||
    STATUS_CATEGORY_ANALOG = 0x30,
 | 
			
		||||
    STATUS_CATEGORY_COM    = 0x40,
 | 
			
		||||
    STATUS_CATEGORY_IO     = 0x50,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Status code that may be returned by shell commands and protocol
 | 
			
		||||
 * implementations.
 | 
			
		||||
 *
 | 
			
		||||
 * \note Any change to these status codes and the corresponding
 | 
			
		||||
 * message strings is strictly forbidden. New codes can be added,
 | 
			
		||||
 * however, but make sure that any message string tables are updated
 | 
			
		||||
 * at the same time.
 | 
			
		||||
 */
 | 
			
		||||
enum status_code {
 | 
			
		||||
    STATUS_OK         = STATUS_CATEGORY_OK | 0x00,
 | 
			
		||||
    STATUS_VALID_DATA = STATUS_CATEGORY_OK | 0x01,
 | 
			
		||||
    STATUS_NO_CHANGE  = STATUS_CATEGORY_OK | 0x02,
 | 
			
		||||
    STATUS_ABORTED    = STATUS_CATEGORY_OK | 0x04,
 | 
			
		||||
    STATUS_BUSY       = STATUS_CATEGORY_OK | 0x05,
 | 
			
		||||
    STATUS_SUSPEND    = STATUS_CATEGORY_OK | 0x06,
 | 
			
		||||
 | 
			
		||||
    STATUS_ERR_IO                  = STATUS_CATEGORY_COMMON | 0x00,
 | 
			
		||||
    STATUS_ERR_REQ_FLUSHED         = STATUS_CATEGORY_COMMON | 0x01,
 | 
			
		||||
    STATUS_ERR_TIMEOUT             = STATUS_CATEGORY_COMMON | 0x02,
 | 
			
		||||
    STATUS_ERR_BAD_DATA            = STATUS_CATEGORY_COMMON | 0x03,
 | 
			
		||||
    STATUS_ERR_NOT_FOUND           = STATUS_CATEGORY_COMMON | 0x04,
 | 
			
		||||
    STATUS_ERR_UNSUPPORTED_DEV     = STATUS_CATEGORY_COMMON | 0x05,
 | 
			
		||||
    STATUS_ERR_NO_MEMORY           = STATUS_CATEGORY_COMMON | 0x06,
 | 
			
		||||
    STATUS_ERR_INVALID_ARG         = STATUS_CATEGORY_COMMON | 0x07,
 | 
			
		||||
    STATUS_ERR_BAD_ADDRESS         = STATUS_CATEGORY_COMMON | 0x08,
 | 
			
		||||
    STATUS_ERR_BAD_FORMAT          = STATUS_CATEGORY_COMMON | 0x0A,
 | 
			
		||||
    STATUS_ERR_BAD_FRQ             = STATUS_CATEGORY_COMMON | 0x0B,
 | 
			
		||||
    STATUS_ERR_DENIED              = STATUS_CATEGORY_COMMON | 0x0c,
 | 
			
		||||
    STATUS_ERR_ALREADY_INITIALIZED = STATUS_CATEGORY_COMMON | 0x0d,
 | 
			
		||||
    STATUS_ERR_OVERFLOW            = STATUS_CATEGORY_COMMON | 0x0e,
 | 
			
		||||
    STATUS_ERR_NOT_INITIALIZED     = STATUS_CATEGORY_COMMON | 0x0f,
 | 
			
		||||
 | 
			
		||||
    STATUS_ERR_SAMPLERATE_UNAVAILABLE = STATUS_CATEGORY_ANALOG | 0x00,
 | 
			
		||||
    STATUS_ERR_RESOLUTION_UNAVAILABLE = STATUS_CATEGORY_ANALOG | 0x01,
 | 
			
		||||
 | 
			
		||||
    STATUS_ERR_BAUDRATE_UNAVAILABLE = STATUS_CATEGORY_COM | 0x00,
 | 
			
		||||
    STATUS_ERR_PACKET_COLLISION     = STATUS_CATEGORY_COM | 0x01,
 | 
			
		||||
    STATUS_ERR_PROTOCOL             = STATUS_CATEGORY_COM | 0x02,
 | 
			
		||||
 | 
			
		||||
    STATUS_ERR_PIN_MUX_INVALID = STATUS_CATEGORY_IO | 0x00,
 | 
			
		||||
};
 | 
			
		||||
typedef enum status_code status_code_genare_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Status codes used by MAC stack.
 | 
			
		||||
 */
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * \brief Operation in progress
 | 
			
		||||
     *
 | 
			
		||||
     * This status code is for driver-internal use when an operation
 | 
			
		||||
     * is currently being performed.
 | 
			
		||||
     *
 | 
			
		||||
     * \note Drivers should never return this status code to any
 | 
			
		||||
     * callers. It is strictly for internal use.
 | 
			
		||||
     */
 | 
			
		||||
    OPERATION_IN_PROGRESS = -128,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef enum status_code_wireless status_code_t;
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
#endif /* STATUS_CODES_H_INCLUDED */
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,256 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief Interface of the USB Device Controller (UDC)
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _UDC_H_
 | 
			
		||||
#define _UDC_H_
 | 
			
		||||
 | 
			
		||||
#include "conf_usb.h"
 | 
			
		||||
#include "usb_protocol.h"
 | 
			
		||||
#include "udc_desc.h"
 | 
			
		||||
#include "udd.h"
 | 
			
		||||
 | 
			
		||||
#if USB_DEVICE_VENDOR_ID == 0
 | 
			
		||||
#    error USB_DEVICE_VENDOR_ID cannot be equal to 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if USB_DEVICE_PRODUCT_ID == 0
 | 
			
		||||
#    error USB_DEVICE_PRODUCT_ID cannot be equal to 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \ingroup usb_device_group
 | 
			
		||||
 * \defgroup udc_group USB Device Controller (UDC)
 | 
			
		||||
 *
 | 
			
		||||
 * The UDC provides a high-level abstraction of the usb device.
 | 
			
		||||
 * You can use these functions to control the main device state
 | 
			
		||||
 * (start/attach/wakeup).
 | 
			
		||||
 *
 | 
			
		||||
 * \section USB_DEVICE_CONF USB Device Custom configuration
 | 
			
		||||
 * The following USB Device configuration must be included in the conf_usb.h
 | 
			
		||||
 * file of the application.
 | 
			
		||||
 *
 | 
			
		||||
 * USB_DEVICE_VENDOR_ID (Word)<br>
 | 
			
		||||
 * Vendor ID provided by USB org (ATMEL 0x03EB).
 | 
			
		||||
 *
 | 
			
		||||
 * USB_DEVICE_PRODUCT_ID (Word)<br>
 | 
			
		||||
 * Product ID (Referenced in usb_atmel.h).
 | 
			
		||||
 *
 | 
			
		||||
 * USB_DEVICE_MAJOR_VERSION (Byte)<br>
 | 
			
		||||
 * Major version of the device
 | 
			
		||||
 *
 | 
			
		||||
 * USB_DEVICE_MINOR_VERSION (Byte)<br>
 | 
			
		||||
 * Minor version of the device
 | 
			
		||||
 *
 | 
			
		||||
 * USB_DEVICE_MANUFACTURE_NAME (string)<br>
 | 
			
		||||
 * ASCII name for the manufacture
 | 
			
		||||
 *
 | 
			
		||||
 * USB_DEVICE_PRODUCT_NAME (string)<br>
 | 
			
		||||
 * ASCII name for the product
 | 
			
		||||
 *
 | 
			
		||||
 * USB_DEVICE_SERIAL_NAME (string)<br>
 | 
			
		||||
 * ASCII name to enable and set a serial number
 | 
			
		||||
 *
 | 
			
		||||
 * USB_DEVICE_POWER (Numeric)<br>
 | 
			
		||||
 * (unit mA) Maximum device power
 | 
			
		||||
 *
 | 
			
		||||
 * USB_DEVICE_ATTR (Byte)<br>
 | 
			
		||||
 * USB attributes available:
 | 
			
		||||
 *  - USB_CONFIG_ATTR_SELF_POWERED
 | 
			
		||||
 *  - USB_CONFIG_ATTR_REMOTE_WAKEUP
 | 
			
		||||
 *  Note: if remote wake enabled then defines remotewakeup callbacks,
 | 
			
		||||
 * see Table 5-2. External API from UDC - Callback
 | 
			
		||||
 *
 | 
			
		||||
 * USB_DEVICE_LOW_SPEED (Only defined)<br>
 | 
			
		||||
 * Force the USB Device to run in low speed
 | 
			
		||||
 *
 | 
			
		||||
 * USB_DEVICE_HS_SUPPORT (Only defined)<br>
 | 
			
		||||
 * Authorize the USB Device to run in high speed
 | 
			
		||||
 *
 | 
			
		||||
 * USB_DEVICE_MAX_EP (Byte)<br>
 | 
			
		||||
 * Define the maximum endpoint number used by the USB Device.<br>
 | 
			
		||||
 * This one is already defined in UDI default configuration.
 | 
			
		||||
 * Ex:
 | 
			
		||||
 * - When endpoint control 0x00, endpoint 0x01 and
 | 
			
		||||
 *   endpoint 0x82 is used then USB_DEVICE_MAX_EP=2
 | 
			
		||||
 * - When only endpoint control 0x00 is used then USB_DEVICE_MAX_EP=0
 | 
			
		||||
 * - When endpoint 0x01 and endpoint 0x81 is used then USB_DEVICE_MAX_EP=1<br>
 | 
			
		||||
 *   (configuration not possible on USBB interface)
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Authorizes the VBUS event
 | 
			
		||||
 *
 | 
			
		||||
 * \return true, if the VBUS monitoring is possible.
 | 
			
		||||
 *
 | 
			
		||||
 * \section udc_vbus_monitoring VBus monitoring used cases
 | 
			
		||||
 *
 | 
			
		||||
 * The VBus monitoring is used only for USB SELF Power application.
 | 
			
		||||
 *
 | 
			
		||||
 * - By default the USB device is automatically attached when Vbus is high
 | 
			
		||||
 * or when USB is start for devices without internal Vbus monitoring.
 | 
			
		||||
 * conf_usb.h file does not contains define USB_DEVICE_ATTACH_AUTO_DISABLE.
 | 
			
		||||
 * \code //#define USB_DEVICE_ATTACH_AUTO_DISABLE \endcode
 | 
			
		||||
 *
 | 
			
		||||
 * - Add custom VBUS monitoring. conf_usb.h file contains define
 | 
			
		||||
 * USB_DEVICE_ATTACH_AUTO_DISABLE:
 | 
			
		||||
 * \code #define USB_DEVICE_ATTACH_AUTO_DISABLE \endcode
 | 
			
		||||
 * User C file contains:
 | 
			
		||||
 * \code
 | 
			
		||||
    // Authorize VBUS monitoring
 | 
			
		||||
    if (!udc_include_vbus_monitoring()) {
 | 
			
		||||
      // Implement custom VBUS monitoring via GPIO or other
 | 
			
		||||
    }
 | 
			
		||||
    Event_VBUS_present() // VBUS interrupt or GPIO interrupt or other
 | 
			
		||||
    {
 | 
			
		||||
      // Attach USB Device
 | 
			
		||||
      udc_attach();
 | 
			
		||||
    }
 | 
			
		||||
\endcode
 | 
			
		||||
 *
 | 
			
		||||
 * - Case of battery charging. conf_usb.h file contains define
 | 
			
		||||
 * USB_DEVICE_ATTACH_AUTO_DISABLE:
 | 
			
		||||
 * \code #define USB_DEVICE_ATTACH_AUTO_DISABLE \endcode
 | 
			
		||||
 * User C file contains:
 | 
			
		||||
 * \code
 | 
			
		||||
    Event VBUS present() // VBUS interrupt or GPIO interrupt or ..
 | 
			
		||||
    {
 | 
			
		||||
      // Authorize battery charging, but wait key press to start USB.
 | 
			
		||||
    }
 | 
			
		||||
    Event Key press()
 | 
			
		||||
    {
 | 
			
		||||
      // Stop batteries charging
 | 
			
		||||
      // Start USB
 | 
			
		||||
      udc_attach();
 | 
			
		||||
    }
 | 
			
		||||
\endcode
 | 
			
		||||
 */
 | 
			
		||||
static inline bool udc_include_vbus_monitoring(void) {
 | 
			
		||||
    return udd_include_vbus_monitoring();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*! \brief Start the USB Device stack
 | 
			
		||||
 */
 | 
			
		||||
void udc_start(void);
 | 
			
		||||
 | 
			
		||||
/*! \brief Stop the USB Device stack
 | 
			
		||||
 */
 | 
			
		||||
void udc_stop(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Attach device to the bus when possible
 | 
			
		||||
 *
 | 
			
		||||
 * \warning If a VBus control is included in driver,
 | 
			
		||||
 * then it will attach device when an acceptable Vbus
 | 
			
		||||
 * level from the host is detected.
 | 
			
		||||
 */
 | 
			
		||||
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();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*! \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();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Returns a pointer on the current interface descriptor
 | 
			
		||||
 *
 | 
			
		||||
 * \return pointer on the current interface descriptor.
 | 
			
		||||
 */
 | 
			
		||||
usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void);
 | 
			
		||||
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \ingroup usb_group
 | 
			
		||||
 * \defgroup usb_device_group USB Stack Device
 | 
			
		||||
 *
 | 
			
		||||
 * This module includes USB Stack Device implementation.
 | 
			
		||||
 * The stack is divided in three parts:
 | 
			
		||||
 * - USB Device Controller (UDC) provides USB chapter 9 compliance
 | 
			
		||||
 * - USB Device Interface (UDI) provides USB Class compliance
 | 
			
		||||
 * - USB Device Driver (UDD) provides USB Driver for each Atmel MCU
 | 
			
		||||
 | 
			
		||||
 * Many USB Device applications can be implemented on Atmel MCU.
 | 
			
		||||
 * Atmel provides many application notes for different applications:
 | 
			
		||||
 * - AVR4900, provides general information about Device Stack
 | 
			
		||||
 * - AVR4901, explains how to create a new class
 | 
			
		||||
 * - AVR4902, explains how to create a composite device
 | 
			
		||||
 * - AVR49xx, all device classes provided in ASF have an application note
 | 
			
		||||
 *
 | 
			
		||||
 * A basic USB knowledge is required to understand the USB Device
 | 
			
		||||
 * Class application notes (HID,MS,CDC,PHDC,...).
 | 
			
		||||
 * Then, to create an USB device with
 | 
			
		||||
 * only one class provided by ASF, refer directly to the application note
 | 
			
		||||
 * corresponding to this USB class. The USB Device application note for
 | 
			
		||||
 * New Class and Composite is dedicated to advanced USB users.
 | 
			
		||||
 *
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // _UDC_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,132 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief Common API for USB Device Interface
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _UDC_DESC_H_
 | 
			
		||||
#define _UDC_DESC_H_
 | 
			
		||||
 | 
			
		||||
#include "conf_usb.h"
 | 
			
		||||
#include "usb_protocol.h"
 | 
			
		||||
#include "udi.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \ingroup udc_group
 | 
			
		||||
 * \defgroup udc_desc_group USB Device Descriptor
 | 
			
		||||
 *
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Defines the memory's location of USB descriptors
 | 
			
		||||
 *
 | 
			
		||||
 * By default the Descriptor is stored in RAM
 | 
			
		||||
 * (UDC_DESC_STORAGE is defined empty).
 | 
			
		||||
 *
 | 
			
		||||
 * If you have need to free RAM space,
 | 
			
		||||
 * it is possible to put descriptor in flash in following case:
 | 
			
		||||
 * - USB driver authorize flash transfer (USBB on UC3 and USB on Mega)
 | 
			
		||||
 * - USB Device is not high speed (UDC no need to change USB descriptors)
 | 
			
		||||
 *
 | 
			
		||||
 * For UC3 application used "const".
 | 
			
		||||
 *
 | 
			
		||||
 * For Mega application used "code".
 | 
			
		||||
 */
 | 
			
		||||
#define UDC_DESC_STORAGE
 | 
			
		||||
// Descriptor storage in internal RAM
 | 
			
		||||
#if (defined UDC_DATA_USE_HRAM_SUPPORT)
 | 
			
		||||
#    if defined(__GNUC__)
 | 
			
		||||
#        define UDC_DATA(x) COMPILER_WORD_ALIGNED __attribute__((__section__(".data_hram0")))
 | 
			
		||||
#        define UDC_BSS(x) COMPILER_ALIGNED(x) __attribute__((__section__(".bss_hram0")))
 | 
			
		||||
#    elif defined(__ICCAVR32__)
 | 
			
		||||
#        define UDC_DATA(x) COMPILER_ALIGNED(x) __data32
 | 
			
		||||
#        define UDC_BSS(x) COMPILER_ALIGNED(x) __data32
 | 
			
		||||
#    endif
 | 
			
		||||
#else
 | 
			
		||||
#    define UDC_DATA(x) COMPILER_ALIGNED(x)
 | 
			
		||||
#    define UDC_BSS(x) COMPILER_ALIGNED(x)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Configuration descriptor and UDI link for one USB speed
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    //! USB configuration descriptor
 | 
			
		||||
    usb_conf_desc_t UDC_DESC_STORAGE *desc;
 | 
			
		||||
    //! Array of UDI API pointer
 | 
			
		||||
    udi_api_t UDC_DESC_STORAGE *UDC_DESC_STORAGE *udi_apis;
 | 
			
		||||
} udc_config_speed_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief All information about the USB Device
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    //! USB device descriptor for low or full speed
 | 
			
		||||
    usb_dev_desc_t UDC_DESC_STORAGE *confdev_lsfs;
 | 
			
		||||
    //! USB configuration descriptor and UDI API pointers for low or full speed
 | 
			
		||||
    udc_config_speed_t UDC_DESC_STORAGE *conf_lsfs;
 | 
			
		||||
#ifdef USB_DEVICE_HS_SUPPORT
 | 
			
		||||
    //! USB device descriptor for high speed
 | 
			
		||||
    usb_dev_desc_t UDC_DESC_STORAGE *confdev_hs;
 | 
			
		||||
    //! USB device qualifier, only use in high speed mode
 | 
			
		||||
    usb_dev_qual_desc_t UDC_DESC_STORAGE *qualifier;
 | 
			
		||||
    //! USB configuration descriptor and UDI API pointers for high speed
 | 
			
		||||
    udc_config_speed_t UDC_DESC_STORAGE *conf_hs;
 | 
			
		||||
#endif
 | 
			
		||||
    usb_dev_bos_desc_t UDC_DESC_STORAGE *conf_bos;
 | 
			
		||||
} udc_config_t;
 | 
			
		||||
 | 
			
		||||
//! Global variables of USB Device Descriptor and UDI links
 | 
			
		||||
extern UDC_DESC_STORAGE udc_config_t udc_config;
 | 
			
		||||
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif // _UDC_DESC_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,384 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief Common API for USB Device Drivers (UDD)
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _UDD_H_
 | 
			
		||||
#define _UDD_H_
 | 
			
		||||
 | 
			
		||||
#include "usb_protocol.h"
 | 
			
		||||
#include "udc_desc.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \ingroup usb_device_group
 | 
			
		||||
 * \defgroup udd_group USB Device Driver (UDD)
 | 
			
		||||
 *
 | 
			
		||||
 * The UDD driver provides a low-level abstraction of the device
 | 
			
		||||
 * controller hardware. Most events coming from the hardware such as
 | 
			
		||||
 * interrupts, which may cause the UDD to call into the UDC and UDI.
 | 
			
		||||
 *
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//! \brief Endpoint identifier
 | 
			
		||||
typedef uint8_t udd_ep_id_t;
 | 
			
		||||
 | 
			
		||||
//! \brief Endpoint transfer status
 | 
			
		||||
//! Returned in parameters of callback register via udd_ep_run routine.
 | 
			
		||||
typedef enum {
 | 
			
		||||
    UDD_EP_TRANSFER_OK    = 0,
 | 
			
		||||
    UDD_EP_TRANSFER_ABORT = 1,
 | 
			
		||||
} udd_ep_status_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Global variable to give and record information of the setup request management
 | 
			
		||||
 *
 | 
			
		||||
 * This global variable allows to decode and response a setup request.
 | 
			
		||||
 * It can be updated by udc_process_setup() from UDC or *setup() from UDIs.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    //! Data received in USB SETUP packet
 | 
			
		||||
    //! Note: The swap of "req.wValues" from uin16_t to le16_t is done by UDD.
 | 
			
		||||
    usb_setup_req_t req;
 | 
			
		||||
 | 
			
		||||
    //! Point to buffer to send or fill with data following SETUP packet
 | 
			
		||||
    //! This buffer must be word align for DATA IN phase (use prefix COMPILER_WORD_ALIGNED for buffer)
 | 
			
		||||
    uint8_t *payload;
 | 
			
		||||
 | 
			
		||||
    //! Size of buffer to send or fill, and content the number of byte transfered
 | 
			
		||||
    uint16_t payload_size;
 | 
			
		||||
 | 
			
		||||
    //! Callback called after reception of ZLP from setup request
 | 
			
		||||
    void (*callback)(void);
 | 
			
		||||
 | 
			
		||||
    //! Callback called when the buffer given (.payload) is full or empty.
 | 
			
		||||
    //! This one return false to abort data transfer, or true with a new buffer in .payload.
 | 
			
		||||
    bool (*over_under_run)(void);
 | 
			
		||||
} udd_ctrl_request_t;
 | 
			
		||||
extern udd_ctrl_request_t udd_g_ctrlreq;
 | 
			
		||||
 | 
			
		||||
//! Return true if the setup request \a udd_g_ctrlreq indicates IN data transfer
 | 
			
		||||
#define Udd_setup_is_in() (USB_REQ_DIR_IN == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK))
 | 
			
		||||
 | 
			
		||||
//! Return true if the setup request \a udd_g_ctrlreq indicates OUT data transfer
 | 
			
		||||
#define Udd_setup_is_out() (USB_REQ_DIR_OUT == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK))
 | 
			
		||||
 | 
			
		||||
//! Return the type of the SETUP request \a udd_g_ctrlreq. \see usb_reqtype.
 | 
			
		||||
#define Udd_setup_type() (udd_g_ctrlreq.req.bmRequestType & USB_REQ_TYPE_MASK)
 | 
			
		||||
 | 
			
		||||
//! Return the recipient of the SETUP request \a udd_g_ctrlreq. \see usb_recipient
 | 
			
		||||
#define Udd_setup_recipient() (udd_g_ctrlreq.req.bmRequestType & USB_REQ_RECIP_MASK)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief End of halt callback function type.
 | 
			
		||||
 * Registered by routine udd_ep_wait_stall_clear()
 | 
			
		||||
 * Callback called when endpoint stall is cleared.
 | 
			
		||||
 */
 | 
			
		||||
typedef void (*udd_callback_halt_cleared_t)(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief End of transfer callback function type.
 | 
			
		||||
 * Registered by routine udd_ep_run()
 | 
			
		||||
 * Callback called by USB interrupt after data transfer or abort (reset,...).
 | 
			
		||||
 *
 | 
			
		||||
 * \param status     UDD_EP_TRANSFER_OK, if transfer is complete
 | 
			
		||||
 * \param status     UDD_EP_TRANSFER_ABORT, if transfer is aborted
 | 
			
		||||
 * \param n          number of data transfered
 | 
			
		||||
 */
 | 
			
		||||
typedef void (*udd_callback_trans_t)(udd_ep_status_t status, iram_size_t nb_transfered, udd_ep_id_t ep);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Authorizes the VBUS event
 | 
			
		||||
 *
 | 
			
		||||
 * \return true, if the VBUS monitoring is possible.
 | 
			
		||||
 */
 | 
			
		||||
bool udd_include_vbus_monitoring(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Enables the USB Device mode
 | 
			
		||||
 */
 | 
			
		||||
void udd_enable(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Disables the USB Device mode
 | 
			
		||||
 */
 | 
			
		||||
void udd_disable(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Attach device to the bus when possible
 | 
			
		||||
 *
 | 
			
		||||
 * \warning If a VBus control is included in driver,
 | 
			
		||||
 * then it will attach device when an acceptable Vbus
 | 
			
		||||
 * level from the host is detected.
 | 
			
		||||
 */
 | 
			
		||||
void udd_attach(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Detaches the device from the bus
 | 
			
		||||
 *
 | 
			
		||||
 * The driver must remove pull-up on USB line D- or D+.
 | 
			
		||||
 */
 | 
			
		||||
void udd_detach(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Test whether the USB Device Controller is running at high
 | 
			
		||||
 * speed or not.
 | 
			
		||||
 *
 | 
			
		||||
 * \return \c true if the Device is running at high speed mode, otherwise \c false.
 | 
			
		||||
 */
 | 
			
		||||
bool udd_is_high_speed(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Changes the USB address of device
 | 
			
		||||
 *
 | 
			
		||||
 * \param address    New USB address
 | 
			
		||||
 */
 | 
			
		||||
void udd_set_address(uint8_t address);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Returns the USB address of device
 | 
			
		||||
 *
 | 
			
		||||
 * \return USB address
 | 
			
		||||
 */
 | 
			
		||||
uint8_t udd_getaddress(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Returns the current start of frame number
 | 
			
		||||
 *
 | 
			
		||||
 * \return current start of frame number.
 | 
			
		||||
 */
 | 
			
		||||
uint16_t udd_get_frame_number(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Returns the current micro start of frame number
 | 
			
		||||
 *
 | 
			
		||||
 * \return current micro start of frame number required in high speed mode.
 | 
			
		||||
 */
 | 
			
		||||
uint16_t udd_get_micro_frame_number(void);
 | 
			
		||||
 | 
			
		||||
/*! \brief The USB driver sends a resume signal called Upstream Resume
 | 
			
		||||
 */
 | 
			
		||||
void udd_send_remotewakeup(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Load setup payload
 | 
			
		||||
 *
 | 
			
		||||
 * \param payload       Pointer on payload
 | 
			
		||||
 * \param payload_size  Size of payload
 | 
			
		||||
 */
 | 
			
		||||
void udd_set_setup_payload(uint8_t *payload, uint16_t payload_size);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \name Endpoint Management
 | 
			
		||||
 *
 | 
			
		||||
 * The following functions allow drivers to create and remove
 | 
			
		||||
 * endpoints, as well as set, clear and query their "halted" and
 | 
			
		||||
 * "wedged" states.
 | 
			
		||||
 */
 | 
			
		||||
//@{
 | 
			
		||||
 | 
			
		||||
#if (USB_DEVICE_MAX_EP != 0)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Configures and enables an endpoint
 | 
			
		||||
 *
 | 
			
		||||
 * \param ep               Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT).
 | 
			
		||||
 * \param bmAttributes     Attributes of endpoint declared in the descriptor.
 | 
			
		||||
 * \param MaxEndpointSize  Endpoint maximum size
 | 
			
		||||
 *
 | 
			
		||||
 * \return \c 1 if the endpoint is enabled, otherwise \c 0.
 | 
			
		||||
 */
 | 
			
		||||
bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, uint16_t MaxEndpointSize);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Disables an endpoint
 | 
			
		||||
 *
 | 
			
		||||
 * \param ep               Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT).
 | 
			
		||||
 */
 | 
			
		||||
void udd_ep_free(udd_ep_id_t ep);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Check if the endpoint \a ep is halted.
 | 
			
		||||
 *
 | 
			
		||||
 * \param ep The ID of the endpoint to check.
 | 
			
		||||
 *
 | 
			
		||||
 * \return \c 1 if \a ep is halted, otherwise \c 0.
 | 
			
		||||
 */
 | 
			
		||||
bool udd_ep_is_halted(udd_ep_id_t ep);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Set the halted state of the endpoint \a ep
 | 
			
		||||
 *
 | 
			
		||||
 * After calling this function, any transaction on \a ep will result
 | 
			
		||||
 * in a STALL handshake being sent. Any pending transactions will be
 | 
			
		||||
 * performed first, however.
 | 
			
		||||
 *
 | 
			
		||||
 * \param ep The ID of the endpoint to be halted
 | 
			
		||||
 *
 | 
			
		||||
 * \return \c 1 if \a ep is halted, otherwise \c 0.
 | 
			
		||||
 */
 | 
			
		||||
bool udd_ep_set_halt(udd_ep_id_t ep);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Clear the halted state of the endpoint \a ep
 | 
			
		||||
 *
 | 
			
		||||
 * After calling this function, any transaction on \a ep will
 | 
			
		||||
 * be handled normally, i.e. a STALL handshake will not be sent, and
 | 
			
		||||
 * the data toggle sequence will start at DATA0.
 | 
			
		||||
 *
 | 
			
		||||
 * \param ep The ID of the endpoint to be un-halted
 | 
			
		||||
 *
 | 
			
		||||
 * \return \c 1 if function was successfully done, otherwise \c 0.
 | 
			
		||||
 */
 | 
			
		||||
bool udd_ep_clear_halt(udd_ep_id_t ep);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Registers a callback to call when endpoint halt is cleared
 | 
			
		||||
 *
 | 
			
		||||
 * \param ep            The ID of the endpoint to use
 | 
			
		||||
 * \param callback      NULL or function to call when endpoint halt is cleared
 | 
			
		||||
 *
 | 
			
		||||
 * \warning if the endpoint is not halted then the \a callback is called immediately.
 | 
			
		||||
 *
 | 
			
		||||
 * \return \c 1 if the register is accepted, otherwise \c 0.
 | 
			
		||||
 */
 | 
			
		||||
bool udd_ep_wait_stall_clear(udd_ep_id_t ep, udd_callback_halt_cleared_t callback);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Allows to receive or send data on an endpoint
 | 
			
		||||
 *
 | 
			
		||||
 * The driver uses a specific DMA USB to transfer data
 | 
			
		||||
 * from internal RAM to endpoint, if this one is available.
 | 
			
		||||
 * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called.
 | 
			
		||||
 * The \a callback returns the transfer status and eventually the number of byte transfered.
 | 
			
		||||
 * Note: The control endpoint is not authorized.
 | 
			
		||||
 *
 | 
			
		||||
 * \param ep            The ID of the endpoint to use
 | 
			
		||||
 * \param b_shortpacket Enabled automatic short packet
 | 
			
		||||
 * \param buf           Buffer on Internal RAM to send or fill.
 | 
			
		||||
 *                      It must be align, then use COMPILER_WORD_ALIGNED.
 | 
			
		||||
 * \param buf_size      Buffer size to send or fill
 | 
			
		||||
 * \param callback      NULL or function to call at the end of transfer
 | 
			
		||||
 *
 | 
			
		||||
 * \warning About \a b_shortpacket, for IN endpoint it means that a short packet
 | 
			
		||||
 * (or a Zero Length Packet) will be sent to the USB line to properly close the usb
 | 
			
		||||
 * transfer at the end of the data transfer.
 | 
			
		||||
 * For Bulk and Interrupt OUT endpoint, it will automatically stop the transfer
 | 
			
		||||
 * at the end of the data transfer (received short packet).
 | 
			
		||||
 *
 | 
			
		||||
 * \return \c 1 if function was successfully done, otherwise \c 0.
 | 
			
		||||
 */
 | 
			
		||||
bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, uint8_t *buf, iram_size_t buf_size, udd_callback_trans_t callback);
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Aborts transfer on going on endpoint
 | 
			
		||||
 *
 | 
			
		||||
 * If a transfer is on going, then it is stopped and
 | 
			
		||||
 * the callback registered is called to signal the end of transfer.
 | 
			
		||||
 * Note: The control endpoint is not authorized.
 | 
			
		||||
 *
 | 
			
		||||
 * \param ep            Endpoint to abort
 | 
			
		||||
 */
 | 
			
		||||
void udd_ep_abort(udd_ep_id_t ep);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \name High speed test mode management
 | 
			
		||||
 *
 | 
			
		||||
 * The following functions allow the device to jump to a specific test mode required in high speed mode.
 | 
			
		||||
 */
 | 
			
		||||
//@{
 | 
			
		||||
void udd_test_mode_j(void);
 | 
			
		||||
void udd_test_mode_k(void);
 | 
			
		||||
void udd_test_mode_se0_nak(void);
 | 
			
		||||
void udd_test_mode_packet(void);
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \name UDC callbacks to provide for UDD
 | 
			
		||||
 *
 | 
			
		||||
 * The following callbacks are used by UDD.
 | 
			
		||||
 */
 | 
			
		||||
//@{
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Decodes and manages a setup request
 | 
			
		||||
 *
 | 
			
		||||
 * The driver call it when a SETUP packet is received.
 | 
			
		||||
 * The \c udd_g_ctrlreq contains the data of SETUP packet.
 | 
			
		||||
 * If this callback accepts the setup request then it must
 | 
			
		||||
 * return \c 1 and eventually update \c udd_g_ctrlreq to send or receive data.
 | 
			
		||||
 *
 | 
			
		||||
 * \return \c 1 if the request is accepted, otherwise \c 0.
 | 
			
		||||
 */
 | 
			
		||||
extern bool udc_process_setup(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Reset the UDC
 | 
			
		||||
 *
 | 
			
		||||
 * The UDC must reset all configuration.
 | 
			
		||||
 */
 | 
			
		||||
extern void udc_reset(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief To signal that a SOF is occurred
 | 
			
		||||
 *
 | 
			
		||||
 * The UDC must send the signal to all UDIs enabled
 | 
			
		||||
 */
 | 
			
		||||
extern void udc_sof_notify(void);
 | 
			
		||||
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif // _UDD_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,133 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief Common API for USB Device Interface
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _UDI_H_
 | 
			
		||||
#define _UDI_H_
 | 
			
		||||
 | 
			
		||||
#include "conf_usb.h"
 | 
			
		||||
#include "usb_protocol.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \ingroup usb_device_group
 | 
			
		||||
 * \defgroup udi_group USB Device Interface (UDI)
 | 
			
		||||
 * The UDI provides a common API for all classes,
 | 
			
		||||
 * and this is used by UDC for the main control of USB Device interface.
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief UDI API.
 | 
			
		||||
 *
 | 
			
		||||
 * The callbacks within this structure are called only by
 | 
			
		||||
 * USB Device Controller (UDC)
 | 
			
		||||
 *
 | 
			
		||||
 * The udc_get_interface_desc() can be use by UDI to know the interface descriptor
 | 
			
		||||
 * selected by UDC.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    /**
 | 
			
		||||
     * \brief Enable the interface.
 | 
			
		||||
     *
 | 
			
		||||
     * This function is called when the host selects a configuration
 | 
			
		||||
     * to which this interface belongs through a Set Configuration
 | 
			
		||||
     * request, and when the host selects an alternate setting of
 | 
			
		||||
     * this interface through a Set Interface request.
 | 
			
		||||
     *
 | 
			
		||||
     * \return \c 1 if function was successfully done, otherwise \c 0.
 | 
			
		||||
     */
 | 
			
		||||
    bool (*enable)(void);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * \brief Disable the interface.
 | 
			
		||||
     *
 | 
			
		||||
     * This function is called when this interface is currently
 | 
			
		||||
     * active, and
 | 
			
		||||
     * - the host selects any configuration through a Set
 | 
			
		||||
     *   Configuration request, or
 | 
			
		||||
     * - the host issues a USB reset, or
 | 
			
		||||
     * - the device is detached from the host (i.e. Vbus is no
 | 
			
		||||
     *   longer present)
 | 
			
		||||
     */
 | 
			
		||||
    void (*disable)(void);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * \brief Handle a control request directed at an interface.
 | 
			
		||||
     *
 | 
			
		||||
     * This function is called when this interface is currently
 | 
			
		||||
     * active and the host sends a SETUP request
 | 
			
		||||
     * with this interface as the recipient.
 | 
			
		||||
     *
 | 
			
		||||
     * Use udd_g_ctrlreq to decode and response to SETUP request.
 | 
			
		||||
     *
 | 
			
		||||
     * \return \c 1 if this interface supports the SETUP request, otherwise \c 0.
 | 
			
		||||
     */
 | 
			
		||||
    bool (*setup)(void);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * \brief Returns the current setting of the selected interface.
 | 
			
		||||
     *
 | 
			
		||||
     * This function is called when UDC when know alternate setting of selected interface.
 | 
			
		||||
     *
 | 
			
		||||
     * \return alternate setting of selected interface
 | 
			
		||||
     */
 | 
			
		||||
    uint8_t (*getsetting)(void);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * \brief To signal that a SOF is occurred
 | 
			
		||||
     */
 | 
			
		||||
    void (*sof_notify)(void);
 | 
			
		||||
} udi_api_t;
 | 
			
		||||
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif // _UDI_H_
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,376 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief USB Device Communication Device Class (CDC) interface definitions.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2016 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _UDI_CDC_H_
 | 
			
		||||
#define _UDI_CDC_H_
 | 
			
		||||
 | 
			
		||||
#ifdef VIRTSER_ENABLE
 | 
			
		||||
 | 
			
		||||
#    include "conf_usb.h"
 | 
			
		||||
#    include "usb_protocol.h"
 | 
			
		||||
#    include "usb_protocol_cdc.h"
 | 
			
		||||
#    include "udd.h"
 | 
			
		||||
#    include "udc_desc.h"
 | 
			
		||||
#    include "udi.h"
 | 
			
		||||
 | 
			
		||||
// Check the number of port
 | 
			
		||||
#    ifndef UDI_CDC_PORT_NB
 | 
			
		||||
#        define UDI_CDC_PORT_NB 1
 | 
			
		||||
#    endif
 | 
			
		||||
#    if (UDI_CDC_PORT_NB > 1)
 | 
			
		||||
#        error UDI_CDC_PORT_NB must be at most 1
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \addtogroup udi_cdc_group_udc
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//! Global structure which contains standard UDI API for UDC
 | 
			
		||||
extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm;
 | 
			
		||||
extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_data;
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
//#define CDC_ACM_SIZE  64  see usb_protocol_cdc.h
 | 
			
		||||
//#define CDC_RX_SIZE   64
 | 
			
		||||
 | 
			
		||||
//! CDC communication endpoints size for all speeds
 | 
			
		||||
#    define UDI_CDC_COMM_EP_SIZE CDC_ACM_SIZE
 | 
			
		||||
//! CDC data endpoints size for FS speed (8B, 16B, 32B, 64B)
 | 
			
		||||
#    define UDI_CDC_DATA_EPS_FS_SIZE CDC_RX_SIZE
 | 
			
		||||
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \ingroup udi_group
 | 
			
		||||
 * \defgroup udi_cdc_group USB Device Interface (UDI) for Communication Class Device (CDC)
 | 
			
		||||
 *
 | 
			
		||||
 * Common APIs used by high level application to use this USB class.
 | 
			
		||||
 *
 | 
			
		||||
 * These routines are used to transfer and control data
 | 
			
		||||
 * to/from USB CDC endpoint.
 | 
			
		||||
 *
 | 
			
		||||
 * See \ref udi_cdc_quickstart.
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \name Interface for application with single CDC interface support
 | 
			
		||||
 */
 | 
			
		||||
//@{
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Notify a state change of DCD signal
 | 
			
		||||
 *
 | 
			
		||||
 * \param b_set      DCD is enabled if true, else disabled
 | 
			
		||||
 */
 | 
			
		||||
void udi_cdc_ctrl_signal_dcd(bool b_set);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Notify a state change of DSR signal
 | 
			
		||||
 *
 | 
			
		||||
 * \param b_set      DSR is enabled if true, else disabled
 | 
			
		||||
 */
 | 
			
		||||
void udi_cdc_ctrl_signal_dsr(bool b_set);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Notify a framing error
 | 
			
		||||
 */
 | 
			
		||||
void udi_cdc_signal_framing_error(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Notify a parity error
 | 
			
		||||
 */
 | 
			
		||||
void udi_cdc_signal_parity_error(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Notify a overrun
 | 
			
		||||
 */
 | 
			
		||||
void udi_cdc_signal_overrun(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Gets the number of byte received
 | 
			
		||||
 *
 | 
			
		||||
 * \return the number of data available
 | 
			
		||||
 */
 | 
			
		||||
iram_size_t udi_cdc_get_nb_received_data(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief This function checks if a character has been received on the CDC line
 | 
			
		||||
 *
 | 
			
		||||
 * \return \c 1 if a byte is ready to be read.
 | 
			
		||||
 */
 | 
			
		||||
bool udi_cdc_is_rx_ready(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Waits and gets a value on CDC line
 | 
			
		||||
 *
 | 
			
		||||
 * \return value read on CDC line
 | 
			
		||||
 */
 | 
			
		||||
int udi_cdc_getc(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Reads a RAM buffer on CDC line
 | 
			
		||||
 *
 | 
			
		||||
 * \param buf       Values read
 | 
			
		||||
 * \param size      Number of value read
 | 
			
		||||
 *
 | 
			
		||||
 * \return the number of data remaining
 | 
			
		||||
 */
 | 
			
		||||
iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Non polling reads of a up to 'size' data from CDC line
 | 
			
		||||
 *
 | 
			
		||||
 * \param port      Communication port number to manage
 | 
			
		||||
 * \param buf       Buffer where to store read data
 | 
			
		||||
 * \param size      Maximum number of data to read (size of buffer)
 | 
			
		||||
 *
 | 
			
		||||
 * \return the number of data effectively read
 | 
			
		||||
 */
 | 
			
		||||
iram_size_t udi_cdc_read_no_polling(void* buf, iram_size_t size);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Gets the number of free byte in TX buffer
 | 
			
		||||
 *
 | 
			
		||||
 * \return the number of free byte in TX buffer
 | 
			
		||||
 */
 | 
			
		||||
iram_size_t udi_cdc_get_free_tx_buffer(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief This function checks if a new character sent is possible
 | 
			
		||||
 * The type int is used to support scanf redirection from compiler LIB.
 | 
			
		||||
 *
 | 
			
		||||
 * \return \c 1 if a new character can be sent
 | 
			
		||||
 */
 | 
			
		||||
bool udi_cdc_is_tx_ready(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Puts a byte on CDC line
 | 
			
		||||
 * The type int is used to support printf redirection from compiler LIB.
 | 
			
		||||
 *
 | 
			
		||||
 * \param value      Value to put
 | 
			
		||||
 *
 | 
			
		||||
 * \return \c 1 if function was successfully done, otherwise \c 0.
 | 
			
		||||
 */
 | 
			
		||||
int udi_cdc_putc(int value);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Writes a RAM buffer on CDC line
 | 
			
		||||
 *
 | 
			
		||||
 * \param buf       Values to write
 | 
			
		||||
 * \param size      Number of value to write
 | 
			
		||||
 *
 | 
			
		||||
 * \return the number of data remaining
 | 
			
		||||
 */
 | 
			
		||||
iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size);
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \name Interface for application with multi CDC interfaces support
 | 
			
		||||
 */
 | 
			
		||||
//@{
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Notify a state change of DCD signal
 | 
			
		||||
 *
 | 
			
		||||
 * \param port       Communication port number to manage
 | 
			
		||||
 * \param b_set      DCD is enabled if true, else disabled
 | 
			
		||||
 */
 | 
			
		||||
void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Notify a state change of DSR signal
 | 
			
		||||
 *
 | 
			
		||||
 * \param port       Communication port number to manage
 | 
			
		||||
 * \param b_set      DSR is enabled if true, else disabled
 | 
			
		||||
 */
 | 
			
		||||
void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Notify a framing error
 | 
			
		||||
 *
 | 
			
		||||
 * \param port       Communication port number to manage
 | 
			
		||||
 */
 | 
			
		||||
void udi_cdc_multi_signal_framing_error(uint8_t port);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Notify a parity error
 | 
			
		||||
 *
 | 
			
		||||
 * \param port       Communication port number to manage
 | 
			
		||||
 */
 | 
			
		||||
void udi_cdc_multi_signal_parity_error(uint8_t port);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Notify a overrun
 | 
			
		||||
 *
 | 
			
		||||
 * \param port       Communication port number to manage
 | 
			
		||||
 */
 | 
			
		||||
void udi_cdc_multi_signal_overrun(uint8_t port);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Gets the number of byte received
 | 
			
		||||
 *
 | 
			
		||||
 * \param port       Communication port number to manage
 | 
			
		||||
 *
 | 
			
		||||
 * \return the number of data available
 | 
			
		||||
 */
 | 
			
		||||
iram_size_t udi_cdc_multi_get_nb_received_data(uint8_t port);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief This function checks if a character has been received on the CDC line
 | 
			
		||||
 *
 | 
			
		||||
 * \param port       Communication port number to manage
 | 
			
		||||
 *
 | 
			
		||||
 * \return \c 1 if a byte is ready to be read.
 | 
			
		||||
 */
 | 
			
		||||
bool udi_cdc_multi_is_rx_ready(uint8_t port);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Waits and gets a value on CDC line
 | 
			
		||||
 *
 | 
			
		||||
 * \param port       Communication port number to manage
 | 
			
		||||
 *
 | 
			
		||||
 * \return value read on CDC line
 | 
			
		||||
 */
 | 
			
		||||
int udi_cdc_multi_getc(uint8_t port);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Reads a RAM buffer on CDC line
 | 
			
		||||
 *
 | 
			
		||||
 * \param port       Communication port number to manage
 | 
			
		||||
 * \param buf       Values read
 | 
			
		||||
 * \param size      Number of values read
 | 
			
		||||
 *
 | 
			
		||||
 * \return the number of data remaining
 | 
			
		||||
 */
 | 
			
		||||
iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Gets the number of free byte in TX buffer
 | 
			
		||||
 *
 | 
			
		||||
 * \param port       Communication port number to manage
 | 
			
		||||
 *
 | 
			
		||||
 * \return the number of free byte in TX buffer
 | 
			
		||||
 */
 | 
			
		||||
iram_size_t udi_cdc_multi_get_free_tx_buffer(uint8_t port);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief This function checks if a new character sent is possible
 | 
			
		||||
 * The type int is used to support scanf redirection from compiler LIB.
 | 
			
		||||
 *
 | 
			
		||||
 * \param port       Communication port number to manage
 | 
			
		||||
 *
 | 
			
		||||
 * \return \c 1 if a new character can be sent
 | 
			
		||||
 */
 | 
			
		||||
bool udi_cdc_multi_is_tx_ready(uint8_t port);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Puts a byte on CDC line
 | 
			
		||||
 * The type int is used to support printf redirection from compiler LIB.
 | 
			
		||||
 *
 | 
			
		||||
 * \param port       Communication port number to manage
 | 
			
		||||
 * \param value      Value to put
 | 
			
		||||
 *
 | 
			
		||||
 * \return \c 1 if function was successfully done, otherwise \c 0.
 | 
			
		||||
 */
 | 
			
		||||
int udi_cdc_multi_putc(uint8_t port, int value);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Writes a RAM buffer on CDC line
 | 
			
		||||
 *
 | 
			
		||||
 * \param port       Communication port number to manage
 | 
			
		||||
 * \param buf       Values to write
 | 
			
		||||
 * \param size      Number of value to write
 | 
			
		||||
 *
 | 
			
		||||
 * \return the number of data remaining
 | 
			
		||||
 */
 | 
			
		||||
iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size);
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
#    define CDC_PRINTBUF_SIZE 256
 | 
			
		||||
extern char printbuf[CDC_PRINTBUF_SIZE];
 | 
			
		||||
 | 
			
		||||
#    define CDC_INBUF_SIZE 256
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint32_t count;
 | 
			
		||||
    uint32_t lastcount;
 | 
			
		||||
    char     buf[CDC_INBUF_SIZE];
 | 
			
		||||
} inbuf_t;
 | 
			
		||||
 | 
			
		||||
#else // VIRTSER_ENABLE
 | 
			
		||||
 | 
			
		||||
// keep these to accommodate calls if remaining
 | 
			
		||||
#    define CDC_PRINTBUF_SIZE 1
 | 
			
		||||
extern char printbuf[CDC_PRINTBUF_SIZE];
 | 
			
		||||
 | 
			
		||||
#    define CDC_INBUF_SIZE 1
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint32_t count;
 | 
			
		||||
    uint32_t lastcount;
 | 
			
		||||
    char     buf[CDC_INBUF_SIZE];
 | 
			
		||||
} inbuf_t;
 | 
			
		||||
 | 
			
		||||
extern inbuf_t inbuf;
 | 
			
		||||
 | 
			
		||||
#endif // VIRTSER_ENABLE
 | 
			
		||||
 | 
			
		||||
uint32_t CDC_print(char* printbuf);
 | 
			
		||||
int      CDC_printf(const char* _Format, ...);
 | 
			
		||||
uint32_t CDC_input(void);
 | 
			
		||||
void     CDC_init(void);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // _UDI_CDC_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,72 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief Default CDC configuration for a USB Device with a single interface
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _UDI_CDC_CONF_H_
 | 
			
		||||
#define _UDI_CDC_CONF_H_
 | 
			
		||||
 | 
			
		||||
#include "usb_protocol_cdc.h"
 | 
			
		||||
#include "conf_usb.h"
 | 
			
		||||
#include "udi_device_conf.h"
 | 
			
		||||
 | 
			
		||||
#ifndef UDI_CDC_PORT_NB
 | 
			
		||||
#    define UDI_CDC_PORT_NB 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
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_COMM_IFACE_NUMBER_0 (CDC_STATUS_INTERFACE)
 | 
			
		||||
#define UDI_CDC_DATA_IFACE_NUMBER_0 (CDC_DATA_INTERFACE)
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif // _UDI_CDC_CONF_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,806 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _UDI_DEVICE_CONF_H_
 | 
			
		||||
#define _UDI_DEVICE_CONF_H_
 | 
			
		||||
 | 
			
		||||
#include "udi_device_epsize.h"
 | 
			
		||||
#include "usb_protocol.h"
 | 
			
		||||
#include "compiler.h"
 | 
			
		||||
#include "usb_protocol_hid.h"
 | 
			
		||||
 | 
			
		||||
#ifndef USB_POLLING_INTERVAL_MS
 | 
			
		||||
#    define USB_POLLING_INTERVAL_MS 10
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef VIRTSER_ENABLE
 | 
			
		||||
// because CDC uses IAD (interface association descriptor
 | 
			
		||||
// per USB Interface Association Descriptor Device Class Code and Use Model 7/23/2003 Rev 1.0)
 | 
			
		||||
#    define DEVICE_CLASS 0xEF
 | 
			
		||||
#    define DEVICE_SUBCLASS 0x02
 | 
			
		||||
#    define DEVICE_PROTOCOL 0x01
 | 
			
		||||
#else
 | 
			
		||||
#    define DEVICE_CLASS 0x00
 | 
			
		||||
#    define DEVICE_SUBCLASS 0x00
 | 
			
		||||
#    define DEVICE_PROTOCOL 0x00
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* number of interfaces */
 | 
			
		||||
#define NEXT_INTERFACE_0 0
 | 
			
		||||
 | 
			
		||||
#define KEYBOARD_INTERFACE NEXT_INTERFACE_0
 | 
			
		||||
#define NEXT_INTERFACE_1 (KEYBOARD_INTERFACE + 1)
 | 
			
		||||
#define UDI_HID_KBD_IFACE_NUMBER KEYBOARD_INTERFACE
 | 
			
		||||
 | 
			
		||||
// It is important that the Raw HID interface is at a constant
 | 
			
		||||
// interface number, to support Linux/OSX platforms and chrome.hid
 | 
			
		||||
// If Raw HID is enabled, let it be always 1.
 | 
			
		||||
#ifdef RAW_ENABLE
 | 
			
		||||
#    define RAW_INTERFACE NEXT_INTERFACE_1
 | 
			
		||||
#    define NEXT_INTERFACE_2 (RAW_INTERFACE + 1)
 | 
			
		||||
#else
 | 
			
		||||
#    define NEXT_INTERFACE_2 NEXT_INTERFACE_1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MOUSE_ENABLE
 | 
			
		||||
#    define MOUSE_INTERFACE NEXT_INTERFACE_2
 | 
			
		||||
#    define UDI_HID_MOU_IFACE_NUMBER MOUSE_INTERFACE
 | 
			
		||||
#    define NEXT_INTERFACE_3 (MOUSE_INTERFACE + 1)
 | 
			
		||||
#else
 | 
			
		||||
#    define NEXT_INTERFACE_3 NEXT_INTERFACE_2
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EXTRAKEY_ENABLE
 | 
			
		||||
#    define EXTRAKEY_INTERFACE NEXT_INTERFACE_3
 | 
			
		||||
#    define NEXT_INTERFACE_4 (EXTRAKEY_INTERFACE + 1)
 | 
			
		||||
#    define UDI_HID_EXK_IFACE_NUMBER EXTRAKEY_INTERFACE
 | 
			
		||||
#else
 | 
			
		||||
#    define NEXT_INTERFACE_4 NEXT_INTERFACE_3
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
#    define CON_INTERFACE NEXT_INTERFACE_4
 | 
			
		||||
#    define NEXT_INTERFACE_5 (CON_INTERFACE + 1)
 | 
			
		||||
#    define UDI_HID_CON_IFACE_NUMBER CON_INTERFACE
 | 
			
		||||
#else
 | 
			
		||||
#    define NEXT_INTERFACE_5 NEXT_INTERFACE_4
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef NKRO_ENABLE
 | 
			
		||||
#    define NKRO_INTERFACE NEXT_INTERFACE_5
 | 
			
		||||
#    define NEXT_INTERFACE_6 (NKRO_INTERFACE + 1)
 | 
			
		||||
#    define UDI_HID_NKRO_IFACE_NUMBER NKRO_INTERFACE
 | 
			
		||||
#else
 | 
			
		||||
#    define NEXT_INTERFACE_6 NEXT_INTERFACE_5
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
#    define AC_INTERFACE NEXT_INTERFACE_6
 | 
			
		||||
#    define AS_INTERFACE (AC_INTERFACE + 1)
 | 
			
		||||
#    define NEXT_INTERFACE_7 (AS_INTERFACE + 1)
 | 
			
		||||
#else
 | 
			
		||||
#    define NEXT_INTERFACE_7 NEXT_INTERFACE_6
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef VIRTSER_ENABLE
 | 
			
		||||
#    define CCI_INTERFACE NEXT_INTERFACE_7
 | 
			
		||||
#    define CDI_INTERFACE (CCI_INTERFACE + 1)
 | 
			
		||||
#    define NEXT_INTERFACE_8 (CDI_INTERFACE + 1)
 | 
			
		||||
#    define CDC_STATUS_INTERFACE CCI_INTERFACE
 | 
			
		||||
#    define CDC_DATA_INTERFACE CDI_INTERFACE
 | 
			
		||||
#else
 | 
			
		||||
#    define NEXT_INTERFACE_8 NEXT_INTERFACE_7
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* nubmer of interfaces */
 | 
			
		||||
#define TOTAL_INTERFACES NEXT_INTERFACE_8
 | 
			
		||||
#define USB_DEVICE_NB_INTERFACE TOTAL_INTERFACES
 | 
			
		||||
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
// Endopoint number and size
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
#define USB_DEVICE_EP_CTRL_SIZE 8
 | 
			
		||||
 | 
			
		||||
#define NEXT_IN_EPNUM_0 1
 | 
			
		||||
#define NEXT_OUT_EPNUM_0 1
 | 
			
		||||
 | 
			
		||||
#define KEYBOARD_IN_EPNUM NEXT_IN_EPNUM_0
 | 
			
		||||
#define UDI_HID_KBD_EP_IN KEYBOARD_IN_EPNUM
 | 
			
		||||
#define NEXT_IN_EPNUM_1 (KEYBOARD_IN_EPNUM + 1)
 | 
			
		||||
#define UDI_HID_KBD_EP_SIZE KEYBOARD_EPSIZE
 | 
			
		||||
#define KBD_POLLING_INTERVAL USB_POLLING_INTERVAL_MS
 | 
			
		||||
#ifndef UDI_HID_KBD_STRING_ID
 | 
			
		||||
#    define UDI_HID_KBD_STRING_ID 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MOUSE_ENABLE
 | 
			
		||||
#    define MOUSE_IN_EPNUM NEXT_IN_EPNUM_1
 | 
			
		||||
#    define NEXT_IN_EPNUM_2 (MOUSE_IN_EPNUM + 1)
 | 
			
		||||
#    define UDI_HID_MOU_EP_IN MOUSE_IN_EPNUM
 | 
			
		||||
#    define UDI_HID_MOU_EP_SIZE MOUSE_EPSIZE
 | 
			
		||||
#    define MOU_POLLING_INTERVAL USB_POLLING_INTERVAL_MS
 | 
			
		||||
#    ifndef UDI_HID_MOU_STRING_ID
 | 
			
		||||
#        define UDI_HID_MOU_STRING_ID 0
 | 
			
		||||
#    endif
 | 
			
		||||
#else
 | 
			
		||||
#    define NEXT_IN_EPNUM_2 NEXT_IN_EPNUM_1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EXTRAKEY_ENABLE
 | 
			
		||||
#    define EXTRAKEY_IN_EPNUM NEXT_IN_EPNUM_2
 | 
			
		||||
#    define UDI_HID_EXK_EP_IN EXTRAKEY_IN_EPNUM
 | 
			
		||||
#    define NEXT_IN_EPNUM_3 (EXTRAKEY_IN_EPNUM + 1)
 | 
			
		||||
#    define UDI_HID_EXK_EP_SIZE EXTRAKEY_EPSIZE
 | 
			
		||||
#    define EXTRAKEY_POLLING_INTERVAL USB_POLLING_INTERVAL_MS
 | 
			
		||||
#    ifndef UDI_HID_EXK_STRING_ID
 | 
			
		||||
#        define UDI_HID_EXK_STRING_ID 0
 | 
			
		||||
#    endif
 | 
			
		||||
#else
 | 
			
		||||
#    define NEXT_IN_EPNUM_3 NEXT_IN_EPNUM_2
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef RAW_ENABLE
 | 
			
		||||
#    define RAW_IN_EPNUM NEXT_IN_EPNUM_3
 | 
			
		||||
#    define UDI_HID_RAW_EP_IN RAW_IN_EPNUM
 | 
			
		||||
#    define NEXT_IN_EPNUM_4 (RAW_IN_EPNUM + 1)
 | 
			
		||||
#    define RAW_OUT_EPNUM NEXT_OUT_EPNUM_0
 | 
			
		||||
#    define UDI_HID_RAW_EP_OUT RAW_OUT_EPNUM
 | 
			
		||||
#    define NEXT_OUT_EPNUM_1 (RAW_OUT_EPNUM + 1)
 | 
			
		||||
#    define RAW_POLLING_INTERVAL 1
 | 
			
		||||
#    ifndef UDI_HID_RAW_STRING_ID
 | 
			
		||||
#        define UDI_HID_RAW_STRING_ID 0
 | 
			
		||||
#    endif
 | 
			
		||||
#else
 | 
			
		||||
#    define NEXT_IN_EPNUM_4 NEXT_IN_EPNUM_3
 | 
			
		||||
#    define NEXT_OUT_EPNUM_1 NEXT_OUT_EPNUM_0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
#    define CON_IN_EPNUM NEXT_IN_EPNUM_4
 | 
			
		||||
#    define UDI_HID_CON_EP_IN CON_IN_EPNUM
 | 
			
		||||
#    define NEXT_IN_EPNUM_5 (CON_IN_EPNUM + 1)
 | 
			
		||||
#    define CON_OUT_EPNUM NEXT_OUT_EPNUM_1
 | 
			
		||||
#    define UDI_HID_CON_EP_OUT CON_OUT_EPNUM
 | 
			
		||||
#    define NEXT_OUT_EPNUM_2 (CON_OUT_EPNUM + 1)
 | 
			
		||||
#    define CON_POLLING_INTERVAL 1
 | 
			
		||||
#    ifndef UDI_HID_CON_STRING_ID
 | 
			
		||||
#        define UDI_HID_CON_STRING_ID 0
 | 
			
		||||
#    endif
 | 
			
		||||
#else
 | 
			
		||||
#    define NEXT_IN_EPNUM_5 NEXT_IN_EPNUM_4
 | 
			
		||||
#    define NEXT_OUT_EPNUM_2 NEXT_OUT_EPNUM_1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef NKRO_ENABLE
 | 
			
		||||
#    define NKRO_IN_EPNUM NEXT_IN_EPNUM_5
 | 
			
		||||
#    define UDI_HID_NKRO_EP_IN NKRO_IN_EPNUM
 | 
			
		||||
#    define NEXT_IN_EPNUM_6 (NKRO_IN_EPNUM + 1)
 | 
			
		||||
#    define UDI_HID_NKRO_EP_SIZE NKRO_EPSIZE
 | 
			
		||||
#    define NKRO_POLLING_INTERVAL 1
 | 
			
		||||
#    ifndef UDI_HID_NKRO_STRING_ID
 | 
			
		||||
#        define UDI_HID_NKRO_STRING_ID 0
 | 
			
		||||
#    endif
 | 
			
		||||
#else
 | 
			
		||||
#    define NEXT_IN_EPNUM_6 NEXT_IN_EPNUM_5
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
#    define MIDI_STREAM_IN_EPNUM NEXT_IN_EPNUM_6
 | 
			
		||||
#    define NEXT_IN_EPNUM_7 (MIDI_STREAM_IN_EPNUM + 1)
 | 
			
		||||
#    define MIDI_STREAM_OUT_EPNUM NEXT_OUT_EPNUM_2
 | 
			
		||||
#    define NEXT_OUT_EPNUM_3 (MIDI_STREAM_OUT_EPNUM + 1)
 | 
			
		||||
#    define MIDI_POLLING_INTERVAL 5
 | 
			
		||||
#else
 | 
			
		||||
#    define NEXT_IN_EPNUM_7 NEXT_IN_EPNUM_6
 | 
			
		||||
#    define NEXT_OUT_EPNUM_3 NEXT_OUT_EPNUM_2
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef VIRTSER_ENABLE
 | 
			
		||||
#    define CDC_NOTIFICATION_EPNUM NEXT_IN_EPNUM_7
 | 
			
		||||
#    define CDC_ACM_ENDPOINT CDC_NOTIFICATION_EPNUM
 | 
			
		||||
#    define CDC_TX_ENDPOINT (CDC_NOTIFICATION_EPNUM + 1)
 | 
			
		||||
#    define NEXT_IN_EPNUM_8 (CDC_TX_ENDPOINT + 1)
 | 
			
		||||
 | 
			
		||||
#    define CDC_OUT_EPNUM NEXT_OUT_EPNUM_3
 | 
			
		||||
#    define CDC_RX_ENDPOINT CDC_OUT_EPNUM
 | 
			
		||||
#    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_TX_SIZE CDC_RX_SIZE
 | 
			
		||||
#    define CDC_ACM_POLLING_INTERVAL 255
 | 
			
		||||
#    define CDC_EP_INTERVAL_STATUS CDC_ACM_POLLING_INTERVAL
 | 
			
		||||
#    define CDC_DATA_POLLING_INTERVAL 5
 | 
			
		||||
#    define CDC_EP_INTERVAL_DATA CDC_DATA_POLLING_INTERVAL
 | 
			
		||||
#    define CDC_STATUS_NAME L"Virtual Serial Port - Status"
 | 
			
		||||
#    define CDC_DATA_NAME L"Virtual Serial Port - Data"
 | 
			
		||||
#else
 | 
			
		||||
#    define NEXT_IN_EPNUM_8 NEXT_IN_EPNUM_7
 | 
			
		||||
#    define NEXT_OUT_EPNUM_4 NEXT_OUT_EPNUM_3
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define TOTAL_OUT_EP NEXT_OUT_EPNUM_4
 | 
			
		||||
#define TOTAL_IN_EP NEXT_IN_EPNUM_8
 | 
			
		||||
#define USB_DEVICE_MAX_EP (max(NEXT_OUT_EPNUM_4, NEXT_IN_EPNUM_8))
 | 
			
		||||
 | 
			
		||||
#if USB_DEVICE_MAX_EP > 8
 | 
			
		||||
#    error "There are not enough available endpoints to support all functions. Remove some in the rules.mk file.(MOUSEKEY, EXTRAKEY, CONSOLE, NKRO, MIDI, VIRTSER)"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
// KBD Descriptor structure and content
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
COMPILER_PACK_SET(1)
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    usb_iface_desc_t     iface;
 | 
			
		||||
    usb_hid_descriptor_t hid;
 | 
			
		||||
    usb_ep_desc_t        ep;
 | 
			
		||||
} udi_hid_kbd_desc_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t array[59];
 | 
			
		||||
} udi_hid_kbd_report_desc_t;
 | 
			
		||||
 | 
			
		||||
// clang-format off
 | 
			
		||||
 | 
			
		||||
#    define UDI_HID_KBD_DESC { \
 | 
			
		||||
    .iface = { \
 | 
			
		||||
        .bLength = sizeof(usb_iface_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_INTERFACE, \
 | 
			
		||||
        .bInterfaceNumber = UDI_HID_KBD_IFACE_NUMBER, \
 | 
			
		||||
        .bAlternateSetting = 0, \
 | 
			
		||||
        .bNumEndpoints = 1, \
 | 
			
		||||
        .bInterfaceClass = HID_CLASS, \
 | 
			
		||||
        .bInterfaceSubClass = HID_SUB_CLASS_BOOT, \
 | 
			
		||||
        .bInterfaceProtocol = HID_PROTOCOL_KEYBOARD, \
 | 
			
		||||
        .iInterface = UDI_HID_KBD_STRING_ID, \
 | 
			
		||||
    }, \
 | 
			
		||||
    .hid = { \
 | 
			
		||||
        .bLength = sizeof(usb_hid_descriptor_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_HID, \
 | 
			
		||||
        .bcdHID = LE16(USB_HID_BDC_V1_11), \
 | 
			
		||||
        .bCountryCode = USB_HID_NO_COUNTRY_CODE, \
 | 
			
		||||
        .bNumDescriptors = USB_HID_NUM_DESC, \
 | 
			
		||||
        .bRDescriptorType = USB_DT_HID_REPORT, \
 | 
			
		||||
        .wDescriptorLength = LE16(sizeof(udi_hid_kbd_report_desc_t)), \
 | 
			
		||||
    }, \
 | 
			
		||||
    .ep = { \
 | 
			
		||||
        .bLength = sizeof(usb_ep_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_ENDPOINT, \
 | 
			
		||||
        .bEndpointAddress = UDI_HID_KBD_EP_IN | USB_EP_DIR_IN, \
 | 
			
		||||
        .bmAttributes = USB_EP_TYPE_INTERRUPT, \
 | 
			
		||||
        .wMaxPacketSize = LE16(UDI_HID_KBD_EP_SIZE), \
 | 
			
		||||
        .bInterval = KBD_POLLING_INTERVAL \
 | 
			
		||||
    } \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// clang-format on
 | 
			
		||||
 | 
			
		||||
// set report buffer (from host)
 | 
			
		||||
extern uint8_t udi_hid_kbd_report_set;
 | 
			
		||||
 | 
			
		||||
// report buffer (to host)
 | 
			
		||||
#define UDI_HID_KBD_REPORT_SIZE 8
 | 
			
		||||
extern uint8_t udi_hid_kbd_report[UDI_HID_KBD_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
COMPILER_PACK_RESET()
 | 
			
		||||
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
// EXK Descriptor structure and content
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
#ifdef EXTRAKEY_ENABLE
 | 
			
		||||
 | 
			
		||||
COMPILER_PACK_SET(1)
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    usb_iface_desc_t     iface;
 | 
			
		||||
    usb_hid_descriptor_t hid;
 | 
			
		||||
    usb_ep_desc_t        ep;
 | 
			
		||||
} udi_hid_exk_desc_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t array[50];
 | 
			
		||||
} udi_hid_exk_report_desc_t;
 | 
			
		||||
 | 
			
		||||
// clang-format off
 | 
			
		||||
 | 
			
		||||
#    define UDI_HID_EXK_DESC { \
 | 
			
		||||
    .iface = { \
 | 
			
		||||
        .bLength = sizeof(usb_iface_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_INTERFACE, \
 | 
			
		||||
        .bInterfaceNumber = UDI_HID_EXK_IFACE_NUMBER, \
 | 
			
		||||
        .bAlternateSetting = 0, \
 | 
			
		||||
        .bNumEndpoints = 1, \
 | 
			
		||||
        .bInterfaceClass = HID_CLASS, \
 | 
			
		||||
        .bInterfaceSubClass = HID_SUB_CLASS_BOOT, \
 | 
			
		||||
        .bInterfaceProtocol = HID_PROTOCOL_GENERIC, \
 | 
			
		||||
        .iInterface = UDI_HID_EXK_STRING_ID \
 | 
			
		||||
    }, \
 | 
			
		||||
    .hid = { \
 | 
			
		||||
        .bLength = sizeof(usb_hid_descriptor_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_HID, \
 | 
			
		||||
        .bcdHID = LE16(USB_HID_BDC_V1_11), \
 | 
			
		||||
        .bCountryCode = USB_HID_NO_COUNTRY_CODE, \
 | 
			
		||||
        .bNumDescriptors = USB_HID_NUM_DESC, \
 | 
			
		||||
        .bRDescriptorType = USB_DT_HID_REPORT, \
 | 
			
		||||
        .wDescriptorLength = LE16(sizeof(udi_hid_exk_report_desc_t)) \
 | 
			
		||||
    }, \
 | 
			
		||||
    .ep = { \
 | 
			
		||||
        .bLength = sizeof(usb_ep_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_ENDPOINT, \
 | 
			
		||||
        .bEndpointAddress = UDI_HID_EXK_EP_IN | USB_EP_DIR_IN, \
 | 
			
		||||
        .bmAttributes = USB_EP_TYPE_INTERRUPT, \
 | 
			
		||||
        .wMaxPacketSize = LE16(UDI_HID_EXK_EP_SIZE), \
 | 
			
		||||
        .bInterval = EXTRAKEY_POLLING_INTERVAL \
 | 
			
		||||
    } \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// clang-format on
 | 
			
		||||
 | 
			
		||||
// report buffer
 | 
			
		||||
#    define UDI_HID_EXK_REPORT_SIZE 3
 | 
			
		||||
extern uint8_t udi_hid_exk_report[UDI_HID_EXK_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
COMPILER_PACK_RESET()
 | 
			
		||||
 | 
			
		||||
#endif // EXTRAKEY_ENABLE
 | 
			
		||||
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
// NKRO Descriptor structure and content
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
#ifdef NKRO_ENABLE
 | 
			
		||||
 | 
			
		||||
COMPILER_PACK_SET(1)
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    usb_iface_desc_t     iface;
 | 
			
		||||
    usb_hid_descriptor_t hid;
 | 
			
		||||
    usb_ep_desc_t        ep;
 | 
			
		||||
} udi_hid_nkro_desc_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t array[57];
 | 
			
		||||
} udi_hid_nkro_report_desc_t;
 | 
			
		||||
 | 
			
		||||
// clang-format off
 | 
			
		||||
 | 
			
		||||
#    define UDI_HID_NKRO_DESC { \
 | 
			
		||||
    .iface = { \
 | 
			
		||||
        .bLength = sizeof(usb_iface_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_INTERFACE, \
 | 
			
		||||
        .bInterfaceNumber = UDI_HID_NKRO_IFACE_NUMBER, \
 | 
			
		||||
        .bAlternateSetting = 0, \
 | 
			
		||||
        .bNumEndpoints = 1, \
 | 
			
		||||
        .bInterfaceClass = HID_CLASS, \
 | 
			
		||||
        .bInterfaceSubClass = HID_SUB_CLASS_NOBOOT, \
 | 
			
		||||
        .bInterfaceProtocol = HID_PROTOCOL_KEYBOARD, \
 | 
			
		||||
        .iInterface = UDI_HID_NKRO_STRING_ID \
 | 
			
		||||
    }, \
 | 
			
		||||
    .hid = { \
 | 
			
		||||
        .bLength = sizeof(usb_hid_descriptor_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_HID, \
 | 
			
		||||
        .bcdHID = LE16(USB_HID_BDC_V1_11), \
 | 
			
		||||
        .bCountryCode = USB_HID_NO_COUNTRY_CODE, \
 | 
			
		||||
        .bNumDescriptors = USB_HID_NUM_DESC, \
 | 
			
		||||
        .bRDescriptorType = USB_DT_HID_REPORT, \
 | 
			
		||||
        .wDescriptorLength = LE16(sizeof(udi_hid_nkro_report_desc_t)) \
 | 
			
		||||
    }, \
 | 
			
		||||
    .ep = { \
 | 
			
		||||
        .bLength = sizeof(usb_ep_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_ENDPOINT, \
 | 
			
		||||
        .bEndpointAddress = UDI_HID_NKRO_EP_IN | USB_EP_DIR_IN, \
 | 
			
		||||
        .bmAttributes = USB_EP_TYPE_INTERRUPT, \
 | 
			
		||||
        .wMaxPacketSize = LE16(UDI_HID_NKRO_EP_SIZE), \
 | 
			
		||||
        .bInterval = NKRO_POLLING_INTERVAL \
 | 
			
		||||
    } \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// clang-format on
 | 
			
		||||
 | 
			
		||||
// set report buffer
 | 
			
		||||
extern uint8_t udi_hid_nkro_report_set;
 | 
			
		||||
 | 
			
		||||
// report buffer
 | 
			
		||||
#    define UDI_HID_NKRO_REPORT_SIZE 32
 | 
			
		||||
extern uint8_t udi_hid_nkro_report[UDI_HID_NKRO_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
COMPILER_PACK_RESET()
 | 
			
		||||
 | 
			
		||||
#endif // NKRO_ENABLE
 | 
			
		||||
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
// MOU Descriptor structure and content
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
#ifdef MOUSE_ENABLE
 | 
			
		||||
 | 
			
		||||
COMPILER_PACK_SET(1)
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    usb_iface_desc_t     iface;
 | 
			
		||||
    usb_hid_descriptor_t hid;
 | 
			
		||||
    usb_ep_desc_t        ep;
 | 
			
		||||
} udi_hid_mou_desc_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t array[77]; // MOU PDS
 | 
			
		||||
} udi_hid_mou_report_desc_t;
 | 
			
		||||
 | 
			
		||||
// clang-format off
 | 
			
		||||
 | 
			
		||||
#    define UDI_HID_MOU_DESC { \
 | 
			
		||||
    .iface = { \
 | 
			
		||||
        .bLength = sizeof(usb_iface_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_INTERFACE, \
 | 
			
		||||
        .bInterfaceNumber = MOUSE_INTERFACE, \
 | 
			
		||||
        .bAlternateSetting = 0, \
 | 
			
		||||
        .bNumEndpoints = 1, \
 | 
			
		||||
        .bInterfaceClass = HID_CLASS, \
 | 
			
		||||
        .bInterfaceSubClass = HID_SUB_CLASS_BOOT, \
 | 
			
		||||
        .bInterfaceProtocol = HID_PROTOCOL_MOUSE, \
 | 
			
		||||
        .iInterface = UDI_HID_MOU_STRING_ID \
 | 
			
		||||
    }, \
 | 
			
		||||
    .hid = { \
 | 
			
		||||
        .bLength = sizeof(usb_hid_descriptor_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_HID, \
 | 
			
		||||
        .bcdHID = LE16(USB_HID_BDC_V1_11), \
 | 
			
		||||
        .bCountryCode = USB_HID_NO_COUNTRY_CODE, \
 | 
			
		||||
        .bNumDescriptors = USB_HID_NUM_DESC, \
 | 
			
		||||
        .bRDescriptorType = USB_DT_HID_REPORT, \
 | 
			
		||||
        .wDescriptorLength = LE16(sizeof(udi_hid_mou_report_desc_t)) \
 | 
			
		||||
    }, \
 | 
			
		||||
    .ep = { \
 | 
			
		||||
        .bLength = sizeof(usb_ep_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_ENDPOINT, \
 | 
			
		||||
        .bEndpointAddress = UDI_HID_MOU_EP_IN | USB_EP_DIR_IN, \
 | 
			
		||||
        .bmAttributes = USB_EP_TYPE_INTERRUPT, \
 | 
			
		||||
        .wMaxPacketSize = LE16(UDI_HID_MOU_EP_SIZE), \
 | 
			
		||||
        .bInterval = MOU_POLLING_INTERVAL \
 | 
			
		||||
    } \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// clang-format on
 | 
			
		||||
 | 
			
		||||
// report buffer
 | 
			
		||||
#    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
 | 
			
		||||
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
// RAW Descriptor structure and content
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
#ifdef RAW_ENABLE
 | 
			
		||||
 | 
			
		||||
COMPILER_PACK_SET(1)
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    usb_iface_desc_t     iface;
 | 
			
		||||
    usb_hid_descriptor_t hid;
 | 
			
		||||
    usb_ep_desc_t        ep_out;
 | 
			
		||||
    usb_ep_desc_t        ep_in;
 | 
			
		||||
} udi_hid_raw_desc_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t array[26];
 | 
			
		||||
} udi_hid_raw_report_desc_t;
 | 
			
		||||
 | 
			
		||||
// clang-format off
 | 
			
		||||
 | 
			
		||||
#    define UDI_HID_RAW_DESC { \
 | 
			
		||||
    .iface = { \
 | 
			
		||||
        .bLength = sizeof(usb_iface_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_INTERFACE, \
 | 
			
		||||
        .bInterfaceNumber = RAW_INTERFACE, \
 | 
			
		||||
        .bAlternateSetting = 0, \
 | 
			
		||||
        .bNumEndpoints = 2, \
 | 
			
		||||
        .bInterfaceClass = HID_CLASS, \
 | 
			
		||||
        .bInterfaceSubClass = HID_SUB_CLASS_NOBOOT, \
 | 
			
		||||
        .bInterfaceProtocol = HID_SUB_CLASS_NOBOOT, \
 | 
			
		||||
        .iInterface = UDI_HID_RAW_STRING_ID \
 | 
			
		||||
    }, \
 | 
			
		||||
    .hid = { \
 | 
			
		||||
        .bLength = sizeof(usb_hid_descriptor_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_HID, \
 | 
			
		||||
        .bcdHID = LE16(USB_HID_BDC_V1_11), \
 | 
			
		||||
        .bCountryCode = USB_HID_NO_COUNTRY_CODE, \
 | 
			
		||||
        .bNumDescriptors = USB_HID_NUM_DESC, \
 | 
			
		||||
        .bRDescriptorType = USB_DT_HID_REPORT, \
 | 
			
		||||
        .wDescriptorLength = LE16(sizeof(udi_hid_raw_report_desc_t)) \
 | 
			
		||||
    }, \
 | 
			
		||||
    .ep_out = { \
 | 
			
		||||
        .bLength = sizeof(usb_ep_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_ENDPOINT, \
 | 
			
		||||
        .bEndpointAddress = UDI_HID_RAW_EP_OUT | USB_EP_DIR_OUT, \
 | 
			
		||||
        .bmAttributes = USB_EP_TYPE_INTERRUPT, \
 | 
			
		||||
        .wMaxPacketSize = LE16(RAW_EPSIZE), \
 | 
			
		||||
        .bInterval = RAW_POLLING_INTERVAL \
 | 
			
		||||
    }, \
 | 
			
		||||
    .ep_in = { \
 | 
			
		||||
        .bLength = sizeof(usb_ep_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_ENDPOINT, \
 | 
			
		||||
        .bEndpointAddress = UDI_HID_RAW_EP_IN | USB_EP_DIR_IN, \
 | 
			
		||||
        .bmAttributes = USB_EP_TYPE_INTERRUPT, \
 | 
			
		||||
        .wMaxPacketSize = LE16(RAW_EPSIZE), \
 | 
			
		||||
        .bInterval = RAW_POLLING_INTERVAL \
 | 
			
		||||
    } \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// clang-format on
 | 
			
		||||
 | 
			
		||||
#    define UDI_HID_RAW_REPORT_SIZE RAW_EPSIZE
 | 
			
		||||
 | 
			
		||||
extern uint8_t udi_hid_raw_report_set[UDI_HID_RAW_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
// report buffer
 | 
			
		||||
extern uint8_t udi_hid_raw_report[UDI_HID_RAW_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
COMPILER_PACK_RESET()
 | 
			
		||||
 | 
			
		||||
#endif // RAW_ENABLE
 | 
			
		||||
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
// CON Descriptor structure and content
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
 | 
			
		||||
COMPILER_PACK_SET(1)
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    usb_iface_desc_t     iface;
 | 
			
		||||
    usb_hid_descriptor_t hid;
 | 
			
		||||
    usb_ep_desc_t        ep_out;
 | 
			
		||||
    usb_ep_desc_t        ep_in;
 | 
			
		||||
} udi_hid_con_desc_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t array[34];
 | 
			
		||||
} udi_hid_con_report_desc_t;
 | 
			
		||||
 | 
			
		||||
// clang-format off
 | 
			
		||||
 | 
			
		||||
#    define UDI_HID_CON_DESC { \
 | 
			
		||||
    .iface = { \
 | 
			
		||||
        .bLength = sizeof(usb_iface_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_INTERFACE, \
 | 
			
		||||
        .bInterfaceNumber = UDI_HID_CON_IFACE_NUMBER, \
 | 
			
		||||
        .bAlternateSetting = 0, \
 | 
			
		||||
        .bNumEndpoints = 2, \
 | 
			
		||||
        .bInterfaceClass = HID_CLASS, \
 | 
			
		||||
        .bInterfaceSubClass = HID_SUB_CLASS_NOBOOT, \
 | 
			
		||||
        .bInterfaceProtocol = HID_SUB_CLASS_NOBOOT, \
 | 
			
		||||
        .iInterface = UDI_HID_CON_STRING_ID \
 | 
			
		||||
    }, \
 | 
			
		||||
    .hid = { \
 | 
			
		||||
        .bLength = sizeof(usb_hid_descriptor_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_HID, \
 | 
			
		||||
        .bcdHID = LE16(USB_HID_BDC_V1_11), \
 | 
			
		||||
        .bCountryCode = USB_HID_NO_COUNTRY_CODE, \
 | 
			
		||||
        .bNumDescriptors = USB_HID_NUM_DESC, \
 | 
			
		||||
        .bRDescriptorType = USB_DT_HID_REPORT, \
 | 
			
		||||
        .wDescriptorLength = LE16(sizeof(udi_hid_con_report_desc_t)) \
 | 
			
		||||
    }, \
 | 
			
		||||
    .ep_out = { \
 | 
			
		||||
        .bLength = sizeof(usb_ep_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_ENDPOINT, \
 | 
			
		||||
        .bEndpointAddress = UDI_HID_CON_EP_OUT | USB_EP_DIR_OUT, \
 | 
			
		||||
        .bmAttributes = USB_EP_TYPE_INTERRUPT, \
 | 
			
		||||
        .wMaxPacketSize = LE16(CONSOLE_EPSIZE), \
 | 
			
		||||
        .bInterval = CON_POLLING_INTERVAL \
 | 
			
		||||
    }, \
 | 
			
		||||
    .ep_in = { \
 | 
			
		||||
        .bLength = sizeof(usb_ep_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_ENDPOINT, \
 | 
			
		||||
        .bEndpointAddress = UDI_HID_CON_EP_IN | USB_EP_DIR_IN, \
 | 
			
		||||
        .bmAttributes = USB_EP_TYPE_INTERRUPT, \
 | 
			
		||||
        .wMaxPacketSize = LE16(CONSOLE_EPSIZE), \
 | 
			
		||||
        .bInterval = CON_POLLING_INTERVAL \
 | 
			
		||||
    } \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// clang-format on
 | 
			
		||||
 | 
			
		||||
#    define UDI_HID_CON_REPORT_SIZE CONSOLE_EPSIZE
 | 
			
		||||
 | 
			
		||||
extern uint8_t udi_hid_con_report_set[UDI_HID_CON_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
// report buffer
 | 
			
		||||
extern uint8_t udi_hid_con_report[UDI_HID_CON_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
COMPILER_PACK_RESET()
 | 
			
		||||
 | 
			
		||||
#endif // CONSOLE_ENABLE
 | 
			
		||||
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
// CDC Descriptor structure and content
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
#ifdef VIRTSER_ENABLE
 | 
			
		||||
 | 
			
		||||
COMPILER_PACK_SET(1)
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t bFunctionLength;
 | 
			
		||||
    uint8_t bDescriptorType;
 | 
			
		||||
    uint8_t bDescriptorSubtype;
 | 
			
		||||
    le16_t  bcdCDC;
 | 
			
		||||
} usb_cdc_hdr_desc_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t bFunctionLength;
 | 
			
		||||
    uint8_t bDescriptorType;
 | 
			
		||||
    uint8_t bDescriptorSubtype;
 | 
			
		||||
    uint8_t bmCapabilities;
 | 
			
		||||
    uint8_t bDataInterface;
 | 
			
		||||
} usb_cdc_call_mgmt_desc_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t bFunctionLength;
 | 
			
		||||
    uint8_t bDescriptorType;
 | 
			
		||||
    uint8_t bDescriptorSubtype;
 | 
			
		||||
    uint8_t bmCapabilities;
 | 
			
		||||
} usb_cdc_acm_desc_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t bFunctionLength;
 | 
			
		||||
    uint8_t bDescriptorType;
 | 
			
		||||
    uint8_t bDescriptorSubtype;
 | 
			
		||||
    uint8_t bMasterInterface;
 | 
			
		||||
    uint8_t bSlaveInterface0;
 | 
			
		||||
} usb_cdc_union_desc_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    usb_association_desc_t   iaface;
 | 
			
		||||
    usb_iface_desc_t         iface_c;
 | 
			
		||||
    usb_cdc_hdr_desc_t       fd;
 | 
			
		||||
    usb_cdc_call_mgmt_desc_t mfd;
 | 
			
		||||
    usb_cdc_acm_desc_t       acmd;
 | 
			
		||||
    usb_cdc_union_desc_t     ufd;
 | 
			
		||||
    usb_ep_desc_t            ep_c;
 | 
			
		||||
    usb_iface_desc_t         iface_d;
 | 
			
		||||
    usb_ep_desc_t            ep_tx;
 | 
			
		||||
    usb_ep_desc_t            ep_rx;
 | 
			
		||||
} udi_cdc_desc_t;
 | 
			
		||||
 | 
			
		||||
// clang-format off
 | 
			
		||||
 | 
			
		||||
#    define CDC_DESCRIPTOR { \
 | 
			
		||||
    .iaface = { \
 | 
			
		||||
        .bLength = sizeof(usb_association_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_IAD, \
 | 
			
		||||
        .bFirstInterface = CDC_STATUS_INTERFACE, \
 | 
			
		||||
        .bInterfaceCount = 2, \
 | 
			
		||||
        .bFunctionClass = CDC_CLASS_DEVICE, \
 | 
			
		||||
        .bFunctionSubClass = CDC_SUBCLASS_ACM, \
 | 
			
		||||
        .bFunctionProtocol = CDC_PROTOCOL_V25TER, \
 | 
			
		||||
        .iFunction = 0 \
 | 
			
		||||
    }, \
 | 
			
		||||
    .iface_c = { \
 | 
			
		||||
        .bLength = sizeof(usb_iface_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_INTERFACE, \
 | 
			
		||||
        .bInterfaceNumber = CDC_STATUS_INTERFACE, \
 | 
			
		||||
        .bAlternateSetting = 0, \
 | 
			
		||||
        .bNumEndpoints = 1, \
 | 
			
		||||
        .bInterfaceClass = 0x02, \
 | 
			
		||||
        .bInterfaceSubClass = 0x02, \
 | 
			
		||||
        .bInterfaceProtocol = CDC_PROTOCOL_V25TER, \
 | 
			
		||||
        .iInterface = 0 \
 | 
			
		||||
    }, \
 | 
			
		||||
    .fd = { \
 | 
			
		||||
        .bFunctionLength = sizeof(usb_cdc_hdr_desc_t), \
 | 
			
		||||
        .bDescriptorType = CDC_CS_INTERFACE, \
 | 
			
		||||
        .bDescriptorSubtype = CDC_SCS_HEADER, \
 | 
			
		||||
        .bcdCDC = 0x0110 \
 | 
			
		||||
    }, \
 | 
			
		||||
    .mfd = { \
 | 
			
		||||
        .bFunctionLength = sizeof(usb_cdc_call_mgmt_desc_t), \
 | 
			
		||||
        .bDescriptorType = CDC_CS_INTERFACE, \
 | 
			
		||||
        .bDescriptorSubtype = CDC_SCS_CALL_MGMT, \
 | 
			
		||||
        .bmCapabilities = CDC_CALL_MGMT_SUPPORTED, \
 | 
			
		||||
        .bDataInterface = CDC_DATA_INTERFACE \
 | 
			
		||||
    }, \
 | 
			
		||||
    .acmd = { \
 | 
			
		||||
        .bFunctionLength = sizeof(usb_cdc_acm_desc_t), \
 | 
			
		||||
        .bDescriptorType = CDC_CS_INTERFACE, \
 | 
			
		||||
        .bDescriptorSubtype = CDC_SCS_ACM, \
 | 
			
		||||
        .bmCapabilities = CDC_ACM_SUPPORT_LINE_REQUESTS \
 | 
			
		||||
    }, \
 | 
			
		||||
    .ufd = { \
 | 
			
		||||
        .bFunctionLength = sizeof(usb_cdc_union_desc_t), \
 | 
			
		||||
        .bDescriptorType = CDC_CS_INTERFACE, \
 | 
			
		||||
        .bDescriptorSubtype = CDC_SCS_UNION, \
 | 
			
		||||
        .bMasterInterface = CDC_STATUS_INTERFACE, \
 | 
			
		||||
        .bSlaveInterface0 = CDC_DATA_INTERFACE \
 | 
			
		||||
    }, \
 | 
			
		||||
    .ep_c = { \
 | 
			
		||||
        .bLength = sizeof(usb_ep_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_ENDPOINT, \
 | 
			
		||||
        .bEndpointAddress = CDC_ACM_ENDPOINT | USB_EP_DIR_IN, \
 | 
			
		||||
        .bmAttributes = USB_EP_TYPE_INTERRUPT, \
 | 
			
		||||
        .wMaxPacketSize = LE16(CDC_ACM_SIZE), \
 | 
			
		||||
        .bInterval = CDC_EP_INTERVAL_STATUS \
 | 
			
		||||
    }, \
 | 
			
		||||
    .iface_d = { \
 | 
			
		||||
        .bLength = sizeof(usb_iface_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_INTERFACE, \
 | 
			
		||||
        .bInterfaceNumber = CDC_DATA_INTERFACE, \
 | 
			
		||||
        .bAlternateSetting = 0, \
 | 
			
		||||
        .bNumEndpoints = 2, \
 | 
			
		||||
        .bInterfaceClass = CDC_CLASS_DATA, \
 | 
			
		||||
        .bInterfaceSubClass = 0, \
 | 
			
		||||
        .bInterfaceProtocol = 0, \
 | 
			
		||||
        .iInterface = 0 \
 | 
			
		||||
    }, \
 | 
			
		||||
    .ep_rx = { \
 | 
			
		||||
        .bLength = sizeof(usb_ep_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_ENDPOINT, \
 | 
			
		||||
        .bEndpointAddress = CDC_RX_ENDPOINT | USB_EP_DIR_OUT, \
 | 
			
		||||
        .bmAttributes = USB_EP_TYPE_BULK, \
 | 
			
		||||
        .wMaxPacketSize = LE16(CDC_RX_SIZE), \
 | 
			
		||||
        .bInterval = CDC_EP_INTERVAL_DATA \
 | 
			
		||||
    }, \
 | 
			
		||||
    .ep_tx = { \
 | 
			
		||||
        .bLength = sizeof(usb_ep_desc_t), \
 | 
			
		||||
        .bDescriptorType = USB_DT_ENDPOINT, \
 | 
			
		||||
        .bEndpointAddress = CDC_TX_ENDPOINT | USB_EP_DIR_IN, \
 | 
			
		||||
        .bmAttributes = USB_EP_TYPE_BULK, \
 | 
			
		||||
        .wMaxPacketSize = LE16(CDC_TX_SIZE), \
 | 
			
		||||
        .bInterval = CDC_EP_INTERVAL_DATA \
 | 
			
		||||
    } \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// clang-format on
 | 
			
		||||
 | 
			
		||||
COMPILER_PACK_RESET()
 | 
			
		||||
 | 
			
		||||
#endif // VIRTSER_ENABLE
 | 
			
		||||
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
// CONFIGURATION Descriptor structure and content
 | 
			
		||||
// **********************************************************************
 | 
			
		||||
COMPILER_PACK_SET(1)
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    usb_conf_desc_t    conf;
 | 
			
		||||
    udi_hid_kbd_desc_t hid_kbd;
 | 
			
		||||
#ifdef MOUSE_ENABLE
 | 
			
		||||
    udi_hid_mou_desc_t hid_mou;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef EXTRAKEY_ENABLE
 | 
			
		||||
    udi_hid_exk_desc_t hid_exk;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef RAW_ENABLE
 | 
			
		||||
    udi_hid_raw_desc_t hid_raw;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
    udi_hid_con_desc_t hid_con;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef NKRO_ENABLE
 | 
			
		||||
    udi_hid_nkro_desc_t hid_nkro;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
    udi_hid_midi_desc_t hid_midi;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef VIRTSER_ENABLE
 | 
			
		||||
    udi_cdc_desc_t cdc_serial;
 | 
			
		||||
#endif
 | 
			
		||||
} udc_desc_t;
 | 
			
		||||
 | 
			
		||||
COMPILER_PACK_RESET()
 | 
			
		||||
 | 
			
		||||
#endif //_UDI_DEVICE_CONF_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,31 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _UDI_DEVICE_EPSIZE_H_
 | 
			
		||||
#define _UDI_DEVICE_EPSIZE_H_
 | 
			
		||||
 | 
			
		||||
#define KEYBOARD_EPSIZE 8
 | 
			
		||||
#define MOUSE_EPSIZE 16
 | 
			
		||||
#define EXTRAKEY_EPSIZE 8
 | 
			
		||||
#define RAW_EPSIZE 32
 | 
			
		||||
#define CONSOLE_EPSIZE 32
 | 
			
		||||
#define NKRO_EPSIZE 32
 | 
			
		||||
#define MIDI_STREAM_EPSIZE 64
 | 
			
		||||
#define CDC_NOTIFICATION_EPSIZE 8
 | 
			
		||||
#define CDC_EPSIZE 16
 | 
			
		||||
 | 
			
		||||
#endif //_UDI_DEVICE_EPSIZE_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,148 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief USB Device Human Interface Device (HID) interface.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "conf_usb.h"
 | 
			
		||||
#include "usb_protocol.h"
 | 
			
		||||
#include "udd.h"
 | 
			
		||||
#include "udc.h"
 | 
			
		||||
#include "udi_hid.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \ingroup udi_hid_group
 | 
			
		||||
 * \defgroup udi_hid_group_internal Implementation of HID common library
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Send the specific descriptors requested by SETUP request
 | 
			
		||||
 *
 | 
			
		||||
 * \retval true if the descriptor is supported
 | 
			
		||||
 */
 | 
			
		||||
static bool udi_hid_reqstdifaceget_descriptor(uint8_t *report_desc);
 | 
			
		||||
 | 
			
		||||
bool udi_hid_setup(uint8_t *rate, uint8_t *protocol, uint8_t *report_desc, bool (*setup_report)(void)) {
 | 
			
		||||
    if (Udd_setup_is_in()) {
 | 
			
		||||
        // Requests Interface GET
 | 
			
		||||
        if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) {
 | 
			
		||||
            // Requests Standard Interface Get
 | 
			
		||||
            switch (udd_g_ctrlreq.req.bRequest) {
 | 
			
		||||
                case USB_REQ_GET_DESCRIPTOR:
 | 
			
		||||
                    return udi_hid_reqstdifaceget_descriptor(report_desc);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (Udd_setup_type() == USB_REQ_TYPE_CLASS) {
 | 
			
		||||
            // Requests Class Interface Get
 | 
			
		||||
            switch (udd_g_ctrlreq.req.bRequest) {
 | 
			
		||||
                case USB_REQ_HID_GET_REPORT:
 | 
			
		||||
                    return setup_report();
 | 
			
		||||
 | 
			
		||||
                case USB_REQ_HID_GET_IDLE:
 | 
			
		||||
                    udd_g_ctrlreq.payload      = rate;
 | 
			
		||||
                    udd_g_ctrlreq.payload_size = 1;
 | 
			
		||||
                    return true;
 | 
			
		||||
 | 
			
		||||
                case USB_REQ_HID_GET_PROTOCOL:
 | 
			
		||||
                    udd_g_ctrlreq.payload      = protocol;
 | 
			
		||||
                    udd_g_ctrlreq.payload_size = 1;
 | 
			
		||||
                    return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (Udd_setup_is_out()) {
 | 
			
		||||
        // Requests Interface SET
 | 
			
		||||
        if (Udd_setup_type() == USB_REQ_TYPE_CLASS) {
 | 
			
		||||
            // Requests Class Interface Set
 | 
			
		||||
            switch (udd_g_ctrlreq.req.bRequest) {
 | 
			
		||||
                case USB_REQ_HID_SET_REPORT:
 | 
			
		||||
                    return setup_report();
 | 
			
		||||
 | 
			
		||||
                case USB_REQ_HID_SET_IDLE:
 | 
			
		||||
                    *rate = udd_g_ctrlreq.req.wValue >> 8;
 | 
			
		||||
                    return true;
 | 
			
		||||
 | 
			
		||||
                case USB_REQ_HID_SET_PROTOCOL:
 | 
			
		||||
                    if (0 != udd_g_ctrlreq.req.wLength) return false;
 | 
			
		||||
                    *protocol = udd_g_ctrlreq.req.wValue;
 | 
			
		||||
                    return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return false; // Request not supported
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//---------------------------------------------
 | 
			
		||||
//------- Internal routines
 | 
			
		||||
 | 
			
		||||
static bool udi_hid_reqstdifaceget_descriptor(uint8_t *report_desc) {
 | 
			
		||||
    usb_hid_descriptor_t UDC_DESC_STORAGE *ptr_hid_desc;
 | 
			
		||||
 | 
			
		||||
    // Get the USB descriptor which is located after the interface descriptor
 | 
			
		||||
    // This descriptor must be the HID descriptor
 | 
			
		||||
    ptr_hid_desc = (usb_hid_descriptor_t UDC_DESC_STORAGE *)((uint8_t *)udc_get_interface_desc() + sizeof(usb_iface_desc_t));
 | 
			
		||||
    if (USB_DT_HID != ptr_hid_desc->bDescriptorType) return false;
 | 
			
		||||
 | 
			
		||||
    // The SETUP request can ask for:
 | 
			
		||||
    // - an USB_DT_HID descriptor
 | 
			
		||||
    // - or USB_DT_HID_REPORT descriptor
 | 
			
		||||
    // - or USB_DT_HID_PHYSICAL descriptor
 | 
			
		||||
    if (USB_DT_HID == (uint8_t)(udd_g_ctrlreq.req.wValue >> 8)) {
 | 
			
		||||
        // USB_DT_HID descriptor requested then send it
 | 
			
		||||
        udd_g_ctrlreq.payload      = (uint8_t *)ptr_hid_desc;
 | 
			
		||||
        udd_g_ctrlreq.payload_size = min(udd_g_ctrlreq.req.wLength, ptr_hid_desc->bLength);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    // The HID_X descriptor requested must correspond to report type
 | 
			
		||||
    // included in the HID descriptor
 | 
			
		||||
    if (ptr_hid_desc->bRDescriptorType == (uint8_t)(udd_g_ctrlreq.req.wValue >> 8)) {
 | 
			
		||||
        // Send HID Report descriptor given by high level
 | 
			
		||||
        udd_g_ctrlreq.payload      = report_desc;
 | 
			
		||||
        udd_g_ctrlreq.payload_size = min(udd_g_ctrlreq.req.wLength, le16_to_cpu(ptr_hid_desc->wDescriptorLength));
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//@}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,85 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief USB Device Human Interface Device (HID) interface definitions.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _UDI_HID_H_
 | 
			
		||||
#define _UDI_HID_H_
 | 
			
		||||
 | 
			
		||||
#include "conf_usb.h"
 | 
			
		||||
#include "usb_protocol.h"
 | 
			
		||||
#include "usb_protocol_hid.h"
 | 
			
		||||
#include "udd.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \ingroup udi_group
 | 
			
		||||
 * \defgroup udi_hid_group USB Device Interface (UDI) for Human Interface Device (HID)
 | 
			
		||||
 *
 | 
			
		||||
 * Common library for all Human Interface Device (HID) implementation.
 | 
			
		||||
 *
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Decode HID setup request
 | 
			
		||||
 *
 | 
			
		||||
 * \param rate         Pointer on rate of current HID interface
 | 
			
		||||
 * \param protocol     Pointer on protocol of current HID interface
 | 
			
		||||
 * \param report_desc  Pointer on report descriptor of current HID interface
 | 
			
		||||
 * \param set_report   Pointer on set_report callback of current HID interface
 | 
			
		||||
 *
 | 
			
		||||
 * \return \c 1 if function was successfully done, otherwise \c 0.
 | 
			
		||||
 */
 | 
			
		||||
bool udi_hid_setup(uint8_t *rate, uint8_t *protocol, uint8_t *report_desc, bool (*setup_report)(void));
 | 
			
		||||
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif // _UDI_HID_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,861 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief USB Device Human Interface Device (HID) keyboard interface.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "samd51j18a.h"
 | 
			
		||||
#include "d51_util.h"
 | 
			
		||||
#include "conf_usb.h"
 | 
			
		||||
#include "usb_protocol.h"
 | 
			
		||||
#include "udd.h"
 | 
			
		||||
#include "udc.h"
 | 
			
		||||
#include "udi_device_conf.h"
 | 
			
		||||
#include "udi_hid.h"
 | 
			
		||||
#include "udi_hid_kbd.h"
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "report.h"
 | 
			
		||||
#include "usb_descriptor_common.h"
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// KBD
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
bool    udi_hid_kbd_enable(void);
 | 
			
		||||
void    udi_hid_kbd_disable(void);
 | 
			
		||||
bool    udi_hid_kbd_setup(void);
 | 
			
		||||
uint8_t udi_hid_kbd_getsetting(void);
 | 
			
		||||
 | 
			
		||||
UDC_DESC_STORAGE udi_api_t udi_api_hid_kbd = {
 | 
			
		||||
    .enable     = (bool (*)(void))udi_hid_kbd_enable,
 | 
			
		||||
    .disable    = (void (*)(void))udi_hid_kbd_disable,
 | 
			
		||||
    .setup      = (bool (*)(void))udi_hid_kbd_setup,
 | 
			
		||||
    .getsetting = (uint8_t(*)(void))udi_hid_kbd_getsetting,
 | 
			
		||||
    .sof_notify = NULL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
static uint8_t udi_hid_kbd_rate;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
static uint8_t udi_hid_kbd_protocol;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
uint8_t udi_hid_kbd_report_set;
 | 
			
		||||
 | 
			
		||||
bool udi_hid_kbd_b_report_valid;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
uint8_t udi_hid_kbd_report[UDI_HID_KBD_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
volatile bool udi_hid_kbd_b_report_trans_ongoing;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
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)
 | 
			
		||||
    // 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)
 | 
			
		||||
    // Reserved (1 byte)
 | 
			
		||||
    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)
 | 
			
		||||
 | 
			
		||||
    // 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)
 | 
			
		||||
    // LED padding (3 bits)
 | 
			
		||||
    0x95, 0x03, //   Report Count (3)
 | 
			
		||||
    0x91, 0x01, //   Output (Constant)
 | 
			
		||||
    0xC0        // End Collection
 | 
			
		||||
}};
 | 
			
		||||
 | 
			
		||||
static bool udi_hid_kbd_setreport(void);
 | 
			
		||||
 | 
			
		||||
static void udi_hid_kbd_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
 | 
			
		||||
 | 
			
		||||
static void udi_hid_kbd_setreport_valid(void);
 | 
			
		||||
 | 
			
		||||
bool udi_hid_kbd_enable(void) {
 | 
			
		||||
    // Initialize internal values
 | 
			
		||||
    udi_hid_kbd_rate                   = 0;
 | 
			
		||||
    udi_hid_kbd_protocol               = 0;
 | 
			
		||||
    udi_hid_kbd_b_report_trans_ongoing = false;
 | 
			
		||||
    memset(udi_hid_kbd_report, 0, UDI_HID_KBD_REPORT_SIZE);
 | 
			
		||||
    udi_hid_kbd_b_report_valid = false;
 | 
			
		||||
    return UDI_HID_KBD_ENABLE_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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)) {
 | 
			
		||||
        // Report OUT type on report ID 0 from USB Host
 | 
			
		||||
        udd_g_ctrlreq.payload      = &udi_hid_kbd_report_set;
 | 
			
		||||
        udd_g_ctrlreq.callback     = udi_hid_kbd_setreport_valid;
 | 
			
		||||
        udd_g_ctrlreq.payload_size = 1;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool udi_hid_kbd_send_report(void) {
 | 
			
		||||
    if (!main_b_kbd_enable) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (udi_hid_kbd_b_report_trans_ongoing) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memcpy(udi_hid_kbd_report_trans, udi_hid_kbd_report, UDI_HID_KBD_REPORT_SIZE);
 | 
			
		||||
    udi_hid_kbd_b_report_valid         = false;
 | 
			
		||||
    udi_hid_kbd_b_report_trans_ongoing = udd_ep_run(UDI_HID_KBD_EP_IN | USB_EP_DIR_IN, false, udi_hid_kbd_report_trans, UDI_HID_KBD_REPORT_SIZE, udi_hid_kbd_report_sent);
 | 
			
		||||
 | 
			
		||||
    return udi_hid_kbd_b_report_trans_ongoing;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void udi_hid_kbd_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep) {
 | 
			
		||||
    UNUSED(status);
 | 
			
		||||
    UNUSED(nb_sent);
 | 
			
		||||
    UNUSED(ep);
 | 
			
		||||
    udi_hid_kbd_b_report_trans_ongoing = false;
 | 
			
		||||
    if (udi_hid_kbd_b_report_valid) {
 | 
			
		||||
        udi_hid_kbd_send_report();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void udi_hid_kbd_setreport_valid(void) {
 | 
			
		||||
    // UDI_HID_KBD_CHANGE_LED(udi_hid_kbd_report_set);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
// NKRO Keyboard
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
#ifdef NKRO_ENABLE
 | 
			
		||||
 | 
			
		||||
bool    udi_hid_nkro_enable(void);
 | 
			
		||||
void    udi_hid_nkro_disable(void);
 | 
			
		||||
bool    udi_hid_nkro_setup(void);
 | 
			
		||||
uint8_t udi_hid_nkro_getsetting(void);
 | 
			
		||||
 | 
			
		||||
UDC_DESC_STORAGE udi_api_t udi_api_hid_nkro = {
 | 
			
		||||
    .enable     = (bool (*)(void))udi_hid_nkro_enable,
 | 
			
		||||
    .disable    = (void (*)(void))udi_hid_nkro_disable,
 | 
			
		||||
    .setup      = (bool (*)(void))udi_hid_nkro_setup,
 | 
			
		||||
    .getsetting = (uint8_t(*)(void))udi_hid_nkro_getsetting,
 | 
			
		||||
    .sof_notify = NULL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
static uint8_t udi_hid_nkro_rate;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
static uint8_t udi_hid_nkro_protocol;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
uint8_t udi_hid_nkro_report_set;
 | 
			
		||||
 | 
			
		||||
bool udi_hid_nkro_b_report_valid;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
uint8_t udi_hid_nkro_report[UDI_HID_NKRO_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
volatile bool udi_hid_nkro_b_report_trans_ongoing;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
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)
 | 
			
		||||
 | 
			
		||||
    // 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)
 | 
			
		||||
    // 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)
 | 
			
		||||
 | 
			
		||||
    // 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)
 | 
			
		||||
    // LED padding (3 bits)
 | 
			
		||||
    0x95, 0x01, //   Report Count (1)
 | 
			
		||||
    0x75, 0x03, //   Report Size (3)
 | 
			
		||||
    0x91, 0x03, //   Output (Constant)
 | 
			
		||||
    0xC0        // End Collection
 | 
			
		||||
}};
 | 
			
		||||
 | 
			
		||||
static bool udi_hid_nkro_setreport(void);
 | 
			
		||||
static void udi_hid_nkro_setreport_valid(void);
 | 
			
		||||
static void udi_hid_nkro_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
 | 
			
		||||
 | 
			
		||||
bool udi_hid_nkro_enable(void) {
 | 
			
		||||
    // Initialize internal values
 | 
			
		||||
    udi_hid_nkro_rate                   = 0;
 | 
			
		||||
    udi_hid_nkro_protocol               = 0;
 | 
			
		||||
    udi_hid_nkro_b_report_trans_ongoing = false;
 | 
			
		||||
    memset(udi_hid_nkro_report, 0, UDI_HID_NKRO_REPORT_SIZE);
 | 
			
		||||
    udi_hid_nkro_b_report_valid = false;
 | 
			
		||||
    return UDI_HID_NKRO_ENABLE_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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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.payload_size = 1;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool udi_hid_nkro_send_report(void) {
 | 
			
		||||
    if (!main_b_nkro_enable) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (udi_hid_nkro_b_report_trans_ongoing) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memcpy(udi_hid_nkro_report_trans, udi_hid_nkro_report, UDI_HID_NKRO_REPORT_SIZE);
 | 
			
		||||
    udi_hid_nkro_b_report_valid         = false;
 | 
			
		||||
    udi_hid_nkro_b_report_trans_ongoing = udd_ep_run(UDI_HID_NKRO_EP_IN | USB_EP_DIR_IN, false, udi_hid_nkro_report_trans, UDI_HID_NKRO_REPORT_SIZE, udi_hid_nkro_report_sent);
 | 
			
		||||
 | 
			
		||||
    return udi_hid_nkro_b_report_trans_ongoing;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void udi_hid_nkro_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep) {
 | 
			
		||||
    UNUSED(status);
 | 
			
		||||
    UNUSED(nb_sent);
 | 
			
		||||
    UNUSED(ep);
 | 
			
		||||
    udi_hid_nkro_b_report_trans_ongoing = false;
 | 
			
		||||
    if (udi_hid_nkro_b_report_valid) {
 | 
			
		||||
        udi_hid_nkro_send_report();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void udi_hid_nkro_setreport_valid(void) {
 | 
			
		||||
    // UDI_HID_NKRO_CHANGE_LED(udi_hid_nkro_report_set);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // NKRO_ENABLE
 | 
			
		||||
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
// EXK (extra-keys) SYS-CTRL  Keyboard
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
#ifdef EXTRAKEY_ENABLE
 | 
			
		||||
 | 
			
		||||
bool    udi_hid_exk_enable(void);
 | 
			
		||||
void    udi_hid_exk_disable(void);
 | 
			
		||||
bool    udi_hid_exk_setup(void);
 | 
			
		||||
uint8_t udi_hid_exk_getsetting(void);
 | 
			
		||||
 | 
			
		||||
UDC_DESC_STORAGE udi_api_t udi_api_hid_exk = {
 | 
			
		||||
    .enable     = (bool (*)(void))udi_hid_exk_enable,
 | 
			
		||||
    .disable    = (void (*)(void))udi_hid_exk_disable,
 | 
			
		||||
    .setup      = (bool (*)(void))udi_hid_exk_setup,
 | 
			
		||||
    .getsetting = (uint8_t(*)(void))udi_hid_exk_getsetting,
 | 
			
		||||
    .sof_notify = NULL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
static uint8_t udi_hid_exk_rate;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
static uint8_t udi_hid_exk_protocol;
 | 
			
		||||
 | 
			
		||||
// COMPILER_WORD_ALIGNED
 | 
			
		||||
// uint8_t udi_hid_exk_report_set;
 | 
			
		||||
 | 
			
		||||
bool udi_hid_exk_b_report_valid;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
uint8_t udi_hid_exk_report[UDI_HID_EXK_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
static bool udi_hid_exk_b_report_trans_ongoing;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
static uint8_t udi_hid_exk_report_trans[UDI_HID_EXK_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
UDC_DESC_STORAGE udi_hid_exk_report_desc_t udi_hid_exk_report_desc = {{
 | 
			
		||||
    // clang-format off
 | 
			
		||||
    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
 | 
			
		||||
    //clang-format on
 | 
			
		||||
}};
 | 
			
		||||
 | 
			
		||||
static void udi_hid_exk_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
 | 
			
		||||
 | 
			
		||||
bool udi_hid_exk_enable(void) {
 | 
			
		||||
    // Initialize internal values
 | 
			
		||||
    udi_hid_exk_rate                   = 0;
 | 
			
		||||
    udi_hid_exk_protocol               = 0;
 | 
			
		||||
    udi_hid_exk_b_report_trans_ongoing = false;
 | 
			
		||||
    memset(udi_hid_exk_report, 0, UDI_HID_EXK_REPORT_SIZE);
 | 
			
		||||
    udi_hid_exk_b_report_valid = false;
 | 
			
		||||
    return UDI_HID_EXK_ENABLE_EXT();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udi_hid_exk_disable(void) { UDI_HID_EXK_DISABLE_EXT(); }
 | 
			
		||||
 | 
			
		||||
bool udi_hid_exk_setup(void) { return udi_hid_setup(&udi_hid_exk_rate, &udi_hid_exk_protocol, (uint8_t *)&udi_hid_exk_report_desc, NULL); }
 | 
			
		||||
 | 
			
		||||
uint8_t udi_hid_exk_getsetting(void) { return 0; }
 | 
			
		||||
 | 
			
		||||
bool udi_hid_exk_send_report(void) {
 | 
			
		||||
    if (!main_b_exk_enable) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (udi_hid_exk_b_report_trans_ongoing) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memcpy(udi_hid_exk_report_trans, udi_hid_exk_report, UDI_HID_EXK_REPORT_SIZE);
 | 
			
		||||
    udi_hid_exk_b_report_valid         = false;
 | 
			
		||||
    udi_hid_exk_b_report_trans_ongoing = udd_ep_run(UDI_HID_EXK_EP_IN | USB_EP_DIR_IN, false, udi_hid_exk_report_trans, UDI_HID_EXK_REPORT_SIZE, udi_hid_exk_report_sent);
 | 
			
		||||
 | 
			
		||||
    return udi_hid_exk_b_report_trans_ongoing;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void udi_hid_exk_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep) {
 | 
			
		||||
    UNUSED(status);
 | 
			
		||||
    UNUSED(nb_sent);
 | 
			
		||||
    UNUSED(ep);
 | 
			
		||||
    udi_hid_exk_b_report_trans_ongoing = false;
 | 
			
		||||
    if (udi_hid_exk_b_report_valid) {
 | 
			
		||||
        udi_hid_exk_send_report();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif  // EXTRAKEY_ENABLE
 | 
			
		||||
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
// MOU Mouse
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
#ifdef MOUSE_ENABLE
 | 
			
		||||
 | 
			
		||||
bool    udi_hid_mou_enable(void);
 | 
			
		||||
void    udi_hid_mou_disable(void);
 | 
			
		||||
bool    udi_hid_mou_setup(void);
 | 
			
		||||
uint8_t udi_hid_mou_getsetting(void);
 | 
			
		||||
 | 
			
		||||
UDC_DESC_STORAGE udi_api_t udi_api_hid_mou = {
 | 
			
		||||
    .enable     = (bool (*)(void))udi_hid_mou_enable,
 | 
			
		||||
    .disable    = (void (*)(void))udi_hid_mou_disable,
 | 
			
		||||
    .setup      = (bool (*)(void))udi_hid_mou_setup,
 | 
			
		||||
    .getsetting = (uint8_t(*)(void))udi_hid_mou_getsetting,
 | 
			
		||||
    .sof_notify = NULL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
static uint8_t udi_hid_mou_rate;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
static uint8_t udi_hid_mou_protocol;
 | 
			
		||||
 | 
			
		||||
// COMPILER_WORD_ALIGNED
 | 
			
		||||
// uint8_t udi_hid_mou_report_set; //No set report
 | 
			
		||||
 | 
			
		||||
bool udi_hid_mou_b_report_valid;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
uint8_t udi_hid_mou_report[UDI_HID_MOU_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
static bool udi_hid_mou_b_report_trans_ongoing;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
static uint8_t udi_hid_mou_report_trans[UDI_HID_MOU_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
UDC_DESC_STORAGE udi_hid_mou_report_desc_t udi_hid_mou_report_desc = {{
 | 
			
		||||
    0x05, 0x01,  // Usage Page (Generic Desktop)
 | 
			
		||||
    0x09, 0x02,  // Usage (Mouse)
 | 
			
		||||
    0xA1, 0x01,  // Collection (Application)
 | 
			
		||||
    0x09, 0x01,  //   Usage (Pointer)
 | 
			
		||||
    0xA1, 0x00,  //   Collection (Physical)
 | 
			
		||||
    // Buttons (5 bits)
 | 
			
		||||
    0x05, 0x09,  //     Usage Page (Button)
 | 
			
		||||
    0x19, 0x01,  //     Usage Minimum (Button 1)
 | 
			
		||||
    0x29, 0x05,  //     Usage Maximun (Button 5)
 | 
			
		||||
    0x15, 0x00,  //     Logical Minimum (0)
 | 
			
		||||
    0x25, 0x01,  //     Logical Maximum (1)
 | 
			
		||||
    0x95, 0x05,  //     Report Count (5)
 | 
			
		||||
    0x75, 0x01,  //     Report Size (1)
 | 
			
		||||
    0x81, 0x02,  //     Input (Data, Variable, Absolute)
 | 
			
		||||
    // Button padding (3 bits)
 | 
			
		||||
    0x95, 0x01,  //     Report Count (1)
 | 
			
		||||
    0x75, 0x03,  //     Report Size (3)
 | 
			
		||||
    0x81, 0x01,  //     Input (Constant)
 | 
			
		||||
 | 
			
		||||
    // 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)
 | 
			
		||||
 | 
			
		||||
    // 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)
 | 
			
		||||
 | 
			
		||||
    // 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
 | 
			
		||||
}};
 | 
			
		||||
 | 
			
		||||
static void udi_hid_mou_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
 | 
			
		||||
 | 
			
		||||
bool udi_hid_mou_enable(void) {
 | 
			
		||||
    // Initialize internal values
 | 
			
		||||
    udi_hid_mou_rate                   = 0;
 | 
			
		||||
    udi_hid_mou_protocol               = 0;
 | 
			
		||||
    udi_hid_mou_b_report_trans_ongoing = false;
 | 
			
		||||
    memset(udi_hid_mou_report, 0, UDI_HID_MOU_REPORT_SIZE);
 | 
			
		||||
    udi_hid_mou_b_report_valid = false;
 | 
			
		||||
    return UDI_HID_MOU_ENABLE_EXT();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udi_hid_mou_disable(void) { UDI_HID_MOU_DISABLE_EXT(); }
 | 
			
		||||
 | 
			
		||||
bool udi_hid_mou_setup(void) { return udi_hid_setup(&udi_hid_mou_rate, &udi_hid_mou_protocol, (uint8_t *)&udi_hid_mou_report_desc, NULL); }
 | 
			
		||||
 | 
			
		||||
uint8_t udi_hid_mou_getsetting(void) { return 0; }
 | 
			
		||||
 | 
			
		||||
bool udi_hid_mou_send_report(void) {
 | 
			
		||||
    if (!main_b_mou_enable) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (udi_hid_mou_b_report_trans_ongoing) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memcpy(udi_hid_mou_report_trans, udi_hid_mou_report, UDI_HID_MOU_REPORT_SIZE);
 | 
			
		||||
    udi_hid_mou_b_report_valid         = false;
 | 
			
		||||
    udi_hid_mou_b_report_trans_ongoing = udd_ep_run(UDI_HID_MOU_EP_IN | USB_EP_DIR_IN, false, udi_hid_mou_report_trans, UDI_HID_MOU_REPORT_SIZE, udi_hid_mou_report_sent);
 | 
			
		||||
 | 
			
		||||
    return udi_hid_mou_b_report_trans_ongoing;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void udi_hid_mou_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep) {
 | 
			
		||||
    UNUSED(status);
 | 
			
		||||
    UNUSED(nb_sent);
 | 
			
		||||
    UNUSED(ep);
 | 
			
		||||
    udi_hid_mou_b_report_trans_ongoing = false;
 | 
			
		||||
    if (udi_hid_mou_b_report_valid) {
 | 
			
		||||
        udi_hid_mou_send_report();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif  // MOUSE_ENABLE
 | 
			
		||||
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
// RAW
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
#ifdef RAW_ENABLE
 | 
			
		||||
 | 
			
		||||
bool    udi_hid_raw_enable(void);
 | 
			
		||||
void    udi_hid_raw_disable(void);
 | 
			
		||||
bool    udi_hid_raw_setup(void);
 | 
			
		||||
uint8_t udi_hid_raw_getsetting(void);
 | 
			
		||||
 | 
			
		||||
UDC_DESC_STORAGE udi_api_t udi_api_hid_raw = {
 | 
			
		||||
    .enable     = (bool (*)(void))udi_hid_raw_enable,
 | 
			
		||||
    .disable    = (void (*)(void))udi_hid_raw_disable,
 | 
			
		||||
    .setup      = (bool (*)(void))udi_hid_raw_setup,
 | 
			
		||||
    .getsetting = (uint8_t(*)(void))udi_hid_raw_getsetting,
 | 
			
		||||
    .sof_notify = NULL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
static uint8_t udi_hid_raw_rate;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
static uint8_t udi_hid_raw_protocol;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
uint8_t udi_hid_raw_report_set[UDI_HID_RAW_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
static bool udi_hid_raw_b_report_valid;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
uint8_t udi_hid_raw_report[UDI_HID_RAW_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
static bool udi_hid_raw_b_report_trans_ongoing;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
static uint8_t udi_hid_raw_report_trans[UDI_HID_RAW_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
static uint8_t udi_hid_raw_report_recv[UDI_HID_RAW_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
UDC_DESC_STORAGE udi_hid_raw_report_desc_t udi_hid_raw_report_desc = {{
 | 
			
		||||
    0x06, HID_VALUE_16(RAW_USAGE_PAGE),  // Usage Page (Vendor Defined)
 | 
			
		||||
    0x09, RAW_USAGE_ID,                  // Usage (Vendor Defined)
 | 
			
		||||
    0xA1, 0x01,                          // Collection (Application)
 | 
			
		||||
    0x75, 0x08,                          //   Report Size (8)
 | 
			
		||||
    0x15, 0x00,                          //   Logical Minimum (0)
 | 
			
		||||
    0x25, 0xFF,                          //   Logical Maximum (255)
 | 
			
		||||
    // Data to host
 | 
			
		||||
    0x09, 0x62,        //   Usage (Vendor Defined)
 | 
			
		||||
    0x95, RAW_EPSIZE,  //   Report Count
 | 
			
		||||
    0x81, 0x02,        //   Input (Data, Variable, Absolute)
 | 
			
		||||
    // Data from host
 | 
			
		||||
    0x09, 0x63,        //   Usage (Vendor Defined)
 | 
			
		||||
    0x95, RAW_EPSIZE,  //   Report Count
 | 
			
		||||
    0x91, 0x02,        //   Output (Data, Variable, Absolute)
 | 
			
		||||
    0xC0               // End Collection
 | 
			
		||||
}};
 | 
			
		||||
 | 
			
		||||
static bool udi_hid_raw_setreport(void);
 | 
			
		||||
static void udi_hid_raw_setreport_valid(void);
 | 
			
		||||
 | 
			
		||||
static void udi_hid_raw_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
 | 
			
		||||
static void udi_hid_raw_report_rcvd(udd_ep_status_t status, iram_size_t nb_rcvd, udd_ep_id_t ep);
 | 
			
		||||
 | 
			
		||||
bool udi_hid_raw_enable(void) {
 | 
			
		||||
    // Initialize internal values
 | 
			
		||||
    udi_hid_raw_rate                   = 0;
 | 
			
		||||
    udi_hid_raw_protocol               = 0;
 | 
			
		||||
    udi_hid_raw_b_report_trans_ongoing = false;
 | 
			
		||||
    memset(udi_hid_raw_report, 0, UDI_HID_RAW_REPORT_SIZE);
 | 
			
		||||
    udi_hid_raw_b_report_valid = false;
 | 
			
		||||
    return UDI_HID_RAW_ENABLE_EXT();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udi_hid_raw_disable(void) { UDI_HID_RAW_DISABLE_EXT(); }
 | 
			
		||||
 | 
			
		||||
bool udi_hid_raw_setup(void) { return udi_hid_setup(&udi_hid_raw_rate, &udi_hid_raw_protocol, (uint8_t *)&udi_hid_raw_report_desc, udi_hid_raw_setreport); }
 | 
			
		||||
 | 
			
		||||
uint8_t udi_hid_raw_getsetting(void) { return 0; }
 | 
			
		||||
 | 
			
		||||
static bool udi_hid_raw_setreport(void) {
 | 
			
		||||
    if ((USB_HID_REPORT_TYPE_OUTPUT == (udd_g_ctrlreq.req.wValue >> 8)) && (0 == (0xFF & udd_g_ctrlreq.req.wValue)) && (UDI_HID_RAW_REPORT_SIZE == udd_g_ctrlreq.req.wLength)) {
 | 
			
		||||
        // Report OUT type on report ID 0 from USB Host
 | 
			
		||||
        udd_g_ctrlreq.payload      = udi_hid_raw_report_set;
 | 
			
		||||
        udd_g_ctrlreq.callback     = udi_hid_raw_setreport_valid;  // must call routine to transform setreport to LED state
 | 
			
		||||
        udd_g_ctrlreq.payload_size = UDI_HID_RAW_REPORT_SIZE;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool udi_hid_raw_send_report(void) {
 | 
			
		||||
    if (!main_b_raw_enable) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (udi_hid_raw_b_report_trans_ongoing) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memcpy(udi_hid_raw_report_trans, udi_hid_raw_report, UDI_HID_RAW_REPORT_SIZE);
 | 
			
		||||
    udi_hid_raw_b_report_valid         = false;
 | 
			
		||||
    udi_hid_raw_b_report_trans_ongoing = udd_ep_run(UDI_HID_RAW_EP_IN | USB_EP_DIR_IN, false, udi_hid_raw_report_trans, UDI_HID_RAW_REPORT_SIZE, udi_hid_raw_report_sent);
 | 
			
		||||
 | 
			
		||||
    return udi_hid_raw_b_report_trans_ongoing;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void udi_hid_raw_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep) {
 | 
			
		||||
    UNUSED(status);
 | 
			
		||||
    UNUSED(nb_sent);
 | 
			
		||||
    UNUSED(ep);
 | 
			
		||||
    udi_hid_raw_b_report_trans_ongoing = false;
 | 
			
		||||
    if (udi_hid_raw_b_report_valid) {
 | 
			
		||||
        udi_hid_raw_send_report();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void udi_hid_raw_setreport_valid(void) {}
 | 
			
		||||
 | 
			
		||||
void raw_hid_send(uint8_t *data, uint8_t length) {
 | 
			
		||||
    if (main_b_raw_enable && !udi_hid_raw_b_report_trans_ongoing && length == UDI_HID_RAW_REPORT_SIZE) {
 | 
			
		||||
        memcpy(udi_hid_raw_report, data, UDI_HID_RAW_REPORT_SIZE);
 | 
			
		||||
        udi_hid_raw_send_report();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool udi_hid_raw_receive_report(void) {
 | 
			
		||||
    if (!main_b_raw_enable) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return udd_ep_run(UDI_HID_RAW_EP_OUT | USB_EP_DIR_OUT, false, udi_hid_raw_report_recv, UDI_HID_RAW_REPORT_SIZE, udi_hid_raw_report_rcvd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void udi_hid_raw_report_rcvd(udd_ep_status_t status, iram_size_t nb_rcvd, udd_ep_id_t ep) {
 | 
			
		||||
    UNUSED(ep);
 | 
			
		||||
 | 
			
		||||
    if (status == UDD_EP_TRANSFER_OK && nb_rcvd == UDI_HID_RAW_REPORT_SIZE) {
 | 
			
		||||
        UDI_HID_RAW_RECEIVE(udi_hid_raw_report_recv, UDI_HID_RAW_REPORT_SIZE);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // RAW_ENABLE
 | 
			
		||||
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
// CON
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
 | 
			
		||||
bool    udi_hid_con_enable(void);
 | 
			
		||||
void    udi_hid_con_disable(void);
 | 
			
		||||
bool    udi_hid_con_setup(void);
 | 
			
		||||
uint8_t udi_hid_con_getsetting(void);
 | 
			
		||||
 | 
			
		||||
UDC_DESC_STORAGE udi_api_t udi_api_hid_con = {
 | 
			
		||||
    .enable     = (bool (*)(void))udi_hid_con_enable,
 | 
			
		||||
    .disable    = (void (*)(void))udi_hid_con_disable,
 | 
			
		||||
    .setup      = (bool (*)(void))udi_hid_con_setup,
 | 
			
		||||
    .getsetting = (uint8_t(*)(void))udi_hid_con_getsetting,
 | 
			
		||||
    .sof_notify = NULL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
static uint8_t udi_hid_con_rate;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
static uint8_t udi_hid_con_protocol;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
uint8_t udi_hid_con_report_set[UDI_HID_CON_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
bool udi_hid_con_b_report_valid;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
uint8_t udi_hid_con_report[UDI_HID_CON_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
volatile bool udi_hid_con_b_report_trans_ongoing;
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
static uint8_t udi_hid_con_report_trans[UDI_HID_CON_REPORT_SIZE];
 | 
			
		||||
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
UDC_DESC_STORAGE udi_hid_con_report_desc_t udi_hid_con_report_desc = {{
 | 
			
		||||
    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_EPSIZE,  //   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_EPSIZE,  //   Report Count
 | 
			
		||||
    0x75, 0x08,            //   Report Size (8)
 | 
			
		||||
    0x91, 0x02,            //   Output (Data)
 | 
			
		||||
    0xC0                   // End Collection
 | 
			
		||||
}};
 | 
			
		||||
 | 
			
		||||
static bool udi_hid_con_setreport(void);
 | 
			
		||||
static void udi_hid_con_setreport_valid(void);
 | 
			
		||||
 | 
			
		||||
static void udi_hid_con_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
 | 
			
		||||
 | 
			
		||||
bool udi_hid_con_enable(void) {
 | 
			
		||||
    // Initialize internal values
 | 
			
		||||
    udi_hid_con_rate                   = 0;
 | 
			
		||||
    udi_hid_con_protocol               = 0;
 | 
			
		||||
    udi_hid_con_b_report_trans_ongoing = false;
 | 
			
		||||
    memset(udi_hid_con_report, 0, UDI_HID_CON_REPORT_SIZE);
 | 
			
		||||
    udi_hid_con_b_report_valid = false;
 | 
			
		||||
    return UDI_HID_CON_ENABLE_EXT();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udi_hid_con_disable(void) { UDI_HID_CON_DISABLE_EXT(); }
 | 
			
		||||
 | 
			
		||||
bool udi_hid_con_setup(void) { return udi_hid_setup(&udi_hid_con_rate, &udi_hid_con_protocol, (uint8_t *)&udi_hid_con_report_desc, udi_hid_con_setreport); }
 | 
			
		||||
 | 
			
		||||
uint8_t udi_hid_con_getsetting(void) { return 0; }
 | 
			
		||||
 | 
			
		||||
static bool udi_hid_con_setreport(void) {
 | 
			
		||||
    if ((USB_HID_REPORT_TYPE_OUTPUT == (udd_g_ctrlreq.req.wValue >> 8)) && (0 == (0xFF & udd_g_ctrlreq.req.wValue)) && (UDI_HID_CON_REPORT_SIZE == udd_g_ctrlreq.req.wLength)) {
 | 
			
		||||
        udd_g_ctrlreq.payload      = udi_hid_con_report_set;
 | 
			
		||||
        udd_g_ctrlreq.callback     = udi_hid_con_setreport_valid;
 | 
			
		||||
        udd_g_ctrlreq.payload_size = UDI_HID_CON_REPORT_SIZE;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool udi_hid_con_send_report(void) {
 | 
			
		||||
    if (!main_b_con_enable) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (udi_hid_con_b_report_trans_ongoing) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memcpy(udi_hid_con_report_trans, udi_hid_con_report, UDI_HID_CON_REPORT_SIZE);
 | 
			
		||||
    udi_hid_con_b_report_valid         = false;
 | 
			
		||||
    udi_hid_con_b_report_trans_ongoing = udd_ep_run(UDI_HID_CON_EP_IN | USB_EP_DIR_IN, false, udi_hid_con_report_trans, UDI_HID_CON_REPORT_SIZE, udi_hid_con_report_sent);
 | 
			
		||||
 | 
			
		||||
    return udi_hid_con_b_report_trans_ongoing;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void udi_hid_con_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep) {
 | 
			
		||||
    UNUSED(status);
 | 
			
		||||
    UNUSED(nb_sent);
 | 
			
		||||
    UNUSED(ep);
 | 
			
		||||
    udi_hid_con_b_report_trans_ongoing = false;
 | 
			
		||||
    if (udi_hid_con_b_report_valid) {
 | 
			
		||||
        udi_hid_con_send_report();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void udi_hid_con_setreport_valid(void) {}
 | 
			
		||||
 | 
			
		||||
#endif  // CONSOLE_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			@ -1,120 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief USB Device Human Interface Device (HID) keyboard interface.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _UDC_HID_KBD_H_
 | 
			
		||||
#define _UDC_HID_KBD_H_
 | 
			
		||||
 | 
			
		||||
#include "udc_desc.h"
 | 
			
		||||
#include "udi.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//******************************************************************************
 | 
			
		||||
// Keyboard interface definitions
 | 
			
		||||
//******************************************************************************
 | 
			
		||||
extern UDC_DESC_STORAGE udi_api_t udi_api_hid_kbd;
 | 
			
		||||
extern bool                       udi_hid_kbd_b_report_valid;
 | 
			
		||||
extern volatile bool              udi_hid_kbd_b_report_trans_ongoing;
 | 
			
		||||
extern uint8_t                    udi_hid_kbd_report_set;
 | 
			
		||||
bool                              udi_hid_kbd_send_report(void);
 | 
			
		||||
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
// NKRO Keyboard
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
#ifdef NKRO_ENABLE
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
// SYS-CTRL interface
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
#ifdef EXTRAKEY_ENABLE
 | 
			
		||||
extern UDC_DESC_STORAGE udi_api_t udi_api_hid_exk;
 | 
			
		||||
extern bool                       udi_hid_exk_b_report_valid;
 | 
			
		||||
bool                              udi_hid_exk_send_report(void);
 | 
			
		||||
#endif // EXTRAKEY_ENABLE
 | 
			
		||||
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
// CON Console
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
extern UDC_DESC_STORAGE udi_api_t udi_api_hid_con;
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
// MOU Mouse
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
#ifdef MOUSE_ENABLE
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
// RAW Raw
 | 
			
		||||
//********************************************************************************************
 | 
			
		||||
#ifdef RAW_ENABLE
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // _UDC_HID_KBD_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,60 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief Default HID keyboard configuration for a USB Device
 | 
			
		||||
 * with a single interface HID keyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _UDI_HID_KBD_CONF_H_
 | 
			
		||||
#define _UDI_HID_KBD_CONF_H_
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \addtogroup udi_hid_keyboard_group_single_desc
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "udi_device_conf.h"
 | 
			
		||||
 | 
			
		||||
#include "udi_hid_kbd.h"
 | 
			
		||||
 | 
			
		||||
#endif // _UDI_HID_KBD_CONF_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,179 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief Default descriptors for a USB Device
 | 
			
		||||
 * with a single interface HID keyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2016 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "conf_usb.h"
 | 
			
		||||
#include "usb_protocol.h"
 | 
			
		||||
#include "udc_desc.h"
 | 
			
		||||
#include "udi_device_conf.h"
 | 
			
		||||
#include "udi_hid_kbd.h"
 | 
			
		||||
#include "udi_cdc.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \ingroup udi_hid_keyboard_group
 | 
			
		||||
 * \defgroup udi_hid_keyboard_group_single_desc USB device descriptors for a single interface
 | 
			
		||||
 *
 | 
			
		||||
 * The following structures provide the USB device descriptors required
 | 
			
		||||
 * for USB Device with a single interface HID keyboard.
 | 
			
		||||
 *
 | 
			
		||||
 * It is ready to use and do not require more definition.
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//! USB Device Descriptor
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = {.bLength         = sizeof(usb_dev_desc_t),
 | 
			
		||||
                                                   .bDescriptorType = USB_DT_DEVICE,
 | 
			
		||||
                                                   .bcdUSB          = LE16(USB_V2_0),
 | 
			
		||||
                                                   .bDeviceClass    = DEVICE_CLASS,
 | 
			
		||||
                                                   .bDeviceSubClass = DEVICE_SUBCLASS,
 | 
			
		||||
                                                   .bDeviceProtocol = DEVICE_PROTOCOL,
 | 
			
		||||
                                                   .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE,
 | 
			
		||||
                                                   .idVendor        = LE16(USB_DEVICE_VENDOR_ID),
 | 
			
		||||
                                                   .idProduct       = LE16(USB_DEVICE_PRODUCT_ID),
 | 
			
		||||
                                                   .bcdDevice       = LE16(USB_DEVICE_VERSION),
 | 
			
		||||
#ifdef USB_DEVICE_MANUFACTURE_NAME
 | 
			
		||||
                                                   .iManufacturer = 1,
 | 
			
		||||
#else
 | 
			
		||||
                                                   .iManufacturer = 0, // No manufacture string
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef USB_DEVICE_PRODUCT_NAME
 | 
			
		||||
                                                   .iProduct = 2,
 | 
			
		||||
#else
 | 
			
		||||
                                                   .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
 | 
			
		||||
#endif
 | 
			
		||||
                                                   .bNumConfigurations = 1};
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
#    ifdef USB_DEVICE_HS_SUPPORT
 | 
			
		||||
//! USB Device Qualifier Descriptor for HS
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = {
 | 
			
		||||
    .bLength                   = sizeof(usb_dev_qual_desc_t),
 | 
			
		||||
    .bDescriptorType           = USB_DT_DEVICE_QUALIFIER,
 | 
			
		||||
    .bcdUSB                    = LE16(USB_V2_0),
 | 
			
		||||
    .bDeviceClass              = 0,
 | 
			
		||||
    .bDeviceSubClass           = 0,
 | 
			
		||||
    .bDeviceProtocol           = 0,
 | 
			
		||||
    .bMaxPacketSize0           = USB_DEVICE_EP_CTRL_SIZE,
 | 
			
		||||
    .bNumConfigurations        = 1
 | 
			
		||||
};
 | 
			
		||||
#    endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//! USB Device Configuration Descriptor filled for FS and HS
 | 
			
		||||
COMPILER_WORD_ALIGNED
 | 
			
		||||
UDC_DESC_STORAGE udc_desc_t udc_desc = {
 | 
			
		||||
    .conf.bLength             = sizeof(usb_conf_desc_t),
 | 
			
		||||
    .conf.bDescriptorType     = USB_DT_CONFIGURATION,
 | 
			
		||||
    .conf.wTotalLength        = LE16(sizeof(udc_desc_t)),
 | 
			
		||||
    .conf.bNumInterfaces      = USB_DEVICE_NB_INTERFACE,
 | 
			
		||||
    .conf.bConfigurationValue = 1,
 | 
			
		||||
    .conf.iConfiguration      = 0,
 | 
			
		||||
    .conf.bmAttributes        = /* USB_CONFIG_ATTR_MUST_SET | */ USB_DEVICE_ATTR,
 | 
			
		||||
    .conf.bMaxPower           = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER),
 | 
			
		||||
    .hid_kbd                  = UDI_HID_KBD_DESC,
 | 
			
		||||
#ifdef RAW_ENABLE
 | 
			
		||||
    .hid_raw = UDI_HID_RAW_DESC,
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef MOUSE_ENABLE
 | 
			
		||||
    .hid_mou = UDI_HID_MOU_DESC,
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef EXTRAKEY_ENABLE
 | 
			
		||||
    .hid_exk = UDI_HID_EXK_DESC,
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
    .hid_con = UDI_HID_CON_DESC,
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef NKRO_ENABLE
 | 
			
		||||
    .hid_nkro = UDI_HID_NKRO_DESC,
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef VIRTSER_ENABLE
 | 
			
		||||
    .cdc_serial = CDC_DESCRIPTOR,
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = {
 | 
			
		||||
    &udi_api_hid_kbd,
 | 
			
		||||
#ifdef RAW_ENABLE
 | 
			
		||||
    &udi_api_hid_raw,
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef MOUSE_ENABLE
 | 
			
		||||
    &udi_api_hid_mou,
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef EXTRAKEY_ENABLE
 | 
			
		||||
    &udi_api_hid_exk,
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
    &udi_api_hid_con,
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef NKRO_ENABLE
 | 
			
		||||
    &udi_api_hid_nkro,
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef VIRTSER_ENABLE
 | 
			
		||||
    &udi_api_cdc_comm, &udi_api_cdc_data,
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//! Add UDI with USB Descriptors FS & HS
 | 
			
		||||
UDC_DESC_STORAGE udc_config_speed_t udc_config_fshs[1] = {{
 | 
			
		||||
    .desc     = (usb_conf_desc_t UDC_DESC_STORAGE *)&udc_desc,
 | 
			
		||||
    .udi_apis = udi_apis,
 | 
			
		||||
}};
 | 
			
		||||
 | 
			
		||||
//! Add all information about USB Device in global structure for UDC
 | 
			
		||||
UDC_DESC_STORAGE udc_config_t udc_config = {
 | 
			
		||||
    .confdev_lsfs = &udc_device_desc,
 | 
			
		||||
    .conf_lsfs    = udc_config_fshs,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//@}
 | 
			
		||||
//@}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,83 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief User Interface
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef ARM_MATH_CM4
 | 
			
		||||
#    define ARM_MATH_CM4
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#undef LITTLE_ENDIAN // redefined in samd51j18a.h
 | 
			
		||||
#include "samd51j18a.h"
 | 
			
		||||
#include "ui.h"
 | 
			
		||||
 | 
			
		||||
//! Sequence process running each \c SEQUENCE_PERIOD ms
 | 
			
		||||
#define SEQUENCE_PERIOD 150
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
/* Interrupt on "pin change" from push button to do wakeup on USB
 | 
			
		||||
 * Note:
 | 
			
		||||
 * This interrupt is enable when the USB host enable remote wakeup feature
 | 
			
		||||
 * This interrupt wakeup the CPU if this one is in idle mode
 | 
			
		||||
 */
 | 
			
		||||
static void ui_wakeup_handler(void)
 | 
			
		||||
{
 | 
			
		||||
    /* It is a wakeup then send wakeup USB */
 | 
			
		||||
    udc_remotewakeup();
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void ui_init(void) {}
 | 
			
		||||
 | 
			
		||||
void ui_powerdown(void) {}
 | 
			
		||||
 | 
			
		||||
void ui_wakeup_enable(void) {}
 | 
			
		||||
 | 
			
		||||
void ui_wakeup_disable(void) {}
 | 
			
		||||
 | 
			
		||||
void ui_wakeup(void) {}
 | 
			
		||||
 | 
			
		||||
void ui_process(uint16_t framenumber) {}
 | 
			
		||||
 | 
			
		||||
void ui_kbd_led(uint8_t value) {}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,76 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief Common User Interface for HID Keyboard application
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _UI_H_
 | 
			
		||||
#define _UI_H_
 | 
			
		||||
 | 
			
		||||
//! \brief Initializes the user interface
 | 
			
		||||
void ui_init(void);
 | 
			
		||||
 | 
			
		||||
//! \brief Enters the user interface in power down mode
 | 
			
		||||
void ui_powerdown(void);
 | 
			
		||||
 | 
			
		||||
//! \brief Enables the asynchronous interrupts of the user interface
 | 
			
		||||
void ui_wakeup_enable(void);
 | 
			
		||||
 | 
			
		||||
//! \brief Disables the asynchronous interrupts of the user interface
 | 
			
		||||
void ui_wakeup_disable(void);
 | 
			
		||||
 | 
			
		||||
//! \brief Exits the user interface of power down mode
 | 
			
		||||
void ui_wakeup(void);
 | 
			
		||||
 | 
			
		||||
/*! \brief This process is called each 1ms
 | 
			
		||||
 * It is called only if the USB interface is enabled.
 | 
			
		||||
 *
 | 
			
		||||
 * \param framenumber  Current frame number
 | 
			
		||||
 */
 | 
			
		||||
void ui_process(uint16_t framenumber);
 | 
			
		||||
 | 
			
		||||
/*! \brief Turn on or off the keyboard LEDs
 | 
			
		||||
 */
 | 
			
		||||
void ui_kbd_led(uint8_t value);
 | 
			
		||||
 | 
			
		||||
#endif // _UI_H_
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,462 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief SAM USB Driver
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2014-2016 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
#ifndef USB_H_INCLUDED
 | 
			
		||||
#define USB_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \defgroup asfdoc_sam0_usb_group SAM Universal Serial Bus (USB)
 | 
			
		||||
 *
 | 
			
		||||
 * The Universal Serial Bus (USB) module complies with the USB 2.1 specification.
 | 
			
		||||
 *
 | 
			
		||||
 * The following peripherals are used by this module:
 | 
			
		||||
 *  - USB (Universal Serial Bus)
 | 
			
		||||
 *
 | 
			
		||||
 * The following devices can use this module:
 | 
			
		||||
 *  - Atmel | SMART SAM D51
 | 
			
		||||
 *
 | 
			
		||||
 * The USB module covers following mode:
 | 
			
		||||
 * \if USB_DEVICE_MODE
 | 
			
		||||
 *  - USB Device Mode
 | 
			
		||||
 * \endif
 | 
			
		||||
 * \if USB_HOST_MODE
 | 
			
		||||
 *  - USB Host Mode
 | 
			
		||||
 * \endif
 | 
			
		||||
 *
 | 
			
		||||
 * The USB module covers following speed:
 | 
			
		||||
 * \if USB_HS_MODE
 | 
			
		||||
 *  - USB High Speed (480Mbit/s)
 | 
			
		||||
 * \endif
 | 
			
		||||
 *  - USB Full Speed (12Mbit/s)
 | 
			
		||||
 * \if USB_LS_MODE
 | 
			
		||||
 *  - USB Low Speed (1.5Mbit/s)
 | 
			
		||||
 * \endif
 | 
			
		||||
 *
 | 
			
		||||
 * \if USB_LPM_MODE
 | 
			
		||||
 * The USB module supports Link Power Management (LPM-L1) protocol.
 | 
			
		||||
 * \endif
 | 
			
		||||
 *
 | 
			
		||||
 * USB support needs whole set of enumeration process, to make the device
 | 
			
		||||
 * recognizable and usable. The USB driver is designed to interface to the
 | 
			
		||||
 * USB Stack in Atmel Software Framework (ASF).
 | 
			
		||||
 *
 | 
			
		||||
 * \if USB_DEVICE_MODE
 | 
			
		||||
 * \section asfdoc_sam0_usb_device USB Device Mode
 | 
			
		||||
 * The ASF USB Device Stack has defined the USB Device Driver (UDD) interface,
 | 
			
		||||
 * to support USB device operations. The USB module device driver complies with
 | 
			
		||||
 * this interface, so that the USB Device Stack can work based on the
 | 
			
		||||
 * USB module.
 | 
			
		||||
 *
 | 
			
		||||
 * Refer to <a href="http://www.atmel.com/images/doc8360.pdf">
 | 
			
		||||
 * "ASF - USB Device Stack"</a> for more details.
 | 
			
		||||
 * \endif
 | 
			
		||||
 *
 | 
			
		||||
 * \if USB_HOST_MODE
 | 
			
		||||
 * \section adfdoc_sam0_usb_host USB Host Mode
 | 
			
		||||
 * The ASF USB Host Stack has defined the USB Host Driver (UHD) interface,
 | 
			
		||||
 * to support USB host operations. The USB module host driver complies with
 | 
			
		||||
 * this interface, so that the USB Host Stack can work based on the USB module.
 | 
			
		||||
 *
 | 
			
		||||
 * Refer to <a href="http://www.atmel.com/images/doc8486.pdf">
 | 
			
		||||
 * "ASF - USB Host Stack"</a> for more details.
 | 
			
		||||
 * \endif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** Enum for the speed status for the USB module */
 | 
			
		||||
enum usb_speed {
 | 
			
		||||
    USB_SPEED_LOW,
 | 
			
		||||
    USB_SPEED_FULL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Enum for the possible callback types for the USB in host module */
 | 
			
		||||
enum usb_host_callback {
 | 
			
		||||
    USB_HOST_CALLBACK_SOF,
 | 
			
		||||
    USB_HOST_CALLBACK_RESET,
 | 
			
		||||
    USB_HOST_CALLBACK_WAKEUP,
 | 
			
		||||
    USB_HOST_CALLBACK_DNRSM,
 | 
			
		||||
    USB_HOST_CALLBACK_UPRSM,
 | 
			
		||||
    USB_HOST_CALLBACK_RAMACER,
 | 
			
		||||
    USB_HOST_CALLBACK_CONNECT,
 | 
			
		||||
    USB_HOST_CALLBACK_DISCONNECT,
 | 
			
		||||
    USB_HOST_CALLBACK_N,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Enum for the possible callback types for the USB pipe in host module */
 | 
			
		||||
enum usb_host_pipe_callback {
 | 
			
		||||
    USB_HOST_PIPE_CALLBACK_TRANSFER_COMPLETE,
 | 
			
		||||
    USB_HOST_PIPE_CALLBACK_ERROR,
 | 
			
		||||
    USB_HOST_PIPE_CALLBACK_SETUP,
 | 
			
		||||
    USB_HOST_PIPE_CALLBACK_STALL,
 | 
			
		||||
    USB_HOST_PIPE_CALLBACK_N,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Host pipe types.
 | 
			
		||||
 */
 | 
			
		||||
enum usb_host_pipe_type {
 | 
			
		||||
    USB_HOST_PIPE_TYPE_DISABLE,
 | 
			
		||||
    USB_HOST_PIPE_TYPE_CONTROL,
 | 
			
		||||
    USB_HOST_PIPE_TYPE_ISO,
 | 
			
		||||
    USB_HOST_PIPE_TYPE_BULK,
 | 
			
		||||
    USB_HOST_PIPE_TYPE_INTERRUPT,
 | 
			
		||||
    USB_HOST_PIPE_TYPE_EXTENDED,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Host pipe token types.
 | 
			
		||||
 */
 | 
			
		||||
enum usb_host_pipe_token {
 | 
			
		||||
    USB_HOST_PIPE_TOKEN_SETUP,
 | 
			
		||||
    USB_HOST_PIPE_TOKEN_IN,
 | 
			
		||||
    USB_HOST_PIPE_TOKEN_OUT,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Enumeration for the possible callback types for the USB in device module
 | 
			
		||||
 */
 | 
			
		||||
enum usb_device_callback {
 | 
			
		||||
    USB_DEVICE_CALLBACK_SOF,
 | 
			
		||||
    USB_DEVICE_CALLBACK_RESET,
 | 
			
		||||
    USB_DEVICE_CALLBACK_WAKEUP,
 | 
			
		||||
    USB_DEVICE_CALLBACK_RAMACER,
 | 
			
		||||
    USB_DEVICE_CALLBACK_SUSPEND,
 | 
			
		||||
    USB_DEVICE_CALLBACK_LPMNYET,
 | 
			
		||||
    USB_DEVICE_CALLBACK_LPMSUSP,
 | 
			
		||||
    USB_DEVICE_CALLBACK_N,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Enumeration for the possible callback types for the USB endpoint in device module
 | 
			
		||||
 */
 | 
			
		||||
enum usb_device_endpoint_callback {
 | 
			
		||||
    USB_DEVICE_ENDPOINT_CALLBACK_TRCPT,
 | 
			
		||||
    USB_DEVICE_ENDPOINT_CALLBACK_TRFAIL,
 | 
			
		||||
    USB_DEVICE_ENDPOINT_CALLBACK_RXSTP,
 | 
			
		||||
    USB_DEVICE_ENDPOINT_CALLBACK_STALL,
 | 
			
		||||
    USB_DEVICE_EP_CALLBACK_N,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Device Endpoint types.
 | 
			
		||||
 */
 | 
			
		||||
enum usb_device_endpoint_type {
 | 
			
		||||
    USB_DEVICE_ENDPOINT_TYPE_DISABLE,
 | 
			
		||||
    USB_DEVICE_ENDPOINT_TYPE_CONTROL,
 | 
			
		||||
    USB_DEVICE_ENDPOINT_TYPE_ISOCHRONOUS,
 | 
			
		||||
    USB_DEVICE_ENDPOINT_TYPE_BULK,
 | 
			
		||||
    USB_DEVICE_ENDPOINT_TYPE_INTERRUPT,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Endpoint Size
 | 
			
		||||
 */
 | 
			
		||||
enum usb_endpoint_size {
 | 
			
		||||
    USB_ENDPOINT_8_BYTE,
 | 
			
		||||
    USB_ENDPOINT_16_BYTE,
 | 
			
		||||
    USB_ENDPOINT_32_BYTE,
 | 
			
		||||
    USB_ENDPOINT_64_BYTE,
 | 
			
		||||
    USB_ENDPOINT_128_BYTE,
 | 
			
		||||
    USB_ENDPOINT_256_BYTE,
 | 
			
		||||
    USB_ENDPOINT_512_BYTE,
 | 
			
		||||
    USB_ENDPOINT_1023_BYTE,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Link Power Management Handshake.
 | 
			
		||||
 */
 | 
			
		||||
enum usb_device_lpm_mode {
 | 
			
		||||
    USB_DEVICE_LPM_NOT_SUPPORT,
 | 
			
		||||
    USB_DEVICE_LPM_ACK,
 | 
			
		||||
    USB_DEVICE_LPM_NYET,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Module structure
 | 
			
		||||
 */
 | 
			
		||||
struct usb_module;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \name Host Callback Functions Types
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
typedef void (*usb_host_callback_t)(struct usb_module *module_inst);
 | 
			
		||||
typedef void (*usb_host_pipe_callback_t)(struct usb_module *module_inst, void *);
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \name Device Callback Functions Types
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
typedef void (*usb_device_callback_t)(struct usb_module *module_inst, void *pointer);
 | 
			
		||||
typedef void (*usb_device_endpoint_callback_t)(struct usb_module *module_inst, void *pointer);
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
/** USB configurations */
 | 
			
		||||
struct usb_config {
 | 
			
		||||
    /** \c true for host, \c false for device. */
 | 
			
		||||
    bool select_host_mode;
 | 
			
		||||
    /** When \c true the module is enabled during standby. */
 | 
			
		||||
    bool run_in_standby;
 | 
			
		||||
    /** Generic Clock Generator source channel. */
 | 
			
		||||
    // enum gclk_generator source_generator;
 | 
			
		||||
    uint8_t source_generator;
 | 
			
		||||
    /** Speed mode */
 | 
			
		||||
    // enum usb_speed speed_mode;
 | 
			
		||||
    uint8_t speed_mode;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief USB software module instance structure.
 | 
			
		||||
 *
 | 
			
		||||
 * USB software module instance structure, used to retain software state
 | 
			
		||||
 * information of an associated hardware module instance.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
struct usb_module {
 | 
			
		||||
    /** Hardware module pointer of the associated USB peripheral. */
 | 
			
		||||
    Usb *hw;
 | 
			
		||||
 | 
			
		||||
    /** Array to store device related callback functions */
 | 
			
		||||
    usb_device_callback_t          device_callback[USB_DEVICE_CALLBACK_N];
 | 
			
		||||
    usb_device_endpoint_callback_t device_endpoint_callback[USB_EPT_NUM][USB_DEVICE_EP_CALLBACK_N];
 | 
			
		||||
    /** Bit mask for device callbacks registered */
 | 
			
		||||
    uint16_t device_registered_callback_mask;
 | 
			
		||||
    /** Bit mask for device callbacks enabled */
 | 
			
		||||
    uint16_t device_enabled_callback_mask;
 | 
			
		||||
    /** Bit mask for device endpoint callbacks registered */
 | 
			
		||||
    uint8_t device_endpoint_registered_callback_mask[USB_EPT_NUM];
 | 
			
		||||
    /** Bit mask for device endpoint callbacks enabled */
 | 
			
		||||
    uint8_t device_endpoint_enabled_callback_mask[USB_EPT_NUM];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** USB device endpoint configurations */
 | 
			
		||||
struct usb_device_endpoint_config {
 | 
			
		||||
    /** device address */
 | 
			
		||||
    uint8_t ep_address;
 | 
			
		||||
    /** endpoint size */
 | 
			
		||||
    enum usb_endpoint_size ep_size;
 | 
			
		||||
    /** automatic zero length packet mode, \c true to enable */
 | 
			
		||||
    bool auto_zlp;
 | 
			
		||||
    /** type of endpoint with Bank */
 | 
			
		||||
    enum usb_device_endpoint_type ep_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** USB device endpoint callback status parameter structure */
 | 
			
		||||
struct usb_endpoint_callback_parameter {
 | 
			
		||||
    uint16_t received_bytes;
 | 
			
		||||
    uint16_t sent_bytes;
 | 
			
		||||
    uint16_t out_buffer_size;
 | 
			
		||||
    uint8_t  endpoint_address;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void usb_enable(struct usb_module *module_inst);
 | 
			
		||||
void usb_disable(struct usb_module *module_inst);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Get the status of USB module's state machine
 | 
			
		||||
 *
 | 
			
		||||
 * \param module_inst Pointer to USB module instance
 | 
			
		||||
 */
 | 
			
		||||
static inline uint8_t usb_get_state_machine_status(struct usb_module *module_inst) {
 | 
			
		||||
    /* Sanity check arguments */
 | 
			
		||||
    Assert(module_inst);
 | 
			
		||||
    Assert(module_inst->hw);
 | 
			
		||||
 | 
			
		||||
    return module_inst->hw->DEVICE.FSMSTATUS.reg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void             usb_get_config_defaults(struct usb_config *module_config);
 | 
			
		||||
enum status_code usb_init(struct usb_module *module_inst, Usb *const hw, struct usb_config *module_config);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Attach USB device to the bus
 | 
			
		||||
 *
 | 
			
		||||
 * \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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Get the speed mode of USB device
 | 
			
		||||
 *
 | 
			
		||||
 * \param module_inst Pointer to USB device module instance
 | 
			
		||||
 * \return USB Speed mode (\ref usb_speed).
 | 
			
		||||
 */
 | 
			
		||||
static inline enum usb_speed usb_device_get_speed(struct usb_module *module_inst) {
 | 
			
		||||
    if (!(module_inst->hw->DEVICE.STATUS.reg & USB_DEVICE_STATUS_SPEED_Msk)) {
 | 
			
		||||
        return USB_SPEED_FULL;
 | 
			
		||||
    } else {
 | 
			
		||||
        return USB_SPEED_LOW;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Get the address of USB device
 | 
			
		||||
 *
 | 
			
		||||
 * \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));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Set the speed mode of USB device
 | 
			
		||||
 *
 | 
			
		||||
 * \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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Get the frame number of USB device
 | 
			
		||||
 *
 | 
			
		||||
 * \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));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Get the micro-frame number of USB device
 | 
			
		||||
 *
 | 
			
		||||
 * \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));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief USB device set the LPM mode
 | 
			
		||||
 *
 | 
			
		||||
 * \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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \name USB Device Callback Management
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
enum status_code usb_device_register_callback(struct usb_module *module_inst, enum usb_device_callback callback_type, usb_device_callback_t callback_func);
 | 
			
		||||
enum status_code usb_device_unregister_callback(struct usb_module *module_inst, enum usb_device_callback callback_type);
 | 
			
		||||
enum status_code usb_device_enable_callback(struct usb_module *module_inst, enum usb_device_callback callback_type);
 | 
			
		||||
enum status_code usb_device_disable_callback(struct usb_module *module_inst, enum usb_device_callback callback_type);
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \name USB Device Endpoint Configuration
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
void             usb_device_endpoint_get_config_defaults(struct usb_device_endpoint_config *ep_config);
 | 
			
		||||
enum status_code usb_device_endpoint_set_config(struct usb_module *module_inst, struct usb_device_endpoint_config *ep_config);
 | 
			
		||||
bool             usb_device_endpoint_is_configured(struct usb_module *module_inst, uint8_t ep);
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \name USB Device Endpoint Callback Management
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
enum status_code usb_device_endpoint_register_callback(struct usb_module *module_inst, uint8_t ep_num, enum usb_device_endpoint_callback callback_type, usb_device_endpoint_callback_t callback_func);
 | 
			
		||||
enum status_code usb_device_endpoint_unregister_callback(struct usb_module *module_inst, uint8_t ep_num, enum usb_device_endpoint_callback callback_type);
 | 
			
		||||
enum status_code usb_device_endpoint_enable_callback(struct usb_module *module_inst, uint8_t ep, enum usb_device_endpoint_callback callback_type);
 | 
			
		||||
enum status_code usb_device_endpoint_disable_callback(struct usb_module *module_inst, uint8_t ep, enum usb_device_endpoint_callback callback_type);
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \name USB Device Endpoint Job Management
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
enum status_code usb_device_endpoint_write_buffer_job(struct usb_module *module_inst, uint8_t ep_num, uint8_t *pbuf, uint32_t buf_size);
 | 
			
		||||
enum status_code usb_device_endpoint_read_buffer_job(struct usb_module *module_inst, uint8_t ep_num, uint8_t *pbuf, uint32_t buf_size);
 | 
			
		||||
enum status_code usb_device_endpoint_setup_buffer_job(struct usb_module *module_inst, uint8_t *pbuf);
 | 
			
		||||
void             usb_device_endpoint_abort_job(struct usb_module *module_inst, uint8_t ep);
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \name USB Device Endpoint Operations
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
bool usb_device_endpoint_is_halted(struct usb_module *module_inst, uint8_t ep);
 | 
			
		||||
void usb_device_endpoint_set_halt(struct usb_module *module_inst, uint8_t ep);
 | 
			
		||||
void usb_device_endpoint_clear_halt(struct usb_module *module_inst, uint8_t ep);
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* USB_H_INCLUDED */
 | 
			
		||||
| 
						 | 
				
			
			@ -1,189 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief All USB VIDs and PIDs from Atmel USB applications
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _USB_ATMEL_H_
 | 
			
		||||
#define _USB_ATMEL_H_
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \defgroup usb_group USB Stack
 | 
			
		||||
 *
 | 
			
		||||
 * This stack includes the USB Device Stack, USB Host Stack and common
 | 
			
		||||
 * definitions.
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \ingroup usb_group
 | 
			
		||||
 * \defgroup usb_atmel_ids_group Atmel USB Identifiers
 | 
			
		||||
 *
 | 
			
		||||
 * This module defines Atmel PID and VIDs constants.
 | 
			
		||||
 *
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//! \name Vendor Identifier assigned by USB org to ATMEL
 | 
			
		||||
#define USB_VID_ATMEL 0x03EB
 | 
			
		||||
 | 
			
		||||
//! \name Product Identifier assigned by ATMEL to AVR applications
 | 
			
		||||
//! @{
 | 
			
		||||
 | 
			
		||||
//! \name The range from 2000h to 20FFh is reserved to the old PID for C51, MEGA, and others.
 | 
			
		||||
//! @{
 | 
			
		||||
#define USB_PID_ATMEL_MEGA_HIDGENERIC 0x2013
 | 
			
		||||
#define USB_PID_ATMEL_MEGA_HIDKEYBOARD 0x2017
 | 
			
		||||
#define USB_PID_ATMEL_MEGA_CDC 0x2018
 | 
			
		||||
#define USB_PID_ATMEL_MEGA_AUDIO_IN 0x2019
 | 
			
		||||
#define USB_PID_ATMEL_MEGA_MS 0x201A
 | 
			
		||||
#define USB_PID_ATMEL_MEGA_AUDIO_IN_OUT 0x201B
 | 
			
		||||
#define USB_PID_ATMEL_MEGA_HIDMOUSE 0x201C
 | 
			
		||||
#define USB_PID_ATMEL_MEGA_HIDMOUSE_CERTIF_U4 0x201D
 | 
			
		||||
#define USB_PID_ATMEL_MEGA_CDC_MULTI 0x201E
 | 
			
		||||
#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_USBKEY 0x2022
 | 
			
		||||
#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_STK525 0x2023
 | 
			
		||||
#define USB_PID_ATMEL_MEGA_MS_2 0x2029
 | 
			
		||||
#define USB_PID_ATMEL_MEGA_MS_HIDMS 0x202A
 | 
			
		||||
#define USB_PID_ATMEL_MEGA_MS_3 0x2032
 | 
			
		||||
#define USB_PID_ATMEL_MEGA_LIBUSB 0x2050
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
//! \name The range 2100h to 21FFh is reserved to PIDs for AVR Tools.
 | 
			
		||||
//! @{
 | 
			
		||||
#define USB_PID_ATMEL_XPLAINED 0x2122
 | 
			
		||||
#define USB_PID_ATMEL_XMEGA_USB_ZIGBIT_2_4GHZ 0x214A
 | 
			
		||||
#define USB_PID_ATMEL_XMEGA_USB_ZIGBIT_SUBGHZ 0x214B
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
//! \name The range 2300h to 23FFh is reserved to PIDs for demo from ASF1.7=>
 | 
			
		||||
//! @{
 | 
			
		||||
#define USB_PID_ATMEL_UC3_ENUM 0x2300
 | 
			
		||||
#define USB_PID_ATMEL_UC3_MS 0x2301
 | 
			
		||||
#define USB_PID_ATMEL_UC3_MS_SDRAM_LOADER 0x2302
 | 
			
		||||
#define USB_PID_ATMEL_UC3_EVK1100_CTRLPANEL 0x2303
 | 
			
		||||
#define USB_PID_ATMEL_UC3_HID 0x2304
 | 
			
		||||
#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID 0x2305
 | 
			
		||||
#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_AUDIO_SPEAKER_MICRO 0x2311
 | 
			
		||||
#define USB_PID_ATMEL_UC3_CDC_MSC 0x2312
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
//! \name The range 2400h to 24FFh is reserved to PIDs for ASF applications
 | 
			
		||||
//! @{
 | 
			
		||||
#define USB_PID_ATMEL_ASF_HIDMOUSE 0x2400
 | 
			
		||||
#define USB_PID_ATMEL_ASF_HIDKEYBOARD 0x2401
 | 
			
		||||
#define USB_PID_ATMEL_ASF_HIDGENERIC 0x2402
 | 
			
		||||
#define USB_PID_ATMEL_ASF_MSC 0x2403
 | 
			
		||||
#define USB_PID_ATMEL_ASF_CDC 0x2404
 | 
			
		||||
#define USB_PID_ATMEL_ASF_PHDC 0x2405
 | 
			
		||||
#define USB_PID_ATMEL_ASF_HIDMTOUCH 0x2406
 | 
			
		||||
#define USB_PID_ATMEL_ASF_MSC_HIDMOUSE 0x2420
 | 
			
		||||
#define USB_PID_ATMEL_ASF_MSC_HIDS_CDC 0x2421
 | 
			
		||||
#define USB_PID_ATMEL_ASF_MSC_HIDKEYBOARD 0x2422
 | 
			
		||||
#define USB_PID_ATMEL_ASF_VENDOR_CLASS 0x2423
 | 
			
		||||
#define USB_PID_ATMEL_ASF_MSC_CDC 0x2424
 | 
			
		||||
#define USB_PID_ATMEL_ASF_TWO_CDC 0x2425
 | 
			
		||||
#define USB_PID_ATMEL_ASF_SEVEN_CDC 0x2426
 | 
			
		||||
#define USB_PID_ATMEL_ASF_XPLAIN_BC_POWERONLY 0x2430
 | 
			
		||||
#define USB_PID_ATMEL_ASF_XPLAIN_BC_TERMINAL 0x2431
 | 
			
		||||
#define USB_PID_ATMEL_ASF_XPLAIN_BC_TOUCH 0x2432
 | 
			
		||||
#define USB_PID_ATMEL_ASF_AUDIO_SPEAKER 0x2433
 | 
			
		||||
#define USB_PID_ATMEL_ASF_XMEGA_B1_XPLAINED 0x2434
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
//! \name The range 2F00h to 2FFFh is reserved to official PIDs for AVR bootloaders
 | 
			
		||||
//! Note, !!!! don't use this range for demos or examples !!!!
 | 
			
		||||
//! @{
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA64C3 0x2FD6
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA128C3 0x2FD7
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA16C4 0x2FD8
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA32C4 0x2FD9
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA256C3 0x2FDA
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA384C3 0x2FDB
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATUCL3_L4 0x2FDC
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA64A4U 0x2FDD
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA128A4U 0x2FDE
 | 
			
		||||
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA64B3 0x2FDF
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA128B3 0x2FE0
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA64B1 0x2FE1
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA256A3BU 0x2FE2
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA16A4U 0x2FE3
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA32A4U 0x2FE4
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA64A3U 0x2FE5
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA128A3U 0x2FE6
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA192A3U 0x2FE7
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA64A1U 0x2FE8
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATUC3D 0x2FE9
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA128B1 0x2FEA
 | 
			
		||||
#define USB_PID_ATMEL_DFU_AT32UC3C 0x2FEB
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA256A3U 0x2FEC
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATXMEGA128A1U 0x2FED
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATMEGA8U2 0x2FEE
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATMEGA16U2 0x2FEF
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATMEGA32U2 0x2FF0
 | 
			
		||||
#define USB_PID_ATMEL_DFU_AT32UC3A3 0x2FF1
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATMEGA32U6 0x2FF2
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATMEGA16U4 0x2FF3
 | 
			
		||||
#define USB_PID_ATMEL_DFU_ATMEGA32U4 0x2FF4
 | 
			
		||||
#define USB_PID_ATMEL_DFU_AT32AP7200 0x2FF5
 | 
			
		||||
#define USB_PID_ATMEL_DFU_AT32UC3B 0x2FF6
 | 
			
		||||
#define USB_PID_ATMEL_DFU_AT90USB82 0x2FF7
 | 
			
		||||
#define USB_PID_ATMEL_DFU_AT32UC3A 0x2FF8
 | 
			
		||||
#define USB_PID_ATMEL_DFU_AT90USB64 0x2FF9
 | 
			
		||||
#define USB_PID_ATMEL_DFU_AT90USB162 0x2FFA
 | 
			
		||||
#define USB_PID_ATMEL_DFU_AT90USB128 0x2FFB
 | 
			
		||||
// 2FFCh to 2FFFh used by C51 family products
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
#endif // _USB_ATMEL_H_
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,342 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "arm_atsam_protocol.h"
 | 
			
		||||
#include "drivers/usb2422.h"
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
uint8_t usb_host_port;
 | 
			
		||||
 | 
			
		||||
#ifndef MD_BOOTLOADER
 | 
			
		||||
 | 
			
		||||
uint8_t usb_extra_state;
 | 
			
		||||
uint8_t usb_extra_manual;
 | 
			
		||||
uint8_t usb_gcr_auto;
 | 
			
		||||
 | 
			
		||||
#endif // MD_BOOTLOADER
 | 
			
		||||
 | 
			
		||||
uint16_t adc_extra;
 | 
			
		||||
 | 
			
		||||
void USB_Hub_init(void) {
 | 
			
		||||
    Gclk *   pgclk = GCLK;
 | 
			
		||||
    Mclk *   pmclk = MCLK;
 | 
			
		||||
    Port *   pport = PORT;
 | 
			
		||||
    Oscctrl *posc  = OSCCTRL;
 | 
			
		||||
    Usb *    pusb  = USB;
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_USB2422_INIT_BEGIN);
 | 
			
		||||
 | 
			
		||||
    while ((v_5v = adc_get(ADC_5V)) < ADC_5V_START_LEVEL) {
 | 
			
		||||
        DBGC(DC_USB2422_INIT_WAIT_5V_LOW);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // setup peripheral and synchronous bus clocks to USB
 | 
			
		||||
    pgclk->PCHCTRL[10].bit.GEN  = 0;
 | 
			
		||||
    pgclk->PCHCTRL[10].bit.CHEN = 1;
 | 
			
		||||
    pmclk->AHBMASK.bit.USB_     = 1;
 | 
			
		||||
    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].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].PINCFG[22].bit.PMUXEN = 1;
 | 
			
		||||
 | 
			
		||||
    // configure and enable DFLL for USB clock recovery mode at 48MHz
 | 
			
		||||
    posc->DFLLCTRLA.bit.ENABLE = 0;
 | 
			
		||||
    while (posc->DFLLSYNC.bit.ENABLE) {
 | 
			
		||||
        DBGC(DC_USB2422_INIT_OSC_SYNC_DISABLING);
 | 
			
		||||
    }
 | 
			
		||||
    while (posc->DFLLSYNC.bit.DFLLCTRLB) {
 | 
			
		||||
        DBGC(DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_1);
 | 
			
		||||
    }
 | 
			
		||||
    posc->DFLLCTRLB.bit.USBCRM = 1;
 | 
			
		||||
    while (posc->DFLLSYNC.bit.DFLLCTRLB) {
 | 
			
		||||
        DBGC(DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_2);
 | 
			
		||||
    }
 | 
			
		||||
    posc->DFLLCTRLB.bit.MODE = 1;
 | 
			
		||||
    while (posc->DFLLSYNC.bit.DFLLCTRLB) {
 | 
			
		||||
        DBGC(DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_3);
 | 
			
		||||
    }
 | 
			
		||||
    posc->DFLLCTRLB.bit.QLDIS = 0;
 | 
			
		||||
    while (posc->DFLLSYNC.bit.DFLLCTRLB) {
 | 
			
		||||
        DBGC(DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_4);
 | 
			
		||||
    }
 | 
			
		||||
    posc->DFLLCTRLB.bit.CCDIS = 1;
 | 
			
		||||
    posc->DFLLMUL.bit.MUL     = 0xBB80; // 4800 x 1KHz
 | 
			
		||||
    while (posc->DFLLSYNC.bit.DFLLMUL) {
 | 
			
		||||
        DBGC(DC_USB2422_INIT_OSC_SYNC_DFLLMUL);
 | 
			
		||||
    }
 | 
			
		||||
    posc->DFLLCTRLA.bit.ENABLE = 1;
 | 
			
		||||
    while (posc->DFLLSYNC.bit.ENABLE) {
 | 
			
		||||
        DBGC(DC_USB2422_INIT_OSC_SYNC_ENABLING);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pusb->DEVICE.CTRLA.bit.SWRST = 1;
 | 
			
		||||
    while (pusb->DEVICE.SYNCBUSY.bit.SWRST) {
 | 
			
		||||
        DBGC(DC_USB2422_INIT_USB_SYNC_SWRST);
 | 
			
		||||
    }
 | 
			
		||||
    while (pusb->DEVICE.CTRLA.bit.SWRST) {
 | 
			
		||||
        DBGC(DC_USB2422_INIT_USB_WAIT_SWRST);
 | 
			
		||||
    }
 | 
			
		||||
    // calibration from factory presets
 | 
			
		||||
    pusb->DEVICE.PADCAL.bit.TRANSN = (USB_FUSES_TRANSN_ADDR >> USB_FUSES_TRANSN_Pos) & USB_FUSES_TRANSN_Msk;
 | 
			
		||||
    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.CTRLA.bit.MODE    = 0;
 | 
			
		||||
    pusb->DEVICE.CTRLA.bit.ENABLE  = 1;
 | 
			
		||||
    while (pusb->DEVICE.SYNCBUSY.bit.ENABLE) {
 | 
			
		||||
        DBGC(DC_USB2422_INIT_USB_SYNC_ENABLING);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pusb->DEVICE.QOSCTRL.bit.DQOS = 2;
 | 
			
		||||
    pusb->DEVICE.QOSCTRL.bit.CQOS = 2;
 | 
			
		||||
 | 
			
		||||
    USB2422_init();
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
#ifndef MD_BOOTLOADER
 | 
			
		||||
 | 
			
		||||
    usb_extra_manual = 0;
 | 
			
		||||
    usb_gcr_auto     = 1;
 | 
			
		||||
 | 
			
		||||
#endif // MD_BOOTLOADER
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_USB2422_INIT_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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_WriteData();
 | 
			
		||||
    wait_us(2);
 | 
			
		||||
    sr_exp_data.bit.HUB_RESET_N = 1; // reset high to run
 | 
			
		||||
    SR_EXP_WriteData();
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_USB_RESET_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void USB_configure(void) {
 | 
			
		||||
    DBGC(DC_USB_CONFIGURE_BEGIN);
 | 
			
		||||
 | 
			
		||||
    USB2422_configure();
 | 
			
		||||
 | 
			
		||||
    adc_extra = 0;
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_USB_CONFIGURE_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t USB_active(void) {
 | 
			
		||||
    return USB2422_active();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void USB_set_host_by_voltage(void) {
 | 
			
		||||
    // UP is upstream device (HOST)
 | 
			
		||||
    // DN1 is downstream device (EXTRA)
 | 
			
		||||
    // DN2 is keyboard (KEYB)
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_USB_SET_HOST_BY_VOLTAGE_BEGIN);
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
    SR_EXP_WriteData();
 | 
			
		||||
 | 
			
		||||
    wait_ms(250);
 | 
			
		||||
 | 
			
		||||
    while ((v_5v = adc_get(ADC_5V)) < ADC_5V_START_LEVEL) {
 | 
			
		||||
        DBGC(DC_USB_SET_HOST_5V_LOW_WAITING);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    v_con_1 = adc_get(ADC_CON1);
 | 
			
		||||
    v_con_2 = adc_get(ADC_CON2);
 | 
			
		||||
 | 
			
		||||
    v_con_1_boot = v_con_1;
 | 
			
		||||
    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.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_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.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_WriteData();
 | 
			
		||||
 | 
			
		||||
        usb_host_port = USB_HOST_PORT_2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifndef MD_BOOTLOADER
 | 
			
		||||
    usb_extra_state = USB_EXTRA_STATE_DISABLED;
 | 
			
		||||
#endif // MD_BOOTLOADER
 | 
			
		||||
 | 
			
		||||
    USB_reset();
 | 
			
		||||
    USB_configure();
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_USB_SET_HOST_BY_VOLTAGE_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t USB_Hub_Port_Detect_Init(void) {
 | 
			
		||||
    uint32_t port_detect_retry_ms;
 | 
			
		||||
    uint32_t tmod;
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_PORT_DETECT_INIT_BEGIN);
 | 
			
		||||
 | 
			
		||||
    USB_set_host_by_voltage();
 | 
			
		||||
 | 
			
		||||
    port_detect_retry_ms = timer_read64() + PORT_DETECT_RETRY_INTERVAL;
 | 
			
		||||
 | 
			
		||||
    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();
 | 
			
		||||
        {
 | 
			
		||||
            // 1 flash for port 1 detected
 | 
			
		||||
            if (tmod > 500 && tmod < 600) {
 | 
			
		||||
                DBG_LED_ON;
 | 
			
		||||
            } else {
 | 
			
		||||
                DBG_LED_OFF;
 | 
			
		||||
            }
 | 
			
		||||
        } else if (v_con_2 > v_con_1) // Values updated from USB_set_host_by_voltage();
 | 
			
		||||
        {
 | 
			
		||||
            // 2 flash for port 2 detected
 | 
			
		||||
            if (tmod > 500 && tmod < 600) {
 | 
			
		||||
                DBG_LED_ON;
 | 
			
		||||
            } else if (tmod > 700 && tmod < 800) {
 | 
			
		||||
                DBG_LED_ON;
 | 
			
		||||
            } else {
 | 
			
		||||
                DBG_LED_OFF;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (timer_read64() > port_detect_retry_ms) {
 | 
			
		||||
            DBGC(DC_PORT_DETECT_INIT_FAILED);
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_PORT_DETECT_INIT_COMPLETE);
 | 
			
		||||
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef MD_BOOTLOADER
 | 
			
		||||
 | 
			
		||||
void USB_ExtraSetState(uint8_t state) {
 | 
			
		||||
    uint8_t state_save = state;
 | 
			
		||||
 | 
			
		||||
    if (state == USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG) state = USB_EXTRA_STATE_DISABLED;
 | 
			
		||||
 | 
			
		||||
    if (usb_host_port == USB_HOST_PORT_1)
 | 
			
		||||
        sr_exp_data.bit.E_VBUS_2 = state;
 | 
			
		||||
    else if (usb_host_port == USB_HOST_PORT_2)
 | 
			
		||||
        sr_exp_data.bit.E_VBUS_1 = state;
 | 
			
		||||
    else
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    sr_exp_data.bit.E_DN1_N = !state;
 | 
			
		||||
    SR_EXP_WriteData();
 | 
			
		||||
 | 
			
		||||
    usb_extra_state = state_save;
 | 
			
		||||
 | 
			
		||||
    if (usb_extra_state == USB_EXTRA_STATE_ENABLED)
 | 
			
		||||
        CDC_print("USB: Extra enabled\r\n");
 | 
			
		||||
    else if (usb_extra_state == USB_EXTRA_STATE_DISABLED) {
 | 
			
		||||
        CDC_print("USB: Extra disabled\r\n");
 | 
			
		||||
#    ifdef USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
        if (led_animation_breathing) gcr_breathe = gcr_desired;
 | 
			
		||||
#    endif
 | 
			
		||||
    } else if (usb_extra_state == USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG)
 | 
			
		||||
        CDC_print("USB: Extra disabled until replug\r\n");
 | 
			
		||||
    else
 | 
			
		||||
        CDC_print("USB: Extra state unknown\r\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void USB_HandleExtraDevice(void) {
 | 
			
		||||
    uint16_t adcval;
 | 
			
		||||
 | 
			
		||||
    if (usb_host_port == USB_HOST_PORT_1)
 | 
			
		||||
        adcval = adc_get(ADC_CON2);
 | 
			
		||||
    else if (usb_host_port == USB_HOST_PORT_2)
 | 
			
		||||
        adcval = adc_get(ADC_CON1);
 | 
			
		||||
    else
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    adc_extra = adc_extra * 0.9 + adcval * 0.1;
 | 
			
		||||
 | 
			
		||||
    // Check for a forced disable state (such as overload prevention)
 | 
			
		||||
    if (usb_extra_state == USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG) {
 | 
			
		||||
        // 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
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (usb_extra_manual) {
 | 
			
		||||
        if (usb_extra_state == USB_EXTRA_STATE_DISABLED) USB_ExtraSetState(USB_EXTRA_STATE_ENABLED);
 | 
			
		||||
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // dpf("a %i %i\r\n",adcval, adc_extra);
 | 
			
		||||
    if (usb_extra_state == USB_EXTRA_STATE_DISABLED && adc_extra < USB_EXTRA_ADC_THRESHOLD)
 | 
			
		||||
        USB_ExtraSetState(USB_EXTRA_STATE_ENABLED);
 | 
			
		||||
    else if (usb_extra_state == USB_EXTRA_STATE_ENABLED && adc_extra > USB_EXTRA_ADC_THRESHOLD)
 | 
			
		||||
        USB_ExtraSetState(USB_EXTRA_STATE_DISABLED);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // MD_BOOTLOADER
 | 
			
		||||
| 
						 | 
				
			
			@ -1,51 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _USB2422_H_
 | 
			
		||||
#define _USB2422_H_
 | 
			
		||||
 | 
			
		||||
#define REV_USB2422 0x100
 | 
			
		||||
 | 
			
		||||
#define PORT_DETECT_RETRY_INTERVAL 2000
 | 
			
		||||
 | 
			
		||||
#define USB_EXTRA_ADC_THRESHOLD 900
 | 
			
		||||
 | 
			
		||||
#define USB_EXTRA_STATE_DISABLED 0
 | 
			
		||||
#define USB_EXTRA_STATE_ENABLED 1
 | 
			
		||||
#define USB_EXTRA_STATE_UNKNOWN 2
 | 
			
		||||
#define USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG 3
 | 
			
		||||
 | 
			
		||||
#define USB_HOST_PORT_1 0
 | 
			
		||||
#define USB_HOST_PORT_2 1
 | 
			
		||||
#define USB_HOST_PORT_UNKNOWN 2
 | 
			
		||||
 | 
			
		||||
extern uint8_t usb_host_port;
 | 
			
		||||
extern uint8_t usb_extra_state;
 | 
			
		||||
extern uint8_t usb_extra_manual;
 | 
			
		||||
extern uint8_t usb_gcr_auto;
 | 
			
		||||
 | 
			
		||||
void     USB_Hub_init(void);
 | 
			
		||||
uint8_t  USB_Hub_Port_Detect_Init(void);
 | 
			
		||||
void     USB_reset(void);
 | 
			
		||||
void     USB_configure(void);
 | 
			
		||||
uint16_t USB_active(void);
 | 
			
		||||
void     USB_set_host_by_voltage(void);
 | 
			
		||||
uint16_t adc_get(uint8_t muxpos);
 | 
			
		||||
void     USB_HandleExtraDevice(void);
 | 
			
		||||
void     USB_ExtraSetState(uint8_t state);
 | 
			
		||||
 | 
			
		||||
#endif //_USB2422_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,101 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief Declaration of main function used by HID keyboard example
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _MAIN_H_
 | 
			
		||||
#define _MAIN_H_
 | 
			
		||||
 | 
			
		||||
// Enters the application in low power mode
 | 
			
		||||
// Callback called when USB host sets USB line in suspend state
 | 
			
		||||
void main_suspend_action(void);
 | 
			
		||||
 | 
			
		||||
// Called by UDD when the USB line exit of suspend state
 | 
			
		||||
void main_resume_action(void);
 | 
			
		||||
 | 
			
		||||
// Called when a start of frame is received on USB line
 | 
			
		||||
void main_sof_action(void);
 | 
			
		||||
 | 
			
		||||
// Called by UDC when USB Host request to enable remote wakeup
 | 
			
		||||
void main_remotewakeup_enable(void);
 | 
			
		||||
 | 
			
		||||
// Called by UDC when USB Host request to disable remote wakeup
 | 
			
		||||
void main_remotewakeup_disable(void);
 | 
			
		||||
 | 
			
		||||
extern volatile bool main_b_kbd_enable;
 | 
			
		||||
bool                 main_kbd_enable(void);
 | 
			
		||||
void                 main_kbd_disable(void);
 | 
			
		||||
 | 
			
		||||
#ifdef NKRO_ENABLE
 | 
			
		||||
extern volatile bool main_b_nkro_enable;
 | 
			
		||||
bool                 main_nkro_enable(void);
 | 
			
		||||
void                 main_nkro_disable(void);
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
extern volatile bool main_b_con_enable;
 | 
			
		||||
bool                 main_con_enable(void);
 | 
			
		||||
void                 main_con_disable(void);
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
#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 // _MAIN_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,488 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief USB protocol definitions.
 | 
			
		||||
 *
 | 
			
		||||
 * This file contains the USB definitions and data structures provided by the
 | 
			
		||||
 * USB 2.0 specification.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _USB_PROTOCOL_H_
 | 
			
		||||
#define _USB_PROTOCOL_H_
 | 
			
		||||
 | 
			
		||||
#include "usb_atmel.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \ingroup usb_group
 | 
			
		||||
 * \defgroup usb_protocol_group USB Protocol Definitions
 | 
			
		||||
 *
 | 
			
		||||
 * This module defines constants and data structures provided by the USB
 | 
			
		||||
 * 2.0 specification.
 | 
			
		||||
 *
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//! Value for field bcdUSB
 | 
			
		||||
#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)
 | 
			
		||||
 */
 | 
			
		||||
//! @{
 | 
			
		||||
#define NO_CLASS 0x00
 | 
			
		||||
#define CLASS_VENDOR_SPECIFIC 0xFF
 | 
			
		||||
#define NO_SUBCLASS 0x00
 | 
			
		||||
#define NO_PROTOCOL 0x00
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
//! \name IAD (Interface Association Descriptor) constants
 | 
			
		||||
//! @{
 | 
			
		||||
#define CLASS_IAD 0xEF
 | 
			
		||||
#define SUB_CLASS_IAD 0x02
 | 
			
		||||
#define PROTOCOL_IAD 0x01
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \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
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \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
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \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
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Standard USB requests (bRequest)
 | 
			
		||||
 */
 | 
			
		||||
enum usb_reqid {
 | 
			
		||||
    USB_REQ_GET_STATUS        = 0,
 | 
			
		||||
    USB_REQ_CLEAR_FEATURE     = 1,
 | 
			
		||||
    USB_REQ_SET_FEATURE       = 3,
 | 
			
		||||
    USB_REQ_SET_ADDRESS       = 5,
 | 
			
		||||
    USB_REQ_GET_DESCRIPTOR    = 6,
 | 
			
		||||
    USB_REQ_SET_DESCRIPTOR    = 7,
 | 
			
		||||
    USB_REQ_GET_CONFIGURATION = 8,
 | 
			
		||||
    USB_REQ_SET_CONFIGURATION = 9,
 | 
			
		||||
    USB_REQ_GET_INTERFACE     = 10,
 | 
			
		||||
    USB_REQ_SET_INTERFACE     = 11,
 | 
			
		||||
    USB_REQ_SYNCH_FRAME       = 12,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Standard USB device status flags
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
enum usb_device_status { USB_DEV_STATUS_BUS_POWERED = 0, USB_DEV_STATUS_SELF_POWERED = 1, USB_DEV_STATUS_REMOTEWAKEUP = 2 };
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Standard USB Interface status flags
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
enum usb_interface_status { USB_IFACE_STATUS_RESERVED = 0 };
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Standard USB endpoint status flags
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
enum usb_endpoint_status {
 | 
			
		||||
    USB_EP_STATUS_HALTED = 1,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Standard USB device feature flags
 | 
			
		||||
 *
 | 
			
		||||
 * \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_OTG_B_HNP_ENABLE      = 3,
 | 
			
		||||
    USB_DEV_FEATURE_OTG_A_HNP_SUPPORT     = 4,
 | 
			
		||||
    USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT = 5
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Test Mode possible on HS USB device
 | 
			
		||||
 *
 | 
			
		||||
 * \note valid for USB_DEV_FEATURE_TEST_MODE request.
 | 
			
		||||
 */
 | 
			
		||||
enum usb_device_hs_test_mode {
 | 
			
		||||
    USB_DEV_TEST_MODE_J            = 1,
 | 
			
		||||
    USB_DEV_TEST_MODE_K            = 2,
 | 
			
		||||
    USB_DEV_TEST_MODE_SE0_NAK      = 3,
 | 
			
		||||
    USB_DEV_TEST_MODE_PACKET       = 4,
 | 
			
		||||
    USB_DEV_TEST_MODE_FORCE_ENABLE = 5,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Standard USB endpoint feature/status flags
 | 
			
		||||
 */
 | 
			
		||||
enum usb_endpoint_feature {
 | 
			
		||||
    USB_EP_FEATURE_HALT = 0,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Standard USB Test Mode Selectors
 | 
			
		||||
 */
 | 
			
		||||
enum usb_test_mode_selector {
 | 
			
		||||
    USB_TEST_J            = 0x01,
 | 
			
		||||
    USB_TEST_K            = 0x02,
 | 
			
		||||
    USB_TEST_SE0_NAK      = 0x03,
 | 
			
		||||
    USB_TEST_PACKET       = 0x04,
 | 
			
		||||
    USB_TEST_FORCE_ENABLE = 0x05,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Standard USB descriptor types
 | 
			
		||||
 */
 | 
			
		||||
enum usb_descriptor_type {
 | 
			
		||||
    USB_DT_DEVICE                    = 1,
 | 
			
		||||
    USB_DT_CONFIGURATION             = 2,
 | 
			
		||||
    USB_DT_STRING                    = 3,
 | 
			
		||||
    USB_DT_INTERFACE                 = 4,
 | 
			
		||||
    USB_DT_ENDPOINT                  = 5,
 | 
			
		||||
    USB_DT_DEVICE_QUALIFIER          = 6,
 | 
			
		||||
    USB_DT_OTHER_SPEED_CONFIGURATION = 7,
 | 
			
		||||
    USB_DT_INTERFACE_POWER           = 8,
 | 
			
		||||
    USB_DT_OTG                       = 9,
 | 
			
		||||
    USB_DT_IAD                       = 0x0B,
 | 
			
		||||
    USB_DT_BOS                       = 0x0F,
 | 
			
		||||
    USB_DT_DEVICE_CAPABILITY         = 0x10,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief USB Device Capability types
 | 
			
		||||
 */
 | 
			
		||||
enum usb_capability_type {
 | 
			
		||||
    USB_DC_USB20_EXTENSION = 0x02,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief USB Device Capability - USB 2.0 Extension
 | 
			
		||||
 * To fill bmAttributes field of usb_capa_ext_desc_t structure.
 | 
			
		||||
 */
 | 
			
		||||
enum usb_capability_extension_attr {
 | 
			
		||||
    USB_DC_EXT_LPM = 0x00000002,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define HIRD_50_US 0
 | 
			
		||||
#define HIRD_125_US 1
 | 
			
		||||
#define HIRD_200_US 2
 | 
			
		||||
#define HIRD_275_US 3
 | 
			
		||||
#define HIRD_350_US 4
 | 
			
		||||
#define HIRD_425_US 5
 | 
			
		||||
#define HIRD_500_US 6
 | 
			
		||||
#define HIRD_575_US 7
 | 
			
		||||
#define HIRD_650_US 8
 | 
			
		||||
#define HIRD_725_US 9
 | 
			
		||||
#define HIRD_800_US 10
 | 
			
		||||
#define HIRD_875_US 11
 | 
			
		||||
#define HIRD_950_US 12
 | 
			
		||||
#define HIRD_1025_US 13
 | 
			
		||||
#define HIRD_1100_US 14
 | 
			
		||||
#define HIRD_1175_US 15
 | 
			
		||||
 | 
			
		||||
/** Fields definition from a LPM TOKEN  */
 | 
			
		||||
#define USB_LPM_ATTRIBUT_BLINKSTATE_MASK (0xF << 0)
 | 
			
		||||
#define USB_LPM_ATTRIBUT_FIRD_MASK (0xF << 4)
 | 
			
		||||
#define USB_LPM_ATTRIBUT_REMOTEWAKE_MASK (1 << 8)
 | 
			
		||||
#define USB_LPM_ATTRIBUT_BLINKSTATE(value) ((value & 0xF) << 0)
 | 
			
		||||
#define USB_LPM_ATTRIBUT_FIRD(value) ((value & 0xF) << 4)
 | 
			
		||||
#define USB_LPM_ATTRIBUT_REMOTEWAKE(value) ((value & 1) << 8)
 | 
			
		||||
#define USB_LPM_ATTRIBUT_BLINKSTATE_L1 USB_LPM_ATTRIBUT_BLINKSTATE(1)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Standard USB endpoint transfer types
 | 
			
		||||
 */
 | 
			
		||||
enum usb_ep_type {
 | 
			
		||||
    USB_EP_TYPE_CONTROL     = 0x00,
 | 
			
		||||
    USB_EP_TYPE_ISOCHRONOUS = 0x01,
 | 
			
		||||
    USB_EP_TYPE_BULK        = 0x02,
 | 
			
		||||
    USB_EP_TYPE_INTERRUPT   = 0x03,
 | 
			
		||||
    USB_EP_TYPE_MASK        = 0x03,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Standard USB language IDs for string descriptors
 | 
			
		||||
 */
 | 
			
		||||
enum usb_langid {
 | 
			
		||||
    USB_LANGID_EN_US = 0x0409, //!< English (United States)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Mask selecting the index part of an endpoint address
 | 
			
		||||
 */
 | 
			
		||||
#define USB_EP_ADDR_MASK 0x0f
 | 
			
		||||
 | 
			
		||||
//! \brief USB address identifier
 | 
			
		||||
typedef uint8_t usb_add_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Endpoint transfer direction is IN
 | 
			
		||||
 */
 | 
			
		||||
#define USB_EP_DIR_IN 0x80
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Endpoint transfer direction is OUT
 | 
			
		||||
 */
 | 
			
		||||
#define USB_EP_DIR_OUT 0x00
 | 
			
		||||
 | 
			
		||||
//! \brief Endpoint identifier
 | 
			
		||||
typedef uint8_t usb_ep_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Maximum length in bytes of a USB descriptor
 | 
			
		||||
 *
 | 
			
		||||
 * The maximum length of a USB descriptor is limited by the 8-bit
 | 
			
		||||
 * bLength field.
 | 
			
		||||
 */
 | 
			
		||||
#define USB_MAX_DESC_LEN 255
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 2-byte alignment requested for all USB structures.
 | 
			
		||||
 */
 | 
			
		||||
COMPILER_PACK_SET(1)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief A USB Device SETUP request
 | 
			
		||||
 *
 | 
			
		||||
 * The data payload of SETUP packets always follows this structure.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t bmRequestType;
 | 
			
		||||
    uint8_t bRequest;
 | 
			
		||||
    le16_t  wValue;
 | 
			
		||||
    le16_t  wIndex;
 | 
			
		||||
    le16_t  wLength;
 | 
			
		||||
} usb_setup_req_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Standard USB device descriptor structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t bLength;
 | 
			
		||||
    uint8_t bDescriptorType;
 | 
			
		||||
    le16_t  bcdUSB;
 | 
			
		||||
    uint8_t bDeviceClass;
 | 
			
		||||
    uint8_t bDeviceSubClass;
 | 
			
		||||
    uint8_t bDeviceProtocol;
 | 
			
		||||
    uint8_t bMaxPacketSize0;
 | 
			
		||||
    le16_t  idVendor;
 | 
			
		||||
    le16_t  idProduct;
 | 
			
		||||
    le16_t  bcdDevice;
 | 
			
		||||
    uint8_t iManufacturer;
 | 
			
		||||
    uint8_t iProduct;
 | 
			
		||||
    uint8_t iSerialNumber;
 | 
			
		||||
    uint8_t bNumConfigurations;
 | 
			
		||||
} usb_dev_desc_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Standard USB device qualifier descriptor structure
 | 
			
		||||
 *
 | 
			
		||||
 * This descriptor contains information about the device when running at
 | 
			
		||||
 * the "other" speed (i.e. if the device is currently operating at high
 | 
			
		||||
 * speed, this descriptor can be used to determine what would change if
 | 
			
		||||
 * the device was operating at full speed.)
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t bLength;
 | 
			
		||||
    uint8_t bDescriptorType;
 | 
			
		||||
    le16_t  bcdUSB;
 | 
			
		||||
    uint8_t bDeviceClass;
 | 
			
		||||
    uint8_t bDeviceSubClass;
 | 
			
		||||
    uint8_t bDeviceProtocol;
 | 
			
		||||
    uint8_t bMaxPacketSize0;
 | 
			
		||||
    uint8_t bNumConfigurations;
 | 
			
		||||
    uint8_t bReserved;
 | 
			
		||||
} usb_dev_qual_desc_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief USB Device BOS descriptor structure
 | 
			
		||||
 *
 | 
			
		||||
 * The BOS descriptor (Binary device Object Store) defines a root
 | 
			
		||||
 * descriptor that is similar to the configuration descriptor, and is
 | 
			
		||||
 * the base descriptor for accessing a family of related descriptors.
 | 
			
		||||
 * A host can read a BOS descriptor and learn from the wTotalLength field
 | 
			
		||||
 * the entire size of the device-level descriptor set, or it can read in
 | 
			
		||||
 * the entire BOS descriptor set of device capabilities.
 | 
			
		||||
 * The host accesses this descriptor using the GetDescriptor() request.
 | 
			
		||||
 * The descriptor type in the GetDescriptor() request is set to BOS.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t bLength;
 | 
			
		||||
    uint8_t bDescriptorType;
 | 
			
		||||
    le16_t  wTotalLength;
 | 
			
		||||
    uint8_t bNumDeviceCaps;
 | 
			
		||||
} usb_dev_bos_desc_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief USB Device Capabilities - USB 2.0 Extension Descriptor structure
 | 
			
		||||
 *
 | 
			
		||||
 * Defines the set of USB 1.1-specific device level capabilities.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t bLength;
 | 
			
		||||
    uint8_t bDescriptorType;
 | 
			
		||||
    uint8_t bDevCapabilityType;
 | 
			
		||||
    le32_t  bmAttributes;
 | 
			
		||||
} usb_dev_capa_ext_desc_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief USB Device LPM Descriptor structure
 | 
			
		||||
 *
 | 
			
		||||
 * The BOS descriptor and capabilities descriptors for LPM.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    usb_dev_bos_desc_t      bos;
 | 
			
		||||
    usb_dev_capa_ext_desc_t capa_ext;
 | 
			
		||||
} usb_dev_lpm_desc_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \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
 | 
			
		||||
} usb_association_desc_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Standard USB configuration descriptor structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t bLength;
 | 
			
		||||
    uint8_t bDescriptorType;
 | 
			
		||||
    le16_t  wTotalLength;
 | 
			
		||||
    uint8_t bNumInterfaces;
 | 
			
		||||
    uint8_t bConfigurationValue;
 | 
			
		||||
    uint8_t iConfiguration;
 | 
			
		||||
    uint8_t bmAttributes;
 | 
			
		||||
    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_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
 | 
			
		||||
} usb_iad_desc_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Standard USB interface descriptor structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t bLength;
 | 
			
		||||
    uint8_t bDescriptorType;
 | 
			
		||||
    uint8_t bInterfaceNumber;
 | 
			
		||||
    uint8_t bAlternateSetting;
 | 
			
		||||
    uint8_t bNumEndpoints;
 | 
			
		||||
    uint8_t bInterfaceClass;
 | 
			
		||||
    uint8_t bInterfaceSubClass;
 | 
			
		||||
    uint8_t bInterfaceProtocol;
 | 
			
		||||
    uint8_t iInterface;
 | 
			
		||||
} usb_iface_desc_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Standard USB endpoint descriptor structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t bLength;
 | 
			
		||||
    uint8_t bDescriptorType;
 | 
			
		||||
    uint8_t bEndpointAddress;
 | 
			
		||||
    uint8_t bmAttributes;
 | 
			
		||||
    le16_t  wMaxPacketSize;
 | 
			
		||||
    uint8_t bInterval;
 | 
			
		||||
} usb_ep_desc_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief A standard USB string descriptor structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t bLength;
 | 
			
		||||
    uint8_t bDescriptorType;
 | 
			
		||||
} usb_str_desc_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    usb_str_desc_t desc;
 | 
			
		||||
    le16_t         string[1];
 | 
			
		||||
} usb_str_lgid_desc_t;
 | 
			
		||||
 | 
			
		||||
COMPILER_PACK_RESET()
 | 
			
		||||
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
#endif /* _USB_PROTOCOL_H_ */
 | 
			
		||||
| 
						 | 
				
			
			@ -1,190 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief USB Communication Device Class (CDC) protocol definitions
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
#ifndef _USB_PROTOCOL_CDC_H_
 | 
			
		||||
#define _USB_PROTOCOL_CDC_H_
 | 
			
		||||
 | 
			
		||||
#include "compiler.h"
 | 
			
		||||
 | 
			
		||||
#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_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_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_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
 | 
			
		||||
#    define USB_REQ_CDC_SET_COMM_FEATURE 0x02
 | 
			
		||||
#    define USB_REQ_CDC_GET_COMM_FEATURE 0x03
 | 
			
		||||
#    define USB_REQ_CDC_CLEAR_COMM_FEATURE 0x04
 | 
			
		||||
#    define USB_REQ_CDC_SET_AUX_LINE_STATE 0x10
 | 
			
		||||
#    define USB_REQ_CDC_SET_HOOK_STATE 0x11
 | 
			
		||||
#    define USB_REQ_CDC_PULSE_SETUP 0x12
 | 
			
		||||
#    define USB_REQ_CDC_SEND_PULSE 0x13
 | 
			
		||||
#    define USB_REQ_CDC_SET_PULSE_TIME 0x14
 | 
			
		||||
#    define USB_REQ_CDC_RING_AUX_JACK 0x15
 | 
			
		||||
#    define USB_REQ_CDC_SET_LINE_CODING 0x20
 | 
			
		||||
#    define USB_REQ_CDC_GET_LINE_CODING 0x21
 | 
			
		||||
#    define USB_REQ_CDC_SET_CONTROL_LINE_STATE 0x22
 | 
			
		||||
#    define USB_REQ_CDC_SEND_BREAK 0x23
 | 
			
		||||
#    define USB_REQ_CDC_SET_RINGER_PARMS 0x30
 | 
			
		||||
#    define USB_REQ_CDC_GET_RINGER_PARMS 0x31
 | 
			
		||||
#    define USB_REQ_CDC_SET_OPERATION_PARMS 0x32
 | 
			
		||||
#    define USB_REQ_CDC_GET_OPERATION_PARMS 0x33
 | 
			
		||||
#    define USB_REQ_CDC_SET_LINE_PARMS 0x34
 | 
			
		||||
#    define USB_REQ_CDC_GET_LINE_PARMS 0x35
 | 
			
		||||
#    define USB_REQ_CDC_DIAL_DIGITS 0x36
 | 
			
		||||
#    define USB_REQ_CDC_SET_UNIT_PARAMETER 0x37
 | 
			
		||||
#    define USB_REQ_CDC_GET_UNIT_PARAMETER 0x38
 | 
			
		||||
#    define USB_REQ_CDC_CLEAR_UNIT_PARAMETER 0x39
 | 
			
		||||
#    define USB_REQ_CDC_GET_PROFILE 0x3A
 | 
			
		||||
#    define USB_REQ_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40
 | 
			
		||||
#    define USB_REQ_CDC_SET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x41
 | 
			
		||||
#    define USB_REQ_CDC_GET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x42
 | 
			
		||||
#    define USB_REQ_CDC_SET_ETHERNET_PACKET_FILTER 0x43
 | 
			
		||||
#    define USB_REQ_CDC_GET_ETHERNET_STATISTIC 0x44
 | 
			
		||||
#    define USB_REQ_CDC_SET_ATM_DATA_FORMAT 0x50
 | 
			
		||||
#    define USB_REQ_CDC_GET_ATM_DEVICE_STATISTICS 0x51
 | 
			
		||||
#    define USB_REQ_CDC_SET_ATM_DEFAULT_VC 0x52
 | 
			
		||||
#    define USB_REQ_CDC_GET_ATM_VC_STATISTICS 0x53
 | 
			
		||||
// Added bNotification codes according cdc spec 1.1 chapter 6.3
 | 
			
		||||
#    define USB_REQ_CDC_NOTIFY_RING_DETECT 0x09
 | 
			
		||||
#    define USB_REQ_CDC_NOTIFY_SERIAL_STATE 0x20
 | 
			
		||||
#    define USB_REQ_CDC_NOTIFY_CALL_STATE_CHANGE 0x28
 | 
			
		||||
#    define USB_REQ_CDC_NOTIFY_LINE_STATE_CHANGE 0x29
 | 
			
		||||
 | 
			
		||||
#    define CDC_CALL_MGMT_SUPPORTED (1 << 0)
 | 
			
		||||
#    define CDC_CALL_MGMT_OVER_DCI (1 << 1)
 | 
			
		||||
#    define CDC_ACM_SUPPORT_FEATURE_REQUESTS (1 << 0)
 | 
			
		||||
#    define CDC_ACM_SUPPORT_LINE_REQUESTS (1 << 1)
 | 
			
		||||
#    define CDC_ACM_SUPPORT_SENDBREAK_REQUESTS (1 << 2)
 | 
			
		||||
#    define CDC_ACM_SUPPORT_NOTIFY_REQUESTS (1 << 3)
 | 
			
		||||
 | 
			
		||||
#    pragma pack(push, 1)
 | 
			
		||||
typedef struct {
 | 
			
		||||
    le32_t  dwDTERate;
 | 
			
		||||
    uint8_t bCharFormat;
 | 
			
		||||
    uint8_t bParityType;
 | 
			
		||||
    uint8_t bDataBits;
 | 
			
		||||
} usb_cdc_line_coding_t;
 | 
			
		||||
#    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
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint16_t value;
 | 
			
		||||
} usb_cdc_control_signal_t;
 | 
			
		||||
 | 
			
		||||
#    define CDC_CTRL_SIGNAL_ACTIVATE_CARRIER (1 << 1)
 | 
			
		||||
#    define CDC_CTRL_SIGNAL_DTE_PRESENT (1 << 0)
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t bmRequestType;
 | 
			
		||||
    uint8_t bNotification;
 | 
			
		||||
    le16_t  wValue;
 | 
			
		||||
    le16_t  wIndex;
 | 
			
		||||
    le16_t  wLength;
 | 
			
		||||
} usb_cdc_notify_msg_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    usb_cdc_notify_msg_t header;
 | 
			
		||||
    le16_t               value;
 | 
			
		||||
} usb_cdc_notify_serial_state_t;
 | 
			
		||||
 | 
			
		||||
#    define CDC_SERIAL_STATE_DCD CPU_TO_LE16((1 << 0))
 | 
			
		||||
#    define CDC_SERIAL_STATE_DSR CPU_TO_LE16((1 << 1))
 | 
			
		||||
#    define CDC_SERIAL_STATE_BREAK CPU_TO_LE16((1 << 2))
 | 
			
		||||
#    define CDC_SERIAL_STATE_RING CPU_TO_LE16((1 << 3))
 | 
			
		||||
#    define CDC_SERIAL_STATE_FRAMING CPU_TO_LE16((1 << 4))
 | 
			
		||||
#    define CDC_SERIAL_STATE_PARITY CPU_TO_LE16((1 << 5))
 | 
			
		||||
#    define CDC_SERIAL_STATE_OVERRUN CPU_TO_LE16((1 << 6))
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // _USB_PROTOCOL_CDC_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,317 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief USB Human Interface Device (HID) protocol definitions.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _USB_PROTOCOL_HID_H_
 | 
			
		||||
#define _USB_PROTOCOL_HID_H_
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \ingroup usb_protocol_group
 | 
			
		||||
 * \defgroup usb_hid_protocol USB Human Interface Device (HID)
 | 
			
		||||
 * protocol definitions
 | 
			
		||||
 * \brief USB Human Interface Device (HID) protocol definitions
 | 
			
		||||
 *
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//! \name Possible Class value
 | 
			
		||||
//@{
 | 
			
		||||
#define HID_CLASS 0x03
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
//! \name Possible SubClass value
 | 
			
		||||
//@{
 | 
			
		||||
//! Interface subclass NO support BOOT protocol
 | 
			
		||||
#define HID_SUB_CLASS_NOBOOT 0x00
 | 
			
		||||
//! Interface subclass support BOOT protocol
 | 
			
		||||
#define HID_SUB_CLASS_BOOT 0x01
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
//! \name Possible protocol value
 | 
			
		||||
//@{
 | 
			
		||||
//! Protocol generic standard
 | 
			
		||||
#define HID_PROTOCOL_GENERIC 0x00
 | 
			
		||||
//! Protocol keyboard standard
 | 
			
		||||
#define HID_PROTOCOL_KEYBOARD 0x01
 | 
			
		||||
//! Protocol mouse standard
 | 
			
		||||
#define HID_PROTOCOL_MOUSE 0x02
 | 
			
		||||
//@}
 | 
			
		||||
 | 
			
		||||
//! \brief Hid USB requests (bRequest)
 | 
			
		||||
enum usb_reqid_hid {
 | 
			
		||||
    USB_REQ_HID_GET_REPORT   = 0x01,
 | 
			
		||||
    USB_REQ_HID_GET_IDLE     = 0x02,
 | 
			
		||||
    USB_REQ_HID_GET_PROTOCOL = 0x03,
 | 
			
		||||
    USB_REQ_HID_SET_REPORT   = 0x09,
 | 
			
		||||
    USB_REQ_HID_SET_IDLE     = 0x0A,
 | 
			
		||||
    USB_REQ_HID_SET_PROTOCOL = 0x0B,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//! \brief HID USB descriptor types
 | 
			
		||||
enum usb_descriptor_type_hid {
 | 
			
		||||
    USB_DT_HID          = 0x21,
 | 
			
		||||
    USB_DT_HID_REPORT   = 0x22,
 | 
			
		||||
    USB_DT_HID_PHYSICAL = 0x23,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//! \brief HID Type for report descriptor
 | 
			
		||||
enum usb_hid_item_report_type {
 | 
			
		||||
    USB_HID_ITEM_REPORT_TYPE_MAIN   = 0,
 | 
			
		||||
    USB_HID_ITEM_REPORT_TYPE_GLOBAL = 1,
 | 
			
		||||
    USB_HID_ITEM_REPORT_TYPE_LOCAL  = 2,
 | 
			
		||||
    USB_HID_ITEM_REPORT_TYPE_LONG   = 3,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//! \brief HID report type
 | 
			
		||||
enum usb_hid_report_type {
 | 
			
		||||
    USB_HID_REPORT_TYPE_INPUT   = 1,
 | 
			
		||||
    USB_HID_REPORT_TYPE_OUTPUT  = 2,
 | 
			
		||||
    USB_HID_REPORT_TYPE_FEATURE = 3,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//! \brief HID protocol
 | 
			
		||||
enum usb_hid_protocol {
 | 
			
		||||
    USB_HID_PROCOTOL_BOOT   = 0,
 | 
			
		||||
    USB_HID_PROCOTOL_REPORT = 1,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
} usb_hid_descriptor_t;
 | 
			
		||||
 | 
			
		||||
COMPILER_PACK_RESET()
 | 
			
		||||
 | 
			
		||||
//! \name HID Report type
 | 
			
		||||
//! Used by SETUP_HID_GET_REPORT & SETUP_HID_SET_REPORT
 | 
			
		||||
//! @{
 | 
			
		||||
#define REPORT_TYPE_INPUT 0x01
 | 
			
		||||
#define REPORT_TYPE_OUTPUT 0x02
 | 
			
		||||
#define REPORT_TYPE_FEATURE 0x03
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
//! \name Constants of field DESCRIPTOR_HID
 | 
			
		||||
//! @{
 | 
			
		||||
//! Numeric expression identifying the HID Class
 | 
			
		||||
//! Specification release (here V1.11)
 | 
			
		||||
#define USB_HID_BDC_V1_11 0x0111
 | 
			
		||||
//! Numeric expression specifying the number of class descriptors
 | 
			
		||||
//! Note: Always at least one i.e. Report descriptor.
 | 
			
		||||
#define USB_HID_NUM_DESC 0x01
 | 
			
		||||
 | 
			
		||||
//! \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_COUNTRY_TURKISH_F \
 | 
			
		||||
    35 // Turkish-F
 | 
			
		||||
       //! @}
 | 
			
		||||
       //! @}
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
//! \name HID KEYS values
 | 
			
		||||
//! @{
 | 
			
		||||
#define HID_A 0x04
 | 
			
		||||
#define HID_B 0x05
 | 
			
		||||
#define HID_C 0x06
 | 
			
		||||
#define HID_D 0x07
 | 
			
		||||
#define HID_E 0x08
 | 
			
		||||
#define HID_F 0x09
 | 
			
		||||
#define HID_G 0x0A
 | 
			
		||||
#define HID_H 0x0B
 | 
			
		||||
#define HID_I 0x0C
 | 
			
		||||
#define HID_J 0x0D
 | 
			
		||||
#define HID_K 0x0E
 | 
			
		||||
#define HID_L 0x0F
 | 
			
		||||
#define HID_M 0x10
 | 
			
		||||
#define HID_N 0x11
 | 
			
		||||
#define HID_O 0x12
 | 
			
		||||
#define HID_P 0x13
 | 
			
		||||
#define HID_Q 0x14
 | 
			
		||||
#define HID_R 0x15
 | 
			
		||||
#define HID_S 0x16
 | 
			
		||||
#define HID_T 0x17
 | 
			
		||||
#define HID_U 0x18
 | 
			
		||||
#define HID_V 0x19
 | 
			
		||||
#define HID_W 0x1A
 | 
			
		||||
#define HID_X 0x1B
 | 
			
		||||
#define HID_Y 0x1C
 | 
			
		||||
#define HID_Z 0x1D
 | 
			
		||||
#define HID_1 30
 | 
			
		||||
#define HID_2 31
 | 
			
		||||
#define HID_3 32
 | 
			
		||||
#define HID_4 33
 | 
			
		||||
#define HID_5 34
 | 
			
		||||
#define HID_6 35
 | 
			
		||||
#define HID_7 36
 | 
			
		||||
#define HID_8 37
 | 
			
		||||
#define HID_9 38
 | 
			
		||||
#define HID_0 39
 | 
			
		||||
#define HID_ENTER 40
 | 
			
		||||
#define HID_ESCAPE 41
 | 
			
		||||
#define HID_BACKSPACE 42
 | 
			
		||||
#define HID_TAB 43
 | 
			
		||||
#define HID_SPACEBAR 44
 | 
			
		||||
#define HID_UNDERSCORE 45
 | 
			
		||||
#define HID_PLUS 46
 | 
			
		||||
#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_TILDE 53
 | 
			
		||||
#define HID_COMMA 54
 | 
			
		||||
#define HID_DOT 55
 | 
			
		||||
#define HID_SLASH 56
 | 
			
		||||
#define HID_CAPS_LOCK 57
 | 
			
		||||
#define HID_F1 58
 | 
			
		||||
#define HID_F2 59
 | 
			
		||||
#define HID_F3 60
 | 
			
		||||
#define HID_F4 61
 | 
			
		||||
#define HID_F5 62
 | 
			
		||||
#define HID_F6 63
 | 
			
		||||
#define HID_F7 64
 | 
			
		||||
#define HID_F8 65
 | 
			
		||||
#define HID_F9 66
 | 
			
		||||
#define HID_F10 67
 | 
			
		||||
#define HID_F11 68
 | 
			
		||||
#define HID_F12 69
 | 
			
		||||
#define HID_PRINTSCREEN 70
 | 
			
		||||
#define HID_SCROLL_LOCK 71
 | 
			
		||||
#define HID_PAUSE 72
 | 
			
		||||
#define HID_INSERT 73
 | 
			
		||||
#define HID_HOME 74
 | 
			
		||||
#define HID_PAGEUP 75
 | 
			
		||||
#define HID_DELETE 76
 | 
			
		||||
#define HID_END 77
 | 
			
		||||
#define HID_PAGEDOWN 78
 | 
			
		||||
#define HID_RIGHT 79
 | 
			
		||||
#define HID_LEFT 80
 | 
			
		||||
#define HID_DOWN 81
 | 
			
		||||
#define HID_UP 82
 | 
			
		||||
#define HID_KEYPAD_NUM_LOCK 83
 | 
			
		||||
#define HID_KEYPAD_DIVIDE 84
 | 
			
		||||
#define HID_KEYPAD_AT 85
 | 
			
		||||
#define HID_KEYPAD_MULTIPLY 85
 | 
			
		||||
#define HID_KEYPAD_MINUS 86
 | 
			
		||||
#define HID_KEYPAD_PLUS 87
 | 
			
		||||
#define HID_KEYPAD_ENTER 88
 | 
			
		||||
#define HID_KEYPAD_1 89
 | 
			
		||||
#define HID_KEYPAD_2 90
 | 
			
		||||
#define HID_KEYPAD_3 91
 | 
			
		||||
#define HID_KEYPAD_4 92
 | 
			
		||||
#define HID_KEYPAD_5 93
 | 
			
		||||
#define HID_KEYPAD_6 94
 | 
			
		||||
#define HID_KEYPAD_7 95
 | 
			
		||||
#define HID_KEYPAD_8 96
 | 
			
		||||
#define HID_KEYPAD_9 97
 | 
			
		||||
#define HID_KEYPAD_0 98
 | 
			
		||||
 | 
			
		||||
//! \name HID modifier values
 | 
			
		||||
//! @{
 | 
			
		||||
#define HID_MODIFIER_NONE 0x00
 | 
			
		||||
#define HID_MODIFIER_LEFT_CTRL 0x01
 | 
			
		||||
#define HID_MODIFIER_LEFT_SHIFT 0x02
 | 
			
		||||
#define HID_MODIFIER_LEFT_ALT 0x04
 | 
			
		||||
#define HID_MODIFIER_LEFT_UI 0x08
 | 
			
		||||
#define HID_MODIFIER_RIGHT_CTRL 0x10
 | 
			
		||||
#define HID_MODIFIER_RIGHT_SHIFT 0x20
 | 
			
		||||
#define HID_MODIFIER_RIGHT_ALT 0x40
 | 
			
		||||
#define HID_MODIFIER_RIGHT_UI 0x80
 | 
			
		||||
//! @}
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
//! \name HID KEYS values
 | 
			
		||||
//! @{
 | 
			
		||||
#define HID_LED_NUM_LOCK (1 << 0)
 | 
			
		||||
#define HID_LED_CAPS_LOCK (1 << 1)
 | 
			
		||||
#define HID_LED_SCROLL_LOCK (1 << 2)
 | 
			
		||||
#define HID_LED_COMPOSE (1 << 3)
 | 
			
		||||
#define HID_LED_KANA (1 << 4)
 | 
			
		||||
//! @}
 | 
			
		||||
 | 
			
		||||
#endif // _USB_PROTOCOL_HID_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,49 +0,0 @@
 | 
			
		|||
#include "samd51j18a.h"
 | 
			
		||||
#include "string.h"
 | 
			
		||||
#include "usb_util.h"
 | 
			
		||||
 | 
			
		||||
char digit(int d, int radix) {
 | 
			
		||||
    if (d < 10) {
 | 
			
		||||
        return d + '0';
 | 
			
		||||
    } else {
 | 
			
		||||
        return d - 10 + 'A';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int UTIL_ltoa_radix(int64_t value, char *dest, int radix) {
 | 
			
		||||
    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
 | 
			
		||||
        value = -value;
 | 
			
		||||
 | 
			
		||||
    do // write least significant digit of value that's left
 | 
			
		||||
    {
 | 
			
		||||
        d        = (value % radix);
 | 
			
		||||
        buf[--c] = digit(d, radix);
 | 
			
		||||
        value /= radix;
 | 
			
		||||
    } while (value);
 | 
			
		||||
 | 
			
		||||
    if (original < 0) buf[--c] = '-';
 | 
			
		||||
 | 
			
		||||
    size = last - c + 1; // includes null at end
 | 
			
		||||
    memcpy(dest, &buf[c], last - c + 1);
 | 
			
		||||
 | 
			
		||||
    return (size - 1); // without null termination
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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_utoa(uint32_t value, char *dest) {
 | 
			
		||||
    return UTIL_ltoa_radix((int64_t)value, dest, 10);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +0,0 @@
 | 
			
		|||
#ifndef _USB_UTIL_H_
 | 
			
		||||
#define _USB_UTIL_H_
 | 
			
		||||
 | 
			
		||||
int UTIL_ltoa_radix(int64_t value, char *dest, int radix);
 | 
			
		||||
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_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +0,0 @@
 | 
			
		|||
#ifndef _wait_api_h_
 | 
			
		||||
#define _wait_api_h_
 | 
			
		||||
 | 
			
		||||
void wait_ms(uint64_t msec);
 | 
			
		||||
void wait_us(uint16_t usec);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -279,8 +279,6 @@ enum usb_endpoints {
 | 
			
		|||
#    define MAX_ENDPOINTS USB_MAX_ENDPOINTS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// TODO - ARM_ATSAM
 | 
			
		||||
 | 
			
		||||
#if (NEXT_EPNUM - 1) > MAX_ENDPOINTS
 | 
			
		||||
#    error There are not enough available endpoints to support all functions. Please disable one or more of the following: Mouse Keys, Extra Keys, Console, NKRO, MIDI, Serial, Steno
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue