I2C. Merge code from trunk.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3263 35acf78f-673a-0410-8e92-d51de3d6d3f4master
commit
fc492c6d19
|
@ -0,0 +1,192 @@
|
|||
##############################################################################
|
||||
# Build global options
|
||||
# NOTE: Can be overridden externally.
|
||||
#
|
||||
|
||||
# Compiler options here.
|
||||
ifeq ($(USE_OPT),)
|
||||
USE_OPT = -O2 -ggdb -fomit-frame-pointer
|
||||
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
|
||||
|
||||
# If enabled, this option allows to compile the application in THUMB mode.
|
||||
ifeq ($(USE_THUMB),)
|
||||
USE_THUMB = yes
|
||||
endif
|
||||
|
||||
# Enable register caching optimization (read documentation).
|
||||
ifeq ($(USE_CURRP_CACHING),)
|
||||
USE_CURRP_CACHING = no
|
||||
endif
|
||||
|
||||
#
|
||||
# Build global options
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Architecture or project specific options
|
||||
#
|
||||
|
||||
# Enable this if you really want to use the STM FWLib.
|
||||
ifeq ($(USE_FWLIB),)
|
||||
USE_FWLIB = no
|
||||
endif
|
||||
|
||||
#
|
||||
# Architecture or project specific options
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Project, sources and paths
|
||||
#
|
||||
|
||||
# Define project name here
|
||||
PROJECT = ch
|
||||
|
||||
# Imported source files and paths
|
||||
CHIBIOS = ../..
|
||||
include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F1xx/port.mk
|
||||
include $(CHIBIOS)/os/kernel/kernel.mk
|
||||
|
||||
# Define linker script file here
|
||||
LDSCRIPT= $(PORTLD)/STM32F103xB.ld
|
||||
|
||||
# C sources that can be compiled in ARM or THUMB mode depending on the global
|
||||
# setting.
|
||||
CSRC = $(PORTSRC) \
|
||||
$(KERNSRC) \
|
||||
main.c
|
||||
|
||||
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
|
||||
# setting.
|
||||
CPPSRC =
|
||||
|
||||
# C sources to be compiled in ARM mode regardless of the global setting.
|
||||
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
|
||||
# option that results in lower performance and larger code size.
|
||||
ACSRC =
|
||||
|
||||
# C++ sources to be compiled in ARM mode regardless of the global setting.
|
||||
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
|
||||
# option that results in lower performance and larger code size.
|
||||
ACPPSRC =
|
||||
|
||||
# C sources to be compiled in THUMB mode regardless of the global setting.
|
||||
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
|
||||
# option that results in lower performance and larger code size.
|
||||
TCSRC =
|
||||
|
||||
# C sources to be compiled in THUMB mode regardless of the global setting.
|
||||
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
|
||||
# option that results in lower performance and larger code size.
|
||||
TCPPSRC =
|
||||
|
||||
# List ASM source files here
|
||||
ASMSRC = $(PORTASM)
|
||||
|
||||
INCDIR = $(PORTINC) $(KERNINC) $(CHIBIOS)/os/various
|
||||
|
||||
#
|
||||
# Project, sources and paths
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Compiler settings
|
||||
#
|
||||
|
||||
MCU = cortex-m3
|
||||
|
||||
#TRGT = arm-elf-
|
||||
TRGT = arm-none-eabi-
|
||||
CC = $(TRGT)gcc
|
||||
CPPC = $(TRGT)g++
|
||||
# Enable loading with g++ only if you need C++ runtime support.
|
||||
# NOTE: You can use C++ even without C++ support if you are careful. C++
|
||||
# runtime support makes code size explode.
|
||||
LD = $(TRGT)gcc
|
||||
#LD = $(TRGT)g++
|
||||
CP = $(TRGT)objcopy
|
||||
AS = $(TRGT)gcc -x assembler-with-cpp
|
||||
OD = $(TRGT)objdump
|
||||
HEX = $(CP) -O ihex
|
||||
BIN = $(CP) -O binary
|
||||
|
||||
# ARM-specific options here
|
||||
AOPT =
|
||||
|
||||
# THUMB-specific options here
|
||||
TOPT = -mthumb -DTHUMB
|
||||
|
||||
# Define C warning options here
|
||||
CWARN = -Wall -Wextra -Wstrict-prototypes
|
||||
|
||||
# Define C++ warning options here
|
||||
CPPWARN = -Wall -Wextra
|
||||
|
||||
#
|
||||
# Compiler settings
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Start of default section
|
||||
#
|
||||
|
||||
# List all default C defines here, like -D_DEBUG=1
|
||||
DDEFS = -DSTM32F10X_MD
|
||||
|
||||
# List all default ASM defines here, like -D_DEBUG=1
|
||||
DADEFS =
|
||||
|
||||
# List all default directories to look for include files here
|
||||
DINCDIR =
|
||||
|
||||
# List the default directory to look for the libraries here
|
||||
DLIBDIR =
|
||||
|
||||
# List all default libraries here
|
||||
DLIBS =
|
||||
|
||||
#
|
||||
# End of default section
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Start of user section
|
||||
#
|
||||
|
||||
# List all user C define here, like -D_DEBUG=1
|
||||
UDEFS =
|
||||
|
||||
# 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 defines
|
||||
##############################################################################
|
||||
|
||||
ifeq ($(USE_FWLIB),yes)
|
||||
include $(CHIBIOS)/ext/stm32lib/stm32lib.mk
|
||||
CSRC += $(STM32SRC)
|
||||
INCDIR += $(STM32INC)
|
||||
USE_OPT += -DUSE_STDPERIPH_DRIVER
|
||||
endif
|
||||
|
||||
include $(CHIBIOS)/os/ports/GCC/ARMCMx/rules.mk
|
|
@ -0,0 +1,535 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file 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_
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name Kernel parameters and options
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @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_FREQUENCY) || defined(__DOXYGEN__)
|
||||
#define CH_FREQUENCY 1000
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
#if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__)
|
||||
#define CH_TIME_QUANTUM 20
|
||||
#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_USE_MEMCORE.
|
||||
*/
|
||||
#if !defined(CH_MEMCORE_SIZE) || defined(__DOXYGEN__)
|
||||
#define CH_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 automatically. The application has
|
||||
* then the responsibility to do one of the following:
|
||||
* - Spawn a custom idle thread at priority @p IDLEPRIO.
|
||||
* - Change the main() thread priority to @p IDLEPRIO then enter
|
||||
* an endless loop. In this scenario the @p main() thread acts as
|
||||
* the idle thread.
|
||||
* .
|
||||
* @note Unless an idle thread is spawned the @p main() thread must not
|
||||
* enter a sleep state.
|
||||
*/
|
||||
#if !defined(CH_NO_IDLE_THREAD) || defined(__DOXYGEN__)
|
||||
#define CH_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_OPTIMIZE_SPEED) || defined(__DOXYGEN__)
|
||||
#define CH_OPTIMIZE_SPEED TRUE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name Subsystem options
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @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_USE_REGISTRY) || defined(__DOXYGEN__)
|
||||
#define CH_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_USE_WAITEXIT) || defined(__DOXYGEN__)
|
||||
#define CH_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_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
||||
#define CH_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_USE_SEMAPHORES.
|
||||
*/
|
||||
#if !defined(CH_USE_SEMAPHORES_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define CH_USE_SEMAPHORES_PRIORITY FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Atomic semaphore API.
|
||||
* @details If enabled then the semaphores the @p chSemSignalWait() API
|
||||
* is included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
* @note Requires @p CH_USE_SEMAPHORES.
|
||||
*/
|
||||
#if !defined(CH_USE_SEMSW) || defined(__DOXYGEN__)
|
||||
#define CH_USE_SEMSW TRUE
|
||||
#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_USE_MUTEXES) || defined(__DOXYGEN__)
|
||||
#define CH_USE_MUTEXES TRUE
|
||||
#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_USE_MUTEXES.
|
||||
*/
|
||||
#if !defined(CH_USE_CONDVARS) || defined(__DOXYGEN__)
|
||||
#define CH_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_USE_CONDVARS.
|
||||
*/
|
||||
#if !defined(CH_USE_CONDVARS_TIMEOUT) || defined(__DOXYGEN__)
|
||||
#define CH_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_USE_EVENTS) || defined(__DOXYGEN__)
|
||||
#define CH_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_USE_EVENTS.
|
||||
*/
|
||||
#if !defined(CH_USE_EVENTS_TIMEOUT) || defined(__DOXYGEN__)
|
||||
#define CH_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_USE_MESSAGES) || defined(__DOXYGEN__)
|
||||
#define CH_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_USE_MESSAGES.
|
||||
*/
|
||||
#if !defined(CH_USE_MESSAGES_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define CH_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_USE_SEMAPHORES.
|
||||
*/
|
||||
#if !defined(CH_USE_MAILBOXES) || defined(__DOXYGEN__)
|
||||
#define CH_USE_MAILBOXES TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief I/O Queues APIs.
|
||||
* @details If enabled then the I/O queues APIs are included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(CH_USE_QUEUES) || defined(__DOXYGEN__)
|
||||
#define CH_USE_QUEUES 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_USE_MEMCORE) || defined(__DOXYGEN__)
|
||||
#define CH_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_USE_MEMCORE and either @p CH_USE_MUTEXES or
|
||||
* @p CH_USE_SEMAPHORES.
|
||||
* @note Mutexes are recommended.
|
||||
*/
|
||||
#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__)
|
||||
#define CH_USE_HEAP TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief C-runtime allocator.
|
||||
* @details If enabled the the heap allocator APIs just wrap the C-runtime
|
||||
* @p malloc() and @p free() functions.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
* @note Requires @p CH_USE_HEAP.
|
||||
* @note The C-runtime may or may not require @p CH_USE_MEMCORE, see the
|
||||
* appropriate documentation.
|
||||
*/
|
||||
#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
|
||||
#define CH_USE_MALLOC_HEAP FALSE
|
||||
#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_USE_MEMPOOLS) || defined(__DOXYGEN__)
|
||||
#define CH_USE_MEMPOOLS 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_USE_WAITEXIT.
|
||||
* @note Requires @p CH_USE_HEAP and/or @p CH_USE_MEMPOOLS.
|
||||
*/
|
||||
#if !defined(CH_USE_DYNAMIC) || defined(__DOXYGEN__)
|
||||
#define CH_USE_DYNAMIC TRUE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name Debug options
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @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) || defined(__DOXYGEN__)
|
||||
#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) || defined(__DOXYGEN__)
|
||||
#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) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_ENABLE_ASSERTS FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Debug option, trace buffer.
|
||||
* @details If enabled then the context switch circular trace buffer is
|
||||
* activated.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_ENABLE_TRACE FALSE
|
||||
#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) || defined(__DOXYGEN__)
|
||||
#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) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_FILL_THREADS FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Debug option, threads profiling.
|
||||
* @details If enabled then a field is added to the @p Thread structure that
|
||||
* counts the system ticks occurred while executing the thread.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
* @note This debug option is defaulted to TRUE because it is required by
|
||||
* some test cases into the test suite.
|
||||
*/
|
||||
#if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_THREADS_PROFILING TRUE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name Kernel hooks
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Threads descriptor structure extension.
|
||||
* @details User fields added to the end of the @p Thread structure.
|
||||
*/
|
||||
#if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__)
|
||||
#define THREAD_EXT_FIELDS \
|
||||
/* Add threads custom fields here.*/
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Threads initialization hook.
|
||||
* @details User initialization code added to the @p chThdInit() API.
|
||||
*
|
||||
* @note It is invoked from within @p chThdInit() and implicitily from all
|
||||
* the threads creation APIs.
|
||||
*/
|
||||
#if !defined(THREAD_EXT_INIT_HOOK) || defined(__DOXYGEN__)
|
||||
#define THREAD_EXT_INIT_HOOK(tp) { \
|
||||
/* Add threads initialization code here.*/ \
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Threads finalization hook.
|
||||
* @details User finalization code added to the @p chThdExit() API.
|
||||
*
|
||||
* @note It is inserted into lock zone.
|
||||
* @note It is also invoked when the threads simply return in order to
|
||||
* terminate.
|
||||
*/
|
||||
#if !defined(THREAD_EXT_EXIT_HOOK) || defined(__DOXYGEN__)
|
||||
#define THREAD_EXT_EXIT_HOOK(tp) { \
|
||||
/* Add threads finalization code here.*/ \
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Context switch hook.
|
||||
* @details This hook is invoked just before switching between threads.
|
||||
*/
|
||||
#if !defined(THREAD_CONTEXT_SWITCH_HOOK) || defined(__DOXYGEN__)
|
||||
#define THREAD_CONTEXT_SWITCH_HOOK(ntp, otp) { \
|
||||
/* System halt code here.*/ \
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Idle Loop hook.
|
||||
* @details This hook is continuously invoked by the idle thread loop.
|
||||
*/
|
||||
#if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__)
|
||||
#define IDLE_LOOP_HOOK() { \
|
||||
/* Idle loop code here.*/ \
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief System tick event hook.
|
||||
* @details This hook is invoked in the system tick handler immediately
|
||||
* after processing the virtual timers queue.
|
||||
*/
|
||||
#if !defined(SYSTEM_TICK_EVENT_HOOK) || defined(__DOXYGEN__)
|
||||
#define SYSTEM_TICK_EVENT_HOOK() { \
|
||||
/* System tick event code here.*/ \
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief System halt hook.
|
||||
* @details This hook is invoked in case to a system halting error before
|
||||
* the system is halted.
|
||||
*/
|
||||
#if !defined(SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
|
||||
#define SYSTEM_HALT_HOOK() { \
|
||||
/* System halt code here.*/ \
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Port-specific settings (override port settings defaulted in chcore.h). */
|
||||
/*===========================================================================*/
|
||||
|
||||
#endif /* _CHCONF_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,2011 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#if !defined(SYSTEM_CLOCK)
|
||||
#define SYSTEM_CLOCK 8000000
|
||||
#endif
|
||||
|
||||
static uint32_t seconds_counter;
|
||||
static uint32_t minutes_counter;
|
||||
|
||||
/*
|
||||
* This is a periodic thread that does absolutely nothing except increasing
|
||||
* the seconds counter.
|
||||
*/
|
||||
static WORKING_AREA(waThread1, 128);
|
||||
static msg_t Thread1(void *arg) {
|
||||
|
||||
(void)arg;
|
||||
while (TRUE) {
|
||||
chThdSleepMilliseconds(1000);
|
||||
seconds_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Application entry point.
|
||||
*/
|
||||
int main(void) {
|
||||
|
||||
/**
|
||||
* Hardware initialization, in this simple demo just the systick timer is
|
||||
* initialized.
|
||||
*/
|
||||
STBase->RVR = SYSTEM_CLOCK / CH_FREQUENCY - 1;
|
||||
STBase->CVR = 0;
|
||||
STBase->CSR = CLKSOURCE_CORE_BITS | ENABLE_ON_BITS | TICKINT_ENABLED_BITS;
|
||||
|
||||
/*
|
||||
* System initializations.
|
||||
* - Kernel initialization, the main() function becomes a thread and the
|
||||
* RTOS is active.
|
||||
*/
|
||||
chSysInit();
|
||||
|
||||
/*
|
||||
* Creates the example thread.
|
||||
*/
|
||||
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
|
||||
|
||||
/*
|
||||
* Normal main() thread activity, in this demo it does nothing except
|
||||
* increasing the minutes counter.
|
||||
*/
|
||||
while (TRUE) {
|
||||
chThdSleepSeconds(60);
|
||||
minutes_counter++;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
*****************************************************************************
|
||||
** ChibiOS/RT demo for generict ARM Cortex-M3 processor, kernel only. **
|
||||
*****************************************************************************
|
||||
|
||||
** TARGET **
|
||||
|
||||
The demo runs on any ARM Cortex-M3 processor after changing few constants
|
||||
in main.c, the defaults are setup for an STM32F1xx.
|
||||
|
||||
** 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.
|
|
@ -139,6 +139,7 @@
|
|||
<files visible="yes" title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
|
@ -150,7 +151,6 @@
|
|||
<events title=""/>
|
||||
<properties title=""/>
|
||||
<friends title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<memberdef>
|
||||
<pagedocs/>
|
||||
|
|
|
@ -39,6 +39,10 @@
|
|||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name ADC configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
|
@ -54,6 +58,7 @@
|
|||
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define ADC_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
|
@ -84,6 +89,10 @@ typedef enum {
|
|||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Low Level driver helper macros
|
||||
* @{
|
||||
*/
|
||||
#if ADC_USE_WAIT || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Resumes a thread waiting for a conversion completion.
|
||||
|
@ -211,6 +220,7 @@ typedef enum {
|
|||
_adc_wakeup_isr(adcp); \
|
||||
} \
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
|
|
|
@ -35,6 +35,10 @@
|
|||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name CAN status flags
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Errors rate warning.
|
||||
*/
|
||||
|
@ -55,17 +59,26 @@
|
|||
* @brief Overflow in receive queue.
|
||||
*/
|
||||
#define CAN_OVERFLOW_ERROR 16
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name CAN configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Sleep mode related APIs inclusion switch.
|
||||
* @details This option can only be enabled if the CAN implementation supports
|
||||
* the sleep mode, see the macro @p CAN_SUPPORTS_SLEEP exported by
|
||||
* the underlying implementation.
|
||||
*/
|
||||
#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
|
||||
#define CAN_USE_SLEEP_MODE TRUE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
|
@ -96,6 +109,10 @@ typedef enum {
|
|||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Adds some flags to the CAN status mask.
|
||||
*
|
||||
|
@ -105,6 +122,7 @@ typedef enum {
|
|||
* @iclass
|
||||
*/
|
||||
#define canAddFlagsI(canp, mask) ((canp)->status |= (mask))
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
|
|
|
@ -77,6 +77,10 @@ typedef void (*icucallback_t)(ICUDriver *icup);
|
|||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables the input capture.
|
||||
*
|
||||
|
@ -118,7 +122,12 @@ typedef void (*icucallback_t)(ICUDriver *icup);
|
|||
* @iclass
|
||||
*/
|
||||
#define icuGetPeriodI(icup) icu_lld_get_period(icup)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Low Level driver helper macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Common ISR code, ICU width event.
|
||||
*
|
||||
|
@ -144,6 +153,7 @@ typedef void (*icucallback_t)(ICUDriver *icup);
|
|||
if (previous_state != ICU_WAITING) \
|
||||
(icup)->config->period_cb(icup); \
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
|
|
|
@ -56,6 +56,10 @@
|
|||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the received frames event source.
|
||||
*
|
||||
|
@ -98,6 +102,7 @@
|
|||
*/
|
||||
#define macReadReceiveDescriptor(rdp, buf, size) \
|
||||
mac_lld_read_receive_descriptor(rdp, buf, size)
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
|
|
|
@ -18,12 +18,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Parts of this file have been borrowed from the Linux include file
|
||||
* linux/mii.h:
|
||||
* Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com)
|
||||
*/
|
||||
|
||||
/*-*
|
||||
* @file mii.h
|
||||
* @brief MII Driver macros and structures.
|
||||
|
|
|
@ -53,6 +53,10 @@
|
|||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name MMC_SPI configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Block size for MMC transfers.
|
||||
*/
|
||||
|
@ -86,6 +90,7 @@
|
|||
#if !defined(MMC_POLLING_DELAY) || defined(__DOXYGEN__)
|
||||
#define MMC_POLLING_DELAY 10
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
|
@ -181,6 +186,10 @@ typedef struct {
|
|||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the driver state.
|
||||
*
|
||||
|
@ -202,6 +211,7 @@ typedef struct {
|
|||
* @api
|
||||
*/
|
||||
#define mmcIsWriteProtected(mmcp) ((mmcp)->is_protected())
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
|
|
|
@ -35,6 +35,10 @@
|
|||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Pads mode constants
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief After reset state.
|
||||
* @details The state itself is not specified and is architecture dependent,
|
||||
|
@ -81,7 +85,12 @@
|
|||
* @brief Open-drain output pad.
|
||||
*/
|
||||
#define PAL_MODE_OUTPUT_OPENDRAIN 7
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Logic level constants
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Logical low state.
|
||||
*/
|
||||
|
@ -91,6 +100,7 @@
|
|||
* @brief Logical high state.
|
||||
*/
|
||||
#define PAL_HIGH 1
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
|
@ -177,6 +187,10 @@ typedef struct {
|
|||
#define IOBUS_DECL(name, port, width, offset) \
|
||||
IOBus name = _IOBUS_DATA(name, port, width, offset)
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief PAL subsystem initialization.
|
||||
* @note This function is implicitly invoked by @p halInit(), there is
|
||||
|
@ -499,6 +513,7 @@ typedef struct {
|
|||
#else
|
||||
#define palSetPadMode(port, pad, mode) pal_lld_setpadmode(port, pad, mode)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
|
|
|
@ -35,6 +35,10 @@
|
|||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name PWM output mode macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Standard output modes mask.
|
||||
*/
|
||||
|
@ -54,6 +58,7 @@
|
|||
* @brief Inverse PWM logic, active is logic level zero.
|
||||
*/
|
||||
#define PWM_OUTPUT_ACTIVE_LOW 0x02
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
|
@ -94,6 +99,10 @@ typedef void (*pwmcallback_t)(PWMDriver *pwmp);
|
|||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name PWM duty cycle conversion
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Converts from fraction to pulse width.
|
||||
* @note Be careful with rounding errors, this is integer math not magic.
|
||||
|
@ -143,7 +152,12 @@ typedef void (*pwmcallback_t)(PWMDriver *pwmp);
|
|||
*/
|
||||
#define PWM_PERCENTAGE_TO_WIDTH(pwmp, percentage) \
|
||||
PWM_FRACTION_TO_WIDTH(pwmp, 10000, percentage)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Changes the period the PWM peripheral.
|
||||
* @details This function changes the period of a PWM unit that has already
|
||||
|
@ -197,6 +211,7 @@ typedef void (*pwmcallback_t)(PWMDriver *pwmp);
|
|||
*/
|
||||
#define pwmDisableChannelI(pwmp, channel) \
|
||||
pwm_lld_disable_channel(pwmp, channel)
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
|
|
|
@ -42,11 +42,16 @@
|
|||
*/
|
||||
#define SDC_CMD8_PATTERN 0x000001AA
|
||||
|
||||
/**
|
||||
* @name SD cart types
|
||||
* @{
|
||||
*/
|
||||
#define SDC_MODE_CARDTYPE_MASK 0xF /**< @brief Card type mask. */
|
||||
#define SDC_MODE_CARDTYPE_SDV11 0 /**< @brief Card is SD V1.1.*/
|
||||
#define SDC_MODE_CARDTYPE_SDV20 1 /**< @brief Card is SD V2.0.*/
|
||||
#define SDC_MODE_CARDTYPE_MMC 2 /**< @brief Card is MMC. */
|
||||
#define SDC_MODE_HIGH_CAPACITY 0x10 /**< @brief High cap.card. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Mask of error bits in R1 responses.
|
||||
|
@ -87,6 +92,10 @@
|
|||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name SDC configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Number of initialization attempts before rejecting the card.
|
||||
* @note Attempts are performed at 10mS intevals.
|
||||
|
@ -113,6 +122,7 @@
|
|||
#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
|
||||
#define SDC_NICE_WAITING TRUE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
|
@ -142,6 +152,10 @@ typedef enum {
|
|||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name R1 response utilities
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Evaluates to @p TRUE if the R1 response contains error flags.
|
||||
*
|
||||
|
@ -162,7 +176,12 @@ typedef enum {
|
|||
* @param[in] r1 the r1 response
|
||||
*/
|
||||
#define SDC_R1_IS_CARD_LOCKED(r1) (((r1) >> 21) & 1)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the driver state.
|
||||
*
|
||||
|
@ -204,6 +223,7 @@ typedef enum {
|
|||
* @api
|
||||
*/
|
||||
#define sdcIsWriteProtected(sdcp) (sdc_lld_is_write_protected(sdcp))
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
|
@ -222,7 +242,7 @@ extern "C" {
|
|||
uint8_t *buffer, uint32_t n);
|
||||
bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk,
|
||||
const uint8_t *buffer, uint32_t n);
|
||||
bool_t sdc_wait_for_transfer_state(SDCDriver *sdcp);
|
||||
bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -35,21 +35,25 @@
|
|||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** @brief Parity error happened.*/
|
||||
#define SD_PARITY_ERROR 32
|
||||
/** @brief Framing error happened.*/
|
||||
#define SD_FRAMING_ERROR 64
|
||||
/** @brief Overflow happened.*/
|
||||
#define SD_OVERRUN_ERROR 128
|
||||
/** @brief Noise on the line.*/
|
||||
#define SD_NOISE_ERROR 256
|
||||
/** @brief Break detected.*/
|
||||
#define SD_BREAK_DETECTED 512
|
||||
/**
|
||||
* @name Serial status flags
|
||||
* @{
|
||||
*/
|
||||
#define SD_PARITY_ERROR 32 /**< @brief Parity error happened. */
|
||||
#define SD_FRAMING_ERROR 64 /**< @brief Framing error happened. */
|
||||
#define SD_OVERRUN_ERROR 128 /**< @brief Overflow happened. */
|
||||
#define SD_NOISE_ERROR 256 /**< @brief Noise on the line. */
|
||||
#define SD_BREAK_DETECTED 512 /**< @brief Break detected. */
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Serial configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Default bit rate.
|
||||
* @details Configuration parameter, this is the baud rate selected for the
|
||||
|
@ -69,6 +73,7 @@
|
|||
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
|
||||
#define SERIAL_BUFFERS_SIZE 16
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
|
@ -105,6 +110,8 @@ typedef struct SerialDriver SerialDriver;
|
|||
_base_asynchronous_channel_methods
|
||||
|
||||
/**
|
||||
* @extends BaseAsynchronousChannelVMT
|
||||
*
|
||||
* @brief @p SerialDriver virtual methods table.
|
||||
*/
|
||||
struct SerialDriverVMT {
|
||||
|
@ -128,6 +135,10 @@ struct SerialDriver {
|
|||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Direct output check on a @p SerialDriver.
|
||||
* @note This function bypasses the indirect access to the channel and
|
||||
|
@ -281,6 +292,7 @@ struct SerialDriver {
|
|||
*/
|
||||
#define sdAsynchronousRead(sdp, b, n) \
|
||||
chIQReadTimeout(&(sdp)->iqueue, b, n, TIME_IMMEDIATE)
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
|
|
|
@ -39,6 +39,10 @@
|
|||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name SERIAL_USB configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Serial over USB buffers size.
|
||||
* @details Configuration parameter, the buffer size must be a multiple of
|
||||
|
@ -49,6 +53,7 @@
|
|||
#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
|
||||
#define SERIAL_USB_BUFFERS_SIZE 64
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
|
@ -119,6 +124,8 @@ typedef struct {
|
|||
_base_asynchronous_channel_methods
|
||||
|
||||
/**
|
||||
* @extends BaseAsynchronousChannelVMT
|
||||
*
|
||||
* @brief @p SerialDriver virtual methods table.
|
||||
*/
|
||||
struct SerialUSBDriverVMT {
|
||||
|
|
|
@ -39,6 +39,10 @@
|
|||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name SPI configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
|
@ -54,6 +58,7 @@
|
|||
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define SPI_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
|
@ -84,6 +89,10 @@ typedef enum {
|
|||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Asserts the slave select signal and prepares for transfers.
|
||||
*
|
||||
|
@ -201,7 +210,12 @@ typedef enum {
|
|||
* @return The received data frame from the SPI bus.
|
||||
*/
|
||||
#define spiPolledExchange(spip, frame) spi_lld_polled_exchange(spip, frame)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Low Level driver helper macros
|
||||
* @{
|
||||
*/
|
||||
#if SPI_USE_WAIT || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Waits for operation completion.
|
||||
|
@ -268,6 +282,7 @@ typedef enum {
|
|||
(spip)->state = SPI_READY; \
|
||||
_spi_wakeup_isr(spip); \
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
|
|
|
@ -35,18 +35,17 @@
|
|||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** @brief No pending conditions.*/
|
||||
#define UART_NO_ERROR 0
|
||||
/** @brief Parity error happened.*/
|
||||
#define UART_PARITY_ERROR 4
|
||||
/** @brief Framing error happened.*/
|
||||
#define UART_FRAMING_ERROR 8
|
||||
/** @brief Overflow happened.*/
|
||||
#define UART_OVERRUN_ERROR 16
|
||||
/** @brief Noise on the line.*/
|
||||
#define UART_NOISE_ERROR 32
|
||||
/** @brief Break detected.*/
|
||||
#define UART_BREAK_DETECTED 64
|
||||
/**
|
||||
* @name UART status flags
|
||||
* @{
|
||||
*/
|
||||
#define UART_NO_ERROR 0 /**< @brief No pending conditions. */
|
||||
#define UART_PARITY_ERROR 4 /**< @brief Parity error happened. */
|
||||
#define UART_FRAMING_ERROR 8 /**< @brief Framing error happened. */
|
||||
#define UART_OVERRUN_ERROR 16 /**< @brief Overflow happened. */
|
||||
#define UART_NOISE_ERROR 32 /**< @brief Noise on the line. */
|
||||
#define UART_BREAK_DETECTED 64 /**< @brief Break detected. */
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
|
|
|
@ -77,6 +77,10 @@
|
|||
#define USB_EARLY_SET_ADDRESS 0
|
||||
#define USB_LATE_SET_ADDRESS 1
|
||||
|
||||
/**
|
||||
* @name Helper macros for USB descriptors
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Helper macro for index values into descriptor strings.
|
||||
*/
|
||||
|
@ -166,12 +170,17 @@
|
|||
USB_DESC_BYTE(bmAttributes), \
|
||||
USB_DESC_WORD(wMaxPacketSize), \
|
||||
USB_DESC_BYTE(bInterval)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Returned by some functions to report a busy endpoint.
|
||||
*/
|
||||
#define USB_ENDPOINT_BUSY ((size_t)0xFFFFFFFF)
|
||||
|
||||
/**
|
||||
* @name Endpoint types and settings
|
||||
* @{
|
||||
*/
|
||||
#define USB_EP_MODE_TYPE 0x0003 /**< Endpoint type mask. */
|
||||
#define USB_EP_MODE_TYPE_CTRL 0x0000 /**< Control endpoint. */
|
||||
#define USB_EP_MODE_TYPE_ISOC 0x0001 /**< Isochronous endpoint. */
|
||||
|
@ -179,6 +188,7 @@
|
|||
#define USB_EP_MODE_TYPE_INTR 0x0003 /**< Interrupt endpoint. */
|
||||
#define USB_EP_MODE_TRANSACTION 0x0000 /**< Transaction mode. */
|
||||
#define USB_EP_MODE_PACKET 0x0010 /**< Packet mode enabled. */
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
|
@ -311,6 +321,11 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
|
|||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the current frame number.
|
||||
*
|
||||
|
@ -411,7 +426,12 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
|
|||
* @special
|
||||
*/
|
||||
#define usbReadSetup(usbp, ep, buf) usb_lld_read_setup(usbp, ep, buf)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Low Level driver helper macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Common ISR code, usb event callback.
|
||||
*
|
||||
|
@ -474,6 +494,7 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
|
|||
(usbp)->receiving &= ~(1 << (ep)); \
|
||||
(usbp)->epc[ep]->out_cb(usbp, ep); \
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
|
|
|
@ -33,6 +33,10 @@
|
|||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name CDC specific messages.
|
||||
* @{
|
||||
*/
|
||||
#define CDC_SEND_ENCAPSULATED_COMMAND 0x00
|
||||
#define CDC_GET_ENCAPSULATED_RESPONSE 0x01
|
||||
#define CDC_SET_COMM_FEATURE 0x02
|
||||
|
@ -52,7 +56,12 @@
|
|||
#define CDC_GET_RINGER_PARMS 0x31
|
||||
#define CDC_SET_OPERATION_PARMS 0x32
|
||||
#define CDC_GET_OPERATION_PARMS 0x33
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Line Control bit definitions.
|
||||
* @{
|
||||
*/
|
||||
#define LC_STOP_1 0
|
||||
#define LC_STOP_1P5 1
|
||||
#define LC_STOP_2 2
|
||||
|
@ -62,31 +71,37 @@
|
|||
#define LC_PARITY_EVEN 2
|
||||
#define LC_PARITY_MARK 3
|
||||
#define LC_PARITY_SPACE 4
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name USB_CDC configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Endpoint number for bulk IN.
|
||||
*/
|
||||
#if !defined(DATA_REQUEST_EP) || defined(__DOXYGEN__)
|
||||
#define DATA_REQUEST_EP 1
|
||||
#if !defined(USB_CDC_DATA_REQUEST_EP) || defined(__DOXYGEN__)
|
||||
#define USB_CDC_DATA_REQUEST_EP 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Endpoint number for interrupt IN.
|
||||
*/
|
||||
#if !defined(INTERRUPT_REQUEST_EP) || defined(__DOXYGEN__)
|
||||
#define INTERRUPT_REQUEST_EP 2
|
||||
#if !defined(USB_CDC_INTERRUPT_REQUEST_EP) || defined(__DOXYGEN__)
|
||||
#define USB_CDC_INTERRUPT_REQUEST_EP 2
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Endpoint number for bulk OUT.
|
||||
*/
|
||||
#if !defined(DATA_AVAILABLE_EP) || defined(__DOXYGEN__)
|
||||
#define DATA_AVAILABLE_EP 3
|
||||
#if !defined(USB_CDC_DATA_AVAILABLE_EP) || defined(__DOXYGEN__)
|
||||
#define USB_CDC_DATA_AVAILABLE_EP 3
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
|
|
|
@ -78,15 +78,17 @@ static bool_t sdc_lld_read_multiple(SDCDriver *sdcp, uint32_t startblk,
|
|||
uint32_t resp[1];
|
||||
|
||||
/* Checks for errors and waits for the card to be ready for reading.*/
|
||||
if (sdc_wait_for_transfer_state(sdcp))
|
||||
if (_sdc_wait_for_transfer_state(sdcp))
|
||||
return TRUE;
|
||||
|
||||
/* Prepares the DMA channel for reading.*/
|
||||
dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4],
|
||||
(n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf,
|
||||
(STM32_SDC_SDIO_DMA_PRIORITY << 12) |
|
||||
DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 |
|
||||
DMA_CCR1_MINC);
|
||||
dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf);
|
||||
dmaStreamSetTransactionSize(STM32_DMA2_STREAM4,
|
||||
(n * SDC_BLOCK_SIZE) / sizeof (uint32_t));
|
||||
dmaStreamSetMode(STM32_DMA2_STREAM4,
|
||||
STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) |
|
||||
STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_PSIZE_WORD |
|
||||
STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC);
|
||||
|
||||
/* Setting up data transfer.
|
||||
Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/
|
||||
|
@ -100,7 +102,7 @@ static bool_t sdc_lld_read_multiple(SDCDriver *sdcp, uint32_t startblk,
|
|||
SDIO_DCTRL_DTEN;
|
||||
|
||||
/* DMA channel activation.*/
|
||||
dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
|
||||
dmaStreamEnable(STM32_DMA2_STREAM4);
|
||||
|
||||
/* Read multiple blocks command.*/
|
||||
if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0)
|
||||
|
@ -123,14 +125,14 @@ static bool_t sdc_lld_read_multiple(SDCDriver *sdcp, uint32_t startblk,
|
|||
chSysUnlock();
|
||||
goto error;
|
||||
}
|
||||
dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
|
||||
dmaStreamDisable(STM32_DMA2_STREAM4);
|
||||
SDIO->ICR = 0xFFFFFFFF;
|
||||
SDIO->DCTRL = 0;
|
||||
chSysUnlock();
|
||||
|
||||
return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp);
|
||||
error:
|
||||
dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
|
||||
dmaStreamDisable(STM32_DMA2_STREAM4);
|
||||
SDIO->ICR = 0xFFFFFFFF;
|
||||
SDIO->MASK = 0;
|
||||
SDIO->DCTRL = 0;
|
||||
|
@ -156,15 +158,17 @@ static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk,
|
|||
uint32_t resp[1];
|
||||
|
||||
/* Checks for errors and waits for the card to be ready for reading.*/
|
||||
if (sdc_wait_for_transfer_state(sdcp))
|
||||
if (_sdc_wait_for_transfer_state(sdcp))
|
||||
return TRUE;
|
||||
|
||||
/* Prepares the DMA channel for reading.*/
|
||||
dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4],
|
||||
SDC_BLOCK_SIZE / sizeof (uint32_t), buf,
|
||||
(STM32_SDC_SDIO_DMA_PRIORITY << 12) |
|
||||
DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 |
|
||||
DMA_CCR1_MINC);
|
||||
dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf);
|
||||
dmaStreamSetTransactionSize(STM32_DMA2_STREAM4,
|
||||
SDC_BLOCK_SIZE / sizeof (uint32_t));
|
||||
dmaStreamSetMode(STM32_DMA2_STREAM4,
|
||||
STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) |
|
||||
STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_PSIZE_WORD |
|
||||
STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC);
|
||||
|
||||
/* Setting up data transfer.
|
||||
Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/
|
||||
|
@ -178,7 +182,7 @@ static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk,
|
|||
SDIO_DCTRL_DTEN;
|
||||
|
||||
/* DMA channel activation.*/
|
||||
dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
|
||||
dmaStreamEnable(STM32_DMA2_STREAM4);
|
||||
|
||||
/* Read single block command.*/
|
||||
if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0)
|
||||
|
@ -201,14 +205,14 @@ static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk,
|
|||
chSysUnlock();
|
||||
goto error;
|
||||
}
|
||||
dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
|
||||
dmaStreamDisable(STM32_DMA2_STREAM4);
|
||||
SDIO->ICR = 0xFFFFFFFF;
|
||||
SDIO->DCTRL = 0;
|
||||
chSysUnlock();
|
||||
|
||||
return FALSE;
|
||||
error:
|
||||
dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
|
||||
dmaStreamDisable(STM32_DMA2_STREAM4);
|
||||
SDIO->ICR = 0xFFFFFFFF;
|
||||
SDIO->MASK = 0;
|
||||
SDIO->DCTRL = 0;
|
||||
|
@ -235,15 +239,17 @@ static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk,
|
|||
uint32_t resp[1];
|
||||
|
||||
/* Checks for errors and waits for the card to be ready for writing.*/
|
||||
if (sdc_wait_for_transfer_state(sdcp))
|
||||
if (_sdc_wait_for_transfer_state(sdcp))
|
||||
return TRUE;
|
||||
|
||||
/* Prepares the DMA channel for writing.*/
|
||||
dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4],
|
||||
(n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf,
|
||||
(STM32_SDC_SDIO_DMA_PRIORITY << 12) |
|
||||
DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 |
|
||||
DMA_CCR1_MINC | DMA_CCR1_DIR);
|
||||
dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf);
|
||||
dmaStreamSetTransactionSize(STM32_DMA2_STREAM4,
|
||||
(n * SDC_BLOCK_SIZE) / sizeof (uint32_t));
|
||||
dmaStreamSetMode(STM32_DMA2_STREAM4,
|
||||
STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) |
|
||||
STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD |
|
||||
STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC);
|
||||
|
||||
/* Write multiple blocks command.*/
|
||||
if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0)
|
||||
|
@ -265,7 +271,7 @@ static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk,
|
|||
SDIO_DCTRL_DTEN;
|
||||
|
||||
/* DMA channel activation.*/
|
||||
dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
|
||||
dmaStreamEnable(STM32_DMA2_STREAM4);
|
||||
|
||||
/* Note the mask is checked before going to sleep because the interrupt
|
||||
may have occurred before reaching the critical zone.*/
|
||||
|
@ -282,14 +288,14 @@ static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk,
|
|||
chSysUnlock();
|
||||
goto error;
|
||||
}
|
||||
dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
|
||||
dmaStreamDisable(STM32_DMA2_STREAM4);
|
||||
SDIO->ICR = 0xFFFFFFFF;
|
||||
SDIO->DCTRL = 0;
|
||||
chSysUnlock();
|
||||
|
||||
return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp);
|
||||
error:
|
||||
dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
|
||||
dmaStreamDisable(STM32_DMA2_STREAM4);
|
||||
SDIO->ICR = 0xFFFFFFFF;
|
||||
SDIO->MASK = 0;
|
||||
SDIO->DCTRL = 0;
|
||||
|
@ -316,15 +322,17 @@ static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk,
|
|||
uint32_t resp[1];
|
||||
|
||||
/* Checks for errors and waits for the card to be ready for writing.*/
|
||||
if (sdc_wait_for_transfer_state(sdcp))
|
||||
if (_sdc_wait_for_transfer_state(sdcp))
|
||||
return TRUE;
|
||||
|
||||
/* Prepares the DMA channel for writing.*/
|
||||
dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4],
|
||||
SDC_BLOCK_SIZE / sizeof (uint32_t), buf,
|
||||
(STM32_SDC_SDIO_DMA_PRIORITY << 12) |
|
||||
DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 |
|
||||
DMA_CCR1_MINC | DMA_CCR1_DIR);
|
||||
dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf);
|
||||
dmaStreamSetTransactionSize(STM32_DMA2_STREAM4,
|
||||
SDC_BLOCK_SIZE / sizeof (uint32_t));
|
||||
dmaStreamSetMode(STM32_DMA2_STREAM4,
|
||||
STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) |
|
||||
STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD |
|
||||
STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC);
|
||||
|
||||
/* Write single block command.*/
|
||||
if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0)
|
||||
|
@ -346,7 +354,7 @@ static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk,
|
|||
SDIO_DCTRL_DTEN;
|
||||
|
||||
/* DMA channel activation.*/
|
||||
dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
|
||||
dmaStreamEnable(STM32_DMA2_STREAM4);
|
||||
|
||||
/* Note the mask is checked before going to sleep because the interrupt
|
||||
may have occurred before reaching the critical zone.*/
|
||||
|
@ -363,14 +371,14 @@ static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk,
|
|||
chSysUnlock();
|
||||
goto error;
|
||||
}
|
||||
dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
|
||||
dmaStreamDisable(STM32_DMA2_STREAM4);
|
||||
SDIO->ICR = 0xFFFFFFFF;
|
||||
SDIO->DCTRL = 0;
|
||||
chSysUnlock();
|
||||
|
||||
return FALSE;
|
||||
error:
|
||||
dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
|
||||
dmaStreamDisable(STM32_DMA2_STREAM4);
|
||||
SDIO->ICR = 0xFFFFFFFF;
|
||||
SDIO->MASK = 0;
|
||||
SDIO->DCTRL = 0;
|
||||
|
@ -431,8 +439,8 @@ void sdc_lld_start(SDCDriver *sdcp) {
|
|||
|
||||
if (sdcp->state == SDC_STOP) {
|
||||
/* Note, the DMA must be enabled before the IRQs.*/
|
||||
dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_4, NULL, NULL);
|
||||
dmaChannelSetPeripheral(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], &SDIO->FIFO);
|
||||
dmaStreamAllocate(STM32_DMA2_STREAM4, 0, NULL, NULL);
|
||||
dmaStreamSetPeripheral(STM32_DMA2_STREAM4, &SDIO->FIFO);
|
||||
NVICEnableVector(SDIO_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_SDC_SDIO_IRQ_PRIORITY));
|
||||
RCC->AHBENR |= RCC_AHBENR_SDIOEN;
|
||||
|
@ -461,7 +469,7 @@ void sdc_lld_stop(SDCDriver *sdcp) {
|
|||
|
||||
/* Clock deactivation.*/
|
||||
NVICDisableVector(SDIO_IRQn);
|
||||
dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_4);
|
||||
dmaStreamRelease(STM32_DMA2_STREAM4);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -152,7 +152,7 @@ struct SDCDriver {
|
|||
uint32_t rca;
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Tthread waiting for I/O completion IRQ.
|
||||
* @brief Thread waiting for I/O completion IRQ.
|
||||
*/
|
||||
Thread *thread;
|
||||
};
|
||||
|
|
|
@ -67,8 +67,8 @@ static uint16_t dummyrx;
|
|||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*/
|
||||
#define dma_stop(spip) { \
|
||||
dmaChannelDisable(spip->dmatx); \
|
||||
dmaChannelDisable(spip->dmarx); \
|
||||
dmaStreamDisable(spip->dmatx); \
|
||||
dmaStreamDisable(spip->dmarx); \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,7 +91,7 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) {
|
|||
|
||||
/* DMA errors handling.*/
|
||||
#if defined(STM32_SPI_DMA_ERROR_HOOK)
|
||||
if ((flags & DMA_ISR_TEIF1) != 0) {
|
||||
if ((flags & STM32_DMA_ISR_TEIF) != 0) {
|
||||
STM32_SPI_DMA_ERROR_HOOK(spip);
|
||||
}
|
||||
#else
|
||||
|
@ -117,7 +117,7 @@ static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) {
|
|||
/* DMA errors handling.*/
|
||||
#if defined(STM32_SPI_DMA_ERROR_HOOK)
|
||||
(void)spip;
|
||||
if ((flags & DMA_ISR_TEIF1) != 0) {
|
||||
if ((flags & STM32_DMA_ISR_TEIF) != 0) {
|
||||
STM32_SPI_DMA_ERROR_HOOK(spip);
|
||||
}
|
||||
#else
|
||||
|
@ -147,24 +147,24 @@ void spi_lld_init(void) {
|
|||
spiObjectInit(&SPID1);
|
||||
SPID1.thread = NULL;
|
||||
SPID1.spi = SPI1;
|
||||
SPID1.dmarx = STM32_DMA1_CH2;
|
||||
SPID1.dmatx = STM32_DMA1_CH3;
|
||||
SPID1.dmarx = STM32_DMA1_STREAM2;
|
||||
SPID1.dmatx = STM32_DMA1_STREAM3;
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI2
|
||||
spiObjectInit(&SPID2);
|
||||
SPID2.thread = NULL;
|
||||
SPID2.spi = SPI2;
|
||||
SPID2.dmarx = STM32_DMA1_CH4;
|
||||
SPID2.dmatx = STM32_DMA1_CH5;
|
||||
SPID2.dmarx = STM32_DMA1_STREAM4;
|
||||
SPID2.dmatx = STM32_DMA1_STREAM5;
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI3
|
||||
spiObjectInit(&SPID3);
|
||||
SPID3.thread = NULL;
|
||||
SPID3.spi = SPI3;
|
||||
SPID3.dmarx = STM32_DMA2_CH1;
|
||||
SPID3.dmatx = STM32_DMA2_CH2;
|
||||
SPID3.dmarx = STM32_DMA2_STREAM1;
|
||||
SPID3.dmatx = STM32_DMA2_STREAM2;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -181,60 +181,69 @@ void spi_lld_start(SPIDriver *spip) {
|
|||
if (spip->state == SPI_STOP) {
|
||||
#if STM32_SPI_USE_SPI1
|
||||
if (&SPID1 == spip) {
|
||||
/* Note, the DMA must be enabled before the IRQs.*/
|
||||
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_2,
|
||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip);
|
||||
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_3,
|
||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip);
|
||||
NVICEnableVector(DMA1_Channel2_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_SPI_SPI1_IRQ_PRIORITY));
|
||||
NVICEnableVector(DMA1_Channel3_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_SPI_SPI1_IRQ_PRIORITY));
|
||||
bool_t b;
|
||||
b = dmaStreamAllocate(STM32_DMA1_STREAM2,
|
||||
STM32_SPI_SPI1_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
|
||||
(void *)spip);
|
||||
chDbgAssert(!b, "spi_lld_start(), #1", "stream already allocated");
|
||||
b = dmaStreamAllocate(STM32_DMA1_STREAM3,
|
||||
STM32_SPI_SPI1_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
|
||||
(void *)spip);
|
||||
chDbgAssert(!b, "spi_lld_start(), #2", "stream already allocated");
|
||||
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
|
||||
}
|
||||
#endif
|
||||
#if STM32_SPI_USE_SPI2
|
||||
if (&SPID2 == spip) {
|
||||
/* Note, the DMA must be enabled before the IRQs.*/
|
||||
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_4,
|
||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip);
|
||||
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_5,
|
||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip);
|
||||
NVICEnableVector(DMA1_Channel4_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_SPI_SPI2_IRQ_PRIORITY));
|
||||
NVICEnableVector(DMA1_Channel5_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_SPI_SPI2_IRQ_PRIORITY));
|
||||
bool_t b;
|
||||
b = dmaStreamAllocate(STM32_DMA1_STREAM4,
|
||||
STM32_SPI_SPI2_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
|
||||
(void *)spip);
|
||||
chDbgAssert(!b, "spi_lld_start(), #3", "stream already allocated");
|
||||
b = dmaStreamAllocate(STM32_DMA1_STREAM5,
|
||||
STM32_SPI_SPI2_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
|
||||
(void *)spip);
|
||||
chDbgAssert(!b, "spi_lld_start(), #4", "stream already allocated");
|
||||
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
|
||||
}
|
||||
#endif
|
||||
#if STM32_SPI_USE_SPI3
|
||||
if (&SPID3 == spip) {
|
||||
/* Note, the DMA must be enabled before the IRQs.*/
|
||||
dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_1,
|
||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip);
|
||||
dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_2,
|
||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip);
|
||||
NVICEnableVector(DMA2_Channel1_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_SPI_SPI3_IRQ_PRIORITY));
|
||||
NVICEnableVector(DMA2_Channel2_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_SPI_SPI3_IRQ_PRIORITY));
|
||||
bool_t b;
|
||||
b = dmaStreamAllocate(STM32_DMA1_STREAM1,
|
||||
STM32_SPI_SPI3_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
|
||||
(void *)spip);
|
||||
chDbgAssert(!b, "spi_lld_start(), #5", "stream already allocated");
|
||||
b = dmaStreamAllocate(STM32_DMA1_STREAM2,
|
||||
STM32_SPI_SPI3_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
|
||||
(void *)spip);
|
||||
chDbgAssert(!b, "spi_lld_start(), #6", "stream already allocated");
|
||||
RCC->APB1ENR |= RCC_APB1ENR_SPI3EN;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* DMA setup.*/
|
||||
dmaChannelSetPeripheral(spip->dmarx, &spip->spi->DR);
|
||||
dmaChannelSetPeripheral(spip->dmatx, &spip->spi->DR);
|
||||
dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR);
|
||||
dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR);
|
||||
}
|
||||
|
||||
/* More DMA setup.*/
|
||||
if ((spip->config->cr1 & SPI_CR1_DFF) == 0)
|
||||
spip->dmaccr = (STM32_SPI_SPI2_DMA_PRIORITY << 12) |
|
||||
DMA_CCR1_TEIE; /* 8 bits transfers. */
|
||||
spip->dmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) |
|
||||
STM32_DMA_CR_TEIE |
|
||||
STM32_DMA_CR_PSIZE_BYTE |
|
||||
STM32_DMA_CR_MSIZE_BYTE; /* 8 bits transfers. */
|
||||
else
|
||||
spip->dmaccr = (STM32_SPI_SPI2_DMA_PRIORITY << 12) |
|
||||
DMA_CCR1_TEIE | DMA_CCR1_MSIZE_0 |
|
||||
DMA_CCR1_PSIZE_0; /* 16 bits transfers. */
|
||||
spip->dmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) |
|
||||
STM32_DMA_CR_TEIE |
|
||||
STM32_DMA_CR_PSIZE_HWORD |
|
||||
STM32_DMA_CR_MSIZE_HWORD; /* 16 bits transfers. */
|
||||
|
||||
/* SPI setup and enable.*/
|
||||
spip->spi->CR1 = 0;
|
||||
|
@ -261,28 +270,22 @@ void spi_lld_stop(SPIDriver *spip) {
|
|||
|
||||
#if STM32_SPI_USE_SPI1
|
||||
if (&SPID1 == spip) {
|
||||
NVICDisableVector(DMA1_Channel2_IRQn);
|
||||
NVICDisableVector(DMA1_Channel3_IRQn);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_2);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_3);
|
||||
dmaStreamRelease(STM32_DMA1_STREAM2);
|
||||
dmaStreamRelease(STM32_DMA1_STREAM3);
|
||||
RCC->APB2ENR &= ~RCC_APB2ENR_SPI1EN;
|
||||
}
|
||||
#endif
|
||||
#if STM32_SPI_USE_SPI2
|
||||
if (&SPID2 == spip) {
|
||||
NVICDisableVector(DMA1_Channel4_IRQn);
|
||||
NVICDisableVector(DMA1_Channel5_IRQn);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_4);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_5);
|
||||
dmaStreamRelease(STM32_DMA1_STREAM4);
|
||||
dmaStreamRelease(STM32_DMA1_STREAM5);
|
||||
RCC->APB1ENR &= ~RCC_APB1ENR_SPI2EN;
|
||||
}
|
||||
#endif
|
||||
#if STM32_SPI_USE_SPI3
|
||||
if (&SPID3 == spip) {
|
||||
NVICDisableVector(DMA2_Channel1_IRQn);
|
||||
NVICDisableVector(DMA2_Channel2_IRQn);
|
||||
dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_1);
|
||||
dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_2);
|
||||
dmaStreamRelease(STM32_DMA1_STREAM1);
|
||||
dmaStreamRelease(STM32_DMA1_STREAM2);
|
||||
RCC->APB1ENR &= ~RCC_APB1ENR_SPI3EN;
|
||||
}
|
||||
#endif
|
||||
|
@ -327,10 +330,14 @@ void spi_lld_unselect(SPIDriver *spip) {
|
|||
*/
|
||||
void spi_lld_ignore(SPIDriver *spip, size_t n) {
|
||||
|
||||
dmaChannelSetup(spip->dmarx, n, &dummyrx,
|
||||
spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_EN);
|
||||
dmaChannelSetup(spip->dmatx, n, &dummytx,
|
||||
spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_EN);
|
||||
dmaStreamSetMemory0(spip->dmarx, &dummyrx);
|
||||
dmaStreamSetTransactionSize(spip->dmarx, n);
|
||||
dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M |
|
||||
STM32_DMA_CR_TCIE | STM32_DMA_CR_EN);
|
||||
dmaStreamSetMemory0(spip->dmatx, &dummytx);
|
||||
dmaStreamSetTransactionSize(spip->dmatx, n);
|
||||
dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P |
|
||||
STM32_DMA_CR_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -351,12 +358,15 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) {
|
|||
void spi_lld_exchange(SPIDriver *spip, size_t n,
|
||||
const void *txbuf, void *rxbuf) {
|
||||
|
||||
dmaChannelSetup(spip->dmarx, n, rxbuf,
|
||||
spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC |
|
||||
DMA_CCR1_EN);
|
||||
dmaChannelSetup(spip->dmatx, n, txbuf,
|
||||
spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC |
|
||||
DMA_CCR1_EN);
|
||||
dmaStreamSetMemory0(spip->dmarx, rxbuf);
|
||||
dmaStreamSetTransactionSize(spip->dmarx, n);
|
||||
dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M |
|
||||
STM32_DMA_CR_TCIE | STM32_DMA_CR_MINC |
|
||||
STM32_DMA_CR_EN);
|
||||
dmaStreamSetMemory0(spip->dmatx, txbuf);
|
||||
dmaStreamSetTransactionSize(spip->dmatx, n);
|
||||
dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P |
|
||||
STM32_DMA_CR_MINC | STM32_DMA_CR_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -374,11 +384,14 @@ void spi_lld_exchange(SPIDriver *spip, size_t n,
|
|||
*/
|
||||
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
|
||||
|
||||
dmaChannelSetup(spip->dmarx, n, &dummyrx,
|
||||
spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_EN);
|
||||
dmaChannelSetup(spip->dmatx, n, txbuf,
|
||||
spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC |
|
||||
DMA_CCR1_EN);
|
||||
dmaStreamSetMemory0(spip->dmarx, &dummyrx);
|
||||
dmaStreamSetTransactionSize(spip->dmarx, n);
|
||||
dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M |
|
||||
STM32_DMA_CR_TCIE | STM32_DMA_CR_EN);
|
||||
dmaStreamSetMemory0(spip->dmatx, txbuf);
|
||||
dmaStreamSetTransactionSize(spip->dmatx, n);
|
||||
dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P |
|
||||
STM32_DMA_CR_MINC | STM32_DMA_CR_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -396,11 +409,15 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
|
|||
*/
|
||||
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
|
||||
|
||||
dmaChannelSetup(spip->dmarx, n, rxbuf,
|
||||
spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC |
|
||||
DMA_CCR1_EN);
|
||||
dmaChannelSetup(spip->dmatx, n, &dummytx,
|
||||
spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_EN);
|
||||
dmaStreamSetMemory0(spip->dmarx, rxbuf);
|
||||
dmaStreamSetTransactionSize(spip->dmarx, n);
|
||||
dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M |
|
||||
STM32_DMA_CR_TCIE | STM32_DMA_CR_MINC |
|
||||
STM32_DMA_CR_EN);
|
||||
dmaStreamSetMemory0(spip->dmatx, &dummytx);
|
||||
dmaStreamSetTransactionSize(spip->dmatx, n);
|
||||
dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P |
|
||||
STM32_DMA_CR_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -227,17 +227,17 @@ struct SPIDriver{
|
|||
*/
|
||||
SPI_TypeDef *spi;
|
||||
/**
|
||||
* @brief Pointer to the receive DMA channel registers block.
|
||||
* @brief Receive DMA channel.
|
||||
*/
|
||||
stm32_dma_channel_t *dmarx;
|
||||
const stm32_dma_stream_t *dmarx;
|
||||
/**
|
||||
* @brief Pointer to the transmit DMA channel registers block.
|
||||
* @brief Transmit DMA channel.
|
||||
*/
|
||||
stm32_dma_channel_t *dmatx;
|
||||
const stm32_dma_stream_t *dmatx;
|
||||
/**
|
||||
* @brief DMA priority bit mask.
|
||||
* @brief DMA mode bit mask.
|
||||
*/
|
||||
uint32_t dmaccr;
|
||||
uint32_t dmamode;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -19,29 +19,79 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file stm32_dma.c
|
||||
* @brief STM32 DMA helper driver code.
|
||||
* @file DMAv1/stm32_dma.c
|
||||
* @brief DMA helper driver code.
|
||||
*
|
||||
* @addtogroup STM32_DMA
|
||||
* @details DMA sharing helper driver. In the STM32 the DMA channels are a
|
||||
* @details DMA sharing helper driver. In the STM32 the DMA streams are a
|
||||
* shared resource, this driver allows to allocate and free DMA
|
||||
* channels at runtime in order to allow all the other device
|
||||
* streams at runtime in order to allow all the other device
|
||||
* drivers to coordinate the access to the resource.
|
||||
* @note The DMA ISR handlers are all declared into this module because
|
||||
* sharing, the various device drivers can associate a callback to
|
||||
* IRSs when allocating channels.
|
||||
* IRSs when allocating streams.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
/* The following macro is only defined if some driver requiring DMA services
|
||||
has been enabled.*/
|
||||
#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Mask of the DMA1 streams in @p dma_streams_mask.
|
||||
*/
|
||||
#define STM32_DMA1_STREAMS_MASK 0x0000007F
|
||||
|
||||
/**
|
||||
* @brief Mask of the DMA2 streams in @p dma_streams_mask.
|
||||
*/
|
||||
#define STM32_DMA2_STREAMS_MASK 0x00000F80
|
||||
|
||||
/**
|
||||
* @brief Post-reset value of the stream CCR register.
|
||||
*/
|
||||
#define STM32_DMA_CCR_RESET_VALUE 0x00000000
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief DMA streams descriptors.
|
||||
* @details This table keeps the association between an unique stream
|
||||
* identifier and the involved physical registers.
|
||||
* @note Don't use this array directly, use the appropriate wrapper macros
|
||||
* instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc.
|
||||
*/
|
||||
const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
|
||||
{DMA1_Channel1, &DMA1->IFCR, 0, 0, DMA1_Channel1_IRQn},
|
||||
{DMA1_Channel2, &DMA1->IFCR, 4, 1, DMA1_Channel2_IRQn},
|
||||
{DMA1_Channel3, &DMA1->IFCR, 8, 2, DMA1_Channel3_IRQn},
|
||||
{DMA1_Channel4, &DMA1->IFCR, 12, 3, DMA1_Channel4_IRQn},
|
||||
{DMA1_Channel5, &DMA1->IFCR, 16, 4, DMA1_Channel5_IRQn},
|
||||
{DMA1_Channel6, &DMA1->IFCR, 20, 5, DMA1_Channel6_IRQn},
|
||||
{DMA1_Channel7, &DMA1->IFCR, 24, 6, DMA1_Channel7_IRQn},
|
||||
#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
|
||||
{DMA2_Channel1, &DMA2->IFCR, 0, 7, DMA2_Channel1_IRQn},
|
||||
{DMA2_Channel2, &DMA2->IFCR, 4, 8, DMA2_Channel2_IRQn},
|
||||
{DMA2_Channel3, &DMA2->IFCR, 8, 9, DMA2_Channel3_IRQn},
|
||||
#if defined(STM32F10X_CL) || defined(__DOXYGEN__)
|
||||
{DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_IRQn},
|
||||
{DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel5_IRQn},
|
||||
#else /* !STM32F10X_CL */
|
||||
{DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_5_IRQn},
|
||||
{DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel4_5_IRQn},
|
||||
#endif /* !STM32F10X_CL */
|
||||
#endif /* STM32_HAS_DMA2 */
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
@ -50,17 +100,19 @@
|
|||
* @brief DMA ISR redirector type.
|
||||
*/
|
||||
typedef struct {
|
||||
stm32_dmaisr_t dmaisrfunc;
|
||||
void *dmaisrparam;
|
||||
stm32_dmaisr_t dma_func;
|
||||
void *dma_param;
|
||||
} dma_isr_redir_t;
|
||||
|
||||
static uint32_t dmamsk1;
|
||||
static dma_isr_redir_t dma1[7];
|
||||
/**
|
||||
* @brief Mask of the allocated streams.
|
||||
*/
|
||||
static uint32_t dma_streams_mask;
|
||||
|
||||
#if STM32_HAS_DMA2
|
||||
static uint32_t dmamsk2;
|
||||
static dma_isr_redir_t dma2[5];
|
||||
#endif
|
||||
/**
|
||||
* @brief DMA IRQ redirectors.
|
||||
*/
|
||||
static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS];
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
|
@ -71,250 +123,249 @@ static dma_isr_redir_t dma2[5];
|
|||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief DMA1 channel 1 shared interrupt handler.
|
||||
* @brief DMA1 stream 1 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) {
|
||||
uint32_t isr;
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_1 * 4);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_1);
|
||||
if (dma1[0].dmaisrfunc)
|
||||
dma1[0].dmaisrfunc(dma1[0].dmaisrparam, isr);
|
||||
flags = (DMA1->ISR >> 0) & STM32_DMA_ISR_MASK;
|
||||
DMA1->IFCR = STM32_DMA_ISR_MASK << 0;
|
||||
if (dma_isr_redir[0].dma_func)
|
||||
dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 channel 2 shared interrupt handler.
|
||||
* @brief DMA1 stream 2 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) {
|
||||
uint32_t isr;
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_2 * 4);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
|
||||
if (dma1[1].dmaisrfunc)
|
||||
dma1[1].dmaisrfunc(dma1[1].dmaisrparam, isr);
|
||||
flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK;
|
||||
DMA1->IFCR = STM32_DMA_ISR_MASK << 4;
|
||||
if (dma_isr_redir[1].dma_func)
|
||||
dma_isr_redir[1].dma_func(dma_isr_redir[1].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 channel 3 shared interrupt handler.
|
||||
* @brief DMA1 stream 3 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) {
|
||||
uint32_t isr;
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_3 * 4);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
|
||||
if (dma1[2].dmaisrfunc)
|
||||
dma1[2].dmaisrfunc(dma1[2].dmaisrparam, isr);
|
||||
flags = (DMA1->ISR >> 8) & STM32_DMA_ISR_MASK;
|
||||
DMA1->IFCR = STM32_DMA_ISR_MASK << 8;
|
||||
if (dma_isr_redir[2].dma_func)
|
||||
dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 channel 4 shared interrupt handler.
|
||||
* @brief DMA1 stream 4 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) {
|
||||
uint32_t isr;
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_4 * 4);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
|
||||
if (dma1[3].dmaisrfunc)
|
||||
dma1[3].dmaisrfunc(dma1[3].dmaisrparam, isr);
|
||||
flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK;
|
||||
DMA1->IFCR = STM32_DMA_ISR_MASK << 12;
|
||||
if (dma_isr_redir[3].dma_func)
|
||||
dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 channel 5 shared interrupt handler.
|
||||
* @brief DMA1 stream 5 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) {
|
||||
uint32_t isr;
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_5 * 4);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
|
||||
if (dma1[4].dmaisrfunc)
|
||||
dma1[4].dmaisrfunc(dma1[4].dmaisrparam, isr);
|
||||
flags = (DMA1->ISR >> 16) & STM32_DMA_ISR_MASK;
|
||||
DMA1->IFCR = STM32_DMA_ISR_MASK << 16;
|
||||
if (dma_isr_redir[4].dma_func)
|
||||
dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 channel 6 shared interrupt handler.
|
||||
* @brief DMA1 stream 6 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) {
|
||||
uint32_t isr;
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_6 * 4);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
|
||||
if (dma1[5].dmaisrfunc)
|
||||
dma1[5].dmaisrfunc(dma1[5].dmaisrparam, isr);
|
||||
flags = (DMA1->ISR >> 20) & STM32_DMA_ISR_MASK;
|
||||
DMA1->IFCR = STM32_DMA_ISR_MASK << 20;
|
||||
if (dma_isr_redir[5].dma_func)
|
||||
dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 channel 7 shared interrupt handler.
|
||||
* @brief DMA1 stream 7 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) {
|
||||
uint32_t isr;
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_7 * 4);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_7);
|
||||
if (dma1[6].dmaisrfunc)
|
||||
dma1[6].dmaisrfunc(dma1[6].dmaisrparam, isr);
|
||||
flags = (DMA1->ISR >> 24) & STM32_DMA_ISR_MASK;
|
||||
DMA1->IFCR = STM32_DMA_ISR_MASK << 24;
|
||||
if (dma_isr_redir[6].dma_func)
|
||||
dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief DMA2 channel 1 shared interrupt handler.
|
||||
* @brief DMA2 stream 1 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) {
|
||||
uint32_t isr;
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_1 * 4);
|
||||
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_1);
|
||||
if (dma2[0].dmaisrfunc)
|
||||
dma2[0].dmaisrfunc(dma2[0].dmaisrparam, isr);
|
||||
flags = (DMA2->ISR >> 0) & STM32_DMA_ISR_MASK;
|
||||
DMA2->IFCR = STM32_DMA_ISR_MASK << 0;
|
||||
if (dma_isr_redir[7].dma_func)
|
||||
dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA2 channel 2 shared interrupt handler.
|
||||
* @brief DMA2 stream 2 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) {
|
||||
uint32_t isr;
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_2 * 4);
|
||||
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_2);
|
||||
if (dma2[1].dmaisrfunc)
|
||||
dma2[1].dmaisrfunc(dma2[1].dmaisrparam, isr);
|
||||
flags = (DMA2->ISR >> 4) & STM32_DMA_ISR_MASK;
|
||||
DMA2->IFCR = STM32_DMA_ISR_MASK << 4;
|
||||
if (dma_isr_redir[8].dma_func)
|
||||
dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA2 channel 3 shared interrupt handler.
|
||||
* @brief DMA2 stream 3 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Ch3_IRQHandler) {
|
||||
uint32_t isr;
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_3 * 4);
|
||||
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_3);
|
||||
if (dma2[2].dmaisrfunc)
|
||||
dma2[2].dmaisrfunc(dma2[2].dmaisrparam, isr);
|
||||
flags = (DMA2->ISR >> 8) & STM32_DMA_ISR_MASK;
|
||||
DMA2->IFCR = STM32_DMA_ISR_MASK << 8;
|
||||
if (dma_isr_redir[9].dma_func)
|
||||
dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
#if defined(STM32F10X_CL) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief DMA2 channel 4 shared interrupt handler.
|
||||
* @brief DMA2 stream 4 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Ch4_IRQHandler) {
|
||||
uint32_t isr;
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_4 * 4);
|
||||
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
|
||||
if (dma2[3].dmaisrfunc)
|
||||
dma2[3].dmaisrfunc(dma2[3].dmaisrparam, isr);
|
||||
flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK;
|
||||
DMA2->IFCR = STM32_DMA_ISR_MASK << 12;
|
||||
if (dma_isr_redir[10].dma_func)
|
||||
dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA2 channel 5 shared interrupt handler.
|
||||
* @brief DMA2 stream 5 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Ch5_IRQHandler) {
|
||||
uint32_t isr;
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_5 * 4);
|
||||
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5);
|
||||
if (dma2[4].dmaisrfunc)
|
||||
dma2[4].dmaisrfunc(dma2[4].dmaisrparam, isr);
|
||||
flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK;
|
||||
DMA2->IFCR = STM32_DMA_ISR_MASK << 16;
|
||||
if (dma_isr_redir[11].dma_func)
|
||||
dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
#else /* !STM32F10X_CL */
|
||||
/**
|
||||
* @brief DMA2 channels 4 and 5 shared interrupt handler.
|
||||
* @brief DMA2 streams 4 and 5 shared interrupt handler.
|
||||
* @note This IRQ is shared between DMA2 channels 4 and 5 so it is a
|
||||
* bit less efficient because an extra check.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) {
|
||||
uint32_t isr;
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
/* Check on channel 4.*/
|
||||
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_5 * 4);
|
||||
if (isr & DMA_ISR_GIF1) {
|
||||
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5);
|
||||
if (dma2[3].dmaisrfunc)
|
||||
dma2[3].dmaisrfunc(dma2[3].dmaisrparam, isr);
|
||||
flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK;
|
||||
if (flags & STM32_DMA_ISR_MASK) {
|
||||
DMA2->IFCR = STM32_DMA_ISR_MASK << 12;
|
||||
if (dma_isr_redir[10].dma_func)
|
||||
dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags);
|
||||
}
|
||||
|
||||
/* Check on channel 5.*/
|
||||
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_4 * 4);
|
||||
if (isr & DMA_ISR_GIF1) {
|
||||
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5);
|
||||
if (dma2[4].dmaisrfunc)
|
||||
dma2[4].dmaisrfunc(dma2[4].dmaisrparam, isr);
|
||||
flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK;
|
||||
if (flags & STM32_DMA_ISR_MASK) {
|
||||
DMA2->IFCR = STM32_DMA_ISR_MASK << 16;
|
||||
if (dma_isr_redir[11].dma_func)
|
||||
dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags);
|
||||
}
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
|
@ -334,132 +385,109 @@ CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) {
|
|||
void dmaInit(void) {
|
||||
int i;
|
||||
|
||||
dmamsk1 = 0;
|
||||
for (i = STM32_DMA_CHANNEL_7; i >= STM32_DMA_CHANNEL_1; i--) {
|
||||
dmaDisableChannel(STM32_DMA1, i);
|
||||
dma1[i].dmaisrfunc = NULL;
|
||||
dma_streams_mask = 0;
|
||||
for (i = 0; i < STM32_DMA_STREAMS; i++) {
|
||||
_stm32_dma_streams[i].channel->CCR = 0;
|
||||
dma_isr_redir[i].dma_func = NULL;
|
||||
}
|
||||
STM32_DMA1->IFCR = 0xFFFFFFFF;
|
||||
DMA1->IFCR = 0xFFFFFFFF;
|
||||
#if STM32_HAS_DMA2
|
||||
dmamsk2 = 0;
|
||||
for (i = STM32_DMA_CHANNEL_5; i >= STM32_DMA_CHANNEL_1; i--) {
|
||||
dmaDisableChannel(STM32_DMA2, i);
|
||||
dma2[i].dmaisrfunc = NULL;
|
||||
}
|
||||
STM32_DMA1->IFCR = 0xFFFFFFFF;
|
||||
DMA2->IFCR = 0xFFFFFFFF;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocates a DMA channel.
|
||||
* @details The channel is allocated and, if required, the DMA clock enabled.
|
||||
* Trying to allocate a channel already allocated is an illegal
|
||||
* operation and is trapped if assertions are enabled.
|
||||
* @pre The channel must not be already in use.
|
||||
* @post The channel is allocated and the default ISR handler redirected
|
||||
* @brief Allocates a DMA stream.
|
||||
* @details The stream is allocated and, if required, the DMA clock enabled.
|
||||
* The function also enables the IRQ vector associated to the stream
|
||||
* and initializes its priority.
|
||||
* @pre The stream must not be already in use or an error is returned.
|
||||
* @post The stream is allocated and the default ISR handler redirected
|
||||
* to the specified function.
|
||||
* @post The channel must be freed using @p dmaRelease() before it can
|
||||
* @post The stream ISR vector is enabled and its priority configured.
|
||||
* @post The stream must be freed using @p dmaStreamRelease() before it can
|
||||
* be reused with another peripheral.
|
||||
* @post The stream is in its post-reset state.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dma DMA controller id
|
||||
* @param[in] channel requested channel id
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] func handling function pointer, can be @p NULL
|
||||
* @param[in] param a parameter to be passed to the handling function
|
||||
* @return The operation status.
|
||||
* @retval FALSE operation successfully allocated.
|
||||
* @retval TRUE the channel was already in use.
|
||||
* @retval FALSE no error, stream taken.
|
||||
* @retval TRUE error, stream already taken.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
void dmaAllocate(uint32_t dma, uint32_t channel,
|
||||
stm32_dmaisr_t func, void *param) {
|
||||
bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
|
||||
uint32_t priority,
|
||||
stm32_dmaisr_t func,
|
||||
void *param) {
|
||||
|
||||
chDbgCheck(func != NULL, "dmaAllocate");
|
||||
chDbgCheck(dmastp != NULL, "dmaAllocate");
|
||||
|
||||
#if STM32_HAS_DMA2
|
||||
switch (dma) {
|
||||
case STM32_DMA1_ID:
|
||||
#else
|
||||
(void)dma;
|
||||
#endif
|
||||
/* Check if the channel is already taken.*/
|
||||
chDbgAssert((dmamsk1 & (1 << channel)) == 0,
|
||||
"dmaAllocate(), #1", "already allocated");
|
||||
/* Checks if the stream is already taken.*/
|
||||
if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0)
|
||||
return TRUE;
|
||||
|
||||
/* If the DMA unit was idle then the clock is enabled.*/
|
||||
if (dmamsk1 == 0) {
|
||||
/* Marks the stream as allocated.*/
|
||||
dma_isr_redir[dmastp->selfindex].dma_func = func;
|
||||
dma_isr_redir[dmastp->selfindex].dma_param = param;
|
||||
dma_streams_mask |= (1 << dmastp->selfindex);
|
||||
|
||||
/* Enabling DMA clocks required by the current streams set.*/
|
||||
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0)
|
||||
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
|
||||
DMA1->IFCR = 0x0FFFFFFF;
|
||||
}
|
||||
|
||||
dmamsk1 |= 1 << channel;
|
||||
dma1[channel].dmaisrfunc = func;
|
||||
dma1[channel].dmaisrparam = param;
|
||||
#if STM32_HAS_DMA2
|
||||
break;
|
||||
case STM32_DMA2_ID:
|
||||
/* Check if the channel is already taken.*/
|
||||
chDbgAssert((dmamsk2 & (1 << channel)) == 0,
|
||||
"dmaAllocate(), #2", "already allocated");
|
||||
|
||||
/* If the DMA unit was idle then the clock is enabled.*/
|
||||
if (dmamsk2 == 0) {
|
||||
if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0)
|
||||
RCC->AHBENR |= RCC_AHBENR_DMA2EN;
|
||||
DMA2->IFCR = 0x0FFFFFFF;
|
||||
}
|
||||
|
||||
dmamsk2 |= 1 << channel;
|
||||
dma2[channel].dmaisrfunc = func;
|
||||
dma2[channel].dmaisrparam = param;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Putting the stream in a safe state.*/
|
||||
dmaStreamDisable(dmastp);
|
||||
dmaStreamClearInterrupt(dmastp);
|
||||
dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE;
|
||||
|
||||
/* Enables the associated IRQ vector if a callback is defined.*/
|
||||
if (func != NULL)
|
||||
NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Releases a DMA channel.
|
||||
* @details The channel is freed and, if required, the DMA clock disabled.
|
||||
* Trying to release a unallocated channel is an illegal operation
|
||||
* @brief Releases a DMA stream.
|
||||
* @details The stream is freed and, if required, the DMA clock disabled.
|
||||
* Trying to release a unallocated stream is an illegal operation
|
||||
* and is trapped if assertions are enabled.
|
||||
* @pre The channel must have been allocated using @p dmaRequest().
|
||||
* @post The channel is again available.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAllocate().
|
||||
* @post The stream is again available.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dma DMA controller id
|
||||
* @param[in] channel requested channel id
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
void dmaRelease(uint32_t dma, uint32_t channel) {
|
||||
void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {
|
||||
|
||||
#if STM32_HAS_DMA2
|
||||
switch (dma) {
|
||||
case STM32_DMA1_ID:
|
||||
#else
|
||||
(void)dma;
|
||||
#endif
|
||||
/* Check if the channel is not taken.*/
|
||||
chDbgAssert((dmamsk1 & (1 << channel)) != 0,
|
||||
chDbgCheck(dmastp != NULL, "dmaRelease");
|
||||
|
||||
/* Check if the streams is not taken.*/
|
||||
chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0,
|
||||
"dmaRelease(), #1", "not allocated");
|
||||
|
||||
dma1[channel].dmaisrfunc = NULL;
|
||||
dmamsk1 &= ~(1 << channel);
|
||||
if (dmamsk1 == 0)
|
||||
/* Disables the associated IRQ vector.*/
|
||||
NVICDisableVector(dmastp->vector);
|
||||
|
||||
/* Marks the stream as not allocated.*/
|
||||
dma_streams_mask &= ~(1 << dmastp->selfindex);
|
||||
|
||||
/* Shutting down clocks that are no more required, if any.*/
|
||||
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0)
|
||||
RCC->AHBENR &= ~RCC_AHBENR_DMA1EN;
|
||||
#if STM32_HAS_DMA2
|
||||
break;
|
||||
case STM32_DMA2_ID:
|
||||
/* Check if the channel is not taken.*/
|
||||
chDbgAssert((dmamsk2 & (1 << channel)) != 0,
|
||||
"dmaRelease(), #2", "not allocated");
|
||||
|
||||
dma2[channel].dmaisrfunc = NULL;
|
||||
dmamsk2 &= ~(1 << channel);
|
||||
if (dmamsk2 == 0)
|
||||
if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0)
|
||||
RCC->AHBENR &= ~RCC_AHBENR_DMA2EN;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -19,10 +19,12 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file stm32_dma.h
|
||||
* @brief STM32 DMA helper driver header.
|
||||
* @note This file requires definitions from the ST STM32 header file
|
||||
* stm3232f10x.h.
|
||||
* @file DMAv1/stm32_dma.h
|
||||
* @brief DMA helper driver header.
|
||||
* @note This file requires definitions from the ST header files
|
||||
* stm32f10x.h or stm32l1xx.h.
|
||||
* @note This driver uses the new naming convention used for the STM32F2xx
|
||||
* so the "DMA channels" are referred as "DMA streams".
|
||||
*
|
||||
* @addtogroup STM32_DMA
|
||||
* @{
|
||||
|
@ -35,14 +37,82 @@
|
|||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** @brief DMA1 identifier.*/
|
||||
#define STM32_DMA1_ID 0
|
||||
|
||||
/** @brief DMA2 identifier.*/
|
||||
/**
|
||||
* @brief Total number of DMA streams.
|
||||
* @note This is the total number of streams among all the DMA units.
|
||||
*/
|
||||
#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
|
||||
#define STM32_DMA2_ID 1
|
||||
#define STM32_DMA_STREAMS 12
|
||||
#else
|
||||
#define STM32_DMA_STREAMS 7
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Mask of the ISR bits passed to the DMA callback functions.
|
||||
*/
|
||||
#define STM32_DMA_ISR_MASK 0x0F
|
||||
|
||||
/**
|
||||
* @name DMA streams identifiers
|
||||
* @{
|
||||
*/
|
||||
#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[0])
|
||||
#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[1])
|
||||
#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[2])
|
||||
#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[3])
|
||||
#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[4])
|
||||
#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[5])
|
||||
#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[6])
|
||||
#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[8])
|
||||
#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[9])
|
||||
#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[10])
|
||||
#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[11])
|
||||
#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[12])
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name CR register constants common to all DMA types
|
||||
*/
|
||||
#define STM32_DMA_CR_EN DMA_CCR1_EN
|
||||
#define STM32_DMA_CR_TEIE DMA_CCR1_TEIE
|
||||
#define STM32_DMA_CR_HTIE DMA_CCR1_HTIE
|
||||
#define STM32_DMA_CR_TCIE DMA_CCR1_TCIE
|
||||
#define STM32_DMA_CR_DIR_MASK (DMA_CCR1_DIR | DMA_CCR1_MEM2MEM)
|
||||
#define STM32_DMA_CR_DIR_P2M 0
|
||||
#define STM32_DMA_CR_DIR_M2P DMA_CCR1_DIR
|
||||
#define STM32_DMA_CR_DIR_M2M DMA_CCR1_MEM2MEM
|
||||
#define STM32_DMA_CR_CIRC DMA_CCR1_CIRC
|
||||
#define STM32_DMA_CR_PINC DMA_CCR1_PINC
|
||||
#define STM32_DMA_CR_MINC DMA_CCR1_MINC
|
||||
#define STM32_DMA_CR_PSIZE_MASK DMA_CCR1_PSIZE
|
||||
#define STM32_DMA_CR_PSIZE_BYTE 0
|
||||
#define STM32_DMA_CR_PSIZE_HWORD DMA_CCR1_PSIZE_0
|
||||
#define STM32_DMA_CR_PSIZE_WORD DMA_CCR1_PSIZE_1
|
||||
#define STM32_DMA_CR_MSIZE_MASK DMA_CCR1_MSIZE
|
||||
#define STM32_DMA_CR_MSIZE_BYTE 0
|
||||
#define STM32_DMA_CR_MSIZE_HWORD DMA_CCR1_MSIZE_0
|
||||
#define STM32_DMA_CR_MSIZE_WORD DMA_CCR1_MSIZE_1
|
||||
#define STM32_DMA_CR_PL_MASK DMA_CCR1_PL
|
||||
#define STM32_DMA_CR_PL(n) ((n) << 12)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name CR register constants only found in enhanced DMA
|
||||
*/
|
||||
#define STM32_DMA_CR_CHSEL_MASK 0 /**< @brief Ignored by normal DMA. */
|
||||
#define STM32_DMA_CR_CHSEL(n) 0 /**< @brief Ignored by normal DMA. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Status flags passed to the ISR callbacks
|
||||
*/
|
||||
#define STM32_DMA_ISR_FEIF 0
|
||||
#define STM32_DMA_ISR_DMEIF 0
|
||||
#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1
|
||||
#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1
|
||||
#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
@ -56,33 +126,23 @@
|
|||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief STM32 DMA channel memory structure type.
|
||||
* @brief STM32 DMA stream descriptor structure.
|
||||
*/
|
||||
typedef struct {
|
||||
volatile uint32_t CCR;
|
||||
volatile uint32_t CNDTR;
|
||||
volatile uint32_t CPAR;
|
||||
volatile uint32_t CMAR;
|
||||
volatile uint32_t dummy;
|
||||
} stm32_dma_channel_t;
|
||||
|
||||
/**
|
||||
* @brief STM32 DMA subsystem memory structure type.
|
||||
* @note This structure has been redefined here because it is convenient to
|
||||
* have the channels organized as an array, the ST header does not
|
||||
* do that.
|
||||
*/
|
||||
typedef struct {
|
||||
volatile uint32_t ISR;
|
||||
volatile uint32_t IFCR;
|
||||
stm32_dma_channel_t channels[7];
|
||||
} stm32_dma_t;
|
||||
DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */
|
||||
volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */
|
||||
uint8_t ishift; /**< @brief Bits offset in xIFCR
|
||||
register. */
|
||||
uint8_t selfindex; /**< @brief Index to self in array. */
|
||||
uint8_t vector; /**< @brief Associated IRQ vector. */
|
||||
} stm32_dma_stream_t;
|
||||
|
||||
/**
|
||||
* @brief STM32 DMA ISR function type.
|
||||
*
|
||||
* @param[in] p parameter for the registered function
|
||||
* @param[in] flags pre-shifted content of the ISR register
|
||||
* @param[in] flags pre-shifted content of the ISR register, the bits
|
||||
* are aligned to bit zero
|
||||
*/
|
||||
typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
||||
|
||||
|
@ -90,187 +150,122 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
|||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** DMA1 registers block numeric address.*/
|
||||
#define STM32_DMA1_BASE (AHBPERIPH_BASE + 0x0000)
|
||||
/** Pointer to the DMA1 registers block.*/
|
||||
#define STM32_DMA1 ((stm32_dma_t *)STM32_DMA1_BASE)
|
||||
/** Pointer to the DMA1 channel 1 registers block.*/
|
||||
#define STM32_DMA1_CH1 (&STM32_DMA1->channels[0])
|
||||
/** Pointer to the DMA1 channel 2 registers block.*/
|
||||
#define STM32_DMA1_CH2 (&STM32_DMA1->channels[1])
|
||||
/** Pointer to the DMA1 channel 3 registers block.*/
|
||||
#define STM32_DMA1_CH3 (&STM32_DMA1->channels[2])
|
||||
/** Pointer to the DMA1 channel 4 registers block.*/
|
||||
#define STM32_DMA1_CH4 (&STM32_DMA1->channels[3])
|
||||
/** Pointer to the DMA1 channel 5 registers block.*/
|
||||
#define STM32_DMA1_CH5 (&STM32_DMA1->channels[4])
|
||||
/** Pointer to the DMA1 channel 6 registers block.*/
|
||||
#define STM32_DMA1_CH6 (&STM32_DMA1->channels[5])
|
||||
/** Pointer to the DMA1 channel 7 registers block.*/
|
||||
#define STM32_DMA1_CH7 (&STM32_DMA1->channels[6])
|
||||
|
||||
#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
|
||||
/** DMA2 registers block numeric address.*/
|
||||
#define STM32_DMA2_BASE (AHBPERIPH_BASE + 0x0400)
|
||||
/** Pointer to the DMA2 registers block.*/
|
||||
#define STM32_DMA2 ((stm32_dma_t *)STM32_DMA2_BASE)
|
||||
/** Pointer to the DMA2 channel 1 registers block.*/
|
||||
#define STM32_DMA2_CH1 (&STM32_DMA2->channels[0])
|
||||
/** Pointer to the DMA2 channel 2 registers block.*/
|
||||
#define STM32_DMA2_CH2 (&STM32_DMA2->channels[1])
|
||||
/** Pointer to the DMA2 channel 3 registers block.*/
|
||||
#define STM32_DMA2_CH3 (&STM32_DMA2->channels[2])
|
||||
/** Pointer to the DMA2 channel 4 registers block.*/
|
||||
#define STM32_DMA2_CH4 (&STM32_DMA2->channels[3])
|
||||
/** Pointer to the DMA2 channel 5 registers block.*/
|
||||
#define STM32_DMA2_CH5 (&STM32_DMA2->channels[4])
|
||||
#endif
|
||||
|
||||
#define STM32_DMA_CHANNEL_1 0 /**< @brief DMA channel 1. */
|
||||
#define STM32_DMA_CHANNEL_2 1 /**< @brief DMA channel 2. */
|
||||
#define STM32_DMA_CHANNEL_3 2 /**< @brief DMA channel 3. */
|
||||
#define STM32_DMA_CHANNEL_4 3 /**< @brief DMA channel 4. */
|
||||
#define STM32_DMA_CHANNEL_5 4 /**< @brief DMA channel 5. */
|
||||
#define STM32_DMA_CHANNEL_6 5 /**< @brief DMA channel 6. */
|
||||
#define STM32_DMA_CHANNEL_7 6 /**< @brief DMA channel 7. */
|
||||
|
||||
/**
|
||||
* @brief Associates a peripheral data register to a DMA channel.
|
||||
* @brief Associates a peripheral data register to a DMA stream.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
|
||||
* @param[in] cpar value to be written in the CPAR register
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] addr value to be written in the CPAR register
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaChannelSetPeripheral(dmachp, cpar) { \
|
||||
(dmachp)->CPAR = (uint32_t)(cpar); \
|
||||
#define dmaStreamSetPeripheral(dmastp, addr) { \
|
||||
(dmastp)->channel->CPAR = (uint32_t)(addr); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA channel setup by channel pointer.
|
||||
* @note This macro does not change the CPAR register because that register
|
||||
* value does not change frequently, it usually points to a peripheral
|
||||
* data register.
|
||||
* @brief Associates a memory destination to a DMA stream.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
|
||||
* @param[in] cndtr value to be written in the CNDTR register
|
||||
* @param[in] cmar value to be written in the CMAR register
|
||||
* @param[in] ccr value to be written in the CCR register
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] addr value to be written in the CMAR register
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaChannelSetup(dmachp, cndtr, cmar, ccr) { \
|
||||
(dmachp)->CNDTR = (uint32_t)(cndtr); \
|
||||
(dmachp)->CMAR = (uint32_t)(cmar); \
|
||||
(dmachp)->CCR = (uint32_t)(ccr); \
|
||||
#define dmaStreamSetMemory0(dmastp, addr) { \
|
||||
(dmastp)->channel->CMAR = (uint32_t)(addr); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA channel enable by channel pointer.
|
||||
* @brief Sets the number of transfers to be performed.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] size value to be written in the CNDTR register
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaChannelEnable(dmachp) { \
|
||||
(dmachp)->CCR |= DMA_CCR1_EN; \
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief DMA channel disable by channel pointer.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaChannelDisable(dmachp) { \
|
||||
(dmachp)->CCR = 0; \
|
||||
#define dmaStreamSetTransactionSize(dmastp, size) { \
|
||||
(dmastp)->channel->CNDTR = (uint32_t)(size); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA channel setup by channel ID.
|
||||
* @note This macro does not change the CPAR register because that register
|
||||
* value does not change frequently, it usually points to a peripheral
|
||||
* data register.
|
||||
* @note Channels are numbered from 0 to 6, use the appropriate macro
|
||||
* as parameter.
|
||||
* @brief Returns the number of transfers to be performed.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmap pointer to a stm32_dma_t structure
|
||||
* @param[in] ch channel number
|
||||
* @param[in] cndtr value to be written in the CNDTR register
|
||||
* @param[in] cmar value to be written in the CMAR register
|
||||
* @param[in] ccr value to be written in the CCR register
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @return The number of transfers to be performed.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaSetupChannel(dmap, ch, cndtr, cmar, ccr) { \
|
||||
dmaChannelSetup(&(dmap)->channels[ch], (cndtr), (cmar), (ccr)); \
|
||||
#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->channel->CNDTR))
|
||||
|
||||
/**
|
||||
* @brief Programs the stream mode settings.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] mode value to be written in the CCR register
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamSetMode(dmastp, mode) { \
|
||||
(dmastp)->channel->CCR = (uint32_t)(mode); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA channel enable by channel ID.
|
||||
* @note Channels are numbered from 0 to 6, use the appropriate macro
|
||||
* as parameter.
|
||||
* @brief DMA stream enable.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmap pointer to a stm32_dma_t structure
|
||||
* @param[in] ch channel number
|
||||
* @param[in] dmachp pointer to a stm32_dma_stream_t structure
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaEnableChannel(dmap, ch) { \
|
||||
dmaChannelEnable(&(dmap)->channels[ch]); \
|
||||
#define dmaStreamEnable(dmastp) { \
|
||||
(dmastp)->channel->CCR |= STM32_DMA_CR_EN; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA channel disable by channel ID.
|
||||
* @note Channels are numbered from 0 to 6, use the appropriate macro
|
||||
* as parameter.
|
||||
* @brief DMA stream disable.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmap pointer to a stm32_dma_t structure
|
||||
* @param[in] ch channel number
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaDisableChannel(dmap, ch) { \
|
||||
dmaChannelDisable(&(dmap)->channels[ch]); \
|
||||
#define dmaStreamDisable(dmastp) { \
|
||||
(dmastp)->channel->CCR &= ~STM32_DMA_CR_EN; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA channel interrupt sources clear.
|
||||
* @details Sets the appropriate CGIF bit into the IFCR register in order to
|
||||
* withdraw all the pending interrupt bits from the ISR register.
|
||||
* @note Channels are numbered from 0 to 6, use the appropriate macro
|
||||
* as parameter.
|
||||
* @brief DMA stream interrupt sources clear.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmap pointer to a stm32_dma_t structure
|
||||
* @param[in] ch channel number
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaClearChannel(dmap, ch){ \
|
||||
(dmap)->IFCR = 1 << ((ch) * 4); \
|
||||
#define dmaStreamClearInterrupt(dmastp) { \
|
||||
*(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS];
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void dmaInit(void);
|
||||
void dmaAllocate(uint32_t dma, uint32_t channel,
|
||||
stm32_dmaisr_t func, void *param);
|
||||
void dmaRelease(uint32_t dma, uint32_t channel);
|
||||
bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
|
||||
uint32_t priority,
|
||||
stm32_dmaisr_t func,
|
||||
void *param);
|
||||
void dmaStreamRelease(const stm32_dma_stream_t *dmastp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -87,17 +87,19 @@ static uartflags_t translate_errors(uint16_t sr) {
|
|||
* @param[in] uartp pointer to the @p UARTDriver object
|
||||
*/
|
||||
static void set_rx_idle_loop(UARTDriver *uartp) {
|
||||
uint32_t ccr;
|
||||
uint32_t mode;
|
||||
|
||||
/* RX DMA channel preparation, if the char callback is defined then the
|
||||
TCIE interrupt is enabled too.*/
|
||||
if (uartp->config->rxchar_cb == NULL)
|
||||
ccr = DMA_CCR1_CIRC | DMA_CCR1_TEIE;
|
||||
mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TEIE;
|
||||
else
|
||||
ccr = DMA_CCR1_CIRC | DMA_CCR1_TEIE | DMA_CCR1_TCIE;
|
||||
dmaSetupChannel(uartp->dmap, uartp->dmarx, 1,
|
||||
&uartp->rxbuf, uartp->dmaccr | ccr);
|
||||
dmaEnableChannel(uartp->dmap, uartp->dmarx);
|
||||
mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TEIE |
|
||||
STM32_DMA_CR_TCIE;
|
||||
dmaStreamSetMemory0(uartp->dmarx, &uartp->rxbuf);
|
||||
dmaStreamSetTransactionSize(uartp->dmarx, 1);
|
||||
dmaStreamSetMode(uartp->dmarx, uartp->dmamode | mode);
|
||||
dmaStreamEnable(uartp->dmarx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,10 +111,10 @@ static void set_rx_idle_loop(UARTDriver *uartp) {
|
|||
static void usart_stop(UARTDriver *uartp) {
|
||||
|
||||
/* Stops RX and TX DMA channels.*/
|
||||
dmaDisableChannel(uartp->dmap, uartp->dmarx);
|
||||
dmaDisableChannel(uartp->dmap, uartp->dmatx);
|
||||
dmaClearChannel(uartp->dmap, uartp->dmarx);
|
||||
dmaClearChannel(uartp->dmap, uartp->dmatx);
|
||||
dmaStreamDisable(uartp->dmarx);
|
||||
dmaStreamClearInterrupt(uartp->dmarx);
|
||||
dmaStreamDisable(uartp->dmatx);
|
||||
dmaStreamClearInterrupt(uartp->dmatx);
|
||||
|
||||
/* Stops USART operations.*/
|
||||
uartp->usart->CR1 = 0;
|
||||
|
@ -170,7 +172,7 @@ static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) {
|
|||
|
||||
/* DMA errors handling.*/
|
||||
#if defined(STM32_UART_DMA_ERROR_HOOK)
|
||||
if ((flags & DMA_ISR_TEIF1) != 0) {
|
||||
if ((flags & STM32_DMA_ISR_TEIF) != 0) {
|
||||
STM32_UART_DMA_ERROR_HOOK(uartp);
|
||||
}
|
||||
#else
|
||||
|
@ -186,7 +188,7 @@ static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) {
|
|||
else {
|
||||
/* Receiver in active state, a callback is generated, if enabled, after
|
||||
a completed transfer.*/
|
||||
dmaDisableChannel(uartp->dmap, uartp->dmarx);
|
||||
dmaStreamDisable(uartp->dmarx);
|
||||
uartp->rxstate = UART_RX_COMPLETE;
|
||||
if (uartp->config->rxend_cb != NULL)
|
||||
uartp->config->rxend_cb(uartp);
|
||||
|
@ -209,14 +211,14 @@ static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) {
|
|||
|
||||
/* DMA errors handling.*/
|
||||
#if defined(STM32_UART_DMA_ERROR_HOOK)
|
||||
if ((flags & DMA_ISR_TEIF1) != 0) {
|
||||
if ((flags & STM32_DMA_ISR_TEIF) != 0) {
|
||||
STM32_UART_DMA_ERROR_HOOK(uartp);
|
||||
}
|
||||
#else
|
||||
(void)flags;
|
||||
#endif
|
||||
|
||||
dmaDisableChannel(uartp->dmap, uartp->dmatx);
|
||||
dmaStreamDisable(uartp->dmatx);
|
||||
/* A callback is generated, if enabled, after a completed transfer.*/
|
||||
uartp->txstate = UART_TX_COMPLETE;
|
||||
if (uartp->config->txend1_cb != NULL)
|
||||
|
@ -318,28 +320,22 @@ void uart_lld_init(void) {
|
|||
#if STM32_UART_USE_USART1
|
||||
uartObjectInit(&UARTD1);
|
||||
UARTD1.usart = USART1;
|
||||
UARTD1.dmap = STM32_DMA1;
|
||||
UARTD1.dmarx = STM32_DMA_CHANNEL_5;
|
||||
UARTD1.dmatx = STM32_DMA_CHANNEL_4;
|
||||
UARTD1.dmaccr = 0;
|
||||
UARTD1.dmarx = STM32_DMA1_STREAM5;
|
||||
UARTD1.dmatx = STM32_DMA1_STREAM4;
|
||||
#endif
|
||||
|
||||
#if STM32_UART_USE_USART2
|
||||
uartObjectInit(&UARTD2);
|
||||
UARTD2.usart = USART2;
|
||||
UARTD2.dmap = STM32_DMA1;
|
||||
UARTD2.dmarx = STM32_DMA_CHANNEL_6;
|
||||
UARTD2.dmatx = STM32_DMA_CHANNEL_7;
|
||||
UARTD2.dmaccr = 0;
|
||||
UARTD2.dmarx = STM32_DMA1_STREAM6;
|
||||
UARTD2.dmatx = STM32_DMA1_STREAM7;
|
||||
#endif
|
||||
|
||||
#if STM32_UART_USE_USART3
|
||||
uartObjectInit(&UARTD3);
|
||||
UARTD3.usart = USART3;
|
||||
UARTD3.dmap = STM32_DMA1;
|
||||
UARTD3.dmarx = STM32_DMA_CHANNEL_3;
|
||||
UARTD3.dmatx = STM32_DMA_CHANNEL_2;
|
||||
UARTD3.dmaccr = 0;
|
||||
UARTD3.dmarx = STM32_DMA1_STREAM3;
|
||||
UARTD3.dmatx = STM32_DMA1_STREAM2;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -355,64 +351,68 @@ void uart_lld_start(UARTDriver *uartp) {
|
|||
if (uartp->state == UART_STOP) {
|
||||
#if STM32_UART_USE_USART1
|
||||
if (&UARTD1 == uartp) {
|
||||
/* Note, the DMA must be enabled before the IRQs.*/
|
||||
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_4,
|
||||
(stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp);
|
||||
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_5,
|
||||
(stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp);
|
||||
bool_t b;
|
||||
b = dmaStreamAllocate(STM32_DMA1_STREAM4,
|
||||
STM32_UART_USART1_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
|
||||
(void *)uartp);
|
||||
chDbgAssert(!b, "uart_lld_start(), #1", "stream already allocated");
|
||||
b = dmaStreamAllocate(STM32_DMA1_STREAM5,
|
||||
STM32_UART_USART1_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
|
||||
(void *)uartp);
|
||||
chDbgAssert(!b, "uart_lld_start(), #2", "stream already allocated");
|
||||
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
|
||||
NVICEnableVector(USART1_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY));
|
||||
NVICEnableVector(DMA1_Channel4_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY));
|
||||
NVICEnableVector(DMA1_Channel5_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY));
|
||||
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if STM32_UART_USE_USART2
|
||||
if (&UARTD2 == uartp) {
|
||||
/* Note, the DMA must be enabled before the IRQs.*/
|
||||
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_6,
|
||||
(stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp);
|
||||
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_7,
|
||||
(stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp);
|
||||
bool_t b;
|
||||
b = dmaStreamAllocate(STM32_DMA1_STREAM6,
|
||||
STM32_UART_USART2_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
|
||||
(void *)uartp);
|
||||
chDbgAssert(!b, "uart_lld_start(), #3", "stream already allocated");
|
||||
b = dmaStreamAllocate(STM32_DMA1_STREAM7,
|
||||
STM32_UART_USART2_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
|
||||
(void *)uartp);
|
||||
chDbgAssert(!b, "uart_lld_start(), #4", "stream already allocated");
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
|
||||
NVICEnableVector(USART2_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY));
|
||||
NVICEnableVector(DMA1_Channel6_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY));
|
||||
NVICEnableVector(DMA1_Channel7_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY));
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if STM32_UART_USE_USART3
|
||||
if (&UARTD3 == uartp) {
|
||||
/* Note, the DMA must be enabled before the IRQs.*/
|
||||
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_2,
|
||||
(stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp);
|
||||
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_3,
|
||||
(stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp);
|
||||
bool_t b;
|
||||
b = dmaStreamAllocate(STM32_DMA1_STREAM2,
|
||||
STM32_UART_USART3_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
|
||||
(void *)uartp);
|
||||
chDbgAssert(!b, "uart_lld_start(), #5", "stream already allocated");
|
||||
b = dmaStreamAllocate(STM32_DMA1_STREAM3,
|
||||
STM32_UART_USART3_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
|
||||
(void *)uartp);
|
||||
chDbgAssert(!b, "uart_lld_start(), #6", "stream already allocated");
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
|
||||
NVICEnableVector(USART3_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY));
|
||||
NVICEnableVector(DMA1_Channel2_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY));
|
||||
NVICEnableVector(DMA1_Channel3_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY));
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Static DMA setup, the transfer size depends on the USART settings,
|
||||
it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/
|
||||
uartp->dmaccr = STM32_UART_USART1_DMA_PRIORITY << 12;
|
||||
uartp->dmamode = STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY);
|
||||
if ((uartp->config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M)
|
||||
uartp->dmaccr |= DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0;
|
||||
dmaChannelSetPeripheral(&uartp->dmap->channels[uartp->dmarx],
|
||||
&uartp->usart->DR);
|
||||
dmaChannelSetPeripheral(&uartp->dmap->channels[uartp->dmatx],
|
||||
&uartp->usart->DR);
|
||||
uartp->dmamode |= STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
|
||||
dmaStreamSetPeripheral(uartp->dmarx, &uartp->usart->DR);
|
||||
dmaStreamSetPeripheral(uartp->dmatx, &uartp->usart->DR);
|
||||
uartp->rxbuf = 0;
|
||||
}
|
||||
|
||||
|
@ -435,11 +435,9 @@ void uart_lld_stop(UARTDriver *uartp) {
|
|||
|
||||
#if STM32_UART_USE_USART1
|
||||
if (&UARTD1 == uartp) {
|
||||
dmaStreamRelease(STM32_DMA1_STREAM4);
|
||||
dmaStreamRelease(STM32_DMA1_STREAM5);
|
||||
NVICDisableVector(USART1_IRQn);
|
||||
NVICDisableVector(DMA1_Channel4_IRQn);
|
||||
NVICDisableVector(DMA1_Channel5_IRQn);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_4);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_5);
|
||||
RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN;
|
||||
return;
|
||||
}
|
||||
|
@ -447,11 +445,9 @@ void uart_lld_stop(UARTDriver *uartp) {
|
|||
|
||||
#if STM32_UART_USE_USART2
|
||||
if (&UARTD2 == uartp) {
|
||||
dmaStreamRelease(STM32_DMA1_STREAM6);
|
||||
dmaStreamRelease(STM32_DMA1_STREAM7);
|
||||
NVICDisableVector(USART2_IRQn);
|
||||
NVICDisableVector(DMA1_Channel6_IRQn);
|
||||
NVICDisableVector(DMA1_Channel7_IRQn);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_6);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_7);
|
||||
RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN;
|
||||
return;
|
||||
}
|
||||
|
@ -459,11 +455,9 @@ void uart_lld_stop(UARTDriver *uartp) {
|
|||
|
||||
#if STM32_UART_USE_USART3
|
||||
if (&UARTD3 == uartp) {
|
||||
dmaStreamRelease(STM32_DMA1_STREAM2);
|
||||
dmaStreamRelease(STM32_DMA1_STREAM3);
|
||||
NVICDisableVector(USART3_IRQn);
|
||||
NVICDisableVector(DMA1_Channel2_IRQn);
|
||||
NVICDisableVector(DMA1_Channel3_IRQn);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_2);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_3);
|
||||
RCC->APB1ENR &= ~RCC_APB1ENR_USART3EN;
|
||||
return;
|
||||
}
|
||||
|
@ -485,10 +479,12 @@ void uart_lld_stop(UARTDriver *uartp) {
|
|||
void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) {
|
||||
|
||||
/* TX DMA channel preparation and start.*/
|
||||
dmaSetupChannel(uartp->dmap, uartp->dmatx, n, txbuf,
|
||||
uartp->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC |
|
||||
DMA_CCR1_TEIE | DMA_CCR1_TCIE);
|
||||
dmaEnableChannel(uartp->dmap, uartp->dmatx);
|
||||
dmaStreamSetMemory0(uartp->dmatx, txbuf);
|
||||
dmaStreamSetTransactionSize(uartp->dmatx, n);
|
||||
dmaStreamSetMode(uartp->dmatx, uartp->dmamode | STM32_DMA_CR_DIR_M2P |
|
||||
STM32_DMA_CR_MINC | STM32_DMA_CR_TEIE |
|
||||
STM32_DMA_CR_TCIE);
|
||||
dmaStreamEnable(uartp->dmatx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -504,9 +500,9 @@ void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) {
|
|||
*/
|
||||
size_t uart_lld_stop_send(UARTDriver *uartp) {
|
||||
|
||||
dmaDisableChannel(uartp->dmap, uartp->dmatx);
|
||||
dmaClearChannel(uartp->dmap, uartp->dmatx);
|
||||
return (size_t)uartp->dmap->channels[uartp->dmatx].CNDTR;
|
||||
dmaStreamDisable(uartp->dmatx);
|
||||
dmaStreamClearInterrupt(uartp->dmatx);
|
||||
return dmaStreamGetTransactionSize(uartp->dmatx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -523,14 +519,16 @@ size_t uart_lld_stop_send(UARTDriver *uartp) {
|
|||
void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) {
|
||||
|
||||
/* Stopping previous activity (idle state).*/
|
||||
dmaDisableChannel(uartp->dmap, uartp->dmarx);
|
||||
dmaClearChannel(uartp->dmap, uartp->dmarx);
|
||||
dmaStreamDisable(uartp->dmarx);
|
||||
dmaStreamClearInterrupt(uartp->dmarx);
|
||||
|
||||
/* RX DMA channel preparation and start.*/
|
||||
dmaSetupChannel(uartp->dmap, uartp->dmarx, n, rxbuf,
|
||||
uartp->dmaccr | DMA_CCR1_MINC |
|
||||
DMA_CCR1_TEIE | DMA_CCR1_TCIE);
|
||||
dmaEnableChannel(uartp->dmap, uartp->dmarx);
|
||||
dmaStreamSetMemory0(uartp->dmarx, rxbuf);
|
||||
dmaStreamSetTransactionSize(uartp->dmarx, n);
|
||||
dmaStreamSetMode(uartp->dmarx, uartp->dmamode | STM32_DMA_CR_DIR_P2M |
|
||||
STM32_DMA_CR_MINC | STM32_DMA_CR_TEIE |
|
||||
STM32_DMA_CR_TCIE);
|
||||
dmaStreamEnable(uartp->dmarx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -547,9 +545,9 @@ void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) {
|
|||
size_t uart_lld_stop_receive(UARTDriver *uartp) {
|
||||
size_t n;
|
||||
|
||||
dmaDisableChannel(uartp->dmap, uartp->dmarx);
|
||||
dmaClearChannel(uartp->dmap, uartp->dmarx);
|
||||
n = (size_t)uartp->dmap->channels[uartp->dmarx].CNDTR;
|
||||
dmaStreamDisable(uartp->dmarx);
|
||||
dmaStreamClearInterrupt(uartp->dmarx);
|
||||
n = dmaStreamGetTransactionSize(uartp->dmarx);
|
||||
set_rx_idle_loop(uartp);
|
||||
return n;
|
||||
}
|
||||
|
|
|
@ -260,21 +260,17 @@ struct UARTDriver {
|
|||
*/
|
||||
USART_TypeDef *usart;
|
||||
/**
|
||||
* @brief Pointer to the DMA registers block.
|
||||
* @brief DMA mode bit mask.
|
||||
*/
|
||||
stm32_dma_t *dmap;
|
||||
/**
|
||||
* @brief DMA priority bit mask.
|
||||
*/
|
||||
uint32_t dmaccr;
|
||||
uint32_t dmamode;
|
||||
/**
|
||||
* @brief Receive DMA channel.
|
||||
*/
|
||||
uint8_t dmarx;
|
||||
const stm32_dma_stream_t *dmarx;
|
||||
/**
|
||||
* @brief Transmit DMA channel.
|
||||
*/
|
||||
uint8_t dmatx;
|
||||
const stm32_dma_stream_t *dmatx;
|
||||
/**
|
||||
* @brief Default receive buffer while into @p UART_RX_IDLE state.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,540 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file DMAv2/stm32_dma.c
|
||||
* @brief Enhanced DMA helper driver code.
|
||||
*
|
||||
* @addtogroup STM32_DMA
|
||||
* @details DMA sharing helper driver. In the STM32 the DMA streams are a
|
||||
* shared resource, this driver allows to allocate and free DMA
|
||||
* streams at runtime in order to allow all the other device
|
||||
* drivers to coordinate the access to the resource.
|
||||
* @note The DMA ISR handlers are all declared into this module because
|
||||
* sharing, the various device drivers can associate a callback to
|
||||
* IRSs when allocating streams.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
/* The following macro is only defined if some driver requiring DMA services
|
||||
has been enabled.*/
|
||||
#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Mask of the DMA1 streams in @p dma_streams_mask.
|
||||
*/
|
||||
#define STM32_DMA1_STREAMS_MASK 0x000000FF
|
||||
|
||||
/**
|
||||
* @brief Mask of the DMA2 streams in @p dma_streams_mask.
|
||||
*/
|
||||
#define STM32_DMA2_STREAMS_MASK 0x0000FF00
|
||||
|
||||
/**
|
||||
* @brief Post-reset value of the stream CR register.
|
||||
*/
|
||||
#define STM32_DMA_CR_RESET_VALUE 0x00000000
|
||||
|
||||
/**
|
||||
* @brief Post-reset value of the stream FCR register.
|
||||
*/
|
||||
#define STM32_DMA_FCR_RESET_VALUE 0x00000021
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief DMA streams descriptors.
|
||||
* @details This table keeps the association between an unique stream
|
||||
* identifier and the involved physical registers.
|
||||
* @note Don't use this array directly, use the appropriate wrapper macros
|
||||
* instead: @p STM32_DMA1_STREAM0, @p STM32_DMA1_STREAM1 etc.
|
||||
*/
|
||||
const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
|
||||
{0, DMA1, DMA1_Stream0, &DMA1->LIFCR, 0},
|
||||
{1, DMA1, DMA1_Stream1, &DMA1->LIFCR, 6},
|
||||
{2, DMA1, DMA1_Stream2, &DMA1->LIFCR, 16},
|
||||
{3, DMA1, DMA1_Stream3, &DMA1->LIFCR, 22},
|
||||
{4, DMA1, DMA1_Stream4, &DMA1->HIFCR, 0},
|
||||
{5, DMA1, DMA1_Stream5, &DMA1->HIFCR, 6},
|
||||
{6, DMA1, DMA1_Stream6, &DMA1->HIFCR, 16},
|
||||
{7, DMA1, DMA1_Stream7, &DMA1->HIFCR, 22},
|
||||
{8, DMA2, DMA2_Stream0, &DMA2->LIFCR, 0},
|
||||
{9, DMA2, DMA2_Stream1, &DMA2->LIFCR, 6},
|
||||
{10, DMA2, DMA2_Stream2, &DMA2->LIFCR, 16},
|
||||
{11, DMA2, DMA2_Stream3, &DMA2->LIFCR, 22},
|
||||
{12, DMA2, DMA2_Stream4, &DMA2->HIFCR, 0},
|
||||
{13, DMA2, DMA2_Stream5, &DMA2->HIFCR, 6},
|
||||
{14, DMA2, DMA2_Stream6, &DMA2->HIFCR, 16},
|
||||
{15, DMA2, DMA2_Stream7, &DMA2->HIFCR, 22},
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief DMA ISR redirector type.
|
||||
*/
|
||||
typedef struct {
|
||||
stm32_dmaisr_t dma_func;
|
||||
void *dma_param;
|
||||
} dma_isr_redir_t;
|
||||
|
||||
/**
|
||||
* @brief Mask of the allocated streams.
|
||||
*/
|
||||
static uint32_t dma_streams_mask;
|
||||
|
||||
/**
|
||||
* @brief DMA IRQ redirectors.
|
||||
*/
|
||||
static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS];
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief DMA1 stream 0 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Stream0_IRQHandler) {
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
flags = (DMA1->LISR >> 0) & STM32_DMA_ISR_MASK;
|
||||
DMA1->LIFCR = STM32_DMA_ISR_MASK << 0;
|
||||
if (dma_isr_redir[0].dma_func)
|
||||
dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 stream 1 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Stream1_IRQHandler) {
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
flags = (DMA1->LISR >> 6) & STM32_DMA_ISR_MASK;
|
||||
DMA1->LIFCR = STM32_DMA_ISR_MASK << 6;
|
||||
if (dma_isr_redir[1].dma_func)
|
||||
dma_isr_redir[1].dma_func(dma_isr_redir[0].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 stream 2 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Stream2_IRQHandler) {
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
flags = (DMA1->LISR >> 16) & STM32_DMA_ISR_MASK;
|
||||
DMA1->LIFCR = STM32_DMA_ISR_MASK << 16;
|
||||
if (dma_isr_redir[2].dma_func)
|
||||
dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 stream 3 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Stream3_IRQHandler) {
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
flags = (DMA1->LISR >> 22) & STM32_DMA_ISR_MASK;
|
||||
DMA1->LIFCR = STM32_DMA_ISR_MASK << 22;
|
||||
if (dma_isr_redir[3].dma_func)
|
||||
dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 stream 4 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Stream4_IRQHandler) {
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
flags = (DMA1->HISR >> 0) & STM32_DMA_ISR_MASK;
|
||||
DMA1->HIFCR = STM32_DMA_ISR_MASK << 0;
|
||||
if (dma_isr_redir[4].dma_func)
|
||||
dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 stream 5 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Stream5_IRQHandler) {
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
flags = (DMA1->HISR >> 6) & STM32_DMA_ISR_MASK;
|
||||
DMA1->HIFCR = STM32_DMA_ISR_MASK << 6;
|
||||
if (dma_isr_redir[5].dma_func)
|
||||
dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 stream 6 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Stream6_IRQHandler) {
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
flags = (DMA1->HISR >> 16) & STM32_DMA_ISR_MASK;
|
||||
DMA1->HIFCR = STM32_DMA_ISR_MASK << 16;
|
||||
if (dma_isr_redir[6].dma_func)
|
||||
dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 stream 7 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Stream7_IRQHandler) {
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
flags = (DMA1->HISR >> 22) & STM32_DMA_ISR_MASK;
|
||||
DMA1->HIFCR = STM32_DMA_ISR_MASK << 22;
|
||||
if (dma_isr_redir[7].dma_func)
|
||||
dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA2 stream 0 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Stream0_IRQHandler) {
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
flags = (DMA2->LISR >> 0) & STM32_DMA_ISR_MASK;
|
||||
DMA2->LIFCR = STM32_DMA_ISR_MASK << 0;
|
||||
if (dma_isr_redir[8].dma_func)
|
||||
dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA2 stream 1 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Stream1_IRQHandler) {
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
flags = (DMA2->LISR >> 6) & STM32_DMA_ISR_MASK;
|
||||
DMA2->LIFCR = STM32_DMA_ISR_MASK << 6;
|
||||
if (dma_isr_redir[9].dma_func)
|
||||
dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA2 stream 2 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Stream2_IRQHandler) {
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
flags = (DMA2->LISR >> 16) & STM32_DMA_ISR_MASK;
|
||||
DMA2->LIFCR = STM32_DMA_ISR_MASK << 16;
|
||||
if (dma_isr_redir[10].dma_func)
|
||||
dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA2 stream 3 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Stream3_IRQHandler) {
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
flags = (DMA2->LISR >> 22) & STM32_DMA_ISR_MASK;
|
||||
DMA2->LIFCR = STM32_DMA_ISR_MASK << 22;
|
||||
if (dma_isr_redir[11].dma_func)
|
||||
dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA2 stream 4 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Stream4_IRQHandler) {
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
flags = (DMA2->HISR >> 0) & STM32_DMA_ISR_MASK;
|
||||
DMA2->HIFCR = STM32_DMA_ISR_MASK << 0;
|
||||
if (dma_isr_redir[12].dma_func)
|
||||
dma_isr_redir[12].dma_func(dma_isr_redir[12].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA2 stream 5 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Stream5_IRQHandler) {
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
flags = (DMA2->HISR >> 6) & STM32_DMA_ISR_MASK;
|
||||
DMA2->HIFCR = STM32_DMA_ISR_MASK << 6;
|
||||
if (dma_isr_redir[13].dma_func)
|
||||
dma_isr_redir[13].dma_func(dma_isr_redir[13].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA2 stream 6 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Stream6_IRQHandler) {
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
flags = (DMA2->HISR >> 16) & STM32_DMA_ISR_MASK;
|
||||
DMA2->HIFCR = STM32_DMA_ISR_MASK << 16;
|
||||
if (dma_isr_redir[14].dma_func)
|
||||
dma_isr_redir[14].dma_func(dma_isr_redir[14].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA2 stream 7 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Stream7_IRQHandler) {
|
||||
uint32_t flags;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
flags = (DMA2->HISR >> 22) & STM32_DMA_ISR_MASK;
|
||||
DMA2->HIFCR = STM32_DMA_ISR_MASK << 22;
|
||||
if (dma_isr_redir[15].dma_func)
|
||||
dma_isr_redir[15].dma_func(dma_isr_redir[15].dma_param, flags);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief STM32 DMA helper initialization.
|
||||
*
|
||||
* @init
|
||||
*/
|
||||
void dmaInit(void) {
|
||||
int i;
|
||||
|
||||
dma_streams_mask = 0;
|
||||
for (i = 0; i < STM32_DMA_STREAMS; i++) {
|
||||
_stm32_dma_streams[i].stream->CR = 0;
|
||||
dma_isr_redir[i].dma_func = NULL;
|
||||
}
|
||||
DMA1->LIFCR = 0xFFFFFFFF;
|
||||
DMA1->HIFCR = 0xFFFFFFFF;
|
||||
DMA2->LIFCR = 0xFFFFFFFF;
|
||||
DMA2->HIFCR = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocates a DMA stream.
|
||||
* @details The stream is allocated and, if required, the DMA clock enabled.
|
||||
* The function also enables the IRQ vector associated to the stream
|
||||
* and initializes its priority.
|
||||
* @pre The stream must not be already in use or an error is returned.
|
||||
* @post The stream is allocated and the default ISR handler redirected
|
||||
* to the specified function.
|
||||
* @post The stream ISR vector is enabled and its priority configured.
|
||||
* @post The stream must be freed using @p dmaStreamRelease() before it can
|
||||
* be reused with another peripheral.
|
||||
* @post The stream is in its post-reset state.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] func handling function pointer, can be @p NULL
|
||||
* @param[in] param a parameter to be passed to the handling function
|
||||
* @return The operation status.
|
||||
* @retval FALSE no error, stream taken.
|
||||
* @retval TRUE error, stream already taken.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
|
||||
uint32_t priority,
|
||||
stm32_dmaisr_t func,
|
||||
void *param) {
|
||||
|
||||
chDbgCheck(dmastp != NULL, "dmaAllocate");
|
||||
|
||||
/* Checks if the stream is already taken.*/
|
||||
if ((dma_streams_mask & dmastp->mask) != 0)
|
||||
return TRUE;
|
||||
|
||||
/* Marks the stream as allocated.*/
|
||||
dma_isr_redir[dmastp->selfindex].dma_func = func;
|
||||
dma_isr_redir[dmastp->selfindex].dma_param = param;
|
||||
dma_streams_mask |= (1 << dmastp->selfindex);
|
||||
|
||||
/* Enabling DMA clocks required by the current streams set.*/
|
||||
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) {
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
|
||||
RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA1LPEN;
|
||||
}
|
||||
if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) {
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
|
||||
RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA2LPEN;
|
||||
}
|
||||
|
||||
/* Putting the stream in a safe state.*/
|
||||
dmaStreamDisable(dmastp);
|
||||
dmaStreamClearInterrupt(dmastp);
|
||||
dmastp->channel->CR = STM32_DMA_CR_RESET_VALUE;
|
||||
dmastp->channel->FCR = STM32_DMA_FCR_RESET_VALUE;
|
||||
|
||||
/* Enables the associated IRQ vector if a callback is defined.*/
|
||||
if (func != NULL)
|
||||
NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Releases a DMA stream.
|
||||
* @details The stream is freed and, if required, the DMA clock disabled.
|
||||
* Trying to release a unallocated stream is an illegal operation
|
||||
* and is trapped if assertions are enabled.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAllocate().
|
||||
* @post The stream is again available.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {
|
||||
|
||||
chDbgCheck(dmastp != NULL, "dmaRelease");
|
||||
|
||||
/* Check if the streams is not taken.*/
|
||||
chDbgAssert((dma_streams_mask & dmastp->mask) != 0,
|
||||
"dmaRelease(), #1", "not allocated");
|
||||
|
||||
/* Disables the associated IRQ vector.*/
|
||||
NVICDisableVector(dmastp->vector);
|
||||
|
||||
/* Marks the stream as not allocated.*/
|
||||
dma_streams_mask &= ~(1 << dmastp->selfindex);
|
||||
|
||||
/* Shutting down clocks that are no more required, if any.*/
|
||||
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) {
|
||||
RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA1EN;
|
||||
RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA1LPEN;
|
||||
}
|
||||
if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) {
|
||||
RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA2EN;
|
||||
RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA2LPEN;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* STM32_DMA_REQUIRED */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,327 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file DMAv2/stm32_dma.h
|
||||
* @brief Enhanced-DMA helper driver header.
|
||||
* @note This file requires definitions from the ST STM32F2xx header file
|
||||
* stm32f2xx.h.
|
||||
*
|
||||
* @addtogroup STM32_DMA
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _STM32_DMA_H_
|
||||
#define _STM32_DMA_H_
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Total number of DMA streams.
|
||||
* @note This is the total number of streams among all the DMA units.
|
||||
*/
|
||||
#define STM32_DMA_STREAMS 16
|
||||
|
||||
/**
|
||||
* @brief Mask of the ISR bits passed to the DMA callback functions.
|
||||
*/
|
||||
#define STM32_DMA_ISR_MASK 0x3D
|
||||
|
||||
/**
|
||||
* @name DMA streams identifiers
|
||||
* @{
|
||||
*/
|
||||
#define STM32_DMA1_STREAM0 (&_stm32_dma_streams[0])
|
||||
#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[1])
|
||||
#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[2])
|
||||
#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[3])
|
||||
#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[4])
|
||||
#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[5])
|
||||
#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[6])
|
||||
#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[7])
|
||||
#define STM32_DMA2_STREAM0 (&_stm32_dma_streams[8])
|
||||
#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[9])
|
||||
#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[10])
|
||||
#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[11])
|
||||
#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[12])
|
||||
#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[13])
|
||||
#define STM32_DMA2_STREAM6 (&_stm32_dma_streams[14])
|
||||
#define STM32_DMA2_STREAM7 (&_stm32_dma_streams[15])
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name CR register constants common to all DMA types
|
||||
*/
|
||||
#define STM32_DMA_CR_EN DMA_SxCR_EN
|
||||
#define STM32_DMA_CR_TEIE DMA_SxCR_TEIE
|
||||
#define STM32_DMA_CR_HTIE DMA_SxCR_HTIE
|
||||
#define STM32_DMA_CR_TCIE DMA_SxCR_TCIE
|
||||
#define STM32_DMA_CR_DIR_MASK DMA_SxCR_DIR
|
||||
#define STM32_DMA_CR_DIR_P2M 0
|
||||
#define STM32_DMA_CR_DIR_M2P DMA_SxCR_DIR_0
|
||||
#define STM32_DMA_CR_DIR_M2M DMA_SxCR_DIR_1
|
||||
#define STM32_DMA_CR_CIRC DMA_SxCR_CIRC
|
||||
#define STM32_DMA_CR_PINC DMA_SxCR_PINC
|
||||
#define STM32_DMA_CR_MINC DMA_SxCR_MINC
|
||||
#define STM32_DMA_CR_PSIZE_MASK DMA_SxCR_PSIZE
|
||||
#define STM32_DMA_CR_PSIZE_BYTE 0
|
||||
#define STM32_DMA_CR_PSIZE_HWORD DMA_SxCR_PSIZE_0
|
||||
#define STM32_DMA_CR_PSIZE_WORD DMA_SxCR_PSIZE_1
|
||||
#define STM32_DMA_CR_MSIZE_MASK DMA_SxCR_MSIZE
|
||||
#define STM32_DMA_CR_MSIZE_BYTE 0
|
||||
#define STM32_DMA_CR_MSIZE_HWORD DMA_SxCR_MSIZE_0
|
||||
#define STM32_DMA_CR_MSIZE_WORD DMA_SxCR_MSIZE_1
|
||||
#define STM32_DMA_CR_PL_MASK DMA_SxCR_PL
|
||||
#define STM32_DMA_CR_PL(n) ((n) << 16)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name CR register constants only found in STM32F2xx
|
||||
*/
|
||||
#define STM32_DMA_CR_DMEIE DMA_SxCR_DMEIE
|
||||
#define STM32_DMA_CR_PFCTRL DMA_SxCR_PFCTRL
|
||||
#define STM32_DMA_CR_PINCOS DMA_SxCR_PINCOS
|
||||
#define STM32_DMA_CR_DBM DMA_SxCR_DBM
|
||||
#define STM32_DMA_CR_CT DMA_SxCR_CT
|
||||
#define STM32_DMA_CR_PBURST_MASK DMA_SxCR_PBURST
|
||||
#define STM32_DMA_CR_PBURST_SINGLE 0
|
||||
#define STM32_DMA_CR_PBURST_INCR4 DMA_SxCR_PBURST_0
|
||||
#define STM32_DMA_CR_PBURST_INCR8 DMA_SxCR_PBURST_1
|
||||
#define STM32_DMA_CR_PBURST_INCR16 (DMA_SxCR_PBURST_0 | DMA_SxCR_PBURST_1)
|
||||
#define STM32_DMA_CR_MBURST_MASK DMA_SxCR_MBURST
|
||||
#define STM32_DMA_CR_MBURST_SINGLE 0
|
||||
#define STM32_DMA_CR_MBURST_INCR4 DMA_SxCR_MBURST_0
|
||||
#define STM32_DMA_CR_MBURST_INCR8 DMA_SxCR_MBURST_1
|
||||
#define STM32_DMA_CR_MBURST_INCR16 (DMA_SxCR_MBURST_0 | DMA_SxCR_MBURST_1)
|
||||
#define STM32_DMA_CR_CHSEL_MASK DMA_SxCR_CHSEL
|
||||
#define STM32_DMA_CR_CHSEL(n) ((n) << 25)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name FCR register constants only found in STM32F2xx
|
||||
*/
|
||||
#define STM32_DMA_FCR_FEIE DMA_SxFCR_FEIE
|
||||
#define STM32_DMA_FCR_FS_MASK DMA_SxFCR_FS
|
||||
#define STM32_DMA_FCR_DMDIS DMA_SxFCR_DMDIS
|
||||
#define STM32_DMA_FCR_FTH_MASK DMA_SxFCR_FTH
|
||||
#define STM32_DMA_FCR_FTH_1Q 0
|
||||
#define STM32_DMA_FCR_FTH_HALF DMA_SxFCR_FTH_0
|
||||
#define STM32_DMA_FCR_FTH_3Q DMA_SxFCR_FTH_1
|
||||
#define STM32_DMA_FCR_FTH_FULL (DMA_SxFCR_FTH_0 | DMA_SxFCR_FTH_1)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Status flags passed to the ISR callbacks
|
||||
*/
|
||||
#define STM32_DMA_ISR_FEIF DMA_LISR_FEIF0
|
||||
#define STM32_DMA_ISR_DMEIF DMA_LISR_DMEIF0
|
||||
#define STM32_DMA_ISR_TEIF DMA_LISR_TEIF0
|
||||
#define STM32_DMA_ISR_HTIF DMA_LISR_HTIF0
|
||||
#define STM32_DMA_ISR_TCIF DMA_LISR_TCIF0
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief STM32 DMA stream descriptor structure.
|
||||
*/
|
||||
typedef struct {
|
||||
DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */
|
||||
volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */
|
||||
uint8_t ishift; /**< @brief Bits offset in xIFCR
|
||||
register. */
|
||||
uint8_t selfindex; /**< @brief Index to self in array. */
|
||||
uint8_t vector; /**< @brief Associated IRQ vector. */
|
||||
} stm32_dma_stream_t;
|
||||
|
||||
/**
|
||||
* @brief STM32 DMA ISR function type.
|
||||
*
|
||||
* @param[in] p parameter for the registered function
|
||||
* @param[in] flags pre-shifted content of the xISR register, the bits
|
||||
* are aligned to bit zero
|
||||
*/
|
||||
typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Associates a peripheral data register to a DMA stream.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] addr value to be written in the PAR register
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamSetPeripheral(dmastp, addr) { \
|
||||
(dmastp)->stream->PAR = (uint32_t)(addr); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Associates a memory destination to a DMA stream.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] addr value to be written in the M0AR register
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamSetMemory0(dmastp, addr) { \
|
||||
(dmastp)->stream->M0AR = (uint32_t)(addr); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Associates an alternate memory destination to a DMA stream.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] addr value to be written in the M1AR register
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamSetMemory1(dmastp, addr) { \
|
||||
(dmastp)->stream->M1AR = (uint32_t)(addr); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the number of transfers to be performed.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] size value to be written in the CNDTR register
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamSetTransactionSize(dmastp, size) { \
|
||||
(dmastp)->stream->NDTR = (uint32_t)(size); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the number of transfers to be performed.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @return The number of transfers to be performed.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->stream->NDTR))
|
||||
|
||||
/**
|
||||
* @brief Programs the stream mode settings.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] mode value to be written in the CR register
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamSetMode(dmastp, mode) { \
|
||||
(dmastp)->stream->CR = (uint32_t)(mode); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Programs the stream FIFO settings.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] mode value to be written in the FCR register
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamSetFIFO(dmastp, mode) { \
|
||||
(dmastp)->stream->FCR = (uint32_t)(mode); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA stream enable.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmachp pointer to a stm32_dma_stream_t structure
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamEnable(dmachp) { \
|
||||
(dmastp)->stream->CR |= STM32_DMA_CR_EN; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA stream disable.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamDisable(dmastp) { \
|
||||
(dmastp)->stream->CR &= ~STM32_DMA_CR_EN; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA stream interrupt sources clear.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamClearInterrupt(dmastp) { \
|
||||
*(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS];
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void dmaInit(void);
|
||||
bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
|
||||
uint32_t priority,
|
||||
stm32_dmaisr_t func,
|
||||
void *param);
|
||||
void dmaStreamRelease(const stm32_dma_stream_t *dmastp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _STM32_DMA_H_ */
|
||||
|
||||
/** @} */
|
|
@ -19,8 +19,8 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file STM32/pal_lld.c
|
||||
* @brief STM32 GPIO low level driver code.
|
||||
* @file STM32/GPIOv1/pal_lld.c
|
||||
* @brief STM32F1xx GPIO low level driver code.
|
||||
*
|
||||
* @addtogroup PAL
|
||||
* @{
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file STM32/pal_lld.h
|
||||
* @brief STM32 GPIO low level driver header.
|
||||
* @file STM32/GPIOv1/pal_lld.h
|
||||
* @brief STM32F1xx GPIO low level driver header.
|
||||
*
|
||||
* @addtogroup PAL
|
||||
* @{
|
||||
|
|
|
@ -105,7 +105,7 @@ static uint32_t pm_alloc(USBDriver *usbp, size_t size) {
|
|||
|
||||
next = usbp->pmnext;
|
||||
usbp->pmnext += size;
|
||||
chDbgAssert(usbp->pmnext > USB_PMA_SIZE, "pm_alloc(), #1", "PMA overflow");
|
||||
chDbgAssert(usbp->pmnext <= USB_PMA_SIZE, "pm_alloc(), #1", "PMA overflow");
|
||||
return next;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,17 +58,17 @@ static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
|
|||
|
||||
/* DMA errors handling.*/
|
||||
#if defined(STM32_ADC_DMA_ERROR_HOOK)
|
||||
if ((flags & DMA_ISR_TEIF1) != 0) {
|
||||
if ((flags & STM32_DMA_ISR_TEIF) != 0) {
|
||||
STM32_ADC_DMA_ERROR_HOOK(spip);
|
||||
}
|
||||
#else
|
||||
(void)flags;
|
||||
#endif
|
||||
if ((flags & DMA_ISR_HTIF1) != 0) {
|
||||
if ((flags & STM32_DMA_ISR_HTIF) != 0) {
|
||||
/* Half transfer processing.*/
|
||||
_adc_isr_half_code(adcp);
|
||||
}
|
||||
if ((flags & DMA_ISR_TCIF1) != 0) {
|
||||
if ((flags & STM32_DMA_ISR_TCIF) != 0) {
|
||||
/* Transfer complete processing.*/
|
||||
_adc_isr_full_code(adcp);
|
||||
}
|
||||
|
@ -93,10 +93,11 @@ void adc_lld_init(void) {
|
|||
/* Driver initialization.*/
|
||||
adcObjectInit(&ADCD1);
|
||||
ADCD1.adc = ADC1;
|
||||
ADCD1.dmachp = STM32_DMA1_CH1;
|
||||
ADCD1.dmaccr = (STM32_ADC_ADC1_DMA_PRIORITY << 12) |
|
||||
DMA_CCR1_EN | DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0 |
|
||||
DMA_CCR1_MINC | DMA_CCR1_TCIE | DMA_CCR1_TEIE;
|
||||
ADCD1.dmastp = STM32_DMA1_STREAM1;
|
||||
ADCD1.dmamode = STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) |
|
||||
STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
|
||||
STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
|
||||
STM32_DMA_CR_TEIE | STM32_DMA_CR_EN;
|
||||
|
||||
/* Temporary activation.*/
|
||||
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
|
||||
|
@ -132,11 +133,13 @@ void adc_lld_start(ADCDriver *adcp) {
|
|||
if (adcp->state == ADC_STOP) {
|
||||
#if STM32_ADC_USE_ADC1
|
||||
if (&ADCD1 == adcp) {
|
||||
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_1,
|
||||
(stm32_dmaisr_t)adc_lld_serve_rx_interrupt, (void *)adcp);
|
||||
NVICEnableVector(DMA1_Channel1_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_ADC_ADC1_IRQ_PRIORITY));
|
||||
dmaChannelSetPeripheral(adcp->dmachp, &ADC1->DR);
|
||||
bool_t b;
|
||||
b = dmaStreamAllocate(adcp->dmastp,
|
||||
STM32_ADC_ADC1_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
|
||||
(void *)adcp);
|
||||
chDbgAssert(!b, "adc_lld_start(), #1", "stream already allocated");
|
||||
dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR);
|
||||
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
|
||||
}
|
||||
#endif
|
||||
|
@ -163,8 +166,7 @@ void adc_lld_stop(ADCDriver *adcp) {
|
|||
if (&ADCD1 == adcp) {
|
||||
ADC1->CR1 = 0;
|
||||
ADC1->CR2 = 0;
|
||||
NVICDisableVector(DMA1_Channel1_IRQn);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_1);
|
||||
dmaStreamRelease(adcp->dmastp);
|
||||
RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN;
|
||||
}
|
||||
#endif
|
||||
|
@ -179,27 +181,28 @@ void adc_lld_stop(ADCDriver *adcp) {
|
|||
* @notapi
|
||||
*/
|
||||
void adc_lld_start_conversion(ADCDriver *adcp) {
|
||||
uint32_t ccr, n;
|
||||
uint32_t mode, n;
|
||||
const ADCConversionGroup *grpp = adcp->grpp;
|
||||
|
||||
/* DMA setup.*/
|
||||
ccr = adcp->dmaccr;
|
||||
mode = adcp->dmamode;
|
||||
if (grpp->circular)
|
||||
ccr |= DMA_CCR1_CIRC;
|
||||
mode |= STM32_DMA_CR_CIRC;
|
||||
if (adcp->depth > 1) {
|
||||
/* If the buffer depth is greater than one then the half transfer interrupt
|
||||
interrupt is enabled in order to allows streaming processing.*/
|
||||
ccr |= DMA_CCR1_HTIE;
|
||||
mode |= STM32_DMA_CR_HTIE;
|
||||
n = (uint32_t)grpp->num_channels * (uint32_t)adcp->depth;
|
||||
}
|
||||
else
|
||||
n = (uint32_t)grpp->num_channels;
|
||||
dmaChannelSetup(adcp->dmachp, n, adcp->samples, ccr);
|
||||
dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
|
||||
dmaStreamSetTransactionSize(adcp->dmastp, n);
|
||||
dmaStreamSetMode(adcp->dmastp, mode);
|
||||
|
||||
/* ADC setup.*/
|
||||
adcp->adc->CR1 = grpp->cr1 | ADC_CR1_SCAN;
|
||||
adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA |
|
||||
ADC_CR2_CONT | ADC_CR2_ADON;
|
||||
adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON;
|
||||
adcp->adc->SMPR1 = grpp->smpr1;
|
||||
adcp->adc->SMPR2 = grpp->smpr2;
|
||||
adcp->adc->SQR1 = grpp->sqr1;
|
||||
|
@ -207,8 +210,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) {
|
|||
adcp->adc->SQR3 = grpp->sqr3;
|
||||
|
||||
/* ADC start by writing ADC_CR2_ADON a second time.*/
|
||||
adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA |
|
||||
ADC_CR2_CONT | ADC_CR2_ADON;
|
||||
adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -220,7 +222,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) {
|
|||
*/
|
||||
void adc_lld_stop_conversion(ADCDriver *adcp) {
|
||||
|
||||
dmaChannelDisable(adcp->dmachp);
|
||||
dmaStreamDisable(adcp->dmastp);
|
||||
adcp->adc->CR2 = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -268,13 +268,13 @@ struct ADCDriver {
|
|||
*/
|
||||
ADC_TypeDef *adc;
|
||||
/**
|
||||
* @brief Pointer to the DMA registers block.
|
||||
* @brief Pointer to associated SMA channel.
|
||||
*/
|
||||
stm32_dma_channel_t *dmachp;
|
||||
const stm32_dma_stream_t *dmastp;
|
||||
/**
|
||||
* @brief DMA CCR register bit mask.
|
||||
* @brief DMA mode bit mask.
|
||||
*/
|
||||
uint32_t dmaccr;
|
||||
uint32_t dmamode;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_ADC || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
@ -176,13 +180,14 @@ void adcStartConversionI(ADCDriver *adcp,
|
|||
adcsample_t *samples,
|
||||
size_t depth) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck((adcp != NULL) && (grpp != NULL) && (samples != NULL) &&
|
||||
((depth == 1) || ((depth & 1) == 0)),
|
||||
"adcStartConversionI");
|
||||
|
||||
chDbgAssert((adcp->state == ADC_READY) ||
|
||||
(adcp->state == ADC_COMPLETE),
|
||||
"adcStartConversionI(), #1", "not ready");
|
||||
|
||||
adcp->samples = samples;
|
||||
adcp->depth = depth;
|
||||
adcp->grpp = grpp;
|
||||
|
@ -229,12 +234,13 @@ void adcStopConversion(ADCDriver *adcp) {
|
|||
*/
|
||||
void adcStopConversionI(ADCDriver *adcp) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(adcp != NULL, "adcStopConversionI");
|
||||
|
||||
chDbgAssert((adcp->state == ADC_READY) ||
|
||||
(adcp->state == ADC_ACTIVE) ||
|
||||
(adcp->state == ADC_COMPLETE),
|
||||
"adcStopConversionI(), #1", "invalid state");
|
||||
|
||||
if (adcp->state != ADC_READY) {
|
||||
adc_lld_stop_conversion(adcp);
|
||||
adcp->grpp = NULL;
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_CAN || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_GPT || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
@ -137,8 +141,11 @@ void gptStartContinuous(GPTDriver *gptp, gptcnt_t interval) {
|
|||
*/
|
||||
void gptStartContinuousI(GPTDriver *gptp, gptcnt_t interval) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(gptp != NULL, "gptStartContinuousI");
|
||||
chDbgAssert(gptp->state == GPT_READY,
|
||||
"gptStartContinuousI(), #1", "invalid state");
|
||||
|
||||
gptp->state = GPT_CONTINUOUS;
|
||||
gpt_lld_start_timer(gptp, interval);
|
||||
}
|
||||
|
@ -168,8 +175,11 @@ void gptStartOneShot(GPTDriver *gptp, gptcnt_t interval) {
|
|||
*/
|
||||
void gptStartOneShotI(GPTDriver *gptp, gptcnt_t interval) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(gptp != NULL, "gptStartOneShotI");
|
||||
chDbgAssert(gptp->state == GPT_READY,
|
||||
"gptStartOneShotI(), #1", "invalid state");
|
||||
|
||||
gptp->state = GPT_ONESHOT;
|
||||
gpt_lld_start_timer(gptp, interval);
|
||||
}
|
||||
|
@ -197,9 +207,12 @@ void gptStopTimer(GPTDriver *gptp) {
|
|||
*/
|
||||
void gptStopTimerI(GPTDriver *gptp) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(gptp != NULL, "gptStopTimerI");
|
||||
chDbgAssert((gptp->state == GPT_READY) || (gptp->state == GPT_CONTINUOUS) ||
|
||||
(gptp->state == GPT_ONESHOT),
|
||||
"gptStopTimerI(), #1", "invalid state");
|
||||
|
||||
gptp->state = GPT_READY;
|
||||
gpt_lld_stop_timer(gptp);
|
||||
}
|
||||
|
@ -220,6 +233,7 @@ void gptPolledDelay(GPTDriver *gptp, gptcnt_t interval) {
|
|||
|
||||
chDbgAssert(gptp->state == GPT_READY,
|
||||
"gptPolledDelay(), #1", "invalid state");
|
||||
|
||||
gptp->state = GPT_ONESHOT;
|
||||
gpt_lld_polled_delay(gptp, interval);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_I2C || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_ICU || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
@ -121,6 +125,8 @@ void icuStop(ICUDriver *icup) {
|
|||
*/
|
||||
void icuEnable(ICUDriver *icup) {
|
||||
|
||||
chDbgCheck(icup != NULL, "icuEnable");
|
||||
|
||||
chSysLock();
|
||||
chDbgAssert(icup->state == ICU_READY, "icuEnable(), #1", "invalid state");
|
||||
icu_lld_enable(icup);
|
||||
|
@ -137,6 +143,8 @@ void icuEnable(ICUDriver *icup) {
|
|||
*/
|
||||
void icuDisable(ICUDriver *icup) {
|
||||
|
||||
chDbgCheck(icup != NULL, "icuDisable");
|
||||
|
||||
chSysLock();
|
||||
chDbgAssert((icup->state == ICU_READY) || (icup->state == ICU_WAITING) ||
|
||||
(icup->state == ICU_ACTIVE) || (icup->state == ICU_IDLE),
|
||||
|
|
|
@ -33,6 +33,10 @@
|
|||
|
||||
#if HAL_USE_MAC || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_MMC_SPI || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_PWM || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_SDC || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
@ -54,7 +58,7 @@
|
|||
*
|
||||
* @notapi
|
||||
*/
|
||||
bool_t sdc_wait_for_transfer_state(SDCDriver *sdcp) {
|
||||
bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp) {
|
||||
uint32_t resp[1];
|
||||
|
||||
while (TRUE) {
|
||||
|
@ -314,7 +318,7 @@ bool_t sdcDisconnect(SDCDriver *sdcp) {
|
|||
chSysUnlock();
|
||||
|
||||
/* Waits for eventual pending operations completion.*/
|
||||
if (sdc_wait_for_transfer_state(sdcp))
|
||||
if (_sdc_wait_for_transfer_state(sdcp))
|
||||
return TRUE;
|
||||
|
||||
/* Card clock stopped.*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
@ -207,6 +211,7 @@ void sdStop(SerialDriver *sdp) {
|
|||
*/
|
||||
void sdIncomingDataI(SerialDriver *sdp, uint8_t b) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(sdp != NULL, "sdIncomingDataI");
|
||||
|
||||
if (chIQIsEmptyI(&sdp->iqueue))
|
||||
|
@ -233,6 +238,7 @@ void sdIncomingDataI(SerialDriver *sdp, uint8_t b) {
|
|||
msg_t sdRequestDataI(SerialDriver *sdp) {
|
||||
msg_t b;
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(sdp != NULL, "sdRequestDataI");
|
||||
|
||||
b = chOQGetI(&sdp->oqueue);
|
||||
|
|
|
@ -33,6 +33,10 @@
|
|||
|
||||
#if HAL_USE_SERIAL_USB || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
@ -120,7 +124,7 @@ static void inotify(GenericQueue *qp) {
|
|||
emptied, then a whole packet is loaded in the queue.*/
|
||||
if (chIQIsEmptyI(&sdup->iqueue)) {
|
||||
|
||||
n = usbReadPacketI(sdup->config->usbp, DATA_AVAILABLE_EP,
|
||||
n = usbReadPacketI(sdup->config->usbp, USB_CDC_DATA_AVAILABLE_EP,
|
||||
sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE);
|
||||
if (n != USB_ENDPOINT_BUSY) {
|
||||
chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE);
|
||||
|
@ -142,7 +146,7 @@ static void onotify(GenericQueue *qp) {
|
|||
/* If there is any data in the output queue then it is sent within a
|
||||
single packet and the queue is emptied.*/
|
||||
n = chOQGetFullI(&sdup->oqueue);
|
||||
w = usbWritePacketI(sdup->config->usbp, DATA_REQUEST_EP,
|
||||
w = usbWritePacketI(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP,
|
||||
sdup->oqueue.q_buffer, n);
|
||||
if (w != USB_ENDPOINT_BUSY) {
|
||||
chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY);
|
||||
|
@ -207,10 +211,10 @@ void sduStart(SerialUSBDriver *sdup, const SerialUSBConfig *config) {
|
|||
"sduStart(), #1",
|
||||
"invalid state");
|
||||
sdup->config = config;
|
||||
usbStart(config->usbp, &config->usb_config);
|
||||
config->usbp->param = sdup;
|
||||
sdup->state = SDU_READY;
|
||||
chSysUnlock();
|
||||
usbStart(config->usbp, &config->usb_config);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -230,9 +234,9 @@ void sduStop(SerialUSBDriver *sdup) {
|
|||
chDbgAssert((sdup->state == SDU_STOP) || (sdup->state == SDU_READY),
|
||||
"sduStop(), #1",
|
||||
"invalid state");
|
||||
usbStop(sdup->config->usbp);
|
||||
sdup->state = SDU_STOP;
|
||||
chSysUnlock();
|
||||
usbStop(sdup->config->usbp);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_SPI || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_UART || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
@ -161,12 +165,13 @@ void uartStartSend(UARTDriver *uartp, size_t n, const void *txbuf) {
|
|||
*/
|
||||
void uartStartSendI(UARTDriver *uartp, size_t n, const void *txbuf) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck((uartp != NULL) && (n > 0) && (txbuf != NULL),
|
||||
"uartStartSendI");
|
||||
|
||||
chDbgAssert((uartp->state == UART_READY) &&
|
||||
(uartp->txstate != UART_TX_ACTIVE),
|
||||
"uartStartSendI(), #1", "not active");
|
||||
|
||||
uart_lld_start_send(uartp, n, txbuf);
|
||||
uartp->txstate = UART_TX_ACTIVE;
|
||||
}
|
||||
|
@ -216,8 +221,8 @@ size_t uartStopSend(UARTDriver *uartp) {
|
|||
*/
|
||||
size_t uartStopSendI(UARTDriver *uartp) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(uartp != NULL, "uartStopSendI");
|
||||
|
||||
chDbgAssert(uartp->state == UART_READY, "uartStopSendI(), #1", "not active");
|
||||
|
||||
if (uartp->txstate == UART_TX_ACTIVE) {
|
||||
|
@ -267,9 +272,9 @@ void uartStartReceive(UARTDriver *uartp, size_t n, void *rxbuf) {
|
|||
*/
|
||||
void uartStartReceiveI(UARTDriver *uartp, size_t n, void *rxbuf) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck((uartp != NULL) && (n > 0) && (rxbuf != NULL),
|
||||
"uartStartReceiveI");
|
||||
|
||||
chDbgAssert((uartp->state == UART_READY) && (uartp->rxstate == UART_RX_IDLE),
|
||||
"uartStartReceiveI(), #1", "not active");
|
||||
|
||||
|
@ -322,8 +327,9 @@ size_t uartStopReceive(UARTDriver *uartp) {
|
|||
* @iclass
|
||||
*/
|
||||
size_t uartStopReceiveI(UARTDriver *uartp) {
|
||||
chDbgCheck(uartp != NULL, "uartStopReceiveI");
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(uartp != NULL, "uartStopReceiveI");
|
||||
chDbgAssert(uartp->state == UART_READY,
|
||||
"uartStopReceiveI(), #1", "not active");
|
||||
|
||||
|
|
|
@ -34,6 +34,10 @@
|
|||
|
||||
#if HAL_USE_USB || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
@ -301,6 +305,8 @@ void usbStop(USBDriver *usbp) {
|
|||
void usbInitEndpointI(USBDriver *usbp, usbep_t ep,
|
||||
const USBEndpointConfig *epcp) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck((usbp != NULL) && (epcp != NULL), "usbInitEndpointI");
|
||||
chDbgAssert(usbp->state == USB_ACTIVE,
|
||||
"usbEnableEndpointI(), #1", "invalid state");
|
||||
chDbgAssert(usbp->epc[ep] != NULL,
|
||||
|
@ -331,6 +337,8 @@ void usbInitEndpointI(USBDriver *usbp, usbep_t ep,
|
|||
void usbDisableEndpointsI(USBDriver *usbp) {
|
||||
unsigned i;
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(usbp != NULL, "usbDisableEndpointsI");
|
||||
chDbgAssert(usbp->state == USB_SELECTED,
|
||||
"usbDisableEndpointsI(), #1", "invalid state");
|
||||
|
||||
|
@ -364,6 +372,9 @@ void usbDisableEndpointsI(USBDriver *usbp) {
|
|||
size_t usbReadPacketI(USBDriver *usbp, usbep_t ep,
|
||||
uint8_t *buf, size_t n) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck((usbp != NULL) && (buf != NULL), "usbReadPacketI");
|
||||
|
||||
if (usbGetReceiveStatusI(usbp, ep))
|
||||
return USB_ENDPOINT_BUSY;
|
||||
|
||||
|
@ -391,6 +402,9 @@ size_t usbReadPacketI(USBDriver *usbp, usbep_t ep,
|
|||
size_t usbWritePacketI(USBDriver *usbp, usbep_t ep,
|
||||
const uint8_t *buf, size_t n) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck((usbp != NULL) && (buf != NULL), "usbWritePacketI");
|
||||
|
||||
if (usbGetTransmitStatusI(usbp, ep))
|
||||
return USB_ENDPOINT_BUSY;
|
||||
|
||||
|
@ -419,6 +433,9 @@ size_t usbWritePacketI(USBDriver *usbp, usbep_t ep,
|
|||
bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep,
|
||||
uint8_t *buf, size_t n) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck((usbp != NULL) && (buf != NULL), "usbStartReceiveI");
|
||||
|
||||
if (usbGetReceiveStatusI(usbp, ep))
|
||||
return TRUE;
|
||||
|
||||
|
@ -447,6 +464,9 @@ bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep,
|
|||
bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep,
|
||||
const uint8_t *buf, size_t n) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck((usbp != NULL) && (buf != NULL), "usbStartTransmitI");
|
||||
|
||||
if (usbGetTransmitStatusI(usbp, ep))
|
||||
return TRUE;
|
||||
|
||||
|
@ -468,6 +488,9 @@ bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep,
|
|||
*/
|
||||
bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(usbp != NULL, "usbStallReceiveI");
|
||||
|
||||
if (usbGetReceiveStatusI(usbp, ep))
|
||||
return TRUE;
|
||||
|
||||
|
@ -488,6 +511,9 @@ bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep) {
|
|||
*/
|
||||
bool_t usbStallTransmitI(USBDriver *usbp, usbep_t ep) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(usbp != NULL, "usbStallTransmitI");
|
||||
|
||||
if (usbGetTransmitStatusI(usbp, ep))
|
||||
return TRUE;
|
||||
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_ADC || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_CAN || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -45,19 +45,6 @@
|
|||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Sleep mode related APIs inclusion switch.
|
||||
* @note This switch is enforced to @p FALSE if the driver implementation
|
||||
* does not support the sleep mode.
|
||||
*/
|
||||
#if CAN_SUPPORTS_SLEEP || defined(__DOXYGEN__)
|
||||
#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
|
||||
#define CAN_USE_SLEEP_MODE TRUE
|
||||
#endif
|
||||
#else /* !CAN_SUPPORTS_SLEEP */
|
||||
#define CAN_USE_SLEEP_MODE FALSE
|
||||
#endif /* !CAN_SUPPORTS_SLEEP */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_GPT || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -34,6 +34,10 @@
|
|||
|
||||
#include "mcuconf.h"
|
||||
|
||||
/**
|
||||
* @name Drivers enable switches
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables the PAL subsystem.
|
||||
*/
|
||||
|
@ -138,9 +142,13 @@
|
|||
#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_USB TRUE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* ADC driver related settings. */
|
||||
/**
|
||||
* @name ADC driver related setting
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
|
@ -158,9 +166,13 @@
|
|||
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define ADC_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* CAN driver related settings. */
|
||||
/**
|
||||
* @name CAN driver related setting
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
|
@ -169,9 +181,13 @@
|
|||
#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
|
||||
#define CAN_USE_SLEEP_MODE TRUE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* I2C driver related settings. */
|
||||
/**
|
||||
* @name I2C driver related setting
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
|
@ -180,13 +196,21 @@
|
|||
#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define I2C_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* MAC driver related settings. */
|
||||
/**
|
||||
* @name MAC driver related setting
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* MMC_SPI driver related settings. */
|
||||
/**
|
||||
* @name MMC_SPI driver related setting
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
|
@ -233,17 +257,29 @@
|
|||
#if !defined(MMC_USE_SPI_POLLING) || defined(__DOXYGEN__)
|
||||
#define MMC_USE_SPI_POLLING TRUE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* PAL driver related settings. */
|
||||
/**
|
||||
* @name PAL driver related setting
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* PWM driver related settings. */
|
||||
/**
|
||||
* @name PWM driver related setting
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* SDC driver related settings. */
|
||||
/**
|
||||
* @name SDC driver related setting
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @brief Number of initialization attempts before rejecting the card.
|
||||
|
@ -271,9 +307,13 @@
|
|||
#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
|
||||
#define SDC_NICE_WAITING TRUE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* SERIAL driver related settings. */
|
||||
/**
|
||||
* @name SERIAL driver related setting
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
|
@ -295,9 +335,32 @@
|
|||
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
|
||||
#define SERIAL_BUFFERS_SIZE 16
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
|
||||
/*===========================================================================*/
|
||||
/* SPI driver related settings. */
|
||||
/**
|
||||
* @name 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 64 bytes for both the transmission and receive
|
||||
* buffers.
|
||||
*/
|
||||
#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
|
||||
#define SERIAL_USB_BUFFERS_SIZE 64
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name SPI driver related setting
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
|
@ -315,10 +378,15 @@
|
|||
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define SPI_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* UART driver related settings. */
|
||||
/**
|
||||
* @name UART driver related setting
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
/** @} */
|
||||
|
||||
#endif /* _HALCONF_H_ */
|
||||
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_I2C || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_ICU || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_MAC || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -39,27 +39,6 @@
|
|||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Number of available transmit buffers.
|
||||
*/
|
||||
#if !defined(MAC_TRANSMIT_BUFFERS) || defined(__DOXYGEN__)
|
||||
#define MAC_TRANSMIT_BUFFERS 2
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Number of available receive buffers.
|
||||
*/
|
||||
#if !defined(MAC_RECEIVE_BUFFERS) || defined(__DOXYGEN__)
|
||||
#define MAC_RECEIVE_BUFFERS 2
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maximum supported frame size.
|
||||
*/
|
||||
#if !defined(MAC_BUFFERS_SIZE) || defined(__DOXYGEN__)
|
||||
#define MAC_BUFFERS_SIZE 1518
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_XXX || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_XXX || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_PWM || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_SPI || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_UART || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if HAL_USE_USB || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -42,6 +42,10 @@
|
|||
*/
|
||||
#define CH_KERNEL_VERSION "2.3.3unstable"
|
||||
|
||||
/**
|
||||
* @name Kernel version
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Kernel version major number.
|
||||
*/
|
||||
|
@ -56,6 +60,7 @@
|
|||
* @brief Kernel version patch number.
|
||||
*/
|
||||
#define CH_KERNEL_PATCH 3
|
||||
/** @} */
|
||||
|
||||
/*
|
||||
* Common values.
|
||||
|
|
|
@ -84,6 +84,10 @@ typedef struct {
|
|||
#define BSEMAPHORE_DECL(name, taken) \
|
||||
BinarySemaphore name = _BSEMAPHORE_DATA(name, taken)
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Initializes a binary semaphore.
|
||||
*
|
||||
|
@ -238,6 +242,7 @@ typedef struct {
|
|||
* @iclass
|
||||
*/
|
||||
#define chBSemGetStateI(bsp) ((bsp)->bs_sem.s_cnt > 0 ? FALSE : TRUE)
|
||||
/** @} */
|
||||
|
||||
#endif /* CH_USE_SEMAPHORES */
|
||||
|
||||
|
|
|
@ -132,7 +132,10 @@ extern ch_trace_buffer_t dbg_trace_buffer;
|
|||
/*===========================================================================*/
|
||||
|
||||
#if CH_DBG_ENABLE_CHECKS || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Function parameter check.
|
||||
* @details If the condition check fails then the kernel panics and halts.
|
||||
|
@ -150,6 +153,7 @@ extern ch_trace_buffer_t dbg_trace_buffer;
|
|||
chDbgPanic(__QUOTE_THIS(func)"()"); \
|
||||
}
|
||||
#endif /* !defined(chDbgCheck) */
|
||||
/** @} */
|
||||
#else /* !CH_DBG_ENABLE_CHECKS */
|
||||
#define chDbgCheck(c, func) { \
|
||||
(void)(c), (void)__QUOTE_THIS(func)"()"; \
|
||||
|
@ -161,6 +165,10 @@ extern ch_trace_buffer_t dbg_trace_buffer;
|
|||
/*===========================================================================*/
|
||||
|
||||
#if CH_DBG_ENABLE_ASSERTS || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Condition assertion.
|
||||
* @details If the condition check fails then the kernel panics with the
|
||||
|
@ -184,6 +192,7 @@ extern ch_trace_buffer_t dbg_trace_buffer;
|
|||
chDbgPanic(m); \
|
||||
}
|
||||
#endif /* !defined(chDbgAssert) */
|
||||
/** @} */
|
||||
#else /* !CH_DBG_ENABLE_ASSERTS */
|
||||
#define chDbgAssert(c, m, r) {(void)(c);}
|
||||
#endif /* !CH_DBG_ENABLE_ASSERTS */
|
||||
|
|
|
@ -78,12 +78,20 @@ typedef void (*evhandler_t)(eventid_t);
|
|||
*/
|
||||
#define EVENTSOURCE_DECL(name) EventSource name = _EVENTSOURCE_DATA(name)
|
||||
|
||||
/** All events allowed mask.*/
|
||||
/**
|
||||
* @brief All events allowed mask.
|
||||
*/
|
||||
#define ALL_EVENTS ((eventmask_t)-1)
|
||||
|
||||
/** Returns the event mask from the event identifier.*/
|
||||
/**
|
||||
* @brief Returns an event mask from an event identifier.
|
||||
*/
|
||||
#define EVENT_MASK(eid) ((eventmask_t)(1 << (eid)))
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Registers an Event Listener on an Event Source.
|
||||
* @note Multiple Event Listeners can use the same event identifier, the
|
||||
|
@ -147,6 +155,7 @@ typedef void (*evhandler_t)(eventid_t);
|
|||
* @iclass
|
||||
*/
|
||||
#define chEvtBroadcastI(esp) chEvtBroadcastFlagsI(esp, 0)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -74,6 +74,8 @@ typedef uint32_t fileoffset_t;
|
|||
_base_sequential_stream_data
|
||||
|
||||
/**
|
||||
* @extends BaseSequentialStreamVMT
|
||||
*
|
||||
* @brief @p BaseFileStream virtual methods table.
|
||||
*/
|
||||
struct BaseFilelStreamVMT {
|
||||
|
@ -92,6 +94,10 @@ typedef struct {
|
|||
_base_file_stream_data
|
||||
} BaseFileStream;
|
||||
|
||||
/**
|
||||
* @name Macro Functions (BaseFileStream)
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Base file Stream close.
|
||||
* @details The function closes a file stream.
|
||||
|
@ -138,6 +144,7 @@ typedef struct {
|
|||
* @api
|
||||
*/
|
||||
#define chFileStreamSeek ((ip)->vmt->lseek(ip, offset))
|
||||
/** @} */
|
||||
|
||||
#endif /* _CHFILES_H_ */
|
||||
|
||||
|
|
|
@ -67,6 +67,8 @@
|
|||
_base_sequential_stream_data
|
||||
|
||||
/**
|
||||
* @extends BaseSequentialStreamVMT
|
||||
*
|
||||
* @brief @p BaseChannel virtual methods table.
|
||||
*/
|
||||
struct BaseChannelVMT { \
|
||||
|
@ -86,6 +88,10 @@ typedef struct {
|
|||
_base_channel_data
|
||||
} BaseChannel;
|
||||
|
||||
/**
|
||||
* @name Macro Functions (BaseChannel)
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Channel output check.
|
||||
* @details This function verifies if a subsequent put/write operation would
|
||||
|
@ -227,9 +233,13 @@ typedef struct {
|
|||
*/
|
||||
#define chIOReadTimeout(ip, bp, n, time) \
|
||||
((ip)->vmt->readt(ip, bp, n, time))
|
||||
/** @} */
|
||||
|
||||
#if CH_USE_EVENTS
|
||||
|
||||
#if CH_USE_EVENTS || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @name I/O status flags
|
||||
* @{
|
||||
*/
|
||||
/** @brief No pending conditions.*/
|
||||
#define IO_NO_ERROR 0
|
||||
/** @brief Connection happened.*/
|
||||
|
@ -242,6 +252,7 @@ typedef struct {
|
|||
#define IO_OUTPUT_EMPTY 8
|
||||
/** @brief Transmission end.*/
|
||||
#define IO_TRANSMISSION_END 16
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Type of an I/O condition flags mask.
|
||||
|
@ -267,6 +278,8 @@ typedef uint_fast16_t ioflags_t;
|
|||
ioflags_t flags;
|
||||
|
||||
/**
|
||||
* @extends BaseChannelVMT
|
||||
*
|
||||
* @brief @p BaseAsynchronousChannel virtual methods table.
|
||||
*/
|
||||
struct BaseAsynchronousChannelVMT {
|
||||
|
@ -286,6 +299,10 @@ typedef struct {
|
|||
_base_asynchronous_channel_data
|
||||
} BaseAsynchronousChannel;
|
||||
|
||||
/**
|
||||
* @name Macro Functions (BaseAsynchronousChannel)
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the I/O condition event source.
|
||||
* @details The event source is broadcasted when an I/O condition happens.
|
||||
|
@ -299,7 +316,7 @@ typedef struct {
|
|||
#define chIOGetEventSource(ip) (&((ip)->event))
|
||||
|
||||
/**
|
||||
* @brief Adds condition flags to the channel's mask.
|
||||
* @brief Adds status flags to the channel's mask.
|
||||
* @details This function is usually called from the I/O ISTs in order to
|
||||
* notify I/O conditions such as data events, errors, signal
|
||||
* changes etc.
|
||||
|
@ -316,7 +333,7 @@ typedef struct {
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Returns and clears the errors mask associated to the channel.
|
||||
* @brief Returns and clears the status flags associated to the channel.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseAsynchronousChannel or derived
|
||||
* class
|
||||
|
@ -326,6 +343,7 @@ typedef struct {
|
|||
* @api
|
||||
*/
|
||||
#define chIOGetAndClearFlags(ip) ((ip)->vmt->getflags(ip))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Default implementation of the @p getflags virtual method.
|
||||
|
|
|
@ -72,6 +72,10 @@ extern "C" {
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the mailbox buffer size.
|
||||
*
|
||||
|
@ -120,6 +124,7 @@ extern "C" {
|
|||
* @iclass
|
||||
*/
|
||||
#define chMBPeekI(mbp) (*(mbp)->mb_rdptr)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Data part of a static mailbox initializer.
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
*/
|
||||
typedef void *(*memgetfunc_t)(size_t size);
|
||||
|
||||
/**
|
||||
* @name Alignment support macros
|
||||
*/
|
||||
/**
|
||||
* @brief Alignment size constant.
|
||||
*/
|
||||
|
@ -61,6 +64,7 @@ typedef void *(*memgetfunc_t)(size_t size);
|
|||
* the type @p align_t.
|
||||
*/
|
||||
#define MEM_IS_ALIGNED(p) (((size_t)(p) & MEM_ALIGN_MASK) == 0)
|
||||
/** @} */
|
||||
|
||||
#if CH_USE_MEMCORE || defined(__DOXYGEN__)
|
||||
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#if CH_USE_MESSAGES || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Evaluates to TRUE if the thread has pending messages.
|
||||
*
|
||||
|
@ -74,6 +78,7 @@
|
|||
* @sclass
|
||||
*/
|
||||
#define chMsgReleaseS(tp, msg) chSchWakeupS(tp, msg)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -76,6 +76,10 @@ extern "C" {
|
|||
*/
|
||||
#define MUTEX_DECL(name) Mutex name = _MUTEX_DATA(name)
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns @p TRUE if the mutex queue contains at least a waiting
|
||||
* thread.
|
||||
|
@ -83,6 +87,7 @@ extern "C" {
|
|||
* @sclass
|
||||
*/
|
||||
#define chMtxQueueNotEmptyS(mp) notempty(&(mp)->m_queue)
|
||||
/** @} */
|
||||
|
||||
#endif /* CH_USE_MUTEXES */
|
||||
|
||||
|
|
|
@ -31,16 +31,16 @@
|
|||
|
||||
#if CH_USE_QUEUES || defined(__DOXYGEN__)
|
||||
|
||||
/** @brief Returned by the queue functions if the operation is successful.*/
|
||||
#define Q_OK RDY_OK
|
||||
/** @brief Returned by the queue functions if a timeout occurs.*/
|
||||
#define Q_TIMEOUT RDY_TIMEOUT
|
||||
/** @brief Returned by the queue functions if the queue has been reset.*/
|
||||
#define Q_RESET RDY_RESET
|
||||
/** @brief Returned by the queue functions if the queue is empty.*/
|
||||
#define Q_EMPTY -3
|
||||
/** @brief Returned by the queue functions if the queue is full.*/
|
||||
#define Q_FULL -4
|
||||
/**
|
||||
* @name Queue functions returned status value
|
||||
* @{
|
||||
*/
|
||||
#define Q_OK RDY_OK /**< @brief Operation successful. */
|
||||
#define Q_TIMEOUT RDY_TIMEOUT /**< @brief Timeout condition. */
|
||||
#define Q_RESET RDY_RESET /**< @brief Queue has been reset. */
|
||||
#define Q_EMPTY -3 /**< @brief Queue empty. */
|
||||
#define Q_FULL -4 /**< @brief Queue full, */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Type of a generic I/O queue structure.
|
||||
|
@ -70,6 +70,10 @@ struct GenericQueue {
|
|||
qnotify_t q_notify; /**< @brief Data notification callback. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the queue's buffer size.
|
||||
*
|
||||
|
@ -90,7 +94,8 @@ struct GenericQueue {
|
|||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chQSpaceI(qp) ((size_t)((qp)->q_counter))
|
||||
#define chQSpaceI(qp) ((qp)->q_counter)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @extends GenericQueue
|
||||
|
@ -105,6 +110,10 @@ struct GenericQueue {
|
|||
*/
|
||||
typedef GenericQueue InputQueue;
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the filled space into an input queue.
|
||||
*
|
||||
|
@ -165,6 +174,7 @@ typedef GenericQueue InputQueue;
|
|||
* @api
|
||||
*/
|
||||
#define chIQGet(iqp) chIQGetTimeout(iqp, TIME_INFINITE)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Data part of a static input queue initializer.
|
||||
|
@ -212,7 +222,11 @@ typedef GenericQueue InputQueue;
|
|||
*/
|
||||
typedef GenericQueue OutputQueue;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the filled space into an output queue.
|
||||
*
|
||||
* @param[in] oqp pointer to an @p OutputQueue structure
|
||||
|
@ -274,6 +288,7 @@ typedef GenericQueue OutputQueue;
|
|||
* @api
|
||||
*/
|
||||
#define chOQPut(oqp, b) chOQPutTimeout(oqp, b, TIME_INFINITE)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Data part of a static output queue initializer.
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
#define _CHREGISTRY_H_
|
||||
|
||||
#if CH_USE_REGISTRY || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Sets the current thread name.
|
||||
* @pre This function only stores the pointer to the name if the option
|
||||
|
@ -52,13 +56,13 @@
|
|||
* @retval NULL if the thread name has not been set.
|
||||
*/
|
||||
#define chRegGetThreadName(tp) ((tp)->p_name)
|
||||
/** @} */
|
||||
#else /* !CH_USE_REGISTRY */
|
||||
#define chRegSetThreadName(p)
|
||||
#define chRegGetThreadName(tp) NULL
|
||||
#endif /* !CH_USE_REGISTRY */
|
||||
|
||||
#if CH_USE_REGISTRY || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief Removes a thread from the registry list.
|
||||
* @note This macro is not meant for use in application code.
|
||||
|
|
|
@ -29,22 +29,35 @@
|
|||
#ifndef _CHSCHD_H_
|
||||
#define _CHSCHD_H_
|
||||
|
||||
/** @brief Default thread wakeup low level message.*/
|
||||
#define RDY_OK 0
|
||||
/** @brief Low level message sent to a thread awakened by a timeout.*/
|
||||
#define RDY_TIMEOUT -1
|
||||
/** @brief Low level message sent to a thread awakened by a reset operation.*/
|
||||
#define RDY_RESET -2
|
||||
/**
|
||||
* @name Wakeup status codes
|
||||
* @{
|
||||
*/
|
||||
#define RDY_OK 0 /**< @brief Normal wakeup message. */
|
||||
#define RDY_TIMEOUT -1 /**< @brief Wakeup caused by a timeout
|
||||
condition. */
|
||||
#define RDY_RESET -2 /**< @brief Wakeup caused by a reset
|
||||
condition. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Priority constants
|
||||
* @{
|
||||
*/
|
||||
#define NOPRIO 0 /**< @brief Ready list header priority. */
|
||||
#define IDLEPRIO 1 /**< @brief Idle thread priority. */
|
||||
#define LOWPRIO 2 /**< @brief Lowest user priority. */
|
||||
#define NORMALPRIO 64 /**< @brief Normal user priority. */
|
||||
#define HIGHPRIO 127 /**< @brief Highest user priority. */
|
||||
#define ABSPRIO 255 /**< @brief Greatest possible priority. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Zero time specification for some syscalls with a timeout
|
||||
* @name Special time constants
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Zero time specification for some functions with a timeout
|
||||
* specification.
|
||||
* @note Not all functions accept @p TIME_IMMEDIATE as timeout parameter,
|
||||
* see the specific function documentation.
|
||||
|
@ -52,10 +65,11 @@
|
|||
#define TIME_IMMEDIATE ((systime_t)0)
|
||||
|
||||
/**
|
||||
* @brief Infinite time specification for all the syscalls with a timeout
|
||||
* @brief Infinite time specification for all functions with a timeout
|
||||
* specification.
|
||||
*/
|
||||
#define TIME_INFINITE ((systime_t)-1)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Returns the priority of the first thread on the given ready list.
|
||||
|
@ -147,6 +161,10 @@ extern "C" {
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Determines if the current thread must reschedule.
|
||||
* @details This function returns @p TRUE if there is a ready thread with
|
||||
|
@ -209,6 +227,7 @@ extern "C" {
|
|||
chSchDoReschedule(); \
|
||||
}
|
||||
#endif /* CH_TIME_QUANTUM == 0 */
|
||||
/** @} */
|
||||
|
||||
#endif /* _CHSCHD_H_ */
|
||||
|
||||
|
|
|
@ -82,6 +82,10 @@ extern "C" {
|
|||
*/
|
||||
#define SEMAPHORE_DECL(name, n) Semaphore name = _SEMAPHORE_DATA(name, n)
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Decreases the semaphore counter.
|
||||
* @details This macro can be used when the counter is known to be positive.
|
||||
|
@ -105,6 +109,7 @@ extern "C" {
|
|||
* @iclass
|
||||
*/
|
||||
#define chSemGetCounterI(sp) ((sp)->s_cnt)
|
||||
/** @} */
|
||||
|
||||
#endif /* CH_USE_SEMAPHORES */
|
||||
|
||||
|
|
|
@ -73,6 +73,10 @@ typedef struct {
|
|||
_base_sequential_stream_data
|
||||
} BaseSequentialStream;
|
||||
|
||||
/**
|
||||
* @name Macro Functions (BaseSequentialStream)
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Sequential Stream write.
|
||||
* @details The function writes data from a buffer to a stream.
|
||||
|
@ -103,6 +107,7 @@ typedef struct {
|
|||
* @api
|
||||
*/
|
||||
#define chSequentialStreamRead(ip, bp, n) ((ip)->vmt->read(ip, bp, n))
|
||||
/** @} */
|
||||
|
||||
#endif /* _CHSTREAMS_H_ */
|
||||
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
#ifndef _CHSYS_H_
|
||||
#define _CHSYS_H_
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
#if !CH_NO_IDLE_THREAD || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Returns a pointer to the idle thread.
|
||||
|
@ -177,7 +181,11 @@
|
|||
dbg_check_unlock_from_isr(); \
|
||||
port_unlock_from_isr(); \
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name ISRs abstraction macros
|
||||
*/
|
||||
/**
|
||||
* @brief IRQ handler enter code.
|
||||
* @note Usually IRQ handlers functions are also declared naked.
|
||||
|
@ -211,7 +219,11 @@
|
|||
* @special
|
||||
*/
|
||||
#define CH_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Fast ISRs abstraction macros
|
||||
*/
|
||||
/**
|
||||
* @brief Standard fast IRQ handler declaration.
|
||||
* @note @p id can be a function name or a vector number depending on the
|
||||
|
@ -221,6 +233,7 @@
|
|||
* @special
|
||||
*/
|
||||
#define CH_FAST_IRQ_HANDLER(id) PORT_FAST_IRQ_HANDLER(id)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -29,6 +29,43 @@
|
|||
#ifndef _CHTHREADS_H_
|
||||
#define _CHTHREADS_H_
|
||||
|
||||
/**
|
||||
* @name Thread states
|
||||
* @{
|
||||
*/
|
||||
#define THD_STATE_READY 0 /**< @brief Waiting on the ready list. */
|
||||
#define THD_STATE_CURRENT 1 /**< @brief Currently running. */
|
||||
#define THD_STATE_SUSPENDED 2 /**< @brief Created in suspended state. */
|
||||
#define THD_STATE_WTSEM 3 /**< @brief Waiting on a semaphore. */
|
||||
#define THD_STATE_WTMTX 4 /**< @brief Waiting on a mutex. */
|
||||
#define THD_STATE_WTCOND 5 /**< @brief Waiting on a condition
|
||||
variable. */
|
||||
#define THD_STATE_SLEEPING 6 /**< @brief Waiting in @p chThdSleep()
|
||||
or @p chThdSleepUntil(). */
|
||||
#define THD_STATE_WTEXIT 7 /**< @brief Waiting in @p chThdWait(). */
|
||||
#define THD_STATE_WTOREVT 8 /**< @brief Waiting for an event. */
|
||||
#define THD_STATE_WTANDEVT 9 /**< @brief Waiting for several events. */
|
||||
#define THD_STATE_SNDMSGQ 10 /**< @brief Sending a message, in queue.*/
|
||||
#define THD_STATE_SNDMSG 11 /**< @brief Sent a message, waiting
|
||||
answer. */
|
||||
#define THD_STATE_WTMSG 12 /**< @brief Waiting for a message. */
|
||||
#define THD_STATE_WTQUEUE 13 /**< @brief Waiting on an I/O queue. */
|
||||
#define THD_STATE_FINAL 14 /**< @brief Thread terminated. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Thread flags and attributes
|
||||
* @{
|
||||
*/
|
||||
#define THD_MEM_MODE_MASK 3 /**< @brief Thread memory mode mask. */
|
||||
#define THD_MEM_MODE_STATIC 0 /**< @brief Static thread. */
|
||||
#define THD_MEM_MODE_HEAP 1 /**< @brief Thread allocated from a
|
||||
Memory Heap. */
|
||||
#define THD_MEM_MODE_MEMPOOL 2 /**< @brief Thread allocated from a
|
||||
Memory Pool. */
|
||||
#define THD_TERMINATE 4 /**< @brief Termination requested flag. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @extends ThreadsQueue
|
||||
*
|
||||
|
@ -163,51 +200,15 @@ struct Thread {
|
|||
#endif
|
||||
};
|
||||
|
||||
/** @brief Thread state: Ready to run, waiting on the ready list.*/
|
||||
#define THD_STATE_READY 0
|
||||
/** @brief Thread state: Currently running.*/
|
||||
#define THD_STATE_CURRENT 1
|
||||
/** @brief Thread state: Thread created in suspended state.*/
|
||||
#define THD_STATE_SUSPENDED 2
|
||||
/** @brief Thread state: Waiting on a semaphore.*/
|
||||
#define THD_STATE_WTSEM 3
|
||||
/** @brief Thread state: Waiting on a mutex.*/
|
||||
#define THD_STATE_WTMTX 4
|
||||
/** @brief Thread state: Waiting in @p chCondWait().*/
|
||||
#define THD_STATE_WTCOND 5
|
||||
/** @brief Thread state: Waiting in @p chThdSleep() or @p chThdSleepUntil().*/
|
||||
#define THD_STATE_SLEEPING 6
|
||||
/** @brief Thread state: Waiting in @p chThdWait().*/
|
||||
#define THD_STATE_WTEXIT 7
|
||||
/** @brief Thread state: Waiting in @p chEvtWaitXXX().*/
|
||||
#define THD_STATE_WTOREVT 8
|
||||
/** @brief Thread state: Waiting in @p chEvtWaitAllTimeout().*/
|
||||
#define THD_STATE_WTANDEVT 9
|
||||
/** @brief Thread state: Waiting in @p chMsgSend() (queued).*/
|
||||
#define THD_STATE_SNDMSGQ 10
|
||||
/** @brief Thread state: Waiting in @p chMsgSend() (not queued).*/
|
||||
#define THD_STATE_SNDMSG 11
|
||||
/** @brief Thread state: Waiting in @p chMsgWait().*/
|
||||
#define THD_STATE_WTMSG 12
|
||||
/** @brief Thread state: Waiting on an I/O queue.*/
|
||||
#define THD_STATE_WTQUEUE 13
|
||||
/** @brief Thread state: After termination.*/
|
||||
#define THD_STATE_FINAL 14
|
||||
|
||||
/*
|
||||
* Various flags into the thread p_flags field.
|
||||
*/
|
||||
#define THD_MEM_MODE_MASK 3 /**< @brief Thread memory mode mask. */
|
||||
#define THD_MEM_MODE_STATIC 0 /**< @brief Thread memory mode: static. */
|
||||
#define THD_MEM_MODE_HEAP 1 /**< @brief Thread memory mode: heap. */
|
||||
#define THD_MEM_MODE_MEMPOOL 2 /**< @brief Thread memory mode: pool. */
|
||||
#define THD_TERMINATE 4 /**< @brief Termination requested. */
|
||||
|
||||
/**
|
||||
* @brief Thread function.
|
||||
*/
|
||||
typedef msg_t (*tfunc_t)(void *);
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns a pointer to the current @p Thread.
|
||||
*
|
||||
|
@ -262,7 +263,7 @@ typedef msg_t (*tfunc_t)(void *);
|
|||
#define chThdShouldTerminate() (currp->p_flags & THD_TERMINATE)
|
||||
|
||||
/**
|
||||
* @brief Resumes a thread created with @p chThdInit().
|
||||
* @brief Resumes a thread created with @p chThdCreateI().
|
||||
*
|
||||
* @param[in] tp pointer to the thread
|
||||
*
|
||||
|
@ -321,6 +322,7 @@ typedef msg_t (*tfunc_t)(void *);
|
|||
* @api
|
||||
*/
|
||||
#define chThdSleepMicroseconds(usec) chThdSleep(US2ST(usec))
|
||||
/** @} */
|
||||
|
||||
/*
|
||||
* Threads APIs.
|
||||
|
|
|
@ -30,25 +30,30 @@
|
|||
#define _CHVT_H_
|
||||
|
||||
/**
|
||||
* @brief Time conversion utility.
|
||||
* @name Time conversion utilities
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Seconds to system ticks.
|
||||
* @details Converts from seconds to system ticks number.
|
||||
* @note The result is rounded upward to the next tick boundary.
|
||||
*/
|
||||
#define S2ST(sec) ((systime_t)((sec) * CH_FREQUENCY))
|
||||
|
||||
/**
|
||||
* @brief Time conversion utility.
|
||||
* @brief Milliseconds t0 system ticks.
|
||||
* @details Converts from milliseconds to system ticks number.
|
||||
* @note The result is rounded upward to the next tick boundary.
|
||||
*/
|
||||
#define MS2ST(msec) ((systime_t)(((((msec) - 1L) * CH_FREQUENCY) / 1000L) + 1L))
|
||||
|
||||
/**
|
||||
* @brief Time conversion utility.
|
||||
* @brief Microseconds to system ticks.
|
||||
* @details Converts from microseconds to system ticks number.
|
||||
* @note The result is rounded upward to the next tick boundary.
|
||||
*/
|
||||
#define US2ST(usec) ((systime_t)(((((usec) - 1L) * CH_FREQUENCY) / 1000000L) + 1L))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Virtual Timer callback function.
|
||||
|
@ -94,6 +99,10 @@ typedef struct {
|
|||
|
||||
extern VTList vtlist;
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Virtual timers ticker.
|
||||
*
|
||||
|
@ -115,20 +124,6 @@ extern VTList vtlist;
|
|||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* Virtual Timers APIs.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void _vt_init(void);
|
||||
void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par);
|
||||
void chVTResetI(VirtualTimer *vtp);
|
||||
bool_t chTimeIsWithin(systime_t start, systime_t end);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Returns TRUE if the speciified timer is armed.
|
||||
*
|
||||
|
@ -148,6 +143,21 @@ extern "C" {
|
|||
* @api
|
||||
*/
|
||||
#define chTimeNow() (vtlist.vt_systime)
|
||||
/** @} */
|
||||
|
||||
/*
|
||||
* Virtual Timers APIs.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void _vt_init(void);
|
||||
void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par);
|
||||
void chVTResetI(VirtualTimer *vtp);
|
||||
bool_t chTimeIsWithin(systime_t start, systime_t end);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _CHVT_H_ */
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ Thread *chMsgWait(void) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Releases the thread waiting on top of the messages queue.
|
||||
* @brief Releases a sender thread specifying a response message.
|
||||
* @pre Invoke this function only after a message has been received
|
||||
* using @p chMsgWait().
|
||||
*
|
||||
|
|
|
@ -80,9 +80,6 @@ Thread *_thread_init(Thread *tp, tprio_t prio) {
|
|||
#if CH_USE_EVENTS
|
||||
tp->p_epending = 0;
|
||||
#endif
|
||||
#if CH_USE_NESTED_LOCKS
|
||||
tp->p_locks = 0;
|
||||
#endif
|
||||
#if CH_DBG_THREADS_PROFILING
|
||||
tp->p_time = 0;
|
||||
#endif
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#if CH_DBG_ENABLE_STACK_CHECK
|
||||
#error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief If enabled allows the idle thread to enter a low power mode.
|
||||
*/
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
#include <iomacros.h>
|
||||
#include <msp430/common.h>
|
||||
|
||||
#if CH_DBG_ENABLE_STACK_CHECK
|
||||
#error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the use of a wait state in the idle thread loop.
|
||||
*/
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
#ifndef _CHCORE_H_
|
||||
#define _CHCORE_H_
|
||||
|
||||
#if CH_DBG_ENABLE_STACK_CHECK
|
||||
#error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Port-related configuration parameters.
|
||||
*/
|
||||
|
|
|
@ -26,6 +26,10 @@
|
|||
#ifndef _CHCORE_H_
|
||||
#define _CHCORE_H_
|
||||
|
||||
#if CH_DBG_ENABLE_STACK_CHECK
|
||||
#error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Macro defining the a simulated architecture into x86.
|
||||
*/
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#include <intrins.h>
|
||||
|
||||
#if CH_DBG_ENABLE_STACK_CHECK
|
||||
#error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Port configurable parameters. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
#ifndef _CHCORE_H_
|
||||
#define _CHCORE_H_
|
||||
|
||||
#if CH_DBG_ENABLE_STACK_CHECK
|
||||
#error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Port configurable parameters. */
|
||||
/*===========================================================================*/
|
||||
|
|
10
readme.txt
10
readme.txt
|
@ -89,6 +89,16 @@
|
|||
(backported to 2.2.4).
|
||||
- FIX: Fixed timeout problem in the lwIP interface layer (bug 3302420)
|
||||
(backported to 2.2.4).
|
||||
- NEW: New DMA helper driver for STM32, it simplifies the use of the DMA
|
||||
resources and hides most differences with the new enhanced DMA units
|
||||
found in the STM32F2xx sub-family.
|
||||
- NEW: Now an error is generated at compile time when trying to enable the
|
||||
options CH_DBG_ENABLE_STACK_CHECK on ports that do not support it.
|
||||
- NEW: Added a kernel-only Cortex-Mx demo as reference project for users not
|
||||
interested in the HAL but just want to use the ChibiOS/RT kernel.
|
||||
The demo is named ARMCM3-GENERIC-KERNEL and is defaulted to the STM32, in
|
||||
order to use it on other families or on the ARM Cortex-M0 just change the
|
||||
inclusion paths in the makefile.
|
||||
- NEW: Integrated new FatFs version 0.8b.
|
||||
- NEW: Added a new hook THREAD_CONTEXT_SWITCH_HOOK() that allows to insert
|
||||
code just before a context switch. For example this hook could be used
|
||||
|
|
|
@ -361,7 +361,7 @@
|
|||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_SYSTEM_STATE_CHECK FALSE
|
||||
#define CH_DBG_SYSTEM_STATE_CHECK TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -372,7 +372,7 @@
|
|||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_ENABLE_CHECKS FALSE
|
||||
#define CH_DBG_ENABLE_CHECKS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -384,7 +384,7 @@
|
|||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_ENABLE_ASSERTS FALSE
|
||||
#define CH_DBG_ENABLE_ASSERTS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -395,7 +395,7 @@
|
|||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_ENABLE_TRACE FALSE
|
||||
#define CH_DBG_ENABLE_TRACE TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -409,7 +409,7 @@
|
|||
* @p panic_msg variable set to @p NULL.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_ENABLE_STACK_CHECK FALSE
|
||||
#define CH_DBG_ENABLE_STACK_CHECK TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -421,7 +421,7 @@
|
|||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_FILL_THREADS FALSE
|
||||
#define CH_DBG_FILL_THREADS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
|
@ -361,7 +361,7 @@
|
|||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_SYSTEM_STATE_CHECK FALSE
|
||||
#define CH_DBG_SYSTEM_STATE_CHECK TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -372,7 +372,7 @@
|
|||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_ENABLE_CHECKS FALSE
|
||||
#define CH_DBG_ENABLE_CHECKS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -384,7 +384,7 @@
|
|||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_ENABLE_ASSERTS FALSE
|
||||
#define CH_DBG_ENABLE_ASSERTS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -395,7 +395,7 @@
|
|||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_ENABLE_TRACE FALSE
|
||||
#define CH_DBG_ENABLE_TRACE TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -409,7 +409,7 @@
|
|||
* @p panic_msg variable set to @p NULL.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_ENABLE_STACK_CHECK FALSE
|
||||
#define CH_DBG_ENABLE_STACK_CHECK TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -421,7 +421,7 @@
|
|||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_FILL_THREADS FALSE
|
||||
#define CH_DBG_FILL_THREADS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
|
@ -361,7 +361,7 @@
|
|||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_SYSTEM_STATE_CHECK FALSE
|
||||
#define CH_DBG_SYSTEM_STATE_CHECK TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -372,7 +372,7 @@
|
|||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_ENABLE_CHECKS FALSE
|
||||
#define CH_DBG_ENABLE_CHECKS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -384,7 +384,7 @@
|
|||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_ENABLE_ASSERTS FALSE
|
||||
#define CH_DBG_ENABLE_ASSERTS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -395,7 +395,7 @@
|
|||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_ENABLE_TRACE FALSE
|
||||
#define CH_DBG_ENABLE_TRACE TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -409,7 +409,7 @@
|
|||
* @p panic_msg variable set to @p NULL.
|
||||
*/
|
||||
#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_ENABLE_STACK_CHECK FALSE
|
||||
#define CH_DBG_ENABLE_STACK_CHECK TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -421,7 +421,7 @@
|
|||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
|
||||
#define CH_DBG_FILL_THREADS FALSE
|
||||
#define CH_DBG_FILL_THREADS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
|
@ -127,7 +127,7 @@
|
|||
* SPI driver system settings.
|
||||
*/
|
||||
#define STM32_SPI_USE_SPI1 TRUE
|
||||
#define STM32_SPI_USE_SPI2 FALSE
|
||||
#define STM32_SPI_USE_SPI2 TRUE
|
||||
#define STM32_SPI_USE_SPI3 FALSE
|
||||
#define STM32_SPI_SPI1_DMA_PRIORITY 1
|
||||
#define STM32_SPI_SPI2_DMA_PRIORITY 1
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue