/*********************************************************** * Function: * Description: * Input: * Input: * Output: * Return: * Others: ***********************************************************/ static rt_uint8_t _spi_sd_sendcmd_hold( rt_uint8_t cmd, rt_uint32_t arg, rt_uint8_t crc ) { rt_uint32_t r1, n; #if 1 if( cmd & 0x80 ) /* ACMD<n> is the command sequence of CMD55-CMD<n> */ { cmd &= 0x7F; r1 = _spi_sd_sendcmd( APP_CMD, 0, DUMMY_CRC ); /* CMD55 */ if( r1 > 1 ) { return r1; /* cmd send failed */ } } #endif _spi_send_recv( DUMMY_BYTE ); _card_enable( ); _spi_send_recv( cmd ); _spi_send_recv( arg >> 24 ); _spi_send_recv( arg >> 16 ); _spi_send_recv( arg >> 8 ); _spi_send_recv( arg ); _spi_send_recv( crc ); for( n = 0; n < 200; n++ ) { r1 = _spi_send_recv( DUMMY_BYTE ); if( r1 != 0xFF ) { break; } } return ( r1 ); /* Return with the response value */ }
/***************************************************************************** Write "count" Sector(s) starting from sector index "sector", buff -> [sector, sector+1, ... sector+count-1] if success, return true, otherwise return false *****************************************************************************/ static rt_uint8_t _spi_sd_writesector( rt_uint32_t sector, const rt_uint8_t *buff, rt_uint32_t count ) { if( !( CardType & CT_BLOCK ) ) { sector *= 512; /* Convert to byte address if needed */ } if( count == 1 ) /* Single block write */ { if( ( _spi_sd_sendcmd( WRITE_BLOCK, sector, DUMMY_CRC ) == 0 ) && _spi_sd_writedatablock( buff, TOKEN_SINGLE_BLOCK ) ) { count = 0; } } else /* Multiple block write */ { if( CardType & CT_SDC ) { _spi_sd_sendcmd( SET_WR_BLK_ERASE_COUNT, count, DUMMY_CRC ); } if( _spi_sd_sendcmd( WRITE_MULT_BLOCK, sector, DUMMY_CRC ) == 0 ) { do { if( !_spi_sd_writedatablock( buff, TOKEN_MULTI_BLOCK ) ) { break; } buff += 512; } while( --count ); #if 1 if( !_spi_sd_writedatablock( 0, TOKEN_STOP_TRAN ) ) /* STOP_TRAN token */ { count = 1; } #else _spi_send_recv( TOKEN_STOP_TRAN ); #endif } } //LPC17xx_SPI_Release(); //SPI_SSOutputCmd(SPI1,DISABLE); _card_disable( ); _spi_send_recv( DUMMY_BYTE ); return count ? false : true; }
/***************************************************************************** Read "count" Sector(s) starting from sector index "sector", buff <- [sector, sector+1, ... sector+count-1] if success, return true, otherwise return false *****************************************************************************/ static rt_uint8_t _spi_sd_readsector( rt_uint32_t sector, rt_uint8_t * buff, rt_uint32_t count ) { /* Convert to byte address if needed */ if( !( CardType & CT_BLOCK ) ) { sector *= SD_SECTOR_SIZE; } if( count == 1 ) /* Single block read */ { if( _spi_sd_sendcmd_hold( READ_BLOCK, sector, DUMMY_CRC ) != 0x0 ) { return false; } if( !_spi_sd_readdatablock( buff, SD_SECTOR_SIZE, RELEASE ) ) { return false; } //if (_spi_sd_sendcmd(STOP_TRAN, 0,DUMMY_CRC) != 0x0) return false; return true; } else /* Multiple block read */ { if( !_spi_sd_sendcmd( READ_MULT_BLOCK, sector, DUMMY_CRC ) ) { return false; } do { if( !_spi_sd_readdatablock( buff, SD_SECTOR_SIZE, HOLD ) ) { return false; } buff += SD_SECTOR_SIZE; } while( --count ); _spi_sd_sendcmd( STOP_TRAN, 0, DUMMY_CRC ); /* STOP_TRANSMISSION */ } //LPC17xx_SPI_Release(); //SPI_SSOutputCmd(SPI1,DISABLE); _card_disable( ); _spi_send_recv( DUMMY_BYTE ); return true; }
/***************************************************************************** Send a Command to Flash card and get a Response cmd: cmd index arg: argument for the cmd return the received response of the commond *****************************************************************************/ static rt_uint8_t _spi_sd_sendcmd( rt_uint8_t cmd, rt_uint32_t arg, rt_uint8_t crc ) { rt_uint32_t n; rt_uint8_t r1; #if 1 if( cmd & 0x80 ) /* ACMD<n> is the command sequence of CMD55-CMD<n> */ { cmd &= 0x7F; r1 = _spi_sd_sendcmd( APP_CMD, 0, DUMMY_CRC ); /* CMD55 */ if( r1 > 1 ) { return r1; /* cmd send failed */ } } #endif /* Select the card and wait for ready */ // LPC17xx_SPI_DeSelect(); // LPC17xx_SPI_Select(); // if (_spi_sd_wait4ready() == false ) return 0xFF; _spi_send_recv( DUMMY_BYTE ); _card_enable( ); _spi_send_recv( cmd ); _spi_send_recv( arg >> 24 ); _spi_send_recv( arg >> 16 ); _spi_send_recv( arg >> 8 ); _spi_send_recv( arg ); _spi_send_recv( crc ); #if 0 n = 10; /* Wait for a valid response in timeout of 10 attempts */ do { r1 = _spi_send_recv( DUMMY_BYTE ); } while( ( r1 & 0x80 ) && --n ); #endif #if 1 for( n = 0; n < 200; n++ ) { r1 = _spi_send_recv( DUMMY_BYTE ); if( r1 != 0xFF ) { break; } } #endif _card_disable( ); _spi_send_recv( DUMMY_BYTE ); return r1; /* Return with the response value */ }