/**************************************************************************//** * @file main.c * @brief USB Host integration test program source file * * SPDX-License-Identifier: Apache-2.0 * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved. *****************************************************************************/ #ifdef ECOS #include "stdio.h" #include "stdlib.h" #include "string.h" #include "drv_api.h" #include "diag.h" #include "wbtypes.h" #include "wbio.h" #else #include <stdio.h> #include <stdlib.h> #include <string.h> #include "wbtypes.h" #include "wblib.h" #endif #include "N9H20.h" /* USB */ #include "usbvideo.h" #include "usbkbd.h" #define SYSTEM_CLOCK 12000000 #define UART_BAUD_RATE 115200 #define DUMMY_BUFFER_SIZE (64 * 1024) #ifdef ECOS #define sysGetTicks(TIMER0) cyg_current_time() #endif UINT8 _JpegImage[256 * 1024] __attribute__((aligned(32))); UINT8 _JpegImageR[256 * 1024] __attribute__((aligned(32))); extern UINT32 _QueuedSize; extern INT W99683_HasImageQueued(VOID); void GetJpegImage(UINT8 *image, UINT32 *len, INT interval) { UINT8 *bufPTR; INT bufLEN; UINT32 idx = 0; *len = 0; /* Skip frames */ while (1) { if (W99683_GetFramePiece(&bufPTR, &bufLEN) < 0) ; /* W99683 is not enabled, we wait */ if ((bufPTR[0] == 0xFF) && (bufPTR[1] == 0xD8)) { if (interval == 0) break; interval--; } } while (1) { memcpy(&image[idx], bufPTR, bufLEN); idx += bufLEN; *len += bufLEN; if (W99683_GetFramePiece(&bufPTR, &bufLEN) < 0) continue; /* W99683 is not enabled, we wait */ if ((bufPTR[0] == 0xFF) && (bufPTR[1] == 0xD8)) return; } } static INT Action_Compare(CHAR *suFileName1, CHAR *szAsciiName1, CHAR *suFileName2, CHAR *szAsciiName2) { INT hFile1, hFile2; INT nLen1, nLen2, nCount, nStatus1, nStatus2; UINT8 buffer1[8192], buffer2[8192]; UINT32 nJpegLen; hFile1 = fsOpenFile(suFileName1, szAsciiName1, O_RDONLY); if (hFile1 < 0) return hFile1; hFile2 = fsOpenFile(suFileName2, szAsciiName2, O_RDONLY); if (hFile2 < 0) return hFile2; sysprintf("\nComparing file ...\n"); nCount = 0; while (1) { nStatus1 = fsReadFile(hFile1, buffer1, 1024, &nLen1); nStatus2 = fsReadFile(hFile2, buffer2, 1024, &nLen2); GetJpegImage(_JpegImage, &nJpegLen, 0); if ((nStatus1 == ERR_FILE_EOF) && (nStatus2 == ERR_FILE_EOF)) { sysprintf("\ncompare ok!\n"); fsCloseFile(hFile1); fsCloseFile(hFile2); return 0; } if (nLen1 != nLen2) break; if (memcmp(buffer1, buffer2, 1024)) break; nCount++; // if ((nCount % 1024) == 0) // sysprintf("%d KB \r", nCount); } sysprintf("\nFile Compare failed at offset %x\n", nCount * 1024); fsCloseFile(hFile1); fsCloseFile(hFile2); return -1; } INT copy_file(CHAR *suSrcName, CHAR *szSrcAsciiName, CHAR *suDstName, CHAR *szDstAsciiName) { INT hFileSrc, hFileDst, nByteCnt, nStatus; UINT8 *pucBuff; UINT32 nJpegLen; pucBuff = (UINT8 *)malloc(4096 + MAX_FILE_NAME_LEN + 512); if (pucBuff == NULL) return ERR_NO_FREE_MEMORY; hFileSrc = fsOpenFile(suSrcName, szSrcAsciiName, O_RDONLY); if (hFileSrc < 0) { free(pucBuff); return hFileSrc; } hFileDst = fsOpenFile(suDstName, szDstAsciiName, O_RDONLY); if (hFileDst > 0) { fsCloseFile(hFileSrc); fsCloseFile(hFileDst); free(pucBuff); return ERR_FILE_EXIST; } hFileDst = fsOpenFile(suDstName, szDstAsciiName, O_CREATE); if (hFileDst < 0) { fsCloseFile(hFileSrc); free(pucBuff); return hFileDst; } while (1) { nStatus = fsReadFile(hFileSrc, pucBuff, 4096, &nByteCnt); if (nStatus < 0) break; nStatus = fsWriteFile(hFileDst, pucBuff, nByteCnt, &nByteCnt); if (nStatus < 0) break; GetJpegImage(_JpegImage, &nJpegLen, 0); } fsCloseFile(hFileSrc); fsCloseFile(hFileDst); free(pucBuff); if (nStatus == ERR_FILE_EOF) nStatus = 0; return nStatus; } INT Test() { INT nStatus; CHAR szSrcA[24] = "C:\\1.mp4"; CHAR szDstA[24] = "C:\\copya"; CHAR suFileName1[64], suFileName2[64]; UINT32 nJpegLen; while (1) { sysprintf("Delete file: %s\n", szDstA); fsAsciiToUnicode(szDstA, suFileName1, TRUE); nStatus = fsDeleteFile(suFileName1, NULL); if (nStatus < 0) sysprintf("Failed, status = %x\n", nStatus); while (_QueuedSize > 16*1024) { GetJpegImage(_JpegImage, &nJpegLen, 0); sysprintf("."); } sysprintf("Copy file: %s\n", szSrcA); fsAsciiToUnicode(szSrcA, suFileName1, TRUE); fsAsciiToUnicode(szDstA, suFileName2, TRUE); nStatus = copy_file(suFileName1, NULL, suFileName2, NULL); if (nStatus < 0) { sysprintf("Failed, status = %x\n", nStatus); exit(0); } sysprintf("Compare file: %s and %s\n", szSrcA, szDstA); fsAsciiToUnicode(szSrcA, suFileName1, TRUE); fsAsciiToUnicode(szDstA, suFileName2, TRUE); if (Action_Compare(suFileName1, NULL, suFileName2, NULL) < 0) break; } return 0; } void Isochronous_Test() { CHAR szFileName[32] = {'C',0,':',0,'\\',0,'1',0,0,0 }; CHAR suFileName[128]; INT nIdx = 0; UINT32 nJpegLen; INT hFile; INT nWriteBytes; W99683Cam_Init(); while (!W99683Cam_IsConnected()) #ifdef ECOS Hub_CheckIrqEvent(0); #else Hub_CheckIrqEvent(); #endif if (W99683Cam_Open() < 0) { sysprintf("Failed to open W99683 device!\n"); return; /* _W99683_Camera is freed also */ } while (!W99683Cam_IsStreaming()) ; /* Drop 5 pictures */ for (nIdx = 0; nIdx < 10; nIdx++) { sysprintf("%d GetJpegImage...\n", nIdx); GetJpegImage(_JpegImage, &nJpegLen, 0); sysprintf("ImageSize: %d, _QueuedSize: %d\n", nJpegLen, _QueuedSize); } for (nIdx = 0; nIdx < 30; nIdx++) { reget: GetJpegImage(_JpegImage, &nJpegLen, 0); if (_QueuedSize > 200000) { goto reget; } sysprintf("ImageSize: %d, _QueuedSize: %d\n", nJpegLen, _QueuedSize); /* Open a new file for writing */ sprintf(szFileName, "C:\\%04d.jpg", nIdx); fsAsciiToUnicode(szFileName, suFileName, 1); hFile = fsOpenFile(suFileName, NULL, O_CREATE); if (hFile > 0) sysprintf("Opene file:[%s], file handle:%d\n", szFileName, hFile); else { sysprintf("Failed to open file: %s (%x)\n", szFileName, hFile); continue; } if ((fsWriteFile(hFile, _JpegImage, nJpegLen, &nWriteBytes) < 0) || (nWriteBytes != nJpegLen)) sysprintf("File write error! %d %d\n", nWriteBytes); else sysprintf("%d bytes\n", nWriteBytes); fsCloseFile(hFile); } while (1) GetJpegImage(_JpegImage, &nJpegLen, 0); } void IntegrationTest(void) { INT t0; UINT32 uBlockSize, uFreeSize, uDiskSize; sysprintf("Please plug in pen driver, key board and W99683 camera in advance\n"); InitUsbSystem(); UMAS_InitUmasDriver(); USBKeyboardInit(); /* wait hard disk ready */ t0 = sysGetTicks(TIMER0); while (sysGetTicks(TIMER0) - t0 < 300) ; if (fsDiskFreeSpace('C', &uBlockSize, &uFreeSize, &uDiskSize) == 0) sysprintf("Disk size = %d KB, Free speace = %d KB\n", uDiskSize, uFreeSize); else sysprintf("fsDiskFreeSpace failed!!\n"); Isochronous_Test(); } /* Pen driver Connect/disconnect Test */ volatile UINT32 i32MsConnect = 0; volatile UINT32 i32MsDisConnect = 1; volatile UINT32 i32AccessDone = 0; VOID MassStotrageConnection(void* umas) { volatile int i=0x20000; sysprintf("Umas driver connect 0x%x\n", (UINT32)umas); i32MsConnect = 1; i32MsDisConnect =0; while(i--); } VOID MassStotrageDisconnection(void* umas) { sysprintf("Umas driver disconnect 0x%x\n", (UINT32)umas); i32MsConnect = 0; i32MsDisConnect = 1; i32AccessDone = 0; } /************************************************************************************* * Test Condition: * Plug in a pen driver to USBH port 1 or port 0. * *************************************************************************************/ void PenDriverAccess(UINT32 u32Count) { CHAR szFileName[32] = {'C',0,':',0,'\\',0,'1',0,0,0 }; CHAR szAsciiStr[32]={0}; CHAR suFileName[128]; INT nIdx = 0, nIdy=0; UINT32 nJpegLen= 256*1024; INT hFile; INT nWriteBytes; sprintf(szAsciiStr, "C:\\Test"); fsAsciiToUnicode(szAsciiStr, suFileName, TRUE); fsMakeDirectory(suFileName, NULL); for (nIdx = 0; nIdx < u32Count; nIdx++) { for (nIdy = 0; nIdy < (nJpegLen); nIdy=nIdy+1) _JpegImage[nIdy] = (nIdy+(nIdy>>8)+(nIdy>>16))+nIdx; sysprintf("ImageSize: %d\n", nJpegLen); /* Open a new file for writing */ sprintf(szFileName, "C:\\Test\\%07d.jpg", nIdx); fsAsciiToUnicode(szFileName, suFileName, 1); hFile = fsOpenFile(suFileName, NULL, O_CREATE); if (hFile > 0) sysprintf("Opene file:[%s], file handle:%d\n", szFileName, hFile); else { sysprintf("Failed to open file: %s (%x)\n", szFileName, hFile); continue; } if ((fsWriteFile(hFile, _JpegImage, nJpegLen, &nWriteBytes) < 0) || (nWriteBytes != nJpegLen)) sysprintf("File write error! %d %d\n", nWriteBytes); else sysprintf("%d bytes\n", nWriteBytes); fsCloseFile(hFile); hFile = fsOpenFile(suFileName, NULL, O_RDONLY ); if (hFile > 0) sysprintf("Opene file:[%s], file handle:%d\n", szFileName, hFile); else { sysprintf("Opene file Error\n"); while(1); } if ((fsReadFile(hFile, _JpegImageR, nJpegLen, &nWriteBytes) < 0) || (nWriteBytes != nJpegLen)) sysprintf("File read error! %d %d\n", nWriteBytes); fsCloseFile(hFile); if(memcmp(_JpegImage, _JpegImageR, nJpegLen) != 0 ) { sysprintf("Compare file error\n"); while(1); } } sysprintf("Done\n"); } void PenDriverConnectTest(void) { UINT32 uBlockSize, uFreeSize, uDiskSize; umass_register_connect(MassStotrageConnection); umass_register_disconnect(MassStotrageDisconnection); InitUsbSystem(); UMAS_InitUmasDriver(); sysDelay(30); /* Delay 300 ms */ while(1) { Hub_CheckIrqEvent(); if(i32MsConnect ==1) { if(i32AccessDone==0) { if (fsDiskFreeSpace('C', &uBlockSize, &uFreeSize, &uDiskSize) == 0) { sysprintf("Disk size = %d KB, Free speace = %d KB\n", uDiskSize, uFreeSize); } else { sysprintf("fsDiskFreeSpace failed!!\n"); sysprintf("Pen driver may plug out !\n"); } PenDriverAccess(1); i32AccessDone = 1; sysprintf("Please plug out the pen driver for test\n"); } } if(i32MsDisConnect == 0) ; if(i32MsConnect == 0) { sysDelay(100); sysprintf("Please plug in the pen driver for test\n"); } Hub_CheckIrqEvent(); } } INT main() { UINT32 u32Item, u32ExtFreq; UINT32 u32PllOutKHz; WB_UART_T uart; #ifndef ECOS sysDisableCache(); sysFlushCache(I_D_CACHE); sysEnableCache(CACHE_WRITE_BACK); u32ExtFreq = sysGetExternalClock(); sysUartPort(1); uart.uiFreq = u32ExtFreq*1000; /* use APB clock */ uart.uiBaudrate = 115200; uart.uiDataBits = WB_DATA_BITS_8; uart.uiStopBits = WB_STOP_BITS_1; uart.uiParity = WB_PARITY_NONE; uart.uiRxTriggerLevel = LEVEL_1_BYTE; sysInitializeUART(&uart); sysSetSystemClock(eSYS_UPLL, /* E_SYS_SRC_CLK eSrcClk, */ 192000, /* UINT32 u32PllKHz, */ 192000, /* UINT32 u32SysKHz, */ 192000, /* UINT32 u32CpuKHz, */ 192000/2, /* UINT32 u32HclkKHz, */ 192000/4); /* UINT32 u32ApbKHz */ u32PllOutKHz = sysGetPLLOutputKhz(eSYS_UPLL, u32ExtFreq); sysprintf("PLL out frequency %d Khz\n", u32PllOutKHz); sysSetTimerReferenceClock (TIMER0, u32ExtFreq*1000); sysStartTimer(TIMER0, 100, PERIODIC_MODE); outp32(REG_AHBCLK, inp32(REG_AHBCLK) & ~USBD_CKE); outp32(REG_APBCLK, 0xFFFFFFFF); #endif fsInitFileSystem(); do { sysprintf("====================================================================\n"); sysprintf("Please select the USB host port through Transceiver ports or GPIO\n"); sysprintf("[1] Transceiver port 0\n"); sysprintf("[2] Transceiver port 0 and 1\n"); sysprintf("[3] Host-like port (GPB0 , GPB1)\n"); sysprintf("[4] Host-like port (GPA3 , GPA4)\n"); sysprintf("====================================================================\n"); u32Item = sysGetChar(); switch(u32Item) { case '1': USB_PortInit(HOST_NORMAL_PORT0_ONLY); break; case '2': USB_PortInit(HOST_NORMAL_TWO_PORT); break; case '3': USB_PortInit(HOST_LIKE_PORT0); break; case '4': USB_PortInit(HOST_LIKE_PORT1); break; } }while((u32Item> '4') || (u32Item< '0')); sysprintf("=============================================================================================\n"); sysprintf("[1] Pen driver connect/disconect test\n"); sysprintf("[2] Integration test\n"); u32Item = sysGetChar(); switch(u32Item) { case '1': PenDriverConnectTest(); break; case '2': IntegrationTest(); break; } return 0; }