forked from xuos/xiuos
add sd card driver part for ok1052-c board
This commit is contained in:
parent
d5ff9259a0
commit
7b32e213ce
|
@ -31,7 +31,7 @@ void test_adc()
|
|||
|
||||
adc_fd = PrivOpen(ADC_DEV_DRIVER, O_RDWR);
|
||||
if (adc_fd < 0) {
|
||||
KPrintf("open adc fd error %d\n", adc_fd);
|
||||
printf("open adc fd error %d\n", adc_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ void test_adc()
|
|||
ioctl_cfg.ioctl_driver_type = ADC_TYPE;
|
||||
ioctl_cfg.args = &adc_channel;
|
||||
if (0 != PrivIoctl(adc_fd, OPE_CFG, &ioctl_cfg)) {
|
||||
KPrintf("ioctl adc fd error %d\n", adc_fd);
|
||||
printf("ioctl adc fd error %d\n", adc_fd);
|
||||
PrivClose(adc_fd);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -5,18 +5,6 @@
|
|||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file board.c
|
||||
* @brief relative configure for ok1052-c
|
||||
|
@ -25,10 +13,25 @@
|
|||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: board.c
|
||||
Description: support imxrt1052-board init function
|
||||
Others: take SDK_2.6.1_MIMXRT1052xxxxB for references
|
||||
History:
|
||||
1. Date: 2022-01-25
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. support imxrt1052-board MPU、clock、memory init
|
||||
2. support imxrt1052-board uart、semc、sdio driver init
|
||||
*************************************************/
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "board.h"
|
||||
#include "pin_mux.h"
|
||||
|
||||
#ifdef BSP_USING_SDIO
|
||||
extern int Imrt1052HwSdioInit(void);
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_SEMC
|
||||
extern status_t BOARD_InitSEMC(void);
|
||||
|
@ -640,8 +643,12 @@ void InitBoardHardware()
|
|||
#ifdef BSP_USING_LPUART
|
||||
Imrt1052HwUartInit();
|
||||
#endif
|
||||
|
||||
InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME);
|
||||
|
||||
#ifdef BSP_USING_SDIO
|
||||
Imrt1052HwSdioInit();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -13,8 +13,15 @@ menuconfig BSP_USING_LWIP
|
|||
|
||||
menuconfig BSP_USING_SEMC
|
||||
bool "Using SEMC device"
|
||||
default y
|
||||
|
||||
default n
|
||||
if BSP_USING_SEMC
|
||||
source "$BSP_DIR/third_party_driver/semc/Kconfig"
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_SDIO
|
||||
bool "Using SD card device"
|
||||
default y
|
||||
select RESOURCES_SDIO
|
||||
if BSP_USING_SDIO
|
||||
source "$BSP_DIR/third_party_driver/sdio/Kconfig"
|
||||
endif
|
||||
|
|
|
@ -12,4 +12,8 @@ ifeq ($(CONFIG_BSP_USING_SEMC),y)
|
|||
SRC_DIR += semc
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_SDIO),y)
|
||||
SRC_DIR += sdio
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
SRC_FILES := system_MIMXRT1052.c fsl_cache.c fsl_clock.c fsl_common.c pin_mux.c clock_config.c
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_SDIO),y)
|
||||
SRC_FILES += fsl_usdhc.c
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
|
@ -35,6 +35,7 @@ pin_labels:
|
|||
#include "fsl_common.h"
|
||||
#include "fsl_iomuxc.h"
|
||||
#include "pin_mux.h"
|
||||
#include "xsconfig.h"
|
||||
|
||||
/* FUNCTION ************************************************************************************************************
|
||||
*
|
||||
|
@ -46,6 +47,101 @@ void BOARD_InitBootPins(void) {
|
|||
BOARD_InitPins();
|
||||
}
|
||||
|
||||
void SDHCPinmuxConfig(void)
|
||||
{
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_B1_14_USDHC1_VSELECT, /* GPIO_B1_14 is configured as USDHC1_VSELECT */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, /* GPIO_SD_B0_00 is configured as USDHC1_CMD */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_SD_B0_01_USDHC1_CLK, /* GPIO_SD_B0_01 is configured as USDHC1_CLK */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0, /* GPIO_SD_B0_02 is configured as USDHC1_DATA0 */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1, /* GPIO_SD_B0_03 is configured as USDHC1_DATA1 */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2, /* GPIO_SD_B0_04 is configured as USDHC1_DATA2 */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3, /* GPIO_SD_B0_05 is configured as USDHC1_DATA3 */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_B1_14_USDHC1_VSELECT, /* GPIO_B1_14 PAD functional properties : */
|
||||
0x0170A1u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/4
|
||||
Speed Field: medium(100MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Pull
|
||||
Pull Up / Down Config. Field: 47K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Enabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, /* GPIO_SD_B0_00 PAD functional properties : */
|
||||
0x017089u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0(150 Ohm @ 3.3V, 260 Ohm@1.8V)
|
||||
Speed Field: medium(100MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Pull
|
||||
Pull Up / Down Config. Field: 47K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Enabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_SD_B0_01_USDHC1_CLK, /* GPIO_SD_B0_01 PAD functional properties : */
|
||||
0x014089u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0(150 Ohm @ 3.3V, 260 Ohm@1.8V)
|
||||
Speed Field: medium(100MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Disabled
|
||||
Pull / Keep Select Field: Keeper
|
||||
Pull Up / Down Config. Field: 47K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Enabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0, /* GPIO_SD_B0_02 PAD functional properties : */
|
||||
0x017089u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0(150 Ohm @ 3.3V, 260 Ohm@1.8V)
|
||||
Speed Field: medium(100MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Pull
|
||||
Pull Up / Down Config. Field: 47K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Enabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1, /* GPIO_SD_B0_03 PAD functional properties : */
|
||||
0x017089u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0(150 Ohm @ 3.3V, 260 Ohm@1.8V)
|
||||
Speed Field: medium(100MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Pull
|
||||
Pull Up / Down Config. Field: 47K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Enabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2, /* GPIO_SD_B0_04 PAD functional properties : */
|
||||
0x017089u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0(150 Ohm @ 3.3V, 260 Ohm@1.8V)
|
||||
Speed Field: medium(100MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Pull
|
||||
Pull Up / Down Config. Field: 47K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Enabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3, /* GPIO_SD_B0_05 PAD functional properties : */
|
||||
0x017089u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0(150 Ohm @ 3.3V, 260 Ohm@1.8V)
|
||||
Speed Field: medium(100MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Pull
|
||||
Pull Up / Down Config. Field: 47K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Enabled */
|
||||
}
|
||||
|
||||
void SemcPinmuxConfig(void)
|
||||
{
|
||||
|
||||
|
@ -630,6 +726,20 @@ BOARD_InitPins:
|
|||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_5, slew_rate: Fast}
|
||||
- {pin_num: G13, peripheral: GPIO1, signal: 'gpio_io, 10', pin_signal: GPIO_AD_B0_10, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_100K_Ohm,
|
||||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_5, slew_rate: Fast}
|
||||
- {pin_num: J3, peripheral: USDHC1, signal: usdhc_clk, pin_signal: GPIO_SD_B0_01, software_input_on: Disable, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_47K_Ohm,
|
||||
pull_keeper_select: Keeper, pull_keeper_enable: Disable, open_drain: Disable, speed: MHZ_100, drive_strength: R0, slew_rate: Fast}
|
||||
- {pin_num: J4, peripheral: USDHC1, signal: usdhc_cmd, pin_signal: GPIO_SD_B0_00, software_input_on: Disable, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_47K_Ohm,
|
||||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0, slew_rate: Fast}
|
||||
- {pin_num: J1, peripheral: USDHC1, signal: 'usdhc_data, 0', pin_signal: GPIO_SD_B0_02, software_input_on: Disable, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_47K_Ohm,
|
||||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0, slew_rate: Fast}
|
||||
- {pin_num: K1, peripheral: USDHC1, signal: 'usdhc_data, 1', pin_signal: GPIO_SD_B0_03, software_input_on: Disable, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_47K_Ohm,
|
||||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0, slew_rate: Fast}
|
||||
- {pin_num: H2, peripheral: USDHC1, signal: 'usdhc_data, 2', pin_signal: GPIO_SD_B0_04, software_input_on: Disable, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_47K_Ohm,
|
||||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0, slew_rate: Fast}
|
||||
- {pin_num: J2, peripheral: USDHC1, signal: 'usdhc_data, 3', pin_signal: GPIO_SD_B0_05, software_input_on: Disable, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_47K_Ohm,
|
||||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0, slew_rate: Fast}
|
||||
- {pin_num: C14, peripheral: USDHC1, signal: usdhc_vselect, pin_signal: GPIO_B1_14, software_input_on: Disable, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_47K_Ohm,
|
||||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_4, slew_rate: Fast}
|
||||
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
|
||||
*/
|
||||
|
||||
|
@ -661,6 +771,10 @@ void BOARD_InitPins(void) {
|
|||
IOMUXC_GPIO_AD_B0_13_LPUART1_RX, /* GPIO_AD_B0_13 is configured as LPUART1_RX */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
|
||||
#ifdef BSP_USING_SDIO
|
||||
SDHCPinmuxConfig();
|
||||
#endif
|
||||
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_B1_04_ENET_RX_DATA00, /* GPIO_B1_04 is configured as ENET_RX_DATA00 */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file connect_sdio.h
|
||||
* @brief define OK1052-board sdio function and struct
|
||||
* @version 2.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-01-24
|
||||
*/
|
||||
|
||||
#ifndef CONNECT_SDIO_H
|
||||
#define CONNECT_SDIO_H
|
||||
|
||||
#include <device.h>
|
||||
#include <fsl_sd.h>
|
||||
#include <pin_mux.h>
|
||||
#include <clock_config.h>
|
||||
#include <fsl_gpio.h>
|
||||
#include <fsl_common.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int Imrt1052HwSdioInit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -6,18 +6,6 @@
|
|||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_common.h
|
||||
* @brief common drivers header
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
if BSP_USING_SDIO
|
||||
config SDIO_BUS_NAME
|
||||
string "sdio bus name"
|
||||
default "sdio"
|
||||
|
||||
config SDIO_DRIVER_NAME
|
||||
string "sdio driver name"
|
||||
default "sdio_drv"
|
||||
|
||||
config SDIO_DEVICE_NAME
|
||||
string "sdio device name"
|
||||
default "sdio_dev"
|
||||
endif
|
|
@ -0,0 +1,5 @@
|
|||
SRC_DIR := sdmmc
|
||||
|
||||
SRC_FILES := connect_sdio.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,409 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file connect_sdio.c
|
||||
* @brief support sdio function using bus driver framework on OK1052 board
|
||||
* @version 2.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-01-24
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: connect_sdio.c
|
||||
Description: support imxrt1052-board sd card configure and sdio bus register function
|
||||
Others: take SDK_2.6.1_MIMXRT1052xxxxB/boards/evkbimxrt1050/driver_examples/sdcard/polling/sdcard_polling.c for references
|
||||
History:
|
||||
1. Date: 2022-01-24
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. support imxrt1052-board sdio configure, write and read
|
||||
2. support imxrt1052-board sdio bus device and driver register
|
||||
*************************************************/
|
||||
|
||||
#include <connect_sdio.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#define SDCARD_POWER_CTRL_FUNCTION_EXIST
|
||||
|
||||
/*! @brief Data block count accessed in card */
|
||||
#define DATA_BLOCK_COUNT (5U)
|
||||
/*! @brief Start data block number accessed in card */
|
||||
#define DATA_BLOCK_START (2U)
|
||||
/*! @brief Data buffer size. */
|
||||
#define DATA_BUFFER_SIZE (FSL_SDMMC_DEFAULT_BLOCK_SIZE * DATA_BLOCK_COUNT)
|
||||
|
||||
#define BOARD_USDHC_SDCARD_POWER_CONTROL(state) \
|
||||
(GPIO_PinWrite(BOARD_SD_POWER_RESET_GPIO, BOARD_SD_POWER_RESET_GPIO_PIN, state))
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
static void BoardPowerOffSdCard(void);
|
||||
static void BoardPowerOnSdCard(void);
|
||||
|
||||
/*!
|
||||
* @brief printf the card information log.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*/
|
||||
static void CardInformationLog(sd_card_t *card);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/* @brief decription about the read/write buffer
|
||||
* The size of the read/write buffer should be a multiple of 512, since SDHC/SDXC card uses 512-byte fixed
|
||||
* block length and this driver example is enabled with a SDHC/SDXC card.If you are using a SDSC card, you
|
||||
* can define the block length by yourself if the card supports partial access.
|
||||
* The address of the read/write buffer should align to the specific DMA data buffer address align value if
|
||||
* DMA transfer is used, otherwise the buffer address is not important.
|
||||
* At the same time buffer address/size should be aligned to the cache line size if cache is supported.
|
||||
*/
|
||||
/*! @brief Data written to the card */
|
||||
SDK_ALIGN(uint8_t g_data_write[SDK_SIZEALIGN(DATA_BUFFER_SIZE, SDMMC_DATA_BUFFER_ALIGN_CACHE)],
|
||||
MAX(SDMMC_DATA_BUFFER_ALIGN_CACHE, SDMMCHOST_DMA_BUFFER_ADDR_ALIGN));
|
||||
/*! @brief Data read from the card */
|
||||
SDK_ALIGN(uint8_t g_data_read[SDK_SIZEALIGN(DATA_BUFFER_SIZE, SDMMC_DATA_BUFFER_ALIGN_CACHE)],
|
||||
MAX(SDMMC_DATA_BUFFER_ALIGN_CACHE, SDMMCHOST_DMA_BUFFER_ADDR_ALIGN));
|
||||
|
||||
/*! @brief SDMMC host detect card configuration */
|
||||
static const sdmmchost_detect_card_t s_sdcard_detect = {
|
||||
#ifndef BOARD_SD_DETECT_TYPE
|
||||
.cdType = kSDMMCHOST_DetectCardByGpioCD,
|
||||
#else
|
||||
.cdType = BOARD_SD_DETECT_TYPE,
|
||||
#endif
|
||||
.cdTimeOut_ms = (~0U),
|
||||
};
|
||||
|
||||
/*! @brief SDMMC card power control configuration */
|
||||
#if defined SDCARD_POWER_CTRL_FUNCTION_EXIST
|
||||
static const sdmmchost_pwr_card_t s_sdcard_pwr_ctrl = {
|
||||
.powerOn = BoardPowerOnSdCard,
|
||||
.powerOnDelay_ms = 0U,
|
||||
.powerOff = BoardPowerOffSdCard,
|
||||
.powerOffDelay_ms = 0U,
|
||||
};
|
||||
#endif
|
||||
|
||||
/*! @brief SDMMC card power control configuration */
|
||||
#if defined SDCARD_SWITCH_VOLTAGE_FUNCTION_EXIST
|
||||
static const sdmmchost_card_switch_voltage_func_t s_sdcard_voltage_switch = {
|
||||
.cardSignalLine1V8 = BOARD_USDHC_Switch_VoltageTo1V8,
|
||||
.cardSignalLine3V3 = BOARD_USDHC_Switch_VoltageTo3V3,
|
||||
};
|
||||
#endif
|
||||
|
||||
/*! @brief SD card detect flag */
|
||||
static volatile bool s_card_inserted = false;
|
||||
|
||||
/*! @brief Card descriptor. */
|
||||
static sd_card_t g_sd;
|
||||
static int sd_lock = -1;
|
||||
|
||||
static void BoardUSDHCClockConfiguration(void)
|
||||
{
|
||||
CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN);
|
||||
/*configure system pll PFD0 fractional divider to 24, output clock is 528MHZ * 18 / 24 = 396 MHZ*/
|
||||
CLOCK_InitSysPfd(kCLOCK_Pfd0, 24U);
|
||||
/* Configure USDHC clock source and divider */
|
||||
CLOCK_SetDiv(kCLOCK_Usdhc1Div, 0U);
|
||||
CLOCK_SetMux(kCLOCK_Usdhc1Mux, 1U);
|
||||
}
|
||||
|
||||
static void BoardPowerOffSdCard(void)
|
||||
{
|
||||
/*
|
||||
Do nothing here.
|
||||
|
||||
SD card will not be detected correctly if the card VDD is power off,
|
||||
the reason is caused by card VDD supply to the card detect circuit, this issue is exist on EVK board rev A1 and
|
||||
A2.
|
||||
|
||||
If power off function is not implemented after soft reset and prior to SD Host initialization without
|
||||
remove/insert card,
|
||||
a UHS-I card may not reach its highest speed mode during the second card initialization.
|
||||
Application can avoid this issue by toggling the SD_VDD (GPIO) before the SD host initialization.
|
||||
*/
|
||||
}
|
||||
|
||||
static void BoardPowerOnSdCard(void)
|
||||
{
|
||||
BOARD_USDHC_SDCARD_POWER_CONTROL(1);
|
||||
}
|
||||
|
||||
static void SdcardDetectCallBack(bool is_inserted, void *user_data)
|
||||
{
|
||||
s_card_inserted = is_inserted;
|
||||
}
|
||||
|
||||
static void CardInformationLog(sd_card_t *card)
|
||||
{
|
||||
NULL_PARAM_CHECK(card);
|
||||
|
||||
KPrintf("\r\nCard size %d * %d bytes\r\n", card->blockCount, card->blockSize);
|
||||
KPrintf("\r\nWorking condition:\r\n");
|
||||
if (card->operationVoltage == kCARD_OperationVoltage330V) {
|
||||
KPrintf("\r\n Voltage : 3.3V\r\n");
|
||||
} else if (card->operationVoltage == kCARD_OperationVoltage180V) {
|
||||
KPrintf("\r\n Voltage : 1.8V\r\n");
|
||||
}
|
||||
|
||||
if (card->currentTiming == kSD_TimingSDR12DefaultMode) {
|
||||
if (card->operationVoltage == kCARD_OperationVoltage330V) {
|
||||
KPrintf("\r\n Timing mode: Default mode\r\n");
|
||||
} else if (card->operationVoltage == kCARD_OperationVoltage180V) {
|
||||
KPrintf("\r\n Timing mode: SDR12 mode\r\n");
|
||||
}
|
||||
} else if (card->currentTiming == kSD_TimingSDR25HighSpeedMode) {
|
||||
if (card->operationVoltage == kCARD_OperationVoltage180V) {
|
||||
KPrintf("\r\n Timing mode: SDR25\r\n");
|
||||
} else {
|
||||
KPrintf("\r\n Timing mode: High Speed\r\n");
|
||||
}
|
||||
} else if (card->currentTiming == kSD_TimingSDR50Mode) {
|
||||
KPrintf("\r\n Timing mode: SDR50\r\n");
|
||||
} else if (card->currentTiming == kSD_TimingSDR104Mode) {
|
||||
KPrintf("\r\n Timing mode: SDR104\r\n");
|
||||
} else if (card->currentTiming == kSD_TimingDDR50Mode) {
|
||||
KPrintf("\r\n Timing mode: DDR50\r\n");
|
||||
}
|
||||
|
||||
KPrintf("\r\n Freq : %d HZ\r\n", card->busClock_Hz);
|
||||
}
|
||||
|
||||
static uint32 SdioConfigure(void *drv, struct BusConfigureInfo *configure_info)
|
||||
{
|
||||
NULL_PARAM_CHECK(drv);
|
||||
NULL_PARAM_CHECK(configure_info);
|
||||
|
||||
if (configure_info->configure_cmd == OPER_BLK_GETGEOME) {
|
||||
// NULL_PARAM_CHECK(configure_info->private_data);
|
||||
// struct DeviceBlockArrange *args = (struct DeviceBlockArrange *)configure_info->private_data;
|
||||
// //SD_GetCardInfo(&SDCardInfo);
|
||||
|
||||
// // args->size_perbank = SDCardInfo.CardBlockSize;
|
||||
// // args->block_size = SDCardInfo.CardBlockSize;
|
||||
// // if(SDCardInfo.CardType == SDIO_HIGH_CAPACITY_SD_CARD)
|
||||
// // args->bank_num = (SDCardInfo.SD_csd.DeviceSize + 1) * 1024;
|
||||
// // else
|
||||
// // args->bank_num = SDCardInfo.CardCapacity;
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static uint32 SdioOpen(void *dev)
|
||||
{
|
||||
NULL_PARAM_CHECK(dev);
|
||||
|
||||
if(sd_lock >= 0) {
|
||||
KSemaphoreDelete(sd_lock);
|
||||
}
|
||||
sd_lock = KSemaphoreCreate(1);
|
||||
if (sd_lock < 0){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static uint32 SdioClose(void *dev)
|
||||
{
|
||||
NULL_PARAM_CHECK(dev);
|
||||
|
||||
KSemaphoreDelete(sd_lock);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static uint32 SdioRead(void *dev, struct BusBlockReadParam *read_param)
|
||||
{
|
||||
uint8 ret = EOK;
|
||||
|
||||
KSemaphoreObtain(sd_lock, WAITING_FOREVER);
|
||||
|
||||
// if (((uint32)read_param->buffer & 0x03) != 0) {
|
||||
// uint64_t sector;
|
||||
// uint8_t* temp;
|
||||
|
||||
// sector = (uint64_t)read_param->pos * SDCARD_SECTOR_SIZE;
|
||||
// temp = (uint8_t*)read_param->buffer;
|
||||
|
||||
// for (uint8 i = 0; i < read_param->size; i++) {
|
||||
// ret = SD_ReadBlock((uint8_t *)SDBuffer, sector, 1);
|
||||
// if(ret != SD_OK) {
|
||||
// KPrintf("read failed: %d, buffer 0x%08x\n", ret, temp);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// memcpy(temp, SDBuffer, SDCARD_SECTOR_SIZE);
|
||||
|
||||
// sector += SDCARD_SECTOR_SIZE;
|
||||
// temp += SDCARD_SECTOR_SIZE;
|
||||
// }
|
||||
// } else {
|
||||
// ret = SD_ReadBlock((uint8_t *)read_param->buffer, (uint64_t)read_param->pos * SDCARD_SECTOR_SIZE, read_param->size);
|
||||
// if (ret != SD_OK) {
|
||||
// KPrintf("read failed: %d, buffer 0x%08x\n", ret, (uint8_t *)read_param->buffer);
|
||||
// return 0;
|
||||
// }
|
||||
// }
|
||||
|
||||
// KSemaphoreAbandon(sd_lock);
|
||||
|
||||
return read_param->size;
|
||||
}
|
||||
|
||||
static uint32 SdioWrite(void *dev, struct BusBlockWriteParam *write_param)
|
||||
{
|
||||
uint8 ret = EOK;
|
||||
|
||||
// KSemaphoreObtain(sd_lock, WAITING_FOREVER);
|
||||
|
||||
// if (((uint32)write_param->buffer & 0x03) != 0) {
|
||||
// uint64_t sector;
|
||||
// uint8_t* temp;
|
||||
|
||||
// sector = (uint64_t)write_param->pos * SDCARD_SECTOR_SIZE;
|
||||
// temp = (uint8_t*)write_param->buffer;
|
||||
|
||||
// for (uint8 i = 0; i < write_param->size; i++) {
|
||||
// memcpy(SDBuffer, temp, SDCARD_SECTOR_SIZE);
|
||||
|
||||
// ret = SD_WriteBlock((uint8_t *)SDBuffer, sector, 1);
|
||||
// if(ret != SD_OK) {
|
||||
// KPrintf("write failed: %d, buffer 0x%08x\n", ret, temp);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// sector += SDCARD_SECTOR_SIZE;
|
||||
// temp += SDCARD_SECTOR_SIZE;
|
||||
// }
|
||||
// } else {
|
||||
// ret = SD_WriteBlock((uint8_t *)write_param->buffer, (uint64_t)write_param->pos * SDCARD_SECTOR_SIZE, write_param->size);
|
||||
// if (ret != SD_OK) {
|
||||
// KPrintf("write failed: %d, buffer 0x%08x\n", ret, (uint8_t *)write_param->buffer);
|
||||
// return 0;
|
||||
// }
|
||||
// }
|
||||
|
||||
KSemaphoreAbandon(sd_lock);
|
||||
|
||||
return write_param->size;
|
||||
}
|
||||
|
||||
static struct SdioDevDone dev_done =
|
||||
{
|
||||
SdioOpen,
|
||||
SdioClose,
|
||||
SdioWrite,
|
||||
SdioRead,
|
||||
};
|
||||
|
||||
int Imrt1052HwSdioInit(void)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
bool is_read_only;
|
||||
|
||||
static struct SdioBus sdio_bus;
|
||||
static struct SdioDriver sdio_drv;
|
||||
static struct SdioHardwareDevice sdio_dev;
|
||||
static sd_card_t *card = &g_sd;
|
||||
|
||||
memset(&sdio_bus, 0, sizeof(struct SdioBus));
|
||||
memset(&sdio_drv, 0, sizeof(struct SdioDriver));
|
||||
memset(&sdio_dev, 0, sizeof(struct SdioHardwareDevice));
|
||||
|
||||
BoardUSDHCClockConfiguration();
|
||||
|
||||
card->host.base = SD_HOST_BASEADDR;
|
||||
card->host.sourceClock_Hz = SD_HOST_CLK_FREQ;
|
||||
|
||||
/* card detect type */
|
||||
card->usrParam.cd = &s_sdcard_detect;
|
||||
|
||||
#if defined SDCARD_POWER_CTRL_FUNCTION_EXIST
|
||||
card->usrParam.pwr = &s_sdcard_pwr_ctrl;
|
||||
#endif
|
||||
|
||||
#if defined DEMO_SDCARD_SWITCH_VOLTAGE_FUNCTION_EXIST
|
||||
card->usrParam.cardVoltage = &s_sdcard_voltage_switch;
|
||||
#endif
|
||||
|
||||
/* SD host init function */
|
||||
if (SD_HostInit(card) != kStatus_Success) {
|
||||
KPrintf("\r\nSD host init fail\r\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
KPrintf("\r\nPlease insert a card into board.\r\n");
|
||||
|
||||
/* power off card */
|
||||
SD_PowerOffCard(card->host.base, card->usrParam.pwr);
|
||||
|
||||
if (SD_WaitCardDetectStatus(SD_HOST_BASEADDR, &s_sdcard_detect, true) == kStatus_Success) {
|
||||
KPrintf("\r\nCard inserted.\r\n");
|
||||
/* reset host once card re-plug in */
|
||||
SD_HostReset(&(card->host));
|
||||
/* power on the card */
|
||||
SD_PowerOnCard(card->host.base, card->usrParam.pwr);
|
||||
KPrintf("power on done\n");
|
||||
} else {
|
||||
KPrintf("\r\nCard detect fail.\r\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Init card. */
|
||||
if (SD_CardInit(card)) {
|
||||
KPrintf("\r\nSD card init failed.\r\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* card information log */
|
||||
CardInformationLog(card);
|
||||
|
||||
/* Check if card is readonly. */
|
||||
is_read_only = SD_CheckReadOnly(card);
|
||||
|
||||
ret = SdioBusInit(&sdio_bus, SDIO_BUS_NAME);
|
||||
if (ret != EOK) {
|
||||
KPrintf("Sdio bus init error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = SdioDriverInit(&sdio_drv, SDIO_DRIVER_NAME);
|
||||
if (ret != EOK) {
|
||||
KPrintf("Sdio driver init error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
ret = SdioDriverAttachToBus(SDIO_DRIVER_NAME, SDIO_BUS_NAME);
|
||||
if (ret != EOK) {
|
||||
KPrintf("Sdio driver attach error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
sdio_dev.dev_done = &dev_done;
|
||||
ret = SdioDeviceRegister(&sdio_dev, SDIO_DEVICE_NAME);
|
||||
if (ret != EOK) {
|
||||
KPrintf("Sdio device register error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
ret = SdioDeviceAttachToBus(SDIO_DEVICE_NAME, SDIO_BUS_NAME);
|
||||
if (ret != EOK) {
|
||||
KPrintf("Sdio device register error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
SRC_DIR += port src
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,321 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_MMC_H_
|
||||
#define _FSL_MMC_H_
|
||||
|
||||
#include "fsl_sdmmc_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup MMCCARD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
/*! @brief MMC card flags */
|
||||
enum _mmc_card_flag
|
||||
{
|
||||
kMMC_SupportHighSpeed26MHZFlag = (1U << 0U), /*!< Support high speed 26MHZ */
|
||||
kMMC_SupportHighSpeed52MHZFlag = (1U << 1U), /*!< Support high speed 52MHZ */
|
||||
kMMC_SupportHighSpeedDDR52MHZ180V300VFlag = (1 << 2U), /*!< ddr 52MHZ 1.8V or 3.0V */
|
||||
kMMC_SupportHighSpeedDDR52MHZ120VFlag = (1 << 3U), /*!< DDR 52MHZ 1.2V */
|
||||
kMMC_SupportHS200200MHZ180VFlag = (1 << 4U), /*!< HS200 ,200MHZ,1.8V */
|
||||
kMMC_SupportHS200200MHZ120VFlag = (1 << 5U), /*!< HS200, 200MHZ, 1.2V */
|
||||
kMMC_SupportHS400DDR200MHZ180VFlag = (1 << 6U), /*!< HS400, DDR, 200MHZ,1.8V */
|
||||
kMMC_SupportHS400DDR200MHZ120VFlag = (1 << 7U), /*!< HS400, DDR, 200MHZ,1.2V */
|
||||
kMMC_SupportHighCapacityFlag = (1U << 8U), /*!< Support high capacity */
|
||||
kMMC_SupportAlternateBootFlag = (1U << 9U), /*!< Support alternate boot */
|
||||
kMMC_SupportDDRBootFlag = (1U << 10U), /*!< support DDR boot flag*/
|
||||
kMMC_SupportHighSpeedBootFlag = (1U << 11U), /*!< support high speed boot flag*/
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief mmc card state
|
||||
*
|
||||
* Define the card structure including the necessary fields to identify and describe the card.
|
||||
*/
|
||||
typedef struct _mmc_card
|
||||
{
|
||||
SDMMCHOST_CONFIG host; /*!< Host information */
|
||||
mmccard_usr_param_t usrParam; /*!< user parameter */
|
||||
|
||||
bool isHostReady; /*!< Use this flag to indicate if need host re-init or not*/
|
||||
bool noInteralAlign; /*!< use this flag to disable sdmmc align. If disable, sdmmc will not make sure the
|
||||
data buffer address is word align, otherwise all the transfer are align to low level driver */
|
||||
uint32_t busClock_Hz; /*!< MMC bus clock united in Hz */
|
||||
uint32_t relativeAddress; /*!< Relative address of the card */
|
||||
bool enablePreDefinedBlockCount; /*!< Enable PRE-DEFINED block count when read/write */
|
||||
uint32_t flags; /*!< Capability flag in _mmc_card_flag */
|
||||
uint32_t rawCid[4U]; /*!< Raw CID content */
|
||||
uint32_t rawCsd[4U]; /*!< Raw CSD content */
|
||||
uint32_t rawExtendedCsd[MMC_EXTENDED_CSD_BYTES / 4U]; /*!< Raw MMC Extended CSD content */
|
||||
uint32_t ocr; /*!< Raw OCR content */
|
||||
mmc_cid_t cid; /*!< CID */
|
||||
mmc_csd_t csd; /*!< CSD */
|
||||
mmc_extended_csd_t extendedCsd; /*!< Extended CSD */
|
||||
uint32_t blockSize; /*!< Card block size */
|
||||
uint32_t userPartitionBlocks; /*!< Card total block number in user partition */
|
||||
uint32_t bootPartitionBlocks; /*!< Boot partition size united as block size */
|
||||
uint32_t eraseGroupBlocks; /*!< Erase group size united as block size */
|
||||
mmc_access_partition_t currentPartition; /*!< Current access partition */
|
||||
mmc_voltage_window_t hostVoltageWindowVCCQ; /*!< Host IO voltage window */
|
||||
mmc_voltage_window_t hostVoltageWindowVCC; /*!< application must set this value according to board specific */
|
||||
mmc_high_speed_timing_t busTiming; /*!< indicate the current work timing mode*/
|
||||
mmc_data_bus_width_t busWidth; /*!< indicate the current work bus width */
|
||||
} mmc_card_t;
|
||||
|
||||
/*************************************************************************************************
|
||||
* API
|
||||
************************************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name MMCCARD Function
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the MMC card and host.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*
|
||||
* @retval kStatus_SDMMC_HostNotReady host is not ready.
|
||||
* @retval kStatus_SDMMC_GoIdleFailed Go idle failed.
|
||||
* @retval kStatus_SDMMC_SendOperationConditionFailed Send operation condition failed.
|
||||
* @retval kStatus_SDMMC_AllSendCidFailed Send CID failed.
|
||||
* @retval kStatus_SDMMC_SetRelativeAddressFailed Set relative address failed.
|
||||
* @retval kStatus_SDMMC_SendCsdFailed Send CSD failed.
|
||||
* @retval kStatus_SDMMC_CardNotSupport Card not support.
|
||||
* @retval kStatus_SDMMC_SelectCardFailed Send SELECT_CARD command failed.
|
||||
* @retval kStatus_SDMMC_SendExtendedCsdFailed Send EXT_CSD failed.
|
||||
* @retval kStatus_SDMMC_SetBusWidthFailed Set bus width failed.
|
||||
* @retval kStatus_SDMMC_SwitchHighSpeedFailed Switch high speed failed.
|
||||
* @retval kStatus_SDMMC_SetCardBlockSizeFailed Set card block size failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t MMC_Init(mmc_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes the card and host.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*/
|
||||
void MMC_Deinit(mmc_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief intialize the card.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*
|
||||
* @retval kStatus_SDMMC_HostNotReady host is not ready.
|
||||
* @retval kStatus_SDMMC_GoIdleFailed Go idle failed.
|
||||
* @retval kStatus_SDMMC_SendOperationConditionFailed Send operation condition failed.
|
||||
* @retval kStatus_SDMMC_AllSendCidFailed Send CID failed.
|
||||
* @retval kStatus_SDMMC_SetRelativeAddressFailed Set relative address failed.
|
||||
* @retval kStatus_SDMMC_SendCsdFailed Send CSD failed.
|
||||
* @retval kStatus_SDMMC_CardNotSupport Card not support.
|
||||
* @retval kStatus_SDMMC_SelectCardFailed Send SELECT_CARD command failed.
|
||||
* @retval kStatus_SDMMC_SendExtendedCsdFailed Send EXT_CSD failed.
|
||||
* @retval kStatus_SDMMC_SetBusWidthFailed Set bus width failed.
|
||||
* @retval kStatus_SDMMC_SwitchHighSpeedFailed Switch high speed failed.
|
||||
* @retval kStatus_SDMMC_SetCardBlockSizeFailed Set card block size failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t MMC_CardInit(mmc_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes the card.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*/
|
||||
void MMC_CardDeinit(mmc_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief initialize the host.
|
||||
*
|
||||
* This function deinitializes the specific host.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*/
|
||||
status_t MMC_HostInit(mmc_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes the host.
|
||||
*
|
||||
* This function deinitializes the host.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*/
|
||||
void MMC_HostDeinit(mmc_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief reset the host.
|
||||
*
|
||||
* This function reset the specific host.
|
||||
*
|
||||
* @param host host descriptor.
|
||||
*/
|
||||
void MMC_HostReset(SDMMCHOST_CONFIG *host);
|
||||
|
||||
/*!
|
||||
* @brief power on card.
|
||||
*
|
||||
* The power on operation depend on host or the user define power on function.
|
||||
* @param base host base address.
|
||||
* @param pwr user define power control configuration
|
||||
*/
|
||||
void MMC_PowerOnCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr);
|
||||
|
||||
/*!
|
||||
* @brief power off card.
|
||||
*
|
||||
* The power off operation depend on host or the user define power on function.
|
||||
* @param base host base address.
|
||||
* @param pwr user define power control configuration
|
||||
*/
|
||||
void MMC_PowerOffCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr);
|
||||
|
||||
/*!
|
||||
* @brief Checks if the card is read-only.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @retval true Card is read only.
|
||||
* @retval false Card isn't read only.
|
||||
*/
|
||||
bool MMC_CheckReadOnly(mmc_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief Reads data blocks from the card.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param buffer The buffer to save data.
|
||||
* @param startBlock The start block index.
|
||||
* @param blockCount The number of blocks to read.
|
||||
* @retval kStatus_InvalidArgument Invalid argument.
|
||||
* @retval kStatus_SDMMC_CardNotSupport Card not support.
|
||||
* @retval kStatus_SDMMC_SetBlockCountFailed Set block count failed.
|
||||
* @retval kStatus_SDMMC_TransferFailed Transfer failed.
|
||||
* @retval kStatus_SDMMC_StopTransmissionFailed Stop transmission failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t MMC_ReadBlocks(mmc_card_t *card, uint8_t *buffer, uint32_t startBlock, uint32_t blockCount);
|
||||
|
||||
/*!
|
||||
* @brief Writes data blocks to the card.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param buffer The buffer to save data blocks.
|
||||
* @param startBlock Start block number to write.
|
||||
* @param blockCount Block count.
|
||||
* @retval kStatus_InvalidArgument Invalid argument.
|
||||
* @retval kStatus_SDMMC_NotSupportYet Not support now.
|
||||
* @retval kStatus_SDMMC_SetBlockCountFailed Set block count failed.
|
||||
* @retval kStatus_SDMMC_WaitWriteCompleteFailed Send status failed.
|
||||
* @retval kStatus_SDMMC_TransferFailed Transfer failed.
|
||||
* @retval kStatus_SDMMC_StopTransmissionFailed Stop transmission failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t MMC_WriteBlocks(mmc_card_t *card, const uint8_t *buffer, uint32_t startBlock, uint32_t blockCount);
|
||||
|
||||
/*!
|
||||
* @brief Erases groups of the card.
|
||||
*
|
||||
* Erase group is the smallest erase unit in MMC card. The erase range is [startGroup, endGroup].
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param startGroup Start group number.
|
||||
* @param endGroup End group number.
|
||||
* @retval kStatus_InvalidArgument Invalid argument.
|
||||
* @retval kStatus_SDMMC_WaitWriteCompleteFailed Send status failed.
|
||||
* @retval kStatus_SDMMC_TransferFailed Transfer failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t MMC_EraseGroups(mmc_card_t *card, uint32_t startGroup, uint32_t endGroup);
|
||||
|
||||
/*!
|
||||
* @brief Selects the partition to access.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param partitionNumber The partition number.
|
||||
* @retval kStatus_SDMMC_ConfigureExtendedCsdFailed Configure EXT_CSD failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t MMC_SelectPartition(mmc_card_t *card, mmc_access_partition_t partitionNumber);
|
||||
|
||||
/*!
|
||||
* @brief Configures the boot activity of the card.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param config Boot configuration structure.
|
||||
* @retval kStatus_SDMMC_NotSupportYet Not support now.
|
||||
* @retval kStatus_SDMMC_ConfigureExtendedCsdFailed Configure EXT_CSD failed.
|
||||
* @retval kStatus_SDMMC_ConfigureBootFailed Configure boot failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t MMC_SetBootConfig(mmc_card_t *card, const mmc_boot_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief MMC card start boot.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param mmcConfig mmc Boot configuration structure.
|
||||
* @param buffer address to recieve data.
|
||||
* @param hostConfig host boot configurations.
|
||||
* @retval kStatus_Fail fail.
|
||||
* @retval kStatus_SDMMC_TransferFailed transfer fail.
|
||||
* @retval kStatus_SDMMC_GoIdleFailed reset card fail.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t MMC_StartBoot(mmc_card_t *card,
|
||||
const mmc_boot_config_t *mmcConfig,
|
||||
uint8_t *buffer,
|
||||
SDMMCHOST_BOOT_CONFIG *hostConfig);
|
||||
|
||||
/*!
|
||||
* @brief MMC card set boot configuration write protect.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param wp write protect value.
|
||||
*/
|
||||
status_t MMC_SetBootConfigWP(mmc_card_t *card, uint8_t wp);
|
||||
|
||||
/*!
|
||||
* @brief MMC card continous read boot data.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param buffer buffer address.
|
||||
* @param hostConfig host boot configurations.
|
||||
*/
|
||||
status_t MMC_ReadBootData(mmc_card_t *card, uint8_t *buffer, SDMMCHOST_BOOT_CONFIG *hostConfig);
|
||||
|
||||
/*!
|
||||
* @brief MMC card stop boot mode.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param bootMode boot mode.
|
||||
*/
|
||||
status_t MMC_StopBoot(mmc_card_t *card, uint32_t bootMode);
|
||||
|
||||
/*!
|
||||
* @brief MMC card set boot partition write protect.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param bootPartitionWP boot partition write protect value.
|
||||
*/
|
||||
status_t MMC_SetBootPartitionWP(mmc_card_t *card, mmc_boot_partition_wp_t bootPartitionWP);
|
||||
|
||||
/* @} */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
/*! @} */
|
||||
#endif /* _FSL_MMC_H_*/
|
|
@ -0,0 +1,315 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_SD_H_
|
||||
#define _FSL_SD_H_
|
||||
|
||||
#include "fsl_sdmmc_common.h"
|
||||
/*!
|
||||
* @addtogroup SDCARD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
/*! @brief SD card flags */
|
||||
enum _sd_card_flag
|
||||
{
|
||||
kSD_SupportHighCapacityFlag = (1U << 1U), /*!< Support high capacity */
|
||||
kSD_Support4BitWidthFlag = (1U << 2U), /*!< Support 4-bit data width */
|
||||
kSD_SupportSdhcFlag = (1U << 3U), /*!< Card is SDHC */
|
||||
kSD_SupportSdxcFlag = (1U << 4U), /*!< Card is SDXC */
|
||||
kSD_SupportVoltage180v = (1U << 5U), /*!< card support 1.8v voltage*/
|
||||
kSD_SupportSetBlockCountCmd = (1U << 6U), /*!< card support cmd23 flag*/
|
||||
kSD_SupportSpeedClassControlCmd = (1U << 7U), /*!< card support speed class control flag */
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief SD card state
|
||||
*
|
||||
* Define the card structure including the necessary fields to identify and describe the card.
|
||||
*/
|
||||
typedef struct _sd_card
|
||||
{
|
||||
SDMMCHOST_CONFIG host; /*!< Host information */
|
||||
|
||||
sdcard_usr_param_t usrParam; /*!< user parameter */
|
||||
bool isHostReady; /*!< use this flag to indicate if need host re-init or not*/
|
||||
bool noInteralAlign; /*!< use this flag to disable sdmmc align. If disable, sdmmc will not make sure the
|
||||
data buffer address is word align, otherwise all the transfer are align to low level driver */
|
||||
uint32_t busClock_Hz; /*!< SD bus clock frequency united in Hz */
|
||||
uint32_t relativeAddress; /*!< Relative address of the card */
|
||||
uint32_t version; /*!< Card version */
|
||||
uint32_t flags; /*!< Flags in _sd_card_flag */
|
||||
uint32_t rawCid[4U]; /*!< Raw CID content */
|
||||
uint32_t rawCsd[4U]; /*!< Raw CSD content */
|
||||
uint32_t rawScr[2U]; /*!< Raw CSD content */
|
||||
uint32_t ocr; /*!< Raw OCR content */
|
||||
sd_cid_t cid; /*!< CID */
|
||||
sd_csd_t csd; /*!< CSD */
|
||||
sd_scr_t scr; /*!< SCR */
|
||||
sd_status_t stat; /*!< sd 512 bit status */
|
||||
uint32_t blockCount; /*!< Card total block number */
|
||||
uint32_t blockSize; /*!< Card block size */
|
||||
sd_timing_mode_t currentTiming; /*!< current timing mode */
|
||||
sd_driver_strength_t driverStrength; /*!< driver strength */
|
||||
sd_max_current_t maxCurrent; /*!< card current limit */
|
||||
sdmmc_operation_voltage_t operationVoltage; /*!< card operation voltage */
|
||||
} sd_card_t;
|
||||
|
||||
/*************************************************************************************************
|
||||
* API
|
||||
************************************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name SDCARD Function
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the card on a specific host controller.
|
||||
* @deprecated Do not use this function. It has been superceded by @ref SD_HostInit,SD_CardInit.
|
||||
|
||||
* This function initializes the card on a specific host controller, it is consist of
|
||||
* host init, card detect, card init function, however user can ignore this high level function,
|
||||
* instead of use the low level function, such as SD_CardInit, SD_HostInit, SD_CardDetect.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @retval kStatus_SDMMC_HostNotReady host is not ready.
|
||||
* @retval kStatus_SDMMC_GoIdleFailed Go idle failed.
|
||||
* @retval kStatus_SDMMC_NotSupportYet Card not support.
|
||||
* @retval kStatus_SDMMC_SendOperationConditionFailed Send operation condition failed.
|
||||
* @retval kStatus_SDMMC_AllSendCidFailed Send CID failed.
|
||||
* @retval kStatus_SDMMC_SendRelativeAddressFailed Send relative address failed.
|
||||
* @retval kStatus_SDMMC_SendCsdFailed Send CSD failed.
|
||||
* @retval kStatus_SDMMC_SelectCardFailed Send SELECT_CARD command failed.
|
||||
* @retval kStatus_SDMMC_SendScrFailed Send SCR failed.
|
||||
* @retval kStatus_SDMMC_SetBusWidthFailed Set bus width failed.
|
||||
* @retval kStatus_SDMMC_SwitchHighSpeedFailed Switch high speed failed.
|
||||
* @retval kStatus_SDMMC_SetCardBlockSizeFailed Set card block size failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t SD_Init(sd_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes the card.
|
||||
* @deprecated Do not use this function. It has been superceded by @ref SD_HostDeinit,SD_CardDeinit.
|
||||
* This function deinitializes the specific card and host.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*/
|
||||
void SD_Deinit(sd_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief Initializes the card.
|
||||
*
|
||||
* This function initializes the card only, make sure the host is ready when call this function,
|
||||
* otherwise it will return kStatus_SDMMC_HostNotReady.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @retval kStatus_SDMMC_HostNotReady host is not ready.
|
||||
* @retval kStatus_SDMMC_GoIdleFailed Go idle failed.
|
||||
* @retval kStatus_SDMMC_NotSupportYet Card not support.
|
||||
* @retval kStatus_SDMMC_SendOperationConditionFailed Send operation condition failed.
|
||||
* @retval kStatus_SDMMC_AllSendCidFailed Send CID failed.
|
||||
* @retval kStatus_SDMMC_SendRelativeAddressFailed Send relative address failed.
|
||||
* @retval kStatus_SDMMC_SendCsdFailed Send CSD failed.
|
||||
* @retval kStatus_SDMMC_SelectCardFailed Send SELECT_CARD command failed.
|
||||
* @retval kStatus_SDMMC_SendScrFailed Send SCR failed.
|
||||
* @retval kStatus_SDMMC_SetBusWidthFailed Set bus width failed.
|
||||
* @retval kStatus_SDMMC_SwitchHighSpeedFailed Switch high speed failed.
|
||||
* @retval kStatus_SDMMC_SetCardBlockSizeFailed Set card block size failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t SD_CardInit(sd_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes the card.
|
||||
*
|
||||
* This function deinitializes the specific card.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*/
|
||||
void SD_CardDeinit(sd_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief initialize the host.
|
||||
*
|
||||
* This function deinitializes the specific host.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*/
|
||||
status_t SD_HostInit(sd_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes the host.
|
||||
*
|
||||
* This function deinitializes the host.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*/
|
||||
void SD_HostDeinit(sd_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief reset the host.
|
||||
*
|
||||
* This function reset the specific host.
|
||||
*
|
||||
* @param host host descriptor.
|
||||
*/
|
||||
void SD_HostReset(SDMMCHOST_CONFIG *host);
|
||||
|
||||
/*!
|
||||
* @brief power on card.
|
||||
*
|
||||
* The power on operation depend on host or the user define power on function.
|
||||
* @param base host base address.
|
||||
* @param pwr user define power control configuration
|
||||
*/
|
||||
void SD_PowerOnCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr);
|
||||
|
||||
/*!
|
||||
* @brief power off card.
|
||||
*
|
||||
* The power off operation depend on host or the user define power on function.
|
||||
* @param base host base address.
|
||||
* @param pwr user define power control configuration
|
||||
*/
|
||||
void SD_PowerOffCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr);
|
||||
|
||||
/*!
|
||||
* @brief sd wait card detect function.
|
||||
*
|
||||
* Detect card through GPIO, CD, DATA3.
|
||||
*
|
||||
* @param card card descriptor.
|
||||
* @param card detect configuration
|
||||
* @param waitCardStatus wait card detect status
|
||||
*/
|
||||
status_t SD_WaitCardDetectStatus(SDMMCHOST_TYPE *hostBase, const sdmmchost_detect_card_t *cd, bool waitCardStatus);
|
||||
|
||||
/*!
|
||||
* @brief sd card present check function.
|
||||
*
|
||||
* @param card card descriptor.
|
||||
*/
|
||||
bool SD_IsCardPresent(sd_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief Checks whether the card is write-protected.
|
||||
*
|
||||
* This function checks if the card is write-protected via the CSD register.
|
||||
*
|
||||
* @param card The specific card.
|
||||
* @retval true Card is read only.
|
||||
* @retval false Card isn't read only.
|
||||
*/
|
||||
bool SD_CheckReadOnly(sd_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief Send SELECT_CARD command to set the card to be transfer state or not.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param isSelected True to set the card into transfer state, false to disselect.
|
||||
* @retval kStatus_SDMMC_TransferFailed Transfer failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t SD_SelectCard(sd_card_t *card, bool isSelected);
|
||||
|
||||
/*!
|
||||
* @brief Send ACMD13 to get the card current status.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @retval kStatus_SDMMC_TransferFailed Transfer failed.
|
||||
* @retval kStatus_SDMMC_SendApplicationCommandFailed send application command failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t SD_ReadStatus(sd_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief Reads blocks from the specific card.
|
||||
*
|
||||
* This function reads blocks from the specific card with default block size defined by the
|
||||
* SDHC_CARD_DEFAULT_BLOCK_SIZE.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param buffer The buffer to save the data read from card.
|
||||
* @param startBlock The start block index.
|
||||
* @param blockCount The number of blocks to read.
|
||||
* @retval kStatus_InvalidArgument Invalid argument.
|
||||
* @retval kStatus_SDMMC_CardNotSupport Card not support.
|
||||
* @retval kStatus_SDMMC_NotSupportYet Not support now.
|
||||
* @retval kStatus_SDMMC_WaitWriteCompleteFailed Send status failed.
|
||||
* @retval kStatus_SDMMC_TransferFailed Transfer failed.
|
||||
* @retval kStatus_SDMMC_StopTransmissionFailed Stop transmission failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t SD_ReadBlocks(sd_card_t *card, uint8_t *buffer, uint32_t startBlock, uint32_t blockCount);
|
||||
|
||||
/*!
|
||||
* @brief Writes blocks of data to the specific card.
|
||||
*
|
||||
* This function writes blocks to the specific card with default block size 512 bytes.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param buffer The buffer holding the data to be written to the card.
|
||||
* @param startBlock The start block index.
|
||||
* @param blockCount The number of blocks to write.
|
||||
* @retval kStatus_InvalidArgument Invalid argument.
|
||||
* @retval kStatus_SDMMC_NotSupportYet Not support now.
|
||||
* @retval kStatus_SDMMC_CardNotSupport Card not support.
|
||||
* @retval kStatus_SDMMC_WaitWriteCompleteFailed Send status failed.
|
||||
* @retval kStatus_SDMMC_TransferFailed Transfer failed.
|
||||
* @retval kStatus_SDMMC_StopTransmissionFailed Stop transmission failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t SD_WriteBlocks(sd_card_t *card, const uint8_t *buffer, uint32_t startBlock, uint32_t blockCount);
|
||||
|
||||
/*!
|
||||
* @brief Erases blocks of the specific card.
|
||||
*
|
||||
* This function erases blocks of the specific card with default block size 512 bytes.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param startBlock The start block index.
|
||||
* @param blockCount The number of blocks to erase.
|
||||
* @retval kStatus_InvalidArgument Invalid argument.
|
||||
* @retval kStatus_SDMMC_WaitWriteCompleteFailed Send status failed.
|
||||
* @retval kStatus_SDMMC_TransferFailed Transfer failed.
|
||||
* @retval kStatus_SDMMC_WaitWriteCompleteFailed Send status failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t SD_EraseBlocks(sd_card_t *card, uint32_t startBlock, uint32_t blockCount);
|
||||
|
||||
/*!
|
||||
* @brief select card driver strength
|
||||
* select card driver strength
|
||||
* @param card Card descriptor.
|
||||
* @param driverStrength Driver strength
|
||||
*/
|
||||
status_t SD_SetDriverStrength(sd_card_t *card, sd_driver_strength_t driverStrength);
|
||||
|
||||
/*!
|
||||
* @brief select max current
|
||||
* select max operation current
|
||||
* @param card Card descriptor.
|
||||
* @param maxCurrent Max current
|
||||
*/
|
||||
status_t SD_SetMaxCurrent(sd_card_t *card, sd_max_current_t maxCurrent);
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
/*! @} */
|
||||
#endif /* _FSL_SD_H_*/
|
|
@ -0,0 +1,507 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef _FSL_SDIO_H_
|
||||
#define _FSL_SDIO_H_
|
||||
|
||||
#include "fsl_sdmmc_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup SDIOCARD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
/*! @brief Middleware version. */
|
||||
#define FSL_SDIO_DRIVER_VERSION (MAKE_VERSION(2U, 2U, 11U)) /*2.2.11*/
|
||||
|
||||
/*!@brief sdio device support maximum IO number */
|
||||
#ifndef FSL_SDIO_MAX_IO_NUMS
|
||||
#define FSL_SDIO_MAX_IO_NUMS (7U)
|
||||
#endif
|
||||
/*!@brief sdio card descriptor */
|
||||
typedef struct _sdio_card sdio_card_t;
|
||||
/*!@brief sdio io handler */
|
||||
typedef void (*sdio_io_irq_handler_t)(sdio_card_t *card, uint32_t func);
|
||||
/*! @brief sdio io read/write direction */
|
||||
typedef enum _sdio_io_direction
|
||||
{
|
||||
kSDIO_IORead = 0U, /*!< io read */
|
||||
kSDIO_IOWrite = 1U, /*!< io write */
|
||||
} sdio_io_direction_t;
|
||||
|
||||
/*!
|
||||
* @brief SDIO card state
|
||||
*
|
||||
* Define the card structure including the necessary fields to identify and describe the card.
|
||||
*/
|
||||
struct _sdio_card
|
||||
{
|
||||
SDMMCHOST_CONFIG host; /*!< Host information */
|
||||
sdiocard_usr_param_t usrParam; /*!< user parameter */
|
||||
bool noInternalAlign; /*!< use this flag to disable sdmmc align. If disable, sdmmc will not make sure the
|
||||
data buffer address is word align, otherwise all the transfer are align to low level driver */
|
||||
bool isHostReady; /*!< use this flag to indicate if need host re-init or not*/
|
||||
bool memPresentFlag; /*!< indicate if memory present */
|
||||
|
||||
uint32_t busClock_Hz; /*!< SD bus clock frequency united in Hz */
|
||||
uint32_t relativeAddress; /*!< Relative address of the card */
|
||||
uint8_t sdVersion; /*!< SD version */
|
||||
sd_timing_mode_t currentTiming; /*!< current timing mode */
|
||||
sd_driver_strength_t driverStrength; /*!< driver strength */
|
||||
sd_max_current_t maxCurrent; /*!< card current limit */
|
||||
sdmmc_operation_voltage_t operationVoltage; /*!< card operation voltage */
|
||||
|
||||
uint8_t sdioVersion; /*!< SDIO version */
|
||||
uint8_t cccrVersioin; /*!< CCCR version */
|
||||
uint8_t ioTotalNumber; /*!< total number of IO function */
|
||||
uint32_t cccrflags; /*!< Flags in _sd_card_flag */
|
||||
uint32_t io0blockSize; /*!< record the io0 block size*/
|
||||
uint32_t ocr; /*!< Raw OCR content, only 24bit avalible for SDIO card */
|
||||
uint32_t commonCISPointer; /*!< point to common CIS */
|
||||
sdio_common_cis_t commonCIS; /*!< CIS table */
|
||||
|
||||
/* io registers/IRQ handler */
|
||||
sdio_fbr_t ioFBR[FSL_SDIO_MAX_IO_NUMS]; /*!< FBR table */
|
||||
sdio_func_cis_t funcCIS[FSL_SDIO_MAX_IO_NUMS]; /*!< function CIS table*/
|
||||
sdio_io_irq_handler_t ioIRQHandler[FSL_SDIO_MAX_IO_NUMS]; /*!< io IRQ handler */
|
||||
uint8_t ioIntIndex; /*!< used to record current enabled io interrupt index */
|
||||
uint8_t ioIntNums; /*!< used to record total enabled io interrupt numbers */
|
||||
};
|
||||
|
||||
/*************************************************************************************************
|
||||
* API
|
||||
************************************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
/*!
|
||||
* @name Initialization and deinitialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief SDIO card init function
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @retval kStatus_SDMMC_GoIdleFailed
|
||||
* @retval kStatus_SDMMC_HandShakeOperationConditionFailed
|
||||
* @retval kStatus_SDMMC_SDIO_InvalidCard
|
||||
* @retval kStatus_SDMMC_SDIO_InvalidVoltage
|
||||
* @retval kStatus_SDMMC_SendRelativeAddressFailed
|
||||
* @retval kStatus_SDMMC_SelectCardFailed
|
||||
* @retval kStatus_SDMMC_SDIO_SwitchHighSpeedFail
|
||||
* @retval kStatus_SDMMC_SDIO_ReadCISFail
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_Init(sdio_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief SDIO card deinit, include card and host deinit.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*/
|
||||
void SDIO_Deinit(sdio_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief Initializes the card.
|
||||
*
|
||||
* This function initializes the card only, make sure the host is ready when call this function,
|
||||
* otherwise it will return kStatus_SDMMC_HostNotReady.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @retval kStatus_SDMMC_HostNotReady host is not ready.
|
||||
* @retval kStatus_SDMMC_GoIdleFailed Go idle failed.
|
||||
* @retval kStatus_SDMMC_NotSupportYet Card not support.
|
||||
* @retval kStatus_SDMMC_SendOperationConditionFailed Send operation condition failed.
|
||||
* @retval kStatus_SDMMC_AllSendCidFailed Send CID failed.
|
||||
* @retval kStatus_SDMMC_SendRelativeAddressFailed Send relative address failed.
|
||||
* @retval kStatus_SDMMC_SendCsdFailed Send CSD failed.
|
||||
* @retval kStatus_SDMMC_SelectCardFailed Send SELECT_CARD command failed.
|
||||
* @retval kStatus_SDMMC_SendScrFailed Send SCR failed.
|
||||
* @retval kStatus_SDMMC_SetBusWidthFailed Set bus width failed.
|
||||
* @retval kStatus_SDMMC_SwitchHighSpeedFailed Switch high speed failed.
|
||||
* @retval kStatus_SDMMC_SetCardBlockSizeFailed Set card block size failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t SDIO_CardInit(sdio_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes the card.
|
||||
*
|
||||
* This function deinitializes the specific card.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*/
|
||||
void SDIO_CardDeinit(sdio_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief initialize the host.
|
||||
*
|
||||
* This function deinitializes the specific host.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*/
|
||||
status_t SDIO_HostInit(sdio_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes the host.
|
||||
*
|
||||
* This function deinitializes the host.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*/
|
||||
void SDIO_HostDeinit(sdio_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief reset the host.
|
||||
*
|
||||
* This function reset the specific host.
|
||||
*
|
||||
* @param host host descriptor.
|
||||
*/
|
||||
void SDIO_HostReset(SDMMCHOST_CONFIG *host);
|
||||
|
||||
/*!
|
||||
* @brief power on card.
|
||||
*
|
||||
* The power on operation depend on host or the user define power on function.
|
||||
* @param base host base address.
|
||||
* @param pwr user define power control configuration
|
||||
*/
|
||||
void SDIO_PowerOnCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr);
|
||||
|
||||
/*!
|
||||
* @brief power on card.
|
||||
*
|
||||
* The power off operation depend on host or the user define power on function.
|
||||
* @param base host base address.
|
||||
* @param pwr user define power control configuration
|
||||
*/
|
||||
void SDIO_PowerOffCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr);
|
||||
|
||||
/*!
|
||||
* @brief set SDIO card to inactive state
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_CardInActive(sdio_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief get SDIO card capability
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param function IO number
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_GetCardCapability(sdio_card_t *card, sdio_func_num_t func);
|
||||
|
||||
/*!
|
||||
* @brief set SDIO card block size
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param function io number
|
||||
* @param block size
|
||||
* @retval kStatus_SDMMC_SetCardBlockSizeFailed
|
||||
* @retval kStatus_SDMMC_SDIO_InvalidArgument
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_SetBlockSize(sdio_card_t *card, sdio_func_num_t func, uint32_t blockSize);
|
||||
|
||||
/*!
|
||||
* @brief set SDIO card reset
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_CardReset(sdio_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief set SDIO card data bus width
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param data bus width
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_SetDataBusWidth(sdio_card_t *card, sdio_bus_width_t busWidth);
|
||||
|
||||
/*!
|
||||
* @brief switch the card to high speed
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_SDMMC_SDIO_SwitchHighSpeedFail
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_SwitchToHighSpeed(sdio_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief read SDIO card CIS for each function
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param function io number
|
||||
* @param tuple code list
|
||||
* @param tuple code number
|
||||
* @retval kStatus_SDMMC_SDIO_ReadCISFail
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_ReadCIS(sdio_card_t *card, sdio_func_num_t func, const uint32_t *tupleList, uint32_t tupleNum);
|
||||
|
||||
/*!
|
||||
* @brief sdio wait card detect function.
|
||||
*
|
||||
* Detect card through GPIO, CD, DATA3.
|
||||
*
|
||||
* @param card card descriptor.
|
||||
* @param card detect configuration
|
||||
* @param waitCardStatus wait card detect status
|
||||
*/
|
||||
status_t SDIO_WaitCardDetectStatus(SDMMCHOST_TYPE *hostBase,
|
||||
const sdmmchost_detect_card_t *cd,
|
||||
bool waitCardStatus);
|
||||
|
||||
/*!
|
||||
* @brief sdio card present check function.
|
||||
*
|
||||
* @param card card descriptor.
|
||||
*/
|
||||
bool SDIO_IsCardPresent(sdio_card_t *card);
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name IO operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief IO direct write transfer function
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param function IO numner
|
||||
* @param register address
|
||||
* @param the data pinter to write
|
||||
* @param raw flag, indicate read after write or write only
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_IO_Write_Direct(sdio_card_t *card, sdio_func_num_t func, uint32_t regAddr, uint8_t *data, bool raw);
|
||||
|
||||
/*!
|
||||
* @brief IO direct read transfer function
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param function IO number
|
||||
* @param register address
|
||||
* @param data pointer to read
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_IO_Read_Direct(sdio_card_t *card, sdio_func_num_t func, uint32_t regAddr, uint8_t *data);
|
||||
|
||||
/*!
|
||||
* @brief IO direct read/write transfer function
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param direction io access direction, please reference sdio_io_direction_t.
|
||||
* @param function IO number
|
||||
* @param register address
|
||||
* @param dataIn data to write
|
||||
* @param dataOut data pointer for readback data, support both for read and write, when application want readback
|
||||
* the data after write command, dataOut should not be NULL.
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
|
||||
status_t SDIO_IO_RW_Direct(sdio_card_t *card,
|
||||
sdio_io_direction_t direction,
|
||||
sdio_func_num_t func,
|
||||
uint32_t regAddr,
|
||||
uint8_t dataIn,
|
||||
uint8_t *dataOut);
|
||||
|
||||
/*!
|
||||
* @brief IO extended write transfer function
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param function IO number
|
||||
* @param register address
|
||||
* @param data buffer to write
|
||||
* @param data count
|
||||
* @param write flags
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_SDMMC_SDIO_InvalidArgument
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_IO_Write_Extended(
|
||||
sdio_card_t *card, sdio_func_num_t func, uint32_t regAddr, uint8_t *buffer, uint32_t count, uint32_t flags);
|
||||
/*!
|
||||
* @brief IO extended read transfer function
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param function IO number
|
||||
* @param register address
|
||||
* @param data buffer to read
|
||||
* @param data count
|
||||
* @param write flags
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_SDMMC_SDIO_InvalidArgument
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_IO_Read_Extended(
|
||||
sdio_card_t *card, sdio_func_num_t func, uint32_t regAddr, uint8_t *buffer, uint32_t count, uint32_t flags);
|
||||
/*!
|
||||
* @brief enable IO interrupt
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param function IO number
|
||||
* @param enable/disable flag
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_EnableIOInterrupt(sdio_card_t *card, sdio_func_num_t func, bool enable);
|
||||
|
||||
/*!
|
||||
* @brief enable IO and wait IO ready
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param function IO number
|
||||
* @param enable/disable flag
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_EnableIO(sdio_card_t *card, sdio_func_num_t func, bool enable);
|
||||
|
||||
/*!
|
||||
* @brief select IO
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param function IO number
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_SelectIO(sdio_card_t *card, sdio_func_num_t func);
|
||||
|
||||
/*!
|
||||
* @brief Abort IO transfer
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param function IO number
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_AbortIO(sdio_card_t *card, sdio_func_num_t func);
|
||||
|
||||
/*!
|
||||
* @brief Set driver strength.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param driverStrength target driver strength.
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_SetDriverStrength(sdio_card_t *card, sd_driver_strength_t driverStrength);
|
||||
|
||||
/*!
|
||||
* @brief Enable/Disable Async interrupt.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param func function io number.
|
||||
* @param enable true is enable, false is disable.
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_EnableAsyncInterrupt(sdio_card_t *card, bool enable);
|
||||
|
||||
/*!
|
||||
* @brief Get pending interrupt.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param pendingInt pointer store pending interrupt
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_GetPendingInterrupt(sdio_card_t *card, uint8_t *pendingInt);
|
||||
|
||||
/*!
|
||||
* @brief sdio card io transfer function.
|
||||
* This function can be used for trnansfer direct/extend command.
|
||||
* Please pay attention to the non-align data buffer address transfer,
|
||||
* if data buffer address can not meet host controller internal DMA requirement, sdio driver will try to use
|
||||
internal align buffer if data size is not bigger than internal buffer size,
|
||||
* Align address transfer always can get a better performance, so if application want sdio driver make sure buffer
|
||||
address align,
|
||||
* please redefine the SDMMC_GLOBAL_BUFFER_SIZE macro to a value which is big enough for your application.
|
||||
*
|
||||
* @param card card descriptor.
|
||||
* @param cmd command to transfer
|
||||
* @param argument argument to transfer
|
||||
* @param blockSize used for block mode.
|
||||
* @param txData tx buffer pointer or NULL
|
||||
* @param rxData rx buffer pointer or NULL
|
||||
* @param dataSize transfer data size
|
||||
* @param response reponse pointer, if application want read response back, please set it to a NON-NULL pointer.
|
||||
|
||||
*/
|
||||
status_t SDIO_IO_Transfer(sdio_card_t *card,
|
||||
sdio_command_t cmd,
|
||||
uint32_t argument,
|
||||
uint32_t blockSize,
|
||||
uint8_t *txData,
|
||||
uint8_t *rxData,
|
||||
uint16_t dataSize,
|
||||
uint32_t *response);
|
||||
|
||||
/*!
|
||||
* @brief sdio set io IRQ handler.
|
||||
*
|
||||
* @param card card descriptor.
|
||||
* @param func function io number.
|
||||
* @param handler, io IRQ handler.
|
||||
*/
|
||||
void SDIO_SetIOIRQHandler(sdio_card_t *card, sdio_func_num_t func, sdio_io_irq_handler_t handler);
|
||||
|
||||
/*!
|
||||
* @brief sdio card io pending interrupt handle function.
|
||||
* This function is used to handle the pending io interrupt.
|
||||
* To reigster a IO IRQ handler,
|
||||
* @code
|
||||
* //initialization
|
||||
* SDIO_EnableIOInterrupt(card, 0, true);
|
||||
* SDIO_SetIOIRQHandler(card, 0, func0_handler);
|
||||
* //call it in interrupt callback
|
||||
* SDIO_HandlePendingIOInterrupt(card);
|
||||
* @code
|
||||
* To releae a IO IRQ handler,
|
||||
* @code
|
||||
* SDIO_EnableIOInterrupt(card, 0, false);
|
||||
* SDIO_SetIOIRQHandler(card, 0, NULL);
|
||||
* @code
|
||||
* @param card card descriptor.
|
||||
*
|
||||
* @retval kStatus_SDMMC_TransferFailed
|
||||
* @retval kStatus_Success
|
||||
*/
|
||||
status_t SDIO_HandlePendingIOInterrupt(sdio_card_t *card);
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
/*! @} */
|
||||
#endif /* _FSL_SDIO_H_*/
|
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_SDMMC_COMMON_H_
|
||||
#define _FSL_SDMMC_COMMON_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "fsl_sdmmc_host.h"
|
||||
#include "fsl_sdmmc_spec.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup CARD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
/*! @brief Middleware version. */
|
||||
#define FSL_SDMMC_DRIVER_VERSION (MAKE_VERSION(2U, 2U, 11U)) /*2.2.11*/
|
||||
|
||||
/*! @brief Reverse byte sequence in uint32_t */
|
||||
#define SWAP_WORD_BYTE_SEQUENCE(x) (__REV(x))
|
||||
/*! @brief Reverse byte sequence for each half word in uint32_t */
|
||||
#define SWAP_HALF_WROD_BYTE_SEQUENCE(x) (__REV16(x))
|
||||
/*! @brief Maximum loop count to check the card operation voltage range */
|
||||
#define FSL_SDMMC_MAX_VOLTAGE_RETRIES (1000U)
|
||||
/*! @brief Maximum loop count to send the cmd */
|
||||
#define FSL_SDMMC_MAX_CMD_RETRIES (10U)
|
||||
/*! @brief Default block size */
|
||||
#define FSL_SDMMC_DEFAULT_BLOCK_SIZE (512U)
|
||||
#ifndef SDMMC_GLOBAL_BUFFER_SIZE
|
||||
/*! @brief SDMMC global data buffer size, word unit*/
|
||||
#define SDMMC_GLOBAL_BUFFER_SIZE (128U)
|
||||
#endif
|
||||
/*! @brief SDMMC enable software tuning */
|
||||
#define SDMMC_ENABLE_SOFTWARE_TUNING (0U)
|
||||
/* Common definition for cache line size align */
|
||||
#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
|
||||
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
|
||||
#if defined(FSL_FEATURE_L2DCACHE_LINESIZE_BYTE)
|
||||
#define SDMMC_DATA_BUFFER_ALIGN_CACHE MAX(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE, FSL_FEATURE_L2DCACHE_LINESIZE_BYTE)
|
||||
#else
|
||||
#define SDMMC_DATA_BUFFER_ALIGN_CACHE FSL_FEATURE_L1DCACHE_LINESIZE_BYTE
|
||||
#endif
|
||||
#else
|
||||
#define SDMMC_DATA_BUFFER_ALIGN_CACHE 1
|
||||
#endif
|
||||
#else
|
||||
#define SDMMC_DATA_BUFFER_ALIGN_CACHE 1
|
||||
#endif
|
||||
|
||||
/*! @brief SD/MMC error log. */
|
||||
#if defined SDMMC_ENABLE_LOG_PRINT
|
||||
#include "fsl_debug_console.h"
|
||||
#define SDMMC_LOG(...) PRINTF(__VA_ARGS__)
|
||||
#else
|
||||
#define SDMMC_LOG(format, ...)
|
||||
#endif
|
||||
|
||||
/*! @brief SD/MMC card API's running status. */
|
||||
enum _sdmmc_status
|
||||
{
|
||||
kStatus_SDMMC_NotSupportYet = MAKE_STATUS(kStatusGroup_SDMMC, 0U), /*!< Haven't supported */
|
||||
kStatus_SDMMC_TransferFailed = MAKE_STATUS(kStatusGroup_SDMMC, 1U), /*!< Send command failed */
|
||||
kStatus_SDMMC_SetCardBlockSizeFailed = MAKE_STATUS(kStatusGroup_SDMMC, 2U), /*!< Set block size failed */
|
||||
kStatus_SDMMC_HostNotSupport = MAKE_STATUS(kStatusGroup_SDMMC, 3U), /*!< Host doesn't support */
|
||||
kStatus_SDMMC_CardNotSupport = MAKE_STATUS(kStatusGroup_SDMMC, 4U), /*!< Card doesn't support */
|
||||
kStatus_SDMMC_AllSendCidFailed = MAKE_STATUS(kStatusGroup_SDMMC, 5U), /*!< Send CID failed */
|
||||
kStatus_SDMMC_SendRelativeAddressFailed = MAKE_STATUS(kStatusGroup_SDMMC, 6U), /*!< Send relative address failed */
|
||||
kStatus_SDMMC_SendCsdFailed = MAKE_STATUS(kStatusGroup_SDMMC, 7U), /*!< Send CSD failed */
|
||||
kStatus_SDMMC_SelectCardFailed = MAKE_STATUS(kStatusGroup_SDMMC, 8U), /*!< Select card failed */
|
||||
kStatus_SDMMC_SendScrFailed = MAKE_STATUS(kStatusGroup_SDMMC, 9U), /*!< Send SCR failed */
|
||||
kStatus_SDMMC_SetDataBusWidthFailed = MAKE_STATUS(kStatusGroup_SDMMC, 10U), /*!< Set bus width failed */
|
||||
kStatus_SDMMC_GoIdleFailed = MAKE_STATUS(kStatusGroup_SDMMC, 11U), /*!< Go idle failed */
|
||||
kStatus_SDMMC_HandShakeOperationConditionFailed =
|
||||
MAKE_STATUS(kStatusGroup_SDMMC, 12U), /*!< Send Operation Condition failed */
|
||||
kStatus_SDMMC_SendApplicationCommandFailed =
|
||||
MAKE_STATUS(kStatusGroup_SDMMC, 13U), /*!< Send application command failed */
|
||||
kStatus_SDMMC_SwitchFailed = MAKE_STATUS(kStatusGroup_SDMMC, 14U), /*!< Switch command failed */
|
||||
kStatus_SDMMC_StopTransmissionFailed = MAKE_STATUS(kStatusGroup_SDMMC, 15U), /*!< Stop transmission failed */
|
||||
kStatus_SDMMC_WaitWriteCompleteFailed = MAKE_STATUS(kStatusGroup_SDMMC, 16U), /*!< Wait write complete failed */
|
||||
kStatus_SDMMC_SetBlockCountFailed = MAKE_STATUS(kStatusGroup_SDMMC, 17U), /*!< Set block count failed */
|
||||
kStatus_SDMMC_SetRelativeAddressFailed = MAKE_STATUS(kStatusGroup_SDMMC, 18U), /*!< Set relative address failed */
|
||||
kStatus_SDMMC_SwitchBusTimingFailed = MAKE_STATUS(kStatusGroup_SDMMC, 19U), /*!< Switch high speed failed */
|
||||
kStatus_SDMMC_SendExtendedCsdFailed = MAKE_STATUS(kStatusGroup_SDMMC, 20U), /*!< Send EXT_CSD failed */
|
||||
kStatus_SDMMC_ConfigureBootFailed = MAKE_STATUS(kStatusGroup_SDMMC, 21U), /*!< Configure boot failed */
|
||||
kStatus_SDMMC_ConfigureExtendedCsdFailed = MAKE_STATUS(kStatusGroup_SDMMC, 22U), /*!< Configure EXT_CSD failed */
|
||||
kStatus_SDMMC_EnableHighCapacityEraseFailed =
|
||||
MAKE_STATUS(kStatusGroup_SDMMC, 23U), /*!< Enable high capacity erase failed */
|
||||
kStatus_SDMMC_SendTestPatternFailed = MAKE_STATUS(kStatusGroup_SDMMC, 24U), /*!< Send test pattern failed */
|
||||
kStatus_SDMMC_ReceiveTestPatternFailed = MAKE_STATUS(kStatusGroup_SDMMC, 25U), /*!< Receive test pattern failed */
|
||||
kStatus_SDMMC_SDIO_ResponseError = MAKE_STATUS(kStatusGroup_SDMMC, 26U), /*!< sdio response error */
|
||||
kStatus_SDMMC_SDIO_InvalidArgument =
|
||||
MAKE_STATUS(kStatusGroup_SDMMC, 27U), /*!< sdio invalid argument response error */
|
||||
kStatus_SDMMC_SDIO_SendOperationConditionFail =
|
||||
MAKE_STATUS(kStatusGroup_SDMMC, 28U), /*!< sdio send operation condition fail */
|
||||
kStatus_SDMMC_InvalidVoltage = MAKE_STATUS(kStatusGroup_SDMMC, 29U), /*!< invaild voltage */
|
||||
kStatus_SDMMC_SDIO_SwitchHighSpeedFail = MAKE_STATUS(kStatusGroup_SDMMC, 30U), /*!< switch to high speed fail */
|
||||
kStatus_SDMMC_SDIO_ReadCISFail = MAKE_STATUS(kStatusGroup_SDMMC, 31U), /*!< read CIS fail */
|
||||
kStatus_SDMMC_SDIO_InvalidCard = MAKE_STATUS(kStatusGroup_SDMMC, 32U), /*!< invaild SDIO card */
|
||||
kStatus_SDMMC_TuningFail = MAKE_STATUS(kStatusGroup_SDMMC, 33U), /*!< tuning fail */
|
||||
|
||||
kStatus_SDMMC_SwitchVoltageFail = MAKE_STATUS(kStatusGroup_SDMMC, 34U), /*!< switch voltage fail*/
|
||||
kStatus_SDMMC_SwitchVoltage18VFail33VSuccess = MAKE_STATUS(kStatusGroup_SDMMC, 35U), /*!< switch voltage fail*/
|
||||
|
||||
kStatus_SDMMC_ReTuningRequest = MAKE_STATUS(kStatusGroup_SDMMC, 36U), /*!< retuning request */
|
||||
kStatus_SDMMC_SetDriverStrengthFail = MAKE_STATUS(kStatusGroup_SDMMC, 37U), /*!< set driver strength fail */
|
||||
kStatus_SDMMC_SetPowerClassFail = MAKE_STATUS(kStatusGroup_SDMMC, 38U), /*!< set power class fail */
|
||||
kStatus_SDMMC_HostNotReady = MAKE_STATUS(kStatusGroup_SDMMC, 39U), /*!< host controller not ready */
|
||||
kStatus_SDMMC_CardDetectFailed = MAKE_STATUS(kStatusGroup_SDMMC, 40U), /*!< card detect failed */
|
||||
kStatus_SDMMC_AuSizeNotSetProperly = MAKE_STATUS(kStatusGroup_SDMMC, 41U), /*!< AU size not set properly */
|
||||
|
||||
};
|
||||
|
||||
/*! @brief card operation voltage */
|
||||
typedef enum _sdmmc_operation_voltage
|
||||
{
|
||||
kCARD_OperationVoltageNone = 0U, /*!< indicate current voltage setting is not setting by suser*/
|
||||
kCARD_OperationVoltage330V = 1U, /*!< card operation voltage around 3.3v */
|
||||
kCARD_OperationVoltage300V = 2U, /*!< card operation voltage around 3.0v */
|
||||
kCARD_OperationVoltage180V = 3U, /*!< card operation voltage around 1.8v */
|
||||
} sdmmc_operation_voltage_t;
|
||||
|
||||
/*************************************************************************************************
|
||||
* API
|
||||
************************************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
/*!
|
||||
* @name common function
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Selects the card to put it into transfer state.
|
||||
*
|
||||
* @param base SDMMCHOST peripheral base address.
|
||||
* @param transfer SDMMCHOST transfer function.
|
||||
* @param relativeAddress Relative address.
|
||||
* @param isSelected True to put card into transfer state.
|
||||
* @retval kStatus_SDMMC_TransferFailed Transfer failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t SDMMC_SelectCard(SDMMCHOST_TYPE *base,
|
||||
SDMMCHOST_TRANSFER_FUNCTION transfer,
|
||||
uint32_t relativeAddress,
|
||||
bool isSelected);
|
||||
|
||||
/*!
|
||||
* @brief Sends an application command.
|
||||
*
|
||||
* @param base SDMMCHOST peripheral base address.
|
||||
* @param transfer SDMMCHOST transfer function.
|
||||
* @param relativeAddress Card relative address.
|
||||
* @retval kStatus_SDMMC_TransferFailed Transfer failed.
|
||||
* @retval kStatus_SDMMC_CardNotSupport Card doesn't support.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t SDMMC_SendApplicationCommand(SDMMCHOST_TYPE *base,
|
||||
SDMMCHOST_TRANSFER_FUNCTION transfer,
|
||||
uint32_t relativeAddress);
|
||||
|
||||
/*!
|
||||
* @brief Sets the block count.
|
||||
*
|
||||
* @param base SDMMCHOST peripheral base address.
|
||||
* @param transfer SDMMCHOST transfer function.
|
||||
* @param blockCount Block count.
|
||||
* @retval kStatus_SDMMC_TransferFailed Transfer failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t SDMMC_SetBlockCount(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer, uint32_t blockCount);
|
||||
|
||||
/*!
|
||||
* @brief Sets the card to be idle state.
|
||||
*
|
||||
* @param base SDMMCHOST peripheral base address.
|
||||
* @param transfer SDMMCHOST transfer function.
|
||||
* @retval kStatus_SDMMC_TransferFailed Transfer failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t SDMMC_GoIdle(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer);
|
||||
|
||||
/*!
|
||||
* @brief Sets data block size.
|
||||
*
|
||||
* @param base SDMMCHOST peripheral base address.
|
||||
* @param transfer SDMMCHOST transfer function.
|
||||
* @param blockSize Block size.
|
||||
* @retval kStatus_SDMMC_TransferFailed Transfer failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t SDMMC_SetBlockSize(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer, uint32_t blockSize);
|
||||
|
||||
/*!
|
||||
* @brief Sets card to inactive status
|
||||
*
|
||||
* @param base SDMMCHOST peripheral base address.
|
||||
* @param transfer SDMMCHOST transfer function.
|
||||
* @retval kStatus_SDMMC_TransferFailed Transfer failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t SDMMC_SetCardInactive(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer);
|
||||
|
||||
/*!
|
||||
* @brief provide a simple delay function for sdmmc
|
||||
*
|
||||
* @param num Delay num*10000.
|
||||
*/
|
||||
void SDMMC_Delay(uint32_t num);
|
||||
|
||||
/*!
|
||||
* @brief provide a voltage switch function for SD/SDIO card
|
||||
* @deprecated Do not use this function, it has been superceded by SDMMC_SwitchToVoltage.
|
||||
* @param base SDMMCHOST peripheral base address.
|
||||
* @param transfer SDMMCHOST transfer function.
|
||||
*/
|
||||
status_t SDMMC_SwitchVoltage(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer);
|
||||
|
||||
/*!
|
||||
* @brief provide a voltage switch function for SD/SDIO card
|
||||
*
|
||||
* @param base SDMMCHOST peripheral base address.
|
||||
* @param transfer SDMMCHOST transfer function.
|
||||
* @param switchVoltageFunc voltage switch function.
|
||||
* @return error code.
|
||||
*/
|
||||
|
||||
status_t SDMMC_SwitchToVoltage(SDMMCHOST_TYPE *base,
|
||||
SDMMCHOST_TRANSFER_FUNCTION transfer,
|
||||
sdmmchost_card_switch_voltage_t switchVoltageFunc);
|
||||
/*!
|
||||
* @brief excute tuning
|
||||
*
|
||||
* @param base SDMMCHOST peripheral base address.
|
||||
* @param transfer Host transfer function
|
||||
* @param tuningCmd Tuning cmd
|
||||
* @param blockSize Tuning block size
|
||||
*/
|
||||
status_t SDMMC_ExecuteTuning(SDMMCHOST_TYPE *base,
|
||||
SDMMCHOST_TRANSFER_FUNCTION transfer,
|
||||
uint32_t tuningCmd,
|
||||
uint32_t blockSize);
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
/* @} */
|
||||
#endif /* _FSL_SDMMC_COMMON_H_ */
|
|
@ -0,0 +1,780 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_SDMMC_HOST_H
|
||||
#define _FSL_SDMMC_HOST_H
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "board.h"
|
||||
#if defined(FSL_FEATURE_SOC_SDHC_COUNT) && FSL_FEATURE_SOC_SDHC_COUNT > 0U
|
||||
#include "fsl_sdhc.h"
|
||||
#elif defined(FSL_FEATURE_SOC_SDIF_COUNT) && FSL_FEATURE_SOC_SDIF_COUNT > 0U
|
||||
#include "fsl_sdif.h"
|
||||
#elif defined(FSL_FEATURE_SOC_USDHC_COUNT) && FSL_FEATURE_SOC_USDHC_COUNT > 0U
|
||||
#include "fsl_usdhc.h"
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @addtogroup SDMMCHOST
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/* Common definition for support and not support macro */
|
||||
#define SDMMCHOST_NOT_SUPPORT 0U /*!< use this define to indicate the host not support feature*/
|
||||
#define SDMMCHOST_SUPPORT 1U /*!< use this define to indicate the host support feature*/
|
||||
|
||||
/* Common definition for board support SDR104/HS200/HS400 frequency */
|
||||
/* SDR104 mode freq */
|
||||
#if defined BOARD_SD_HOST_SUPPORT_SDR104_FREQ
|
||||
#define SDMMCHOST_SUPPORT_SDR104_FREQ BOARD_SD_HOST_SUPPORT_SDR104_FREQ
|
||||
#else
|
||||
#define SDMMCHOST_SUPPORT_SDR104_FREQ SD_CLOCK_208MHZ
|
||||
#endif
|
||||
/* HS200 mode freq */
|
||||
#if defined BOARD_SD_HOST_SUPPORT_HS200_FREQ
|
||||
#define SDMMCHOST_SUPPORT_HS200_FREQ BOARD_SD_HOST_SUPPORT_HS200_FREQ
|
||||
#else
|
||||
#define SDMMCHOST_SUPPORT_HS200_FREQ MMC_CLOCK_HS200
|
||||
#endif
|
||||
/* HS400 mode freq */
|
||||
#if defined BOARD_SD_HOST_SUPPORT_HS400_FREQ
|
||||
#define SDMMCHOST_SUPPORT_HS400_FREQ BOARD_SD_HOST_SUPPORT_HS400_FREQ
|
||||
#else
|
||||
#define SDMMCHOST_SUPPORT_HS400_FREQ MMC_CLOCK_HS400
|
||||
#endif
|
||||
|
||||
/* Common definition for SDMMCHOST transfer complete timeout */
|
||||
#define SDMMCHOST_TRANSFER_COMPLETE_TIMEOUT (500U)
|
||||
/* Common definition for card detect timeout */
|
||||
#define SDMMCHOST_CARD_DETECT_TIMEOUT (~0U)
|
||||
|
||||
/* Common definition for IRQ */
|
||||
#if defined(__CORTEX_M)
|
||||
#define SDMMCHOST_SET_IRQ_PRIORITY(id, priority) (NVIC_SetPriority(id, priority))
|
||||
#else
|
||||
#define SDMMCHOST_SET_IRQ_PRIORITY(id, priority) (GIC_SetPriority(id, priority))
|
||||
#endif
|
||||
|
||||
#define SDMMCHOST_ENABLE_IRQ(id) (EnableIRQ(id))
|
||||
|
||||
/*********************************************************SDHC**********************************************************/
|
||||
#if (defined(FSL_FEATURE_SOC_SDHC_COUNT) && (FSL_FEATURE_SOC_SDHC_COUNT > 0U))
|
||||
|
||||
/*define host baseaddr ,clk freq, IRQ number*/
|
||||
#define MMC_HOST_BASEADDR BOARD_SDHC_BASEADDR
|
||||
#define MMC_HOST_CLK_FREQ BOARD_SDHC_CLK_FREQ
|
||||
#define MMC_HOST_IRQ BOARD_SDHC_IRQ
|
||||
#define SD_HOST_BASEADDR BOARD_SDHC_BASEADDR
|
||||
#define SD_HOST_CLK_FREQ BOARD_SDHC_CLK_FREQ
|
||||
#define SD_HOST_IRQ BOARD_SDHC_IRQ
|
||||
|
||||
/* define for card bus speed/strength cnofig */
|
||||
#define CARD_BUS_FREQ_50MHZ (0U)
|
||||
#define CARD_BUS_FREQ_100MHZ0 (0U)
|
||||
#define CARD_BUS_FREQ_100MHZ1 (0U)
|
||||
#define CARD_BUS_FREQ_200MHZ (0U)
|
||||
|
||||
#define CARD_BUS_STRENGTH_0 (0U)
|
||||
#define CARD_BUS_STRENGTH_1 (0U)
|
||||
#define CARD_BUS_STRENGTH_2 (0U)
|
||||
#define CARD_BUS_STRENGTH_3 (0U)
|
||||
#define CARD_BUS_STRENGTH_4 (0U)
|
||||
#define CARD_BUS_STRENGTH_5 (0U)
|
||||
#define CARD_BUS_STRENGTH_6 (0U)
|
||||
#define CARD_BUS_STRENGTH_7 (0U)
|
||||
|
||||
#define SDMMCHOST_TYPE SDHC_Type
|
||||
#define SDMMCHOST_CONFIG sdhc_host_t
|
||||
#define SDMMCHOST_TRANSFER sdhc_transfer_t
|
||||
#define SDMMCHOST_COMMAND sdhc_command_t
|
||||
#define SDMMCHOST_DATA sdhc_data_t
|
||||
#define SDMMCHOST_BUS_WIDTH_TYPE sdhc_data_bus_width_t
|
||||
#define SDMMCHOST_CAPABILITY sdhc_capability_t
|
||||
#define SDMMCHOST_BOOT_CONFIG sdhc_boot_config_t
|
||||
|
||||
#define CARD_DATA0_STATUS_MASK (kSDHC_Data0LineLevelFlag)
|
||||
#define CARD_DATA0_NOT_BUSY (kSDHC_Data0LineLevelFlag)
|
||||
#define CARD_DATA1_STATUS_MASK (kSDHC_Data1LineLevelFlag)
|
||||
#define CARD_DATA2_STATUS_MASK (kSDHC_Data2LineLevelFlag)
|
||||
#define CARD_DATA3_STATUS_MASK (kSDHC_Data3LineLevelFlag)
|
||||
|
||||
#define kSDMMCHOST_DATABUSWIDTH1BIT kSDHC_DataBusWidth1Bit /*!< 1-bit mode */
|
||||
#define kSDMMCHOST_DATABUSWIDTH4BIT kSDHC_DataBusWidth4Bit /*!< 4-bit mode */
|
||||
#define kSDMMCHOST_DATABUSWIDTH8BIT kSDHC_DataBusWidth8Bit /*!< 8-bit mode */
|
||||
|
||||
#define SDMMCHOST_STANDARD_TUNING_START (0U) /*!< standard tuning start point */
|
||||
#define SDMMCHOST_TUINIG_STEP (1U) /*!< standard tuning step */
|
||||
#define SDMMCHOST_RETUNING_TIMER_COUNT (4U) /*!< Re-tuning timer */
|
||||
#define SDMMCHOST_TUNING_DELAY_MAX (0x7FU)
|
||||
#define SDMMCHOST_RETUNING_REQUEST (1U)
|
||||
#define SDMMCHOST_TUNING_ERROR (2U)
|
||||
|
||||
/* function pointer define */
|
||||
#define SDMMCHOST_TRANSFER_FUNCTION sdhc_transfer_function_t
|
||||
#define GET_SDMMCHOST_CAPABILITY(base, capability) (SDHC_GetCapability(base, capability))
|
||||
#define GET_SDMMCHOST_STATUS(base) (SDHC_GetPresentStatusFlags(base))
|
||||
#define SDMMCHOST_SET_CARD_CLOCK(base, sourceClock_HZ, busClock_HZ) (SDHC_SetSdClock(base, sourceClock_HZ, busClock_HZ))
|
||||
#define SDMMCHOST_SET_CARD_BUS_WIDTH(base, busWidth) (SDHC_SetDataBusWidth(base, busWidth))
|
||||
#define SDMMCHOST_SEND_CARD_ACTIVE(base, timeout) (SDHC_SetCardActive(base, timeout))
|
||||
#define SDMMCHOST_SWITCH_VOLTAGE180V(base, enable18v)
|
||||
#define SDMMCHOST_SWITCH_VOLTAGE120V(base, enable12v)
|
||||
#define SDMMCHOST_CONFIG_IO_STRENGTH(speed, strength)
|
||||
#define SDMMCHOST_EXECUTE_STANDARD_TUNING_ENABLE(base, flag)
|
||||
#define SDMMCHOST_EXECUTE_STANDARD_TUNING_STATUS(base) (0U)
|
||||
#define SDMMCHOST_EXECUTE_STANDARD_TUNING_RESULT(base) (1U)
|
||||
#define SDMMCHOST_CONFIG_SD_IO(speed, strength)
|
||||
#define SDMMCHOST_CONFIG_MMC_IO(speed, strength)
|
||||
#define SDMMCHOST_ENABLE_DDR_MODE(base, flag, nibblePos)
|
||||
#define SDMMCHOST_FORCE_SDCLOCK_ON(base, enable)
|
||||
#define SDMMCHOST_EXECUTE_MANUAL_TUNING_ENABLE(base, flag)
|
||||
#define SDMMCHOST_ADJUST_MANUAL_TUNING_DELAY(base, delay)
|
||||
#define SDMMCHOST_AUTO_MANUAL_TUNING_ENABLE(base, flag)
|
||||
#define SDMMCHOST_ENABLE_CARD_CLOCK(base, enable) (SDHC_EnableSdClock(base, enable))
|
||||
#define SDMMCHOST_RESET_TUNING(base, timeout)
|
||||
#define SDMMCHOST_CHECK_TUNING_ERROR(base) (0U)
|
||||
#define SDMMCHOST_ADJUST_TUNING_DELAY(base, delay)
|
||||
#define SDMMCHOST_AUTO_STANDARD_RETUNING_TIMER(base)
|
||||
#define SDMMCHOST_TRANSFER_DATA_ERROR kStatus_SDHC_TransferDataFailed
|
||||
#define SDMMCHOST_TRANSFER_CMD_ERROR kStatus_SDHC_SendCommandFailed
|
||||
#define SDMMCHOST_ENABLE_HS400_MODE(base, flag)
|
||||
#define SDMMCHOST_RESET_STROBE_DLL(base)
|
||||
#define SDMMCHOST_ENABLE_STROBE_DLL(base, flag)
|
||||
#define SDMMCHOST_CONFIG_STROBE_DLL(base, delay, updateInterval)
|
||||
#define SDMMCHOST_GET_STROBE_DLL_STATUS(base)
|
||||
/* sd card power */
|
||||
#define SDMMCHOST_INIT_SD_POWER()
|
||||
#define SDMMCHOST_ENABLE_SD_POWER(enable)
|
||||
#define SDMMCHOST_SWITCH_VCC_TO_180V()
|
||||
#define SDMMCHOST_SWITCH_VCC_TO_330V()
|
||||
/* mmc card power */
|
||||
#define SDMMCHOST_INIT_MMC_POWER()
|
||||
#define SDMMCHOST_ENABLE_MMC_POWER(enable)
|
||||
#define SDMMCHOST_ENABLE_TUNING_FLAG(data)
|
||||
#define SDMMCHOST_ENABLE_BOOT_FLAG(data)
|
||||
#define SDMMCHOST_ENABLE_BOOT_CONTINOUS_FLAG(data)
|
||||
#define SDMMCHOST_GET_HOST_CONFIG_BLOCK_SIZE(config) (0U)
|
||||
#define SDMMCHOST_GET_HOST_CONFIG_BLOCK_COUNT(config) (0U)
|
||||
#define SDMMCHOST_GET_HOST_CONFIG_BOOT_MODE(config) (0U)
|
||||
#define SDMMCHOST_EMPTY_CMD_FLAG(command)
|
||||
#define SDMMCHOST_CARD_DETECT_GPIO_INTERRUPT_HANDLER BOARD_SDHC_CD_PORT_IRQ_HANDLER
|
||||
#define SDMMCHOST_CARD_DETECT_IRQ BOARD_SDHC_CD_PORT_IRQ
|
||||
/* sd card detect through host CD */
|
||||
#define SDMMCHOST_CARD_DETECT_INSERT_ENABLE(base) (SDHC_EnableInterruptStatus(base, kSDHC_CardInsertionFlag))
|
||||
#define SDMMCHOST_CARD_DETECT_REMOVE_ENABLE(base) (SDHC_EnableInterruptStatus(base, kSDHC_CardRemovalFlag))
|
||||
#define SDMMCHOST_CARD_DETECT_INSERT_STATUS(base) (SDHC_GetInterruptStatusFlags(base) & kSDHC_CardInsertionFlag)
|
||||
#define SDMMCHOST_CARD_DETECT_REMOVE_STATUS(base) (SDHC_GetInterruptStatusFlags(base, kSDHC_CardRemovalFlag))
|
||||
#define SDMMCHOST_CARD_DETECT_INSERT_INTERRUPT_ENABLE(base) (SDHC_EnableInterruptSignal(base, kSDHC_CardInsertionFlag))
|
||||
#define SDMMCHOST_CARD_DETECT_INSERT_INTERRUPT_DISABLE(base) \
|
||||
(SDHC_DisableInterruptSignal(base, kSDHC_CardInsertionFlag))
|
||||
#define SDMMCHOST_CARD_DETECT_REMOVE_INTERRUPT_ENABLE(base) (SDHC_EnableInterruptSignal(base, kSDHC_CardRemovalFlag))
|
||||
#define SDMMCHOST_CARD_DETECT_DATA3_ENABLE(base, flag) (SDHC_CardDetectByData3(base, flag))
|
||||
#define SDMMCHOST_ENABLE_MMC_BOOT(base, flag)
|
||||
#define SDMMCHOST_SETMMCBOOTCONFIG(base, config) (SDHC_SetMmcBootConfig(base, config))
|
||||
/* define card detect pin voltage level when card inserted */
|
||||
#if defined BOARD_SDHC_CARD_INSERT_CD_LEVEL
|
||||
#define SDMMCHOST_CARD_INSERT_CD_LEVEL BOARD_SDHC_CARD_INSERT_CD_LEVEL
|
||||
#else
|
||||
#define SDMMCHOST_CARD_INSERT_CD_LEVEL (0U)
|
||||
#endif
|
||||
#define SDMMCHOST_AUTO_TUNING_ENABLE(base, flag)
|
||||
#define SDMMCHOST_ENABLE_SDIO_INT(base) \
|
||||
SDHC_EnableInterruptStatus(base, kSDHC_CardInterruptFlag); \
|
||||
SDHC_EnableInterruptSignal(base, kSDHC_CardInterruptFlag)
|
||||
#define SDMMCHOST_DISABLE_SDIO_INT(base) \
|
||||
SDHC_DisableInterruptStatus(base, kSDHC_CardInterruptFlag); \
|
||||
SDHC_DisableInterruptSignal(base, kSDHC_CardInterruptFlag)
|
||||
|
||||
/*! @brief SDHC host capability*/
|
||||
enum _host_capability
|
||||
{
|
||||
kSDMMCHOST_SupportAdma = kSDHC_SupportAdmaFlag,
|
||||
kSDMMCHOST_SupportHighSpeed = kSDHC_SupportHighSpeedFlag,
|
||||
kSDMMCHOST_SupportDma = kSDHC_SupportDmaFlag,
|
||||
kSDMMCHOST_SupportSuspendResume = kSDHC_SupportSuspendResumeFlag,
|
||||
kSDMMCHOST_SupportV330 = kSDHC_SupportV330Flag,
|
||||
kSDMMCHOST_SupportV300 = SDMMCHOST_NOT_SUPPORT,
|
||||
kSDMMCHOST_SupportV180 = SDMMCHOST_NOT_SUPPORT,
|
||||
kSDMMCHOST_SupportV120 = SDMMCHOST_NOT_SUPPORT,
|
||||
kSDMMCHOST_Support4BitBusWidth = kSDHC_Support4BitFlag,
|
||||
kSDMMCHOST_Support8BitBusWidth = kSDHC_Support8BitFlag,
|
||||
kSDMMCHOST_SupportDDR50 = SDMMCHOST_NOT_SUPPORT,
|
||||
kSDMMCHOST_SupportSDR104 = SDMMCHOST_NOT_SUPPORT,
|
||||
kSDMMCHOST_SupportSDR50 = SDMMCHOST_NOT_SUPPORT,
|
||||
kSDMMCHOST_SupportHS200 = SDMMCHOST_NOT_SUPPORT,
|
||||
kSDMMCHOST_SupportHS400 = SDMMCHOST_NOT_SUPPORT,
|
||||
};
|
||||
|
||||
/* Endian mode. */
|
||||
#define SDHC_ENDIAN_MODE kSDHC_EndianModeLittle
|
||||
|
||||
/* DMA mode */
|
||||
#define SDHC_DMA_MODE kSDHC_DmaModeAdma2
|
||||
/* address align */
|
||||
#define SDMMCHOST_DMA_BUFFER_ADDR_ALIGN (SDHC_ADMA2_ADDRESS_ALIGN)
|
||||
|
||||
/* Read/write watermark level. The bigger value indicates DMA has higher read/write performance. */
|
||||
#define SDHC_READ_WATERMARK_LEVEL (0x80U)
|
||||
#define SDHC_WRITE_WATERMARK_LEVEL (0x80U)
|
||||
|
||||
/* ADMA table length united as word.
|
||||
*
|
||||
* SD card driver can't support ADMA1 transfer mode currently.
|
||||
* One ADMA2 table item occupy two words which can transfer maximum 0xFFFFU bytes one time.
|
||||
* The more data to be transferred in one time, the bigger value of SDHC_ADMA_TABLE_WORDS need to be set.
|
||||
*/
|
||||
#define SDHC_ADMA_TABLE_WORDS (8U)
|
||||
|
||||
/*********************************************************SDIF**********************************************************/
|
||||
#elif (defined(FSL_FEATURE_SOC_SDIF_COUNT) && (FSL_FEATURE_SOC_SDIF_COUNT > 0U))
|
||||
|
||||
/*define host baseaddr ,clk freq, IRQ number*/
|
||||
#define MMC_HOST_BASEADDR BOARD_SDIF_BASEADDR
|
||||
#define MMC_HOST_CLK_FREQ BOARD_SDIF_CLK_FREQ
|
||||
#define MMC_HOST_IRQ BOARD_SDIF_IRQ
|
||||
#define SD_HOST_BASEADDR BOARD_SDIF_BASEADDR
|
||||
#define SD_HOST_CLK_FREQ BOARD_SDIF_CLK_FREQ
|
||||
#define SD_HOST_IRQ BOARD_SDIF_IRQ
|
||||
|
||||
/* define for card bus speed/strength cnofig */
|
||||
#define CARD_BUS_FREQ_50MHZ (0U)
|
||||
#define CARD_BUS_FREQ_100MHZ0 (0U)
|
||||
#define CARD_BUS_FREQ_100MHZ1 (0U)
|
||||
#define CARD_BUS_FREQ_200MHZ (0U)
|
||||
|
||||
#define CARD_BUS_STRENGTH_0 (0U)
|
||||
#define CARD_BUS_STRENGTH_1 (0U)
|
||||
#define CARD_BUS_STRENGTH_2 (0U)
|
||||
#define CARD_BUS_STRENGTH_3 (0U)
|
||||
#define CARD_BUS_STRENGTH_4 (0U)
|
||||
#define CARD_BUS_STRENGTH_5 (0U)
|
||||
#define CARD_BUS_STRENGTH_6 (0U)
|
||||
#define CARD_BUS_STRENGTH_7 (0U)
|
||||
|
||||
#define SDMMCHOST_TYPE SDIF_Type
|
||||
#define SDMMCHOST_CONFIG sdif_host_t
|
||||
#define SDMMCHOST_TRANSFER sdif_transfer_t
|
||||
#define SDMMCHOST_COMMAND sdif_command_t
|
||||
#define SDMMCHOST_DATA sdif_data_t
|
||||
#define SDMMCHOST_BUS_WIDTH_TYPE sdif_bus_width_t
|
||||
#define SDMMCHOST_CAPABILITY sdif_capability_t
|
||||
#define SDMMCHOST_BOOT_CONFIG void
|
||||
|
||||
#define CARD_DATA0_STATUS_MASK SDIF_STATUS_DATA_BUSY_MASK
|
||||
#define CARD_DATA0_NOT_BUSY 0U
|
||||
|
||||
#define CARD_DATA1_STATUS_MASK (0U)
|
||||
#define CARD_DATA2_STATUS_MASK (0U)
|
||||
#define CARD_DATA3_STATUS_MASK (0U)
|
||||
|
||||
#define kSDMMCHOST_DATABUSWIDTH1BIT kSDIF_Bus1BitWidth /*!< 1-bit mode */
|
||||
#define kSDMMCHOST_DATABUSWIDTH4BIT kSDIF_Bus4BitWidth /*!< 4-bit mode */
|
||||
#define kSDMMCHOST_DATABUSWIDTH8BIT kSDIF_Bus8BitWidth /*!< 8-bit mode */
|
||||
|
||||
#define SDMMCHOST_STANDARD_TUNING_START (0U) /*!< standard tuning start point */
|
||||
#define SDMMCHOST_TUINIG_STEP (1U) /*!< standard tuning step */
|
||||
#define SDMMCHOST_RETUNING_TIMER_COUNT (4U) /*!< Re-tuning timer */
|
||||
#define SDMMCHOST_TUNING_DELAY_MAX (0x7FU)
|
||||
#define SDMMCHOST_RETUNING_REQUEST (1U)
|
||||
#define SDMMCHOST_TUNING_ERROR (2U)
|
||||
/* function pointer define */
|
||||
#define SDMMCHOST_TRANSFER_FUNCTION sdif_transfer_function_t
|
||||
#define GET_SDMMCHOST_CAPABILITY(base, capability) (SDIF_GetCapability(base, capability))
|
||||
#define GET_SDMMCHOST_STATUS(base) (SDIF_GetControllerStatus(base))
|
||||
#define SDMMCHOST_SET_CARD_CLOCK(base, sourceClock_HZ, busClock_HZ) \
|
||||
(SDIF_SetCardClock(base, sourceClock_HZ, busClock_HZ))
|
||||
#define SDMMCHOST_SET_CARD_BUS_WIDTH(base, busWidth) (SDIF_SetCardBusWidth(base, busWidth))
|
||||
#define SDMMCHOST_SEND_CARD_ACTIVE(base, timeout) (SDIF_SendCardActive(base, timeout))
|
||||
#define SDMMCHOST_SWITCH_VOLTAGE180V(base, enable18v)
|
||||
#define SDMMCHOST_SWITCH_VOLTAGE120V(base, enable12v)
|
||||
#define SDMMCHOST_CONFIG_IO_STRENGTH(speed, strength)
|
||||
#define SDMMCHOST_EXECUTE_STANDARD_TUNING_ENABLE(base, flag)
|
||||
#define SDMMCHOST_EXECUTE_STANDARD_TUNING_STATUS(base) (0U)
|
||||
#define SDMMCHOST_EXECUTE_STANDARD_TUNING_RESULT(base) (1U)
|
||||
#define SDMMCHOST_CONFIG_SD_IO(speed, strength)
|
||||
#define SDMMCHOST_CONFIG_MMC_IO(speed, strength)
|
||||
#define SDMMCHOST_ENABLE_DDR_MODE(base, flag, nibblePos)
|
||||
#define SDMMCHOST_FORCE_SDCLOCK_ON(base, enable)
|
||||
#define SDMMCHOST_EXECUTE_MANUAL_TUNING_ENABLE(base, flag)
|
||||
#define SDMMCHOST_ADJUST_MANUAL_TUNING_DELAY(base, delay)
|
||||
#define SDMMCHOST_AUTO_MANUAL_TUNING_ENABLE(base, flag)
|
||||
#define SDMMCHOST_ENABLE_CARD_CLOCK(base, enable) (SDIF_EnableCardClock(base, enable))
|
||||
#define SDMMCHOST_RESET_TUNING(base, timeout)
|
||||
#define SDMMCHOST_CHECK_TUNING_ERROR(base) (0U)
|
||||
#define SDMMCHOST_ADJUST_TUNING_DELAY(base, delay)
|
||||
#define SDMMCHOST_AUTO_STANDARD_RETUNING_TIMER(base)
|
||||
|
||||
#define SDMMCHOST_ENABLE_HS400_MODE(base, flag)
|
||||
#define SDMMCHOST_RESET_STROBE_DLL(base)
|
||||
#define SDMMCHOST_ENABLE_STROBE_DLL(base, flag)
|
||||
#define SDMMCHOST_CONFIG_STROBE_DLL(base, delay, updateInterval)
|
||||
#define SDMMCHOST_GET_STROBE_DLL_STATUS(base)
|
||||
/* sd card power */
|
||||
#define SDMMCHOST_INIT_SD_POWER()
|
||||
#define SDMMCHOST_ENABLE_SD_POWER(enable)
|
||||
#define SDMMCHOST_SWITCH_VCC_TO_180V()
|
||||
#define SDMMCHOST_SWITCH_VCC_TO_330V()
|
||||
/* mmc card power */
|
||||
#define SDMMCHOST_INIT_MMC_POWER()
|
||||
#define SDMMCHOST_ENABLE_MMC_POWER(enable)
|
||||
#define SDMMCHOST_ENABLE_TUNING_FLAG(data)
|
||||
#define SDMMCHOST_ENABLE_MMC_BOOT(base, flag)
|
||||
#define SDMMCHOST_SETMMCBOOTCONFIG(base, config)
|
||||
#define SDMMCHOST_ENABLE_BOOT_FLAG(data)
|
||||
#define SDMMCHOST_ENABLE_BOOT_CONTINOUS_FLAG(data)
|
||||
#define SDMMCHOST_GET_HOST_CONFIG_BLOCK_SIZE(config) (0U)
|
||||
#define SDMMCHOST_GET_HOST_CONFIG_BLOCK_COUNT(config) (0U)
|
||||
#define SDMMCHOST_GET_HOST_CONFIG_BOOT_MODE(config) (0U)
|
||||
#define SDMMCHOST_EMPTY_CMD_FLAG(command)
|
||||
#define SDMMCHOST_CARD_DETECT_STATUS() BOARD_SDIF_CD_STATUS()
|
||||
#define SDMMCHOST_CARD_DETECT_INIT() BOARD_SDIF_CD_GPIO_INIT()
|
||||
#define SDMMCHOST_CARD_DETECT_INTERRUPT_STATUS() BOARD_SDIF_CD_INTERRUPT_STATUS()
|
||||
#define SDMMCHOST_CARD_DETECT_INTERRUPT_CLEAR(flag) BOARD_SDIF_CD_CLEAR_INTERRUPT(flag)
|
||||
#define SDMMCHOST_CARD_DETECT_GPIO_INTERRUPT_HANDLER BOARD_SDIF_CD_PORT_IRQ_HANDLER
|
||||
#define SDMMCHOST_CARD_DETECT_IRQ BOARD_SDIF_CD_PORT_IRQ
|
||||
#define SDMMCHOST_TRANSFER_DATA_ERROR kStatus_SDIF_DataTransferFail
|
||||
#define SDMMCHOST_TRANSFER_CMD_ERROR kStatus_SDIF_SendCmdFail
|
||||
/* define card detect pin voltage level when card inserted */
|
||||
#if defined BOARD_SDIF_CARD_INSERT_CD_LEVEL
|
||||
#define SDMMCHOST_CARD_INSERT_CD_LEVEL BOARD_SDIF_CARD_INSERT_CD_LEVEL
|
||||
#else
|
||||
#define SDMMCHOST_CARD_INSERT_CD_LEVEL (0U)
|
||||
#endif
|
||||
#define SDMMCHOST_AUTO_TUNING_ENABLE(base, flag)
|
||||
/* sd card detect through host CD */
|
||||
#define SDMMCHOST_CARD_DETECT_INSERT_ENABLE(base) (SDIF_EnableInterrupt(base, kSDIF_CardDetect))
|
||||
#define SDMMCHOST_CARD_DETECT_INSERT_STATUS(base, data3) (SDIF_DetectCardInsert(base, data3))
|
||||
#define SDMMCHOST_ENABLE_SDIO_INT(base)
|
||||
#define SDMMCHOST_DISABLE_SDIO_INT(base)
|
||||
/*! @brief SDIF host capability*/
|
||||
enum _host_capability
|
||||
{
|
||||
kSDMMCHOST_SupportHighSpeed = kSDIF_SupportHighSpeedFlag,
|
||||
kSDMMCHOST_SupportDma = kSDIF_SupportDmaFlag,
|
||||
kSDMMCHOST_SupportSuspendResume = kSDIF_SupportSuspendResumeFlag,
|
||||
kSDMMCHOST_SupportV330 = kSDIF_SupportV330Flag,
|
||||
kSDMMCHOST_SupportV300 = SDMMCHOST_NOT_SUPPORT,
|
||||
kSDMMCHOST_SupportV180 = SDMMCHOST_NOT_SUPPORT,
|
||||
kSDMMCHOST_SupportV120 = SDMMCHOST_NOT_SUPPORT,
|
||||
kSDMMCHOST_Support4BitBusWidth = kSDIF_Support4BitFlag,
|
||||
kSDMMCHOST_Support8BitBusWidth =
|
||||
SDMMCHOST_NOT_SUPPORT, /* mask the 8 bit here,user can change depend on your board */
|
||||
kSDMMCHOST_SupportDDR50 = SDMMCHOST_NOT_SUPPORT,
|
||||
kSDMMCHOST_SupportSDR104 = SDMMCHOST_NOT_SUPPORT,
|
||||
kSDMMCHOST_SupportSDR50 = SDMMCHOST_NOT_SUPPORT,
|
||||
kSDMMCHOST_SupportHS200 = SDMMCHOST_NOT_SUPPORT,
|
||||
kSDMMCHOST_SupportHS400 = SDMMCHOST_NOT_SUPPORT,
|
||||
|
||||
};
|
||||
|
||||
/*! @brief DMA table length united as word
|
||||
* One dma table item occupy four words which can transfer maximum 2*8188 bytes in dual DMA mode
|
||||
* and 8188 bytes in chain mode
|
||||
* The more data to be transferred in one time, the bigger value of SDHC_ADMA_TABLE_WORDS need to be set.
|
||||
* user need check the DMA descriptor table lenght if bigger enough.
|
||||
*/
|
||||
#define SDIF_DMA_TABLE_WORDS (0x40U)
|
||||
/* address align */
|
||||
#define SDMMCHOST_DMA_BUFFER_ADDR_ALIGN (4U)
|
||||
|
||||
/*********************************************************USDHC**********************************************************/
|
||||
#elif (defined(FSL_FEATURE_SOC_USDHC_COUNT) && (FSL_FEATURE_SOC_USDHC_COUNT > 0U))
|
||||
|
||||
/*define host baseaddr ,clk freq, IRQ number*/
|
||||
#define MMC_HOST_BASEADDR BOARD_MMC_HOST_BASEADDR
|
||||
#define MMC_HOST_CLK_FREQ BOARD_MMC_HOST_CLK_FREQ
|
||||
#define MMC_HOST_IRQ BOARD_MMC_HOST_IRQ
|
||||
#define SD_HOST_BASEADDR BOARD_SD_HOST_BASEADDR
|
||||
#define SD_HOST_CLK_FREQ BOARD_SD_HOST_CLK_FREQ
|
||||
#define SD_HOST_IRQ BOARD_SD_HOST_IRQ
|
||||
|
||||
#define SDMMCHOST_TYPE USDHC_Type
|
||||
#define SDMMCHOST_CONFIG usdhc_host_t
|
||||
#define SDMMCHOST_TRANSFER usdhc_transfer_t
|
||||
#define SDMMCHOST_COMMAND usdhc_command_t
|
||||
#define SDMMCHOST_DATA usdhc_data_t
|
||||
#define SDMMCHOST_BOOT_CONFIG usdhc_boot_config_t
|
||||
#define CARD_DATA0_STATUS_MASK (kUSDHC_Data0LineLevelFlag)
|
||||
#define CARD_DATA1_STATUS_MASK (kUSDHC_Data1LineLevelFlag)
|
||||
#define CARD_DATA2_STATUS_MASK (kUSDHC_Data2LineLevelFlag)
|
||||
#define CARD_DATA3_STATUS_MASK (kUSDHC_Data3LineLevelFlag)
|
||||
#define CARD_DATA0_NOT_BUSY (kUSDHC_Data0LineLevelFlag)
|
||||
|
||||
#define SDMMCHOST_BUS_WIDTH_TYPE usdhc_data_bus_width_t
|
||||
#define SDMMCHOST_CAPABILITY usdhc_capability_t
|
||||
|
||||
#define kSDMMCHOST_DATABUSWIDTH1BIT kUSDHC_DataBusWidth1Bit /*!< 1-bit mode */
|
||||
#define kSDMMCHOST_DATABUSWIDTH4BIT kUSDHC_DataBusWidth4Bit /*!< 4-bit mode */
|
||||
#define kSDMMCHOST_DATABUSWIDTH8BIT kUSDHC_DataBusWidth8Bit /*!< 8-bit mode */
|
||||
|
||||
#define SDMMCHOST_STANDARD_TUNING_START (10U) /*!< standard tuning start point */
|
||||
#define SDMMCHOST_TUINIG_STEP (2U) /*!< standard tuning step */
|
||||
#define SDMMCHOST_RETUNING_TIMER_COUNT (0U) /*!< Re-tuning timer */
|
||||
#define SDMMCHOST_TUNING_DELAY_MAX (0x7FU)
|
||||
#define SDMMCHOST_RETUNING_REQUEST kStatus_USDHC_ReTuningRequest
|
||||
#define SDMMCHOST_TUNING_ERROR kStatus_USDHC_TuningError
|
||||
#define SDMMCHOST_TRANSFER_DATA_ERROR kStatus_USDHC_TransferDataFailed
|
||||
#define SDMMCHOST_TRANSFER_CMD_ERROR kStatus_USDHC_SendCommandFailed
|
||||
/* define for card bus speed/strength cnofig */
|
||||
#define CARD_BUS_FREQ_50MHZ (0U)
|
||||
#define CARD_BUS_FREQ_100MHZ0 (1U)
|
||||
#define CARD_BUS_FREQ_100MHZ1 (2U)
|
||||
#define CARD_BUS_FREQ_200MHZ (3U)
|
||||
|
||||
#define CARD_BUS_STRENGTH_0 (0U)
|
||||
#define CARD_BUS_STRENGTH_1 (1U)
|
||||
#define CARD_BUS_STRENGTH_2 (2U)
|
||||
#define CARD_BUS_STRENGTH_3 (3U)
|
||||
#define CARD_BUS_STRENGTH_4 (4U)
|
||||
#define CARD_BUS_STRENGTH_5 (5U)
|
||||
#define CARD_BUS_STRENGTH_6 (6U)
|
||||
#define CARD_BUS_STRENGTH_7 (7U)
|
||||
|
||||
#define SDMMCHOST_STROBE_DLL_DELAY_TARGET (7U)
|
||||
#define SDMMCHOST_STROBE_DLL_DELAY_UPDATE_INTERVAL (4U)
|
||||
|
||||
/* function pointer define */
|
||||
#define SDMMCHOST_TRANSFER_FUNCTION usdhc_transfer_function_t
|
||||
#define GET_SDMMCHOST_CAPABILITY(base, capability) (USDHC_GetCapability(base, capability))
|
||||
#define GET_SDMMCHOST_STATUS(base) (USDHC_GetPresentStatusFlags(base))
|
||||
#define SDMMCHOST_SET_CARD_CLOCK(base, sourceClock_HZ, busClock_HZ) \
|
||||
(USDHC_SetSdClock(base, sourceClock_HZ, busClock_HZ))
|
||||
#define SDMMCHOST_ENABLE_CARD_CLOCK(base, enable)
|
||||
#define SDMMCHOST_FORCE_SDCLOCK_ON(base, enable) (USDHC_ForceClockOn(base, enable))
|
||||
#define SDMMCHOST_SET_CARD_BUS_WIDTH(base, busWidth) (USDHC_SetDataBusWidth(base, busWidth))
|
||||
#define SDMMCHOST_SEND_CARD_ACTIVE(base, timeout) (USDHC_SetCardActive(base, timeout))
|
||||
#define SDMMCHOST_SWITCH_VOLTAGE180V(base, enable18v) (UDSHC_SelectVoltage(base, enable18v))
|
||||
#define SDMMCHOST_SWITCH_VOLTAGE120V(base, enable12v)
|
||||
#define SDMMCHOST_CONFIG_SD_IO(speed, strength) BOARD_SD_Pin_Config(speed, strength)
|
||||
#define SDMMCHOST_CONFIG_MMC_IO(speed, strength) BOARD_MMC_Pin_Config(speed, strength)
|
||||
#define SDMMCHOST_SWITCH_VCC_TO_180V()
|
||||
#define SDMMCHOST_SWITCH_VCC_TO_330V()
|
||||
|
||||
#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
|
||||
#define SDMMCHOST_EXECUTE_STANDARD_TUNING_STATUS(base) (0U)
|
||||
#define SDMMCHOST_EXECUTE_STANDARD_TUNING_RESULT(base) (1U)
|
||||
#define SDMMCHOST_AUTO_STANDARD_RETUNING_TIMER(base)
|
||||
#define SDMMCHOST_EXECUTE_STANDARD_TUNING_ENABLE(base, flag)
|
||||
#define SDMMCHOST_CHECK_TUNING_ERROR(base) (0U)
|
||||
#define SDMMCHOST_ADJUST_TUNING_DELAY(base, delay)
|
||||
#else
|
||||
#define SDMMCHOST_EXECUTE_STANDARD_TUNING_ENABLE(base, flag) \
|
||||
(USDHC_EnableStandardTuning(base, SDMMCHOST_STANDARD_TUNING_START, SDMMCHOST_TUINIG_STEP, flag))
|
||||
#define SDMMCHOST_EXECUTE_STANDARD_TUNING_STATUS(base) (USDHC_GetExecuteStdTuningStatus(base))
|
||||
#define SDMMCHOST_EXECUTE_STANDARD_TUNING_RESULT(base) (USDHC_CheckStdTuningResult(base))
|
||||
#define SDMMCHOST_AUTO_STANDARD_RETUNING_TIMER(base) (USDHC_SetRetuningTimer(base, SDMMCHOST_RETUNING_TIMER_COUNT))
|
||||
#define SDMMCHOST_EXECUTE_MANUAL_TUNING_ENABLE(base, flag) (USDHC_EnableManualTuning(base, flag))
|
||||
#define SDMMCHOST_ADJUST_TUNING_DELAY(base, delay) (USDHC_AdjustDelayForManualTuning(base, delay))
|
||||
#define SDMMCHOST_AUTO_TUNING_ENABLE(base, flag) (USDHC_EnableAutoTuning(base, flag))
|
||||
#define SDMMCHOST_CHECK_TUNING_ERROR(base) (USDHC_CheckTuningError(base))
|
||||
#endif
|
||||
|
||||
#define SDMMCHOST_AUTO_TUNING_CONFIG(base) (USDHC_EnableAutoTuningForCmdAndData(base))
|
||||
#define SDMMCHOST_RESET_TUNING(base, timeout) \
|
||||
{ \
|
||||
(USDHC_Reset(base, kUSDHC_ResetTuning | kUSDHC_ResetData | kUSDHC_ResetCommand, timeout)); \
|
||||
}
|
||||
|
||||
#define SDMMCHOST_ENABLE_DDR_MODE(base, flag, nibblePos) (USDHC_EnableDDRMode(base, flag, nibblePos))
|
||||
|
||||
#if FSL_FEATURE_USDHC_HAS_HS400_MODE
|
||||
#define SDMMCHOST_ENABLE_HS400_MODE(base, flag) (USDHC_EnableHS400Mode(base, flag))
|
||||
#define SDMMCHOST_RESET_STROBE_DLL(base) (USDHC_ResetStrobeDLL(base))
|
||||
#define SDMMCHOST_ENABLE_STROBE_DLL(base, flag) (USDHC_EnableStrobeDLL(base, flag))
|
||||
#define SDMMCHOST_CONFIG_STROBE_DLL(base, delay, updateInterval) (USDHC_ConfigStrobeDLL(base, delay, updateInterval))
|
||||
#define SDMMCHOST_GET_STROBE_DLL_STATUS (base)(USDHC_GetStrobeDLLStatus(base))
|
||||
#else
|
||||
#define SDMMCHOST_ENABLE_HS400_MODE(base, flag)
|
||||
#define SDMMCHOST_RESET_STROBE_DLL(base)
|
||||
#define SDMMCHOST_ENABLE_STROBE_DLL(base, flag)
|
||||
#define SDMMCHOST_CONFIG_STROBE_DLL(base, delay, updateInterval)
|
||||
#define SDMMCHOST_GET_STROBE_DLL_STATUS(base)
|
||||
#endif
|
||||
|
||||
#define SDMMCHOST_ENABLE_MMC_BOOT(base, flag) (USDHC_EnableMmcBoot(base, flag))
|
||||
#define SDMMCHOST_SETMMCBOOTCONFIG(base, config) (USDHC_SetMmcBootConfig(base, config))
|
||||
/* sd card power */
|
||||
#define SDMMCHOST_INIT_SD_POWER() BOARD_USDHC_SDCARD_POWER_CONTROL_INIT()
|
||||
#define SDMMCHOST_ENABLE_SD_POWER(enable) BOARD_USDHC_SDCARD_POWER_CONTROL(enable)
|
||||
/* mmc card power */
|
||||
#define SDMMCHOST_INIT_MMC_POWER() BOARD_USDHC_MMCCARD_POWER_CONTROL_INIT()
|
||||
#define SDMMCHOST_ENABLE_MMC_POWER(enable) BOARD_USDHC_MMCCARD_POWER_CONTROL(enable)
|
||||
/* sd card detect through gpio */
|
||||
#define SDMMCHOST_CARD_DETECT_GPIO_STATUS() BOARD_USDHC_CD_STATUS()
|
||||
#define SDMMCHOST_CARD_DETECT_GPIO_INIT() BOARD_USDHC_CD_GPIO_INIT()
|
||||
#define SDMMCHOST_CARD_DETECT_GPIO_INTERRUPT_STATUS() BOARD_USDHC_CD_INTERRUPT_STATUS()
|
||||
#define SDMMCHOST_CARD_DETECT_GPIO_INTERRUPT_STATUS_CLEAR(flag) BOARD_USDHC_CD_CLEAR_INTERRUPT(flag)
|
||||
#define SDMMCHOST_CARD_DETECT_GPIO_INTERRUPT_HANDLER BOARD_USDHC_CD_PORT_IRQ_HANDLER
|
||||
#define SDMMCHOST_CARD_DETECT_GPIO_IRQ BOARD_USDHC_CD_PORT_IRQ
|
||||
/* sd card detect through host CD */
|
||||
#define SDMMCHOST_CARD_DETECT_INSERT_ENABLE(base) (USDHC_EnableInterruptStatus(base, kUSDHC_CardInsertionFlag))
|
||||
#define SDMMCHOST_CARD_DETECT_REMOVE_ENABLE(base) (USDHC_EnableInterruptStatus(base, kUSDHC_CardRemovalFlag))
|
||||
#define SDMMCHOST_CARD_DETECT_INSERT_STATUS(base) (USDHC_DetectCardInsert(base))
|
||||
#define SDMMCHOST_CARD_DETECT_REMOVE_STATUS(base) (USDHC_GetInterruptStatusFlags(base, kUSDHC_CardRemovalFlag))
|
||||
#define SDMMCHOST_CARD_DETECT_INSERT_INTERRUPT_ENABLE(base) \
|
||||
(USDHC_EnableInterruptSignal(base, kUSDHC_CardInsertionFlag))
|
||||
#define SDMMCHOST_CARD_DETECT_REMOVE_INTERRUPT_ENABLE(base) (USDHC_EnableInterruptSignal(base, kUSDHC_CardRemovalFlag))
|
||||
#define SDMMCHOST_CARD_DETECT_DATA3_ENABLE(base, flag) (USDHC_CardDetectByData3(base, flag))
|
||||
|
||||
/* define card detect pin voltage level when card inserted */
|
||||
#if defined BOARD_USDHC_CARD_INSERT_CD_LEVEL
|
||||
#define SDMMCHOST_CARD_INSERT_CD_LEVEL BOARD_USDHC_CARD_INSERT_CD_LEVEL
|
||||
#else
|
||||
#define SDMMCHOST_CARD_INSERT_CD_LEVEL (0U)
|
||||
#endif
|
||||
#define SDMMCHOST_ENABLE_TUNING_FLAG(data) (data.dataType = kUSDHC_TransferDataTuning)
|
||||
#define SDMMCHOST_ENABLE_BOOT_FLAG(data) (data.dataType = kUSDHC_TransferDataBoot)
|
||||
#define SDMMCHOST_ENABLE_BOOT_CONTINOUS_FLAG(data) (data.dataType = kUSDHC_TransferDataBootcontinous)
|
||||
#define SDMMCHOST_GET_HOST_CONFIG_BLOCK_SIZE(config) (config->blockSize)
|
||||
#define SDMMCHOST_GET_HOST_CONFIG_BLOCK_COUNT(config) (config->blockCount)
|
||||
#define SDMMCHOST_GET_HOST_CONFIG_BOOT_MODE(config) (config->bootMode)
|
||||
#define SDMMCHOST_EMPTY_CMD_FLAG(command) (command.type = kCARD_CommandTypeEmpty)
|
||||
#define SDMMCHOST_ENABLE_SDIO_INT(base) \
|
||||
USDHC_EnableInterruptStatus(base, kUSDHC_CardInterruptFlag); \
|
||||
USDHC_EnableInterruptSignal(base, kUSDHC_CardInterruptFlag)
|
||||
#define SDMMCHOST_DISABLE_SDIO_INT(base) \
|
||||
USDHC_DisableInterruptStatus(base, kUSDHC_CardInterruptFlag); \
|
||||
USDHC_DisableInterruptSignal(base, kUSDHC_CardInterruptFlag)
|
||||
/*! @brief USDHC host capability*/
|
||||
enum _host_capability
|
||||
{
|
||||
kSDMMCHOST_SupportAdma = kUSDHC_SupportAdmaFlag,
|
||||
kSDMMCHOST_SupportHighSpeed = kUSDHC_SupportHighSpeedFlag,
|
||||
kSDMMCHOST_SupportDma = kUSDHC_SupportDmaFlag,
|
||||
kSDMMCHOST_SupportSuspendResume = kUSDHC_SupportSuspendResumeFlag,
|
||||
kSDMMCHOST_SupportV330 = kUSDHC_SupportV330Flag, /* this define should depend on your board config */
|
||||
kSDMMCHOST_SupportV300 = kUSDHC_SupportV300Flag, /* this define should depend on your board config */
|
||||
#if defined(BOARD_SD_SUPPORT_180V) && !BOARD_SD_SUPPORT_180V
|
||||
kSDMMCHOST_SupportV180 = SDMMCHOST_NOT_SUPPORT, /* this define should depend on you board config */
|
||||
#else
|
||||
kSDMMCHOST_SupportV180 = kUSDHC_SupportV180Flag, /* this define should depend on you board config */
|
||||
#endif
|
||||
kSDMMCHOST_SupportV120 = SDMMCHOST_NOT_SUPPORT,
|
||||
kSDMMCHOST_Support4BitBusWidth = kUSDHC_Support4BitFlag,
|
||||
#if defined(BOARD_MMC_SUPPORT_8BIT_BUS)
|
||||
#if BOARD_MMC_SUPPORT_8BIT_BUS
|
||||
kSDMMCHOST_Support8BitBusWidth = kUSDHC_Support8BitFlag,
|
||||
#else
|
||||
kSDMMCHOST_Support8BitBusWidth = SDMMCHOST_NOT_SUPPORT,
|
||||
#endif
|
||||
#else
|
||||
kSDMMCHOST_Support8BitBusWidth = kUSDHC_Support8BitFlag,
|
||||
#endif
|
||||
kSDMMCHOST_SupportDDR50 = kUSDHC_SupportDDR50Flag,
|
||||
kSDMMCHOST_SupportSDR104 = kUSDHC_SupportSDR104Flag,
|
||||
kSDMMCHOST_SupportSDR50 = kUSDHC_SupportSDR50Flag,
|
||||
kSDMMCHOST_SupportHS200 = kUSDHC_SupportSDR104Flag,
|
||||
#if FSL_FEATURE_USDHC_HAS_HS400_MODE
|
||||
kSDMMCHOST_SupportHS400 = SDMMCHOST_SUPPORT
|
||||
#else
|
||||
kSDMMCHOST_SupportHS400 = SDMMCHOST_NOT_SUPPORT,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Endian mode. */
|
||||
#define USDHC_ENDIAN_MODE kUSDHC_EndianModeLittle
|
||||
|
||||
/* DMA mode */
|
||||
#define USDHC_DMA_MODE kUSDHC_DmaModeAdma2
|
||||
/* address align */
|
||||
#define SDMMCHOST_DMA_BUFFER_ADDR_ALIGN (USDHC_ADMA2_ADDRESS_ALIGN)
|
||||
|
||||
/* Read/write watermark level. The bigger value indicates DMA has higher read/write performance. */
|
||||
#define USDHC_READ_WATERMARK_LEVEL (0x80U)
|
||||
#define USDHC_WRITE_WATERMARK_LEVEL (0x80U)
|
||||
|
||||
/* ADMA table length united as word.
|
||||
*
|
||||
* One ADMA2 table item occupy two words which can transfer maximum 0xFFFFU bytes one time.
|
||||
* The more data to be transferred in one time, the bigger value of SDHC_ADMA_TABLE_WORDS need to be set.
|
||||
*/
|
||||
#define USDHC_ADMA_TABLE_WORDS (8U) /* define the ADMA descriptor table length */
|
||||
#define USDHC_ADMA2_ADDR_ALIGN (4U) /* define the ADMA2 descriptor table addr align size */
|
||||
#define USDHC_READ_BURST_LEN (8U) /*!< number of words USDHC read in a single burst */
|
||||
#define USDHC_WRITE_BURST_LEN (8U) /*!< number of words USDHC write in a single burst */
|
||||
#define USDHC_DATA_TIMEOUT (0xFU) /*!< data timeout counter value */
|
||||
|
||||
#endif /* (defined(FSL_FEATURE_SOC_SDHC_COUNT) && (FSL_FEATURE_SOC_SDHC_COUNT > 0U)) */
|
||||
|
||||
/*! @brief card detect callback definition */
|
||||
typedef void (*sdmmchost_cd_callback_t)(bool isInserted, void *userData);
|
||||
|
||||
/*! @brief host Endian mode
|
||||
* corresponding to driver define
|
||||
*/
|
||||
enum _sdmmchost_endian_mode
|
||||
{
|
||||
kSDMMCHOST_EndianModeBig = 0U, /*!< Big endian mode */
|
||||
kSDMMCHOST_EndianModeHalfWordBig = 1U, /*!< Half word big endian mode */
|
||||
kSDMMCHOST_EndianModeLittle = 2U, /*!< Little endian mode */
|
||||
};
|
||||
|
||||
/*! @brief sd card detect type */
|
||||
typedef enum _sdmmchost_detect_card_type
|
||||
{
|
||||
kSDMMCHOST_DetectCardByGpioCD, /*!< sd card detect by CD pin through GPIO */
|
||||
kSDMMCHOST_DetectCardByHostCD, /*!< sd card detect by CD pin through host */
|
||||
kSDMMCHOST_DetectCardByHostDATA3, /*!< sd card detect by DAT3 pin through host */
|
||||
} sdmmchost_detect_card_type_t;
|
||||
|
||||
/*! @brief sd card detect */
|
||||
typedef struct _sdmmchost_detect_card
|
||||
{
|
||||
sdmmchost_detect_card_type_t cdType; /*!< card detect type */
|
||||
uint32_t cdTimeOut_ms; /*!< card detect timeout which allow 0 - 0xFFFFFFF, value 0 will return immediately, value
|
||||
0xFFFFFFFF will block until card is insert */
|
||||
|
||||
sdmmchost_cd_callback_t cardInserted; /*!< card inserted callback which is meaningful for interrupt case */
|
||||
sdmmchost_cd_callback_t cardRemoved; /*!< card removed callback which is meaningful for interrupt case */
|
||||
|
||||
void *userData; /*!< user data */
|
||||
} sdmmchost_detect_card_t;
|
||||
|
||||
/*! @brief card power control function pointer */
|
||||
typedef void (*sdmmchost_pwr_t)(void);
|
||||
|
||||
/*! @brief card power control */
|
||||
typedef struct _sdmmchost_pwr_card
|
||||
{
|
||||
sdmmchost_pwr_t powerOn; /*!< power on function pointer */
|
||||
uint32_t powerOnDelay_ms; /*!< power on delay */
|
||||
|
||||
sdmmchost_pwr_t powerOff; /*!< power off function pointer */
|
||||
uint32_t powerOffDelay_ms; /*!< power off delay */
|
||||
} sdmmchost_pwr_card_t;
|
||||
|
||||
/*! @brief card interrupt function pointer */
|
||||
typedef void (*sdmmchost_card_int_callback_t)(void *userData);
|
||||
/*! @brief card interrupt application callback */
|
||||
typedef struct _sdmmchost_card_int
|
||||
{
|
||||
void *userData; /*!< user data */
|
||||
sdmmchost_card_int_callback_t cardInterrupt; /*!< card int call back */
|
||||
} sdmmchost_card_int_t;
|
||||
|
||||
/*! @brief card switch voltage function pointer */
|
||||
typedef void (*sdmmchost_card_switch_voltage_t)(void);
|
||||
/*! @brief card switch voltage function collection */
|
||||
typedef struct _sdmmchost_card_switch_voltage_func
|
||||
{
|
||||
sdmmchost_card_switch_voltage_t cardSignalLine1V8; /*!< switch to 1.8v function pointer */
|
||||
sdmmchost_card_switch_voltage_t cardSignalLine3V3; /*!<switch to 3.3V function pointer */
|
||||
} sdmmchost_card_switch_voltage_func_t;
|
||||
|
||||
/*! @brief card user parameter, user can define the parameter according the board, card capability */
|
||||
typedef struct _sdmmhostcard_usr_param
|
||||
{
|
||||
const sdmmchost_detect_card_t *cd; /*!< card detect type */
|
||||
const sdmmchost_pwr_card_t *pwr; /*!< power control configuration */
|
||||
const sdmmchost_card_int_t *cardInt; /*!< call back function for card interrupt */
|
||||
const sdmmchost_card_switch_voltage_func_t *cardVoltage; /*!< card voltage switch function */
|
||||
} sdmmhostcard_usr_param_t;
|
||||
|
||||
/*! @ brief specifiy card user parameter name*/
|
||||
typedef sdmmhostcard_usr_param_t sdcard_usr_param_t;
|
||||
typedef sdmmhostcard_usr_param_t sdiocard_usr_param_t;
|
||||
typedef sdmmhostcard_usr_param_t mmccard_usr_param_t;
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name adaptor function
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief host not support function, this function is used for host not support feature
|
||||
* @param void parameter ,used to avoid build warning
|
||||
* @retval kStatus_Fail ,host do not suppport
|
||||
*/
|
||||
static inline status_t SDMMCHOST_NotSupport(void *parameter)
|
||||
{
|
||||
parameter = parameter;
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Detect card insert, only need for SD cases.
|
||||
* @param base the pointer to host base address
|
||||
* @param cd card detect configuration
|
||||
* @param waitCardStatus status which user want to wait
|
||||
* @retval kStatus_Success detect card insert
|
||||
* @retval kStatus_Fail card insert event fail
|
||||
*/
|
||||
status_t SDMMCHOST_WaitCardDetectStatus(SDMMCHOST_TYPE *hostBase,
|
||||
const sdmmchost_detect_card_t *cd,
|
||||
bool waitCardStatus);
|
||||
|
||||
/*!
|
||||
* @brief check card is present or not.
|
||||
* @retval true card is present
|
||||
* @retval false card is not present
|
||||
*/
|
||||
bool SDMMCHOST_IsCardPresent(void);
|
||||
|
||||
/*!
|
||||
* @brief Init host controller.
|
||||
* @param host the pointer to host structure in card structure.
|
||||
* @param userData specific user data
|
||||
* @retval kStatus_Success host init success
|
||||
* @retval kStatus_Fail event fail
|
||||
*/
|
||||
status_t SDMMCHOST_Init(SDMMCHOST_CONFIG *host, void *userData);
|
||||
|
||||
/*!
|
||||
* @brief reset host controller.
|
||||
* @param host base address.
|
||||
*/
|
||||
void SDMMCHOST_Reset(SDMMCHOST_TYPE *base);
|
||||
|
||||
/*!
|
||||
* @brief host controller error recovery.
|
||||
* @param host base address.
|
||||
*/
|
||||
void SDMMCHOST_ErrorRecovery(SDMMCHOST_TYPE *base);
|
||||
|
||||
/*!
|
||||
* @brief Deinit host controller.
|
||||
* @param host the pointer to host structure in card structure.
|
||||
*/
|
||||
void SDMMCHOST_Deinit(void *host);
|
||||
|
||||
/*!
|
||||
* @brief host power off card function.
|
||||
* @param base host base address.
|
||||
* @param pwr depend on user define power configuration.
|
||||
*/
|
||||
void SDMMCHOST_PowerOffCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr);
|
||||
|
||||
/*!
|
||||
* @brief host power on card function.
|
||||
* @param base host base address.
|
||||
* @param pwr depend on user define power configuration.
|
||||
*/
|
||||
void SDMMCHOST_PowerOnCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr);
|
||||
|
||||
/*!
|
||||
* @brief SDMMC host delay function.
|
||||
* @param milliseconds delay counter.
|
||||
*/
|
||||
void SDMMCHOST_Delay(uint32_t milliseconds);
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
/* @} */
|
||||
#endif /* _FSL_SDMMC_HOST_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,3 @@
|
|||
SRC_DIR += usdhc
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_SDMMC_EVENT_H_
|
||||
#define _FSL_SDMMC_EVENT_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
/*! @brief Event type */
|
||||
typedef enum _sdmmc_event
|
||||
{
|
||||
kSDMMCEVENT_TransferComplete = 0U, /*!< Transfer complete event */
|
||||
kSDMMCEVENT_CardDetect = 1U, /*!< Card detect event */
|
||||
} sdmmc_event_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name Event Function
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initialize timer to implement wait event timeout.
|
||||
*/
|
||||
void SDMMCEVENT_InitTimer(void);
|
||||
|
||||
/* Callback function for SDHC */
|
||||
|
||||
/*!
|
||||
* @brief Create event.
|
||||
* @param eventType The event type
|
||||
* @retval true Create event successfully.
|
||||
* @retval false Create event failed.
|
||||
*/
|
||||
bool SDMMCEVENT_Create(sdmmc_event_t eventType);
|
||||
|
||||
/*!
|
||||
* @brief Wait event.
|
||||
*
|
||||
* @param eventType The event type
|
||||
* @param timeoutMilliseconds Timeout time in milliseconds.
|
||||
* @retval true Wait event successfully.
|
||||
* @retval false Wait event failed.
|
||||
*/
|
||||
bool SDMMCEVENT_Wait(sdmmc_event_t eventType, uint32_t timeoutMilliseconds);
|
||||
|
||||
/*!
|
||||
* @brief Notify event.
|
||||
* @param eventType The event type
|
||||
* @retval true Notify event successfully.
|
||||
* @retval false Notify event failed.
|
||||
*/
|
||||
bool SDMMCEVENT_Notify(sdmmc_event_t eventType);
|
||||
|
||||
/*!
|
||||
* @brief Delete event.
|
||||
* @param eventType The event type
|
||||
*/
|
||||
void SDMMCEVENT_Delete(sdmmc_event_t eventType);
|
||||
|
||||
/*!
|
||||
* @brief sdmmc delay.
|
||||
* @param milliseconds time to delay
|
||||
*/
|
||||
void SDMMCEVENT_Delay(uint32_t milliseconds);
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FSL_SDMMC_EVENT_H_*/
|
|
@ -0,0 +1,3 @@
|
|||
SRC_DIR += polling
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := fsl_sdmmc_host.c fsl_sdmmc_event.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include "fsl_sdmmc_event.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief Get event instance.
|
||||
* @param eventType The event type
|
||||
* @return The event instance's pointer.
|
||||
*/
|
||||
static volatile uint32_t *SDMMCEVENT_GetInstance(sdmmc_event_t eventType);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
/*! @brief Card detect event. */
|
||||
static volatile uint32_t g_eventCardDetect;
|
||||
|
||||
/*! @brief transfer complete event. */
|
||||
static volatile uint32_t g_eventTransferComplete;
|
||||
|
||||
/*! @brief Time variable unites as milliseconds. */
|
||||
volatile uint32_t g_eventTimeMilliseconds;
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
static void SysTickHandler(void)
|
||||
{
|
||||
#ifdef __CA7_REV
|
||||
SystemClearSystickFlag();
|
||||
#endif
|
||||
g_eventTimeMilliseconds++;
|
||||
}
|
||||
|
||||
void SDMMCEVENT_InitTimer(void)
|
||||
{
|
||||
#ifdef __CA7_REV
|
||||
/* special for i.mx6ul */
|
||||
SystemSetupSystick(1000U, (void *)SysTickHandler, 32U);
|
||||
SystemClearSystickFlag();
|
||||
#else
|
||||
/* Set systick reload value to generate 1ms interrupt */
|
||||
SysTick_Config(CLOCK_GetFreq(kCLOCK_CoreSysClk) / 1000U);
|
||||
#endif
|
||||
}
|
||||
|
||||
static volatile uint32_t *SDMMCEVENT_GetInstance(sdmmc_event_t eventType)
|
||||
{
|
||||
volatile uint32_t *event;
|
||||
|
||||
switch (eventType)
|
||||
{
|
||||
case kSDMMCEVENT_TransferComplete:
|
||||
event = &g_eventTransferComplete;
|
||||
break;
|
||||
case kSDMMCEVENT_CardDetect:
|
||||
event = &g_eventCardDetect;
|
||||
break;
|
||||
default:
|
||||
event = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
bool SDMMCEVENT_Create(sdmmc_event_t eventType)
|
||||
{
|
||||
volatile uint32_t *event = SDMMCEVENT_GetInstance(eventType);
|
||||
|
||||
if (event)
|
||||
{
|
||||
*event = 0;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SDMMCEVENT_Wait(sdmmc_event_t eventType, uint32_t timeoutMilliseconds)
|
||||
{
|
||||
uint32_t startTime;
|
||||
uint32_t elapsedTime;
|
||||
|
||||
volatile uint32_t *event = SDMMCEVENT_GetInstance(eventType);
|
||||
|
||||
if (timeoutMilliseconds && event)
|
||||
{
|
||||
startTime = g_eventTimeMilliseconds;
|
||||
do
|
||||
{
|
||||
elapsedTime = (g_eventTimeMilliseconds - startTime);
|
||||
} while ((*event == 0U) && (elapsedTime < timeoutMilliseconds));
|
||||
*event = 0U;
|
||||
|
||||
return ((elapsedTime < timeoutMilliseconds) ? true : false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SDMMCEVENT_Notify(sdmmc_event_t eventType)
|
||||
{
|
||||
volatile uint32_t *event = SDMMCEVENT_GetInstance(eventType);
|
||||
|
||||
if (event)
|
||||
{
|
||||
*event = 1U;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void SDMMCEVENT_Delete(sdmmc_event_t eventType)
|
||||
{
|
||||
volatile uint32_t *event = SDMMCEVENT_GetInstance(eventType);
|
||||
|
||||
if (event)
|
||||
{
|
||||
*event = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
void SDMMCEVENT_Delay(uint32_t milliseconds)
|
||||
{
|
||||
uint32_t startTime = g_eventTimeMilliseconds;
|
||||
uint32_t periodTime = 0;
|
||||
while (periodTime < milliseconds)
|
||||
{
|
||||
periodTime = g_eventTimeMilliseconds - startTime;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,437 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_sdmmc_event.h"
|
||||
#include "fsl_sdmmc_host.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief SDMMCHOST notify card insertion status.
|
||||
* @param inserted true is inserted, false is not
|
||||
* @param cd card detect descriptor
|
||||
*/
|
||||
static void SDMMCHOST_NofiyCardInsertStatus(bool inserted, const sdmmchost_detect_card_t *cd);
|
||||
|
||||
/*!
|
||||
* @brief SDMMCHOST detect card insert status by host controller.
|
||||
* @param base host base address.
|
||||
* @param userData user can register a application card insert callback through userData.
|
||||
*/
|
||||
static void SDMMCHOST_DetectCardInsertByHost(SDMMCHOST_TYPE *base, void *userData);
|
||||
|
||||
/*!
|
||||
* @brief SDMMCHOST detect card remove status by host controller.
|
||||
* @param base host base address.
|
||||
* @param userData user can register a application card insert callback through userData.
|
||||
*/
|
||||
static void SDMMCHOST_DetectCardRemoveByHost(SDMMCHOST_TYPE *base, void *userData);
|
||||
|
||||
/*!
|
||||
* @brief SDMMCHOST transfer function.
|
||||
* @param base host base address.
|
||||
* @param content transfer configurations.
|
||||
*/
|
||||
static status_t SDMMCHOST_TransferFunction(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER *content);
|
||||
|
||||
/*!
|
||||
* @brief SDMMCHOST transfer complete callback.
|
||||
* @param base host base address.
|
||||
* @param handle host handle.
|
||||
* @param status interrupt status.
|
||||
* @param userData user data.
|
||||
*/
|
||||
static void SDMMCHOST_TransferCompleteCallback(SDMMCHOST_TYPE *base,
|
||||
usdhc_handle_t *handle,
|
||||
status_t status,
|
||||
void *userData);
|
||||
|
||||
/*!
|
||||
* @brief SDMMCHOST re-tuning callback
|
||||
* @param base host base address.
|
||||
* @param userData user can register a application card insert callback through userData.
|
||||
*/
|
||||
static void SDMMCHOST_ReTuningCallback(SDMMCHOST_TYPE *base, void *userData);
|
||||
|
||||
/*!
|
||||
* @brief card detect deinit function.
|
||||
*/
|
||||
static void SDMMCHOST_CardDetectDeinit(void);
|
||||
|
||||
/*!
|
||||
* @brief card detect deinit function.
|
||||
* @param host base address.
|
||||
* @param host detect card configuration.
|
||||
*/
|
||||
static status_t SDMMCHOST_CardDetectInit(SDMMCHOST_TYPE *base, const sdmmchost_detect_card_t *cd);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
/* DMA descriptor should allocate at non-cached memory */
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(uint32_t g_usdhcAdma2Table[USDHC_ADMA_TABLE_WORDS], USDHC_ADMA2_ADDR_ALIGN);
|
||||
|
||||
usdhc_handle_t g_usdhcHandle;
|
||||
volatile status_t g_usdhcTransferStatus = kStatus_Success;
|
||||
static volatile bool s_sdInsertedFlag = false;
|
||||
volatile status_t g_reTuningFlag = false;
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
static void SDMMCHOST_NofiyCardInsertStatus(bool inserted, const sdmmchost_detect_card_t *cd)
|
||||
{
|
||||
if (inserted == false)
|
||||
{
|
||||
s_sdInsertedFlag = false;
|
||||
if (cd && (cd->cardRemoved))
|
||||
{
|
||||
cd->cardRemoved(false, cd->userData);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s_sdInsertedFlag = true;
|
||||
if (cd && (cd->cardInserted))
|
||||
{
|
||||
cd->cardInserted(true, cd->userData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SDMMCHOST_DetectCardInsertByHost(SDMMCHOST_TYPE *base, void *userData)
|
||||
{
|
||||
s_sdInsertedFlag = true;
|
||||
SDMMCEVENT_Notify(kSDMMCEVENT_CardDetect);
|
||||
/* application callback */
|
||||
if (userData && (((sdmmhostcard_usr_param_t *)userData)->cd) &&
|
||||
((sdmmhostcard_usr_param_t *)userData)->cd->cardInserted)
|
||||
{
|
||||
((sdmmhostcard_usr_param_t *)userData)
|
||||
->cd->cardInserted(true, ((sdmmhostcard_usr_param_t *)userData)->cd->userData);
|
||||
}
|
||||
}
|
||||
|
||||
static void SDMMCHOST_DetectCardRemoveByHost(SDMMCHOST_TYPE *base, void *userData)
|
||||
{
|
||||
s_sdInsertedFlag = false;
|
||||
/* application callback */
|
||||
if (userData && (((sdmmhostcard_usr_param_t *)userData)->cd) &&
|
||||
((sdmmhostcard_usr_param_t *)userData)->cd->cardRemoved)
|
||||
{
|
||||
((sdmmhostcard_usr_param_t *)userData)
|
||||
->cd->cardRemoved(false, ((sdmmhostcard_usr_param_t *)userData)->cd->userData);
|
||||
}
|
||||
}
|
||||
|
||||
static void SDMMCHOST_CardInterrupt(SDMMCHOST_TYPE *base, void *userData)
|
||||
{
|
||||
/* application callback */
|
||||
if (userData && ((sdmmhostcard_usr_param_t *)userData)->cardInt)
|
||||
{
|
||||
((sdmmhostcard_usr_param_t *)userData)
|
||||
->cardInt->cardInterrupt(((sdmmhostcard_usr_param_t *)userData)->cardInt->userData);
|
||||
}
|
||||
}
|
||||
|
||||
void SDMMCHOST_CARD_DETECT_GPIO_INTERRUPT_HANDLER(void)
|
||||
{
|
||||
if (SDMMCHOST_CARD_DETECT_GPIO_INTERRUPT_STATUS() & (1U << BOARD_USDHC_CD_GPIO_PIN))
|
||||
{
|
||||
SDMMCHOST_NofiyCardInsertStatus((SDMMCHOST_CARD_DETECT_GPIO_STATUS() == SDMMCHOST_CARD_INSERT_CD_LEVEL),
|
||||
((sdmmhostcard_usr_param_t *)g_usdhcHandle.userData)->cd);
|
||||
}
|
||||
/* Clear interrupt flag.*/
|
||||
SDMMCHOST_CARD_DETECT_GPIO_INTERRUPT_STATUS_CLEAR(~0U);
|
||||
SDMMCEVENT_Notify(kSDMMCEVENT_CardDetect);
|
||||
}
|
||||
|
||||
static void SDMMCHOST_TransferCompleteCallback(SDMMCHOST_TYPE *base,
|
||||
usdhc_handle_t *handle,
|
||||
status_t status,
|
||||
void *userData)
|
||||
{
|
||||
/* if reading data from sdcard, ignore the command error, usdhc will continue transfer data */
|
||||
if (!((handle->data) && (handle->data->rxData) && (status == kStatus_USDHC_SendCommandFailed)))
|
||||
{
|
||||
SDMMCEVENT_Notify(kSDMMCEVENT_TransferComplete);
|
||||
}
|
||||
/* wait the target status and then notify the transfer complete */
|
||||
g_usdhcTransferStatus = status;
|
||||
}
|
||||
|
||||
static void SDMMCHOST_ReTuningCallback(SDMMCHOST_TYPE *base, void *userData)
|
||||
{
|
||||
g_reTuningFlag = true;
|
||||
SDMMCEVENT_Notify(kSDMMCEVENT_TransferComplete);
|
||||
}
|
||||
|
||||
static status_t SDMMCHOST_TransferFunction(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER *content)
|
||||
{
|
||||
status_t error = kStatus_Success;
|
||||
|
||||
usdhc_adma_config_t dmaConfig;
|
||||
|
||||
if (content->data != NULL)
|
||||
{
|
||||
memset(&dmaConfig, 0, sizeof(usdhc_adma_config_t));
|
||||
/* config adma */
|
||||
dmaConfig.dmaMode = USDHC_DMA_MODE;
|
||||
dmaConfig.burstLen = kUSDHC_EnBurstLenForINCR;
|
||||
dmaConfig.admaTable = g_usdhcAdma2Table;
|
||||
dmaConfig.admaTableWords = USDHC_ADMA_TABLE_WORDS;
|
||||
}
|
||||
|
||||
/* make sure complete event is cleared. */
|
||||
SDMMCEVENT_Delete(kSDMMCEVENT_TransferComplete);
|
||||
|
||||
do
|
||||
{
|
||||
error = USDHC_TransferNonBlocking(base, &g_usdhcHandle, &dmaConfig, content);
|
||||
} while (error == kStatus_USDHC_BusyTransferring);
|
||||
|
||||
if ((error != kStatus_Success) ||
|
||||
(false == SDMMCEVENT_Wait(kSDMMCEVENT_TransferComplete, SDMMCHOST_TRANSFER_COMPLETE_TIMEOUT)) ||
|
||||
(g_reTuningFlag) || (g_usdhcTransferStatus != kStatus_Success))
|
||||
{
|
||||
if (g_reTuningFlag || (error == kStatus_USDHC_ReTuningRequest))
|
||||
{
|
||||
if (g_reTuningFlag)
|
||||
{
|
||||
g_reTuningFlag = false;
|
||||
error = kStatus_USDHC_TuningError;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error = g_usdhcTransferStatus;
|
||||
/* host error recovery */
|
||||
SDMMCHOST_ErrorRecovery(base);
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void SDMMCHOST_ErrorRecovery(SDMMCHOST_TYPE *base)
|
||||
{
|
||||
uint32_t status = 0U;
|
||||
/* get host present status */
|
||||
status = USDHC_GetPresentStatusFlags(base);
|
||||
/* check command inhibit status flag */
|
||||
if ((status & kUSDHC_CommandInhibitFlag) != 0U)
|
||||
{
|
||||
/* reset command line */
|
||||
USDHC_Reset(base, kUSDHC_ResetCommand, 100U);
|
||||
}
|
||||
/* check data inhibit status flag */
|
||||
if ((status & kUSDHC_DataInhibitFlag) != 0U)
|
||||
{
|
||||
/* reset data line */
|
||||
USDHC_Reset(base, kUSDHC_ResetData, 100U);
|
||||
}
|
||||
}
|
||||
|
||||
static status_t SDMMCHOST_CardDetectInit(SDMMCHOST_TYPE *base, const sdmmchost_detect_card_t *cd)
|
||||
{
|
||||
sdmmchost_detect_card_type_t cdType = kSDMMCHOST_DetectCardByGpioCD;
|
||||
bool cardInserted = false;
|
||||
|
||||
if (cd != NULL)
|
||||
{
|
||||
cdType = cd->cdType;
|
||||
}
|
||||
|
||||
if (!SDMMCEVENT_Create(kSDMMCEVENT_CardDetect))
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
|
||||
if (cdType == kSDMMCHOST_DetectCardByGpioCD)
|
||||
{
|
||||
SDMMCHOST_CARD_DETECT_GPIO_INIT();
|
||||
|
||||
/* Open card detection pin NVIC. */
|
||||
SDMMCHOST_ENABLE_IRQ(SDMMCHOST_CARD_DETECT_GPIO_IRQ);
|
||||
/* detect card insert status */
|
||||
if (SDMMCHOST_CARD_DETECT_GPIO_STATUS() == SDMMCHOST_CARD_INSERT_CD_LEVEL)
|
||||
{
|
||||
cardInserted = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* enable card detect through DATA3 */
|
||||
if (cdType == kSDMMCHOST_DetectCardByHostDATA3)
|
||||
{
|
||||
SDMMCHOST_CARD_DETECT_DATA3_ENABLE(base, true);
|
||||
}
|
||||
/* enable card detect interrupt */
|
||||
SDMMCHOST_CARD_DETECT_INSERT_ENABLE(base);
|
||||
/* check if card is inserted */
|
||||
if (SDMMCHOST_CARD_DETECT_INSERT_STATUS(base))
|
||||
{
|
||||
cardInserted = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SDMMCHOST_CARD_DETECT_INSERT_INTERRUPT_ENABLE(base);
|
||||
SDMMCHOST_CARD_DETECT_REMOVE_INTERRUPT_ENABLE(base);
|
||||
}
|
||||
}
|
||||
|
||||
/* notify application about the card insertion status */
|
||||
SDMMCHOST_NofiyCardInsertStatus(cardInserted, cd);
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
static void SDMMCHOST_CardDetectDeinit(void)
|
||||
{
|
||||
SDMMCEVENT_Delete(kSDMMCEVENT_CardDetect);
|
||||
s_sdInsertedFlag = false;
|
||||
}
|
||||
|
||||
void SDMMCHOST_Delay(uint32_t milliseconds)
|
||||
{
|
||||
SDMMCEVENT_Delay(milliseconds);
|
||||
}
|
||||
|
||||
status_t SDMMCHOST_WaitCardDetectStatus(SDMMCHOST_TYPE *base, const sdmmchost_detect_card_t *cd, bool waitCardStatus)
|
||||
{
|
||||
uint32_t timeout = SDMMCHOST_CARD_DETECT_TIMEOUT;
|
||||
|
||||
if (cd != NULL)
|
||||
{
|
||||
timeout = cd->cdTimeOut_ms;
|
||||
}
|
||||
|
||||
if (waitCardStatus != s_sdInsertedFlag)
|
||||
{
|
||||
/* Wait card inserted. */
|
||||
do
|
||||
{
|
||||
if (!SDMMCEVENT_Wait(kSDMMCEVENT_CardDetect, timeout))
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
} while (waitCardStatus != s_sdInsertedFlag);
|
||||
}
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
bool SDMMCHOST_IsCardPresent(void)
|
||||
{
|
||||
return s_sdInsertedFlag;
|
||||
}
|
||||
|
||||
void SDMMCHOST_PowerOffCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr)
|
||||
{
|
||||
if (pwr != NULL)
|
||||
{
|
||||
pwr->powerOff();
|
||||
SDMMCHOST_Delay(pwr->powerOffDelay_ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* only SD card need card detect*/
|
||||
SDMMCHOST_ENABLE_SD_POWER(false);
|
||||
/* Delay several milliseconds to make card stable. */
|
||||
SDMMCHOST_Delay(500U);
|
||||
}
|
||||
}
|
||||
|
||||
void SDMMCHOST_PowerOnCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr)
|
||||
{
|
||||
/* use user define the power on function */
|
||||
if (pwr != NULL)
|
||||
{
|
||||
pwr->powerOn();
|
||||
SDMMCHOST_Delay(pwr->powerOnDelay_ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* card power on */
|
||||
SDMMCHOST_ENABLE_SD_POWER(true);
|
||||
/* Delay several milliseconds to make card stable. */
|
||||
SDMMCHOST_Delay(500U);
|
||||
}
|
||||
}
|
||||
|
||||
status_t SDMMCHOST_Init(SDMMCHOST_CONFIG *host, void *userData)
|
||||
{
|
||||
usdhc_host_t *usdhcHost = (usdhc_host_t *)host;
|
||||
usdhc_transfer_callback_t callback = {
|
||||
.TransferComplete = SDMMCHOST_TransferCompleteCallback,
|
||||
.ReTuning = SDMMCHOST_ReTuningCallback,
|
||||
.CardInserted = SDMMCHOST_DetectCardInsertByHost,
|
||||
.CardRemoved = SDMMCHOST_DetectCardRemoveByHost,
|
||||
.SdioInterrupt = SDMMCHOST_CardInterrupt,
|
||||
.BlockGap = NULL,
|
||||
};
|
||||
/* init card power control */
|
||||
SDMMCHOST_INIT_SD_POWER();
|
||||
SDMMCHOST_INIT_MMC_POWER();
|
||||
|
||||
/* Initializes USDHC. */
|
||||
usdhcHost->config.dataTimeout = USDHC_DATA_TIMEOUT;
|
||||
usdhcHost->config.endianMode = USDHC_ENDIAN_MODE;
|
||||
usdhcHost->config.readWatermarkLevel = USDHC_READ_WATERMARK_LEVEL;
|
||||
usdhcHost->config.writeWatermarkLevel = USDHC_WRITE_WATERMARK_LEVEL;
|
||||
usdhcHost->config.readBurstLen = USDHC_READ_BURST_LEN;
|
||||
usdhcHost->config.writeBurstLen = USDHC_WRITE_BURST_LEN;
|
||||
|
||||
USDHC_Init(usdhcHost->base, &(usdhcHost->config));
|
||||
|
||||
/* disable the card insert/remove interrupt, due to use GPIO interrupt detect card */
|
||||
USDHC_DisableInterruptSignal(usdhcHost->base, kUSDHC_CardRemovalFlag | kUSDHC_CardInsertionFlag);
|
||||
/* create interrupt handler */
|
||||
USDHC_TransferCreateHandle(usdhcHost->base, &g_usdhcHandle, &callback, userData);
|
||||
/* Create transfer complete event. */
|
||||
SDMMCEVENT_InitTimer();
|
||||
|
||||
if (false == SDMMCEVENT_Create(kSDMMCEVENT_TransferComplete))
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
|
||||
/* Define transfer function. */
|
||||
usdhcHost->transfer = SDMMCHOST_TransferFunction;
|
||||
/* card detect init */
|
||||
SDMMCHOST_CardDetectInit(usdhcHost->base, (userData == NULL) ? NULL : (((sdmmhostcard_usr_param_t *)userData)->cd));
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
void SDMMCHOST_Reset(SDMMCHOST_TYPE *base)
|
||||
{
|
||||
/* voltage switch to normal but not 1.8V */
|
||||
SDMMCHOST_SWITCH_VOLTAGE180V(base, false);
|
||||
/* Disable DDR mode */
|
||||
SDMMCHOST_ENABLE_DDR_MODE(base, false, 0U);
|
||||
/* disable tuning */
|
||||
SDMMCHOST_EXECUTE_STANDARD_TUNING_ENABLE(base, false);
|
||||
/* Disable HS400 mode */
|
||||
SDMMCHOST_ENABLE_HS400_MODE(base, false);
|
||||
/* Disable DLL */
|
||||
SDMMCHOST_ENABLE_STROBE_DLL(base, false);
|
||||
}
|
||||
|
||||
void SDMMCHOST_Deinit(void *host)
|
||||
{
|
||||
usdhc_host_t *usdhcHost = (usdhc_host_t *)host;
|
||||
SDMMCHOST_Reset(usdhcHost->base);
|
||||
USDHC_Deinit(usdhcHost->base);
|
||||
SDMMCHOST_CardDetectDeinit();
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := fsl_sdmmc_host.c fsl_sdmmc_event.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_sdmmc_event.h"
|
||||
#include "xiuos.h"
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief Get event instance.
|
||||
* @param eventType The event type
|
||||
* @return The event instance's pointer.
|
||||
*/
|
||||
static volatile uint32_t *SDMMCEVENT_GetInstance(sdmmc_event_t eventType);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
/*! @brief Card detect event. */
|
||||
static volatile uint32_t g_eventCardDetect;
|
||||
|
||||
/*! @brief transfer complete event. */
|
||||
static volatile uint32_t g_eventTransferComplete;
|
||||
|
||||
/*! @brief Time variable unites as milliseconds. */
|
||||
volatile uint32_t g_eventTimeMilliseconds;
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
// void SysTick_Handler(void)
|
||||
// {
|
||||
// #ifdef __CA7_REV
|
||||
// SystemClearSystickFlag();
|
||||
// #endif
|
||||
// g_eventTimeMilliseconds++;
|
||||
// }
|
||||
|
||||
void SDMMCEVENT_InitTimer(void)
|
||||
{
|
||||
#ifdef __CA7_REV
|
||||
/* special for i.mx6ul */
|
||||
SystemSetupSystick(1000U, (void *)SysTick_Handler, 32U);
|
||||
SystemClearSystickFlag();
|
||||
#else
|
||||
/* Set systick reload value to generate 1ms interrupt */
|
||||
SysTick_Config(CLOCK_GetFreq(kCLOCK_CoreSysClk) / 1000U);
|
||||
#endif
|
||||
}
|
||||
|
||||
static volatile uint32_t *SDMMCEVENT_GetInstance(sdmmc_event_t eventType)
|
||||
{
|
||||
volatile uint32_t *event;
|
||||
|
||||
switch (eventType)
|
||||
{
|
||||
case kSDMMCEVENT_TransferComplete:
|
||||
event = &g_eventTransferComplete;
|
||||
break;
|
||||
case kSDMMCEVENT_CardDetect:
|
||||
event = &g_eventCardDetect;
|
||||
break;
|
||||
default:
|
||||
event = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
bool SDMMCEVENT_Create(sdmmc_event_t eventType)
|
||||
{
|
||||
volatile uint32_t *event = SDMMCEVENT_GetInstance(eventType);
|
||||
|
||||
if (event)
|
||||
{
|
||||
*event = 0;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SDMMCEVENT_Wait(sdmmc_event_t eventType, uint32_t timeoutMilliseconds)
|
||||
{
|
||||
uint32_t startTime;
|
||||
uint32_t elapsedTime;
|
||||
|
||||
volatile uint32_t *event = SDMMCEVENT_GetInstance(eventType);
|
||||
|
||||
if (timeoutMilliseconds && event)
|
||||
{
|
||||
startTime = CurrentTicksGain();
|
||||
do
|
||||
{
|
||||
elapsedTime = (CurrentTicksGain() - startTime);
|
||||
} while ((*event == 0U) && (elapsedTime < timeoutMilliseconds));
|
||||
*event = 0U;
|
||||
|
||||
return ((elapsedTime < timeoutMilliseconds) ? true : false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SDMMCEVENT_Notify(sdmmc_event_t eventType)
|
||||
{
|
||||
volatile uint32_t *event = SDMMCEVENT_GetInstance(eventType);
|
||||
|
||||
if (event)
|
||||
{
|
||||
*event = 1U;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void SDMMCEVENT_Delete(sdmmc_event_t eventType)
|
||||
{
|
||||
volatile uint32_t *event = SDMMCEVENT_GetInstance(eventType);
|
||||
|
||||
if (event)
|
||||
{
|
||||
*event = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
void SDMMCEVENT_Delay(uint32_t milliseconds)
|
||||
{
|
||||
uint32_t startTime = CurrentTicksGain();
|
||||
uint32_t periodTime = 0;
|
||||
while (periodTime < milliseconds)
|
||||
{
|
||||
KPrintf("period time %u millisecond %u event %u start %u\n",
|
||||
periodTime, milliseconds, CurrentTicksGain(), startTime);
|
||||
periodTime = CurrentTicksGain() - startTime;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_sdmmc_host.h"
|
||||
#include "fsl_sdmmc_event.h"
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief SDMMCHOST notify card insertion status.
|
||||
* @param inserted true is inserted, false is not
|
||||
* @param cd card detect descriptor
|
||||
*/
|
||||
static void SDMMCHOST_NofiyCardInsertStatus(bool inserted, const sdmmchost_detect_card_t *cd);
|
||||
|
||||
/*!
|
||||
* @brief SDMMCHOST transfer function.
|
||||
* @param base host base address.
|
||||
* @param content transfer configurations.
|
||||
*/
|
||||
static status_t SDMMCHOST_TransferFunction(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER *content);
|
||||
|
||||
/*!
|
||||
* @brief card detect deinit function.
|
||||
*/
|
||||
static void SDMMCHOST_CardDetectDeinit(void);
|
||||
|
||||
/*!
|
||||
* @brief card detect deinit function.
|
||||
* @param host base address.
|
||||
* @param host detect card configuration.
|
||||
*/
|
||||
static status_t SDMMCHOST_CardDetectInit(SDMMCHOST_TYPE *base, const sdmmchost_detect_card_t *cd);
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
/* DMA descriptor should allocate at non-cached memory */
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(uint32_t g_usdhcAdma2Table[USDHC_ADMA_TABLE_WORDS], USDHC_ADMA2_ADDR_ALIGN);
|
||||
static volatile bool s_sdInsertedFlag = false;
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
static void SDMMCHOST_NofiyCardInsertStatus(bool inserted, const sdmmchost_detect_card_t *cd)
|
||||
{
|
||||
if (inserted == false)
|
||||
{
|
||||
s_sdInsertedFlag = false;
|
||||
if (cd && (cd->cardRemoved))
|
||||
{
|
||||
cd->cardRemoved(false, cd->userData);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s_sdInsertedFlag = true;
|
||||
if (cd && (cd->cardInserted))
|
||||
{
|
||||
cd->cardInserted(true, cd->userData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static status_t SDMMCHOST_TransferFunction(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER *content)
|
||||
{
|
||||
usdhc_adma_config_t dmaConfig;
|
||||
status_t error = kStatus_Success;
|
||||
|
||||
if (content->data != NULL)
|
||||
{
|
||||
memset(&dmaConfig, 0, sizeof(usdhc_adma_config_t));
|
||||
/* config adma */
|
||||
dmaConfig.dmaMode = USDHC_DMA_MODE;
|
||||
dmaConfig.burstLen = kUSDHC_EnBurstLenForINCR;
|
||||
dmaConfig.admaTable = g_usdhcAdma2Table;
|
||||
dmaConfig.admaTableWords = USDHC_ADMA_TABLE_WORDS;
|
||||
}
|
||||
|
||||
error = USDHC_TransferBlocking(base, &dmaConfig, content);
|
||||
|
||||
if (error != kStatus_Success)
|
||||
{
|
||||
/* host error recovery */
|
||||
SDMMCHOST_ErrorRecovery(base);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void SDMMCHOST_ErrorRecovery(SDMMCHOST_TYPE *base)
|
||||
{
|
||||
uint32_t status = 0U;
|
||||
/* get host present status */
|
||||
status = USDHC_GetPresentStatusFlags(base);
|
||||
/* check command inhibit status flag */
|
||||
if ((status & kUSDHC_CommandInhibitFlag) != 0U)
|
||||
{
|
||||
/* reset command line */
|
||||
USDHC_Reset(base, kUSDHC_ResetCommand, 100U);
|
||||
}
|
||||
/* check data inhibit status flag */
|
||||
if ((status & kUSDHC_DataInhibitFlag) != 0U)
|
||||
{
|
||||
/* reset data line */
|
||||
USDHC_Reset(base, kUSDHC_ResetData, 100U);
|
||||
}
|
||||
}
|
||||
|
||||
static status_t SDMMCHOST_CardDetectInit(SDMMCHOST_TYPE *base, const sdmmchost_detect_card_t *cd)
|
||||
{
|
||||
sdmmchost_detect_card_type_t cdType = kSDMMCHOST_DetectCardByGpioCD;
|
||||
bool cardInserted = false;
|
||||
|
||||
if (cd != NULL)
|
||||
{
|
||||
cdType = cd->cdType;
|
||||
}
|
||||
|
||||
if (cdType == kSDMMCHOST_DetectCardByGpioCD)
|
||||
{
|
||||
SDMMCHOST_CARD_DETECT_GPIO_INIT();
|
||||
/* detect card insert status */
|
||||
if (SDMMCHOST_CARD_DETECT_GPIO_STATUS() == SDMMCHOST_CARD_INSERT_CD_LEVEL)
|
||||
{
|
||||
cardInserted = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* enable card detect through DATA3 */
|
||||
if (cdType == kSDMMCHOST_DetectCardByHostDATA3)
|
||||
{
|
||||
SDMMCHOST_CARD_DETECT_DATA3_ENABLE(base, true);
|
||||
}
|
||||
/* enable card detect status */
|
||||
SDMMCHOST_CARD_DETECT_INSERT_ENABLE(base);
|
||||
SDMMCHOST_CARD_DETECT_REMOVE_ENABLE(base);
|
||||
/* check if card is inserted */
|
||||
if (SDMMCHOST_CARD_DETECT_INSERT_STATUS(base))
|
||||
{
|
||||
cardInserted = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* notify application about the card insertion status */
|
||||
SDMMCHOST_NofiyCardInsertStatus(cardInserted, cd);
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
static void SDMMCHOST_CardDetectDeinit(void)
|
||||
{
|
||||
SDMMCEVENT_Delete(kSDMMCEVENT_CardDetect);
|
||||
s_sdInsertedFlag = false;
|
||||
}
|
||||
|
||||
void SDMMCHOST_Delay(uint32_t milliseconds)
|
||||
{
|
||||
SDMMCEVENT_Delay(milliseconds);
|
||||
}
|
||||
|
||||
status_t SDMMCHOST_WaitCardDetectStatus(SDMMCHOST_TYPE *base, const sdmmchost_detect_card_t *cd, bool waitCardStatus)
|
||||
{
|
||||
sdmmchost_detect_card_type_t cdType = kSDMMCHOST_DetectCardByGpioCD;
|
||||
|
||||
if (cd != NULL)
|
||||
{
|
||||
cdType = cd->cdType;
|
||||
}
|
||||
|
||||
if (waitCardStatus != s_sdInsertedFlag)
|
||||
{
|
||||
/* Wait card inserted. */
|
||||
do
|
||||
{
|
||||
if (cdType != kSDMMCHOST_DetectCardByGpioCD)
|
||||
{
|
||||
if (SDMMCHOST_CARD_DETECT_INSERT_STATUS(base))
|
||||
{
|
||||
s_sdInsertedFlag = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SDMMCHOST_CARD_DETECT_INSERT_STATUS(base))
|
||||
{
|
||||
s_sdInsertedFlag = true;
|
||||
}
|
||||
}
|
||||
} while (waitCardStatus != s_sdInsertedFlag);
|
||||
}
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
bool SDMMCHOST_IsCardPresent(void)
|
||||
{
|
||||
return s_sdInsertedFlag;
|
||||
}
|
||||
|
||||
void SDMMCHOST_PowerOffCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr)
|
||||
{
|
||||
if (pwr != NULL)
|
||||
{
|
||||
pwr->powerOff();
|
||||
SDMMCHOST_Delay(pwr->powerOffDelay_ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* only SD card need card detect*/
|
||||
SDMMCHOST_ENABLE_SD_POWER(false);
|
||||
/* Delay several milliseconds to make card stable. */
|
||||
SDMMCHOST_Delay(500U);
|
||||
}
|
||||
}
|
||||
|
||||
void SDMMCHOST_PowerOnCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr)
|
||||
{
|
||||
/* use user define the power on function */
|
||||
if (pwr != NULL)
|
||||
{
|
||||
pwr->powerOn();
|
||||
SDMMCHOST_Delay(pwr->powerOnDelay_ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* card power on */
|
||||
SDMMCHOST_ENABLE_SD_POWER(true);
|
||||
/* Delay several milliseconds to make card stable. */
|
||||
SDMMCHOST_Delay(500U);
|
||||
}
|
||||
}
|
||||
|
||||
status_t SDMMCHOST_Init(SDMMCHOST_CONFIG *host, void *userData)
|
||||
{
|
||||
usdhc_host_t *usdhcHost = (usdhc_host_t *)host;
|
||||
|
||||
/* init card power control */
|
||||
SDMMCHOST_INIT_SD_POWER();
|
||||
SDMMCHOST_INIT_MMC_POWER();
|
||||
|
||||
/* Initializes SDHC. */
|
||||
usdhcHost->config.dataTimeout = USDHC_DATA_TIMEOUT;
|
||||
usdhcHost->config.endianMode = USDHC_ENDIAN_MODE;
|
||||
usdhcHost->config.readWatermarkLevel = USDHC_READ_WATERMARK_LEVEL;
|
||||
usdhcHost->config.writeWatermarkLevel = USDHC_WRITE_WATERMARK_LEVEL;
|
||||
usdhcHost->config.readBurstLen = USDHC_READ_BURST_LEN;
|
||||
usdhcHost->config.writeBurstLen = USDHC_WRITE_BURST_LEN;
|
||||
|
||||
USDHC_Init(usdhcHost->base, &(usdhcHost->config));
|
||||
|
||||
/* Define transfer function. */
|
||||
usdhcHost->transfer = SDMMCHOST_TransferFunction;
|
||||
/* event init timer */
|
||||
SDMMCEVENT_InitTimer();
|
||||
/* card detect init */
|
||||
SDMMCHOST_CardDetectInit(usdhcHost->base, (userData == NULL) ? NULL : (((sdmmhostcard_usr_param_t *)userData)->cd));
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
void SDMMCHOST_Reset(SDMMCHOST_TYPE *base)
|
||||
{
|
||||
/* voltage switch to normal but not 1.8V */
|
||||
SDMMCHOST_SWITCH_VOLTAGE180V(base, false);
|
||||
/* Disable DDR mode */
|
||||
SDMMCHOST_ENABLE_DDR_MODE(base, false, 0U);
|
||||
/* disable tuning */
|
||||
SDMMCHOST_EXECUTE_STANDARD_TUNING_ENABLE(base, false);
|
||||
/* Disable HS400 mode */
|
||||
SDMMCHOST_ENABLE_HS400_MODE(base, false);
|
||||
/* Disable DLL */
|
||||
SDMMCHOST_ENABLE_STROBE_DLL(base, false);
|
||||
}
|
||||
|
||||
void SDMMCHOST_Deinit(void *host)
|
||||
{
|
||||
usdhc_host_t *usdhcHost = (usdhc_host_t *)host;
|
||||
SDMMCHOST_Reset(usdhcHost->base);
|
||||
USDHC_Deinit(usdhcHost->base);
|
||||
SDMMCHOST_CardDetectDeinit();
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := fsl_sd.c fsl_sdmmc_common.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,393 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_sdmmc_common.h"
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
SDK_ALIGN(uint32_t g_sdmmc[SDK_SIZEALIGN(SDMMC_GLOBAL_BUFFER_SIZE, SDMMC_DATA_BUFFER_ALIGN_CACHE)],
|
||||
MAX(SDMMC_DATA_BUFFER_ALIGN_CACHE, SDMMCHOST_DMA_BUFFER_ADDR_ALIGN));
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
status_t SDMMC_SelectCard(SDMMCHOST_TYPE *base,
|
||||
SDMMCHOST_TRANSFER_FUNCTION transfer,
|
||||
uint32_t relativeAddress,
|
||||
bool isSelected)
|
||||
{
|
||||
assert(transfer);
|
||||
|
||||
SDMMCHOST_TRANSFER content = {0};
|
||||
SDMMCHOST_COMMAND command = {0};
|
||||
|
||||
command.index = kSDMMC_SelectCard;
|
||||
if (isSelected)
|
||||
{
|
||||
command.argument = relativeAddress << 16U;
|
||||
command.responseType = kCARD_ResponseTypeR1;
|
||||
}
|
||||
else
|
||||
{
|
||||
command.argument = 0U;
|
||||
command.responseType = kCARD_ResponseTypeNone;
|
||||
}
|
||||
|
||||
content.command = &command;
|
||||
content.data = NULL;
|
||||
if ((kStatus_Success != transfer(base, &content)) || (command.response[0U] & SDMMC_R1_ALL_ERROR_FLAG))
|
||||
{
|
||||
return kStatus_SDMMC_TransferFailed;
|
||||
}
|
||||
|
||||
/* Wait until card to transfer state */
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t SDMMC_SendApplicationCommand(SDMMCHOST_TYPE *base,
|
||||
SDMMCHOST_TRANSFER_FUNCTION transfer,
|
||||
uint32_t relativeAddress)
|
||||
{
|
||||
assert(transfer);
|
||||
|
||||
SDMMCHOST_TRANSFER content = {0};
|
||||
SDMMCHOST_COMMAND command = {0};
|
||||
|
||||
command.index = kSDMMC_ApplicationCommand;
|
||||
command.argument = (relativeAddress << 16U);
|
||||
command.responseType = kCARD_ResponseTypeR1;
|
||||
|
||||
content.command = &command;
|
||||
content.data = 0U;
|
||||
if ((kStatus_Success != transfer(base, &content)) || (command.response[0U] & SDMMC_R1_ALL_ERROR_FLAG))
|
||||
{
|
||||
return kStatus_SDMMC_TransferFailed;
|
||||
}
|
||||
|
||||
if (!(command.response[0U] & SDMMC_MASK(kSDMMC_R1ApplicationCommandFlag)))
|
||||
{
|
||||
return kStatus_SDMMC_CardNotSupport;
|
||||
}
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t SDMMC_SetBlockCount(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer, uint32_t blockCount)
|
||||
{
|
||||
assert(transfer);
|
||||
|
||||
SDMMCHOST_TRANSFER content = {0};
|
||||
SDMMCHOST_COMMAND command = {0};
|
||||
|
||||
command.index = kSDMMC_SetBlockCount;
|
||||
command.argument = blockCount;
|
||||
command.responseType = kCARD_ResponseTypeR1;
|
||||
|
||||
content.command = &command;
|
||||
content.data = 0U;
|
||||
if ((kStatus_Success != transfer(base, &content)) || (command.response[0U] & SDMMC_R1_ALL_ERROR_FLAG))
|
||||
{
|
||||
return kStatus_SDMMC_TransferFailed;
|
||||
}
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t SDMMC_GoIdle(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer)
|
||||
{
|
||||
assert(transfer);
|
||||
|
||||
SDMMCHOST_TRANSFER content = {0};
|
||||
SDMMCHOST_COMMAND command = {0};
|
||||
|
||||
command.index = kSDMMC_GoIdleState;
|
||||
|
||||
content.command = &command;
|
||||
content.data = 0U;
|
||||
if (kStatus_Success != transfer(base, &content))
|
||||
{
|
||||
return kStatus_SDMMC_TransferFailed;
|
||||
}
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t SDMMC_SetBlockSize(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer, uint32_t blockSize)
|
||||
{
|
||||
assert(transfer);
|
||||
|
||||
SDMMCHOST_TRANSFER content = {0};
|
||||
SDMMCHOST_COMMAND command = {0};
|
||||
|
||||
command.index = kSDMMC_SetBlockLength;
|
||||
command.argument = blockSize;
|
||||
command.responseType = kCARD_ResponseTypeR1;
|
||||
|
||||
content.command = &command;
|
||||
content.data = 0U;
|
||||
if ((kStatus_Success != transfer(base, &content)) || (command.response[0U] & SDMMC_R1_ALL_ERROR_FLAG))
|
||||
{
|
||||
return kStatus_SDMMC_TransferFailed;
|
||||
}
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t SDMMC_SetCardInactive(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer)
|
||||
{
|
||||
assert(transfer);
|
||||
|
||||
SDMMCHOST_TRANSFER content = {0};
|
||||
SDMMCHOST_COMMAND command = {0};
|
||||
|
||||
command.index = kSDMMC_GoInactiveState;
|
||||
command.argument = 0U;
|
||||
command.responseType = kCARD_ResponseTypeNone;
|
||||
|
||||
content.command = &command;
|
||||
content.data = 0U;
|
||||
if ((kStatus_Success != transfer(base, &content)))
|
||||
{
|
||||
return kStatus_SDMMC_TransferFailed;
|
||||
}
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t SDMMC_SwitchVoltage(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer)
|
||||
{
|
||||
assert(transfer);
|
||||
|
||||
SDMMCHOST_TRANSFER content = {0};
|
||||
SDMMCHOST_COMMAND command = {0};
|
||||
status_t error = kStatus_Success;
|
||||
|
||||
if (kSDMMCHOST_SupportV180 != SDMMCHOST_NOT_SUPPORT)
|
||||
{
|
||||
command.index = kSD_VoltageSwitch;
|
||||
command.argument = 0U;
|
||||
command.responseType = kCARD_ResponseTypeR1;
|
||||
|
||||
content.command = &command;
|
||||
content.data = NULL;
|
||||
if (kStatus_Success != transfer(base, &content))
|
||||
{
|
||||
return kStatus_SDMMC_TransferFailed;
|
||||
}
|
||||
/* disable card clock */
|
||||
SDMMCHOST_ENABLE_CARD_CLOCK(base, false);
|
||||
|
||||
/* check data line and cmd line status */
|
||||
if ((GET_SDMMCHOST_STATUS(base) &
|
||||
(CARD_DATA1_STATUS_MASK | CARD_DATA2_STATUS_MASK | CARD_DATA3_STATUS_MASK | CARD_DATA0_NOT_BUSY)) != 0U)
|
||||
{
|
||||
return kStatus_SDMMC_SwitchVoltageFail;
|
||||
}
|
||||
|
||||
/* host switch to 1.8V */
|
||||
SDMMCHOST_SWITCH_VOLTAGE180V(base, true);
|
||||
|
||||
SDMMCHOST_Delay(100U);
|
||||
|
||||
/*enable sd clock*/
|
||||
SDMMCHOST_ENABLE_CARD_CLOCK(base, true);
|
||||
/*enable force clock on*/
|
||||
SDMMCHOST_FORCE_SDCLOCK_ON(base, true);
|
||||
/* dealy 1ms,not exactly correct when use while */
|
||||
SDMMCHOST_Delay(10U);
|
||||
/*disable force clock on*/
|
||||
SDMMCHOST_FORCE_SDCLOCK_ON(base, false);
|
||||
|
||||
/* check data line and cmd line status */
|
||||
if ((GET_SDMMCHOST_STATUS(base) &
|
||||
(CARD_DATA1_STATUS_MASK | CARD_DATA2_STATUS_MASK | CARD_DATA3_STATUS_MASK | CARD_DATA0_NOT_BUSY)) == 0U)
|
||||
{
|
||||
error = kStatus_SDMMC_SwitchVoltageFail;
|
||||
/* power reset the card */
|
||||
SDMMCHOST_ENABLE_SD_POWER(false);
|
||||
SDMMCHOST_Delay(10U);
|
||||
SDMMCHOST_ENABLE_SD_POWER(true);
|
||||
SDMMCHOST_Delay(10U);
|
||||
/* re-check the data line status */
|
||||
if ((GET_SDMMCHOST_STATUS(base) &
|
||||
(CARD_DATA1_STATUS_MASK | CARD_DATA2_STATUS_MASK | CARD_DATA3_STATUS_MASK | CARD_DATA0_NOT_BUSY)))
|
||||
{
|
||||
error = kStatus_SDMMC_SwitchVoltage18VFail33VSuccess;
|
||||
SDMMC_LOG(
|
||||
"\r\nNote: Current card support 1.8V, but board don't support, so sdmmc switch back to 3.3V.");
|
||||
}
|
||||
else
|
||||
{
|
||||
SDMMC_LOG(
|
||||
"\r\nError: Current card support 1.8V, but board don't support, sdmmc tried to switch back\
|
||||
to 3.3V, but failed, please check board setting.");
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
else
|
||||
{
|
||||
return kStatus_SDMMC_HostNotSupport;
|
||||
}
|
||||
}
|
||||
|
||||
status_t SDMMC_SwitchToVoltage(SDMMCHOST_TYPE *base,
|
||||
SDMMCHOST_TRANSFER_FUNCTION transfer,
|
||||
sdmmchost_card_switch_voltage_t switchVoltageFunc)
|
||||
{
|
||||
assert(transfer);
|
||||
|
||||
SDMMCHOST_TRANSFER content = {0};
|
||||
SDMMCHOST_COMMAND command = {0};
|
||||
status_t error = kStatus_Success;
|
||||
|
||||
if (kSDMMCHOST_SupportV180 != SDMMCHOST_NOT_SUPPORT)
|
||||
{
|
||||
command.index = kSD_VoltageSwitch;
|
||||
command.argument = 0U;
|
||||
command.responseType = kCARD_ResponseTypeR1;
|
||||
|
||||
content.command = &command;
|
||||
content.data = NULL;
|
||||
if (kStatus_Success != transfer(base, &content))
|
||||
{
|
||||
return kStatus_SDMMC_TransferFailed;
|
||||
}
|
||||
/* disable card clock */
|
||||
SDMMCHOST_ENABLE_CARD_CLOCK(base, false);
|
||||
|
||||
/* check data line and cmd line status */
|
||||
if ((GET_SDMMCHOST_STATUS(base) &
|
||||
(CARD_DATA1_STATUS_MASK | CARD_DATA2_STATUS_MASK | CARD_DATA3_STATUS_MASK | CARD_DATA0_NOT_BUSY)) != 0U)
|
||||
{
|
||||
return kStatus_SDMMC_SwitchVoltageFail;
|
||||
}
|
||||
|
||||
if (switchVoltageFunc != NULL)
|
||||
{
|
||||
switchVoltageFunc();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* host switch to 1.8V */
|
||||
SDMMCHOST_SWITCH_VOLTAGE180V(base, true);
|
||||
}
|
||||
|
||||
SDMMCHOST_Delay(100U);
|
||||
|
||||
/*enable sd clock*/
|
||||
SDMMCHOST_ENABLE_CARD_CLOCK(base, true);
|
||||
/*enable force clock on*/
|
||||
SDMMCHOST_FORCE_SDCLOCK_ON(base, true);
|
||||
/* dealy 1ms,not exactly correct when use while */
|
||||
SDMMCHOST_Delay(10U);
|
||||
/*disable force clock on*/
|
||||
SDMMCHOST_FORCE_SDCLOCK_ON(base, false);
|
||||
|
||||
/* check data line and cmd line status */
|
||||
if ((GET_SDMMCHOST_STATUS(base) &
|
||||
(CARD_DATA1_STATUS_MASK | CARD_DATA2_STATUS_MASK | CARD_DATA3_STATUS_MASK | CARD_DATA0_NOT_BUSY)) == 0U)
|
||||
{
|
||||
error = kStatus_SDMMC_SwitchVoltageFail;
|
||||
/* power reset the card */
|
||||
SDMMCHOST_ENABLE_SD_POWER(false);
|
||||
SDMMCHOST_Delay(10U);
|
||||
SDMMCHOST_ENABLE_SD_POWER(true);
|
||||
SDMMCHOST_Delay(10U);
|
||||
/* re-check the data line status */
|
||||
if ((GET_SDMMCHOST_STATUS(base) &
|
||||
(CARD_DATA1_STATUS_MASK | CARD_DATA2_STATUS_MASK | CARD_DATA3_STATUS_MASK | CARD_DATA0_NOT_BUSY)))
|
||||
{
|
||||
error = kStatus_SDMMC_SwitchVoltage18VFail33VSuccess;
|
||||
SDMMC_LOG(
|
||||
"\r\nNote: Current card support 1.8V, but board don't support, so sdmmc switch back to 3.3V.");
|
||||
}
|
||||
else
|
||||
{
|
||||
SDMMC_LOG(
|
||||
"\r\nError: Current card support 1.8V, but board don't support, sdmmc tried to switch back\
|
||||
to 3.3V, but failed, please check board setting.");
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
else
|
||||
{
|
||||
return kStatus_SDMMC_HostNotSupport;
|
||||
}
|
||||
}
|
||||
|
||||
status_t SDMMC_ExecuteTuning(SDMMCHOST_TYPE *base,
|
||||
SDMMCHOST_TRANSFER_FUNCTION transfer,
|
||||
uint32_t tuningCmd,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
SDMMCHOST_TRANSFER content = {0U};
|
||||
SDMMCHOST_COMMAND command = {0U};
|
||||
SDMMCHOST_DATA data = {0U};
|
||||
uint32_t buffer[32U] = {0U};
|
||||
bool tuningError = true;
|
||||
|
||||
command.index = tuningCmd;
|
||||
command.argument = 0U;
|
||||
command.responseType = kCARD_ResponseTypeR1;
|
||||
|
||||
data.blockSize = blockSize;
|
||||
data.blockCount = 1U;
|
||||
data.rxData = buffer;
|
||||
/* add this macro for adpter to different driver */
|
||||
SDMMCHOST_ENABLE_TUNING_FLAG(data);
|
||||
|
||||
content.command = &command;
|
||||
content.data = &data;
|
||||
|
||||
/* enable the standard tuning */
|
||||
SDMMCHOST_EXECUTE_STANDARD_TUNING_ENABLE(base, true);
|
||||
|
||||
while (true)
|
||||
{
|
||||
/* send tuning block */
|
||||
if ((kStatus_Success != transfer(base, &content)))
|
||||
{
|
||||
return kStatus_SDMMC_TransferFailed;
|
||||
}
|
||||
SDMMCHOST_Delay(1U);
|
||||
|
||||
/*wait excute tuning bit clear*/
|
||||
if ((SDMMCHOST_EXECUTE_STANDARD_TUNING_STATUS(base) != 0U))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if tuning error , re-tuning again */
|
||||
if ((SDMMCHOST_CHECK_TUNING_ERROR(base) != 0U) && tuningError)
|
||||
{
|
||||
tuningError = false;
|
||||
/* enable the standard tuning */
|
||||
SDMMCHOST_EXECUTE_STANDARD_TUNING_ENABLE(base, true);
|
||||
SDMMCHOST_ADJUST_TUNING_DELAY(base, SDMMCHOST_STANDARD_TUNING_START);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* check tuning result*/
|
||||
if (SDMMCHOST_EXECUTE_STANDARD_TUNING_RESULT(base) == 0U)
|
||||
{
|
||||
return kStatus_SDMMC_TuningFail;
|
||||
}
|
||||
|
||||
#if !SDMMC_ENABLE_SOFTWARE_TUNING
|
||||
SDMMCHOST_AUTO_TUNING_ENABLE(base, true);
|
||||
#endif
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
|
@ -174,6 +174,8 @@ KERNELPATHS :=-I$(BSP_ROOT) \
|
|||
-I$(KERNEL_ROOT)/arch/arm/cortex-m7 \
|
||||
-I$(BSP_ROOT)/third_party_driver \
|
||||
-I$(BSP_ROOT)/third_party_driver/include \
|
||||
-I$(BSP_ROOT)/third_party_driver/sdio/sdmmc/inc \
|
||||
-I$(BSP_ROOT)/third_party_driver/sdio/sdmmc/port \
|
||||
-I$(BSP_ROOT)/third_party_driver/ethernet \
|
||||
-I$(BSP_ROOT)/third_party_driver/ethernet/ksz8081 \
|
||||
-I$(BSP_ROOT)/third_party_driver/MIMXRT1052 \
|
||||
|
|
Loading…
Reference in New Issue