Parcourir la source

Merge pull request #1270 from kasjer/kasjer/pic32mz

Driver for Microchip PIC32MZ family
Ha Thach il y a 4 ans
Parent
commit
976405dea3

+ 5 - 0
hw/bsp/pic32mz/boards/olimex_emz64/board.mk

@@ -0,0 +1,5 @@
+JLINK_DEVICE=PIC32MZ2048EFH064
+JLINK_IF=ICSP
+
+CFLAGS += \
+  -mprocessor=32MZ2048EFH064 \

+ 144 - 0
hw/bsp/pic32mz/boards/olimex_emz64/olimex_emz64.c

@@ -0,0 +1,144 @@
+/* 
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2022 Jerzy Kasenberg
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <xc.h>
+#include "tusb.h"
+
+/* JTAG on, WDT off */
+#pragma config FDMTEN=0, FSOSCEN=0, DMTCNT=1
+#pragma config DEBUG=ON
+#pragma config JTAGEN=ON
+#pragma config FSLEEP=OFF
+#pragma config TRCEN=OFF
+#pragma config ICESEL=ICS_PGx2
+
+#pragma config POSCMOD = EC
+#pragma config FNOSC = SPLL
+/* 24MHz posc input to pll, div by 3, multiply by 50, div by 2 -> 200mhz*/
+#pragma config FPLLICLK=0, FPLLIDIV=DIV_3, FPLLRNG=RANGE_5_10_MHZ, FPLLMULT=MUL_50, FPLLODIV=DIV_2
+#pragma config FUSBIDIO=1
+#pragma config WINDIS=NORMAL
+#pragma config WDTSPGM=1
+#pragma config WDTPS=15
+#pragma config FWDTEN=OFF
+
+void button_init(void)
+{
+  // RB12 - button
+  // ANSELB B12 not analog
+  ANSELBCLR = TU_BIT(12);
+  // TRISB B12 input
+  TRISBSET = TU_BIT(12);
+  // Pull-up
+  CNPUBSET = TU_BIT(12);
+}
+
+void led_init(void)
+{
+  // RB8 - LED
+  // ANASELB RB8 not analog
+  ANSELBCLR = TU_BIT(8);
+  // TRISH RH2 input
+  TRISBCLR = TU_BIT(8);
+  // Initial value 0, LED off
+  LATBCLR = TU_BIT(8);
+}
+
+void uart_init(void)
+{
+  // RD4/RD0 Uart4 TX/RX
+  // ANSELD - not present on 64 pin device
+
+  /* Unlock system for PPS configuration */
+  SYSKEY = 0x00000000;
+  SYSKEY = 0xAA996655;
+  SYSKEY = 0x556699AA;
+  CFGCONbits.IOLOCK = 0;
+
+  // PPS Input Remapping
+  // U4RX -> RD0
+  U4RXR = 3;
+
+  // PPS Output Remapping
+  // RD4 -> U4TX
+  RPD4R = 2;
+
+  // Lock back the system after PPS configuration
+  CFGCONbits.IOLOCK = 1;
+  SYSKEY = 0x00000000;
+
+  // UART4
+  // High speed mode
+  // 8 bits, no parity, no RTS/CTS, no flow control
+  U4MODE = 0x0;
+
+  // Enable UART2 Receiver and Transmitter
+  U4STASET = (_U4STA_UTXEN_MASK | _U4STA_URXEN_MASK | _U4STA_UTXISEL1_MASK);
+
+  // BAUD Rate register Setup
+  U4BRG = 100000000 / (16 * 115200) + 1;
+
+  // Disable Interrupts
+  IEC4CLR = _IEC5_U4EIE_MASK | _IEC5_U4RXIE_MASK | _IEC5_U4TXIE_MASK;
+
+  // Turn ON UART2
+  U4MODESET = _U4MODE_ON_MASK;
+}
+
+//--------------------------------------------------------------------+
+// Board porting API
+//--------------------------------------------------------------------+
+
+void board_led_write(bool state)
+{
+  if (state)
+  {
+    LATBSET = TU_BIT(8);
+  }
+  else
+  {
+    LATBCLR = TU_BIT(8);
+  }
+}
+
+uint32_t board_button_read(void)
+{
+  return (PORTB >> 12) & 1;
+}
+
+int board_uart_write(void const * buf, int len)
+{
+  int i = len;
+  uint8_t const * data = buf;
+  while (i--)
+  {
+    while (U4STAbits.UTXBF) ;
+    U4TXREG = *data++;
+  }
+  return len;
+}

+ 5 - 0
hw/bsp/pic32mz/boards/olimex_hmz144/board.mk

@@ -0,0 +1,5 @@
+JLINK_DEVICE=PIC32MZ2048EFM144
+JLINK_IF=ICSP
+
+CFLAGS += \
+  -mprocessor=32MZ2048EFM144 \

+ 142 - 0
hw/bsp/pic32mz/boards/olimex_hmz144/olimex_hmz144.c

@@ -0,0 +1,142 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2022 Jerzy Kasenberg
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <xc.h>
+#include "tusb.h"
+
+/* JTAG on, WDT off */
+#pragma config FDMTEN=0, FSOSCEN=0, DMTCNT=1
+#pragma config DEBUG=ON
+#pragma config JTAGEN=ON
+#pragma config FSLEEP=OFF
+#pragma config TRCEN=OFF
+#pragma config ICESEL=ICS_PGx2
+
+#pragma config POSCMOD = HS
+#pragma config FNOSC = SPLL
+/* 24MHz posc input to pll, div by 3, multiply by 50, div by 2 -> 200mhz*/
+#pragma config FPLLICLK=0, FPLLIDIV=DIV_3, FPLLRNG=RANGE_5_10_MHZ, FPLLMULT=MUL_50, FPLLODIV=DIV_2
+#pragma config FUSBIDIO=1
+#pragma config WINDIS=NORMAL
+#pragma config WDTSPGM=1
+#pragma config WDTPS=15
+#pragma config FWDTEN=OFF
+
+void button_init(void)
+{
+  // RB12 - button
+  // ANSELB B12 not analog
+  ANSELBCLR = TU_BIT(12);
+  // TRISB B12 input
+  TRISBSET = TU_BIT(12);
+}
+
+void led_init(void)
+{
+  // RH2 - LED
+  // ANASELH no analog function on RH2
+  // TRISH RH2 input
+  TRISHCLR = TU_BIT(2);
+  // Initial value 0, LED off
+  LATHCLR = TU_BIT(2);
+}
+
+void uart_init(void)
+{
+  // RE8/RE9 Uart2 TX/RX
+  // ANSELE - TX/RX not analog
+  ANSELECLR = TU_BIT(8) | TU_BIT(9);
+
+  /* Unlock system for PPS configuration */
+  SYSKEY = 0x00000000;
+  SYSKEY = 0xAA996655;
+  SYSKEY = 0x556699AA;
+  CFGCONbits.IOLOCK = 0;
+
+  // PPS Input Remapping
+  // U2RX -> RE9
+  U2RXR = 13;
+
+  // PPS Output Remapping
+  // RE8 -> U2TX
+  RPE8R = 2;
+
+  // Lock back the system after PPS configuration
+  CFGCONbits.IOLOCK = 1;
+  SYSKEY = 0x00000000;
+
+  // UART2
+  // High speed mode
+  // 8 bits, no parity, no RTS/CTS, no flow control
+  U2MODE = 0x0;
+
+  // Enable UART2 Receiver and Transmitter
+  U2STASET = (_U2STA_UTXEN_MASK | _U2STA_URXEN_MASK | _U2STA_UTXISEL1_MASK);
+
+  // BAUD Rate register Setup
+  U2BRG = 100000000 / (16 * 115200) + 1;
+
+  // Disable Interrupts
+  IEC4CLR = _IEC4_U2EIE_MASK | _IEC4_U2RXIE_MASK | _IEC4_U2TXIE_MASK;
+
+  // Turn ON UART2
+  U2MODESET = _U2MODE_ON_MASK;
+}
+
+//--------------------------------------------------------------------+
+// Board porting API
+//--------------------------------------------------------------------+
+
+void board_led_write(bool state)
+{
+  if (state)
+  {
+    LATHSET = TU_BIT(2);
+  }
+  else
+  {
+    LATHCLR = TU_BIT(2);
+  }
+}
+
+uint32_t board_button_read(void)
+{
+  return (PORTB >> 12) & 1;
+}
+
+int board_uart_write(void const * buf, int len)
+{
+  int i = len;
+  uint8_t const * data = buf;
+  while (i--)
+  {
+    while (U2STAbits.UTXBF) ;
+    U2TXREG = *data++;
+  }
+  return len;
+}

+ 110 - 0
hw/bsp/pic32mz/family.c

@@ -0,0 +1,110 @@
+/* 
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2022 Jerzy Kasenberg
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <xc.h>
+#include "tusb.h"
+
+void __attribute__((interrupt(IPL2AUTO), vector(_USB_VECTOR), no_fpu))
+USBD_IRQHandler(void)
+{
+  IFS4CLR = _IFS4_USBIF_MASK;
+  tud_int_handler(0);
+}
+
+TU_ATTR_WEAK void button_init(void)
+{
+}
+
+TU_ATTR_WEAK void led_init(void)
+{
+}
+
+TU_ATTR_WEAK void uart_init(void)
+{
+}
+
+void board_init(void)
+{
+  button_init();
+  led_init();
+  uart_init();
+
+  // Force device mode by overriding USB ID and settings it to 1
+  USBCRCONbits.PHYIDEN = 0;
+  USBCRCONbits.USBIDVAL = 1;
+  USBCRCONbits.USBIDOVEN = 1;
+
+  // set interrupt priority (must much IPL2AUTO)
+  IPC33CLR = _IPC33_USBIP_MASK;
+  IPC33SET = (2 << _IPC33_USBIP_POSITION);
+  // set interrupt subpriority
+  IPC33CLR = _IPC33_USBIS_MASK;
+  IPC33SET = (0 << _IPC33_USBIS_POSITION);
+
+  USBCRCONbits.USBIE = 0;
+  IFS4CLR = _IFS4_USBIF_MASK;
+  IEC4SET = _IEC4_USBIE_MASK;
+
+  __builtin_enable_interrupts();
+}
+
+//--------------------------------------------------------------------+
+// Board porting API
+//--------------------------------------------------------------------+
+
+TU_ATTR_WEAK void board_led_write(bool state)
+{
+  (void) state;
+}
+
+TU_ATTR_WEAK uint32_t board_button_read(void)
+{
+  return 0;
+}
+
+TU_ATTR_WEAK int board_uart_read(uint8_t * buf, int len)
+{
+  (void) buf;
+  (void) len;
+
+  return 0;
+}
+
+TU_ATTR_WEAK int board_uart_write(void const * buf, int len)
+{
+  (void) buf;
+  return len;
+}
+
+#if CFG_TUSB_OS  == OPT_OS_NONE
+uint32_t board_millis(void)
+{
+  // COUNTER is system clock (200MHz / 2 = 100MHz) convert to ms)
+  return _CP0_GET_COUNT() / (100000000 / 1000);
+}
+#endif

+ 20 - 0
hw/bsp/pic32mz/family.mk

@@ -0,0 +1,20 @@
+CROSS_COMPILE = xc32-
+CFLAGS_OPTIMIZED = -O2
+LIBS_GCC = -lgcc -lm
+SKIP_NANOLIB = 1
+
+CFLAGS = \
+  -std=c99 \
+  -DCFG_TUSB_MCU=OPT_MCU_PIC32MZ
+
+include $(TOP)/$(BOARD_PATH)/board.mk
+
+SRC_C += \
+	src/portable/microchip/pic32mz/dcd_pic32mz.c \
+
+INC += \
+	$(TOP)/hw/mcu/microchip/pic32mz \
+	$(TOP)/$(BOARD_PATH) \
+
+# flash target using jlink
+flash: flash-jlink

+ 4 - 0
src/device/dcd_attr.h

@@ -86,6 +86,10 @@
   #define DCD_ATTR_ENDPOINT_MAX   10
   #define DCD_ATTR_ENDPOINT_MAX   10
   #define DCD_ATTR_ENDPOINT_EXCLUSIVE_NUMBER
   #define DCD_ATTR_ENDPOINT_EXCLUSIVE_NUMBER
 
 
+#elif TU_CHECK_MCU(OPT_MCU_PIC32MZ)
+  #define DCD_ATTR_ENDPOINT_MAX   8
+  #define DCD_ATTR_ENDPOINT_EXCLUSIVE_NUMBER
+
 //------------- ST -------------//
 //------------- ST -------------//
 #elif TU_CHECK_MCU(OPT_MCU_STM32F0)
 #elif TU_CHECK_MCU(OPT_MCU_STM32F0)
   #define DCD_ATTR_ENDPOINT_MAX   8
   #define DCD_ATTR_ENDPOINT_MAX   8

+ 737 - 0
src/portable/microchip/pic32mz/dcd_pic32mz.c

@@ -0,0 +1,737 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2022 Jerzy Kasenberg
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "tusb_option.h"
+
+#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_PIC32MZ
+
+#include <common/tusb_common.h>
+#include <device/dcd.h>
+
+#include <xc.h>
+#include "usbhs_registers.h"
+
+#define USB_REGS  ((usbhs_registers_t *) (_USB_BASE_ADDRESS))
+
+// Maximum number of endpoints, could be trimmed down in tusb_config to reduce RAM usage.
+#ifndef EP_MAX
+#define EP_MAX            8
+#endif
+
+
+typedef enum {
+  EP0_STAGE_NONE,
+  EP0_STAGE_SETUP_IN_DATA,
+  EP0_STAGE_SETUP_OUT_NO_DATA,
+  EP0_STAGE_SETUP_OUT_DATA,
+  EP0_STAGE_DATA_IN,
+  EP0_STAGE_DATA_IN_LAST_PACKET_FILLED,
+  EP0_STAGE_DATA_IN_SENT,
+  EP0_STAGE_DATA_OUT,
+  EP0_STAGE_DATA_OUT_COMPLETE,
+  EP0_STAGE_STATUS_IN,
+  EP0_STAGE_ADDRESS_CHANGE,
+} ep0_stage_t;
+
+typedef struct {
+  uint8_t * buffer;
+  // Total length of current transfer
+  uint16_t total_len;
+  // Bytes transferred so far
+  uint16_t transferred;
+  uint16_t max_packet_size;
+  uint16_t fifo_size;
+  // Packet size sent or received so far. It is used to modify transferred field
+  // after ACK is received or when filling ISO endpoint with size larger then
+  // FIFO size.
+  uint16_t last_packet_size;
+  uint8_t ep_addr;
+} xfer_ctl_t;
+
+static struct
+{
+  // Current FIFO RAM address used for FIFO allocation
+  uint16_t fifo_addr_top;
+  // EP0 transfer stage
+  ep0_stage_t ep0_stage;
+  // Device address
+  uint8_t dev_addr;
+  xfer_ctl_t xfer_status[EP_MAX][2];
+} _dcd;
+
+// Two endpoint 0 descriptor definition for unified dcd_edpt_open()
+static tusb_desc_endpoint_t const ep0OUT_desc =
+{
+  .bLength          = sizeof(tusb_desc_endpoint_t),
+  .bDescriptorType  = TUSB_DESC_ENDPOINT,
+
+  .bEndpointAddress = 0x00,
+  .bmAttributes     = { .xfer = TUSB_XFER_CONTROL },
+  .wMaxPacketSize   = CFG_TUD_ENDPOINT0_SIZE,
+  .bInterval        = 0
+};
+
+static tusb_desc_endpoint_t const ep0IN_desc =
+{
+  .bLength          = sizeof(tusb_desc_endpoint_t),
+  .bDescriptorType  = TUSB_DESC_ENDPOINT,
+
+  .bEndpointAddress = 0x80,
+  .bmAttributes     = { .xfer = TUSB_XFER_CONTROL },
+  .wMaxPacketSize   = CFG_TUD_ENDPOINT0_SIZE,
+  .bInterval        = 0
+};
+
+#define XFER_CTL_BASE(_ep, _dir) &_dcd.xfer_status[_ep][_dir]
+
+static void ep0_set_stage(ep0_stage_t stage)
+{
+  _dcd.ep0_stage = stage;
+}
+
+static ep0_stage_t ep0_get_stage(void)
+{
+  return _dcd.ep0_stage;
+}
+
+/*------------------------------------------------------------------*/
+/* Controller API
+ *------------------------------------------------------------------*/
+void dcd_init(uint8_t rhport)
+{
+  // Disable endpoint interrupts for now
+  USB_REGS->INTRRXEbits.w = 0;
+  USB_REGS->INTRTXEbits.w = 0;
+  // Enable Reset/Suspend/Resume interrupts only
+  USB_REGS->INTRUSBEbits.w = 7;
+
+  dcd_connect(rhport);
+}
+
+void dcd_int_enable(uint8_t rhport)
+{
+  (void) rhport;
+
+  USBCRCONbits.USBIE = 1;
+}
+
+void dcd_int_disable(uint8_t rhport)
+{
+  (void) rhport;
+
+  USBCRCONbits.USBIE = 0;
+}
+
+void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
+{
+  (void) rhport;
+
+  ep0_set_stage(EP0_STAGE_ADDRESS_CHANGE);
+  // Store address it will be used later after status stage is done
+  _dcd.dev_addr = dev_addr;
+  // Confirm packet now, address will be set when status stage is detected
+  USB_REGS->EPCSR[0].CSR0L_DEVICEbits.w = (USBHS_EP0_DEVICE_SERVICED_RXPKTRDY | USBHS_EP0_DEVICE_DATAEND);
+}
+
+void dcd_remote_wakeup(uint8_t rhport)
+{
+  (void) rhport;
+
+  USB_REGS->POWERbits.RESUME = 1;
+#if CFG_TUSB_OS != OPT_OS_NONE
+  osal_task_delay(10);
+#endif
+  USB_REGS->POWERbits.RESUME = 0;
+}
+
+void dcd_connect(uint8_t rhport)
+{
+  (void) rhport;
+
+  USB_REGS->POWERbits.HSEN = TUD_OPT_HIGH_SPEED ? 1 : 0;
+  USB_REGS->POWERbits.SOFTCONN = 1;
+}
+
+void dcd_disconnect(uint8_t rhport)
+{
+  (void) rhport;
+
+  USB_REGS->POWERbits.SOFTCONN = 1;
+}
+
+TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void)
+{
+  return (_CP0_GET_STATUS() & (_CP0_STATUS_EXL_MASK | _CP0_STATUS_IPL_MASK)) != 0;
+}
+
+static void epn_rx_configure(uint8_t endpoint, uint16_t endpointSize,
+                             uint16_t fifoAddress, uint8_t fifoSize,
+                             uint32_t transferType)
+{
+  uint8_t old_index = USB_REGS->INDEXbits.ENDPOINT;
+
+  // Select endpoint register set (same register address is used for all endpoints.
+  USB_REGS->INDEXbits.ENDPOINT = endpoint;
+
+  // Configure the Endpoint size
+  USB_REGS->INDEXED_EPCSR.RXMAXPbits.RXMAXP = endpointSize;
+
+  // Set up the fifo address.
+  USB_REGS->RXFIFOADDbits.RXFIFOAD = fifoAddress;
+
+  // Resets the endpoint data toggle to 0
+  USB_REGS->INDEXED_EPCSR.RXCSRL_DEVICEbits.CLRDT = 1;
+
+  // Set up the FIFO size
+  USB_REGS->RXFIFOSZbits.RXFIFOSZ = fifoSize;
+
+  USB_REGS->INDEXED_EPCSR.RXCSRH_DEVICEbits.ISO = transferType == 1 ? 1 : 0;
+  // Disable NYET Handshakes for interrupt endpoints
+  USB_REGS->INDEXED_EPCSR.RXCSRH_DEVICEbits.DISNYET = transferType == 3 ? 1 : 0;
+
+  // Restore the index register.
+  USB_REGS->INDEXbits.ENDPOINT = old_index;
+
+  // Enable the endpoint interrupt.
+  USB_REGS->INTRRXEbits.w |= (1 << endpoint);
+}
+
+static void epn_tx_configure(uint8_t endpoint, uint16_t endpointSize,
+                             uint16_t fifoAddress, uint8_t fifoSize,
+                             uint32_t transferType)
+{
+  uint8_t old_index = USB_REGS->INDEXbits.ENDPOINT;
+
+  // Select endpoint register set (same register address is used for all endpoints.
+  USB_REGS->INDEXbits.ENDPOINT = endpoint;
+
+  // Configure the Endpoint size
+  USB_REGS->INDEXED_EPCSR.TXMAXPbits.TXMAXP = endpointSize;
+
+  // Set up the fifo address
+  USB_REGS->TXFIFOADDbits.TXFIFOAD = fifoAddress;
+
+  // Resets the endpoint data toggle to 0
+  USB_REGS->INDEXED_EPCSR.TXCSRL_DEVICEbits.CLRDT = 1;
+
+  // Set up the FIFO size
+  USB_REGS->TXFIFOSZbits.TXFIFOSZ = fifoSize;
+
+  USB_REGS->INDEXED_EPCSR.TXCSRH_DEVICEbits.ISO = 1 == transferType ? 1 : 0;
+
+  // Restore the index register
+  USB_REGS->INDEXbits.ENDPOINT = old_index;
+
+  // Enable the interrupt
+  USB_REGS->INTRTXEbits.w |=  (1 << endpoint);
+}
+
+static void tx_fifo_write(uint8_t endpoint, uint8_t const * buffer, size_t count)
+{
+  size_t i;
+  volatile uint8_t * fifo_reg;
+
+  fifo_reg = (volatile uint8_t *) (&USB_REGS->FIFO[endpoint]);
+
+  for (i = 0; i < count; i++)
+  {
+    *fifo_reg = buffer[i];
+  }
+}
+
+static int rx_fifo_read(uint8_t epnum, uint8_t * buffer)
+{
+  uint32_t i;
+  uint32_t count;
+  volatile uint8_t * fifo_reg;
+
+  fifo_reg = (volatile uint8_t *) (&USB_REGS->FIFO[epnum]);
+
+  count = USB_REGS->EPCSR[epnum].RXCOUNTbits.RXCNT;
+
+  for (i = 0; i < count; i++)
+  {
+    buffer[i] = fifo_reg[i & 3];
+  }
+
+  return count;
+}
+
+static void xfer_complete(xfer_ctl_t * xfer, uint8_t result, bool in_isr)
+{
+  dcd_event_xfer_complete(0, xfer->ep_addr, xfer->transferred, result, in_isr);
+}
+
+static void ep0_fill_tx(xfer_ctl_t * xfer_in)
+{
+  uint16_t left = xfer_in->total_len - xfer_in->transferred;
+
+  if (left)
+  {
+    xfer_in->last_packet_size = tu_min16(xfer_in->max_packet_size, left);
+    tx_fifo_write(0, xfer_in->buffer + xfer_in->transferred, xfer_in->last_packet_size);
+    xfer_in->transferred += xfer_in->last_packet_size;
+    left = xfer_in->total_len - xfer_in->transferred;
+  }
+
+  if (xfer_in->last_packet_size < xfer_in->max_packet_size || left == 0)
+  {
+    switch (ep0_get_stage())
+    {
+      case EP0_STAGE_SETUP_IN_DATA:
+      case EP0_STAGE_DATA_IN:
+      case EP0_STAGE_DATA_IN_SENT:
+        ep0_set_stage(EP0_STAGE_DATA_IN_LAST_PACKET_FILLED);
+        USB_REGS->EPCSR[0].CSR0L_DEVICEbits.TXPKTRDY = 1;
+        break;
+      case EP0_STAGE_SETUP_OUT_NO_DATA:
+        ep0_set_stage(EP0_STAGE_STATUS_IN);
+        USB_REGS->EPCSR[0].CSR0L_DEVICEbits.w = (USBHS_EP0_DEVICE_SERVICED_RXPKTRDY | USBHS_EP0_DEVICE_DATAEND);
+        break;
+      case EP0_STAGE_DATA_OUT_COMPLETE:
+        ep0_set_stage(EP0_STAGE_STATUS_IN);
+        USB_REGS->EPCSR[0].CSR0L_DEVICEbits.w = (USBHS_EP0_DEVICE_SERVICED_RXPKTRDY | USBHS_EP0_DEVICE_DATAEND);
+        break;
+      default:
+        break;
+    }
+  }
+  else
+  {
+    switch (ep0_get_stage())
+    {
+      case EP0_STAGE_SETUP_IN_DATA:
+        ep0_set_stage(EP0_STAGE_DATA_IN);
+        // fall through
+      case EP0_STAGE_DATA_IN:
+        USB_REGS->EPCSR[0].CSR0L_DEVICEbits.TXPKTRDY = 1;
+        break;
+      default:
+        break;
+    }
+  }
+}
+
+static void epn_fill_tx(xfer_ctl_t * xfer_in, uint8_t epnum)
+{
+  uint16_t left = xfer_in->total_len - xfer_in->transferred;
+  if (left)
+  {
+    xfer_in->last_packet_size = tu_min16(xfer_in->max_packet_size, left);
+    tx_fifo_write(epnum, xfer_in->buffer + xfer_in->transferred, xfer_in->last_packet_size);
+  }
+  USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.TXPKTRDY = 1;
+}
+
+static bool ep0_xfer(xfer_ctl_t * xfer, int dir)
+{
+  if (dir == TUSB_DIR_OUT)
+  {
+    if (xfer->total_len)
+    {
+      switch (_dcd.ep0_stage)
+      {
+        case EP0_STAGE_DATA_OUT_COMPLETE:
+        case EP0_STAGE_SETUP_OUT_DATA:
+          ep0_set_stage(EP0_STAGE_DATA_OUT);
+          USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVCRPR = 1;
+          break;
+        default:
+          TU_ASSERT(0);
+      }
+    }
+    else
+    {
+      switch (_dcd.ep0_stage)
+      {
+        case EP0_STAGE_DATA_IN_SENT:
+          ep0_set_stage(EP0_STAGE_NONE);
+          // fall through
+        case EP0_STAGE_NONE:
+          xfer_complete(xfer, XFER_RESULT_SUCCESS, true);
+          break;
+        default:
+          break;
+      }
+    }
+  }
+  else // IN
+  {
+    ep0_fill_tx(xfer);
+  }
+
+  return true;
+}
+
+/*------------------------------------------------------------------*/
+/* DCD Endpoint port
+ *------------------------------------------------------------------*/
+
+bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
+{
+  (void) rhport;
+  uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress);
+  uint8_t const dir   = tu_edpt_dir(desc_edpt->bEndpointAddress);
+  xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
+
+  TU_ASSERT(epnum < EP_MAX);
+
+  xfer->max_packet_size = tu_edpt_packet_size(desc_edpt);
+  xfer->fifo_size = xfer->max_packet_size;
+  xfer->ep_addr = desc_edpt->bEndpointAddress;
+
+  if (epnum != 0)
+  {
+    if (dir == TUSB_DIR_OUT)
+    {
+      epn_rx_configure(epnum, xfer->max_packet_size, _dcd.fifo_addr_top, __builtin_ctz(xfer->fifo_size) - 3, desc_edpt->bmAttributes.xfer);
+      _dcd.fifo_addr_top += (xfer->fifo_size + 7) >> 3;
+    }
+    else
+    {
+      epn_tx_configure(epnum, xfer->max_packet_size, _dcd.fifo_addr_top, __builtin_ctz(xfer->fifo_size) - 3, desc_edpt->bmAttributes.xfer);
+      _dcd.fifo_addr_top += (xfer->fifo_size + 7) >> 3;
+    }
+  }
+  return true;
+}
+
+void dcd_edpt_close_all (uint8_t rhport)
+{
+  (void) rhport;
+
+  // Reserve EP0 FIFO address
+  _dcd.fifo_addr_top = 64 >> 3;
+  for (int i = 1; i < EP_MAX; ++i)
+  {
+    tu_memclr(&_dcd.xfer_status[i], sizeof(_dcd.xfer_status[i]));
+  }
+}
+
+void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
+{
+  (void) rhport;
+  (void) ep_addr;
+}
+
+bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
+{
+  uint8_t const epnum = tu_edpt_number(ep_addr);
+  uint8_t const dir   = tu_edpt_dir(ep_addr);
+  xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
+  (void) rhport;
+
+  xfer->buffer = buffer;
+  xfer->total_len = total_bytes;
+  xfer->last_packet_size = 0;
+  xfer->transferred = 0;
+
+  if (epnum == 0)
+  {
+    return ep0_xfer(xfer, dir);
+  }
+  if (dir == TUSB_DIR_OUT)
+  {
+    USB_REGS->INTRRXEbits.w |= (1u << epnum);
+  }
+  else // IN
+  {
+    epn_fill_tx(xfer, epnum);
+  }
+
+  return true;
+}
+
+void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
+{
+  uint8_t const epnum = tu_edpt_number(ep_addr);
+  uint8_t const dir   = tu_edpt_dir(ep_addr);
+  (void) rhport;
+
+  if (epnum == 0)
+  {
+    USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SENDSTALL = 1;
+  }
+  else
+  {
+    if (dir == TUSB_DIR_OUT)
+    {
+      USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.SENDSTALL = 1;
+    }
+    else
+    {
+      USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.SENDSTALL = 1;
+    }
+  }
+}
+
+void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
+{
+  uint8_t const epnum = tu_edpt_number(ep_addr);
+  uint8_t const dir   = tu_edpt_dir(ep_addr);
+  (void) rhport;
+
+  if (epnum == 0)
+  {
+    USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SENDSTALL = 0;
+  }
+  else
+  {
+    if (dir == TUSB_DIR_OUT)
+    {
+      USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.w &= ~(USBHS_EP_DEVICE_RX_SENT_STALL | USBHS_EP_DEVICE_RX_SEND_STALL);
+      USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.CLRDT = 1;
+    }
+    else
+    {
+      USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.w &= ~(USBHS_EP_DEVICE_TX_SENT_STALL | USBHS_EP_DEVICE_TX_SEND_STALL);
+      USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.CLRDT = 1;
+    }
+  }
+}
+
+/*------------------------------------------------------------------*/
+/* Interrupt Handler
+ *------------------------------------------------------------------*/
+
+static void ep0_handle_rx(void)
+{
+  int transferred;
+  xfer_ctl_t * xfer = XFER_CTL_BASE(0, TUSB_DIR_OUT);
+
+  TU_ASSERT(xfer->buffer,);
+
+  transferred = rx_fifo_read(0, xfer->buffer + xfer->transferred);
+  xfer->transferred += transferred;
+  if (transferred < xfer->max_packet_size || xfer->transferred == xfer->total_len)
+  {
+    ep0_set_stage(EP0_STAGE_DATA_OUT_COMPLETE);
+    xfer_complete(xfer, XFER_RESULT_SUCCESS, true);
+  }
+  else
+  {
+    USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVCRPR = 1;
+  }
+}
+
+static void epn_handle_rx_int(uint8_t epnum)
+{
+  uint8_t ep_status;
+  int transferred;
+  xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);
+
+  ep_status = USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.w;
+  if (ep_status & USBHS_EP_DEVICE_RX_SENT_STALL)
+  {
+    USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.w &= ~USBHS_EP_DEVICE_RX_SENT_STALL;
+  }
+
+  if (ep_status & USBHS_EP0_HOST_RXPKTRDY)
+  {
+    TU_ASSERT(xfer->buffer != NULL,);
+
+    transferred = rx_fifo_read(epnum, xfer->buffer + xfer->transferred);
+    USB_REGS->EPCSR[epnum].RXCSRL_HOSTbits.RXPKTRDY = 0;
+    xfer->transferred += transferred;
+    if (transferred < xfer->max_packet_size || xfer->transferred == xfer->total_len)
+    {
+      xfer_complete(xfer, XFER_RESULT_SUCCESS, true);
+    }
+  }
+}
+
+static void epn_handle_tx_int(uint8_t epnum)
+{
+  uint8_t ep_status = USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.w;
+  xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_IN);
+
+  if (ep_status & USBHS_EP_DEVICE_TX_SENT_STALL)
+  {
+    USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.w &= ~USBHS_EP_DEVICE_TX_SENT_STALL;
+  }
+  else
+  {
+    xfer->transferred += xfer->last_packet_size;
+    if (xfer->last_packet_size < xfer->max_packet_size || xfer->transferred == xfer->total_len)
+    {
+      xfer->last_packet_size = 0;
+      xfer_complete(xfer, XFER_RESULT_SUCCESS, true);
+    }
+    else
+    {
+      epn_fill_tx(xfer, epnum);
+    }
+  }
+}
+
+static void ep0_handle_int(void)
+{
+  __USBHS_CSR0L_DEVICE_t  ep0_status;
+  union {
+    tusb_control_request_t request;
+    uint32_t setup_buffer[2];
+  } setup_packet;
+  xfer_ctl_t * xfer_in = XFER_CTL_BASE(0, TUSB_DIR_IN);
+  uint8_t old_index = USB_REGS->INDEXbits.ENDPOINT;
+
+  // Select EP0 registers
+  USB_REGS->INDEXbits.ENDPOINT = 0;
+
+  ep0_status = USB_REGS->EPCSR[0].CSR0L_DEVICEbits;
+
+  if (ep0_status.SENTSTALL)
+  {
+    // Stall was sent. Reset the endpoint 0 state.
+    // Clear the sent stall bit.
+    ep0_set_stage(EP0_STAGE_NONE);
+    USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SENTSTALL = 0;
+  }
+
+  if (ep0_status.SETUPEND)
+  {
+    // This means the current control transfer end prematurely. We don't
+    // need to end any transfers. The device layer will manage the
+    // premature transfer end. We clear the SetupEnd bit and reset the
+    // driver control transfer state machine to waiting for next setup
+    // packet from host.
+    USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVSSETEND = 1;
+    ep0_set_stage(EP0_STAGE_NONE);
+  }
+
+  if (ep0_status.RXPKTRDY)
+  {
+    switch (ep0_get_stage())
+    {
+      default:
+        // Data arrived at unexpected state, this must be setup stage packet after all.
+        // Fall through
+      case EP0_STAGE_NONE:
+        // This means we were expecting a SETUP packet and we got one.
+        setup_packet.setup_buffer[0] = USB_REGS->FIFO[0];
+        setup_packet.setup_buffer[1] = USB_REGS->FIFO[0];
+        if (setup_packet.request.bmRequestType_bit.direction == TUSB_DIR_OUT)
+        {
+          // SVCRPR is not set yet, it will be set later when out xfer is started
+          // Till then NAKs will hold incommint data
+          ep0_set_stage(setup_packet.request.wLength == 0 ? EP0_STAGE_SETUP_OUT_NO_DATA : EP0_STAGE_SETUP_OUT_DATA);
+        }
+        else
+        {
+          USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVCRPR = 1;
+          ep0_set_stage(EP0_STAGE_SETUP_IN_DATA);
+        }
+        dcd_event_setup_received(0, &setup_packet.request.bmRequestType, true);
+        break;
+      case EP0_STAGE_DATA_OUT:
+        ep0_handle_rx();
+        break;
+    }
+  }
+  else
+  {
+    switch (ep0_get_stage())
+    {
+      case EP0_STAGE_STATUS_IN:
+        // Status was just sent, this concludes request, notify client
+        ep0_set_stage(EP0_STAGE_NONE);
+        xfer_complete(xfer_in, XFER_RESULT_SUCCESS, true);
+        break;
+      case EP0_STAGE_DATA_IN:
+        // Packet sent, fill more data
+        ep0_fill_tx(xfer_in);
+        break;
+      case EP0_STAGE_DATA_IN_LAST_PACKET_FILLED:
+        ep0_set_stage(EP0_STAGE_DATA_IN_SENT);
+        xfer_complete(xfer_in, XFER_RESULT_SUCCESS, true);
+        break;
+      case EP0_STAGE_ADDRESS_CHANGE:
+        // Status stage after set address request finished, address can be changed
+        USB_REGS->FADDRbits.FUNC = _dcd.dev_addr;
+        ep0_set_stage(EP0_STAGE_NONE);
+        break;
+      default:
+        break;
+    }
+  }
+  // Restore register index
+  USB_REGS->INDEXbits.ENDPOINT = old_index;
+}
+
+void dcd_int_handler(uint8_t rhport)
+{
+  int i;
+  uint8_t mask;
+  __USBCSR2bits_t csr2_bits;
+  uint16_t rxints = USB_REGS->INTRRX;
+  uint16_t txints = USB_REGS->INTRTX;
+  csr2_bits = USBCSR2bits;
+  (void) rhport;
+
+  IFS4CLR = _IFS4_USBIF_MASK;
+
+  if (csr2_bits.SOFIF && csr2_bits.SOFIE)
+  {
+    dcd_event_bus_signal(0, DCD_EVENT_SOF, true);
+  }
+  if (csr2_bits.RESETIF)
+  {
+    dcd_edpt_open(0, &ep0OUT_desc);
+    dcd_edpt_open(0, &ep0IN_desc);
+    dcd_event_bus_reset(0, USB_REGS->POWERbits.HSMODE ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true);
+  }
+  if (csr2_bits.SUSPIF)
+  {
+    dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true);
+  }
+  if (csr2_bits.RESUMEIF)
+  {
+    dcd_event_bus_signal(0, DCD_EVENT_RESUME, true);
+  }
+  // INTRTX has bit for EP0
+  if (txints & 1)
+  {
+    txints ^= 1;
+    ep0_handle_int();
+  }
+  for (mask = 0x02, i = 1; rxints != 0 && mask != 0; mask <<= 1, ++i)
+  {
+    if (rxints & mask)
+    {
+      rxints ^= mask;
+      epn_handle_rx_int(i);
+    }
+  }
+  for (mask = 0x02, i = 1; txints != 0 && mask != 0; mask <<= 1, ++i)
+  {
+    if (txints & mask)
+    {
+      txints ^= mask;
+      epn_handle_tx_int(i);
+    }
+  }
+}
+
+#endif

+ 931 - 0
src/portable/microchip/pic32mz/usbhs_registers.h

@@ -0,0 +1,931 @@
+/*******************************************************************************
+* Copyright (C) 2019 Microchip Technology Inc. and its subsidiaries.
+*
+* Subject to your compliance with these terms, you may use Microchip software
+* and any derivatives exclusively with Microchip products. It is your
+* responsibility to comply with third party license terms applicable to your
+* use of third party software (including open source software) that may
+* accompany Microchip software.
+*
+* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
+* EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
+* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
+* PARTICULAR PURPOSE.
+*
+* IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
+* INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
+* WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
+* BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
+* FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
+* ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
+* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
+*******************************************************************************/
+/*******************************************************************************
+  USBHS Peripheral Library Register Defintions 
+
+  File Name:
+    usbhs_registers.h
+
+  Summary:
+    USBHS PLIB Register Defintions
+
+  Description:
+    This file contains the constants and defintions which are required by the
+    the USBHS library.
+*******************************************************************************/
+
+#ifndef __USBHS_REGISTERS_H__
+#define __USBHS_REGISTERS_H__
+
+#include <p32xxxx.h>
+#include <stdint.h>
+
+/*****************************************
+ * Module Register Offsets.
+ *****************************************/
+
+#define USBHS_REG_FADDR         0x000
+#define USBHS_REG_POWER         0x001
+#define USBHS_REG_INTRTX        0x002
+#define USBHS_REG_INTRRX        0x004
+#define USBHS_REG_INTRTXE       0x006
+#define USBHS_REG_INTRRXE       0x008
+#define USBHS_REG_INTRUSB       0x00A 
+#define USBHS_REG_INTRUSBE      0x00B 
+#define USBHS_REG_FRAME         0x00C
+#define USBHS_REG_INDEX         0x00E
+#define USBHS_REG_TESTMODE      0x00F
+
+/*******************************************************
+ * Endpoint Control Status Registers (CSR). These values 
+ * should be added to either the 0x10 to access the
+ * register through Indexed CSR. To access the actual 
+ * CSR, see ahead in this header file.
+ ******************************************************/
+
+#define USBHS_REG_EP_TXMAXP     0x000
+#define USBHS_REG_EP_CSR0L      0x002
+#define USBHS_REG_EP_CSR0H      0x003
+#define USBHS_REG_EP_TXCSRL     0x002
+#define USBHS_REG_EP_TXCSRH     0x003
+#define USBHS_REG_EP_RXMAXP     0x004
+#define USBHS_REG_EP_RXCSRL     0x006
+#define USBHS_REG_EP_RXCSRH     0x007
+#define USBHS_REG_EP_COUNT0     0x008
+#define USBHS_REG_EP_RXCOUNT    0x008
+#define USBHS_REG_EP_TYPE0      0x01A
+#define USBHS_REG_EP_TXTYPE     0x01A
+#define USBHS_REG_EP_NAKLIMIT0  0x01B
+#define USBHS_REG_EP_TXINTERVAL 0x01B
+#define USBHS_REG_EP_RXTYPE     0x01C
+#define USBHS_REG_EP_RXINTERVAL 0x01D
+#define USBHS_REG_EP_CONFIGDATA 0x01F
+#define USBHS_REG_EP_FIFOSIZE   0x01F
+
+#define USBHS_HOST_EP0_SETUPKT_SET 0x8
+#define USBHS_HOST_EP0_TXPKTRDY_SET 0x2
+#define USBHS_SOFT_RST_NRST_SET 0x1
+#define USBHS_SOFT_RST_NRSTX_SET 0x2
+#define USBHS_EP0_DEVICE_SERVICED_RXPKTRDY 0x40
+#define USBHS_EP0_DEVICE_DATAEND 0x08
+#define USBHS_EP0_DEVICE_TXPKTRDY 0x02
+#define USBHS_EP0_HOST_STATUS_STAGE_START 0x40
+#define USBHS_EP0_HOST_REQPKT 0x20
+#define USBHS_EP0_HOST_TXPKTRDY 0x02
+#define USBHS_EP0_HOST_RXPKTRDY 0x01
+#define USBHS_EP_DEVICE_TX_SENT_STALL 0x20
+#define USBHS_EP_DEVICE_TX_SEND_STALL 0x10
+#define USBHS_EP_DEVICE_RX_SENT_STALL 0x40
+#define USBHS_EP_DEVICE_RX_SEND_STALL 0x20
+
+/* FADDR - Device Function Address */
+typedef union 
+{
+    struct __attribute__((packed)) 
+    {
+        unsigned FUNC:7;
+        unsigned :1;
+    };
+
+    uint8_t w;  
+
+} __USBHS_FADDR_t;
+
+/* POWER - Control Resume and Suspend signalling */
+typedef union 
+{
+    struct __attribute__((packed))
+    {
+        unsigned SUSPEN:1;
+        unsigned SUSPMODE:1;
+        unsigned RESUME:1;
+        unsigned RESET:1;
+        unsigned HSMODE:1;
+        unsigned HSEN:1;
+        unsigned SOFTCONN:1;
+        unsigned ISOUPD:1;
+    };
+    struct
+    {   
+        uint8_t w;
+    };
+
+} __USBHS_POWER_t;
+
+/* INTRTXE - Transmit endpoint interrupt enable */
+typedef union 
+{
+    struct __attribute__((packed))
+    {
+        unsigned EP0IE:1;
+        unsigned EP1TXIE:1;
+        unsigned EP2TXIE:1;
+        unsigned EP3TXIE:1;
+        unsigned EP4TXIE:1;
+        unsigned EP5TXIE:1;
+        unsigned EP6TXIE:1;
+        unsigned EP7TXIE:1;
+        unsigned :8;
+    };
+    struct
+    {
+        uint16_t    w;
+    };
+
+} __USBHS_INTRTXE_t;
+
+/* INTRRXE - Receive endpoint interrupt enable */
+typedef union 
+{
+    struct __attribute__((packed))
+    {
+        unsigned :1;
+        unsigned EP1RXIE:1;
+        unsigned EP2RXIE:1;
+        unsigned EP3RXIE:1;
+        unsigned EP4RXIE:1;
+        unsigned EP5RXIE:1;
+        unsigned EP6RXIE:1;
+        unsigned EP7RXIE:1;
+        unsigned :8;
+    };
+    struct
+    {
+        uint16_t    w;
+    };
+
+} __USBHS_INTRRXE_t;
+
+/* INTRUSBE - General USB Interrupt enable */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned SUSPIE:1;
+        unsigned RESUMEIE:1;
+        unsigned RESETIE:1;
+        unsigned SOFIE:1;
+        unsigned CONNIE:1;
+        unsigned DISCONIE:1;
+        unsigned SESSRQIE:1;
+        unsigned VBUSERRIE:1;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_INTRUSBE_t;
+
+/* FRAME - Frame number */
+typedef union 
+{
+    struct __attribute__((packed))
+    {
+        unsigned RFRMNUM:11;
+        unsigned :5;
+    };
+    struct
+    {
+        uint16_t w;
+    };
+
+} __USBHS_FRAME_t;
+
+/* INDEX - Endpoint index */
+typedef union 
+{
+    struct __attribute__((packed))
+    {
+        unsigned ENDPOINT:4;
+        unsigned :4;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_INDEX_t;
+
+/* TESTMODE - Test mode register */
+typedef union 
+{
+    struct __attribute__((packed))
+    {
+        unsigned NAK:1;
+        unsigned TESTJ:1;
+        unsigned TESTK:1;
+        unsigned PACKET:1;
+        unsigned FORCEHS:1;
+        unsigned FORCEFS:1;
+        unsigned FIFOACC:1;
+        unsigned FORCEHST:1;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_TESTMODE_t;
+
+/* COUNT0 - Indicates the amount of data received in endpoint 0 */ 
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned RXCNT:7;
+        unsigned :1;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_COUNT0_t;
+
+/* TYPE0 - Operating speed of target device */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned :6;
+        unsigned SPEED:2;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_TYPE0_t;
+
+/* DEVCTL - Module control register */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned SESSION:1;
+        unsigned HOSTREQ:1;
+        unsigned HOSTMODE:1;
+        unsigned VBUS:2;
+        unsigned LSDEV:1;
+        unsigned FSDEV:1;
+        unsigned BDEV:1;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_DEVCTL_t;
+
+/* CSR0L Device - Endpoint Device Mode Control Status Register */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned RXPKTRDY:1;
+        unsigned TXPKTRDY:1;
+        unsigned SENTSTALL:1;
+        unsigned DATAEND:1;
+        unsigned SETUPEND:1;
+        unsigned SENDSTALL:1;
+        unsigned SVCRPR:1;
+        unsigned SVSSETEND:1;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_CSR0L_DEVICE_t;
+
+/* CSR0L Host - Endpoint Host Mode Control Status Register */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned RXPKTRDY:1;
+        unsigned TXPKTRDY:1;
+        unsigned RXSTALL:1;
+        unsigned SETUPPKT:1;
+        unsigned ERROR:1;
+        unsigned REQPKT:1;
+        unsigned STATPKT:1;
+        unsigned NAKTMOUT:1;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_CSR0L_HOST_t;
+
+/* TXCSRL Device - Endpoint Transmit Control Status Register Low */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned TXPKTRDY:1;
+        unsigned FIFOONE:1;
+        unsigned UNDERRUN:1;
+        unsigned FLUSH:1;
+        unsigned SENDSTALL:1;
+        unsigned SENTSTALL:1;
+        unsigned CLRDT:1;
+        unsigned INCOMPTX:1;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_TXCSRL_DEVICE_t;
+
+/* TXCSRL Host - Endpoint Transmit Control Status Register Low */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned TXPKTRDY:1;
+        unsigned FIFONE:1;
+        unsigned ERROR:1;
+        unsigned FLUSH:1;
+        unsigned SETUPPKT:1;
+        unsigned RXSTALL:1;
+        unsigned CLRDT:1;
+        unsigned INCOMPTX:1;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_TXCSRL_HOST_t;
+
+/* TXCSRH Device - Endpoint Transmit Control Status Register High */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned :2;
+        unsigned DMAREQMD:1;
+        unsigned FRCDATTG:1;
+        unsigned DMAREQENL:1;
+        unsigned MODE:1;
+        unsigned ISO:1;
+        unsigned AUTOSET:1;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_TXCSRH_DEVICE_t;
+
+/* TXCSRH Host - Endpoint Transmit Control Status Register High */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned DATATGGL:1;
+        unsigned DTWREN:1;
+        unsigned DMAREQMD:1;
+        unsigned FRCDATTG:1;
+        unsigned DMAREQEN:1;
+        unsigned MODE:1;
+        unsigned :1;
+        unsigned AUOTSET:1;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_TXCSRH_HOST_t;
+
+/* CSR0H Device - Endpoint 0 Control Status Register High */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned FLSHFIFO:1;
+        unsigned :7;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_CSR0H_DEVICE_t;
+
+/* CSR0H Host - Endpoint 0 Control Status Register High */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned FLSHFIFO:1;
+        unsigned DATATGGL:1;
+        unsigned DTWREN:1;
+        unsigned DISPING:1;
+        unsigned :4;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_CSR0H_HOST_t;
+
+/* RXMAXP - Receive Endpoint Max packet size. */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned RXMAXP:11;
+        unsigned MULT:5;
+    };
+    struct
+    {
+        uint16_t w;
+    };
+
+} __USBHS_RXMAXP_t;
+
+/* RXCSRL Device - Receive endpoint Control Status Register */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned RXPKTRDY:1;
+        unsigned FIFOFULL:1;
+        unsigned OVERRUN:1;
+        unsigned DATAERR:1;
+        unsigned FLUSH:1;
+        unsigned SENDSTALL:1;
+        unsigned SENTSTALL:1;
+        unsigned CLRDT:1;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_RXCSRL_DEVICE_t;
+
+/* RXCSRL Host - Receive endpoint Control Status Register */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned RXPKTRDY:1;
+        unsigned FIFOFULL:1;
+        unsigned ERROR:1;
+        unsigned DERRNAKT:1;
+        unsigned FLUSH:1;
+        unsigned REQPKT:1;
+        unsigned RXSTALL:1;
+        unsigned CLRDT:1;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_RXCSRL_HOST_t;
+
+/* RXCSRH Device - Receive endpoint Control Status Register */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned INCOMPRX:1;
+        unsigned :2;
+        unsigned DMAREQMODE:1;
+        unsigned DISNYET:1;
+        unsigned DMAREQEN:1;
+        unsigned ISO:1;
+        unsigned AUTOCLR:1;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_RXCSRH_DEVICE_t;
+
+/* RXCSRH Host - Receive endpoint Control Status Register */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned INCOMPRX:1;
+        unsigned DATATGGL:1;
+        unsigned DATATWEN:1;
+        unsigned DMAREQMD:1;
+        unsigned PIDERR:1;
+        unsigned DMAREQEN:1;
+        unsigned AUTORQ:1;
+        unsigned AUOTCLR:1;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_RXCSRH_HOST_t;
+
+/* RXCOUNT - Amount of data pending in RX FIFO */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned RXCNT:14;
+        unsigned :2;
+    };
+    struct
+    {
+        uint16_t w;
+    };
+
+} __USBHS_RXCOUNT_t;
+
+/* TXTYPE - Specifies the target transmit endpoint */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned TEP:4;
+        unsigned PROTOCOL:2;
+        unsigned SPEED:2;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_TXTYPE_t;
+
+/* RXTYPE - Specifies the target receive endpoint */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned TEP:4;
+        unsigned PROTOCOL:2;
+        unsigned SPEED:2;
+    };
+    struct
+    {
+        uint8_t w;
+    };
+
+} __USBHS_RXTYPE_t;
+
+/* TXINTERVAL - Defines the polling interval */
+typedef struct
+{
+    uint8_t TXINTERV;
+
+} __USBHS_TXINTERVAL_t;
+
+/* RXINTERVAL - Defines the polling interval */
+typedef struct
+{
+    uint8_t RXINTERV;
+
+} __USBHS_RXINTERVAL_t;
+
+/* TXMAXP - Maximum amount of data that can be transferred through a TX endpoint
+ * */
+
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned TXMAXP:11;
+        unsigned MULT:5;
+    };
+    uint16_t w;
+
+} __USBHS_TXMAXP_t;  
+
+/* TXFIFOSZ - Size of the transmit endpoint FIFO */
+typedef struct __attribute__((packed))
+{
+    unsigned TXFIFOSZ:4;
+    unsigned TXDPB:1;
+    unsigned :3;
+
+} __USBHS_TXFIFOSZ_t;
+
+/* RXFIFOSZ - Size of the receive endpoint FIFO */
+typedef struct __attribute__((packed))
+{
+    unsigned RXFIFOSZ:4;
+    unsigned RXDPB:1;
+    unsigned :3;
+
+} __USBHS_RXFIFOSZ_t;
+
+/* TXFIFOADD - Start address of the transmit endpoint FIFO */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned TXFIFOAD:13;
+        unsigned :3;
+    };
+    uint16_t w;
+
+} __USBHS_TXFIFOADD_t;
+
+/* RXFIFOADD - Start address of the receive endpoint FIFO */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned RXFIFOAD:13;
+        unsigned :3;
+    };
+    uint16_t w;
+
+} __USBHS_RXFIFOADD_t;
+
+/* SOFTRST - Asserts NRSTO and NRSTOX */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned NRST:1;
+        unsigned NRSTX:1;
+        unsigned :6;
+    };
+    uint8_t w;
+
+} __USBHS_SOFTRST_t;
+
+/* TXFUNCADDR - Target address of transmit endpoint */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned TXFADDR:7;
+        unsigned :1;
+    };
+    uint8_t w;
+
+} __USBHS_TXFUNCADDR_t;
+
+/* RXFUNCADDR - Target address of receive endpoint */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned RXFADDR:7;
+        unsigned :1;
+    };
+    uint8_t w;
+
+} __USBHS_RXFUNCADDR_t;
+
+/* TXHUBADDR - Address of the hub to which the target transmit device endpoint
+ * is connected */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned TXHUBADDR:7;
+        unsigned MULTTRAN:1;
+    };
+    uint8_t w;
+
+} __USBHS_TXHUBADDR_t;
+
+/* RXHUBADDR - Address of the hub to which the target receive device endpoint is
+ * connected */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned RXHUBADDR:7;
+        unsigned MULTTRAN:1;
+    };
+    uint8_t w;
+
+} __USBHS_RXHUBADDR_t;
+
+/* TXHUBPORT - Address of the hub to which the target transmit device endpoint
+ * is connected. */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned TXHUBPRT:7;
+        unsigned :1;
+    };
+
+    uint8_t w;
+
+} __USBHS_TXHUBPORT_t;
+
+/* RXHUBPORT - Address of the hub to which the target receive device endpoint
+ * is connected. */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned RXHUBPRT:7;
+        unsigned :1;
+    };
+
+    uint8_t w;
+
+} __USBHS_RXHUBPORT_t;
+
+/* DMACONTROL - Configures a DMA channel */
+typedef union
+{
+    struct __attribute__((packed))
+    {
+        unsigned DMAEN:1;
+        unsigned DMADIR:1;
+        unsigned DMAMODE:1;
+        unsigned DMAIE:1;
+        unsigned DMAEP:4;
+        unsigned DMAERR:1;
+        unsigned DMABRSTM:2;
+        unsigned:21;
+    };
+
+    uint32_t w;
+
+} __USBHS_DMACNTL_t;
+
+/* Endpoint Control and Status Register Set */    
+typedef struct __attribute__((packed))
+{
+    volatile __USBHS_TXMAXP_t TXMAXPbits;
+    union
+    {
+        struct
+        {
+            union
+            {
+                volatile __USBHS_CSR0L_DEVICE_t CSR0L_DEVICEbits;
+                volatile __USBHS_CSR0L_HOST_t CSR0L_HOSTbits;
+            };
+            union
+            {
+                volatile __USBHS_CSR0H_DEVICE_t CSR0H_DEVICEbits;
+                volatile __USBHS_CSR0H_HOST_t CSR0H_HOSTbits;
+            };
+        };
+
+        struct
+        {
+            union
+            {
+                volatile __USBHS_TXCSRL_DEVICE_t TXCSRL_DEVICEbits;
+                volatile __USBHS_TXCSRL_HOST_t TXCSRL_HOSTbits;
+            };
+
+            union
+            {
+                volatile __USBHS_TXCSRH_DEVICE_t TXCSRH_DEVICEbits;
+                volatile __USBHS_TXCSRH_HOST_t TXCSRH_HOSTbits;
+            };
+        };
+    };
+
+    volatile __USBHS_RXMAXP_t RXMAXPbits;
+
+    union
+    {
+        volatile __USBHS_RXCSRL_DEVICE_t RXCSRL_DEVICEbits;
+        volatile __USBHS_RXCSRL_HOST_t RXCSRL_HOSTbits;
+    };
+
+    union
+    {
+        volatile __USBHS_RXCSRH_DEVICE_t RXCSRH_DEVICEbits;
+        volatile __USBHS_RXCSRH_HOST_t RXCSRH_HOSTbits;
+    };
+
+    union
+    {
+        volatile __USBHS_COUNT0_t COUNT0bits;
+        volatile __USBHS_RXCOUNT_t RXCOUNTbits;
+    };
+
+    union
+    {
+        volatile __USBHS_TYPE0_t TYPE0bits;
+        volatile __USBHS_TXTYPE_t TXTYPEbits;
+    };
+
+    union
+    {
+        volatile uint8_t NAKLIMIT0;
+        volatile __USBHS_TXINTERVAL_t TXINTERVALbits;
+    };
+
+    volatile __USBHS_RXTYPE_t RXTYPEbits;
+    volatile __USBHS_RXINTERVAL_t RXINTERVALbits;
+    unsigned :8;
+    union
+    {
+        volatile uint8_t CONFIGDATA;
+        volatile uint8_t FIFOSIZE;
+    };
+
+} __USBHS_EPCSR_t;
+
+/* Set of registers that configure the multi-point option */
+typedef struct __attribute__((packed))
+{
+    volatile __USBHS_TXFUNCADDR_t TXFUNCADDRbits;
+    unsigned :8;
+    volatile __USBHS_TXHUBADDR_t TXHUBADDRbits;
+    volatile __USBHS_TXHUBPORT_t TXHUBPORTbits;
+    volatile __USBHS_RXFUNCADDR_t RXFUNCADDRbits;
+    unsigned :8;
+    volatile __USBHS_RXHUBADDR_t RXHUBADDRbits;
+    volatile __USBHS_RXHUBPORT_t RXHUBPORTbits;
+
+} __USBHS_TARGET_ADDR_t;
+
+/* Set of registers that configure the DMA channel */
+typedef struct __attribute__((packed))
+{
+    volatile __USBHS_DMACNTL_t DMACNTLbits;
+    volatile uint32_t DMAADDR;
+    volatile uint32_t DMACOUNT;
+    volatile uint32_t pad;
+} __USBHS_DMA_CHANNEL_t;
+
+/* USBHS module register set */
+typedef struct __attribute__((aligned(4),packed))
+{
+    volatile __USBHS_FADDR_t    FADDRbits;
+    volatile __USBHS_POWER_t    POWERbits;
+    volatile uint16_t           INTRTX;
+    volatile uint16_t           INTRRX;
+    volatile __USBHS_INTRTXE_t  INTRTXEbits;
+    volatile __USBHS_INTRRXE_t  INTRRXEbits;
+    volatile uint8_t            INTRUSB;
+    volatile __USBHS_INTRUSBE_t INTRUSBEbits;
+    volatile __USBHS_FRAME_t    FRAMEbits;
+    volatile __USBHS_INDEX_t    INDEXbits;
+    volatile __USBHS_TESTMODE_t TESTMODEbits;
+    volatile __USBHS_EPCSR_t    INDEXED_EPCSR;
+    volatile uint32_t           FIFO[16];
+    volatile __USBHS_DEVCTL_t   DEVCTLbits;
+    volatile uint8_t            MISC;
+    volatile __USBHS_TXFIFOSZ_t TXFIFOSZbits;
+    volatile __USBHS_RXFIFOSZ_t RXFIFOSZbits;
+
+    volatile __USBHS_TXFIFOADD_t   TXFIFOADDbits;
+    volatile __USBHS_RXFIFOADD_t   RXFIFOADDbits;
+    
+    volatile uint32_t   VCONTROL;
+    volatile uint16_t   HWVERS;
+    volatile uint8_t    padding1[10];
+    volatile uint8_t    EPINFO;
+    volatile uint8_t    RAMINFO;
+    volatile uint8_t    LINKINFO;
+    volatile uint8_t    VPLEN;
+    volatile uint8_t    HS_EOF1;
+    volatile uint8_t    FS_EOF1;
+    volatile uint8_t    LS_EOF1;
+
+    volatile __USBHS_SOFTRST_t    SOFTRSTbits;
+
+    volatile __USBHS_TARGET_ADDR_t  TADDR[16];
+    volatile __USBHS_EPCSR_t        EPCSR[16];
+    volatile uint32_t               DMA_INTR;
+    volatile __USBHS_DMA_CHANNEL_t  DMA_CHANNEL[8]; 
+    volatile uint32_t               RQPKTXOUNT[16];
+
+} usbhs_registers_t;
+
+#endif

+ 3 - 0
src/tusb_option.h

@@ -138,6 +138,9 @@
 // Infineon
 // Infineon
 #define OPT_MCU_XMC4000          1800 ///< Infineon XMC4000
 #define OPT_MCU_XMC4000          1800 ///< Infineon XMC4000
 
 
+// PIC
+#define OPT_MCU_PIC32MZ          1900 ///< MicroChip PIC32MZ family
+
 // Helper to check if configured MCU is one of listed
 // Helper to check if configured MCU is one of listed
 // Apply _TU_CHECK_MCU with || as separator to list of input
 // Apply _TU_CHECK_MCU with || as separator to list of input
 #define _TU_CHECK_MCU(_m)   (CFG_TUSB_MCU == _m)
 #define _TU_CHECK_MCU(_m)   (CFG_TUSB_MCU == _m)