mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-12 06:35:22 -05:00
as3525v2-usb: rework thing, simplify
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26967 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
3603f24370
commit
c1e454d819
2 changed files with 126 additions and 154 deletions
|
|
@ -34,6 +34,18 @@
|
||||||
#define LOGF_ENABLE
|
#define LOGF_ENABLE
|
||||||
#include "logf.h"
|
#include "logf.h"
|
||||||
#include "usb-drv-as3525v2.h"
|
#include "usb-drv-as3525v2.h"
|
||||||
|
#include "usb_core.h"
|
||||||
|
|
||||||
|
static int __in_ep_list[USB_NUM_IN_EP] = {USB_IN_EP_LIST};
|
||||||
|
static int __out_ep_list[USB_NUM_OUT_EP] = {USB_OUT_EP_LIST};
|
||||||
|
|
||||||
|
/* iterate through each in/out ep except EP0
|
||||||
|
* 'counter' is the counter, 'ep' is the actual value */
|
||||||
|
#define FOR_EACH_IN_EP(counter, ep) \
|
||||||
|
for(counter = 0, ep = __in_ep_list[0]; counter < USB_NUM_IN_EP; counter++, ep = __in_ep_list[counter])
|
||||||
|
|
||||||
|
#define FOR_EACH_OUT_EP(counter, ep) \
|
||||||
|
for(counter = 0, ep = __out_ep_list[0]; counter < USB_NUM_OUT_EP; counter++, ep = __out_ep_list[counter])
|
||||||
|
|
||||||
struct usb_endpoint
|
struct usb_endpoint
|
||||||
{
|
{
|
||||||
|
|
@ -63,7 +75,10 @@ static void usb_delay(void)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while(i < 0x300)
|
while(i < 0x300)
|
||||||
|
{
|
||||||
|
asm volatile("nop");
|
||||||
i++;
|
i++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void as3525v2_connect(void)
|
static void as3525v2_connect(void)
|
||||||
|
|
@ -110,31 +125,20 @@ static void as3525v2_connect(void)
|
||||||
usb_delay();
|
usb_delay();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usb_enable_common_interrupts(void)
|
|
||||||
{
|
|
||||||
/* Clear any pending otg interrupt */
|
|
||||||
USB_GOTGINT = 0xffffffff;
|
|
||||||
/* Clear any pending interrupt */
|
|
||||||
USB_GINTSTS = 0Xffffffff;
|
|
||||||
/* Enable interrupts */
|
|
||||||
USB_GINTMSK = USB_GINTMSK_otgintr
|
|
||||||
| USB_GINTMSK_conidstschng
|
|
||||||
| USB_GINTMSK_disconnect;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void usb_enable_device_interrupts(void)
|
static void usb_enable_device_interrupts(void)
|
||||||
{
|
{
|
||||||
/* Disable all interrupts */
|
|
||||||
USB_GINTMSK = 0;
|
|
||||||
/* Clear any pending interrupt */
|
/* Clear any pending interrupt */
|
||||||
USB_GINTSTS = 0xffffffff;
|
USB_GINTSTS = 0xffffffff;
|
||||||
/* Enable common interrupts */
|
/* Clear any pending otg interrupt */
|
||||||
usb_enable_common_interrupts();
|
USB_GOTGINT = 0xffffffff;
|
||||||
/* Enable interrupts */
|
/* Enable interrupts */
|
||||||
USB_GINTMSK |= USB_GINTMSK_usbreset
|
USB_GINTMSK = USB_GINTMSK_usbreset
|
||||||
| USB_GINTMSK_enumdone
|
| USB_GINTMSK_enumdone
|
||||||
| USB_GINTMSK_inepintr
|
| USB_GINTMSK_inepintr
|
||||||
| USB_GINTMSK_outepintr;
|
| USB_GINTMSK_outepintr
|
||||||
|
| USB_GINTMSK_otgintr
|
||||||
|
| USB_GINTMSK_usbsuspend
|
||||||
|
| USB_GINTMSK_wkupintr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usb_flush_tx_fifos(int nums)
|
static void usb_flush_tx_fifos(int nums)
|
||||||
|
|
@ -184,6 +188,47 @@ static void core_reset(void)
|
||||||
udelay(1);
|
udelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void reset_endpoints(void)
|
||||||
|
{
|
||||||
|
int i, ep;
|
||||||
|
/* disable all endpoints except EP0 */
|
||||||
|
FOR_EACH_IN_EP(i, ep)
|
||||||
|
if(USB_DIEPCTL(ep) & USB_DEPCTL_epena)
|
||||||
|
USB_DIEPCTL(ep) = USB_DEPCTL_epdis | USB_DEPCTL_snak;
|
||||||
|
else
|
||||||
|
USB_DIEPCTL(ep) = 0;
|
||||||
|
|
||||||
|
FOR_EACH_OUT_EP(i, ep)
|
||||||
|
if(USB_DOEPCTL(ep) & USB_DEPCTL_epena)
|
||||||
|
USB_DOEPCTL(ep) = USB_DEPCTL_epdis | USB_DEPCTL_snak;
|
||||||
|
else
|
||||||
|
USB_DOEPCTL(ep) = 0;
|
||||||
|
/* Setup EP0 OUT with the following parameters:
|
||||||
|
* packet count = 1
|
||||||
|
* setup packet count = 1
|
||||||
|
* transfer size = 64
|
||||||
|
* Setup EP0 IN/OUT with 64 byte maximum packet size and activate both. Enable transfer on EP0 OUT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 64 bytes packet size, active endpoint */
|
||||||
|
USB_DOEPCTL(0) = USB_DEPCTL_usbactep | (USB_DEPCTL_MPS_64 << USB_DEPCTL_mps_bit_pos);
|
||||||
|
|
||||||
|
USB_DOEPTSIZ(0) = (1 << USB_DEPTSIZ0_supcnt_bit_pos)
|
||||||
|
| (1 << USB_DEPTSIZ0_pkcnt_bit_pos)
|
||||||
|
| 64;
|
||||||
|
|
||||||
|
/* setup DMA */
|
||||||
|
clean_dcache_range((void*)&ep0_setup_pkt, sizeof ep0_setup_pkt); /* force write back */
|
||||||
|
USB_DOEPDMA(0) = (unsigned long)&ep0_setup_pkt; /* virtual address=physical address */
|
||||||
|
|
||||||
|
/* Enable endpoint, clear nak */
|
||||||
|
USB_DOEPCTL(0) |= USB_DEPCTL_epena | USB_DEPCTL_cnak;
|
||||||
|
|
||||||
|
/* 64 bytes packet size, active endpoint */
|
||||||
|
USB_DIEPCTL(0) = (USB_DEPCTL_MPS_64 << USB_DEPCTL_mps_bit_pos)
|
||||||
|
| USB_DEPCTL_usbactep;
|
||||||
|
}
|
||||||
|
|
||||||
static void core_dev_init(void)
|
static void core_dev_init(void)
|
||||||
{
|
{
|
||||||
unsigned int usb_num_in_ep = 0;
|
unsigned int usb_num_in_ep = 0;
|
||||||
|
|
@ -192,9 +237,7 @@ static void core_dev_init(void)
|
||||||
/* Restart the phy clock */
|
/* Restart the phy clock */
|
||||||
USB_PCGCCTL = 0;
|
USB_PCGCCTL = 0;
|
||||||
/* Set phy speed : high speed */
|
/* Set phy speed : high speed */
|
||||||
USB_DCFG = (USB_DCFG & (~USB_DCFG_devspd_bits)) | USB_DCFG_devspd_hs_phy_hs;
|
USB_DCFG = (USB_DCFG & ~USB_DCFG_devspd_bits) | USB_DCFG_devspd_hs_phy_hs;
|
||||||
/* Set periodic frame interval */
|
|
||||||
USB_DCFG = (USB_DCFG & (~USB_DCFG_perfrint_bits)) | (USB_DCFG_FRAME_INTERVAL_80 << USB_DCFG_perfrint_bit_pos);
|
|
||||||
|
|
||||||
/* Check hardware capabilities */
|
/* Check hardware capabilities */
|
||||||
if(USB_GHWCFG2_ARCH != USB_INT_DMA_ARCH)
|
if(USB_GHWCFG2_ARCH != USB_INT_DMA_ARCH)
|
||||||
|
|
@ -208,6 +251,7 @@ static void core_dev_init(void)
|
||||||
if(USB_GHWCFG4_DED_FIFO_EN != 1) /* it seems to be multiple tx fifo support */
|
if(USB_GHWCFG4_DED_FIFO_EN != 1) /* it seems to be multiple tx fifo support */
|
||||||
panicf("usb: no multiple tx fifo");
|
panicf("usb: no multiple tx fifo");
|
||||||
|
|
||||||
|
/* do some logging */
|
||||||
logf("hwcfg1: %08lx", USB_GHWCFG1);
|
logf("hwcfg1: %08lx", USB_GHWCFG1);
|
||||||
logf("hwcfg2: %08lx", USB_GHWCFG2);
|
logf("hwcfg2: %08lx", USB_GHWCFG2);
|
||||||
logf("hwcfg3: %08lx", USB_GHWCFG3);
|
logf("hwcfg3: %08lx", USB_GHWCFG3);
|
||||||
|
|
@ -233,11 +277,13 @@ static void core_dev_init(void)
|
||||||
panicf("usb: num out ep static mismatch(%u,%u)", usb_num_out_ep, USB_NUM_OUT_EP);
|
panicf("usb: num out ep static mismatch(%u,%u)", usb_num_out_ep, USB_NUM_OUT_EP);
|
||||||
|
|
||||||
logf("%d in ep, %d out ep", usb_num_in_ep, usb_num_out_ep);
|
logf("%d in ep, %d out ep", usb_num_in_ep, usb_num_out_ep);
|
||||||
|
/*
|
||||||
logf("initial:");
|
logf("initial:");
|
||||||
logf(" tot fifo sz: %lx", USB_GHWCFG3_DFIFO_LEN);
|
logf(" tot fifo sz: %lx", USB_GHWCFG3_DFIFO_LEN);
|
||||||
logf(" rx fifo: [%04x,+%4lx]", 0, USB_GRXFSIZ);
|
logf(" rx fifo: [%04x,+%4lx]", 0, USB_GRXFSIZ);
|
||||||
logf(" nptx fifo: [%04lx,+%4lx]", USB_GET_FIFOSIZE_START_ADR(USB_GNPTXFSIZ),
|
logf(" nptx fifo: [%04lx,+%4lx]", USB_GET_FIFOSIZE_START_ADR(USB_GNPTXFSIZ),
|
||||||
USB_GET_FIFOSIZE_DEPTH(USB_GNPTXFSIZ));
|
USB_GET_FIFOSIZE_DEPTH(USB_GNPTXFSIZ));
|
||||||
|
*/
|
||||||
for(i = 1; i <= USB_NUM_IN_EP; i++)
|
for(i = 1; i <= USB_NUM_IN_EP; i++)
|
||||||
{
|
{
|
||||||
logf(" dieptx fifo(%2u): [%04lx,+%4lx]", i,
|
logf(" dieptx fifo(%2u): [%04lx,+%4lx]", i,
|
||||||
|
|
@ -253,72 +299,40 @@ static void core_dev_init(void)
|
||||||
USB_GRSTCTL = USB_GRSTCTL_intknqflsh;
|
USB_GRSTCTL = USB_GRSTCTL_intknqflsh;
|
||||||
|
|
||||||
/* Clear all pending device interrupts */
|
/* Clear all pending device interrupts */
|
||||||
USB_DIEPMSK = 0;
|
|
||||||
USB_DOEPMSK = 0;
|
|
||||||
USB_DAINT = 0xffffffff;
|
USB_DAINT = 0xffffffff;
|
||||||
USB_DAINTMSK = 0;
|
/* Setup interrupt masks for enpoints */
|
||||||
|
/* Setup interrupt masks */
|
||||||
|
USB_DOEPMSK = USB_DOEPINT_setup | USB_DOEPINT_xfercompl | USB_DOEPINT_ahberr
|
||||||
|
| USB_DOEPINT_epdisabled;
|
||||||
|
USB_DIEPMSK = USB_DIEPINT_xfercompl | USB_DIEPINT_timeout
|
||||||
|
| USB_DIEPINT_epdisabled | USB_DIEPINT_ahberr
|
||||||
|
| USB_DIEPINT_intknepmis;
|
||||||
|
USB_DAINTMSK = 0xffffffff;
|
||||||
|
|
||||||
for(i = 0; i <= USB_NUM_IN_EP; i++)
|
reset_endpoints();
|
||||||
{
|
|
||||||
/* disable endpoint if enabled */
|
|
||||||
if(USB_DIEPCTL(i) & USB_DEPCTL_epena)
|
|
||||||
USB_DIEPCTL(i) = USB_DEPCTL_epdis | USB_DEPCTL_snak;
|
|
||||||
else
|
|
||||||
USB_DIEPCTL(i) = 0;
|
|
||||||
|
|
||||||
USB_DIEPTSIZ(i) = 0;
|
|
||||||
USB_DIEPDMA(i) = 0;
|
|
||||||
USB_DIEPINT(i) = 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i <= USB_NUM_OUT_EP; i++)
|
|
||||||
{
|
|
||||||
/* disable endpoint if enabled */
|
|
||||||
if(USB_DOEPCTL(i) & USB_DEPCTL_epena)
|
|
||||||
USB_DOEPCTL(i) = USB_DEPCTL_epdis | USB_DEPCTL_snak;
|
|
||||||
else
|
|
||||||
USB_DOEPCTL(i) = 0;
|
|
||||||
|
|
||||||
USB_DOEPTSIZ(i) = 0;
|
|
||||||
USB_DOEPDMA(i) = 0;
|
|
||||||
USB_DOEPINT(i) = 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fixme: threshold tweaking only takes place if we use multiple tx fifos it seems */
|
/* fixme: threshold tweaking only takes place if we use multiple tx fifos it seems */
|
||||||
/* only dump them for now, leave threshold disabled */
|
/* only dump them for now, leave threshold disabled */
|
||||||
|
/*
|
||||||
logf("threshold control:");
|
logf("threshold control:");
|
||||||
logf(" non_iso_thr_en: %d", (USB_DTHRCTL & USB_DTHRCTL_non_iso_thr_en) ? 1 : 0);
|
logf(" non_iso_thr_en: %d", (USB_DTHRCTL & USB_DTHRCTL_non_iso_thr_en) ? 1 : 0);
|
||||||
logf(" iso_thr_en: %d", (USB_DTHRCTL & USB_DTHRCTL_iso_thr_en) ? 1 : 0);
|
logf(" iso_thr_en: %d", (USB_DTHRCTL & USB_DTHRCTL_iso_thr_en) ? 1 : 0);
|
||||||
logf(" tx_thr_len: %lu", (USB_DTHRCTL & USB_DTHRCTL_tx_thr_len_bits) >> USB_DTHRCTL_tx_thr_len_bit_pos);
|
logf(" tx_thr_len: %lu", (USB_DTHRCTL & USB_DTHRCTL_tx_thr_len_bits) >> USB_DTHRCTL_tx_thr_len_bit_pos);
|
||||||
logf(" rx_thr_en: %d", (USB_DTHRCTL & USB_DTHRCTL_rx_thr_en) ? 1 : 0);
|
logf(" rx_thr_en: %d", (USB_DTHRCTL & USB_DTHRCTL_rx_thr_en) ? 1 : 0);
|
||||||
logf(" rx_thr_len: %lu", (USB_DTHRCTL & USB_DTHRCTL_rx_thr_len_bits) >> USB_DTHRCTL_rx_thr_len_bit_pos);
|
logf(" rx_thr_len: %lu", (USB_DTHRCTL & USB_DTHRCTL_rx_thr_len_bits) >> USB_DTHRCTL_rx_thr_len_bit_pos);
|
||||||
|
*/
|
||||||
|
|
||||||
/* enable USB interrupts */
|
/* enable USB interrupts */
|
||||||
usb_enable_device_interrupts();
|
usb_enable_device_interrupts();
|
||||||
|
|
||||||
/* enable fifo underrun interrupt ? */
|
|
||||||
USB_DIEPMSK |= USB_DIEPINT_txfifoundrn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void core_init(void)
|
static void core_init(void)
|
||||||
{
|
{
|
||||||
/* Setup phy for high speed */
|
|
||||||
USB_GUSBCFG &= ~USB_GUSBCFG_ulpi_ext_vbus_drv;
|
|
||||||
/* Disable external TS Dline pulsing (???) */
|
|
||||||
USB_GUSBCFG &= ~USB_GUSBCFG_term_sel_dl_pulse;
|
|
||||||
/* core reset */
|
|
||||||
core_reset();
|
|
||||||
|
|
||||||
/* Select UTMI */
|
|
||||||
USB_GUSBCFG &= ~USB_GUSBCFG_ulpi_utmi_sel;
|
|
||||||
/* Select UTMI+ 16 */
|
/* Select UTMI+ 16 */
|
||||||
USB_GUSBCFG |= USB_GUSBCFG_phy_if;
|
USB_GUSBCFG |= USB_GUSBCFG_phy_if;
|
||||||
/* core reset */
|
/* core reset */
|
||||||
core_reset();
|
core_reset();
|
||||||
|
|
||||||
/* fixme: the linux code does that but the clip+ doesn't use ULPI it seems */
|
|
||||||
USB_GUSBCFG &= ~(USB_GUSBCFG_ulpi_fsls | USB_GUSBCFG_ulpi_clk_sus_m);
|
|
||||||
|
|
||||||
/* fixme: the current code is for internal DMA only, the clip+ architecture
|
/* fixme: the current code is for internal DMA only, the clip+ architecture
|
||||||
* define the internal DMA model */
|
* define the internal DMA model */
|
||||||
/* Set burstlen and enable DMA*/
|
/* Set burstlen and enable DMA*/
|
||||||
|
|
@ -327,9 +341,6 @@ static void core_init(void)
|
||||||
/* Disable HNP and SRP, not sure it's useful because we already forced dev mode */
|
/* Disable HNP and SRP, not sure it's useful because we already forced dev mode */
|
||||||
USB_GUSBCFG &= ~(USB_GUSBCFG_srpcap | USB_GUSBCFG_hnpcapp);
|
USB_GUSBCFG &= ~(USB_GUSBCFG_srpcap | USB_GUSBCFG_hnpcapp);
|
||||||
|
|
||||||
/* enable basic interrupts */
|
|
||||||
usb_enable_common_interrupts();
|
|
||||||
|
|
||||||
/* perform device model specific init */
|
/* perform device model specific init */
|
||||||
core_dev_init();
|
core_dev_init();
|
||||||
}
|
}
|
||||||
|
|
@ -351,8 +362,6 @@ void usb_drv_init(void)
|
||||||
logf("usb_drv_init");
|
logf("usb_drv_init");
|
||||||
/* Enable PHY and clocks (but leave pullups disabled) */
|
/* Enable PHY and clocks (but leave pullups disabled) */
|
||||||
as3525v2_connect();
|
as3525v2_connect();
|
||||||
/* Disable global interrupts */
|
|
||||||
usb_disable_global_interrupts();
|
|
||||||
logf("usb: synopsis id: %lx", USB_GSNPSID);
|
logf("usb: synopsis id: %lx", USB_GSNPSID);
|
||||||
/* Core init */
|
/* Core init */
|
||||||
core_init();
|
core_init();
|
||||||
|
|
@ -365,90 +374,39 @@ void usb_drv_exit(void)
|
||||||
logf("usb_drv_exit");
|
logf("usb_drv_exit");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_ep0(void)
|
|
||||||
{
|
|
||||||
/* Setup EP0 OUT to receive setup packets and
|
|
||||||
* EP0 IN to transmit packets
|
|
||||||
* The setup takes enumeration speed into account
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Setup packet size of IN ep based of enumerated speed */
|
|
||||||
switch((USB_DSTS & USB_DSTS_enumspd_bits) >> USB_DSTS_enumspd_bit_pos)
|
|
||||||
{
|
|
||||||
case USB_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
|
|
||||||
case USB_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
|
|
||||||
case USB_DSTS_ENUMSPD_FS_PHY_48MHZ:
|
|
||||||
/* Use 64 bytes packet size */
|
|
||||||
USB_DIEPCTL(0) = (USB_DIEPCTL(0) & (~USB_DEPCTL_mps_bits))
|
|
||||||
| (USB_DEPCTL_MPS_64 << USB_DEPCTL_mps_bit_pos);
|
|
||||||
break;
|
|
||||||
case USB_DSTS_ENUMSPD_LS_PHY_6MHZ:
|
|
||||||
USB_DIEPCTL(0) = (USB_DIEPCTL(0) & (~USB_DEPCTL_mps_bits))
|
|
||||||
| (USB_DEPCTL_MPS_8 << USB_DEPCTL_mps_bit_pos);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
panicf("usb: invalid enum speed");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enable OUT ep for receive */
|
|
||||||
//USB_DOEPCTL(0) |= USB_DEPCTL_epena;
|
|
||||||
|
|
||||||
/* Clear non periodic NAK for IN ep */
|
|
||||||
USB_DCTL |= USB_DCTL_cgnpinnak;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ep0_out_start(void)
|
|
||||||
{
|
|
||||||
/* Setup EP0 OUT with the following parameters:
|
|
||||||
* packet count = 1
|
|
||||||
* setup packet count = 1
|
|
||||||
* transfer size = 8 (=sizeof setup packet)
|
|
||||||
*/
|
|
||||||
USB_DOEPTSIZ(0) = (1 << USB_DEPTSIZ0_supcnt_bit_pos)
|
|
||||||
| (1 << USB_DEPTSIZ0_pkcnt_bit_pos)
|
|
||||||
| 8;
|
|
||||||
|
|
||||||
/* setup DMA */
|
|
||||||
clean_dcache_range((void*)&ep0_setup_pkt, sizeof ep0_setup_pkt); /* force write back */
|
|
||||||
USB_DOEPDMA(0) = (unsigned long)&ep0_setup_pkt; /* virtual address=physical address */
|
|
||||||
|
|
||||||
/* enable EP */
|
|
||||||
USB_DOEPCTL(0) |= USB_DEPCTL_epena | USB_DEPCTL_usbactep;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool handle_usb_reset(void)
|
static bool handle_usb_reset(void)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
|
||||||
logf("usb: bus reset");
|
logf("usb: bus reset");
|
||||||
|
|
||||||
/* Clear the Remote Wakeup Signalling */
|
/* Clear the Remote Wakeup Signalling */
|
||||||
USB_DCTL &= ~USB_DCTL_rmtwkupsig;
|
USB_DCTL &= ~USB_DCTL_rmtwkupsig;
|
||||||
|
|
||||||
/* Set NAK for all OUT EPs */
|
|
||||||
for(i = 0; i <= USB_NUM_OUT_EP; i++)
|
|
||||||
USB_DOEPCTL(i) = USB_DEPCTL_snak;
|
|
||||||
|
|
||||||
/* Flush the NP Tx FIFO */
|
/* Flush the NP Tx FIFO */
|
||||||
usb_flush_tx_fifos(0);
|
usb_flush_tx_fifos(0);
|
||||||
|
|
||||||
/* Flush the Learning Queue */
|
/* Flush the Learning Queue */
|
||||||
USB_GRSTCTL = USB_GRSTCTL_intknqflsh;
|
USB_GRSTCTL = USB_GRSTCTL_intknqflsh;
|
||||||
|
|
||||||
/* Setup interrupt masks */
|
reset_endpoints();
|
||||||
USB_DAINTMSK = USB_DAINT_IN_EP(0) | USB_DAINT_OUT_EP(0);
|
|
||||||
USB_DOEPMSK = USB_DOEPINT_setup | USB_DOEPINT_xfercompl | USB_DOEPINT_ahberr
|
|
||||||
| USB_DOEPINT_epdisabled;
|
|
||||||
USB_DIEPMSK = USB_DIEPINT_xfercompl | USB_DIEPINT_timeout
|
|
||||||
| USB_DIEPINT_epdisabled | USB_DIEPINT_ahberr
|
|
||||||
| USB_DIEPINT_intknepmis;
|
|
||||||
|
|
||||||
/* Reset Device Address */
|
/* Reset Device Address */
|
||||||
USB_DCFG &= ~USB_DCFG_devadr_bits;
|
USB_DCFG &= ~USB_DCFG_devadr_bits;
|
||||||
|
|
||||||
/* setup EP0 to receive SETUP packets */
|
usb_core_bus_reset();
|
||||||
ep0_out_start();
|
|
||||||
/* Clear interrupt */
|
return true;
|
||||||
USB_GINTSTS = USB_GINTMSK_usbreset;
|
}
|
||||||
|
|
||||||
|
static bool handle_usb_suspend(void)
|
||||||
|
{
|
||||||
|
logf("usb: suspend");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool handle_wake_up(void)
|
||||||
|
{
|
||||||
|
logf("usb: wake up");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -457,16 +415,21 @@ static bool handle_enum_done(void)
|
||||||
{
|
{
|
||||||
logf("usb: enum done");
|
logf("usb: enum done");
|
||||||
|
|
||||||
/* Enable EP0 to receive SETUP packets */
|
/* read speed */
|
||||||
activate_ep0();
|
logf("DSTS: %lx", USB_DSTS);
|
||||||
|
logf("DOEPCTL0=%lx", USB_DOEPCTL(0));
|
||||||
/* Set USB turnaround time
|
logf("DOEPTSIZ=%lx", USB_DOEPTSIZ(0));
|
||||||
* fixme: unsure about this */
|
logf("DIEPCTL0=%lx", USB_DIEPCTL(0));
|
||||||
//USB_GUSBCFG = (USB_GUSBCFG & ~USB_GUSBCFG_usbtrdtim_bits) | (5 << USB_GUSBCFG_usbtrdtim_bit_pos);
|
logf("DOEPMSK=%lx", USB_DOEPMSK);
|
||||||
//panicf("usb: turnaround time is %d", (USB_GUSBCFG & USB_GUSBCFG_usbtrdtim_bits) >> USB_GUSBCFG_usbtrdtim_bit_pos);
|
logf("DIEPMSK=%lx", USB_DIEPMSK);
|
||||||
|
logf("DAINTMSK=%lx", USB_DAINTMSK);
|
||||||
/* Clear interrupt */
|
logf("DAINT=%lx", USB_DAINT);
|
||||||
USB_GINTSTS = USB_GINTMSK_enumdone;
|
logf("GINTSTS=%lx", USB_GINTSTS);
|
||||||
|
logf("GINTMSK=%lx", USB_GINTMSK);
|
||||||
|
logf("DCTL=%lx", USB_DCTL);
|
||||||
|
logf("GAHBCFG=%lx", USB_GAHBCFG);
|
||||||
|
logf("GUSBCFG=%lx", USB_GUSBCFG);
|
||||||
|
logf("DCFG=%lx", USB_DCFG);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -523,7 +486,6 @@ static void dump_intsts(char *buffer, size_t size, unsigned long sts)
|
||||||
/* interrupt service routine */
|
/* interrupt service routine */
|
||||||
void INT_USB(void)
|
void INT_USB(void)
|
||||||
{
|
{
|
||||||
static char buffer[256];
|
|
||||||
/* some bits in GINTSTS can be set even though we didn't enable the interrupt source
|
/* some bits in GINTSTS can be set even though we didn't enable the interrupt source
|
||||||
* so AND it with the actual mask */
|
* so AND it with the actual mask */
|
||||||
unsigned long sts = USB_GINTSTS & USB_GINTMSK;
|
unsigned long sts = USB_GINTSTS & USB_GINTMSK;
|
||||||
|
|
@ -545,8 +507,14 @@ void INT_USB(void)
|
||||||
/* device part */
|
/* device part */
|
||||||
HANDLED_CASE(USB_GINTMSK_usbreset, handle_usb_reset)
|
HANDLED_CASE(USB_GINTMSK_usbreset, handle_usb_reset)
|
||||||
HANDLED_CASE(USB_GINTMSK_enumdone, handle_enum_done)
|
HANDLED_CASE(USB_GINTMSK_enumdone, handle_enum_done)
|
||||||
|
HANDLED_CASE(USB_GINTMSK_usbsuspend, handle_usb_suspend)
|
||||||
|
HANDLED_CASE(USB_GINTMSK_wkupintr, handle_wake_up)
|
||||||
|
/*
|
||||||
HANDLED_CASE(USB_GINTMSK_inepintr, handle_in_ep_int)
|
HANDLED_CASE(USB_GINTMSK_inepintr, handle_in_ep_int)
|
||||||
HANDLED_CASE(USB_GINTMSK_outepintr, handle_out_ep_int)
|
HANDLED_CASE(USB_GINTMSK_outepintr, handle_out_ep_int)
|
||||||
|
*/
|
||||||
|
UNHANDLED_CASE(USB_GINTMSK_outepintr)
|
||||||
|
UNHANDLED_CASE(USB_GINTMSK_inepintr)
|
||||||
|
|
||||||
/* common part */
|
/* common part */
|
||||||
UNHANDLED_CASE(USB_GINTMSK_otgintr)
|
UNHANDLED_CASE(USB_GINTMSK_otgintr)
|
||||||
|
|
@ -557,15 +525,15 @@ void INT_USB(void)
|
||||||
if(sts & ~handled_one)
|
if(sts & ~handled_one)
|
||||||
goto Lunhandled;
|
goto Lunhandled;
|
||||||
|
|
||||||
|
USB_GINTSTS = USB_GINTSTS;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Lunhandled:
|
Lunhandled:
|
||||||
dump_intsts(buffer, sizeof buffer, sts);
|
panicf("unhandled usb int: %lx", sts);
|
||||||
panicf("unhandled usb int: %lx (%s)", sts, buffer);
|
|
||||||
|
|
||||||
Lerr:
|
Lerr:
|
||||||
dump_intsts(buffer, sizeof buffer, sts);
|
panicf("error in usb int: %lx", sts);
|
||||||
panicf("error in usb int: %lx (%s)", sts, buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int usb_drv_port_speed(void)
|
int usb_drv_port_speed(void)
|
||||||
|
|
|
||||||
|
|
@ -363,7 +363,11 @@
|
||||||
* Parameters
|
* Parameters
|
||||||
*/
|
*/
|
||||||
/* Number of IN/OUT endpoints */
|
/* Number of IN/OUT endpoints */
|
||||||
#define USB_NUM_IN_EP 3u
|
#define USB_NUM_IN_EP 3
|
||||||
#define USB_NUM_OUT_EP 2u
|
#define USB_NUM_OUT_EP 2
|
||||||
|
|
||||||
|
/* List of IN enpoints */
|
||||||
|
#define USB_IN_EP_LIST 1, 3, 5
|
||||||
|
#define USB_OUT_EP_LIST 2, 4
|
||||||
|
|
||||||
#endif /* __USB_DRV_AS3525v2_H__ */
|
#endif /* __USB_DRV_AS3525v2_H__ */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue