?? usbhw.c
字號:
* Parameters: pData: Pointer to Data Buffer
* Return Value: Number of bytes read
*/
DWORD USB_ReadSetupEP0 (BYTE *pData) {
DWORD cnt, n;
USBEIX = EIX_SEL_EP0SET; // Setup buffer allocated
USBECtrl |= ECTRL_DATA; // set DATA bit
cnt = USBDCnt;
for (n = 0; n < (cnt + 3) / 4; n++) {
*((__packed DWORD *)pData) = USBData;
pData += 4;
}
return (cnt);
}
/*
* Read USB Endpoint Data
* Parameters: EPNum: Endpoint Number
* EPNum.0..3: Address
* EPNum.7: Dir
* pData: Pointer to Data Buffer
* Return Value: Number of bytes read
*/
DWORD USB_ReadEP (DWORD EPNum, BYTE *pData) {
DWORD cnt, n;
USBEIX = EPNum << 1; // direction: OUT
if ( (EPNum & 0x7F) == 0x00 ) {
USBECtrl |= ECTRL_DATA; // set DATA bit if EP0
}
cnt = USBDCnt;
for (n = 0; n < (cnt + 3) / 4; n++) {
*((__packed DWORD *)pData) = USBData;
pData += 4;
}
return (cnt);
}
/*
* Write USB Endpoint Data
* Parameters: EPNum: Endpoint Number
* EPNum.0..3: Address
* EPNum.7: Dir
* pData: Pointer to Data Buffer
* cnt: Number of bytes to write
* Return Value: Number of bytes written
*/
DWORD USB_WriteEP (DWORD EPNum, BYTE *pData, DWORD cnt) {
DWORD n;
USBEIX = ((EPNum & 0x7F)<<1)|EIX_DIR; // direction IN
if ( (EPNum & 0x7F) == 0x00 ) {
USBECtrl |= ECTRL_DATA; // set DATA bit if EP0
}
USBDCnt = cnt;
for (n = 0; n < (cnt + 3) / 4; n++) {
USBData = *((__packed DWORD *)pData);
pData += 4;
}
return (cnt);
}
/*
* Read USB Status Input (Zero Data) on Endpoint 0
* Parameters: None
* Return Value: Number of bytes read
*/
DWORD USB_StatusInEP0 (void) {
USBEIX = EIX_DIR; // direction: IN
USBECtrl |= ECTRL_STATUS;
return (0);
}
/*
* Write USB Status Output (Zero Data) on Endpoint 0
* Parameters: None
* Return Value: Number of bytes written
*/
DWORD USB_StatusOutEP0 (void) {
USBEIX = 0x00; // direction: OUT
USBECtrl |= ECTRL_STATUS;
return (0);
}
#if USB_DMA
/*
* Setup USB DMA Transfer for selected Endpoint
* Parameters: Endpoint Num
* Src or Dest address, for EP IN, it's the src
* for EP OUT, it's the Dest.
* Return Value: TRUE - Success, FALSE - Error
*/
BOOL USB_DMA_Setup(DWORD EPNum, DWORD SrcDestAddr, DWORD Length) {
DWORD ep_addr;
DWORD regCtrl0, regCtrl1;
ep_addr = EPNum & 0x7F;
if ( ep_addr == 0 ) {
return( FALSE );
}
if ( EPNum & 0x80 ) { // Direction IN, channel 1
UDMA1Src = SrcDestAddr; // Source is IRAM on LPC288x
switch ( ep_addr ) {
case 1:
UDMA1Dest = 0x00000004; // EP1 IN transfer
break;
case 2:
UDMA1Dest = 0x00000008; // EP2 IN transfer
break;
}
UDMA1Throtl = 0x00000001;
UDMA1Cnt = Length;
UDMAFCP3 = 0x00000001;
/* for Channel 1, ERR(31) and EOT(30) Enabled, DFC_PORT(23) is
IN EP2(0x3), DFC_MODE(21) is 0x1(IN), DA_ADJ(19) is 0x0(IN),
DTYPE(17) is 0x2(32 bit), DEST(15) is 0x1(IN), SFC_PORT(11) is
N/A, SFC_MODE(9) is 0x0(IN), SA_ADJ(7) is 0x1(IN src
adr inc), STYPE(5) is 0x2(32 bit), SOURCE(3) is 0x0(IN), CHEN
is 0x3 */
regCtrl1 = 0xC0000000|(0x3<<23)|(0x1<<21)|(0x0<<19)|(0x2<<17)
|(0x1<<15)|(0x0<<9)|(0x1<<7)|(0x2<<5)|(0x0<<3);
UDMA1Ctrl = regCtrl1;
}
else { // direction OUT, channel 0
switch ( ep_addr ) {
case 1:
UDMA0Src = 0x00000004; // EP1 OUT transfer
break;
case 2:
UDMA0Src = 0x00000008; // EP2 OUT transfer
break;
}
UDMA0Dest = SrcDestAddr; // Destination is IRAM on LPC288x
UDMA0Throtl = 0x00000001;
UDMA0Cnt = Length; // For FS = 0x40, for HS = 0x200
UDMAFCP2 = 0x00000001;
/* for Channel 0, ERR(31) and EOT(30) Enabled, DFC_PORT(23) is N/A,
DFC_MODE(21) is 0x0( no dest FC, OUT), DA_ADJ(19) is 0x1(OUT dest
adr inc), DTYPE(17) is 0x2(32 bit), DEST(15) is 0x0(OUT), SFC_PORT(11)
is 0x2(OUT EP2), SFC_MODE(9) is 0x1(OUT), SA_ADJ(7) is 0x0(OUT),
STYPE(5) is 0x2(32 bit), SOURCE(3) is 0x1(OUT). */
regCtrl0 = 0xC0000000|(0x0<<21)|(0x1<<19)|(0x2<<17)
|(0x0<<15)|(0x2<<11)|(0x1<<9)|(0x0<<7)|(0x2<<5)|(0x1<<3);
UDMA0Ctrl = regCtrl0;
}
return (TRUE); /* Success */
}
/*
* Enable USB DMA Endpoint
* Parameters: Channel Num
* Return Value: None
*/
void USB_DMA_Enable (DWORD CHNum) {
if ( CHNum == 0x0 ) {
// UDMAIntEn |= 0x06;
UDMA0Ctrl |= 0x01; // Send DMA request on channel 0
}
else if ( CHNum == 0x01 ) {
// UDMAIntEn |= 0x60;
UDMA1Ctrl |= 0x01; // Send DMA request on channel 1
}
}
/*
* Disable USB DMA Endpoint
* Parameters: Channel Num
* Return Value: None
*/
void USB_DMA_Disable (DWORD CHNum) {
if ( CHNum == 0x00 ) {
UDMAIntDis |= 0x06;
}
else if ( CHNum == 0x01 ) {
UDMAIntDis |= 0x60;
}
}
/*
* Get USB DMA Endpoint Status
* Parameters: Channel Num
*
* Return Value: DMA Status
*/
DWORD USB_DMA_Status (DWORD CHNum) {
DWORD regVal, CHStat;
if ( CHNum == 1 ) { // direction IN, channel 1
regVal = UDMA1Stat;
} else if ( CHNum == 0 ) {
regVal = UDMA0Stat;
}
switch ( regVal & 0x03 ) {
case 0:
CHStat = USB_DMA_IDLE;
break;
case 1:
CHStat = USB_DMA_BUSY;
break;
case 2:
CHStat = USB_DMA_SUSPEND;
break;
case 3:
CHStat = USB_DMA_ERROR;
break;
}
return( CHStat );
}
#endif /* USB_DMA */
/*
* Get USB Last Frame Number
* Parameters: None
* Return Value: Frame Number
*/
DWORD USB_GetFrame (void) {
DWORD val;
val = USBFN;
return (val);
}
/*
* USB Interrupt Service Routine
*/
void USB_ISR(void)
{
DWORD disr, n, m;
disr = USBIntStat; /* Device Interrupt Status */
if ( disr != 0 )
{
/* Device Status Interrupt (Reset, Connect change, Suspend/Resume) */
if (disr & (0x1<<0)) { /* Reset */
USB_Reset();
USB_SetAddress(0x00);
#if USB_RESET_EVENT
USB_Reset_Event();
#endif
goto isr_end;
}
if (disr & (0x1<<3)) { /* Suspend */
USB_Suspend();
#if USB_SUSPEND_EVENT
USB_Suspend_Event();
#endif
goto isr_end;
}
if (disr & (0x1<<4)) { /* Resume */
USBLock = 0xAA37;
USB_Resume();
#if USB_RESUME_EVENT
USB_Resume_Event();
#endif
goto isr_end;
}
#if USB_SOF_EVENT
/* Start of Frame Interrupt */
if (disr & (0x1<<1)) {
USB_SOF_Event();
USBIntClr |= (0x1<<1);
}
#endif
if (disr & (0x1<<5)) { /* High speed or full speed */
USBLock = 0xAA37;
DevStatusFS2HS = TRUE;
goto isr_end;
}
/* Setup 0 packet coming */
if (disr & (0x1<<7)) {
USB_P_EP[0](USB_EVT_SETUP);
goto isr_end;
}
}
while (USBEIntStat) { /* Endpoint Interrupt Status */
for (n = 0; n < USB_EP_NUM; n++) { /* Check All Endpoints */
if (USBEIntStat & (1 << n)) {
m = n >> 1;
USBEIntClr = 1 << n;
if ((n & 1) == 0) { /* OUT Endpoint */
if (USB_P_EP[m]) {
USB_P_EP[m](USB_EVT_OUT);
}
} else { /* IN Endpoint */
if (USB_P_EP[m]) {
USB_P_EP[m](USB_EVT_IN);
}
}
}
}
}
#if USB_DMA
if (UDMAIntStat & 0x02) { /* End of Transfer Interrupt */
DMACh0EOT++;
UDMAIntClr = 0x02;
}
if (UDMAIntStat & 0x20) {
DMACh1EOT++;
UDMAIntClr = 0x20;
}
if (UDMAIntStat & 0x04) { /* System Error Interrupt */
USB_DMA_Status(0);
UDMAIntClr = 0x04;
}
if (UDMAIntStat & 0x40) {
USB_DMA_Status(1);
UDMAIntClr = 0x40;
}
#endif /* USB_DMA */
isr_end:
USBIntClr = disr;
return;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -