/////////////////////////////////////////////////////////////////////////////// // SDMemSetBlockLen - Sets read/write block length for SD memory card // Input: pMemCard - SD memory card structure // BlockLen - New read/write block length // Output: // Return: win32 status code // Notes: /////////////////////////////////////////////////////////////////////////////// DWORD SDMemSetBlockLen(PSD_MEMCARD_INFO pMemcard, DWORD BlockLen) { DEBUGMSG(SDMEM_ZONE_CARD_IO, (TEXT("SDMemSetBlockLen: Setting block length to %d bytes\r\n"),BlockLen)); // issue a Set Block Length command return SDMemDoBusRequest( pMemcard, SD_CMD_SET_BLOCKLEN, BlockLen, SD_COMMAND, ResponseR1, 0, 0, NULL, 0); }
/////////////////////////////////////////////////////////////////////////////// // SDMemWriteUsingSingleBlocks - Write using only single block commands // Input: pMemCard - SD memory card structure // StartBlock - Starting 512 byte block for write // NumBlocks - Number of blocks to write // pBuffer - Pointer to buffer containing write data // Output: // Return: win32 status code // Notes: /////////////////////////////////////////////////////////////////////////////// DWORD SDMemWriteUsingSingleBlocks( PSD_MEMCARD_INFO pMemCard, LONG StartBlock, LONG NumBlocks, PUCHAR pBuffer ) { DWORD status = SD_API_STATUS_SUCCESS; // intermediate win32 status LONG block; // block count if (StartBlock + NumBlocks < StartBlock) { // Check for arithmetic overflow return ERROR_INVALID_PARAMETER; } if (!pMemCard->HighCapacity) { if (ULONG_MAX / SD_BLOCK_SIZE < StartBlock + NumBlocks) { return ERROR_INVALID_PARAMETER; } } // Split write operation into single blocks for( block=0; block<NumBlocks; block++ ) { DEBUGMSG(SDMEM_ZONE_CARD_IO, (TEXT("SDMemWriteUsingSingleBlocks: Writing block %d\r\n"), StartBlock+block)); DWORD dwOffset = StartBlock + block; if (!pMemCard->HighCapacity) { dwOffset *= SD_BLOCK_SIZE; } // issue single block write request status = SDMemDoBusRequest( pMemCard, SD_CMD_WRITE_BLOCK, dwOffset, SD_WRITE, ResponseR1, 1, SD_BLOCK_SIZE, pBuffer + (block*SD_BLOCK_SIZE), 0); if( ERROR_SUCCESS != status ) break; } return status; }
/////////////////////////////////////////////////////////////////////////////// // SDMemWriteMultiple - Write multiple 512 byte blocks of data to card // Input: pMemCard - SD memory card structure // StartBlock - Starting 512 byte block for write // NumBlocks - Number of blocks to write // pBuffer - Pointer to buffer containing write data // Output: // Return: win32 status code // Notes: /////////////////////////////////////////////////////////////////////////////// DWORD SDMemWriteMultiple( PSD_MEMCARD_INFO pMemCard, LONG StartBlock, LONG NumBlocks, PUCHAR pBuffer ) { DEBUGMSG(SDMEM_ZONE_CARD_IO, (TEXT("SDMemWriteMultiple: Writing blocks %d-%d\r\n"), StartBlock, StartBlock+NumBlocks-1)); if( pMemCard->SingleBlockWrites || (NumBlocks == 1)) { DEBUGMSG(SDMEM_ZONE_CARD_IO, (TEXT("SDMemWriteMultiple: Sending request to SDMemWriteUsingSingleBlocks\r\n"))); return SDMemWriteUsingSingleBlocks( pMemCard, StartBlock, NumBlocks, pBuffer ); } // high capacity cards just take the block offset. standard cards // take a byte offset. if (!pMemCard->HighCapacity) { if (ULONG_MAX / SD_BLOCK_SIZE < StartBlock) { ASSERT(FALSE); return ERROR_INVALID_PARAMETER; } StartBlock *= SD_BLOCK_SIZE; } // issue multi-block write request return SDMemDoBusRequest( pMemCard, SD_CMD_WRITE_MULTIPLE_BLOCK, StartBlock, SD_WRITE, ResponseR1, NumBlocks, SD_BLOCK_SIZE, pBuffer, SD_AUTO_ISSUE_CMD12); }
/////////////////////////////////////////////////////////////////////////////// // SDMemDoErase - Erase a contiguous set of blocks // Input: pMemCard - SD memory card structure // StartBlock - Starting 512 byte block for write // NumBlocks - Number of blocks to write // Output: // Return: win32 status code // Notes: /////////////////////////////////////////////////////////////////////////////// DWORD SDMemDoErase( PSD_MEMCARD_INFO pHandle, LONG StartBlock, LONG NumBlocks ) { DWORD dwStatus = ERROR_SUCCESS; DEBUGMSG(SDMEM_ZONE_CARD_IO, (TEXT("SDMemDoErase: Erasing {%u, %u}\r\n"), StartBlock, (StartBlock + NumBlocks))); // Specify starting block dwStatus = SDMemDoBusRequest( pHandle, SD_CMD_ERASE_WR_BLK_START, StartBlock, SD_COMMAND, ResponseR1, 0, 0, NULL, 0 ); if (dwStatus != ERROR_SUCCESS) { goto EXIT; } // Specify ending block dwStatus = SDMemDoBusRequest( pHandle, SD_CMD_ERASE_WR_BLK_END, StartBlock + NumBlocks, SD_COMMAND, ResponseR1, 0, 0, NULL, 0 ); if (dwStatus != ERROR_SUCCESS) { goto EXIT; } // Erase dwStatus = SDMemDoBusRequest( pHandle, SD_CMD_ERASE, 0, SD_COMMAND, ResponseR1b, 0, 0, NULL, 0 ); if (dwStatus != ERROR_SUCCESS) { goto EXIT; } EXIT:; if (dwStatus != ERROR_SUCCESS) { DEBUGMSG(SDMEM_ZONE_CARD_IO, (TEXT("SDMemDoErase: Failed\r\n"))); } return dwStatus; }
/////////////////////////////////////////////////////////////////////////////// // SDMemReadMultiple - Read multiple 512 byte blocks of data from card // Input: pMemCard - SD memory card info // StartBlock - Starting 512 byte block for read // NumBlocks - Number of blocks to read // pBuffer - Pointer to buffer for read data // Output: // Return: Win32 status code // Notes: /////////////////////////////////////////////////////////////////////////////// DWORD SDMemReadMultiple( PSD_MEMCARD_INFO pMemCard, ULONG StartBlock, ULONG NumBlocks, PUCHAR pBuffer ) { DEBUGMSG( SDMEM_ZONE_CARD_IO, (TEXT("SDMemReadMultiple: Reading blocks %d-%d\r\n"), StartBlock, StartBlock+NumBlocks-1)); // high capacity cards just take the block offset. standard cards // take a byte offset. if (!pMemCard->HighCapacity) { if (ULONG_MAX / SD_BLOCK_SIZE < StartBlock) { ASSERT(FALSE); return ERROR_INVALID_PARAMETER; } StartBlock *= SD_BLOCK_SIZE; } // perform block read request if (NumBlocks == 1) { // for single blocks return SDMemDoBusRequest( pMemCard, SD_CMD_READ_SINGLE_BLOCK, StartBlock, SD_READ, ResponseR1, NumBlocks, SD_BLOCK_SIZE, pBuffer, 0); } #if 0 // multi-block writes use the optimized command // we have to auto issue a stop command though return SDMemDoBusRequest( pMemCard, SD_CMD_READ_MULTIPLE_BLOCK, StartBlock, SD_READ, ResponseR1, NumBlocks, SD_BLOCK_SIZE, pBuffer, SD_AUTO_ISSUE_CMD12); // auto issue CMD12 #else // work around for a OMAP35XX silicon issue (data CRC error on READ_MULTIPLE_BLOCK command) { ULONG BlocksRead; DWORD Result = ERROR_SUCCESS; for (BlocksRead = 0; BlocksRead < NumBlocks; BlocksRead++) { Result = SDMemDoBusRequest( pMemCard, SD_CMD_READ_SINGLE_BLOCK, StartBlock, SD_READ, ResponseR1, 1, SD_BLOCK_SIZE, pBuffer, 0); pBuffer += SD_BLOCK_SIZE; if (!pMemCard->HighCapacity) StartBlock += SD_BLOCK_SIZE; else StartBlock++; if (Result != ERROR_SUCCESS) { RETAILMSG( 1, (TEXT("SDMemReadMultiple: Error READ_MULIPLE_BLOCK replacement failure at block %d, Error %d\r\n"), StartBlock, Result)); return Result; } } return Result; } #endif }
/////////////////////////////////////////////////////////////////////////////// // SDMemWriteMultiple - Write multiple 512 byte blocks of data to card // Input: pMemCard - SD memory card structure // StartBlock - Starting 512 byte block for write // NumBlocks - Number of blocks to write // pBuffer - Pointer to buffer containing write data // Output: // Return: win32 status code // Notes: /////////////////////////////////////////////////////////////////////////////// DWORD SDMemWriteMultiple( PSD_MEMCARD_INFO pMemCard, LONG StartBlock, LONG NumBlocks, PUCHAR pBuffer ) { DEBUGMSG(SDMEM_ZONE_CARD_IO, (TEXT("SDMemWriteMultiple: Writing blocks %d-%d\r\n"), StartBlock, StartBlock+NumBlocks-1)); #ifdef _FOR_MOVI_NAND_ // Date : 07.05.28 // Developer : HS.JANG // Description : moviNAND dose not support Single-Block write if ( pMemCard->IsHSMMC == TRUE ) { } else #endif { if( pMemCard->SingleBlockWrites || (NumBlocks == 1)) { DEBUGMSG(SDMEM_ZONE_CARD_IO, (TEXT("SDMemWriteMultiple: Sending request to SDMemWriteUsingSingleBlocks\r\n"))); return SDMemWriteUsingSingleBlocks( pMemCard, StartBlock, NumBlocks, pBuffer ); } } // high capacity cards just take the block offset. standard cards // take a byte offset. if (!pMemCard->HighCapacity) { if (ULONG_MAX / SD_BLOCK_SIZE < StartBlock) { ASSERT(FALSE); return ERROR_INVALID_PARAMETER; } StartBlock *= SD_BLOCK_SIZE; } // issue multi-block write request #ifdef _FOR_MOVI_NAND_ // Date : 07.05.28 // Developer : HS.JANG // Description : To use Pre-Define. Set the flag as // for moviANND. If you do not use moviNAND // Do NOT define FOR_MOVI_NAND if ( pMemCard->IsHSMMC == TRUE ) { return SDMemDoBusRequest( pMemCard, SD_CMD_WRITE_MULTIPLE_BLOCK, StartBlock, SD_WRITE, ResponseR1, NumBlocks, SD_BLOCK_SIZE, pBuffer, SD_MOVINAND_PRE_DEFINE); } #endif return SDMemDoBusRequest( pMemCard, SD_CMD_WRITE_MULTIPLE_BLOCK, StartBlock, SD_WRITE, ResponseR1, NumBlocks, SD_BLOCK_SIZE, pBuffer, SD_AUTO_ISSUE_CMD12); }
/////////////////////////////////////////////////////////////////////////////// // SDMemReadMultiple - Read multiple 512 byte blocks of data from card // Input: pMemCard - SD memory card info // StartBlock - Starting 512 byte block for read // NumBlocks - Number of blocks to read // pBuffer - Pointer to buffer for read data // Output: // Return: Win32 status code // Notes: /////////////////////////////////////////////////////////////////////////////// DWORD SDMemReadMultiple( PSD_MEMCARD_INFO pMemCard, ULONG StartBlock, ULONG NumBlocks, PUCHAR pBuffer ) { DEBUGMSG( SDMEM_ZONE_CARD_IO, (TEXT("SDMemReadMultiple: Reading blocks %d-%d\r\n"), StartBlock, StartBlock+NumBlocks-1)); // high capacity cards just take the block offset. standard cards // take a byte offset. if (!pMemCard->HighCapacity) { if (ULONG_MAX / SD_BLOCK_SIZE < StartBlock) { ASSERT(FALSE); return ERROR_INVALID_PARAMETER; } StartBlock *= SD_BLOCK_SIZE; } // perform block read request if (NumBlocks == 1) { // for single blocks return SDMemDoBusRequest( pMemCard, SD_CMD_READ_SINGLE_BLOCK, StartBlock, SD_READ, ResponseR1, NumBlocks, SD_BLOCK_SIZE, pBuffer, 0); } // multi-block writes use the optimized command // we have to auto issue a stop command though #ifdef _FOR_MOVI_NAND_ // Date : 07.05.28 // Developer : HS.JANG // Description : To use Pre-Define. Set the flag as // for moviANND. If you do not use moviNAND // Do NOT define FOR_MOVI_NAND if ( pMemCard->IsHSMMC == TRUE ) { return SDMemDoBusRequest( pMemCard, SD_CMD_READ_MULTIPLE_BLOCK, StartBlock, SD_READ, ResponseR1, NumBlocks, SD_BLOCK_SIZE, pBuffer, SD_MOVINAND_PRE_DEFINE); } #endif return SDMemDoBusRequest( pMemCard, SD_CMD_READ_MULTIPLE_BLOCK, StartBlock, SD_READ, ResponseR1, NumBlocks, SD_BLOCK_SIZE, pBuffer, SD_AUTO_ISSUE_CMD12); // auto issue CMD12 }