aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple
diff options
context:
space:
mode:
Diffstat (limited to 'libmaple')
-rw-r--r--libmaple/include/libmaple/usb_cdcacm.h22
-rw-r--r--libmaple/stm32f1/bkp.c4
-rw-r--r--libmaple/stm32f1/dma.c1
-rw-r--r--libmaple/stm32f1/include/series/dma.h10
-rw-r--r--libmaple/usb/stm32f1/usb_cdcacm.c57
-rw-r--r--libmaple/usb/stm32f1/usb_reg_map.c13
-rw-r--r--libmaple/usb/stm32f1/usb_reg_map.h230
7 files changed, 275 insertions, 62 deletions
diff --git a/libmaple/include/libmaple/usb_cdcacm.h b/libmaple/include/libmaple/usb_cdcacm.h
index 8b3c1fe..5fe832c 100644
--- a/libmaple/include/libmaple/usb_cdcacm.h
+++ b/libmaple/include/libmaple/usb_cdcacm.h
@@ -72,6 +72,27 @@ extern "C" {
#define USB_INTERFACE_SUBCLASS_CDC_ACM 0x02
#define USB_INTERFACE_CLASS_DIC 0x0A
+/*
+ * Endpoint configuration
+ */
+
+#define USB_CDCACM_CTRL_ENDP 0
+#define USB_CDCACM_CTRL_RX_ADDR 0x40
+#define USB_CDCACM_CTRL_TX_ADDR 0x80
+#define USB_CDCACM_CTRL_EPSIZE 0x40
+
+#define USB_CDCACM_TX_ENDP 1
+#define USB_CDCACM_TX_ADDR 0xC0
+#define USB_CDCACM_TX_EPSIZE 0x40
+
+#define USB_CDCACM_MANAGEMENT_ENDP 2
+#define USB_CDCACM_MANAGEMENT_ADDR 0x100
+#define USB_CDCACM_MANAGEMENT_EPSIZE 0x40
+
+#define USB_CDCACM_RX_ENDP 3
+#define USB_CDCACM_RX_ADDR 0x110
+#define USB_CDCACM_RX_EPSIZE 0x40
+
#ifndef __cplusplus
#define USB_CDCACM_DECLARE_DEV_DESC(vid, pid) \
{ \
@@ -106,6 +127,7 @@ uint32 usb_cdcacm_peek(uint8* buf, uint32 len);
uint32 usb_cdcacm_data_available(void); /* in RX buffer */
uint16 usb_cdcacm_get_pending(void);
+uint8 usb_cdcacm_is_transmitting(void);
uint8 usb_cdcacm_get_dtr(void);
uint8 usb_cdcacm_get_rts(void);
diff --git a/libmaple/stm32f1/bkp.c b/libmaple/stm32f1/bkp.c
index f435ff1..01ad419 100644
--- a/libmaple/stm32f1/bkp.c
+++ b/libmaple/stm32f1/bkp.c
@@ -62,14 +62,14 @@ void bkp_init(void) {
* @see bkp_init()
*/
void bkp_enable_writes(void) {
- *bb_perip(&PWR_BASE->CR, PWR_CR_DBP) = 1;
+ *bb_perip(&PWR_BASE->CR, PWR_CR_DBP_BIT) = 1;
}
/**
* Disable write access to the backup registers.
*/
void bkp_disable_writes(void) {
- *bb_perip(&PWR_BASE->CR, PWR_CR_DBP) = 0;
+ *bb_perip(&PWR_BASE->CR, PWR_CR_DBP_BIT) = 0;
}
/**
diff --git a/libmaple/stm32f1/dma.c b/libmaple/stm32f1/dma.c
index 5364a04..6400d15 100644
--- a/libmaple/stm32f1/dma.c
+++ b/libmaple/stm32f1/dma.c
@@ -145,6 +145,7 @@ static int config_to_per(dma_tube_reg_map *chregs, dma_tube_config *cfg) {
cfg->tube_src_size, cfg->tube_flags & DMA_CFG_SRC_INC,
cfg->tube_dst_size, cfg->tube_flags & DMA_CFG_DST_INC,
(cfg_ccr_flags(cfg->tube_flags) | DMA_CCR_DIR_FROM_MEM));
+ chregs->CNDTR = cfg->tube_nr_xfers;
chregs->CMAR = (uint32)cfg->tube_src;
chregs->CPAR = (uint32)cfg->tube_dst;
return DMA_TUBE_CFG_SUCCESS;
diff --git a/libmaple/stm32f1/include/series/dma.h b/libmaple/stm32f1/include/series/dma.h
index 3b19e2b..bedb602 100644
--- a/libmaple/stm32f1/include/series/dma.h
+++ b/libmaple/stm32f1/include/series/dma.h
@@ -145,6 +145,16 @@ typedef struct dma_tube_reg_map {
/* Interrupt status register */
+#define DMA_ISR_TEIF_BIT 3
+#define DMA_ISR_HTIF_BIT 2
+#define DMA_ISR_TCIF_BIT 1
+#define DMA_ISR_GIF_BIT 0
+
+#define DMA_ISR_TEIF (1 << DMA_ISR_TEIF_BIT)
+#define DMA_ISR_HTIF (1 << DMA_ISR_HTIF_BIT)
+#define DMA_ISR_TCID (1 << DMA_ISR_TCIF_BIT)
+#define DMA_ISR_GIF (1 << DMA_ISR_GIF_BIT)
+
#define DMA_ISR_TEIF7_BIT 27
#define DMA_ISR_HTIF7_BIT 26
#define DMA_ISR_TCIF7_BIT 25
diff --git a/libmaple/usb/stm32f1/usb_cdcacm.c b/libmaple/usb/stm32f1/usb_cdcacm.c
index addab3c..d4d4262 100644
--- a/libmaple/usb/stm32f1/usb_cdcacm.c
+++ b/libmaple/usb/stm32f1/usb_cdcacm.c
@@ -82,27 +82,6 @@ static void usbSetConfiguration(void);
static void usbSetDeviceAddress(void);
/*
- * Endpoint configuration
- */
-
-#define USB_CDCACM_CTRL_ENDP 0
-#define USB_CDCACM_CTRL_RX_ADDR 0x40
-#define USB_CDCACM_CTRL_TX_ADDR 0x80
-#define USB_CDCACM_CTRL_EPSIZE 0x40
-
-#define USB_CDCACM_TX_ENDP 1
-#define USB_CDCACM_TX_ADDR 0xC0
-#define USB_CDCACM_TX_EPSIZE 0x40
-
-#define USB_CDCACM_MANAGEMENT_ENDP 2
-#define USB_CDCACM_MANAGEMENT_ADDR 0x100
-#define USB_CDCACM_MANAGEMENT_EPSIZE 0x40
-
-#define USB_CDCACM_RX_ENDP 3
-#define USB_CDCACM_RX_ADDR 0x110
-#define USB_CDCACM_RX_EPSIZE 0x40
-
-/*
* Descriptors
*/
@@ -288,6 +267,8 @@ static volatile uint8 vcomBufferRx[USB_CDCACM_RX_EPSIZE];
static volatile uint32 rx_offset = 0;
/* Number of bytes left to transmit */
static volatile uint32 n_unsent_bytes = 0;
+/* Are we currently sending an IN packet? */
+static volatile uint8 transmitting = 0;
/* Number of unread bytes */
static volatile uint32 n_unread_bytes = 0;
@@ -328,16 +309,19 @@ static void (*ep_int_out[7])(void) =
/*
* Globals required by usb_lib/
+ *
+ * Mark these weak so they can be overriden to implement other USB
+ * functionality.
*/
#define NUM_ENDPTS 0x04
-DEVICE Device_Table = {
+__weak DEVICE Device_Table = {
.Total_Endpoint = NUM_ENDPTS,
.Total_Configuration = 1
};
#define MAX_PACKET_SIZE 0x40 /* 64B, maximum for USB FS Devices */
-DEVICE_PROP Device_Property = {
+__weak DEVICE_PROP Device_Property = {
.Init = usbInit,
.Reset = usbReset,
.Process_Status_IN = NOP_Process,
@@ -352,7 +336,7 @@ DEVICE_PROP Device_Property = {
.MaxPacketSize = MAX_PACKET_SIZE
};
-USER_STANDARD_REQUESTS User_Standard_Requests = {
+__weak USER_STANDARD_REQUESTS User_Standard_Requests = {
.User_GetConfiguration = NOP_Process,
.User_SetConfiguration = usbSetConfiguration,
.User_GetInterface = NOP_Process,
@@ -413,7 +397,7 @@ void usb_cdcacm_putc(char ch) {
* buffer, and returns the number of bytes copied. */
uint32 usb_cdcacm_tx(const uint8* buf, uint32 len) {
/* Last transmission hasn't finished, so abort. */
- if (n_unsent_bytes) {
+ if (usb_cdcacm_is_transmitting()) {
return 0;
}
@@ -425,10 +409,14 @@ uint32 usb_cdcacm_tx(const uint8* buf, uint32 len) {
/* Queue bytes for sending. */
if (len) {
usb_copy_to_pma(buf, len, USB_CDCACM_TX_ADDR);
- usb_set_ep_tx_count(USB_CDCACM_TX_ENDP, len);
- n_unsent_bytes = len;
- usb_set_ep_tx_stat(USB_CDCACM_TX_ENDP, USB_EP_STAT_TX_VALID);
}
+ // We still need to wait for the interrupt, even if we're sending
+ // zero bytes. (Sending zero-size packets is useful for flushing
+ // host-side buffers.)
+ usb_set_ep_tx_count(USB_CDCACM_TX_ENDP, len);
+ n_unsent_bytes = len;
+ transmitting = 1;
+ usb_set_ep_tx_stat(USB_CDCACM_TX_ENDP, USB_EP_STAT_TX_VALID);
return len;
}
@@ -437,7 +425,11 @@ uint32 usb_cdcacm_data_available(void) {
return n_unread_bytes;
}
-uint16 usb_cdcacm_get_pending() {
+uint8 usb_cdcacm_is_transmitting(void) {
+ return transmitting;
+}
+
+uint16 usb_cdcacm_get_pending(void) {
return n_unsent_bytes;
}
@@ -518,12 +510,8 @@ int usb_cdcacm_get_n_data_bits(void) {
*/
static void vcomDataTxCb(void) {
- /* The following assumes that all of the bytes we copied during
- * the last call to usb_cdcacm_tx were sent during the IN
- * transaction (this seems to be the case). */
- /* TODO find out why this is broken:
- * n_unsent_bytes = usb_get_ep_tx_count(USB_CDCACM_TX_ENDP); */
n_unsent_bytes = 0;
+ transmitting = 0;
}
static void vcomDataRxCb(void) {
@@ -621,6 +609,7 @@ static void usbReset(void) {
n_unread_bytes = 0;
n_unsent_bytes = 0;
rx_offset = 0;
+ transmitting = 0;
}
static RESULT usbDataSetup(uint8 request) {
diff --git a/libmaple/usb/stm32f1/usb_reg_map.c b/libmaple/usb/stm32f1/usb_reg_map.c
index 75562e1..ea60cb3 100644
--- a/libmaple/usb/stm32f1/usb_reg_map.c
+++ b/libmaple/usb/stm32f1/usb_reg_map.c
@@ -58,8 +58,7 @@ void usb_copy_from_pma(uint8 *buf, uint16 len, uint16 pma_offset) {
}
}
-void usb_set_ep_rx_count(uint8 ep, uint16 count) {
- uint32 *rxc = usb_ep_rx_count_ptr(ep);
+static void usb_set_ep_rx_count_common(uint32 *rxc, uint16 count) {
uint16 nblocks;
if (count > 62) {
/* use 32-byte memory block size */
@@ -77,3 +76,13 @@ void usb_set_ep_rx_count(uint8 ep, uint16 count) {
*rxc = nblocks << 10;
}
}
+
+void usb_set_ep_rx_buf0_count(uint8 ep, uint16 count) {
+ uint32 *rxc = usb_ep_rx_buf0_count_ptr(ep);
+ usb_set_ep_rx_count_common(rxc, count);
+}
+
+void usb_set_ep_rx_count(uint8 ep, uint16 count) {
+ uint32 *rxc = usb_ep_rx_count_ptr(ep);
+ usb_set_ep_rx_count_common(rxc, count);
+}
diff --git a/libmaple/usb/stm32f1/usb_reg_map.h b/libmaple/usb/stm32f1/usb_reg_map.h
index ea483d2..2e3f6bc 100644
--- a/libmaple/usb/stm32f1/usb_reg_map.h
+++ b/libmaple/usb/stm32f1/usb_reg_map.h
@@ -88,6 +88,7 @@ typedef struct usb_reg_map {
#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_EP_KIND_DBL_BUF (0x1 << 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)
@@ -205,6 +206,86 @@ static inline void usb_clear_ctr_tx(uint8 ep) {
USB_BASE->EP[ep] = epr & ~USB_EP_CTR_TX & __EP_NONTOGGLE;
}
+static inline uint32 usb_get_ep_dtog_tx(uint8 ep) {
+ uint32 epr = USB_BASE->EP[ep];
+ return epr & USB_EP_DTOG_TX;
+}
+
+static inline uint32 usb_get_ep_dtog_rx(uint8 ep) {
+ uint32 epr = USB_BASE->EP[ep];
+ return epr & USB_EP_DTOG_RX;
+}
+
+static inline uint32 usb_get_ep_tx_sw_buf(uint8 ep) {
+ return usb_get_ep_dtog_rx(ep);
+}
+
+static inline uint32 usb_get_ep_rx_sw_buf(uint8 ep) {
+ return usb_get_ep_dtog_tx(ep);
+}
+
+static inline void usb_toggle_ep_dtog_tx(uint8 ep) {
+ uint32 epr = USB_BASE->EP[ep];
+ epr &= __EP_NONTOGGLE;
+ epr |= USB_EP_DTOG_TX;
+ USB_BASE->EP[ep] = epr;
+}
+
+static inline void usb_toggle_ep_dtog_rx(uint8 ep) {
+ uint32 epr = USB_BASE->EP[ep];
+ epr &= __EP_NONTOGGLE;
+ epr |= USB_EP_DTOG_RX;
+ USB_BASE->EP[ep] = epr;
+}
+
+static inline void usb_clear_ep_dtog_tx(uint8 ep) {
+ if (usb_get_ep_dtog_tx(ep) != 0) {
+ usb_toggle_ep_dtog_tx(ep);
+ }
+}
+
+static inline void usb_clear_ep_dtog_rx(uint8 ep) {
+ if (usb_get_ep_dtog_rx(ep) != 0) {
+ usb_toggle_ep_dtog_rx(ep);
+ }
+}
+
+static inline void usb_set_ep_dtog_tx(uint8 ep) {
+ if (usb_get_ep_dtog_tx(ep) == 0) {
+ usb_toggle_ep_dtog_tx(ep);
+ }
+}
+
+static inline void usb_set_ep_dtog_rx(uint8 ep) {
+ if (usb_get_ep_dtog_rx(ep) == 0) {
+ usb_toggle_ep_dtog_rx(ep);
+ }
+}
+
+static inline void usb_toggle_ep_rx_sw_buf(uint8 ep) {
+ usb_toggle_ep_dtog_tx(ep);
+}
+
+static inline void usb_toggle_ep_tx_sw_buf(uint8 ep) {
+ usb_toggle_ep_dtog_rx(ep);
+}
+
+static inline void usb_clear_ep_rx_sw_buf(uint8 ep) {
+ usb_clear_ep_dtog_tx(ep);
+}
+
+static inline void usb_clear_ep_tx_sw_buf(uint8 ep) {
+ usb_clear_ep_dtog_rx(ep);
+}
+
+static inline void usb_set_ep_rx_sw_buf(uint8 ep) {
+ usb_set_ep_dtog_tx(ep);
+}
+
+static inline void usb_set_ep_tx_sw_buf(uint8 ep) {
+ usb_set_ep_dtog_rx(ep);
+}
+
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);
@@ -235,6 +316,17 @@ static inline void usb_set_ep_kind(uint8 ep, uint32 kind) {
USB_BASE->EP[ep] = epr;
}
+static inline uint32 usb_get_ep_type(uint8 ep) {
+ uint32 epr = USB_BASE->EP[ep];
+ return epr & USB_EP_EP_TYPE;
+}
+
+static inline uint32 usb_get_ep_kind(uint8 ep) {
+ uint32 epr = USB_BASE->EP[ep];
+ return epr & USB_EP_EP_TYPE;
+}
+
+
static inline void usb_clear_status_out(uint8 ep) {
usb_set_ep_kind(ep, 0);
}
@@ -275,42 +367,42 @@ 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;
+ __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;
+ __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;
+ __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;
+ __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;
+ __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 */
@@ -336,10 +428,6 @@ 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) {
@@ -399,6 +487,100 @@ static inline uint16 usb_get_ep_rx_count(uint8 ep) {
void usb_set_ep_rx_count(uint8 ep, uint16 count);
+/* double buffer definitions */
+static inline uint32* usb_get_ep_tx_buf0_addr_ptr(uint8 ep) {
+ return usb_ep_tx_addr_ptr(ep);
+}
+
+static inline uint16 usb_get_ep_tx_buf0_addr(uint8 ep) {
+ return usb_get_ep_tx_addr(ep);
+}
+
+static inline void usb_set_ep_tx_buf0_addr(uint8 ep, uint16 addr) {
+ usb_set_ep_tx_addr(ep, addr);
+}
+
+static inline uint32* usb_get_ep_tx_buf1_addr_ptr(uint8 ep) {
+ return usb_ep_rx_addr_ptr(ep);
+}
+
+static inline uint16 usb_get_ep_tx_buf1_addr(uint8 ep) {
+ return usb_get_ep_rx_addr(ep);
+}
+
+static inline void usb_set_ep_tx_buf1_addr(uint8 ep, uint16 addr) {
+ usb_set_ep_rx_addr(ep, addr);
+}
+
+static inline uint32* usb_ep_tx_buf0_count_ptr(uint8 ep) {
+ return usb_ep_tx_count_ptr(ep);
+}
+
+static inline uint16 usb_get_ep_tx_buf0_count(uint8 ep) {
+ return usb_get_ep_tx_count(ep);
+}
+
+static inline void usb_set_ep_tx_buf0_count(uint8 ep, uint16 count) {
+ usb_set_ep_tx_count(ep, count);
+}
+
+static inline uint32* usb_ep_tx_buf1_count_ptr(uint8 ep) {
+ return usb_ep_rx_count_ptr(ep);
+}
+
+static inline uint16 usb_get_ep_tx_buf1_count(uint8 ep) {
+ return usb_get_ep_rx_count(ep);
+}
+
+static inline void usb_set_ep_tx_buf1_count(uint8 ep, uint16 count) {
+ usb_set_ep_rx_count(ep, count);
+}
+static inline uint32* usb_get_ep_rx_buf0_addr_ptr(uint8 ep) {
+ return usb_ep_tx_addr_ptr(ep);
+}
+
+static inline uint16 usb_get_ep_rx_buf0_addr(uint8 ep) {
+ return usb_get_ep_tx_addr(ep);
+}
+
+static inline void usb_set_ep_rx_buf0_addr(uint8 ep, uint16 addr) {
+ usb_set_ep_tx_addr(ep, addr);
+}
+
+static inline uint32* usb_get_ep_rx_buf1_addr_ptr(uint8 ep) {
+ return usb_ep_rx_addr_ptr(ep);
+}
+
+static inline uint16 usb_get_ep_rx_buf1_addr(uint8 ep) {
+ return usb_get_ep_rx_addr(ep);
+}
+
+static inline void usb_set_ep_rx_buf1_addr(uint8 ep, uint16 addr) {
+ usb_set_ep_rx_addr(ep, addr);
+}
+
+static inline uint32* usb_ep_rx_buf0_count_ptr(uint8 ep) {
+ return usb_ep_tx_count_ptr(ep);
+}
+
+static inline uint16 usb_get_ep_rx_buf0_count(uint8 ep) {
+ return usb_get_ep_tx_count(ep);
+}
+
+void usb_set_ep_rx_buf0_count(uint8 ep, uint16 count);
+
+static inline uint32* usb_ep_rx_buf1_count_ptr(uint8 ep) {
+ return usb_ep_rx_count_ptr(ep);
+}
+
+static inline uint16 usb_get_ep_rx_buf1_count(uint8 ep) {
+ return usb_get_ep_rx_count(ep);
+}
+
+static inline void usb_set_ep_rx_buf1_count(uint8 ep, uint16 count) {
+ usb_set_ep_rx_count(ep, count);
+}
+
/*
* Misc. types
*/