📄 pu_irom_mmc.c
字号:
/******************************************************************************* pu_irom_mmc.c**** Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.**** This file contains copyrighted material. Use of this file is** restricted by the provisions of a Freescale Software License** Agreement, which has either been electronically accepted by** you or has been expressly executed between the parties.**** Description: Explanation for the usage of this file.**** Revision History:** -----------------*****************************************************************************//*! * @file pu_irom_mmc.c * * @brief source code for the mmc card operation * * @ingroup mmc *//*================================================================================== INCLUDE FILES==================================================================================*/#include "pu_irom_sdhc_ip.h"#include "pu_irom_card.h"#include "pu_irom_mmc.h"#include "protocol.h"#include "flash_lib.h"/*================================================================================================== LOCAL FUNCTION PROTOTYPES==================================================================================================*/static UINT32 mmc_set_rca (void);static UINT32 mmc_get_spec_ver(void);static UINT32 mmc_set_bus_width (UINT32,UINT32);/*================================================================================ Hash Defines And Macros=================================================================================*//*========================================================================= GLOBAL Variables==========================================================================*/UINT32 address_mode; /* Global variable for addressing mode *//*========================================================================== Global FUNCTIONS==========================================================================*//*! * initialize the MMC device. * @bus_width * @return * int - SUCCESS (TRUE) or FAIL */UINT32 mmc_init(UINT32 bus_width){ UINT32 status = FAIL; UINT32 spec_version=0; /* Get CID number of MMC Card */ if(!card_get_cid()) { /* Set RCA of the MMC Card */ if(!mmc_set_rca()) { /* Get Spec version supported by the card */ spec_version = mmc_get_spec_ver(); /*Enable operating frequency */ interface_configure_clock(OPERATING_FREQ); /*Put MMC in Transfer State */ if(!card_set_data_transfer_mode ()) { /* Set status variable as SUCESS */ status = SUCCESS; } } } return status; }/*! * read data from MMC card for specified length from specified offset and copy it a dest pointer. * 1. Issue Commnand CMD16 to set block length as 512 bytes. * 2. Issue Command CMD17 to read single block. * @dest_ptr * @length * @offset * @return UINT32 */UINT32 mmc_data_read (UINT32 *dest_ptr,UINT32 length,UINT32 offset,dump_callback callback){ command_t cmd; int len; UINT32 read_block_status=SUCCESS; U16 csum; /* Assing length of data to be read */ len = length; if(address_mode == SECT_MODE) { offset /= BLK_LEN; } /* Configure interface block and number of blocks */ interface_config_block_info(BLK_LEN,ONE); /* Configure CMD16 to set block length as 512 bytes.*/ card_command_config(&cmd,CMD16,BLK_LEN,READ,RESPONSE_48, DATA_PRESENT_NONE,ENABLE,ENABLE); /* Issue command CMD16 to set block length as 512 bytes */ if(interface_send_cmd_wait_resp(&cmd) == FAIL) { read_block_status = FAIL; } else { while(len>0 && !read_block_status) { /* Comfigure command CMD17 for single block read */ card_command_config(&cmd,CMD17,offset,READ,RESPONSE_48, DATA_PRESENT,ENABLE,ENABLE); if(interface_send_cmd_wait_resp(&cmd) == FAIL) { read_block_status = FAIL; } else { /* Call interface Data read function */ read_block_status = interface_data_read(dest_ptr,BLK_LEN); /*decrement length by block size */ len = len - BLK_LEN; /* Increment offset by Block Size */ address_mode == SECT_MODE ? (offset++) : (offset += BLK_LEN); /* send the dump status and data to host */ if(callback){ if(len > 0){ csum = calculate_checksum((u8 *)dest_ptr, BLK_LEN); callback((u8 *)dest_ptr, FLASH_PARTLY, csum, BLK_LEN); }else{ csum = calculate_checksum((u8 *)dest_ptr, len + BLK_LEN ); callback((u8 *)dest_ptr, FLASH_PARTLY, csum, len + BLK_LEN); } } /* Increment Destination pointer */ dest_ptr = dest_ptr + (BLK_LEN/FOUR); } } } return read_block_status;}/*! * write data from buffer to card for specified length * from specified offset and copy it a dest pointer. * @dest_ptr * @length * @offset * @return UINT32 */UINT32 mmc_data_write (UINT32 *dest_ptr,UINT32 length,UINT32 offset,response_callback callback){ command_t cmd; int len; UINT32 write_block_status=SUCCESS; /* Assing length of data to be read */ len = length; if(address_mode == SECT_MODE) { offset /= BLK_LEN; } /* Configure interface block and number of blocks */ interface_config_block_info(BLK_LEN,ONE); /* Configure CMD16 to set block length as 512 bytes.*/ card_command_config(&cmd,CMD16,BLK_LEN,READ,RESPONSE_48, DATA_PRESENT_NONE,ENABLE,ENABLE); /* Issue command CMD16 to set block length as 512 bytes */ if(interface_send_cmd_wait_resp(&cmd) == FAIL) { write_block_status = FAIL; } else { while(len>0 && !write_block_status) { /* Comfigure command CMD24 for single block write */ card_command_config(&cmd,CMD24,offset,WRITE,RESPONSE_48, DATA_PRESENT,ENABLE,ENABLE); if(interface_send_cmd_wait_resp(&cmd) == FAIL) { write_block_status = FAIL; } else { /* Call interface write read function */ write_block_status = interface_data_write(dest_ptr,BLK_LEN); /*decrement length by block size */ len = len - BLK_LEN; /* Increment offset by Block Size */ address_mode == SECT_MODE ? (offset++) : (offset += BLK_LEN); /* send the prg status to host */ if(callback) callback(FLASH_PARTLY, offset, BLK_LEN); /* Increment Destination pointer */ dest_ptr = dest_ptr + (BLK_LEN/FOUR); } } } return write_block_status;}/*! * erase data from card for specified length * from specified offset * 1. Issue Commnand CMD35 to set first block to erase * 2. Issue Command CMD36 to set end block to erase * 3. Issue Command CMD38 to start erase * * In MMC card, CMD32, CMD33 and CMD34 are reserved. * * @param [in] offset offset in MMC card from which erase starts. * @param [in] size size to erase. * @return * Return result in UINT32 format. */UINT32 mmc_data_erase (UINT32 offset, UINT32 size){ command_t cmd; U8 startEraseBlockCmd = CMD35; U8 endEraseBlockCmd = CMD36; UINT32 startBlock = offset / BLK_LEN; UINT32 endBlock = (offset + size) / BLK_LEN; U32 ret; if (address_mode != SECT_MODE) { /* Byte mode, erase by sectors in both mode */ startBlock *= BLK_LEN; endBlock *= BLK_LEN;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -