298 lines
17 KiB
C
298 lines
17 KiB
C
|
/*!
|
||
|
\file usbd_regs.h
|
||
|
\brief USB device registers
|
||
|
|
||
|
\version 2014-12-26, V1.0.0, firmware for GD32F10x
|
||
|
\version 2017-06-20, V2.0.0, firmware for GD32F10x
|
||
|
\version 2018-07-31, V2.1.0, firmware for GD32F10x
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
Copyright (c) 2018, GigaDevice Semiconductor Inc.
|
||
|
|
||
|
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 holder 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 AND CONTRIBUTORS "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 OR CONTRIBUTORS 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.
|
||
|
*/
|
||
|
|
||
|
#ifndef USBD_REGS_H
|
||
|
#define USBD_REGS_H
|
||
|
|
||
|
#include "usbd_conf.h"
|
||
|
|
||
|
/* USB device registers base address */
|
||
|
#define USBD USBD_BASE
|
||
|
#define USBD_RAM (APB1_BUS_BASE + 0x00006000U)
|
||
|
|
||
|
/* registers definitions */
|
||
|
/* common registers */
|
||
|
#define USBD_CTL (REG32(USBD + 0x40U)) /*!< control register */
|
||
|
#define USBD_INTF (REG32(USBD + 0x44U)) /*!< interrupt flag register */
|
||
|
#define USBD_STAT (REG32(USBD + 0x48U)) /*!< status register */
|
||
|
#define USBD_DADDR (REG32(USBD + 0x4CU)) /*!< device address register */
|
||
|
#define USBD_BADDR (REG32(USBD + 0x50U)) /*!< buffer address register */
|
||
|
|
||
|
/* endpoint control and status register */
|
||
|
#define USBD_EPxCS(ep_id) (REG32(USBD + (ep_id) * 4U)) /*!< endpoint x control and status register address */
|
||
|
|
||
|
/* LPM Registers */
|
||
|
#define USBD_LPMCS (REG32(USBD + 0x54U)) /*!< USBD LPM control and status register */
|
||
|
|
||
|
/* bits definitions */
|
||
|
/* USBD_CTL */
|
||
|
#define CTL_STIE BIT(15) /*!< successful transfer interrupt enable mask */
|
||
|
#define CTL_PMOUIE BIT(14) /*!< packet memory overrun/underrun interrupt enable mask */
|
||
|
#define CTL_ERRIE BIT(13) /*!< error interrupt enable mask */
|
||
|
#define CTL_WKUPIE BIT(12) /*!< wakeup interrupt enable mask */
|
||
|
#define CTL_SPSIE BIT(11) /*!< suspend state interrupt enable mask */
|
||
|
#define CTL_RSTIE BIT(10) /*!< reset interrupt enable mask */
|
||
|
#define CTL_SOFIE BIT(9) /*!< start of frame interrupt enable mask */
|
||
|
#define CTL_ESOFIE BIT(8) /*!< expected start of frame interrupt enable mask */
|
||
|
#define CTL_L1REQIE BIT(7) /*!< LPM L1 state request interrupt enable */
|
||
|
#define CTL_L1RSREQ BIT(5) /*!< LPM L1 resume request */
|
||
|
#define CTL_RSREQ BIT(4) /*!< resume request */
|
||
|
#define CTL_SETSPS BIT(3) /*!< set suspend state */
|
||
|
#define CTL_LOWM BIT(2) /*!< low-power mode at suspend state */
|
||
|
#define CTL_CLOSE BIT(1) /*!< goes to close state */
|
||
|
#define CTL_SETRST BIT(0) /*!< set USB reset */
|
||
|
|
||
|
/* USBD_INTF */
|
||
|
#define INTF_STIF BIT(15) /*!< successful transfer interrupt flag (read only bit) */
|
||
|
#define INTF_PMOUIF BIT(14) /*!< packet memory overrun/underrun interrupt flag (clear-only bit) */
|
||
|
#define INTF_ERRIF BIT(13) /*!< error interrupt flag (clear-only bit) */
|
||
|
#define INTF_WKUPIF BIT(12) /*!< wakeup interrupt flag (clear-only bit) */
|
||
|
#define INTF_SPSIF BIT(11) /*!< suspend state interrupt flag (clear-only bit) */
|
||
|
#define INTF_RSTIF BIT(10) /*!< reset interrupt flag (clear-only bit) */
|
||
|
#define INTF_SOFIF BIT(9) /*!< start of frame interrupt flag (clear-only bit) */
|
||
|
#define INTF_ESOFIF BIT(8) /*!< expected start of frame interrupt flag(clear-only bit) */
|
||
|
#define INTF_L1REQ BIT(7) /*!< LPM L1 transaction is successfully received and acknowledged */
|
||
|
#define INTF_DIR BIT(4) /*!< direction of transaction (read-only bit) */
|
||
|
#define INTF_EPNUM BITS(0, 3) /*!< endpoint number (read-only bit) */
|
||
|
|
||
|
/* USBD_STAT */
|
||
|
#define STAT_RXDP BIT(15) /*!< data plus line status */
|
||
|
#define STAT_RXDM BIT(14) /*!< data minus line status */
|
||
|
#define STAT_LOCK BIT(13) /*!< locked the USB */
|
||
|
#define STAT_SOFLN BITS(11, 12) /*!< SOF lost number */
|
||
|
#define STAT_FCNT BITS(0, 10) /*!< frame number count */
|
||
|
|
||
|
/* USBD_DADDR */
|
||
|
#define DADDR_USBEN BIT(7) /*!< USB module enable */
|
||
|
#define DADDR_USBDAR BITS(0, 6) /*!< USB device address */
|
||
|
|
||
|
/* USBD_EPxCS */
|
||
|
#define EPxCS_RX_ST BIT(15) /*!< endpoint reception successful transferred */
|
||
|
#define EPxCS_RX_DTG BIT(14) /*!< endpoint reception data PID toggle */
|
||
|
#define EPxCS_RX_STA BITS(12, 13) /*!< endpoint reception status bits */
|
||
|
#define EPxCS_SETUP BIT(11) /*!< endpoint setup transaction completed */
|
||
|
#define EPxCS_CTL BITS(9, 10) /*!< endpoint type control */
|
||
|
#define EPxCS_KCTL BIT(8) /*!< endpoint kind control */
|
||
|
#define EPxCS_TX_ST BIT(7) /*!< endpoint transmission successful transfer */
|
||
|
#define EPxCS_TX_DTG BIT(6) /*!< endpoint transmission data toggle */
|
||
|
#define EPxCS_TX_STA BITS(4, 5) /*!< endpoint transmission transfers status bits */
|
||
|
#define EPxCS_ADDR BITS(0, 3) /*!< endpoint address */
|
||
|
|
||
|
/* USBD_LPMCS */
|
||
|
#define LPMCS_BLSTAT BITS(4, 7) /*!< bLinkState value */
|
||
|
#define LPMCS_REMWK BIT(3) /*!< bRemoteWake value */
|
||
|
#define LPMCS_LPMACK BIT(1) /*!< LPM token acknowledge enable */
|
||
|
#define LPMCS_LPMEN BIT(0) /*!< LPM support enable */
|
||
|
|
||
|
/* constants definitions */
|
||
|
/* endpoint control and status register mask (no toggle fields) */
|
||
|
#define EPCS_MASK (EPxCS_RX_ST|EPxCS_SETUP|EPxCS_CTL|EPxCS_KCTL|EPxCS_TX_ST|EPxCS_ADDR)
|
||
|
|
||
|
/* EPxCS_CTL[1:0] endpoint type control */
|
||
|
#define ENDP_TYPE(regval) (EPxCS_CTL & ((regval) << 9U))
|
||
|
|
||
|
#define EP_BULK ENDP_TYPE(0U) /* bulk transfers */
|
||
|
#define EP_CONTROL ENDP_TYPE(1U) /* control transfers */
|
||
|
#define EP_ISO ENDP_TYPE(2U) /* isochronous transfers */
|
||
|
#define EP_INTERRUPT ENDP_TYPE(3U) /* interrupt transfers */
|
||
|
#define EP_CTL_MASK (~EPxCS_CTL & EPCS_MASK)
|
||
|
|
||
|
/* endpoint kind control mask */
|
||
|
#define EPKCTL_MASK (~EPxCS_KCTL & EPCS_MASK)
|
||
|
|
||
|
/* EPxCS_TX_STA[1:0] status for tx transfer */
|
||
|
#define ENDP_TXSTAT(regval) (EPxCS_TX_STA & ((regval) << 4U))
|
||
|
|
||
|
#define EPTX_DISABLED ENDP_TXSTAT(0U) /* transmission state is disabled */
|
||
|
#define EPTX_STALL ENDP_TXSTAT(1U) /* transmission state is STALL */
|
||
|
#define EPTX_NAK ENDP_TXSTAT(2U) /* transmission state is NAK */
|
||
|
#define EPTX_VALID ENDP_TXSTAT(3U) /* transmission state is enabled */
|
||
|
#define EPTX_DTGMASK (EPxCS_TX_STA | EPCS_MASK)
|
||
|
|
||
|
/* EPxCS_RX_STA[1:0] status for rx transfer */
|
||
|
#define ENDP_RXSTAT(regval) (EPxCS_RX_STA & ((regval) << 12U))
|
||
|
|
||
|
#define EPRX_DISABLED ENDP_RXSTAT(0U) /* reception state is disabled */
|
||
|
#define EPRX_STALL ENDP_RXSTAT(1U) /* reception state is STALL */
|
||
|
#define EPRX_NAK ENDP_RXSTAT(2U) /* reception state is NAK */
|
||
|
#define EPRX_VALID ENDP_RXSTAT(3U) /* reception state is enabled */
|
||
|
#define EPRX_DTGMASK (EPxCS_RX_STA | EPCS_MASK)
|
||
|
|
||
|
/* endpoint receive/transmission counter register bit definitions */
|
||
|
#define EPRCNT_BLKSIZ BIT(15) /* reception data block size */
|
||
|
#define EPRCNT_BLKNUM BITS(10, 14) /* reception data block number */
|
||
|
#define EPRCNT_CNT BITS(0, 9) /* reception data count */
|
||
|
|
||
|
#define EPTCNT_CNT BITS(0, 9) /* transmisson data count */
|
||
|
|
||
|
/* interrupt flag clear bits */
|
||
|
#define CLR_STIF (~INTF_STIF)
|
||
|
#define CLR_PMOUIF (~INTF_PMOUIF)
|
||
|
#define CLR_ERRIF (~INTF_ERRIF)
|
||
|
#define CLR_WKUPIF (~INTF_WKUPIF)
|
||
|
#define CLR_SPSIF (~INTF_SPSIF)
|
||
|
#define CLR_RSTIF (~INTF_RSTIF)
|
||
|
#define CLR_SOFIF (~INTF_SOFIF)
|
||
|
#define CLR_ESOFIF (~INTF_ESOFIF)
|
||
|
#define CLR_L1REQ (~INTF_L1REQ)
|
||
|
|
||
|
/* endpoint receive/transmission counter register bit offset */
|
||
|
#define BLKSIZE_OFFSET (0x01U)
|
||
|
#define BLKNUM_OFFSET (0x05U)
|
||
|
#define RXCNT_OFFSET (0x0AU)
|
||
|
|
||
|
#define TXCNT_OFFSET (0x0AU)
|
||
|
|
||
|
#define BLKSIZE32_MASK (0x1fU)
|
||
|
#define BLKSIZE2_MASK (0x01U)
|
||
|
|
||
|
#define BLKSIZE32_OFFSETMASK (0x05U)
|
||
|
#define BLKSIZE2_OFFSETMASK (0x01U)
|
||
|
|
||
|
/* double buffer endpoint direction */
|
||
|
typedef enum
|
||
|
{
|
||
|
DBUF_EP_IN, /* double buffer IN direction */
|
||
|
DBUF_EP_OUT, /* double buffer OUT direction */
|
||
|
DBUF_EP_ERR, /* double buffer errer direction */
|
||
|
}dbuf_ep_dir_enum;
|
||
|
|
||
|
/* endpoints address */
|
||
|
/* first bit is direction(0 for rx and 1 for tx) */
|
||
|
#define EP0_OUT ((uint8_t)0x00) /* out endpoint 0 address */
|
||
|
#define EP0_IN ((uint8_t)0x80) /* in endpoint 0 address */
|
||
|
#define EP1_OUT ((uint8_t)0x01) /* out endpoint 1 address */
|
||
|
#define EP1_IN ((uint8_t)0x81) /* in endpoint 1 address */
|
||
|
#define EP2_OUT ((uint8_t)0x02) /* out endpoint 2 address */
|
||
|
#define EP2_IN ((uint8_t)0x82) /* in endpoint 2 address */
|
||
|
#define EP3_OUT ((uint8_t)0x03) /* out endpoint 3 address */
|
||
|
#define EP3_IN ((uint8_t)0x83) /* in endpoint 3 address */
|
||
|
#define EP4_OUT ((uint8_t)0x04) /* out endpoint 4 address */
|
||
|
#define EP4_IN ((uint8_t)0x84) /* in endpoint 4 address */
|
||
|
#define EP5_OUT ((uint8_t)0x05) /* out endpoint 5 address */
|
||
|
#define EP5_IN ((uint8_t)0x85) /* in endpoint 5 address */
|
||
|
#define EP6_OUT ((uint8_t)0x06) /* out endpoint 6 address */
|
||
|
#define EP6_IN ((uint8_t)0x86) /* in endpoint 6 address */
|
||
|
#define EP7_OUT ((uint8_t)0x07) /* out endpoint 7 address */
|
||
|
#define EP7_IN ((uint8_t)0x87) /* in endpoint 7 address */
|
||
|
|
||
|
/* endpoints_identifier */
|
||
|
#define EP0 ((uint8_t)0) /* endpoint 0 ID */
|
||
|
#define EP1 ((uint8_t)1) /* endpoint 1 ID */
|
||
|
#define EP2 ((uint8_t)2) /* endpoint 2 ID */
|
||
|
#define EP3 ((uint8_t)3) /* endpoint 3 ID */
|
||
|
#define EP4 ((uint8_t)4) /* endpoint 4 ID */
|
||
|
#define EP5 ((uint8_t)5) /* endpoint 5 ID */
|
||
|
#define EP6 ((uint8_t)6) /* endpoint 6 ID */
|
||
|
#define EP7 ((uint8_t)7) /* endpoint 7 ID */
|
||
|
|
||
|
/* USBD operation macros */
|
||
|
|
||
|
/* set register value */
|
||
|
#define USBD_REG_SET(reg, regvalue) ((reg) = (uint16_t)(regvalue))
|
||
|
|
||
|
/* get register value */
|
||
|
#define USBD_REG_GET(reg) ((uint16_t)(reg))
|
||
|
|
||
|
#define _EP_ADDR_SET(ep_num, addr) USBD_REG_SET(USBD_EPxCS(ep_num), (USBD_REG_GET(USBD_EPxCS(ep_num)) & EPCS_MASK) | addr)
|
||
|
|
||
|
/* tx or rx transfer status setting (bits EPTX_STA[1:0]) */
|
||
|
#define USBD_ENDP_TX_STATUS_SET(ep_num, state) do {\
|
||
|
register uint16_t _regval; \
|
||
|
_regval = USBD_REG_GET(USBD_EPxCS(ep_num)) & (uint16_t)EPTX_DTGMASK;\
|
||
|
USBD_REG_SET(USBD_EPxCS(ep_num), ((_regval) ^ (state))); \
|
||
|
} while(0)
|
||
|
|
||
|
#define USBD_ENDP_RX_STATUS_SET(ep_num, state) do {\
|
||
|
register uint16_t _regval; \
|
||
|
_regval = USBD_REG_GET(USBD_EPxCS(ep_num)) & (uint16_t)EPRX_DTGMASK;\
|
||
|
USBD_REG_SET(USBD_EPxCS(ep_num), ((_regval) ^ (state))); \
|
||
|
} while(0)
|
||
|
|
||
|
/* tx or rx transfer status getting (bits EPxCS_RX_STA[1:0]) */
|
||
|
#define USBD_ENDP_TX_STATUS_GET(ep_num) (USBD_REG_GET(USBD_EPxCS(ep_num)) & EPxCS_TX_STA)
|
||
|
#define USBD_ENDP_RX_STATUS_GET(ep_num) (USBD_REG_GET(USBD_EPxCS(ep_num)) & EPxCS_RX_STA)
|
||
|
|
||
|
/* rx and tx transfer status setting (bits EPxCS_RX_STA[1:0] & EPxCS_TX_STA[1:0]) */
|
||
|
#define USBD_ENDP_RX_TX_STATUS_SET(ep_num, state_rx, state_tx) do {\
|
||
|
register uint16_t _regval; \
|
||
|
_regval = USBD_REG_GET(USBD_EPxCS(ep_num)) & (uint16_t)(EPRX_DTGMASK | EPxCS_TX_STA) ;\
|
||
|
USBD_REG_SET(USBD_EPxCS(ep_num), (((_regval) ^ (state_rx)) ^ (state_tx))); \
|
||
|
} while(0)
|
||
|
|
||
|
/* set and clear endpoint kind (bit EPxCS_KCTL) */
|
||
|
#define USBD_ENDP_KIND_SET(ep_num) (USBD_REG_SET(USBD_EPxCS(ep_num), ((USBD_REG_GET(USBD_EPxCS(ep_num)) | EPxCS_KCTL) & EPCS_MASK)))
|
||
|
#define USBD_ENDP_KIND_CLEAR(ep_num) (USBD_REG_SET(USBD_EPxCS(ep_num), (USBD_REG_GET(USBD_EPxCS(ep_num)) & EPKCTL_MASK)))
|
||
|
|
||
|
/* set and clear directly STATUS_OUT state of endpoint */
|
||
|
#define USBD_STATUS_OUT_SET(ep_num) USBD_ENDP_KIND_SET(ep_num)
|
||
|
#define USBD_STATUS_OUT_CLEAR(ep_num) USBD_ENDP_KIND_CLEAR(ep_num)
|
||
|
|
||
|
/* clear bit EPxCS_RX_ST/EPxCS_TX_ST in the endpoint control and status register */
|
||
|
#define USBD_ENDP_RX_STAT_CLEAR(ep_num) (USBD_REG_SET(USBD_EPxCS(ep_num), USBD_REG_GET(USBD_EPxCS(ep_num)) & 0x7FFFU & (uint16_t)EPCS_MASK))
|
||
|
#define USBD_ENDP_TX_STAT_CLEAR(ep_num) (USBD_REG_SET(USBD_EPxCS(ep_num), USBD_REG_GET(USBD_EPxCS(ep_num)) & 0xFF7FU & (uint16_t)EPCS_MASK))
|
||
|
|
||
|
/* toggle EPxCS_RX_DTG or EPxCS_TX_DTG bit in the endpoint control and status register */
|
||
|
#define USBD_DTG_RX_TOGGLE(ep_num) (USBD_REG_SET(USBD_EPxCS(ep_num), EPxCS_RX_DTG | (USBD_REG_GET(USBD_EPxCS(ep_num)) & EPCS_MASK)))
|
||
|
#define USBD_DTG_TX_TOGGLE(ep_num) (USBD_REG_SET(USBD_EPxCS(ep_num), EPxCS_TX_DTG | (USBD_REG_GET(USBD_EPxCS(ep_num)) & EPCS_MASK)))
|
||
|
|
||
|
/* clear EPxCS_RX_DTG or EPxCS_TX_DTG bit in the endpoint control and status register */
|
||
|
#define USBD_DTG_RX_CLEAR(ep_num) do {\
|
||
|
if ((USBD_REG_GET(USBD_EPxCS(ep_num)) & EPxCS_RX_DTG) != 0U) {\
|
||
|
USBD_DTG_RX_TOGGLE(ep_num);\
|
||
|
} else {\
|
||
|
}\
|
||
|
} while(0)
|
||
|
|
||
|
#define USBD_DTG_TX_CLEAR(ep_num) do {\
|
||
|
if ((USBD_REG_GET(USBD_EPxCS(ep_num)) & EPxCS_TX_DTG) != 0U) {\
|
||
|
USBD_DTG_TX_TOGGLE(ep_num);\
|
||
|
} else {\
|
||
|
}\
|
||
|
} while(0)
|
||
|
|
||
|
/* set and clear directly double buffered feature of endpoint */
|
||
|
#define USBD_ENDP_DOUBLE_BUF_SET(ep_num) USBD_ENDP_KIND_SET(ep_num)
|
||
|
#define USBD_ENDP_DOUBLE_BUF_CLEAR(ep_num) USBD_ENDP_KIND_CLEAR(ep_num)
|
||
|
|
||
|
/* toggle SW_BUF bit in the double buffered endpoint */
|
||
|
#define USBD_SWBUF_TX_TOGGLE(ep_num) USBD_DTG_RX_TOGGLE(ep_num)
|
||
|
#define USBD_SWBUF_RX_TOGGLE(ep_num) USBD_DTG_TX_TOGGLE(ep_num)
|
||
|
|
||
|
#endif /* USBD_REGS_H */
|