 83f1d660ce
			
		
	
	83f1d660ce
	
	
	
		
			
			add some doxygen work finalize device disconnection & suspend - suspend & resume & remote wake up is not supported yet
		
			
				
	
	
		
			244 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			244 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /**************************************************************************/
 | |
| /*!
 | |
|     @file     dcd_lpc175x_6x.h
 | |
|     @author   hathach (tinyusb.org)
 | |
| 
 | |
|     @section LICENSE
 | |
| 
 | |
|     Software License Agreement (BSD License)
 | |
| 
 | |
|     Copyright (c) 2013, hathach (tinyusb.org)
 | |
|     All rights reserved.
 | |
| 
 | |
|     Redistribution and use in source and binary forms, with or without
 | |
|     modification, are permitted provided that the following conditions are met:
 | |
|     1. Redistributions of source code must retain the above copyright
 | |
|     notice, this list of conditions and the following disclaimer.
 | |
|     2. Redistributions in binary form must reproduce the above copyright
 | |
|     notice, this list of conditions and the following disclaimer in the
 | |
|     documentation and/or other materials provided with the distribution.
 | |
|     3. Neither the name of the copyright holders nor the
 | |
|     names of its contributors may be used to endorse or promote products
 | |
|     derived from this software without specific prior written permission.
 | |
| 
 | |
|     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
 | |
|     EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | |
|     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | |
|     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
 | |
|     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | |
|     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | |
|     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 | |
|     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
|     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | |
|     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| 
 | |
|     This file is part of the tinyusb stack.
 | |
| */
 | |
| /**************************************************************************/
 | |
| 
 | |
| /** \ingroup Port_DCD
 | |
|  * @{
 | |
|  *  \defgroup LPC175x_6x
 | |
|  *  @{
 | |
|  */
 | |
| 
 | |
| 
 | |
| #ifndef _TUSB_DCD_LPC175X_6X_H_
 | |
| #define _TUSB_DCD_LPC175X_6X_H_
 | |
| 
 | |
| #include "common/common.h"
 | |
| 
 | |
| #ifdef __cplusplus
 | |
