Pārlūkot izejas kodu

add: add STM32F303D/E support

Dmitry 8 gadi atpakaļ
vecāks
revīzija
8a7b06f004
9 mainītis faili ar 311 papildinājumiem un 75 dzēšanām
  1. 8 2
      Makefile
  2. 13 0
      demo/cdc_startup.c
  3. 88 0
      demo/stm32f303xe.ld
  4. 2 2
      inc/usb.h
  5. 1 1
      readme.md
  6. 26 2
      src/memmap.inc
  7. 0 1
      src/usb_32v1.c
  8. 86 31
      src/usb_32v3.c
  9. 87 36
      src/usb_32v3A.S

+ 8 - 2
Makefile

@@ -111,9 +111,15 @@ $(OBJDIR)/%.o: %.s
 stm32f103x6 bluepill:
 	@$(MAKE) clean demo STARTUP='$(CMSISDEV)/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103x6.s' \
 						LDSCRIPT='demo/stm32f103x6.ld' \
-						DEFINES='STM32F1 STM32F103x6 USBD_SOF_DISABLED USBD_ASM_DRIVER' \
+						DEFINES='STM32F1 STM32F103x6 USBD_SOF_DISABLED' \
 						CFLAGS='-mcpu=cortex-m3 -mthumb'
 
+stm32f303xe 32f303re-nucleo:
+	@$(MAKE) clean demo STARTUP='$(CMSISDEV)/ST/STM32F3xx/Source/Templates/gcc/startup_stm32f303xe.s' \
+						LDSCRIPT='demo/stm32f303xe.ld' \
+						DEFINES='STM32F3 STM32F303xE USBD_SOF_DISABLED' \
+						CFLAGS='-mcpu=cortex-m4 -mthumb'
+
 stm32l052x8:
 	@$(MAKE) clean demo STARTUP='$(CMSISDEV)/ST/STM32L0xx/Source/Templates/gcc/startup_stm32l052xx.s' \
 						LDSCRIPT='demo/stm32l052x8.ld' \
@@ -130,4 +136,4 @@ stm32l476xg 32l476rg-nucleo:
 	@$(MAKE) clean demo STARTUP='$(CMSISDEV)/ST/STM32L4xx/Source/Templates/gcc/startup_stm32l476xx.s' \
 						LDSCRIPT='demo/stm32l476xg.ld' \
 						DEFINES='STM32L4 STM32L476xx USBD_SOF_DISABLED' \
-						CFLAGS='-mcpu=cortex-m4 -mthumb'
+						CFLAGS='-mcpu=cortex-m4 -mthumb'

+ 13 - 0
demo/cdc_startup.c

