📄 smc_drv.c
字号:
/* Write 256 bytes from the buffer */
smc_download_buffer();
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xE8);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xE8);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
/* Valid the page programmation */
Smc_send_command(SMC_PAGE_PROGRAM_CMD);
start += 128;
address2++;
address++;
}
while (start < 1024);
gl_buf_idx_max = 0;
if (lut_index[smc_zone] == 0)
{
address2 = (Uint32)(lut_block[smc_zone])<<5;
/* Update address of look up table */
Smc_wait_busy();
Smc_send_command (SMC_READ_A_AREA_CMD);
Smc_send_command (SMC_BLOCK_ERASE_CMD); /* Auto Block Erase Setup */
Smc_send_address ( ((Byte*)&address2)[3] ); /* 2nd address cycle*/
Smc_send_address ( ((Byte*)&address2)[2] ); /* 3rd address cycle*/
if (smc_64) /* Size of card >= 64Mbytes ?*/
Smc_send_address ( ((Byte*)&address2)[1] ); /* 4th address cycle*/
Smc_send_command(SMC_BLOCK_ERASE_CONFIRM_CMD); /* Erase command */
lut_block[smc_zone] = look_up_table_block;
}
Smc_wait_busy();
}
/*F**************************************************************************
* NAME: smc_mark_bad_block
*----------------------------------------------------------------------------
* PARAMS:
*
*
* RETURN:
*
*
*----------------------------------------------------------------------------
* PURPOSE: Write 0x00 on block status byte (Byte 5 of spare data)
*
*
*****************************************************************************
* NOTE: This function use the global variable Uint32 address
*
*
*
*
*****************************************************************************/
void smc_mark_bad_block(void)
{
Smc_wait_busy();
Smc_send_command (SMC_READ_C_AREA_CMD);
Smc_send_command (SMC_SEQUENTIAL_DATA_INPUT_CMD);
Smc_send_address (0x00);
Smc_send_address ( ((Byte*)&address)[3] ); /* 2nd address cycle */
Smc_send_address ( ((Byte*)&address)[2] ); /* 3rd address cycle */
if (smc_64) /* Size of card >= 64Mbytes ?*/
Smc_send_address ( ((Byte*)&address)[1] ); /* 4th address cycle */
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
/* Send program command */
Smc_send_command (SMC_PAGE_PROGRAM_CMD);
Smc_wait_busy();
}
/*F**************************************************************************
* NAME: smc_block_erase
*----------------------------------------------------------------------------
* PARAMS:
*
*
* RETURN: OK : erase done
* KO : erase not done
*
*----------------------------------------------------------------------------
* PURPOSE: Erase a block on Nand Flash Media
*
*
*****************************************************************************
* NOTE:
*
*
*
*
*****************************************************************************/
bit smc_block_erase (Uint32 pos)
{
Smc_wait_busy();
Smc_send_command (SMC_READ_A_AREA_CMD);
Smc_send_command (SMC_BLOCK_ERASE_CMD); /* Auto Block Erase Setup */
Smc_send_address ( ((Byte*)&pos)[3] ); /* 2nd address cycle */
Smc_send_address ( ((Byte*)&pos)[2] ); /* 3rd address cycle */
if (smc_64) /* Size of card >= 64Mbytes ? */
Smc_send_address ( ((Byte*)&pos)[1] ); /* 4th address cycle */
Smc_send_command(SMC_BLOCK_ERASE_CONFIRM_CMD);/* Erase command */
return OK;
}
/*F**************************************************************************
* NAME: smc_erase_all_block
*----------------------------------------------------------------------------
* PARAMS:
*
*
* RETURN:
*
*----------------------------------------------------------------------------
* PURPOSE: This function erase all blocks on a SMC card and write CIS
* information
*
*
*****************************************************************************
* NOTE:
*
*****************************************************************************/
bit smc_erase_all_block(void)
{
char pdata *ptr = gl_buffer;
bit bad_block_detect;
Uint16 i;
Smc_CS_ON();
/* Erase all block */
for (address = (Uint32)(smc_zone_max) * 1024 * 32 - 32; address != 0; address-=32)
{
/* Read block status byte */
Smc_wait_busy();
Smc_send_command(SMC_READ_C_AREA_CMD);
Smc_send_address(0x05);
Smc_send_address ( ((Byte*)&address)[3] ); /* 2nd address cycle */
Smc_send_address ( ((Byte*)&address)[2] ); /* 3rd address cycle */
if (smc_64) /* Size of card >= 64Mbytes ?*/
Smc_send_address ( ((Byte*)&address)[1] ); /* 4th address cycle */
Smc_wait_busy();
if (Smc_rd_byte() == 0xFF) /* Not a bad block */
{
smc_block_erase(address);
if ( smc_check_status() == KO)
{ /* Failure on erase operation */
smc_mark_bad_block();
}
else
{ /* Fill redundant area with 0x00 */
Smc_wait_busy();
Smc_send_command(SMC_READ_C_AREA_CMD);
Smc_send_command(SMC_SEQUENTIAL_DATA_INPUT_CMD);
Smc_send_address(0x00);
Smc_send_address ( ((Byte*)&address)[3] ); /* 2nd address cycle */
Smc_send_address ( ((Byte*)&address)[2] ); /* 3rd address cycle */
if (smc_64) /* Size of card >= 64Mbytes ?*/
Smc_send_address ( ((Byte*)&address)[1] ); /* 4th address cycle */
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
/* Valid the page programmation */
Smc_send_command(SMC_PAGE_PROGRAM_CMD);
if ( smc_check_status() == KO)
{ /* Failure on program operation */
smc_mark_bad_block();
}
/* Read 16 bytes */
Smc_wait_busy();
Smc_send_command(SMC_READ_C_AREA_CMD);
Smc_send_address(0x00);
Smc_send_address( ((Byte*)&address)[3] ); /* 2nd address cycle */
Smc_send_address( ((Byte*)&address)[2] ); /* 3rd address cycle */
if (smc_64) /* Size of card >= 64Mbytes ?*/
Smc_send_address( ((Byte*)&address)[1] ); /* 4th address cycle */
Smc_wait_busy();
bad_block_detect = FALSE;
for (i = 16; i != 0; i--)
{
if (Smc_rd_byte() != 0x00) bad_block_detect = TRUE;
}
if (bad_block_detect)
{
smc_mark_bad_block();
}
else
{
/* Finally, erase the block */
smc_block_erase(address);
if ( smc_check_status() == KO)
{ /* Failure on erase operation */
smc_mark_bad_block();
}
}
}
}
}
/* Reconstruct the CIS */
/* Open in write mode at the address 0x00 */
Smc_wait_busy();
Smc_send_command(SMC_READ_A_AREA_CMD);
Smc_send_command(SMC_SEQUENTIAL_DATA_INPUT_CMD);
Smc_send_address(0x00);
Smc_send_address(0x00);
Smc_send_address(0x00);
if (smc_64)
Smc_send_address(0x00);
/* Save CIS table in gl_buffer */
for (i = 0; i < 256; i++)
{
(*ptr++) = smc_cis_table[i];
}
/* write buffer 2 times */
smc_download_buffer();
smc_download_buffer();
/* Calculate ecc */
smc_calculate_ecc();
ecc[0] = ecc1;
ecc[1] = ecc2;
ecc[2] = ecc3;
/* Write spare data */
#ifndef SMC_ECC
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0x00);
Smc_wr_byte(0x00);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
Smc_wr_byte(0xFF);
#else
Smc_wr_byte(0xFF); /* User Data area */
Smc_wr_byte(0xFF); /* User Data area */
Smc_wr_byte(0xFF); /* User Data area */
Smc_wr_byte(0xFF); /* User Data area */
Smc_wr_byte(0xFF); /* User status area */
Smc_wr_byte(0xFF); /* Block status area */
Smc_wr_byte(0x00); /* Block address area 1 */
Smc_wr_byte(0x00); /* Block address area 1 */
Smc_wr_byte(ecc[0]); /* ECC area 2 */
Smc_wr_byte(ecc[1]); /* ECC area 2 */
Smc_wr_byte(ecc[2]); /* ECC area 2 */
Smc_wr_byte(0x00); /* Block address area 2 */
Smc_wr_byte(0x00); /* Block address area 2 */
Smc_wr_byte(ecc[0]); /* ECC area 1 */
Smc_wr_byte(ecc[1]); /* ECC area 1 */
Smc_wr_byte(ecc[2]); /* ECC area 1 */
#endif
/* Valid the page programmation */
Smc_send_command(SMC_PAGE_PROGRAM_CMD);
Smc_wait_busy();
read_spare_byte();
return OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -