summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--openpcd/firmware/src/pcd_enumerate.c162
-rw-r--r--openpcd/firmware/src/pcd_enumerate.h49
2 files changed, 90 insertions, 121 deletions
diff --git a/openpcd/firmware/src/pcd_enumerate.c b/openpcd/firmware/src/pcd_enumerate.c
index dd0ba48..d0edc60 100644
--- a/openpcd/firmware/src/pcd_enumerate.c
+++ b/openpcd/firmware/src/pcd_enumerate.c
@@ -1,26 +1,23 @@
-//*----------------------------------------------------------------------------
-//* ATMEL Microcontroller Software Support - ROUSSET -
-//*----------------------------------------------------------------------------
-//* The software is delivered "AS IS" without warranty or condition of any
-//* kind, either express, implied or statutory. This includes without
-//* limitation any warranty or condition with respect to merchantability or
-//* fitness for any particular purpose, or against the infringements of
-//* intellectual property rights of others.
-//*----------------------------------------------------------------------------
-//* File Name : cdc_enumerate.c
-//* Object : Handle CDC enumeration
-//*
-//* 1.0 Apr 20 200 : ODi Creation
-//* 1.1 14/Sep/2004 JPP : Minor change
-//* 1.1 15/12/2004 JPP : suppress warning
-//*----------------------------------------------------------------------------
-
-// 12. Apr. 2006: added modification found in the mikrocontroller.net gcc-Forum
-// additional line marked with /* +++ */
+/* AT91SAM7 USB interface code for OpenPCD
+ *
+ * (C) 2006 by Harald Welte <laforge@gnumonks.org>
+ *
+ * based on existing AT91SAM7 UDP CDC ACM example code, licensed as followed:
+ *----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support - ROUSSET -
+ *----------------------------------------------------------------------------
+ * The software is delivered "AS IS" without warranty or condition of any
+ * kind, either express, implied or statutory. This includes without
+ * limitation any warranty or condition with respect to merchantability or
+ * fitness for any particular purpose, or against the infringements of
+ * intellectual property rights of others.
+ *----------------------------------------------------------------------------
+ */
#include <errno.h>
-#include <sys/types.h>
#include <usb_ch9.h>
+#include <sys/types.h>
+#include <asm/atomic.h>
#include <lib_AT91SAM7.h>
#include <openpcd.h>
@@ -28,12 +25,31 @@
#include "openpcd.h"
#include "dbgu.h"
-static struct _AT91S_CDC pCDC;
-static AT91PS_CDC pCdc = &pCDC;
+#define AT91C_EP_OUT 1
+#define AT91C_EP_OUT_SIZE 0x40
+#define AT91C_EP_IN 2
+#define AT91C_EP_IN_SIZE 0x40
+#define AT91C_EP_INT 3
+
+struct ep_ctx {
+ atomic_t pkts_in_transit;
+ void *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];
+};
+
+
+static struct udp_pcd upcd;
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-struct usb_device_descriptor devDescriptor = {
+struct usb_device_descriptor dev_descriptor = {
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = 0x0200,
@@ -56,7 +72,7 @@ struct _desc {
struct usb_endpoint_descriptor ep[3];
};
-const struct _desc cfgDescriptor = {
+const struct _desc cfg_descriptor = {
.ucfg = {
.bLength = USB_DT_CONFIG_SIZE,
.bDescriptorType = USB_DT_CONFIG,
@@ -85,21 +101,21 @@ const struct _desc cfgDescriptor = {
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = OPENPCD_OUT_EP,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = 64,
+ .wMaxPacketSize = AT91C_EP_OUT_SIZE,
.bInterval = 0x00,
}, {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = OPENPCD_IN_EP,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = 64,
+ .wMaxPacketSize = AT91C_EP_IN_SIZE,
.bInterval = 0x00,
}, {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = OPENPCD_IRQ_EP,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = 64,
+ .wMaxPacketSize = AT91C_EP_IN_SIZE,
.bInterval = 0xff, /* FIXME */
},
},
@@ -132,16 +148,16 @@ static void udp_ep0_handler(void);
void udp_unthrottle(void)
{
- AT91PS_UDP pUDP = pCDC.pUdp;
+ AT91PS_UDP pUDP = upcd.pUdp;
pUDP->UDP_IER = AT91C_UDP_EPINT1;
}
int udp_refill_ep(int ep, struct req_ctx *rctx)
{
u_int16_t i;
- AT91PS_UDP pUDP = pCDC.pUdp;
+ AT91PS_UDP pUDP = upcd.pUdp;
- if (rctx->tx.tot_len > 64) {
+ if (rctx->tx.tot_len > AT91C_EP_IN_SIZE) {
DEBUGPCRF("TOO LARGE!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
return -EINVAL;
}
@@ -149,17 +165,17 @@ int udp_refill_ep(int ep, struct req_ctx *rctx)
DEBUGP("refilling EP%u ", ep);
/* FIXME: state machine to handle two banks of FIFO memory, etc */
- if (atomic_read(&pCDC.ep[ep].pkts_in_transit) >= 2)
+ 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(&pCDC.ep[ep].pkts_in_transit) == 0) {
+ if (atomic_read(&upcd.ep[ep].pkts_in_transit) == 0) {
/* start transmit */
pUDP->UDP_CSR[ep] |= AT91C_UDP_TXPKTRDY;
- atomic_inc(&pCDC.ep[ep].pkts_in_transit);
+ atomic_inc(&upcd.ep[ep].pkts_in_transit);
}
/* return rctx to pool of free contexts */
@@ -171,7 +187,7 @@ int udp_refill_ep(int ep, struct req_ctx *rctx)
static void udp_irq(void)
{
u_int32_t csr;
- AT91PS_UDP pUDP = pCDC.pUdp;
+ AT91PS_UDP pUDP = upcd.pUdp;
AT91_REG isr = pUDP->UDP_ISR;
DEBUGP("udp_irq(imr=0x%04x, isr=0x%04x): ", pUDP->UDP_IMR, isr);
@@ -180,14 +196,14 @@ static void udp_irq(void)
DEBUGP("ENDBUSRES ");
pUDP->UDP_ICR = AT91C_UDP_ENDBUSRES;
pUDP->UDP_IER = AT91C_UDP_EPINT0;
- // reset all endpoints
+ /* reset all endpoints */
pUDP->UDP_RSTEP = (unsigned int)-1;
pUDP->UDP_RSTEP = 0;
- // Enable the function
+ /* Enable the function */
pUDP->UDP_FADDR = AT91C_UDP_FEN;
- // Configure endpoint 0
+ /* Configure endpoint 0 */
pUDP->UDP_CSR[0] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);
- pCDC.currentConfiguration = 0; /* +++ */
+ upcd.cur_config = 0;
}
if (isr & AT91C_UDP_EPINT0) {
@@ -195,7 +211,7 @@ static void udp_irq(void)
udp_ep0_handler();
}
if (isr & AT91C_UDP_EPINT1) {
- u_int32_t cur_rcv_bank = pCDC.currentRcvBank;
+ u_int32_t cur_rcv_bank = upcd.cur_rcv_bank;
csr = pUDP->UDP_CSR[1];
DEBUGP("EP1INT(Out, CSR=0x%08x) ", csr);
if (cur_rcv_bank == AT91C_UDP_RX_DATA_BK1)
@@ -225,11 +241,7 @@ static void udp_irq(void)
cur_rcv_bank = AT91C_UDP_RX_DATA_BK1;
else
cur_rcv_bank = AT91C_UDP_RX_DATA_BK0;
-#if 0
- rctx->rx.data[MAX_REQSIZE+MAX_HDRSIZE-1] = '\0';
- DEBUGP(rctx->rx.data);
-#endif
- pCDC.currentRcvBank = cur_rcv_bank;
+ upcd.cur_rcv_bank = cur_rcv_bank;
req_ctx_set_state(rctx, RCTX_STATE_UDP_RCV_DONE);
DEBUGP("RCTX=%u ", req_ctx_num(rctx));
} else {
@@ -251,7 +263,7 @@ static void udp_irq(void)
while (pUDP->UDP_CSR[2] & AT91C_UDP_TXCOMP) ;
/* if we already have another packet in DPR, send it */
- if (atomic_dec_return(&pCDC.ep[2].pkts_in_transit) == 1)
+ if (atomic_dec_return(&upcd.ep[2].pkts_in_transit) == 1)
pUDP->UDP_CSR[2] |= AT91C_UDP_TXPKTRDY;
/* try to re-fill from pending rcts for EP2 */
@@ -301,13 +313,13 @@ static void udp_irq(void)
}
/* Open USB Device Port */
-static AT91PS_CDC AT91F_PCD_Open(AT91PS_UDP pUdp)
+static int udp_open(AT91PS_UDP pUdp)
{
DEBUGPCRF("entering");
- pCdc->pUdp = pUdp;
- pCdc->currentConfiguration = 0;
- pCdc->currentConnection = 0;
- pCdc->currentRcvBank = AT91C_UDP_RX_DATA_BK0;
+ 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,
OPENPCD_IRQ_PRIO_UDP,
@@ -316,9 +328,7 @@ static AT91PS_CDC AT91F_PCD_Open(AT91PS_UDP pUdp)
/* End-of-Bus-Reset is always enabled */
- DEBUGPCRF("returning after enabling UDP irq");
-
- return pCdc;
+ return 0;
}
void udp_init(void)
@@ -337,20 +347,20 @@ void udp_init(void)
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, OPENPCD_PIO_UDP_PUP);
/* CDC Open by structure initialization */
- AT91F_PCD_Open(AT91C_BASE_UDP);
+ udp_open(AT91C_BASE_UDP);
}
+#if 0
/* Test if the device is configured and handle enumeration */
u_int8_t udp_is_configured(void)
{
- return pCdc->currentConfiguration;
+ return upcd.cur_config;
}
-
/* Send data through endpoint 2/3 */
u_int32_t AT91F_UDP_Write(u_int8_t irq, const unsigned char *pData, u_int32_t length)
{
- AT91PS_UDP pUdp = pCdc->pUdp;
+ AT91PS_UDP pUdp = upcd.pUdp;
u_int32_t cpt = 0;
u_int8_t ep;
@@ -361,8 +371,8 @@ u_int32_t AT91F_UDP_Write(u_int8_t irq, const unsigned char *pData, u_int32_t le
else
ep = 2;
- // Send the first packet
- cpt = MIN(length, 64);
+ /* Send the first packet */
+ cpt = MIN(length, AT91C_EP_IN_SIZE);
length -= cpt;
while (cpt--)
pUdp->UDP_FDR[ep] = *pData++;
@@ -371,13 +381,13 @@ u_int32_t AT91F_UDP_Write(u_int8_t irq, const unsigned char *pData, u_int32_t le
while (length) {
DEBUGPCRF("sending further packet");
- // Fill the second bank
- cpt = MIN(length, 64);
+ /* Fill the second bank */
+ cpt = MIN(length, AT91C_EP_IN_SIZE);
length -= cpt;
while (cpt--)
pUdp->UDP_FDR[ep] = *pData++;
DEBUGPCRF("waiting for end of further packet");
- // Wait for the the first bank to be sent
+ /* Wait for the the first bank to be sent */
while (!(pUdp->UDP_CSR[ep] & AT91C_UDP_TXCOMP))
if (!udp_is_configured()) {
DEBUGPCRF("return(!configured)");
@@ -387,7 +397,7 @@ u_int32_t AT91F_UDP_Write(u_int8_t irq, const unsigned char *pData, u_int32_t le
while (pUdp->UDP_CSR[ep] & AT91C_UDP_TXCOMP) ;
pUdp->UDP_CSR[ep] |= AT91C_UDP_TXPKTRDY;
}
- // Wait for the end of transfer
+ /* Wait for the end of transfer */
DEBUGPCRF("waiting for end of transfer");
while (!(pUdp->UDP_CSR[ep] & AT91C_UDP_TXCOMP))
if (!udp_is_configured()) {
@@ -400,6 +410,7 @@ u_int32_t AT91F_UDP_Write(u_int8_t irq, const unsigned char *pData, u_int32_t le
DEBUGPCRF("return(normal, len=%u)", length);
return length;
}
+#endif
/* Send Data through the control endpoint */
static void udp_ep0_send_data(AT91PS_UDP pUdp, const char *pData, u_int32_t length)
@@ -425,7 +436,7 @@ static void udp_ep0_send_data(AT91PS_UDP pUdp, const char *pData, u_int32_t leng
do {
csr = pUdp->UDP_CSR[0];
- // Data IN stage has been stopped by a status OUT
+ /* 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 ");
@@ -462,7 +473,7 @@ static void udp_ep0_send_stall(AT91PS_UDP pUdp)
/* Handle requests on the USB Control Endpoint */
static void udp_ep0_handler(void)
{
- AT91PS_UDP pUDP = pCdc->pUdp;
+ AT91PS_UDP pUDP = upcd.pUdp;
u_int8_t bmRequestType, bRequest;
u_int16_t wValue, wIndex, wLength, wStatus;
u_int32_t csr = pUDP->UDP_CSR[0];
@@ -500,16 +511,17 @@ static void udp_ep0_handler(void)
pUDP->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP;
while ((pUDP->UDP_CSR[0] & AT91C_UDP_RXSETUP)) ;
- // Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1
+ /* Handle supported standard device request Cf Table 9-3 in USB
+ * specification Rev 1.1 */
switch ((bRequest << 8) | bmRequestType) {
case STD_GET_DESCRIPTOR:
DEBUGP("GET_DESCRIPTOR ");
- if (wValue == 0x100) // Return Device Descriptor
- udp_ep0_send_data(pUDP, (const char *) &devDescriptor,
- MIN(sizeof(devDescriptor), wLength));
- else if (wValue == 0x200) // Return Configuration Descriptor
- udp_ep0_send_data(pUDP, (const char *) &cfgDescriptor,
- MIN(sizeof(cfgDescriptor), wLength));
+ if (wValue == 0x100) /* Return Device Descriptor */
+ udp_ep0_send_data(pUDP, (const char *) &dev_descriptor,
+ MIN(sizeof(dev_descriptor), wLength));
+ else if (wValue == 0x200) /* Return Configuration Descriptor */
+ udp_ep0_send_data(pUDP, (const char *) &cfg_descriptor,
+ MIN(sizeof(cfg_descriptor), wLength));
else
udp_ep0_send_stall(pUDP);
break;
@@ -523,7 +535,7 @@ static void udp_ep0_handler(void)
DEBUGP("SET_CONFIG ");
if (wValue)
DEBUGP("VALUE!=0 ");
- pCdc->currentConfiguration = wValue;
+ upcd.cur_config = wValue;
udp_ep0_send_zlp(pUDP);
pUDP->UDP_GLBSTATE =
(wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;
@@ -539,8 +551,8 @@ static void udp_ep0_handler(void)
break;
case STD_GET_CONFIGURATION:
DEBUGP("GET_CONFIG ");
- udp_ep0_send_data(pUDP, (char *)&(pCdc->currentConfiguration),
- sizeof(pCdc->currentConfiguration));
+ udp_ep0_send_data(pUDP, (char *)&(upcd.cur_config),
+ sizeof(upcd.cur_config));
break;
case STD_GET_STATUS_ZERO:
DEBUGP("GET_STATUS_ZERO ");
diff --git a/openpcd/firmware/src/pcd_enumerate.h b/openpcd/firmware/src/pcd_enumerate.h
index d08ba65..aa007de 100644
--- a/openpcd/firmware/src/pcd_enumerate.h
+++ b/openpcd/firmware/src/pcd_enumerate.h
@@ -1,55 +1,12 @@
-//*----------------------------------------------------------------------------
-//* ATMEL Microcontroller Software Support - ROUSSET -
-//*----------------------------------------------------------------------------
-//* The software is delivered "AS IS" without warranty or condition of any
-//* kind, either express, implied or statutory. This includes without
-//* limitation any warranty or condition with respect to merchantability or
-//* fitness for any particular purpose, or against the infringements of
-//* intellectual property rights of others.
-//*----------------------------------------------------------------------------
-//* File Name : cdc_enumerate.h
-//* Object : Handle CDC enumeration
-//*
-//* 1.0 Apr 20 200 : ODi Creation
-//*----------------------------------------------------------------------------
-#ifndef PCD_ENUMERATE_H
-#define PCD_ENUMERATE_H
+#ifndef _OPCD_USB_H
+#define _OPCD_USB_H
#include <sys/types.h>
-#include <AT91SAM7.h>
-#include <asm/atomic.h>
#include "src/openpcd.h"
-#define AT91C_EP_OUT 1
-#define AT91C_EP_OUT_SIZE 0x40
-#define AT91C_EP_IN 2
-#define AT91C_EP_IN_SIZE 0x40
-#define AT91C_EP_INT 3
-
-struct ep_ctx {
- atomic_t pkts_in_transit;
- void *ctx;
-};
-
-
-typedef struct _AT91S_CDC
-{
- AT91PS_UDP pUdp;
- unsigned char currentConfiguration;
- unsigned char currentConnection;
- unsigned int currentRcvBank;
- struct ep_ctx ep[4];
-} AT91S_CDC, *AT91PS_CDC;
-
-//* external function description
-
extern void udp_init(void);
-u_int8_t AT91F_UDP_IsConfigured(void);
-
-//u_int32_t AT91F_UDP_Write(u_int8_t irq, const unsigned char *pData, u_int32_t length);
-
extern int udp_refill_ep(int ep, struct req_ctx *rctx);
extern void udp_unthrottle(void);
-#endif // CDC_ENUMERATE_H
+#endif
personal git repositories of Harald Welte. Your mileage may vary