📄 smc.c
字号:
}
else
{
Smc_send_command(SMC_READ_A_AREA_CMD); /* first half page */
Smc_send_address(logical_block << 1);
}
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();
for (j = 0; j < block_max ; j++)
{
/* Read conversion table : 64 datas */
buf[j].b[0] = Smc_rd_byte();
buf[j].b[1] = Smc_rd_byte();
i++;
if (i == 0)
{
address++;
Smc_send_command(SMC_READ_A_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();
}
}
if (change_zone) /* If it is a new zone, then load the spare buffer */
{
/* Check for used block : first, read in the LUT the free physical block */
address = ((Uint32)(look_up_table_block)<<5) + 3;
address += (Uint32)(lut_index[smc_zone])<<2;
Smc_send_command(SMC_READ_B_AREA_CMD); /* Second half array */
Smc_send_address( 208);
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();
for (i = 0; i <= (spare_block); i++)
{
buf_free[i] = (Uint16)(Smc_rd_byte()<<8);
buf_free[i] += Smc_rd_byte();
}
}
gl_buf_idx = 0; /* initialize index for main buffer */
gl_buf_idx_max = 0; /* initialize the max index for the buffer */
}
/* if block is already assigned, then invert with a spare block */
block_used = ( !(buf[gl_buf_idx].w & 0x8000) ) ? TRUE : FALSE;
if (block_used)
{
if ((buf_free[gl_buf_free_idx] & 0x7FFF) == look_up_table_block)
{
gl_buf_free_idx++;
if (gl_buf_free_idx >= spare_block )
{
gl_buf_free_idx = 0;
}
}
/* assign block to be deleted */
block_to_be_deleted = buf[gl_buf_idx].w;
buf[gl_buf_idx].w = buf_free[gl_buf_free_idx];
buf_free[gl_buf_free_idx++] = block_to_be_deleted | 0x8000;
/* increase the index for spare block buffer */
if (gl_buf_free_idx >= spare_block )
{
gl_buf_free_idx = 0;
}
}
/* Mark block as assigned */
buf[gl_buf_idx].w &= 0x7FFF;
if (gl_buf_idx > gl_buf_idx_max)
gl_buf_idx_max = gl_buf_idx;
/* Update the current physical sector address */
current_physical_sector_addr = ((Uint32)(buf[gl_buf_idx].w) << 5);
if ( block_used ) /* Fisrt block already used block ? */
{
smc_copy_block_head(); /* Copy the first part of the block */
}
else
{
smc_init_spare(); /* else init spare data for new logical block */
}
smc_busy = FALSE; /* Clear flag busy */
lut_modified = TRUE;
/* Set LUT as modified */
address = ((Uint32)(look_up_table_block)<<5);
address += (Uint32)(lut_index[smc_zone])<<2;
Smc_send_command(SMC_READ_C_AREA_CMD); /* Data spare area */
Smc_send_command (SMC_SEQUENTIAL_DATA_INPUT_CMD);/* Sequential data input Type Command */
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); /* Reset first byte */
Smc_send_command(SMC_PAGE_PROGRAM_CMD); /* Send program command to the device */
Smc_wait_busy();
return OK;
}
/*F**************************************************************************
* NAME: smc_write_close
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Low level memory write close: release SMC
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit smc_write_close (void)
{
Smc_CS_ON();
if (gl_cpt_page != 0) /* uncomplete write */
{
if (gl_cpt_page < 256) /* First half page */
{
for ( ; gl_cpt_page < 256; gl_cpt_page++)
{
gl_buffer[gl_cpt_page] = 0x00;
}
Smc_wait_busy();
Smc_send_command (SMC_READ_A_AREA_CMD);
Smc_send_command (SMC_SEQUENTIAL_DATA_INPUT_CMD); /* Sequential data input Type Command */
Smc_send_address ( 0x00 ); /* 1st address cycle*/
Smc_send_address ( ((Byte*)¤t_physical_sector_addr)[3] ); /* 2nd address cycle*/
Smc_send_address ( ((Byte*)¤t_physical_sector_addr)[2] ); /* 3rd address cycle*/
if (smc_64) /* Size of card >= 64Mbytes ?*/
Smc_send_address ( ((Byte*)¤t_physical_sector_addr)[1] );/* 4th address cycle*/
/* Copy the buffer */
smc_download_buffer();
/* Program the device */
Smc_send_command(SMC_PAGE_PROGRAM_CMD);
#ifdef SMC_ECC
smc_calculate_ecc();
ecc[0] = ecc1;
ecc[1] = ecc2;
ecc[2] = ecc3;
#endif
}
/* 2nd half page */
for ( ; gl_cpt_page < 512; gl_cpt_page++)
{
gl_buffer[gl_cpt_page] = 0x00;
}
Smc_wait_busy();
Smc_send_command (SMC_READ_B_AREA_CMD);
Smc_send_command (SMC_SEQUENTIAL_DATA_INPUT_CMD); /* Sequential data input Type Command */
Smc_send_address ( 0x00 ); /* 1st address cycle*/
Smc_send_address ( ((Byte*)¤t_physical_sector_addr)[3] ); /* 2nd address cycle*/
Smc_send_address ( ((Byte*)¤t_physical_sector_addr)[2] ); /* 3rd address cycle*/
if (smc_64) /* Size of card >= 64Mbytes ?*/
Smc_send_address ( ((Byte*)¤t_physical_sector_addr)[1] );/* 4th address cycle*/
/* Copy the buffer */
smc_download_buffer();
#ifdef SMC_ECC
smc_calculate_ecc();
ecc[3] = ecc1;
ecc[4] = ecc2;
ecc[5] = ecc3;
#endif
smc_update_spare_data();
Smc_send_command(SMC_PAGE_PROGRAM_CMD); /* Send program command to the device */
gl_cpt_page = 0;
gl_ptr_mem++;
}
/* Copy last part of a block if the block was assigned */
if (block_used)
{
if ( gl_ptr_mem & 0x1F )
smc_copy_block_tail();
smc_block_erase((Uint32)(block_to_be_deleted) << 5); /* Erase old block */
}
Smc_wait_busy();
Smc_CS_OFF();
return OK;
}
/*F**************************************************************************
* NAME: smc_write_byte
*----------------------------------------------------------------------------
* PARAMS:
* b: data to write
*
* RETURN:
* write status: OK: write done
* KO: write not done
*
*----------------------------------------------------------------------------
* PURPOSE:
* Low level memory write function
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit smc_write_byte (Byte b)
{
char pdata *ptr = gl_buffer;
if ( Smc_card_detect() == KO )
{
gl_mem_failure = TRUE;
Smc_CS_OFF();
return KO;
}
if (smc_busy)
{
smc_busy = FALSE;
if (!gl_cpt_page) /* if we are at the beginning of a new page */
{
/* if there is a block change */
if ( !(gl_ptr_mem & 0x1F) )
{
/* If previous block have to de deleted */
if (block_used)
{
smc_block_erase((Uint32)(block_to_be_deleted) << 5);
}
/* increase the main buffer index */
gl_buf_idx++;
/* if zone change */
if (gl_buf_idx >= block_max)
{
smc_write_open(gl_ptr_mem);
}
else
{
/* if the block in the buffer is already assign, then invert it with a spare block */
if ( !(buf[gl_buf_idx].w & 0x8000))
{
if ((buf_free[gl_buf_free_idx] & 0x7FFF) == lut_block[smc_zone])
{
gl_buf_free_idx++;
if (gl_buf_free_idx >= spare_block)
{
gl_buf_free_idx = 0;
}
}
/* invert the block and assign the next block to be deleted */
block_to_be_deleted = buf[gl_buf_idx].w;
buf[gl_buf_idx].w = buf_free[gl_buf_free_idx] & 0x7FFF;
buf_free[gl_buf_free_idx] = block_to_be_deleted | 0x8000;
/* block have to be deleted */
block_used = TRUE;
/* increase the spare buffer index */
if ((gl_buf_free_idx++) >= spare_block )
{
gl_buf_free_idx = 0;
}
}
else /* The block is not assigned. Nothing to do */
{
buf[gl_buf_idx].w &= 0x7FFF;
block_used = FALSE;
}
/* update the max index buffer */
if (gl_buf_idx > gl_buf_idx_max)
gl_buf_idx_max = gl_buf_idx;
/* Update current physical sector */
current_physical_sector_addr = (Uint32)(buf[gl_buf_idx].w) << 5;
/* increase the logical block */
logical_block++;
/* calculate the redundant block address */
smc_calc_logical_block();
}
}
else /* if there is no block change, we just need to continue write operation */
{ /* on the next physical sector */
current_physical_sector_addr++;
}
}
}
Smc_CS_ON();
/* Save data in gl_buffer */
gl_buffer[(gl_cpt_page & 0xFF)] = b;
/* Increase internal page counter */
gl_cpt_page++;
if (gl_cpt_page == 256) /* First 256 bytes */
{
/* Open in write mode in A Area */
Smc_wait_busy();
Smc_send_command (SMC_READ_A_AREA_CMD);
Smc_send_command (SMC_SEQUENTIAL_DATA_INPUT_CMD); /* Sequential data input Type Command */
Smc_send_address ( 0x00 ); /* 1st address cycle*/
Smc_send_address ( ((Byte*)¤t_physical_sector_addr)[3] ); /* 2nd address cycle*/
Smc_send_address ( ((Byte*)¤t_physical_sector_addr)[2] ); /* 3rd address cycle*/
if (smc_64) /* Size of card >= 64Mbytes ?*/
Smc_send_address ( ((Byte*)¤t_physical_sector_addr)[1] );/* 4th address cycle*/
/* Copy the buffer */
smc_download_buffer();
Smc_send_command(SMC_PAGE_PROGRAM_CMD);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -