1、support sd card driver for ok1052-c board by NXP uSDHC library; 2、support sd card mount for fatfs from Liu_WeiChao

it is OK
This commit is contained in:
xuedongliang 2022-02-24 16:15:16 +08:00
commit f1e8216944
96 changed files with 33523 additions and 60 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

@ -29,6 +29,9 @@
#define UART1_IRQn 20
#define UART2_IRQn 21
#define USB1_IRQn 113
#define USB2_IRQn 112
int32 ArchEnableHwIrq(uint32 irq_num);
int32 ArchDisableHwIrq(uint32 irq_num);

View File

@ -28,7 +28,7 @@ CONFIG_BSP_USING_UART=y
# CONFIG_BSP_USING_UART4 is not set
# CONFIG_BSP_USING_UART5 is not set
# CONFIG_BSP_USING_USB is not set
# CONFIG_BSP_USING_USBH is not set
# CONFIG_BSP_USING_STM32_USBH is not set
#
# Hardware feature

View File

@ -120,7 +120,7 @@ endif
menuconfig BSP_USING_USB
bool "Using USB device"
default n
select BSP_USING_USBH
select BSP_USING_STM32_USBH
select RESOURCES_USB
select RESOURCES_USB_HOST
select USBH_MSTORAGE

View File

@ -1,7 +1,7 @@
config BSP_USING_USBH
config BSP_USING_STM32_USBH
bool "Using usb host"
default y
if BSP_USING_USBH
if BSP_USING_STM32_USBH
config USB_BUS_NAME
string "usb bus name"
default "usb"

View File

@ -31,7 +31,7 @@ Modification:
*************************************************/
#include <xiuos.h>
#include <usb_host.h>
#include <stm32_usb_host.h>
#include <hardware_gpio.h>
#include <hardware_rcc.h>
#include <stm32f4xx.h>

View File

@ -40,6 +40,13 @@ menu "ok1052-c feature"
int "stack size for interrupt"
default 4096
menu "config board peripheral"
config MOUNT_SDCARD
bool "mount cd card"
default n
select BSP_USING_SDIO
endmenu
endmenu

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);
@ -37,6 +40,24 @@ extern int ExtSramInit(void);
#endif
#endif
#if defined(FS_VFS) && defined(MOUNT_SDCARD)
#include <iot-vfs.h>
/**
* @description: Mount SD card
* @return 0
*/
int MountSDCard(void)
{
if (MountFilesystem(SDIO_BUS_NAME, SDIO_DEVICE_NAME, SDIO_DRIVER_NAME, FSTYPE_FATFS, "/") == 0)
KPrintf("sd card mount to '/'");
else
KPrintf("sd card mount to '/' failed!");
return 0;
}
#endif
#if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED
#include "fsl_lpi2c.h"
#endif /* SDK_I2C_BASED_COMPONENT_USED */
@ -621,13 +642,11 @@ void InitBoardHardware()
CLOCK_SetMux(kCLOCK_SemcMux, 1);
CLOCK_SetDiv(kCLOCK_SemcDiv, 1);
if (BOARD_InitSEMC() != kStatus_Success)
{
if (BOARD_InitSEMC() != kStatus_Success) {
KPrintf("\r\n SEMC Init Failed\r\n");
}
#ifdef MEM_EXTERN_SRAM
else
{
else {
ExtSramInit();
}
#endif
@ -640,8 +659,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

@ -241,9 +241,9 @@ SECTIONS
stack_end = .;
__StackTop = .;
heap_start = .;
} > m_data2
} > m_data
PROVIDE(heap_end = ORIGIN(m_data2) + LENGTH(m_data2));
PROVIDE(heap_end = ORIGIN(m_data) + LENGTH(m_data));
.ARM.attributes 0 : { *(.ARM.attributes) }
}

View File

@ -13,8 +13,23 @@ 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 n
select RESOURCES_SDIO
if BSP_USING_SDIO
source "$BSP_DIR/third_party_driver/sdio/Kconfig"
endif
menuconfig BSP_USING_USB
bool "Using USB device"
default n
select RESOURCES_USB
if BSP_USING_USB
source "$BSP_DIR/third_party_driver/usb/Kconfig"
endif

View File

@ -12,4 +12,12 @@ ifeq ($(CONFIG_BSP_USING_SEMC),y)
SRC_DIR += semc
endif
ifeq ($(CONFIG_BSP_USING_SDIO),y)
SRC_DIR += sdio
endif
ifeq ($(CONFIG_BSP_USING_USB),y)
SRC_DIR += usb
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

File diff suppressed because it is too large Load Diff

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

@ -0,0 +1,53 @@
/*
* 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_usb.h
* @brief define ok1052-board usb function and struct
* @version 2.0
* @author AIIT XUOS Lab
* @date 2022-02-09
*/
#ifndef CONNECT_USB_H
#define CONNECT_USB_H
#include <device.h>
#include <fsl_common.h>
#include <usb_host_config.h>
#include <usb_host.h>
#include <usb_host_msd.h>
#include <host_msd_command.h>
#include <usb_phy.h>
#if defined(FS_VFS)
#include <iot-vfs.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define CONTROLLER_ID kUSB_ControllerEhci1
#define USB_HOST_INTERRUPT_PRIORITY (3U)
#define USB_HOST_STACK_SIZE 4096
#define USB_SINGLE_BLOCK_SIZE 512
int Imrt1052HwUsbHostInit(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

File diff suppressed because it is too large Load Diff

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,367 @@
/*
* 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;
args->size_perbank = g_sd.blockSize;
args->block_size = g_sd.blockSize;
args->bank_num = g_sd.blockCount;
}
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;
uint32 sector = read_param->pos;
uint32 block_num = read_param->size;
uint8 *read_buffer = (uint8 *)read_param->buffer;
KSemaphoreObtain(sd_lock, WAITING_FOREVER);
if (kStatus_Success != SD_ReadBlocks(&g_sd, read_buffer, sector, block_num)) {
KPrintf("Read multiple data blocks failed.\r\n");
return 0;
}
KSemaphoreAbandon(sd_lock);
return read_param->size;
}
static uint32 SdioWrite(void *dev, struct BusBlockWriteParam *write_param)
{
uint8 ret = EOK;
uint32 sector = write_param->pos;
uint32 block_num = write_param->size;
const uint8 *write_buffer = (uint8 *)write_param->buffer;
KSemaphoreObtain(sd_lock, WAITING_FOREVER);
if (kStatus_Success != SD_WriteBlocks(&g_sd, write_buffer, sector, block_num)) {
KPrintf("Write multiple data blocks failed.\r\n");
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

@ -0,0 +1,15 @@
config BSP_USING_NXP_USBH
bool "Using usb host by NXP library"
default n
if BSP_USING_NXP_USBH
config USB_BUS_NAME
string "usb bus name"
default "usb"
config USB_DRIVER_NAME
string "usb bus driver name"
default "usb_drv"
config USB_DEVICE_NAME
string "usb bus device name"
default "usb_dev"
endif

View File

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

View File

@ -0,0 +1,296 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file connect_usb.c
* @brief support usb host function using bus driver framework on OK1052 board
* @version 2.0
* @author AIIT XUOS Lab
* @date 2022-02-09
*/
/*************************************************
File name: connect_usb.c
Description: support imxrt1052-board usb host configure and sdio bus register function
Others: take SDK_2.6.1_MIMXRT1052xxxxB/boards/evkbimxrt1050/usb_examples/usb_host_msd_command for references
History:
1. Date: 2022-02-09
Author: AIIT XUOS Lab
Modification:
1. support imxrt1052-board usb host configure, write and read
2. support imxrt1052-board usb host bus device and driver register
*************************************************/
#include <board.h>
#include <connect_usb.h>
#define BSP_USING_NXP_USBH
#ifdef BSP_USING_NXP_USBH
/*! @brief USB host msd command instance global variable */
extern usb_host_msd_command_instance_t g_MsdCommandInstance;
usb_host_handle g_HostHandle;
extern usb_status_t USB_HostMsdReadApi(usb_host_msd_command_instance_t *msdCommandInstance, uint8_t *buffer, uint32_t pos, uint32_t block_size, uint32_t block_num);
extern usb_status_t USB_HostMsdWriteApi(usb_host_msd_command_instance_t *msdCommandInstance, const uint8_t *buffer, uint32_t pos, uint32_t block_size, uint32_t block_num);
//USB HOST ISR
void UsbOtg2IrqHandler(int irqn, void *arg)
{
x_base lock = 0;
lock = DISABLE_INTERRUPT();
USB_HostEhciIsrFunction(g_HostHandle);
ENABLE_INTERRUPT(lock);
}
DECLARE_HW_IRQ(USB2_IRQn, UsbOtg2IrqHandler, NONE);
void UsbHostClockInit(void)
{
usb_phy_config_struct_t phyConfig = {
BOARD_USB_PHY_D_CAL,
BOARD_USB_PHY_TXCAL45DP,
BOARD_USB_PHY_TXCAL45DM,
};
if (CONTROLLER_ID == kUSB_ControllerEhci0) {
CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U);
} else {
CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U);
}
USB_EhciPhyInit(CONTROLLER_ID, BOARD_XTAL0_CLK_HZ, &phyConfig);
}
void UsbHostIsrEnable(void)
{
uint8_t irqNumber;
uint8_t usbHOSTEhciIrq[] = USBHS_IRQS;
irqNumber = usbHOSTEhciIrq[CONTROLLER_ID - kUSB_ControllerEhci0];
/* USB_HOST_CONFIG_EHCI */
/* Install isr, set priority, and enable IRQ. */
NVIC_SetPriority((IRQn_Type)irqNumber, USB_HOST_INTERRUPT_PRIORITY);
EnableIRQ((IRQn_Type)irqNumber);
}
void UsbHostTaskFn(void *param)
{
USB_HostEhciTaskFunction(param);
}
/*!
* @brief USB isr function.
*/
static usb_status_t UsbHostEvent(usb_device_handle deviceHandle,
usb_host_configuration_handle configurationHandle,
uint32_t eventCode)
{
usb_status_t status = kStatus_USB_Success;
switch (eventCode)
{
case kUSB_HostEventAttach:
KPrintf("usb device attached\n");
status = USB_HostMsdEvent(deviceHandle, configurationHandle, eventCode);
break;
case kUSB_HostEventNotSupported:
KPrintf("device not supported.\r\n");
break;
case kUSB_HostEventEnumerationDone:
status = USB_HostMsdEvent(deviceHandle, configurationHandle, eventCode);
break;
case kUSB_HostEventDetach:
KPrintf("usb device detached\n");
status = USB_HostMsdEvent(deviceHandle, configurationHandle, eventCode);
break;
default:
break;
}
return status;
}
static void UsbHostApplicationInit(void)
{
usb_status_t status = kStatus_USB_Success;
UsbHostClockInit();
status = USB_HostInit(CONTROLLER_ID, &g_HostHandle, UsbHostEvent);
if (status != kStatus_USB_Success) {
KPrintf("host init error\r\n");
return;
}
UsbHostIsrEnable();
KPrintf("host init done\r\n");
}
#if defined(FS_VFS)
void UsbMountFileSystem()
{
if (MountFilesystem(USB_BUS_NAME, USB_DEVICE_NAME, USB_DRIVER_NAME, FSTYPE_FATFS, UDISK_MOUNTPOINT) == 0)
KPrintf("Mount FAT on Udisk successful.\n");
else
KPrintf("Mount FAT on Udisk failed.\n");
}
void UsbUnmountFileSystem()
{
UnmountFileSystem(UDISK_MOUNTPOINT);
}
#endif
static uint32 UsbHostOpen(void *dev)
{
return EOK;
}
static uint32 UsbHostClose(void *dev)
{
return EOK;
}
static uint32 UsbHostRead(void *dev, struct BusBlockReadParam *read_param)
{
usb_status_t status;
status = USB_HostMsdReadApi(&g_MsdCommandInstance, (uint8 *)read_param->buffer, read_param->pos, USB_SINGLE_BLOCK_SIZE, read_param->size);
if (kStatus_USB_Success == status) {
return read_param->size;
}
return 0;
}
static uint32 UsbHostWrite(void *dev, struct BusBlockWriteParam *write_param)
{
usb_status_t status;
status = USB_HostMsdWriteApi(&g_MsdCommandInstance, (const uint8 *)write_param->buffer, write_param->pos, USB_SINGLE_BLOCK_SIZE, write_param->size);
if (kStatus_USB_Success == status) {
return write_param->size;
}
return 0;
}
/*manage the usb device operations*/
static const struct UsbDevDone dev_done =
{
.open = UsbHostOpen,
.close = UsbHostClose,
.write = UsbHostWrite,
.read = UsbHostRead,
};
static void UsbHostTask(void* parameter)
{
while (1) {
UsbHostTaskFn(g_HostHandle);
USB_HostMsdTask(&g_MsdCommandInstance);
}
}
/*Init usb host bus、driver*/
static int BoardUsbBusInit(struct UsbBus *usb_bus, struct UsbDriver *usb_driver)
{
x_err_t ret = EOK;
/*Init the usb bus */
ret = UsbBusInit(usb_bus, USB_BUS_NAME);
if (EOK != ret) {
KPrintf("board_usb_init UsbBusInit error %d\n", ret);
return ERROR;
}
/*Init the usb driver*/
ret = UsbDriverInit(usb_driver, USB_DRIVER_NAME);
if (EOK != ret){
KPrintf("board_usb_init UsbDriverInit error %d\n", ret);
return ERROR;
}
/*Attach the usb driver to the usb bus*/
ret = UsbDriverAttachToBus(USB_DRIVER_NAME, USB_BUS_NAME);
if (EOK != ret) {
KPrintf("board_usb_init USEDriverAttachToBus error %d\n", ret);
return ERROR;
}
return ret;
}
/*Attach the usb device to the usb bus*/
static int BoardUsbDevBend(void)
{
x_err_t ret = EOK;
static struct UsbHardwareDevice usb_device;
memset(&usb_device, 0, sizeof(struct UsbHardwareDevice));
usb_device.dev_done = &dev_done;
ret = USBDeviceRegister(&usb_device, NONE, USB_DEVICE_NAME);
if (EOK != ret) {
KPrintf("USBDeviceRegister device %s error %d\n", USB_DEVICE_NAME, ret);
return ERROR;
}
ret = USBDeviceAttachToBus(USB_DEVICE_NAME, USB_BUS_NAME);
if (EOK != ret) {
KPrintf("USBDeviceAttachToBus device %s error %d\n", USB_DEVICE_NAME, ret);
return ERROR;
}
return ret;
}
/*RT1052 BOARD USB INIT*/
int Imrt1052HwUsbHostInit(void)
{
x_err_t ret = EOK;
int32 usb_host_task = 0;
static struct UsbBus usb_bus;
memset(&usb_bus, 0, sizeof(struct UsbBus));
static struct UsbDriver usb_driver;
memset(&usb_driver, 0, sizeof(struct UsbDriver));
UsbHostApplicationInit();
ret = BoardUsbBusInit(&usb_bus, &usb_driver);
if (EOK != ret) {
KPrintf("BoardUsbBusInit error ret %u\n", ret);
return ERROR;
}
ret = BoardUsbDevBend();
if (EOK != ret) {
KPrintf("BoardUsbDevBend error ret %u\n", ret);
return ERROR;
}
usb_host_task = KTaskCreate("usbh", UsbHostTask, NONE,
USB_HOST_STACK_SIZE, 8);
if(usb_host_task < 0) {
KPrintf("usb_host_task create failed ...%s %d.\n", __FUNCTION__,__LINE__);
return ERROR;
}
StartupKTask(usb_host_task);
return ret;
}
#endif

View File

