summaryrefslogtreecommitdiff
path: root/tmk_core
diff options
context:
space:
mode:
authorJoel Challis <git@zvecr.com>2024-09-02 03:48:17 +0100
committerGitHub <noreply@github.com>2024-09-02 03:48:17 +0100
commit3bd303f204a59ed950934f5da4c299a8be33b363 (patch)
tree17ff660931b925909be4a75fba55bd67441bf2bb /tmk_core
parent096aca63c5d7789669d90ef5f128189be85b7a35 (diff)
Remove `arm_atsam` platform (#24337)
Diffstat (limited to 'tmk_core')
-rw-r--r--tmk_core/protocol/arm_atsam/adc.c115
-rw-r--r--tmk_core/protocol/arm_atsam/adc.h37
-rw-r--r--tmk_core/protocol/arm_atsam/arm_atsam.mk31
-rw-r--r--tmk_core/protocol/arm_atsam/arm_atsam_protocol.h47
-rw-r--r--tmk_core/protocol/arm_atsam/clks.c436
-rw-r--r--tmk_core/protocol/arm_atsam/clks.h89
-rw-r--r--tmk_core/protocol/arm_atsam/d51_util.c244
-rw-r--r--tmk_core/protocol/arm_atsam/d51_util.h224
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.c593
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.h113
-rw-r--r--tmk_core/protocol/arm_atsam/issi3733_driver.h201
-rw-r--r--tmk_core/protocol/arm_atsam/main_arm_atsam.c381
-rw-r--r--tmk_core/protocol/arm_atsam/main_arm_atsam.h23
-rw-r--r--tmk_core/protocol/arm_atsam/md_rgb_matrix.c556
-rw-r--r--tmk_core/protocol/arm_atsam/md_rgb_matrix.h200
-rw-r--r--tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c102
-rw-r--r--tmk_core/protocol/arm_atsam/shift_register.c122
-rw-r--r--tmk_core/protocol/arm_atsam/shift_register.h49
-rw-r--r--tmk_core/protocol/arm_atsam/spi_master.c109
-rw-r--r--tmk_core/protocol/arm_atsam/spi_master.h50
-rw-r--r--tmk_core/protocol/arm_atsam/startup.c563
-rw-r--r--tmk_core/protocol/arm_atsam/usb/compiler.h1079
-rw-r--r--tmk_core/protocol/arm_atsam/usb/conf_usb.h164
-rw-r--r--tmk_core/protocol/arm_atsam/usb/main_usb.c120
-rw-r--r--tmk_core/protocol/arm_atsam/usb/status_codes.h158
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udc.c1072
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udc.h256
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udc_desc.h132
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udd.h384
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udi.h133
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udi_cdc.c1267
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udi_cdc.h376
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udi_cdc_conf.h72
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udi_device_conf.h806
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udi_device_epsize.h31
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udi_hid.c148
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udi_hid.h85
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c861
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.h120
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udi_hid_kbd_conf.h60
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udi_hid_kbd_desc.c179
-rw-r--r--tmk_core/protocol/arm_atsam/usb/ui.c83
-rw-r--r--tmk_core/protocol/arm_atsam/usb/ui.h76
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb.c1083
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb.h462
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb_atmel.h189
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb_device_udd.c1046
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb_hub.c342
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb_hub.h51
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb_main.h101
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb_protocol.h488
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb_protocol_cdc.h190
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb_protocol_hid.h317
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb_util.c49
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb_util.h9
-rw-r--r--tmk_core/protocol/arm_atsam/wait_api.h7
-rw-r--r--tmk_core/protocol/usb_descriptor.h2
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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include "arm_atsam_protocol.h"
19
20uint16_t v_5v;
21uint16_t v_5v_avg;
22uint16_t v_con_1;
23uint16_t v_con_2;
24uint16_t v_con_1_boot;
25uint16_t v_con_2_boot;
26
27void 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
38void 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
103uint16_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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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
27extern uint16_t v_5v;
28extern uint16_t v_5v_avg;
29extern uint16_t v_con_1;
30extern uint16_t v_con_2;
31extern uint16_t v_con_1_boot;
32extern uint16_t v_con_2_boot;
33
34void ADC0_clock_init(void);
35void 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 @@
1ARM_ATSAM_DIR = protocol/arm_atsam
2
3SRC += $(ARM_ATSAM_DIR)/adc.c
4SRC += $(ARM_ATSAM_DIR)/clks.c
5SRC += $(ARM_ATSAM_DIR)/d51_util.c
6SRC += $(ARM_ATSAM_DIR)/i2c_master.c
7ifeq ($(RGB_MATRIX_DRIVER),custom)
8 SRC += $(ARM_ATSAM_DIR)/md_rgb_matrix_programs.c
9 SRC += $(ARM_ATSAM_DIR)/md_rgb_matrix.c
10endif
11SRC += $(ARM_ATSAM_DIR)/main_arm_atsam.c
12SRC += $(ARM_ATSAM_DIR)/shift_register.c
13SRC += $(ARM_ATSAM_DIR)/spi_master.c
14SRC += $(ARM_ATSAM_DIR)/startup.c
15
16SRC += $(ARM_ATSAM_DIR)/usb/main_usb.c
17SRC += $(ARM_ATSAM_DIR)/usb/udc.c
18SRC += $(ARM_ATSAM_DIR)/usb/udi_cdc.c
19SRC += $(ARM_ATSAM_DIR)/usb/udi_hid.c
20SRC += $(ARM_ATSAM_DIR)/usb/udi_hid_kbd.c
21SRC += $(ARM_ATSAM_DIR)/usb/udi_hid_kbd_desc.c
22SRC += $(ARM_ATSAM_DIR)/usb/ui.c
23SRC += $(ARM_ATSAM_DIR)/usb/usb.c
24SRC += $(ARM_ATSAM_DIR)/usb/usb_device_udd.c
25SRC += $(ARM_ATSAM_DIR)/usb/usb_hub.c
26SRC += $(ARM_ATSAM_DIR)/usb/usb_util.c
27
28SRC += $(DRIVER_PATH)/usb2422.c
29
30# Search Path
31VPATH += $(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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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
22volatile clk_t system_clks;
23volatile uint64_t ms_clk;
24uint32_t usec_delay_mult;
25#define USEC_DELAY_LOOP_CYCLES 3 // Sum of instruction cycles in us delay loop
26
27const uint32_t sercom_apbbase[] = {(uint32_t)SERCOM0, (uint32_t)SERCOM1, (uint32_t)SERCOM2, (uint32_t)SERCOM3, (uint32_t)SERCOM4, (uint32_t)SERCOM5};
28const 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
33void 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);
97uint32_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
128void 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
158void 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
191void TC4_Handler() {
192 if (TC4->COUNT16.INTFLAG.bit.MC0) {
193 TC4->COUNT16.INTFLAG.reg = TC_INTENCLR_MC0;
194 ms_clk++;
195 }
196}
197
198uint32_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
303void 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
317void CLK_delay_ms(uint64_t msec) {
318 msec += timer_read64();
319 while (msec > timer_read64()) {
320 }
321}
322
323void 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);
345uint32_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);
373uint32_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);
401uint32_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
427void 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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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
60typedef 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
73extern volatile clk_t system_clks;
74extern volatile uint64_t ms_clk;
75
76void CLK_oscctrl_init(void);
77void CLK_reset_time(void);
78uint32_t CLK_set_gclk_freq(uint8_t gclkn, uint32_t freq);
79uint32_t CLK_enable_timebase(void);
80uint64_t timer_read64(void);
81void CLK_delay_us(uint32_t usec);
82void CLK_delay_ms(uint64_t msec);
83
84uint32_t CLK_set_spi_freq(uint8_t sercomn, uint32_t freq);
85uint32_t CLK_set_i2c0_freq(uint8_t sercomn, uint32_t freq);
86uint32_t CLK_set_i2c1_freq(uint8_t sercomn, uint32_t freq);
87void 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
3static 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
8void 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
66void 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
138volatile 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)
176DEBUG_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
189void 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
218void 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
241void debug_code_init(void) {}
242void 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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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
75void dbg_print(uint32_t x);
76void dled_print(uint32_t x, uint8_t long_pause);
77
78void debug_code_init(void);
79void debug_code_disable(void);
80
81#ifdef DEBUG_BOOT_TRACING_ENABLE
82
83# define DBGC(n) debug_code = n
84
85extern volatile uint32_t debug_code;
86
87enum 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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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
31DmacDescriptor dmac_desc;
32DmacDescriptor dmac_desc_wb;
33
34static uint8_t i2c_led_q[I2C_Q_SIZE]; // I2C queue circular buffer
35static uint8_t i2c_led_q_s; // Start of circular buffer
36static uint8_t i2c_led_q_e; // End of circular buffer
37static uint8_t i2c_led_q_full; // Queue full counter for reset
38
39static uint8_t dma_sendbuf[I2C_DMA_MAX_SEND]; // Data being written to I2C
40
41volatile uint8_t i2c_led_q_running;
42
43#endif // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
44
45void 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
80uint8_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
92uint8_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
113void 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)
128void 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
167uint8_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
179uint8_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
200void 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
214void 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
219void 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
224void 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
233void 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
247void 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
252void 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
258void 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
272uint8_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
291uint8_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
326void 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
373void 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
382void 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
393void 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
402void 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
408void 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
416void 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
424void 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
432void 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
441void 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
450void 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
458uint8_t i2c_led_q_isempty(void) {
459 return i2c_led_q_s == i2c_led_q_e;
460}
461
462uint8_t i2c_led_q_size(void) {
463 return (i2c_led_q_e - i2c_led_q_s) % I2C_Q_SIZE;
464}
465
466uint8_t i2c_led_q_available(void) {
467 return I2C_Q_SIZE - i2c_led_q_size() - 1; // Never allow end to meet start
468}
469
470void 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
479void 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
486uint8_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
506uint8_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
584i2c_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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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
27extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc;
28extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb;
29
30uint8_t I2C3733_Init_Control(void);
31uint8_t I2C3733_Init_Drivers(void);
32void I2C3733_Control_Set(uint8_t state);
33void 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
46extern 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
87void i2c_led_q_init(void);
88void i2c_led_q_add(uint8_t cmd);
89void i2c_led_q_s_advance(void);
90uint8_t i2c_led_q_size(void);
91uint8_t i2c_led_q_request_room(uint8_t request_size);
92uint8_t i2c_led_q_run(void);
93
94void i2c1_init(void);
95uint8_t i2c1_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout);
96void i2c1_stop(void);
97
98#endif // MD_BOOTLOADER
99
100void i2c0_init(void);
101uint8_t i2c0_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout);
102void i2c0_stop(void);
103
104// Terrible interface compatiblity...
105#define I2C_STATUS_SUCCESS (0)
106#define I2C_STATUS_ERROR (-1)
107
108typedef int16_t i2c_status_t;
109
110void i2c_init(void);
111i2c_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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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
34uint8_t g_usb_state = USB_FSMSTATUS_FSMSTATE_OFF_Val; // Saved USB state from hardware value to detect changes
35
36void main_subtasks(void);
37uint8_t keyboard_leds(void);
38void send_keyboard(report_keyboard_t *report);
39void send_nkro(report_nkro_t *report);
40void send_mouse(report_mouse_t *report);
41void send_extra(report_extra_t *report);
42
43#ifdef DEFERRED_EXEC_ENABLE
44void deferred_exec_task(void);
45#endif // DEFERRED_EXEC_ENABLE
46
47host_driver_t arm_atsam_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};
48
49uint8_t led_states;
50
51uint8_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
60void 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
79void 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
106void 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
133void 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
152static char console_printbuf[CONSOLE_PRINTBUF_SIZE];
153static uint16_t console_printbuf_len = 0;
154
155int8_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
162void 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
201void 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
242void 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
257void 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
268void main_subtask_raw(void) {
269 udi_hid_raw_receive_report();
270}
271#endif
272
273void 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
285int 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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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
21uint8_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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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
33md_led_config_t md_led_config = {0};
34
35EECONFIG_DEBOUNCE_HELPER(md_led, EECONFIG_MD_LED, md_led_config);
36
37void 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
58void md_led_changed(void) {
59 eeconfig_flag_md_led(true);
60}
61
62// todo: use real task rather than this bodge
63void housekeeping_task_kb(void) {
64 eeconfig_flush_md_led_task(FLUSH_TIMEOUT);
65}
66
67__attribute__((weak)) led_instruction_t led_instructions[] = {{.end = 1}};
68static void md_rgb_matrix_config_override(int i);
69# else
70uint8_t gcr_desired;
71# endif // USE_MASSDROP_CONFIGURATOR
72
73void SERCOM1_0_Handler(void) {
74 if (SERCOM1->I2CM.INTFLAG.bit.ERROR) {
75 SERCOM1->I2CM.INTFLAG.reg = SERCOM_I2CM_INTENCLR_ERROR;
76 }
77}
78
79void 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
97issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT];
98
99issi3733_led_t led_map[ISSI3733_LED_COUNT] = ISSI3733_LED_MAP;
100RGB led_buffer[ISSI3733_LED_COUNT];
101
102uint8_t gcr_actual;
103uint8_t gcr_actual_last;
104# ifdef USE_MASSDROP_CONFIGURATOR
105uint8_t gcr_breathe;
106float breathe_mult;
107float 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
116static uint8_t gcr_min_counter;
117static uint8_t v_5v_cat_hit;
118
119// WARNING: Automatic GCR is in place to prevent USB shutdown and LED driver overloading
120void 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
210void 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
240void 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
248static 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
260static 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
266static 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
286static 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
351void 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
382const 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
391static 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
449static 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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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
44typedef 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
54typedef 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
60typedef 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
68typedef 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
79extern issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT];
80
81extern uint8_t gcr_breathe;
82extern uint8_t gcr_actual;
83extern uint8_t gcr_actual_last;
84
85void gcr_compute(void);
86
87void 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
99typedef 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
112extern const uint8_t led_setups_count;
113extern 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
123typedef 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
139extern led_instruction_t led_instructions[];
140
141typedef 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
160extern md_led_config_t md_led_config;
161
162void 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
199extern 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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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
25led_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
33led_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
39led_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
45led_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
51led_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
57led_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
63led_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
69led_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
77led_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
84led_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
89led_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
97void *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
99const 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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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
30void 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
36void 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
57void shift_init_impl(void) {
58 spi_init();
59}
60
61void 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
72void shift_out(const uint8_t *data, uint16_t length) {
73 shift_out_impl(data, length);
74}
75
76void shift_enable(void) {
77 gpio_set_pin_output(SR_EXP_OE_PIN);
78 gpio_write_pin_low(SR_EXP_OE_PIN);
79}
80
81void shift_disable(void) {
82 gpio_set_pin_output(SR_EXP_OE_PIN);
83 gpio_write_pin_high(SR_EXP_OE_PIN);
84}
85
86void shift_init(void) {
87 shift_disable();
88 shift_init_impl();
89}
90
91// ***************************************************************
92
93sr_exp_t sr_exp_data;
94
95void 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
103void 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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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 */
24typedef 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
46extern sr_exp_t sr_exp_data;
47
48void SR_EXP_WriteData(void);
49void 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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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
36static 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
57bool 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
80spi_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
95void 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
105spi_status_t spi_write(uint8_t data);
106
107spi_status_t spi_read(void);
108
109spi_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
23typedef 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
33extern "C" {
34#endif
35void spi_init(void);
36
37bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor);
38
39spi_status_t spi_write(uint8_t data);
40
41spi_status_t spi_read(void);
42
43spi_status_t spi_transmit(const uint8_t *data, uint16_t length);
44
45spi_status_t spi_receive(uint8_t *data, uint16_t length);
46
47void 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 */
33extern uint32_t _sfixed;
34extern uint32_t _efixed;
35extern uint32_t _etext;
36extern uint32_t _srelocate;
37extern uint32_t _erelocate;
38extern uint32_t _szero;
39extern uint32_t _ezero;
40extern uint32_t _sstack;
41extern uint32_t _estack;
42
43/** \cond DOXYGEN_SHOULD_SKIP_THIS */
44int main(void);
45/** \endcond */
46
47void __libc_init_array(void);
48
49/* Default empty handler */
50void Dummy_Handler(void);
51
52/* Cortex-M4 core handlers */
53void NMI_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
54void HardFault_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
55void MemManage_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
56void BusFault_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
57void UsageFault_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
58void SVC_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
59void DebugMon_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
60void PendSV_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
61void SysTick_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
62
63/* Peripherals handlers */
64void PM_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
65void MCLK_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
66void OSCCTRL_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* OSCCTRL_XOSCFAIL_0, OSCCTRL_XOSCRDY_0 */
67void OSCCTRL_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* OSCCTRL_XOSCFAIL_1, OSCCTRL_XOSCRDY_1 */
68void OSCCTRL_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* OSCCTRL_DFLLLOCKC, OSCCTRL_DFLLLOCKF, OSCCTRL_DFLLOOB, OSCCTRL_DFLLRCS, OSCCTRL_DFLLRDY */
69void OSCCTRL_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* OSCCTRL_DPLLLCKF_0, OSCCTRL_DPLLLCKR_0, OSCCTRL_DPLLLDRTO_0, OSCCTRL_DPLLLTO_0 */
70void OSCCTRL_4_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* OSCCTRL_DPLLLCKF_1, OSCCTRL_DPLLLCKR_1, OSCCTRL_DPLLLDRTO_1, OSCCTRL_DPLLLTO_1 */
71void OSC32KCTRL_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
72void SUPC_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SUPC_B12SRDY, SUPC_B33SRDY, SUPC_BOD12RDY, SUPC_BOD33RDY, SUPC_VCORERDY, SUPC_VREGRDY */
73void SUPC_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SUPC_BOD12DET, SUPC_BOD33DET */
74void WDT_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
75void RTC_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
76void EIC_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_0 */
77void EIC_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_1 */
78void EIC_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_2 */
79void EIC_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_3 */
80void EIC_4_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_4 */
81void EIC_5_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_5 */
82void EIC_6_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_6 */
83void EIC_7_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_7 */
84void EIC_8_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_8 */
85void EIC_9_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_9 */
86void EIC_10_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_10 */
87void EIC_11_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_11 */
88void EIC_12_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_12 */
89void EIC_13_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_13 */
90void EIC_14_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_14 */
91void EIC_15_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EIC_EXTINT_15 */
92void FREQM_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
93void 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 */
94void NVMCTRL_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* NVMCTRL_10, NVMCTRL_8, NVMCTRL_9 */
95void DMAC_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DMAC_SUSP_0, DMAC_TCMPL_0, DMAC_TERR_0 */
96void DMAC_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DMAC_SUSP_1, DMAC_TCMPL_1, DMAC_TERR_1 */
97void DMAC_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DMAC_SUSP_2, DMAC_TCMPL_2, DMAC_TERR_2 */
98void DMAC_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DMAC_SUSP_3, DMAC_TCMPL_3, DMAC_TERR_3 */
99void 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 */
101void EVSYS_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EVSYS_EVD_0, EVSYS_OVR_0 */
102void EVSYS_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EVSYS_EVD_1, EVSYS_OVR_1 */
103void EVSYS_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EVSYS_EVD_2, EVSYS_OVR_2 */
104void EVSYS_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* EVSYS_EVD_3, EVSYS_OVR_3 */
105void 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 */
106void PAC_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
107void TAL_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TAL_BRK */
108void TAL_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TAL_IPS_0, TAL_IPS_1 */
109void RAMECC_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
110void SERCOM0_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM0_0 */
111void SERCOM0_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM0_1 */
112void SERCOM0_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM0_2 */
113void SERCOM0_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM0_3, SERCOM0_4, SERCOM0_5, SERCOM0_6 */
114void SERCOM1_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM1_0 */
115void SERCOM1_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM1_1 */
116void SERCOM1_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM1_2 */
117void SERCOM1_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM1_3, SERCOM1_4, SERCOM1_5, SERCOM1_6 */
118void SERCOM2_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM2_0 */
119void SERCOM2_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM2_1 */
120void SERCOM2_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM2_2 */
121void SERCOM2_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM2_3, SERCOM2_4, SERCOM2_5, SERCOM2_6 */
122void SERCOM3_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM3_0 */
123void SERCOM3_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM3_1 */
124void SERCOM3_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM3_2 */
125void SERCOM3_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM3_3, SERCOM3_4, SERCOM3_5, SERCOM3_6 */
126#ifdef ID_SERCOM4
127void SERCOM4_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM4_0 */
128void SERCOM4_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM4_1 */
129void SERCOM4_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM4_2 */
130void SERCOM4_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM4_3, SERCOM4_4, SERCOM4_5, SERCOM4_6 */
131#endif
132#ifdef ID_SERCOM5
133void SERCOM5_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM5_0 */
134void SERCOM5_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM5_1 */
135void SERCOM5_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM5_2 */
136void SERCOM5_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM5_3, SERCOM5_4, SERCOM5_5, SERCOM5_6 */
137#endif
138#ifdef ID_SERCOM6
139void SERCOM6_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM6_0 */
140void SERCOM6_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM6_1 */
141void SERCOM6_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM6_2 */
142void SERCOM6_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM6_3, SERCOM6_4, SERCOM6_5, SERCOM6_6 */
143#endif
144#ifdef ID_SERCOM7
145void SERCOM7_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM7_0 */
146void SERCOM7_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM7_1 */
147void SERCOM7_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM7_2 */
148void SERCOM7_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* SERCOM7_3, SERCOM7_4, SERCOM7_5, SERCOM7_6 */
149#endif
150#ifdef ID_CAN0
151void CAN0_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
152#endif
153#ifdef ID_CAN1
154void CAN1_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
155#endif
156#ifdef ID_USB
157void 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 */
158void USB_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* USB_SOF_HSOF */
159void 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 */
160void 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
163void GMAC_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
164#endif
165void 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 */
166void TCC0_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_MC_0 */
167void TCC0_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_MC_1 */
168void TCC0_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_MC_2 */
169void TCC0_4_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_MC_3 */
170void TCC0_5_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_MC_4 */
171void TCC0_6_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC0_MC_5 */
172void 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 */
173void TCC1_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC1_MC_0 */
174void TCC1_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC1_MC_1 */
175void TCC1_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC1_MC_2 */
176void TCC1_4_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC1_MC_3 */
177void 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 */
178void TCC2_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC2_MC_0 */
179void TCC2_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC2_MC_1 */
180void TCC2_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC2_MC_2 */
181#ifdef ID_TCC3
182void 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 */
183void TCC3_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC3_MC_0 */
184void TCC3_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC3_MC_1 */
185#endif
186#ifdef ID_TCC4
187void 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 */
188void TCC4_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC4_MC_0 */
189void TCC4_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* TCC4_MC_1 */
190#endif
191void TC0_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
192void TC1_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
193void TC2_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
194void TC3_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
195#ifdef ID_TC4
196void TC4_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
197#endif
198#ifdef ID_TC5
199void TC5_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
200#endif
201#ifdef ID_TC6
202void TC6_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
203#endif
204#ifdef ID_TC7
205void TC7_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
206#endif
207void PDEC_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* PDEC_DIR_A, PDEC_ERR_A, PDEC_OVF, PDEC_VLC_A */
208void PDEC_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* PDEC_MC_0 */
209void PDEC_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* PDEC_MC_1 */
210void ADC0_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* ADC0_OVERRUN, ADC0_WINMON */
211void ADC0_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* ADC0_RESRDY */
212void ADC1_0_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* ADC1_OVERRUN, ADC1_WINMON */
213void ADC1_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* ADC1_RESRDY */
214void AC_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
215void 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 */
216void DAC_1_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DAC_EMPTY_0 */
217void DAC_2_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DAC_EMPTY_1 */
218void DAC_3_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DAC_RESRDY_0 */
219void DAC_4_Handler(void) __attribute__((weak, alias("Dummy_Handler"))); /* DAC_RESRDY_1 */
220#ifdef ID_I2S
221void I2S_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
222#endif
223void PCC_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
224void AES_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
225void TRNG_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
226#ifdef ID_ICM
227void ICM_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
228#endif
229#ifdef ID_PUKCC
230void PUKCC_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
231#endif
232void QSPI_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
233#ifdef ID_SDHC0
234void SDHC0_Handler(void) __attribute__((weak, alias("Dummy_Handler")));
235#endif
236#ifdef ID_SDHC1
237void 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
499extern 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 */
507void 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 */
560void 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)
209typedef unsigned char bool;
210# endif
211# endif
212typedef uint16_t le16_t;
213typedef uint16_t be16_t;
214typedef uint32_t le32_t;
215typedef uint32_t be32_t;
216typedef uint32_t iram_size_t;
217/** @} */
218
219/** \name Aliasing Aggregate Types
220 * @{ */
221
222/** 16-bit union. */
223typedef 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. */
231typedef 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. */
241typedef 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. */
253typedef 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. */
265typedef 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. */
277typedef 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. */
289typedef 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. */
301typedef 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. */
313typedef 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. */
325typedef 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. */
337typedef 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
879typedef int8_t S8; //!< 8-bit signed integer.
880typedef uint8_t U8; //!< 8-bit unsigned integer.
881typedef int16_t S16; //!< 16-bit signed integer.
882typedef uint16_t U16; //!< 16-bit unsigned integer.
883typedef int32_t S32; //!< 32-bit signed integer.
884typedef uint32_t U32; //!< 32-bit unsigned integer.
885typedef int64_t S64; //!< 64-bit signed integer.
886typedef uint64_t U64; //!< 64-bit unsigned integer.
887typedef float F32; //!< 32-bit floating-point number.
888typedef 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 */
993static 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 */
1009static 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 */
1015static 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 */
1021static 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 */
1034static 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 */
1039static 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 */
1062static 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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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
26uint8_t keyboard_protocol = 1;
27
28void main_suspend_action(void) {
29 ui_powerdown();
30}
31
32void main_resume_action(void) {
33 ui_wakeup();
34}
35
36void main_sof_action(void) {
37 ui_process(udd_get_frame_number());
38}
39
40void main_remotewakeup_enable(void) {
41 ui_wakeup_enable();
42}
43
44void main_remotewakeup_disable(void) {
45 ui_wakeup_disable();
46}
47
48volatile bool main_b_kbd_enable = false;
49bool main_kbd_enable(void) {
50 main_b_kbd_enable = true;
51 return true;
52}
53
54void main_kbd_disable(void) {
55 main_b_kbd_enable = false;
56}
57
58#ifdef NKRO_ENABLE
59volatile bool main_b_nkro_enable = false;
60bool main_nkro_enable(void) {
61 main_b_nkro_enable = true;
62 return true;
63}
64
65void main_nkro_disable(void) {
66 main_b_nkro_enable = false;
67}
68#endif
69
70#ifdef EXTRAKEY_ENABLE
71volatile bool main_b_exk_enable = false;
72bool main_exk_enable(void) {
73 main_b_exk_enable = true;
74 return true;
75}
76
77void main_exk_disable(void) {
78 main_b_exk_enable = false;
79}
80#endif
81
82#ifdef CONSOLE_ENABLE
83volatile bool main_b_con_enable = false;
84bool main_con_enable(void) {
85 main_b_con_enable = true;
86 return true;
87}
88
89void main_con_disable(void) {
90 main_b_con_enable = false;
91}
92#endif
93
94#ifdef MOUSE_ENABLE
95volatile bool main_b_mou_enable = false;
96bool main_mou_enable(void) {
97 main_b_mou_enable = true;
98 return true;
99}
100
101void main_mou_disable(void) {
102 main_b_mou_enable = false;
103}
104#endif
105
106#ifdef RAW_ENABLE
107volatile bool main_b_raw_enable = false;
108bool main_raw_enable(void) {
109 main_b_raw_enable = true;
110 return true;
111}
112
113void main_raw_disable(void) {
114 main_b_raw_enable = false;
115}
116
117void 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. */
70enum 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 */
87enum 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};
120typedef enum status_code status_code_genare_t;
121
122/**
123 Status codes used by MAC stack.
124 */
125enum 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
154typedef 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)
69static le16_t udc_device_status;
70
71COMPILER_WORD_ALIGNED
72//! Device interface setting value
73static uint8_t udc_iface_setting = 0;
74
75//! Device Configuration number selected by the USB host
76COMPILER_WORD_ALIGNED
77static uint8_t udc_num_configuration = 0;
78
79//! Pointer on the selected speed device configuration
80static udc_config_speed_t UDC_DESC_STORAGE *udc_ptr_conf;
81
82//! Pointer on interface descriptor used by SETUP request.
83static 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 */
93COMPILER_WORD_ALIGNED
94static 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
102static 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
114static 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
126extern uint32_t _srom;
127
128uint8_t usb_device_serial_name_size = 0;
129#if defined USB_DEVICE_SERIAL_USE_BOOTLOADER_SERIAL
130uint8_t bootloader_serial_number[BOOTLOADER_SERIAL_MAX_SIZE + 1] = "";
131#endif
132static 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
173struct 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};
177COMPILER_WORD_ALIGNED
178static UDC_DESC_STORAGE struct udc_string_desc_t udc_string_desc = {.header.bDescriptorType = USB_DT_STRING};
179//! @}
180
181usb_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 */
190static 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 */
205static 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 */
237static 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 */
275static 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 */
323static 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 */
350void udc_start(void) {
351 udd_enable();
352}
353
354/*! \brief Stop the USB Device stack
355 */
356void 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 */
365void 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
388void 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 */
405static 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 */
420static 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 */
439static 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 */
460static 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 */
477static 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)
537static 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 */
553static 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 */
562static 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 */
578static 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 */
631static 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 */
727static 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 */
741static 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 */
802static 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 */
839static 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 */
866static 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 */
959static 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 */
993static 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 */
1030bool 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
64extern "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 */
175static inline bool udc_include_vbus_monitoring(void) {
176 return udd_include_vbus_monitoring();
177}
178
179/*! \brief Start the USB Device stack
180 */
181void udc_start(void);
182
183/*! \brief Stop the USB Device stack
184 */
185void 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 */
194static 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 */
203static 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 */
210inline 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 */
219usb_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
55extern "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 */
98typedef 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 */
108typedef 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
125extern 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
54extern "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
69typedef uint8_t udd_ep_id_t;
70
71//! \brief Endpoint transfer status
72//! Returned in parameters of callback register via udd_ep_run routine.
73typedef 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 */
84typedef 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;
103extern 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 */
122typedef 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 */
133typedef 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 */
140bool udd_include_vbus_monitoring(void);
141
142/**
143 * \brief Enables the USB Device mode
144 */
145void udd_enable(void);
146
147/**
148 * \brief Disables the USB Device mode
149 */
150void 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 */
159void 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 */
166void 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 */
174bool udd_is_high_speed(void);
175
176/**
177 * \brief Changes the USB address of device
178 *
179 * \param address New USB address
180 */
181void udd_set_address(uint8_t address);
182
183/**
184 * \brief Returns the USB address of device
185 *
186 * \return USB address
187 */
188uint8_t udd_getaddress(void);
189
190/**
191 * \brief Returns the current start of frame number
192 *
193 * \return current start of frame number.
194 */
195uint16_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 */
202uint16_t udd_get_micro_frame_number(void);
203
204/*! \brief The USB driver sends a resume signal called Upstream Resume
205 */
206void 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 */
214void 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 */
236bool 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 */
243void 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 */
252bool 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 */
265bool 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 */
278bool 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 */
290bool 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 */
316bool 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 */
326void 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//@{
338void udd_test_mode_j(void);
339void udd_test_mode_k(void);
340void udd_test_mode_se0_nak(void);
341void 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 */
361extern bool udc_process_setup(void);
362
363/**
364 * \brief Reset the UDC
365 *
366 * The UDC must reset all configuration.
367 */
368extern 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 */
375extern 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
54extern "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 */
74typedef 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 */
92bool udi_cdc_comm_enable(void);
93void udi_cdc_comm_disable(void);
94bool udi_cdc_comm_setup(void);
95bool udi_cdc_data_enable(void);
96void udi_cdc_data_disable(void);
97bool udi_cdc_data_setup(void);
98uint8_t udi_cdc_getsetting(void);
99void udi_cdc_data_sof_notify(void);
100UDC_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};
101UDC_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 */
133static 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 */
140static 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 */
149static 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 */
157static 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 */
167static 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 */
185static 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 */
195static 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 */
205static 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 */
212static void udi_cdc_tx_send(uint8_t port);
213
214//@}
215
216//@}
217
218/**
219 * \name Information about configuration of communication line
220 */
221//@{
222COMPILER_WORD_ALIGNED
223static usb_cdc_line_coding_t udi_cdc_line_coding[UDI_CDC_PORT_NB];
224static bool udi_cdc_serial_state_msg_ongoing[UDI_CDC_PORT_NB];
225static volatile le16_t udi_cdc_state[UDI_CDC_PORT_NB];
226COMPILER_WORD_ALIGNED static usb_cdc_notify_serial_state_t uid_cdc_state_msg[UDI_CDC_PORT_NB];
227
228//! Status of CDC COMM interfaces
229static 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
239static volatile uint8_t udi_cdc_nb_data_enabled = 0;
240static volatile bool udi_cdc_data_running = false;
241//! Buffer to receive data
242COMPILER_WORD_ALIGNED static uint8_t udi_cdc_rx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_RX_BUFFERS];
243//! Data available in RX buffers
244static 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)
246static volatile uint8_t udi_cdc_rx_buf_sel[UDI_CDC_PORT_NB];
247//! Read position in current RX buffer
248static volatile uint16_t udi_cdc_rx_pos[UDI_CDC_PORT_NB];
249//! Signal a transfer on-going
250static 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
256COMPILER_WORD_ALIGNED static uint8_t udi_cdc_tx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_TX_BUFFERS];
257//! Data available in TX buffers
258static uint16_t udi_cdc_tx_buf_nb[UDI_CDC_PORT_NB][2];
259//! Give current TX buffer used (tx0 if 0, tx1 if 1)
260static volatile uint8_t udi_cdc_tx_buf_sel[UDI_CDC_PORT_NB];
261//! Value of SOF during last TX transfer
262static uint16_t udi_cdc_tx_sof_num[UDI_CDC_PORT_NB];
263//! Signal a transfer on-going
264static volatile bool udi_cdc_tx_trans_ongoing[UDI_CDC_PORT_NB];
265//! Signal that both buffer content data to send
266static volatile bool udi_cdc_tx_both_buf_to_send[UDI_CDC_PORT_NB];
267
268//@}
269
270bool 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
326bool 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
364void udi_cdc_comm_disable(void) {
365 Assert(udi_cdc_nb_comm_enabled != 0);
366 udi_cdc_nb_comm_enabled--;
367}
368
369void 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
379bool 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
423bool udi_cdc_data_setup(void) {
424 return false; // request Not supported
425}
426
427uint8_t udi_cdc_getsetting(void) {
428 return 0; // CDC don't have multiple alternate setting
429}
430
431void 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
449static 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
470static 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
477static 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
516static 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
530static 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
564static 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
616static 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
652static 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
687static 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
771void udi_cdc_ctrl_signal_dcd(bool b_set) {
772 udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DCD);
773}
774
775void udi_cdc_ctrl_signal_dsr(bool b_set) {
776 udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DSR);
777}
778
779void udi_cdc_signal_framing_error(void) {
780 udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_FRAMING);
781}
782
783void udi_cdc_signal_parity_error(void) {
784 udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_PARITY);
785}
786
787void udi_cdc_signal_overrun(void) {
788 udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_OVERRUN);
789}
790
791void 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
795void 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
799void udi_cdc_multi_signal_framing_error(uint8_t port) {
800 udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_FRAMING);
801}
802
803void udi_cdc_multi_signal_parity_error(uint8_t port) {
804 udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_PARITY);
805}
806
807void udi_cdc_multi_signal_overrun(uint8_t port) {
808 udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_OVERRUN);
809}
810
811iram_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
830iram_size_t udi_cdc_get_nb_received_data(void) {
831 return udi_cdc_multi_get_nb_received_data(0);
832}
833
834bool udi_cdc_multi_is_rx_ready(uint8_t port) {
835 return (udi_cdc_multi_get_nb_received_data(port) > 0);
836}
837
838bool udi_cdc_is_rx_ready(void) {
839 return udi_cdc_multi_is_rx_ready(0);
840}
841
842int 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
856udi_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
888int udi_cdc_getc(void) {
889 return udi_cdc_multi_getc(0);
890}
891
892iram_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
904udi_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
938static 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
983iram_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
987iram_size_t udi_cdc_read_buf(void *buf, iram_size_t size) {
988 return udi_cdc_multi_read_buf(0, buf, size);
989}
990
991iram_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
1021iram_size_t udi_cdc_get_free_tx_buffer(void) {
1022 return udi_cdc_multi_get_free_tx_buffer(0);
1023}
1024
1025bool udi_cdc_multi_is_tx_ready(uint8_t port) {
1026 return (udi_cdc_multi_get_free_tx_buffer(port) != 0);
1027}
1028
1029bool udi_cdc_is_tx_ready(void) {
1030 return udi_cdc_multi_is_tx_ready(0);
1031}
1032
1033int 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
1044udi_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
1071int udi_cdc_putc(int value) {
1072 return udi_cdc_multi_putc(0, value);
1073}
1074
1075iram_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
1090udi_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
1126iram_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
1132uint32_t cdc_tx_send_time_next;
1133
1134void 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
1141uint32_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
1163char printbuf[CDC_PRINTBUF_SIZE];
1164
1165int 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
1179inbuf_t inbuf;
1180
1181uint32_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
1226uint32_t CDC_input() {
1227 return CDC_input_buf(inbuf, CDC_INBUF_SIZE);
1228}
1229
1230void 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
1239char printbuf[CDC_PRINTBUF_SIZE];
1240
1241void CDC_send(void) {
1242 return;
1243}
1244
1245uint32_t CDC_print(char *printbuf) {
1246 return 0;
1247}
1248
1249int CDC_printf(const char *_Format, ...) {
1250 return 0;
1251}
1252
1253inbuf_t inbuf;
1254
1255uint32_t CDC_input(void) {
1256 return 0;
1257}
1258
1259void 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
68extern "C" {
69# endif
70
71/**
72 * \addtogroup udi_cdc_group_udc
73 * @{
74 */
75
76//! Global structure which contains standard UDI API for UDC
77extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm;
78extern 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 */
114void 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 */
121void udi_cdc_ctrl_signal_dsr(bool b_set);
122
123/**
124 * \brief Notify a framing error
125 */
126void udi_cdc_signal_framing_error(void);
127
128/**
129 * \brief Notify a parity error
130 */
131void udi_cdc_signal_parity_error(void);
132
133/**
134 * \brief Notify a overrun
135 */
136void udi_cdc_signal_overrun(void);
137
138/**
139 * \brief Gets the number of byte received
140 *
141 * \return the number of data available
142 */
143iram_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 */
150bool 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 */
157int 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 */
167iram_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 */
178iram_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 */
185iram_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 */
193bool 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 */
203int 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 */
213iram_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 */
227void 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 */
235void 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 */
242void 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 */
249void 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 */
256void 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 */
265iram_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 */
274bool 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 */
283int 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 */
294iram_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 */
303iram_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 */
313bool 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 */
324int 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 */
335iram_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
339extern char printbuf[CDC_PRINTBUF_SIZE];
340
341# define CDC_INBUF_SIZE 256
342
343typedef 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
353extern char printbuf[CDC_PRINTBUF_SIZE];
354
355# define CDC_INBUF_SIZE 1
356
357typedef struct {
358 uint32_t count;
359 uint32_t lastcount;
360 char buf[CDC_INBUF_SIZE];
361} inbuf_t;
362
363extern inbuf_t inbuf;
364
365#endif // VIRTSER_ENABLE
366
367uint32_t CDC_print(char* printbuf);
368int CDC_printf(const char* _Format, ...);
369uint32_t CDC_input(void);
370void 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
59extern "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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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// **********************************************************************
247COMPILER_PACK_SET(1)
248
249typedef 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
255typedef 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)
295extern uint8_t udi_hid_kbd_report_set;
296
297// report buffer (to host)
298#define UDI_HID_KBD_REPORT_SIZE 8
299extern uint8_t udi_hid_kbd_report[UDI_HID_KBD_REPORT_SIZE];
300
301COMPILER_PACK_RESET()
302
303// **********************************************************************
304// EXK Descriptor structure and content
305// **********************************************************************
306#ifdef EXTRAKEY_ENABLE
307
308COMPILER_PACK_SET(1)
309
310typedef 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
316typedef 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
357extern uint8_t udi_hid_exk_report[UDI_HID_EXK_REPORT_SIZE];
358
359COMPILER_PACK_RESET()
360
361#endif // EXTRAKEY_ENABLE
362
363// **********************************************************************
364// NKRO Descriptor structure and content
365// **********************************************************************
366#ifdef NKRO_ENABLE
367
368COMPILER_PACK_SET(1)
369
370typedef 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
376typedef 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
416extern uint8_t udi_hid_nkro_report_set;
417
418// report buffer
419# define UDI_HID_NKRO_REPORT_SIZE 32
420extern uint8_t udi_hid_nkro_report[UDI_HID_NKRO_REPORT_SIZE];
421
422COMPILER_PACK_RESET()
423
424#endif // NKRO_ENABLE
425
426// **********************************************************************
427// MOU Descriptor structure and content
428// **********************************************************************
429#ifdef MOUSE_ENABLE
430
431COMPILER_PACK_SET(1)
432
433typedef 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
439typedef 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
480extern uint8_t udi_hid_mou_report[UDI_HID_MOU_REPORT_SIZE];
481
482COMPILER_PACK_RESET()
483
484#endif // MOUSE_ENABLE
485
486// **********************************************************************
487// RAW Descriptor structure and content
488// **********************************************************************
489#ifdef RAW_ENABLE
490
491COMPILER_PACK_SET(1)
492
493typedef 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
500typedef 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
549extern uint8_t udi_hid_raw_report_set[UDI_HID_RAW_REPORT_SIZE];
550
551// report buffer
552extern uint8_t udi_hid_raw_report[UDI_HID_RAW_REPORT_SIZE];
553
554COMPILER_PACK_RESET()
555
556#endif // RAW_ENABLE
557
558// **********************************************************************
559// CON Descriptor structure and content
560// **********************************************************************
561#ifdef CONSOLE_ENABLE
562
563COMPILER_PACK_SET(1)
564
565typedef 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
572typedef 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
621extern uint8_t udi_hid_con_report_set[UDI_HID_CON_REPORT_SIZE];
622
623// report buffer
624extern uint8_t udi_hid_con_report[UDI_HID_CON_REPORT_SIZE];
625
626COMPILER_PACK_RESET()
627
628#endif // CONSOLE_ENABLE
629
630// **********************************************************************
631// CDC Descriptor structure and content
632// **********************************************************************
633#ifdef VIRTSER_ENABLE
634
635COMPILER_PACK_SET(1)
636
637typedef struct {
638 uint8_t bFunctionLength;
639 uint8_t bDescriptorType;
640 uint8_t bDescriptorSubtype;
641 le16_t bcdCDC;
642} usb_cdc_hdr_desc_t;
643
644typedef 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
652typedef struct {
653 uint8_t bFunctionLength;
654 uint8_t bDescriptorType;
655 uint8_t bDescriptorSubtype;
656 uint8_t bmCapabilities;
657} usb_cdc_acm_desc_t;
658
659typedef 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
667typedef 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
769COMPILER_PACK_RESET()
770
771#endif // VIRTSER_ENABLE
772
773// **********************************************************************
774// CONFIGURATION Descriptor structure and content
775// **********************************************************************
776COMPILER_PACK_SET(1)
777
778typedef 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
804COMPILER_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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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 */
64static bool udi_hid_reqstdifaceget_descriptor(uint8_t *report_desc);
65
66bool 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
119static 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
56extern "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 */
78bool 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//***************************************************************************
63bool udi_hid_kbd_enable(void);
64void udi_hid_kbd_disable(void);
65bool udi_hid_kbd_setup(void);
66uint8_t udi_hid_kbd_getsetting(void);
67
68UDC_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
76COMPILER_WORD_ALIGNED
77static uint8_t udi_hid_kbd_rate;
78
79COMPILER_WORD_ALIGNED
80static uint8_t udi_hid_kbd_protocol;
81
82COMPILER_WORD_ALIGNED
83uint8_t udi_hid_kbd_report_set;
84
85bool udi_hid_kbd_b_report_valid;
86
87COMPILER_WORD_ALIGNED
88uint8_t udi_hid_kbd_report[UDI_HID_KBD_REPORT_SIZE];
89
90volatile bool udi_hid_kbd_b_report_trans_ongoing;
91
92COMPILER_WORD_ALIGNED
93static uint8_t udi_hid_kbd_report_trans[UDI_HID_KBD_REPORT_SIZE];
94
95COMPILER_WORD_ALIGNED
96UDC_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
135static bool udi_hid_kbd_setreport(void);
136
137static void udi_hid_kbd_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
138
139static void udi_hid_kbd_setreport_valid(void);
140
141bool 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
151void udi_hid_kbd_disable(void) {
152 UDI_HID_KBD_DISABLE_EXT();
153}
154
155bool 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
159uint8_t udi_hid_kbd_getsetting(void) {
160 return 0;
161}
162
163static 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
174bool 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
190static 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
200static 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
209bool udi_hid_nkro_enable(void);
210void udi_hid_nkro_disable(void);
211bool udi_hid_nkro_setup(void);
212uint8_t udi_hid_nkro_getsetting(void);
213
214UDC_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
222COMPILER_WORD_ALIGNED
223static uint8_t udi_hid_nkro_rate;
224
225COMPILER_WORD_ALIGNED
226static uint8_t udi_hid_nkro_protocol;
227
228COMPILER_WORD_ALIGNED
229uint8_t udi_hid_nkro_report_set;
230
231bool udi_hid_nkro_b_report_valid;
232
233COMPILER_WORD_ALIGNED
234uint8_t udi_hid_nkro_report[UDI_HID_NKRO_REPORT_SIZE];
235
236volatile bool udi_hid_nkro_b_report_trans_ongoing;
237
238COMPILER_WORD_ALIGNED
239static uint8_t udi_hid_nkro_report_trans[UDI_HID_NKRO_REPORT_SIZE];
240
241COMPILER_WORD_ALIGNED
242UDC_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
280static bool udi_hid_nkro_setreport(void);
281static void udi_hid_nkro_setreport_valid(void);
282static void udi_hid_nkro_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
283
284bool 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
294void udi_hid_nkro_disable(void) {
295 UDI_HID_NKRO_DISABLE_EXT();
296}
297
298bool 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
302uint8_t udi_hid_nkro_getsetting(void) {
303 return 0;
304}
305
306// keyboard receives LED report here
307static 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
318bool 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
334static 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
344static 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
355bool udi_hid_exk_enable(void);
356void udi_hid_exk_disable(void);
357bool udi_hid_exk_setup(void);
358uint8_t udi_hid_exk_getsetting(void);
359
360UDC_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
368COMPILER_WORD_ALIGNED
369static uint8_t udi_hid_exk_rate;
370
371COMPILER_WORD_ALIGNED
372static uint8_t udi_hid_exk_protocol;
373
374// COMPILER_WORD_ALIGNED
375// uint8_t udi_hid_exk_report_set;
376
377bool udi_hid_exk_b_report_valid;
378
379COMPILER_WORD_ALIGNED
380uint8_t udi_hid_exk_report[UDI_HID_EXK_REPORT_SIZE];
381
382static bool udi_hid_exk_b_report_trans_ongoing;
383
384COMPILER_WORD_ALIGNED
385static uint8_t udi_hid_exk_report_trans[UDI_HID_EXK_REPORT_SIZE];
386
387COMPILER_WORD_ALIGNED
388UDC_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
418static void udi_hid_exk_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
419
420bool 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
430void udi_hid_exk_disable(void) { UDI_HID_EXK_DISABLE_EXT(); }
431
432bool 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
434uint8_t udi_hid_exk_getsetting(void) { return 0; }
435
436bool 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
452static 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
469bool udi_hid_mou_enable(void);
470void udi_hid_mou_disable(void);
471bool udi_hid_mou_setup(void);
472uint8_t udi_hid_mou_getsetting(void);
473
474UDC_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
482COMPILER_WORD_ALIGNED
483static uint8_t udi_hid_mou_rate;
484
485COMPILER_WORD_ALIGNED
486static uint8_t udi_hid_mou_protocol;
487
488// COMPILER_WORD_ALIGNED
489// uint8_t udi_hid_mou_report_set; //No set report
490
491bool udi_hid_mou_b_report_valid;
492
493COMPILER_WORD_ALIGNED
494uint8_t udi_hid_mou_report[UDI_HID_MOU_REPORT_SIZE];
495
496static bool udi_hid_mou_b_report_trans_ongoing;
497
498COMPILER_WORD_ALIGNED
499static uint8_t udi_hid_mou_report_trans[UDI_HID_MOU_REPORT_SIZE];
500
501COMPILER_WORD_ALIGNED
502UDC_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
552static void udi_hid_mou_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
553
554bool 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
564void udi_hid_mou_disable(void) { UDI_HID_MOU_DISABLE_EXT(); }
565
566bool 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
568uint8_t udi_hid_mou_getsetting(void) { return 0; }
569
570bool 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
586static 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
603bool udi_hid_raw_enable(void);
604void udi_hid_raw_disable(void);
605bool udi_hid_raw_setup(void);
606uint8_t udi_hid_raw_getsetting(void);
607
608UDC_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
616COMPILER_WORD_ALIGNED
617static uint8_t udi_hid_raw_rate;
618
619COMPILER_WORD_ALIGNED
620static uint8_t udi_hid_raw_protocol;
621
622COMPILER_WORD_ALIGNED
623uint8_t udi_hid_raw_report_set[UDI_HID_RAW_REPORT_SIZE];
624
625static bool udi_hid_raw_b_report_valid;
626
627COMPILER_WORD_ALIGNED
628uint8_t udi_hid_raw_report[UDI_HID_RAW_REPORT_SIZE];
629
630static bool udi_hid_raw_b_report_trans_ongoing;
631
632COMPILER_WORD_ALIGNED
633static uint8_t udi_hid_raw_report_trans[UDI_HID_RAW_REPORT_SIZE];
634
635COMPILER_WORD_ALIGNED
636static uint8_t udi_hid_raw_report_recv[UDI_HID_RAW_REPORT_SIZE];
637
638COMPILER_WORD_ALIGNED
639UDC_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
657static bool udi_hid_raw_setreport(void);
658static void udi_hid_raw_setreport_valid(void);
659
660static void udi_hid_raw_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
661static void udi_hid_raw_report_rcvd(udd_ep_status_t status, iram_size_t nb_rcvd, udd_ep_id_t ep);
662
663bool 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
673void udi_hid_raw_disable(void) { UDI_HID_RAW_DISABLE_EXT(); }
674
675bool 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
677uint8_t udi_hid_raw_getsetting(void) { return 0; }
678
679static 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
690bool 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
706static 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
716static void udi_hid_raw_setreport_valid(void) {}
717
718void 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
725bool 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
733static 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
748bool udi_hid_con_enable(void);
749void udi_hid_con_disable(void);
750bool udi_hid_con_setup(void);
751uint8_t udi_hid_con_getsetting(void);
752
753UDC_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
761COMPILER_WORD_ALIGNED
762static uint8_t udi_hid_con_rate;
763
764COMPILER_WORD_ALIGNED
765static uint8_t udi_hid_con_protocol;
766
767COMPILER_WORD_ALIGNED
768uint8_t udi_hid_con_report_set[UDI_HID_CON_REPORT_SIZE];
769
770bool udi_hid_con_b_report_valid;
771
772COMPILER_WORD_ALIGNED
773uint8_t udi_hid_con_report[UDI_HID_CON_REPORT_SIZE];
774
775volatile bool udi_hid_con_b_report_trans_ongoing;
776
777COMPILER_WORD_ALIGNED
778static uint8_t udi_hid_con_report_trans[UDI_HID_CON_REPORT_SIZE];
779
780COMPILER_WORD_ALIGNED
781UDC_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
802static bool udi_hid_con_setreport(void);
803static void udi_hid_con_setreport_valid(void);
804
805static void udi_hid_con_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
806
807bool 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
817void udi_hid_con_disable(void) { UDI_HID_CON_DISABLE_EXT(); }
818
819bool 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
821uint8_t udi_hid_con_getsetting(void) { return 0; }
822
823static 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
833bool 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
849static 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
859static 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
54extern "C" {
55#endif
56
57//******************************************************************************
58// Keyboard interface definitions
59//******************************************************************************
60extern UDC_DESC_STORAGE udi_api_t udi_api_hid_kbd;
61extern bool udi_hid_kbd_b_report_valid;
62extern volatile bool udi_hid_kbd_b_report_trans_ongoing;
63extern uint8_t udi_hid_kbd_report_set;
64bool udi_hid_kbd_send_report(void);
65
66//********************************************************************************************
67// NKRO Keyboard
68//********************************************************************************************
69#ifdef NKRO_ENABLE
70extern UDC_DESC_STORAGE udi_api_t udi_api_hid_nkro;
71extern bool udi_hid_nkro_b_report_valid;
72extern volatile bool udi_hid_nkro_b_report_trans_ongoing;
73bool udi_hid_nkro_send_report(void);
74#endif // NKRO_ENABLE
75
76//********************************************************************************************
77// SYS-CTRL interface
78//********************************************************************************************
79#ifdef EXTRAKEY_ENABLE
80extern UDC_DESC_STORAGE udi_api_t udi_api_hid_exk;
81extern bool udi_hid_exk_b_report_valid;
82bool udi_hid_exk_send_report(void);
83#endif // EXTRAKEY_ENABLE
84
85//********************************************************************************************
86// CON Console
87//********************************************************************************************
88#ifdef CONSOLE_ENABLE
89extern UDC_DESC_STORAGE udi_api_t udi_api_hid_con;
90extern bool udi_hid_con_b_report_valid;
91extern uint8_t udi_hid_con_report_set[UDI_HID_CON_REPORT_SIZE];
92extern volatile bool udi_hid_con_b_report_trans_ongoing;
93bool udi_hid_con_send_report(void);
94#endif // CONSOLE_ENABLE
95
96//********************************************************************************************
97// MOU Mouse
98//********************************************************************************************
99#ifdef MOUSE_ENABLE
100extern UDC_DESC_STORAGE udi_api_t udi_api_hid_mou;
101extern bool udi_hid_mou_b_report_valid;
102bool udi_hid_mou_send_report(void);
103#endif // MOUSE_ENABLE
104
105//********************************************************************************************
106// RAW Raw
107//********************************************************************************************
108#ifdef RAW_ENABLE
109extern UDC_DESC_STORAGE udi_api_t udi_api_hid_raw;
110bool udi_hid_raw_send_report(void);
111bool 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
67COMPILER_WORD_ALIGNED
68UDC_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
98COMPILER_WORD_ALIGNED
99UDC_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
113COMPILER_WORD_ALIGNED
114UDC_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
144UDC_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
167UDC_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
173UDC_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 */
64static void ui_wakeup_handler(void)
65{
66 /* It is a wakeup then send wakeup USB */
67 udc_remotewakeup();
68}
69#endif
70
71void ui_init(void) {}
72
73void ui_powerdown(void) {}
74
75void ui_wakeup_enable(void) {}
76
77void ui_wakeup_disable(void) {}
78
79void ui_wakeup(void) {}
80
81void ui_process(uint16_t framenumber) {}
82
83void 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
51void ui_init(void);
52
53//! \brief Enters the user interface in power down mode
54void ui_powerdown(void);
55
56//! \brief Enables the asynchronous interrupts of the user interface
57void ui_wakeup_enable(void);
58
59//! \brief Disables the asynchronous interrupts of the user interface
60void ui_wakeup_disable(void);
61
62//! \brief Exits the user interface of power down mode
63void 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 */
70void ui_process(uint16_t framenumber);
71
72/*! \brief Turn on or off the keyboard LEDs
73 */
74void 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 */
98COMPILER_PACK_SET(1)
99COMPILER_WORD_ALIGNED
100union {
101 UsbDeviceDescriptor usb_endpoint_table[USB_EPT_NUM];
102} usb_descriptor_table;
103COMPILER_PACK_RESET()
104/** @} */
105
106/**
107 * \brief Local USB module instance
108 */
109static struct usb_module *_usb_instances;
110
111/* Device LPM callback variable */
112static 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 */
117static struct usb_endpoint_callback_parameter ep_callback_para;
118
119/**
120 * \internal USB Device IRQ Mask Bits Map
121 */
122static 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 */
129static 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 */
147enum 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 */
173enum 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 */
198enum 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 */
225enum 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 */
255enum 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 */
283enum 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 */
310enum 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 */
368enum 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 */
430void 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 */
455enum 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 */
564bool 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 */
582void 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 */
606bool 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 */
622void 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 */
639void 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 */
677enum 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 */
710enum 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 */
741enum 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
755static 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 */
870void 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 */
884void 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 */
898void 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
906void USB_1_Handler(void) {
907 _usb_device_interrupt_handler();
908}
909
910void USB_2_Handler(void) {
911 _usb_device_interrupt_handler();
912}
913
914void 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 */
923void 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
959enum 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
50extern "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 */
112enum 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 */
118enum 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 */
131enum 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 */
142enum 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 */
154enum 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 */
163enum 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 */
177enum 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 */
188enum 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 */
199enum 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 */
213enum 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 */
222struct usb_module;
223
224/**
225 * \name Host Callback Functions Types
226 * @{
227 */
228typedef void (*usb_host_callback_t)(struct usb_module *module_inst);
229typedef void (*usb_host_pipe_callback_t)(struct usb_module *module_inst, void *);
230/** @} */
231
232/**
233 * \name Device Callback Functions Types
234 * @{
235 */
236typedef void (*usb_device_callback_t)(struct usb_module *module_inst, void *pointer);
237typedef void (*usb_device_endpoint_callback_t)(struct usb_module *module_inst, void *pointer);
238/** @} */
239
240/** USB configurations */
241struct 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 */
261struct 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 */
279struct 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 */
291struct 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
298void usb_enable(struct usb_module *module_inst);
299void 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 */
306static 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
314void usb_get_config_defaults(struct usb_config *module_config);
315enum 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 */
322static 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 */
331static 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 */
341static 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 */
355static 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 */
365static 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 */
375static 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 */
385static 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 */
394static 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 */
404static 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 */
412enum status_code usb_device_register_callback(struct usb_module *module_inst, enum usb_device_callback callback_type, usb_device_callback_t callback_func);
413enum status_code usb_device_unregister_callback(struct usb_module *module_inst, enum usb_device_callback callback_type);
414enum status_code usb_device_enable_callback(struct usb_module *module_inst, enum usb_device_callback callback_type);
415enum 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 */
422void usb_device_endpoint_get_config_defaults(struct usb_device_endpoint_config *ep_config);
423enum status_code usb_device_endpoint_set_config(struct usb_module *module_inst, struct usb_device_endpoint_config *ep_config);
424bool 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 */
431enum 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);
432enum status_code usb_device_endpoint_unregister_callback(struct usb_module *module_inst, uint8_t ep_num, enum usb_device_endpoint_callback callback_type);
433enum status_code usb_device_endpoint_enable_callback(struct usb_module *module_inst, uint8_t ep, enum usb_device_endpoint_callback callback_type);
434enum 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 */
441enum status_code usb_device_endpoint_write_buffer_job(struct usb_module *module_inst, uint8_t ep_num, uint8_t *pbuf, uint32_t buf_size);
442enum status_code usb_device_endpoint_read_buffer_job(struct usb_module *module_inst, uint8_t ep_num, uint8_t *pbuf, uint32_t buf_size);
443enum status_code usb_device_endpoint_setup_buffer_job(struct usb_module *module_inst, uint8_t *pbuf);
444void 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
452bool usb_device_endpoint_is_halted(struct usb_module *module_inst, uint8_t ep);
453void usb_device_endpoint_set_halt(struct usb_module *module_inst, uint8_t ep);
454void 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 */
90struct usb_module usb_device;
91
92/**
93 * \name Clock management
94 *
95 * @{
96 */
97
98#define UDD_CLOCK_GEN 0
99
100static 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 */
125UDC_BSS(4)
126uint8_t udd_ctrl_buffer[USB_DEVICE_EP_CTRL_SIZE];
127
128/** Bit definitions about endpoint control state machine for udd_ep_control_state */
129typedef 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 */
139udd_ctrl_request_t udd_g_ctrlreq;
140
141/** State of the endpoint control management */
142static 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 */
145static uint16_t udd_ctrl_prev_payload_nb_trans;
146
147/** Number of data received/sent to/from udd_g_ctrlreq.payload buffer */
148static 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)
176UDC_BSS(4) uint8_t udd_ep_out_cache_buffer[USB_DEVICE_MAX_EP][8];
177#elif (defined USB_DEVICE_HS_SUPPORT)
178UDC_BSS(4) uint8_t udd_ep_out_cache_buffer[USB_DEVICE_MAX_EP][512];
179#else
180UDC_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 */
184typedef 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 */
208static 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 */
217static 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 */
229static 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 */
278static 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 */
338static 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
349void 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
366bool udd_is_high_speed(void) {
367 return false;
368}
369
370uint16_t udd_get_frame_number(void) {
371 return usb_device_get_frame_number(&usb_device);
372}
373
374uint16_t udd_get_micro_frame_number(void) {
375 return usb_device_get_micro_frame_number(&usb_device);
376}
377
378void 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
392bool 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
445bool udd_ep_is_halted(udd_ep_id_t ep) {
446 return usb_device_endpoint_is_halted(&usb_device, ep);
447}
448
449bool 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
462bool 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
482bool 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 */
513static 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
520bool 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
602void udd_set_address(uint8_t address) {
603 usb_device_set_address(&usb_device, address);
604}
605
606uint8_t udd_getaddress(void) {
607 return usb_device_get_address(&usb_device);
608}
609
610void 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
619void 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 */
627static 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 */
638static 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 */
647static 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 */
692static 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 */
762static 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 */
804static 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 */
822static 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 */
842static 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 */
858static 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 */
875static 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 */
906static 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
916static 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 */
944static 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 */
957static 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 */
970static 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
985void udd_detach(void) {
986 usb_device_detach(&usb_device);
987 udd_sleep_mode(UDD_STATE_SUSPEND);
988}
989
990void 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
1009void 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
1041void 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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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
22uint8_t usb_host_port;
23
24#ifndef MD_BOOTLOADER
25
26uint8_t usb_extra_state;
27uint8_t usb_extra_manual;
28uint8_t usb_gcr_auto;
29
30#endif // MD_BOOTLOADER
31
32uint16_t adc_extra;
33
34void 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
130void 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
143void 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
153uint16_t USB_active(void) {
154 return USB2422_active();
155}
156
157void 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
233uint8_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
279void 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
309void 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/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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
36extern uint8_t usb_host_port;
37extern uint8_t usb_extra_state;
38extern uint8_t usb_extra_manual;
39extern uint8_t usb_gcr_auto;
40
41void USB_Hub_init(void);
42uint8_t USB_Hub_Port_Detect_Init(void);
43void USB_reset(void);
44void USB_configure(void);
45uint16_t USB_active(void);
46void USB_set_host_by_voltage(void);
47uint16_t adc_get(uint8_t muxpos);
48void USB_HandleExtraDevice(void);
49void 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
52void main_suspend_action(void);
53
54// Called by UDD when the USB line exit of suspend state
55void main_resume_action(void);
56
57// Called when a start of frame is received on USB line
58void main_sof_action(void);
59
60// Called by UDC when USB Host request to enable remote wakeup
61void main_remotewakeup_enable(void);
62
63// Called by UDC when USB Host request to disable remote wakeup
64void main_remotewakeup_disable(void);
65
66extern volatile bool main_b_kbd_enable;
67bool main_kbd_enable(void);
68void main_kbd_disable(void);
69
70#ifdef NKRO_ENABLE
71extern volatile bool main_b_nkro_enable;
72bool main_nkro_enable(void);
73void main_nkro_disable(void);
74#endif // NKRO_ENABLE
75
76#ifdef EXTRAKEY_ENABLE
77extern volatile bool main_b_exk_enable;
78bool main_exk_enable(void);
79void main_exk_disable(void);
80#endif // EXTRAKEY_ENABLE
81
82#ifdef CONSOLE_ENABLE
83extern volatile bool main_b_con_enable;
84bool main_con_enable(void);
85void main_con_disable(void);
86#endif // CONSOLE_ENABLE
87
88#ifdef MOUSE_ENABLE
89extern volatile bool main_b_mou_enable;
90bool main_mou_enable(void);
91void main_mou_disable(void);
92#endif // MOUSE_ENABLE
93
94#ifdef RAW_ENABLE
95extern volatile bool main_b_raw_enable;
96bool main_raw_enable(void);
97void main_raw_disable(void);
98void 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 */
112enum 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 */
130enum 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 */
136enum usb_interface_status { USB_IFACE_STATUS_RESERVED = 0 };
137
138/**
139 * \brief Standard USB endpoint status flags
140 *
141 */
142enum 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 */
151enum 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 */
164enum 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 */
175enum usb_endpoint_feature {
176 USB_EP_FEATURE_HALT = 0,
177};
178
179/**
180 * \brief Standard USB Test Mode Selectors
181 */
182enum 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 */
193enum 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 */
211enum 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 */
219enum 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 */
252enum 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 */
263enum 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
273typedef 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
286typedef 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 */
299COMPILER_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 */
306typedef 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 */
317typedef 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 */
342typedef 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 */
366typedef 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 */
378typedef 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 */
390typedef 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 */
398typedef 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 */
412typedef 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 */
433typedef 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 */
447typedef 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 */
462typedef 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 */
474typedef struct {
475 uint8_t bLength;
476 uint8_t bDescriptorType;
477} usb_str_desc_t;
478
479typedef struct {
480 usb_str_desc_t desc;
481 le16_t string[1];
482} usb_str_lgid_desc_t;
483
484COMPILER_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)
138typedef 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
146enum 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
152enum 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
160typedef 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
167typedef 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
175typedef 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)
83enum 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
93enum 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
100enum 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
108enum 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
115enum usb_hid_protocol {
116 USB_HID_PROCOTOL_BOOT = 0,
117 USB_HID_PROCOTOL_REPORT = 1,
118};
119
120COMPILER_PACK_SET(1)
121
122//! \brief HID Descriptor
123typedef 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
133COMPILER_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
5char digit(int d, int radix) {
6 if (d < 10) {
7 return d + '0';
8 } else {
9 return d - 10 + 'A';
10 }
11}
12
13int 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
39int UTIL_ltoa(int64_t value, char *dest) {
40 return UTIL_ltoa_radix(value, dest, 10);
41}
42
43int UTIL_itoa(int value, char *dest) {
44 return UTIL_ltoa_radix((int64_t)value, dest, 10);
45}
46
47int 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
4int UTIL_ltoa_radix(int64_t value, char *dest, int radix);
5int UTIL_ltoa(int64_t value, char *dest);
6int UTIL_itoa(int value, char *dest);
7int 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
4void wait_ms(uint64_t msec);
5void 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