-
-
Notifications
You must be signed in to change notification settings - Fork 212
/
Copy path0088-RP2040-backport-p2040_usb_device_enumeration-fix.patch
95 lines (85 loc) · 4.08 KB
/
0088-RP2040-backport-p2040_usb_device_enumeration-fix.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
From c3e4ce73d19f384ef5d874e7aad0a89ec3d7b80e Mon Sep 17 00:00:00 2001
From: Martino Facchin <m.facchin@arduino.cc>
Date: Mon, 15 Nov 2021 16:47:42 +0100
Subject: [PATCH 088/204] RP2040: backport p2040_usb_device_enumeration fix
---
.../rp2040_usb_device_enumeration.c | 42 +++++++++++++++----
1 file changed, 33 insertions(+), 9 deletions(-)
diff --git a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c
index 8319e36cb7..91583205bb 100644
--- a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c
+++ b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c
@@ -8,6 +8,8 @@
#include "pico/time.h"
#include "hardware/structs/usb.h"
#include "hardware/gpio.h"
+#include "hardware/structs/iobank0.h"
+#include "hardware/structs/padsbank0.h"
#include "pico/fix/rp2040_usb_device_enumeration.h"
#define LS_SE0 0b00
@@ -36,7 +38,7 @@ static inline uint8_t hw_line_state(void) {
return (usb_hw->sie_status & USB_SIE_STATUS_LINE_STATE_BITS) >> USB_SIE_STATUS_LINE_STATE_LSB;
}
-int64_t hw_enumeration_fix_wait_se0_callback(alarm_id_t id, void *user_data) {
+int64_t hw_enumeration_fix_wait_se0_callback(__unused alarm_id_t id, __unused void *user_data) {
if (hw_line_state() == LS_SE0) {
// Come back in 1ms and check again
return 1000;
@@ -69,25 +71,42 @@ static void hw_enumeration_fix_wait_se0(void) {
hw_enumeration_fix_busy_wait_se0();
}
-int64_t hw_enumeration_fix_force_ls_j_done(alarm_id_t id, void *user_data) {
+int64_t hw_enumeration_fix_force_ls_j_done(__unused alarm_id_t id, __unused void *user_data) {
hw_enumeration_fix_finish();
return 0;
}
+static uint32_t gpio_ctrl_prev = 0;
+static uint32_t pad_ctrl_prev = 0;
+static const uint dp = 15;
+static const uint dm = 16;
+
static void hw_enumeration_fix_force_ls_j(void) {
- // Force LS_J
- const uint dp = 15;
- //const uint dm = 16;
- gpio_set_function(dp, 8);
- // TODO: assert dm is not funcseld to usb
+ // DM must be 0 for this to work. This is true if it is selected
+ // to any other function. fn 8 on this pin is only for debug so shouldn't
+ // be selected
+ if (gpio_get_function(dm) == 8) {
+ panic("Not expecting DM to be function 8");
+ }
+
+ // Before changing any pin state, take a copy of the current gpio control register
+ gpio_ctrl_prev = iobank0_hw->io[dp].ctrl;
+ // Also take a copy of the pads register
+ pad_ctrl_prev = padsbank0_hw->io[dp];
+
+ // Enable bus keep and force pin to tristate, so USB DP muxing doesn't affect
+ // pin state
+ gpio_set_pulls(dp, true, true);
+ gpio_set_oeover(dp, GPIO_OVERRIDE_LOW);
+ // Select function 8 (USB debug muxing) without disturbing other controls
+ hw_write_masked(&iobank0_hw->io[dp].ctrl,
+ 8 << IO_BANK0_GPIO15_CTRL_FUNCSEL_LSB, IO_BANK0_GPIO15_CTRL_FUNCSEL_BITS);
// J state is a differential 1 for a full speed device so
// DP = 1 and DM = 0. Don't actually need to set DM low as it
// is already gated assuming it isn't funcseld.
gpio_set_inover(dp, GPIO_OVERRIDE_HIGH);
- // TODO: What to do about existing DP state here?
-
// Force PHY pull up to stay before switching away from the phy
hw_set_alias(usb_hw)->phy_direct = USB_USBPHY_DIRECT_DP_PULLUP_EN_BITS;
hw_set_alias(usb_hw)->phy_direct_override = USB_USBPHY_DIRECT_OVERRIDE_DP_PULLUP_EN_OVERRIDE_EN_BITS;
@@ -118,4 +137,9 @@ static void hw_enumeration_fix_finish(void) {
// Get rid of DP pullup override
hw_clear_alias(usb_hw)->phy_direct_override = USB_USBPHY_DIRECT_OVERRIDE_DP_PULLUP_EN_OVERRIDE_EN_BITS;
+
+ // Finally, restore the gpio ctrl value back to GPIO15
+ iobank0_hw->io[dp].ctrl = gpio_ctrl_prev;
+ // Restore the pad ctrl value
+ padsbank0_hw->io[dp] = pad_ctrl_prev;
}
--
2.39.1