|  extern "C" {
 | |
| #endif
 | |
| 
 | |
| 
 | |
| typedef struct ATTR_ALIGNED(4)
 | |
| {
 | |
| 	//------------- Word 0 -------------//
 | |
| 	uint32_t next;
 | |
| 
 | |
| 	//------------- Word 1 -------------//
 | |
| 	uint16_t mode            : 2; // either 00 normal or 01 ATLE(auto length extraction)
 | |
| 	uint16_t is_next_valid   : 1;
 | |
| 	uint16_t used            : 1; ///< make use of reserved bit
 | |
| 	uint16_t is_isochronous  : 1; // is an iso endpoint
 | |
| 	uint16_t max_packet_size : 11;
 | |
| 	volatile uint16_t buffer_length;
 | |
| 
 | |
| 	//------------- Word 2 -------------//
 | |
| 	volatile uint32_t buffer_addr;
 | |
| 
 | |
| 	//------------- Word 3 -------------//
 | |
| 	volatile uint16_t is_retired                   : 1; // initialized to zero
 | |
| 	volatile uint16_t status                       : 4;
 | |
| 	volatile uint16_t iso_last_packet_valid        : 1;
 | |
| 	volatile uint16_t atle_is_lsb_extracted        : 1;	// used in ATLE mode
 | |
| 	volatile uint16_t atle_is_msb_extracted        : 1;	// used in ATLE mode
 | |
| 	volatile uint16_t atle_message_length_position : 6; // used in ATLE mode
 | |
| 	uint16_t                                       : 2;
 | |
| 	volatile uint16_t present_count; // The number of bytes transferred by the DMA engine. The DMA engine updates this field after completing each packet transfer.
 | |
| 
 | |
| 	//------------- Word 4 -------------//
 | |
| //	uint32_t iso_packet_size_addr;		// iso only, can be omitted for non-iso
 | |
| }dcd_dma_descriptor_t;
 | |
| 
 | |
| STATIC_ASSERT( sizeof(dcd_dma_descriptor_t) == 16, "size is not correct"); // TODO not support ISO for now
 | |
| 
 | |
| 
 | |
| //--------------------------------------------------------------------+
 | |
| // Register Interface
 | |
| //--------------------------------------------------------------------+
 | |
| 
 | |
| //------------- USB Interrupt USBIntSt -------------//
 | |
| //enum {
 | |
| //  DCD_USB_REQ_LOW_PRIO_MASK   = BIT_(0),
 | |
| //  DCD_USB_REQ_HIGH_PRIO_MASK  = BIT_(1),
 | |
| //  DCD_USB_REQ_DMA_MASK        = BIT_(2),
 | |
| //  DCD_USB_REQ_NEED_CLOCK_MASK = BIT_(8),
 | |
| //  DCD_USB_REQ_ENABLE_MASK     = BIT_(31)
 | |
| //};
 | |
| 
 | |
| //------------- Device Interrupt USBDevInt -------------//
 | |
| enum {
 | |
|   DEV_INT_FRAME_MASK              = BIT_(0),
 | |
|   DEV_INT_ENDPOINT_FAST_MASK      = BIT_(1),
 | |
|   DEV_INT_ENDPOINT_SLOW_MASK      = BIT_(2),
 | |
|   DEV_INT_DEVICE_STATUS_MASK      = BIT_(3),
 | |
|   DEV_INT_COMMAND_CODE_EMPTY_MASK = BIT_(4),
 | |
|   DEV_INT_COMMAND_DATA_FULL_MASK  = BIT_(5),
 | |
|   DEV_INT_RX_ENDPOINT_PACKET_MASK = BIT_(6),
 | |
|   DEV_INT_TX_ENDPOINT_PACKET_MASK = BIT_(7),
 | |
|   DEV_INT_ENDPOINT_REALIZED_MASK  = BIT_(8),
 | |
|   DEV_INT_ERROR_MASK              = BIT_(9)
 | |
| };
 | |
| 
 | |
| //------------- DMA Interrupt USBDMAInt-------------//
 | |
| enum {
 | |
|   DMA_INT_END_OF_XFER_MASK    = BIT_(0),
 | |
|   DMA_INT_NEW_DD_REQUEST_MASK = BIT_(1),
 | |
|   DMA_INT_ERROR_MASK          = BIT_(2)
 | |
| };
 | |
| 
 | |
| //------------- USBCtrl -------------//
 | |
| enum {
 | |
|   USBCTRL_READ_ENABLE_MASK  = BIT_(0),
 | |
|   USBCTRL_WRITE_ENABLE_MASK = BIT_(1),
 | |
| };
 | |
| 
 | |
| //------------- USBRxPLen -------------//
 | |
| enum {
 | |
|   USBRXPLEN_PACKET_LENGTH_MASK = (BIT_(10)-1),
 | |
|   USBRXPLEN_DATA_VALID_MASK    = BIT_(10),
 | |
|   USBRXPLEN_PACKET_READY_MASK  = BIT_(11),
 | |
| };
 | |
| 
 | |
| //------------- SIE Command Code -------------//
 | |
| typedef enum {
 | |
|   SIE_CMDPHASE_WRITE   = 1,
 | |
|   SIE_CMDPHASE_READ    = 2,
 | |
|   SIE_CMDPHASE_COMMAND = 5
 | |
| } sie_cmdphase_t;
 | |
| 
 | |
| enum {
 | |
|   // device commands
 | |
|   SIE_CMDCODE_SET_ADDRESS                     = 0xd0,
 | |
|   SIE_CMDCODE_CONFIGURE_DEVICE                = 0xd8,
 | |
|   SIE_CMDCODE_SET_MODE                        = 0xf3,
 | |
|   SIE_CMDCODE_READ_FRAME_NUMBER               = 0xf5,
 | |
|   SIE_CMDCODE_READ_TEST_REGISTER              = 0xfd,
 | |
|   SIE_CMDCODE_DEVICE_STATUS                   = 0xfe,
 | |
|   SIE_CMDCODE_GET_ERROR                       = 0xff,
 | |
|   SIE_CMDCODE_READ_ERROR_STATUS               = 0xfb,
 | |
| 
 | |
|   // endpoint commands
 | |
|   SIE_CMDCODE_ENDPOINT_SELECT                 = 0x00, // + endpoint index
 | |
|   SIE_CMDCODE_ENDPOINT_SELECT_CLEAR_INTERRUPT = 0x40, // + endpoint index, should use USBEpIntClr instead
 | |
|   SIE_CMDCODE_ENDPOINT_SET_STATUS             = 0x40, // + endpoint index
 | |
|   SIE_CMDCODE_BUFFER_CLEAR                    = 0xf2,
 | |
|   SIE_CMDCODE_BUFFER_VALIDATE                 = 0xfa
 | |
| };
 | |
| 
 | |
| //------------- SIE Device Status (get/set from SIE_CMDCODE_DEVICE_STATUS) -------------//
 | |
| enum {
 | |
|   SIE_DEV_STATUS_CONNECT_STATUS_MASK = BIT_(0),
 | |
|   SIE_DEV_STATUS_CONNECT_CHANGE_MASK = BIT_(1),
 | |
|   SIE_DEV_STATUS_SUSPEND_MASK        = BIT_(2),
 | |
|   SIE_DEV_STATUS_SUSPEND_CHANGE_MASK = BIT_(3),
 | |
|   SIE_DEV_STATUS_RESET_MASK          = BIT_(4)
 | |
| };
 | |
| 
 | |
| //------------- SIE Select Endpoint Command -------------//
 | |
| enum {
 | |
|   SIE_SELECT_ENDPOINT_FULL_EMPTY_MASK         = BIT_(0), // 0: empty, 1 full. IN endpoint checks empty, OUT endpoint check full
 | |
|   SIE_SELECT_ENDPOINT_STALL_MASK              = BIT_(1),
 | |
|   SIE_SELECT_ENDPOINT_SETUP_RECEIVED_MASK     = BIT_(2), // clear by SIE_CMDCODE_ENDPOINT_SELECT_CLEAR_INTERRUPT
 | |
|   SIE_SELECT_ENDPOINT_PACKET_OVERWRITTEN_MASK = BIT_(3), // previous packet is overwritten by a SETUP packet
 | |
|   SIE_SELECT_ENDPOINT_NAK_MASK                = BIT_(4), // last packet response is NAK (auto clear by an ACK)
 | |
|   SIE_SELECT_ENDPOINT_BUFFER1_FULL_MASK       = BIT_(5),
 | |
|   SIE_SELECT_ENDPOINT_BUFFER2_FULL_MASK       = BIT_(6)
 | |
| };
 | |
| 
 | |
| typedef enum {
 | |
|   SIE_SET_ENDPOINT_STALLED_MASK           = BIT_(0),
 | |
|   SIE_SET_ENDPOINT_DISABLED_MASK          = BIT_(5),
 | |
|   SIE_SET_ENDPOINT_RATE_FEEDBACK_MASK     = BIT_(6),
 | |
|   SIE_SET_ENDPOINT_CONDITION_STALLED_MASK = BIT_(7),
 | |
| }sie_endpoint_set_status_mask_t;
 | |
| 
 | |
| //------------- DMA Descriptor Status -------------//
 | |
| enum {
 | |
|   DD_STATUS_NOT_SERVICED = 0,
 | |
|   DD_STATUS_BEING_SERVICED,
 | |
|   DD_STATUS_NORMAL,
 | |
|   DD_STATUS_DATA_UNDERUN, // short packet
 | |
|   DD_STATUS_DATA_OVERRUN,
 | |
|   DD_STATUS_SYSTEM_ERROR
 | |
| };
 | |
| 
 | |
| //--------------------------------------------------------------------+
 | |
| // SIE Command
 | |
| //--------------------------------------------------------------------+
 | |
| static inline void sie_cmd_code (sie_cmdphase_t phase, uint8_t code_data) ATTR_ALWAYS_INLINE;
 | |
| static inline void sie_cmd_code (sie_cmdphase_t phase, uint8_t code_data)
 | |
| {
 | |
|   LPC_USB->USBDevIntClr = (DEV_INT_COMMAND_CODE_EMPTY_MASK | DEV_INT_COMMAND_DATA_FULL_MASK);
 | |
|   LPC_USB->USBCmdCode   = (phase << 8) | (code_data << 16);
 | |
| 
 | |
|   uint32_t const wait_flag = (phase == SIE_CMDPHASE_READ) ? DEV_INT_COMMAND_DATA_FULL_MASK : DEV_INT_COMMAND_CODE_EMPTY_MASK;
 | |
| #ifndef _TEST_
 | |
|   while ((LPC_USB->USBDevIntSt & wait_flag) == 0); // TODO blocking forever potential
 | |
| #endif
 | |
|   LPC_USB->USBDevIntClr = wait_flag;
 | |
| }
 | |
| 
 | |
| static inline void sie_write (uint8_t cmd_code, uint8_t data_len, uint8_t data) ATTR_ALWAYS_INLINE;
 | |
| static inline void sie_write (uint8_t cmd_code, uint8_t data_len, uint8_t data)
 | |
| {
 | |
|   sie_cmd_code(SIE_CMDPHASE_COMMAND, cmd_code);
 | |
| 
 | |
|   if (data_len)
 | |
|   {
 | |
|     sie_cmd_code(SIE_CMDPHASE_WRITE, data);
 | |
|   }
 | |
| }
 | |
| 
 | |
| static inline uint32_t sie_read (uint8_t cmd_code, uint8_t data_len) ATTR_ALWAYS_INLINE;
 | |
| static inline uint32_t sie_read (uint8_t cmd_code, uint8_t data_len)
 | |
| {
 | |
|   // TODO multiple read
 | |
|   sie_cmd_code(SIE_CMDPHASE_COMMAND , cmd_code);
 | |
|   sie_cmd_code(SIE_CMDPHASE_READ    , cmd_code);
 | |
|   return LPC_USB->USBCmdData;
 | |
| }
 | |
| 
 | |
| #ifdef __cplusplus
 | |
|  }
 | |
| #endif
 | |
| 
 | |
| #endif /* _TUSB_DCD_LPC175X_6X_H_ */
 | |
| 
 | |
| /** @} */
 | |
| /** @} */
 | |
| 
 |