aboutsummaryrefslogtreecommitdiff
path: root/tmk_core
diff options
context:
space:
mode:
authorJoel Challis <git@zvecr.com>2021-10-22 00:49:58 +0100
committerGitHub <noreply@github.com>2021-10-22 00:49:58 +0100
commit0093d3d761e60a31bb2a15a5859dbd0c08ef9999 (patch)
tree144db2e99236bd0fc2654cbeaecc57bbb5409b39 /tmk_core
parent1b1f3ec68ee1e7abe436a46bcfedf30f21330aef (diff)
downloadqmk_firmware-0093d3d761e60a31bb2a15a5859dbd0c08ef9999.tar.gz
qmk_firmware-0093d3d761e60a31bb2a15a5859dbd0c08ef9999.zip
Initial USB2422 driver (#14835)
Diffstat (limited to 'tmk_core')
-rw-r--r--tmk_core/protocol/arm_atsam.mk4
-rw-r--r--tmk_core/protocol/arm_atsam/arm_atsam_protocol.h2
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.c19
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.h9
-rw-r--r--tmk_core/protocol/arm_atsam/main_arm_atsam.c4
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb2422.h402
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb_hub.c (renamed from tmk_core/protocol/arm_atsam/usb/usb2422.c)98
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb_hub.h51
8 files changed, 91 insertions, 498 deletions
diff --git a/tmk_core/protocol/arm_atsam.mk b/tmk_core/protocol/arm_atsam.mk
index e3b550596..ffd1fa9f5 100644
--- a/tmk_core/protocol/arm_atsam.mk
+++ b/tmk_core/protocol/arm_atsam.mk
@@ -20,10 +20,12 @@ SRC += $(ARM_ATSAM_DIR)/usb/udi_hid.c
20SRC += $(ARM_ATSAM_DIR)/usb/udi_hid_kbd.c 20SRC += $(ARM_ATSAM_DIR)/usb/udi_hid_kbd.c
21SRC += $(ARM_ATSAM_DIR)/usb/udi_hid_kbd_desc.c 21SRC += $(ARM_ATSAM_DIR)/usb/udi_hid_kbd_desc.c
22SRC += $(ARM_ATSAM_DIR)/usb/ui.c 22SRC += $(ARM_ATSAM_DIR)/usb/ui.c
23SRC += $(ARM_ATSAM_DIR)/usb/usb2422.c
24SRC += $(ARM_ATSAM_DIR)/usb/usb.c 23SRC += $(ARM_ATSAM_DIR)/usb/usb.c
25SRC += $(ARM_ATSAM_DIR)/usb/usb_device_udd.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 26SRC += $(ARM_ATSAM_DIR)/usb/usb_util.c
27 27
28SRC += $(DRIVER_PATH)/usb2422.c
29
28# Search Path 30# Search Path
29VPATH += $(TMK_DIR)/$(ARM_ATSAM_DIR) 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
index c3eab39fb..e1749f872 100644
--- a/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h
+++ b/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h
@@ -29,7 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
29#include "i2c_master.h" 29#include "i2c_master.h"
30#include "shift_register.h" 30#include "shift_register.h"
31 31
32#include "./usb/usb2422.h" 32#include "./usb/usb_hub.h"
33 33
34#ifndef MD_BOOTLOADER 34#ifndef MD_BOOTLOADER
35 35
diff --git a/tmk_core/protocol/arm_atsam/i2c_master.c b/tmk_core/protocol/arm_atsam/i2c_master.c
index dda2f85b0..af046625f 100644
--- a/tmk_core/protocol/arm_atsam/i2c_master.c
+++ b/tmk_core/protocol/arm_atsam/i2c_master.c
@@ -564,4 +564,23 @@ uint8_t i2c_led_q_run(void) {
564 564
565 return 1; 565 return 1;
566} 566}
567
568__attribute__((weak)) void i2c_init(void) {
569 static bool is_initialised = false;
570 if (!is_initialised) {
571 is_initialised = true;
572
573 i2c0_init();
574 }
575}
576
577i2c_status_t i2c_transmit(uint8_t address, const uint8_t *data, uint16_t length, uint16_t timeout) {
578 uint8_t ret = i2c0_transmit(address, (uint8_t *)data, length, timeout);
579 SERCOM0->I2CM.CTRLB.bit.CMD = 0x03;
580 while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) {
581 DBGC(DC_USB_WRITE2422_BLOCK_SYNC_SYSOP);
582 }
583 return ret ? I2C_STATUS_SUCCESS : I2C_STATUS_ERROR;
584}
585
567#endif // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE) 586#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
index 68773f213..e11235d44 100644
--- a/tmk_core/protocol/arm_atsam/i2c_master.h
+++ b/tmk_core/protocol/arm_atsam/i2c_master.h
@@ -101,4 +101,13 @@ void i2c0_init(void);
101uint8_t i2c0_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout); 101uint8_t i2c0_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout);
102void i2c0_stop(void); 102void i2c0_stop(void);
103 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
104#endif // _I2C_MASTER_H_ 113#endif // _I2C_MASTER_H_
diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
index 858b4cd9f..1df5112ed 100644
--- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c
+++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
@@ -296,7 +296,7 @@ int main(void) {
296 296
297 matrix_init(); 297 matrix_init();
298 298
299 USB2422_init(); 299 USB_Hub_init();
300 300
301 DBGC(DC_MAIN_UDC_START_BEGIN); 301 DBGC(DC_MAIN_UDC_START_BEGIN);
302 udc_start(); 302 udc_start();
@@ -306,7 +306,7 @@ int main(void) {
306 CDC_init(); 306 CDC_init();
307 DBGC(DC_MAIN_CDC_INIT_COMPLETE); 307 DBGC(DC_MAIN_CDC_INIT_COMPLETE);
308 308
309 while (USB2422_Port_Detect_Init() == 0) { 309 while (USB_Hub_Port_Detect_Init() == 0) {
310 } 310 }
311 311
312 DBG_LED_OFF; 312 DBG_LED_OFF;
diff --git a/tmk_core/protocol/arm_atsam/usb/usb2422.h b/tmk_core/protocol/arm_atsam/usb/usb2422.h
deleted file mode 100644
index b4830b5bc..000000000
--- a/tmk_core/protocol/arm_atsam/usb/usb2422.h
+++ /dev/null
@@ -1,402 +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 USB2422_ADDR 0x58 // I2C device address, one instance
24
25#define USB2422_HUB_ACTIVE_GROUP 0 // PA
26#define USB2422_HUB_ACTIVE_PIN 18 // 18
27
28/* -------- USB2422_VID : (USB2422L Offset: 0x00) (R/W 16) Vendor ID -------- */
29#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
30typedef union {
31 struct {
32 uint16_t VID_LSB : 8;
33 uint16_t VID_MSB : 8;
34 } bit; /*!< Structure used for bit access */
35 uint16_t reg; /*!< Type used for register access */
36} USB2422_VID_Type;
37#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
38
39/* -------- USB2422_PID : (USB2422L Offset: 0x02) (R/W 16) Product ID -------- */
40#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
41typedef union {
42 struct {
43 uint16_t PID_LSB : 8;
44 uint16_t PID_MSB : 8;
45 } bit; /*!< Structure used for bit access */
46 uint16_t reg; /*!< Type used for register access */
47} USB2422_PID_Type;
48#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
49
50/* -------- USB2422_DID : (USB2422L Offset: 0x04) (R/W 16) Device ID -------- */
51#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
52typedef union {
53 struct {
54 uint16_t DID_LSB : 8;
55 uint16_t DID_MSB : 8;
56 } bit; /*!< Structure used for bit access */
57 uint16_t reg; /*!< Type used for register access */
58} USB2422_DID_Type;
59#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
60
61/* -------- USB2422_CFG1 : (USB2422L Offset: 0x06) (R/W 8) Configuration Data Byte 1-------- */
62#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
63typedef union {
64 struct {
65 uint8_t PORT_PWR : 1;
66 uint8_t CURRENT_SNS : 2;
67 uint8_t EOP_DISABLE : 1;
68 uint8_t MTT_ENABLE : 1;
69 uint8_t HS_DISABLE : 1;
70 uint8_t : 1;
71 uint8_t SELF_BUS_PWR : 1;
72 } bit; /*!< Structure used for bit access */
73 uint8_t reg; /*!< Type used for register access */
74} USB2422_CFG1_Type;
75#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
76
77/* -------- USB2422_CFG2 : (USB2422L Offset: 0x07) (R/W 8) Configuration Data Byte 2-------- */
78#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
79typedef union {
80 struct {
81 uint8_t : 3;
82 uint8_t COMPOUND : 1;
83 uint8_t OC_TIMER : 2;
84 uint8_t : 1;
85 uint8_t DYNAMIC : 1;
86 } bit; /*!< Structure used for bit access */
87 uint8_t reg; /*!< Type used for register access */
88} USB2422_CFG2_Type;
89#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
90
91/* -------- USB2422_CFG3 : (USB2422L Offset: 0x08) (R/W 16) Configuration Data Byte 3-------- */
92#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
93typedef union {
94 struct {
95 uint8_t STRING_EN : 1;
96 uint8_t : 2;
97 uint8_t PRTMAP_EN : 1;
98 uint8_t : 4;
99 } bit; /*!< Structure used for bit access */
100 uint8_t reg; /*!< Type used for register access */
101} USB2422_CFG3_Type;
102#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
103
104/* -------- USB2422_NRD : (USB2422L Offset: 0x09) (R/W 8) Non Removable Device -------- */
105#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
106typedef union {
107 struct {
108 uint8_t : 5;
109 uint8_t PORT2_NR : 1;
110 uint8_t PORT1_NR : 1;
111 uint8_t : 1;
112 } bit; /*!< Structure used for bit access */
113 uint8_t reg; /*!< Type used for register access */
114} USB2422_NRD_Type;
115#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
116
117/* -------- USB2422_PDS : (USB2422L Offset: 0x0A) (R/W 8) Port Diable for Self-Powered Operation -------- */
118#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
119typedef union {
120 struct {
121 uint8_t : 1;
122 uint8_t PORT1_DIS : 1;
123 uint8_t PORT2_DIS : 1;
124 uint8_t : 5;
125 } bit; /*!< Structure used for bit access */
126 uint8_t reg; /*!< Type used for register access */
127} USB2422_PDS_Type;
128#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
129
130/* -------- USB2422_PDB : (USB2422L Offset: 0x0B) (R/W 8) Port Diable for Bus-Powered Operation -------- */
131#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
132typedef union {
133 struct {
134 uint8_t : 1;
135 uint8_t PORT1_DIS : 1;
136 uint8_t PORT2_DIS : 1;
137 uint8_t : 5;
138 } bit; /*!< Structure used for bit access */
139 uint8_t reg; /*!< Type used for register access */
140} USB2422_PDB_Type;
141#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
142
143/* -------- USB2422_MAXPS : (USB2422L Offset: 0x0C) (R/W 8) Max Power for Self-Powered Operation -------- */
144#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
145typedef union {
146 struct {
147 uint8_t MAX_PWR_SP : 8;
148 } bit; /*!< Structure used for bit access */
149 uint8_t reg; /*!< Type used for register access */
150} USB2422_MAXPS_Type;
151#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
152
153/* -------- USB2422_MAXPB : (USB2422L Offset: 0x0D) (R/W 8) Max Power for Bus-Powered Operation -------- */
154#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
155typedef union {
156 struct {
157 uint8_t MAX_PWR_BP : 8;
158 } bit; /*!< Structure used for bit access */
159 uint8_t reg; /*!< Type used for register access */
160} USB2422_MAXPB_Type;
161#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
162
163/* -------- USB2422_HCMCS : (USB2422L Offset: 0x0E) (R/W 8) Hub Controller Max Current for Self-Powered Operation -------- */
164#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
165typedef union {
166 struct {
167 uint8_t HC_MAX_C_SP : 8;
168 } bit; /*!< Structure used for bit access */
169 uint8_t reg; /*!< Type used for register access */
170} USB2422_HCMCS_Type;
171#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
172
173/* -------- USB2422_HCMCB : (USB2422L Offset: 0x0F) (R/W 8) Hub Controller Max Current for Bus-Powered Operation -------- */
174#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
175typedef union {
176 struct {
177 uint8_t HC_MAX_C_BP : 8;
178 } bit; /*!< Structure used for bit access */
179 uint8_t reg; /*!< Type used for register access */
180} USB2422_HCMCB_Type;
181#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
182
183/* -------- USB2422_PWRT : (USB2422L Offset: 0x10) (R/W 8) Power On Time -------- */
184#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
185typedef union {
186 struct {
187 uint8_t POWER_ON_TIME : 8;
188 } bit; /*!< Structure used for bit access */
189 uint8_t reg; /*!< Type used for register access */
190} USB2422_PWRT_Type;
191#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
192
193/* -------- USB2422_LANGID LSB : (USB2422L Offset: 0x11) (R/W 16) Language ID -------- */
194#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
195typedef union {
196 struct {
197 uint8_t LANGID_LSB : 8;
198 } bit; /*!< Structure used for bit access */
199 uint8_t reg; /*!< Type used for register access */
200} USB2422_LANGID_LSB_Type;
201#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
202
203/* -------- USB2422_LANGID MSB : (USB2422L Offset: 0x12) (R/W 16) Language ID -------- */
204#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
205typedef union {
206 struct {
207 uint8_t LANGID_MSB : 8;
208 } bit; /*!< Structure used for bit access */
209 uint8_t reg; /*!< Type used for register access */
210} USB2422_LANGID_MSB_Type;
211#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
212
213/* -------- USB2422_MFRSL : (USB2422L Offset: 0x13) (R/W 8) Manufacturer String Length -------- */
214#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
215typedef union {
216 struct {
217 uint8_t MFR_STR_LEN : 8;
218 } bit; /*!< Structure used for bit access */
219 uint8_t reg; /*!< Type used for register access */
220} USB2422_MFRSL_Type;
221#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
222
223/* -------- USB2422_PRDSL : (USB2422L Offset: 0x14) (R/W 8) Product String Length -------- */
224#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
225typedef union {
226 struct {
227 uint8_t PRD_STR_LEN : 8;
228 } bit; /*!< Structure used for bit access */
229 uint8_t reg; /*!< Type used for register access */
230} USB2422_PRDSL_Type;
231#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
232
233/* -------- USB2422_SERSL : (USB2422L Offset: 0x15) (R/W 8) Serial String Length -------- */
234#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
235typedef union {
236 struct {
237 uint8_t SER_STR_LEN : 8;
238 } bit; /*!< Structure used for bit access */
239 uint8_t reg; /*!< Type used for register access */
240} USB2422_SERSL_Type;
241#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
242
243/* -------- USB2422_MFRSTR : (USB2422L Offset: 0x16-53) (R/W 8) Maufacturer String -------- */
244#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
245typedef uint16_t USB2422_MFRSTR_Type;
246#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
247
248/* -------- USB2422_PRDSTR : (USB2422L Offset: 0x54-91) (R/W 8) Product String -------- */
249#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
250typedef uint16_t USB2422_PRDSTR_Type;
251#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
252
253/* -------- USB2422_SERSTR : (USB2422L Offset: 0x92-CF) (R/W 8) Serial String -------- */
254#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
255typedef uint16_t USB2422_SERSTR_Type;
256#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
257
258/* -------- USB2422_BCEN : (USB2422L Offset: 0xD0) (R/W 8) Battery Charging Enable -------- */
259#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
260typedef union {
261 struct {
262 uint8_t : 1;
263 uint8_t PORT1_BCE : 1;
264 uint8_t PORT2_BCE : 1;
265 uint8_t : 5;
266 } bit; /*!< Structure used for bit access */
267 uint8_t reg; /*!< Type used for register access */
268} USB2422_BCEN_Type;
269#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
270
271/* -------- USB2422_BOOSTUP : (USB2422L Offset: 0xF6) (R/W 8) Boost Upstream -------- */
272#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
273typedef union {
274 struct {
275 uint8_t BOOST : 2;
276 uint8_t : 6;
277 } bit; /*!< Structure used for bit access */
278 uint8_t reg; /*!< Type used for register access */
279} USB2422_BOOSTUP_Type;
280#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
281
282/* -------- USB2422_BOOSTDOWN : (USB2422L Offset: 0xF8) (R/W 8) Boost Downstream -------- */
283#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
284typedef union {
285 struct {
286 uint8_t BOOST1 : 2;
287 uint8_t BOOST2 : 2;
288 uint8_t : 4;
289 } bit; /*!< Structure used for bit access */
290 uint8_t reg; /*!< Type used for register access */
291} USB2422_BOOSTDOWN_Type;
292#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
293
294/* -------- USB2422_PRTSP : (USB2422L Offset: 0xFA) (R/W 8) Port Swap -------- */
295#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
296typedef union {
297 struct {
298 uint8_t : 1;
299 uint8_t PORT1_SP : 1;
300 uint8_t PORT2_SP : 1;
301 uint8_t : 5;
302 } bit; /*!< Structure used for bit access */
303 uint8_t reg; /*!< Type used for register access */
304} USB2422_PRTSP_Type;
305#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
306
307/* -------- USB2422_PRTR12 : (USB2422L Offset: 0xFB) (R/W 8) Port 1/2 Remap -------- */
308#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
309typedef union {
310 struct {
311 uint8_t PORT1_REMAP : 4;
312 uint8_t PORT2_REMAP : 4;
313 } bit; /*!< Structure used for bit access */
314 uint8_t reg; /*!< Type used for register access */
315} USB2422_PRTR12_Type;
316#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
317#define USB2422_PRTR12_DISABLE 0
318#define USB2422_PRT12_P2TOL1 1
319#define USB2422_PRT12_P2XTOL2 2
320#define USB2422_PRT12_P1TOL1 1
321#define USB2422_PRT12_P1XTOL2 2
322
323/* -------- USB2422_STCD : (USB2422L Offset: 0xFF) (R/W 8) Status Command -------- */
324#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
325typedef union {
326 struct {
327 uint8_t USB_ATTACH : 1;
328 uint8_t RESET : 1;
329 uint8_t INTF_PWRDN : 1;
330 uint8_t : 5;
331 } bit; /*!< Structure used for bit access */
332 uint8_t reg; /*!< Type used for register access */
333} USB2422_STCD_Type;
334#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
335
336/** \brief USB2422 device hardware registers */
337#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
338typedef struct {
339 USB2422_VID_Type VID; /**< \brief Offset: 0x00*/
340 USB2422_PID_Type PID; /**< \brief Offset: 0x02*/
341 USB2422_DID_Type DID; /**< \brief Offset: 0x04*/
342 USB2422_CFG1_Type CFG1; /**< \brief Offset: 0x06*/
343 USB2422_CFG2_Type CFG2; /**< \brief Offset: 0x07*/
344 USB2422_CFG3_Type CFG3; /**< \brief Offset: 0x08*/
345 USB2422_NRD_Type NRD; /**< \brief Offset: 0x09*/
346 USB2422_PDS_Type PDS; /**< \brief Offset: 0x0A*/
347 USB2422_PDB_Type PDB; /**< \brief Offset: 0x0B*/
348 USB2422_MAXPS_Type MAXPS; /**< \brief Offset: 0x0C*/
349 USB2422_MAXPB_Type MAXPB; /**< \brief Offset: 0x0D*/
350 USB2422_HCMCS_Type HCMCS; /**< \brief Offset: 0x0E*/
351 USB2422_HCMCB_Type HCMCB; /**< \brief Offset: 0x0F*/
352 USB2422_PWRT_Type PWRT; /**< \brief Offset: 0x10*/
353 USB2422_LANGID_LSB_Type LANGID_LSB; /**< \brief Offset: 0x11*/
354 USB2422_LANGID_MSB_Type LANGID_MSB; /**< \brief Offset: 0x12*/
355 USB2422_MFRSL_Type MFRSL; /**< \brief Offset: 0x13*/
356 USB2422_PRDSL_Type PRDSL; /**< \brief Offset: 0x14*/
357 USB2422_SERSL_Type SERSL; /**< \brief Offset: 0x15*/
358 USB2422_MFRSTR_Type MFRSTR[31]; /**< \brief Offset: 0x16*/
359 USB2422_PRDSTR_Type PRDSTR[31]; /**< \brief Offset: 0x54*/
360 USB2422_SERSTR_Type SERSTR[31]; /**< \brief Offset: 0x92*/
361 USB2422_BCEN_Type BCEN; /**< \brief Offset: 0xD0*/
362 uint8_t Reserved1[0x25];
363 USB2422_BOOSTUP_Type BOOSTUP; /**< \brief Offset: 0xF6*/
364 uint8_t Reserved2[0x1];
365 USB2422_BOOSTDOWN_Type BOOSTDOWN; /**< \brief Offset: 0xF8*/
366 uint8_t Reserved3[0x1];
367 USB2422_PRTSP_Type PRTSP; /**< \brief Offset: 0xFA*/
368 USB2422_PRTR12_Type PRTR12; /**< \brief Offset: 0xFB*/
369 uint8_t Reserved4[0x3];
370 USB2422_STCD_Type STCD; /**< \brief Offset: 0xFF*/
371} Usb2422;
372#endif
373
374#define PORT_DETECT_RETRY_INTERVAL 2000
375
376#define USB_EXTRA_ADC_THRESHOLD 900
377
378#define USB_EXTRA_STATE_DISABLED 0
379#define USB_EXTRA_STATE_ENABLED 1
380#define USB_EXTRA_STATE_UNKNOWN 2
381#define USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG 3
382
383#define USB_HOST_PORT_1 0
384#define USB_HOST_PORT_2 1
385#define USB_HOST_PORT_UNKNOWN 2
386
387extern uint8_t usb_host_port;
388extern uint8_t usb_extra_state;
389extern uint8_t usb_extra_manual;
390extern uint8_t usb_gcr_auto;
391
392void USB2422_init(void);
393void USB_reset(void);
394void USB_configure(void);
395uint16_t USB_active(void);
396void USB_set_host_by_voltage(void);
397uint16_t adc_get(uint8_t muxpos);
398uint8_t USB2422_Port_Detect_Init(void);
399void USB_HandleExtraDevice(void);
400void USB_ExtraSetState(uint8_t state);
401
402#endif //_USB2422_H_
diff --git a/tmk_core/protocol/arm_atsam/usb/usb2422.c b/tmk_core/protocol/arm_atsam/usb/usb_hub.c
index a878cb6b7..c5fd284aa 100644
--- a/tmk_core/protocol/arm_atsam/usb/usb2422.c
+++ b/tmk_core/protocol/arm_atsam/usb/usb_hub.c
@@ -16,25 +16,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17 17
18#include "arm_atsam_protocol.h" 18#include "arm_atsam_protocol.h"
19#include "drivers/usb2422.h"
19#include <string.h> 20#include <string.h>
20 21
21Usb2422 USB2422_shadow;
22unsigned char i2c0_buf[34];
23
24const uint16_t MFRNAME[] = {'M', 'a', 's', 's', 'd', 'r', 'o', 'p', ' ', 'I', 'n', 'c', '.'}; // Massdrop Inc.
25const uint16_t PRDNAME[] = {'M', 'a', 's', 's', 'd', 'r', 'o', 'p', ' ', 'H', 'u', 'b'}; // Massdrop Hub
26#ifndef MD_BOOTLOADER
27// Serial number reported stops before first found space character or at last found character
28const uint16_t SERNAME[] = {'U', 'n', 'a', 'v', 'a', 'i', 'l', 'a', 'b', 'l', 'e'}; // Unavailable
29#else
30// In production, this field is found, modified, and offset noted as the last 32-bit word in the bootloader space
31// The offset allows the application to use the factory programmed serial (which may differ from the physical serial label)
32// Serial number reported stops before first found space character or when max size is reached
33__attribute__((__aligned__(4))) const uint16_t SERNAME[BOOTLOADER_SERIAL_MAX_SIZE] = {'M', 'D', 'H', 'U', 'B', 'B', 'O', 'O', 'T', 'L', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'};
34// NOTE: Serial replacer will not write a string longer than given here as a precaution, so give enough
35// space as needed and adjust BOOTLOADER_SERIAL_MAX_SIZE to match amount given
36#endif // MD_BOOTLOADER
37
38uint8_t usb_host_port; 22uint8_t usb_host_port;
39 23
40#ifndef MD_BOOTLOADER 24#ifndef MD_BOOTLOADER
@@ -47,29 +31,7 @@ uint8_t usb_gcr_auto;
47 31
48uint16_t adc_extra; 32uint16_t adc_extra;
49 33
50void USB_write2422_block(void) { 34void USB_Hub_init(void) {
51 unsigned char *dest = i2c0_buf;
52 unsigned char *src;
53 unsigned char *base = (unsigned char *)&USB2422_shadow;
54
55 DBGC(DC_USB_WRITE2422_BLOCK_BEGIN);
56
57 for (src = base; src < base + 256; src += 32) {
58 dest[0] = src - base;
59 dest[1] = 32;
60 memcpy(&dest[2], src, 32);
61 i2c0_transmit(USB2422_ADDR, dest, 34, 50000);
62 SERCOM0->I2CM.CTRLB.bit.CMD = 0x03;
63 while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) {
64 DBGC(DC_USB_WRITE2422_BLOCK_SYNC_SYSOP);
65 }
66 wait_us(100);
67 }
68
69 DBGC(DC_USB_WRITE2422_BLOCK_COMPLETE);
70}
71
72void USB2422_init(void) {
73 Gclk * pgclk = GCLK; 35 Gclk * pgclk = GCLK;
74 Mclk * pmclk = MCLK; 36 Mclk * pmclk = MCLK;
75 Port * pport = PORT; 37 Port * pport = PORT;
@@ -147,9 +109,7 @@ void USB2422_init(void) {
147 pusb->DEVICE.QOSCTRL.bit.DQOS = 2; 109 pusb->DEVICE.QOSCTRL.bit.DQOS = 2;
148 pusb->DEVICE.QOSCTRL.bit.CQOS = 2; 110 pusb->DEVICE.QOSCTRL.bit.CQOS = 2;
149 111
150 pport->Group[USB2422_HUB_ACTIVE_GROUP].PINCFG[USB2422_HUB_ACTIVE_PIN].bit.INEN = 1; 112 USB2422_init();
151
152 i2c0_init(); // IC2 clk must be high at USB2422 reset release time to signal SMB configuration
153 113
154 sr_exp_data.bit.HUB_CONNECT = 1; // connect signal 114 sr_exp_data.bit.HUB_CONNECT = 1; // connect signal
155 sr_exp_data.bit.HUB_RESET_N = 1; // reset high 115 sr_exp_data.bit.HUB_RESET_N = 1; // reset high
@@ -181,62 +141,16 @@ void USB_reset(void) {
181} 141}
182 142
183void USB_configure(void) { 143void USB_configure(void) {
184 Usb2422 *pusb2422 = &USB2422_shadow;
185 memset(pusb2422, 0, sizeof(Usb2422));
186
187 uint16_t *serial_use = (uint16_t *)SERNAME; // Default to use SERNAME from this file
188 uint8_t serial_length = sizeof(SERNAME) / sizeof(uint16_t); // Default to use SERNAME from this file
189#ifndef MD_BOOTLOADER
190 uint32_t serial_ptrloc = (uint32_t)&_srom - 4;
191#else // MD_BOOTLOADER
192 uint32_t serial_ptrloc = (uint32_t)&_erom - 4;
193#endif // MD_BOOTLOADER
194 uint32_t serial_address = *(uint32_t *)serial_ptrloc; // Address of bootloader's serial number if available
195
196 DBGC(DC_USB_CONFIGURE_BEGIN); 144 DBGC(DC_USB_CONFIGURE_BEGIN);
197 145
198 if (serial_address != 0xFFFFFFFF && serial_address < serial_ptrloc) // Check for factory programmed serial address 146 USB2422_configure();
199 {
200 if ((serial_address & 0xFF) % 4 == 0) // Check alignment
201 {
202 serial_use = (uint16_t *)(serial_address);
203 serial_length = 0;
204 while ((*(serial_use + serial_length) > 32 && *(serial_use + serial_length) < 127) && serial_length < BOOTLOADER_SERIAL_MAX_SIZE) {
205 serial_length++;
206 DBGC(DC_USB_CONFIGURE_GET_SERIAL);
207 }
208 }
209 }
210
211 // configure Usb2422 registers
212 pusb2422->VID.reg = 0x04D8; // from Microchip 4/19/2018
213 pusb2422->PID.reg = 0xEEC5; // from Microchip 4/19/2018 = Massdrop, Inc. USB Hub
214 pusb2422->DID.reg = 0x0101; // BCD 01.01
215 pusb2422->CFG1.bit.SELF_BUS_PWR = 1; // self powered for now
216 pusb2422->CFG1.bit.HS_DISABLE = 1; // full or high speed
217 // pusb2422->CFG2.bit.COMPOUND = 0; // compound device
218 pusb2422->CFG3.bit.STRING_EN = 1; // strings enabled
219 // pusb2422->NRD.bit.PORT2_NR = 0; // MCU is non-removable
220 pusb2422->MAXPB.reg = 20; // 0mA
221 pusb2422->HCMCB.reg = 20; // 0mA
222 pusb2422->MFRSL.reg = sizeof(MFRNAME) / sizeof(uint16_t);
223 pusb2422->PRDSL.reg = sizeof(PRDNAME) / sizeof(uint16_t);
224 pusb2422->SERSL.reg = serial_length;
225 memcpy(pusb2422->MFRSTR, MFRNAME, sizeof(MFRNAME));
226 memcpy(pusb2422->PRDSTR, PRDNAME, sizeof(PRDNAME));
227 memcpy(pusb2422->SERSTR, serial_use, serial_length * sizeof(uint16_t));
228 // pusb2422->BOOSTUP.bit.BOOST=3; //upstream port
229 // pusb2422->BOOSTDOWN.bit.BOOST1=0; // extra port
230 // pusb2422->BOOSTDOWN.bit.BOOST2=2; //MCU is close
231 pusb2422->STCD.bit.USB_ATTACH = 1;
232 USB_write2422_block();
233 147
234 adc_extra = 0; 148 adc_extra = 0;
235 149
236 DBGC(DC_USB_CONFIGURE_COMPLETE); 150 DBGC(DC_USB_CONFIGURE_COMPLETE);
237} 151}
238 152
239uint16_t USB_active(void) { return (PORT->Group[USB2422_HUB_ACTIVE_GROUP].IN.reg & (1 << USB2422_HUB_ACTIVE_PIN)) != 0; } 153uint16_t USB_active(void) { return USB2422_active(); }
240 154
241void USB_set_host_by_voltage(void) { 155void USB_set_host_by_voltage(void) {
242 // UP is upstream device (HOST) 156 // UP is upstream device (HOST)
@@ -314,7 +228,7 @@ void USB_set_host_by_voltage(void) {
314 DBGC(DC_USB_SET_HOST_BY_VOLTAGE_COMPLETE); 228 DBGC(DC_USB_SET_HOST_BY_VOLTAGE_COMPLETE);
315} 229}
316 230
317uint8_t USB2422_Port_Detect_Init(void) { 231uint8_t USB_Hub_Port_Detect_Init(void) {
318 uint32_t port_detect_retry_ms; 232 uint32_t port_detect_retry_ms;
319 uint32_t tmod; 233 uint32_t tmod;
320 234
diff --git a/tmk_core/protocol/arm_atsam/usb/usb_hub.h b/tmk_core/protocol/arm_atsam/usb/usb_hub.h
new file mode 100644
index 000000000..76b1e0a32
--- /dev/null
+++ b/tmk_core/protocol/arm_atsam/usb/usb_hub.h
@@ -0,0 +1,51 @@
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_