diff --git a/arch/arm/include/stm32g0/irq.h b/arch/arm/include/stm32g0/irq.h index 1edbcd2b850..4d4b3c98ff4 100644 --- a/arch/arm/include/stm32g0/irq.h +++ b/arch/arm/include/stm32g0/irq.h @@ -90,6 +90,7 @@ #else # define STM32_IRQ_UCPD12 (STM32_IRQ_EXTINT + 8) /* 8: UCPD1_2 */ # define STM32_IRQ_EXTI32_33 (STM32_IRQ_EXTINT + 8) /* 8: EXTI_32_33 */ +# define STM32_IRQ_USB (STM32_IRQ_EXTINT + 8) /* 8: USB */ #endif #define STM32_IRQ_DMA1CH1 (STM32_IRQ_EXTINT + 9) /* 9: DMA1_CH1 */ diff --git a/arch/arm/src/common/stm32/hardware/stm32_usbdev_m0.h b/arch/arm/src/common/stm32/hardware/stm32_usbdev_m0.h index 80c3445f962..9af1c4f14bd 100644 --- a/arch/arm/src/common/stm32/hardware/stm32_usbdev_m0.h +++ b/arch/arm/src/common/stm32/hardware/stm32_usbdev_m0.h @@ -40,39 +40,44 @@ /* Endpoint Registers */ -#define STM32_USB_EPR_OFFSET(n) ((n) << 2) /* USB endpoint n register (16-bits) */ +#define STM32_USB_EPR_OFFSET(n) ((n) << 2) -#define STM32_USB_EP0R_OFFSET 0x0000 /* USB endpoint 0 register (16-bits) */ -#define STM32_USB_EP1R_OFFSET 0x0004 /* USB endpoint 1 register (16-bits) */ -#define STM32_USB_EP2R_OFFSET 0x0008 /* USB endpoint 2 register (16-bits) */ -#define STM32_USB_EP3R_OFFSET 0x000c /* USB endpoint 3 register (16-bits) */ -#define STM32_USB_EP4R_OFFSET 0x0010 /* USB endpoint 4 register (16-bits) */ -#define STM32_USB_EP5R_OFFSET 0x0014 /* USB endpoint 5 register (16-bits) */ -#define STM32_USB_EP6R_OFFSET 0x0018 /* USB endpoint 6 register (16-bits) */ -#define STM32_USB_EP7R_OFFSET 0x001c /* USB endpoint 7 register (16-bits) */ +#define STM32_USB_EP0R_OFFSET 0x0000 /* USB endpoint 0 register */ +#define STM32_USB_EP1R_OFFSET 0x0004 /* USB endpoint 1 register */ +#define STM32_USB_EP2R_OFFSET 0x0008 /* USB endpoint 2 register */ +#define STM32_USB_EP3R_OFFSET 0x000c /* USB endpoint 3 register */ +#define STM32_USB_EP4R_OFFSET 0x0010 /* USB endpoint 4 register */ +#define STM32_USB_EP5R_OFFSET 0x0014 /* USB endpoint 5 register */ +#define STM32_USB_EP6R_OFFSET 0x0018 /* USB endpoint 6 register */ +#define STM32_USB_EP7R_OFFSET 0x001c /* USB endpoint 7 register */ /* Common Registers */ -#define STM32_USB_CNTR_OFFSET 0x0040 /* USB control register (16-bits) */ -#define STM32_USB_ISTR_OFFSET 0x0044 /* USB interrupt status register (16-bits) */ -#define STM32_USB_FNR_OFFSET 0x0048 /* USB frame number register (16-bits) */ -#define STM32_USB_DADDR_OFFSET 0x004c /* USB device address (16-bits) */ -#define STM32_USB_BTABLE_OFFSET 0x0050 /* Buffer table address (16-bits) */ -#define STM32_USB_LPMCSR_OFFSET 0x0054 /* LPM control and status register (16-bits) */ -#define STM32_USB_BCDR_OFFSET 0x0058 /* Battery charging detector (16-bits) */ +#define STM32_USB_CNTR_OFFSET 0x0040 /* USB control register */ +#define STM32_USB_ISTR_OFFSET 0x0044 /* USB interrupt status register */ +#define STM32_USB_FNR_OFFSET 0x0048 /* USB frame number register */ +#define STM32_USB_DADDR_OFFSET 0x004c /* USB device address */ +#ifndef CONFIG_STM32_STM32G0 +# define STM32_USB_BTABLE_OFFSET 0x0050 /* Buffer table address (16-bits) */ +#endif +#define STM32_USB_LPMCSR_OFFSET 0x0054 /* LPM control and status register */ +#define STM32_USB_BCDR_OFFSET 0x0058 /* Battery charging detector */ -/* Buffer Descriptor Table (Relatative to BTABLE address) */ +/* Buffer Descriptor Table (Relative to BTABLE address) */ -#define STM32_USB_ADDR_TX_WOFFSET (0) /* Transmission buffer address n (16-bits) */ -#define STM32_USB_COUNT_TX_WOFFSET (2) /* Transmission byte count n (16-bits) */ -#define STM32_USB_ADDR_RX_WOFFSET (4) /* Reception buffer address n (16-bits) */ -#define STM32_USB_COUNT_RX_WOFFSET (6) /* Reception byte count n (16-bits) */ - -#define STM32_USB_BTABLE_RADDR(ep,o) (((uint32_t)getreg16(STM32_USB_BTABLE) + ((ep) << 3)) + (o)) -#define STM32_USB_ADDR_TX_OFFSET(ep) STM32_USB_BTABLE_RADDR(ep,STM32_USB_ADDR_TX_WOFFSET) -#define STM32_USB_COUNT_TX_OFFSET(ep) STM32_USB_BTABLE_RADDR(ep,STM32_USB_COUNT_TX_WOFFSET) -#define STM32_USB_ADDR_RX_OFFSET(ep) STM32_USB_BTABLE_RADDR(ep,STM32_USB_ADDR_RX_WOFFSET) -#define STM32_USB_COUNT_RX_OFFSET(ep) STM32_USB_BTABLE_RADDR(ep,STM32_USB_COUNT_RX_WOFFSET) +#ifdef CONFIG_STM32_STM32G0 +# define STM32_USB_TX_WOFFSET (0) /* Transmission descriptor n (32-bits) */ +# define STM32_USB_RX_WOFFSET (4) /* Reception descriptor n (32-bits) */ +# define STM32_USB_BTABLE_RADDR(ep,o) \ + (STM32_USBRAM_BASE + ((ep) << 3) + (o)) +#else +# define STM32_USB_ADDR_TX_WOFFSET (0) /* Transmission buffer address n (16-bits) */ +# define STM32_USB_COUNT_TX_WOFFSET (2) /* Transmission byte count n (16-bits) */ +# define STM32_USB_ADDR_RX_WOFFSET (4) /* Reception buffer address n (16-bits) */ +# define STM32_USB_COUNT_RX_WOFFSET (6) /* Reception byte count n (16-bits) */ +# define STM32_USB_BTABLE_RADDR(ep,o) \ + ((uint32_t)getreg16(STM32_USB_BTABLE) + ((ep) << 3) + (o)) +#endif /* Register Addresses *******************************************************/ @@ -94,17 +99,26 @@ #define STM32_USB_ISTR (STM32_USB_BASE + STM32_USB_ISTR_OFFSET) #define STM32_USB_FNR (STM32_USB_BASE + STM32_USB_FNR_OFFSET) #define STM32_USB_DADDR (STM32_USB_BASE + STM32_USB_DADDR_OFFSET) -#define STM32_USB_BTABLE (STM32_USB_BASE + STM32_USB_BTABLE_OFFSET) +#ifndef CONFIG_STM32_STM32G0 +# define STM32_USB_BTABLE (STM32_USB_BASE + STM32_USB_BTABLE_OFFSET) +#endif #define STM32_USB_LPMCSR (STM32_USB_BASE + STM32_USB_LPMCSR_OFFSET) #define STM32_USB_BCDR (STM32_USB_BASE + STM32_USB_BCDR_OFFSET) /* Buffer Descriptor Table (Relative to BTABLE address) */ -#define STM32_USB_BTABLE_ADDR(ep,o) (STM32_USBRAM_BASE + STM32_USB_BTABLE_RADDR(ep,o)) -#define STM32_USB_ADDR_TX(ep) STM32_USB_BTABLE_ADDR(ep,STM32_USB_ADDR_TX_WOFFSET) -#define STM32_USB_COUNT_TX(ep) STM32_USB_BTABLE_ADDR(ep,STM32_USB_COUNT_TX_WOFFSET) -#define STM32_USB_ADDR_RX(ep) STM32_USB_BTABLE_ADDR(ep,STM32_USB_ADDR_RX_WOFFSET) -#define STM32_USB_COUNT_RX(ep) STM32_USB_BTABLE_ADDR(ep,STM32_USB_COUNT_RX_WOFFSET) +#ifdef CONFIG_STM32_STM32G0 +# define STM32_USB_BTABLE_ADDR(ep,o) STM32_USB_BTABLE_RADDR(ep,o) +# define STM32_USB_TX(ep) STM32_USB_BTABLE_RADDR(ep,STM32_USB_TX_WOFFSET) +# define STM32_USB_RX(ep) STM32_USB_BTABLE_RADDR(ep,STM32_USB_RX_WOFFSET) +#else +# define STM32_USB_BTABLE_ADDR(ep,o) \ + (STM32_USBRAM_BASE + STM32_USB_BTABLE_RADDR(ep,o)) +# define STM32_USB_ADDR_TX(ep) STM32_USB_BTABLE_ADDR(ep,STM32_USB_ADDR_TX_WOFFSET) +# define STM32_USB_COUNT_TX(ep) STM32_USB_BTABLE_ADDR(ep,STM32_USB_COUNT_TX_WOFFSET) +# define STM32_USB_ADDR_RX(ep) STM32_USB_BTABLE_ADDR(ep,STM32_USB_ADDR_RX_WOFFSET) +# define STM32_USB_COUNT_RX(ep) STM32_USB_BTABLE_ADDR(ep,STM32_USB_COUNT_RX_WOFFSET) +#endif /* Register Bitfield Definitions ********************************************/ @@ -239,16 +253,27 @@ /* Reception buffer address */ -#define USB_ADDR_RX_ZERO (1 << 0) /* Bit 0 This bit must always be written as ‘0’ */ -#define USB_ADDR_RX_SHIFT (1) /* Bits 15:1 ADDRn_RX[15:1]: Reception Buffer Address */ -#define USB_ADDR_RX_MASK (0x7fff << USB_ADDR_RX_SHIFT) +#ifdef CONFIG_STM32_STM32G0 +# define USB_ADDR_RX_SHIFT (2) /* Bits 15:2: Reception buffer address */ +# define USB_ADDR_RX_MASK (0x3fff << USB_ADDR_RX_SHIFT) +#else +# define USB_ADDR_RX_ZERO (1 << 0) /* Bit 0 must always be written as zero */ +# define USB_ADDR_RX_SHIFT (1) /* Bits 15:1: Reception buffer address */ +# define USB_ADDR_RX_MASK (0x7fff << USB_ADDR_RX_SHIFT) +#endif /* Reception byte count */ -#define USB_COUNT_RX_BL_SIZE (1 << 15) /* Bit 15: BLock SIZE. */ -#define USB_COUNT_RX_NUM_BLOCK_SHIFT (10) /* Bits 14-10: Number of blocks */ +#ifdef CONFIG_STM32_STM32G0 +# define USB_COUNT_RX_BL_SIZE (1 << 31) /* Bit 31: Block size */ +# define USB_COUNT_RX_NUM_BLOCK_SHIFT (26) /* Bits 30-26: Number of blocks */ +# define USB_COUNT_RX_SHIFT (16) /* Bits 25-16: Reception byte count */ +#else +# define USB_COUNT_RX_BL_SIZE (1 << 15) /* Bit 15: Block size */ +# define USB_COUNT_RX_NUM_BLOCK_SHIFT (10) /* Bits 14-10: Number of blocks */ +# define USB_COUNT_RX_SHIFT (0) /* Bits 9-0: Reception byte count */ +#endif #define USB_COUNT_RX_NUM_BLOCK_MASK (0x1f << USB_COUNT_RX_NUM_BLOCK_SHIFT) -#define USB_COUNT_RX_SHIFT (0) /* Bits 9-0: Reception Byte Count */ #define USB_COUNT_RX_MASK (0x03ff << USB_COUNT_RX_SHIFT) #endif /* CONFIG_STM32_HAVE_USBDEV */ diff --git a/arch/arm/src/common/stm32/stm32_pwr.h b/arch/arm/src/common/stm32/stm32_pwr.h index 9de201ed61e..4e41b05c465 100644 --- a/arch/arm/src/common/stm32/stm32_pwr.h +++ b/arch/arm/src/common/stm32/stm32_pwr.h @@ -216,6 +216,25 @@ void stm32_pwr_enablebreg(bool region); void stm32_pwr_setvos(uint16_t vos); #endif +/**************************************************************************** + * Name: stm32_pwr_enableusv + * + * Description: + * Declare the USB supply valid or not valid. The USB transceiver cannot + * be used on STM32G0 until the supply has been declared valid. + * + * Input Parameters: + * enable - True: USB supply is valid; False: USB supply is not valid. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32G0 +void stm32_pwr_enableusv(bool enable); +#endif + /**************************************************************************** * Name: stm32_pwr_setpvd * diff --git a/arch/arm/src/common/stm32/stm32_pwr_m0_g0.c b/arch/arm/src/common/stm32/stm32_pwr_m0_g0.c index d1627f7fa5f..7dbda38f4ac 100644 --- a/arch/arm/src/common/stm32/stm32_pwr_m0_g0.c +++ b/arch/arm/src/common/stm32/stm32_pwr_m0_g0.c @@ -34,6 +34,7 @@ #include #include "arm_internal.h" +#include "hardware/stm32_rcc.h" #include "stm32_pwr.h" #if defined(CONFIG_STM32_PWR) @@ -91,6 +92,51 @@ void stm32_pwr_setvos(uint16_t vos) } } +/**************************************************************************** + * Name: stm32_pwr_enableusv + * + * Description: + * Declare the USB supply valid or not valid. The USB transceiver cannot + * be used on STM32G0 until the supply has been declared valid. + * + * Input Parameters: + * enable - True: USB supply is valid; False: USB supply is not valid. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32G0 +void stm32_pwr_enableusv(bool enable) +{ + uint32_t regval; + bool wasenabled; + + regval = getreg32(STM32_RCC_APB1ENR); + wasenabled = (regval & RCC_APB1ENR_PWREN) != 0; + + if (!wasenabled) + { + modifyreg32(STM32_RCC_APB1ENR, 0, RCC_APB1ENR_PWREN); + } + + if (enable) + { + modifyreg32(STM32_PWR_CR2, 0, PWR_CR2_USV); + } + else + { + modifyreg32(STM32_PWR_CR2, PWR_CR2_USV, 0); + } + + if (!wasenabled) + { + modifyreg32(STM32_RCC_APB1ENR, RCC_APB1ENR_PWREN, 0); + } +} +#endif + /* TODO Other stm32_pwr_* functions need to be implemented */ #endif /* CONFIG_STM32_PWR */ diff --git a/arch/arm/src/common/stm32/stm32_usbdev_m0_v1.c b/arch/arm/src/common/stm32/stm32_usbdev_m0_v1.c index af2660767ab..d0bf8eae531 100644 --- a/arch/arm/src/common/stm32/stm32_usbdev_m0_v1.c +++ b/arch/arm/src/common/stm32/stm32_usbdev_m0_v1.c @@ -53,6 +53,7 @@ #include "hardware/stm32_rcc.h" #include "hardware/stm32_usbdev.h" #include "stm32_gpio.h" +#include "stm32_pwr.h" #include "stm32_usbdev.h" #if defined(CONFIG_USBDEV) && defined(CONFIG_STM32_USB) @@ -352,12 +353,17 @@ struct stm32_usbdev_s /* Register operations ******************************************************/ #ifdef CONFIG_STM32_USBDEV_REGDEBUG -static uint16_t stm32_getreg(uint32_t addr); -static void stm32_putreg(uint16_t val, uint32_t addr); +static uint32_t stm32_getreg(uint32_t addr); +static void stm32_putreg(uint32_t val, uint32_t addr); static void stm32_dumpep(int epno); #else -# define stm32_getreg(addr) getreg16(addr) -# define stm32_putreg(val,addr) putreg16(val,addr) +# ifdef CONFIG_STM32_STM32G0 +# define stm32_getreg(addr) getreg32(addr) +# define stm32_putreg(val,addr) putreg32(val,addr) +# else +# define stm32_getreg(addr) getreg16(addr) +# define stm32_putreg(val,addr) putreg16(val,addr) +# endif # define stm32_dumpep(epno) #endif @@ -600,15 +606,19 @@ const struct trace_msg_t g_usb_trace_strings_deverror[] = ****************************************************************************/ #ifdef CONFIG_STM32_USBDEV_REGDEBUG -static uint16_t stm32_getreg(uint32_t addr) +static uint32_t stm32_getreg(uint32_t addr) { static uint32_t prevaddr = 0; - static uint16_t preval = 0; + static uint32_t preval = 0; static uint32_t count = 0; /* Read the value from the register */ - uint16_t val = getreg16(addr); +#ifdef CONFIG_STM32_STM32G0 + uint32_t val = getreg32(addr); +#else + uint32_t val = getreg16(addr); +#endif /* Is this the same value that we read from the same register last time? * Are we polling the register? If so, suppress some of the output. @@ -658,7 +668,7 @@ static uint16_t stm32_getreg(uint32_t addr) ****************************************************************************/ #ifdef CONFIG_STM32_USBDEV_REGDEBUG -static void stm32_putreg(uint16_t val, uint32_t addr) +static void stm32_putreg(uint32_t val, uint32_t addr) { /* Show the register value being written */ @@ -666,7 +676,11 @@ static void stm32_putreg(uint16_t val, uint32_t addr) /* Write the value */ +#ifdef CONFIG_STM32_STM32G0 + putreg32(val, addr); +#else putreg16(val, addr); +#endif } #endif @@ -679,6 +693,27 @@ static void stm32_dumpep(int epno) { uint32_t addr; +#ifdef CONFIG_STM32_STM32G0 + uinfo("CNTR: %04" PRIx32 "\n", getreg32(STM32_USB_CNTR)); + uinfo("ISTR: %04" PRIx32 "\n", getreg32(STM32_USB_ISTR)); + uinfo("FNR: %04" PRIx32 "\n", getreg32(STM32_USB_FNR)); + uinfo("DADDR: %04" PRIx32 "\n", getreg32(STM32_USB_DADDR)); + + addr = STM32_USB_EPR(epno); + uinfo("EPR%d: [%08" PRIx32 "] %04" PRIx32 "\n", + epno, addr, getreg32(addr)); + + addr = STM32_USB_BTABLE_ADDR(epno, 0); + uinfo("DESC: %08" PRIx32 "\n", addr); + + addr = STM32_USB_TX(epno); + uinfo(" TX BUF: [%08" PRIx32 "] %08" PRIx32 "\n", + addr, getreg32(addr)); + + addr = STM32_USB_RX(epno); + uinfo(" RX BUF: [%08" PRIx32 "] %08" PRIx32 "\n", + addr, getreg32(addr)); +#else /* Common registers */ uinfo("CNTR: %04x\n", getreg16(STM32_USB_CNTR)); @@ -710,6 +745,7 @@ static void stm32_dumpep(int epno) addr = STM32_USB_COUNT_RX(epno); uinfo(" COUNT: [%08" PRIx32 "] %04x\n", addr, getreg16(addr)); +#endif } #endif @@ -723,8 +759,13 @@ static void stm32_dumpep(int epno) static inline void stm32_seteptxcount(uint8_t epno, uint16_t count) { +#ifdef CONFIG_STM32_STM32G0 + volatile uint32_t *epaddr = (uint32_t *)STM32_USB_TX(epno); + *epaddr = (*epaddr & 0x0000ffff) | ((uint32_t)count << 16); +#else volatile uint16_t *epaddr = (uint16_t *)STM32_USB_COUNT_TX(epno); *epaddr = count; +#endif } /**************************************************************************** @@ -733,8 +774,13 @@ static inline void stm32_seteptxcount(uint8_t epno, uint16_t count) static inline void stm32_seteptxaddr(uint8_t epno, uint16_t addr) { +#ifdef CONFIG_STM32_STM32G0 + volatile uint32_t *txaddr = (uint32_t *)STM32_USB_TX(epno); + *txaddr = (*txaddr & 0xffff0000) | addr; +#else volatile uint16_t *txaddr = (uint16_t *)STM32_USB_ADDR_TX(epno); *txaddr = addr; +#endif } /**************************************************************************** @@ -743,7 +789,11 @@ static inline void stm32_seteptxaddr(uint8_t epno, uint16_t addr) static inline uint16_t stm32_geteptxaddr(uint8_t epno) { +#ifdef CONFIG_STM32_STM32G0 + volatile uint32_t *txaddr = (uint32_t *)STM32_USB_TX(epno); +#else volatile uint16_t *txaddr = (uint16_t *)STM32_USB_ADDR_TX(epno); +#endif return (uint16_t)*txaddr; } @@ -753,7 +803,11 @@ static inline uint16_t stm32_geteptxaddr(uint8_t epno) static void stm32_seteprxcount(uint8_t epno, uint16_t count) { +#ifdef CONFIG_STM32_STM32G0 + volatile uint32_t *epaddr = (uint32_t *)STM32_USB_RX(epno); +#else volatile uint16_t *epaddr = (uint16_t *)STM32_USB_COUNT_RX(epno); +#endif uint32_t rxcount = 0; uint16_t nblocks; @@ -793,7 +847,11 @@ static void stm32_seteprxcount(uint8_t epno, uint16_t count) DEBUGASSERT(nblocks > 0 && nblocks < 0x1f); rxcount = (uint32_t)(nblocks << USB_COUNT_RX_NUM_BLOCK_SHIFT); } +#ifdef CONFIG_STM32_STM32G0 + *epaddr = (*epaddr & 0x0000ffff) | rxcount; +#else *epaddr = rxcount; +#endif } /**************************************************************************** @@ -802,8 +860,13 @@ static void stm32_seteprxcount(uint8_t epno, uint16_t count) static inline uint16_t stm32_geteprxcount(uint8_t epno) { +#ifdef CONFIG_STM32_STM32G0 + volatile uint32_t *epaddr = (uint32_t *)STM32_USB_RX(epno); + return (uint16_t)((*epaddr & USB_COUNT_RX_MASK) >> 16); +#else volatile uint16_t *epaddr = (uint16_t *)STM32_USB_COUNT_RX(epno); return (*epaddr) & USB_COUNT_RX_MASK; +#endif } /**************************************************************************** @@ -812,8 +875,13 @@ static inline uint16_t stm32_geteprxcount(uint8_t epno) static inline void stm32_seteprxaddr(uint8_t epno, uint16_t addr) { +#ifdef CONFIG_STM32_STM32G0 + volatile uint32_t *rxaddr = (uint32_t *)STM32_USB_RX(epno); + *rxaddr = (*rxaddr & 0xffff0000) | addr; +#else volatile uint16_t *rxaddr = (uint16_t *)STM32_USB_ADDR_RX(epno); *rxaddr = addr; +#endif } /**************************************************************************** @@ -822,7 +890,11 @@ static inline void stm32_seteprxaddr(uint8_t epno, uint16_t addr) static inline uint16_t stm32_geteprxaddr(uint8_t epno) { +#ifdef CONFIG_STM32_STM32G0 + volatile uint32_t *rxaddr = (uint32_t *)STM32_USB_RX(epno); +#else volatile uint16_t *rxaddr = (uint16_t *)STM32_USB_ADDR_RX(epno); +#endif return (uint16_t)*rxaddr; } @@ -1042,6 +1114,36 @@ static inline bool stm32_eprxstalled(uint8_t epno) static void stm32_copytopma(const uint8_t *buffer, uint16_t pma, uint16_t nbytes) { +#ifdef CONFIG_STM32_STM32G0 + volatile uint32_t *dest; + + dest = (uint32_t *)(STM32_USBRAM_BASE + (uint32_t)pma); + while (nbytes >= 4) + { + *dest++ = (uint32_t)buffer[0] | ((uint32_t)buffer[1] << 8) | + ((uint32_t)buffer[2] << 16) | + ((uint32_t)buffer[3] << 24); + buffer += 4; + nbytes -= 4; + } + + if (nbytes > 0) + { + uint32_t value = buffer[0]; + + if (nbytes > 1) + { + value |= (uint32_t)buffer[1] << 8; + } + + if (nbytes > 2) + { + value |= (uint32_t)buffer[2] << 16; + } + + *dest = value; + } +#else uint16_t *dest; uint16_t ms; uint16_t ls; @@ -1061,6 +1163,7 @@ static void stm32_copytopma(const uint8_t *buffer, dest++; } +#endif } /**************************************************************************** @@ -1070,6 +1173,25 @@ static void stm32_copytopma(const uint8_t *buffer, static inline void stm32_copyfrompma(uint8_t *buffer, uint16_t pma, uint16_t nbytes) { +#ifdef CONFIG_STM32_STM32G0 + volatile uint32_t *src; + + src = (uint32_t *)(STM32_USBRAM_BASE + (uint32_t)pma); + while (nbytes > 0) + { + uint32_t value = *src++; + uint16_t count = nbytes > 4 ? 4 : nbytes; + uint16_t i; + + for (i = 0; i < count; i++) + { + *buffer++ = (uint8_t)value; + value >>= 8; + } + + nbytes -= count; + } +#else uint16_t *src; int nwords = (nbytes + 1) >> 1; int i; @@ -1089,6 +1211,7 @@ stm32_copyfrompma(uint8_t *buffer, uint16_t pma, uint16_t nbytes) buffer += 2; } +#endif } /**************************************************************************** @@ -3531,7 +3654,9 @@ static void stm32_hwreset(struct stm32_usbdev_s *priv) /* Set the STM32 BTABLE address */ +#ifndef CONFIG_STM32_STM32G0 stm32_putreg(STM32_BTABLE_ADDRESS & 0xfff8, STM32_USB_BTABLE); +#endif /* Initialize EP0 */ @@ -3566,6 +3691,12 @@ static void stm32_hwsetup(struct stm32_usbdev_s *priv) { int epno; +#ifdef CONFIG_STM32_STM32G0 + /* Enable the STM32G0 USB transceiver supply. */ + + stm32_pwr_enableusv(true); +#endif + /* Power the USB controller, put the USB controller into reset, disable * all USB interrupts */ @@ -3662,6 +3793,12 @@ static void stm32_hwshutdown(struct stm32_usbdev_s *priv) /* Power down the USB controller */ stm32_putreg(USB_CNTR_FRES | USB_CNTR_PDWN, STM32_USB_CNTR); + +#ifdef CONFIG_STM32_STM32G0 + /* Disable the STM32G0 USB transceiver supply. */ + + stm32_pwr_enableusv(false); +#endif } /**************************************************************************** diff --git a/arch/arm/src/stm32g0/hardware/stm32g0_memorymap.h b/arch/arm/src/stm32g0/hardware/stm32g0_memorymap.h index c5455b4df97..144d7cc6f63 100644 --- a/arch/arm/src/stm32g0/hardware/stm32g0_memorymap.h +++ b/arch/arm/src/stm32g0/hardware/stm32g0_memorymap.h @@ -74,6 +74,7 @@ #define STM32_USART4_BASE 0x40004c00 /* 0x40004c00-0x40004fff USART4 */ #define STM32_I2C1_BASE 0x40005400 /* 0x40005400-0x400057ff I2C1 */ #define STM32_I2C2_BASE 0x40005800 /* 0x40005800-0x40005bff I2C2 */ +#define STM32_USB_BASE 0x40005c00 /* 0x40005c00-0x40005fff USB */ #define STM32_CRS_BASE 0x40006C00 /* 0x40006C00-0x40006fff CRS */ #define STM32_PWR_BASE 0x40007000 /* 0x40007000-0x400073ff PWR */ #define STM32_DAC1_BASE 0x40007400 /* 0x40007400-0x400077ff DAC 1 */ @@ -81,6 +82,8 @@ #define STM32_LPTIM1_BASE 0x40007C00 /* 0x40007c00-0x40007fff LPTIM1 */ #define STM32_LPUART1_BASE 0x40008000 /* 0x40008000-0x400083ff LPUART1 */ #define STM32_LPTIM2_BASE 0x40009400 /* 0x40009400-0x400097ff LPTIM2 */ +#define STM32_USBRAM_BASE 0x40009800 /* 0x40009800-0x40009bff USB RAM1 */ +#define STM32_USBRAM2_BASE 0x40009c00 /* 0x40009c00-0x40009fff USB RAM2 */ #define STM32_UCPD1_BASE 0x4000a000 /* 0x4000a000-0x4000a3ff UCPD1 */ #define STM32_UCPD2_BASE 0x4000a400 /* 0x4000a400-0x4000a7ff UCPD2 */ #define STM32_TAMP_BASE 0x4000b000 /* 0x4000b000-0x4000b3ff TAMP */ diff --git a/arch/arm/src/stm32g0/hardware/stm32g0_pinmap.h b/arch/arm/src/stm32g0/hardware/stm32g0_pinmap.h index 3cc3b5b0850..bbd5e79cedd 100644 --- a/arch/arm/src/stm32g0/hardware/stm32g0_pinmap.h +++ b/arch/arm/src/stm32g0/hardware/stm32g0_pinmap.h @@ -273,6 +273,11 @@ #define GPIO_USART4_TX_2 (GPIO_ALT | GPIO_PULLUP | GPIO_AF1 | GPIO_PUSHPULL | GPIO_PORTC | GPIO_PIN10) #define GPIO_USART4_RTS_1 (GPIO_ALT | GPIO_AF4 | GPIO_PORTA | GPIO_PIN15) +/* USB */ + +#define GPIO_USB_DM (GPIO_INPUT | GPIO_FLOAT | GPIO_PORTA | GPIO_PIN11) +#define GPIO_USB_DP (GPIO_INPUT | GPIO_FLOAT | GPIO_PORTA | GPIO_PIN12) + /* TODO: LPTIM */ /* TODO: LPUART */ diff --git a/arch/arm/src/stm32g0/hardware/stm32g0_pwr.h b/arch/arm/src/stm32g0/hardware/stm32g0_pwr.h index 2df357db170..0e6ec210a40 100644 --- a/arch/arm/src/stm32g0/hardware/stm32g0_pwr.h +++ b/arch/arm/src/stm32g0/hardware/stm32g0_pwr.h @@ -120,6 +120,7 @@ #define PWR_CR2_PVDFT_MASK (7 << PWR_CR2_PLS_SHIFT) #define PWR_CR2_PVDRT_SHIFT (4) /* Bits 4-6: Power voltage detector rising threshold selection */ #define PWR_CR2_PVDRT_MASK (7 << PWR_CR2_PLS_SHIFT) +#define PWR_CR2_USV (1 << 10) /* Bit 10: USB supply valid */ /* Power control register 3 */ diff --git a/arch/arm/src/stm32g0/hardware/stm32g0_rcc.h b/arch/arm/src/stm32g0/hardware/stm32g0_rcc.h index 3c5f8ca4521..003a2305754 100644 --- a/arch/arm/src/stm32g0/hardware/stm32g0_rcc.h +++ b/arch/arm/src/stm32g0/hardware/stm32g0_rcc.h @@ -220,7 +220,8 @@ /* Bits 2-3: Reserved */ #define RCC_APB1RSTR_TIM6RST (1 << 4) /* Bit 4: Timer 6 reset */ #define RCC_APB1RSTR_TIM7RST (1 << 5) /* Bit 5: Timer 7 reset */ - /* Bits 6-13: Reserved */ + /* Bits 6-12: Reserved */ +#define RCC_APB1RSTR_USBRST (1 << 13) /* Bit 13: USB reset */ #define RCC_APB1RSTR_SPI2RST (1 << 14) /* Bit 14: SPI 2 reset */ /* Bits 15-16: Reserved */ #define RCC_APB1RSTR_USART2RST (1 << 17) /* Bit 17: USART 2 reset */ @@ -284,9 +285,11 @@ /* Bits 2-3: Reserved */ #define RCC_APB1ENR_TIM6EN (1 << 4) /* Bit 4: Timer 6 enable */ #define RCC_APB1ENR_TIM7EN (1 << 5) /* Bit 5: Timer 7 enable */ - /* Bits 6-13: Reserved */ + /* Bits 6-12: Reserved */ +#define RCC_APB1ENR_USBEN (1 << 13) /* Bit 13: USB enable */ #define RCC_APB1ENR_SPI2EN (1 << 14) /* Bit 14: SPI 2 enable */ - /* Bits 15-16: Reserved */ + /* Bit 15: Reserved */ +#define RCC_APB1ENR_CRSEN (1 << 16) /* Bit 16: CRS enable */ #define RCC_APB1ENR_USART2EN (1 << 17) /* Bit 17: USART 2 enable */ #define RCC_APB1ENR_USART3EN (1 << 18) /* Bit 18: USART 3 enable */ #define RCC_APB1ENR_USART4EN (1 << 19) /* Bit 19: USART 4 enable */ diff --git a/arch/arm/src/stm32g0/stm32_rcc.c b/arch/arm/src/stm32g0/stm32_rcc.c index f2f084012f8..0e9733b9e38 100644 --- a/arch/arm/src/stm32g0/stm32_rcc.c +++ b/arch/arm/src/stm32g0/stm32_rcc.c @@ -54,6 +54,12 @@ # endif #endif +/* HSI48 is the only 48MHz clock source on STM32G0 */ + +#if defined(CONFIG_STM32_HAVE_HSI48) && defined(STM32_USE_CLK48) +# define STM32_USE_HSI48 +#endif + static_assert(CONFIG_BOARD_LOOPSPERMSEC != -1, "Configure BOARD_LOOPSPERMSEC to non-default value."); diff --git a/arch/arm/src/stm32g0/stm32g0_rcc.c b/arch/arm/src/stm32g0/stm32g0_rcc.c index b79a0224392..5a90665f868 100644 --- a/arch/arm/src/stm32g0/stm32g0_rcc.c +++ b/arch/arm/src/stm32g0/stm32g0_rcc.c @@ -205,6 +205,12 @@ static inline void rcc_enableapb1(void) regval |= RCC_APB1ENR_TIM7EN; #endif +#ifdef CONFIG_STM32_USB + /* USB clock enable */ + + regval |= RCC_APB1ENR_USBEN; +#endif + #ifdef CONFIG_STM32_SPI2 /* SPI 2 clock enable */ @@ -241,6 +247,12 @@ static inline void rcc_enableapb1(void) regval |= RCC_APB1ENR_I2C1EN; #endif +#if defined(CONFIG_STM32_CRS) || defined(STM32_USE_HSI48) + /* Clock recovery system clock enable */ + + regval |= RCC_APB1ENR_CRSEN; +#endif + #ifdef CONFIG_STM32_I2C2 /* I2C 2 clock enable */ @@ -674,6 +686,12 @@ static inline void rcc_enableperipherals(void) rcc_enableahb(); rcc_enableapb2(); rcc_enableapb1(); + +#ifdef STM32_USE_HSI48 + /* Enable HSI48 clocking to support USB transfers or RNG */ + + stm32_enable_hsi48(STM32_HSI48_SYNCSRC); +#endif } /****************************************************************************