@@ -78,6 +78,19 @@ static void cdc_init_rcc (void) {
     /* switch to PLL */
     _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
     _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
+
+#elif defined(STM32F303xE)
+    /* set flash latency 1WS */
+    _BMD(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_1);
+    /* use PLL 48MHz clock from 8Mhz HSI */
+    _BMD(RCC->CFGR,
+         RCC_CFGR_PLLMUL | RCC_CFGR_PLLSRC | RCC_CFGR_USBPRE ,
+         RCC_CFGR_PLLMUL12 | RCC_CFGR_USBPRE);
+    _BST(RCC->CR, RCC_CR_PLLON);
+    _WBS(RCC->CR, RCC_CR_PLLRDY);
+    /* switch to PLL */
+    _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
+    _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
 #else
     #error Not supported
 #endif

+ 88 - 0
demo/stm32f303xe.ld

@@ -0,0 +1,88 @@
+ENTRY(Reset_Handler)
+MEMORY
+{
+    ROM     (rx): ORIGIN = 0x08000000, LENGTH = 512K
+    RAM    (rwx): ORIGIN = 0x20000000, LENGTH = 64K
+    CCMRAM (rwx): ORIGIN = 0x10000000, LENGTH = 16K
+}
+SECTIONS
+{
+    .text :
+    {
+        KEEP(*(.isr_vector))
+        *(.text*)
+        KEEP(*(.init))  KEEP(*(.fini))
+        *crtbegin.o(.ctors)
+        *crtbegin?.o(.ctors)
+        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+        *(SORT(.ctors.*))
+        *(.ctors)
+        *crtbegin.o(.dtors)
+        *crtbegin?.o(.dtors)
+        *(EXCLUDE_FILE(*crtend?.o *crtend.o).dtors)
+        *(SORT(.dtors.*))
+        *(.dtors)
+        *(.rodata*)
+        KEEP(*(.eh_frame*))
+    } > ROM
+    .ARM.extab :
+    {
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+    } > ROM
+    __exidx_start = .;
+    .ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    } > ROM
+    __exidx_end = .;
+    __etext = .;
+    .data : AT (__etext)
+    {
+        __data_start__ = .;
+        *(vtable)
+        *(.data*)
+        . = ALIGN(4);
+        PROVIDE_HIDDEN (__preinit_array_start = .);
+        KEEP(*(.preinit_array))
+        PROVIDE_HIDDEN (__preinit_array_end = .);
+        . = ALIGN(4);
+        PROVIDE_HIDDEN (__init_array_start = .);
+        KEEP(*(SORT(.init_array.*)))
+        KEEP(*(.init_array))
+        PROVIDE_HIDDEN (__init_array_end = .);
+        . = ALIGN(4);
+        PROVIDE_HIDDEN (__fini_array_start = .);
+        KEEP(*(SORT(.fini_array.*)))
+        KEEP(*(.fini_array))
+        PROVIDE_HIDDEN (__fini_array_end = .);
+        . = ALIGN(4);
+        __data_end__ = .;
+    } > RAM
+    .bss (NOLOAD) :
+    {
+        __bss_start__ = .;
+        *(.bss*)
+        *(COMMON)
+        __bss_end__ = .;
+    } > RAM
+    .heap (NOLOAD) :
+    {
+        __end__ = .;
+        *(.heap*)
+        __HeapLimit = .;
+    } > RAM
+    .stack_dummy (NOLOAD) :
+    {
+        *(.stack)
+    } > RAM
+    __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+    __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+    PROVIDE(__stack = __StackTop);
+    ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
+    PROVIDE(_estack = __stack);
+    PROVIDE(_sidata = __etext);
+    PROVIDE(_sdata = __data_start__);
+    PROVIDE(_edata = __data_end__);
+    PROVIDE(_sbss = __bss_start__);
+    PROVIDE(_ebss = __bss_end__);
+}

+ 2 - 2
inc/usb.h

@@ -45,13 +45,13 @@
       defined(STM32F303xC) || defined(STM32F303xE) || \
       defined(STM32F373xC)
 
-      #define USE_STMV3_DRIVER
+    #define USE_STMV3_DRIVER
 
 #else
     #error Unsupported STM32 family
 #endif
 
-
+#include <stdbool.h>
 #include "usbd_core.h"
 #if !defined(__ASSEMBLER__)
     #include "usb_std.h"

+ 1 - 1
readme.md

@@ -30,7 +30,7 @@
 
 2. At this moment BULK IN endpoint can use both buffers, but it is not **real** doublebuffered.
 