@ -0,0 +1,5 @@
SRC_DIR += host phy osa
SRC_FILES := host_msd_command.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,5 @@
SRC_DIR += class
SRC_FILES += usb_host_devices.c usb_host_framework.c usb_host_ehci.c usb_host_hci.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,3 @@
SRC_FILES += usb_host_msd_ufi.c usb_host_msd.c usb_host_hub.c usb_host_hub_app.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,608 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "usb_host_config.h"
#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
#include "usb_host.h"
#include "usb_host_hub.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief hub control transfer callback.
*
* @param param callback parameter.
* @param transfer callback transfer.
* @param status transfer status.
*/
static void USB_HostHubControlCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
/*!
* @brief hub interrupt in transfer callback.
*
* @param param callback parameter.
* @param transfer callback transfer.
* @param status transfer status.
*/
static void USB_HostHubInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
/*!
* @brief USB_HostHubSendPortReset's transfer callback.
*
* @param param callback parameter.
* @param transfer callback transfer.
* @param status transfer status.
*/
static void USB_HostHubResetCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
/*!
* @brief hub control transfer common code.
*
* @param classHandle the class handle.
* @param requestType request type.
* @param request setup packet request field.
* @param wvalue setup packet wValue field.
* @param windex setup packet wIndex field.
* @param buffer the buffer pointer.
* @param bufferLength the buffer length.
* @param callbackFn this callback is called after this function completes.
* @param callbackParam the first parameter in the callback function.
*
* @return kStatus_USB_Success or error codes.
*/
static usb_status_t USB_HostHubClassRequestCommon(usb_host_class_handle classHandle,
uint8_t requestType,
uint8_t request,
uint16_t wvalue,
uint16_t windex,
uint8_t *buffer,
uint16_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam);
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
static void USB_HostHubControlCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
{
usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)param;
hubInstance->controlTransfer = NULL;
if (hubInstance->controlCallbackFn)
{
/* callback to application, callback function is initialized in the USB_HostPrinterControl,
USB_HostPrinterSetInterface
or USB_HostHubClassRequestCommon, but is the same function */
hubInstance->controlCallbackFn(hubInstance->controlCallbackParam, transfer->transferBuffer,
transfer->transferSofar, status); /* callback to application */
}
USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
}
static void USB_HostHubInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
{
usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)param;
if (hubInstance->inCallbackFn)
{
/* callback to application, callback function is initialized in the USB_HostHubInterruptRecv */
hubInstance->inCallbackFn(hubInstance->inCallbackParam, transfer->transferBuffer, transfer->transferSofar,
status); /* callback to application */
}
USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
}
static void USB_HostHubResetCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
{
usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)param;
/* note: there is not callback to application, the re-enumeration will start automatically after reset. */
USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
}
static usb_status_t USB_HostHubClassRequestCommon(usb_host_class_handle classHandle,
uint8_t requestType,
uint8_t request,
uint16_t wvalue,
uint16_t windex,
uint8_t *buffer,
uint16_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam)
{
usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
usb_host_transfer_t *transfer;
if (hubInstance->controlTransfer != NULL)
{
return kStatus_USB_Busy;
}
/* get transfer */
if (USB_HostMallocTransfer(hubInstance->hostHandle, &transfer) != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("error to get transfer\r\n");
#endif
return kStatus_USB_Error;
}
/* save hub application callback */
hubInstance->controlCallbackFn = callbackFn;
hubInstance->controlCallbackParam = callbackParam;
/* initialize transfer */
transfer->transferBuffer = buffer;
transfer->transferLength = bufferLength;
transfer->callbackFn = USB_HostHubControlCallback;
transfer->callbackParam = hubInstance;
transfer->setupPacket->bmRequestType = requestType;
transfer->setupPacket->bRequest = request;
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(wvalue);
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(windex);
transfer->setupPacket->wLength = USB_SHORT_TO_LITTLE_ENDIAN(bufferLength);
/* send transfer */
if (USB_HostSendSetup(hubInstance->hostHandle, hubInstance->controlPipe, transfer) != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("Error in hid get report descriptor\r\n");
#endif
USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
return kStatus_USB_Error;
}
hubInstance->controlTransfer = transfer; /* record the on-going setup transfer */
return kStatus_USB_Success;
}
usb_status_t USB_HostHubInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle)
{
/* malloc the hub instance */
usb_host_hub_instance_t *hubInstance =
(usb_host_hub_instance_t *)USB_OsaMemoryAllocate(sizeof(usb_host_hub_instance_t));
uint32_t infoValue;
if (hubInstance == NULL)
{
return kStatus_USB_AllocFail;
}
#if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
hubInstance->hubDescriptor = (uint8_t *)SDK_Malloc(7 + (USB_HOST_HUB_MAX_PORT >> 3) + 1, USB_CACHE_LINESIZE);
hubInstance->portStatusBuffer = (uint8_t *)SDK_Malloc(4, USB_CACHE_LINESIZE);
hubInstance->hubStatusBuffer = (uint8_t *)SDK_Malloc(4, USB_CACHE_LINESIZE);
hubInstance->hubBitmapBuffer = (uint8_t *)SDK_Malloc((USB_HOST_HUB_MAX_PORT >> 3) + 1, USB_CACHE_LINESIZE);
#endif
/* initialize hub instance structure */
hubInstance->deviceHandle = deviceHandle;
hubInstance->interfaceHandle = NULL;
USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetHostHandle, &infoValue);
hubInstance->hostHandle = (usb_host_handle)infoValue;
USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceControlPipe, &infoValue);
hubInstance->controlPipe = (usb_host_pipe_handle)infoValue;
USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceLevel, &infoValue);
hubInstance->hubLevel = infoValue;
*classHandle = hubInstance; /* return the hub class handle */
return kStatus_USB_Success;
}
usb_status_t USB_HostHubSetInterface(usb_host_class_handle classHandle,
usb_host_interface_handle interfaceHandle,
uint8_t alternateSetting,
transfer_callback_t callbackFn,
void *callbackParam)
{
usb_status_t status;
usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
usb_host_interface_t *interface = (usb_host_interface_t *)interfaceHandle;
usb_descriptor_endpoint_t *epDesc = NULL;
usb_host_pipe_init_t pipeInit;
uint8_t epIndex;
if (classHandle == NULL)
{
return kStatus_USB_InvalidHandle;
}
hubInstance->interfaceHandle = interfaceHandle; /* save the interface handle */
/* notify the host driver that the interface is used by class */
status = USB_HostOpenDeviceInterface(hubInstance->deviceHandle, interfaceHandle);
if (status != kStatus_USB_Success)
{
return status;
}
/* close opened hub interrupt pipe */
if (hubInstance->interruptPipe != NULL)
{
status = USB_HostCancelTransfer(hubInstance->hostHandle, hubInstance->interruptPipe, NULL);
status = USB_HostClosePipe(hubInstance->hostHandle, hubInstance->interruptPipe);
if (status != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("error when close pipe\r\n");
#endif
}
hubInstance->interruptPipe = NULL;
}
/* open hub interrupt pipe */
for (epIndex = 0; epIndex < interface->epCount; ++epIndex)
{
epDesc = interface->epList[epIndex].epDesc;
if (((epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
((epDesc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_INTERRUPT))
{
/* get pipe information from endpoint descriptor */
pipeInit.devInstance = hubInstance->deviceHandle;
pipeInit.pipeType = USB_ENDPOINT_INTERRUPT;
pipeInit.direction = USB_IN;
pipeInit.endpointAddress = (epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
pipeInit.interval = epDesc->bInterval;
pipeInit.maxPacketSize = (uint16_t)(USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK);
pipeInit.numberPerUframe = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK);
pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
/* open hub interrupt in pipe */
status = USB_HostOpenPipe(hubInstance->hostHandle, &hubInstance->interruptPipe, &pipeInit);
if (status != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("usb_host_hid_set_interface fail to open pipe\r\n");
#endif
return kStatus_USB_Error;
}
break;
}
}
/* hub don't support alternatesetting that is not 0 */
if (alternateSetting == 0)
{
if (callbackFn != NULL)
{
callbackFn(callbackParam, NULL, 0, kStatus_USB_Success);
}
}
else
{
#ifdef HOST_ECHO
usb_echo("host don't support alternate setting\r\n");
#endif
return kStatus_USB_Error;
}
return status;
}
usb_status_t USB_HostHubDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle)
{
usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
uint8_t status;
if (deviceHandle == NULL)
{
return kStatus_USB_InvalidHandle;
}
if (classHandle != NULL)
{
/* close opened hub interrupt pipe */
if (hubInstance->interruptPipe != NULL)
{
status = USB_HostCancelTransfer(hubInstance->hostHandle, hubInstance->interruptPipe, NULL);
status = USB_HostClosePipe(hubInstance->hostHandle, hubInstance->interruptPipe);
if (status != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("hub close interrupt pipe error\r\n");
#endif
}
hubInstance->interruptPipe = NULL;
}
/* cancel control transfer if exist */
if ((hubInstance->controlPipe != NULL) && (hubInstance->controlTransfer != NULL))
{
status =
USB_HostCancelTransfer(hubInstance->hostHandle, hubInstance->controlPipe, hubInstance->controlTransfer);
}
/* notify host driver that the interface will not be used */
USB_HostCloseDeviceInterface(deviceHandle, hubInstance->interfaceHandle);
#if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
SDK_Free(hubInstance->hubDescriptor);
SDK_Free(hubInstance->portStatusBuffer);
SDK_Free(hubInstance->hubStatusBuffer);
SDK_Free(hubInstance->hubBitmapBuffer);
#endif
USB_OsaMemoryFree(hubInstance);
}
else
{
/* notify host driver that the interface will not be used */
USB_HostCloseDeviceInterface(deviceHandle, NULL);
}
return kStatus_USB_Success;
}
usb_status_t USB_HostHubInterruptRecv(usb_host_class_handle classHandle,
uint8_t *buffer,
uint16_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam)
{
usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
usb_host_transfer_t *transfer;
if (classHandle == NULL)
{
return kStatus_USB_InvalidHandle;
}
/* get transfer */
if (USB_HostMallocTransfer(hubInstance->hostHandle, &transfer) != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("error to get transfer\r\n");
#endif
return kStatus_USB_Error;
}
/* save hub application callback */
hubInstance->inCallbackFn = callbackFn;
hubInstance->inCallbackParam = callbackParam;
/* initialize transfer */
transfer->transferBuffer = buffer;
transfer->transferLength = bufferLength;
transfer->callbackFn = USB_HostHubInPipeCallback;
transfer->callbackParam = hubInstance;
/* call host driver API to receive data */
if (USB_HostRecv(hubInstance->hostHandle, hubInstance->interruptPipe, transfer) != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("failed to USB_HostRecv\r\n");
#endif
USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
return kStatus_USB_Error;
}
return kStatus_USB_Success;
}
usb_status_t USB_HostHubSendPortReset(usb_host_class_handle classHandle, uint8_t portNumber)
{
usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
usb_host_transfer_t *transfer;
if (classHandle == NULL)
{
return kStatus_USB_InvalidHandle;
}
/* get transfer */
if (USB_HostMallocTransfer(hubInstance->hostHandle, &transfer) != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("error to get transfer\r\n");
#endif
return kStatus_USB_Busy;
}
/* initialize transfer */
transfer->transferBuffer = NULL;
transfer->transferLength = 0;
transfer->callbackFn = USB_HostHubResetCallback;
transfer->callbackParam = hubInstance;
transfer->setupPacket->bmRequestType =
USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_OTHER;
transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_SET_FEATURE;
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(PORT_RESET);
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(portNumber);
transfer->setupPacket->wLength = 0;
/* send the transfer */
if (USB_HostSendSetup(hubInstance->hostHandle, hubInstance->controlPipe, transfer) != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("Error in hid get report descriptor\r\n");
#endif
USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
return kStatus_USB_Error;
}
return kStatus_USB_Success;
}
/*!
* @brief hub get descriptor.
*
* This function implements get hub descriptor specific request.
*
* @param classHandle the class handle.
* @param buffer the buffer pointer.
* @param bufferLength the buffer length.
* @param callbackFn this callback is called after this function completes.
* @param callbackParam the first parameter in the callback function.
*
* @retval kStatus_USB_Success send successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy There is no idle transfer.
* @retval kStatus_USB_Error pipe is not initialized.
* Or, send transfer fail, please reference to USB_HostSendSetup.
*/
usb_status_t USB_HostHubGetDescriptor(usb_host_class_handle classHandle,
uint8_t *buffer,
uint16_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam)
{
return USB_HostHubClassRequestCommon(
classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_DEVICE,
USB_REQUEST_STANDARD_GET_DESCRIPTOR, 0x00, 0, buffer, bufferLength, callbackFn, callbackParam);
}
/*!
* @brief hub clear feature.
*
* This function implements clear hub feature specific request.
*
* @param classHandle the class handle.
* @param buffer the buffer pointer.
* @param bufferLength the buffer length.
* @param callbackFn this callback is called after this function completes.
* @param callbackParam the first parameter in the callback function.
*
* @retval kStatus_USB_Success send successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy There is no idle transfer.
* @retval kStatus_USB_Error pipe is not initialized.
* Or, send transfer fail, please reference to USB_HostSendSetup.
*/
usb_status_t USB_HostHubClearFeature(usb_host_class_handle classHandle,
uint8_t feature,
transfer_callback_t callbackFn,
void *callbackParam)
{
return USB_HostHubClassRequestCommon(classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS,
USB_REQUEST_STANDARD_CLEAR_FEATURE, feature, 0, NULL, 0, callbackFn,
callbackParam);
}
/*!
* @brief hub get status.
*
* This function implements get hub status specific request.
*
* @param classHandle the class handle.
* @param buffer the buffer pointer.
* @param bufferLength the buffer length.
* @param callbackFn this callback is called after this function completes.
* @param callbackParam the first parameter in the callback function.
*
* @retval kStatus_USB_Success send successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy There is no idle transfer.
* @retval kStatus_USB_Error pipe is not initialized.
* Or, send transfer fail, please reference to USB_HostSendSetup.
*/
usb_status_t USB_HostHubGetStatus(usb_host_class_handle classHandle,
uint8_t *buffer,
uint16_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam)
{
return USB_HostHubClassRequestCommon(classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS,
USB_REQUEST_STANDARD_GET_STATUS, 0, 0, buffer, bufferLength, callbackFn,
callbackParam);
}
/*!
* @brief hub set feature.
*
* This function implements set hub feature specific request.
*
* @param classHandle the class handle.
* @param buffer the buffer pointer.
* @param bufferLength the buffer length.
* @param callbackFn this callback is called after this function completes.
* @param callbackParam the first parameter in the callback function.
*
* @retval kStatus_USB_Success send successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy There is no idle transfer.
* @retval kStatus_USB_Error pipe is not initialized.
* Or, send transfer fail, please reference to USB_HostSendSetup.
*/
usb_status_t USB_HostHubSetPortFeature(usb_host_class_handle classHandle,
uint8_t portNumber,
uint8_t feature,
transfer_callback_t callbackFn,
void *callbackParam)
{
return USB_HostHubClassRequestCommon(
classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_OTHER,
USB_REQUEST_STANDARD_SET_FEATURE, feature, portNumber, NULL, 0, callbackFn, callbackParam);
}
/*!
* @brief hub clear port feature.
*
* This function implements clear hub port feature specific request.
*
* @param classHandle the class handle.
* @param buffer the buffer pointer.
* @param bufferLength the buffer length.
* @param callbackFn this callback is called after this function completes.
* @param callbackParam the first parameter in the callback function.
*
* @retval kStatus_USB_Success send successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy There is no idle transfer.
* @retval kStatus_USB_Error pipe is not initialized.
* Or, send transfer fail, please reference to USB_HostSendSetup.
*/
usb_status_t USB_HostHubClearPortFeature(usb_host_class_handle classHandle,
uint8_t portNumber,
uint8_t feature,
transfer_callback_t callbackFn,
void *callbackParam)
{
return USB_HostHubClassRequestCommon(
classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_OTHER,
USB_REQUEST_STANDARD_CLEAR_FEATURE, feature, portNumber, NULL, 0, callbackFn, callbackParam);
}
/*!
* @brief hub port get status.
*
* This function implements get hub port status specific request.
*
* @param classHandle the class handle.
* @param buffer the buffer pointer.
* @param bufferLength the buffer length.
* @param callbackFn this callback is called after this function completes.
* @param callbackParam the first parameter in the callback function.
*
* @retval kStatus_USB_Success send successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy There is no idle transfer.
* @retval kStatus_USB_Error pipe is not initialized.
* Or, send transfer fail, please reference to USB_HostSendSetup.
*/
usb_status_t USB_HostHubGetPortStatus(usb_host_class_handle classHandle,
uint8_t portNumber,
uint8_t *buffer,
uint16_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam)
{
return USB_HostHubClassRequestCommon(
classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_OTHER,
USB_REQUEST_STANDARD_GET_STATUS, 0, portNumber, buffer, bufferLength, callbackFn, callbackParam);
}
#endif /* USB_HOST_CONFIG_HUB */

View File

@ -0,0 +1,379 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _USB_HOST_HUB_H_
#define _USB_HOST_HUB_H_
#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief USB host HUB maximum port count */
#define USB_HOST_HUB_MAX_PORT (7U)
/*! @brief HUB class code */
#define USB_HOST_HUB_CLASS_CODE (9U)
/*! @brief HUB sub-class code */
#define USB_HOST_HUB_SUBCLASS_CODE_NONE (0U)
/* HUB and PORT status according to Table 11-17 in chapter 11.*/
/*! @brief Local Power Status Change: This field indicates that a change has occurred in the HUB's Local Power Source */
#define C_HUB_LOCAL_POWER (0U)
/*! @brief Over-Current Change: This field indicates if a change has occurred in the Over-Current field*/
#define C_HUB_OVER_CURRENT (1U)
/*! @brief Current Connect Status: This field reflects whether or not a device is currently connected to this port*/
#define PORT_CONNECTION (0U)
/*! @brief Port Enabled/Disabled: Ports can be enabled by the USB System Software only. Ports
can be disabled by either a fault condition (disconnect event or other fault condition) or by the USB System
Software*/
#define PORT_ENABLE (1U)
/*! @brief Suspend: This field indicates whether or not the device on this port is suspended */
#define PORT_SUSPEND (2U)
/*! @brief this field indicate that the current drain on the port exceeds the specified maximum. */
#define PORT_OVER_CURRENT (3U)
/*! @brief This field is set when the host wishes to reset the attached device */
#define PORT_RESET (4U)
/*! @brief This field reflects a port's logical, power control state */
#define PORT_POWER (8U)
/*! @brief Low- Speed Device Attached: This is relevant only if a device is attached */
#define PORT_LOW_SPEED (9U)
/*! @brief High-speed Device Attached: This is relevant only if a device is attached */
#define PORT_HIGH_SPEED (10U)
/*! @brief Connect Status Change: Indicates a change has occurred in the port's Current Connect Status */
#define C_PORT_CONNECTION (16U)
/*! @brief Port Enable/Disable Change: This field is set to one when a port is disabled because of a Port_Error
* condition */
#define C_PORT_ENABLE (17U)
/*! @brief Suspend Change: This field indicates a change in the host-visible suspend state of the attached device */
#define C_PORT_SUSPEND (18U)
/*! @brief Over-Current Indicator Change: This field applies only to HUBs that report over-current conditions on a
* per-port basis */
#define C_PORT_OVER_CURRENT (19U)
/*! @brief Reset Change: This field is set when reset processing on this port is complete */
#define C_PORT_RESET (20U)
/*! @brief Get HUB think time value */
#define USB_HOST_HUB_DESCRIPTOR_CHARACTERISTICS_THINK_TIME_MASK (0x60U)
/*! @brief Get HUB think time value */
#define USB_HOST_HUB_DESCRIPTOR_CHARACTERISTICS_THINK_TIME_SHIFT (5U)
/*******************************************************************************
* Prototypes
******************************************************************************/
/*! @brief HUB descriptor structure */
typedef struct _usb_host_hub_descriptor
{
uint8_t blength; /*!< Number of bytes in this descriptor*/
uint8_t bdescriptortype; /*!< Descriptor Type*/
uint8_t bnrports; /*!< Number of downstream facing ports that this HUB supports*/
uint8_t whubcharacteristics[2]; /*!< HUB characteristics please reference to Table 11-13 in usb2.0 specification*/
uint8_t bpwron2pwrgood; /*!< Time (in 2 ms intervals) from the time the power-on sequence begins on a port until
power is good on that port.*/
uint8_t bhubcontrcurrent; /*!< Maximum current requirements of the HUB Controller electronics in mA*/
uint8_t deviceremovable; /*!< Indicates if a port has a removable device attached*/
} usb_host_hub_descriptor_t;
/*! @brief HUB port instance structure */
typedef struct _usb_host_hub_port_instance
{
usb_device_handle deviceHandle; /*!< Device handle*/
uint8_t portStatus; /*!< Port running status*/
uint8_t resetCount; /*!< Port reset time*/
uint8_t speed; /*!< Port's device speed*/
} usb_host_hub_port_instance_t;
/*! @brief HUB instance structure */
typedef struct _usb_host_hub_instance
{
struct _usb_host_hub_instance *next; /*!< Next HUB instance*/
usb_host_handle hostHandle; /*!< Host handle*/
usb_device_handle deviceHandle; /*!< Device handle*/
usb_host_interface_handle interfaceHandle; /*!< Interface handle*/
usb_host_pipe_handle controlPipe; /*!< Control pipe handle*/
usb_host_pipe_handle interruptPipe; /*!< HUB interrupt in pipe handle*/
usb_host_hub_port_instance_t *portList; /*!< HUB's port instance list*/
usb_host_transfer_t *controlTransfer; /*!< Control transfer in progress*/
transfer_callback_t inCallbackFn; /*!< Interrupt in callback*/
void *inCallbackParam; /*!< Interrupt in callback parameter*/
transfer_callback_t controlCallbackFn; /*!< Control callback*/
void *controlCallbackParam; /*!< Control callback parameter*/
/* HUB property */
uint16_t totalThinktime; /*!< HUB total think time*/
uint8_t hubLevel; /*!< HUB level, the root HUB's level is 1*/
/* HUB application parameter */
#if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
uint8_t *hubDescriptor; /*!< HUB descriptor buffer*/
uint8_t *hubBitmapBuffer; /*!< HUB receiving bitmap data buffer*/
uint8_t *hubStatusBuffer; /*!< HUB status buffer*/
uint8_t *portStatusBuffer; /*!< Port status buffer*/
#else
uint8_t hubDescriptor[7 + (USB_HOST_HUB_MAX_PORT >> 3) + 1]; /*!< HUB descriptor buffer*/
uint8_t hubBitmapBuffer[(USB_HOST_HUB_MAX_PORT >> 3) + 1]; /*!< HUB receiving bitmap data buffer*/
uint8_t hubStatusBuffer[4]; /*!< HUB status buffer*/
uint8_t portStatusBuffer[4]; /*!< Port status buffer*/
#endif
uint8_t hubStatus; /*!< HUB instance running status*/
uint8_t portCount; /*!< HUB port count*/
uint8_t portIndex; /*!< Record the index when processing ports in turn*/
uint8_t portProcess; /*!< The port that is processing*/
uint8_t primeStatus; /*!< Data prime transfer status*/
uint8_t invalid; /*!< 0/1, when invalid, cannot send transfer to the class*/
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
uint8_t supportRemoteWakeup; /*!< The HUB supports remote wakeup or not*/
uint8_t controlRetry; /*!< Retry count for set remote wakeup feature*/
#endif
} usb_host_hub_instance_t;
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/*!
* @brief Initializes the HUB instance.
*
* This function allocates the resource for HUB instance.
*
* @param deviceHandle The device handle.
* @param classHandle Return class handle.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_AllocFail Allocate memory fail.
*/
extern usb_status_t USB_HostHubInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle);
/*!
* @brief Sets interface.
*
* This function binds the interfaces with the HUB instance.
*
* @param classHandle The class handle.
* @param interfaceHandle The interface handle.
* @param alternateSetting The alternate setting value.
* @param callbackFn This callback is called after this function completes.
* @param callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy There is no idle transfer.
* @retval kStatus_USB_Error Open pipe fail. See the USB_HostOpenPipe.
* Or send transfer fail. See the USB_HostSendSetup,
*/
extern usb_status_t USB_HostHubSetInterface(usb_host_class_handle classHandle,
usb_host_interface_handle interfaceHandle,
uint8_t alternateSetting,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Deinitializes the HUB instance.
*
* This function releases the resource for HUB instance.
*
* @param deviceHandle The device handle.
* @param classHandle The class handle.
*
* @retval kStatus_USB_Success The device is deinitialized successfully.
*/
extern usb_status_t USB_HostHubDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle);
/*!
* @brief Receives data.
*
* This function implements the HUB receiving data.
*
* @param classHandle The class handle.
* @param buffer The buffer pointer.
* @param bufferLength The buffer length.
* @param callbackFn This callback is called after this function completes.
* @param callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success Receive request successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy There is no idle transfer.
* @retval kStatus_USB_Error Pipe is not initialized.
* Or, send transfer fail. See the USB_HostRecv.
*/
extern usb_status_t USB_HostHubInterruptRecv(usb_host_class_handle classHandle,
uint8_t *buffer,
uint16_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Port reset setup.
*
* This function sends the HUB port reset transfer.
*
* @param classHandle The class handle.
* @param portNumber Port number.
*
* @retval kStatus_USB_Success Send successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy There is no idle transfer.
* @retval kStatus_USB_Error Pipe is not initialized.
* Or, send transfer fail. See the USB_HostSendSetup.
*/
extern usb_status_t USB_HostHubSendPortReset(usb_host_class_handle classHandle, uint8_t portNumber);
/*!
* @brief HUB get descriptor.
*
* This function implements get HUB descriptor-specific request.
*
* @param classHandle The class handle.
* @param buffer The buffer pointer.
* @param bufferLength The buffer length.
* @param callbackFn This callback is called after this function completes.
* @param callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success Send successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy There is no idle transfer.
* @retval kStatus_USB_Error Pipe is not initialized.
* Or, send transfer fail. See the USB_HostSendSetup.
*/
extern usb_status_t USB_HostHubGetDescriptor(usb_host_class_handle classHandle,
uint8_t *buffer,
uint16_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief HUB clear feature.
*
* This function implements clear HUB feature specific request.
*
* @param classHandle the class handle.
* @param buffer the buffer pointer.
* @param bufferLength the buffer length.
* @param callbackFn this callback is called after this function completes.
* @param callbackParam the first parameter in the callback function.
*
* @retval kStatus_USB_Success send successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy There is no idle transfer.
* @retval kStatus_USB_Error pipe is not initialized.
* Or, send transfer fail, please reference to USB_HostSendSetup.
*/
extern usb_status_t USB_HostHubClearFeature(usb_host_class_handle classHandle,
uint8_t feature,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief HUB get status.
*
* This function implements the get HUB status-specific request.
*
* @param classHandle The class handle.
* @param buffer The buffer pointer.
* @param bufferLength The buffer length.
* @param callbackFn This callback is called after this function completes.
* @param callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success Send successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy There is no idle transfer.
* @retval kStatus_USB_Error Pipe is not initialized.
* Or, send transfer fail. See the USB_HostSendSetup.
*/
extern usb_status_t USB_HostHubGetStatus(usb_host_class_handle classHandle,
uint8_t *buffer,
uint16_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief HUB set feature.
*
* This function implements the set HUB feature-specific request.
*
* @param classHandle The class handle.
* @param buffer The buffer pointer.
* @param bufferLength The buffer length.
* @param callbackFn This callback is called after this function completes.
* @param callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success Send successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy There is no idle transfer.
* @retval kStatus_USB_Error Pipe is not initialized.
* Or, send transfer fail. See the USB_HostSendSetup.
*/
extern usb_status_t USB_HostHubSetPortFeature(usb_host_class_handle classHandle,
uint8_t portNumber,
uint8_t feature,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief HUB clear port feature.
*
* This function implements the clear HUB port feature-specific request.
*
* @param classHandle The class handle.
* @param buffer The buffer pointer.
* @param bufferLength The buffer length.
* @param callbackFn This callback is called after this function completes.
* @param callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success Send successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy There is no idle transfer.
* @retval kStatus_USB_Error Pipe is not initialized.
* Or, send transfer fail. See the USB_HostSendSetup.
*/
extern usb_status_t USB_HostHubClearPortFeature(usb_host_class_handle classHandle,
uint8_t portNumber,
uint8_t feature,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief HUB port get status.
*
* This function implements the get HUB port status-specific request.
*
* @param classHandle The class handle.
* @param buffer The buffer pointer.
* @param bufferLength The buffer length.
* @param callbackFn This callback is called after this function completes.
* @param callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success Send successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy There is no idle transfer.
* @retval kStatus_USB_Error Pipe is not initialized.
* Or, send transfer fail. See the USB_HostSendSetup.
*/
extern usb_status_t USB_HostHubGetPortStatus(usb_host_class_handle classHandle,
uint8_t portNumber,
uint8_t *buffer,
uint16_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam);
#ifdef __cplusplus
}
#endif
#endif /* USB_HOST_CONFIG_HUB */
#endif /* _USB_HSOT_HUB_H_ */

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _USB_HOST_HUB_APP_H_
#define _USB_HOST_HUB_APP_H_
#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief HUB reset times*/
#define USB_HOST_HUB_PORT_RESET_TIMES (1)
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
/*! @brief HUB Control tansaction retry times for remote wakeup*/
#define USB_HOST_HUB_REMOTE_WAKEUP_TIMES (3U)
#endif
/*! @brief HUB application global structure */
typedef struct _usb_host_hub_global
{
usb_host_handle hostHandle; /*!< This HUB list belong to this host*/
usb_host_hub_instance_t *hubProcess; /*!< HUB in processing*/
usb_host_hub_instance_t *hubList; /*!< host's HUB list*/
usb_osa_mutex_handle hubMutex; /*!< HUB mutex*/
} usb_host_hub_global_t;
/*! @brief HUB application status */
typedef enum _usb_host_hub_app_status
{
kHubRunIdle = 0, /*!< Idle */
kHubRunInvalid, /*!< Invalid state */
kHubRunWaitSetInterface, /*!< Wait callback of set interface */
kHubRunGetDescriptor7, /*!< Get 7 bytes HUB descriptor */
kHubRunGetDescriptor, /*!< Get all HUB descriptor */
kHubRunSetPortPower, /*!< Set HUB's port power */
kHubRunGetStatusDone, /*!< HUB status changed */
kHubRunClearDone, /*!< clear HUB feature callback */
} usb_host_hub_app_status_t;
/*! @brief HUB port application status */
typedef enum _usb_host_port_app_status
{
kPortRunIdle = 0, /*!< Idle */
kPortRunInvalid, /*!< Invalid state */
kPortRunWaitPortChange, /*!< Wait port status change */
kPortRunCheckCPortConnection, /*!< Check C_PORT_CONNECTION */
kPortRunGetPortConnection, /*!< Get port status data */
kPortRunCheckPortConnection, /*!< Check PORT_CONNECTION */
kPortRunWaitPortResetDone, /*!< Wait port reset transfer done */
kPortRunWaitCPortReset, /*!< Wait C_PORT_RESET */
KPortRunCheckCPortReset, /*!< Check C_PORT_RESET */
kPortRunResetAgain, /*!< Reset port again */
kPortRunPortAttached, /*!< Device is attached on the port */
kPortRunCheckPortDetach, /*!< Check port is detached */
kPortRunGetConnectionBit, /*!< Get the port status data */
kPortRunCheckConnectionBit, /*!< Check PORT_CONNECTION */
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
kPortRunClearCPortSuspend, /*!< Clear C_PORT_SUSPEND */
kPortRunCheckPortSuspend, /*!< Check PORT_SUSPEND */
kPortRunPortSuspended, /*!< Port is suspended */
#endif
} usb_host_port_app_status_t;
/*! @brief HUB data prime status */
typedef enum _usb_host_hub_prime_status
{
kPrimeNone = 0, /*!< Don't prime data*/
kPrimeHubControl, /*!< Prime HUB control transfer*/
kPrimePortControl, /*!< Prime port control transfer*/
kPrimeInterrupt, /*!< Prime interrupt transfer*/
} usb_host_hub_prime_status_t;
/*******************************************************************************
* API
******************************************************************************/
#endif /* USB_HOST_CONFIG_HUB */
#endif /* _USB_HOST_HUB_APP_H_ */

View File

@ -0,0 +1,851 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _USB_HOST_MSD_H_
#define _USB_HOST_MSD_H_
/*******************************************************************************
* MSD class private structure, enumeration, macro
******************************************************************************/
/*******************************************************************************
* Definitions
******************************************************************************/
/* CBW and CSW Macros */
#define USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT (0x00U)
#define USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN (0x80U)
#define USB_HOST_MSD_CBW_SIGNATURE (0x43425355U)
#define USB_HOST_MSD_CSW_SIGNATURE (0x53425355U)
/* UFI data bit macro */
#define USB_HOST_UFI_BLOCK_DATA_VALID_LENGTH (10U)
#define USB_HOST_UFI_LOGICAL_UNIT_POSITION (5U)
#define USB_HOST_UFI_CBW_LENGTH (31U)
#define USB_HOST_UFI_CSW_LENGTH (13U)
#define USB_HOST_UFI_MODE_SENSE_PAGE_CONTROL_SHIFT (6U)
#define USB_HOST_UFI_MODE_SENSE_PAGE_CODE_SHIFT (0U)
#define USB_HOST_UFI_START_STOP_UNIT_LOEJ_SHIFT (1U)
#define USB_HOST_UFI_START_STOP_UNIT_START_SHIFT (0U)
#define USB_HOST_UFI_SEND_DIAGNOSTIC_SELF_TEST_SHIFT (2U)
/*******************************************************************************
* MSD class public structure, enumeration, macro, function
******************************************************************************/
/*!
* @addtogroup usb_host_msc_drv
* @{
*/
/*! @brief retry time when transfer fail, when all the retries fail the transfer callback with error status */
#define USB_HOST_MSD_RETRY_MAX_TIME (1U)
/*! @brief mass storage block size */
#define USB_HOST_MSD_BLOCK_SIZE (512U)
/*! @brief MSD class code */
#define USB_HOST_MSD_CLASS_CODE (8U)
/*! @brief MSD sub-class code */
#define USB_HOST_MSD_SUBCLASS_CODE_UFI (4U)
/*! @brief MSD sub-class code */
#define USB_HOST_MSD_SUBCLASS_CODE_SCSI (6U)
/*! @brief MSD protocol code */
#define USB_HOST_MSD_PROTOCOL_BULK (0x50U)
/*! @brief MSD class-specific request (mass storage reset) */
#define USB_HOST_HID_MASS_STORAGE_RESET (0xFFU)
/*! @brief MSD class-specific request (get maximum logical unit number) */
#define USB_HOST_HID_GET_MAX_LUN (0xFEU)
/*! @brief UFI command process status */
typedef enum _usb_host_msd_command_status
{
kMSD_CommandIdle = 0,
kMSD_CommandTransferCBW,
kMSD_CommandTransferData,
kMSD_CommandTransferCSW,
kMSD_CommandDone,
kMSD_CommandCancel,
kMSD_CommandErrorDone,
} usb_host_msd_command_status_t;
/*! @brief MSC Bulk-Only command block wrapper (CBW) */
typedef struct _usb_host_cbw
{
uint32_t CBWSignature; /*!< Signature that helps identify this data packet as a CBW. The signature field shall
contain the value 43425355h (little endian), indicating a CBW */
uint32_t
CBWTag; /*!< A Command Block Tag sent by the host. The device shall echo the contents of this field back to the
host in the dCSWTag field of the associated CSW */
uint32_t CBWDataTransferLength; /*!< The number of bytes of data that the host expects to transfer on the Bulk-In or
Bulk-Out endpoint during the execution of this command */
uint8_t CBWFlags; /*!<
Bit 7 Direction - the device shall ignore this bit if the dCBWDataTransferLength field is
zero, otherwise:
0 = Data-Out from host to the device,
1 = Data-In from the device to the host.
Bit 6 Obsolete. The host shall set this bit to zero.
Bits 5..0 Reserved - the host shall set these bits to zero.
*/
uint8_t CBWLun; /*!< The device Logical Unit Number (LUN) to which the command block is being sent */
uint8_t CBWCBLength; /*!< The valid length of the CBWCB in bytes. This defines the valid length of the command
block. The only legal values are 1 through 16 (01h through 10h).*/
uint8_t CBWCB[16]; /*!< The command block to be executed by the device*/
} usb_host_cbw_t;
/*! @brief MSC Bulk-Only command status wrapper (CSW) */
typedef struct _usb_host_csw
{
uint32_t CSWSignature; /*!< Signature that helps identify this data packet as a CSW. The signature field shall
contain the value 53425355h (little endian), indicating CSW.*/
uint32_t CSWTag; /*!< The device shall set this field to the value received in the dCBWTag of the associated CBW*/
uint32_t CSWDataResidue; /*!< the difference between the amount of data expected as stated in the
dCBWDataTransferLength and the actual amount of relevant data processed by the device.*/
uint8_t CSWStatus; /*!<
bCSWStatus indicates the success or failure of the command.
00h - Command passed.
01h - Command Failed.
02h - Phase error.
others - Reserved.
*/
} usb_host_csw_t;
/*! @brief MSC UFI command information structure */
typedef struct _usb_host_msd_command
{
usb_host_cbw_t cbwBlock; /*!< CBW data block*/
usb_host_csw_t cswBlock; /*!< CSW data block*/
uint8_t *dataBuffer; /*!< Data buffer pointer*/
uint32_t dataLength; /*!< Data buffer length*/
uint32_t dataSofar; /*!< Successful transfer data length*/
usb_host_transfer_t *transfer; /*!< The transfer is used for processing the UFI command*/
uint8_t retryTime; /*!< The UFI command residual retry time, when it reduce to zero the UFI command fail */
uint8_t dataDirection; /*!< The data direction, its value is USB_OUT or USB_IN*/
} usb_host_msd_command_t;
/*! @brief MSD instance structure, MSD usb_host_class_handle pointer to this structure */
typedef struct _usb_host_msd_instance
{
usb_host_handle hostHandle; /*!< This instance's related host handle*/
usb_device_handle deviceHandle; /*!< This instance's related device handle*/
usb_host_interface_handle interfaceHandle; /*!< This instance's related interface handle*/
usb_host_pipe_handle controlPipe; /*!< This instance's related device control pipe*/
usb_host_pipe_handle outPipe; /*!< MSD bulk out pipe*/
usb_host_pipe_handle inPipe; /*!< MSD bulk in pipe*/
transfer_callback_t commandCallbackFn; /*!< MSD UFI command callback function pointer*/
void *commandCallbackParam; /*!< MSD UFI command callback parameter*/
transfer_callback_t controlCallbackFn; /*!< MSD control transfer callback function pointer*/
void *controlCallbackParam; /*!< MSD control transfer callback parameter*/
usb_host_transfer_t *controlTransfer; /*!< Ongoing control transfer*/
usb_host_msd_command_t msdCommand; /*!< Ongoing MSD UFI command information*/
uint8_t commandStatus; /*!< UFI command process status, see command_status_t*/
uint8_t internalResetRecovery; /*!< 1 - class driver internal mass storage reset recovery is on-going; 0 -
application call USB_HostMsdMassStorageReset to reset or there is no reset*/
} usb_host_msd_instance_t;
/*! @brief UFI standard sense data structure */
typedef struct _usb_host_ufi_sense_data
{
uint8_t errorCode; /*!< This field shall contain a value of 70h to indicate current errors*/
uint8_t reserved1; /*!< Reserved field*/
uint8_t senseKey; /*!< Provide a hierarchy of error or command result information*/
uint8_t information[4]; /*!< This field is command-specific; it is typically used by some commands to return a
logical block address denoting where an error occurred*/
uint8_t additionalSenseLength; /*!< The UFI device sets the value of this field to ten, to indicate that ten more
bytes of sense data follow this field*/
uint8_t reserved2[4]; /*!< Reserved field*/
uint8_t additionalSenseCode; /*!< Provide a hierarchy of error or command result information*/
uint8_t additionalSenseCodeQualifier; /*!< Provide a hierarchy of error or command result information*/
uint8_t reserved3[4]; /*!< Reserved field*/
} usb_host_ufi_sense_data_t;
/*! @brief UFI standard inquiry data structure */
typedef struct _usb_host_ufi_inquiry_data
{
uint8_t peripheralDeviceType; /*!< Identifies the device currently connected to the requested logical unit*/
uint8_t removableMediaBit; /*!< This shall be set to one to indicate removable media*/
uint8_t version; /*!< Version*/
uint8_t responseDataFormat; /*!< A value of 01h shall be used for UFI device*/
uint8_t additionalLength; /*!< Specify the length in bytes of the parameters*/
uint8_t reserved1[3]; /*!< Reserved field*/
uint8_t vendorInformation[8]; /*!< Contains 8 bytes of ASCII data identifying the vendor of the product*/
uint8_t productIdentification[16]; /*!< Contains 16 bytes of ASCII data as defined by the vendor*/
uint8_t productRevisionLevel[4]; /*!< Contains 4 bytes of ASCII data as defined by the vendor*/
} usb_host_ufi_inquiry_data_t;
/*! @brief UFI read capacity data structure */
typedef struct _usb_host_ufi_read_capacity
{
uint8_t lastLogicalBlockAddress[4]; /*!< The logical block number*/
uint8_t blockLengthInBytes[4]; /*!< Block size*/
} usb_host_ufi_read_capacity_t;
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* API
******************************************************************************/
/*!
* @name USB host MSD class APIs
* @{
*/
/*!
* @brief Initializes the MSD instance.
*
* This function allocates the resources for the MSD instance.
*
* @param[in] deviceHandle The device handle.
* @param[out] classHandle Return class handle.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_AllocFail Allocate memory fail.
*/
extern usb_status_t USB_HostMsdInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle);
/*!
* @brief Sets the interface.
*
* This function binds the interface with the MSD instance.
*
* @param[in] classHandle The class handle.
* @param[in] interfaceHandle The interface handle.
* @param[in] alternateSetting The alternate setting value.
* @param[in] callbackFn This callback is called after this function completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy There is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
* @retval kStatus_USB_Success Callback return status, the command succeeded.
* @retval kStatus_USB_Busy Callback return status, there is no idle pipe.
* @retval kStatus_USB_TransferStall Callback return status, the transfer is stalled by the device.
* @retval kStatus_USB_Error Callback return status, open pipe fail. See the USB_HostOpenPipe.
*/
extern usb_status_t USB_HostMsdSetInterface(usb_host_class_handle classHandle,
usb_host_interface_handle interfaceHandle,
uint8_t alternateSetting,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Deinitializes the MSD instance.
*
* This function frees the resource for the MSD instance.
*
* @param[in] deviceHandle The device handle.
* @param[in] classHandle The class handle.
*
* @retval kStatus_USB_Success The device is de-initialized successfully.
*/
extern usb_status_t USB_HostMsdDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle);
/*!
* @brief Mass storage reset.
*
* This function implements the mass storage reset request.
*
* @param[in] classHandle The class handle.
* @param[in] callbackFn This callback is called after this function completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy There is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
*/
extern usb_status_t USB_HostMsdMassStorageReset(usb_host_class_handle classHandle,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Gets the maximum logical unit number.
*
* This function implements the get maximum LUN request.
*
* @param[in] classHandle The class handle.
* @param[out] logicalUnitNumber Return logical unit number value.
* @param[in] callbackFn This callback is called after this function completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy There is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdGetMaxLun(usb_host_class_handle classHandle,
uint8_t *logicalUnitNumber,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Mass storage read (10).
*
* This function implements the UFI READ(10) command. This command requests that the UFI
* device transfer data to the host.
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[in] blockAddress The start block address.
* @param[out] buffer Buffer pointer.
* @param[in] bufferLength The buffer length.
* @param[in] blockNumber Read block number.
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdRead10(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint32_t blockAddress,
uint8_t *buffer,
uint32_t bufferLength,
uint32_t blockNumber,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Mass storage read (12).
*
* This function implements the UFI READ(12) command and requests that the UFI
* device transfer data to the host.
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[in] blockAddress The start block address.
* @param[out] buffer Buffer pointer.
* @param[in] bufferLength The buffer length.
* @param[in] blockNumber Read block number.
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdRead12(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint32_t blockAddress,
uint8_t *buffer,
uint32_t bufferLength,
uint32_t blockNumber,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Mass storage write (10).
*
* This function implements the UFI WRITE(10) command and requests that the UFI device
* write the data transferred by the host to the medium.
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[in] blockAddress The start block address.
* @param[in] buffer Buffer pointer.
* @param[in] bufferLength The buffer length.
* @param[in] blockNumber Write block number.
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdWrite10(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint32_t blockAddress,
uint8_t *buffer,
uint32_t bufferLength,
uint32_t blockNumber,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Mass storage write (12).
*
* This function implements the UFI WRITE(12) command and requests that the UFI device
* write the data transferred by the host to the medium.
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[in] blockAddress The start block address.
* @param[in] buffer Buffer pointer.
* @param[in] bufferLength The buffer length.
* @param[in] blockNumber Write block number.
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdWrite12(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint32_t blockAddress,
uint8_t *buffer,
uint32_t bufferLength,
uint32_t blockNumber,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Mass storage read capacity.
*
* This function implements the UFI READ CAPACITY command and allows the host to request
* capacities of the currently installed medium.
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[out] buffer Buffer pointer.
* @param[in] bufferLength The buffer length.
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdReadCapacity(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t *buffer,
uint32_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Mass storage test unit ready.
*
* This function implements the UFI TEST UNIT READY command and
* checks if the UFI device is ready.
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdTestUnitReady(usb_host_class_handle classHandle,
uint8_t logicalUnit,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief mass storage request sense.
*
* This function implements the UFI REQUEST SENSE command, this command instructs
* the UFI device to transfer sense data to the host for the specified logical unit.
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[out] buffer Buffer pointer.
* @param[in] bufferLength The buffer length.
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdRequestSense(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t *buffer,
uint32_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Mass storage mode select.
*
* This function implements the UFI MODE SELECT command and allows the host
* to specify medium or device parameters to the UFI device.
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[in] buffer Buffer pointer.
* @param[in] bufferLength The buffer length.
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdModeSelect(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t *buffer,
uint32_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Mass storage mode sense.
*
* This function implements the UFI MODE SENSE command and allows the UFI
* device to report medium or device parameters to the host.
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[in] pageControl The page control field specifies the type of mode parameters to return.
* @param[in] pageCode Buffer pointer.
* @param[out] buffer Buffer pointer.
* @param[in] bufferLength The buffer length.
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdModeSense(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t pageControl,
uint8_t pageCode,
uint8_t *buffer,
uint32_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Mass storage inquiry.
*
* This function implements the UFI INQUIRY command and requests that information regarding
* parameters of the UFI device itself be sent to the host.
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[out] buffer Buffer pointer.
* @param[in] bufferLength The buffer length.
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdInquiry(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t *buffer,
uint32_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Mass storage read format capacities.
*
* This function implements the UFI READ FORMAT CAPACITIES command and allows the host to request
* a list of the possible capacities that can be formatted on the currently installed medium.
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[out] buffer Buffer pointer.
* @param[in] bufferLength The buffer length.
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdReadFormatCapacities(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t *buffer,
uint32_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Mass storage format unit.
*
* This function implements the UFI FORMAT UNIT command and the host sends this command to physically format one
* track of a diskette according to the selected options.
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[in] trackNumber This specifies which track is to be formatted.
* @param[in] interLeave This specifies the interleave that shall be used for formatting.
* @param[in] buffer Buffer pointer.
* @param[in] bufferLength The buffer length.
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdFormatUnit(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t trackNumber,
uint16_t interLeave,
uint8_t *buffer,
uint32_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Mass storage prevents/allows a medium removal.
*
* This function implements the UFI PREVENT-ALLOW MEDIUM REMOVAL command and notifies the FUI device
* to enable or disable the removal of the medium in the logical unit.
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[in] prevent Prevent or allow
* - 0: enable (allow) the removal of the medium
* - 1: disable (prevent) removal of the medium
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdPreventAllowRemoval(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t prevent,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Mass storage write and verify.
*
* This function implements the UFI WRITE AND VERIFY command and requests that the UFI device
* writes the data transferred by the host to the medium, then verifies the data on the medium.
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[in] blockAddress The start block address.
* @param[in] buffer Buffer pointer.
* @param[in] bufferLength The buffer length.
* @param[in] blockNumber Write and verify block number.
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdWriteAndVerify(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint32_t blockAddress,
uint8_t *buffer,
uint32_t bufferLength,
uint32_t blockNumber,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Mass storage start stop unit.
*
* This function implements the UFI START-STOP UNIT command and instructs the UFI device
* to enable or disable media access operations .
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[in] loadEject A Load Eject (LoEj) bit of zero requests that no eject action be performed. A LoEj bit of
* one, with the
* Start bit cleared to zero, which instructs the UFI device to eject the media.
* @param[in] start A Start bit of one instructs the UFI device to enable media access operations. A Start bit
* of zero instructs the UFI device to disable media access operations.
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdStartStopUnit(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t loadEject,
uint8_t start,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Mass storage verify.
*
* This function implements the UFI VERIFY command and requests that the UFI device
* verify the data on the medium.
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[in] blockAddress The start block address.
* @param[in] verificationLength The data length that need to be verified.
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdVerify(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint32_t blockAddress,
uint16_t verificationLength,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Mass storage rezero.
*
* This function implements the UFI REZERO UNIT command. This command positions the head of
* the drive to the cylinder 0.
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdRezeroUnit(usb_host_class_handle classHandle,
uint8_t logicalUnit,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Mass storage seek(10).
*
* This function implements the UFI SEEK(10) command and requests that the UFI device
* seek to the specified Logical Block Address.
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[in] blockAddress The start block address.
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdSeek10(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint32_t blockAddress,
transfer_callback_t callbackFn,
void *callbackParam);
/*!
* @brief Mass storage send diagnostic.
*
* This function implements the UFI SEND DIAGNOSTIC command. This command requests the UFI device
* to do a reset or perform a self-test.
*
* @param[in] classHandle The class MSD handle.
* @param[in] logicalUnit Logical unit number.
* @param[in] selfTest 0 = perform special diagnostic test; 1 = perform default self-test.
* @param[in] callbackFn This callback is called after this command completes.
* @param[in] callbackParam The first parameter in the callback function.
*
* @retval kStatus_USB_Success The device is initialized successfully.
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
* @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
* @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
* @retval kStatus_USB_Success Callback return status, the command succeed.
* @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
* @retval kStatus_USB_Error Callback return status, the command fail.
*/
extern usb_status_t USB_HostMsdSendDiagnostic(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t selfTest,
transfer_callback_t callbackFn,
void *callbackParam);
/*! @}*/
#ifdef __cplusplus
}
#endif
/*! @}*/
#endif /* _USB_HOST_MSD_H_ */

View File

@ -0,0 +1,451 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "usb_host_config.h"
#if ((defined USB_HOST_CONFIG_MSD) && (USB_HOST_CONFIG_MSD))
#include "usb_host.h"
#include "usb_host_msd.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* UFI command code */
#define UFI_FORMAT_UNIT (0x04U)
#define UFI_INQUIRY (0x12U)
#define UFI_START_STOP (0x1BU)
#define UFI_MODE_SELECT (0x55U)
#define UFI_MODE_SENSE (0x5AU)
#define UFI_MEDIUM_REMOVAL (0x1EU)
#define UFI_READ10 (0x28U)
#define UFI_READ12 (0xA8U)
#define UFI_READ_CAPACITY (0x25U)
#define UFI_READ_FORMAT_CAPACITY (0x23U)
#define UFI_REQUEST_SENSE (0x03U)
#define UFI_REZERO_UINT (0x01U)
#define UFI_SEEK (0x2BU)
#define UFI_SEND_DIAGNOSTIC (0x1DU)
#define UFI_TEST_UNIT_READY (0x00U)
#define UFI_VERIFY (0x2FU)
#define UFI_WRITE10 (0x2AU)
#define UFI_WRITE12 (0xAAU)
#define UFI_WRITE_VERIFY (0x2EU)
#define GET_BYTE_FROM_LE_LONG(b, n) \
((uint8_t)((USB_LONG_TO_LITTLE_ENDIAN(b)) >> (n * 8))) /* get the byte from the long value */
/*******************************************************************************
* Prototypes
******************************************************************************/
extern usb_status_t USB_HostMsdCommand(usb_host_class_handle classHandle,
uint8_t *buffer,
uint32_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam,
uint8_t direction,
uint8_t byteValues[10]);
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
usb_status_t USB_HostMsdRead10(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint32_t blockAddress,
uint8_t *buffer,
uint32_t bufferLength,
uint32_t blockNumber,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_READ10,
(uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
GET_BYTE_FROM_LE_LONG(blockAddress, 3),
GET_BYTE_FROM_LE_LONG(blockAddress, 2),
GET_BYTE_FROM_LE_LONG(blockAddress, 1),
GET_BYTE_FROM_LE_LONG(blockAddress, 0),
0x00,
GET_BYTE_FROM_LE_LONG(blockNumber, 1),
GET_BYTE_FROM_LE_LONG(blockNumber, 0),
0x00};
return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
}
usb_status_t USB_HostMsdRead12(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint32_t blockAddress,
uint8_t *buffer,
uint32_t bufferLength,
uint32_t blockNumber,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_READ12,
(uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
GET_BYTE_FROM_LE_LONG(blockAddress, 3),
GET_BYTE_FROM_LE_LONG(blockAddress, 2),
GET_BYTE_FROM_LE_LONG(blockAddress, 1),
GET_BYTE_FROM_LE_LONG(blockAddress, 0),
GET_BYTE_FROM_LE_LONG(blockNumber, 3),
GET_BYTE_FROM_LE_LONG(blockNumber, 2),
GET_BYTE_FROM_LE_LONG(blockNumber, 1),
GET_BYTE_FROM_LE_LONG(blockNumber, 0)};
return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
}
usb_status_t USB_HostMsdWrite10(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint32_t blockAddress,
uint8_t *buffer,
uint32_t bufferLength,
uint32_t blockNumber,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_WRITE10,
(uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
GET_BYTE_FROM_LE_LONG(blockAddress, 3),
GET_BYTE_FROM_LE_LONG(blockAddress, 2),
GET_BYTE_FROM_LE_LONG(blockAddress, 1),
GET_BYTE_FROM_LE_LONG(blockAddress, 0),
0x00,
GET_BYTE_FROM_LE_LONG(blockNumber, 1),
GET_BYTE_FROM_LE_LONG(blockNumber, 0),
0x00};
return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
}
usb_status_t USB_HostMsdWrite12(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint32_t blockAddress,
uint8_t *buffer,
uint32_t bufferLength,
uint32_t blockNumber,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_WRITE12,
(uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
GET_BYTE_FROM_LE_LONG(blockAddress, 3),
GET_BYTE_FROM_LE_LONG(blockAddress, 2),
GET_BYTE_FROM_LE_LONG(blockAddress, 1),
GET_BYTE_FROM_LE_LONG(blockAddress, 0),
GET_BYTE_FROM_LE_LONG(blockNumber, 3),
GET_BYTE_FROM_LE_LONG(blockNumber, 2),
GET_BYTE_FROM_LE_LONG(blockNumber, 1),
GET_BYTE_FROM_LE_LONG(blockNumber, 0)};
return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
}
usb_status_t USB_HostMsdReadCapacity(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t *buffer,
uint32_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_READ_CAPACITY,
(uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00};
return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
}
usb_status_t USB_HostMsdTestUnitReady(usb_host_class_handle classHandle,
uint8_t logicalUnit,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_TEST_UNIT_READY,
(uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00};
return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
ufiBytes);
}
usb_status_t USB_HostMsdRequestSense(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t *buffer,
uint32_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_REQUEST_SENSE,
(uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
0x00,
0x00,
(uint8_t)bufferLength,
0x00,
0x00,
0x00,
0x00,
0x00};
return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
}
usb_status_t USB_HostMsdModeSelect(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t *buffer,
uint32_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_MODE_SELECT,
(uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
0x00,
0x00,
0x00,
0x00,
0x00,
GET_BYTE_FROM_LE_LONG(bufferLength, 1),
GET_BYTE_FROM_LE_LONG(bufferLength, 0),
0x00};
return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
}
usb_status_t USB_HostMsdModeSense(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t pageControl,
uint8_t pageCode,
uint8_t *buffer,
uint32_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_MODE_SENSE, (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
(uint8_t)(((uint32_t)pageCode << USB_HOST_UFI_MODE_SENSE_PAGE_CONTROL_SHIFT) |
((uint32_t)pageCode << USB_HOST_UFI_MODE_SENSE_PAGE_CODE_SHIFT)),
0x00, 0x00, 0x00, 0x00, GET_BYTE_FROM_LE_LONG(bufferLength, 1),
GET_BYTE_FROM_LE_LONG(bufferLength, 0), 0x00};
return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
}
usb_status_t USB_HostMsdInquiry(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t *buffer,
uint32_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_INQUIRY,
(uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
0x00,
0x00,
(uint8_t)bufferLength,
0x00,
0x00,
0x00,
0x00,
0x00};
return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
}
usb_status_t USB_HostMsdReadFormatCapacities(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t *buffer,
uint32_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_READ_FORMAT_CAPACITY,
(uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
0x00,
0x00,
0x00,
0x00,
0x00,
GET_BYTE_FROM_LE_LONG(bufferLength, 1),
GET_BYTE_FROM_LE_LONG(bufferLength, 0),
0x00};
return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
}
usb_status_t USB_HostMsdFormatUnit(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t trackNumber,
uint16_t interLeave,
uint8_t *buffer,
uint32_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_FORMAT_UNIT,
(uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
trackNumber,
GET_BYTE_FROM_LE_LONG(interLeave, 1),
GET_BYTE_FROM_LE_LONG(interLeave, 0),
0x00,
0x00,
GET_BYTE_FROM_LE_LONG(bufferLength, 1),
GET_BYTE_FROM_LE_LONG(bufferLength, 0),
0x00};
return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
}
usb_status_t USB_HostMsdPreventAllowRemoval(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t prevent,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_MEDIUM_REMOVAL,
(uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
0x00,
0x00,
prevent,
0x00,
0x00,
0x00,
0x00,
0x00};
return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
ufiBytes);
}
usb_status_t USB_HostMsdWriteAndVerify(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint32_t blockAddress,
uint8_t *buffer,
uint32_t bufferLength,
uint32_t blockNumber,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_WRITE_VERIFY,
(uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
GET_BYTE_FROM_LE_LONG(blockAddress, 3),
GET_BYTE_FROM_LE_LONG(blockAddress, 2),
GET_BYTE_FROM_LE_LONG(blockAddress, 1),
GET_BYTE_FROM_LE_LONG(blockAddress, 0),
0x00,
GET_BYTE_FROM_LE_LONG(blockNumber, 1),
GET_BYTE_FROM_LE_LONG(blockNumber, 0),
0x00};
return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
}
usb_status_t USB_HostMsdStartStopUnit(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t loadEject,
uint8_t start,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_START_STOP, (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION), 0x00, 0x00,
(uint8_t)(((uint32_t)loadEject << USB_HOST_UFI_START_STOP_UNIT_LOEJ_SHIFT) |
((uint32_t)start << USB_HOST_UFI_START_STOP_UNIT_START_SHIFT)),
0x00, 0x00, 0x00, 0x00, 0x00};
return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
ufiBytes);
}
usb_status_t USB_HostMsdVerify(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint32_t blockAddress,
uint16_t verificationLength,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_VERIFY,
(uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
GET_BYTE_FROM_LE_LONG(blockAddress, 3),
GET_BYTE_FROM_LE_LONG(blockAddress, 2),
GET_BYTE_FROM_LE_LONG(blockAddress, 1),
GET_BYTE_FROM_LE_LONG(blockAddress, 0),
0x00,
GET_BYTE_FROM_LE_LONG(verificationLength, 1),
GET_BYTE_FROM_LE_LONG(verificationLength, 0),
0x00};
return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
ufiBytes);
}
usb_status_t USB_HostMsdRezeroUnit(usb_host_class_handle classHandle,
uint8_t logicalUnit,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_REZERO_UINT,
(uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00};
return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
ufiBytes);
}
usb_status_t USB_HostMsdSeek10(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint32_t blockAddress,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_SEEK,
(uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
GET_BYTE_FROM_LE_LONG(blockAddress, 3),
GET_BYTE_FROM_LE_LONG(blockAddress, 2),
GET_BYTE_FROM_LE_LONG(blockAddress, 1),
GET_BYTE_FROM_LE_LONG(blockAddress, 0),
0x00,
0x00,
0x00,
0x00};
return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
ufiBytes);
}
usb_status_t USB_HostMsdSendDiagnostic(usb_host_class_handle classHandle,
uint8_t logicalUnit,
uint8_t selfTest,
transfer_callback_t callbackFn,
void *callbackParam)
{
uint8_t ufiBytes[] = {UFI_REZERO_UINT,
(uint8_t)(((uint32_t)logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION) |
((uint32_t)selfTest << USB_HOST_UFI_SEND_DIAGNOSTIC_SELF_TEST_SHIFT)),
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
ufiBytes);
}
#endif /* USB_HOST_CONFIG_MSD */

View File

@ -0,0 +1,705 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _USB_HOST_H_
#define _USB_HOST_H_
#include "usb.h"
#include "usb_misc.h"
#include "usb_spec.h"
#include "usb_host_framework.h"
/*******************************************************************************
* Definitions
******************************************************************************/
struct _usb_host_transfer; /* for cross reference */
/*!
* @addtogroup usb_host_drv
* @{
*/
/*! @brief USB host class handle type define */
typedef void *usb_host_class_handle;
/*! @brief USB host controller handle type define */
typedef void *usb_host_controller_handle;
/*! @brief USB host configuration handle type define */
typedef void *usb_host_configuration_handle;
/*! @brief USB host interface handle type define */
typedef void *usb_host_interface_handle;
/*! @brief USB host pipe handle type define */
typedef void *usb_host_pipe_handle;
/*! @brief Event codes for device attach/detach */
typedef enum _usb_host_event
{
kUSB_HostEventAttach = 1U, /*!< Device is attached */
kUSB_HostEventDetach, /*!< Device is detached */
kUSB_HostEventEnumerationDone, /*!< Device's enumeration is done and the device is supported */
kUSB_HostEventNotSupported, /*!< Device's enumeration is done and the device is not supported */
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
kUSB_HostEventNotSuspended, /*!< Suspend failed */
kUSB_HostEventSuspended, /*!< Suspend successful */
kUSB_HostEventNotResumed, /*!< Resume failed */
kUSB_HostEventDetectResume, /*!< Detect resume signal */
kUSB_HostEventResumed, /*!< Resume successful */
kUSB_HostEventL1Sleeped, /*!< L1 Sleep successful,state transition was successful (ACK) */
kUSB_HostEventL1SleepNYET, /*!< Device was unable to enter the L1 state at this time (NYET) */
kUSB_HostEventL1SleepNotSupport, /*!< Device does not support the L1 state (STALL) */
kUSB_HostEventL1SleepError, /*!< Device failed to respond or an error occurred */
kUSB_HostEventL1NotResumed, /*!< Resume failed */
kUSB_HostEventL1DetectResume, /*!< Detect resume signal */
kUSB_HostEventL1Resumed, /*!< Resume successful */
#endif
} usb_host_event_t;
/*! @brief USB host device information code */
typedef enum _usb_host_dev_info
{
kUSB_HostGetDeviceAddress = 1U, /*!< Device's address */
kUSB_HostGetDeviceHubNumber, /*!< Device's first hub address */
kUSB_HostGetDevicePortNumber, /*!< Device's first hub port number */
kUSB_HostGetDeviceSpeed, /*!< Device's speed */
kUSB_HostGetDeviceHSHubNumber, /*!< Device's first high-speed hub address */
kUSB_HostGetDeviceHSHubPort, /*!< Device's first high-speed hub number */
kUSB_HostGetDeviceLevel, /*!< Device's hub level */
kUSB_HostGetHostHandle, /*!< Device's host handle */
kUSB_HostGetDeviceControlPipe, /*!< Device's control pipe handle */
kUSB_HostGetDevicePID, /*!< Device's PID */
kUSB_HostGetDeviceVID, /*!< Device's VID */
kUSB_HostGetHubThinkTime, /*!< Device's hub total think time */
kUSB_HostGetDeviceConfigIndex, /*!< Device's running zero-based config index */
kUSB_HostGetConfigurationDes, /*!< Device's configuration descriptor pointer */
kUSB_HostGetConfigurationLength, /*!< Device's configuration descriptor pointer */
} usb_host_dev_info_t;
/*!
* @brief Host callback function typedef.
*
* This callback function is used to notify application device attach/detach event.
* This callback pointer is passed when initializing the host.
*
* @param deviceHandle The device handle, which indicates the attached device.
* @param configurationHandle The configuration handle contains the attached device's configuration information.
* @param event_code The callback event code; See the enumeration host_event_t.
*
* @return A USB error code or kStatus_USB_Success.
* @retval kStatus_USB_Success Application handles the attached device successfully.
* @retval kStatus_USB_NotSupported Application don't support the attached device.
* @retval kStatus_USB_Error Application handles the attached device falsely.
*/
typedef usb_status_t (*host_callback_t)(usb_device_handle deviceHandle,
usb_host_configuration_handle configurationHandle,
uint32_t eventCode);
/*!
* @brief Transfer callback function typedef.
*
* This callback function is used to notify the upper layer the result of the transfer.
* This callback pointer is passed when calling the send/receive APIs.
*
* @param param The parameter pointer, which is passed when calling the send/receive APIs.
* @param data The data buffer pointer.
* @param data_len The result data length.
* @param status A USB error code or kStatus_USB_Success.
*/
typedef void (*transfer_callback_t)(void *param, uint8_t *data, uint32_t dataLen, usb_status_t status);
/*!
* @brief Host stack inner transfer callback function typedef.
*
* This callback function is used to notify the upper layer the result of a transfer.
* This callback pointer is passed when initializing the structure usb_host_transfer_t.
*
* @param param The parameter pointer, which is passed when calling the send/receive APIs.
* @param transfer The transfer information; See the structure usb_host_transfer_t.
* @param status A USB error code or kStatus_USB_Success.
*/
typedef void (*host_inner_transfer_callback_t)(void *param, struct _usb_host_transfer *transfer, usb_status_t status);
/*! @brief USB host endpoint information structure */
typedef struct _usb_host_ep
{
usb_descriptor_endpoint_t *epDesc; /*!< Endpoint descriptor pointer*/
uint8_t *epExtension; /*!< Endpoint extended descriptor pointer*/
uint16_t epExtensionLength; /*!< Extended descriptor length*/
} usb_host_ep_t;
/*! @brief USB host interface information structure */
typedef struct _usb_host_interface
{
usb_host_ep_t epList[USB_HOST_CONFIG_INTERFACE_MAX_EP]; /*!< Endpoint array*/
usb_descriptor_interface_t *interfaceDesc; /*!< Interface descriptor pointer*/
uint8_t *interfaceExtension; /*!< Interface extended descriptor pointer*/
uint16_t interfaceExtensionLength; /*!< Extended descriptor length*/
uint8_t interfaceIndex; /*!< The interface index*/
uint8_t alternateSettingNumber; /*!< The interface alternate setting value*/
uint8_t epCount; /*!< Interface's endpoint number*/
} usb_host_interface_t;
/*! @brief USB host configuration information structure */
typedef struct _usb_host_configuration
{
usb_host_interface_t interfaceList[USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE]; /*!< Interface array*/
usb_descriptor_configuration_t *configurationDesc; /*!< Configuration descriptor pointer*/
uint8_t *configurationExtension; /*!< Configuration extended descriptor pointer*/
uint16_t configurationExtensionLength; /*!< Extended descriptor length*/
uint8_t interfaceCount; /*!< The configuration's interface number*/
} usb_host_configuration_t;
/*! @brief USB host pipe common structure */
typedef struct _usb_host_pipe
{
struct _usb_host_pipe *next; /*!< Link the idle pipes*/
usb_device_handle deviceHandle; /*!< This pipe's device's handle*/
uint16_t currentCount; /*!< For KHCI transfer*/
uint16_t nakCount; /*!< Maximum NAK count*/
uint16_t maxPacketSize; /*!< Maximum packet size*/
uint16_t interval; /*!< FS/LS: frame unit; HS: micro-frame unit*/
uint8_t open; /*!< 0 - closed, 1 - open*/
uint8_t nextdata01; /*!< Data toggle*/
uint8_t endpointAddress; /*!< Endpoint address*/
uint8_t direction; /*!< Pipe direction*/
uint8_t pipeType; /*!< Pipe type, for example USB_ENDPOINT_BULK*/
uint8_t numberPerUframe; /*!< Transaction number per micro-frame*/
} usb_host_pipe_t;
/*! @brief USB host transfer structure */
typedef struct _usb_host_transfer
{
struct _usb_host_transfer *next; /*!< The next transfer structure*/
uint8_t *transferBuffer; /*!< Transfer data buffer*/
uint32_t transferLength; /*!< Transfer data length*/
uint32_t transferSofar; /*!< Length transferred so far*/
host_inner_transfer_callback_t callbackFn; /*!< Transfer callback function*/
void *callbackParam; /*!< Transfer callback parameter*/
usb_host_pipe_t *transferPipe; /*!< Transfer pipe pointer*/
usb_setup_struct_t *setupPacket; /*!< Set up packet buffer*/
uint8_t direction; /*!< Transfer direction; it's values are USB_OUT or USB_IN*/
uint8_t setupStatus; /*!< Set up the transfer status*/
union
{
uint32_t unitHead; /*!< xTD head for this transfer*/
int32_t transferResult; /*!< KHCI transfer result */
} union1;
union
{
uint32_t unitTail; /*!<xTD tail for this transfer*/
uint32_t frame; /*!< KHCI transfer frame number */
} union2;
#if USB_HOST_CONFIG_KHCI
uint16_t nakTimeout; /*!< KHCI transfer NAK timeout */
uint16_t retry; /*!< KHCI transfer retry */
#endif
} usb_host_transfer_t;
/*! @brief USB host pipe information structure for opening pipe */
typedef struct _usb_host_pipe_init
{
void *devInstance; /*!< Device instance handle*/
uint16_t nakCount; /*!< Maximum NAK retry count. MUST be zero for interrupt*/
uint16_t maxPacketSize; /*!< Pipe's maximum packet size*/
uint8_t interval; /*!< Pipe's interval*/
uint8_t endpointAddress; /*!< Endpoint address*/
uint8_t direction; /*!< Endpoint direction*/
uint8_t pipeType; /*!< Endpoint type, the value is USB_ENDPOINT_INTERRUPT, USB_ENDPOINT_CONTROL,
USB_ENDPOINT_ISOCHRONOUS, USB_ENDPOINT_BULK*/
uint8_t numberPerUframe; /*!< Transaction number for each micro-frame*/
} usb_host_pipe_init_t;
/*! @brief Cancel transfer parameter structure */
typedef struct _usb_host_cancel_param
{
usb_host_pipe_handle pipeHandle; /*!< Canceling pipe handle*/
usb_host_transfer_t *transfer; /*!< Canceling transfer*/
} usb_host_cancel_param_t;
/*******************************************************************************
* API
******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/*!
* @name USB host APIs Part 1
* The following APIs are recommended for application use.
* @{
*/
/*!
* @brief Initializes the USB host stack.
*
* This function initializes the USB host module specified by the controllerId.
*
* @param[in] controllerId The controller ID of the USB IP. See the enumeration usb_controller_index_t.
* @param[out] hostHandle Returns the host handle.
* @param[in] callbackFn Host callback function notifies device attach/detach.
*
* @retval kStatus_USB_Success The host is initialized successfully.
* @retval kStatus_USB_InvalidHandle The hostHandle is a NULL pointer.
* @retval kStatus_USB_ControllerNotFound Cannot find the controller according to the controller ID.
* @retval kStatus_USB_AllocFail Allocation memory fail.
* @retval kStatus_USB_Error Host mutex create fail; KHCI/EHCI mutex or KHCI/EHCI event create fail,
* or, KHCI/EHCI IP initialize fail.
*/
extern usb_status_t USB_HostInit(uint8_t controllerId, usb_host_handle *hostHandle, host_callback_t callbackFn);
/*!
* @brief Deinitializes the USB host stack.
*
* This function deinitializes the USB host module specified by the hostHandle.
*
* @param[in] hostHandle The host handle.
*
* @retval kStatus_USB_Success The host is initialized successfully.
* @retval kStatus_USB_InvalidHandle The hostHandle is a NULL pointer.
* @retval kStatus_USB_Error Controller deinitialization fail.
*/
extern usb_status_t USB_HostDeinit(usb_host_handle hostHandle);
/*!
* @brief Gets the device information.
*
* This function gets the device information.
*
* @param[in] deviceHandle Removing device handle.
* @param[in] infoCode See the enumeration host_dev_info_t.
* @param[out] infoValue Return the information value.
*
* @retval kStatus_USB_Success Close successfully.
* @retval kStatus_USB_InvalidParameter The deviceHandle or info_value is a NULL pointer.
* @retval kStatus_USB_Error The info_code is not the host_dev_info_t value.
*/
extern usb_status_t USB_HostHelperGetPeripheralInformation(usb_device_handle deviceHandle,
uint32_t infoCode,
uint32_t *infoValue);
/*!
* @brief Parses the alternate interface descriptor.
*
* This function parses the alternate interface descriptor and returns an interface information through the structure
* usb_host_interface_t.
*
* @param[in] interfaceHandle The whole interface handle.
* @param[in] alternateSetting Alternate setting value.
* @param[out] interface Return interface information.
*
* @retval kStatus_USB_Success Close successfully.
* @retval kStatus_USB_InvalidHandle The interfaceHandle is a NULL pointer.
* @retval kStatus_USB_InvalidParameter The alternateSetting is 0.
* @retval kStatus_USB_Error The interface descriptor is wrong.
*/
extern usb_status_t USB_HostHelperParseAlternateSetting(usb_host_interface_handle interfaceHandle,
uint8_t alternateSetting,
usb_host_interface_t *interface);
/*!
* @brief Removes the attached device.
*
* This function removes the attached device.
* This function should not be used all the time.
*
* @param[in] hostHandle The host handle.
* @param[in] deviceHandle Removing device handle.
*
* @retval kStatus_USB_Success Remove successfully.
* @retval kStatus_USB_InvalidHandle The hostHandle or deviceHandle is a NULL pointer.
* @retval kStatus_USB_InvalidParameter The deviceHandle instance don't belong to hostHandle instance.
*/
extern usb_status_t USB_HostRemoveDevice(usb_host_handle hostHandle, usb_device_handle deviceHandle);
/*!
* @brief KHCI task function.
*
* The function is used to handle the KHCI controller message.
* In the bare metal environment, this function should be called periodically in the main function.
* In the RTOS environment, this function should be used as a function entry to create a task.
*
* @param[in] hostHandle The host handle.
*/
extern void USB_HostKhciTaskFunction(void *hostHandle);
/*!
* @brief EHCI task function.
*
* The function is used to handle the EHCI controller message.
* In the bare metal environment, this function should be called periodically in the main function.
* In the RTOS environment, this function should be used as a function entry to create a task.
*
* @param[in] hostHandle The host handle.
*/
extern void USB_HostEhciTaskFunction(void *hostHandle);
/*!
* @brief OHCI task function.
*
* The function is used to handle the OHCI controller message.
* In the bare metal environment, this function should be called periodically in the main function.
* In the RTOS environment, this function should be used as a function entry to create a task.
*
* @param[in] hostHandle The host handle.
*/
extern void USB_HostOhciTaskFunction(void *hostHandle);
/*!
* @brief IP3516HS task function.
*
* The function is used to handle the IP3516HS controller message.
* In the bare metal environment, this function should be called periodically in the main function.
* In the RTOS environment, this function should be used as a function entry to create a task.
*
* @param[in] hostHandle The host handle.
*/
extern void USB_HostIp3516HsTaskFunction(void *hostHandle);
/*!
* @brief Device KHCI ISR function.
*
* The function is the KHCI interrupt service routine.
*
* @param[in] hostHandle The host handle.
*/
extern void USB_HostKhciIsrFunction(void *hostHandle);
/*!
* @brief Device EHCI ISR function.
*
* The function is the EHCI interrupt service routine.
*
* @param[in] hostHandle The host handle.
*/
extern void USB_HostEhciIsrFunction(void *hostHandle);
/*!
* @brief Device OHCI ISR function.
*
* The function is the OHCI interrupt service routine.
*
* @param[in] hostHandle The host handle.
*/
extern void USB_HostOhciIsrFunction(void *hostHandle);
/*!
* @brief Device IP3516HS ISR function.
*
* The function is the IP3516HS interrupt service routine.
*
* @param[in] hostHandle The host handle.
*/
extern void USB_HostIp3516HsIsrFunction(void *hostHandle);
/*! @}*/
/*!
* @name USB host APIs Part 2.
* The following APIs are not recommended for application use. They are mainly used in the class driver.
* @{
*/
/*!
* @brief Opens the USB host pipe.
*
* This function opens a pipe according to the pipe_init_ptr parameter.
*
* @param[in] hostHandle The host handle.
* @param[out] pipeHandle The pipe handle pointer used to return the pipe handle.
* @param[in] pipeInit Used to initialize the pipe.
*
* @retval kStatus_USB_Success The host is initialized successfully.
* @retval kStatus_USB_InvalidHandle The hostHandle or pipe_handle_ptr is a NULL pointer.
* @retval kStatus_USB_Error There is no idle pipe.
* Or, there is no idle QH for EHCI.
* Or, bandwidth allocate fail for EHCI.
*/
extern usb_status_t USB_HostOpenPipe(usb_host_handle hostHandle,
usb_host_pipe_handle *pipeHandle,
usb_host_pipe_init_t *pipeInit);
/*!
* @brief Closes the USB host pipe.
*
* This function closes a pipe and frees the related resources.
*
* @param[in] hostHandle The host handle.
* @param[in] pipeHandle The closing pipe handle.
*
* @retval kStatus_USB_Success The host is initialized successfully.
* @retval kStatus_USB_InvalidHandle The hostHandle or pipeHandle is a NULL pointer.
*/
extern usb_status_t USB_HostClosePipe(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle);
/*!
* @brief Sends data to a pipe.
*
* This function requests to send the transfer to the specified pipe.
*
* @param[in] hostHandle The host handle.
* @param[in] pipeHandle The sending pipe handle.
* @param[in] transfer The transfer information.
*
* @retval kStatus_USB_Success Send successfully.
* @retval kStatus_USB_InvalidHandle The hostHandle, pipeHandle or transfer is a NULL pointer.
* @retval kStatus_USB_LackSwapBuffer There is no swap buffer for KHCI.
* @retval kStatus_USB_Error There is no idle QTD/ITD/SITD for EHCI.
*/
extern usb_status_t USB_HostSend(usb_host_handle hostHandle,
usb_host_pipe_handle pipeHandle,
usb_host_transfer_t *transfer);
/*!
* @brief Sends a setup transfer to the pipe.
*
* This function request to send the setup transfer to the specified pipe.
*
* @param[in] hostHandle The host handle.
* @param[in] pipeHandle The sending pipe handle.
* @param[in] transfer The transfer information.
*
* @retval kStatus_USB_Success Send successfully.
* @retval kStatus_USB_InvalidHandle The hostHandle, pipeHandle or transfer is a NULL pointer.
* @retval kStatus_USB_LackSwapBuffer There is no swap buffer for KHCI.
* @retval kStatus_USB_Error There is no idle QTD/ITD/SITD for EHCI.
*/
extern usb_status_t USB_HostSendSetup(usb_host_handle hostHandle,
usb_host_pipe_handle pipeHandle,
usb_host_transfer_t *transfer);
/*!
* @brief Receives the data from the pipe.
*
* This function requests to receive the transfer from the specified pipe.
*
* @param[in] hostHandle The host handle.
* @param[in] pipeHandle The receiving pipe handle.
* @param[in] transfer The transfer information.
*
* @retval kStatus_USB_Success Receive successfully.
* @retval kStatus_USB_InvalidHandle The hostHandle, pipeHandle or transfer is a NULL pointer.
* @retval kStatus_USB_LackSwapBuffer There is no swap buffer for KHCI.
* @retval kStatus_USB_Error There is no idle QTD/ITD/SITD for EHCI.
*/
extern usb_status_t USB_HostRecv(usb_host_handle hostHandle,
usb_host_pipe_handle pipeHandle,
usb_host_transfer_t *transfer);
/*!
* @brief Cancel the pipe's transfers.
*
* This function cancels all pipe's transfers when the parameter transfer is NULL or cancels the transfers altogether.
*
* @param[in] hostHandle The host handle.
* @param[in] pipeHandle The receiving pipe handle.
* @param[in] transfer The transfer information.
*
* @retval kStatus_USB_Success Cancel successfully.
* @retval kStatus_USB_InvalidHandle The hostHandle or pipeHandle is a NULL pointer.
*/
extern usb_status_t USB_HostCancelTransfer(usb_host_handle hostHandle,
usb_host_pipe_handle pipeHandle,
usb_host_transfer_t *transfer);
/*!
* @brief Allocates a transfer resource.
*
* This function allocates a transfer. This transfer is used to pass data information to a low level stack.
*
* @param[in] hostHandle The host handle.
* @param[out] transfer Return the transfer.
*
* @retval kStatus_USB_Success Allocate successfully.
* @retval kStatus_USB_InvalidHandle The hostHandle or transfer is a NULL pointer.
* @retval kStatus_USB_Error There is no idle transfer.
*/
extern usb_status_t USB_HostMallocTransfer(usb_host_handle hostHandle, usb_host_transfer_t **transfer);
/*!
* @brief Frees a transfer resource.
*
* This function frees a transfer. This transfer is used to pass data information to a low level stack.
*
* @param[in] hostHandle The host handle.
* @param[in] transfer Release the transfer.
*
* @retval kStatus_USB_Success Free successfully.
* @retval kStatus_USB_InvalidHandle The hostHandle or transfer is a NULL pointer.
*/
extern usb_status_t USB_HostFreeTransfer(usb_host_handle hostHandle, usb_host_transfer_t *transfer);
/*!
* @brief Requests the USB standard request.
*
* This function sends the USB standard request packet.
*
* @param[in] deviceHandle The device handle for control transfer.
* @param[in] usbRequest A USB standard request code. See the usb_spec.h.
* @param[in] transfer The used transfer.
* @param[in] param The parameter structure is different for different request, see
* usb_host_framework.h.
*
* @retval kStatus_USB_Success Send successfully.
* @retval kStatus_USB_InvalidHandle The deviceHandle is a NULL pointer.
* @retval kStatus_USB_LackSwapBuffer There is no swap buffer for KHCI.
* @retval kStatus_USB_Error There is no idle QTD/ITD/SITD for EHCI,
* Or, the request is not standard request.
*/
extern usb_status_t USB_HostRequestControl(usb_device_handle deviceHandle,
uint8_t usbRequest,
usb_host_transfer_t *transfer,
void *param);
/*!
* @brief Opens the interface.
*
* This function opens the interface. It is used to notify the host driver the interface is used by APP or class driver.
*
* @param[in] deviceHandle Removing device handle.
* @param[in] interfaceHandle Opening interface handle.
*
* @retval kStatus_USB_Success Open successfully.
* @retval kStatus_USB_InvalidHandle The deviceHandle or interfaceHandle is a NULL pointer.
*/
extern usb_status_t USB_HostOpenDeviceInterface(usb_device_handle deviceHandle,
usb_host_interface_handle interfaceHandle);
/*!
* @brief Closes an interface.
*
* This function opens an interface. It is used to notify the host driver the interface is not used by APP or class
* driver.
*
* @param[in] deviceHandle Removing device handle.
* @param[in] interfaceHandle Opening interface handle.
*
* @retval kStatus_USB_Success Close successfully.
* @retval kStatus_USB_InvalidHandle The deviceHandle is a NULL pointer.
*/
extern usb_status_t USB_HostCloseDeviceInterface(usb_device_handle deviceHandle,
usb_host_interface_handle interfaceHandle);
/*!
* @brief Gets a host stack version function.
*
* The function is used to get the host stack version.
*
* @param[out] version The version structure pointer to keep the host stack version.
*
*/
extern void USB_HostGetVersion(uint32_t *version);
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
/*!
* @brief Send a bus or device suspend request.
*
* This function is used to send a bus or device suspend request.
*
* @param[in] hostHandle The host handle.
* @param[in] deviceHandle The device handle.
*
* @retval kStatus_USB_Success Request successfully.
* @retval kStatus_USB_InvalidHandle The hostHandle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_Error There is no idle transfer.
* Or, the deviceHandle is invalid.
* Or, the request is invalid.
*/
extern usb_status_t USB_HostSuspendDeviceResquest(usb_host_handle hostHandle, usb_device_handle deviceHandle);
/*!
* @brief Send a bus or device resume request.
*
* This function is used to send a bus or device resume request.
*
* @param[in] hostHandle The host handle.
* @param[in] deviceHandle The device handle.
*
* @retval kStatus_USB_Success Request successfully.
* @retval kStatus_USB_InvalidHandle The hostHandle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_Error There is no idle transfer.
* Or, the deviceHandle is invalid.
* Or, the request is invalid.
*/
extern usb_status_t USB_HostResumeDeviceResquest(usb_host_handle hostHandle, usb_device_handle deviceHandle);
#if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
/*!
* @brief Send a bus or device suspend request.
*
* This function is used to send a bus or device suspend request.
*
* @param[in] hostHandle The host handle.
* @param[in] deviceHandle The device handle.
*@param[in] sleeptype Bus suspend or single device suspend.
*
* @retval kStatus_USB_Success Request successfully.
* @retval kStatus_USB_InvalidHandle The hostHandle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_Error There is no idle transfer.
* Or, the deviceHandle is invalid.
* Or, the request is invalid.
*/
extern usb_status_t USB_HostL1SleepDeviceResquest(usb_host_handle hostHandle,
usb_device_handle deviceHandle,
uint8_t sleeptype);
/*!
* @brief Send a bus or device resume request.
*
* This function is used to send a bus or device resume request.
*
* @param[in] hostHandle The host handle.
* @param[in] deviceHandle The device handle.
* *@param[in] sleeptype Bus suspend or single device suspend.
*
* @retval kStatus_USB_Success Request successfully.
* @retval kStatus_USB_InvalidHandle The hostHandle is a NULL pointer. Or the controller handle is invalid.
* @retval kStatus_USB_Error There is no idle transfer.
* Or, the deviceHandle is invalid.
* Or, the request is invalid.
*/
extern usb_status_t USB_HostL1ResumeDeviceResquest(usb_host_handle hostHandle,
usb_device_handle deviceHandle,
uint8_t sleepType);
/*!
* @brief Update the lpm param.
*
* The function is used to configure the lpm token.
*
* @param[in] hostHandle The host handle.
* @param[in] lpmParam HIRD value and whether enable remotewakeup.
*
*/
extern usb_status_t USB_HostL1SleepDeviceResquestConfig(usb_host_handle hostHandle, uint8_t *lpmParam);
#endif
/*!
* @brief Update the hardware tick.
*
* The function is used to update the hardware tick.
*
* @param[in] hostHandle The host handle.
* @param[in] tick Current hardware tick(uint is ms).
*
*/
extern usb_status_t USB_HostUpdateHwTick(usb_host_handle hostHandle, uint64_t tick);
#endif
/*! @}*/
#ifdef __cplusplus
}
#endif
/*! @}*/
#endif /* _USB_HOST_H_ */

View File

@ -0,0 +1,156 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _USB_HOST_DEV_MNG_H_
#define _USB_HOST_DEV_MNG_H_
#include "usb_host.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*!
* @addtogroup usb_host_drv
* @{
*/
/*! @brief States of device instances enumeration */
typedef enum _usb_host_device_enumeration_status
{
kStatus_DEV_Notinit = 0, /*!< Device is invalid */
kStatus_DEV_Initial, /*!< Device has been processed by host driver */
kStatus_DEV_GetDes8, /*!< Enumeration process: get 8 bytes' device descriptor */
kStatus_DEV_SetAddress, /*!< Enumeration process: set device address */
kStatus_DEV_GetDes, /*!< Enumeration process: get device descriptor */
kStatus_DEV_GetCfg9, /*!< Enumeration process: get 9 bytes' configuration descriptor */
kStatus_DEV_GetCfg, /*!< Enumeration process: get configuration descriptor */
kStatus_DEV_SetCfg, /*!< Enumeration process: set configuration */
kStatus_DEV_EnumDone, /*!< Enumeration is done */
kStatus_DEV_AppUsed, /*!< This device has been used by application */
} usb_host_device_enumeration_status_t;
/*! @brief States of device's interface */
typedef enum _usb_host_interface_state
{
kStatus_interface_Attached = 1, /*!< Interface's default status */
kStatus_interface_Opened, /*!< Interface is used by application */
kStatus_interface_Detached, /*!< Interface is not used by application */
} usb_host_interface_state_t;
/*! @brief States of device */
typedef enum _usb_host_device_state
{
kStatus_device_Detached = 0, /*!< Device is used by application */
kStatus_device_Attached, /*!< Device's default status */
} usb_host_device_state_t;
/*! @brief Device instance */
typedef struct _usb_host_device_instance
{
struct _usb_host_device_instance *next; /*!< Next device, or NULL */
usb_host_handle hostHandle; /*!< Host handle */
usb_host_configuration_t configuration; /*!< Parsed configuration information for the device */
usb_descriptor_device_t *deviceDescriptor; /*!< Standard device descriptor */
usb_host_pipe_handle controlPipe; /*!< Device's control pipe */
uint8_t *configurationDesc; /*!< Configuration descriptor pointer */
uint16_t configurationLen; /*!< Configuration descriptor length */
uint16_t configurationValue; /*!< Configuration index */
uint8_t interfaceStatus[USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE]; /*!< Interfaces' status, please reference to
#usb_host_interface_state_t */
uint8_t *enumBuffer; /*!< Buffer for enumeration */
uint8_t state; /*!< Device state for enumeration */
uint8_t enumRetries; /*!< Re-enumeration when error in control transfer */
uint8_t stallRetries; /*!< Re-transfer when stall */
uint8_t speed; /*!< Device speed */
uint8_t allocatedAddress; /*!< Temporary address for the device. When set address request succeeds, setAddress is
a value, 1 - 127 */
uint8_t setAddress; /*!< The address has been set to the device successfully, 1 - 127 */
uint8_t deviceAttachState; /*!< See the usb_host_device_state_t */
#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
/* hub related */
uint8_t hubNumber; /*!< Device's first connected hub address (root hub = 0) */
uint8_t portNumber; /*!< Device's first connected hub's port no (1 - 8) */
uint8_t hsHubNumber; /*!< Device's first connected high-speed hub's address (1 - 8) */
uint8_t hsHubPort; /*!< Device's first connected high-speed hub's port no (1 - 8) */
uint8_t level; /*!< Device's level (root device = 0) */
#endif
} usb_host_device_instance_t;
typedef struct _usb_host_enum_process_entry
{
uint8_t successState; /*!< When the last step is successful, the next state value */
uint8_t retryState; /*!< When the last step need retry, the next state value */
usb_status_t (*process)(usb_host_device_instance_t *deviceInstance); /*!< When the last step transfer is done, the
function is used to process the transfer
data */
} usb_host_enum_process_entry_t;
/*******************************************************************************
* API
******************************************************************************/
/*!
* @brief Calls this function when device attach.
*
* @param hostHandle Host instance handle.
* @param speed Device speed.
* @param hubNumber Device hub no. root device's hub no. is 0.
* @param portNumber Device port no. root device's port no. is 0.
* @param level Device level. root device's level is 1.
* @param deviceHandle Return device handle.
*
* @return kStatus_USB_Success or error codes.
*/
extern usb_status_t USB_HostAttachDevice(usb_host_handle hostHandle,
uint8_t speed,
uint8_t hubNumber,
uint8_t portNumber,
uint8_t level,
usb_device_handle *deviceHandle);
/*!
* @brief Call this function when device detaches.
*
* @param hostHandle Host instance handle.
* @param hubNumber Device hub no. root device's hub no. is 0.
* @param portNumber Device port no. root device's port no. is 0.
*
* @return kStatus_USB_Success or error codes.
*/
extern usb_status_t USB_HostDetachDevice(usb_host_handle hostHandle, uint8_t hubNumber, uint8_t portNumber);
/*!
* @brief Call this function when device detaches.
*
* @param hostHandle Host instance handle.
* @param deviceHandle Device handle.
*
* @return kStatus_USB_Success or error codes.
*/
extern usb_status_t USB_HostDetachDeviceInternal(usb_host_handle hostHandle, usb_device_handle deviceHandle);
/*!
* @brief Gets the device attach/detach state.
*
* @param deviceHandle Device handle.
*
* @return 0x01 - attached; 0x00 - detached.
*/
extern uint8_t USB_HostGetDeviceAttachState(usb_device_handle deviceHandle);
/*!
* @brief Determine whether the device is attached.
*
* @param hostHandle Host instance pointer.
* @param deviceHandle Device handle.
*
* @return kStatus_USB_Success or error codes.
*/
extern usb_status_t USB_HostValidateDevice(usb_host_handle hostHandle, usb_device_handle deviceHandle);
/*! @}*/
#endif /* _USB_HOST_DEV_MNG_H_ */

View File

@ -0,0 +1,477 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _USB_HOST_CONTROLLER_EHCI_H_
#define _USB_HOST_CONTROLLER_EHCI_H_
/*******************************************************************************
* KHCI private public structures, enumerations, macros, functions
******************************************************************************/
/*******************************************************************************
* Definitions
******************************************************************************/
/* EHCI host macros */
#define EHCI_HOST_T_INVALID_VALUE (1U)
#define EHCI_HOST_POINTER_TYPE_ITD (0x00U)
#define EHCI_HOST_POINTER_TYPE_QH (0x00000002U)
#define EHCI_HOST_POINTER_TYPE_SITD (0x00000004U)
#define EHCI_HOST_POINTER_TYPE_FSTN (0x00000006U)
#define EHCI_HOST_POINTER_TYPE_MASK (0x00000006U)
#define EHCI_HOST_POINTER_ADDRESS_MASK (0xFFFFFFE0U)
#define EHCI_HOST_PID_OUT (0U)
#define EHCI_HOST_PID_IN (1U)
#define EHCI_HOST_PID_SETUP (2U)
#define EHCI_HOST_QH_RL_SHIFT (28U)
#define EHCI_HOST_QH_RL_MASK (0xF0000000U)
#define EHCI_HOST_QH_C_SHIFT (27U)
#define EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT (16U)
#define EHCI_HOST_QH_MAX_PACKET_LENGTH_MASK (0x07FF0000U)
#define EHCI_HOST_QH_H_SHIFT (15U)
#define EHCI_HOST_QH_DTC_SHIFT (14U)
#define EHCI_HOST_QH_EPS_SHIFT (12U)
#define EHCI_HOST_QH_ENDPT_SHIFT (8U)
#define EHCI_HOST_QH_I_SHIFT (7U)
#define EHCI_HOST_QH_DEVICE_ADDRESS_SHIFT (0U)
#define EHCI_HOST_QH_MULT_SHIFT (30U)
#define EHCI_HOST_QH_PORT_NUMBER_SHIFT (23U)
#define EHCI_HOST_QH_HUB_ADDR_SHIFT (16U)
#define EHCI_HOST_QH_UFRAME_CMASK_SHIFT (8U)
#define EHCI_HOST_QH_UFRAME_SMASK_SHIFT (0U)
#define EHCI_HOST_QH_STATUS_ERROR_MASK (0x0000007EU)
#define EHCI_HOST_QH_STATUS_NOSTALL_ERROR_MASK (0x0000003EU)
#define EHCI_HOST_QTD_DT_SHIFT (31U)
#define EHCI_HOST_QTD_DT_MASK (0x80000000U)
#define EHCI_HOST_QTD_TOTAL_BYTES_SHIFT (16U)
#define EHCI_HOST_QTD_TOTAL_BYTES_MASK (0x7FFF0000U)
#define EHCI_HOST_QTD_IOC_MASK (0x00008000U)
#define EHCI_HOST_QTD_C_PAGE_SHIFT (12U)
#define EHCI_HOST_QTD_CERR_SHIFT (10U)
#define EHCI_HOST_QTD_CERR_MAX_VALUE (0x00000003U)
#define EHCI_HOST_QTD_PID_CODE_SHIFT (8U)
#define EHCI_HOST_QTD_STATUS_SHIFT (0U)
#define EHCI_HOST_QTD_CURRENT_OFFSET_MASK (0x00000FFFU)
#define EHCI_HOST_QTD_BUFFER_POINTER_SHIFT (12U)
#define EHCI_HOST_QTD_STATUS_ACTIVE_MASK (0x00000080U)
#define EHCI_HOST_QTD_STATUS_MASK (0x000000ffU)
#define EHCI_HOST_QTD_STATUS_ERROR_MASK (0x0000007EU)
#define EHCI_HOST_QTD_STATUS_STALL_ERROR_MASK (0x00000040U)
#define EHCI_HOST_ITD_STATUS_ACTIVE_MASK (0x80000000U)
#define EHCI_HOST_ITD_TRANSACTION_LEN_SHIFT (16U)
#define EHCI_HOST_ITD_TRANSACTION_LEN_MASK (0x0FFF0000U)
#define EHCI_HOST_ITD_IOC_SHIFT (15U)
#define EHCI_HOST_ITD_PG_SHIFT (12U)
#define EHCI_HOST_ITD_TRANSACTION_OFFSET_SHIFT (0U)
#define EHCI_HOST_ITD_TRANSACTION_OFFSET_MASK (0x00000FFFU)
#define EHCI_HOST_ITD_BUFFER_POINTER_SHIFT (12U)
#define EHCI_HOST_ITD_ENDPT_SHIFT (8U)
#define EHCI_HOST_ITD_DEVICE_ADDRESS_SHIFT (0U)
#define EHCI_HOST_ITD_MAX_PACKET_SIZE_SHIFT (0U)
#define EHCI_HOST_ITD_MULT_SHIFT (0U)
#define EHCI_HOST_ITD_DIRECTION_SHIFT (11U)
#define EHCI_HOST_SITD_STATUS_ACTIVE_MASK (0x00000080U)
#define EHCI_HOST_SITD_DIRECTION_SHIFT (31U)
#define EHCI_HOST_SITD_PORT_NUMBER_SHIFT (24U)
#define EHCI_HOST_SITD_HUB_ADDR_SHIFT (16U)
#define EHCI_HOST_SITD_ENDPT_SHIFT (8U)
#define EHCI_HOST_SITD_DEVICE_ADDRESS_SHIFT (0U)
#define EHCI_HOST_SITD_CMASK_SHIFT (8U)
#define EHCI_HOST_SITD_SMASK_SHIFT (0U)
#define EHCI_HOST_SITD_TOTAL_BYTES_SHIFT (16U)
#define EHCI_HOST_SITD_TOTAL_BYTES_MASK (0x03FF0000U)
#define EHCI_HOST_SITD_TP_SHIFT (3U)
#define EHCI_HOST_SITD_TCOUNT_SHIFT (0U)
#define EHCI_HOST_SITD_IOC_SHIFT (31U)
/* register related MACROs */
#define EHCI_PORTSC1_W1_BITS (0x0000002AU)
#define EHCI_MAX_UFRAME_VALUE (0x00003FFFU)
/* task event */
#define EHCI_TASK_EVENT_DEVICE_ATTACH (0x01U)
#define EHCI_TASK_EVENT_TRANSACTION_DONE (0x02U)
#define EHCI_TASK_EVENT_DEVICE_DETACH (0x04U)
#define EHCI_TASK_EVENT_PORT_CHANGE (0x08U)
#define EHCI_TASK_EVENT_TIMER0 (0x10U)
#define EHCI_TASK_EVENT_TIMER1 (0x20U)
#define USB_HostEhciLock() USB_OsaMutexLock(ehciInstance->ehciMutex)
#define USB_HostEhciUnlock() USB_OsaMutexUnlock(ehciInstance->ehciMutex)
/*******************************************************************************
* KHCI driver public structures, enumerations, macros, functions
******************************************************************************/
/*!
* @addtogroup usb_host_controller_ehci
* @{
*/
/*! @brief The maximum supported ISO pipe number */
#define USB_HOST_EHCI_ISO_NUMBER USB_HOST_CONFIG_EHCI_MAX_ITD
/*! @brief Check the port connect state delay if the state is unstable */
#define USB_HOST_EHCI_PORT_CONNECT_DEBOUNCE_DELAY (101U)
/*! @brief Delay for port reset */
#define USB_HOST_EHCI_PORT_RESET_DELAY (11U)
/*! @brief The SITD inserts a frame interval for putting more SITD continuously.
* There is an interval when an application sends two FS/LS ISO transfers.
* When the interval is less than the macro, the two transfers are continuous in the frame list. Otherwise, the two
* transfers
* are not continuous.
* For example:
* - Use case 1: when inserting the SITD first, the inserted frame = the current frame value + this MACRO value.
* - Use case 2: when inserting SITD is not first, choose between the last inserted frame value and the
* current frame value according to the following criteria:
* If the interval is less than the MACRO value, the new SITD is continuous with the last SITD.
* If not, the new SITD inserting frame = the current frame value + this MACRO value.
*/
#define USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER (2U)
/*! @brief The ITD inserts a micro-frame interval for putting more ITD continuously.
* There is an interval when an application sends two HS ISO transfers.
* When the interval is less than the macro, the two transfers are continuous in the frame list. Otherwise, the two
* transfers
* are not continuous.
* For example:
* - Use case 1: when inserting ITD first, the inserted micro-frame = the current micro-frame value + this MACRO value.
* - Use case 2: when inserting ITD is not first, choose between the last inserted micro-frame value and the
* current micro-frame value according to the following criteria:
* If the interval is less than this MACRO value, the new ITD is continuous with the last ITD.
* If not, the new ITD inserting micro-frame = the current micro-frame value + this MACRO value.
*/
#define USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER (16U)
/*! @brief Control or bulk transaction timeout value (unit: 100 ms) */
#define USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE (50U)
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
typedef enum _bus_ehci_suspend_request_state
{
kBus_EhciIdle = 0U,
kBus_EhciStartSuspend,
kBus_EhciSuspended,
kBus_EhciStartResume,
} bus_ehci_suspend_request_state_t;
#endif
/*! @brief EHCI state for device attachment/detachment. */
typedef enum _host_ehci_device_state_
{
kEHCIDevicePhyAttached = 1, /*!< Device is physically attached */
kEHCIDeviceAttached, /*!< Device is attached and initialized */
kEHCIDeviceDetached, /*!< Device is detached and de-initialized */
} host_ehci_device_state_t;
/*! @brief EHCI pipe structure */
typedef struct _usb_host_ehci_pipe
{
usb_host_pipe_t pipeCommon; /*!< Common pipe information */
void *ehciQh; /*!< Control/bulk/interrupt: QH; ISO: usb_host_ehci_iso_t*/
/* bandwidth */
uint16_t uframeInterval; /*!< Micro-frame interval value */
uint16_t startFrame; /*!<
Bandwidth start frame: its value is from 0 to frame_list.
*/
uint16_t dataTime; /*!<
Bandwidth time value:
- When the host works as HS: it's the data bandwidth value.
- When the host works as FS/LS:
- For FS/LS device, it's the data bandwidth value when transferring the data by FS/LS.
- For HS device, it's the data bandwidth value when transferring the data by HS.
*/
uint16_t startSplitTime; /*!<
Start splitting the bandwidth time value:
- When the host works as HS, it is the start split bandwidth value.
*/
uint16_t completeSplitTime; /*!<
Complete splitting the bandwidth time value:
- When host works as HS, it is the complete split bandwidth value.
*/
uint8_t startUframe; /*!<
Bandwidth start micro-frame: its value is from 0 to 7.
*/
uint8_t uframeSmask; /*!<
Start micro-frame.
- When host works as an HS:
- For FS/LS device, it's the interrupt or ISO transfer start-split mask.
- For HS device, it's the interrupt transfer start micro-frame mask.
- When host works as FS/LS, it's the interrupt and ISO start micro-frame mask
*/
uint8_t uframeCmask; /*!<
Complete micro-frame
- When host works as HS:
- For FS/LS device, it's the interrupt or ISO transfer complete-split mask.
*/
} usb_host_ehci_pipe_t;
/*! @brief EHCI QH structure. See the USB EHCI specification */
typedef struct _usb_host_ehci_qh
{
uint32_t horizontalLinkPointer; /*!< QH specification filed, queue head a horizontal link pointer */
uint32_t
staticEndpointStates[2]; /*!< QH specification filed, static endpoint state and configuration information */
uint32_t currentQtdPointer; /*!< QH specification filed, current qTD pointer */
uint32_t nextQtdPointer; /*!< QH specification filed, next qTD pointer */
uint32_t alternateNextQtdPointer; /*!< QH specification filed, alternate next qTD pointer */
uint32_t
transferOverlayResults[6]; /*!< QH specification filed, transfer overlay configuration and transfer results */
/* reserved space */
usb_host_ehci_pipe_t *ehciPipePointer; /*!< EHCI pipe pointer */
usb_host_transfer_t *ehciTransferHead; /*!< Transfer list head on this QH */
usb_host_transfer_t *ehciTransferTail; /*!< Transfer list tail on this QH */
uint16_t timeOutValue; /*!< Its maximum value is USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE. When the value is
zero, the transfer times out. */
uint16_t timeOutLabel; /*!< It's used to judge the transfer timeout. The EHCI driver maintain the value */
} usb_host_ehci_qh_t;
/*! @brief EHCI QTD structure. See the USB EHCI specification. */
typedef struct _usb_host_ehci_qtd
{
uint32_t nextQtdPointer; /*!< QTD specification filed, the next QTD pointer */
uint32_t alternateNextQtdPointer; /*!< QTD specification filed, alternate next QTD pointer */
uint32_t transferResults[2]; /*!< QTD specification filed, transfer results fields */
uint32_t bufferPointers[4]; /*!< QTD specification filed, transfer buffer fields */
} usb_host_ehci_qtd_t;
/*! @brief EHCI ITD structure. See the USB EHCI specification. */
typedef struct _usb_host_ehci_itd
{
uint32_t nextLinkPointer; /*!< ITD specification filed, the next linker pointer */
uint32_t transactions[8]; /*!< ITD specification filed, transactions information */
uint32_t bufferPointers[7]; /*!< ITD specification filed, transfer buffer fields */
/* add space */
struct _usb_host_ehci_itd *nextItdPointer; /*!< Next ITD pointer */
uint32_t frameEntryIndex; /*!< The ITD inserted frame value */
uint32_t reserved[6]; /*!< Reserved fields for 32 bytes align */
} usb_host_ehci_itd_t;
/*! @brief EHCI SITD structure. See the USB EHCI specification. */
typedef struct _usb_host_ehci_sitd
{
uint32_t nextLinkPointer; /*!< SITD specification filed, the next linker pointer */
uint32_t endpointStates[2]; /*!< SITD specification filed, endpoint configuration information */
uint32_t transferResults[3]; /*!< SITD specification filed, transfer result fields */
uint32_t backPointer; /*!< SITD specification filed, back pointer */
/* reserved space */
uint16_t frameEntryIndex; /*!< The SITD inserted frame value */
uint8_t nextSitdIndex; /*!< The next SITD index; Get the next SITD pointer through adding base address with the
index. 0xFF means invalid. */
uint8_t reserved; /*!< Reserved fields for 32 bytes align */
} usb_host_ehci_sitd_t;
/*! @brief EHCI ISO structure; An ISO pipe has an instance of this structure to keep the ISO pipe-specific information.
*/
typedef struct _usb_host_ehci_iso
{
struct _usb_host_ehci_iso *next; /*!< Next instance pointer */
usb_host_pipe_t *ehciPipePointer; /*!< This ISO's EHCI pipe pointer */
usb_host_transfer_t *ehciTransferHead; /*!< Transfer list head on this ISO pipe */
usb_host_transfer_t *ehciTransferTail; /*!< Transfer list head on this ISO pipe */
uint16_t lastLinkFrame; /*!< It means that the inserted frame for ISO ITD/SITD. 0xFFFF is invalid. For ITD, it is a
micro-frame value. For SITD, it is a frame value */
} usb_host_ehci_iso_t;
/*! @brief EHCI instance structure */
typedef struct _usb_host_ehci_instance
{
usb_host_handle hostHandle; /*!< Related host handle*/
uint32_t *ehciUnitBase; /*!< Keep the QH/QTD/ITD/SITD buffer pointer for release*/
uint8_t *ehciFrameList; /*!< The frame list of the current ehci instance*/
usb_host_ehci_qh_t *ehciQhList; /*!< Idle QH list pointer */
usb_host_ehci_qtd_t *ehciQtdHead; /*!< Idle QTD list pointer head */
usb_host_ehci_qtd_t *ehciQtdTail; /*!< Idle QTD list pointer tail (recently used qTD will be used)*/
usb_host_ehci_itd_t *ehciItdList; /*!< Idle ITD list pointer*/
usb_host_ehci_sitd_t *ehciSitdIndexBase; /*!< SITD buffer's start pointer*/
usb_host_ehci_sitd_t *ehciSitdList; /*!< Idle SITD list pointer*/
usb_host_ehci_iso_t *ehciIsoList; /*!< Idle ISO list pointer*/
USBHS_Type *ehciIpBase; /*!< EHCI IP base address*/
usb_host_ehci_qh_t *shedFirstQh; /*!< First async QH*/
usb_host_ehci_pipe_t *ehciPipeIndexBase; /*!< Pipe buffer's start pointer*/
usb_host_ehci_pipe_t *ehciPipeList; /*!< Idle pipe list pointer*/
usb_host_ehci_pipe_t *ehciRunningPipeList; /*!< Running pipe list pointer*/
usb_osa_mutex_handle ehciMutex; /*!< EHCI mutex*/
usb_osa_event_handle taskEventHandle; /*!< EHCI task event*/
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
uint64_t matchTick;
USBPHY_Type *registerPhyBase; /*!< The base address of the PHY register */
#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
USBNC_Type *registerNcBase; /*!< The base address of the USBNC register */
#endif
#endif
uint8_t controllerId; /*!< EHCI controller ID*/
uint8_t deviceAttached; /*!< Device attach/detach state, see #host_ehci_device_state_t */
uint8_t firstDeviceSpeed; /*!< The first device's speed, the controller's work speed*/
uint8_t ehciItdNumber; /*!< Idle ITD number*/
uint8_t ehciSitdNumber; /*!< Idle SITD number*/
uint8_t ehciQtdNumber; /*!< Idle QTD number*/
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
bus_ehci_suspend_request_state_t busSuspendStatus; /*!< Bus Suspend Status*/
#endif
} usb_host_ehci_instance_t;
/*! @brief EHCI data structure */
typedef struct _usb_host_ehci_data
{
#if ((defined(USB_HOST_CONFIG_EHCI_MAX_QH)) && (USB_HOST_CONFIG_EHCI_MAX_QH > 0U))
usb_host_ehci_qh_t ehciQh[USB_HOST_CONFIG_EHCI_MAX_QH]; /*!< Idle QH list array*/
#endif
#if ((defined(USB_HOST_CONFIG_EHCI_MAX_QTD)) && (USB_HOST_CONFIG_EHCI_MAX_QTD > 0U))
usb_host_ehci_qtd_t ehciQtd[USB_HOST_CONFIG_EHCI_MAX_QTD]; /*!< Idle QTD list array*/
#endif
#if ((defined(USB_HOST_CONFIG_EHCI_MAX_ITD)) && (USB_HOST_CONFIG_EHCI_MAX_ITD > 0U))
usb_host_ehci_itd_t ehciItd[USB_HOST_CONFIG_EHCI_MAX_ITD]; /*!< Idle ITD list array*/
#endif
#if ((defined(USB_HOST_CONFIG_EHCI_MAX_SITD)) && (USB_HOST_CONFIG_EHCI_MAX_SITD > 0U))
usb_host_ehci_sitd_t ehciSitd[USB_HOST_CONFIG_EHCI_MAX_SITD]; /*!< Idle SITD list array*/
#endif
#if ((defined(USB_HOST_EHCI_ISO_NUMBER)) && (USB_HOST_EHCI_ISO_NUMBER > 0U))
usb_host_ehci_iso_t ehciIso[USB_HOST_EHCI_ISO_NUMBER]; /*!< Idle ISO list array*/
#endif
#if ((defined(USB_HOST_CONFIG_MAX_PIPES)) && (USB_HOST_CONFIG_MAX_PIPES > 0U))
usb_host_ehci_pipe_t ehciPipe[USB_HOST_CONFIG_MAX_PIPES]; /*!< Idle pipe list array*/
#endif
} usb_host_ehci_data_t;
/*******************************************************************************
* API
******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/*!
* @name USB host EHCI APIs
* @{
*/
/*!
* @brief Creates the USB host EHCI instance.
*
* This function initializes the USB host EHCI controller driver.
*
* @param[in] controllerId The controller ID of the USB IP. Please refer to the enumeration usb_controller_index_t.
* @param[in] upperLayerHandle The host level handle.
* @param[out] controllerHandle return the controller instance handle.
*
* @retval kStatus_USB_Success The host is initialized successfully.
* @retval kStatus_USB_AllocFail Allocating memory failed.
* @retval kStatus_USB_Error Host mutex create fail, KHCI/EHCI mutex or KHCI/EHCI event create fail.
* Or, KHCI/EHCI IP initialize fail.
*/
extern usb_status_t USB_HostEhciCreate(uint8_t controllerId,
usb_host_handle upperLayerHandle,
usb_host_controller_handle *controllerHandle);
/*!
* @brief Destroys the USB host EHCI instance.
*
* This function de-initializes The USB host EHCI controller driver.
*
* @param[in] controllerHandle The controller handle.
*
* @retval kStatus_USB_Success The host is initialized successfully.
*/
extern usb_status_t USB_HostEhciDestory(usb_host_controller_handle controllerHandle);
/*!
* @brief Opens the USB host pipe.
*
* This function opens a pipe according to the pipe_init_ptr parameter.
*
* @param[in] controllerHandle The controller handle.
* @param[out] pipeHandle The pipe handle pointer, it is used to return the pipe handle.
* @param[in] pipeInit It is used to initialize the pipe.
*
* @retval kStatus_USB_Success The host is initialized successfully.
* @retval kStatus_USB_Error There is no idle pipe.
* Or, there is no idle QH for EHCI.
* Or, bandwidth allocate fail for EHCI.
*/
extern usb_status_t USB_HostEhciOpenPipe(usb_host_controller_handle controllerHandle,
usb_host_pipe_handle *pipeHandle,
usb_host_pipe_init_t *pipeInit);
/*!
* @brief Closes the USB host pipe.
*
* This function closes a pipe and releases related resources.
*
* @param[in] controllerHandle The controller handle.
* @param[in] pipeHandle The closing pipe handle.
*
* @retval kStatus_USB_Success The host is initialized successfully.
*/
extern usb_status_t USB_HostEhciClosePipe(usb_host_controller_handle controllerHandle, usb_host_pipe_handle pipeHandle);
/*!
* @brief Sends data to the pipe.
*
* This function requests to send the transfer to the specified pipe.
*
* @param[in] controllerHandle The controller handle.
* @param[in] pipeHandle The sending pipe handle.
* @param[in] transfer The transfer information.
*
* @retval kStatus_USB_Success Sent successfully.
* @retval kStatus_USB_LackSwapBuffer There is no swap buffer for KHCI.
* @retval kStatus_USB_Error There is no idle QTD/ITD/SITD for EHCI.
*/
extern usb_status_t USB_HostEhciWritePipe(usb_host_controller_handle controllerHandle,
usb_host_pipe_handle pipeHandle,
usb_host_transfer_t *transfer);
/*!
* @brief Receives data from the pipe.
*
* This function requests to receive the transfer from the specified pipe.
*
* @param[in] controllerHandle The controller handle.
* @param[in] pipeHandle The receiving pipe handle.
* @param[in] transfer The transfer information.
* @retval kStatus_USB_Success Send successfully.
* @retval kStatus_USB_LackSwapBuffer There is no swap buffer for KHCI.
* @retval kStatus_USB_Error There is no idle QTD/ITD/SITD for EHCI.
*/
extern usb_status_t USB_HostEhciReadpipe(usb_host_controller_handle controllerHandle,
usb_host_pipe_handle pipeHandle,
usb_host_transfer_t *transfer);
/*!
* @brief Controls the EHCI.
*
* This function controls the EHCI.
*
* @param[in] controllerHandle The controller handle.
* @param[in] ioctlEvent See enumeration host_bus_control_t.
* @param[in] ioctlParam The control parameter.
*
* @retval kStatus_USB_Success Cancel successfully.
* @retval kStatus_USB_InvalidHandle The controllerHandle is a NULL pointer.
*/
extern usb_status_t USB_HostEhciIoctl(usb_host_controller_handle controllerHandle,
uint32_t ioctlEvent,
void *ioctlParam);
/*! @}*/
#ifdef __cplusplus
}
#endif
/*! @}*/
#endif /* _USB_HOST_CONTROLLER_EHCI_H_ */

View File

@ -0,0 +1,361 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "usb_host_config.h"
#include "usb_host.h"
#include "usb_host_hci.h"
#include "usb_host_devices.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*!
* @brief standard control transfer common code.
*
* @param deviceInstance device instance handle.
* @param transfer transfer.
* @param buffer data buffer pointer.
* @param bufferLen data length.
*
* @return kStatus_USB_Success or error codes.
*/
usb_status_t USB_HostCh9RequestCommon(usb_host_device_instance_t *deviceInstance,
usb_host_transfer_t *transfer,
uint8_t *buffer,
uint32_t bufferLen);
/*!
* @brief standard get status implementation.
*
* @param deviceInstance device instance handle.
* @param transfer transfer.
* @param param parameter.
*
* @return kStatus_USB_Success or error codes.
*/
usb_status_t USB_HostStandardGetStatus(usb_host_device_instance_t *deviceInstance,
usb_host_transfer_t *transfer,
void *param);
/*!
* @brief standard set/clear feature implementation.
*
* @param deviceInstance device instance handle.
* @param transfer transfer.
* @param param parameter.
*
* @return kStatus_USB_Success or error codes.
*/
usb_status_t USB_HostStandardSetClearFeature(usb_host_device_instance_t *deviceInstance,
usb_host_transfer_t *transfer,
void *param);
/*!
* @brief standard set address implementation.
*
* @param deviceInstance device instance handle.
* @param transfer transfer.
* @param param parameter.
*
* @return kStatus_USB_Success or error codes.
*/
usb_status_t USB_HostStandardSetAddress(usb_host_device_instance_t *deviceInstance,
usb_host_transfer_t *transfer,
void *param);
/*!
* @brief standard set/get descriptor implementation.
*
* @param deviceInstance device instance handle.
* @param transfer transfer.
* @param param parameter.
*
* @return kStatus_USB_Success or error codes.
*/
usb_status_t USB_HostStandardSetGetDescriptor(usb_host_device_instance_t *deviceInstance,
usb_host_transfer_t *transfer,
void *param);
/*!
* @brief standard get interface implementation.
*
* @param deviceInstance device instance handle.
* @param transfer transfer.
* @param param parameter.
*
* @return kStatus_USB_Success or error codes.
*/
usb_status_t USB_HostStandardGetInterface(usb_host_device_instance_t *deviceInstance,
usb_host_transfer_t *transfer,
void *param);
/*!
* @brief standard set interface implementation.
*
* @param deviceInstance device instance handle.
* @param transfer transfer.
* @param param parameter.
*
* @return kStatus_USB_Success or error codes.
*/
usb_status_t USB_HostStandardSetInterface(usb_host_device_instance_t *deviceInstance,
usb_host_transfer_t *transfer,
void *param);
/*!
* @brief standard sync frame implementation.
*
* @param deviceInstance device instance handle.
* @param transfer transfer.
* @param param parameter.
*
* @return kStatus_USB_Success or error codes.
*/
usb_status_t USB_HostStandardSyncFrame(usb_host_device_instance_t *deviceInstance,
usb_host_transfer_t *transfer,
void *param);
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
usb_status_t USB_HostCh9RequestCommon(usb_host_device_instance_t *deviceInstance,
usb_host_transfer_t *transfer,
uint8_t *buffer,
uint32_t bufferLen)
{
/* initialize transfer */
transfer->setupPacket->wLength = USB_SHORT_TO_LITTLE_ENDIAN(bufferLen);
transfer->transferBuffer = buffer;
transfer->transferLength = bufferLen;
if (USB_HostSendSetup(deviceInstance->hostHandle, deviceInstance->controlPipe, transfer) !=
kStatus_USB_Success) /* send setup transfer */
{
#ifdef HOST_ECHO
usb_echo("failed for USB_HostSendSetup\r\n");
#endif
USB_HostFreeTransfer(deviceInstance->hostHandle, transfer);
return kStatus_USB_Error;
}
return kStatus_USB_Success;
}
usb_status_t USB_HostStandardGetStatus(usb_host_device_instance_t *deviceInstance,
usb_host_transfer_t *transfer,
void *param)
{
usb_host_get_status_param_t *statusParam;
uint8_t length;
/* initialize transfer */
statusParam = (usb_host_get_status_param_t *)param;
transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_STANDARD;
if (statusParam->requestType == kRequestDevice)
{
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_DEVICE;
}
else if (statusParam->requestType == kRequestInterface)
{
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
}
else
{
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
}
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(statusParam->statusSelector);
length = 2;
if (statusParam->statusSelector == USB_REQUEST_STANDARD_GET_STATUS_OTG_STATUS_SELECTOR)
{
length = 1;
}
return USB_HostCh9RequestCommon(deviceInstance, transfer, statusParam->statusBuffer, length);
}
usb_status_t USB_HostStandardSetClearFeature(usb_host_device_instance_t *deviceInstance,
usb_host_transfer_t *transfer,
void *param)
{
usb_host_process_feature_param_t *featureParam;
/* initialize transfer */
featureParam = (usb_host_process_feature_param_t *)param;
if (featureParam->requestType == kRequestDevice)
{
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_DEVICE;
}
else if (featureParam->requestType == kRequestInterface)
{
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
}
else
{
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
}
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(featureParam->featureSelector);
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(featureParam->interfaceOrEndpoint);
return USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
}
usb_status_t USB_HostStandardSetAddress(usb_host_device_instance_t *deviceInstance,
usb_host_transfer_t *transfer,
void *param)
{
uint8_t address;
/* initialize transfer */
address = *(uint8_t *)param;
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(address);
return USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
}
usb_status_t USB_HostStandardSetGetDescriptor(usb_host_device_instance_t *deviceInstance,
usb_host_transfer_t *transfer,
void *param)
{
usb_host_process_descriptor_param_t *descriptorParam;
/* initialize transfer */
descriptorParam = (usb_host_process_descriptor_param_t *)param;
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(
(uint16_t)((uint16_t)descriptorParam->descriptorType << 8) | descriptorParam->descriptorIndex);
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(descriptorParam->languageId);
return USB_HostCh9RequestCommon(deviceInstance, transfer, descriptorParam->descriptorBuffer,
descriptorParam->descriptorLength);
}
usb_status_t USB_HostStandardGetInterface(usb_host_device_instance_t *deviceInstance,
usb_host_transfer_t *transfer,
void *param)
{
usb_host_get_interface_param_t *interfaceParam;
/* initialize transfer */
interfaceParam = (usb_host_get_interface_param_t *)param;
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(interfaceParam->interface);
return USB_HostCh9RequestCommon(deviceInstance, transfer, interfaceParam->alternateInterfaceBuffer, 1);
}
usb_status_t USB_HostStandardSetInterface(usb_host_device_instance_t *deviceInstance,
usb_host_transfer_t *transfer,
void *param)
{
usb_host_set_interface_param_t *setParam;
/* initialize transfer */
setParam = (usb_host_set_interface_param_t *)param;
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(setParam->interface);
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(setParam->alternateSetting);
return USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
}
usb_status_t USB_HostStandardSyncFrame(usb_host_device_instance_t *deviceInstance,
usb_host_transfer_t *transfer,
void *param)
{
usb_host_synch_frame_param_t *frameParam;
/* initialize transfer */
frameParam = (usb_host_synch_frame_param_t *)param;
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(frameParam->endpoint);
return USB_HostCh9RequestCommon(deviceInstance, transfer, frameParam->frameNumberBuffer, 2);
}
usb_status_t USB_HostRequestControl(usb_device_handle deviceHandle,
uint8_t usbRequest,
usb_host_transfer_t *transfer,
void *param)
{
usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
usb_status_t status = kStatus_USB_Error;
if (deviceHandle == NULL)
{
return kStatus_USB_InvalidHandle;
}
/* reset transfer fields */
transfer->setupPacket->bmRequestType = 0x00;
transfer->setupPacket->bRequest = usbRequest;
transfer->setupPacket->wIndex = 0;
transfer->setupPacket->wLength = 0;
transfer->setupPacket->wValue = 0;
switch (usbRequest)
{
case USB_REQUEST_STANDARD_GET_STATUS: /* standard get status request */
status = USB_HostStandardGetStatus(deviceInstance, transfer, param);
break;
case USB_REQUEST_STANDARD_CLEAR_FEATURE: /* standard clear status request */
case USB_REQUEST_STANDARD_SET_FEATURE: /* standard set feature request */
status = USB_HostStandardSetClearFeature(deviceInstance, transfer, param);
break;
case USB_REQUEST_STANDARD_SET_ADDRESS: /* standard set address request */
status = USB_HostStandardSetAddress(deviceInstance, transfer, param);
break;
case USB_REQUEST_STANDARD_GET_DESCRIPTOR: /* standard get descriptor request */
case USB_REQUEST_STANDARD_SET_DESCRIPTOR: /* standard set descriptor request */
if (usbRequest == USB_REQUEST_STANDARD_GET_DESCRIPTOR)
{
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
}
status = USB_HostStandardSetGetDescriptor(deviceInstance, transfer, param);
break;
case USB_REQUEST_STANDARD_GET_CONFIGURATION: /* standard get configuration descriptor request */
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
status =
USB_HostCh9RequestCommon((usb_host_device_instance_t *)deviceHandle, transfer, (uint8_t *)param, 1);
break;
case USB_REQUEST_STANDARD_SET_CONFIGURATION: /* standard set configuration request */
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(*((uint8_t *)param));
status = USB_HostCh9RequestCommon((usb_host_device_instance_t *)deviceHandle, transfer, NULL, 0);
break;
case USB_REQUEST_STANDARD_GET_INTERFACE: /* standard get interface request */
status = USB_HostStandardGetInterface(deviceInstance, transfer, param);
break;
case USB_REQUEST_STANDARD_SET_INTERFACE: /* standard set interface request */
status = USB_HostStandardSetInterface(deviceInstance, transfer, param);
break;
case USB_REQUEST_STANDARD_SYNCH_FRAME: /* standard synch frame request */
status = USB_HostStandardSyncFrame(deviceInstance, transfer, param);
break;
default:
break;
}
return status;
}

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _USB_HOST_CH9_H_
#define _USB_HOST_CH9_H_
/*******************************************************************************
* Definitions
******************************************************************************/
/*!
* @addtogroup usb_host_drv
* @{
*/
/*! @brief Request type */
typedef enum _usb_host_request_type
{
kRequestDevice = 1U, /*!< Control request object is device */
kRequestInterface, /*!< Control request object is interface */
kRequestEndpoint, /*!< Control request object is endpoint */
} usb_host_request_type_t;
/*! @brief For USB_REQUEST_STANDARD_CLEAR_FEATURE and USB_REQUEST_STANDARD_SET_FEATURE */
typedef struct _usb_host_process_feature_param
{
uint8_t requestType; /*!< See the #usb_host_request_type_t */
uint8_t featureSelector; /*!< Set/cleared feature */
uint8_t interfaceOrEndpoint; /*!< Interface or end pointer */
} usb_host_process_feature_param_t;
/*! @brief For USB_REQUEST_STANDARD_GET_DESCRIPTOR and USB_REQUEST_STANDARD_SET_DESCRIPTOR */
typedef struct _usb_host_process_descriptor_param
{
uint8_t descriptorType; /*!< See the usb_spec.h, such as the USB_DESCRIPTOR_TYPE_DEVICE */
uint8_t descriptorIndex; /*!< The descriptor index is used to select a specific descriptor (only for configuration
and string descriptors) when several descriptors of the same type are implemented in a
device */
uint8_t languageId; /*!< It specifies the language ID for string descriptors or is reset to zero for other
descriptors */
uint8_t *descriptorBuffer; /*!< Buffer pointer */
uint16_t descriptorLength; /*!< Buffer data length */
} usb_host_process_descriptor_param_t;
/*! @brief For USB_REQUEST_STANDARD_GET_INTERFACE */
typedef struct _usb_host_get_interface_param
{
uint8_t interface; /*!< Interface number */
uint8_t *alternateInterfaceBuffer; /*!< Save the transfer result */
} usb_host_get_interface_param_t;
/*! @brief For USB_REQUEST_STANDARD_GET_STATUS */
typedef struct _usb_host_get_status_param
{
uint16_t statusSelector; /*!< Interface number, the end pointer number or OTG status selector */
uint8_t requestType; /*!< See the #usb_host_request_type_t */
uint8_t *statusBuffer; /*!< Save the transfer result */
} usb_host_get_status_param_t;
/*! @brief For USB_REQUEST_STANDARD_SET_INTERFACE */
typedef struct _usb_host_set_interface_param
{
uint8_t alternateSetting; /*!< Alternate setting value */
uint8_t interface; /*!< Interface number */
} usb_host_set_interface_param_t;
/*! @brief For USB_REQUEST_STANDARD_SYNCH_FRAME */
typedef struct _usb_host_synch_frame_param
{
uint8_t endpoint; /*!< Endpoint number */
uint8_t *frameNumberBuffer; /*!< Frame number data buffer */
} usb_host_synch_frame_param_t;
/*! @}*/
/*******************************************************************************
* API
******************************************************************************/
#endif /* _USB_HOST_CH9_H_ */

View File

@ -0,0 +1,109 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _USB_HOST_HCI_H_
#define _USB_HOST_HCI_H_
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief USB host lock */
#define USB_HostLock() USB_OsaMutexLock(hostInstance->hostMutex)
/*! @brief USB host unlock */
#define USB_HostUnlock() USB_OsaMutexUnlock(hostInstance->hostMutex)
/*!
* @addtogroup usb_host_controller_driver
* @{
*/
/*! @brief USB host controller control code */
typedef enum _usb_host_controller_control
{
kUSB_HostCancelTransfer = 1U, /*!< Cancel transfer code */
kUSB_HostBusControl, /*!< Bus control code */
kUSB_HostGetFrameNumber, /*!< Get frame number code */
kUSB_HostUpdateControlEndpointAddress, /*!< Update control endpoint address */
kUSB_HostUpdateControlPacketSize, /*!< Update control endpoint maximum packet size */
kUSB_HostPortAttachDisable, /*!< Disable the port attach event */
kUSB_HostPortAttachEnable, /*!< Enable the port attach event */
kUSB_HostL1Config, /*!< L1 suspend Bus control code */
} usb_host_controller_control_t;
/*! @brief USB host controller bus control code */
typedef enum _usb_host_bus_control
{
kUSB_HostBusReset = 1U, /*!< Reset bus */
kUSB_HostBusRestart, /*!< Restart bus */
kUSB_HostBusEnableAttach, /*!< Enable attach */
kUSB_HostBusDisableAttach, /*!< Disable attach */
kUSB_HostBusSuspend, /*!< Suspend BUS */
kUSB_HostBusResume, /*!< Resume BUS */
kUSB_HostBusL1SuspendInit, /*!< L1 Suspend BUS */
kUSB_HostBusL1Sleep, /*!< L1 Suspend BUS */
kUSB_HostBusL1Resume, /*!< L1 Resume BUS */
} usb_host_bus_control_t;
/*! @brief USB host controller interface structure */
typedef struct _usb_host_controller_interface
{
usb_status_t (*controllerCreate)(
uint8_t controllerId,
usb_host_handle upperLayerHandle,
usb_host_controller_handle *controllerHandle); /*!< Create a controller instance function prototype*/
usb_status_t (*controllerDestory)(
usb_host_controller_handle controllerHandle); /*!< Destroy a controller instance function prototype*/
usb_status_t (*controllerOpenPipe)(usb_host_controller_handle controllerHandle,
usb_host_pipe_handle *pipeHandle,
usb_host_pipe_init_t *pipeInit); /*!< Open a controller pipe function prototype*/
usb_status_t (*controllerClosePipe)(
usb_host_controller_handle controllerHandle,
usb_host_pipe_handle pipeHandle); /*!< Close a controller pipe function prototype*/
usb_status_t (*controllerWritePipe)(usb_host_controller_handle controllerHandle,
usb_host_pipe_handle pipeHandle,
usb_host_transfer_t *transfer); /*!< Write data to a pipe function prototype*/
usb_status_t (*controllerReadPipe)(usb_host_controller_handle controllerHandle,
usb_host_pipe_handle pipeHandle,
usb_host_transfer_t *transfer); /*!< Read data from a pipe function prototype*/
usb_status_t (*controllerIoctl)(usb_host_controller_handle controllerHandle,
uint32_t ioctlEvent,
void *ioctlParam); /*!< Control a controller function prototype*/
} usb_host_controller_interface_t;
/*! @}*/
/*!
* @addtogroup usb_host_drv
* @{
*/
/*! @brief USB host instance structure */
typedef struct _usb_host_instance
{
void *controllerHandle; /*!< The low level controller handle*/
host_callback_t deviceCallback; /*!< Device attach/detach callback*/
usb_osa_mutex_handle hostMutex; /*!< Host layer mutex*/
usb_host_transfer_t transferList[USB_HOST_CONFIG_MAX_TRANSFERS]; /*!< Transfer resource*/
usb_host_transfer_t *transferHead; /*!< Idle transfer head*/
const usb_host_controller_interface_t *controllerTable; /*!< KHCI/EHCI interface*/
void *deviceList; /*!< Device list*/
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
void *suspendedDevice; /*!< Suspended device handle*/
volatile uint64_t hwTick; /*!< Current hw tick(ms)*/
uint8_t sleepType; /*!< L1 LPM device handle*/
#endif
uint8_t addressBitMap[16]; /*!< Used for address allocation. The first bit is the address 1, second bit is the
address 2*/
uint8_t occupied; /*!< 0 - the instance is not occupied; 1 - the instance is occupied*/
uint8_t controllerId; /*!< The controller ID*/
} usb_host_instance_t;
/*! @}*/
#endif /* _USB_HOST_HCI_H_ */

View File

@ -0,0 +1,735 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016, 2018 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file host_msd_command.c
* @brief modify usb msd command test function
* @version 2.0
* @author AIIT XUOS Lab
* @date 2022-02-10
*/
/*************************************************
File name: usb_misc.h
Description: modify usb_echo to KPrintf
Others: take SDK_2.6.1_MIMXRT1052xxxxB/boards/evkbimxrt1050/usb_examples/usb_host_msd_command for references
History:
1. Date: 2022-02-10
Author: AIIT XUOS Lab
Modification:
1. modify USB_HostMsdCommandTest, delete read10 and write10 test
2. add USB_HostMsdReadApi and USB_HostMsdWriteApi
3. add UsbMountFileSystem() and UsbUnmountFileSystem()
*************************************************/
#include "usb_host_config.h"
#include "usb_host.h"
#include "usb_host_msd.h"
#include "host_msd_command.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#if MSD_THROUGHPUT_TEST_ENABLE
#include "fsl_device_registers.h"
#define THROUGHPUT_BUFFER_SIZE (64 * 1024) /* throughput test buffer */
#define MCU_CORE_CLOCK (120000000) /* mcu core clock, user need to configure it. */
#endif /* MSD_THROUGHPUT_TEST_ENABLE */
/*******************************************************************************
* Prototypes
******************************************************************************/
extern void UsbMountFileSystem();
extern void UsbUnmountFileSystem();
/*!
* @brief host msd ufi command callback.
*
* This function is used as callback function for ufi command.
*
* @param param the host msd command instance pointer.
* @param data data buffer pointer.
* @param dataLength data length.
* @status transfer result status.
*/
static void USB_HostMsdUfiCallback(void *param, uint8_t *data, uint32_t dataLength, usb_status_t status);
/*!
* @brief host msd control transfer callback.
*
* This function is used as callback function for control transfer .
*
* @param param the host msd command instance pointer.
* @param data data buffer pointer.
* @param dataLength data length.
* @status transfer result status.
*/
static void USB_HostMsdControlCallback(void *param, uint8_t *data, uint32_t dataLength, usb_status_t status);
/*!
* @brief host msd command test done.
*
* @param msdCommandInstance the host command instance pointer.
*/
static void msd_command_test_done(usb_host_msd_command_instance_t *msdCommandInstance);
/*!
* @brief host msd command test.
*
* This function implements msd command test.
*
* @param msdCommandInstance the host command instance pointer.
*/
static void USB_HostMsdCommandTest(usb_host_msd_command_instance_t *msdCommandInstance);
/*******************************************************************************
* Variables
******************************************************************************/
extern usb_host_handle g_HostHandle; /* global host handle */
usb_host_msd_command_instance_t g_MsdCommandInstance = {0}; /* global msd command instance */
/* command on-going state. It should set to 1 when start command, it is set to 0 in the callback */
volatile uint8_t ufiIng;
/* command callback status */
volatile usb_status_t ufiStatus;
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t s_TestUfiBuffer[512]; /*!< test buffer */
#if MSD_THROUGHPUT_TEST_ENABLE
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint32_t testThroughputBuffer[THROUGHPUT_BUFFER_SIZE / 4]; /* the buffer for throughput test */
uint32_t testSizeArray[] = {50 * 1024, 50 * 1024}; /* test time and test size (uint: K) */
#endif /* MSD_THROUGHPUT_TEST_ENABLE */
/*******************************************************************************
* Code
******************************************************************************/
static void USB_HostMsdUfiCallback(void *param, uint8_t *data, uint32_t dataLength, usb_status_t status)
{
ufiIng = 0;
ufiStatus = status;
}
static void USB_HostMsdControlCallback(void *param, uint8_t *data, uint32_t dataLength, usb_status_t status)
{
usb_host_msd_command_instance_t *msdCommandInstance = (usb_host_msd_command_instance_t *)param;
if (msdCommandInstance->runWaitState == kUSB_HostMsdRunWaitSetInterface) /* set interface finish */
{
msdCommandInstance->runWaitState = kUSB_HostMsdRunIdle;
msdCommandInstance->runState = kUSB_HostMsdRunMassStorageTest;
}
}
static void msd_command_test_done(usb_host_msd_command_instance_t *msdCommandInstance)
{
usb_echo("........................check USB device done....................\r\n");
}
static inline void USB_HostControllerTaskFunction(usb_host_handle hostHandle)
{
#if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
USB_HostKhciTaskFunction(hostHandle);
#endif /* USB_HOST_CONFIG_KHCI */
#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
USB_HostEhciTaskFunction(hostHandle);
#endif /* USB_HOST_CONFIG_EHCI */
#if ((defined USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI > 0U))
USB_HostOhciTaskFunction(g_HostHandle);
#endif /* USB_HOST_CONFIG_OHCI */
#if ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS > 0U))
USB_HostIp3516HsTaskFunction(g_HostHandle);
#endif /* USB_HOST_CONFIG_IP3516HS */
}
static void USB_HostMsdCommandTest(usb_host_msd_command_instance_t *msdCommandInstance)
{
usb_status_t status;
uint32_t blockSize = 512;
uint32_t address;
usb_echo("........................check USB device start....................\r\n");
usb_echo("get max logical units....");
ufiIng = 1;
status = USB_HostMsdGetMaxLun(msdCommandInstance->classHandle, msdCommandInstance->testUfiBuffer,
USB_HostMsdUfiCallback, msdCommandInstance);
if (status != kStatus_USB_Success)
{
usb_echo("error\r\n");
msd_command_test_done(msdCommandInstance);
return;
}
while (ufiIng) /* wait the command */
{
USB_HostControllerTaskFunction(g_HostHandle);
}
if (ufiStatus == kStatus_USB_Success) /* print the command result */
{
usb_echo("success, logical units: %d\r\n", msdCommandInstance->testUfiBuffer[0]);
}
else
{
usb_echo("fail\r\n");
msd_command_test_done(msdCommandInstance);
return;
}
if (msdCommandInstance->deviceState != kStatus_DEV_Attached)
{
msd_command_test_done(msdCommandInstance);
return;
}
usb_echo("test unit ready....");
ufiIng = 1;
status = USB_HostMsdTestUnitReady(msdCommandInstance->classHandle, 0, USB_HostMsdUfiCallback, msdCommandInstance);
if (status != kStatus_USB_Success)
{
usb_echo("error\r\n");
msd_command_test_done(msdCommandInstance);
return;
}
while (ufiIng) /* wait the command */
{
USB_HostControllerTaskFunction(g_HostHandle);
}
if ((ufiStatus == kStatus_USB_Success) || (ufiStatus == kStatus_USB_MSDStatusFail)) /* print the command result */
{
usb_echo("success, unit status: %s\r\n", ufiStatus == kStatus_USB_MSDStatusFail ? "not ready" : "ready");
}
else
{
usb_echo("fail\r\n");
msd_command_test_done(msdCommandInstance);
return;
}
if (msdCommandInstance->deviceState != kStatus_DEV_Attached)
{
msd_command_test_done(msdCommandInstance);
return;
}
usb_echo("request sense....");
ufiIng = 1;
status = USB_HostMsdRequestSense(msdCommandInstance->classHandle, 0, msdCommandInstance->testUfiBuffer,
sizeof(usb_host_ufi_sense_data_t), USB_HostMsdUfiCallback, msdCommandInstance);
if (status != kStatus_USB_Success)
{
usb_echo("error\r\n");
msd_command_test_done(msdCommandInstance);
return;
}
while (ufiIng) /* wait the command */
{
USB_HostControllerTaskFunction(g_HostHandle);
}
if (ufiStatus == kStatus_USB_Success) /* print the command result */
{
usb_echo("success\r\n");
}
else
{
usb_echo("fail\r\n");
msd_command_test_done(msdCommandInstance);
return;
}
if (msdCommandInstance->deviceState != kStatus_DEV_Attached)
{
msd_command_test_done(msdCommandInstance);
return;
}
usb_echo("inquiry...");
ufiIng = 1;
status = USB_HostMsdInquiry(msdCommandInstance->classHandle, 0, msdCommandInstance->testUfiBuffer,
sizeof(usb_host_ufi_inquiry_data_t), USB_HostMsdUfiCallback, msdCommandInstance);
if (status != kStatus_USB_Success)
{
usb_echo("error\r\n");
msd_command_test_done(msdCommandInstance);
return;
}
while (ufiIng) /* wait the command */
{
USB_HostControllerTaskFunction(g_HostHandle);
}
if (ufiStatus == kStatus_USB_Success) /* print the command result */
{
usb_echo("success\r\n");
}
else
{
usb_echo("fail\r\n");
msd_command_test_done(msdCommandInstance);
return;
}
if (msdCommandInstance->deviceState != kStatus_DEV_Attached)
{
msd_command_test_done(msdCommandInstance);
return;
}
usb_echo("read capacity...");
ufiIng = 1;
status = USB_HostMsdReadCapacity(msdCommandInstance->classHandle, 0, msdCommandInstance->testUfiBuffer,
sizeof(usb_host_ufi_read_capacity_t), USB_HostMsdUfiCallback, msdCommandInstance);
if (status != kStatus_USB_Success)
{
usb_echo("error\r\n");
msd_command_test_done(msdCommandInstance);
return;
}
while (ufiIng) /* wait the command */
{
USB_HostControllerTaskFunction(g_HostHandle);
}
if (ufiStatus == kStatus_USB_Success) /* print the command result */
{
address = (uint32_t) & (msdCommandInstance->testUfiBuffer[0]);
address = (uint32_t)((usb_host_ufi_read_capacity_t *)(address))->blockLengthInBytes;
blockSize = USB_LONG_FROM_BIG_ENDIAN_ADDRESS(((uint8_t *)address));
address = (uint32_t) & (msdCommandInstance->testUfiBuffer[0]);
address = (uint32_t)((usb_host_ufi_read_capacity_t *)(address))->lastLogicalBlockAddress;
usb_echo("success, last logical block:%d block length:%d\r\n",
USB_LONG_FROM_BIG_ENDIAN_ADDRESS(((uint8_t *)address)), blockSize);
}
else
{
usb_echo("fail\r\n");
msd_command_test_done(msdCommandInstance);
return;
}
if (msdCommandInstance->deviceState != kStatus_DEV_Attached)
{
msd_command_test_done(msdCommandInstance);
return;
}
#if 1
if (blockSize == 0)
{
blockSize = 512;
}
usb_echo("read(10)...");
ufiIng = 1;
status = USB_HostMsdRead10(msdCommandInstance->classHandle, 0, 0, msdCommandInstance->testUfiBuffer, blockSize, 1,
USB_HostMsdUfiCallback, msdCommandInstance);
if (status != kStatus_USB_Success)
{
usb_echo("error\r\n");
msd_command_test_done(msdCommandInstance);
return;
}
while (ufiIng) /* wait the command */
{
USB_HostControllerTaskFunction(g_HostHandle);
}
if (ufiStatus == kStatus_USB_Success) /* print the command result */
{
usb_echo("success\r\n");
}
else
{
usb_echo("fail\r\n");
msd_command_test_done(msdCommandInstance);
return;
}
if (msdCommandInstance->deviceState != kStatus_DEV_Attached)
{
msd_command_test_done(msdCommandInstance);
return;
}
usb_echo("write(10)...");
ufiIng = 1;
status = USB_HostMsdWrite10(msdCommandInstance->classHandle, 0, 0, msdCommandInstance->testUfiBuffer, blockSize, 1,
USB_HostMsdUfiCallback, msdCommandInstance);
if (status != kStatus_USB_Success)
{
usb_echo("error\r\n");
msd_command_test_done(msdCommandInstance);
return;
}
while (ufiIng) /* wait the command */
{
USB_HostControllerTaskFunction(g_HostHandle);
}
if (ufiStatus == kStatus_USB_Success) /* print the command result */
{
usb_echo("success\r\n");
}
else
{
usb_echo("fail\r\n");
msd_command_test_done(msdCommandInstance);
return;
}
#endif
#if MSD_THROUGHPUT_TEST_ENABLE
uint64_t totalTime;
uint32_t testSize;
uint32_t blockAddress;
uint8_t testIndex;
/* time delay (~100ms) */
for (testSize = 0; testSize < 400000; ++testSize)
{
__ASM("nop");
}
CoreDebug->DEMCR |= (1 << CoreDebug_DEMCR_TRCENA_Pos);
for (testSize = 0; testSize < (THROUGHPUT_BUFFER_SIZE / 4); ++testSize)
{
testThroughputBuffer[testSize] = testSize;
}
usb_echo("throughput test:\r\n");
for (testIndex = 0; testIndex < (sizeof(testSizeArray) / 4); ++testIndex)
{
totalTime = 0;
blockAddress = 0;
testSize = testSizeArray[testIndex] * 1024;
while (testSize)
{
if (msdCommandInstance->deviceState != kStatus_DEV_Attached)
{
msd_command_test_done(msdCommandInstance);
return;
}
ufiIng = 1;
DWT->CYCCNT = 0;
DWT->CTRL |= (1 << DWT_CTRL_CYCCNTENA_Pos);
status =
USB_HostMsdWrite10(msdCommandInstance->classHandle, 0, blockAddress,
(uint8_t *)&testThroughputBuffer[0], THROUGHPUT_BUFFER_SIZE,
(THROUGHPUT_BUFFER_SIZE / blockSize), USB_HostMsdUfiCallback, msdCommandInstance);
if (status != kStatus_USB_Success)
{
usb_echo(" error\r\n");
msd_command_test_done(msdCommandInstance);
return;
}
while (ufiIng) /* wait the command */
{
USB_HostControllerTaskFunction(g_HostHandle);
}
totalTime += DWT->CYCCNT;
DWT->CTRL &= ~(1U << DWT_CTRL_CYCCNTENA_Pos);
if (ufiStatus != kStatus_USB_Success)
{
usb_echo("fail\r\n");
msd_command_test_done(msdCommandInstance);
return;
}
testSize -= THROUGHPUT_BUFFER_SIZE;
blockAddress += (THROUGHPUT_BUFFER_SIZE / blockSize);
}
testSize = testSizeArray[testIndex];
usb_echo(" write %dKB data the speed is %d KB/s\r\n", testSize,
(uint32_t)((uint64_t)testSize * (uint64_t)MCU_CORE_CLOCK / (uint64_t)totalTime));
totalTime = 0;
blockAddress = 0;
testSize = testSizeArray[testIndex] * 1024;
while (testSize)
{
if (msdCommandInstance->deviceState != kStatus_DEV_Attached)
{
msd_command_test_done(msdCommandInstance);
return;
}
ufiIng = 1;
DWT->CYCCNT = 0;
DWT->CTRL |= (1 << DWT_CTRL_CYCCNTENA_Pos);
status =
USB_HostMsdRead10(msdCommandInstance->classHandle, 0, blockAddress, (uint8_t *)&testThroughputBuffer[0],
THROUGHPUT_BUFFER_SIZE, (THROUGHPUT_BUFFER_SIZE / blockSize), USB_HostMsdUfiCallback,
msdCommandInstance);
if (status != kStatus_USB_Success)
{
usb_echo(" error\r\n");
msd_command_test_done(msdCommandInstance);
return;
}
while (ufiIng) /* wait the command */
{
USB_HostControllerTaskFunction(g_HostHandle);
}
totalTime += DWT->CYCCNT;
DWT->CTRL &= ~(1U << DWT_CTRL_CYCCNTENA_Pos);
if (ufiStatus != kStatus_USB_Success)
{
usb_echo("fail\r\n");
msd_command_test_done(msdCommandInstance);
return;
}
testSize -= THROUGHPUT_BUFFER_SIZE;
blockAddress += (THROUGHPUT_BUFFER_SIZE / blockSize);
}
testSize = testSizeArray[testIndex];
usb_echo(" read %dKB data the speed is %d KB/s\r\n", testSize,
(uint32_t)((uint64_t)testSize * (uint64_t)MCU_CORE_CLOCK / (uint64_t)totalTime));
}
#endif /* MSD_THROUGHPUT_TEST_ENABLE */
UsbMountFileSystem();
msd_command_test_done(msdCommandInstance); /* all test are done */
}
usb_status_t USB_HostMsdReadApi(usb_host_msd_command_instance_t *msdCommandInstance, uint8_t *buffer, uint32_t pos, uint32_t block_size, uint32_t block_num)
{
usb_status_t status, ret = kStatus_USB_Error;
uint32_t retry = 2;
if (msdCommandInstance->deviceState == kStatus_DEV_Attached) {
ufiIng = 1;
while (retry--) {
status = USB_HostMsdRead10(msdCommandInstance->classHandle, 0, pos, buffer, (uint32_t)(block_size * block_num), block_num, USB_HostMsdUfiCallback, msdCommandInstance);
if (status != kStatus_USB_Success) {
usb_echo("UsbHostRead error\r\n");
ret = kStatus_USB_Error;
} else {
while (ufiIng) {
USB_HostControllerTaskFunction(g_HostHandle);
}
if (ufiStatus == kStatus_USB_Success) {
ret = kStatus_USB_Success;
break;
} else {
ret = kStatus_USB_Error;
}
}
}
}
return ret;
}
usb_status_t USB_HostMsdWriteApi(usb_host_msd_command_instance_t *msdCommandInstance, const uint8_t *buffer, uint32_t pos, uint32_t block_size, uint32_t block_num)
{
usb_status_t fatfs_code = kStatus_USB_Error;
usb_status_t status = kStatus_USB_Success;
uint32_t retry = 2;
const uint8_t *transferBuf;
uint32_t sectorCount;
uint32_t sectorIndex;
if (!block_num)
{
return kStatus_USB_Error;
}
transferBuf = buffer;
sectorCount = block_num;
sectorIndex = pos;
while (retry--)
{
ufiIng = 1;
if (msdCommandInstance == NULL)
{
return kStatus_USB_Error;
}
status = USB_HostMsdWrite10(msdCommandInstance->classHandle, 0, sectorIndex, (uint8_t *)transferBuf,
(uint32_t)(block_size * sectorCount), sectorCount, USB_HostMsdUfiCallback, NULL);
if (status != kStatus_USB_Success)
{
fatfs_code = kStatus_USB_Error;
}
else
{
while (ufiIng)
{
USB_HostControllerTaskFunction(g_HostHandle);
}
if (ufiStatus == kStatus_USB_Success)
{
fatfs_code = kStatus_USB_Success;
break;
}
else
{
fatfs_code = kStatus_USB_Busy;
}
}
}
return fatfs_code;
}
void USB_HostMsdTask(void *arg)
{
usb_status_t status;
usb_host_msd_command_instance_t *msdCommandInstance = (usb_host_msd_command_instance_t *)arg;
if (msdCommandInstance->deviceState != msdCommandInstance->prevDeviceState)
{
msdCommandInstance->prevDeviceState = msdCommandInstance->deviceState;
switch (msdCommandInstance->deviceState)
{
case kStatus_DEV_Idle:
break;
case kStatus_DEV_Attached: /* deivce is attached and numeration is done */
status = USB_HostMsdInit(msdCommandInstance->deviceHandle,
&msdCommandInstance->classHandle); /* msd class initialization */
if (status != kStatus_USB_Success)
{
usb_echo("usb host msd init fail\r\n");
return;
}
msdCommandInstance->runState = kUSB_HostMsdRunSetInterface;
break;
case kStatus_DEV_Detached: /* device is detached */
UsbUnmountFileSystem();
msdCommandInstance->deviceState = kStatus_DEV_Idle;
msdCommandInstance->runState = kUSB_HostMsdRunIdle;
USB_HostMsdDeinit(msdCommandInstance->deviceHandle,
msdCommandInstance->classHandle); /* msd class de-initialization */
msdCommandInstance->classHandle = NULL;
usb_echo("mass storage device detached\r\n");
break;
default:
break;
}
}
/* run state */
switch (msdCommandInstance->runState)
{
case kUSB_HostMsdRunIdle:
break;
case kUSB_HostMsdRunSetInterface: /* set msd interface */
msdCommandInstance->runState = kUSB_HostMsdRunIdle;
msdCommandInstance->runWaitState = kUSB_HostMsdRunWaitSetInterface;
status = USB_HostMsdSetInterface(msdCommandInstance->classHandle, msdCommandInstance->interfaceHandle, 0,
USB_HostMsdControlCallback, msdCommandInstance);
if (status != kStatus_USB_Success)
{
usb_echo("set interface fail\r\n");
}
break;
case kUSB_HostMsdRunMassStorageTest: /* set interface succeed */
USB_HostMsdCommandTest(msdCommandInstance); /* test msd device */
msdCommandInstance->runState = kUSB_HostMsdRunIdle;
break;
default:
break;
}
}
usb_status_t USB_HostMsdEvent(usb_device_handle deviceHandle,
usb_host_configuration_handle configurationHandle,
uint32_t eventCode)
{
usb_status_t status = kStatus_USB_Success;
uint8_t id;
usb_host_configuration_t *configuration;
uint8_t interfaceIndex;
usb_host_interface_t *interface;
uint32_t infoValue;
switch (eventCode)
{
case kUSB_HostEventAttach:
/* judge whether is configurationHandle supported */
configuration = (usb_host_configuration_t *)configurationHandle;
for (interfaceIndex = 0; interfaceIndex < configuration->interfaceCount; ++interfaceIndex)
{
interface = &configuration->interfaceList[interfaceIndex];
id = interface->interfaceDesc->bInterfaceClass;
if (id != USB_HOST_MSD_CLASS_CODE)
{
continue;
}
id = interface->interfaceDesc->bInterfaceSubClass;
if ((id != USB_HOST_MSD_SUBCLASS_CODE_UFI) && (id != USB_HOST_MSD_SUBCLASS_CODE_SCSI))
{
continue;
}
id = interface->interfaceDesc->bInterfaceProtocol;
if (id != USB_HOST_MSD_PROTOCOL_BULK)
{
continue;
}
else
{
if (g_MsdCommandInstance.deviceState == kStatus_DEV_Idle)
{
/* the interface is supported by the application */
g_MsdCommandInstance.testUfiBuffer = s_TestUfiBuffer;
g_MsdCommandInstance.deviceHandle = deviceHandle;
g_MsdCommandInstance.interfaceHandle = interface;
g_MsdCommandInstance.configHandle = configurationHandle;
return kStatus_USB_Success;
}
else
{
continue;
}
}
}
status = kStatus_USB_NotSupported;
break;
case kUSB_HostEventNotSupported:
break;
case kUSB_HostEventEnumerationDone:
if (g_MsdCommandInstance.configHandle == configurationHandle)
{
if ((g_MsdCommandInstance.deviceHandle != NULL) && (g_MsdCommandInstance.interfaceHandle != NULL))
{
/* the device enumeration is done */
if (g_MsdCommandInstance.deviceState == kStatus_DEV_Idle)
{
g_MsdCommandInstance.deviceState = kStatus_DEV_Attached;
USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDevicePID, &infoValue);
usb_echo("mass storage device attached:pid=0x%x", infoValue);
USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceVID, &infoValue);
usb_echo("vid=0x%x ", infoValue);
USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceAddress, &infoValue);
usb_echo("address=%d\r\n", infoValue);
}
else
{
usb_echo("not idle msd instance\r\n");
status = kStatus_USB_Error;
}
}
}
break;
case kUSB_HostEventDetach:
if (g_MsdCommandInstance.configHandle == configurationHandle)
{
/* the device is detached */
g_MsdCommandInstance.configHandle = NULL;
if (g_MsdCommandInstance.deviceState != kStatus_DEV_Idle)
{
g_MsdCommandInstance.deviceState = kStatus_DEV_Detached;
}
}
break;
default:
break;
}
return status;
}

View File

@ -0,0 +1,83 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016, 2018 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _HOST_MSD_COMMAND_H_
#define _HOST_MSD_COMMAND_H_
#include "usb_host.h"
#include "usb_host_msd.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief 1 - execute throughput test; 0 - don't execute throughput test */
#define MSD_THROUGHPUT_TEST_ENABLE (0U)
/*! @brief host app device attach/detach status */
typedef enum _usb_host_app_state
{
kStatus_DEV_Idle = 0, /*!< there is no device attach/detach */
kStatus_DEV_Attached, /*!< device is attached */
kStatus_DEV_Detached, /*!< device is detached */
} usb_host_app_state_t;
/*! @brief host app run status */
typedef enum _usb_host_msd_run_state
{
kUSB_HostMsdRunIdle = 0, /*!< idle */
kUSB_HostMsdRunSetInterface, /*!< execute set interface code */
kUSB_HostMsdRunWaitSetInterface, /*!< wait set interface done */
kUSB_HostMsdRunMassStorageTest /*!< execute mass storage test code */
} usb_host_msd_run_state_t;
/*! @brief USB host msd command instance structure */
typedef struct _usb_host_msd_command_instance
{
usb_host_configuration_handle configHandle; /*!< configuration handle */
usb_device_handle deviceHandle; /*!< device handle */
usb_host_class_handle classHandle; /*!< class handle */
usb_host_interface_handle interfaceHandle; /*!< interface handle */
uint8_t *testUfiBuffer; /*!< test buffer */
uint8_t prevDeviceState; /*!< device attach/detach previous status */
uint8_t deviceState; /*!< device attach/detach status */
uint8_t runWaitState; /*!< application wait status, go to next run status when the wait status success */
uint8_t runState; /*!< application run status */
} usb_host_msd_command_instance_t;
/*******************************************************************************
* API
******************************************************************************/
/*!
* @brief host msd callback function.
*
* This function should be called in the host callback function.
*
* @param deviceHandle device handle.
* @param configurationHandle attached device's configuration descriptor information.
* @param eventCode callback event code, please reference to enumeration host_event_t.
*
* @retval kStatus_USB_Success The host is initialized successfully.
* @retval kStatus_USB_NotSupported The configuration don't contain msd interface.
* @retval kStatus_USB_Error There is no idle msd instance.
*/
extern usb_status_t USB_HostMsdEvent(usb_device_handle deviceHandle,
usb_host_configuration_handle configurationHandle,
uint32_t eventCode);
/*!
* @brief host msd command task function.
*
* This function implements the host msd command action, it is used to create task.
*
* @param arg the host msd command instance pointer.
*/
extern void USB_HostMsdTask(void *arg);
#endif /* _HOST_MSD_COMMAND_H_ */

View File

@ -0,0 +1,136 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_H__
#define __USB_H__
#include <stdint.h>
#include <stdio.h>
#include "fsl_common.h"
#include "usb_osa.h"
#include "usb_misc.h"
#include "usb_spec.h"
/*!
* @addtogroup usb_drv
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Defines USB stack major version */
#define USB_STACK_VERSION_MAJOR (2U)
/*! @brief Defines USB stack minor version */
#define USB_STACK_VERSION_MINOR (2U)
/*! @brief Defines USB stack bugfix version */
#define USB_STACK_VERSION_BUGFIX (0U)
/*! @brief USB stack version definition */
#define USB_MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))
#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))
/*! @brief USB stack component version definition, changed with component in yaml together */
#define USB_STACK_COMPONENT_VERSION MAKE_VERSION(2, 2, 0)
/*
* Component ID used by tools
*
* FSL_COMPONENT_ID "middleware.usb.stack_common"
*/
/*! @brief USB error code */
typedef enum _usb_status
{
kStatus_USB_Success = 0x00U, /*!< Success */
kStatus_USB_Error, /*!< Failed */
kStatus_USB_Busy, /*!< Busy */
kStatus_USB_InvalidHandle, /*!< Invalid handle */
kStatus_USB_InvalidParameter, /*!< Invalid parameter */
kStatus_USB_InvalidRequest, /*!< Invalid request */
kStatus_USB_ControllerNotFound, /*!< Controller cannot be found */
kStatus_USB_InvalidControllerInterface, /*!< Invalid controller interface */
kStatus_USB_NotSupported, /*!< Configuration is not supported */
kStatus_USB_Retry, /*!< Enumeration get configuration retry */
kStatus_USB_TransferStall, /*!< Transfer stalled */
kStatus_USB_TransferFailed, /*!< Transfer failed */
kStatus_USB_AllocFail, /*!< Allocation failed */
kStatus_USB_LackSwapBuffer, /*!< Insufficient swap buffer for KHCI */
kStatus_USB_TransferCancel, /*!< The transfer cancelled */
kStatus_USB_BandwidthFail, /*!< Allocate bandwidth failed */
kStatus_USB_MSDStatusFail, /*!< For MSD, the CSW status means fail */
kStatus_USB_EHCIAttached,
kStatus_USB_EHCIDetached,
} usb_status_t;
/*! @brief USB host handle type define */
typedef void *usb_host_handle;
/*! @brief USB device handle type define. For device stack it is the whole device handle; for host stack it is the
* attached device instance handle*/
typedef void *usb_device_handle;
/*! @brief USB OTG handle type define */
typedef void *usb_otg_handle;
/*! @brief USB controller ID */
typedef enum _usb_controller_index
{
kUSB_ControllerKhci0 = 0U, /*!< KHCI 0U */
kUSB_ControllerKhci1 = 1U, /*!< KHCI 1U, Currently, there are no platforms which have two KHCI IPs, this is reserved
to be used in the future. */
kUSB_ControllerEhci0 = 2U, /*!< EHCI 0U */
kUSB_ControllerEhci1 = 3U, /*!< EHCI 1U, Currently, there are no platforms which have two EHCI IPs, this is reserved
to be used in the future. */
kUSB_ControllerLpcIp3511Fs0 = 4U, /*!< LPC USB IP3511 FS controller 0 */
kUSB_ControllerLpcIp3511Fs1 =
5U, /*!< LPC USB IP3511 FS controller 1, there are no platforms which have two IP3511 IPs, this is reserved
to be used in the future. */
kUSB_ControllerLpcIp3511Hs0 = 6U, /*!< LPC USB IP3511 HS controller 0 */
kUSB_ControllerLpcIp3511Hs1 =
7U, /*!< LPC USB IP3511 HS controller 1, there are no platforms which have two IP3511 IPs, this is reserved
to be used in the future. */
kUSB_ControllerOhci0 = 8U, /*!< OHCI 0U */
kUSB_ControllerOhci1 = 9U, /*!< OHCI 1U, Currently, there are no platforms which have two OHCI IPs, this is reserved
to be used in the future. */
kUSB_ControllerIp3516Hs0 = 10U, /*!< IP3516HS 0U */
kUSB_ControllerIp3516Hs1 =
11U, /*!< IP3516HS 1U, Currently, there are no platforms which have two IP3516HS IPs, this is reserved
to be used in the future. */
kUSB_ControllerDwc30 = 12U, /*!< DWC3 0U */
kUSB_ControllerDwc31 =
13U, /*!< DWC3 1U Currently, there are no platforms which have two Dwc IPs, this is reserved
to be used in the future.*/
} usb_controller_index_t;
/**
* @brief USB stack version fields
*/
typedef struct _usb_version
{
uint8_t major; /*!< Major */
uint8_t minor; /*!< Minor */
uint8_t bugfix; /*!< Bug fix */
} usb_version_t;
/*******************************************************************************
* API
******************************************************************************/
/*! @} */
#endif /* __USB_H__ */

View File

@ -0,0 +1,240 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _USB_HOST_CONFIG_H_
#define _USB_HOST_CONFIG_H_
/* Host Controller Enable */
/*!
* @brief host khci instance count, meantime it indicates khci enable or disable.
* - if 0, host khci driver is disable.
* - if greater than 0, host khci driver is enable.
*/
#define USB_HOST_CONFIG_KHCI (0U)
/*!
* @brief host ehci instance count, meantime it indicates ehci enable or disable.
* - if 0, host ehci driver is disable.
* - if greater than 0, host ehci driver is enable.
*/
#define USB_HOST_CONFIG_EHCI (2U)
/*!
* @brief host ohci instance count, meantime it indicates ohci enable or disable.
* - if 0, host ohci driver is disable.
* - if greater than 0, host ohci driver is enable.
*/
#define USB_HOST_CONFIG_OHCI (0U)
/*!
* @brief host ip3516hs instance count, meantime it indicates ohci enable or disable.
* - if 0, host ip3516hs driver is disable.
* - if greater than 0, host ip3516hs driver is enable.
*/
#define USB_HOST_CONFIG_IP3516HS (0U)
/* Common configuration macros for all controllers */
/*!
* @brief host driver instance max count.
* for example: 2 - one for khci, one for ehci.
*/
#define USB_HOST_CONFIG_MAX_HOST \
(USB_HOST_CONFIG_KHCI + USB_HOST_CONFIG_EHCI + USB_HOST_CONFIG_OHCI + USB_HOST_CONFIG_IP3516HS)
/*!
* @brief host pipe max count.
* pipe is the host driver resource for device endpoint, one endpoint need one pipe.
*/
#define USB_HOST_CONFIG_MAX_PIPES (16U)
/*!
* @brief host transfer max count.
* transfer is the host driver resource for data transmission mission, one transmission mission need one transfer.
*/
#define USB_HOST_CONFIG_MAX_TRANSFERS (16U)
/*!
* @brief the max endpoint for one interface.
* the max endpoint descriptor number that one interface descriptor contain.
*/
#define USB_HOST_CONFIG_INTERFACE_MAX_EP (4U)
/*!
* @brief the max interface for one configuration.
* the max interface descriptor number that one configuration descriptor can contain.
*/
#define USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE (5U)
/*!
* @brief the max power for one device.
* the max power the host can provide for one device.
*/
#define USB_HOST_CONFIG_MAX_POWER (250U)
/*!
* @brief the max retries for enumeration.
* retry time when enumeration fail.
*/
#define USB_HOST_CONFIG_ENUMERATION_MAX_RETRIES (3U)
/*!
* @brief the max retries for enumeration setup stall.
* the max times for one transfer can stall.
*/
#define USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES (1U)
/*!
* @brief the max NAK count for one transaction.
* when nak count reach to the value, the transaction fail.
*/
#define USB_HOST_CONFIG_MAX_NAK (3000U)
/*! @brief Whether the transfer buffer is cache-enabled or not. */
#ifndef USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE
#define USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE (0U)
#endif
/*! @brief if 1, enable usb compliance test codes; if 0, disable usb compliance test codes. */
#define USB_HOST_CONFIG_COMPLIANCE_TEST (0U)
/*! @brief if 1, class driver clear stall automatically; if 0, class driver don't clear stall. */
#define USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL (0U)
/* KHCI configuration */
#if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
/*!
* @brief khci dma align fix buffer size.
*/
#define USB_HOST_CONFIG_KHCI_DMA_ALIGN_BUFFER (64U)
#endif
/* EHCI configuration */
#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
/*!
* @brief ehci periodic frame list size.
* the value can be 1024, 512, 256, 128, 64, 32, 16 or 8.
*/
#define USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE (1024U)
/*!
* @brief ehci QH max count.
*/
#define USB_HOST_CONFIG_EHCI_MAX_QH (8U)
/*!
* @brief ehci QTD max count.
*/
#define USB_HOST_CONFIG_EHCI_MAX_QTD (8U)
/*!
* @brief ehci ITD max count.
*/
#define USB_HOST_CONFIG_EHCI_MAX_ITD (0U)
/*!
* @brief ehci SITD max count.
*/
#define USB_HOST_CONFIG_EHCI_MAX_SITD (0U)
#endif
/* OHCI configuration */
#if ((defined USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI))
/*!
* @brief ohci ED max count.
*/
#define USB_HOST_CONFIG_OHCI_MAX_ED (16U)
/*!
* @brief ohci GTD max count.
*/
#define USB_HOST_CONFIG_OHCI_MAX_GTD (16U)
/*!
* @brief ohci ITD max count.
*/
#define USB_HOST_CONFIG_OHCI_MAX_ITD (8U)
#endif
/* OHCI configuration */
#if ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS))
#define USB_HOST_CONFIG_IP3516HS_MAX_PIPE (32U)
/*!
* @brief ohci ED max count.
*/
#define USB_HOST_CONFIG_IP3516HS_MAX_ATL (32U)
/*!
* @brief ohci GTD max count.
*/
#define USB_HOST_CONFIG_IP3516HS_MAX_INT (32U)
/*!
* @brief ohci ITD max count.
*/
#define USB_HOST_CONFIG_IP3516HS_MAX_ISO (0U)
#endif
/*!
* @brief host HUB class instance count, meantime it indicates HUB class enable or disable.
* - if 0, host HUB class driver is disable.
* - if greater than 0, host HUB class driver is enable.
*/
#define USB_HOST_CONFIG_HUB (1U)
/*!
* @brief host HID class instance count, meantime it indicates HID class enable or disable.
* - if 0, host HID class driver is disable.
* - if greater than 0, host HID class driver is enable.
*/
#define USB_HOST_CONFIG_HID (1U)
/*!
* @brief host MSD class instance count, meantime it indicates MSD class enable or disable.
* - if 0, host MSD class driver is disable.
* - if greater than 0, host MSD class driver is enable.
*/
#define USB_HOST_CONFIG_MSD (1U)
/*!
* @brief host CDC class instance count, meantime it indicates CDC class enable or disable.
* - if 0, host CDC class driver is disable.
* - if greater than 0, host CDC class driver is enable.
*/
#define USB_HOST_CONFIG_CDC (1U)
/*!
* @brief host AUDIO class instance count, meantime it indicates AUDIO class enable or disable.
* - if 0, host AUDIO class driver is disable.
* - if greater than 0, host AUDIO class driver is enable.
*/
#define USB_HOST_CONFIG_AUDIO (1U)
/*!
* @brief host PHDC class instance count, meantime it indicates PHDC class enable or disable.
* - if 0, host PHDC class driver is disable.
* - if greater than 0, host PHDC class driver is enable.
*/
#define USB_HOST_CONFIG_PHDC (1U)
/*!
* @brief host printer class instance count, meantime it indicates printer class enable or disable.
* - if 0, host printer class driver is disable.
* - if greater than 0, host printer class driver is enable.
*/
#define USB_HOST_CONFIG_PRINTER (1U)
#endif /* _USB_HOST_CONFIG_H_ */

View File

@ -0,0 +1,452 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016, 2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file usb_misc.h
* @brief modify usb_echo to KPrintf
* @version 2.0
* @author AIIT XUOS Lab
* @date 2022-02-10
*/
/*************************************************
File name: usb_misc.h
Description: modify usb_echo to KPrintf
Others: take SDK_2.6.1_MIMXRT1052xxxxB/middleware/usb/include/usb_misc.h for references
History:
1. Date: 2022-02-10
Author: AIIT XUOS Lab
Modification:
1. add xiuos.h
2. modify usb_echo to KPrintf
*************************************************/
#ifndef __USB_MISC_H__
#define __USB_MISC_H__
#include <xiuos.h>
#ifndef ENDIANNESS
#error ENDIANNESS should be defined, and then rebulid the project.
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Define USB printf */
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
extern int DbgConsole_Printf(const char *fmt_s, ...);
#if defined(__cplusplus)
}
#endif /* __cplusplus */
#if defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE < 1)
#define usb_echo printf
#else
#define usb_echo KPrintf
#endif
#if defined(__ICCARM__)
#ifndef STRUCT_PACKED
#define STRUCT_PACKED __packed
#endif
#ifndef STRUCT_UNPACKED
#define STRUCT_UNPACKED
#endif
#elif defined(__GNUC__)
#ifndef STRUCT_PACKED
#define STRUCT_PACKED
#endif
#ifndef STRUCT_UNPACKED
#define STRUCT_UNPACKED __attribute__((__packed__))
#endif
#elif defined(__CC_ARM) || (defined(__ARMCC_VERSION))
#ifndef STRUCT_PACKED
#define STRUCT_PACKED _Pragma("pack(1U)")
#endif
#ifndef STRUCT_UNPACKED
#define STRUCT_UNPACKED _Pragma("pack()")
#endif
#endif
#define USB_SHORT_GET_LOW(x) (((uint16_t)x) & 0xFFU)
#define USB_SHORT_GET_HIGH(x) ((uint8_t)(((uint16_t)x) >> 8U) & 0xFFU)
#define USB_LONG_GET_BYTE0(x) ((uint8_t)(((uint32_t)(x))) & 0xFFU)
#define USB_LONG_GET_BYTE1(x) ((uint8_t)(((uint32_t)(x)) >> 8U) & 0xFFU)
#define USB_LONG_GET_BYTE2(x) ((uint8_t)(((uint32_t)(x)) >> 16U) & 0xFFU)
#define USB_LONG_GET_BYTE3(x) ((uint8_t)(((uint32_t)(x)) >> 24U) & 0xFFU)
#define USB_MEM4_ALIGN_MASK (0x03U)
/* accessory macro */
#define USB_MEM4_ALIGN(n) ((n + 3U) & (0xFFFFFFFCu))
#define USB_MEM32_ALIGN(n) ((n + 31U) & (0xFFFFFFE0u))
#define USB_MEM64_ALIGN(n) ((n + 63U) & (0xFFFFFFC0u))
/* big/little endian */
#define SWAP2BYTE_CONST(n) ((((n)&0x00FFU) << 8U) | (((n)&0xFF00U) >> 8U))
#define SWAP4BYTE_CONST(n) \
((((n)&0x000000FFU) << 24U) | (((n)&0x0000FF00U) << 8U) | (((n)&0x00FF0000U) >> 8U) | (((n)&0xFF000000U) >> 24U))
#define USB_ASSIGN_VALUE_ADDRESS_LONG_BY_BYTE(n, m) \
{ \
*((uint8_t *)&(n)) = *((uint8_t *)&(m)); \
*((uint8_t *)&(n) + 1) = *((uint8_t *)&(m) + 1); \
*((uint8_t *)&(n) + 2) = *((uint8_t *)&(m) + 2); \
*((uint8_t *)&(n) + 3) = *((uint8_t *)&(m) + 3); \
}
#define USB_ASSIGN_VALUE_ADDRESS_SHORT_BY_BYTE(n, m) \
{ \
*((uint8_t *)&(n)) = *((uint8_t *)&(m)); \
*((uint8_t *)&(n) + 1) = *((uint8_t *)&(m) + 1); \
}
#define USB_ASSIGN_MACRO_VALUE_ADDRESS_LONG_BY_BYTE(n, m) \
{ \
*((uint8_t *)&(n)) = (uint8_t)m; \
*((uint8_t *)&(n) + 1) = (uint8_t)(m >> 8); \
*((uint8_t *)&(n) + 2) = (uint8_t)(m >> 16); \
*((uint8_t *)&(n) + 3) = (uint8_t)(m >> 24); \
}
#define USB_ASSIGN_MACRO_VALUE_ADDRESS_SHORT_BY_BYTE(n, m) \
{ \
*((uint8_t *)&(n)) = (uint8_t)m; \
*((uint8_t *)&(n) + 1) = (uint8_t)(m >> 8); \
}
#if (ENDIANNESS == USB_BIG_ENDIAN)
#define USB_SHORT_TO_LITTLE_ENDIAN(n) SWAP2BYTE_CONST(n)
#define USB_LONG_TO_LITTLE_ENDIAN(n) SWAP4BYTE_CONST(n)
#define USB_SHORT_FROM_LITTLE_ENDIAN(n) SWAP2BYTE_CONST(n)
#define USB_LONG_FROM_LITTLE_ENDIAN(n) SWAP2BYTE_CONST(n)
#define USB_SHORT_TO_BIG_ENDIAN(n) (n)
#define USB_LONG_TO_BIG_ENDIAN(n) (n)
#define USB_SHORT_FROM_BIG_ENDIAN(n) (n)
#define USB_LONG_FROM_BIG_ENDIAN(n) (n)
#define USB_LONG_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
{ \
m[3] = ((((uint32_t)(n)) >> 24U) & 0xFFU); \
m[2] = ((((uint32_t)(n)) >> 16U) & 0xFFU); \
m[1] = ((((uint32_t)(n)) >> 8U) & 0xFFU); \
m[0] = (((uint32_t)(n)) & 0xFFU); \
}
#define USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(n) \
((uint32_t)((((uint8_t)n[3]) << 24U) | (((uint8_t)n[2]) << 16U) | (((uint8_t)n[1]) << 8U) | \
(((uint8_t)n[0]) << 0U)))
#define USB_LONG_TO_BIG_ENDIAN_ADDRESS(n, m) \
{ \
m[0] = ((((uint32_t)(n)) >> 24U) & 0xFFU); \
m[1] = ((((uint32_t)(n)) >> 16U) & 0xFFU); \
m[2] = ((((uint32_t)(n)) >> 8U) & 0xFFU); \
m[3] = (((uint32_t)(n)) & 0xFFU); \
}
#define USB_LONG_FROM_BIG_ENDIAN_ADDRESS(n) \
((uint32_t)((((uint8_t)n[0]) << 24U) | (((uint8_t)n[1]) << 16U) | (((uint8_t)n[2]) << 8U) | \
(((uint8_t)n[3]) << 0U)))
#define USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
{ \
m[1] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \
m[0] = (((uint16_t)(n)) & 0xFFU); \
}
#define USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[1]) << 8U) | (((uint8_t)n[0]) << 0U)))
#define USB_SHORT_TO_BIG_ENDIAN_ADDRESS(n, m) \
{ \
m[0] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \
m[1] = (((uint16_t)(n)) & 0xFFU); \
}
#define USB_SHORT_FROM_BIG_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[0]) << 8U) | (((uint8_t)n[1]) << 0U)))
#define USB_LONG_TO_LITTLE_ENDIAN_DATA(n, m) \
{ \
*((uint8_t *)&(m) + 3) = ((((uint32_t)(n)) >> 24U) & 0xFFU); \
*((uint8_t *)&(m) + 2) = ((((uint32_t)(n)) >> 16U) & 0xFFU); \
*((uint8_t *)&(m) + 1) = ((((uint32_t)(n)) >> 8U) & 0xFFU); \
*((uint8_t *)&(m) + 0) = (((uint32_t)(n)) & 0xFFU); \
}
#define USB_LONG_FROM_LITTLE_ENDIAN_DATA(n) \
((uint32_t)(((*((uint8_t *)&(n) + 3)) << 24U) | ((*((uint8_t *)&(n) + 2)) << 16U) | \
((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n))) << 0U)))
#define USB_SHORT_TO_LITTLE_ENDIAN_DATA(n, m) \
{ \
*((uint8_t *)&(m) + 1) = ((((uint16_t)(n)) >> 8U) & 0xFFU); \
*((uint8_t *)&(m)) = ((((uint16_t)(n))) & 0xFFU); \
}
#define USB_SHORT_FROM_LITTLE_ENDIAN_DATA(n) ((uint32_t)(((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n))))))
#else
#define USB_SHORT_TO_LITTLE_ENDIAN(n) (n)
#define USB_LONG_TO_LITTLE_ENDIAN(n) (n)
#define USB_SHORT_FROM_LITTLE_ENDIAN(n) (n)
#define USB_LONG_FROM_LITTLE_ENDIAN(n) (n)
#define USB_SHORT_TO_BIG_ENDIAN(n) SWAP2BYTE_CONST(n)
#define USB_LONG_TO_BIG_ENDIAN(n) SWAP4BYTE_CONST(n)
#define USB_SHORT_FROM_BIG_ENDIAN(n) SWAP2BYTE_CONST(n)
#define USB_LONG_FROM_BIG_ENDIAN(n) SWAP4BYTE_CONST(n)
#define USB_LONG_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
{ \
m[3] = ((((uint32_t)(n)) >> 24U) & 0xFFU); \
m[2] = ((((uint32_t)(n)) >> 16U) & 0xFFU); \
m[1] = ((((uint32_t)(n)) >> 8U) & 0xFFU); \
m[0] = (((uint32_t)(n)) & 0xFFU); \
}
#define USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(n) \
((uint32_t)((((uint8_t)n[3]) << 24U) | (((uint8_t)n[2]) << 16U) | (((uint8_t)n[1]) << 8U) | \
(((uint8_t)n[0]) << 0U)))
#define USB_LONG_TO_BIG_ENDIAN_ADDRESS(n, m) \
{ \
m[0] = ((((uint32_t)(n)) >> 24U) & 0xFFU); \
m[1] = ((((uint32_t)(n)) >> 16U) & 0xFFU); \
m[2] = ((((uint32_t)(n)) >> 8U) & 0xFFU); \
m[3] = (((uint32_t)(n)) & 0xFFU); \
}
#define USB_LONG_FROM_BIG_ENDIAN_ADDRESS(n) \
((uint32_t)((((uint8_t)n[0]) << 24U) | (((uint8_t)n[1]) << 16U) | (((uint8_t)n[2]) << 8U) | \
(((uint8_t)n[3]) << 0U)))
#define USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
{ \
m[1] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \
m[0] = (((uint16_t)(n)) & 0xFFU); \
}
#define USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[1]) << 8U) | (((uint8_t)n[0]) << 0U)))
#define USB_SHORT_TO_BIG_ENDIAN_ADDRESS(n, m) \
{ \
m[0] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \
m[1] = (((uint16_t)(n)) & 0xFFU); \
}
#define USB_SHORT_FROM_BIG_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[0]) << 8U) | (((uint8_t)n[1]) << 0U)))
#define USB_LONG_TO_LITTLE_ENDIAN_DATA(n, m) \
{ \
*((uint8_t *)&(m) + 3) = ((((uint32_t)(n)) >> 24U) & 0xFFU); \
*((uint8_t *)&(m) + 2) = ((((uint32_t)(n)) >> 16U) & 0xFFU); \
*((uint8_t *)&(m) + 1) = ((((uint32_t)(n)) >> 8U) & 0xFFU); \
*((uint8_t *)&(m) + 0) = (((uint32_t)(n)) & 0xFFU); \
}
#define USB_LONG_FROM_LITTLE_ENDIAN_DATA(n) \
((uint32_t)(((*((uint8_t *)&(n) + 3)) << 24U) | ((*((uint8_t *)&(n) + 2)) << 16U) | \
((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n))) << 0U)))
#define USB_SHORT_TO_LITTLE_ENDIAN_DATA(n, m) \
{ \
*((uint8_t *)&(m) + 1) = ((((uint16_t)(n)) >> 8U) & 0xFFU); \
*((uint8_t *)&(m)) = ((((uint16_t)(n))) & 0xFFU); \
}
#define USB_SHORT_FROM_LITTLE_ENDIAN_DATA(n) ((uint32_t)(((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n))))))
#endif
/*
* The following MACROs (USB_GLOBAL, USB_BDT, USB_RAM_ADDRESS_ALIGNMENT, etc) are only used for USB device stack.
* The USB device global variables are put into the section m_usb_global and m_usb_bdt or the section
* .bss.m_usb_global and .bss.m_usb_bdt by using the MACRO USB_GLOBAL and USB_BDT. In this way, the USB device
* global variables can be linked into USB dedicated RAM by USB_STACK_USE_DEDICATED_RAM.
* The MACRO USB_STACK_USE_DEDICATED_RAM is used to decide the USB stack uses dedicated RAM or not. The value of
* the macro can be set as 0, USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL, or USB_STACK_DEDICATED_RAM_TYPE_BDT.
* The MACRO USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL means USB device global variables, including USB_BDT and
* USB_GLOBAL, are put into the USB dedicated RAM. This feature can only be enabled when the USB dedicated RAM
* is not less than 2K Bytes.
* The MACRO USB_STACK_DEDICATED_RAM_TYPE_BDT means USB device global variables, only including USB_BDT, are put
* into the USB dedicated RAM, the USB_GLOBAL will be put into .bss section. This feature is used for some SOCs,
* the USB dedicated RAM size is not more than 512 Bytes.
*/
#define USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL 1
#define USB_STACK_DEDICATED_RAM_TYPE_BDT 2
#if defined(__ICCARM__)
#define USB_WEAK_VAR __attribute__((weak))
#define USB_WEAK_FUN __attribute__((weak))
/* disable misra 19.13 */
_Pragma("diag_suppress=Pm120")
#define USB_ALIGN_PRAGMA(x) _Pragma(#x)
_Pragma("diag_default=Pm120")
#define USB_RAM_ADDRESS_ALIGNMENT(n) USB_ALIGN_PRAGMA(data_alignment = n)
_Pragma("diag_suppress=Pm120")
#define USB_LINK_SECTION_PART(str) _Pragma(#str)
#define USB_LINK_DMA_INIT_DATA(sec) USB_LINK_SECTION_PART(location = #sec)
#define USB_LINK_USB_GLOBAL _Pragma("location = \"m_usb_global\"")
#define USB_LINK_USB_BDT _Pragma("location = \"m_usb_bdt\"")
#define USB_LINK_USB_GLOBAL_BSS _Pragma("location = \".bss.m_usb_global\"")
#define USB_LINK_USB_BDT_BSS _Pragma("location = \".bss.m_usb_bdt\"")
_Pragma("diag_default=Pm120")
#define USB_LINK_DMA_NONINIT_DATA _Pragma("location = \"m_usb_dma_noninit_data\"")
#define USB_LINK_NONCACHE_NONINIT_DATA _Pragma("location = \"NonCacheable\"")
#elif defined(__CC_ARM) || (defined(__ARMCC_VERSION))
#define USB_WEAK_VAR __attribute__((weak))
#define USB_WEAK_FUN __attribute__((weak))
#define USB_RAM_ADDRESS_ALIGNMENT(n) __attribute__((aligned(n)))
#define USB_LINK_DMA_INIT_DATA(sec) __attribute__((section(#sec)))
#define USB_LINK_USB_GLOBAL __attribute__((section("m_usb_global"))) __attribute__((zero_init))
#define USB_LINK_USB_BDT __attribute__((section("m_usb_bdt"))) __attribute__((zero_init))
#define USB_LINK_USB_GLOBAL_BSS __attribute__((section(".bss.m_usb_global"))) __attribute__((zero_init))
#define USB_LINK_USB_BDT_BSS __attribute__((section(".bss.m_usb_bdt"))) __attribute__((zero_init))
#define USB_LINK_DMA_NONINIT_DATA __attribute__((section("m_usb_dma_noninit_data"))) __attribute__((zero_init))
#define USB_LINK_NONCACHE_NONINIT_DATA __attribute__((section("NonCacheable"))) __attribute__((zero_init))
#elif defined(__GNUC__)
#define USB_WEAK_VAR __attribute__((weak))
#define USB_WEAK_FUN __attribute__((weak))
#define USB_RAM_ADDRESS_ALIGNMENT(n) __attribute__((aligned(n)))
#define USB_LINK_DMA_INIT_DATA(sec) __attribute__((section(#sec)))
#define USB_LINK_USB_GLOBAL __attribute__((section("m_usb_global, \"aw\", %nobits @")))
#define USB_LINK_USB_BDT __attribute__((section("m_usb_bdt, \"aw\", %nobits @")))
#define USB_LINK_USB_GLOBAL_BSS __attribute__((section(".bss.m_usb_global, \"aw\", %nobits @")))
#define USB_LINK_USB_BDT_BSS __attribute__((section(".bss.m_usb_bdt, \"aw\", %nobits @")))
#define USB_LINK_DMA_NONINIT_DATA __attribute__((section("m_usb_dma_noninit_data, \"aw\", %nobits @")))
#define USB_LINK_NONCACHE_NONINIT_DATA __attribute__((section("NonCacheable, \"aw\", %nobits @")))
#else
#error The tool-chain is not supported.
#endif
#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \
(defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
#if ((defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)) && (defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)))
#define USB_CACHE_LINESIZE MAX(FSL_FEATURE_L2CACHE_LINESIZE_BYTE, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#elif (defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE))
#define USB_CACHE_LINESIZE MAX(FSL_FEATURE_L2CACHE_LINESIZE_BYTE, 0)
#elif (defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE))
#define USB_CACHE_LINESIZE MAX(0, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#else
#define USB_CACHE_LINESIZE 4
#endif
#else
#define USB_CACHE_LINESIZE 4
#endif
#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)))
#define USB_DATA_ALIGN 64
#else
#define USB_DATA_ALIGN 4
#endif
#define USB_DATA_ALIGN_SIZE MAX(USB_CACHE_LINESIZE, USB_DATA_ALIGN)
#define USB_DATA_ALIGN_SIZE_MULTIPLE(n) ((n + USB_DATA_ALIGN_SIZE - 1U) & (~(USB_DATA_ALIGN_SIZE - 1U)))
#if defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM == USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL)
#define USB_GLOBAL USB_LINK_USB_GLOBAL
#define USB_BDT USB_LINK_USB_BDT
#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \
(defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
#define USB_DMA_DATA_NONINIT_SUB USB_LINK_DMA_NONINIT_DATA
#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(m_usb_dma_init_data)
#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA
#else
#define USB_DMA_DATA_NONINIT_SUB
#define USB_DMA_DATA_INIT_SUB
#define USB_CONTROLLER_DATA USB_LINK_USB_GLOBAL
#endif
#elif defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM == USB_STACK_DEDICATED_RAM_TYPE_BDT)
#define USB_BDT USB_LINK_USB_BDT
#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \
(defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
#define USB_GLOBAL USB_LINK_DMA_NONINIT_DATA
#define USB_DMA_DATA_NONINIT_SUB USB_LINK_DMA_NONINIT_DATA
#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(m_usb_dma_init_data)
#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA
#else
#define USB_GLOBAL USB_LINK_USB_GLOBAL_BSS
#define USB_DMA_DATA_NONINIT_SUB
#define USB_DMA_DATA_INIT_SUB
#define USB_CONTROLLER_DATA
#endif
#else
#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \
(defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
#define USB_GLOBAL USB_LINK_DMA_NONINIT_DATA
#define USB_BDT USB_LINK_NONCACHE_NONINIT_DATA
#define USB_DMA_DATA_NONINIT_SUB USB_LINK_DMA_NONINIT_DATA
#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(m_usb_dma_init_data)
#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA
#else
#define USB_GLOBAL USB_LINK_USB_GLOBAL_BSS
#define USB_BDT USB_LINK_USB_BDT_BSS
#define USB_DMA_DATA_NONINIT_SUB
#define USB_DMA_DATA_INIT_SUB
#define USB_CONTROLLER_DATA
#endif
#endif
#define USB_DMA_NONINIT_DATA_ALIGN(n) USB_RAM_ADDRESS_ALIGNMENT(n) USB_DMA_DATA_NONINIT_SUB
#define USB_DMA_INIT_DATA_ALIGN(n) USB_RAM_ADDRESS_ALIGNMENT(n) USB_DMA_DATA_INIT_SUB
#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \
(defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
#define USB_DMA_DATA_NONCACHEABLE USB_LINK_NONCACHE_NONINIT_DATA
#else
#define USB_DMA_DATA_NONCACHEABLE
#endif
#define USB_GLOBAL_DEDICATED_RAM USB_LINK_USB_GLOBAL
/* #define USB_RAM_ADDRESS_NONCACHEREG_ALIGNMENT(n, var) AT_NONCACHEABLE_SECTION_ALIGN(var, n) */
/* #define USB_RAM_ADDRESS_NONCACHEREG(var) AT_NONCACHEABLE_SECTION(var) */
#endif /* __USB_MISC_H__ */

View File

@ -0,0 +1,300 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_SPEC_H__
#define __USB_SPEC_H__
/*******************************************************************************
* Definitions
******************************************************************************/
/* USB speed (the value cannot be changed because EHCI QH use the value directly)*/
#define USB_SPEED_FULL (0x00U)
#define USB_SPEED_LOW (0x01U)
#define USB_SPEED_HIGH (0x02U)
#define USB_SPEED_SUPER (0x04U)
/* Set up packet structure */
typedef struct _usb_setup_struct
{
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} usb_setup_struct_t;
/* USB standard descriptor endpoint type */
#define USB_ENDPOINT_CONTROL (0x00U)
#define USB_ENDPOINT_ISOCHRONOUS (0x01U)
#define USB_ENDPOINT_BULK (0x02U)
#define USB_ENDPOINT_INTERRUPT (0x03U)
/* USB standard descriptor transfer direction (cannot change the value because iTD use the value directly) */
#define USB_OUT (0U)
#define USB_IN (1U)
/* USB standard descriptor length */
#define USB_DESCRIPTOR_LENGTH_DEVICE (0x12U)
#define USB_DESCRIPTOR_LENGTH_CONFIGURE (0x09U)
#define USB_DESCRIPTOR_LENGTH_INTERFACE (0x09U)
#define USB_DESCRIPTOR_LENGTH_ENDPOINT (0x07U)
#define USB_DESCRIPTOR_LENGTH_ENDPOINT_COMPANION (0x06U)
#define USB_DESCRIPTOR_LENGTH_DEVICE_QUALITIER (0x0AU)
#define USB_DESCRIPTOR_LENGTH_OTG_DESCRIPTOR (5U)
#define USB_DESCRIPTOR_LENGTH_BOS_DESCRIPTOR (5U)
#define USB_DESCRIPTOR_LENGTH_DEVICE_CAPABILITY_USB20_EXTENSION (0x07U)
#define USB_DESCRIPTOR_LENGTH_DEVICE_CAPABILITY_SUPERSPEED (0x0AU)
/* USB Device Capability Type Codes */
#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY_WIRELESS (0x01U)
#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY_USB20_EXTENSION (0x02U)
#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY_SUPERSPEED (0x03U)
/* USB standard descriptor type */
#define USB_DESCRIPTOR_TYPE_DEVICE (0x01U)
#define USB_DESCRIPTOR_TYPE_CONFIGURE (0x02U)
#define USB_DESCRIPTOR_TYPE_STRING (0x03U)
#define USB_DESCRIPTOR_TYPE_INTERFACE (0x04U)
#define USB_DESCRIPTOR_TYPE_ENDPOINT (0x05U)
#define USB_DESCRIPTOR_TYPE_DEVICE_QUALITIER (0x06U)
#define USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION (0x07U)
#define USB_DESCRIPTOR_TYPE_INTERFAACE_POWER (0x08U)
#define USB_DESCRIPTOR_TYPE_OTG (0x09U)
#define USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION (0x0BU)
#define USB_DESCRIPTOR_TYPE_BOS (0x0F)
#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY (0x10)
#define USB_DESCRIPTOR_TYPE_HID (0x21U)
#define USB_DESCRIPTOR_TYPE_HID_REPORT (0x22U)
#define USB_DESCRIPTOR_TYPE_HID_PHYSICAL (0x23U)
#define USB_DESCRIPTOR_TYPE_ENDPOINT_COMPANION (0x30U)
/* USB standard request type */
#define USB_REQUEST_TYPE_DIR_MASK (0x80U)
#define USB_REQUEST_TYPE_DIR_SHIFT (7U)
#define USB_REQUEST_TYPE_DIR_OUT (0x00U)
#define USB_REQUEST_TYPE_DIR_IN (0x80U)
#define USB_REQUEST_TYPE_TYPE_MASK (0x60U)
#define USB_REQUEST_TYPE_TYPE_SHIFT (5U)
#define USB_REQUEST_TYPE_TYPE_STANDARD (0U)
#define USB_REQUEST_TYPE_TYPE_CLASS (0x20U)
#define USB_REQUEST_TYPE_TYPE_VENDOR (0x40U)
#define USB_REQUEST_TYPE_RECIPIENT_MASK (0x1FU)
#define USB_REQUEST_TYPE_RECIPIENT_SHIFT (0U)
#define USB_REQUEST_TYPE_RECIPIENT_DEVICE (0x00U)
#define USB_REQUEST_TYPE_RECIPIENT_INTERFACE (0x01U)
#define USB_REQUEST_TYPE_RECIPIENT_ENDPOINT (0x02U)
#define USB_REQUEST_TYPE_RECIPIENT_OTHER (0x03U)
/* USB standard request */
#define USB_REQUEST_STANDARD_GET_STATUS (0x00U)
#define USB_REQUEST_STANDARD_CLEAR_FEATURE (0x01U)
#define USB_REQUEST_STANDARD_SET_FEATURE (0x03U)
#define USB_REQUEST_STANDARD_SET_ADDRESS (0x05U)
#define USB_REQUEST_STANDARD_GET_DESCRIPTOR (0x06U)
#define USB_REQUEST_STANDARD_SET_DESCRIPTOR (0x07U)
#define USB_REQUEST_STANDARD_GET_CONFIGURATION (0x08U)
#define USB_REQUEST_STANDARD_SET_CONFIGURATION (0x09U)
#define USB_REQUEST_STANDARD_GET_INTERFACE (0x0AU)
#define USB_REQUEST_STANDARD_SET_INTERFACE (0x0BU)
#define USB_REQUEST_STANDARD_SYNCH_FRAME (0x0CU)
/* USB standard request GET Status */
#define USB_REQUEST_STANDARD_GET_STATUS_DEVICE_SELF_POWERED_SHIFT (0U)
#define USB_REQUEST_STANDARD_GET_STATUS_DEVICE_REMOTE_WARKUP_SHIFT (1U)
#define USB_REQUEST_STANDARD_GET_STATUS_ENDPOINT_HALT_MASK (0x01U)
#define USB_REQUEST_STANDARD_GET_STATUS_ENDPOINT_HALT_SHIFT (0U)
#define USB_REQUEST_STANDARD_GET_STATUS_OTG_STATUS_SELECTOR (0xF000U)
/* USB standard request CLEAR/SET feature */
#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT (0U)
#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_REMOTE_WAKEUP (1U)
#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_TEST_MODE (2U)
#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_B_HNP_ENABLE (3U)
#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_A_HNP_SUPPORT (4U)
#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_A_ALT_HNP_SUPPORT (5U)
/* USB standard descriptor configure bmAttributes */
#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_MASK (0x80U)
#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_SHIFT (7U)
#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_MASK (0x40U)
#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_SHIFT (6U)
#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_MASK (0x20U)
#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_SHIFT (5U)
/* USB standard descriptor endpoint bmAttributes */
#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK (0x80U)
#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT (7U)
#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT (0U)
#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN (0x80U)
#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK (0x0FU)
#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_SHFIT (0U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK (0x03U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_NUMBER_SHFIT (0U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_MASK (0x0CU)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_SHFIT (2U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_NO_SYNC (0x00U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_ASYNC (0x04U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_ADAPTIVE (0x08U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_SYNC (0x0CU)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_MASK (0x30U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_SHFIT (4U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_DATA_ENDPOINT (0x00U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_FEEDBACK_ENDPOINT (0x10U)
#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_IMPLICIT_FEEDBACK_DATA_ENDPOINT (0x20U)
#define USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK (0x07FFu)
#define USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK (0x1800u)
#define USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_SHFIT (11U)
/* USB standard descriptor otg bmAttributes */
#define USB_DESCRIPTOR_OTG_ATTRIBUTES_SRP_MASK (0x01u)
#define USB_DESCRIPTOR_OTG_ATTRIBUTES_HNP_MASK (0x02u)
#define USB_DESCRIPTOR_OTG_ATTRIBUTES_ADP_MASK (0x04u)
/* USB standard descriptor device capability usb20 extension bmAttributes */
#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_LPM_MASK (0x02U)
#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_LPM_SHIFT (1U)
#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_BESL_MASK (0x04U)
#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_BESL_SHIFT (2U)
/* Language structure */
typedef struct _usb_language
{
uint8_t **string; /* The Strings descriptor array */
uint32_t *length; /* The strings descriptor length array */
uint16_t languageId; /* The language id of current language */
} usb_language_t;
typedef struct _usb_language_list
{
uint8_t *languageString; /* The String 0U pointer */
uint32_t stringLength; /* The String 0U Length */
usb_language_t *languageList; /* The language list */
uint8_t count; /* The language count */
} usb_language_list_t;
typedef struct _usb_descriptor_common
{
uint8_t bLength; /* Size of this descriptor in bytes */
uint8_t bDescriptorType; /* DEVICE Descriptor Type */
uint8_t bData[1]; /* Data */
} usb_descriptor_common_t;
typedef struct _usb_descriptor_device
{
uint8_t bLength; /* Size of this descriptor in bytes */
uint8_t bDescriptorType; /* DEVICE Descriptor Type */
uint8_t bcdUSB[2]; /* UUSB Specification Release Number in Binary-Coded Decimal, e.g. 0x0200U */
uint8_t bDeviceClass; /* Class code */
uint8_t bDeviceSubClass; /* Sub-Class code */
uint8_t bDeviceProtocol; /* Protocol code */
uint8_t bMaxPacketSize0; /* Maximum packet size for endpoint zero */
uint8_t idVendor[2]; /* Vendor ID (assigned by the USB-IF) */
uint8_t idProduct[2]; /* Product ID (assigned by the manufacturer) */
uint8_t bcdDevice[2]; /* Device release number in binary-coded decimal */
uint8_t iManufacturer; /* Index of string descriptor describing manufacturer */
uint8_t iProduct; /* Index of string descriptor describing product */
uint8_t iSerialNumber; /* Index of string descriptor describing the device serial number */
uint8_t bNumConfigurations; /* Number of possible configurations */
} usb_descriptor_device_t;
typedef struct _usb_descriptor_configuration
{
uint8_t bLength; /* Descriptor size in bytes = 9U */
uint8_t bDescriptorType; /* CONFIGURATION type = 2U or 7U */
uint8_t wTotalLength[2]; /* Length of concatenated descriptors */
uint8_t bNumInterfaces; /* Number of interfaces, this configuration. */
uint8_t bConfigurationValue; /* Value to set this configuration. */
uint8_t iConfiguration; /* Index to configuration string */
uint8_t bmAttributes; /* Configuration characteristics */
uint8_t bMaxPower; /* Maximum power from bus, 2 mA units */
} usb_descriptor_configuration_t;
typedef struct _usb_descriptor_interface
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t iInterface;
} usb_descriptor_interface_t;
typedef struct _usb_descriptor_endpoint
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint8_t wMaxPacketSize[2];
uint8_t bInterval;
} usb_descriptor_endpoint_t;
typedef struct _usb_descriptor_endpoint_companion
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bMaxBurst;
uint8_t bmAttributes;
uint8_t wBytesPerInterval[2];
} usb_descriptor_endpoint_companion_t;
typedef struct _usb_descriptor_binary_device_object_store
{
uint8_t bLength; /* Descriptor size in bytes = 5U */
uint8_t bDescriptorType; /* BOS Descriptor type = 0FU*/
uint8_t wTotalLength[2]; /*Length of this descriptor and all of its sub descriptors*/
uint8_t bNumDeviceCaps; /*The number of separate device capability descriptors in the BOS*/
} usb_descriptor_bos_t;
typedef struct _usb_descriptor_usb20_extension
{
uint8_t bLength; /* Descriptor size in bytes = 7U */
uint8_t bDescriptorType; /* DEVICE CAPABILITY Descriptor type = 0x10U*/
uint8_t bDevCapabilityType; /*Length of this descriptor and all of its sub descriptors*/
uint8_t bmAttributes[4]; /*Bitmap encoding of supported device level features.*/
} usb_descriptor_usb20_extension_t;
typedef struct _usb_descriptor_super_speed_device_capability
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDevCapabilityType;
uint8_t bmAttributes;
uint8_t wSpeedsSupported[2];
uint8_t bFunctionalitySupport;
uint8_t bU1DevExitLat;
uint8_t wU2DevExitLat[2];
} usb_bos_device_capability_susperspeed_desc_t;
typedef union _usb_descriptor_union
{
usb_descriptor_common_t common; /* Common descriptor */
usb_descriptor_device_t device; /* Device descriptor */
usb_descriptor_configuration_t configuration; /* Configuration descriptor */
usb_descriptor_interface_t interface; /* Interface descriptor */
usb_descriptor_endpoint_t endpoint; /* Endpoint descriptor */
usb_descriptor_endpoint_companion_t endpointCompanion; /* Endpoint companion descriptor */
} usb_descriptor_union_t;
#endif /* __USB_SPEC_H__ */

View File

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

View File

@ -0,0 +1,577 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_OSA_H__
#define __USB_OSA_H__
/*!
* @addtogroup usb_os_abstraction
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Define big endian */
#define USB_BIG_ENDIAN (0U)
/*! @brief Define little endian */
#define USB_LITTLE_ENDIAN (1U)
/*! @brief Define current endian */
#define ENDIANNESS USB_LITTLE_ENDIAN
/*! @brief Define USB OSA event handle */
typedef void *usb_osa_event_handle;
/*! @brief Define USB OSA semaphore handle */
typedef void *usb_osa_sem_handle;
/*! @brief Define USB OSA mutex handle */
typedef void *usb_osa_mutex_handle;
/*! @brief Define USB OSA message queue handle */
typedef void *usb_osa_msgq_handle;
/*! @brief USB OSA error code */
typedef enum _usb_osa_status
{
kStatus_USB_OSA_Success = 0x00U, /*!< Success */
kStatus_USB_OSA_Error, /*!< Failed */
kStatus_USB_OSA_TimeOut, /*!< Timeout occurs while waiting */
} usb_osa_status_t;
/*! @brief The event flags are cleared automatically or manually.*/
typedef enum _usb_osa_event_mode
{
kUSB_OsaEventManualClear = 0U, /*!< The flags of the event is cleared manually. */
kUSB_OsaEventAutoClear = 1U, /*!< The flags of the event is cleared automatically. */
} usb_osa_event_mode_t;
#define USB_STACK_BM
/* Include required header file based on RTOS selection */
#if defined(USB_STACK_BM)
#include "usb_osa_bm.h"
#elif defined(USB_STACK_FREERTOS)
#include "usb_osa_freertos.h"
#elif defined(USB_STACK_UCOSII)
#include "usb_osa_ucosii.h"
#elif defined(USB_STACK_UCOSIII)
#include "usb_osa_ucosiii.h"
#else
#if defined(SDK_OS_BAREMETAL)
#define USB_STACK_BM
#include "usb_osa_bm.h"
#elif defined(SDK_OS_FREE_RTOS)
#define USB_STACK_FREERTOS
#include "usb_osa_freertos.h"
#elif defined(SDK_OS_UCOSII)
#define USB_STACK_UCOSII
#include "usb_osa_ucosii.h"
#elif defined(SDK_OS_UCOSIII)
#define USB_STACK_UCOSIII
#include "usb_osa_ucosiii.h"
#else
#error Not define RTOS in file "usb_osa.h".
#endif
#endif
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name USB OSA Memory Management
* @{
*/
/*!
* @brief Reserves the requested amount of memory in bytes.
*
* The function is used to reserve the requested amount of memory in bytes and initializes it to 0.
*
* @param length Amount of bytes to reserve.
*
* @return Pointer to the reserved memory. NULL if memory can't be allocated.
*/
void *USB_OsaMemoryAllocate(uint32_t length);
/*!
* @brief Frees the memory previously reserved.
*
* The function is used to free the memory block previously reserved.
*
* @param p Pointer to the start of the memory block previously reserved.
*
*/
extern void USB_OsaMemoryFree(void *p);
/* @} */
/*!
* @name USB OSA Event
* @{
*/
/*!
* @brief Creates an event object with all flags cleared.
*
* This function creates an event object and sets its clear mode. If the clear mode
* is kUSB_OsaEventAutoClear, when a task gets the event flags, these flags are
* cleared automatically. If the clear mode is kUSB_OsaEventManualClear, the flags must
* be cleared manually.
*
* @param handle It is an out parameter, which is used to return the pointer of the event object.
* @param flag The event is auto-clear or manual-clear. See the enumeration #usb_osa_event_mode_t.
*
* @return A USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_event_handle eventHandle;
usb_osa_status_t usbOsaStatus;
usbOsaStatus = USB_OsaEventCreate(&eventHandle, kUSB_OsaEventManualClear);
@endcode
*
*/
extern usb_osa_status_t USB_OsaEventCreate(usb_osa_event_handle *handle, uint32_t flag);
/*!
* @brief Destroys a created event object.
*
* @param handle Pointer to the event object.
*
* @return A USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_status_t usbOsaStatus;
...
usbOsaStatus = USB_OsaEventDestroy(eventHandle);
@endcode
*
*/
extern usb_osa_status_t USB_OsaEventDestroy(usb_osa_event_handle handle);
/*!
* @brief Sets an event flag.
*
* Sets specified flags for an event object.
*
* @param handle Pointer to the event object.
* @param bitMask Event flags to be set.
*
* @return A USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_status_t usbOsaStatus;
...
usbOsaStatus = USB_OsaEventSet(eventHandle, 0x01U);
@endcode
*
*/
extern usb_osa_status_t USB_OsaEventSet(usb_osa_event_handle handle, uint32_t bitMask);
/*!
* @brief Waits for an event flag.
*
* This function waits for a combination of flags to be set in an event object.
* An applications can wait for any/all bits to be set. This function can
* get the flags that wake up the waiting task.
*
* @param handle Pointer to the event object.
* @param bitMask Event flags to wait.
* @param flag Wait all flags or any flag to be set. 0U - wait any flag, others, wait all flags.
* @param timeout The maximum number of milliseconds to wait for the event.
* If the wait condition is not met, passing 0U
* waits indefinitely when the environment is an RTOS and returns the kStatus_OSA_Timeout
* immediately. Pass any value for the bare metal.
* @param bitSet Flags that wake up the waiting task are obtained by this parameter.
*
* @return An USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_status_t usbOsaStatus;
uint32_t bitSet;
...
usbOsaStatus = USB_OsaEventWait(eventHandle, 0x01U, 0U, 0U, &bitSet);
@endcode
*
*/
extern usb_osa_status_t USB_OsaEventWait(
usb_osa_event_handle handle, uint32_t bitMask, uint32_t flag, uint32_t timeout, uint32_t *bitSet);
/*!
* @brief Checks an event flag.
*
* This function checks for a combination of flags to be set in an event object.
*
* @param handle Pointer to the event object.
* @param bitMask Event flags to check.
* @param bitSet Flags have been set.
*
* @return An USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_status_t usbOsaStatus;
uint32_t bitSet;
...
usbOsaStatus = USB_OsaEventCheck(eventHandle, 0x01U, &bitSet);
@endcode
*
*/
extern usb_osa_status_t USB_OsaEventCheck(usb_osa_event_handle handle, uint32_t bitMask, uint32_t *bitSet);
/*!
* @brief Clears an event flag.
*
* This function clears flags of an event object.
*
* @param handle Pointer to the event object
* @param bitMask Event flags to be cleared.
*
* @return An USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_status_t usbOsaStatus;
...
usbOsaStatus = USB_OsaEventClear(eventHandle, 0x01U);
@endcode
*/
extern usb_osa_status_t USB_OsaEventClear(usb_osa_event_handle handle, uint32_t bitMask);
/* @} */
/*!
* @name USB OSA Semaphore
* @{
*/
/*!
* @brief Creates a semaphore with a given value.
*
* This function creates a semaphore and sets the default count.
*
* @param handle It is an out parameter, which is used to return pointer of the semaphore object.
* @param count Initializes a value of the semaphore.
*
* @return An USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_sem_handle semHandle;
usb_osa_status_t usbOsaStatus;
usbOsaStatus = USB_OsaSemCreate(&semHandle, 1U);
@endcode
*
*/
extern usb_osa_status_t USB_OsaSemCreate(usb_osa_sem_handle *handle, uint32_t count);
/*!
* @brief Destroys a semaphore object.
*
* This function destroys a semaphore object.
*
* @param handle Pointer to the semaphore.
*
* @return An USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_sem_handle semHandle;
usb_osa_status_t usbOsaStatus;
...
usbOsaStatus = USB_OsaSemDestroy(semHandle);
@endcode
*
*/
extern usb_osa_status_t USB_OsaSemDestroy(usb_osa_sem_handle handle);
/*!
* @brief Posts a semaphore.
*
* This function wakes up a task waiting on the semaphore. If a task is not pending, increases the semaphore's
value.
*
* @param handle Pointer to the semaphore.
*
* @return A USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_sem_handle semHandle;
usb_osa_status_t usbOsaStatus;
...
usbOsaStatus = USB_OsaSemPost(semHandle);
@endcode
*
*/
extern usb_osa_status_t USB_OsaSemPost(usb_osa_sem_handle handle);
/*!
* @brief Waits on a semaphore.
*
* This function checks the semaphore's value. If it is positive, it decreases the semaphore's value and return
kStatus_OSA_Success.
*
* @param handle Pointer to the semaphore.
* @param timeout The maximum number of milliseconds to wait for the semaphore.
* If the wait condition is not met, passing 0U
* waits indefinitely when environment is RTOS. And return kStatus_OSA_Timeout
* immediately for bare metal no matter what value has been passed.
*
* @return A USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_sem_handle semHandle;
usb_osa_status_t usbOsaStatus;
...
usbOsaStatus = USB_OsaSemWait(semHandle, 0U);
@endcode
*
*/
extern usb_osa_status_t USB_OsaSemWait(usb_osa_sem_handle handle, uint32_t timeout);
/* @} */
/*!
* @name USB OSA Mutex
* @{
*/
/*!
* @brief Creates a mutex.
*
* This function creates a mutex and sets it to an unlocked status.
*
* @param handle It is out parameter, which is used to return the pointer of the mutex object.
*
* @return A USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_mutex_handle mutexHandle;
usb_osa_status_t usbOsaStatus;
usbOsaStatus = USB_OsaMutexCreate(&mutexHandle);
@endcode
*
*/
extern usb_osa_status_t USB_OsaMutexCreate(usb_osa_mutex_handle *handle);
/*!
* @brief Destroys a mutex.
*
* This function destroys a mutex and sets it to an unlocked status.
*
* @param handle Pointer to the mutex.
*
* @return A USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_mutex_handle mutexHandle;
usb_osa_status_t usbOsaStatus;
...
usbOsaStatus = USB_OsaMutexDestroy(mutexHandle);
@endcode
*
*/
extern usb_osa_status_t USB_OsaMutexDestroy(usb_osa_mutex_handle handle);
/*!
* @brief Waits for a mutex and locks it.
*
* This function checks the mutex status. If it is unlocked, it locks it and returns the
* kStatus_OSA_Success. Otherwise, it waits forever to lock in RTOS and returns the
* kStatus_OSA_Success immediately for bare metal.
*
* @param handle Pointer to the mutex.
*
* @return A USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_mutex_handle mutexHandle;
usb_osa_status_t usbOsaStatus;
...
usbOsaStatus = USB_OsaMutexLock(mutexHandle);
@endcode
*
*/
extern usb_osa_status_t USB_OsaMutexLock(usb_osa_mutex_handle handle);
/*!
* @brief Unlocks a mutex.
*
* This function unlocks a mutex.
*
* @param handle Pointer to the mutex.
*
* @return A USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_mutex_handle mutexHandle;
usb_osa_status_t usbOsaStatus;
...
usbOsaStatus = USB_OsaMutexUnlock(mutexHandle);
@endcode
*
*/
extern usb_osa_status_t USB_OsaMutexUnlock(usb_osa_mutex_handle handle);
/* @} */
/*!
* @name USB OSA Message Queue
* @{
*/
/*!
* @brief Creates a message queue.
*
* This function creates a message queue.
*
* @param handle It is an out parameter, which is used to return a pointer of the message queue object.
* @param count The count of elements in the queue.
* @param size Size of every elements in words.
*
* @return A USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_msgq_handle msgqHandle;
usb_osa_status_t usbOsaStatus;
usbOsaStatus = USB_OsaMsgqCreate(msgqHandle, 8U, 4U);
@endcode
*
*/
extern usb_osa_status_t USB_OsaMsgqCreate(usb_osa_msgq_handle *handle, uint32_t count, uint32_t size);
/*!
* @brief Destroys a message queue.
*
* This function destroys a message queue.
*
* @param handle Pointer to a message queue.
*
* @return A USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_msgq_handle msgqHandle;
usb_osa_status_t usbOsaStatus;
...
usbOsaStatus = USB_OsaMsgqDestroy(msgqHandle);
@endcode
*
*/
extern usb_osa_status_t USB_OsaMsgqDestroy(usb_osa_msgq_handle handle);
/*!
* @brief Sends a message.
*
* This function sends a message to the tail of the message queue.
*
* @param handle Pointer to a message queue.
* @param msg The pointer to a message to be put into the queue.
*
* @return A USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_msgq_handle msgqHandle;
message_struct_t message;
usb_osa_status_t usbOsaStatus;
...
usbOsaStatus = USB_OsaMsgqSend(msgqHandle, &message);
@endcode
*
*/
extern usb_osa_status_t USB_OsaMsgqSend(usb_osa_msgq_handle handle, void *msg);
/*!
* @brief Receives a message.
*
* This function receives a message from the head of the message queue.
*
* @param handle Pointer to a message queue.
* @param msg The pointer to save a received message.
* @param timeout The maximum number of milliseconds to wait for a message.
* If the wait condition is not met, passing 0U
* waits indefinitely when an environment is RTOS and returns the kStatus_OSA_Timeout
* immediately for bare metal.
*
* @return A USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_msgq_handle msgqHandle;
message_struct_t message;
usb_osa_status_t usbOsaStatus;
...
usbOsaStatus = USB_OsaMsgqRecv(msgqHandle, &message, 0U);
@endcode
*
*/
extern usb_osa_status_t USB_OsaMsgqRecv(usb_osa_msgq_handle handle, void *msg, uint32_t timeout);
/*!
* @brief Checks a message queue and receives a message if the queue is not empty.
*
* This function checks a message queue and receives a message if the queue is not empty.
*
* @param handle Pointer to a message queue.
* @param msg The pointer to save a received message.
*
* @return A USB OSA error code or kStatus_OSA_Success.
*
* Example:
@code
usb_osa_msgq_handle msgqHandle;
message_struct_t message;
usb_osa_status_t usbOsaStatus;
...
usbOsaStatus = USB_OsaMsgqCheck(msgqHandle, &message);
@endcode
*
*/
extern usb_osa_status_t USB_OsaMsgqCheck(usb_osa_msgq_handle handle, void *msg);
/* @} */
#if defined(__cplusplus)
}
#endif
/* @} */
#endif /* __USB_OSA_H__ */

View File

@ -0,0 +1,522 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "stdint.h"
#include "usb.h"
#include "usb_osa.h"
#include "stdlib.h"
#include "fsl_device_registers.h"
#include "fsl_common.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define USB_OSA_BM_EVENT_COUNT (4U)
#define USB_OSA_BM_SEM_COUNT (1U)
#define USB_OSA_BM_MSGQ_COUNT (1U)
#define USB_OSA_BM_MSG_COUNT (8U)
#define USB_OSA_BM_MSG_SIZE (4U)
/* BM Event status structure */
typedef struct _usb_osa_event_struct
{
uint32_t value; /* Event mask */
uint32_t flag; /* Event flags, includes auto clear flag */
uint8_t isUsed; /* Is used */
} usb_osa_event_struct_t;
/* BM semaphore status structure */
typedef struct _usb_osa_sem_struct
{
uint32_t value; /* Semaphore count */
uint8_t isUsed; /* Is used */
} usb_osa_sem_struct_t;
/* BM msg status structure */
typedef struct _usb_osa_msg_struct
{
uint32_t msg[USB_OSA_BM_MSG_SIZE]; /* Message entity pointer */
} usb_osa_msg_struct_t;
/* BM msgq status structure */
typedef struct _usb_osa_msgq_struct
{
usb_osa_msg_struct_t msgs[USB_OSA_BM_MSG_COUNT]; /* Message entity list */
uint32_t count; /* Max message entity count */
uint32_t msgSize; /* Size of each message */
uint32_t msgCount; /* Valid messages */
uint32_t index; /* The first empty message entity index */
uint32_t current; /* The vaild message index */
uint8_t isUsed; /* Is used */
} usb_osa_msgq_struct_t;
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_osa_sem_struct_t
s_UsbBmSemStruct[USB_OSA_BM_SEM_COUNT];
USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_osa_event_struct_t
s_UsbBmEventStruct[USB_OSA_BM_EVENT_COUNT];
USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_osa_msgq_struct_t
s_UsbBmMsgqStruct[USB_OSA_BM_MSGQ_COUNT];
/*******************************************************************************
* Code
******************************************************************************/
void *USB_OsaMemoryAllocate(uint32_t length)
{
void *p = (void *)malloc(length);
uint8_t *temp = (uint8_t *)p;
if (p)
{
for (uint32_t count = 0U; count < length; count++)
{
temp[count] = 0U;
}
}
return p;
}
void USB_OsaMemoryFree(void *p)
{
free(p);
}
void USB_OsaEnterCritical(uint32_t *sr)
{
*sr = DisableGlobalIRQ();
__ASM("CPSID i");
}
void USB_OsaExitCritical(uint32_t sr)
{
EnableGlobalIRQ(sr);
}
usb_osa_status_t USB_OsaEventCreate(usb_osa_event_handle *handle, uint32_t flag)
{
usb_osa_event_struct_t *event = NULL;
USB_OSA_SR_ALLOC();
if (!handle)
{
return kStatus_USB_OSA_Error;
}
USB_OSA_ENTER_CRITICAL();
for (uint32_t i = 0; i < USB_OSA_BM_EVENT_COUNT; i++)
{
if (0 == s_UsbBmEventStruct[i].isUsed)
{
event = &s_UsbBmEventStruct[i];
break;
}
}
if (NULL == event)
{
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Error;
}
event->value = 0U;
event->flag = flag;
event->isUsed = 1;
*handle = event;
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Success;
}
usb_osa_status_t USB_OsaEventDestroy(usb_osa_event_handle handle)
{
usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle;
USB_OSA_SR_ALLOC();
if (handle)
{
USB_OSA_ENTER_CRITICAL();
event->isUsed = 0;
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Success;
}
return kStatus_USB_OSA_Error;
}
usb_osa_status_t USB_OsaEventSet(usb_osa_event_handle handle, uint32_t bitMask)
{
usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle;
USB_OSA_SR_ALLOC();
if (handle)
{
USB_OSA_ENTER_CRITICAL();
event->value |= bitMask;
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Success;
}
return kStatus_USB_OSA_Error;
}
usb_osa_status_t USB_OsaEventWait(
usb_osa_event_handle handle, uint32_t bitMask, uint32_t flag, uint32_t timeout, uint32_t *bitSet)
{
usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle;
uint32_t bits;
USB_OSA_SR_ALLOC();
if (handle)
{
USB_OSA_ENTER_CRITICAL();
bits = event->value & bitMask;
if (flag)
{
if (bits != bitMask)
{
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_TimeOut;
}
}
else
{
if (!bits)
{
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_TimeOut;
}
}
if (bitSet)
{
*bitSet = bits;
}
if (event->flag)
{
event->value &= ~bits;
}
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Success;
}
return kStatus_USB_OSA_Error;
}
usb_osa_status_t USB_OsaEventCheck(usb_osa_event_handle handle, uint32_t bitMask, uint32_t *bitSet)
{
usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle;
uint32_t bits;
USB_OSA_SR_ALLOC();
if (handle)
{
USB_OSA_ENTER_CRITICAL();
bits = event->value & bitMask;
if (!bits)
{
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Error;
}
if (bitSet)
{
*bitSet = bits;
}
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Success;
}
return kStatus_USB_OSA_Error;
}
usb_osa_status_t USB_OsaEventClear(usb_osa_event_handle handle, uint32_t bitMask)
{
usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle;
uint32_t bits;
USB_OSA_SR_ALLOC();
if (handle)
{
USB_OSA_ENTER_CRITICAL();
bits = event->value & bitMask;
event->value &= ~bits;
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Success;
}
return kStatus_USB_OSA_Error;
}
usb_osa_status_t USB_OsaSemCreate(usb_osa_sem_handle *handle, uint32_t count)
{
usb_osa_sem_struct_t *sem = NULL;
USB_OSA_SR_ALLOC();
if (!handle)
{
return kStatus_USB_OSA_Error;
}
USB_OSA_ENTER_CRITICAL();
for (uint32_t i = 0; i < USB_OSA_BM_SEM_COUNT; i++)
{
if (0 == s_UsbBmSemStruct[i].isUsed)
{
sem = &s_UsbBmSemStruct[i];
break;
}
}
if (NULL == sem)
{
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Error;
}
sem->value = count;
sem->isUsed = 1;
*handle = sem;
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Success;
}
usb_osa_status_t USB_OsaSemDestroy(usb_osa_sem_handle handle)
{
usb_osa_sem_struct_t *sem = (usb_osa_sem_struct_t *)handle;
USB_OSA_SR_ALLOC();
if (handle)
{
USB_OSA_ENTER_CRITICAL();
sem->isUsed = 0;
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Success;
}
return kStatus_USB_OSA_Error;
}
usb_osa_status_t USB_OsaSemPost(usb_osa_sem_handle handle)
{
usb_osa_sem_struct_t *sem = (usb_osa_sem_struct_t *)handle;
USB_OSA_SR_ALLOC();
if (!handle)
{
return kStatus_USB_OSA_Error;
}
USB_OSA_ENTER_CRITICAL();
sem->value++;
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Success;
}
usb_osa_status_t USB_OsaSemWait(usb_osa_sem_handle handle, uint32_t timeout)
{
usb_osa_sem_struct_t *sem = (usb_osa_sem_struct_t *)handle;
USB_OSA_SR_ALLOC();
if (!handle)
{
return kStatus_USB_OSA_Error;
}
USB_OSA_ENTER_CRITICAL();
if (sem->value)
{
sem->value--;
}
else
{
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_TimeOut;
}
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Success;
}
usb_osa_status_t USB_OsaMutexCreate(usb_osa_mutex_handle *handle)
{
if (!handle)
{
return kStatus_USB_OSA_Error;
}
*handle = (usb_osa_mutex_handle)0xFFFF0000U;
return kStatus_USB_OSA_Success;
}
usb_osa_status_t USB_OsaMutexDestroy(usb_osa_mutex_handle handle)
{
return kStatus_USB_OSA_Success;
}
usb_osa_status_t USB_OsaMutexLock(usb_osa_mutex_handle handle)
{
return kStatus_USB_OSA_Success;
}
usb_osa_status_t USB_OsaMutexUnlock(usb_osa_mutex_handle handle)
{
return kStatus_USB_OSA_Success;
}
usb_osa_status_t USB_OsaMsgqCreate(usb_osa_msgq_handle *handle, uint32_t count, uint32_t size)
{
usb_osa_msgq_struct_t *msgq = NULL;
USB_OSA_SR_ALLOC();
if (!handle)
{
return kStatus_USB_OSA_Error;
}
USB_OSA_ENTER_CRITICAL();
for (uint32_t i = 0; i < USB_OSA_BM_MSGQ_COUNT; i++)
{
if (0 == s_UsbBmMsgqStruct[i].isUsed)
{
msgq = &s_UsbBmMsgqStruct[i];
break;
}
}
if ((NULL == msgq) || (count > USB_OSA_BM_MSG_COUNT) || (size > USB_OSA_BM_MSG_SIZE))
{
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Error;
}
msgq->count = count;
msgq->msgSize = size;
msgq->msgCount = 0U;
msgq->index = 0U;
msgq->current = 0U;
msgq->isUsed = 1;
*handle = msgq;
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Success;
}
usb_osa_status_t USB_OsaMsgqDestroy(usb_osa_msgq_handle handle)
{
usb_osa_msgq_struct_t *msgq = (usb_osa_msgq_struct_t *)handle;
USB_OSA_SR_ALLOC();
if (!handle)
{
return kStatus_USB_OSA_Error;
}
USB_OSA_ENTER_CRITICAL();
msgq->isUsed = 0;
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Success;
}
usb_osa_status_t USB_OsaMsgqSend(usb_osa_msgq_handle handle, void *msg)
{
usb_osa_msgq_struct_t *msgq = (usb_osa_msgq_struct_t *)handle;
usb_osa_msg_struct_t *msgEntity;
uint32_t *p;
uint32_t *q;
uint32_t count;
USB_OSA_SR_ALLOC();
if (!handle)
{
return kStatus_USB_OSA_Error;
}
USB_OSA_ENTER_CRITICAL();
if (msgq->msgCount >= msgq->count)
{
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Error;
}
msgEntity = &msgq->msgs[msgq->index];
p = (uint32_t *)&msgEntity->msg[0];
q = (uint32_t *)msg;
for (count = 0U; count < msgq->msgSize; count++)
{
p[count] = q[count];
}
if (0U == msgq->msgCount)
{
msgq->current = msgq->index;
}
msgq->msgCount++;
msgq->index++;
msgq->index = msgq->index % msgq->count;
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Success;
}
usb_osa_status_t USB_OsaMsgqRecv(usb_osa_msgq_handle handle, void *msg, uint32_t timeout)
{
usb_osa_msgq_struct_t *msgq = (usb_osa_msgq_struct_t *)handle;
usb_osa_msg_struct_t *msgEntity;
uint32_t *p;
uint32_t *q;
uint32_t count;
USB_OSA_SR_ALLOC();
if (!handle)
{
return kStatus_USB_OSA_Error;
}
USB_OSA_ENTER_CRITICAL();
if (msgq->msgCount < 1U)
{
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_TimeOut;
}
msgEntity = &msgq->msgs[msgq->current];
q = (uint32_t *)&msgEntity->msg[0];
p = (uint32_t *)msg;
for (count = 0U; count < msgq->msgSize; count++)
{
p[count] = q[count];
}
msgq->msgCount--;
msgq->current++;
msgq->current = msgq->current % msgq->count;
USB_OSA_EXIT_CRITICAL();
return kStatus_USB_OSA_Success;
}
usb_osa_status_t USB_OsaMsgqCheck(usb_osa_msgq_handle handle, void *msg)
{
usb_osa_msgq_struct_t *msgq = (usb_osa_msgq_struct_t *)handle;
uint32_t msgCount;
USB_OSA_SR_ALLOC();
if (!handle)
{
return kStatus_USB_OSA_Error;
}
USB_OSA_ENTER_CRITICAL();
msgCount = msgq->msgCount;
USB_OSA_EXIT_CRITICAL();
if (msgCount)
{
if (kStatus_USB_OSA_Success == USB_OsaMsgqRecv(msgq, msg, 0U))
{
return kStatus_USB_OSA_Success;
}
}
return kStatus_USB_OSA_Error;
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_OSA_BM_H__
#define __USB_OSA_BM_H__
/*******************************************************************************
* Definitions
******************************************************************************/
#define USB_OSA_SR_ALLOC() uint32_t usbOsaCurrentSr;
#define USB_OSA_ENTER_CRITICAL() USB_OsaEnterCritical(&usbOsaCurrentSr)
#define USB_OSA_EXIT_CRITICAL() USB_OsaExitCritical(usbOsaCurrentSr)
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
extern void USB_OsaEnterCritical(uint32_t *sr);
extern void USB_OsaExitCritical(uint32_t sr);
#if defined(__cplusplus)
}
#endif
#endif /* __USB_OSA_BM_H__ */

View File

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

View File

@ -0,0 +1,243 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 - 2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "usb.h"
#include "fsl_device_registers.h"
#include "usb_phy.h"
void *USB_EhciPhyGetBase(uint8_t controllerId)
{
void *usbPhyBase = NULL;
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
uint32_t instance;
uint32_t newinstance = 0;
uint32_t usbphy_base_temp[] = USBPHY_BASE_ADDRS;
uint32_t usbphy_base[] = USBPHY_BASE_ADDRS;
if (controllerId < kUSB_ControllerEhci0)
{
return NULL;
}
if ((controllerId == kUSB_ControllerEhci0) || (controllerId == kUSB_ControllerEhci1))
{
controllerId = controllerId - kUSB_ControllerEhci0;
}
else if ((controllerId == kUSB_ControllerLpcIp3511Hs0) || (controllerId == kUSB_ControllerLpcIp3511Hs1))
{
controllerId = controllerId - kUSB_ControllerLpcIp3511Hs0;
}
else if ((controllerId == kUSB_ControllerIp3516Hs0) || (controllerId == kUSB_ControllerIp3516Hs1))
{
controllerId = controllerId - kUSB_ControllerIp3516Hs0;
}
else
{
}
for (instance = 0; instance < (sizeof(usbphy_base_temp) / sizeof(usbphy_base_temp[0])); instance++)
{
if (usbphy_base_temp[instance])
{
usbphy_base[newinstance++] = usbphy_base_temp[instance];
}
}
if (controllerId > newinstance)
{
return NULL;
}
usbPhyBase = (void *)usbphy_base[controllerId];
#endif
return usbPhyBase;
}
/*!
* @brief ehci phy initialization.
*
* This function initialize ehci phy IP.
*
* @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
* @param[in] freq the external input clock.
* for example: if the external input clock is 16M, the parameter freq should be 16000000.
*
* @retval kStatus_USB_Success cancel successfully.
* @retval kStatus_USB_Error the freq value is incorrect.
*/
uint32_t USB_EhciPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig)
{
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
USBPHY_Type *usbPhyBase;
usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
if (NULL == usbPhyBase)
{
return kStatus_USB_Error;
}
#if ((defined FSL_FEATURE_SOC_ANATOP_COUNT) && (FSL_FEATURE_SOC_ANATOP_COUNT > 0U))
ANATOP->HW_ANADIG_REG_3P0.RW =
(ANATOP->HW_ANADIG_REG_3P0.RW &
(~(ANATOP_HW_ANADIG_REG_3P0_OUTPUT_TRG(0x1F) | ANATOP_HW_ANADIG_REG_3P0_ENABLE_ILIMIT_MASK))) |
ANATOP_HW_ANADIG_REG_3P0_OUTPUT_TRG(0x17) | ANATOP_HW_ANADIG_REG_3P0_ENABLE_LINREG_MASK;
ANATOP->HW_ANADIG_USB2_CHRG_DETECT.SET =
ANATOP_HW_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B_MASK | ANATOP_HW_ANADIG_USB2_CHRG_DETECT_EN_B_MASK;
#endif
#if (defined USB_ANALOG)
USB_ANALOG->INSTANCE[controllerId - kUSB_ControllerEhci0].CHRG_DETECT_SET = USB_ANALOG_CHRG_DETECT_CHK_CHRG_B(1) | USB_ANALOG_CHRG_DETECT_EN_B(1);
#endif
#if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)))
usbPhyBase->TRIM_OVERRIDE_EN = 0x001fU; /* override IFR value */
#endif
usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK; /* support LS device. */
usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; /* support external FS Hub with LS device connected. */
/* PWD register provides overall control of the PHY power state */
usbPhyBase->PWD = 0U;
if ((kUSB_ControllerIp3516Hs0 == controllerId) || (kUSB_ControllerIp3516Hs1 == controllerId) ||
(kUSB_ControllerLpcIp3511Hs0 == controllerId) || (kUSB_ControllerLpcIp3511Hs0 == controllerId))
{
usbPhyBase->CTRL_SET = USBPHY_CTRL_SET_ENAUTOCLR_CLKGATE_MASK;
usbPhyBase->CTRL_SET = USBPHY_CTRL_SET_ENAUTOCLR_PHY_PWD_MASK;
}
if (NULL != phyConfig)
{
/* Decode to trim the nominal 17.78mA current source for the High Speed TX drivers on USB_DP and USB_DM. */
usbPhyBase->TX =
((usbPhyBase->TX & (~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK))) |
(USBPHY_TX_D_CAL(phyConfig->D_CAL) | USBPHY_TX_TXCAL45DP(phyConfig->TXCAL45DP) |
USBPHY_TX_TXCAL45DM(phyConfig->TXCAL45DM)));
}
#endif
return kStatus_USB_Success;
}
/*!
* @brief ehci phy initialization for suspend and resume.
*
* This function initialize ehci phy IP for suspend and resume.
*
* @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
* @param[in] freq the external input clock.
* for example: if the external input clock is 16M, the parameter freq should be 16000000.
*
* @retval kStatus_USB_Success cancel successfully.
* @retval kStatus_USB_Error the freq value is incorrect.
*/
uint32_t USB_EhciLowPowerPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig)
{
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
USBPHY_Type *usbPhyBase;
usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
if (NULL == usbPhyBase)
{
return kStatus_USB_Error;
}
#if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)))
usbPhyBase->TRIM_OVERRIDE_EN = 0x001fU; /* override IFR value */
#endif
#if ((defined USBPHY_CTRL_AUTORESUME_EN_MASK) && (USBPHY_CTRL_AUTORESUME_EN_MASK > 0U))
usbPhyBase->CTRL |= USBPHY_CTRL_AUTORESUME_EN_MASK;
#else
usbPhyBase->CTRL |= USBPHY_CTRL_ENAUTO_PWRON_PLL_MASK;
#endif
usbPhyBase->CTRL |= USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK | USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK;
usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK; /* support LS device. */
usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; /* support external FS Hub with LS device connected. */
/* PWD register provides overall control of the PHY power state */
usbPhyBase->PWD = 0U;
#if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)) && (!(defined FSL_FEATURE_USBHSD_USB_RAM)))
/* now the 480MHz USB clock is up, then configure fractional divider after PLL with PFD
* pfd clock = 480MHz*18/N, where N=18~35
* Please note that USB1PFDCLK has to be less than 180MHz for RUN or HSRUN mode
*/
usbPhyBase->ANACTRL |= USBPHY_ANACTRL_PFD_FRAC(24); /* N=24 */
usbPhyBase->ANACTRL |= USBPHY_ANACTRL_PFD_CLK_SEL(1); /* div by 4 */
usbPhyBase->ANACTRL &= ~USBPHY_ANACTRL_DEV_PULLDOWN_MASK;
usbPhyBase->ANACTRL &= ~USBPHY_ANACTRL_PFD_CLKGATE_MASK;
while (!(usbPhyBase->ANACTRL & USBPHY_ANACTRL_PFD_STABLE_MASK))
{
}
#endif
if (NULL != phyConfig)
{
/* Decode to trim the nominal 17.78mA current source for the High Speed TX drivers on USB_DP and USB_DM. */
usbPhyBase->TX =
((usbPhyBase->TX & (~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK))) |
(USBPHY_TX_D_CAL(phyConfig->D_CAL) | USBPHY_TX_TXCAL45DP(phyConfig->TXCAL45DP) |
USBPHY_TX_TXCAL45DM(phyConfig->TXCAL45DM)));
}
#endif
return kStatus_USB_Success;
}
/*!
* @brief ehci phy de-initialization.
*
* This function de-initialize ehci phy IP.
*
* @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
*/
void USB_EhciPhyDeinit(uint8_t controllerId)
{
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
USBPHY_Type *usbPhyBase;
usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
if (NULL == usbPhyBase)
{
return;
}
#if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)))
usbPhyBase->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_POWER_MASK; /* power down PLL */
usbPhyBase->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_EN_USB_CLKS_MASK; /* disable USB clock output from USB PHY PLL */
#endif
usbPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* set to 1U to gate clocks */
#endif
}
/*!
* @brief ehci phy disconnect detection enable or disable.
*
* This function enable/disable host ehci disconnect detection.
*
* @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
* @param[in] enable
* 1U - enable;
* 0U - disable;
*/
void USB_EhcihostPhyDisconnectDetectCmd(uint8_t controllerId, uint8_t enable)
{
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
USBPHY_Type *usbPhyBase;
usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
if (NULL == usbPhyBase)
{
return;
}
if (enable)
{
usbPhyBase->CTRL |= USBPHY_CTRL_ENHOSTDISCONDETECT_MASK;
}
else
{
usbPhyBase->CTRL &= (~USBPHY_CTRL_ENHOSTDISCONDETECT_MASK);
}
#endif
}

View File

@ -0,0 +1,91 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 - 2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __USB_PHY_H__
#define __USB_PHY_H__
/*******************************************************************************
* Definitions
******************************************************************************/
typedef struct _usb_phy_config_struct
{
uint8_t D_CAL; /* Decode to trim the nominal 17.78mA current source */
uint8_t TXCAL45DP; /* Decode to trim the nominal 45-Ohm series termination resistance to the USB_DP output pin */
uint8_t TXCAL45DM; /* Decode to trim the nominal 45-Ohm series termination resistance to the USB_DM output pin */
} usb_phy_config_struct_t;
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* API
******************************************************************************/
/*!
* @brief EHCI PHY get USB phy bass address.
*
* This function is used to get USB phy bass address.
*
* @param[in] controllerId EHCI controller ID; See the #usb_controller_index_t.
*
* @retval USB phy bass address.
*/
extern void *USB_EhciPhyGetBase(uint8_t controllerId);
/*!
* @brief EHCI PHY initialization.
*
* This function initializes the EHCI PHY IP.
*
* @param[in] controllerId EHCI controller ID; See the #usb_controller_index_t.
* @param[in] freq The external input clock.
*
* @retval kStatus_USB_Success Cancel successfully.
* @retval kStatus_USB_Error The freq value is incorrect.
*/
extern uint32_t USB_EhciPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig);
/*!
* @brief ehci phy initialization for suspend and resume.
*
* This function initialize ehci phy IP for suspend and resume.
*
* @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
* @param[in] freq the external input clock.
* for example: if the external input clock is 16M, the parameter freq should be 16000000.
*
* @retval kStatus_USB_Success cancel successfully.
* @retval kStatus_USB_Error the freq value is incorrect.
*/
extern uint32_t USB_EhciLowPowerPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig);
/*!
* @brief EHCI PHY deinitialization.
*
* This function deinitializes the EHCI PHY IP.
*
* @param[in] controllerId EHCI controller ID; See #usb_controller_index_t.
*/
extern void USB_EhciPhyDeinit(uint8_t controllerId);
/*!
* @brief EHCI PHY disconnect detection enable or disable.
*
* This function enable/disable the host EHCI disconnect detection.
*
* @param[in] controllerId EHCI controller ID; See #usb_controller_index_t.
* @param[in] enable
* 1U - enable;
* 0U - disable;
*/
extern void USB_EhcihostPhyDisconnectDetectCmd(uint8_t controllerId, uint8_t enable);
#if defined(__cplusplus)
}
#endif
#endif /* __USB_PHY_H__ */

View File

@ -26,7 +26,7 @@ CONFIG_BSP_USING_UART1=y
# CONFIG_BSP_USING_UART4 is not set
# CONFIG_BSP_USING_UART5 is not set
# CONFIG_BSP_USING_USB is not set
# CONFIG_BSP_USING_USBH is not set
# CONFIG_BSP_USING_STM32_USBH is not set
#
# Hardware feature

View File

@ -26,7 +26,7 @@ CONFIG_BSP_USING_UART3=y
# CONFIG_BSP_USING_UART4 is not set
# CONFIG_BSP_USING_UART5 is not set
#CONFIG_BSP_USING_USB is not set
#CONFIG_BSP_USING_USBH is not set
#CONFIG_BSP_USING_STM32_USBH is not set
#
# Hardware feature

View File

@ -98,7 +98,7 @@ endif
menuconfig BSP_USING_USB
bool "Using USB device"
default n
select BSP_USING_USBH
select BSP_USING_STM32_USBH
select RESOURCES_USB
select RESOURCES_USB_HOST
select USBH_MSTORAGE

View File

@ -1,4 +1,4 @@
config BSP_USING_USBH
config BSP_USING_STM32_USBH
bool "Using usb host"
default y
config USB_BUS_NAME

View File

@ -31,7 +31,7 @@ Modification:
*************************************************/
#include <xiuos.h>
#include <usb_host.h>
#include <stm32_usb_host.h>
#include <hardware_gpio.h>
#include <hardware_rcc.h>
#include <stm32f4xx.h>

View File

@ -26,7 +26,7 @@ CONFIG_BSP_USING_UART3=y
# CONFIG_BSP_USING_UART4 is not set
# CONFIG_BSP_USING_UART5 is not set
#CONFIG_BSP_USING_USB is not set
#CONFIG_BSP_USING_USBH is not set
#CONFIG_BSP_USING_STM32_USBH is not set
#
# Hardware feature

View File

@ -27,7 +27,7 @@
#include <stdlib.h>
#include <board.h>
#ifdef BSP_USING_USBH
#ifdef BSP_USING_USB
#include "connect_usb.h"
#endif
@ -123,9 +123,12 @@ struct InitSequenceDesc env_init[] =
};
struct InitSequenceDesc communication_init[] =
{
#ifdef BSP_USING_USBH
#ifdef BSP_USING_STM32_USBH
{ "STM32USBHostRegister", STM32USBHostRegister },
{ "hw usb", Stm32HwUsbInit },
#endif
#ifdef BSP_USING_NXP_USBH
{ "nxp hw usb", Imrt1052HwUsbHostInit },
#endif
{ " NONE ", NONE },
};

