mx27_habtools.c
来自「NorFlash bootloader(SPANSION_S71WS256ND0」· C语言 代码 · 共 844 行 · 第 1/2 页
C
844 行
qhead.TotalBytes = TotalBytes; qhead.ioc = IOC_SET; qhead.Status = NO_STATUS; qhead.BuffPtr0 = BUFPTR_P0_EP1OUT; qhead.CurrentOffset = (BUFPTR_P0_EP1OUT & 0xFFF); qhead.BuffPtr1 = 0; qhead.BuffPtr2 = 0; qhead.BuffPtr3 = 0; qhead.BuffPtr4 = 0; // EP1 OUT command = 16 bytes SetupQHead(&qhead); // Endpoint 1 : MPS = 64, OUT (Rx endpoint) *(P_U32)USB_OTG_ENDPTCTRL1 = 0x00080048; // Enable EP1 OUT *(P_U32)USB_OTG_ENDPTCTRL1 |= EP1OUT_ENABLE;}/*==================================================================================================FUNCTION: EP1OutCommandSetupDESCRIPTION: This function is used to prepare the Setup command from PC and prime the endpointARGUMENTS PASSED: None RETURN VALUE: None IMPORTANT NOTES: None==================================================================================================*/void EP1OutCommandSetup(void){ U32 TotalBytes = COMMAND; struct s_dTD td;// OUT // setup dTD // dTD for status of GET_DEVICE_DESCRIPTOR td.dTDBase = dTD0_EP1OUT; td.dTDNextLinkPtr = dTD1_EP1OUT; td.Terminate = TERMINATE; td.TotalBytes = TotalBytes; td.ioc = IOC_SET; td.Status = ACTIVE; td.BuffPtr0 = BUFPTR_P0_EP1OUT; td.CurrentOffset = (BUFPTR_P0_EP1OUT & 0xFFF); td.BuffPtr1 = 0; td.BuffPtr2 = 0; td.BuffPtr3 = 0; td.BuffPtr4 = 0; SetupTransferDescriptor(&td); // 1. write dQH next ptr and dQH terminate bit to 0 *(P_U32)(dQH2_EP1OUT+0x8)= (dTD0_EP1OUT); // 2. clear active & halt bit in dQH *(P_U32)(dQH2_EP1OUT+0xC) &= ~0xFF; // 3. prime endpoint by writing '1' in ENDPTPRIME *(P_U32)USB_OTG_ENDPTPRIME |= EP1OUT_PRIME; }/*==================================================================================================FUNCTION: EP1OutRxDataDESCRIPTION: This function is used to rx binary data for the downloadARGUMENTS PASSED: None RETURN VALUE: None IMPORTANT NOTES: None==================================================================================================*/void EP1OutRxData(U32 Address, U32 Offset, U32 ByteCount){ struct s_dTD td; // setting up the dTD buffer pointer depend on the ByteCounts // each page is 0x1000 and the max recommanded transfer is 0x4000 (16k bytes) U32 BufferPtrPage0 = Address; U32 BufferPtrPage1 = (Address + 0x1000); U32 BufferPtrPage2 = (Address + 0x2000); U32 BufferPtrPage3 = (Address + 0x3000); U32 BufferPtrPage4 = (Address + 0x4000); // Clear the EP1 OUT complete status if set if (*(P_U32)USB_OTG_ENDPTCOMPLETE & BIT1) *(P_U32)USB_OTG_ENDPTCOMPLETE = BIT1; // OUT // setup dTD // dTD for status of GET_DEVICE_DESCRIPTOR td.dTDBase = dTD0_EP1OUT; td.dTDNextLinkPtr = dTD1_EP1OUT; td.Terminate = TERMINATE; td.TotalBytes = ByteCount; td.ioc = IOC_SET; td.Status = ACTIVE; td.BuffPtr0 = BufferPtrPage0; td.CurrentOffset = Offset; td.BuffPtr1 = BufferPtrPage1; td.BuffPtr2 = BufferPtrPage2; td.BuffPtr3 = BufferPtrPage3; td.BuffPtr4 = BufferPtrPage4; SetupTransferDescriptor(&td); // 1. write dQH next ptr and dQH terminate bit to 0 *(P_U32)(dQH2_EP1OUT+0x8)= (dTD0_EP1OUT); // 2. clear active & halt bit in dQH *(P_U32)(dQH2_EP1OUT+0xC) &= ~0xFF; // 3. prime endpoint by writing '1' in ENDPTPRIME *(P_U32)USB_OTG_ENDPTPRIME |= EP1OUT_PRIME; // 4. Wait for the Complete Status while (!(*(VP_U32)USB_OTG_ENDPTCOMPLETE & BIT1)); //clear the complete status *(VP_U32)USB_OTG_ENDPTCOMPLETE = BIT1;}/*==================================================================================================FUNCTION: EnableEP2INDESCRIPTION: This function is used to enable the EP2 as INARGUMENTS PASSED: None RETURN VALUE: None IMPORTANT NOTES: None==================================================================================================*/void EnableEP2IN(void){ // EP2 IN response = 4 bytes U32 TotalBytes = 0x4; struct s_dQH qhead; qhead.dQHBase = dQH5_EP2IN; qhead.ZLT = ZLT_DISABLE; qhead.MPS = MPS_64; qhead.ios = IOS_SET; qhead.NextLinkPtr = dTD0_EP2IN; qhead.Terminate = TERMINATE; qhead.TotalBytes = TotalBytes; qhead.ioc = IOC_SET; qhead.Status = NO_STATUS; qhead.BuffPtr0 = BUFPTR_P0_EP2IN; qhead.CurrentOffset = (BUFPTR_P0_EP2IN & 0xFFF); qhead.BuffPtr1 = 0; qhead.BuffPtr2 = 0; qhead.BuffPtr3 = 0; qhead.BuffPtr4 = 0; // EP1 OUT command = 16 bytes SetupQHead(&qhead); // Endpoint 2: MPS = 64, IN (Tx endpoint) *(P_U32)USB_OTG_ENDPTCTRL2 = 0x00480008; // Enable EP2 IN *(P_U32)USB_OTG_ENDPTCTRL2 |= EP2IN_ENABLE; // 3. prime endpoint by writing '1' in ENDPTPRIME *(P_U32)USB_OTG_ENDPTPRIME |= EP2IN_PRIME; }/*==================================================================================================FUNCTION: CommandAckDESCRIPTION: This function is used to prepare the 4 bytes response to USB HostARGUMENTS PASSED: U32 ack: response RETURN VALUE: None IMPORTANT NOTES: None==================================================================================================*/void CommandAck(U32 ack, U8 channel){ struct s_dTD td; U32 TotalBytes = 0x4; if (channel) { *(P_U32)BUFPTR_P0_EP2IN = ack; td.dTDBase = dTD0_EP2IN; td.dTDNextLinkPtr = dTD1_EP2IN; td.Terminate = TERMINATE; td.TotalBytes = TotalBytes; td.ioc = IOC_SET; td.Status = ACTIVE; td.BuffPtr0 = BUFPTR_P0_EP2IN; td.CurrentOffset = (BUFPTR_P0_EP2IN & 0xFFF); td.BuffPtr1 = 0; td.BuffPtr2 = 0; td.BuffPtr3 = 0; td.BuffPtr4 = 0; SetupTransferDescriptor(&td); // 1. write dQH next ptr and dQH terminate bit to 0 *(P_U32)(dQH5_EP2IN+0x8)= (dTD0_EP2IN); // 2. clear active & halt bit in dQH *(P_U32)(dQH5_EP2IN+0xC) &= ~0xFF; // 3. prime endpoint by writing '1' in ENDPTPRIME *(P_U32)USB_OTG_ENDPTPRIME = EP2IN_PRIME; // wait for complete set and clear while (!(*(VP_U32)USB_OTG_ENDPTCOMPLETE & EP2IN_COMPLETE)); *(P_U32)USB_OTG_ENDPTCOMPLETE = EP2IN_COMPLETE; }//####### // UART//####### else { MX31_PutCharInFIFO((U8)ack & 0xFF); MX31_PutCharInFIFO((U8)((ack & 0xFF00)>>8)); MX31_PutCharInFIFO((U8)((ack & 0xFF0000)>>16)); MX31_PutCharInFIFO((U8)((ack & 0xFF000000)>>24)); //wait for TF empty while (!(*(VP_U32)UART1_USR2_1 & 0x4000)); } } /*==================================================================================================FUNCTION: EP2INTxDataDESCRIPTION: This function is used to transmit the data for READ commandARGUMENTS PASSED: U32 BufPtrAddress - Buffer pointer address U32 TotalBytes - TotalBytes to be read RETURN VALUE: None IMPORTANT NOTES: None==================================================================================================*/void EP2INTxData(U32 BufPtrAddress, U32 TotalBytes){ struct s_dTD td; td.dTDBase = dTD0_EP2IN; td.dTDNextLinkPtr = dTD1_EP2IN; td.Terminate = TERMINATE; td.TotalBytes = TotalBytes; td.ioc = IOC_SET; td.Status = ACTIVE; td.BuffPtr0 = BufPtrAddress; td.CurrentOffset = 0; td.BuffPtr1 = 0; td.BuffPtr2 = 0; td.BuffPtr3 = 0; td.BuffPtr4 = 0; SetupTransferDescriptor(&td); // 1. write dQH next ptr and dQH terminate bit to 0 *(P_U32)(dQH5_EP2IN+0x8)= (dTD0_EP2IN); // 2. clear active & halt bit in dQH *(P_U32)(dQH5_EP2IN+0xC) &= ~0xFF; // 3. prime endpoint by writing '1' in ENDPTPRIME *(P_U32)USB_OTG_ENDPTPRIME = EP2IN_PRIME; // wait for complete set and clear while (!(*(VP_U32)USB_OTG_ENDPTCOMPLETE & EP2IN_COMPLETE)); *(P_U32)USB_OTG_ENDPTCOMPLETE = EP2IN_COMPLETE;}/*==================================================================================================FUNCTION: HandleCommandDESCRIPTION: This function is used to handle the PC CommandARGUMENTS PASSED: U8 ErrorCode: Error Code passed from HAB RETURN VALUE: DONE (1) : when Execute = 0xAA, return to Bootstrap CONTINUE (0) : for others IMPORTANT NOTES: None ==================================================================================================*/int HandleCommand(int status, int count, U8 channel){ int i = 0; U16 Header = 0; U32 Response = 0; P_U32 BufPtr; // USB if (channel) { BufPtr = (P_U32)BUFPTR_P0_EP1OUT; for (i=0; i < 16; i += 4) { _gCommand[i] = 0x0; _gCommand[i] = (U8) (*BufPtr & 0xff); _gCommand[i + 1] = 0x0; _gCommand[i + 1] = (U8) ((*BufPtr >> 8) & 0xff); _gCommand[i + 2] = 0x0; _gCommand[i + 2] = (U8) ((*BufPtr >> 16) & 0xff); _gCommand[i + 3] = 0x0; _gCommand[i + 3] = (U8) ((*BufPtr >> 24) & 0xff); BufPtr++; } } // UART here else { for (i=0; i< 16; i++) { while (!(*(VP_U32)UART1_USR2_1 & 0x1)); _gCommand[i] = MX31_GetCharFromFIFO(); } } Header = ((_gCommand[0]<<8) | (_gCommand[1])); { Response =( (status << 16) | count) ; CommandAck(Response, channel); } return 1;}unsigned char MX31_GetCharFromFIFO (void){ return (*(VP_U32)UART1_URXD_1 & 0xFF);}// PutCharInFIFOvoid MX31_PutCharInFIFO (unsigned char c){ *(VP_U32)UART1_UTXD_1 = c;}void HAB_flash_status(int status, int count, U8 channel){ if (channel) { //if ((*(VP_U32)USB_OTG_ENDPTCOMPLETE) & BIT1) while(! ((*(VP_U32)USB_OTG_ENDPTCOMPLETE) & BIT1)); { *(P_U32)USB_OTG_ENDPTCOMPLETE = BIT1; HandleCommand(status, count, channel); EP1OutCommandSetup(); } } else { while (!(*(VP_U32)UART1_USR2_1 & 0x1)); // if (*(VP_U32)UART1_USR2_1 & 0x1) HandleCommand(status, count, channel); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?