-3. Tested with STM32L052, STM31L100, STM32L476RG, STM32F103CB, STM32F303CC
+3. Tested with STM32L052, STM31L100, STM32L476RG, STM32F103CB, STM32F303CC, STM32F303RE
 
 ### Implemented definitions for classes ###
 1. USB HID based on [Device Class Definition for Human Interface Devices (HID) Version 1.11](http://www.usb.org/developers/hidpage/HID1_11.pdf)

+ 26 - 2
src/memmap.inc

@@ -73,8 +73,16 @@
     #define USB_BTABLE      0x10
     #define USB_PMABASE     0x40006000
     #define RCC_BASE        0x40021000
-    #define RCC_APB1ENR     0x1C
     #define RCC_APB1RSTR    0x10
+    #define RCC_APB2ENR     0x18
+    #define RCC_APB1ENR     0x1C
+    #define RCC_GPIOAEN     0x02
+    #define RCC_GPIOBEN     0x03
+    #define RCC_GPIOCEN     0x04
+    #define RCC_GPIODEN     0x05
+    #define RCC_GPIOEEN     0x06
+    #define RCC_GPIOFEN     0x07
+
     #define UID_BASE        0x1FFFF7E8
     #define GPIOA           0x40010800
     #define GPIOB           0x40010C00
@@ -86,7 +94,10 @@
     #define GPIO_CRL        0x00
     #define GPIO_CRH        0x04
     #define GPIO_BSRR       0x10
-#elif defined(STM32F303xB) || defined(STM32F303xC)
+
+
+#elif defined(STM32F303x8) || defined(STM32F303xC) || \
+      defined(STM32F303xE)
 
     #define USB_EPBASE      0x40005C00
     #define USB_REGBASE     0x40005C40
@@ -100,6 +111,16 @@
     #define RCC_BASE        0x40021000
     #define RCC_APB1ENR     0x1C
     #define RCC_APB1RSTR    0x10
+    #define RCC_AHBENR      0x14
+    #define RCC_GPIOAEN     0x11
+    #define RCC_GPIOBEN     0x12
+    #define RCC_GPIOCEN     0x13
+    #define RCC_GPIODEN     0x14
+    #define RCC_GPIOEEN     0x15
+    #define RCC_GPIOFEN     0x16
+    #define RCC_GPIOGEN     0x17
+    #define RCC_GPIOHEN     0x10
+
     #define UID_BASE        0x1FFFF7AC
 
     #define GPIOA           0x48000000
@@ -108,6 +129,9 @@
     #define GPIOD           0x48000C00
     #define GPIOE           0x48001000
     #define GPIOF           0x48001400
+    #define GPIO_MODER      0x00
+    #define GPIO_BSRR       0x18
+
 #else
     #error Unsupported MCU
 #endif

+ 0 - 1
src/usb_32v1.c

@@ -67,7 +67,6 @@ typedef union pma_table {
  */
 inline static pma_table *EPT(uint8_t ep) {
     return (pma_table*)((ep & 0x07) * 16 + USB_PMAADDR);
-
 }
 
 /** \brief Helper function. Returns pointer to the endpoint control register.

+ 86 - 31
src/usb_32v3.c

@@ -21,20 +21,9 @@
 
 #if defined(USE_STMV3_DRIVER)
 
-#ifndef USB_PMASIZE
-    #warning PMA memory size is not defined. Use 512 bytes by default
-    #define USB_PMASIZE 0x200
-#endif
-
 #define USB_EP_SWBUF_TX     USB_EP_DTOG_RX
 #define USB_EP_SWBUF_RX     USB_EP_DTOG_TX
 
-#ifndef UID_BASE
-    #if defined(STM32F303xC) || defined(STM32F303xE)
-        #define UID_BASE 0x1FFFF7AC
-    #endif
-#endif
-
 #define EP_TOGGLE_SET(epr, bits, mask) *(epr) = (*(epr) ^ (bits)) & (USB_EPREG_MASK | (mask))
 
 #define EP_TX_STALL(epr)    EP_TOGGLE_SET((epr), USB_EP_TX_STALL,                   USB_EPTX_STAT)
@@ -46,14 +35,52 @@
 #define EP_TX_VALID(epr)    EP_TOGGLE_SET((epr), USB_EP_TX_VALID,                   USB_EPTX_STAT)
 #define EP_RX_VALID(epr)    EP_TOGGLE_SET((epr), USB_EP_RX_VALID,                   USB_EPRX_STAT)
 
-typedef struct {
-    uint16_t    addr;
-    uint16_t    :16;
-    uint16_t    cnt;
-    uint16_t    :16;
-} pma_rec;
+typedef union _pma_table pma_table;
+
+#if defined(STM32F302x8) || defined(STM32F302xE) || defined(STM32F303xE)
+    #if !defined(USB_PMASIZE)
+    #warning PMA memory size is not defined. Use 768 bytes by default
+    #define USB_PMASIZE 0x300
+    #endif
+    #define PMA_STEP    1
+
+    typedef struct {
+        uint16_t    addr;
+        uint16_t    cnt;
+    } pma_rec;
+
+    inline static pma_table *EPT(uint8_t ep) {
+        return (pma_table*)((ep & 0x07) * 8 + USB_PMAADDR);
+    }
+
+    inline static uint16_t *PMA(uint16_t addr) {
+        return (uint16_t*)(USB_PMAADDR + addr);
+    }
+
+#else
+    #if !defined(USB_PMASIZE)
+    #warning PMA memory size is not defined. Use 512 bytes by default
+    #define USB_PMASIZE 0x200
+    #endif
+    #define PMA_STEP    2
 
-typedef union pma_table {
+    typedef struct {
+        uint16_t    addr;
+        uint16_t    :16;
+        uint16_t    cnt;
+        uint16_t    :16;
+    } pma_rec;
+
+    inline static pma_table *EPT(uint8_t ep) {
+        return (pma_table*)((ep & 0x07) * 16 + USB_PMAADDR);
+    }
+
+    inline static uint16_t *PMA(uint16_t addr) {
+        return (uint16_t*)(USB_PMAADDR + 2 * addr);
+    }
+#endif
+
+union _pma_table {
     struct {
     pma_rec     tx;
     pma_rec     rx;
@@ -66,14 +93,43 @@ typedef union pma_table {
     pma_rec     rx0;
     pma_rec     rx1;
     };
-} pma_table;
-
+};
 
-/** \brief Helper function. Returns pointer to the buffer descriptor table.
+/** \brief Helper function. Enables GPIOx for DP.
+ * Looks ugly. But compiler should optimize this
+ * to single line
  */
-inline static pma_table *EPT(uint8_t ep) {
-    return (pma_table*)((ep & 0x07) * 16 + USB_PMAADDR);
-
+inline static void set_gpiox() {
+#if defined(STM32F1) && defined(USBD_DP_PORT)
+    if (USBD_DP_PORT == GPIOA) {RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; return;}
+    if (USBD_DP_PORT == GPIOB) {RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; return;}
+    if (USBD_DP_PORT == GPIOC) {RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; return;}
+    if (USBD_DP_PORT == GPIOD) {RCC->APB2ENR |= RCC_APB2ENR_IOPDEN; return;}
+    #if defined(GPIOE)
+    if (USBD_DP_PORT == GPIOE) {RCC->APB2ENR |= RCC_APB2ENR_IOPEEN; return;}
+    #endif
+    #if defined(GPIOF)
+    if (USBD_DP_PORT = GPIOF) {RCC->APB2ENR |= RCC_APB2ENR_IOPFEN; return;}
+    #endif
+#elif defined(STM32F3) && defined(USBD_DP_PORT)
+    if (USBD_DP_PORT == GPIOA) {RCC->AHBENR |= RCC_AHBENR_GPIOAEN; return;}
+    if (USBD_DP_PORT == GPIOB) {RCC->AHBENR |= RCC_AHBENR_GPIOBEN; return;}
+    if (USBD_DP_PORT == GPIOC) {RCC->AHBENR |= RCC_AHBENR_GPIOCEN; return;}
+    if (USBD_DP_PORT == GPIOD) {RCC->AHBENR |= RCC_AHBENR_GPIODEN; return;}
+    #if defined(GPIOE)
+    if (USBD_DP_PORT == GPIOE) {RCC->AHBENR |= RCC_AHBENR_GPIOEEN; return;}
+    #endif
+    #if defined(GPIOF)
+    if (USBD_DP_PORT == GPIOF) {RCC->AHBENR |= RCC_AHBENR_GPIOFEN; return;}
+    #endif
+    #if defined(GPIOG)
+    if (USBD_DP_PORT == GPIOG) {RCC->AHBENR |= RCC_AHBENR_GPIOGEN; return;}
+    #endif
+    #if defined(GPIOH)
+    if (USBD_DP_PORT == GPIOH) {RCC->AHBENR |= RCC_AHBENR_GPIOHEN; return;}
+    #endif
+#endif
+    return;
 }
 
 /** \brief Helper function. Returns pointer to the endpoint control register.
@@ -82,7 +138,6 @@ inline static volatile uint16_t *EPR(uint8_t ep) {
     return (uint16_t*)((ep & 0x07) * 4 + USB_BASE);
 }
 
-
 /** \brief Helper function. Returns next available PMA buffer.
  *
  * \param sz uint16_t Requested buffer size.
@@ -187,6 +242,7 @@ uint8_t connect(bool connect) {
 
 void enable(bool enable) {
     if (enable) {
+        set_gpiox();
         RCC->APB1ENR  |= RCC_APB1ENR_USBEN;
         RCC->APB1RSTR |= RCC_APB1RSTR_USBRST;
         RCC->APB1RSTR &= ~RCC_APB1RSTR_USBRST;
@@ -207,7 +263,6 @@ void setaddr (uint8_t addr) {
     USB->DADDR = USB_DADDR_EF | addr;
 }
 
-
 bool ep_config(uint8_t ep, uint8_t eptype, uint16_t epsize) {
     volatile uint16_t *reg = EPR(ep);
     pma_table *tbl = EPT(ep);
@@ -291,7 +346,7 @@ void ep_deconfig(uint8_t ep) {
 }
 
 static uint16_t pma_read (uint8_t *buf, uint16_t blen, pma_rec *rx) {
-    uint16_t *pma = (void*)(USB_PMAADDR + 2 * rx->addr);
+    uint16_t *pma = PMA(rx->addr);
     uint16_t rxcnt = rx->cnt & 0x03FF;
     rx->cnt &= ~0x3FF;
     if (blen > rxcnt) {
@@ -303,7 +358,7 @@ static uint16_t pma_read (uint8_t *buf, uint16_t blen, pma_rec *rx) {
         *buf++ = _t & 0xFF;
         if (--blen) {
             *buf++ = _t >> 8;
-            pma += 2;
+            pma += PMA_STEP;
             blen--;
         } else break;
     }
@@ -353,11 +408,11 @@ int32_t ep_read(uint8_t ep, void *buf, uint16_t blen) {
 }
 
 static void pma_write(const uint8_t *buf, uint16_t blen, pma_rec *tx) {
-    uint16_t *pma = (void*)(USB_PMAADDR + 2 * (tx->addr));
+    uint16_t *pma = PMA(tx->addr);
     tx->cnt = blen;
     while (blen > 1) {
         *pma = buf[1] << 8 | buf[0];
-        pma += 2;
+        pma += PMA_STEP;
         buf += 2;
         blen -= 2;
     }
@@ -490,4 +545,4 @@ const struct usbd_driver usb_stmv3 = {
     get_serialno_desc,
 };
 
-#endif //USE_STM32V1_DRIVER
+#endif //USE_STM32V3_DRIVER

+ 87 - 36
src/usb_32v3A.S

@@ -46,22 +46,52 @@
 #define EP_TX_NAK   0x0020
 #define EP_TX_VAL   0x0030
 
-#define RXADDR0     0x00
-#define RXCOUNT0    0x04
-#define RXADDR1     0x08
-#define RXCOUNT1    0x0C
+#if defined(STM32F302x8) || defined(STM32F302xE) || defined(STM32F303xE)
+    #define RXADDR0     0x00
+    #define RXCOUNT0    0x02
+    #define RXADDR1     0x04
+    #define RXCOUNT1    0x06
+    #define USB_PMASZ   0x300
+    #define USB_PMASTP  0x02
+
+    .macro GetEPT
+    add     r4, r4, r0, LSR #25     //*EPT -> R4
+    .endm
+
+    .macro GetPMA
+    ldr     r4, =#USB_PMABASE
+    adds    r5, r4          // PMA BUFFER -> R5
+    .endm
 
-#define TXADDR0     0x00
-#define TXCOUNT0    0x04
-#define TXADDR1     0x08
-#define TXCOUNT1    0x0C
+#else
+    #define RXADDR0     0x00
+    #define RXCOUNT0    0x04
+    #define RXADDR1     0x08
+    #define RXCOUNT1    0x0C
+    #define USB_PMASZ   0x200
+    #define USB_PMASTP  0x04
+
+    .macro GetEPT
+    add     r4, r4, r0, LSR #24     //*EPT -> R4
+    .endm
 
-#define TXADDR      0x00
-#define TXCOUNT     0x04
-#define RXADDR      0x08
-#define RXCOUNT     0x0C
+    .macro GetPMA
+    ldr     r4, =#USB_PMABASE
+    lsls    r5, #1
+    adds    r5, r4          // PMA BUFFER -> R5
+    .endm
+
+#endif
 
+#define TXADDR0     RXADDR0
+#define TXCOUNT0    RXCOUNT0
+#define TXADDR1     RXADDR1
+#define TXCOUNT1    RXCOUNT1
 
+#define TXADDR      RXADDR0
+#define TXCOUNT     RXCOUNT0
+#define RXADDR      RXADDR1
+#define RXCOUNT     RXCOUNT1
 
 #define EP_NOTOG    (EP_RX_CTR | EP_TX_CTR | EP_SETUP | EP_TYPE | EP_KIND | EP_ADDR)
 
@@ -75,6 +105,28 @@
 #define DRX_USTALL  TGL_SET(EP_RX_STAT | EP_RX_DTOG | EP_RX_SWBUF, EP_RX_VAL | EP_RX_SWBUF)
 
 
+#if (USBD_DP_PORT == GPIOA)
+    #define RCC_GPIOxEN RCC_GPIOAEN
+#elif (USBD_DP_PORT == GPIOB)
+    #define RCC_GPIOxEN RCC_GPIOBEN
+#elif (USBD_DP_PORT == GPIOC)
+    #define RCC_GPIOxEN RCC_GPIOCEN
+#elif (USBD_DP_PORT == GPIOD)
+    #define RCC_GPIOxEN RCC_GPIODEN
+#elif (USBD_DP_PORT == GPIOE)
+    #define RCC_GPIOxEN RCC_GPIOEEN
+#elif (USBD_DP_PORT == GPIOF)
+    #define RCC_GPIOxEN RCC_GPIOFEN
+#elif (USBD_DP_PORT == GPIOG)
+    #define RCC_GPIOxEN RCC_GPIOGEN
+#elif (USBD_DP_PORT == GPIOH)
+    #define RCC_GPIOxEN RCC_GPIOHEN
+#else
+    #warning "No USB DP control used for F303"
+    #undef USBD_DP_PORT
+    #undef USBD_DP_PIN
+#endif
+
     .syntax unified
     .cpu cortex-m3
     .text
@@ -180,7 +232,7 @@ _connect:
     lsls    r1, #USBD_DP_PIN
     str     r1, [r3, #GPIO_BSRR]
     movs    r1, #0x02
-.L_store:    
+.L_store:
     orrs    r2, r2, r1, LSL #DP_PIN
     str     r2, [r3, #GPIO_CRx]
 #elif defined(USBD_DP_PORT) && defined(USBD_DP_PIN) && defined(STM32F3)
@@ -200,7 +252,6 @@ _connect:
     bx      lr
     .size   _connect, . - _connect
 
-
     .thumb_func
     .type   _setaddr, %function
 _setaddr:
@@ -237,11 +288,23 @@ _get_frame:
     .type   _enable, %function
 _enable:
     ldr     r2, =#RCC_BASE        //RCC
-    movs    r3, #0x01
-    lsls    r3, #23             //USBEN or USBRST
+    movs    r1, #0x01
+    lsls    r3, r1, #23           //USBEN or USBRST
     cbz     r0, .L_disable
 .L_enable:
 /* enabling and resetting USB peripheral */
+/* enabling DP control GPIO port */
+#if defined(USBD_DP_PORT) && defined(USBD_DP_PIN) && defined(STM32F3)
+    lsls    r1, #RCC_GPIOxEN
+    ldr     r0, [r2, #RCC_AHBENR]
+    orrs    r0, r1
+    str     r0, [r2, #RCC_AHBENR]
+#elif defined(USBD_DP_PORT) && defined(USBD_DP_PIN)
+    lsls    r1, #RCC_GPIOxEN
+    ldr     r0, [r2, #RCC_APB2ENR]
+    orrs    r0, r1
+    str     r0, [r2, #RCC_APB2ENR]
+#endif
     ldr     r1, =#USB_REGBASE
     ldr     r0, [r2, #RCC_APB1ENR]
     orrs    r0, r3
@@ -367,7 +430,7 @@ _ep_read:
     ldr     r4, =#USB_PMABASE
     lsls    r0, #28
     add     r3, r3, r0, LSR #26     //*EPR -> R3
-    add     r4, r4, r0, LSR #24     //*EPT -> R4
+    GetEPT                          //*EPT -> R4
     ldrh    r5, [r3]                // reading epr
 /* validating endpoint */
     movs    r0, #0x37
@@ -387,8 +450,6 @@ _ep_read:
     b       .L_epr_exit
 /* processing */
 .L_epr_dbl:
-//    lsrs    r0, r5, #8
-//    eors    r0, r5
     eors    r0, r5, r5, LSR #8
     lsrs    r0, #7          // SW_RX ^ DTOG_RX -> CF
     bcs     .L_epr_notog    // jmp if SW_RX != DTOG_RX (VALID)
@@ -411,9 +472,7 @@ _ep_read:
     lsls    r0, #22
     lsrs    r0, #22         // r0 &= 0x3FF (RX count)
     ldrh    r5, [r4, #RXADDR]
-    ldr     r4, =#USB_PMABASE
-    lsls    r5, #0x01
-    adds    r5, r4          // R5 now has a physical address
+    GetPMA
     cmp     r2, r0
     blo     .L_epr_read
     mov     r2, r0          // if buffer is larger
@@ -426,7 +485,7 @@ _ep_read:
     lsrs    r4, #8
     strb    r4, [r1, #1]
     adds    r1, #2
-    adds    r5, #4
+    adds    r5, #USB_PMASTP
     subs    r2, #2
     bhi     .L_epr_read
 .L_epr_read_end:
@@ -460,7 +519,7 @@ _ep_write:
     ldr     r4, =#USB_PMABASE
     lsls    r0, #28
     add     r3, r3, r0, LSR #26     //*EPR -> R3
-    add     r4, r4, r0, LSR #24     //*EPT -> R4    
+    GetEPT
     ldrh    r5, [r3]        // reading epr
     movs    r0, #0x73
     and     r0, r0, r5, LSR #4
@@ -488,9 +547,7 @@ _ep_write:
     strh    r2, [r4, #TXCOUNT]
     mov     r0, r2          // save count for return
     ldrh    r5, [r4, #TXADDR]
-    ldr     r4, =#USB_PMABASE
-    lsls    r5, #1
-    adds    r5, r4          // PMA BUFFER -> R5
+    GetPMA
 .L_epw_write:
     cmp     r2, #1
     blo     .L_epw_write_end
@@ -501,7 +558,7 @@ _ep_write:
     orrs    r4, r6
 .L_epw_store:
     strh    r4, [r5]
-    adds    r5, #4
+    adds    r5, #USB_PMASTP
     adds    r1, #2
     subs    r2, #2
     bhi     .L_epw_write
@@ -518,8 +575,6 @@ _ep_write:
     bics    r5, r2          // clear TX_SWBUF
 .L_epw_setstate:
     eors    r5, r2
-//    lsrs    r2, #16
-//    ands    r5, r2
     and     r5, r5, r2, LSR #16
     strh    r5, [r3]
 .L_epw_exit:
@@ -535,8 +590,7 @@ _ep_write:
 _get_next_pma:
     push    {r1, r3, r4, lr}
     movs    r1, #16
-    movs    r3, #1
-    lsls    r3, #9          //R3 MAX_PMA_SIZE 512b
+    ldr     r3, =#USB_PMASZ
     ldr     r0, =#USB_PMABASE
 .L_gnp_chkaddr:
     ldrh    r4, [r0, #0]    //txaddr
@@ -749,9 +803,6 @@ _evt_poll:
 .L_ep_ctrm:
     movs    r5, #0x80           // CTR_TX mask to R5
     ldr     r0,=#USB_EPBASE
-//    lsrs    r0, #2
-//    adds    r0, r2
-//    lsls    r0, #2              // R0 ep register address
     add     r0, r0, r2, LSL #2  // R0 ep register address
     ldrh    r4, [r0]            // R4 EPR valur
     lsrs    r3, r4, #8          // CTR_TX -> CF
@@ -817,7 +868,7 @@ _evt_poll:
     strh    r4, [r0, #RXADDR]
     strh    r4, [r0, #RXCOUNT]
     adds    r2, #0x04
-    adds    r0, #0x10
+    adds    r0, #(0x04 * USB_PMASTP)
     subs    r1, #1
     bpl     .L_ep_reset_loop
     movs    r2, #0x00