[C] 纯文本查看 复制代码
/**
* @file
* @author
* @brief
* @version 1.0
* @date 2024-06-24
* @copyright Copyright (c)
* Provides a serial port service interface that supports multithreaded calls
*/
/***********************************************************************
** INCLUDE **
**********************************************************************/
#include "cal_mmc.h"
#include "stm32h7xx_hal_sd.h"
#include "stm32h7xx_hal_mmc.h"
#include "ahd_tpv706sl1.h"
/***********************************************************************
** CONSTANT ( MACRO AND ENUM ) **
**********************************************************************/
#define MMC1_D0_PORT GPIOC
#define MMC1_D0_PIN CAL_GPIO_PIN_8
#define MMC1_D1_PORT GPIOC
#define MMC1_D1_PIN CAL_GPIO_PIN_9
#define MMC1_D2_PORT GPIOC
#define MMC1_D2_PIN CAL_GPIO_PIN_10
#define MMC1_D3_PORT GPIOC
#define MMC1_D3_PIN CAL_GPIO_PIN_11
#define MMC1_CLK_PORT GPIOC
#define MMC1_CLK_PIN CAL_GPIO_PIN_12
#define MMC1_CMD_PORT GPIOD
#define MMC1_CMD_PIN CAL_GPIO_PIN_2
#define MMC1_RST_PORT GPIOG
#define MMC1_RST_PIN CAL_GPIO_PIN_14
#define cal_sd_mcc1_set() cal_gpio_write(MMC1_RST_PORT,MMC1_RST_PIN,CAL_GPIO_LEVEL_HIGH)
#define cal_sd_mcc1_reset() cal_gpio_write(MMC1_RST_PORT,MMC1_RST_PIN,CAL_GPIO_LEVEL_LOW)
#define ABLOCK_SIZE 512
#define EMMC_WAIT_CNT 0xFFFF
//MMC_HandleTypeDef uSdHandle;
__attribute__((section(".Mmc_Struct_Section"))) MMC_HandleTypeDef uSdHandle;;
__attribute__((section(".Mmc_Tx_Section"))) uint8_t g_mmc_tx_buf[2048];
__attribute__((section(".Mmc_Rx_Section"))) uint8_t g_mmc_rx_buf[2048];
void cal_emmc_init(void)
{
uint16_t i = 0xFFFF;
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SDMMC;
PeriphClkInitStruct.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
uSdHandle.Instance = SDMMC1;
uSdHandle.Init.ClockDiv = 4;
uSdHandle.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
uSdHandle.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
uSdHandle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;//SDMMC_HARDWARE_FLOW_CONTROL_ENABLE;
uSdHandle.Init.BusWide = SDMMC_BUS_WIDE_4B;
__HAL_RCC_SDMMC1_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
/**SDMMC1 GPIO Configuration
PC8 ------> SDMMC1_D0
PC9 ------> SDMMC1_D1
PC10 ------> SDMMC1_D2
PC11 ------> SDMMC1_D3
PC12 ------> SDMMC1_CK
PD2 ------> SDMMC1_CMD
*/
cal_gpio_init(MMC1_D0_PORT,MMC1_D0_PIN,CAL_GPIO_MODE_AF_PP,CAL_GPIO_PULLUP,CAL_GPIO_AF_12);
cal_gpio_init(MMC1_D1_PORT,MMC1_D1_PIN,CAL_GPIO_MODE_AF_PP,CAL_GPIO_NOPULL,CAL_GPIO_AF_12);
cal_gpio_init(MMC1_D2_PORT,MMC1_D2_PIN,CAL_GPIO_MODE_AF_PP,CAL_GPIO_NOPULL,CAL_GPIO_AF_12);
cal_gpio_init(MMC1_D3_PORT,MMC1_D3_PIN,CAL_GPIO_MODE_AF_PP,CAL_GPIO_NOPULL,CAL_GPIO_AF_12);
cal_gpio_init(MMC1_CMD_PORT,MMC1_CMD_PIN,CAL_GPIO_MODE_AF_PP,CAL_GPIO_NOPULL,CAL_GPIO_AF_12);
cal_gpio_init(MMC1_CLK_PORT,MMC1_CLK_PIN,CAL_GPIO_MODE_AF_PP,CAL_GPIO_NOPULL,CAL_GPIO_AF_12);
cal_gpio_init(MMC1_RST_PORT,MMC1_RST_PIN,CAL_GPIO_MODE_OUTPUT_PP,CAL_GPIO_NOPULL,CAL_GPIO_AF_0);
HAL_NVIC_SetPriority(SDMMC1_IRQn,3,1); //配置SDMMC1中断
HAL_NVIC_EnableIRQ(SDMMC1_IRQn); //使能SDMMC1中断
HAL_MMC_Init(&uSdHandle);
HAL_MMC_ConfigWideBusOperation(&uSdHandle,SDMMC_BUS_WIDE_1B);
cal_sd_mcc1_reset();
while(i--);
cal_sd_mcc1_set();
i = 0xFFFF;
while(i--);
}
/**
* @brief Reads block(s) from a specified address in an MMC card, in polling mode.
* @param pData: Pointer to the buffer that will contain the data to transmit
* @param ReadAddr: Address from where data is to be read
* @param NumOfBlocks: Number of MMC blocks to read
* @param Timeout: Timeout for read operation
* @retval MMC status
*/
uint8_t cal_mmc_readblock(uint8_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout)
{
if(NumOfBlocks > sizeof(g_mmc_rx_buf)/ABLOCK_SIZE)
{
return HAL_ERROR;
}
if (HAL_MMC_ReadBlocks(&uSdHandle, g_mmc_rx_buf, ReadAddr, NumOfBlocks, Timeout) == HAL_OK)
{
memcpy(pData,g_mmc_rx_buf,NumOfBlocks*ABLOCK_SIZE);
return HAL_OK;
}
else
{
return HAL_ERROR;
}
}
/**
* @brief Writes block(s) to a specified address in an MMC card, in polling mode.
* @param pData: Pointer to the buffer that will contain the data to transmit
* @param WriteAddr: Address from where data is to be written
* @param NumOfBlocks: Number of MMC blocks to write
* @param Timeout: Timeout for write operation
* @retval MMC status
*/
uint8_t cal_mmc_writeblocks(uint8_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout)
{
if(NumOfBlocks > sizeof(g_mmc_tx_buf)/ABLOCK_SIZE)
{
return HAL_ERROR;
}
memcpy(g_mmc_tx_buf,pData,NumOfBlocks*ABLOCK_SIZE);
if (HAL_MMC_WriteBlocks(&uSdHandle, g_mmc_tx_buf, WriteAddr, NumOfBlocks, Timeout) == HAL_OK)
{
return HAL_OK;
}
else
{
return HAL_ERROR;
}
}
/**
* @brief 在DMA模式下,从MMC卡的指定地址读取数据
* @param pData:指向将包含要传输的数据的缓冲区的指针
* @param ReadAddr:要读取数据的地址
* @param NumOfBlocks:要读取的MMC块数量
* @retval eMMC状态
*/
uint8_t cal_mmc_readblocks_dma(uint8_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks)
{
uint32_t loop = EMMC_WAIT_CNT;
if(NumOfBlocks > sizeof(g_mmc_rx_buf)/ABLOCK_SIZE)
{
return HAL_ERROR;
}
HAL_MMC_ReadBlocks_DMA(&uSdHandle, g_mmc_rx_buf, ReadAddr, NumOfBlocks);
while(loop > 0)
{
loop--;
if(HAL_MMC_GetCardState(&uSdHandle) == HAL_MMC_CARD_TRANSFER)
{
memcpy(pData,g_mmc_rx_buf,NumOfBlocks*ABLOCK_SIZE);
return HAL_OK;
}
}
return HAL_ERROR;
}
/**
* @brief 在DMA模式下,向MMC卡的指定地址写入数据;
* @param pData:指向将包含要传输的数据的缓冲区的指针
* @param WriteAddr:要写入数据的地址
* @param NumOfBlocks:要写的MMC块的数量
* @retval MMC状态4
*/
uint8_t cal_mmc_writeblocks_dma(uint8_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks)
{
uint32_t loop = EMMC_WAIT_CNT;
if(NumOfBlocks > sizeof(g_mmc_tx_buf)/ABLOCK_SIZE)
{
return HAL_ERROR;
}
memcpy(g_mmc_tx_buf,pData,NumOfBlocks*ABLOCK_SIZE);
/* Write block(s) in DMA transfer mode */
HAL_MMC_WriteBlocks_DMA(&uSdHandle, g_mmc_tx_buf, WriteAddr, NumOfBlocks);
while(loop > 0)
{
loop--;
if(HAL_MMC_GetCardState(&uSdHandle) == HAL_MMC_CARD_TRANSFER)
{
return HAL_OK;
}
}
return HAL_ERROR;
}
/**
* @brief Erases the specified memory area of the given MMC card.
* @param StartAddr: Start byte address
* @param EndAddr: End byte address
* @retval MMC status
*/
uint8_t cal_mmc_erase(uint32_t StartAddr, uint32_t EndAddr)
{
uint32_t loop = EMMC_WAIT_CNT;
HAL_MMC_Erase(&uSdHandle, StartAddr, EndAddr);
while(loop > 0)
{
loop--;
if(HAL_MMC_GetCardState(&uSdHandle) == HAL_MMC_CARD_TRANSFER)
{
return HAL_OK;
}
}
return HAL_ERROR;
}
void cal_emmc_rw_test(void)
{
uint16_t i = 0;
static uint8_t first = 1;
HAL_StatusTypeDef FlashStatus=HAL_OK;
// HAL_MMC_CardInfoTypeDef test;
// //ceshi
// HAL_MMC_CardCIDTypeDef PCID;
// HAL_MMC_CardCSDTypeDef PCSD;
// HAL_MMC_GetCardCID(&uSdHandle,&PCID);
// HAL_MMC_GetCardCSD(&uSdHandle,&PCSD);
// HAL_MMC_GetCardInfo(&uSdHandle, &test);
FlashStatus = cal_mmc_erase(0x08,0x10);
if(first)
{
for(i = 0;i < sizeof(g_mmc_tx_buf);i++)
{
g_mmc_tx_buf[i] = i;
}
first = 0;
}
FlashStatus = cal_mmc_writeblocks_dma(g_mmc_tx_buf,1,1);
//// //cal_mmc_writeblocks(g_mmc_tx_buf,1,1,0xFFFFFFFF);
//// memset(g_mmc_tx_buf,0,sizeof(g_mmc_tx_buf));
FlashStatus = cal_mmc_readblocks_dma(g_mmc_rx_buf,1,1);
//// cal_mmc_readblock(g_mmc_rx_buf,1,1,0xFFFFFFFF);
memset(g_mmc_rx_buf,0,sizeof(g_mmc_rx_buf));
}
void SDMMC1_IRQHandler(void)
{
HAL_MMC_IRQHandler(&uSdHandle);
}