Merge branch 'master' into segger_systemview
This commit is contained in:
Коммит
ea844db446
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="0.114656749">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.114656749" moduleId="org.eclipse.cdt.core.settings" name="Default">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="${ProjName}" buildProperties="" description="" id="0.114656749" name="Default" optionalBuildProperties="" parent="org.eclipse.cdt.build.core.prefbase.cfg">
|
||||
<folderInfo id="0.114656749." name="/" resourcePath="">
|
||||
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.1182750861" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
|
||||
<targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.1182750861.169007201" name=""/>
|
||||
<builder autoBuildTarget="all" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="org.eclipse.cdt.build.core.settings.default.builder.579570726" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.2143276802" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1873650595" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1337802279" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1707090075" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.338985256" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1165165914" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.714476670" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<folderInfo id="0.114656749.839627589" name="/" resourcePath="contrib-os/various/fault_handlers">
|
||||
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.293033704" name="No ToolChain" superClass="org.eclipse.cdt.build.core.prefbase.toolchain" unusedChildren="">
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.1140657077" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs.2143276802"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1084730546" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder.1873650595"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1064503935" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder.1707090075"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.57346275" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder.1165165914"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry excluding="fault_handlers" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
<storageModule moduleId="ilg.gnumcueclipse.managedbuild.packs"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="RT-STM32F407-DISCOVERY-fault_handlers.null.1703860681" name="RT-STM32F407-DISCOVERY-fault_handlers"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<scannerConfigBuildInfo instanceId="0.114656749">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
<configuration configurationName="Default">
|
||||
<resource resourceType="PROJECT" workspacePath="/RT-STM32F407-DISCOVERY-fault_handlers"/>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
</cproject>
|
|
@ -0,0 +1,100 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>RT-STM32F407-DISCOVERY-fault_handlers</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>?name?</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.append_environment</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildArguments</key>
|
||||
<value>-j1</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
|
||||
<value>clean</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.contents</key>
|
||||
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
|
||||
<value>false</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.stopOnError</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
<linkedResources>
|
||||
<link>
|
||||
<name>board</name>
|
||||
<type>2</type>
|
||||
<locationURI>$%7BPARENT-4-PROJECT_LOC%7D/ChibiOS/os/hal/boards/ST_STM32F4_DISCOVERY</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>contrib-os</name>
|
||||
<type>2</type>
|
||||
<locationURI>$%7BPARENT-3-PROJECT_LOC%7D/os</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>os</name>
|
||||
<type>2</type>
|
||||
<locationURI>$%7BPARENT-4-PROJECT_LOC%7D/ChibiOS/os</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>test</name>
|
||||
<type>2</type>
|
||||
<locationURI>CHIBIOS/test</locationURI>
|
||||
</link>
|
||||
</linkedResources>
|
||||
</projectDescription>
|
|
@ -0,0 +1,6 @@
|
|||
eclipse.preferences.version=1
|
||||
environment/project/0.114656749/PATH/delimiter=;
|
||||
environment/project/0.114656749/PATH/operation=replace
|
||||
environment/project/0.114656749/PATH/value=${PATH};D\:\\toolchains\\gcc-arm-none-eabi-8-2018-q4-major-win32\\bin;${PATH};D\:\\toolchains\\gcc-arm-none-eabi-4_9-2014q4-20141203-win32\\bin;D\:\\toolchains\\msys64\\usr\\bin
|
||||
environment/project/0.114656749/append=true
|
||||
environment/project/0.114656749/appendContributed=true
|
|
@ -0,0 +1,189 @@
|
|||
##############################################################################
|
||||
# Build global options
|
||||
# NOTE: Can be overridden externally.
|
||||
#
|
||||
|
||||
# Compiler options here.
|
||||
ifeq ($(USE_OPT),)
|
||||
USE_OPT = -Og -ggdb -fomit-frame-pointer -falign-functions=16
|
||||
endif
|
||||
|
||||
# C specific options here (added to USE_OPT).
|
||||
ifeq ($(USE_COPT),)
|
||||
USE_COPT =
|
||||
endif
|
||||
|
||||
# C++ specific options here (added to USE_OPT).
|
||||
ifeq ($(USE_CPPOPT),)
|
||||
USE_CPPOPT = -fno-rtti
|
||||
endif
|
||||
|
||||
# Enable this if you want the linker to remove unused code and data.
|
||||
ifeq ($(USE_LINK_GC),)
|
||||
USE_LINK_GC = yes
|
||||
endif
|
||||
|
||||
# Linker extra options here.
|
||||
ifeq ($(USE_LDOPT),)
|
||||
USE_LDOPT =
|
||||
endif
|
||||
|
||||
# Enable this if you want link time optimizations (LTO).
|
||||
ifeq ($(USE_LTO),)
|
||||
USE_LTO = no
|
||||
endif
|
||||
|
||||
# Enable this if you want to see the full log while compiling.
|
||||
ifeq ($(USE_VERBOSE_COMPILE),)
|
||||
USE_VERBOSE_COMPILE = no
|
||||
endif
|
||||
|
||||
# If enabled, this option makes the build process faster by not compiling
|
||||
# modules not used in the current configuration.
|
||||
ifeq ($(USE_SMART_BUILD),)
|
||||
USE_SMART_BUILD = yes
|
||||
endif
|
||||
|
||||
#
|
||||
# Build global options
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Architecture or project specific options
|
||||
#
|
||||
|
||||
# Stack size to be allocated to the Cortex-M process stack. This stack is
|
||||
# the stack used by the main() thread.
|
||||
ifeq ($(USE_PROCESS_STACKSIZE),)
|
||||
USE_PROCESS_STACKSIZE = 0x400
|
||||
endif
|
||||
|
||||
# Stack size to the allocated to the Cortex-M main/exceptions stack. This
|
||||
# stack is used for processing interrupts and exceptions.
|
||||
ifeq ($(USE_EXCEPTIONS_STACKSIZE),)
|
||||
USE_EXCEPTIONS_STACKSIZE = 0x400
|
||||
endif
|
||||
|
||||
# Enables the use of FPU (no, softfp, hard).
|
||||
ifeq ($(USE_FPU),)
|
||||
USE_FPU = hard
|
||||
endif
|
||||
|
||||
# FPU-related options.
|
||||
ifeq ($(USE_FPU_OPT),)
|
||||
USE_FPU_OPT = -mfloat-abi=$(USE_FPU) -mfpu=fpv4-sp-d16
|
||||
endif
|
||||
|
||||
#
|
||||
# Architecture or project specific options
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Project, target, sources and paths
|
||||
#
|
||||
|
||||
# Define project name here
|
||||
PROJECT = ch
|
||||
|
||||
# Target settings.
|
||||
MCU = cortex-m4
|
||||
|
||||
# Imported source files and paths.
|
||||
CHIBIOS := ../../../../ChibiOS
|
||||
CHIBIOS_CONTRIB := ../../../
|
||||
CONFDIR := ./cfg
|
||||
BUILDDIR := ./build
|
||||
DEPDIR := ./.dep
|
||||
|
||||
# Licensing files.
|
||||
include $(CHIBIOS)/os/license/license.mk
|
||||
# Startup files.
|
||||
include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f4xx.mk
|
||||
# HAL-OSAL files (optional).
|
||||
include $(CHIBIOS)/os/hal/hal.mk
|
||||
include $(CHIBIOS)/os/hal/ports/STM32/STM32F4xx/platform.mk
|
||||
include $(CHIBIOS)/os/hal/boards/ST_STM32F4_DISCOVERY/board.mk
|
||||
include $(CHIBIOS)/os/hal/osal/rt/osal.mk
|
||||
# RTOS files (optional).
|
||||
include $(CHIBIOS)/os/rt/rt.mk
|
||||
include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk
|
||||
# Auto-build files in ./source recursively.
|
||||
include $(CHIBIOS)/tools/mk/autobuild.mk
|
||||
# Other files (optional).
|
||||
include $(CHIBIOS_CONTRIB)/os/common/ports/ARMCMx/compilers/GCC/utils/fault_handlers_v7m.mk
|
||||
include $(CHIBIOS)/os/hal/lib/streams/streams.mk
|
||||
|
||||
# Define linker script file here
|
||||
LDSCRIPT= $(STARTUPLD)/STM32F407xG.ld
|
||||
|
||||
# C sources that can be compiled in ARM or THUMB mode depending on the global
|
||||
# setting.
|
||||
CSRC = $(ALLCSRC) \
|
||||
$(TESTSRC) \
|
||||
main.c crash_test.c
|
||||
|
||||
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
|
||||
# setting.
|
||||
CPPSRC = $(ALLCPPSRC)
|
||||
|
||||
# List ASM source files here.
|
||||
ASMSRC = $(ALLASMSRC)
|
||||
|
||||
# List ASM with preprocessor source files here.
|
||||
ASMXSRC = $(ALLXASMSRC) crash_test_asm.S
|
||||
|
||||
# Inclusion directories.
|
||||
INCDIR = $(CONFDIR) $(ALLINC) $(TESTINC)
|
||||
|
||||
# Define C warning options here.
|
||||
CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes
|
||||
|
||||
# Define C++ warning options here.
|
||||
CPPWARN = -Wall -Wextra -Wundef
|
||||
|
||||
#
|
||||
# Project, target, sources and paths
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Start of user section
|
||||
#
|
||||
|
||||
# List all user C define here, like -D_DEBUG=1
|
||||
UDEFS = -DFAULT_INFO_HOOK=_fault_info_hook
|
||||
|
||||
# Define ASM defines here
|
||||
UADEFS =
|
||||
|
||||
# List all user directories here
|
||||
UINCDIR =
|
||||
|
||||
# List the user directory to look for the libraries here
|
||||
ULIBDIR =
|
||||
|
||||
# List all user libraries here
|
||||
ULIBS =
|
||||
|
||||
#
|
||||
# End of user section
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Common rules
|
||||
#
|
||||
|
||||
RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk
|
||||
include $(RULESPATH)/arm-none-eabi.mk
|
||||
include $(RULESPATH)/rules.mk
|
||||
|
||||
#
|
||||
# Common rules
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Custom rules
|
||||
#
|
||||
|
||||
#
|
||||
# Custom rules
|
||||
##############################################################################
|
|
@ -0,0 +1,714 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file rt/templates/chconf.h
|
||||
* @brief Configuration file template.
|
||||
* @details A copy of this file must be placed in each project directory, it
|
||||
* contains the application specific kernel settings.
|
||||
*
|
||||
* @addtogroup config
|
||||
* @details Kernel related settings and hooks.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef CHCONF_H
|
||||
#define CHCONF_H
|
||||
|
||||
#define _CHIBIOS_RT_CONF_
|
||||
#define _CHIBIOS_RT_CONF_VER_6_0_
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name System timers settings
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief System time counter resolution.
|
||||
* @note Allowed values are 16 or 32 bits.
|
||||
*/
|
||||
#if !defined(CH_CFG_ST_RESOLUTION)
|
||||
#define CH_CFG_ST_RESOLUTION 32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief System tick frequency.
|
||||
* @details Frequency of the system timer that drives the system ticks. This
|
||||
* setting also defines the system tick time unit.
|
||||
*/
|
||||
#if !defined(CH_CFG_ST_FREQUENCY)
|
||||
#define CH_CFG_ST_FREQUENCY 10000
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Time intervals data size.
|
||||
* @note Allowed values are 16, 32 or 64 bits.
|
||||
*/
|
||||
#if !defined(CH_CFG_INTERVALS_SIZE)
|
||||
#define CH_CFG_INTERVALS_SIZE 32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Time types data size.
|
||||
* @note Allowed values are 16 or 32 bits.
|
||||
*/
|
||||
#if !defined(CH_CFG_TIME_TYPES_SIZE)
|
||||
#define CH_CFG_TIME_TYPES_SIZE 32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Time delta constant for the tick-less mode.
|
||||
* @note If this value is zero then the system uses the classic
|
||||
* periodic tick. This value represents the minimum number
|
||||
* of ticks that is safe to specify in a timeout directive.
|
||||
* The value one is not valid, timeouts are rounded up to
|
||||
* this value.
|
||||
*/
|
||||
#if !defined(CH_CFG_ST_TIMEDELTA)
|
||||
#define CH_CFG_ST_TIMEDELTA 2
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name Kernel parameters and options
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Round robin interval.
|
||||
* @details This constant is the number of system ticks allowed for the
|
||||
* threads before preemption occurs. Setting this value to zero
|
||||
* disables the preemption for threads with equal priority and the
|
||||
* round robin becomes cooperative. Note that higher priority
|
||||
* threads can still preempt, the kernel is always preemptive.
|
||||
* @note Disabling the round robin preemption makes the kernel more compact
|
||||
* and generally faster.
|
||||
* @note The round robin preemption is not supported in tickless mode and
|
||||
* must be set to zero in that case.
|
||||
*/
|
||||
#if !defined(CH_CFG_TIME_QUANTUM)
|
||||
#define CH_CFG_TIME_QUANTUM 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Managed RAM size.
|
||||
* @details Size of the RAM area to be managed by the OS. If set to zero
|
||||
* then the whole available RAM is used. The core memory is made
|
||||
* available to the heap allocator and/or can be used directly through
|
||||
* the simplified core memory allocator.
|
||||
*
|
||||
* @note In order to let the OS manage the whole RAM the linker script must
|
||||
* provide the @p __heap_base__ and @p __heap_end__ symbols.
|
||||
* @note Requires @p CH_CFG_USE_MEMCORE.
|
||||
*/
|
||||
#if !defined(CH_CFG_MEMCORE_SIZE)
|
||||
#define CH_CFG_MEMCORE_SIZE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Idle thread automatic spawn suppression.
|
||||
* @details When this option is activated the function @p chSysInit()
|
||||
* does not spawn the idle thread. The application @p main()
|
||||
* function becomes the idle thread and must implement an
|
||||
* infinite loop.
|
||||
*/
|
||||
#if !defined(CH_CFG_NO_IDLE_THREAD)
|
||||
#define CH_CFG_NO_IDLE_THREAD FALSE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name Performance options
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief OS optimization.
|
||||
* @details If enabled then time efficient rather than space efficient code
|
||||
* is used when two possible implementations exist.
|
||||
*
|
||||
* @note This is not related to the compiler optimization options.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_OPTIMIZE_SPEED)
|
||||
#define CH_CFG_OPTIMIZE_SPEED TRUE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name Subsystem options
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Time Measurement APIs.
|
||||
* @details If enabled then the time measurement APIs are included in
|
||||
* the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_TM)
|
||||
#define CH_CFG_USE_TM TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Threads registry APIs.
|
||||
* @details If enabled then the registry APIs are included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_REGISTRY)
|
||||
#define CH_CFG_USE_REGISTRY TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Threads synchronization APIs.
|
||||
* @details If enabled then the @p chThdWait() function is included in
|
||||
* the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_WAITEXIT)
|
||||
#define CH_CFG_USE_WAITEXIT TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Semaphores APIs.
|
||||
* @details If enabled then the Semaphores APIs are included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_SEMAPHORES)
|
||||
#define CH_CFG_USE_SEMAPHORES TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Semaphores queuing mode.
|
||||
* @details If enabled then the threads are enqueued on semaphores by
|
||||
* priority rather than in FIFO order.
|
||||
*
|
||||
* @note The default is @p FALSE. Enable this if you have special
|
||||
* requirements.
|
||||
* @note Requires @p CH_CFG_USE_SEMAPHORES.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY)
|
||||
#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Mutexes APIs.
|
||||
* @details If enabled then the mutexes APIs are included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_MUTEXES)
|
||||
#define CH_CFG_USE_MUTEXES TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables recursive behavior on mutexes.
|
||||
* @note Recursive mutexes are heavier and have an increased
|
||||
* memory footprint.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
* @note Requires @p CH_CFG_USE_MUTEXES.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_MUTEXES_RECURSIVE)
|
||||
#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Conditional Variables APIs.
|
||||
* @details If enabled then the conditional variables APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
* @note Requires @p CH_CFG_USE_MUTEXES.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_CONDVARS)
|
||||
#define CH_CFG_USE_CONDVARS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Conditional Variables APIs with timeout.
|
||||
* @details If enabled then the conditional variables APIs with timeout
|
||||
* specification are included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
* @note Requires @p CH_CFG_USE_CONDVARS.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_CONDVARS_TIMEOUT)
|
||||
#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Events Flags APIs.
|
||||
* @details If enabled then the event flags APIs are included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_EVENTS)
|
||||
#define CH_CFG_USE_EVENTS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Events Flags APIs with timeout.
|
||||
* @details If enabled then the events APIs with timeout specification
|
||||
* are included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
* @note Requires @p CH_CFG_USE_EVENTS.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_EVENTS_TIMEOUT)
|
||||
#define CH_CFG_USE_EVENTS_TIMEOUT TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Synchronous Messages APIs.
|
||||
* @details If enabled then the synchronous messages APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_MESSAGES)
|
||||
#define CH_CFG_USE_MESSAGES TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Synchronous Messages queuing mode.
|
||||
* @details If enabled then messages are served by priority rather than in
|
||||
* FIFO order.
|
||||
*
|
||||
* @note The default is @p FALSE. Enable this if you have special
|
||||
* requirements.
|
||||
* @note Requires @p CH_CFG_USE_MESSAGES.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_MESSAGES_PRIORITY)
|
||||
#define CH_CFG_USE_MESSAGES_PRIORITY FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Mailboxes APIs.
|
||||
* @details If enabled then the asynchronous messages (mailboxes) APIs are
|
||||
* included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
* @note Requires @p CH_CFG_USE_SEMAPHORES.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_MAILBOXES)
|
||||
#define CH_CFG_USE_MAILBOXES TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Core Memory Manager APIs.
|
||||
* @details If enabled then the core memory manager APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_MEMCORE)
|
||||
#define CH_CFG_USE_MEMCORE TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Heap Allocator APIs.
|
||||
* @details If enabled then the memory heap allocator APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
* @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or
|
||||
* @p CH_CFG_USE_SEMAPHORES.
|
||||
* @note Mutexes are recommended.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_HEAP)
|
||||
#define CH_CFG_USE_HEAP TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Memory Pools Allocator APIs.
|
||||
* @details If enabled then the memory pools allocator APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_MEMPOOLS)
|
||||
#define CH_CFG_USE_MEMPOOLS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Objects FIFOs APIs.
|
||||
* @details If enabled then the objects FIFOs APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_OBJ_FIFOS)
|
||||
#define CH_CFG_USE_OBJ_FIFOS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Pipes APIs.
|
||||
* @details If enabled then the pipes APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_PIPES)
|
||||
#define CH_CFG_USE_PIPES TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Dynamic Threads APIs.
|
||||
* @details If enabled then the dynamic threads creation APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
* @note Requires @p CH_CFG_USE_WAITEXIT.
|
||||
* @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_DYNAMIC)
|
||||
#define CH_CFG_USE_DYNAMIC TRUE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name Objects factory options
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Objects Factory APIs.
|
||||
* @details If enabled then the objects factory APIs are included in the
|
||||
* kernel.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_CFG_USE_FACTORY)
|
||||
#define CH_CFG_USE_FACTORY TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maximum length for object names.
|
||||
* @details If the specified length is zero then the name is stored by
|
||||
* pointer but this could have unintended side effects.
|
||||
*/
|
||||
#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH)
|
||||
#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the registry of generic objects.
|
||||
*/
|
||||
#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY)
|
||||
#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables factory for generic buffers.
|
||||
*/
|
||||
#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS)
|
||||
#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables factory for semaphores.
|
||||
*/
|
||||
#if !defined(CH_CFG_FACTORY_SEMAPHORES)
|
||||
#define CH_CFG_FACTORY_SEMAPHORES TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables factory for mailboxes.
|
||||
*/
|
||||
#if !defined(CH_CFG_FACTORY_MAILBOXES)
|
||||
#define CH_CFG_FACTORY_MAILBOXES TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables factory for objects FIFOs.
|
||||
*/
|
||||
#if !defined(CH_CFG_FACTORY_OBJ_FIFOS)
|
||||
#define CH_CFG_FACTORY_OBJ_FIFOS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables factory for Pipes.
|
||||
*/
|
||||
#if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__)
|
||||
#define CH_CFG_FACTORY_PIPES TRUE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name Debug options
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Debug option, kernel statistics.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_STATISTICS)
|
||||
#define CH_DBG_STATISTICS FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Debug option, system state check.
|
||||
* @details If enabled the correct call protocol for system APIs is checked
|
||||
* at runtime.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_SYSTEM_STATE_CHECK)
|
||||
#define CH_DBG_SYSTEM_STATE_CHECK FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Debug option, parameters checks.
|
||||
* @details If enabled then the checks on the API functions input
|
||||
* parameters are activated.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_CHECKS)
|
||||
#define CH_DBG_ENABLE_CHECKS FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Debug option, consistency checks.
|
||||
* @details If enabled then all the assertions in the kernel code are
|
||||
* activated. This includes consistency checks inside the kernel,
|
||||
* runtime anomalies and port-defined checks.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_ASSERTS)
|
||||
#define CH_DBG_ENABLE_ASSERTS FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Debug option, trace buffer.
|
||||
* @details If enabled then the trace buffer is activated.
|
||||
*
|
||||
* @note The default is @p CH_DBG_TRACE_MASK_DISABLED.
|
||||
*/
|
||||
#if !defined(CH_DBG_TRACE_MASK)
|
||||
#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Trace buffer entries.
|
||||
* @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is
|
||||
* different from @p CH_DBG_TRACE_MASK_DISABLED.
|
||||
*/
|
||||
#if !defined(CH_DBG_TRACE_BUFFER_SIZE)
|
||||
#define CH_DBG_TRACE_BUFFER_SIZE 128
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Debug option, stack checks.
|
||||
* @details If enabled then a runtime stack check is performed.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
* @note The stack check is performed in a architecture/port dependent way.
|
||||
* It may not be implemented or some ports.
|
||||
* @note The default failure mode is to halt the system with the global
|
||||
* @p panic_msg variable set to @p NULL.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_STACK_CHECK)
|
||||
#define CH_DBG_ENABLE_STACK_CHECK FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Debug option, stacks initialization.
|
||||
* @details If enabled then the threads working area is filled with a byte
|
||||
* value when a thread is created. This can be useful for the
|
||||
* runtime measurement of the used stack.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_FILL_THREADS)
|
||||
#define CH_DBG_FILL_THREADS FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Debug option, threads profiling.
|
||||
* @details If enabled then a field is added to the @p thread_t structure that
|
||||
* counts the system ticks occurred while executing the thread.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
* @note This debug option is not currently compatible with the
|
||||
* tickless mode.
|
||||
*/
|
||||
#if !defined(CH_DBG_THREADS_PROFILING)
|
||||
#define CH_DBG_THREADS_PROFILING FALSE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name Kernel hooks
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief System structure extension.
|
||||
* @details User fields added to the end of the @p ch_system_t structure.
|
||||
*/
|
||||
#define CH_CFG_SYSTEM_EXTRA_FIELDS \
|
||||
/* Add threads custom fields here.*/
|
||||
|
||||
/**
|
||||
* @brief System initialization hook.
|
||||
* @details User initialization code added to the @p chSysInit() function
|
||||
* just before interrupts are enabled globally.
|
||||
*/
|
||||
#define CH_CFG_SYSTEM_INIT_HOOK() { \
|
||||
/* Add threads initialization code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Threads descriptor structure extension.
|
||||
* @details User fields added to the end of the @p thread_t structure.
|
||||
*/
|
||||
#define CH_CFG_THREAD_EXTRA_FIELDS \
|
||||
/* Add threads custom fields here.*/
|
||||
|
||||
/**
|
||||
* @brief Threads initialization hook.
|
||||
* @details User initialization code added to the @p _thread_init() function.
|
||||
*
|
||||
* @note It is invoked from within @p _thread_init() and implicitly from all
|
||||
* the threads creation APIs.
|
||||
*/
|
||||
#define CH_CFG_THREAD_INIT_HOOK(tp) { \
|
||||
/* Add threads initialization code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Threads finalization hook.
|
||||
* @details User finalization code added to the @p chThdExit() API.
|
||||
*/
|
||||
#define CH_CFG_THREAD_EXIT_HOOK(tp) { \
|
||||
/* Add threads finalization code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Context switch hook.
|
||||
* @details This hook is invoked just before switching between threads.
|
||||
*/
|
||||
#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \
|
||||
/* Context switch code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ISR enter hook.
|
||||
*/
|
||||
#define CH_CFG_IRQ_PROLOGUE_HOOK() { \
|
||||
/* IRQ prologue code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ISR exit hook.
|
||||
*/
|
||||
#define CH_CFG_IRQ_EPILOGUE_HOOK() { \
|
||||
/* IRQ epilogue code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Idle thread enter hook.
|
||||
* @note This hook is invoked within a critical zone, no OS functions
|
||||
* should be invoked from here.
|
||||
* @note This macro can be used to activate a power saving mode.
|
||||
*/
|
||||
#define CH_CFG_IDLE_ENTER_HOOK() { \
|
||||
/* Idle-enter code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Idle thread leave hook.
|
||||
* @note This hook is invoked within a critical zone, no OS functions
|
||||
* should be invoked from here.
|
||||
* @note This macro can be used to deactivate a power saving mode.
|
||||
*/
|
||||
#define CH_CFG_IDLE_LEAVE_HOOK() { \
|
||||
/* Idle-leave code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Idle Loop hook.
|
||||
* @details This hook is continuously invoked by the idle thread loop.
|
||||
*/
|
||||
#define CH_CFG_IDLE_LOOP_HOOK() { \
|
||||
/* Idle loop code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief System tick event hook.
|
||||
* @details This hook is invoked in the system tick handler immediately
|
||||
* after processing the virtual timers queue.
|
||||
*/
|
||||
#define CH_CFG_SYSTEM_TICK_HOOK() { \
|
||||
/* System tick event code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief System halt hook.
|
||||
* @details This hook is invoked in case to a system halting error before
|
||||
* the system is halted.
|
||||
*/
|
||||
#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \
|
||||
/* System halt code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trace hook.
|
||||
* @details This hook is invoked each time a new record is written in the
|
||||
* trace buffer.
|
||||
*/
|
||||
#define CH_CFG_TRACE_HOOK(tep) { \
|
||||
/* Trace code here.*/ \
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Port-specific settings (override port settings defaulted in chcore.h). */
|
||||
/*===========================================================================*/
|
||||
|
||||
#endif /* CHCONF_H */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,525 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file templates/halconf.h
|
||||
* @brief HAL configuration header.
|
||||
* @details HAL configuration file, this file allows to enable or disable the
|
||||
* various device drivers from your application. You may also use
|
||||
* this file in order to override the device drivers default settings.
|
||||
*
|
||||
* @addtogroup HAL_CONF
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef HALCONF_H
|
||||
#define HALCONF_H
|
||||
|
||||
#define _CHIBIOS_HAL_CONF_
|
||||
#define _CHIBIOS_HAL_CONF_VER_7_0_
|
||||
|
||||
#include "mcuconf.h"
|
||||
|
||||
/**
|
||||
* @brief Enables the PAL subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_PAL TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the ADC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_ADC FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the CAN subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_CAN FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the cryptographic subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_CRY) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_CRY FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the DAC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_DAC FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the GPT subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_GPT FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the I2C subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_I2C FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the I2S subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_I2S FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the ICU subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_ICU FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the MAC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_MAC FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the MMC_SPI subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_MMC_SPI FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the PWM subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_PWM FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the RTC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_RTC FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the SDC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SDC FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the SERIAL subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SERIAL TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the SERIAL over USB subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SERIAL_USB FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the SIO subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SIO) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SIO FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the SPI subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SPI FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the TRNG subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_TRNG) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_TRNG FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the UART subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_UART FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the USB subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_USB FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the WDG subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_WDG FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the WSPI subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_WSPI) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_WSPI FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* PAL driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(PAL_USE_CALLBACKS) || defined(__DOXYGEN__)
|
||||
#define PAL_USE_CALLBACKS FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(PAL_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define PAL_USE_WAIT FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* ADC driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define ADC_USE_WAIT TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define ADC_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* CAN driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Sleep mode related APIs inclusion switch.
|
||||
*/
|
||||
#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
|
||||
#define CAN_USE_SLEEP_MODE TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enforces the driver to use direct callbacks rather than OSAL events.
|
||||
*/
|
||||
#if !defined(CAN_ENFORCE_USE_CALLBACKS) || defined(__DOXYGEN__)
|
||||
#define CAN_ENFORCE_USE_CALLBACKS FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* CRY driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables the SW fall-back of the cryptographic driver.
|
||||
* @details When enabled, this option, activates a fall-back software
|
||||
* implementation for algorithms not supported by the underlying
|
||||
* hardware.
|
||||
* @note Fall-back implementations may not be present for all algorithms.
|
||||
*/
|
||||
#if !defined(HAL_CRY_USE_FALLBACK) || defined(__DOXYGEN__)
|
||||
#define HAL_CRY_USE_FALLBACK FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Makes the driver forcibly use the fall-back implementations.
|
||||
*/
|
||||
#if !defined(HAL_CRY_ENFORCE_FALLBACK) || defined(__DOXYGEN__)
|
||||
#define HAL_CRY_ENFORCE_FALLBACK FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* DAC driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define DAC_USE_WAIT TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define DAC_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* I2C driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables the mutual exclusion APIs on the I2C bus.
|
||||
*/
|
||||
#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define I2C_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* MAC driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables the zero-copy API.
|
||||
*/
|
||||
#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
|
||||
#define MAC_USE_ZERO_COPY FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables an event sources for incoming packets.
|
||||
*/
|
||||
#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
|
||||
#define MAC_USE_EVENTS TRUE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* MMC_SPI driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Delays insertions.
|
||||
* @details If enabled this options inserts delays into the MMC waiting
|
||||
* routines releasing some extra CPU time for the threads with
|
||||
* lower priority, this may slow down the driver a bit however.
|
||||
* This option is recommended also if the SPI driver does not
|
||||
* use a DMA channel and heavily loads the CPU.
|
||||
*/
|
||||
#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
|
||||
#define MMC_NICE_WAITING TRUE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* SDC driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Number of initialization attempts before rejecting the card.
|
||||
* @note Attempts are performed at 10mS intervals.
|
||||
*/
|
||||
#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
|
||||
#define SDC_INIT_RETRY 100
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Include support for MMC cards.
|
||||
* @note MMC support is not yet implemented so this option must be kept
|
||||
* at @p FALSE.
|
||||
*/
|
||||
#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
|
||||
#define SDC_MMC_SUPPORT FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Delays insertions.
|
||||
* @details If enabled this options inserts delays into the MMC waiting
|
||||
* routines releasing some extra CPU time for the threads with
|
||||
* lower priority, this may slow down the driver a bit however.
|
||||
*/
|
||||
#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
|
||||
#define SDC_NICE_WAITING TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief OCR initialization constant for V20 cards.
|
||||
*/
|
||||
#if !defined(SDC_INIT_OCR_V20) || defined(__DOXYGEN__)
|
||||
#define SDC_INIT_OCR_V20 0x50FF8000U
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief OCR initialization constant for non-V20 cards.
|
||||
*/
|
||||
#if !defined(SDC_INIT_OCR) || defined(__DOXYGEN__)
|
||||
#define SDC_INIT_OCR 0x80100000U
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* SERIAL driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Default bit rate.
|
||||
* @details Configuration parameter, this is the baud rate selected for the
|
||||
* default configuration.
|
||||
*/
|
||||
#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
|
||||
#define SERIAL_DEFAULT_BITRATE 38400
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Serial buffers size.
|
||||
* @details Configuration parameter, you can change the depth of the queue
|
||||
* buffers depending on the requirements of your application.
|
||||
* @note The default is 16 bytes for both the transmission and receive
|
||||
* buffers.
|
||||
*/
|
||||
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
|
||||
#define SERIAL_BUFFERS_SIZE 16
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* SERIAL_USB driver related setting. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Serial over USB buffers size.
|
||||
* @details Configuration parameter, the buffer size must be a multiple of
|
||||
* the USB data endpoint maximum packet size.
|
||||
* @note The default is 256 bytes for both the transmission and receive
|
||||
* buffers.
|
||||
*/
|
||||
#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
|
||||
#define SERIAL_USB_BUFFERS_SIZE 256
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Serial over USB number of buffers.
|
||||
* @note The default is 2 buffers.
|
||||
*/
|
||||
#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__)
|
||||
#define SERIAL_USB_BUFFERS_NUMBER 2
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* SPI driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define SPI_USE_WAIT TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables circular transfers APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(SPI_USE_CIRCULAR) || defined(__DOXYGEN__)
|
||||
#define SPI_USE_CIRCULAR FALSE
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define SPI_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Handling method for SPI CS line.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__)
|
||||
#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* UART driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define UART_USE_WAIT FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define UART_USE_MUTUAL_EXCLUSION FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* USB driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define USB_USE_WAIT FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* WSPI driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(WSPI_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define WSPI_USE_WAIT TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the @p wspiAcquireBus() and @p wspiReleaseBus() APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(WSPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define WSPI_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
|
||||
#endif /* HALCONF_H */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,342 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MCUCONF_H
|
||||
#define MCUCONF_H
|
||||
|
||||
/*
|
||||
* STM32F4xx drivers configuration.
|
||||
* The following settings override the default settings present in
|
||||
* the various device driver implementation headers.
|
||||
* Note that the settings for each driver only have effect if the whole
|
||||
* driver is enabled in halconf.h.
|
||||
*
|
||||
* IRQ priorities:
|
||||
* 15...0 Lowest...Highest.
|
||||
*
|
||||
* DMA priorities:
|
||||
* 0...3 Lowest...Highest.
|
||||
*/
|
||||
|
||||
#define STM32F4xx_MCUCONF
|
||||
|
||||
/*
|
||||
* HAL driver system settings.
|
||||
*/
|
||||
#define STM32_NO_INIT FALSE
|
||||
#define STM32_HSI_ENABLED TRUE
|
||||
#define STM32_LSI_ENABLED TRUE
|
||||
#define STM32_HSE_ENABLED TRUE
|
||||
#define STM32_LSE_ENABLED FALSE
|
||||
#define STM32_CLOCK48_REQUIRED TRUE
|
||||
#define STM32_SW STM32_SW_PLL
|
||||
#define STM32_PLLSRC STM32_PLLSRC_HSE
|
||||
#define STM32_PLLM_VALUE 8
|
||||
#define STM32_PLLN_VALUE 336
|
||||
#define STM32_PLLP_VALUE 2
|
||||
#define STM32_PLLQ_VALUE 7
|
||||
#define STM32_HPRE STM32_HPRE_DIV1
|
||||
#define STM32_PPRE1 STM32_PPRE1_DIV4
|
||||
#define STM32_PPRE2 STM32_PPRE2_DIV2
|
||||
#define STM32_RTCSEL STM32_RTCSEL_LSI
|
||||
#define STM32_RTCPRE_VALUE 8
|
||||
#define STM32_MCO1SEL STM32_MCO1SEL_HSI
|
||||
#define STM32_MCO1PRE STM32_MCO1PRE_DIV1
|
||||
#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK
|
||||
#define STM32_MCO2PRE STM32_MCO2PRE_DIV5
|
||||
#define STM32_I2SSRC STM32_I2SSRC_CKIN
|
||||
#define STM32_PLLI2SN_VALUE 192
|
||||
#define STM32_PLLI2SR_VALUE 5
|
||||
#define STM32_PVD_ENABLE FALSE
|
||||
#define STM32_PLS STM32_PLS_LEV0
|
||||
#define STM32_BKPRAM_ENABLE FALSE
|
||||
|
||||
/*
|
||||
* IRQ system settings.
|
||||
*/
|
||||
#define STM32_IRQ_EXTI0_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI1_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI2_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI3_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI4_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI5_9_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI10_15_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI16_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI17_PRIORITY 15
|
||||
#define STM32_IRQ_EXTI18_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI19_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI20_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI21_PRIORITY 15
|
||||
#define STM32_IRQ_EXTI22_PRIORITY 15
|
||||
|
||||
/*
|
||||
* ADC driver system settings.
|
||||
*/
|
||||
#define STM32_ADC_ADCPRE ADC_CCR_ADCPRE_DIV4
|
||||
#define STM32_ADC_USE_ADC1 FALSE
|
||||
#define STM32_ADC_USE_ADC2 FALSE
|
||||
#define STM32_ADC_USE_ADC3 FALSE
|
||||
#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
|
||||
#define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
|
||||
#define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
|
||||
#define STM32_ADC_ADC1_DMA_PRIORITY 2
|
||||
#define STM32_ADC_ADC2_DMA_PRIORITY 2
|
||||
#define STM32_ADC_ADC3_DMA_PRIORITY 2
|
||||
#define STM32_ADC_IRQ_PRIORITY 6
|
||||
#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 6
|
||||
#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 6
|
||||
#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 6
|
||||
|
||||
/*
|
||||
* CAN driver system settings.
|
||||
*/
|
||||
#define STM32_CAN_USE_CAN1 FALSE
|
||||
#define STM32_CAN_USE_CAN2 FALSE
|
||||
#define STM32_CAN_CAN1_IRQ_PRIORITY 11
|
||||
#define STM32_CAN_CAN2_IRQ_PRIORITY 11
|
||||
|
||||
/*
|
||||
* DAC driver system settings.
|
||||
*/
|
||||
#define STM32_DAC_DUAL_MODE FALSE
|
||||
#define STM32_DAC_USE_DAC1_CH1 FALSE
|
||||
#define STM32_DAC_USE_DAC1_CH2 FALSE
|
||||
#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10
|
||||
#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10
|
||||
#define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2
|
||||
#define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2
|
||||
#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
|
||||
#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
|
||||
|
||||
/*
|
||||
* GPT driver system settings.
|
||||
*/
|
||||
#define STM32_GPT_USE_TIM1 FALSE
|
||||
#define STM32_GPT_USE_TIM2 FALSE
|
||||
#define STM32_GPT_USE_TIM3 FALSE
|
||||
#define STM32_GPT_USE_TIM4 FALSE
|
||||
#define STM32_GPT_USE_TIM5 FALSE
|
||||
#define STM32_GPT_USE_TIM6 FALSE
|
||||
#define STM32_GPT_USE_TIM7 FALSE
|
||||
#define STM32_GPT_USE_TIM8 FALSE
|
||||
#define STM32_GPT_USE_TIM9 FALSE
|
||||
#define STM32_GPT_USE_TIM11 FALSE
|
||||
#define STM32_GPT_USE_TIM12 FALSE
|
||||
#define STM32_GPT_USE_TIM14 FALSE
|
||||
#define STM32_GPT_TIM1_IRQ_PRIORITY 7
|
||||
#define STM32_GPT_TIM2_IRQ_PRIORITY 7
|
||||
#define STM32_GPT_TIM3_IRQ_PRIORITY 7
|
||||
#define STM32_GPT_TIM4_IRQ_PRIORITY 7
|
||||
#define STM32_GPT_TIM5_IRQ_PRIORITY 7
|
||||
#define STM32_GPT_TIM6_IRQ_PRIORITY 7
|
||||
#define STM32_GPT_TIM7_IRQ_PRIORITY 7
|
||||
#define STM32_GPT_TIM8_IRQ_PRIORITY 7
|
||||
#define STM32_GPT_TIM9_IRQ_PRIORITY 7
|
||||
#define STM32_GPT_TIM11_IRQ_PRIORITY 7
|
||||
#define STM32_GPT_TIM12_IRQ_PRIORITY 7
|
||||
#define STM32_GPT_TIM14_IRQ_PRIORITY 7
|
||||
|
||||
/*
|
||||
* I2C driver system settings.
|
||||
*/
|
||||
#define STM32_I2C_USE_I2C1 FALSE
|
||||
#define STM32_I2C_USE_I2C2 FALSE
|
||||
#define STM32_I2C_USE_I2C3 FALSE
|
||||
#define STM32_I2C_BUSY_TIMEOUT 50
|
||||
#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
|
||||
#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
|
||||
#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
|
||||
#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
|
||||
#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
|
||||
#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
|
||||
#define STM32_I2C_I2C1_IRQ_PRIORITY 5
|
||||
#define STM32_I2C_I2C2_IRQ_PRIORITY 5
|
||||
#define STM32_I2C_I2C3_IRQ_PRIORITY 5
|
||||
#define STM32_I2C_I2C1_DMA_PRIORITY 3
|
||||
#define STM32_I2C_I2C2_DMA_PRIORITY 3
|
||||
#define STM32_I2C_I2C3_DMA_PRIORITY 3
|
||||
#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
|
||||
|
||||
/*
|
||||
* I2S driver system settings.
|
||||
*/
|
||||
#define STM32_I2S_USE_SPI2 FALSE
|
||||
#define STM32_I2S_USE_SPI3 FALSE
|
||||
#define STM32_I2S_SPI2_IRQ_PRIORITY 10
|
||||
#define STM32_I2S_SPI3_IRQ_PRIORITY 10
|
||||
#define STM32_I2S_SPI2_DMA_PRIORITY 1
|
||||
#define STM32_I2S_SPI3_DMA_PRIORITY 1
|
||||
#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
|
||||
#define STM32_I2S_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
|
||||
#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
|
||||
#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
|
||||
#define STM32_I2S_DMA_ERROR_HOOK(i2sp) osalSysHalt("DMA failure")
|
||||
|
||||
/*
|
||||
* ICU driver system settings.
|
||||
*/
|
||||
#define STM32_ICU_USE_TIM1 FALSE
|
||||
#define STM32_ICU_USE_TIM2 FALSE
|
||||
#define STM32_ICU_USE_TIM3 FALSE
|
||||
#define STM32_ICU_USE_TIM4 FALSE
|
||||
#define STM32_ICU_USE_TIM5 FALSE
|
||||
#define STM32_ICU_USE_TIM8 FALSE
|
||||
#define STM32_ICU_USE_TIM9 FALSE
|
||||
#define STM32_ICU_TIM1_IRQ_PRIORITY 7
|
||||
#define STM32_ICU_TIM2_IRQ_PRIORITY 7
|
||||
#define STM32_ICU_TIM3_IRQ_PRIORITY 7
|
||||
#define STM32_ICU_TIM4_IRQ_PRIORITY 7
|
||||
#define STM32_ICU_TIM5_IRQ_PRIORITY 7
|
||||
#define STM32_ICU_TIM8_IRQ_PRIORITY 7
|
||||
#define STM32_ICU_TIM9_IRQ_PRIORITY 7
|
||||
|
||||
/*
|
||||
* MAC driver system settings.
|
||||
*/
|
||||
#define STM32_MAC_TRANSMIT_BUFFERS 2
|
||||
#define STM32_MAC_RECEIVE_BUFFERS 4
|
||||
#define STM32_MAC_BUFFERS_SIZE 1522
|
||||
#define STM32_MAC_PHY_TIMEOUT 100
|
||||
#define STM32_MAC_ETH1_CHANGE_PHY_STATE TRUE
|
||||
#define STM32_MAC_ETH1_IRQ_PRIORITY 13
|
||||
#define STM32_MAC_IP_CHECKSUM_OFFLOAD 0
|
||||
|
||||
/*
|
||||
* PWM driver system settings.
|
||||
*/
|
||||
#define STM32_PWM_USE_ADVANCED FALSE
|
||||
#define STM32_PWM_USE_TIM1 FALSE
|
||||
#define STM32_PWM_USE_TIM2 FALSE
|
||||
#define STM32_PWM_USE_TIM3 FALSE
|
||||
#define STM32_PWM_USE_TIM4 FALSE
|
||||
#define STM32_PWM_USE_TIM5 FALSE
|
||||
#define STM32_PWM_USE_TIM8 FALSE
|
||||
#define STM32_PWM_USE_TIM9 FALSE
|
||||
#define STM32_PWM_TIM1_IRQ_PRIORITY 7
|
||||
#define STM32_PWM_TIM2_IRQ_PRIORITY 7
|
||||
#define STM32_PWM_TIM3_IRQ_PRIORITY 7
|
||||
#define STM32_PWM_TIM4_IRQ_PRIORITY 7
|
||||
#define STM32_PWM_TIM5_IRQ_PRIORITY 7
|
||||
#define STM32_PWM_TIM8_IRQ_PRIORITY 7
|
||||
#define STM32_PWM_TIM9_IRQ_PRIORITY 7
|
||||
|
||||
/*
|
||||
* SDC driver system settings.
|
||||
*/
|
||||
#define STM32_SDC_SDIO_DMA_PRIORITY 3
|
||||
#define STM32_SDC_SDIO_IRQ_PRIORITY 9
|
||||
#define STM32_SDC_WRITE_TIMEOUT_MS 1000
|
||||
#define STM32_SDC_READ_TIMEOUT_MS 1000
|
||||
#define STM32_SDC_CLOCK_ACTIVATION_DELAY 10
|
||||
#define STM32_SDC_SDIO_UNALIGNED_SUPPORT TRUE
|
||||
#define STM32_SDC_SDIO_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
|
||||
|
||||
/*
|
||||
* SERIAL driver system settings.
|
||||
*/
|
||||
#define STM32_SERIAL_USE_USART1 FALSE
|
||||
#define STM32_SERIAL_USE_USART2 TRUE
|
||||
#define STM32_SERIAL_USE_USART3 FALSE
|
||||
#define STM32_SERIAL_USE_UART4 FALSE
|
||||
#define STM32_SERIAL_USE_UART5 FALSE
|
||||
#define STM32_SERIAL_USE_USART6 FALSE
|
||||
#define STM32_SERIAL_USART1_PRIORITY 12
|
||||
#define STM32_SERIAL_USART2_PRIORITY 12
|
||||
#define STM32_SERIAL_USART3_PRIORITY 12
|
||||
#define STM32_SERIAL_UART4_PRIORITY 12
|
||||
#define STM32_SERIAL_UART5_PRIORITY 12
|
||||
#define STM32_SERIAL_USART6_PRIORITY 12
|
||||
|
||||
/*
|
||||
* SPI driver system settings.
|
||||
*/
|
||||
#define STM32_SPI_USE_SPI1 FALSE
|
||||
#define STM32_SPI_USE_SPI2 FALSE
|
||||
#define STM32_SPI_USE_SPI3 FALSE
|
||||
#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0)
|
||||
#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
|
||||
#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
|
||||
#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
|
||||
#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
|
||||
#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
|
||||
#define STM32_SPI_SPI1_DMA_PRIORITY 1
|
||||
#define STM32_SPI_SPI2_DMA_PRIORITY 1
|
||||
#define STM32_SPI_SPI3_DMA_PRIORITY 1
|
||||
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
|
||||
|
||||
/*
|
||||
* ST driver system settings.
|
||||
*/
|
||||
#define STM32_ST_IRQ_PRIORITY 8
|
||||
#define STM32_ST_USE_TIMER 2
|
||||
|
||||
/*
|
||||
* UART driver system settings.
|
||||
*/
|
||||
#define STM32_UART_USE_USART1 FALSE
|
||||
#define STM32_UART_USE_USART2 FALSE
|
||||
#define STM32_UART_USE_USART3 FALSE
|
||||
#define STM32_UART_USE_UART4 FALSE
|
||||
#define STM32_UART_USE_UART5 FALSE
|
||||
#define STM32_UART_USE_USART6 FALSE
|
||||
#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
|
||||
#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7)
|
||||
#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
|
||||
#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
|
||||
#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 1)
|
||||
#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
|
||||
#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
|
||||
#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
|
||||
#define STM32_UART_UART5_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
|
||||
#define STM32_UART_UART5_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
|
||||
#define STM32_UART_USART6_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
|
||||
#define STM32_UART_USART6_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7)
|
||||
#define STM32_UART_USART1_IRQ_PRIORITY 12
|
||||
#define STM32_UART_USART2_IRQ_PRIORITY 12
|
||||
#define STM32_UART_USART3_IRQ_PRIORITY 12
|
||||
#define STM32_UART_UART4_IRQ_PRIORITY 12
|
||||
#define STM32_UART_UART5_IRQ_PRIORITY 12
|
||||
#define STM32_UART_USART6_IRQ_PRIORITY 12
|
||||
#define STM32_UART_USART1_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART2_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART3_DMA_PRIORITY 0
|
||||
#define STM32_UART_UART4_DMA_PRIORITY 0
|
||||
#define STM32_UART_UART5_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART6_DMA_PRIORITY 0
|
||||
#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure")
|
||||
|
||||
/*
|
||||
* USB driver system settings.
|
||||
*/
|
||||
#define STM32_USB_USE_OTG1 FALSE
|
||||
#define STM32_USB_USE_OTG2 FALSE
|
||||
#define STM32_USB_OTG1_IRQ_PRIORITY 14
|
||||
#define STM32_USB_OTG2_IRQ_PRIORITY 14
|
||||
#define STM32_USB_OTG1_RX_FIFO_SIZE 512
|
||||
#define STM32_USB_OTG2_RX_FIFO_SIZE 1024
|
||||
#define STM32_USB_OTG_THREAD_PRIO LOWPRIO
|
||||
#define STM32_USB_OTG_THREAD_STACK_SIZE 128
|
||||
#define STM32_USB_OTGFIFO_FILL_BASEPRI 0
|
||||
|
||||
/*
|
||||
* WDG driver system settings.
|
||||
*/
|
||||
#define STM32_WDG_USE_IWDG FALSE
|
||||
|
||||
#endif /* MCUCONF_H */
|
|
@ -0,0 +1,169 @@
|
|||
/* Copyright (C) 2018 Adam Green (https://github.com/adamgreen)
|
||||
2019 Diego Ismirlian (dismirlian(at)google's mail)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This code is heavily based on the work of Adam Green (https://github.com/adamgreen)
|
||||
*/
|
||||
|
||||
|
||||
#include <ch.h>
|
||||
#include <hal.h>
|
||||
|
||||
// Assembly language routines defined in tests.S
|
||||
void testMspMultipleOf8(void);
|
||||
void testMspNotMultipleOf8(void);
|
||||
void testPspMultipleOf8(void);
|
||||
void testInitFPURegisters(void);
|
||||
void testBreakpoints(void);
|
||||
|
||||
static void enable8ByteStackAlignment(void);
|
||||
static void crashWithFPUDisabled(void);
|
||||
static void crashWithFPUAutoStackingDisabled(void);
|
||||
static void crashWithFPUAutoStackEnabled(void);
|
||||
static void crashWithFPULazyAutoStacking(void);
|
||||
|
||||
#define CRASH_CATCHER_READ_FAULT() (*(volatile unsigned int*)0x55555550)
|
||||
#define CRASH_CATCHER_WRITE_FAULT() (*(volatile unsigned int*)0x55555550 = 0x0)
|
||||
#define CRASH_CATCHER_INVALID_INSTRUCTION() { __asm volatile (".word 0xDE00"); }
|
||||
|
||||
/* Macro used to insert hardcoded breakpoint into user's code. */
|
||||
#define CRASH_CATCHER_BREAKPOINT() { __asm volatile ("bkpt #0"); }
|
||||
|
||||
int crash(int option) {
|
||||
|
||||
enable8ByteStackAlignment();
|
||||
|
||||
switch (option) {
|
||||
case 1:
|
||||
testMspMultipleOf8();
|
||||
break;
|
||||
case 2:
|
||||
testMspNotMultipleOf8();
|
||||
break;
|
||||
case 3:
|
||||
testPspMultipleOf8();
|
||||
break;
|
||||
case 4:
|
||||
CRASH_CATCHER_READ_FAULT();
|
||||
break;
|
||||
case 5:
|
||||
CRASH_CATCHER_WRITE_FAULT();
|
||||
break;
|
||||
case 6:
|
||||
crashWithFPUDisabled();
|
||||
break;
|
||||
case 7:
|
||||
crashWithFPUAutoStackingDisabled();
|
||||
break;
|
||||
case 8:
|
||||
crashWithFPUAutoStackEnabled();
|
||||
break;
|
||||
case 9:
|
||||
crashWithFPULazyAutoStacking();
|
||||
break;
|
||||
case 10:
|
||||
testBreakpoints();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void enable8ByteStackAlignment()
|
||||
{
|
||||
SCB->CCR |= SCB_CCR_STKALIGN_Msk;
|
||||
}
|
||||
|
||||
#if CORTEX_HAS_FPU
|
||||
static void disableFPU(void)
|
||||
{
|
||||
static const uint32_t FPCA = 1 << 2;
|
||||
SCB->CPACR &= ~(0xF << 20);
|
||||
__set_CONTROL(__get_CONTROL() & ~FPCA);
|
||||
}
|
||||
|
||||
static void enableFPU(void)
|
||||
{
|
||||
SCB->CPACR |= (0xF << 20);
|
||||
}
|
||||
|
||||
static void crashWithFPUDisabled(void)
|
||||
{
|
||||
disableFPU();
|
||||
__disable_irq();
|
||||
testInitFPURegisters();
|
||||
CRASH_CATCHER_READ_FAULT();
|
||||
}
|
||||
|
||||
static const uint32_t ASPEN = 1 << 31;
|
||||
static const uint32_t LSPEN = 1 << 30;
|
||||
|
||||
static void crashWithFPUAutoStackingDisabled(void)
|
||||
{
|
||||
disableFPU();
|
||||
FPU->FPCCR &= ~(ASPEN | LSPEN);
|
||||
enableFPU();
|
||||
__disable_irq();
|
||||
testInitFPURegisters();
|
||||
CRASH_CATCHER_READ_FAULT();
|
||||
}
|
||||
|
||||
static void crashWithFPUAutoStackEnabled(void)
|
||||
{
|
||||
disableFPU();
|
||||
FPU->FPCCR |= ASPEN;
|
||||
FPU->FPCCR &= ~LSPEN;
|
||||
enableFPU();
|
||||
__disable_irq();
|
||||
testInitFPURegisters();
|
||||
CRASH_CATCHER_READ_FAULT();
|
||||
}
|
||||
|
||||
static void crashWithFPULazyAutoStacking(void)
|
||||
{
|
||||
disableFPU();
|
||||
FPU->FPCCR |= (ASPEN | LSPEN);
|
||||
enableFPU();
|
||||
__disable_irq();
|
||||
testInitFPURegisters();
|
||||
CRASH_CATCHER_READ_FAULT();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void crashWithFPUDisabled(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void crashWithFPUAutoStackingDisabled(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void crashWithFPUAutoStackEnabled(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void crashWithFPULazyAutoStacking(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#endif // !defined(CORTEX_M4)
|
|
@ -0,0 +1,273 @@
|
|||
/* Copyright (C) 2018 Adam Green (https://github.com/adamgreen)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
/* Implementation of code to generate various crash scenarios for testing. */
|
||||
.text
|
||||
.syntax unified
|
||||
|
||||
.global testMspMultipleOf8
|
||||
.type testMspMultipleOf8, %function
|
||||
.thumb_func
|
||||
/* extern "C" void testMspMultipleOf8(void);
|
||||
Uses MSP and has it pointing to an even multiple of 8.
|
||||
*/
|
||||
testMspMultipleOf8:
|
||||
// Make SP, an even multiple of 8.
|
||||
mov r0, sp
|
||||
movs r1, #4
|
||||
bics r0, r1
|
||||
mov sp, r0
|
||||
// Load 0xFFFFFFFF into LR
|
||||
movs r1, #1
|
||||
rsbs r0, r1, #0
|
||||
mov lr, r0
|
||||
// Load known values into R0-R12
|
||||
movs r0, #0
|
||||
// r1 was already set correctly above when initializing LR.
|
||||
movs r2, #2
|
||||
movs r3, #3
|
||||
movs r4, #4
|
||||
movs r5, #5
|
||||
movs r6, #6
|
||||
movs r7, #7
|
||||
mov r8, r7
|
||||
mov r9, r7
|
||||
mov r10, r7
|
||||
mov r11, r7
|
||||
mov r12, r7
|
||||
add r8, r1
|
||||
add r9, r2
|
||||
add r10, r3
|
||||
add r11, r4
|
||||
add r12, r5
|
||||
// Generate a hard fault by executing an undefined instruction.
|
||||
.word 0xDE00
|
||||
// CrashCatcher_Entry() shouldn't return but if it does, just infinite loop here.
|
||||
b .
|
||||
// Let assembler know that we have hit the end of the function.
|
||||
.pool
|
||||
.size testMspMultipleOf8, .-testMspMultipleOf8
|
||||
|
||||
|
||||
.global testMspNotMultipleOf8
|
||||
.type testMspNotMultipleOf8, %function
|
||||
.thumb_func
|
||||
/* extern "C" void testMspNotMultipleOf8(void);
|
||||
Uses MSP and has it not pointing to an even multiple of 8.
|
||||
*/
|
||||
testMspNotMultipleOf8:
|
||||
// Make SP, not an even multiple of 8.
|
||||
mov r0, sp
|
||||
subs r0, #8
|
||||
movs r1, #4
|
||||
orrs r0, r1
|
||||
mov sp, r0
|
||||
// Load 0xFFFFFFFF into LR
|
||||
movs r1, #1
|
||||
rsbs r0, r1, #0
|
||||
mov lr, r0
|
||||
// Load known values into R0-R12
|
||||
movs r0, #0
|
||||
// r1 was already set correctly above when initializing LR.
|
||||
movs r2, #2
|
||||
movs r3, #3
|
||||
movs r4, #4
|
||||
movs r5, #5
|
||||
movs r6, #6
|
||||
movs r7, #7
|
||||
mov r8, r7
|
||||
mov r9, r7
|
||||
mov r10, r7
|
||||
mov r11, r7
|
||||
mov r12, r7
|
||||
add r8, r1
|
||||
add r9, r2
|
||||
add r10, r3
|
||||
add r11, r4
|
||||
add r12, r5
|
||||
// Generate a hard fault by executing an undefined instruction.
|
||||
.word 0xDE00
|
||||
// CrashCatcher_Entry() shouldn't return but if it does, just infinite loop here.
|
||||
b .
|
||||
// Let assembler know that we have hit the end of the function.
|
||||
.pool
|
||||
.size testMspNotMultipleOf8, .-testMspNotMultipleOf8
|
||||
|
||||
|
||||
.global testPspMultipleOf8
|
||||
.type testPspMultipleOf8, %function
|
||||
.thumb_func
|
||||
/* extern "C" void testPspMultipleOf8(void);
|
||||
Uses MSP and has it pointing to an even multiple of 8.
|
||||
*/
|
||||
testPspMultipleOf8:
|
||||
// Make PSP, an even multiple of 8.
|
||||
mov r0, sp
|
||||
movs r1, #4
|
||||
bics r0, r1
|
||||
msr psp, r0
|
||||
// Switch to use of PSP.
|
||||
movs r0, #3
|
||||
msr control,r0
|
||||
// Flush instructions so that control mods take effect.
|
||||
isb
|
||||
// Load 0xFFFFFFFF into LR
|
||||
movs r1, #1
|
||||
rsbs r0, r1, #0
|
||||
mov lr, r0
|
||||
// Load known values into R0-R12
|
||||
movs r0, #0
|
||||
// r1 was already set correctly above when initializing LR.
|
||||
movs r2, #2
|
||||
movs r3, #3
|
||||
movs r4, #4
|
||||
movs r5, #5
|
||||
movs r6, #6
|
||||
movs r7, #7
|
||||
mov r8, r7
|
||||
mov r9, r7
|
||||
mov r10, r7
|
||||
mov r11, r7
|
||||
mov r12, r7
|
||||
add r8, r1
|
||||
add r9, r2
|
||||
add r10, r3
|
||||
add r11, r4
|
||||
add r12, r5
|
||||
// Generate a hard fault by executing an undefined instruction.
|
||||
.word 0xDE00
|
||||
// CrashCatcher_Entry() shouldn't return but if it does, just infinite loop here.
|
||||
b .
|
||||
// Let assembler know that we have hit the end of the function.
|
||||
.pool
|
||||
.size testPspMultipleOf8, .-testPspMultipleOf8
|
||||
|
||||
|
||||
.global testBreakpoints
|
||||
.type testBreakpoints, %function
|
||||
.thumb_func
|
||||
/* extern "C" void testBreakpoints(void);
|
||||
Set registers to known values, breakpoint, allow continuation, and breakpoint again to see if anything changed.
|
||||
*/
|
||||
testBreakpoints:
|
||||
// Save away non-volatile registers that will be modified for testing.
|
||||
mov r0, r8
|
||||
mov r1, r9
|
||||
mov r2, r10
|
||||
mov r3, r11
|
||||
push {r0-r7}
|
||||
|
||||
// Load incrementing values into R0-R12
|
||||
movs r0, #0
|
||||
movs r1, #1
|
||||
movs r2, #2
|
||||
movs r3, #3
|
||||
movs r4, #4
|
||||
movs r5, #5
|
||||
movs r6, #6
|
||||
movs r7, #7
|
||||
mov r8, r7
|
||||
mov r9, r7
|
||||
mov r10, r7
|
||||
mov r11, r7
|
||||
mov r12, r7
|
||||
add r8, r1
|
||||
add r9, r2
|
||||
add r10, r3
|
||||
add r11, r4
|
||||
add r12, r5
|
||||
|
||||
// Issue one hard coded breakpoint.
|
||||
bkpt #0
|
||||
|
||||
// Issue another hard coded breakpoint and see if dumps contain same values for all registers other than PC.
|
||||
bkpt #255
|
||||
|
||||
// Restore non-volatile registers and return to caller.
|
||||
pop {r0-r7}
|
||||
mov r8, r0
|
||||
mov r9, r1
|
||||
mov r10, r2
|
||||
mov r11, r3
|
||||
bx lr
|
||||
|
||||
// Let assembler know that we have hit the end of the function.
|
||||
.pool
|
||||
.size testBreakpoints, .-testBreakpoints
|
||||
|
||||
|
||||
#if defined(TARGET_M4)
|
||||
|
||||
.global testInitFPURegisters
|
||||
.type testInitFPURegisters, %function
|
||||
.thumb_func
|
||||
/* extern "C" void testInitFPURegisters(void);
|
||||
Initialize FPU registers to known values.
|
||||
*/
|
||||
testInitFPURegisters:
|
||||
vmov.f32 s0, #-1.0
|
||||
vmov.f32 s1, #1.0
|
||||
vmov.f32 s2, #2.0
|
||||
vmov.f32 s3, #3.0
|
||||
vmov.f32 s4, #4.0
|
||||
vmov.f32 s5, #5.0
|
||||
vmov.f32 s6, #6.0
|
||||
vmov.f32 s7, #7.0
|
||||
vmov.f32 s8, #8.0
|
||||
vmov.f32 s9, #9.0
|
||||
vmov.f32 s10, #10.0
|
||||
vmov.f32 s11, #11.0
|
||||
vmov.f32 s12, #12.0
|
||||
vmov.f32 s13, #13.0
|
||||
vmov.f32 s14, #14.0
|
||||
vmov.f32 s15, #15.0
|
||||
vmov.f32 s16, #16.0
|
||||
vmov.f32 s17, #17.0
|
||||
vmov.f32 s18, #18.0
|
||||
vmov.f32 s19, #19.0
|
||||
vmov.f32 s20, #20.0
|
||||
vmov.f32 s21, #21.0
|
||||
vmov.f32 s22, #22.0
|
||||
vmov.f32 s23, #23.0
|
||||
vmov.f32 s24, #24.0
|
||||
vmov.f32 s25, #25.0
|
||||
vmov.f32 s26, #26.0
|
||||
vmov.f32 s27, #27.0
|
||||
vmov.f32 s28, #28.0
|
||||
vmov.f32 s29, #29.0
|
||||
vmov.f32 s30, #30.0
|
||||
vmov.f32 s31, #31.0
|
||||
ldr r0, =0xBAADFEED
|
||||
vmsr fpscr, r0
|
||||
bx lr
|
||||
.pool
|
||||
.size testInitFPURegisters, .-testInitFPURegisters
|
||||
|
||||
#else
|
||||
|
||||
.global testInitFPURegisters
|
||||
.type testInitFPURegisters, %function
|
||||
.thumb_func
|
||||
/* extern "C" void testInitFPURegisters(void);
|
||||
Initialize FPU registers to known values.
|
||||
*/
|
||||
testInitFPURegisters:
|
||||
bx lr
|
||||
.pool
|
||||
.size testInitFPURegisters, .-testInitFPURegisters
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
.end
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.cdt.debug.gdbjtag.launchConfigurationType">
|
||||
<stringAttribute key="bad_container_name" value="\RT-STM32F407-DISCOVERY\debug"/>
|
||||
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.delay" value="1"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.initCommands" value="set remotetimeout 20 monitor reset init monitor sleep 50 "/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="Generic TCP/IP"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
|
||||
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.runCommands" value=""/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.mi.core.DEBUG_NAME" value="arm-none-eabi-gdb"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.mi.core.commandFactory" value="Standard"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.mi.core.protocol" value="mi"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.mi.core.verboseMode" value="false"/>
|
||||
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="arm-none-eabi-gdb"/>
|
||||
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?><contentList/>"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <globalVariableList/> "/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList/> "/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="RT-STM32F407-DISCOVERY"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="0.114656749"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/RT-STM32F407-DISCOVERY"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
</listAttribute>
|
||||
</launchConfiguration>
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.cdt.debug.gdbjtag.launchConfigurationType">
|
||||
<stringAttribute key="bad_container_name" value="\RT-STM32F407-DISCOVERY\debug"/>
|
||||
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.delay" value="1"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.initCommands" value="set remotetimeout 20 monitor reset init monitor sleep 50 "/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="Generic TCP/IP"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
|
||||
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.runCommands" value=""/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.mi.core.DEBUG_NAME" value="arm-none-eabi-gdb"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.mi.core.commandFactory" value="Standard"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.mi.core.protocol" value="mi"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.mi.core.verboseMode" value="false"/>
|
||||
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="arm-none-eabi-gdb"/>
|
||||
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="0"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?><contentList><content id="r3-(format)" val="4"/><content id="vt_delta-null-chVTDoSetI-(format)" val="4"/></contentList>"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <globalVariableList/> "/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList/> "/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="RT-STM32F407-DISCOVERY"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="0.114656749"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/RT-STM32F407-DISCOVERY"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
</listAttribute>
|
||||
</launchConfiguration>
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include "fault_handlers.h"
|
||||
|
||||
int crash(int option);
|
||||
|
||||
void _fault_info_hook(const struct fault_info *info) {
|
||||
(void)info;
|
||||
/* _print_message(info->decoded_info_string); */
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
/*
|
||||
* System initializations.
|
||||
* - HAL initialization, this also initializes the configured device drivers
|
||||
* and performs the board-specific initializations.
|
||||
* - Kernel initialization, the main() function becomes a thread and the
|
||||
* RTOS is active.
|
||||
*/
|
||||
halInit();
|
||||
chSysInit();
|
||||
|
||||
/*
|
||||
1) MSP Rounded to multiple of 8 bytes.
|
||||
2) MSP Not Rounded to multiple of 8 bytes.
|
||||
3) PSP in use.
|
||||
4) Precise fault.
|
||||
5) Imprecise fault.
|
||||
6) Fault with FPU disabled.
|
||||
7) Fault with FPU auto-stacking disabled.
|
||||
8) Fault with FPU auto-stacking enabled.
|
||||
9) Fault with FPU lazy auto-stacking.
|
||||
10) Issue two breakpoints and return.
|
||||
*/
|
||||
crash(4);
|
||||
|
||||
/*
|
||||
* Activates the serial driver 2 using the driver default configuration.
|
||||
* PA2(TX) and PA3(RX) are routed to USART2.
|
||||
*/
|
||||
sdStart(&SD2, NULL);
|
||||
palSetPadMode(GPIOA, 2, PAL_MODE_ALTERNATE(7));
|
||||
palSetPadMode(GPIOA, 3, PAL_MODE_ALTERNATE(7));
|
||||
|
||||
/*
|
||||
* Normal main() thread activity, in this demo it does nothing except
|
||||
* sleeping in a loop and check the button state.
|
||||
*/
|
||||
while (true) {
|
||||
chThdSleepMilliseconds(500);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
*****************************************************************************
|
||||
** ChibiOS/RT port for ARM-Cortex-M4 STM32F407. **
|
||||
*****************************************************************************
|
||||
|
||||
** TARGET **
|
||||
|
||||
The demo runs on an ST STM32F4-Discovery board.
|
||||
|
||||
** The Demo **
|
||||
|
||||
|
||||
** Build Procedure **
|
||||
|
||||
The demo has been tested by using the free Codesourcery GCC-based toolchain
|
||||
and YAGARTO. just modify the TRGT line in the makefile in order to use
|
||||
different GCC toolchains.
|
||||
|
||||
** Notes **
|
||||
|
||||
Some files used by the demo are not part of ChibiOS/RT but are copyright of
|
||||
ST Microelectronics and are licensed under a different license.
|
||||
Also note that not all the files present in the ST library are distributed
|
||||
with ChibiOS/RT, you can find the whole library on the ST web site:
|
||||
|
||||
http://www.st.com
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2019 Diego Ismirlian (dismirlian(at)google's mail)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "fault_handlers.h"
|
||||
#include <hal.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef FAULT_NO_PRINT
|
||||
#include <chprintf.h>
|
||||
#include <memstreams.h>
|
||||
|
||||
#define fault_printf(f, ...) \
|
||||
chprintf((BaseSequentialStream *)(&ms), \
|
||||
f "\n", ##__VA_ARGS__)
|
||||
|
||||
static MemoryStream ms;
|
||||
#else
|
||||
#define fault_printf(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
static struct fault_info fault_info;
|
||||
|
||||
static void _mem_fault(void) {
|
||||
fault_printf("== Mem faults follow ==");
|
||||
|
||||
if (SCB->CFSR & SCB_CFSR_MSTKERR_Msk) {
|
||||
fault_printf("Stacking error");
|
||||
fault_info.decoded_fault_registers.memfault.stacking_error = true;
|
||||
}
|
||||
if (SCB->CFSR & SCB_CFSR_MUNSTKERR_Msk) {
|
||||
fault_printf("Unstacking error");
|
||||
fault_info.decoded_fault_registers.memfault.unstacking_error = true;
|
||||
}
|
||||
if (SCB->CFSR & SCB_CFSR_DACCVIOL_Msk) {
|
||||
fault_printf("Data Access Violation");
|
||||
fault_info.decoded_fault_registers.memfault.data_access_violation = true;
|
||||
}
|
||||
if (SCB->CFSR & SCB_CFSR_MMARVALID_Msk) {
|
||||
fault_printf("Address: 0x%08x", (uint32_t)SCB->MMFAR);
|
||||
fault_info.decoded_fault_registers.memfault.data_access_violation_address = (uint32_t)SCB->MMFAR;
|
||||
} else {
|
||||
fault_printf("Address: unknown");
|
||||
fault_info.decoded_fault_registers.memfault.data_access_violation_address = 0xffffffff;
|
||||
}
|
||||
if (SCB->CFSR & SCB_CFSR_IACCVIOL_Msk) {
|
||||
fault_printf("Instruction Access Violation");
|
||||
fault_info.decoded_fault_registers.memfault.instruction_access_violation = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void _bus_fault(void) {
|
||||
fault_printf("== Bus faults follow ==");
|
||||
|
||||
if (SCB->CFSR & SCB_CFSR_STKERR_Msk) {
|
||||
fault_printf("Stacking error");
|
||||
fault_info.decoded_fault_registers.busfault.stacking_error = true;
|
||||
}
|
||||
if (SCB->CFSR & SCB_CFSR_UNSTKERR_Msk) {
|
||||
fault_printf("Unstacking error");
|
||||
fault_info.decoded_fault_registers.busfault.unstacking_error = true;
|
||||
}
|
||||
if (SCB->CFSR & SCB_CFSR_PRECISERR_Msk) {
|
||||
fault_printf("Precise data bus error");
|
||||
fault_info.decoded_fault_registers.busfault.precise_data_bus_error = true;
|
||||
}
|
||||
if (SCB->CFSR & SCB_CFSR_BFARVALID_Msk) {
|
||||
fault_printf("Address: 0x%08x", (uint32_t)SCB->BFAR);
|
||||
fault_info.decoded_fault_registers.busfault.precise_data_bus_error_address = (uint32_t)SCB->BFAR;
|
||||
} else {
|
||||
fault_printf("Address: unknown");
|
||||
fault_info.decoded_fault_registers.busfault.precise_data_bus_error_address = 0xffffffff;
|
||||
}
|
||||
if (SCB->CFSR & SCB_CFSR_IMPRECISERR_Msk) {
|
||||
fault_printf("Imprecise data bus error");
|
||||
fault_info.decoded_fault_registers.busfault.imprecise_data_bus_error = true;
|
||||
}
|
||||
if (SCB->CFSR & SCB_CFSR_IBUSERR_Msk) {
|
||||
fault_printf("Instruction bus error");
|
||||
fault_info.decoded_fault_registers.busfault.instruction_bus_error = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void _usage_fault(void) {
|
||||
fault_printf("== Usage faults follow ==");
|
||||
|
||||
if (SCB->CFSR & SCB_CFSR_DIVBYZERO_Msk) {
|
||||
fault_printf("Division by zero");
|
||||
fault_info.decoded_fault_registers.usagefault.division_by_zero = true;
|
||||
}
|
||||
if (SCB->CFSR & SCB_CFSR_UNALIGNED_Msk) {
|
||||
fault_printf("Unaligned memory access");
|
||||
fault_info.decoded_fault_registers.usagefault.unaligned_memory_access = true;
|
||||
}
|
||||
if (SCB->CFSR & SCB_CFSR_NOCP_Msk) {
|
||||
fault_printf("No coprocessor instructions");
|
||||
fault_info.decoded_fault_registers.usagefault.no_coprocessor_instructions = true;
|
||||
}
|
||||
if (SCB->CFSR & SCB_CFSR_INVPC_Msk) {
|
||||
fault_printf("Invalid load of PC");
|
||||
fault_info.decoded_fault_registers.usagefault.invalid_load_of_pc = true;
|
||||
}
|
||||
if (SCB->CFSR & SCB_CFSR_INVSTATE_Msk) {
|
||||
fault_printf("Invalid state");
|
||||
fault_info.decoded_fault_registers.usagefault.invalid_state = true;
|
||||
}
|
||||
if (SCB->CFSR & SCB_CFSR_UNDEFINSTR_Msk) {
|
||||
fault_printf("Undefined instruction");
|
||||
fault_info.decoded_fault_registers.usagefault.undefined_instruction = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void _init_fault_info(void) {
|
||||
#ifndef FAULT_NO_PRINT
|
||||
msObjectInit(&ms,
|
||||
(uint8_t *)fault_info.decoded_info_string,
|
||||
sizeof(fault_info.decoded_info_string) - 1, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void _save_fault_info(void) {
|
||||
memset(&fault_info, 0, sizeof(fault_info));
|
||||
|
||||
if (ch.rlist.current) {
|
||||
fault_printf("Thread: 0x%08x, %s",
|
||||
ch.rlist.current, ch.rlist.current->name);
|
||||
|
||||
fault_info.decoded_fault_registers.general.current_thread_address = (uint32_t)ch.rlist.current;
|
||||
fault_info.decoded_fault_registers.general.current_thread_name = ch.rlist.current->name;
|
||||
} else {
|
||||
fault_printf("Thread: unknown");
|
||||
}
|
||||
|
||||
if (SCB->HFSR & SCB_HFSR_VECTTBL_Msk) {
|
||||
fault_printf("Bus fault on vector table read");
|
||||
fault_info.decoded_fault_registers.general.bus_fault_on_ivt_read = true;
|
||||
}
|
||||
|
||||
if (SCB->HFSR & SCB_HFSR_FORCED_Msk) {
|
||||
fault_info.decoded_fault_registers.general.escalation = true;
|
||||
_mem_fault();
|
||||
_bus_fault();
|
||||
_usage_fault();
|
||||
}
|
||||
if (!(SCB->HFSR &
|
||||
(SCB_HFSR_VECTTBL_Msk | SCB_HFSR_FORCED_Msk))) {
|
||||
fault_printf("No fault info");
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(FAULT_INFO_HOOK)
|
||||
void FAULT_INFO_HOOK(const struct fault_info *info);
|
||||
#endif
|
||||
|
||||
void _hardfault_info(void) {
|
||||
_init_fault_info();
|
||||
fault_printf("HardFault Handler");
|
||||
_save_fault_info();
|
||||
|
||||
#if defined(FAULT_INFO_HOOK)
|
||||
FAULT_INFO_HOOK(&fault_info);
|
||||
#endif
|
||||
}
|
||||
|
||||
void _hardfault_epilogue(void) __attribute__((used, naked));
|
||||
void _hardfault_epilogue(void) {
|
||||
|
||||
/* This is part of the HardFault handler
|
||||
*
|
||||
* You may inspect fault_info.decoded_fault_registers and
|
||||
* fault_info.decoded_info_string to get a description of the fault that
|
||||
* occurred.
|
||||
*
|
||||
* Also, the debugger should show an artificial call stack that led to the
|
||||
* fault. This stack is reconstructed in assembly code, until GDB includes
|
||||
* a way of automatically unwind an exception stack.
|
||||
*
|
||||
*/
|
||||
__asm volatile(
|
||||
"bkpt #0 \n"
|
||||
"b _hardfault_exit \n"
|
||||
);
|
||||
}
|
||||
|
||||
void _unhandled_exception(void) {
|
||||
/* This is an unhandled exception
|
||||
*
|
||||
* Once the breakpoint is hit, the debugger should show the ISR number
|
||||
* in the vector_number variable. Don't trust the debugger's stack unwind;
|
||||
* the _unhandled_exception ISR is shared among all undefined vectors.
|
||||
*/
|
||||
|
||||
volatile uint32_t vector_number = SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk;
|
||||
(void)vector_number;
|
||||
|
||||
__asm volatile("bkpt #0");
|
||||
|
||||
/* we are here if there is no debugger attached */
|
||||
chSysHalt("unhandled exception");
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
ALLINC += $(CHIBIOS_CONTRIB)/os/various/fault_handlers \
|
||||
$(CHIBIOS_CONTRIB)/os/common/ports/ARMCMx/compilers/GCC/utils/
|
||||
ALLCSRC += $(CHIBIOS_CONTRIB)/os/common/ports/ARMCMx/compilers/GCC/utils/fault_handlers_v7m.c
|
||||
ALLXASMSRC += $(CHIBIOS_CONTRIB)/os/common/ports/ARMCMx/compilers/GCC/utils/hardfault_handler_v7m.S
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2019 Diego Ismirlian (dismirlian(at)google's mail)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m4
|
||||
|
||||
.section .data._fault_stack
|
||||
.align 3
|
||||
_fault_stack:
|
||||
.skip 256
|
||||
_fault_stack_end:
|
||||
|
||||
.thumb
|
||||
|
||||
.section .text.HardFault_Handler
|
||||
.thumb_func
|
||||
.globl HardFault_Handler
|
||||
HardFault_Handler:
|
||||
/* disable further interrupts */
|
||||
cpsid i
|
||||
|
||||
/* preserve the ISR sp for later */
|
||||
mov r1, sp
|
||||
|
||||
/* set the sp to a separate stack, in case of sp corruption */
|
||||
ldr sp, .L1
|
||||
|
||||
/* preserve the ISR lr and sp for later */
|
||||
push {r1, lr}
|
||||
|
||||
/* print info */
|
||||
bl _hardfault_info
|
||||
|
||||
/* restore the sp and the lr */
|
||||
pop {r1, lr}
|
||||
mov sp, r1
|
||||
|
||||
/* Try to rebuild the stack for the debugger.
|
||||
* The idea is that the debugger will unwind the stack, and
|
||||
* show a call to the HardFault_Handler from the offending
|
||||
* instruction */
|
||||
|
||||
/* check which stack was in use */
|
||||
tst lr, #4 //check bit 2 of EXC_RETURN
|
||||
ite eq
|
||||
mrseq r0, msp
|
||||
mrsne r0, psp //r0 points to the stack that was in use
|
||||
|
||||
/* try to rebuild the stack for the debugger */
|
||||
mov sp, r0 //sp points to the end of the IRQ stack
|
||||
/* check if FPU registers were stacked */
|
||||
tst lr, #16 //check bit 4 of EXC_RETURN
|
||||
ite eq
|
||||
addeq sp, #104 //jump over the IRQ+FPU stack
|
||||
addne sp, #32 //jump over the IRQ stack
|
||||
|
||||
/* compensate padding */
|
||||
ldr r1, [sp, #28] //r1 = stacked xPSR
|
||||
tst r1, #512 //check bit 9 of the stacked xPSR
|
||||
ite eq
|
||||
addeq sp, #0 //add 0 to sp if there was no padding
|
||||
addne sp, #4 //add 4 to sp if there was padding
|
||||
/* here, sp finally points to the stack before the IRQ was triggered */
|
||||
|
||||
/* set lr to the stacked PC address, so the debugger can show where the
|
||||
fault was produced (may not be accurate, depending on the fault) */
|
||||
ldr lr, [r0, #24]
|
||||
|
||||
/* restore used registers */
|
||||
ldr r0, [r0, #0]
|
||||
ldr r1, [r0, #4]
|
||||
|
||||
b _hardfault_epilogue
|
||||
|
||||
.align 2
|
||||
.L1: .word _fault_stack_end
|
||||
|
||||
|
||||
.section .text._hardfault_exit
|
||||
.thumb_func
|
||||
.globl _hardfault_exit
|
||||
_hardfault_exit:
|
||||
/* we are here if there is no debugger attached */
|
||||
|
||||
/* restore the sp to the separate stack */
|
||||
ldr sp, .L3
|
||||
|
||||
/* call chSysHalt */
|
||||
ldr r0, =.L2
|
||||
bl chSysHalt
|
||||
|
||||
b .
|
||||
|
||||
.align 2
|
||||
.L3: .word _fault_stack_end
|
||||
|
||||
.align 2
|
||||
.L2: .asciz "hard fault"
|
||||
|
||||
.align 2
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2019 Diego Ismirlian (dismirlian(at)google's mail)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FAULT_HANDLERS_v7m_H_
|
||||
#define FAULT_HANDLERS_v7m_H_
|
||||
|
||||
struct decoded_fault_registers {
|
||||
struct general {
|
||||
bool bus_fault_on_ivt_read;
|
||||
bool escalation;
|
||||
uint32_t current_thread_address;
|
||||
const char *current_thread_name;
|
||||
} general;
|
||||
struct memfault {
|
||||
bool stacking_error;
|
||||
bool unstacking_error;
|
||||
bool data_access_violation;
|
||||
uint32_t data_access_violation_address;
|
||||
bool instruction_access_violation;
|
||||
} memfault;
|
||||
struct busfault {
|
||||
bool stacking_error;
|
||||
bool unstacking_error;
|
||||
bool precise_data_bus_error;
|
||||
uint32_t precise_data_bus_error_address;
|
||||
bool imprecise_data_bus_error;
|
||||
bool instruction_bus_error;
|
||||
} busfault;
|
||||
struct usagefault {
|
||||
bool division_by_zero;
|
||||
bool unaligned_memory_access;
|
||||
bool no_coprocessor_instructions;
|
||||
bool invalid_load_of_pc;
|
||||
bool invalid_state;
|
||||
bool undefined_instruction;
|
||||
} usagefault;
|
||||
};
|
||||
|
||||
#endif /* FAULT_HANDLERS_v7m_H_ */
|
|
@ -28,10 +28,8 @@ endif
|
|||
ifneq ($(findstring HAL_USE_USBH TRUE,$(HALCONF)),)
|
||||
HALSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/src/hal_usbh.c \
|
||||
${CHIBIOS_CONTRIB}/os/hal/src/usbh/hal_usbh_debug.c \
|
||||
${CHIBIOS_CONTRIB}/os/hal/src/usbh/hal_usbh_desciter.c
|
||||
endif
|
||||
ifneq ($(findstring HAL_USBH_USE_HUB TRUE,$(HALCONF)),)
|
||||
HALSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/src/usbh/hal_usbh_hub.c
|
||||
${CHIBIOS_CONTRIB}/os/hal/src/usbh/hal_usbh_desciter.c \
|
||||
${CHIBIOS_CONTRIB}/os/hal/src/usbh/hal_usbh_hub.c
|
||||
endif
|
||||
ifneq ($(findstring HAL_USBH_USE_MSD TRUE,$(HALCONF)),)
|
||||
HALSRC_CONTRIB += ${CHIBIOS_CONTRIB}/os/hal/src/usbh/hal_usbh_msd.c
|
||||
|
|
|
@ -242,6 +242,31 @@ struct usbh_port {
|
|||
_usbh_port_ll_data
|
||||
};
|
||||
|
||||
|
||||
#if USBH_DEBUG_ENABLE
|
||||
struct usbh_dq {
|
||||
int rem;
|
||||
int sz;
|
||||
uint8_t *first;
|
||||
uint8_t *next;
|
||||
uint8_t *start;
|
||||
uint8_t *end;
|
||||
};
|
||||
|
||||
typedef struct usbh_dq usbh_dq_t;
|
||||
|
||||
struct usbh_debug_helper {
|
||||
uint8_t buff[USBH_DEBUG_BUFFER];
|
||||
THD_WORKING_AREA(thd_wa, 512);
|
||||
usbh_dq_t dq;
|
||||
systime_t first;
|
||||
systime_t last;
|
||||
bool ena;
|
||||
bool on;
|
||||
thread_reference_t tr;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct USBHDriver {
|
||||
usbh_status_t status;
|
||||
uint8_t address_bitmap[(USBH_MAX_ADDRESSES + 7) / 8];
|
||||
|
@ -255,15 +280,16 @@ struct USBHDriver {
|
|||
/* Low level part */
|
||||
_usbhdriver_ll_data
|
||||
|
||||
#if USBH_DEBUG_ENABLE
|
||||
#if USBH_DEBUG_ENABLE && USBH_DEBUG_MULTI_HOST
|
||||
/* debug */
|
||||
uint8_t dbg_buff[USBH_DEBUG_BUFFER];
|
||||
THD_WORKING_AREA(waDebug, 512);
|
||||
input_queue_t iq;
|
||||
struct usbh_debug_helper debug;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#if USBH_DEBUG_ENABLE && !USBH_DEBUG_MULTI_HOST
|
||||
/* debug */
|
||||
extern struct usbh_debug_helper usbh_debug;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
|
@ -289,10 +315,10 @@ extern "C" {
|
|||
/* Device-related */
|
||||
#if USBH_DEBUG_ENABLE && USBH_DEBUG_ENABLE_INFO
|
||||
void usbhDevicePrintInfo(usbh_device_t *dev);
|
||||
void usbhDevicePrintConfiguration(const uint8_t *descriptor, uint16_t rem);
|
||||
void usbhDevicePrintConfiguration(const usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem);
|
||||
#else
|
||||
# define usbhDevicePrintInfo(dev) do {} while(0)
|
||||
# define usbhDevicePrintConfiguration(descriptor, rem) do {} while(0)
|
||||
# define usbhDevicePrintConfiguration(dev, descriptor, rem) do {} while(0)
|
||||
#endif
|
||||
bool usbhDeviceReadString(usbh_device_t *dev, char *dest, uint8_t size,
|
||||
uint8_t index, uint16_t langID);
|
||||
|
|
|
@ -24,19 +24,54 @@
|
|||
#if HAL_USE_USBH
|
||||
|
||||
#if USBH_DEBUG_ENABLE
|
||||
#if USBH_DEBUG_MULTI_HOST
|
||||
/* output callback */
|
||||
void USBH_DEBUG_OUTPUT_CALLBACK(USBHDriver *host, const uint8_t *buff, size_t len);
|
||||
|
||||
/* printing functions */
|
||||
void usbDbgPrintf(USBHDriver *host, const char *fmt, ...);
|
||||
void usbDbgPuts(USBHDriver *host, const char *s);
|
||||
void usbDbgInit(USBHDriver *host);
|
||||
#else
|
||||
/* output callback */
|
||||
void USBH_DEBUG_OUTPUT_CALLBACK(const uint8_t *buff, size_t len);
|
||||
|
||||
/* printing functions */
|
||||
void usbDbgPrintf(const char *fmt, ...);
|
||||
void usbDbgPuts(const char *s);
|
||||
void usbDbgInit(USBHDriver *host);
|
||||
void usbDbgReset(void);
|
||||
void usbDbgSystemHalted(void);
|
||||
#else
|
||||
#define usbDbgPrintf(fmt, ...) do {} while(0)
|
||||
#define usbDbgPuts(s) do {} while(0)
|
||||
#define usbDbgInit(host) do {} while(0)
|
||||
#define usbDbgReset() do {} while(0)
|
||||
#define usbDbgSystemHalted() do {} while(0)
|
||||
void usbDbgInit(void);
|
||||
#endif
|
||||
|
||||
void usbDbgReset(void);
|
||||
#else
|
||||
|
||||
#if USBH_DEBUG_MULTI_HOST
|
||||
# define usbDbgPrintf(host, fmt, ...) do {} while(0)
|
||||
# define usbDbgPuts(host, s) do {} while(0)
|
||||
# define usbDbgInit(host) do {} while(0)
|
||||
#else
|
||||
# define usbDbgPrintf(fmt, ...) do {} while(0)
|
||||
# define usbDbgPuts(s) do {} while(0)
|
||||
# define usbDbgInit() do {} while(0)
|
||||
#endif
|
||||
# define usbDbgReset() do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBH_DEBUG_MULTI_HOST
|
||||
#define _usbh_dbg(host, s) usbDbgPuts(host, s)
|
||||
#define _usbh_dbgf(host, f, ...) usbDbgPrintf(host, f, ##__VA_ARGS__)
|
||||
#define _usbh_ldbg(host, lvl, n, s) do {if (lvl >= n) usbDbgPuts(host, s); } while(0)
|
||||
#define _usbh_ldbgf(host, lvl, n, f, ...) do {if (lvl >= n) usbDbgPrintf(host, f, ##__VA_ARGS__); } while(0)
|
||||
#else
|
||||
|
||||
#define _usbh_dbg(host, s) usbDbgPuts(s)
|
||||
#define _usbh_dbgf(host, f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define _usbh_ldbg(host, lvl, n, s) do {if (lvl >= n) usbDbgPuts(s); } while(0)
|
||||
#define _usbh_ldbgf(host, lvl, n, f, ...) do {if (lvl >= n) usbDbgPrintf(f, ##__VA_ARGS__); } while(0)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* USBH_DEBUG_H_ */
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
#ifndef USBH_INTERNAL_H_
|
||||
#error "Internal use only"
|
||||
#endif
|
||||
|
||||
#ifndef _USBH_DEBUG_HELPER_ENABLE_TRACE
|
||||
#error "_USBH_DEBUG_HELPER_ENABLE_TRACE must be set"
|
||||
#endif
|
||||
#ifndef _USBH_DEBUG_HELPER_ENABLE_INFO
|
||||
#error "_USBH_DEBUG_HELPER_ENABLE_INFO must be set"
|
||||
#endif
|
||||
#ifndef _USBH_DEBUG_HELPER_ENABLE_WARNINGS
|
||||
#error "_USBH_DEBUG_HELPER_ENABLE_WARNINGS must be set"
|
||||
#endif
|
||||
#ifndef _USBH_DEBUG_HELPER_ENABLE_ERRORS
|
||||
#error "_USBH_DEBUG_HELPER_ENABLE_ERRORS must be set"
|
||||
#endif
|
||||
|
||||
#define _usbh_dbg_host(s) _usbh_dbg(host, s)
|
||||
#define _usbh_dbg_port(s) _usbh_dbg(port->device.host, s)
|
||||
#define _usbh_dbg_dev(s) _usbh_dbg(dev->host, s)
|
||||
#define _usbh_dbg_ep(lvl, s) _usbh_ldbg(ep->device->host, ep->trace_level, lvl, s)
|
||||
#define _usbh_dbg_urb(lvl, s) _usbh_ldbg(urb->ep->device->host, urb->ep->trace_level, lvl, s)
|
||||
|
||||
#define _usbh_dbgf_host(f, ...) _usbh_dbgf(host, f, ##__VA_ARGS__)
|
||||
#define _usbh_dbgf_port(f, ...) _usbh_dbgf(port->device.host, f, ##__VA_ARGS__)
|
||||
#define _usbh_dbgf_dev(f, ...) _usbh_dbgf(dev->host, f, ##__VA_ARGS__)
|
||||
#define _usbh_dbgf_ep(f, lvl, ...) _usbh_ldbgf(ep->device->host, ep->trace_level, lvl, "\t%s: " f, ep->name, ##__VA_ARGS__)
|
||||
#define _usbh_dbgf_urb(f, lvl, ...) _usbh_ldbgf(urb->ep->device->host, urb->ep->trace_level, lvl, "\t%s: " f, urb->ep->name, ##__VA_ARGS__)
|
||||
|
||||
#if defined(_USBH_DEBUG_HELPER_CLASS_DRIVER)
|
||||
#define _usbh_dbg_classdrv(drv, s) _usbh_dbg(drv->dev->host, s)
|
||||
#define _usbh_dbgf_classdrv(drv, f, ...) _usbh_dbgf(drv->dev->host, f, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define _usbh_dbg_dummy do {} while(0)
|
||||
|
||||
#if _USBH_DEBUG_HELPER_ENABLE_TRACE
|
||||
#define udbg(s) _usbh_dbg_host(s)
|
||||
#define uportdbg(s) _usbh_dbg_port(s)
|
||||
#define udevdbg(s) _usbh_dbg_dev(s)
|
||||
#define uepdbg(s) _usbh_dbg_ep(4, s)
|
||||
#define uurbdbg(s) _usbh_dbg_urb(4, s)
|
||||
#define udbgf(f, ...) _usbh_dbgf_host(f, ##__VA_ARGS__)
|
||||
#define uportdbgf(f, ...) _usbh_dbgf_port(f, ##__VA_ARGS__)
|
||||
#define udevdbgf(f, ...) _usbh_dbgf_dev(f, ##__VA_ARGS__)
|
||||
#define uepdbgf(f, ...) _usbh_dbgf_ep(f, 4, ##__VA_ARGS__)
|
||||
#define uurbdbgf(f, ...) _usbh_dbgf_urb(f, 4, ##__VA_ARGS__)
|
||||
#else
|
||||
#define udbg(s) _usbh_dbg_dummy
|
||||
#define uportdbg(s) _usbh_dbg_dummy
|
||||
#define udevdbg(s) _usbh_dbg_dummy
|
||||
#define uurbdbg(s) _usbh_dbg_dummy
|
||||
#define uepdbg(s) _usbh_dbg_dummy
|
||||
#define udbgf(f, ...) _usbh_dbg_dummy
|
||||
#define uportdbgf(f, ...) _usbh_dbg_dummy
|
||||
#define udevdbgf(f, ...) _usbh_dbg_dummy
|
||||
#define uepdbgf(f, ...) _usbh_dbg_dummy
|
||||
#define uurbdbgf(f, ...) _usbh_dbg_dummy
|
||||
#endif
|
||||
|
||||
#if _USBH_DEBUG_HELPER_ENABLE_INFO
|
||||
#define uinfo(s) _usbh_dbg_host(s)
|
||||
#define uportinfo(s) _usbh_dbg_port(s)
|
||||
#define udevinfo(s) _usbh_dbg_dev(s)
|
||||
#define uepinfo(s) _usbh_dbg_ep(3, s)
|
||||
#define uurbinfo(s) _usbh_dbg_urb(3, s)
|
||||
#define uinfof(f, ...) _usbh_dbgf_host(f, ##__VA_ARGS__)
|
||||
#define uportinfof(f, ...) _usbh_dbgf_port(f, ##__VA_ARGS__)
|
||||
#define udevinfof(f, ...) _usbh_dbgf_dev(f, ##__VA_ARGS__)
|
||||
#define uepinfof(f, ...) _usbh_dbgf_ep(f, 3, ##__VA_ARGS__)
|
||||
#define uurbinfof(f, ...) _usbh_dbgf_urb(f, 3, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uinfo(s) _usbh_dbg_dummy
|
||||
#define udevinfo(s) _usbh_dbg_dummy
|
||||
#define uportinfo(s) _usbh_dbg_dummy
|
||||
#define uepinfo(s) _usbh_dbg_dummy
|
||||
#define uurbinfo(s) _usbh_dbg_dummy
|
||||
#define uinfof(f, ...) _usbh_dbg_dummy
|
||||
#define uportinfof(f, ...) _usbh_dbg_dummy
|
||||
#define udevinfof(f, ...) _usbh_dbg_dummy
|
||||
#define uepinfof(f, ...) _usbh_dbg_dummy
|
||||
#define uurbinfof(f, ...) _usbh_dbg_dummy
|
||||
#endif
|
||||
|
||||
#if _USBH_DEBUG_HELPER_ENABLE_WARNINGS
|
||||
#define uwarn(s) _usbh_dbg_host(s)
|
||||
#define uportwarn(s) _usbh_dbg_port(s)
|
||||
#define udevwarn(s) _usbh_dbg_dev(s)
|
||||
#define uepwarn(s) _usbh_dbg_ep(3, s)
|
||||
#define uurbwarn(s) _usbh_dbg_urb(3, s)
|
||||
#define uwarnf(f, ...) _usbh_dbgf_host(f, ##__VA_ARGS__)
|
||||
#define uportwarnf(f, ...) _usbh_dbgf_port(f, ##__VA_ARGS__)
|
||||
#define udevwarnf(f, ...) _usbh_dbgf_dev(f, ##__VA_ARGS__)
|
||||
#define uepwarnf(f, ...) _usbh_dbgf_ep(f, 3, ##__VA_ARGS__)
|
||||
#define uurbwarnf(f, ...) _usbh_dbgf_urb(f, 3, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uwarn(s) _usbh_dbg_dummy
|
||||
#define udevwarn(s) _usbh_dbg_dummy
|
||||
#define uportwarn(s) _usbh_dbg_dummy
|
||||
#define uepwarn(s) _usbh_dbg_dummy
|
||||
#define uurbwarn(s) _usbh_dbg_dummy
|
||||
#define uwarnf(f, ...) _usbh_dbg_dummy
|
||||
#define uportwarnf(f, ...) _usbh_dbg_dummy
|
||||
#define udevwarnf(f, ...) _usbh_dbg_dummy
|
||||
#define uepwarnf(f, ...) _usbh_dbg_dummy
|
||||
#define uurbwarnf(f, ...) _usbh_dbg_dummy
|
||||
#endif
|
||||
|
||||
|
||||
#if _USBH_DEBUG_HELPER_ENABLE_ERRORS
|
||||
#define uerr(s) _usbh_dbg_host(s)
|
||||
#define uporterr(s) _usbh_dbg_port(s)
|
||||
#define udeverr(s) _usbh_dbg_dev(s)
|
||||
#define ueperr(s) _usbh_dbg_ep(3, s)
|
||||
#define uurberr(s) _usbh_dbg_urb(3, s)
|
||||
#define uerrf(f, ...) _usbh_dbgf_host(f, ##__VA_ARGS__)
|
||||
#define uporterrf(f, ...) _usbh_dbgf_port(f, ##__VA_ARGS__)
|
||||
#define udeverrf(f, ...) _usbh_dbgf_dev(f, ##__VA_ARGS__)
|
||||
#define ueperrf(f, ...) _usbh_dbgf_ep(f, 3, ##__VA_ARGS__)
|
||||
#define uurberrf(f, ...) _usbh_dbgf_urb(f, 3, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uerr(s) _usbh_dbg_dummy
|
||||
#define udeverr(s) _usbh_dbg_dummy
|
||||
#define uporterr(s) _usbh_dbg_dummy
|
||||
#define ueperr(s) _usbh_dbg_dummy
|
||||
#define uurberr(s) _usbh_dbg_dummy
|
||||
#define uerrf(f, ...) _usbh_dbg_dummy
|
||||
#define uporterrf(f, ...) _usbh_dbg_dummy
|
||||
#define udeverrf(f, ...) _usbh_dbg_dummy
|
||||
#define ueperrf(f, ...) _usbh_dbg_dummy
|
||||
#define uurberrf(f, ...) _usbh_dbg_dummy
|
||||
#endif
|
||||
|
||||
#if defined(_USBH_DEBUG_HELPER_CLASS_DRIVER)
|
||||
#if _USBH_DEBUG_HELPER_ENABLE_TRACE
|
||||
#define uclassdrvdbg(s) _usbh_dbg_classdrv(_USBH_DEBUG_HELPER_CLASS_DRIVER, s)
|
||||
#define uclassdrvdbgf(f, ...) _usbh_dbgf_classdrv(_USBH_DEBUG_HELPER_CLASS_DRIVER, f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uclassdrvdbg(s) _usbh_dbg_dummy
|
||||
#define uclassdrvdbgf(f, ...) _usbh_dbg_dummy
|
||||
#endif
|
||||
#if _USBH_DEBUG_HELPER_ENABLE_INFO
|
||||
#define uclassdrvinfo(s) _usbh_dbg_classdrv(_USBH_DEBUG_HELPER_CLASS_DRIVER, s)
|
||||
#define uclassdrvinfof(f, ...) _usbh_dbgf_classdrv(_USBH_DEBUG_HELPER_CLASS_DRIVER, f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uclassdrvinfo(s) _usbh_dbg_dummy
|
||||
#define uclassdrvinfof(f, ...) _usbh_dbg_dummy
|
||||
#endif
|
||||
#if _USBH_DEBUG_HELPER_ENABLE_WARNINGS
|
||||
#define uclassdrvwarn(s) _usbh_dbg_classdrv(_USBH_DEBUG_HELPER_CLASS_DRIVER, s)
|
||||
#define uclassdrvwarnf(f, ...) _usbh_dbgf_classdrv(_USBH_DEBUG_HELPER_CLASS_DRIVER, f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uclassdrvwarn(s) _usbh_dbg_dummy
|
||||
#define uclassdrvwarnf(f, ...) _usbh_dbg_dummy
|
||||
#endif
|
||||
#if _USBH_DEBUG_HELPER_ENABLE_ERRORS
|
||||
#define uclassdrverr(s) _usbh_dbg_classdrv(_USBH_DEBUG_HELPER_CLASS_DRIVER, s)
|
||||
#define uclassdrverrf(f, ...) _usbh_dbgf_classdrv(_USBH_DEBUG_HELPER_CLASS_DRIVER, f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uclassdrverr(s) _usbh_dbg_dummy
|
||||
#define uclassdrverrf(f, ...) _usbh_dbg_dummy
|
||||
#endif
|
||||
#endif
|
|
@ -130,6 +130,7 @@ typedef bool (*usbhaoa_filter_callback_t)(usbh_device_t *dev, const uint8_t *des
|
|||
#define usbhaoaGetState(aoap) ((aoap)->state)
|
||||
|
||||
#define usbhaoaGetChannelState(aoap) ((aoap)->channel.state)
|
||||
#define usbhaoaGetHost(aoap) ((aoap)->dev->host)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
|
|
|
@ -127,7 +127,7 @@ struct USBHFTDIDriver {
|
|||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
#define usbhftdipGetState(ftdipp) ((ftdipp)->state)
|
||||
|
||||
#define usbhftdipGetHost(ftdipp) ((ftdipp)->ftdip->dev->host)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
|
|
|
@ -72,7 +72,6 @@ struct USBHMassStorageLUNDriver {
|
|||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
@ -95,6 +94,8 @@ extern "C" {
|
|||
bool usbhmsdLUNGetInfo(USBHMassStorageLUNDriver *lunp, BlockDeviceInfo *bdip);
|
||||
bool usbhmsdLUNIsInserted(USBHMassStorageLUNDriver *lunp);
|
||||
bool usbhmsdLUNIsProtected(USBHMassStorageLUNDriver *lunp);
|
||||
|
||||
USBHDriver *usbhmsdLUNGetHost(const USBHMassStorageLUNDriver *lunp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -408,9 +408,9 @@ extern "C" {
|
|||
const uint8_t *framedesc, uint32_t dwFrameInterval);
|
||||
|
||||
#if USBH_DEBUG_ENABLE && USBHUVC_DEBUG_ENABLE_INFO
|
||||
void usbhuvcPrintProbeCommit(const usbh_uvc_ctrl_vs_probecommit_data_t *pc);
|
||||
void usbhuvcPrintProbeCommit(USBHUVCDriver *uvcdp, const usbh_uvc_ctrl_vs_probecommit_data_t *pc);
|
||||
#else
|
||||
# define usbhuvcPrintProbeCommit(pc) do {} while(0)
|
||||
# define usbhuvcPrintProbeCommit(uvcdp, pc) do {} while(0)
|
||||
#endif
|
||||
bool usbhuvcProbe(USBHUVCDriver *uvcdp);
|
||||
bool usbhuvcCommit(USBHUVCDriver *uvcdp);
|
||||
|
|
|
@ -67,38 +67,11 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if USBH_LLD_DEBUG_ENABLE_TRACE
|
||||
#define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define udbgf(f, ...) do {} while(0)
|
||||
#define udbg(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBH_LLD_DEBUG_ENABLE_INFO
|
||||
#define uinfof(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uinfo(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uinfof(f, ...) do {} while(0)
|
||||
#define uinfo(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBH_LLD_DEBUG_ENABLE_WARNINGS
|
||||
#define uwarnf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uwarn(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uwarnf(f, ...) do {} while(0)
|
||||
#define uwarn(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBH_LLD_DEBUG_ENABLE_ERRORS
|
||||
#define uerrf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uerr(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uerrf(f, ...) do {} while(0)
|
||||
#define uerr(f, ...) do {} while(0)
|
||||
#endif
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_TRACE USBH_LLD_DEBUG_ENABLE_TRACE
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_INFO USBH_LLD_DEBUG_ENABLE_INFO
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_WARNINGS USBH_LLD_DEBUG_ENABLE_WARNINGS
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_ERRORS USBH_LLD_DEBUG_ENABLE_ERRORS
|
||||
#include "usbh/debug_helpers.h"
|
||||
|
||||
static void _transfer_completedI(usbh_ep_t *ep, usbh_urb_t *urb, usbh_urbstatus_t status);
|
||||
static void _try_commit_np(USBHDriver *host);
|
||||
|
@ -161,7 +134,10 @@ static void _halt_channel(USBHDriver *host, stm32_hc_management_t *hcm, usbh_lld
|
|||
(void)host;
|
||||
|
||||
if (hcm->halt_reason != USBH_LLD_HALTREASON_NONE) {
|
||||
uwarnf("\t%s: Repeated halt (original=%d, new=%d)", hcm->ep->name, hcm->halt_reason, reason);
|
||||
#if USBH_DEBUG_ENABLE && USBH_LLD_DEBUG_ENABLE_WARNINGS
|
||||
usbh_ep_t *const ep = hcm->ep;
|
||||
uepwarnf("Repeated halt (original=%d, new=%d)", hcm->halt_reason, reason);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -178,17 +154,20 @@ static void _halt_channel(USBHDriver *host, stm32_hc_management_t *hcm, usbh_lld
|
|||
}
|
||||
|
||||
static void _release_channel(USBHDriver *host, stm32_hc_management_t *hcm) {
|
||||
// static const char *reason[] = {"XFRC", "XFRC", "NAK", "STALL", "ERROR", "ABORT"};
|
||||
// udbgf("\t%s: release (%s)", hcm->ep->name, reason[hcm->halt_reason]);
|
||||
usbh_ep_t *const ep = hcm->ep;
|
||||
#if USBH_DEBUG_ENABLE && USBH_LLD_DEBUG_ENABLE_TRACE
|
||||
static const char *reason[] = {"XFRC", "XFRC", "NAK", "STALL", "ERROR", "ABORT"};
|
||||
uepdbgf("release (%s)", reason[hcm->halt_reason]);
|
||||
#endif
|
||||
hcm->hc->HCINTMSK = 0;
|
||||
host->otg->HAINTMSK &= ~hcm->haintmsk;
|
||||
hcm->halt_reason = USBH_LLD_HALTREASON_NONE;
|
||||
if (usbhEPIsPeriodic(hcm->ep)) {
|
||||
if (usbhEPIsPeriodic(ep)) {
|
||||
list_add(&hcm->node, &host->ch_free[0]);
|
||||
} else {
|
||||
list_add(&hcm->node, &host->ch_free[1]);
|
||||
}
|
||||
hcm->ep->xfer.hcm = 0;
|
||||
ep->xfer.hcm = 0;
|
||||
hcm->ep = 0;
|
||||
}
|
||||
|
||||
|
@ -207,12 +186,12 @@ static bool _activate_ep(USBHDriver *host, usbh_ep_t *ep) {
|
|||
}
|
||||
|
||||
if (list_empty(list)) {
|
||||
uwarnf("\t%s: No free %s channels", ep->name, usbhEPIsPeriodic(ep) ? "P" : "NP");
|
||||
uepwarnf("No free %s channels", usbhEPIsPeriodic(ep) ? "P" : "NP");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (spc <= STM32_USBH_MIN_QSPACE) {
|
||||
uwarnf("\t%s: No space in %s Queue (spc=%d)", ep->name, usbhEPIsPeriodic(ep) ? "P" : "NP", spc);
|
||||
uepwarnf("No space in %s Queue (spc=%d)", usbhEPIsPeriodic(ep) ? "P" : "NP", spc);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -332,15 +311,15 @@ static bool _activate_ep(USBHDriver *host, usbh_ep_t *ep) {
|
|||
if (--spc > STM32_USBH_MIN_QSPACE) {
|
||||
hc->HCCHAR |= HCCHAR_CHENA;
|
||||
} else {
|
||||
uwarnf("\t%s: Could not queue back-to-back packets", ep->name);
|
||||
uepwarnf("Could not queue back-to-back packets");
|
||||
}
|
||||
}
|
||||
|
||||
if (urb->queued == FALSE) {
|
||||
urb->queued = TRUE;
|
||||
udbgf("\t%s: Start (%dB)", ep->name, xfer_len);
|
||||
uepdbgf("Start (%dB)", xfer_len);
|
||||
} else {
|
||||
udbgf("\t%s: Restart (%dB)", ep->name, xfer_len);
|
||||
uepdbgf("Restart (%dB)", xfer_len);
|
||||
}
|
||||
|
||||
ep->xfer.len = xfer_len;
|
||||
|
@ -387,7 +366,7 @@ static bool _update_urb(usbh_ep_t *ep, uint32_t hctsiz, usbh_urb_t *urb, bool co
|
|||
osalDbgAssert(urb->actualLength + len <= urb->requestedLength, "what happened?");
|
||||
#else
|
||||
if (urb->actualLength + len > urb->requestedLength) {
|
||||
uerrf("\t%s: Trimming actualLength %u -> %u", ep->name, urb->actualLength + len, urb->requestedLength);
|
||||
ueperrf("Trimming actualLength %u -> %u", urb->actualLength + len, urb->requestedLength);
|
||||
urb->actualLength = urb->requestedLength;
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -449,9 +428,9 @@ static void _purge_queue(USBHDriver *host, struct list_head *list) {
|
|||
list_for_each_entry_safe(ep, usbh_ep_t, tmp, list, node) {
|
||||
usbh_urb_t *const urb = _active_urb(ep);
|
||||
stm32_hc_management_t *const hcm = ep->xfer.hcm;
|
||||
uwarnf("\t%s: Abort URB, USBH_URBSTATUS_DISCONNECTED", ep->name);
|
||||
uepwarnf("Abort URB, USBH_URBSTATUS_DISCONNECTED");
|
||||
if (hcm) {
|
||||
uwarnf("\t%s: URB had channel %d assigned, halt_reason = %d", ep->name, hcm - host->channels, hcm->halt_reason);
|
||||
uepwarnf("URB had channel %d assigned, halt_reason = %d", hcm - host->channels, hcm->halt_reason);
|
||||
_release_channel(host, hcm);
|
||||
_update_urb(ep, hcm->hc->HCTSIZ, urb, FALSE);
|
||||
}
|
||||
|
@ -514,7 +493,7 @@ static uint32_t _write_packet(struct list_head *list, uint32_t space_available)
|
|||
|
||||
volatile uint32_t *dest = ep->xfer.hcm->fifo;
|
||||
uint32_t *src = (uint32_t *)ep->xfer.buf;
|
||||
udbgf("\t%s: write %d words (%dB), partial=%d", ep->name, words, written, ep->xfer.partial);
|
||||
uepdbgf("write %d words (%dB), partial=%d", words, written, ep->xfer.partial);
|
||||
while (words--) {
|
||||
*dest = *src++;
|
||||
}
|
||||
|
@ -589,19 +568,19 @@ void usbh_lld_ep_object_init(usbh_ep_t *ep) {
|
|||
}
|
||||
|
||||
void usbh_lld_ep_open(usbh_ep_t *ep) {
|
||||
uinfof("\t%s: Open EP", ep->name);
|
||||
uepinfof("Open EP");
|
||||
ep->status = USBH_EPSTATUS_OPEN;
|
||||
}
|
||||
|
||||
void usbh_lld_ep_close(usbh_ep_t *ep) {
|
||||
usbh_urb_t *urb;
|
||||
uinfof("\t%s: Closing EP...", ep->name);
|
||||
uepinfof("Closing EP...");
|
||||
while (!list_empty(&ep->urb_list)) {
|
||||
urb = list_first_entry(&ep->urb_list, usbh_urb_t, node);
|
||||
uinfof("\t%s: Abort URB, USBH_URBSTATUS_DISCONNECTED", ep->name);
|
||||
uepinfof("Abort URB, USBH_URBSTATUS_DISCONNECTED");
|
||||
_usbh_urb_abort_and_waitS(urb, USBH_URBSTATUS_DISCONNECTED);
|
||||
}
|
||||
uinfof("\t%s: Closed", ep->name);
|
||||
uepinfof("Closed");
|
||||
ep->status = USBH_EPSTATUS_CLOSED;
|
||||
}
|
||||
|
||||
|
@ -615,7 +594,7 @@ void usbh_lld_urb_submit(usbh_urb_t *urb) {
|
|||
USBHDriver *const host = ep->device->host;
|
||||
|
||||
if (!(host->otg->HPRT & HPRT_PENA)) {
|
||||
uwarnf("\t%s: Can't submit URB, port disabled", ep->name);
|
||||
uepwarnf("Can't submit URB, port disabled");
|
||||
_usbh_urb_completeI(urb, USBH_URBSTATUS_DISCONNECTED);
|
||||
return;
|
||||
}
|
||||
|
@ -651,20 +630,20 @@ bool usbh_lld_urb_abort(usbh_urb_t *urb, usbh_urbstatus_t status) {
|
|||
|
||||
if (hcm->halt_reason == USBH_LLD_HALTREASON_NONE) {
|
||||
/* The channel is not being halted */
|
||||
uinfof("\t%s: usbh_lld_urb_abort: channel is not being halted", hcm->ep->name);
|
||||
uepinfof("usbh_lld_urb_abort: channel is not being halted");
|
||||
urb->status = status;
|
||||
_halt_channel(ep->device->host, hcm, USBH_LLD_HALTREASON_ABORT);
|
||||
} else {
|
||||
/* The channel is being halted, so we can't re-halt it. The CHH interrupt will
|
||||
* be in charge of completing the transfer, but the URB will not have the specified status.
|
||||
*/
|
||||
uinfof("\t%s: usbh_lld_urb_abort: channel is being halted", hcm->ep->name);
|
||||
uepinfof("usbh_lld_urb_abort: channel is being halted");
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* This URB is inactive, we can cancel it now */
|
||||
uinfof("\t%s: usbh_lld_urb_abort: URB is not active", ep->name);
|
||||
uepinfof("usbh_lld_urb_abort: URB is not active");
|
||||
_transfer_completedI(ep, urb, status);
|
||||
|
||||
return TRUE;
|
||||
|
@ -679,94 +658,103 @@ bool usbh_lld_urb_abort(usbh_urb_t *urb, usbh_urbstatus_t status) {
|
|||
// si si si si si si no no ep->type != ISO && !ep->in
|
||||
static inline void _ack_int(USBHDriver *host, stm32_hc_management_t *hcm, stm32_otg_host_chn_t *hc) {
|
||||
(void)host;
|
||||
osalDbgAssert(hcm->ep->type != USBH_EPTYPE_ISO, "ACK should not happen in ISO endpoints");
|
||||
hcm->ep->xfer.error_count = 0;
|
||||
usbh_ep_t *const ep = hcm->ep;
|
||||
osalDbgAssert(ep->type != USBH_EPTYPE_ISO, "ACK should not happen in ISO endpoints");
|
||||
ep->xfer.error_count = 0;
|
||||
hc->HCINTMSK &= ~HCINTMSK_ACKM;
|
||||
udbgf("\t%s: ACK", hcm->ep->name);
|
||||
uepdbgf("ACK");
|
||||
}
|
||||
|
||||
//CTRL(IN) CTRL(OUT) INT(IN) INT(OUT) BULK(IN) BULK(OUT) ISO(IN) ISO(OUT)
|
||||
// si no si no si no no no ep->type != ISO && ep->in
|
||||
static inline void _dterr_int(USBHDriver *host, stm32_hc_management_t *hcm, stm32_otg_host_chn_t *hc) {
|
||||
(void)host;
|
||||
osalDbgAssert(hcm->ep->in && (hcm->ep->type != USBH_EPTYPE_ISO), "DTERR should not happen in OUT or ISO endpoints");
|
||||
usbh_ep_t *const ep = hcm->ep;
|
||||
osalDbgAssert(ep->in && (ep->type != USBH_EPTYPE_ISO), "DTERR should not happen in OUT or ISO endpoints");
|
||||
#if 0
|
||||
hc->HCINTMSK &= ~(HCINTMSK_DTERRM | HCINTMSK_ACKM);
|
||||
hcm->ep->xfer.error_count = 0;
|
||||
ep->xfer.error_count = 0;
|
||||
_halt_channel(host, hcm, USBH_LLD_HALTREASON_ERROR);
|
||||
#else
|
||||
/* restart directly, no need to halt it in this case */
|
||||
hcm->ep->xfer.error_count = 0;
|
||||
ep->xfer.error_count = 0;
|
||||
hc->HCINTMSK &= ~HCINTMSK_ACKM;
|
||||
hc->HCCHAR |= HCCHAR_CHENA;
|
||||
#endif
|
||||
uerrf("\t%s: DTERR", hcm->ep->name);
|
||||
ueperrf("DTERR");
|
||||
}
|
||||
|
||||
//CTRL(IN) CTRL(OUT) INT(IN) INT(OUT) BULK(IN) BULK(OUT) ISO(IN) ISO(OUT)
|
||||
// si no si no si no si no ep->in
|
||||
static inline void _bberr_int(USBHDriver *host, stm32_hc_management_t *hcm, stm32_otg_host_chn_t *hc) {
|
||||
osalDbgAssert(hcm->ep->in, "BBERR should not happen in OUT endpoints");
|
||||
usbh_ep_t *const ep = hcm->ep;
|
||||
osalDbgAssert(ep->in, "BBERR should not happen in OUT endpoints");
|
||||
hc->HCINTMSK &= ~HCINTMSK_BBERRM;
|
||||
hcm->ep->xfer.error_count = 3;
|
||||
ep->xfer.error_count = 3;
|
||||
_halt_channel(host, hcm, USBH_LLD_HALTREASON_ERROR);
|
||||
uerrf("\t%s: BBERR", hcm->ep->name);
|
||||
ueperrf("BBERR");
|
||||
}
|
||||
|
||||
///CTRL(IN) CTRL(OUT) INT(IN) INT(OUT) BULK(IN) BULK(OUT) ISO(IN) ISO(OUT)
|
||||
// si si si si si si si no ep->type != ISO || ep->in
|
||||
static inline void _trerr_int(USBHDriver *host, stm32_hc_management_t *hcm, stm32_otg_host_chn_t *hc) {
|
||||
osalDbgAssert(hcm->ep->in || (hcm->ep->type != USBH_EPTYPE_ISO), "TRERR should not happen in ISO OUT endpoints");
|
||||
usbh_ep_t *const ep = hcm->ep;
|
||||
osalDbgAssert(ep->in || (ep->type != USBH_EPTYPE_ISO), "TRERR should not happen in ISO OUT endpoints");
|
||||
hc->HCINTMSK &= ~HCINTMSK_TRERRM;
|
||||
++hcm->ep->xfer.error_count;
|
||||
++ep->xfer.error_count;
|
||||
_halt_channel(host, hcm, USBH_LLD_HALTREASON_ERROR);
|
||||
uerrf("\t%s: TRERR", hcm->ep->name);
|
||||
ueperrf("TRERR");
|
||||
}
|
||||
|
||||
//CTRL(IN) CTRL(OUT) INT(IN) INT(OUT) BULK(IN) BULK(OUT) ISO(IN) ISO(OUT)
|
||||
// no no si si no no si si ep->type = PERIODIC
|
||||
static inline void _frmor_int(USBHDriver *host, stm32_hc_management_t *hcm, stm32_otg_host_chn_t *hc) {
|
||||
osalDbgAssert(usbhEPIsPeriodic(hcm->ep), "FRMOR should not happen in non-periodic endpoints");
|
||||
usbh_ep_t *const ep = hcm->ep;
|
||||
osalDbgAssert(usbhEPIsPeriodic(ep), "FRMOR should not happen in non-periodic endpoints");
|
||||
hc->HCINTMSK &= ~HCINTMSK_FRMORM;
|
||||
hcm->ep->xfer.error_count = 3;
|
||||
ep->xfer.error_count = 3;
|
||||
_halt_channel(host, hcm, USBH_LLD_HALTREASON_ERROR);
|
||||
uerrf("\t%s: FRMOR", hcm->ep->name);
|
||||
ueperrf("FRMOR");
|
||||
}
|
||||
|
||||
//CTRL(IN) CTRL(OUT) INT(IN) INT(OUT) BULK(IN) BULK(OUT) ISO(IN) ISO(OUT)
|
||||
// si si si si si si no no ep->type != ISO
|
||||
static inline void _nak_int(USBHDriver *host, stm32_hc_management_t *hcm, stm32_otg_host_chn_t *hc) {
|
||||
usbh_ep_t *const ep = hcm->ep;
|
||||
osalDbgAssert(hcm->ep->type != USBH_EPTYPE_ISO, "NAK should not happen in ISO endpoints");
|
||||
if (!hcm->ep->in || (hcm->ep->type == USBH_EPTYPE_INT)) {
|
||||
if (!ep->in || (ep->type == USBH_EPTYPE_INT)) {
|
||||
hc->HCINTMSK &= ~HCINTMSK_NAKM;
|
||||
_halt_channel(host, hcm, USBH_LLD_HALTREASON_NAK);
|
||||
} else {
|
||||
/* restart directly, no need to halt it in this case */
|
||||
hcm->ep->xfer.error_count = 0;
|
||||
ep->xfer.error_count = 0;
|
||||
hc->HCINTMSK &= ~HCINTMSK_ACKM;
|
||||
hc->HCCHAR |= HCCHAR_CHENA;
|
||||
}
|
||||
udbgf("\t%s: NAK", hcm->ep->name);
|
||||
uepdbgf("NAK");
|
||||
}
|
||||
|
||||
//CTRL(IN) CTRL(OUT) INT(IN) INT(OUT) BULK(IN) BULK(OUT) ISO(IN) ISO(OUT)
|
||||
// si sólo DAT/STAT si si si si no no ep->type != ISO && (ep->type != CTRL || ctrlphase != SETUP)
|
||||
// si solo DAT/STAT si si si si no no ep->type != ISO && (ep->type != CTRL || ctrlphase != SETUP)
|
||||
static inline void _stall_int(USBHDriver *host, stm32_hc_management_t *hcm, stm32_otg_host_chn_t *hc) {
|
||||
osalDbgAssert(hcm->ep->type != USBH_EPTYPE_ISO, "STALL should not happen in ISO endpoints");
|
||||
hc->HCINTMSK &= ~HCINTMSK_STALLM;
|
||||
_halt_channel(host, hcm, USBH_LLD_HALTREASON_STALL);
|
||||
uwarnf("\t%s: STALL", hcm->ep->name);
|
||||
#if USBH_DEBUG_ENABLE && USBH_LLD_DEBUG_ENABLE_WARNINGS
|
||||
usbh_ep_t *const ep = hcm->ep;
|
||||
uepwarnf("STALL");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void _complete_bulk_int(USBHDriver *host, stm32_hc_management_t *hcm, usbh_ep_t *ep, usbh_urb_t *urb, uint32_t hctsiz) {
|
||||
_release_channel(host, hcm);
|
||||
_save_dt_mask(ep, hctsiz);
|
||||
if (_update_urb(ep, hctsiz, urb, TRUE)) {
|
||||
udbgf("\t%s: done", ep->name);
|
||||
uepdbgf("done");
|
||||
_transfer_completedI(ep, urb, USBH_URBSTATUS_OK);
|
||||
} else {
|
||||
osalDbgCheck(urb->requestedLength > 0x7FFFF);
|
||||
uwarnf("\t%s: incomplete", ep->name);
|
||||
uepwarnf("incomplete");
|
||||
_move_to_pending_queue(ep);
|
||||
}
|
||||
if (usbhEPIsPeriodic(ep)) {
|
||||
|
@ -782,18 +770,18 @@ static void _complete_control(USBHDriver *host, stm32_hc_management_t *hcm, usbh
|
|||
_release_channel(host, hcm);
|
||||
if (ep->xfer.u.ctrl_phase == USBH_LLD_CTRLPHASE_DATA) {
|
||||
if (_update_urb(ep, hctsiz, urb, TRUE)) {
|
||||
udbgf("\t%s: DATA done", ep->name);
|
||||
uepdbgf("DATA done");
|
||||
ep->xfer.u.ctrl_phase = USBH_LLD_CTRLPHASE_STATUS;
|
||||
ep->in = !ep->in;
|
||||
} else {
|
||||
osalDbgCheck(urb->requestedLength > 0x7FFFF);
|
||||
uwarnf("\t%s: DATA incomplete", ep->name);
|
||||
uepwarnf("DATA incomplete");
|
||||
_save_dt_mask(ep, hctsiz);
|
||||
}
|
||||
_move_to_pending_queue(ep);
|
||||
} else {
|
||||
osalDbgCheck(ep->xfer.u.ctrl_phase == USBH_LLD_CTRLPHASE_STATUS);
|
||||
udbgf("\t%s: STATUS done", ep->name);
|
||||
uepdbgf("STATUS done");
|
||||
_transfer_completedI(ep, urb, USBH_URBSTATUS_OK);
|
||||
}
|
||||
_try_commit_np(host);
|
||||
|
@ -802,13 +790,13 @@ static void _complete_control(USBHDriver *host, stm32_hc_management_t *hcm, usbh
|
|||
static void _complete_control_setup(USBHDriver *host, stm32_hc_management_t *hcm, usbh_ep_t *ep, usbh_urb_t *urb) {
|
||||
_release_channel(host, hcm);
|
||||
if (urb->requestedLength) {
|
||||
udbgf("\t%s: SETUP done -> DATA", ep->name);
|
||||
uepdbgf("SETUP done -> DATA");
|
||||
ep->xfer.u.ctrl_phase = USBH_LLD_CTRLPHASE_DATA;
|
||||
ep->in = *((uint8_t *)urb->setup_buff) & 0x80 ? TRUE : FALSE;
|
||||
ep->dt_mask = HCTSIZ_DPID_DATA1;
|
||||
ep->xfer.error_count = 0;
|
||||
} else {
|
||||
udbgf("\t%s: SETUP done -> STATUS", ep->name);
|
||||
uepdbgf("SETUP done -> STATUS");
|
||||
ep->in = TRUE;
|
||||
ep->xfer.u.ctrl_phase = USBH_LLD_CTRLPHASE_STATUS;
|
||||
}
|
||||
|
@ -817,7 +805,7 @@ static void _complete_control_setup(USBHDriver *host, stm32_hc_management_t *hcm
|
|||
}
|
||||
|
||||
static void _complete_iso(USBHDriver *host, stm32_hc_management_t *hcm, usbh_ep_t *ep, usbh_urb_t *urb, uint32_t hctsiz) {
|
||||
udbgf("\t%s: done", hcm->ep->name);
|
||||
uepdbgf("done");
|
||||
_release_channel(host, hcm);
|
||||
_update_urb(ep, hctsiz, urb, TRUE);
|
||||
_transfer_completedI(ep, urb, USBH_URBSTATUS_OK);
|
||||
|
@ -915,7 +903,7 @@ static inline void _chh_int(USBHDriver *host, stm32_hc_management_t *hcm, stm32_
|
|||
case USBH_LLD_HALTREASON_STALL:
|
||||
if (ep->type == USBH_EPTYPE_CTRL) {
|
||||
if (ep->xfer.u.ctrl_phase == USBH_LLD_CTRLPHASE_SETUP) {
|
||||
uerrf("\t%s: Faulty device: STALLed SETUP phase", ep->name);
|
||||
ueperrf("Faulty device: STALLed SETUP phase");
|
||||
}
|
||||
} else {
|
||||
ep->status = USBH_EPSTATUS_HALTED;
|
||||
|
@ -927,13 +915,13 @@ static inline void _chh_int(USBHDriver *host, stm32_hc_management_t *hcm, stm32_
|
|||
if ((ep->type == USBH_EPTYPE_ISO) || done || (ep->xfer.error_count >= 3)) {
|
||||
_transfer_completedI(ep, urb, USBH_URBSTATUS_ERROR);
|
||||
} else {
|
||||
uerrf("\t%s: err=%d, done=%d, retry", ep->name, ep->xfer.error_count, done);
|
||||
ueperrf("err=%d, done=%d, retry", ep->xfer.error_count, done);
|
||||
_move_to_pending_queue(ep);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBH_LLD_HALTREASON_ABORT:
|
||||
uwarnf("\t%s: Abort", ep->name);
|
||||
uepwarnf("Abort");
|
||||
_transfer_completedI(ep, urb, urb->status);
|
||||
break;
|
||||
|
||||
|
@ -1094,8 +1082,7 @@ static inline void _rxflvl_int(USBHDriver *host) {
|
|||
hcm->hc->HCCHAR |= HCCHAR_CHENA;
|
||||
}
|
||||
|
||||
udbgf("\t%s: RXFLVL rx=%dB, rem=%dB (%dpkts)",
|
||||
ep->name,
|
||||
uepdbgf("RXFLVL rx=%dB, rem=%dB (%dpkts)",
|
||||
(grxstsp & GRXSTSP_BCNT_MASK) >> 4,
|
||||
(hctsiz & HCTSIZ_XFRSIZ_MASK),
|
||||
(hctsiz & HCTSIZ_PKTCNT_MASK) >> 19);
|
||||
|
@ -1131,7 +1118,7 @@ static inline void _rxflvl_int(USBHDriver *host) {
|
|||
uint32_t pkt = (hctsiz & HCTSIZ_PKTCNT_MASK) >> 19;
|
||||
uint32_t siz = (hctsiz & HCTSIZ_XFRSIZ_MASK);
|
||||
if (pkt * ep->wMaxPacketSize != siz) {
|
||||
uerrf("\t%s: whatttt???", ep->name);
|
||||
ueperrf("whatttt???");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1479,13 +1466,13 @@ void usbh_lld_init(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static void _usbh_start(USBHDriver *usbh) {
|
||||
stm32_otg_t *const otgp = usbh->otg;
|
||||
static void _usbh_start(USBHDriver *host) {
|
||||
stm32_otg_t *const otgp = host->otg;
|
||||
|
||||
/* Clock activation.*/
|
||||
#if STM32_USBH_USE_OTG1
|
||||
#if STM32_USBH_USE_OTG2
|
||||
if (&USBHD1 == usbh)
|
||||
if (&USBHD1 == host)
|
||||
#endif
|
||||
{
|
||||
/* OTG FS clock enable and reset.*/
|
||||
|
@ -1501,7 +1488,7 @@ static void _usbh_start(USBHDriver *usbh) {
|
|||
|
||||
#if STM32_USBH_USE_OTG2
|
||||
#if STM32_USBH_USE_OTG1
|
||||
if (&USBHD2 == usbh)
|
||||
if (&USBHD2 == host)
|
||||
#endif
|
||||
{
|
||||
/* OTG HS clock enable and reset.*/
|
||||
|
@ -1518,7 +1505,7 @@ static void _usbh_start(USBHDriver *usbh) {
|
|||
|
||||
otgp->GUSBCFG = GUSBCFG_PHYSEL | GUSBCFG_TRDT(5);
|
||||
|
||||
otg_core_reset(usbh);
|
||||
otg_core_reset(host);
|
||||
|
||||
otgp->GCCFG = GCCFG_PWRDWN;
|
||||
|
||||
|
@ -1553,28 +1540,28 @@ static void _usbh_start(USBHDriver *usbh) {
|
|||
|
||||
otgp->HPRT |= HPRT_PPWR;
|
||||
|
||||
otg_txfifo_flush(usbh, 0x10);
|
||||
otg_rxfifo_flush(usbh);
|
||||
otg_txfifo_flush(host, 0x10);
|
||||
otg_rxfifo_flush(host);
|
||||
|
||||
otgp->GINTSTS = 0xffffffff;
|
||||
otgp->GINTMSK = GINTMSK_DISCM | GINTMSK_HPRTM | GINTMSK_MMISM;
|
||||
|
||||
usbh->rootport.lld_status = USBH_PORTSTATUS_POWER;
|
||||
usbh->rootport.lld_c_status = 0;
|
||||
host->rootport.lld_status = USBH_PORTSTATUS_POWER;
|
||||
host->rootport.lld_c_status = 0;
|
||||
|
||||
/* Global interrupts enable.*/
|
||||
otgp->GAHBCFG |= GAHBCFG_GINTMSK;
|
||||
}
|
||||
|
||||
void usbh_lld_start(USBHDriver *usbh) {
|
||||
if (usbh->status != USBH_STATUS_STOPPED) return;
|
||||
_usbh_start(usbh);
|
||||
void usbh_lld_start(USBHDriver *host) {
|
||||
if (host->status != USBH_STATUS_STOPPED) return;
|
||||
_usbh_start(host);
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Root Hub request handler. */
|
||||
/*===========================================================================*/
|
||||
usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestType, uint8_t bRequest,
|
||||
usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *host, uint8_t bmRequestType, uint8_t bRequest,
|
||||
uint16_t wvalue, uint16_t windex, uint16_t wlength, uint8_t *buf) {
|
||||
|
||||
uint16_t typereq = (bmRequestType << 8) | bRequest;
|
||||
|
@ -1606,23 +1593,23 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy
|
|||
break;
|
||||
|
||||
case USBH_PORT_FEAT_C_CONNECTION:
|
||||
usbh->rootport.lld_c_status &= ~USBH_PORTSTATUS_C_CONNECTION;
|
||||
host->rootport.lld_c_status &= ~USBH_PORTSTATUS_C_CONNECTION;
|
||||
break;
|
||||
|
||||
case USBH_PORT_FEAT_C_RESET:
|
||||
usbh->rootport.lld_c_status &= ~USBH_PORTSTATUS_C_RESET;
|
||||
host->rootport.lld_c_status &= ~USBH_PORTSTATUS_C_RESET;
|
||||
break;
|
||||
|
||||
case USBH_PORT_FEAT_C_ENABLE:
|
||||
usbh->rootport.lld_c_status &= ~USBH_PORTSTATUS_C_ENABLE;
|
||||
host->rootport.lld_c_status &= ~USBH_PORTSTATUS_C_ENABLE;
|
||||
break;
|
||||
|
||||
case USBH_PORT_FEAT_C_SUSPEND:
|
||||
usbh->rootport.lld_c_status &= ~USBH_PORTSTATUS_C_SUSPEND;
|
||||
host->rootport.lld_c_status &= ~USBH_PORTSTATUS_C_SUSPEND;
|
||||
break;
|
||||
|
||||
case USBH_PORT_FEAT_C_OVERCURRENT:
|
||||
usbh->rootport.lld_c_status &= ~USBH_PORTSTATUS_C_OVERCURRENT;
|
||||
host->rootport.lld_c_status &= ~USBH_PORTSTATUS_C_OVERCURRENT;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1645,7 +1632,7 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy
|
|||
osalDbgAssert(windex == 1, "invalid windex");
|
||||
osalDbgCheck(wlength >= 4);
|
||||
osalSysLock();
|
||||
*(uint32_t *)buf = usbh->rootport.lld_status | (usbh->rootport.lld_c_status << 16);
|
||||
*(uint32_t *)buf = host->rootport.lld_status | (host->rootport.lld_c_status << 16);
|
||||
osalSysUnlock();
|
||||
break;
|
||||
|
||||
|
@ -1665,7 +1652,7 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy
|
|||
|
||||
case USBH_PORT_FEAT_RESET: {
|
||||
osalSysLock();
|
||||
stm32_otg_t *const otg = usbh->otg;
|
||||
stm32_otg_t *const otg = host->otg;
|
||||
uint32_t hprt;
|
||||
otg->PCGCCTL = 0;
|
||||
hprt = otg->HPRT;
|
||||
|
@ -1675,14 +1662,14 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy
|
|||
uerr("Detected enabled port; resetting OTG core");
|
||||
otg->GAHBCFG = 0;
|
||||
osalThreadSleepS(OSAL_MS2I(20));
|
||||
_usbh_start(usbh); /* this effectively resets the core */
|
||||
_usbh_start(host); /* this effectively resets the core */
|
||||
osalThreadSleepS(OSAL_MS2I(100)); /* during this delay, the core generates connect ISR */
|
||||
uinfo("OTG reset ended");
|
||||
if (otg->HPRT & HPRT_PCSTS) {
|
||||
/* if the device is still connected, don't report a C_CONNECTION flag, which would cause
|
||||
* the upper layer to abort enumeration */
|
||||
uinfo("Clear connection change flag");
|
||||
usbh->rootport.lld_c_status &= ~USBH_PORTSTATUS_C_CONNECTION;
|
||||
host->rootport.lld_c_status &= ~USBH_PORTSTATUS_C_CONNECTION;
|
||||
}
|
||||
}
|
||||
/* note: writing PENA = 1 actually disables the port */
|
||||
|
@ -1692,7 +1679,7 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy
|
|||
osalThreadSleepS(OSAL_MS2I(15));
|
||||
otg->HPRT = hprt;
|
||||
osalThreadSleepS(OSAL_MS2I(10));
|
||||
usbh->rootport.lld_c_status |= USBH_PORTSTATUS_C_RESET;
|
||||
host->rootport.lld_c_status |= USBH_PORTSTATUS_C_RESET;
|
||||
osalSysUnlock();
|
||||
} break;
|
||||
|
||||
|
@ -1714,8 +1701,8 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy
|
|||
return USBH_URBSTATUS_OK;
|
||||
}
|
||||
|
||||
uint8_t usbh_lld_roothub_get_statuschange_bitmap(USBHDriver *usbh) {
|
||||
return usbh->rootport.lld_c_status ? (1 << 1) : 0;
|
||||
uint8_t usbh_lld_roothub_get_statuschange_bitmap(USBHDriver *host) {
|
||||
return host->rootport.lld_c_status ? (1 << 1) : 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -83,6 +83,7 @@ typedef struct stm32_hc_management {
|
|||
uint32_t hcintmsk; \
|
||||
uint32_t hcchar; \
|
||||
uint32_t dt_mask; /* data-toggle mask */ \
|
||||
int32_t trace_level; /* enable tracing */ \
|
||||
/* current transfer */ \
|
||||
struct { \
|
||||
stm32_hc_management_t *hcm; /* assigned channel */ \
|
||||
|
|
|
@ -23,36 +23,15 @@
|
|||
#include "usbh/dev/hub.h"
|
||||
#include <string.h>
|
||||
|
||||
#if USBH_DEBUG_ENABLE_TRACE
|
||||
#define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define udbgf(f, ...) do {} while(0)
|
||||
#define udbg(f, ...) do {} while(0)
|
||||
#endif
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_TRACE USBH_DEBUG_ENABLE_TRACE
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_INFO USBH_DEBUG_ENABLE_INFO
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_WARNINGS USBH_DEBUG_ENABLE_WARNINGS
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_ERRORS USBH_DEBUG_ENABLE_ERRORS
|
||||
#include "usbh/debug_helpers.h"
|
||||
|
||||
#if USBH_DEBUG_ENABLE_INFO
|
||||
#define uinfof(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uinfo(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uinfof(f, ...) do {} while(0)
|
||||
#define uinfo(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBH_DEBUG_ENABLE_WARNINGS
|
||||
#define uwarnf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uwarn(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uwarnf(f, ...) do {} while(0)
|
||||
#define uwarn(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBH_DEBUG_ENABLE_ERRORS
|
||||
#define uerrf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uerr(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uerrf(f, ...) do {} while(0)
|
||||
#define uerr(f, ...) do {} while(0)
|
||||
#if USBH_DEBUG_ENABLE && !USBH_DEBUG_MULTI_HOST
|
||||
/* debug */
|
||||
struct usbh_debug_helper usbh_debug;
|
||||
#endif
|
||||
|
||||
static void _classdriver_process_device(usbh_device_t *dev);
|
||||
|
@ -104,7 +83,11 @@ void usbhObjectInit(USBHDriver *usbh) {
|
|||
}
|
||||
|
||||
void usbhStart(USBHDriver *usbh) {
|
||||
#if USBH_DEBUG_MULTI_HOST
|
||||
usbDbgInit(usbh);
|
||||
#else
|
||||
usbDbgInit();
|
||||
#endif
|
||||
|
||||
osalSysLock();
|
||||
osalDbgAssert((usbh->status == USBH_STATUS_STOPPED) || (usbh->status == USBH_STATUS_STARTED),
|
||||
|
@ -264,7 +247,7 @@ void _usbh_urb_abort_and_waitS(usbh_urb_t *urb, usbh_urbstatus_t status) {
|
|||
_check_urb(urb);
|
||||
|
||||
if (_usbh_urb_abortI(urb, status) == FALSE) {
|
||||
uwarn("URB wasn't aborted immediately, suspend");
|
||||
uurbwarn("URB wasn't aborted immediately, suspend");
|
||||
osalThreadSuspendS(&urb->abortingThread);
|
||||
osalDbgAssert(urb->abortingThread == 0, "maybe we should uncomment the line below");
|
||||
//urb->abortingThread = 0;
|
||||
|
@ -272,7 +255,7 @@ void _usbh_urb_abort_and_waitS(usbh_urb_t *urb, usbh_urbstatus_t status) {
|
|||
/* This call is necessary because _usbh_urb_abortI may require a reschedule */
|
||||
osalOsRescheduleS();
|
||||
}
|
||||
uwarn("URB aborted");
|
||||
uurbwarn("URB aborted");
|
||||
}
|
||||
|
||||
/* usbhURBCancelI may require a reschedule if called from a S-locked state */
|
||||
|
@ -607,26 +590,26 @@ static bool _device_set_configuration(usbh_device_t *dev, uint8_t configuration)
|
|||
static bool _device_configure(usbh_device_t *dev, uint8_t bConfiguration) {
|
||||
uint8_t i;
|
||||
|
||||
uinfof("Reading basic configuration descriptor %d", bConfiguration);
|
||||
udevinfof("Reading basic configuration descriptor %d", bConfiguration);
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (!_device_read_basic_cfgdesc(dev, bConfiguration))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == 3) {
|
||||
uerrf("Could not read basic configuration descriptor %d; "
|
||||
udeverrf("Could not read basic configuration descriptor %d; "
|
||||
"won't configure device", bConfiguration);
|
||||
return HAL_FAILED;
|
||||
}
|
||||
|
||||
uinfof("Selecting configuration %d", bConfiguration);
|
||||
udevinfof("Selecting configuration %d", bConfiguration);
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (!_device_set_configuration(dev, dev->basicConfigDesc.bConfigurationValue)) {
|
||||
/* TODO: check if correctly configured using GET_CONFIGURATION */
|
||||
dev->status = USBH_DEVSTATUS_CONFIGURED;
|
||||
dev->bConfiguration = bConfiguration;
|
||||
|
||||
uinfo("Device configured.");
|
||||
udevinfo("Device configured.");
|
||||
return HAL_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -636,16 +619,16 @@ static bool _device_configure(usbh_device_t *dev, uint8_t bConfiguration) {
|
|||
|
||||
static bool _device_enumerate(usbh_device_t *dev) {
|
||||
|
||||
uinfo("Enumerate.");
|
||||
uinfo("Get first 8 bytes of device descriptor");
|
||||
udevinfo("Enumerate.");
|
||||
udevinfo("Get first 8 bytes of device descriptor");
|
||||
|
||||
/* get first 8 bytes of device descriptor */
|
||||
if (usbhStdReqGetDeviceDescriptor(dev, 8, (uint8_t *)&dev->devDesc)) {
|
||||
uerr("Error");
|
||||
udeverr("Error");
|
||||
return HAL_FAILED;
|
||||
}
|
||||
|
||||
uinfof("Configure bMaxPacketSize0 = %d", dev->devDesc.bMaxPacketSize0);
|
||||
udevinfof("Configure bMaxPacketSize0 = %d", dev->devDesc.bMaxPacketSize0);
|
||||
/* configure EP0 wMaxPacketSize */
|
||||
usbhEPClose(&dev->ctrl);
|
||||
_ep0_object_init(dev, dev->devDesc.bMaxPacketSize0);
|
||||
|
@ -653,14 +636,14 @@ static bool _device_enumerate(usbh_device_t *dev) {
|
|||
|
||||
uint8_t addr = _find_address(dev->host);
|
||||
if (addr == 0) {
|
||||
uerr("No free addresses found");
|
||||
udeverr("No free addresses found");
|
||||
return HAL_FAILED;
|
||||
}
|
||||
|
||||
/* set device address */
|
||||
uinfof("Set device address: %d", addr);
|
||||
udevinfof("Set device address: %d", addr);
|
||||
if (_device_setaddress(dev, addr)) {
|
||||
uerr("Error");
|
||||
udeverr("Error");
|
||||
_free_address(dev->host, addr);
|
||||
return HAL_FAILED;
|
||||
}
|
||||
|
@ -670,23 +653,23 @@ static bool _device_enumerate(usbh_device_t *dev) {
|
|||
_ep0_object_init(dev, dev->devDesc.bMaxPacketSize0);
|
||||
usbhEPOpen(&dev->ctrl);
|
||||
|
||||
uinfof("Wait stabilization...");
|
||||
udevinfof("Wait stabilization...");
|
||||
osalThreadSleepMilliseconds(HAL_USBH_DEVICE_ADDRESS_STABILIZATION);
|
||||
|
||||
/* address is set */
|
||||
dev->status = USBH_DEVSTATUS_ADDRESS;
|
||||
|
||||
uinfof("Get full device desc");
|
||||
udevinfof("Get full device desc");
|
||||
/* get full device descriptor */
|
||||
if (usbhStdReqGetDeviceDescriptor(dev, sizeof(dev->devDesc),
|
||||
(uint8_t *)&dev->devDesc)) {
|
||||
uerr("Error");
|
||||
udeverr("Error");
|
||||
_device_setaddress(dev, 0);
|
||||
_free_address(dev->host, addr);
|
||||
return HAL_FAILED;
|
||||
}
|
||||
|
||||
uinfof("Enumeration finished.");
|
||||
udevinfof("Enumeration finished.");
|
||||
return HAL_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -695,93 +678,96 @@ void usbhDevicePrintInfo(usbh_device_t *dev) {
|
|||
USBH_DEFINE_BUFFER(char str[64]);
|
||||
usbh_device_descriptor_t *const desc = &dev->devDesc;
|
||||
|
||||
uinfo("----- Device info -----");
|
||||
uinfo("Device descriptor:");
|
||||
uinfof("\tUSBSpec=%04x, #configurations=%d, langID0=%04x",
|
||||
udevinfo("----- Device info -----");
|
||||
udevinfo("Device descriptor:");
|
||||
udevinfof("\tUSBSpec=%04x, #configurations=%d, langID0=%04x",
|
||||
desc->bcdUSB,
|
||||
desc->bNumConfigurations,
|
||||
dev->langID0);
|
||||
|
||||
uinfof("\tClass=%02x, Subclass=%02x, Protocol=%02x",
|
||||
udevinfof("\tClass=%02x, Subclass=%02x, Protocol=%02x",
|
||||
desc->bDeviceClass,
|
||||
desc->bDeviceSubClass,
|
||||
desc->bDeviceProtocol);
|
||||
|
||||
uinfof("\tVID=%04x, PID=%04x, Release=%04x",
|
||||
udevinfof("\tVID=%04x, PID=%04x, Release=%04x",
|
||||
desc->idVendor,
|
||||
desc->idProduct,
|
||||
desc->bcdDevice);
|
||||
|
||||
if (dev->langID0) {
|
||||
usbhDeviceReadString(dev, str, sizeof(str), desc->iManufacturer, dev->langID0);
|
||||
uinfof("\tManufacturer: %s", str);
|
||||
udevinfof("\tManufacturer: %s", str);
|
||||
usbhDeviceReadString(dev, str, sizeof(str), desc->iProduct, dev->langID0);
|
||||
uinfof("\tProduct: %s", str);
|
||||
udevinfof("\tProduct: %s", str);
|
||||
usbhDeviceReadString(dev, str, sizeof(str), desc->iSerialNumber, dev->langID0);
|
||||
uinfof("\tSerial Number: %s", str);
|
||||
udevinfof("\tSerial Number: %s", str);
|
||||
}
|
||||
|
||||
if (dev->status == USBH_DEVSTATUS_CONFIGURED) {
|
||||
uinfo("Configuration descriptor (partial):");
|
||||
udevinfo("Configuration descriptor (partial):");
|
||||
usbh_config_descriptor_t *const cfg = &dev->basicConfigDesc;
|
||||
uinfof("\tbConfigurationValue=%d, Length=%d, #interfaces=%d",
|
||||
udevinfof("\tbConfigurationValue=%d, Length=%d, #interfaces=%d",
|
||||
cfg->bConfigurationValue,
|
||||
cfg->wTotalLength,
|
||||
cfg->bNumInterfaces);
|
||||
|
||||
uinfof("\tCurrent=%dmA", cfg->bMaxPower * 2);
|
||||
uinfof("\tSelfPowered=%d, RemoteWakeup=%d",
|
||||
udevinfof("\tCurrent=%dmA", cfg->bMaxPower * 2);
|
||||
udevinfof("\tSelfPowered=%d, RemoteWakeup=%d",
|
||||
cfg->bmAttributes & 0x40 ? 1 : 0,
|
||||
cfg->bmAttributes & 0x20 ? 1 : 0);
|
||||
if (dev->langID0) {
|
||||
usbhDeviceReadString(dev, str, sizeof(str), cfg->iConfiguration, dev->langID0);
|
||||
uinfof("\tName: %s", str);
|
||||
udevinfof("\tName: %s", str);
|
||||
}
|
||||
}
|
||||
|
||||
uinfo("----- End Device info -----");
|
||||
udevinfo("----- End Device info -----");
|
||||
|
||||
}
|
||||
|
||||
void usbhDevicePrintConfiguration(const uint8_t *descriptor, uint16_t rem) {
|
||||
void usbhDevicePrintConfiguration(const usbh_device_t *dev,
|
||||
const uint8_t *descriptor, uint16_t rem) {
|
||||
(void)dev;
|
||||
|
||||
generic_iterator_t iep, icfg, ics;
|
||||
if_iterator_t iif;
|
||||
|
||||
uinfo("----- Configuration info -----");
|
||||
uinfo("Configuration descriptor:");
|
||||
udevinfo("----- Configuration info -----");
|
||||
udevinfo("Configuration descriptor:");
|
||||
cfg_iter_init(&icfg, descriptor, rem);
|
||||
const usbh_config_descriptor_t *const cfgdesc = cfg_get(&icfg);
|
||||
uinfof("Configuration %d, #IFs=%d", cfgdesc->bConfigurationValue, cfgdesc->bNumInterfaces);
|
||||
udevinfof("Configuration %d, #IFs=%d", cfgdesc->bConfigurationValue, cfgdesc->bNumInterfaces);
|
||||
|
||||
for (if_iter_init(&iif, &icfg); iif.valid; if_iter_next(&iif)) {
|
||||
const usbh_interface_descriptor_t *const ifdesc = if_get(&iif);
|
||||
|
||||
uinfof(" Interface %d, alt=%d, #EPs=%d, "
|
||||
udevinfof(" Interface %d, alt=%d, #EPs=%d, "
|
||||
"Class=%02x, Subclass=%02x, Protocol=%02x",
|
||||
ifdesc->bInterfaceNumber, ifdesc->bAlternateSetting, ifdesc->bNumEndpoints,
|
||||
ifdesc->bInterfaceClass, ifdesc->bInterfaceSubClass, ifdesc->bInterfaceProtocol);
|
||||
|
||||
for (cs_iter_init(&ics, (generic_iterator_t *)&iif); ics.valid; cs_iter_next(&ics)) {
|
||||
uinfof(" Class-Specific descriptor, Length=%d, Type=%02x",
|
||||
udevinfof(" Class-Specific descriptor, Length=%d, Type=%02x",
|
||||
ics.curr[0], ics.curr[1]);
|
||||
}
|
||||
|
||||
for (ep_iter_init(&iep, &iif); iep.valid; ep_iter_next(&iep)) {
|
||||
const usbh_endpoint_descriptor_t *const epdesc = ep_get(&iep);
|
||||
|
||||
uinfof(" Endpoint descriptor, Address=%02x, Type=%d, MaxPacket=%d, Interval=%d",
|
||||
udevinfof(" Endpoint descriptor, Address=%02x, Type=%d, MaxPacket=%d, Interval=%d",
|
||||
epdesc->bEndpointAddress,
|
||||
epdesc->bmAttributes & 3,
|
||||
epdesc->wMaxPacketSize,
|
||||
epdesc->bInterval);
|
||||
|
||||
for (cs_iter_init(&ics, &iep); ics.valid; cs_iter_next(&ics)) {
|
||||
uinfof(" Class-Specific descriptor, Length=%d, Type=%02x",
|
||||
udevinfof(" Class-Specific descriptor, Length=%d, Type=%02x",
|
||||
ics.curr[0], ics.curr[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
uinfo("----- End Configuration info -----");
|
||||
udevinfo("----- End Configuration info -----");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -873,25 +859,25 @@ static void _port_process_status_change(usbh_port_t *port) {
|
|||
if (port->c_status & USBH_PORTSTATUS_C_RESET) {
|
||||
port->c_status &= ~USBH_PORTSTATUS_C_RESET;
|
||||
usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_RESET);
|
||||
udbgf("Port %d: reset=%d", port->number, port->status & USBH_PORTSTATUS_RESET ? 1 : 0);
|
||||
uportdbgf("Port %d: reset=%d", port->number, port->status & USBH_PORTSTATUS_RESET ? 1 : 0);
|
||||
}
|
||||
|
||||
if (port->c_status & USBH_PORTSTATUS_C_ENABLE) {
|
||||
port->c_status &= ~USBH_PORTSTATUS_C_ENABLE;
|
||||
usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_ENABLE);
|
||||
udbgf("Port %d: enable=%d", port->number, port->status & USBH_PORTSTATUS_ENABLE ? 1 : 0);
|
||||
uportdbgf("Port %d: enable=%d", port->number, port->status & USBH_PORTSTATUS_ENABLE ? 1 : 0);
|
||||
}
|
||||
|
||||
if (port->c_status & USBH_PORTSTATUS_C_OVERCURRENT) {
|
||||
port->c_status &= ~USBH_PORTSTATUS_C_OVERCURRENT;
|
||||
usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_OVERCURRENT);
|
||||
uwarnf("Port %d: overcurrent=%d", port->number, port->status & USBH_PORTSTATUS_OVERCURRENT ? 1 : 0);
|
||||
uportwarnf("Port %d: overcurrent=%d", port->number, port->status & USBH_PORTSTATUS_OVERCURRENT ? 1 : 0);
|
||||
}
|
||||
|
||||
if (port->c_status & USBH_PORTSTATUS_C_SUSPEND) {
|
||||
port->c_status &= ~USBH_PORTSTATUS_C_SUSPEND;
|
||||
usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_SUSPEND);
|
||||
uinfof("Port %d: suspend=%d", port->number, port->status & USBH_PORTSTATUS_SUSPEND ? 1 : 0);
|
||||
uportinfof("Port %d: suspend=%d", port->number, port->status & USBH_PORTSTATUS_SUSPEND ? 1 : 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -906,7 +892,7 @@ static void _port_connected(usbh_port_t *port) {
|
|||
USBH_DEFINE_BUFFER(usbh_string_descriptor_t strdesc);
|
||||
|
||||
port->device.status = USBH_DEVSTATUS_ATTACHED;
|
||||
uinfof("Port %d: attached, wait debounce...", port->number);
|
||||
uportinfof("Port %d: attached, wait debounce...", port->number);
|
||||
|
||||
/* wait for attach de-bounce */
|
||||
osalThreadSleepMilliseconds(HAL_USBH_PORT_DEBOUNCE_TIME);
|
||||
|
@ -916,23 +902,23 @@ static void _port_connected(usbh_port_t *port) {
|
|||
if (port->c_status & USBH_PORTSTATUS_C_CONNECTION) {
|
||||
port->c_status &= ~USBH_PORTSTATUS_C_CONNECTION;
|
||||
usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_CONNECTION);
|
||||
uwarnf("Port %d: connection state changed; abort #1", port->number);
|
||||
uportwarnf("Port %d: connection state changed; abort #1", port->number);
|
||||
goto abort;
|
||||
}
|
||||
|
||||
/* make sure that the device is still connected */
|
||||
if ((port->status & USBH_PORTSTATUS_CONNECTION) == 0) {
|
||||
uwarnf("Port %d: device is disconnected", port->number);
|
||||
uportwarnf("Port %d: device is disconnected", port->number);
|
||||
goto abort;
|
||||
}
|
||||
|
||||
uinfof("Port %d: connected", port->number);
|
||||
uportinfof("Port %d: connected", port->number);
|
||||
port->device.status = USBH_DEVSTATUS_CONNECTED;
|
||||
retries = 3;
|
||||
|
||||
reset:
|
||||
for (i = 0; i < 3; i++) {
|
||||
uinfof("Port %d: Try reset...", port->number);
|
||||
uportinfof("Port %d: Try reset...", port->number);
|
||||
/* TODO: check that port is actually disabled */
|
||||
port->c_status &= ~(USBH_PORTSTATUS_C_RESET | USBH_PORTSTATUS_C_ENABLE);
|
||||
_port_reset(port);
|
||||
|
@ -945,7 +931,7 @@ reset:
|
|||
if (port->c_status & USBH_PORTSTATUS_C_CONNECTION) {
|
||||
port->c_status &= ~USBH_PORTSTATUS_C_CONNECTION;
|
||||
usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_CONNECTION);
|
||||
uwarnf("Port %d: connection state changed; abort #2", port->number);
|
||||
uportwarnf("Port %d: connection state changed; abort #2", port->number);
|
||||
goto abort;
|
||||
}
|
||||
|
||||
|
@ -962,7 +948,7 @@ reset:
|
|||
|
||||
/* check for timeout */
|
||||
if (osalOsGetSystemTimeX() - start > HAL_USBH_PORT_RESET_TIMEOUT) {
|
||||
uwarnf("Port %d: reset timeout", port->number);
|
||||
uportwarnf("Port %d: reset timeout", port->number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -972,7 +958,7 @@ reset:
|
|||
goto abort;
|
||||
|
||||
reset_success:
|
||||
uinfof("Port %d: Reset OK, recovery...", port->number);
|
||||
uportinfof("Port %d: Reset OK, recovery...", port->number);
|
||||
|
||||
/* reset recovery */
|
||||
osalThreadSleepMilliseconds(100);
|
||||
|
@ -994,17 +980,17 @@ reset_success:
|
|||
usbhEPClose(&port->device.ctrl);
|
||||
|
||||
if (!--retries) {
|
||||
uwarnf("Port %d: enumeration failed; abort", port->number);
|
||||
uportwarnf("Port %d: enumeration failed; abort", port->number);
|
||||
goto abort;
|
||||
}
|
||||
|
||||
/* retry reset & enumeration */
|
||||
uwarnf("Port %d: enumeration failed; retry reset & enumeration", port->number);
|
||||
uportwarnf("Port %d: enumeration failed; retry reset & enumeration", port->number);
|
||||
goto reset;
|
||||
}
|
||||
|
||||
/* load the default language ID */
|
||||
uinfof("Port %d: Loading langID0...", port->number);
|
||||
uportinfof("Port %d: Loading langID0...", port->number);
|
||||
if (!usbhStdReqGetStringDescriptor(&port->device, 0, 0,
|
||||
USBH_DT_STRING_SIZE, (uint8_t *)&strdesc)
|
||||
&& (strdesc.bLength >= 4)
|
||||
|
@ -1012,12 +998,12 @@ reset_success:
|
|||
4, (uint8_t *)&strdesc)) {
|
||||
|
||||
port->device.langID0 = strdesc.wData[0];
|
||||
uinfof("Port %d: langID0=%04x", port->number, port->device.langID0);
|
||||
uportinfof("Port %d: langID0=%04x", port->number, port->device.langID0);
|
||||
}
|
||||
|
||||
/* check if the device has only one configuration */
|
||||
if (port->device.devDesc.bNumConfigurations == 1) {
|
||||
uinfof("Port %d: device has only one configuration", port->number);
|
||||
uportinfof("Port %d: device has only one configuration", port->number);
|
||||
_device_configure(&port->device, 0);
|
||||
}
|
||||
|
||||
|
@ -1025,7 +1011,7 @@ reset_success:
|
|||
return;
|
||||
|
||||
abort:
|
||||
uerrf("Port %d: abort", port->number);
|
||||
uporterrf("Port %d: abort", port->number);
|
||||
port->device.status = USBH_DEVSTATUS_DISCONNECTED;
|
||||
}
|
||||
|
||||
|
@ -1033,14 +1019,14 @@ void _usbh_port_disconnected(usbh_port_t *port) {
|
|||
if (port->device.status == USBH_DEVSTATUS_DISCONNECTED)
|
||||
return;
|
||||
|
||||
uinfof("Port %d: disconnected", port->number);
|
||||
uportinfof("Port %d: disconnected", port->number);
|
||||
|
||||
/* unload drivers */
|
||||
while (port->device.drivers) {
|
||||
usbh_baseclassdriver_t *drv = port->device.drivers;
|
||||
|
||||
/* unload */
|
||||
uinfof("Port %d: unload driver %s", port->number, drv->info->name);
|
||||
uportinfof("Port %d: unload driver %s", port->number, drv->info->name);
|
||||
drv->info->vmt->unload(drv);
|
||||
|
||||
/* unlink */
|
||||
|
@ -1277,7 +1263,7 @@ static bool _classdriver_load(usbh_device_t *dev, uint8_t *descbuff, uint16_t re
|
|||
for (i = 0; i < sizeof_array(usbh_classdrivers_lookup); i++) {
|
||||
const usbh_classdriverinfo_t *const info = usbh_classdrivers_lookup[i];
|
||||
|
||||
uinfof("Try load driver %s", info->name);
|
||||
udevinfof("Try load driver %s", info->name);
|
||||
drv = info->vmt->load(dev, descbuff, rem);
|
||||
|
||||
if (drv != NULL)
|
||||
|
@ -1297,7 +1283,7 @@ success:
|
|||
}
|
||||
|
||||
static void _classdriver_process_device(usbh_device_t *dev) {
|
||||
uinfo("New device found.");
|
||||
udevinfo("New device found.");
|
||||
const usbh_device_descriptor_t *const devdesc = &dev->devDesc;
|
||||
|
||||
usbhDevicePrintInfo(dev);
|
||||
|
@ -1308,20 +1294,20 @@ static void _classdriver_process_device(usbh_device_t *dev) {
|
|||
* will have multiple configurations.
|
||||
*/
|
||||
if (dev->status != USBH_DEVSTATUS_CONFIGURED) {
|
||||
uwarn("Multiple configurations not supported, selecting configuration #0");
|
||||
udevwarn("Multiple configurations not supported, selecting configuration #0");
|
||||
if (_device_configure(dev, 0) != HAL_SUCCESS) {
|
||||
uerr("Couldn't configure device; abort.");
|
||||
udeverr("Couldn't configure device; abort.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_device_read_full_cfgdesc(dev, dev->bConfiguration);
|
||||
if (dev->fullConfigurationDescriptor == NULL) {
|
||||
uerr("Couldn't read full configuration descriptor; abort.");
|
||||
udeverr("Couldn't read full configuration descriptor; abort.");
|
||||
return;
|
||||
}
|
||||
|
||||
usbhDevicePrintConfiguration(dev->fullConfigurationDescriptor,
|
||||
usbhDevicePrintConfiguration(dev, dev->fullConfigurationDescriptor,
|
||||
dev->basicConfigDesc.wTotalLength);
|
||||
|
||||
#if HAL_USBH_USE_IAD
|
||||
|
@ -1329,7 +1315,7 @@ static void _classdriver_process_device(usbh_device_t *dev) {
|
|||
&& dev->devDesc.bDeviceSubClass == 0x02
|
||||
&& dev->devDesc.bDeviceProtocol == 0x01) {
|
||||
|
||||
uinfo("Load a driver for each IF collection.");
|
||||
udevinfo("Load a driver for each IF collection.");
|
||||
|
||||
generic_iterator_t icfg;
|
||||
if_iterator_t iif;
|
||||
|
@ -1338,7 +1324,7 @@ static void _classdriver_process_device(usbh_device_t *dev) {
|
|||
cfg_iter_init(&icfg, dev->fullConfigurationDescriptor,
|
||||
dev->basicConfigDesc.wTotalLength);
|
||||
if (!icfg.valid) {
|
||||
uerr("Invalid configuration descriptor.");
|
||||
udeverr("Invalid configuration descriptor.");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -1348,7 +1334,7 @@ static void _classdriver_process_device(usbh_device_t *dev) {
|
|||
if (_classdriver_load(dev,
|
||||
(uint8_t *)iif.iad,
|
||||
(uint8_t *)iif.curr - (uint8_t *)iif.iad + iif.rem) != HAL_SUCCESS) {
|
||||
uwarnf("No drivers found for IF collection #%d:%d",
|
||||
udevwarnf("No drivers found for IF collection #%d:%d",
|
||||
iif.iad->bFirstInterface,
|
||||
iif.iad->bFirstInterface + iif.iad->bInterfaceCount - 1);
|
||||
}
|
||||
|
@ -1358,11 +1344,11 @@ static void _classdriver_process_device(usbh_device_t *dev) {
|
|||
} else
|
||||
#endif
|
||||
if (_classdriver_load(dev, (uint8_t *)devdesc, USBH_DT_DEVICE_SIZE) != HAL_SUCCESS) {
|
||||
uinfo("No drivers found for device.");
|
||||
udevinfo("No drivers found for device.");
|
||||
|
||||
if (devdesc->bDeviceClass == 0) {
|
||||
/* each interface defines its own device class/subclass/protocol */
|
||||
uinfo("Try load a driver for each IF.");
|
||||
udevinfo("Try load a driver for each IF.");
|
||||
|
||||
generic_iterator_t icfg;
|
||||
if_iterator_t iif;
|
||||
|
@ -1371,7 +1357,7 @@ static void _classdriver_process_device(usbh_device_t *dev) {
|
|||
cfg_iter_init(&icfg, dev->fullConfigurationDescriptor,
|
||||
dev->basicConfigDesc.wTotalLength);
|
||||
if (!icfg.valid) {
|
||||
uerr("Invalid configuration descriptor.");
|
||||
udeverr("Invalid configuration descriptor.");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -1380,12 +1366,12 @@ static void _classdriver_process_device(usbh_device_t *dev) {
|
|||
if (ifdesc->bInterfaceNumber != last_if) {
|
||||
last_if = ifdesc->bInterfaceNumber;
|
||||
if (_classdriver_load(dev, (uint8_t *)ifdesc, iif.rem) != HAL_SUCCESS) {
|
||||
uwarnf("No drivers found for IF #%d", ifdesc->bInterfaceNumber);
|
||||
udevwarnf("No drivers found for IF #%d", ifdesc->bInterfaceNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uwarn("Unable to load driver.");
|
||||
udevwarn("Unable to load driver.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,39 +29,12 @@
|
|||
|
||||
//#pragma GCC optimize("Og")
|
||||
|
||||
|
||||
#if USBHAOA_DEBUG_ENABLE_TRACE
|
||||
#define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define udbgf(f, ...) do {} while(0)
|
||||
#define udbg(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBHAOA_DEBUG_ENABLE_INFO
|
||||
#define uinfof(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uinfo(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uinfof(f, ...) do {} while(0)
|
||||
#define uinfo(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBHAOA_DEBUG_ENABLE_WARNINGS
|
||||
#define uwarnf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uwarn(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uwarnf(f, ...) do {} while(0)
|
||||
#define uwarn(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBHAOA_DEBUG_ENABLE_ERRORS
|
||||
#define uerrf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uerr(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uerrf(f, ...) do {} while(0)
|
||||
#define uerr(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#define _USBH_DEBUG_HELPER_CLASS_DRIVER container_of(aoacp, USBHAOADriver, channel)
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_TRACE USBHAOA_DEBUG_ENABLE_TRACE
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_INFO USBHAOA_DEBUG_ENABLE_INFO
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_WARNINGS USBHAOA_DEBUG_ENABLE_WARNINGS
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_ERRORS USBHAOA_DEBUG_ENABLE_ERRORS
|
||||
#include "usbh/debug_helpers.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Constants */
|
||||
|
@ -162,11 +135,11 @@ static usbh_baseclassdriver_t *_aoa_load(usbh_device_t *dev, const uint8_t *desc
|
|||
};
|
||||
|
||||
if (descriptor[1] != USBH_DT_DEVICE) {
|
||||
uinfo("AOA: Won't try to detect Android device at interface level");
|
||||
udevinfo("AOA: Won't try to detect Android device at interface level");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uinfo("AOA: Unrecognized VID");
|
||||
udevinfo("AOA: Unrecognized VID");
|
||||
|
||||
#if defined(HAL_USBHAOA_FILTER_CALLBACK)
|
||||
if (!HAL_USBHAOA_FILTER_CALLBACK(dev, descriptor, rem, &config)) {
|
||||
|
@ -174,12 +147,12 @@ static usbh_baseclassdriver_t *_aoa_load(usbh_device_t *dev, const uint8_t *desc
|
|||
}
|
||||
#endif
|
||||
|
||||
uinfo("AOA: Try if it's an Android device");
|
||||
udevinfo("AOA: Try if it's an Android device");
|
||||
if (_get_protocol(dev, &protocol) != HAL_SUCCESS) {
|
||||
uinfo("AOA: not an Android device");
|
||||
udevinfo("AOA: not an Android device");
|
||||
return NULL;
|
||||
}
|
||||
uinfof("AOA: Possible Android device found (protocol=%d)", protocol);
|
||||
udevinfof("AOA: Possible Android device found (protocol=%d)", protocol);
|
||||
|
||||
if (config.channel.manufacturer != NULL) {
|
||||
if ((_send_string(dev, USBHAOA_ACCESSORY_STRING_MANUFACTURER, config.channel.manufacturer) != HAL_SUCCESS)
|
||||
|
@ -188,22 +161,22 @@ static usbh_baseclassdriver_t *_aoa_load(usbh_device_t *dev, const uint8_t *desc
|
|||
|| (_send_string(dev, USBHAOA_ACCESSORY_STRING_VERSION, config.channel.version) != HAL_SUCCESS)
|
||||
|| (_send_string(dev, USBHAOA_ACCESSORY_STRING_URI, config.channel.uri) != HAL_SUCCESS)
|
||||
|| (_send_string(dev, USBHAOA_ACCESSORY_STRING_SERIAL, config.channel.serial) != HAL_SUCCESS)) {
|
||||
uerr("AOA: Can't send string; abort start");
|
||||
udeverr("AOA: Can't send string; abort start");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (protocol > 1) {
|
||||
if (_set_audio_mode(dev, (uint16_t)(config.audio.mode)) != HAL_SUCCESS) {
|
||||
uerr("AOA: Can't set audio mode; abort channel start");
|
||||
udeverr("AOA: Can't set audio mode; abort channel start");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (_accessory_start(dev) != HAL_SUCCESS) {
|
||||
uerr("AOA: Can't start accessory; abort channel start");
|
||||
udeverr("AOA: Can't start accessory; abort channel start");
|
||||
} else {
|
||||
uinfo("AOA: Accessory started");
|
||||
udevinfo("AOA: Accessory started");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -227,18 +200,18 @@ static usbh_baseclassdriver_t *_aoa_load(usbh_device_t *dev, const uint8_t *desc
|
|||
case AOA_GOOGLE_PID_ACCESSORY_AUDIO_ABD:
|
||||
break;
|
||||
default:
|
||||
uerr("AOA: Unrecognized PID");
|
||||
udeverr("AOA: Unrecognized PID");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const usbh_interface_descriptor_t * const ifdesc = (const usbh_interface_descriptor_t *)descriptor;
|
||||
if ((_usbh_match_descriptor(descriptor, rem, USBH_DT_INTERFACE, 0xFF, 0xFF, 0x00) != HAL_SUCCESS)
|
||||
|| (ifdesc->bNumEndpoints < 2)) {
|
||||
uerr("AOA: This IF is not the Accessory IF");
|
||||
udeverr("AOA: This IF is not the Accessory IF");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uinfof("AOA: Found Accessory Interface #%d", ifdesc->bInterfaceNumber);
|
||||
udevinfof("AOA: Found Accessory Interface #%d", ifdesc->bInterfaceNumber);
|
||||
|
||||
for (i = 0; i < HAL_USBHAOA_MAX_INSTANCES; i++) {
|
||||
if (USBHAOAD[i].dev == NULL) {
|
||||
|
@ -247,7 +220,7 @@ static usbh_baseclassdriver_t *_aoa_load(usbh_device_t *dev, const uint8_t *desc
|
|||
}
|
||||
}
|
||||
|
||||
uwarn("AOA: Can't alloc driver");
|
||||
udevwarn("AOA: Can't alloc driver");
|
||||
|
||||
/* can't alloc */
|
||||
return NULL;
|
||||
|
@ -269,30 +242,30 @@ alloc_ok:
|
|||
for (ep_iter_init(&iep, &iif); iep.valid; ep_iter_next(&iep)) {
|
||||
const usbh_endpoint_descriptor_t *const epdesc = ep_get(&iep);
|
||||
if ((epdesc->bEndpointAddress & 0x80) && (epdesc->bmAttributes == USBH_EPTYPE_BULK)) {
|
||||
uinfof("AOA: BULK IN endpoint found: bEndpointAddress=%02x", epdesc->bEndpointAddress);
|
||||
udevinfof("AOA: BULK IN endpoint found: bEndpointAddress=%02x", epdesc->bEndpointAddress);
|
||||
usbhEPObjectInit(&aoap->channel.epin, dev, epdesc);
|
||||
usbhEPSetName(&aoap->channel.epin, "AOA[BIN ]");
|
||||
} else if (((epdesc->bEndpointAddress & 0x80) == 0)
|
||||
&& (epdesc->bmAttributes == USBH_EPTYPE_BULK)) {
|
||||
uinfof("AOA: BULK OUT endpoint found: bEndpointAddress=%02x", epdesc->bEndpointAddress);
|
||||
udevinfof("AOA: BULK OUT endpoint found: bEndpointAddress=%02x", epdesc->bEndpointAddress);
|
||||
usbhEPObjectInit(&aoap->channel.epout, dev, epdesc);
|
||||
usbhEPSetName(&aoap->channel.epout, "AOA[BOUT]");
|
||||
} else {
|
||||
uinfof("AOA: unsupported endpoint found: bEndpointAddress=%02x, bmAttributes=%02x",
|
||||
udevinfof("AOA: unsupported endpoint found: bEndpointAddress=%02x, bmAttributes=%02x",
|
||||
epdesc->bEndpointAddress, epdesc->bmAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
if ((aoap->channel.epin.status != USBH_EPSTATUS_CLOSED)
|
||||
|| (aoap->channel.epout.status != USBH_EPSTATUS_CLOSED)) {
|
||||
uwarn("AOA: Couldn't find endpoints");
|
||||
udevwarn("AOA: Couldn't find endpoints");
|
||||
aoap->state = USBHAOA_STATE_STOP;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
aoap->state = USBHAOA_STATE_READY;
|
||||
aoap->channel.state = USBHAOA_CHANNEL_STATE_ACTIVE;
|
||||
uwarn("AOA: Ready");
|
||||
udevwarn("AOA: Ready");
|
||||
return (usbh_baseclassdriver_t *)aoap;
|
||||
}
|
||||
|
||||
|
@ -311,7 +284,7 @@ static void _aoa_unload(usbh_baseclassdriver_t *drv) {
|
|||
/* ------------------------------------ */
|
||||
|
||||
static void _submitOutI(USBHAOAChannel *aoacp, uint32_t len) {
|
||||
udbgf("AOA: Submit OUT %d", len);
|
||||
uclassdrvdbgf("AOA: Submit OUT %d", len);
|
||||
aoacp->oq_urb.requestedLength = len;
|
||||
usbhURBObjectResetI(&aoacp->oq_urb);
|
||||
usbhURBSubmitI(&aoacp->oq_urb);
|
||||
|
@ -327,12 +300,12 @@ static void _out_cb(usbh_urb_t *urb) {
|
|||
chnAddFlagsI(aoacp, CHN_OUTPUT_EMPTY | CHN_TRANSMISSION_END);
|
||||
return;
|
||||
case USBH_URBSTATUS_DISCONNECTED:
|
||||
uwarn("AOA: URB OUT disconnected");
|
||||
uclassdrvwarn("AOA: URB OUT disconnected");
|
||||
chThdDequeueAllI(&aoacp->oq_waiting, Q_RESET);
|
||||
chnAddFlagsI(aoacp, CHN_OUTPUT_EMPTY);
|
||||
return;
|
||||
default:
|
||||
uerrf("AOA: URB OUT status unexpected = %d", urb->status);
|
||||
uclassdrverrf("AOA: URB OUT status unexpected = %d", urb->status);
|
||||
break;
|
||||
}
|
||||
usbhURBObjectResetI(&aoacp->oq_urb);
|
||||
|
@ -406,7 +379,7 @@ static msg_t _put(USBHAOAChannel *aoacp, uint8_t b) {
|
|||
}
|
||||
|
||||
static void _submitInI(USBHAOAChannel *aoacp) {
|
||||
udbg("AOA: Submit IN");
|
||||
uclassdrvdbg("AOA: Submit IN");
|
||||
usbhURBObjectResetI(&aoacp->iq_urb);
|
||||
usbhURBSubmitI(&aoacp->iq_urb);
|
||||
}
|
||||
|
@ -416,9 +389,9 @@ static void _in_cb(usbh_urb_t *urb) {
|
|||
switch (urb->status) {
|
||||
case USBH_URBSTATUS_OK:
|
||||
if (urb->actualLength == 0) {
|
||||
udbgf("AOA: URB IN no data");
|
||||
uurbdbgf("AOA: URB IN no data");
|
||||
} else {
|
||||
udbgf("AOA: URB IN data len=%d", urb->actualLength);
|
||||
uurbdbgf("AOA: URB IN data len=%d", urb->actualLength);
|
||||
aoacp->iq_ptr = aoacp->iq_buff;
|
||||
aoacp->iq_counter = urb->actualLength;
|
||||
chThdDequeueNextI(&aoacp->iq_waiting, Q_OK);
|
||||
|
@ -426,14 +399,14 @@ static void _in_cb(usbh_urb_t *urb) {
|
|||
}
|
||||
break;
|
||||
case USBH_URBSTATUS_DISCONNECTED:
|
||||
uwarn("AOA: URB IN disconnected");
|
||||
uurbwarn("AOA: URB IN disconnected");
|
||||
chThdDequeueAllI(&aoacp->iq_waiting, Q_RESET);
|
||||
chnAddFlagsI(aoacp, CHN_DISCONNECTED);
|
||||
aoacp->state = USBHAOA_CHANNEL_STATE_ACTIVE;
|
||||
container_of(aoacp, USBHAOADriver, channel)->state = USBHAOA_STATE_ACTIVE;
|
||||
break;
|
||||
default:
|
||||
uerrf("AOA: URB IN status unexpected = %d", urb->status);
|
||||
uurberrf("AOA: URB IN status unexpected = %d", urb->status);
|
||||
_submitInI(aoacp);
|
||||
break;
|
||||
}
|
||||
|
@ -532,7 +505,7 @@ static const struct AOADriverVMT async_channel_vmt = {
|
|||
static void _stop_channelS(USBHAOAChannel *aoacp) {
|
||||
if (aoacp->state != USBHAOA_CHANNEL_STATE_READY)
|
||||
return;
|
||||
uwarn("AOA: Stop channel");
|
||||
uclassdrvwarn("AOA: Stop channel");
|
||||
chVTResetI(&aoacp->vt);
|
||||
usbhEPCloseS(&aoacp->epin);
|
||||
usbhEPCloseS(&aoacp->epout);
|
||||
|
|
|
@ -21,573 +21,199 @@
|
|||
|
||||
#include "ch.h"
|
||||
#include "usbh/debug.h"
|
||||
#include <stdarg.h>
|
||||
#if 0
|
||||
#include "debug.h"
|
||||
#else
|
||||
#include "chprintf.h"
|
||||
#define dbg_lock()
|
||||
#define dbg_unlock()
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
|
||||
#define MAX_FILLER 11
|
||||
#define FLOAT_PRECISION 9
|
||||
#define MPRINTF_USE_FLOAT 0
|
||||
#define TEMP_BUFF_LEN 255
|
||||
|
||||
static char *long_to_string_with_divisor(char *p, long num, unsigned radix, long divisor)
|
||||
{
|
||||
int i;
|
||||
char *q;
|
||||
long l, ll;
|
||||
/* ************************ */
|
||||
/* Circular queue structure */
|
||||
/* ************************ */
|
||||
static int dq_append_string(usbh_dq_t *q, const uint8_t *s, int len) {
|
||||
if (len <= 0) return 0;
|
||||
if (len > TEMP_BUFF_LEN) len = TEMP_BUFF_LEN;
|
||||
if (q->rem < len + 1) return -1;
|
||||
q->rem -= len + 1;
|
||||
|
||||
l = num;
|
||||
if (divisor == 0) {
|
||||
ll = num;
|
||||
} else {
|
||||
ll = divisor;
|
||||
uint8_t *d = q->next;
|
||||
*d++ = len;
|
||||
if (d == q->end) d = q->start;
|
||||
while (len--) {
|
||||
*d++ = *s++;
|
||||
if (d == q->end) d = q->start;
|
||||
}
|
||||
|
||||
q = p + MAX_FILLER;
|
||||
do {
|
||||
i = (int)(l % radix);
|
||||
i += '0';
|
||||
if (i > '9') {
|
||||
i += 'A' - '0' - 10;
|
||||
}
|
||||
*--q = i;
|
||||
l /= radix;
|
||||
} while ((ll /= radix) != 0);
|
||||
|
||||
i = (int)(p + MAX_FILLER - q);
|
||||
do {
|
||||
*p++ = *q++;
|
||||
} while (--i);
|
||||
|
||||
return p;
|
||||
q->next = d;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *ltoa(char *p, long num, unsigned radix) {
|
||||
|
||||
return long_to_string_with_divisor(p, num, radix, 0);
|
||||
}
|
||||
|
||||
#if MPRINTF_USE_FLOAT
|
||||
static const long _pow10[FLOAT_PRECISION] = {10, 100, 1000, 10000, 100000, 1000000,
|
||||
10000000, 100000000, 1000000000};
|
||||
static const double m10[FLOAT_PRECISION] = {5.0/100, 5.0/1000, 5.0/10000, 5.0/100000, 5.0/1000000,
|
||||
5.0/10000000, 5.0/100000000, 5.0/1000000000, 5.0/10000000000};
|
||||
|
||||
static char *ftoa(char *p, double num, unsigned long precision, bool dot) {
|
||||
long l;
|
||||
char *q;
|
||||
double r;
|
||||
|
||||
|
||||
if (precision == 0) {
|
||||
l = (long)(num + 0.5);
|
||||
return long_to_string_with_divisor(p, l, 10, 0);
|
||||
} else {
|
||||
if (precision > FLOAT_PRECISION) precision = FLOAT_PRECISION;
|
||||
r = m10[precision - 1];
|
||||
precision = _pow10[precision - 1];
|
||||
|
||||
l = (long)num;
|
||||
p = long_to_string_with_divisor(p, l, 10, 0);
|
||||
if (dot) *p++ = '.';
|
||||
l = (long)((num - l + r) * precision);
|
||||
q = long_to_string_with_divisor(p, l, 10, precision / 10) - 1;
|
||||
|
||||
while (q > p) {
|
||||
if (*q != '0') {
|
||||
break;
|
||||
}
|
||||
--q;
|
||||
static void dq_remove_oldest_string(usbh_dq_t *q) {
|
||||
int len = *q->first;
|
||||
if (len) {
|
||||
++len;
|
||||
q->rem += len;
|
||||
q->first += len;
|
||||
if (q->first >= q->end) {
|
||||
q->first -= q->sz;
|
||||
}
|
||||
return ++q;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void _wr(input_queue_t *iqp, char c) {
|
||||
*iqp->q_wrptr++ = c;
|
||||
if (iqp->q_wrptr >= iqp->q_top)
|
||||
iqp->q_wrptr = iqp->q_buffer;
|
||||
}
|
||||
|
||||
static inline void _put(char c) {
|
||||
input_queue_t *iqp = &USBH_DEBUG_USBHD.iq;
|
||||
if (sizeof(USBH_DEBUG_USBHD.dbg_buff) - iqp->q_counter <= 1)
|
||||
return;
|
||||
iqp->q_counter++;
|
||||
_wr(iqp, c);
|
||||
}
|
||||
|
||||
int _dbg_printf(const char *fmt, va_list ap) {
|
||||
char *p, *s, c, filler;
|
||||
int i, precision, width;
|
||||
int n = 0;
|
||||
bool is_long, left_align, sign;
|
||||
long l;
|
||||
#if MPRINTF_USE_FLOAT
|
||||
double f;
|
||||
char tmpbuf[2*MAX_FILLER + 1];
|
||||
#else
|
||||
char tmpbuf[MAX_FILLER + 1];
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
|
||||
//agarrar nuevo caracter de formato
|
||||
c = *fmt++;
|
||||
|
||||
//chequeo eos
|
||||
if (c == 0) return n;
|
||||
|
||||
//copio los caracteres comunes
|
||||
if (c != '%') {
|
||||
_put(c);
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
|
||||
//encontré un '%'
|
||||
p = tmpbuf;
|
||||
s = tmpbuf;
|
||||
|
||||
//left align
|
||||
left_align = FALSE;
|
||||
if (*fmt == '-') {
|
||||
fmt++;
|
||||
left_align = TRUE;
|
||||
}
|
||||
|
||||
sign = FALSE;
|
||||
if (*fmt == '+') {
|
||||
fmt++;
|
||||
sign = TRUE;
|
||||
}
|
||||
|
||||
//filler
|
||||
filler = ' ';
|
||||
if (*fmt == '0') {
|
||||
fmt++;
|
||||
filler = '0';
|
||||
}
|
||||
|
||||
//width
|
||||
width = 0;
|
||||
while (TRUE) {
|
||||
c = *fmt++;
|
||||
if (c >= '0' && c <= '9')
|
||||
c -= '0';
|
||||
else if (c == '*')
|
||||
c = va_arg(ap, int);
|
||||
else
|
||||
break;
|
||||
width = width * 10 + c;
|
||||
}
|
||||
|
||||
//precision
|
||||
precision = 0;
|
||||
if (c == '.') {
|
||||
|
||||
if (*fmt == 'n') {
|
||||
fmt++;
|
||||
|
||||
}
|
||||
while (TRUE) {
|
||||
c = *fmt++;
|
||||
if (c >= '0' && c <= '9')
|
||||
c -= '0';
|
||||
else if (c == '*')
|
||||
c = va_arg(ap, int);
|
||||
else
|
||||
break;
|
||||
precision = precision * 10 + c;
|
||||
}
|
||||
}
|
||||
|
||||
//long modifier
|
||||
if (c == 'l' || c == 'L') {
|
||||
is_long = TRUE;
|
||||
if (*fmt)
|
||||
c = *fmt++;
|
||||
}
|
||||
else
|
||||
is_long = (c >= 'A') && (c <= 'Z');
|
||||
|
||||
/* Command decoding.*/
|
||||
switch (c) {
|
||||
//char
|
||||
case 'c':
|
||||
filler = ' ';
|
||||
*p++ = va_arg(ap, int);
|
||||
break;
|
||||
|
||||
//string
|
||||
case 's':
|
||||
filler = ' ';
|
||||
if ((s = va_arg(ap, char *)) == 0)
|
||||
s = (char *)"(null)";
|
||||
if (precision == 0)
|
||||
precision = 32767;
|
||||
|
||||
//strlen con límite hasta precision
|
||||
for (p = s; *p && (--precision >= 0); p++)
|
||||
;
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case 'D':
|
||||
case 'd':
|
||||
case 'I':
|
||||
case 'i':
|
||||
if (is_long)
|
||||
l = va_arg(ap, long);
|
||||
else
|
||||
l = va_arg(ap, int);
|
||||
if (l < 0) {
|
||||
*p++ = '-';
|
||||
l = -l;
|
||||
sign = TRUE;
|
||||
} else if (sign) {
|
||||
*p++ = '+';
|
||||
}
|
||||
p = ltoa(p, l, 10);
|
||||
break;
|
||||
|
||||
#if MPRINTF_USE_FLOAT
|
||||
case 'f':
|
||||
f = va_arg(ap, double);
|
||||
if (f < 0) {
|
||||
*p++ = '-';
|
||||
f = -f;
|
||||
sign = TRUE;
|
||||
} else if (sign) {
|
||||
*p++ = '+';
|
||||
}
|
||||
if (prec == FALSE) precision = 6;
|
||||
p = ftoa(p, f, precision, dot);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
case 'X':
|
||||
case 'x':
|
||||
c = 16;
|
||||
goto unsigned_common;
|
||||
case 'U':
|
||||
case 'u':
|
||||
c = 10;
|
||||
goto unsigned_common;
|
||||
case 'O':
|
||||
case 'o':
|
||||
c = 8;
|
||||
|
||||
unsigned_common:
|
||||
if (is_long)
|
||||
l = va_arg(ap, unsigned long);
|
||||
else
|
||||
l = va_arg(ap, unsigned int);
|
||||
p = ltoa(p, l, c);
|
||||
break;
|
||||
|
||||
//copiar
|
||||
default:
|
||||
*p++ = c;
|
||||
break;
|
||||
}
|
||||
|
||||
//longitud
|
||||
i = (int)(p - s);
|
||||
|
||||
//calculo cuántos caracteres de filler debo poner
|
||||
if ((width -= i) < 0)
|
||||
width = 0;
|
||||
|
||||
if (left_align == FALSE)
|
||||
width = -width;
|
||||
|
||||
if (width < 0) {
|
||||
//alineado a la derecha
|
||||
|
||||
//poner el signo adelante
|
||||
if (sign && filler == '0') {
|
||||
_put(*s++);
|
||||
n++;
|
||||
i--;
|
||||
}
|
||||
|
||||
//fill a la izquierda
|
||||
do {
|
||||
_put(filler);
|
||||
n++;
|
||||
} while (++width != 0);
|
||||
}
|
||||
|
||||
//copiar los caracteres
|
||||
while (--i >= 0) {
|
||||
_put(*s++);
|
||||
n++;
|
||||
}
|
||||
|
||||
//fill a la derecha
|
||||
while (width) {
|
||||
_put(filler);
|
||||
n++;
|
||||
width--;
|
||||
if (q->rem == q->sz) {
|
||||
*q->first = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//return n; // can raise 'code is unreachable' warning
|
||||
|
||||
}
|
||||
|
||||
static systime_t first, last;
|
||||
static bool ena;
|
||||
static uint32_t hdr[2];
|
||||
static int dq_read_oldest_string(usbh_dq_t *q, uint8_t *d) {
|
||||
uint8_t *s = q->first;
|
||||
int len;
|
||||
int sz;
|
||||
len = sz = *s++;
|
||||
while (len--) {
|
||||
*d++ = *s++;
|
||||
if (d == q->end) d = q->start;
|
||||
}
|
||||
*d = 0;
|
||||
return sz;
|
||||
}
|
||||
|
||||
static void _build_hdr(void) {
|
||||
uint32_t hfnum = USBH_DEBUG_USBHD.otg->HFNUM;
|
||||
uint16_t hfir = USBH_DEBUG_USBHD.otg->HFIR;
|
||||
last = osalOsGetSystemTimeX();
|
||||
if (ena) {
|
||||
first = last;
|
||||
static void dq_init(usbh_dq_t *q, uint8_t *buff, int len) {
|
||||
q->start = q->first = q->next = buff;
|
||||
q->end = q->start + len;
|
||||
q->sz = q->rem = len;
|
||||
*buff = 0;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t buff[TEMP_BUFF_LEN + 1];
|
||||
|
||||
static inline syssts_t _dbg_prologue(struct usbh_debug_helper *debug,
|
||||
uint32_t hfnum, uint16_t hfir, const char *s, int *len) {
|
||||
syssts_t sts = chSysGetStatusAndLockX();
|
||||
|
||||
debug->last = osalOsGetSystemTimeX();
|
||||
if (debug->ena) {
|
||||
debug->first = debug->last;
|
||||
}
|
||||
|
||||
if (((hfnum & 0x3fff) == 0x3fff) && (hfir == (hfnum >> 16))) {
|
||||
hdr[0] = 0xfeff;
|
||||
hdr[1] = last - first;
|
||||
ena = FALSE;
|
||||
*len = chsnprintf((char *)buff, sizeof(buff), "+%08d ", debug->last - debug->first);
|
||||
debug->ena = FALSE;
|
||||
} else {
|
||||
hdr[0] = 0xffff | (hfir << 16);
|
||||
hdr[1] = hfnum;
|
||||
ena = TRUE;
|
||||
uint32_t f = hfnum & 0xffff;
|
||||
uint32_t p = 1000 - ((hfnum >> 16) / (hfir / 1000));
|
||||
*len = chsnprintf((char *)buff, sizeof(buff), "%05d.%03d %s", f, p, s);
|
||||
debug->ena = TRUE;
|
||||
}
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
static void _print_hdr(void)
|
||||
{
|
||||
_put(hdr[0] & 0xff);
|
||||
_put((hdr[0] >> 8) & 0xff);
|
||||
_put((hdr[0] >> 16) & 0xff);
|
||||
_put((hdr[0] >> 24) & 0xff);
|
||||
_put(hdr[1] & 0xff);
|
||||
_put((hdr[1] >> 8) & 0xff);
|
||||
_put((hdr[1] >> 16) & 0xff);
|
||||
_put((hdr[1] >> 24) & 0xff);
|
||||
static inline void dbg_epilogue(struct usbh_debug_helper *debug,
|
||||
syssts_t sts, int len) {
|
||||
|
||||
while (dq_append_string(&debug->dq, buff, len) < 0) {
|
||||
dq_remove_oldest_string(&debug->dq);
|
||||
}
|
||||
|
||||
if (debug->on) {
|
||||
chThdResumeI(&debug->tr, MSG_OK);
|
||||
}
|
||||
|
||||
chSysRestoreStatusX(sts);
|
||||
}
|
||||
|
||||
void usbDbgPrintf(const char *fmt, ...)
|
||||
{
|
||||
#if USBH_DEBUG_MULTI_HOST
|
||||
void usbDbgPrintf(USBHDriver *host, const char *fmt, ...) {
|
||||
if (!host) return;
|
||||
struct usbh_debug_helper *const debug = &host->debug;
|
||||
uint32_t hfnum = host->otg->HFNUM;
|
||||
uint16_t hfir = host->otg->HFIR;
|
||||
#else
|
||||
void usbDbgPrintf(const char *fmt, ...) {
|
||||
struct usbh_debug_helper *const debug = &usbh_debug;
|
||||
uint32_t hfnum = USBH_DEBUG_SINGLE_HOST_SELECTION.otg->HFNUM;
|
||||
uint16_t hfir = USBH_DEBUG_SINGLE_HOST_SELECTION.otg->HFIR;
|
||||
#endif
|
||||
int len;
|
||||
|
||||
syssts_t sts = _dbg_prologue(debug, hfnum, hfir, "", &len);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
syssts_t sts = chSysGetStatusAndLockX();
|
||||
input_queue_t *iqp = &USBH_DEBUG_USBHD.iq;
|
||||
int rem = sizeof(USBH_DEBUG_USBHD.dbg_buff) - iqp->q_counter;
|
||||
if (rem >= 9) {
|
||||
_build_hdr();
|
||||
_print_hdr();
|
||||
_dbg_printf(fmt, ap);
|
||||
iqp->q_counter++;
|
||||
_wr(iqp, 0);
|
||||
chThdDequeueNextI(&USBH_DEBUG_USBHD.iq.q_waiting, Q_OK);
|
||||
}
|
||||
chSysRestoreStatusX(sts);
|
||||
if (!port_is_isr_context() && chSchIsPreemptionRequired()) {
|
||||
chSchRescheduleS();
|
||||
}
|
||||
len += chvsnprintf((char *)buff + len, sizeof(buff) - len, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
dbg_epilogue(debug, sts, len);
|
||||
}
|
||||
|
||||
|
||||
void usbDbgPuts(const char *s)
|
||||
{
|
||||
_build_hdr();
|
||||
uint8_t *p = (uint8_t *)hdr;
|
||||
uint8_t *top = p + 8;
|
||||
|
||||
syssts_t sts = chSysGetStatusAndLockX();
|
||||
input_queue_t *iqp = &USBH_DEBUG_USBHD.iq;
|
||||
int rem = sizeof(USBH_DEBUG_USBHD.dbg_buff) - iqp->q_counter;
|
||||
if (rem >= 9) {
|
||||
while (rem) {
|
||||
_wr(iqp, *p);
|
||||
if (++p == top) break;
|
||||
}
|
||||
rem -= 9;
|
||||
while (rem && *s) {
|
||||
_wr(iqp, *s);
|
||||
rem--;
|
||||
s++;
|
||||
}
|
||||
_wr(iqp, 0);
|
||||
iqp->q_counter = sizeof(USBH_DEBUG_USBHD.dbg_buff) - rem;
|
||||
chThdDequeueNextI(&USBH_DEBUG_USBHD.iq.q_waiting, Q_OK);
|
||||
}
|
||||
chSysRestoreStatusX(sts);
|
||||
if (!port_is_isr_context() && chSchIsPreemptionRequired()) {
|
||||
chSchRescheduleS();
|
||||
}
|
||||
#if USBH_DEBUG_MULTI_HOST
|
||||
void usbDbgPuts(USBHDriver *host, const char *s) {
|
||||
if (!host) return;
|
||||
struct usbh_debug_helper *const debug = &host->debug;
|
||||
uint32_t hfnum = host->otg->HFNUM;
|
||||
uint16_t hfir = host->otg->HFIR;
|
||||
#else
|
||||
void usbDbgPuts(const char *s) {
|
||||
struct usbh_debug_helper *const debug = &usbh_debug;
|
||||
uint32_t hfnum = USBH_DEBUG_SINGLE_HOST_SELECTION.otg->HFNUM;
|
||||
uint16_t hfir = USBH_DEBUG_SINGLE_HOST_SELECTION.otg->HFIR;
|
||||
#endif
|
||||
int len;
|
||||
syssts_t sts = _dbg_prologue(debug, hfnum, hfir, s, &len);
|
||||
dbg_epilogue(debug, sts, len);
|
||||
}
|
||||
|
||||
void usbDbgReset(void) {
|
||||
const char *msg = "\r\n\r\n==== DEBUG OUTPUT RESET ====\r\n";
|
||||
|
||||
syssts_t sts = chSysGetStatusAndLockX();
|
||||
iqResetI(&USBH_DEBUG_USBHD.iq);
|
||||
oqResetI(&USBH_DEBUG_SD.oqueue);
|
||||
while (*msg) {
|
||||
*USBH_DEBUG_SD.oqueue.q_wrptr++ = *msg++;
|
||||
USBH_DEBUG_SD.oqueue.q_counter--;
|
||||
}
|
||||
chSysRestoreStatusX(sts);
|
||||
if (!port_is_isr_context() && chSchIsPreemptionRequired()) {
|
||||
chSchRescheduleS();
|
||||
}
|
||||
}
|
||||
|
||||
static int _get(void) {
|
||||
if (!USBH_DEBUG_USBHD.iq.q_counter) return -1;
|
||||
USBH_DEBUG_USBHD.iq.q_counter--;
|
||||
uint8_t b = *USBH_DEBUG_USBHD.iq.q_rdptr++;
|
||||
if (USBH_DEBUG_USBHD.iq.q_rdptr >= USBH_DEBUG_USBHD.iq.q_top) {
|
||||
USBH_DEBUG_USBHD.iq.q_rdptr = USBH_DEBUG_USBHD.iq.q_buffer;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
void usbDbgSystemHalted(void) {
|
||||
while (true) {
|
||||
if (!((bool)((USBH_DEBUG_SD.oqueue.q_wrptr == USBH_DEBUG_SD.oqueue.q_rdptr) && (USBH_DEBUG_SD.oqueue.q_counter != 0U))))
|
||||
break;
|
||||
USBH_DEBUG_SD.oqueue.q_counter++;
|
||||
while (!(USBH_DEBUG_SD.usart->SR & USART_SR_TXE));
|
||||
USBH_DEBUG_SD.usart->DR = *USBH_DEBUG_SD.oqueue.q_rdptr++;
|
||||
if (USBH_DEBUG_SD.oqueue.q_rdptr >= USBH_DEBUG_SD.oqueue.q_top) {
|
||||
USBH_DEBUG_SD.oqueue.q_rdptr = USBH_DEBUG_SD.oqueue.q_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
int c;
|
||||
int state = 0;
|
||||
for (;;) {
|
||||
c = _get(); if (c < 0) break;
|
||||
|
||||
if (state == 0) {
|
||||
if (c == 0xff) state = 1;
|
||||
} else if (state == 1) {
|
||||
if (c == 0xff) state = 2;
|
||||
else (state = 0);
|
||||
} else {
|
||||
c = _get(); if (c < 0) return;
|
||||
c = _get(); if (c < 0) return;
|
||||
c = _get(); if (c < 0) return;
|
||||
c = _get(); if (c < 0) return;
|
||||
c = _get(); if (c < 0) return;
|
||||
|
||||
while (true) {
|
||||
c = _get(); if (c < 0) return;
|
||||
if (!c) {
|
||||
while (!(USBH_DEBUG_SD.usart->SR & USART_SR_TXE));
|
||||
USBH_DEBUG_SD.usart->DR = '\r';
|
||||
while (!(USBH_DEBUG_SD.usart->SR & USART_SR_TXE));
|
||||
USBH_DEBUG_SD.usart->DR = '\n';
|
||||
state = 0;
|
||||
break;
|
||||
}
|
||||
while (!(USBH_DEBUG_SD.usart->SR & USART_SR_TXE));
|
||||
USBH_DEBUG_SD.usart->DR = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if USBH_DEBUG_MULTI_HOST
|
||||
void usbDbgEnable(USBHDriver *host, bool enable) {
|
||||
struct usbh_debug_helper *const debug = &host->debug;
|
||||
#else
|
||||
void usbDbgEnable(bool enable) {
|
||||
struct usbh_debug_helper *const debug = &usbh_debug;
|
||||
#endif
|
||||
debug->on = enable;
|
||||
}
|
||||
|
||||
static void usb_debug_thread(void *arg) {
|
||||
USBHDriver *host = (USBHDriver *)arg;
|
||||
uint8_t state = 0;
|
||||
#if USBH_DEBUG_MULTI_HOST
|
||||
USBHDriver *const host = (USBHDriver *)arg;
|
||||
struct usbh_debug_helper *const debug = &host->debug;
|
||||
#else
|
||||
(void)arg;
|
||||
struct usbh_debug_helper *const debug = &usbh_debug;
|
||||
#endif
|
||||
|
||||
uint8_t rdbuff[TEMP_BUFF_LEN + 1];
|
||||
|
||||
chRegSetThreadName("USBH_DBG");
|
||||
while (true) {
|
||||
msg_t c = iqGet(&host->iq);
|
||||
if (c < 0) goto reset;
|
||||
|
||||
if (state == 0) {
|
||||
if (c == 0xff) state = 1;
|
||||
} else if (state == 1) {
|
||||
if (c == 0xff) state = 2;
|
||||
else if (c == 0xfe) state = 3;
|
||||
else (state = 0);
|
||||
} else if (state == 2) {
|
||||
uint16_t hfir;
|
||||
uint32_t hfnum;
|
||||
|
||||
hfir = c;
|
||||
c = iqGet(&host->iq); if (c < 0) goto reset;
|
||||
hfir |= c << 8;
|
||||
|
||||
c = iqGet(&host->iq); if (c < 0) goto reset;
|
||||
hfnum = c;
|
||||
c = iqGet(&host->iq); if (c < 0) goto reset;
|
||||
hfnum |= c << 8;
|
||||
c = iqGet(&host->iq); if (c < 0) goto reset;
|
||||
hfnum |= c << 16;
|
||||
c = iqGet(&host->iq); if (c < 0) goto reset;
|
||||
hfnum |= c << 24;
|
||||
|
||||
uint32_t f = hfnum & 0xffff;
|
||||
uint32_t p = 1000 - ((hfnum >> 16) / (hfir / 1000));
|
||||
dbg_lock();
|
||||
chprintf((BaseSequentialStream *)&USBH_DEBUG_SD, "%05d.%03d ", f, p);
|
||||
state = 4;
|
||||
} else if (state == 3) {
|
||||
uint32_t t;
|
||||
|
||||
c = iqGet(&host->iq); if (c < 0) goto reset;
|
||||
c = iqGet(&host->iq); if (c < 0) goto reset;
|
||||
|
||||
t = c;
|
||||
c = iqGet(&host->iq); if (c < 0) goto reset;
|
||||
t |= c << 8;
|
||||
c = iqGet(&host->iq); if (c < 0) goto reset;
|
||||
t |= c << 16;
|
||||
c = iqGet(&host->iq); if (c < 0) goto reset;
|
||||
t |= c << 24;
|
||||
|
||||
dbg_lock();
|
||||
chprintf((BaseSequentialStream *)&USBH_DEBUG_SD, "+%08d ", t);
|
||||
state = 4;
|
||||
chSysLock();
|
||||
int len = dq_read_oldest_string(&debug->dq, rdbuff);
|
||||
if (!len) {
|
||||
chThdSuspendS(&debug->tr);
|
||||
chSysUnlock();
|
||||
} else {
|
||||
while (true) {
|
||||
if (!c) {
|
||||
sdPut(&USBH_DEBUG_SD, '\r');
|
||||
sdPut(&USBH_DEBUG_SD, '\n');
|
||||
goto reset;
|
||||
}
|
||||
sdPut(&USBH_DEBUG_SD, (uint8_t)c);
|
||||
c = iqGet(&host->iq); if (c < 0) goto reset;
|
||||
}
|
||||
dq_remove_oldest_string(&debug->dq);
|
||||
chSysUnlock();
|
||||
#if USBH_DEBUG_MULTI_HOST
|
||||
USBH_DEBUG_OUTPUT_CALLBACK(host, rdbuff, len);
|
||||
#else
|
||||
USBH_DEBUG_OUTPUT_CALLBACK(rdbuff, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
continue;
|
||||
reset:
|
||||
if (state == 4) {
|
||||
dbg_unlock();
|
||||
}
|
||||
state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if USBH_DEBUG_MULTI_HOST
|
||||
void usbDbgInit(USBHDriver *host) {
|
||||
if (host != &USBH_DEBUG_USBHD)
|
||||
return;
|
||||
iqObjectInit(&USBH_DEBUG_USBHD.iq, USBH_DEBUG_USBHD.dbg_buff, sizeof(USBH_DEBUG_USBHD.dbg_buff), 0, 0);
|
||||
chThdCreateStatic(USBH_DEBUG_USBHD.waDebug, sizeof(USBH_DEBUG_USBHD.waDebug), NORMALPRIO, usb_debug_thread, &USBH_DEBUG_USBHD);
|
||||
struct usbh_debug_helper *const debug = &host->debug;
|
||||
void *param = host;
|
||||
#else
|
||||
void usbDbgInit(void) {
|
||||
struct usbh_debug_helper *const debug = &usbh_debug;
|
||||
void *param = NULL;
|
||||
#endif
|
||||
dq_init(&debug->dq, debug->buff, sizeof(debug->buff));
|
||||
debug->on = true;
|
||||
chThdCreateStatic(debug->thd_wa, sizeof(debug->thd_wa),
|
||||
NORMALPRIO, usb_debug_thread, param);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
void cfg_iter_init(generic_iterator_t *icfg, const uint8_t *buff, uint16_t rem) {
|
||||
icfg->valid = 0;
|
||||
|
||||
if ((buff[0] < 2) || (rem < 2) || (rem < buff[0])
|
||||
if ((rem < 2) || (buff[0] < 2) || (rem < buff[0])
|
||||
|| (buff[0] < USBH_DT_CONFIG_SIZE)
|
||||
|| (buff[1] != USBH_DT_CONFIG))
|
||||
return;
|
||||
|
@ -45,14 +45,14 @@ void if_iter_next(if_iterator_t *iif) {
|
|||
|
||||
iif->valid = 0;
|
||||
|
||||
if ((curr[0] < 2) || (rem < 2) || (rem < curr[0]))
|
||||
if ((rem < 2) || (curr[0] < 2) || (rem < curr[0]))
|
||||
return;
|
||||
|
||||
for (;;) {
|
||||
rem -= curr[0];
|
||||
curr += curr[0];
|
||||
|
||||
if ((curr[0] < 2) || (rem < 2) || (rem < curr[0]))
|
||||
if ((rem < 2) || (curr[0] < 2) || (rem < curr[0]))
|
||||
return;
|
||||
|
||||
if (curr[1] == USBH_DT_INTERFACE_ASSOCIATION) {
|
||||
|
@ -92,14 +92,14 @@ void ep_iter_next(generic_iterator_t *iep) {
|
|||
|
||||
iep->valid = 0;
|
||||
|
||||
if ((curr[0] < 2) || (rem < 2) || (rem < curr[0]))
|
||||
if ((rem < 2) || (curr[0] < 2) || (rem < curr[0]))
|
||||
return;
|
||||
|
||||
for (;;) {
|
||||
rem -= curr[0];
|
||||
curr += curr[0];
|
||||
|
||||
if ((curr[0] < 2) || (rem < 2) || (rem < curr[0]))
|
||||
if ((rem < 2) || (curr[0] < 2) || (rem < curr[0]))
|
||||
return;
|
||||
|
||||
if ((curr[1] == USBH_DT_INTERFACE_ASSOCIATION)
|
||||
|
@ -131,13 +131,13 @@ void cs_iter_next(generic_iterator_t *ics) {
|
|||
|
||||
ics->valid = 0;
|
||||
|
||||
if ((curr[0] < 2) || (rem < 2) || (rem < curr[0]))
|
||||
if ((rem < 2) || (curr[0] < 2) || (rem < curr[0]))
|
||||
return;
|
||||
|
||||
rem -= curr[0];
|
||||
curr += curr[0];
|
||||
|
||||
if ((curr[0] < 2) || (rem < 2) || (rem < curr[0]))
|
||||
if ((rem < 2) || (curr[0] < 2) || (rem < curr[0]))
|
||||
return;
|
||||
|
||||
if ((curr[1] == USBH_DT_INTERFACE_ASSOCIATION)
|
||||
|
|
|
@ -27,37 +27,13 @@
|
|||
#include "usbh/dev/ftdi.h"
|
||||
#include "usbh/internal.h"
|
||||
|
||||
#if USBHFTDI_DEBUG_ENABLE_TRACE
|
||||
#define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define udbgf(f, ...) do {} while(0)
|
||||
#define udbg(f, ...) do {} while(0)
|
||||
#endif
|
||||
#define _USBH_DEBUG_HELPER_CLASS_DRIVER ftdipp->ftdip
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_TRACE USBHFTDI_DEBUG_ENABLE_TRACE
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_INFO USBHFTDI_DEBUG_ENABLE_INFO
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_WARNINGS USBHFTDI_DEBUG_ENABLE_WARNINGS
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_ERRORS USBHFTDI_DEBUG_ENABLE_ERRORS
|
||||
#include "usbh/debug_helpers.h"
|
||||
|
||||
#if USBHFTDI_DEBUG_ENABLE_INFO
|
||||
#define uinfof(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uinfo(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uinfof(f, ...) do {} while(0)
|
||||
#define uinfo(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBHFTDI_DEBUG_ENABLE_WARNINGS
|
||||
#define uwarnf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uwarn(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uwarnf(f, ...) do {} while(0)
|
||||
#define uwarn(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBHFTDI_DEBUG_ENABLE_ERRORS
|
||||
#define uerrf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uerr(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uerrf(f, ...) do {} while(0)
|
||||
#define uerr(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
static void _ftdip_object_init(USBHFTDIPortDriver *ftdipp);
|
||||
|
||||
|
@ -105,7 +81,7 @@ static usbh_baseclassdriver_t *_ftdi_load(usbh_device_t *dev, const uint8_t *des
|
|||
case 0xE2E6:
|
||||
break;
|
||||
default:
|
||||
uerr("FTDI: Unrecognized PID");
|
||||
udeverr("FTDI: Unrecognized PID");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -114,7 +90,7 @@ static usbh_baseclassdriver_t *_ftdi_load(usbh_device_t *dev, const uint8_t *des
|
|||
return NULL;
|
||||
|
||||
if (((const usbh_interface_descriptor_t *)descriptor)->bInterfaceNumber != 0) {
|
||||
uwarn("FTDI: Will allocate driver along with IF #0");
|
||||
udevwarn("FTDI: Will allocate driver along with IF #0");
|
||||
}
|
||||
|
||||
/* alloc driver */
|
||||
|
@ -125,7 +101,7 @@ static usbh_baseclassdriver_t *_ftdi_load(usbh_device_t *dev, const uint8_t *des
|
|||
}
|
||||
}
|
||||
|
||||
uwarn("FTDI: Can't alloc driver");
|
||||
udevwarn("FTDI: Can't alloc driver");
|
||||
|
||||
/* can't alloc */
|
||||
return NULL;
|
||||
|
@ -135,24 +111,24 @@ alloc_ok:
|
|||
ftdip->ports = 0;
|
||||
switch (dev->devDesc.bcdDevice) {
|
||||
case 0x200: //AM
|
||||
uinfo("FTDI: Type A chip");
|
||||
udevinfo("FTDI: Type A chip");
|
||||
ftdip->type = USBHFTDI_TYPE_A;
|
||||
break;
|
||||
case 0x400: //BM
|
||||
case 0x500: //2232C
|
||||
case 0x600: //R
|
||||
case 0x1000: //230X
|
||||
uinfo("FTDI: Type B chip");
|
||||
udevinfo("FTDI: Type B chip");
|
||||
ftdip->type = USBHFTDI_TYPE_B;
|
||||
break;
|
||||
case 0x700: //2232H;
|
||||
case 0x800: //4232H;
|
||||
case 0x900: //232H;
|
||||
uinfo("FTDI: Type H chip");
|
||||
udevinfo("FTDI: Type H chip");
|
||||
ftdip->type = USBHFTDI_TYPE_H;
|
||||
break;
|
||||
default:
|
||||
uerr("FTDI: Unrecognized chip type");
|
||||
udeverr("FTDI: Unrecognized chip type");
|
||||
return NULL;
|
||||
}
|
||||
usbhEPSetName(&dev->ctrl, "FTD[CTRL]");
|
||||
|
@ -163,11 +139,11 @@ alloc_ok:
|
|||
cfg_iter_init(&icfg, dev->fullConfigurationDescriptor, dev->basicConfigDesc.wTotalLength);
|
||||
for (if_iter_init(&iif, &icfg); iif.valid; if_iter_next(&iif)) {
|
||||
const usbh_interface_descriptor_t *const ifdesc = if_get(&iif);
|
||||
uinfof("FTDI: Interface #%d", ifdesc->bInterfaceNumber);
|
||||
udevinfof("FTDI: Interface #%d", ifdesc->bInterfaceNumber);
|
||||
|
||||
USBHFTDIPortDriver *const prt = _find_port();
|
||||
if (prt == NULL) {
|
||||
uwarn("\tCan't alloc port for this interface");
|
||||
udevwarn("\tCan't alloc port for this interface");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -178,23 +154,23 @@ alloc_ok:
|
|||
for (ep_iter_init(&iep, &iif); iep.valid; ep_iter_next(&iep)) {
|
||||
const usbh_endpoint_descriptor_t *const epdesc = ep_get(&iep);
|
||||
if ((epdesc->bEndpointAddress & 0x80) && (epdesc->bmAttributes == USBH_EPTYPE_BULK)) {
|
||||
uinfof("BULK IN endpoint found: bEndpointAddress=%02x", epdesc->bEndpointAddress);
|
||||
udevinfof("BULK IN endpoint found: bEndpointAddress=%02x", epdesc->bEndpointAddress);
|
||||
usbhEPObjectInit(&prt->epin, dev, epdesc);
|
||||
usbhEPSetName(&prt->epin, "FTD[BIN ]");
|
||||
} else if (((epdesc->bEndpointAddress & 0x80) == 0)
|
||||
&& (epdesc->bmAttributes == USBH_EPTYPE_BULK)) {
|
||||
uinfof("BULK OUT endpoint found: bEndpointAddress=%02x", epdesc->bEndpointAddress);
|
||||
udevinfof("BULK OUT endpoint found: bEndpointAddress=%02x", epdesc->bEndpointAddress);
|
||||
usbhEPObjectInit(&prt->epout, dev, epdesc);
|
||||
usbhEPSetName(&prt->epout, "FTD[BOUT]");
|
||||
} else {
|
||||
uinfof("unsupported endpoint found: bEndpointAddress=%02x, bmAttributes=%02x",
|
||||
udevinfof("unsupported endpoint found: bEndpointAddress=%02x, bmAttributes=%02x",
|
||||
epdesc->bEndpointAddress, epdesc->bmAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
if ((prt->epin.status != USBH_EPSTATUS_CLOSED)
|
||||
|| (prt->epout.status != USBH_EPSTATUS_CLOSED)) {
|
||||
uwarn("\tCouldn't find endpoints; can't alloc port for this interface");
|
||||
udevwarn("\tCouldn't find endpoints; can't alloc port for this interface");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -336,13 +312,14 @@ static usbh_urbstatus_t _ftdi_port_control(USBHFTDIPortDriver *ftdipp,
|
|||
return usbhControlRequestExtended(ftdipp->ftdip->dev, &req, buff, NULL, OSAL_MS2I(1000));
|
||||
}
|
||||
|
||||
static uint32_t _get_divisor(uint32_t baud, usbhftdi_type_t type) {
|
||||
static uint32_t _get_divisor(const USBHFTDIPortDriver *ftdipp, uint32_t baud) {
|
||||
usbhftdi_type_t type = ftdipp->ftdip->type;
|
||||
static const uint8_t divfrac[8] = {0, 3, 2, 4, 1, 5, 6, 7};
|
||||
uint32_t divisor;
|
||||
|
||||
if (type == USBHFTDI_TYPE_A) {
|
||||
uint32_t divisor3 = ((48000000UL / 2) + baud / 2) / baud;
|
||||
uinfof("FTDI: desired=%dbps, real=%dbps", baud, (48000000UL / 2) / divisor3);
|
||||
uclassdrvinfof("FTDI: desired=%dbps, real=%dbps", baud, (48000000UL / 2) / divisor3);
|
||||
if ((divisor3 & 0x7) == 7)
|
||||
divisor3++; /* round x.7/8 up to x+1 */
|
||||
|
||||
|
@ -359,13 +336,13 @@ static uint32_t _get_divisor(uint32_t baud, usbhftdi_type_t type) {
|
|||
} else {
|
||||
if (type == USBHFTDI_TYPE_B) {
|
||||
divisor = ((48000000UL / 2) + baud / 2) / baud;
|
||||
uinfof("FTDI: desired=%dbps, real=%dbps", baud, (48000000UL / 2) / divisor);
|
||||
uclassdrvinfof("FTDI: desired=%dbps, real=%dbps", baud, (48000000UL / 2) / divisor);
|
||||
} else {
|
||||
/* hi-speed baud rate is 10-bit sampling instead of 16-bit */
|
||||
if (baud < 1200)
|
||||
baud = 1200;
|
||||
divisor = (120000000UL * 8 + baud * 5) / (baud * 10);
|
||||
uinfof("FTDI: desired=%dbps, real=%dbps", baud, (120000000UL * 8) / divisor / 10);
|
||||
uclassdrvinfof("FTDI: desired=%dbps, real=%dbps", baud, (120000000UL * 8) / divisor / 10);
|
||||
}
|
||||
divisor = (divisor >> 3) | (divfrac[divisor & 0x7] << 14);
|
||||
|
||||
|
@ -382,7 +359,7 @@ static uint32_t _get_divisor(uint32_t baud, usbhftdi_type_t type) {
|
|||
}
|
||||
|
||||
static usbh_urbstatus_t _set_baudrate(USBHFTDIPortDriver *ftdipp, uint32_t baudrate) {
|
||||
uint32_t divisor = _get_divisor(baudrate, ftdipp->ftdip->type);
|
||||
uint32_t divisor = _get_divisor(ftdipp, baudrate);
|
||||
uint16_t wValue = (uint16_t)divisor;
|
||||
uint16_t wIndex = (uint16_t)(divisor >> 16);
|
||||
if (ftdipp->ftdip->dev->basicConfigDesc.bNumInterfaces > 1)
|
||||
|
@ -400,7 +377,7 @@ static usbh_urbstatus_t _set_baudrate(USBHFTDIPortDriver *ftdipp, uint32_t baudr
|
|||
|
||||
|
||||
static void _submitOutI(USBHFTDIPortDriver *ftdipp, uint32_t len) {
|
||||
udbgf("FTDI: Submit OUT %d", len);
|
||||
uclassdrvdbgf("FTDI: Submit OUT %d", len);
|
||||
ftdipp->oq_urb.requestedLength = len;
|
||||
usbhURBObjectResetI(&ftdipp->oq_urb);
|
||||
usbhURBSubmitI(&ftdipp->oq_urb);
|
||||
|
@ -415,11 +392,11 @@ static void _out_cb(usbh_urb_t *urb) {
|
|||
chThdDequeueNextI(&ftdipp->oq_waiting, Q_OK);
|
||||
return;
|
||||
case USBH_URBSTATUS_DISCONNECTED:
|
||||
uwarn("FTDI: URB OUT disconnected");
|
||||
uurbwarn("FTDI: URB OUT disconnected");
|
||||
chThdDequeueAllI(&ftdipp->oq_waiting, Q_RESET);
|
||||
return;
|
||||
default:
|
||||
uerrf("FTDI: URB OUT status unexpected = %d", urb->status);
|
||||
uurberrf("FTDI: URB OUT status unexpected = %d", urb->status);
|
||||
break;
|
||||
}
|
||||
usbhURBObjectResetI(&ftdipp->oq_urb);
|
||||
|
@ -493,7 +470,7 @@ static msg_t _put(USBHFTDIPortDriver *ftdipp, uint8_t b) {
|
|||
}
|
||||
|
||||
static void _submitInI(USBHFTDIPortDriver *ftdipp) {
|
||||
udbg("FTDI: Submit IN");
|
||||
uclassdrvdbg("FTDI: Submit IN");
|
||||
usbhURBObjectResetI(&ftdipp->iq_urb);
|
||||
usbhURBSubmitI(&ftdipp->iq_urb);
|
||||
}
|
||||
|
@ -503,9 +480,9 @@ static void _in_cb(usbh_urb_t *urb) {
|
|||
switch (urb->status) {
|
||||
case USBH_URBSTATUS_OK:
|
||||
if (urb->actualLength < 2) {
|
||||
uwarnf("FTDI: URB IN actualLength = %d, < 2", urb->actualLength);
|
||||
uurbwarnf("FTDI: URB IN actualLength = %d, < 2", urb->actualLength);
|
||||
} else if (urb->actualLength > 2) {
|
||||
udbgf("FTDI: URB IN data len=%d, status=%02x %02x",
|
||||
uurbdbgf("FTDI: URB IN data len=%d, status=%02x %02x",
|
||||
urb->actualLength - 2,
|
||||
((uint8_t *)urb->buff)[0],
|
||||
((uint8_t *)urb->buff)[1]);
|
||||
|
@ -514,18 +491,18 @@ static void _in_cb(usbh_urb_t *urb) {
|
|||
chThdDequeueNextI(&ftdipp->iq_waiting, Q_OK);
|
||||
return;
|
||||
} else {
|
||||
udbgf("FTDI: URB IN no data, status=%02x %02x",
|
||||
uurbdbgf("FTDI: URB IN no data, status=%02x %02x",
|
||||
((uint8_t *)urb->buff)[0],
|
||||
((uint8_t *)urb->buff)[1]);
|
||||
// return;
|
||||
}
|
||||
break;
|
||||
case USBH_URBSTATUS_DISCONNECTED:
|
||||
uwarn("FTDI: URB IN disconnected");
|
||||
uurbwarn("FTDI: URB IN disconnected");
|
||||
chThdDequeueAllI(&ftdipp->iq_waiting, Q_RESET);
|
||||
return;
|
||||
default:
|
||||
uerrf("FTDI: URB IN status unexpected = %d", urb->status);
|
||||
uurberrf("FTDI: URB IN status unexpected = %d", urb->status);
|
||||
break;
|
||||
}
|
||||
_submitInI(ftdipp);
|
||||
|
|
|
@ -27,39 +27,12 @@
|
|||
#include "usbh/dev/hid.h"
|
||||
#include "usbh/internal.h"
|
||||
|
||||
#if USBHHID_DEBUG_ENABLE_TRACE
|
||||
#define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define udbgf(f, ...) do {} while(0)
|
||||
#define udbg(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBHHID_DEBUG_ENABLE_INFO
|
||||
#define uinfof(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uinfo(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uinfof(f, ...) do {} while(0)
|
||||
#define uinfo(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBHHID_DEBUG_ENABLE_WARNINGS
|
||||
#define uwarnf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uwarn(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uwarnf(f, ...) do {} while(0)
|
||||
#define uwarn(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBHHID_DEBUG_ENABLE_ERRORS
|
||||
#define uerrf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uerr(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uerrf(f, ...) do {} while(0)
|
||||
#define uerr(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
|
||||
#define _USBH_DEBUG_HELPER_CLASS_DRIVER hidp
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_TRACE USBHHID_DEBUG_ENABLE_TRACE
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_INFO USBHHID_DEBUG_ENABLE_INFO
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_WARNINGS USBHHID_DEBUG_ENABLE_WARNINGS
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_ERRORS USBHHID_DEBUG_ENABLE_ERRORS
|
||||
#include "usbh/debug_helpers.h"
|
||||
|
||||
#define USBH_HID_REQ_GET_REPORT 0x01
|
||||
#define USBH_HID_REQ_GET_IDLE 0x02
|
||||
|
@ -113,7 +86,7 @@ static usbh_baseclassdriver_t *_hid_load(usbh_device_t *dev, const uint8_t *desc
|
|||
}
|
||||
}
|
||||
|
||||
uwarn("Can't alloc HID driver");
|
||||
udevwarn("Can't alloc HID driver");
|
||||
|
||||
/* can't alloc */
|
||||
return NULL;
|
||||
|
@ -136,7 +109,7 @@ alloc_ok:
|
|||
for (ep_iter_init(&iep, &iif); iep.valid; ep_iter_next(&iep)) {
|
||||
const usbh_endpoint_descriptor_t *const epdesc = ep_get(&iep);
|
||||
if ((epdesc->bEndpointAddress & 0x80) && (epdesc->bmAttributes == USBH_EPTYPE_INT)) {
|
||||
uinfof("INT IN endpoint found: bEndpointAddress=%02x", epdesc->bEndpointAddress);
|
||||
udevinfof("INT IN endpoint found: bEndpointAddress=%02x", epdesc->bEndpointAddress);
|
||||
usbhEPObjectInit(&hidp->epin, dev, epdesc);
|
||||
usbhEPSetName(&hidp->epin, "HID[IIN ]");
|
||||
#if HAL_USBHHID_USE_INTERRUPT_OUT
|
||||
|
@ -147,7 +120,7 @@ alloc_ok:
|
|||
usbhEPSetName(&hidp->epout, "HID[IOUT]");
|
||||
#endif
|
||||
} else {
|
||||
uinfof("unsupported endpoint found: bEndpointAddress=%02x, bmAttributes=%02x",
|
||||
udevinfof("unsupported endpoint found: bEndpointAddress=%02x, bmAttributes=%02x",
|
||||
epdesc->bEndpointAddress, epdesc->bmAttributes);
|
||||
}
|
||||
}
|
||||
|
@ -157,19 +130,19 @@ alloc_ok:
|
|||
|
||||
if (ifdesc->bInterfaceSubClass != 0x01) {
|
||||
hidp->type = USBHHID_DEVTYPE_GENERIC;
|
||||
uinfof("HID: bInterfaceSubClass=%02x, generic HID", ifdesc->bInterfaceSubClass);
|
||||
udevinfof("HID: bInterfaceSubClass=%02x, generic HID", ifdesc->bInterfaceSubClass);
|
||||
if (ifdesc->bInterfaceSubClass != 0x00) {
|
||||
uinfof("HID: bInterfaceSubClass=%02x is an invalid bInterfaceSubClass value",
|
||||
udevinfof("HID: bInterfaceSubClass=%02x is an invalid bInterfaceSubClass value",
|
||||
ifdesc->bInterfaceSubClass);
|
||||
}
|
||||
} else if (ifdesc->bInterfaceProtocol == 0x01) {
|
||||
hidp->type = USBHHID_DEVTYPE_BOOT_KEYBOARD;
|
||||
uinfo("HID: BOOT protocol keyboard found");
|
||||
udevinfo("HID: BOOT protocol keyboard found");
|
||||
} else if (ifdesc->bInterfaceProtocol == 0x02) {
|
||||
hidp->type = USBHHID_DEVTYPE_BOOT_MOUSE;
|
||||
uinfo("HID: BOOT protocol mouse found");
|
||||
udevinfo("HID: BOOT protocol mouse found");
|
||||
} else {
|
||||
uerrf("HID: bInterfaceProtocol=%02x is an invalid boot protocol, abort",
|
||||
udeverrf("HID: bInterfaceProtocol=%02x is an invalid boot protocol, abort",
|
||||
ifdesc->bInterfaceProtocol);
|
||||
goto deinit;
|
||||
}
|
||||
|
@ -200,14 +173,14 @@ static void _in_cb(usbh_urb_t *urb) {
|
|||
}
|
||||
break;
|
||||
case USBH_URBSTATUS_DISCONNECTED:
|
||||
uwarn("HID: URB IN disconnected");
|
||||
uurbwarn("HID: URB IN disconnected");
|
||||
|
||||
return;
|
||||
case USBH_URBSTATUS_TIMEOUT:
|
||||
//no data
|
||||
break;
|
||||
default:
|
||||
uerrf("HID: URB IN status unexpected = %d", urb->status);
|
||||
uurberrf("HID: URB IN status unexpected = %d", urb->status);
|
||||
break;
|
||||
}
|
||||
usbhURBObjectResetI(&hidp->in_urb);
|
||||
|
|
|
@ -27,38 +27,12 @@
|
|||
#include "usbh/dev/hub.h"
|
||||
#include "usbh/internal.h"
|
||||
|
||||
#if USBHHUB_DEBUG_ENABLE_TRACE
|
||||
#define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define udbgf(f, ...) do {} while(0)
|
||||
#define udbg(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBHHUB_DEBUG_ENABLE_INFO
|
||||
#define uinfof(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uinfo(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uinfof(f, ...) do {} while(0)
|
||||
#define uinfo(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBHHUB_DEBUG_ENABLE_WARNINGS
|
||||
#define uwarnf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uwarn(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uwarnf(f, ...) do {} while(0)
|
||||
#define uwarn(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBHHUB_DEBUG_ENABLE_ERRORS
|
||||
#define uerrf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uerr(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uerrf(f, ...) do {} while(0)
|
||||
#define uerr(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#define _USBH_DEBUG_HELPER_CLASS_DRIVER hubp
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_TRACE USBHHUB_DEBUG_ENABLE_TRACE
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_INFO USBHHUB_DEBUG_ENABLE_INFO
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_WARNINGS USBHHUB_DEBUG_ENABLE_WARNINGS
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_ERRORS USBHHUB_DEBUG_ENABLE_ERRORS
|
||||
#include "usbh/debug_helpers.h"
|
||||
|
||||
USBHHubDriver USBHHUBD[HAL_USBHHUB_MAX_INSTANCES];
|
||||
static usbh_port_t USBHPorts[HAL_USBHHUB_MAX_PORTS];
|
||||
|
@ -106,13 +80,13 @@ static void _urb_complete(usbh_urb_t *urb) {
|
|||
switch (urb->status) {
|
||||
case USBH_URBSTATUS_TIMEOUT:
|
||||
/* the device NAKed */
|
||||
udbg("HUB: no info");
|
||||
uurbdbg("HUB: no info");
|
||||
//hubdp->statuschange = 0;
|
||||
break;
|
||||
case USBH_URBSTATUS_OK: {
|
||||
uint8_t len = hubdp->hubDesc.bNbrPorts / 8 + 1;
|
||||
if (urb->actualLength != len) {
|
||||
uwarnf("Expected %d status change bytes but got %d", len, urb->actualLength);
|
||||
uurbwarnf("Expected %d status change bytes but got %d", len, urb->actualLength);
|
||||
}
|
||||
|
||||
if (urb->actualLength < len)
|
||||
|
@ -126,13 +100,13 @@ static void _urb_complete(usbh_urb_t *urb) {
|
|||
while (len--)
|
||||
*sc++ |= *r++;
|
||||
|
||||
uinfof("HUB: change, %08x", hubdp->statuschange);
|
||||
uurbinfof("HUB: change, %08x", hubdp->statuschange);
|
||||
} break;
|
||||
case USBH_URBSTATUS_DISCONNECTED:
|
||||
uwarn("HUB: URB disconnected, aborting poll");
|
||||
uurbwarn("HUB: URB disconnected, aborting poll");
|
||||
return;
|
||||
default:
|
||||
uerrf("HUB: URB status unexpected = %d", urb->status);
|
||||
uurberrf("HUB: URB status unexpected = %d", urb->status);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -181,7 +155,7 @@ static usbh_baseclassdriver_t *_hub_load(usbh_device_t *dev,
|
|||
}
|
||||
}
|
||||
|
||||
uwarn("Can't alloc HUB driver");
|
||||
udevwarn("Can't alloc HUB driver");
|
||||
|
||||
/* can't alloc */
|
||||
return NULL;
|
||||
|
@ -195,7 +169,7 @@ alloc_ok:
|
|||
usbhEPSetName(&dev->ctrl, "HUB[CTRL]");
|
||||
|
||||
/* read Hub descriptor */
|
||||
uinfo("Read Hub descriptor");
|
||||
udevinfo("Read Hub descriptor");
|
||||
if (usbhhubControlRequest(dev->host, hubdp,
|
||||
USBH_REQTYPE_DIR_IN | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_DEVICE,
|
||||
USBH_REQ_GET_DESCRIPTOR,
|
||||
|
@ -207,7 +181,7 @@ alloc_ok:
|
|||
|
||||
const usbh_hub_descriptor_t *const hubdesc = &hubdp->hubDesc;
|
||||
|
||||
uinfof("Hub descriptor loaded; %d ports, wHubCharacteristics=%04x, bPwrOn2PwrGood=%d, bHubContrCurrent=%d",
|
||||
udevinfof("Hub descriptor loaded; %d ports, wHubCharacteristics=%04x, bPwrOn2PwrGood=%d, bHubContrCurrent=%d",
|
||||
hubdesc->bNbrPorts,
|
||||
hubdesc->wHubCharacteristics,
|
||||
hubdesc->bPwrOn2PwrGood,
|
||||
|
@ -217,7 +191,7 @@ alloc_ok:
|
|||
uint8_t ports = hubdesc->bNbrPorts;
|
||||
for (i = 0; (ports > 0) && (i < HAL_USBHHUB_MAX_PORTS); i++) {
|
||||
if (USBHPorts[i].hub == NULL) {
|
||||
uinfof("Alloc port %d", ports);
|
||||
udevinfof("Alloc port %d", ports);
|
||||
_usbhub_port_object_init(&USBHPorts[i], dev->host, hubdp, ports);
|
||||
USBHPorts[i].next = hubdp->ports;
|
||||
hubdp->ports = &USBHPorts[i];
|
||||
|
@ -226,7 +200,7 @@ alloc_ok:
|
|||
}
|
||||
|
||||
if (ports) {
|
||||
uwarn("Could not alloc all ports");
|
||||
udevwarn("Could not alloc all ports");
|
||||
}
|
||||
|
||||
/* link hub to the host's list */
|
||||
|
@ -235,7 +209,7 @@ alloc_ok:
|
|||
/* enable power to ports */
|
||||
usbh_port_t *port = hubdp->ports;
|
||||
while (port) {
|
||||
uinfof("Enable power for port %d", port->number);
|
||||
udevinfof("Enable power for port %d", port->number);
|
||||
usbhhubSetFeaturePort(port, USBH_PORT_FEAT_POWER);
|
||||
port = port->next;
|
||||
}
|
||||
|
|
|
@ -27,37 +27,12 @@
|
|||
#include "usbh/dev/msd.h"
|
||||
#include "usbh/internal.h"
|
||||
|
||||
#if USBHMSD_DEBUG_ENABLE_TRACE
|
||||
#define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define udbgf(f, ...) do {} while(0)
|
||||
#define udbg(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBHMSD_DEBUG_ENABLE_INFO
|
||||
#define uinfof(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uinfo(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uinfof(f, ...) do {} while(0)
|
||||
#define uinfo(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBHMSD_DEBUG_ENABLE_WARNINGS
|
||||
#define uwarnf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uwarn(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uwarnf(f, ...) do {} while(0)
|
||||
#define uwarn(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBHMSD_DEBUG_ENABLE_ERRORS
|
||||
#define uerrf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uerr(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uerrf(f, ...) do {} while(0)
|
||||
#define uerr(f, ...) do {} while(0)
|
||||
#endif
|
||||
#define _USBH_DEBUG_HELPER_CLASS_DRIVER msdp
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_TRACE USBHMSD_DEBUG_ENABLE_TRACE
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_INFO USBHMSD_DEBUG_ENABLE_INFO
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_WARNINGS USBHMSD_DEBUG_ENABLE_WARNINGS
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_ERRORS USBHMSD_DEBUG_ENABLE_ERRORS
|
||||
#include "usbh/debug_helpers.h"
|
||||
|
||||
static void _lun_object_deinit(USBHMassStorageLUNDriver *lunp);
|
||||
|
||||
|
@ -122,7 +97,7 @@ static usbh_baseclassdriver_t *_msd_load(usbh_device_t *dev, const uint8_t *desc
|
|||
}
|
||||
}
|
||||
|
||||
uwarn("Can't alloc MSD driver");
|
||||
udevwarn("Can't alloc MSD driver");
|
||||
|
||||
/* can't alloc */
|
||||
return NULL;
|
||||
|
@ -146,16 +121,16 @@ alloc_ok:
|
|||
for (ep_iter_init(&iep, &iif); iep.valid; ep_iter_next(&iep)) {
|
||||
const usbh_endpoint_descriptor_t *const epdesc = ep_get(&iep);
|
||||
if ((epdesc->bEndpointAddress & 0x80) && (epdesc->bmAttributes == USBH_EPTYPE_BULK)) {
|
||||
uinfof("BULK IN endpoint found: bEndpointAddress=%02x", epdesc->bEndpointAddress);
|
||||
udevinfof("BULK IN endpoint found: bEndpointAddress=%02x", epdesc->bEndpointAddress);
|
||||
usbhEPObjectInit(&msdp->epin, dev, epdesc);
|
||||
usbhEPSetName(&msdp->epin, "MSD[BIN ]");
|
||||
} else if (((epdesc->bEndpointAddress & 0x80) == 0)
|
||||
&& (epdesc->bmAttributes == USBH_EPTYPE_BULK)) {
|
||||
uinfof("BULK OUT endpoint found: bEndpointAddress=%02x", epdesc->bEndpointAddress);
|
||||
udevinfof("BULK OUT endpoint found: bEndpointAddress=%02x", epdesc->bEndpointAddress);
|
||||
usbhEPObjectInit(&msdp->epout, dev, epdesc);
|
||||
usbhEPSetName(&msdp->epout, "MSD[BOUT]");
|
||||
} else {
|
||||
uinfof("unsupported endpoint found: bEndpointAddress=%02x, bmAttributes=%02x",
|
||||
udevinfof("unsupported endpoint found: bEndpointAddress=%02x, bmAttributes=%02x",
|
||||
epdesc->bEndpointAddress, epdesc->bmAttributes);
|
||||
}
|
||||
}
|
||||
|
@ -164,23 +139,23 @@ alloc_ok:
|
|||
}
|
||||
|
||||
/* read the number of LUNs */
|
||||
uinfo("Reading Max LUN:");
|
||||
udevinfo("Reading Max LUN:");
|
||||
USBH_DEFINE_BUFFER(uint8_t buff[4]);
|
||||
stat = usbhControlRequest(dev,
|
||||
USBH_REQTYPE_CLASSIN(USBH_REQTYPE_RECIP_INTERFACE),
|
||||
MSD_GET_MAX_LUN, 0, msdp->ifnum, 1, buff);
|
||||
if (stat == USBH_URBSTATUS_OK) {
|
||||
msdp->max_lun = buff[0] + 1;
|
||||
uinfof("\tmax_lun = %d", msdp->max_lun);
|
||||
udevinfof("\tmax_lun = %d", msdp->max_lun);
|
||||
if (msdp->max_lun > HAL_USBHMSD_MAX_LUNS) {
|
||||
msdp->max_lun = HAL_USBHMSD_MAX_LUNS;
|
||||
uwarnf("\tUsing max_lun = %d", msdp->max_lun);
|
||||
udevwarnf("\tUsing max_lun = %d", msdp->max_lun);
|
||||
}
|
||||
} else if (stat == USBH_URBSTATUS_STALL) {
|
||||
uwarn("\tStall, max_lun = 1");
|
||||
udevwarn("\tStall, max_lun = 1");
|
||||
msdp->max_lun = 1;
|
||||
} else {
|
||||
uerr("\tError");
|
||||
udeverr("\tError");
|
||||
goto deinit;
|
||||
}
|
||||
|
||||
|
@ -293,28 +268,30 @@ static bool _msd_bot_reset(USBHMassStorageDriver *msdp) {
|
|||
|
||||
static msd_bot_result_t _msd_bot_transaction(msd_transaction_t *tran, USBHMassStorageLUNDriver *lunp, void *data) {
|
||||
|
||||
USBHMassStorageDriver *const msdp = lunp->msdp;
|
||||
|
||||
uint32_t data_actual_len, actual_len;
|
||||
usbh_urbstatus_t status;
|
||||
USBH_DEFINE_BUFFER(msd_csw_t csw);
|
||||
|
||||
tran->cbw->bCBWLUN = (uint8_t)(lunp - &lunp->msdp->luns[0]);
|
||||
tran->cbw->bCBWLUN = (uint8_t)(lunp - &msdp->luns[0]);
|
||||
tran->cbw->dCBWSignature = MSD_CBW_SIGNATURE;
|
||||
tran->cbw->dCBWTag = ++lunp->msdp->tag;
|
||||
tran->cbw->dCBWTag = ++msdp->tag;
|
||||
tran->data_processed = 0;
|
||||
|
||||
/* control phase */
|
||||
status = usbhBulkTransfer(&lunp->msdp->epout, tran->cbw,
|
||||
status = usbhBulkTransfer(&msdp->epout, tran->cbw,
|
||||
sizeof(*tran->cbw), &actual_len, OSAL_MS2I(1000));
|
||||
|
||||
if (status == USBH_URBSTATUS_CANCELLED) {
|
||||
uerr("\tMSD: Control phase: USBH_URBSTATUS_CANCELLED");
|
||||
uclassdrverr("\tMSD: Control phase: USBH_URBSTATUS_CANCELLED");
|
||||
return MSD_BOTRESULT_DISCONNECTED;
|
||||
}
|
||||
|
||||
if ((status != USBH_URBSTATUS_OK) || (actual_len != sizeof(*tran->cbw))) {
|
||||
uerrf("\tMSD: Control phase: status = %d (!= OK), actual_len = %d (expected to send %d)",
|
||||
uclassdrverrf("\tMSD: Control phase: status = %d (!= OK), actual_len = %d (expected to send %d)",
|
||||
status, actual_len, sizeof(*tran->cbw));
|
||||
_msd_bot_reset(lunp->msdp);
|
||||
_msd_bot_reset(msdp);
|
||||
return MSD_BOTRESULT_ERROR;
|
||||
}
|
||||
|
||||
|
@ -322,7 +299,7 @@ static msd_bot_result_t _msd_bot_transaction(msd_transaction_t *tran, USBHMassSt
|
|||
/* data phase */
|
||||
data_actual_len = 0;
|
||||
if (tran->cbw->dCBWDataTransferLength) {
|
||||
usbh_ep_t *const ep = tran->cbw->bmCBWFlags & MSD_CBWFLAGS_D2H ? &lunp->msdp->epin : &lunp->msdp->epout;
|
||||
usbh_ep_t *const ep = tran->cbw->bmCBWFlags & MSD_CBWFLAGS_D2H ? &msdp->epin : &msdp->epout;
|
||||
status = usbhBulkTransfer(
|
||||
ep,
|
||||
data,
|
||||
|
@ -330,62 +307,62 @@ static msd_bot_result_t _msd_bot_transaction(msd_transaction_t *tran, USBHMassSt
|
|||
&data_actual_len, OSAL_MS2I(20000));
|
||||
|
||||
if (status == USBH_URBSTATUS_CANCELLED) {
|
||||
uerr("\tMSD: Data phase: USBH_URBSTATUS_CANCELLED");
|
||||
uclassdrverr("\tMSD: Data phase: USBH_URBSTATUS_CANCELLED");
|
||||
return MSD_BOTRESULT_DISCONNECTED;
|
||||
}
|
||||
|
||||
if (status == USBH_URBSTATUS_STALL) {
|
||||
uerrf("\tMSD: Data phase: USBH_URBSTATUS_STALL, clear halt");
|
||||
uclassdrverrf("\tMSD: Data phase: USBH_URBSTATUS_STALL, clear halt");
|
||||
status = (usbhEPReset(ep) == HAL_SUCCESS) ? USBH_URBSTATUS_OK : USBH_URBSTATUS_ERROR;
|
||||
}
|
||||
|
||||
if (status != USBH_URBSTATUS_OK) {
|
||||
uerrf("\tMSD: Data phase: status = %d (!= OK), resetting", status);
|
||||
_msd_bot_reset(lunp->msdp);
|
||||
uclassdrverrf("\tMSD: Data phase: status = %d (!= OK), resetting", status);
|
||||
_msd_bot_reset(msdp);
|
||||
return MSD_BOTRESULT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* status phase */
|
||||
status = usbhBulkTransfer(&lunp->msdp->epin, &csw,
|
||||
status = usbhBulkTransfer(&msdp->epin, &csw,
|
||||
sizeof(csw), &actual_len, OSAL_MS2I(1000));
|
||||
|
||||
if (status == USBH_URBSTATUS_STALL) {
|
||||
uwarn("\tMSD: Status phase: USBH_URBSTATUS_STALL, clear halt and retry");
|
||||
uclassdrvwarn("\tMSD: Status phase: USBH_URBSTATUS_STALL, clear halt and retry");
|
||||
|
||||
status = (usbhEPReset(&lunp->msdp->epin) == HAL_SUCCESS) ? USBH_URBSTATUS_OK : USBH_URBSTATUS_ERROR;
|
||||
status = (usbhEPReset(&msdp->epin) == HAL_SUCCESS) ? USBH_URBSTATUS_OK : USBH_URBSTATUS_ERROR;
|
||||
|
||||
if (status == USBH_URBSTATUS_OK) {
|
||||
status = usbhBulkTransfer(&lunp->msdp->epin, &csw,
|
||||
status = usbhBulkTransfer(&msdp->epin, &csw,
|
||||
sizeof(csw), &actual_len, OSAL_MS2I(1000));
|
||||
}
|
||||
}
|
||||
|
||||
if (status == USBH_URBSTATUS_CANCELLED) {
|
||||
uerr("\tMSD: Status phase: USBH_URBSTATUS_CANCELLED");
|
||||
uclassdrverr("\tMSD: Status phase: USBH_URBSTATUS_CANCELLED");
|
||||
return MSD_BOTRESULT_DISCONNECTED;
|
||||
}
|
||||
|
||||
if (status != USBH_URBSTATUS_OK) {
|
||||
uerrf("\tMSD: Status phase: status = %d (!= OK), resetting", status);
|
||||
_msd_bot_reset(lunp->msdp);
|
||||
uclassdrverrf("\tMSD: Status phase: status = %d (!= OK), resetting", status);
|
||||
_msd_bot_reset(msdp);
|
||||
return MSD_BOTRESULT_ERROR;
|
||||
}
|
||||
|
||||
/* validate CSW */
|
||||
if ((actual_len != sizeof(csw))
|
||||
|| (csw.dCSWSignature != MSD_CSW_SIGNATURE)
|
||||
|| (csw.dCSWTag != lunp->msdp->tag)
|
||||
|| (csw.dCSWTag != msdp->tag)
|
||||
|| (csw.bCSWStatus >= CSW_STATUS_PHASE_ERROR)) {
|
||||
/* CSW is not valid */
|
||||
uerrf("\tMSD: Status phase: Invalid CSW: len=%d, dCSWSignature=%x, dCSWTag=%x (expected %x), bCSWStatus=%d, resetting",
|
||||
uclassdrverrf("\tMSD: Status phase: Invalid CSW: len=%d, dCSWSignature=%x, dCSWTag=%x (expected %x), bCSWStatus=%d, resetting",
|
||||
actual_len,
|
||||
csw.dCSWSignature,
|
||||
csw.dCSWTag,
|
||||
lunp->msdp->tag,
|
||||
msdp->tag,
|
||||
csw.bCSWStatus);
|
||||
_msd_bot_reset(lunp->msdp);
|
||||
_msd_bot_reset(msdp);
|
||||
return MSD_BOTRESULT_ERROR;
|
||||
}
|
||||
|
||||
|
@ -393,17 +370,17 @@ static msd_bot_result_t _msd_bot_transaction(msd_transaction_t *tran, USBHMassSt
|
|||
if ((csw.bCSWStatus != CSW_STATUS_PHASE_ERROR)
|
||||
&& (csw.dCSWDataResidue > tran->cbw->dCBWDataTransferLength)) {
|
||||
/* CSW is not meaningful */
|
||||
uerrf("\tMSD: Status phase: CSW not meaningful: bCSWStatus=%d, dCSWDataResidue=%u, dCBWDataTransferLength=%u, resetting",
|
||||
uclassdrverrf("\tMSD: Status phase: CSW not meaningful: bCSWStatus=%d, dCSWDataResidue=%u, dCBWDataTransferLength=%u, resetting",
|
||||
csw.bCSWStatus,
|
||||
csw.dCSWDataResidue,
|
||||
tran->cbw->dCBWDataTransferLength);
|
||||
_msd_bot_reset(lunp->msdp);
|
||||
_msd_bot_reset(msdp);
|
||||
return MSD_BOTRESULT_ERROR;
|
||||
}
|
||||
|
||||
if (csw.bCSWStatus == CSW_STATUS_PHASE_ERROR) {
|
||||
uerr("\tMSD: Status phase: Phase error, resetting");
|
||||
_msd_bot_reset(lunp->msdp);
|
||||
uclassdrverr("\tMSD: Status phase: Phase error, resetting");
|
||||
_msd_bot_reset(msdp);
|
||||
return MSD_BOTRESULT_ERROR;
|
||||
}
|
||||
|
||||
|
@ -502,6 +479,9 @@ static msd_result_t scsi_requestsense(USBHMassStorageLUNDriver *lunp, scsi_sense
|
|||
static msd_result_t _scsi_perform_transaction(USBHMassStorageLUNDriver *lunp,
|
||||
msd_transaction_t *transaction, void *data) {
|
||||
|
||||
USBHMassStorageDriver *const msdp = lunp->msdp;
|
||||
(void)msdp;
|
||||
|
||||
msd_bot_result_t res;
|
||||
res = _msd_bot_transaction(transaction, lunp, data);
|
||||
if (res != MSD_BOTRESULT_OK) {
|
||||
|
@ -511,13 +491,11 @@ static msd_result_t _scsi_perform_transaction(USBHMassStorageLUNDriver *lunp,
|
|||
if (transaction->csw_status == CSW_STATUS_FAILED) {
|
||||
if (transaction->cbw->CBWCB[0] != SCSI_CMD_REQUEST_SENSE) {
|
||||
/* do auto-sense (except for SCSI_CMD_REQUEST_SENSE!) */
|
||||
uwarn("\tMSD: Command failed, auto-sense");
|
||||
uclassdrvwarn("\tMSD: Command failed, auto-sense");
|
||||
USBH_DEFINE_BUFFER(scsi_sense_response_t sense);
|
||||
if (scsi_requestsense(lunp, &sense) == MSD_RESULT_OK) {
|
||||
uwarnf("\tMSD: REQUEST SENSE: Sense key=%x, ASC=%02x, ASCQ=%02x",
|
||||
uclassdrvwarnf("\tMSD: REQUEST SENSE: Sense key=%x, ASC=%02x, ASCQ=%02x",
|
||||
sense.byte[2] & 0xf, sense.byte[12], sense.byte[13]);
|
||||
|
||||
return MSD_RESULT_OK;
|
||||
}
|
||||
}
|
||||
return MSD_RESULT_FAILED;
|
||||
|
@ -724,6 +702,9 @@ bool usbhmsdLUNConnect(USBHMassStorageLUNDriver *lunp) {
|
|||
osalDbgCheck(lunp->msdp != NULL);
|
||||
msd_result_t res;
|
||||
|
||||
USBHMassStorageDriver *const msdp = lunp->msdp;
|
||||
(void)msdp;
|
||||
|
||||
chSemWait(&lunp->sem);
|
||||
osalDbgAssert((lunp->state == BLK_READY) || (lunp->state == BLK_ACTIVE), "invalid state");
|
||||
if (lunp->state == BLK_READY) {
|
||||
|
@ -734,7 +715,7 @@ bool usbhmsdLUNConnect(USBHMassStorageLUNDriver *lunp) {
|
|||
|
||||
{
|
||||
USBH_DEFINE_BUFFER(scsi_inquiry_response_t inq);
|
||||
uinfo("INQUIRY...");
|
||||
uclassdrvinfo("INQUIRY...");
|
||||
res = scsi_inquiry(lunp, &inq);
|
||||
if (res == MSD_RESULT_DISCONNECTED) {
|
||||
goto failed;
|
||||
|
@ -746,9 +727,9 @@ bool usbhmsdLUNConnect(USBHMassStorageLUNDriver *lunp) {
|
|||
goto failed;
|
||||
}
|
||||
|
||||
uinfof("\tPDT=%02x", inq.peripheral & 0x1f);
|
||||
uclassdrvinfof("\tPDT=%02x", inq.peripheral & 0x1f);
|
||||
if (inq.peripheral != 0) {
|
||||
uerr("\tUnsupported PDT");
|
||||
uclassdrverr("\tUnsupported PDT");
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
@ -756,7 +737,7 @@ bool usbhmsdLUNConnect(USBHMassStorageLUNDriver *lunp) {
|
|||
// Test if unit ready
|
||||
uint8_t i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
uinfo("TEST UNIT READY...");
|
||||
uclassdrvinfo("TEST UNIT READY...");
|
||||
res = scsi_testunitready(lunp);
|
||||
if (res == MSD_RESULT_DISCONNECTED) {
|
||||
goto failed;
|
||||
|
@ -764,11 +745,11 @@ bool usbhmsdLUNConnect(USBHMassStorageLUNDriver *lunp) {
|
|||
//retry?
|
||||
goto failed;
|
||||
} else if (res == MSD_RESULT_FAILED) {
|
||||
uinfo("\tTEST UNIT READY: Command Failed, retry");
|
||||
uclassdrvinfo("\tTEST UNIT READY: Command Failed, retry");
|
||||
osalThreadSleepMilliseconds(200);
|
||||
continue;
|
||||
}
|
||||
uinfo("\tReady.");
|
||||
uclassdrvinfo("\tReady.");
|
||||
break;
|
||||
}
|
||||
if (i == 10) goto failed;
|
||||
|
@ -776,7 +757,7 @@ bool usbhmsdLUNConnect(USBHMassStorageLUNDriver *lunp) {
|
|||
{
|
||||
USBH_DEFINE_BUFFER(scsi_readcapacity10_response_t cap);
|
||||
// Read capacity
|
||||
uinfo("READ CAPACITY(10)...");
|
||||
uclassdrvinfo("READ CAPACITY(10)...");
|
||||
res = scsi_readcapacity10(lunp, &cap);
|
||||
if (res == MSD_RESULT_DISCONNECTED) {
|
||||
goto failed;
|
||||
|
@ -792,17 +773,17 @@ bool usbhmsdLUNConnect(USBHMassStorageLUNDriver *lunp) {
|
|||
lunp->info.blk_num = __REV(cap.last_block_addr) + 1;
|
||||
}
|
||||
|
||||
uinfof("\tBlock size=%dbytes, blocks=%u (~%u MB)", lunp->info.blk_size, lunp->info.blk_num,
|
||||
uclassdrvinfof("\tBlock size=%dbytes, blocks=%u (~%u MB)", lunp->info.blk_size, lunp->info.blk_num,
|
||||
(uint32_t)(((uint64_t)lunp->info.blk_size * lunp->info.blk_num) / (1024UL * 1024UL)));
|
||||
|
||||
uinfo("MSD Connected.");
|
||||
uclassdrvinfo("MSD Connected.");
|
||||
lunp->state = BLK_READY;
|
||||
chSemSignal(&lunp->sem);
|
||||
return HAL_SUCCESS;
|
||||
|
||||
/* Connection failed, state reset to BLK_ACTIVE.*/
|
||||
failed:
|
||||
uinfo("MSD Connect failed.");
|
||||
uclassdrvinfo("MSD Connect failed.");
|
||||
lunp->state = BLK_ACTIVE;
|
||||
chSemSignal(&lunp->sem);
|
||||
return HAL_FAILED;
|
||||
|
@ -949,6 +930,10 @@ bool usbhmsdLUNIsProtected(USBHMassStorageLUNDriver *lunp) {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
USBHDriver *usbhmsdLUNGetHost(const USBHMassStorageLUNDriver *lunp) {
|
||||
return lunp->msdp->dev->host;
|
||||
}
|
||||
|
||||
static void _msd_object_init(USBHMassStorageDriver *msdp) {
|
||||
osalDbgCheck(msdp != NULL);
|
||||
memset(msdp, 0, sizeof(*msdp));
|
||||
|
|
|
@ -31,38 +31,12 @@
|
|||
#include "usbh/dev/uvc.h"
|
||||
#include "usbh/internal.h"
|
||||
|
||||
#if USBHUVC_DEBUG_ENABLE_TRACE
|
||||
#define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define udbgf(f, ...) do {} while(0)
|
||||
#define udbg(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBHUVC_DEBUG_ENABLE_INFO
|
||||
#define uinfof(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uinfo(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uinfof(f, ...) do {} while(0)
|
||||
#define uinfo(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBHUVC_DEBUG_ENABLE_WARNINGS
|
||||
#define uwarnf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uwarn(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uwarnf(f, ...) do {} while(0)
|
||||
#define uwarn(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#if USBHUVC_DEBUG_ENABLE_ERRORS
|
||||
#define uerrf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
|
||||
#define uerr(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
|
||||
#else
|
||||
#define uerrf(f, ...) do {} while(0)
|
||||
#define uerr(f, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#define _USBH_DEBUG_HELPER_CLASS_DRIVER uvcdp
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_TRACE USBHUVC_DEBUG_ENABLE_TRACE
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_INFO USBHUVC_DEBUG_ENABLE_INFO
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_WARNINGS USBHUVC_DEBUG_ENABLE_WARNINGS
|
||||
#define _USBH_DEBUG_HELPER_ENABLE_ERRORS USBHUVC_DEBUG_ENABLE_ERRORS
|
||||
#include "usbh/debug_helpers.h"
|
||||
|
||||
USBHUVCDriver USBHUVCD[HAL_USBHUVC_MAX_INSTANCES];
|
||||
|
||||
|
@ -124,7 +98,7 @@ bool usbhuvcVSRequest(USBHUVCDriver *uvcdp,
|
|||
static bool _set_vs_alternate(USBHUVCDriver *uvcdp, uint16_t min_ep_size) {
|
||||
|
||||
if (min_ep_size == 0) {
|
||||
uinfo("Selecting Alternate setting 0");
|
||||
uclassdrvinfo("Selecting Alternate setting 0");
|
||||
return usbhStdReqSetInterface(uvcdp->dev, if_get(&uvcdp->ivs)->bInterfaceNumber, 0);
|
||||
}
|
||||
|
||||
|
@ -134,7 +108,7 @@ static bool _set_vs_alternate(USBHUVCDriver *uvcdp, uint16_t min_ep_size) {
|
|||
uint8_t alt = 0;
|
||||
uint16_t sz = 0xffff;
|
||||
|
||||
uinfof("Searching alternate setting with min_ep_size=%d", min_ep_size);
|
||||
uclassdrvinfof("Searching alternate setting with min_ep_size=%d", min_ep_size);
|
||||
|
||||
for (; iif.valid; if_iter_next(&iif)) {
|
||||
const usbh_interface_descriptor_t *const ifdesc = if_get(&iif);
|
||||
|
@ -143,7 +117,7 @@ static bool _set_vs_alternate(USBHUVCDriver *uvcdp, uint16_t min_ep_size) {
|
|||
|| (ifdesc->bInterfaceSubClass != UVC_SC_VIDEOSTREAMING))
|
||||
continue;
|
||||
|
||||
uinfof("\tScanning alternate setting=%d", ifdesc->bAlternateSetting);
|
||||
uclassdrvinfof("\tScanning alternate setting=%d", ifdesc->bAlternateSetting);
|
||||
|
||||
if (ifdesc->bNumEndpoints == 0)
|
||||
continue;
|
||||
|
@ -153,11 +127,11 @@ static bool _set_vs_alternate(USBHUVCDriver *uvcdp, uint16_t min_ep_size) {
|
|||
if (((epdesc->bmAttributes & 0x03) == USBH_EPTYPE_ISO)
|
||||
&& ((epdesc->bEndpointAddress & 0x80) == USBH_EPDIR_IN)) {
|
||||
|
||||
uinfof("\t Endpoint wMaxPacketSize = %d", epdesc->wMaxPacketSize);
|
||||
uclassdrvinfof("\t Endpoint wMaxPacketSize = %d", epdesc->wMaxPacketSize);
|
||||
|
||||
if (epdesc->wMaxPacketSize >= min_ep_size) {
|
||||
if (epdesc->wMaxPacketSize < sz) {
|
||||
uinfo("\t Found new optimal alternate setting");
|
||||
uclassdrvinfo("\t Found new optimal alternate setting");
|
||||
sz = epdesc->wMaxPacketSize;
|
||||
alt = ifdesc->bAlternateSetting;
|
||||
ep = epdesc;
|
||||
|
@ -168,7 +142,7 @@ static bool _set_vs_alternate(USBHUVCDriver *uvcdp, uint16_t min_ep_size) {
|
|||
}
|
||||
|
||||
if (ep && alt) {
|
||||
uinfof("\tSelecting Alternate setting %d", alt);
|
||||
uclassdrvinfof("\tSelecting Alternate setting %d", alt);
|
||||
if (usbhStdReqSetInterface(uvcdp->dev, if_get(&uvcdp->ivs)->bInterfaceNumber, alt) == HAL_SUCCESS) {
|
||||
usbhEPObjectInit(&uvcdp->ep_iso, uvcdp->dev, ep);
|
||||
usbhEPSetName(&uvcdp->ep_iso, "UVC[ISO ]");
|
||||
|
@ -180,20 +154,22 @@ static bool _set_vs_alternate(USBHUVCDriver *uvcdp, uint16_t min_ep_size) {
|
|||
}
|
||||
|
||||
#if USBH_DEBUG_ENABLE && USBHUVC_DEBUG_ENABLE_INFO
|
||||
void usbhuvcPrintProbeCommit(const usbh_uvc_ctrl_vs_probecommit_data_t *pc) {
|
||||
void usbhuvcPrintProbeCommit(USBHUVCDriver *uvcdp,
|
||||
const usbh_uvc_ctrl_vs_probecommit_data_t *pc) {
|
||||
(void)uvcdp;
|
||||
|
||||
//uinfof("UVC: probe/commit data:");
|
||||
uinfof("\tbmHint=%04x", pc->bmHint);
|
||||
uinfof("\tbFormatIndex=%d, bFrameIndex=%d, dwFrameInterval=%u",
|
||||
uclassdrvinfof("\tbmHint=%04x", pc->bmHint);
|
||||
uclassdrvinfof("\tbFormatIndex=%d, bFrameIndex=%d, dwFrameInterval=%u",
|
||||
pc->bFormatIndex, pc->bFrameIndex, pc->dwFrameInterval);
|
||||
uinfof("\twKeyFrameRate=%d, wPFrameRate=%d, wCompQuality=%u, wCompWindowSize=%u",
|
||||
uclassdrvinfof("\twKeyFrameRate=%d, wPFrameRate=%d, wCompQuality=%u, wCompWindowSize=%u",
|
||||
pc->wKeyFrameRate, pc->wPFrameRate, pc->wCompQuality, pc->wCompWindowSize);
|
||||
uinfof("\twDelay=%d", pc->wDelay);
|
||||
uinfof("\tdwMaxVideoFrameSize=%u", pc->dwMaxVideoFrameSize);
|
||||
uinfof("\tdwMaxPayloadTransferSize=%u", pc->dwMaxPayloadTransferSize);
|
||||
/* uinfof("\tdwClockFrequency=%u", pc->dwClockFrequency);
|
||||
uinfof("\tbmFramingInfo=%02x", pc->bmFramingInfo);
|
||||
uinfof("\tbPreferedVersion=%d, bMinVersion=%d, bMaxVersion=%d",
|
||||
uclassdrvinfof("\twDelay=%d", pc->wDelay);
|
||||
uclassdrvinfof("\tdwMaxVideoFrameSize=%u", pc->dwMaxVideoFrameSize);
|
||||
uclassdrvinfof("\tdwMaxPayloadTransferSize=%u", pc->dwMaxPayloadTransferSize);
|
||||
/* uclassdrvinfof("\tdwClockFrequency=%u", pc->dwClockFrequency);
|
||||
uclassdrvinfof("\tbmFramingInfo=%02x", pc->bmFramingInfo);
|
||||
uclassdrvinfof("\tbPreferedVersion=%d, bMinVersion=%d, bMaxVersion=%d",
|
||||
pc->bPreferedVersion, pc->bMinVersion, pc->bMaxVersion); */
|
||||
}
|
||||
#endif
|
||||
|
@ -205,7 +181,8 @@ static void _post(USBHUVCDriver *uvcdp, usbh_urb_t *urb, memory_pool_t *mp, uint
|
|||
usbhuvc_message_base_t *const new_msg = (usbhuvc_message_base_t *)chPoolAllocI(mp);
|
||||
if (new_msg != NULL) {
|
||||
/* allocated the new buffer, now try to post the message to the mailbox */
|
||||
if (chMBPostI(&uvcdp->mb, (msg_t)msg) == MSG_OK) {
|
||||
msg_t r = chMBPostI(&uvcdp->mb, (msg_t)msg);
|
||||
if (r == MSG_OK) {
|
||||
/* everything OK, complete the missing fields */
|
||||
msg->type = type;
|
||||
msg->length = urb->actualLength;
|
||||
|
@ -213,12 +190,16 @@ static void _post(USBHUVCDriver *uvcdp, usbh_urb_t *urb, memory_pool_t *mp, uint
|
|||
/* change the URB's buffer to the newly allocated one */
|
||||
urb->buff = ((usbhuvc_message_data_t *)new_msg)->data;
|
||||
} else {
|
||||
if (r == MSG_RESET) {
|
||||
uurbwarn("UVC: error, mailbox reset");
|
||||
} else {
|
||||
uurberr("UVC: error, mailbox overrun");
|
||||
}
|
||||
/* couldn't post the message, free the newly allocated buffer */
|
||||
uerr("UVC: error, mailbox overrun");
|
||||
chPoolFreeI(&uvcdp->mp_status, new_msg);
|
||||
}
|
||||
} else {
|
||||
uerrf("UVC: error, %s pool overrun", mp == &uvcdp->mp_data ? "data" : "status");
|
||||
uurberrf("UVC: error, %s pool overrun", mp == &uvcdp->mp_data ? "data" : "status");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,18 +211,18 @@ static void _cb_int(usbh_urb_t *urb) {
|
|||
if (urb->actualLength >= 2) {
|
||||
_post(uvcdp, urb, &uvcdp->mp_status, USBHUVC_MESSAGETYPE_STATUS);
|
||||
} else {
|
||||
uerrf("UVC: INT IN, actualLength=%d", urb->actualLength);
|
||||
uurberrf("UVC: INT IN, actualLength=%d", urb->actualLength);
|
||||
}
|
||||
break;
|
||||
case USBH_URBSTATUS_TIMEOUT: /* the device NAKed */
|
||||
udbg("UVC: INT IN no info");
|
||||
uurbdbg("UVC: INT IN no info");
|
||||
break;
|
||||
case USBH_URBSTATUS_DISCONNECTED:
|
||||
case USBH_URBSTATUS_CANCELLED:
|
||||
uwarn("UVC: INT IN status = DISCONNECTED/CANCELLED, aborting");
|
||||
uurbwarn("UVC: INT IN status = DISCONNECTED/CANCELLED, aborting");
|
||||
return;
|
||||
default:
|
||||
uerrf("UVC: INT IN error, unexpected status = %d", urb->status);
|
||||
uurberrf("UVC: INT IN error, unexpected status = %d", urb->status);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -254,20 +235,20 @@ static void _cb_iso(usbh_urb_t *urb) {
|
|||
|
||||
if ((urb->status == USBH_URBSTATUS_DISCONNECTED)
|
||||
|| (urb->status == USBH_URBSTATUS_CANCELLED)) {
|
||||
uwarn("UVC: ISO IN status = DISCONNECTED/CANCELLED, aborting");
|
||||
uurbwarn("UVC: ISO IN status = DISCONNECTED/CANCELLED, aborting");
|
||||
return;
|
||||
}
|
||||
|
||||
if (urb->status != USBH_URBSTATUS_OK) {
|
||||
uerrf("UVC: ISO IN error, unexpected status = %d", urb->status);
|
||||
uurberrf("UVC: ISO IN error, unexpected status = %d", urb->status);
|
||||
} else if (urb->actualLength >= 2) {
|
||||
const uint8_t *const buff = (const uint8_t *)urb->buff;
|
||||
if (buff[0] < 2) {
|
||||
uerrf("UVC: ISO IN, bHeaderLength=%d", buff[0]);
|
||||
uurberrf("UVC: ISO IN, bHeaderLength=%d", buff[0]);
|
||||
} else if (buff[0] > urb->actualLength) {
|
||||
uerrf("UVC: ISO IN, bHeaderLength=%d > actualLength=%d", buff[0], urb->actualLength);
|
||||
uurberrf("UVC: ISO IN, bHeaderLength=%d > actualLength=%d", buff[0], urb->actualLength);
|
||||
} else {
|
||||
udbgf("UVC: ISO IN len=%d, hdr=%d, FID=%d, EOF=%d, ERR=%d, EOH=%d",
|
||||
uurbdbgf("UVC: ISO IN len=%d, hdr=%d, FID=%d, EOF=%d, ERR=%d, EOH=%d",
|
||||
urb->actualLength,
|
||||
buff[0],
|
||||
buff[1] & UVC_HDR_FID,
|
||||
|
@ -279,7 +260,7 @@ static void _cb_iso(usbh_urb_t *urb) {
|
|||
|| (buff[1] & (UVC_HDR_EOF | UVC_HDR_ERR))) {
|
||||
_post(uvcdp, urb, &uvcdp->mp_data, USBHUVC_MESSAGETYPE_DATA);
|
||||
} else {
|
||||
udbgf("UVC: ISO IN skip: len=%d, hdr=%d, FID=%d, EOF=%d, ERR=%d, EOH=%d",
|
||||
uurbdbgf("UVC: ISO IN skip: len=%d, hdr=%d, FID=%d, EOF=%d, ERR=%d, EOH=%d",
|
||||
urb->actualLength,
|
||||
buff[0],
|
||||
buff[1] & UVC_HDR_FID,
|
||||
|
@ -289,7 +270,7 @@ static void _cb_iso(usbh_urb_t *urb) {
|
|||
}
|
||||
}
|
||||
} else if (urb->actualLength > 0) {
|
||||
uerrf("UVC: ISO IN, actualLength=%d", urb->actualLength);
|
||||
uurberrf("UVC: ISO IN, actualLength=%d", urb->actualLength);
|
||||
}
|
||||
|
||||
usbhURBObjectResetI(urb);
|
||||
|
@ -327,20 +308,20 @@ bool usbhuvcStreamStart(USBHUVCDriver *uvcdp, uint16_t min_ep_sz) {
|
|||
data_sz = (uvcdp->ep_iso.wMaxPacketSize + sizeof(usbhuvc_message_data_t) + 3) & ~3;
|
||||
datapackets = HAL_USBHUVC_WORK_RAM_SIZE / data_sz;
|
||||
if (datapackets == 0) {
|
||||
uerr("Not enough work RAM");
|
||||
uclassdrverr("Not enough work RAM");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
workramsz = datapackets * data_sz;
|
||||
uinfof("Reserving %u bytes of RAM (%d data packets of %d bytes)", workramsz, datapackets, data_sz);
|
||||
uclassdrvinfof("Reserving %u bytes of RAM (%d data packets of %d bytes)", workramsz, datapackets, data_sz);
|
||||
if (datapackets > (HAL_USBHUVC_MAX_MAILBOX_SZ - HAL_USBHUVC_STATUS_PACKETS_COUNT)) {
|
||||
uwarn("Mailbox may overflow, use a larger HAL_USBHUVC_MAX_MAILBOX_SZ. UVC will under-utilize the assigned work RAM.");
|
||||
uclassdrvwarn("Mailbox may overflow, use a larger HAL_USBHUVC_MAX_MAILBOX_SZ. UVC will under-utilize the assigned work RAM.");
|
||||
}
|
||||
chMBResumeX(&uvcdp->mb);
|
||||
|
||||
uvcdp->mp_data_buffer = chHeapAlloc(NULL, workramsz);
|
||||
if (uvcdp->mp_data_buffer == NULL) {
|
||||
uerr("Couldn't reserve RAM");
|
||||
uclassdrverr("Couldn't reserve RAM");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -497,7 +478,7 @@ uint32_t usbhuvcEstimateRequiredEPSize(USBHUVCDriver *uvcdp, const uint8_t *form
|
|||
mul = div = 1;
|
||||
} break;
|
||||
default:
|
||||
uwarn("Unsupported format");
|
||||
uclassdrvwarn("Unsupported format");
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
|
@ -528,7 +509,7 @@ static usbh_baseclassdriver_t *_uvc_load(usbh_device_t *dev, const uint8_t *desc
|
|||
}
|
||||
}
|
||||
|
||||
uwarn("Can't alloc UVC driver");
|
||||
udevwarn("Can't alloc UVC driver");
|
||||
|
||||
/* can't alloc */
|
||||
return NULL;
|
||||
|
@ -553,12 +534,12 @@ alloc_ok:
|
|||
|
||||
const usbh_interface_descriptor_t *const ifdesc = if_get(&iif);
|
||||
if (ifdesc->bInterfaceClass != UVC_CC_VIDEO) {
|
||||
uwarnf("Skipping Interface %d (class != UVC_CC_VIDEO)",
|
||||
udevwarnf("Skipping Interface %d (class != UVC_CC_VIDEO)",
|
||||
ifdesc->bInterfaceNumber);
|
||||
continue;
|
||||
}
|
||||
|
||||
uinfof("Interface %d, Alt=%d, Class=UVC_CC_VIDEO, Subclass=%02x",
|
||||
udevinfof("Interface %d, Alt=%d, Class=UVC_CC_VIDEO, Subclass=%02x",
|
||||
ifdesc->bInterfaceNumber,
|
||||
ifdesc->bAlternateSetting,
|
||||
ifdesc->bInterfaceSubClass);
|
||||
|
@ -570,24 +551,24 @@ alloc_ok:
|
|||
}
|
||||
for (cs_iter_init(&ics, (generic_iterator_t *)&iif); ics.valid; cs_iter_next(&ics)) {
|
||||
if (ics.curr[1] != UVC_CS_INTERFACE) {
|
||||
uwarnf("Unknown descriptor=%02X", ics.curr[1]);
|
||||
udevwarnf("Unknown descriptor=%02X", ics.curr[1]);
|
||||
continue;
|
||||
}
|
||||
switch (ics.curr[2]) {
|
||||
case UVC_VC_HEADER:
|
||||
uinfo(" VC_HEADER"); break;
|
||||
udevinfo(" VC_HEADER"); break;
|
||||
case UVC_VC_INPUT_TERMINAL:
|
||||
uinfof(" VC_INPUT_TERMINAL, ID=%d", ics.curr[3]); break;
|
||||
udevinfof(" VC_INPUT_TERMINAL, ID=%d", ics.curr[3]); break;
|
||||
case UVC_VC_OUTPUT_TERMINAL:
|
||||
uinfof(" VC_OUTPUT_TERMINAL, ID=%d", ics.curr[3]); break;
|
||||
udevinfof(" VC_OUTPUT_TERMINAL, ID=%d", ics.curr[3]); break;
|
||||
case UVC_VC_SELECTOR_UNIT:
|
||||
uinfof(" VC_SELECTOR_UNIT, ID=%d", ics.curr[3]); break;
|
||||
udevinfof(" VC_SELECTOR_UNIT, ID=%d", ics.curr[3]); break;
|
||||
case UVC_VC_PROCESSING_UNIT:
|
||||
uinfof(" VC_PROCESSING_UNIT, ID=%d", ics.curr[3]); break;
|
||||
udevinfof(" VC_PROCESSING_UNIT, ID=%d", ics.curr[3]); break;
|
||||
case UVC_VC_EXTENSION_UNIT:
|
||||
uinfof(" VC_EXTENSION_UNIT, ID=%d", ics.curr[3]); break;
|
||||
udevinfof(" VC_EXTENSION_UNIT, ID=%d", ics.curr[3]); break;
|
||||
default:
|
||||
uwarnf("Unknown video bDescriptorSubtype=%02x", ics.curr[2]);
|
||||
udevwarnf("Unknown video bDescriptorSubtype=%02x", ics.curr[2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -598,47 +579,47 @@ alloc_ok:
|
|||
}
|
||||
for (cs_iter_init(&ics, (generic_iterator_t *)&iif); ics.valid; cs_iter_next(&ics)) {
|
||||
if (ics.curr[1] != UVC_CS_INTERFACE) {
|
||||
uwarnf("Unknown descriptor=%02X", ics.curr[1]);
|
||||
udevwarnf("Unknown descriptor=%02X", ics.curr[1]);
|
||||
continue;
|
||||
}
|
||||
switch (ics.curr[2]) {
|
||||
case UVC_VS_INPUT_HEADER:
|
||||
uinfo(" VS_INPUT_HEADER"); break;
|
||||
udevinfo(" VS_INPUT_HEADER"); break;
|
||||
case UVC_VS_OUTPUT_HEADER:
|
||||
uinfo(" VS_OUTPUT_HEADER"); break;
|
||||
udevinfo(" VS_OUTPUT_HEADER"); break;
|
||||
case UVC_VS_STILL_IMAGE_FRAME:
|
||||
uinfo(" VS_STILL_IMAGE_FRAME"); break;
|
||||
udevinfo(" VS_STILL_IMAGE_FRAME"); break;
|
||||
|
||||
case UVC_VS_FORMAT_UNCOMPRESSED:
|
||||
uinfof(" VS_FORMAT_UNCOMPRESSED, bFormatIndex=%d", ics.curr[3]); break;
|
||||
udevinfof(" VS_FORMAT_UNCOMPRESSED, bFormatIndex=%d", ics.curr[3]); break;
|
||||
case UVC_VS_FORMAT_MPEG2TS:
|
||||
uinfof(" VS_FORMAT_MPEG2TS, bFormatIndex=%d", ics.curr[3]); break;
|
||||
udevinfof(" VS_FORMAT_MPEG2TS, bFormatIndex=%d", ics.curr[3]); break;
|
||||
case UVC_VS_FORMAT_DV:
|
||||
uinfof(" VS_FORMAT_DV, bFormatIndex=%d", ics.curr[3]); break;
|
||||
udevinfof(" VS_FORMAT_DV, bFormatIndex=%d", ics.curr[3]); break;
|
||||
case UVC_VS_FORMAT_MJPEG:
|
||||
uinfof(" VS_FORMAT_MJPEG, bFormatIndex=%d", ics.curr[3]); break;
|
||||
udevinfof(" VS_FORMAT_MJPEG, bFormatIndex=%d", ics.curr[3]); break;
|
||||
case UVC_VS_FORMAT_FRAME_BASED:
|
||||
uinfof(" VS_FORMAT_FRAME_BASED, bFormatIndex=%d", ics.curr[3]); break;
|
||||
udevinfof(" VS_FORMAT_FRAME_BASED, bFormatIndex=%d", ics.curr[3]); break;
|
||||
case UVC_VS_FORMAT_STREAM_BASED:
|
||||
uinfof(" VS_FORMAT_STREAM_BASED, bFormatIndex=%d", ics.curr[3]); break;
|
||||
udevinfof(" VS_FORMAT_STREAM_BASED, bFormatIndex=%d", ics.curr[3]); break;
|
||||
|
||||
case UVC_VS_FRAME_UNCOMPRESSED:
|
||||
uinfof(" VS_FRAME_UNCOMPRESSED, bFrameIndex=%d", ics.curr[3]); break;
|
||||
udevinfof(" VS_FRAME_UNCOMPRESSED, bFrameIndex=%d", ics.curr[3]); break;
|
||||
case UVC_VS_FRAME_MJPEG:
|
||||
uinfof(" VS_FRAME_MJPEG, bFrameIndex=%d", ics.curr[3]); break;
|
||||
udevinfof(" VS_FRAME_MJPEG, bFrameIndex=%d", ics.curr[3]); break;
|
||||
case UVC_VS_FRAME_FRAME_BASED:
|
||||
uinfof(" VS_FRAME_FRAME_BASED, bFrameIndex=%d", ics.curr[3]); break;
|
||||
udevinfof(" VS_FRAME_FRAME_BASED, bFrameIndex=%d", ics.curr[3]); break;
|
||||
|
||||
case UVC_VS_COLOR_FORMAT:
|
||||
uinfo(" VS_COLOR_FORMAT"); break;
|
||||
udevinfo(" VS_COLOR_FORMAT"); break;
|
||||
default:
|
||||
uwarnf("Unknown video bDescriptorSubtype=%02x", ics.curr[2]);
|
||||
udevwarnf("Unknown video bDescriptorSubtype=%02x", ics.curr[2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
uwarnf("Unknown video bInterfaceSubClass=%02x", ifdesc->bInterfaceSubClass);
|
||||
udevwarnf("Unknown video bInterfaceSubClass=%02x", ifdesc->bInterfaceSubClass);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -649,7 +630,7 @@ alloc_ok:
|
|||
&& ((epdesc->bmAttributes & 0x03) == USBH_EPTYPE_INT)
|
||||
&& ((epdesc->bEndpointAddress & 0x80) == USBH_EPDIR_IN)) {
|
||||
/* found VC interrupt endpoint */
|
||||
uinfof(" VC Interrupt endpoint; %02x, bInterval=%d",
|
||||
udevinfof(" VC Interrupt endpoint; %02x, bInterval=%d",
|
||||
epdesc->bEndpointAddress, epdesc->bInterval);
|
||||
usbhEPObjectInit(&uvcdp->ep_int, dev, epdesc);
|
||||
usbhEPSetName(&uvcdp->ep_int, "UVC[INT ]");
|
||||
|
@ -657,16 +638,16 @@ alloc_ok:
|
|||
&& ((epdesc->bmAttributes & 0x03) == USBH_EPTYPE_ISO)
|
||||
&& ((epdesc->bEndpointAddress & 0x80) == USBH_EPDIR_IN)) {
|
||||
/* found VS isochronous endpoint */
|
||||
uinfof(" VS Isochronous endpoint; %02x, bInterval=%d, bmAttributes=%02x",
|
||||
udevinfof(" VS Isochronous endpoint; %02x, bInterval=%d, bmAttributes=%02x",
|
||||
epdesc->bEndpointAddress, epdesc->bInterval, epdesc->bmAttributes);
|
||||
} else {
|
||||
/* unknown EP */
|
||||
uwarnf(" <unknown endpoint>, bEndpointAddress=%02x, bmAttributes=%02x",
|
||||
udevwarnf(" <unknown endpoint>, bEndpointAddress=%02x, bmAttributes=%02x",
|
||||
epdesc->bEndpointAddress, epdesc->bmAttributes);
|
||||
}
|
||||
|
||||
for (cs_iter_init(&ics, &iep); ics.valid; cs_iter_next(&ics)) {
|
||||
uinfof(" CS_ENDPOINT bLength=%d, bDescriptorType=%02X",
|
||||
udevinfof(" CS_ENDPOINT bLength=%d, bDescriptorType=%02X",
|
||||
ics.curr[0], ics.curr[1]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef FAULT_HANDLERS_H_
|
||||
#define FAULT_HANDLERS_H_
|
||||
|
||||
#include <ch.h>
|
||||
#include "port_fault_handlers.h"
|
||||
|
||||
/*
|
||||
* Notes:
|
||||
*
|
||||
* 1) #define FAULT_NO_PRINT to remove chprintf, etc
|
||||
* 2) #define FAULT_INFO_HOOK(fault_info) to receive a struct fault_info when
|
||||
* a fault is produced.
|
||||
*/
|
||||
|
||||
struct fault_info {
|
||||
struct decoded_fault_registers decoded_fault_registers;
|
||||
#ifndef FAULT_NO_PRINT
|
||||
char decoded_info_string[300];
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* FAULT_HANDLERS_H_ */
|
|
@ -1,6 +1,6 @@
|
|||
eclipse.preferences.version=1
|
||||
environment/project/0.1003150841/PATH/delimiter=;
|
||||
environment/project/0.1003150841/PATH/operation=replace
|
||||
environment/project/0.1003150841/PATH/value=${PATH};D\:\\toolchains\\gcc-arm-none-eabi-8-2018-q4-major-win32\\bin;${PATH};D\:\\toolchains\\gcc-arm-none-eabi-4_9-2014q4-20141203-win32\\bin;D\:\\toolchains\\msys64\\usr\\bin
|
||||
environment/project/0.1003150841/PATH/value=${PATH};D\:\\toolchains\\gcc-arm-none-eabi-8-2019-q3-update-win32\\bin;D\:\\toolchains\\msys64\\usr\\bin
|
||||
environment/project/0.1003150841/append=true
|
||||
environment/project/0.1003150841/appendContributed=true
|
||||
|
|
|
@ -712,3 +712,4 @@
|
|||
#endif /* CHCONF_H */
|
||||
|
||||
/** @} */
|
||||
|
||||
|
|
|
@ -177,7 +177,7 @@
|
|||
#define HAL_USBH_PORT_DEBOUNCE_TIME 200
|
||||
#define HAL_USBH_PORT_RESET_TIMEOUT 500
|
||||
#define HAL_USBH_DEVICE_ADDRESS_STABILIZATION 20
|
||||
#define HAL_USBH_CONTROL_REQUEST_DEFAULT_TIMEOUT OSAL_MS2I(1000)
|
||||
#define HAL_USBH_CONTROL_REQUEST_DEFAULT_TIMEOUT OSAL_MS2I(1000)
|
||||
|
||||
/* MSD */
|
||||
#define HAL_USBH_USE_MSD TRUE
|
||||
|
@ -202,7 +202,7 @@
|
|||
|
||||
#define HAL_USBHAOA_MAX_INSTANCES 1
|
||||
/* Uncomment this if you need a filter for AOA devices:
|
||||
* #define HAL_USBHAOA_FILTER_CALLBACK _try_aoa
|
||||
* #define HAL_USBHAOA_FILTER_CALLBACK _try_aoa
|
||||
*/
|
||||
#define HAL_USBHAOA_DEFAULT_MANUFACTURER "Diego MFG & Co."
|
||||
#define HAL_USBHAOA_DEFAULT_MODEL "Diego's device"
|
||||
|
@ -235,9 +235,10 @@
|
|||
|
||||
/* debug */
|
||||
#define USBH_DEBUG_ENABLE TRUE
|
||||
#define USBH_DEBUG_USBHD USBHD1
|
||||
#define USBH_DEBUG_SD SD2
|
||||
#define USBH_DEBUG_MULTI_HOST FALSE
|
||||
#define USBH_DEBUG_SINGLE_HOST_SELECTION USBHD1
|
||||
#define USBH_DEBUG_BUFFER 25000
|
||||
#define USBH_DEBUG_OUTPUT_CALLBACK usbh_debug_output
|
||||
|
||||
#define USBH_DEBUG_ENABLE_TRACE FALSE
|
||||
#define USBH_DEBUG_ENABLE_INFO TRUE
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "hal.h"
|
||||
#include "ff.h"
|
||||
#include <string.h>
|
||||
#include "usbh/debug.h" /* for usbDbgPuts/usbDbgPrintf */
|
||||
#include "usbh/debug.h" /* for _usbh_dbg/_usbh_dbgf */
|
||||
|
||||
|
||||
#define UVC_TO_MSD_PHOTOS_CAPTURE FALSE
|
||||
|
@ -85,6 +85,8 @@ static const ShellConfig shell_cfg1 = {
|
|||
static void ThreadTestFTDI(void *p) {
|
||||
(void)p;
|
||||
USBHFTDIPortDriver *const ftdipp = &FTDIPD[0];
|
||||
USBHDriver *host = NULL;
|
||||
(void)host;
|
||||
|
||||
chRegSetThreadName("FTDI");
|
||||
|
||||
|
@ -95,7 +97,8 @@ start:
|
|||
chThdSleepMilliseconds(100);
|
||||
}
|
||||
|
||||
usbDbgPuts("FTDI: Connected");
|
||||
host = usbhftdipGetHost(ftdipp);
|
||||
_usbh_dbg(host, "FTDI: Connected");
|
||||
|
||||
USBHFTDIPortConfig config = {
|
||||
115200,
|
||||
|
@ -112,7 +115,7 @@ start:
|
|||
for(;;) {
|
||||
msg_t m = streamGet(ftdipp);
|
||||
if (m < MSG_OK) {
|
||||
usbDbgPuts("FTDI: Disconnected");
|
||||
_usbh_dbg(host, "FTDI: Disconnected");
|
||||
goto start;
|
||||
}
|
||||
streamPut(ftdipp, (uint8_t)m);
|
||||
|
@ -146,10 +149,10 @@ start:
|
|||
for(;;) {
|
||||
msg_t m = streamGet(ftdipp);
|
||||
if (m < MSG_OK) {
|
||||
usbDbgPuts("FTDI: Disconnected");
|
||||
_usbh_dbg(host, "FTDI: Disconnected");
|
||||
goto start;
|
||||
}
|
||||
sdPut(&USBH_DEBUG_SD, (uint8_t)m);
|
||||
sdPut(&SD2, (uint8_t)m);
|
||||
if (m == 'q')
|
||||
break;
|
||||
}
|
||||
|
@ -169,19 +172,19 @@ start:
|
|||
st = chVTGetSystemTimeX();
|
||||
while (times--) {
|
||||
if (streamWrite(ftdipp, buf, 1024) < 1024) {
|
||||
usbDbgPuts("FTDI: Disconnected");
|
||||
_usbh_dbg(host, "FTDI: Disconnected");
|
||||
goto start;
|
||||
}
|
||||
bytes -= 1024;
|
||||
}
|
||||
if (bytes) {
|
||||
if (streamWrite(ftdipp, buf, bytes) < bytes) {
|
||||
usbDbgPuts("FTDI: Disconnected");
|
||||
_usbh_dbg(host, "FTDI: Disconnected");
|
||||
goto start;
|
||||
}
|
||||
}
|
||||
et = chVTGetSystemTimeX();
|
||||
usbDbgPrintf("\tRate=%uB/s", (config.speed * 100) / (et - st));
|
||||
_usbh_dbgf(host, "\tRate=%uB/s", (config.speed * 100) / (et - st));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,7 +192,7 @@ start:
|
|||
if (0) {
|
||||
for (;;) {
|
||||
if (streamPut(ftdipp, 'A') != MSG_OK) {
|
||||
usbDbgPuts("FTDI: Disconnected");
|
||||
_usbh_dbg(host, "FTDI: Disconnected");
|
||||
goto start;
|
||||
}
|
||||
chThdSleepMilliseconds(100);
|
||||
|
@ -198,7 +201,7 @@ start:
|
|||
|
||||
usbhftdipStop(ftdipp);
|
||||
|
||||
usbDbgPuts("FTDI: Tests done, restarting in 3s");
|
||||
_usbh_dbg(host, "FTDI: Tests done, restarting in 3s");
|
||||
chThdSleepMilliseconds(3000);
|
||||
|
||||
goto start;
|
||||
|
@ -218,6 +221,8 @@ static void ThreadTestAOA(void *p) {
|
|||
(void)p;
|
||||
USBHAOADriver *const aoap = &USBHAOAD[0];
|
||||
USBHAOAChannel *const aoacp = &aoap->channel;
|
||||
USBHDriver *host = NULL;
|
||||
(void)host;
|
||||
|
||||
chRegSetThreadName("AOA");
|
||||
|
||||
|
@ -226,11 +231,12 @@ start:
|
|||
chThdSleepMilliseconds(100);
|
||||
}
|
||||
|
||||
usbDbgPuts("AOA: Connected");
|
||||
host = usbhaoaGetHost(aoap);
|
||||
_usbh_dbg(host, "AOA: Connected");
|
||||
|
||||
if (usbhaoaGetChannelState(aoap) != USBHAOA_CHANNEL_STATE_READY) {
|
||||
usbhaoaChannelStart(aoap);
|
||||
usbDbgPuts("AOA: Channel started");
|
||||
_usbh_dbg(host, "AOA: Channel started");
|
||||
}
|
||||
|
||||
//loopback
|
||||
|
@ -238,7 +244,7 @@ start:
|
|||
for(;;) {
|
||||
msg_t m = streamGet(aoacp);
|
||||
if (m < MSG_OK) {
|
||||
usbDbgPuts("AOA: Disconnected");
|
||||
_usbh_dbg(host, "AOA: Disconnected");
|
||||
goto start;
|
||||
}
|
||||
streamPut(aoacp, (uint8_t)m);
|
||||
|
@ -258,19 +264,19 @@ start:
|
|||
st = chVTGetSystemTimeX();
|
||||
while (times--) {
|
||||
if (streamWrite(aoacp, buf, 1024) < 1024) {
|
||||
usbDbgPuts("AOA: Disconnected");
|
||||
_usbh_dbg(host, "AOA: Disconnected");
|
||||
goto start;
|
||||
}
|
||||
bytes -= 1024;
|
||||
}
|
||||
if (bytes) {
|
||||
if (streamWrite(aoacp, buf, bytes) < bytes) {
|
||||
usbDbgPuts("AOA: Disconnected");
|
||||
_usbh_dbg(host, "AOA: Disconnected");
|
||||
goto start;
|
||||
}
|
||||
}
|
||||
et = chVTGetSystemTimeX();
|
||||
usbDbgPrintf("\tRate=%uB/s", AOA_WRITE_SPEED_TEST_BYTES / (et - st) * 100);
|
||||
_usbh_dbgf(host, "\tRate=%uB/s", AOA_WRITE_SPEED_TEST_BYTES / (et - st) * 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,7 +284,7 @@ start:
|
|||
if (0) {
|
||||
for (;;) {
|
||||
if (streamPut(aoacp, 'A') != MSG_OK) {
|
||||
usbDbgPuts("AOA: Disconnected");
|
||||
_usbh_dbg(host, "AOA: Disconnected");
|
||||
goto start;
|
||||
}
|
||||
chThdSleepMilliseconds(100);
|
||||
|
@ -287,7 +293,7 @@ start:
|
|||
|
||||
usbhaoaChannelStop(aoap);
|
||||
|
||||
usbDbgPuts("AOA: Tests done, restarting in 3s");
|
||||
_usbh_dbg(host, "AOA: Tests done, restarting in 3s");
|
||||
chThdSleepMilliseconds(3000);
|
||||
|
||||
goto start;
|
||||
|
@ -305,7 +311,7 @@ static FATFS MSDLUN0FS;
|
|||
static uint8_t fbuff[10240];
|
||||
static FIL file;
|
||||
|
||||
static FRESULT scan_files(BaseSequentialStream *chp, char *path) {
|
||||
static FRESULT scan_files(USBHDriver *host, BaseSequentialStream *chp, char *path) {
|
||||
FRESULT res;
|
||||
DIR dir;
|
||||
UINT i;
|
||||
|
@ -321,12 +327,12 @@ static FRESULT scan_files(BaseSequentialStream *chp, char *path) {
|
|||
i = strlen(path);
|
||||
path[i++] = '/';
|
||||
strcpy(&path[i], fno.fname);
|
||||
res = scan_files(chp, path);
|
||||
res = scan_files(host, chp, path);
|
||||
if (res != FR_OK)
|
||||
break;
|
||||
path[--i] = 0;
|
||||
} else {
|
||||
usbDbgPrintf("FS: %s/%s", path, fno.fname);
|
||||
_usbh_dbgf(host, "FS: %s/%s", path, fno.fname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -341,11 +347,12 @@ static void ThreadTestMSD(void *p) {
|
|||
FATFS *fsp;
|
||||
DWORD clusters;
|
||||
FRESULT res;
|
||||
USBHDriver *host = NULL;
|
||||
|
||||
chRegSetThreadName("MSD");
|
||||
|
||||
#if !UVC_TO_MSD_PHOTOS_CAPTURE
|
||||
BaseSequentialStream * const chp = (BaseSequentialStream *)&USBH_DEBUG_SD;
|
||||
BaseSequentialStream * const chp = (BaseSequentialStream *)&SD2;
|
||||
systime_t st, et;
|
||||
uint32_t j;
|
||||
#endif
|
||||
|
@ -355,14 +362,15 @@ start:
|
|||
chThdSleepMilliseconds(100);
|
||||
|
||||
if (blkGetDriverState(&MSBLKD[0]) == BLK_ACTIVE) {
|
||||
usbDbgPuts("BLK: Active, connect....");
|
||||
host = usbhmsdLUNGetHost(&MSBLKD[0]);
|
||||
_usbh_dbg(host, "BLK: Active, connect....");
|
||||
usbhmsdLUNConnect(&MSBLKD[0]);
|
||||
}
|
||||
if (blkGetDriverState(&MSBLKD[0]) != BLK_READY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
usbDbgPuts("BLK: Ready.");
|
||||
_usbh_dbg(host, "BLK: Ready.");
|
||||
|
||||
#if !UVC_TO_MSD_PHOTOS_CAPTURE
|
||||
//raw read test
|
||||
|
@ -372,7 +380,7 @@ start:
|
|||
#define NITERATIONS ((RAW_READ_SZ_MB * 1024UL * 1024UL) / sizeof(fbuff))
|
||||
uint32_t start = 0;
|
||||
chThdSetPriority(HIGHPRIO);
|
||||
usbDbgPrintf("BLK: Raw read test (%dMB, %dB blocks)", RAW_READ_SZ_MB, sizeof(fbuff));
|
||||
_usbh_dbgf(host, "BLK: Raw read test (%dMB, %dB blocks)", RAW_READ_SZ_MB, sizeof(fbuff));
|
||||
st = chVTGetSystemTime();
|
||||
for (j = 0; j < NITERATIONS; j++) {
|
||||
if (blkRead(&MSBLKD[0], start, fbuff, NBLOCKS) != HAL_SUCCESS)
|
||||
|
@ -380,29 +388,29 @@ start:
|
|||
start += NBLOCKS;
|
||||
}
|
||||
et = chVTGetSystemTime();
|
||||
usbDbgPrintf("BLK: Raw read in %d ms, %dkB/s",
|
||||
_usbh_dbgf(host, "BLK: Raw read in %d ms, %dkB/s",
|
||||
et - st,
|
||||
(RAW_READ_SZ_MB * 1024UL * 1000) / (et - st));
|
||||
chThdSetPriority(NORMALPRIO);
|
||||
}
|
||||
#endif
|
||||
|
||||
usbDbgPuts("FS: Block driver ready, try mount...");
|
||||
_usbh_dbg(host, "FS: Block driver ready, try mount...");
|
||||
|
||||
res = f_mount(&MSDLUN0FS, FATFSDEV_MSD_DRIVE, 1);
|
||||
if (res != FR_OK) {
|
||||
usbDbgPuts("FS: Can't mount. Check file system.");
|
||||
_usbh_dbg(host, "FS: Can't mount. Check file system.");
|
||||
continue;
|
||||
}
|
||||
usbDbgPuts("FS: Mounted.");
|
||||
_usbh_dbg(host, "FS: Mounted.");
|
||||
|
||||
res = f_getfree(FATFSDEV_MSD_DRIVE, &clusters, &fsp);
|
||||
if (res != FR_OK) {
|
||||
usbDbgPuts("FS: f_getfree() failed");
|
||||
_usbh_dbg(host, "FS: f_getfree() failed");
|
||||
continue;
|
||||
}
|
||||
|
||||
usbDbgPrintf("FS: %lu free clusters, %lu sectors per cluster, %lu bytes free",
|
||||
_usbh_dbgf(host, "FS: %lu free clusters, %lu sectors per cluster, %lu bytes free",
|
||||
clusters, (uint32_t)MSDLUN0FS.csize,
|
||||
clusters * (uint32_t)MSDLUN0FS.csize * MSBLKD[0].info.blk_size);
|
||||
|
||||
|
@ -419,7 +427,7 @@ start:
|
|||
|
||||
//write test
|
||||
if (1) {
|
||||
usbDbgPuts("FS: Write test (create file /test.dat, 1MB)");
|
||||
_usbh_dbg(host, "FS: Write test (create file /test.dat, 1MB)");
|
||||
f_open(&file, FATFSDEV_MSD_DRIVE "/test.dat", FA_CREATE_ALWAYS | FA_WRITE);
|
||||
src = start;
|
||||
st = chVTGetSystemTime();
|
||||
|
@ -431,7 +439,7 @@ start:
|
|||
src = start;
|
||||
}
|
||||
et = chVTGetSystemTime();
|
||||
usbDbgPrintf("FS: Written 1MB in %d ms, %dkB/s",
|
||||
_usbh_dbgf(host, "FS: Written 1MB in %d ms, %dkB/s",
|
||||
et - st,
|
||||
(1024UL*1000) / (et - st));
|
||||
f_close(&file);
|
||||
|
@ -439,7 +447,7 @@ start:
|
|||
|
||||
//read test
|
||||
if (1) {
|
||||
usbDbgPuts("FS: Read test (read file /test.dat, 1MB, compare)");
|
||||
_usbh_dbg(host, "FS: Read test (read file /test.dat, 1MB, compare)");
|
||||
f_open(&file, FATFSDEV_MSD_DRIVE "/test.dat", FA_READ);
|
||||
src = start;
|
||||
st = chVTGetSystemTime();
|
||||
|
@ -447,7 +455,7 @@ start:
|
|||
if (f_read(&file, fbuff, 512, &bw) != FR_OK)
|
||||
goto start;
|
||||
if (memcmp(src, fbuff, bw)) {
|
||||
usbDbgPrintf("Compare error @%08x", (uint32_t)src);
|
||||
_usbh_dbgf(host, "Compare error @%08x", (uint32_t)src);
|
||||
goto start;
|
||||
}
|
||||
src += bw;
|
||||
|
@ -455,7 +463,7 @@ start:
|
|||
src = start;
|
||||
}
|
||||
et = chVTGetSystemTime();
|
||||
usbDbgPrintf("FS: Read 1MB in %d ms, %dkB/s",
|
||||
_usbh_dbgf(host, "FS: Read 1MB in %d ms, %dkB/s",
|
||||
et - st,
|
||||
(1024UL*1000) / (et - st));
|
||||
f_close(&file);
|
||||
|
@ -463,14 +471,14 @@ start:
|
|||
|
||||
//scan files test
|
||||
if (1) {
|
||||
usbDbgPuts("FS: Scan files test");
|
||||
_usbh_dbg(host, "FS: Scan files test");
|
||||
strcpy((char *)fbuff, FATFSDEV_MSD_DRIVE);
|
||||
scan_files(chp, (char *)fbuff);
|
||||
scan_files(host, chp, (char *)fbuff);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
usbDbgPuts("FS: Tests done, restarting in 3s");
|
||||
_usbh_dbg(host, "FS: Tests done, restarting in 3s");
|
||||
chThdSleepMilliseconds(3000);
|
||||
|
||||
goto start;
|
||||
|
@ -488,12 +496,12 @@ static void _hid_report_callback(USBHHIDDriver *hidp, uint16_t len) {
|
|||
uint8_t *report = (uint8_t *)hidp->config->report_buffer;
|
||||
|
||||
if (hidp->type == USBHHID_DEVTYPE_BOOT_MOUSE) {
|
||||
usbDbgPrintf("Mouse report: buttons=%02x, Dx=%d, Dy=%d",
|
||||
_usbh_dbgf(hidp->dev->host, "Mouse report: buttons=%02x, Dx=%d, Dy=%d",
|
||||
report[0],
|
||||
(int8_t)report[1],
|
||||
(int8_t)report[2]);
|
||||
} else if (hidp->type == USBHHID_DEVTYPE_BOOT_KEYBOARD) {
|
||||
usbDbgPrintf("Keyboard report: modifier=%02x, keys=%02x %02x %02x %02x %02x %02x",
|
||||
_usbh_dbgf(hidp->dev->host, "Keyboard report: modifier=%02x, keys=%02x %02x %02x %02x %02x %02x",
|
||||
report[0],
|
||||
report[2],
|
||||
report[3],
|
||||
|
@ -502,7 +510,7 @@ static void _hid_report_callback(USBHHIDDriver *hidp, uint16_t len) {
|
|||
report[6],
|
||||
report[7]);
|
||||
} else {
|
||||
usbDbgPrintf("Generic report, %d bytes", len);
|
||||
_usbh_dbgf(hidp->dev->host, "Generic report, %d bytes", len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -525,21 +533,22 @@ static void ThreadTestHID(void *p) {
|
|||
|
||||
for (;;) {
|
||||
for (i = 0; i < HAL_USBHHID_MAX_INSTANCES; i++) {
|
||||
if (usbhhidGetState(&USBHHIDD[i]) == USBHHID_STATE_ACTIVE) {
|
||||
usbDbgPrintf("HID: Connected, HID%d", i);
|
||||
usbhhidStart(&USBHHIDD[i], &hidcfg[i]);
|
||||
if (usbhhidGetType(&USBHHIDD[i]) != USBHHID_DEVTYPE_GENERIC) {
|
||||
usbhhidSetIdle(&USBHHIDD[i], 0, 0);
|
||||
USBHHIDDriver *const hidp = &USBHHIDD[i];
|
||||
if (usbhhidGetState(hidp) == USBHHID_STATE_ACTIVE) {
|
||||
_usbh_dbgf(hidp->dev->host, "HID: Connected, HID%d", i);
|
||||
usbhhidStart(hidp, &hidcfg[i]);
|
||||
if (usbhhidGetType(hidp) != USBHHID_DEVTYPE_GENERIC) {
|
||||
usbhhidSetIdle(hidp, 0, 0);
|
||||
}
|
||||
kbd_led_states[i] = 1;
|
||||
} else if (usbhhidGetState(&USBHHIDD[i]) == USBHHID_STATE_READY) {
|
||||
if (usbhhidGetType(&USBHHIDD[i]) == USBHHID_DEVTYPE_BOOT_KEYBOARD) {
|
||||
} else if (usbhhidGetState(hidp) == USBHHID_STATE_READY) {
|
||||
if (usbhhidGetType(hidp) == USBHHID_DEVTYPE_BOOT_KEYBOARD) {
|
||||
USBH_DEFINE_BUFFER(uint8_t val);
|
||||
val = kbd_led_states[i] << 1;
|
||||
if (val == 0x08) {
|
||||
val = 1;
|
||||
}
|
||||
usbhhidSetReport(&USBHHIDD[i], 0, USBHHID_REPORTTYPE_OUTPUT, &val, 1);
|
||||
usbhhidSetReport(hidp, 0, USBHHID_REPORTTYPE_OUTPUT, &val, 1);
|
||||
kbd_led_states[i] = val;
|
||||
}
|
||||
}
|
||||
|
@ -637,12 +646,12 @@ static void ThreadTestUVC(void *p) {
|
|||
if (usbhuvcGetState(&USBHUVCD[0]) != USBHUVC_STATE_ACTIVE)
|
||||
continue;
|
||||
|
||||
usbDbgPuts("UVC: Webcam connected");
|
||||
_usbh_dbg(uvcdp->dev->host, "UVC: Webcam connected");
|
||||
|
||||
/* ************************************ */
|
||||
/* Find best configuration */
|
||||
/* ************************************ */
|
||||
usbDbgPuts("UVC: Find best configuration");
|
||||
_usbh_dbg(uvcdp->dev->host, "UVC: Find best configuration");
|
||||
|
||||
generic_iterator_t ics;
|
||||
const usbh_uvc_format_mjpeg_t *format;
|
||||
|
@ -658,7 +667,7 @@ static void ThreadTestUVC(void *p) {
|
|||
goto failed;
|
||||
|
||||
format = (const usbh_uvc_format_mjpeg_t *)ics.curr;
|
||||
usbDbgPrintf("\tSelect bFormatIndex=%d", format->bFormatIndex);
|
||||
_usbh_dbgf(uvcdp->dev->host, "\tSelect bFormatIndex=%d", format->bFormatIndex);
|
||||
|
||||
//find the most suitable frame (largest one within the bandwidth requirements)
|
||||
if (usbhuvcFindVSDescriptor(uvcdp, &ics, UVC_VS_FRAME_MJPEG, TRUE) != HAL_SUCCESS)
|
||||
|
@ -668,18 +677,18 @@ static void ThreadTestUVC(void *p) {
|
|||
const usbh_uvc_frame_mjpeg_t *const frame = (usbh_uvc_frame_mjpeg_t *)ics.curr;
|
||||
uint32_t frame_sz = frame->wWidth * frame->wHeight;
|
||||
|
||||
usbDbgPrintf("\t\tbFrameIndex=%d", frame->bFrameIndex);
|
||||
usbDbgPrintf("\t\t\twWidth=%d, wHeight=%d", frame->wWidth, frame->wHeight);
|
||||
usbDbgPrintf("\t\t\tdwMinBitRate=%u, dwMaxBitRate=%u", frame->dwMinBitRate, frame->dwMaxBitRate);
|
||||
usbDbgPrintf("\t\t\tdwMaxVideoFrameBufferSize=%u", frame->dwMaxVideoFrameBufferSize);
|
||||
usbDbgPrintf("\t\t\tdwDefaultFrameInterval=%u", frame->dwDefaultFrameInterval);
|
||||
_usbh_dbgf(uvcdp->dev->host, "\t\tbFrameIndex=%d", frame->bFrameIndex);
|
||||
_usbh_dbgf(uvcdp->dev->host, "\t\t\twWidth=%d, wHeight=%d", frame->wWidth, frame->wHeight);
|
||||
_usbh_dbgf(uvcdp->dev->host, "\t\t\tdwMinBitRate=%u, dwMaxBitRate=%u", frame->dwMinBitRate, frame->dwMaxBitRate);
|
||||
_usbh_dbgf(uvcdp->dev->host, "\t\t\tdwMaxVideoFrameBufferSize=%u", frame->dwMaxVideoFrameBufferSize);
|
||||
_usbh_dbgf(uvcdp->dev->host, "\t\t\tdwDefaultFrameInterval=%u", frame->dwDefaultFrameInterval);
|
||||
|
||||
uint8_t j;
|
||||
for (j = 0; j < frame->bFrameIntervalType; j++) {
|
||||
uint32_t ep_sz =
|
||||
usbhuvcEstimateRequiredEPSize(uvcdp, (const uint8_t *)format, (const uint8_t *)frame, frame->dwFrameInterval[j]);
|
||||
|
||||
usbDbgPrintf("\t\t\tdwFrameInterval=%u, estimated EP size=%u", frame->dwFrameInterval[j], ep_sz);
|
||||
_usbh_dbgf(uvcdp->dev->host, "\t\t\tdwFrameInterval=%u, estimated EP size=%u", frame->dwFrameInterval[j], ep_sz);
|
||||
|
||||
if (ep_sz > 310)
|
||||
continue;
|
||||
|
@ -697,7 +706,7 @@ static void ThreadTestUVC(void *p) {
|
|||
if (ep_sz < min_ep_sz) {
|
||||
/* new best bitrate */
|
||||
min_ep_sz = ep_sz;
|
||||
usbDbgPuts("\t\t\tNew best candidate found");
|
||||
_usbh_dbg(uvcdp->dev->host, "\t\t\tNew best candidate found");
|
||||
best_frame_interval_index = j;
|
||||
best_frame = frame;
|
||||
}
|
||||
|
@ -706,14 +715,14 @@ static void ThreadTestUVC(void *p) {
|
|||
|
||||
failed:
|
||||
if (best_frame == NULL) {
|
||||
usbDbgPuts("\t\t\tCouldn't find suitable format/frame");
|
||||
_usbh_dbg(uvcdp->dev->host, "\t\t\tCouldn't find suitable format/frame");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* ************************************ */
|
||||
/* NEGOTIATION */
|
||||
/* ************************************ */
|
||||
usbDbgPuts("UVC: Start negotiation");
|
||||
_usbh_dbg(uvcdp->dev->host, "UVC: Start negotiation");
|
||||
|
||||
usbhuvcResetPC(uvcdp);
|
||||
usbh_uvc_ctrl_vs_probecommit_data_t *const pc = usbhuvcGetPC(uvcdp);
|
||||
|
@ -723,42 +732,42 @@ failed:
|
|||
pc->bFrameIndex = best_frame->bFrameIndex;
|
||||
pc->dwFrameInterval = best_frame->dwFrameInterval[best_frame_interval_index];
|
||||
|
||||
usbDbgPrintf("\tFirst probe, selecting bFormatIndex=%d, bFrameIndex=%d, dwFrameInterval=%u",
|
||||
_usbh_dbgf(uvcdp->dev->host, "\tFirst probe, selecting bFormatIndex=%d, bFrameIndex=%d, dwFrameInterval=%u",
|
||||
pc->bFormatIndex, pc->bFrameIndex, pc->dwFrameInterval);
|
||||
|
||||
usbDbgPuts("SET_CUR (PROBE):"); usbhuvcPrintProbeCommit(&uvcdp->pc);
|
||||
_usbh_dbg(uvcdp->dev->host, "SET_CUR (PROBE):"); usbhuvcPrintProbeCommit(uvcdp, &uvcdp->pc);
|
||||
if (usbhuvcProbe(uvcdp) != HAL_SUCCESS) {
|
||||
usbDbgPuts("\tFirst probe failed");
|
||||
_usbh_dbg(uvcdp->dev->host, "\tFirst probe failed");
|
||||
continue;
|
||||
}
|
||||
usbDbgPuts("GET_CUR (PROBE):"); usbhuvcPrintProbeCommit(&uvcdp->pc);
|
||||
usbDbgPuts("GET_MIN (PROBE):"); usbhuvcPrintProbeCommit(&uvcdp->pc_min);
|
||||
usbDbgPuts("GET_MAX (PROBE):"); usbhuvcPrintProbeCommit(&uvcdp->pc_max);
|
||||
_usbh_dbg(uvcdp->dev->host, "GET_CUR (PROBE):"); usbhuvcPrintProbeCommit(uvcdp, &uvcdp->pc);
|
||||
_usbh_dbg(uvcdp->dev->host, "GET_MIN (PROBE):"); usbhuvcPrintProbeCommit(uvcdp, &uvcdp->pc_min);
|
||||
_usbh_dbg(uvcdp->dev->host, "GET_MAX (PROBE):"); usbhuvcPrintProbeCommit(uvcdp, &uvcdp->pc_max);
|
||||
|
||||
pc->bmHint = 0x0001;
|
||||
pc->wCompQuality = uvcdp->pc_min.wCompQuality;
|
||||
|
||||
usbDbgPuts("SET_CUR (PROBE):"); usbhuvcPrintProbeCommit(&uvcdp->pc);
|
||||
usbDbgPrintf("\tSecond probe, selecting wCompQuality=%d", pc->wCompQuality);
|
||||
_usbh_dbg(uvcdp->dev->host, "SET_CUR (PROBE):"); usbhuvcPrintProbeCommit(uvcdp, &uvcdp->pc);
|
||||
_usbh_dbgf(uvcdp->dev->host, "\tSecond probe, selecting wCompQuality=%d", pc->wCompQuality);
|
||||
if (usbhuvcProbe(uvcdp) != HAL_SUCCESS) {
|
||||
usbDbgPuts("\tSecond probe failed");
|
||||
_usbh_dbg(uvcdp->dev->host, "\tSecond probe failed");
|
||||
continue;
|
||||
}
|
||||
usbDbgPuts("GET_CUR (PROBE):"); usbhuvcPrintProbeCommit(&uvcdp->pc);
|
||||
usbDbgPuts("GET_MIN (PROBE):"); usbhuvcPrintProbeCommit(&uvcdp->pc_min);
|
||||
usbDbgPuts("GET_MAX (PROBE):"); usbhuvcPrintProbeCommit(&uvcdp->pc_max);
|
||||
_usbh_dbg(uvcdp->dev->host, "GET_CUR (PROBE):"); usbhuvcPrintProbeCommit(uvcdp, &uvcdp->pc);
|
||||
_usbh_dbg(uvcdp->dev->host, "GET_MIN (PROBE):"); usbhuvcPrintProbeCommit(uvcdp, &uvcdp->pc_min);
|
||||
_usbh_dbg(uvcdp->dev->host, "GET_MAX (PROBE):"); usbhuvcPrintProbeCommit(uvcdp, &uvcdp->pc_max);
|
||||
|
||||
/* ************************************ */
|
||||
/* Commit negotiated parameters */
|
||||
/* ************************************ */
|
||||
usbDbgPuts("UVC: Commit negotiated parameters");
|
||||
usbDbgPuts("SET_CUR (COMMIT):"); usbhuvcPrintProbeCommit(&uvcdp->pc);
|
||||
_usbh_dbg(uvcdp->dev->host, "UVC: Commit negotiated parameters");
|
||||
_usbh_dbg(uvcdp->dev->host, "SET_CUR (COMMIT):"); usbhuvcPrintProbeCommit(uvcdp, &uvcdp->pc);
|
||||
if (usbhuvcCommit(uvcdp) != HAL_SUCCESS) {
|
||||
usbDbgPuts("\tCommit failed");
|
||||
_usbh_dbg(uvcdp->dev->host, "\tCommit failed");
|
||||
continue;
|
||||
}
|
||||
|
||||
usbDbgPuts("UVC: Ready to start streaming");
|
||||
_usbh_dbg(uvcdp->dev->host, "UVC: Ready to start streaming");
|
||||
|
||||
uint32_t npackets = 0;
|
||||
uint32_t payload = 0;
|
||||
|
@ -774,7 +783,7 @@ failed:
|
|||
msg_t msg, ret;
|
||||
ret = usbhuvcLockAndFetch(uvcdp, &msg, TIME_INFINITE);
|
||||
if (ret == MSG_RESET) {
|
||||
usbDbgPuts("UVC: Driver is unloading");
|
||||
_usbh_dbg(uvcdp->dev->host, "UVC: Driver is unloading");
|
||||
break;
|
||||
} else if (ret == MSG_TIMEOUT) {
|
||||
continue;
|
||||
|
@ -784,7 +793,7 @@ failed:
|
|||
usbhuvc_message_data_t *const data = (usbhuvc_message_data_t *)msg;
|
||||
|
||||
if (data->length < data->data[0]) {
|
||||
usbDbgPrintf("UVC: Length error!");
|
||||
_usbh_dbgf(uvcdp->dev->host, "UVC: Length error!");
|
||||
goto free_data;
|
||||
}
|
||||
|
||||
|
@ -815,20 +824,20 @@ failed:
|
|||
chsnprintf(fn, sizeof(fn), "/img%d.jpg", frame);
|
||||
if (f_open(&fp, fn, FA_CREATE_ALWAYS | FA_WRITE) == FR_OK) {
|
||||
if (with_dht && f_write(&fp, jpeg_header_plus_dht, sizeof(jpeg_header_plus_dht), &bw) != FR_OK) {
|
||||
usbDbgPuts("UVC->MSD: File write error");
|
||||
_usbh_dbg(uvcdp->dev->host, "UVC->MSD: File write error");
|
||||
f_close(&fp);
|
||||
state = 0;
|
||||
}
|
||||
state = 2;
|
||||
} else {
|
||||
usbDbgPuts("UVC->MSD: File open error");
|
||||
_usbh_dbg(uvcdp->dev->host, "UVC->MSD: File open error");
|
||||
state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (state == 2) {
|
||||
if (f_write(&fp, message_data, message_payload, &bw) != FR_OK) {
|
||||
usbDbgPuts("UVC->MSD: File write error");
|
||||
_usbh_dbg(uvcdp->dev->host, "UVC->MSD: File write error");
|
||||
f_close(&fp);
|
||||
state = 0;
|
||||
}
|
||||
|
@ -837,7 +846,7 @@ failed:
|
|||
check_eof:
|
||||
#endif
|
||||
if (data->data[1] & UVC_HDR_EOF) {
|
||||
usbDbgPrintf("UVC: FRAME #%d, delta=%03dticks, #packets=%d, useful_payload=%dbytes, total=%dbytes",
|
||||
_usbh_dbgf(uvcdp->dev->host, "UVC: FRAME #%d, delta=%03dticks, #packets=%d, useful_payload=%dbytes, total=%dbytes",
|
||||
frame, data->timestamp - last , npackets, payload, total);
|
||||
last = data->timestamp;
|
||||
npackets = 0;
|
||||
|
@ -856,17 +865,17 @@ free_data:
|
|||
const uint8_t *const stat = status->data;
|
||||
switch (stat[0] & 0x0f) {
|
||||
case 1:
|
||||
usbDbgPrintf("UVC: STATUS Control event, "
|
||||
_usbh_dbgf(uvcdp->dev->host, "UVC: STATUS Control event, "
|
||||
"bOriginator=%d, bEvent=%d, bSelector=%d, bAttribute=%d",
|
||||
stat[1], stat[2], stat[3], stat[4]);
|
||||
break;
|
||||
case 2:
|
||||
usbDbgPrintf("UVC: STATUS Streaming event, "
|
||||
_usbh_dbgf(uvcdp->dev->host, "UVC: STATUS Streaming event, "
|
||||
"bOriginator=%d, bEvent=%d, bValue=%d",
|
||||
stat[1], stat[2], stat[3]);
|
||||
break;
|
||||
default:
|
||||
usbDbgPrintf("UVC: STATUS unknown status report = %d", stat[0]);
|
||||
_usbh_dbgf(uvcdp->dev->host, "UVC: STATUS unknown status report = %d", stat[0]);
|
||||
break;
|
||||
}
|
||||
usbhuvcFreeStatusMessage(uvcdp, status);
|
||||
|
@ -879,6 +888,16 @@ free_data:
|
|||
}
|
||||
#endif
|
||||
|
||||
#if USBH_DEBUG_MULTI_HOST
|
||||
void USBH_DEBUG_OUTPUT_CALLBACK(USBHDriver *host, const uint8_t *buff, size_t len) {
|
||||
(void)host;
|
||||
#else
|
||||
void USBH_DEBUG_OUTPUT_CALLBACK(const uint8_t *buff, size_t len) {
|
||||
#endif
|
||||
sdWrite(&SD2, buff, len);
|
||||
sdWrite(&SD2, (const uint8_t *)"\r\n", 2);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
IWDG->KR = 0x5555;
|
||||
|
@ -928,9 +947,11 @@ int main(void) {
|
|||
//start
|
||||
#if STM32_USBH_USE_OTG1
|
||||
usbhStart(&USBHD1);
|
||||
_usbh_dbgf(&USBHD1, "Started");
|
||||
#endif
|
||||
#if STM32_USBH_USE_OTG2
|
||||
usbhStart(&USBHD2);
|
||||
_usbh_dbgf(&USBHD2, "Started");
|
||||
#endif
|
||||
|
||||
for(;;) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче