📄 pu_irom_sd.c
字号:
/******************************************************************************* pu_irom_sd.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_sd.c * * @brief source code for the sd card operation * * @ingroup sd *///#define TY_DBG/*================================================================================= INCLUDE FILES==================================================================================*/#include "pu_irom_sdhc_ip.h"#include "pu_irom_card.h"#include "pu_irom_sd.h"#include "protocol.h"#include "flash_lib.h"#ifdef TY_DBG#include "channel.h"#include "stdio.h"#endif/*================================================================================================== LOCAL FUNCTION PROTOTYPES==================================================================================================*/static UINT32 sd_get_rca (void);static UINT32 sd_get_bit_mode_support(void);static UINT32 sd_set_bus_width (UINT32); /*================================================================================ Hash Defines And Macros=================================================================================*/#define RCA_SHIFT 16#define SD_R1_STATUS_APP_CMD_MSK 0x20#define BIT_MODE_4_SUPPORT 5#define SD_BUS_WIDTH_OFFSET 6#define BIT_4_MODE 4#define SD_STATUS_LEN 64/*========================================================================= GLOBAL Variables==========================================================================*/UINT32 address_mode; /* Global variable for addressing mode *//*========================================================================== Global FUNCTIONS==========================================================================*//*! * initialize the SD memory card. * @bus_width * @return * int - SUCCESS (TRUE) or FAIL */UINT32 sd_init(UINT32 bus_width){ UINT32 status = FAIL; //UINT32 status = -10;#ifdef TY_DBG { // Terry adds for debug, :-) U8 au8StrBuf[100] = { 0 }; sprintf(au8StrBuf, "Ty, Entry: sd_init\n"); atk_channel_send(au8StrBuf, sizeof(au8StrBuf)); }#endif /* Get CID number of SD Memory Card */ if(!card_get_cid ()) { //status = -11;#ifdef TY_DBG { // Terry adds for debug, :-) U8 au8StrBuf[100] = { 0 }; sprintf(au8StrBuf, "Ty, Get cid success!\n"); atk_channel_send(au8StrBuf, sizeof(au8StrBuf)); }#endif /* Set RCA of the SD Card */ if(!sd_get_rca()) { //status = -12;#ifdef TY_DBG { // Terry adds for debug, :-) U8 au8StrBuf[100] = { 0 }; sprintf(au8StrBuf, "Ty, Get rca success!\n"); atk_channel_send(au8StrBuf, sizeof(au8StrBuf)); }#endif /*Put SD Card in Transfer State */ if(!card_set_data_transfer_mode ()) {#ifdef TY_DBG { // Terry adds for debug, :-) U8 au8StrBuf[100] = { 0 }; sprintf(au8StrBuf, "Ty, set transfer mode success!\n"); atk_channel_send(au8StrBuf, sizeof(au8StrBuf)); }#endif /* Set Bus width of the device */ status = SUCCESS; } else {#ifdef TY_DBG { // Terry adds for debug, :-) U8 au8StrBuf[100] = { 0 }; sprintf(au8StrBuf, "Ty, set transfer mode failed!\n"); atk_channel_send(au8StrBuf, sizeof(au8StrBuf)); }#endif } } } /*Enable operating frequency */ interface_configure_clock(OPERATING_FREQ); #ifdef TY_DBG { // Terry adds for debug, :-) U8 au8StrBuf[100] = { 0 }; sprintf(au8StrBuf, "Ty, Exit: sd_init, status: %d\n", status); atk_channel_send(au8StrBuf, sizeof(au8StrBuf)); }#endif return status;}/*! * read data from SD 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 sd_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 SD card for specified length * from specified offset and copy it a dest pointer. * @dest_ptr * @length * @offset * @return UINT32 */UINT32 sd_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 CMD32 to set first block to erase * 2. Issue Command CMD33 to set end block to erase * 3. Issue Command CMD38 to start erase * * @param [in] offset offset in SD card from which erase starts. * @param [in] size size to erase. * @return * Return result in UINT32 format. */UINT32 sd_data_erase (UINT32 offset, UINT32 size){ command_t cmd; U8 startEraseBlockCmd = CMD32; U8 endEraseBlockCmd = CMD33; UINT32 startBlock = offset / BLK_LEN; UINT32 endBlock = (offset + size) / BLK_LEN; U32 ret;#ifdef TY_DBG { // Terry adds for debug, :-) U8 au8StrBuf[100] = { 0 }; sprintf(au8StrBuf, "Ty, Entry: sd_data_erase\n"); atk_channel_send(au8StrBuf, sizeof(au8StrBuf)); }#endif if (address_mode != SECT_MODE) { /* Byte mode, erase by sectors in both mode */ startBlock *= BLK_LEN; endBlock *= BLK_LEN; } /* Configure start erase command to set first block*/ card_command_config(&cmd,startEraseBlockCmd, startBlock, SD_COMMAND, RESPONSE_48, DATA_PRESENT_NONE, ENABLE,ENABLE); /* wait response */ if ((ret = interface_send_cmd_wait_resp(&cmd)) == SUCCESS) {#ifdef TY_DBG { // Terry adds for debug, :-) U8 au8StrBuf[100] = { 0 }; sprintf(au8StrBuf, "Ty: Send CMD32 succeed!\n"); atk_channel_send(au8StrBuf, sizeof(au8StrBuf)); }#endif /* Configure end erase command to set end block*/ card_command_config(&cmd, endEraseBlockCmd, endBlock, SD_COMMAND, RESPONSE_48, DATA_PRESENT_NONE, ENABLE,ENABLE); if ((ret = interface_send_cmd_wait_resp(&cmd)) == SUCCESS) {#ifdef TY_DBG { // Terry adds for debug, :-) U8 au8StrBuf[100] = { 0 }; sprintf(au8StrBuf, "Ty: Send CMD33 succeed!\n"); atk_channel_send(au8StrBuf, sizeof(au8StrBuf)); }#endif /* Comfigure command to start erase*/ card_command_config(&cmd, CMD38, 0, SD_COMMAND, RESPONSE_48, DATA_PRESENT_NONE, ENABLE, ENABLE); if ((ret = interface_send_cmd_wait_resp(&cmd)) == SUCCESS) {#ifdef TY_DBG { // Terry adds for debug, :-) U8 au8StrBuf[100] = { 0 }; sprintf(au8StrBuf, "Ty: Send CMD38 succeed!\n"); atk_channel_send(au8StrBuf, sizeof(au8StrBuf)); }#endif //wait for completion return ret; } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -