add sd card driver part for ok1052-c board

This commit is contained in:
Liu_Weichao 2022-01-26 17:14:43 +08:00
parent d5ff9259a0
commit 7b32e213ce
34 changed files with 11901 additions and 28 deletions

View File

@ -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;
}

View File

@ -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 MPUclockmemory init
2. support imxrt1052-board uartsemcsdio 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
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,5 @@
SRC_DIR := sdmmc
SRC_FILES := connect_sdio.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -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;
}

View File

@ -0,0 +1,3 @@
SRC_DIR += port src
include $(KERNEL_ROOT)/compiler.mk

View File

@ -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_*/

View File

@ -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_*/

View File

@ -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_*/

View File

@ -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_ */

View File

@ -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 */

View File

@ -0,0 +1,3 @@
SRC_DIR += usdhc
include $(KERNEL_ROOT)/compiler.mk

View File

@ -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_*/

View File

@ -0,0 +1,3 @@
SRC_DIR += polling
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,3 @@
SRC_FILES := fsl_sdmmc_host.c fsl_sdmmc_event.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -0,0 +1,3 @@
SRC_FILES := fsl_sdmmc_host.c fsl_sdmmc_event.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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

View File

@ -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;
}

View File

@ -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 \