summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author(no author) <(no author)@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2006-08-23 20:29:47 +0000
committer(no author) <(no author)@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2006-08-23 20:29:47 +0000
commitcc0a7ad63f71f75972d5764ce4294f15c24c18b3 (patch)
treed5e7ee64a77f428725f13c540f882b0dd92ecb42
parent38f0dbf7f76ff2350f28e2a51702be3690fd5952 (diff)
- add support for filling second TX packet in FIFO while first is transmitting to host
- remove unneeded variable from data structure - add separate EP0 debugging definition git-svn-id: https://svn.openpcd.org:2342/trunk@127 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
-rw-r--r--openpcd/firmware/src/pcd_enumerate.c84
1 files changed, 48 insertions, 36 deletions
diff --git a/openpcd/firmware/src/pcd_enumerate.c b/openpcd/firmware/src/pcd_enumerate.c
index 982a1b8..3ac03fe 100644
--- a/openpcd/firmware/src/pcd_enumerate.c
+++ b/openpcd/firmware/src/pcd_enumerate.c
@@ -26,6 +26,7 @@
#include "dbgu.h"
//#define DEBUG_UDP_IRQ
+//#ifdef DEBUG_UDP_EP0
#define AT91C_EP_OUT 1
#define AT91C_EP_OUT_SIZE 0x40
@@ -41,7 +42,6 @@ struct ep_ctx {
struct udp_pcd {
AT91PS_UDP pUdp;
unsigned char cur_config;
- unsigned char cur_connection;
unsigned int cur_rcv_bank;
struct ep_ctx ep[4];
};
@@ -159,27 +159,27 @@ int udp_refill_ep(int ep, struct req_ctx *rctx)
u_int16_t i;
AT91PS_UDP pUDP = upcd.pUdp;
+ if (!upcd.cur_config)
+ return -ENXIO;
+
if (rctx->tx.tot_len > AT91C_EP_IN_SIZE) {
- DEBUGPCRF("TOO LARGE!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
+ DEBUGPCRF("TOO LARGE!!!!!!!!!!!!!!!!!!!!!!!!!!! (%d > %d)",
+ rctx->tx.tot_len, AT91C_EP_IN_SIZE);
return -EINVAL;
}
- DEBUGP("refilling EP%u ", ep);
-
- /* FIXME: state machine to handle two banks of FIFO memory, etc */
- if (atomic_read(&upcd.ep[ep].pkts_in_transit) >= 1)
+ if (atomic_read(&upcd.ep[ep].pkts_in_transit) == 2)
return -EBUSY;
/* fill FIFO/DPR */
for (i = 0; i < rctx->tx.tot_len; i++)
pUDP->UDP_FDR[ep] = rctx->tx.data[i];
- if (atomic_read(&upcd.ep[ep].pkts_in_transit) == 0) {
- /* start transmit */
+ if (atomic_inc_return(&upcd.ep[ep].pkts_in_transit) == 1) {
+ /* not been transmitting before, start transmit */
pUDP->UDP_CSR[ep] |= AT91C_UDP_TXPKTRDY;
- atomic_inc(&upcd.ep[ep].pkts_in_transit);
}
-
+
/* return rctx to pool of free contexts */
req_ctx_put(rctx);
@@ -280,9 +280,7 @@ static void udp_irq(void)
if (rctx)
udp_refill_ep(2, rctx);
else
- DEBUGP("NO_RCTX_pending ");
-
- /* FIXME: re-fill second packet into DPR */
+ DEBUGI("NO_RCTX_pending ");
}
}
if (isr & AT91C_UDP_EPINT3) {
@@ -326,7 +324,6 @@ static int udp_open(AT91PS_UDP pUdp)
DEBUGPCRF("entering");
upcd.pUdp = pUdp;
upcd.cur_config = 0;
- upcd.cur_connection = 0;
upcd.cur_rcv_bank = AT91C_UDP_RX_DATA_BK0;
AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_UDP,
@@ -420,13 +417,19 @@ u_int32_t AT91F_UDP_Write(u_int8_t irq, const unsigned char *pData, u_int32_t le
}
#endif
+#ifdef DEBUG_UDP_EP0
+#define DEBUGE(x, args ...) DEBUGP(x, ## args)
+#else
+#define DEBUGE(x, args ...) do { } while (0)
+#endif
+
/* Send Data through the control endpoint */
static void udp_ep0_send_data(AT91PS_UDP pUdp, const char *pData, u_int32_t length)
{
u_int32_t cpt = 0;
AT91_REG csr;
- DEBUGP("send_data: %u bytes ", length);
+ DEBUGE("send_data: %u bytes ", length);
do {
cpt = MIN(length, 8);
@@ -447,7 +450,7 @@ static void udp_ep0_send_data(AT91PS_UDP pUdp, const char *pData, u_int32_t leng
/* Data IN stage has been stopped by a status OUT */
if (csr & AT91C_UDP_RX_DATA_BK0) {
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);
- DEBUGP("stopped by status out ");
+ DEBUGE("stopped by status out ");
return;
}
} while (!(csr & AT91C_UDP_TXCOMP));
@@ -486,20 +489,26 @@ static void udp_ep0_handler(void)
u_int16_t wValue, wIndex, wLength, wStatus;
u_int32_t csr = pUDP->UDP_CSR[0];
- DEBUGP("CSR=0x%04x ", csr);
+ DEBUGE("CSR=0x%04x ", csr);
if (csr & AT91C_UDP_STALLSENT) {
- DEBUGP("ACK_STALLSENT ");
+ DEBUGE("ACK_STALLSENT ");
pUDP->UDP_CSR[0] = ~AT91C_UDP_STALLSENT;
}
if (csr & AT91C_UDP_RX_DATA_BK0) {
- DEBUGP("ACK_BANK0 ");
+ DEBUGE("ACK_BANK0 ");
pUDP->UDP_CSR[0] &= ~AT91C_UDP_RX_DATA_BK0;
}
if (!(csr & AT91C_UDP_RXSETUP)) {
- DEBUGP("no setup packet ");
+ DEBUGE("no setup packet ");
+ return;
+ }
+
+ DEBUGE("len=%d ", csr >> 16);
+ if (csr >> 16 == 0) {
+ DEBUGE("empty packet ");
return;
}
@@ -512,7 +521,10 @@ static void udp_ep0_handler(void)
wLength = (pUDP->UDP_FDR[0] & 0xFF);
wLength |= (pUDP->UDP_FDR[0] << 8);
+ DEBUGE("bmRequestType=0x%2x ", bmRequestType);
+
if (bmRequestType & 0x80) {
+ DEBUGE("DATA_IN=1 ");
pUDP->UDP_CSR[0] |= AT91C_UDP_DIR;
while (!(pUDP->UDP_CSR[0] & AT91C_UDP_DIR)) ;
}
@@ -520,10 +532,10 @@ static void udp_ep0_handler(void)
while ((pUDP->UDP_CSR[0] & AT91C_UDP_RXSETUP)) ;
/* Handle supported standard device request Cf Table 9-3 in USB
- * specification Rev 1.1 */
+ * speciication Rev 1.1 */
switch ((bRequest << 8) | bmRequestType) {
case STD_GET_DESCRIPTOR:
- DEBUGP("GET_DESCRIPTOR ");
+ DEBUGE("GET_DESCRIPTOR ");
if (wValue == 0x100) /* Return Device Descriptor */
udp_ep0_send_data(pUDP, (const char *) &dev_descriptor,
MIN(sizeof(dev_descriptor), wLength));
@@ -534,15 +546,15 @@ static void udp_ep0_handler(void)
udp_ep0_send_stall(pUDP);
break;
case STD_SET_ADDRESS:
- DEBUGP("SET_ADDRESS ");
+ DEBUGE("SET_ADDRESS ");
udp_ep0_send_zlp(pUDP);
pUDP->UDP_FADDR = (AT91C_UDP_FEN | wValue);
pUDP->UDP_GLBSTATE = (wValue) ? AT91C_UDP_FADDEN : 0;
break;
case STD_SET_CONFIGURATION:
- DEBUGP("SET_CONFIG ");
+ DEBUGE("SET_CONFIG ");
if (wValue)
- DEBUGP("VALUE!=0 ");
+ DEBUGE("VALUE!=0 ");
upcd.cur_config = wValue;
udp_ep0_send_zlp(pUDP);
pUDP->UDP_GLBSTATE =
@@ -558,22 +570,22 @@ static void udp_ep0_handler(void)
AT91C_UDP_EPINT2|AT91C_UDP_EPINT3);
break;
case STD_GET_CONFIGURATION:
- DEBUGP("GET_CONFIG ");
+ DEBUGE("GET_CONFIG ");
udp_ep0_send_data(pUDP, (char *)&(upcd.cur_config),
sizeof(upcd.cur_config));
break;
case STD_GET_STATUS_ZERO:
- DEBUGP("GET_STATUS_ZERO ");
+ DEBUGE("GET_STATUS_ZERO ");
wStatus = 0;
udp_ep0_send_data(pUDP, (char *)&wStatus, sizeof(wStatus));
break;
case STD_GET_STATUS_INTERFACE:
- DEBUGP("GET_STATUS_INTERFACE ");
+ DEBUGE("GET_STATUS_INTERFACE ");
wStatus = 0;
udp_ep0_send_data(pUDP, (char *)&wStatus, sizeof(wStatus));
break;
case STD_GET_STATUS_ENDPOINT:
- DEBUGP("GET_STATUS_ENDPOINT(EPidx=%u) ", wIndex&0x0f);
+ DEBUGE("GET_STATUS_ENDPOINT(EPidx=%u) ", wIndex&0x0f);
wStatus = 0;
wIndex &= 0x0F;
if ((pUDP->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= 3)) {
@@ -591,15 +603,15 @@ static void udp_ep0_handler(void)
udp_ep0_send_stall(pUDP);
break;
case STD_SET_FEATURE_ZERO:
- DEBUGP("SET_FEATURE_ZERO ");
+ DEBUGE("SET_FEATURE_ZERO ");
udp_ep0_send_stall(pUDP);
break;
case STD_SET_FEATURE_INTERFACE:
- DEBUGP("SET_FEATURE_INTERFACE ");
+ DEBUGE("SET_FEATURE_INTERFACE ");
udp_ep0_send_zlp(pUDP);
break;
case STD_SET_FEATURE_ENDPOINT:
- DEBUGP("SET_FEATURE_ENDPOINT ");
+ DEBUGE("SET_FEATURE_ENDPOINT ");
udp_ep0_send_zlp(pUDP);
wIndex &= 0x0F;
if ((wValue == 0) && wIndex && (wIndex <= 3)) {
@@ -609,7 +621,7 @@ static void udp_ep0_handler(void)
udp_ep0_send_stall(pUDP);
break;
case STD_CLEAR_FEATURE_ZERO:
- DEBUGP("CLEAR_FEATURE_ZERO ");
+ DEBUGE("CLEAR_FEATURE_ZERO ");
udp_ep0_send_stall(pUDP);
break;
case STD_CLEAR_FEATURE_INTERFACE:
@@ -617,7 +629,7 @@ static void udp_ep0_handler(void)
udp_ep0_send_zlp(pUDP);
break;
case STD_CLEAR_FEATURE_ENDPOINT:
- DEBUGP("CLEAR_FEATURE_ENDPOINT(EPidx=%u) ", wIndex & 0x0f);
+ DEBUGE("CLEAR_FEATURE_ENDPOINT(EPidx=%u) ", wIndex & 0x0f);
wIndex &= 0x0F;
if ((wValue == 0) && wIndex && (wIndex <= 3)) {
struct req_ctx *rctx;
@@ -657,11 +669,11 @@ static void udp_ep0_handler(void)
udp_ep0_send_stall(pUDP);
break;
case STD_SET_INTERFACE:
- DEBUGP("SET INTERFACE ");
+ DEBUGE("SET INTERFACE ");
udp_ep0_send_stall(pUDP);
break;
default:
- DEBUGP("DEFAULT(req=0x%02x, type=0x%02x) ", bRequest, bmRequestType);
+ DEBUGE("DEFAULT(req=0x%02x, type=0x%02x) ", bRequest, bmRequestType);
udp_ep0_send_stall(pUDP);
break;
}
personal git repositories of Harald Welte. Your mileage may vary