mcu_hi3321_watch/tjd/driver/nandflash/flash_port_sdio.c
2025-05-26 20:15:20 +08:00

918 lines
34 KiB
C

/*----------------------------------------------------------------------------
* Copyright (c) Fenda Technologies Co., Ltd. 2020. All rights reserved.
*
* Description: flash_port_mspi.c
*
* Author: saimen
*
* Create: 2020-09-25
*--------------------------------------------------------------------------*/
//lib
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
//os
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
//sdk
//#include "apollo4b.h"//uninclude am_hal_lib
#include "am_mcu_apollo.h"
#include "am_util.h"
//drv
#include "flash_port_sdio.h"
//user
#include "sys_config.h"
#define ENABLE_STATIC_PRINT false
extern uint32_t flash_port_print(const char *pcFmt, ...);
#define static_print_remind(...) flash_port_print(__VA_ARGS__)
#if ENABLE_STATIC_PRINT
#define static_print_info(...) flash_api_print(__VA_ARGS__)
#else
#define static_print_info(...)
#endif
#define EMMC_AUTO_TIMING_SCAN 0
#define EMMC_DDR_MODE 0
#define EMMC_CLK_SPEED (96000000)
#define STA_NOINIT 0x01/* Drive not initialized */
#define STA_NODISK 0x02/* No medium in the drive */
#define STA_PROTECT 0x04/* Write protected */
/* from am_hal_card_host.c
static am_hal_card_host_ops_t g_sdhc_host_ops = {
.init = am_hal_sdhc_host_init,
.deinit = am_hal_sdhc_host_deinit,
.pwr_ctrl = am_hal_card_host_power_control,
.execute_cmd = am_hal_sdhc_host_execute_cmd,
.set_bus_voltage = am_hal_sdhc_set_bus_voltage,
.set_bus_width = am_hal_sdhc_set_bus_width,
.set_bus_clock = am_hal_sdhc_set_bus_clock,
.set_uhs_mode = am_hal_sdhc_set_uhs_mode,
.set_txrx_delay = am_hal_sdhc_set_txrx_delay,
.get_cd = am_hal_sdhc_get_cd,
.card_busy = am_hal_sdhc_card_busy,
};
static am_hal_card_host_t g_sdhc_card_host = {
.pHandle = NULL,
.bInited = false,
.eBusVoltage = AM_HAL_HOST_BUS_VOLTAGE_1_8,
.ui32Module = 0x0,
.ops = &g_sdhc_host_ops,
};
*/
static SemaphoreHandle_t flash_mutex_handle = NULL;
static volatile uint32_t Stat = STA_NOINIT; /* Disk status */
static volatile bool bAsyncWriteIsDone = false;
static volatile bool bAsyncReadIsDone = false;
am_hal_card_t eMMCard;
am_hal_card_host_t *pSdhcCardHost = NULL;
//*****************************************************************************
//
// SDIO_DAT0 pin: eMMC NAND Flash I/F using SDIO data 0.
//
//*****************************************************************************
#define AM_BSP_GPIO_SDIO_DAT0 84
#define AM_BSP_GPIO_SDIO_DAT1 85
#define AM_BSP_GPIO_SDIO_DAT2 86
#define AM_BSP_GPIO_SDIO_DAT3 87
#define AM_BSP_GPIO_SDIO_DAT4 79
#define AM_BSP_GPIO_SDIO_DAT5 80
#define AM_BSP_GPIO_SDIO_DAT6 81
#define AM_BSP_GPIO_SDIO_DAT7 82
#define AM_BSP_GPIO_SDIO_CMD 83
#define AM_BSP_GPIO_SDIO_CLK 88
#define AM_BSP_GPIO_SDIO_RST 60
#define AM_BSP_GPIO_SDIO_POWER_33V 58
#if HARD_PCB_VERSION == PCB_EVT1
#define AM_BSP_GPIO_SDIO_POWER_18V 10
#endif
am_hal_gpio_pincfg_t g_AM_BSP_GPIO_SDIO_DAT0 =
{
.GP.cfg_b.uFuncSel = AM_HAL_PIN_84_SDIF_DAT0,
.GP.cfg_b.eGPInput = AM_HAL_GPIO_PIN_INPUT_NONE,
.GP.cfg_b.eGPRdZero = AM_HAL_GPIO_PIN_RDZERO_READPIN,
.GP.cfg_b.eIntDir = AM_HAL_GPIO_PIN_INTDIR_NONE,
.GP.cfg_b.eGPOutCfg = AM_HAL_GPIO_PIN_OUTCFG_DISABLE,
.GP.cfg_b.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_1P0X,
.GP.cfg_b.uSlewRate = 0,
.GP.cfg_b.ePullup = AM_HAL_GPIO_PIN_PULLUP_12K,
.GP.cfg_b.uNCE = 0,
.GP.cfg_b.eCEpol = AM_HAL_GPIO_PIN_CEPOL_ACTIVELOW,
.GP.cfg_b.uRsvd_0 = 0,
.GP.cfg_b.ePowerSw = AM_HAL_GPIO_PIN_POWERSW_NONE,
.GP.cfg_b.eForceInputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.eForceOutputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.uRsvd_1 = 0,
};
//*****************************************************************************
//
// SDIO_DAT1 (85) - eMMC NAND Flash I/F using SDIO data 1.
//
//*****************************************************************************
am_hal_gpio_pincfg_t g_AM_BSP_GPIO_SDIO_DAT1 =
{
.GP.cfg_b.uFuncSel = AM_HAL_PIN_85_SDIF_DAT1,
.GP.cfg_b.eGPInput = AM_HAL_GPIO_PIN_INPUT_NONE,
.GP.cfg_b.eGPRdZero = AM_HAL_GPIO_PIN_RDZERO_READPIN,
.GP.cfg_b.eIntDir = AM_HAL_GPIO_PIN_INTDIR_NONE,
.GP.cfg_b.eGPOutCfg = AM_HAL_GPIO_PIN_OUTCFG_DISABLE,
.GP.cfg_b.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_1P0X,
.GP.cfg_b.uSlewRate = 0,
.GP.cfg_b.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE,
.GP.cfg_b.uNCE = 0,
.GP.cfg_b.eCEpol = AM_HAL_GPIO_PIN_CEPOL_ACTIVELOW,
.GP.cfg_b.uRsvd_0 = 0,
.GP.cfg_b.ePowerSw = AM_HAL_GPIO_PIN_POWERSW_NONE,
.GP.cfg_b.eForceInputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.eForceOutputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.uRsvd_1 = 0,
};
//*****************************************************************************
//
// SDIO_DAT2 (86) - eMMC NAND Flash I/F using SDIO data 2.
//
//*****************************************************************************
am_hal_gpio_pincfg_t g_AM_BSP_GPIO_SDIO_DAT2 =
{
.GP.cfg_b.uFuncSel = AM_HAL_PIN_86_SDIF_DAT2,
.GP.cfg_b.eGPInput = AM_HAL_GPIO_PIN_INPUT_NONE,
.GP.cfg_b.eGPRdZero = AM_HAL_GPIO_PIN_RDZERO_READPIN,
.GP.cfg_b.eIntDir = AM_HAL_GPIO_PIN_INTDIR_NONE,
.GP.cfg_b.eGPOutCfg = AM_HAL_GPIO_PIN_OUTCFG_DISABLE,
.GP.cfg_b.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_1P0X,
.GP.cfg_b.uSlewRate = 0,
.GP.cfg_b.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE,
.GP.cfg_b.uNCE = 0,
.GP.cfg_b.eCEpol = AM_HAL_GPIO_PIN_CEPOL_ACTIVELOW,
.GP.cfg_b.uRsvd_0 = 0,
.GP.cfg_b.ePowerSw = AM_HAL_GPIO_PIN_POWERSW_NONE,
.GP.cfg_b.eForceInputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.eForceOutputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.uRsvd_1 = 0,
};
//*****************************************************************************
//
// SDIO_DAT3 (87) - eMMC NAND Flash I/F using SDIO data 3.
//
//*****************************************************************************
am_hal_gpio_pincfg_t g_AM_BSP_GPIO_SDIO_DAT3 =
{
.GP.cfg_b.uFuncSel = AM_HAL_PIN_87_SDIF_DAT3,
.GP.cfg_b.eGPInput = AM_HAL_GPIO_PIN_INPUT_NONE,
.GP.cfg_b.eGPRdZero = AM_HAL_GPIO_PIN_RDZERO_READPIN,
.GP.cfg_b.eIntDir = AM_HAL_GPIO_PIN_INTDIR_NONE,
.GP.cfg_b.eGPOutCfg = AM_HAL_GPIO_PIN_OUTCFG_DISABLE,
.GP.cfg_b.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_1P0X,
.GP.cfg_b.uSlewRate = 0,
.GP.cfg_b.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE,
.GP.cfg_b.uNCE = 0,
.GP.cfg_b.eCEpol = AM_HAL_GPIO_PIN_CEPOL_ACTIVELOW,
.GP.cfg_b.uRsvd_0 = 0,
.GP.cfg_b.ePowerSw = AM_HAL_GPIO_PIN_POWERSW_NONE,
.GP.cfg_b.eForceInputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.eForceOutputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.uRsvd_1 = 0,
};
//*****************************************************************************
//
// SDIO_DAT4 (79) - eMMC NAND Flash I/F using SDIO data 4.
//
//*****************************************************************************
am_hal_gpio_pincfg_t g_AM_BSP_GPIO_SDIO_DAT4 =
{
.GP.cfg_b.uFuncSel = AM_HAL_PIN_79_SDIF_DAT4,
.GP.cfg_b.eGPInput = AM_HAL_GPIO_PIN_INPUT_NONE,
.GP.cfg_b.eGPRdZero = AM_HAL_GPIO_PIN_RDZERO_READPIN,
.GP.cfg_b.eIntDir = AM_HAL_GPIO_PIN_INTDIR_NONE,
.GP.cfg_b.eGPOutCfg = AM_HAL_GPIO_PIN_OUTCFG_DISABLE,
.GP.cfg_b.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_1P0X,
.GP.cfg_b.uSlewRate = 0,
.GP.cfg_b.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE,
.GP.cfg_b.uNCE = 0,
.GP.cfg_b.eCEpol = AM_HAL_GPIO_PIN_CEPOL_ACTIVELOW,
.GP.cfg_b.uRsvd_0 = 0,
.GP.cfg_b.ePowerSw = AM_HAL_GPIO_PIN_POWERSW_NONE,
.GP.cfg_b.eForceInputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.eForceOutputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.uRsvd_1 = 0,
};
//*****************************************************************************
//
// SDIO_DAT5 (80) - eMMC NAND Flash I/F using SDIO data 5.
//
//*****************************************************************************
am_hal_gpio_pincfg_t g_AM_BSP_GPIO_SDIO_DAT5 =
{
.GP.cfg_b.uFuncSel = AM_HAL_PIN_80_SDIF_DAT5,
.GP.cfg_b.eGPInput = AM_HAL_GPIO_PIN_INPUT_NONE,
.GP.cfg_b.eGPRdZero = AM_HAL_GPIO_PIN_RDZERO_READPIN,
.GP.cfg_b.eIntDir = AM_HAL_GPIO_PIN_INTDIR_NONE,
.GP.cfg_b.eGPOutCfg = AM_HAL_GPIO_PIN_OUTCFG_DISABLE,
.GP.cfg_b.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_1P0X,
.GP.cfg_b.uSlewRate = 0,
.GP.cfg_b.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE,
.GP.cfg_b.uNCE = 0,
.GP.cfg_b.eCEpol = AM_HAL_GPIO_PIN_CEPOL_ACTIVELOW,
.GP.cfg_b.uRsvd_0 = 0,
.GP.cfg_b.ePowerSw = AM_HAL_GPIO_PIN_POWERSW_NONE,
.GP.cfg_b.eForceInputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.eForceOutputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.uRsvd_1 = 0,
};
//*****************************************************************************
//
// SDIO_DAT6 (81) - eMMC NAND Flash I/F using SDIO data 6.
//
//*****************************************************************************
am_hal_gpio_pincfg_t g_AM_BSP_GPIO_SDIO_DAT6 =
{
.GP.cfg_b.uFuncSel = AM_HAL_PIN_81_SDIF_DAT6,
.GP.cfg_b.eGPInput = AM_HAL_GPIO_PIN_INPUT_NONE,
.GP.cfg_b.eGPRdZero = AM_HAL_GPIO_PIN_RDZERO_READPIN,
.GP.cfg_b.eIntDir = AM_HAL_GPIO_PIN_INTDIR_NONE,
.GP.cfg_b.eGPOutCfg = AM_HAL_GPIO_PIN_OUTCFG_DISABLE,
.GP.cfg_b.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_1P0X,
.GP.cfg_b.uSlewRate = 0,
.GP.cfg_b.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE,
.GP.cfg_b.uNCE = 0,
.GP.cfg_b.eCEpol = AM_HAL_GPIO_PIN_CEPOL_ACTIVELOW,
.GP.cfg_b.uRsvd_0 = 0,
.GP.cfg_b.ePowerSw = AM_HAL_GPIO_PIN_POWERSW_NONE,
.GP.cfg_b.eForceInputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.eForceOutputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.uRsvd_1 = 0,
};
//*****************************************************************************
//
// SDIO_DAT7 (82) - eMMC NAND Flash I/F using SDIO data 7.
//
//*****************************************************************************
am_hal_gpio_pincfg_t g_AM_BSP_GPIO_SDIO_DAT7 =
{
.GP.cfg_b.uFuncSel = AM_HAL_PIN_82_SDIF_DAT7,
.GP.cfg_b.eGPInput = AM_HAL_GPIO_PIN_INPUT_NONE,
.GP.cfg_b.eGPRdZero = AM_HAL_GPIO_PIN_RDZERO_READPIN,
.GP.cfg_b.eIntDir = AM_HAL_GPIO_PIN_INTDIR_NONE,
.GP.cfg_b.eGPOutCfg = AM_HAL_GPIO_PIN_OUTCFG_DISABLE,
.GP.cfg_b.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_1P0X,
.GP.cfg_b.uSlewRate = 0,
.GP.cfg_b.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE,
.GP.cfg_b.uNCE = 0,
.GP.cfg_b.eCEpol = AM_HAL_GPIO_PIN_CEPOL_ACTIVELOW,
.GP.cfg_b.uRsvd_0 = 0,
.GP.cfg_b.ePowerSw = AM_HAL_GPIO_PIN_POWERSW_NONE,
.GP.cfg_b.eForceInputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.eForceOutputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.uRsvd_1 = 0,
};
//*****************************************************************************
//
// SDIO_CMD (83) - eMMC NAND Flash I/F using SDIO CMD
//
//*****************************************************************************
am_hal_gpio_pincfg_t g_AM_BSP_GPIO_SDIO_CMD =
{
.GP.cfg_b.uFuncSel = AM_HAL_PIN_83_SDIF_CMD,
.GP.cfg_b.eGPInput = AM_HAL_GPIO_PIN_INPUT_NONE,
.GP.cfg_b.eGPRdZero = AM_HAL_GPIO_PIN_RDZERO_READPIN,
.GP.cfg_b.eIntDir = AM_HAL_GPIO_PIN_INTDIR_NONE,
.GP.cfg_b.eGPOutCfg = AM_HAL_GPIO_PIN_OUTCFG_DISABLE,
.GP.cfg_b.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_1P0X,
.GP.cfg_b.uSlewRate = 0,
.GP.cfg_b.ePullup = AM_HAL_GPIO_PIN_PULLUP_12K,
.GP.cfg_b.uNCE = 0,
.GP.cfg_b.eCEpol = AM_HAL_GPIO_PIN_CEPOL_ACTIVELOW,
.GP.cfg_b.uRsvd_0 = 0,
.GP.cfg_b.ePowerSw = AM_HAL_GPIO_PIN_POWERSW_NONE,
.GP.cfg_b.eForceInputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.eForceOutputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.uRsvd_1 = 0,
};
//*****************************************************************************
//
// SDIO_CLK (88) - eMMC NAND Flash I/F using SDIO clock.
//
//*****************************************************************************
am_hal_gpio_pincfg_t g_AM_BSP_GPIO_SDIO_CLK =
{
.GP.cfg_b.uFuncSel = AM_HAL_PIN_88_SDIF_CLKOUT,
.GP.cfg_b.eGPInput = AM_HAL_GPIO_PIN_INPUT_NONE,
.GP.cfg_b.eGPRdZero = AM_HAL_GPIO_PIN_RDZERO_READPIN,
.GP.cfg_b.eIntDir = AM_HAL_GPIO_PIN_INTDIR_NONE,
.GP.cfg_b.eGPOutCfg = AM_HAL_GPIO_PIN_OUTCFG_DISABLE,
.GP.cfg_b.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_1P0X,
.GP.cfg_b.uSlewRate = 0,
.GP.cfg_b.ePullup = AM_HAL_GPIO_PIN_PULLUP_12K,
.GP.cfg_b.uNCE = 0,
.GP.cfg_b.eCEpol = AM_HAL_GPIO_PIN_CEPOL_ACTIVELOW,
.GP.cfg_b.uRsvd_0 = 0,
.GP.cfg_b.ePowerSw = AM_HAL_GPIO_PIN_POWERSW_NONE,
.GP.cfg_b.eForceInputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.eForceOutputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.uRsvd_1 = 0,
};
//*****************************************************************************
//
// SDIO_RST (96) - eMMC NAND Flash I/F using GPIO for Reset.
//
//*****************************************************************************
am_hal_gpio_pincfg_t g_AM_BSP_GPIO_SDIO_RST =
{
.GP.cfg_b.uFuncSel = AM_HAL_PIN_96_GPIO,
.GP.cfg_b.eGPInput = AM_HAL_GPIO_PIN_INPUT_NONE,
.GP.cfg_b.eGPRdZero = AM_HAL_GPIO_PIN_RDZERO_READPIN,
.GP.cfg_b.eIntDir = AM_HAL_GPIO_PIN_INTDIR_NONE,
.GP.cfg_b.eGPOutCfg = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL,
.GP.cfg_b.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_0P1X,
.GP.cfg_b.uSlewRate = 0,
.GP.cfg_b.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE,
.GP.cfg_b.uNCE = 0,
.GP.cfg_b.eCEpol = AM_HAL_GPIO_PIN_CEPOL_ACTIVELOW,
.GP.cfg_b.uRsvd_0 = 0,
.GP.cfg_b.ePowerSw = AM_HAL_GPIO_PIN_POWERSW_NONE,
.GP.cfg_b.eForceInputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.eForceOutputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.uRsvd_1 = 0,
};
am_hal_gpio_pincfg_t g_AM_BSP_GPIO_SDIO_POWER_33V =
{
.GP.cfg_b.uFuncSel = AM_HAL_PIN_58_GPIO,
.GP.cfg_b.eGPInput = AM_HAL_GPIO_PIN_INPUT_NONE,
.GP.cfg_b.eGPRdZero = AM_HAL_GPIO_PIN_RDZERO_READPIN,
.GP.cfg_b.eIntDir = AM_HAL_GPIO_PIN_INTDIR_NONE,
.GP.cfg_b.eGPOutCfg = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL,
.GP.cfg_b.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_0P1X,
.GP.cfg_b.uSlewRate = 0,
.GP.cfg_b.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE,
.GP.cfg_b.uNCE = 0,
.GP.cfg_b.eCEpol = AM_HAL_GPIO_PIN_CEPOL_ACTIVELOW,
.GP.cfg_b.uRsvd_0 = 0,
.GP.cfg_b.ePowerSw = AM_HAL_GPIO_PIN_POWERSW_NONE,
.GP.cfg_b.eForceInputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.eForceOutputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.uRsvd_1 = 0,
};
am_hal_gpio_pincfg_t g_AM_BSP_GPIO_SDIO_POWER_18V =
{
.GP.cfg_b.uFuncSel = AM_HAL_PIN_10_GPIO,
.GP.cfg_b.eGPInput = AM_HAL_GPIO_PIN_INPUT_NONE,
.GP.cfg_b.eGPRdZero = AM_HAL_GPIO_PIN_RDZERO_READPIN,
.GP.cfg_b.eIntDir = AM_HAL_GPIO_PIN_INTDIR_NONE,
.GP.cfg_b.eGPOutCfg = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL,
.GP.cfg_b.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_0P1X,
.GP.cfg_b.uSlewRate = 0,
.GP.cfg_b.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE,
.GP.cfg_b.uNCE = 0,
.GP.cfg_b.eCEpol = AM_HAL_GPIO_PIN_CEPOL_ACTIVELOW,
.GP.cfg_b.uRsvd_0 = 0,
.GP.cfg_b.ePowerSw = AM_HAL_GPIO_PIN_POWERSW_NONE,
.GP.cfg_b.eForceInputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.eForceOutputEn = AM_HAL_GPIO_PIN_FORCEEN_NONE,
.GP.cfg_b.uRsvd_1 = 0,
};
//-------------------------------------------------------------
uint32_t flash_port_print(const char *pcFmt, ...)
{
return am_util_stdio_printf(pcFmt);
}
void flash_port_create_mutex(void)
{
if ( flash_mutex_handle == NULL )
{
static_print_info("create_flash_mutex:\r\n");
flash_mutex_handle = xSemaphoreCreateRecursiveMutex();
}
else
{
static_print_info("flash_mutex_handle != NULL\r\n");
}
if(flash_mutex_handle == NULL)
{
static_print_remind("create_flash_mutex:null\r\n");
}
}
void flash_port_mutex_lock(void)
{
if ( flash_mutex_handle )
{
xSemaphoreTakeRecursive ( flash_mutex_handle, portMAX_DELAY );
}
}
void flash_port_mutex_unlock(void)
{
if ( flash_mutex_handle )
{
xSemaphoreGiveRecursive ( flash_mutex_handle );
}
}
void flash_port_delay_ms(uint32_t ms)
{
if(xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED)
{
am_util_delay_ms(ms);
}
else
{
vTaskDelay(pdMS_TO_TICKS(ms));
}
}
void flash_port_delay_us(uint32_t us)
{
am_util_delay_us(us);
}
//*****************************************************************************
//
// Interrupt handler for SDIO
//
//*****************************************************************************
void am_sdio_isr(void)
{
uint32_t ui32IntStatus;
am_hal_sdhc_intr_status_get(pSdhcCardHost->pHandle, &ui32IntStatus, true);
am_hal_sdhc_intr_status_clear(pSdhcCardHost->pHandle, ui32IntStatus);
am_hal_sdhc_interrupt_service(pSdhcCardHost->pHandle, ui32IntStatus);
}
//*****************************************************************************
//
// Card event call back function
//
//*****************************************************************************
void flash_port_event_call_back(am_hal_host_evt_t *pEvt)
{
am_hal_card_host_t *pHost = (am_hal_card_host_t *)pEvt->pCtx;
if (AM_HAL_EVT_XFER_COMPLETE == pEvt->eType &&
pHost->AsyncCmdData.dir == AM_HAL_DATA_DIR_READ)
{
bAsyncReadIsDone = true;
static_print_remind("Last Read Xfered block %d\n", pEvt->ui32BlkCnt);
}
if (AM_HAL_EVT_XFER_COMPLETE == pEvt->eType &&
pHost->AsyncCmdData.dir == AM_HAL_DATA_DIR_WRITE)
{
bAsyncWriteIsDone = true;
static_print_remind("Last Write Xfered block %d\n", pEvt->ui32BlkCnt);
}
if (AM_HAL_EVT_SDMA_DONE == pEvt->eType &&
pHost->AsyncCmdData.dir == AM_HAL_DATA_DIR_READ)
{
static_print_remind("SDMA Read Xfered block %d\n", pEvt->ui32BlkCnt);
}
if (AM_HAL_EVT_SDMA_DONE == pEvt->eType &&
pHost->AsyncCmdData.dir == AM_HAL_DATA_DIR_WRITE)
{
static_print_remind("SDMA Write Xfered block %d\n", pEvt->ui32BlkCnt);
}
if (AM_HAL_EVT_CARD_PRESENT == pEvt->eType)
{
static_print_remind("A card is inserted\n");
}
}
void flash_port_power_on(void)
{
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_POWER_33V, g_AM_BSP_GPIO_SDIO_POWER_33V);
am_hal_gpio_state_write(AM_BSP_GPIO_SDIO_POWER_33V, AM_HAL_GPIO_OUTPUT_SET);
#if HARD_PCB_VERSION == PCB_EVT1
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_POWER_18V, g_AM_BSP_GPIO_SDIO_POWER_18V);
am_hal_gpio_state_write(AM_BSP_GPIO_SDIO_POWER_18V, AM_HAL_GPIO_OUTPUT_SET);
#endif
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_RST, g_AM_BSP_GPIO_SDIO_RST);
am_hal_gpio_state_write(AM_BSP_GPIO_SDIO_RST, AM_HAL_GPIO_OUTPUT_CLEAR);
am_util_delay_ms(10);
am_hal_gpio_state_write(AM_BSP_GPIO_SDIO_RST, AM_HAL_GPIO_OUTPUT_SET);
}
void flash_port_power_off(void)
{
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_POWER_33V, g_AM_BSP_GPIO_SDIO_POWER_33V);
am_hal_gpio_state_write(AM_BSP_GPIO_SDIO_POWER_33V, AM_HAL_GPIO_OUTPUT_CLEAR);
#if HARD_PCB_VERSION == PCB_EVT1
// am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_POWER_18V, g_AM_BSP_GPIO_SDIO_POWER_18V);
// am_hal_gpio_state_write(AM_BSP_GPIO_SDIO_POWER_18V, AM_HAL_GPIO_OUTPUT_CLEAR);
#endif
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_RST, am_hal_gpio_pincfg_default);
am_util_delay_ms(10);
}
//*****************************************************************************
//
//! @brief Set up the SDIO's pins.
//!
//! This function configures SDIO's CMD, CLK, DAT0-7 pins
//!
//! @return None.
//
//*****************************************************************************
void flash_port_bus_pins_enable(void)
{
uint8_t ui8BusWidth = 8;
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_CMD, g_AM_BSP_GPIO_SDIO_CMD);
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_CLK, g_AM_BSP_GPIO_SDIO_CLK);
switch (ui8BusWidth)
{
case 8:
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_DAT4, g_AM_BSP_GPIO_SDIO_DAT4);
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_DAT5, g_AM_BSP_GPIO_SDIO_DAT5);
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_DAT6, g_AM_BSP_GPIO_SDIO_DAT6);
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_DAT7, g_AM_BSP_GPIO_SDIO_DAT7);
case 4:
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_DAT1, g_AM_BSP_GPIO_SDIO_DAT1);
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_DAT2, g_AM_BSP_GPIO_SDIO_DAT2);
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_DAT3, g_AM_BSP_GPIO_SDIO_DAT3);
case 1:
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_DAT0, g_AM_BSP_GPIO_SDIO_DAT0);
break;
}
}
void flash_port_bus_pins_disable(void)
{
uint8_t ui8BusWidth = 8;
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_CMD, am_hal_gpio_pincfg_default);
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_CLK, am_hal_gpio_pincfg_default);
switch (ui8BusWidth)
{
case 8:
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_DAT4, am_hal_gpio_pincfg_default);
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_DAT5, am_hal_gpio_pincfg_default);
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_DAT6, am_hal_gpio_pincfg_default);
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_DAT7, am_hal_gpio_pincfg_default);
case 4:
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_DAT1, am_hal_gpio_pincfg_default);
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_DAT2, am_hal_gpio_pincfg_default);
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_DAT3, am_hal_gpio_pincfg_default);
case 1:
am_hal_gpio_pinconfig(AM_BSP_GPIO_SDIO_DAT0, am_hal_gpio_pincfg_default);
break;
}
}
int flash_port_sdio_init (void)
{
uint8_t ui8TxRxDelays[2];
uint8_t ret = true;
uint8_t count = 0;
uint8_t retry_unmber = 3;
#if EMMC_AUTO_TIMING_SCAN
#define START_BLK 0//3000
#define BLK_NUM 2
#define BUF_LEN 512*BLK_NUM
uint8_t buffer_rd[BUF_LEN] __attribute__((aligned(8)));
#endif
//
// Get the uderlying SDHC card host instance
//
pSdhcCardHost = am_hal_get_card_host(AM_HAL_SDHC_CARD_HOST, true);
if (pSdhcCardHost == NULL)
{
static_print_remind("No such card host and stop\n");
while(1);
}
#if EMMC_AUTO_TIMING_SCAN
am_hal_card_emmc_calibrate(AM_HAL_HOST_UHS_SDR104, EMMC_CLK_SPEED, AM_HAL_HOST_BUS_WIDTH_8,
(uint8_t *)buffer_rd, START_BLK, 2, ui8TxRxDelays);
#else
ui8TxRxDelays[0] = 7;
ui8TxRxDelays[1] = 4;
am_hal_card_host_set_txrx_delay(pSdhcCardHost, ui8TxRxDelays);
#endif
//
// check if card is present
//
while (am_hal_card_host_find_card(pSdhcCardHost, &eMMCard) != AM_HAL_STATUS_SUCCESS)
{
am_util_delay_ms(100);
count++;
if(count > retry_unmber)
{
ret = false;
break;
}
static_print_remind("Checking if card is available again\n");
}
while (am_hal_card_init(&eMMCard, NULL, AM_HAL_CARD_PWR_CTRL_SDHC_OFF) != AM_HAL_STATUS_SUCCESS)
{
am_util_delay_ms(100);
count++;
if(count > retry_unmber)
{
ret = false;
break;
}
static_print_remind("card init failed, try again\n");
}
#if EMMC_DDR_MODE
//
// 48MHz, 8-bit DDR mode for read and write
//
while (am_hal_card_cfg_set(&eMMCard, AM_HAL_CARD_TYPE_EMMC,
AM_HAL_HOST_BUS_WIDTH_8, EMMC_CLK_SPEED, AM_HAL_HOST_BUS_VOLTAGE_1_8,
AM_HAL_HOST_UHS_DDR50) != AM_HAL_STATUS_SUCCESS)
{
am_util_delay_ms(100);
count++;
if(count > retry_unmber)
{
ret = false;
break;
}
static_print_remind("setting DDR50 failed\n");
}
#else
//
// 96MHz, 8-bit SDR mode for read and write
//
while (am_hal_card_cfg_set(&eMMCard, AM_HAL_CARD_TYPE_EMMC,
AM_HAL_HOST_BUS_WIDTH_8, EMMC_CLK_SPEED, AM_HAL_HOST_BUS_VOLTAGE_1_8,
AM_HAL_HOST_UHS_SDR104) != AM_HAL_STATUS_SUCCESS)
{
am_util_delay_ms(100);
count++;
if(count > retry_unmber)
{
ret = false;
break;
}
static_print_remind("setting SDR50 failed\n");
}
// static_print_remind("eMMCard.ui32CID=0x%x,0x%x,0x%x,0x%x\n",eMMCard.ui32CID[0],eMMCard.ui32CID[1],eMMCard.ui32CID[2],eMMCard.ui32CID[3]);
// static_print_remind("eMMCard.ui32BlkNum=0x%x,0x%x,0x%x,0x%x,0x%x,0x%x\r\n",
// eMMCard.ui32BlkNum,eMMCard.ui32BlkSize,eMMCard.ui32CacheSize,eMMCard.ui32NativeBlkSize,eMMCard.ui32MaxBlks,eMMCard.bUseBlkEmulation);
#endif
// //
// // Set ADMA transfer mode
// //
// am_hal_card_host_set_xfer_mode(pSdhcCardHost, AM_HAL_HOST_XFER_ADMA);
// //
// // async read & write, card insert & remove needs a callback function
// //
// am_hal_card_register_evt_callback(&eMMCard, am_hal_card_event_test_cb);
return ret;
}
int flash_port_sdio_deinit (void)
{
if(eMMCard.pHost)
{
if(eMMCard.pHost->pHandle)
{
eMMCard.pHost->ops->deinit(eMMCard.pHost->pHandle);
}
}
return true;
}
int flash_port_enter_sleep (void)
{
return am_hal_card_pwrctrl_sleep(&eMMCard);
}
int flash_port_exit_sleep (void)
{
return am_hal_card_pwrctrl_wakeup(&eMMCard);
}
uint32_t flash_port_get_id (void)
{
uint32_t ret;
ret = eMMCard.ui32CID[1];
return ret;
}
int flash_port_timing_scan (uint32_t eUHSMode,
uint32_t ui32Clock,
uint32_t eBusWidth,
uint8_t *ui8CalibBuf,
uint32_t ui32StartBlk,
uint32_t ui32BlkCnt,
uint8_t ui8TxRxDelays[2])
{
return am_hal_card_emmc_calibrate(eUHSMode, ui32Clock, eBusWidth,
ui8CalibBuf, ui32StartBlk, ui32BlkCnt, ui8TxRxDelays);
}
int flash_port_set_txrx_delay(void *pHost, uint8_t ui8TxRxDelays[2])
{
am_hal_card_host_set_txrx_delay(pHost, ui8TxRxDelays);
return true;
}
uint32_t flash_port_block_rw(uint32_t ui32Blk, uint32_t ui32BlkCnt, uint8_t *pui8Buf, bool bRead, bool bASync)
{
am_hal_card_t *pCard = &eMMCard;
uint32_t ui32Status;
am_hal_card_host_t *pHost;
am_hal_card_cmd_t cmd;
am_hal_card_cmd_data_t cmd_data;
//static_print_remind("ui32Blk:0x%x,BlkCnt:0x%x,pui8Buf:0x%x,bRead:%d\r\n",ui32Blk*512,ui32BlkCnt,pui8Buf,bRead);
#ifndef AM_HAL_DISABLE_API_VALIDATION
if ( !pCard || !pCard->pHost )
{
return AM_HAL_STATUS_INVALID_ARG;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
if ( pCard->eState != AM_HAL_CARD_STATE_TRANS )
{
return AM_HAL_STATUS_INVALID_OPERATION;
}
pHost = pCard->pHost;
//
// Check if the start block number and block count is valid or not
//
if ( ui32Blk >= pCard->ui32MaxBlks || (ui32BlkCnt > 0xFFFF) || (ui32Blk + ui32BlkCnt) > pCard->ui32MaxBlks )
{
return AM_HAL_STATUS_OUT_OF_RANGE;
}
if ( pHost->eXferMode == AM_HAL_HOST_XFER_ADMA && ui32BlkCnt > pHost->ui32MaxADMA2BlkNums )
{
ui32BlkCnt = pHost->ui32MaxADMA2BlkNums;
}
#ifdef DSP_RAM1_WORKAROUND
if (bRead == false)
{
memcpy((void *)DSP_RAM1_TMP_ADDR, pui8Buf, ui32BlkCnt*512);
pui8Buf = (uint8_t *)DSP_RAM1_TMP_ADDR;
}
#endif
#ifndef ENABLE_SDHC_AUTO_CMD23_FEATURE
//
// Send CMD23 firstly for mulitple blocks transfer
//
memset((void *)&cmd, 0x0, sizeof(cmd));
if ( ui32BlkCnt > 1 )
{
cmd.ui8Idx = MMC_CMD_SET_BLOCK_COUNT;
cmd.ui32Arg = ui32BlkCnt;
cmd.ui32RespType = MMC_RSP_R1;
if ( (ui32Status = pHost->ops->execute_cmd(pHost->pHandle, &cmd, NULL)) != AM_HAL_STATUS_SUCCESS )
{
return ui32Status;
}
}
#endif
memset((void *)&cmd, 0x0, sizeof(cmd));
memset((void *)&cmd_data, 0x0, sizeof(cmd_data));
if ( bRead )
{
cmd.ui8Idx = ui32BlkCnt > 1 ? MMC_CMD_READ_MULTIPLE_BLOCK : MMC_CMD_READ_SINGLE_BLOCK;
}
else
{
cmd.ui8Idx = ui32BlkCnt > 1 ? MMC_CMD_WRITE_MULTIPLE_BLOCK : MMC_CMD_WRITE_SINGLE_BLOCK;
}
cmd.ui32Arg = pCard->bHighCapcity ? ui32Blk : ui32Blk * pCard->ui32BlkSize;
cmd.ui32RespType = MMC_RSP_R1;
cmd.bASync = bASync;
#ifdef ENABLE_SDHC_AUTO_CMD23_FEATURE
cmd.bAutoCMD23 = ui32BlkCnt > 1 ? true : false;
#endif
cmd_data.pui8Buf = pui8Buf;
cmd_data.ui32BlkCnt = ui32BlkCnt;
cmd_data.ui32BlkSize = pCard->ui32BlkSize;
cmd_data.dir = bRead ? AM_HAL_DATA_DIR_READ : AM_HAL_DATA_DIR_WRITE;
if ( cmd.bASync )
{
pHost->AsyncCmd = cmd;
pHost->AsyncCmdData = cmd_data;
}
ui32Status = pHost->ops->execute_cmd(pHost->pHandle, &cmd, &cmd_data);
return ui32Status;
}
uint32_t flash_port_block_erase(uint32_t ui32Blk, uint32_t ui32BlkCnt)
{
am_hal_card_t *pCard = &eMMCard;
uint32_t ui32Status;
am_hal_card_host_t *pHost;
am_hal_card_cmd_t cmd;
#ifndef AM_HAL_DISABLE_API_VALIDATION
if ( !pCard || !pCard->pHost )
{
return AM_HAL_STATUS_INVALID_ARG;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
if ( pCard->eState != AM_HAL_CARD_STATE_TRANS )
{
return AM_HAL_STATUS_INVALID_OPERATION;
}
//
// Check if the start block number and block count is valid or not
//
if ( ui32Blk >= pCard->ui32MaxBlks || ui32Blk + ui32BlkCnt >= pCard->ui32MaxBlks )
{
return AM_HAL_STATUS_OUT_OF_RANGE;
}
pHost = pCard->pHost;
//
// Define the erase start address
//
memset((void *)&cmd, 0x0, sizeof(cmd));
cmd.ui8Idx = MMC_CMD_ERASE_GROUP_START;
cmd.ui32Arg = pCard->bHighCapcity ? ui32Blk : ui32Blk * pCard->ui32BlkSize;
cmd.ui32RespType = MMC_RSP_R1;
if ( (ui32Status = pHost->ops->execute_cmd(pHost->pHandle, &cmd, NULL)) != AM_HAL_STATUS_SUCCESS )
{
return ui32Status;
}
//
// Define the erase end address
//
memset((void *)&cmd, 0x0, sizeof(cmd));
cmd.ui8Idx = MMC_CMD_ERASE_GROUP_END;
cmd.ui32Arg = pCard->bHighCapcity ? (ui32Blk + ui32BlkCnt - 1) : (ui32Blk + ui32BlkCnt - 1) * pCard->ui32BlkSize;
cmd.ui32RespType = MMC_RSP_R1;
if ( (ui32Status = pHost->ops->execute_cmd(pHost->pHandle, &cmd, NULL)) != AM_HAL_STATUS_SUCCESS )
{
return ui32Status;
}
//
// Do the erase job
//
memset((void *)&cmd, 0x0, sizeof(cmd));
cmd.bCheckBusyCmd = true;
cmd.ui8Idx = MMC_CMD_ERASE;
cmd.ui32Arg = (uint32_t)AM_HAL_TRIM;
cmd.ui32RespType = MMC_RSP_R1b;
if ( (ui32Status = pHost->ops->execute_cmd(pHost->pHandle, &cmd, NULL)) != AM_HAL_STATUS_SUCCESS )
{
return ui32Status;
}
return pHost->ops->card_busy(pHost->pHandle, 400);
}