2014-09-21 21:45:36 +08:00

843 lines
19 KiB
C

/**
*****************************************************************************
* @file cmem7_usb.c
*
* @brief CMEM7 USB source file
*
*
* @version V1.0
* @date 3. September 2013
*
* @note
*
*****************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, CAPITAL-MICRO SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2013 Capital-micro </center></h2>
*****************************************************************************
*/
#include "cmem7_usb.h"
static void USB_SET_REG_HPRT(const USB_REG_HPRT *clr, const USB_REG_HPRT *set)
{
USB_REG_HPRT hprt;
hprt.HPRT = USB->__HPRT; // @0x41300440
hprt.HPRT_b.POC = hprt.HPRT_b.PEDC = hprt.HPRT_b.PE = hprt.HPRT_b.PCD = 0;
if (clr)
hprt.HPRT &= (~clr->HPRT);
if (set)
hprt.HPRT |= (set->HPRT);
USB->__HPRT = hprt.HPRT;
}
void USB_coreInit(uint32_t type)
{
USB->GINTEN = 0;
USB->GINTSTS = ~0;
GLOBAL_CTRL->USB_PHY_CTRL_b.CKISEL = 0; // Crystal
// core initialization
// choose PHY and soft reset
USB->GUSBCFG_b.PHY_IF = 0; // 60MHz, 8bit
USB->GUSBCFG_b.ULPI_UTMI_SEL = 0; // UTMI
USB->GUSBCFG_b.PHY_SEL = 0; // USB 2.0 HS UTMI+
USB->GRSTCTL_b.CORE_SOFT_RST = 1;
while (USB->GRSTCTL_b.CORE_SOFT_RST == 1) ;
while (USB->GRSTCTL_b.AHB_IDLE == 0) ;
USB->GAHBCFG_b.DMA_EN = 1;
USB->GAHBCFG_b.GLBL_INTR_EN = 1;
USB->GAHBCFG_b.BST_LEN = 0x1; // INCR
USB->GINTEN_b.RFNE = FALSE;
USB->GUSBCFG_b.USB_TRD_TIM = 0x9; // 8-bit UTMI+
USB->GUSBCFG_b.SRP_CAP = (type & 0x10) ? 1 : 0;
USB->GUSBCFG_b.HNP_CAP = (type & 0x20) ? 1 : 0;
if (type & 0x1) {
USB->GUSBCFG_b.FORCE_HOST_MODE = 1;
USB->GUSBCFG_b.FORCE_DEVICE_MODE = 0;
} else if (type & 0x2) {
USB->GUSBCFG_b.FORCE_DEVICE_MODE = 1;
USB->GUSBCFG_b.FORCE_HOST_MODE = 0;
}
udelay(50000);
}
void USB_EnableInt(BOOL enable)
{
USB->GAHBCFG_b.GLBL_INTR_EN = enable;
}
void USB_FlushFIFO(uint32_t num)
{
if (num < 0x10) {
USB->GRSTCTL_b.TX_FIFO_FLUSH_NUM = num;
USB->GRSTCTL_b.TX_FIFO_FLUSH = 1;
while (USB->GRSTCTL_b.TX_FIFO_FLUSH);
} else if (num > 0x10) {
USB->GRSTCTL_b.RX_FIFO_FLUSH = 1;
while (USB->GRSTCTL_b.RX_FIFO_FLUSH);
} else {
USB->GRSTCTL_b.TX_FIFO_FLUSH_NUM = 0;
USB->GRSTCTL_b.TX_FIFO_ALL = 1;
USB->GRSTCTL_b.TX_FIFO_FLUSH = 1;
while (USB->GRSTCTL_b.TX_FIFO_FLUSH);
}
}
BOOL USB_ogtIsBdevID()
{
return USB->GOTGCTL_b.CON_ID_STS ? TRUE : FALSE;
}
BOOL USB_hostVBus(uint32_t opt)
{
if (opt & 0x2) {
USB_REG_HPRT hprt;
hprt.HPRT = 0;
hprt.HPRT_b.PP = 1;
if (opt & 0x1)
USB_SET_REG_HPRT(NULL, &hprt);
else
USB_SET_REG_HPRT(&hprt, NULL);
}
return USB->__HPRT_b.PP ? TRUE : FALSE;
}
void USB_hostInit()
{
USB_REG_HPRT hprt;
// HOST MODE
USB->HCFG_b.FS_LS_PCS = 0x0; // PHY clock is running at 30/60 MHz
USB->HCFG_b.FS_LS_SUPPORT = 0x0; // HS/FS/LS
USB->HCFG_b.EN_SG_DMA = 0x1; // Enable Scatter/Gather DMA
hprt.HPRT = 0;
hprt.HPRT_b.PP = 1;
USB_SET_REG_HPRT(NULL, &hprt);
}
void USB_HostResetPort(BOOL rst)
{
USB_REG_HPRT hprt;
hprt.HPRT = 0;
hprt.HPRT_b.PRESET = 1;
if (rst)
USB_SET_REG_HPRT(NULL, &hprt);
else
USB_SET_REG_HPRT(&hprt, NULL);
}
uint16_t USB_HostGetCurFrame()
{
return USB->HFNUM_b.FN;
}
void USB_HostSuspendPort()
{
USB_REG_HPRT hprt;
hprt.HPRT = 0;
hprt.HPRT_b.PS = 1;
USB_SET_REG_HPRT(NULL, &hprt);
}
USB_ENUM_SPEED USB_hostGetEnumSpd()
{
return (USB_ENUM_SPEED)USB->__HPRT_b.SPEED;
}
BOOL USB_hostPrtConn()
{
return USB->__HPRT_b.PCS ? TRUE : FALSE;
}
void USB_hostCH0(uint32_t devaddr, OTG_DESCRIPTOR *desc, uint32_t ctd, uint32_t ntd, BOOL ping, uint32_t pid, uint32_t mps, uint32_t epnum, BOOL in, USB_EP_TYPE eptype, USB_ENUM_SPEED speed)
{
USB->HCDMA0_b.ADDR = SET_HCDMA_DESC_ADDR(desc);
USB->HCDMA0_b.CTD = ctd;
USB->HCTSIZ0_b.PING = ping ? 1 : 0;
USB->HCTSIZ0_b.NTD = ntd;
USB->HCTSIZ0_b.PID = pid;
USB->HCC0_b.MPS = mps;
USB->HCC0_b.EP_NUM = epnum;
USB->HCC0_b.EP_DIR = in ? 1 : 0;
USB->HCC0_b.LSD = (USB_ENUM_SPEED_LS == speed) ? 1 : 0;
USB->HCC0_b.EP_TYPE = eptype;
USB->HCC0_b.EC = 0;
USB->HCC0_b.DA = devaddr;
USB->HCC0_b.CE = 1;
}
void USB_hostCH1(uint32_t devaddr, OTG_DESCRIPTOR *desc, uint32_t ctd, uint32_t ntd, BOOL ping, uint32_t pid, uint32_t mps, uint32_t epnum, BOOL in, USB_EP_TYPE eptype, USB_ENUM_SPEED speed)
{
USB->HCDMA1_b.ADDR = SET_HCDMA_DESC_ADDR(desc);
USB->HCDMA1_b.CTD = ctd;
USB->HCTSIZ1_b.PING = ping ? 1 : 0;
USB->HCTSIZ1_b.NTD = ntd;
USB->HCTSIZ1_b.PID = pid;
USB->HCC1_b.MPS = mps;
USB->HCC1_b.EP_NUM = epnum;
USB->HCC1_b.EP_DIR = in ? 1 : 0;
USB->HCC1_b.LSD = (USB_ENUM_SPEED_LS == speed) ? 1 : 0;
USB->HCC1_b.EP_TYPE = eptype;
USB->HCC1_b.EC = 0;
USB->HCC1_b.DA = devaddr;
USB->HCC1_b.CE = 1;
}
void USB_hostCH2(uint32_t devaddr, OTG_DESCRIPTOR *desc, uint32_t ctd, uint32_t ntd, BOOL ping, uint32_t pid, uint32_t mps, uint32_t epnum, BOOL in, USB_EP_TYPE eptype, USB_ENUM_SPEED speed)
{
USB->HCDMA2_b.ADDR = SET_HCDMA_DESC_ADDR(desc);
USB->HCDMA2_b.CTD = ctd;
USB->HCTSIZ2_b.PING = ping ? 1 : 0;
USB->HCTSIZ2_b.NTD = ntd;
USB->HCTSIZ2_b.PID = pid;
USB->HCC2_b.MPS = mps;
USB->HCC2_b.EP_NUM = epnum;
USB->HCC2_b.EP_DIR = in ? 1 : 0;
USB->HCC2_b.LSD = (USB_ENUM_SPEED_LS == speed) ? 1 : 0;
USB->HCC2_b.EP_TYPE = eptype;
USB->HCC2_b.EC = 0;
USB->HCC2_b.DA = devaddr;
USB->HCC2_b.CE = 1;
}
int USB_hostCHn(uint32_t ch, uint32_t devaddr, OTG_DESCRIPTOR *desc, uint32_t ctd, uint32_t ntd, BOOL ping, uint32_t pid, uint32_t mps, uint32_t epnum, BOOL in, USB_EP_TYPE eptype, USB_ENUM_SPEED speed)
{
USB_Type *USBn = (USB_Type *)(((char *)USB) + (ch * 0x20));
if (ch > 15)
return -1;
USBn->HCDMA0_b.ADDR = SET_HCDMA_DESC_ADDR(desc);
USBn->HCDMA0_b.CTD = ctd;
USBn->HCTSIZ0_b.PING = ping ? 1 : 0;
USBn->HCTSIZ0_b.NTD = ntd;
USBn->HCTSIZ0_b.PID = pid;
USBn->HCC0_b.MPS = mps;
USBn->HCC0_b.EP_NUM = epnum;
USBn->HCC0_b.EP_DIR = in ? 1 : 0;
USBn->HCC0_b.LSD = (USB_ENUM_SPEED_LS == speed) ? 1 : 0;
USBn->HCC0_b.EP_TYPE = eptype;
USBn->HCC0_b.EC = 0;
USBn->HCC0_b.DA = devaddr;
USBn->HCC0_b.CE = 1;
return 0;
}
int USB_hostCHnHalt(uint32_t ch)
{
uint32_t hcchar;
USB_Type *USBn = (USB_Type *)(((char *)USB) + (ch * 0x20));
if (ch > 15)
return -1;
hcchar = USBn->HCC0;
hcchar |= (0x3 << 30);
USBn->HCC0 = hcchar;
return 0;
}
BOOL USB_hostPortDisable(BOOL dis)
{
if (dis) {
USB_REG_HPRT hprt;
hprt.HPRT = 0;
hprt.HPRT_b.PE = 1;
USB_SET_REG_HPRT(&hprt, NULL);
}
return USB->__HPRT_b.PE ? FALSE : TRUE;
}
BOOL USB_roleIsHost()
{
return USB->GINTSTS_b.CUR_MOD ? TRUE : FALSE;
}
void USB_hostINT_enConn(BOOL en)
{
USB->GINTEN_b.HP = en;
}
BOOL USB_hostINT_isConn()
{
return USB->GINTSTS_b.HP ? TRUE : FALSE;
}
BOOL USB_hostINT_isPCD()
{
return USB->__HPRT_b.PCD ? TRUE : FALSE;
}
void USB_hostINT_clrPCD()
{
USB_REG_HPRT hprt;
hprt.HPRT = 0;
hprt.HPRT_b.PCD = 1;
USB_SET_REG_HPRT(NULL, &hprt);
}
BOOL USB_hostINT_isPEDC()
{
return USB->__HPRT_b.PEDC ? TRUE : FALSE;
}
void USB_hostINT_clrPEDC()
{
USB_REG_HPRT hprt;
hprt.HPRT = 0;
hprt.HPRT_b.PEDC = 1;
USB_SET_REG_HPRT(NULL, &hprt);
}
int USB_hostINT_enDone(uint32_t ch, BOOL en)
{
USB_Type *USBn = (USB_Type *)(((char *)USB) + (ch * 0x20));
if (ch > 15)
return -1;
if (en) {
USB->GINTEN_b.HC = 1;
USB->HAINT_EN_b.EN |= BIT(ch);
} else
USB->HAINT_EN_b.EN &= ~BIT(ch);
USBn->HCINT_EN0_b.TC = USBn->HCINT_EN0_b.CH_HALT = USBn->HCINT_EN0_b.BNA = en ? 1 : 0;
return 0;
}
uint32_t USB_hostINT_isDone(uint32_t ch)
{
uint32_t retval = 0;
if (ch > 15)
return 0;
if ((USB->GINTSTS_b.HC) && ((USB->HAINT & BIT(ch)))) {
USB_Type *USBn = (USB_Type *)(((char *)USB) + (ch * 0x20));
if (USBn->HCINT0_b.TC) {
USBn->HCINT0 = BIT(0);
retval |= 0x1;
}
if (USBn->HCINT0_b.BNA) {
USBn->HCINT0 = BIT(11);
retval |= 0x2;
}
if (USBn->HCINT0_b.CH_HALT) {
USBn->HCINT0 = BIT(1);
retval |= 0x4;
}
if (USBn->HCINT0_b.ETE) {
USBn->HCINT0 = BIT(12);
retval |= 0x8;
}
}
return retval;
}
uint32_t USB_hostINT_isPend(uint32_t ch)
{
uint32_t retval = 0;
if (ch > 15)
return 0;
if ((USB->GINTSTS_b.HC) && ((USB->HAINT & BIT(ch)))) {
USB_Type *USBn = (USB_Type *)(((char *)USB) + (ch * 0x20));
retval = USBn->HCINT0;
USBn->HCINT0 = retval;
}
return retval;
}
void USB_devInit()
{
// If still has some int needed to be enable
USB->GINTEN_b.MODE_MIS = TRUE;
USB->GINTEN_b.OTG_INT = TRUE;
// DEVICE MODE
USB->GINTEN_b.RFNE = FALSE; // REG_CS(0x018/*GINTMSK*/, BIT(5)/*NPTxFEmpMsk*/ | BIT(4)/*RxFLvlMsk*/, 0);
USB->GINTEN_b.NPTFE = FALSE;
USB->DCFG_b.DSPEED = 0; // HS DEV
USB->DCFG_b.NZLSOH = 0; // REG_CS(0x800/*DCFG*/, BIT(2)/*NZStsOUTHShk*/ | BIT(1) | BIT(0)/*DevSpd: HS*/, BIT(23)/*DescDMA*/ | BIT(13)/*EnDevOutNak*/);
USB->DCFG_b.EN_SG_DMA = 1;
USB->DCFG_b.EDON = 1;
USB->DCTL_b.SD = 0;
}
USB_ENUM_SPEED USB_devGetEnumSpd()
{
return (USB_ENUM_SPEED)USB->DSTS_b.SPEED;
}
void USB_devSetAddress(uint32_t addr)
{
USB->DCFG_b.DEVICE_ADDR = addr;
}
void USB_devEP0out(uint32_t size, uint32_t pktcnt, uint32_t stpcnt, void *desc, BOOL snoop)
{
USB->DOEPTSIZ0_b.SIZE = size;
USB->DOEPTSIZ0_b.PACKET_CNT = pktcnt;
USB->DOEPTSIZ0_b.SETUP_CNT = stpcnt;
USB->DOEPDMA0 = (uint32_t)(desc);
USB->DOEPCTL0_b.SNOOP = snoop;
USB->DOEPCTL0_b.CNAK = 1;
USB->DOEPCTL0_b.EPE = 1; // REG_CS(0xB00/*DOEPCTL0*/, 0, BIT(31)/*EPEna*/);
}
BOOL USB_devEP0in(uint32_t size, uint32_t pktcnt, void *desc, uint32_t mps/*8,16,32,64-byte*/)
{
switch (mps) {
case 64: mps = 0x0; break;
case 32: mps = 0x1; break;
case 16: mps = 0x2; break;
case 8: mps = 0x3; break;
default: return FALSE;
}
USB->DIEPTSIZ0_b.SIZE = size;
USB->DIEPTSIZ0_b.PACKET_CNT = pktcnt;
USB->DIEPDMA0 = (uint32_t)(desc);
USB->DIEPCTL0_b.MPS = mps;
USB->DIEPCTL0_b.TX_FIFO_NUM = 0;
USB->DIEPCTL0_b.CNAK = 1;
USB->DIEPCTL0_b.EPE = 1; // REG_CS(0xB00/*DOEPCTL0*/, 0, BIT(31)/*EPEna*/);
return TRUE;
}
void USB_devActEP1(const BOOL in, const uint32_t mps, USB_EP_TYPE type)
{
if (in) {
USB->DIEPCTL1_b.MPS = mps;
USB->DIEPCTL1_b.EP_TYPE = type;
USB->DIEPCTL1_b.UAE = (mps != 0) ? 1 : 0;
} else {
USB->DOEPCTL1_b.MPS = mps;
USB->DOEPCTL1_b.EP_TYPE = type;
USB->DOEPCTL1_b.UAE = (mps != 0) ? 1 : 0;
}
}
void USB_devActEP2(const BOOL in, const uint32_t mps, USB_EP_TYPE type)
{
if (in) {
USB->DIEPCTL2_b.MPS = mps;
USB->DIEPCTL2_b.EP_TYPE = type;
USB->DIEPCTL2_b.UAE = (mps != 0) ? 1 : 0;
} else {
USB->DOEPCTL2_b.MPS = mps;
USB->DOEPCTL2_b.EP_TYPE = type;
USB->DOEPCTL2_b.UAE = (mps != 0) ? 1 : 0;
}
}
void USB_devEP1in(uint32_t size, uint32_t pktcnt, uint32_t pid, void *desc)
{
USB->DIEPTSIZ1_b.SIZE = size;
USB->DIEPTSIZ1_b.PACKET_CNT = pktcnt;
USB->DIEPDMA1 = (uint32_t)(desc);
USB->DIEPCTL1_b.CNAK = 1;
USB->DIEPCTL1_b.SET_D0_PID = (pid >> 0) & 0x1;
USB->DIEPCTL1_b.SET_D1_PID = (pid >> 1) & 0x1;
USB->DIEPCTL1_b.EPE = 1;
}
void USB_devEP1out(uint32_t size, uint32_t pktcnt, uint32_t pid, uint32_t stpcnt, void *desc, BOOL snoop)
{
USB->DOEPTSIZ1_b.SIZE = size;
USB->DOEPTSIZ1_b.PACKET_CNT = pktcnt;
USB->DOEPTSIZ1_b.SETUPCNT_PID = stpcnt;
USB->DOEPDMA1 = (uint32_t)(desc);
USB->DOEPCTL1_b.EC = snoop;
USB->DOEPCTL1_b.CNAK = 1;
USB->DOEPCTL1_b.SET_D0_PID = (pid >> 0) & 0x1;
USB->DOEPCTL1_b.SET_D1_PID = (pid >> 1) & 0x1;
USB->DOEPCTL1_b.EPE = 1;
}
void USB_devEP2in(uint32_t size, uint32_t pktcnt, uint32_t pid, void *desc)
{
USB->DIEPTSIZ2_b.SIZE = size;
USB->DIEPTSIZ2_b.PACKET_CNT = pktcnt;
USB->DIEPDMA2 = (uint32_t)(desc);
USB->DIEPCTL2_b.CNAK = 1;
USB->DIEPCTL2_b.SET_D0_PID = (pid >> 0) & 0x1;
USB->DIEPCTL2_b.SET_D1_PID = (pid >> 1) & 0x1;
USB->DIEPCTL2_b.EPE = 1;
}
void USB_devEP2out(uint32_t size, uint32_t pktcnt, uint32_t pid, uint32_t stpcnt, void *desc, BOOL snoop)
{
USB->DOEPTSIZ2_b.SIZE = size;
USB->DOEPTSIZ2_b.PACKET_CNT = pktcnt;
USB->DOEPTSIZ2_b.SETUPCNT_PID = stpcnt;
USB->DOEPDMA2 = (uint32_t)(desc);
USB->DOEPCTL2_b.EC = snoop;
USB->DOEPCTL2_b.CNAK = 1;
USB->DOEPCTL2_b.SET_D0_PID = (pid >> 0) & 0x1;
USB->DOEPCTL2_b.SET_D1_PID = (pid >> 1) & 0x1;
USB->DOEPCTL2_b.EPE = 1;
}
void USB_devNAKhandshake(uint32_t ep, BOOL in, BOOL en)
{
switch (ep) {
case 0:
if (in) {
if (en) USB->DIEPCTL0_b.SNAK = 1; else USB->DIEPCTL0_b.CNAK = 1;
} else {
if (en) USB->DOEPCTL0_b.SNAK = 1; else USB->DOEPCTL0_b.CNAK = 1;
}
break;
case 1:
if (in) {
if (en) USB->DIEPCTL1_b.SNAK = 1; else USB->DIEPCTL1_b.CNAK = 1;
} else {
if (en) USB->DOEPCTL1_b.SNAK = 1; else USB->DOEPCTL1_b.CNAK = 1;
}
break;
case 2:
if (in) {
if (en) USB->DIEPCTL2_b.SNAK = 1; else USB->DIEPCTL2_b.CNAK = 1;
} else {
if (en) USB->DOEPCTL2_b.SNAK = 1; else USB->DOEPCTL2_b.CNAK = 1;
}
break;
default:
break;
}
}
BOOL USB_devSTALLhandshake(uint32_t ep, BOOL in, BOOL en)
{
BOOL retval = FALSE;
switch (ep) {
case 0:
if (in) {
retval = USB->DIEPCTL0_b.STALL;
USB->DIEPCTL0_b.STALL = en ? 1 : 0;
} else {
retval = USB->DOEPCTL0_b.STALL;
USB->DOEPCTL0_b.STALL = en ? 1 : 0;
}
break;
case 1:
if (in) {
retval = USB->DIEPCTL1_b.STALL;
USB->DIEPCTL1_b.STALL = en ? 1 : 0;
} else {
retval = USB->DOEPCTL1_b.STALL;
USB->DOEPCTL1_b.STALL = en ? 1 : 0;
}
break;
case 2:
if (in) {
retval = USB->DIEPCTL2_b.STALL;
USB->DIEPCTL2_b.STALL = en ? 1 : 0;
} else {
retval = USB->DOEPCTL2_b.STALL;
USB->DOEPCTL2_b.STALL = en ? 1 : 0;
}
break;
default:
break;
}
return retval;
}
void USB_devINT_enDone(uint32_t ep, BOOL in, BOOL en)
{
if (in) {
USB->DIEPEN_b.TIMEOUT = en ? 1 : 0;
USB->DIEPEN_b.TC = en ? 1 : 0;
if (en) {
USB->GINTEN_b.IEP_INT = 1;
USB->DAINT_EN_b.IN_EN |= BIT(ep);
} else
USB->DAINT_EN_b.IN_EN &= ~BIT(ep);
} else {
USB->DOEPEN_b.SPD = en ? 1 : 0;
USB->DOEPEN_b.TC = en ? 1 : 0;
if (en) {
USB->GINTEN_b.OEP_INT = 1;
USB->DAINT_EN_b.OUT_EN |= BIT(ep);
} else
USB->DAINT_EN_b.OUT_EN &= ~BIT(ep);
}
}
uint32_t USB_devINT_isDone(uint32_t ep, BOOL in)
{
int32_t retval = 0;
if (in) {
if (USB->GINTSTS_b.IEP_INT)
switch (ep) {
case 0:
if (USB->DIEPINT0_b.TC) {
retval |= 0x1;
USB->DIEPINT0 = BIT(0);
}
if (USB->DIEPINT0_b.BNA) {
retval |= 0x2;
USB->DIEPINT0 = BIT(9);
}
break;
case 1:
if (USB->DIEPINT1_b.TC) {
retval |= 0x1;
USB->DIEPINT1 = BIT(0);
}
if (USB->DIEPINT1_b.BNA) {
retval |= 0x2;
USB->DIEPINT1 = BIT(9);
}
break;
case 2:
if (USB->DIEPINT2_b.TC) {
retval |= 0x1;
USB->DIEPINT2 = BIT(0);
}
if (USB->DIEPINT2_b.BNA) {
retval |= 0x2;
USB->DIEPINT2 = BIT(9);
}
default:
break;
}
} else {
if (USB->GINTSTS_b.OEP_INT)
switch (ep) {
case 0:
if (USB->DOEPINT0_b.TC) {
retval |= 0x1;
USB->DOEPINT0 = BIT(0);
}
if (USB->DOEPINT0_b.SETUP) {
retval |= 0x4;
USB->DOEPINT0 = BIT(3);
}
break;
case 1:
if (USB->DOEPINT1_b.TC) {
retval |= 0x1;
USB->DOEPINT1 = BIT(0);
}
if (USB->DOEPINT1_b.BNA) {
retval |= 0x2;
USB->DOEPINT1 = BIT(9);
}
break;
case 2:
if (USB->DOEPINT2_b.TC) {
retval |= 0x1;
USB->DOEPINT2 = BIT(0);
}
if (USB->DOEPINT2_b.BNA) {
retval |= 0x2;
USB->DOEPINT2 = BIT(9);
}
break;
default:
break;
}
}
return retval;
}
void USB_INT_enOTG(BOOL en)
{
USB->GINTEN_b.OTG_INT = en;
}
BOOL USB_INT_isOTG()
{
return USB->GINTSTS_b.OTG_INT ? TRUE : FALSE;
}
BOOL USB_INT_isOTGon(USB_INT_OTG otg)
{
switch (otg) {
case USB_INT_OTG_SESEND:
return USB->GOTGINT_b.SES_END_DET ? TRUE : FALSE;
break;
case USB_INT_OTG_STANDAUP:
return USB->GOTGINT_b.A_DEV_TOUT_CHG ? TRUE : FALSE;
break;
case USB_INT_OTG_HNDETECT:
return USB->GOTGINT_b.HST_NEG_DET ? TRUE : FALSE;
break;
case USB_INT_OTG_HNSUCCHG:
return USB->GOTGINT_b.HST_NEG_SUC_STS_CHNG ? TRUE : FALSE;
break;
case USB_INT_OTG_KEEPAPP:
return USB->GOTGINT_b.DBNCE_DONE ? TRUE : FALSE;
break;
default:
break;
}
return FALSE;
}
void USB_INT_clrOTGon(USB_INT_OTG otg)
{
switch (otg) {
case USB_INT_OTG_SESEND:
USB->GOTGINT = BIT(2);
break;
case USB_INT_OTG_STANDAUP:
USB->GOTGINT = BIT(18);
break;
case USB_INT_OTG_HNDETECT:
USB->GOTGINT = BIT(17);
break;
case USB_INT_OTG_HNSUCCHG:
USB->GOTGINT = BIT(9);
break;
case USB_INT_OTG_KEEPAPP:
USB->GOTGINT = BIT(19);
break;
default:
break;
}
}
void USB_INT_enGP(USB_INT_GP name, BOOL en)
{
switch (name) {
case USB_INT_GP_HOST_DISC:
USB->GINTEN_b.DD = en ? 1 : 0;
break;
case USB_INT_GP_DEV_RESET:
USB->GINTEN_b.USB_RST = en ? 1 : 0;
break;
case USB_INT_GP_DEV_ENUMDONE:
USB->GINTEN_b.ENUM_DONE = en ? 1 : 0;
break;
case USB_INT_GP_DEV_SUSP:
USB->GINTEN_b.USB_SUS = en ? 1 : 0;
break;
case USB_INT_GP_DEV_EARLY:
USB->GINTEN_b.EARLY_SUS = en ? 1 : 0;
break;
case USB_INT_GP_SOF:
USB->GINTEN_b.SOF = en ? 1 : 0;
break;
case USB_INT_GP_MIS:
USB->GINTEN_b.MODE_MIS = en ? 1 : 0;
break;
case USB_INT_GP_IDCHG:
USB->GINTEN_b.CIDSC = en ? 1 : 0;
break;
case USB_INT_GP_SESSREQ:
USB->GINTEN_b.SR = en ? 1 : 0;
break;
default:
break;
}
}
BOOL USB_INT_isGP(USB_INT_GP name)
{
switch (name) {
case USB_INT_GP_HOST_DISC:
return USB->GINTSTS_b.DD ? TRUE : FALSE;
break;
case USB_INT_GP_DEV_RESET:
return USB->GINTSTS_b.USB_RST ? TRUE : FALSE;
break;
case USB_INT_GP_DEV_ENUMDONE:
return USB->GINTSTS_b.ENUM_DONE ? TRUE : FALSE;
break;
case USB_INT_GP_DEV_SUSP:
return USB->GINTSTS_b.USB_SUS ? TRUE : FALSE;
break;
case USB_INT_GP_DEV_EARLY:
return USB->GINTSTS_b.EARLY_SUS ? TRUE : FALSE;
break;
case USB_INT_GP_SOF:
return USB->GINTSTS_b.SOF ? TRUE : FALSE;
break;
case USB_INT_GP_MIS:
return USB->GINTSTS_b.MODE_MIS ? TRUE : FALSE;
break;
case USB_INT_GP_IDCHG:
return USB->GINTSTS_b.CIDSC ? TRUE : FALSE;
break;
case USB_INT_GP_SESSREQ:
return USB->GINTSTS_b.SR ? TRUE : FALSE;
break;
default:
break;
}
return FALSE;
}
void USB_INT_clrGP(USB_INT_GP name)
{
switch (name) {
case USB_INT_GP_HOST_DISC:
USB->GINTSTS = BIT(29);
break;
case USB_INT_GP_DEV_RESET:
USB->GINTSTS = BIT(12);
break;
case USB_INT_GP_DEV_ENUMDONE:
USB->GINTSTS = BIT(13);
break;
case USB_INT_GP_DEV_SUSP:
USB->GINTSTS = BIT(11);
break;
case USB_INT_GP_DEV_EARLY:
USB->GINTSTS = BIT(10);
break;
case USB_INT_GP_SOF:
USB->GINTSTS = BIT(3);
break;
case USB_INT_GP_MIS:
USB->GINTSTS = BIT(1);
break;
case USB_INT_GP_IDCHG:
USB->GINTSTS = BIT(28);
break;
case USB_INT_GP_SESSREQ:
USB->GINTSTS = BIT(30);
break;
default:
break;
}
}
BOOL USB_otgControl(USB_OTG_CTL ctl, BOOL val)
{
BOOL retval = FALSE;
switch (ctl) {
case USB_OTG_DEV_HNSUCC:
retval = USB->GOTGCTL_b.HST_NEG_SCS ? TRUE : FALSE;
break;
case USB_OTG_DEV_HNPREQ:
retval = USB->GOTGCTL_b.HNP_REQ ? TRUE : FALSE;
USB->GOTGCTL_b.HNP_REQ = val ? 1 : 0;
break;
case USB_OTG_HST_HNPENABLE:
retval = USB->GOTGCTL_b.HST_SET_HNP_EN ? TRUE : FALSE;
USB->GOTGCTL_b.HST_SET_HNP_EN = val ? 1 : 0;
break;
case USB_OTG_DEV_HNPENABLE:
retval = USB->GOTGCTL_b.DEV_HNP_EN ? TRUE : FALSE;
USB->GOTGCTL_b.DEV_HNP_EN = val ? 1 : 0;
break;
default:
break;
}
return retval;
}