📄 smc.c
字号:
}
/*F**************************************************************************
* NAME: smc_read_close
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Low level memory read close
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void smc_read_close (void)
{
Smc_CS_OFF();
}
/*F*************************************************************************
* NAME: smc_read_byte
*---------------------------------------------------------------------------
* PARAMS:
*
* return:
* Data read from memory
*---------------------------------------------------------------------------
* PURPOSE:
* Low level memory read function
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
****************************************************************************/
Byte smc_read_byte (void)
{
Byte b;
if ( Smc_card_detect() == KO )
{
gl_mem_failure = TRUE;
Smc_CS_OFF();
return KO;
}
Smc_wait_busy();
if (!gl_cpt_page)
{
Smc_CS_ON();
Smc_send_command (SMC_READ_A_AREA_CMD);
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 */
Smc_wait_busy();
b = Smc_rd_byte();
Smc_CS_OFF();
}
else
{
b = Smc_rd_byte();
}
gl_cpt_page++;
/* Detection of the end of data page */
if (gl_cpt_page == SMC_DATA_SIZE)
{
/* read spare data bytes */
Smc_rd_byte();
Smc_rd_byte();
Smc_rd_byte();
Smc_rd_byte();
Smc_rd_byte();
Smc_rd_byte();
Smc_rd_byte();
Smc_rd_byte();
Smc_rd_byte();
Smc_rd_byte();
Smc_rd_byte();
Smc_rd_byte();
Smc_rd_byte();
Smc_rd_byte();
Smc_rd_byte();
Smc_rd_byte();
gl_ptr_mem++; /* new page */
gl_cpt_page=0; /* start at column 0 */
if ( !(gl_ptr_mem & 0x1F) ) /* New block ? */
{
smc_read_open(gl_ptr_mem);
}
else
{
current_physical_sector_addr++;
}
}
return b;
}
/*F**************************************************************************
* NAME: smc_read_sector
*----------------------------------------------------------------------------
* PARAMS:
* global: gl_ptr_mem
*
* return: OK read done
* KO read failure
*----------------------------------------------------------------------------
* PURPOSE:
* This function is an optimized function that writes 512 bytes from SMC
* card to USB controller
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit smc_read_sector(void)
{
Byte i;
if ( Smc_card_detect() == KO )
{
gl_mem_failure = TRUE;
Smc_CS_OFF();
return KO;
}
Smc_CS_ON();
Smc_wait_busy();
Smc_send_command (SMC_READ_A_AREA_CMD);
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 */
Smc_wait_busy();
for (i = 8; i != 0; i--)
{
Usb_write_byte(Smc_rd_byte()); /* read 64 bytes from card */
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_write_byte(Smc_rd_byte());
Usb_set_TXRDY(); /* start usb transfer */
while (!Usb_tx_complete()); /* wait end of transfer */
Usb_clear_TXCMPL(); /* ack transfer */
}
gl_ptr_mem++; /* new page */
Smc_CS_OFF();
if ( !(gl_ptr_mem & 0x1F) ) /* New block ? */
{
smc_read_open(gl_ptr_mem);
}
else
{
current_physical_sector_addr++;
}
return OK;
}
/*F**************************************************************************
* NAME: smc_write_open
*----------------------------------------------------------------------------
* AUTHOR:
*----------------------------------------------------------------------------
* PARAMS:
* pos: address of the the next write data
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Low level memory write update
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit smc_write_open (Uint32 pos)
{
Byte i;
Byte j;
bit change_zone = FALSE;
if ( Smc_card_detect() == KO )
{
gl_mem_failure = TRUE;
Smc_CS_OFF();
return KO;
}
gl_ptr_mem = pos;
gl_cpt_page = 0;
/* Determine the logical block value */
logical_block = (gl_ptr_mem >> 5);
smc_zone = 0;
while (logical_block > 999)
{
logical_block -= 1000;
smc_zone++;
}
Smc_CS_ON();
if (smc_zone != smc_old_zone)
{
change_zone = TRUE;
if (lut_modified)
{ /* save old lut */
i = smc_old_zone;
smc_old_zone = smc_zone;
smc_zone = i;
smc_reassign_block();
lut_modified = FALSE;
smc_zone = smc_old_zone;
}
else
{ /* update old zone value */
smc_old_zone = smc_zone;
}
block_min = 0xFFFF;
gl_buf_free_idx = 0;
}
if ( (logical_block >= block_min) && (logical_block < (block_min + SMC_BUFFER_SIZE - 5)))
{ /* we don't have to update the buffer */
smc_calc_logical_block();
gl_buf_idx = logical_block - block_min;
}
else
{ /* we have to update the buffer */
/* Store the look up table block address */
look_up_table_block = lut_block[smc_zone];
/* If LUT have been modified */
if (lut_modified)
{
smc_reassign_block(); /* update the LUT */
}
/* Calculate the address for LUT access */
address = ((Uint32)(look_up_table_block)<<5) + ((Uint32)(logical_block) >> 8);
address += (Uint32)(lut_index[smc_zone])<<2;
/* Calculate the redundant block address value */
smc_calc_logical_block();
i = logical_block & 0xFF;
/* For the current zone, initialize the number of spare block */
spare_block = smc_spare_block_number[smc_zone];
/* Calculate the low and the high block stored in the buffer */
block_min = logical_block;
block_max = ( (logical_block + SMC_BUFFER_SIZE) > 999) ? (1000 - logical_block) : SMC_BUFFER_SIZE;
/* Open the look-up table */
Smc_wait_busy();
if (logical_block & 0x80)
{
Smc_send_command(SMC_READ_B_AREA_CMD); /* 2nd half page */
Smc_send_address( (logical_block << 1) - 256);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -