📄 smc.c
字号:
* 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 (smc_block_used)
{
smc_block_erase((Uint32)(smc_block_to_be_deleted) << 5);
}
/* increase the main buffer index */
smc_gl_buf_idx++;
/* if zone change */
if (smc_gl_buf_idx >= smc_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 ( !(smc_buf[smc_gl_buf_idx].w & 0x8000))
{
if ((smc_buf_free[smc_gl_buf_free_idx] & 0x7FFF) == smc_lut_block[smc_zone])
{
smc_gl_buf_free_idx++;
if (smc_gl_buf_free_idx >= smc_spare_block)
{
smc_gl_buf_free_idx = 0;
}
}
/* invert the block and assign the next block to be deleted */
smc_block_to_be_deleted = smc_buf[smc_gl_buf_idx].w;
smc_buf[smc_gl_buf_idx].w = smc_buf_free[smc_gl_buf_free_idx] & 0x7FFF;
smc_buf_free[smc_gl_buf_free_idx] = smc_block_to_be_deleted | 0x8000;
/* block have to be deleted */
smc_block_used = TRUE;
/* increase the spare buffer index */
if ((smc_gl_buf_free_idx++) >= smc_spare_block )
{
smc_gl_buf_free_idx = 0;
}
}
else /* The block is not assigned. Nothing to do */
{
smc_buf[smc_gl_buf_idx].w &= 0x7FFF;
smc_block_used = FALSE;
}
/* update the max index buffer */
if (smc_gl_buf_idx > smc_gl_buf_idx_max)
smc_gl_buf_idx_max = smc_gl_buf_idx;
/* Update current physical sector */
smc_current_physical_sector_addr = (Uint32)(smc_buf[smc_gl_buf_idx].w) << 5;
/* increase the logical block */
smc_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 */
smc_current_physical_sector_addr++;
}
}
}
Smc_CS_ON();
gl_buffer[(gl_cpt_page & 0xFF)] = b; /* Save data in gl_buffer */
gl_cpt_page++; /* Increase internal page counter */
if (gl_cpt_page == 256) /* First 256 bytes */
{
Smc_wait_busy();
Smc_write_open_A_area(smc_current_physical_sector_addr, 0x00);
smc_download_buffer(); /* Copy the buffer */
Smc_send_command(SMC_PAGE_PROGRAM_CMD);
#ifdef SMC_ECC
smc_calculate_ecc();
ecc[0] = ecc1;
ecc[1] = ecc2;
ecc[2] = ecc3;
#endif
smc_busy = TRUE;
}
else
if (gl_cpt_page == SMC_DATA_SIZE) /* check if end of data page */
{
Smc_wait_busy();
Smc_write_open_B_area(smc_current_physical_sector_addr, 0x00);
smc_download_buffer(); /* Copy the buffer */
#ifdef SMC_ECC
smc_calculate_ecc();
ecc[3] = ecc1;
ecc[4] = ecc2;
ecc[5] = ecc3;
#endif
smc_update_spare_data(); /* Update spare data */
Smc_send_command(SMC_PAGE_PROGRAM_CMD);
smc_busy = TRUE;
gl_ptr_mem++;
gl_cpt_page = 0;
}
return OK;
}
/*F**************************************************************************
* NAME: smc_write_sector
*----------------------------------------------------------------------------
* PARAMS:
* global: gl_ptr_mem
*
* return:
* write status: OK: write done
* KO: write not done
*----------------------------------------------------------------------------
* PURPOSE:
* This function is an optimized function that writes 512 bytes from USB
* controller to SMC card
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit smc_write_sector (Uint16 nb_sector)
{
bdata bit erase;
// char pdata *ptr = gl_buffer;
do
{
if ( Smc_card_detect() == KO )
{
gl_mem_failure = TRUE;
Smc_CS_OFF();
return KO;
}
erase = FALSE;
if (smc_busy)
{
smc_busy = FALSE;
/* if there is a block change */
if ( !(gl_ptr_mem & 0x1F) )
{
/* If previous block have to de deleted */
if (smc_block_used)
{
smc_block_erase((Uint32)(smc_block_to_be_deleted) << 5);
erase = TRUE;
}
/* increase the main buffer index */
smc_gl_buf_idx++;
/* if zone change */
if (smc_gl_buf_idx >= smc_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 ( !(smc_buf[smc_gl_buf_idx].w & 0x8000))
{
if ((smc_buf_free[smc_gl_buf_free_idx] & 0x7FFF) == smc_lut_block[smc_zone])
{
smc_gl_buf_free_idx++;
if (smc_gl_buf_free_idx >= smc_spare_block)
{
smc_gl_buf_free_idx = 0;
}
}
/* invert the block and assign the next block to be deleted */
smc_block_to_be_deleted = smc_buf[smc_gl_buf_idx].w;
smc_buf[smc_gl_buf_idx].w = smc_buf_free[smc_gl_buf_free_idx] & 0x7FFF;
smc_buf_free[smc_gl_buf_free_idx] = smc_block_to_be_deleted | 0x8000;
/* block have to be deleted */
smc_block_used = TRUE;
/* increase the spare buffer index */
if ((smc_gl_buf_free_idx++) >= smc_spare_block )
{
smc_gl_buf_free_idx = 0;
}
}
else /* The block is not assigned. Nothing to do */
{
smc_buf[smc_gl_buf_idx].w &= 0x7FFF;
smc_block_used = FALSE;
}
/* update the max index buffer */
if (smc_gl_buf_idx > smc_gl_buf_idx_max)
smc_gl_buf_idx_max = smc_gl_buf_idx;
/* Update current physical sector */
smc_current_physical_sector_addr = (Uint32)(smc_buf[smc_gl_buf_idx].w) << 5;
/* increase the logical block */
smc_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 */
smc_current_physical_sector_addr++;
}
}
#ifndef SMC_ECC
Smc_CS_ON();
Smc_wait_busy();
Smc_write_open_A_area(smc_current_physical_sector_addr, 0x00);
/* If no ECC */
for (j = 8; j != 0; j--)
{
while (!Usb_rx_complete()); /* wait end of reception */
Smc_wr_byte(Usb_read_byte()); /* write 64 bytes to card */
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Smc_wr_byte(Usb_read_byte());
Usb_clear_RXOUT_PP(); /* usb read acknowledgement */
}
#else
Smc_wait_busy();
Smc_write_open_A_area(smc_current_physical_sector_addr, 0x00);
/* If ECC */
// for (j = 4 ; j != 0; j--) /* Load 256b = 4 * 64 */
// {
while (!Usb_rx_complete()); /* wait end of reception */
smc_usb_to_buff_64(0); /* Download usb datas to gl_buffer b0 b63*/
Usb_clear_RXOUT_PP();
while (!Usb_rx_complete()); /* wait end of reception */
smc_usb_to_buff_64(64); /* Download usb datas to gl_buffer b64 b127*/
Usb_clear_RXOUT_PP();
while (!Usb_rx_complete()); /* wait end of reception */
smc_usb_to_buff_64(128); /* Download usb datas to gl_buffer b128 b191*/
Usb_clear_RXOUT_PP();
while (!Usb_rx_complete()); /* wait end of reception */
smc_usb_to_buff_64(192); /* Download usb datas to gl_buffer b192 b255*/
Usb_clear_RXOUT_PP();
/* (*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
(*ptr++) = Usb_read_byte();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -