From 48e1f6d8990e450783f4887e41ce58fe0e463953 Mon Sep 17 00:00:00 2001 From: Valentin Milea Date: Sat, 4 Dec 2021 16:04:48 +0200 Subject: Handle the closing of endpoints on RP2040 --- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 28 +++++++++++++++++++++++----- src/portable/raspberrypi/rp2040/rp2040_usb.c | 4 +++- 2 files changed, 26 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index e084478e0..8be16ad22 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -83,7 +83,7 @@ static void _hw_endpoint_alloc(struct hw_endpoint *ep, uint8_t transfer_type) assert(((uintptr_t )next_buffer_ptr & 0b111111u) == 0); uint dpram_offset = hw_data_offset(ep->hw_data_buf); - assert(hw_data_offset(next_buffer_ptr) <= USB_DPRAM_MAX); + hard_assert(hw_data_offset(next_buffer_ptr) <= USB_DPRAM_MAX); pico_info(" Alloced %d bytes at offset 0x%x (0x%p)\r\n", size, dpram_offset, ep->hw_data_buf); @@ -93,7 +93,6 @@ static void _hw_endpoint_alloc(struct hw_endpoint *ep, uint8_t transfer_type) *ep->endpoint_control = reg; } -#if 0 // todo unused static void _hw_endpoint_close(struct hw_endpoint *ep) { // Clear hardware registers and then zero the struct @@ -103,6 +102,22 @@ static void _hw_endpoint_close(struct hw_endpoint *ep) *ep->buffer_control = 0; // Clear any endpoint state memset(ep, 0, sizeof(struct hw_endpoint)); + + // Reclaim buffer space if all endpoints are closed + bool reclaim_buffers = true; + for ( uint8_t i = 1; i < USB_MAX_ENDPOINTS; i++ ) + { + if (hw_endpoint_get_by_num(i, TUSB_DIR_OUT)->hw_data_buf != NULL || hw_endpoint_get_by_num(i, TUSB_DIR_IN)->hw_data_buf != NULL) + { + reclaim_buffers = false; + break; + } + } + if (reclaim_buffers) + { + pico_info(" reclaim buffer space\n"); + next_buffer_ptr = &usb_dpram->epx_data[0]; + } } static void hw_endpoint_close(uint8_t ep_addr) @@ -110,7 +125,6 @@ static void hw_endpoint_close(uint8_t ep_addr) struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); _hw_endpoint_close(ep); } -#endif static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) { @@ -224,6 +238,8 @@ static void reset_non_control_endpoints(void) // clear non-control hw endpoints tu_memclr(hw_endpoints[1], sizeof(hw_endpoints) - 2*sizeof(hw_endpoint_t)); + + pico_info(" reclaim buffer space\n"); next_buffer_ptr = &usb_dpram->epx_data[0]; } @@ -479,10 +495,12 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) { (void) rhport; - (void) ep_addr; - // usbd.c says: In progress transfers on this EP may be delivered after this call pico_trace("dcd_edpt_close %02x\n", ep_addr); + + // usbd.c says: In progress transfers on this EP may be delivered after this call. + // If the endpoint is no longer active when the transfer event is delivered, it will be ignored. + hw_endpoint_close(ep_addr); } void dcd_int_handler(uint8_t rhport) diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index c9e2f6b26..0a943b676 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -294,7 +294,9 @@ bool hw_endpoint_xfer_continue(struct hw_endpoint *ep) // Part way through a transfer if (!ep->active) { - panic("Can't continue xfer on inactive ep %d %s", tu_edpt_number(ep->ep_addr), ep_dir_string); + pico_info("Ignore xfer on inactive ep %d %s", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); + _hw_endpoint_lock_update(ep, -1); + return false; } // Update EP struct from hardware state -- cgit v1.3.1 From ef879e8a8a43dfa34160f50d7f432c3140dec7fa Mon Sep 17 00:00:00 2001 From: Valentin Milea Date: Mon, 6 Dec 2021 18:49:58 +0200 Subject: Support disabling feedback format correction #1234 --- src/class/audio/audio_device.c | 3 ++- src/class/audio/audio_device.h | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index d9f2e284e..a461e97c5 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2248,12 +2248,13 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Input value feedback has to be in 16.16 format - the format will be converted according to speed settings automatically +// unless format correction is disabled. bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); // Format the feedback value -#if !TUD_OPT_HIGH_SPEED +#if !TUD_OPT_HIGH_SPEED && !CFG_TUD_AUDIO_DISABLE_FEEDBACK_FORMAT_CORRECTION uint8_t * fb = (uint8_t *) &_audiod_fct[func_id].fb_val; // For FS format is 10.14 diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 5a469523c..731fd6c01 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -186,6 +186,11 @@ #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP 0 // Feedback - 0 or 1 #endif +// Disable/enable conversion from 16.16 to 10.14 format on high-speed devices. See tud_audio_n_fb_set(). +#ifndef CFG_TUD_AUDIO_DISABLE_FEEDBACK_FORMAT_CORRECTION +#define CFG_TUD_AUDIO_DISABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1 +#endif + // Audio interrupt control EP size - disabled if 0 #ifndef CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN #define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 0 // Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74) @@ -458,6 +463,11 @@ TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport); // Value will be corrected for FS to 10.14 format automatically. // (see Universal Serial Bus Specification Revision 2.0 5.12.4.2). // Feedback value will be sent at FB endpoint interval till it's changed. +// +// Note that the USB Audio 2.0 driver on Windows 10 is not following the spec and expects 16.16 +// format for FS. You can define CFG_TUD_AUDIO_DISABLE_FEEDBACK_FORMAT_CORRECTION=1 as a workaround +// to transmit the feedback value unchanged. Be aware that this might break feedback on other hosts, +// though at least on Linux the ALSA driver will happily accept either format. bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); static inline bool tud_audio_fb_set(uint32_t feedback); #endif -- cgit v1.3.1 From 36e69b86bf0f95916a66a35874da15fb420296e1 Mon Sep 17 00:00:00 2001 From: Valentin Milea Date: Tue, 7 Dec 2021 15:35:30 +0200 Subject: Remove buffer reclaim logs --- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 8be16ad22..3a3bef6a5 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -115,7 +115,6 @@ static void _hw_endpoint_close(struct hw_endpoint *ep) } if (reclaim_buffers) { - pico_info(" reclaim buffer space\n"); next_buffer_ptr = &usb_dpram->epx_data[0]; } } @@ -239,7 +238,7 @@ static void reset_non_control_endpoints(void) // clear non-control hw endpoints tu_memclr(hw_endpoints[1], sizeof(hw_endpoints) - 2*sizeof(hw_endpoint_t)); - pico_info(" reclaim buffer space\n"); + // reclaim buffer space next_buffer_ptr = &usb_dpram->epx_data[0]; } -- cgit v1.3.1 From 21db2351fdd3edd560e14d2949b9b0d217a51f93 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Wed, 1 Dec 2021 13:38:20 +0100 Subject: nrf5x: Fix race condition during startup When NRF5x device is reset by software (after DFU for example), power event is ready from the beginning. When power interrupt is triggered before tud_init() finished USBD_IRQn is enabled before it would be enabled in tud_init(). This in turn may result in BUS RESET event being sent from USB interrupt to USB task when queue is not initialized yet. This scenario often happens in Mynewt build where queue creation takes more time. To prevent this scenario USBD_IRQn is not enabled in power event interrupt handler before dcd_init() was called. --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 2bcd56b8a..ed597a34f 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -1059,7 +1059,13 @@ void tusb_hal_nrf_power_event (uint32_t event) // Enable interrupt, priorities should be set by application NVIC_ClearPendingIRQ(USBD_IRQn); - NVIC_EnableIRQ(USBD_IRQn); + // Don't enable USBD interrupt yet, if dcd_init() did not finish yet + // Interrupt will be enabled by tud_init(), when USB stack is ready + // to handle interrupts. + if (tud_inited()) + { + NVIC_EnableIRQ(USBD_IRQn); + } // Wait for HFCLK while ( !hfclk_running() ) { } -- cgit v1.3.1 From ae970ba2e2cc83881c52e66cd79fad5947e5e59e Mon Sep 17 00:00:00 2001 From: Valentin Milea Date: Wed, 8 Dec 2021 12:33:30 +0200 Subject: Handle xfer events before closing EP --- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 17 ++++++++--------- src/portable/raspberrypi/rp2040/rp2040_usb.c | 4 +--- 2 files changed, 9 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 3a3bef6a5..42add3167 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -247,6 +247,14 @@ static void dcd_rp2040_irq(void) uint32_t const status = usb_hw->ints; uint32_t handled = 0; + // xfer events are handled before setup req. So if a transfer completes immediately + // before closing the EP, the events will be delivered in same order. + if (status & USB_INTS_BUFF_STATUS_BITS) + { + handled |= USB_INTS_BUFF_STATUS_BITS; + hw_handle_buff_status(); + } + if (status & USB_INTS_SETUP_REQ_BITS) { handled |= USB_INTS_SETUP_REQ_BITS; @@ -260,12 +268,6 @@ static void dcd_rp2040_irq(void) usb_hw_clear->sie_status = USB_SIE_STATUS_SETUP_REC_BITS; } - if (status & USB_INTS_BUFF_STATUS_BITS) - { - handled |= USB_INTS_BUFF_STATUS_BITS; - hw_handle_buff_status(); - } - #if FORCE_VBUS_DETECT == 0 // Since we force VBUS detect On, device will always think it is connected and // couldn't distinguish between disconnect and suspend @@ -496,9 +498,6 @@ void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) (void) rhport; pico_trace("dcd_edpt_close %02x\n", ep_addr); - - // usbd.c says: In progress transfers on this EP may be delivered after this call. - // If the endpoint is no longer active when the transfer event is delivered, it will be ignored. hw_endpoint_close(ep_addr); } diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 0a943b676..9d833e65f 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -294,9 +294,7 @@ bool hw_endpoint_xfer_continue(struct hw_endpoint *ep) // Part way through a transfer if (!ep->active) { - pico_info("Ignore xfer on inactive ep %d %s", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); - _hw_endpoint_lock_update(ep, -1); - return false; + panic("Can't continue xfer on inactive ep %d %s", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); } // Update EP struct from hardware state -- cgit v1.3.1 From 7a596b9e559e9c1b3305906eb9eb6ff707643f75 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sun, 26 Dec 2021 22:32:35 +0100 Subject: Fix Mynewt build for Microchip PIC32MZ devices. definition of DEBUG breaks Microchip pic32 builds for Mynewt. When MCU is not VALENTYUSB_EPTRI there is no need to have any preprocessor definitions. It may not look like a big deal but for xc32 builds, compiler automatically force-includes some file that have structure with field name DEBUG that result in build error in dcd_eptri.c when this file is not really needed. Moving DEBUG and LOG_USB few lines down should not break eptri builds. --- src/portable/valentyusb/eptri/dcd_eptri.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/portable/valentyusb/eptri/dcd_eptri.c b/src/portable/valentyusb/eptri/dcd_eptri.c index 837d0c0ce..51fb8b401 100644 --- a/src/portable/valentyusb/eptri/dcd_eptri.c +++ b/src/portable/valentyusb/eptri/dcd_eptri.c @@ -24,6 +24,10 @@ * This file is part of the TinyUSB stack. */ +#include "tusb_option.h" + +#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_VALENTYUSB_EPTRI) + #ifndef DEBUG #define DEBUG 0 #endif @@ -32,10 +36,6 @@ #define LOG_USB 0 #endif -#include "tusb_option.h" - -#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_VALENTYUSB_EPTRI) - #include "device/dcd.h" #include "dcd_eptri.h" #include "csr.h" -- cgit v1.3.1 From 2f69649bb6a2dcd583b52005dc946e08580323fd Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sun, 26 Dec 2021 21:50:48 +0100 Subject: Add register file for Microchip PIC32MZ --- src/portable/microchip/pic32mz/usbhs_registers.h | 931 +++++++++++++++++++++++ 1 file changed, 931 insertions(+) create mode 100644 src/portable/microchip/pic32mz/usbhs_registers.h (limited to 'src') diff --git a/src/portable/microchip/pic32mz/usbhs_registers.h b/src/portable/microchip/pic32mz/usbhs_registers.h new file mode 100644 index 000000000..757e3f083 --- /dev/null +++ b/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 +#include + +/***************************************** + * 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 -- cgit v1.3.1 From a79ffeb7643bb9c7e7af69f29fe2cfe7ded837d8 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 5 Jan 2022 13:47:01 -0800 Subject: Add Raspberry Pi Zero W and Zero 2 W These are different Broadcom chips. The peripherals are essentially the same. The main differences are: * The CPU(s) * The interrupt controller * The peripheral base address (but not the peripherals that we use) --- hw/bsp/bcm2835/boards/raspberrypi_cm4/board.h | 38 +++++ hw/bsp/bcm2835/boards/raspberrypi_cm4/board.mk | 9 ++ hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.h | 38 +++++ hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.mk | 9 ++ hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.h | 38 +++++ hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.mk | 7 + hw/bsp/bcm2835/family.c | 156 +++++++++++++++++++++ hw/bsp/bcm2835/family.mk | 43 ++++++ hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.h | 38 ----- .../raspberrypi4/boards/raspberrypi_cm4/board.mk | 1 - hw/bsp/raspberrypi4/family.c | 144 ------------------- hw/bsp/raspberrypi4/family.mk | 51 ------- hw/mcu/broadcom | 2 +- src/device/dcd_attr.h | 2 +- src/portable/synopsys/dwc2/dcd_dwc2.c | 5 +- src/portable/synopsys/dwc2/dwc2_bcm.h | 3 +- src/tusb_option.h | 2 + 17 files changed, 346 insertions(+), 240 deletions(-) create mode 100644 hw/bsp/bcm2835/boards/raspberrypi_cm4/board.h create mode 100644 hw/bsp/bcm2835/boards/raspberrypi_cm4/board.mk create mode 100644 hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.h create mode 100644 hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.mk create mode 100644 hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.h create mode 100644 hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.mk create mode 100644 hw/bsp/bcm2835/family.c create mode 100644 hw/bsp/bcm2835/family.mk delete mode 100644 hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.h delete mode 100644 hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.mk delete mode 100644 hw/bsp/raspberrypi4/family.c delete mode 100644 hw/bsp/raspberrypi4/family.mk (limited to 'src') diff --git a/hw/bsp/bcm2835/boards/raspberrypi_cm4/board.h b/hw/bsp/bcm2835/boards/raspberrypi_cm4/board.h new file mode 100644 index 000000000..1d3565d5c --- /dev/null +++ b/hw/bsp/bcm2835/boards/raspberrypi_cm4/board.h @@ -0,0 +1,38 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * 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. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/bcm2835/boards/raspberrypi_cm4/board.mk b/hw/bsp/bcm2835/boards/raspberrypi_cm4/board.mk new file mode 100644 index 000000000..b4fa3dff6 --- /dev/null +++ b/hw/bsp/bcm2835/boards/raspberrypi_cm4/board.mk @@ -0,0 +1,9 @@ +CFLAGS += -mcpu=cortex-a72 \ + -DBCM_VERSION=2711 \ + -DCFG_TUSB_MCU=OPT_MCU_BCM2711 + +CROSS_COMPILE = aarch64-none-elf- + +SUFFIX = 8 + +INC += $(TOP)/lib/CMSIS_5/CMSIS/Core_A/Include diff --git a/hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.h b/hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.h new file mode 100644 index 000000000..1d3565d5c --- /dev/null +++ b/hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.h @@ -0,0 +1,38 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * 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. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.mk b/hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.mk new file mode 100644 index 000000000..f43e12e35 --- /dev/null +++ b/hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.mk @@ -0,0 +1,9 @@ +CFLAGS += -mcpu=cortex-a53 \ + -DBCM_VERSION=2837 \ + -DCFG_TUSB_MCU=OPT_MCU_BCM2837 + +CROSS_COMPILE = aarch64-none-elf- + +SUFFIX = 8 + +INC += $(TOP)/lib/CMSIS_5/CMSIS/Core_A/Include diff --git a/hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.h b/hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.h new file mode 100644 index 000000000..1d3565d5c --- /dev/null +++ b/hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.h @@ -0,0 +1,38 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * 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. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.mk b/hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.mk new file mode 100644 index 000000000..79d7096ce --- /dev/null +++ b/hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.mk @@ -0,0 +1,7 @@ +CFLAGS += -mcpu=arm1176jzf-s \ + -DBCM_VERSION=2835 \ + -DCFG_TUSB_MCU=OPT_MCU_BCM2835 + +CROSS_COMPILE = arm-none-eabi- + +SUFFIX = diff --git a/hw/bsp/bcm2835/family.c b/hw/bsp/bcm2835/family.c new file mode 100644 index 000000000..f7a11fb49 --- /dev/null +++ b/hw/bsp/bcm2835/family.c @@ -0,0 +1,156 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * 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 "bsp/board.h" +#include "board.h" + +#include "broadcom/cpu.h" +#include "broadcom/gpio.h" +#include "broadcom/interrupts.h" +#include "broadcom/mmu.h" +#include "broadcom/caches.h" +#include "broadcom/vcmailbox.h" + +// LED +#define LED_PIN 18 +#define LED_STATE_ON 1 + +// UART TX +#define UART_TX_PIN 14 + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB_IRQHandler(void) +{ + tud_int_handler(0); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ +void board_init(void) +{ + setup_mmu_flat_map(); + init_caches(); + + // LED + gpio_set_function(LED_PIN, GPIO_FUNCTION_OUTPUT); + gpio_set_pull(LED_PIN, BP_PULL_NONE); + board_led_write(true); + + // Uart + COMPLETE_MEMORY_READS; + AUX->ENABLES_b.UART_1 = true; + + UART1->IER = 0; + UART1->CNTL = 0; + UART1->LCR_b.DATA_SIZE = UART1_LCR_DATA_SIZE_MODE_8BIT; + UART1->MCR = 0; + UART1->IER = 0; + + uint32_t source_clock = vcmailbox_get_clock_rate_measured(VCMAILBOX_CLOCK_CORE); + UART1->BAUD = ((source_clock / (115200 * 8)) - 1); + UART1->CNTL |= UART1_CNTL_TX_ENABLE_Msk; + COMPLETE_MEMORY_READS; + + gpio_set_function(UART_TX_PIN, GPIO_FUNCTION_ALT5); + + // Turn on USB peripheral. + vcmailbox_set_power_state(VCMAILBOX_DEVICE_USB_HCD, true); + + // Timer 1/1024 second tick + SYSTMR->CS_b.M1 = 1; + SYSTMR->C1 = SYSTMR->CLO + 977; + BP_EnableIRQ(TIMER_1_IRQn); + + BP_SetPriority(USB_IRQn, 0x00); + BP_ClearPendingIRQ(USB_IRQn); + BP_EnableIRQ(USB_IRQn); + BP_EnableIRQs(); +} + +void board_led_write(bool state) +{ + gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return 0; +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ + for (int i = 0; i < len; i++) { + const char* cbuf = buf; + while (!UART1->STAT_b.TX_READY) {} + if (cbuf[i] == '\n') { + UART1->IO = '\r'; + while (!UART1->STAT_b.TX_READY) {} + } + UART1->IO = cbuf[i]; + } + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void TIMER_1_IRQHandler(void) +{ + system_ticks++; + SYSTMR->C1 += 977; + SYSTMR->CS_b.M1 = 1; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif + +void HardFault_Handler (void) +{ + // asm("bkpt"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) +{ + +} diff --git a/hw/bsp/bcm2835/family.mk b/hw/bsp/bcm2835/family.mk new file mode 100644 index 000000000..6de97f584 --- /dev/null +++ b/hw/bsp/bcm2835/family.mk @@ -0,0 +1,43 @@ +MCU_DIR = hw/mcu/broadcom +DEPS_SUBMODULES += $(MCU_DIR) + +include $(TOP)/$(BOARD_PATH)/board.mk + +CFLAGS += \ + -Wall \ + -O0 \ + -ffreestanding \ + -nostdlib \ + -nostartfiles \ + -mgeneral-regs-only \ + -std=c17 + +# mcu driver cause following warnings +CFLAGS += -Wno-error=cast-qual + +SRC_C += \ + src/portable/synopsys/dwc2/dcd_dwc2.c \ + $(MCU_DIR)/broadcom/gen/interrupt_handlers.c \ + $(MCU_DIR)/broadcom/gpio.c \ + $(MCU_DIR)/broadcom/interrupts.c \ + $(MCU_DIR)/broadcom/mmu.c \ + $(MCU_DIR)/broadcom/caches.c \ + $(MCU_DIR)/broadcom/vcmailbox.c + +SKIP_NANOLIB = 1 + +LD_FILE = $(MCU_DIR)/broadcom/link$(SUFFIX).ld + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(MCU_DIR) + +SRC_S += $(MCU_DIR)/broadcom/boot$(SUFFIX).S + +$(BUILD)/kernel$(SUFFIX).img: $(BUILD)/$(PROJECT).elf + $(OBJCOPY) -O binary $^ $@ + +# Copy to kernel to netboot drive or SD card +# Change destinaation to fit your need +flash: $(BUILD)/kernel$(SUFFIX).img + @$(CP) $< /home/$(USER)/Documents/code/pi_tinyusb/boot_cpy diff --git a/hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.h b/hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.h deleted file mode 100644 index 1d3565d5c..000000000 --- a/hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020, Ha Thach (tinyusb.org) - * - * 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. - */ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#ifdef __cplusplus - } -#endif - -#endif /* BOARD_H_ */ diff --git a/hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.mk b/hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.mk deleted file mode 100644 index 897342479..000000000 --- a/hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.mk +++ /dev/null @@ -1 +0,0 @@ -CFLAGS += -DBCM_VERSION=2711 diff --git a/hw/bsp/raspberrypi4/family.c b/hw/bsp/raspberrypi4/family.c deleted file mode 100644 index ba0b2700a..000000000 --- a/hw/bsp/raspberrypi4/family.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * 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 "bsp/board.h" -#include "board.h" - -#include "broadcom/interrupts.h" -#include "broadcom/io.h" -#include "broadcom/mmu.h" -#include "broadcom/caches.h" -#include "broadcom/vcmailbox.h" - -// LED -#define LED_PIN 18 -#define LED_STATE_ON 1 - -// Button -#define BUTTON_PIN 16 -#define BUTTON_STATE_ACTIVE 0 - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void USB_IRQHandler(void) -{ - tud_int_handler(0); -} - -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM -//--------------------------------------------------------------------+ - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ -void board_init(void) -{ - setup_mmu_flat_map(); - init_caches(); - - // LED - gpio_initOutputPinWithPullNone(LED_PIN); - board_led_write(true); - - // Button - // TODO - - // Uart - uart_init(); - - // Turn on USB peripheral. - vcmailbox_set_power_state(VCMAILBOX_DEVICE_USB_HCD, true); - - // Timer 1/1024 second tick - SYSTMR->CS_b.M1 = 1; - SYSTMR->C1 = SYSTMR->CLO + 977; - BP_EnableIRQ(TIMER_1_IRQn); - - BP_SetPriority(USB_IRQn, 0x00); - BP_ClearPendingIRQ(USB_IRQn); - BP_EnableIRQ(USB_IRQn); - BP_EnableIRQs(); -} - -void board_led_write(bool state) -{ - gpio_setPinOutputBool(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); -} - -uint32_t board_button_read(void) -{ - return 0; -} - -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; - return 0; -} - -int board_uart_write(void const * buf, int len) -{ - for (int i = 0; i < len; i++) { - const char* cbuf = buf; - while (!UART1->STAT_b.TX_READY) {} - if (cbuf[i] == '\n') { - UART1->IO = '\r'; - while (!UART1->STAT_b.TX_READY) {} - } - UART1->IO = cbuf[i]; - } - return len; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; - -void TIMER_1_IRQHandler(void) -{ - system_ticks++; - SYSTMR->C1 += 977; - SYSTMR->CS_b.M1 = 1; -} - -uint32_t board_millis(void) -{ - return system_ticks; -} -#endif - -void HardFault_Handler (void) -{ - // asm("bkpt"); -} - -// Required by __libc_init_array in startup code if we are compiling using -// -nostdlib/-nostartfiles. -void _init(void) -{ - -} diff --git a/hw/bsp/raspberrypi4/family.mk b/hw/bsp/raspberrypi4/family.mk deleted file mode 100644 index c65070a71..000000000 --- a/hw/bsp/raspberrypi4/family.mk +++ /dev/null @@ -1,51 +0,0 @@ -MCU_DIR = hw/mcu/broadcom -DEPS_SUBMODULES += $(MCU_DIR) - -include $(TOP)/$(BOARD_PATH)/board.mk - -CC = clang - -CFLAGS += \ - -mcpu=cortex-a72 \ - -Wall \ - -O0 \ - -ffreestanding \ - -nostdlib \ - -nostartfiles \ - -std=c17 \ - -mgeneral-regs-only \ - -DCFG_TUSB_MCU=OPT_MCU_BCM2711 - -# mcu driver cause following warnings -CFLAGS += -Wno-error=cast-qual - -SRC_C += \ - src/portable/synopsys/dwc2/dcd_dwc2.c \ - $(MCU_DIR)/broadcom/gen/interrupt_handlers.c \ - $(MCU_DIR)/broadcom/interrupts.c \ - $(MCU_DIR)/broadcom/io.c \ - $(MCU_DIR)/broadcom/mmu.c \ - $(MCU_DIR)/broadcom/caches.c \ - $(MCU_DIR)/broadcom/vcmailbox.c - - -CROSS_COMPILE = aarch64-none-elf- - -SKIP_NANOLIB = 1 - -LD_FILE = $(MCU_DIR)/broadcom/link.ld - -INC += \ - $(TOP)/$(BOARD_PATH) \ - $(TOP)/$(MCU_DIR) \ - $(TOP)/lib/CMSIS_5/CMSIS/Core_A/Include - -SRC_S += $(MCU_DIR)/broadcom/boot.S - -$(BUILD)/kernel8.img: $(BUILD)/$(PROJECT).elf - $(OBJCOPY) -O binary $^ $@ - -# Copy to kernel to netboot drive or SD card -# Change destinaation to fit your need -flash: $(BUILD)/kernel8.img - $(CP) $< /home/$(USER)/Documents/code/pi4_tinyusb/boot_cpy diff --git a/hw/mcu/broadcom b/hw/mcu/broadcom index 5bff1d5e0..083700860 160000 --- a/hw/mcu/broadcom +++ b/hw/mcu/broadcom @@ -1 +1 @@ -Subproject commit 5bff1d5e02c37c38ee1e5cf3f7fe82fdc7e1517e +Subproject commit 08370086080759ed54ac1136d62d2ad24c6fa267 diff --git a/src/device/dcd_attr.h b/src/device/dcd_attr.h index 3c5dadaf4..feba82ea9 100644 --- a/src/device/dcd_attr.h +++ b/src/device/dcd_attr.h @@ -190,7 +190,7 @@ #define DCD_ATTR_ENDPOINT_MAX 4 //------------- Broadcom -------------// -#elif TU_CHECK_MCU(OPT_MCU_BCM2711) +#elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) #define DCD_ATTR_ENDPOINT_MAX 8 //------------- Broadcom -------------// diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index bb21b3dcd..188611743 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -33,7 +33,8 @@ #if TUSB_OPT_DEVICE_ENABLED && \ ( defined(DCD_ATTR_DWC2_STM32) || \ TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_GD32VF103) || \ - TU_CHECK_MCU(OPT_MCU_EFM32GG, OPT_MCU_BCM2711, OPT_MCU_XMC4000) ) + TU_CHECK_MCU(OPT_MCU_EFM32GG, OPT_MCU_BCM2711, OPT_MCU_BCM2835) || \ + TU_CHECK_MCU(OPT_MCU_BCM2837, OPT_MCU_XMC4000) ) #include "device/dcd.h" #include "dwc2_type.h" @@ -44,7 +45,7 @@ #include "dwc2_esp32.h" #elif TU_CHECK_MCU(OPT_MCU_GD32VF103) #include "dwc2_gd32.h" -#elif TU_CHECK_MCU(OPT_MCU_BCM2711) +#elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) #include "dwc2_bcm.h" #elif TU_CHECK_MCU(OPT_MCU_EFM32GG) #include "dwc2_efm32.h" diff --git a/src/portable/synopsys/dwc2/dwc2_bcm.h b/src/portable/synopsys/dwc2/dwc2_bcm.h index 353bc21ee..14194e754 100644 --- a/src/portable/synopsys/dwc2/dwc2_bcm.h +++ b/src/portable/synopsys/dwc2/dwc2_bcm.h @@ -31,6 +31,7 @@ extern "C" { #endif +#include "broadcom/defines.h" #include "broadcom/interrupts.h" #include "broadcom/caches.h" @@ -47,7 +48,6 @@ static inline void dwc2_dcd_int_enable(uint8_t rhport) { (void) rhport; BP_EnableIRQ(USB_IRQn); - __asm__ volatile("isb"); // needed if TIMER1 IRQ is not enabled !? } TU_ATTR_ALWAYS_INLINE @@ -55,7 +55,6 @@ static inline void dwc2_dcd_int_disable (uint8_t rhport) { (void) rhport; BP_DisableIRQ(USB_IRQn); - __asm__ volatile("isb"); // needed if TIMER1 IRQ is not enabled !? } static inline void dwc2_remote_wakeup_delay(void) diff --git a/src/tusb_option.h b/src/tusb_option.h index 2edd310fa..c7c7b2454 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -132,6 +132,8 @@ // Broadcom #define OPT_MCU_BCM2711 1700 ///< Broadcom BCM2711 +#define OPT_MCU_BCM2835 1701 ///< Broadcom BCM2835 +#define OPT_MCU_BCM2837 1702 ///< Broadcom BCM2837 // Infineon #define OPT_MCU_XMC4000 1800 ///< Infineon XMC4000 -- cgit v1.3.1 From 47218eeb674789db9dbd9b8b305c6390c3e00577 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 5 Jan 2022 16:07:17 -0800 Subject: No exceptions on broadcom. Add parens to if --- hw/bsp/broadcom_32bit/family.mk | 1 + src/class/usbtmc/usbtmc_device.c | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/hw/bsp/broadcom_32bit/family.mk b/hw/bsp/broadcom_32bit/family.mk index 4ff574744..98744c5d0 100644 --- a/hw/bsp/broadcom_32bit/family.mk +++ b/hw/bsp/broadcom_32bit/family.mk @@ -10,6 +10,7 @@ CFLAGS += \ -nostdlib \ -nostartfiles \ -mgeneral-regs-only \ + -fno-exceptions \ -std=c17 CROSS_COMPILE = arm-none-eabi- diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 4bd1edf12..26be987cf 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -235,17 +235,19 @@ void usbtmcd_init_cb(void) usbtmc_state.capabilities = tud_usbtmc_get_capabilities_cb(); #ifndef NDEBUG # if CFG_TUD_USBTMC_ENABLE_488 - if(usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger) - TU_ASSERT(&tud_usbtmc_msg_trigger_cb != NULL,); - // Per USB488 spec: table 8 - TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.listenOnly,); - TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.talkOnly,); + if (usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger) { + TU_ASSERT(&tud_usbtmc_msg_trigger_cb != NULL,); + } + // Per USB488 spec: table 8 + TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.listenOnly,); + TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.talkOnly,); # endif - if(usbtmc_state.capabilities->bmIntfcCapabilities.supportsIndicatorPulse) - TU_ASSERT(&tud_usbtmc_indicator_pulse_cb != NULL,); + if (usbtmc_state.capabilities->bmIntfcCapabilities.supportsIndicatorPulse) { + TU_ASSERT(&tud_usbtmc_indicator_pulse_cb != NULL,); + } #endif - usbtmcLock = osal_mutex_create(&usbtmcLockBuffer); + usbtmcLock = osal_mutex_create(&usbtmcLockBuffer); } uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) -- cgit v1.3.1 From 44406a8940a96bbe03e103a4f4895ec19183941f Mon Sep 17 00:00:00 2001 From: EmergReanimator Date: Thu, 6 Jan 2022 09:56:45 +0100 Subject: Enable breakpoints for ARM8M (e.g. cortex-m33) --- src/common/tusb_verify.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index 56ba8bcd1..8fef11dc7 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -37,31 +37,31 @@ * manipulation that you are told to stay away. * * This contains macros for both VERIFY and ASSERT: - * + * * VERIFY: Used when there is an error condition which is not the * fault of the MCU. For example, bounds checking on data * sent to the micro over USB should use this function. * Another example is checking for buffer overflows, where * returning from the active function causes a NAK. - * + * * ASSERT: Used for error conditions that are caused by MCU firmware * bugs. This is used to discover bugs in the code more * quickly. One example would be adding assertions in library * function calls to confirm a function's (untainted) * parameters are valid. - * + * * The difference in behavior is that ASSERT triggers a breakpoint while * verify does not. * * #define TU_VERIFY(cond) if(cond) return false; * #define TU_VERIFY(cond,ret) if(cond) return ret; - * + * * #define TU_VERIFY_HDLR(cond,handler) if(cond) {handler; return false;} * #define TU_VERIFY_HDLR(cond,ret,handler) if(cond) {handler; return ret;} * * #define TU_ASSERT(cond) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return false;} * #define TU_ASSERT(cond,ret) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return ret;} - * + * *------------------------------------------------------------------*/ #ifdef __cplusplus @@ -81,8 +81,8 @@ #define _MESS_FAILED() do {} while (0) #endif -// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 -#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7, M33 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) #define TU_BREAKPOINT() do \ { \ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ -- cgit v1.3.1 From a284e438f1952315631f354dee2b30b264afb324 Mon Sep 17 00:00:00 2001 From: Valentin Milea Date: Fri, 7 Jan 2022 15:02:52 +0200 Subject: Disable feedback format correction by default #1234 --- src/class/audio/audio_device.c | 6 ++---- src/class/audio/audio_device.h | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index a461e97c5..5ffc9b0dc 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2247,14 +2247,12 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -// Input value feedback has to be in 16.16 format - the format will be converted according to speed settings automatically -// unless format correction is disabled. bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); // Format the feedback value -#if !TUD_OPT_HIGH_SPEED && !CFG_TUD_AUDIO_DISABLE_FEEDBACK_FORMAT_CORRECTION +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION && !TUD_OPT_HIGH_SPEED uint8_t * fb = (uint8_t *) &_audiod_fct[func_id].fb_val; // For FS format is 10.14 @@ -2264,7 +2262,7 @@ bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) // 4th byte is needed to work correctly with MS Windows *fb = 0; #else - // For HS format is 16.16 as originally demanded + // Send value as-is, caller will choose the appropriate format _audiod_fct[func_id].fb_val = feedback; #endif diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 731fd6c01..f406cf281 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -186,9 +186,9 @@ #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP 0 // Feedback - 0 or 1 #endif -// Disable/enable conversion from 16.16 to 10.14 format on high-speed devices. See tud_audio_n_fb_set(). -#ifndef CFG_TUD_AUDIO_DISABLE_FEEDBACK_FORMAT_CORRECTION -#define CFG_TUD_AUDIO_DISABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1 +// Enable/disable conversion from 16.16 to 10.14 format on full-speed devices. See tud_audio_n_fb_set(). +#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1 #endif // Audio interrupt control EP size - disabled if 0 @@ -459,15 +459,15 @@ TU_ATTR_WEAK bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_byte #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport); -// User code should call this function with feedback value in 16.16 format for FS and HS. -// Value will be corrected for FS to 10.14 format automatically. -// (see Universal Serial Bus Specification Revision 2.0 5.12.4.2). -// Feedback value will be sent at FB endpoint interval till it's changed. + +// This function is used to provide data rate feedback from an asynchronous sink. Feedback value will be sent at FB endpoint interval till it's changed. +// +// The feedback format is specified to be 16.16 for HS and 10.14 for FS devices (see Universal Serial Bus Specification Revision 2.0 5.12.4.2). By default, +// the choice of format is left to the caller and feedback argument is sent as-is. If CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION is set, then tinyusb +// expects 16.16 format and handles the conversion to 10.14 on FS. // -// Note that the USB Audio 2.0 driver on Windows 10 is not following the spec and expects 16.16 -// format for FS. You can define CFG_TUD_AUDIO_DISABLE_FEEDBACK_FORMAT_CORRECTION=1 as a workaround -// to transmit the feedback value unchanged. Be aware that this might break feedback on other hosts, -// though at least on Linux the ALSA driver will happily accept either format. +// Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and macOS it seems the +// driver can work with either format. So a good compromise is to keep format correction disabled and stick to 16.16 format. bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); static inline bool tud_audio_fb_set(uint32_t feedback); #endif -- cgit v1.3.1 From 340309561dbf10f17798dc74731e9804e892e0f4 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sun, 26 Dec 2021 22:37:27 +0100 Subject: Add driver for PIC32MZ MCUs Device-only driver for PIC32MZ MCUs. --- src/device/dcd_attr.h | 4 + src/portable/microchip/pic32mz/dcd_pic32mz.c | 737 +++++++++++++++++++++++++++ src/tusb_option.h | 1 + 3 files changed, 742 insertions(+) create mode 100644 src/portable/microchip/pic32mz/dcd_pic32mz.c (limited to 'src') diff --git a/src/device/dcd_attr.h b/src/device/dcd_attr.h index 3c5dadaf4..bd8994fd8 100644 --- a/src/device/dcd_attr.h +++ b/src/device/dcd_attr.h @@ -86,6 +86,10 @@ #define DCD_ATTR_ENDPOINT_MAX 10 #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 -------------// #elif TU_CHECK_MCU(OPT_MCU_STM32F0) #define DCD_ATTR_ENDPOINT_MAX 8 diff --git a/src/portable/microchip/pic32mz/dcd_pic32mz.c b/src/portable/microchip/pic32mz/dcd_pic32mz.c new file mode 100644 index 000000000..323d01a71 --- /dev/null +++ b/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 +#include + +#include +#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 diff --git a/src/tusb_option.h b/src/tusb_option.h index 2edd310fa..4f16a3c1a 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -66,6 +66,7 @@ #define OPT_MCU_SAML22 205 ///< MicroChip SAML22 #define OPT_MCU_SAML21 206 ///< MicroChip SAML21 #define OPT_MCU_SAMX7X 207 ///< MicroChip SAME70, S70, V70, V71 family +#define OPT_MCU_PIC32MZ 220 ///< MicroChip PIC32MZ family // STM32 #define OPT_MCU_STM32F0 300 ///< ST F0 -- cgit v1.3.1 From 45fb60e883b62a550420d88426e443d0a2e7dd45 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 16 Jan 2022 12:12:57 +0700 Subject: update format correction with actual bus speed --- src/class/audio/audio_device.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 5ffc9b0dc..d21980060 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2252,18 +2252,23 @@ bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); // Format the feedback value -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION && !TUD_OPT_HIGH_SPEED - uint8_t * fb = (uint8_t *) &_audiod_fct[func_id].fb_val; - - // For FS format is 10.14 - *(fb++) = (feedback >> 2) & 0xFF; - *(fb++) = (feedback >> 10) & 0xFF; - *(fb++) = (feedback >> 18) & 0xFF; - // 4th byte is needed to work correctly with MS Windows - *fb = 0; +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION + if ( TUSB_SPEED_FULL == tud_speed_get() ) + { + uint8_t * fb = (uint8_t *) &_audiod_fct[func_id].fb_val; + + // For FS format is 10.14 + *(fb++) = (feedback >> 2) & 0xFF; + *(fb++) = (feedback >> 10) & 0xFF; + *(fb++) = (feedback >> 18) & 0xFF; + // 4th byte is needed to work correctly with MS Windows + *fb = 0; + }else #else - // Send value as-is, caller will choose the appropriate format - _audiod_fct[func_id].fb_val = feedback; + { + // Send value as-is, caller will choose the appropriate format + _audiod_fct[func_id].fb_val = feedback; + } #endif // Schedule a transmit with the new value if EP is not busy - this triggers repetitive scheduling of the feedback value -- cgit v1.3.1 From c722133671a632d6baf60506bd93c3c6d1ed6435 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 16 Jan 2022 15:38:23 +0700 Subject: change OPT_MCU_PIC32MZ to value of 1900 --- src/tusb_option.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/tusb_option.h b/src/tusb_option.h index 4f16a3c1a..351eeab88 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -66,7 +66,6 @@ #define OPT_MCU_SAML22 205 ///< MicroChip SAML22 #define OPT_MCU_SAML21 206 ///< MicroChip SAML21 #define OPT_MCU_SAMX7X 207 ///< MicroChip SAME70, S70, V70, V71 family -#define OPT_MCU_PIC32MZ 220 ///< MicroChip PIC32MZ family // STM32 #define OPT_MCU_STM32F0 300 ///< ST F0 @@ -137,6 +136,9 @@ // Infineon #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 // Apply _TU_CHECK_MCU with || as separator to list of input #define _TU_CHECK_MCU(_m) (CFG_TUSB_MCU == _m) -- cgit v1.3.1