📄 usb.c
字号:
/*
* File: usb.c
* Purpose: Device Driver for the USB module of the MCF5275
*/
#include "common.h"
#include "usb.h"
extern int usb_isr_debug_print = 0;
/********************************************************************/
/* Global Endpoint Status Structures */
USB_EP_STATE ep[NUM_ENDPOINTS];
/* Global USB Descriptor Data (application specific) */
extern DESCRIPTOR_STRUCT Descriptors;
extern CFG_BUFF_STRUCT cfg_data;
extern unsigned char String0Desc;
extern unsigned char String1Desc;
extern unsigned char String2Desc;
uint32 usb_reset_stop =0;
uint32 usb_change_cfg =0;
uint32 usb_devreq_in_progress =0;
/* Full Desc Ram Array */
char Desc_RAM[0x400];
/* EP1 Data test variables */
int iPacket = 0;
int iPacketEP1 = 0;
uint8 INdata = 0x00;
uint32 FIFOdata = 0x00000000;
uint32 TotalData = 0x00000000;
int EOP = FALSE;
uint32 test = 0;
/* For Enumeration process, keep trace of current Configuration and Interface */
int8 cConfiguration = 0;
int8 cInterface = 0;
/********************************************************************/
void
usb_init(void)
{
uint32 i, DescSize, CfgSize;
uint8 *pCfgDesc;
uint8 *pDevDesc;
uint8 *pStr0;
uint8 *pStr1;
uint8 *pStr2;
uint32 tmp;
/* Disable USB device as it should be disabled the first time */
MCF_USB_CR &= ~MCF_USB_CR_USBENA;
/* reset USB module to allow CFG download */
MCF_USB_CR |= MCF_USB_CR_USBRST;
/* Setup pointers to Cfg and Desc Data*/
pDevDesc = (uint8 *)usb_get_desc(-1, -1, -1, -1);
DescSize = (sizeof(Descriptors));
/* Initialize Configuration pointers and variables */
pCfgDesc = (uint8 *)&cfg_data;
CfgSize =(sizeof(cfg_data));
/* Initialize Endpoint status structures */
ep[0].ttype = CONTROL;
ep[0].packet_size = ((USB_DEVICE_DESC *)pDevDesc)->bMaxPacketSize0;
ep[0].fifo_length = 32;
ep[0].buffer.start = 0;
ep[0].buffer.free = 0;
for (i = 1; i < NUM_ENDPOINTS; i++)
ep[i].ttype = DISABLED;
//////////////////////////////////////////////////////////////////
//
// Download Configuration data
//
//////////////////////////////////////////////////////////////////
/* Set DADR field to the 0x000 to download Configuration */
MCF_USB_DAR = 0x0000;
/* Wait for CFG bit to be set from the above reset */
while(!(MCF_USB_DAR & MCF_USB_DAR_CFG));
/* Load the Configuration RAM with the cfg buffers */
for (i = 0; i < (CfgSize); i++)
{
tmp = pCfgDesc[i];
MCF_USB_DDR = tmp;
/* wait until BSY is clear */
while(MCF_USB_DAR & MCF_USB_DAR_BSY);
}
/* Fill up the reset of the CFG RAM with "0" */
while(MCF_USB_DAR & MCF_USB_DAR_CFG)
{
MCF_USB_DDR = 0x00;
/* wait until BSY is clear */
while(MCF_USB_DAR & MCF_USB_DAR_BSY);
}
//////////////////////////////////////////////////////////////////
//
// Download Descriptor data
//
//////////////////////////////////////////////////////////////////
/* Clear the CFG bit in the USB_DAR to download Descriptors first */
/* This also sets DADR field to STARTOFDESC */
MCF_USB_DAR = STARTOFDESC;
/* Verify that the CFG bit is NOT set in the USB_DAR register */
if(MCF_USB_DAR & MCF_USB_DAR_CFG)
{
printf("usb_init Error: CFG bit is set in the USB_DAR\n");
return;
}
/* Load the Descriptor RAM with the descriptors */
for (i = 0; i < (DescSize); i++)
{MCF_USB_DDR = pDevDesc[i];}
/* Load the Descriptor RAM with the string descriptors */
/* Point the MCF_USB_DAR to 0x300 */
MCF_USB_DAR = STARTOFSTRD;
pStr0 = &String0Desc;
pStr1 = &String1Desc;
pStr2 = &String2Desc;
/* now load string 0 */
for (i = 0; i < (SD0LEN); i++)
{MCF_USB_DDR = pStr0[i];}
/* now load string 1 */
for (i = 0; i < (SD1LEN+2); i++)
{MCF_USB_DDR = pStr1[i];}
/* now load string 2 */
for (i = 0; i < (SD2LEN+2); i++)
{MCF_USB_DDR = pStr2[i];}
/* Initialize FIFOs */
usb_fifo_init();
/* Initialize the Interrupts */
usb_isr_init();
/* Enable USB device */
MCF_USB_CR |= MCF_USB_CR_USBENA;
printf("\nUSB enabled\n");
}
/********************************************************************/
void usb_isr_init(void)
{
/* set-up GPIO */
MCF_GPIO_PAR_USB = 0x01FF;
/* clear all ep interrupts */
MCF_USB_EP3ISR = 0xFFFFFFFF;
MCF_USB_EP2ISR = 0xFFFFFFFF;
//MCF_USB_EP1ISR = 0xFFFFFFFF;
MCF_USB_EP0ISR = 0xFFFFFFFF;
mcf5xxx_set_handler(107, (ADDRESS)usb_handler);
mcf5xxx_set_handler(108, (ADDRESS)usb_ep0_handler);
mcf5xxx_set_handler(109, (ADDRESS)usb_ep1_handler);
mcf5xxx_set_handler(110, (ADDRESS)usb_ep2_handler);
mcf5xxx_set_handler(111, (ADDRESS)usb_ep3_handler);
/* set up INCT0 interrupts for USB */
MCF_INTC0_ICR43 = (MCF_INTC0_ICRn_IP(5) | MCF_INTC0_ICRn_IL(3));
MCF_INTC0_ICR44 = (MCF_INTC0_ICRn_IP(4) | MCF_INTC0_ICRn_IL(3));
MCF_INTC0_ICR45 = (MCF_INTC0_ICRn_IP(4) | MCF_INTC0_ICRn_IL(3));
MCF_INTC0_ICR46 = (MCF_INTC0_ICRn_IP(4) | MCF_INTC0_ICRn_IL(3));
MCF_INTC0_ICR47 = (MCF_INTC0_ICRn_IP(4) | MCF_INTC0_ICRn_IL(3));
MCF_INTC0_IMRH &= ~(MCF_INTC0_IMRH_INT_MASK43 |
MCF_INTC0_IMRH_INT_MASK44 |
MCF_INTC0_IMRH_INT_MASK45 |
MCF_INTC0_IMRH_INT_MASK46 |
MCF_INTC0_IMRH_INT_MASK47 );
MCF_INTC0_IMRL &= ~(MCF_INTC0_IMRL_MASKALL);
/* Unmask all USB Module Interrupts except... */
MCF_USB_IMR = ( 0 | MCF_USB_ISR_FM |MCF_USB_IMR_SOF | MCF_USB_IMR_MSOF );
/* Setup USB module interrupts */
MCF_USB_EP0IMR &= ~( MCF_USB_EPnIMR_EOF |
MCF_USB_EPnIMR_DR |
MCF_USB_EPnIMR_EOT |
MCF_USB_EPnIMR_MDR |
MCF_USB_EPnIMR_FL |
MCF_USB_EPnIMR_FH |
MCF_USB_EPnIMR_FE
/*MCF_USB_EPnIMR_FM |*/
/*MCF_USB_EPnIMR_FF*/ );
MCF_USB_EP1IMR &= ~( MCF_USB_EPnIMR_EOF |
MCF_USB_EPnIMR_DR |
MCF_USB_EPnIMR_EOT |
MCF_USB_EPnIMR_MDR |
MCF_USB_EPnIMR_FL |
/* MCF_USB_EPnIMR_FH |*/
MCF_USB_EPnIMR_FE |
MCF_USB_EPnIMR_FM );
/* MCF_USB_EPnIMR_FF*/
MCF_USB_EP2IMR &= ~( MCF_USB_EPnIMR_EOF |
MCF_USB_EPnIMR_DR |
MCF_USB_EPnIMR_EOT |
MCF_USB_EPnIMR_MDR |
MCF_USB_EPnIMR_FL |
MCF_USB_EPnIMR_FH |
MCF_USB_EPnIMR_FE |
MCF_USB_EPnIMR_FM |
MCF_USB_EPnIMR_FF );
MCF_USB_EP3IMR &= ~( MCF_USB_EPnIMR_EOF |
MCF_USB_EPnIMR_DR |
MCF_USB_EPnIMR_EOT |
MCF_USB_EPnIMR_MDR |
MCF_USB_EPnIMR_FL |
MCF_USB_EPnIMR_FH |
MCF_USB_EPnIMR_FE |
MCF_USB_EPnIMR_FM |
MCF_USB_EPnIMR_FF );
}
/********************************************************************/
void usb_fifo_init(void)
{
//////////////////////////////////////////////////////////////////
//
// Setup USB FIFOs
//
//////////////////////////////////////////////////////////////////
/* Select the USB FIFO sizes */
MCF_USB_MCR = MCF_USB_MCR_MEMC(2);
MCF_USB_EP0FAR = 0x00;
MCF_USB_EP1FAR = 0x40;
/* Program endpoint type direction and maximum packet size in the USB EPnSR */
MCF_USB_EP0SR = (MCF_USB_EPnSR_TYP(0)| MCF_USB_EPnSR_MAX(0) );
MCF_USB_EP1SR = (MCF_USB_EPnSR_TYP(2)| MCF_USB_EPnSR_MAX(2) | MCF_USB_EPnSR_DIR );
MCF_USB_EP2SR = (MCF_USB_EPnSR_TYP(2)| MCF_USB_EPnSR_MAX(2) | MCF_USB_EPnSR_ZLPS);
MCF_USB_EP3SR = (MCF_USB_EPnSR_TYP(2)| MCF_USB_EPnSR_MAX(2) | MCF_USB_EPnSR_ZLPS);
/* Program the FIFO controller registers */
MCF_USB_EP0FCR = MCF_USB_EPnFCR_FRAME;
MCF_USB_EP1FCR = (MCF_USB_EPnFCR_FRAME | MCF_USB_EPnFCR_GR(4));
MCF_USB_EP2FCR = MCF_USB_EPnFCR_FRAME;
MCF_USB_EP3FCR = MCF_USB_EPnFCR_FRAME;
}
/********************************************************************/
uint8*
usb_get_desc(int8 config, int8 iface, int8 setting, int8 endpoint)
{
/* Note:
* ep is the offset and not the physical endpoint number
* In order to get the config desc pointer, specify -1 for
* all other inputs except config
* In order to get the interface/alternate setting desc pointer,
* specify -1 for epNum
*/
int i;
uint8 *pDescriptor = (uint8 *)&Descriptors;
if (config != -1)
{
if (config > ((USB_DEVICE_DESC *)pDescriptor)->bNumConfigurations)
return 0;
/* Allow for non-standard desc between device and config desc */
while (pDescriptor[1] != CONFIGURATION)
pDescriptor += pDescriptor[0];
/* pDescriptor now points to Config 1 descriptor */
for (i = 1; i < config;)
{
pDescriptor += pDescriptor[0];
if (pDescriptor[1] == CONFIGURATION)
i++;
}
/* pDescriptor now points to the correct Configuration descriptor */
if ((iface != -1) && (setting != -1))
{
if (iface >= ((USB_CONFIG_DESC *)pDescriptor)->bNumInterfaces)
return 0;
/* Allow for non-standard desc between config and iface desc */
while (pDescriptor[1] != INTERFACE)
pDescriptor += pDescriptor[0];
/* pDescriptor now points to first Interface descriptor */
for (i = 0; i < iface;)
{
pDescriptor += pDescriptor[0];
if (pDescriptor[1] == INTERFACE && pDescriptor[3] == 0)
i++;
}
/* pDescriptor now points to correct Interface descriptor */
for (i = 0; i < setting;)
{
pDescriptor += pDescriptor[0];
if (pDescriptor[1] == INTERFACE)
{
if (pDescriptor[2] != iface)
return 0;
else
i++;
}
}
/* pDescriptor now points to correct Alternate Setting descriptor */
if (endpoint != -1)
{
if (endpoint >= pDescriptor[4])
return 0;
/* Allow for non-standard desc between iface and endpoint desc */
while (pDescriptor[1] != ENDPOINT)
pDescriptor += pDescriptor[0];
/* pDescriptor now points to first Endpoint descriptor */
for (i = 0; i < endpoint;)
{
pDescriptor += pDescriptor[0];
if (pDescriptor[1] == ENDPOINT)
i++;
}
/* pDescriptor now points to the correct Endpoint descriptor */
}
}
}
return (pDescriptor);
}
/********************************************************************/
void usb_reset(void)
{
/* reset USB module */
}
/********************************************************************/
void
usb_handle_device_request(void)
{
uint32 tmp1;
uint32 tmp2;
uint32 bytes_left;
uint8 bmRequestType;
uint8 bRequest;
uint16 wValue;
uint16 wIndex;
uint16 wLength;
/* GET_DESCRIPTOR */
uint8 bDesType;
uint8 bDesIndex;
/* Read in Device Request from FIFO */
tmp1 = MCF_USB_EP0FDR;
tmp2 = MCF_USB_EP0FDR;
bmRequestType = (tmp1 & 0xFF000000) >>24;
bRequest = (tmp1 & 0x00FF0000) >>16;
wValue = swap16((tmp1 & 0x0000FFFF));
wIndex = swap16((tmp2 & 0xFFFF0000) >>16);
wLength = swap16((tmp2 & 0x0000FFFF));
switch(bRequest)
{
case GET_STATUS:
break;
case CLEAR_FEATURE:
break;
case SET_FEATURE:
break;
case SET_ADDRESS:
break;
case GET_DESCRIPTOR:
/* Clear EOF and DEVREQ interrupts */
MCF_USB_EP0ISR = MCF_USB_EPnISR_EOF | MCF_USB_EPnISR_DR;
/* Data Phase */
bDesType = (wValue & 0xFF00) >>8;
bDesIndex = wValue & 0x00FF;
if(bDesType == DEVICE)
{
ep[0].buffer.start = usb_get_desc(-1, -1, -1, -1);
ep[0].buffer.length = wLength;
}
else if(bDesType == CONFIGURATION)
{
ep[0].buffer.start = usb_get_desc(bDesIndex, -1, -1, -1);
cConfiguration = bDesIndex;
ep[0].buffer.length = wLength;
}
else if(bDesType == STRING)
{
if(bDesIndex == 0)
{
ep[0].buffer.start = &String0Desc;
if(wLength == 255)
ep[0].buffer.length = SD0LEN;
else
ep[0].buffer.length = wLength;
}
else if(bDesIndex == 1)
{
ep[0].buffer.start = &String1Desc;
if(wLength == 255)
ep[0].buffer.length = SD1LEN;
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -