📄 mmc.c
字号:
Mmc_set_clock(MMC_CLK_TRANS); /* set MMC clock to max */
mmc_state = MMC_FUNCT_START;
return (MMC_END);
}
}
}
}
/*F**************************************************************************
* NAME: mmc_setup_card
*----------------------------------------------------------------------------
* PARAMS:
* card_id: 0: RCA 1
* 1: RCA 2
*
* return:
* MMC_OK: state result OK
* MMC_ERROR: state result KO
* MMC_END: end of setup execution
*----------------------------------------------------------------------------
* PURPOSE:
* Select the corresponding card
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* - This function must be called at least 2 times for completion
* - Each call must be delayed enough to leave time for command
* transmission and response reception
* - Contrary to what is written in MMC spec, the request CSD can
* not be done in transfer state
*
* STATES: MMC_SETUP_SELECT select card
* MMC_SETUP_STATUS check status
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Byte mmc_setup_card (bit card_id)
{
switch (mmc_state)
{
case MMC_SETUP_SELECT:
{
if (card_id == MMC_CARD1)
{
mmc_send_cmd(MMC_SELECT_CARD, MMC_RCA_1, MMC_RESP_R1);
}
else
{
mmc_send_cmd(MMC_SELECT_CARD, MMC_RCA_2, MMC_RESP_R1);
}
mmc_state = MMC_SETUP_STATUS;
return (MMC_OK);
}
case MMC_SETUP_STATUS:
{
if (mmc_check_response() == MMC_ERR_RESP)
{
mmc_state = MMC_FUNCT_START;
return (MMC_ERROR); /* response error */
}
else
{
if (Mmc_card_busy())
{
mmc_state = MMC_FUNCT_START;
return (MMC_ERROR); /* bus busy */
}
if ((mmc_read_response() & MMC_STBY_STATE_MSK) != MMC_STBY_STATE)
{
mmc_state = MMC_FUNCT_START;
return (MMC_ERROR); /* bad status */
}
else
{
mmc_state = MMC_FUNCT_START;
return (MMC_END);
}
}
}
}
}
#if (0) /* not used
/*F**************************************************************************
* NAME: mmc_check_stack
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
* OK: card present
* KO: card not present
*----------------------------------------------------------------------------
* PURPOSE:
* Return a status on card presence or not
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit mmc_check_stack (void)
{
Byte t;
Mmc_enable();
mmc_send_cmd(MMC_SEND_OP_COND, MMC_OCR_INIT, MMC_RESP_R3);
t = MMC_RESPONSE_TIME;
while (mmc_check_response() == MMC_ERR_RESP)
{
if (t == MMC_TIME_OUT)
{
Mmc_disable();
return KO;
}
t--;
}
return OK;
}
#endif
/*F**************************************************************************
* NAME: mmc_check_presence
*----------------------------------------------------------------------------
* PARAMS:
* card_id: 0: RCA 1
* 1: RCA 2
*
* return:
* OK: addressed card present
* KO: addressed card not present
*----------------------------------------------------------------------------
* PURPOSE:
* Return a status on card presence or not
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit mmc_check_presence (bit card_id)
{
Byte t;
if (mmc_mem_busy)
{
mmc_mem_busy = FALSE;
while (Mmc_card_busy()); /* wait end of programming */
}
if (card_id == MMC_CARD1)
{
mmc_send_cmd(MMC_SEND_STATUS, MMC_RCA_1, MMC_RESP_R1);
}
else
{
mmc_send_cmd(MMC_SEND_STATUS, MMC_RCA_2, MMC_RESP_R1);
}
t = MMC_RESPONSE_TIME;
while (mmc_check_response() == MMC_ERR_RESP)
{
if (t == MMC_TIME_OUT)
{
return KO;
}
t--;
}
return OK;
}
/*F**************************************************************************
* NAME: mmc_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 MMC card has the
* READ_BL_PARTIAL capability this has interest only if
* block size > 512 bytes
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit mmc_read_open (Uint32 pos)
{
gl_ptr_mem = pos << 9; /* gl_ptr_mem = pos * 512 */
if (mmc_mem_busy)
{
mmc_mem_busy = FALSE;
while (Mmc_card_busy()); /* wait end of programming */
}
Mmc_enable_flow_ctrl(); /* stop clock when FIFO 1&2 full*/
Mmc_set_read(); /* dir from card to uc */
Mmc_read_block_cmd(gl_ptr_mem); /* send read block */
// while (!Mmc_command_sent()); /* wait end of transmission */
gl_mem_tick = MMC_RESP_TIME;
while (mmc_check_response() == MMC_ERR_RESP)
{
if (gl_mem_tick == MMC_TIME_OUT)
{
return KO;
}
}
if ((mmc_read_response() & MMC_TRAN_STATE_MSK) == MMC_TRAN_STATE)
{
gl_mem_tick = MMC_DATA_TIME;
while (!Mmc_read_ready()) /* wait data in FIFO 1 */
{
if (gl_mem_tick == MMC_TIME_OUT)
{
return KO;
}
}
return OK;
}
else
{
return KO;
}
}
/*F**************************************************************************
* NAME: mmc_read_close
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Memory card read close: release MMC card
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* End of block check is done by testing both FIFOs empty
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void mmc_read_close (void)
{
while (!Mmc_end_of_block_read()) /* check if end of block */
{
ACC = Mmc_rd_byte(); /* dummy read to end of block */
}
// Mmc_disable();
}
/*F*************************************************************************
* NAME: mmc_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:
* The end of block read is detected when both FIFOs are empty
*----------------------------------------------------------------------------
* REQUIREMENTS:
****************************************************************************/
Byte mmc_read_byte (void)
{
if (Mmc_end_of_block_read()) /* check if end of block */
{
Mmc_read_block_cmd(gl_ptr_mem); /* read next block */
gl_mem_tick = MMC_RESP_TIME;
while (mmc_check_response() == MMC_ERR_RESP)
{
if (gl_mem_tick == MMC_TIME_OUT)
{
gl_mem_failure = TRUE;
return 0xAA;
}
}
if ((mmc_read_response() & MMC_TRAN_STATE_MSK) == MMC_TRAN_STATE)
{
gl_mem_tick = MMC_DATA_TIME;
while (!Mmc_read_ready()) /* wait data in FIFO 1 */
{
if (gl_mem_tick == MMC_TIME_OUT)
{
gl_mem_failure = TRUE;
return 0xAA;
}
}
}
else
{
gl_mem_failure = TRUE;
return 0xAA;
}
}
gl_ptr_mem++;
return Mmc_rd_byte();
}
/*F**************************************************************************
* NAME: mmc_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 mmc_read_sector (Uint16 nb_sector)
{
Byte i;
bit begin_ping_pong;
begin_ping_pong = TRUE;
do
{
if (Mmc_end_of_block_read()) /* check if end of block */
{
Mmc_read_block_cmd(gl_ptr_mem); /* read next block */
// while (!Mmc_command_sent()); /* wait end of transmission */
gl_mem_tick = MMC_RESP_TIME;
while (mmc_check_response() == MMC_ERR_RESP)
{
if (gl_mem_tick == MMC_TIME_OUT)
{
gl_mem_failure = TRUE;
return KO;
}
}
if ((mmc_read_response() & MMC_TRAN_STATE_MSK) == MMC_TRAN_STATE)
{
gl_mem_tick = MMC_DATA_TIME;
while (!Mmc_read_ready()) /* wait data in FIFO 1 */
{
if (gl_mem_tick == MMC_TIME_OUT)
{
gl_mem_failure = TRUE;
return KO;
}
}
}
else
{
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 = MMC_DATA_TIME;
while (!Mmc_read_ready()) /* wait data in FIFO 1 */
{
if (gl_mem_tick == MMC_TIME_OUT)
{
gl_mem_failure = TRUE;
return KO;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -