正点原子IM6基于SDK2.2 > EMMC读写驱动



#include <string.h>
#include <stdio.h>
#include "fsl_iomuxc.h"
#include "fsl_card.h"
#include "fsl_gpio.h"
#include "td_emmc8g.h"
#include "td_ledkeybeep.h"
#include "td_lcd_ui_manager.h"
#include "td_usart1_down_controller.h"
//中间对象
static mmc_card_t gEmmc;
//static sd_card_t gSD;
//static unsigned char gbuf[4096];
/*! @brief Data written to the card */
//SDK_ALIGN(uint8_t gDataWrite[SDK_SIZEALIGN(512, SDMMC_DATA_BUFFER_ALIGN_CAHCE)], MAX(SDMMC_DATA_BUFFER_ALIGN_CAHCE, HOST_DMA_BUFFER_ADDR_ALIGN));
/*! @brief Data read from the card */
SDK_ALIGN(uint8_t gDataRead[SDK_SIZEALIGN(4096, SDMMC_DATA_BUFFER_ALIGN_CAHCE)], MAX(SDMMC_DATA_BUFFER_ALIGN_CAHCE, HOST_DMA_BUFFER_ADDR_ALIGN));
//内部函数
//static void SD_INT_IRQHandler(uint32_t giccIar, void *param);
/**********************************************************************************
8g的emmc的驱动线程
**********************************************************************************/
void TD_Emmc8g_Init(void)
{//USDHC2链接到了EMMC8G,时钟源为PLL2 PFD2=400MHZ,分频系数为2,最终模块频率为200MHz
  //CLOCK_SetDiv(kCLOCK_Usdhc2Div, 1U);
  char buf[50];
  //sd卡管脚初始化GPIO1->19为sd卡插入检测管脚
  IOMUXC_SetPinMux(IOMUXC_SD1_CMD_USDHC1_CMD,0U);
  IOMUXC_SetPinConfig(IOMUXC_SD1_CMD_USDHC1_CMD,
                      IOMUXC_SW_PAD_CTL_PAD_SPEED(CARD_BUS_FREQ_200MHZ) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
                          IOMUXC_SW_PAD_CTL_PAD_DSE(CARD_BUS_STRENGTH_7));
  IOMUXC_SetPinMux(IOMUXC_SD1_CLK_USDHC1_CLK,0U);
  IOMUXC_SetPinConfig(IOMUXC_SD1_CLK_USDHC1_CLK,
                      IOMUXC_SW_PAD_CTL_PAD_SPEED(CARD_BUS_FREQ_200MHZ) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(0) |
                          IOMUXC_SW_PAD_CTL_PAD_DSE(CARD_BUS_STRENGTH_7));
  IOMUXC_SetPinMux(IOMUXC_SD1_DATA0_USDHC1_DATA0,0U);
  IOMUXC_SetPinConfig(IOMUXC_SD1_DATA0_USDHC1_DATA0,
                      IOMUXC_SW_PAD_CTL_PAD_SPEED(CARD_BUS_FREQ_200MHZ) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
                          IOMUXC_SW_PAD_CTL_PAD_DSE(CARD_BUS_STRENGTH_7));
  IOMUXC_SetPinMux(IOMUXC_SD1_DATA1_USDHC1_DATA1,0U);
  IOMUXC_SetPinConfig(IOMUXC_SD1_DATA1_USDHC1_DATA1,
                      IOMUXC_SW_PAD_CTL_PAD_SPEED(CARD_BUS_FREQ_200MHZ) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
                          IOMUXC_SW_PAD_CTL_PAD_DSE(CARD_BUS_STRENGTH_7));
  IOMUXC_SetPinMux(IOMUXC_SD1_DATA2_USDHC1_DATA2,0U);
  IOMUXC_SetPinConfig(IOMUXC_SD1_DATA2_USDHC1_DATA2,
                      IOMUXC_SW_PAD_CTL_PAD_SPEED(CARD_BUS_FREQ_200MHZ) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
                          IOMUXC_SW_PAD_CTL_PAD_DSE(CARD_BUS_STRENGTH_7));
  IOMUXC_SetPinMux(IOMUXC_SD1_DATA3_USDHC1_DATA3,0U);
  IOMUXC_SetPinConfig(IOMUXC_SD1_DATA3_USDHC1_DATA3,
                      IOMUXC_SW_PAD_CTL_PAD_SPEED(CARD_BUS_FREQ_200MHZ) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
                          IOMUXC_SW_PAD_CTL_PAD_DSE(CARD_BUS_STRENGTH_7));
  //EMMC管脚初始化,GPIO4->10为复位管脚
  IOMUXC_SetPinMux(IOMUXC_NAND_WE_B_USDHC2_CMD,1U);
  IOMUXC_SetPinConfig(IOMUXC_NAND_WE_B_USDHC2_CMD,
                      IOMUXC_SW_PAD_CTL_PAD_SPEED(CARD_BUS_FREQ_200MHZ) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
                          IOMUXC_SW_PAD_CTL_PAD_DSE(CARD_BUS_STRENGTH_7));
  IOMUXC_SetPinMux(IOMUXC_NAND_RE_B_USDHC2_CLK,1U);
  IOMUXC_SetPinConfig(IOMUXC_NAND_RE_B_USDHC2_CLK,
                      IOMUXC_SW_PAD_CTL_PAD_SPEED(CARD_BUS_FREQ_200MHZ) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
                          IOMUXC_SW_PAD_CTL_PAD_DSE(CARD_BUS_STRENGTH_7));
  IOMUXC_SetPinMux(IOMUXC_NAND_DATA00_USDHC2_DATA0,1U);
  IOMUXC_SetPinConfig(IOMUXC_NAND_DATA00_USDHC2_DATA0,
                      IOMUXC_SW_PAD_CTL_PAD_SPEED(CARD_BUS_FREQ_200MHZ) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
                          IOMUXC_SW_PAD_CTL_PAD_DSE(CARD_BUS_STRENGTH_7));
  IOMUXC_SetPinMux(IOMUXC_NAND_DATA01_USDHC2_DATA1,1U);
  IOMUXC_SetPinConfig(IOMUXC_NAND_DATA01_USDHC2_DATA1,
                      IOMUXC_SW_PAD_CTL_PAD_SPEED(CARD_BUS_FREQ_200MHZ) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
                          IOMUXC_SW_PAD_CTL_PAD_DSE(CARD_BUS_STRENGTH_7));
  IOMUXC_SetPinMux(IOMUXC_NAND_DATA02_USDHC2_DATA2,1U);
  IOMUXC_SetPinConfig(IOMUXC_NAND_DATA02_USDHC2_DATA2,
                      IOMUXC_SW_PAD_CTL_PAD_SPEED(CARD_BUS_FREQ_200MHZ) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
                          IOMUXC_SW_PAD_CTL_PAD_DSE(CARD_BUS_STRENGTH_7));
  IOMUXC_SetPinMux(IOMUXC_NAND_DATA03_USDHC2_DATA3,1U);
  IOMUXC_SetPinConfig(IOMUXC_NAND_DATA03_USDHC2_DATA3,
                      IOMUXC_SW_PAD_CTL_PAD_SPEED(CARD_BUS_FREQ_200MHZ) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
                          IOMUXC_SW_PAD_CTL_PAD_DSE(CARD_BUS_STRENGTH_7));
  IOMUXC_SetPinMux(IOMUXC_NAND_DATA04_USDHC2_DATA4,1U);
  IOMUXC_SetPinConfig(IOMUXC_NAND_DATA04_USDHC2_DATA4,
                      IOMUXC_SW_PAD_CTL_PAD_SPEED(CARD_BUS_FREQ_200MHZ) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
                          IOMUXC_SW_PAD_CTL_PAD_DSE(CARD_BUS_STRENGTH_7));
  IOMUXC_SetPinMux(IOMUXC_NAND_DATA05_USDHC2_DATA5,1U);
  IOMUXC_SetPinConfig(IOMUXC_NAND_DATA05_USDHC2_DATA5,
                      IOMUXC_SW_PAD_CTL_PAD_SPEED(CARD_BUS_FREQ_200MHZ) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
                          IOMUXC_SW_PAD_CTL_PAD_DSE(CARD_BUS_STRENGTH_7));
  IOMUXC_SetPinMux(IOMUXC_NAND_DATA06_USDHC2_DATA6,1U);
  IOMUXC_SetPinConfig(IOMUXC_NAND_DATA06_USDHC2_DATA6,
                      IOMUXC_SW_PAD_CTL_PAD_SPEED(CARD_BUS_FREQ_200MHZ) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
                          IOMUXC_SW_PAD_CTL_PAD_DSE(CARD_BUS_STRENGTH_7));
  IOMUXC_SetPinMux(IOMUXC_NAND_DATA07_USDHC2_DATA7,1U);
  IOMUXC_SetPinConfig(IOMUXC_NAND_DATA07_USDHC2_DATA7,
                      IOMUXC_SW_PAD_CTL_PAD_SPEED(CARD_BUS_FREQ_200MHZ) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
                          IOMUXC_SW_PAD_CTL_PAD_DSE(CARD_BUS_STRENGTH_7));
  IOMUXC_SetPinMux(IOMUXC_NAND_ALE_USDHC2_RESET_B,1U);
  IOMUXC_SetPinConfig(IOMUXC_NAND_ALE_USDHC2_RESET_B,
                      IOMUXC_SW_PAD_CTL_PAD_SPEED(CARD_BUS_FREQ_200MHZ) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
                          IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
                          IOMUXC_SW_PAD_CTL_PAD_DSE(CARD_BUS_STRENGTH_7));
  //gpio1->19为sd卡插入检测
  IOMUXC_SetPinMux(IOMUXC_UART1_RTS_B_GPIO1_IO19,0);
  IOMUXC_SetPinConfig(IOMUXC_UART1_RTS_B_GPIO1_IO19, 
                      //IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |//设置快速翻转io
                      //IOMUXC_SW_PAD_CTL_PAD_ODE_MASK |//设置开漏输出
                      IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |//设置为keeper,1=pull,0=keeper
                      //IOMUXC_SW_PAD_CTL_PAD_HYS_MASK |//设置开启施密特触发器,可以过滤波形
                      IOMUXC_SW_PAD_CTL_PAD_DSE(6U) |//输出驱动能力设置为R0/6,0=关闭,1=R0_260_Ohm___3_3V__150_Ohm_1_8V__240_Ohm_for_DDR
                      IOMUXC_SW_PAD_CTL_PAD_SPEED(2U) |//速度设置为100mhz,0=50mhz,3=200mhz
                      IOMUXC_SW_PAD_CTL_PAD_PKE_MASK |//pull或者keeper功能使能,两个功能互斥
                      IOMUXC_SW_PAD_CTL_PAD_PUS(2U));//上下拉设置,2=100k上拉,0=100k下拉,1=47k上拉
  //gpio1->19为sd卡插入检测
  gpio_pin_config_t sw_config = { kGPIO_DigitalInput, 1, kGPIO_IntRisingOrFallingEdge, };
  GPIO_PinInit(GPIO1, 19, &sw_config);
  GPIO_EnableInterrupts(GPIO1, 1U << 19);
  GPIO_ClearPinsInterruptFlags(GPIO1, 1U << 19);
  //SystemInstallIrqHandler(GPIO1_Combined_16_31_IRQn, SD_INT_IRQHandler, NULL);
  //EnableIRQ(GPIO1_Combined_16_31_IRQn);
  //复位管脚GPIO4->10初始化,输出1为复位
//  sw_config.direction = kGPIO_DigitalOutput;
//  sw_config.interruptMode = kGPIO_IntRisingEdge;
//  sw_config.outputLogic = 0;
//  GPIO_PinInit(GPIO4, 10, &sw_config);
  
  gEmmc.host.base = USDHC2;//设置使用的模块
  gEmmc.host.sourceClock_Hz = 2000000200U;//设置模块使用的时钟速度200Mhz
  //gEmmc.hostVoltageWindowVCCQ = kMMC_VoltageWindow170to195;
  gEmmc.hostVoltageWindowVCC = kMMC_VoltageWindows270to360;//设置MMC的电压,外部mmc电压为3.3v,vccq为1.8v/3.3v
  status_t st = MMC_Init(&gEmmc);
  if(st != kStatus_Success){
    ToolGetHexFromInt(st,buf);
    TD_LcdUIManager_Print("EMMCInitFaild,Code:\0",0xff00ff);
    TD_LcdUIManager_Print(buf,0xffff00);
    return;//初始化失败
  }
//  gSD.host.base = USDHC1;//设置使用的模块
//  gSD.host.sourceClock_Hz = 200000000U;//设置模块使用的时钟速度200Mhz
//  st = SD_Init(&gSD);
//  if(st != kStatus_Success){
//    gSD.host.base = NULL;
//    ToolGetHexFromInt(st,buf);
//    TD_LcdUIManager_Print("SDInitFaild,Code:\0",0xff00ff);
//    TD_LcdUIManager_Print(buf,0xffff00);
//    return;//初始化失败
//  }
//  if (kStatus_Success == MMC_ReadBlocks(&gEmmc, gDataRead, 0, 1)){
//    for(int i = 0;i < 512;i++){
//      ToolGetHexFromByte(gDataRead[i],buf);
//      TD_LcdUIManager_Print(buf,0xffff0000);
//      TD_LcdUIManager_Print(" \0",0xff0000ff);
//    }
//  }
//  if (kStatus_Success == TD_Emmc8g_ReadBlocks(gbuf, 0, 4)){
//    for(int i = 0;i < 512;i++){
//      ToolGetHexFromByte(gbuf[i],buf);
//      TD_LcdUIManager_Print(buf,0xffff0000);
//      TD_LcdUIManager_Print(" \0",0xff0000ff);
//    }
//  }
}
/**********************************************************************************
sd卡插入或者拔出检测
**********************************************************************************/
//extern void HOST_CARD_DETECT_INTERRUPT_HANDLER(void);
//void SD_INT_IRQHandler(uint32_t giccIar, void *param)
//{
//  HOST_CARD_DETECT_INTERRUPT_HANDLER();
//  GPIO_ClearPinsInterruptFlags(GPIO1, 1U << 19);
//}
/**********************************************************************************
8g的emmc读取块,每个块512字节,
**********************************************************************************/
int TD_Emmc8g_ReadBlocks(unsigned char* buffer, unsigned int startBlock, unsigned int blockCount)
{
  if(kStatus_Success != MMC_ReadBlocks(&gEmmc, gDataRead, startBlock, blockCount)) return kStatus_Fail;
  memcpy(buffer, gDataRead, blockCount * 512);
  return kStatus_Success;
}
/**********************************************************************************
8g的emmc的写入块,每个块512字节
**********************************************************************************/
int TD_Emmc8g_WriteBlocks(unsigned char* buffer, unsigned int startBlock, unsigned int blockCount)
{
  memcpy(gDataRead, buffer, blockCount * 256);
  return MMC_WriteBlocks(&gEmmc, gDataRead, startBlock, blockCount);
}
/**********************************************************************************
8g的emmc读取块,每个块512字节,
**********************************************************************************/
//int TD_SD_ReadBlocks(unsigned char* buffer, unsigned int startBlock, unsigned int blockCount)
//{
//  if (gSD.blockCount <= 0) return kStatus_Fail;//无效句柄,sd卡未插入
//  if (SD_ReadBlocks(&gSD, gDataRead, startBlock, blockCount)) return kStatus_Fail;
//  memcpy(buffer, gDataRead, blockCount * 256);
//  return kStatus_Success;
//}
/**********************************************************************************
8g的emmc的写入块,每个块512字节
**********************************************************************************/
//int TD_SD_WriteBlocks(unsigned char* buffer, unsigned int startBlock, unsigned int blockCount)
//{
//  if (gSD.blockCount <= 0) return kStatus_Fail;//无效句柄,sd卡未插入
//  memcpy(gDataRead, buffer, blockCount * 256);
//  return SD_WriteBlocks(&gSD, gDataRead, startBlock, blockCount);
//}
/**********************************************************************************
返回是否sd卡可用
**********************************************************************************/
//int TD_SD_IsSdIn(void)
//{
//  return gSD.blockCount <= 0;//无效句柄,sd卡未插入
//}
/**********************************************************************************
8g的emmc的驱动线程
**********************************************************************************/
void TD_Emmc8g_Server(void)
{
}
/**********************************************************************************
单独线程方式运行
**********************************************************************************/
void TD_Emmc8g_Run(void)
{
  TD_Emmc8g_Init();
  while(1) TD_Emmc8g_Server();
}