#define MUSB_HDRC_INTRTX 0x02 /* 16-bit */
#define MUSB_HDRC_INTRRX 0x04
-#define MUSB_HDRC_INTRTXE 0x06
-#define MUSB_HDRC_INTRRXE 0x08
+#define MUSB_HDRC_INTRTXE 0x06
+#define MUSB_HDRC_INTRRXE 0x08
#define MUSB_HDRC_INTRUSB 0x0a /* 8 bit */
#define MUSB_HDRC_INTRUSBE 0x0b /* 8 bit */
#define MUSB_HDRC_FRAME 0x0c /* 16-bit */
*/
/* POWER */
-#define MGC_M_POWER_ISOUPDATE 0x80
+#define MGC_M_POWER_ISOUPDATE 0x80
#define MGC_M_POWER_SOFTCONN 0x40
#define MGC_M_POWER_HSENAB 0x20
#define MGC_M_POWER_HSMODE 0x10
#define MGC_M_INTR_RESUME 0x02
#define MGC_M_INTR_RESET 0x04
#define MGC_M_INTR_BABBLE 0x04
-#define MGC_M_INTR_SOF 0x08
+#define MGC_M_INTR_SOF 0x08
#define MGC_M_INTR_CONNECT 0x10
#define MGC_M_INTR_DISCONNECT 0x20
#define MGC_M_INTR_SESSREQ 0x40
#define MGC_M_INTR_EP0 0x01 /* FOR EP0 INTERRUPT */
/* DEVCTL */
-#define MGC_M_DEVCTL_BDEVICE 0x80
+#define MGC_M_DEVCTL_BDEVICE 0x80
#define MGC_M_DEVCTL_FSDEV 0x40
#define MGC_M_DEVCTL_LSDEV 0x20
#define MGC_M_DEVCTL_VBUS 0x18
int setup_len;
int session;
- uint32_t buf[0x2000];
+ uint8_t buf[0x8000];
struct musb_ep_s {
uint16_t faddr[2];
uint8_t fifosize;
int timeout[2]; /* Always in microframes */
- uint32_t *buf[2];
+ uint8_t *buf[2];
int fifolen[2];
int fifostart[2];
int fifoaddr[2];
struct musb_ep_s *ep = s->ep + epnum;
int pid;
int total, valid = 0;
-
+ TRACE("start %d, len %d", ep->fifostart[0], ep->fifolen[0] );
ep->fifostart[0] += ep->fifolen[0];
ep->fifolen[0] = 0;
}
/* If the packet is not fully ready yet, wait for a next segment. */
- if (epnum && (ep->fifostart[0] << 2) < total)
+ if (epnum && (ep->fifostart[0]) < total)
return;
if (!valid)
- total = ep->fifostart[0] << 2;
+ total = ep->fifostart[0];
pid = USB_TOKEN_OUT;
if (!epnum && (ep->csr[0] & MGC_M_CSR0_H_SETUPPKT)) {
/* If we already have a packet, which didn't fit into the
* 64 bytes of the FIFO, only move the FIFO start and return. (Obsolete) */
if (ep->packey[1].pid == USB_TOKEN_IN && ep->status[1] >= 0 &&
- (ep->fifostart[1] << 2) + ep->rxcount <
+ (ep->fifostart[1]) + ep->rxcount <
ep->packey[1].len) {
- ep->fifostart[1] += ep->rxcount >> 2;
+ TRACE("0x%08x, %d", ep->fifostart[1], ep->rxcount );
+ ep->fifostart[1] += ep->rxcount;
ep->fifolen[1] = 0;
- ep->rxcount = MIN(ep->packey[0].len - (ep->fifostart[1] << 2),
+ ep->rxcount = MIN(ep->packey[0].len - (ep->fifostart[1]),
ep->maxp[1]);
ep->csr[1] &= ~MGC_M_RXCSR_H_REQPKT;
total, musb_rx_packet_complete, 1);
}
-static uint32_t musb_read_fifo(struct musb_ep_s *ep)
+static uint8_t musb_read_fifo(struct musb_ep_s *ep)
{
- uint32_t value;
- if (ep->fifolen[1] >= 16) {
+ uint8_t value;
+ if (ep->fifolen[1] >= 64) {
/* We have a FIFO underrun */
- printf("%s: EP FIFO is now empty, stop reading\n",
- __FUNCTION__);
+ printf("%s: EP%d FIFO is now empty, stop reading\n",
+ __FUNCTION__, ep->epnum);
return 0x00000000;
}
/* In DMA mode clear RXPKTRDY and set REQPKT automatically
ep->csr[1] &= ~MGC_M_RXCSR_FIFOFULL;
value=ep->buf[1][ep->fifostart[1] + ep->fifolen[1] ++];
- TRACE("fifo_read 0x%08x, %d", value, ep->fifolen[1] );
+ TRACE("EP%d 0x%02x, %d", ep->epnum, value, ep->fifolen[1] );
return value;
}
+static void musb_write_fifo(struct musb_ep_s *ep, uint8_t value)
+{
+ TRACE("EP%d = %02x", ep->epnum, value);
+ if (ep->fifolen[0] >= 64) {
+ /* We have a FIFO overrun */
+ printf("%s: EP%d FIFO exceeded 64 bytes, stop feeding data\n",
+ __FUNCTION__, ep->epnum);
+ return;
+ }
+
+ ep->buf[0][ep->fifostart[0] + ep->fifolen[0] ++] = value;
+ ep->csr[0] |= MGC_M_TXCSR_FIFONOTEMPTY;
+}
+
static void musb_ep_frame_cancel(struct musb_ep_s *ep, int dir)
{
if (ep->intv_timer[dir])
static uint8_t musb_busctl_readb(void *opaque, int ep, int addr)
{
struct musb_s *s = (struct musb_s *) opaque;
- TRACE("ADDR = 0x%08x", addr);
+// TRACE("ADDR = 0x%08x", addr);
switch (addr) {
/* For USB2.0 HS hubs only */
struct musb_s *s = (struct musb_s *) opaque;
int ep, i;
uint8_t ret;
- TRACE("ADDR = 0x%08x", addr);
+// TRACE("ADDR = 0x%08x", addr);
switch (addr) {
case MUSB_HDRC_FADDR:
{
struct musb_s *s = (struct musb_s *) opaque;
int ep;
- TRACE("ADDR = 0x%08x = %08x", addr, value);
+// TRACE("ADDR = 0x%08x = %08x", addr, value);
switch (addr) {
case MUSB_HDRC_FADDR:
musb_ep_writeb(s, ep, addr & 0xf, value);
break;
+ case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
+ ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
+ musb_write_fifo(s->ep + ep, value & 0xff);
+ break;
+
default:
printf("%s: unknown register at %02x\n", __FUNCTION__, (int) addr);
};
struct musb_s *s = (struct musb_s *) opaque;
int ep, i;
uint16_t ret;
- TRACE("ADDR = 0x%08x", addr);
+// TRACE("ADDR = 0x%08x", addr);
switch (addr) {
case MUSB_HDRC_INTRTX:
case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
- return musb_read_fifo(s->ep + ep);
+ return (musb_read_fifo(s->ep + ep) | musb_read_fifo(s->ep + ep) << 8);
default:
return musb_readb(s, addr) | (musb_readb(s, addr | 1) << 8);
{
struct musb_s *s = (struct musb_s *) opaque;
int ep;
- TRACE("ADDR = 0x%08x = %08x", addr, value);
+ //TRACE("ADDR = 0x%08x = %08x", addr, value);
switch (addr) {
case MUSB_HDRC_INTRTXE:
case MUSB_HDRC_TXFIFOADDR:
s->ep[s->idx].fifoaddr[0] = value;
s->ep[s->idx].buf[0] =
- s->buf + ((value << 1) & (sizeof(s->buf) / 4 - 1));
+ s->buf + ((value << 3) & 0x7ff );
+ //TRACE("TXFIFOADDR = 0x%08x, BUF %08x", value, s->ep[s->idx].buf[0]);
break;
case MUSB_HDRC_RXFIFOADDR:
s->ep[s->idx].fifoaddr[1] = value;
s->ep[s->idx].buf[1] =
- s->buf + ((value << 1) & (sizeof(s->buf) / 4 - 1));
+ s->buf + ((value << 3) & 0x7ff);
+ //TRACE("RXFIFOADDR = 0x%08x, BUF %08x", value, s->ep[s->idx].buf[1]);
break;
case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
musb_ep_writeh(s, ep, addr & 0xf, value);
break;
+ case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
+ ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
+ musb_write_fifo(s->ep + ep, value & 0xff);
+ musb_write_fifo(s->ep + ep, (value >> 8) & 0xff);
+ break;
+
default:
musb_writeb(s, addr, value & 0xff);
musb_writeb(s, addr | 1, value >> 8);
static uint32_t musb_readw(void *opaque, target_phys_addr_t addr)
{
struct musb_s *s = (struct musb_s *) opaque;
- int epnum;
+ int ep;
switch (addr) {
case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
- epnum = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
- return musb_read_fifo(s->ep + epnum);
+ ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
+ return ( musb_read_fifo(s->ep + ep) |
+ musb_read_fifo(s->ep + ep) << 8 |
+ musb_read_fifo(s->ep + ep) << 16 |
+ musb_read_fifo(s->ep + ep) << 24 );
default:
printf("%s: unknown register at %02x\n", __FUNCTION__, (int) addr);
return 0x00000000;
static void musb_writew(void *opaque, target_phys_addr_t addr, uint32_t value)
{
struct musb_s *s = (struct musb_s *) opaque;
- struct musb_ep_s *ep;
- int epnum;
- TRACE("ADDR = 0x%08x = %08x", addr, value);
+ int ep;
+// TRACE("ADDR = 0x%08x = %08x", addr, value);
switch (addr) {
case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
- epnum = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
- ep = s->ep + epnum;
-
- if (ep->fifolen[0] >= 16) {
- /* We have a FIFO overrun */
- printf("%s: EP%i FIFO exceeded 64 bytes, stop feeding data\n",
- __FUNCTION__, epnum);
- break;
- }
-
- ep->buf[0][ep->fifostart[0] + ep->fifolen[0] ++] = value;
- if (epnum)
- ep->csr[0] |= MGC_M_TXCSR_FIFONOTEMPTY;
+ ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
+ musb_write_fifo(s->ep + ep, value & 0xff);
+ musb_write_fifo(s->ep + ep, (value >> 8 ) & 0xff);
+ musb_write_fifo(s->ep + ep, (value >> 16) & 0xff);
+ musb_write_fifo(s->ep + ep, (value >> 24) & 0xff);
break;
-
default:
printf("%s: unknown register at %02x\n", __FUNCTION__, (int) addr);
};