/****************************************************************************** * The MIT License * * Copyright (c) 2011 LeafLabs, LLC. * * 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. *****************************************************************************/ #include #include #ifndef _USB_REG_MAP_H_ #define _USB_REG_MAP_H_ /* TODO: * - Pick one of "endp", "ep" "endpt" */ /* * Register map and base pointer */ #define USB_NR_EP_REGS 8 /** USB register map type */ typedef struct usb_reg_map { __io uint32 EP[USB_NR_EP_REGS]; /**< Endpoint registers */ const uint32 RESERVED[8]; /**< Reserved */ __io uint32 CNTR; /**< Control register */ __io uint32 ISTR; /**< Interrupt status register */ __io uint32 FNR; /**< Frame number register */ __io uint32 DADDR; /**< Device address */ __io uint32 BTABLE; /**< @brief Buffer table address * * Address offset within the USB * packet memory area which points * to the base of the buffer * descriptor table. Must be * aligned to an 8 byte boundary. */ } usb_reg_map; /** USB register map base pointer */ #define USB_BASE ((struct usb_reg_map*)0x40005C00) /* * Register bit definitions */ /* Endpoint registers (USB_EPnR) */ #define USB_EP_CTR_RX_BIT 15 #define USB_EP_DTOG_RX_BIT 14 #define USB_EP_SETUP_BIT 11 #define USB_EP_EP_KIND_BIT 8 #define USB_EP_CTR_TX_BIT 7 #define USB_EP_DTOG_TX_BIT 6 #define USB_EP_CTR_RX BIT(USB_EP_CTR_RX_BIT) #define USB_EP_DTOG_RX BIT(USB_EP_DTOG_RX_BIT) #define USB_EP_STAT_RX (0x3 << 12) #define USB_EP_STAT_RX_DISABLED (0x0 << 12) #define USB_EP_STAT_RX_STALL (0x1 << 12) #define USB_EP_STAT_RX_NAK (0x2 << 12) #define USB_EP_STAT_RX_VALID (0x3 << 12) #define USB_EP_SETUP BIT(USB_EP_SETUP_BIT) #define USB_EP_EP_TYPE (0x3 << 9) #define USB_EP_EP_TYPE_BULK (0x0 << 9) #define USB_EP_EP_TYPE_CONTROL (0x1 << 9) #define USB_EP_EP_TYPE_ISO (0x2 << 9) #define USB_EP_EP_TYPE_INTERRUPT (0x3 << 9) #define USB_EP_EP_KIND BIT(USB_EP_EP_KIND_BIT) #define USB_EP_CTR_TX BIT(USB_EP_CTR_TX_BIT) #define USB_EP_DTOG_TX BIT(USB_EP_DTOG_TX_BIT) #define USB_EP_STAT_TX (0x3 << 4) #define USB_EP_STAT_TX_DISABLED (0x0 << 4) #define USB_EP_STAT_TX_STALL (0x1 << 4) #define USB_EP_STAT_TX_NAK (0x2 << 4) #define USB_EP_STAT_TX_VALID (0x3 << 4) #define USB_EP_EA 0xF /* Control register (USB_CNTR) */ #define USB_CNTR_CTRM_BIT 15 #define USB_CNTR_PMAOVERM_BIT 14 #define USB_CNTR_ERRM_BIT 13 #define USB_CNTR_WKUPM_BIT 12 #define USB_CNTR_SUSPM_BIT 11 #define USB_CNTR_RESETM_BIT 10 #define USB_CNTR_SOFM_BIT 9 #define USB_CNTR_ESOFM_BIT 8 #define USB_CNTR_RESUME_BIT 4 #define USB_CNTR_FSUSP_BIT 3 #define USB_CNTR_LP_MODE_BIT 2 #define USB_CNTR_PDWN_BIT 1 #define USB_CNTR_FRES_BIT 0 #define USB_CNTR_CTRM BIT(USB_CNTR_CTRM_BIT) #define USB_CNTR_PMAOVERM BIT(USB_CNTR_PMAOVERM_BIT) #define USB_CNTR_ERRM BIT(USB_CNTR_ERRM_BIT) #define USB_CNTR_WKUPM BIT(USB_CNTR_WKUPM_BIT) #define USB_CNTR_SUSPM BIT(USB_CNTR_SUSPM_BIT) #define USB_CNTR_RESETM BIT(USB_CNTR_RESETM_BIT) #define USB_CNTR_SOFM BIT(USB_CNTR_SOFM_BIT) #define USB_CNTR_ESOFM BIT(USB_CNTR_ESOFM_BIT) #define USB_CNTR_RESUME BIT(USB_CNTR_RESUME_BIT) #define USB_CNTR_FSUSP BIT(USB_CNTR_FSUSP_BIT) #define USB_CNTR_LP_MODE BIT(USB_CNTR_LP_MODE_BIT) #define USB_CNTR_PDWN BIT(USB_CNTR_PDWN_BIT) #define USB_CNTR_FRES BIT(USB_CNTR_FRES_BIT) /* Interrupt status register (USB_ISTR) */ #define USB_ISTR_CTR_BIT 15 #define USB_ISTR_PMAOVR_BIT 14 #define USB_ISTR_ERR_BIT 13 #define USB_ISTR_WKUP_BIT 12 #define USB_ISTR_SUSP_BIT 11 #define USB_ISTR_RESET_BIT 10 #define USB_ISTR_SOF_BIT 9 #define USB_ISTR_ESOF_BIT 8 #define USB_ISTR_DIR_BIT 4 #define USB_ISTR_CTR BIT(USB_ISTR_CTR_BIT) #define USB_ISTR_PMAOVR BIT(USB_ISTR_PMAOVR_BIT) #define USB_ISTR_ERR BIT(USB_ISTR_ERR_BIT) #define USB_ISTR_WKUP BIT(USB_ISTR_WKUP_BIT) #define USB_ISTR_SUSP BIT(USB_ISTR_SUSP_BIT) #define USB_ISTR_RESET BIT(USB_ISTR_RESET_BIT) #define USB_ISTR_SOF BIT(USB_ISTR_SOF_BIT) #define USB_ISTR_ESOF BIT(USB_ISTR_ESOF_BIT) #define USB_ISTR_DIR BIT(USB_ISTR_DIR_BIT) #define USB_ISTR_EP_ID 0xF /* Frame number register (USB_FNR) */ #define USB_FNR_RXDP_BIT 15 #define USB_FNR_RXDM_BIT 14 #define USB_FNR_LCK_BIT 13 #define USB_FNR_RXDP BIT(USB_FNR_RXDP_BIT) #define USB_FNR_RXDM BIT(USB_FNR_RXDM_BIT) #define USB_FNR_LCK BIT(USB_FNR_LCK_BIT) #define USB_FNR_LSOF (0x3 << 11) #define USB_FNR_FN 0x7FF /* Device address (USB_DADDR) */ #define USB_DADDR_EF_BIT 7 #define USB_DADDR_ADD6_BIT 6 #define USB_DADDR_ADD5_BIT 5 #define USB_DADDR_ADD4_BIT 4 #define USB_DADDR_ADD3_BIT 3 #define USB_DADDR_ADD2_BIT 2 #define USB_DADDR_ADD1_BIT 1 #define USB_DADDR_ADD0_BIT 0 #define USB_DADDR_EF BIT(USB_DADDR_EF_BIT) #define USB_DADDR_ADD6 BIT(USB_DADDR_ADD6_BIT) #define USB_DADDR_ADD5 BIT(USB_DADDR_ADD5_BIT) #define USB_DADDR_ADD4 BIT(USB_DADDR_ADD4_BIT) #define USB_DADDR_ADD3 BIT(USB_DADDR_ADD3_BIT) #define USB_DADDR_ADD2 BIT(USB_DADDR_ADD2_BIT) #define USB_DADDR_ADD1 BIT(USB_DADDR_ADD1_BIT) #define USB_DADDR_ADD0 BIT(USB_DADDR_ADD0_BIT) /* Buffer table address (USB_BTABLE) */ #define USB_BTABLE_BTABLE (0x1FFF << 3) /* * Register convenience routines */ #define __EP_CTR_NOP (USB_EP_CTR_RX | USB_EP_CTR_TX) #define __EP_NONTOGGLE (USB_EP_CTR_RX | USB_EP_SETUP | \ USB_EP_EP_TYPE | USB_EP_EP_KIND | \ USB_EP_CTR_TX | USB_EP_EA) static inline void usb_clear_ctr_rx(uint8 ep) { uint32 epr = USB_BASE->EP[ep]; USB_BASE->EP[ep] = epr & ~USB_EP_CTR_RX & __EP_NONTOGGLE; } static inline void usb_clear_ctr_tx(uint8 ep) { uint32 epr = USB_BASE->EP[ep]; USB_BASE->EP[ep] = epr & ~USB_EP_CTR_TX & __EP_NONTOGGLE; } static inline void usb_set_ep_rx_stat(uint8 ep, uint32 status) { uint32 epr = USB_BASE->EP[ep]; epr &= ~(USB_EP_STAT_TX | USB_EP_DTOG_RX | USB_EP_DTOG_TX); epr |= __EP_CTR_NOP; epr ^= status; USB_BASE->EP[ep] = epr; } static inline void usb_set_ep_tx_stat(uint8 ep, uint32 status) { uint32 epr = USB_BASE->EP[ep]; epr &= ~(USB_EP_STAT_RX | USB_EP_DTOG_RX | USB_EP_DTOG_TX); epr |= __EP_CTR_NOP; epr ^= status; USB_BASE->EP[ep] = epr; } static inline void usb_set_ep_type(uint8 ep, uint32 type) { uint32 epr = USB_BASE->EP[ep]; epr &= ~USB_EP_EP_TYPE & __EP_NONTOGGLE; epr |= type; USB_BASE->EP[ep] = epr; } static inline void usb_set_ep_kind(uint8 ep, uint32 kind) { uint32 epr = USB_BASE->EP[ep]; epr &= ~USB_EP_EP_KIND & __EP_NONTOGGLE; epr |= kind; USB_BASE->EP[ep] = epr; } static inline void usb_clear_status_out(uint8 ep) { usb_set_ep_kind(ep, 0); } /* * Packet memory area (PMA) base pointer */ /** * @brief USB packet memory area (PMA) base pointer. * * The USB PMA is SRAM shared between USB and CAN. The USB peripheral * accesses this memory directly via the packet buffer interface. */ #define USB_PMA_BASE ((__io void*)0x40006000) /* * PMA conveniences */ void usb_copy_to_pma(const uint8 *buf, uint16 len, uint16 pma_offset); void usb_copy_from_pma(uint8 *buf, uint16 len, uint16 pma_offset); static inline void* usb_pma_ptr(uint32 offset) { return (void*)(USB_PMA_BASE + 2 * offset); } /* * BTABLE */ /* (Forward-declared) BTABLE entry. * * The BTABLE can be viewed as an array of usb_btable_ent values; * these vary in structure according to the configuration of the * endpoint. */ union usb_btable_ent; /* Bidirectional endpoint BTABLE entry */ typedef struct usb_btable_bidi { __io uint16 addr_tx; const uint16 PAD1; __io uint16 count_tx; const uint16 PAD2; __io uint16 addr_rx; const uint16 PAD3; __io uint16 count_rx; const uint16 PAD4; } usb_btable_bidi; /* Unidirectional receive-only endpoint BTABLE entry */ typedef struct usb_btable_uni_rx { __io uint16 empty1; const uint16 PAD1; __io uint16 empty2; const uint16 PAD2; __io uint16 addr_rx; const uint16 PAD3; __io uint16 count_rx; const uint16 PAD4; } usb_btable_uni_rx; /* Unidirectional transmit-only endpoint BTABLE entry */ typedef struct usb_btable_uni_tx { __io uint16 addr_tx; const uint16 PAD1; __io uint16 count_tx; const uint16 PAD2; __io uint16 empty1; const uint16 PAD3; __io uint16 empty2; const uint16 PAD4; } usb_btable_uni_tx; /* Double-buffered transmission endpoint BTABLE entry */ typedef struct usb_btable_dbl_tx { __io uint16 addr_tx0; const uint16 PAD1; __io uint16 count_tx0; const uint16 PAD2; __io uint16 addr_tx1; const uint16 PAD3; __io uint16 count_tx1; const uint16 PAD4; } usb_btable_dbl_tx; /* Double-buffered reception endpoint BTABLE entry */ typedef struct usb_btable_dbl_rx { __io uint16 addr_rx0; const uint16 PAD1; __io uint16 count_rx0; const uint16 PAD2; __io uint16 addr_rx1; const uint16 PAD3; __io uint16 count_rx1; const uint16 PAD4; } usb_btable_dbl_rx; /* TODO isochronous endpoint entries */ /* Definition for above forward-declared BTABLE entry. */ typedef union usb_btable_ent { usb_btable_bidi bidi; usb_btable_uni_rx u_rx; usb_btable_uni_tx u_tx; usb_btable_dbl_tx d_tx; usb_btable_dbl_rx d_rx; } usb_btable_ent; /* * BTABLE conveniences */ /* TODO (?) Convert usages of the many (and lengthily-named) * accessors/mutators below to just manipulating usb_btable_entry * values. */ static inline uint32* usb_btable_ptr(uint32 offset) { return (uint32*)usb_pma_ptr(USB_BASE->BTABLE + offset); } static inline usb_btable_ent *usb_btable(void) { return (usb_btable_ent*)usb_btable_ptr(0); } /* TX address */ static inline uint32* usb_ep_tx_addr_ptr(uint8 ep) { return usb_btable_ptr(ep * 8); } static inline uint16 usb_get_ep_tx_addr(uint8 ep) { return (uint16)*usb_ep_tx_addr_ptr(ep); } static inline void usb_set_ep_tx_addr(uint8 ep, uint16 addr) { uint32 *tx_addr = usb_ep_tx_addr_ptr(ep); *tx_addr = addr & ~0x1; } /* RX address */ static inline uint32* usb_ep_rx_addr_ptr(uint8 ep) { return usb_btable_ptr(ep * 8 + 4); } static inline uint16 usb_get_ep_rx_addr(uint8 ep) { return (uint16)*usb_ep_rx_addr_ptr(ep); } static inline void usb_set_ep_rx_addr(uint8 ep, uint16 addr) { uint32 *rx_addr = usb_ep_rx_addr_ptr(ep); *rx_addr = addr & ~0x1; } /* TX count (doesn't cover double-buffered and isochronous in) */ static inline uint32* usb_ep_tx_count_ptr(uint8 ep) { return usb_btable_ptr(ep * 8 + 2); } static inline uint16 usb_get_ep_tx_count(uint8 ep) { /* FIXME: this is broken somehow; calling it seems to * confuse/crash the chip. */ return (uint16)(*usb_ep_tx_count_ptr(ep) & 0x3FF); } static inline void usb_set_ep_tx_count(uint8 ep, uint16 count) { uint32 *txc = usb_ep_tx_count_ptr(ep); *txc = count; } /* RX count */ static inline uint32* usb_ep_rx_count_ptr(uint8 ep) { return usb_btable_ptr(ep * 8 + 6); } static inline uint16 usb_get_ep_rx_count(uint8 ep) { return (uint16)*usb_ep_rx_count_ptr(ep) & 0x3FF; } void usb_set_ep_rx_count(uint8 ep, uint16 count); /* * Misc. types */ typedef enum usb_ep { USB_EP0, USB_EP1, USB_EP2, USB_EP3, USB_EP4, USB_EP5, USB_EP6, USB_EP7, } usb_ep; typedef enum usb_ep_type { USB_EP_T_CTL = USB_EP_EP_TYPE_CONTROL, USB_EP_T_BULK = USB_EP_EP_TYPE_BULK, USB_EP_T_INT = USB_EP_EP_TYPE_INTERRUPT, USB_EP_T_ISO = USB_EP_EP_TYPE_ISO } usb_ep_type; typedef enum usb_ep_stat { USB_EP_ST_RX_DIS = USB_EP_STAT_RX_DISABLED, USB_EP_ST_RX_STL = USB_EP_STAT_RX_STALL, USB_EP_ST_RX_NAK = USB_EP_STAT_RX_NAK, USB_EP_ST_RX_VAL = USB_EP_STAT_RX_VALID, USB_EP_ST_TX_DIS = USB_EP_STAT_TX_DISABLED, USB_EP_ST_TX_STL = USB_EP_STAT_TX_STALL, USB_EP_ST_TX_NAK = USB_EP_STAT_TX_NAK, USB_EP_ST_TX_VAL = USB_EP_STAT_TX_VALID } usb_ep_stat; #endif