View File

@ -174,6 +174,13 @@ 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/usb/nxp_usb_driver/host \
-I$(BSP_ROOT)/third_party_driver/usb/nxp_usb_driver/host/class \
-I$(BSP_ROOT)/third_party_driver/usb/nxp_usb_driver/include \
-I$(BSP_ROOT)/third_party_driver/usb/nxp_usb_driver/osa \
-I$(BSP_ROOT)/third_party_driver/usb/nxp_usb_driver/phy \
-I$(BSP_ROOT)/third_party_driver/ethernet \
-I$(BSP_ROOT)/third_party_driver/ethernet/ksz8081 \
-I$(BSP_ROOT)/third_party_driver/MIMXRT1052 \

View File

@ -53,7 +53,7 @@
#include <bus_usb.h>
#include <dev_usb.h>
#ifdef RESOURCES_USB_HOST
#include <usb_host.h>
#include <stm32_usb_host.h>
#endif
#endif

View File

@ -11,7 +11,7 @@
*/
/**
* @file usb_common.h
* @file stm32_usb_common.h
* @brief define usb function and struct
* @version 1.0
* @author AIIT XUOS Lab
@ -19,7 +19,7 @@
*/
/*************************************************
File name: usb_common.h
File name: stm32_usb_common.h
Description: define usb function and common struct
Others: take RT-Thread v4.0.2/components/drivers/include/drivers/usb_common.h for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2

View File

@ -9,7 +9,7 @@
*/
/**
* @file usb_host.h
* @file stm32_usb_host.h
* @brief define usb host function and struct
* @version 1.0
* @author AIIT XUOS Lab
@ -17,7 +17,7 @@
*/
/*************************************************
File name: usb_host.h
File name: stm32_usb_host.h
Description: define usb host function and struct
Others: take RT-Thread v4.0.2/components/drivers/include/drivers/usb_host.h for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
@ -34,7 +34,7 @@ Modification:
#include <xiuos.h>
#include <usb_common.h>
#include <stm32_usb_common.h>
#ifdef __cplusplus
extern "C" {

View File

@ -1,3 +1,5 @@
SRC_DIR := usbhost
ifeq ($(CONFIG_BSP_USING_STM32_USBH),y)
SRC_DIR := usbhost
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -30,7 +30,7 @@ Modification:
*************************************************/
#include <xiuos.h>
#include <usb_host.h>
#include <stm32_usb_host.h>
#include "mass.h"
#ifdef USBH_MSTORAGE

View File

@ -31,7 +31,7 @@ Modification:
#include <xiuos.h>
#include <usb_host.h>
#include <stm32_usb_host.h>
#include "mass.h"
#if defined(FS_VFS)

View File

@ -30,7 +30,7 @@ Modification:
*************************************************/
#include <xiuos.h>
#include <usb_host.h>
#include <stm32_usb_host.h>
static struct uinstance dev[USB_MAX_DEVICE];

View File

@ -31,7 +31,7 @@ Modification:
#include <xiuos.h>
#include <xs_klist.h>
#include <usb_host.h>
#include <stm32_usb_host.h>
static DoubleLinklistType DriverList;

View File

@ -30,7 +30,7 @@ Modification:
*************************************************/
#include <xiuos.h>
#include <usb_host.h>
#include <stm32_usb_host.h>
#define USB_THREAD_STACK_SIZE 4096

View File

@ -30,7 +30,7 @@ Modification:
*************************************************/
#include <xiuos.h>
#include <usb_host.h>
#include <stm32_usb_host.h>
#define USB_HOST_CONTROLLER_NAME "usbh"