/** * Run disk performance test * R/W test can be masked to verify previous written data only * \param iMci Controller number. * \param wr Do block write. * \param rd Do block read. * \param errDetail Dump detailed error information. */ static void DiskPerformanceTest(uint8_t iMci, uint8_t wr, uint8_t rd, uint8_t errDetail) { sSdCard *pSd = &sdDrv[iMci]; uint8_t error = 0; uint32_t block, i, nBadBlock = 0, nErrors; uint32_t tickStart, tickEnd, ticks, rwSpeed; uint32_t *pBuf; DumpSeperator(); printf("-I- Performance test, size %dK, Multi %d, MCK %dMHz\n\r", TEST_PERFORMENCT_SIZE/1024, (int)performanceMultiBlock, (int)(BOARD_MCK/1000000)); #ifdef READ_MULTI printf("-I- Read by Multi block, size %d\n\r", (int)SDMMC_BLOCK_SIZE); #else printf("-I- Read block by block, size %d\n\r", (int)SDMMC_BLOCK_SIZE); #endif #ifdef WRITE_MULTI printf("-I- Write by Multi block, size %d\n\r", (int)SDMMC_BLOCK_SIZE); #else printf("-I- Write block by block, size %d\n\r", (int)SDMMC_BLOCK_SIZE); #endif if (wr) { printf("--- Write test .. "); for (i = 0; i < SDMMC_BLOCK_SIZE * performanceMultiBlock; i += 4) { pBuf = (uint32_t*)(void*)(&pBuffer[i]); *pBuf = TEST_FILL_VALUE_U32; } nBadBlock = 0; tickStart = GetTickCount(); for (block = TEST_BLOCK_START; block < (TEST_PERFORMENCT_SIZE/SDMMC_BLOCK_SIZE) + TEST_BLOCK_START; block += performanceMultiBlock) { pBuf = (uint32_t*)(void*)pBuffer; *pBuf = block; error = MMCT_WriteFun(pSd, block, performanceMultiBlock, pBuffer); if (error) { if (nBadBlock ++ >= NB_BAD_BLOCK) { printf("-E- WR_B(%u)\n\r", (unsigned int)block); break; } else error = 0; } } tickEnd = GetTickCount(); ticks = GetDelayInTicks(tickStart, tickEnd); rwSpeed = (TEST_PERFORMENCT_SIZE - nBadBlock * performanceMultiBlock * SDMMC_BLOCK_SIZE) / ticks; printf("Done, Bad %u, Speed %uK\n\r", (unsigned int)nBadBlock, (unsigned int)rwSpeed); } if (rd) { printf("--- Read test .. "); nBadBlock = 0; tickStart = GetTickCount(); for (block = TEST_BLOCK_START; block < (TEST_PERFORMENCT_SIZE/SDMMC_BLOCK_SIZE) + TEST_BLOCK_START; block += performanceMultiBlock) { error = MMCT_ReadFun(pSd, block, performanceMultiBlock, pBuffer); if (error) { if (nBadBlock ++ >= NB_BAD_BLOCK) { printf("-E- RD_B(%u)\n\r", (unsigned int)block); break; } else error = 0; } if (error) break; } tickEnd = GetTickCount(); ticks = GetDelayInTicks(tickStart, tickEnd); rwSpeed = (TEST_PERFORMENCT_SIZE - nBadBlock * performanceMultiBlock * SDMMC_BLOCK_SIZE) / ticks; printf("Done, read %u, Speed %uK\n\r", (unsigned int)(TEST_PERFORMENCT_SIZE - nBadBlock * performanceMultiBlock * SDMMC_BLOCK_SIZE)/SDMMC_BLOCK_SIZE, (unsigned int)rwSpeed); } printf("--- Data verify .. "); nErrors = 0; for (block = TEST_BLOCK_START; block < (TEST_PERFORMENCT_SIZE/SDMMC_BLOCK_SIZE) + TEST_BLOCK_START; block += performanceMultiBlock) { memset(pBuffer, 0x00, SDMMC_BLOCK_SIZE * performanceMultiBlock); error = MMCT_ReadFun(pSd, block, performanceMultiBlock, pBuffer); if (error) { printf("-E- RD_B(%u)\n\r", (unsigned int)block); break; } pBuf = (uint32_t*)(void*)pBuffer; if (*pBuf != block) { if (errDetail) { if (nErrors ++ < NB_ERRORS) { printf("-E- Blk(%u)[0](%08x<>%08x)\n\r", (unsigned int)block, (unsigned int)block, (unsigned int)(*pBuf)); } } else { printf("-E- BlkN(%x<>%x)\n\r", (unsigned int)block, (unsigned int)(*pBuf)); error = 1; break; } } for (i = 4; i < SDMMC_BLOCK_SIZE * performanceMultiBlock; i += 4) { pBuf = (uint32_t*)(void*)(&pBuffer[i]); if ( (*pBuf != TEST_FILL_VALUE_U32)) { if (errDetail) { /* Dump 10 errors only */ if (nErrors ++ < NB_ERRORS) { uint32_t j; printf("-E- Blk(%u)[%u](%08x.. <>", (unsigned int)block, (unsigned int)i, (unsigned int)TEST_FILL_VALUE_U32); for (j = (i > 4) ? (i - 4) : i; j <= i + 4; j += 4) { printf("%c%08X", (i == j) ? '!' : ' ', (unsigned int)(*pBuf)); } printf(")\n\r"); } } else { printf("-E- Blk(%u)[%u](%x<>%x)\n\r", (unsigned int)block, (unsigned int)i, (unsigned int)TEST_FILL_VALUE_U32, (unsigned int)(*pBuf)); error = 1; break; } } } if (error) break; } if (errDetail && nErrors) { printf("-I- %u u32 ERRORS found!\n\r", (unsigned int)nErrors); } if (error) return; printf("OK\n\r"); }
/** * \brief usart-hw-handshaking Application entry point.. * * Configures USART in hardware handshaking mode and * Timer Counter 0 to generate an interrupt every second. Then, start the first * transfer on the USART and wait in an endless loop. * * \return Unused (ANSI-C compatibility). */ int main( void ) { char pbaud_time[8]; uint32_t BytesRead, BytesToRead, baudrate, timeout, TxBytesLeft; uint8_t AppBufferRollOver = 0; uint8_t *pTxBuff; /* Disable watchdog*/ WDT_Disable(WDT); printf("-- USART Hardware Handshaking Example %s --\n\r", SOFTPACK_VERSION); printf("-- %s\n\r", BOARD_NAME); printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__, COMPILER_NAME); /* Enable I and D cache */ SCB_EnableICache(); SCB_EnableDCache(); /* Configure USART pins*/ PIO_Configure(pins, PIO_LISTSIZE(pins)); /* Configure systick for 1 ms. */ TimeTick_Configure(); NVIC_SetPriority(XDMAC_IRQn , XDMA_NVIC_PRIO); printf("\n\rEnter required baudrate:"); gets(pbaud_time); baudrate = (atoi(pbaud_time)) ? (atoi(pbaud_time)): 921600; printf("\n\rEnter required timeout (in microsec):"); gets(pbaud_time); timeout = atoi(pbaud_time); if (timeout > 1000) { timeout /= 1000; timeout = ((timeout * baudrate) / 1000); } else { timeout = (timeout * baudrate) / 1000000; } timeout = (timeout) ? ((timeout > MAX_RX_TIMEOUT) ? MAX_RX_TIMEOUT : timeout) \ : MAX_RX_TIMEOUT; printf("\n\r"); /* Configure USART */ _ConfigureUsart(baudrate, timeout); printf("\n\r"); /*Enable Rx channel of USART */ USARTD_EnableRxChannels(&Usartd, &UsartRx); #ifdef FULL_DUPLEX /*Enable Tx channel of USART */ USARTD_EnableTxChannels(&Usartd, &UsartTx); #endif /* Start receiving data and start timer*/ USARTD_RcvData(&Usartd); /*Initialize Ring buffer */ pUsartBuffer = (RignBuffer_t *)malloc(sizeof(RignBuffer_t)); _initCircularBuffer(pUsartBuffer); pTxBuff = &FirstAppBuff[0]; TxBytesLeft = 0; #ifdef USE_MD5_CHECK md5_init(&pms); #endif //USE_MD5_CHECK #ifdef FULL_DUPLEX printf( "\n\r-I- USART is in Full Duplex mode \n\r"); #else printf( "\n\r-I- USART is in Half Duplex mode \n\r"); #endif printf( "\n\r-I- Please send a file to serial port (USART0) \n\r"); BytesToRead = MIN_FREE_BYTES; // Bytes to read from ring-buffer while (1) { #ifdef USE_MD5_CHECK if (DBG_IsRxReady()) { ch = DBG_GetChar(); if (ch == 'm') { uint8_t i; md5_finish(&pms, md5); printf("\r\nmd5:"); for (i = 0; i < sizeof(md5);i++) printf("%.2x",md5[i]); printf("\r\n"); md5_init(&pms); TotalbytesReceived = 0; } } #endif /* Check Application buffer (100 KB)overflow */ if (((PingPongBufferFlag == 0) && (pTxBuff+BytesToRead) >= &FirstAppBuff[APP_BUFFER]) || (( PingPongBufferFlag == 1) && (pTxBuff+BytesToRead) >= &SecondAppBuff[APP_BUFFER])) { AppBufferRollOver = 1; // Roll over and start copying to the beginning of Application buffer to avoid errors if (PingPongBufferFlag) BytesToRead = (&SecondAppBuff[APP_BUFFER] - pTxBuff); else BytesToRead = (&FirstAppBuff[APP_BUFFER] - pTxBuff); memory_barrier(); } /* Read ring buffer */ BytesRead = RingBufferRead(pUsartBuffer, pTxBuff, BytesToRead); memory_sync(); TxBytesLeft += BytesRead; // number of bytes to send via USART Tx #ifdef USE_MD5_CHECK if (BytesRead > 0) md5_append(&pms,pTxBuff,BytesRead); #endif /* check if one of the application buffer is full and ready to send */ if (AppBufferRollOver && (TxBytesLeft == APP_BUFFER)) { AppBufferRollOver = 0; TxBytesLeft = 0; BytesRead = 0; BytesToRead = MIN_FREE_BYTES; // Bytes to read from ring-buffer while (!UsartTx.dmaProgress); if (PingPongBufferFlag) { PingPongBufferFlag = 0; pTxBuff = &FirstAppBuff[0]; } else { PingPongBufferFlag = 1; pTxBuff = &SecondAppBuff[0]; } memory_sync(); #ifdef FULL_DUPLEX USARTD_SendData(&Usartd); #endif } /* otherwise keep storing in same application buffer from Rx DMA's ring buffer */ else { BytesToRead = MIN_FREE_BYTES; // Bytes to read from ring-buffer pTxBuff += BytesRead; #ifdef FULL_DUPLEX /* Check for Tx timeout, if there is timeout then send the bytes left (less than 100 KB) in application buffer */ if ((GetDelayInTicks(TimeOutTimer, GetTicks()) == USART_TX_TIMEOUT) && TxBytesLeft) { // wait for any eventual USART Tx in progress while (!UsartTx.dmaProgress); FlushTxBuffer(TxBytesLeft); TimeOutTimer = GetTicks(); PingPongBufferFlag = 0; TxBytesLeft = 0; BytesRead = 0; BytesToRead = MIN_FREE_BYTES; // Bytes to read from ring-buffer pTxBuff = &FirstAppBuff[0]; _UpdateTxConfig((uint32_t)&FirstAppBuff[0], APP_BUFFER); TRACE_INFO_WP(" TX Tiemout \n\r"); } #endif } } }
/** * Sdio performance test * \param iMci Controller number. */ static void SdioPerformanceTest(uint8_t iMci) { sSdCard *pSd = &sdDrv[iMci]; uint32_t i, blkSize = 1, totalNb = 0; uint32_t tickStart, tickEnd, ticks, rwSpeed; DumpSeperator(); printf("-I- IO Performence test, size %dK, MCK %dMHz\n\r", TEST_PERFORMENCT_SIZE/1024, (int)(BOARD_MCK/1000000)); printf("Read Direct speed: "); tickStart = GetTickCount(); for (totalNb = 0;;) { if (SDIO_ReadDirect(pSd, SDIO_CIA, 0, &pBuffer[0], 0x14)) { return; } totalNb += 0x14; tickEnd = GetTickCount(); ticks = GetDelayInTicks(tickStart, tickEnd); if (ticks > 800) break; } rwSpeed = totalNb / ticks; printf("%uK\n\r", (unsigned int)rwSpeed); printf("Write Direct speed: "); tickStart = GetTickCount(); for (totalNb = 0;;) { for (i = 0; i < 0x14; i ++) { if (SDIO_WriteDirect(pSd, SDIO_CIA, SDIO_IEN_REG, pBuffer[SDIO_IEN_REG])) { return; } } totalNb += 0x14; tickEnd = GetTickCount(); ticks = GetDelayInTicks(tickStart, tickEnd); if (ticks > 800) break; } rwSpeed = totalNb / ticks; printf("%uK\n\r", (unsigned int)rwSpeed); #if 1 printf("R/W Extended test:\n\r"); for (blkSize = 4; blkSize <= 512; blkSize <<= 1) { printf("- Cnt %3u: ", (unsigned int)blkSize); tickStart = GetTickCount(); for (totalNb = 0;;) { if (SDIO_ReadBytes(pSd, SDIO_CIA, 0, 0, pBuffer, blkSize, 0, 0)) { return; } totalNb += blkSize; tickEnd = GetTickCount(); ticks = GetDelayInTicks(tickStart, tickEnd); if (ticks > 800) break; } rwSpeed = totalNb / ticks; printf("R %5uK, ", (unsigned int)rwSpeed); #if 1 for (i = 0; i < blkSize; i ++) pBuffer[i] = pBuffer[SDIO_IEN_REG]; tickStart = GetTickCount(); for (totalNb = 0;;) { if (SDIO_WriteBytes(pSd, SDIO_CIA, SDIO_IEN_REG, 1, pBuffer, blkSize, 0, 0)) { return; } totalNb += blkSize; tickEnd = GetTickCount(); ticks = GetDelayInTicks(tickStart, tickEnd); if (ticks > 800) break; } rwSpeed = totalNb / ticks; printf("W %5uK", (unsigned int)rwSpeed); #endif printf("\n\r"); } #endif }