📄 usb_driver.c
字号:
{
return(usbStatus);
}
//---------------------------------------------------------------------------------------
// Decode USB commands
// Called when SETUP request received
//---------------------------------------------------------------------------------------
void USB_StandardRequest(void)
{
word temp;
uchar idxTmp;
extern byte* ptrToConfigDsc;
extern byte* ptrToDeviceDsc;
extern byte* STRING_DSC_TAB[STRING_DSC_TAB_LEN];
// Clear pending Data Control State
// Standart reguest GET DESCRIPTOR
if (((SetupPcktStrc *)ep0BufSh)->bRequest == RQST_GET_DESCRIPTOR)
{
switch ((byte)((SetupPcktStrc *)ep0BufSh)->wValue)
{
// Get CONFIGURATION Descriptor request
case (DSC_CONFIGURATION_TYPE):
// number of requested data
temp = CHNG_ENDIAN(((SetupPcktStrc *)ep0BufSh)->wLength);
if (temp > 0xFF) temp = 0xFF;
if ((byte)temp > *(ptrToConfigDsc + 2))
temp = *(ptrToConfigDsc + 2);
(void) USB_TxBuff0(ptrToConfigDsc, (byte)temp);
break;
// Get DEVICE Descriptor
case (DSC_DEVICE_TYPE):
temp = CHNG_ENDIAN(((SetupPcktStrc *)ep0BufSh)->wLength);
if (temp > 0xFF) temp = 0xFF;
if (temp > *ptrToDeviceDsc)
temp = *ptrToDeviceDsc;
// Upload Data to EP buffer
(void) USB_TxBuff0(ptrToDeviceDsc, (byte)temp);
break;
// Get STRING Descriptor
case (DSC_STRING_TYPE):
// load STRING descriptor index number
idxTmp = H_BYTE(((SetupPcktStrc *)ep0BufSh)->wValue);
if (idxTmp <= STRING_DSC_TAB_LEN)
{ // load requested number of bytes
temp = CHNG_ENDIAN(((SetupPcktStrc *)ep0BufSh)->wLength);
if (temp > 0xFF) temp = 0xFF;
// if string descriptor length is shorter than requested num of bytes, trim it
if (temp > * STRING_DSC_TAB[idxTmp])
temp = * STRING_DSC_TAB[idxTmp];
(void) USB_TxBuff0(STRING_DSC_TAB[idxTmp], (byte)temp);
}
// Illegal String descriptor Index
else
USB_WRSTALL_EP0(1);
break;
// Illegal descriptor type
default:
{
#ifdef USB_GET_DESCRIPTOR_CB
extern void USB_GET_DESCRIPTOR_CB(void);
USB_GET_DESCRIPTOR_CB();
#else
USB_WRSTALL_EP0(1);
#endif
}
break;
} // end switch
}
else USB_WRSTALL_EP0(1);
}
//-------------------------------------------------------------------
// USB Interrupt Service Routines
//-------------------------------------------------------------------
interrupt void USB_EP_ISR(void)
{
/* ENDPOINT 0 - dedicated to control transfer */
if(UEP0CSR & UEP0CSR_TFRC_IN_MASK) // EP0 IN packet odeslan, naplnim zbytek?
{
UEP0CSR &= ~UEP0CSR_TFRC_IN_MASK;
if(usbStatus & CTRL_READ_STATE)
{
pDst0 = EP0_BASE_ADR;
cntDst0 = EP0_BUFFER_SIZE;
while(cntDst0 && cntSrc0)
{
*pDst0++ = *pSrc0++;
cntDst0--;
cntSrc0--;
}
if(cntDst0 > 0)
usbStatus &= ~CTRL_READ_STATE;
// set DVALID_IN flag and data length, others bits leave unchanged
UEP0CSR = (EP0_BUFFER_SIZE - cntDst0)<<4 | (UEP0CSR_DVALID_IN_MASK | UEP0CSR_TFRC_IN_MASK | UEP0CSR_TFRC_OUT_MASK | UEP0CSR_DVALID_OUT_MASK);
}
}
if(UEP0CSR & UEP0CSR_TFRC_OUT_MASK) //EP0 OUT packet prijat
{
if(usbStatus & CTRL_WRITE_STATE)
{
pSrc0 = EP0_BASE_ADR;
cntSrc0 = EP0_BUFFER_SIZE;
while(cntDst0 && cntSrc0)
{
*pDst0++ = *pSrc0++;
cntDst0--;
cntSrc0--;
}
if(cntSrc0 > 0)
{
// end of data state in OUT packet -> we must send IN packet with zero data length
UEP0CSR = (UEP0CSR_DVALID_IN_MASK | UEP0CSR_TFRC_IN_MASK | UEP0CSR_TFRC_OUT_MASK | UEP0CSR_DVALID_OUT_MASK);
usbStatus &= ~CTRL_WRITE_STATE;
}
#ifndef USB_CALLBACK_EP0
#define USB_CALLBACK_EP0 0
#endif
#if USB_CALLBACK_EP0 == 1
USB_RxReadyCB0();
#endif
}
UEP0CSR &= ~(UEP0CSR_TFRC_OUT_MASK | UEP0CSR_DVALID_OUT_MASK); // Clear TFRC0 and DVALID_OUT flag
}
// ENDPOINT 1
// endpoint is enabled
#ifndef USB_CALLBACK_EP1
#define USB_CALLBACK_EP1 0
#endif
#if EP1_MODE
if(UEP1CSR & UEP1CSR_TFRC_MASK)
{
// EP in IN mode
#if EP1_DIR & EP_DIR_IN
pDst1 = EP1_BASE_ADR;
cntDst1 = EP1_BUFFER_SIZE;
#if USB_CALLBACK_EP1 == 0
while(cntDst1 && cntSrc1)
{
cntDst1--;
cntSrc1--;
*pDst1++ = *pSrc1++;
}
if((uchar)(EP1_BUFFER_SIZE - cntDst1) > 0)
{
UEP1DSR = EP1_BUFFER_SIZE - cntDst1;
UEP1CSR |= UEP1CSR_DVALID_MASK;
}
#else
USB_TxEmptyCB1(EP1_BUFFER_SIZE);
#endif
// EP in OUT mode
#else
pSrc1 = EP1_BASE_ADR;
cntSrc1 = UEP1DSR;
#if USB_CALLBACK_EP1 == 0
while(cntSrc1 && cntDst1)
{
cntSrc1--;
cntDst1--;
*pDst1++ = *pSrc1++;
}
if(cntSrc1 == 0)
UEP1CSR &= ~UEP1CSR_DVALID_MASK;
#else
USB_RxReadyCB1(UEP1DSR);
#endif
#endif
UEP1CSR &= ~UEP1CSR_TFRC_MASK;
}
#endif
// ENDPOINT 2
// endpoint is enabled
#ifndef USB_CALLBACK_EP2
#define USB_CALLBACK_EP2 0
#endif
#if EP2_MODE
if(UEP2CSR & UEP2CSR_TFRC_MASK)
{
// EP in IN mode
#if EP2_DIR & EP_DIR_IN
pDst2 = EP2_BASE_ADR;
cntDst2 = EP2_BUFFER_SIZE;
#if USB_CALLBACK_EP2 == 0
while(cntDst2 && cntSrc2)
{
cntDst2--;
cntSrc2--;
*pDst2++ = *pSrc2++;
}
if((uchar)(EP2_BUFFER_SIZE - cntDst2) > 0)
{
UEP2DSR = EP2_BUFFER_SIZE - cntDst2;
UEP2CSR |= UEP2CSR_DVALID_MASK;
}
#else
USB_TxEmptyCB2(EP2_BUFFER_SIZE);
#endif
// EP in OUT mode
#else
pSrc2 = EP2_BASE_ADR;
cntSrc2 = UEP2DSR;
#if USB_CALLBACK_EP2 == 0
while(cntSrc2 && cntDst2)
{
cntSrc2--;
cntDst2--;
*pDst2++ = *pSrc2++;
}
if(cntSrc2 == 0)
UEP2CSR &= ~UEP2CSR_DVALID_MASK;
#else
USB_RxReadyCB2(UEP2DSR);
#endif
#endif
UEP2CSR &= ~UEP2CSR_TFRC_MASK;
}
#endif
/* ENDPOINT 3 */
// endpoint is enabled
#ifndef USB_CALLBACK_EP3
#define USB_CALLBACK_EP3 0
#endif
#if EP3_MODE
if(UEP3CSR & UEP3CSR_TFRC_MASK)
{
// EP in IN mode
#if EP3_DIR & EP_DIR_IN
pDst3 = EP3_BASE_ADR;
cntDst3 = EP3_BUFFER_SIZE;
#if USB_CALLBACK_EP3 == 0
while(cntDst3 && cntSrc3)
{
cntDst3--;
cntSrc3--;
*pDst3++ = *pSrc3++;
}
if((uchar)(EP3_BUFFER_SIZE - cntDst3) > 0)
{
UEP3DSR = EP3_BUFFER_SIZE - cntDst3;
UEP3CSR |= UEP3CSR_DVALID_MASK;
}
#else
USB_TxEmptyCB3(EP3_BUFFER_SIZE);
#endif
// EP in OUT mode
#else
pSrc3 = EP3_BASE_ADR;
cntSrc3 = UEP3DSR;
#if USB_CALLBACK_EP3 == 0
while(cntSrc3 && cntDst3)
{
cntSrc3--;
cntDst3--;
*pDst3++ = *pSrc3++;
}
if(cntSrc3 == 0)
UEP3CSR &= ~UEP3CSR_DVALID_MASK;
#else
USB_RxReadyCB3(UEP3DSR);
#endif
#endif
UEP3CSR &= ~UEP3CSR_TFRC_MASK;
}
#endif
// ENDPOINT 4
// endpoint is enabled
#ifndef USB_CALLBACK_EP4
#define USB_CALLBACK_EP4 0
#endif
#if EP4_MODE
if(UEP4CSR & UEP4CSR_TFRC_MASK)
{
// EP in IN mode
#if EP4_DIR & EP_DIR_IN
pDst4 = EP4_BASE_ADR;
cntDst4 = EP4_BUFFER_SIZE;
#if USB_CALLBACK_EP4 == 0
while(cntDst4 && cntSrc4)
{
cntDst4--;
cntSrc4--;
*pDst4++ = *pSrc4++;
}
if((uchar)(EP4_BUFFER_SIZE - cntDst4) > 0)
{
UEP4DSR = EP4_BUFFER_SIZE - cntDst4;
UEP4CSR |= UEP4CSR_DVALID_MASK;
}
#else
USB_TxEmptyCB4(EP4_BUFFER_SIZE);
#endif
// EP in OUT mode
#else
pSrc4 = EP4_BASE_ADR;
cntSrc4 = UEP4DSR;
#if USB_CALLBACK_EP4 == 0
while(cntSrc4 && cntDst4)
{
cntSrc4--;
cntDst4--;
*pDst4++ = *pSrc4++;
}
if(cntSrc4 == 0)
UEP4CSR &= ~UEP4CSR_DVALID_MASK;
#else
USB_RxReadyCB4(UEP4DSR);
#endif
#endif
UEP4CSR &= ~UEP4CSR_TFRC_MASK;
}
#endif
}
//-------------------------------------------------------------------
// USB Interrupt Service Routines
//-------------------------------------------------------------------
interrupt void USB_SYS_ISR(void)
{
// setup packet interrupt?
#if USB_SETUPIE_ENA != 0
if(USBSR & USBSR_SETUP_MASK)
{
// Copy ep0 data into shadow data buffer
ep0BufSh[0] = *(EP0_BASE_ADR + 0);
ep0BufSh[1] = *(EP0_BASE_ADR + 1);
ep0BufSh[2] = *(EP0_BASE_ADR + 2);
ep0BufSh[3] = *(EP0_BASE_ADR + 3);
ep0BufSh[4] = *(EP0_BASE_ADR + 4);
ep0BufSh[5] = *(EP0_BASE_ADR + 5);
ep0BufSh[6] = *(EP0_BASE_ADR + 6);
ep0BufSh[7] = *(EP0_BASE_ADR + 7);
// GET_DESCRIPTOR, SYNC_FRAME, class/vendor specific request
UEP0CSR &= ~(UEP0CSR_TFRC_OUT_MASK | UEP0CSR_DVALID_OUT_MASK); // Clear TFRC_0UT bit
USBSR &= ~USBSR_SETUP_MASK; // Clear SETUP flag
usbStatus &= ~(CTRL_READ_STATE | CTRL_WRITE_STATE);
// standard requests
if ((((SetupPcktStrc *)ep0BufSh)->bmRequestType & M_COMMAND_TYPE_MASK) == M_STANDARD_COMMAND)
{
USB_StandardRequest();
}
// class specific requests
else if ((((SetupPcktStrc *)ep0BufSh)->bmRequestType & M_COMMAND_TYPE_MASK) == M_CLASS_COMMAND)
{
#ifdef USB_CLASS_REQUEST_CB
extern void USB_CLASS_REQUEST_CB(void);
USB_CLASS_REQUEST_CB();
#else
USB_WRSTALL_EP0(1);
#endif
}
// vendor specific requests
else if ((((SetupPcktStrc *)ep0BufSh)->bmRequestType & M_COMMAND_TYPE_MASK) == M_VENDOR_COMMAND)
{
#ifdef USB_VENDOR_REQUEST_CB
extern void USB_VENDOR_REQUEST_CB(void);
USB_VENDOR_REQUEST_CB();
#else
USB_WRSTALL_EP0(1);
#endif
}
// all other illegal requests
else
{
USB_WRSTALL_EP0(1);
}
}
#endif
// Start of frame interrupt
#if USB_SOFIE_ENA != 0
if(USBSR & USBSR_SOF_MASK)
{
USBSR &= ~USBSR_SOF_MASK; // Clear SOF flag
USB_SofCB();
}
#endif
// Config change interrupt
#if USB_CONFIGCHGIE_ENA != 0
if(USBSR & USBSR_CONFIG_CHG_MASK)
{
USBSR &= ~USBSR_CONFIG_CHG_MASK; // Clear CONFIGCHG flag
USB_ConfigChngCB();
}
#endif
// Reset flag - divne!!! Jak to ma byt?
#if USB_USBRSTIE_ENA != 0
if (USBSR & USBSR_USBRST_MASK)
{
USBSR &= ~USBSR_USBRST_MASK; // Clear USB Reset flag
// clear all unlatched STALL
USIMR_EP0_STALL = 0;
#if EP1_MODE
UEP1CSR_STALL = 0;
#endif
#if EP2_MODE
UEP2CSR_STALL = 0;
#endif
#if EP3_MODE
UEP3CSR_STALL = 0;
#endif
#if EP4_MODE
UEP4CSR_STALL = 0;
#endif
USB_ResetCB(); // Custom RESET Handling
}
#endif
// Resume flag - budim procesor ze spanku
#if USB_RESUMEFIE_ENA != 0
if (USBSR & USBSR_RESUMEF_MASK)
{
USBSR &= ~USBSR_RESUMEF_MASK; // Clear USB RESUME flag
USB_ResumeCB(); // User setting for USB resume
USBCR |= USBCR_USBCLKEN_MASK; // Enable USB clk
}
#endif
// Suspend flag
#if USB_SUSPNDIE_ENA != 0
if (USBSR & USBSR_SUSPND_MASK)
{
USBSR &= ~USBSR_SUSPND_MASK; // Clear USB Suspend
USBCR &= ~USBCR_USBCLKEN_MASK; // Stop USB module clock
USB_SuspendCB();
}
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -