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