843 lines
19 KiB
C
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>© 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;
|
|
}
|