diff options
Diffstat (limited to 'src/device/dcd.h')
| -rw-r--r-- | src/device/dcd.h | 136 |
1 files changed, 78 insertions, 58 deletions
diff --git a/src/device/dcd.h b/src/device/dcd.h index c1780f656..789552d47 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -1,4 +1,4 @@ -/* +/* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_DCD_H_ -#define _TUSB_DCD_H_ +#ifndef TUSB_DCD_H_ +#define TUSB_DCD_H_ #include "common/tusb_common.h" #include "osal/osal.h" @@ -36,42 +36,27 @@ #endif //--------------------------------------------------------------------+ -// Configuration -//--------------------------------------------------------------------+ - -#ifndef CFG_TUD_ENDPPOINT_MAX - #define CFG_TUD_ENDPPOINT_MAX TUP_DCD_ENDPOINT_MAX -#endif - -//--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ -typedef enum -{ - DCD_EVENT_INVALID = 0, - DCD_EVENT_BUS_RESET, - DCD_EVENT_UNPLUGGED, - DCD_EVENT_SOF, - DCD_EVENT_SUSPEND, // TODO LPM Sleep L1 support - DCD_EVENT_RESUME, - - DCD_EVENT_SETUP_RECEIVED, - DCD_EVENT_XFER_COMPLETE, - - // Not an DCD event, just a convenient way to defer ISR function - USBD_EVENT_FUNC_CALL, - +typedef enum { + DCD_EVENT_INVALID = 0, // 0 + DCD_EVENT_BUS_RESET, // 1 + DCD_EVENT_UNPLUGGED, // 2 + DCD_EVENT_SOF, // 3 + DCD_EVENT_SUSPEND, // 4 TODO LPM Sleep L1 support + DCD_EVENT_RESUME, // 5 + DCD_EVENT_SETUP_RECEIVED, // 6 + DCD_EVENT_XFER_COMPLETE, // 7 + USBD_EVENT_FUNC_CALL, // 8 Not an DCD event, just a convenient way to defer ISR function DCD_EVENT_COUNT } dcd_eventid_t; -typedef struct TU_ATTR_ALIGNED(4) -{ +typedef struct TU_ATTR_ALIGNED(4) { uint8_t rhport; uint8_t event_id; - union - { + union { // BUS RESET struct { tusb_speed_t speed; @@ -103,11 +88,30 @@ typedef struct TU_ATTR_ALIGNED(4) //TU_VERIFY_STATIC(sizeof(dcd_event_t) <= 12, "size is not correct"); //--------------------------------------------------------------------+ +// Memory API +//--------------------------------------------------------------------+ + +// clean/flush data cache: write cache -> memory. +// Required before an DMA TX transfer to make sure data is in memory +bool dcd_dcache_clean(const void* addr, uint32_t data_size); + +// invalidate data cache: mark cache as invalid, next read will read from memory +// Required BOTH before and after an DMA RX transfer +bool dcd_dcache_invalidate(const void* addr, uint32_t data_size); + +// clean and invalidate data cache +// Required before an DMA transfer where memory is both read/write by DMA +bool dcd_dcache_clean_invalidate(const void* addr, uint32_t data_size); + +//--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ // Initialize controller to device mode -void dcd_init (uint8_t rhport); +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init); + +// Deinitialize controller, unset device mode. +bool dcd_deinit(uint8_t rhport); // Interrupt Handler void dcd_int_handler(uint8_t rhport); @@ -125,21 +129,25 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr); void dcd_remote_wakeup(uint8_t rhport); // Connect by enabling internal pull-up resistor on D+/D- -void dcd_connect(uint8_t rhport) TU_ATTR_WEAK; +void dcd_connect(uint8_t rhport); // Disconnect by disabling internal pull-up resistor on D+/D- -void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK; +void dcd_disconnect(uint8_t rhport); // Enable/Disable Start-of-frame interrupt. Default is disabled void dcd_sof_enable(uint8_t rhport, bool en); +#if CFG_TUD_TEST_MODE +// Put device into a test mode (needs power cycle to quit) +void dcd_enter_test_mode(uint8_t rhport, tusb_feature_test_mode_t test_selector); +#endif //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ // Invoked when a control transfer's status stage is complete. // May help DCD to prepare for next control transfer, this API is optional. -void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) TU_ATTR_WEAK; +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request); // Configure endpoint's registers according to descriptor bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_ep); @@ -149,10 +157,6 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc // required for multiple configuration support. void dcd_edpt_close_all (uint8_t rhport); -// Close an endpoint. -// Since it is weak, caller must TU_ASSERT this function's existence before calling it. -void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) TU_ATTR_WEAK; - // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes); @@ -167,6 +171,20 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr); // This API never calls with control endpoints, since it is auto cleared when receiving setup packet void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr); +#ifdef TUP_DCD_EDPT_ISO_ALLOC +// Allocate packet buffer used by ISO endpoints +// Some MCU need manual packet buffer allocation, we allocate the largest size to avoid clustering +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size); + +// Configure and enable an ISO endpoint according to descriptor +bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep); + +#else +// Close an endpoint. +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr); + +#endif + //--------------------------------------------------------------------+ // Event API (implemented by stack) //--------------------------------------------------------------------+ @@ -175,44 +193,46 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr); extern void dcd_event_handler(dcd_event_t const * event, bool in_isr); // helper to send bus signal event -TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) -{ - dcd_event_t event = { .rhport = rhport, .event_id = eid }; +TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) { + dcd_event_t event; + event.rhport = rhport; + event.event_id = eid; dcd_event_handler(&event, in_isr); } // helper to send bus reset event -TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr) -{ - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_BUS_RESET }; +TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr) { + dcd_event_t event; + event.rhport = rhport; + event.event_id = DCD_EVENT_BUS_RESET; event.bus_reset.speed = speed; dcd_event_handler(&event, in_isr); } // helper to send setup received -TU_ATTR_ALWAYS_INLINE static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr) -{ - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED }; - memcpy(&event.setup_received, setup, 8); - +TU_ATTR_ALWAYS_INLINE static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr) { + dcd_event_t event; + event.rhport = rhport; + event.event_id = DCD_EVENT_SETUP_RECEIVED; + memcpy(&event.setup_received, setup, sizeof(tusb_control_request_t)); dcd_event_handler(&event, in_isr); } // helper to send transfer complete event -TU_ATTR_ALWAYS_INLINE static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr) -{ - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE }; - +TU_ATTR_ALWAYS_INLINE static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr) { + dcd_event_t event; + event.rhport = rhport; + event.event_id = DCD_EVENT_XFER_COMPLETE; event.xfer_complete.ep_addr = ep_addr; event.xfer_complete.len = xferred_bytes; event.xfer_complete.result = result; - dcd_event_handler(&event, in_isr); } -static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_isr) -{ - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SOF }; +TU_ATTR_ALWAYS_INLINE static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_isr) { + dcd_event_t event; + event.rhport = rhport; + event.event_id = DCD_EVENT_SOF; event.sof.frame_count = frame_count; dcd_event_handler(&event, in_isr); } @@ -221,4 +241,4 @@ static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_i } #endif -#endif /* _TUSB_DCD_H_ */ +#endif |
