Restore GPIO15 state after modifying it for USB enumeration fix (#80)
Restore GPIO15 state after usb enumeration fix Co-authored-by: Luke Wren <wren6991@gmail.com>
This commit is contained in:
		
				
					committed by
					
						
						graham sanderson
					
				
			
			
				
	
			
			
			
						parent
						
							c44d5026db
						
					
				
				
					commit
					5514401bf4
				
			@ -8,6 +8,8 @@
 | 
				
			|||||||
#include "pico/time.h"
 | 
					#include "pico/time.h"
 | 
				
			||||||
#include "hardware/structs/usb.h"
 | 
					#include "hardware/structs/usb.h"
 | 
				
			||||||
#include "hardware/gpio.h"
 | 
					#include "hardware/gpio.h"
 | 
				
			||||||
 | 
					#include "hardware/structs/iobank0.h"
 | 
				
			||||||
 | 
					#include "hardware/structs/padsbank0.h"
 | 
				
			||||||
#include "pico/fix/rp2040_usb_device_enumeration.h"
 | 
					#include "pico/fix/rp2040_usb_device_enumeration.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define LS_SE0 0b00
 | 
					#define LS_SE0 0b00
 | 
				
			||||||
@ -74,20 +76,37 @@ int64_t hw_enumeration_fix_force_ls_j_done(alarm_id_t id, void *user_data) {
 | 
				
			|||||||
    return 0;
 | 
					    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) {
 | 
					static void hw_enumeration_fix_force_ls_j(void) {
 | 
				
			||||||
    // Force LS_J
 | 
					    // DM must be 0 for this to work. This is true if it is selected
 | 
				
			||||||
    const uint dp = 15;
 | 
					    // to any other function. fn 8 on this pin is only for debug so shouldn't
 | 
				
			||||||
    //const uint dm = 16;
 | 
					    // be selected
 | 
				
			||||||
    gpio_set_function(dp, 8);
 | 
					    if (gpio_get_function(dm) == 8) {
 | 
				
			||||||
    // TODO: assert dm is not funcseld to usb
 | 
					        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
 | 
					    // 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
 | 
					    // DP = 1 and DM = 0. Don't actually need to set DM low as it
 | 
				
			||||||
    // is already gated assuming it isn't funcseld.
 | 
					    // is already gated assuming it isn't funcseld.
 | 
				
			||||||
    gpio_set_inover(dp, GPIO_OVERRIDE_HIGH);
 | 
					    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
 | 
					    // 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 = 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;
 | 
					    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
 | 
					    // Get rid of DP pullup override
 | 
				
			||||||
    hw_clear_alias(usb_hw)->phy_direct_override = USB_USBPHY_DIRECT_OVERRIDE_DP_PULLUP_EN_OVERRIDE_EN_BITS;
 | 
					    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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user