/*---------------------------------------------------------------------------- * Copyright (c) Fenda Technologies Co., Ltd. 2020. All rights reserved. * * Description: flash_port_mspi.c * * Author: saimen * * Create: 2020-09-25 *--------------------------------------------------------------------------*/ //lib #include #include #include //os #include "FreeRTOS.h" #include "task.h" #include "semphr.h" //sdk #include "am_util.h" #include "am_bsp.h" //drv #include "flash_port_mspi.h" //#include "flash_port_sdio.h" //user #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 1 #define EMMC_DDR_MODE 0 #define STA_NOINIT 0x01/* Drive not initialized */ #define STA_NODISK 0x02/* No medium in the drive */ #define STA_PROTECT 0x04/* Write protected */ 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 96 #define AM_BSP_GPIO_SDIO_RST 60 #define AM_BSP_GPIO_SDIO_POWER_33V 58 #define AM_BSP_GPIO_SDIO_POWER_18V 10 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); 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); 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); 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); // 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); } //***************************************************************************** // //! @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; flash_port_power_off(); 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]; #if 0 #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); } static_print_remind("card host is found\n"); #if EMMC_AUTO_TIMING_SCAN ui8TxRxDelays[0] = 9; ui8TxRxDelays[1] = 6; am_hal_card_host_set_txrx_delay(pSdhcCardHost, ui8TxRxDelays); #else am_hal_card_emmc_calibrate(AM_HAL_HOST_UHS_SDR104, 96000000, AM_HAL_HOST_BUS_WIDTH_8, (uint8_t *)buffer_rd, START_BLK, 2, ui8TxRxDelays); #endif static_print_remind("calibrate:ok================\r\n"); // // check if card is present // while (am_hal_card_host_find_card(pSdhcCardHost, &eMMCard) != AM_HAL_STATUS_SUCCESS) { static_print_remind("No card is present now\n"); am_util_delay_ms(100); 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); static_print_remind("card init failed, try again\n"); } static_print_remind("init:ok===========\r\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, 48000000, AM_HAL_HOST_BUS_VOLTAGE_1_8, AM_HAL_HOST_UHS_DDR50) != AM_HAL_STATUS_SUCCESS) { am_util_delay_ms(100); 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, 96000000, AM_HAL_HOST_BUS_VOLTAGE_1_8, AM_HAL_HOST_UHS_SDR104) != AM_HAL_STATUS_SUCCESS) { am_util_delay_ms(100); 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 true; } 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; #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, 100); }