mirror of https://github.com/Desuuuu/klipper.git
stm32: Add USBOTG support to stm32h7
Signed-off-by: Aaron DeLyser <bluwolf@gmail.com> Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
4d738c8379
commit
4eeb4620cd
|
@ -91,7 +91,7 @@ config HAVE_STM32_USBFS
|
||||||
default y if MACH_STM32F103 || MACH_STM32F0x2 || MACH_STM32F070
|
default y if MACH_STM32F103 || MACH_STM32F0x2 || MACH_STM32F070
|
||||||
config HAVE_STM32_USBOTG
|
config HAVE_STM32_USBOTG
|
||||||
bool
|
bool
|
||||||
default y if MACH_STM32F2 || MACH_STM32F4
|
default y if MACH_STM32F2 || MACH_STM32F4 || MACH_STM32H7
|
||||||
config HAVE_STM32_CANBUS
|
config HAVE_STM32_CANBUS
|
||||||
bool
|
bool
|
||||||
default y if MACH_STM32F1 || MACH_STM32F2 || MACH_STM32F4 || MACH_STM32F0x2
|
default y if MACH_STM32F1 || MACH_STM32F2 || MACH_STM32F4 || MACH_STM32F0x2
|
||||||
|
@ -263,6 +263,10 @@ choice
|
||||||
config STM32_USB_PA11_PA12_REMAP
|
config STM32_USB_PA11_PA12_REMAP
|
||||||
bool "USB (on PA9/PA10)" if LOW_LEVEL_OPTIONS && MACH_STM32F042
|
bool "USB (on PA9/PA10)" if LOW_LEVEL_OPTIONS && MACH_STM32F042
|
||||||
select USBSERIAL
|
select USBSERIAL
|
||||||
|
config STM32_USB_PB14_PB15
|
||||||
|
bool "USB (on PB14/PB15)"
|
||||||
|
depends on MACH_STM32H7
|
||||||
|
select USBSERIAL
|
||||||
config STM32_SERIAL_USART1
|
config STM32_SERIAL_USART1
|
||||||
bool "Serial (on USART1 PA10/PA9)"
|
bool "Serial (on USART1 PA10/PA9)"
|
||||||
select SERIAL
|
select SERIAL
|
||||||
|
|
|
@ -127,6 +127,19 @@ gpio_peripheral(uint32_t gpio, uint32_t mode, int pullup)
|
||||||
regs->OSPEEDR = (regs->OSPEEDR & ~m_msk) | (STM_OSPEED << m_shift);
|
regs->OSPEEDR = (regs->OSPEEDR & ~m_msk) | (STM_OSPEED << m_shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define USB_BOOT_FLAG_ADDR (CONFIG_RAM_START + CONFIG_RAM_SIZE - 4096)
|
||||||
|
#define USB_BOOT_FLAG 0x55534220424f4f54 // "USB BOOT"
|
||||||
|
|
||||||
|
// Handle USB reboot requests
|
||||||
|
void
|
||||||
|
usb_request_bootloader(void)
|
||||||
|
{
|
||||||
|
irq_disable();
|
||||||
|
// System DFU Bootloader
|
||||||
|
*(uint64_t*)USB_BOOT_FLAG_ADDR = USB_BOOT_FLAG;
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
|
||||||
#if !CONFIG_STM32_CLOCK_REF_INTERNAL
|
#if !CONFIG_STM32_CLOCK_REF_INTERNAL
|
||||||
DECL_CONSTANT_STR("RESERVE_PINS_crystal", "PH0,PH1");
|
DECL_CONSTANT_STR("RESERVE_PINS_crystal", "PH0,PH1");
|
||||||
#endif
|
#endif
|
||||||
|
@ -135,6 +148,10 @@ DECL_CONSTANT_STR("RESERVE_PINS_crystal", "PH0,PH1");
|
||||||
static void
|
static void
|
||||||
clock_setup(void)
|
clock_setup(void)
|
||||||
{
|
{
|
||||||
|
// Ensure USB OTG ULPI is not enabled
|
||||||
|
CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_USB2OTGHSULPIEN);
|
||||||
|
CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_USB2OTGHSULPILPEN);
|
||||||
|
|
||||||
// Set this despite correct defaults.
|
// Set this despite correct defaults.
|
||||||
// "The software has to program the supply configuration in PWR control
|
// "The software has to program the supply configuration in PWR control
|
||||||
// register 3" (pg. 259)
|
// register 3" (pg. 259)
|
||||||
|
@ -205,11 +222,16 @@ clock_setup(void)
|
||||||
;
|
;
|
||||||
|
|
||||||
// Set HPRE, D1PPRE, D2PPRE, D2PPRE2, D3PPRE dividers
|
// Set HPRE, D1PPRE, D2PPRE, D2PPRE2, D3PPRE dividers
|
||||||
MODIFY_REG(RCC->D1CFGR, RCC_D1CFGR_HPRE_Msk, RCC_D1CFGR_HPRE_DIV2);
|
// 480MHz / 2 = 240MHz rcc_hclk3
|
||||||
MODIFY_REG(RCC->D1CFGR, RCC_D1CFGR_D1PPRE_Msk, RCC_D1CFGR_D1PPRE_DIV2);
|
MODIFY_REG(RCC->D1CFGR, RCC_D1CFGR_HPRE, RCC_D1CFGR_HPRE_3);
|
||||||
MODIFY_REG(RCC->D2CFGR, RCC_D2CFGR_D2PPRE1_Msk, RCC_D2CFGR_D2PPRE1_DIV2);
|
// 240MHz / 2 = 120MHz rcc_pclk3
|
||||||
MODIFY_REG(RCC->D2CFGR, RCC_D2CFGR_D2PPRE2_Msk, RCC_D2CFGR_D2PPRE2_DIV2);
|
MODIFY_REG(RCC->D1CFGR, RCC_D1CFGR_D1PPRE, RCC_D1CFGR_D1PPRE_DIV2);
|
||||||
MODIFY_REG(RCC->D3CFGR, RCC_D3CFGR_D3PPRE_Msk, RCC_D3CFGR_D3PPRE_DIV2);
|
// 240MHz / 2 = 120MHz rcc_pclk1
|
||||||
|
MODIFY_REG(RCC->D2CFGR, RCC_D2CFGR_D2PPRE1, RCC_D2CFGR_D2PPRE1_DIV2);
|
||||||
|
// 240MHz / 2 = 120MHz rcc_pclk2
|
||||||
|
MODIFY_REG(RCC->D2CFGR, RCC_D2CFGR_D2PPRE2, RCC_D2CFGR_D2PPRE2_DIV2);
|
||||||
|
// 240MHz / 2 = 120MHz rcc_pclk4
|
||||||
|
MODIFY_REG(RCC->D3CFGR, RCC_D3CFGR_D3PPRE, RCC_D3CFGR_D3PPRE_DIV2);
|
||||||
|
|
||||||
// Switch on PLL1
|
// Switch on PLL1
|
||||||
RCC->CR |= RCC_CR_PLL1ON;
|
RCC->CR |= RCC_CR_PLL1ON;
|
||||||
|
@ -220,6 +242,19 @@ clock_setup(void)
|
||||||
MODIFY_REG(RCC->CFGR, RCC_CFGR_SW_Msk, RCC_CFGR_SW_PLL1);
|
MODIFY_REG(RCC->CFGR, RCC_CFGR_SW_Msk, RCC_CFGR_SW_PLL1);
|
||||||
while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL1)
|
while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL1)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
// Configure HSI48 clock for USB
|
||||||
|
if (CONFIG_USBSERIAL) {
|
||||||
|
SET_BIT(RCC->CR, RCC_CR_HSI48ON);
|
||||||
|
while((RCC->CR & RCC_CR_HSI48RDY) == 0);
|
||||||
|
SET_BIT(RCC->APB1HENR, RCC_APB1HENR_CRSEN);
|
||||||
|
SET_BIT(RCC->APB1HRSTR, RCC_APB1HRSTR_CRSRST);
|
||||||
|
CLEAR_BIT(RCC->APB1HRSTR, RCC_APB1HRSTR_CRSRST);
|
||||||
|
CLEAR_BIT(CRS->CFGR, CRS_CFGR_SYNCSRC);
|
||||||
|
SET_BIT(CRS->CR, CRS_CR_CEN | CRS_CR_AUTOTRIMEN);
|
||||||
|
CLEAR_BIT(RCC->D2CCIP2R, RCC_D2CCIP2R_USBSEL);
|
||||||
|
SET_BIT(RCC->D2CCIP2R, RCC_D2CCIP2R_USBSEL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main entry point - called from armcm_boot.c:ResetHandler()
|
// Main entry point - called from armcm_boot.c:ResetHandler()
|
||||||
|
|
|
@ -14,16 +14,34 @@
|
||||||
#include "internal.h" // GPIO
|
#include "internal.h" // GPIO
|
||||||
#include "sched.h" // DECL_INIT
|
#include "sched.h" // DECL_INIT
|
||||||
|
|
||||||
|
#if CONFIG_STM32_USB_PB14_PB15
|
||||||
|
#define USB_PERIPH_BASE USB_OTG_HS_PERIPH_BASE
|
||||||
|
#define OTG_IRQn OTG_HS_IRQn
|
||||||
|
#define USBOTGEN RCC_AHB1ENR_USB1OTGHSEN
|
||||||
|
#define GPIO_D_NEG GPIO('B', 14)
|
||||||
|
#define GPIO_D_POS GPIO('B', 15)
|
||||||
|
#define GPIO_FUNC GPIO_FUNCTION(12)
|
||||||
|
DECL_CONSTANT_STR("RESERVE_PINS_USB1", "PB14,PB15");
|
||||||
|
#else
|
||||||
|
#define USB_PERIPH_BASE USB_OTG_FS_PERIPH_BASE
|
||||||
|
#define OTG_IRQn OTG_FS_IRQn
|
||||||
|
#define USBOTGEN RCC_AHB1ENR_USB2OTGHSEN
|
||||||
|
#define GPIO_D_NEG GPIO('A', 11)
|
||||||
|
#define GPIO_D_POS GPIO('A', 12)
|
||||||
|
#define GPIO_FUNC GPIO_FUNCTION(10)
|
||||||
|
DECL_CONSTANT_STR("RESERVE_PINS_USB", "PA11,PA12");
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usb_irq_disable(void)
|
usb_irq_disable(void)
|
||||||
{
|
{
|
||||||
NVIC_DisableIRQ(OTG_FS_IRQn);
|
NVIC_DisableIRQ(OTG_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usb_irq_enable(void)
|
usb_irq_enable(void)
|
||||||
{
|
{
|
||||||
NVIC_EnableIRQ(OTG_FS_IRQn);
|
NVIC_EnableIRQ(OTG_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,17 +49,13 @@ usb_irq_enable(void)
|
||||||
* USB transfer memory
|
* USB transfer memory
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
|
|
||||||
#define OTG ((USB_OTG_GlobalTypeDef*)USB_OTG_FS_PERIPH_BASE)
|
#define OTG ((USB_OTG_GlobalTypeDef*)USB_PERIPH_BASE)
|
||||||
#define OTGD ((USB_OTG_DeviceTypeDef*) \
|
#define OTGD ((USB_OTG_DeviceTypeDef*)(USB_PERIPH_BASE + USB_OTG_DEVICE_BASE))
|
||||||
(USB_OTG_FS_PERIPH_BASE + USB_OTG_DEVICE_BASE))
|
#define EPFIFO(EP) ((void*)(USB_PERIPH_BASE + USB_OTG_FIFO_BASE + ((EP) << 12)))
|
||||||
#define EPFIFO(EP) ((void*)(USB_OTG_FS_PERIPH_BASE + USB_OTG_FIFO_BASE \
|
|
||||||
+ ((EP) << 12)))
|
|
||||||
#define EPIN(EP) ((USB_OTG_INEndpointTypeDef*) \
|
#define EPIN(EP) ((USB_OTG_INEndpointTypeDef*) \
|
||||||
(USB_OTG_FS_PERIPH_BASE + USB_OTG_IN_ENDPOINT_BASE \
|
(USB_PERIPH_BASE + USB_OTG_IN_ENDPOINT_BASE + ((EP) << 5)))
|
||||||
+ ((EP) << 5)))
|
|
||||||
#define EPOUT(EP) ((USB_OTG_OUTEndpointTypeDef*) \
|
#define EPOUT(EP) ((USB_OTG_OUTEndpointTypeDef*) \
|
||||||
(USB_OTG_FS_PERIPH_BASE + USB_OTG_OUT_ENDPOINT_BASE \
|
(USB_PERIPH_BASE + USB_OTG_OUT_ENDPOINT_BASE + ((EP) << 5)))
|
||||||
+ ((EP) << 5)))
|
|
||||||
|
|
||||||
// Setup the USB fifos
|
// Setup the USB fifos
|
||||||
static void
|
static void
|
||||||
|
@ -382,14 +396,19 @@ OTG_FS_IRQHandler(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DECL_CONSTANT_STR("RESERVE_PINS_USB", "PA11,PA12");
|
|
||||||
|
|
||||||
// Initialize the usb controller
|
// Initialize the usb controller
|
||||||
void
|
void
|
||||||
usb_init(void)
|
usb_init(void)
|
||||||
{
|
{
|
||||||
// Enable USB clock
|
// Enable USB clock
|
||||||
|
#if CONFIG_MACH_STM32H7
|
||||||
|
if (READ_BIT(PWR->CR3, PWR_CR3_USB33RDY) != (PWR_CR3_USB33RDY)) {
|
||||||
|
SET_BIT(PWR->CR3, PWR_CR3_USB33DEN);
|
||||||
|
}
|
||||||
|
SET_BIT(RCC->AHB1ENR, USBOTGEN);
|
||||||
|
#else
|
||||||
RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
|
RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
|
||||||
|
#endif
|
||||||
while (!(OTG->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL))
|
while (!(OTG->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL))
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -397,15 +416,15 @@ usb_init(void)
|
||||||
OTG->GUSBCFG = (USB_OTG_GUSBCFG_FDMOD | USB_OTG_GUSBCFG_PHYSEL
|
OTG->GUSBCFG = (USB_OTG_GUSBCFG_FDMOD | USB_OTG_GUSBCFG_PHYSEL
|
||||||
| (6 << USB_OTG_GUSBCFG_TRDT_Pos));
|
| (6 << USB_OTG_GUSBCFG_TRDT_Pos));
|
||||||
OTGD->DCFG |= (3 << USB_OTG_DCFG_DSPD_Pos);
|
OTGD->DCFG |= (3 << USB_OTG_DCFG_DSPD_Pos);
|
||||||
#if CONFIG_MACH_STM32F446
|
#if CONFIG_MACH_STM32F446 || CONFIG_MACH_STM32H7
|
||||||
OTG->GOTGCTL = USB_OTG_GOTGCTL_BVALOEN | USB_OTG_GOTGCTL_BVALOVAL;
|
OTG->GOTGCTL = USB_OTG_GOTGCTL_BVALOEN | USB_OTG_GOTGCTL_BVALOVAL;
|
||||||
#else
|
#else
|
||||||
OTG->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
|
OTG->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Route pins
|
// Route pins
|
||||||
gpio_peripheral(GPIO('A', 11), GPIO_FUNCTION(10), 0);
|
gpio_peripheral(GPIO_D_NEG, GPIO_FUNC, 0);
|
||||||
gpio_peripheral(GPIO('A', 12), GPIO_FUNCTION(10), 0);
|
gpio_peripheral(GPIO_D_POS, GPIO_FUNC, 0);
|
||||||
|
|
||||||
// Setup USB packet memory
|
// Setup USB packet memory
|
||||||
fifo_configure();
|
fifo_configure();
|
||||||
|
@ -423,7 +442,7 @@ usb_init(void)
|
||||||
OTGD->DIEPMSK = USB_OTG_DIEPMSK_XFRCM;
|
OTGD->DIEPMSK = USB_OTG_DIEPMSK_XFRCM;
|
||||||
OTG->GINTMSK = USB_OTG_GINTMSK_RXFLVLM | USB_OTG_GINTMSK_IEPINT;
|
OTG->GINTMSK = USB_OTG_GINTMSK_RXFLVLM | USB_OTG_GINTMSK_IEPINT;
|
||||||
OTG->GAHBCFG = USB_OTG_GAHBCFG_GINT;
|
OTG->GAHBCFG = USB_OTG_GAHBCFG_GINT;
|
||||||
armcm_enable_irq(OTG_FS_IRQHandler, OTG_FS_IRQn, 1);
|
armcm_enable_irq(OTG_FS_IRQHandler, OTG_IRQn, 1);
|
||||||
|
|
||||||
// Enable USB
|
// Enable USB
|
||||||
OTG->GCCFG |= USB_OTG_GCCFG_PWRDWN;
|
OTG->GCCFG |= USB_OTG_GCCFG_PWRDWN;
|
||||||
|
|
Loading…
Reference in New Issue