//========================================================================= //函数名: hw_usb_endpoint_setup_handler //功 能: 当主机请求接口配置请求时,执行该函数 //参 数: 无 //返 回: 无 //========================================================================= void hw_usb_endpoint_setup_handler(void) { uint_16 u16Status; switch(Setup_Pkt->bRequest) { case GET_STATUS: if(FLAG_CHK(Setup_Pkt->wIndex_h,gu8HALT_EP)) u16Status=0x0100; else u16Status=0x0000; hw_usb_ep_in_transfer(EP0,(uint_8*)&u16Status,2); break; case CLEAR_FEATURE: FLAG_CLR(Setup_Pkt->wIndex_h,gu8HALT_EP); hw_usb_ep_in_transfer(EP0,0,0); break; case SET_FEATURE: FLAG_SET(Setup_Pkt->wIndex_h,gu8HALT_EP); hw_usb_ep_in_transfer(EP0,0,0); break; default: break; } }
void USB_Endpoint_Setup_Handler(void) { UINT16 u16Status; switch(Setup_Pkt->bRequest) { case GET_STATUS: if(FLAG_CHK(Setup_Pkt->wIndex_h,gu8HALT_EP)) u16Status=0x0100; else u16Status=0x0000; EP_IN_Transfer(EP0,(UINT8*)&u16Status,2); break; case CLEAR_FEATURE: FLAG_CLR(Setup_Pkt->wIndex_h,gu8HALT_EP); EP_IN_Transfer(EP0,0,0); break; case SET_FEATURE: FLAG_SET(Setup_Pkt->wIndex_h,gu8HALT_EP); EP_IN_Transfer(EP0,0,0); break; default: break; } }
void CDC_Engine(void) { //uint16 u8RecData; /* control Stage */ switch(u8CDCState) { case WAITING_FOR_ENUMERATION: /* 等待 USB 枚举 */ while(gu8USB_State != uENUMERATED) { (void)u8CDCState; }; u8CDCState = 0; break; case SET_LINE_CODING: if(FLAG_CHK(EP0, gu8USB_Flags)) { FLAG_CLR(EP0, gu8USB_Flags); (void)EP_OUT_Transfer(EP0, (uint8 *)&com_cfg); EP_IN_Transfer(EP0, 0, 0); } break; case SET_CONTROL_LINE_STATE: EP_IN_Transfer(EP0, 0, 0); break; } }
void main (void) { Display_Intro(); init_I2C(); port_config(); DISABLE_USB_5V; // Disable USB 5v (for Host support) MAX3353_ISR(); if(MAX3353_Init()) printf("\nMAX3353 not Present\n"); else printf("\nMAX3353 Present\n"); while(1) { /*** Check for changes ****/ if(FLAG_CHK(_MAX3353,gu8ISR_Flags)) { FLAG_CLR(_MAX3353,gu8ISR_Flags); if(gu8MAX3353StatusRegister & ID_GND_EVENT) { printf("\nID-GND --> Changing to HOST mode (Enabling 5V)"); gu8USB_Mode=USB_HOST_MODE_INIT; } if(gu8MAX3353StatusRegister & ID_FLOAT_EVENT) { printf("\nID-FLOAT --> Changing to DEVICE mode (Disabling 5V)"); gu8USB_Mode=USB_DEVICE_MODE_INIT; } if(gu8MAX3353StatusRegister & VBUS_HIGH_EVENT) { printf("\nVBUS is Up"); } if(gu8MAX3353StatusRegister & VBUS_LOW_EVENT) { printf("\nVBUS is Down"); if(gu8USB_Mode==USB_DEVICE_MODE) gu8USB_Mode=USB_DEVICE_MODE_INIT; //enter_vlps(); // Enter VLPS //mcg_pbe_2_pee(); // Exit VLPS // Low power } } /* USB Switch stacks */ USB_State_Machine(); } }
void USB_Init(void) { extern uint32 __VECTOR_RAM[]; /* Software Configuration */ Setup_Pkt=(tUSB_Setup*)BufferPointer[bEP0OUT_ODD]; gu8USB_State=uPOWER; /* MPU Configuration */ MPU_CESR=0; // MPU is disable. All accesses from all bus masters are allowed /* SIM Configuration */ #ifdef USB_CLOCK_CLKIN FLAG_SET(SIM_SCGC5_PORTE_SHIFT,SIM_SCGC5); PORTE_PCR26=(0|PORT_PCR_MUX(7)); // Enabling PTE26 as CLK input #endif #ifdef USB_CLOCK_PLL FLAG_SET(SIM_SOPT2_PLLFLLSEL_SHIFT,SIM_SOPT2); // Select PLL output #endif #ifndef USB_CLOCK_CLKIN FLAG_SET(SIM_SOPT2_USBSRC_SHIFT,SIM_SOPT2); // PLL/FLL selected as CLK source #endif SIM_CLKDIV2|=USB_FARCTIONAL_VALUE; // USB Freq Divider SIM_SCGC4|=(SIM_SCGC4_USBOTG_MASK); // USB Clock Gating /* NVIC Configuration */ __VECTOR_RAM[89]=(UINT32)USB_ISR; //replace ISR //NVICICER2|=(1<<9); //Clear any pending interrupts on USB NVICISER2|=(1<<9); //Enable interrupts from USB module /* USB Module Configuration */ // Reset USB Module USB0_USBTRC0|=USB_USBTRC0_USBRESET_MASK; while(FLAG_CHK(USB_USBTRC0_USBRESET_SHIFT,USB0_USBTRC0)){}; // Set BDT Base Register USB0_BDTPAGE1=(UINT8)((UINT32)tBDTtable>>8); USB0_BDTPAGE2=(UINT8)((UINT32)tBDTtable>>16); USB0_BDTPAGE3=(UINT8)((UINT32)tBDTtable>>24); // Clear USB Reset flag FLAG_SET(USB_ISTAT_USBRST_MASK,USB0_ISTAT); // Enable USB Reset Interrupt FLAG_SET(USB_INTEN_USBRSTEN_SHIFT,USB0_INTEN); // Enable weak pull downs USB0_USBCTRL=0x40; USB0_USBTRC0|=0x40; USB0_CTL|=0x01; }
void CDC_Engine(void) { //UINT16 u8RecData; /* control Stage */ switch(u8CDCState) { case WAITING_FOR_ENUMERATION: /* Wait for USB Enumeration */ //while(gu8USB_State!=uENUMERATED) { (void)u8CDCState; //__RESET_WATCHDOG(); //USB_FLAGS=USB_ISTAT; //USB_ERROR_FLAGS=USB_ERRSTAT; }; //u8CDCState=0; break; case SET_LINE_CODING: if(FLAG_CHK(EP0,gu8USB_Flags)) { FLAG_CLR(EP0,gu8USB_Flags); (void)EP_OUT_Transfer(EP0,(UINT8*)&LineCoding); EP_IN_Transfer(EP0,0,0); //vfnSCI1Init(); } break; case SET_CONTROL_LINE_STATE: EP_IN_Transfer(EP0,0,0); break; } /* Data stage */ /* if(FLAG_CHK(EP_OUT,gu8USB_Flags)) { u8RecData=USB_EP_OUT_SizeCheck(EP_OUT); // Check how many bytes from the PC usbEP_Reset(EP_OUT); usbSIE_CONTROL(EP_OUT); FLAG_CLR(EP_OUT,gu8USB_Flags); EP_IN_Transfer(EP2,CDC_OUTPointer,2); u8RecData=0; } */ }
//========================================================================= //函数名: hw_usb_init //功 能: USB模块初始 //参 数: 无 //返 回: 无 //========================================================================= void hw_usb_init(void) { tBDTtable = (tBDT *)((( uint_32 ) tBDT_unaligned & 0xFFFFFE00UL)+ 0x200UL); Setup_Pkt=(tUSB_Setup*)BufferPointer[bEP0OUT_ODD]; gu8USB_State=uPOWER; //USB_FMC_ACC_ENABLE; USB_REG_SET_ENABLE; USB_REG_CLEAR_STDBY; //MPU_CESR=0;//禁止MPU FLAG_SET(SIM_SOPT2_PLLFLLSEL_SHIFT,SIM_SOPT2); // 使能PLL输出 FLAG_SET(SIM_SOPT2_USBSRC_SHIFT,SIM_SOPT2); // 使能PLL/FLL为时钟源 //SIM_CLKDIV2|=USB_FARCTIONAL_VALUE; //USB分频因子设置 SIM_SCGC4|=(SIM_SCGC4_USBOTG_MASK); //USB模块时钟门使能 enable_irq(USB_INTERRUPT_IRQ); //使能USB模块IRQ中断 //USB模块寄存器配置 USB0_USBTRC0|=USB_USBTRC0_USBRESET_MASK; //复位USB模块 while(FLAG_CHK(USB_USBTRC0_USBRESET_SHIFT,USB0_USBTRC0)){}; //设置BDT基址寄存器 //( 低9 位是默认512 字节的偏移) 512 = 16 * 4 * 8 。 //8 位表示: 4 个字节的控制状态,4 个字节的缓冲区地址 。 USB0_BDTPAGE1=(uint_8)((uint_32)tBDTtable>>8); USB0_BDTPAGE2=(uint_8)((uint_32)tBDTtable>>16); USB0_BDTPAGE3=(uint_8)((uint_32)tBDTtable>>24); //清除USB模块复位标志 FLAG_SET(USB_ISTAT_USBRST_MASK,USB0_ISTAT); //使能USB模块复位中断 FLAG_SET(USB_INTEN_USBRSTEN_SHIFT,USB0_INTEN); USB0_USBCTRL=0x40; USB0_USBTRC0|=0x40; //强制设置第6位为1 USB0_CTL|=0x01; //USB模块使能 //上拉使能 FLAG_SET(USB_CONTROL_DPPULLUPNONOTG_SHIFT,USB0_CONTROL); }
void USB_Init(void) { /* Software Configuration */ Setup_Pkt=(tUSB_Setup*)BufferPointer[bEP0OUT_ODD]; gu8USB_State=uPOWER; /* MPU Configuration */ // MPU_CESR=0; MPU is disable. All accesses from all bus masters are allowed /** Feed 48MHz to the USB FS clock */ vfnInitUSBClock(USB_CLOCK); /* NVIC Configuration */ extern uint32 __VECTOR_RAM[]; //Get vector table that was copied to RAM __VECTOR_RAM[40]=(uint32)USB_ISR; //replace ISR enable_irq(24); //IRQ 24 for USBOTG and USBCDC on L2K /* USB Module Configuration */ // Reset USB Module USB0_USBTRC0 |= USB_USBTRC0_USBRESET_MASK; while(FLAG_CHK(USB_USBTRC0_USBRESET_SHIFT,USB0_USBTRC0)) {}; // Set BDT Base Register USB0_BDTPAGE1=(uint8)((uint32)tBDTtable>>8); USB0_BDTPAGE2=(uint8)((uint32)tBDTtable>>16); USB0_BDTPAGE3=(uint8)((uint32)tBDTtable>>24); // Clear USB Reset flag FLAG_SET(USB_ISTAT_USBRST_MASK,USB0_ISTAT); // Enable USB Reset Interrupt FLAG_SET(USB_INTEN_USBRSTEN_SHIFT,USB0_INTEN); // Enable weak pull downs //USB0_USBCTRL = USB_USBCTRL_PDE_MASK; // Disable weak pull downs USB0_USBCTRL &= ~(uint8)(USB_USBCTRL_PDE_MASK | USB_USBCTRL_SUSP_MASK); USB0_USBTRC0|=0x40; USB0_CTL|=0x01; // Pull up enable FLAG_SET(USB_CONTROL_DPPULLUPNONOTG_SHIFT,USB0_CONTROL); }
void main (void) { Display_Intro(); init_I2C(); port_config(); DISABLE_USB_5V; // Disable USB 5v (for Host support) if(MAX3353_Init()) printf("\nMAX3353 not Present\n"); else printf("\nMAX3353 Present\n"); MAX3353_ISR(); while(1) { in_char(); #if 0 //CW enter_vlps(); #endif //kevin //enter_stop(); mcg_pbe_2_pee(); if(FLAG_CHK(_MAX3353,gu8ISR_Flags)) { if(gu8MAX3353StatusRegister & ID_GND_EVENT) { ENABLE_USB_5V; printf("\nID-GND --> Changing to HOST mode (Enabling 5V)"); } if(gu8MAX3353StatusRegister & ID_FLOAT_EVENT) { DISABLE_USB_5V; printf("\nID-FLOAT --> Changing to DEVICE mode (Disabling 5V)"); } if(gu8MAX3353StatusRegister & VBUS_HIGH_EVENT) printf("\nVBUS is Up"); if(gu8MAX3353StatusRegister & VBUS_LOW_EVENT) printf("\nVBUS is Down"); FLAG_CLR(_MAX3353,gu8ISR_Flags); } } }
void usb_service(void) { // If data transfer arrives if(FLAG_CHK(EP_OUT,gu8USB_Flags)) { (void)USB_EP_OUT_SizeCheck(EP_OUT); usbEP_Reset(EP_OUT); usbSIE_CONTROL(EP_OUT); FLAG_CLR(EP_OUT,gu8USB_Flags); // Send it back to the PC EP_IN_Transfer(EP2,CDC_OUTPointer,1); } if (!ti_print) { ti_print = 300; sprintf((char *)gu8USB_Buffer,"\rtsi %%= %03i ", AbsolutePercentegePosition); EP_IN_Transfer(EP2,gu8USB_Buffer,15); } }
//========================================================================= //函数名: hw_usb_isr //功 能: 处理复位中断 //参 数: 无 //返 回: 无 //========================================================================= void hw_usb_isr(void) { // 检测USB 模块是否解析到有效的复位。 if(FLAG_CHK(USB_ISTAT_USBRST_SHIFT,USB0_ISTAT)) { hw_usb_reset_handler(); return; } if(FLAG_CHK(USB_ISTAT_SOFTOK_SHIFT,USB0_ISTAT)) { USB0_ISTAT = USB_ISTAT_SOFTOK_MASK; } // 检测STALL if(FLAG_CHK(USB_ISTAT_STALL_SHIFT,USB0_ISTAT)) { hw_usb_stall_handler(); } // 令牌完成中断 if(FLAG_CHK(USB_ISTAT_TOKDNE_SHIFT,USB0_ISTAT)) { FLAG_SET(USB_CTL_ODDRST_SHIFT,USB0_CTL); // USB 处理函数 hw_usb_handler(); // 清除令牌完成中断 FLAG_SET(USB_ISTAT_TOKDNE_SHIFT,USB0_ISTAT); } // SLEEP if(FLAG_CHK(USB_ISTAT_SLEEP_SHIFT,USB0_ISTAT)) { // 清除SLEEP中断 FLAG_SET(USB_ISTAT_SLEEP_SHIFT,USB0_ISTAT); } // 错误 if(FLAG_CHK(USB_ISTAT_ERROR_SHIFT,USB0_ISTAT)) { FLAG_SET(USB_ISTAT_ERROR_SHIFT,USB0_ISTAT); } }
//========================================================================= //函数名: hw_usb_ep_in_transfer //功 能: USB发送IN包 //参 数: u8EP:端点 // pu8DataPointer:待发数据所在缓冲区首地址 // u8DataSize:待发数据长度 //返 回: 无 //========================================================================= void hw_usb_ep_in_transfer(uint_8 u8EP,uint_8 *pu8DataPointer,uint_8 u8DataSize) { uint_8 *pu8EPBuffer; uint_8 u8EPSize; uint_16 u16Lenght=0; uint_8 u8EndPointFlag; //设置端点所对应的端点描述符 u8EndPointFlag=u8EP; if(u8EP) u8EP=(uint_8)(u8EP<<2); u8EP+=2; // 指向端点的缓冲区 pu8EPBuffer=BufferPointer[u8EP]; //检查是否可以发送数据 if(FLAG_CHK(fIN,gu8USBClearFlags)) { // 待传输的数据 pu8IN_DataPointer=pu8DataPointer; gu8IN_Counter=u8DataSize; u16Lenght=(Setup_Pkt->wLength_h<<8)+Setup_Pkt->wLength_l ; if((u16Lenght < u8DataSize) && (u8EP==2)) { gu8IN_Counter=Setup_Pkt->wLength_l; } } // 看看待发送的数据是否大于端点所能发送数据的长度。 if(gu8IN_Counter > cEP_Size[u8EP]) { u8EPSize = cEP_Size[u8EP]; gu8IN_Counter-=cEP_Size[u8EP]; FLAG_CLR(fIN,gu8USBClearFlags); } else { u8EPSize = gu8IN_Counter; gu8IN_Counter=0; FLAG_SET(fIN,gu8USBClearFlags); } // 把待发数据长度写入BDT tBDTtable[u8EP].Cnt=(u8EPSize); // 把数据拷贝到BDT 缓冲区 while(u8EPSize--) *pu8EPBuffer++=*pu8IN_DataPointer++; // gu8USB_Toogle_flags : 用Data0 和Data1 来跟USB 设备进行同步用的。 // DATA0/DATA1 交替 if(FLAG_CHK(u8EndPointFlag,gu8USB_Toogle_flags)) { // gu8USB_Toogle_flags : 表示是DATA0 还是DATA1 。1: 表示发送DATA0, 0: 表示发送DATA1. tBDTtable[u8EP].Stat._byte= kUDATA0; FLAG_CLR(u8EndPointFlag,gu8USB_Toogle_flags); } else { tBDTtable[u8EP].Stat._byte= kUDATA1; FLAG_SET(u8EndPointFlag,gu8USB_Toogle_flags); } }
void USB_ISR(void) { *pu8trace++=0xCC; //PMC_VLPR_Exit(); FLAG_SET(1,GPIOC_PDOR); if(FLAG_CHK(USB_ISTAT_USBRST_SHIFT,USB0_ISTAT)) { // Clear Reset Flag //USB_ISTAT = USB_ISTAT_USBRST_MASK; // Handle RESET Interrupt USB_Reset_Handler(); // Clearing this bit allows the SIE to continue token processing // and clear suspend condition //CTL_TXSUSPEND_TOKENBUSY = 0; //FLAG_CLR(USB_CTL_TXSUSPENDTOKENBUSY_SHIFT,USB_CTL); // No need to process other interrupts //return; } if(FLAG_CHK(USB_ISTAT_SOFTOK_SHIFT,USB0_ISTAT)) { USB0_ISTAT = USB_ISTAT_SOFTOK_MASK; } if(FLAG_CHK(USB_ISTAT_STALL_SHIFT,USB0_ISTAT)) //if(INT_STAT_STALL && INT_ENB_STALL_EN ) { USB_Stall_Handler(); } if(FLAG_CHK(USB_ISTAT_TOKDNE_SHIFT,USB0_ISTAT)) { FLAG_SET(USB_CTL_ODDRST_SHIFT,USB0_CTL); USB_Handler(); FLAG_SET(USB_ISTAT_TOKDNE_SHIFT,USB0_ISTAT); } if(FLAG_CHK(USB_ISTAT_SLEEP_SHIFT,USB0_ISTAT)) //if(INT_STAT_SLEEP && INT_ENB_SLEEP_EN_MASK) { // Clear RESUME Interrupt if Pending //INT_STAT = INT_STAT_RESUME_MASK; //u8ISRCounter++; //FLAG_SET(USB_ISTAT_RESUME_SHIFT,USB_ISTAT); // Clear SLEEP Interrupt FLAG_SET(USB_ISTAT_SLEEP_SHIFT,USB0_ISTAT); //INT_STAT = INT_STAT_SLEEP_MASK; //FLAG_SET(USB_INTEN_RESUME_SHIFT,USB_ISTAT); //INT_ENB_RESUME_EN = 1; } if(FLAG_CHK(USB_ISTAT_ERROR_SHIFT,USB0_ISTAT)) //if(INT_STAT_ERROR && INT_ENB_ERROR_EN ) { FLAG_CHK(USB_ISTAT_ERROR_SHIFT,USB0_ISTAT); //printf("\nUSB Error\n"); //INT_STAT_ERROR=1; } }
void USB_Stall_Handler(void) { if(FLAG_CHK(USB_ENDPT_EPSTALL_SHIFT,USB0_ENDPT0)) FLAG_CLR(USB_ENDPT_EPSTALL_SHIFT,USB0_ENDPT0); FLAG_SET(USB_ISTAT_STALL_SHIFT,USB0_ISTAT); }
//========================================================================= //函数名: hw_usb_stall_handler //功 能: 处理stall中断 //参 数: 无 //返 回: 无 //========================================================================= void hw_usb_stall_handler(void) { if(FLAG_CHK(USB_ENDPT_EPSTALL_SHIFT,USB0_ENDPT0)) FLAG_CLR(USB_ENDPT_EPSTALL_SHIFT,USB0_ENDPT0); FLAG_SET(USB_ISTAT_STALL_SHIFT,USB0_ISTAT); }
void EP_IN_Transfer(UINT8 u8EP,UINT8 *pu8DataPointer,UINT8 u8DataSize) { UINT8 *pu8EPBuffer; UINT8 u8EPSize; UINT16 u16Lenght=0; UINT8 u8EndPointFlag; /* Adjust the buffer location */ u8EndPointFlag=u8EP; if(u8EP) u8EP=(UINT8)(u8EP<<2); u8EP+=2; /* Assign the proper EP buffer */ pu8EPBuffer=BufferPointer[u8EP]; /* Check if is a pending transfer */ if(FLAG_CHK(fIN,gu8USBClearFlags)) { pu8IN_DataPointer=pu8DataPointer; gu8IN_Counter=u8DataSize; u16Lenght=(Setup_Pkt->wLength_h<<8)+Setup_Pkt->wLength_l ; if((u16Lenght < u8DataSize) && (u8EP==2)) { gu8IN_Counter=Setup_Pkt->wLength_l; } } /* Check transfer Size */ if(gu8IN_Counter > cEP_Size[u8EP]) { u8EPSize = cEP_Size[u8EP]; gu8IN_Counter-=cEP_Size[u8EP]; FLAG_CLR(fIN,gu8USBClearFlags); } else { u8EPSize = gu8IN_Counter; gu8IN_Counter=0; FLAG_SET(fIN,gu8USBClearFlags); } /* Copy User buffer to EP buffer */ tBDTtable[u8EP].Cnt=(u8EPSize); while(u8EPSize--) *pu8EPBuffer++=*pu8IN_DataPointer++; /* USB Flags Handling */ if(FLAG_CHK(u8EndPointFlag,gu8USB_Toogle_flags)) { tBDTtable[u8EP].Stat._byte= kUDATA0; FLAG_CLR(u8EndPointFlag,gu8USB_Toogle_flags); } else { tBDTtable[u8EP].Stat._byte= kUDATA1; FLAG_SET(u8EndPointFlag,gu8USB_Toogle_flags); } }
void CDC_Engine(void) { //uint16 u8RecData; /** re-init CDC class if a VBUS HIGH event was detected */ if (FLAG_CHK(VBUS_HIGH_EVENT,gu8ISR_Flags)) { FLAG_SET(USB_CTL_USBENSOFEN_MASK,USB0_CTL); u8CDCState = WAITING_FOR_ENUMERATION; enum_msg = TRUE; CDC_Init(); FLAG_CLR(VBUS_HIGH_EVENT,gu8ISR_Flags); } /* control Stage */ switch(u8CDCState) { case WAITING_FOR_ENUMERATION: /* Wait for USB Enumeration */ while(gu8USB_State!=uENUMERATED) { (void)u8CDCState; }; if (enum_msg) { printf ("\nUSB Enumerated, check your COM ports "); enum_msg = FALSE; } u8CDCState=0; break; case SET_LINE_CODING: if(FLAG_CHK(EP0,gu8USB_Flags)) { FLAG_CLR(EP0,gu8USB_Flags); (void)EP_OUT_Transfer(EP0,(uint8*)&LineCoding); EP_IN_Transfer(EP0,0,0); //vfnSCI1Init(); } break; case SET_CONTROL_LINE_STATE: EP_IN_Transfer(EP0,0,0); break; } /* Data stage */ /* if(FLAG_CHK(EP_OUT,gu8USB_Flags)) { u8RecData=USB_EP_OUT_SizeCheck(EP_OUT); // Check how many bytes from the PC usbEP_Reset(EP_OUT); usbSIE_CONTROL(EP_OUT); FLAG_CLR(EP_OUT,gu8USB_Flags); EP_IN_Transfer(EP2,CDC_OUTPointer,2); u8RecData=0; } */ }