aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple
diff options
context:
space:
mode:
Diffstat (limited to 'libmaple')
-rw-r--r--libmaple/rules.mk1
-rwxr-xr-xlibmaple/usb/usb_reg_map.c79
-rw-r--r--libmaple/usb/usb_reg_map.h433
3 files changed, 513 insertions, 0 deletions
diff --git a/libmaple/rules.mk b/libmaple/rules.mk
index 495c366..dff21b1 100644
--- a/libmaple/rules.mk
+++ b/libmaple/rules.mk
@@ -34,6 +34,7 @@ cSRCS_$(d) := adc.c \
usb/descriptors.c \
usb/usb.c \
usb/usb_callbacks.c \
+ usb/usb_reg_map.c \
usb/usb_lib/usb_core.c \
usb/usb_lib/usb_init.c \
usb/usb_lib/usb_int.c \
diff --git a/libmaple/usb/usb_reg_map.c b/libmaple/usb/usb_reg_map.c
new file mode 100755
index 0000000..75562e1
--- /dev/null
+++ b/libmaple/usb/usb_reg_map.c
@@ -0,0 +1,79 @@
+/******************************************************************************
+ * 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 "usb_reg_map.h"
+
+/* TODO these could use some improvement; they're fairly
+ * straightforward ports of the analogous ST code. The PMA blit
+ * routines in particular are obvious targets for performance
+ * measurement and tuning. */
+
+void usb_copy_to_pma(const uint8 *buf, uint16 len, uint16 pma_offset) {
+ uint16 *dst = (uint16*)usb_pma_ptr(pma_offset);
+ uint16 n = len >> 1;
+ uint16 i;
+ for (i = 0; i < n; i++) {
+ *dst = (uint16)(*buf) | *(buf + 1) << 8;
+ buf += 2;
+ dst += 2;
+ }
+ if (len & 1) {
+ *dst = *buf;
+ }
+}
+
+void usb_copy_from_pma(uint8 *buf, uint16 len, uint16 pma_offset) {
+ uint32 *src = (uint32*)usb_pma_ptr(pma_offset);
+ uint16 *dst = (uint16*)buf;
+ uint16 n = len >> 1;
+ uint16 i;
+ for (i = 0; i < n; i++) {
+ *dst++ = *src++;
+ }
+ if (len & 1) {
+ *dst = *src & 0xFF;
+ }
+}
+
+void usb_set_ep_rx_count(uint8 ep, uint16 count) {
+ uint32 *rxc = usb_ep_rx_count_ptr(ep);
+ uint16 nblocks;
+ if (count > 62) {
+ /* use 32-byte memory block size */
+ nblocks = count >> 5;
+ if ((count & 0x1F) == 0) {
+ nblocks--;
+ }
+ *rxc = (nblocks << 10) | 0x8000;
+ } else {
+ /* use 2-byte memory block size */
+ nblocks = count >> 1;
+ if ((count & 0x1) != 0) {
+ nblocks++;
+ }
+ *rxc = nblocks << 10;
+ }
+}
diff --git a/libmaple/usb/usb_reg_map.h b/libmaple/usb/usb_reg_map.h
new file mode 100644
index 0000000..5bf5d96
--- /dev/null
+++ b/libmaple/usb/usb_reg_map.h
@@ -0,0 +1,433 @@
+/******************************************************************************
+ * 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 "libmaple_types.h"
+#include "util.h"
+
+#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) {
+ return (uint16)*usb_ep_tx_count_ptr(ep);
+}
+
+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