1
0
Fork 0
forked from len0rd/rockbox

Ingenic Jz4740:

* Fix compiling
 * More USB work


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19628 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Maurus Cuelenaere 2008-12-31 18:15:24 +00:00
parent a2e80d573c
commit 5bf0cf5910
2 changed files with 71 additions and 34 deletions

View file

@ -5102,32 +5102,32 @@ struct Ration2m
#define W_COEF_MSK 0xFF
// function about REG_CTRL
#define stop_ipu(IPU_V_BASE) \
#define IPU_STOP_IPU(IPU_V_BASE) \
REG32(IPU_V_BASE + REG_CTRL) &= ~IPU_EN;
#define run_ipu(IPU_V_BASE) \
#define IPU_RUN_IPU(IPU_V_BASE) \
REG32(IPU_V_BASE + REG_CTRL) |= IPU_EN;
#define reset_ipu(IPU_V_BASE) \
#define IPU_RESET_IPU(IPU_V_BASE) \
REG32(IPU_V_BASE + REG_CTRL) |= IPU_RESET;
#define disable_irq(IPU_V_BASE) \
#define IPU_DISABLE_IRQ(IPU_V_BASE) \
REG32(IPU_V_BASE + REG_CTRL) &= ~FM_IRQ_EN;
#define disable_rsize(IPU_V_BASE) \
#define IPU_DISABLE_RSIZE(IPU_V_BASE) \
REG32(IPU_V_BASE + REG_CTRL) &= ~RSZ_EN;
#define enable_rsize(IPU_V_BASE) \
#define IPU_ENABLE_RSIZE(IPU_V_BASE) \
REG32(IPU_V_BASE + REG_CTRL) |= RSZ_EN;
#define ipu_is_enable(IPU_V_BASE) \
#define IPU_IS_ENABLED(IPU_V_BASE) \
(REG32(IPU_V_BASE + REG_CTRL) & IPU_EN)
// function about REG_STATUS
#define clear_end_flag(IPU_V_BASE) \
#define IPU_CLEAR_END_FLAG(IPU_V_BASE) \
REG32(IPU_V_BASE + REG_STATUS) &= ~OUT_END;
#define polling_end_flag(IPU_V_BASE) \
#define IPU_POLLING_END_FLAG(IPU_V_BASE) \
(REG32(IPU_V_BASE + REG_STATUS) & OUT_END)
/* parameter

View file

@ -30,6 +30,12 @@
#include "jz4740.h"
#include "thread.h"
/*
The Jz4740 USB controller is called MUSBHSFC in the datasheet.
It also seems to be a more generic controller, with support for
up to 15 endpoints (the Jz4740 only has 3).
*/
#define USB_EP0_IDLE 0
#define USB_EP0_RX 1
#define USB_EP0_TX 2
@ -162,13 +168,16 @@ static void flushFIFO(struct usb_endpoint *ep)
static void EP0_send(void)
{
register struct usb_endpoint* ep = &endpoints[1];
register unsigned int length;
struct usb_endpoint* ep = &endpoints[1];
unsigned int length;
unsigned char csr0;
select_endpoint(0);
csr0 = REG_USB_REG_CSR0;
if(ep->length == 0)
{
select_endpoint(0);
REG_USB_REG_CSR0 |= (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND);
REG_USB_REG_CSR0 = (csr0 | USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND);
return;
}
@ -177,22 +186,22 @@ static void EP0_send(void)
else
length = (EP_BUF_LEFT(ep) <= ep->fifo_size ? EP_BUF_LEFT(ep) : ep->fifo_size);
select_endpoint(0);
writeFIFO(ep, length);
ep->sent += length;
if(ep->sent >= ep->length)
{
REG_USB_REG_CSR0 |= (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND); /* Set data end! */
REG_USB_REG_CSR0 = (csr0 | USB_CSR0_INPKTRDY | USB_CSR0_DATAEND); /* Set data end! */
ep0state = USB_EP0_IDLE;
}
else
REG_USB_REG_CSR0 |= USB_CSR0_INPKTRDY;
REG_USB_REG_CSR0 = (csr0 | USB_CSR0_INPKTRDY);
}
static void EP0_handler(void)
{
logf("EP0_handler");
logf("EP0_handler");
register unsigned char csr0;
/* Read CSR0 */
@ -204,7 +213,7 @@ logf("EP0_handler");
*/
if (csr0 & USB_CSR0_SENTSTALL)
{
REG_USB_REG_CSR0 &= ~USB_CSR0_SENTSTALL;
REG_USB_REG_CSR0 = csr0 & ~USB_CSR0_SENTSTALL;
ep0state = USB_EP0_IDLE;
return;
}
@ -216,7 +225,7 @@ logf("EP0_handler");
*/
if (csr0 & USB_CSR0_SETUPEND)
{
REG_USB_REG_CSR0 |= USB_CSR0_SVDSETUPEND;
REG_USB_REG_CSR0 = csr0 | USB_CSR0_SVDSETUPEND;
ep0state = USB_EP0_IDLE;
return;
}
@ -224,10 +233,10 @@ logf("EP0_handler");
/* Call relevant routines for endpoint 0 state */
if (ep0state == USB_EP0_IDLE)
{
if (csr0 & USB_CSR0_OUTPKTRDY) /* There is data in the fifo */
if(csr0 & USB_CSR0_OUTPKTRDY) /* There is data in the fifo */
{
readFIFO(&endpoints[0], REG_USB_REG_COUNT0);
REG_USB_REG_CSR0 |= USB_CSR0_SVDOUTPKTRDY; /* clear OUTPKTRDY bit */
REG_USB_REG_CSR0 = csr0 | USB_CSR0_SVDOUTPKTRDY; /* clear OUTPKTRDY bit */
usb_core_control_request((struct usb_ctrlrequest*)endpoints[0].buf);
}
}
@ -237,14 +246,15 @@ logf("EP0_handler");
static void EPIN_handler(unsigned int endpoint)
{
logf("EPIN_handler(%d)", endpoint);
logf("EPIN_handler(%d)", endpoint);
struct usb_endpoint* ep = &endpoints[endpoint*2+1];
unsigned int length, csr;
select_endpoint(endpoint);
csr = REG_USB_REG_INCSR;
if(ep->length == 0)
if(ep->buf == NULL || ep->length == 0)
{
REG_USB_REG_INCSR = csr | USB_INCSR_INPKTRDY;
return;
@ -266,19 +276,25 @@ logf("EPIN_handler(%d)", endpoint);
REG_USB_REG_INCSR = csr | USB_INCSR_INPKTRDY;
if(ep->sent >= ep->length)
usb_core_transfer_complete(endpoint|USB_DIR_IN, USB_DIR_IN, 0, ep->sent);
{
usb_core_transfer_complete(endpoint, USB_DIR_IN, 0, ep->sent);
ep->sent = 0;
ep->length = 0;
ep->buf = NULL;
}
}
static void EPOUT_handler(unsigned int endpoint)
{
logf("EPOUT_handler(%d)", endpoint);
logf("EPOUT_handler(%d)", endpoint);
struct usb_endpoint* ep = &endpoints[endpoint*2];
unsigned int size, csr;
select_endpoint(endpoint);
csr = REG_USB_REG_OUTCSR;
if(ep->buf == NULL && ep->length == 0)
if(ep->buf == NULL || ep->length == 0)
{
REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_OUTPKTRDY;
return;
@ -291,16 +307,21 @@ logf("EPOUT_handler(%d)", endpoint);
}
size = REG_USB_REG_OUTCOUNT;
ep->received += size;
readFIFO(ep, size);
ep->received += size;
REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_OUTPKTRDY;
logf("received: %d length: %d", ep->received, ep->length);
//if(ep->received >= ep->length)
usb_core_transfer_complete(endpoint|USB_DIR_OUT, USB_DIR_OUT, 0, ep->received);
if(size < ep->fifo_size || ep->received >= ep->length)
{
usb_core_transfer_complete(endpoint, USB_DIR_OUT, 0, ep->received);
ep->received = 0;
ep->length = 0;
ep->buf = NULL;
}
}
static void setup_endpoint(struct usb_endpoint *ep)
@ -351,6 +372,17 @@ static void setup_endpoint(struct usb_endpoint *ep)
static void udc_reset(void)
{
/* From the datasheet:
When a reset condition is detected on the USB, the controller performs the following actions:
* Sets FAddr to 0.
* Sets Index to 0.
* Flushes all endpoint FIFOs.
* Clears all control/status registers.
* Enables all endpoint interrupts.
* Generates a Reset interrupt.
*/
logf("udc_reset()");
register unsigned int i;
@ -371,8 +403,7 @@ static void udc_reset(void)
REG_USB_REG_FADDR = 0;
/* High speed and softconnect */
//REG_USB_REG_POWER = (USB_POWER_SOFTCONN | USB_POWER_HSENAB);
REG_USB_REG_POWER = USB_POWER_SOFTCONN;
REG_USB_REG_POWER = (USB_POWER_SOFTCONN | USB_POWER_HSENAB);
/* Enable SUSPEND */
/* REG_USB_REG_POWER |= USB_POWER_SUSPENDM; */
@ -560,6 +591,9 @@ int usb_drv_send(int endpoint, void* ptr, int length)
logf("usb_drv_send(%d, 0x%x, %d)", endpoint, (int)ptr, length);
if(endpoint == EP_CONTROL && ptr == NULL && length == 0)
return 0; /* ACK request, handled by the USB controller */
if(endpoint == EP_CONTROL)
{
flags = disable_irq_save();
@ -660,6 +694,9 @@ void usb_drv_cancel_all_transfers(void)
for(i=0; i<TOTAL_EP(); i++)
{
if(i > 2)
endpoints[i].buf = NULL;
endpoints[i].sent = 0;
endpoints[i].length = 0;