📄 sd.c
字号:
* SD_SETUP_STATUS check status
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Byte sd_setup_card (void)
{
switch (sd_state)
{
case SD_SETUP_SELECT:
{
if (sd_flag == SD)
{
mmc_send_cmd(MMC_SELECT_CARD, sd_rca, MMC_RESP_R1);
}
else
{
mmc_send_cmd(MMC_SELECT_CARD, MMC_RCA, MMC_RESP_R1);
}
sd_state = SD_SETUP_STATUS;
return (SD_BUSY);
}
case SD_SETUP_STATUS:
{
if (mmc_check_response() == MMC_ERR_RESP)
{
return (SD_ERROR); /* response error */
}
else
{
if (Mmc_card_busy())
{
return (SD_ERROR); /* bus busy */
}
if ((mmc_read_response() & MMC_STBY_STATE_MSK) != MMC_STBY_STATE)
{
return (SD_ERROR); /* bad status */
}
else
{
return (SD_END);
}
}
}
}
}
/*F**************************************************************************
* NAME: sd_check_presence
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
* OK: addressed card present
* KO: addressed card not present
*----------------------------------------------------------------------------
* PURPOSE:
* Return a status on card presence or not
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit sd_check_presence (void)
{
Byte t;
if (sd_flag == SD)
{
mmc_send_cmd(MMC_SEND_STATUS, sd_rca, MMC_RESP_R1);
}
else
{
mmc_send_cmd(MMC_SEND_STATUS, MMC_RCA, MMC_RESP_R1);
}
t = SD_RESPONSE_TIME;
while (mmc_check_response() == MMC_ERR_RESP)
{
if (t == SD_TIME_OUT)
{
return KO;
}
t--;
}
return OK;
}
/*F**************************************************************************
* NAME: sd_read_open
*----------------------------------------------------------------------------
* PARAMS:
* pos: address of the logic sector to read (size 512 bytes)
* global: gl_ptr_mem
*
* return:
* open status: OK: open done
* KO: open not done
*----------------------------------------------------------------------------
* PURPOSE:
* Open memory card in read mode (read block)
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* - pos may not be on the beginning of a block only if SD/MMC card has the
* READ_BL_PARTIAL capability this has interest only if
* block size > 512 bytes
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit sd_read_open (Uint32 pos)
{
gl_ptr_mem = pos << 9; /* gl_ptr_mem = pos * 512 */
if (sd_mem_busy) /* wait end of programming */
{
sd_mem_busy = FALSE;
Mmc_disable_flow_ctrl();
do
{
if (sd_flag == SD)
{
mmc_send_cmd(MMC_SEND_STATUS, sd_rca, MMC_RESP_R1);
}
else
{
mmc_send_cmd(MMC_SEND_STATUS, MMC_RCA, MMC_RESP_R1);
}
gl_mem_tick = SD_RESP_TIME;
while (mmc_check_response() == MMC_ERR_RESP)
{
if (gl_mem_tick == SD_TIME_OUT)
{
return KO;
}
}
}
while ((mmc_read_response() & MMC_TRAN_STATE_MSK) != MMC_TRAN_STATE);
}
Mmc_set_multi_block(); /* set multiblock mode */
Mmc_set_read(); /* dir from card to uc */
Mmc_enable_flow_ctrl(); /* stop clock when FIFO 1&2 full */
Mmc_read_multiple_block_cmd(gl_ptr_mem); /* send read blocks */
gl_mem_tick = SD_RESP_TIME;
while (mmc_check_response() == MMC_ERR_RESP)
{
if (gl_mem_tick == SD_TIME_OUT)
{
return KO;
}
}
if ((mmc_read_response() & MMC_TRAN_STATE_MSK) == MMC_TRAN_STATE)
{
gl_mem_tick = SD_DATA_TIME;
while (!Mmc_read_ready()) /* wait data in FIFO 1 */
{
if (gl_mem_tick == SD_TIME_OUT)
{
return KO;
}
}
return OK;
}
else
{
return KO;
}
}
/*F**************************************************************************
* NAME: sd_read_close
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Memory card read close: release SD or MMC card
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* End of block check is done by testing both FIFOs empty
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit sd_read_close (void)
{
Mmc_stop_tran_cmd();
Mmc_disable_flow_ctrl(); /* re-enable clock for CRC status */
gl_mem_tick = SD_RESP_TIME;
while (mmc_check_response() == MMC_ERR_RESP)
{
if (gl_mem_tick == SD_TIME_OUT)
{
return KO;
}
}
Mmc_reset_data_fifos(); /* discard dummy received data */
return OK;
}
/*F*************************************************************************
* NAME: sd_read_byte
*---------------------------------------------------------------------------
* PARAMS:
* global: gl_ptr_mem
*
* return:
* Data read from memory
* gl_mem_failure set to TRUE if command failure (card removed)
*----------------------------------------------------------------------------
* PURPOSE:
* Card byte read function
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
****************************************************************************/
Byte sd_read_byte (void)
{
gl_mem_tick = SD_DATA_TIME;
while (Mmc_empty_fifos()) /* Wait one byte at least in one FIFO */
{
if (gl_mem_tick == SD_TIME_OUT)
{
gl_mem_failure = TRUE;
return 0xAA;
}
}
gl_ptr_mem++;
return Mmc_rd_byte();
}
/*F**************************************************************************
* NAME: sd_read_sector
*----------------------------------------------------------------------------
* PARAMS:
* nb_sector: number of contiguous sector to read
* global: gl_ptr_mem
*
* return: OK read done
* KO read failure
*----------------------------------------------------------------------------
* PURPOSE:
* This function is an optimized function that writes nb-sector * 512 bytes
* from MMC card to USB controller
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* nb_sector always >= 1, can not be zero
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit sd_read_sector (Uint16 nb_sector)
{
Byte i;
bit begin_ping_pong;
begin_ping_pong = TRUE;
do
{
gl_mem_tick = SD_DATA_TIME;
while (!Mmc_read_ready()) /* wait data in FIFO 1 */
{
if (gl_mem_tick == SD_TIME_OUT)
{
gl_mem_failure = TRUE;
return KO;
}
}
for (i = 8; i != 0; i--) /* read 8x64b = 512b */
{
Usb_write_byte(Mmc_rd_byte()); /* read 16 bytes from FIFO */
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
gl_mem_tick = SD_DATA_TIME;
while (!Mmc_read_ready()) /* wait data in FIFO 1 */
{
if (gl_mem_tick == SD_TIME_OUT)
{
gl_mem_failure = TRUE;
return KO;
}
}
Usb_write_byte(Mmc_rd_byte()); /* read 16 bytes from FIFO */
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
gl_mem_tick = SD_DATA_TIME;
while (!Mmc_read_ready()) /* wait data in FIFO 1 */
{
if (gl_mem_tick == SD_TIME_OUT)
{
gl_mem_failure = TRUE;
return KO;
}
}
Usb_write_byte(Mmc_rd_byte()); /* read 16 bytes from FIFO */
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
gl_mem_tick = SD_DATA_TIME;
while (!Mmc_read_ready()) /* wait data in FIFO 1 */
{
if (gl_mem_tick == SD_TIME_OUT)
{
gl_mem_failure = TRUE;
return KO;
}
}
Usb_write_byte(Mmc_rd_byte()); /* read 16 bytes from FIFO */
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
Usb_write_byte(Mmc_rd_byte());
if (begin_ping_pong)
{
begin_ping_pong = FALSE;
}
else
{
while (!Usb_tx_complete()); /* wait end of transfer */
Usb_clear_TXCMPL(); /* ack transfer */
}
Usb_set_TXRDY(); /* start usb transfer */
}
gl_ptr_mem += 512;
nb_sector--; /* 1 more sector read */
}
while (nb_sector != 0);
while (!Usb_tx_complete()); /* wait end of last transfer */
Usb_clear_TXCMPL(); /* ack transfer */
return OK; /* read done */
}
/*F**************************************************************************
* NAME: sd_write_open
*----------------------------------------------------------------------------
* PARAMS:
* pos: address of the the next write data
* global: gl_ptr_mem
*
* return:
* status: OK: open done
* KO: open not done
*----------------------------------------------------------------------------
* PURPOSE:
* Open memory card in write mode (write block)
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* - pos must always be synchronized on a block boundary address
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit sd_write_open (Uint32 pos)
{
gl_ptr_mem = pos << 9; /* gl_ptr_mem = pos * 512 */
if (sd_mem_busy) /* wait end of programming */
{
sd_mem_busy = FALSE;
Mmc_disable_flow_ctrl();
do
{
Mmc_reset_cmd_fifos();
if (sd_flag == SD)
{
mmc_send_cmd(MMC_SEND_STATUS, sd_rca, MMC_RESP_R1);
}
else
{
mmc_send_cmd(MMC_SEND_STATUS, MMC_RCA, MMC_RESP_R1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -