📄 usb_drv.c
字号:
* pipes.
*****************************************************************************/
void USB_SOF_Handler(void)
{
/*can add some code if isochronous transfer*/
INTSTAT_SOFTOKF = 1; /*clear the interrupt flag*/
}
/******************************************************************************
* Function: void USB_Stall_Handler(void)
* Input: None
* Output: None
* Overview: The STALLIF is set anytime the SIE sends out a STALL
* packet regardless of which endpoint causes it.
* A Setup transaction overrides the STALL function. A stalled
* endpoint stops stalling once it receives a setup packet.
*
* There are a few reasons for an endpoint to be stalled.
* 1. When a non-supported USB request is received.
* Example: GET_DESCRIPTOR(DEVICE_QUALIFIER)
* 2. When an endpoint is currently halted.
* 3. When the device class specifies that an endpoint must
* stall in response to a specific event.
*
*****************************************************************************/
void USB_Stall_Handler(void)
{
if((STAT & 0xF0)== 0x00)
{
if(EPCTL0_EPSTALL == 1)
EPCTL0_EPSTALL = 0;
/*Notice if is generated by BDTSTALL, the firmware should notice the IN or OUT DIR*/
/*we only set it for OUT direction in this demo*/
USB_Prepare_Next_Trf();
}
/*
else
{
//Add the process for STALL generated by other endpoints (even or odd)
}
*/
INTSTAT_STALLF = 1;
}
/******************************************************************************
* Function: void USB_Error_Handler(void)
* Input: None
* Output: None
* Overview: You can check error register to see which error occured
* Note: None
*****************************************************************************/
void USB_Error_Handler(void)
{
INTSTAT_ERRORF = 1;
/*add code to check the error source */
if((ERRSTAT_BUFERRF) && ((STAT & 0xF0)==0)) /*Bdt buffer overflow*/
{
USB_Prepare_Next_Trf();
}
/*check the other error at here */
ERRSTAT = 0xBF; /*clear all errors*/
return;
}
/******************************************************************************
* Function: void USB_Bus_Reset_Handler(void)
*
* Input: None
* Output: None
*
* Overview: Once a USB bus reset is received from the host, this
* function should be called. It resets the device address to
* zero, disables all non-EP0 endpoints, initializes EP0 to
* be ready for default communication, clears all USB
* interrupt flags, unmasks applicable USB interrupts, and
* reinitializes internal state-machine.
*****************************************************************************/
void USB_Bus_Reset_Handler(void)
{
ERRSTAT = 0xFF; /* clear USB error flag*/
INTSTAT = 0xBF; /* clear USB interrupt*/
ERRENB = 0xBF; /* disable all USB error interrupt sources*/
INTENB = 0x9F; /* enable all interrupts except RESUME*/
ADDR = 0x00; /* reset to default address*/
Clear_Mem((byte*)&EPCTL1,6); /* disable all endpoints */
EPCTL0 = EP_CTRL|HSHK_EN; /* enable endpoint 0*/
while(INTSTAT_TOKDNEF ) /* Flush any pending transactions because 4 status buffer*/
INTSTAT = 0xBF;
USB_Prepare_Next_Trf(); /*prepare to receive the setup packet*/
Usb_Stat.BitCtl.RemoteWakeup = 0; /* default status flag to disable*/
Usb_Active_Cfg = 0;
Usb_Device_State = DEFAULT_STATE;
}
/******************************************************************************
* Function: void USB_Buf_Rdy(buffer_dsc)
*
* PreCondition: IN endpoint: Buffer is control by MCU.
* OUT endpoint: Buffer is conrolled by SIE.
*
* Input: byte buffer_dsc: one buffer descriptor in Bdtmap
* Output: None
*
* Overview: This function turns the buffer ownership to SIE,
* and toggles the DTS bit for synchronization.
* Note: This function should not be called by Endpoint 5 or 6
* because they are pingpong buffer, DATA0/1 do not need
* to be switched
*****************************************************************************/
void USB_Buf_Rdy(BUFF_DSC *buffer_dsc)
{
buffer_dsc->Stat._byte &= _DATA1;
buffer_dsc->Stat.McuCtlBit.DATA = ~ buffer_dsc->Stat.McuCtlBit.DATA; /* Toggle DTS bit*/
buffer_dsc->Stat._byte |= _SIE|_DTS; /*give the ownership to SIE*/
}
/******************************************************************************
* Function: void Clear_Mem(byte* startAdr,byte count)
* Input:
* Output: None
* Overview: None
*****************************************************************************/
void Clear_Mem(byte* startAdr,byte count)
{
byte i;
for(i=0; i < count; i++)
{
*(startAdr + i) = 0x00;
}
return;
}
/******************************************************************************
* Function: void interrupt USB_ISR()
* Input:
* Output: None
* Overview: The USB stat interrupt service routine
* Note: None
*****************************************************************************/
void interrupt 7 USB_ISR()
{
if((USBCTL0_LPRESF) && (Usb_Device_State == USB_SUSPEND))
{
USBCTL0_USBRESMEN = 0;
}
if(INTSTAT_RESUMEF && INTENB_RESUME)
USB_WakeFrom_Suspend();
if(INTSTAT_USBRSTF && INTENB_USBRST)
{
USB_Bus_Reset_Handler();
}
if(INTSTAT_SOFTOKF && INTENB_SOFTOK)
{
USB_SOF_Handler();
}
if(INTSTAT_STALLF && INTENB_STALL )
USB_Stall_Handler();
if(INTSTAT_ERRORF && INTENB_ERROR)
USB_Error_Handler();
if((INTSTAT_SLEEPF && INTENB_SLEEP)&&(Usb_Device_State >= CONFIGURED_STATE))
{
Usb_Device_State = USB_ENTER_SUSPEND; /*do not hope enter into suspend */
INTSTAT_SLEEPF = 1;
}
if(INTSTAT_TOKDNEF && INTENB_TOKDNE)
{
USB_Transaction_Handler();
INTSTAT_TOKDNEF = 1; /*write 1 to clear*/
}
return;
}
/******************************************************************************
* Function: void interrupt IRQ_ISR()
* Input:
* Output: None
* Overview: The IRQ is used to wakup the USB and MCU.
* Note: None
*****************************************************************************/
void interrupt 2 IRQ_ISR()
{
IRQSC_IRQACK = 1;
return;
}
/******************************************************************************
* Function: unsigned char USB_WakeUp()
* Input:
* Output: 0: noise, re-entern into sleep
* 1: Bus wake-up
* 2: remote wake up
* Overview: The USB sleep and wake up
* Note: None
*****************************************************************************/
unsigned char USB_WakeUp(void )
{
int delay_count;
asm STOP; /*MCU enter into stop3*/
Usb_Device_State = CONFIGURED_STATE;
if((! USBCTL0_LPRESF) /*&& (Kbi_Stat)*/) /*Is the KBI interrupt bring the MCU out of STOP3*/
{
if(Usb_Stat.BitCtl.RemoteWakeup == 1) /*Is remote wakeup supported*/
return 2; /*will enable remote wakeup*/
else
return 0;
} /*tell MCU it should enter STOP3 again*/
else
{ /*add delay to filter the noise */
delay_count = 50;
do
{
delay_count--;
__RESET_WATCHDOG();
}while(delay_count);
if(INTSTAT_RESUMEF) /*The resume signal has engouh time to set RESUMEF bit*/
{
return 1; /*USB resume*/
}
else
return 0; /*resume is caused by noise*/
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -