I2C. Merge code from trunk.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3263 35acf78f-673a-0410-8e92-d51de3d6d3f4
master
barthess 2011-08-28 13:39:56 +00:00
commit fc492c6d19
106 changed files with 3112 additions and 834 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -174,20 +174,20 @@ typedef struct {
/**
* @brief Operation complete callback or @p NULL.
*/
spicallback_t end_cb;
spicallback_t end_cb;
/* End of the mandatory fields.*/
/**
* @brief The chip select line port.
*/
ioportid_t ssport;
ioportid_t ssport;
/**
* @brief The chip select line pad number.
*/
uint16_t sspad;
uint16_t sspad;
/**
* @brief SPI initialization data.
*/
uint16_t cr1;
uint16_t cr1;
} SPIConfig;
/**
@ -197,25 +197,25 @@ struct SPIDriver{
/**
* @brief Driver state.
*/
spistate_t state;
spistate_t state;
/**
* @brief Current configuration data.
*/
const SPIConfig *config;
const SPIConfig *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
Thread *thread;
Thread *thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
Mutex mutex;
Mutex mutex;
#elif CH_USE_SEMAPHORES
Semaphore semaphore;
Semaphore semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
@ -225,19 +225,19 @@ struct SPIDriver{
/**
* @brief Pointer to the SPIx registers block.
*/
SPI_TypeDef *spi;
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;
};
/*===========================================================================*/

View File

@ -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");
/* Checks if the stream is already taken.*/
if ((dma_streams_mask & (1 << dmastp->selfindex)) != 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->AHBENR |= RCC_AHBENR_DMA1EN;
#if STM32_HAS_DMA2
switch (dma) {
case STM32_DMA1_ID:
#else
(void)dma;
if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0)
RCC->AHBENR |= RCC_AHBENR_DMA2EN;
#endif
/* Check if the channel is already taken.*/
chDbgAssert((dmamsk1 & (1 << channel)) == 0,
"dmaAllocate(), #1", "already allocated");
/* If the DMA unit was idle then the clock is enabled.*/
if (dmamsk1 == 0) {
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
DMA1->IFCR = 0x0FFFFFFF;
}
/* Putting the stream in a safe state.*/
dmaStreamDisable(dmastp);
dmaStreamClearInterrupt(dmastp);
dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE;
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");
/* Enables the associated IRQ vector if a callback is defined.*/
if (func != NULL)
NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority));
/* If the DMA unit was idle then the clock is enabled.*/
if (dmamsk2 == 0) {
RCC->AHBENR |= RCC_AHBENR_DMA2EN;
DMA2->IFCR = 0x0FFFFFFF;
}
dmamsk2 |= 1 << channel;
dma2[channel].dmaisrfunc = func;
dma2[channel].dmaisrparam = param;
break;
}
#endif
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) {
chDbgCheck(dmastp != NULL, "dmaRelease");
/* Check if the streams is not taken.*/
chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 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->AHBENR &= ~RCC_AHBENR_DMA1EN;
#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,
"dmaRelease(), #1", "not allocated");
dma1[channel].dmaisrfunc = NULL;
dmamsk1 &= ~(1 << channel);
if (dmamsk1 == 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)
RCC->AHBENR &= ~RCC_AHBENR_DMA2EN;
break;
}
if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0)
RCC->AHBENR &= ~RCC_AHBENR_DMA2EN;
#endif
}

View File

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

View File

@ -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;
@ -154,7 +156,7 @@ static void usart_start(UARTDriver *uartp) {
u->CR1 = uartp->config->cr1 | cr1;
u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE;
u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR |
USART_CR3_EIE;
USART_CR3_EIE;
/* Starting the receiver idle loop.*/
set_rx_idle_loop(uartp);
@ -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;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
};
/*===========================================================================*/

View File

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

View File

@ -31,6 +31,10 @@
#if HAL_USE_CAN || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

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

View File

@ -29,6 +29,10 @@
#include "ch.h"
#include "hal.h"
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

@ -31,6 +31,10 @@
#if HAL_USE_I2C || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

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

View File

@ -33,6 +33,10 @@
#if HAL_USE_MAC || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

@ -31,6 +31,10 @@
#if HAL_USE_MMC_SPI || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

@ -31,6 +31,10 @@
#if HAL_USE_PAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

@ -31,6 +31,10 @@
#if HAL_USE_PWM || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

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

View File

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

View File

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

View File

@ -31,6 +31,10 @@
#if HAL_USE_SPI || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

@ -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");

View File

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

View File

@ -31,6 +31,10 @@
#if HAL_USE_ADC || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

@ -31,6 +31,10 @@
#if HAL_USE_CAN || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

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

View File

@ -31,6 +31,10 @@
#if HAL_USE_GPT || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

@ -29,6 +29,10 @@
#include "ch.h"
#include "hal.h"
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

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

View File

@ -31,6 +31,10 @@
#if HAL_USE_I2C || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

@ -31,6 +31,10 @@
#if HAL_USE_ICU || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

@ -31,6 +31,10 @@
#if HAL_USE_MAC || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

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

View File

@ -31,6 +31,10 @@
#if HAL_USE_XXX || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

@ -31,6 +31,10 @@
#if HAL_USE_XXX || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

@ -31,6 +31,10 @@
#if HAL_USE_PAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

@ -31,6 +31,10 @@
#if HAL_USE_PWM || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

@ -31,6 +31,10 @@
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

@ -31,6 +31,10 @@
#if HAL_USE_SPI || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

@ -31,6 +31,10 @@
#if HAL_USE_UART || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

@ -31,6 +31,10 @@
#if HAL_USE_USB || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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,15 +222,19 @@ typedef GenericQueue InputQueue;
*/
typedef GenericQueue OutputQueue;
/**
* @brief Returns the filled space into an output queue.
*
* @param[in] oqp pointer to an @p OutputQueue structure
* @return The number of full bytes in the queue.
* @retval 0 if the queue is empty.
*
* @iclass
*/
/**
* @name Macro Functions
* @{
*/
/**
* @brief Returns the filled space into an output queue.
*
* @param[in] oqp pointer to an @p OutputQueue structure
* @return The number of full bytes in the queue.
* @retval 0 if the queue is empty.
*
* @iclass
*/
#define chOQGetFullI(oqp) (chQSizeI(oqp) - chQSpaceI(oqp))
/**
@ -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.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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().
*

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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