diff options
| author | Joel Challis <git@zvecr.com> | 2024-09-02 03:48:17 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-02 03:48:17 +0100 |
| commit | 3bd303f204a59ed950934f5da4c299a8be33b363 (patch) | |
| tree | 17ff660931b925909be4a75fba55bd67441bf2bb /tmk_core | |
| parent | 096aca63c5d7789669d90ef5f128189be85b7a35 (diff) | |
Remove `arm_atsam` platform (#24337)
Diffstat (limited to 'tmk_core')
57 files changed, 0 insertions, 16283 deletions
diff --git a/tmk_core/protocol/arm_atsam/adc.c b/tmk_core/protocol/arm_atsam/adc.c deleted file mode 100644 index 3afcbddf10..0000000000 --- a/tmk_core/protocol/arm_atsam/adc.c +++ /dev/null | |||
| @@ -1,115 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include "arm_atsam_protocol.h" | ||
| 19 | |||
| 20 | uint16_t v_5v; | ||
| 21 | uint16_t v_5v_avg; | ||
| 22 | uint16_t v_con_1; | ||
| 23 | uint16_t v_con_2; | ||
| 24 | uint16_t v_con_1_boot; | ||
| 25 | uint16_t v_con_2_boot; | ||
| 26 | |||
| 27 | void ADC0_clock_init(void) { | ||
| 28 | DBGC(DC_ADC0_CLOCK_INIT_BEGIN); | ||
| 29 | |||
| 30 | MCLK->APBDMASK.bit.ADC0_ = 1; // ADC0 Clock Enable | ||
| 31 | |||
| 32 | GCLK->PCHCTRL[ADC0_GCLK_ID].bit.GEN = GEN_OSC0; // Select generator clock | ||
| 33 | GCLK->PCHCTRL[ADC0_GCLK_ID].bit.CHEN = 1; // Enable peripheral clock | ||
| 34 | |||
| 35 | DBGC(DC_ADC0_CLOCK_INIT_COMPLETE); | ||
| 36 | } | ||
| 37 | |||
| 38 | void ADC0_init(void) { | ||
| 39 | DBGC(DC_ADC0_INIT_BEGIN); | ||
| 40 | |||
| 41 | // MCU | ||
| 42 | PORT->Group[1].DIRCLR.reg = 1 << 0; // PB00 as input 5V | ||
| 43 | PORT->Group[1].DIRCLR.reg = 1 << 1; // PB01 as input CON2 | ||
| 44 | PORT->Group[1].DIRCLR.reg = 1 << 2; // PB02 as input CON1 | ||
| 45 | PORT->Group[1].PMUX[0].bit.PMUXE = 1; // PB00 mux select B ADC 5V | ||
| 46 | PORT->Group[1].PMUX[0].bit.PMUXO = 1; // PB01 mux select B ADC CON2 | ||
| 47 | PORT->Group[1].PMUX[1].bit.PMUXE = 1; // PB02 mux select B ADC CON1 | ||
| 48 | PORT->Group[1].PINCFG[0].bit.PMUXEN = 1; // PB01 mux ADC Enable 5V | ||
| 49 | PORT->Group[1].PINCFG[1].bit.PMUXEN = 1; // PB01 mux ADC Enable CON2 | ||
| 50 | PORT->Group[1].PINCFG[2].bit.PMUXEN = 1; // PB02 mux ADC Enable CON1 | ||
| 51 | |||
| 52 | // ADC | ||
| 53 | ADC0->CTRLA.bit.SWRST = 1; | ||
| 54 | while (ADC0->SYNCBUSY.bit.SWRST) { | ||
| 55 | DBGC(DC_ADC0_SWRST_SYNCING_1); | ||
| 56 | } | ||
| 57 | while (ADC0->CTRLA.bit.SWRST) { | ||
| 58 | DBGC(DC_ADC0_SWRST_SYNCING_2); | ||
| 59 | } | ||
| 60 | |||
| 61 | // Clock divide | ||
| 62 | ADC0->CTRLA.bit.PRESCALER = ADC_CTRLA_PRESCALER_DIV2_Val; | ||
| 63 | |||
| 64 | // Averaging | ||
| 65 | ADC0->AVGCTRL.bit.SAMPLENUM = ADC_AVGCTRL_SAMPLENUM_4_Val; | ||
| 66 | while (ADC0->SYNCBUSY.bit.AVGCTRL) { | ||
| 67 | DBGC(DC_ADC0_AVGCTRL_SYNCING_1); | ||
| 68 | } | ||
| 69 | if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_1_Val) | ||
| 70 | ADC0->AVGCTRL.bit.ADJRES = 0; | ||
| 71 | else if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_2_Val) | ||
| 72 | ADC0->AVGCTRL.bit.ADJRES = 1; | ||
| 73 | else if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_4_Val) | ||
| 74 | ADC0->AVGCTRL.bit.ADJRES = 2; | ||
| 75 | else if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_8_Val) | ||
| 76 | ADC0->AVGCTRL.bit.ADJRES = 3; | ||
| 77 | else | ||
| 78 | ADC0->AVGCTRL.bit.ADJRES = 4; | ||
| 79 | while (ADC0->SYNCBUSY.bit.AVGCTRL) { | ||
| 80 | DBGC(DC_ADC0_AVGCTRL_SYNCING_2); | ||
| 81 | } | ||
| 82 | |||
| 83 | // Settling | ||
| 84 | ADC0->SAMPCTRL.bit.SAMPLEN = 45; // Sampling Time Length: 1-63, 1 ADC CLK per | ||
| 85 | while (ADC0->SYNCBUSY.bit.SAMPCTRL) { | ||
| 86 | DBGC(DC_ADC0_SAMPCTRL_SYNCING_1); | ||
| 87 | } | ||
| 88 | |||
| 89 | // Load factory calibration data | ||
| 90 | ADC0->CALIB.bit.BIASCOMP = ((*(uint32_t *)ADC0_FUSES_BIASCOMP_ADDR) & ADC0_FUSES_BIASCOMP_Msk) >> ADC0_FUSES_BIASCOMP_Pos; | ||
| 91 | ADC0->CALIB.bit.BIASR2R = ((*(uint32_t *)ADC0_FUSES_BIASR2R_ADDR) & ADC0_FUSES_BIASR2R_Msk) >> ADC0_FUSES_BIASR2R_Pos; | ||
| 92 | ADC0->CALIB.bit.BIASREFBUF = ((*(uint32_t *)ADC0_FUSES_BIASREFBUF_ADDR) & ADC0_FUSES_BIASREFBUF_Msk) >> ADC0_FUSES_BIASREFBUF_Pos; | ||
| 93 | |||
| 94 | // Enable | ||
| 95 | ADC0->CTRLA.bit.ENABLE = 1; | ||
| 96 | while (ADC0->SYNCBUSY.bit.ENABLE) { | ||
| 97 | DBGC(DC_ADC0_ENABLE_SYNCING_1); | ||
| 98 | } | ||
| 99 | |||
| 100 | DBGC(DC_ADC0_INIT_COMPLETE); | ||
| 101 | } | ||
| 102 | |||
| 103 | uint16_t adc_get(uint8_t muxpos) { | ||
| 104 | ADC0->INPUTCTRL.bit.MUXPOS = muxpos; | ||
| 105 | while (ADC0->SYNCBUSY.bit.INPUTCTRL) { | ||
| 106 | } | ||
| 107 | |||
| 108 | ADC0->SWTRIG.bit.START = 1; | ||
| 109 | while (ADC0->SYNCBUSY.bit.SWTRIG) { | ||
| 110 | } | ||
| 111 | while (!ADC0->INTFLAG.bit.RESRDY) { | ||
| 112 | } | ||
| 113 | |||
| 114 | return ADC0->RESULT.reg; | ||
| 115 | } | ||
diff --git a/tmk_core/protocol/arm_atsam/adc.h b/tmk_core/protocol/arm_atsam/adc.h deleted file mode 100644 index 74fbb0e66f..0000000000 --- a/tmk_core/protocol/arm_atsam/adc.h +++ /dev/null | |||
| @@ -1,37 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef _ADC_H_ | ||
| 19 | #define _ADC_H_ | ||
| 20 | |||
| 21 | #define ADC_5V_START_LEVEL 2365 | ||
| 22 | |||
| 23 | #define ADC_5V ADC_INPUTCTRL_MUXPOS_AIN12_Val | ||
| 24 | #define ADC_CON1 ADC_INPUTCTRL_MUXPOS_AIN14_Val | ||
| 25 | #define ADC_CON2 ADC_INPUTCTRL_MUXPOS_AIN13_Val | ||
| 26 | |||
| 27 | extern uint16_t v_5v; | ||
| 28 | extern uint16_t v_5v_avg; | ||
| 29 | extern uint16_t v_con_1; | ||
| 30 | extern uint16_t v_con_2; | ||
| 31 | extern uint16_t v_con_1_boot; | ||
| 32 | extern uint16_t v_con_2_boot; | ||
| 33 | |||
| 34 | void ADC0_clock_init(void); | ||
| 35 | void ADC0_init(void); | ||
| 36 | |||
| 37 | #endif //_ADC_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/arm_atsam.mk b/tmk_core/protocol/arm_atsam/arm_atsam.mk deleted file mode 100644 index ffd1fa9f50..0000000000 --- a/tmk_core/protocol/arm_atsam/arm_atsam.mk +++ /dev/null | |||
| @@ -1,31 +0,0 @@ | |||
| 1 | ARM_ATSAM_DIR = protocol/arm_atsam | ||
| 2 | |||
| 3 | SRC += $(ARM_ATSAM_DIR)/adc.c | ||
| 4 | SRC += $(ARM_ATSAM_DIR)/clks.c | ||
| 5 | SRC += $(ARM_ATSAM_DIR)/d51_util.c | ||
| 6 | SRC += $(ARM_ATSAM_DIR)/i2c_master.c | ||
| 7 | ifeq ($(RGB_MATRIX_DRIVER),custom) | ||
| 8 | SRC += $(ARM_ATSAM_DIR)/md_rgb_matrix_programs.c | ||
| 9 | SRC += $(ARM_ATSAM_DIR)/md_rgb_matrix.c | ||
| 10 | endif | ||
| 11 | SRC += $(ARM_ATSAM_DIR)/main_arm_atsam.c | ||
| 12 | SRC += $(ARM_ATSAM_DIR)/shift_register.c | ||
| 13 | SRC += $(ARM_ATSAM_DIR)/spi_master.c | ||
| 14 | SRC += $(ARM_ATSAM_DIR)/startup.c | ||
| 15 | |||
| 16 | SRC += $(ARM_ATSAM_DIR)/usb/main_usb.c | ||
| 17 | SRC += $(ARM_ATSAM_DIR)/usb/udc.c | ||
| 18 | SRC += $(ARM_ATSAM_DIR)/usb/udi_cdc.c | ||
| 19 | SRC += $(ARM_ATSAM_DIR)/usb/udi_hid.c | ||
| 20 | SRC += $(ARM_ATSAM_DIR)/usb/udi_hid_kbd.c | ||
| 21 | SRC += $(ARM_ATSAM_DIR)/usb/udi_hid_kbd_desc.c | ||
| 22 | SRC += $(ARM_ATSAM_DIR)/usb/ui.c | ||
| 23 | SRC += $(ARM_ATSAM_DIR)/usb/usb.c | ||
| 24 | SRC += $(ARM_ATSAM_DIR)/usb/usb_device_udd.c | ||
| 25 | SRC += $(ARM_ATSAM_DIR)/usb/usb_hub.c | ||
| 26 | SRC += $(ARM_ATSAM_DIR)/usb/usb_util.c | ||
| 27 | |||
| 28 | SRC += $(DRIVER_PATH)/usb2422.c | ||
| 29 | |||
| 30 | # Search Path | ||
| 31 | VPATH += $(TMK_DIR)/$(ARM_ATSAM_DIR) | ||
diff --git a/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h b/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h deleted file mode 100644 index db9827f6a2..0000000000 --- a/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h +++ /dev/null | |||
| @@ -1,47 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef _ARM_ATSAM_PROTOCOL_H_ | ||
| 19 | #define _ARM_ATSAM_PROTOCOL_H_ | ||
| 20 | |||
| 21 | #include "samd51j18a.h" | ||
| 22 | |||
| 23 | #include "timer.h" | ||
| 24 | #include "d51_util.h" | ||
| 25 | #include "clks.h" | ||
| 26 | #include "wait.h" | ||
| 27 | #include "adc.h" | ||
| 28 | #include "i2c_master.h" | ||
| 29 | #include "shift_register.h" | ||
| 30 | |||
| 31 | #include "./usb/usb_hub.h" | ||
| 32 | |||
| 33 | #ifndef MD_BOOTLOADER | ||
| 34 | |||
| 35 | # include "main_arm_atsam.h" | ||
| 36 | # ifdef RGB_MATRIX_ENABLE | ||
| 37 | # include "md_rgb_matrix.h" | ||
| 38 | # include "rgb_matrix.h" | ||
| 39 | # endif | ||
| 40 | # include "issi3733_driver.h" | ||
| 41 | # include "./usb/compiler.h" | ||
| 42 | # include "./usb/udc.h" | ||
| 43 | # include "./usb/udi_cdc.h" | ||
| 44 | |||
| 45 | #endif // MD_BOOTLOADER | ||
| 46 | |||
| 47 | #endif //_ARM_ATSAM_PROTOCOL_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/clks.c b/tmk_core/protocol/arm_atsam/clks.c deleted file mode 100644 index 9b9475c616..0000000000 --- a/tmk_core/protocol/arm_atsam/clks.c +++ /dev/null | |||
| @@ -1,436 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include "arm_atsam_protocol.h" | ||
| 19 | |||
| 20 | #include <string.h> | ||
| 21 | |||
| 22 | volatile clk_t system_clks; | ||
| 23 | volatile uint64_t ms_clk; | ||
| 24 | uint32_t usec_delay_mult; | ||
| 25 | #define USEC_DELAY_LOOP_CYCLES 3 // Sum of instruction cycles in us delay loop | ||
| 26 | |||
| 27 | const uint32_t sercom_apbbase[] = {(uint32_t)SERCOM0, (uint32_t)SERCOM1, (uint32_t)SERCOM2, (uint32_t)SERCOM3, (uint32_t)SERCOM4, (uint32_t)SERCOM5}; | ||
| 28 | const uint8_t sercom_pchan[] = {7, 8, 23, 24, 34, 35}; | ||
| 29 | |||
| 30 | #define USE_DPLL_IND 0 | ||
| 31 | #define USE_DPLL_DEF GCLK_SOURCE_DPLL0 | ||
| 32 | |||
| 33 | void CLK_oscctrl_init(void) { | ||
| 34 | Oscctrl *posctrl = OSCCTRL; | ||
| 35 | Gclk * pgclk = GCLK; | ||
| 36 | |||
| 37 | DBGC(DC_CLK_OSC_INIT_BEGIN); | ||
| 38 | |||
| 39 | // default setup on por | ||
| 40 | system_clks.freq_dfll = FREQ_DFLL_DEFAULT; | ||
| 41 | system_clks.freq_gclk[0] = system_clks.freq_dfll; | ||
| 42 | |||
| 43 | // configure and startup 16MHz xosc0 | ||
| 44 | posctrl->XOSCCTRL[0].bit.ENABLE = 0; | ||
| 45 | posctrl->XOSCCTRL[0].bit.STARTUP = 0xD; | ||
| 46 | posctrl->XOSCCTRL[0].bit.ENALC = 1; | ||
| 47 | posctrl->XOSCCTRL[0].bit.IMULT = 5; | ||
| 48 | posctrl->XOSCCTRL[0].bit.IPTAT = 3; | ||
| 49 | posctrl->XOSCCTRL[0].bit.ONDEMAND = 0; | ||
| 50 | posctrl->XOSCCTRL[0].bit.XTALEN = 1; | ||
| 51 | posctrl->XOSCCTRL[0].bit.ENABLE = 1; | ||
| 52 | while (posctrl->STATUS.bit.XOSCRDY0 == 0) { | ||
| 53 | DBGC(DC_CLK_OSC_INIT_XOSC0_SYNC); | ||
| 54 | } | ||
| 55 | system_clks.freq_xosc0 = FREQ_XOSC0; | ||
| 56 | |||
| 57 | // configure and startup DPLL | ||
| 58 | posctrl->Dpll[USE_DPLL_IND].DPLLCTRLA.bit.ENABLE = 0; | ||
| 59 | while (posctrl->Dpll[USE_DPLL_IND].DPLLSYNCBUSY.bit.ENABLE) { | ||
| 60 | DBGC(DC_CLK_OSC_INIT_DPLL_SYNC_DISABLE); | ||
| 61 | } | ||
| 62 | posctrl->Dpll[USE_DPLL_IND].DPLLCTRLB.bit.REFCLK = 2; // select XOSC0 (16MHz) | ||
| 63 | posctrl->Dpll[USE_DPLL_IND].DPLLCTRLB.bit.DIV = 7; // 16 MHz / (2 * (7 + 1)) = 1 MHz | ||
| 64 | posctrl->Dpll[USE_DPLL_IND].DPLLRATIO.bit.LDR = PLL_RATIO; // 1 MHz * (PLL_RATIO(47) + 1) = 48MHz | ||
| 65 | while (posctrl->Dpll[USE_DPLL_IND].DPLLSYNCBUSY.bit.DPLLRATIO) { | ||
| 66 | DBGC(DC_CLK_OSC_INIT_DPLL_SYNC_RATIO); | ||
| 67 | } | ||
| 68 | posctrl->Dpll[USE_DPLL_IND].DPLLCTRLA.bit.ONDEMAND = 0; | ||
| 69 | posctrl->Dpll[USE_DPLL_IND].DPLLCTRLA.bit.ENABLE = 1; | ||
| 70 | while (posctrl->Dpll[USE_DPLL_IND].DPLLSYNCBUSY.bit.ENABLE) { | ||
| 71 | DBGC(DC_CLK_OSC_INIT_DPLL_SYNC_ENABLE); | ||
| 72 | } | ||
| 73 | while (posctrl->Dpll[USE_DPLL_IND].DPLLSTATUS.bit.LOCK == 0) { | ||
| 74 | DBGC(DC_CLK_OSC_INIT_DPLL_WAIT_LOCK); | ||
| 75 | } | ||
| 76 | while (posctrl->Dpll[USE_DPLL_IND].DPLLSTATUS.bit.CLKRDY == 0) { | ||
| 77 | DBGC(DC_CLK_OSC_INIT_DPLL_WAIT_CLKRDY); | ||
| 78 | } | ||
| 79 | 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); | ||
| 80 | |||
| 81 | // change gclk0 to DPLL | ||
| 82 | pgclk->GENCTRL[GEN_DPLL0].bit.SRC = USE_DPLL_DEF; | ||
| 83 | while (pgclk->SYNCBUSY.bit.GENCTRL0) { | ||
| 84 | DBGC(DC_CLK_OSC_INIT_GCLK_SYNC_GENCTRL0); | ||
| 85 | } | ||
| 86 | |||
| 87 | system_clks.freq_gclk[0] = system_clks.freq_dpll[0]; | ||
| 88 | |||
| 89 | usec_delay_mult = system_clks.freq_gclk[0] / (USEC_DELAY_LOOP_CYCLES * 1000000); | ||
| 90 | if (usec_delay_mult < 1) usec_delay_mult = 1; // Never allow a multiplier of zero | ||
| 91 | |||
| 92 | DBGC(DC_CLK_OSC_INIT_COMPLETE); | ||
| 93 | } | ||
| 94 | |||
| 95 | // configure for 1MHz (1 usec timebase) | ||
| 96 | // call CLK_set_gclk_freq(GEN_TC45, FREQ_TC45_DEFAULT); | ||
| 97 | uint32_t CLK_set_gclk_freq(uint8_t gclkn, uint32_t freq) { | ||
| 98 | Gclk *pgclk = GCLK; | ||
| 99 | |||
| 100 | DBGC(DC_CLK_SET_GCLK_FREQ_BEGIN); | ||
| 101 | |||
| 102 | while (pgclk->SYNCBUSY.vec.GENCTRL) { | ||
| 103 | DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_1); | ||
| 104 | } | ||
| 105 | pgclk->GENCTRL[gclkn].bit.SRC = USE_DPLL_DEF; | ||
| 106 | while (pgclk->SYNCBUSY.vec.GENCTRL) { | ||
| 107 | DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_2); | ||
| 108 | } | ||
| 109 | pgclk->GENCTRL[gclkn].bit.DIV = (uint8_t)(system_clks.freq_dpll[0] / freq); | ||
| 110 | while (pgclk->SYNCBUSY.vec.GENCTRL) { | ||
| 111 | DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_3); | ||
| 112 | } | ||
| 113 | pgclk->GENCTRL[gclkn].bit.DIVSEL = 0; | ||
| 114 | while (pgclk->SYNCBUSY.vec.GENCTRL) { | ||
| 115 | DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_4); | ||
| 116 | } | ||
| 117 | pgclk->GENCTRL[gclkn].bit.GENEN = 1; | ||
| 118 | while (pgclk->SYNCBUSY.vec.GENCTRL) { | ||
| 119 | DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_5); | ||
| 120 | } | ||
| 121 | system_clks.freq_gclk[gclkn] = system_clks.freq_dpll[0] / pgclk->GENCTRL[gclkn].bit.DIV; | ||
| 122 | |||
| 123 | DBGC(DC_CLK_SET_GCLK_FREQ_COMPLETE); | ||
| 124 | |||
| 125 | return system_clks.freq_gclk[gclkn]; | ||
| 126 | } | ||
| 127 | |||
| 128 | void CLK_init_osc(void) { | ||
| 129 | uint8_t gclkn = GEN_OSC0; | ||
| 130 | Gclk * pgclk = GCLK; | ||
| 131 | |||
| 132 | DBGC(DC_CLK_INIT_OSC_BEGIN); | ||
| 133 | |||
| 134 | while (pgclk->SYNCBUSY.vec.GENCTRL) { | ||
| 135 | DBGC(DC_CLK_INIT_OSC_SYNC_1); | ||
| 136 | } | ||
| 137 | pgclk->GENCTRL[gclkn].bit.SRC = GCLK_SOURCE_XOSC0; | ||
| 138 | while (pgclk->SYNCBUSY.vec.GENCTRL) { | ||
| 139 | DBGC(DC_CLK_INIT_OSC_SYNC_2); | ||
| 140 | } | ||
| 141 | pgclk->GENCTRL[gclkn].bit.DIV = 1; | ||
| 142 | while (pgclk->SYNCBUSY.vec.GENCTRL) { | ||
| 143 | DBGC(DC_CLK_INIT_OSC_SYNC_3); | ||
| 144 | } | ||
| 145 | pgclk->GENCTRL[gclkn].bit.DIVSEL = 0; | ||
| 146 | while (pgclk->SYNCBUSY.vec.GENCTRL) { | ||
| 147 | DBGC(DC_CLK_INIT_OSC_SYNC_4); | ||
| 148 | } | ||
| 149 | pgclk->GENCTRL[gclkn].bit.GENEN = 1; | ||
| 150 | while (pgclk->SYNCBUSY.vec.GENCTRL) { | ||
| 151 | DBGC(DC_CLK_INIT_OSC_SYNC_5); | ||
| 152 | } | ||
| 153 | system_clks.freq_gclk[gclkn] = system_clks.freq_xosc0; | ||
| 154 | |||
| 155 | DBGC(DC_CLK_INIT_OSC_COMPLETE); | ||
| 156 | } | ||
| 157 | |||
| 158 | void CLK_reset_time(void) { | ||
| 159 | Tc *ptc4 = TC4; | ||
| 160 | Tc *ptc0 = TC0; | ||
| 161 | |||
| 162 | ms_clk = 0; | ||
| 163 | |||
| 164 | DBGC(DC_CLK_RESET_TIME_BEGIN); | ||
| 165 | |||
| 166 | // stop counters | ||
| 167 | ptc4->COUNT16.CTRLA.bit.ENABLE = 0; | ||
| 168 | while (ptc4->COUNT16.SYNCBUSY.bit.ENABLE) { | ||
| 169 | } | ||
| 170 | ptc0->COUNT32.CTRLA.bit.ENABLE = 0; | ||
| 171 | while (ptc0->COUNT32.SYNCBUSY.bit.ENABLE) { | ||
| 172 | } | ||
| 173 | // zero counters | ||
| 174 | ptc4->COUNT16.COUNT.reg = 0; | ||
| 175 | while (ptc4->COUNT16.SYNCBUSY.bit.COUNT) { | ||
| 176 | } | ||
| 177 | ptc0->COUNT32.COUNT.reg = 0; | ||
| 178 | while (ptc0->COUNT32.SYNCBUSY.bit.COUNT) { | ||
| 179 | } | ||
| 180 | // start counters | ||
| 181 | ptc0->COUNT32.CTRLA.bit.ENABLE = 1; | ||
| 182 | while (ptc0->COUNT32.SYNCBUSY.bit.ENABLE) { | ||
| 183 | } | ||
| 184 | ptc4->COUNT16.CTRLA.bit.ENABLE = 1; | ||
| 185 | while (ptc4->COUNT16.SYNCBUSY.bit.ENABLE) { | ||
| 186 | } | ||
| 187 | |||
| 188 | DBGC(DC_CLK_RESET_TIME_COMPLETE); | ||
| 189 | } | ||
| 190 | |||
| 191 | void TC4_Handler() { | ||
| 192 | if (TC4->COUNT16.INTFLAG.bit.MC0) { | ||
| 193 | TC4->COUNT16.INTFLAG.reg = TC_INTENCLR_MC0; | ||
| 194 | ms_clk++; | ||
| 195 | } | ||
| 196 | } | ||
| 197 | |||
| 198 | uint32_t CLK_enable_timebase(void) { | ||
| 199 | Gclk * pgclk = GCLK; | ||
| 200 | Mclk * pmclk = MCLK; | ||
| 201 | Tc * ptc4 = TC4; | ||
| 202 | Tc * ptc0 = TC0; | ||
| 203 | Evsys *pevsys = EVSYS; | ||
| 204 | |||
| 205 | DBGC(DC_CLK_ENABLE_TIMEBASE_BEGIN); | ||
| 206 | |||
| 207 | // gclk2 highspeed time base | ||
| 208 | CLK_set_gclk_freq(GEN_TC45, FREQ_TC45_DEFAULT); | ||
| 209 | CLK_init_osc(); | ||
| 210 | |||
| 211 | // unmask TC4, sourcegclk2 to TC4 | ||
| 212 | pmclk->APBCMASK.bit.TC4_ = 1; | ||
| 213 | pgclk->PCHCTRL[TC4_GCLK_ID].bit.GEN = GEN_TC45; | ||
| 214 | pgclk->PCHCTRL[TC4_GCLK_ID].bit.CHEN = 1; | ||
| 215 | |||
| 216 | // configure TC4 | ||
| 217 | DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_BEGIN); | ||
| 218 | ptc4->COUNT16.CTRLA.bit.ENABLE = 0; | ||
| 219 | while (ptc4->COUNT16.SYNCBUSY.bit.ENABLE) { | ||
| 220 | DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_DISABLE); | ||
| 221 | } | ||
| 222 | ptc4->COUNT16.CTRLA.bit.SWRST = 1; | ||
| 223 | while (ptc4->COUNT16.SYNCBUSY.bit.SWRST) { | ||
| 224 | DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_SWRST_1); | ||
| 225 | } | ||
| 226 | while (ptc4->COUNT16.CTRLA.bit.SWRST) { | ||
| 227 | DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_SWRST_2); | ||
| 228 | } | ||
| 229 | |||
| 230 | // CTRLA defaults | ||
| 231 | // CTRLB as default, counting up | ||
| 232 | ptc4->COUNT16.CTRLBCLR.reg = 5; | ||
| 233 | while (ptc4->COUNT16.SYNCBUSY.bit.CTRLB) { | ||
| 234 | DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_CLTRB); | ||
| 235 | } | ||
| 236 | ptc4->COUNT16.CC[0].reg = 999; | ||
| 237 | while (ptc4->COUNT16.SYNCBUSY.bit.CC0) { | ||
| 238 | DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_CC0); | ||
| 239 | } | ||
| 240 | // ptc4->COUNT16.DBGCTRL.bit.DBGRUN = 1; | ||
| 241 | |||
| 242 | // wave mode | ||
| 243 | ptc4->COUNT16.WAVE.bit.WAVEGEN = 1; // MFRQ match frequency mode, toggle each CC match | ||
| 244 | // generate event for next stage | ||
| 245 | ptc4->COUNT16.EVCTRL.bit.MCEO0 = 1; | ||
| 246 | |||
| 247 | NVIC_EnableIRQ(TC4_IRQn); | ||
| 248 | ptc4->COUNT16.INTENSET.bit.MC0 = 1; | ||
| 249 | |||
| 250 | DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_COMPLETE); | ||
| 251 | |||
| 252 | // unmask TC0,1, sourcegclk2 to TC0,1 | ||
| 253 | pmclk->APBAMASK.bit.TC0_ = 1; | ||
| 254 | pgclk->PCHCTRL[TC0_GCLK_ID].bit.GEN = GEN_TC45; | ||
| 255 | pgclk->PCHCTRL[TC0_GCLK_ID].bit.CHEN = 1; | ||
| 256 | |||
| 257 | pmclk->APBAMASK.bit.TC1_ = 1; | ||
| 258 | pgclk->PCHCTRL[TC1_GCLK_ID].bit.GEN = GEN_TC45; | ||
| 259 | pgclk->PCHCTRL[TC1_GCLK_ID].bit.CHEN = 1; | ||
| 260 | |||
| 261 | // configure TC0 | ||
| 262 | DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_BEGIN); | ||
| 263 | ptc0->COUNT32.CTRLA.bit.ENABLE = 0; | ||
| 264 | while (ptc0->COUNT32.SYNCBUSY.bit.ENABLE) { | ||
| 265 | DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_DISABLE); | ||
| 266 | } | ||
| 267 | ptc0->COUNT32.CTRLA.bit.SWRST = 1; | ||
| 268 | while (ptc0->COUNT32.SYNCBUSY.bit.SWRST) { | ||
| 269 | DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_SWRST_1); | ||
| 270 | } | ||
| 271 | while (ptc0->COUNT32.CTRLA.bit.SWRST) { | ||
| 272 | DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_SWRST_2); | ||
| 273 | } | ||
| 274 | // CTRLA as default | ||
| 275 | ptc0->COUNT32.CTRLA.bit.MODE = 2; // 32 bit mode | ||
| 276 | ptc0->COUNT32.EVCTRL.bit.TCEI = 1; // enable incoming events | ||
| 277 | ptc0->COUNT32.EVCTRL.bit.EVACT = 2; // count events | ||
| 278 | |||
| 279 | DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_COMPLETE); | ||
| 280 | |||
| 281 | DBGC(DC_CLK_ENABLE_TIMEBASE_EVSYS_BEGIN); | ||
| 282 | |||
| 283 | // configure event system | ||
| 284 | pmclk->APBBMASK.bit.EVSYS_ = 1; | ||
| 285 | pgclk->PCHCTRL[EVSYS_GCLK_ID_0].bit.GEN = GEN_TC45; | ||
| 286 | pgclk->PCHCTRL[EVSYS_GCLK_ID_0].bit.CHEN = 1; | ||
| 287 | pevsys->USER[44].reg = EVSYS_ID_USER_PORT_EV_0; // TC0 will get event channel 0 | ||
| 288 | pevsys->Channel[0].CHANNEL.bit.EDGSEL = EVSYS_CHANNEL_EDGSEL_RISING_EDGE_Val; // Rising edge | ||
| 289 | pevsys->Channel[0].CHANNEL.bit.PATH = EVSYS_CHANNEL_PATH_SYNCHRONOUS_Val; // Synchronous | ||
| 290 | pevsys->Channel[0].CHANNEL.bit.EVGEN = EVSYS_ID_GEN_TC4_MCX_0; // TC4 MC0 | ||
| 291 | |||
| 292 | DBGC(DC_CLK_ENABLE_TIMEBASE_EVSYS_COMPLETE); | ||
| 293 | |||
| 294 | CLK_reset_time(); | ||
| 295 | |||
| 296 | ADC0_clock_init(); | ||
| 297 | |||
| 298 | DBGC(DC_CLK_ENABLE_TIMEBASE_COMPLETE); | ||
| 299 | |||
| 300 | return 0; | ||
| 301 | } | ||
| 302 | |||
| 303 | void CLK_delay_us(uint32_t usec) { | ||
| 304 | asm("CBZ R0, return\n\t" // If usec == 0, branch to return label | ||
| 305 | ); | ||
| 306 | asm("MULS R0, %0\n\t" // Multiply R0(usec) by usec_delay_mult and store in R0 | ||
| 307 | ".balign 16\n\t" // Ensure loop is aligned for fastest performance | ||
| 308 | "loop: SUBS R0, #1\n\t" // Subtract 1 from R0 and update flags (1 cycle) | ||
| 309 | "BNE loop\n\t" // Branch if non-zero to loop label (2 cycles) NOTE: USEC_DELAY_LOOP_CYCLES is the sum of loop cycles | ||
| 310 | "return:\n\t" // Return label | ||
| 311 | : // No output registers | ||
| 312 | : "r"(usec_delay_mult) // For %0 | ||
| 313 | ); | ||
| 314 | // Note: BX LR generated | ||
| 315 | } | ||
| 316 | |||
| 317 | void CLK_delay_ms(uint64_t msec) { | ||
| 318 | msec += timer_read64(); | ||
| 319 | while (msec > timer_read64()) { | ||
| 320 | } | ||
| 321 | } | ||
| 322 | |||
| 323 | void clk_enable_sercom_apbmask(int sercomn) { | ||
| 324 | Mclk *pmclk = MCLK; | ||
| 325 | switch (sercomn) { | ||
| 326 | case 0: | ||
| 327 | pmclk->APBAMASK.bit.SERCOM0_ = 1; | ||
| 328 | break; | ||
| 329 | case 1: | ||
| 330 | pmclk->APBAMASK.bit.SERCOM1_ = 1; | ||
| 331 | break; | ||
| 332 | case 2: | ||
| 333 | pmclk->APBBMASK.bit.SERCOM2_ = 1; | ||
| 334 | break; | ||
| 335 | case 3: | ||
| 336 | pmclk->APBBMASK.bit.SERCOM3_ = 1; | ||
| 337 | break; | ||
| 338 | default: | ||
| 339 | break; | ||
| 340 | } | ||
| 341 | } | ||
| 342 | |||
| 343 | // call CLK_oscctrl_init first | ||
| 344 | // call CLK_set_spi_freq(CHAN_SERCOM_SPI, FREQ_SPI_DEFAULT); | ||
| 345 | uint32_t CLK_set_spi_freq(uint8_t sercomn, uint32_t freq) { | ||
| 346 | DBGC(DC_CLK_SET_SPI_FREQ_BEGIN); | ||
| 347 | |||
| 348 | Gclk * pgclk = GCLK; | ||
| 349 | Sercom *psercom = (Sercom *)sercom_apbbase[sercomn]; | ||
| 350 | clk_enable_sercom_apbmask(sercomn); | ||
| 351 | |||
| 352 | // all gclk0 for now | ||
| 353 | pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.GEN = 0; | ||
| 354 | pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.CHEN = 1; | ||
| 355 | |||
| 356 | psercom->I2CM.CTRLA.bit.SWRST = 1; | ||
| 357 | while (psercom->I2CM.SYNCBUSY.bit.SWRST) { | ||
| 358 | } | ||
| 359 | while (psercom->I2CM.CTRLA.bit.SWRST) { | ||
| 360 | } | ||
| 361 | |||
| 362 | psercom->SPI.BAUD.reg = (uint8_t)(system_clks.freq_gclk[0] / 2 / freq - 1); | ||
| 363 | system_clks.freq_spi = system_clks.freq_gclk[0] / 2 / (psercom->SPI.BAUD.reg + 1); | ||
| 364 | system_clks.freq_sercom[sercomn] = system_clks.freq_spi; | ||
| 365 | |||
| 366 | DBGC(DC_CLK_SET_SPI_FREQ_COMPLETE); | ||
| 367 | |||
| 368 | return system_clks.freq_spi; | ||
| 369 | } | ||
| 370 | |||
| 371 | // call CLK_oscctrl_init first | ||
| 372 | // call CLK_set_i2c0_freq(CHAN_SERCOM_I2C0, FREQ_I2C0_DEFAULT); | ||
| 373 | uint32_t CLK_set_i2c0_freq(uint8_t sercomn, uint32_t freq) { | ||
| 374 | DBGC(DC_CLK_SET_I2C0_FREQ_BEGIN); | ||
| 375 | |||
| 376 | Gclk * pgclk = GCLK; | ||
| 377 | Sercom *psercom = (Sercom *)sercom_apbbase[sercomn]; | ||
| 378 | clk_enable_sercom_apbmask(sercomn); | ||
| 379 | |||
| 380 | // all gclk0 for now | ||
| 381 | pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.GEN = 0; | ||
| 382 | pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.CHEN = 1; | ||
| 383 | |||
| 384 | psercom->I2CM.CTRLA.bit.SWRST = 1; | ||
| 385 | while (psercom->I2CM.SYNCBUSY.bit.SWRST) { | ||
| 386 | } | ||
| 387 | while (psercom->I2CM.CTRLA.bit.SWRST) { | ||
| 388 | } | ||
| 389 | |||
| 390 | psercom->I2CM.BAUD.bit.BAUD = (uint8_t)(system_clks.freq_gclk[0] / 2 / freq - 1); | ||
| 391 | system_clks.freq_i2c0 = system_clks.freq_gclk[0] / 2 / (psercom->I2CM.BAUD.bit.BAUD + 1); | ||
| 392 | system_clks.freq_sercom[sercomn] = system_clks.freq_i2c0; | ||
| 393 | |||
| 394 | DBGC(DC_CLK_SET_I2C0_FREQ_COMPLETE); | ||
| 395 | |||
| 396 | return system_clks.freq_i2c0; | ||
| 397 | } | ||
| 398 | |||
| 399 | // call CLK_oscctrl_init first | ||
| 400 | // call CLK_set_i2c1_freq(CHAN_SERCOM_I2C1, FREQ_I2C1_DEFAULT); | ||
| 401 | uint32_t CLK_set_i2c1_freq(uint8_t sercomn, uint32_t freq) { | ||
| 402 | DBGC(DC_CLK_SET_I2C1_FREQ_BEGIN); | ||
| 403 | |||
| 404 | Gclk * pgclk = GCLK; | ||
| 405 | Sercom *psercom = (Sercom *)sercom_apbbase[sercomn]; | ||
| 406 | clk_enable_sercom_apbmask(sercomn); | ||
| 407 | |||
| 408 | // all gclk0 for now | ||
| 409 | pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.GEN = 0; | ||
| 410 | pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.CHEN = 1; | ||
| 411 | |||
| 412 | psercom->I2CM.CTRLA.bit.SWRST = 1; | ||
| 413 | while (psercom->I2CM.SYNCBUSY.bit.SWRST) { | ||
| 414 | } | ||
| 415 | while (psercom->I2CM.CTRLA.bit.SWRST) { | ||
| 416 | } | ||
| 417 | |||
| 418 | psercom->I2CM.BAUD.bit.BAUD = (uint8_t)(system_clks.freq_gclk[0] / 2 / freq - 10); | ||
| 419 | system_clks.freq_i2c1 = system_clks.freq_gclk[0] / 2 / (psercom->I2CM.BAUD.bit.BAUD + 10); | ||
| 420 | system_clks.freq_sercom[sercomn] = system_clks.freq_i2c1; | ||
| 421 | |||
| 422 | DBGC(DC_CLK_SET_I2C1_FREQ_COMPLETE); | ||
| 423 | |||
| 424 | return system_clks.freq_i2c1; | ||
| 425 | } | ||
| 426 | |||
| 427 | void CLK_init(void) { | ||
| 428 | DBGC(DC_CLK_INIT_BEGIN); | ||
| 429 | |||
| 430 | memset((void *)&system_clks, 0, sizeof(system_clks)); | ||
| 431 | |||
| 432 | CLK_oscctrl_init(); | ||
| 433 | CLK_enable_timebase(); | ||
| 434 | |||
| 435 | DBGC(DC_CLK_INIT_COMPLETE); | ||
| 436 | } | ||
diff --git a/tmk_core/protocol/arm_atsam/clks.h b/tmk_core/protocol/arm_atsam/clks.h deleted file mode 100644 index 6ee71aff8f..0000000000 --- a/tmk_core/protocol/arm_atsam/clks.h +++ /dev/null | |||
| @@ -1,89 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef _CLKS_H_ | ||
| 19 | #define _CLKS_H_ | ||
| 20 | |||
| 21 | #ifndef MD_BOOTLOADER | ||
| 22 | |||
| 23 | // From keyboard | ||
| 24 | # include "config_led.h" | ||
| 25 | # include "config.h" | ||
| 26 | |||
| 27 | #endif // MD_BOOTLOADER | ||
| 28 | |||
| 29 | #define PLL_RATIO 47 // mcu frequency ((X+1)MHz) | ||
| 30 | #define FREQ_DFLL_DEFAULT 48000000 // DFLL frequency / usb clock | ||
| 31 | #define FREQ_SPI_DEFAULT 1000000 // spi to 595 shift regs | ||
| 32 | #define FREQ_I2C0_DEFAULT 100000 // i2c to hub | ||
| 33 | #define FREQ_I2C1_DEFAULT I2C_HZ // i2c to LED drivers | ||
| 34 | #define FREQ_TC45_DEFAULT 1000000 // 1 usec resolution | ||
| 35 | |||
| 36 | // I2C1 Set ~Result PWM Time (2x Drivers) | ||
| 37 | // 1000000 1090000 | ||
| 38 | // 900000 1000000 3.82ms | ||
| 39 | // 800000 860000 | ||
| 40 | // 700000 750000 | ||
| 41 | // 600000 630000 | ||
| 42 | // 580000 615000 6.08ms | ||
| 43 | // 500000 522000 | ||
| 44 | |||
| 45 | #define FREQ_XOSC0 16000000 | ||
| 46 | |||
| 47 | #define CHAN_SERCOM_SPI 2 // shift regs | ||
| 48 | #define CHAN_SERCOM_I2C0 0 // hub | ||
| 49 | #define CHAN_SERCOM_I2C1 1 // led drivers | ||
| 50 | #define CHAN_SERCOM_UART 3 // debug util | ||
| 51 | |||
| 52 | // Generator clock channels | ||
| 53 | #define GEN_DPLL0 0 | ||
| 54 | #define GEN_OSC0 1 | ||
| 55 | #define GEN_TC45 2 | ||
| 56 | |||
| 57 | #define SERCOM_COUNT 5 | ||
| 58 | #define GCLK_COUNT 12 | ||
| 59 | |||
| 60 | typedef struct clk_s { | ||
| 61 | uint32_t freq_dfll; | ||
| 62 | uint32_t freq_dpll[2]; | ||
| 63 | uint32_t freq_sercom[SERCOM_COUNT]; | ||
| 64 | uint32_t freq_gclk[GCLK_COUNT]; | ||
| 65 | uint32_t freq_xosc0; | ||
| 66 | uint32_t freq_spi; | ||
| 67 | uint32_t freq_i2c0; | ||
| 68 | uint32_t freq_i2c1; | ||
| 69 | uint32_t freq_uart; | ||
| 70 | uint32_t freq_adc0; | ||
| 71 | } clk_t; | ||
| 72 | |||
| 73 | extern volatile clk_t system_clks; | ||
| 74 | extern volatile uint64_t ms_clk; | ||
| 75 | |||
| 76 | void CLK_oscctrl_init(void); | ||
| 77 | void CLK_reset_time(void); | ||
| 78 | uint32_t CLK_set_gclk_freq(uint8_t gclkn, uint32_t freq); | ||
| 79 | uint32_t CLK_enable_timebase(void); | ||
| 80 | uint64_t timer_read64(void); | ||
| 81 | void CLK_delay_us(uint32_t usec); | ||
| 82 | void CLK_delay_ms(uint64_t msec); | ||
| 83 | |||
| 84 | uint32_t CLK_set_spi_freq(uint8_t sercomn, uint32_t freq); | ||
| 85 | uint32_t CLK_set_i2c0_freq(uint8_t sercomn, uint32_t freq); | ||
| 86 | uint32_t CLK_set_i2c1_freq(uint8_t sercomn, uint32_t freq); | ||
| 87 | void CLK_init(void); | ||
| 88 | |||
| 89 | #endif // _CLKS_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/d51_util.c b/tmk_core/protocol/arm_atsam/d51_util.c deleted file mode 100644 index 5903233085..0000000000 --- a/tmk_core/protocol/arm_atsam/d51_util.c +++ /dev/null | |||
| @@ -1,244 +0,0 @@ | |||
| 1 | #include "d51_util.h" | ||
| 2 | |||
| 3 | static volatile uint32_t w; | ||
| 4 | |||
| 5 | // Display unsigned 32-bit number by port toggling DBG_1 (to view on a scope) | ||
| 6 | // Read as follows: 1230 = | | | | | | || (note zero is fast double toggle) | ||
| 7 | #define DBG_PAUSE 5 | ||
| 8 | void dbg_print(uint32_t x) { | ||
| 9 | int8_t t; | ||
| 10 | uint32_t n; | ||
| 11 | uint32_t p, p2; | ||
| 12 | |||
| 13 | if (x < 10) | ||
| 14 | t = 0; | ||
| 15 | else if (x < 100) | ||
| 16 | t = 1; | ||
| 17 | else if (x < 1000) | ||
| 18 | t = 2; | ||
| 19 | else if (x < 10000) | ||
| 20 | t = 3; | ||
| 21 | else if (x < 100000) | ||
| 22 | t = 4; | ||
| 23 | else if (x < 1000000) | ||
| 24 | t = 5; | ||
| 25 | else if (x < 10000000) | ||
| 26 | t = 6; | ||
| 27 | else if (x < 100000000) | ||
| 28 | t = 7; | ||
| 29 | else if (x < 1000000000) | ||
| 30 | t = 8; | ||
| 31 | else | ||
| 32 | t = 9; | ||
| 33 | |||
| 34 | while (t >= 0) { | ||
| 35 | p2 = t; | ||
| 36 | p = 1; | ||
| 37 | while (p2--) | ||
| 38 | p *= 10; | ||
| 39 | n = x / p; | ||
| 40 | x -= n * p; | ||
| 41 | if (!n) { | ||
| 42 | DBG_1_ON; | ||
| 43 | DBG_1_OFF; | ||
| 44 | DBG_1_ON; | ||
| 45 | DBG_1_OFF; | ||
| 46 | n--; | ||
| 47 | } else { | ||
| 48 | while (n > 0) { | ||
| 49 | DBG_1_ON; | ||
| 50 | DBG_1_OFF; | ||
| 51 | n--; | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | t--; | ||
| 56 | } | ||
| 57 | |||
| 58 | for (w = DBG_PAUSE; w; w--) | ||
| 59 | ; // Long pause after number is complete | ||
| 60 | } | ||
| 61 | |||
| 62 | // Display unsigned 32-bit number through debug led | ||
| 63 | // Read as follows: 1230 = [*] [* *] [* * *] [**] (note zero is fast double flash) | ||
| 64 | #define DLED_ONTIME 1000000 | ||
| 65 | #define DLED_PAUSE 1500000 | ||
| 66 | void dled_print(uint32_t x, uint8_t long_pause) { | ||
| 67 | int8_t t; | ||
| 68 | uint32_t n; | ||
| 69 | uint32_t p, p2; | ||
| 70 | |||
| 71 | if (x < 10) | ||
| 72 | t = 0; | ||
| 73 | else if (x < 100) | ||
| 74 | t = 1; | ||
| 75 | else if (x < 1000) | ||
| 76 | t = 2; | ||
| 77 | else if (x < 10000) | ||
| 78 | t = 3; | ||
| 79 | else if (x < 100000) | ||
| 80 | t = 4; | ||
| 81 | else if (x < 1000000) | ||
| 82 | t = 5; | ||
| 83 | else if (x < 10000000) | ||
| 84 | t = 6; | ||
| 85 | else if (x < 100000000) | ||
| 86 | t = 7; | ||
| 87 | else if (x < 1000000000) | ||
| 88 | t = 8; | ||
| 89 | else | ||
| 90 | t = 9; | ||
| 91 | |||
| 92 | while (t >= 0) { | ||
| 93 | p2 = t; | ||
| 94 | p = 1; | ||
| 95 | while (p2--) | ||
| 96 | p *= 10; | ||
| 97 | n = x / p; | ||
| 98 | x -= n * p; | ||
| 99 | if (!n) { | ||
| 100 | DBG_LED_ON; | ||
| 101 | for (w = DLED_ONTIME / 4; w; w--) | ||
| 102 | ; | ||
| 103 | DBG_LED_OFF; | ||
| 104 | for (w = DLED_ONTIME / 4; w; w--) | ||
| 105 | ; | ||
| 106 | DBG_LED_ON; | ||
| 107 | for (w = DLED_ONTIME / 4; w; w--) | ||
| 108 | ; | ||
| 109 | DBG_LED_OFF; | ||
| 110 | for (w = DLED_ONTIME / 4; w; w--) | ||
| 111 | ; | ||
| 112 | n--; | ||
| 113 | } else { | ||
| 114 | while (n > 0) { | ||
| 115 | DBG_LED_ON; | ||
| 116 | for (w = DLED_ONTIME; w; w--) | ||
| 117 | ; | ||
| 118 | DBG_LED_OFF; | ||
| 119 | for (w = DLED_ONTIME / 2; w; w--) | ||
| 120 | ; | ||
| 121 | n--; | ||
| 122 | } | ||
| 123 | } | ||
| 124 | |||
| 125 | for (w = DLED_PAUSE; w; w--) | ||
| 126 | ; | ||
| 127 | t--; | ||
| 128 | } | ||
| 129 | |||
| 130 | if (long_pause) { | ||
| 131 | for (w = DLED_PAUSE * 4; w; w--) | ||
| 132 | ; | ||
| 133 | } | ||
| 134 | } | ||
| 135 | |||
| 136 | #ifdef DEBUG_BOOT_TRACING_ENABLE | ||
| 137 | |||
| 138 | volatile uint32_t debug_code; | ||
| 139 | |||
| 140 | // These macros are for compile time substitution | ||
| 141 | # define DEBUG_BOOT_TRACING_EXTINTn (DEBUG_BOOT_TRACING_PIN % _U_(0x10)) | ||
| 142 | # define DEBUG_BOOT_TRACING_EXTINTb (_U_(0x1) << DEBUG_BOOT_TRACING_EXTINTn) | ||
| 143 | # define DEBUG_BOOT_TRACING_CONFIG_INDn (DEBUG_BOOT_TRACING_EXTINTn / _U_(0x8)) | ||
| 144 | # define DEBUG_BOOT_TRACING_CONFIG_SENSEn (DEBUG_BOOT_TRACING_EXTINTn % _U_(0x8)) | ||
| 145 | # define DEBUG_BOOT_TRACING_CONFIG_SENSEb (DEBUG_BOOT_TRACING_CONFIG_SENSEn * _U_(0x4)) | ||
| 146 | # define DEBUG_BOOT_TRACING_IRQn (EIC_0_IRQn + DEBUG_BOOT_TRACING_EXTINTn) | ||
| 147 | |||
| 148 | // These macros perform PORT+PIN definition translation to IRQn in the preprocessor | ||
| 149 | # define PORTPIN_TO_IRQn_EXPAND(def) def | ||
| 150 | # define PORTPIN_TO_IRQn_DEF(def) PORTPIN_TO_IRQn_EXPAND(def) | ||
| 151 | # if DEBUG_BOOT_TRACING_PIN < 10 | ||
| 152 | # define PORTPIN_TO_IRQn_TODEF(port, pin) PORTPIN_TO_IRQn_DEF(PIN_##port##0##pin##A_EIC_EXTINT_NUM) | ||
| 153 | # else | ||
| 154 | # define PORTPIN_TO_IRQn_TODEF(port, pin) PORTPIN_TO_IRQn_DEF(PIN_##port##pin##A_EIC_EXTINT_NUM) | ||
| 155 | # endif | ||
| 156 | # define PORTPIN_TO_IRQn(port, pin) PORTPIN_TO_IRQn_TODEF(port, pin) | ||
| 157 | |||
| 158 | // These macros perform function name output in the preprocessor | ||
| 159 | # define DEBUG_BOOT_TRACING_HANDLER_CONCAT(irq) void EIC_##irq##_Handler(void) | ||
| 160 | # define DEBUG_BOOT_TRACING_HANDLER(irq) DEBUG_BOOT_TRACING_HANDLER_CONCAT(irq) | ||
| 161 | |||
| 162 | // To generate the function name of the IRQ handler catching boot tracing, | ||
| 163 | // certain macros must be undefined, so save their current values to macro stack | ||
| 164 | # pragma push_macro("PA") | ||
| 165 | # pragma push_macro("PB") | ||
| 166 | # pragma push_macro("_L_") | ||
| 167 | |||
| 168 | // Undefine / redefine pushed macros | ||
| 169 | # undef PA | ||
| 170 | # undef PB | ||
| 171 | # undef _L_ | ||
| 172 | # define _L_(x) x | ||
| 173 | |||
| 174 | // Perform the work and output | ||
| 175 | // Ex: PORT PB, PIN 31 = void EIC_15_Handler(void) | ||
| 176 | DEBUG_BOOT_TRACING_HANDLER(PORTPIN_TO_IRQn(DEBUG_BOOT_TRACING_PORT, DEBUG_BOOT_TRACING_PIN)) | ||
| 177 | // Restore macros | ||
| 178 | # pragma pop_macro("PA") | ||
| 179 | # pragma pop_macro("PB") | ||
| 180 | # pragma pop_macro("_L_") | ||
| 181 | { | ||
| 182 | // This is only for non-functional keyboard troubleshooting and should be disabled after boot | ||
| 183 | // Intention is to lock up the keyboard here with repeating debug led code | ||
| 184 | while (1) { | ||
| 185 | dled_print(debug_code, 1); | ||
| 186 | } | ||
| 187 | } | ||
| 188 | |||
| 189 | void debug_code_init(void) { | ||
| 190 | DBGC(DC_UNSET); | ||
| 191 | |||
| 192 | // Configure Ports for EIC | ||
| 193 | PORT->Group[DEBUG_BOOT_TRACING_PORT].DIRCLR.reg = 1 << DEBUG_BOOT_TRACING_PIN; // Input | ||
| 194 | PORT->Group[DEBUG_BOOT_TRACING_PORT].OUTSET.reg = 1 << DEBUG_BOOT_TRACING_PIN; // High | ||
| 195 | PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.INEN = 1; // Input Enable | ||
| 196 | PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PULLEN = 1; // Pull Enable | ||
| 197 | PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PMUXEN = 1; // Mux Enable | ||
| 198 | PORT->Group[DEBUG_BOOT_TRACING_PORT].PMUX[DEBUG_BOOT_TRACING_PIN / 2].bit.PMUXO = 0; // Mux A | ||
| 199 | |||
| 200 | // Enable CLK_EIC_APB | ||
| 201 | MCLK->APBAMASK.bit.EIC_ = 1; | ||
| 202 | |||
| 203 | // Configure EIC | ||
| 204 | EIC->CTRLA.bit.SWRST = 1; | ||
| 205 | while (EIC->SYNCBUSY.bit.SWRST) { | ||
| 206 | } | ||
| 207 | EIC->ASYNCH.reg = DEBUG_BOOT_TRACING_EXTINTb; | ||
| 208 | EIC->INTENSET.reg = DEBUG_BOOT_TRACING_EXTINTb; | ||
| 209 | EIC->CONFIG[DEBUG_BOOT_TRACING_CONFIG_INDn].reg |= (EIC_CONFIG_SENSE0_FALL_Val << DEBUG_BOOT_TRACING_CONFIG_SENSEb); | ||
| 210 | EIC->CTRLA.bit.ENABLE = 1; | ||
| 211 | while (EIC->SYNCBUSY.bit.ENABLE) { | ||
| 212 | } | ||
| 213 | |||
| 214 | // Enable EIC IRQ | ||
| 215 | NVIC_EnableIRQ(DEBUG_BOOT_TRACING_IRQn); | ||
| 216 | } | ||
| 217 | |||
| 218 | void debug_code_disable(void) { | ||
| 219 | // Disable EIC IRQ | ||
| 220 | NVIC_DisableIRQ(DEBUG_BOOT_TRACING_IRQn); | ||
| 221 | |||
| 222 | // Disable EIC | ||
| 223 | EIC->CTRLA.bit.ENABLE = 0; | ||
| 224 | while (EIC->SYNCBUSY.bit.ENABLE) { | ||
| 225 | } | ||
| 226 | |||
| 227 | // Default port configuration | ||
| 228 | PORT->Group[DEBUG_BOOT_TRACING_PORT].DIRCLR.reg = 1 << DEBUG_BOOT_TRACING_PIN; // Input | ||
| 229 | PORT->Group[DEBUG_BOOT_TRACING_PORT].OUTCLR.reg = 1 << DEBUG_BOOT_TRACING_PIN; // Low | ||
| 230 | PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.INEN = 0; // Input Disable | ||
| 231 | PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PULLEN = 0; // Pull Disable | ||
| 232 | PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PMUXEN = 0; // Mux Disable | ||
| 233 | PORT->Group[DEBUG_BOOT_TRACING_PORT].PMUX[DEBUG_BOOT_TRACING_PIN / 2].bit.PMUXO = 0; // Mux A | ||
| 234 | |||
| 235 | // Disable CLK_EIC_APB | ||
| 236 | MCLK->APBAMASK.bit.EIC_ = 0; | ||
| 237 | } | ||
| 238 | |||
| 239 | #else | ||
| 240 | |||
| 241 | void debug_code_init(void) {} | ||
| 242 | void debug_code_disable(void) {} | ||
| 243 | |||
| 244 | #endif // DEBUG_BOOT_TRACING_ENABLE | ||
diff --git a/tmk_core/protocol/arm_atsam/d51_util.h b/tmk_core/protocol/arm_atsam/d51_util.h deleted file mode 100644 index d301e55411..0000000000 --- a/tmk_core/protocol/arm_atsam/d51_util.h +++ /dev/null | |||
| @@ -1,224 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef _D51_UTIL_H_ | ||
| 19 | #define _D51_UTIL_H_ | ||
| 20 | |||
| 21 | #include "samd51j18a.h" | ||
| 22 | |||
| 23 | /* Debug LED */ | ||
| 24 | #if DEBUG_LED_ENABLE == 1 | ||
| 25 | # define DBG_LED_ENA PORT->Group[DEBUG_LED_PORT].DIRSET.reg = (1 << DEBUG_LED_PIN) | ||
| 26 | # define DBG_LED_DIS PORT->Group[DEBUG_LED_PORT].DIRCLR.reg = (1 << DEBUG_LED_PIN) | ||
| 27 | # define DBG_LED_ON PORT->Group[DEBUG_LED_PORT].OUTSET.reg = (1 << DEBUG_LED_PIN) | ||
| 28 | # define DBG_LED_OFF PORT->Group[DEBUG_LED_PORT].OUTCLR.reg = (1 << DEBUG_LED_PIN) | ||
| 29 | #else | ||
| 30 | # define DBG_LED_ENA | ||
| 31 | # define DBG_LED_DIS | ||
| 32 | # define DBG_LED_ON | ||
| 33 | # define DBG_LED_OFF | ||
| 34 | #endif | ||
| 35 | |||
| 36 | /* Debug Port 1 */ | ||
| 37 | #if DEBUG_PORT1_ENABLE == 1 | ||
| 38 | # define DBG_1_ENA PORT->Group[DEBUG_PORT1_PORT].DIRSET.reg = (1 << DEBUG_PORT1_PIN) | ||
| 39 | # define DBG_1_DIS PORT->Group[DEBUG_PORT1_PORT].DIRCLR.reg = (1 << DEBUG_PORT1_PIN) | ||
| 40 | # define DBG_1_ON PORT->Group[DEBUG_PORT1_PORT].OUTSET.reg = (1 << DEBUG_PORT1_PIN) | ||
| 41 | # define DBG_1_OFF PORT->Group[DEBUG_PORT1_PORT].OUTCLR.reg = (1 << DEBUG_PORT1_PIN) | ||
| 42 | #else | ||
| 43 | # define DBG_1_ENA | ||
| 44 | # define DBG_1_DIS | ||
| 45 | # define DBG_1_ON | ||
| 46 | # define DBG_1_OFF | ||
| 47 | #endif | ||
| 48 | |||
| 49 | /* Debug Port 2 */ | ||
| 50 | #if DEBUG_PORT2_ENABLE == 1 | ||
| 51 | # define DBG_2_ENA PORT->Group[DEBUG_PORT2_PORT].DIRSET.reg = (1 << DEBUG_PORT2_PIN) | ||
| 52 | # define DBG_2_DIS PORT->Group[DEBUG_PORT2_PORT].DIRCLR.reg = (1 << DEBUG_PORT2_PIN) | ||
| 53 | # define DBG_2_ON PORT->Group[DEBUG_PORT2_PORT].OUTSET.reg = (1 << DEBUG_PORT2_PIN) | ||
| 54 | # define DBG_2_OFF PORT->Group[DEBUG_PORT2_PORT].OUTCLR.reg = (1 << DEBUG_PORT2_PIN) | ||
| 55 | #else | ||
| 56 | # define DBG_2_ENA | ||
| 57 | # define DBG_2_DIS | ||
| 58 | # define DBG_2_ON | ||
| 59 | # define DBG_2_OFF | ||
| 60 | #endif | ||
| 61 | |||
| 62 | /* Debug Port 3 */ | ||
| 63 | #if DEBUG_PORT3_ENABLE == 1 | ||
| 64 | # define DBG_3_ENA PORT->Group[DEBUG_PORT3_PORT].DIRSET.reg = (1 << DEBUG_PORT3_PIN) | ||
| 65 | # define DBG_3_DIS PORT->Group[DEBUG_PORT3_PORT].DIRCLR.reg = (1 << DEBUG_PORT3_PIN) | ||
| 66 | # define DBG_3_ON PORT->Group[DEBUG_PORT3_PORT].OUTSET.reg = (1 << DEBUG_PORT3_PIN) | ||
| 67 | # define DBG_3_OFF PORT->Group[DEBUG_PORT3_PORT].OUTCLR.reg = (1 << DEBUG_PORT3_PIN) | ||
| 68 | #else | ||
| 69 | # define DBG_3_ENA | ||
| 70 | # define DBG_3_DIS | ||
| 71 | # define DBG_3_ON | ||
| 72 | # define DBG_3_OFF | ||
| 73 | #endif | ||
| 74 | |||
| 75 | void dbg_print(uint32_t x); | ||
| 76 | void dled_print(uint32_t x, uint8_t long_pause); | ||
| 77 | |||
| 78 | void debug_code_init(void); | ||
| 79 | void debug_code_disable(void); | ||
| 80 | |||
| 81 | #ifdef DEBUG_BOOT_TRACING_ENABLE | ||
| 82 | |||
| 83 | # define DBGC(n) debug_code = n | ||
| 84 | |||
| 85 | extern volatile uint32_t debug_code; | ||
| 86 | |||
| 87 | enum debug_code_list { | ||
| 88 | DC_UNSET = 0, | ||
| 89 | DC_CLK_INIT_BEGIN, | ||
| 90 | DC_CLK_INIT_COMPLETE, | ||
| 91 | DC_CLK_SET_I2C1_FREQ_BEGIN, | ||
| 92 | DC_CLK_SET_I2C1_FREQ_COMPLETE, | ||
| 93 | DC_CLK_SET_I2C0_FREQ_BEGIN, | ||
| 94 | DC_CLK_SET_I2C0_FREQ_COMPLETE, | ||
| 95 | DC_CLK_SET_SPI_FREQ_BEGIN, | ||
| 96 | DC_CLK_SET_SPI_FREQ_COMPLETE, | ||
| 97 | DC_CLK_ENABLE_TIMEBASE_BEGIN, | ||
| 98 | DC_CLK_ENABLE_TIMEBASE_SYNC_ENABLE, | ||
| 99 | DC_CLK_ENABLE_TIMEBASE_SYNC_SWRST_1, | ||
| 100 | DC_CLK_ENABLE_TIMEBASE_SYNC_SWRST_2, | ||
| 101 | DC_CLK_ENABLE_TIMEBASE_TC4_BEGIN, | ||
| 102 | DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_DISABLE, | ||
| 103 | DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_SWRST_1, | ||
| 104 | DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_SWRST_2, | ||
| 105 | DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_CLTRB, | ||
| 106 | DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_CC0, | ||
| 107 | DC_CLK_ENABLE_TIMEBASE_TC4_COMPLETE, | ||
| 108 | DC_CLK_ENABLE_TIMEBASE_TC5_BEGIN, | ||
| 109 | DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_DISABLE, | ||
| 110 | DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_SWRST_1, | ||
| 111 | DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_SWRST_2, | ||
| 112 | DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_CLTRB, | ||
| 113 | DC_CLK_ENABLE_TIMEBASE_TC5_COMPLETE, | ||
| 114 | DC_CLK_ENABLE_TIMEBASE_TC0_BEGIN, | ||
| 115 | DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_DISABLE, | ||
| 116 | DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_SWRST_1, | ||
| 117 | DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_SWRST_2, | ||
| 118 | DC_CLK_ENABLE_TIMEBASE_TC0_COMPLETE, | ||
| 119 | DC_CLK_ENABLE_TIMEBASE_EVSYS_BEGIN, | ||
| 120 | DC_CLK_ENABLE_TIMEBASE_EVSYS_COMPLETE, | ||
| 121 | DC_CLK_ENABLE_TIMEBASE_COMPLETE, | ||
| 122 | DC_CLK_SET_GCLK_FREQ_BEGIN, | ||
| 123 | DC_CLK_SET_GCLK_FREQ_SYNC_1, | ||
| 124 | DC_CLK_SET_GCLK_FREQ_SYNC_2, | ||
| 125 | DC_CLK_SET_GCLK_FREQ_SYNC_3, | ||
| 126 | DC_CLK_SET_GCLK_FREQ_SYNC_4, | ||
| 127 | DC_CLK_SET_GCLK_FREQ_SYNC_5, | ||
| 128 | DC_CLK_SET_GCLK_FREQ_COMPLETE, | ||
| 129 | DC_CLK_INIT_OSC_BEGIN, | ||
| 130 | DC_CLK_INIT_OSC_SYNC_1, | ||
| 131 | DC_CLK_INIT_OSC_SYNC_2, | ||
| 132 | DC_CLK_INIT_OSC_SYNC_3, | ||
| 133 | DC_CLK_INIT_OSC_SYNC_4, | ||
| 134 | DC_CLK_INIT_OSC_SYNC_5, | ||
| 135 | DC_CLK_INIT_OSC_COMPLETE, | ||
| 136 | DC_CLK_RESET_TIME_BEGIN, | ||
| 137 | DC_CLK_RESET_TIME_COMPLETE, | ||
| 138 | DC_CLK_OSC_INIT_BEGIN, | ||
| 139 | DC_CLK_OSC_INIT_XOSC0_SYNC, | ||
| 140 | DC_CLK_OSC_INIT_DPLL_SYNC_DISABLE, | ||
| 141 | DC_CLK_OSC_INIT_DPLL_SYNC_RATIO, | ||
| 142 | DC_CLK_OSC_INIT_DPLL_SYNC_ENABLE, | ||
| 143 | DC_CLK_OSC_INIT_DPLL_WAIT_LOCK, | ||
| 144 | DC_CLK_OSC_INIT_DPLL_WAIT_CLKRDY, | ||
| 145 | DC_CLK_OSC_INIT_GCLK_SYNC_GENCTRL0, | ||
| 146 | DC_CLK_OSC_INIT_COMPLETE, | ||
| 147 | DC_SPI_INIT_BEGIN, | ||
| 148 | DC_SPI_WRITE_DRE, | ||
| 149 | DC_SPI_WRITE_TXC_1, | ||
| 150 | DC_SPI_WRITE_TXC_2, | ||
| 151 | DC_SPI_SYNC_ENABLING, | ||
| 152 | DC_SPI_INIT_COMPLETE, | ||
| 153 | DC_PORT_DETECT_INIT_BEGIN, | ||
| 154 | DC_PORT_DETECT_INIT_FAILED, | ||
| 155 | DC_PORT_DETECT_INIT_COMPLETE, | ||
| 156 | DC_USB_RESET_BEGIN, | ||
| 157 | DC_USB_RESET_COMPLETE, | ||
| 158 | DC_USB_SET_HOST_BY_VOLTAGE_BEGIN, | ||
| 159 | DC_USB_SET_HOST_5V_LOW_WAITING, | ||
| 160 | DC_USB_SET_HOST_BY_VOLTAGE_COMPLETE, | ||
| 161 | DC_USB_CONFIGURE_BEGIN, | ||
| 162 | DC_USB_CONFIGURE_GET_SERIAL, | ||
| 163 | DC_USB_CONFIGURE_COMPLETE, | ||
| 164 | DC_USB_WRITE2422_BLOCK_BEGIN, | ||
| 165 | DC_USB_WRITE2422_BLOCK_SYNC_SYSOP, | ||
| 166 | DC_USB_WRITE2422_BLOCK_COMPLETE, | ||
| 167 | DC_ADC0_CLOCK_INIT_BEGIN, | ||
| 168 | DC_ADC0_CLOCK_INIT_COMPLETE, | ||
| 169 | DC_ADC0_INIT_BEGIN, | ||
| 170 | DC_ADC0_SWRST_SYNCING_1, | ||
| 171 | DC_ADC0_SWRST_SYNCING_2, | ||
| 172 | DC_ADC0_AVGCTRL_SYNCING_1, | ||
| 173 | DC_ADC0_AVGCTRL_SYNCING_2, | ||
| 174 | DC_ADC0_SAMPCTRL_SYNCING_1, | ||
| 175 | DC_ADC0_ENABLE_SYNCING_1, | ||
| 176 | DC_ADC0_INIT_COMPLETE, | ||
| 177 | DC_I2C0_INIT_BEGIN, | ||
| 178 | DC_I2C0_INIT_SYNC_ENABLING, | ||
| 179 | DC_I2C0_INIT_SYNC_SYSOP, | ||
| 180 | DC_I2C0_INIT_WAIT_IDLE, | ||
| 181 | DC_I2C0_INIT_COMPLETE, | ||
| 182 | DC_I2C1_INIT_BEGIN, | ||
| 183 | DC_I2C1_INIT_SYNC_ENABLING, | ||
| 184 | DC_I2C1_INIT_SYNC_SYSOP, | ||
| 185 | DC_I2C1_INIT_WAIT_IDLE, | ||
| 186 | DC_I2C1_INIT_COMPLETE, | ||
| 187 | DC_I2C3733_INIT_CONTROL_BEGIN, | ||
| 188 | DC_I2C3733_INIT_CONTROL_COMPLETE, | ||
| 189 | DC_I2C3733_INIT_DRIVERS_BEGIN, | ||
| 190 | DC_I2C3733_INIT_DRIVERS_COMPLETE, | ||
| 191 | DC_I2C_DMAC_LED_INIT_BEGIN, | ||
| 192 | DC_I2C_DMAC_LED_INIT_COMPLETE, | ||
| 193 | DC_I2C3733_CONTROL_SET_BEGIN, | ||
| 194 | DC_I2C3733_CONTROL_SET_COMPLETE, | ||
| 195 | DC_LED_MATRIX_INIT_BEGIN, | ||
| 196 | DC_LED_MATRIX_INIT_COMPLETE, | ||
| 197 | DC_USB2422_INIT_BEGIN, | ||
| 198 | DC_USB2422_INIT_WAIT_5V_LOW, | ||
| 199 | DC_USB2422_INIT_OSC_SYNC_DISABLING, | ||
| 200 | DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_1, | ||
| 201 | DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_2, | ||
| 202 | DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_3, | ||
| 203 | DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_4, | ||
| 204 | DC_USB2422_INIT_OSC_SYNC_DFLLMUL, | ||
| 205 | DC_USB2422_INIT_OSC_SYNC_ENABLING, | ||
| 206 | DC_USB2422_INIT_USB_SYNC_SWRST, | ||
| 207 | DC_USB2422_INIT_USB_WAIT_SWRST, | ||
| 208 | DC_USB2422_INIT_USB_SYNC_ENABLING, | ||
| 209 | DC_USB2422_INIT_COMPLETE, | ||
| 210 | DC_MAIN_UDC_START_BEGIN, | ||
| 211 | DC_MAIN_UDC_START_COMPLETE, | ||
| 212 | DC_MAIN_CDC_INIT_BEGIN, | ||
| 213 | DC_MAIN_CDC_INIT_COMPLETE, | ||
| 214 | /* Never change the order of error codes! Only add codes to end! */ | ||
| 215 | }; | ||
| 216 | |||
| 217 | #else | ||
| 218 | |||
| 219 | # define DBGC(n) \ | ||
| 220 | {} | ||
| 221 | |||
| 222 | #endif // DEBUG_BOOT_TRACING_ENABLE | ||
| 223 | |||
| 224 | #endif //_D51_UTIL_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/i2c_master.c b/tmk_core/protocol/arm_atsam/i2c_master.c deleted file mode 100644 index 07ffcc8172..0000000000 --- a/tmk_core/protocol/arm_atsam/i2c_master.c +++ /dev/null | |||
| @@ -1,593 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include "arm_atsam_protocol.h" | ||
| 19 | |||
| 20 | #if !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE) | ||
| 21 | |||
| 22 | # include <string.h> | ||
| 23 | |||
| 24 | // From keyboard | ||
| 25 | # include "config.h" | ||
| 26 | # include "config_led.h" | ||
| 27 | # include "matrix.h" | ||
| 28 | |||
| 29 | # define I2C_LED_USE_DMA 1 // Set 1 to use background DMA transfers for leds, Set 0 to use inline software transfers | ||
| 30 | |||
| 31 | DmacDescriptor dmac_desc; | ||
| 32 | DmacDescriptor dmac_desc_wb; | ||
| 33 | |||
| 34 | static uint8_t i2c_led_q[I2C_Q_SIZE]; // I2C queue circular buffer | ||
| 35 | static uint8_t i2c_led_q_s; // Start of circular buffer | ||
| 36 | static uint8_t i2c_led_q_e; // End of circular buffer | ||
| 37 | static uint8_t i2c_led_q_full; // Queue full counter for reset | ||
| 38 | |||
| 39 | static uint8_t dma_sendbuf[I2C_DMA_MAX_SEND]; // Data being written to I2C | ||
| 40 | |||
| 41 | volatile uint8_t i2c_led_q_running; | ||
| 42 | |||
| 43 | #endif // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE) | ||
| 44 | |||
| 45 | void i2c0_init(void) { | ||
| 46 | DBGC(DC_I2C0_INIT_BEGIN); | ||
| 47 | |||
| 48 | CLK_set_i2c0_freq(CHAN_SERCOM_I2C0, FREQ_I2C0_DEFAULT); | ||
| 49 | |||
| 50 | // MCU | ||
| 51 | PORT->Group[0].PMUX[4].bit.PMUXE = 2; | ||
| 52 | PORT->Group[0].PMUX[4].bit.PMUXO = 2; | ||
| 53 | PORT->Group[0].PINCFG[8].bit.PMUXEN = 1; | ||
| 54 | PORT->Group[0].PINCFG[9].bit.PMUXEN = 1; | ||
| 55 | |||
| 56 | // I2C | ||
| 57 | // Note: SW Reset handled in CLK_set_i2c0_freq clks.c | ||
| 58 | |||
| 59 | SERCOM0->I2CM.CTRLA.bit.MODE = 5; // Set master mode | ||
| 60 | |||
| 61 | SERCOM0->I2CM.CTRLA.bit.SPEED = 0; // Set to 1 for Fast-mode Plus (FM+) up to 1 MHz | ||
| 62 | SERCOM0->I2CM.CTRLA.bit.RUNSTDBY = 1; // Enabled | ||
| 63 | |||
| 64 | SERCOM0->I2CM.CTRLA.bit.ENABLE = 1; // Enable the device | ||
| 65 | while (SERCOM0->I2CM.SYNCBUSY.bit.ENABLE) { | ||
| 66 | DBGC(DC_I2C0_INIT_SYNC_ENABLING); | ||
| 67 | } // Wait for SYNCBUSY.ENABLE to clear | ||
| 68 | |||
| 69 | SERCOM0->I2CM.STATUS.bit.BUSSTATE = 1; // Force into IDLE state | ||
| 70 | while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) { | ||
| 71 | DBGC(DC_I2C0_INIT_SYNC_SYSOP); | ||
| 72 | } | ||
| 73 | while (SERCOM0->I2CM.STATUS.bit.BUSSTATE != 1) { | ||
| 74 | DBGC(DC_I2C0_INIT_WAIT_IDLE); | ||
| 75 | } // Wait while not idle | ||
| 76 | |||
| 77 | DBGC(DC_I2C0_INIT_COMPLETE); | ||
| 78 | } | ||
| 79 | |||
| 80 | uint8_t i2c0_start(uint8_t address) { | ||
| 81 | SERCOM0->I2CM.ADDR.bit.ADDR = address; | ||
| 82 | while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) { | ||
| 83 | } | ||
| 84 | while (SERCOM0->I2CM.INTFLAG.bit.MB == 0) { | ||
| 85 | } | ||
| 86 | while (SERCOM0->I2CM.STATUS.bit.RXNACK) { | ||
| 87 | } | ||
| 88 | |||
| 89 | return 1; | ||
| 90 | } | ||
| 91 | |||
| 92 | uint8_t i2c0_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout) { | ||
| 93 | if (!length) return 0; | ||
| 94 | |||
| 95 | i2c0_start(address); | ||
| 96 | |||
| 97 | while (length) { | ||
| 98 | SERCOM0->I2CM.DATA.bit.DATA = *data; | ||
| 99 | while (SERCOM0->I2CM.INTFLAG.bit.MB == 0) { | ||
| 100 | } | ||
| 101 | while (SERCOM0->I2CM.STATUS.bit.RXNACK) { | ||
| 102 | } | ||
| 103 | |||
| 104 | data++; | ||
| 105 | length--; | ||
| 106 | } | ||
| 107 | |||
| 108 | i2c0_stop(); | ||
| 109 | |||
| 110 | return 1; | ||
| 111 | } | ||
| 112 | |||
| 113 | void i2c0_stop(void) { | ||
| 114 | if (SERCOM0->I2CM.STATUS.bit.CLKHOLD || SERCOM0->I2CM.INTFLAG.bit.MB == 1 || SERCOM0->I2CM.STATUS.bit.BUSSTATE != 1) { | ||
| 115 | SERCOM0->I2CM.CTRLB.bit.CMD = 3; | ||
| 116 | while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) | ||
| 117 | ; | ||
| 118 | while (SERCOM0->I2CM.STATUS.bit.CLKHOLD) | ||
| 119 | ; | ||
| 120 | while (SERCOM0->I2CM.INTFLAG.bit.MB) | ||
| 121 | ; | ||
| 122 | while (SERCOM0->I2CM.STATUS.bit.BUSSTATE != 1) | ||
| 123 | ; | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | #if !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE) | ||
| 128 | void i2c1_init(void) { | ||
| 129 | DBGC(DC_I2C1_INIT_BEGIN); | ||
| 130 | |||
| 131 | CLK_set_i2c1_freq(CHAN_SERCOM_I2C1, FREQ_I2C1_DEFAULT); | ||
| 132 | |||
| 133 | /* MCU */ | ||
| 134 | PORT->Group[0].PMUX[8].bit.PMUXE = 2; | ||
| 135 | PORT->Group[0].PMUX[8].bit.PMUXO = 2; | ||
| 136 | PORT->Group[0].PINCFG[16].bit.PMUXEN = 1; | ||
| 137 | PORT->Group[0].PINCFG[17].bit.PMUXEN = 1; | ||
| 138 | |||
| 139 | /* I2C */ | ||
| 140 | // Note: SW Reset handled in CLK_set_i2c1_freq clks.c | ||
| 141 | |||
| 142 | SERCOM1->I2CM.CTRLA.bit.MODE = 5; // MODE: Set master mode (No sync) | ||
| 143 | SERCOM1->I2CM.CTRLA.bit.SPEED = 1; // SPEED: Fm+ up to 1MHz (No sync) | ||
| 144 | SERCOM1->I2CM.CTRLA.bit.RUNSTDBY = 1; // RUNSTBY: Enabled (No sync) | ||
| 145 | |||
| 146 | SERCOM1->I2CM.CTRLB.bit.SMEN = 1; // SMEN: Smart mode enabled (For DMA)(No sync) | ||
| 147 | |||
| 148 | NVIC_EnableIRQ(SERCOM1_0_IRQn); | ||
| 149 | SERCOM1->I2CM.INTENSET.bit.ERROR = 1; | ||
| 150 | |||
| 151 | SERCOM1->I2CM.CTRLA.bit.ENABLE = 1; // ENABLE: Enable the device (sync SYNCBUSY.ENABLE) | ||
| 152 | while (SERCOM1->I2CM.SYNCBUSY.bit.ENABLE) { | ||
| 153 | DBGC(DC_I2C1_INIT_SYNC_ENABLING); | ||
| 154 | } // Wait for SYNCBUSY.ENABLE to clear | ||
| 155 | |||
| 156 | SERCOM1->I2CM.STATUS.bit.BUSSTATE = 1; // BUSSTATE: Force into IDLE state (sync SYNCBUSY.SYSOP) | ||
| 157 | while (SERCOM1->I2CM.SYNCBUSY.bit.SYSOP) { | ||
| 158 | DBGC(DC_I2C1_INIT_SYNC_SYSOP); | ||
| 159 | } | ||
| 160 | while (SERCOM1->I2CM.STATUS.bit.BUSSTATE != 1) { | ||
| 161 | DBGC(DC_I2C1_INIT_WAIT_IDLE); | ||
| 162 | } // Wait while not idle | ||
| 163 | |||
| 164 | DBGC(DC_I2C1_INIT_COMPLETE); | ||
| 165 | } | ||
| 166 | |||
| 167 | uint8_t i2c1_start(uint8_t address) { | ||
| 168 | SERCOM1->I2CM.ADDR.bit.ADDR = address; | ||
| 169 | while (SERCOM1->I2CM.SYNCBUSY.bit.SYSOP) { | ||
| 170 | } | ||
| 171 | while (SERCOM1->I2CM.INTFLAG.bit.MB == 0) { | ||
| 172 | } | ||
| 173 | while (SERCOM1->I2CM.STATUS.bit.RXNACK) { | ||
| 174 | } | ||
| 175 | |||
| 176 | return 1; | ||
| 177 | } | ||
| 178 | |||
| 179 | uint8_t i2c1_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout) { | ||
| 180 | if (!length) return 0; | ||
| 181 | |||
| 182 | i2c1_start(address); | ||
| 183 | |||
| 184 | while (length) { | ||
| 185 | SERCOM1->I2CM.DATA.bit.DATA = *data; | ||
| 186 | while (SERCOM1->I2CM.INTFLAG.bit.MB == 0) { | ||
| 187 | } | ||
| 188 | while (SERCOM1->I2CM.STATUS.bit.RXNACK) { | ||
| 189 | } | ||
| 190 | |||
| 191 | data++; | ||
| 192 | length--; | ||
| 193 | } | ||
| 194 | |||
| 195 | i2c1_stop(); | ||
| 196 | |||
| 197 | return 1; | ||
| 198 | } | ||
| 199 | |||
| 200 | void i2c1_stop(void) { | ||
| 201 | if (SERCOM1->I2CM.STATUS.bit.CLKHOLD || SERCOM1->I2CM.INTFLAG.bit.MB == 1 || SERCOM1->I2CM.STATUS.bit.BUSSTATE != 1) { | ||
| 202 | SERCOM1->I2CM.CTRLB.bit.CMD = 3; | ||
| 203 | while (SERCOM1->I2CM.SYNCBUSY.bit.SYSOP) | ||
| 204 | ; | ||
| 205 | while (SERCOM1->I2CM.STATUS.bit.CLKHOLD) | ||
| 206 | ; | ||
| 207 | while (SERCOM1->I2CM.INTFLAG.bit.MB) | ||
| 208 | ; | ||
| 209 | while (SERCOM1->I2CM.STATUS.bit.BUSSTATE != 1) | ||
| 210 | ; | ||
| 211 | } | ||
| 212 | } | ||
| 213 | |||
| 214 | void i2c_led_send_CRWL(uint8_t drvid) { | ||
| 215 | uint8_t i2cdata[] = {ISSI3733_CMDRWL, ISSI3733_CMDRWL_WRITE_ENABLE_ONCE}; | ||
| 216 | i2c1_transmit(issidrv[drvid].addr, i2cdata, sizeof(i2cdata), 0); | ||
| 217 | } | ||
| 218 | |||
| 219 | void i2c_led_select_page(uint8_t drvid, uint8_t pageno) { | ||
| 220 | uint8_t i2cdata[] = {ISSI3733_CMDR, pageno}; | ||
| 221 | i2c1_transmit(issidrv[drvid].addr, i2cdata, sizeof(i2cdata), 0); | ||
| 222 | } | ||
| 223 | |||
| 224 | void i2c_led_send_GCR(uint8_t drvid) { | ||
| 225 | uint8_t i2cdata[] = {ISSI3733_GCCR, 0x00}; | ||
| 226 | |||
| 227 | if (gcr_actual > LED_GCR_MAX) gcr_actual = LED_GCR_MAX; | ||
| 228 | i2cdata[1] = gcr_actual; | ||
| 229 | |||
| 230 | i2c1_transmit(issidrv[drvid].addr, i2cdata, sizeof(i2cdata), 0); | ||
| 231 | } | ||
| 232 | |||
| 233 | void i2c_led_send_onoff(uint8_t drvid) { | ||
| 234 | # if I2C_LED_USE_DMA != 1 | ||
| 235 | if (!i2c_led_q_running) { | ||
| 236 | # endif | ||
| 237 | i2c_led_send_CRWL(drvid); | ||
| 238 | i2c_led_select_page(drvid, 0); | ||
| 239 | # if I2C_LED_USE_DMA != 1 | ||
| 240 | } | ||
| 241 | # endif | ||
| 242 | |||
| 243 | *issidrv[drvid].onoff = 0; // Force start location offset to zero | ||
| 244 | i2c1_transmit(issidrv[drvid].addr, issidrv[drvid].onoff, ISSI3733_PG0_BYTES, 0); | ||
| 245 | } | ||
| 246 | |||
| 247 | void i2c_led_send_mode_op_gcr(uint8_t drvid, uint8_t mode, uint8_t operation) { | ||
| 248 | uint8_t i2cdata[] = {ISSI3733_CR, mode | operation, gcr_actual}; | ||
| 249 | i2c1_transmit(issidrv[drvid].addr, i2cdata, sizeof(i2cdata), 0); | ||
| 250 | } | ||
| 251 | |||
| 252 | void i2c_led_send_pur_pdr(uint8_t drvid, uint8_t pur, uint8_t pdr) { | ||
| 253 | uint8_t i2cdata[] = {ISSI3733_SWYR_PUR, pur, pdr}; | ||
| 254 | |||
| 255 | i2c1_transmit(issidrv[drvid].addr, i2cdata, sizeof(i2cdata), 0); | ||
| 256 | } | ||
| 257 | |||
| 258 | void i2c_led_send_pwm(uint8_t drvid) { | ||
| 259 | # if I2C_LED_USE_DMA != 1 | ||
| 260 | if (!i2c_led_q_running) { | ||
| 261 | # endif | ||
| 262 | i2c_led_send_CRWL(drvid); | ||
| 263 | i2c_led_select_page(drvid, 0); | ||
| 264 | # if I2C_LED_USE_DMA != 1 | ||
| 265 | } | ||
| 266 | # endif | ||
| 267 | |||
| 268 | *issidrv[drvid].pwm = 0; // Force start location offset to zero | ||
| 269 | i2c1_transmit(issidrv[drvid].addr, issidrv[drvid].pwm, ISSI3733_PG1_BYTES, 0); | ||
| 270 | } | ||
| 271 | |||
| 272 | uint8_t I2C3733_Init_Control(void) { | ||
| 273 | DBGC(DC_I2C3733_INIT_CONTROL_BEGIN); | ||
| 274 | |||
| 275 | // Hardware state shutdown on boot | ||
| 276 | // USB state machine will enable driver when communication is ready | ||
| 277 | I2C3733_Control_Set(0); | ||
| 278 | |||
| 279 | wait_ms(1); | ||
| 280 | |||
| 281 | sr_exp_data.bit.IRST = 0; | ||
| 282 | SR_EXP_WriteData(); | ||
| 283 | |||
| 284 | wait_ms(1); | ||
| 285 | |||
| 286 | DBGC(DC_I2C3733_INIT_CONTROL_COMPLETE); | ||
| 287 | |||
| 288 | return 1; | ||
| 289 | } | ||
| 290 | |||
| 291 | uint8_t I2C3733_Init_Drivers(void) { | ||
| 292 | DBGC(DC_I2C3733_INIT_DRIVERS_BEGIN); | ||
| 293 | |||
| 294 | gcr_actual = ISSI3733_GCR_DEFAULT; | ||
| 295 | gcr_actual_last = gcr_actual; | ||
| 296 | |||
| 297 | if (gcr_actual > LED_GCR_MAX) gcr_actual = LED_GCR_MAX; | ||
| 298 | gcr_desired = gcr_actual; | ||
| 299 | |||
| 300 | void issi3733_prepare_arrays(void); | ||
| 301 | issi3733_prepare_arrays(); | ||
| 302 | |||
| 303 | // Set up master device | ||
| 304 | i2c_led_send_CRWL(0); | ||
| 305 | i2c_led_select_page(0, 3); | ||
| 306 | i2c_led_send_mode_op_gcr(0, 0, ISSI3733_CR_SSD_NORMAL); // No SYNC due to brightness mismatch with second driver | ||
| 307 | |||
| 308 | // Set up slave device | ||
| 309 | i2c_led_send_CRWL(1); | ||
| 310 | i2c_led_select_page(1, 3); | ||
| 311 | 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 | ||
| 312 | |||
| 313 | i2c_led_send_CRWL(0); | ||
| 314 | i2c_led_select_page(0, 3); | ||
| 315 | i2c_led_send_pur_pdr(0, ISSI3733_SWYR_PUR_8000, ISSI3733_CSXR_PDR_8000); | ||
| 316 | |||
| 317 | i2c_led_send_CRWL(1); | ||
| 318 | i2c_led_select_page(1, 3); | ||
| 319 | i2c_led_send_pur_pdr(1, ISSI3733_SWYR_PUR_8000, ISSI3733_CSXR_PDR_8000); | ||
| 320 | |||
| 321 | DBGC(DC_I2C3733_INIT_DRIVERS_COMPLETE); | ||
| 322 | |||
| 323 | return 1; | ||
| 324 | } | ||
| 325 | |||
| 326 | void I2C_DMAC_LED_Init(void) { | ||
| 327 | Dmac *dmac = DMAC; | ||
| 328 | |||
| 329 | DBGC(DC_I2C_DMAC_LED_INIT_BEGIN); | ||
| 330 | |||
| 331 | // Disable device | ||
| 332 | dmac->CTRL.bit.DMAENABLE = 0; // Disable DMAC | ||
| 333 | while (dmac->CTRL.bit.DMAENABLE) { | ||
| 334 | } // Wait for disabled state in case of ongoing transfers | ||
| 335 | dmac->CTRL.bit.SWRST = 1; // Software Reset DMAC | ||
| 336 | while (dmac->CTRL.bit.SWRST) { | ||
| 337 | } // Wait for software reset to complete | ||
| 338 | |||
| 339 | // Configure device | ||
| 340 | dmac->BASEADDR.reg = (uint32_t)&dmac_desc; // Set descriptor base address | ||
| 341 | dmac->WRBADDR.reg = (uint32_t)&dmac_desc_wb; // Set descriptor write back address | ||
| 342 | dmac->CTRL.reg |= 0x0f00; // Handle all priorities (LVL0-3) | ||
| 343 | |||
| 344 | // Disable channel | ||
| 345 | dmac->Channel[0].CHCTRLA.bit.ENABLE = 0; // Disable the channel | ||
| 346 | while (dmac->Channel[0].CHCTRLA.bit.ENABLE) { | ||
| 347 | } // Wait for disabled state in case of ongoing transfers | ||
| 348 | dmac->Channel[0].CHCTRLA.bit.SWRST = 1; // Software Reset the channel | ||
| 349 | while (dmac->Channel[0].CHCTRLA.bit.SWRST) { | ||
| 350 | } // Wait for software reset to complete | ||
| 351 | |||
| 352 | // Configure channel | ||
| 353 | dmac->Channel[0].CHCTRLA.bit.THRESHOLD = 0; // 1BEAT | ||
| 354 | dmac->Channel[0].CHCTRLA.bit.BURSTLEN = 0; // SINGLE | ||
| 355 | dmac->Channel[0].CHCTRLA.bit.TRIGACT = 2; // BURST | ||
| 356 | dmac->Channel[0].CHCTRLA.bit.TRIGSRC = SERCOM1_DMAC_ID_TX; // Trigger source | ||
| 357 | dmac->Channel[0].CHCTRLA.bit.RUNSTDBY = 1; // Run in standby | ||
| 358 | |||
| 359 | NVIC_EnableIRQ(DMAC_0_IRQn); | ||
| 360 | dmac->Channel[0].CHINTENSET.bit.TCMPL = 1; | ||
| 361 | dmac->Channel[0].CHINTENSET.bit.TERR = 1; | ||
| 362 | |||
| 363 | // Enable device | ||
| 364 | dmac->CTRL.bit.DMAENABLE = 1; // Enable DMAC | ||
| 365 | while (dmac->CTRL.bit.DMAENABLE == 0) { | ||
| 366 | } // Wait for enable state | ||
| 367 | |||
| 368 | DBGC(DC_I2C_DMAC_LED_INIT_COMPLETE); | ||
| 369 | } | ||
| 370 | |||
| 371 | // state = 1 enable | ||
| 372 | // state = 0 disable | ||
| 373 | void I2C3733_Control_Set(uint8_t state) { | ||
| 374 | DBGC(DC_I2C3733_CONTROL_SET_BEGIN); | ||
| 375 | |||
| 376 | sr_exp_data.bit.SDB_N = (state == 1 ? 1 : 0); | ||
| 377 | SR_EXP_WriteData(); | ||
| 378 | |||
| 379 | DBGC(DC_I2C3733_CONTROL_SET_COMPLETE); | ||
| 380 | } | ||
| 381 | |||
| 382 | void i2c_led_desc_defaults(void) { | ||
| 383 | dmac_desc.BTCTRL.bit.STEPSIZE = 0; // SRCINC used in favor for auto 1 inc | ||
| 384 | dmac_desc.BTCTRL.bit.STEPSEL = 0; // SRCINC used in favor for auto 1 inc | ||
| 385 | dmac_desc.BTCTRL.bit.DSTINC = 0; // The Destination Address Increment is disabled | ||
| 386 | dmac_desc.BTCTRL.bit.SRCINC = 1; // The Source Address Increment is enabled (Inc by 1) | ||
| 387 | dmac_desc.BTCTRL.bit.BEATSIZE = 0; // 8-bit bus transfer | ||
| 388 | dmac_desc.BTCTRL.bit.BLOCKACT = 0; // Channel will be disabled if it is the last block transfer in the transaction | ||
| 389 | dmac_desc.BTCTRL.bit.EVOSEL = 0; // Event generation disabled | ||
| 390 | dmac_desc.BTCTRL.bit.VALID = 1; // Set dmac valid | ||
| 391 | } | ||
| 392 | |||
| 393 | void i2c_led_prepare_send_dma(uint8_t *data, uint8_t len) { | ||
| 394 | i2c_led_desc_defaults(); | ||
| 395 | |||
| 396 | dmac_desc.BTCNT.reg = len; | ||
| 397 | dmac_desc.SRCADDR.reg = (uint32_t)data + len; | ||
| 398 | dmac_desc.DSTADDR.reg = (uint32_t)&SERCOM1->I2CM.DATA.reg; | ||
| 399 | dmac_desc.DESCADDR.reg = 0; | ||
| 400 | } | ||
| 401 | |||
| 402 | void i2c_led_begin_dma(uint8_t drvid) { | ||
| 403 | DMAC->Channel[0].CHCTRLA.bit.ENABLE = 1; // Enable the channel | ||
| 404 | |||
| 405 | SERCOM1->I2CM.ADDR.reg = (dmac_desc.BTCNT.reg << 16) | 0x2000 | issidrv[drvid].addr; // Begin transfer | ||
| 406 | } | ||
| 407 | |||
| 408 | void i2c_led_send_CRWL_dma(uint8_t drvid) { | ||
| 409 | *(dma_sendbuf + 0) = ISSI3733_CMDRWL; | ||
| 410 | *(dma_sendbuf + 1) = ISSI3733_CMDRWL_WRITE_ENABLE_ONCE; | ||
| 411 | i2c_led_prepare_send_dma(dma_sendbuf, 2); | ||
| 412 | |||
| 413 | i2c_led_begin_dma(drvid); | ||
| 414 | } | ||
| 415 | |||
| 416 | void i2c_led_select_page_dma(uint8_t drvid, uint8_t pageno) { | ||
| 417 | *(dma_sendbuf + 0) = ISSI3733_CMDR; | ||
| 418 | *(dma_sendbuf + 1) = pageno; | ||
| 419 | i2c_led_prepare_send_dma(dma_sendbuf, 2); | ||
| 420 | |||
| 421 | i2c_led_begin_dma(drvid); | ||
| 422 | } | ||
| 423 | |||
| 424 | void i2c_led_send_GCR_dma(uint8_t drvid) { | ||
| 425 | *(dma_sendbuf + 0) = ISSI3733_GCCR; | ||
| 426 | *(dma_sendbuf + 1) = gcr_actual; | ||
| 427 | i2c_led_prepare_send_dma(dma_sendbuf, 2); | ||
| 428 | |||
| 429 | i2c_led_begin_dma(drvid); | ||
| 430 | } | ||
| 431 | |||
| 432 | void i2c_led_send_pwm_dma(uint8_t drvid) { | ||
| 433 | // Note: This copies the CURRENT pwm buffer, which may be getting modified | ||
| 434 | memcpy(dma_sendbuf, issidrv[drvid].pwm, ISSI3733_PG1_BYTES); | ||
| 435 | *dma_sendbuf = 0; // Force start location offset to zero | ||
| 436 | i2c_led_prepare_send_dma(dma_sendbuf, ISSI3733_PG1_BYTES); | ||
| 437 | |||
| 438 | i2c_led_begin_dma(drvid); | ||
| 439 | } | ||
| 440 | |||
| 441 | void i2c_led_send_onoff_dma(uint8_t drvid) { | ||
| 442 | // Note: This copies the CURRENT onoff buffer, which may be getting modified | ||
| 443 | memcpy(dma_sendbuf, issidrv[drvid].onoff, ISSI3733_PG0_BYTES); | ||
| 444 | *dma_sendbuf = 0; // Force start location offset to zero | ||
| 445 | i2c_led_prepare_send_dma(dma_sendbuf, ISSI3733_PG0_BYTES); | ||
| 446 | |||
| 447 | i2c_led_begin_dma(drvid); | ||
| 448 | } | ||
| 449 | |||
| 450 | void i2c_led_q_init(void) { | ||
| 451 | memset(i2c_led_q, 0, I2C_Q_SIZE); | ||
| 452 | i2c_led_q_s = 0; | ||
| 453 | i2c_led_q_e = 0; | ||
| 454 | i2c_led_q_running = 0; | ||
| 455 | i2c_led_q_full = 0; | ||
| 456 | } | ||
| 457 | |||
| 458 | uint8_t i2c_led_q_isempty(void) { | ||
| 459 | return i2c_led_q_s == i2c_led_q_e; | ||
| 460 | } | ||
| 461 | |||
| 462 | uint8_t i2c_led_q_size(void) { | ||
| 463 | return (i2c_led_q_e - i2c_led_q_s) % I2C_Q_SIZE; | ||
| 464 | } | ||
| 465 | |||
| 466 | uint8_t i2c_led_q_available(void) { | ||
| 467 | return I2C_Q_SIZE - i2c_led_q_size() - 1; // Never allow end to meet start | ||
| 468 | } | ||
| 469 | |||
| 470 | void i2c_led_q_add(uint8_t cmd) { | ||
| 471 | // WARNING: Always request room before adding commands! | ||
| 472 | |||
| 473 | // Assign command | ||
| 474 | i2c_led_q[i2c_led_q_e] = cmd; | ||
| 475 | |||
| 476 | i2c_led_q_e = (i2c_led_q_e + 1) % I2C_Q_SIZE; // Move end up one or wrap | ||
| 477 | } | ||
| 478 | |||
| 479 | void i2c_led_q_s_advance(void) { | ||
| 480 | i2c_led_q_s = (i2c_led_q_s + 1) % I2C_Q_SIZE; // Move start up one or wrap | ||
| 481 | } | ||
| 482 | |||
| 483 | // Always request room before adding commands | ||
| 484 | // PS: In case the queue somehow gets filled, it will reset if it can not clear up | ||
| 485 | // PS: Could only get this to happen through unrealistic timings to overload the I2C bus | ||
| 486 | uint8_t i2c_led_q_request_room(uint8_t request_size) { | ||
| 487 | if (request_size > i2c_led_q_available()) { | ||
| 488 | i2c_led_q_full++; | ||
| 489 | |||
| 490 | if (i2c_led_q_full >= 100) // Give the queue a chance to clear up | ||
| 491 | { | ||
| 492 | DBG_LED_ON; | ||
| 493 | I2C_DMAC_LED_Init(); | ||
| 494 | i2c_led_q_init(); | ||
| 495 | return 1; | ||
| 496 | } | ||
| 497 | |||
| 498 | return 0; | ||
| 499 | } | ||
| 500 | |||
| 501 | i2c_led_q_full = 0; | ||
| 502 | |||
| 503 | return 1; | ||
| 504 | } | ||
| 505 | |||
| 506 | uint8_t i2c_led_q_run(void) { | ||
| 507 | if (i2c_led_q_isempty()) { | ||
| 508 | i2c_led_q_running = 0; | ||
| 509 | return 0; | ||
| 510 | } | ||
| 511 | |||
| 512 | if (i2c_led_q_running) return 1; | ||
| 513 | |||
| 514 | i2c_led_q_running = 1; | ||
| 515 | |||
| 516 | # if I2C_LED_USE_DMA != 1 | ||
| 517 | while (!i2c_led_q_isempty()) { | ||
| 518 | # endif | ||
| 519 | // run command | ||
| 520 | if (i2c_led_q[i2c_led_q_s] == I2C_Q_CRWL) { | ||
| 521 | i2c_led_q_s_advance(); | ||
| 522 | uint8_t drvid = i2c_led_q[i2c_led_q_s]; | ||
| 523 | # if I2C_LED_USE_DMA == 1 | ||
| 524 | i2c_led_send_CRWL_dma(drvid); | ||
| 525 | # else | ||
| 526 | i2c_led_send_CRWL(drvid); | ||
| 527 | # endif | ||
| 528 | } else if (i2c_led_q[i2c_led_q_s] == I2C_Q_PAGE_SELECT) { | ||
| 529 | i2c_led_q_s_advance(); | ||
| 530 | uint8_t drvid = i2c_led_q[i2c_led_q_s]; | ||
| 531 | i2c_led_q_s_advance(); | ||
| 532 | uint8_t page = i2c_led_q[i2c_led_q_s]; | ||
| 533 | # if I2C_LED_USE_DMA == 1 | ||
| 534 | i2c_led_select_page_dma(drvid, page); | ||
| 535 | # else | ||
| 536 | i2c_led_select_page(drvid, page); | ||
| 537 | # endif | ||
| 538 | } else if (i2c_led_q[i2c_led_q_s] == I2C_Q_PWM) { | ||
| 539 | i2c_led_q_s_advance(); | ||
| 540 | uint8_t drvid = i2c_led_q[i2c_led_q_s]; | ||
| 541 | # if I2C_LED_USE_DMA == 1 | ||
| 542 | i2c_led_send_pwm_dma(drvid); | ||
| 543 | # else | ||
| 544 | i2c_led_send_pwm(drvid); | ||
| 545 | # endif | ||
| 546 | } else if (i2c_led_q[i2c_led_q_s] == I2C_Q_GCR) { | ||
| 547 | i2c_led_q_s_advance(); | ||
| 548 | uint8_t drvid = i2c_led_q[i2c_led_q_s]; | ||
| 549 | # if I2C_LED_USE_DMA == 1 | ||
| 550 | i2c_led_send_GCR_dma(drvid); | ||
| 551 | # else | ||
| 552 | i2c_led_send_GCR(drvid); | ||
| 553 | # endif | ||
| 554 | } else if (i2c_led_q[i2c_led_q_s] == I2C_Q_ONOFF) { | ||
| 555 | i2c_led_q_s_advance(); | ||
| 556 | uint8_t drvid = i2c_led_q[i2c_led_q_s]; | ||
| 557 | # if I2C_LED_USE_DMA == 1 | ||
| 558 | i2c_led_send_onoff_dma(drvid); | ||
| 559 | # else | ||
| 560 | i2c_led_send_onoff(drvid); | ||
| 561 | # endif | ||
| 562 | } | ||
| 563 | |||
| 564 | i2c_led_q_s_advance(); // Advance last run command or if the command byte was not serviced | ||
| 565 | |||
| 566 | # if I2C_LED_USE_DMA != 1 | ||
| 567 | } | ||
| 568 | |||
| 569 | i2c_led_q_running = 0; | ||
| 570 | # endif | ||
| 571 | |||
| 572 | return 1; | ||
| 573 | } | ||
| 574 | |||
| 575 | __attribute__((weak)) void i2c_init(void) { | ||
| 576 | static bool is_initialised = false; | ||
| 577 | if (!is_initialised) { | ||
| 578 | is_initialised = true; | ||
| 579 | |||
| 580 | i2c0_init(); | ||
| 581 | } | ||
| 582 | } | ||
| 583 | |||
| 584 | i2c_status_t i2c_transmit(uint8_t address, const uint8_t *data, uint16_t length, uint16_t timeout) { | ||
| 585 | uint8_t ret = i2c0_transmit(address, (uint8_t *)data, length, timeout); | ||
| 586 | SERCOM0->I2CM.CTRLB.bit.CMD = 0x03; | ||
| 587 | while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) { | ||
| 588 | DBGC(DC_USB_WRITE2422_BLOCK_SYNC_SYSOP); | ||
| 589 | } | ||
| 590 | return ret ? I2C_STATUS_SUCCESS : I2C_STATUS_ERROR; | ||
| 591 | } | ||
| 592 | |||
| 593 | #endif // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE) | ||
diff --git a/tmk_core/protocol/arm_atsam/i2c_master.h b/tmk_core/protocol/arm_atsam/i2c_master.h deleted file mode 100644 index 5459923de4..0000000000 --- a/tmk_core/protocol/arm_atsam/i2c_master.h +++ /dev/null | |||
| @@ -1,113 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef _I2C_MASTER_H_ | ||
| 19 | #define _I2C_MASTER_H_ | ||
| 20 | |||
| 21 | #ifndef MD_BOOTLOADER | ||
| 22 | |||
| 23 | # include "samd51j18a.h" | ||
| 24 | # include "issi3733_driver.h" | ||
| 25 | # include "config.h" | ||
| 26 | |||
| 27 | extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc; | ||
| 28 | extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb; | ||
| 29 | |||
| 30 | uint8_t I2C3733_Init_Control(void); | ||
| 31 | uint8_t I2C3733_Init_Drivers(void); | ||
| 32 | void I2C3733_Control_Set(uint8_t state); | ||
| 33 | void I2C_DMAC_LED_Init(void); | ||
| 34 | |||
| 35 | # define I2C_Q_SIZE 100 | ||
| 36 | |||
| 37 | # define I2C_Q_NA 100 | ||
| 38 | # define I2C_Q_CRWL 101 | ||
| 39 | # define I2C_Q_PAGE_SELECT 102 | ||
| 40 | # define I2C_Q_PWM 103 | ||
| 41 | # define I2C_Q_GCR 104 | ||
| 42 | # define I2C_Q_ONOFF 105 | ||
| 43 | |||
| 44 | # define I2C_DMA_MAX_SEND 255 | ||
| 45 | |||
| 46 | extern volatile uint8_t i2c_led_q_running; | ||
| 47 | |||
| 48 | # define I2C_LED_Q_PWM(a) \ | ||
| 49 | { \ | ||
| 50 | if (i2c_led_q_request_room(7)) { \ | ||
| 51 | i2c_led_q_add(I2C_Q_CRWL); \ | ||
| 52 | i2c_led_q_add(a); \ | ||
| 53 | i2c_led_q_add(I2C_Q_PAGE_SELECT); \ | ||
| 54 | i2c_led_q_add(a); \ | ||
| 55 | i2c_led_q_add(ISSI3733_PG_PWM); \ | ||
| 56 | i2c_led_q_add(I2C_Q_PWM); \ | ||
| 57 | i2c_led_q_add(a); \ | ||
| 58 | } \ | ||
| 59 | } | ||
| 60 | |||
| 61 | # define I2C_LED_Q_GCR(a) \ | ||
| 62 | { \ | ||
| 63 | if (i2c_led_q_request_room(7)) { \ | ||
| 64 | i2c_led_q_add(I2C_Q_CRWL); \ | ||
| 65 | i2c_led_q_add(a); \ | ||
| 66 | i2c_led_q_add(I2C_Q_PAGE_SELECT); \ | ||
| 67 | i2c_led_q_add(a); \ | ||
| 68 | i2c_led_q_add(ISSI3733_PG_FN); \ | ||
| 69 | i2c_led_q_add(I2C_Q_GCR); \ | ||
| 70 | i2c_led_q_add(a); \ | ||
| 71 | } \ | ||
| 72 | } | ||
| 73 | |||
| 74 | # define I2C_LED_Q_ONOFF(a) \ | ||
| 75 | { \ | ||
| 76 | if (i2c_led_q_request_room(7)) { \ | ||
| 77 | i2c_led_q_add(I2C_Q_CRWL); \ | ||
| 78 | i2c_led_q_add(a); \ | ||
| 79 | i2c_led_q_add(I2C_Q_PAGE_SELECT); \ | ||
| 80 | i2c_led_q_add(a); \ | ||
| 81 | i2c_led_q_add(ISSI3733_PG_ONOFF); \ | ||
| 82 | i2c_led_q_add(I2C_Q_ONOFF); \ | ||
| 83 | i2c_led_q_add(a); \ | ||
| 84 | } \ | ||
| 85 | } | ||
| 86 | |||
| 87 | void i2c_led_q_init(void); | ||
| 88 | void i2c_led_q_add(uint8_t cmd); | ||
| 89 | void i2c_led_q_s_advance(void); | ||
| 90 | uint8_t i2c_led_q_size(void); | ||
| 91 | uint8_t i2c_led_q_request_room(uint8_t request_size); | ||
| 92 | uint8_t i2c_led_q_run(void); | ||
| 93 | |||
| 94 | void i2c1_init(void); | ||
| 95 | uint8_t i2c1_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout); | ||
| 96 | void i2c1_stop(void); | ||
| 97 | |||
| 98 | #endif // MD_BOOTLOADER | ||
| 99 | |||
| 100 | void i2c0_init(void); | ||
| 101 | uint8_t i2c0_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout); | ||
| 102 | void i2c0_stop(void); | ||
| 103 | |||
| 104 | // Terrible interface compatiblity... | ||
| 105 | #define I2C_STATUS_SUCCESS (0) | ||
| 106 | #define I2C_STATUS_ERROR (-1) | ||
| 107 | |||
| 108 | typedef int16_t i2c_status_t; | ||
| 109 | |||
| 110 | void i2c_init(void); | ||
| 111 | i2c_status_t i2c_transmit(uint8_t address, const uint8_t *data, uint16_t length, uint16_t timeout); | ||
| 112 | |||
| 113 | #endif // _I2C_MASTER_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/issi3733_driver.h b/tmk_core/protocol/arm_atsam/issi3733_driver.h deleted file mode 100644 index c01f147e13..0000000000 --- a/tmk_core/protocol/arm_atsam/issi3733_driver.h +++ /dev/null | |||
| @@ -1,201 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef _ISSI3733_DRIVER_H_ | ||
| 19 | #define _ISSI3733_DRIVER_H_ | ||
| 20 | |||
| 21 | // ISII3733 Registers | ||
| 22 | |||
| 23 | #define ISSI3733_CMDR 0xFD // Command Register (Write Only) | ||
| 24 | |||
| 25 | #define ISSI3733_CMDRWL 0xFE // Command Register Write Lock (Read/Write) | ||
| 26 | #define ISSI3733_CMDRWL_WRITE_DISABLE 0x00 // Lock register | ||
| 27 | #define ISSI3733_CMDRWL_WRITE_ENABLE_ONCE 0xC5 // Enable one write to register then reset to locked | ||
| 28 | |||
| 29 | #define ISSI3733_IMR 0xF0 // Interrupt Mask Register (Write Only) | ||
| 30 | #define ISSI3733_IMR_IAC_ON 0x08 // Auto Clear Interrupt Bit - Interrupt auto clear when INTB stay low exceeds 8ms | ||
| 31 | #define ISSI3733_IMR_IAB_ON 0x04 // Auto Breath Interrupt Bit - Enable auto breath loop finish interrupt | ||
| 32 | #define ISSI3733_IMR_IS_ON 0x02 // Dot Short Interrupt Bit - Enable dot short interrupt | ||
| 33 | #define ISSI3733_IMR_IO_ON 0x01 // Dot Open Interrupt Bit - Enable dot open interrupt | ||
| 34 | |||
| 35 | #define ISSI3733_ISR 0xF1 // Interrupt Status Register (Read Only) | ||
| 36 | #define ISSI3733_ISR_ABM3_FINISH 0x10 // Auto Breath Mode 3 Finish Bit - ABM3 finished | ||
| 37 | #define ISSI3733_ISR_ABM2_FINISH 0x08 // Auto Breath Mode 2 Finish Bit - ABM2 finished | ||
| 38 | #define ISSI3733_ISR_ABM1_FINISH 0x04 // Auto Breath Mode 1 Finish Bit - ABM1 finished | ||
| 39 | #define ISSI3733_ISR_SB 0x02 // Short Bit - Shorted | ||
| 40 | #define ISSI3733_ISR_OB 0x01 // Open Bit - Opened | ||
| 41 | |||
| 42 | #define ISSI3733_PG0 0x00 // LED Control Register | ||
| 43 | #define ISSI3733_PG1 0x01 // PWM Register | ||
| 44 | #define ISSI3733_PG2 0x02 // Auto Breath Mode Register | ||
| 45 | #define ISSI3733_PG3 0x03 // Function Register | ||
| 46 | |||
| 47 | #define ISSI3733_PG_ONOFF ISSI3733_PG0 | ||
| 48 | #define ISSI3733_PG_OR ISSI3733_PG0 | ||
| 49 | #define ISSI3733_PG_SR ISSI3733_PG0 | ||
| 50 | #define ISSI3733_PG_PWM ISSI3733_PG1 | ||
| 51 | #define ISSI3733_PG_ABM ISSI3733_PG2 | ||
| 52 | #define ISSI3733_PG_FN ISSI3733_PG3 | ||
| 53 | |||
| 54 | #define ISSI3733_CR 0x00 // Configuration Register | ||
| 55 | |||
| 56 | // PG3: Configuration Register: Synchronize Configuration | ||
| 57 | #define ISSI3733_CR_SYNC_MASTER 0x40 // Master | ||
| 58 | #define ISSI3733_CR_SYNC_SLAVE 0x80 // Slave | ||
| 59 | #define ISSI3733_CR_SYNC_HIGH_IMP 0xC0 // High Impedance | ||
| 60 | |||
| 61 | // PG3: Configuration Register: Open/Short Detection Enable Bit | ||
| 62 | //#define ISSI3733_CR_OSD_DISABLE 0x00 //Disable open/short detection | ||
| 63 | #define ISSI3733_CR_OSD_ENABLE 0x04 // Enable open/short detection | ||
| 64 | |||
| 65 | // PG3: Configuration Register: Auto Breath Enable | ||
| 66 | //#define ISSI3733_CR_B_EN_PWM 0x00 //PWM Mode Enable | ||
| 67 | #define ISSI3733_CR_B_EN_AUTO 0x02 // Auto Breath Mode Enable | ||
| 68 | |||
| 69 | // PG3: Configuration Register: Software Shutdown Control | ||
| 70 | //#define ISSI3733_CR_SSD_SHUTDOWN 0x00 //Software shutdown | ||
| 71 | #define ISSI3733_CR_SSD_NORMAL 0x01 // Normal operation | ||
| 72 | |||
| 73 | #define ISSI3733_GCCR 0x01 // Global Current Control Register | ||
| 74 | |||
| 75 | // 1 Byte, Iout = (GCC / 256) * (840 / Rext) | ||
| 76 | // TODO: Give user define for Rext | ||
| 77 | |||
| 78 | // PG3: Auto Breath Control Register 1 | ||
| 79 | #define ISSI3733_ABCR1_ABM1 0x02 // Auto Breath Control Register 1 of ABM-1 | ||
| 80 | #define ISSI3733_ABCR1_ABM2 0x06 // Auto Breath Control Register 1 of ABM-2 | ||
| 81 | #define ISSI3733_ABCR1_ABM3 0x0A // Auto Breath Control Register 1 of ABM-3 | ||
| 82 | |||
| 83 | // Rise time | ||
| 84 | #define ISSI3733_ABCR1_T1_0021 0x00 // 0.21s | ||
| 85 | #define ISSI3733_ABCR1_T1_0042 0x20 // 0.42s | ||
| 86 | #define ISSI3733_ABCR1_T1_0084 0x40 // 0.84s | ||
| 87 | #define ISSI3733_ABCR1_T1_0168 0x60 // 1.68s | ||
| 88 | #define ISSI3733_ABCR1_T1_0336 0x80 // 3.36s | ||
| 89 | #define ISSI3733_ABCR1_T1_0672 0xA0 // 6.72s | ||
| 90 | #define ISSI3733_ABCR1_T1_1344 0xC0 // 13.44s | ||
| 91 | #define ISSI3733_ABCR1_T1_2688 0xE0 // 26.88s | ||
| 92 | |||
| 93 | // Max value time | ||
| 94 | #define ISSI3733_ABCR1_T2_0000 0x00 // 0s | ||
| 95 | #define ISSI3733_ABCR1_T2_0021 0x02 // 0.21s | ||
| 96 | #define ISSI3733_ABCR1_T2_0042 0x04 // 0.42s | ||
| 97 | #define ISSI3733_ABCR1_T2_0084 0x06 // 0.84s | ||
| 98 | #define ISSI3733_ABCR1_T2_0168 0x08 // 1.68s | ||
| 99 | #define ISSI3733_ABCR1_T2_0336 0x0A // 3.36s | ||
| 100 | #define ISSI3733_ABCR1_T2_0672 0x0C // 6.72s | ||
| 101 | #define ISSI3733_ABCR1_T2_1344 0x0E // 13.44s | ||
| 102 | #define ISSI3733_ABCR1_T2_2688 0x10 // 26.88s | ||
| 103 | |||
| 104 | // PG3: Auto Breath Control Register 2 | ||
| 105 | #define ISSI3733_ABCR2_ABM1 0x03 // Auto Breath Control Register 2 of ABM-1 | ||
| 106 | #define ISSI3733_ABCR2_ABM2 0x07 // Auto Breath Control Register 2 of ABM-2 | ||
| 107 | #define ISSI3733_ABCR2_ABM3 0x0B // Auto Breath Control Register 2 of ABM-3 | ||
| 108 | |||
| 109 | // Fall time | ||
| 110 | #define ISSI3733_ABCR2_T3_0021 0x00 // 0.21s | ||
| 111 | #define ISSI3733_ABCR2_T3_0042 0x20 // 0.42s | ||
| 112 | #define ISSI3733_ABCR2_T3_0084 0x40 // 0.84s | ||
| 113 | #define ISSI3733_ABCR2_T3_0168 0x60 // 1.68s | ||
| 114 | #define ISSI3733_ABCR2_T3_0336 0x80 // 3.36s | ||
| 115 | #define ISSI3733_ABCR2_T3_0672 0xA0 // 6.72s | ||
| 116 | #define ISSI3733_ABCR2_T3_1344 0xC0 // 13.44s | ||
| 117 | #define ISSI3733_ABCR2_T3_2688 0xE0 // 26.88s | ||
| 118 | |||
| 119 | // Min value time | ||
| 120 | #define ISSI3733_ABCR2_T4_0000 0x00 // 0s | ||
| 121 | #define ISSI3733_ABCR2_T4_0021 0x02 // 0.21s | ||
| 122 | #define ISSI3733_ABCR2_T4_0042 0x04 // 0.42s | ||
| 123 | #define ISSI3733_ABCR2_T4_0084 0x06 // 0.84s | ||
| 124 | #define ISSI3733_ABCR2_T4_0168 0x08 // 1.68s | ||
| 125 | #define ISSI3733_ABCR2_T4_0336 0x0A // 3.36s | ||
| 126 | #define ISSI3733_ABCR2_T4_0672 0x0C // 6.72s | ||
| 127 | #define ISSI3733_ABCR2_T4_1344 0x0E // 13.44s | ||
| 128 | #define ISSI3733_ABCR2_T4_2688 0x10 // 26.88s | ||
| 129 | #define ISSI3733_ABCR2_T4_5376 0x12 // 53.76s | ||
| 130 | #define ISSI3733_ABCR2_T4_10752 0x14 // 107.52s | ||
| 131 | |||
| 132 | // PG3: Auto Breath Control Register 3 | ||
| 133 | #define ISSI3733_ABCR3_ABM1 0x04 // Auto Breath Control Register 3 of ABM-1 | ||
| 134 | #define ISSI3733_ABCR3_ABM2 0x08 // Auto Breath Control Register 3 of ABM-2 | ||
| 135 | #define ISSI3733_ABCR3_ABM3 0x0C // Auto Breath Control Register 3 of ABM-3 | ||
| 136 | |||
| 137 | #define ISSI3733_ABCR3_LTA_LOOP_ENDLESS 0x00 | ||
| 138 | #define ISSI3733_ABCR3_LTA_LOOP_1 0x01 | ||
| 139 | #define ISSI3733_ABCR3_LTA_LOOP_2 0x02 | ||
| 140 | #define ISSI3733_ABCR3_LTA_LOOP_3 0x03 | ||
| 141 | #define ISSI3733_ABCR3_LTA_LOOP_4 0x04 | ||
| 142 | #define ISSI3733_ABCR3_LTA_LOOP_5 0x05 | ||
| 143 | #define ISSI3733_ABCR3_LTA_LOOP_6 0x06 | ||
| 144 | #define ISSI3733_ABCR3_LTA_LOOP_7 0x07 | ||
| 145 | #define ISSI3733_ABCR3_LTA_LOOP_8 0x08 | ||
| 146 | #define ISSI3733_ABCR3_LTA_LOOP_9 0x09 | ||
| 147 | #define ISSI3733_ABCR3_LTA_LOOP_10 0x0A | ||
| 148 | #define ISSI3733_ABCR3_LTA_LOOP_11 0x0B | ||
| 149 | #define ISSI3733_ABCR3_LTA_LOOP_12 0x0C | ||
| 150 | #define ISSI3733_ABCR3_LTA_LOOP_13 0x0D | ||
| 151 | #define ISSI3733_ABCR3_LTA_LOOP_14 0x0E | ||
| 152 | #define ISSI3733_ABCR3_LTA_LOOP_15 0x0F | ||
| 153 | |||
| 154 | // Loop Begin | ||
| 155 | #define ISSI3733_ABCR3_LB_T1 0x00 | ||
| 156 | #define ISSI3733_ABCR3_LB_T2 0x10 | ||
| 157 | #define ISSI3733_ABCR3_LB_T3 0x20 | ||
| 158 | #define ISSI3733_ABCR3_LB_T4 0x30 | ||
| 159 | |||
| 160 | // Loop End | ||
| 161 | #define ISSI3733_ABCR3_LE_T3 0x00 // End at Off state | ||
| 162 | #define ISSI3733_ABCR3_LE_T1 0x40 // End at On State | ||
| 163 | |||
| 164 | // PG3: Auto Breath Control Register 4 | ||
| 165 | #define ISSI3733_ABCR4_ABM1 0x05 // Auto Breath Control Register 4 of ABM-1 | ||
| 166 | #define ISSI3733_ABCR4_ABM2 0x09 // Auto Breath Control Register 4 of ABM-2 | ||
| 167 | #define ISSI3733_ABCR4_ABM3 0x0D // Auto Breath Control Register 4 of ABM-3 | ||
| 168 | |||
| 169 | #define ISSI3733_ABCR4_LTB_LOOP_ENDLESS 0x00 | ||
| 170 | // Or 8bit loop times | ||
| 171 | |||
| 172 | // PG3: Time Update Register | ||
| 173 | #define ISSI3733_TUR 0x0E | ||
| 174 | #define ISSI3733_TUR_UPDATE 0x00 // Write to update 02h~0Dh time registers after configuring | ||
| 175 | |||
| 176 | // PG3: SWy Pull-Up Resistor Selection Register | ||
| 177 | #define ISSI3733_SWYR_PUR 0x0F | ||
| 178 | #define ISSI3733_SWYR_PUR_NONE 0x00 // No pull-up resistor | ||
| 179 | #define ISSI3733_SWYR_PUR_500 0x01 // 0.5k Ohm | ||
| 180 | #define ISSI3733_SWYR_PUR_1000 0x02 // 1.0k Ohm | ||
| 181 | #define ISSI3733_SWYR_PUR_2000 0x03 // 2.0k Ohm | ||
| 182 | #define ISSI3733_SWYR_PUR_4000 0x04 // 4.0k Ohm | ||
| 183 | #define ISSI3733_SWYR_PUR_8000 0x05 // 8.0k Ohm | ||
| 184 | #define ISSI3733_SWYR_PUR_16000 0x06 // 16k Ohm | ||
| 185 | #define ISSI3733_SWYR_PUR_32000 0x07 // 32k Ohm | ||
| 186 | |||
| 187 | // PG3: CSx Pull-Down Resistor Selection Register | ||
| 188 | #define ISSI3733_CSXR_PDR 0x10 | ||
| 189 | #define ISSI3733_CSXR_PDR_NONE 0x00 // No pull-down resistor | ||
| 190 | #define ISSI3733_CSXR_PDR_500 0x01 // 0.5k Ohm | ||
| 191 | #define ISSI3733_CSXR_PDR_1000 0x02 // 1.0k Ohm | ||
| 192 | #define ISSI3733_CSXR_PDR_2000 0x03 // 2.0k Ohm | ||
| 193 | #define ISSI3733_CSXR_PDR_4000 0x04 // 4.0k Ohm | ||
| 194 | #define ISSI3733_CSXR_PDR_8000 0x05 // 8.0k Ohm | ||
| 195 | #define ISSI3733_CSXR_PDR_16000 0x06 // 16k Ohm | ||
| 196 | #define ISSI3733_CSXR_PDR_32000 0x07 // 32k Ohm | ||
| 197 | |||
| 198 | // PG3: Reset Register | ||
| 199 | #define ISSI3733_RR 0x11 // Read to reset all registers to default values | ||
| 200 | |||
| 201 | #endif //_ISSI3733_DRIVER_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c deleted file mode 100644 index 15592bf908..0000000000 --- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c +++ /dev/null | |||
| @@ -1,381 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include "samd51j18a.h" | ||
| 19 | #include "keyboard.h" | ||
| 20 | |||
| 21 | #include "report.h" | ||
| 22 | #include "host.h" | ||
| 23 | #include "host_driver.h" | ||
| 24 | #include "suspend.h" | ||
| 25 | #include "keycode_config.h" | ||
| 26 | #include <string.h> | ||
| 27 | |||
| 28 | // From protocol directory | ||
| 29 | #include "arm_atsam_protocol.h" | ||
| 30 | |||
| 31 | // From keyboard's directory | ||
| 32 | #include "config_led.h" | ||
| 33 | |||
| 34 | uint8_t g_usb_state = USB_FSMSTATUS_FSMSTATE_OFF_Val; // Saved USB state from hardware value to detect changes | ||
| 35 | |||
| 36 | void main_subtasks(void); | ||
| 37 | uint8_t keyboard_leds(void); | ||
| 38 | void send_keyboard(report_keyboard_t *report); | ||
| 39 | void send_nkro(report_nkro_t *report); | ||
| 40 | void send_mouse(report_mouse_t *report); | ||
| 41 | void send_extra(report_extra_t *report); | ||
| 42 | |||
| 43 | #ifdef DEFERRED_EXEC_ENABLE | ||
| 44 | void deferred_exec_task(void); | ||
| 45 | #endif // DEFERRED_EXEC_ENABLE | ||
| 46 | |||
| 47 | host_driver_t arm_atsam_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra}; | ||
| 48 | |||
| 49 | uint8_t led_states; | ||
| 50 | |||
| 51 | uint8_t keyboard_leds(void) { | ||
| 52 | #ifdef NKRO_ENABLE | ||
| 53 | if (keymap_config.nkro) | ||
| 54 | return udi_hid_nkro_report_set; | ||
| 55 | else | ||
| 56 | #endif // NKRO_ENABLE | ||
| 57 | return udi_hid_kbd_report_set; | ||
| 58 | } | ||
| 59 | |||
| 60 | void send_keyboard(report_keyboard_t *report) { | ||
| 61 | uint32_t irqflags; | ||
| 62 | |||
| 63 | while (udi_hid_kbd_b_report_trans_ongoing) { | ||
| 64 | main_subtasks(); | ||
| 65 | } // Run other tasks while waiting for USB to be free | ||
| 66 | |||
| 67 | irqflags = __get_PRIMASK(); | ||
| 68 | __disable_irq(); | ||
| 69 | __DMB(); | ||
| 70 | |||
| 71 | memcpy(udi_hid_kbd_report, report, UDI_HID_KBD_REPORT_SIZE); | ||
| 72 | udi_hid_kbd_b_report_valid = 1; | ||
| 73 | udi_hid_kbd_send_report(); | ||
| 74 | |||
| 75 | __DMB(); | ||
| 76 | __set_PRIMASK(irqflags); | ||
| 77 | } | ||
| 78 | |||
| 79 | void send_nkro(report_nkro_t *report) { | ||
| 80 | #ifdef NKRO_ENABLE | ||
| 81 | uint32_t irqflags; | ||
| 82 | |||
| 83 | while (udi_hid_nkro_b_report_trans_ongoing) { | ||
| 84 | main_subtasks(); | ||
| 85 | } // Run other tasks while waiting for USB to be free | ||
| 86 | |||
| 87 | irqflags = __get_PRIMASK(); | ||
| 88 | __disable_irq(); | ||
| 89 | __DMB(); | ||
| 90 | |||
| 91 | /* | ||
| 92 | Skipping ahead `sizeof(report->report_id)` bytes | ||
| 93 | since `report_id` is not used by this driver | ||
| 94 | */ | ||
| 95 | void *report_no_report_id = (void *)((char *)report + sizeof(report->report_id)); | ||
| 96 | |||
| 97 | memcpy(udi_hid_nkro_report, report_no_report_id, UDI_HID_NKRO_REPORT_SIZE); | ||
| 98 | udi_hid_nkro_b_report_valid = 1; | ||
| 99 | udi_hid_nkro_send_report(); | ||
| 100 | |||
| 101 | __DMB(); | ||
| 102 | __set_PRIMASK(irqflags); | ||
| 103 | #endif | ||
| 104 | } | ||
| 105 | |||
| 106 | void send_mouse(report_mouse_t *report) { | ||
| 107 | #ifdef MOUSEKEY_ENABLE | ||
| 108 | uint32_t irqflags; | ||
| 109 | |||
| 110 | irqflags = __get_PRIMASK(); | ||
| 111 | __disable_irq(); | ||
| 112 | __DMB(); | ||
| 113 | |||
| 114 | # ifdef MOUSE_SHARED_EP | ||
| 115 | /* | ||
| 116 | Skipping ahead `sizeof(report->report_id)` bytes | ||
| 117 | since `report_id` is not used by this driver | ||
| 118 | */ | ||
| 119 | void *report_no_report_id = (void *)((char *)report + sizeof(report->report_id)); | ||
| 120 | |||
| 121 | memcpy(udi_hid_mou_report, report_no_report_id, UDI_HID_MOU_REPORT_SIZE); | ||
| 122 | # else | ||
| 123 | memcpy(udi_hid_mou_report, report, UDI_HID_MOU_REPORT_SIZE); | ||
| 124 | # endif | ||
| 125 | udi_hid_mou_b_report_valid = 1; | ||
| 126 | udi_hid_mou_send_report(); | ||
| 127 | |||
| 128 | __DMB(); | ||
| 129 | __set_PRIMASK(irqflags); | ||
| 130 | #endif // MOUSEKEY_ENABLE | ||
| 131 | } | ||
| 132 | |||
| 133 | void send_extra(report_extra_t *report) { | ||
| 134 | #ifdef EXTRAKEY_ENABLE | ||
| 135 | uint32_t irqflags; | ||
| 136 | |||
| 137 | irqflags = __get_PRIMASK(); | ||
| 138 | __disable_irq(); | ||
| 139 | __DMB(); | ||
| 140 | |||
| 141 | memcpy(udi_hid_exk_report, report, UDI_HID_EXK_REPORT_SIZE); | ||
| 142 | udi_hid_exk_b_report_valid = 1; | ||
| 143 | udi_hid_exk_send_report(); | ||
| 144 | |||
| 145 | __DMB(); | ||
| 146 | __set_PRIMASK(irqflags); | ||
| 147 | #endif // EXTRAKEY_ENABLE | ||
| 148 | } | ||
| 149 | |||
| 150 | #ifdef CONSOLE_ENABLE | ||
| 151 | # define CONSOLE_PRINTBUF_SIZE 512 | ||
| 152 | static char console_printbuf[CONSOLE_PRINTBUF_SIZE]; | ||
| 153 | static uint16_t console_printbuf_len = 0; | ||
| 154 | |||
| 155 | int8_t sendchar(uint8_t c) { | ||
| 156 | if (console_printbuf_len >= CONSOLE_PRINTBUF_SIZE) return -1; | ||
| 157 | |||
| 158 | console_printbuf[console_printbuf_len++] = c; | ||
| 159 | return 0; | ||
| 160 | } | ||
| 161 | |||
| 162 | void main_subtask_console_flush(void) { | ||
| 163 | while (udi_hid_con_b_report_trans_ongoing) { | ||
| 164 | } // Wait for any previous transfers to complete | ||
| 165 | |||
| 166 | uint16_t result = console_printbuf_len; | ||
| 167 | uint32_t irqflags; | ||
| 168 | char * pconbuf = console_printbuf; // Pointer to start send from | ||
| 169 | int send_out = CONSOLE_EPSIZE; // Bytes to send per transfer | ||
| 170 | |||
| 171 | while (result > 0) { // While not error and bytes remain | ||
| 172 | while (udi_hid_con_b_report_trans_ongoing) { | ||
| 173 | } // Wait for any previous transfers to complete | ||
| 174 | |||
| 175 | irqflags = __get_PRIMASK(); | ||
| 176 | __disable_irq(); | ||
| 177 | __DMB(); | ||
| 178 | |||
| 179 | if (result < CONSOLE_EPSIZE) { // If remaining bytes are less than console epsize | ||
| 180 | memset(udi_hid_con_report, 0, CONSOLE_EPSIZE); // Clear the buffer | ||
| 181 | send_out = result; // Send remaining size | ||
| 182 | } | ||
| 183 | |||
| 184 | memcpy(udi_hid_con_report, pconbuf, send_out); // Copy data into the send buffer | ||
| 185 | |||
| 186 | udi_hid_con_b_report_valid = 1; // Set report valid | ||
| 187 | udi_hid_con_send_report(); // Send report | ||
| 188 | |||
| 189 | __DMB(); | ||
| 190 | __set_PRIMASK(irqflags); | ||
| 191 | |||
| 192 | result -= send_out; // Decrement result by bytes sent | ||
| 193 | pconbuf += send_out; // Increment buffer point by bytes sent | ||
| 194 | } | ||
| 195 | |||
| 196 | console_printbuf_len = 0; | ||
| 197 | } | ||
| 198 | |||
| 199 | #endif // CONSOLE_ENABLE | ||
| 200 | |||
| 201 | void main_subtask_usb_state(void) { | ||
| 202 | static uint64_t fsmstate_on_delay = 0; // Delay timer to be sure USB is actually operating before bringing up hardware | ||
| 203 | uint8_t fsmstate_now = USB->DEVICE.FSMSTATUS.reg; // Current state from hardware register | ||
| 204 | |||
| 205 | if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SUSPEND_Val) // If USB SUSPENDED | ||
| 206 | { | ||
| 207 | fsmstate_on_delay = 0; // Clear ON delay timer | ||
| 208 | |||
| 209 | if (g_usb_state != USB_FSMSTATUS_FSMSTATE_SUSPEND_Val) // If previously not SUSPENDED | ||
| 210 | { | ||
| 211 | suspend_power_down(); // Run suspend routine | ||
| 212 | g_usb_state = fsmstate_now; // Save current USB state | ||
| 213 | } | ||
| 214 | } else if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SLEEP_Val) // Else if USB SLEEPING | ||
| 215 | { | ||
| 216 | fsmstate_on_delay = 0; // Clear ON delay timer | ||
| 217 | |||
| 218 | if (g_usb_state != USB_FSMSTATUS_FSMSTATE_SLEEP_Val) // If previously not SLEEPING | ||
| 219 | { | ||
| 220 | suspend_power_down(); // Run suspend routine | ||
| 221 | g_usb_state = fsmstate_now; // Save current USB state | ||
| 222 | } | ||
| 223 | } else if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_ON_Val) // Else if USB ON | ||
| 224 | { | ||
| 225 | if (g_usb_state != USB_FSMSTATUS_FSMSTATE_ON_Val) // If previously not ON | ||
| 226 | { | ||
| 227 | if (fsmstate_on_delay == 0) // If ON delay timer is cleared | ||
| 228 | { | ||
| 229 | fsmstate_on_delay = timer_read64() + 250; // Set ON delay timer | ||
| 230 | } else if (timer_read64() > fsmstate_on_delay) // Else if ON delay timer is active and timed out | ||
| 231 | { | ||
| 232 | suspend_wakeup_init(); // Run wakeup routine | ||
| 233 | g_usb_state = fsmstate_now; // Save current USB state | ||
| 234 | } | ||
| 235 | } | ||
| 236 | } else // Else if USB is in a state not being tracked | ||
| 237 | { | ||
| 238 | fsmstate_on_delay = 0; // Clear ON delay timer | ||
| 239 | } | ||
| 240 | } | ||
| 241 | |||
| 242 | void main_subtask_power_check(void) { | ||
| 243 | static uint64_t next_5v_checkup = 0; | ||
| 244 | |||
| 245 | if (timer_read64() > next_5v_checkup) { | ||
| 246 | next_5v_checkup = timer_read64() + 5; | ||
| 247 | |||
| 248 | v_5v = adc_get(ADC_5V); | ||
| 249 | v_5v_avg = 0.9 * v_5v_avg + 0.1 * v_5v; | ||
| 250 | |||
| 251 | #ifdef RGB_MATRIX_ENABLE | ||
| 252 | gcr_compute(); | ||
| 253 | #endif | ||
| 254 | } | ||
| 255 | } | ||
| 256 | |||
| 257 | void main_subtask_usb_extra_device(void) { | ||
| 258 | static uint64_t next_usb_checkup = 0; | ||
| 259 | |||
| 260 | if (timer_read64() > next_usb_checkup) { | ||
| 261 | next_usb_checkup = timer_read64() + 10; | ||
| 262 | |||
| 263 | USB_HandleExtraDevice(); | ||
| 264 | } | ||
| 265 | } | ||
| 266 | |||
| 267 | #ifdef RAW_ENABLE | ||
| 268 | void main_subtask_raw(void) { | ||
| 269 | udi_hid_raw_receive_report(); | ||
| 270 | } | ||
| 271 | #endif | ||
| 272 | |||
| 273 | void main_subtasks(void) { | ||
| 274 | main_subtask_usb_state(); | ||
| 275 | main_subtask_power_check(); | ||
| 276 | main_subtask_usb_extra_device(); | ||
| 277 | #ifdef CONSOLE_ENABLE | ||
| 278 | main_subtask_console_flush(); | ||
| 279 | #endif | ||
| 280 | #ifdef RAW_ENABLE | ||
| 281 | main_subtask_raw(); | ||
| 282 | #endif | ||
| 283 | } | ||
| 284 | |||
| 285 | int main(void) { | ||
| 286 | DBG_LED_ENA; | ||
| 287 | DBG_1_ENA; | ||
| 288 | DBG_1_OFF; | ||
| 289 | DBG_2_ENA; | ||
| 290 | DBG_2_OFF; | ||
| 291 | DBG_3_ENA; | ||
| 292 | DBG_3_OFF; | ||
| 293 | |||
| 294 | debug_code_init(); | ||
| 295 | |||
| 296 | CLK_init(); | ||
| 297 | |||
| 298 | ADC0_init(); | ||
| 299 | |||
| 300 | SR_EXP_Init(); | ||
| 301 | |||
| 302 | #ifdef RGB_MATRIX_ENABLE | ||
| 303 | i2c1_init(); | ||
| 304 | #endif // RGB_MATRIX_ENABLE | ||
| 305 | |||
| 306 | USB_Hub_init(); | ||
| 307 | |||
| 308 | DBGC(DC_MAIN_UDC_START_BEGIN); | ||
| 309 | udc_start(); | ||
| 310 | DBGC(DC_MAIN_UDC_START_COMPLETE); | ||
| 311 | |||
| 312 | DBGC(DC_MAIN_CDC_INIT_BEGIN); | ||
| 313 | CDC_init(); | ||
| 314 | DBGC(DC_MAIN_CDC_INIT_COMPLETE); | ||
| 315 | |||
| 316 | while (USB_Hub_Port_Detect_Init() == 0) { | ||
| 317 | } | ||
| 318 | |||
| 319 | DBG_LED_OFF; | ||
| 320 | |||
| 321 | #ifdef RGB_MATRIX_ENABLE | ||
| 322 | while (I2C3733_Init_Control() != 1) { | ||
| 323 | } | ||
| 324 | while (I2C3733_Init_Drivers() != 1) { | ||
| 325 | } | ||
| 326 | |||
| 327 | I2C_DMAC_LED_Init(); | ||
| 328 | |||
| 329 | i2c_led_q_init(); | ||
| 330 | |||
| 331 | for (uint8_t drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++) | ||
| 332 | I2C_LED_Q_ONOFF(drvid); // Queue data | ||
| 333 | #endif // RGB_MATRIX_ENABLE | ||
| 334 | |||
| 335 | keyboard_setup(); | ||
| 336 | |||
| 337 | keyboard_init(); | ||
| 338 | |||
| 339 | host_set_driver(&arm_atsam_driver); | ||
| 340 | |||
| 341 | #ifdef CONSOLE_ENABLE | ||
| 342 | uint64_t next_print = 0; | ||
| 343 | #endif // CONSOLE_ENABLE | ||
| 344 | |||
| 345 | v_5v_avg = adc_get(ADC_5V); | ||
| 346 | |||
| 347 | debug_code_disable(); | ||
| 348 | |||
| 349 | while (1) { | ||
| 350 | main_subtasks(); // Note these tasks will also be run while waiting for USB keyboard polling intervals | ||
| 351 | |||
| 352 | if (g_usb_state == USB_FSMSTATUS_FSMSTATE_SUSPEND_Val || g_usb_state == USB_FSMSTATUS_FSMSTATE_SLEEP_Val) { | ||
| 353 | if (suspend_wakeup_condition()) { | ||
| 354 | udc_remotewakeup(); // Send remote wakeup signal | ||
| 355 | wait_ms(50); | ||
| 356 | } | ||
| 357 | |||
| 358 | continue; | ||
| 359 | } | ||
| 360 | |||
| 361 | keyboard_task(); | ||
| 362 | |||
| 363 | #ifdef CONSOLE_ENABLE | ||
| 364 | if (timer_read64() > next_print) { | ||
| 365 | next_print = timer_read64() + 250; | ||
| 366 | // Add any debug information here that you want to see very often | ||
| 367 | // 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); | ||
| 368 | } | ||
| 369 | #endif // CONSOLE_ENABLE | ||
| 370 | |||
| 371 | #ifdef DEFERRED_EXEC_ENABLE | ||
| 372 | // Run deferred executions | ||
| 373 | deferred_exec_task(); | ||
| 374 | #endif // DEFERRED_EXEC_ENABLE | ||
| 375 | |||
| 376 | // Run housekeeping | ||
| 377 | housekeeping_task(); | ||
| 378 | } | ||
| 379 | |||
| 380 | return 1; | ||
| 381 | } | ||
diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.h b/tmk_core/protocol/arm_atsam/main_arm_atsam.h deleted file mode 100644 index 78205e2e1b..0000000000 --- a/tmk_core/protocol/arm_atsam/main_arm_atsam.h +++ /dev/null | |||
| @@ -1,23 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef _MAIN_ARM_ATSAM_H_ | ||
| 19 | #define _MAIN_ARM_ATSAM_H_ | ||
| 20 | |||
| 21 | uint8_t keyboard_leds(void); | ||
| 22 | |||
| 23 | #endif //_MAIN_ARM_ATSAM_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/md_rgb_matrix.c b/tmk_core/protocol/arm_atsam/md_rgb_matrix.c deleted file mode 100644 index 0f316b256c..0000000000 --- a/tmk_core/protocol/arm_atsam/md_rgb_matrix.c +++ /dev/null | |||
| @@ -1,556 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #define FLUSH_TIMEOUT 5000 | ||
| 19 | #define EECONFIG_MD_LED ((uint8_t*)(EECONFIG_SIZE + 64)) | ||
| 20 | #define MD_LED_CONFIG_VERSION 1 | ||
| 21 | |||
| 22 | #ifdef RGB_MATRIX_ENABLE | ||
| 23 | # include "arm_atsam_protocol.h" | ||
| 24 | # include "led.h" | ||
| 25 | # include "rgb_matrix.h" | ||
| 26 | # include "eeprom.h" | ||
| 27 | # include "host.h" | ||
| 28 | # include <string.h> | ||
| 29 | # include <math.h> | ||
| 30 | |||
| 31 | # ifdef USE_MASSDROP_CONFIGURATOR | ||
| 32 | // TODO?: wire these up to keymap.c | ||
| 33 | md_led_config_t md_led_config = {0}; | ||
| 34 | |||
| 35 | EECONFIG_DEBOUNCE_HELPER(md_led, EECONFIG_MD_LED, md_led_config); | ||
| 36 | |||
| 37 | void eeconfig_update_md_led_default(void) { | ||
| 38 | md_led_config.ver = MD_LED_CONFIG_VERSION; | ||
| 39 | |||
| 40 | gcr_desired = LED_GCR_MAX; | ||
| 41 | led_animation_orientation = 0; | ||
| 42 | led_animation_direction = 0; | ||
| 43 | led_animation_breathing = 0; | ||
| 44 | led_animation_id = 0; | ||
| 45 | led_animation_speed = 4.0f; | ||
| 46 | led_lighting_mode = LED_MODE_NORMAL; | ||
| 47 | led_enabled = 1; | ||
| 48 | led_animation_breathe_cur = BREATHE_MIN_STEP; | ||
| 49 | breathe_dir = 1; | ||
| 50 | led_animation_circular = 0; | ||
| 51 | led_edge_brightness = 1.0f; | ||
| 52 | led_ratio_brightness = 1.0f; | ||
| 53 | led_edge_mode = LED_EDGE_MODE_ALL; | ||
| 54 | |||
| 55 | eeconfig_flush_md_led(true); | ||
| 56 | } | ||
| 57 | |||
| 58 | void md_led_changed(void) { | ||
| 59 | eeconfig_flag_md_led(true); | ||
| 60 | } | ||
| 61 | |||
| 62 | // todo: use real task rather than this bodge | ||
| 63 | void housekeeping_task_kb(void) { | ||
| 64 | eeconfig_flush_md_led_task(FLUSH_TIMEOUT); | ||
| 65 | } | ||
| 66 | |||
| 67 | __attribute__((weak)) led_instruction_t led_instructions[] = {{.end = 1}}; | ||
| 68 | static void md_rgb_matrix_config_override(int i); | ||
| 69 | # else | ||
| 70 | uint8_t gcr_desired; | ||
| 71 | # endif // USE_MASSDROP_CONFIGURATOR | ||
| 72 | |||
| 73 | void SERCOM1_0_Handler(void) { | ||
| 74 | if (SERCOM1->I2CM.INTFLAG.bit.ERROR) { | ||
| 75 | SERCOM1->I2CM.INTFLAG.reg = SERCOM_I2CM_INTENCLR_ERROR; | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | void DMAC_0_Handler(void) { | ||
| 80 | if (DMAC->Channel[0].CHINTFLAG.bit.TCMPL) { | ||
| 81 | DMAC->Channel[0].CHINTFLAG.reg = DMAC_CHINTENCLR_TCMPL; | ||
| 82 | |||
| 83 | i2c1_stop(); | ||
| 84 | |||
| 85 | i2c_led_q_running = 0; | ||
| 86 | |||
| 87 | i2c_led_q_run(); | ||
| 88 | |||
| 89 | return; | ||
| 90 | } | ||
| 91 | |||
| 92 | if (DMAC->Channel[0].CHINTFLAG.bit.TERR) { | ||
| 93 | DMAC->Channel[0].CHINTFLAG.reg = DMAC_CHINTENCLR_TERR; | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT]; | ||
| 98 | |||
| 99 | issi3733_led_t led_map[ISSI3733_LED_COUNT] = ISSI3733_LED_MAP; | ||
| 100 | RGB led_buffer[ISSI3733_LED_COUNT]; | ||
| 101 | |||
| 102 | uint8_t gcr_actual; | ||
| 103 | uint8_t gcr_actual_last; | ||
| 104 | # ifdef USE_MASSDROP_CONFIGURATOR | ||
| 105 | uint8_t gcr_breathe; | ||
| 106 | float breathe_mult; | ||
| 107 | float pomod; | ||
| 108 | # endif | ||
| 109 | |||
| 110 | # define ACT_GCR_NONE 0 | ||
| 111 | # define ACT_GCR_INC 1 | ||
| 112 | # define ACT_GCR_DEC 2 | ||
| 113 | |||
| 114 | # define LED_GCR_STEP_AUTO 2 | ||
| 115 | |||
| 116 | static uint8_t gcr_min_counter; | ||
| 117 | static uint8_t v_5v_cat_hit; | ||
| 118 | |||
| 119 | // WARNING: Automatic GCR is in place to prevent USB shutdown and LED driver overloading | ||
| 120 | void gcr_compute(void) { | ||
| 121 | uint8_t action = ACT_GCR_NONE; | ||
| 122 | uint8_t gcr_use = gcr_desired; | ||
| 123 | |||
| 124 | # ifdef USE_MASSDROP_CONFIGURATOR | ||
| 125 | if (led_animation_breathing) { | ||
| 126 | gcr_use = gcr_breathe; | ||
| 127 | } | ||
| 128 | # endif | ||
| 129 | |||
| 130 | // If the 5v takes a catastrophic hit, disable the LED drivers briefly, assert auto gcr mode, min gcr and let the auto take over | ||
| 131 | if (v_5v < V5_CAT) { | ||
| 132 | I2C3733_Control_Set(0); | ||
| 133 | // CDC_print("USB: WARNING: 5V catastrophic level reached! Disabling LED drivers!\r\n"); //Blocking print is bad here! | ||
| 134 | v_5v_cat_hit = 20; //~100ms recover | ||
| 135 | gcr_actual = 0; // Minimize GCR | ||
| 136 | usb_gcr_auto = 1; // Force auto mode enabled | ||
| 137 | return; | ||
| 138 | } else if (v_5v_cat_hit > 1) { | ||
| 139 | v_5v_cat_hit--; | ||
| 140 | return; | ||
| 141 | } else if (v_5v_cat_hit == 1) { | ||
| 142 | I2C3733_Control_Set(1); | ||
| 143 | CDC_print("USB: WARNING: Re-enabling LED drivers\r\n"); | ||
| 144 | v_5v_cat_hit = 0; | ||
| 145 | return; | ||
| 146 | } | ||
| 147 | |||
| 148 | if (usb_gcr_auto) { | ||
| 149 | if (v_5v_avg < V5_LOW) | ||
| 150 | action = ACT_GCR_DEC; | ||
| 151 | else if (v_5v_avg > V5_HIGH && gcr_actual < gcr_use) | ||
| 152 | action = ACT_GCR_INC; | ||
| 153 | else if (gcr_actual > gcr_use) | ||
| 154 | action = ACT_GCR_DEC; | ||
| 155 | } else { | ||
| 156 | if (gcr_actual < gcr_use) | ||
| 157 | action = ACT_GCR_INC; | ||
| 158 | else if (gcr_actual > gcr_use) | ||
| 159 | action = ACT_GCR_DEC; | ||
| 160 | } | ||
| 161 | |||
| 162 | if (action == ACT_GCR_NONE) { | ||
| 163 | gcr_min_counter = 0; | ||
| 164 | } else if (action == ACT_GCR_INC) { | ||
| 165 | if (LED_GCR_STEP_AUTO > LED_GCR_MAX - gcr_actual) | ||
| 166 | gcr_actual = LED_GCR_MAX; // Obey max and prevent wrapping | ||
| 167 | else | ||
| 168 | gcr_actual += LED_GCR_STEP_AUTO; | ||
| 169 | gcr_min_counter = 0; | ||
| 170 | } else if (action == ACT_GCR_DEC) { | ||
| 171 | if (LED_GCR_STEP_AUTO > gcr_actual) // Prevent wrapping | ||
| 172 | { | ||
| 173 | gcr_actual = 0; | ||
| 174 | // At this point, power can no longer be cut from the LED drivers, so focus on cutting out extra port if active | ||
| 175 | if (usb_extra_state != USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG) // If not in a wait for replug state | ||
| 176 | { | ||
| 177 | if (usb_extra_state == USB_EXTRA_STATE_ENABLED) // If extra usb is enabled | ||
| 178 | { | ||
| 179 | gcr_min_counter++; | ||
| 180 | if (gcr_min_counter > 200) // 5ms per check = 1s delay | ||
| 181 | { | ||
| 182 | USB_ExtraSetState(USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG); | ||
| 183 | usb_extra_manual = 0; // Force disable manual mode of extra port | ||
| 184 | if (usb_extra_manual) | ||
| 185 | CDC_print("USB: Disabling extra port until replug and manual mode toggle!\r\n"); | ||
| 186 | else | ||
| 187 | CDC_print("USB: Disabling extra port until replug!\r\n"); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | } | ||
| 191 | } else { | ||
| 192 | // Power successfully cut back from LED drivers | ||
| 193 | gcr_actual -= LED_GCR_STEP_AUTO; | ||
| 194 | gcr_min_counter = 0; | ||
| 195 | |||
| 196 | # ifdef USE_MASSDROP_CONFIGURATOR | ||
| 197 | // If breathe mode is active, the top end can fluctuate if the host can not supply enough current | ||
| 198 | // So set the breathe GCR to where it becomes stable | ||
| 199 | if (led_animation_breathing == 1) { | ||
| 200 | gcr_breathe = gcr_actual; | ||
| 201 | // PS: At this point, setting breathing to exhale makes a noticebly shorter cycle | ||
| 202 | // and the same would happen maybe one or two more times. Therefore I'm favoring | ||
| 203 | // powering through one full breathe and letting gcr settle completely | ||
| 204 | } | ||
| 205 | # endif | ||
| 206 | } | ||
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 210 | void issi3733_prepare_arrays(void) { | ||
| 211 | static bool s_init = false; | ||
| 212 | if (s_init) { | ||
| 213 | return; | ||
| 214 | } | ||
| 215 | s_init = true; | ||
| 216 | |||
| 217 | memset(issidrv, 0, sizeof(issi3733_driver_t) * ISSI3733_DRIVER_COUNT); | ||
| 218 | |||
| 219 | int i; | ||
| 220 | uint8_t addrs[ISSI3733_DRIVER_COUNT] = ISSI3773_DRIVER_ADDRESSES; | ||
| 221 | |||
| 222 | for (i = 0; i < ISSI3733_DRIVER_COUNT; i++) { | ||
| 223 | issidrv[i].addr = addrs[i]; | ||
| 224 | } | ||
| 225 | |||
| 226 | for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) { | ||
| 227 | // BYTE: 1 + (SW-1)*16 + (CS-1) | ||
| 228 | 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)); | ||
| 229 | 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)); | ||
| 230 | 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)); | ||
| 231 | |||
| 232 | // BYTE: 1 + (SW-1)*2 + (CS-1)/8 | ||
| 233 | // BIT: (CS-1)%8 | ||
| 234 | *(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)); | ||
| 235 | *(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)); | ||
| 236 | *(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)); | ||
| 237 | } | ||
| 238 | } | ||
| 239 | |||
| 240 | void md_rgb_matrix_prepare(void) { | ||
| 241 | for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) { | ||
| 242 | *led_map[i].rgb.r = 0; | ||
| 243 | *led_map[i].rgb.g = 0; | ||
| 244 | *led_map[i].rgb.b = 0; | ||
| 245 | } | ||
| 246 | } | ||
| 247 | |||
| 248 | static void led_set_one(int i, uint8_t r, uint8_t g, uint8_t b) { | ||
| 249 | if (i < ISSI3733_LED_COUNT) { | ||
| 250 | # ifdef USE_MASSDROP_CONFIGURATOR | ||
| 251 | md_rgb_matrix_config_override(i); | ||
| 252 | # else | ||
| 253 | led_buffer[i].r = r; | ||
| 254 | led_buffer[i].g = g; | ||
| 255 | led_buffer[i].b = b; | ||
| 256 | # endif | ||
| 257 | } | ||
| 258 | } | ||
| 259 | |||
| 260 | static void led_set_all(uint8_t r, uint8_t g, uint8_t b) { | ||
| 261 | for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) { | ||
| 262 | led_set_one(i, r, g, b); | ||
| 263 | } | ||
| 264 | } | ||
| 265 | |||
| 266 | static void init(void) { | ||
| 267 | DBGC(DC_LED_MATRIX_INIT_BEGIN); | ||
| 268 | |||
| 269 | # ifdef USE_MASSDROP_CONFIGURATOR | ||
| 270 | eeconfig_init_md_led(); | ||
| 271 | if (md_led_config.ver != MD_LED_CONFIG_VERSION) { | ||
| 272 | eeconfig_update_md_led_default(); | ||
| 273 | } | ||
| 274 | # endif | ||
| 275 | |||
| 276 | issi3733_prepare_arrays(); | ||
| 277 | |||
| 278 | md_rgb_matrix_prepare(); | ||
| 279 | |||
| 280 | gcr_min_counter = 0; | ||
| 281 | v_5v_cat_hit = 0; | ||
| 282 | |||
| 283 | DBGC(DC_LED_MATRIX_INIT_COMPLETE); | ||
| 284 | } | ||
| 285 | |||
| 286 | static void flush(void) { | ||
| 287 | # ifdef USE_MASSDROP_CONFIGURATOR | ||
| 288 | if (!led_enabled) { | ||
| 289 | return; | ||
| 290 | } // Prevent calculations and I2C traffic if LED drivers are not enabled | ||
| 291 | # else | ||
| 292 | if (!sr_exp_data.bit.SDB_N) { | ||
| 293 | return; | ||
| 294 | } // Prevent calculations and I2C traffic if LED drivers are not enabled | ||
| 295 | # endif | ||
| 296 | |||
| 297 | // Wait for previous transfer to complete | ||
| 298 | while (i2c_led_q_running) { | ||
| 299 | } | ||
| 300 | |||
| 301 | // Copy buffer to live DMA region | ||
| 302 | for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) { | ||
| 303 | *led_map[i].rgb.r = led_buffer[i].r; | ||
| 304 | *led_map[i].rgb.g = led_buffer[i].g; | ||
| 305 | *led_map[i].rgb.b = led_buffer[i].b; | ||
| 306 | } | ||
| 307 | |||
| 308 | # ifdef USE_MASSDROP_CONFIGURATOR | ||
| 309 | breathe_mult = 1; | ||
| 310 | |||
| 311 | if (led_animation_breathing) { | ||
| 312 | //+60us 119 LED | ||
| 313 | led_animation_breathe_cur += BREATHE_STEP * breathe_dir; | ||
| 314 | |||
| 315 | if (led_animation_breathe_cur >= BREATHE_MAX_STEP) | ||
| 316 | breathe_dir = -1; | ||
| 317 | else if (led_animation_breathe_cur <= BREATHE_MIN_STEP) | ||
| 318 | breathe_dir = 1; | ||
| 319 | |||
| 320 | // Brightness curve created for 256 steps, 0 - ~98% | ||
| 321 | breathe_mult = 0.000015 * led_animation_breathe_cur * led_animation_breathe_cur; | ||
| 322 | if (breathe_mult > 1) | ||
| 323 | breathe_mult = 1; | ||
| 324 | else if (breathe_mult < 0) | ||
| 325 | breathe_mult = 0; | ||
| 326 | } | ||
| 327 | |||
| 328 | // This should only be performed once per frame | ||
| 329 | pomod = (float)((g_rgb_timer / 10) % (uint32_t)(1000.0f / led_animation_speed)) / 10.0f * led_animation_speed; | ||
| 330 | pomod *= 100.0f; | ||
| 331 | pomod = (uint32_t)pomod % 10000; | ||
| 332 | pomod /= 100.0f; | ||
| 333 | |||
| 334 | # endif // USE_MASSDROP_CONFIGURATOR | ||
| 335 | |||
| 336 | uint8_t drvid; | ||
| 337 | |||
| 338 | // NOTE: GCR does not need to be timed with LED processing, but there is really no harm | ||
| 339 | if (gcr_actual != gcr_actual_last) { | ||
| 340 | for (drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++) | ||
| 341 | I2C_LED_Q_GCR(drvid); // Queue data | ||
| 342 | gcr_actual_last = gcr_actual; | ||
| 343 | } | ||
| 344 | |||
| 345 | for (drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++) | ||
| 346 | I2C_LED_Q_PWM(drvid); // Queue data | ||
| 347 | |||
| 348 | i2c_led_q_run(); | ||
| 349 | } | ||
| 350 | |||
| 351 | void md_rgb_matrix_indicators_advanced(uint8_t led_min, uint8_t led_max) { | ||
| 352 | led_t led_state = host_keyboard_led_state(); | ||
| 353 | if (led_state.raw && rgb_matrix_config.enable) { | ||
| 354 | for (uint8_t i = led_min; i < led_max; i++) { | ||
| 355 | if ( | ||
| 356 | # if USB_LED_NUM_LOCK_SCANCODE != 255 | ||
| 357 | (led_map[i].scan == USB_LED_NUM_LOCK_SCANCODE && led_state.num_lock) || | ||
| 358 | # endif // NUM LOCK | ||
| 359 | # if USB_LED_CAPS_LOCK_SCANCODE != 255 | ||
| 360 | (led_map[i].scan == USB_LED_CAPS_LOCK_SCANCODE && led_state.caps_lock) || | ||
| 361 | # endif // CAPS LOCK | ||
| 362 | # if USB_LED_SCROLL_LOCK_SCANCODE != 255 | ||
| 363 | (led_map[i].scan == USB_LED_SCROLL_LOCK_SCANCODE && led_state.scroll_lock) || | ||
| 364 | # endif // SCROLL LOCK | ||
| 365 | # if USB_LED_COMPOSE_SCANCODE != 255 | ||
| 366 | (led_map[i].scan == USB_LED_COMPOSE_SCANCODE && led_state.compose) || | ||
| 367 | # endif // COMPOSE | ||
| 368 | # if USB_LED_KANA_SCANCODE != 255 | ||
| 369 | (led_map[i].scan == USB_LED_KANA_SCANCODE && led_state.kana) || | ||
| 370 | # endif // KANA | ||
| 371 | (0)) { | ||
| 372 | if (rgb_matrix_get_flags() & LED_FLAG_INDICATOR) { | ||
| 373 | led_buffer[i].r = 255 - led_buffer[i].r; | ||
| 374 | led_buffer[i].g = 255 - led_buffer[i].g; | ||
| 375 | led_buffer[i].b = 255 - led_buffer[i].b; | ||
| 376 | } | ||
| 377 | } | ||
| 378 | } | ||
| 379 | } | ||
| 380 | } | ||
| 381 | |||
| 382 | const rgb_matrix_driver_t rgb_matrix_driver = {.init = init, .flush = flush, .set_color = led_set_one, .set_color_all = led_set_all}; | ||
| 383 | |||
| 384 | /*============================================================================== | ||
| 385 | = Legacy Lighting Support = | ||
| 386 | ==============================================================================*/ | ||
| 387 | |||
| 388 | # ifdef USE_MASSDROP_CONFIGURATOR | ||
| 389 | // Ported from Massdrop QMK GitHub Repo | ||
| 390 | |||
| 391 | static void led_run_pattern(led_setup_t* f, float* ro, float* go, float* bo, float pos) { | ||
| 392 | float po; | ||
| 393 | |||
| 394 | while (f->end != 1) { | ||
| 395 | po = pos; // Reset po for new frame | ||
| 396 | |||
| 397 | // Add in any moving effects | ||
| 398 | if ((!led_animation_direction && f->ef & EF_SCR_R) || (led_animation_direction && (f->ef & EF_SCR_L))) { | ||
| 399 | po -= pomod; | ||
| 400 | |||
| 401 | if (po > 100) | ||
| 402 | po -= 100; | ||
| 403 | else if (po < 0) | ||
| 404 | po += 100; | ||
| 405 | } else if ((!led_animation_direction && f->ef & EF_SCR_L) || (led_animation_direction && (f->ef & EF_SCR_R))) { | ||
| 406 | po += pomod; | ||
| 407 | |||
| 408 | if (po > 100) | ||
| 409 | po -= 100; | ||
| 410 | else if (po < 0) | ||
| 411 | po += 100; | ||
| 412 | } | ||
| 413 | |||
| 414 | // Check if LED's po is in current frame | ||
| 415 | if (po < f->hs) { | ||
| 416 | f++; | ||
| 417 | continue; | ||
| 418 | } | ||
| 419 | if (po > f->he) { | ||
| 420 | f++; | ||
| 421 | continue; | ||
| 422 | } | ||
| 423 | // note: < 0 or > 100 continue | ||
| 424 | |||
| 425 | // Calculate the po within the start-stop percentage for color blending | ||
| 426 | po = (po - f->hs) / (f->he - f->hs); | ||
| 427 | |||
| 428 | // Add in any color effects | ||
| 429 | if (f->ef & EF_OVER) { | ||
| 430 | *ro = (po * (f->re - f->rs)) + f->rs; // + 0.5; | ||
| 431 | *go = (po * (f->ge - f->gs)) + f->gs; // + 0.5; | ||
| 432 | *bo = (po * (f->be - f->bs)) + f->bs; // + 0.5; | ||
| 433 | } else if (f->ef & EF_SUBTRACT) { | ||
| 434 | *ro -= (po * (f->re - f->rs)) + f->rs; // + 0.5; | ||
| 435 | *go -= (po * (f->ge - f->gs)) + f->gs; // + 0.5; | ||
| 436 | *bo -= (po * (f->be - f->bs)) + f->bs; // + 0.5; | ||
| 437 | } else { | ||
| 438 | *ro += (po * (f->re - f->rs)) + f->rs; // + 0.5; | ||
| 439 | *go += (po * (f->ge - f->gs)) + f->gs; // + 0.5; | ||
| 440 | *bo += (po * (f->be - f->bs)) + f->bs; // + 0.5; | ||
| 441 | } | ||
| 442 | |||
| 443 | f++; | ||
| 444 | } | ||
| 445 | } | ||
| 446 | |||
| 447 | # define RGB_MAX_DISTANCE 232.9635f | ||
| 448 | |||
| 449 | static void md_rgb_matrix_config_override(int i) { | ||
| 450 | float ro = 0; | ||
| 451 | float go = 0; | ||
| 452 | float bo = 0; | ||
| 453 | float po; | ||
| 454 | |||
| 455 | uint8_t highest_active_layer = get_highest_layer(layer_state); | ||
| 456 | |||
| 457 | if (led_animation_circular) { | ||
| 458 | // TODO: should use min/max values from LED configuration instead of | ||
| 459 | // hard-coded 224, 64 | ||
| 460 | // 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; | ||
| 461 | 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; | ||
| 462 | } else { | ||
| 463 | if (led_animation_orientation) { | ||
| 464 | po = (float)g_led_config.point[i].y / 64.f * 100; | ||
| 465 | } else { | ||
| 466 | po = (float)g_led_config.point[i].x / 224.f * 100; | ||
| 467 | } | ||
| 468 | } | ||
| 469 | |||
| 470 | if (led_edge_mode == LED_EDGE_MODE_ALTERNATE && LED_IS_EDGE_ALT(led_map[i].scan)) { | ||
| 471 | // Do not act on this LED (Edge alternate lighting mode) | ||
| 472 | } else if (led_lighting_mode == LED_MODE_KEYS_ONLY && HAS_FLAGS(g_led_config.flags[i], LED_FLAG_UNDERGLOW)) { | ||
| 473 | // Do not act on this LED | ||
| 474 | } else if (led_lighting_mode == LED_MODE_NON_KEYS_ONLY && !HAS_FLAGS(g_led_config.flags[i], LED_FLAG_UNDERGLOW)) { | ||
| 475 | // Do not act on this LED | ||
| 476 | } else if (led_lighting_mode == LED_MODE_INDICATORS_ONLY) { | ||
| 477 | // Do not act on this LED (Only show indicators) | ||
| 478 | } else { | ||
| 479 | led_instruction_t* led_cur_instruction = led_instructions; | ||
| 480 | while (!led_cur_instruction->end) { | ||
| 481 | // Check if this applies to current layer | ||
| 482 | if ((led_cur_instruction->flags & LED_FLAG_MATCH_LAYER) && (led_cur_instruction->layer != highest_active_layer)) { | ||
| 483 | goto next_iter; | ||
| 484 | } | ||
| 485 | |||
| 486 | // Check if this applies to current index | ||
| 487 | if (led_cur_instruction->flags & LED_FLAG_MATCH_ID) { | ||
| 488 | uint8_t modid = i / 32; // Calculate which id# contains the led bit | ||
| 489 | uint32_t modidbit = 1 << (i % 32); // Calculate the bit within the id# | ||
| 490 | uint32_t* bitfield = &led_cur_instruction->id0 + modid; // Add modid as offset to id0 address. *bitfield is now idX of the led id | ||
| 491 | if (~(*bitfield) & modidbit) { // Check if led bit is not set in idX | ||
| 492 | goto next_iter; | ||
| 493 | } | ||
| 494 | } | ||
| 495 | |||
| 496 | if (led_cur_instruction->flags & LED_FLAG_USE_RGB) { | ||
| 497 | ro = led_cur_instruction->r; | ||
| 498 | go = led_cur_instruction->g; | ||
| 499 | bo = led_cur_instruction->b; | ||
| 500 | } else if (led_cur_instruction->flags & LED_FLAG_USE_PATTERN) { | ||
| 501 | led_run_pattern(led_setups[led_cur_instruction->pattern_id], &ro, &go, &bo, po); | ||
| 502 | } else if (led_cur_instruction->flags & LED_FLAG_USE_ROTATE_PATTERN) { | ||
| 503 | led_run_pattern(led_setups[led_animation_id], &ro, &go, &bo, po); | ||
| 504 | } | ||
| 505 | |||
| 506 | next_iter: | ||
| 507 | led_cur_instruction++; | ||
| 508 | } | ||
| 509 | |||
| 510 | if (ro > 255) | ||
| 511 | ro = 255; | ||
| 512 | else if (ro < 0) | ||
| 513 | ro = 0; | ||
| 514 | if (go > 255) | ||
| 515 | go = 255; | ||
| 516 | else if (go < 0) | ||
| 517 | go = 0; | ||
| 518 | if (bo > 255) | ||
| 519 | bo = 255; | ||
| 520 | else if (bo < 0) | ||
| 521 | bo = 0; | ||
| 522 | |||
| 523 | if (led_animation_breathing) { | ||
| 524 | ro *= breathe_mult; | ||
| 525 | go *= breathe_mult; | ||
| 526 | bo *= breathe_mult; | ||
| 527 | } | ||
| 528 | } | ||
| 529 | |||
| 530 | // Adjust edge LED brightness | ||
| 531 | if (led_edge_brightness != 1 && LED_IS_EDGE(led_map[i].scan)) { | ||
| 532 | ro *= led_edge_brightness; | ||
| 533 | go *= led_edge_brightness; | ||
| 534 | bo *= led_edge_brightness; | ||
| 535 | } | ||
| 536 | |||
| 537 | // Adjust ratio of key vs. underglow (edge) LED brightness | ||
| 538 | if (LED_IS_EDGE(led_map[i].scan) && led_ratio_brightness > 1.0) { | ||
| 539 | // Decrease edge (underglow) LEDs | ||
| 540 | ro *= (2.0 - led_ratio_brightness); | ||
| 541 | go *= (2.0 - led_ratio_brightness); | ||
| 542 | bo *= (2.0 - led_ratio_brightness); | ||
| 543 | } else if (LED_IS_KEY(led_map[i].scan) && led_ratio_brightness < 1.0) { | ||
| 544 | // Decrease KEY LEDs | ||
| 545 | ro *= led_ratio_brightness; | ||
| 546 | go *= led_ratio_brightness; | ||
| 547 | bo *= led_ratio_brightness; | ||
| 548 | } | ||
| 549 | |||
| 550 | led_buffer[i].r = (uint8_t)ro; | ||
| 551 | led_buffer[i].g = (uint8_t)go; | ||
| 552 | led_buffer[i].b = (uint8_t)bo; | ||
| 553 | } | ||
| 554 | |||
| 555 | # endif // USE_MASSDROP_CONFIGURATOR | ||
| 556 | #endif // RGB_MATRIX_ENABLE | ||
diff --git a/tmk_core/protocol/arm_atsam/md_rgb_matrix.h b/tmk_core/protocol/arm_atsam/md_rgb_matrix.h deleted file mode 100644 index bb3312e8e7..0000000000 --- a/tmk_core/protocol/arm_atsam/md_rgb_matrix.h +++ /dev/null | |||
| @@ -1,200 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | #include <stdint.h> | ||
| 21 | |||
| 22 | // From keyboard | ||
| 23 | #include "config_led.h" | ||
| 24 | |||
| 25 | // CS1-CS16 Current Source "Col" | ||
| 26 | #define ISSI3733_CS_COUNT 16 | ||
| 27 | |||
| 28 | // SW1-SW12 Switch "Row" | ||
| 29 | #define ISSI3733_SW_COUNT 12 | ||
| 30 | |||
| 31 | #define ISSI3733_LED_RGB_COUNT ISSI3733_CS_COUNT *ISSI3733_SW_COUNT | ||
| 32 | #define ISSI3733_PG0_BYTES ISSI3733_LED_RGB_COUNT / 8 + 1 //+1 for first byte being memory start offset for I2C transfer | ||
| 33 | #define ISSI3733_PG1_BYTES ISSI3733_LED_RGB_COUNT + 1 //+1 for first byte being memory start offset for I2C transfer | ||
| 34 | #define ISSI3733_PG2_BYTES ISSI3733_LED_RGB_COUNT + 1 //+1 for first byte being memory start offset for I2C transfer | ||
| 35 | #define ISSI3733_PG3_BYTES 18 + 1 //+1 for first byte being memory start offset for I2C transfer | ||
| 36 | |||
| 37 | #define ISSI3733_PG_ONOFF_BYTES ISSI3733_PG0_BYTES | ||
| 38 | #define ISSI3733_PG_OR_BYTES ISSI3733_PG0_BYTES | ||
| 39 | #define ISSI3733_PG_SR_BYTES ISSI3733_PG0_BYTES | ||
| 40 | #define ISSI3733_PG_PWM_BYTES ISSI3733_PG1_BYTES | ||
| 41 | #define ISSI3733_PG_ABM_BYTES ISSI3733_PG2_BYTES | ||
| 42 | #define ISSI3733_PG_FN_BYTES ISSI3733_PG3_BYTES | ||
| 43 | |||
| 44 | typedef struct issi3733_driver_s { | ||
| 45 | uint8_t addr; // Address of the driver according to wiring "ISSI3733: Table 1 Slave Address" | ||
| 46 | uint8_t onoff[ISSI3733_PG_ONOFF_BYTES]; // PG0 - LED Control Register - LED On/Off Register | ||
| 47 | uint8_t open[ISSI3733_PG_OR_BYTES]; // PG0 - LED Control Register - LED Open Register | ||
| 48 | uint8_t shrt[ISSI3733_PG_SR_BYTES]; // PG0 - LED Control Register - LED Short Register | ||
| 49 | uint8_t pwm[ISSI3733_PG_PWM_BYTES]; // PG1 - PWM Register | ||
| 50 | uint8_t abm[ISSI3733_PG_ABM_BYTES]; // PG2 - Auto Breath Mode Register | ||
| 51 | uint8_t conf[ISSI3733_PG_FN_BYTES]; // PG3 - Function Register | ||
| 52 | } issi3733_driver_t; | ||
| 53 | |||
| 54 | typedef struct issi3733_rgb_s { | ||
| 55 | uint8_t *r; // Direct access into PWM data | ||
| 56 | uint8_t *g; // Direct access into PWM data | ||
| 57 | uint8_t *b; // Direct access into PWM data | ||
| 58 | } issi3733_rgb_t; | ||
| 59 | |||
| 60 | typedef struct issi3733_rgb_adr_s { | ||
| 61 | uint8_t drv; // Driver from given list | ||
| 62 | uint8_t cs; // CS | ||
| 63 | uint8_t swr; // SW Red | ||
| 64 | uint8_t swg; // SW Green | ||
| 65 | uint8_t swb; // SW Blue | ||
| 66 | } issi3733_rgb_adr_t; | ||
| 67 | |||
| 68 | typedef struct issi3733_led_s { | ||
| 69 | uint8_t id; // According to PCB ref | ||
| 70 | issi3733_rgb_t rgb; // PWM settings of R G B | ||
| 71 | issi3733_rgb_adr_t adr; // Hardware addresses | ||
| 72 | float x; // Physical position X | ||
| 73 | float y; // Physical position Y | ||
| 74 | float px; // Physical position X in percent | ||
| 75 | float py; // Physical position Y in percent | ||
| 76 | uint8_t scan; // Key scan code from wiring (set 0xFF if no key) | ||
| 77 | } issi3733_led_t; | ||
| 78 | |||
| 79 | extern issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT]; | ||
| 80 | |||
| 81 | extern uint8_t gcr_breathe; | ||
| 82 | extern uint8_t gcr_actual; | ||
| 83 | extern uint8_t gcr_actual_last; | ||
| 84 | |||
| 85 | void gcr_compute(void); | ||
| 86 | |||
| 87 | void md_rgb_matrix_indicators_advanced(uint8_t led_min, uint8_t led_max); | ||
| 88 | |||
| 89 | /*------------------------- Legacy Lighting Support ------------------------*/ | ||
| 90 | |||
| 91 | #ifdef USE_MASSDROP_CONFIGURATOR | ||
| 92 | |||
| 93 | # define EF_NONE 0x00000000 // No effect | ||
| 94 | # define EF_OVER 0x00000001 // Overwrite any previous color information with new | ||
| 95 | # define EF_SCR_L 0x00000002 // Scroll left | ||
| 96 | # define EF_SCR_R 0x00000004 // Scroll right | ||
| 97 | # define EF_SUBTRACT 0x00000008 // Subtract color values | ||
| 98 | |||
| 99 | typedef struct led_setup_s { | ||
| 100 | float hs; // Band begin at percent | ||
| 101 | float he; // Band end at percent | ||
| 102 | uint8_t rs; // Red start value | ||
| 103 | uint8_t re; // Red end value | ||
| 104 | uint8_t gs; // Green start value | ||
| 105 | uint8_t ge; // Green end value | ||
| 106 | uint8_t bs; // Blue start value | ||
| 107 | uint8_t be; // Blue end value | ||
| 108 | uint32_t ef; // Animation and color effects | ||
| 109 | uint8_t end; // Set to signal end of the setup | ||
| 110 | } led_setup_t; | ||
| 111 | |||
| 112 | extern const uint8_t led_setups_count; | ||
| 113 | extern void * led_setups[]; | ||
| 114 | |||
| 115 | // LED Extra Instructions | ||
| 116 | # define LED_FLAG_NULL 0x00 // Matching and coloring not used (default) | ||
| 117 | # 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) | ||
| 118 | # define LED_FLAG_MATCH_LAYER 0x02 // Match on the current active layer (set layer to desired match layer) | ||
| 119 | # define LED_FLAG_USE_RGB 0x10 // Use a specific RGB value (set r, g, b to desired output color values) | ||
| 120 | # define LED_FLAG_USE_PATTERN 0x20 // Use a specific pattern ID (set pattern_id to desired output pattern) | ||
| 121 | # define LED_FLAG_USE_ROTATE_PATTERN 0x40 // Use pattern the user has cycled to manually | ||
| 122 | |||
| 123 | typedef struct led_instruction_s { | ||
| 124 | uint16_t flags; // Bitfield for LED instructions | ||
| 125 | uint32_t id0; // Bitwise id, IDs 0-31 | ||
| 126 | uint32_t id1; // Bitwise id, IDs 32-63 | ||
| 127 | uint32_t id2; // Bitwise id, IDs 64-95 | ||
| 128 | uint32_t id3; // Bitwise id, IDs 96-127 | ||
| 129 | uint32_t id4; // Bitwise id, IDs 128-159 | ||
| 130 | uint32_t id5; // Bitwise id, IDs 160-191 | ||
| 131 | uint8_t layer; | ||
| 132 | uint8_t r; | ||
| 133 | uint8_t g; | ||
| 134 | uint8_t b; | ||
| 135 | uint8_t pattern_id; | ||
| 136 | uint8_t end; | ||
| 137 | } led_instruction_t; | ||
| 138 | |||
| 139 | extern led_instruction_t led_instructions[]; | ||
| 140 | |||
| 141 | typedef struct led_config_s { | ||
| 142 | uint8_t ver; // assumed to be zero on eeprom reset | ||
| 143 | |||
| 144 | uint8_t desired_gcr; | ||
| 145 | uint8_t animation_breathing; | ||
| 146 | uint8_t animation_id; | ||
| 147 | float animation_speed; | ||
| 148 | uint8_t lighting_mode; | ||
| 149 | uint8_t enabled; | ||
| 150 | uint8_t animation_breathe_cur; | ||
| 151 | uint8_t animation_direction; | ||
| 152 | uint8_t animation_breathe_dir; | ||
| 153 | uint8_t animation_orientation; | ||
| 154 | uint8_t animation_circular; | ||
| 155 | float edge_brightness; | ||
| 156 | float ratio_brightness; | ||
| 157 | uint8_t edge_mode; | ||
| 158 | } md_led_config_t; | ||
| 159 | |||
| 160 | extern md_led_config_t md_led_config; | ||
| 161 | |||
| 162 | void md_led_changed(void); | ||
| 163 | |||
| 164 | # define gcr_desired md_led_config.desired_gcr | ||
| 165 | # define led_animation_breathing md_led_config.animation_breathing | ||
| 166 | # define led_animation_id md_led_config.animation_id | ||
| 167 | # define led_animation_speed md_led_config.animation_speed | ||
| 168 | # define led_lighting_mode md_led_config.lighting_mode | ||
| 169 | # define led_enabled md_led_config.enabled | ||
| 170 | # define led_animation_breathe_cur md_led_config.animation_breathe_cur | ||
| 171 | # define led_animation_direction md_led_config.animation_direction | ||
| 172 | # define breathe_dir md_led_config.animation_breathe_dir | ||
| 173 | # define led_animation_orientation md_led_config.animation_orientation | ||
| 174 | # define led_animation_circular md_led_config.animation_circular | ||
| 175 | # define led_edge_brightness md_led_config.edge_brightness | ||
| 176 | # define led_ratio_brightness md_led_config.ratio_brightness | ||
| 177 | # define led_edge_mode md_led_config.edge_mode | ||
| 178 | |||
| 179 | # define LED_MODE_NORMAL 0 // Must be 0 | ||
| 180 | # define LED_MODE_KEYS_ONLY 1 | ||
| 181 | # define LED_MODE_NON_KEYS_ONLY 2 | ||
| 182 | # define LED_MODE_INDICATORS_ONLY 3 | ||
| 183 | # define LED_MODE_MAX_INDEX LED_MODE_INDICATORS_ONLY // Must be highest value | ||
| 184 | |||
| 185 | # define LED_EDGE_MODE_ALL 0 // All edge LEDs are active (Must be 0) | ||
| 186 | # define LED_EDGE_MODE_ALTERNATE 1 // Alternate mode of edge LEDs are active (Intention is for 'only every other edge LED' to be active) | ||
| 187 | # define LED_EDGE_MODE_MAX LED_EDGE_MODE_ALTERNATE // Must be the highest valued LED edge mode | ||
| 188 | |||
| 189 | # define LED_EDGE_FULL_MODE 255 // LEDs configured with this scan code will always be on for edge lighting modes | ||
| 190 | # define LED_EDGE_ALT_MODE 254 // LEDs configured with this scan code will turn off in edge alternating mode | ||
| 191 | # define LED_EDGE_MIN_SCAN 254 // LEDs configured with scan code >= to this are assigned as edge LEDs | ||
| 192 | # define LED_INDICATOR_SCAN 253 // LEDs configured as dedicated indicators | ||
| 193 | |||
| 194 | # define LED_IS_KEY(scan) (scan < LED_INDICATOR_SCAN) // Return true if an LED's scan value indicates it is a key LED | ||
| 195 | # define LED_IS_EDGE(scan) (scan >= LED_EDGE_MIN_SCAN) // Return true if an LED's scan value indicates an edge LED | ||
| 196 | # 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 | ||
| 197 | # define LED_IS_INDICATOR(scan) (scan == LED_INDICATOR_SCAN) // Return true if an LED's scan value indicates it is a dedicated Indicator | ||
| 198 | #else | ||
| 199 | extern uint8_t gcr_desired; | ||
| 200 | #endif // USE_MASSDROP_CONFIGURATOR | ||
diff --git a/tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c b/tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c deleted file mode 100644 index 476b605297..0000000000 --- a/tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c +++ /dev/null | |||
| @@ -1,102 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifdef RGB_MATRIX_ENABLE | ||
| 19 | # ifdef USE_MASSDROP_CONFIGURATOR | ||
| 20 | |||
| 21 | # include "md_rgb_matrix.h" | ||
| 22 | # include "util.h" | ||
| 23 | |||
| 24 | // Teal <-> Salmon | ||
| 25 | led_setup_t leds_teal_salmon[] = { | ||
| 26 | {.hs = 0, .he = 33, .rs = 24, .re = 24, .gs = 215, .ge = 215, .bs = 204, .be = 204, .ef = EF_NONE}, | ||
| 27 | {.hs = 33, .he = 66, .rs = 24, .re = 255, .gs = 215, .ge = 114, .bs = 204, .be = 118, .ef = EF_NONE}, | ||
| 28 | {.hs = 66, .he = 100, .rs = 255, .re = 255, .gs = 114, .ge = 114, .bs = 118, .be = 118, .ef = EF_NONE}, | ||
| 29 | {.end = 1}, | ||
| 30 | }; | ||
| 31 | |||
| 32 | // Yellow | ||
| 33 | led_setup_t leds_yellow[] = { | ||
| 34 | {.hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_NONE}, | ||
| 35 | {.end = 1}, | ||
| 36 | }; | ||
| 37 | |||
| 38 | // Off | ||
| 39 | led_setup_t leds_off[] = { | ||
| 40 | {.hs = 0, .he = 100, .rs = 0, .re = 0, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_NONE}, | ||
| 41 | {.end = 1}, | ||
| 42 | }; | ||
| 43 | |||
| 44 | // Red | ||
| 45 | led_setup_t leds_red[] = { | ||
| 46 | {.hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_NONE}, | ||
| 47 | {.end = 1}, | ||
| 48 | }; | ||
| 49 | |||
| 50 | // Green | ||
| 51 | led_setup_t leds_green[] = { | ||
| 52 | {.hs = 0, .he = 100, .rs = 0, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_NONE}, | ||
| 53 | {.end = 1}, | ||
| 54 | }; | ||
| 55 | |||
| 56 | // Blue | ||
| 57 | led_setup_t leds_blue[] = { | ||
| 58 | {.hs = 0, .he = 100, .rs = 0, .re = 0, .gs = 0, .ge = 0, .bs = 255, .be = 255, .ef = EF_NONE}, | ||
| 59 | {.end = 1}, | ||
| 60 | }; | ||
| 61 | |||
| 62 | // White | ||
| 63 | led_setup_t leds_white[] = { | ||
| 64 | {.hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 255, .ge = 255, .bs = 255, .be = 255, .ef = EF_NONE}, | ||
| 65 | {.end = 1}, | ||
| 66 | }; | ||
| 67 | |||
| 68 | // White with moving red stripe | ||
| 69 | led_setup_t leds_white_with_red_stripe[] = { | ||
| 70 | {.hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 255, .ge = 255, .bs = 255, .be = 255, .ef = EF_NONE}, | ||
| 71 | {.hs = 0, .he = 15, .rs = 0, .re = 0, .gs = 0, .ge = 255, .bs = 0, .be = 255, .ef = EF_SCR_R | EF_SUBTRACT}, | ||
| 72 | {.hs = 15, .he = 30, .rs = 0, .re = 0, .gs = 255, .ge = 0, .bs = 255, .be = 0, .ef = EF_SCR_R | EF_SUBTRACT}, | ||
| 73 | {.end = 1}, | ||
| 74 | }; | ||
| 75 | |||
| 76 | // Black with moving red stripe | ||
| 77 | led_setup_t leds_black_with_red_stripe[] = { | ||
| 78 | {.hs = 0, .he = 15, .rs = 0, .re = 255, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_SCR_R}, | ||
| 79 | {.hs = 15, .he = 30, .rs = 255, .re = 0, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_SCR_R}, | ||
| 80 | {.end = 1}, | ||
| 81 | }; | ||
| 82 | |||
| 83 | // Rainbow no scrolling | ||
| 84 | led_setup_t leds_rainbow_ns[] = { | ||
| 85 | {.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}, | ||
| 86 | }; | ||
| 87 | |||
| 88 | // Rainbow scrolling | ||
| 89 | led_setup_t leds_rainbow_s[] = { | ||
| 90 | {.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}, | ||
| 91 | }; | ||
| 92 | |||
| 93 | // Add new LED animations here using one from above as example | ||
| 94 | // The last entry must be { .end = 1 } | ||
| 95 | // Add the new animation name to the list below following its format | ||
| 96 | |||
| 97 | 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}; | ||
| 98 | |||
| 99 | const uint8_t led_setups_count = ARRAY_SIZE(led_setups); | ||
| 100 | |||
| 101 | # endif // USE_MASSDROP_CONFIGURATOR | ||
| 102 | #endif // RGB_MATRIX_ENABLE \ No newline at end of file | ||
diff --git a/tmk_core/protocol/arm_atsam/shift_register.c b/tmk_core/protocol/arm_atsam/shift_register.c deleted file mode 100644 index e81db4a19d..0000000000 --- a/tmk_core/protocol/arm_atsam/shift_register.c +++ /dev/null | |||
| @@ -1,122 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include "arm_atsam_protocol.h" | ||
| 19 | |||
| 20 | #include "spi_master.h" | ||
| 21 | #include "wait.h" | ||
| 22 | #include "gpio.h" | ||
| 23 | |||
| 24 | // #define SR_USE_BITBANG | ||
| 25 | |||
| 26 | // Bodge for when spi_master is not available | ||
| 27 | #ifdef SR_USE_BITBANG | ||
| 28 | # define CLOCK_DELAY 10 | ||
| 29 | |||
| 30 | void shift_init_impl(void) { | ||
| 31 | gpio_set_pin_output(SR_EXP_RCLK_PIN); | ||
| 32 | gpio_set_pin_output(SPI_DATAOUT_PIN); | ||
| 33 | gpio_set_pin_output(SPI_SCLK_PIN); | ||
| 34 | } | ||
| 35 | |||
| 36 | void shift_out_impl(const uint8_t *data, uint16_t length) { | ||
| 37 | gpio_write_pin_low(SR_EXP_RCLK_PIN); | ||
| 38 | for (uint16_t i = 0; i < length; i++) { | ||
| 39 | uint8_t val = data[i]; | ||
| 40 | |||
| 41 | // shift out lsb first | ||
| 42 | for (uint8_t bit = 0; bit < 8; bit++) { | ||
| 43 | gpio_write_pin(SPI_DATAOUT_PIN, !!(val & (1 << bit))); | ||
| 44 | gpio_write_pin(SPI_SCLK_PIN, true); | ||
| 45 | wait_us(CLOCK_DELAY); | ||
| 46 | |||
| 47 | gpio_write_pin(SPI_SCLK_PIN, false); | ||
| 48 | wait_us(CLOCK_DELAY); | ||
| 49 | } | ||
| 50 | } | ||
| 51 | gpio_write_pin_high(SR_EXP_RCLK_PIN); | ||
| 52 | return SPI_STATUS_SUCCESS; | ||
| 53 | } | ||
| 54 | |||
| 55 | #else | ||
| 56 | |||
| 57 | void shift_init_impl(void) { | ||
| 58 | spi_init(); | ||
| 59 | } | ||
| 60 | |||
| 61 | void shift_out_impl(const uint8_t *data, uint16_t length) { | ||
| 62 | spi_start(SR_EXP_RCLK_PIN, true, 0, 0); | ||
| 63 | |||
| 64 | spi_transmit(data, length); | ||
| 65 | |||
| 66 | spi_stop(); | ||
| 67 | } | ||
| 68 | #endif | ||
| 69 | |||
| 70 | // *************************************************************** | ||
| 71 | |||
| 72 | void shift_out(const uint8_t *data, uint16_t length) { | ||
| 73 | shift_out_impl(data, length); | ||
| 74 | } | ||
| 75 | |||
| 76 | void shift_enable(void) { | ||
| 77 | gpio_set_pin_output(SR_EXP_OE_PIN); | ||
| 78 | gpio_write_pin_low(SR_EXP_OE_PIN); | ||
| 79 | } | ||
| 80 | |||
| 81 | void shift_disable(void) { | ||
| 82 | gpio_set_pin_output(SR_EXP_OE_PIN); | ||
| 83 | gpio_write_pin_high(SR_EXP_OE_PIN); | ||
| 84 | } | ||
| 85 | |||
| 86 | void shift_init(void) { | ||
| 87 | shift_disable(); | ||
| 88 | shift_init_impl(); | ||
| 89 | } | ||
| 90 | |||
| 91 | // *************************************************************** | ||
| 92 | |||
| 93 | sr_exp_t sr_exp_data; | ||
| 94 | |||
| 95 | void SR_EXP_WriteData(void) { | ||
| 96 | uint8_t data[2] = { | ||
| 97 | sr_exp_data.reg & 0xFF, // Shift in bits 7-0 | ||
| 98 | (sr_exp_data.reg >> 8) & 0xFF, // Shift in bits 15-8 | ||
| 99 | }; | ||
| 100 | shift_out(data, 2); | ||
| 101 | } | ||
| 102 | |||
| 103 | void SR_EXP_Init(void) { | ||
| 104 | shift_init(); | ||
| 105 | |||
| 106 | sr_exp_data.reg = 0; | ||
| 107 | sr_exp_data.bit.HUB_CONNECT = 0; | ||
| 108 | sr_exp_data.bit.HUB_RESET_N = 0; | ||
| 109 | sr_exp_data.bit.S_UP = 0; | ||
| 110 | sr_exp_data.bit.E_UP_N = 1; | ||
| 111 | sr_exp_data.bit.S_DN1 = 1; | ||
| 112 | sr_exp_data.bit.E_DN1_N = 1; | ||
| 113 | sr_exp_data.bit.E_VBUS_1 = 0; | ||
| 114 | sr_exp_data.bit.E_VBUS_2 = 0; | ||
| 115 | sr_exp_data.bit.SRC_1 = 1; | ||
| 116 | sr_exp_data.bit.SRC_2 = 1; | ||
| 117 | sr_exp_data.bit.IRST = 1; | ||
| 118 | sr_exp_data.bit.SDB_N = 0; | ||
| 119 | SR_EXP_WriteData(); | ||
| 120 | |||
| 121 | shift_enable(); | ||
| 122 | } | ||
diff --git a/tmk_core/protocol/arm_atsam/shift_register.h b/tmk_core/protocol/arm_atsam/shift_register.h deleted file mode 100644 index 56a8c7f717..0000000000 --- a/tmk_core/protocol/arm_atsam/shift_register.h +++ /dev/null | |||
| @@ -1,49 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | #include <stdint.h> | ||
| 21 | |||
| 22 | /* Data structure to define Shift Register output expander hardware */ | ||
| 23 | /* This structure gets shifted into registers LSB first */ | ||
| 24 | typedef union { | ||
| 25 | struct { | ||
| 26 | uint16_t RSVD4 : 1; /*!< bit: 0 */ | ||
| 27 | uint16_t RSVD3 : 1; /*!< bit: 1 */ | ||
| 28 | uint16_t RSVD2 : 1; /*!< bit: 2 */ | ||
| 29 | uint16_t RSVD1 : 1; /*!< bit: 3 */ | ||
| 30 | uint16_t SDB_N : 1; /*!< bit: 4 SHUTDOWN THE CHIP WHEN 0, RUN WHEN 1 */ | ||
| 31 | uint16_t IRST : 1; /*!< bit: 5 RESET THE IS3733 I2C WHEN 1, RUN WHEN 0 */ | ||
| 32 | uint16_t SRC_2 : 1; /*!< bit: 6 ADVERTISE A SOURCE TO USBC-2 CC */ | ||
| 33 | uint16_t SRC_1 : 1; /*!< bit: 7 ADVERTISE A SOURCE TO USBC-1 CC */ | ||
| 34 | uint16_t E_VBUS_2 : 1; /*!< bit: 8 ENABLE 5V OUT TO USBC-2 WHEN 1 */ | ||
| 35 | uint16_t E_VBUS_1 : 1; /*!< bit: 9 ENABLE 5V OUT TO USBC-1 WHEN 1 */ | ||
| 36 | uint16_t E_DN1_N : 1; /*!< bit: 10 ENABLE DN1 1:2 MUX WHEN 0 */ | ||
| 37 | uint16_t S_DN1 : 1; /*!< bit: 11 SELECT DN1 PATH 0:USBC-1, 1:USBC-2 */ | ||
| 38 | uint16_t E_UP_N : 1; /*!< bit: 12 ENABLE SUP 1:2 MUX WHEN 0 */ | ||
| 39 | uint16_t S_UP : 1; /*!< bit: 13 SELECT UP PATH 0:USBC-1, 1:USBC-2 */ | ||
| 40 | uint16_t HUB_RESET_N : 1; /*!< bit: 14 RESET USB HUB WHEN 0, RUN WHEN 1 */ | ||
| 41 | uint16_t HUB_CONNECT : 1; /*!< bit: 15 SIGNAL VBUS CONNECT TO USB HUB WHEN 1 */ | ||
| 42 | } bit; /*!< Structure used for bit access */ | ||
| 43 | uint16_t reg; /*!< Type used for register access */ | ||
| 44 | } sr_exp_t; | ||
| 45 | |||
| 46 | extern sr_exp_t sr_exp_data; | ||
| 47 | |||
| 48 | void SR_EXP_WriteData(void); | ||
| 49 | void SR_EXP_Init(void); | ||
diff --git a/tmk_core/protocol/arm_atsam/spi_master.c b/tmk_core/protocol/arm_atsam/spi_master.c deleted file mode 100644 index fedb9654fd..0000000000 --- a/tmk_core/protocol/arm_atsam/spi_master.c +++ /dev/null | |||
| @@ -1,109 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include "arm_atsam_protocol.h" | ||
| 19 | #include "spi_master.h" | ||
| 20 | #include "gpio.h" | ||
| 21 | |||
| 22 | /* Determine bits to set for mux selection */ | ||
| 23 | #if SPI_DATAOUT_PIN % 2 == 0 | ||
| 24 | # define SPI_DATAOUT_MUX_SEL PMUXE | ||
| 25 | #else | ||
| 26 | # define SPI_DATAOUT_MUX_SEL PMUXO | ||
| 27 | #endif | ||
| 28 | |||
| 29 | /* Determine bits to set for mux selection */ | ||
| 30 | #if SPI_SCLK_PIN % 2 == 0 | ||
| 31 | # define SPI_SCLK_MUX_SEL PMUXE | ||
| 32 | #else | ||
| 33 | # define SPI_SCLK_MUX_SEL PMUXO | ||
| 34 | #endif | ||
| 35 | |||
| 36 | static pin_t currentSelectPin = NO_PIN; | ||
| 37 | |||
| 38 | __attribute__((weak)) void spi_init(void) { | ||
| 39 | static bool is_initialised = false; | ||
| 40 | if (!is_initialised) { | ||
| 41 | is_initialised = true; | ||
| 42 | |||
| 43 | DBGC(DC_SPI_INIT_BEGIN); | ||
| 44 | |||
| 45 | CLK_set_spi_freq(CHAN_SERCOM_SPI, FREQ_SPI_DEFAULT); | ||
| 46 | |||
| 47 | // Set up MCU SPI pins | ||
| 48 | 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 | ||
| 49 | 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 | ||
| 50 | PORT->Group[SAMD_PORT(SPI_DATAOUT_PIN)].PINCFG[SAMD_PIN(SPI_DATAOUT_PIN)].bit.PMUXEN = 1; // MUX Enable | ||
| 51 | PORT->Group[SAMD_PORT(SPI_SCLK_PIN)].PINCFG[SAMD_PIN(SPI_SCLK_PIN)].bit.PMUXEN = 1; // MUX Enable | ||
| 52 | |||
| 53 | DBGC(DC_SPI_INIT_COMPLETE); | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | bool spi_start(pin_t csPin, bool lsbFirst, uint8_t mode, uint16_t divisor) { | ||
| 58 | if (currentSelectPin != NO_PIN || csPin == NO_PIN) { | ||
| 59 | return false; | ||
| 60 | } | ||
| 61 | |||
| 62 | currentSelectPin = csPin; | ||
| 63 | gpio_set_pin_output(currentSelectPin); | ||
| 64 | gpio_write_pin_low(currentSelectPin); | ||
| 65 | |||
| 66 | SPI_SERCOM->SPI.CTRLA.bit.DORD = lsbFirst; // Data Order - LSB is transferred first | ||
| 67 | SPI_SERCOM->SPI.CTRLA.bit.CPOL = 1; // Clock Polarity - SCK high when idle. Leading edge of cycle is falling. Trailing rising. | ||
| 68 | SPI_SERCOM->SPI.CTRLA.bit.CPHA = 1; // Clock Phase - Leading Edge Falling, change, Trailing Edge - Rising, sample | ||
| 69 | 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.) | ||
| 70 | SPI_SERCOM->SPI.CTRLA.bit.DOPO = 0; // Data Output PAD[0], Serial Clock PAD[1] | ||
| 71 | SPI_SERCOM->SPI.CTRLA.bit.MODE = 3; // Operating Mode - Master operation | ||
| 72 | |||
| 73 | SPI_SERCOM->SPI.CTRLA.bit.ENABLE = 1; // Enable - Peripheral is enabled or being enabled | ||
| 74 | while (SPI_SERCOM->SPI.SYNCBUSY.bit.ENABLE) { | ||
| 75 | DBGC(DC_SPI_SYNC_ENABLING); | ||
| 76 | } | ||
| 77 | return true; | ||
| 78 | } | ||
| 79 | |||
| 80 | spi_status_t spi_transmit(const uint8_t *data, uint16_t length) { | ||
| 81 | while (!(SPI_SERCOM->SPI.INTFLAG.bit.DRE)) { | ||
| 82 | DBGC(DC_SPI_WRITE_DRE); | ||
| 83 | } | ||
| 84 | |||
| 85 | for (uint16_t i = 0; i < length; i++) { | ||
| 86 | SPI_SERCOM->SPI.DATA.bit.DATA = data[i]; | ||
| 87 | while (!(SPI_SERCOM->SPI.INTFLAG.bit.TXC)) { | ||
| 88 | DBGC(DC_SPI_WRITE_TXC_1); | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | return SPI_STATUS_SUCCESS; | ||
| 93 | } | ||
| 94 | |||
| 95 | void spi_stop(void) { | ||
| 96 | if (currentSelectPin != NO_PIN) { | ||
| 97 | gpio_set_pin_output(currentSelectPin); | ||
| 98 | gpio_write_pin_high(currentSelectPin); | ||
| 99 | currentSelectPin = NO_PIN; | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | // Not implemented yet.... | ||
| 104 | |||
| 105 | spi_status_t spi_write(uint8_t data); | ||
| 106 | |||
| 107 | spi_status_t spi_read(void); | ||
| 108 | |||
| 109 | spi_status_t spi_receive(uint8_t *data, uint16_t length); | ||
diff --git a/tmk_core/protocol/arm_atsam/spi_master.h b/tmk_core/protocol/arm_atsam/spi_master.h deleted file mode 100644 index 80678a5707..0000000000 --- a/tmk_core/protocol/arm_atsam/spi_master.h +++ /dev/null | |||
| @@ -1,50 +0,0 @@ | |||
| 1 | /* Copyright 2021 QMK | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 3 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #pragma once | ||
| 18 | |||
| 19 | #include <stdint.h> | ||
| 20 | #include <stdbool.h> | ||
| 21 | #include "gpio.h" | ||
| 22 | |||
| 23 | typedef int16_t spi_status_t; | ||
| 24 | |||
| 25 | #define SPI_STATUS_SUCCESS (0) | ||
| 26 | #define SPI_STATUS_ERROR (-1) | ||
| 27 | #define SPI_STATUS_TIMEOUT (-2) | ||
| 28 | |||
| 29 | #define SPI_TIMEOUT_IMMEDIATE (0) | ||
| 30 | #define SPI_TIMEOUT_INFINITE (0xFFFF) | ||
| 31 | |||
| 32 | #ifdef __cplusplus | ||
| 33 | extern "C" { | ||
| 34 | #endif | ||
| 35 | void spi_init(void); | ||
| 36 | |||
| 37 | bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor); | ||
| 38 | |||
| 39 | spi_status_t spi_write(uint8_t data); | ||
| 40 | |||
| 41 | spi_status_t spi_read(void); | ||
| 42 | |||
| 43 | spi_status_t spi_transmit(const uint8_t *data, uint16_t length); | ||
| 44 | |||
| 45 | spi_status_t spi_receive(uint8_t *data, uint16_t length); | ||
| 46 | |||
| 47 | void spi_stop(void); | ||
| 48 | #ifdef __cplusplus | ||
| 49 | } | ||
| 50 | #endif | ||
diff --git a/tmk_core/protocol/arm_atsam/startup.c b/tmk_core/protocol/arm_atsam/startup.c deleted file mode 100644 index ce043bad51..0000000000 --- a/tmk_core/protocol/arm_atsam/startup.c +++ /dev/null | |||
| @@ -1,563 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief gcc starttup file for SAMD51 | ||
| 5 | * | ||
| 6 | * Copyright (c) 2017 Microchip Technology Inc. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * SPDX-License-Identifier: Apache-2.0 | ||
| 13 | * | ||
| 14 | * Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
| 15 | * not use this file except in compliance with the License. | ||
| 16 | * You may obtain a copy of the Licence at | ||
| 17 | * | ||
| 18 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 19 | * | ||
| 20 | * Unless required by applicable law or agreed to in writing, software | ||
| 21 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||
| 22 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 23 | * See the License for the specific language governing permissions and | ||
| 24 | * limitations under the License. | ||
| 25 | * | ||
| 26 | * \asf_license_stop | ||
| 27 | * | ||
| 28 | */ | ||
| 29 | |||
| 30 | #include "samd51.h" | ||
| 31 | |||
| 32 | /* Initialize segments */ | ||
| 33 | extern uint32_t _sfixed; | ||
| 34 | extern uint32_t _efixed; | ||
| 35 | extern uint32_t _etext; | ||
| 36 | extern uint32_t _srelocate; | ||
| 37 | extern uint32_t _erelocate; | ||
| 38 | extern uint32_t _szero; | ||
| 39 | extern uint32_t _ezero; | ||
| 40 | extern uint32_t _sstack; | ||
| 41 | extern uint32_t _estack; | ||
| 42 | |||
| 43 | /** \cond DOXYGEN_SHOULD_SKIP_THIS */ | ||
| 44 | int main(void); | ||
| 45 | /** \endcond */ | ||
| 46 | |||
| 47 | void __libc_init_array(void); | ||
| 48 | |||
| 49 | /* Default empty handler */ | ||
| 50 | void Dummy_Handler(void); | ||
| 51 | |||
| 52 | /* Cortex-M4 core handlers */ | ||
| 53 | void NMI_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 54 | void HardFault_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 55 | void MemManage_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 56 | void BusFault_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 57 | void UsageFault_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 58 | void SVC_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 59 | void DebugMon_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 60 | void PendSV_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 61 | void SysTick_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 62 | |||
| 63 | /* Peripherals handlers */ | ||
| 64 | void PM_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 65 | void MCLK_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 66 | void OSCCTRL_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* OSCCTRL_XOSCFAIL_0, OSCCTRL_XOSCRDY_0 */ | ||
| 67 | void OSCCTRL_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* OSCCTRL_XOSCFAIL_1, OSCCTRL_XOSCRDY_1 */ | ||
| 68 | void OSCCTRL_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* OSCCTRL_DFLLLOCKC, OSCCTRL_DFLLLOCKF, OSCCTRL_DFLLOOB, OSCCTRL_DFLLRCS, OSCCTRL_DFLLRDY */ | ||
| 69 | void OSCCTRL_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* OSCCTRL_DPLLLCKF_0, OSCCTRL_DPLLLCKR_0, OSCCTRL_DPLLLDRTO_0, OSCCTRL_DPLLLTO_0 */ | ||
| 70 | void OSCCTRL_4_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* OSCCTRL_DPLLLCKF_1, OSCCTRL_DPLLLCKR_1, OSCCTRL_DPLLLDRTO_1, OSCCTRL_DPLLLTO_1 */ | ||
| 71 | void OSC32KCTRL_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 72 | void SUPC_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SUPC_B12SRDY, SUPC_B33SRDY, SUPC_BOD12RDY, SUPC_BOD33RDY, SUPC_VCORERDY, SUPC_VREGRDY */ | ||
| 73 | void SUPC_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SUPC_BOD12DET, SUPC_BOD33DET */ | ||
| 74 | void WDT_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 75 | void RTC_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 76 | void EIC_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_0 */ | ||
| 77 | void EIC_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_1 */ | ||
| 78 | void EIC_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_2 */ | ||
| 79 | void EIC_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_3 */ | ||
| 80 | void EIC_4_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_4 */ | ||
| 81 | void EIC_5_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_5 */ | ||
| 82 | void EIC_6_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_6 */ | ||
| 83 | void EIC_7_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_7 */ | ||
| 84 | void EIC_8_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_8 */ | ||
| 85 | void EIC_9_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_9 */ | ||
| 86 | void EIC_10_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_10 */ | ||
| 87 | void EIC_11_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_11 */ | ||
| 88 | void EIC_12_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_12 */ | ||
| 89 | void EIC_13_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_13 */ | ||
| 90 | void EIC_14_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_14 */ | ||
| 91 | void EIC_15_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_15 */ | ||
| 92 | void FREQM_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 93 | 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 */ | ||
| 94 | void NVMCTRL_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* NVMCTRL_10, NVMCTRL_8, NVMCTRL_9 */ | ||
| 95 | void DMAC_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DMAC_SUSP_0, DMAC_TCMPL_0, DMAC_TERR_0 */ | ||
| 96 | void DMAC_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DMAC_SUSP_1, DMAC_TCMPL_1, DMAC_TERR_1 */ | ||
| 97 | void DMAC_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DMAC_SUSP_2, DMAC_TCMPL_2, DMAC_TERR_2 */ | ||
| 98 | void DMAC_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DMAC_SUSP_3, DMAC_TCMPL_3, DMAC_TERR_3 */ | ||
| 99 | 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, | ||
| 100 | 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 */ | ||
| 101 | void EVSYS_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EVSYS_EVD_0, EVSYS_OVR_0 */ | ||
| 102 | void EVSYS_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EVSYS_EVD_1, EVSYS_OVR_1 */ | ||
| 103 | void EVSYS_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EVSYS_EVD_2, EVSYS_OVR_2 */ | ||
| 104 | void EVSYS_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EVSYS_EVD_3, EVSYS_OVR_3 */ | ||
| 105 | 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 */ | ||
| 106 | void PAC_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 107 | void TAL_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TAL_BRK */ | ||
| 108 | void TAL_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TAL_IPS_0, TAL_IPS_1 */ | ||
| 109 | void RAMECC_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 110 | void SERCOM0_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM0_0 */ | ||
| 111 | void SERCOM0_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM0_1 */ | ||
| 112 | void SERCOM0_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM0_2 */ | ||
| 113 | void SERCOM0_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM0_3, SERCOM0_4, SERCOM0_5, SERCOM0_6 */ | ||
| 114 | void SERCOM1_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM1_0 */ | ||
| 115 | void SERCOM1_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM1_1 */ | ||
| 116 | void SERCOM1_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM1_2 */ | ||
| 117 | void SERCOM1_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM1_3, SERCOM1_4, SERCOM1_5, SERCOM1_6 */ | ||
| 118 | void SERCOM2_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM2_0 */ | ||
| 119 | void SERCOM2_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM2_1 */ | ||
| 120 | void SERCOM2_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM2_2 */ | ||
| 121 | void SERCOM2_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM2_3, SERCOM2_4, SERCOM2_5, SERCOM2_6 */ | ||
| 122 | void SERCOM3_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM3_0 */ | ||
| 123 | void SERCOM3_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM3_1 */ | ||
| 124 | void SERCOM3_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM3_2 */ | ||
| 125 | void SERCOM3_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM3_3, SERCOM3_4, SERCOM3_5, SERCOM3_6 */ | ||
| 126 | #ifdef ID_SERCOM4 | ||
| 127 | void SERCOM4_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM4_0 */ | ||
| 128 | void SERCOM4_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM4_1 */ | ||
| 129 | void SERCOM4_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM4_2 */ | ||
| 130 | void SERCOM4_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM4_3, SERCOM4_4, SERCOM4_5, SERCOM4_6 */ | ||
| 131 | #endif | ||
| 132 | #ifdef ID_SERCOM5 | ||
| 133 | void SERCOM5_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM5_0 */ | ||
| 134 | void SERCOM5_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM5_1 */ | ||
| 135 | void SERCOM5_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM5_2 */ | ||
| 136 | void SERCOM5_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM5_3, SERCOM5_4, SERCOM5_5, SERCOM5_6 */ | ||
| 137 | #endif | ||
| 138 | #ifdef ID_SERCOM6 | ||
| 139 | void SERCOM6_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM6_0 */ | ||
| 140 | void SERCOM6_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM6_1 */ | ||
| 141 | void SERCOM6_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM6_2 */ | ||
| 142 | void SERCOM6_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM6_3, SERCOM6_4, SERCOM6_5, SERCOM6_6 */ | ||
| 143 | #endif | ||
| 144 | #ifdef ID_SERCOM7 | ||
| 145 | void SERCOM7_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM7_0 */ | ||
| 146 | void SERCOM7_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM7_1 */ | ||
| 147 | void SERCOM7_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM7_2 */ | ||
| 148 | void SERCOM7_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM7_3, SERCOM7_4, SERCOM7_5, SERCOM7_6 */ | ||
| 149 | #endif | ||
| 150 | #ifdef ID_CAN0 | ||
| 151 | void CAN0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 152 | #endif | ||
| 153 | #ifdef ID_CAN1 | ||
| 154 | void CAN1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 155 | #endif | ||
| 156 | #ifdef ID_USB | ||
| 157 | 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 */ | ||
| 158 | void USB_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* USB_SOF_HSOF */ | ||
| 159 | 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 */ | ||
| 160 | 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 */ | ||
| 161 | #endif | ||
| 162 | #ifdef ID_GMAC | ||
| 163 | void GMAC_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 164 | #endif | ||
| 165 | 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 */ | ||
| 166 | void TCC0_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_MC_0 */ | ||
| 167 | void TCC0_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_MC_1 */ | ||
| 168 | void TCC0_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_MC_2 */ | ||
| 169 | void TCC0_4_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_MC_3 */ | ||
| 170 | void TCC0_5_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_MC_4 */ | ||
| 171 | void TCC0_6_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_MC_5 */ | ||
| 172 | 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 */ | ||
| 173 | void TCC1_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC1_MC_0 */ | ||
| 174 | void TCC1_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC1_MC_1 */ | ||
| 175 | void TCC1_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC1_MC_2 */ | ||
| 176 | void TCC1_4_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC1_MC_3 */ | ||
| 177 | 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 */ | ||
| 178 | void TCC2_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC2_MC_0 */ | ||
| 179 | void TCC2_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC2_MC_1 */ | ||
| 180 | void TCC2_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC2_MC_2 */ | ||
| 181 | #ifdef ID_TCC3 | ||
| 182 | 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 */ | ||
| 183 | void TCC3_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC3_MC_0 */ | ||
| 184 | void TCC3_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC3_MC_1 */ | ||
| 185 | #endif | ||
| 186 | #ifdef ID_TCC4 | ||
| 187 | 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 */ | ||
| 188 | void TCC4_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC4_MC_0 */ | ||
| 189 | void TCC4_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC4_MC_1 */ | ||
| 190 | #endif | ||
| 191 | void TC0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 192 | void TC1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 193 | void TC2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 194 | void TC3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 195 | #ifdef ID_TC4 | ||
| 196 | void TC4_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 197 | #endif | ||
| 198 | #ifdef ID_TC5 | ||
| 199 | void TC5_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 200 | #endif | ||
| 201 | #ifdef ID_TC6 | ||
| 202 | void TC6_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 203 | #endif | ||
| 204 | #ifdef ID_TC7 | ||
| 205 | void TC7_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 206 | #endif | ||
| 207 | void PDEC_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* PDEC_DIR_A, PDEC_ERR_A, PDEC_OVF, PDEC_VLC_A */ | ||
| 208 | void PDEC_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* PDEC_MC_0 */ | ||
| 209 | void PDEC_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* PDEC_MC_1 */ | ||
| 210 | void ADC0_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* ADC0_OVERRUN, ADC0_WINMON */ | ||
| 211 | void ADC0_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* ADC0_RESRDY */ | ||
| 212 | void ADC1_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* ADC1_OVERRUN, ADC1_WINMON */ | ||
| 213 | void ADC1_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* ADC1_RESRDY */ | ||
| 214 | void AC_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 215 | 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 */ | ||
| 216 | void DAC_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DAC_EMPTY_0 */ | ||
| 217 | void DAC_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DAC_EMPTY_1 */ | ||
| 218 | void DAC_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DAC_RESRDY_0 */ | ||
| 219 | void DAC_4_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DAC_RESRDY_1 */ | ||
| 220 | #ifdef ID_I2S | ||
| 221 | void I2S_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 222 | #endif | ||
| 223 | void PCC_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 224 | void AES_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 225 | void TRNG_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 226 | #ifdef ID_ICM | ||
| 227 | void ICM_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 228 | #endif | ||
| 229 | #ifdef ID_PUKCC | ||
| 230 | void PUKCC_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 231 | #endif | ||
| 232 | void QSPI_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 233 | #ifdef ID_SDHC0 | ||
| 234 | void SDHC0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 235 | #endif | ||
| 236 | #ifdef ID_SDHC1 | ||
| 237 | void SDHC1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); | ||
| 238 | #endif | ||
| 239 | |||
| 240 | /* Exception Table */ | ||
| 241 | __attribute__((section(".vectors"))) const DeviceVectors exception_table = { | ||
| 242 | |||
| 243 | /* Configure Initial Stack Pointer, using linker-generated symbols */ | ||
| 244 | .pvStack = (void *)(&_estack), | ||
| 245 | |||
| 246 | .pfnReset_Handler = (void *)Reset_Handler, | ||
| 247 | .pfnNMI_Handler = (void *)NMI_Handler, | ||
| 248 | .pfnHardFault_Handler = (void *)HardFault_Handler, | ||
| 249 | .pfnMemManage_Handler = (void *)MemManage_Handler, | ||
| 250 | .pfnBusFault_Handler = (void *)BusFault_Handler, | ||
| 251 | .pfnUsageFault_Handler = (void *)UsageFault_Handler, | ||
| 252 | .pvReservedM9 = (void *)(0UL), /* Reserved */ | ||
| 253 | .pvReservedM8 = (void *)(0UL), /* Reserved */ | ||
| 254 | .pvReservedM7 = (void *)(0UL), /* Reserved */ | ||
| 255 | .pvReservedM6 = (void *)(0UL), /* Reserved */ | ||
| 256 | .pfnSVC_Handler = (void *)SVC_Handler, | ||
| 257 | .pfnDebugMon_Handler = (void *)DebugMon_Handler, | ||
| 258 | .pvReservedM3 = (void *)(0UL), /* Reserved */ | ||
| 259 | .pfnPendSV_Handler = (void *)PendSV_Handler, | ||
| 260 | .pfnSysTick_Handler = (void *)SysTick_Handler, | ||
| 261 | |||
| 262 | /* Configurable interrupts */ | ||
| 263 | .pfnPM_Handler = (void *)PM_Handler, /* 0 Power Manager */ | ||
| 264 | .pfnMCLK_Handler = (void *)MCLK_Handler, /* 1 Main Clock */ | ||
| 265 | .pfnOSCCTRL_0_Handler = (void *)OSCCTRL_0_Handler, /* 2 OSCCTRL_XOSCFAIL_0, OSCCTRL_XOSCRDY_0 */ | ||
| 266 | .pfnOSCCTRL_1_Handler = (void *)OSCCTRL_1_Handler, /* 3 OSCCTRL_XOSCFAIL_1, OSCCTRL_XOSCRDY_1 */ | ||
| 267 | .pfnOSCCTRL_2_Handler = (void *)OSCCTRL_2_Handler, /* 4 OSCCTRL_DFLLLOCKC, OSCCTRL_DFLLLOCKF, OSCCTRL_DFLLOOB, OSCCTRL_DFLLRCS, OSCCTRL_DFLLRDY */ | ||
| 268 | .pfnOSCCTRL_3_Handler = (void *)OSCCTRL_3_Handler, /* 5 OSCCTRL_DPLLLCKF_0, OSCCTRL_DPLLLCKR_0, OSCCTRL_DPLLLDRTO_0, OSCCTRL_DPLLLTO_0 */ | ||
| 269 | .pfnOSCCTRL_4_Handler = (void *)OSCCTRL_4_Handler, /* 6 OSCCTRL_DPLLLCKF_1, OSCCTRL_DPLLLCKR_1, OSCCTRL_DPLLLDRTO_1, OSCCTRL_DPLLLTO_1 */ | ||
| 270 | .pfnOSC32KCTRL_Handler = (void *)OSC32KCTRL_Handler, /* 7 32kHz Oscillators Control */ | ||
| 271 | .pfnSUPC_0_Handler = (void *)SUPC_0_Handler, /* 8 SUPC_B12SRDY, SUPC_B33SRDY, SUPC_BOD12RDY, SUPC_BOD33RDY, SUPC_VCORERDY, SUPC_VREGRDY */ | ||
| 272 | .pfnSUPC_1_Handler = (void *)SUPC_1_Handler, /* 9 SUPC_BOD12DET, SUPC_BOD33DET */ | ||
| 273 | .pfnWDT_Handler = (void *)WDT_Handler, /* 10 Watchdog Timer */ | ||
| 274 | .pfnRTC_Handler = (void *)RTC_Handler, /* 11 Real-Time Counter */ | ||
| 275 | .pfnEIC_0_Handler = (void *)EIC_0_Handler, /* 12 EIC_EXTINT_0 */ | ||
| 276 | .pfnEIC_1_Handler = (void *)EIC_1_Handler, /* 13 EIC_EXTINT_1 */ | ||
| 277 | .pfnEIC_2_Handler = (void *)EIC_2_Handler, /* 14 EIC_EXTINT_2 */ | ||
| 278 | .pfnEIC_3_Handler = (void *)EIC_3_Handler, /* 15 EIC_EXTINT_3 */ | ||
| 279 | .pfnEIC_4_Handler = (void *)EIC_4_Handler, /* 16 EIC_EXTINT_4 */ | ||
| 280 | .pfnEIC_5_Handler = (void *)EIC_5_Handler, /* 17 EIC_EXTINT_5 */ | ||
| 281 | .pfnEIC_6_Handler = (void *)EIC_6_Handler, /* 18 EIC_EXTINT_6 */ | ||
| 282 | .pfnEIC_7_Handler = (void *)EIC_7_Handler, /* 19 EIC_EXTINT_7 */ | ||
| 283 | .pfnEIC_8_Handler = (void *)EIC_8_Handler, /* 20 EIC_EXTINT_8 */ | ||
| 284 | .pfnEIC_9_Handler = (void *)EIC_9_Handler, /* 21 EIC_EXTINT_9 */ | ||
| 285 | .pfnEIC_10_Handler = (void *)EIC_10_Handler, /* 22 EIC_EXTINT_10 */ | ||
| 286 | .pfnEIC_11_Handler = (void *)EIC_11_Handler, /* 23 EIC_EXTINT_11 */ | ||
| 287 | .pfnEIC_12_Handler = (void *)EIC_12_Handler, /* 24 EIC_EXTINT_12 */ | ||
| 288 | .pfnEIC_13_Handler = (void *)EIC_13_Handler, /* 25 EIC_EXTINT_13 */ | ||
| 289 | .pfnEIC_14_Handler = (void *)EIC_14_Handler, /* 26 EIC_EXTINT_14 */ | ||
| 290 | .pfnEIC_15_Handler = (void *)EIC_15_Handler, /* 27 EIC_EXTINT_15 */ | ||
| 291 | .pfnFREQM_Handler = (void *)FREQM_Handler, /* 28 Frequency Meter */ | ||
| 292 | .pfnNVMCTRL_0_Handler = (void *)NVMCTRL_0_Handler, /* 29 NVMCTRL_0, NVMCTRL_1, NVMCTRL_2, NVMCTRL_3, NVMCTRL_4, NVMCTRL_5, NVMCTRL_6, NVMCTRL_7 */ | ||
| 293 | .pfnNVMCTRL_1_Handler = (void *)NVMCTRL_1_Handler, /* 30 NVMCTRL_10, NVMCTRL_8, NVMCTRL_9 */ | ||
| 294 | .pfnDMAC_0_Handler = (void *)DMAC_0_Handler, /* 31 DMAC_SUSP_0, DMAC_TCMPL_0, DMAC_TERR_0 */ | ||
| 295 | .pfnDMAC_1_Handler = (void *)DMAC_1_Handler, /* 32 DMAC_SUSP_1, DMAC_TCMPL_1, DMAC_TERR_1 */ | ||
| 296 | .pfnDMAC_2_Handler = (void *)DMAC_2_Handler, /* 33 DMAC_SUSP_2, DMAC_TCMPL_2, DMAC_TERR_2 */ | ||
| 297 | .pfnDMAC_3_Handler = (void *)DMAC_3_Handler, /* 34 DMAC_SUSP_3, DMAC_TCMPL_3, DMAC_TERR_3 */ | ||
| 298 | .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, | ||
| 299 | 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 */ | ||
| 300 | .pfnEVSYS_0_Handler = (void *)EVSYS_0_Handler, /* 36 EVSYS_EVD_0, EVSYS_OVR_0 */ | ||
| 301 | .pfnEVSYS_1_Handler = (void *)EVSYS_1_Handler, /* 37 EVSYS_EVD_1, EVSYS_OVR_1 */ | ||
| 302 | .pfnEVSYS_2_Handler = (void *)EVSYS_2_Handler, /* 38 EVSYS_EVD_2, EVSYS_OVR_2 */ | ||
| 303 | .pfnEVSYS_3_Handler = (void *)EVSYS_3_Handler, /* 39 EVSYS_EVD_3, EVSYS_OVR_3 */ | ||
| 304 | .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 */ | ||
| 305 | .pfnPAC_Handler = (void *)PAC_Handler, /* 41 Peripheral Access Controller */ | ||
| 306 | .pfnTAL_0_Handler = (void *)TAL_0_Handler, /* 42 TAL_BRK */ | ||
| 307 | .pfnTAL_1_Handler = (void *)TAL_1_Handler, /* 43 TAL_IPS_0, TAL_IPS_1 */ | ||
| 308 | .pvReserved44 = (void *)(0UL), /* 44 Reserved */ | ||
| 309 | .pfnRAMECC_Handler = (void *)RAMECC_Handler, /* 45 RAM ECC */ | ||
| 310 | .pfnSERCOM0_0_Handler = (void *)SERCOM0_0_Handler, /* 46 SERCOM0_0 */ | ||
| 311 | .pfnSERCOM0_1_Handler = (void *)SERCOM0_1_Handler, /* 47 SERCOM0_1 */ | ||
| 312 | .pfnSERCOM0_2_Handler = (void *)SERCOM0_2_Handler, /* 48 SERCOM0_2 */ | ||
| 313 | .pfnSERCOM0_3_Handler = (void *)SERCOM0_3_Handler, /* 49 SERCOM0_3, SERCOM0_4, SERCOM0_5, SERCOM0_6 */ | ||
| 314 | .pfnSERCOM1_0_Handler = (void *)SERCOM1_0_Handler, /* 50 SERCOM1_0 */ | ||
| 315 | .pfnSERCOM1_1_Handler = (void *)SERCOM1_1_Handler, /* 51 SERCOM1_1 */ | ||
| 316 | .pfnSERCOM1_2_Handler = (void *)SERCOM1_2_Handler, /* 52 SERCOM1_2 */ | ||
| 317 | .pfnSERCOM1_3_Handler = (void *)SERCOM1_3_Handler, /* 53 SERCOM1_3, SERCOM1_4, SERCOM1_5, SERCOM1_6 */ | ||
| 318 | .pfnSERCOM2_0_Handler = (void *)SERCOM2_0_Handler, /* 54 SERCOM2_0 */ | ||
| 319 | .pfnSERCOM2_1_Handler = (void *)SERCOM2_1_Handler, /* 55 SERCOM2_1 */ | ||
| 320 | .pfnSERCOM2_2_Handler = (void *)SERCOM2_2_Handler, /* 56 SERCOM2_2 */ | ||
| 321 | .pfnSERCOM2_3_Handler = (void *)SERCOM2_3_Handler, /* 57 SERCOM2_3, SERCOM2_4, SERCOM2_5, SERCOM2_6 */ | ||
| 322 | .pfnSERCOM3_0_Handler = (void *)SERCOM3_0_Handler, /* 58 SERCOM3_0 */ | ||
| 323 | .pfnSERCOM3_1_Handler = (void *)SERCOM3_1_Handler, /* 59 SERCOM3_1 */ | ||
| 324 | .pfnSERCOM3_2_Handler = (void *)SERCOM3_2_Handler, /* 60 SERCOM3_2 */ | ||
| 325 | .pfnSERCOM3_3_Handler = (void *)SERCOM3_3_Handler, /* 61 SERCOM3_3, SERCOM3_4, SERCOM3_5, SERCOM3_6 */ | ||
| 326 | #ifdef ID_SERCOM4 | ||
| 327 | .pfnSERCOM4_0_Handler = (void *)SERCOM4_0_Handler, /* 62 SERCOM4_0 */ | ||
| 328 | .pfnSERCOM4_1_Handler = (void *)SERCOM4_1_Handler, /* 63 SERCOM4_1 */ | ||
| 329 | .pfnSERCOM4_2_Handler = (void *)SERCOM4_2_Handler, /* 64 SERCOM4_2 */ | ||
| 330 | .pfnSERCOM4_3_Handler = (void *)SERCOM4_3_Handler, /* 65 SERCOM4_3, SERCOM4_4, SERCOM4_5, SERCOM4_6 */ | ||
| 331 | #else | ||
| 332 | .pvReserved62 = (void *)(0UL), /* 62 Reserved */ | ||
| 333 | .pvReserved63 = (void *)(0UL), /* 63 Reserved */ | ||
| 334 | .pvReserved64 = (void *)(0UL), /* 64 Reserved */ | ||
| 335 | .pvReserved65 = (void *)(0UL), /* 65 Reserved */ | ||
| 336 | #endif | ||
| 337 | #ifdef ID_SERCOM5 | ||
| 338 | .pfnSERCOM5_0_Handler = (void *)SERCOM5_0_Handler, /* 66 SERCOM5_0 */ | ||
| 339 | .pfnSERCOM5_1_Handler = (void *)SERCOM5_1_Handler, /* 67 SERCOM5_1 */ | ||
| 340 | .pfnSERCOM5_2_Handler = (void *)SERCOM5_2_Handler, /* 68 SERCOM5_2 */ | ||
| 341 | .pfnSERCOM5_3_Handler = (void *)SERCOM5_3_Handler, /* 69 SERCOM5_3, SERCOM5_4, SERCOM5_5, SERCOM5_6 */ | ||
| 342 | #else | ||
| 343 | .pvReserved66 = (void *)(0UL), /* 66 Reserved */ | ||
| 344 | .pvReserved67 = (void *)(0UL), /* 67 Reserved */ | ||
| 345 | .pvReserved68 = (void *)(0UL), /* 68 Reserved */ | ||
| 346 | .pvReserved69 = (void *)(0UL), /* 69 Reserved */ | ||
| 347 | #endif | ||
| 348 | #ifdef ID_SERCOM6 | ||
| 349 | .pfnSERCOM6_0_Handler = (void *)SERCOM6_0_Handler, /* 70 SERCOM6_0 */ | ||
| 350 | .pfnSERCOM6_1_Handler = (void *)SERCOM6_1_Handler, /* 71 SERCOM6_1 */ | ||
| 351 | .pfnSERCOM6_2_Handler = (void *)SERCOM6_2_Handler, /* 72 SERCOM6_2 */ | ||
| 352 | .pfnSERCOM6_3_Handler = (void *)SERCOM6_3_Handler, /* 73 SERCOM6_3, SERCOM6_4, SERCOM6_5, SERCOM6_6 */ | ||
| 353 | #else | ||
| 354 | .pvReserved70 = (void *)(0UL), /* 70 Reserved */ | ||
| 355 | .pvReserved71 = (void *)(0UL), /* 71 Reserved */ | ||
| 356 | .pvReserved72 = (void *)(0UL), /* 72 Reserved */ | ||
| 357 | .pvReserved73 = (void *)(0UL), /* 73 Reserved */ | ||
| 358 | #endif | ||
| 359 | #ifdef ID_SERCOM7 | ||
| 360 | .pfnSERCOM7_0_Handler = (void *)SERCOM7_0_Handler, /* 74 SERCOM7_0 */ | ||
| 361 | .pfnSERCOM7_1_Handler = (void *)SERCOM7_1_Handler, /* 75 SERCOM7_1 */ | ||
| 362 | .pfnSERCOM7_2_Handler = (void *)SERCOM7_2_Handler, /* 76 SERCOM7_2 */ | ||
| 363 | .pfnSERCOM7_3_Handler = (void *)SERCOM7_3_Handler, /* 77 SERCOM7_3, SERCOM7_4, SERCOM7_5, SERCOM7_6 */ | ||
| 364 | #else | ||
| 365 | .pvReserved74 = (void *)(0UL), /* 74 Reserved */ | ||
| 366 | .pvReserved75 = (void *)(0UL), /* 75 Reserved */ | ||
| 367 | .pvReserved76 = (void *)(0UL), /* 76 Reserved */ | ||
| 368 | .pvReserved77 = (void *)(0UL), /* 77 Reserved */ | ||
| 369 | #endif | ||
| 370 | #ifdef ID_CAN0 | ||
| 371 | .pfnCAN0_Handler = (void *)CAN0_Handler, /* 78 Control Area Network 0 */ | ||
| 372 | #else | ||
| 373 | .pvReserved78 = (void *)(0UL), /* 78 Reserved */ | ||
| 374 | #endif | ||
| 375 | #ifdef ID_CAN1 | ||
| 376 | .pfnCAN1_Handler = (void *)CAN1_Handler, /* 79 Control Area Network 1 */ | ||
| 377 | #else | ||
| 378 | .pvReserved79 = (void *)(0UL), /* 79 Reserved */ | ||
| 379 | #endif | ||
| 380 | #ifdef ID_USB | ||
| 381 | .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 */ | ||
| 382 | .pfnUSB_1_Handler = (void *)USB_1_Handler, /* 81 USB_SOF_HSOF */ | ||
| 383 | .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 */ | ||
| 384 | .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 */ | ||
| 385 | #else | ||
| 386 | .pvReserved80 = (void *)(0UL), /* 80 Reserved */ | ||
| 387 | .pvReserved81 = (void *)(0UL), /* 81 Reserved */ | ||
| 388 | .pvReserved82 = (void *)(0UL), /* 82 Reserved */ | ||
| 389 | .pvReserved83 = (void *)(0UL), /* 83 Reserved */ | ||
| 390 | #endif | ||
| 391 | #ifdef ID_GMAC | ||
| 392 | .pfnGMAC_Handler = (void *)GMAC_Handler, /* 84 Ethernet MAC */ | ||
| 393 | #else | ||
| 394 | .pvReserved84 = (void *)(0UL), /* 84 Reserved */ | ||
| 395 | #endif | ||
| 396 | .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 */ | ||
| 397 | .pfnTCC0_1_Handler = (void *)TCC0_1_Handler, /* 86 TCC0_MC_0 */ | ||
| 398 | .pfnTCC0_2_Handler = (void *)TCC0_2_Handler, /* 87 TCC0_MC_1 */ | ||
| 399 | .pfnTCC0_3_Handler = (void *)TCC0_3_Handler, /* 88 TCC0_MC_2 */ | ||
| 400 | .pfnTCC0_4_Handler = (void *)TCC0_4_Handler, /* 89 TCC0_MC_3 */ | ||
| 401 | .pfnTCC0_5_Handler = (void *)TCC0_5_Handler, /* 90 TCC0_MC_4 */ | ||
| 402 | .pfnTCC0_6_Handler = (void *)TCC0_6_Handler, /* 91 TCC0_MC_5 */ | ||
| 403 | .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 */ | ||
| 404 | .pfnTCC1_1_Handler = (void *)TCC1_1_Handler, /* 93 TCC1_MC_0 */ | ||
| 405 | .pfnTCC1_2_Handler = (void *)TCC1_2_Handler, /* 94 TCC1_MC_1 */ | ||
| 406 | .pfnTCC1_3_Handler = (void *)TCC1_3_Handler, /* 95 TCC1_MC_2 */ | ||
| 407 | .pfnTCC1_4_Handler = (void *)TCC1_4_Handler, /* 96 TCC1_MC_3 */ | ||
| 408 | .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 */ | ||
| 409 | .pfnTCC2_1_Handler = (void *)TCC2_1_Handler, /* 98 TCC2_MC_0 */ | ||
| 410 | .pfnTCC2_2_Handler = (void *)TCC2_2_Handler, /* 99 TCC2_MC_1 */ | ||
| 411 | .pfnTCC2_3_Handler = (void *)TCC2_3_Handler, /* 100 TCC2_MC_2 */ | ||
| 412 | #ifdef ID_TCC3 | ||
| 413 | .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 */ | ||
| 414 | .pfnTCC3_1_Handler = (void *)TCC3_1_Handler, /* 102 TCC3_MC_0 */ | ||
| 415 | .pfnTCC3_2_Handler = (void *)TCC3_2_Handler, /* 103 TCC3_MC_1 */ | ||
| 416 | #else | ||
| 417 | .pvReserved101 = (void *)(0UL), /* 101 Reserved */ | ||
| 418 | .pvReserved102 = (void *)(0UL), /* 102 Reserved */ | ||
| 419 | .pvReserved103 = (void *)(0UL), /* 103 Reserved */ | ||
| 420 | #endif | ||
| 421 | #ifdef ID_TCC4 | ||
| 422 | .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 */ | ||
| 423 | .pfnTCC4_1_Handler = (void *)TCC4_1_Handler, /* 105 TCC4_MC_0 */ | ||
| 424 | .pfnTCC4_2_Handler = (void *)TCC4_2_Handler, /* 106 TCC4_MC_1 */ | ||
| 425 | #else | ||
| 426 | .pvReserved104 = (void *)(0UL), /* 104 Reserved */ | ||
| 427 | .pvReserved105 = (void *)(0UL), /* 105 Reserved */ | ||
| 428 | .pvReserved106 = (void *)(0UL), /* 106 Reserved */ | ||
| 429 | #endif | ||
| 430 | .pfnTC0_Handler = (void *)TC0_Handler, /* 107 Basic Timer Counter 0 */ | ||
| 431 | .pfnTC1_Handler = (void *)TC1_Handler, /* 108 Basic Timer Counter 1 */ | ||
| 432 | .pfnTC2_Handler = (void *)TC2_Handler, /* 109 Basic Timer Counter 2 */ | ||
| 433 | .pfnTC3_Handler = (void *)TC3_Handler, /* 110 Basic Timer Counter 3 */ | ||
| 434 | #ifdef ID_TC4 | ||
| 435 | .pfnTC4_Handler = (void *)TC4_Handler, /* 111 Basic Timer Counter 4 */ | ||
| 436 | #else | ||
| 437 | .pvReserved111 = (void *)(0UL), /* 111 Reserved */ | ||
| 438 | #endif | ||
| 439 | #ifdef ID_TC5 | ||
| 440 | .pfnTC5_Handler = (void *)TC5_Handler, /* 112 Basic Timer Counter 5 */ | ||
| 441 | #else | ||
| 442 | .pvReserved112 = (void *)(0UL), /* 112 Reserved */ | ||
| 443 | #endif | ||
| 444 | #ifdef ID_TC6 | ||
| 445 | .pfnTC6_Handler = (void *)TC6_Handler, /* 113 Basic Timer Counter 6 */ | ||
| 446 | #else | ||
| 447 | .pvReserved113 = (void *)(0UL), /* 113 Reserved */ | ||
| 448 | #endif | ||
| 449 | #ifdef ID_TC7 | ||
| 450 | .pfnTC7_Handler = (void *)TC7_Handler, /* 114 Basic Timer Counter 7 */ | ||
| 451 | #else | ||
| 452 | .pvReserved114 = (void *)(0UL), /* 114 Reserved */ | ||
| 453 | #endif | ||
| 454 | .pfnPDEC_0_Handler = (void *)PDEC_0_Handler, /* 115 PDEC_DIR_A, PDEC_ERR_A, PDEC_OVF, PDEC_VLC_A */ | ||
| 455 | .pfnPDEC_1_Handler = (void *)PDEC_1_Handler, /* 116 PDEC_MC_0 */ | ||
| 456 | .pfnPDEC_2_Handler = (void *)PDEC_2_Handler, /* 117 PDEC_MC_1 */ | ||
| 457 | .pfnADC0_0_Handler = (void *)ADC0_0_Handler, /* 118 ADC0_OVERRUN, ADC0_WINMON */ | ||
| 458 | .pfnADC0_1_Handler = (void *)ADC0_1_Handler, /* 119 ADC0_RESRDY */ | ||
| 459 | .pfnADC1_0_Handler = (void *)ADC1_0_Handler, /* 120 ADC1_OVERRUN, ADC1_WINMON */ | ||
| 460 | .pfnADC1_1_Handler = (void *)ADC1_1_Handler, /* 121 ADC1_RESRDY */ | ||
| 461 | .pfnAC_Handler = (void *)AC_Handler, /* 122 Analog Comparators */ | ||
| 462 | .pfnDAC_0_Handler = (void *)DAC_0_Handler, /* 123 DAC_OVERRUN_A_0, DAC_OVERRUN_A_1, DAC_UNDERRUN_A_0, DAC_UNDERRUN_A_1 */ | ||
| 463 | .pfnDAC_1_Handler = (void *)DAC_1_Handler, /* 124 DAC_EMPTY_0 */ | ||
| 464 | .pfnDAC_2_Handler = (void *)DAC_2_Handler, /* 125 DAC_EMPTY_1 */ | ||
| 465 | .pfnDAC_3_Handler = (void *)DAC_3_Handler, /* 126 DAC_RESRDY_0 */ | ||
| 466 | .pfnDAC_4_Handler = (void *)DAC_4_Handler, /* 127 DAC_RESRDY_1 */ | ||
| 467 | #ifdef ID_I2S | ||
| 468 | .pfnI2S_Handler = (void *)I2S_Handler, /* 128 Inter-IC Sound Interface */ | ||
| 469 | #else | ||
| 470 | .pvReserved128 = (void *)(0UL), /* 128 Reserved */ | ||
| 471 | #endif | ||
| 472 | .pfnPCC_Handler = (void *)PCC_Handler, /* 129 Parallel Capture Controller */ | ||
| 473 | .pfnAES_Handler = (void *)AES_Handler, /* 130 Advanced Encryption Standard */ | ||
| 474 | .pfnTRNG_Handler = (void *)TRNG_Handler, /* 131 True Random Generator */ | ||
| 475 | #ifdef ID_ICM | ||
| 476 | .pfnICM_Handler = (void *)ICM_Handler, /* 132 Integrity Check Monitor */ | ||
| 477 | #else | ||
| 478 | .pvReserved132 = (void *)(0UL), /* 132 Reserved */ | ||
| 479 | #endif | ||
| 480 | #ifdef ID_PUKCC | ||
| 481 | .pfnPUKCC_Handler = (void *)PUKCC_Handler, /* 133 PUblic-Key Cryptography Controller */ | ||
| 482 | #else | ||
| 483 | .pvReserved133 = (void *)(0UL), /* 133 Reserved */ | ||
| 484 | #endif | ||
| 485 | .pfnQSPI_Handler = (void *)QSPI_Handler, /* 134 Quad SPI interface */ | ||
| 486 | #ifdef ID_SDHC0 | ||
| 487 | .pfnSDHC0_Handler = (void *)SDHC0_Handler, /* 135 SD/MMC Host Controller 0 */ | ||
| 488 | #else | ||
| 489 | .pvReserved135 = (void *)(0UL), /* 135 Reserved */ | ||
| 490 | #endif | ||
| 491 | #ifdef ID_SDHC1 | ||
| 492 | .pfnSDHC1_Handler = (void *)SDHC1_Handler /* 136 SD/MMC Host Controller 1 */ | ||
| 493 | #else | ||
| 494 | .pvReserved136 = (void *)(0UL) /* 136 Reserved */ | ||
| 495 | #endif | ||
| 496 | }; | ||
| 497 | |||
| 498 | // WARNING: These are only for CTRL bootloader release "v2.18Jun 22 2018 17:28:08" for bootloader_jump support | ||
| 499 | extern uint32_t _eram; | ||
| 500 | #define BOOTLOADER_MAGIC 0x3B9ACA00 | ||
| 501 | #define MAGIC_ADDR (uint32_t *)((intptr_t)(&_eram) - 4) | ||
| 502 | |||
| 503 | /** | ||
| 504 | * \brief This is the code that gets called on processor reset. | ||
| 505 | * To initialize the device, and call the main() routine. | ||
| 506 | */ | ||
| 507 | void Reset_Handler(void) { | ||
| 508 | #ifdef KEYBOARD_massdrop_ctrl | ||
| 509 | /* WARNING: This is only for CTRL bootloader release "v2.18Jun 22 2018 17:28:08" for bootloader_jump support */ | ||
| 510 | if (*MAGIC_ADDR == BOOTLOADER_MAGIC) { | ||
| 511 | /* At this point, the bootloader's memory is initialized properly, so undo the jump to here, then jump back */ | ||
| 512 | *MAGIC_ADDR = 0x00000000; /* Change value to prevent potential bootloader entrance loop */ | ||
| 513 | __set_MSP(0x20008818); /* MSP according to bootloader */ | ||
| 514 | SCB->VTOR = 0x00000000; /* Vector table back to bootloader's */ | ||
| 515 | asm("bx %0" ::"r"(0x00001267)); /* Jump past bootloader RCAUSE check using THUMB */ | ||
| 516 | } | ||
| 517 | #endif | ||
| 518 | uint32_t *pSrc, *pDest; | ||
| 519 | |||
| 520 | /* Initialize the relocate segment */ | ||
| 521 | pSrc = &_etext; | ||
| 522 | pDest = &_srelocate; | ||
| 523 | |||
| 524 | if (pSrc != pDest) { | ||
| 525 | for (; pDest < &_erelocate;) { | ||
| 526 | *pDest++ = *pSrc++; | ||
| 527 | } | ||
| 528 | } | ||
| 529 | |||
| 530 | /* Clear the zero segment */ | ||
| 531 | for (pDest = &_szero; pDest < &_ezero;) { | ||
| 532 | *pDest++ = 0; | ||
| 533 | } | ||
| 534 | |||
| 535 | /* Set the vector table base address */ | ||
| 536 | pSrc = (uint32_t *)&_sfixed; | ||
| 537 | SCB->VTOR = ((uint32_t)pSrc & SCB_VTOR_TBLOFF_Msk); | ||
| 538 | |||
| 539 | #if __FPU_USED | ||
| 540 | /* Enable FPU */ | ||
| 541 | SCB->CPACR |= (0xFu << 20); | ||
| 542 | __DSB(); | ||
| 543 | __ISB(); | ||
| 544 | #endif | ||
| 545 | |||
| 546 | /* Initialize the C library */ | ||
| 547 | __libc_init_array(); | ||
| 548 | |||
| 549 | /* Branch to main function */ | ||
| 550 | main(); | ||
| 551 | |||
| 552 | /* Infinite loop */ | ||
| 553 | while (1) | ||
| 554 | ; | ||
| 555 | } | ||
| 556 | |||
| 557 | /** | ||
| 558 | * \brief Default interrupt handler for unused IRQs. | ||
| 559 | */ | ||
| 560 | void Dummy_Handler(void) { | ||
| 561 | while (1) { | ||
| 562 | } | ||
| 563 | } | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/compiler.h b/tmk_core/protocol/arm_atsam/usb/compiler.h deleted file mode 100644 index 9fb04ff628..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/compiler.h +++ /dev/null | |||
| @@ -1,1079 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief Commonly used includes, types and macros. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2012-2016 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or without | ||
| 11 | * modification, are permitted provided that the following conditions are met: | ||
| 12 | * | ||
| 13 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 14 | * this list of conditions and the following disclaimer. | ||
| 15 | * | ||
| 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 17 | * this list of conditions and the following disclaimer in the documentation | ||
| 18 | * and/or other materials provided with the distribution. | ||
| 19 | * | ||
| 20 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 21 | * from this software without specific prior written permission. | ||
| 22 | * | ||
| 23 | * 4. This software may only be redistributed and used in connection with an | ||
| 24 | * Atmel microcontroller product. | ||
| 25 | * | ||
| 26 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 27 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 28 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 29 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 30 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 34 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 35 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 36 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 37 | * | ||
| 38 | * \asf_license_stop | ||
| 39 | * | ||
| 40 | */ | ||
| 41 | /* | ||
| 42 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 43 | */ | ||
| 44 | |||
| 45 | #ifndef UTILS_COMPILER_H_INCLUDED | ||
| 46 | #define UTILS_COMPILER_H_INCLUDED | ||
| 47 | |||
| 48 | /** | ||
| 49 | * \defgroup group_sam0_utils Compiler abstraction layer and code utilities | ||
| 50 | * | ||
| 51 | * Compiler abstraction layer and code utilities for Cortex-M0+ based Atmel SAM devices. | ||
| 52 | * This module provides various abstraction layers and utilities to make code compatible between different compilers. | ||
| 53 | * | ||
| 54 | * @{ | ||
| 55 | */ | ||
| 56 | |||
| 57 | #if (defined __ICCARM__) | ||
| 58 | # include <intrinsics.h> | ||
| 59 | #endif | ||
| 60 | |||
| 61 | #include <stddef.h> | ||
| 62 | //#include <parts.h> | ||
| 63 | //#include <status_codes.h> | ||
| 64 | //#include <preprocessor.h> | ||
| 65 | //#include <io.h> | ||
| 66 | |||
| 67 | #ifndef __ASSEMBLY__ | ||
| 68 | |||
| 69 | # include <stdio.h> | ||
| 70 | # include <stdbool.h> | ||
| 71 | # include <stdint.h> | ||
| 72 | # include <stdlib.h> | ||
| 73 | |||
| 74 | /** | ||
| 75 | * \def UNUSED | ||
| 76 | * \brief Marking \a v as a unused parameter or value. | ||
| 77 | */ | ||
| 78 | # define UNUSED(v) (void)(v) | ||
| 79 | |||
| 80 | /** | ||
| 81 | * \def barrier | ||
| 82 | * \brief Memory barrier | ||
| 83 | */ | ||
| 84 | # ifdef __GNUC__ | ||
| 85 | # define barrier() asm volatile("" ::: "memory") | ||
| 86 | # else | ||
| 87 | # define barrier() asm("") | ||
| 88 | # endif | ||
| 89 | |||
| 90 | /** | ||
| 91 | * \brief Emit the compiler pragma \a arg. | ||
| 92 | * | ||
| 93 | * \param[in] arg The pragma directive as it would appear after \e \#pragma | ||
| 94 | * (i.e. not stringified). | ||
| 95 | */ | ||
| 96 | # define COMPILER_PRAGMA(arg) _Pragma(# arg) | ||
| 97 | |||
| 98 | /** | ||
| 99 | * \def COMPILER_PACK_SET(alignment) | ||
| 100 | * \brief Set maximum alignment for subsequent struct and union definitions to \a alignment. | ||
| 101 | */ | ||
| 102 | # define COMPILER_PACK_SET(alignment) COMPILER_PRAGMA(pack(alignment)) | ||
| 103 | |||
| 104 | /** | ||
| 105 | * \def COMPILER_PACK_RESET() | ||
| 106 | * \brief Set default alignment for subsequent struct and union definitions. | ||
| 107 | */ | ||
| 108 | # define COMPILER_PACK_RESET() COMPILER_PRAGMA(pack()) | ||
| 109 | |||
| 110 | /** | ||
| 111 | * \brief Set aligned boundary. | ||
| 112 | */ | ||
| 113 | # if (defined __GNUC__) || (defined __CC_ARM) | ||
| 114 | # define COMPILER_ALIGNED(a) __attribute__((__aligned__(a))) | ||
| 115 | # elif (defined __ICCARM__) | ||
| 116 | # define COMPILER_ALIGNED(a) COMPILER_PRAGMA(data_alignment = a) | ||
| 117 | # endif | ||
| 118 | |||
| 119 | /** | ||
| 120 | * \brief Set word-aligned boundary. | ||
| 121 | */ | ||
| 122 | # if (defined __GNUC__) || defined(__CC_ARM) | ||
| 123 | # define COMPILER_WORD_ALIGNED __attribute__((__aligned__(4))) | ||
| 124 | # elif (defined __ICCARM__) | ||
| 125 | # define COMPILER_WORD_ALIGNED COMPILER_PRAGMA(data_alignment = 4) | ||
| 126 | # endif | ||
| 127 | |||
| 128 | /** | ||
| 129 | * \def __always_inline | ||
| 130 | * \brief The function should always be inlined. | ||
| 131 | * | ||
| 132 | * This annotation instructs the compiler to ignore its inlining | ||
| 133 | * heuristics and inline the function no matter how big it thinks it | ||
| 134 | * becomes. | ||
| 135 | */ | ||
| 136 | # if !defined(__always_inline) | ||
| 137 | # if defined(__CC_ARM) | ||
| 138 | # define __always_inline __forceinline | ||
| 139 | # elif (defined __GNUC__) | ||
| 140 | # define __always_inline __attribute__((__always_inline__)) | ||
| 141 | # elif (defined __ICCARM__) | ||
| 142 | # define __always_inline _Pragma("inline=forced") | ||
| 143 | # endif | ||
| 144 | # endif | ||
| 145 | |||
| 146 | /** | ||
| 147 | * \def __no_inline | ||
| 148 | * \brief The function should never be inlined | ||
| 149 | * | ||
| 150 | * This annotation instructs the compiler to ignore its inlining | ||
| 151 | * heuristics and not inline the function no matter how small it thinks it | ||
| 152 | * becomes. | ||
| 153 | */ | ||
| 154 | # if defined(__CC_ARM) | ||
| 155 | # define __no_inline __attribute__((noinline)) | ||
| 156 | # elif (defined __GNUC__) | ||
| 157 | # define __no_inline __attribute__((noinline)) | ||
| 158 | # elif (defined __ICCARM__) | ||
| 159 | # define __no_inline _Pragma("inline=never") | ||
| 160 | # endif | ||
| 161 | |||
| 162 | /** \brief This macro is used to test fatal errors. | ||
| 163 | * | ||
| 164 | * The macro tests if the expression is false. If it is, a fatal error is | ||
| 165 | * detected and the application hangs up. If \c TEST_SUITE_DEFINE_ASSERT_MACRO | ||
| 166 | * is defined, a unit test version of the macro is used, to allow execution | ||
| 167 | * of further tests after a false expression. | ||
| 168 | * | ||
| 169 | * \param[in] expr Expression to evaluate and supposed to be nonzero. | ||
| 170 | */ | ||
| 171 | # if defined(_ASSERT_ENABLE_) | ||
| 172 | # if defined(TEST_SUITE_DEFINE_ASSERT_MACRO) | ||
| 173 | # include "unit_test/suite.h" | ||
| 174 | # else | ||
| 175 | # undef TEST_SUITE_DEFINE_ASSERT_MACRO | ||
| 176 | # define Assert(expr) \ | ||
| 177 | { \ | ||
| 178 | if (!(expr)) asm("BKPT #0"); \ | ||
| 179 | } | ||
| 180 | # endif | ||
| 181 | # else | ||
| 182 | # define Assert(expr) ((void)0) | ||
| 183 | # endif | ||
| 184 | |||
| 185 | /* Define WEAK attribute */ | ||
| 186 | # if defined(__CC_ARM) | ||
| 187 | # define WEAK __attribute__((weak)) | ||
| 188 | # elif defined(__ICCARM__) | ||
| 189 | # define WEAK __weak | ||
| 190 | # elif defined(__GNUC__) | ||
| 191 | # define WEAK __attribute__((weak)) | ||
| 192 | # endif | ||
| 193 | |||
| 194 | /* Define NO_INIT attribute */ | ||
| 195 | # if defined(__CC_ARM) | ||
| 196 | # define NO_INIT __attribute__((zero_init)) | ||
| 197 | # elif defined(__ICCARM__) | ||
| 198 | # define NO_INIT __no_init | ||
| 199 | # elif defined(__GNUC__) | ||
| 200 | # define NO_INIT __attribute__((section(".no_init"))) | ||
| 201 | # endif | ||
| 202 | |||
| 203 | //#include "interrupt.h" | ||
| 204 | |||
| 205 | /** \name Usual Types | ||
| 206 | * @{ */ | ||
| 207 | # ifndef __cplusplus | ||
| 208 | # if !defined(__bool_true_false_are_defined) | ||
| 209 | typedef unsigned char bool; | ||
| 210 | # endif | ||
| 211 | # endif | ||
| 212 | typedef uint16_t le16_t; | ||
| 213 | typedef uint16_t be16_t; | ||
| 214 | typedef uint32_t le32_t; | ||
| 215 | typedef uint32_t be32_t; | ||
| 216 | typedef uint32_t iram_size_t; | ||
| 217 | /** @} */ | ||
| 218 | |||
| 219 | /** \name Aliasing Aggregate Types | ||
| 220 | * @{ */ | ||
| 221 | |||
| 222 | /** 16-bit union. */ | ||
| 223 | typedef union { | ||
| 224 | int16_t s16; | ||
| 225 | uint16_t u16; | ||
| 226 | int8_t s8[2]; | ||
| 227 | uint8_t u8[2]; | ||
| 228 | } Union16; | ||
| 229 | |||
| 230 | /** 32-bit union. */ | ||
| 231 | typedef union { | ||
| 232 | int32_t s32; | ||
| 233 | uint32_t u32; | ||
| 234 | int16_t s16[2]; | ||
| 235 | uint16_t u16[2]; | ||
| 236 | int8_t s8[4]; | ||
| 237 | uint8_t u8[4]; | ||
| 238 | } Union32; | ||
| 239 | |||
| 240 | /** 64-bit union. */ | ||
| 241 | typedef union { | ||
| 242 | int64_t s64; | ||
| 243 | uint64_t u64; | ||
| 244 | int32_t s32[2]; | ||
| 245 | uint32_t u32[2]; | ||
| 246 | int16_t s16[4]; | ||
| 247 | uint16_t u16[4]; | ||
| 248 | int8_t s8[8]; | ||
| 249 | uint8_t u8[8]; | ||
| 250 | } Union64; | ||
| 251 | |||
| 252 | /** Union of pointers to 64-, 32-, 16- and 8-bit unsigned integers. */ | ||
| 253 | typedef union { | ||
| 254 | int64_t * s64ptr; | ||
| 255 | uint64_t *u64ptr; | ||
| 256 | int32_t * s32ptr; | ||
| 257 | uint32_t *u32ptr; | ||
| 258 | int16_t * s16ptr; | ||
| 259 | uint16_t *u16ptr; | ||
| 260 | int8_t * s8ptr; | ||
| 261 | uint8_t * u8ptr; | ||
| 262 | } UnionPtr; | ||
| 263 | |||
| 264 | /** Union of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers. */ | ||
| 265 | typedef union { | ||
| 266 | volatile int64_t * s64ptr; | ||
| 267 | volatile uint64_t *u64ptr; | ||
| 268 | volatile int32_t * s32ptr; | ||
| 269 | volatile uint32_t *u32ptr; | ||
| 270 | volatile int16_t * s16ptr; | ||
| 271 | volatile uint16_t *u16ptr; | ||
| 272 | volatile int8_t * s8ptr; | ||
| 273 | volatile uint8_t * u8ptr; | ||
| 274 | } UnionVPtr; | ||
| 275 | |||
| 276 | /** Union of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers. */ | ||
| 277 | typedef union { | ||
| 278 | const int64_t * s64ptr; | ||
| 279 | const uint64_t *u64ptr; | ||
| 280 | const int32_t * s32ptr; | ||
| 281 | const uint32_t *u32ptr; | ||
| 282 | const int16_t * s16ptr; | ||
| 283 | const uint16_t *u16ptr; | ||
| 284 | const int8_t * s8ptr; | ||
| 285 | const uint8_t * u8ptr; | ||
| 286 | } UnionCPtr; | ||
| 287 | |||
| 288 | /** Union of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers. */ | ||
| 289 | typedef union { | ||
| 290 | const volatile int64_t * s64ptr; | ||
| 291 | const volatile uint64_t *u64ptr; | ||
| 292 | const volatile int32_t * s32ptr; | ||
| 293 | const volatile uint32_t *u32ptr; | ||
| 294 | const volatile int16_t * s16ptr; | ||
| 295 | const volatile uint16_t *u16ptr; | ||
| 296 | const volatile int8_t * s8ptr; | ||
| 297 | const volatile uint8_t * u8ptr; | ||
| 298 | } UnionCVPtr; | ||
| 299 | |||
| 300 | /** Structure of pointers to 64-, 32-, 16- and 8-bit unsigned integers. */ | ||
| 301 | typedef struct { | ||
| 302 | int64_t * s64ptr; | ||
| 303 | uint64_t *u64ptr; | ||
| 304 | int32_t * s32ptr; | ||
| 305 | uint32_t *u32ptr; | ||
| 306 | int16_t * s16ptr; | ||
| 307 | uint16_t *u16ptr; | ||
| 308 | int8_t * s8ptr; | ||
| 309 | uint8_t * u8ptr; | ||
| 310 | } StructPtr; | ||
| 311 | |||
| 312 | /** Structure of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers. */ | ||
| 313 | typedef struct { | ||
| 314 | volatile int64_t * s64ptr; | ||
| 315 | volatile uint64_t *u64ptr; | ||
| 316 | volatile int32_t * s32ptr; | ||
| 317 | volatile uint32_t *u32ptr; | ||
| 318 | volatile int16_t * s16ptr; | ||
| 319 | volatile uint16_t *u16ptr; | ||
| 320 | volatile int8_t * s8ptr; | ||
| 321 | volatile uint8_t * u8ptr; | ||
| 322 | } StructVPtr; | ||
| 323 | |||
| 324 | /** Structure of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers. */ | ||
| 325 | typedef struct { | ||
| 326 | const int64_t * s64ptr; | ||
| 327 | const uint64_t *u64ptr; | ||
| 328 | const int32_t * s32ptr; | ||
| 329 | const uint32_t *u32ptr; | ||
| 330 | const int16_t * s16ptr; | ||
| 331 | const uint16_t *u16ptr; | ||
| 332 | const int8_t * s8ptr; | ||
| 333 | const uint8_t * u8ptr; | ||
| 334 | } StructCPtr; | ||
| 335 | |||
| 336 | /** Structure of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers. */ | ||
| 337 | typedef struct { | ||
| 338 | const volatile int64_t * s64ptr; | ||
| 339 | const volatile uint64_t *u64ptr; | ||
| 340 | const volatile int32_t * s32ptr; | ||
| 341 | const volatile uint32_t *u32ptr; | ||
| 342 | const volatile int16_t * s16ptr; | ||
| 343 | const volatile uint16_t *u16ptr; | ||
| 344 | const volatile int8_t * s8ptr; | ||
| 345 | const volatile uint8_t * u8ptr; | ||
| 346 | } StructCVPtr; | ||
| 347 | |||
| 348 | /** @} */ | ||
| 349 | |||
| 350 | #endif /* #ifndef __ASSEMBLY__ */ | ||
| 351 | |||
| 352 | /** \name Usual Constants | ||
| 353 | * @{ */ | ||
| 354 | // kmod #define DISABLE 0 | ||
| 355 | // kmod #define ENABLE 1 | ||
| 356 | |||
| 357 | #ifndef __cplusplus | ||
| 358 | # if !defined(__bool_true_false_are_defined) | ||
| 359 | # define false 0 | ||
| 360 | # define true 1 | ||
| 361 | # endif | ||
| 362 | #endif | ||
| 363 | /** @} */ | ||
| 364 | |||
| 365 | #ifndef __ASSEMBLY__ | ||
| 366 | |||
| 367 | /** \name Optimization Control | ||
| 368 | * @{ */ | ||
| 369 | |||
| 370 | /** | ||
| 371 | * \def likely(exp) | ||
| 372 | * \brief The expression \a exp is likely to be true | ||
| 373 | */ | ||
| 374 | # if !defined(likely) || defined(__DOXYGEN__) | ||
| 375 | # define likely(exp) (exp) | ||
| 376 | # endif | ||
| 377 | |||
| 378 | /** | ||
| 379 | * \def unlikely(exp) | ||
| 380 | * \brief The expression \a exp is unlikely to be true | ||
| 381 | */ | ||
| 382 | # if !defined(unlikely) || defined(__DOXYGEN__) | ||
| 383 | # define unlikely(exp) (exp) | ||
| 384 | # endif | ||
| 385 | |||
| 386 | /** | ||
| 387 | * \def is_constant(exp) | ||
| 388 | * \brief Determine if an expression evaluates to a constant value. | ||
| 389 | * | ||
| 390 | * \param[in] exp Any expression | ||
| 391 | * | ||
| 392 | * \return true if \a exp is constant, false otherwise. | ||
| 393 | */ | ||
| 394 | # if (defined __GNUC__) || (defined __CC_ARM) | ||
| 395 | # define is_constant(exp) __builtin_constant_p(exp) | ||
| 396 | # else | ||
| 397 | # define is_constant(exp) (0) | ||
| 398 | # endif | ||
| 399 | |||
| 400 | /** @} */ | ||
| 401 | |||
| 402 | /** \name Bit-Field Handling | ||
| 403 | * @{ */ | ||
| 404 | |||
| 405 | /** \brief Reads the bits of a value specified by a given bit-mask. | ||
| 406 | * | ||
| 407 | * \param[in] value Value to read bits from. | ||
| 408 | * \param[in] mask Bit-mask indicating bits to read. | ||
| 409 | * | ||
| 410 | * \return Read bits. | ||
| 411 | */ | ||
| 412 | # define Rd_bits(value, mask) ((value) & (mask)) | ||
| 413 | |||
| 414 | /** \brief Writes the bits of a C lvalue specified by a given bit-mask. | ||
| 415 | * | ||
| 416 | * \param[in] lvalue C lvalue to write bits to. | ||
| 417 | * \param[in] mask Bit-mask indicating bits to write. | ||
| 418 | * \param[in] bits Bits to write. | ||
| 419 | * | ||
| 420 | * \return Resulting value with written bits. | ||
| 421 | */ | ||
| 422 | # define Wr_bits(lvalue, mask, bits) ((lvalue) = ((lvalue) & ~(mask)) | ((bits) & (mask))) | ||
| 423 | |||
| 424 | /** \brief Tests the bits of a value specified by a given bit-mask. | ||
| 425 | * | ||
| 426 | * \param[in] value Value of which to test bits. | ||
| 427 | * \param[in] mask Bit-mask indicating bits to test. | ||
| 428 | * | ||
| 429 | * \return \c 1 if at least one of the tested bits is set, else \c 0. | ||
| 430 | */ | ||
| 431 | # define Tst_bits(value, mask) (Rd_bits(value, mask) != 0) | ||
| 432 | |||
| 433 | /** \brief Clears the bits of a C lvalue specified by a given bit-mask. | ||
| 434 | * | ||
| 435 | * \param[in] lvalue C lvalue of which to clear bits. | ||
| 436 | * \param[in] mask Bit-mask indicating bits to clear. | ||
| 437 | * | ||
| 438 | * \return Resulting value with cleared bits. | ||
| 439 | */ | ||
| 440 | # define Clr_bits(lvalue, mask) ((lvalue) &= ~(mask)) | ||
| 441 | |||
| 442 | /** \brief Sets the bits of a C lvalue specified by a given bit-mask. | ||
| 443 | * | ||
| 444 | * \param[in] lvalue C lvalue of which to set bits. | ||
| 445 | * \param[in] mask Bit-mask indicating bits to set. | ||
| 446 | * | ||
| 447 | * \return Resulting value with set bits. | ||
| 448 | */ | ||
| 449 | # define Set_bits(lvalue, mask) ((lvalue) |= (mask)) | ||
| 450 | |||
| 451 | /** \brief Toggles the bits of a C lvalue specified by a given bit-mask. | ||
| 452 | * | ||
| 453 | * \param[in] lvalue C lvalue of which to toggle bits. | ||
| 454 | * \param[in] mask Bit-mask indicating bits to toggle. | ||
| 455 | * | ||
| 456 | * \return Resulting value with toggled bits. | ||
| 457 | */ | ||
| 458 | # define Tgl_bits(lvalue, mask) ((lvalue) ^= (mask)) | ||
| 459 | |||
| 460 | /** \brief Reads the bit-field of a value specified by a given bit-mask. | ||
| 461 | * | ||
| 462 | * \param[in] value Value to read a bit-field from. | ||
| 463 | * \param[in] mask Bit-mask indicating the bit-field to read. | ||
| 464 | * | ||
| 465 | * \return Read bit-field. | ||
| 466 | */ | ||
| 467 | # define Rd_bitfield(value, mask) (Rd_bits(value, mask) >> ctz(mask)) | ||
| 468 | |||
| 469 | /** \brief Writes the bit-field of a C lvalue specified by a given bit-mask. | ||
| 470 | * | ||
| 471 | * \param[in] lvalue C lvalue to write a bit-field to. | ||
| 472 | * \param[in] mask Bit-mask indicating the bit-field to write. | ||
| 473 | * \param[in] bitfield Bit-field to write. | ||
| 474 | * | ||
| 475 | * \return Resulting value with written bit-field. | ||
| 476 | */ | ||
| 477 | # define Wr_bitfield(lvalue, mask, bitfield) (Wr_bits(lvalue, mask, (uint32_t)(bitfield) << ctz(mask))) | ||
| 478 | |||
| 479 | /** @} */ | ||
| 480 | |||
| 481 | /** \name Zero-Bit Counting | ||
| 482 | * | ||
| 483 | * Under GCC, __builtin_clz and __builtin_ctz behave like macros when | ||
| 484 | * applied to constant expressions (values known at compile time), so they are | ||
| 485 | * more optimized than the use of the corresponding assembly instructions and | ||
| 486 | * they can be used as constant expressions e.g. to initialize objects having | ||
| 487 | * static storage duration, and like the corresponding assembly instructions | ||
| 488 | * when applied to non-constant expressions (values unknown at compile time), so | ||
| 489 | * they are more optimized than an assembly periphrasis. Hence, clz and ctz | ||
| 490 | * ensure a possible and optimized behavior for both constant and non-constant | ||
| 491 | * expressions. | ||
| 492 | * | ||
| 493 | * @{ */ | ||
| 494 | |||
| 495 | /** \brief Counts the leading zero bits of the given value considered as a 32-bit integer. | ||
| 496 | * | ||
| 497 | * \param[in] u Value of which to count the leading zero bits. | ||
| 498 | * | ||
| 499 | * \return The count of leading zero bits in \a u. | ||
| 500 | */ | ||
| 501 | # if (defined __GNUC__) || (defined __CC_ARM) | ||
| 502 | # define clz(u) ((u) ? __builtin_clz(u) : 32) | ||
| 503 | # else | ||
| 504 | # define clz(u) (((u) == 0) ? 32 : ((u) & (1ul << 31)) ? 0 : ((u) & (1ul << 30)) ? 1 : ((u) & (1ul << 29)) ? 2 : ((u) & (1ul << 28)) ? 3 : ((u) & (1ul << 27)) ? 4 : ((u) & (1ul << 26)) ? 5 : ((u) & (1ul << 25)) ? 6 : ((u) & (1ul << 24)) ? 7 : ((u) & (1ul << 23)) ? 8 : ((u) & (1ul << 22)) ? 9 : ((u) & (1ul << 21)) ? 10 : ((u) & (1ul << 20)) ? 11 : ((u) & (1ul << 19)) ? 12 : ((u) & (1ul << 18)) ? 13 : ((u) & (1ul << 17)) ? 14 : ((u) & (1ul << 16)) ? 15 : ((u) & (1ul << 15)) ? 16 : ((u) & (1ul << 14)) ? 17 : ((u) & (1ul << 13)) ? 18 : ((u) & (1ul << 12)) ? 19 : ((u) & (1ul << 11)) ? 20 : ((u) & (1ul << 10)) ? 21 : ((u) & (1ul << 9)) ? 22 : ((u) & (1ul << 8)) ? 23 : ((u) & (1ul << 7)) ? 24 : ((u) & (1ul << 6)) ? 25 : ((u) & (1ul << 5)) ? 26 : ((u) & (1ul << 4)) ? 27 : ((u) & (1ul << 3)) ? 28 : ((u) & (1ul << 2)) ? 29 : ((u) & (1ul << 1)) ? 30 : 31) | ||
| 505 | # endif | ||
| 506 | |||
| 507 | /** \brief Counts the trailing zero bits of the given value considered as a 32-bit integer. | ||
| 508 | * | ||
| 509 | * \param[in] u Value of which to count the trailing zero bits. | ||
| 510 | * | ||
| 511 | * \return The count of trailing zero bits in \a u. | ||
| 512 | */ | ||
| 513 | # if (defined __GNUC__) || (defined __CC_ARM) | ||
| 514 | # define ctz(u) ((u) ? __builtin_ctz(u) : 32) | ||
| 515 | # else | ||
| 516 | # define ctz(u) ((u) & (1ul << 0) ? 0 : (u) & (1ul << 1) ? 1 : (u) & (1ul << 2) ? 2 : (u) & (1ul << 3) ? 3 : (u) & (1ul << 4) ? 4 : (u) & (1ul << 5) ? 5 : (u) & (1ul << 6) ? 6 : (u) & (1ul << 7) ? 7 : (u) & (1ul << 8) ? 8 : (u) & (1ul << 9) ? 9 : (u) & (1ul << 10) ? 10 : (u) & (1ul << 11) ? 11 : (u) & (1ul << 12) ? 12 : (u) & (1ul << 13) ? 13 : (u) & (1ul << 14) ? 14 : (u) & (1ul << 15) ? 15 : (u) & (1ul << 16) ? 16 : (u) & (1ul << 17) ? 17 : (u) & (1ul << 18) ? 18 : (u) & (1ul << 19) ? 19 : (u) & (1ul << 20) ? 20 : (u) & (1ul << 21) ? 21 : (u) & (1ul << 22) ? 22 : (u) & (1ul << 23) ? 23 : (u) & (1ul << 24) ? 24 : (u) & (1ul << 25) ? 25 : (u) & (1ul << 26) ? 26 : (u) & (1ul << 27) ? 27 : (u) & (1ul << 28) ? 28 : (u) & (1ul << 29) ? 29 : (u) & (1ul << 30) ? 30 : (u) & (1ul << 31) ? 31 : 32) | ||
| 517 | # endif | ||
| 518 | |||
| 519 | /** @} */ | ||
| 520 | |||
| 521 | /** \name Bit Reversing | ||
| 522 | * @{ */ | ||
| 523 | |||
| 524 | /** \brief Reverses the bits of \a u8. | ||
| 525 | * | ||
| 526 | * \param[in] u8 U8 of which to reverse the bits. | ||
| 527 | * | ||
| 528 | * \return Value resulting from \a u8 with reversed bits. | ||
| 529 | */ | ||
| 530 | # define bit_reverse8(u8) ((U8)(bit_reverse32((U8)(u8)) >> 24)) | ||
| 531 | |||
| 532 | /** \brief Reverses the bits of \a u16. | ||
| 533 | * | ||
| 534 | * \param[in] u16 U16 of which to reverse the bits. | ||
| 535 | * | ||
| 536 | * \return Value resulting from \a u16 with reversed bits. | ||
| 537 | */ | ||
| 538 | # define bit_reverse16(u16) ((uint16_t)(bit_reverse32((uint16_t)(u16)) >> 16)) | ||
| 539 | |||
| 540 | /** \brief Reverses the bits of \a u32. | ||
| 541 | * | ||
| 542 | * \param[in] u32 U32 of which to reverse the bits. | ||
| 543 | * | ||
| 544 | * \return Value resulting from \a u32 with reversed bits. | ||
| 545 | */ | ||
| 546 | # define bit_reverse32(u32) __RBIT(u32) | ||
| 547 | |||
| 548 | /** \brief Reverses the bits of \a u64. | ||
| 549 | * | ||
| 550 | * \param[in] u64 U64 of which to reverse the bits. | ||
| 551 | * | ||
| 552 | * \return Value resulting from \a u64 with reversed bits. | ||
| 553 | */ | ||
| 554 | # define bit_reverse64(u64) ((uint64_t)(((uint64_t)bit_reverse32((uint64_t)(u64) >> 32)) | ((uint64_t)bit_reverse32((uint64_t)(u64)) << 32))) | ||
| 555 | |||
| 556 | /** @} */ | ||
| 557 | |||
| 558 | /** \name Alignment | ||
| 559 | * @{ */ | ||
| 560 | |||
| 561 | /** \brief Tests alignment of the number \a val with the \a n boundary. | ||
| 562 | * | ||
| 563 | * \param[in] val Input value. | ||
| 564 | * \param[in] n Boundary. | ||
| 565 | * | ||
| 566 | * \return \c 1 if the number \a val is aligned with the \a n boundary, else \c 0. | ||
| 567 | */ | ||
| 568 | # define Test_align(val, n) (!Tst_bits(val, (n)-1)) | ||
| 569 | |||
| 570 | /** \brief Gets alignment of the number \a val with respect to the \a n boundary. | ||
| 571 | * | ||
| 572 | * \param[in] val Input value. | ||
| 573 | * \param[in] n Boundary. | ||
| 574 | * | ||
| 575 | * \return Alignment of the number \a val with respect to the \a n boundary. | ||
| 576 | */ | ||
| 577 | # define Get_align(val, n) (Rd_bits(val, (n)-1)) | ||
| 578 | |||
| 579 | /** \brief Sets alignment of the lvalue number \a lval to \a alg with respect to the \a n boundary. | ||
| 580 | * | ||
| 581 | * \param[in] lval Input/output lvalue. | ||
| 582 | * \param[in] n Boundary. | ||
| 583 | * \param[in] alg Alignment. | ||
| 584 | * | ||
| 585 | * \return New value of \a lval resulting from its alignment set to \a alg with respect to the \a n boundary. | ||
| 586 | */ | ||
| 587 | # define Set_align(lval, n, alg) (Wr_bits(lval, (n)-1, alg)) | ||
| 588 | |||
| 589 | /** \brief Aligns the number \a val with the upper \a n boundary. | ||
| 590 | * | ||
| 591 | * \param[in] val Input value. | ||
| 592 | * \param[in] n Boundary. | ||
| 593 | * | ||
| 594 | * \return Value resulting from the number \a val aligned with the upper \a n boundary. | ||
| 595 | */ | ||
| 596 | # define Align_up(val, n) (((val) + ((n)-1)) & ~((n)-1)) | ||
| 597 | |||
| 598 | /** \brief Aligns the number \a val with the lower \a n boundary. | ||
| 599 | * | ||
| 600 | * \param[in] val Input value. | ||
| 601 | * \param[in] n Boundary. | ||
| 602 | * | ||
| 603 | * \return Value resulting from the number \a val aligned with the lower \a n boundary. | ||
| 604 | */ | ||
| 605 | # define Align_down(val, n) ((val) & ~((n)-1)) | ||
| 606 | |||
| 607 | /** @} */ | ||
| 608 | |||
| 609 | /** \name Mathematics | ||
| 610 | * | ||
| 611 | * The same considerations as for clz and ctz apply here but GCC does not | ||
| 612 | * provide built-in functions to access the assembly instructions abs, min and | ||
| 613 | * max and it does not produce them by itself in most cases, so two sets of | ||
| 614 | * macros are defined here: | ||
| 615 | * - Abs, Min and Max to apply to constant expressions (values known at | ||
| 616 | * compile time); | ||
| 617 | * - abs, min and max to apply to non-constant expressions (values unknown at | ||
| 618 | * compile time), abs is found in stdlib.h. | ||
| 619 | * | ||
| 620 | * @{ */ | ||
| 621 | |||
| 622 | /** \brief Takes the absolute value of \a a. | ||
| 623 | * | ||
| 624 | * \param[in] a Input value. | ||
| 625 | * | ||
| 626 | * \return Absolute value of \a a. | ||
| 627 | * | ||
| 628 | * \note More optimized if only used with values known at compile time. | ||
| 629 | */ | ||
| 630 | # define Abs(a) (((a) < 0) ? -(a) : (a)) | ||
| 631 | |||
| 632 | # ifndef __cplusplus | ||
| 633 | /** \brief Takes the minimal value of \a a and \a b. | ||
| 634 | * | ||
| 635 | * \param[in] a Input value. | ||
| 636 | * \param[in] b Input value. | ||
| 637 | * | ||
| 638 | * \return Minimal value of \a a and \a b. | ||
| 639 | * | ||
| 640 | * \note More optimized if only used with values known at compile time. | ||
| 641 | */ | ||
| 642 | # define Min(a, b) (((a) < (b)) ? (a) : (b)) | ||
| 643 | |||
| 644 | /** \brief Takes the maximal value of \a a and \a b. | ||
| 645 | * | ||
| 646 | * \param[in] a Input value. | ||
| 647 | * \param[in] b Input value. | ||
| 648 | * | ||
| 649 | * \return Maximal value of \a a and \a b. | ||
| 650 | * | ||
| 651 | * \note More optimized if only used with values known at compile time. | ||
| 652 | */ | ||
| 653 | # define Max(a, b) (((a) > (b)) ? (a) : (b)) | ||
| 654 | |||
| 655 | /** \brief Takes the minimal value of \a a and \a b. | ||
| 656 | * | ||
| 657 | * \param[in] a Input value. | ||
| 658 | * \param[in] b Input value. | ||
| 659 | * | ||
| 660 | * \return Minimal value of \a a and \a b. | ||
| 661 | * | ||
| 662 | * \note More optimized if only used with values unknown at compile time. | ||
| 663 | */ | ||
| 664 | # define min(a, b) Min(a, b) | ||
| 665 | |||
| 666 | /** \brief Takes the maximal value of \a a and \a b. | ||
| 667 | * | ||
| 668 | * \param[in] a Input value. | ||
| 669 | * \param[in] b Input value. | ||
| 670 | * | ||
| 671 | * \return Maximal value of \a a and \a b. | ||
| 672 | * | ||
| 673 | * \note More optimized if only used with values unknown at compile time. | ||
| 674 | */ | ||
| 675 | # define max(a, b) Max(a, b) | ||
| 676 | # endif | ||
| 677 | |||
| 678 | /** @} */ | ||
| 679 | |||
| 680 | /** \brief Calls the routine at address \a addr. | ||
| 681 | * | ||
| 682 | * It generates a long call opcode. | ||
| 683 | * | ||
| 684 | * For example, `Long_call(0x80000000)' generates a software reset on a UC3 if | ||
| 685 | * it is invoked from the CPU supervisor mode. | ||
| 686 | * | ||
| 687 | * \param[in] addr Address of the routine to call. | ||
| 688 | * | ||
| 689 | * \note It may be used as a long jump opcode in some special cases. | ||
| 690 | */ | ||
| 691 | # define Long_call(addr) ((*(void (*)(void))(addr))()) | ||
| 692 | |||
| 693 | /** \name MCU Endianism Handling | ||
| 694 | * ARM is MCU little endian. | ||
| 695 | * | ||
| 696 | * @{ */ | ||
| 697 | # define BE16(x) swap16(x) | ||
| 698 | # define LE16(x) (x) | ||
| 699 | |||
| 700 | # define le16_to_cpu(x) (x) | ||
| 701 | # define cpu_to_le16(x) (x) | ||
| 702 | # define LE16_TO_CPU(x) (x) | ||
| 703 | # define CPU_TO_LE16(x) (x) | ||
| 704 | |||
| 705 | # define be16_to_cpu(x) swap16(x) | ||
| 706 | # define cpu_to_be16(x) swap16(x) | ||
| 707 | # define BE16_TO_CPU(x) swap16(x) | ||
| 708 | # define CPU_TO_BE16(x) swap16(x) | ||
| 709 | |||
| 710 | # define le32_to_cpu(x) (x) | ||
| 711 | # define cpu_to_le32(x) (x) | ||
| 712 | # define LE32_TO_CPU(x) (x) | ||
| 713 | # define CPU_TO_LE32(x) (x) | ||
| 714 | |||
| 715 | # define be32_to_cpu(x) swap32(x) | ||
| 716 | # define cpu_to_be32(x) swap32(x) | ||
| 717 | # define BE32_TO_CPU(x) swap32(x) | ||
| 718 | # define CPU_TO_BE32(x) swap32(x) | ||
| 719 | /** @} */ | ||
| 720 | |||
| 721 | /** \name Endianism Conversion | ||
| 722 | * | ||
| 723 | * The same considerations as for clz and ctz apply here but GCC's | ||
| 724 | * __builtin_bswap_32 and __builtin_bswap_64 do not behave like macros when | ||
| 725 | * applied to constant expressions, so two sets of macros are defined here: | ||
| 726 | * - Swap16, Swap32 and Swap64 to apply to constant expressions (values known | ||
| 727 | * at compile time); | ||
| 728 | * - swap16, swap32 and swap64 to apply to non-constant expressions (values | ||
| 729 | * unknown at compile time). | ||
| 730 | * | ||
| 731 | * @{ */ | ||
| 732 | |||
| 733 | /** \brief Toggles the endianism of \a u16 (by swapping its bytes). | ||
| 734 | * | ||
| 735 | * \param[in] u16 U16 of which to toggle the endianism. | ||
| 736 | * | ||
| 737 | * \return Value resulting from \a u16 with toggled endianism. | ||
| 738 | * | ||
| 739 | * \note More optimized if only used with values known at compile time. | ||
| 740 | */ | ||
| 741 | # define Swap16(u16) ((uint16_t)(((uint16_t)(u16) >> 8) | ((uint16_t)(u16) << 8))) | ||
| 742 | |||
| 743 | /** \brief Toggles the endianism of \a u32 (by swapping its bytes). | ||
| 744 | * | ||
| 745 | * \param[in] u32 U32 of which to toggle the endianism. | ||
| 746 | * | ||
| 747 | * \return Value resulting from \a u32 with toggled endianism. | ||
| 748 | * | ||
| 749 | * \note More optimized if only used with values known at compile time. | ||
| 750 | */ | ||
| 751 | # define Swap32(u32) ((uint32_t)(((uint32_t)Swap16((uint32_t)(u32) >> 16)) | ((uint32_t)Swap16((uint32_t)(u32)) << 16))) | ||
| 752 | |||
| 753 | /** \brief Toggles the endianism of \a u64 (by swapping its bytes). | ||
| 754 | * | ||
| 755 | * \param[in] u64 U64 of which to toggle the endianism. | ||
| 756 | * | ||
| 757 | * \return Value resulting from \a u64 with toggled endianism. | ||
| 758 | * | ||
| 759 | * \note More optimized if only used with values known at compile time. | ||
| 760 | */ | ||
| 761 | # define Swap64(u64) ((uint64_t)(((uint64_t)Swap32((uint64_t)(u64) >> 32)) | ((uint64_t)Swap32((uint64_t)(u64)) << 32))) | ||
| 762 | |||
| 763 | /** \brief Toggles the endianism of \a u16 (by swapping its bytes). | ||
| 764 | * | ||
| 765 | * \param[in] u16 U16 of which to toggle the endianism. | ||
| 766 | * | ||
| 767 | * \return Value resulting from \a u16 with toggled endianism. | ||
| 768 | * | ||
| 769 | * \note More optimized if only used with values unknown at compile time. | ||
| 770 | */ | ||
| 771 | # define swap16(u16) Swap16(u16) | ||
| 772 | |||
| 773 | /** \brief Toggles the endianism of \a u32 (by swapping its bytes). | ||
| 774 | * | ||
| 775 | * \param[in] u32 U32 of which to toggle the endianism. | ||
| 776 | * | ||
| 777 | * \return Value resulting from \a u32 with toggled endianism. | ||
| 778 | * | ||
| 779 | * \note More optimized if only used with values unknown at compile time. | ||
| 780 | */ | ||
| 781 | # if (defined __GNUC__) | ||
| 782 | # define swap32(u32) ((uint32_t)__builtin_bswap32((uint32_t)(u32))) | ||
| 783 | # else | ||
| 784 | # define swap32(u32) Swap32(u32) | ||
| 785 | # endif | ||
| 786 | |||
| 787 | /** \brief Toggles the endianism of \a u64 (by swapping its bytes). | ||
| 788 | * | ||
| 789 | * \param[in] u64 U64 of which to toggle the endianism. | ||
| 790 | * | ||
| 791 | * \return Value resulting from \a u64 with toggled endianism. | ||
| 792 | * | ||
| 793 | * \note More optimized if only used with values unknown at compile time. | ||
| 794 | */ | ||
| 795 | # if (defined __GNUC__) | ||
| 796 | # define swap64(u64) ((uint64_t)__builtin_bswap64((uint64_t)(u64))) | ||
| 797 | # else | ||
| 798 | # define swap64(u64) ((uint64_t)(((uint64_t)swap32((uint64_t)(u64) >> 32)) | ((uint64_t)swap32((uint64_t)(u64)) << 32))) | ||
| 799 | # endif | ||
| 800 | |||
| 801 | /** @} */ | ||
| 802 | |||
| 803 | /** \name Target Abstraction | ||
| 804 | * | ||
| 805 | * @{ */ | ||
| 806 | |||
| 807 | # define _GLOBEXT_ extern /**< extern storage-class specifier. */ | ||
| 808 | # define _CONST_TYPE_ const /**< const type qualifier. */ | ||
| 809 | # define _MEM_TYPE_SLOW_ /**< Slow memory type. */ | ||
| 810 | # define _MEM_TYPE_MEDFAST_ /**< Fairly fast memory type. */ | ||
| 811 | # define _MEM_TYPE_FAST_ /**< Fast memory type. */ | ||
| 812 | |||
| 813 | # define memcmp_ram2ram memcmp /**< Target-specific memcmp of RAM to RAM. */ | ||
| 814 | # define memcmp_code2ram memcmp /**< Target-specific memcmp of RAM to NVRAM. */ | ||
| 815 | # define memcpy_ram2ram memcpy /**< Target-specific memcpy from RAM to RAM. */ | ||
| 816 | # define memcpy_code2ram memcpy /**< Target-specific memcpy from NVRAM to RAM. */ | ||
| 817 | |||
| 818 | /** @} */ | ||
| 819 | |||
| 820 | /** | ||
| 821 | * \brief Calculate \f$ \left\lceil \frac{a}{b} \right\rceil \f$ using | ||
| 822 | * integer arithmetic. | ||
| 823 | * | ||
| 824 | * \param[in] a An integer | ||
| 825 | * \param[in] b Another integer | ||
| 826 | * | ||
| 827 | * \return (\a a / \a b) rounded up to the nearest integer. | ||
| 828 | */ | ||
| 829 | # define div_ceil(a, b) (((a) + (b)-1) / (b)) | ||
| 830 | |||
| 831 | #endif /* #ifndef __ASSEMBLY__ */ | ||
| 832 | #ifdef __ICCARM__ | ||
| 833 | /** \name Compiler Keywords | ||
| 834 | * | ||
| 835 | * Port of some keywords from GCC to IAR Embedded Workbench. | ||
| 836 | * | ||
| 837 | * @{ */ | ||
| 838 | |||
| 839 | # define __asm__ asm | ||
| 840 | # define __inline__ inline | ||
| 841 | # define __volatile__ | ||
| 842 | |||
| 843 | /** @} */ | ||
| 844 | |||
| 845 | #endif | ||
| 846 | |||
| 847 | #define FUNC_PTR void * | ||
| 848 | /** | ||
| 849 | * \def unused | ||
| 850 | * \brief Marking \a v as a unused parameter or value. | ||
| 851 | */ | ||
| 852 | #define unused(v) \ | ||
| 853 | do { \ | ||
| 854 | (void)(v); \ | ||
| 855 | } while (0) | ||
| 856 | |||
| 857 | /* Define RAMFUNC attribute */ | ||
| 858 | #if defined(__CC_ARM) /* Keil uVision 4 */ | ||
| 859 | # define RAMFUNC __attribute__((section(".ramfunc"))) | ||
| 860 | #elif defined(__ICCARM__) /* IAR Ewarm 5.41+ */ | ||
| 861 | # define RAMFUNC __ramfunc | ||
| 862 | #elif defined(__GNUC__) /* GCC CS3 2009q3-68 */ | ||
| 863 | # define RAMFUNC __attribute__((section(".ramfunc"))) | ||
| 864 | #endif | ||
| 865 | |||
| 866 | /* Define OPTIMIZE_HIGH attribute */ | ||
| 867 | #if defined(__CC_ARM) /* Keil uVision 4 */ | ||
| 868 | # define OPTIMIZE_HIGH _Pragma("O3") | ||
| 869 | #elif defined(__ICCARM__) /* IAR Ewarm 5.41+ */ | ||
| 870 | # define OPTIMIZE_HIGH _Pragma("optimize=high") | ||
| 871 | #elif defined(__GNUC__) /* GCC CS3 2009q3-68 */ | ||
| 872 | # define OPTIMIZE_HIGH __attribute__((optimize("s"))) | ||
| 873 | #endif | ||
| 874 | // kmod #define PASS 0 | ||
| 875 | // kmod #define FAIL 1 | ||
| 876 | // kmod #define LOW 0 | ||
| 877 | // kmod #define HIGH 1 | ||
| 878 | |||
| 879 | typedef int8_t S8; //!< 8-bit signed integer. | ||
| 880 | typedef uint8_t U8; //!< 8-bit unsigned integer. | ||
| 881 | typedef int16_t S16; //!< 16-bit signed integer. | ||
| 882 | typedef uint16_t U16; //!< 16-bit unsigned integer. | ||
| 883 | typedef int32_t S32; //!< 32-bit signed integer. | ||
| 884 | typedef uint32_t U32; //!< 32-bit unsigned integer. | ||
| 885 | typedef int64_t S64; //!< 64-bit signed integer. | ||
| 886 | typedef uint64_t U64; //!< 64-bit unsigned integer. | ||
| 887 | typedef float F32; //!< 32-bit floating-point number. | ||
| 888 | typedef double F64; //!< 64-bit floating-point number. | ||
| 889 | |||
| 890 | #define MSB(u16) (((U8 *)&(u16))[1]) //!< Most significant byte of \a u16. | ||
| 891 | #define LSB(u16) (((U8 *)&(u16))[0]) //!< Least significant byte of \a u16. | ||
| 892 | |||
| 893 | #define MSH(u32) (((U16 *)&(u32))[1]) //!< Most significant half-word of \a u32. | ||
| 894 | #define LSH(u32) (((U16 *)&(u32))[0]) //!< Least significant half-word of \a u32. | ||
| 895 | #define MSB0W(u32) (((U8 *)&(u32))[3]) //!< Most significant byte of 1st rank of \a u32. | ||
| 896 | #define MSB1W(u32) (((U8 *)&(u32))[2]) //!< Most significant byte of 2nd rank of \a u32. | ||
| 897 | #define MSB2W(u32) (((U8 *)&(u32))[1]) //!< Most significant byte of 3rd rank of \a u32. | ||
| 898 | #define MSB3W(u32) (((U8 *)&(u32))[0]) //!< Most significant byte of 4th rank of \a u32. | ||
| 899 | #define LSB3W(u32) MSB0W(u32) //!< Least significant byte of 4th rank of \a u32. | ||
| 900 | #define LSB2W(u32) MSB1W(u32) //!< Least significant byte of 3rd rank of \a u32. | ||
| 901 | #define LSB1W(u32) MSB2W(u32) //!< Least significant byte of 2nd rank of \a u32. | ||
| 902 | #define LSB0W(u32) MSB3W(u32) //!< Least significant byte of 1st rank of \a u32. | ||
| 903 | |||
| 904 | #define MSW(u64) (((U32 *)&(u64))[1]) //!< Most significant word of \a u64. | ||
| 905 | #define LSW(u64) (((U32 *)&(u64))[0]) //!< Least significant word of \a u64. | ||
| 906 | #define MSH0(u64) (((U16 *)&(u64))[3]) //!< Most significant half-word of 1st rank of \a u64. | ||
| 907 | #define MSH1(u64) (((U16 *)&(u64))[2]) //!< Most significant half-word of 2nd rank of \a u64. | ||
| 908 | #define MSH2(u64) (((U16 *)&(u64))[1]) //!< Most significant half-word of 3rd rank of \a u64. | ||
| 909 | #define MSH3(u64) (((U16 *)&(u64))[0]) //!< Most significant half-word of 4th rank of \a u64. | ||
| 910 | #define LSH3(u64) MSH0(u64) //!< Least significant half-word of 4th rank of \a u64. | ||
| 911 | #define LSH2(u64) MSH1(u64) //!< Least significant half-word of 3rd rank of \a u64. | ||
| 912 | #define LSH1(u64) MSH2(u64) //!< Least significant half-word of 2nd rank of \a u64. | ||
| 913 | #define LSH0(u64) MSH3(u64) //!< Least significant half-word of 1st rank of \a u64. | ||
| 914 | #define MSB0D(u64) (((U8 *)&(u64))[7]) //!< Most significant byte of 1st rank of \a u64. | ||
| 915 | #define MSB1D(u64) (((U8 *)&(u64))[6]) //!< Most significant byte of 2nd rank of \a u64. | ||
| 916 | #define MSB2D(u64) (((U8 *)&(u64))[5]) //!< Most significant byte of 3rd rank of \a u64. | ||
| 917 | #define MSB3D(u64) (((U8 *)&(u64))[4]) //!< Most significant byte of 4th rank of \a u64. | ||
| 918 | #define MSB4D(u64) (((U8 *)&(u64))[3]) //!< Most significant byte of 5th rank of \a u64. | ||
| 919 | #define MSB5D(u64) (((U8 *)&(u64))[2]) //!< Most significant byte of 6th rank of \a u64. | ||
| 920 | #define MSB6D(u64) (((U8 *)&(u64))[1]) //!< Most significant byte of 7th rank of \a u64. | ||
| 921 | #define MSB7D(u64) (((U8 *)&(u64))[0]) //!< Most significant byte of 8th rank of \a u64. | ||
| 922 | #define LSB7D(u64) MSB0D(u64) //!< Least significant byte of 8th rank of \a u64. | ||
| 923 | #define LSB6D(u64) MSB1D(u64) //!< Least significant byte of 7th rank of \a u64. | ||
| 924 | #define LSB5D(u64) MSB2D(u64) //!< Least significant byte of 6th rank of \a u64. | ||
| 925 | #define LSB4D(u64) MSB3D(u64) //!< Least significant byte of 5th rank of \a u64. | ||
| 926 | #define LSB3D(u64) MSB4D(u64) //!< Least significant byte of 4th rank of \a u64. | ||
| 927 | #define LSB2D(u64) MSB5D(u64) //!< Least significant byte of 3rd rank of \a u64. | ||
| 928 | #define LSB1D(u64) MSB6D(u64) //!< Least significant byte of 2nd rank of \a u64. | ||
| 929 | #define LSB0D(u64) MSB7D(u64) //!< Least significant byte of 1st rank of \a u64. | ||
| 930 | |||
| 931 | #define LSB0(u32) LSB0W(u32) //!< Least significant byte of 1st rank of \a u32. | ||
| 932 | #define LSB1(u32) LSB1W(u32) //!< Least significant byte of 2nd rank of \a u32. | ||
| 933 | #define LSB2(u32) LSB2W(u32) //!< Least significant byte of 3rd rank of \a u32. | ||
| 934 | #define LSB3(u32) LSB3W(u32) //!< Least significant byte of 4th rank of \a u32. | ||
| 935 | #define MSB3(u32) MSB3W(u32) //!< Most significant byte of 4th rank of \a u32. | ||
| 936 | #define MSB2(u32) MSB2W(u32) //!< Most significant byte of 3rd rank of \a u32. | ||
| 937 | #define MSB1(u32) MSB1W(u32) //!< Most significant byte of 2nd rank of \a u32. | ||
| 938 | #define MSB0(u32) MSB0W(u32) //!< Most significant byte of 1st rank of \a u32. | ||
| 939 | |||
| 940 | #if defined(__ICCARM__) | ||
| 941 | # define SHORTENUM __packed | ||
| 942 | #elif defined(__GNUC__) | ||
| 943 | # define SHORTENUM __attribute__((packed)) | ||
| 944 | #endif | ||
| 945 | |||
| 946 | /* No operation */ | ||
| 947 | #if defined(__ICCARM__) | ||
| 948 | # define nop() __no_operation() | ||
| 949 | #elif defined(__GNUC__) | ||
| 950 | # define nop() (__NOP()) | ||
| 951 | #endif | ||
| 952 | |||
| 953 | #define FLASH_DECLARE(x) const x | ||
| 954 | #define FLASH_EXTERN(x) extern const x | ||
| 955 | #define PGM_READ_BYTE(x) *(x) | ||
| 956 | #define PGM_READ_WORD(x) *(x) | ||
| 957 | #define MEMCPY_ENDIAN memcpy | ||
| 958 | #define PGM_READ_BLOCK(dst, src, len) memcpy((dst), (src), (len)) | ||
| 959 | |||
| 960 | /*Defines the Flash Storage for the request and response of MAC*/ | ||
| 961 | #define CMD_ID_OCTET (0) | ||
| 962 | |||
| 963 | /* Converting of values from CPU endian to little endian. */ | ||
| 964 | #define CPU_ENDIAN_TO_LE16(x) (x) | ||
| 965 | #define CPU_ENDIAN_TO_LE32(x) (x) | ||
| 966 | #define CPU_ENDIAN_TO_LE64(x) (x) | ||
| 967 | |||
| 968 | /* Converting of values from little endian to CPU endian. */ | ||
| 969 | #define LE16_TO_CPU_ENDIAN(x) (x) | ||
| 970 | #define LE32_TO_CPU_ENDIAN(x) (x) | ||
| 971 | #define LE64_TO_CPU_ENDIAN(x) (x) | ||
| 972 | |||
| 973 | /* Converting of constants from little endian to CPU endian. */ | ||
| 974 | #define CLE16_TO_CPU_ENDIAN(x) (x) | ||
| 975 | #define CLE32_TO_CPU_ENDIAN(x) (x) | ||
| 976 | #define CLE64_TO_CPU_ENDIAN(x) (x) | ||
| 977 | |||
| 978 | /* Converting of constants from CPU endian to little endian. */ | ||
| 979 | #define CCPU_ENDIAN_TO_LE16(x) (x) | ||
| 980 | #define CCPU_ENDIAN_TO_LE32(x) (x) | ||
| 981 | #define CCPU_ENDIAN_TO_LE64(x) (x) | ||
| 982 | |||
| 983 | #define ADDR_COPY_DST_SRC_16(dst, src) ((dst) = (src)) | ||
| 984 | #define ADDR_COPY_DST_SRC_64(dst, src) ((dst) = (src)) | ||
| 985 | |||
| 986 | /** | ||
| 987 | * @brief Converts a 64-Bit value into a 8 Byte array | ||
| 988 | * | ||
| 989 | * @param[in] value 64-Bit value | ||
| 990 | * @param[out] data Pointer to the 8 Byte array to be updated with 64-Bit value | ||
| 991 | * @ingroup apiPalApi | ||
| 992 | */ | ||
| 993 | static inline void convert_64_bit_to_byte_array(uint64_t value, uint8_t *data) { | ||
| 994 | uint8_t index = 0; | ||
| 995 | |||
| 996 | while (index < 8) { | ||
| 997 | data[index++] = value & 0xFF; | ||
| 998 | value = value >> 8; | ||
| 999 | } | ||
| 1000 | } | ||
| 1001 | |||
| 1002 | /** | ||
| 1003 | * @brief Converts a 16-Bit value into a 2 Byte array | ||
| 1004 | * | ||
| 1005 | * @param[in] value 16-Bit value | ||
| 1006 | * @param[out] data Pointer to the 2 Byte array to be updated with 16-Bit value | ||
| 1007 | * @ingroup apiPalApi | ||
| 1008 | */ | ||
| 1009 | static inline void convert_16_bit_to_byte_array(uint16_t value, uint8_t *data) { | ||
| 1010 | data[0] = value & 0xFF; | ||
| 1011 | data[1] = (value >> 8) & 0xFF; | ||
| 1012 | } | ||
| 1013 | |||
| 1014 | /* Converts a 16-Bit value into a 2 Byte array */ | ||
| 1015 | static inline void convert_spec_16_bit_to_byte_array(uint16_t value, uint8_t *data) { | ||
| 1016 | data[0] = value & 0xFF; | ||
| 1017 | data[1] = (value >> 8) & 0xFF; | ||
| 1018 | } | ||
| 1019 | |||
| 1020 | /* Converts a 16-Bit value into a 2 Byte array */ | ||
| 1021 | static inline void convert_16_bit_to_byte_address(uint16_t value, uint8_t *data) { | ||
| 1022 | data[0] = value & 0xFF; | ||
| 1023 | data[1] = (value >> 8) & 0xFF; | ||
| 1024 | } | ||
| 1025 | |||
| 1026 | /* | ||
| 1027 | * @brief Converts a 2 Byte array into a 16-Bit value | ||
| 1028 | * | ||
| 1029 | * @param data Specifies the pointer to the 2 Byte array | ||
| 1030 | * | ||
| 1031 | * @return 16-Bit value | ||
| 1032 | * @ingroup apiPalApi | ||
| 1033 | */ | ||
| 1034 | static inline uint16_t convert_byte_array_to_16_bit(uint8_t *data) { | ||
| 1035 | return (data[0] | ((uint16_t)data[1] << 8)); | ||
| 1036 | } | ||
| 1037 | |||
| 1038 | /* Converts a 4 Byte array into a 32-Bit value */ | ||
| 1039 | static inline uint32_t convert_byte_array_to_32_bit(uint8_t *data) { | ||
| 1040 | union { | ||
| 1041 | uint32_t u32; | ||
| 1042 | uint8_t u8[4]; | ||
| 1043 | } long_addr; | ||
| 1044 | |||
| 1045 | uint8_t index; | ||
| 1046 | |||
| 1047 | for (index = 0; index < 4; index++) { | ||
| 1048 | long_addr.u8[index] = *data++; | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | return long_addr.u32; | ||
| 1052 | } | ||
| 1053 | |||
| 1054 | /** | ||
| 1055 | * @brief Converts a 8 Byte array into a 64-Bit value | ||
| 1056 | * | ||
| 1057 | * @param data Specifies the pointer to the 8 Byte array | ||
| 1058 | * | ||
| 1059 | * @return 64-Bit value | ||
| 1060 | * @ingroup apiPalApi | ||
| 1061 | */ | ||
| 1062 | static inline uint64_t convert_byte_array_to_64_bit(uint8_t *data) { | ||
| 1063 | union { | ||
| 1064 | uint64_t u64; | ||
| 1065 | uint8_t u8[8]; | ||
| 1066 | } long_addr; | ||
| 1067 | |||
| 1068 | uint8_t index; | ||
| 1069 | |||
| 1070 | for (index = 0; index < 8; index++) { | ||
| 1071 | long_addr.u8[index] = *data++; | ||
| 1072 | } | ||
| 1073 | |||
| 1074 | return long_addr.u64; | ||
| 1075 | } | ||
| 1076 | |||
| 1077 | /** @} */ | ||
| 1078 | |||
| 1079 | #endif /* UTILS_COMPILER_H_INCLUDED */ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/conf_usb.h b/tmk_core/protocol/arm_atsam/usb/conf_usb.h deleted file mode 100644 index 50d189a202..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/conf_usb.h +++ /dev/null | |||
| @@ -1,164 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief USB configuration file | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #ifndef _CONF_USB_H_ | ||
| 48 | #define _CONF_USB_H_ | ||
| 49 | |||
| 50 | #include "compiler.h" | ||
| 51 | #include "udi_device_conf.h" | ||
| 52 | |||
| 53 | #define UDI_CDC_DEFAULT_RATE 115200 | ||
| 54 | #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 | ||
| 55 | #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE | ||
| 56 | #define UDI_CDC_DEFAULT_DATABITS 8 | ||
| 57 | |||
| 58 | //! Device definition (mandatory) | ||
| 59 | #define USB_DEVICE_VENDOR_ID VENDOR_ID | ||
| 60 | #define USB_DEVICE_PRODUCT_ID PRODUCT_ID | ||
| 61 | #define USB_DEVICE_VERSION DEVICE_VER | ||
| 62 | #define USB_DEVICE_POWER 500 // Consumption on Vbus line (mA) | ||
| 63 | #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_BUS_POWERED) | ||
| 64 | // (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED) | ||
| 65 | // (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_SELF_POWERED) | ||
| 66 | // (USB_CONFIG_ATTR_SELF_POWERED) | ||
| 67 | // (USB_CONFIG_ATTR_BUS_POWERED) | ||
| 68 | |||
| 69 | //! USB Device string definitions (Optional) | ||
| 70 | #define USB_DEVICE_MANUFACTURE_NAME MANUFACTURER | ||
| 71 | #define USB_DEVICE_PRODUCT_NAME PRODUCT | ||
| 72 | #define USB_DEVICE_SERIAL_NAME SERIAL_NUM | ||
| 73 | |||
| 74 | // Comment out USB_DEVICE_SERIAL_USE_BOOTLOADER_SERIAL to prevent ROM lookup of factory programmed serial number | ||
| 75 | #define USB_DEVICE_SERIAL_USE_BOOTLOADER_SERIAL | ||
| 76 | |||
| 77 | /** | ||
| 78 | * Device speeds support | ||
| 79 | * @{ | ||
| 80 | */ | ||
| 81 | //! To define a Low speed device | ||
| 82 | //#define USB_DEVICE_LOW_SPEED | ||
| 83 | |||
| 84 | //! To authorize the High speed | ||
| 85 | #if (UC3A3 || UC3A4) | ||
| 86 | //#define USB_DEVICE_HS_SUPPORT | ||
| 87 | #elif (SAM3XA || SAM3U) | ||
| 88 | //#define USB_DEVICE_HS_SUPPORT | ||
| 89 | #endif | ||
| 90 | //@} | ||
| 91 | |||
| 92 | /** | ||
| 93 | * USB Device Callbacks definitions (Optional) | ||
| 94 | * @{ | ||
| 95 | */ | ||
| 96 | #define UDC_VBUS_EVENT(b_vbus_high) | ||
| 97 | #define UDC_SOF_EVENT() main_sof_action() | ||
| 98 | #define UDC_SUSPEND_EVENT() main_suspend_action() | ||
| 99 | #define UDC_RESUME_EVENT() main_resume_action() | ||
| 100 | //! Mandatory when USB_DEVICE_ATTR authorizes remote wakeup feature | ||
| 101 | #define UDC_REMOTEWAKEUP_ENABLE() main_remotewakeup_enable() | ||
| 102 | #define UDC_REMOTEWAKEUP_DISABLE() main_remotewakeup_disable() | ||
| 103 | //! When a extra string descriptor must be supported | ||
| 104 | //! other than manufacturer, product and serial string | ||
| 105 | // #define UDC_GET_EXTRA_STRING() | ||
| 106 | //@} | ||
| 107 | |||
| 108 | //@} | ||
| 109 | |||
| 110 | /** | ||
| 111 | * USB Interface Configuration | ||
| 112 | * @{ | ||
| 113 | */ | ||
| 114 | /** | ||
| 115 | * Configuration of HID Keyboard interface | ||
| 116 | * @{ | ||
| 117 | */ | ||
| 118 | //! Interface callback definition | ||
| 119 | #define UDI_HID_KBD_ENABLE_EXT() main_kbd_enable() | ||
| 120 | #define UDI_HID_KBD_DISABLE_EXT() main_kbd_disable() | ||
| 121 | //#define UDI_HID_KBD_CHANGE_LED(value) ui_kbd_led(value) | ||
| 122 | |||
| 123 | #ifdef NKRO_ENABLE | ||
| 124 | # define UDI_HID_NKRO_ENABLE_EXT() main_nkro_enable() | ||
| 125 | # define UDI_HID_NKRO_DISABLE_EXT() main_nkro_disable() | ||
| 126 | //#define UDI_HID_NKRO_CHANGE_LED(value) ui_kbd_led(value) | ||
| 127 | #endif | ||
| 128 | |||
| 129 | #ifdef EXTRAKEY_ENABLE | ||
| 130 | # define UDI_HID_EXK_ENABLE_EXT() main_exk_enable() | ||
| 131 | # define UDI_HID_EXK_DISABLE_EXT() main_exk_disable() | ||
| 132 | #endif | ||
| 133 | |||
| 134 | #ifdef CONSOLE_ENABLE | ||
| 135 | # define UDI_HID_CON_ENABLE_EXT() main_con_enable() | ||
| 136 | # define UDI_HID_CON_DISABLE_EXT() main_con_disable() | ||
| 137 | #endif | ||
| 138 | |||
| 139 | #ifdef MOUSE_ENABLE | ||
| 140 | # define UDI_HID_MOU_ENABLE_EXT() main_mou_enable() | ||
| 141 | # define UDI_HID_MOU_DISABLE_EXT() main_mou_disable() | ||
| 142 | #endif | ||
| 143 | |||
| 144 | #ifdef RAW_ENABLE | ||
| 145 | # define UDI_HID_RAW_ENABLE_EXT() main_raw_enable() | ||
| 146 | # define UDI_HID_RAW_DISABLE_EXT() main_raw_disable() | ||
| 147 | # define UDI_HID_RAW_RECEIVE(buffer, len) main_raw_receive(buffer, len) | ||
| 148 | #endif | ||
| 149 | |||
| 150 | //@} | ||
| 151 | //@} | ||
| 152 | |||
| 153 | /** | ||
| 154 | * USB Device Driver Configuration | ||
| 155 | * @{ | ||
| 156 | */ | ||
| 157 | //@} | ||
| 158 | |||
| 159 | //! The includes of classes and other headers must be done at the end of this file to avoid compile error | ||
| 160 | #include "udi_hid_kbd_conf.h" | ||
| 161 | #include "usb_main.h" | ||
| 162 | #include "ui.h" | ||
| 163 | |||
| 164 | #endif // _CONF_USB_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/main_usb.c b/tmk_core/protocol/arm_atsam/usb/main_usb.c deleted file mode 100644 index ee6ed25b85..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/main_usb.c +++ /dev/null | |||
| @@ -1,120 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include "samd51j18a.h" | ||
| 19 | #include "conf_usb.h" | ||
| 20 | #include "udd.h" | ||
| 21 | |||
| 22 | #ifdef RAW_ENABLE | ||
| 23 | # include "raw_hid.h" | ||
| 24 | #endif | ||
| 25 | |||
| 26 | uint8_t keyboard_protocol = 1; | ||
| 27 | |||
| 28 | void main_suspend_action(void) { | ||
| 29 | ui_powerdown(); | ||
| 30 | } | ||
| 31 | |||
| 32 | void main_resume_action(void) { | ||
| 33 | ui_wakeup(); | ||
| 34 | } | ||
| 35 | |||
| 36 | void main_sof_action(void) { | ||
| 37 | ui_process(udd_get_frame_number()); | ||
| 38 | } | ||
| 39 | |||
| 40 | void main_remotewakeup_enable(void) { | ||
| 41 | ui_wakeup_enable(); | ||
| 42 | } | ||
| 43 | |||
| 44 | void main_remotewakeup_disable(void) { | ||
| 45 | ui_wakeup_disable(); | ||
| 46 | } | ||
| 47 | |||
| 48 | volatile bool main_b_kbd_enable = false; | ||
| 49 | bool main_kbd_enable(void) { | ||
| 50 | main_b_kbd_enable = true; | ||
| 51 | return true; | ||
| 52 | } | ||
| 53 | |||
| 54 | void main_kbd_disable(void) { | ||
| 55 | main_b_kbd_enable = false; | ||
| 56 | } | ||
| 57 | |||
| 58 | #ifdef NKRO_ENABLE | ||
| 59 | volatile bool main_b_nkro_enable = false; | ||
| 60 | bool main_nkro_enable(void) { | ||
| 61 | main_b_nkro_enable = true; | ||
| 62 | return true; | ||
| 63 | } | ||
| 64 | |||
| 65 | void main_nkro_disable(void) { | ||
| 66 | main_b_nkro_enable = false; | ||
| 67 | } | ||
| 68 | #endif | ||
| 69 | |||
| 70 | #ifdef EXTRAKEY_ENABLE | ||
| 71 | volatile bool main_b_exk_enable = false; | ||
| 72 | bool main_exk_enable(void) { | ||
| 73 | main_b_exk_enable = true; | ||
| 74 | return true; | ||
| 75 | } | ||
| 76 | |||
| 77 | void main_exk_disable(void) { | ||
| 78 | main_b_exk_enable = false; | ||
| 79 | } | ||
| 80 | #endif | ||
| 81 | |||
| 82 | #ifdef CONSOLE_ENABLE | ||
| 83 | volatile bool main_b_con_enable = false; | ||
| 84 | bool main_con_enable(void) { | ||
| 85 | main_b_con_enable = true; | ||
| 86 | return true; | ||
| 87 | } | ||
| 88 | |||
| 89 | void main_con_disable(void) { | ||
| 90 | main_b_con_enable = false; | ||
| 91 | } | ||
| 92 | #endif | ||
| 93 | |||
| 94 | #ifdef MOUSE_ENABLE | ||
| 95 | volatile bool main_b_mou_enable = false; | ||
| 96 | bool main_mou_enable(void) { | ||
| 97 | main_b_mou_enable = true; | ||
| 98 | return true; | ||
| 99 | } | ||
| 100 | |||
| 101 | void main_mou_disable(void) { | ||
| 102 | main_b_mou_enable = false; | ||
| 103 | } | ||
| 104 | #endif | ||
| 105 | |||
| 106 | #ifdef RAW_ENABLE | ||
| 107 | volatile bool main_b_raw_enable = false; | ||
| 108 | bool main_raw_enable(void) { | ||
| 109 | main_b_raw_enable = true; | ||
| 110 | return true; | ||
| 111 | } | ||
| 112 | |||
| 113 | void main_raw_disable(void) { | ||
| 114 | main_b_raw_enable = false; | ||
| 115 | } | ||
| 116 | |||
| 117 | void main_raw_receive(uint8_t *buffer, uint8_t len) { | ||
| 118 | raw_hid_receive(buffer, len); | ||
| 119 | } | ||
| 120 | #endif | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/status_codes.h b/tmk_core/protocol/arm_atsam/usb/status_codes.h deleted file mode 100644 index 72819a0d7d..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/status_codes.h +++ /dev/null | |||
| @@ -1,158 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief Status code definitions. | ||
| 5 | * | ||
| 6 | * This file defines various status codes returned by functions, | ||
| 7 | * indicating success or failure as well as what kind of failure. | ||
| 8 | * | ||
| 9 | * Copyright (C) 2012-2015 Atmel Corporation. All rights reserved. | ||
| 10 | * | ||
| 11 | * \asf_license_start | ||
| 12 | * | ||
| 13 | * \page License | ||
| 14 | * | ||
| 15 | * Redistribution and use in source and binary forms, with or without | ||
| 16 | * modification, are permitted provided that the following conditions are met: | ||
| 17 | * | ||
| 18 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer. | ||
| 20 | * | ||
| 21 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 22 | * this list of conditions and the following disclaimer in the documentation | ||
| 23 | * and/or other materials provided with the distribution. | ||
| 24 | * | ||
| 25 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 26 | * from this software without specific prior written permission. | ||
| 27 | * | ||
| 28 | * 4. This software may only be redistributed and used in connection with an | ||
| 29 | * Atmel microcontroller product. | ||
| 30 | * | ||
| 31 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 32 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 33 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 34 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 35 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 40 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 41 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 42 | * | ||
| 43 | * \asf_license_stop | ||
| 44 | * | ||
| 45 | */ | ||
| 46 | /* | ||
| 47 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 48 | */ | ||
| 49 | |||
| 50 | #ifndef STATUS_CODES_H_INCLUDED | ||
| 51 | #define STATUS_CODES_H_INCLUDED | ||
| 52 | |||
| 53 | #include <stdint.h> | ||
| 54 | |||
| 55 | /** | ||
| 56 | * \defgroup group_sam0_utils_status_codes Status Codes | ||
| 57 | * | ||
| 58 | * \ingroup group_sam0_utils | ||
| 59 | * | ||
| 60 | * @{ | ||
| 61 | */ | ||
| 62 | |||
| 63 | /** Mask to retrieve the error category of a status code. */ | ||
| 64 | #define STATUS_CATEGORY_MASK 0xF0 | ||
| 65 | |||
| 66 | /** Mask to retrieve the error code within the category of a status code. */ | ||
| 67 | #define STATUS_ERROR_MASK 0x0F | ||
| 68 | |||
| 69 | /** Status code error categories. */ | ||
| 70 | enum status_categories { | ||
| 71 | STATUS_CATEGORY_OK = 0x00, | ||
| 72 | STATUS_CATEGORY_COMMON = 0x10, | ||
| 73 | STATUS_CATEGORY_ANALOG = 0x30, | ||
| 74 | STATUS_CATEGORY_COM = 0x40, | ||
| 75 | STATUS_CATEGORY_IO = 0x50, | ||
| 76 | }; | ||
| 77 | |||
| 78 | /** | ||
| 79 | * Status code that may be returned by shell commands and protocol | ||
| 80 | * implementations. | ||
| 81 | * | ||
| 82 | * \note Any change to these status codes and the corresponding | ||
| 83 | * message strings is strictly forbidden. New codes can be added, | ||
| 84 | * however, but make sure that any message string tables are updated | ||
| 85 | * at the same time. | ||
| 86 | */ | ||
| 87 | enum status_code { | ||
| 88 | STATUS_OK = STATUS_CATEGORY_OK | 0x00, | ||
| 89 | STATUS_VALID_DATA = STATUS_CATEGORY_OK | 0x01, | ||
| 90 | STATUS_NO_CHANGE = STATUS_CATEGORY_OK | 0x02, | ||
| 91 | STATUS_ABORTED = STATUS_CATEGORY_OK | 0x04, | ||
| 92 | STATUS_BUSY = STATUS_CATEGORY_OK | 0x05, | ||
| 93 | STATUS_SUSPEND = STATUS_CATEGORY_OK | 0x06, | ||
| 94 | |||
| 95 | STATUS_ERR_IO = STATUS_CATEGORY_COMMON | 0x00, | ||
| 96 | STATUS_ERR_REQ_FLUSHED = STATUS_CATEGORY_COMMON | 0x01, | ||
| 97 | STATUS_ERR_TIMEOUT = STATUS_CATEGORY_COMMON | 0x02, | ||
| 98 | STATUS_ERR_BAD_DATA = STATUS_CATEGORY_COMMON | 0x03, | ||
| 99 | STATUS_ERR_NOT_FOUND = STATUS_CATEGORY_COMMON | 0x04, | ||
| 100 | STATUS_ERR_UNSUPPORTED_DEV = STATUS_CATEGORY_COMMON | 0x05, | ||
| 101 | STATUS_ERR_NO_MEMORY = STATUS_CATEGORY_COMMON | 0x06, | ||
| 102 | STATUS_ERR_INVALID_ARG = STATUS_CATEGORY_COMMON | 0x07, | ||
| 103 | STATUS_ERR_BAD_ADDRESS = STATUS_CATEGORY_COMMON | 0x08, | ||
| 104 | STATUS_ERR_BAD_FORMAT = STATUS_CATEGORY_COMMON | 0x0A, | ||
| 105 | STATUS_ERR_BAD_FRQ = STATUS_CATEGORY_COMMON | 0x0B, | ||
| 106 | STATUS_ERR_DENIED = STATUS_CATEGORY_COMMON | 0x0c, | ||
| 107 | STATUS_ERR_ALREADY_INITIALIZED = STATUS_CATEGORY_COMMON | 0x0d, | ||
| 108 | STATUS_ERR_OVERFLOW = STATUS_CATEGORY_COMMON | 0x0e, | ||
| 109 | STATUS_ERR_NOT_INITIALIZED = STATUS_CATEGORY_COMMON | 0x0f, | ||
| 110 | |||
| 111 | STATUS_ERR_SAMPLERATE_UNAVAILABLE = STATUS_CATEGORY_ANALOG | 0x00, | ||
| 112 | STATUS_ERR_RESOLUTION_UNAVAILABLE = STATUS_CATEGORY_ANALOG | 0x01, | ||
| 113 | |||
| 114 | STATUS_ERR_BAUDRATE_UNAVAILABLE = STATUS_CATEGORY_COM | 0x00, | ||
| 115 | STATUS_ERR_PACKET_COLLISION = STATUS_CATEGORY_COM | 0x01, | ||
| 116 | STATUS_ERR_PROTOCOL = STATUS_CATEGORY_COM | 0x02, | ||
| 117 | |||
| 118 | STATUS_ERR_PIN_MUX_INVALID = STATUS_CATEGORY_IO | 0x00, | ||
| 119 | }; | ||
| 120 | typedef enum status_code status_code_genare_t; | ||
| 121 | |||
| 122 | /** | ||
| 123 | Status codes used by MAC stack. | ||
| 124 | */ | ||
| 125 | enum status_code_wireless { | ||
| 126 | // STATUS_OK = 0, //!< Success | ||
| 127 | ERR_IO_ERROR = -1, //!< I/O error | ||
| 128 | ERR_FLUSHED = -2, //!< Request flushed from queue | ||
| 129 | ERR_TIMEOUT = -3, //!< Operation timed out | ||
| 130 | ERR_BAD_DATA = -4, //!< Data integrity check failed | ||
| 131 | ERR_PROTOCOL = -5, //!< Protocol error | ||
| 132 | ERR_UNSUPPORTED_DEV = -6, //!< Unsupported device | ||
| 133 | ERR_NO_MEMORY = -7, //!< Insufficient memory | ||
| 134 | ERR_INVALID_ARG = -8, //!< Invalid argument | ||
| 135 | ERR_BAD_ADDRESS = -9, //!< Bad address | ||
| 136 | ERR_BUSY = -10, //!< Resource is busy | ||
| 137 | ERR_BAD_FORMAT = -11, //!< Data format not recognized | ||
| 138 | ERR_NO_TIMER = -12, //!< No timer available | ||
| 139 | ERR_TIMER_ALREADY_RUNNING = -13, //!< Timer already running | ||
| 140 | ERR_TIMER_NOT_RUNNING = -14, //!< Timer not running | ||
| 141 | |||
| 142 | /** | ||
| 143 | * \brief Operation in progress | ||
| 144 | * | ||
| 145 | * This status code is for driver-internal use when an operation | ||
| 146 | * is currently being performed. | ||
| 147 | * | ||
| 148 | * \note Drivers should never return this status code to any | ||
| 149 | * callers. It is strictly for internal use. | ||
| 150 | */ | ||
| 151 | OPERATION_IN_PROGRESS = -128, | ||
| 152 | }; | ||
| 153 | |||
| 154 | typedef enum status_code_wireless status_code_t; | ||
| 155 | |||
| 156 | /** @} */ | ||
| 157 | |||
| 158 | #endif /* STATUS_CODES_H_INCLUDED */ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/udc.c b/tmk_core/protocol/arm_atsam/usb/udc.c deleted file mode 100644 index 2a371c200a..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/udc.c +++ /dev/null | |||
| @@ -1,1072 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief USB Device Controller (UDC) | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #include "conf_usb.h" | ||
| 48 | #include "usb_protocol.h" | ||
| 49 | #include "udd.h" | ||
| 50 | #include "udc_desc.h" | ||
| 51 | #include "udi_device_conf.h" | ||
| 52 | #include "udi.h" | ||
| 53 | #include "udc.h" | ||
| 54 | |||
| 55 | #define BOOTLOADER_SERIAL_MAX_SIZE 20 // DO NOT MODIFY! | ||
| 56 | |||
| 57 | /** | ||
| 58 | * \ingroup udc_group | ||
| 59 | * \defgroup udc_group_interne Implementation of UDC | ||
| 60 | * | ||
| 61 | * Internal implementation | ||
| 62 | * @{ | ||
| 63 | */ | ||
| 64 | |||
| 65 | //! \name Internal variables to manage the USB device | ||
| 66 | //! @{ | ||
| 67 | |||
| 68 | //! Device status state (see enum usb_device_status in usb_protocol.h) | ||
| 69 | static le16_t udc_device_status; | ||
| 70 | |||
| 71 | COMPILER_WORD_ALIGNED | ||
| 72 | //! Device interface setting value | ||
| 73 | static uint8_t udc_iface_setting = 0; | ||
| 74 | |||
| 75 | //! Device Configuration number selected by the USB host | ||
| 76 | COMPILER_WORD_ALIGNED | ||
| 77 | static uint8_t udc_num_configuration = 0; | ||
| 78 | |||
| 79 | //! Pointer on the selected speed device configuration | ||
| 80 | static udc_config_speed_t UDC_DESC_STORAGE *udc_ptr_conf; | ||
| 81 | |||
| 82 | //! Pointer on interface descriptor used by SETUP request. | ||
| 83 | static usb_iface_desc_t UDC_DESC_STORAGE *udc_ptr_iface; | ||
| 84 | |||
| 85 | //! @} | ||
| 86 | |||
| 87 | //! \name Internal structure to store the USB device main strings | ||
| 88 | //! @{ | ||
| 89 | |||
| 90 | /** | ||
| 91 | * \brief Language ID of USB device (US ID by default) | ||
| 92 | */ | ||
| 93 | COMPILER_WORD_ALIGNED | ||
| 94 | static UDC_DESC_STORAGE usb_str_lgid_desc_t udc_string_desc_languageid = {.desc.bLength = sizeof(usb_str_lgid_desc_t), .desc.bDescriptorType = USB_DT_STRING, .string = {LE16(USB_LANGID_EN_US)}}; | ||
| 95 | |||
| 96 | /** | ||
| 97 | * \brief USB device manufacture name storage | ||
| 98 | * String is allocated only if USB_DEVICE_MANUFACTURE_NAME is declared | ||
| 99 | * by usb application configuration | ||
| 100 | */ | ||
| 101 | #ifdef USB_DEVICE_MANUFACTURE_NAME | ||
| 102 | static uint8_t udc_string_manufacturer_name[] = USB_DEVICE_MANUFACTURE_NAME; | ||
| 103 | # define USB_DEVICE_MANUFACTURE_NAME_SIZE (sizeof(udc_string_manufacturer_name) - 1) | ||
| 104 | #else | ||
| 105 | # define USB_DEVICE_MANUFACTURE_NAME_SIZE 0 | ||
| 106 | #endif | ||
| 107 | |||
| 108 | /** | ||
| 109 | * \brief USB device product name storage | ||
| 110 | * String is allocated only if USB_DEVICE_PRODUCT_NAME is declared | ||
| 111 | * by usb application configuration | ||
| 112 | */ | ||
| 113 | #ifdef USB_DEVICE_PRODUCT_NAME | ||
| 114 | static uint8_t udc_string_product_name[] = USB_DEVICE_PRODUCT_NAME; | ||
| 115 | # define USB_DEVICE_PRODUCT_NAME_SIZE (sizeof(udc_string_product_name) - 1) | ||
| 116 | #else | ||
| 117 | # define USB_DEVICE_PRODUCT_NAME_SIZE 0 | ||
| 118 | #endif | ||
| 119 | |||
| 120 | #if defined USB_DEVICE_SERIAL_NAME | ||
| 121 | # define USB_DEVICE_SERIAL_NAME_SIZE (sizeof(USB_DEVICE_SERIAL_NAME) - 1) | ||
| 122 | #else | ||
| 123 | # define USB_DEVICE_SERIAL_NAME_SIZE 0 | ||
| 124 | #endif | ||
| 125 | |||
| 126 | extern uint32_t _srom; | ||
| 127 | |||
| 128 | uint8_t usb_device_serial_name_size = 0; | ||
| 129 | #if defined USB_DEVICE_SERIAL_USE_BOOTLOADER_SERIAL | ||
| 130 | uint8_t bootloader_serial_number[BOOTLOADER_SERIAL_MAX_SIZE + 1] = ""; | ||
| 131 | #endif | ||
| 132 | static const uint8_t *udc_get_string_serial_name(void) { | ||
| 133 | #if defined USB_DEVICE_SERIAL_USE_BOOTLOADER_SERIAL | ||
| 134 | uint32_t serial_ptrloc = (uint32_t)&_srom - 4; | ||
| 135 | uint32_t serial_address = *(uint32_t *)serial_ptrloc; // Address of bootloader's serial number if available | ||
| 136 | |||
| 137 | if (serial_address != 0xFFFFFFFF && serial_address < serial_ptrloc) // Check for factory programmed serial address | ||
| 138 | { | ||
| 139 | if ((serial_address & 0xFF) % 4 == 0) // Check alignment | ||
| 140 | { | ||
| 141 | uint16_t *serial_use = (uint16_t *)(serial_address); // Point to address of string in rom | ||
| 142 | uint8_t serial_length = 0; | ||
| 143 | |||
| 144 | while ((*(serial_use + serial_length) > 32 && *(serial_use + serial_length) < 127) && serial_length < BOOTLOADER_SERIAL_MAX_SIZE) { | ||
| 145 | bootloader_serial_number[serial_length] = *(serial_use + serial_length) & 0xFF; | ||
| 146 | serial_length++; | ||
| 147 | } | ||
| 148 | bootloader_serial_number[serial_length] = 0; | ||
| 149 | |||
| 150 | usb_device_serial_name_size = serial_length; | ||
| 151 | |||
| 152 | return bootloader_serial_number; // Use serial programmed into bootloader rom | ||
| 153 | } | ||
| 154 | } | ||
| 155 | #endif | ||
| 156 | |||
| 157 | usb_device_serial_name_size = USB_DEVICE_SERIAL_NAME_SIZE; | ||
| 158 | |||
| 159 | #if defined USB_DEVICE_SERIAL_NAME | ||
| 160 | return (const uint8_t *)USB_DEVICE_SERIAL_NAME; // Use serial supplied by keyboard's config.h | ||
| 161 | #else | ||
| 162 | return 0; // No serial supplied | ||
| 163 | #endif | ||
| 164 | } | ||
| 165 | |||
| 166 | /** | ||
| 167 | * \brief USB device string descriptor | ||
| 168 | * Structure used to transfer ASCII strings to USB String descriptor structure. | ||
| 169 | */ | ||
| 170 | #ifndef BOOTLOADER_SERIAL_MAX_SIZE | ||
| 171 | # define BOOTLOADER_SERIAL_MAX_SIZE 0 | ||
| 172 | #endif // BOOTLOADER_SERIAL_MAX_SIZE | ||
| 173 | struct udc_string_desc_t { | ||
| 174 | usb_str_desc_t header; | ||
| 175 | le16_t string[Max(Max(Max(USB_DEVICE_MANUFACTURE_NAME_SIZE, USB_DEVICE_PRODUCT_NAME_SIZE), USB_DEVICE_SERIAL_NAME_SIZE), BOOTLOADER_SERIAL_MAX_SIZE)]; | ||
| 176 | }; | ||
| 177 | COMPILER_WORD_ALIGNED | ||
| 178 | static UDC_DESC_STORAGE struct udc_string_desc_t udc_string_desc = {.header.bDescriptorType = USB_DT_STRING}; | ||
| 179 | //! @} | ||
| 180 | |||
| 181 | usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void) { | ||
| 182 | return udc_ptr_iface; | ||
| 183 | } | ||
| 184 | |||
| 185 | /** | ||
| 186 | * \brief Returns a value to check the end of USB Configuration descriptor | ||
| 187 | * | ||
| 188 | * \return address after the last byte of USB Configuration descriptor | ||
| 189 | */ | ||
| 190 | static usb_conf_desc_t UDC_DESC_STORAGE *udc_get_eof_conf(void) { | ||
| 191 | return (UDC_DESC_STORAGE usb_conf_desc_t *)((uint8_t *)udc_ptr_conf->desc + le16_to_cpu(udc_ptr_conf->desc->wTotalLength)); | ||
| 192 | } | ||
| 193 | |||
| 194 | #if (0 != USB_DEVICE_MAX_EP) | ||
| 195 | /** | ||
| 196 | * \brief Search specific descriptor in global interface descriptor | ||
| 197 | * | ||
| 198 | * \param desc Address of interface descriptor | ||
| 199 | * or previous specific descriptor found | ||
| 200 | * \param desc_id Descriptor ID to search | ||
| 201 | * | ||
| 202 | * \return address of specific descriptor found | ||
| 203 | * \return NULL if it is the end of global interface descriptor | ||
| 204 | */ | ||
| 205 | static usb_conf_desc_t UDC_DESC_STORAGE *udc_next_desc_in_iface(usb_conf_desc_t UDC_DESC_STORAGE *desc, uint8_t desc_id) { | ||
| 206 | usb_conf_desc_t UDC_DESC_STORAGE *ptr_eof_desc; | ||
| 207 | |||
| 208 | ptr_eof_desc = udc_get_eof_conf(); | ||
| 209 | // Go to next descriptor | ||
| 210 | desc = (UDC_DESC_STORAGE usb_conf_desc_t *)((uint8_t *)desc + desc->bLength); | ||
| 211 | // Check the end of configuration descriptor | ||
| 212 | while (ptr_eof_desc > desc) { | ||
| 213 | // If new interface descriptor is found, | ||
| 214 | // then it is the end of the current global interface descriptor | ||
| 215 | if (USB_DT_INTERFACE == desc->bDescriptorType) { | ||
| 216 | break; // End of global interface descriptor | ||
| 217 | } | ||
| 218 | if (desc_id == desc->bDescriptorType) { | ||
| 219 | return desc; // Specific descriptor found | ||
| 220 | } | ||
| 221 | // Go to next descriptor | ||
| 222 | desc = (UDC_DESC_STORAGE usb_conf_desc_t *)((uint8_t *)desc + desc->bLength); | ||
| 223 | } | ||
| 224 | return NULL; // No specific descriptor found | ||
| 225 | } | ||
| 226 | #endif | ||
| 227 | |||
| 228 | /** | ||
| 229 | * \brief Search an interface descriptor | ||
| 230 | * This routine updates the internal pointer udc_ptr_iface. | ||
| 231 | * | ||
| 232 | * \param iface_num Interface number to find in Configuration Descriptor | ||
| 233 | * \param setting_num Setting number of interface to find | ||
| 234 | * | ||
| 235 | * \return 1 if found or 0 if not found | ||
| 236 | */ | ||
| 237 | static bool udc_update_iface_desc(uint8_t iface_num, uint8_t setting_num) { | ||
| 238 | usb_conf_desc_t UDC_DESC_STORAGE *ptr_end_desc; | ||
| 239 | |||
| 240 | if (0 == udc_num_configuration) { | ||
| 241 | return false; | ||
| 242 | } | ||
| 243 | |||
| 244 | if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { | ||
| 245 | return false; | ||
| 246 | } | ||
| 247 | |||
| 248 | // Start at the beginning of configuration descriptor | ||
| 249 | udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *)udc_ptr_conf->desc; | ||
| 250 | |||
| 251 | // Check the end of configuration descriptor | ||
| 252 | ptr_end_desc = udc_get_eof_conf(); | ||
| 253 | while (ptr_end_desc > (UDC_DESC_STORAGE usb_conf_desc_t *)udc_ptr_iface) { | ||
| 254 | if (USB_DT_INTERFACE == udc_ptr_iface->bDescriptorType) { | ||
| 255 | // A interface descriptor is found | ||
| 256 | // Check interface and alternate setting number | ||
| 257 | if ((iface_num == udc_ptr_iface->bInterfaceNumber) && (setting_num == udc_ptr_iface->bAlternateSetting)) { | ||
| 258 | return true; // Interface found | ||
| 259 | } | ||
| 260 | } | ||
| 261 | // Go to next descriptor | ||
| 262 | udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *)((uint8_t *)udc_ptr_iface + udc_ptr_iface->bLength); | ||
| 263 | } | ||
| 264 | return false; // Interface not found | ||
| 265 | } | ||
| 266 | |||
| 267 | /** | ||
| 268 | * \brief Disables an usb device interface (UDI) | ||
| 269 | * This routine call the UDI corresponding to interface number | ||
| 270 | * | ||
| 271 | * \param iface_num Interface number to disable | ||
| 272 | * | ||
| 273 | * \return 1 if it is done or 0 if interface is not found | ||
| 274 | */ | ||
| 275 | static bool udc_iface_disable(uint8_t iface_num) { | ||
| 276 | udi_api_t UDC_DESC_STORAGE *udi_api; | ||
| 277 | |||
| 278 | // Select first alternate setting of the interface | ||
| 279 | // to update udc_ptr_iface before call iface->getsetting() | ||
| 280 | if (!udc_update_iface_desc(iface_num, 0)) { | ||
| 281 | return false; | ||
| 282 | } | ||
| 283 | |||
| 284 | // Select the interface with the current alternate setting | ||
| 285 | udi_api = udc_ptr_conf->udi_apis[iface_num]; | ||
| 286 | |||
| 287 | #if (0 != USB_DEVICE_MAX_EP) | ||
| 288 | if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { | ||
| 289 | return false; | ||
| 290 | } | ||
| 291 | |||
| 292 | // Start at the beginning of interface descriptor | ||
| 293 | { | ||
| 294 | usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; | ||
| 295 | ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *)udc_ptr_iface; | ||
| 296 | while (1) { | ||
| 297 | // Search Endpoint descriptor included in global interface descriptor | ||
| 298 | ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *)udc_next_desc_in_iface((UDC_DESC_STORAGE usb_conf_desc_t *)ep_desc, USB_DT_ENDPOINT); | ||
| 299 | if (NULL == ep_desc) { | ||
| 300 | break; | ||
| 301 | } | ||
| 302 | // Free the endpoint used by the interface | ||
| 303 | udd_ep_free(ep_desc->bEndpointAddress); | ||
| 304 | } | ||
| 305 | } | ||
| 306 | #endif | ||
| 307 | |||
| 308 | // Disable interface | ||
| 309 | udi_api->disable(); | ||
| 310 | return true; | ||
| 311 | } | ||
| 312 | |||
| 313 | /** | ||
| 314 | * \brief Enables an usb device interface (UDI) | ||
| 315 | * This routine calls the UDI corresponding | ||
| 316 | * to the interface and setting number. | ||
| 317 | * | ||
| 318 | * \param iface_num Interface number to enable | ||
| 319 | * \param setting_num Setting number to enable | ||
| 320 | * | ||
| 321 | * \return 1 if it is done or 0 if interface is not found | ||
| 322 | */ | ||
| 323 | static bool udc_iface_enable(uint8_t iface_num, uint8_t setting_num) { | ||
| 324 | // Select the interface descriptor | ||
| 325 | if (!udc_update_iface_desc(iface_num, setting_num)) { | ||
| 326 | return false; | ||
| 327 | } | ||
| 328 | |||
| 329 | #if (0 != USB_DEVICE_MAX_EP) | ||
| 330 | usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; | ||
| 331 | |||
| 332 | // Start at the beginning of the global interface descriptor | ||
| 333 | ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *)udc_ptr_iface; | ||
| 334 | while (1) { | ||
| 335 | // Search Endpoint descriptor included in the global interface descriptor | ||
| 336 | ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *)udc_next_desc_in_iface((UDC_DESC_STORAGE usb_conf_desc_t *)ep_desc, USB_DT_ENDPOINT); | ||
| 337 | if (NULL == ep_desc) break; | ||
| 338 | // Alloc the endpoint used by the interface | ||
| 339 | if (!udd_ep_alloc(ep_desc->bEndpointAddress, ep_desc->bmAttributes, le16_to_cpu(ep_desc->wMaxPacketSize))) { | ||
| 340 | return false; | ||
| 341 | } | ||
| 342 | } | ||
| 343 | #endif | ||
| 344 | // Enable the interface | ||
| 345 | return udc_ptr_conf->udi_apis[iface_num]->enable(); | ||
| 346 | } | ||
| 347 | |||
| 348 | /*! \brief Start the USB Device stack | ||
| 349 | */ | ||
| 350 | void udc_start(void) { | ||
| 351 | udd_enable(); | ||
| 352 | } | ||
| 353 | |||
| 354 | /*! \brief Stop the USB Device stack | ||
| 355 | */ | ||
| 356 | void udc_stop(void) { | ||
| 357 | udd_disable(); | ||
| 358 | udc_reset(); | ||
| 359 | } | ||
| 360 | |||
| 361 | /** | ||
| 362 | * \brief Reset the current configuration of the USB device, | ||
| 363 | * This routines can be called by UDD when a RESET on the USB line occurs. | ||
| 364 | */ | ||
| 365 | void udc_reset(void) { | ||
| 366 | uint8_t iface_num; | ||
| 367 | |||
| 368 | if (udc_num_configuration) { | ||
| 369 | for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces; iface_num++) { | ||
| 370 | udc_iface_disable(iface_num); | ||
| 371 | } | ||
| 372 | } | ||
| 373 | udc_num_configuration = 0; | ||
| 374 | #if (USB_CONFIG_ATTR_REMOTE_WAKEUP == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) | ||
| 375 | if (CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP) & udc_device_status) { | ||
| 376 | // Remote wakeup is enabled then disable it | ||
| 377 | UDC_REMOTEWAKEUP_DISABLE(); | ||
| 378 | } | ||
| 379 | #endif | ||
| 380 | udc_device_status = | ||
| 381 | #if (USB_DEVICE_ATTR & USB_CONFIG_ATTR_SELF_POWERED) | ||
| 382 | CPU_TO_LE16(USB_DEV_STATUS_SELF_POWERED); | ||
| 383 | #else | ||
| 384 | CPU_TO_LE16(USB_DEV_STATUS_BUS_POWERED); | ||
| 385 | #endif | ||
| 386 | } | ||
| 387 | |||
| 388 | void udc_sof_notify(void) { | ||
| 389 | uint8_t iface_num; | ||
| 390 | |||
| 391 | if (udc_num_configuration) { | ||
| 392 | for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces; iface_num++) { | ||
| 393 | if (udc_ptr_conf->udi_apis[iface_num]->sof_notify != NULL) { | ||
| 394 | udc_ptr_conf->udi_apis[iface_num]->sof_notify(); | ||
| 395 | } | ||
| 396 | } | ||
| 397 | } | ||
| 398 | } | ||
| 399 | |||
| 400 | /** | ||
| 401 | * \brief Standard device request to get device status | ||
| 402 | * | ||
| 403 | * \return true if success | ||
| 404 | */ | ||
| 405 | static bool udc_req_std_dev_get_status(void) { | ||
| 406 | if (udd_g_ctrlreq.req.wLength != sizeof(udc_device_status)) { | ||
| 407 | return false; | ||
| 408 | } | ||
| 409 | |||
| 410 | udd_set_setup_payload((uint8_t *)&udc_device_status, sizeof(udc_device_status)); | ||
| 411 | return true; | ||
| 412 | } | ||
| 413 | |||
| 414 | #if (0 != USB_DEVICE_MAX_EP) | ||
| 415 | /** | ||
| 416 | * \brief Standard endpoint request to get endpoint status | ||
| 417 | * | ||
| 418 | * \return true if success | ||
| 419 | */ | ||
| 420 | static bool udc_req_std_ep_get_status(void) { | ||
| 421 | static le16_t udc_ep_status; | ||
| 422 | |||
| 423 | if (udd_g_ctrlreq.req.wLength != sizeof(udc_ep_status)) { | ||
| 424 | return false; | ||
| 425 | } | ||
| 426 | |||
| 427 | udc_ep_status = udd_ep_is_halted(udd_g_ctrlreq.req.wIndex & 0xFF) ? CPU_TO_LE16(USB_EP_STATUS_HALTED) : 0; | ||
| 428 | |||
| 429 | udd_set_setup_payload((uint8_t *)&udc_ep_status, sizeof(udc_ep_status)); | ||
| 430 | return true; | ||
| 431 | } | ||
| 432 | #endif | ||
| 433 | |||
| 434 | /** | ||
| 435 | * \brief Standard device request to change device status | ||
| 436 | * | ||
| 437 | * \return true if success | ||
| 438 | */ | ||
| 439 | static bool udc_req_std_dev_clear_feature(void) { | ||
| 440 | if (udd_g_ctrlreq.req.wLength) { | ||
| 441 | return false; | ||
| 442 | } | ||
| 443 | |||
| 444 | if (udd_g_ctrlreq.req.wValue == USB_DEV_FEATURE_REMOTE_WAKEUP) { | ||
| 445 | udc_device_status &= CPU_TO_LE16(~(uint32_t)USB_DEV_STATUS_REMOTEWAKEUP); | ||
| 446 | #if (USB_CONFIG_ATTR_REMOTE_WAKEUP == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) | ||
| 447 | UDC_REMOTEWAKEUP_DISABLE(); | ||
| 448 | #endif | ||
| 449 | return true; | ||
| 450 | } | ||
| 451 | return false; | ||
| 452 | } | ||
| 453 | |||
| 454 | #if (0 != USB_DEVICE_MAX_EP) | ||
| 455 | /** | ||
| 456 | * \brief Standard endpoint request to clear endpoint feature | ||
| 457 | * | ||
| 458 | * \return true if success | ||
| 459 | */ | ||
| 460 | static bool udc_req_std_ep_clear_feature(void) { | ||
| 461 | if (udd_g_ctrlreq.req.wLength) { | ||
| 462 | return false; | ||
| 463 | } | ||
| 464 | |||
| 465 | if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { | ||
| 466 | return udd_ep_clear_halt(udd_g_ctrlreq.req.wIndex & 0xFF); | ||
| 467 | } | ||
| 468 | return false; | ||
| 469 | } | ||
| 470 | #endif | ||
| 471 | |||
| 472 | /** | ||
| 473 | * \brief Standard device request to set a feature | ||
| 474 | * | ||
| 475 | * \return true if success | ||
| 476 | */ | ||
| 477 | static bool udc_req_std_dev_set_feature(void) { | ||
| 478 | if (udd_g_ctrlreq.req.wLength) { | ||
| 479 | return false; | ||
| 480 | } | ||
| 481 | |||
| 482 | switch (udd_g_ctrlreq.req.wValue) { | ||
| 483 | case USB_DEV_FEATURE_REMOTE_WAKEUP: | ||
| 484 | #if (USB_CONFIG_ATTR_REMOTE_WAKEUP == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) | ||
| 485 | udc_device_status |= CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP); | ||
| 486 | UDC_REMOTEWAKEUP_ENABLE(); | ||
| 487 | return true; | ||
| 488 | #else | ||
| 489 | return false; | ||
| 490 | #endif | ||
| 491 | |||
| 492 | #ifdef USB_DEVICE_HS_SUPPORT | ||
| 493 | case USB_DEV_FEATURE_TEST_MODE: | ||
| 494 | if (!udd_is_high_speed()) { | ||
| 495 | break; | ||
| 496 | } | ||
| 497 | if (udd_g_ctrlreq.req.wIndex & 0xff) { | ||
| 498 | break; | ||
| 499 | } | ||
| 500 | // Unconfigure the device, terminating all ongoing requests | ||
| 501 | udc_reset(); | ||
| 502 | switch ((udd_g_ctrlreq.req.wIndex >> 8) & 0xFF) { | ||
| 503 | case USB_DEV_TEST_MODE_J: | ||
| 504 | udd_g_ctrlreq.callback = udd_test_mode_j; | ||
| 505 | return true; | ||
| 506 | |||
| 507 | case USB_DEV_TEST_MODE_K: | ||
| 508 | udd_g_ctrlreq.callback = udd_test_mode_k; | ||
| 509 | return true; | ||
| 510 | |||
| 511 | case USB_DEV_TEST_MODE_SE0_NAK: | ||
| 512 | udd_g_ctrlreq.callback = udd_test_mode_se0_nak; | ||
| 513 | return true; | ||
| 514 | |||
| 515 | case USB_DEV_TEST_MODE_PACKET: | ||
| 516 | udd_g_ctrlreq.callback = udd_test_mode_packet; | ||
| 517 | return true; | ||
| 518 | |||
| 519 | case USB_DEV_TEST_MODE_FORCE_ENABLE: // Only for downstream facing hub ports | ||
| 520 | default: | ||
| 521 | break; | ||
| 522 | } | ||
| 523 | break; | ||
| 524 | #endif | ||
| 525 | default: | ||
| 526 | break; | ||
| 527 | } | ||
| 528 | return false; | ||
| 529 | } | ||
| 530 | |||
| 531 | /** | ||
| 532 | * \brief Standard endpoint request to halt an endpoint | ||
| 533 | * | ||
| 534 | * \return true if success | ||
| 535 | */ | ||
| 536 | #if (0 != USB_DEVICE_MAX_EP) | ||
| 537 | static bool udc_req_std_ep_set_feature(void) { | ||
| 538 | if (udd_g_ctrlreq.req.wLength) { | ||
| 539 | return false; | ||
| 540 | } | ||
| 541 | if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { | ||
| 542 | udd_ep_abort(udd_g_ctrlreq.req.wIndex & 0xFF); | ||
| 543 | return udd_ep_set_halt(udd_g_ctrlreq.req.wIndex & 0xFF); | ||
| 544 | } | ||
| 545 | return false; | ||
| 546 | } | ||
| 547 | #endif | ||
| 548 | |||
| 549 | /** | ||
| 550 | * \brief Change the address of device | ||
| 551 | * Callback called at the end of request set address | ||
| 552 | */ | ||
| 553 | static void udc_valid_address(void) { | ||
| 554 | udd_set_address(udd_g_ctrlreq.req.wValue & 0x7F); | ||
| 555 | } | ||
| 556 | |||
| 557 | /** | ||
| 558 | * \brief Standard device request to set device address | ||
| 559 | * | ||
| 560 | * \return true if success | ||
| 561 | */ | ||
| 562 | static bool udc_req_std_dev_set_address(void) { | ||
| 563 | if (udd_g_ctrlreq.req.wLength) { | ||
| 564 | return false; | ||
| 565 | } | ||
| 566 | |||
| 567 | // The address must be changed at the end of setup request after the handshake | ||
| 568 | // then we use a callback to change address | ||
| 569 | udd_g_ctrlreq.callback = udc_valid_address; | ||
| 570 | return true; | ||
| 571 | } | ||
| 572 | |||
| 573 | /** | ||
| 574 | * \brief Standard device request to get device string descriptor | ||
| 575 | * | ||
| 576 | * \return true if success | ||
| 577 | */ | ||
| 578 | static bool udc_req_std_dev_get_str_desc(void) { | ||
| 579 | uint8_t i; | ||
| 580 | const uint8_t *str; | ||
| 581 | uint8_t str_length = 0; | ||
| 582 | |||
| 583 | // Link payload pointer to the string corresponding at request | ||
| 584 | switch (udd_g_ctrlreq.req.wValue & 0xff) { | ||
| 585 | case 0: | ||
| 586 | udd_set_setup_payload((uint8_t *)&udc_string_desc_languageid, sizeof(udc_string_desc_languageid)); | ||
| 587 | break; | ||
| 588 | |||
| 589 | #ifdef USB_DEVICE_MANUFACTURE_NAME | ||
| 590 | case 1: | ||
| 591 | str_length = USB_DEVICE_MANUFACTURE_NAME_SIZE; | ||
| 592 | str = udc_string_manufacturer_name; | ||
| 593 | break; | ||
| 594 | #endif | ||
| 595 | #ifdef USB_DEVICE_PRODUCT_NAME | ||
| 596 | case 2: | ||
| 597 | str_length = USB_DEVICE_PRODUCT_NAME_SIZE; | ||
| 598 | str = udc_string_product_name; | ||
| 599 | break; | ||
| 600 | #endif | ||
| 601 | case 3: | ||
| 602 | str = udc_get_string_serial_name(); | ||
| 603 | str_length = usb_device_serial_name_size; | ||
| 604 | break; | ||
| 605 | default: | ||
| 606 | #ifdef UDC_GET_EXTRA_STRING | ||
| 607 | if (UDC_GET_EXTRA_STRING()) { | ||
| 608 | break; | ||
| 609 | } | ||
| 610 | #endif | ||
| 611 | return false; | ||
| 612 | } | ||
| 613 | |||
| 614 | if (str_length) { | ||
| 615 | for (i = 0; i < str_length; i++) { | ||
| 616 | udc_string_desc.string[i] = cpu_to_le16((le16_t)str[i]); | ||
| 617 | } | ||
| 618 | |||
| 619 | udc_string_desc.header.bLength = 2 + (str_length)*2; | ||
| 620 | udd_set_setup_payload((uint8_t *)&udc_string_desc, udc_string_desc.header.bLength); | ||
| 621 | } | ||
| 622 | |||
| 623 | return true; | ||
| 624 | } | ||
| 625 | |||
| 626 | /** | ||
| 627 | * \brief Standard device request to get descriptors about USB device | ||
| 628 | * | ||
| 629 | * \return true if success | ||
| 630 | */ | ||
| 631 | static bool udc_req_std_dev_get_descriptor(void) { | ||
| 632 | uint8_t conf_num; | ||
| 633 | |||
| 634 | conf_num = udd_g_ctrlreq.req.wValue & 0xff; | ||
| 635 | |||
| 636 | // Check descriptor ID | ||
| 637 | switch ((uint8_t)(udd_g_ctrlreq.req.wValue >> 8)) { | ||
| 638 | case USB_DT_DEVICE: | ||
| 639 | // Device descriptor requested | ||
| 640 | #ifdef USB_DEVICE_HS_SUPPORT | ||
| 641 | if (!udd_is_high_speed()) { | ||
| 642 | udd_set_setup_payload((uint8_t *)udc_config.confdev_hs, udc_config.confdev_hs->bLength); | ||
| 643 | } else | ||
| 644 | #endif | ||
| 645 | { | ||
| 646 | udd_set_setup_payload((uint8_t *)udc_config.confdev_lsfs, udc_config.confdev_lsfs->bLength); | ||
| 647 | } | ||
| 648 | break; | ||
| 649 | |||
| 650 | case USB_DT_CONFIGURATION: | ||
| 651 | // Configuration descriptor requested | ||
| 652 | #ifdef USB_DEVICE_HS_SUPPORT | ||
| 653 | if (udd_is_high_speed()) { | ||
| 654 | // HS descriptor | ||
| 655 | if (conf_num >= udc_config.confdev_hs->bNumConfigurations) { | ||
| 656 | return false; | ||
| 657 | } | ||
| 658 | udd_set_setup_payload((uint8_t *)udc_config.conf_hs[conf_num].desc, le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); | ||
| 659 | } else | ||
| 660 | #endif | ||
| 661 | { | ||
| 662 | // FS descriptor | ||
| 663 | if (conf_num >= udc_config.confdev_lsfs->bNumConfigurations) { | ||
| 664 | return false; | ||
| 665 | } | ||
| 666 | udd_set_setup_payload((uint8_t *)udc_config.conf_lsfs[conf_num].desc, le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); | ||
| 667 | } | ||
| 668 | ((usb_conf_desc_t *)udd_g_ctrlreq.payload)->bDescriptorType = USB_DT_CONFIGURATION; | ||
| 669 | break; | ||
| 670 | |||
| 671 | #ifdef USB_DEVICE_HS_SUPPORT | ||
| 672 | case USB_DT_DEVICE_QUALIFIER: | ||
| 673 | // Device qualifier descriptor requested | ||
| 674 | udd_set_setup_payload((uint8_t *)udc_config.qualifier, udc_config.qualifier->bLength); | ||
| 675 | break; | ||
| 676 | |||
| 677 | case USB_DT_OTHER_SPEED_CONFIGURATION: | ||
| 678 | // Other configuration descriptor requested | ||
| 679 | if (!udd_is_high_speed()) { | ||
| 680 | // HS descriptor | ||
| 681 | if (conf_num >= udc_config.confdev_hs->bNumConfigurations) { | ||
| 682 | return false; | ||
| 683 | } | ||
| 684 | udd_set_setup_payload((uint8_t *)udc_config.conf_hs[conf_num].desc, le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); | ||
| 685 | } else { | ||
| 686 | // FS descriptor | ||
| 687 | if (conf_num >= udc_config.confdev_lsfs->bNumConfigurations) { | ||
| 688 | return false; | ||
| 689 | } | ||
| 690 | udd_set_setup_payload((uint8_t *)udc_config.conf_lsfs[conf_num].desc, le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); | ||
| 691 | } | ||
| 692 | ((usb_conf_desc_t *)udd_g_ctrlreq.payload)->bDescriptorType = USB_DT_OTHER_SPEED_CONFIGURATION; | ||
| 693 | break; | ||
| 694 | #endif | ||
| 695 | |||
| 696 | case USB_DT_BOS: | ||
| 697 | // Device BOS descriptor requested | ||
| 698 | if (udc_config.conf_bos == NULL) { | ||
| 699 | return false; | ||
| 700 | } | ||
| 701 | udd_set_setup_payload((uint8_t *)udc_config.conf_bos, udc_config.conf_bos->wTotalLength); | ||
| 702 | break; | ||
| 703 | |||
| 704 | case USB_DT_STRING: | ||
| 705 | // String descriptor requested | ||
| 706 | if (!udc_req_std_dev_get_str_desc()) { | ||
| 707 | return false; | ||
| 708 | } | ||
| 709 | break; | ||
| 710 | |||
| 711 | default: | ||
| 712 | // Unknown descriptor requested | ||
| 713 | return false; | ||
| 714 | } | ||
| 715 | // if the descriptor is larger than length requested, then reduce it | ||
| 716 | if (udd_g_ctrlreq.req.wLength < udd_g_ctrlreq.payload_size) { | ||
| 717 | udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength; | ||
| 718 | } | ||
| 719 | return true; | ||
| 720 | } | ||
| 721 | |||
| 722 | /** | ||
| 723 | * \brief Standard device request to get configuration number | ||
| 724 | * | ||
| 725 | * \return true if success | ||
| 726 | */ | ||
| 727 | static bool udc_req_std_dev_get_configuration(void) { | ||
| 728 | if (udd_g_ctrlreq.req.wLength != 1) { | ||
| 729 | return false; | ||
| 730 | } | ||
| 731 | |||
| 732 | udd_set_setup_payload(&udc_num_configuration, 1); | ||
| 733 | return true; | ||
| 734 | } | ||
| 735 | |||
| 736 | /** | ||
| 737 | * \brief Standard device request to enable a configuration | ||
| 738 | * | ||
| 739 | * \return true if success | ||
| 740 | */ | ||
| 741 | static bool udc_req_std_dev_set_configuration(void) { | ||
| 742 | uint8_t iface_num; | ||
| 743 | |||
| 744 | // Check request length | ||
| 745 | if (udd_g_ctrlreq.req.wLength) { | ||
| 746 | return false; | ||
| 747 | } | ||
| 748 | // Authorize configuration only if the address is valid | ||
| 749 | if (!udd_getaddress()) { | ||
| 750 | return false; | ||
| 751 | } | ||
| 752 | // Check the configuration number requested | ||
| 753 | #ifdef USB_DEVICE_HS_SUPPORT | ||
| 754 | if (udd_is_high_speed()) { | ||
| 755 | // HS descriptor | ||
| 756 | if ((udd_g_ctrlreq.req.wValue & 0xFF) > udc_config.confdev_hs->bNumConfigurations) { | ||
| 757 | return false; | ||
| 758 | } | ||
| 759 | } else | ||
| 760 | #endif | ||
| 761 | { | ||
| 762 | // FS descriptor | ||
| 763 | if ((udd_g_ctrlreq.req.wValue & 0xFF) > udc_config.confdev_lsfs->bNumConfigurations) { | ||
| 764 | return false; | ||
| 765 | } | ||
| 766 | } | ||
| 767 | |||
| 768 | // Reset current configuration | ||
| 769 | udc_reset(); | ||
| 770 | |||
| 771 | // Enable new configuration | ||
| 772 | udc_num_configuration = udd_g_ctrlreq.req.wValue & 0xFF; | ||
| 773 | if (udc_num_configuration == 0) { | ||
| 774 | return true; // Default empty configuration requested | ||
| 775 | } | ||
| 776 | // Update pointer of the configuration descriptor | ||
| 777 | #ifdef USB_DEVICE_HS_SUPPORT | ||
| 778 | if (udd_is_high_speed()) { | ||
| 779 | // HS descriptor | ||
| 780 | udc_ptr_conf = &udc_config.conf_hs[udc_num_configuration - 1]; | ||
| 781 | } else | ||
| 782 | #endif | ||
| 783 | { | ||
| 784 | // FS descriptor | ||
| 785 | udc_ptr_conf = &udc_config.conf_lsfs[udc_num_configuration - 1]; | ||
| 786 | } | ||
| 787 | // Enable all interfaces of the selected configuration | ||
| 788 | for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces; iface_num++) { | ||
| 789 | if (!udc_iface_enable(iface_num, 0)) { | ||
| 790 | return false; | ||
| 791 | } | ||
| 792 | } | ||
| 793 | return true; | ||
| 794 | } | ||
| 795 | |||
| 796 | /** | ||
| 797 | * \brief Standard interface request | ||
| 798 | * to get the alternate setting number of an interface | ||
| 799 | * | ||
| 800 | * \return true if success | ||
| 801 | */ | ||
| 802 | static bool udc_req_std_iface_get_setting(void) { | ||
| 803 | uint8_t iface_num; | ||
| 804 | udi_api_t UDC_DESC_STORAGE *udi_api; | ||
| 805 | |||
| 806 | if (udd_g_ctrlreq.req.wLength != 1) { | ||
| 807 | return false; // Error in request | ||
| 808 | } | ||
| 809 | if (!udc_num_configuration) { | ||
| 810 | return false; // The device is not is configured state yet | ||
| 811 | } | ||
| 812 | |||
| 813 | // Check the interface number included in the request | ||
| 814 | iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; | ||
| 815 | if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { | ||
| 816 | return false; | ||
| 817 | } | ||
| 818 | |||
| 819 | // Select first alternate setting of the interface to update udc_ptr_iface | ||
| 820 | // before call iface->getsetting() | ||
| 821 | if (!udc_update_iface_desc(iface_num, 0)) { | ||
| 822 | return false; | ||
| 823 | } | ||
| 824 | // Get alternate setting from UDI | ||
| 825 | udi_api = udc_ptr_conf->udi_apis[iface_num]; | ||
| 826 | udc_iface_setting = udi_api->getsetting(); | ||
| 827 | |||
| 828 | // Link value to payload pointer of request | ||
| 829 | udd_set_setup_payload(&udc_iface_setting, 1); | ||
| 830 | return true; | ||
| 831 | } | ||
| 832 | |||
| 833 | /** | ||
| 834 | * \brief Standard interface request | ||
| 835 | * to set an alternate setting of an interface | ||
| 836 | * | ||
| 837 | * \return true if success | ||
| 838 | */ | ||
| 839 | static bool udc_req_std_iface_set_setting(void) { | ||
| 840 | uint8_t iface_num, setting_num; | ||
| 841 | |||
| 842 | if (udd_g_ctrlreq.req.wLength) { | ||
| 843 | return false; // Error in request | ||
| 844 | } | ||
| 845 | if (!udc_num_configuration) { | ||
| 846 | return false; // The device is not is configured state yet | ||
| 847 | } | ||
| 848 | |||
| 849 | iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; | ||
| 850 | setting_num = udd_g_ctrlreq.req.wValue & 0xFF; | ||
| 851 | |||
| 852 | // Disable current setting | ||
| 853 | if (!udc_iface_disable(iface_num)) { | ||
| 854 | return false; | ||
| 855 | } | ||
| 856 | |||
| 857 | // Enable new setting | ||
| 858 | return udc_iface_enable(iface_num, setting_num); | ||
| 859 | } | ||
| 860 | |||
| 861 | /** | ||
| 862 | * \brief Main routine to manage the standard USB SETUP request | ||
| 863 | * | ||
| 864 | * \return true if the request is supported | ||
| 865 | */ | ||
| 866 | static bool udc_reqstd(void) { | ||
| 867 | if (Udd_setup_is_in()) { | ||
| 868 | // GET Standard Requests | ||
| 869 | if (udd_g_ctrlreq.req.wLength == 0) { | ||
| 870 | return false; // Error for USB host | ||
| 871 | } | ||
| 872 | |||
| 873 | if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { | ||
| 874 | // Standard Get Device request | ||
| 875 | switch (udd_g_ctrlreq.req.bRequest) { | ||
| 876 | case USB_REQ_GET_STATUS: | ||
| 877 | return udc_req_std_dev_get_status(); | ||
| 878 | case USB_REQ_GET_DESCRIPTOR: | ||
| 879 | return udc_req_std_dev_get_descriptor(); | ||
| 880 | case USB_REQ_GET_CONFIGURATION: | ||
| 881 | return udc_req_std_dev_get_configuration(); | ||
| 882 | default: | ||
| 883 | break; | ||
| 884 | } | ||
| 885 | } | ||
| 886 | |||
| 887 | if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { | ||
| 888 | // Standard Get Interface request | ||
| 889 | switch (udd_g_ctrlreq.req.bRequest) { | ||
| 890 | case USB_REQ_GET_INTERFACE: | ||
| 891 | return udc_req_std_iface_get_setting(); | ||
| 892 | default: | ||
| 893 | break; | ||
| 894 | } | ||
| 895 | } | ||
| 896 | #if (0 != USB_DEVICE_MAX_EP) | ||
| 897 | if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { | ||
| 898 | // Standard Get Endpoint request | ||
| 899 | switch (udd_g_ctrlreq.req.bRequest) { | ||
| 900 | case USB_REQ_GET_STATUS: | ||
| 901 | return udc_req_std_ep_get_status(); | ||
| 902 | default: | ||
| 903 | break; | ||
| 904 | } | ||
| 905 | } | ||
| 906 | #endif | ||
| 907 | } else { | ||
| 908 | // SET Standard Requests | ||
| 909 | if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { | ||
| 910 | // Standard Set Device request | ||
| 911 | switch (udd_g_ctrlreq.req.bRequest) { | ||
| 912 | case USB_REQ_SET_ADDRESS: | ||
| 913 | return udc_req_std_dev_set_address(); | ||
| 914 | case USB_REQ_CLEAR_FEATURE: | ||
| 915 | return udc_req_std_dev_clear_feature(); | ||
| 916 | case USB_REQ_SET_FEATURE: | ||
| 917 | return udc_req_std_dev_set_feature(); | ||
| 918 | case USB_REQ_SET_CONFIGURATION: | ||
| 919 | return udc_req_std_dev_set_configuration(); | ||
| 920 | case USB_REQ_SET_DESCRIPTOR: | ||
| 921 | /* Not supported (defined as optional by the USB 2.0 spec) */ | ||
| 922 | break; | ||
| 923 | default: | ||
| 924 | break; | ||
| 925 | } | ||
| 926 | } | ||
| 927 | |||
| 928 | if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { | ||
| 929 | // Standard Set Interface request | ||
| 930 | switch (udd_g_ctrlreq.req.bRequest) { | ||
| 931 | case USB_REQ_SET_INTERFACE: | ||
| 932 | return udc_req_std_iface_set_setting(); | ||
| 933 | default: | ||
| 934 | break; | ||
| 935 | } | ||
| 936 | } | ||
| 937 | #if (0 != USB_DEVICE_MAX_EP) | ||
| 938 | if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { | ||
| 939 | // Standard Set Endpoint request | ||
| 940 | switch (udd_g_ctrlreq.req.bRequest) { | ||
| 941 | case USB_REQ_CLEAR_FEATURE: | ||
| 942 | return udc_req_std_ep_clear_feature(); | ||
| 943 | case USB_REQ_SET_FEATURE: | ||
| 944 | return udc_req_std_ep_set_feature(); | ||
| 945 | default: | ||
| 946 | break; | ||
| 947 | } | ||
| 948 | } | ||
| 949 | #endif | ||
| 950 | } | ||
| 951 | return false; | ||
| 952 | } | ||
| 953 | |||
| 954 | /** | ||
| 955 | * \brief Send the SETUP interface request to UDI | ||
| 956 | * | ||
| 957 | * \return true if the request is supported | ||
| 958 | */ | ||
| 959 | static bool udc_req_iface(void) { | ||
| 960 | uint8_t iface_num; | ||
| 961 | udi_api_t UDC_DESC_STORAGE *udi_api; | ||
| 962 | |||
| 963 | if (0 == udc_num_configuration) { | ||
| 964 | return false; // The device is not is configured state yet | ||
| 965 | } | ||
| 966 | // Check interface number | ||
| 967 | iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; | ||
| 968 | if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { | ||
| 969 | return false; | ||
| 970 | } | ||
| 971 | |||
| 972 | //* To update udc_ptr_iface with the selected interface in request | ||
| 973 | // Select first alternate setting of interface to update udc_ptr_iface | ||
| 974 | // before calling udi_api->getsetting() | ||
| 975 | if (!udc_update_iface_desc(iface_num, 0)) { | ||
| 976 | return false; | ||
| 977 | } | ||
| 978 | // Select the interface with the current alternate setting | ||
| 979 | udi_api = udc_ptr_conf->udi_apis[iface_num]; | ||
| 980 | if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { | ||
| 981 | return false; | ||
| 982 | } | ||
| 983 | |||
| 984 | // Send the SETUP request to the UDI corresponding to the interface number | ||
| 985 | return udi_api->setup(); | ||
| 986 | } | ||
| 987 | |||
| 988 | /** | ||
| 989 | * \brief Send the SETUP interface request to UDI | ||
| 990 | * | ||
| 991 | * \return true if the request is supported | ||
| 992 | */ | ||
| 993 | static bool udc_req_ep(void) { | ||
| 994 | uint8_t iface_num; | ||
| 995 | udi_api_t UDC_DESC_STORAGE *udi_api; | ||
| 996 | |||
| 997 | if (0 == udc_num_configuration) { | ||
| 998 | return false; // The device is not is configured state yet | ||
| 999 | } | ||
| 1000 | // Send this request on all enabled interfaces | ||
| 1001 | iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; | ||
| 1002 | for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces; iface_num++) { | ||
| 1003 | // Select the interface with the current alternate setting | ||
| 1004 | udi_api = udc_ptr_conf->udi_apis[iface_num]; | ||
| 1005 | if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { | ||
| 1006 | return false; | ||
| 1007 | } | ||
| 1008 | |||
| 1009 | // Send the SETUP request to the UDI | ||
| 1010 | if (udi_api->setup()) { | ||
| 1011 | return true; | ||
| 1012 | } | ||
| 1013 | } | ||
| 1014 | return false; | ||
| 1015 | } | ||
| 1016 | |||
| 1017 | /** | ||
| 1018 | * \brief Main routine to manage the USB SETUP request. | ||
| 1019 | * | ||
| 1020 | * This function parses a USB SETUP request and submits an appropriate | ||
| 1021 | * response back to the host or, in the case of SETUP OUT requests | ||
| 1022 | * with data, sets up a buffer for receiving the data payload. | ||
| 1023 | * | ||
| 1024 | * The main standard requests defined by the USB 2.0 standard are handled | ||
| 1025 | * internally. The interface requests are sent to UDI, and the specific request | ||
| 1026 | * sent to a specific application callback. | ||
| 1027 | * | ||
| 1028 | * \return true if the request is supported, else the request is stalled by UDD | ||
| 1029 | */ | ||
| 1030 | bool udc_process_setup(void) { | ||
| 1031 | // By default no data (receive/send) and no callbacks registered | ||
| 1032 | udd_g_ctrlreq.payload_size = 0; | ||
| 1033 | udd_g_ctrlreq.callback = NULL; | ||
| 1034 | udd_g_ctrlreq.over_under_run = NULL; | ||
| 1035 | |||
| 1036 | if (Udd_setup_is_in()) { | ||
| 1037 | if (udd_g_ctrlreq.req.wLength == 0) { | ||
| 1038 | return false; // Error from USB host | ||
| 1039 | } | ||
| 1040 | } | ||
| 1041 | |||
| 1042 | // If standard request then try to decode it in UDC | ||
| 1043 | if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) { | ||
| 1044 | if (udc_reqstd()) { | ||
| 1045 | return true; | ||
| 1046 | } | ||
| 1047 | } | ||
| 1048 | |||
| 1049 | // If interface request then try to decode it in UDI | ||
| 1050 | if (Udd_setup_recipient() == USB_REQ_RECIP_INTERFACE) { | ||
| 1051 | if (udc_req_iface()) { | ||
| 1052 | return true; | ||
| 1053 | } | ||
| 1054 | } | ||
| 1055 | |||
| 1056 | // If endpoint request then try to decode it in UDI | ||
| 1057 | if (Udd_setup_recipient() == USB_REQ_RECIP_ENDPOINT) { | ||
| 1058 | if (udc_req_ep()) { | ||
| 1059 | return true; | ||
| 1060 | } | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | // Here SETUP request unknown by UDC and UDIs | ||
| 1064 | #ifdef USB_DEVICE_SPECIFIC_REQUEST | ||
| 1065 | // Try to decode it in specific callback | ||
| 1066 | return USB_DEVICE_SPECIFIC_REQUEST(); // Ex: Vendor request,... | ||
| 1067 | #else | ||
| 1068 | return false; | ||
| 1069 | #endif | ||
| 1070 | } | ||
| 1071 | |||
| 1072 | //! @} | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/udc.h b/tmk_core/protocol/arm_atsam/usb/udc.h deleted file mode 100644 index f2144059eb..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/udc.h +++ /dev/null | |||
| @@ -1,256 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief Interface of the USB Device Controller (UDC) | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #ifndef _UDC_H_ | ||
| 48 | #define _UDC_H_ | ||
| 49 | |||
| 50 | #include "conf_usb.h" | ||
| 51 | #include "usb_protocol.h" | ||
| 52 | #include "udc_desc.h" | ||
| 53 | #include "udd.h" | ||
| 54 | |||
| 55 | #if USB_DEVICE_VENDOR_ID == 0 | ||
| 56 | # error USB_DEVICE_VENDOR_ID cannot be equal to 0 | ||
| 57 | #endif | ||
| 58 | |||
| 59 | #if USB_DEVICE_PRODUCT_ID == 0 | ||
| 60 | # error USB_DEVICE_PRODUCT_ID cannot be equal to 0 | ||
| 61 | #endif | ||
| 62 | |||
| 63 | #ifdef __cplusplus | ||
| 64 | extern "C" { | ||
| 65 | #endif | ||
| 66 | |||
| 67 | /** | ||
| 68 | * \ingroup usb_device_group | ||
| 69 | * \defgroup udc_group USB Device Controller (UDC) | ||
| 70 | * | ||
| 71 | * The UDC provides a high-level abstraction of the usb device. | ||
| 72 | * You can use these functions to control the main device state | ||
| 73 | * (start/attach/wakeup). | ||
| 74 | * | ||
| 75 | * \section USB_DEVICE_CONF USB Device Custom configuration | ||
| 76 | * The following USB Device configuration must be included in the conf_usb.h | ||
| 77 | * file of the application. | ||
| 78 | * | ||
| 79 | * USB_DEVICE_VENDOR_ID (Word)<br> | ||
| 80 | * Vendor ID provided by USB org (ATMEL 0x03EB). | ||
| 81 | * | ||
| 82 | * USB_DEVICE_PRODUCT_ID (Word)<br> | ||
| 83 | * Product ID (Referenced in usb_atmel.h). | ||
| 84 | * | ||
| 85 | * USB_DEVICE_MAJOR_VERSION (Byte)<br> | ||
| 86 | * Major version of the device | ||
| 87 | * | ||
| 88 | * USB_DEVICE_MINOR_VERSION (Byte)<br> | ||
| 89 | * Minor version of the device | ||
| 90 | * | ||
| 91 | * USB_DEVICE_MANUFACTURE_NAME (string)<br> | ||
| 92 | * ASCII name for the manufacture | ||
| 93 | * | ||
| 94 | * USB_DEVICE_PRODUCT_NAME (string)<br> | ||
| 95 | * ASCII name for the product | ||
| 96 | * | ||
| 97 | * USB_DEVICE_SERIAL_NAME (string)<br> | ||
| 98 | * ASCII name to enable and set a serial number | ||
| 99 | * | ||
| 100 | * USB_DEVICE_POWER (Numeric)<br> | ||
| 101 | * (unit mA) Maximum device power | ||
| 102 | * | ||
| 103 | * USB_DEVICE_ATTR (Byte)<br> | ||
| 104 | * USB attributes available: | ||
| 105 | * - USB_CONFIG_ATTR_SELF_POWERED | ||
| 106 | * - USB_CONFIG_ATTR_REMOTE_WAKEUP | ||
| 107 | * Note: if remote wake enabled then defines remotewakeup callbacks, | ||
| 108 | * see Table 5-2. External API from UDC - Callback | ||
| 109 | * | ||
| 110 | * USB_DEVICE_LOW_SPEED (Only defined)<br> | ||
| 111 | * Force the USB Device to run in low speed | ||
| 112 | * | ||
| 113 | * USB_DEVICE_HS_SUPPORT (Only defined)<br> | ||
| 114 | * Authorize the USB Device to run in high speed | ||
| 115 | * | ||
| 116 | * USB_DEVICE_MAX_EP (Byte)<br> | ||
| 117 | * Define the maximum endpoint number used by the USB Device.<br> | ||
| 118 | * This one is already defined in UDI default configuration. | ||
| 119 | * Ex: | ||
| 120 | * - When endpoint control 0x00, endpoint 0x01 and | ||
| 121 | * endpoint 0x82 is used then USB_DEVICE_MAX_EP=2 | ||
| 122 | * - When only endpoint control 0x00 is used then USB_DEVICE_MAX_EP=0 | ||
| 123 | * - When endpoint 0x01 and endpoint 0x81 is used then USB_DEVICE_MAX_EP=1<br> | ||
| 124 | * (configuration not possible on USBB interface) | ||
| 125 | * @{ | ||
| 126 | */ | ||
| 127 | |||
| 128 | /** | ||
| 129 | * \brief Authorizes the VBUS event | ||
| 130 | * | ||
| 131 | * \return true, if the VBUS monitoring is possible. | ||
| 132 | * | ||
| 133 | * \section udc_vbus_monitoring VBus monitoring used cases | ||
| 134 | * | ||
| 135 | * The VBus monitoring is used only for USB SELF Power application. | ||
| 136 | * | ||
| 137 | * - By default the USB device is automatically attached when Vbus is high | ||
| 138 | * or when USB is start for devices without internal Vbus monitoring. | ||
| 139 | * conf_usb.h file does not contains define USB_DEVICE_ATTACH_AUTO_DISABLE. | ||
| 140 | * \code //#define USB_DEVICE_ATTACH_AUTO_DISABLE \endcode | ||
| 141 | * | ||
| 142 | * - Add custom VBUS monitoring. conf_usb.h file contains define | ||
| 143 | * USB_DEVICE_ATTACH_AUTO_DISABLE: | ||
| 144 | * \code #define USB_DEVICE_ATTACH_AUTO_DISABLE \endcode | ||
| 145 | * User C file contains: | ||
| 146 | * \code | ||
| 147 | // Authorize VBUS monitoring | ||
| 148 | if (!udc_include_vbus_monitoring()) { | ||
| 149 | // Implement custom VBUS monitoring via GPIO or other | ||
| 150 | } | ||
| 151 | Event_VBUS_present() // VBUS interrupt or GPIO interrupt or other | ||
| 152 | { | ||
| 153 | // Attach USB Device | ||
| 154 | udc_attach(); | ||
| 155 | } | ||
| 156 | \endcode | ||
| 157 | * | ||
| 158 | * - Case of battery charging. conf_usb.h file contains define | ||
| 159 | * USB_DEVICE_ATTACH_AUTO_DISABLE: | ||
| 160 | * \code #define USB_DEVICE_ATTACH_AUTO_DISABLE \endcode | ||
| 161 | * User C file contains: | ||
| 162 | * \code | ||
| 163 | Event VBUS present() // VBUS interrupt or GPIO interrupt or .. | ||
| 164 | { | ||
| 165 | // Authorize battery charging, but wait key press to start USB. | ||
| 166 | } | ||
| 167 | Event Key press() | ||
| 168 | { | ||
| 169 | // Stop batteries charging | ||
| 170 | // Start USB | ||
| 171 | udc_attach(); | ||
| 172 | } | ||
| 173 | \endcode | ||
| 174 | */ | ||
| 175 | static inline bool udc_include_vbus_monitoring(void) { | ||
| 176 | return udd_include_vbus_monitoring(); | ||
| 177 | } | ||
| 178 | |||
| 179 | /*! \brief Start the USB Device stack | ||
| 180 | */ | ||
| 181 | void udc_start(void); | ||
| 182 | |||
| 183 | /*! \brief Stop the USB Device stack | ||
| 184 | */ | ||
| 185 | void udc_stop(void); | ||
| 186 | |||
| 187 | /** | ||
| 188 | * \brief Attach device to the bus when possible | ||
| 189 | * | ||
| 190 | * \warning If a VBus control is included in driver, | ||
| 191 | * then it will attach device when an acceptable Vbus | ||
| 192 | * level from the host is detected. | ||
| 193 | */ | ||
| 194 | static inline void udc_attach(void) { | ||
| 195 | udd_attach(); | ||
| 196 | } | ||
| 197 | |||
| 198 | /** | ||
| 199 | * \brief Detaches the device from the bus | ||
| 200 | * | ||
| 201 | * The driver must remove pull-up on USB line D- or D+. | ||
| 202 | */ | ||
| 203 | static inline void udc_detach(void) { | ||
| 204 | udd_detach(); | ||
| 205 | } | ||
| 206 | |||
| 207 | /*! \brief The USB driver sends a resume signal called \e "Upstream Resume" | ||
| 208 | * This is authorized only when the remote wakeup feature is enabled by host. | ||
| 209 | */ | ||
| 210 | inline void udc_remotewakeup(void) { | ||
| 211 | udd_send_remotewakeup(); | ||
| 212 | } | ||
| 213 | |||
| 214 | /** | ||
| 215 | * \brief Returns a pointer on the current interface descriptor | ||
| 216 | * | ||
| 217 | * \return pointer on the current interface descriptor. | ||
| 218 | */ | ||
| 219 | usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void); | ||
| 220 | |||
| 221 | //@} | ||
| 222 | |||
| 223 | /** | ||
| 224 | * \ingroup usb_group | ||
| 225 | * \defgroup usb_device_group USB Stack Device | ||
| 226 | * | ||
| 227 | * This module includes USB Stack Device implementation. | ||
| 228 | * The stack is divided in three parts: | ||
| 229 | * - USB Device Controller (UDC) provides USB chapter 9 compliance | ||
| 230 | * - USB Device Interface (UDI) provides USB Class compliance | ||
| 231 | * - USB Device Driver (UDD) provides USB Driver for each Atmel MCU | ||
| 232 | |||
| 233 | * Many USB Device applications can be implemented on Atmel MCU. | ||
| 234 | * Atmel provides many application notes for different applications: | ||
| 235 | * - AVR4900, provides general information about Device Stack | ||
| 236 | * - AVR4901, explains how to create a new class | ||
| 237 | * - AVR4902, explains how to create a composite device | ||
| 238 | * - AVR49xx, all device classes provided in ASF have an application note | ||
| 239 | * | ||
| 240 | * A basic USB knowledge is required to understand the USB Device | ||
| 241 | * Class application notes (HID,MS,CDC,PHDC,...). | ||
| 242 | * Then, to create an USB device with | ||
| 243 | * only one class provided by ASF, refer directly to the application note | ||
| 244 | * corresponding to this USB class. The USB Device application note for | ||
| 245 | * New Class and Composite is dedicated to advanced USB users. | ||
| 246 | * | ||
| 247 | * @{ | ||
| 248 | */ | ||
| 249 | |||
| 250 | //! @} | ||
| 251 | |||
| 252 | #ifdef __cplusplus | ||
| 253 | } | ||
| 254 | #endif | ||
| 255 | |||
| 256 | #endif // _UDC_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/udc_desc.h b/tmk_core/protocol/arm_atsam/usb/udc_desc.h deleted file mode 100644 index 50861da964..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/udc_desc.h +++ /dev/null | |||
| @@ -1,132 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief Common API for USB Device Interface | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #ifndef _UDC_DESC_H_ | ||
| 48 | #define _UDC_DESC_H_ | ||
| 49 | |||
| 50 | #include "conf_usb.h" | ||
| 51 | #include "usb_protocol.h" | ||
| 52 | #include "udi.h" | ||
| 53 | |||
| 54 | #ifdef __cplusplus | ||
| 55 | extern "C" { | ||
| 56 | #endif | ||
| 57 | |||
| 58 | /** | ||
| 59 | * \ingroup udc_group | ||
| 60 | * \defgroup udc_desc_group USB Device Descriptor | ||
| 61 | * | ||
| 62 | * @{ | ||
| 63 | */ | ||
| 64 | |||
| 65 | /** | ||
| 66 | * \brief Defines the memory's location of USB descriptors | ||
| 67 | * | ||
| 68 | * By default the Descriptor is stored in RAM | ||
| 69 | * (UDC_DESC_STORAGE is defined empty). | ||
| 70 | * | ||
| 71 | * If you have need to free RAM space, | ||
| 72 | * it is possible to put descriptor in flash in following case: | ||
| 73 | * - USB driver authorize flash transfer (USBB on UC3 and USB on Mega) | ||
| 74 | * - USB Device is not high speed (UDC no need to change USB descriptors) | ||
| 75 | * | ||
| 76 | * For UC3 application used "const". | ||
| 77 | * | ||
| 78 | * For Mega application used "code". | ||
| 79 | */ | ||
| 80 | #define UDC_DESC_STORAGE | ||
| 81 | // Descriptor storage in internal RAM | ||
| 82 | #if (defined UDC_DATA_USE_HRAM_SUPPORT) | ||
| 83 | # if defined(__GNUC__) | ||
| 84 | # define UDC_DATA(x) COMPILER_WORD_ALIGNED __attribute__((__section__(".data_hram0"))) | ||
| 85 | # define UDC_BSS(x) COMPILER_ALIGNED(x) __attribute__((__section__(".bss_hram0"))) | ||
| 86 | # elif defined(__ICCAVR32__) | ||
| 87 | # define UDC_DATA(x) COMPILER_ALIGNED(x) __data32 | ||
| 88 | # define UDC_BSS(x) COMPILER_ALIGNED(x) __data32 | ||
| 89 | # endif | ||
| 90 | #else | ||
| 91 | # define UDC_DATA(x) COMPILER_ALIGNED(x) | ||
| 92 | # define UDC_BSS(x) COMPILER_ALIGNED(x) | ||
| 93 | #endif | ||
| 94 | |||
| 95 | /** | ||
| 96 | * \brief Configuration descriptor and UDI link for one USB speed | ||
| 97 | */ | ||
| 98 | typedef struct { | ||
| 99 | //! USB configuration descriptor | ||
| 100 | usb_conf_desc_t UDC_DESC_STORAGE *desc; | ||
| 101 | //! Array of UDI API pointer | ||
| 102 | udi_api_t UDC_DESC_STORAGE *UDC_DESC_STORAGE *udi_apis; | ||
| 103 | } udc_config_speed_t; | ||
| 104 | |||
| 105 | /** | ||
| 106 | * \brief All information about the USB Device | ||
| 107 | */ | ||
| 108 | typedef struct { | ||
| 109 | //! USB device descriptor for low or full speed | ||
| 110 | usb_dev_desc_t UDC_DESC_STORAGE *confdev_lsfs; | ||
| 111 | //! USB configuration descriptor and UDI API pointers for low or full speed | ||
| 112 | udc_config_speed_t UDC_DESC_STORAGE *conf_lsfs; | ||
| 113 | #ifdef USB_DEVICE_HS_SUPPORT | ||
| 114 | //! USB device descriptor for high speed | ||
| 115 | usb_dev_desc_t UDC_DESC_STORAGE *confdev_hs; | ||
| 116 | //! USB device qualifier, only use in high speed mode | ||
| 117 | usb_dev_qual_desc_t UDC_DESC_STORAGE *qualifier; | ||
| 118 | //! USB configuration descriptor and UDI API pointers for high speed | ||
| 119 | udc_config_speed_t UDC_DESC_STORAGE *conf_hs; | ||
| 120 | #endif | ||
| 121 | usb_dev_bos_desc_t UDC_DESC_STORAGE *conf_bos; | ||
| 122 | } udc_config_t; | ||
| 123 | |||
| 124 | //! Global variables of USB Device Descriptor and UDI links | ||
| 125 | extern UDC_DESC_STORAGE udc_config_t udc_config; | ||
| 126 | |||
| 127 | //@} | ||
| 128 | |||
| 129 | #ifdef __cplusplus | ||
| 130 | } | ||
| 131 | #endif | ||
| 132 | #endif // _UDC_DESC_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/udd.h b/tmk_core/protocol/arm_atsam/usb/udd.h deleted file mode 100644 index d9f58baf0b..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/udd.h +++ /dev/null | |||
| @@ -1,384 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief Common API for USB Device Drivers (UDD) | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #ifndef _UDD_H_ | ||
| 48 | #define _UDD_H_ | ||
| 49 | |||
| 50 | #include "usb_protocol.h" | ||
| 51 | #include "udc_desc.h" | ||
| 52 | |||
| 53 | #ifdef __cplusplus | ||
| 54 | extern "C" { | ||
| 55 | #endif | ||
| 56 | |||
| 57 | /** | ||
| 58 | * \ingroup usb_device_group | ||
| 59 | * \defgroup udd_group USB Device Driver (UDD) | ||
| 60 | * | ||
| 61 | * The UDD driver provides a low-level abstraction of the device | ||
| 62 | * controller hardware. Most events coming from the hardware such as | ||
| 63 | * interrupts, which may cause the UDD to call into the UDC and UDI. | ||
| 64 | * | ||
| 65 | * @{ | ||
| 66 | */ | ||
| 67 | |||
| 68 | //! \brief Endpoint identifier | ||
| 69 | typedef uint8_t udd_ep_id_t; | ||
| 70 | |||
| 71 | //! \brief Endpoint transfer status | ||
| 72 | //! Returned in parameters of callback register via udd_ep_run routine. | ||
| 73 | typedef enum { | ||
| 74 | UDD_EP_TRANSFER_OK = 0, | ||
| 75 | UDD_EP_TRANSFER_ABORT = 1, | ||
| 76 | } udd_ep_status_t; | ||
| 77 | |||
| 78 | /** | ||
| 79 | * \brief Global variable to give and record information of the setup request management | ||
| 80 | * | ||
| 81 | * This global variable allows to decode and response a setup request. | ||
| 82 | * It can be updated by udc_process_setup() from UDC or *setup() from UDIs. | ||
| 83 | */ | ||
| 84 | typedef struct { | ||
| 85 | //! Data received in USB SETUP packet | ||
| 86 | //! Note: The swap of "req.wValues" from uin16_t to le16_t is done by UDD. | ||
| 87 | usb_setup_req_t req; | ||
| 88 | |||
| 89 | //! Point to buffer to send or fill with data following SETUP packet | ||
| 90 | //! This buffer must be word align for DATA IN phase (use prefix COMPILER_WORD_ALIGNED for buffer) | ||
| 91 | uint8_t *payload; | ||
| 92 | |||
| 93 | //! Size of buffer to send or fill, and content the number of byte transfered | ||
| 94 | uint16_t payload_size; | ||
| 95 | |||
| 96 | //! Callback called after reception of ZLP from setup request | ||
| 97 | void (*callback)(void); | ||
| 98 | |||
| 99 | //! Callback called when the buffer given (.payload) is full or empty. | ||
| 100 | //! This one return false to abort data transfer, or true with a new buffer in .payload. | ||
| 101 | bool (*over_under_run)(void); | ||
| 102 | } udd_ctrl_request_t; | ||
| 103 | extern udd_ctrl_request_t udd_g_ctrlreq; | ||
| 104 | |||
| 105 | //! Return true if the setup request \a udd_g_ctrlreq indicates IN data transfer | ||
| 106 | #define Udd_setup_is_in() (USB_REQ_DIR_IN == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) | ||
| 107 | |||
| 108 | //! Return true if the setup request \a udd_g_ctrlreq indicates OUT data transfer | ||
| 109 | #define Udd_setup_is_out() (USB_REQ_DIR_OUT == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) | ||
| 110 | |||
| 111 | //! Return the type of the SETUP request \a udd_g_ctrlreq. \see usb_reqtype. | ||
| 112 | #define Udd_setup_type() (udd_g_ctrlreq.req.bmRequestType & USB_REQ_TYPE_MASK) | ||
| 113 | |||
| 114 | //! Return the recipient of the SETUP request \a udd_g_ctrlreq. \see usb_recipient | ||
| 115 | #define Udd_setup_recipient() (udd_g_ctrlreq.req.bmRequestType & USB_REQ_RECIP_MASK) | ||
| 116 | |||
| 117 | /** | ||
| 118 | * \brief End of halt callback function type. | ||
| 119 | * Registered by routine udd_ep_wait_stall_clear() | ||
| 120 | * Callback called when endpoint stall is cleared. | ||
| 121 | */ | ||
| 122 | typedef void (*udd_callback_halt_cleared_t)(void); | ||
| 123 | |||
| 124 | /** | ||
| 125 | * \brief End of transfer callback function type. | ||
| 126 | * Registered by routine udd_ep_run() | ||
| 127 | * Callback called by USB interrupt after data transfer or abort (reset,...). | ||
| 128 | * | ||
| 129 | * \param status UDD_EP_TRANSFER_OK, if transfer is complete | ||
| 130 | * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted | ||
| 131 | * \param n number of data transfered | ||
| 132 | */ | ||
| 133 | typedef void (*udd_callback_trans_t)(udd_ep_status_t status, iram_size_t nb_transfered, udd_ep_id_t ep); | ||
| 134 | |||
| 135 | /** | ||
| 136 | * \brief Authorizes the VBUS event | ||
| 137 | * | ||
| 138 | * \return true, if the VBUS monitoring is possible. | ||
| 139 | */ | ||
| 140 | bool udd_include_vbus_monitoring(void); | ||
| 141 | |||
| 142 | /** | ||
| 143 | * \brief Enables the USB Device mode | ||
| 144 | */ | ||
| 145 | void udd_enable(void); | ||
| 146 | |||
| 147 | /** | ||
| 148 | * \brief Disables the USB Device mode | ||
| 149 | */ | ||
| 150 | void udd_disable(void); | ||
| 151 | |||
| 152 | /** | ||
| 153 | * \brief Attach device to the bus when possible | ||
| 154 | * | ||
| 155 | * \warning If a VBus control is included in driver, | ||
| 156 | * then it will attach device when an acceptable Vbus | ||
| 157 | * level from the host is detected. | ||
| 158 | */ | ||
| 159 | void udd_attach(void); | ||
| 160 | |||
| 161 | /** | ||
| 162 | * \brief Detaches the device from the bus | ||
| 163 | * | ||
| 164 | * The driver must remove pull-up on USB line D- or D+. | ||
| 165 | */ | ||
| 166 | void udd_detach(void); | ||
| 167 | |||
| 168 | /** | ||
| 169 | * \brief Test whether the USB Device Controller is running at high | ||
| 170 | * speed or not. | ||
| 171 | * | ||
| 172 | * \return \c true if the Device is running at high speed mode, otherwise \c false. | ||
| 173 | */ | ||
| 174 | bool udd_is_high_speed(void); | ||
| 175 | |||
| 176 | /** | ||
| 177 | * \brief Changes the USB address of device | ||
| 178 | * | ||
| 179 | * \param address New USB address | ||
| 180 | */ | ||
| 181 | void udd_set_address(uint8_t address); | ||
| 182 | |||
| 183 | /** | ||
| 184 | * \brief Returns the USB address of device | ||
| 185 | * | ||
| 186 | * \return USB address | ||
| 187 | */ | ||
| 188 | uint8_t udd_getaddress(void); | ||
| 189 | |||
| 190 | /** | ||
| 191 | * \brief Returns the current start of frame number | ||
| 192 | * | ||
| 193 | * \return current start of frame number. | ||
| 194 | */ | ||
| 195 | uint16_t udd_get_frame_number(void); | ||
| 196 | |||
| 197 | /** | ||
| 198 | * \brief Returns the current micro start of frame number | ||
| 199 | * | ||
| 200 | * \return current micro start of frame number required in high speed mode. | ||
| 201 | */ | ||
| 202 | uint16_t udd_get_micro_frame_number(void); | ||
| 203 | |||
| 204 | /*! \brief The USB driver sends a resume signal called Upstream Resume | ||
| 205 | */ | ||
| 206 | void udd_send_remotewakeup(void); | ||
| 207 | |||
| 208 | /** | ||
| 209 | * \brief Load setup payload | ||
| 210 | * | ||
| 211 | * \param payload Pointer on payload | ||
| 212 | * \param payload_size Size of payload | ||
| 213 | */ | ||
| 214 | void udd_set_setup_payload(uint8_t *payload, uint16_t payload_size); | ||
| 215 | |||
| 216 | /** | ||
| 217 | * \name Endpoint Management | ||
| 218 | * | ||
| 219 | * The following functions allow drivers to create and remove | ||
| 220 | * endpoints, as well as set, clear and query their "halted" and | ||
| 221 | * "wedged" states. | ||
| 222 | */ | ||
| 223 | //@{ | ||
| 224 | |||
| 225 | #if (USB_DEVICE_MAX_EP != 0) | ||
| 226 | |||
| 227 | /** | ||
| 228 | * \brief Configures and enables an endpoint | ||
| 229 | * | ||
| 230 | * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). | ||
| 231 | * \param bmAttributes Attributes of endpoint declared in the descriptor. | ||
| 232 | * \param MaxEndpointSize Endpoint maximum size | ||
| 233 | * | ||
| 234 | * \return \c 1 if the endpoint is enabled, otherwise \c 0. | ||
| 235 | */ | ||
| 236 | bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, uint16_t MaxEndpointSize); | ||
| 237 | |||
| 238 | /** | ||
| 239 | * \brief Disables an endpoint | ||
| 240 | * | ||
| 241 | * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). | ||
| 242 | */ | ||
| 243 | void udd_ep_free(udd_ep_id_t ep); | ||
| 244 | |||
| 245 | /** | ||
| 246 | * \brief Check if the endpoint \a ep is halted. | ||
| 247 | * | ||
| 248 | * \param ep The ID of the endpoint to check. | ||
| 249 | * | ||
| 250 | * \return \c 1 if \a ep is halted, otherwise \c 0. | ||
| 251 | */ | ||
| 252 | bool udd_ep_is_halted(udd_ep_id_t ep); | ||
| 253 | |||
| 254 | /** | ||
| 255 | * \brief Set the halted state of the endpoint \a ep | ||
| 256 | * | ||
| 257 | * After calling this function, any transaction on \a ep will result | ||
| 258 | * in a STALL handshake being sent. Any pending transactions will be | ||
| 259 | * performed first, however. | ||
| 260 | * | ||
| 261 | * \param ep The ID of the endpoint to be halted | ||
| 262 | * | ||
| 263 | * \return \c 1 if \a ep is halted, otherwise \c 0. | ||
| 264 | */ | ||
| 265 | bool udd_ep_set_halt(udd_ep_id_t ep); | ||
| 266 | |||
| 267 | /** | ||
| 268 | * \brief Clear the halted state of the endpoint \a ep | ||
| 269 | * | ||
| 270 | * After calling this function, any transaction on \a ep will | ||
| 271 | * be handled normally, i.e. a STALL handshake will not be sent, and | ||
| 272 | * the data toggle sequence will start at DATA0. | ||
| 273 | * | ||
| 274 | * \param ep The ID of the endpoint to be un-halted | ||
| 275 | * | ||
| 276 | * \return \c 1 if function was successfully done, otherwise \c 0. | ||
| 277 | */ | ||
| 278 | bool udd_ep_clear_halt(udd_ep_id_t ep); | ||
| 279 | |||
| 280 | /** | ||
| 281 | * \brief Registers a callback to call when endpoint halt is cleared | ||
| 282 | * | ||
| 283 | * \param ep The ID of the endpoint to use | ||
| 284 | * \param callback NULL or function to call when endpoint halt is cleared | ||
| 285 | * | ||
| 286 | * \warning if the endpoint is not halted then the \a callback is called immediately. | ||
| 287 | * | ||
| 288 | * \return \c 1 if the register is accepted, otherwise \c 0. | ||
| 289 | */ | ||
| 290 | bool udd_ep_wait_stall_clear(udd_ep_id_t ep, udd_callback_halt_cleared_t callback); | ||
| 291 | |||
| 292 | /** | ||
| 293 | * \brief Allows to receive or send data on an endpoint | ||
| 294 | * | ||
| 295 | * The driver uses a specific DMA USB to transfer data | ||
| 296 | * from internal RAM to endpoint, if this one is available. | ||
| 297 | * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. | ||
| 298 | * The \a callback returns the transfer status and eventually the number of byte transfered. | ||
| 299 | * Note: The control endpoint is not authorized. | ||
| 300 | * | ||
| 301 | * \param ep The ID of the endpoint to use | ||
| 302 | * \param b_shortpacket Enabled automatic short packet | ||
| 303 | * \param buf Buffer on Internal RAM to send or fill. | ||
| 304 | * It must be align, then use COMPILER_WORD_ALIGNED. | ||
| 305 | * \param buf_size Buffer size to send or fill | ||
| 306 | * \param callback NULL or function to call at the end of transfer | ||
| 307 | * | ||
| 308 | * \warning About \a b_shortpacket, for IN endpoint it means that a short packet | ||
| 309 | * (or a Zero Length Packet) will be sent to the USB line to properly close the usb | ||
| 310 | * transfer at the end of the data transfer. | ||
| 311 | * For Bulk and Interrupt OUT endpoint, it will automatically stop the transfer | ||
| 312 | * at the end of the data transfer (received short packet). | ||
| 313 | * | ||
| 314 | * \return \c 1 if function was successfully done, otherwise \c 0. | ||
| 315 | */ | ||
| 316 | 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); | ||
| 317 | /** | ||
| 318 | * \brief Aborts transfer on going on endpoint | ||
| 319 | * | ||
| 320 | * If a transfer is on going, then it is stopped and | ||
| 321 | * the callback registered is called to signal the end of transfer. | ||
| 322 | * Note: The control endpoint is not authorized. | ||
| 323 | * | ||
| 324 | * \param ep Endpoint to abort | ||
| 325 | */ | ||
| 326 | void udd_ep_abort(udd_ep_id_t ep); | ||
| 327 | |||
| 328 | #endif | ||
| 329 | |||
| 330 | //@} | ||
| 331 | |||
| 332 | /** | ||
| 333 | * \name High speed test mode management | ||
| 334 | * | ||
| 335 | * The following functions allow the device to jump to a specific test mode required in high speed mode. | ||
| 336 | */ | ||
| 337 | //@{ | ||
| 338 | void udd_test_mode_j(void); | ||
| 339 | void udd_test_mode_k(void); | ||
| 340 | void udd_test_mode_se0_nak(void); | ||
| 341 | void udd_test_mode_packet(void); | ||
| 342 | //@} | ||
| 343 | |||
| 344 | /** | ||
| 345 | * \name UDC callbacks to provide for UDD | ||
| 346 | * | ||
| 347 | * The following callbacks are used by UDD. | ||
| 348 | */ | ||
| 349 | //@{ | ||
| 350 | |||
| 351 | /** | ||
| 352 | * \brief Decodes and manages a setup request | ||
| 353 | * | ||
| 354 | * The driver call it when a SETUP packet is received. | ||
| 355 | * The \c udd_g_ctrlreq contains the data of SETUP packet. | ||
| 356 | * If this callback accepts the setup request then it must | ||
| 357 | * return \c 1 and eventually update \c udd_g_ctrlreq to send or receive data. | ||
| 358 | * | ||
| 359 | * \return \c 1 if the request is accepted, otherwise \c 0. | ||
| 360 | */ | ||
| 361 | extern bool udc_process_setup(void); | ||
| 362 | |||
| 363 | /** | ||
| 364 | * \brief Reset the UDC | ||
| 365 | * | ||
| 366 | * The UDC must reset all configuration. | ||
| 367 | */ | ||
| 368 | extern void udc_reset(void); | ||
| 369 | |||
| 370 | /** | ||
| 371 | * \brief To signal that a SOF is occurred | ||
| 372 | * | ||
| 373 | * The UDC must send the signal to all UDIs enabled | ||
| 374 | */ | ||
| 375 | extern void udc_sof_notify(void); | ||
| 376 | |||
| 377 | //@} | ||
| 378 | |||
| 379 | //@} | ||
| 380 | |||
| 381 | #ifdef __cplusplus | ||
| 382 | } | ||
| 383 | #endif | ||
| 384 | #endif // _UDD_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/udi.h b/tmk_core/protocol/arm_atsam/usb/udi.h deleted file mode 100644 index 60b117f3ca..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/udi.h +++ /dev/null | |||
| @@ -1,133 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief Common API for USB Device Interface | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #ifndef _UDI_H_ | ||
| 48 | #define _UDI_H_ | ||
| 49 | |||
| 50 | #include "conf_usb.h" | ||
| 51 | #include "usb_protocol.h" | ||
| 52 | |||
| 53 | #ifdef __cplusplus | ||
| 54 | extern "C" { | ||
| 55 | #endif | ||
| 56 | |||
| 57 | /** | ||
| 58 | * \ingroup usb_device_group | ||
| 59 | * \defgroup udi_group USB Device Interface (UDI) | ||
| 60 | * The UDI provides a common API for all classes, | ||
| 61 | * and this is used by UDC for the main control of USB Device interface. | ||
| 62 | * @{ | ||
| 63 | */ | ||
| 64 | |||
| 65 | /** | ||
| 66 | * \brief UDI API. | ||
| 67 | * | ||
| 68 | * The callbacks within this structure are called only by | ||
| 69 | * USB Device Controller (UDC) | ||
| 70 | * | ||
| 71 | * The udc_get_interface_desc() can be use by UDI to know the interface descriptor | ||
| 72 | * selected by UDC. | ||
| 73 | */ | ||
| 74 | typedef struct { | ||
| 75 | /** | ||
| 76 | * \brief Enable the interface. | ||
| 77 | * | ||
| 78 | * This function is called when the host selects a configuration | ||
| 79 | * to which this interface belongs through a Set Configuration | ||
| 80 | * request, and when the host selects an alternate setting of | ||
| 81 | * this interface through a Set Interface request. | ||
| 82 | * | ||
| 83 | * \return \c 1 if function was successfully done, otherwise \c 0. | ||
| 84 | */ | ||
| 85 | bool (*enable)(void); | ||
| 86 | |||
| 87 | /** | ||
| 88 | * \brief Disable the interface. | ||
| 89 | * | ||
| 90 | * This function is called when this interface is currently | ||
| 91 | * active, and | ||
| 92 | * - the host selects any configuration through a Set | ||
| 93 | * Configuration request, or | ||
| 94 | * - the host issues a USB reset, or | ||
| 95 | * - the device is detached from the host (i.e. Vbus is no | ||
| 96 | * longer present) | ||
| 97 | */ | ||
| 98 | void (*disable)(void); | ||
| 99 | |||
| 100 | /** | ||
| 101 | * \brief Handle a control request directed at an interface. | ||
| 102 | * | ||
| 103 | * This function is called when this interface is currently | ||
| 104 | * active and the host sends a SETUP request | ||
| 105 | * with this interface as the recipient. | ||
| 106 | * | ||
| 107 | * Use udd_g_ctrlreq to decode and response to SETUP request. | ||
| 108 | * | ||
| 109 | * \return \c 1 if this interface supports the SETUP request, otherwise \c 0. | ||
| 110 | */ | ||
| 111 | bool (*setup)(void); | ||
| 112 | |||
| 113 | /** | ||
| 114 | * \brief Returns the current setting of the selected interface. | ||
| 115 | * | ||
| 116 | * This function is called when UDC when know alternate setting of selected interface. | ||
| 117 | * | ||
| 118 | * \return alternate setting of selected interface | ||
| 119 | */ | ||
| 120 | uint8_t (*getsetting)(void); | ||
| 121 | |||
| 122 | /** | ||
| 123 | * \brief To signal that a SOF is occurred | ||
| 124 | */ | ||
| 125 | void (*sof_notify)(void); | ||
| 126 | } udi_api_t; | ||
| 127 | |||
| 128 | //@} | ||
| 129 | |||
| 130 | #ifdef __cplusplus | ||
| 131 | } | ||
| 132 | #endif | ||
| 133 | #endif // _UDI_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_cdc.c b/tmk_core/protocol/arm_atsam/usb/udi_cdc.c deleted file mode 100644 index d40030f36d..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/udi_cdc.c +++ /dev/null | |||
| @@ -1,1267 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief USB Device Communication Device Class (CDC) interface. | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009-2016 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #include "samd51j18a.h" | ||
| 48 | #include "conf_usb.h" | ||
| 49 | #include "usb_protocol.h" | ||
| 50 | #include "usb_protocol_cdc.h" | ||
| 51 | #include "udd.h" | ||
| 52 | #include "udc.h" | ||
| 53 | #include "udi_cdc.h" | ||
| 54 | #include <string.h> | ||
| 55 | #include "udi_cdc_conf.h" | ||
| 56 | #include "udi_device_conf.h" | ||
| 57 | #include "stdarg.h" | ||
| 58 | #include "tmk_core/protocol/arm_atsam/clks.h" | ||
| 59 | |||
| 60 | #ifdef VIRTSER_ENABLE | ||
| 61 | |||
| 62 | # ifdef UDI_CDC_LOW_RATE | ||
| 63 | # ifdef USB_DEVICE_HS_SUPPORT | ||
| 64 | # define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) | ||
| 65 | # define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) | ||
| 66 | # else | ||
| 67 | # define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) | ||
| 68 | # define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) | ||
| 69 | # endif | ||
| 70 | # else | ||
| 71 | # ifdef USB_DEVICE_HS_SUPPORT | ||
| 72 | # define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) | ||
| 73 | # define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) | ||
| 74 | # else | ||
| 75 | # define UDI_CDC_TX_BUFFERS (5 * UDI_CDC_DATA_EPS_FS_SIZE) | ||
| 76 | # define UDI_CDC_RX_BUFFERS (5 * UDI_CDC_DATA_EPS_FS_SIZE) | ||
| 77 | # endif | ||
| 78 | # endif | ||
| 79 | |||
| 80 | # ifndef UDI_CDC_TX_EMPTY_NOTIFY | ||
| 81 | # define UDI_CDC_TX_EMPTY_NOTIFY(port) | ||
| 82 | # endif | ||
| 83 | |||
| 84 | /** | ||
| 85 | * \ingroup udi_cdc_group | ||
| 86 | * \defgroup udi_cdc_group_udc Interface with USB Device Core (UDC) | ||
| 87 | * | ||
| 88 | * Structures and functions required by UDC. | ||
| 89 | * | ||
| 90 | * @{ | ||
| 91 | */ | ||
| 92 | bool udi_cdc_comm_enable(void); | ||
| 93 | void udi_cdc_comm_disable(void); | ||
| 94 | bool udi_cdc_comm_setup(void); | ||
| 95 | bool udi_cdc_data_enable(void); | ||
| 96 | void udi_cdc_data_disable(void); | ||
| 97 | bool udi_cdc_data_setup(void); | ||
| 98 | uint8_t udi_cdc_getsetting(void); | ||
| 99 | void udi_cdc_data_sof_notify(void); | ||
| 100 | UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm = {.enable = udi_cdc_comm_enable, .disable = udi_cdc_comm_disable, .setup = udi_cdc_comm_setup, .getsetting = udi_cdc_getsetting, .sof_notify = NULL}; | ||
| 101 | UDC_DESC_STORAGE udi_api_t udi_api_cdc_data = { | ||
| 102 | .enable = udi_cdc_data_enable, | ||
| 103 | .disable = udi_cdc_data_disable, | ||
| 104 | .setup = udi_cdc_data_setup, | ||
| 105 | .getsetting = udi_cdc_getsetting, | ||
| 106 | .sof_notify = udi_cdc_data_sof_notify, | ||
| 107 | }; | ||
| 108 | //@} | ||
| 109 | |||
| 110 | /** | ||
| 111 | * \ingroup udi_cdc_group | ||
| 112 | * \defgroup udi_cdc_group_internal Implementation of UDI CDC | ||
| 113 | * | ||
| 114 | * Class internal implementation | ||
| 115 | * @{ | ||
| 116 | */ | ||
| 117 | |||
| 118 | /** | ||
| 119 | * \name Internal routines | ||
| 120 | */ | ||
| 121 | //@{ | ||
| 122 | |||
| 123 | /** | ||
| 124 | * \name Routines to control serial line | ||
| 125 | */ | ||
| 126 | //@{ | ||
| 127 | |||
| 128 | /** | ||
| 129 | * \brief Returns the port number corresponding at current setup request | ||
| 130 | * | ||
| 131 | * \return port number | ||
| 132 | */ | ||
| 133 | static uint8_t udi_cdc_setup_to_port(void); | ||
| 134 | |||
| 135 | /** | ||
| 136 | * \brief Sends line coding to application | ||
| 137 | * | ||
| 138 | * Called after SETUP request when line coding data is received. | ||
| 139 | */ | ||
| 140 | static void udi_cdc_line_coding_received(void); | ||
| 141 | |||
| 142 | /** | ||
| 143 | * \brief Records new state | ||
| 144 | * | ||
| 145 | * \param port Communication port number to manage | ||
| 146 | * \param b_set State is enabled if true, else disabled | ||
| 147 | * \param bit_mask Field to process (see CDC_SERIAL_STATE_ defines) | ||
| 148 | */ | ||
| 149 | static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask); | ||
| 150 | |||
| 151 | /** | ||
| 152 | * \brief Check and eventually notify the USB host of new state | ||
| 153 | * | ||
| 154 | * \param port Communication port number to manage | ||
| 155 | * \param ep Port communication endpoint | ||
| 156 | */ | ||
| 157 | static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep); | ||
| 158 | |||
| 159 | /** | ||
| 160 | * \brief Ack sent of serial state message | ||
| 161 | * Callback called after serial state message sent | ||
| 162 | * | ||
| 163 | * \param status UDD_EP_TRANSFER_OK, if transfer finished | ||
| 164 | * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted | ||
| 165 | * \param n number of data transfered | ||
| 166 | */ | ||
| 167 | static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); | ||
| 168 | |||
| 169 | //@} | ||
| 170 | |||
| 171 | /** | ||
| 172 | * \name Routines to process data transfer | ||
| 173 | */ | ||
| 174 | //@{ | ||
| 175 | |||
| 176 | /** | ||
| 177 | * \brief Enable the reception of data from the USB host | ||
| 178 | * | ||
| 179 | * The value udi_cdc_rx_trans_sel indicate the RX buffer to fill. | ||
| 180 | * | ||
| 181 | * \param port Communication port number to manage | ||
| 182 | * | ||
| 183 | * \return \c 1 if function was successfully done, otherwise \c 0. | ||
| 184 | */ | ||
| 185 | static bool udi_cdc_rx_start(uint8_t port); | ||
| 186 | |||
| 187 | /** | ||
| 188 | * \brief Update rx buffer management with a new data | ||
| 189 | * Callback called after data reception on USB line | ||
| 190 | * | ||
| 191 | * \param status UDD_EP_TRANSFER_OK, if transfer finish | ||
| 192 | * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted | ||
| 193 | * \param n number of data received | ||
| 194 | */ | ||
| 195 | static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); | ||
| 196 | |||
| 197 | /** | ||
| 198 | * \brief Ack sent of tx buffer | ||
| 199 | * Callback called after data transfer on USB line | ||
| 200 | * | ||
| 201 | * \param status UDD_EP_TRANSFER_OK, if transfer finished | ||
| 202 | * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted | ||
| 203 | * \param n number of data transfered | ||
| 204 | */ | ||
| 205 | static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); | ||
| 206 | |||
| 207 | /** | ||
| 208 | * \brief Send buffer on line or wait a SOF event | ||
| 209 | * | ||
| 210 | * \param port Communication port number to manage | ||
| 211 | */ | ||
| 212 | static void udi_cdc_tx_send(uint8_t port); | ||
| 213 | |||
| 214 | //@} | ||
| 215 | |||
| 216 | //@} | ||
| 217 | |||
| 218 | /** | ||
| 219 | * \name Information about configuration of communication line | ||
| 220 | */ | ||
| 221 | //@{ | ||
| 222 | COMPILER_WORD_ALIGNED | ||
| 223 | static usb_cdc_line_coding_t udi_cdc_line_coding[UDI_CDC_PORT_NB]; | ||
| 224 | static bool udi_cdc_serial_state_msg_ongoing[UDI_CDC_PORT_NB]; | ||
| 225 | static volatile le16_t udi_cdc_state[UDI_CDC_PORT_NB]; | ||
| 226 | COMPILER_WORD_ALIGNED static usb_cdc_notify_serial_state_t uid_cdc_state_msg[UDI_CDC_PORT_NB]; | ||
| 227 | |||
| 228 | //! Status of CDC COMM interfaces | ||
| 229 | static volatile uint8_t udi_cdc_nb_comm_enabled = 0; | ||
| 230 | //@} | ||
| 231 | |||
| 232 | /** | ||
| 233 | * \name Variables to manage RX/TX transfer requests | ||
| 234 | * Two buffers for each sense are used to optimize the speed. | ||
| 235 | */ | ||
| 236 | //@{ | ||
| 237 | |||
| 238 | //! Status of CDC DATA interfaces | ||
| 239 | static volatile uint8_t udi_cdc_nb_data_enabled = 0; | ||
| 240 | static volatile bool udi_cdc_data_running = false; | ||
| 241 | //! Buffer to receive data | ||
| 242 | COMPILER_WORD_ALIGNED static uint8_t udi_cdc_rx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_RX_BUFFERS]; | ||
| 243 | //! Data available in RX buffers | ||
| 244 | static volatile uint16_t udi_cdc_rx_buf_nb[UDI_CDC_PORT_NB][2]; | ||
| 245 | //! Give the current RX buffer used (rx0 if 0, rx1 if 1) | ||
| 246 | static volatile uint8_t udi_cdc_rx_buf_sel[UDI_CDC_PORT_NB]; | ||
| 247 | //! Read position in current RX buffer | ||
| 248 | static volatile uint16_t udi_cdc_rx_pos[UDI_CDC_PORT_NB]; | ||
| 249 | //! Signal a transfer on-going | ||
| 250 | static volatile bool udi_cdc_rx_trans_ongoing[UDI_CDC_PORT_NB]; | ||
| 251 | |||
| 252 | //! Define a transfer halted | ||
| 253 | # define UDI_CDC_TRANS_HALTED 2 | ||
| 254 | |||
| 255 | //! Buffer to send data | ||
| 256 | COMPILER_WORD_ALIGNED static uint8_t udi_cdc_tx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_TX_BUFFERS]; | ||
| 257 | //! Data available in TX buffers | ||
| 258 | static uint16_t udi_cdc_tx_buf_nb[UDI_CDC_PORT_NB][2]; | ||
| 259 | //! Give current TX buffer used (tx0 if 0, tx1 if 1) | ||
| 260 | static volatile uint8_t udi_cdc_tx_buf_sel[UDI_CDC_PORT_NB]; | ||
| 261 | //! Value of SOF during last TX transfer | ||
| 262 | static uint16_t udi_cdc_tx_sof_num[UDI_CDC_PORT_NB]; | ||
| 263 | //! Signal a transfer on-going | ||
| 264 | static volatile bool udi_cdc_tx_trans_ongoing[UDI_CDC_PORT_NB]; | ||
| 265 | //! Signal that both buffer content data to send | ||
| 266 | static volatile bool udi_cdc_tx_both_buf_to_send[UDI_CDC_PORT_NB]; | ||
| 267 | |||
| 268 | //@} | ||
| 269 | |||
| 270 | bool udi_cdc_comm_enable(void) { | ||
| 271 | uint8_t port; | ||
| 272 | uint8_t iface_comm_num; | ||
| 273 | |||
| 274 | //#if UDI_CDC_PORT_NB == 1 // To optimize code | ||
| 275 | port = 0; | ||
| 276 | udi_cdc_nb_comm_enabled = 0; | ||
| 277 | //#else | ||
| 278 | // if (udi_cdc_nb_comm_enabled > UDI_CDC_PORT_NB) { | ||
| 279 | // udi_cdc_nb_comm_enabled = 0; | ||
| 280 | // } | ||
| 281 | // port = udi_cdc_nb_comm_enabled; | ||
| 282 | //#endif | ||
| 283 | |||
| 284 | // Initialize control signal management | ||
| 285 | udi_cdc_state[port] = CPU_TO_LE16(0); | ||
| 286 | |||
| 287 | uid_cdc_state_msg[port].header.bmRequestType = USB_REQ_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_RECIP_INTERFACE; | ||
| 288 | uid_cdc_state_msg[port].header.bNotification = USB_REQ_CDC_NOTIFY_SERIAL_STATE; | ||
| 289 | uid_cdc_state_msg[port].header.wValue = LE16(0); | ||
| 290 | |||
| 291 | /* | ||
| 292 | switch (port) { | ||
| 293 | #define UDI_CDC_PORT_TO_IFACE_COMM(index, unused) \ | ||
| 294 | case index: \ | ||
| 295 | iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_##index; \ | ||
| 296 | break; | ||
| 297 | MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_IFACE_COMM, ~) | ||
| 298 | #undef UDI_CDC_PORT_TO_IFACE_COMM | ||
| 299 | default: | ||
| 300 | iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_0; | ||
| 301 | break; | ||
| 302 | } | ||
| 303 | */ | ||
| 304 | iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_0; | ||
| 305 | |||
| 306 | uid_cdc_state_msg[port].header.wIndex = LE16(iface_comm_num); | ||
| 307 | uid_cdc_state_msg[port].header.wLength = LE16(2); | ||
| 308 | uid_cdc_state_msg[port].value = CPU_TO_LE16(0); | ||
| 309 | |||
| 310 | udi_cdc_line_coding[port].dwDTERate = CPU_TO_LE32(UDI_CDC_DEFAULT_RATE); | ||
| 311 | udi_cdc_line_coding[port].bCharFormat = UDI_CDC_DEFAULT_STOPBITS; | ||
| 312 | udi_cdc_line_coding[port].bParityType = UDI_CDC_DEFAULT_PARITY; | ||
| 313 | udi_cdc_line_coding[port].bDataBits = UDI_CDC_DEFAULT_DATABITS; | ||
| 314 | // Call application callback | ||
| 315 | // to initialize memories or indicate that interface is enabled | ||
| 316 | # if 0 | ||
| 317 | UDI_CDC_SET_CODING_EXT(port,(&udi_cdc_line_coding[port])); | ||
| 318 | if (!UDI_CDC_ENABLE_EXT(port)) { | ||
| 319 | return false; | ||
| 320 | } | ||
| 321 | # endif | ||
| 322 | udi_cdc_nb_comm_enabled++; | ||
| 323 | return true; | ||
| 324 | } | ||
| 325 | |||
| 326 | bool udi_cdc_data_enable(void) { | ||
| 327 | uint8_t port; | ||
| 328 | |||
| 329 | //#if UDI_CDC_PORT_NB == 1 // To optimize code | ||
| 330 | port = 0; | ||
| 331 | udi_cdc_nb_data_enabled = 0; | ||
| 332 | //#else | ||
| 333 | // if (udi_cdc_nb_data_enabled > UDI_CDC_PORT_NB) { | ||
| 334 | // udi_cdc_nb_data_enabled = 0; | ||
| 335 | // } | ||
| 336 | // port = udi_cdc_nb_data_enabled; | ||
| 337 | //#endif | ||
| 338 | |||
| 339 | // Initialize TX management | ||
| 340 | udi_cdc_tx_trans_ongoing[port] = false; | ||
| 341 | udi_cdc_tx_both_buf_to_send[port] = false; | ||
| 342 | udi_cdc_tx_buf_sel[port] = 0; | ||
| 343 | udi_cdc_tx_buf_nb[port][0] = 0; | ||
| 344 | udi_cdc_tx_buf_nb[port][1] = 0; | ||
| 345 | udi_cdc_tx_sof_num[port] = 0; | ||
| 346 | udi_cdc_tx_send(port); | ||
| 347 | |||
| 348 | // Initialize RX management | ||
| 349 | udi_cdc_rx_trans_ongoing[port] = false; | ||
| 350 | udi_cdc_rx_buf_sel[port] = 0; | ||
| 351 | udi_cdc_rx_buf_nb[port][0] = 0; | ||
| 352 | udi_cdc_rx_buf_nb[port][1] = 0; | ||
| 353 | udi_cdc_rx_pos[port] = 0; | ||
| 354 | if (!udi_cdc_rx_start(port)) { | ||
| 355 | return false; | ||
| 356 | } | ||
| 357 | udi_cdc_nb_data_enabled++; | ||
| 358 | if (udi_cdc_nb_data_enabled == UDI_CDC_PORT_NB) { | ||
| 359 | udi_cdc_data_running = true; | ||
| 360 | } | ||
| 361 | return true; | ||
| 362 | } | ||
| 363 | |||
| 364 | void udi_cdc_comm_disable(void) { | ||
| 365 | Assert(udi_cdc_nb_comm_enabled != 0); | ||
| 366 | udi_cdc_nb_comm_enabled--; | ||
| 367 | } | ||
| 368 | |||
| 369 | void udi_cdc_data_disable(void) { | ||
| 370 | // uint8_t port; | ||
| 371 | |||
| 372 | Assert(udi_cdc_nb_data_enabled != 0); | ||
| 373 | udi_cdc_nb_data_enabled--; | ||
| 374 | // port = udi_cdc_nb_data_enabled; | ||
| 375 | // UDI_CDC_DISABLE_EXT(port); | ||
| 376 | udi_cdc_data_running = false; | ||
| 377 | } | ||
| 378 | |||
| 379 | bool udi_cdc_comm_setup(void) { | ||
| 380 | uint8_t port = udi_cdc_setup_to_port(); | ||
| 381 | |||
| 382 | if (Udd_setup_is_in()) { | ||
| 383 | // GET Interface Requests | ||
| 384 | if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { | ||
| 385 | // Requests Class Interface Get | ||
| 386 | switch (udd_g_ctrlreq.req.bRequest) { | ||
| 387 | case USB_REQ_CDC_GET_LINE_CODING: | ||
| 388 | // Get configuration of CDC line | ||
| 389 | if (sizeof(usb_cdc_line_coding_t) != udd_g_ctrlreq.req.wLength) return false; // Error for USB host | ||
| 390 | udd_g_ctrlreq.payload = (uint8_t *)&udi_cdc_line_coding[port]; | ||
| 391 | udd_g_ctrlreq.payload_size = sizeof(usb_cdc_line_coding_t); | ||
| 392 | return true; | ||
| 393 | } | ||
| 394 | } | ||
| 395 | } | ||
| 396 | if (Udd_setup_is_out()) { | ||
| 397 | // SET Interface Requests | ||
| 398 | if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { | ||
| 399 | // Requests Class Interface Set | ||
| 400 | switch (udd_g_ctrlreq.req.bRequest) { | ||
| 401 | case USB_REQ_CDC_SET_LINE_CODING: | ||
| 402 | // Change configuration of CDC line | ||
| 403 | if (sizeof(usb_cdc_line_coding_t) != udd_g_ctrlreq.req.wLength) return false; // Error for USB host | ||
| 404 | udd_g_ctrlreq.callback = udi_cdc_line_coding_received; | ||
| 405 | udd_g_ctrlreq.payload = (uint8_t *)&udi_cdc_line_coding[port]; | ||
| 406 | udd_g_ctrlreq.payload_size = sizeof(usb_cdc_line_coding_t); | ||
| 407 | return true; | ||
| 408 | case USB_REQ_CDC_SET_CONTROL_LINE_STATE: | ||
| 409 | // According cdc spec 1.1 chapter 6.2.14 | ||
| 410 | // UDI_CDC_SET_DTR_EXT(port, (0 != | ||
| 411 | // (udd_g_ctrlreq.req.wValue | ||
| 412 | // & CDC_CTRL_SIGNAL_DTE_PRESENT))); | ||
| 413 | // UDI_CDC_SET_RTS_EXT(port, (0 != | ||
| 414 | // (udd_g_ctrlreq.req.wValue | ||
| 415 | // & CDC_CTRL_SIGNAL_ACTIVATE_CARRIER))); | ||
| 416 | return true; | ||
| 417 | } | ||
| 418 | } | ||
| 419 | } | ||
| 420 | return false; // request Not supported | ||
| 421 | } | ||
| 422 | |||
| 423 | bool udi_cdc_data_setup(void) { | ||
| 424 | return false; // request Not supported | ||
| 425 | } | ||
| 426 | |||
| 427 | uint8_t udi_cdc_getsetting(void) { | ||
| 428 | return 0; // CDC don't have multiple alternate setting | ||
| 429 | } | ||
| 430 | |||
| 431 | void udi_cdc_data_sof_notify(void) { | ||
| 432 | static uint8_t port_notify = 0; | ||
| 433 | |||
| 434 | // A call of udi_cdc_data_sof_notify() is done for each port | ||
| 435 | udi_cdc_tx_send(port_notify); | ||
| 436 | /* | ||
| 437 | #if UDI_CDC_PORT_NB != 1 // To optimize code | ||
| 438 | port_notify++; | ||
| 439 | if (port_notify >= UDI_CDC_PORT_NB) { | ||
| 440 | port_notify = 0; | ||
| 441 | } | ||
| 442 | #endif | ||
| 443 | */ | ||
| 444 | } | ||
| 445 | |||
| 446 | //------------------------------------------------- | ||
| 447 | //------- Internal routines to control serial line | ||
| 448 | |||
| 449 | static uint8_t udi_cdc_setup_to_port(void) { | ||
| 450 | uint8_t port; | ||
| 451 | |||
| 452 | /* | ||
| 453 | switch (udd_g_ctrlreq.req.wIndex & 0xFF) { | ||
| 454 | #define UDI_CDC_IFACE_COMM_TO_PORT(iface, unused) \ | ||
| 455 | case UDI_CDC_COMM_IFACE_NUMBER_##iface: \ | ||
| 456 | port = iface; \ | ||
| 457 | break; | ||
| 458 | MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_IFACE_COMM_TO_PORT, ~) | ||
| 459 | #undef UDI_CDC_IFACE_COMM_TO_PORT | ||
| 460 | default: | ||
| 461 | port = 0; | ||
| 462 | break; | ||
| 463 | } | ||
| 464 | */ | ||
| 465 | port = 0; | ||
| 466 | |||
| 467 | return port; | ||
| 468 | } | ||
| 469 | |||
| 470 | static void udi_cdc_line_coding_received(void) { | ||
| 471 | uint8_t port = udi_cdc_setup_to_port(); | ||
| 472 | UNUSED(port); | ||
| 473 | |||
| 474 | // UDI_CDC_SET_CODING_EXT(port, (&udi_cdc_line_coding[port])); | ||
| 475 | } | ||
| 476 | |||
| 477 | static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask) { | ||
| 478 | udd_ep_id_t ep_comm; | ||
| 479 | uint32_t irqflags; // irqflags_t | ||
| 480 | |||
| 481 | //#if UDI_CDC_PORT_NB == 1 // To optimize code | ||
| 482 | port = 0; | ||
| 483 | //#endif | ||
| 484 | |||
| 485 | // Update state | ||
| 486 | irqflags = __get_PRIMASK(); | ||
| 487 | __disable_irq(); | ||
| 488 | __DMB(); | ||
| 489 | if (b_set) { | ||
| 490 | udi_cdc_state[port] |= bit_mask; | ||
| 491 | } else { | ||
| 492 | udi_cdc_state[port] &= ~(unsigned)bit_mask; | ||
| 493 | } | ||
| 494 | __DMB(); | ||
| 495 | __set_PRIMASK(irqflags); | ||
| 496 | |||
| 497 | /* | ||
| 498 | // Send it if possible and state changed | ||
| 499 | switch (port) { | ||
| 500 | #define UDI_CDC_PORT_TO_COMM_EP(index, unused) \ | ||
| 501 | case index: \ | ||
| 502 | ep_comm = UDI_CDC_COMM_EP_##index; \ | ||
| 503 | break; | ||
| 504 | MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_COMM_EP, ~) | ||
| 505 | #undef UDI_CDC_PORT_TO_COMM_EP | ||
| 506 | default: | ||
| 507 | ep_comm = UDI_CDC_COMM_EP_0; | ||
| 508 | break; | ||
| 509 | } | ||
| 510 | */ | ||
| 511 | ep_comm = UDI_CDC_COMM_EP_0; | ||
| 512 | |||
| 513 | udi_cdc_ctrl_state_notify(port, ep_comm); | ||
| 514 | } | ||
| 515 | |||
| 516 | static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep) { | ||
| 517 | # if UDI_CDC_PORT_NB == 1 // To optimize code | ||
| 518 | port = 0; | ||
| 519 | # endif | ||
| 520 | |||
| 521 | // Send it if possible and state changed | ||
| 522 | if ((!udi_cdc_serial_state_msg_ongoing[port]) && (udi_cdc_state[port] != uid_cdc_state_msg[port].value)) { | ||
| 523 | // Fill notification message | ||
| 524 | uid_cdc_state_msg[port].value = udi_cdc_state[port]; | ||
| 525 | // Send notification message | ||
| 526 | udi_cdc_serial_state_msg_ongoing[port] = udd_ep_run(ep, false, (uint8_t *)&uid_cdc_state_msg[port], sizeof(uid_cdc_state_msg[0]), udi_cdc_serial_state_msg_sent); | ||
| 527 | } | ||
| 528 | } | ||
| 529 | |||
| 530 | static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) { | ||
| 531 | uint8_t port; | ||
| 532 | UNUSED(n); | ||
| 533 | UNUSED(status); | ||
| 534 | |||
| 535 | /* | ||
| 536 | switch (ep) { | ||
| 537 | #define UDI_CDC_GET_PORT_FROM_COMM_EP(iface, unused) \ | ||
| 538 | case UDI_CDC_COMM_EP_##iface: \ | ||
| 539 | port = iface; \ | ||
| 540 | break; | ||
| 541 | MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_GET_PORT_FROM_COMM_EP, ~) | ||
| 542 | #undef UDI_CDC_GET_PORT_FROM_COMM_EP | ||
| 543 | default: | ||
| 544 | port = 0; | ||
| 545 | break; | ||
| 546 | } | ||
| 547 | */ | ||
| 548 | port = 0; | ||
| 549 | |||
| 550 | udi_cdc_serial_state_msg_ongoing[port] = false; | ||
| 551 | |||
| 552 | // For the irregular signals like break, the incoming ring signal, | ||
| 553 | // or the overrun error state, this will reset their values to zero | ||
| 554 | // and again will not send another notification until their state changes. | ||
| 555 | udi_cdc_state[port] &= ~(CDC_SERIAL_STATE_BREAK | CDC_SERIAL_STATE_RING | CDC_SERIAL_STATE_FRAMING | CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); | ||
| 556 | uid_cdc_state_msg[port].value &= ~(CDC_SERIAL_STATE_BREAK | CDC_SERIAL_STATE_RING | CDC_SERIAL_STATE_FRAMING | CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); | ||
| 557 | // Send it if possible and state changed | ||
| 558 | udi_cdc_ctrl_state_notify(port, ep); | ||
| 559 | } | ||
| 560 | |||
| 561 | //------------------------------------------------- | ||
| 562 | //------- Internal routines to process data transfer | ||
| 563 | |||
| 564 | static bool udi_cdc_rx_start(uint8_t port) { | ||
| 565 | uint32_t irqflags; // irqflags_t | ||
| 566 | uint8_t buf_sel_trans; | ||
| 567 | udd_ep_id_t ep; | ||
| 568 | |||
| 569 | //#if UDI_CDC_PORT_NB == 1 // To optimize code | ||
| 570 | port = 0; | ||
| 571 | //#endif | ||
| 572 | |||
| 573 | irqflags = __get_PRIMASK(); | ||
| 574 | __disable_irq(); | ||
| 575 | __DMB(); | ||
| 576 | buf_sel_trans = udi_cdc_rx_buf_sel[port]; | ||
| 577 | if (udi_cdc_rx_trans_ongoing[port] || (udi_cdc_rx_pos[port] < udi_cdc_rx_buf_nb[port][buf_sel_trans])) { | ||
| 578 | // Transfer already on-going or current buffer no empty | ||
| 579 | __DMB(); | ||
| 580 | __set_PRIMASK(irqflags); | ||
| 581 | return false; | ||
| 582 | } | ||
| 583 | |||
| 584 | // Change current buffer | ||
| 585 | udi_cdc_rx_pos[port] = 0; | ||
| 586 | udi_cdc_rx_buf_sel[port] = (buf_sel_trans == 0) ? 1 : 0; | ||
| 587 | |||
| 588 | // Start transfer on RX | ||
| 589 | udi_cdc_rx_trans_ongoing[port] = true; | ||
| 590 | __DMB(); | ||
| 591 | __set_PRIMASK(irqflags); | ||
| 592 | |||
| 593 | if (udi_cdc_multi_is_rx_ready(port)) { | ||
| 594 | // UDI_CDC_RX_NOTIFY(port); | ||
| 595 | } | ||
| 596 | |||
| 597 | /* | ||
| 598 | // Send the buffer with enable of short packet | ||
| 599 | switch (port) { | ||
| 600 | #define UDI_CDC_PORT_TO_DATA_EP_OUT(index, unused) \ | ||
| 601 | case index: \ | ||
| 602 | ep = UDI_CDC_DATA_EP_OUT_##index; \ | ||
| 603 | break; | ||
| 604 | MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_OUT, ~) | ||
| 605 | #undef UDI_CDC_PORT_TO_DATA_EP_OUT | ||
| 606 | default: | ||
| 607 | ep = UDI_CDC_DATA_EP_OUT_0; | ||
| 608 | break; | ||
| 609 | } | ||
| 610 | */ | ||
| 611 | ep = UDI_CDC_DATA_EP_OUT_0; | ||
| 612 | |||
| 613 | return udd_ep_run(ep, true, udi_cdc_rx_buf[port][buf_sel_trans], UDI_CDC_RX_BUFFERS, udi_cdc_data_received); | ||
| 614 | } | ||
| 615 | |||
| 616 | static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) { | ||
| 617 | uint8_t buf_sel_trans; | ||
| 618 | uint8_t port; | ||
| 619 | |||
| 620 | /* | ||
| 621 | switch (ep) { | ||
| 622 | #define UDI_CDC_DATA_EP_OUT_TO_PORT(index, unused) \ | ||
| 623 | case UDI_CDC_DATA_EP_OUT_##index: \ | ||
| 624 | port = index; \ | ||
| 625 | break; | ||
| 626 | MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_OUT_TO_PORT, ~) | ||
| 627 | #undef UDI_CDC_DATA_EP_OUT_TO_PORT | ||
| 628 | default: | ||
| 629 | port = 0; | ||
| 630 | break; | ||
| 631 | } | ||
| 632 | */ | ||
| 633 | port = 0; | ||
| 634 | |||
| 635 | if (UDD_EP_TRANSFER_OK != status) { | ||
| 636 | // Abort reception | ||
| 637 | return; | ||
| 638 | } | ||
| 639 | |||
| 640 | buf_sel_trans = (udi_cdc_rx_buf_sel[port] == 0) ? 1 : 0; | ||
| 641 | |||
| 642 | if (!n) { | ||
| 643 | udd_ep_run(ep, true, udi_cdc_rx_buf[port][buf_sel_trans], UDI_CDC_RX_BUFFERS, udi_cdc_data_received); | ||
| 644 | return; | ||
| 645 | } | ||
| 646 | |||
| 647 | udi_cdc_rx_buf_nb[port][buf_sel_trans] = n; | ||
| 648 | udi_cdc_rx_trans_ongoing[port] = false; | ||
| 649 | udi_cdc_rx_start(port); | ||
| 650 | } | ||
| 651 | |||
| 652 | static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) { | ||
| 653 | uint8_t port; | ||
| 654 | UNUSED(n); | ||
| 655 | |||
| 656 | /* | ||
| 657 | switch (ep) { | ||
| 658 | #define UDI_CDC_DATA_EP_IN_TO_PORT(index, unused) \ | ||
| 659 | case UDI_CDC_DATA_EP_IN_##index: \ | ||
| 660 | port = index; \ | ||
| 661 | break; | ||
| 662 | MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_IN_TO_PORT, ~) | ||
| 663 | #undef UDI_CDC_DATA_EP_IN_TO_PORT | ||
| 664 | default: | ||
| 665 | port = 0; | ||
| 666 | break; | ||
| 667 | } | ||
| 668 | */ | ||
| 669 | port = 0; | ||
| 670 | |||
| 671 | if (UDD_EP_TRANSFER_OK != status) { | ||
| 672 | // Abort transfer | ||
| 673 | return; | ||
| 674 | } | ||
| 675 | |||
| 676 | udi_cdc_tx_buf_nb[port][(udi_cdc_tx_buf_sel[port] == 0) ? 1 : 0] = 0; | ||
| 677 | udi_cdc_tx_both_buf_to_send[port] = false; | ||
| 678 | udi_cdc_tx_trans_ongoing[port] = false; | ||
| 679 | |||
| 680 | if (n != 0) { | ||
| 681 | UDI_CDC_TX_EMPTY_NOTIFY(port); | ||
| 682 | } | ||
| 683 | |||
| 684 | udi_cdc_tx_send(port); | ||
| 685 | } | ||
| 686 | |||
| 687 | static void udi_cdc_tx_send(uint8_t port) { | ||
| 688 | uint32_t irqflags; // irqflags_t | ||
| 689 | uint8_t buf_sel_trans; | ||
| 690 | bool b_short_packet; | ||
| 691 | udd_ep_id_t ep; | ||
| 692 | static uint16_t sof_zlp_counter = 0; | ||
| 693 | |||
| 694 | //#if UDI_CDC_PORT_NB == 1 // To optimize code | ||
| 695 | port = 0; | ||
| 696 | //#endif | ||
| 697 | |||
| 698 | if (udi_cdc_tx_trans_ongoing[port]) { | ||
| 699 | return; // Already on going or wait next SOF to send next data | ||
| 700 | } | ||
| 701 | if (udd_is_high_speed()) { | ||
| 702 | if (udi_cdc_tx_sof_num[port] == udd_get_micro_frame_number()) { | ||
| 703 | return; // Wait next SOF to send next data | ||
| 704 | } | ||
| 705 | } else { | ||
| 706 | if (udi_cdc_tx_sof_num[port] == udd_get_frame_number()) { | ||
| 707 | return; // Wait next SOF to send next data | ||
| 708 | } | ||
| 709 | } | ||
| 710 | |||
| 711 | irqflags = __get_PRIMASK(); | ||
| 712 | __disable_irq(); | ||
| 713 | __DMB(); | ||
| 714 | buf_sel_trans = udi_cdc_tx_buf_sel[port]; | ||
| 715 | if (udi_cdc_tx_buf_nb[port][buf_sel_trans] == 0) { | ||
| 716 | sof_zlp_counter++; | ||
| 717 | if (((!udd_is_high_speed()) && (sof_zlp_counter < 100)) || (udd_is_high_speed() && (sof_zlp_counter < 800))) { | ||
| 718 | __DMB(); | ||
| 719 | __set_PRIMASK(irqflags); | ||
| 720 | return; | ||
| 721 | } | ||
| 722 | } | ||
| 723 | sof_zlp_counter = 0; | ||
| 724 | |||
| 725 | if (!udi_cdc_tx_both_buf_to_send[port]) { | ||
| 726 | // Send current Buffer | ||
| 727 | // and switch the current buffer | ||
| 728 | udi_cdc_tx_buf_sel[port] = (buf_sel_trans == 0) ? 1 : 0; | ||
| 729 | } else { | ||
| 730 | // Send the other Buffer | ||
| 731 | // and no switch the current buffer | ||
| 732 | buf_sel_trans = (buf_sel_trans == 0) ? 1 : 0; | ||
| 733 | } | ||
| 734 | udi_cdc_tx_trans_ongoing[port] = true; | ||
| 735 | __DMB(); | ||
| 736 | __set_PRIMASK(irqflags); | ||
| 737 | |||
| 738 | b_short_packet = (udi_cdc_tx_buf_nb[port][buf_sel_trans] != UDI_CDC_TX_BUFFERS); | ||
| 739 | if (b_short_packet) { | ||
| 740 | if (udd_is_high_speed()) { | ||
| 741 | udi_cdc_tx_sof_num[port] = udd_get_micro_frame_number(); | ||
| 742 | } else { | ||
| 743 | udi_cdc_tx_sof_num[port] = udd_get_frame_number(); | ||
| 744 | } | ||
| 745 | } else { | ||
| 746 | udi_cdc_tx_sof_num[port] = 0; // Force next transfer without wait SOF | ||
| 747 | } | ||
| 748 | |||
| 749 | /* | ||
| 750 | // Send the buffer with enable of short packet | ||
| 751 | switch (port) { | ||
| 752 | #define UDI_CDC_PORT_TO_DATA_EP_IN(index, unused) \ | ||
| 753 | case index: \ | ||
| 754 | ep = UDI_CDC_DATA_EP_IN_##index; \ | ||
| 755 | break; | ||
| 756 | MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_IN, ~) | ||
| 757 | #undef UDI_CDC_PORT_TO_DATA_EP_IN | ||
| 758 | default: | ||
| 759 | ep = UDI_CDC_DATA_EP_IN_0; | ||
| 760 | break; | ||
| 761 | } | ||
| 762 | */ | ||
| 763 | ep = UDI_CDC_DATA_EP_IN_0; | ||
| 764 | |||
| 765 | udd_ep_run(ep, b_short_packet, udi_cdc_tx_buf[port][buf_sel_trans], udi_cdc_tx_buf_nb[port][buf_sel_trans], udi_cdc_data_sent); | ||
| 766 | } | ||
| 767 | |||
| 768 | //--------------------------------------------- | ||
| 769 | //------- Application interface | ||
| 770 | |||
| 771 | void udi_cdc_ctrl_signal_dcd(bool b_set) { | ||
| 772 | udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DCD); | ||
| 773 | } | ||
| 774 | |||
| 775 | void udi_cdc_ctrl_signal_dsr(bool b_set) { | ||
| 776 | udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DSR); | ||
| 777 | } | ||
| 778 | |||
| 779 | void udi_cdc_signal_framing_error(void) { | ||
| 780 | udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_FRAMING); | ||
| 781 | } | ||
| 782 | |||
| 783 | void udi_cdc_signal_parity_error(void) { | ||
| 784 | udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_PARITY); | ||
| 785 | } | ||
| 786 | |||
| 787 | void udi_cdc_signal_overrun(void) { | ||
| 788 | udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_OVERRUN); | ||
| 789 | } | ||
| 790 | |||
| 791 | void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set) { | ||
| 792 | udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DCD); | ||
| 793 | } | ||
| 794 | |||
| 795 | void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set) { | ||
| 796 | udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DSR); | ||
| 797 | } | ||
| 798 | |||
| 799 | void udi_cdc_multi_signal_framing_error(uint8_t port) { | ||
| 800 | udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_FRAMING); | ||
| 801 | } | ||
| 802 | |||
| 803 | void udi_cdc_multi_signal_parity_error(uint8_t port) { | ||
| 804 | udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_PARITY); | ||
| 805 | } | ||
| 806 | |||
| 807 | void udi_cdc_multi_signal_overrun(uint8_t port) { | ||
| 808 | udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_OVERRUN); | ||
| 809 | } | ||
| 810 | |||
| 811 | iram_size_t udi_cdc_multi_get_nb_received_data(uint8_t port) { | ||
| 812 | uint32_t irqflags; // irqflags_t | ||
| 813 | uint16_t pos; | ||
| 814 | iram_size_t nb_received; | ||
| 815 | |||
| 816 | //#if UDI_CDC_PORT_NB == 1 // To optimize code | ||
| 817 | port = 0; | ||
| 818 | //#endif | ||
| 819 | |||
| 820 | irqflags = __get_PRIMASK(); | ||
| 821 | __disable_irq(); | ||
| 822 | __DMB(); | ||
| 823 | pos = udi_cdc_rx_pos[port]; | ||
| 824 | nb_received = udi_cdc_rx_buf_nb[port][udi_cdc_rx_buf_sel[port]] - pos; | ||
| 825 | __DMB(); | ||
| 826 | __set_PRIMASK(irqflags); | ||
| 827 | return nb_received; | ||
| 828 | } | ||
| 829 | |||
| 830 | iram_size_t udi_cdc_get_nb_received_data(void) { | ||
| 831 | return udi_cdc_multi_get_nb_received_data(0); | ||
| 832 | } | ||
| 833 | |||
| 834 | bool udi_cdc_multi_is_rx_ready(uint8_t port) { | ||
| 835 | return (udi_cdc_multi_get_nb_received_data(port) > 0); | ||
| 836 | } | ||
| 837 | |||
| 838 | bool udi_cdc_is_rx_ready(void) { | ||
| 839 | return udi_cdc_multi_is_rx_ready(0); | ||
| 840 | } | ||
| 841 | |||
| 842 | int udi_cdc_multi_getc(uint8_t port) { | ||
| 843 | uint32_t irqflags; // irqflags_t | ||
| 844 | int rx_data = 0; | ||
| 845 | bool b_databit_9; | ||
| 846 | uint16_t pos; | ||
| 847 | uint8_t buf_sel; | ||
| 848 | bool again; | ||
| 849 | |||
| 850 | //#if UDI_CDC_PORT_NB == 1 // To optimize code | ||
| 851 | port = 0; | ||
| 852 | //#endif | ||
| 853 | |||
| 854 | b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); | ||
| 855 | |||
| 856 | udi_cdc_getc_process_one_byte: | ||
| 857 | // Check available data | ||
| 858 | irqflags = __get_PRIMASK(); | ||
| 859 | __disable_irq(); | ||
| 860 | __DMB(); | ||
| 861 | pos = udi_cdc_rx_pos[port]; | ||
| 862 | buf_sel = udi_cdc_rx_buf_sel[port]; | ||
| 863 | again = pos >= udi_cdc_rx_buf_nb[port][buf_sel]; | ||
| 864 | __DMB(); | ||
| 865 | __set_PRIMASK(irqflags); | ||
| 866 | while (again) { | ||
| 867 | if (!udi_cdc_data_running) { | ||
| 868 | return 0; | ||
| 869 | } | ||
| 870 | goto udi_cdc_getc_process_one_byte; | ||
| 871 | } | ||
| 872 | |||
| 873 | // Read data | ||
| 874 | rx_data |= udi_cdc_rx_buf[port][buf_sel][pos]; | ||
| 875 | udi_cdc_rx_pos[port] = pos + 1; | ||
| 876 | |||
| 877 | udi_cdc_rx_start(port); | ||
| 878 | |||
| 879 | if (b_databit_9) { | ||
| 880 | // Receive MSB | ||
| 881 | b_databit_9 = false; | ||
| 882 | rx_data = rx_data << 8; | ||
| 883 | goto udi_cdc_getc_process_one_byte; | ||
| 884 | } | ||
| 885 | return rx_data; | ||
| 886 | } | ||
| 887 | |||
| 888 | int udi_cdc_getc(void) { | ||
| 889 | return udi_cdc_multi_getc(0); | ||
| 890 | } | ||
| 891 | |||
| 892 | iram_size_t udi_cdc_multi_read_buf(uint8_t port, void *buf, iram_size_t size) { | ||
| 893 | uint32_t irqflags; // irqflags_t | ||
| 894 | uint8_t * ptr_buf = (uint8_t *)buf; | ||
| 895 | iram_size_t copy_nb; | ||
| 896 | uint16_t pos; | ||
| 897 | uint8_t buf_sel; | ||
| 898 | bool again; | ||
| 899 | |||
| 900 | //#if UDI_CDC_PORT_NB == 1 // To optimize code | ||
| 901 | port = 0; | ||
| 902 | //#endif | ||
| 903 | |||
| 904 | udi_cdc_read_buf_loop_wait: | ||
| 905 | // Check available data | ||
| 906 | irqflags = __get_PRIMASK(); | ||
| 907 | __disable_irq(); | ||
| 908 | __DMB(); | ||
| 909 | pos = udi_cdc_rx_pos[port]; | ||
| 910 | buf_sel = udi_cdc_rx_buf_sel[port]; | ||
| 911 | again = pos >= udi_cdc_rx_buf_nb[port][buf_sel]; | ||
| 912 | __DMB(); | ||
| 913 | __set_PRIMASK(irqflags); | ||
| 914 | while (again) { | ||
| 915 | if (!udi_cdc_data_running) { | ||
| 916 | return size; | ||
| 917 | } | ||
| 918 | goto udi_cdc_read_buf_loop_wait; | ||
| 919 | } | ||
| 920 | |||
| 921 | // Read data | ||
| 922 | copy_nb = udi_cdc_rx_buf_nb[port][buf_sel] - pos; | ||
| 923 | if (copy_nb > size) { | ||
| 924 | copy_nb = size; | ||
| 925 | } | ||
| 926 | memcpy(ptr_buf, &udi_cdc_rx_buf[port][buf_sel][pos], copy_nb); | ||
| 927 | udi_cdc_rx_pos[port] += copy_nb; | ||
| 928 | ptr_buf += copy_nb; | ||
| 929 | size -= copy_nb; | ||
| 930 | udi_cdc_rx_start(port); | ||
| 931 | |||
| 932 | if (size) { | ||
| 933 | goto udi_cdc_read_buf_loop_wait; | ||
| 934 | } | ||
| 935 | return 0; | ||
| 936 | } | ||
| 937 | |||
| 938 | static iram_size_t udi_cdc_multi_read_no_polling(uint8_t port, void *buf, iram_size_t size) { | ||
| 939 | uint8_t * ptr_buf = (uint8_t *)buf; | ||
| 940 | iram_size_t nb_avail_data; | ||
| 941 | uint16_t pos; | ||
| 942 | uint8_t buf_sel; | ||
| 943 | uint32_t irqflags; // irqflags_t | ||
| 944 | |||
| 945 | //#if UDI_CDC_PORT_NB == 1 // To optimize code | ||
| 946 | port = 0; | ||
| 947 | //#endif | ||
| 948 | |||
| 949 | // Data interface not started... exit | ||
| 950 | if (!udi_cdc_data_running) { | ||
| 951 | return 0; | ||
| 952 | } | ||
| 953 | |||
| 954 | // Get number of available data | ||
| 955 | // Check available data | ||
| 956 | irqflags = __get_PRIMASK(); | ||
| 957 | __disable_irq(); | ||
| 958 | __DMB(); | ||
| 959 | pos = udi_cdc_rx_pos[port]; | ||
| 960 | buf_sel = udi_cdc_rx_buf_sel[port]; | ||
| 961 | nb_avail_data = udi_cdc_rx_buf_nb[port][buf_sel] - pos; | ||
| 962 | __DMB(); | ||
| 963 | __set_PRIMASK(irqflags); | ||
| 964 | // If the buffer contains less than the requested number of data, | ||
| 965 | // adjust read size | ||
| 966 | if (nb_avail_data < size) { | ||
| 967 | size = nb_avail_data; | ||
| 968 | } | ||
| 969 | if (size > 0) { | ||
| 970 | memcpy(ptr_buf, &udi_cdc_rx_buf[port][buf_sel][pos], size); | ||
| 971 | irqflags = __get_PRIMASK(); | ||
| 972 | __disable_irq(); | ||
| 973 | __DMB(); | ||
| 974 | udi_cdc_rx_pos[port] += size; | ||
| 975 | __DMB(); | ||
| 976 | __set_PRIMASK(irqflags); | ||
| 977 | ptr_buf += size; | ||
| 978 | udi_cdc_rx_start(port); | ||
| 979 | } | ||
| 980 | return (nb_avail_data); | ||
| 981 | } | ||
| 982 | |||
| 983 | iram_size_t udi_cdc_read_no_polling(void *buf, iram_size_t size) { | ||
| 984 | return udi_cdc_multi_read_no_polling(0, buf, size); | ||
| 985 | } | ||
| 986 | |||
| 987 | iram_size_t udi_cdc_read_buf(void *buf, iram_size_t size) { | ||
| 988 | return udi_cdc_multi_read_buf(0, buf, size); | ||
| 989 | } | ||
| 990 | |||
| 991 | iram_size_t udi_cdc_multi_get_free_tx_buffer(uint8_t port) { | ||
| 992 | uint32_t irqflags; // irqflags_t | ||
| 993 | iram_size_t buf_sel_nb, retval; | ||
| 994 | uint8_t buf_sel; | ||
| 995 | |||
| 996 | //#if UDI_CDC_PORT_NB == 1 // To optimize code | ||
| 997 | port = 0; | ||
| 998 | //#endif | ||
| 999 | |||
| 1000 | irqflags = __get_PRIMASK(); | ||
| 1001 | __disable_irq(); | ||
| 1002 | __DMB(); | ||
| 1003 | buf_sel = udi_cdc_tx_buf_sel[port]; | ||
| 1004 | buf_sel_nb = udi_cdc_tx_buf_nb[port][buf_sel]; | ||
| 1005 | if (buf_sel_nb == UDI_CDC_TX_BUFFERS) { | ||
| 1006 | if ((!udi_cdc_tx_trans_ongoing[port]) && (!udi_cdc_tx_both_buf_to_send[port])) { | ||
| 1007 | /* One buffer is full, but the other buffer is not used. | ||
| 1008 | * (not used = transfer on-going) | ||
| 1009 | * then move to the other buffer to store data */ | ||
| 1010 | udi_cdc_tx_both_buf_to_send[port] = true; | ||
| 1011 | udi_cdc_tx_buf_sel[port] = (buf_sel == 0) ? 1 : 0; | ||
| 1012 | buf_sel_nb = 0; | ||
| 1013 | } | ||
| 1014 | } | ||
| 1015 | retval = UDI_CDC_TX_BUFFERS - buf_sel_nb; | ||
| 1016 | __DMB(); | ||
| 1017 | __set_PRIMASK(irqflags); | ||
| 1018 | return retval; | ||
| 1019 | } | ||
| 1020 | |||
| 1021 | iram_size_t udi_cdc_get_free_tx_buffer(void) { | ||
| 1022 | return udi_cdc_multi_get_free_tx_buffer(0); | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | bool udi_cdc_multi_is_tx_ready(uint8_t port) { | ||
| 1026 | return (udi_cdc_multi_get_free_tx_buffer(port) != 0); | ||
| 1027 | } | ||
| 1028 | |||
| 1029 | bool udi_cdc_is_tx_ready(void) { | ||
| 1030 | return udi_cdc_multi_is_tx_ready(0); | ||
| 1031 | } | ||
| 1032 | |||
| 1033 | int udi_cdc_multi_putc(uint8_t port, int value) { | ||
| 1034 | uint32_t irqflags; // irqflags_t | ||
| 1035 | bool b_databit_9; | ||
| 1036 | uint8_t buf_sel; | ||
| 1037 | |||
| 1038 | //#if UDI_CDC_PORT_NB == 1 // To optimize code | ||
| 1039 | port = 0; | ||
| 1040 | //#endif | ||
| 1041 | |||
| 1042 | b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); | ||
| 1043 | |||
| 1044 | udi_cdc_putc_process_one_byte: | ||
| 1045 | // Check available space | ||
| 1046 | if (!udi_cdc_multi_is_tx_ready(port)) { | ||
| 1047 | if (!udi_cdc_data_running) { | ||
| 1048 | return false; | ||
| 1049 | } | ||
| 1050 | goto udi_cdc_putc_process_one_byte; | ||
| 1051 | } | ||
| 1052 | |||
| 1053 | // Write value | ||
| 1054 | irqflags = __get_PRIMASK(); | ||
| 1055 | __disable_irq(); | ||
| 1056 | __DMB(); | ||
| 1057 | buf_sel = udi_cdc_tx_buf_sel[port]; | ||
| 1058 | udi_cdc_tx_buf[port][buf_sel][udi_cdc_tx_buf_nb[port][buf_sel]++] = value; | ||
| 1059 | __DMB(); | ||
| 1060 | __set_PRIMASK(irqflags); | ||
| 1061 | |||
| 1062 | if (b_databit_9) { | ||
| 1063 | // Send MSB | ||
| 1064 | b_databit_9 = false; | ||
| 1065 | value = value >> 8; | ||
| 1066 | goto udi_cdc_putc_process_one_byte; | ||
| 1067 | } | ||
| 1068 | return true; | ||
| 1069 | } | ||
| 1070 | |||
| 1071 | int udi_cdc_putc(int value) { | ||
| 1072 | return udi_cdc_multi_putc(0, value); | ||
| 1073 | } | ||
| 1074 | |||
| 1075 | iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void *buf, iram_size_t size) { | ||
| 1076 | uint32_t irqflags; // irqflags_t | ||
| 1077 | uint8_t buf_sel; | ||
| 1078 | uint16_t buf_nb; | ||
| 1079 | iram_size_t copy_nb; | ||
| 1080 | uint8_t * ptr_buf = (uint8_t *)buf; | ||
| 1081 | |||
| 1082 | //#if UDI_CDC_PORT_NB == 1 // To optimize code | ||
| 1083 | port = 0; | ||
| 1084 | //#endif | ||
| 1085 | |||
| 1086 | if (9 == udi_cdc_line_coding[port].bDataBits) { | ||
| 1087 | size *= 2; | ||
| 1088 | } | ||
| 1089 | |||
| 1090 | udi_cdc_write_buf_loop_wait: | ||
| 1091 | |||
| 1092 | // Check available space | ||
| 1093 | if (!udi_cdc_multi_is_tx_ready(port)) { | ||
| 1094 | if (!udi_cdc_data_running) { | ||
| 1095 | return size; | ||
| 1096 | } | ||
| 1097 | goto udi_cdc_write_buf_loop_wait; | ||
| 1098 | } | ||
| 1099 | |||
| 1100 | // Write values | ||
| 1101 | irqflags = __get_PRIMASK(); | ||
| 1102 | __disable_irq(); | ||
| 1103 | __DMB(); | ||
| 1104 | buf_sel = udi_cdc_tx_buf_sel[port]; | ||
| 1105 | buf_nb = udi_cdc_tx_buf_nb[port][buf_sel]; | ||
| 1106 | copy_nb = UDI_CDC_TX_BUFFERS - buf_nb; | ||
| 1107 | if (copy_nb > size) { | ||
| 1108 | copy_nb = size; | ||
| 1109 | } | ||
| 1110 | memcpy(&udi_cdc_tx_buf[port][buf_sel][buf_nb], ptr_buf, copy_nb); | ||
| 1111 | udi_cdc_tx_buf_nb[port][buf_sel] = buf_nb + copy_nb; | ||
| 1112 | __DMB(); | ||
| 1113 | __set_PRIMASK(irqflags); | ||
| 1114 | |||
| 1115 | // Update buffer pointer | ||
| 1116 | ptr_buf = ptr_buf + copy_nb; | ||
| 1117 | size -= copy_nb; | ||
| 1118 | |||
| 1119 | if (size) { | ||
| 1120 | goto udi_cdc_write_buf_loop_wait; | ||
| 1121 | } | ||
| 1122 | |||
| 1123 | return 0; | ||
| 1124 | } | ||
| 1125 | |||
| 1126 | iram_size_t udi_cdc_write_buf(const void *buf, iram_size_t size) { | ||
| 1127 | return udi_cdc_multi_write_buf(0, buf, size); | ||
| 1128 | } | ||
| 1129 | |||
| 1130 | # define MAX_PRINT 256 | ||
| 1131 | # define CDC_SEND_INTERVAL 2 | ||
| 1132 | uint32_t cdc_tx_send_time_next; | ||
| 1133 | |||
| 1134 | void CDC_send(void) { | ||
| 1135 | while (timer_read64() < cdc_tx_send_time_next) | ||
| 1136 | ; | ||
| 1137 | udi_cdc_tx_send(0); | ||
| 1138 | cdc_tx_send_time_next = timer_read64() + CDC_SEND_INTERVAL; | ||
| 1139 | } | ||
| 1140 | |||
| 1141 | uint32_t CDC_print(char *printbuf) { | ||
| 1142 | uint32_t count = 0; | ||
| 1143 | char * buf = printbuf; | ||
| 1144 | char c; | ||
| 1145 | |||
| 1146 | if (timer_read64() < 5000) return 0; | ||
| 1147 | |||
| 1148 | while ((c = *buf++) != 0 && !(count >= MAX_PRINT)) { | ||
| 1149 | count++; | ||
| 1150 | if (!udi_cdc_is_tx_ready()) return 0; | ||
| 1151 | udi_cdc_putc(c); | ||
| 1152 | if (count >= UDI_CDC_TX_BUFFERS) { | ||
| 1153 | count = 0; | ||
| 1154 | CDC_send(); | ||
| 1155 | } | ||
| 1156 | } | ||
| 1157 | if (count) { | ||
| 1158 | CDC_send(); | ||
| 1159 | } | ||
| 1160 | return 1; | ||
| 1161 | } | ||
| 1162 | |||
| 1163 | char printbuf[CDC_PRINTBUF_SIZE]; | ||
| 1164 | |||
| 1165 | int CDC_printf(const char *_Format, ...) { | ||
| 1166 | va_list va; // Variable argument list variable | ||
| 1167 | int result; | ||
| 1168 | |||
| 1169 | va_start(va, _Format); // Initialize the variable argument list | ||
| 1170 | result = vsnprintf(printbuf, CDC_PRINTBUF_SIZE, _Format, va); | ||
| 1171 | va_end(va); | ||
| 1172 | |||
| 1173 | CDC_print(printbuf); | ||
| 1174 | |||
| 1175 | return result; | ||
| 1176 | } | ||
| 1177 | |||
| 1178 | // global "inbuf" if desired | ||
| 1179 | inbuf_t inbuf; | ||
| 1180 | |||
| 1181 | uint32_t CDC_input_buf(inbuf_t inbuf, uint32_t inbuf_size) { | ||
| 1182 | int RXChar; | ||
| 1183 | int entered = 0; | ||
| 1184 | |||
| 1185 | if (!udi_cdc_is_rx_ready()) return 0; | ||
| 1186 | udi_cdc_get_nb_received_data(); | ||
| 1187 | RXChar = udi_cdc_getc(); | ||
| 1188 | |||
| 1189 | if (RXChar) { | ||
| 1190 | switch (RXChar) { | ||
| 1191 | case '\t': // tab - repeat last | ||
| 1192 | inbuf.count = inbuf.lastcount; | ||
| 1193 | inbuf.buf[inbuf.count + 1] = 0; | ||
| 1194 | CDC_print(inbuf.buf); | ||
| 1195 | break; | ||
| 1196 | case '\r': // enter | ||
| 1197 | inbuf.buf[inbuf.count] = 0; | ||
| 1198 | inbuf.lastcount = inbuf.count; | ||
| 1199 | inbuf.count = 0; | ||
| 1200 | entered = 1; | ||
| 1201 | break; | ||
| 1202 | case '\b': // backspace | ||
| 1203 | if (inbuf.count > 0) { | ||
| 1204 | inbuf.count -= 1; | ||
| 1205 | CDC_print("\b \b\0"); | ||
| 1206 | } else | ||
| 1207 | CDC_print("\a\0"); | ||
| 1208 | break; | ||
| 1209 | default: | ||
| 1210 | if ((RXChar >= 32) && (RXChar <= 126)) { | ||
| 1211 | if (inbuf.count < inbuf_size - 1) { | ||
| 1212 | inbuf.buf[inbuf.count] = RXChar; | ||
| 1213 | inbuf.buf[inbuf.count + 1] = 0; | ||
| 1214 | CDC_print(&inbuf.buf[inbuf.count]); | ||
| 1215 | inbuf.count += 1; | ||
| 1216 | } else | ||
| 1217 | CDC_print("\a\0"); | ||
| 1218 | } | ||
| 1219 | break; | ||
| 1220 | } | ||
| 1221 | RXChar = 0; | ||
| 1222 | } | ||
| 1223 | return entered; | ||
| 1224 | } | ||
| 1225 | |||
| 1226 | uint32_t CDC_input() { | ||
| 1227 | return CDC_input_buf(inbuf, CDC_INBUF_SIZE); | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | void CDC_init(void) { | ||
| 1231 | inbuf.count = 0; | ||
| 1232 | inbuf.lastcount = 0; | ||
| 1233 | printbuf[0] = 0; | ||
| 1234 | cdc_tx_send_time_next = timer_read64() + CDC_SEND_INTERVAL; | ||
| 1235 | } | ||
| 1236 | |||
| 1237 | #else // CDC line 62 | ||
| 1238 | |||
| 1239 | char printbuf[CDC_PRINTBUF_SIZE]; | ||
| 1240 | |||
| 1241 | void CDC_send(void) { | ||
| 1242 | return; | ||
| 1243 | } | ||
| 1244 | |||
| 1245 | uint32_t CDC_print(char *printbuf) { | ||
| 1246 | return 0; | ||
| 1247 | } | ||
| 1248 | |||
| 1249 | int CDC_printf(const char *_Format, ...) { | ||
| 1250 | return 0; | ||
| 1251 | } | ||
| 1252 | |||
| 1253 | inbuf_t inbuf; | ||
| 1254 | |||
| 1255 | uint32_t CDC_input(void) { | ||
| 1256 | return 0; | ||
| 1257 | } | ||
| 1258 | |||
| 1259 | void CDC_init(void) { | ||
| 1260 | inbuf.count = 0; | ||
| 1261 | inbuf.lastcount = 0; | ||
| 1262 | printbuf[0] = 0; | ||
| 1263 | } | ||
| 1264 | |||
| 1265 | #endif // CDC line 62 | ||
| 1266 | |||
| 1267 | //@} | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_cdc.h b/tmk_core/protocol/arm_atsam/usb/udi_cdc.h deleted file mode 100644 index ff4f521ce0..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/udi_cdc.h +++ /dev/null | |||
| @@ -1,376 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief USB Device Communication Device Class (CDC) interface definitions. | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009-2016 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #ifndef _UDI_CDC_H_ | ||
| 48 | #define _UDI_CDC_H_ | ||
| 49 | |||
| 50 | #ifdef VIRTSER_ENABLE | ||
| 51 | |||
| 52 | # include "conf_usb.h" | ||
| 53 | # include "usb_protocol.h" | ||
| 54 | # include "usb_protocol_cdc.h" | ||
| 55 | # include "udd.h" | ||
| 56 | # include "udc_desc.h" | ||
| 57 | # include "udi.h" | ||
| 58 | |||
| 59 | // Check the number of port | ||
| 60 | # ifndef UDI_CDC_PORT_NB | ||
| 61 | # define UDI_CDC_PORT_NB 1 | ||
| 62 | # endif | ||
| 63 | # if (UDI_CDC_PORT_NB > 1) | ||
| 64 | # error UDI_CDC_PORT_NB must be at most 1 | ||
| 65 | # endif | ||
| 66 | |||
| 67 | # ifdef __cplusplus | ||
| 68 | extern "C" { | ||
| 69 | # endif | ||
| 70 | |||
| 71 | /** | ||
| 72 | * \addtogroup udi_cdc_group_udc | ||
| 73 | * @{ | ||
| 74 | */ | ||
| 75 | |||
| 76 | //! Global structure which contains standard UDI API for UDC | ||
| 77 | extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm; | ||
| 78 | extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_data; | ||
| 79 | //@} | ||
| 80 | |||
| 81 | //#define CDC_ACM_SIZE 64 see usb_protocol_cdc.h | ||
| 82 | //#define CDC_RX_SIZE 64 | ||
| 83 | |||
| 84 | //! CDC communication endpoints size for all speeds | ||
| 85 | # define UDI_CDC_COMM_EP_SIZE CDC_ACM_SIZE | ||
| 86 | //! CDC data endpoints size for FS speed (8B, 16B, 32B, 64B) | ||
| 87 | # define UDI_CDC_DATA_EPS_FS_SIZE CDC_RX_SIZE | ||
| 88 | |||
| 89 | //@} | ||
| 90 | |||
| 91 | /** | ||
| 92 | * \ingroup udi_group | ||
| 93 | * \defgroup udi_cdc_group USB Device Interface (UDI) for Communication Class Device (CDC) | ||
| 94 | * | ||
| 95 | * Common APIs used by high level application to use this USB class. | ||
| 96 | * | ||
| 97 | * These routines are used to transfer and control data | ||
| 98 | * to/from USB CDC endpoint. | ||
| 99 | * | ||
| 100 | * See \ref udi_cdc_quickstart. | ||
| 101 | * @{ | ||
| 102 | */ | ||
| 103 | |||
| 104 | /** | ||
| 105 | * \name Interface for application with single CDC interface support | ||
| 106 | */ | ||
| 107 | //@{ | ||
| 108 | |||
| 109 | /** | ||
| 110 | * \brief Notify a state change of DCD signal | ||
| 111 | * | ||
| 112 | * \param b_set DCD is enabled if true, else disabled | ||
| 113 | */ | ||
| 114 | void udi_cdc_ctrl_signal_dcd(bool b_set); | ||
| 115 | |||
| 116 | /** | ||
| 117 | * \brief Notify a state change of DSR signal | ||
| 118 | * | ||
| 119 | * \param b_set DSR is enabled if true, else disabled | ||
| 120 | */ | ||
| 121 | void udi_cdc_ctrl_signal_dsr(bool b_set); | ||
| 122 | |||
| 123 | /** | ||
| 124 | * \brief Notify a framing error | ||
| 125 | */ | ||
| 126 | void udi_cdc_signal_framing_error(void); | ||
| 127 | |||
| 128 | /** | ||
| 129 | * \brief Notify a parity error | ||
| 130 | */ | ||
| 131 | void udi_cdc_signal_parity_error(void); | ||
| 132 | |||
| 133 | /** | ||
| 134 | * \brief Notify a overrun | ||
| 135 | */ | ||
| 136 | void udi_cdc_signal_overrun(void); | ||
| 137 | |||
| 138 | /** | ||
| 139 | * \brief Gets the number of byte received | ||
| 140 | * | ||
| 141 | * \return the number of data available | ||
| 142 | */ | ||
| 143 | iram_size_t udi_cdc_get_nb_received_data(void); | ||
| 144 | |||
| 145 | /** | ||
| 146 | * \brief This function checks if a character has been received on the CDC line | ||
| 147 | * | ||
| 148 | * \return \c 1 if a byte is ready to be read. | ||
| 149 | */ | ||
| 150 | bool udi_cdc_is_rx_ready(void); | ||
| 151 | |||
| 152 | /** | ||
| 153 | * \brief Waits and gets a value on CDC line | ||
| 154 | * | ||
| 155 | * \return value read on CDC line | ||
| 156 | */ | ||
| 157 | int udi_cdc_getc(void); | ||
| 158 | |||
| 159 | /** | ||
| 160 | * \brief Reads a RAM buffer on CDC line | ||
| 161 | * | ||
| 162 | * \param buf Values read | ||
| 163 | * \param size Number of value read | ||
| 164 | * | ||
| 165 | * \return the number of data remaining | ||
| 166 | */ | ||
| 167 | iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size); | ||
| 168 | |||
| 169 | /** | ||
| 170 | * \brief Non polling reads of a up to 'size' data from CDC line | ||
| 171 | * | ||
| 172 | * \param port Communication port number to manage | ||
| 173 | * \param buf Buffer where to store read data | ||
| 174 | * \param size Maximum number of data to read (size of buffer) | ||
| 175 | * | ||
| 176 | * \return the number of data effectively read | ||
| 177 | */ | ||
| 178 | iram_size_t udi_cdc_read_no_polling(void* buf, iram_size_t size); | ||
| 179 | |||
| 180 | /** | ||
| 181 | * \brief Gets the number of free byte in TX buffer | ||
| 182 | * | ||
| 183 | * \return the number of free byte in TX buffer | ||
| 184 | */ | ||
| 185 | iram_size_t udi_cdc_get_free_tx_buffer(void); | ||
| 186 | |||
| 187 | /** | ||
| 188 | * \brief This function checks if a new character sent is possible | ||
| 189 | * The type int is used to support scanf redirection from compiler LIB. | ||
| 190 | * | ||
| 191 | * \return \c 1 if a new character can be sent | ||
| 192 | */ | ||
| 193 | bool udi_cdc_is_tx_ready(void); | ||
| 194 | |||
| 195 | /** | ||
| 196 | * \brief Puts a byte on CDC line | ||
| 197 | * The type int is used to support printf redirection from compiler LIB. | ||
| 198 | * | ||
| 199 | * \param value Value to put | ||
| 200 | * | ||
| 201 | * \return \c 1 if function was successfully done, otherwise \c 0. | ||
| 202 | */ | ||
| 203 | int udi_cdc_putc(int value); | ||
| 204 | |||
| 205 | /** | ||
| 206 | * \brief Writes a RAM buffer on CDC line | ||
| 207 | * | ||
| 208 | * \param buf Values to write | ||
| 209 | * \param size Number of value to write | ||
| 210 | * | ||
| 211 | * \return the number of data remaining | ||
| 212 | */ | ||
| 213 | iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size); | ||
| 214 | //@} | ||
| 215 | |||
| 216 | /** | ||
| 217 | * \name Interface for application with multi CDC interfaces support | ||
| 218 | */ | ||
| 219 | //@{ | ||
| 220 | |||
| 221 | /** | ||
| 222 | * \brief Notify a state change of DCD signal | ||
| 223 | * | ||
| 224 | * \param port Communication port number to manage | ||
| 225 | * \param b_set DCD is enabled if true, else disabled | ||
| 226 | */ | ||
| 227 | void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set); | ||
| 228 | |||
| 229 | /** | ||
| 230 | * \brief Notify a state change of DSR signal | ||
| 231 | * | ||
| 232 | * \param port Communication port number to manage | ||
| 233 | * \param b_set DSR is enabled if true, else disabled | ||
| 234 | */ | ||
| 235 | void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set); | ||
| 236 | |||
| 237 | /** | ||
| 238 | * \brief Notify a framing error | ||
| 239 | * | ||
| 240 | * \param port Communication port number to manage | ||
| 241 | */ | ||
| 242 | void udi_cdc_multi_signal_framing_error(uint8_t port); | ||
| 243 | |||
| 244 | /** | ||
| 245 | * \brief Notify a parity error | ||
| 246 | * | ||
| 247 | * \param port Communication port number to manage | ||
| 248 | */ | ||
| 249 | void udi_cdc_multi_signal_parity_error(uint8_t port); | ||
| 250 | |||
| 251 | /** | ||
| 252 | * \brief Notify a overrun | ||
| 253 | * | ||
| 254 | * \param port Communication port number to manage | ||
| 255 | */ | ||
| 256 | void udi_cdc_multi_signal_overrun(uint8_t port); | ||
| 257 | |||
| 258 | /** | ||
| 259 | * \brief Gets the number of byte received | ||
| 260 | * | ||
| 261 | * \param port Communication port number to manage | ||
| 262 | * | ||
| 263 | * \return the number of data available | ||
| 264 | */ | ||
| 265 | iram_size_t udi_cdc_multi_get_nb_received_data(uint8_t port); | ||
| 266 | |||
| 267 | /** | ||
| 268 | * \brief This function checks if a character has been received on the CDC line | ||
| 269 | * | ||
| 270 | * \param port Communication port number to manage | ||
| 271 | * | ||
| 272 | * \return \c 1 if a byte is ready to be read. | ||
| 273 | */ | ||
| 274 | bool udi_cdc_multi_is_rx_ready(uint8_t port); | ||
| 275 | |||
| 276 | /** | ||
| 277 | * \brief Waits and gets a value on CDC line | ||
| 278 | * | ||
| 279 | * \param port Communication port number to manage | ||
| 280 | * | ||
| 281 | * \return value read on CDC line | ||
| 282 | */ | ||
| 283 | int udi_cdc_multi_getc(uint8_t port); | ||
| 284 | |||
| 285 | /** | ||
| 286 | * \brief Reads a RAM buffer on CDC line | ||
| 287 | * | ||
| 288 | * \param port Communication port number to manage | ||
| 289 | * \param buf Values read | ||
| 290 | * \param size Number of values read | ||
| 291 | * | ||
| 292 | * \return the number of data remaining | ||
| 293 | */ | ||
| 294 | iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size); | ||
| 295 | |||
| 296 | /** | ||
| 297 | * \brief Gets the number of free byte in TX buffer | ||
| 298 | * | ||
| 299 | * \param port Communication port number to manage | ||
| 300 | * | ||
| 301 | * \return the number of free byte in TX buffer | ||
| 302 | */ | ||
| 303 | iram_size_t udi_cdc_multi_get_free_tx_buffer(uint8_t port); | ||
| 304 | |||
| 305 | /** | ||
| 306 | * \brief This function checks if a new character sent is possible | ||
| 307 | * The type int is used to support scanf redirection from compiler LIB. | ||
| 308 | * | ||
| 309 | * \param port Communication port number to manage | ||
| 310 | * | ||
| 311 | * \return \c 1 if a new character can be sent | ||
| 312 | */ | ||
| 313 | bool udi_cdc_multi_is_tx_ready(uint8_t port); | ||
| 314 | |||
| 315 | /** | ||
| 316 | * \brief Puts a byte on CDC line | ||
| 317 | * The type int is used to support printf redirection from compiler LIB. | ||
| 318 | * | ||
| 319 | * \param port Communication port number to manage | ||
| 320 | * \param value Value to put | ||
| 321 | * | ||
| 322 | * \return \c 1 if function was successfully done, otherwise \c 0. | ||
| 323 | */ | ||
| 324 | int udi_cdc_multi_putc(uint8_t port, int value); | ||
| 325 | |||
| 326 | /** | ||
| 327 | * \brief Writes a RAM buffer on CDC line | ||
| 328 | * | ||
| 329 | * \param port Communication port number to manage | ||
| 330 | * \param buf Values to write | ||
| 331 | * \param size Number of value to write | ||
| 332 | * | ||
| 333 | * \return the number of data remaining | ||
| 334 | */ | ||
| 335 | iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size); | ||
| 336 | //@} | ||
| 337 | |||
| 338 | # define CDC_PRINTBUF_SIZE 256 | ||
| 339 | extern char printbuf[CDC_PRINTBUF_SIZE]; | ||
| 340 | |||
| 341 | # define CDC_INBUF_SIZE 256 | ||
| 342 | |||
| 343 | typedef struct { | ||
| 344 | uint32_t count; | ||
| 345 | uint32_t lastcount; | ||
| 346 | char buf[CDC_INBUF_SIZE]; | ||
| 347 | } inbuf_t; | ||
| 348 | |||
| 349 | #else // VIRTSER_ENABLE | ||
| 350 | |||
| 351 | // keep these to accommodate calls if remaining | ||
| 352 | # define CDC_PRINTBUF_SIZE 1 | ||
| 353 | extern char printbuf[CDC_PRINTBUF_SIZE]; | ||
| 354 | |||
| 355 | # define CDC_INBUF_SIZE 1 | ||
| 356 | |||
| 357 | typedef struct { | ||
| 358 | uint32_t count; | ||
| 359 | uint32_t lastcount; | ||
| 360 | char buf[CDC_INBUF_SIZE]; | ||
| 361 | } inbuf_t; | ||
| 362 | |||
| 363 | extern inbuf_t inbuf; | ||
| 364 | |||
| 365 | #endif // VIRTSER_ENABLE | ||
| 366 | |||
| 367 | uint32_t CDC_print(char* printbuf); | ||
| 368 | int CDC_printf(const char* _Format, ...); | ||
| 369 | uint32_t CDC_input(void); | ||
| 370 | void CDC_init(void); | ||
| 371 | |||
| 372 | #ifdef __cplusplus | ||
| 373 | } | ||
| 374 | #endif | ||
| 375 | |||
| 376 | #endif // _UDI_CDC_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_cdc_conf.h b/tmk_core/protocol/arm_atsam/usb/udi_cdc_conf.h deleted file mode 100644 index e17ed7bf44..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/udi_cdc_conf.h +++ /dev/null | |||
| @@ -1,72 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief Default CDC configuration for a USB Device with a single interface | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #ifndef _UDI_CDC_CONF_H_ | ||
| 48 | #define _UDI_CDC_CONF_H_ | ||
| 49 | |||
| 50 | #include "usb_protocol_cdc.h" | ||
| 51 | #include "conf_usb.h" | ||
| 52 | #include "udi_device_conf.h" | ||
| 53 | |||
| 54 | #ifndef UDI_CDC_PORT_NB | ||
| 55 | # define UDI_CDC_PORT_NB 1 | ||
| 56 | #endif | ||
| 57 | |||
| 58 | #ifdef __cplusplus | ||
| 59 | extern "C" { | ||
| 60 | #endif | ||
| 61 | |||
| 62 | #define UDI_CDC_DATA_EP_IN_0 ((CDC_TX_ENDPOINT) | (USB_EP_DIR_IN)) // TX | ||
| 63 | #define UDI_CDC_DATA_EP_OUT_0 ((CDC_RX_ENDPOINT) | (USB_EP_DIR_OUT)) // RX | ||
| 64 | #define UDI_CDC_COMM_EP_0 ((CDC_ACM_ENDPOINT) | (USB_EP_DIR_IN)) // Notify endpoint | ||
| 65 | |||
| 66 | #define UDI_CDC_COMM_IFACE_NUMBER_0 (CDC_STATUS_INTERFACE) | ||
| 67 | #define UDI_CDC_DATA_IFACE_NUMBER_0 (CDC_DATA_INTERFACE) | ||
| 68 | |||
| 69 | #ifdef __cplusplus | ||
| 70 | } | ||
| 71 | #endif | ||
| 72 | #endif // _UDI_CDC_CONF_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_device_conf.h b/tmk_core/protocol/arm_atsam/usb/udi_device_conf.h deleted file mode 100644 index a3c6f1c397..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/udi_device_conf.h +++ /dev/null | |||
| @@ -1,806 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef _UDI_DEVICE_CONF_H_ | ||
| 19 | #define _UDI_DEVICE_CONF_H_ | ||
| 20 | |||
| 21 | #include "udi_device_epsize.h" | ||
| 22 | #include "usb_protocol.h" | ||
| 23 | #include "compiler.h" | ||
| 24 | #include "usb_protocol_hid.h" | ||
| 25 | |||
| 26 | #ifndef USB_POLLING_INTERVAL_MS | ||
| 27 | # define USB_POLLING_INTERVAL_MS 10 | ||
| 28 | #endif | ||
| 29 | |||
| 30 | #ifdef VIRTSER_ENABLE | ||
| 31 | // because CDC uses IAD (interface association descriptor | ||
| 32 | // per USB Interface Association Descriptor Device Class Code and Use Model 7/23/2003 Rev 1.0) | ||
| 33 | # define DEVICE_CLASS 0xEF | ||
| 34 | # define DEVICE_SUBCLASS 0x02 | ||
| 35 | # define DEVICE_PROTOCOL 0x01 | ||
| 36 | #else | ||
| 37 | # define DEVICE_CLASS 0x00 | ||
| 38 | # define DEVICE_SUBCLASS 0x00 | ||
| 39 | # define DEVICE_PROTOCOL 0x00 | ||
| 40 | #endif | ||
| 41 | |||
| 42 | /* number of interfaces */ | ||
| 43 | #define NEXT_INTERFACE_0 0 | ||
| 44 | |||
| 45 | #define KEYBOARD_INTERFACE NEXT_INTERFACE_0 | ||
| 46 | #define NEXT_INTERFACE_1 (KEYBOARD_INTERFACE + 1) | ||
| 47 | #define UDI_HID_KBD_IFACE_NUMBER KEYBOARD_INTERFACE | ||
| 48 | |||
| 49 | // It is important that the Raw HID interface is at a constant | ||
| 50 | // interface number, to support Linux/OSX platforms and chrome.hid | ||
| 51 | // If Raw HID is enabled, let it be always 1. | ||
| 52 | #ifdef RAW_ENABLE | ||
| 53 | # define RAW_INTERFACE NEXT_INTERFACE_1 | ||
| 54 | # define NEXT_INTERFACE_2 (RAW_INTERFACE + 1) | ||
| 55 | #else | ||
| 56 | # define NEXT_INTERFACE_2 NEXT_INTERFACE_1 | ||
| 57 | #endif | ||
| 58 | |||
| 59 | #ifdef MOUSE_ENABLE | ||
| 60 | # define MOUSE_INTERFACE NEXT_INTERFACE_2 | ||
| 61 | # define UDI_HID_MOU_IFACE_NUMBER MOUSE_INTERFACE | ||
| 62 | # define NEXT_INTERFACE_3 (MOUSE_INTERFACE + 1) | ||
| 63 | #else | ||
| 64 | # define NEXT_INTERFACE_3 NEXT_INTERFACE_2 | ||
| 65 | #endif | ||
| 66 | |||
| 67 | #ifdef EXTRAKEY_ENABLE | ||
| 68 | # define EXTRAKEY_INTERFACE NEXT_INTERFACE_3 | ||
| 69 | # define NEXT_INTERFACE_4 (EXTRAKEY_INTERFACE + 1) | ||
| 70 | # define UDI_HID_EXK_IFACE_NUMBER EXTRAKEY_INTERFACE | ||
| 71 | #else | ||
| 72 | # define NEXT_INTERFACE_4 NEXT_INTERFACE_3 | ||
| 73 | #endif | ||
| 74 | |||
| 75 | #ifdef CONSOLE_ENABLE | ||
| 76 | # define CON_INTERFACE NEXT_INTERFACE_4 | ||
| 77 | # define NEXT_INTERFACE_5 (CON_INTERFACE + 1) | ||
| 78 | # define UDI_HID_CON_IFACE_NUMBER CON_INTERFACE | ||
| 79 | #else | ||
| 80 | # define NEXT_INTERFACE_5 NEXT_INTERFACE_4 | ||
| 81 | #endif | ||
| 82 | |||
| 83 | #ifdef NKRO_ENABLE | ||
| 84 | # define NKRO_INTERFACE NEXT_INTERFACE_5 | ||
| 85 | # define NEXT_INTERFACE_6 (NKRO_INTERFACE + 1) | ||
| 86 | # define UDI_HID_NKRO_IFACE_NUMBER NKRO_INTERFACE | ||
| 87 | #else | ||
| 88 | # define NEXT_INTERFACE_6 NEXT_INTERFACE_5 | ||
| 89 | #endif | ||
| 90 | |||
| 91 | #ifdef MIDI_ENABLE | ||
| 92 | # define AC_INTERFACE NEXT_INTERFACE_6 | ||
| 93 | # define AS_INTERFACE (AC_INTERFACE + 1) | ||
| 94 | # define NEXT_INTERFACE_7 (AS_INTERFACE + 1) | ||
| 95 | #else | ||
| 96 | # define NEXT_INTERFACE_7 NEXT_INTERFACE_6 | ||
| 97 | #endif | ||
| 98 | |||
| 99 | #ifdef VIRTSER_ENABLE | ||
| 100 | # define CCI_INTERFACE NEXT_INTERFACE_7 | ||
| 101 | # define CDI_INTERFACE (CCI_INTERFACE + 1) | ||
| 102 | # define NEXT_INTERFACE_8 (CDI_INTERFACE + 1) | ||
| 103 | # define CDC_STATUS_INTERFACE CCI_INTERFACE | ||
| 104 | # define CDC_DATA_INTERFACE CDI_INTERFACE | ||
| 105 | #else | ||
| 106 | # define NEXT_INTERFACE_8 NEXT_INTERFACE_7 | ||
| 107 | #endif | ||
| 108 | |||
| 109 | /* nubmer of interfaces */ | ||
| 110 | #define TOTAL_INTERFACES NEXT_INTERFACE_8 | ||
| 111 | #define USB_DEVICE_NB_INTERFACE TOTAL_INTERFACES | ||
| 112 | |||
| 113 | // ********************************************************************** | ||
| 114 | // Endopoint number and size | ||
| 115 | // ********************************************************************** | ||
| 116 | #define USB_DEVICE_EP_CTRL_SIZE 8 | ||
| 117 | |||
| 118 | #define NEXT_IN_EPNUM_0 1 | ||
| 119 | #define NEXT_OUT_EPNUM_0 1 | ||
| 120 | |||
| 121 | #define KEYBOARD_IN_EPNUM NEXT_IN_EPNUM_0 | ||
| 122 | #define UDI_HID_KBD_EP_IN KEYBOARD_IN_EPNUM | ||
| 123 | #define NEXT_IN_EPNUM_1 (KEYBOARD_IN_EPNUM + 1) | ||
| 124 | #define UDI_HID_KBD_EP_SIZE KEYBOARD_EPSIZE | ||
| 125 | #define KBD_POLLING_INTERVAL USB_POLLING_INTERVAL_MS | ||
| 126 | #ifndef UDI_HID_KBD_STRING_ID | ||
| 127 | # define UDI_HID_KBD_STRING_ID 0 | ||
| 128 | #endif | ||
| 129 | |||
| 130 | #ifdef MOUSE_ENABLE | ||
| 131 | # define MOUSE_IN_EPNUM NEXT_IN_EPNUM_1 | ||
| 132 | # define NEXT_IN_EPNUM_2 (MOUSE_IN_EPNUM + 1) | ||
| 133 | # define UDI_HID_MOU_EP_IN MOUSE_IN_EPNUM | ||
| 134 | # define UDI_HID_MOU_EP_SIZE MOUSE_EPSIZE | ||
| 135 | # define MOU_POLLING_INTERVAL USB_POLLING_INTERVAL_MS | ||
| 136 | # ifndef UDI_HID_MOU_STRING_ID | ||
| 137 | # define UDI_HID_MOU_STRING_ID 0 | ||
| 138 | # endif | ||
| 139 | #else | ||
| 140 | # define NEXT_IN_EPNUM_2 NEXT_IN_EPNUM_1 | ||
| 141 | #endif | ||
| 142 | |||
| 143 | #ifdef EXTRAKEY_ENABLE | ||
| 144 | # define EXTRAKEY_IN_EPNUM NEXT_IN_EPNUM_2 | ||
| 145 | # define UDI_HID_EXK_EP_IN EXTRAKEY_IN_EPNUM | ||
| 146 | # define NEXT_IN_EPNUM_3 (EXTRAKEY_IN_EPNUM + 1) | ||
| 147 | # define UDI_HID_EXK_EP_SIZE EXTRAKEY_EPSIZE | ||
| 148 | # define EXTRAKEY_POLLING_INTERVAL USB_POLLING_INTERVAL_MS | ||
| 149 | # ifndef UDI_HID_EXK_STRING_ID | ||
| 150 | # define UDI_HID_EXK_STRING_ID 0 | ||
| 151 | # endif | ||
| 152 | #else | ||
| 153 | # define NEXT_IN_EPNUM_3 NEXT_IN_EPNUM_2 | ||
| 154 | #endif | ||
| 155 | |||
| 156 | #ifdef RAW_ENABLE | ||
| 157 | # define RAW_IN_EPNUM NEXT_IN_EPNUM_3 | ||
| 158 | # define UDI_HID_RAW_EP_IN RAW_IN_EPNUM | ||
| 159 | # define NEXT_IN_EPNUM_4 (RAW_IN_EPNUM + 1) | ||
| 160 | # define RAW_OUT_EPNUM NEXT_OUT_EPNUM_0 | ||
| 161 | # define UDI_HID_RAW_EP_OUT RAW_OUT_EPNUM | ||
| 162 | # define NEXT_OUT_EPNUM_1 (RAW_OUT_EPNUM + 1) | ||
| 163 | # define RAW_POLLING_INTERVAL 1 | ||
| 164 | # ifndef UDI_HID_RAW_STRING_ID | ||
| 165 | # define UDI_HID_RAW_STRING_ID 0 | ||
| 166 | # endif | ||
| 167 | #else | ||
| 168 | # define NEXT_IN_EPNUM_4 NEXT_IN_EPNUM_3 | ||
| 169 | # define NEXT_OUT_EPNUM_1 NEXT_OUT_EPNUM_0 | ||
| 170 | #endif | ||
| 171 | |||
| 172 | #ifdef CONSOLE_ENABLE | ||
| 173 | # define CON_IN_EPNUM NEXT_IN_EPNUM_4 | ||
| 174 | # define UDI_HID_CON_EP_IN CON_IN_EPNUM | ||
| 175 | # define NEXT_IN_EPNUM_5 (CON_IN_EPNUM + 1) | ||
| 176 | # define CON_OUT_EPNUM NEXT_OUT_EPNUM_1 | ||
| 177 | # define UDI_HID_CON_EP_OUT CON_OUT_EPNUM | ||
| 178 | # define NEXT_OUT_EPNUM_2 (CON_OUT_EPNUM + 1) | ||
| 179 | # define CON_POLLING_INTERVAL 1 | ||
| 180 | # ifndef UDI_HID_CON_STRING_ID | ||
| 181 | # define UDI_HID_CON_STRING_ID 0 | ||
| 182 | # endif | ||
| 183 | #else | ||
| 184 | # define NEXT_IN_EPNUM_5 NEXT_IN_EPNUM_4 | ||
| 185 | # define NEXT_OUT_EPNUM_2 NEXT_OUT_EPNUM_1 | ||
| 186 | #endif | ||
| 187 | |||
| 188 | #ifdef NKRO_ENABLE | ||
| 189 | # define NKRO_IN_EPNUM NEXT_IN_EPNUM_5 | ||
| 190 | # define UDI_HID_NKRO_EP_IN NKRO_IN_EPNUM | ||
| 191 | # define NEXT_IN_EPNUM_6 (NKRO_IN_EPNUM + 1) | ||
| 192 | # define UDI_HID_NKRO_EP_SIZE NKRO_EPSIZE | ||
| 193 | # define NKRO_POLLING_INTERVAL 1 | ||
| 194 | # ifndef UDI_HID_NKRO_STRING_ID | ||
| 195 | # define UDI_HID_NKRO_STRING_ID 0 | ||
| 196 | # endif | ||
| 197 | #else | ||
| 198 | # define NEXT_IN_EPNUM_6 NEXT_IN_EPNUM_5 | ||
| 199 | #endif | ||
| 200 | |||
| 201 | #ifdef MIDI_ENABLE | ||
| 202 | # define MIDI_STREAM_IN_EPNUM NEXT_IN_EPNUM_6 | ||
| 203 | # define NEXT_IN_EPNUM_7 (MIDI_STREAM_IN_EPNUM + 1) | ||
| 204 | # define MIDI_STREAM_OUT_EPNUM NEXT_OUT_EPNUM_2 | ||
| 205 | # define NEXT_OUT_EPNUM_3 (MIDI_STREAM_OUT_EPNUM + 1) | ||
| 206 | # define MIDI_POLLING_INTERVAL 5 | ||
| 207 | #else | ||
| 208 | # define NEXT_IN_EPNUM_7 NEXT_IN_EPNUM_6 | ||
| 209 | # define NEXT_OUT_EPNUM_3 NEXT_OUT_EPNUM_2 | ||
| 210 | #endif | ||
| 211 | |||
| 212 | #ifdef VIRTSER_ENABLE | ||
| 213 | # define CDC_NOTIFICATION_EPNUM NEXT_IN_EPNUM_7 | ||
| 214 | # define CDC_ACM_ENDPOINT CDC_NOTIFICATION_EPNUM | ||
| 215 | # define CDC_TX_ENDPOINT (CDC_NOTIFICATION_EPNUM + 1) | ||
| 216 | # define NEXT_IN_EPNUM_8 (CDC_TX_ENDPOINT + 1) | ||
| 217 | |||
| 218 | # define CDC_OUT_EPNUM NEXT_OUT_EPNUM_3 | ||
| 219 | # define CDC_RX_ENDPOINT CDC_OUT_EPNUM | ||
| 220 | # define NEXT_OUT_EPNUM_4 (CDC_OUT_EPNUM + 1) | ||
| 221 | |||
| 222 | # define CDC_ACM_SIZE CDC_NOTIFICATION_EPSIZE | ||
| 223 | # define CDC_RX_SIZE CDC_EPSIZE // KFSMOD was 64 | ||
| 224 | # define CDC_TX_SIZE CDC_RX_SIZE | ||
| 225 | # define CDC_ACM_POLLING_INTERVAL 255 | ||
| 226 | # define CDC_EP_INTERVAL_STATUS CDC_ACM_POLLING_INTERVAL | ||
| 227 | # define CDC_DATA_POLLING_INTERVAL 5 | ||
| 228 | # define CDC_EP_INTERVAL_DATA CDC_DATA_POLLING_INTERVAL | ||
| 229 | # define CDC_STATUS_NAME L"Virtual Serial Port - Status" | ||
| 230 | # define CDC_DATA_NAME L"Virtual Serial Port - Data" | ||
| 231 | #else | ||
| 232 | # define NEXT_IN_EPNUM_8 NEXT_IN_EPNUM_7 | ||
| 233 | # define NEXT_OUT_EPNUM_4 NEXT_OUT_EPNUM_3 | ||
| 234 | #endif | ||
| 235 | |||
| 236 | #define TOTAL_OUT_EP NEXT_OUT_EPNUM_4 | ||
| 237 | #define TOTAL_IN_EP NEXT_IN_EPNUM_8 | ||
| 238 | #define USB_DEVICE_MAX_EP (max(NEXT_OUT_EPNUM_4, NEXT_IN_EPNUM_8)) | ||
| 239 | |||
| 240 | #if USB_DEVICE_MAX_EP > 8 | ||
| 241 | # error "There are not enough available endpoints to support all functions. Remove some in the rules.mk file.(MOUSEKEY, EXTRAKEY, CONSOLE, NKRO, MIDI, VIRTSER)" | ||
| 242 | #endif | ||
| 243 | |||
| 244 | // ********************************************************************** | ||
| 245 | // KBD Descriptor structure and content | ||
| 246 | // ********************************************************************** | ||
| 247 | COMPILER_PACK_SET(1) | ||
| 248 | |||
| 249 | typedef struct { | ||
| 250 | usb_iface_desc_t iface; | ||
| 251 | usb_hid_descriptor_t hid; | ||
| 252 | usb_ep_desc_t ep; | ||
| 253 | } udi_hid_kbd_desc_t; | ||
| 254 | |||
| 255 | typedef struct { | ||
| 256 | uint8_t array[59]; | ||
| 257 | } udi_hid_kbd_report_desc_t; | ||
| 258 | |||
| 259 | // clang-format off | ||
| 260 | |||
| 261 | # define UDI_HID_KBD_DESC { \ | ||
| 262 | .iface = { \ | ||
| 263 | .bLength = sizeof(usb_iface_desc_t), \ | ||
| 264 | .bDescriptorType = USB_DT_INTERFACE, \ | ||
| 265 | .bInterfaceNumber = UDI_HID_KBD_IFACE_NUMBER, \ | ||
| 266 | .bAlternateSetting = 0, \ | ||
| 267 | .bNumEndpoints = 1, \ | ||
| 268 | .bInterfaceClass = HID_CLASS, \ | ||
| 269 | .bInterfaceSubClass = HID_SUB_CLASS_BOOT, \ | ||
| 270 | .bInterfaceProtocol = HID_PROTOCOL_KEYBOARD, \ | ||
| 271 | .iInterface = UDI_HID_KBD_STRING_ID, \ | ||
| 272 | }, \ | ||
| 273 | .hid = { \ | ||
| 274 | .bLength = sizeof(usb_hid_descriptor_t), \ | ||
| 275 | .bDescriptorType = USB_DT_HID, \ | ||
| 276 | .bcdHID = LE16(USB_HID_BDC_V1_11), \ | ||
| 277 | .bCountryCode = USB_HID_NO_COUNTRY_CODE, \ | ||
| 278 | .bNumDescriptors = USB_HID_NUM_DESC, \ | ||
| 279 | .bRDescriptorType = USB_DT_HID_REPORT, \ | ||
| 280 | .wDescriptorLength = LE16(sizeof(udi_hid_kbd_report_desc_t)), \ | ||
| 281 | }, \ | ||
| 282 | .ep = { \ | ||
| 283 | .bLength = sizeof(usb_ep_desc_t), \ | ||
| 284 | .bDescriptorType = USB_DT_ENDPOINT, \ | ||
| 285 | .bEndpointAddress = UDI_HID_KBD_EP_IN | USB_EP_DIR_IN, \ | ||
| 286 | .bmAttributes = USB_EP_TYPE_INTERRUPT, \ | ||
| 287 | .wMaxPacketSize = LE16(UDI_HID_KBD_EP_SIZE), \ | ||
| 288 | .bInterval = KBD_POLLING_INTERVAL \ | ||
| 289 | } \ | ||
| 290 | } | ||
| 291 | |||
| 292 | // clang-format on | ||
| 293 | |||
| 294 | // set report buffer (from host) | ||
| 295 | extern uint8_t udi_hid_kbd_report_set; | ||
| 296 | |||
| 297 | // report buffer (to host) | ||
| 298 | #define UDI_HID_KBD_REPORT_SIZE 8 | ||
| 299 | extern uint8_t udi_hid_kbd_report[UDI_HID_KBD_REPORT_SIZE]; | ||
| 300 | |||
| 301 | COMPILER_PACK_RESET() | ||
| 302 | |||
| 303 | // ********************************************************************** | ||
| 304 | // EXK Descriptor structure and content | ||
| 305 | // ********************************************************************** | ||
| 306 | #ifdef EXTRAKEY_ENABLE | ||
| 307 | |||
| 308 | COMPILER_PACK_SET(1) | ||
| 309 | |||
| 310 | typedef struct { | ||
| 311 | usb_iface_desc_t iface; | ||
| 312 | usb_hid_descriptor_t hid; | ||
| 313 | usb_ep_desc_t ep; | ||
| 314 | } udi_hid_exk_desc_t; | ||
| 315 | |||
| 316 | typedef struct { | ||
| 317 | uint8_t array[50]; | ||
| 318 | } udi_hid_exk_report_desc_t; | ||
| 319 | |||
| 320 | // clang-format off | ||
| 321 | |||
| 322 | # define UDI_HID_EXK_DESC { \ | ||
| 323 | .iface = { \ | ||
| 324 | .bLength = sizeof(usb_iface_desc_t), \ | ||
| 325 | .bDescriptorType = USB_DT_INTERFACE, \ | ||
| 326 | .bInterfaceNumber = UDI_HID_EXK_IFACE_NUMBER, \ | ||
| 327 | .bAlternateSetting = 0, \ | ||
| 328 | .bNumEndpoints = 1, \ | ||
| 329 | .bInterfaceClass = HID_CLASS, \ | ||
| 330 | .bInterfaceSubClass = HID_SUB_CLASS_BOOT, \ | ||
| 331 | .bInterfaceProtocol = HID_PROTOCOL_GENERIC, \ | ||
| 332 | .iInterface = UDI_HID_EXK_STRING_ID \ | ||
| 333 | }, \ | ||
| 334 | .hid = { \ | ||
| 335 | .bLength = sizeof(usb_hid_descriptor_t), \ | ||
| 336 | .bDescriptorType = USB_DT_HID, \ | ||
| 337 | .bcdHID = LE16(USB_HID_BDC_V1_11), \ | ||
| 338 | .bCountryCode = USB_HID_NO_COUNTRY_CODE, \ | ||
| 339 | .bNumDescriptors = USB_HID_NUM_DESC, \ | ||
| 340 | .bRDescriptorType = USB_DT_HID_REPORT, \ | ||
| 341 | .wDescriptorLength = LE16(sizeof(udi_hid_exk_report_desc_t)) \ | ||
| 342 | }, \ | ||
| 343 | .ep = { \ | ||
| 344 | .bLength = sizeof(usb_ep_desc_t), \ | ||
| 345 | .bDescriptorType = USB_DT_ENDPOINT, \ | ||
| 346 | .bEndpointAddress = UDI_HID_EXK_EP_IN | USB_EP_DIR_IN, \ | ||
| 347 | .bmAttributes = USB_EP_TYPE_INTERRUPT, \ | ||
| 348 | .wMaxPacketSize = LE16(UDI_HID_EXK_EP_SIZE), \ | ||
| 349 | .bInterval = EXTRAKEY_POLLING_INTERVAL \ | ||
| 350 | } \ | ||
| 351 | } | ||
| 352 | |||
| 353 | // clang-format on | ||
| 354 | |||
| 355 | // report buffer | ||
| 356 | # define UDI_HID_EXK_REPORT_SIZE 3 | ||
| 357 | extern uint8_t udi_hid_exk_report[UDI_HID_EXK_REPORT_SIZE]; | ||
| 358 | |||
| 359 | COMPILER_PACK_RESET() | ||
| 360 | |||
| 361 | #endif // EXTRAKEY_ENABLE | ||
| 362 | |||
| 363 | // ********************************************************************** | ||
| 364 | // NKRO Descriptor structure and content | ||
| 365 | // ********************************************************************** | ||
| 366 | #ifdef NKRO_ENABLE | ||
| 367 | |||
| 368 | COMPILER_PACK_SET(1) | ||
| 369 | |||
| 370 | typedef struct { | ||
| 371 | usb_iface_desc_t iface; | ||
| 372 | usb_hid_descriptor_t hid; | ||
| 373 | usb_ep_desc_t ep; | ||
| 374 | } udi_hid_nkro_desc_t; | ||
| 375 | |||
| 376 | typedef struct { | ||
| 377 | uint8_t array[57]; | ||
| 378 | } udi_hid_nkro_report_desc_t; | ||
| 379 | |||
| 380 | // clang-format off | ||
| 381 | |||
| 382 | # define UDI_HID_NKRO_DESC { \ | ||
| 383 | .iface = { \ | ||
| 384 | .bLength = sizeof(usb_iface_desc_t), \ | ||
| 385 | .bDescriptorType = USB_DT_INTERFACE, \ | ||
| 386 | .bInterfaceNumber = UDI_HID_NKRO_IFACE_NUMBER, \ | ||
| 387 | .bAlternateSetting = 0, \ | ||
| 388 | .bNumEndpoints = 1, \ | ||
| 389 | .bInterfaceClass = HID_CLASS, \ | ||
| 390 | .bInterfaceSubClass = HID_SUB_CLASS_NOBOOT, \ | ||
| 391 | .bInterfaceProtocol = HID_PROTOCOL_KEYBOARD, \ | ||
| 392 | .iInterface = UDI_HID_NKRO_STRING_ID \ | ||
| 393 | }, \ | ||
| 394 | .hid = { \ | ||
| 395 | .bLength = sizeof(usb_hid_descriptor_t), \ | ||
| 396 | .bDescriptorType = USB_DT_HID, \ | ||
| 397 | .bcdHID = LE16(USB_HID_BDC_V1_11), \ | ||
| 398 | .bCountryCode = USB_HID_NO_COUNTRY_CODE, \ | ||
| 399 | .bNumDescriptors = USB_HID_NUM_DESC, \ | ||
| 400 | .bRDescriptorType = USB_DT_HID_REPORT, \ | ||
| 401 | .wDescriptorLength = LE16(sizeof(udi_hid_nkro_report_desc_t)) \ | ||
| 402 | }, \ | ||
| 403 | .ep = { \ | ||
| 404 | .bLength = sizeof(usb_ep_desc_t), \ | ||
| 405 | .bDescriptorType = USB_DT_ENDPOINT, \ | ||
| 406 | .bEndpointAddress = UDI_HID_NKRO_EP_IN | USB_EP_DIR_IN, \ | ||
| 407 | .bmAttributes = USB_EP_TYPE_INTERRUPT, \ | ||
| 408 | .wMaxPacketSize = LE16(UDI_HID_NKRO_EP_SIZE), \ | ||
| 409 | .bInterval = NKRO_POLLING_INTERVAL \ | ||
| 410 | } \ | ||
| 411 | } | ||
| 412 | |||
| 413 | // clang-format on | ||
| 414 | |||
| 415 | // set report buffer | ||
| 416 | extern uint8_t udi_hid_nkro_report_set; | ||
| 417 | |||
| 418 | // report buffer | ||
| 419 | # define UDI_HID_NKRO_REPORT_SIZE 32 | ||
| 420 | extern uint8_t udi_hid_nkro_report[UDI_HID_NKRO_REPORT_SIZE]; | ||
| 421 | |||
| 422 | COMPILER_PACK_RESET() | ||
| 423 | |||
| 424 | #endif // NKRO_ENABLE | ||
| 425 | |||
| 426 | // ********************************************************************** | ||
| 427 | // MOU Descriptor structure and content | ||
| 428 | // ********************************************************************** | ||
| 429 | #ifdef MOUSE_ENABLE | ||
| 430 | |||
| 431 | COMPILER_PACK_SET(1) | ||
| 432 | |||
| 433 | typedef struct { | ||
| 434 | usb_iface_desc_t iface; | ||
| 435 | usb_hid_descriptor_t hid; | ||
| 436 | usb_ep_desc_t ep; | ||
| 437 | } udi_hid_mou_desc_t; | ||
| 438 | |||
| 439 | typedef struct { | ||
| 440 | uint8_t array[77]; // MOU PDS | ||
| 441 | } udi_hid_mou_report_desc_t; | ||
| 442 | |||
| 443 | // clang-format off | ||
| 444 | |||
| 445 | # define UDI_HID_MOU_DESC { \ | ||
| 446 | .iface = { \ | ||
| 447 | .bLength = sizeof(usb_iface_desc_t), \ | ||
| 448 | .bDescriptorType = USB_DT_INTERFACE, \ | ||
| 449 | .bInterfaceNumber = MOUSE_INTERFACE, \ | ||
| 450 | .bAlternateSetting = 0, \ | ||
| 451 | .bNumEndpoints = 1, \ | ||
| 452 | .bInterfaceClass = HID_CLASS, \ | ||
| 453 | .bInterfaceSubClass = HID_SUB_CLASS_BOOT, \ | ||
| 454 | .bInterfaceProtocol = HID_PROTOCOL_MOUSE, \ | ||
| 455 | .iInterface = UDI_HID_MOU_STRING_ID \ | ||
| 456 | }, \ | ||
| 457 | .hid = { \ | ||
| 458 | .bLength = sizeof(usb_hid_descriptor_t), \ | ||
| 459 | .bDescriptorType = USB_DT_HID, \ | ||
| 460 | .bcdHID = LE16(USB_HID_BDC_V1_11), \ | ||
| 461 | .bCountryCode = USB_HID_NO_COUNTRY_CODE, \ | ||
| 462 | .bNumDescriptors = USB_HID_NUM_DESC, \ | ||
| 463 | .bRDescriptorType = USB_DT_HID_REPORT, \ | ||
| 464 | .wDescriptorLength = LE16(sizeof(udi_hid_mou_report_desc_t)) \ | ||
| 465 | }, \ | ||
| 466 | .ep = { \ | ||
| 467 | .bLength = sizeof(usb_ep_desc_t), \ | ||
| 468 | .bDescriptorType = USB_DT_ENDPOINT, \ | ||
| 469 | .bEndpointAddress = UDI_HID_MOU_EP_IN | USB_EP_DIR_IN, \ | ||
| 470 | .bmAttributes = USB_EP_TYPE_INTERRUPT, \ | ||
| 471 | .wMaxPacketSize = LE16(UDI_HID_MOU_EP_SIZE), \ | ||
| 472 | .bInterval = MOU_POLLING_INTERVAL \ | ||
| 473 | } \ | ||
| 474 | } | ||
| 475 | |||
| 476 | // clang-format on | ||
| 477 | |||
| 478 | // report buffer | ||
| 479 | # define UDI_HID_MOU_REPORT_SIZE 5 // MOU PDS | ||
| 480 | extern uint8_t udi_hid_mou_report[UDI_HID_MOU_REPORT_SIZE]; | ||
| 481 | |||
| 482 | COMPILER_PACK_RESET() | ||
| 483 | |||
| 484 | #endif // MOUSE_ENABLE | ||
| 485 | |||
| 486 | // ********************************************************************** | ||
| 487 | // RAW Descriptor structure and content | ||
| 488 | // ********************************************************************** | ||
| 489 | #ifdef RAW_ENABLE | ||
| 490 | |||
| 491 | COMPILER_PACK_SET(1) | ||
| 492 | |||
| 493 | typedef struct { | ||
| 494 | usb_iface_desc_t iface; | ||
| 495 | usb_hid_descriptor_t hid; | ||
| 496 | usb_ep_desc_t ep_out; | ||
| 497 | usb_ep_desc_t ep_in; | ||
| 498 | } udi_hid_raw_desc_t; | ||
| 499 | |||
| 500 | typedef struct { | ||
| 501 | uint8_t array[26]; | ||
| 502 | } udi_hid_raw_report_desc_t; | ||
| 503 | |||
| 504 | // clang-format off | ||
| 505 | |||
| 506 | # define UDI_HID_RAW_DESC { \ | ||
| 507 | .iface = { \ | ||
| 508 | .bLength = sizeof(usb_iface_desc_t), \ | ||
| 509 | .bDescriptorType = USB_DT_INTERFACE, \ | ||
| 510 | .bInterfaceNumber = RAW_INTERFACE, \ | ||
| 511 | .bAlternateSetting = 0, \ | ||
| 512 | .bNumEndpoints = 2, \ | ||
| 513 | .bInterfaceClass = HID_CLASS, \ | ||
| 514 | .bInterfaceSubClass = HID_SUB_CLASS_NOBOOT, \ | ||
| 515 | .bInterfaceProtocol = HID_SUB_CLASS_NOBOOT, \ | ||
| 516 | .iInterface = UDI_HID_RAW_STRING_ID \ | ||
| 517 | }, \ | ||
| 518 | .hid = { \ | ||
| 519 | .bLength = sizeof(usb_hid_descriptor_t), \ | ||
| 520 | .bDescriptorType = USB_DT_HID, \ | ||
| 521 | .bcdHID = LE16(USB_HID_BDC_V1_11), \ | ||
| 522 | .bCountryCode = USB_HID_NO_COUNTRY_CODE, \ | ||
| 523 | .bNumDescriptors = USB_HID_NUM_DESC, \ | ||
| 524 | .bRDescriptorType = USB_DT_HID_REPORT, \ | ||
| 525 | .wDescriptorLength = LE16(sizeof(udi_hid_raw_report_desc_t)) \ | ||
| 526 | }, \ | ||
| 527 | .ep_out = { \ | ||
| 528 | .bLength = sizeof(usb_ep_desc_t), \ | ||
| 529 | .bDescriptorType = USB_DT_ENDPOINT, \ | ||
| 530 | .bEndpointAddress = UDI_HID_RAW_EP_OUT | USB_EP_DIR_OUT, \ | ||
| 531 | .bmAttributes = USB_EP_TYPE_INTERRUPT, \ | ||
| 532 | .wMaxPacketSize = LE16(RAW_EPSIZE), \ | ||
| 533 | .bInterval = RAW_POLLING_INTERVAL \ | ||
| 534 | }, \ | ||
| 535 | .ep_in = { \ | ||
| 536 | .bLength = sizeof(usb_ep_desc_t), \ | ||
| 537 | .bDescriptorType = USB_DT_ENDPOINT, \ | ||
| 538 | .bEndpointAddress = UDI_HID_RAW_EP_IN | USB_EP_DIR_IN, \ | ||
| 539 | .bmAttributes = USB_EP_TYPE_INTERRUPT, \ | ||
| 540 | .wMaxPacketSize = LE16(RAW_EPSIZE), \ | ||
| 541 | .bInterval = RAW_POLLING_INTERVAL \ | ||
| 542 | } \ | ||
| 543 | } | ||
| 544 | |||
| 545 | // clang-format on | ||
| 546 | |||
| 547 | # define UDI_HID_RAW_REPORT_SIZE RAW_EPSIZE | ||
| 548 | |||
| 549 | extern uint8_t udi_hid_raw_report_set[UDI_HID_RAW_REPORT_SIZE]; | ||
| 550 | |||
| 551 | // report buffer | ||
| 552 | extern uint8_t udi_hid_raw_report[UDI_HID_RAW_REPORT_SIZE]; | ||
| 553 | |||
| 554 | COMPILER_PACK_RESET() | ||
| 555 | |||
| 556 | #endif // RAW_ENABLE | ||
| 557 | |||
| 558 | // ********************************************************************** | ||
| 559 | // CON Descriptor structure and content | ||
| 560 | // ********************************************************************** | ||
| 561 | #ifdef CONSOLE_ENABLE | ||
| 562 | |||
| 563 | COMPILER_PACK_SET(1) | ||
| 564 | |||
| 565 | typedef struct { | ||
| 566 | usb_iface_desc_t iface; | ||
| 567 | usb_hid_descriptor_t hid; | ||
| 568 | usb_ep_desc_t ep_out; | ||
| 569 | usb_ep_desc_t ep_in; | ||
| 570 | } udi_hid_con_desc_t; | ||
| 571 | |||
| 572 | typedef struct { | ||
| 573 | uint8_t array[34]; | ||
| 574 | } udi_hid_con_report_desc_t; | ||
| 575 | |||
| 576 | // clang-format off | ||
| 577 | |||
| 578 | # define UDI_HID_CON_DESC { \ | ||
| 579 | .iface = { \ | ||
| 580 | .bLength = sizeof(usb_iface_desc_t), \ | ||
| 581 | .bDescriptorType = USB_DT_INTERFACE, \ | ||
| 582 | .bInterfaceNumber = UDI_HID_CON_IFACE_NUMBER, \ | ||
| 583 | .bAlternateSetting = 0, \ | ||
| 584 | .bNumEndpoints = 2, \ | ||
| 585 | .bInterfaceClass = HID_CLASS, \ | ||
| 586 | .bInterfaceSubClass = HID_SUB_CLASS_NOBOOT, \ | ||
| 587 | .bInterfaceProtocol = HID_SUB_CLASS_NOBOOT, \ | ||
| 588 | .iInterface = UDI_HID_CON_STRING_ID \ | ||
| 589 | }, \ | ||
| 590 | .hid = { \ | ||
| 591 | .bLength = sizeof(usb_hid_descriptor_t), \ | ||
| 592 | .bDescriptorType = USB_DT_HID, \ | ||
| 593 | .bcdHID = LE16(USB_HID_BDC_V1_11), \ | ||
| 594 | .bCountryCode = USB_HID_NO_COUNTRY_CODE, \ | ||
| 595 | .bNumDescriptors = USB_HID_NUM_DESC, \ | ||
| 596 | .bRDescriptorType = USB_DT_HID_REPORT, \ | ||
| 597 | .wDescriptorLength = LE16(sizeof(udi_hid_con_report_desc_t)) \ | ||
| 598 | }, \ | ||
| 599 | .ep_out = { \ | ||
| 600 | .bLength = sizeof(usb_ep_desc_t), \ | ||
| 601 | .bDescriptorType = USB_DT_ENDPOINT, \ | ||
| 602 | .bEndpointAddress = UDI_HID_CON_EP_OUT | USB_EP_DIR_OUT, \ | ||
| 603 | .bmAttributes = USB_EP_TYPE_INTERRUPT, \ | ||
| 604 | .wMaxPacketSize = LE16(CONSOLE_EPSIZE), \ | ||
| 605 | .bInterval = CON_POLLING_INTERVAL \ | ||
| 606 | }, \ | ||
| 607 | .ep_in = { \ | ||
| 608 | .bLength = sizeof(usb_ep_desc_t), \ | ||
| 609 | .bDescriptorType = USB_DT_ENDPOINT, \ | ||
| 610 | .bEndpointAddress = UDI_HID_CON_EP_IN | USB_EP_DIR_IN, \ | ||
| 611 | .bmAttributes = USB_EP_TYPE_INTERRUPT, \ | ||
| 612 | .wMaxPacketSize = LE16(CONSOLE_EPSIZE), \ | ||
| 613 | .bInterval = CON_POLLING_INTERVAL \ | ||
| 614 | } \ | ||
| 615 | } | ||
| 616 | |||
| 617 | // clang-format on | ||
| 618 | |||
| 619 | # define UDI_HID_CON_REPORT_SIZE CONSOLE_EPSIZE | ||
| 620 | |||
| 621 | extern uint8_t udi_hid_con_report_set[UDI_HID_CON_REPORT_SIZE]; | ||
| 622 | |||
| 623 | // report buffer | ||
| 624 | extern uint8_t udi_hid_con_report[UDI_HID_CON_REPORT_SIZE]; | ||
| 625 | |||
| 626 | COMPILER_PACK_RESET() | ||
| 627 | |||
| 628 | #endif // CONSOLE_ENABLE | ||
| 629 | |||
| 630 | // ********************************************************************** | ||
| 631 | // CDC Descriptor structure and content | ||
| 632 | // ********************************************************************** | ||
| 633 | #ifdef VIRTSER_ENABLE | ||
| 634 | |||
| 635 | COMPILER_PACK_SET(1) | ||
| 636 | |||
| 637 | typedef struct { | ||
| 638 | uint8_t bFunctionLength; | ||
| 639 | uint8_t bDescriptorType; | ||
| 640 | uint8_t bDescriptorSubtype; | ||
| 641 | le16_t bcdCDC; | ||
| 642 | } usb_cdc_hdr_desc_t; | ||
| 643 | |||
| 644 | typedef struct { | ||
| 645 | uint8_t bFunctionLength; | ||
| 646 | uint8_t bDescriptorType; | ||
| 647 | uint8_t bDescriptorSubtype; | ||
| 648 | uint8_t bmCapabilities; | ||
| 649 | uint8_t bDataInterface; | ||
| 650 | } usb_cdc_call_mgmt_desc_t; | ||
| 651 | |||
| 652 | typedef struct { | ||
| 653 | uint8_t bFunctionLength; | ||
| 654 | uint8_t bDescriptorType; | ||
| 655 | uint8_t bDescriptorSubtype; | ||
| 656 | uint8_t bmCapabilities; | ||
| 657 | } usb_cdc_acm_desc_t; | ||
| 658 | |||
| 659 | typedef struct { | ||
| 660 | uint8_t bFunctionLength; | ||
| 661 | uint8_t bDescriptorType; | ||
| 662 | uint8_t bDescriptorSubtype; | ||
| 663 | uint8_t bMasterInterface; | ||
| 664 | uint8_t bSlaveInterface0; | ||
| 665 | } usb_cdc_union_desc_t; | ||
| 666 | |||
| 667 | typedef struct { | ||
| 668 | usb_association_desc_t iaface; | ||
| 669 | usb_iface_desc_t iface_c; | ||
| 670 | usb_cdc_hdr_desc_t fd; | ||
| 671 | usb_cdc_call_mgmt_desc_t mfd; | ||
| 672 | usb_cdc_acm_desc_t acmd; | ||
| 673 | usb_cdc_union_desc_t ufd; | ||
| 674 | usb_ep_desc_t ep_c; | ||
| 675 | usb_iface_desc_t iface_d; | ||
| 676 | usb_ep_desc_t ep_tx; | ||
| 677 | usb_ep_desc_t ep_rx; | ||
| 678 | } udi_cdc_desc_t; | ||
| 679 | |||
| 680 | // clang-format off | ||
| 681 | |||
| 682 | # define CDC_DESCRIPTOR { \ | ||
| 683 | .iaface = { \ | ||
| 684 | .bLength = sizeof(usb_association_desc_t), \ | ||
| 685 | .bDescriptorType = USB_DT_IAD, \ | ||
| 686 | .bFirstInterface = CDC_STATUS_INTERFACE, \ | ||
| 687 | .bInterfaceCount = 2, \ | ||
| 688 | .bFunctionClass = CDC_CLASS_DEVICE, \ | ||
| 689 | .bFunctionSubClass = CDC_SUBCLASS_ACM, \ | ||
| 690 | .bFunctionProtocol = CDC_PROTOCOL_V25TER, \ | ||
| 691 | .iFunction = 0 \ | ||
| 692 | }, \ | ||
| 693 | .iface_c = { \ | ||
| 694 | .bLength = sizeof(usb_iface_desc_t), \ | ||
| 695 | .bDescriptorType = USB_DT_INTERFACE, \ | ||
| 696 | .bInterfaceNumber = CDC_STATUS_INTERFACE, \ | ||
| 697 | .bAlternateSetting = 0, \ | ||
| 698 | .bNumEndpoints = 1, \ | ||
| 699 | .bInterfaceClass = 0x02, \ | ||
| 700 | .bInterfaceSubClass = 0x02, \ | ||
| 701 | .bInterfaceProtocol = CDC_PROTOCOL_V25TER, \ | ||
| 702 | .iInterface = 0 \ | ||
| 703 | }, \ | ||
| 704 | .fd = { \ | ||
| 705 | .bFunctionLength = sizeof(usb_cdc_hdr_desc_t), \ | ||
| 706 | .bDescriptorType = CDC_CS_INTERFACE, \ | ||
| 707 | .bDescriptorSubtype = CDC_SCS_HEADER, \ | ||
| 708 | .bcdCDC = 0x0110 \ | ||
| 709 | }, \ | ||
| 710 | .mfd = { \ | ||
| 711 | .bFunctionLength = sizeof(usb_cdc_call_mgmt_desc_t), \ | ||
| 712 | .bDescriptorType = CDC_CS_INTERFACE, \ | ||
| 713 | .bDescriptorSubtype = CDC_SCS_CALL_MGMT, \ | ||
| 714 | .bmCapabilities = CDC_CALL_MGMT_SUPPORTED, \ | ||
| 715 | .bDataInterface = CDC_DATA_INTERFACE \ | ||
| 716 | }, \ | ||
| 717 | .acmd = { \ | ||
| 718 | .bFunctionLength = sizeof(usb_cdc_acm_desc_t), \ | ||
| 719 | .bDescriptorType = CDC_CS_INTERFACE, \ | ||
| 720 | .bDescriptorSubtype = CDC_SCS_ACM, \ | ||
| 721 | .bmCapabilities = CDC_ACM_SUPPORT_LINE_REQUESTS \ | ||
| 722 | }, \ | ||
| 723 | .ufd = { \ | ||
| 724 | .bFunctionLength = sizeof(usb_cdc_union_desc_t), \ | ||
| 725 | .bDescriptorType = CDC_CS_INTERFACE, \ | ||
| 726 | .bDescriptorSubtype = CDC_SCS_UNION, \ | ||
| 727 | .bMasterInterface = CDC_STATUS_INTERFACE, \ | ||
| 728 | .bSlaveInterface0 = CDC_DATA_INTERFACE \ | ||
| 729 | }, \ | ||
| 730 | .ep_c = { \ | ||
| 731 | .bLength = sizeof(usb_ep_desc_t), \ | ||
| 732 | .bDescriptorType = USB_DT_ENDPOINT, \ | ||
| 733 | .bEndpointAddress = CDC_ACM_ENDPOINT | USB_EP_DIR_IN, \ | ||
| 734 | .bmAttributes = USB_EP_TYPE_INTERRUPT, \ | ||
| 735 | .wMaxPacketSize = LE16(CDC_ACM_SIZE), \ | ||
| 736 | .bInterval = CDC_EP_INTERVAL_STATUS \ | ||
| 737 | }, \ | ||
| 738 | .iface_d = { \ | ||
| 739 | .bLength = sizeof(usb_iface_desc_t), \ | ||
| 740 | .bDescriptorType = USB_DT_INTERFACE, \ | ||
| 741 | .bInterfaceNumber = CDC_DATA_INTERFACE, \ | ||
| 742 | .bAlternateSetting = 0, \ | ||
| 743 | .bNumEndpoints = 2, \ | ||
| 744 | .bInterfaceClass = CDC_CLASS_DATA, \ | ||
| 745 | .bInterfaceSubClass = 0, \ | ||
| 746 | .bInterfaceProtocol = 0, \ | ||
| 747 | .iInterface = 0 \ | ||
| 748 | }, \ | ||
| 749 | .ep_rx = { \ | ||
| 750 | .bLength = sizeof(usb_ep_desc_t), \ | ||
| 751 | .bDescriptorType = USB_DT_ENDPOINT, \ | ||
| 752 | .bEndpointAddress = CDC_RX_ENDPOINT | USB_EP_DIR_OUT, \ | ||
| 753 | .bmAttributes = USB_EP_TYPE_BULK, \ | ||
| 754 | .wMaxPacketSize = LE16(CDC_RX_SIZE), \ | ||
| 755 | .bInterval = CDC_EP_INTERVAL_DATA \ | ||
| 756 | }, \ | ||
| 757 | .ep_tx = { \ | ||
| 758 | .bLength = sizeof(usb_ep_desc_t), \ | ||
| 759 | .bDescriptorType = USB_DT_ENDPOINT, \ | ||
| 760 | .bEndpointAddress = CDC_TX_ENDPOINT | USB_EP_DIR_IN, \ | ||
| 761 | .bmAttributes = USB_EP_TYPE_BULK, \ | ||
| 762 | .wMaxPacketSize = LE16(CDC_TX_SIZE), \ | ||
| 763 | .bInterval = CDC_EP_INTERVAL_DATA \ | ||
| 764 | } \ | ||
| 765 | } | ||
| 766 | |||
| 767 | // clang-format on | ||
| 768 | |||
| 769 | COMPILER_PACK_RESET() | ||
| 770 | |||
| 771 | #endif // VIRTSER_ENABLE | ||
| 772 | |||
| 773 | // ********************************************************************** | ||
| 774 | // CONFIGURATION Descriptor structure and content | ||
| 775 | // ********************************************************************** | ||
| 776 | COMPILER_PACK_SET(1) | ||
| 777 | |||
| 778 | typedef struct { | ||
| 779 | usb_conf_desc_t conf; | ||
| 780 | udi_hid_kbd_desc_t hid_kbd; | ||
| 781 | #ifdef MOUSE_ENABLE | ||
| 782 | udi_hid_mou_desc_t hid_mou; | ||
| 783 | #endif | ||
| 784 | #ifdef EXTRAKEY_ENABLE | ||
| 785 | udi_hid_exk_desc_t hid_exk; | ||
| 786 | #endif | ||
| 787 | #ifdef RAW_ENABLE | ||
| 788 | udi_hid_raw_desc_t hid_raw; | ||
| 789 | #endif | ||
| 790 | #ifdef CONSOLE_ENABLE | ||
| 791 | udi_hid_con_desc_t hid_con; | ||
| 792 | #endif | ||
| 793 | #ifdef NKRO_ENABLE | ||
| 794 | udi_hid_nkro_desc_t hid_nkro; | ||
| 795 | #endif | ||
| 796 | #ifdef MIDI_ENABLE | ||
| 797 | udi_hid_midi_desc_t hid_midi; | ||
| 798 | #endif | ||
| 799 | #ifdef VIRTSER_ENABLE | ||
| 800 | udi_cdc_desc_t cdc_serial; | ||
| 801 | #endif | ||
| 802 | } udc_desc_t; | ||
| 803 | |||
| 804 | COMPILER_PACK_RESET() | ||
| 805 | |||
| 806 | #endif //_UDI_DEVICE_CONF_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_device_epsize.h b/tmk_core/protocol/arm_atsam/usb/udi_device_epsize.h deleted file mode 100644 index 47bd02c074..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/udi_device_epsize.h +++ /dev/null | |||
| @@ -1,31 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef _UDI_DEVICE_EPSIZE_H_ | ||
| 19 | #define _UDI_DEVICE_EPSIZE_H_ | ||
| 20 | |||
| 21 | #define KEYBOARD_EPSIZE 8 | ||
| 22 | #define MOUSE_EPSIZE 16 | ||
| 23 | #define EXTRAKEY_EPSIZE 8 | ||
| 24 | #define RAW_EPSIZE 32 | ||
| 25 | #define CONSOLE_EPSIZE 32 | ||
| 26 | #define NKRO_EPSIZE 32 | ||
| 27 | #define MIDI_STREAM_EPSIZE 64 | ||
| 28 | #define CDC_NOTIFICATION_EPSIZE 8 | ||
| 29 | #define CDC_EPSIZE 16 | ||
| 30 | |||
| 31 | #endif //_UDI_DEVICE_EPSIZE_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_hid.c b/tmk_core/protocol/arm_atsam/usb/udi_hid.c deleted file mode 100644 index 73e384a039..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/udi_hid.c +++ /dev/null | |||
| @@ -1,148 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief USB Device Human Interface Device (HID) interface. | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #include "conf_usb.h" | ||
| 48 | #include "usb_protocol.h" | ||
| 49 | #include "udd.h" | ||
| 50 | #include "udc.h" | ||
| 51 | #include "udi_hid.h" | ||
| 52 | |||
| 53 | /** | ||
| 54 | * \ingroup udi_hid_group | ||
| 55 | * \defgroup udi_hid_group_internal Implementation of HID common library | ||
| 56 | * @{ | ||
| 57 | */ | ||
| 58 | |||
| 59 | /** | ||
| 60 | * \brief Send the specific descriptors requested by SETUP request | ||
| 61 | * | ||
| 62 | * \retval true if the descriptor is supported | ||
| 63 | */ | ||
| 64 | static bool udi_hid_reqstdifaceget_descriptor(uint8_t *report_desc); | ||
| 65 | |||
| 66 | bool udi_hid_setup(uint8_t *rate, uint8_t *protocol, uint8_t *report_desc, bool (*setup_report)(void)) { | ||
| 67 | if (Udd_setup_is_in()) { | ||
| 68 | // Requests Interface GET | ||
| 69 | if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) { | ||
| 70 | // Requests Standard Interface Get | ||
| 71 | switch (udd_g_ctrlreq.req.bRequest) { | ||
| 72 | case USB_REQ_GET_DESCRIPTOR: | ||
| 73 | return udi_hid_reqstdifaceget_descriptor(report_desc); | ||
| 74 | } | ||
| 75 | } | ||
| 76 | if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { | ||
| 77 | // Requests Class Interface Get | ||
| 78 | switch (udd_g_ctrlreq.req.bRequest) { | ||
| 79 | case USB_REQ_HID_GET_REPORT: | ||
| 80 | return setup_report(); | ||
| 81 | |||
| 82 | case USB_REQ_HID_GET_IDLE: | ||
| 83 | udd_g_ctrlreq.payload = rate; | ||
| 84 | udd_g_ctrlreq.payload_size = 1; | ||
| 85 | return true; | ||
| 86 | |||
| 87 | case USB_REQ_HID_GET_PROTOCOL: | ||
| 88 | udd_g_ctrlreq.payload = protocol; | ||
| 89 | udd_g_ctrlreq.payload_size = 1; | ||
| 90 | return true; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | } | ||
| 94 | if (Udd_setup_is_out()) { | ||
| 95 | // Requests Interface SET | ||
| 96 | if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { | ||
| 97 | // Requests Class Interface Set | ||
| 98 | switch (udd_g_ctrlreq.req.bRequest) { | ||
| 99 | case USB_REQ_HID_SET_REPORT: | ||
| 100 | return setup_report(); | ||
| 101 | |||
| 102 | case USB_REQ_HID_SET_IDLE: | ||
| 103 | *rate = udd_g_ctrlreq.req.wValue >> 8; | ||
| 104 | return true; | ||
| 105 | |||
| 106 | case USB_REQ_HID_SET_PROTOCOL: | ||
| 107 | if (0 != udd_g_ctrlreq.req.wLength) return false; | ||
| 108 | *protocol = udd_g_ctrlreq.req.wValue; | ||
| 109 | return true; | ||
| 110 | } | ||
| 111 | } | ||
| 112 | } | ||
| 113 | return false; // Request not supported | ||
| 114 | } | ||
| 115 | |||
| 116 | //--------------------------------------------- | ||
| 117 | //------- Internal routines | ||
| 118 | |||
| 119 | static bool udi_hid_reqstdifaceget_descriptor(uint8_t *report_desc) { | ||
| 120 | usb_hid_descriptor_t UDC_DESC_STORAGE *ptr_hid_desc; | ||
| 121 | |||
| 122 | // Get the USB descriptor which is located after the interface descriptor | ||
| 123 | // This descriptor must be the HID descriptor | ||
| 124 | ptr_hid_desc = (usb_hid_descriptor_t UDC_DESC_STORAGE *)((uint8_t *)udc_get_interface_desc() + sizeof(usb_iface_desc_t)); | ||
| 125 | if (USB_DT_HID != ptr_hid_desc->bDescriptorType) return false; | ||
| 126 | |||
| 127 | // The SETUP request can ask for: | ||
| 128 | // - an USB_DT_HID descriptor | ||
| 129 | // - or USB_DT_HID_REPORT descriptor | ||
| 130 | // - or USB_DT_HID_PHYSICAL descriptor | ||
| 131 | if (USB_DT_HID == (uint8_t)(udd_g_ctrlreq.req.wValue >> 8)) { | ||
| 132 | // USB_DT_HID descriptor requested then send it | ||
| 133 | udd_g_ctrlreq.payload = (uint8_t *)ptr_hid_desc; | ||
| 134 | udd_g_ctrlreq.payload_size = min(udd_g_ctrlreq.req.wLength, ptr_hid_desc->bLength); | ||
| 135 | return true; | ||
| 136 | } | ||
| 137 | // The HID_X descriptor requested must correspond to report type | ||
| 138 | // included in the HID descriptor | ||
| 139 | if (ptr_hid_desc->bRDescriptorType == (uint8_t)(udd_g_ctrlreq.req.wValue >> 8)) { | ||
| 140 | // Send HID Report descriptor given by high level | ||
| 141 | udd_g_ctrlreq.payload = report_desc; | ||
| 142 | udd_g_ctrlreq.payload_size = min(udd_g_ctrlreq.req.wLength, le16_to_cpu(ptr_hid_desc->wDescriptorLength)); | ||
| 143 | return true; | ||
| 144 | } | ||
| 145 | return false; | ||
| 146 | } | ||
| 147 | |||
| 148 | //@} | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_hid.h b/tmk_core/protocol/arm_atsam/usb/udi_hid.h deleted file mode 100644 index a08b7db744..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/udi_hid.h +++ /dev/null | |||
| @@ -1,85 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief USB Device Human Interface Device (HID) interface definitions. | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #ifndef _UDI_HID_H_ | ||
| 48 | #define _UDI_HID_H_ | ||
| 49 | |||
| 50 | #include "conf_usb.h" | ||
| 51 | #include "usb_protocol.h" | ||
| 52 | #include "usb_protocol_hid.h" | ||
| 53 | #include "udd.h" | ||
| 54 | |||
| 55 | #ifdef __cplusplus | ||
| 56 | extern "C" { | ||
| 57 | #endif | ||
| 58 | |||
| 59 | /** | ||
| 60 | * \ingroup udi_group | ||
| 61 | * \defgroup udi_hid_group USB Device Interface (UDI) for Human Interface Device (HID) | ||
| 62 | * | ||
| 63 | * Common library for all Human Interface Device (HID) implementation. | ||
| 64 | * | ||
| 65 | * @{ | ||
| 66 | */ | ||
| 67 | |||
| 68 | /** | ||
| 69 | * \brief Decode HID setup request | ||
| 70 | * | ||
| 71 | * \param rate Pointer on rate of current HID interface | ||
| 72 | * \param protocol Pointer on protocol of current HID interface | ||
| 73 | * \param report_desc Pointer on report descriptor of current HID interface | ||
| 74 | * \param set_report Pointer on set_report callback of current HID interface | ||
| 75 | * | ||
| 76 | * \return \c 1 if function was successfully done, otherwise \c 0. | ||
| 77 | */ | ||
| 78 | bool udi_hid_setup(uint8_t *rate, uint8_t *protocol, uint8_t *report_desc, bool (*setup_report)(void)); | ||
| 79 | |||
| 80 | //@} | ||
| 81 | |||
| 82 | #ifdef __cplusplus | ||
| 83 | } | ||
| 84 | #endif | ||
| 85 | #endif // _UDI_HID_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c deleted file mode 100644 index bf190b1f18..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c +++ /dev/null | |||
| @@ -1,861 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief USB Device Human Interface Device (HID) keyboard interface. | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #include "samd51j18a.h" | ||
| 48 | #include "d51_util.h" | ||
| 49 | #include "conf_usb.h" | ||
| 50 | #include "usb_protocol.h" | ||
| 51 | #include "udd.h" | ||
| 52 | #include "udc.h" | ||
| 53 | #include "udi_device_conf.h" | ||
| 54 | #include "udi_hid.h" | ||
| 55 | #include "udi_hid_kbd.h" | ||
| 56 | #include <string.h> | ||
| 57 | #include "report.h" | ||
| 58 | #include "usb_descriptor_common.h" | ||
| 59 | |||
| 60 | //*************************************************************************** | ||
| 61 | // KBD | ||
| 62 | //*************************************************************************** | ||
| 63 | bool udi_hid_kbd_enable(void); | ||
| 64 | void udi_hid_kbd_disable(void); | ||
| 65 | bool udi_hid_kbd_setup(void); | ||
| 66 | uint8_t udi_hid_kbd_getsetting(void); | ||
| 67 | |||
| 68 | UDC_DESC_STORAGE udi_api_t udi_api_hid_kbd = { | ||
| 69 | .enable = (bool (*)(void))udi_hid_kbd_enable, | ||
| 70 | .disable = (void (*)(void))udi_hid_kbd_disable, | ||
| 71 | .setup = (bool (*)(void))udi_hid_kbd_setup, | ||
| 72 | .getsetting = (uint8_t(*)(void))udi_hid_kbd_getsetting, | ||
| 73 | .sof_notify = NULL, | ||
| 74 | }; | ||
| 75 | |||
| 76 | COMPILER_WORD_ALIGNED | ||
| 77 | static uint8_t udi_hid_kbd_rate; | ||
| 78 | |||
| 79 | COMPILER_WORD_ALIGNED | ||
| 80 | static uint8_t udi_hid_kbd_protocol; | ||
| 81 | |||
| 82 | COMPILER_WORD_ALIGNED | ||
| 83 | uint8_t udi_hid_kbd_report_set; | ||
| 84 | |||
| 85 | bool udi_hid_kbd_b_report_valid; | ||
| 86 | |||
| 87 | COMPILER_WORD_ALIGNED | ||
| 88 | uint8_t udi_hid_kbd_report[UDI_HID_KBD_REPORT_SIZE]; | ||
| 89 | |||
| 90 | volatile bool udi_hid_kbd_b_report_trans_ongoing; | ||
| 91 | |||
| 92 | COMPILER_WORD_ALIGNED | ||
| 93 | static uint8_t udi_hid_kbd_report_trans[UDI_HID_KBD_REPORT_SIZE]; | ||
| 94 | |||
| 95 | COMPILER_WORD_ALIGNED | ||
| 96 | UDC_DESC_STORAGE udi_hid_kbd_report_desc_t udi_hid_kbd_report_desc = {{ | ||
| 97 | 0x05, 0x01, // Usage Page (Generic Desktop) | ||
| 98 | 0x09, 0x06, // Usage (Keyboard) | ||
| 99 | 0xA1, 0x01, // Collection (Application) | ||
| 100 | // Modifiers (8 bits) | ||
| 101 | 0x05, 0x07, // Usage Page (Keyboard) | ||
| 102 | 0x19, 0xE0, // Usage Minimum (Keyboard Left Control) | ||
| 103 | 0x29, 0xE7, // Usage Maximum (Keyboard Right GUI) | ||
| 104 | 0x15, 0x00, // Logical Minimum (0) | ||
| 105 | 0x25, 0x01, // Logical Maximum (1) | ||
| 106 | 0x95, 0x08, // Report Count (8) | ||
| 107 | 0x75, 0x01, // Report Size (1) | ||
| 108 | 0x81, 0x02, // Input (Data, Variable, Absolute) | ||
| 109 | // Reserved (1 byte) | ||
| 110 | 0x81, 0x01, // Input (Constant) | ||
| 111 | // Keycodes (6 bytes) | ||
| 112 | 0x19, 0x00, // Usage Minimum (0) | ||
| 113 | 0x29, 0xFF, // Usage Maximum (255) | ||
| 114 | 0x15, 0x00, // Logical Minimum (0) | ||
| 115 | 0x25, 0xFF, // Logical Maximum (255) | ||
| 116 | 0x95, 0x06, // Report Count (6) | ||
| 117 | 0x75, 0x08, // Report Size (8) | ||
| 118 | 0x81, 0x00, // Input (Data, Array, Absolute) | ||
| 119 | |||
| 120 | // Status LEDs (5 bits) | ||
| 121 | 0x05, 0x08, // Usage Page (LED) | ||
| 122 | 0x19, 0x01, // Usage Minimum (Num Lock) | ||
| 123 | 0x29, 0x05, // Usage Maximum (Kana) | ||
| 124 | 0x15, 0x00, // Logical Minimum (0) | ||
| 125 | 0x25, 0x01, // Logical Maximum (1) | ||
| 126 | 0x95, 0x05, // Report Count (5) | ||
| 127 | 0x75, 0x01, // Report Size (1) | ||
| 128 | 0x91, 0x02, // Output (Data, Variable, Absolute) | ||
| 129 | // LED padding (3 bits) | ||
| 130 | 0x95, 0x03, // Report Count (3) | ||
| 131 | 0x91, 0x01, // Output (Constant) | ||
| 132 | 0xC0 // End Collection | ||
| 133 | }}; | ||
| 134 | |||
| 135 | static bool udi_hid_kbd_setreport(void); | ||
| 136 | |||
| 137 | static void udi_hid_kbd_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep); | ||
| 138 | |||
| 139 | static void udi_hid_kbd_setreport_valid(void); | ||
| 140 | |||
| 141 | bool udi_hid_kbd_enable(void) { | ||
| 142 | // Initialize internal values | ||
| 143 | udi_hid_kbd_rate = 0; | ||
| 144 | udi_hid_kbd_protocol = 0; | ||
| 145 | udi_hid_kbd_b_report_trans_ongoing = false; | ||
| 146 | memset(udi_hid_kbd_report, 0, UDI_HID_KBD_REPORT_SIZE); | ||
| 147 | udi_hid_kbd_b_report_valid = false; | ||
| 148 | return UDI_HID_KBD_ENABLE_EXT(); | ||
| 149 | } | ||
| 150 | |||
| 151 | void udi_hid_kbd_disable(void) { | ||
| 152 | UDI_HID_KBD_DISABLE_EXT(); | ||
| 153 | } | ||
| 154 | |||
| 155 | bool udi_hid_kbd_setup(void) { | ||
| 156 | return udi_hid_setup(&udi_hid_kbd_rate, &udi_hid_kbd_protocol, (uint8_t *)&udi_hid_kbd_report_desc, udi_hid_kbd_setreport); | ||
| 157 | } | ||
| 158 | |||
| 159 | uint8_t udi_hid_kbd_getsetting(void) { | ||
| 160 | return 0; | ||
| 161 | } | ||
| 162 | |||
| 163 | static bool udi_hid_kbd_setreport(void) { | ||
| 164 | 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)) { | ||
| 165 | // Report OUT type on report ID 0 from USB Host | ||
| 166 | udd_g_ctrlreq.payload = &udi_hid_kbd_report_set; | ||
| 167 | udd_g_ctrlreq.callback = udi_hid_kbd_setreport_valid; | ||
| 168 | udd_g_ctrlreq.payload_size = 1; | ||
| 169 | return true; | ||
| 170 | } | ||
| 171 | return false; | ||
| 172 | } | ||
| 173 | |||
| 174 | bool udi_hid_kbd_send_report(void) { | ||
| 175 | if (!main_b_kbd_enable) { | ||
| 176 | return false; | ||
| 177 | } | ||
| 178 | |||
| 179 | if (udi_hid_kbd_b_report_trans_ongoing) { | ||
| 180 | return false; | ||
| 181 | } | ||
| 182 | |||
| 183 | memcpy(udi_hid_kbd_report_trans, udi_hid_kbd_report, UDI_HID_KBD_REPORT_SIZE); | ||
| 184 | udi_hid_kbd_b_report_valid = false; | ||
| 185 | 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); | ||
| 186 | |||
| 187 | return udi_hid_kbd_b_report_trans_ongoing; | ||
| 188 | } | ||
| 189 | |||
| 190 | static void udi_hid_kbd_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep) { | ||
| 191 | UNUSED(status); | ||
| 192 | UNUSED(nb_sent); | ||
| 193 | UNUSED(ep); | ||
| 194 | udi_hid_kbd_b_report_trans_ongoing = false; | ||
| 195 | if (udi_hid_kbd_b_report_valid) { | ||
| 196 | udi_hid_kbd_send_report(); | ||
| 197 | } | ||
| 198 | } | ||
| 199 | |||
| 200 | static void udi_hid_kbd_setreport_valid(void) { | ||
| 201 | // UDI_HID_KBD_CHANGE_LED(udi_hid_kbd_report_set); | ||
| 202 | } | ||
| 203 | |||
| 204 | //******************************************************************************************** | ||
| 205 | // NKRO Keyboard | ||
| 206 | //******************************************************************************************** | ||
| 207 | #ifdef NKRO_ENABLE | ||
| 208 | |||
| 209 | bool udi_hid_nkro_enable(void); | ||
| 210 | void udi_hid_nkro_disable(void); | ||
| 211 | bool udi_hid_nkro_setup(void); | ||
| 212 | uint8_t udi_hid_nkro_getsetting(void); | ||
| 213 | |||
| 214 | UDC_DESC_STORAGE udi_api_t udi_api_hid_nkro = { | ||
| 215 | .enable = (bool (*)(void))udi_hid_nkro_enable, | ||
| 216 | .disable = (void (*)(void))udi_hid_nkro_disable, | ||
| 217 | .setup = (bool (*)(void))udi_hid_nkro_setup, | ||
| 218 | .getsetting = (uint8_t(*)(void))udi_hid_nkro_getsetting, | ||
| 219 | .sof_notify = NULL, | ||
| 220 | }; | ||
| 221 | |||
| 222 | COMPILER_WORD_ALIGNED | ||
| 223 | static uint8_t udi_hid_nkro_rate; | ||
| 224 | |||
| 225 | COMPILER_WORD_ALIGNED | ||
| 226 | static uint8_t udi_hid_nkro_protocol; | ||
| 227 | |||
| 228 | COMPILER_WORD_ALIGNED | ||
| 229 | uint8_t udi_hid_nkro_report_set; | ||
| 230 | |||
| 231 | bool udi_hid_nkro_b_report_valid; | ||
| 232 | |||
| 233 | COMPILER_WORD_ALIGNED | ||
| 234 | uint8_t udi_hid_nkro_report[UDI_HID_NKRO_REPORT_SIZE]; | ||
| 235 | |||
| 236 | volatile bool udi_hid_nkro_b_report_trans_ongoing; | ||
| 237 | |||
| 238 | COMPILER_WORD_ALIGNED | ||
| 239 | static uint8_t udi_hid_nkro_report_trans[UDI_HID_NKRO_REPORT_SIZE]; | ||
| 240 | |||
| 241 | COMPILER_WORD_ALIGNED | ||
| 242 | UDC_DESC_STORAGE udi_hid_nkro_report_desc_t udi_hid_nkro_report_desc = {{ | ||
| 243 | 0x05, 0x01, // Usage Page (Generic Desktop) | ||
| 244 | 0x09, 0x06, // Usage (Keyboard) | ||
| 245 | 0xA1, 0x01, // Collection (Application) | ||
| 246 | |||
| 247 | // Modifiers (8 bits) | ||
| 248 | 0x05, 0x07, // Usage Page (Keyboard/Keypad) | ||
| 249 | 0x19, 0xE0, // Usage Minimum (Keyboard Left Control) | ||
| 250 | 0x29, 0xE7, // Usage Maximum (Keyboard Right GUI) | ||
| 251 | 0x15, 0x00, // Logical Minimum (0) | ||
| 252 | 0x25, 0x01, // Logical Maximum (1) | ||
| 253 | 0x95, 0x08, // Report Count (8) | ||
| 254 | 0x75, 0x01, // Report Size (1) | ||
| 255 | 0x81, 0x02, // Input (Data, Variable, Absolute) | ||
| 256 | // Keycodes | ||
| 257 | 0x05, 0x07, // Usage Page (Keyboard/Keypad) | ||
| 258 | 0x19, 0x00, // Usage Minimum (0) | ||
| 259 | 0x29, 0xF7, // Usage Maximum (247) | ||
| 260 | 0x15, 0x00, // Logical Minimum (0) | ||
| 261 | 0x25, 0x01, // Logical Maximum (1) | ||
| 262 | 0x95, 0xF8, // Report Count (248) | ||
| 263 | 0x75, 0x01, // Report Size (1) | ||
| 264 | 0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield) | ||
| 265 | |||
| 266 | // Status LEDs (5 bits) | ||
| 267 | 0x05, 0x08, // Usage Page (LED) | ||
| 268 | 0x19, 0x01, // Usage Minimum (Num Lock) | ||
| 269 | 0x29, 0x05, // Usage Maximum (Kana) | ||
| 270 | 0x95, 0x05, // Report Count (5) | ||
| 271 | 0x75, 0x01, // Report Size (1) | ||
| 272 | 0x91, 0x02, // Output (Data, Variable, Absolute) | ||
| 273 | // LED padding (3 bits) | ||
| 274 | 0x95, 0x01, // Report Count (1) | ||
| 275 | 0x75, 0x03, // Report Size (3) | ||
| 276 | 0x91, 0x03, // Output (Constant) | ||
| 277 | 0xC0 // End Collection | ||
| 278 | }}; | ||
| 279 | |||
| 280 | static bool udi_hid_nkro_setreport(void); | ||
| 281 | static void udi_hid_nkro_setreport_valid(void); | ||
| 282 | static void udi_hid_nkro_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep); | ||
| 283 | |||
| 284 | bool udi_hid_nkro_enable(void) { | ||
| 285 | // Initialize internal values | ||
| 286 | udi_hid_nkro_rate = 0; | ||
| 287 | udi_hid_nkro_protocol = 0; | ||
| 288 | udi_hid_nkro_b_report_trans_ongoing = false; | ||
| 289 | memset(udi_hid_nkro_report, 0, UDI_HID_NKRO_REPORT_SIZE); | ||
| 290 | udi_hid_nkro_b_report_valid = false; | ||
| 291 | return UDI_HID_NKRO_ENABLE_EXT(); | ||
| 292 | } | ||
| 293 | |||
| 294 | void udi_hid_nkro_disable(void) { | ||
| 295 | UDI_HID_NKRO_DISABLE_EXT(); | ||
| 296 | } | ||
| 297 | |||
| 298 | bool udi_hid_nkro_setup(void) { | ||
| 299 | return udi_hid_setup(&udi_hid_nkro_rate, &udi_hid_nkro_protocol, (uint8_t *)&udi_hid_nkro_report_desc, udi_hid_nkro_setreport); | ||
| 300 | } | ||
| 301 | |||
| 302 | uint8_t udi_hid_nkro_getsetting(void) { | ||
| 303 | return 0; | ||
| 304 | } | ||
| 305 | |||
| 306 | // keyboard receives LED report here | ||
| 307 | static bool udi_hid_nkro_setreport(void) { | ||
| 308 | 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)) { | ||
| 309 | // Report OUT type on report ID 0 from USB Host | ||
| 310 | udd_g_ctrlreq.payload = &udi_hid_nkro_report_set; | ||
| 311 | udd_g_ctrlreq.callback = udi_hid_nkro_setreport_valid; // must call routine to transform setreport to LED state | ||
| 312 | udd_g_ctrlreq.payload_size = 1; | ||
| 313 | return true; | ||
| 314 | } | ||
| 315 | return false; | ||
| 316 | } | ||
| 317 | |||
| 318 | bool udi_hid_nkro_send_report(void) { | ||
| 319 | if (!main_b_nkro_enable) { | ||
| 320 | return false; | ||
| 321 | } | ||
| 322 | |||
| 323 | if (udi_hid_nkro_b_report_trans_ongoing) { | ||
| 324 | return false; | ||
| 325 | } | ||
| 326 | |||
| 327 | memcpy(udi_hid_nkro_report_trans, udi_hid_nkro_report, UDI_HID_NKRO_REPORT_SIZE); | ||
| 328 | udi_hid_nkro_b_report_valid = false; | ||
| 329 | 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); | ||
| 330 | |||
| 331 | return udi_hid_nkro_b_report_trans_ongoing; | ||
| 332 | } | ||
| 333 | |||
| 334 | static void udi_hid_nkro_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep) { | ||
| 335 | UNUSED(status); | ||
| 336 | UNUSED(nb_sent); | ||
| 337 | UNUSED(ep); | ||
| 338 | udi_hid_nkro_b_report_trans_ongoing = false; | ||
| 339 | if (udi_hid_nkro_b_report_valid) { | ||
| 340 | udi_hid_nkro_send_report(); | ||
| 341 | } | ||
| 342 | } | ||
| 343 | |||
| 344 | static void udi_hid_nkro_setreport_valid(void) { | ||
| 345 | // UDI_HID_NKRO_CHANGE_LED(udi_hid_nkro_report_set); | ||
| 346 | } | ||
| 347 | |||
| 348 | #endif // NKRO_ENABLE | ||
| 349 | |||
| 350 | //******************************************************************************************** | ||
| 351 | // EXK (extra-keys) SYS-CTRL Keyboard | ||
| 352 | //******************************************************************************************** | ||
| 353 | #ifdef EXTRAKEY_ENABLE | ||
| 354 | |||
| 355 | bool udi_hid_exk_enable(void); | ||
| 356 | void udi_hid_exk_disable(void); | ||
| 357 | bool udi_hid_exk_setup(void); | ||
| 358 | uint8_t udi_hid_exk_getsetting(void); | ||
| 359 | |||
| 360 | UDC_DESC_STORAGE udi_api_t udi_api_hid_exk = { | ||
| 361 | .enable = (bool (*)(void))udi_hid_exk_enable, | ||
| 362 | .disable = (void (*)(void))udi_hid_exk_disable, | ||
| 363 | .setup = (bool (*)(void))udi_hid_exk_setup, | ||
| 364 | .getsetting = (uint8_t(*)(void))udi_hid_exk_getsetting, | ||
| 365 | .sof_notify = NULL, | ||
| 366 | }; | ||
| 367 | |||
| 368 | COMPILER_WORD_ALIGNED | ||
| 369 | static uint8_t udi_hid_exk_rate; | ||
| 370 | |||
| 371 | COMPILER_WORD_ALIGNED | ||
| 372 | static uint8_t udi_hid_exk_protocol; | ||
| 373 | |||
| 374 | // COMPILER_WORD_ALIGNED | ||
| 375 | // uint8_t udi_hid_exk_report_set; | ||
| 376 | |||
| 377 | bool udi_hid_exk_b_report_valid; | ||
| 378 | |||
| 379 | COMPILER_WORD_ALIGNED | ||
| 380 | uint8_t udi_hid_exk_report[UDI_HID_EXK_REPORT_SIZE]; | ||
| 381 | |||
| 382 | static bool udi_hid_exk_b_report_trans_ongoing; | ||
| 383 | |||
| 384 | COMPILER_WORD_ALIGNED | ||
| 385 | static uint8_t udi_hid_exk_report_trans[UDI_HID_EXK_REPORT_SIZE]; | ||
| 386 | |||
| 387 | COMPILER_WORD_ALIGNED | ||
| 388 | UDC_DESC_STORAGE udi_hid_exk_report_desc_t udi_hid_exk_report_desc = {{ | ||
| 389 | // clang-format off | ||
| 390 | 0x05, 0x01, // Usage Page (Generic Desktop) | ||
| 391 | 0x09, 0x80, // Usage (System Control) | ||
| 392 | 0xA1, 0x01, // Collection (Application) | ||
| 393 | 0x85, REPORT_ID_SYSTEM, // Report ID | ||
| 394 | 0x19, 0x01, // Usage Minimum (Pointer) | ||
| 395 | 0x2A, 0xB7, 0x00, // Usage Maximum (System Display LCD Autoscale) | ||
| 396 | 0x15, 0x01, // Logical Minimum | ||
| 397 | 0x26, 0xB7, 0x00, // Logical Maximum | ||
| 398 | 0x95, 0x01, // Report Count (1) | ||
| 399 | 0x75, 0x10, // Report Size (16) | ||
| 400 | 0x81, 0x00, // Input (Data, Array, Absolute) | ||
| 401 | 0xC0, // End Collection | ||
| 402 | |||
| 403 | 0x05, 0x0C, // Usage Page (Consumer) | ||
| 404 | 0x09, 0x01, // Usage (Consumer Control) | ||
| 405 | 0xA1, 0x01, // Collection (Application) | ||
| 406 | 0x85, REPORT_ID_CONSUMER, // Report ID | ||
| 407 | 0x19, 0x01, // Usage Minimum (Consumer Control) | ||
| 408 | 0x2A, 0xA0, 0x02, // Usage Maximum (AC Desktop Show All Applications) | ||
| 409 | 0x15, 0x01, // Logical Minimum | ||
| 410 | 0x26, 0xA0, 0x02, // Logical Maximum | ||
| 411 | 0x95, 0x01, // Report Count (1) | ||
| 412 | 0x75, 0x10, // Report Size (16) | ||
| 413 | 0x81, 0x00, // Input (Data, Array, Absolute) | ||
| 414 | 0xC0 // End Collection | ||
| 415 | //clang-format on | ||
| 416 | }}; | ||
| 417 | |||
| 418 | static void udi_hid_exk_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep); | ||
| 419 | |||
| 420 | bool udi_hid_exk_enable(void) { | ||
| 421 | // Initialize internal values | ||
| 422 | udi_hid_exk_rate = 0; | ||
| 423 | udi_hid_exk_protocol = 0; | ||
| 424 | udi_hid_exk_b_report_trans_ongoing = false; | ||
| 425 | memset(udi_hid_exk_report, 0, UDI_HID_EXK_REPORT_SIZE); | ||
| 426 | udi_hid_exk_b_report_valid = false; | ||
| 427 | return UDI_HID_EXK_ENABLE_EXT(); | ||
| 428 | } | ||
| 429 | |||
| 430 | void udi_hid_exk_disable(void) { UDI_HID_EXK_DISABLE_EXT(); } | ||
| 431 | |||
| 432 | 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); } | ||
| 433 | |||
| 434 | uint8_t udi_hid_exk_getsetting(void) { return 0; } | ||
| 435 | |||
| 436 | bool udi_hid_exk_send_report(void) { | ||
| 437 | if (!main_b_exk_enable) { | ||
| 438 | return false; | ||
| 439 | } | ||
| 440 | |||
| 441 | if (udi_hid_exk_b_report_trans_ongoing) { | ||
| 442 | return false; | ||
| 443 | } | ||
| 444 | |||
| 445 | memcpy(udi_hid_exk_report_trans, udi_hid_exk_report, UDI_HID_EXK_REPORT_SIZE); | ||
| 446 | udi_hid_exk_b_report_valid = false; | ||
| 447 | 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); | ||
| 448 | |||
| 449 | return udi_hid_exk_b_report_trans_ongoing; | ||
| 450 | } | ||
| 451 | |||
| 452 | static void udi_hid_exk_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep) { | ||
| 453 | UNUSED(status); | ||
| 454 | UNUSED(nb_sent); | ||
| 455 | UNUSED(ep); | ||
| 456 | udi_hid_exk_b_report_trans_ongoing = false; | ||
| 457 | if (udi_hid_exk_b_report_valid) { | ||
| 458 | udi_hid_exk_send_report(); | ||
| 459 | } | ||
| 460 | } | ||
| 461 | |||
| 462 | #endif // EXTRAKEY_ENABLE | ||
| 463 | |||
| 464 | //******************************************************************************************** | ||
| 465 | // MOU Mouse | ||
| 466 | //******************************************************************************************** | ||
| 467 | #ifdef MOUSE_ENABLE | ||
| 468 | |||
| 469 | bool udi_hid_mou_enable(void); | ||
| 470 | void udi_hid_mou_disable(void); | ||
| 471 | bool udi_hid_mou_setup(void); | ||
| 472 | uint8_t udi_hid_mou_getsetting(void); | ||
| 473 | |||
| 474 | UDC_DESC_STORAGE udi_api_t udi_api_hid_mou = { | ||
| 475 | .enable = (bool (*)(void))udi_hid_mou_enable, | ||
| 476 | .disable = (void (*)(void))udi_hid_mou_disable, | ||
| 477 | .setup = (bool (*)(void))udi_hid_mou_setup, | ||
| 478 | .getsetting = (uint8_t(*)(void))udi_hid_mou_getsetting, | ||
| 479 | .sof_notify = NULL, | ||
| 480 | }; | ||
| 481 | |||
| 482 | COMPILER_WORD_ALIGNED | ||
| 483 | static uint8_t udi_hid_mou_rate; | ||
| 484 | |||
| 485 | COMPILER_WORD_ALIGNED | ||
| 486 | static uint8_t udi_hid_mou_protocol; | ||
| 487 | |||
| 488 | // COMPILER_WORD_ALIGNED | ||
| 489 | // uint8_t udi_hid_mou_report_set; //No set report | ||
| 490 | |||
| 491 | bool udi_hid_mou_b_report_valid; | ||
| 492 | |||
| 493 | COMPILER_WORD_ALIGNED | ||
| 494 | uint8_t udi_hid_mou_report[UDI_HID_MOU_REPORT_SIZE]; | ||
| 495 | |||
| 496 | static bool udi_hid_mou_b_report_trans_ongoing; | ||
| 497 | |||
| 498 | COMPILER_WORD_ALIGNED | ||
| 499 | static uint8_t udi_hid_mou_report_trans[UDI_HID_MOU_REPORT_SIZE]; | ||
| 500 | |||
| 501 | COMPILER_WORD_ALIGNED | ||
| 502 | UDC_DESC_STORAGE udi_hid_mou_report_desc_t udi_hid_mou_report_desc = {{ | ||
| 503 | 0x05, 0x01, // Usage Page (Generic Desktop) | ||
| 504 | 0x09, 0x02, // Usage (Mouse) | ||
| 505 | 0xA1, 0x01, // Collection (Application) | ||
| 506 | 0x09, 0x01, // Usage (Pointer) | ||
| 507 | 0xA1, 0x00, // Collection (Physical) | ||
| 508 | // Buttons (5 bits) | ||
| 509 | 0x05, 0x09, // Usage Page (Button) | ||
| 510 | 0x19, 0x01, // Usage Minimum (Button 1) | ||
| 511 | 0x29, 0x05, // Usage Maximun (Button 5) | ||
| 512 | 0x15, 0x00, // Logical Minimum (0) | ||
| 513 | 0x25, 0x01, // Logical Maximum (1) | ||
| 514 | 0x95, 0x05, // Report Count (5) | ||
| 515 | 0x75, 0x01, // Report Size (1) | ||
| 516 | 0x81, 0x02, // Input (Data, Variable, Absolute) | ||
| 517 | // Button padding (3 bits) | ||
| 518 | 0x95, 0x01, // Report Count (1) | ||
| 519 | 0x75, 0x03, // Report Size (3) | ||
| 520 | 0x81, 0x01, // Input (Constant) | ||
| 521 | |||
| 522 | // X/Y position (2 bytes) | ||
| 523 | 0x05, 0x01, // Usage Page (Generic Desktop) | ||
| 524 | 0x09, 0x30, // Usage (X) | ||
| 525 | 0x09, 0x31, // Usage (Y) | ||
| 526 | 0x15, 0x81, // Logical Minimum (-127) | ||
| 527 | 0x25, 0x7F, // Logical Maximum (127) | ||
| 528 | 0x95, 0x02, // Report Count (2) | ||
| 529 | 0x75, 0x08, // Report Size (8) | ||
| 530 | 0x81, 0x06, // Input (Data, Variable, Relative) | ||
| 531 | |||
| 532 | // Vertical wheel (1 byte) | ||
| 533 | 0x09, 0x38, // Usage (Wheel) | ||
| 534 | 0x15, 0x81, // Logical Minimum (-127) | ||
| 535 | 0x25, 0x7F, // Logical Maximum (127) | ||
| 536 | 0x95, 0x01, // Report Count (1) | ||
| 537 | 0x75, 0x08, // Report Size (8) | ||
| 538 | 0x81, 0x06, // Input (Data, Variable, Relative) | ||
| 539 | |||
| 540 | // Horizontal wheel (1 byte) | ||
| 541 | 0x05, 0x0C, // Usage Page (Consumer) | ||
| 542 | 0x0A, 0x38, 0x02, // Usage (AC Pan) | ||
| 543 | 0x15, 0x81, // Logical Minimum (-127) | ||
| 544 | 0x25, 0x7F, // Logical Maximum (127) | ||
| 545 | 0x95, 0x01, // Report Count (1) | ||
| 546 | 0x75, 0x08, // Report Size (8) | ||
| 547 | 0x81, 0x06, // Input (Data, Variable, Relative) | ||
| 548 | 0xC0, // End Collection | ||
| 549 | 0xC0 // End Collection | ||
| 550 | }}; | ||
| 551 | |||
| 552 | static void udi_hid_mou_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep); | ||
| 553 | |||
| 554 | bool udi_hid_mou_enable(void) { | ||
| 555 | // Initialize internal values | ||
| 556 | udi_hid_mou_rate = 0; | ||
| 557 | udi_hid_mou_protocol = 0; | ||
| 558 | udi_hid_mou_b_report_trans_ongoing = false; | ||
| 559 | memset(udi_hid_mou_report, 0, UDI_HID_MOU_REPORT_SIZE); | ||
| 560 | udi_hid_mou_b_report_valid = false; | ||
| 561 | return UDI_HID_MOU_ENABLE_EXT(); | ||
| 562 | } | ||
| 563 | |||
| 564 | void udi_hid_mou_disable(void) { UDI_HID_MOU_DISABLE_EXT(); } | ||
| 565 | |||
| 566 | 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); } | ||
| 567 | |||
| 568 | uint8_t udi_hid_mou_getsetting(void) { return 0; } | ||
| 569 | |||
| 570 | bool udi_hid_mou_send_report(void) { | ||
| 571 | if (!main_b_mou_enable) { | ||
| 572 | return false; | ||
| 573 | } | ||
| 574 | |||
| 575 | if (udi_hid_mou_b_report_trans_ongoing) { | ||
| 576 | return false; | ||
| 577 | } | ||
| 578 | |||
| 579 | memcpy(udi_hid_mou_report_trans, udi_hid_mou_report, UDI_HID_MOU_REPORT_SIZE); | ||
| 580 | udi_hid_mou_b_report_valid = false; | ||
| 581 | 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); | ||
| 582 | |||
| 583 | return udi_hid_mou_b_report_trans_ongoing; | ||
| 584 | } | ||
| 585 | |||
| 586 | static void udi_hid_mou_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep) { | ||
| 587 | UNUSED(status); | ||
| 588 | UNUSED(nb_sent); | ||
| 589 | UNUSED(ep); | ||
| 590 | udi_hid_mou_b_report_trans_ongoing = false; | ||
| 591 | if (udi_hid_mou_b_report_valid) { | ||
| 592 | udi_hid_mou_send_report(); | ||
| 593 | } | ||
| 594 | } | ||
| 595 | |||
| 596 | #endif // MOUSE_ENABLE | ||
| 597 | |||
| 598 | //******************************************************************************************** | ||
| 599 | // RAW | ||
| 600 | //******************************************************************************************** | ||
| 601 | #ifdef RAW_ENABLE | ||
| 602 | |||
| 603 | bool udi_hid_raw_enable(void); | ||
| 604 | void udi_hid_raw_disable(void); | ||
| 605 | bool udi_hid_raw_setup(void); | ||
| 606 | uint8_t udi_hid_raw_getsetting(void); | ||
| 607 | |||
| 608 | UDC_DESC_STORAGE udi_api_t udi_api_hid_raw = { | ||
| 609 | .enable = (bool (*)(void))udi_hid_raw_enable, | ||
| 610 | .disable = (void (*)(void))udi_hid_raw_disable, | ||
| 611 | .setup = (bool (*)(void))udi_hid_raw_setup, | ||
| 612 | .getsetting = (uint8_t(*)(void))udi_hid_raw_getsetting, | ||
| 613 | .sof_notify = NULL, | ||
| 614 | }; | ||
| 615 | |||
| 616 | COMPILER_WORD_ALIGNED | ||
| 617 | static uint8_t udi_hid_raw_rate; | ||
| 618 | |||
| 619 | COMPILER_WORD_ALIGNED | ||
| 620 | static uint8_t udi_hid_raw_protocol; | ||
| 621 | |||
| 622 | COMPILER_WORD_ALIGNED | ||
| 623 | uint8_t udi_hid_raw_report_set[UDI_HID_RAW_REPORT_SIZE]; | ||
| 624 | |||
| 625 | static bool udi_hid_raw_b_report_valid; | ||
| 626 | |||
| 627 | COMPILER_WORD_ALIGNED | ||
| 628 | uint8_t udi_hid_raw_report[UDI_HID_RAW_REPORT_SIZE]; | ||
| 629 | |||
| 630 | static bool udi_hid_raw_b_report_trans_ongoing; | ||
| 631 | |||
| 632 | COMPILER_WORD_ALIGNED | ||
| 633 | static uint8_t udi_hid_raw_report_trans[UDI_HID_RAW_REPORT_SIZE]; | ||
| 634 | |||
| 635 | COMPILER_WORD_ALIGNED | ||
| 636 | static uint8_t udi_hid_raw_report_recv[UDI_HID_RAW_REPORT_SIZE]; | ||
| 637 | |||
| 638 | COMPILER_WORD_ALIGNED | ||
| 639 | UDC_DESC_STORAGE udi_hid_raw_report_desc_t udi_hid_raw_report_desc = {{ | ||
| 640 | 0x06, HID_VALUE_16(RAW_USAGE_PAGE), // Usage Page (Vendor Defined) | ||
| 641 | 0x09, RAW_USAGE_ID, // Usage (Vendor Defined) | ||
| 642 | 0xA1, 0x01, // Collection (Application) | ||
| 643 | 0x75, 0x08, // Report Size (8) | ||
| 644 | 0x15, 0x00, // Logical Minimum (0) | ||
| 645 | 0x25, 0xFF, // Logical Maximum (255) | ||
| 646 | // Data to host | ||
| 647 | 0x09, 0x62, // Usage (Vendor Defined) | ||
| 648 | 0x95, RAW_EPSIZE, // Report Count | ||
| 649 | 0x81, 0x02, // Input (Data, Variable, Absolute) | ||
| 650 | // Data from host | ||
| 651 | 0x09, 0x63, // Usage (Vendor Defined) | ||
| 652 | 0x95, RAW_EPSIZE, // Report Count | ||
| 653 | 0x91, 0x02, // Output (Data, Variable, Absolute) | ||
| 654 | 0xC0 // End Collection | ||
| 655 | }}; | ||
| 656 | |||
| 657 | static bool udi_hid_raw_setreport(void); | ||
| 658 | static void udi_hid_raw_setreport_valid(void); | ||
| 659 | |||
| 660 | static void udi_hid_raw_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep); | ||
| 661 | static void udi_hid_raw_report_rcvd(udd_ep_status_t status, iram_size_t nb_rcvd, udd_ep_id_t ep); | ||
| 662 | |||
| 663 | bool udi_hid_raw_enable(void) { | ||
| 664 | // Initialize internal values | ||
| 665 | udi_hid_raw_rate = 0; | ||
| 666 | udi_hid_raw_protocol = 0; | ||
| 667 | udi_hid_raw_b_report_trans_ongoing = false; | ||
| 668 | memset(udi_hid_raw_report, 0, UDI_HID_RAW_REPORT_SIZE); | ||
| 669 | udi_hid_raw_b_report_valid = false; | ||
| 670 | return UDI_HID_RAW_ENABLE_EXT(); | ||
| 671 | } | ||
| 672 | |||
| 673 | void udi_hid_raw_disable(void) { UDI_HID_RAW_DISABLE_EXT(); } | ||
| 674 | |||
| 675 | 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); } | ||
| 676 | |||
| 677 | uint8_t udi_hid_raw_getsetting(void) { return 0; } | ||
| 678 | |||
| 679 | static bool udi_hid_raw_setreport(void) { | ||
| 680 | 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)) { | ||
| 681 | // Report OUT type on report ID 0 from USB Host | ||
| 682 | udd_g_ctrlreq.payload = udi_hid_raw_report_set; | ||
| 683 | udd_g_ctrlreq.callback = udi_hid_raw_setreport_valid; // must call routine to transform setreport to LED state | ||
| 684 | udd_g_ctrlreq.payload_size = UDI_HID_RAW_REPORT_SIZE; | ||
| 685 | return true; | ||
| 686 | } | ||
| 687 | return false; | ||
| 688 | } | ||
| 689 | |||
| 690 | bool udi_hid_raw_send_report(void) { | ||
| 691 | if (!main_b_raw_enable) { | ||
| 692 | return false; | ||
| 693 | } | ||
| 694 | |||
| 695 | if (udi_hid_raw_b_report_trans_ongoing) { | ||
| 696 | return false; | ||
| 697 | } | ||
| 698 | |||
| 699 | memcpy(udi_hid_raw_report_trans, udi_hid_raw_report, UDI_HID_RAW_REPORT_SIZE); | ||
| 700 | udi_hid_raw_b_report_valid = false; | ||
| 701 | 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); | ||
| 702 | |||
| 703 | return udi_hid_raw_b_report_trans_ongoing; | ||
| 704 | } | ||
| 705 | |||
| 706 | static void udi_hid_raw_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep) { | ||
| 707 | UNUSED(status); | ||
| 708 | UNUSED(nb_sent); | ||
| 709 | UNUSED(ep); | ||
| 710 | udi_hid_raw_b_report_trans_ongoing = false; | ||
| 711 | if (udi_hid_raw_b_report_valid) { | ||
| 712 | udi_hid_raw_send_report(); | ||
| 713 | } | ||
| 714 | } | ||
| 715 | |||
| 716 | static void udi_hid_raw_setreport_valid(void) {} | ||
| 717 | |||
| 718 | void raw_hid_send(uint8_t *data, uint8_t length) { | ||
| 719 | if (main_b_raw_enable && !udi_hid_raw_b_report_trans_ongoing && length == UDI_HID_RAW_REPORT_SIZE) { | ||
| 720 | memcpy(udi_hid_raw_report, data, UDI_HID_RAW_REPORT_SIZE); | ||
| 721 | udi_hid_raw_send_report(); | ||
| 722 | } | ||
| 723 | } | ||
| 724 | |||
| 725 | bool udi_hid_raw_receive_report(void) { | ||
| 726 | if (!main_b_raw_enable) { | ||
| 727 | return false; | ||
| 728 | } | ||
| 729 | |||
| 730 | 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); | ||
| 731 | } | ||
| 732 | |||
| 733 | static void udi_hid_raw_report_rcvd(udd_ep_status_t status, iram_size_t nb_rcvd, udd_ep_id_t ep) { | ||
| 734 | UNUSED(ep); | ||
| 735 | |||
| 736 | if (status == UDD_EP_TRANSFER_OK && nb_rcvd == UDI_HID_RAW_REPORT_SIZE) { | ||
| 737 | UDI_HID_RAW_RECEIVE(udi_hid_raw_report_recv, UDI_HID_RAW_REPORT_SIZE); | ||
| 738 | } | ||
| 739 | } | ||
| 740 | |||
| 741 | #endif // RAW_ENABLE | ||
| 742 | |||
| 743 | //******************************************************************************************** | ||
| 744 | // CON | ||
| 745 | //******************************************************************************************** | ||
| 746 | #ifdef CONSOLE_ENABLE | ||
| 747 | |||
| 748 | bool udi_hid_con_enable(void); | ||
| 749 | void udi_hid_con_disable(void); | ||
| 750 | bool udi_hid_con_setup(void); | ||
| 751 | uint8_t udi_hid_con_getsetting(void); | ||
| 752 | |||
| 753 | UDC_DESC_STORAGE udi_api_t udi_api_hid_con = { | ||
| 754 | .enable = (bool (*)(void))udi_hid_con_enable, | ||
| 755 | .disable = (void (*)(void))udi_hid_con_disable, | ||
| 756 | .setup = (bool (*)(void))udi_hid_con_setup, | ||
| 757 | .getsetting = (uint8_t(*)(void))udi_hid_con_getsetting, | ||
| 758 | .sof_notify = NULL, | ||
| 759 | }; | ||
| 760 | |||
| 761 | COMPILER_WORD_ALIGNED | ||
| 762 | static uint8_t udi_hid_con_rate; | ||
| 763 | |||
| 764 | COMPILER_WORD_ALIGNED | ||
| 765 | static uint8_t udi_hid_con_protocol; | ||
| 766 | |||
| 767 | COMPILER_WORD_ALIGNED | ||
| 768 | uint8_t udi_hid_con_report_set[UDI_HID_CON_REPORT_SIZE]; | ||
| 769 | |||
| 770 | bool udi_hid_con_b_report_valid; | ||
| 771 | |||
| 772 | COMPILER_WORD_ALIGNED | ||
| 773 | uint8_t udi_hid_con_report[UDI_HID_CON_REPORT_SIZE]; | ||
| 774 | |||
| 775 | volatile bool udi_hid_con_b_report_trans_ongoing; | ||
| 776 | |||
| 777 | COMPILER_WORD_ALIGNED | ||
| 778 | static uint8_t udi_hid_con_report_trans[UDI_HID_CON_REPORT_SIZE]; | ||
| 779 | |||
| 780 | COMPILER_WORD_ALIGNED | ||
| 781 | UDC_DESC_STORAGE udi_hid_con_report_desc_t udi_hid_con_report_desc = {{ | ||
| 782 | 0x06, 0x31, 0xFF, // Usage Page (Vendor Defined - PJRC Teensy compatible) | ||
| 783 | 0x09, 0x74, // Usage (Vendor Defined - PJRC Teensy compatible) | ||
| 784 | 0xA1, 0x01, // Collection (Application) | ||
| 785 | // Data to host | ||
| 786 | 0x09, 0x75, // Usage (Vendor Defined) | ||
| 787 | 0x15, 0x00, // Logical Minimum (0x00) | ||
| 788 | 0x26, 0xFF, 0x00, // Logical Maximum (0x00FF) | ||
| 789 | 0x95, CONSOLE_EPSIZE, // Report Count | ||
| 790 | 0x75, 0x08, // Report Size (8) | ||
| 791 | 0x81, 0x02, // Input (Data, Variable, Absolute) | ||
| 792 | // Data from host | ||
| 793 | 0x09, 0x76, // Usage (Vendor Defined) | ||
| 794 | 0x15, 0x00, // Logical Minimum (0x00) | ||
| 795 | 0x26, 0xFF, 0x00, // Logical Maximum (0x00FF) | ||
| 796 | 0x95, CONSOLE_EPSIZE, // Report Count | ||
| 797 | 0x75, 0x08, // Report Size (8) | ||
| 798 | 0x91, 0x02, // Output (Data) | ||
| 799 | 0xC0 // End Collection | ||
| 800 | }}; | ||
| 801 | |||
| 802 | static bool udi_hid_con_setreport(void); | ||
| 803 | static void udi_hid_con_setreport_valid(void); | ||
| 804 | |||
| 805 | static void udi_hid_con_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep); | ||
| 806 | |||
| 807 | bool udi_hid_con_enable(void) { | ||
| 808 | // Initialize internal values | ||
| 809 | udi_hid_con_rate = 0; | ||
| 810 | udi_hid_con_protocol = 0; | ||
| 811 | udi_hid_con_b_report_trans_ongoing = false; | ||
| 812 | memset(udi_hid_con_report, 0, UDI_HID_CON_REPORT_SIZE); | ||
| 813 | udi_hid_con_b_report_valid = false; | ||
| 814 | return UDI_HID_CON_ENABLE_EXT(); | ||
| 815 | } | ||
| 816 | |||
| 817 | void udi_hid_con_disable(void) { UDI_HID_CON_DISABLE_EXT(); } | ||
| 818 | |||
| 819 | 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); } | ||
| 820 | |||
| 821 | uint8_t udi_hid_con_getsetting(void) { return 0; } | ||
| 822 | |||
| 823 | static bool udi_hid_con_setreport(void) { | ||
| 824 | 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)) { | ||
| 825 | udd_g_ctrlreq.payload = udi_hid_con_report_set; | ||
| 826 | udd_g_ctrlreq.callback = udi_hid_con_setreport_valid; | ||
| 827 | udd_g_ctrlreq.payload_size = UDI_HID_CON_REPORT_SIZE; | ||
| 828 | return true; | ||
| 829 | } | ||
| 830 | return false; | ||
| 831 | } | ||
| 832 | |||
| 833 | bool udi_hid_con_send_report(void) { | ||
| 834 | if (!main_b_con_enable) { | ||
| 835 | return false; | ||
| 836 | } | ||
| 837 | |||
| 838 | if (udi_hid_con_b_report_trans_ongoing) { | ||
| 839 | return false; | ||
| 840 | } | ||
| 841 | |||
| 842 | memcpy(udi_hid_con_report_trans, udi_hid_con_report, UDI_HID_CON_REPORT_SIZE); | ||
| 843 | udi_hid_con_b_report_valid = false; | ||
| 844 | 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); | ||
| 845 | |||
| 846 | return udi_hid_con_b_report_trans_ongoing; | ||
| 847 | } | ||
| 848 | |||
| 849 | static void udi_hid_con_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep) { | ||
| 850 | UNUSED(status); | ||
| 851 | UNUSED(nb_sent); | ||
| 852 | UNUSED(ep); | ||
| 853 | udi_hid_con_b_report_trans_ongoing = false; | ||
| 854 | if (udi_hid_con_b_report_valid) { | ||
| 855 | udi_hid_con_send_report(); | ||
| 856 | } | ||
| 857 | } | ||
| 858 | |||
| 859 | static void udi_hid_con_setreport_valid(void) {} | ||
| 860 | |||
| 861 | #endif // CONSOLE_ENABLE | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.h b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.h deleted file mode 100644 index e17538fa70..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.h +++ /dev/null | |||
| @@ -1,120 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief USB Device Human Interface Device (HID) keyboard interface. | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #ifndef _UDC_HID_KBD_H_ | ||
| 48 | #define _UDC_HID_KBD_H_ | ||
| 49 | |||
| 50 | #include "udc_desc.h" | ||
| 51 | #include "udi.h" | ||
| 52 | |||
| 53 | #ifdef __cplusplus | ||
| 54 | extern "C" { | ||
| 55 | #endif | ||
| 56 | |||
| 57 | //****************************************************************************** | ||
| 58 | // Keyboard interface definitions | ||
| 59 | //****************************************************************************** | ||
| 60 | extern UDC_DESC_STORAGE udi_api_t udi_api_hid_kbd; | ||
| 61 | extern bool udi_hid_kbd_b_report_valid; | ||
| 62 | extern volatile bool udi_hid_kbd_b_report_trans_ongoing; | ||
| 63 | extern uint8_t udi_hid_kbd_report_set; | ||
| 64 | bool udi_hid_kbd_send_report(void); | ||
| 65 | |||
| 66 | //******************************************************************************************** | ||
| 67 | // NKRO Keyboard | ||
| 68 | //******************************************************************************************** | ||
| 69 | #ifdef NKRO_ENABLE | ||
| 70 | extern UDC_DESC_STORAGE udi_api_t udi_api_hid_nkro; | ||
| 71 | extern bool udi_hid_nkro_b_report_valid; | ||
| 72 | extern volatile bool udi_hid_nkro_b_report_trans_ongoing; | ||
| 73 | bool udi_hid_nkro_send_report(void); | ||
| 74 | #endif // NKRO_ENABLE | ||
| 75 | |||
| 76 | //******************************************************************************************** | ||
| 77 | // SYS-CTRL interface | ||
| 78 | //******************************************************************************************** | ||
| 79 | #ifdef EXTRAKEY_ENABLE | ||
| 80 | extern UDC_DESC_STORAGE udi_api_t udi_api_hid_exk; | ||
| 81 | extern bool udi_hid_exk_b_report_valid; | ||
| 82 | bool udi_hid_exk_send_report(void); | ||
| 83 | #endif // EXTRAKEY_ENABLE | ||
| 84 | |||
| 85 | //******************************************************************************************** | ||
| 86 | // CON Console | ||
| 87 | //******************************************************************************************** | ||
| 88 | #ifdef CONSOLE_ENABLE | ||
| 89 | extern UDC_DESC_STORAGE udi_api_t udi_api_hid_con; | ||
| 90 | extern bool udi_hid_con_b_report_valid; | ||
| 91 | extern uint8_t udi_hid_con_report_set[UDI_HID_CON_REPORT_SIZE]; | ||
| 92 | extern volatile bool udi_hid_con_b_report_trans_ongoing; | ||
| 93 | bool udi_hid_con_send_report(void); | ||
| 94 | #endif // CONSOLE_ENABLE | ||
| 95 | |||
| 96 | //******************************************************************************************** | ||
| 97 | // MOU Mouse | ||
| 98 | //******************************************************************************************** | ||
| 99 | #ifdef MOUSE_ENABLE | ||
| 100 | extern UDC_DESC_STORAGE udi_api_t udi_api_hid_mou; | ||
| 101 | extern bool udi_hid_mou_b_report_valid; | ||
| 102 | bool udi_hid_mou_send_report(void); | ||
| 103 | #endif // MOUSE_ENABLE | ||
| 104 | |||
| 105 | //******************************************************************************************** | ||
| 106 | // RAW Raw | ||
| 107 | //******************************************************************************************** | ||
| 108 | #ifdef RAW_ENABLE | ||
| 109 | extern UDC_DESC_STORAGE udi_api_t udi_api_hid_raw; | ||
| 110 | bool udi_hid_raw_send_report(void); | ||
| 111 | bool udi_hid_raw_receive_report(void); | ||
| 112 | #endif // RAW_ENABLE | ||
| 113 | |||
| 114 | //@} | ||
| 115 | |||
| 116 | #ifdef __cplusplus | ||
| 117 | } | ||
| 118 | #endif | ||
| 119 | |||
| 120 | #endif // _UDC_HID_KBD_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd_conf.h b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd_conf.h deleted file mode 100644 index db5db17ed5..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd_conf.h +++ /dev/null | |||
| @@ -1,60 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief Default HID keyboard configuration for a USB Device | ||
| 5 | * with a single interface HID keyboard | ||
| 6 | * | ||
| 7 | * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. | ||
| 8 | * | ||
| 9 | * \asf_license_start | ||
| 10 | * | ||
| 11 | * \page License | ||
| 12 | * | ||
| 13 | * Redistribution and use in source and binary forms, with or without | ||
| 14 | * modification, are permitted provided that the following conditions are met: | ||
| 15 | * | ||
| 16 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 17 | * this list of conditions and the following disclaimer. | ||
| 18 | * | ||
| 19 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 20 | * this list of conditions and the following disclaimer in the documentation | ||
| 21 | * and/or other materials provided with the distribution. | ||
| 22 | * | ||
| 23 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 24 | * from this software without specific prior written permission. | ||
| 25 | * | ||
| 26 | * 4. This software may only be redistributed and used in connection with an | ||
| 27 | * Atmel microcontroller product. | ||
| 28 | * | ||
| 29 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 30 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 31 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 32 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 33 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 34 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 35 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 36 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 37 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 38 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 39 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 40 | * | ||
| 41 | * \asf_license_stop | ||
| 42 | * | ||
| 43 | */ | ||
| 44 | /* | ||
| 45 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 46 | */ | ||
| 47 | |||
| 48 | #ifndef _UDI_HID_KBD_CONF_H_ | ||
| 49 | #define _UDI_HID_KBD_CONF_H_ | ||
| 50 | |||
| 51 | /** | ||
| 52 | * \addtogroup udi_hid_keyboard_group_single_desc | ||
| 53 | * @{ | ||
| 54 | */ | ||
| 55 | |||
| 56 | #include "udi_device_conf.h" | ||
| 57 | |||
| 58 | #include "udi_hid_kbd.h" | ||
| 59 | |||
| 60 | #endif // _UDI_HID_KBD_CONF_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd_desc.c b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd_desc.c deleted file mode 100644 index 2a60868ed2..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd_desc.c +++ /dev/null | |||
| @@ -1,179 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief Default descriptors for a USB Device | ||
| 5 | * with a single interface HID keyboard | ||
| 6 | * | ||
| 7 | * Copyright (c) 2009-2016 Atmel Corporation. All rights reserved. | ||
| 8 | * | ||
| 9 | * \asf_license_start | ||
| 10 | * | ||
| 11 | * \page License | ||
| 12 | * | ||
| 13 | * Redistribution and use in source and binary forms, with or without | ||
| 14 | * modification, are permitted provided that the following conditions are met: | ||
| 15 | * | ||
| 16 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 17 | * this list of conditions and the following disclaimer. | ||
| 18 | * | ||
| 19 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 20 | * this list of conditions and the following disclaimer in the documentation | ||
| 21 | * and/or other materials provided with the distribution. | ||
| 22 | * | ||
| 23 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 24 | * from this software without specific prior written permission. | ||
| 25 | * | ||
| 26 | * 4. This software may only be redistributed and used in connection with an | ||
| 27 | * Atmel microcontroller product. | ||
| 28 | * | ||
| 29 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 30 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 31 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 32 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 33 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 34 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 35 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 36 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 37 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 38 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 39 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 40 | * | ||
| 41 | * \asf_license_stop | ||
| 42 | * | ||
| 43 | */ | ||
| 44 | /* | ||
| 45 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 46 | */ | ||
| 47 | |||
| 48 | #include "conf_usb.h" | ||
| 49 | #include "usb_protocol.h" | ||
| 50 | #include "udc_desc.h" | ||
| 51 | #include "udi_device_conf.h" | ||
| 52 | #include "udi_hid_kbd.h" | ||
| 53 | #include "udi_cdc.h" | ||
| 54 | |||
| 55 | /** | ||
| 56 | * \ingroup udi_hid_keyboard_group | ||
| 57 | * \defgroup udi_hid_keyboard_group_single_desc USB device descriptors for a single interface | ||
| 58 | * | ||
| 59 | * The following structures provide the USB device descriptors required | ||
| 60 | * for USB Device with a single interface HID keyboard. | ||
| 61 | * | ||
| 62 | * It is ready to use and do not require more definition. | ||
| 63 | * @{ | ||
| 64 | */ | ||
| 65 | |||
| 66 | //! USB Device Descriptor | ||
| 67 | COMPILER_WORD_ALIGNED | ||
| 68 | UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = {.bLength = sizeof(usb_dev_desc_t), | ||
| 69 | .bDescriptorType = USB_DT_DEVICE, | ||
| 70 | .bcdUSB = LE16(USB_V2_0), | ||
| 71 | .bDeviceClass = DEVICE_CLASS, | ||
| 72 | .bDeviceSubClass = DEVICE_SUBCLASS, | ||
| 73 | .bDeviceProtocol = DEVICE_PROTOCOL, | ||
| 74 | .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, | ||
| 75 | .idVendor = LE16(USB_DEVICE_VENDOR_ID), | ||
| 76 | .idProduct = LE16(USB_DEVICE_PRODUCT_ID), | ||
| 77 | .bcdDevice = LE16(USB_DEVICE_VERSION), | ||
| 78 | #ifdef USB_DEVICE_MANUFACTURE_NAME | ||
| 79 | .iManufacturer = 1, | ||
| 80 | #else | ||
| 81 | .iManufacturer = 0, // No manufacture string | ||
| 82 | #endif | ||
| 83 | #ifdef USB_DEVICE_PRODUCT_NAME | ||
| 84 | .iProduct = 2, | ||
| 85 | #else | ||
| 86 | .iProduct = 0, // No product string | ||
| 87 | #endif | ||
| 88 | #if (defined USB_DEVICE_SERIAL_NAME || defined USB_DEVICE_GET_SERIAL_NAME_POINTER) | ||
| 89 | .iSerialNumber = 3, | ||
| 90 | #else | ||
| 91 | .iSerialNumber = 0, // No serial string | ||
| 92 | #endif | ||
| 93 | .bNumConfigurations = 1}; | ||
| 94 | |||
| 95 | #if 0 | ||
| 96 | # ifdef USB_DEVICE_HS_SUPPORT | ||
| 97 | //! USB Device Qualifier Descriptor for HS | ||
| 98 | COMPILER_WORD_ALIGNED | ||
| 99 | UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = { | ||
| 100 | .bLength = sizeof(usb_dev_qual_desc_t), | ||
| 101 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, | ||
| 102 | .bcdUSB = LE16(USB_V2_0), | ||
| 103 | .bDeviceClass = 0, | ||
| 104 | .bDeviceSubClass = 0, | ||
| 105 | .bDeviceProtocol = 0, | ||
| 106 | .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, | ||
| 107 | .bNumConfigurations = 1 | ||
| 108 | }; | ||
| 109 | # endif | ||
| 110 | #endif | ||
| 111 | |||
| 112 | //! USB Device Configuration Descriptor filled for FS and HS | ||
| 113 | COMPILER_WORD_ALIGNED | ||
| 114 | UDC_DESC_STORAGE udc_desc_t udc_desc = { | ||
| 115 | .conf.bLength = sizeof(usb_conf_desc_t), | ||
| 116 | .conf.bDescriptorType = USB_DT_CONFIGURATION, | ||
| 117 | .conf.wTotalLength = LE16(sizeof(udc_desc_t)), | ||
| 118 | .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, | ||
| 119 | .conf.bConfigurationValue = 1, | ||
| 120 | .conf.iConfiguration = 0, | ||
| 121 | .conf.bmAttributes = /* USB_CONFIG_ATTR_MUST_SET | */ USB_DEVICE_ATTR, | ||
| 122 | .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), | ||
| 123 | .hid_kbd = UDI_HID_KBD_DESC, | ||
| 124 | #ifdef RAW_ENABLE | ||
| 125 | .hid_raw = UDI_HID_RAW_DESC, | ||
| 126 | #endif | ||
| 127 | #ifdef MOUSE_ENABLE | ||
| 128 | .hid_mou = UDI_HID_MOU_DESC, | ||
| 129 | #endif | ||
| 130 | #ifdef EXTRAKEY_ENABLE | ||
| 131 | .hid_exk = UDI_HID_EXK_DESC, | ||
| 132 | #endif | ||
| 133 | #ifdef CONSOLE_ENABLE | ||
| 134 | .hid_con = UDI_HID_CON_DESC, | ||
| 135 | #endif | ||
| 136 | #ifdef NKRO_ENABLE | ||
| 137 | .hid_nkro = UDI_HID_NKRO_DESC, | ||
| 138 | #endif | ||
| 139 | #ifdef VIRTSER_ENABLE | ||
| 140 | .cdc_serial = CDC_DESCRIPTOR, | ||
| 141 | #endif | ||
| 142 | }; | ||
| 143 | |||
| 144 | UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = { | ||
| 145 | &udi_api_hid_kbd, | ||
| 146 | #ifdef RAW_ENABLE | ||
| 147 | &udi_api_hid_raw, | ||
| 148 | #endif | ||
| 149 | #ifdef MOUSE_ENABLE | ||
| 150 | &udi_api_hid_mou, | ||
| 151 | #endif | ||
| 152 | #ifdef EXTRAKEY_ENABLE | ||
| 153 | &udi_api_hid_exk, | ||
| 154 | #endif | ||
| 155 | #ifdef CONSOLE_ENABLE | ||
| 156 | &udi_api_hid_con, | ||
| 157 | #endif | ||
| 158 | #ifdef NKRO_ENABLE | ||
| 159 | &udi_api_hid_nkro, | ||
| 160 | #endif | ||
| 161 | #ifdef VIRTSER_ENABLE | ||
| 162 | &udi_api_cdc_comm, &udi_api_cdc_data, | ||
| 163 | #endif | ||
| 164 | }; | ||
| 165 | |||
| 166 | //! Add UDI with USB Descriptors FS & HS | ||
| 167 | UDC_DESC_STORAGE udc_config_speed_t udc_config_fshs[1] = {{ | ||
| 168 | .desc = (usb_conf_desc_t UDC_DESC_STORAGE *)&udc_desc, | ||
| 169 | .udi_apis = udi_apis, | ||
| 170 | }}; | ||
| 171 | |||
| 172 | //! Add all information about USB Device in global structure for UDC | ||
| 173 | UDC_DESC_STORAGE udc_config_t udc_config = { | ||
| 174 | .confdev_lsfs = &udc_device_desc, | ||
| 175 | .conf_lsfs = udc_config_fshs, | ||
| 176 | }; | ||
| 177 | |||
| 178 | //@} | ||
| 179 | //@} | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/ui.c b/tmk_core/protocol/arm_atsam/usb/ui.c deleted file mode 100644 index f5263d7289..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/ui.c +++ /dev/null | |||
| @@ -1,83 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief User Interface | ||
| 5 | * | ||
| 6 | * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #ifndef ARM_MATH_CM4 | ||
| 48 | # define ARM_MATH_CM4 | ||
| 49 | #endif | ||
| 50 | |||
| 51 | #undef LITTLE_ENDIAN // redefined in samd51j18a.h | ||
| 52 | #include "samd51j18a.h" | ||
| 53 | #include "ui.h" | ||
| 54 | |||
| 55 | //! Sequence process running each \c SEQUENCE_PERIOD ms | ||
| 56 | #define SEQUENCE_PERIOD 150 | ||
| 57 | |||
| 58 | #if 0 | ||
| 59 | /* Interrupt on "pin change" from push button to do wakeup on USB | ||
| 60 | * Note: | ||
| 61 | * This interrupt is enable when the USB host enable remote wakeup feature | ||
| 62 | * This interrupt wakeup the CPU if this one is in idle mode | ||
| 63 | */ | ||
| 64 | static void ui_wakeup_handler(void) | ||
| 65 | { | ||
| 66 | /* It is a wakeup then send wakeup USB */ | ||
| 67 | udc_remotewakeup(); | ||
| 68 | } | ||
| 69 | #endif | ||
| 70 | |||
| 71 | void ui_init(void) {} | ||
| 72 | |||
| 73 | void ui_powerdown(void) {} | ||
| 74 | |||
| 75 | void ui_wakeup_enable(void) {} | ||
| 76 | |||
| 77 | void ui_wakeup_disable(void) {} | ||
| 78 | |||
| 79 | void ui_wakeup(void) {} | ||
| 80 | |||
| 81 | void ui_process(uint16_t framenumber) {} | ||
| 82 | |||
| 83 | void ui_kbd_led(uint8_t value) {} | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/ui.h b/tmk_core/protocol/arm_atsam/usb/ui.h deleted file mode 100644 index d1c767d457..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/ui.h +++ /dev/null | |||
| @@ -1,76 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief Common User Interface for HID Keyboard application | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #ifndef _UI_H_ | ||
| 48 | #define _UI_H_ | ||
| 49 | |||
| 50 | //! \brief Initializes the user interface | ||
| 51 | void ui_init(void); | ||
| 52 | |||
| 53 | //! \brief Enters the user interface in power down mode | ||
| 54 | void ui_powerdown(void); | ||
| 55 | |||
| 56 | //! \brief Enables the asynchronous interrupts of the user interface | ||
| 57 | void ui_wakeup_enable(void); | ||
| 58 | |||
| 59 | //! \brief Disables the asynchronous interrupts of the user interface | ||
| 60 | void ui_wakeup_disable(void); | ||
| 61 | |||
| 62 | //! \brief Exits the user interface of power down mode | ||
| 63 | void ui_wakeup(void); | ||
| 64 | |||
| 65 | /*! \brief This process is called each 1ms | ||
| 66 | * It is called only if the USB interface is enabled. | ||
| 67 | * | ||
| 68 | * \param framenumber Current frame number | ||
| 69 | */ | ||
| 70 | void ui_process(uint16_t framenumber); | ||
| 71 | |||
| 72 | /*! \brief Turn on or off the keyboard LEDs | ||
| 73 | */ | ||
| 74 | void ui_kbd_led(uint8_t value); | ||
| 75 | |||
| 76 | #endif // _UI_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/usb.c b/tmk_core/protocol/arm_atsam/usb/usb.c deleted file mode 100644 index 1abf0a2f4d..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/usb.c +++ /dev/null | |||
| @@ -1,1083 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief SAM USB Driver. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2014-2016 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #define DEVICE_MODE_ONLY true | ||
| 48 | #define SAMD11 DEVICE_MODE_ONLY | ||
| 49 | |||
| 50 | #ifndef ARM_MATH_CM4 | ||
| 51 | # define ARM_MATH_CM4 | ||
| 52 | #endif | ||
| 53 | |||
| 54 | #include "compiler.h" | ||
| 55 | #undef LITTLE_ENDIAN // redefined in samd51j18a.h | ||
| 56 | #include "samd51j18a.h" | ||
| 57 | #include <stdbool.h> | ||
| 58 | #include <string.h> | ||
| 59 | #include "arm_math.h" | ||
| 60 | #include "status_codes.h" | ||
| 61 | #include "usb.h" | ||
| 62 | |||
| 63 | /** Fields definition from a LPM TOKEN */ | ||
| 64 | #define USB_LPM_ATTRIBUT_BLINKSTATE_MASK (0xF << 0) | ||
| 65 | #define USB_LPM_ATTRIBUT_HIRD_MASK (0xF << 4) | ||
| 66 | #define USB_LPM_ATTRIBUT_REMOTEWAKE_MASK (1 << 8) | ||
| 67 | #define USB_LPM_ATTRIBUT_BLINKSTATE(value) ((value & 0xF) << 0) | ||
| 68 | #define USB_LPM_ATTRIBUT_HIRD(value) ((value & 0xF) << 4) | ||
| 69 | #define USB_LPM_ATTRIBUT_REMOTEWAKE(value) ((value & 1) << 8) | ||
| 70 | #define USB_LPM_ATTRIBUT_BLINKSTATE_L1 USB_LPM_ATTRIBUT_BLINKSTATE(1) | ||
| 71 | |||
| 72 | /** | ||
| 73 | * \brief Mask selecting the index part of an endpoint address | ||
| 74 | */ | ||
| 75 | #define USB_EP_ADDR_MASK 0x0f | ||
| 76 | |||
| 77 | /** | ||
| 78 | * \brief Endpoint transfer direction is IN | ||
| 79 | */ | ||
| 80 | #define USB_EP_DIR_IN 0x80 | ||
| 81 | |||
| 82 | /** | ||
| 83 | * \brief Endpoint transfer direction is OUT | ||
| 84 | */ | ||
| 85 | #define USB_EP_DIR_OUT 0x00 | ||
| 86 | |||
| 87 | /** | ||
| 88 | * \name USB SRAM data containing pipe descriptor table | ||
| 89 | * The content of the USB SRAM can be : | ||
| 90 | * - modified by USB hardware interface to update pipe status. | ||
| 91 | * Thereby, it is read by software. | ||
| 92 | * - modified by USB software to control pipe. | ||
| 93 | * Thereby, it is read by hardware. | ||
| 94 | * This data section is volatile. | ||
| 95 | * | ||
| 96 | * @{ | ||
| 97 | */ | ||
| 98 | COMPILER_PACK_SET(1) | ||
| 99 | COMPILER_WORD_ALIGNED | ||
| 100 | union { | ||
| 101 | UsbDeviceDescriptor usb_endpoint_table[USB_EPT_NUM]; | ||
| 102 | } usb_descriptor_table; | ||
| 103 | COMPILER_PACK_RESET() | ||
| 104 | /** @} */ | ||
| 105 | |||
| 106 | /** | ||
| 107 | * \brief Local USB module instance | ||
| 108 | */ | ||
| 109 | static struct usb_module *_usb_instances; | ||
| 110 | |||
| 111 | /* Device LPM callback variable */ | ||
| 112 | static uint32_t device_callback_lpm_wakeup_enable; | ||
| 113 | |||
| 114 | /** | ||
| 115 | * \brief Device endpoint callback parameter variable, used to transfer info to UDD wrapper layer | ||
| 116 | */ | ||
| 117 | static struct usb_endpoint_callback_parameter ep_callback_para; | ||
| 118 | |||
| 119 | /** | ||
| 120 | * \internal USB Device IRQ Mask Bits Map | ||
| 121 | */ | ||
| 122 | static const uint16_t _usb_device_irq_bits[USB_DEVICE_CALLBACK_N] = { | ||
| 123 | USB_DEVICE_INTFLAG_SOF, USB_DEVICE_INTFLAG_EORST, USB_DEVICE_INTFLAG_WAKEUP | USB_DEVICE_INTFLAG_EORSM | USB_DEVICE_INTFLAG_UPRSM, USB_DEVICE_INTFLAG_RAMACER, USB_DEVICE_INTFLAG_SUSPEND, USB_DEVICE_INTFLAG_LPMNYET, USB_DEVICE_INTFLAG_LPMSUSP, | ||
| 124 | }; | ||
| 125 | |||
| 126 | /** | ||
| 127 | * \internal USB Device IRQ Mask Bits Map | ||
| 128 | */ | ||
| 129 | static const uint8_t _usb_endpoint_irq_bits[USB_DEVICE_EP_CALLBACK_N] = {USB_DEVICE_EPINTFLAG_TRCPT_Msk, USB_DEVICE_EPINTFLAG_TRFAIL_Msk, USB_DEVICE_EPINTFLAG_RXSTP, USB_DEVICE_EPINTFLAG_STALL_Msk}; | ||
| 130 | |||
| 131 | /** | ||
| 132 | * \brief Registers a USB device callback | ||
| 133 | * | ||
| 134 | * Registers a callback function which is implemented by the user. | ||
| 135 | * | ||
| 136 | * \note The callback must be enabled by \ref usb_device_enable_callback, | ||
| 137 | * in order for the interrupt handler to call it when the conditions for the | ||
| 138 | * callback type is met. | ||
| 139 | * | ||
| 140 | * \param[in] module_inst Pointer to USB software instance struct | ||
| 141 | * \param[in] callback_type Callback type given by an enum | ||
| 142 | * \param[in] callback_func Pointer to callback function | ||
| 143 | * | ||
| 144 | * \return Status of the registration operation. | ||
| 145 | * \retval STATUS_OK The callback was registered successfully. | ||
| 146 | */ | ||
| 147 | enum status_code usb_device_register_callback(struct usb_module *module_inst, enum usb_device_callback callback_type, usb_device_callback_t callback_func) { | ||
| 148 | /* Sanity check arguments */ | ||
| 149 | Assert(module_inst); | ||
| 150 | Assert(callback_func); | ||
| 151 | |||
| 152 | /* Register callback function */ | ||
| 153 | module_inst->device_callback[callback_type] = callback_func; | ||
| 154 | |||
| 155 | /* Set the bit corresponding to the callback_type */ | ||
| 156 | module_inst->device_registered_callback_mask |= _usb_device_irq_bits[callback_type]; | ||
| 157 | |||
| 158 | return STATUS_OK; | ||
| 159 | } | ||
| 160 | |||
| 161 | /** | ||
| 162 | * \brief Unregisters a USB device callback | ||
| 163 | * | ||
| 164 | * Unregisters an asynchronous callback implemented by the user. Removing it | ||
| 165 | * from the internal callback registration table. | ||
| 166 | * | ||
| 167 | * \param[in] module_inst Pointer to USB software instance struct | ||
| 168 | * \param[in] callback_type Callback type given by an enum | ||
| 169 | * | ||
| 170 | * \return Status of the de-registration operation. | ||
| 171 | * \retval STATUS_OK The callback was unregistered successfully. | ||
| 172 | */ | ||
| 173 | enum status_code usb_device_unregister_callback(struct usb_module *module_inst, enum usb_device_callback callback_type) { | ||
| 174 | /* Sanity check arguments */ | ||
| 175 | Assert(module_inst); | ||
| 176 | |||
| 177 | /* Unregister callback function */ | ||
| 178 | module_inst->device_callback[callback_type] = NULL; | ||
| 179 | |||
| 180 | /* Clear the bit corresponding to the callback_type */ | ||
| 181 | module_inst->device_registered_callback_mask &= ~_usb_device_irq_bits[callback_type]; | ||
| 182 | |||
| 183 | return STATUS_OK; | ||
| 184 | } | ||
| 185 | |||
| 186 | /** | ||
| 187 | * \brief Enables USB device callback generation for a given type. | ||
| 188 | * | ||
| 189 | * Enables asynchronous callbacks for a given logical type. | ||
| 190 | * This must be called before USB device generate callback events. | ||
| 191 | * | ||
| 192 | * \param[in] module_inst Pointer to USB software instance struct | ||
| 193 | * \param[in] callback_type Callback type given by an enum | ||
| 194 | * | ||
| 195 | * \return Status of the callback enable operation. | ||
| 196 | * \retval STATUS_OK The callback was enabled successfully. | ||
| 197 | */ | ||
| 198 | enum status_code usb_device_enable_callback(struct usb_module *module_inst, enum usb_device_callback callback_type) { | ||
| 199 | /* Sanity check arguments */ | ||
| 200 | Assert(module_inst); | ||
| 201 | Assert(module_inst->hw); | ||
| 202 | |||
| 203 | /* clear related flag */ | ||
| 204 | module_inst->hw->DEVICE.INTFLAG.reg = _usb_device_irq_bits[callback_type]; | ||
| 205 | |||
| 206 | /* Enable callback */ | ||
| 207 | module_inst->device_enabled_callback_mask |= _usb_device_irq_bits[callback_type]; | ||
| 208 | |||
| 209 | module_inst->hw->DEVICE.INTENSET.reg = _usb_device_irq_bits[callback_type]; | ||
| 210 | |||
| 211 | return STATUS_OK; | ||
| 212 | } | ||
| 213 | |||
| 214 | /** | ||
| 215 | * \brief Disables USB device callback generation for a given type. | ||
| 216 | * | ||
| 217 | * Disables asynchronous callbacks for a given logical type. | ||
| 218 | * | ||
| 219 | * \param[in] module_inst Pointer to USB software instance struct | ||
| 220 | * \param[in] callback_type Callback type given by an enum | ||
| 221 | * | ||
| 222 | * \return Status of the callback disable operation. | ||
| 223 | * \retval STATUS_OK The callback was disabled successfully. | ||
| 224 | */ | ||
| 225 | enum status_code usb_device_disable_callback(struct usb_module *module_inst, enum usb_device_callback callback_type) { | ||
| 226 | /* Sanity check arguments */ | ||
| 227 | Assert(module_inst); | ||
| 228 | Assert(module_inst->hw); | ||
| 229 | |||
| 230 | /* Disable callback */ | ||
| 231 | module_inst->device_enabled_callback_mask &= ~_usb_device_irq_bits[callback_type]; | ||
| 232 | |||
| 233 | module_inst->hw->DEVICE.INTENCLR.reg = _usb_device_irq_bits[callback_type]; | ||
| 234 | |||
| 235 | return STATUS_OK; | ||
| 236 | } | ||
| 237 | |||
| 238 | /** | ||
| 239 | * \brief Registers a USB device endpoint callback | ||
| 240 | * | ||
| 241 | * Registers a callback function which is implemented by the user. | ||
| 242 | * | ||
| 243 | * \note The callback must be enabled by \ref usb_device_endpoint_enable_callback, | ||
| 244 | * in order for the interrupt handler to call it when the conditions for the | ||
| 245 | * callback type is met. | ||
| 246 | * | ||
| 247 | * \param[in] module_inst Pointer to USB software instance struct | ||
| 248 | * \param[in] ep_num Endpoint to configure | ||
| 249 | * \param[in] callback_type Callback type given by an enum | ||
| 250 | * \param[in] callback_func Pointer to callback function | ||
| 251 | * | ||
| 252 | * \return Status of the registration operation. | ||
| 253 | * \retval STATUS_OK The callback was registered successfully. | ||
| 254 | */ | ||
| 255 | 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) { | ||
| 256 | /* Sanity check arguments */ | ||
| 257 | Assert(module_inst); | ||
| 258 | Assert(ep_num < USB_EPT_NUM); | ||
| 259 | Assert(callback_func); | ||
| 260 | |||
| 261 | /* Register callback function */ | ||
| 262 | module_inst->device_endpoint_callback[ep_num][callback_type] = callback_func; | ||
| 263 | |||
| 264 | /* Set the bit corresponding to the callback_type */ | ||
| 265 | module_inst->device_endpoint_registered_callback_mask[ep_num] |= _usb_endpoint_irq_bits[callback_type]; | ||
| 266 | |||
| 267 | return STATUS_OK; | ||
| 268 | } | ||
| 269 | |||
| 270 | /** | ||
| 271 | * \brief Unregisters a USB device endpoint callback | ||
| 272 | * | ||
| 273 | * Unregisters an callback implemented by the user. Removing it | ||
| 274 | * from the internal callback registration table. | ||
| 275 | * | ||
| 276 | * \param[in] module_inst Pointer to USB software instance struct | ||
| 277 | * \param[in] ep_num Endpoint to configure | ||
| 278 | * \param[in] callback_type Callback type given by an enum | ||
| 279 | * | ||
| 280 | * \return Status of the de-registration operation. | ||
| 281 | * \retval STATUS_OK The callback was unregistered successfully. | ||
| 282 | */ | ||
| 283 | enum status_code usb_device_endpoint_unregister_callback(struct usb_module *module_inst, uint8_t ep_num, enum usb_device_endpoint_callback callback_type) { | ||
| 284 | /* Sanity check arguments */ | ||
| 285 | Assert(module_inst); | ||
| 286 | Assert(ep_num < USB_EPT_NUM); | ||
| 287 | |||
| 288 | /* Unregister callback function */ | ||
| 289 | module_inst->device_endpoint_callback[ep_num][callback_type] = NULL; | ||
| 290 | |||
| 291 | /* Clear the bit corresponding to the callback_type */ | ||
| 292 | module_inst->device_endpoint_registered_callback_mask[ep_num] &= ~_usb_endpoint_irq_bits[callback_type]; | ||
| 293 | |||
| 294 | return STATUS_OK; | ||
| 295 | } | ||
| 296 | |||
| 297 | /** | ||
| 298 | * \brief Enables USB device endpoint callback generation for a given type. | ||
| 299 | * | ||
| 300 | * Enables callbacks for a given logical type. | ||
| 301 | * This must be called before USB device pipe generate callback events. | ||
| 302 | * | ||
| 303 | * \param[in] module_inst Pointer to USB software instance struct | ||
| 304 | * \param[in] ep Endpoint to configure | ||
| 305 | * \param[in] callback_type Callback type given by an enum | ||
| 306 | * | ||
| 307 | * \return Status of the callback enable operation. | ||
| 308 | * \retval STATUS_OK The callback was enabled successfully. | ||
| 309 | */ | ||
| 310 | enum status_code usb_device_endpoint_enable_callback(struct usb_module *module_inst, uint8_t ep, enum usb_device_endpoint_callback callback_type) { | ||
| 311 | /* Sanity check arguments */ | ||
| 312 | Assert(module_inst); | ||
| 313 | Assert(module_inst->hw); | ||
| 314 | |||
| 315 | uint8_t ep_num = ep & USB_EP_ADDR_MASK; | ||
| 316 | Assert(ep_num < USB_EPT_NUM); | ||
| 317 | |||
| 318 | /* Enable callback */ | ||
| 319 | module_inst->device_endpoint_enabled_callback_mask[ep_num] |= _usb_endpoint_irq_bits[callback_type]; | ||
| 320 | |||
| 321 | if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_TRCPT) { | ||
| 322 | if (ep_num == 0) { // control endpoint | ||
| 323 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRCPT0 | USB_DEVICE_EPINTENSET_TRCPT1; | ||
| 324 | } else if (ep & USB_EP_DIR_IN) { | ||
| 325 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRCPT1; | ||
| 326 | } else { | ||
| 327 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRCPT0; | ||
| 328 | } | ||
| 329 | } | ||
| 330 | |||
| 331 | if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_TRFAIL) { | ||
| 332 | if (ep_num == 0) { // control endpoint | ||
| 333 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRFAIL0 | USB_DEVICE_EPINTENSET_TRFAIL1; | ||
| 334 | } else if (ep & USB_EP_DIR_IN) { | ||
| 335 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRFAIL1; | ||
| 336 | } else { | ||
| 337 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRFAIL0; | ||
| 338 | } | ||
| 339 | } | ||
| 340 | |||
| 341 | if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_RXSTP) { | ||
| 342 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_RXSTP; | ||
| 343 | } | ||
| 344 | |||
| 345 | if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_STALL) { | ||
| 346 | if (ep & USB_EP_DIR_IN) { | ||
| 347 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_STALL1; | ||
| 348 | } else { | ||
| 349 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_STALL0; | ||
| 350 | } | ||
| 351 | } | ||
| 352 | |||
| 353 | return STATUS_OK; | ||
| 354 | } | ||
| 355 | |||
| 356 | /** | ||
| 357 | * \brief Disables USB device endpoint callback generation for a given type. | ||
| 358 | * | ||
| 359 | * Disables callbacks for a given logical type. | ||
| 360 | * | ||
| 361 | * \param[in] module_inst Pointer to USB software instance struct | ||
| 362 | * \param[in] ep Endpoint to configure | ||
| 363 | * \param[in] callback_type Callback type given by an enum | ||
| 364 | * | ||
| 365 | * \return Status of the callback disable operation. | ||
| 366 | * \retval STATUS_OK The callback was disabled successfully. | ||
| 367 | */ | ||
| 368 | enum status_code usb_device_endpoint_disable_callback(struct usb_module *module_inst, uint8_t ep, enum usb_device_endpoint_callback callback_type) { | ||
| 369 | /* Sanity check arguments */ | ||
| 370 | Assert(module_inst); | ||
| 371 | Assert(module_inst->hw); | ||
| 372 | |||
| 373 | uint8_t ep_num = ep & USB_EP_ADDR_MASK; | ||
| 374 | Assert(ep_num < USB_EPT_NUM); | ||
| 375 | |||
| 376 | /* Enable callback */ | ||
| 377 | module_inst->device_endpoint_enabled_callback_mask[ep_num] &= ~_usb_endpoint_irq_bits[callback_type]; | ||
| 378 | |||
| 379 | if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_TRCPT) { | ||
| 380 | if (ep_num == 0) { // control endpoint | ||
| 381 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRCPT0 | USB_DEVICE_EPINTENCLR_TRCPT1; | ||
| 382 | } else if (ep & USB_EP_DIR_IN) { | ||
| 383 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRCPT1; | ||
| 384 | } else { | ||
| 385 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRCPT0; | ||
| 386 | } | ||
| 387 | } | ||
| 388 | |||
| 389 | if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_TRFAIL) { | ||
| 390 | if (ep_num == 0) { // control endpoint | ||
| 391 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRFAIL0 | USB_DEVICE_EPINTENCLR_TRFAIL1; | ||
| 392 | } else if (ep & USB_EP_DIR_IN) { | ||
| 393 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRFAIL1; | ||
| 394 | } else { | ||
| 395 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRFAIL0; | ||
| 396 | } | ||
| 397 | } | ||
| 398 | |||
| 399 | if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_RXSTP) { | ||
| 400 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_RXSTP; | ||
| 401 | } | ||
| 402 | |||
| 403 | if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_STALL) { | ||
| 404 | if (ep & USB_EP_DIR_IN) { | ||
| 405 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_STALL1; | ||
| 406 | } else { | ||
| 407 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_STALL0; | ||
| 408 | } | ||
| 409 | } | ||
| 410 | |||
| 411 | return STATUS_OK; | ||
| 412 | } | ||
| 413 | |||
| 414 | /** | ||
| 415 | * \brief Initializes an USB device endpoint configuration structure to defaults. | ||
| 416 | * | ||
| 417 | * Initializes a given USB device endpoint configuration structure to a | ||
| 418 | * set of known default values. This function should be called on all new | ||
| 419 | * instances of these configuration structures before being modified by the | ||
| 420 | * user application. | ||
| 421 | * | ||
| 422 | * The default configuration is as follows: | ||
| 423 | * \li endpoint address is 0 | ||
| 424 | * \li endpoint size is 8 bytes | ||
| 425 | * \li auto_zlp is false | ||
| 426 | * \li endpoint type is control | ||
| 427 | * | ||
| 428 | * \param[out] ep_config Configuration structure to initialize to default values | ||
| 429 | */ | ||
| 430 | void usb_device_endpoint_get_config_defaults(struct usb_device_endpoint_config *ep_config) { | ||
| 431 | /* Sanity check arguments */ | ||
| 432 | Assert(ep_config); | ||
| 433 | |||
| 434 | /* Write default config to config struct */ | ||
| 435 | ep_config->ep_address = 0; | ||
| 436 | ep_config->ep_size = USB_ENDPOINT_8_BYTE; | ||
| 437 | ep_config->auto_zlp = false; | ||
| 438 | ep_config->ep_type = USB_DEVICE_ENDPOINT_TYPE_CONTROL; | ||
| 439 | } | ||
| 440 | |||
| 441 | /** | ||
| 442 | * \brief Writes an USB device endpoint configuration to the hardware module. | ||
| 443 | * | ||
| 444 | * Writes out a given configuration of an USB device endpoint | ||
| 445 | * configuration to the hardware module. If the pipe is already configured, | ||
| 446 | * the new configuration will replace the existing one. | ||
| 447 | * | ||
| 448 | * \param[in] module_inst Pointer to USB software instance struct | ||
| 449 | * \param[in] ep_config Configuration settings for the endpoint | ||
| 450 | * | ||
| 451 | * \return Status of the device endpoint configuration operation | ||
| 452 | * \retval STATUS_OK The device endpoint was configured successfully | ||
| 453 | * \retval STATUS_ERR_DENIED The endpoint address is already configured | ||
| 454 | */ | ||
| 455 | enum status_code usb_device_endpoint_set_config(struct usb_module *module_inst, struct usb_device_endpoint_config *ep_config) { | ||
| 456 | /* Sanity check arguments */ | ||
| 457 | Assert(module_inst); | ||
| 458 | Assert(ep_config); | ||
| 459 | |||
| 460 | uint8_t ep_num = ep_config->ep_address & USB_EP_ADDR_MASK; | ||
| 461 | uint8_t ep_bank = (ep_config->ep_address & USB_EP_DIR_IN) ? 1 : 0; | ||
| 462 | |||
| 463 | switch (ep_config->ep_type) { | ||
| 464 | case USB_DEVICE_ENDPOINT_TYPE_DISABLE: | ||
| 465 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(0) | USB_DEVICE_EPCFG_EPTYPE1(0); | ||
| 466 | return STATUS_OK; | ||
| 467 | |||
| 468 | case USB_DEVICE_ENDPOINT_TYPE_CONTROL: | ||
| 469 | if ((module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE0_Msk) == 0 && (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE1_Msk) == 0) { | ||
| 470 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(1) | USB_DEVICE_EPCFG_EPTYPE1(1); | ||
| 471 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY; | ||
| 472 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY; | ||
| 473 | } else { | ||
| 474 | return STATUS_ERR_DENIED; | ||
| 475 | } | ||
| 476 | if (true == ep_config->auto_zlp) { | ||
| 477 | usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[0].PCKSIZE.reg |= USB_DEVICE_PCKSIZE_AUTO_ZLP; | ||
| 478 | usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.reg |= USB_DEVICE_PCKSIZE_AUTO_ZLP; | ||
| 479 | } else { | ||
| 480 | usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[0].PCKSIZE.reg &= ~USB_DEVICE_PCKSIZE_AUTO_ZLP; | ||
| 481 | usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.reg &= ~USB_DEVICE_PCKSIZE_AUTO_ZLP; | ||
| 482 | } | ||
| 483 | usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[0].PCKSIZE.bit.SIZE = ep_config->ep_size; | ||
| 484 | usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.SIZE = ep_config->ep_size; | ||
| 485 | return STATUS_OK; | ||
| 486 | |||
| 487 | case USB_DEVICE_ENDPOINT_TYPE_ISOCHRONOUS: | ||
| 488 | if (ep_bank) { | ||
| 489 | if ((module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE1_Msk) == 0) { | ||
| 490 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg |= USB_DEVICE_EPCFG_EPTYPE1(2); | ||
| 491 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY; | ||
| 492 | } else { | ||
| 493 | return STATUS_ERR_DENIED; | ||
| 494 | } | ||
| 495 | } else { | ||
| 496 | if ((module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE0_Msk) == 0) { | ||
| 497 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg |= USB_DEVICE_EPCFG_EPTYPE0(2); | ||
| 498 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY; | ||
| 499 | } else { | ||
| 500 | return STATUS_ERR_DENIED; | ||
| 501 | } | ||
| 502 | } | ||
| 503 | break; | ||
| 504 | |||
| 505 | case USB_DEVICE_ENDPOINT_TYPE_BULK: | ||
| 506 | if (ep_bank) { | ||
| 507 | if ((module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE1_Msk) == 0) { | ||
| 508 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg |= USB_DEVICE_EPCFG_EPTYPE1(3); | ||
| 509 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY; | ||
| 510 | } else { | ||
| 511 | return STATUS_ERR_DENIED; | ||
| 512 | } | ||
| 513 | } else { | ||
| 514 | if ((module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE0_Msk) == 0) { | ||
| 515 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg |= USB_DEVICE_EPCFG_EPTYPE0(3); | ||
| 516 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY; | ||
| 517 | } else { | ||
| 518 | return STATUS_ERR_DENIED; | ||
| 519 | } | ||
| 520 | } | ||
| 521 | break; | ||
| 522 | |||
| 523 | case USB_DEVICE_ENDPOINT_TYPE_INTERRUPT: | ||
| 524 | if (ep_bank) { | ||
| 525 | if ((module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE1_Msk) == 0) { | ||
| 526 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg |= USB_DEVICE_EPCFG_EPTYPE1(4); | ||
| 527 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY; | ||
| 528 | } else { | ||
| 529 | return STATUS_ERR_DENIED; | ||
| 530 | } | ||
| 531 | } else { | ||
| 532 | if ((module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE0_Msk) == 0) { | ||
| 533 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg |= USB_DEVICE_EPCFG_EPTYPE0(4); | ||
| 534 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY; | ||
| 535 | } else { | ||
| 536 | return STATUS_ERR_DENIED; | ||
| 537 | } | ||
| 538 | } | ||
| 539 | break; | ||
| 540 | |||
| 541 | default: | ||
| 542 | break; | ||
| 543 | } | ||
| 544 | |||
| 545 | usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[ep_bank].PCKSIZE.bit.SIZE = ep_config->ep_size; | ||
| 546 | |||
| 547 | if (true == ep_config->auto_zlp) { | ||
| 548 | usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[ep_bank].PCKSIZE.reg |= USB_DEVICE_PCKSIZE_AUTO_ZLP; | ||
| 549 | } else { | ||
| 550 | usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[ep_bank].PCKSIZE.reg &= ~USB_DEVICE_PCKSIZE_AUTO_ZLP; | ||
| 551 | } | ||
| 552 | |||
| 553 | return STATUS_OK; | ||
| 554 | } | ||
| 555 | |||
| 556 | /** | ||
| 557 | * \brief Check if current endpoint is configured | ||
| 558 | * | ||
| 559 | * \param module_inst Pointer to USB software instance struct | ||
| 560 | * \param ep Endpoint address (direction & number) | ||
| 561 | * | ||
| 562 | * \return \c true if endpoint is configured and ready to use | ||
| 563 | */ | ||
| 564 | bool usb_device_endpoint_is_configured(struct usb_module *module_inst, uint8_t ep) { | ||
| 565 | uint8_t ep_num = ep & USB_EP_ADDR_MASK; | ||
| 566 | uint8_t flag; | ||
| 567 | |||
| 568 | if (ep & USB_EP_DIR_IN) { | ||
| 569 | flag = (uint8_t)(module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.bit.EPTYPE1); | ||
| 570 | } else { | ||
| 571 | flag = (uint8_t)(module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.bit.EPTYPE0); | ||
| 572 | } | ||
| 573 | return ((enum usb_device_endpoint_type)(flag) != USB_DEVICE_ENDPOINT_TYPE_DISABLE); | ||
| 574 | } | ||
| 575 | |||
| 576 | /** | ||
| 577 | * \brief Abort ongoing job on the endpoint | ||
| 578 | * | ||
| 579 | * \param module_inst Pointer to USB software instance struct | ||
| 580 | * \param ep Endpoint address | ||
| 581 | */ | ||
| 582 | void usb_device_endpoint_abort_job(struct usb_module *module_inst, uint8_t ep) { | ||
| 583 | uint8_t ep_num; | ||
| 584 | ep_num = ep & USB_EP_ADDR_MASK; | ||
| 585 | |||
| 586 | // Stop transfer | ||
| 587 | if (ep & USB_EP_DIR_IN) { | ||
| 588 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY; | ||
| 589 | // Eventually ack a transfer occur during abort | ||
| 590 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT1; | ||
| 591 | } else { | ||
| 592 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY; | ||
| 593 | // Eventually ack a transfer occur during abort | ||
| 594 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT0; | ||
| 595 | } | ||
| 596 | } | ||
| 597 | |||
| 598 | /** | ||
| 599 | * \brief Check if endpoint is halted | ||
| 600 | * | ||
| 601 | * \param module_inst Pointer to USB software instance struct | ||
| 602 | * \param ep Endpoint address | ||
| 603 | * | ||
| 604 | * \return \c true if the endpoint is halted | ||
| 605 | */ | ||
| 606 | bool usb_device_endpoint_is_halted(struct usb_module *module_inst, uint8_t ep) { | ||
| 607 | uint8_t ep_num = ep & USB_EP_ADDR_MASK; | ||
| 608 | |||
| 609 | if (ep & USB_EP_DIR_IN) { | ||
| 610 | return (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ1); | ||
| 611 | } else { | ||
| 612 | return (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ0); | ||
| 613 | } | ||
| 614 | } | ||
| 615 | |||
| 616 | /** | ||
| 617 | * \brief Halt the endpoint (send STALL) | ||
| 618 | * | ||
| 619 | * \param module_inst Pointer to USB software instance struct | ||
| 620 | * \param ep Endpoint address | ||
| 621 | */ | ||
| 622 | void usb_device_endpoint_set_halt(struct usb_module *module_inst, uint8_t ep) { | ||
| 623 | uint8_t ep_num = ep & USB_EP_ADDR_MASK; | ||
| 624 | |||
| 625 | // Stall endpoint | ||
| 626 | if (ep & USB_EP_DIR_IN) { | ||
| 627 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1; | ||
| 628 | } else { | ||
| 629 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0; | ||
| 630 | } | ||
| 631 | } | ||
| 632 | |||
| 633 | /** | ||
| 634 | * \brief Clear endpoint halt state | ||
| 635 | * | ||
| 636 | * \param module_inst Pointer to USB software instance struct | ||
| 637 | * \param ep Endpoint address | ||
| 638 | */ | ||
| 639 | void usb_device_endpoint_clear_halt(struct usb_module *module_inst, uint8_t ep) { | ||
| 640 | uint8_t ep_num = ep & USB_EP_ADDR_MASK; | ||
| 641 | |||
| 642 | if (ep & USB_EP_DIR_IN) { | ||
| 643 | if (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ1) { | ||
| 644 | // Remove stall request | ||
| 645 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1; | ||
| 646 | if (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_STALL1) { | ||
| 647 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL1; | ||
| 648 | // The Stall has occurred, then reset data toggle | ||
| 649 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSSET_DTGLIN; | ||
| 650 | } | ||
| 651 | } | ||
| 652 | } else { | ||
| 653 | if (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ0) { | ||
| 654 | // Remove stall request | ||
| 655 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0; | ||
| 656 | if (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_STALL0) { | ||
| 657 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL0; | ||
| 658 | // The Stall has occurred, then reset data toggle | ||
| 659 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSSET_DTGLOUT; | ||
| 660 | } | ||
| 661 | } | ||
| 662 | } | ||
| 663 | } | ||
| 664 | |||
| 665 | /** | ||
| 666 | * \brief Start write buffer job on a endpoint | ||
| 667 | * | ||
| 668 | * \param module_inst Pointer to USB module instance | ||
| 669 | * \param ep_num Endpoint number | ||
| 670 | * \param pbuf Pointer to buffer | ||
| 671 | * \param buf_size Size of buffer | ||
| 672 | * | ||
| 673 | * \return Status of procedure | ||
| 674 | * \retval STATUS_OK Job started successfully | ||
| 675 | * \retval STATUS_ERR_DENIED Endpoint is not ready | ||
| 676 | */ | ||
| 677 | 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) { | ||
| 678 | /* Sanity check arguments */ | ||
| 679 | Assert(module_inst); | ||
| 680 | Assert(module_inst->hw); | ||
| 681 | Assert(ep_num < USB_EPT_NUM); | ||
| 682 | |||
| 683 | uint8_t flag; | ||
| 684 | flag = (uint8_t)(module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.bit.EPTYPE1); | ||
| 685 | if ((enum usb_device_endpoint_type)(flag) == USB_DEVICE_ENDPOINT_TYPE_DISABLE) { | ||
| 686 | return STATUS_ERR_DENIED; | ||
| 687 | }; | ||
| 688 | |||
| 689 | /* get endpoint configuration from setting register */ | ||
| 690 | usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[1].ADDR.reg = (uint32_t)pbuf; | ||
| 691 | usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.MULTI_PACKET_SIZE = 0; | ||
| 692 | usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT = buf_size; | ||
| 693 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK1RDY; | ||
| 694 | |||
| 695 | return STATUS_OK; | ||
| 696 | } | ||
| 697 | |||
| 698 | /** | ||
| 699 | * \brief Start read buffer job on a endpoint | ||
| 700 | * | ||
| 701 | * \param module_inst Pointer to USB module instance | ||
| 702 | * \param ep_num Endpoint number | ||
| 703 | * \param pbuf Pointer to buffer | ||
| 704 | * \param buf_size Size of buffer | ||
| 705 | * | ||
| 706 | * \return Status of procedure | ||
| 707 | * \retval STATUS_OK Job started successfully | ||
| 708 | * \retval STATUS_ERR_DENIED Endpoint is not ready | ||
| 709 | */ | ||
| 710 | 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) { | ||
| 711 | /* Sanity check arguments */ | ||
| 712 | Assert(module_inst); | ||
| 713 | Assert(module_inst->hw); | ||
| 714 | Assert(ep_num < USB_EPT_NUM); | ||
| 715 | |||
| 716 | uint8_t flag; | ||
| 717 | flag = (uint8_t)(module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.bit.EPTYPE0); | ||
| 718 | if ((enum usb_device_endpoint_type)(flag) == USB_DEVICE_ENDPOINT_TYPE_DISABLE) { | ||
| 719 | return STATUS_ERR_DENIED; | ||
| 720 | }; | ||
| 721 | |||
| 722 | /* get endpoint configuration from setting register */ | ||
| 723 | usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[0].ADDR.reg = (uint32_t)pbuf; | ||
| 724 | usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = buf_size; | ||
| 725 | usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; | ||
| 726 | module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY; | ||
| 727 | |||
| 728 | return STATUS_OK; | ||
| 729 | } | ||
| 730 | |||
| 731 | /** | ||
| 732 | * \brief Start setup packet read job on a endpoint | ||
| 733 | * | ||
| 734 | * \param module_inst Pointer to USB device module instance | ||
| 735 | * \param pbuf Pointer to buffer | ||
| 736 | * | ||
| 737 | * \return Status of procedure | ||
| 738 | * \retval STATUS_OK Job started successfully | ||
| 739 | * \retval STATUS_ERR_DENIED Endpoint is not ready | ||
| 740 | */ | ||
| 741 | enum status_code usb_device_endpoint_setup_buffer_job(struct usb_module *module_inst, uint8_t *pbuf) { | ||
| 742 | /* Sanity check arguments */ | ||
| 743 | Assert(module_inst); | ||
| 744 | Assert(module_inst->hw); | ||
| 745 | |||
| 746 | /* get endpoint configuration from setting register */ | ||
| 747 | usb_descriptor_table.usb_endpoint_table[0].DeviceDescBank[0].ADDR.reg = (uint32_t)pbuf; | ||
| 748 | usb_descriptor_table.usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 8; | ||
| 749 | usb_descriptor_table.usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; | ||
| 750 | module_inst->hw->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY; | ||
| 751 | |||
| 752 | return STATUS_OK; | ||
| 753 | } | ||
| 754 | |||
| 755 | static void _usb_device_interrupt_handler(void) { | ||
| 756 | uint16_t ep_inst; | ||
| 757 | uint16_t flags, flags_run; | ||
| 758 | ep_inst = _usb_instances->hw->DEVICE.EPINTSMRY.reg; | ||
| 759 | |||
| 760 | /* device interrupt */ | ||
| 761 | if (0 == ep_inst) { | ||
| 762 | int i; | ||
| 763 | |||
| 764 | /* get interrupt flags */ | ||
| 765 | flags = _usb_instances->hw->DEVICE.INTFLAG.reg; | ||
| 766 | flags_run = flags & _usb_instances->device_enabled_callback_mask & _usb_instances->device_registered_callback_mask; | ||
| 767 | |||
| 768 | for (i = 0; i < USB_DEVICE_CALLBACK_N; i++) { | ||
| 769 | if (flags & _usb_device_irq_bits[i]) { | ||
| 770 | _usb_instances->hw->DEVICE.INTFLAG.reg = _usb_device_irq_bits[i]; | ||
| 771 | } | ||
| 772 | if (flags_run & _usb_device_irq_bits[i]) { | ||
| 773 | if (i == USB_DEVICE_CALLBACK_LPMSUSP) { | ||
| 774 | device_callback_lpm_wakeup_enable = usb_descriptor_table.usb_endpoint_table[0].DeviceDescBank[0].EXTREG.bit.VARIABLE & USB_LPM_ATTRIBUT_REMOTEWAKE_MASK; | ||
| 775 | } | ||
| 776 | (_usb_instances->device_callback[i])(_usb_instances, &device_callback_lpm_wakeup_enable); | ||
| 777 | } | ||
| 778 | } | ||
| 779 | |||
| 780 | } else { | ||
| 781 | /* endpoint interrupt */ | ||
| 782 | |||
| 783 | for (uint8_t i = 0; i < USB_EPT_NUM; i++) { | ||
| 784 | if (ep_inst & (1 << i)) { | ||
| 785 | flags = _usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg; | ||
| 786 | flags_run = flags & _usb_instances->device_endpoint_enabled_callback_mask[i] & _usb_instances->device_endpoint_registered_callback_mask[i]; | ||
| 787 | |||
| 788 | // endpoint transfer stall interrupt | ||
| 789 | if (flags & USB_DEVICE_EPINTFLAG_STALL_Msk) { | ||
| 790 | if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_STALL1) { | ||
| 791 | _usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL1; | ||
| 792 | ep_callback_para.endpoint_address = USB_EP_DIR_IN | i; | ||
| 793 | } else if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_STALL0) { | ||
| 794 | _usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL0; | ||
| 795 | ep_callback_para.endpoint_address = USB_EP_DIR_OUT | i; | ||
| 796 | } | ||
| 797 | |||
| 798 | if (flags_run & USB_DEVICE_EPINTFLAG_STALL_Msk) { | ||
| 799 | (_usb_instances->device_endpoint_callback[i][USB_DEVICE_ENDPOINT_CALLBACK_STALL])(_usb_instances, &ep_callback_para); | ||
| 800 | } | ||
| 801 | return; | ||
| 802 | } | ||
| 803 | |||
| 804 | // endpoint received setup interrupt | ||
| 805 | if (flags & USB_DEVICE_EPINTFLAG_RXSTP) { | ||
| 806 | _usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_RXSTP; | ||
| 807 | if (_usb_instances->device_endpoint_enabled_callback_mask[i] & _usb_endpoint_irq_bits[USB_DEVICE_ENDPOINT_CALLBACK_RXSTP]) { | ||
| 808 | ep_callback_para.received_bytes = (uint16_t)(usb_descriptor_table.usb_endpoint_table[i].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT); | ||
| 809 | (_usb_instances->device_endpoint_callback[i][USB_DEVICE_ENDPOINT_CALLBACK_RXSTP])(_usb_instances, &ep_callback_para); | ||
| 810 | } | ||
| 811 | return; | ||
| 812 | } | ||
| 813 | |||
| 814 | // endpoint transfer complete interrupt | ||
| 815 | if (flags & USB_DEVICE_EPINTFLAG_TRCPT_Msk) { | ||
| 816 | if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_TRCPT1) { | ||
| 817 | _usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT1; | ||
| 818 | ep_callback_para.endpoint_address = USB_EP_DIR_IN | i; | ||
| 819 | ep_callback_para.sent_bytes = (uint16_t)(usb_descriptor_table.usb_endpoint_table[i].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT); | ||
| 820 | |||
| 821 | } else if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_TRCPT0) { | ||
| 822 | _usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT0; | ||
| 823 | ep_callback_para.endpoint_address = USB_EP_DIR_OUT | i; | ||
| 824 | ep_callback_para.received_bytes = (uint16_t)(usb_descriptor_table.usb_endpoint_table[i].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT); | ||
| 825 | ep_callback_para.out_buffer_size = (uint16_t)(usb_descriptor_table.usb_endpoint_table[i].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE); | ||
| 826 | } | ||
| 827 | if (flags_run & USB_DEVICE_EPINTFLAG_TRCPT_Msk) { | ||
| 828 | (_usb_instances->device_endpoint_callback[i][USB_DEVICE_ENDPOINT_CALLBACK_TRCPT])(_usb_instances, &ep_callback_para); | ||
| 829 | } | ||
| 830 | return; | ||
| 831 | } | ||
| 832 | |||
| 833 | // endpoint transfer fail interrupt | ||
| 834 | if (flags & USB_DEVICE_EPINTFLAG_TRFAIL_Msk) { | ||
| 835 | if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_TRFAIL1) { | ||
| 836 | _usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRFAIL1; | ||
| 837 | if (usb_descriptor_table.usb_endpoint_table[i].DeviceDescBank[1].STATUS_BK.reg & USB_DEVICE_STATUS_BK_ERRORFLOW) { | ||
| 838 | usb_descriptor_table.usb_endpoint_table[i].DeviceDescBank[1].STATUS_BK.reg &= ~USB_DEVICE_STATUS_BK_ERRORFLOW; | ||
| 839 | } | ||
| 840 | ep_callback_para.endpoint_address = USB_EP_DIR_IN | i; | ||
| 841 | if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_TRCPT1) { | ||
| 842 | return; | ||
| 843 | } | ||
| 844 | } else if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_TRFAIL0) { | ||
| 845 | _usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRFAIL0; | ||
| 846 | if (usb_descriptor_table.usb_endpoint_table[i].DeviceDescBank[0].STATUS_BK.reg & USB_DEVICE_STATUS_BK_ERRORFLOW) { | ||
| 847 | usb_descriptor_table.usb_endpoint_table[i].DeviceDescBank[0].STATUS_BK.reg &= ~USB_DEVICE_STATUS_BK_ERRORFLOW; | ||
| 848 | } | ||
| 849 | ep_callback_para.endpoint_address = USB_EP_DIR_OUT | i; | ||
| 850 | if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_TRCPT0) { | ||
| 851 | return; | ||
| 852 | } | ||
| 853 | } | ||
| 854 | |||
| 855 | if (flags_run & USB_DEVICE_EPINTFLAG_TRFAIL_Msk) { | ||
| 856 | (_usb_instances->device_endpoint_callback[i][USB_DEVICE_ENDPOINT_CALLBACK_TRFAIL])(_usb_instances, &ep_callback_para); | ||
| 857 | } | ||
| 858 | return; | ||
| 859 | } | ||
| 860 | } | ||
| 861 | } | ||
| 862 | } | ||
| 863 | } | ||
| 864 | |||
| 865 | /** | ||
| 866 | * \brief Enable the USB module peripheral | ||
| 867 | * | ||
| 868 | * \param module_inst pointer to USB module instance | ||
| 869 | */ | ||
| 870 | void usb_enable(struct usb_module *module_inst) { | ||
| 871 | Assert(module_inst); | ||
| 872 | Assert(module_inst->hw); | ||
| 873 | |||
| 874 | module_inst->hw->DEVICE.CTRLA.reg |= USB_CTRLA_ENABLE; | ||
| 875 | while (module_inst->hw->DEVICE.SYNCBUSY.reg == USB_SYNCBUSY_ENABLE) | ||
| 876 | ; | ||
| 877 | } | ||
| 878 | |||
| 879 | /** | ||
| 880 | * \brief Disable the USB module peripheral | ||
| 881 | * | ||
| 882 | * \param module_inst pointer to USB module instance | ||
| 883 | */ | ||
| 884 | void usb_disable(struct usb_module *module_inst) { | ||
| 885 | Assert(module_inst); | ||
| 886 | Assert(module_inst->hw); | ||
| 887 | |||
| 888 | module_inst->hw->DEVICE.INTENCLR.reg = USB_DEVICE_INTENCLR_MASK; | ||
| 889 | module_inst->hw->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_MASK; | ||
| 890 | module_inst->hw->DEVICE.CTRLA.reg &= ~USB_CTRLA_ENABLE; | ||
| 891 | while (module_inst->hw->DEVICE.SYNCBUSY.reg == USB_SYNCBUSY_ENABLE) | ||
| 892 | ; | ||
| 893 | } | ||
| 894 | |||
| 895 | /** | ||
| 896 | * \brief Interrupt handler for the USB module. | ||
| 897 | */ | ||
| 898 | void USB_0_Handler(void) { | ||
| 899 | if (_usb_instances->hw->DEVICE.CTRLA.bit.MODE) { | ||
| 900 | } else { | ||
| 901 | /*device mode ISR */ | ||
| 902 | _usb_device_interrupt_handler(); | ||
| 903 | } | ||
| 904 | } | ||
| 905 | |||
| 906 | void USB_1_Handler(void) { | ||
| 907 | _usb_device_interrupt_handler(); | ||
| 908 | } | ||
| 909 | |||
| 910 | void USB_2_Handler(void) { | ||
| 911 | _usb_device_interrupt_handler(); | ||
| 912 | } | ||
| 913 | |||
| 914 | void USB_3_Handler(void) { | ||
| 915 | _usb_device_interrupt_handler(); | ||
| 916 | } | ||
| 917 | |||
| 918 | /** | ||
| 919 | * \brief Get the default USB module settings | ||
| 920 | * | ||
| 921 | * \param[out] module_config Configuration structure to initialize to default values | ||
| 922 | */ | ||
| 923 | void usb_get_config_defaults(struct usb_config *module_config) { | ||
| 924 | Assert(module_config); | ||
| 925 | |||
| 926 | /* Sanity check arguments */ | ||
| 927 | Assert(module_config); | ||
| 928 | /* Write default configuration to config struct */ | ||
| 929 | module_config->select_host_mode = 0; | ||
| 930 | module_config->run_in_standby = 1; | ||
| 931 | module_config->source_generator = 0; | ||
| 932 | module_config->speed_mode = USB_SPEED_FULL; | ||
| 933 | } | ||
| 934 | |||
| 935 | #define NVM_USB_PAD_TRANSN_POS 45 | ||
| 936 | #define NVM_USB_PAD_TRANSN_SIZE 5 | ||
| 937 | #define NVM_USB_PAD_TRANSP_POS 50 | ||
| 938 | #define NVM_USB_PAD_TRANSP_SIZE 5 | ||
| 939 | #define NVM_USB_PAD_TRIM_POS 55 | ||
| 940 | #define NVM_USB_PAD_TRIM_SIZE 3 | ||
| 941 | |||
| 942 | /** | ||
| 943 | * \brief Initializes USB module instance | ||
| 944 | * | ||
| 945 | * Enables the clock and initializes the USB module, based on the given | ||
| 946 | * configuration values. | ||
| 947 | * | ||
| 948 | * \param[in,out] module_inst Pointer to the software module instance struct | ||
| 949 | * \param[in] hw Pointer to the USB hardware module | ||
| 950 | * \param[in] module_config Pointer to the USB configuration options struct | ||
| 951 | * | ||
| 952 | * \return Status of the initialization procedure. | ||
| 953 | * | ||
| 954 | * \retval STATUS_OK The module was initialized successfully | ||
| 955 | */ | ||
| 956 | |||
| 957 | #define GCLK_USB 10 | ||
| 958 | |||
| 959 | enum status_code usb_init(struct usb_module *module_inst, Usb *const hw, struct usb_config *module_config) { | ||
| 960 | /* Sanity check arguments */ | ||
| 961 | Assert(hw); | ||
| 962 | Assert(module_inst); | ||
| 963 | Assert(module_config); | ||
| 964 | |||
| 965 | uint32_t i, j; | ||
| 966 | uint32_t pad_transn, pad_transp, pad_trim; | ||
| 967 | |||
| 968 | Gclk * pgclk = GCLK; | ||
| 969 | Mclk * pmclk = MCLK; | ||
| 970 | Port * pport = PORT; | ||
| 971 | Oscctrl *posc = OSCCTRL; | ||
| 972 | |||
| 973 | _usb_instances = module_inst; | ||
| 974 | |||
| 975 | /* Associate the software module instance with the hardware module */ | ||
| 976 | module_inst->hw = hw; | ||
| 977 | |||
| 978 | // setup peripheral and synchronous bus clocks to USB | ||
| 979 | pmclk->AHBMASK.bit.USB_ = 1; | ||
| 980 | pmclk->APBBMASK.bit.USB_ = 1; | ||
| 981 | |||
| 982 | /* Set up the USB DP/DN pins */ | ||
| 983 | pport->Group[0].PMUX[12].reg = 0x77; // PA24, PA25, function column H for USB D-, D+ | ||
| 984 | pport->Group[0].PINCFG[24].bit.PMUXEN = 1; | ||
| 985 | pport->Group[0].PINCFG[25].bit.PMUXEN = 1; | ||
| 986 | pport->Group[1].PMUX[11].bit.PMUXE = 7; // PB22, function column H for USB SOF_1KHz output | ||
| 987 | pport->Group[1].PINCFG[22].bit.PMUXEN = 1; | ||
| 988 | |||
| 989 | // configure and enable DFLL for USB clock recovery mode at 48MHz | ||
| 990 | posc->DFLLCTRLA.bit.ENABLE = 0; | ||
| 991 | while (posc->DFLLSYNC.bit.ENABLE) | ||
| 992 | ; | ||
| 993 | while (posc->DFLLSYNC.bit.DFLLCTRLB) | ||
| 994 | ; | ||
| 995 | posc->DFLLCTRLB.bit.USBCRM = 1; | ||
| 996 | while (posc->DFLLSYNC.bit.DFLLCTRLB) | ||
| 997 | ; | ||
| 998 | posc->DFLLCTRLB.bit.MODE = 1; | ||
| 999 | while (posc->DFLLSYNC.bit.DFLLCTRLB) | ||
| 1000 | ; | ||
| 1001 | posc->DFLLCTRLB.bit.QLDIS = 0; | ||
| 1002 | while (posc->DFLLSYNC.bit.DFLLCTRLB) | ||
| 1003 | ; | ||
| 1004 | posc->DFLLCTRLB.bit.CCDIS = 1; | ||
| 1005 | posc->DFLLMUL.bit.MUL = 0xbb80; // 4800 x 1KHz | ||
| 1006 | while (posc->DFLLSYNC.bit.DFLLMUL) | ||
| 1007 | ; | ||
| 1008 | posc->DFLLCTRLA.bit.ENABLE = 1; | ||
| 1009 | while (posc->DFLLSYNC.bit.ENABLE) | ||
| 1010 | ; | ||
| 1011 | |||
| 1012 | /* Setup clock for module */ | ||
| 1013 | pgclk->PCHCTRL[GCLK_USB].bit.GEN = 0; | ||
| 1014 | pgclk->PCHCTRL[GCLK_USB].bit.CHEN = 1; | ||
| 1015 | |||
| 1016 | /* Reset */ | ||
| 1017 | hw->DEVICE.CTRLA.bit.SWRST = 1; | ||
| 1018 | while (hw->DEVICE.SYNCBUSY.bit.SWRST) { | ||
| 1019 | /* Sync wait */ | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | /* Change QOS values to have the best performance and correct USB behaviour */ | ||
| 1023 | USB->DEVICE.QOSCTRL.bit.CQOS = 2; | ||
| 1024 | USB->DEVICE.QOSCTRL.bit.DQOS = 2; | ||
| 1025 | |||
| 1026 | /* Load Pad Calibration */ | ||
| 1027 | |||
| 1028 | pad_transn = (USB_FUSES_TRANSN_ADDR >> USB_FUSES_TRANSN_Pos) & USB_FUSES_TRANSN_Msk; | ||
| 1029 | if (pad_transn == 0x1F) { | ||
| 1030 | pad_transn = 5; | ||
| 1031 | } | ||
| 1032 | |||
| 1033 | hw->DEVICE.PADCAL.bit.TRANSN = pad_transn; | ||
| 1034 | |||
| 1035 | pad_transp = (USB_FUSES_TRANSP_ADDR >> USB_FUSES_TRANSP_Pos) & USB_FUSES_TRANSP_Msk; | ||
| 1036 | if (pad_transp == 0x1F) { | ||
| 1037 | pad_transp = 29; | ||
| 1038 | } | ||
| 1039 | |||
| 1040 | hw->DEVICE.PADCAL.bit.TRANSP = pad_transp; | ||
| 1041 | |||
| 1042 | pad_trim = (USB_FUSES_TRIM_ADDR >> USB_FUSES_TRIM_Pos) & USB_FUSES_TRIM_Msk; | ||
| 1043 | if (pad_trim == 0x07) { | ||
| 1044 | pad_trim = 3; | ||
| 1045 | } | ||
| 1046 | |||
| 1047 | hw->DEVICE.PADCAL.bit.TRIM = pad_trim; | ||
| 1048 | |||
| 1049 | /* Set the configuration */ | ||
| 1050 | hw->DEVICE.CTRLA.bit.MODE = module_config->select_host_mode; | ||
| 1051 | hw->DEVICE.CTRLA.bit.RUNSTDBY = module_config->run_in_standby; | ||
| 1052 | hw->DEVICE.DESCADD.reg = (uint32_t)(&usb_descriptor_table.usb_endpoint_table[0]); | ||
| 1053 | if (USB_SPEED_FULL == module_config->speed_mode) { | ||
| 1054 | module_inst->hw->DEVICE.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_FS_Val; | ||
| 1055 | } else if (USB_SPEED_LOW == module_config->speed_mode) { | ||
| 1056 | module_inst->hw->DEVICE.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_LS_Val; | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | memset((uint8_t *)(&usb_descriptor_table.usb_endpoint_table[0]), 0, sizeof(usb_descriptor_table.usb_endpoint_table)); | ||
| 1060 | |||
| 1061 | /* device callback related */ | ||
| 1062 | for (i = 0; i < USB_DEVICE_CALLBACK_N; i++) { | ||
| 1063 | module_inst->device_callback[i] = NULL; | ||
| 1064 | } | ||
| 1065 | for (i = 0; i < USB_EPT_NUM; i++) { | ||
| 1066 | for (j = 0; j < USB_DEVICE_EP_CALLBACK_N; j++) { | ||
| 1067 | module_inst->device_endpoint_callback[i][j] = NULL; | ||
| 1068 | } | ||
| 1069 | } | ||
| 1070 | module_inst->device_registered_callback_mask = 0; | ||
| 1071 | module_inst->device_enabled_callback_mask = 0; | ||
| 1072 | for (j = 0; j < USB_EPT_NUM; j++) { | ||
| 1073 | module_inst->device_endpoint_registered_callback_mask[j] = 0; | ||
| 1074 | module_inst->device_endpoint_enabled_callback_mask[j] = 0; | ||
| 1075 | } | ||
| 1076 | |||
| 1077 | /* Enable interrupts for this USB module */ | ||
| 1078 | NVIC_EnableIRQ(USB_0_IRQn); | ||
| 1079 | NVIC_EnableIRQ(USB_2_IRQn); | ||
| 1080 | NVIC_EnableIRQ(USB_3_IRQn); | ||
| 1081 | |||
| 1082 | return STATUS_OK; | ||
| 1083 | } | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/usb.h b/tmk_core/protocol/arm_atsam/usb/usb.h deleted file mode 100644 index 270143a112..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/usb.h +++ /dev/null | |||
| @@ -1,462 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief SAM USB Driver | ||
| 5 | * | ||
| 6 | * Copyright (C) 2014-2016 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | #ifndef USB_H_INCLUDED | ||
| 47 | #define USB_H_INCLUDED | ||
| 48 | |||
| 49 | #ifdef __cplusplus | ||
| 50 | extern "C" { | ||
| 51 | #endif | ||
| 52 | |||
| 53 | /** | ||
| 54 | * \defgroup asfdoc_sam0_usb_group SAM Universal Serial Bus (USB) | ||
| 55 | * | ||
| 56 | * The Universal Serial Bus (USB) module complies with the USB 2.1 specification. | ||
| 57 | * | ||
| 58 | * The following peripherals are used by this module: | ||
| 59 | * - USB (Universal Serial Bus) | ||
| 60 | * | ||
| 61 | * The following devices can use this module: | ||
| 62 | * - Atmel | SMART SAM D51 | ||
| 63 | * | ||
| 64 | * The USB module covers following mode: | ||
| 65 | * \if USB_DEVICE_MODE | ||
| 66 | * - USB Device Mode | ||
| 67 | * \endif | ||
| 68 | * \if USB_HOST_MODE | ||
| 69 | * - USB Host Mode | ||
| 70 | * \endif | ||
| 71 | * | ||
| 72 | * The USB module covers following speed: | ||
| 73 | * \if USB_HS_MODE | ||
| 74 | * - USB High Speed (480Mbit/s) | ||
| 75 | * \endif | ||
| 76 | * - USB Full Speed (12Mbit/s) | ||
| 77 | * \if USB_LS_MODE | ||
| 78 | * - USB Low Speed (1.5Mbit/s) | ||
| 79 | * \endif | ||
| 80 | * | ||
| 81 | * \if USB_LPM_MODE | ||
| 82 | * The USB module supports Link Power Management (LPM-L1) protocol. | ||
| 83 | * \endif | ||
| 84 | * | ||
| 85 | * USB support needs whole set of enumeration process, to make the device | ||
| 86 | * recognizable and usable. The USB driver is designed to interface to the | ||
| 87 | * USB Stack in Atmel Software Framework (ASF). | ||
| 88 | * | ||
| 89 | * \if USB_DEVICE_MODE | ||
| 90 | * \section asfdoc_sam0_usb_device USB Device Mode | ||
| 91 | * The ASF USB Device Stack has defined the USB Device Driver (UDD) interface, | ||
| 92 | * to support USB device operations. The USB module device driver complies with | ||
| 93 | * this interface, so that the USB Device Stack can work based on the | ||
| 94 | * USB module. | ||
| 95 | * | ||
| 96 | * Refer to <a href="http://www.atmel.com/images/doc8360.pdf"> | ||
| 97 | * "ASF - USB Device Stack"</a> for more details. | ||
| 98 | * \endif | ||
| 99 | * | ||
| 100 | * \if USB_HOST_MODE | ||
| 101 | * \section adfdoc_sam0_usb_host USB Host Mode | ||
| 102 | * The ASF USB Host Stack has defined the USB Host Driver (UHD) interface, | ||
| 103 | * to support USB host operations. The USB module host driver complies with | ||
| 104 | * this interface, so that the USB Host Stack can work based on the USB module. | ||
| 105 | * | ||
| 106 | * Refer to <a href="http://www.atmel.com/images/doc8486.pdf"> | ||
| 107 | * "ASF - USB Host Stack"</a> for more details. | ||
| 108 | * \endif | ||
| 109 | */ | ||
| 110 | |||
| 111 | /** Enum for the speed status for the USB module */ | ||
| 112 | enum usb_speed { | ||
| 113 | USB_SPEED_LOW, | ||
| 114 | USB_SPEED_FULL, | ||
| 115 | }; | ||
| 116 | |||
| 117 | /** Enum for the possible callback types for the USB in host module */ | ||
| 118 | enum usb_host_callback { | ||
| 119 | USB_HOST_CALLBACK_SOF, | ||
| 120 | USB_HOST_CALLBACK_RESET, | ||
| 121 | USB_HOST_CALLBACK_WAKEUP, | ||
| 122 | USB_HOST_CALLBACK_DNRSM, | ||
| 123 | USB_HOST_CALLBACK_UPRSM, | ||
| 124 | USB_HOST_CALLBACK_RAMACER, | ||
| 125 | USB_HOST_CALLBACK_CONNECT, | ||
| 126 | USB_HOST_CALLBACK_DISCONNECT, | ||
| 127 | USB_HOST_CALLBACK_N, | ||
| 128 | }; | ||
| 129 | |||
| 130 | /** Enum for the possible callback types for the USB pipe in host module */ | ||
| 131 | enum usb_host_pipe_callback { | ||
| 132 | USB_HOST_PIPE_CALLBACK_TRANSFER_COMPLETE, | ||
| 133 | USB_HOST_PIPE_CALLBACK_ERROR, | ||
| 134 | USB_HOST_PIPE_CALLBACK_SETUP, | ||
| 135 | USB_HOST_PIPE_CALLBACK_STALL, | ||
| 136 | USB_HOST_PIPE_CALLBACK_N, | ||
| 137 | }; | ||
| 138 | |||
| 139 | /** | ||
| 140 | * \brief Host pipe types. | ||
| 141 | */ | ||
| 142 | enum usb_host_pipe_type { | ||
| 143 | USB_HOST_PIPE_TYPE_DISABLE, | ||
| 144 | USB_HOST_PIPE_TYPE_CONTROL, | ||
| 145 | USB_HOST_PIPE_TYPE_ISO, | ||
| 146 | USB_HOST_PIPE_TYPE_BULK, | ||
| 147 | USB_HOST_PIPE_TYPE_INTERRUPT, | ||
| 148 | USB_HOST_PIPE_TYPE_EXTENDED, | ||
| 149 | }; | ||
| 150 | |||
| 151 | /** | ||
| 152 | * \brief Host pipe token types. | ||
| 153 | */ | ||
| 154 | enum usb_host_pipe_token { | ||
| 155 | USB_HOST_PIPE_TOKEN_SETUP, | ||
| 156 | USB_HOST_PIPE_TOKEN_IN, | ||
| 157 | USB_HOST_PIPE_TOKEN_OUT, | ||
| 158 | }; | ||
| 159 | |||
| 160 | /** | ||
| 161 | * \brief Enumeration for the possible callback types for the USB in device module | ||
| 162 | */ | ||
| 163 | enum usb_device_callback { | ||
| 164 | USB_DEVICE_CALLBACK_SOF, | ||
| 165 | USB_DEVICE_CALLBACK_RESET, | ||
| 166 | USB_DEVICE_CALLBACK_WAKEUP, | ||
| 167 | USB_DEVICE_CALLBACK_RAMACER, | ||
| 168 | USB_DEVICE_CALLBACK_SUSPEND, | ||
| 169 | USB_DEVICE_CALLBACK_LPMNYET, | ||
| 170 | USB_DEVICE_CALLBACK_LPMSUSP, | ||
| 171 | USB_DEVICE_CALLBACK_N, | ||
| 172 | }; | ||
| 173 | |||
| 174 | /** | ||
| 175 | * \brief Enumeration for the possible callback types for the USB endpoint in device module | ||
| 176 | */ | ||
| 177 | enum usb_device_endpoint_callback { | ||
| 178 | USB_DEVICE_ENDPOINT_CALLBACK_TRCPT, | ||
| 179 | USB_DEVICE_ENDPOINT_CALLBACK_TRFAIL, | ||
| 180 | USB_DEVICE_ENDPOINT_CALLBACK_RXSTP, | ||
| 181 | USB_DEVICE_ENDPOINT_CALLBACK_STALL, | ||
| 182 | USB_DEVICE_EP_CALLBACK_N, | ||
| 183 | }; | ||
| 184 | |||
| 185 | /** | ||
| 186 | * \brief Device Endpoint types. | ||
| 187 | */ | ||
| 188 | enum usb_device_endpoint_type { | ||
| 189 | USB_DEVICE_ENDPOINT_TYPE_DISABLE, | ||
| 190 | USB_DEVICE_ENDPOINT_TYPE_CONTROL, | ||
| 191 | USB_DEVICE_ENDPOINT_TYPE_ISOCHRONOUS, | ||
| 192 | USB_DEVICE_ENDPOINT_TYPE_BULK, | ||
| 193 | USB_DEVICE_ENDPOINT_TYPE_INTERRUPT, | ||
| 194 | }; | ||
| 195 | |||
| 196 | /** | ||
| 197 | * \brief Endpoint Size | ||
| 198 | */ | ||
| 199 | enum usb_endpoint_size { | ||
| 200 | USB_ENDPOINT_8_BYTE, | ||
| 201 | USB_ENDPOINT_16_BYTE, | ||
| 202 | USB_ENDPOINT_32_BYTE, | ||
| 203 | USB_ENDPOINT_64_BYTE, | ||
| 204 | USB_ENDPOINT_128_BYTE, | ||
| 205 | USB_ENDPOINT_256_BYTE, | ||
| 206 | USB_ENDPOINT_512_BYTE, | ||
| 207 | USB_ENDPOINT_1023_BYTE, | ||
| 208 | }; | ||
| 209 | |||
| 210 | /** | ||
| 211 | * \brief Link Power Management Handshake. | ||
| 212 | */ | ||
| 213 | enum usb_device_lpm_mode { | ||
| 214 | USB_DEVICE_LPM_NOT_SUPPORT, | ||
| 215 | USB_DEVICE_LPM_ACK, | ||
| 216 | USB_DEVICE_LPM_NYET, | ||
| 217 | }; | ||
| 218 | |||
| 219 | /** | ||
| 220 | * \brief Module structure | ||
| 221 | */ | ||
| 222 | struct usb_module; | ||
| 223 | |||
| 224 | /** | ||
| 225 | * \name Host Callback Functions Types | ||
| 226 | * @{ | ||
| 227 | */ | ||
| 228 | typedef void (*usb_host_callback_t)(struct usb_module *module_inst); | ||
| 229 | typedef void (*usb_host_pipe_callback_t)(struct usb_module *module_inst, void *); | ||
| 230 | /** @} */ | ||
| 231 | |||
| 232 | /** | ||
| 233 | * \name Device Callback Functions Types | ||
| 234 | * @{ | ||
| 235 | */ | ||
| 236 | typedef void (*usb_device_callback_t)(struct usb_module *module_inst, void *pointer); | ||
| 237 | typedef void (*usb_device_endpoint_callback_t)(struct usb_module *module_inst, void *pointer); | ||
| 238 | /** @} */ | ||
| 239 | |||
| 240 | /** USB configurations */ | ||
| 241 | struct usb_config { | ||
| 242 | /** \c true for host, \c false for device. */ | ||
| 243 | bool select_host_mode; | ||
| 244 | /** When \c true the module is enabled during standby. */ | ||
| 245 | bool run_in_standby; | ||
| 246 | /** Generic Clock Generator source channel. */ | ||
| 247 | // enum gclk_generator source_generator; | ||
| 248 | uint8_t source_generator; | ||
| 249 | /** Speed mode */ | ||
| 250 | // enum usb_speed speed_mode; | ||
| 251 | uint8_t speed_mode; | ||
| 252 | }; | ||
| 253 | |||
| 254 | /** | ||
| 255 | * \brief USB software module instance structure. | ||
| 256 | * | ||
| 257 | * USB software module instance structure, used to retain software state | ||
| 258 | * information of an associated hardware module instance. | ||
| 259 | * | ||
| 260 | */ | ||
| 261 | struct usb_module { | ||
| 262 | /** Hardware module pointer of the associated USB peripheral. */ | ||
| 263 | Usb *hw; | ||
| 264 | |||
| 265 | /** Array to store device related callback functions */ | ||
| 266 | usb_device_callback_t device_callback[USB_DEVICE_CALLBACK_N]; | ||
| 267 | usb_device_endpoint_callback_t device_endpoint_callback[USB_EPT_NUM][USB_DEVICE_EP_CALLBACK_N]; | ||
| 268 | /** Bit mask for device callbacks registered */ | ||
| 269 | uint16_t device_registered_callback_mask; | ||
| 270 | /** Bit mask for device callbacks enabled */ | ||
| 271 | uint16_t device_enabled_callback_mask; | ||
| 272 | /** Bit mask for device endpoint callbacks registered */ | ||
| 273 | uint8_t device_endpoint_registered_callback_mask[USB_EPT_NUM]; | ||
| 274 | /** Bit mask for device endpoint callbacks enabled */ | ||
| 275 | uint8_t device_endpoint_enabled_callback_mask[USB_EPT_NUM]; | ||
| 276 | }; | ||
| 277 | |||
| 278 | /** USB device endpoint configurations */ | ||
| 279 | struct usb_device_endpoint_config { | ||
| 280 | /** device address */ | ||
| 281 | uint8_t ep_address; | ||
| 282 | /** endpoint size */ | ||
| 283 | enum usb_endpoint_size ep_size; | ||
| 284 | /** automatic zero length packet mode, \c true to enable */ | ||
| 285 | bool auto_zlp; | ||
| 286 | /** type of endpoint with Bank */ | ||
| 287 | enum usb_device_endpoint_type ep_type; | ||
| 288 | }; | ||
| 289 | |||
| 290 | /** USB device endpoint callback status parameter structure */ | ||
| 291 | struct usb_endpoint_callback_parameter { | ||
| 292 | uint16_t received_bytes; | ||
| 293 | uint16_t sent_bytes; | ||
| 294 | uint16_t out_buffer_size; | ||
| 295 | uint8_t endpoint_address; | ||
| 296 | }; | ||
| 297 | |||
| 298 | void usb_enable(struct usb_module *module_inst); | ||
| 299 | void usb_disable(struct usb_module *module_inst); | ||
| 300 | |||
| 301 | /** | ||
| 302 | * \brief Get the status of USB module's state machine | ||
| 303 | * | ||
| 304 | * \param module_inst Pointer to USB module instance | ||
| 305 | */ | ||
| 306 | static inline uint8_t usb_get_state_machine_status(struct usb_module *module_inst) { | ||
| 307 | /* Sanity check arguments */ | ||
| 308 | Assert(module_inst); | ||
| 309 | Assert(module_inst->hw); | ||
| 310 | |||
| 311 | return module_inst->hw->DEVICE.FSMSTATUS.reg; | ||
| 312 | } | ||
| 313 | |||
| 314 | void usb_get_config_defaults(struct usb_config *module_config); | ||
| 315 | enum status_code usb_init(struct usb_module *module_inst, Usb *const hw, struct usb_config *module_config); | ||
| 316 | |||
| 317 | /** | ||
| 318 | * \brief Attach USB device to the bus | ||
| 319 | * | ||
| 320 | * \param module_inst Pointer to USB device module instance | ||
| 321 | */ | ||
| 322 | static inline void usb_device_attach(struct usb_module *module_inst) { | ||
| 323 | module_inst->hw->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_DETACH; | ||
| 324 | } | ||
| 325 | |||
| 326 | /** | ||
| 327 | * \brief Detach USB device from the bus | ||
| 328 | * | ||
| 329 | * \param module_inst Pointer to USB device module instance | ||
| 330 | */ | ||
| 331 | static inline void usb_device_detach(struct usb_module *module_inst) { | ||
| 332 | module_inst->hw->DEVICE.CTRLB.reg |= USB_DEVICE_CTRLB_DETACH; | ||
| 333 | } | ||
| 334 | |||
| 335 | /** | ||
| 336 | * \brief Get the speed mode of USB device | ||
| 337 | * | ||
| 338 | * \param module_inst Pointer to USB device module instance | ||
| 339 | * \return USB Speed mode (\ref usb_speed). | ||
| 340 | */ | ||
| 341 | static inline enum usb_speed usb_device_get_speed(struct usb_module *module_inst) { | ||
| 342 | if (!(module_inst->hw->DEVICE.STATUS.reg & USB_DEVICE_STATUS_SPEED_Msk)) { | ||
| 343 | return USB_SPEED_FULL; | ||
| 344 | } else { | ||
| 345 | return USB_SPEED_LOW; | ||
| 346 | } | ||
| 347 | } | ||
| 348 | |||
| 349 | /** | ||
| 350 | * \brief Get the address of USB device | ||
| 351 | * | ||
| 352 | * \param module_inst Pointer to USB device module instance | ||
| 353 | * \return USB device address value. | ||
| 354 | */ | ||
| 355 | static inline uint8_t usb_device_get_address(struct usb_module *module_inst) { | ||
| 356 | return ((uint8_t)(module_inst->hw->DEVICE.DADD.bit.DADD)); | ||
| 357 | } | ||
| 358 | |||
| 359 | /** | ||
| 360 | * \brief Set the speed mode of USB device | ||
| 361 | * | ||
| 362 | * \param module_inst Pointer to USB device module instance | ||
| 363 | * \param address USB device address value | ||
| 364 | */ | ||
| 365 | static inline void usb_device_set_address(struct usb_module *module_inst, uint8_t address) { | ||
| 366 | module_inst->hw->DEVICE.DADD.reg = USB_DEVICE_DADD_ADDEN | address; | ||
| 367 | } | ||
| 368 | |||
| 369 | /** | ||
| 370 | * \brief Get the frame number of USB device | ||
| 371 | * | ||
| 372 | * \param module_inst Pointer to USB device module instance | ||
| 373 | * \return USB device frame number value. | ||
| 374 | */ | ||
| 375 | static inline uint16_t usb_device_get_frame_number(struct usb_module *module_inst) { | ||
| 376 | return ((uint16_t)(module_inst->hw->DEVICE.FNUM.bit.FNUM)); | ||
| 377 | } | ||
| 378 | |||
| 379 | /** | ||
| 380 | * \brief Get the micro-frame number of USB device | ||
| 381 | * | ||
| 382 | * \param module_inst Pointer to USB device module instance | ||
| 383 | * \return USB device micro-frame number value. | ||
| 384 | */ | ||
| 385 | static inline uint16_t usb_device_get_micro_frame_number(struct usb_module *module_inst) { | ||
| 386 | return ((uint16_t)(module_inst->hw->DEVICE.FNUM.reg)); | ||
| 387 | } | ||
| 388 | |||
| 389 | /** | ||
| 390 | * \brief USB device send the resume wakeup | ||
| 391 | * | ||
| 392 | * \param module_inst Pointer to USB device module instance | ||
| 393 | */ | ||
| 394 | static inline void usb_device_send_remote_wake_up(struct usb_module *module_inst) { | ||
| 395 | module_inst->hw->DEVICE.CTRLB.reg |= USB_DEVICE_CTRLB_UPRSM; | ||
| 396 | } | ||
| 397 | |||
| 398 | /** | ||
| 399 | * \brief USB device set the LPM mode | ||
| 400 | * | ||
| 401 | * \param module_inst Pointer to USB device module instance | ||
| 402 | * \param lpm_mode LPM mode | ||
| 403 | */ | ||
| 404 | static inline void usb_device_set_lpm_mode(struct usb_module *module_inst, enum usb_device_lpm_mode lpm_mode) { | ||
| 405 | module_inst->hw->DEVICE.CTRLB.bit.LPMHDSK = lpm_mode; | ||
| 406 | } | ||
| 407 | |||
| 408 | /** | ||
| 409 | * \name USB Device Callback Management | ||
| 410 | * @{ | ||
| 411 | */ | ||
| 412 | enum status_code usb_device_register_callback(struct usb_module *module_inst, enum usb_device_callback callback_type, usb_device_callback_t callback_func); | ||
| 413 | enum status_code usb_device_unregister_callback(struct usb_module *module_inst, enum usb_device_callback callback_type); | ||
| 414 | enum status_code usb_device_enable_callback(struct usb_module *module_inst, enum usb_device_callback callback_type); | ||
| 415 | enum status_code usb_device_disable_callback(struct usb_module *module_inst, enum usb_device_callback callback_type); | ||
| 416 | /** @} */ | ||
| 417 | |||
| 418 | /** | ||
| 419 | * \name USB Device Endpoint Configuration | ||
| 420 | * @{ | ||
| 421 | */ | ||
| 422 | void usb_device_endpoint_get_config_defaults(struct usb_device_endpoint_config *ep_config); | ||
| 423 | enum status_code usb_device_endpoint_set_config(struct usb_module *module_inst, struct usb_device_endpoint_config *ep_config); | ||
| 424 | bool usb_device_endpoint_is_configured(struct usb_module *module_inst, uint8_t ep); | ||
| 425 | /** @} */ | ||
| 426 | |||
| 427 | /** | ||
| 428 | * \name USB Device Endpoint Callback Management | ||
| 429 | * @{ | ||
| 430 | */ | ||
| 431 | 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); | ||
| 432 | enum status_code usb_device_endpoint_unregister_callback(struct usb_module *module_inst, uint8_t ep_num, enum usb_device_endpoint_callback callback_type); | ||
| 433 | enum status_code usb_device_endpoint_enable_callback(struct usb_module *module_inst, uint8_t ep, enum usb_device_endpoint_callback callback_type); | ||
| 434 | enum status_code usb_device_endpoint_disable_callback(struct usb_module *module_inst, uint8_t ep, enum usb_device_endpoint_callback callback_type); | ||
| 435 | /** @} */ | ||
| 436 | |||
| 437 | /** | ||
| 438 | * \name USB Device Endpoint Job Management | ||
| 439 | * @{ | ||
| 440 | */ | ||
| 441 | 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); | ||
| 442 | 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); | ||
| 443 | enum status_code usb_device_endpoint_setup_buffer_job(struct usb_module *module_inst, uint8_t *pbuf); | ||
| 444 | void usb_device_endpoint_abort_job(struct usb_module *module_inst, uint8_t ep); | ||
| 445 | /** @} */ | ||
| 446 | |||
| 447 | /** | ||
| 448 | * \name USB Device Endpoint Operations | ||
| 449 | * @{ | ||
| 450 | */ | ||
| 451 | |||
| 452 | bool usb_device_endpoint_is_halted(struct usb_module *module_inst, uint8_t ep); | ||
| 453 | void usb_device_endpoint_set_halt(struct usb_module *module_inst, uint8_t ep); | ||
| 454 | void usb_device_endpoint_clear_halt(struct usb_module *module_inst, uint8_t ep); | ||
| 455 | |||
| 456 | /** @} */ | ||
| 457 | |||
| 458 | #ifdef __cplusplus | ||
| 459 | } | ||
| 460 | #endif | ||
| 461 | |||
| 462 | #endif /* USB_H_INCLUDED */ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/usb_atmel.h b/tmk_core/protocol/arm_atsam/usb/usb_atmel.h deleted file mode 100644 index 82bafdc7d1..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/usb_atmel.h +++ /dev/null | |||
| @@ -1,189 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief All USB VIDs and PIDs from Atmel USB applications | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #ifndef _USB_ATMEL_H_ | ||
| 48 | #define _USB_ATMEL_H_ | ||
| 49 | |||
| 50 | /** | ||
| 51 | * \defgroup usb_group USB Stack | ||
| 52 | * | ||
| 53 | * This stack includes the USB Device Stack, USB Host Stack and common | ||
| 54 | * definitions. | ||
| 55 | * @{ | ||
| 56 | */ | ||
| 57 | |||
| 58 | //! @} | ||
| 59 | |||
| 60 | /** | ||
| 61 | * \ingroup usb_group | ||
| 62 | * \defgroup usb_atmel_ids_group Atmel USB Identifiers | ||
| 63 | * | ||
| 64 | * This module defines Atmel PID and VIDs constants. | ||
| 65 | * | ||
| 66 | * @{ | ||
| 67 | */ | ||
| 68 | |||
| 69 | //! \name Vendor Identifier assigned by USB org to ATMEL | ||
| 70 | #define USB_VID_ATMEL 0x03EB | ||
| 71 | |||
| 72 | //! \name Product Identifier assigned by ATMEL to AVR applications | ||
| 73 | //! @{ | ||
| 74 | |||
| 75 | //! \name The range from 2000h to 20FFh is reserved to the old PID for C51, MEGA, and others. | ||
| 76 | //! @{ | ||
| 77 | #define USB_PID_ATMEL_MEGA_HIDGENERIC 0x2013 | ||
| 78 | #define USB_PID_ATMEL_MEGA_HIDKEYBOARD 0x2017 | ||
| 79 | #define USB_PID_ATMEL_MEGA_CDC 0x2018 | ||
| 80 | #define USB_PID_ATMEL_MEGA_AUDIO_IN 0x2019 | ||
| 81 | #define USB_PID_ATMEL_MEGA_MS 0x201A | ||
| 82 | #define USB_PID_ATMEL_MEGA_AUDIO_IN_OUT 0x201B | ||
| 83 | #define USB_PID_ATMEL_MEGA_HIDMOUSE 0x201C | ||
| 84 | #define USB_PID_ATMEL_MEGA_HIDMOUSE_CERTIF_U4 0x201D | ||
| 85 | #define USB_PID_ATMEL_MEGA_CDC_MULTI 0x201E | ||
| 86 | #define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_USBKEY 0x2022 | ||
| 87 | #define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_STK525 0x2023 | ||
| 88 | #define USB_PID_ATMEL_MEGA_MS_2 0x2029 | ||
| 89 | #define USB_PID_ATMEL_MEGA_MS_HIDMS 0x202A | ||
| 90 | #define USB_PID_ATMEL_MEGA_MS_3 0x2032 | ||
| 91 | #define USB_PID_ATMEL_MEGA_LIBUSB 0x2050 | ||
| 92 | //! @} | ||
| 93 | |||
| 94 | //! \name The range 2100h to 21FFh is reserved to PIDs for AVR Tools. | ||
| 95 | //! @{ | ||
| 96 | #define USB_PID_ATMEL_XPLAINED 0x2122 | ||
| 97 | #define USB_PID_ATMEL_XMEGA_USB_ZIGBIT_2_4GHZ 0x214A | ||
| 98 | #define USB_PID_ATMEL_XMEGA_USB_ZIGBIT_SUBGHZ 0x214B | ||
| 99 | //! @} | ||
| 100 | |||
| 101 | //! \name The range 2300h to 23FFh is reserved to PIDs for demo from ASF1.7=> | ||
| 102 | //! @{ | ||
| 103 | #define USB_PID_ATMEL_UC3_ENUM 0x2300 | ||
| 104 | #define USB_PID_ATMEL_UC3_MS 0x2301 | ||
| 105 | #define USB_PID_ATMEL_UC3_MS_SDRAM_LOADER 0x2302 | ||
| 106 | #define USB_PID_ATMEL_UC3_EVK1100_CTRLPANEL 0x2303 | ||
| 107 | #define USB_PID_ATMEL_UC3_HID 0x2304 | ||
| 108 | #define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID 0x2305 | ||
| 109 | #define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID_MS 0x2306 | ||
| 110 | #define USB_PID_ATMEL_UC3_CDC 0x2307 | ||
| 111 | #define USB_PID_ATMEL_UC3_AUDIO_MICRO 0x2308 | ||
| 112 | #define USB_PID_ATMEL_UC3_CDC_DEBUG 0x2310 // Virtual Com (debug interface) on EVK11xx | ||
| 113 | #define USB_PID_ATMEL_UC3_AUDIO_SPEAKER_MICRO 0x2311 | ||
| 114 | #define USB_PID_ATMEL_UC3_CDC_MSC 0x2312 | ||
| 115 | //! @} | ||
| 116 | |||
| 117 | //! \name The range 2400h to 24FFh is reserved to PIDs for ASF applications | ||
| 118 | //! @{ | ||
| 119 | #define USB_PID_ATMEL_ASF_HIDMOUSE 0x2400 | ||
| 120 | #define USB_PID_ATMEL_ASF_HIDKEYBOARD 0x2401 | ||
| 121 | #define USB_PID_ATMEL_ASF_HIDGENERIC 0x2402 | ||
| 122 | #define USB_PID_ATMEL_ASF_MSC 0x2403 | ||
| 123 | #define USB_PID_ATMEL_ASF_CDC 0x2404 | ||
| 124 | #define USB_PID_ATMEL_ASF_PHDC 0x2405 | ||
| 125 | #define USB_PID_ATMEL_ASF_HIDMTOUCH 0x2406 | ||
| 126 | #define USB_PID_ATMEL_ASF_MSC_HIDMOUSE 0x2420 | ||
| 127 | #define USB_PID_ATMEL_ASF_MSC_HIDS_CDC 0x2421 | ||
| 128 | #define USB_PID_ATMEL_ASF_MSC_HIDKEYBOARD 0x2422 | ||
| 129 | #define USB_PID_ATMEL_ASF_VENDOR_CLASS 0x2423 | ||
| 130 | #define USB_PID_ATMEL_ASF_MSC_CDC 0x2424 | ||
| 131 | #define USB_PID_ATMEL_ASF_TWO_CDC 0x2425 | ||
| 132 | #define USB_PID_ATMEL_ASF_SEVEN_CDC 0x2426 | ||
| 133 | #define USB_PID_ATMEL_ASF_XPLAIN_BC_POWERONLY 0x2430 | ||
| 134 | #define USB_PID_ATMEL_ASF_XPLAIN_BC_TERMINAL 0x2431 | ||
| 135 | #define USB_PID_ATMEL_ASF_XPLAIN_BC_TOUCH 0x2432 | ||
| 136 | #define USB_PID_ATMEL_ASF_AUDIO_SPEAKER 0x2433 | ||
| 137 | #define USB_PID_ATMEL_ASF_XMEGA_B1_XPLAINED 0x2434 | ||
| 138 | //! @} | ||
| 139 | |||
| 140 | //! \name The range 2F00h to 2FFFh is reserved to official PIDs for AVR bootloaders | ||
| 141 | //! Note, !!!! don't use this range for demos or examples !!!! | ||
| 142 | //! @{ | ||
| 143 | #define USB_PID_ATMEL_DFU_ATXMEGA64C3 0x2FD6 | ||
| 144 | #define USB_PID_ATMEL_DFU_ATXMEGA128C3 0x2FD7 | ||
| 145 | #define USB_PID_ATMEL_DFU_ATXMEGA16C4 0x2FD8 | ||
| 146 | #define USB_PID_ATMEL_DFU_ATXMEGA32C4 0x2FD9 | ||
| 147 | #define USB_PID_ATMEL_DFU_ATXMEGA256C3 0x2FDA | ||
| 148 | #define USB_PID_ATMEL_DFU_ATXMEGA384C3 0x2FDB | ||
| 149 | #define USB_PID_ATMEL_DFU_ATUCL3_L4 0x2FDC | ||
| 150 | #define USB_PID_ATMEL_DFU_ATXMEGA64A4U 0x2FDD | ||
| 151 | #define USB_PID_ATMEL_DFU_ATXMEGA128A4U 0x2FDE | ||
| 152 | |||
| 153 | #define USB_PID_ATMEL_DFU_ATXMEGA64B3 0x2FDF | ||
| 154 | #define USB_PID_ATMEL_DFU_ATXMEGA128B3 0x2FE0 | ||
| 155 | #define USB_PID_ATMEL_DFU_ATXMEGA64B1 0x2FE1 | ||
| 156 | #define USB_PID_ATMEL_DFU_ATXMEGA256A3BU 0x2FE2 | ||
| 157 | #define USB_PID_ATMEL_DFU_ATXMEGA16A4U 0x2FE3 | ||
| 158 | #define USB_PID_ATMEL_DFU_ATXMEGA32A4U 0x2FE4 | ||
| 159 | #define USB_PID_ATMEL_DFU_ATXMEGA64A3U 0x2FE5 | ||
| 160 | #define USB_PID_ATMEL_DFU_ATXMEGA128A3U 0x2FE6 | ||
| 161 | #define USB_PID_ATMEL_DFU_ATXMEGA192A3U 0x2FE7 | ||
| 162 | #define USB_PID_ATMEL_DFU_ATXMEGA64A1U 0x2FE8 | ||
| 163 | #define USB_PID_ATMEL_DFU_ATUC3D 0x2FE9 | ||
| 164 | #define USB_PID_ATMEL_DFU_ATXMEGA128B1 0x2FEA | ||
| 165 | #define USB_PID_ATMEL_DFU_AT32UC3C 0x2FEB | ||
| 166 | #define USB_PID_ATMEL_DFU_ATXMEGA256A3U 0x2FEC | ||
| 167 | #define USB_PID_ATMEL_DFU_ATXMEGA128A1U 0x2FED | ||
| 168 | #define USB_PID_ATMEL_DFU_ATMEGA8U2 0x2FEE | ||
| 169 | #define USB_PID_ATMEL_DFU_ATMEGA16U2 0x2FEF | ||
| 170 | #define USB_PID_ATMEL_DFU_ATMEGA32U2 0x2FF0 | ||
| 171 | #define USB_PID_ATMEL_DFU_AT32UC3A3 0x2FF1 | ||
| 172 | #define USB_PID_ATMEL_DFU_ATMEGA32U6 0x2FF2 | ||
| 173 | #define USB_PID_ATMEL_DFU_ATMEGA16U4 0x2FF3 | ||
| 174 | #define USB_PID_ATMEL_DFU_ATMEGA32U4 0x2FF4 | ||
| 175 | #define USB_PID_ATMEL_DFU_AT32AP7200 0x2FF5 | ||
| 176 | #define USB_PID_ATMEL_DFU_AT32UC3B 0x2FF6 | ||
| 177 | #define USB_PID_ATMEL_DFU_AT90USB82 0x2FF7 | ||
| 178 | #define USB_PID_ATMEL_DFU_AT32UC3A 0x2FF8 | ||
| 179 | #define USB_PID_ATMEL_DFU_AT90USB64 0x2FF9 | ||
| 180 | #define USB_PID_ATMEL_DFU_AT90USB162 0x2FFA | ||
| 181 | #define USB_PID_ATMEL_DFU_AT90USB128 0x2FFB | ||
| 182 | // 2FFCh to 2FFFh used by C51 family products | ||
| 183 | //! @} | ||
| 184 | |||
| 185 | //! @} | ||
| 186 | |||
| 187 | //! @} | ||
| 188 | |||
| 189 | #endif // _USB_ATMEL_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/usb_device_udd.c b/tmk_core/protocol/arm_atsam/usb/usb_device_udd.c deleted file mode 100644 index bc5e79d9f0..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/usb_device_udd.c +++ /dev/null | |||
| @@ -1,1046 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief USB Device wrapper layer for compliance with common driver UDD | ||
| 5 | * | ||
| 6 | * Copyright (C) 2014-2016 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | #include "samd51j18a.h" | ||
| 47 | #include <string.h> | ||
| 48 | #include <stdlib.h> | ||
| 49 | |||
| 50 | // Get USB device configuration | ||
| 51 | #include "conf_usb.h" | ||
| 52 | #include "udd.h" | ||
| 53 | #include "usb.h" | ||
| 54 | #include "status_codes.h" | ||
| 55 | |||
| 56 | /** | ||
| 57 | * \ingroup usb_device_group | ||
| 58 | * \defgroup usb_device_udd_group USB Device Driver Implement (UDD) | ||
| 59 | * USB low-level driver for USB device mode | ||
| 60 | * @{ | ||
| 61 | */ | ||
| 62 | // Check USB device configuration | ||
| 63 | #ifdef USB_DEVICE_HS_SUPPORT | ||
| 64 | # error The High speed mode is not supported on this part, please remove USB_DEVICE_HS_SUPPORT in conf_usb.h | ||
| 65 | #endif | ||
| 66 | |||
| 67 | // Note: This driver is adapted for SAMD51 | ||
| 68 | |||
| 69 | #ifndef UDC_REMOTEWAKEUP_LPM_ENABLE | ||
| 70 | # define UDC_REMOTEWAKEUP_LPM_ENABLE() | ||
| 71 | #endif | ||
| 72 | #ifndef UDC_REMOTEWAKEUP_LPM_DISABLE | ||
| 73 | # define UDC_REMOTEWAKEUP_LPM_DISABLE() | ||
| 74 | #endif | ||
| 75 | #ifndef UDC_SUSPEND_LPM_EVENT | ||
| 76 | # define UDC_SUSPEND_LPM_EVENT() | ||
| 77 | #endif | ||
| 78 | |||
| 79 | /* for debug text */ | ||
| 80 | #ifdef USB_DEBUG | ||
| 81 | # define dbg_print printf | ||
| 82 | #else | ||
| 83 | # define dbg_print(...) | ||
| 84 | #endif | ||
| 85 | |||
| 86 | /** Maximum size of a transfer in multi-packet mode */ | ||
| 87 | #define UDD_ENDPOINT_MAX_TRANS ((8 * 1024) - 1) | ||
| 88 | |||
| 89 | /** USB software device instance structure */ | ||
| 90 | struct usb_module usb_device; | ||
| 91 | |||
| 92 | /** | ||
| 93 | * \name Clock management | ||
| 94 | * | ||
| 95 | * @{ | ||
| 96 | */ | ||
| 97 | |||
| 98 | #define UDD_CLOCK_GEN 0 | ||
| 99 | |||
| 100 | static inline void udd_wait_clock_ready(void) {} | ||
| 101 | |||
| 102 | /** | ||
| 103 | * \name Power management | ||
| 104 | * | ||
| 105 | * @{ | ||
| 106 | */ | ||
| 107 | #define udd_sleep_mode(arg) | ||
| 108 | /** @} */ | ||
| 109 | |||
| 110 | /** | ||
| 111 | * \name Control endpoint low level management routine. | ||
| 112 | * | ||
| 113 | * This function performs control endpoint management. | ||
| 114 | * It handles the SETUP/DATA/HANDSHAKE phases of a control transaction. | ||
| 115 | * | ||
| 116 | * @{ | ||
| 117 | */ | ||
| 118 | |||
| 119 | /** | ||
| 120 | * \brief Buffer to store the data received on control endpoint (SETUP/OUT endpoint 0) | ||
| 121 | * | ||
| 122 | * Used to avoid a RAM buffer overflow in case of the payload buffer | ||
| 123 | * is smaller than control endpoint size | ||
| 124 | */ | ||
| 125 | UDC_BSS(4) | ||
| 126 | uint8_t udd_ctrl_buffer[USB_DEVICE_EP_CTRL_SIZE]; | ||
| 127 | |||
| 128 | /** Bit definitions about endpoint control state machine for udd_ep_control_state */ | ||
| 129 | typedef enum { | ||
| 130 | UDD_EPCTRL_SETUP = 0, //!< Wait a SETUP packet | ||
| 131 | UDD_EPCTRL_DATA_OUT = 1, //!< Wait a OUT data packet | ||
| 132 | UDD_EPCTRL_DATA_IN = 2, //!< Wait a IN data packet | ||
| 133 | UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP = 3, //!< Wait a IN ZLP packet | ||
| 134 | UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP = 4, //!< Wait a OUT ZLP packet | ||
| 135 | UDD_EPCTRL_STALL_REQ = 5, //!< STALL enabled on IN & OUT packet | ||
| 136 | } udd_ctrl_ep_state_t; | ||
| 137 | |||
| 138 | /** Global variable to give and record information of the set up request management */ | ||
| 139 | udd_ctrl_request_t udd_g_ctrlreq; | ||
| 140 | |||
| 141 | /** State of the endpoint control management */ | ||
| 142 | static udd_ctrl_ep_state_t udd_ep_control_state; | ||
| 143 | |||
| 144 | /** Total number of data received/sent during data packet phase with previous payload buffers */ | ||
| 145 | static uint16_t udd_ctrl_prev_payload_nb_trans; | ||
| 146 | |||
| 147 | /** Number of data received/sent to/from udd_g_ctrlreq.payload buffer */ | ||
| 148 | static uint16_t udd_ctrl_payload_nb_trans; | ||
| 149 | |||
| 150 | /** @} */ | ||
| 151 | |||
| 152 | /** | ||
| 153 | * \name Management of bulk/interrupt/isochronous endpoints | ||
| 154 | * | ||
| 155 | * The UDD manages the data transfer on endpoints: | ||
| 156 | * - Start data transfer on endpoint with USB Device DMA | ||
| 157 | * - Send a ZLP packet if requested | ||
| 158 | * - Call callback registered to signal end of transfer | ||
| 159 | * The transfer abort and stall feature are supported. | ||
| 160 | * | ||
| 161 | * @{ | ||
| 162 | */ | ||
| 163 | |||
| 164 | /** | ||
| 165 | * \brief Buffer to store the data received on bulk/interrupt endpoints | ||
| 166 | * | ||
| 167 | * Used to avoid a RAM buffer overflow in case of the user buffer | ||
| 168 | * is smaller than endpoint size | ||
| 169 | * | ||
| 170 | * \warning The protected interrupt endpoint size is 512 bytes maximum. | ||
| 171 | * \warning The isochronous and endpoint is not protected by this system and | ||
| 172 | * the user must always use a buffer corresponding at endpoint size. | ||
| 173 | */ | ||
| 174 | |||
| 175 | #if (defined USB_DEVICE_LOW_SPEED) | ||
| 176 | UDC_BSS(4) uint8_t udd_ep_out_cache_buffer[USB_DEVICE_MAX_EP][8]; | ||
| 177 | #elif (defined USB_DEVICE_HS_SUPPORT) | ||
| 178 | UDC_BSS(4) uint8_t udd_ep_out_cache_buffer[USB_DEVICE_MAX_EP][512]; | ||
| 179 | #else | ||
| 180 | UDC_BSS(4) uint8_t udd_ep_out_cache_buffer[USB_DEVICE_MAX_EP][64]; | ||
| 181 | #endif | ||
| 182 | |||
| 183 | /** Structure definition about job registered on an endpoint */ | ||
| 184 | typedef struct { | ||
| 185 | union { | ||
| 186 | //! Callback to call at the end of transfer | ||
| 187 | udd_callback_trans_t call_trans; | ||
| 188 | //! Callback to call when the endpoint halt is cleared | ||
| 189 | udd_callback_halt_cleared_t call_nohalt; | ||
| 190 | }; | ||
| 191 | //! Buffer located in internal RAM to send or fill during job | ||
| 192 | uint8_t *buf; | ||
| 193 | //! Size of buffer to send or fill | ||
| 194 | iram_size_t buf_size; | ||
| 195 | //! Total number of data transferred on endpoint | ||
| 196 | iram_size_t nb_trans; | ||
| 197 | //! Endpoint size | ||
| 198 | uint16_t ep_size; | ||
| 199 | //! A job is registered on this endpoint | ||
| 200 | uint8_t busy : 1; | ||
| 201 | //! A short packet is requested for this job on endpoint IN | ||
| 202 | uint8_t b_shortpacket : 1; | ||
| 203 | //! The cache buffer is currently used on endpoint OUT | ||
| 204 | uint8_t b_use_out_cache_buffer : 1; | ||
| 205 | } udd_ep_job_t; | ||
| 206 | |||
| 207 | /** Array to register a job on bulk/interrupt/isochronous endpoint */ | ||
| 208 | static udd_ep_job_t udd_ep_job[2 * USB_DEVICE_MAX_EP]; | ||
| 209 | |||
| 210 | /** @} */ | ||
| 211 | |||
| 212 | /** | ||
| 213 | * \brief Get the detailed job by endpoint number | ||
| 214 | * \param[in] ep Endpoint Address | ||
| 215 | * \retval pointer to an udd_ep_job_t structure instance | ||
| 216 | */ | ||
| 217 | static udd_ep_job_t *udd_ep_get_job(udd_ep_id_t ep) { | ||
| 218 | if ((ep == 0) || (ep == 0x80)) { | ||
| 219 | return NULL; | ||
| 220 | } else { | ||
| 221 | return &udd_ep_job[(2 * (ep & USB_EP_ADDR_MASK) + ((ep & USB_EP_DIR_IN) ? 1 : 0)) - 2]; | ||
| 222 | } | ||
| 223 | } | ||
| 224 | |||
| 225 | /** | ||
| 226 | * \brief Endpoint IN process, continue to send packets or zero length packet | ||
| 227 | * \param[in] pointer Pointer to the endpoint transfer status parameter struct from driver layer. | ||
| 228 | */ | ||
| 229 | static void udd_ep_trans_in_next(void *pointer) { | ||
| 230 | struct usb_endpoint_callback_parameter *ep_callback_para = (struct usb_endpoint_callback_parameter *)pointer; | ||
| 231 | udd_ep_id_t ep = ep_callback_para->endpoint_address; | ||
| 232 | uint16_t ep_size, nb_trans; | ||
| 233 | uint16_t next_trans; | ||
| 234 | udd_ep_id_t ep_num; | ||
| 235 | udd_ep_job_t * ptr_job; | ||
| 236 | |||
| 237 | ptr_job = udd_ep_get_job(ep); | ||
| 238 | ep_num = ep & USB_EP_ADDR_MASK; | ||
| 239 | |||
| 240 | ep_size = ptr_job->ep_size; | ||
| 241 | /* Update number of data transferred */ | ||
| 242 | nb_trans = ep_callback_para->sent_bytes; | ||
| 243 | ptr_job->nb_trans += nb_trans; | ||
| 244 | |||
| 245 | /* Need to send other data */ | ||
| 246 | if (ptr_job->nb_trans != ptr_job->buf_size) { | ||
| 247 | next_trans = ptr_job->buf_size - ptr_job->nb_trans; | ||
| 248 | if (UDD_ENDPOINT_MAX_TRANS < next_trans) { | ||
| 249 | /* The USB hardware support a maximum | ||
| 250 | * transfer size of UDD_ENDPOINT_MAX_TRANS Bytes */ | ||
| 251 | next_trans = UDD_ENDPOINT_MAX_TRANS - (UDD_ENDPOINT_MAX_TRANS % ep_size); | ||
| 252 | } | ||
| 253 | /* Need ZLP, if requested and last packet is not a short packet */ | ||
| 254 | ptr_job->b_shortpacket = ptr_job->b_shortpacket && (0 == (next_trans % ep_size)); | ||
| 255 | usb_device_endpoint_write_buffer_job(&usb_device, ep_num, &ptr_job->buf[ptr_job->nb_trans], next_trans); | ||
| 256 | return; | ||
| 257 | } | ||
| 258 | |||
| 259 | /* Need to send a ZLP after all data transfer */ | ||
| 260 | if (ptr_job->b_shortpacket) { | ||
| 261 | ptr_job->b_shortpacket = false; | ||
| 262 | /* Start new transfer */ | ||
| 263 | usb_device_endpoint_write_buffer_job(&usb_device, ep_num, &ptr_job->buf[ptr_job->nb_trans], 0); | ||
| 264 | return; | ||
| 265 | } | ||
| 266 | |||
| 267 | /* Job complete then call callback */ | ||
| 268 | ptr_job->busy = false; | ||
| 269 | if (NULL != ptr_job->call_trans) { | ||
| 270 | ptr_job->call_trans(UDD_EP_TRANSFER_OK, ptr_job->nb_trans, ep); | ||
| 271 | } | ||
| 272 | } | ||
| 273 | |||
| 274 | /** | ||
| 275 | * \brief Endpoint OUT process, continue to receive packets or zero length packet | ||
| 276 | * \param[in] pointer Pointer to the endpoint transfer status parameter struct from driver layer. | ||
| 277 | */ | ||
| 278 | static void udd_ep_trans_out_next(void *pointer) { | ||
| 279 | struct usb_endpoint_callback_parameter *ep_callback_para = (struct usb_endpoint_callback_parameter *)pointer; | ||
| 280 | udd_ep_id_t ep = ep_callback_para->endpoint_address; | ||
| 281 | uint16_t ep_size, nb_trans; | ||
| 282 | uint16_t next_trans; | ||
| 283 | udd_ep_id_t ep_num; | ||
| 284 | udd_ep_job_t * ptr_job; | ||
| 285 | |||
| 286 | ptr_job = udd_ep_get_job(ep); | ||
| 287 | ep_num = ep & USB_EP_ADDR_MASK; | ||
| 288 | |||
| 289 | ep_size = ptr_job->ep_size; | ||
| 290 | /* Update number of data transferred */ | ||
| 291 | nb_trans = ep_callback_para->received_bytes; | ||
| 292 | |||
| 293 | /* Can be necessary to copy data receive from cache buffer to user buffer */ | ||
| 294 | if (ptr_job->b_use_out_cache_buffer) { | ||
| 295 | memcpy(&ptr_job->buf[ptr_job->nb_trans], udd_ep_out_cache_buffer[ep_num - 1], ptr_job->buf_size % ep_size); | ||
| 296 | } | ||
| 297 | |||
| 298 | /* Update number of data transferred */ | ||
| 299 | ptr_job->nb_trans += nb_trans; | ||
| 300 | if (ptr_job->nb_trans > ptr_job->buf_size) { | ||
| 301 | ptr_job->nb_trans = ptr_job->buf_size; | ||
| 302 | } | ||
| 303 | |||
| 304 | /* If all previous data requested are received and user buffer not full | ||
| 305 | * then need to receive other data */ | ||
| 306 | if ((nb_trans == ep_callback_para->out_buffer_size) && (ptr_job->nb_trans != ptr_job->buf_size)) { | ||
| 307 | next_trans = ptr_job->buf_size - ptr_job->nb_trans; | ||
| 308 | if (UDD_ENDPOINT_MAX_TRANS < next_trans) { | ||
| 309 | /* The USB hardware support a maximum transfer size | ||
| 310 | * of UDD_ENDPOINT_MAX_TRANS Bytes */ | ||
| 311 | next_trans = UDD_ENDPOINT_MAX_TRANS - (UDD_ENDPOINT_MAX_TRANS % ep_size); | ||
| 312 | } else { | ||
| 313 | next_trans -= next_trans % ep_size; | ||
| 314 | } | ||
| 315 | |||
| 316 | if (next_trans < ep_size) { | ||
| 317 | /* Use the cache buffer for Bulk or Interrupt size endpoint */ | ||
| 318 | ptr_job->b_use_out_cache_buffer = true; | ||
| 319 | usb_device_endpoint_read_buffer_job(&usb_device, ep_num, udd_ep_out_cache_buffer[ep_num - 1], ep_size); | ||
| 320 | } else { | ||
| 321 | usb_device_endpoint_read_buffer_job(&usb_device, ep_num, &ptr_job->buf[ptr_job->nb_trans], next_trans); | ||
| 322 | } | ||
| 323 | return; | ||
| 324 | } | ||
| 325 | |||
| 326 | /* Job complete then call callback */ | ||
| 327 | ptr_job->busy = false; | ||
| 328 | if (NULL != ptr_job->call_trans) { | ||
| 329 | ptr_job->call_trans(UDD_EP_TRANSFER_OK, ptr_job->nb_trans, ep); | ||
| 330 | } | ||
| 331 | } | ||
| 332 | |||
| 333 | /** | ||
| 334 | * \brief Endpoint Transfer Complete callback function, to do the next transfer depends on the direction(IN or OUT) | ||
| 335 | * \param[in] module_inst Pointer to USB module instance | ||
| 336 | * \param[in] pointer Pointer to the endpoint transfer status parameter struct from driver layer. | ||
| 337 | */ | ||
| 338 | static void udd_ep_transfer_process(struct usb_module *module_inst, void *pointer) { | ||
| 339 | struct usb_endpoint_callback_parameter *ep_callback_para = (struct usb_endpoint_callback_parameter *)pointer; | ||
| 340 | udd_ep_id_t ep = ep_callback_para->endpoint_address; | ||
| 341 | |||
| 342 | if (ep & USB_EP_DIR_IN) { | ||
| 343 | udd_ep_trans_in_next(pointer); | ||
| 344 | } else { | ||
| 345 | udd_ep_trans_out_next(pointer); | ||
| 346 | } | ||
| 347 | } | ||
| 348 | |||
| 349 | void udd_ep_abort(udd_ep_id_t ep) { | ||
| 350 | udd_ep_job_t *ptr_job; | ||
| 351 | |||
| 352 | usb_device_endpoint_abort_job(&usb_device, ep); | ||
| 353 | |||
| 354 | /* Job complete then call callback */ | ||
| 355 | ptr_job = udd_ep_get_job(ep); | ||
| 356 | if (!ptr_job->busy) { | ||
| 357 | return; | ||
| 358 | } | ||
| 359 | ptr_job->busy = false; | ||
| 360 | if (NULL != ptr_job->call_trans) { | ||
| 361 | /* It can be a Transfer or stall callback */ | ||
| 362 | ptr_job->call_trans(UDD_EP_TRANSFER_ABORT, ptr_job->nb_trans, ep); | ||
| 363 | } | ||
| 364 | } | ||
| 365 | |||
| 366 | bool udd_is_high_speed(void) { | ||
| 367 | return false; | ||
| 368 | } | ||
| 369 | |||
| 370 | uint16_t udd_get_frame_number(void) { | ||
| 371 | return usb_device_get_frame_number(&usb_device); | ||
| 372 | } | ||
| 373 | |||
| 374 | uint16_t udd_get_micro_frame_number(void) { | ||
| 375 | return usb_device_get_micro_frame_number(&usb_device); | ||
| 376 | } | ||
| 377 | |||
| 378 | void udd_ep_free(udd_ep_id_t ep) { | ||
| 379 | struct usb_device_endpoint_config config_ep; | ||
| 380 | usb_device_endpoint_get_config_defaults(&config_ep); | ||
| 381 | |||
| 382 | uint8_t ep_num = ep & USB_EP_ADDR_MASK; | ||
| 383 | udd_ep_abort(ep); | ||
| 384 | |||
| 385 | config_ep.ep_address = ep; | ||
| 386 | config_ep.ep_type = USB_DEVICE_ENDPOINT_TYPE_DISABLE; | ||
| 387 | usb_device_endpoint_set_config(&usb_device, &config_ep); | ||
| 388 | usb_device_endpoint_unregister_callback(&usb_device, ep_num, USB_DEVICE_ENDPOINT_CALLBACK_TRCPT); | ||
| 389 | usb_device_endpoint_disable_callback(&usb_device, ep, USB_DEVICE_ENDPOINT_CALLBACK_TRCPT); | ||
| 390 | } | ||
| 391 | |||
| 392 | bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, uint16_t MaxEndpointSize) { | ||
| 393 | struct usb_device_endpoint_config config_ep; | ||
| 394 | usb_device_endpoint_get_config_defaults(&config_ep); | ||
| 395 | |||
| 396 | config_ep.ep_address = ep; | ||
| 397 | |||
| 398 | if (MaxEndpointSize <= 8) { | ||
| 399 | config_ep.ep_size = USB_ENDPOINT_8_BYTE; | ||
| 400 | } else if (MaxEndpointSize <= 16) { | ||
| 401 | config_ep.ep_size = USB_ENDPOINT_16_BYTE; | ||
| 402 | } else if (MaxEndpointSize <= 32) { | ||
| 403 | config_ep.ep_size = USB_ENDPOINT_32_BYTE; | ||
| 404 | } else if (MaxEndpointSize <= 64) { | ||
| 405 | config_ep.ep_size = USB_ENDPOINT_64_BYTE; | ||
| 406 | } else if (MaxEndpointSize <= 128) { | ||
| 407 | config_ep.ep_size = USB_ENDPOINT_128_BYTE; | ||
| 408 | } else if (MaxEndpointSize <= 256) { | ||
| 409 | config_ep.ep_size = USB_ENDPOINT_256_BYTE; | ||
| 410 | } else if (MaxEndpointSize <= 512) { | ||
| 411 | config_ep.ep_size = USB_ENDPOINT_512_BYTE; | ||
| 412 | } else if (MaxEndpointSize <= 1023) { | ||
| 413 | config_ep.ep_size = USB_ENDPOINT_1023_BYTE; | ||
| 414 | } else { | ||
| 415 | return false; | ||
| 416 | } | ||
| 417 | udd_ep_job_t *ptr_job = udd_ep_get_job(ep); | ||
| 418 | ptr_job->ep_size = MaxEndpointSize; | ||
| 419 | |||
| 420 | bmAttributes = bmAttributes & USB_EP_TYPE_MASK; | ||
| 421 | |||
| 422 | /* Check endpoint type */ | ||
| 423 | if (USB_EP_TYPE_ISOCHRONOUS == bmAttributes) { | ||
| 424 | config_ep.ep_type = USB_DEVICE_ENDPOINT_TYPE_ISOCHRONOUS; | ||
| 425 | } else if (USB_EP_TYPE_BULK == bmAttributes) { | ||
| 426 | config_ep.ep_type = USB_DEVICE_ENDPOINT_TYPE_BULK; | ||
| 427 | } else if (USB_EP_TYPE_INTERRUPT == bmAttributes) { | ||
| 428 | config_ep.ep_type = USB_DEVICE_ENDPOINT_TYPE_INTERRUPT; | ||
| 429 | } else { | ||
| 430 | return false; | ||
| 431 | } | ||
| 432 | |||
| 433 | uint8_t ep_num = ep & USB_EP_ADDR_MASK; | ||
| 434 | |||
| 435 | if (STATUS_OK != usb_device_endpoint_set_config(&usb_device, &config_ep)) { | ||
| 436 | return false; | ||
| 437 | } | ||
| 438 | usb_device_endpoint_register_callback(&usb_device, ep_num, USB_DEVICE_ENDPOINT_CALLBACK_TRCPT, udd_ep_transfer_process); | ||
| 439 | usb_device_endpoint_enable_callback(&usb_device, ep, USB_DEVICE_ENDPOINT_CALLBACK_TRCPT); | ||
| 440 | usb_device_endpoint_enable_callback(&usb_device, ep, USB_DEVICE_ENDPOINT_CALLBACK_TRFAIL); | ||
| 441 | |||
| 442 | return true; | ||
| 443 | } | ||
| 444 | |||
| 445 | bool udd_ep_is_halted(udd_ep_id_t ep) { | ||
| 446 | return usb_device_endpoint_is_halted(&usb_device, ep); | ||
| 447 | } | ||
| 448 | |||
| 449 | bool udd_ep_set_halt(udd_ep_id_t ep) { | ||
| 450 | uint8_t ep_num = ep & USB_EP_ADDR_MASK; | ||
| 451 | |||
| 452 | if (USB_DEVICE_MAX_EP < ep_num) { | ||
| 453 | return false; | ||
| 454 | } | ||
| 455 | |||
| 456 | usb_device_endpoint_set_halt(&usb_device, ep); | ||
| 457 | |||
| 458 | udd_ep_abort(ep); | ||
| 459 | return true; | ||
| 460 | } | ||
| 461 | |||
| 462 | bool udd_ep_clear_halt(udd_ep_id_t ep) { | ||
| 463 | udd_ep_job_t *ptr_job; | ||
| 464 | uint8_t ep_num = ep & USB_EP_ADDR_MASK; | ||
| 465 | |||
| 466 | if (USB_DEVICE_MAX_EP < ep_num) { | ||
| 467 | return false; | ||
| 468 | } | ||
| 469 | ptr_job = udd_ep_get_job(ep); | ||
| 470 | |||
| 471 | usb_device_endpoint_clear_halt(&usb_device, ep); | ||
| 472 | |||
| 473 | /* If a job is register on clear halt action then execute callback */ | ||
| 474 | if (ptr_job->busy == true) { | ||
| 475 | ptr_job->busy = false; | ||
| 476 | ptr_job->call_nohalt(); | ||
| 477 | } | ||
| 478 | |||
| 479 | return true; | ||
| 480 | } | ||
| 481 | |||
| 482 | bool udd_ep_wait_stall_clear(udd_ep_id_t ep, udd_callback_halt_cleared_t callback) { | ||
| 483 | udd_ep_id_t ep_num; | ||
| 484 | udd_ep_job_t *ptr_job; | ||
| 485 | |||
| 486 | ep_num = ep & USB_EP_ADDR_MASK; | ||
| 487 | if (USB_DEVICE_MAX_EP < ep_num) { | ||
| 488 | return false; | ||
| 489 | } | ||
| 490 | |||
| 491 | ptr_job = udd_ep_get_job(ep); | ||
| 492 | if (ptr_job->busy == true) { | ||
| 493 | return false; /* Job already on going */ | ||
| 494 | } | ||
| 495 | |||
| 496 | /* Wait clear halt endpoint */ | ||
| 497 | if (usb_device_endpoint_is_halted(&usb_device, ep)) { | ||
| 498 | /* Endpoint halted then registers the callback */ | ||
| 499 | ptr_job->busy = true; | ||
| 500 | ptr_job->call_nohalt = callback; | ||
| 501 | return true; | ||
| 502 | } else if (usb_device_endpoint_is_configured(&usb_device, ep)) { | ||
| 503 | callback(); /* Endpoint not halted then call directly callback */ | ||
| 504 | return true; | ||
| 505 | } else { | ||
| 506 | return false; | ||
| 507 | } | ||
| 508 | } | ||
| 509 | |||
| 510 | /** | ||
| 511 | * \brief Control Endpoint stall sending data | ||
| 512 | */ | ||
| 513 | static void udd_ctrl_stall_data(void) { | ||
| 514 | udd_ep_control_state = UDD_EPCTRL_STALL_REQ; | ||
| 515 | |||
| 516 | usb_device_endpoint_set_halt(&usb_device, USB_EP_DIR_IN); | ||
| 517 | usb_device_endpoint_clear_halt(&usb_device, USB_EP_DIR_OUT); | ||
| 518 | } | ||
| 519 | |||
| 520 | 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) { | ||
| 521 | udd_ep_id_t ep_num; | ||
| 522 | udd_ep_job_t *ptr_job; | ||
| 523 | uint32_t irqflags; | ||
| 524 | |||
| 525 | ep_num = ep & USB_EP_ADDR_MASK; | ||
| 526 | |||
| 527 | if ((USB_DEVICE_MAX_EP < ep_num) || (udd_ep_is_halted(ep))) { | ||
| 528 | return false; | ||
| 529 | } | ||
| 530 | |||
| 531 | ptr_job = udd_ep_get_job(ep); | ||
| 532 | |||
| 533 | irqflags = __get_PRIMASK(); | ||
| 534 | __disable_irq(); | ||
| 535 | __DMB(); | ||
| 536 | |||
| 537 | if (ptr_job->busy == true) { | ||
| 538 | __DMB(); | ||
| 539 | __set_PRIMASK(irqflags); | ||
| 540 | return false; /* Job already on going */ | ||
| 541 | } | ||
| 542 | |||
| 543 | ptr_job->busy = true; | ||
| 544 | __DMB(); | ||
| 545 | __set_PRIMASK(irqflags); | ||
| 546 | |||
| 547 | /* No job running, set up a new one */ | ||
| 548 | ptr_job->buf = buf; | ||
| 549 | ptr_job->buf_size = buf_size; | ||
| 550 | ptr_job->nb_trans = 0; | ||
| 551 | ptr_job->call_trans = callback; | ||
| 552 | ptr_job->b_shortpacket = b_shortpacket; | ||
| 553 | ptr_job->b_use_out_cache_buffer = false; | ||
| 554 | |||
| 555 | /* Initialize value to simulate a empty transfer */ | ||
| 556 | uint16_t next_trans; | ||
| 557 | |||
| 558 | if (ep & USB_EP_DIR_IN) { | ||
| 559 | if (0 != ptr_job->buf_size) { | ||
| 560 | next_trans = ptr_job->buf_size; | ||
| 561 | if (UDD_ENDPOINT_MAX_TRANS < next_trans) { | ||
| 562 | next_trans = UDD_ENDPOINT_MAX_TRANS - (UDD_ENDPOINT_MAX_TRANS % ptr_job->ep_size); | ||
| 563 | } | ||
| 564 | ptr_job->b_shortpacket = ptr_job->b_shortpacket && (0 == (next_trans % ptr_job->ep_size)); | ||
| 565 | } else if (true == ptr_job->b_shortpacket) { | ||
| 566 | ptr_job->b_shortpacket = false; /* avoid to send zero length packet again */ | ||
| 567 | next_trans = 0; | ||
| 568 | } else { | ||
| 569 | ptr_job->busy = false; | ||
| 570 | if (NULL != ptr_job->call_trans) { | ||
| 571 | ptr_job->call_trans(UDD_EP_TRANSFER_OK, 0, ep); | ||
| 572 | } | ||
| 573 | return true; | ||
| 574 | } | ||
| 575 | return (STATUS_OK == usb_device_endpoint_write_buffer_job(&usb_device, ep_num, &ptr_job->buf[0], next_trans)); | ||
| 576 | } else { | ||
| 577 | if (0 != ptr_job->buf_size) { | ||
| 578 | next_trans = ptr_job->buf_size; | ||
| 579 | if (UDD_ENDPOINT_MAX_TRANS < next_trans) { | ||
| 580 | /* The USB hardware support a maximum transfer size | ||
| 581 | * of UDD_ENDPOINT_MAX_TRANS Bytes */ | ||
| 582 | next_trans = UDD_ENDPOINT_MAX_TRANS - (UDD_ENDPOINT_MAX_TRANS % ptr_job->ep_size); | ||
| 583 | } else { | ||
| 584 | next_trans -= next_trans % ptr_job->ep_size; | ||
| 585 | } | ||
| 586 | if (next_trans < ptr_job->ep_size) { | ||
| 587 | ptr_job->b_use_out_cache_buffer = true; | ||
| 588 | return (STATUS_OK == usb_device_endpoint_read_buffer_job(&usb_device, ep_num, udd_ep_out_cache_buffer[ep_num - 1], ptr_job->ep_size)); | ||
| 589 | } else { | ||
| 590 | return (STATUS_OK == usb_device_endpoint_read_buffer_job(&usb_device, ep_num, &ptr_job->buf[0], next_trans)); | ||
| 591 | } | ||
| 592 | } else { | ||
| 593 | ptr_job->busy = false; | ||
| 594 | if (NULL != ptr_job->call_trans) { | ||
| 595 | ptr_job->call_trans(UDD_EP_TRANSFER_OK, 0, ep); | ||
| 596 | } | ||
| 597 | return true; | ||
| 598 | } | ||
| 599 | } | ||
| 600 | } | ||
| 601 | |||
| 602 | void udd_set_address(uint8_t address) { | ||
| 603 | usb_device_set_address(&usb_device, address); | ||
| 604 | } | ||
| 605 | |||
| 606 | uint8_t udd_getaddress(void) { | ||
| 607 | return usb_device_get_address(&usb_device); | ||
| 608 | } | ||
| 609 | |||
| 610 | void udd_send_remotewakeup(void) { | ||
| 611 | uint32_t try = 5; | ||
| 612 | udd_wait_clock_ready(); | ||
| 613 | udd_sleep_mode(UDD_STATE_IDLE); | ||
| 614 | while (2 != usb_get_state_machine_status(&usb_device) && try--) { | ||
| 615 | usb_device_send_remote_wake_up(&usb_device); | ||
| 616 | } | ||
| 617 | } | ||
| 618 | |||
| 619 | void udd_set_setup_payload(uint8_t *payload, uint16_t payload_size) { | ||
| 620 | udd_g_ctrlreq.payload = payload; | ||
| 621 | udd_g_ctrlreq.payload_size = payload_size; | ||
| 622 | } | ||
| 623 | |||
| 624 | /** | ||
| 625 | * \brief Control Endpoint translate the data in buffer into Device Request Struct | ||
| 626 | */ | ||
| 627 | static void udd_ctrl_fetch_ram(void) { | ||
| 628 | udd_g_ctrlreq.req.bmRequestType = udd_ctrl_buffer[0]; | ||
| 629 | udd_g_ctrlreq.req.bRequest = udd_ctrl_buffer[1]; | ||
| 630 | udd_g_ctrlreq.req.wValue = ((uint16_t)(udd_ctrl_buffer[3]) << 8) + udd_ctrl_buffer[2]; | ||
| 631 | udd_g_ctrlreq.req.wIndex = ((uint16_t)(udd_ctrl_buffer[5]) << 8) + udd_ctrl_buffer[4]; | ||
| 632 | udd_g_ctrlreq.req.wLength = ((uint16_t)(udd_ctrl_buffer[7]) << 8) + udd_ctrl_buffer[6]; | ||
| 633 | } | ||
| 634 | |||
| 635 | /** | ||
| 636 | * \brief Control Endpoint send out zero length packet | ||
| 637 | */ | ||
| 638 | static void udd_ctrl_send_zlp_in(void) { | ||
| 639 | udd_ep_control_state = UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP; | ||
| 640 | usb_device_endpoint_setup_buffer_job(&usb_device, udd_ctrl_buffer); | ||
| 641 | usb_device_endpoint_write_buffer_job(&usb_device, 0, udd_g_ctrlreq.payload, 0); | ||
| 642 | } | ||
| 643 | |||
| 644 | /** | ||
| 645 | * \brief Process control endpoint IN transaction | ||
| 646 | */ | ||
| 647 | static void udd_ctrl_in_sent(void) { | ||
| 648 | static bool b_shortpacket = false; | ||
| 649 | uint16_t nb_remain; | ||
| 650 | |||
| 651 | nb_remain = udd_g_ctrlreq.payload_size - udd_ctrl_payload_nb_trans; | ||
| 652 | |||
| 653 | if (0 == nb_remain) { | ||
| 654 | /* All content of current buffer payload are sent Update number of total data sending by previous payload buffer */ | ||
| 655 | udd_ctrl_prev_payload_nb_trans += udd_ctrl_payload_nb_trans; | ||
| 656 | if ((udd_g_ctrlreq.req.wLength == udd_ctrl_prev_payload_nb_trans) || b_shortpacket) { | ||
| 657 | /* All data requested are transferred or a short packet has been sent, then it is the end of data phase. | ||
| 658 | * Generate an OUT ZLP for handshake phase */ | ||
| 659 | udd_ep_control_state = UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP; | ||
| 660 | usb_device_endpoint_setup_buffer_job(&usb_device, udd_ctrl_buffer); | ||
| 661 | return; | ||
| 662 | } | ||
| 663 | /* Need of new buffer because the data phase is not complete */ | ||
| 664 | if ((!udd_g_ctrlreq.over_under_run) || (!udd_g_ctrlreq.over_under_run())) { | ||
| 665 | /* Under run then send zlp on IN | ||
| 666 | * Here nb_remain=0, this allows to send a IN ZLP */ | ||
| 667 | } else { | ||
| 668 | /* A new payload buffer is given */ | ||
| 669 | udd_ctrl_payload_nb_trans = 0; | ||
| 670 | nb_remain = udd_g_ctrlreq.payload_size; | ||
| 671 | } | ||
| 672 | } | ||
| 673 | |||
| 674 | /* Continue transfer and send next data */ | ||
| 675 | if (nb_remain >= USB_DEVICE_EP_CTRL_SIZE) { | ||
| 676 | nb_remain = USB_DEVICE_EP_CTRL_SIZE; | ||
| 677 | b_shortpacket = false; | ||
| 678 | } else { | ||
| 679 | b_shortpacket = true; | ||
| 680 | } | ||
| 681 | |||
| 682 | /* Link payload buffer directly on USB hardware */ | ||
| 683 | usb_device_endpoint_write_buffer_job(&usb_device, 0, udd_g_ctrlreq.payload + udd_ctrl_payload_nb_trans, nb_remain); | ||
| 684 | |||
| 685 | udd_ctrl_payload_nb_trans += nb_remain; | ||
| 686 | } | ||
| 687 | |||
| 688 | /** | ||
| 689 | * \brief Process control endpoint OUT transaction | ||
| 690 | * \param[in] pointer Pointer to the endpoint transfer status parameter struct from driver layer. | ||
| 691 | */ | ||
| 692 | static void udd_ctrl_out_received(void *pointer) { | ||
| 693 | struct usb_endpoint_callback_parameter *ep_callback_para = (struct usb_endpoint_callback_parameter *)pointer; | ||
| 694 | |||
| 695 | uint16_t nb_data; | ||
| 696 | nb_data = ep_callback_para->received_bytes; /* Read data received during OUT phase */ | ||
| 697 | |||
| 698 | if (udd_g_ctrlreq.payload_size < (udd_ctrl_payload_nb_trans + nb_data)) { | ||
| 699 | /* Payload buffer too small */ | ||
| 700 | nb_data = udd_g_ctrlreq.payload_size - udd_ctrl_payload_nb_trans; | ||
| 701 | } | ||
| 702 | |||
| 703 | memcpy((uint8_t *)(udd_g_ctrlreq.payload + udd_ctrl_payload_nb_trans), udd_ctrl_buffer, nb_data); | ||
| 704 | udd_ctrl_payload_nb_trans += nb_data; | ||
| 705 | |||
| 706 | if ((USB_DEVICE_EP_CTRL_SIZE != nb_data) || (udd_g_ctrlreq.req.wLength <= (udd_ctrl_prev_payload_nb_trans + udd_ctrl_payload_nb_trans))) { | ||
| 707 | /* End of reception because it is a short packet | ||
| 708 | * or all data are transferred */ | ||
| 709 | |||
| 710 | /* Before send ZLP, call intermediate callback | ||
| 711 | * in case of data receive generate a stall */ | ||
| 712 | udd_g_ctrlreq.payload_size = udd_ctrl_payload_nb_trans; | ||
| 713 | if (NULL != udd_g_ctrlreq.over_under_run) { | ||
| 714 | if (!udd_g_ctrlreq.over_under_run()) { | ||
| 715 | /* Stall ZLP */ | ||
| 716 | udd_ep_control_state = UDD_EPCTRL_STALL_REQ; | ||
| 717 | /* Stall all packets on IN & OUT control endpoint */ | ||
| 718 | udd_ep_set_halt(0); | ||
| 719 | /* Ack reception of OUT to replace NAK by a STALL */ | ||
| 720 | return; | ||
| 721 | } | ||
| 722 | } | ||
| 723 | /* Send IN ZLP to ACK setup request */ | ||
| 724 | udd_ctrl_send_zlp_in(); | ||
| 725 | return; | ||
| 726 | } | ||
| 727 | |||
| 728 | if (udd_g_ctrlreq.payload_size == udd_ctrl_payload_nb_trans) { | ||
| 729 | /* Overrun then request a new payload buffer */ | ||
| 730 | if (!udd_g_ctrlreq.over_under_run) { | ||
| 731 | /* No callback available to request a new payload buffer | ||
| 732 | * Stall ZLP */ | ||
| 733 | udd_ep_control_state = UDD_EPCTRL_STALL_REQ; | ||
| 734 | /* Stall all packets on IN & OUT control endpoint */ | ||
| 735 | udd_ep_set_halt(0); | ||
| 736 | return; | ||
| 737 | } | ||
| 738 | if (!udd_g_ctrlreq.over_under_run()) { | ||
| 739 | /* No new payload buffer delivered | ||
| 740 | * Stall ZLP */ | ||
| 741 | udd_ep_control_state = UDD_EPCTRL_STALL_REQ; | ||
| 742 | /* Stall all packets on IN & OUT control endpoint */ | ||
| 743 | udd_ep_set_halt(0); | ||
| 744 | return; | ||
| 745 | } | ||
| 746 | /* New payload buffer available | ||
| 747 | * Update number of total data received */ | ||
| 748 | udd_ctrl_prev_payload_nb_trans += udd_ctrl_payload_nb_trans; | ||
| 749 | |||
| 750 | /* Reinitialize reception on payload buffer */ | ||
| 751 | udd_ctrl_payload_nb_trans = 0; | ||
| 752 | } | ||
| 753 | usb_device_endpoint_read_buffer_job(&usb_device, 0, udd_ctrl_buffer, USB_DEVICE_EP_CTRL_SIZE); | ||
| 754 | } | ||
| 755 | |||
| 756 | /** | ||
| 757 | * \internal | ||
| 758 | * \brief Endpoint 0 (control) SETUP received callback | ||
| 759 | * \param[in] module_inst pointer to USB module instance | ||
| 760 | * \param[in] pointer Pointer to the endpoint transfer status parameter struct from driver layer. | ||
| 761 | */ | ||
| 762 | static void _usb_ep0_on_setup(struct usb_module *module_inst, void *pointer) { | ||
| 763 | struct usb_endpoint_callback_parameter *ep_callback_para = (struct usb_endpoint_callback_parameter *)pointer; | ||
| 764 | |||
| 765 | if (UDD_EPCTRL_SETUP != udd_ep_control_state) { | ||
| 766 | if (NULL != udd_g_ctrlreq.callback) { | ||
| 767 | udd_g_ctrlreq.callback(); | ||
| 768 | } | ||
| 769 | udd_ep_control_state = UDD_EPCTRL_SETUP; | ||
| 770 | } | ||
| 771 | if (8 != ep_callback_para->received_bytes) { | ||
| 772 | udd_ctrl_stall_data(); | ||
| 773 | return; | ||
| 774 | } else { | ||
| 775 | udd_ctrl_fetch_ram(); | ||
| 776 | if (false == udc_process_setup()) { | ||
| 777 | udd_ctrl_stall_data(); | ||
| 778 | return; | ||
| 779 | } else if (Udd_setup_is_in()) { | ||
| 780 | udd_ctrl_prev_payload_nb_trans = 0; | ||
| 781 | udd_ctrl_payload_nb_trans = 0; | ||
| 782 | udd_ep_control_state = UDD_EPCTRL_DATA_IN; | ||
| 783 | usb_device_endpoint_read_buffer_job(&usb_device, 0, udd_ctrl_buffer, USB_DEVICE_EP_CTRL_SIZE); | ||
| 784 | udd_ctrl_in_sent(); | ||
| 785 | } else { | ||
| 786 | if (0 == udd_g_ctrlreq.req.wLength) { | ||
| 787 | udd_ctrl_send_zlp_in(); | ||
| 788 | return; | ||
| 789 | } else { | ||
| 790 | udd_ctrl_prev_payload_nb_trans = 0; | ||
| 791 | udd_ctrl_payload_nb_trans = 0; | ||
| 792 | udd_ep_control_state = UDD_EPCTRL_DATA_OUT; | ||
| 793 | /* Initialize buffer size and enable OUT bank */ | ||
| 794 | usb_device_endpoint_read_buffer_job(&usb_device, 0, udd_ctrl_buffer, USB_DEVICE_EP_CTRL_SIZE); | ||
| 795 | } | ||
| 796 | } | ||
| 797 | } | ||
| 798 | } | ||
| 799 | |||
| 800 | /** | ||
| 801 | * \brief Control Endpoint Process when underflow condition has occurred | ||
| 802 | * \param[in] pointer Pointer to the endpoint transfer status parameter struct from driver layer. | ||
| 803 | */ | ||
| 804 | static void udd_ctrl_underflow(void *pointer) { | ||
| 805 | struct usb_endpoint_callback_parameter *ep_callback_para = (struct usb_endpoint_callback_parameter *)pointer; | ||
| 806 | |||
| 807 | if (UDD_EPCTRL_DATA_OUT == udd_ep_control_state) { | ||
| 808 | /* Host want to stop OUT transaction | ||
| 809 | * then stop to wait OUT data phase and wait IN ZLP handshake */ | ||
| 810 | udd_ctrl_send_zlp_in(); | ||
| 811 | } else if (UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP == udd_ep_control_state) { | ||
| 812 | /* A OUT handshake is waiting by device, | ||
| 813 | * but host want extra IN data then stall extra IN data */ | ||
| 814 | usb_device_endpoint_set_halt(&usb_device, ep_callback_para->endpoint_address); | ||
| 815 | } | ||
| 816 | } | ||
| 817 | |||
| 818 | /** | ||
| 819 | * \brief Control Endpoint Process when overflow condition has occurred | ||
| 820 | * \param[in] pointer Pointer to the endpoint transfer status parameter struct from driver layer. | ||
| 821 | */ | ||
| 822 | static void udd_ctrl_overflow(void *pointer) { | ||
| 823 | struct usb_endpoint_callback_parameter *ep_callback_para = (struct usb_endpoint_callback_parameter *)pointer; | ||
| 824 | |||
| 825 | if (UDD_EPCTRL_DATA_IN == udd_ep_control_state) { | ||
| 826 | /* Host want to stop IN transaction | ||
| 827 | * then stop to wait IN data phase and wait OUT ZLP handshake */ | ||
| 828 | udd_ep_control_state = UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP; | ||
| 829 | } else if (UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP == udd_ep_control_state) { | ||
| 830 | /* A IN handshake is waiting by device, | ||
| 831 | * but host want extra OUT data then stall extra OUT data and following status stage */ | ||
| 832 | usb_device_endpoint_set_halt(&usb_device, ep_callback_para->endpoint_address); | ||
| 833 | } | ||
| 834 | } | ||
| 835 | |||
| 836 | /** | ||
| 837 | * \internal | ||
| 838 | * \brief Control endpoint transfer fail callback function | ||
| 839 | * \param[in] module_inst Pointer to USB module instance | ||
| 840 | * \param[in] pointer Pointer to the endpoint transfer status parameter struct from driver layer. | ||
| 841 | */ | ||
| 842 | static void _usb_ep0_on_tansfer_fail(struct usb_module *module_inst, void *pointer) { | ||
| 843 | struct usb_endpoint_callback_parameter *ep_callback_para = (struct usb_endpoint_callback_parameter *)pointer; | ||
| 844 | |||
| 845 | if (ep_callback_para->endpoint_address & USB_EP_DIR_IN) { | ||
| 846 | udd_ctrl_underflow(pointer); | ||
| 847 | } else { | ||
| 848 | udd_ctrl_overflow(pointer); | ||
| 849 | } | ||
| 850 | } | ||
| 851 | |||
| 852 | /** | ||
| 853 | * \internal | ||
| 854 | * \brief Control endpoint transfer complete callback function | ||
| 855 | * \param[in] module_inst Pointer to USB module instance | ||
| 856 | * \param[in] pointer Pointer to the endpoint transfer status parameter struct from driver layer. | ||
| 857 | */ | ||
| 858 | static void _usb_ep0_on_tansfer_ok(struct usb_module *module_inst, void *pointer) { | ||
| 859 | if (UDD_EPCTRL_DATA_OUT == udd_ep_control_state) { /* handshake Out for status stage */ | ||
| 860 | udd_ctrl_out_received(pointer); | ||
| 861 | } else if (UDD_EPCTRL_DATA_IN == udd_ep_control_state) { /* handshake In for status stage */ | ||
| 862 | udd_ctrl_in_sent(); | ||
| 863 | } else { | ||
| 864 | if (NULL != udd_g_ctrlreq.callback) { | ||
| 865 | udd_g_ctrlreq.callback(); | ||
| 866 | } | ||
| 867 | udd_ep_control_state = UDD_EPCTRL_SETUP; | ||
| 868 | } | ||
| 869 | } | ||
| 870 | |||
| 871 | /** | ||
| 872 | * \brief Enable Control Endpoint | ||
| 873 | * \param[in] module_inst Pointer to USB module instance | ||
| 874 | */ | ||
| 875 | static void udd_ctrl_ep_enable(struct usb_module *module_inst) { | ||
| 876 | /* USB Device Endpoint0 Configuration */ | ||
| 877 | struct usb_device_endpoint_config config_ep0; | ||
| 878 | |||
| 879 | usb_device_endpoint_get_config_defaults(&config_ep0); | ||
| 880 | config_ep0.ep_size = (enum usb_endpoint_size)(32 - clz(((uint32_t)Min(Max(USB_DEVICE_EP_CTRL_SIZE, 8), 1024) << 1) - 1) - 1 - 3); | ||
| 881 | usb_device_endpoint_set_config(module_inst, &config_ep0); | ||
| 882 | |||
| 883 | usb_device_endpoint_setup_buffer_job(module_inst, udd_ctrl_buffer); | ||
| 884 | |||
| 885 | usb_device_endpoint_register_callback(module_inst, 0, USB_DEVICE_ENDPOINT_CALLBACK_RXSTP, _usb_ep0_on_setup); | ||
| 886 | usb_device_endpoint_register_callback(module_inst, 0, USB_DEVICE_ENDPOINT_CALLBACK_TRCPT, _usb_ep0_on_tansfer_ok); | ||
| 887 | usb_device_endpoint_register_callback(module_inst, 0, USB_DEVICE_ENDPOINT_CALLBACK_TRFAIL, _usb_ep0_on_tansfer_fail); | ||
| 888 | usb_device_endpoint_enable_callback(module_inst, 0, USB_DEVICE_ENDPOINT_CALLBACK_RXSTP); | ||
| 889 | usb_device_endpoint_enable_callback(module_inst, 0, USB_DEVICE_ENDPOINT_CALLBACK_TRCPT); | ||
| 890 | usb_device_endpoint_enable_callback(module_inst, 0, USB_DEVICE_ENDPOINT_CALLBACK_TRFAIL); | ||
| 891 | |||
| 892 | #ifdef USB_DEVICE_LPM_SUPPORT | ||
| 893 | // Enable LPM feature | ||
| 894 | usb_device_set_lpm_mode(module_inst, USB_DEVICE_LPM_ACK); | ||
| 895 | #endif | ||
| 896 | |||
| 897 | udd_ep_control_state = UDD_EPCTRL_SETUP; | ||
| 898 | } | ||
| 899 | |||
| 900 | /** | ||
| 901 | * \internal | ||
| 902 | * \brief Control endpoint Suspend callback function | ||
| 903 | * \param[in] module_inst Pointer to USB module instance | ||
| 904 | * \param[in] pointer Pointer to the callback parameter from driver layer. | ||
| 905 | */ | ||
| 906 | static void _usb_on_suspend(struct usb_module *module_inst, void *pointer) { | ||
| 907 | usb_device_disable_callback(&usb_device, USB_DEVICE_CALLBACK_SUSPEND); | ||
| 908 | usb_device_enable_callback(&usb_device, USB_DEVICE_CALLBACK_WAKEUP); | ||
| 909 | udd_sleep_mode(UDD_STATE_SUSPEND); | ||
| 910 | #ifdef UDC_SUSPEND_EVENT | ||
| 911 | UDC_SUSPEND_EVENT(); | ||
| 912 | #endif | ||
| 913 | } | ||
| 914 | |||
| 915 | #ifdef USB_DEVICE_LPM_SUPPORT | ||
| 916 | static void _usb_device_lpm_suspend(struct usb_module *module_inst, void *pointer) { | ||
| 917 | dbg_print("LPM_SUSP\n"); | ||
| 918 | |||
| 919 | uint32_t *lpm_wakeup_enable; | ||
| 920 | lpm_wakeup_enable = (uint32_t *)pointer; | ||
| 921 | |||
| 922 | usb_device_disable_callback(&usb_device, USB_DEVICE_CALLBACK_LPMSUSP); | ||
| 923 | usb_device_disable_callback(&usb_device, USB_DEVICE_CALLBACK_SUSPEND); | ||
| 924 | usb_device_enable_callback(&usb_device, USB_DEVICE_CALLBACK_WAKEUP); | ||
| 925 | |||
| 926 | //#warning Here the sleep mode must be choose to have a DFLL startup time < bmAttribut.HIRD | ||
| 927 | udd_sleep_mode(UDD_STATE_SUSPEND_LPM); // Enter in LPM SUSPEND mode | ||
| 928 | if ((*lpm_wakeup_enable)) { | ||
| 929 | UDC_REMOTEWAKEUP_LPM_ENABLE(); | ||
| 930 | } | ||
| 931 | if (!(*lpm_wakeup_enable)) { | ||
| 932 | UDC_REMOTEWAKEUP_LPM_DISABLE(); | ||
| 933 | } | ||
| 934 | UDC_SUSPEND_LPM_EVENT(); | ||
| 935 | } | ||
| 936 | #endif | ||
| 937 | |||
| 938 | /** | ||
| 939 | * \internal | ||
| 940 | * \brief Control endpoint SOF callback function | ||
| 941 | * \param[in] module_inst Pointer to USB module instance | ||
| 942 | * \param[in] pointer Pointer to the callback parameter from driver layer. | ||
| 943 | */ | ||
| 944 | static void _usb_on_sof_notify(struct usb_module *module_inst, void *pointer) { | ||
| 945 | udc_sof_notify(); | ||
| 946 | #ifdef UDC_SOF_EVENT | ||
| 947 | UDC_SOF_EVENT(); | ||
| 948 | #endif | ||
| 949 | } | ||
| 950 | |||
| 951 | /** | ||
| 952 | * \internal | ||
| 953 | * \brief Control endpoint Reset callback function | ||
| 954 | * \param[in] module_inst Pointer to USB module instance | ||
| 955 | * \param[in] pointer Pointer to the callback parameter from driver layer. | ||
| 956 | */ | ||
| 957 | static void _usb_on_bus_reset(struct usb_module *module_inst, void *pointer) { | ||
| 958 | // Reset USB Device Stack Core | ||
| 959 | udc_reset(); | ||
| 960 | usb_device_set_address(module_inst, 0); | ||
| 961 | udd_ctrl_ep_enable(module_inst); | ||
| 962 | } | ||
| 963 | |||
| 964 | /** | ||
| 965 | * \internal | ||
| 966 | * \brief Control endpoint Wakeup callback function | ||
| 967 | * \param[in] module_inst Pointer to USB module instance | ||
| 968 | * \param[in] pointer Pointer to the callback parameter from driver layer. | ||
| 969 | */ | ||
| 970 | static void _usb_on_wakeup(struct usb_module *module_inst, void *pointer) { | ||
| 971 | udd_wait_clock_ready(); | ||
| 972 | |||
| 973 | usb_device_disable_callback(&usb_device, USB_DEVICE_CALLBACK_WAKEUP); | ||
| 974 | usb_device_enable_callback(&usb_device, USB_DEVICE_CALLBACK_SUSPEND); | ||
| 975 | #ifdef USB_DEVICE_LPM_SUPPORT | ||
| 976 | usb_device_register_callback(&usb_device, USB_DEVICE_CALLBACK_LPMSUSP, _usb_device_lpm_suspend); | ||
| 977 | usb_device_enable_callback(&usb_device, USB_DEVICE_CALLBACK_LPMSUSP); | ||
| 978 | #endif | ||
| 979 | udd_sleep_mode(UDD_STATE_IDLE); | ||
| 980 | #ifdef UDC_RESUME_EVENT | ||
| 981 | UDC_RESUME_EVENT(); | ||
| 982 | #endif | ||
| 983 | } | ||
| 984 | |||
| 985 | void udd_detach(void) { | ||
| 986 | usb_device_detach(&usb_device); | ||
| 987 | udd_sleep_mode(UDD_STATE_SUSPEND); | ||
| 988 | } | ||
| 989 | |||
| 990 | void udd_attach(void) { | ||
| 991 | udd_sleep_mode(UDD_STATE_IDLE); | ||
| 992 | usb_device_attach(&usb_device); | ||
| 993 | |||
| 994 | usb_device_register_callback(&usb_device, USB_DEVICE_CALLBACK_SUSPEND, _usb_on_suspend); | ||
| 995 | usb_device_register_callback(&usb_device, USB_DEVICE_CALLBACK_SOF, _usb_on_sof_notify); | ||
| 996 | usb_device_register_callback(&usb_device, USB_DEVICE_CALLBACK_RESET, _usb_on_bus_reset); | ||
| 997 | usb_device_register_callback(&usb_device, USB_DEVICE_CALLBACK_WAKEUP, _usb_on_wakeup); | ||
| 998 | |||
| 999 | usb_device_enable_callback(&usb_device, USB_DEVICE_CALLBACK_SUSPEND); | ||
| 1000 | usb_device_enable_callback(&usb_device, USB_DEVICE_CALLBACK_SOF); | ||
| 1001 | usb_device_enable_callback(&usb_device, USB_DEVICE_CALLBACK_RESET); | ||
| 1002 | usb_device_enable_callback(&usb_device, USB_DEVICE_CALLBACK_WAKEUP); | ||
| 1003 | #ifdef USB_DEVICE_LPM_SUPPORT | ||
| 1004 | usb_device_register_callback(&usb_device, USB_DEVICE_CALLBACK_LPMSUSP, _usb_device_lpm_suspend); | ||
| 1005 | usb_device_enable_callback(&usb_device, USB_DEVICE_CALLBACK_LPMSUSP); | ||
| 1006 | #endif | ||
| 1007 | } | ||
| 1008 | |||
| 1009 | void udd_enable(void) { | ||
| 1010 | uint32_t irqflags; | ||
| 1011 | |||
| 1012 | /* To avoid USB interrupt before end of initialization */ | ||
| 1013 | irqflags = __get_PRIMASK(); | ||
| 1014 | __disable_irq(); | ||
| 1015 | __DMB(); | ||
| 1016 | |||
| 1017 | struct usb_config config_usb; | ||
| 1018 | |||
| 1019 | /* USB Module configuration */ | ||
| 1020 | usb_get_config_defaults(&config_usb); | ||
| 1021 | config_usb.source_generator = UDD_CLOCK_GEN; | ||
| 1022 | usb_init(&usb_device, USB, &config_usb); | ||
| 1023 | |||
| 1024 | /* USB Module Enable */ | ||
| 1025 | usb_enable(&usb_device); | ||
| 1026 | |||
| 1027 | /* Check clock after enable module, request the clock */ | ||
| 1028 | udd_wait_clock_ready(); | ||
| 1029 | |||
| 1030 | udd_sleep_mode(UDD_STATE_SUSPEND); | ||
| 1031 | |||
| 1032 | // No VBus detect, assume always high | ||
| 1033 | #ifndef USB_DEVICE_ATTACH_AUTO_DISABLE | ||
| 1034 | udd_attach(); | ||
| 1035 | #endif | ||
| 1036 | |||
| 1037 | __DMB(); | ||
| 1038 | __set_PRIMASK(irqflags); | ||
| 1039 | } | ||
| 1040 | |||
| 1041 | void udd_disable(void) { | ||
| 1042 | udd_detach(); | ||
| 1043 | |||
| 1044 | udd_sleep_mode(UDD_STATE_OFF); | ||
| 1045 | } | ||
| 1046 | /** @} */ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/usb_hub.c b/tmk_core/protocol/arm_atsam/usb/usb_hub.c deleted file mode 100644 index 14fba799c7..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/usb_hub.c +++ /dev/null | |||
| @@ -1,342 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include "arm_atsam_protocol.h" | ||
| 19 | #include "drivers/usb2422.h" | ||
| 20 | #include <string.h> | ||
| 21 | |||
| 22 | uint8_t usb_host_port; | ||
| 23 | |||
| 24 | #ifndef MD_BOOTLOADER | ||
| 25 | |||
| 26 | uint8_t usb_extra_state; | ||
| 27 | uint8_t usb_extra_manual; | ||
| 28 | uint8_t usb_gcr_auto; | ||
| 29 | |||
| 30 | #endif // MD_BOOTLOADER | ||
| 31 | |||
| 32 | uint16_t adc_extra; | ||
| 33 | |||
| 34 | void USB_Hub_init(void) { | ||
| 35 | Gclk * pgclk = GCLK; | ||
| 36 | Mclk * pmclk = MCLK; | ||
| 37 | Port * pport = PORT; | ||
| 38 | Oscctrl *posc = OSCCTRL; | ||
| 39 | Usb * pusb = USB; | ||
| 40 | |||
| 41 | DBGC(DC_USB2422_INIT_BEGIN); | ||
| 42 | |||
| 43 | while ((v_5v = adc_get(ADC_5V)) < ADC_5V_START_LEVEL) { | ||
| 44 | DBGC(DC_USB2422_INIT_WAIT_5V_LOW); | ||
| 45 | } | ||
| 46 | |||
| 47 | // setup peripheral and synchronous bus clocks to USB | ||
| 48 | pgclk->PCHCTRL[10].bit.GEN = 0; | ||
| 49 | pgclk->PCHCTRL[10].bit.CHEN = 1; | ||
| 50 | pmclk->AHBMASK.bit.USB_ = 1; | ||
| 51 | pmclk->APBBMASK.bit.USB_ = 1; | ||
| 52 | |||
| 53 | // setup port pins for D-, D+, and SOF_1KHZ | ||
| 54 | pport->Group[0].PMUX[12].reg = 0x77; // PA24, PA25, function column H for USB D-, D+ | ||
| 55 | pport->Group[0].PINCFG[24].bit.PMUXEN = 1; | ||
| 56 | pport->Group[0].PINCFG[25].bit.PMUXEN = 1; | ||
| 57 | pport->Group[1].PMUX[11].bit.PMUXE = 7; // PB22, function column H for USB SOF_1KHz output | ||
| 58 | pport->Group[1].PINCFG[22].bit.PMUXEN = 1; | ||
| 59 | |||
| 60 | // configure and enable DFLL for USB clock recovery mode at 48MHz | ||
| 61 | posc->DFLLCTRLA.bit.ENABLE = 0; | ||
| 62 | while (posc->DFLLSYNC.bit.ENABLE) { | ||
| 63 | DBGC(DC_USB2422_INIT_OSC_SYNC_DISABLING); | ||
| 64 | } | ||
| 65 | while (posc->DFLLSYNC.bit.DFLLCTRLB) { | ||
| 66 | DBGC(DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_1); | ||
| 67 | } | ||
| 68 | posc->DFLLCTRLB.bit.USBCRM = 1; | ||
| 69 | while (posc->DFLLSYNC.bit.DFLLCTRLB) { | ||
| 70 | DBGC(DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_2); | ||
| 71 | } | ||
| 72 | posc->DFLLCTRLB.bit.MODE = 1; | ||
| 73 | while (posc->DFLLSYNC.bit.DFLLCTRLB) { | ||
| 74 | DBGC(DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_3); | ||
| 75 | } | ||
| 76 | posc->DFLLCTRLB.bit.QLDIS = 0; | ||
| 77 | while (posc->DFLLSYNC.bit.DFLLCTRLB) { | ||
| 78 | DBGC(DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_4); | ||
| 79 | } | ||
| 80 | posc->DFLLCTRLB.bit.CCDIS = 1; | ||
| 81 | posc->DFLLMUL.bit.MUL = 0xBB80; // 4800 x 1KHz | ||
| 82 | while (posc->DFLLSYNC.bit.DFLLMUL) { | ||
| 83 | DBGC(DC_USB2422_INIT_OSC_SYNC_DFLLMUL); | ||
| 84 | } | ||
| 85 | posc->DFLLCTRLA.bit.ENABLE = 1; | ||
| 86 | while (posc->DFLLSYNC.bit.ENABLE) { | ||
| 87 | DBGC(DC_USB2422_INIT_OSC_SYNC_ENABLING); | ||
| 88 | } | ||
| 89 | |||
| 90 | pusb->DEVICE.CTRLA.bit.SWRST = 1; | ||
| 91 | while (pusb->DEVICE.SYNCBUSY.bit.SWRST) { | ||
| 92 | DBGC(DC_USB2422_INIT_USB_SYNC_SWRST); | ||
| 93 | } | ||
| 94 | while (pusb->DEVICE.CTRLA.bit.SWRST) { | ||
| 95 | DBGC(DC_USB2422_INIT_USB_WAIT_SWRST); | ||
| 96 | } | ||
| 97 | // calibration from factory presets | ||
| 98 | pusb->DEVICE.PADCAL.bit.TRANSN = (USB_FUSES_TRANSN_ADDR >> USB_FUSES_TRANSN_Pos) & USB_FUSES_TRANSN_Msk; | ||
| 99 | pusb->DEVICE.PADCAL.bit.TRANSP = (USB_FUSES_TRANSP_ADDR >> USB_FUSES_TRANSP_Pos) & USB_FUSES_TRANSP_Msk; | ||
| 100 | pusb->DEVICE.PADCAL.bit.TRIM = (USB_FUSES_TRIM_ADDR >> USB_FUSES_TRIM_Pos) & USB_FUSES_TRIM_Msk; | ||
| 101 | // device mode, enabled | ||
| 102 | pusb->DEVICE.CTRLB.bit.SPDCONF = 0; // full speed | ||
| 103 | pusb->DEVICE.CTRLA.bit.MODE = 0; | ||
| 104 | pusb->DEVICE.CTRLA.bit.ENABLE = 1; | ||
| 105 | while (pusb->DEVICE.SYNCBUSY.bit.ENABLE) { | ||
| 106 | DBGC(DC_USB2422_INIT_USB_SYNC_ENABLING); | ||
| 107 | } | ||
| 108 | |||
| 109 | pusb->DEVICE.QOSCTRL.bit.DQOS = 2; | ||
| 110 | pusb->DEVICE.QOSCTRL.bit.CQOS = 2; | ||
| 111 | |||
| 112 | USB2422_init(); | ||
| 113 | |||
| 114 | sr_exp_data.bit.HUB_CONNECT = 1; // connect signal | ||
| 115 | sr_exp_data.bit.HUB_RESET_N = 1; // reset high | ||
| 116 | SR_EXP_WriteData(); | ||
| 117 | |||
| 118 | wait_us(100); | ||
| 119 | |||
| 120 | #ifndef MD_BOOTLOADER | ||
| 121 | |||
| 122 | usb_extra_manual = 0; | ||
| 123 | usb_gcr_auto = 1; | ||
| 124 | |||
| 125 | #endif // MD_BOOTLOADER | ||
| 126 | |||
| 127 | DBGC(DC_USB2422_INIT_COMPLETE); | ||
| 128 | } | ||
| 129 | |||
| 130 | void USB_reset(void) { | ||
| 131 | DBGC(DC_USB_RESET_BEGIN); | ||
| 132 | |||
| 133 | // pulse reset for at least 1 usec | ||
| 134 | sr_exp_data.bit.HUB_RESET_N = 0; // reset low | ||
| 135 | SR_EXP_WriteData(); | ||
| 136 | wait_us(2); | ||
| 137 | sr_exp_data.bit.HUB_RESET_N = 1; // reset high to run | ||
| 138 | SR_EXP_WriteData(); | ||
| 139 | |||
| 140 | DBGC(DC_USB_RESET_COMPLETE); | ||
| 141 | } | ||
| 142 | |||
| 143 | void USB_configure(void) { | ||
| 144 | DBGC(DC_USB_CONFIGURE_BEGIN); | ||
| 145 | |||
| 146 | USB2422_configure(); | ||
| 147 | |||
| 148 | adc_extra = 0; | ||
| 149 | |||
| 150 | DBGC(DC_USB_CONFIGURE_COMPLETE); | ||
| 151 | } | ||
| 152 | |||
| 153 | uint16_t USB_active(void) { | ||
| 154 | return USB2422_active(); | ||
| 155 | } | ||
| 156 | |||
| 157 | void USB_set_host_by_voltage(void) { | ||
| 158 | // UP is upstream device (HOST) | ||
| 159 | // DN1 is downstream device (EXTRA) | ||
| 160 | // DN2 is keyboard (KEYB) | ||
| 161 | |||
| 162 | DBGC(DC_USB_SET_HOST_BY_VOLTAGE_BEGIN); | ||
| 163 | |||
| 164 | usb_host_port = USB_HOST_PORT_UNKNOWN; | ||
| 165 | #ifndef MD_BOOTLOADER | ||
| 166 | usb_extra_state = USB_EXTRA_STATE_UNKNOWN; | ||
| 167 | #endif // MD_BOOTLOADER | ||
| 168 | sr_exp_data.bit.SRC_1 = 1; // USBC-1 available for test | ||
| 169 | sr_exp_data.bit.SRC_2 = 1; // USBC-2 available for test | ||
| 170 | sr_exp_data.bit.E_UP_N = 1; // HOST disable | ||
| 171 | sr_exp_data.bit.E_DN1_N = 1; // EXTRA disable | ||
| 172 | sr_exp_data.bit.E_VBUS_1 = 0; // USBC-1 disable full power I/O | ||
| 173 | sr_exp_data.bit.E_VBUS_2 = 0; // USBC-2 disable full power I/O | ||
| 174 | |||
| 175 | SR_EXP_WriteData(); | ||
| 176 | |||
| 177 | wait_ms(250); | ||
| 178 | |||
| 179 | while ((v_5v = adc_get(ADC_5V)) < ADC_5V_START_LEVEL) { | ||
| 180 | DBGC(DC_USB_SET_HOST_5V_LOW_WAITING); | ||
| 181 | } | ||
| 182 | |||
| 183 | v_con_1 = adc_get(ADC_CON1); | ||
| 184 | v_con_2 = adc_get(ADC_CON2); | ||
| 185 | |||
| 186 | v_con_1_boot = v_con_1; | ||
| 187 | v_con_2_boot = v_con_2; | ||
| 188 | |||
| 189 | if (v_con_1 > v_con_2) { | ||
| 190 | sr_exp_data.bit.S_UP = 0; // HOST to USBC-1 | ||
| 191 | sr_exp_data.bit.S_DN1 = 1; // EXTRA to USBC-2 | ||
| 192 | sr_exp_data.bit.SRC_1 = 1; // HOST on USBC-1 | ||
| 193 | sr_exp_data.bit.SRC_2 = 0; // EXTRA available on USBC-2 | ||
| 194 | |||
| 195 | sr_exp_data.bit.E_VBUS_1 = 1; // USBC-1 enable full power I/O | ||
| 196 | sr_exp_data.bit.E_VBUS_2 = 0; // USBC-2 disable full power I/O | ||
| 197 | |||
| 198 | SR_EXP_WriteData(); | ||
| 199 | |||
| 200 | sr_exp_data.bit.E_UP_N = 0; // HOST enable | ||
| 201 | |||
| 202 | SR_EXP_WriteData(); | ||
| 203 | |||
| 204 | usb_host_port = USB_HOST_PORT_1; | ||
| 205 | } else { | ||
| 206 | sr_exp_data.bit.S_UP = 1; // EXTRA to USBC-1 | ||
| 207 | sr_exp_data.bit.S_DN1 = 0; // HOST to USBC-2 | ||
| 208 | sr_exp_data.bit.SRC_1 = 0; // EXTRA available on USBC-1 | ||
| 209 | sr_exp_data.bit.SRC_2 = 1; // HOST on USBC-2 | ||
| 210 | |||
| 211 | sr_exp_data.bit.E_VBUS_1 = 0; // USBC-1 disable full power I/O | ||
| 212 | sr_exp_data.bit.E_VBUS_2 = 1; // USBC-2 enable full power I/O | ||
| 213 | |||
| 214 | SR_EXP_WriteData(); | ||
| 215 | |||
| 216 | sr_exp_data.bit.E_UP_N = 0; // HOST enable | ||
| 217 | |||
| 218 | SR_EXP_WriteData(); | ||
| 219 | |||
| 220 | usb_host_port = USB_HOST_PORT_2; | ||
| 221 | } | ||
| 222 | |||
| 223 | #ifndef MD_BOOTLOADER | ||
| 224 | usb_extra_state = USB_EXTRA_STATE_DISABLED; | ||
| 225 | #endif // MD_BOOTLOADER | ||
| 226 | |||
| 227 | USB_reset(); | ||
| 228 | USB_configure(); | ||
| 229 | |||
| 230 | DBGC(DC_USB_SET_HOST_BY_VOLTAGE_COMPLETE); | ||
| 231 | } | ||
| 232 | |||
| 233 | uint8_t USB_Hub_Port_Detect_Init(void) { | ||
| 234 | uint32_t port_detect_retry_ms; | ||
| 235 | uint32_t tmod; | ||
| 236 | |||
| 237 | DBGC(DC_PORT_DETECT_INIT_BEGIN); | ||
| 238 | |||
| 239 | USB_set_host_by_voltage(); | ||
| 240 | |||
| 241 | port_detect_retry_ms = timer_read64() + PORT_DETECT_RETRY_INTERVAL; | ||
| 242 | |||
| 243 | while (!USB_active()) { | ||
| 244 | tmod = timer_read64() % PORT_DETECT_RETRY_INTERVAL; | ||
| 245 | |||
| 246 | if (v_con_1 > v_con_2) // Values updated from USB_set_host_by_voltage(); | ||
| 247 | { | ||
| 248 | // 1 flash for port 1 detected | ||
| 249 | if (tmod > 500 && tmod < 600) { | ||
| 250 | DBG_LED_ON; | ||
| 251 | } else { | ||
| 252 | DBG_LED_OFF; | ||
| 253 | } | ||
| 254 | } else if (v_con_2 > v_con_1) // Values updated from USB_set_host_by_voltage(); | ||
| 255 | { | ||
| 256 | // 2 flash for port 2 detected | ||
| 257 | if (tmod > 500 && tmod < 600) { | ||
| 258 | DBG_LED_ON; | ||
| 259 | } else if (tmod > 700 && tmod < 800) { | ||
| 260 | DBG_LED_ON; | ||
| 261 | } else { | ||
| 262 | DBG_LED_OFF; | ||
| 263 | } | ||
| 264 | } | ||
| 265 | |||
| 266 | if (timer_read64() > port_detect_retry_ms) { | ||
| 267 | DBGC(DC_PORT_DETECT_INIT_FAILED); | ||
| 268 | return 0; | ||
| 269 | } | ||
| 270 | } | ||
| 271 | |||
| 272 | DBGC(DC_PORT_DETECT_INIT_COMPLETE); | ||
| 273 | |||
| 274 | return 1; | ||
| 275 | } | ||
| 276 | |||
| 277 | #ifndef MD_BOOTLOADER | ||
| 278 | |||
| 279 | void USB_ExtraSetState(uint8_t state) { | ||
| 280 | uint8_t state_save = state; | ||
| 281 | |||
| 282 | if (state == USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG) state = USB_EXTRA_STATE_DISABLED; | ||
| 283 | |||
| 284 | if (usb_host_port == USB_HOST_PORT_1) | ||
| 285 | sr_exp_data.bit.E_VBUS_2 = state; | ||
| 286 | else if (usb_host_port == USB_HOST_PORT_2) | ||
| 287 | sr_exp_data.bit.E_VBUS_1 = state; | ||
| 288 | else | ||
| 289 | return; | ||
| 290 | |||
| 291 | sr_exp_data.bit.E_DN1_N = !state; | ||
| 292 | SR_EXP_WriteData(); | ||
| 293 | |||
| 294 | usb_extra_state = state_save; | ||
| 295 | |||
| 296 | if (usb_extra_state == USB_EXTRA_STATE_ENABLED) | ||
| 297 | CDC_print("USB: Extra enabled\r\n"); | ||
| 298 | else if (usb_extra_state == USB_EXTRA_STATE_DISABLED) { | ||
| 299 | CDC_print("USB: Extra disabled\r\n"); | ||
| 300 | # ifdef USE_MASSDROP_CONFIGURATOR | ||
| 301 | if (led_animation_breathing) gcr_breathe = gcr_desired; | ||
| 302 | # endif | ||
| 303 | } else if (usb_extra_state == USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG) | ||
| 304 | CDC_print("USB: Extra disabled until replug\r\n"); | ||
| 305 | else | ||
| 306 | CDC_print("USB: Extra state unknown\r\n"); | ||
| 307 | } | ||
| 308 | |||
| 309 | void USB_HandleExtraDevice(void) { | ||
| 310 | uint16_t adcval; | ||
| 311 | |||
| 312 | if (usb_host_port == USB_HOST_PORT_1) | ||
| 313 | adcval = adc_get(ADC_CON2); | ||
| 314 | else if (usb_host_port == USB_HOST_PORT_2) | ||
| 315 | adcval = adc_get(ADC_CON1); | ||
| 316 | else | ||
| 317 | return; | ||
| 318 | |||
| 319 | adc_extra = adc_extra * 0.9 + adcval * 0.1; | ||
| 320 | |||
| 321 | // Check for a forced disable state (such as overload prevention) | ||
| 322 | if (usb_extra_state == USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG) { | ||
| 323 | // Detect unplug and reset state to disabled | ||
| 324 | if (adc_extra > USB_EXTRA_ADC_THRESHOLD) usb_extra_state = USB_EXTRA_STATE_DISABLED; | ||
| 325 | |||
| 326 | return; // Return even if unplug detected | ||
| 327 | } | ||
| 328 | |||
| 329 | if (usb_extra_manual) { | ||
| 330 | if (usb_extra_state == USB_EXTRA_STATE_DISABLED) USB_ExtraSetState(USB_EXTRA_STATE_ENABLED); | ||
| 331 | |||
| 332 | return; | ||
| 333 | } | ||
| 334 | |||
| 335 | // dpf("a %i %i\r\n",adcval, adc_extra); | ||
| 336 | if (usb_extra_state == USB_EXTRA_STATE_DISABLED && adc_extra < USB_EXTRA_ADC_THRESHOLD) | ||
| 337 | USB_ExtraSetState(USB_EXTRA_STATE_ENABLED); | ||
| 338 | else if (usb_extra_state == USB_EXTRA_STATE_ENABLED && adc_extra > USB_EXTRA_ADC_THRESHOLD) | ||
| 339 | USB_ExtraSetState(USB_EXTRA_STATE_DISABLED); | ||
| 340 | } | ||
| 341 | |||
| 342 | #endif // MD_BOOTLOADER | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/usb_hub.h b/tmk_core/protocol/arm_atsam/usb/usb_hub.h deleted file mode 100644 index d7b2e3fab4..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/usb_hub.h +++ /dev/null | |||
| @@ -1,51 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef _USB2422_H_ | ||
| 19 | #define _USB2422_H_ | ||
| 20 | |||
| 21 | #define REV_USB2422 0x100 | ||
| 22 | |||
| 23 | #define PORT_DETECT_RETRY_INTERVAL 2000 | ||
| 24 | |||
| 25 | #define USB_EXTRA_ADC_THRESHOLD 900 | ||
| 26 | |||
| 27 | #define USB_EXTRA_STATE_DISABLED 0 | ||
| 28 | #define USB_EXTRA_STATE_ENABLED 1 | ||
| 29 | #define USB_EXTRA_STATE_UNKNOWN 2 | ||
| 30 | #define USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG 3 | ||
| 31 | |||
| 32 | #define USB_HOST_PORT_1 0 | ||
| 33 | #define USB_HOST_PORT_2 1 | ||
| 34 | #define USB_HOST_PORT_UNKNOWN 2 | ||
| 35 | |||
| 36 | extern uint8_t usb_host_port; | ||
| 37 | extern uint8_t usb_extra_state; | ||
| 38 | extern uint8_t usb_extra_manual; | ||
| 39 | extern uint8_t usb_gcr_auto; | ||
| 40 | |||
| 41 | void USB_Hub_init(void); | ||
| 42 | uint8_t USB_Hub_Port_Detect_Init(void); | ||
| 43 | void USB_reset(void); | ||
| 44 | void USB_configure(void); | ||
| 45 | uint16_t USB_active(void); | ||
| 46 | void USB_set_host_by_voltage(void); | ||
| 47 | uint16_t adc_get(uint8_t muxpos); | ||
| 48 | void USB_HandleExtraDevice(void); | ||
| 49 | void USB_ExtraSetState(uint8_t state); | ||
| 50 | |||
| 51 | #endif //_USB2422_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/usb_main.h b/tmk_core/protocol/arm_atsam/usb/usb_main.h deleted file mode 100644 index c3b1698c59..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/usb_main.h +++ /dev/null | |||
| @@ -1,101 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief Declaration of main function used by HID keyboard example | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #ifndef _MAIN_H_ | ||
| 48 | #define _MAIN_H_ | ||
| 49 | |||
| 50 | // Enters the application in low power mode | ||
| 51 | // Callback called when USB host sets USB line in suspend state | ||
| 52 | void main_suspend_action(void); | ||
| 53 | |||
| 54 | // Called by UDD when the USB line exit of suspend state | ||
| 55 | void main_resume_action(void); | ||
| 56 | |||
| 57 | // Called when a start of frame is received on USB line | ||
| 58 | void main_sof_action(void); | ||
| 59 | |||
| 60 | // Called by UDC when USB Host request to enable remote wakeup | ||
| 61 | void main_remotewakeup_enable(void); | ||
| 62 | |||
| 63 | // Called by UDC when USB Host request to disable remote wakeup | ||
| 64 | void main_remotewakeup_disable(void); | ||
| 65 | |||
| 66 | extern volatile bool main_b_kbd_enable; | ||
| 67 | bool main_kbd_enable(void); | ||
| 68 | void main_kbd_disable(void); | ||
| 69 | |||
| 70 | #ifdef NKRO_ENABLE | ||
| 71 | extern volatile bool main_b_nkro_enable; | ||
| 72 | bool main_nkro_enable(void); | ||
| 73 | void main_nkro_disable(void); | ||
| 74 | #endif // NKRO_ENABLE | ||
| 75 | |||
| 76 | #ifdef EXTRAKEY_ENABLE | ||
| 77 | extern volatile bool main_b_exk_enable; | ||
| 78 | bool main_exk_enable(void); | ||
| 79 | void main_exk_disable(void); | ||
| 80 | #endif // EXTRAKEY_ENABLE | ||
| 81 | |||
| 82 | #ifdef CONSOLE_ENABLE | ||
| 83 | extern volatile bool main_b_con_enable; | ||
| 84 | bool main_con_enable(void); | ||
| 85 | void main_con_disable(void); | ||
| 86 | #endif // CONSOLE_ENABLE | ||
| 87 | |||
| 88 | #ifdef MOUSE_ENABLE | ||
| 89 | extern volatile bool main_b_mou_enable; | ||
| 90 | bool main_mou_enable(void); | ||
| 91 | void main_mou_disable(void); | ||
| 92 | #endif // MOUSE_ENABLE | ||
| 93 | |||
| 94 | #ifdef RAW_ENABLE | ||
| 95 | extern volatile bool main_b_raw_enable; | ||
| 96 | bool main_raw_enable(void); | ||
| 97 | void main_raw_disable(void); | ||
| 98 | void main_raw_receive(uint8_t *buffer, uint8_t len); | ||
| 99 | #endif // RAW_ENABLE | ||
| 100 | |||
| 101 | #endif // _MAIN_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/usb_protocol.h b/tmk_core/protocol/arm_atsam/usb/usb_protocol.h deleted file mode 100644 index 639b80a804..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/usb_protocol.h +++ /dev/null | |||
| @@ -1,488 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief USB protocol definitions. | ||
| 5 | * | ||
| 6 | * This file contains the USB definitions and data structures provided by the | ||
| 7 | * USB 2.0 specification. | ||
| 8 | * | ||
| 9 | * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. | ||
| 10 | * | ||
| 11 | * \asf_license_start | ||
| 12 | * | ||
| 13 | * \page License | ||
| 14 | * | ||
| 15 | * Redistribution and use in source and binary forms, with or without | ||
| 16 | * modification, are permitted provided that the following conditions are met: | ||
| 17 | * | ||
| 18 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer. | ||
| 20 | * | ||
| 21 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 22 | * this list of conditions and the following disclaimer in the documentation | ||
| 23 | * and/or other materials provided with the distribution. | ||
| 24 | * | ||
| 25 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 26 | * from this software without specific prior written permission. | ||
| 27 | * | ||
| 28 | * 4. This software may only be redistributed and used in connection with an | ||
| 29 | * Atmel microcontroller product. | ||
| 30 | * | ||
| 31 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 32 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 33 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 34 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 35 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 40 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 41 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 42 | * | ||
| 43 | * \asf_license_stop | ||
| 44 | * | ||
| 45 | */ | ||
| 46 | /* | ||
| 47 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 48 | */ | ||
| 49 | |||
| 50 | #ifndef _USB_PROTOCOL_H_ | ||
| 51 | #define _USB_PROTOCOL_H_ | ||
| 52 | |||
| 53 | #include "usb_atmel.h" | ||
| 54 | |||
| 55 | /** | ||
| 56 | * \ingroup usb_group | ||
| 57 | * \defgroup usb_protocol_group USB Protocol Definitions | ||
| 58 | * | ||
| 59 | * This module defines constants and data structures provided by the USB | ||
| 60 | * 2.0 specification. | ||
| 61 | * | ||
| 62 | * @{ | ||
| 63 | */ | ||
| 64 | |||
| 65 | //! Value for field bcdUSB | ||
| 66 | #define USB_V2_0 0x0200 //!< USB Specification version 2.00 | ||
| 67 | #define USB_V2_1 0x0201 //!< USB Specification version 2.01 | ||
| 68 | |||
| 69 | /*! \name Generic definitions (Class, subclass and protocol) | ||
| 70 | */ | ||
| 71 | //! @{ | ||
| 72 | #define NO_CLASS 0x00 | ||
| 73 | #define CLASS_VENDOR_SPECIFIC 0xFF | ||
| 74 | #define NO_SUBCLASS 0x00 | ||
| 75 | #define NO_PROTOCOL 0x00 | ||
| 76 | //! @} | ||
| 77 | |||
| 78 | //! \name IAD (Interface Association Descriptor) constants | ||
| 79 | //! @{ | ||
| 80 | #define CLASS_IAD 0xEF | ||
| 81 | #define SUB_CLASS_IAD 0x02 | ||
| 82 | #define PROTOCOL_IAD 0x01 | ||
| 83 | //! @} | ||
| 84 | |||
| 85 | /** | ||
| 86 | * \brief USB request data transfer direction (bmRequestType) | ||
| 87 | */ | ||
| 88 | #define USB_REQ_DIR_OUT (0 << 7) //!< Host to device | ||
| 89 | #define USB_REQ_DIR_IN (1 << 7) //!< Device to host | ||
| 90 | #define USB_REQ_DIR_MASK (1 << 7) //!< Mask | ||
| 91 | |||
| 92 | /** | ||
| 93 | * \brief USB request types (bmRequestType) | ||
| 94 | */ | ||
| 95 | #define USB_REQ_TYPE_STANDARD (0 << 5) //!< Standard request | ||
| 96 | #define USB_REQ_TYPE_CLASS (1 << 5) //!< Class-specific request | ||
| 97 | #define USB_REQ_TYPE_VENDOR (2 << 5) //!< Vendor-specific request | ||
| 98 | #define USB_REQ_TYPE_MASK (3 << 5) //!< Mask | ||
| 99 | |||
| 100 | /** | ||
| 101 | * \brief USB recipient codes (bmRequestType) | ||
| 102 | */ | ||
| 103 | #define USB_REQ_RECIP_DEVICE (0 << 0) //!< Recipient device | ||
| 104 | #define USB_REQ_RECIP_INTERFACE (1 << 0) //!< Recipient interface | ||
| 105 | #define USB_REQ_RECIP_ENDPOINT (2 << 0) //!< Recipient endpoint | ||
| 106 | #define USB_REQ_RECIP_OTHER (3 << 0) //!< Recipient other | ||
| 107 | #define USB_REQ_RECIP_MASK (0x1F) //!< Mask | ||
| 108 | |||
| 109 | /** | ||
| 110 | * \brief Standard USB requests (bRequest) | ||
| 111 | */ | ||
| 112 | enum usb_reqid { | ||
| 113 | USB_REQ_GET_STATUS = 0, | ||
| 114 | USB_REQ_CLEAR_FEATURE = 1, | ||
| 115 | USB_REQ_SET_FEATURE = 3, | ||
| 116 | USB_REQ_SET_ADDRESS = 5, | ||
| 117 | USB_REQ_GET_DESCRIPTOR = 6, | ||
| 118 | USB_REQ_SET_DESCRIPTOR = 7, | ||
| 119 | USB_REQ_GET_CONFIGURATION = 8, | ||
| 120 | USB_REQ_SET_CONFIGURATION = 9, | ||
| 121 | USB_REQ_GET_INTERFACE = 10, | ||
| 122 | USB_REQ_SET_INTERFACE = 11, | ||
| 123 | USB_REQ_SYNCH_FRAME = 12, | ||
| 124 | }; | ||
| 125 | |||
| 126 | /** | ||
| 127 | * \brief Standard USB device status flags | ||
| 128 | * | ||
| 129 | */ | ||
| 130 | enum usb_device_status { USB_DEV_STATUS_BUS_POWERED = 0, USB_DEV_STATUS_SELF_POWERED = 1, USB_DEV_STATUS_REMOTEWAKEUP = 2 }; | ||
| 131 | |||
| 132 | /** | ||
| 133 | * \brief Standard USB Interface status flags | ||
| 134 | * | ||
| 135 | */ | ||
| 136 | enum usb_interface_status { USB_IFACE_STATUS_RESERVED = 0 }; | ||
| 137 | |||
| 138 | /** | ||
| 139 | * \brief Standard USB endpoint status flags | ||
| 140 | * | ||
| 141 | */ | ||
| 142 | enum usb_endpoint_status { | ||
| 143 | USB_EP_STATUS_HALTED = 1, | ||
| 144 | }; | ||
| 145 | |||
| 146 | /** | ||
| 147 | * \brief Standard USB device feature flags | ||
| 148 | * | ||
| 149 | * \note valid for SetFeature request. | ||
| 150 | */ | ||
| 151 | enum usb_device_feature { | ||
| 152 | USB_DEV_FEATURE_REMOTE_WAKEUP = 1, //!< Remote wakeup enabled | ||
| 153 | USB_DEV_FEATURE_TEST_MODE = 2, //!< USB test mode | ||
| 154 | USB_DEV_FEATURE_OTG_B_HNP_ENABLE = 3, | ||
| 155 | USB_DEV_FEATURE_OTG_A_HNP_SUPPORT = 4, | ||
| 156 | USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT = 5 | ||
| 157 | }; | ||
| 158 | |||
| 159 | /** | ||
| 160 | * \brief Test Mode possible on HS USB device | ||
| 161 | * | ||
| 162 | * \note valid for USB_DEV_FEATURE_TEST_MODE request. | ||
| 163 | */ | ||
| 164 | enum usb_device_hs_test_mode { | ||
| 165 | USB_DEV_TEST_MODE_J = 1, | ||
| 166 | USB_DEV_TEST_MODE_K = 2, | ||
| 167 | USB_DEV_TEST_MODE_SE0_NAK = 3, | ||
| 168 | USB_DEV_TEST_MODE_PACKET = 4, | ||
| 169 | USB_DEV_TEST_MODE_FORCE_ENABLE = 5, | ||
| 170 | }; | ||
| 171 | |||
| 172 | /** | ||
| 173 | * \brief Standard USB endpoint feature/status flags | ||
| 174 | */ | ||
| 175 | enum usb_endpoint_feature { | ||
| 176 | USB_EP_FEATURE_HALT = 0, | ||
| 177 | }; | ||
| 178 | |||
| 179 | /** | ||
| 180 | * \brief Standard USB Test Mode Selectors | ||
| 181 | */ | ||
| 182 | enum usb_test_mode_selector { | ||
| 183 | USB_TEST_J = 0x01, | ||
| 184 | USB_TEST_K = 0x02, | ||
| 185 | USB_TEST_SE0_NAK = 0x03, | ||
| 186 | USB_TEST_PACKET = 0x04, | ||
| 187 | USB_TEST_FORCE_ENABLE = 0x05, | ||
| 188 | }; | ||
| 189 | |||
| 190 | /** | ||
| 191 | * \brief Standard USB descriptor types | ||
| 192 | */ | ||
| 193 | enum usb_descriptor_type { | ||
| 194 | USB_DT_DEVICE = 1, | ||
| 195 | USB_DT_CONFIGURATION = 2, | ||
| 196 | USB_DT_STRING = 3, | ||
| 197 | USB_DT_INTERFACE = 4, | ||
| 198 | USB_DT_ENDPOINT = 5, | ||
| 199 | USB_DT_DEVICE_QUALIFIER = 6, | ||
| 200 | USB_DT_OTHER_SPEED_CONFIGURATION = 7, | ||
| 201 | USB_DT_INTERFACE_POWER = 8, | ||
| 202 | USB_DT_OTG = 9, | ||
| 203 | USB_DT_IAD = 0x0B, | ||
| 204 | USB_DT_BOS = 0x0F, | ||
| 205 | USB_DT_DEVICE_CAPABILITY = 0x10, | ||
| 206 | }; | ||
| 207 | |||
| 208 | /** | ||
| 209 | * \brief USB Device Capability types | ||
| 210 | */ | ||
| 211 | enum usb_capability_type { | ||
| 212 | USB_DC_USB20_EXTENSION = 0x02, | ||
| 213 | }; | ||
| 214 | |||
| 215 | /** | ||
| 216 | * \brief USB Device Capability - USB 2.0 Extension | ||
| 217 | * To fill bmAttributes field of usb_capa_ext_desc_t structure. | ||
| 218 | */ | ||
| 219 | enum usb_capability_extension_attr { | ||
| 220 | USB_DC_EXT_LPM = 0x00000002, | ||
| 221 | }; | ||
| 222 | |||
| 223 | #define HIRD_50_US 0 | ||
| 224 | #define HIRD_125_US 1 | ||
| 225 | #define HIRD_200_US 2 | ||
| 226 | #define HIRD_275_US 3 | ||
| 227 | #define HIRD_350_US 4 | ||
| 228 | #define HIRD_425_US 5 | ||
| 229 | #define HIRD_500_US 6 | ||
| 230 | #define HIRD_575_US 7 | ||
| 231 | #define HIRD_650_US 8 | ||
| 232 | #define HIRD_725_US 9 | ||
| 233 | #define HIRD_800_US 10 | ||
| 234 | #define HIRD_875_US 11 | ||
| 235 | #define HIRD_950_US 12 | ||
| 236 | #define HIRD_1025_US 13 | ||
| 237 | #define HIRD_1100_US 14 | ||
| 238 | #define HIRD_1175_US 15 | ||
| 239 | |||
| 240 | /** Fields definition from a LPM TOKEN */ | ||
| 241 | #define USB_LPM_ATTRIBUT_BLINKSTATE_MASK (0xF << 0) | ||
| 242 | #define USB_LPM_ATTRIBUT_FIRD_MASK (0xF << 4) | ||
| 243 | #define USB_LPM_ATTRIBUT_REMOTEWAKE_MASK (1 << 8) | ||
| 244 | #define USB_LPM_ATTRIBUT_BLINKSTATE(value) ((value & 0xF) << 0) | ||
| 245 | #define USB_LPM_ATTRIBUT_FIRD(value) ((value & 0xF) << 4) | ||
| 246 | #define USB_LPM_ATTRIBUT_REMOTEWAKE(value) ((value & 1) << 8) | ||
| 247 | #define USB_LPM_ATTRIBUT_BLINKSTATE_L1 USB_LPM_ATTRIBUT_BLINKSTATE(1) | ||
| 248 | |||
| 249 | /** | ||
| 250 | * \brief Standard USB endpoint transfer types | ||
| 251 | */ | ||
| 252 | enum usb_ep_type { | ||
| 253 | USB_EP_TYPE_CONTROL = 0x00, | ||
| 254 | USB_EP_TYPE_ISOCHRONOUS = 0x01, | ||
| 255 | USB_EP_TYPE_BULK = 0x02, | ||
| 256 | USB_EP_TYPE_INTERRUPT = 0x03, | ||
| 257 | USB_EP_TYPE_MASK = 0x03, | ||
| 258 | }; | ||
| 259 | |||
| 260 | /** | ||
| 261 | * \brief Standard USB language IDs for string descriptors | ||
| 262 | */ | ||
| 263 | enum usb_langid { | ||
| 264 | USB_LANGID_EN_US = 0x0409, //!< English (United States) | ||
| 265 | }; | ||
| 266 | |||
| 267 | /** | ||
| 268 | * \brief Mask selecting the index part of an endpoint address | ||
| 269 | */ | ||
| 270 | #define USB_EP_ADDR_MASK 0x0f | ||
| 271 | |||
| 272 | //! \brief USB address identifier | ||
| 273 | typedef uint8_t usb_add_t; | ||
| 274 | |||
| 275 | /** | ||
| 276 | * \brief Endpoint transfer direction is IN | ||
| 277 | */ | ||
| 278 | #define USB_EP_DIR_IN 0x80 | ||
| 279 | |||
| 280 | /** | ||
| 281 | * \brief Endpoint transfer direction is OUT | ||
| 282 | */ | ||
| 283 | #define USB_EP_DIR_OUT 0x00 | ||
| 284 | |||
| 285 | //! \brief Endpoint identifier | ||
| 286 | typedef uint8_t usb_ep_t; | ||
| 287 | |||
| 288 | /** | ||
| 289 | * \brief Maximum length in bytes of a USB descriptor | ||
| 290 | * | ||
| 291 | * The maximum length of a USB descriptor is limited by the 8-bit | ||
| 292 | * bLength field. | ||
| 293 | */ | ||
| 294 | #define USB_MAX_DESC_LEN 255 | ||
| 295 | |||
| 296 | /* | ||
| 297 | * 2-byte alignment requested for all USB structures. | ||
| 298 | */ | ||
| 299 | COMPILER_PACK_SET(1) | ||
| 300 | |||
| 301 | /** | ||
| 302 | * \brief A USB Device SETUP request | ||
| 303 | * | ||
| 304 | * The data payload of SETUP packets always follows this structure. | ||
| 305 | */ | ||
| 306 | typedef struct { | ||
| 307 | uint8_t bmRequestType; | ||
| 308 | uint8_t bRequest; | ||
| 309 | le16_t wValue; | ||
| 310 | le16_t wIndex; | ||
| 311 | le16_t wLength; | ||
| 312 | } usb_setup_req_t; | ||
| 313 | |||
| 314 | /** | ||
| 315 | * \brief Standard USB device descriptor structure | ||
| 316 | */ | ||
| 317 | typedef struct { | ||
| 318 | uint8_t bLength; | ||
| 319 | uint8_t bDescriptorType; | ||
| 320 | le16_t bcdUSB; | ||
| 321 | uint8_t bDeviceClass; | ||
| 322 | uint8_t bDeviceSubClass; | ||
| 323 | uint8_t bDeviceProtocol; | ||
| 324 | uint8_t bMaxPacketSize0; | ||
| 325 | le16_t idVendor; | ||
| 326 | le16_t idProduct; | ||
| 327 | le16_t bcdDevice; | ||
| 328 | uint8_t iManufacturer; | ||
| 329 | uint8_t iProduct; | ||
| 330 | uint8_t iSerialNumber; | ||
| 331 | uint8_t bNumConfigurations; | ||
| 332 | } usb_dev_desc_t; | ||
| 333 | |||
| 334 | /** | ||
| 335 | * \brief Standard USB device qualifier descriptor structure | ||
| 336 | * | ||
| 337 | * This descriptor contains information about the device when running at | ||
| 338 | * the "other" speed (i.e. if the device is currently operating at high | ||
| 339 | * speed, this descriptor can be used to determine what would change if | ||
| 340 | * the device was operating at full speed.) | ||
| 341 | */ | ||
| 342 | typedef struct { | ||
| 343 | uint8_t bLength; | ||
| 344 | uint8_t bDescriptorType; | ||
| 345 | le16_t bcdUSB; | ||
| 346 | uint8_t bDeviceClass; | ||
| 347 | uint8_t bDeviceSubClass; | ||
| 348 | uint8_t bDeviceProtocol; | ||
| 349 | uint8_t bMaxPacketSize0; | ||
| 350 | uint8_t bNumConfigurations; | ||
| 351 | uint8_t bReserved; | ||
| 352 | } usb_dev_qual_desc_t; | ||
| 353 | |||
| 354 | /** | ||
| 355 | * \brief USB Device BOS descriptor structure | ||
| 356 | * | ||
| 357 | * The BOS descriptor (Binary device Object Store) defines a root | ||
| 358 | * descriptor that is similar to the configuration descriptor, and is | ||
| 359 | * the base descriptor for accessing a family of related descriptors. | ||
| 360 | * A host can read a BOS descriptor and learn from the wTotalLength field | ||
| 361 | * the entire size of the device-level descriptor set, or it can read in | ||
| 362 | * the entire BOS descriptor set of device capabilities. | ||
| 363 | * The host accesses this descriptor using the GetDescriptor() request. | ||
| 364 | * The descriptor type in the GetDescriptor() request is set to BOS. | ||
| 365 | */ | ||
| 366 | typedef struct { | ||
| 367 | uint8_t bLength; | ||
| 368 | uint8_t bDescriptorType; | ||
| 369 | le16_t wTotalLength; | ||
| 370 | uint8_t bNumDeviceCaps; | ||
| 371 | } usb_dev_bos_desc_t; | ||
| 372 | |||
| 373 | /** | ||
| 374 | * \brief USB Device Capabilities - USB 2.0 Extension Descriptor structure | ||
| 375 | * | ||
| 376 | * Defines the set of USB 1.1-specific device level capabilities. | ||
| 377 | */ | ||
| 378 | typedef struct { | ||
| 379 | uint8_t bLength; | ||
| 380 | uint8_t bDescriptorType; | ||
| 381 | uint8_t bDevCapabilityType; | ||
| 382 | le32_t bmAttributes; | ||
| 383 | } usb_dev_capa_ext_desc_t; | ||
| 384 | |||
| 385 | /** | ||
| 386 | * \brief USB Device LPM Descriptor structure | ||
| 387 | * | ||
| 388 | * The BOS descriptor and capabilities descriptors for LPM. | ||
| 389 | */ | ||
| 390 | typedef struct { | ||
| 391 | usb_dev_bos_desc_t bos; | ||
| 392 | usb_dev_capa_ext_desc_t capa_ext; | ||
| 393 | } usb_dev_lpm_desc_t; | ||
| 394 | |||
| 395 | /** | ||
| 396 | * \brief Standard USB Interface Association Descriptor structure | ||
| 397 | */ | ||
| 398 | typedef struct { | ||
| 399 | uint8_t bLength; //!< size of this descriptor in bytes | ||
| 400 | uint8_t bDescriptorType; //!< INTERFACE descriptor type | ||
| 401 | uint8_t bFirstInterface; //!< Number of interface | ||
| 402 | uint8_t bInterfaceCount; //!< value to select alternate setting | ||
| 403 | uint8_t bFunctionClass; //!< Class code assigned by the USB | ||
| 404 | uint8_t bFunctionSubClass; //!< Sub-class code assigned by the USB | ||
| 405 | uint8_t bFunctionProtocol; //!< Protocol code assigned by the USB | ||
| 406 | uint8_t iFunction; //!< Index of string descriptor | ||
| 407 | } usb_association_desc_t; | ||
| 408 | |||
| 409 | /** | ||
| 410 | * \brief Standard USB configuration descriptor structure | ||
| 411 | */ | ||
| 412 | typedef struct { | ||
| 413 | uint8_t bLength; | ||
| 414 | uint8_t bDescriptorType; | ||
| 415 | le16_t wTotalLength; | ||
| 416 | uint8_t bNumInterfaces; | ||
| 417 | uint8_t bConfigurationValue; | ||
| 418 | uint8_t iConfiguration; | ||
| 419 | uint8_t bmAttributes; | ||
| 420 | uint8_t bMaxPower; | ||
| 421 | } usb_conf_desc_t; | ||
| 422 | |||
| 423 | #define USB_CONFIG_ATTR_MUST_SET (1 << 7) //!< Must always be set | ||
| 424 | #define USB_CONFIG_ATTR_BUS_POWERED (0 << 6) //!< Bus-powered | ||
| 425 | #define USB_CONFIG_ATTR_SELF_POWERED (1 << 6) //!< Self-powered | ||
| 426 | #define USB_CONFIG_ATTR_REMOTE_WAKEUP (1 << 5) //!< remote wakeup supported | ||
| 427 | |||
| 428 | #define USB_CONFIG_MAX_POWER(ma) (((ma) + 1) / 2) //!< Max power in mA | ||
| 429 | |||
| 430 | /** | ||
| 431 | * \brief Standard USB association descriptor structure | ||
| 432 | */ | ||
| 433 | typedef struct { | ||
| 434 | uint8_t bLength; //!< Size of this descriptor in bytes | ||
| 435 | uint8_t bDescriptorType; //!< Interface descriptor type | ||
| 436 | uint8_t bFirstInterface; //!< Number of interface | ||
| 437 | uint8_t bInterfaceCount; //!< value to select alternate setting | ||
| 438 | uint8_t bFunctionClass; //!< Class code assigned by the USB | ||
| 439 | uint8_t bFunctionSubClass; //!< Sub-class code assigned by the USB | ||
| 440 | uint8_t bFunctionProtocol; //!< Protocol code assigned by the USB | ||
| 441 | uint8_t iFunction; //!< Index of string descriptor | ||
| 442 | } usb_iad_desc_t; | ||
| 443 | |||
| 444 | /** | ||
| 445 | * \brief Standard USB interface descriptor structure | ||
| 446 | */ | ||
| 447 | typedef struct { | ||
| 448 | uint8_t bLength; | ||
| 449 | uint8_t bDescriptorType; | ||
| 450 | uint8_t bInterfaceNumber; | ||
| 451 | uint8_t bAlternateSetting; | ||
| 452 | uint8_t bNumEndpoints; | ||
| 453 | uint8_t bInterfaceClass; | ||
| 454 | uint8_t bInterfaceSubClass; | ||
| 455 | uint8_t bInterfaceProtocol; | ||
| 456 | uint8_t iInterface; | ||
| 457 | } usb_iface_desc_t; | ||
| 458 | |||
| 459 | /** | ||
| 460 | * \brief Standard USB endpoint descriptor structure | ||
| 461 | */ | ||
| 462 | typedef struct { | ||
| 463 | uint8_t bLength; | ||
| 464 | uint8_t bDescriptorType; | ||
| 465 | uint8_t bEndpointAddress; | ||
| 466 | uint8_t bmAttributes; | ||
| 467 | le16_t wMaxPacketSize; | ||
| 468 | uint8_t bInterval; | ||
| 469 | } usb_ep_desc_t; | ||
| 470 | |||
| 471 | /** | ||
| 472 | * \brief A standard USB string descriptor structure | ||
| 473 | */ | ||
| 474 | typedef struct { | ||
| 475 | uint8_t bLength; | ||
| 476 | uint8_t bDescriptorType; | ||
| 477 | } usb_str_desc_t; | ||
| 478 | |||
| 479 | typedef struct { | ||
| 480 | usb_str_desc_t desc; | ||
| 481 | le16_t string[1]; | ||
| 482 | } usb_str_lgid_desc_t; | ||
| 483 | |||
| 484 | COMPILER_PACK_RESET() | ||
| 485 | |||
| 486 | //! @} | ||
| 487 | |||
| 488 | #endif /* _USB_PROTOCOL_H_ */ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/usb_protocol_cdc.h b/tmk_core/protocol/arm_atsam/usb/usb_protocol_cdc.h deleted file mode 100644 index 1d36d58dbd..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/usb_protocol_cdc.h +++ /dev/null | |||
| @@ -1,190 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief USB Communication Device Class (CDC) protocol definitions | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | #ifndef _USB_PROTOCOL_CDC_H_ | ||
| 47 | #define _USB_PROTOCOL_CDC_H_ | ||
| 48 | |||
| 49 | #include "compiler.h" | ||
| 50 | |||
| 51 | #ifdef VIRTSER_ENABLE | ||
| 52 | |||
| 53 | # define CDC_CLASS_DEVICE 0x02 //!< USB Communication Device Class | ||
| 54 | # define CDC_CLASS_COMM 0x02 //!< CDC Communication Class Interface | ||
| 55 | # define CDC_CLASS_DATA 0x0A //!< CDC Data Class Interface | ||
| 56 | |||
| 57 | # define CDC_SUBCLASS_DLCM 0x01 //!< Direct Line Control Model | ||
| 58 | # define CDC_SUBCLASS_ACM 0x02 //!< Abstract Control Model | ||
| 59 | # define CDC_SUBCLASS_TCM 0x03 //!< Telephone Control Model | ||
| 60 | # define CDC_SUBCLASS_MCCM 0x04 //!< Multi-Channel Control Model | ||
| 61 | # define CDC_SUBCLASS_CCM 0x05 //!< CAPI Control Model | ||
| 62 | # define CDC_SUBCLASS_ETH 0x06 //!< Ethernet Networking Control Model | ||
| 63 | # define CDC_SUBCLASS_ATM 0x07 //!< ATM Networking Control Model | ||
| 64 | |||
| 65 | # define CDC_PROTOCOL_V25TER 0x01 //!< Common AT commands | ||
| 66 | |||
| 67 | # define CDC_PROTOCOL_I430 0x30 //!< ISDN BRI | ||
| 68 | # define CDC_PROTOCOL_HDLC 0x31 //!< HDLC | ||
| 69 | # define CDC_PROTOCOL_TRANS 0x32 //!< Transparent | ||
| 70 | # define CDC_PROTOCOL_Q921M 0x50 //!< Q.921 management protocol | ||
| 71 | # define CDC_PROTOCOL_Q921 0x51 //!< Q.931 [sic] Data link protocol | ||
| 72 | # define CDC_PROTOCOL_Q921TM 0x52 //!< Q.921 TEI-multiplexor | ||
| 73 | # define CDC_PROTOCOL_V42BIS 0x90 //!< Data compression procedures | ||
| 74 | # define CDC_PROTOCOL_Q931 0x91 //!< Euro-ISDN protocol control | ||
| 75 | # define CDC_PROTOCOL_V120 0x92 //!< V.24 rate adaption to ISDN | ||
| 76 | # define CDC_PROTOCOL_CAPI20 0x93 //!< CAPI Commands | ||
| 77 | # define CDC_PROTOCOL_HOST 0xFD //!< Host based driver | ||
| 78 | |||
| 79 | # define CDC_PROTOCOL_PUFD 0xFE | ||
| 80 | |||
| 81 | # define CDC_CS_INTERFACE 0x24 //!< Interface Functional Descriptor | ||
| 82 | # define CDC_CS_ENDPOINT 0x25 //!< Endpoint Functional Descriptor | ||
| 83 | |||
| 84 | # define CDC_SCS_HEADER 0x00 //!< Header Functional Descriptor | ||
| 85 | # define CDC_SCS_CALL_MGMT 0x01 //!< Call Management | ||
| 86 | # define CDC_SCS_ACM 0x02 //!< Abstract Control Management | ||
| 87 | # define CDC_SCS_UNION 0x06 //!< Union Functional Descriptor | ||
| 88 | |||
| 89 | # define USB_REQ_CDC_SEND_ENCAPSULATED_COMMAND 0x00 | ||
| 90 | # define USB_REQ_CDC_GET_ENCAPSULATED_RESPONSE 0x01 | ||
| 91 | # define USB_REQ_CDC_SET_COMM_FEATURE 0x02 | ||
| 92 | # define USB_REQ_CDC_GET_COMM_FEATURE 0x03 | ||
| 93 | # define USB_REQ_CDC_CLEAR_COMM_FEATURE 0x04 | ||
| 94 | # define USB_REQ_CDC_SET_AUX_LINE_STATE 0x10 | ||
| 95 | # define USB_REQ_CDC_SET_HOOK_STATE 0x11 | ||
| 96 | # define USB_REQ_CDC_PULSE_SETUP 0x12 | ||
| 97 | # define USB_REQ_CDC_SEND_PULSE 0x13 | ||
| 98 | # define USB_REQ_CDC_SET_PULSE_TIME 0x14 | ||
| 99 | # define USB_REQ_CDC_RING_AUX_JACK 0x15 | ||
| 100 | # define USB_REQ_CDC_SET_LINE_CODING 0x20 | ||
| 101 | # define USB_REQ_CDC_GET_LINE_CODING 0x21 | ||
| 102 | # define USB_REQ_CDC_SET_CONTROL_LINE_STATE 0x22 | ||
| 103 | # define USB_REQ_CDC_SEND_BREAK 0x23 | ||
| 104 | # define USB_REQ_CDC_SET_RINGER_PARMS 0x30 | ||
| 105 | # define USB_REQ_CDC_GET_RINGER_PARMS 0x31 | ||
| 106 | # define USB_REQ_CDC_SET_OPERATION_PARMS 0x32 | ||
| 107 | # define USB_REQ_CDC_GET_OPERATION_PARMS 0x33 | ||
| 108 | # define USB_REQ_CDC_SET_LINE_PARMS 0x34 | ||
| 109 | # define USB_REQ_CDC_GET_LINE_PARMS 0x35 | ||
| 110 | # define USB_REQ_CDC_DIAL_DIGITS 0x36 | ||
| 111 | # define USB_REQ_CDC_SET_UNIT_PARAMETER 0x37 | ||
| 112 | # define USB_REQ_CDC_GET_UNIT_PARAMETER 0x38 | ||
| 113 | # define USB_REQ_CDC_CLEAR_UNIT_PARAMETER 0x39 | ||
| 114 | # define USB_REQ_CDC_GET_PROFILE 0x3A | ||
| 115 | # define USB_REQ_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 | ||
| 116 | # define USB_REQ_CDC_SET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x41 | ||
| 117 | # define USB_REQ_CDC_GET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x42 | ||
| 118 | # define USB_REQ_CDC_SET_ETHERNET_PACKET_FILTER 0x43 | ||
| 119 | # define USB_REQ_CDC_GET_ETHERNET_STATISTIC 0x44 | ||
| 120 | # define USB_REQ_CDC_SET_ATM_DATA_FORMAT 0x50 | ||
| 121 | # define USB_REQ_CDC_GET_ATM_DEVICE_STATISTICS 0x51 | ||
| 122 | # define USB_REQ_CDC_SET_ATM_DEFAULT_VC 0x52 | ||
| 123 | # define USB_REQ_CDC_GET_ATM_VC_STATISTICS 0x53 | ||
| 124 | // Added bNotification codes according cdc spec 1.1 chapter 6.3 | ||
| 125 | # define USB_REQ_CDC_NOTIFY_RING_DETECT 0x09 | ||
| 126 | # define USB_REQ_CDC_NOTIFY_SERIAL_STATE 0x20 | ||
| 127 | # define USB_REQ_CDC_NOTIFY_CALL_STATE_CHANGE 0x28 | ||
| 128 | # define USB_REQ_CDC_NOTIFY_LINE_STATE_CHANGE 0x29 | ||
| 129 | |||
| 130 | # define CDC_CALL_MGMT_SUPPORTED (1 << 0) | ||
| 131 | # define CDC_CALL_MGMT_OVER_DCI (1 << 1) | ||
| 132 | # define CDC_ACM_SUPPORT_FEATURE_REQUESTS (1 << 0) | ||
| 133 | # define CDC_ACM_SUPPORT_LINE_REQUESTS (1 << 1) | ||
| 134 | # define CDC_ACM_SUPPORT_SENDBREAK_REQUESTS (1 << 2) | ||
| 135 | # define CDC_ACM_SUPPORT_NOTIFY_REQUESTS (1 << 3) | ||
| 136 | |||
| 137 | # pragma pack(push, 1) | ||
| 138 | typedef struct { | ||
| 139 | le32_t dwDTERate; | ||
| 140 | uint8_t bCharFormat; | ||
| 141 | uint8_t bParityType; | ||
| 142 | uint8_t bDataBits; | ||
| 143 | } usb_cdc_line_coding_t; | ||
| 144 | # pragma pack(pop) | ||
| 145 | |||
| 146 | enum cdc_char_format { | ||
| 147 | CDC_STOP_BITS_1 = 0, //!< 1 stop bit | ||
| 148 | CDC_STOP_BITS_1_5 = 1, //!< 1.5 stop bits | ||
| 149 | CDC_STOP_BITS_2 = 2, //!< 2 stop bits | ||
| 150 | }; | ||
| 151 | |||
| 152 | enum cdc_parity { | ||
| 153 | CDC_PAR_NONE = 0, //!< No parity | ||
| 154 | CDC_PAR_ODD = 1, //!< Odd parity | ||
| 155 | CDC_PAR_EVEN = 2, //!< Even parity | ||
| 156 | CDC_PAR_MARK = 3, //!< Parity forced to 0 (space) | ||
| 157 | CDC_PAR_SPACE = 4, //!< Parity forced to 1 (mark) | ||
| 158 | }; | ||
| 159 | |||
| 160 | typedef struct { | ||
| 161 | uint16_t value; | ||
| 162 | } usb_cdc_control_signal_t; | ||
| 163 | |||
| 164 | # define CDC_CTRL_SIGNAL_ACTIVATE_CARRIER (1 << 1) | ||
| 165 | # define CDC_CTRL_SIGNAL_DTE_PRESENT (1 << 0) | ||
| 166 | |||
| 167 | typedef struct { | ||
| 168 | uint8_t bmRequestType; | ||
| 169 | uint8_t bNotification; | ||
| 170 | le16_t wValue; | ||
| 171 | le16_t wIndex; | ||
| 172 | le16_t wLength; | ||
| 173 | } usb_cdc_notify_msg_t; | ||
| 174 | |||
| 175 | typedef struct { | ||
| 176 | usb_cdc_notify_msg_t header; | ||
| 177 | le16_t value; | ||
| 178 | } usb_cdc_notify_serial_state_t; | ||
| 179 | |||
| 180 | # define CDC_SERIAL_STATE_DCD CPU_TO_LE16((1 << 0)) | ||
| 181 | # define CDC_SERIAL_STATE_DSR CPU_TO_LE16((1 << 1)) | ||
| 182 | # define CDC_SERIAL_STATE_BREAK CPU_TO_LE16((1 << 2)) | ||
| 183 | # define CDC_SERIAL_STATE_RING CPU_TO_LE16((1 << 3)) | ||
| 184 | # define CDC_SERIAL_STATE_FRAMING CPU_TO_LE16((1 << 4)) | ||
| 185 | # define CDC_SERIAL_STATE_PARITY CPU_TO_LE16((1 << 5)) | ||
| 186 | # define CDC_SERIAL_STATE_OVERRUN CPU_TO_LE16((1 << 6)) | ||
| 187 | |||
| 188 | #endif | ||
| 189 | |||
| 190 | #endif // _USB_PROTOCOL_CDC_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/usb_protocol_hid.h b/tmk_core/protocol/arm_atsam/usb/usb_protocol_hid.h deleted file mode 100644 index c984c0762f..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/usb_protocol_hid.h +++ /dev/null | |||
| @@ -1,317 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file | ||
| 3 | * | ||
| 4 | * \brief USB Human Interface Device (HID) protocol definitions. | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. | ||
| 7 | * | ||
| 8 | * \asf_license_start | ||
| 9 | * | ||
| 10 | * \page License | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or without | ||
| 13 | * modification, are permitted provided that the following conditions are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 16 | * this list of conditions and the following disclaimer. | ||
| 17 | * | ||
| 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 19 | * this list of conditions and the following disclaimer in the documentation | ||
| 20 | * and/or other materials provided with the distribution. | ||
| 21 | * | ||
| 22 | * 3. The name of Atmel may not be used to endorse or promote products derived | ||
| 23 | * from this software without specific prior written permission. | ||
| 24 | * | ||
| 25 | * 4. This software may only be redistributed and used in connection with an | ||
| 26 | * Atmel microcontroller product. | ||
| 27 | * | ||
| 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | ||
| 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | ||
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 38 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 39 | * | ||
| 40 | * \asf_license_stop | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | /* | ||
| 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> | ||
| 45 | */ | ||
| 46 | |||
| 47 | #ifndef _USB_PROTOCOL_HID_H_ | ||
| 48 | #define _USB_PROTOCOL_HID_H_ | ||
| 49 | |||
| 50 | /** | ||
| 51 | * \ingroup usb_protocol_group | ||
| 52 | * \defgroup usb_hid_protocol USB Human Interface Device (HID) | ||
| 53 | * protocol definitions | ||
| 54 | * \brief USB Human Interface Device (HID) protocol definitions | ||
| 55 | * | ||
| 56 | * @{ | ||
| 57 | */ | ||
| 58 | |||
| 59 | //! \name Possible Class value | ||
| 60 | //@{ | ||
| 61 | #define HID_CLASS 0x03 | ||
| 62 | //@} | ||
| 63 | |||
| 64 | //! \name Possible SubClass value | ||
| 65 | //@{ | ||
| 66 | //! Interface subclass NO support BOOT protocol | ||
| 67 | #define HID_SUB_CLASS_NOBOOT 0x00 | ||
| 68 | //! Interface subclass support BOOT protocol | ||
| 69 | #define HID_SUB_CLASS_BOOT 0x01 | ||
| 70 | //@} | ||
| 71 | |||
| 72 | //! \name Possible protocol value | ||
| 73 | //@{ | ||
| 74 | //! Protocol generic standard | ||
| 75 | #define HID_PROTOCOL_GENERIC 0x00 | ||
| 76 | //! Protocol keyboard standard | ||
| 77 | #define HID_PROTOCOL_KEYBOARD 0x01 | ||
| 78 | //! Protocol mouse standard | ||
| 79 | #define HID_PROTOCOL_MOUSE 0x02 | ||
| 80 | //@} | ||
| 81 | |||
| 82 | //! \brief Hid USB requests (bRequest) | ||
| 83 | enum usb_reqid_hid { | ||
| 84 | USB_REQ_HID_GET_REPORT = 0x01, | ||
| 85 | USB_REQ_HID_GET_IDLE = 0x02, | ||
| 86 | USB_REQ_HID_GET_PROTOCOL = 0x03, | ||
| 87 | USB_REQ_HID_SET_REPORT = 0x09, | ||
| 88 | USB_REQ_HID_SET_IDLE = 0x0A, | ||
| 89 | USB_REQ_HID_SET_PROTOCOL = 0x0B, | ||
| 90 | }; | ||
| 91 | |||
| 92 | //! \brief HID USB descriptor types | ||
| 93 | enum usb_descriptor_type_hid { | ||
| 94 | USB_DT_HID = 0x21, | ||
| 95 | USB_DT_HID_REPORT = 0x22, | ||
| 96 | USB_DT_HID_PHYSICAL = 0x23, | ||
| 97 | }; | ||
| 98 | |||
| 99 | //! \brief HID Type for report descriptor | ||
| 100 | enum usb_hid_item_report_type { | ||
| 101 | USB_HID_ITEM_REPORT_TYPE_MAIN = 0, | ||
| 102 | USB_HID_ITEM_REPORT_TYPE_GLOBAL = 1, | ||
| 103 | USB_HID_ITEM_REPORT_TYPE_LOCAL = 2, | ||
| 104 | USB_HID_ITEM_REPORT_TYPE_LONG = 3, | ||
| 105 | }; | ||
| 106 | |||
| 107 | //! \brief HID report type | ||
| 108 | enum usb_hid_report_type { | ||
| 109 | USB_HID_REPORT_TYPE_INPUT = 1, | ||
| 110 | USB_HID_REPORT_TYPE_OUTPUT = 2, | ||
| 111 | USB_HID_REPORT_TYPE_FEATURE = 3, | ||
| 112 | }; | ||
| 113 | |||
| 114 | //! \brief HID protocol | ||
| 115 | enum usb_hid_protocol { | ||
| 116 | USB_HID_PROCOTOL_BOOT = 0, | ||
| 117 | USB_HID_PROCOTOL_REPORT = 1, | ||
| 118 | }; | ||
| 119 | |||
| 120 | COMPILER_PACK_SET(1) | ||
| 121 | |||
| 122 | //! \brief HID Descriptor | ||
| 123 | typedef struct { | ||
| 124 | uint8_t bLength; //!< Size of this descriptor in bytes | ||
| 125 | uint8_t bDescriptorType; //!< HID descriptor type | ||
| 126 | le16_t bcdHID; //!< Binary Coded Decimal Spec. release | ||
| 127 | uint8_t bCountryCode; //!< Hardware target country | ||
| 128 | uint8_t bNumDescriptors; //!< Number of HID class descriptors to follow | ||
| 129 | uint8_t bRDescriptorType; //!< Report descriptor type | ||
| 130 | le16_t wDescriptorLength; //!< Total length of Report descriptor | ||
| 131 | } usb_hid_descriptor_t; | ||
| 132 | |||
| 133 | COMPILER_PACK_RESET() | ||
| 134 | |||
| 135 | //! \name HID Report type | ||
| 136 | //! Used by SETUP_HID_GET_REPORT & SETUP_HID_SET_REPORT | ||
| 137 | //! @{ | ||
| 138 | #define REPORT_TYPE_INPUT 0x01 | ||
| 139 | #define REPORT_TYPE_OUTPUT 0x02 | ||
| 140 | #define REPORT_TYPE_FEATURE 0x03 | ||
| 141 | //! @} | ||
| 142 | |||
| 143 | //! \name Constants of field DESCRIPTOR_HID | ||
| 144 | //! @{ | ||
| 145 | //! Numeric expression identifying the HID Class | ||
| 146 | //! Specification release (here V1.11) | ||
| 147 | #define USB_HID_BDC_V1_11 0x0111 | ||
| 148 | //! Numeric expression specifying the number of class descriptors | ||
| 149 | //! Note: Always at least one i.e. Report descriptor. | ||
| 150 | #define USB_HID_NUM_DESC 0x01 | ||
| 151 | |||
| 152 | //! \name Country code | ||
| 153 | //! @{ | ||
| 154 | #define USB_HID_NO_COUNTRY_CODE 0 // Not Supported | ||
| 155 | #define USB_HID_COUNTRY_ARABIC 1 // Arabic | ||
| 156 | #define USB_HID_COUNTRY_BELGIAN 2 // Belgian | ||
| 157 | #define USB_HID_COUNTRY_CANADIAN_BILINGUAL 3 // Canadian-Bilingual | ||
| 158 | #define USB_HID_COUNTRY_CANADIAN_FRENCH 4 // Canadian-French | ||
| 159 | #define USB_HID_COUNTRY_CZECH_REPUBLIC 5 // Czech Republic | ||
| 160 | #define USB_HID_COUNTRY_DANISH 6 // Danish | ||
| 161 | #define USB_HID_COUNTRY_FINNISH 7 // Finnish | ||
| 162 | #define USB_HID_COUNTRY_FRENCH 8 // French | ||
| 163 | #define USB_HID_COUNTRY_GERMAN 9 // German | ||
| 164 | #define USB_HID_COUNTRY_GREEK 10 // Greek | ||
| 165 | #define USB_HID_COUNTRY_HEBREW 11 // Hebrew | ||
| 166 | #define USB_HID_COUNTRY_HUNGARY 12 // Hungary | ||
| 167 | #define USB_HID_COUNTRY_INTERNATIONAL_ISO 13 // International (ISO) | ||
| 168 | #define USB_HID_COUNTRY_ITALIAN 14 // Italian | ||
| 169 | #define USB_HID_COUNTRY_JAPAN_KATAKANA 15 // Japan (Katakana) | ||
| 170 | #define USB_HID_COUNTRY_KOREAN 16 // Korean | ||
| 171 | #define USB_HID_COUNTRY_LATIN_AMERICAN 17 // Latin American | ||
| 172 | #define USB_HID_COUNTRY_NETHERLANDS_DUTCH 18 // Netherlands/Dutch | ||
| 173 | #define USB_HID_COUNTRY_NORWEGIAN 19 // Norwegian | ||
| 174 | #define USB_HID_COUNTRY_PERSIAN_FARSI 20 // Persian (Farsi) | ||
| 175 | #define USB_HID_COUNTRY_POLAND 21 // Poland | ||
| 176 | #define USB_HID_COUNTRY_PORTUGUESE 22 // Portuguese | ||
| 177 | #define USB_HID_COUNTRY_RUSSIA 23 // Russia | ||
| 178 | #define USB_HID_COUNTRY_SLOVAKIA 24 // Slovakia | ||
| 179 | #define USB_HID_COUNTRY_SPANISH 25 // Spanish | ||
| 180 | #define USB_HID_COUNTRY_SWEDISH 26 // Swedish | ||
| 181 | #define USB_HID_COUNTRY_SWISS_FRENCH 27 // Swiss/French | ||
| 182 | #define USB_HID_COUNTRY_SWISS_GERMAN 28 // Swiss/German | ||
| 183 | #define USB_HID_COUNTRY_SWITZERLAND 29 // Switzerland | ||
| 184 | #define USB_HID_COUNTRY_TAIWAN 30 // Taiwan | ||
| 185 | #define USB_HID_COUNTRY_TURKISH_Q 31 // Turkish-Q | ||
| 186 | #define USB_HID_COUNTRY_UK 32 // UK | ||
| 187 | #define USB_HID_COUNTRY_US 33 // US | ||
| 188 | #define USB_HID_COUNTRY_YUGOSLAVIA 34 // Yugoslavia | ||
| 189 | #define USB_HID_COUNTRY_TURKISH_F \ | ||
| 190 | 35 // Turkish-F | ||
| 191 | //! @} | ||
| 192 | //! @} | ||
| 193 | //! @} | ||
| 194 | |||
| 195 | //! \name HID KEYS values | ||
| 196 | //! @{ | ||
| 197 | #define HID_A 0x04 | ||
| 198 | #define HID_B 0x05 | ||
| 199 | #define HID_C 0x06 | ||
| 200 | #define HID_D 0x07 | ||
| 201 | #define HID_E 0x08 | ||
| 202 | #define HID_F 0x09 | ||
| 203 | #define HID_G 0x0A | ||
| 204 | #define HID_H 0x0B | ||
| 205 | #define HID_I 0x0C | ||
| 206 | #define HID_J 0x0D | ||
| 207 | #define HID_K 0x0E | ||
| 208 | #define HID_L 0x0F | ||
| 209 | #define HID_M 0x10 | ||
| 210 | #define HID_N 0x11 | ||
| 211 | #define HID_O 0x12 | ||
| 212 | #define HID_P 0x13 | ||
| 213 | #define HID_Q 0x14 | ||
| 214 | #define HID_R 0x15 | ||
| 215 | #define HID_S 0x16 | ||
| 216 | #define HID_T 0x17 | ||
| 217 | #define HID_U 0x18 | ||
| 218 | #define HID_V 0x19 | ||
| 219 | #define HID_W 0x1A | ||
| 220 | #define HID_X 0x1B | ||
| 221 | #define HID_Y 0x1C | ||
| 222 | #define HID_Z 0x1D | ||
| 223 | #define HID_1 30 | ||
| 224 | #define HID_2 31 | ||
| 225 | #define HID_3 32 | ||
| 226 | #define HID_4 33 | ||
| 227 | #define HID_5 34 | ||
| 228 | #define HID_6 35 | ||
| 229 | #define HID_7 36 | ||
| 230 | #define HID_8 37 | ||
| 231 | #define HID_9 38 | ||
| 232 | #define HID_0 39 | ||
| 233 | #define HID_ENTER 40 | ||
| 234 | #define HID_ESCAPE 41 | ||
| 235 | #define HID_BACKSPACE 42 | ||
| 236 | #define HID_TAB 43 | ||
| 237 | #define HID_SPACEBAR 44 | ||
| 238 | #define HID_UNDERSCORE 45 | ||
| 239 | #define HID_PLUS 46 | ||
| 240 | #define HID_OPEN_BRACKET 47 // { | ||
| 241 | #define HID_CLOSE_BRACKET 48 // } | ||
| 242 | #define HID_BACKSLASH 49 | ||
| 243 | #define HID_ASH 50 // # ~ | ||
| 244 | #define HID_COLON 51 // ; : | ||
| 245 | #define HID_QUOTE 52 // ' " | ||
| 246 | #define HID_TILDE 53 | ||
| 247 | #define HID_COMMA 54 | ||
| 248 | #define HID_DOT 55 | ||
| 249 | #define HID_SLASH 56 | ||
| 250 | #define HID_CAPS_LOCK 57 | ||
| 251 | #define HID_F1 58 | ||
| 252 | #define HID_F2 59 | ||
| 253 | #define HID_F3 60 | ||
| 254 | #define HID_F4 61 | ||
| 255 | #define HID_F5 62 | ||
| 256 | #define HID_F6 63 | ||
| 257 | #define HID_F7 64 | ||
| 258 | #define HID_F8 65 | ||
| 259 | #define HID_F9 66 | ||
| 260 | #define HID_F10 67 | ||
| 261 | #define HID_F11 68 | ||
| 262 | #define HID_F12 69 | ||
| 263 | #define HID_PRINTSCREEN 70 | ||
| 264 | #define HID_SCROLL_LOCK 71 | ||
| 265 | #define HID_PAUSE 72 | ||
| 266 | #define HID_INSERT 73 | ||
| 267 | #define HID_HOME 74 | ||
| 268 | #define HID_PAGEUP 75 | ||
| 269 | #define HID_DELETE 76 | ||
| 270 | #define HID_END 77 | ||
| 271 | #define HID_PAGEDOWN 78 | ||
| 272 | #define HID_RIGHT 79 | ||
| 273 | #define HID_LEFT 80 | ||
| 274 | #define HID_DOWN 81 | ||
| 275 | #define HID_UP 82 | ||
| 276 | #define HID_KEYPAD_NUM_LOCK 83 | ||
| 277 | #define HID_KEYPAD_DIVIDE 84 | ||
| 278 | #define HID_KEYPAD_AT 85 | ||
| 279 | #define HID_KEYPAD_MULTIPLY 85 | ||
| 280 | #define HID_KEYPAD_MINUS 86 | ||
| 281 | #define HID_KEYPAD_PLUS 87 | ||
| 282 | #define HID_KEYPAD_ENTER 88 | ||
| 283 | #define HID_KEYPAD_1 89 | ||
| 284 | #define HID_KEYPAD_2 90 | ||
| 285 | #define HID_KEYPAD_3 91 | ||
| 286 | #define HID_KEYPAD_4 92 | ||
| 287 | #define HID_KEYPAD_5 93 | ||
| 288 | #define HID_KEYPAD_6 94 | ||
| 289 | #define HID_KEYPAD_7 95 | ||
| 290 | #define HID_KEYPAD_8 96 | ||
| 291 | #define HID_KEYPAD_9 97 | ||
| 292 | #define HID_KEYPAD_0 98 | ||
| 293 | |||
| 294 | //! \name HID modifier values | ||
| 295 | //! @{ | ||
| 296 | #define HID_MODIFIER_NONE 0x00 | ||
| 297 | #define HID_MODIFIER_LEFT_CTRL 0x01 | ||
| 298 | #define HID_MODIFIER_LEFT_SHIFT 0x02 | ||
| 299 | #define HID_MODIFIER_LEFT_ALT 0x04 | ||
| 300 | #define HID_MODIFIER_LEFT_UI 0x08 | ||
| 301 | #define HID_MODIFIER_RIGHT_CTRL 0x10 | ||
| 302 | #define HID_MODIFIER_RIGHT_SHIFT 0x20 | ||
| 303 | #define HID_MODIFIER_RIGHT_ALT 0x40 | ||
| 304 | #define HID_MODIFIER_RIGHT_UI 0x80 | ||
| 305 | //! @} | ||
| 306 | //! @} | ||
| 307 | |||
| 308 | //! \name HID KEYS values | ||
| 309 | //! @{ | ||
| 310 | #define HID_LED_NUM_LOCK (1 << 0) | ||
| 311 | #define HID_LED_CAPS_LOCK (1 << 1) | ||
| 312 | #define HID_LED_SCROLL_LOCK (1 << 2) | ||
| 313 | #define HID_LED_COMPOSE (1 << 3) | ||
| 314 | #define HID_LED_KANA (1 << 4) | ||
| 315 | //! @} | ||
| 316 | |||
| 317 | #endif // _USB_PROTOCOL_HID_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/usb_util.c b/tmk_core/protocol/arm_atsam/usb/usb_util.c deleted file mode 100644 index c7555c84c6..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/usb_util.c +++ /dev/null | |||
| @@ -1,49 +0,0 @@ | |||
| 1 | #include "samd51j18a.h" | ||
| 2 | #include "string.h" | ||
| 3 | #include "usb_util.h" | ||
| 4 | |||
| 5 | char digit(int d, int radix) { | ||
| 6 | if (d < 10) { | ||
| 7 | return d + '0'; | ||
| 8 | } else { | ||
| 9 | return d - 10 + 'A'; | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | int UTIL_ltoa_radix(int64_t value, char *dest, int radix) { | ||
| 14 | int64_t original = value; // save original value | ||
| 15 | char buf[25] = ""; | ||
| 16 | int c = sizeof(buf) - 1; | ||
| 17 | int last = c; | ||
| 18 | int d; | ||
| 19 | int size; | ||
| 20 | |||
| 21 | if (value < 0) // if it's negative, take the absolute value | ||
| 22 | value = -value; | ||
| 23 | |||
| 24 | do // write least significant digit of value that's left | ||
| 25 | { | ||
| 26 | d = (value % radix); | ||
| 27 | buf[--c] = digit(d, radix); | ||
| 28 | value /= radix; | ||
| 29 | } while (value); | ||
| 30 | |||
| 31 | if (original < 0) buf[--c] = '-'; | ||
| 32 | |||
| 33 | size = last - c + 1; // includes null at end | ||
| 34 | memcpy(dest, &buf[c], last - c + 1); | ||
| 35 | |||
| 36 | return (size - 1); // without null termination | ||
| 37 | } | ||
| 38 | |||
| 39 | int UTIL_ltoa(int64_t value, char *dest) { | ||
| 40 | return UTIL_ltoa_radix(value, dest, 10); | ||
| 41 | } | ||
| 42 | |||
| 43 | int UTIL_itoa(int value, char *dest) { | ||
| 44 | return UTIL_ltoa_radix((int64_t)value, dest, 10); | ||
| 45 | } | ||
| 46 | |||
| 47 | int UTIL_utoa(uint32_t value, char *dest) { | ||
| 48 | return UTIL_ltoa_radix((int64_t)value, dest, 10); | ||
| 49 | } | ||
diff --git a/tmk_core/protocol/arm_atsam/usb/usb_util.h b/tmk_core/protocol/arm_atsam/usb/usb_util.h deleted file mode 100644 index 3e5b4fbb32..0000000000 --- a/tmk_core/protocol/arm_atsam/usb/usb_util.h +++ /dev/null | |||
| @@ -1,9 +0,0 @@ | |||
| 1 | #ifndef _USB_UTIL_H_ | ||
| 2 | #define _USB_UTIL_H_ | ||
| 3 | |||
| 4 | int UTIL_ltoa_radix(int64_t value, char *dest, int radix); | ||
| 5 | int UTIL_ltoa(int64_t value, char *dest); | ||
| 6 | int UTIL_itoa(int value, char *dest); | ||
| 7 | int UTIL_utoa(uint32_t value, char *dest); | ||
| 8 | |||
| 9 | #endif //_USB_UTIL_H_ | ||
diff --git a/tmk_core/protocol/arm_atsam/wait_api.h b/tmk_core/protocol/arm_atsam/wait_api.h deleted file mode 100644 index b3918e5346..0000000000 --- a/tmk_core/protocol/arm_atsam/wait_api.h +++ /dev/null | |||
| @@ -1,7 +0,0 @@ | |||
| 1 | #ifndef _wait_api_h_ | ||
| 2 | #define _wait_api_h_ | ||
| 3 | |||
| 4 | void wait_ms(uint64_t msec); | ||
| 5 | void wait_us(uint16_t usec); | ||
| 6 | |||
| 7 | #endif | ||
diff --git a/tmk_core/protocol/usb_descriptor.h b/tmk_core/protocol/usb_descriptor.h index ecfb022702..1de8c5ec88 100644 --- a/tmk_core/protocol/usb_descriptor.h +++ b/tmk_core/protocol/usb_descriptor.h | |||
| @@ -279,8 +279,6 @@ enum usb_endpoints { | |||
| 279 | # define MAX_ENDPOINTS USB_MAX_ENDPOINTS | 279 | # define MAX_ENDPOINTS USB_MAX_ENDPOINTS |
| 280 | #endif | 280 | #endif |
| 281 | 281 | ||
| 282 | // TODO - ARM_ATSAM | ||
| 283 | |||
| 284 | #if (NEXT_EPNUM - 1) > MAX_ENDPOINTS | 282 | #if (NEXT_EPNUM - 1) > MAX_ENDPOINTS |
| 285 | # 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 | 283 | # 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 |
| 286 | #endif | 284 | #endif |
