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
This commit is contained in:
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=""/> <files visible="yes" title=""/>
<functions title=""/> <functions title=""/>
<variables title=""/> <variables title=""/>
<membergroups visible="yes"/>
<defines title=""/> <defines title=""/>
<typedefs title=""/> <typedefs title=""/>
<enums title=""/> <enums title=""/>
@ -150,7 +151,6 @@
<events title=""/> <events title=""/>
<properties title=""/> <properties title=""/>
<friends title=""/> <friends title=""/>
<membergroups visible="yes"/>
</memberdecl> </memberdecl>
<memberdef> <memberdef>
<pagedocs/> <pagedocs/>

View File

@ -39,6 +39,10 @@
/* Driver pre-compile time settings. */ /* Driver pre-compile time settings. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name ADC configuration options
* @{
*/
/** /**
* @brief Enables synchronous APIs. * @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space. * @note Disabling this option saves both code and data space.
@ -54,6 +58,7 @@
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) #if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define ADC_USE_MUTUAL_EXCLUSION TRUE #define ADC_USE_MUTUAL_EXCLUSION TRUE
#endif #endif
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Derived constants and error checks. */ /* Derived constants and error checks. */
@ -84,6 +89,10 @@ typedef enum {
/* Driver macros. */ /* Driver macros. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name Low Level driver helper macros
* @{
*/
#if ADC_USE_WAIT || defined(__DOXYGEN__) #if ADC_USE_WAIT || defined(__DOXYGEN__)
/** /**
* @brief Resumes a thread waiting for a conversion completion. * @brief Resumes a thread waiting for a conversion completion.
@ -211,6 +220,7 @@ typedef enum {
_adc_wakeup_isr(adcp); \ _adc_wakeup_isr(adcp); \
} \ } \
} }
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */

View File

@ -35,6 +35,10 @@
/* Driver constants. */ /* Driver constants. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name CAN status flags
* @{
*/
/** /**
* @brief Errors rate warning. * @brief Errors rate warning.
*/ */
@ -55,17 +59,26 @@
* @brief Overflow in receive queue. * @brief Overflow in receive queue.
*/ */
#define CAN_OVERFLOW_ERROR 16 #define CAN_OVERFLOW_ERROR 16
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Driver pre-compile time settings. */ /* Driver pre-compile time settings. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name CAN configuration options
* @{
*/
/** /**
* @brief Sleep mode related APIs inclusion switch. * @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__) #if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
#define CAN_USE_SLEEP_MODE TRUE #define CAN_USE_SLEEP_MODE TRUE
#endif #endif
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Derived constants and error checks. */ /* Derived constants and error checks. */
@ -96,6 +109,10 @@ typedef enum {
/* Driver macros. */ /* Driver macros. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Adds some flags to the CAN status mask. * @brief Adds some flags to the CAN status mask.
* *
@ -105,6 +122,7 @@ typedef enum {
* @iclass * @iclass
*/ */
#define canAddFlagsI(canp, mask) ((canp)->status |= (mask)) #define canAddFlagsI(canp, mask) ((canp)->status |= (mask))
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */

View File

@ -77,6 +77,10 @@ typedef void (*icucallback_t)(ICUDriver *icup);
/* Driver macros. */ /* Driver macros. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Enables the input capture. * @brief Enables the input capture.
* *
@ -118,7 +122,12 @@ typedef void (*icucallback_t)(ICUDriver *icup);
* @iclass * @iclass
*/ */
#define icuGetPeriodI(icup) icu_lld_get_period(icup) #define icuGetPeriodI(icup) icu_lld_get_period(icup)
/** @} */
/**
* @name Low Level driver helper macros
* @{
*/
/** /**
* @brief Common ISR code, ICU width event. * @brief Common ISR code, ICU width event.
* *
@ -144,6 +153,7 @@ typedef void (*icucallback_t)(ICUDriver *icup);
if (previous_state != ICU_WAITING) \ if (previous_state != ICU_WAITING) \
(icup)->config->period_cb(icup); \ (icup)->config->period_cb(icup); \
} }
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */

View File

@ -56,6 +56,10 @@
/* Driver macros. */ /* Driver macros. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Returns the received frames event source. * @brief Returns the received frames event source.
* *
@ -98,6 +102,7 @@
*/ */
#define macReadReceiveDescriptor(rdp, buf, size) \ #define macReadReceiveDescriptor(rdp, buf, size) \
mac_lld_read_receive_descriptor(rdp, buf, size) mac_lld_read_receive_descriptor(rdp, buf, size)
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */

View File

@ -18,12 +18,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. 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 * @file mii.h
* @brief MII Driver macros and structures. * @brief MII Driver macros and structures.

View File

@ -53,6 +53,10 @@
/* Driver pre-compile time settings. */ /* Driver pre-compile time settings. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name MMC_SPI configuration options
* @{
*/
/** /**
* @brief Block size for MMC transfers. * @brief Block size for MMC transfers.
*/ */
@ -86,6 +90,7 @@
#if !defined(MMC_POLLING_DELAY) || defined(__DOXYGEN__) #if !defined(MMC_POLLING_DELAY) || defined(__DOXYGEN__)
#define MMC_POLLING_DELAY 10 #define MMC_POLLING_DELAY 10
#endif #endif
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Derived constants and error checks. */ /* Derived constants and error checks. */
@ -181,6 +186,10 @@ typedef struct {
/* Driver macros. */ /* Driver macros. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Returns the driver state. * @brief Returns the driver state.
* *
@ -202,6 +211,7 @@ typedef struct {
* @api * @api
*/ */
#define mmcIsWriteProtected(mmcp) ((mmcp)->is_protected()) #define mmcIsWriteProtected(mmcp) ((mmcp)->is_protected())
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */

View File

@ -35,6 +35,10 @@
/* Driver constants. */ /* Driver constants. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name Pads mode constants
* @{
*/
/** /**
* @brief After reset state. * @brief After reset state.
* @details The state itself is not specified and is architecture dependent, * @details The state itself is not specified and is architecture dependent,
@ -81,7 +85,12 @@
* @brief Open-drain output pad. * @brief Open-drain output pad.
*/ */
#define PAL_MODE_OUTPUT_OPENDRAIN 7 #define PAL_MODE_OUTPUT_OPENDRAIN 7
/** @} */
/**
* @name Logic level constants
* @{
*/
/** /**
* @brief Logical low state. * @brief Logical low state.
*/ */
@ -91,6 +100,7 @@
* @brief Logical high state. * @brief Logical high state.
*/ */
#define PAL_HIGH 1 #define PAL_HIGH 1
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Driver pre-compile time settings. */ /* Driver pre-compile time settings. */
@ -177,6 +187,10 @@ typedef struct {
#define IOBUS_DECL(name, port, width, offset) \ #define IOBUS_DECL(name, port, width, offset) \
IOBus name = _IOBUS_DATA(name, port, width, offset) IOBus name = _IOBUS_DATA(name, port, width, offset)
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief PAL subsystem initialization. * @brief PAL subsystem initialization.
* @note This function is implicitly invoked by @p halInit(), there is * @note This function is implicitly invoked by @p halInit(), there is
@ -499,6 +513,7 @@ typedef struct {
#else #else
#define palSetPadMode(port, pad, mode) pal_lld_setpadmode(port, pad, mode) #define palSetPadMode(port, pad, mode) pal_lld_setpadmode(port, pad, mode)
#endif #endif
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */

View File

@ -35,6 +35,10 @@
/* Driver constants. */ /* Driver constants. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name PWM output mode macros
* @{
*/
/** /**
* @brief Standard output modes mask. * @brief Standard output modes mask.
*/ */
@ -54,6 +58,7 @@
* @brief Inverse PWM logic, active is logic level zero. * @brief Inverse PWM logic, active is logic level zero.
*/ */
#define PWM_OUTPUT_ACTIVE_LOW 0x02 #define PWM_OUTPUT_ACTIVE_LOW 0x02
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Driver pre-compile time settings. */ /* Driver pre-compile time settings. */
@ -94,6 +99,10 @@ typedef void (*pwmcallback_t)(PWMDriver *pwmp);
/* Driver macros. */ /* Driver macros. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name PWM duty cycle conversion
* @{
*/
/** /**
* @brief Converts from fraction to pulse width. * @brief Converts from fraction to pulse width.
* @note Be careful with rounding errors, this is integer math not magic. * @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) \ #define PWM_PERCENTAGE_TO_WIDTH(pwmp, percentage) \
PWM_FRACTION_TO_WIDTH(pwmp, 10000, percentage) PWM_FRACTION_TO_WIDTH(pwmp, 10000, percentage)
/** @} */
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Changes the period the PWM peripheral. * @brief Changes the period the PWM peripheral.
* @details This function changes the period of a PWM unit that has already * @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) \ #define pwmDisableChannelI(pwmp, channel) \
pwm_lld_disable_channel(pwmp, channel) pwm_lld_disable_channel(pwmp, channel)
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */

View File

@ -42,11 +42,16 @@
*/ */
#define SDC_CMD8_PATTERN 0x000001AA #define SDC_CMD8_PATTERN 0x000001AA
/**
* @name SD cart types
* @{
*/
#define SDC_MODE_CARDTYPE_MASK 0xF /**< @brief Card type mask. */ #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_SDV11 0 /**< @brief Card is SD V1.1.*/
#define SDC_MODE_CARDTYPE_SDV20 1 /**< @brief Card is SD V2.0.*/ #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_CARDTYPE_MMC 2 /**< @brief Card is MMC. */
#define SDC_MODE_HIGH_CAPACITY 0x10 /**< @brief High cap.card. */ #define SDC_MODE_HIGH_CAPACITY 0x10 /**< @brief High cap.card. */
/** @} */
/** /**
* @brief Mask of error bits in R1 responses. * @brief Mask of error bits in R1 responses.
@ -87,6 +92,10 @@
/* Driver pre-compile time settings. */ /* Driver pre-compile time settings. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name SDC configuration options
* @{
*/
/** /**
* @brief Number of initialization attempts before rejecting the card. * @brief Number of initialization attempts before rejecting the card.
* @note Attempts are performed at 10mS intevals. * @note Attempts are performed at 10mS intevals.
@ -113,6 +122,7 @@
#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) #if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
#define SDC_NICE_WAITING TRUE #define SDC_NICE_WAITING TRUE
#endif #endif
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Derived constants and error checks. */ /* Derived constants and error checks. */
@ -142,6 +152,10 @@ typedef enum {
/* Driver macros. */ /* Driver macros. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name R1 response utilities
* @{
*/
/** /**
* @brief Evaluates to @p TRUE if the R1 response contains error flags. * @brief Evaluates to @p TRUE if the R1 response contains error flags.
* *
@ -162,7 +176,12 @@ typedef enum {
* @param[in] r1 the r1 response * @param[in] r1 the r1 response
*/ */
#define SDC_R1_IS_CARD_LOCKED(r1) (((r1) >> 21) & 1) #define SDC_R1_IS_CARD_LOCKED(r1) (((r1) >> 21) & 1)
/** @} */
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Returns the driver state. * @brief Returns the driver state.
* *
@ -204,6 +223,7 @@ typedef enum {
* @api * @api
*/ */
#define sdcIsWriteProtected(sdcp) (sdc_lld_is_write_protected(sdcp)) #define sdcIsWriteProtected(sdcp) (sdc_lld_is_write_protected(sdcp))
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */
@ -222,7 +242,7 @@ extern "C" {
uint8_t *buffer, uint32_t n); uint8_t *buffer, uint32_t n);
bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk, bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk,
const uint8_t *buffer, uint32_t n); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -35,21 +35,25 @@
/* Driver constants. */ /* Driver constants. */
/*===========================================================================*/ /*===========================================================================*/
/** @brief Parity error happened.*/ /**
#define SD_PARITY_ERROR 32 * @name Serial status flags
/** @brief Framing error happened.*/ * @{
#define SD_FRAMING_ERROR 64 */
/** @brief Overflow happened.*/ #define SD_PARITY_ERROR 32 /**< @brief Parity error happened. */
#define SD_OVERRUN_ERROR 128 #define SD_FRAMING_ERROR 64 /**< @brief Framing error happened. */
/** @brief Noise on the line.*/ #define SD_OVERRUN_ERROR 128 /**< @brief Overflow happened. */
#define SD_NOISE_ERROR 256 #define SD_NOISE_ERROR 256 /**< @brief Noise on the line. */
/** @brief Break detected.*/ #define SD_BREAK_DETECTED 512 /**< @brief Break detected. */
#define SD_BREAK_DETECTED 512 /** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Driver pre-compile time settings. */ /* Driver pre-compile time settings. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name Serial configuration options
* @{
*/
/** /**
* @brief Default bit rate. * @brief Default bit rate.
* @details Configuration parameter, this is the baud rate selected for the * @details Configuration parameter, this is the baud rate selected for the
@ -69,6 +73,7 @@
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) #if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_BUFFERS_SIZE 16 #define SERIAL_BUFFERS_SIZE 16
#endif #endif
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Derived constants and error checks. */ /* Derived constants and error checks. */
@ -105,6 +110,8 @@ typedef struct SerialDriver SerialDriver;
_base_asynchronous_channel_methods _base_asynchronous_channel_methods
/** /**
* @extends BaseAsynchronousChannelVMT
*
* @brief @p SerialDriver virtual methods table. * @brief @p SerialDriver virtual methods table.
*/ */
struct SerialDriverVMT { struct SerialDriverVMT {
@ -128,6 +135,10 @@ struct SerialDriver {
/* Driver macros. */ /* Driver macros. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Direct output check on a @p SerialDriver. * @brief Direct output check on a @p SerialDriver.
* @note This function bypasses the indirect access to the channel and * @note This function bypasses the indirect access to the channel and
@ -281,6 +292,7 @@ struct SerialDriver {
*/ */
#define sdAsynchronousRead(sdp, b, n) \ #define sdAsynchronousRead(sdp, b, n) \
chIQReadTimeout(&(sdp)->iqueue, b, n, TIME_IMMEDIATE) chIQReadTimeout(&(sdp)->iqueue, b, n, TIME_IMMEDIATE)
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */

View File

@ -39,6 +39,10 @@
/* Driver pre-compile time settings. */ /* Driver pre-compile time settings. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name SERIAL_USB configuration options
* @{
*/
/** /**
* @brief Serial over USB buffers size. * @brief Serial over USB buffers size.
* @details Configuration parameter, the buffer size must be a multiple of * @details Configuration parameter, the buffer size must be a multiple of
@ -49,6 +53,7 @@
#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) #if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_USB_BUFFERS_SIZE 64 #define SERIAL_USB_BUFFERS_SIZE 64
#endif #endif
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Derived constants and error checks. */ /* Derived constants and error checks. */
@ -119,6 +124,8 @@ typedef struct {
_base_asynchronous_channel_methods _base_asynchronous_channel_methods
/** /**
* @extends BaseAsynchronousChannelVMT
*
* @brief @p SerialDriver virtual methods table. * @brief @p SerialDriver virtual methods table.
*/ */
struct SerialUSBDriverVMT { struct SerialUSBDriverVMT {

View File

@ -39,6 +39,10 @@
/* Driver pre-compile time settings. */ /* Driver pre-compile time settings. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name SPI configuration options
* @{
*/
/** /**
* @brief Enables synchronous APIs. * @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space. * @note Disabling this option saves both code and data space.
@ -54,6 +58,7 @@
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) #if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define SPI_USE_MUTUAL_EXCLUSION TRUE #define SPI_USE_MUTUAL_EXCLUSION TRUE
#endif #endif
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Derived constants and error checks. */ /* Derived constants and error checks. */
@ -84,6 +89,10 @@ typedef enum {
/* Driver macros. */ /* Driver macros. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Asserts the slave select signal and prepares for transfers. * @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. * @return The received data frame from the SPI bus.
*/ */
#define spiPolledExchange(spip, frame) spi_lld_polled_exchange(spip, frame) #define spiPolledExchange(spip, frame) spi_lld_polled_exchange(spip, frame)
/** @} */
/**
* @name Low Level driver helper macros
* @{
*/
#if SPI_USE_WAIT || defined(__DOXYGEN__) #if SPI_USE_WAIT || defined(__DOXYGEN__)
/** /**
* @brief Waits for operation completion. * @brief Waits for operation completion.
@ -268,6 +282,7 @@ typedef enum {
(spip)->state = SPI_READY; \ (spip)->state = SPI_READY; \
_spi_wakeup_isr(spip); \ _spi_wakeup_isr(spip); \
} }
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */

View File

@ -35,18 +35,17 @@
/* Driver constants. */ /* Driver constants. */
/*===========================================================================*/ /*===========================================================================*/
/** @brief No pending conditions.*/ /**
#define UART_NO_ERROR 0 * @name UART status flags
/** @brief Parity error happened.*/ * @{
#define UART_PARITY_ERROR 4 */
/** @brief Framing error happened.*/ #define UART_NO_ERROR 0 /**< @brief No pending conditions. */
#define UART_FRAMING_ERROR 8 #define UART_PARITY_ERROR 4 /**< @brief Parity error happened. */
/** @brief Overflow happened.*/ #define UART_FRAMING_ERROR 8 /**< @brief Framing error happened. */
#define UART_OVERRUN_ERROR 16 #define UART_OVERRUN_ERROR 16 /**< @brief Overflow happened. */
/** @brief Noise on the line.*/ #define UART_NOISE_ERROR 32 /**< @brief Noise on the line. */
#define UART_NOISE_ERROR 32 #define UART_BREAK_DETECTED 64 /**< @brief Break detected. */
/** @brief Break detected.*/ /** @} */
#define UART_BREAK_DETECTED 64
/*===========================================================================*/ /*===========================================================================*/
/* Driver pre-compile time settings. */ /* Driver pre-compile time settings. */

View File

@ -77,6 +77,10 @@
#define USB_EARLY_SET_ADDRESS 0 #define USB_EARLY_SET_ADDRESS 0
#define USB_LATE_SET_ADDRESS 1 #define USB_LATE_SET_ADDRESS 1
/**
* @name Helper macros for USB descriptors
* @{
*/
/** /**
* @brief Helper macro for index values into descriptor strings. * @brief Helper macro for index values into descriptor strings.
*/ */
@ -166,12 +170,17 @@
USB_DESC_BYTE(bmAttributes), \ USB_DESC_BYTE(bmAttributes), \
USB_DESC_WORD(wMaxPacketSize), \ USB_DESC_WORD(wMaxPacketSize), \
USB_DESC_BYTE(bInterval) USB_DESC_BYTE(bInterval)
/** @} */
/** /**
* @brief Returned by some functions to report a busy endpoint. * @brief Returned by some functions to report a busy endpoint.
*/ */
#define USB_ENDPOINT_BUSY ((size_t)0xFFFFFFFF) #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 0x0003 /**< Endpoint type mask. */
#define USB_EP_MODE_TYPE_CTRL 0x0000 /**< Control endpoint. */ #define USB_EP_MODE_TYPE_CTRL 0x0000 /**< Control endpoint. */
#define USB_EP_MODE_TYPE_ISOC 0x0001 /**< Isochronous 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_TYPE_INTR 0x0003 /**< Interrupt endpoint. */
#define USB_EP_MODE_TRANSACTION 0x0000 /**< Transaction mode. */ #define USB_EP_MODE_TRANSACTION 0x0000 /**< Transaction mode. */
#define USB_EP_MODE_PACKET 0x0010 /**< Packet mode enabled. */ #define USB_EP_MODE_PACKET 0x0010 /**< Packet mode enabled. */
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Driver pre-compile time settings. */ /* Driver pre-compile time settings. */
@ -311,6 +321,11 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
/*===========================================================================*/ /*===========================================================================*/
/* Driver macros. */ /* Driver macros. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Returns the current frame number. * @brief Returns the current frame number.
* *
@ -411,7 +426,12 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
* @special * @special
*/ */
#define usbReadSetup(usbp, ep, buf) usb_lld_read_setup(usbp, ep, buf) #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. * @brief Common ISR code, usb event callback.
* *
@ -474,6 +494,7 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
(usbp)->receiving &= ~(1 << (ep)); \ (usbp)->receiving &= ~(1 << (ep)); \
(usbp)->epc[ep]->out_cb(usbp, ep); \ (usbp)->epc[ep]->out_cb(usbp, ep); \
} }
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */

View File

@ -33,6 +33,10 @@
/* Driver constants. */ /* Driver constants. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name CDC specific messages.
* @{
*/
#define CDC_SEND_ENCAPSULATED_COMMAND 0x00 #define CDC_SEND_ENCAPSULATED_COMMAND 0x00
#define CDC_GET_ENCAPSULATED_RESPONSE 0x01 #define CDC_GET_ENCAPSULATED_RESPONSE 0x01
#define CDC_SET_COMM_FEATURE 0x02 #define CDC_SET_COMM_FEATURE 0x02
@ -52,7 +56,12 @@
#define CDC_GET_RINGER_PARMS 0x31 #define CDC_GET_RINGER_PARMS 0x31
#define CDC_SET_OPERATION_PARMS 0x32 #define CDC_SET_OPERATION_PARMS 0x32
#define CDC_GET_OPERATION_PARMS 0x33 #define CDC_GET_OPERATION_PARMS 0x33
/** @} */
/**
* @name Line Control bit definitions.
* @{
*/
#define LC_STOP_1 0 #define LC_STOP_1 0
#define LC_STOP_1P5 1 #define LC_STOP_1P5 1
#define LC_STOP_2 2 #define LC_STOP_2 2
@ -62,31 +71,37 @@
#define LC_PARITY_EVEN 2 #define LC_PARITY_EVEN 2
#define LC_PARITY_MARK 3 #define LC_PARITY_MARK 3
#define LC_PARITY_SPACE 4 #define LC_PARITY_SPACE 4
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Driver pre-compile time settings. */ /* Driver pre-compile time settings. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name USB_CDC configuration options
* @{
*/
/** /**
* @brief Endpoint number for bulk IN. * @brief Endpoint number for bulk IN.
*/ */
#if !defined(DATA_REQUEST_EP) || defined(__DOXYGEN__) #if !defined(USB_CDC_DATA_REQUEST_EP) || defined(__DOXYGEN__)
#define DATA_REQUEST_EP 1 #define USB_CDC_DATA_REQUEST_EP 1
#endif #endif
/** /**
* @brief Endpoint number for interrupt IN. * @brief Endpoint number for interrupt IN.
*/ */
#if !defined(INTERRUPT_REQUEST_EP) || defined(__DOXYGEN__) #if !defined(USB_CDC_INTERRUPT_REQUEST_EP) || defined(__DOXYGEN__)
#define INTERRUPT_REQUEST_EP 2 #define USB_CDC_INTERRUPT_REQUEST_EP 2
#endif #endif
/** /**
* @brief Endpoint number for bulk OUT. * @brief Endpoint number for bulk OUT.
*/ */
#if !defined(DATA_AVAILABLE_EP) || defined(__DOXYGEN__) #if !defined(USB_CDC_DATA_AVAILABLE_EP) || defined(__DOXYGEN__)
#define DATA_AVAILABLE_EP 3 #define USB_CDC_DATA_AVAILABLE_EP 3
#endif #endif
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Derived constants and error checks. */ /* 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]; uint32_t resp[1];
/* Checks for errors and waits for the card to be ready for reading.*/ /* 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; return TRUE;
/* Prepares the DMA channel for reading.*/ /* Prepares the DMA channel for reading.*/
dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf);
(n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf, dmaStreamSetTransactionSize(STM32_DMA2_STREAM4,
(STM32_SDC_SDIO_DMA_PRIORITY << 12) | (n * SDC_BLOCK_SIZE) / sizeof (uint32_t));
DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 | dmaStreamSetMode(STM32_DMA2_STREAM4,
DMA_CCR1_MINC); 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. /* Setting up data transfer.
Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/ 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; SDIO_DCTRL_DTEN;
/* DMA channel activation.*/ /* DMA channel activation.*/
dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); dmaStreamEnable(STM32_DMA2_STREAM4);
/* Read multiple blocks command.*/ /* Read multiple blocks command.*/
if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) 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(); chSysUnlock();
goto error; goto error;
} }
dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); dmaStreamDisable(STM32_DMA2_STREAM4);
SDIO->ICR = 0xFFFFFFFF; SDIO->ICR = 0xFFFFFFFF;
SDIO->DCTRL = 0; SDIO->DCTRL = 0;
chSysUnlock(); chSysUnlock();
return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp);
error: error:
dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); dmaStreamDisable(STM32_DMA2_STREAM4);
SDIO->ICR = 0xFFFFFFFF; SDIO->ICR = 0xFFFFFFFF;
SDIO->MASK = 0; SDIO->MASK = 0;
SDIO->DCTRL = 0; SDIO->DCTRL = 0;
@ -156,15 +158,17 @@ static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk,
uint32_t resp[1]; uint32_t resp[1];
/* Checks for errors and waits for the card to be ready for reading.*/ /* 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; return TRUE;
/* Prepares the DMA channel for reading.*/ /* Prepares the DMA channel for reading.*/
dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf);
SDC_BLOCK_SIZE / sizeof (uint32_t), buf, dmaStreamSetTransactionSize(STM32_DMA2_STREAM4,
(STM32_SDC_SDIO_DMA_PRIORITY << 12) | SDC_BLOCK_SIZE / sizeof (uint32_t));
DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 | dmaStreamSetMode(STM32_DMA2_STREAM4,
DMA_CCR1_MINC); 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. /* Setting up data transfer.
Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/ 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; SDIO_DCTRL_DTEN;
/* DMA channel activation.*/ /* DMA channel activation.*/
dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); dmaStreamEnable(STM32_DMA2_STREAM4);
/* Read single block command.*/ /* Read single block command.*/
if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) 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(); chSysUnlock();
goto error; goto error;
} }
dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); dmaStreamDisable(STM32_DMA2_STREAM4);
SDIO->ICR = 0xFFFFFFFF; SDIO->ICR = 0xFFFFFFFF;
SDIO->DCTRL = 0; SDIO->DCTRL = 0;
chSysUnlock(); chSysUnlock();
return FALSE; return FALSE;
error: error:
dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); dmaStreamDisable(STM32_DMA2_STREAM4);
SDIO->ICR = 0xFFFFFFFF; SDIO->ICR = 0xFFFFFFFF;
SDIO->MASK = 0; SDIO->MASK = 0;
SDIO->DCTRL = 0; SDIO->DCTRL = 0;
@ -235,15 +239,17 @@ static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk,
uint32_t resp[1]; uint32_t resp[1];
/* Checks for errors and waits for the card to be ready for writing.*/ /* 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; return TRUE;
/* Prepares the DMA channel for writing.*/ /* Prepares the DMA channel for writing.*/
dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf);
(n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf, dmaStreamSetTransactionSize(STM32_DMA2_STREAM4,
(STM32_SDC_SDIO_DMA_PRIORITY << 12) | (n * SDC_BLOCK_SIZE) / sizeof (uint32_t));
DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 | dmaStreamSetMode(STM32_DMA2_STREAM4,
DMA_CCR1_MINC | DMA_CCR1_DIR); 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.*/ /* Write multiple blocks command.*/
if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) 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; SDIO_DCTRL_DTEN;
/* DMA channel activation.*/ /* 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 /* Note the mask is checked before going to sleep because the interrupt
may have occurred before reaching the critical zone.*/ 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(); chSysUnlock();
goto error; goto error;
} }
dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); dmaStreamDisable(STM32_DMA2_STREAM4);
SDIO->ICR = 0xFFFFFFFF; SDIO->ICR = 0xFFFFFFFF;
SDIO->DCTRL = 0; SDIO->DCTRL = 0;
chSysUnlock(); chSysUnlock();
return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp);
error: error:
dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); dmaStreamDisable(STM32_DMA2_STREAM4);
SDIO->ICR = 0xFFFFFFFF; SDIO->ICR = 0xFFFFFFFF;
SDIO->MASK = 0; SDIO->MASK = 0;
SDIO->DCTRL = 0; SDIO->DCTRL = 0;
@ -316,15 +322,17 @@ static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk,
uint32_t resp[1]; uint32_t resp[1];
/* Checks for errors and waits for the card to be ready for writing.*/ /* 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; return TRUE;
/* Prepares the DMA channel for writing.*/ /* Prepares the DMA channel for writing.*/
dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf);
SDC_BLOCK_SIZE / sizeof (uint32_t), buf, dmaStreamSetTransactionSize(STM32_DMA2_STREAM4,
(STM32_SDC_SDIO_DMA_PRIORITY << 12) | SDC_BLOCK_SIZE / sizeof (uint32_t));
DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 | dmaStreamSetMode(STM32_DMA2_STREAM4,
DMA_CCR1_MINC | DMA_CCR1_DIR); 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.*/ /* Write single block command.*/
if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) 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; SDIO_DCTRL_DTEN;
/* DMA channel activation.*/ /* 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 /* Note the mask is checked before going to sleep because the interrupt
may have occurred before reaching the critical zone.*/ 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(); chSysUnlock();
goto error; goto error;
} }
dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); dmaStreamDisable(STM32_DMA2_STREAM4);
SDIO->ICR = 0xFFFFFFFF; SDIO->ICR = 0xFFFFFFFF;
SDIO->DCTRL = 0; SDIO->DCTRL = 0;
chSysUnlock(); chSysUnlock();
return FALSE; return FALSE;
error: error:
dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); dmaStreamDisable(STM32_DMA2_STREAM4);
SDIO->ICR = 0xFFFFFFFF; SDIO->ICR = 0xFFFFFFFF;
SDIO->MASK = 0; SDIO->MASK = 0;
SDIO->DCTRL = 0; SDIO->DCTRL = 0;
@ -431,8 +439,8 @@ void sdc_lld_start(SDCDriver *sdcp) {
if (sdcp->state == SDC_STOP) { if (sdcp->state == SDC_STOP) {
/* Note, the DMA must be enabled before the IRQs.*/ /* Note, the DMA must be enabled before the IRQs.*/
dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_4, NULL, NULL); dmaStreamAllocate(STM32_DMA2_STREAM4, 0, NULL, NULL);
dmaChannelSetPeripheral(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], &SDIO->FIFO); dmaStreamSetPeripheral(STM32_DMA2_STREAM4, &SDIO->FIFO);
NVICEnableVector(SDIO_IRQn, NVICEnableVector(SDIO_IRQn,
CORTEX_PRIORITY_MASK(STM32_SDC_SDIO_IRQ_PRIORITY)); CORTEX_PRIORITY_MASK(STM32_SDC_SDIO_IRQ_PRIORITY));
RCC->AHBENR |= RCC_AHBENR_SDIOEN; RCC->AHBENR |= RCC_AHBENR_SDIOEN;
@ -461,7 +469,7 @@ void sdc_lld_stop(SDCDriver *sdcp) {
/* Clock deactivation.*/ /* Clock deactivation.*/
NVICDisableVector(SDIO_IRQn); 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; uint32_t rca;
/* End of the mandatory fields.*/ /* End of the mandatory fields.*/
/** /**
* @brief Tthread waiting for I/O completion IRQ. * @brief Thread waiting for I/O completion IRQ.
*/ */
Thread *thread; Thread *thread;
}; };

View File

@ -67,8 +67,8 @@ static uint16_t dummyrx;
* @param[in] spip pointer to the @p SPIDriver object * @param[in] spip pointer to the @p SPIDriver object
*/ */
#define dma_stop(spip) { \ #define dma_stop(spip) { \
dmaChannelDisable(spip->dmatx); \ dmaStreamDisable(spip->dmatx); \
dmaChannelDisable(spip->dmarx); \ dmaStreamDisable(spip->dmarx); \
} }
/** /**
@ -91,7 +91,7 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) {
/* DMA errors handling.*/ /* DMA errors handling.*/
#if defined(STM32_SPI_DMA_ERROR_HOOK) #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); STM32_SPI_DMA_ERROR_HOOK(spip);
} }
#else #else
@ -117,7 +117,7 @@ static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) {
/* DMA errors handling.*/ /* DMA errors handling.*/
#if defined(STM32_SPI_DMA_ERROR_HOOK) #if defined(STM32_SPI_DMA_ERROR_HOOK)
(void)spip; (void)spip;
if ((flags & DMA_ISR_TEIF1) != 0) { if ((flags & STM32_DMA_ISR_TEIF) != 0) {
STM32_SPI_DMA_ERROR_HOOK(spip); STM32_SPI_DMA_ERROR_HOOK(spip);
} }
#else #else
@ -147,24 +147,24 @@ void spi_lld_init(void) {
spiObjectInit(&SPID1); spiObjectInit(&SPID1);
SPID1.thread = NULL; SPID1.thread = NULL;
SPID1.spi = SPI1; SPID1.spi = SPI1;
SPID1.dmarx = STM32_DMA1_CH2; SPID1.dmarx = STM32_DMA1_STREAM2;
SPID1.dmatx = STM32_DMA1_CH3; SPID1.dmatx = STM32_DMA1_STREAM3;
#endif #endif
#if STM32_SPI_USE_SPI2 #if STM32_SPI_USE_SPI2
spiObjectInit(&SPID2); spiObjectInit(&SPID2);
SPID2.thread = NULL; SPID2.thread = NULL;
SPID2.spi = SPI2; SPID2.spi = SPI2;
SPID2.dmarx = STM32_DMA1_CH4; SPID2.dmarx = STM32_DMA1_STREAM4;
SPID2.dmatx = STM32_DMA1_CH5; SPID2.dmatx = STM32_DMA1_STREAM5;
#endif #endif
#if STM32_SPI_USE_SPI3 #if STM32_SPI_USE_SPI3
spiObjectInit(&SPID3); spiObjectInit(&SPID3);
SPID3.thread = NULL; SPID3.thread = NULL;
SPID3.spi = SPI3; SPID3.spi = SPI3;
SPID3.dmarx = STM32_DMA2_CH1; SPID3.dmarx = STM32_DMA2_STREAM1;
SPID3.dmatx = STM32_DMA2_CH2; SPID3.dmatx = STM32_DMA2_STREAM2;
#endif #endif
} }
@ -181,60 +181,69 @@ void spi_lld_start(SPIDriver *spip) {
if (spip->state == SPI_STOP) { if (spip->state == SPI_STOP) {
#if STM32_SPI_USE_SPI1 #if STM32_SPI_USE_SPI1
if (&SPID1 == spip) { if (&SPID1 == spip) {
/* Note, the DMA must be enabled before the IRQs.*/ bool_t b;
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_2, b = dmaStreamAllocate(STM32_DMA1_STREAM2,
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip); STM32_SPI_SPI1_IRQ_PRIORITY,
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_3, (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); (void *)spip);
NVICEnableVector(DMA1_Channel2_IRQn, chDbgAssert(!b, "spi_lld_start(), #1", "stream already allocated");
CORTEX_PRIORITY_MASK(STM32_SPI_SPI1_IRQ_PRIORITY)); b = dmaStreamAllocate(STM32_DMA1_STREAM3,
NVICEnableVector(DMA1_Channel3_IRQn, STM32_SPI_SPI1_IRQ_PRIORITY,
CORTEX_PRIORITY_MASK(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; RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
} }
#endif #endif
#if STM32_SPI_USE_SPI2 #if STM32_SPI_USE_SPI2
if (&SPID2 == spip) { if (&SPID2 == spip) {
/* Note, the DMA must be enabled before the IRQs.*/ bool_t b;
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_4, b = dmaStreamAllocate(STM32_DMA1_STREAM4,
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip); STM32_SPI_SPI2_IRQ_PRIORITY,
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_5, (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); (void *)spip);
NVICEnableVector(DMA1_Channel4_IRQn, chDbgAssert(!b, "spi_lld_start(), #3", "stream already allocated");
CORTEX_PRIORITY_MASK(STM32_SPI_SPI2_IRQ_PRIORITY)); b = dmaStreamAllocate(STM32_DMA1_STREAM5,
NVICEnableVector(DMA1_Channel5_IRQn, STM32_SPI_SPI2_IRQ_PRIORITY,
CORTEX_PRIORITY_MASK(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; RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
} }
#endif #endif
#if STM32_SPI_USE_SPI3 #if STM32_SPI_USE_SPI3
if (&SPID3 == spip) { if (&SPID3 == spip) {
/* Note, the DMA must be enabled before the IRQs.*/ bool_t b;
dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_1, b = dmaStreamAllocate(STM32_DMA1_STREAM1,
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip); STM32_SPI_SPI3_IRQ_PRIORITY,
dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_2, (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); (void *)spip);
NVICEnableVector(DMA2_Channel1_IRQn, chDbgAssert(!b, "spi_lld_start(), #5", "stream already allocated");
CORTEX_PRIORITY_MASK(STM32_SPI_SPI3_IRQ_PRIORITY)); b = dmaStreamAllocate(STM32_DMA1_STREAM2,
NVICEnableVector(DMA2_Channel2_IRQn, STM32_SPI_SPI3_IRQ_PRIORITY,
CORTEX_PRIORITY_MASK(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; RCC->APB1ENR |= RCC_APB1ENR_SPI3EN;
} }
#endif #endif
/* DMA setup.*/ /* DMA setup.*/
dmaChannelSetPeripheral(spip->dmarx, &spip->spi->DR); dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR);
dmaChannelSetPeripheral(spip->dmatx, &spip->spi->DR); dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR);
} }
/* More DMA setup.*/ /* More DMA setup.*/
if ((spip->config->cr1 & SPI_CR1_DFF) == 0) if ((spip->config->cr1 & SPI_CR1_DFF) == 0)
spip->dmaccr = (STM32_SPI_SPI2_DMA_PRIORITY << 12) | spip->dmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) |
DMA_CCR1_TEIE; /* 8 bits transfers. */ STM32_DMA_CR_TEIE |
STM32_DMA_CR_PSIZE_BYTE |
STM32_DMA_CR_MSIZE_BYTE; /* 8 bits transfers. */
else else
spip->dmaccr = (STM32_SPI_SPI2_DMA_PRIORITY << 12) | spip->dmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) |
DMA_CCR1_TEIE | DMA_CCR1_MSIZE_0 | STM32_DMA_CR_TEIE |
DMA_CCR1_PSIZE_0; /* 16 bits transfers. */ STM32_DMA_CR_PSIZE_HWORD |
STM32_DMA_CR_MSIZE_HWORD; /* 16 bits transfers. */
/* SPI setup and enable.*/ /* SPI setup and enable.*/
spip->spi->CR1 = 0; spip->spi->CR1 = 0;
@ -261,28 +270,22 @@ void spi_lld_stop(SPIDriver *spip) {
#if STM32_SPI_USE_SPI1 #if STM32_SPI_USE_SPI1
if (&SPID1 == spip) { if (&SPID1 == spip) {
NVICDisableVector(DMA1_Channel2_IRQn); dmaStreamRelease(STM32_DMA1_STREAM2);
NVICDisableVector(DMA1_Channel3_IRQn); dmaStreamRelease(STM32_DMA1_STREAM3);
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_2);
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_3);
RCC->APB2ENR &= ~RCC_APB2ENR_SPI1EN; RCC->APB2ENR &= ~RCC_APB2ENR_SPI1EN;
} }
#endif #endif
#if STM32_SPI_USE_SPI2 #if STM32_SPI_USE_SPI2
if (&SPID2 == spip) { if (&SPID2 == spip) {
NVICDisableVector(DMA1_Channel4_IRQn); dmaStreamRelease(STM32_DMA1_STREAM4);
NVICDisableVector(DMA1_Channel5_IRQn); dmaStreamRelease(STM32_DMA1_STREAM5);
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_4);
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_5);
RCC->APB1ENR &= ~RCC_APB1ENR_SPI2EN; RCC->APB1ENR &= ~RCC_APB1ENR_SPI2EN;
} }
#endif #endif
#if STM32_SPI_USE_SPI3 #if STM32_SPI_USE_SPI3
if (&SPID3 == spip) { if (&SPID3 == spip) {
NVICDisableVector(DMA2_Channel1_IRQn); dmaStreamRelease(STM32_DMA1_STREAM1);
NVICDisableVector(DMA2_Channel2_IRQn); dmaStreamRelease(STM32_DMA1_STREAM2);
dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_1);
dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_2);
RCC->APB1ENR &= ~RCC_APB1ENR_SPI3EN; RCC->APB1ENR &= ~RCC_APB1ENR_SPI3EN;
} }
#endif #endif
@ -327,10 +330,14 @@ void spi_lld_unselect(SPIDriver *spip) {
*/ */
void spi_lld_ignore(SPIDriver *spip, size_t n) { void spi_lld_ignore(SPIDriver *spip, size_t n) {
dmaChannelSetup(spip->dmarx, n, &dummyrx, dmaStreamSetMemory0(spip->dmarx, &dummyrx);
spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_EN); dmaStreamSetTransactionSize(spip->dmarx, n);
dmaChannelSetup(spip->dmatx, n, &dummytx, dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M |
spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_EN); 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, void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf) { const void *txbuf, void *rxbuf) {
dmaChannelSetup(spip->dmarx, n, rxbuf, dmaStreamSetMemory0(spip->dmarx, rxbuf);
spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC | dmaStreamSetTransactionSize(spip->dmarx, n);
DMA_CCR1_EN); dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M |
dmaChannelSetup(spip->dmatx, n, txbuf, STM32_DMA_CR_TCIE | STM32_DMA_CR_MINC |
spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC | STM32_DMA_CR_EN);
DMA_CCR1_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) { void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
dmaChannelSetup(spip->dmarx, n, &dummyrx, dmaStreamSetMemory0(spip->dmarx, &dummyrx);
spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_EN); dmaStreamSetTransactionSize(spip->dmarx, n);
dmaChannelSetup(spip->dmatx, n, txbuf, dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M |
spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC | STM32_DMA_CR_TCIE | STM32_DMA_CR_EN);
DMA_CCR1_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) { void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
dmaChannelSetup(spip->dmarx, n, rxbuf, dmaStreamSetMemory0(spip->dmarx, rxbuf);
spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC | dmaStreamSetTransactionSize(spip->dmarx, n);
DMA_CCR1_EN); dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M |
dmaChannelSetup(spip->dmatx, n, &dummytx, STM32_DMA_CR_TCIE | STM32_DMA_CR_MINC |
spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_EN); 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

@ -227,17 +227,17 @@ struct SPIDriver{
*/ */
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 * @file DMAv1/stm32_dma.c
* @brief STM32 DMA helper driver code. * @brief DMA helper driver code.
* *
* @addtogroup STM32_DMA * @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 * 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. * drivers to coordinate the access to the resource.
* @note The DMA ISR handlers are all declared into this module because * @note The DMA ISR handlers are all declared into this module because
* sharing, the various device drivers can associate a callback to * sharing, the various device drivers can associate a callback to
* IRSs when allocating channels. * IRSs when allocating streams.
* @{ * @{
*/ */
#include "ch.h" #include "ch.h"
#include "hal.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__) #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. */ /* 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. */ /* Driver local variables and types. */
/*===========================================================================*/ /*===========================================================================*/
@ -50,17 +100,19 @@
* @brief DMA ISR redirector type. * @brief DMA ISR redirector type.
*/ */
typedef struct { typedef struct {
stm32_dmaisr_t dmaisrfunc; stm32_dmaisr_t dma_func;
void *dmaisrparam; void *dma_param;
} dma_isr_redir_t; } 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; * @brief DMA IRQ redirectors.
static dma_isr_redir_t dma2[5]; */
#endif static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS];
/*===========================================================================*/ /*===========================================================================*/
/* Driver local functions. */ /* 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 * @isr
*/ */
CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) { CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) {
uint32_t isr; uint32_t flags;
CH_IRQ_PROLOGUE(); CH_IRQ_PROLOGUE();
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_1 * 4); flags = (DMA1->ISR >> 0) & STM32_DMA_ISR_MASK;
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_1); DMA1->IFCR = STM32_DMA_ISR_MASK << 0;
if (dma1[0].dmaisrfunc) if (dma_isr_redir[0].dma_func)
dma1[0].dmaisrfunc(dma1[0].dmaisrparam, isr); dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags);
CH_IRQ_EPILOGUE(); CH_IRQ_EPILOGUE();
} }
/** /**
* @brief DMA1 channel 2 shared interrupt handler. * @brief DMA1 stream 2 shared interrupt handler.
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) { CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) {
uint32_t isr; uint32_t flags;
CH_IRQ_PROLOGUE(); CH_IRQ_PROLOGUE();
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_2 * 4); flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK;
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_2); DMA1->IFCR = STM32_DMA_ISR_MASK << 4;
if (dma1[1].dmaisrfunc) if (dma_isr_redir[1].dma_func)
dma1[1].dmaisrfunc(dma1[1].dmaisrparam, isr); dma_isr_redir[1].dma_func(dma_isr_redir[1].dma_param, flags);
CH_IRQ_EPILOGUE(); CH_IRQ_EPILOGUE();
} }
/** /**
* @brief DMA1 channel 3 shared interrupt handler. * @brief DMA1 stream 3 shared interrupt handler.
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) { CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) {
uint32_t isr; uint32_t flags;
CH_IRQ_PROLOGUE(); CH_IRQ_PROLOGUE();
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_3 * 4); flags = (DMA1->ISR >> 8) & STM32_DMA_ISR_MASK;
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3); DMA1->IFCR = STM32_DMA_ISR_MASK << 8;
if (dma1[2].dmaisrfunc) if (dma_isr_redir[2].dma_func)
dma1[2].dmaisrfunc(dma1[2].dmaisrparam, isr); dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags);
CH_IRQ_EPILOGUE(); CH_IRQ_EPILOGUE();
} }
/** /**
* @brief DMA1 channel 4 shared interrupt handler. * @brief DMA1 stream 4 shared interrupt handler.
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) { CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) {
uint32_t isr; uint32_t flags;
CH_IRQ_PROLOGUE(); CH_IRQ_PROLOGUE();
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_4 * 4); flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK;
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_4); DMA1->IFCR = STM32_DMA_ISR_MASK << 12;
if (dma1[3].dmaisrfunc) if (dma_isr_redir[3].dma_func)
dma1[3].dmaisrfunc(dma1[3].dmaisrparam, isr); dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags);
CH_IRQ_EPILOGUE(); CH_IRQ_EPILOGUE();
} }
/** /**
* @brief DMA1 channel 5 shared interrupt handler. * @brief DMA1 stream 5 shared interrupt handler.
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) { CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) {
uint32_t isr; uint32_t flags;
CH_IRQ_PROLOGUE(); CH_IRQ_PROLOGUE();
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_5 * 4); flags = (DMA1->ISR >> 16) & STM32_DMA_ISR_MASK;
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5); DMA1->IFCR = STM32_DMA_ISR_MASK << 16;
if (dma1[4].dmaisrfunc) if (dma_isr_redir[4].dma_func)
dma1[4].dmaisrfunc(dma1[4].dmaisrparam, isr); dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags);
CH_IRQ_EPILOGUE(); CH_IRQ_EPILOGUE();
} }
/** /**
* @brief DMA1 channel 6 shared interrupt handler. * @brief DMA1 stream 6 shared interrupt handler.
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) { CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) {
uint32_t isr; uint32_t flags;
CH_IRQ_PROLOGUE(); CH_IRQ_PROLOGUE();
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_6 * 4); flags = (DMA1->ISR >> 20) & STM32_DMA_ISR_MASK;
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6); DMA1->IFCR = STM32_DMA_ISR_MASK << 20;
if (dma1[5].dmaisrfunc) if (dma_isr_redir[5].dma_func)
dma1[5].dmaisrfunc(dma1[5].dmaisrparam, isr); dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags);
CH_IRQ_EPILOGUE(); CH_IRQ_EPILOGUE();
} }
/** /**
* @brief DMA1 channel 7 shared interrupt handler. * @brief DMA1 stream 7 shared interrupt handler.
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) { CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) {
uint32_t isr; uint32_t flags;
CH_IRQ_PROLOGUE(); CH_IRQ_PROLOGUE();
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_7 * 4); flags = (DMA1->ISR >> 24) & STM32_DMA_ISR_MASK;
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_7); DMA1->IFCR = STM32_DMA_ISR_MASK << 24;
if (dma1[6].dmaisrfunc) if (dma_isr_redir[6].dma_func)
dma1[6].dmaisrfunc(dma1[6].dmaisrparam, isr); dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags);
CH_IRQ_EPILOGUE(); CH_IRQ_EPILOGUE();
} }
#if STM32_HAS_DMA2 || defined(__DOXYGEN__) #if STM32_HAS_DMA2 || defined(__DOXYGEN__)
/** /**
* @brief DMA2 channel 1 shared interrupt handler. * @brief DMA2 stream 1 shared interrupt handler.
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) { CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) {
uint32_t isr; uint32_t flags;
CH_IRQ_PROLOGUE(); CH_IRQ_PROLOGUE();
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_1 * 4); flags = (DMA2->ISR >> 0) & STM32_DMA_ISR_MASK;
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_1); DMA2->IFCR = STM32_DMA_ISR_MASK << 0;
if (dma2[0].dmaisrfunc) if (dma_isr_redir[7].dma_func)
dma2[0].dmaisrfunc(dma2[0].dmaisrparam, isr); dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags);
CH_IRQ_EPILOGUE(); CH_IRQ_EPILOGUE();
} }
/** /**
* @brief DMA2 channel 2 shared interrupt handler. * @brief DMA2 stream 2 shared interrupt handler.
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) { CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) {
uint32_t isr; uint32_t flags;
CH_IRQ_PROLOGUE(); CH_IRQ_PROLOGUE();
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_2 * 4); flags = (DMA2->ISR >> 4) & STM32_DMA_ISR_MASK;
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_2); DMA2->IFCR = STM32_DMA_ISR_MASK << 4;
if (dma2[1].dmaisrfunc) if (dma_isr_redir[8].dma_func)
dma2[1].dmaisrfunc(dma2[1].dmaisrparam, isr); dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags);
CH_IRQ_EPILOGUE(); CH_IRQ_EPILOGUE();
} }
/** /**
* @brief DMA2 channel 3 shared interrupt handler. * @brief DMA2 stream 3 shared interrupt handler.
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(DMA2_Ch3_IRQHandler) { CH_IRQ_HANDLER(DMA2_Ch3_IRQHandler) {
uint32_t isr; uint32_t flags;
CH_IRQ_PROLOGUE(); CH_IRQ_PROLOGUE();
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_3 * 4); flags = (DMA2->ISR >> 8) & STM32_DMA_ISR_MASK;
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_3); DMA2->IFCR = STM32_DMA_ISR_MASK << 8;
if (dma2[2].dmaisrfunc) if (dma_isr_redir[9].dma_func)
dma2[2].dmaisrfunc(dma2[2].dmaisrparam, isr); dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags);
CH_IRQ_EPILOGUE(); CH_IRQ_EPILOGUE();
} }
#if defined(STM32F10X_CL) || defined(__DOXYGEN__) #if defined(STM32F10X_CL) || defined(__DOXYGEN__)
/** /**
* @brief DMA2 channel 4 shared interrupt handler. * @brief DMA2 stream 4 shared interrupt handler.
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(DMA2_Ch4_IRQHandler) { CH_IRQ_HANDLER(DMA2_Ch4_IRQHandler) {
uint32_t isr; uint32_t flags;
CH_IRQ_PROLOGUE(); CH_IRQ_PROLOGUE();
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_4 * 4); flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK;
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); DMA2->IFCR = STM32_DMA_ISR_MASK << 12;
if (dma2[3].dmaisrfunc) if (dma_isr_redir[10].dma_func)
dma2[3].dmaisrfunc(dma2[3].dmaisrparam, isr); dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags);
CH_IRQ_EPILOGUE(); CH_IRQ_EPILOGUE();
} }
/** /**
* @brief DMA2 channel 5 shared interrupt handler. * @brief DMA2 stream 5 shared interrupt handler.
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(DMA2_Ch5_IRQHandler) { CH_IRQ_HANDLER(DMA2_Ch5_IRQHandler) {
uint32_t isr; uint32_t flags;
CH_IRQ_PROLOGUE(); CH_IRQ_PROLOGUE();
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_5 * 4); flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK;
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5); DMA2->IFCR = STM32_DMA_ISR_MASK << 16;
if (dma2[4].dmaisrfunc) if (dma_isr_redir[11].dma_func)
dma2[4].dmaisrfunc(dma2[4].dmaisrparam, isr); dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags);
CH_IRQ_EPILOGUE(); CH_IRQ_EPILOGUE();
} }
#else /* !STM32F10X_CL */ #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 * @note This IRQ is shared between DMA2 channels 4 and 5 so it is a
* bit less efficient because an extra check. * bit less efficient because an extra check.
* *
* @isr * @isr
*/ */
CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) { CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) {
uint32_t isr; uint32_t flags;
CH_IRQ_PROLOGUE(); CH_IRQ_PROLOGUE();
/* Check on channel 4.*/ /* Check on channel 4.*/
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_5 * 4); flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK;
if (isr & DMA_ISR_GIF1) { if (flags & STM32_DMA_ISR_MASK) {
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5); DMA2->IFCR = STM32_DMA_ISR_MASK << 12;
if (dma2[3].dmaisrfunc) if (dma_isr_redir[10].dma_func)
dma2[3].dmaisrfunc(dma2[3].dmaisrparam, isr); dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags);
} }
/* Check on channel 5.*/ /* Check on channel 5.*/
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_4 * 4); flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK;
if (isr & DMA_ISR_GIF1) { if (flags & STM32_DMA_ISR_MASK) {
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5); DMA2->IFCR = STM32_DMA_ISR_MASK << 16;
if (dma2[4].dmaisrfunc) if (dma_isr_redir[11].dma_func)
dma2[4].dmaisrfunc(dma2[4].dmaisrparam, isr); dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags);
} }
CH_IRQ_EPILOGUE(); CH_IRQ_EPILOGUE();
@ -334,132 +385,109 @@ CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) {
void dmaInit(void) { void dmaInit(void) {
int i; int i;
dmamsk1 = 0; dma_streams_mask = 0;
for (i = STM32_DMA_CHANNEL_7; i >= STM32_DMA_CHANNEL_1; i--) { for (i = 0; i < STM32_DMA_STREAMS; i++) {
dmaDisableChannel(STM32_DMA1, i); _stm32_dma_streams[i].channel->CCR = 0;
dma1[i].dmaisrfunc = NULL; dma_isr_redir[i].dma_func = NULL;
} }
STM32_DMA1->IFCR = 0xFFFFFFFF; DMA1->IFCR = 0xFFFFFFFF;
#if STM32_HAS_DMA2 #if STM32_HAS_DMA2
dmamsk2 = 0; DMA2->IFCR = 0xFFFFFFFF;
for (i = STM32_DMA_CHANNEL_5; i >= STM32_DMA_CHANNEL_1; i--) {
dmaDisableChannel(STM32_DMA2, i);
dma2[i].dmaisrfunc = NULL;
}
STM32_DMA1->IFCR = 0xFFFFFFFF;
#endif #endif
} }
/** /**
* @brief Allocates a DMA channel. * @brief Allocates a DMA stream.
* @details The channel is allocated and, if required, the DMA clock enabled. * @details The stream is allocated and, if required, the DMA clock enabled.
* Trying to allocate a channel already allocated is an illegal * The function also enables the IRQ vector associated to the stream
* operation and is trapped if assertions are enabled. * and initializes its priority.
* @pre The channel must not be already in use. * @pre The stream must not be already in use or an error is returned.
* @post The channel is allocated and the default ISR handler redirected * @post The stream is allocated and the default ISR handler redirected
* to the specified function. * 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. * 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. * @note This function can be invoked in both ISR or thread context.
* *
* @param[in] dma DMA controller id * @param[in] dmastp pointer to a stm32_dma_stream_t structure
* @param[in] channel requested channel id
* @param[in] func handling function pointer, can be @p NULL * @param[in] func handling function pointer, can be @p NULL
* @param[in] param a parameter to be passed to the handling function * @param[in] param a parameter to be passed to the handling function
* @return The operation status. * @return The operation status.
* @retval FALSE operation successfully allocated. * @retval FALSE no error, stream taken.
* @retval TRUE the channel was already in use. * @retval TRUE error, stream already taken.
* *
* @special * @special
*/ */
void dmaAllocate(uint32_t dma, uint32_t channel, bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
stm32_dmaisr_t func, void *param) { uint32_t priority,
stm32_dmaisr_t func,
void *param) {
chDbgCheck(func != NULL, "dmaAllocate"); chDbgCheck(dmastp != NULL, "dmaAllocate");
#if STM32_HAS_DMA2 /* Checks if the stream is already taken.*/
switch (dma) { if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0)
case STM32_DMA1_ID: return TRUE;
#else
(void)dma;
#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.*/ /* Marks the stream as allocated.*/
if (dmamsk1 == 0) { 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; RCC->AHBENR |= RCC_AHBENR_DMA1EN;
DMA1->IFCR = 0x0FFFFFFF;
}
dmamsk1 |= 1 << channel;
dma1[channel].dmaisrfunc = func;
dma1[channel].dmaisrparam = param;
#if STM32_HAS_DMA2 #if STM32_HAS_DMA2
break; if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0)
case STM32_DMA2_ID:
/* Check if the channel is already taken.*/
chDbgAssert((dmamsk2 & (1 << channel)) == 0,
"dmaAllocate(), #2", "already allocated");
/* If the DMA unit was idle then the clock is enabled.*/
if (dmamsk2 == 0) {
RCC->AHBENR |= RCC_AHBENR_DMA2EN; RCC->AHBENR |= RCC_AHBENR_DMA2EN;
DMA2->IFCR = 0x0FFFFFFF;
}
dmamsk2 |= 1 << channel;
dma2[channel].dmaisrfunc = func;
dma2[channel].dmaisrparam = param;
break;
}
#endif #endif
/* Putting the stream in a safe state.*/
dmaStreamDisable(dmastp);
dmaStreamClearInterrupt(dmastp);
dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE;
/* Enables the associated IRQ vector if a callback is defined.*/
if (func != NULL)
NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority));
return FALSE;
} }
/** /**
* @brief Releases a DMA channel. * @brief Releases a DMA stream.
* @details The channel is freed and, if required, the DMA clock disabled. * @details The stream is freed and, if required, the DMA clock disabled.
* Trying to release a unallocated channel is an illegal operation * Trying to release a unallocated stream is an illegal operation
* and is trapped if assertions are enabled. * and is trapped if assertions are enabled.
* @pre The channel must have been allocated using @p dmaRequest(). * @pre The stream must have been allocated using @p dmaStreamAllocate().
* @post The channel is again available. * @post The stream is again available.
* @note This function can be invoked in both ISR or thread context. * @note This function can be invoked in both ISR or thread context.
* *
* @param[in] dma DMA controller id * @param[in] dmastp pointer to a stm32_dma_stream_t structure
* @param[in] channel requested channel id
* *
* @special * @special
*/ */
void dmaRelease(uint32_t dma, uint32_t channel) { void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {
#if STM32_HAS_DMA2 chDbgCheck(dmastp != NULL, "dmaRelease");
switch (dma) {
case STM32_DMA1_ID: /* Check if the streams is not taken.*/
#else chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0,
(void)dma;
#endif
/* Check if the channel is not taken.*/
chDbgAssert((dmamsk1 & (1 << channel)) != 0,
"dmaRelease(), #1", "not allocated"); "dmaRelease(), #1", "not allocated");
dma1[channel].dmaisrfunc = NULL; /* Disables the associated IRQ vector.*/
dmamsk1 &= ~(1 << channel); NVICDisableVector(dmastp->vector);
if (dmamsk1 == 0)
/* 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; RCC->AHBENR &= ~RCC_AHBENR_DMA1EN;
#if STM32_HAS_DMA2 #if STM32_HAS_DMA2
break; if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0)
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; RCC->AHBENR &= ~RCC_AHBENR_DMA2EN;
break;
}
#endif #endif
} }

View File

@ -19,10 +19,12 @@
*/ */
/** /**
* @file stm32_dma.h * @file DMAv1/stm32_dma.h
* @brief STM32 DMA helper driver header. * @brief DMA helper driver header.
* @note This file requires definitions from the ST STM32 header file * @note This file requires definitions from the ST header files
* stm3232f10x.h. * 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 * @addtogroup STM32_DMA
* @{ * @{
@ -35,14 +37,82 @@
/* Driver constants. */ /* Driver constants. */
/*===========================================================================*/ /*===========================================================================*/
/** @brief DMA1 identifier.*/ /**
#define STM32_DMA1_ID 0 * @brief Total number of DMA streams.
* @note This is the total number of streams among all the DMA units.
/** @brief DMA2 identifier.*/ */
#if STM32_HAS_DMA2 || defined(__DOXYGEN__) #if STM32_HAS_DMA2 || defined(__DOXYGEN__)
#define STM32_DMA2_ID 1 #define STM32_DMA_STREAMS 12
#else
#define STM32_DMA_STREAMS 7
#endif #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. */ /* Driver pre-compile time settings. */
/*===========================================================================*/ /*===========================================================================*/
@ -56,33 +126,23 @@
/*===========================================================================*/ /*===========================================================================*/
/** /**
* @brief STM32 DMA channel memory structure type. * @brief STM32 DMA stream descriptor structure.
*/ */
typedef struct { typedef struct {
volatile uint32_t CCR; DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */
volatile uint32_t CNDTR; volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */
volatile uint32_t CPAR; uint8_t ishift; /**< @brief Bits offset in xIFCR
volatile uint32_t CMAR; register. */
volatile uint32_t dummy; uint8_t selfindex; /**< @brief Index to self in array. */
} stm32_dma_channel_t; uint8_t vector; /**< @brief Associated IRQ vector. */
} stm32_dma_stream_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;
/** /**
* @brief STM32 DMA ISR function type. * @brief STM32 DMA ISR function type.
* *
* @param[in] p parameter for the registered function * @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); 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. */ /* 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. * @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] cpar value to be written in the CPAR register * @param[in] addr value to be written in the CPAR register
* *
* @special * @special
*/ */
#define dmaChannelSetPeripheral(dmachp, cpar) { \ #define dmaStreamSetPeripheral(dmastp, addr) { \
(dmachp)->CPAR = (uint32_t)(cpar); \ (dmastp)->channel->CPAR = (uint32_t)(addr); \
} }
/** /**
* @brief DMA channel setup by channel pointer. * @brief Associates a memory destination to a DMA stream.
* @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 This function can be invoked in both ISR or thread context. * @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] cndtr value to be written in the CNDTR register * @param[in] addr value to be written in the CMAR register
* @param[in] cmar value to be written in the CMAR register
* @param[in] ccr value to be written in the CCR register
* *
* @special * @special
*/ */
#define dmaChannelSetup(dmachp, cndtr, cmar, ccr) { \ #define dmaStreamSetMemory0(dmastp, addr) { \
(dmachp)->CNDTR = (uint32_t)(cndtr); \ (dmastp)->channel->CMAR = (uint32_t)(addr); \
(dmachp)->CMAR = (uint32_t)(cmar); \
(dmachp)->CCR = (uint32_t)(ccr); \
} }
/** /**
* @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. * @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 * @special
*/ */
#define dmaChannelEnable(dmachp) { \ #define dmaStreamSetTransactionSize(dmastp, size) { \
(dmachp)->CCR |= DMA_CCR1_EN; \ (dmastp)->channel->CNDTR = (uint32_t)(size); \
}
/**
* @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; \
} }
/** /**
* @brief DMA channel setup by channel ID. * @brief Returns the number of transfers to be performed.
* @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.
* @note This function can be invoked in both ISR or thread context. * @note This function can be invoked in both ISR or thread context.
* *
* @param[in] dmap pointer to a stm32_dma_t structure * @param[in] dmastp pointer to a stm32_dma_stream_t structure
* @param[in] ch channel number * @return The number of transfers to be performed.
* @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
* *
* @special * @special
*/ */
#define dmaSetupChannel(dmap, ch, cndtr, cmar, ccr) { \ #define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->channel->CNDTR))
dmaChannelSetup(&(dmap)->channels[ch], (cndtr), (cmar), (ccr)); \
/**
* @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. * @brief DMA stream enable.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
* @note This function can be invoked in both ISR or thread context. * @note This function can be invoked in both ISR or thread context.
* *
* @param[in] dmap pointer to a stm32_dma_t structure * @param[in] dmachp pointer to a stm32_dma_stream_t structure
* @param[in] ch channel number
* *
* @special * @special
*/ */
#define dmaEnableChannel(dmap, ch) { \ #define dmaStreamEnable(dmastp) { \
dmaChannelEnable(&(dmap)->channels[ch]); \ (dmastp)->channel->CCR |= STM32_DMA_CR_EN; \
} }
/** /**
* @brief DMA channel disable by channel ID. * @brief DMA stream disable.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
* @note This function can be invoked in both ISR or thread context. * @note This function can be invoked in both ISR or thread context.
* *
* @param[in] dmap pointer to a stm32_dma_t structure * @param[in] dmastp pointer to a stm32_dma_stream_t structure
* @param[in] ch channel number
* *
* @special * @special
*/ */
#define dmaDisableChannel(dmap, ch) { \ #define dmaStreamDisable(dmastp) { \
dmaChannelDisable(&(dmap)->channels[ch]); \ (dmastp)->channel->CCR &= ~STM32_DMA_CR_EN; \
} }
/** /**
* @brief DMA channel interrupt sources clear. * @brief DMA stream 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.
* @note This function can be invoked in both ISR or thread context. * @note This function can be invoked in both ISR or thread context.
* *
* @param[in] dmap pointer to a stm32_dma_t structure * @param[in] dmastp pointer to a stm32_dma_stream_t structure
* @param[in] ch channel number
* *
* @special * @special
*/ */
#define dmaClearChannel(dmap, ch){ \ #define dmaStreamClearInterrupt(dmastp) { \
(dmap)->IFCR = 1 << ((ch) * 4); \ *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \
} }
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */
/*===========================================================================*/ /*===========================================================================*/
#if !defined(__DOXYGEN__)
extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS];
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
void dmaInit(void); void dmaInit(void);
void dmaAllocate(uint32_t dma, uint32_t channel, bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
stm32_dmaisr_t func, void *param); uint32_t priority,
void dmaRelease(uint32_t dma, uint32_t channel); stm32_dmaisr_t func,
void *param);
void dmaStreamRelease(const stm32_dma_stream_t *dmastp);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -87,17 +87,19 @@ static uartflags_t translate_errors(uint16_t sr) {
* @param[in] uartp pointer to the @p UARTDriver object * @param[in] uartp pointer to the @p UARTDriver object
*/ */
static void set_rx_idle_loop(UARTDriver *uartp) { 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 /* RX DMA channel preparation, if the char callback is defined then the
TCIE interrupt is enabled too.*/ TCIE interrupt is enabled too.*/
if (uartp->config->rxchar_cb == NULL) 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 else
ccr = DMA_CCR1_CIRC | DMA_CCR1_TEIE | DMA_CCR1_TCIE; mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TEIE |
dmaSetupChannel(uartp->dmap, uartp->dmarx, 1, STM32_DMA_CR_TCIE;
&uartp->rxbuf, uartp->dmaccr | ccr); dmaStreamSetMemory0(uartp->dmarx, &uartp->rxbuf);
dmaEnableChannel(uartp->dmap, uartp->dmarx); 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) { static void usart_stop(UARTDriver *uartp) {
/* Stops RX and TX DMA channels.*/ /* Stops RX and TX DMA channels.*/
dmaDisableChannel(uartp->dmap, uartp->dmarx); dmaStreamDisable(uartp->dmarx);
dmaDisableChannel(uartp->dmap, uartp->dmatx); dmaStreamClearInterrupt(uartp->dmarx);
dmaClearChannel(uartp->dmap, uartp->dmarx); dmaStreamDisable(uartp->dmatx);
dmaClearChannel(uartp->dmap, uartp->dmatx); dmaStreamClearInterrupt(uartp->dmatx);
/* Stops USART operations.*/ /* Stops USART operations.*/
uartp->usart->CR1 = 0; uartp->usart->CR1 = 0;
@ -170,7 +172,7 @@ static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) {
/* DMA errors handling.*/ /* DMA errors handling.*/
#if defined(STM32_UART_DMA_ERROR_HOOK) #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); STM32_UART_DMA_ERROR_HOOK(uartp);
} }
#else #else
@ -186,7 +188,7 @@ static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) {
else { else {
/* Receiver in active state, a callback is generated, if enabled, after /* Receiver in active state, a callback is generated, if enabled, after
a completed transfer.*/ a completed transfer.*/
dmaDisableChannel(uartp->dmap, uartp->dmarx); dmaStreamDisable(uartp->dmarx);
uartp->rxstate = UART_RX_COMPLETE; uartp->rxstate = UART_RX_COMPLETE;
if (uartp->config->rxend_cb != NULL) if (uartp->config->rxend_cb != NULL)
uartp->config->rxend_cb(uartp); 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.*/ /* DMA errors handling.*/
#if defined(STM32_UART_DMA_ERROR_HOOK) #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); STM32_UART_DMA_ERROR_HOOK(uartp);
} }
#else #else
(void)flags; (void)flags;
#endif #endif
dmaDisableChannel(uartp->dmap, uartp->dmatx); dmaStreamDisable(uartp->dmatx);
/* A callback is generated, if enabled, after a completed transfer.*/ /* A callback is generated, if enabled, after a completed transfer.*/
uartp->txstate = UART_TX_COMPLETE; uartp->txstate = UART_TX_COMPLETE;
if (uartp->config->txend1_cb != NULL) if (uartp->config->txend1_cb != NULL)
@ -318,28 +320,22 @@ void uart_lld_init(void) {
#if STM32_UART_USE_USART1 #if STM32_UART_USE_USART1
uartObjectInit(&UARTD1); uartObjectInit(&UARTD1);
UARTD1.usart = USART1; UARTD1.usart = USART1;
UARTD1.dmap = STM32_DMA1; UARTD1.dmarx = STM32_DMA1_STREAM5;
UARTD1.dmarx = STM32_DMA_CHANNEL_5; UARTD1.dmatx = STM32_DMA1_STREAM4;
UARTD1.dmatx = STM32_DMA_CHANNEL_4;
UARTD1.dmaccr = 0;
#endif #endif
#if STM32_UART_USE_USART2 #if STM32_UART_USE_USART2
uartObjectInit(&UARTD2); uartObjectInit(&UARTD2);
UARTD2.usart = USART2; UARTD2.usart = USART2;
UARTD2.dmap = STM32_DMA1; UARTD2.dmarx = STM32_DMA1_STREAM6;
UARTD2.dmarx = STM32_DMA_CHANNEL_6; UARTD2.dmatx = STM32_DMA1_STREAM7;
UARTD2.dmatx = STM32_DMA_CHANNEL_7;
UARTD2.dmaccr = 0;
#endif #endif
#if STM32_UART_USE_USART3 #if STM32_UART_USE_USART3
uartObjectInit(&UARTD3); uartObjectInit(&UARTD3);
UARTD3.usart = USART3; UARTD3.usart = USART3;
UARTD3.dmap = STM32_DMA1; UARTD3.dmarx = STM32_DMA1_STREAM3;
UARTD3.dmarx = STM32_DMA_CHANNEL_3; UARTD3.dmatx = STM32_DMA1_STREAM2;
UARTD3.dmatx = STM32_DMA_CHANNEL_2;
UARTD3.dmaccr = 0;
#endif #endif
} }
@ -355,64 +351,68 @@ void uart_lld_start(UARTDriver *uartp) {
if (uartp->state == UART_STOP) { if (uartp->state == UART_STOP) {
#if STM32_UART_USE_USART1 #if STM32_UART_USE_USART1
if (&UARTD1 == uartp) { if (&UARTD1 == uartp) {
/* Note, the DMA must be enabled before the IRQs.*/ bool_t b;
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_4, b = dmaStreamAllocate(STM32_DMA1_STREAM4,
(stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); STM32_UART_USART1_IRQ_PRIORITY,
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_5, (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
(stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); (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, NVICEnableVector(USART1_IRQn,
CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY)); 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 #endif
#if STM32_UART_USE_USART2 #if STM32_UART_USE_USART2
if (&UARTD2 == uartp) { if (&UARTD2 == uartp) {
/* Note, the DMA must be enabled before the IRQs.*/ bool_t b;
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_6, b = dmaStreamAllocate(STM32_DMA1_STREAM6,
(stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); STM32_UART_USART2_IRQ_PRIORITY,
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_7, (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
(stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); (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, NVICEnableVector(USART2_IRQn,
CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY)); 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 #endif
#if STM32_UART_USE_USART3 #if STM32_UART_USE_USART3
if (&UARTD3 == uartp) { if (&UARTD3 == uartp) {
/* Note, the DMA must be enabled before the IRQs.*/ bool_t b;
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_2, b = dmaStreamAllocate(STM32_DMA1_STREAM2,
(stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); STM32_UART_USART3_IRQ_PRIORITY,
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_3, (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
(stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); (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, NVICEnableVector(USART3_IRQn,
CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY)); 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 #endif
/* Static DMA setup, the transfer size depends on the USART settings, /* 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.*/ 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) if ((uartp->config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M)
uartp->dmaccr |= DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0; uartp->dmamode |= STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
dmaChannelSetPeripheral(&uartp->dmap->channels[uartp->dmarx], dmaStreamSetPeripheral(uartp->dmarx, &uartp->usart->DR);
&uartp->usart->DR); dmaStreamSetPeripheral(uartp->dmatx, &uartp->usart->DR);
dmaChannelSetPeripheral(&uartp->dmap->channels[uartp->dmatx],
&uartp->usart->DR);
uartp->rxbuf = 0; uartp->rxbuf = 0;
} }
@ -435,11 +435,9 @@ void uart_lld_stop(UARTDriver *uartp) {
#if STM32_UART_USE_USART1 #if STM32_UART_USE_USART1
if (&UARTD1 == uartp) { if (&UARTD1 == uartp) {
dmaStreamRelease(STM32_DMA1_STREAM4);
dmaStreamRelease(STM32_DMA1_STREAM5);
NVICDisableVector(USART1_IRQn); 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; RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN;
return; return;
} }
@ -447,11 +445,9 @@ void uart_lld_stop(UARTDriver *uartp) {
#if STM32_UART_USE_USART2 #if STM32_UART_USE_USART2
if (&UARTD2 == uartp) { if (&UARTD2 == uartp) {
dmaStreamRelease(STM32_DMA1_STREAM6);
dmaStreamRelease(STM32_DMA1_STREAM7);
NVICDisableVector(USART2_IRQn); 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; RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN;
return; return;
} }
@ -459,11 +455,9 @@ void uart_lld_stop(UARTDriver *uartp) {
#if STM32_UART_USE_USART3 #if STM32_UART_USE_USART3
if (&UARTD3 == uartp) { if (&UARTD3 == uartp) {
dmaStreamRelease(STM32_DMA1_STREAM2);
dmaStreamRelease(STM32_DMA1_STREAM3);
NVICDisableVector(USART3_IRQn); 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; RCC->APB1ENR &= ~RCC_APB1ENR_USART3EN;
return; return;
} }
@ -485,10 +479,12 @@ void uart_lld_stop(UARTDriver *uartp) {
void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) {
/* TX DMA channel preparation and start.*/ /* TX DMA channel preparation and start.*/
dmaSetupChannel(uartp->dmap, uartp->dmatx, n, txbuf, dmaStreamSetMemory0(uartp->dmatx, txbuf);
uartp->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC | dmaStreamSetTransactionSize(uartp->dmatx, n);
DMA_CCR1_TEIE | DMA_CCR1_TCIE); dmaStreamSetMode(uartp->dmatx, uartp->dmamode | STM32_DMA_CR_DIR_M2P |
dmaEnableChannel(uartp->dmap, uartp->dmatx); 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) { size_t uart_lld_stop_send(UARTDriver *uartp) {
dmaDisableChannel(uartp->dmap, uartp->dmatx); dmaStreamDisable(uartp->dmatx);
dmaClearChannel(uartp->dmap, uartp->dmatx); dmaStreamClearInterrupt(uartp->dmatx);
return (size_t)uartp->dmap->channels[uartp->dmatx].CNDTR; 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) { void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) {
/* Stopping previous activity (idle state).*/ /* Stopping previous activity (idle state).*/
dmaDisableChannel(uartp->dmap, uartp->dmarx); dmaStreamDisable(uartp->dmarx);
dmaClearChannel(uartp->dmap, uartp->dmarx); dmaStreamClearInterrupt(uartp->dmarx);
/* RX DMA channel preparation and start.*/ /* RX DMA channel preparation and start.*/
dmaSetupChannel(uartp->dmap, uartp->dmarx, n, rxbuf, dmaStreamSetMemory0(uartp->dmarx, rxbuf);
uartp->dmaccr | DMA_CCR1_MINC | dmaStreamSetTransactionSize(uartp->dmarx, n);
DMA_CCR1_TEIE | DMA_CCR1_TCIE); dmaStreamSetMode(uartp->dmarx, uartp->dmamode | STM32_DMA_CR_DIR_P2M |
dmaEnableChannel(uartp->dmap, uartp->dmarx); 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 uart_lld_stop_receive(UARTDriver *uartp) {
size_t n; size_t n;
dmaDisableChannel(uartp->dmap, uartp->dmarx); dmaStreamDisable(uartp->dmarx);
dmaClearChannel(uartp->dmap, uartp->dmarx); dmaStreamClearInterrupt(uartp->dmarx);
n = (size_t)uartp->dmap->channels[uartp->dmarx].CNDTR; n = dmaStreamGetTransactionSize(uartp->dmarx);
set_rx_idle_loop(uartp); set_rx_idle_loop(uartp);
return n; return n;
} }

View File

@ -260,21 +260,17 @@ struct UARTDriver {
*/ */
USART_TypeDef *usart; USART_TypeDef *usart;
/** /**
* @brief Pointer to the DMA registers block. * @brief DMA mode bit mask.
*/ */
stm32_dma_t *dmap; uint32_t dmamode;
/**
* @brief DMA priority bit mask.
*/
uint32_t dmaccr;
/** /**
* @brief Receive DMA channel. * @brief Receive DMA channel.
*/ */
uint8_t dmarx; const stm32_dma_stream_t *dmarx;
/** /**
* @brief Transmit DMA channel. * @brief Transmit DMA channel.
*/ */
uint8_t dmatx; const stm32_dma_stream_t *dmatx;
/** /**
* @brief Default receive buffer while into @p UART_RX_IDLE state. * @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 * @file STM32/GPIOv1/pal_lld.c
* @brief STM32 GPIO low level driver code. * @brief STM32F1xx GPIO low level driver code.
* *
* @addtogroup PAL * @addtogroup PAL
* @{ * @{

View File

@ -19,8 +19,8 @@
*/ */
/** /**
* @file STM32/pal_lld.h * @file STM32/GPIOv1/pal_lld.h
* @brief STM32 GPIO low level driver header. * @brief STM32F1xx GPIO low level driver header.
* *
* @addtogroup PAL * @addtogroup PAL
* @{ * @{

View File

@ -105,7 +105,7 @@ static uint32_t pm_alloc(USBDriver *usbp, size_t size) {
next = usbp->pmnext; next = usbp->pmnext;
usbp->pmnext += size; 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; return next;
} }

View File

@ -58,17 +58,17 @@ static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
/* DMA errors handling.*/ /* DMA errors handling.*/
#if defined(STM32_ADC_DMA_ERROR_HOOK) #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); STM32_ADC_DMA_ERROR_HOOK(spip);
} }
#else #else
(void)flags; (void)flags;
#endif #endif
if ((flags & DMA_ISR_HTIF1) != 0) { if ((flags & STM32_DMA_ISR_HTIF) != 0) {
/* Half transfer processing.*/ /* Half transfer processing.*/
_adc_isr_half_code(adcp); _adc_isr_half_code(adcp);
} }
if ((flags & DMA_ISR_TCIF1) != 0) { if ((flags & STM32_DMA_ISR_TCIF) != 0) {
/* Transfer complete processing.*/ /* Transfer complete processing.*/
_adc_isr_full_code(adcp); _adc_isr_full_code(adcp);
} }
@ -93,10 +93,11 @@ void adc_lld_init(void) {
/* Driver initialization.*/ /* Driver initialization.*/
adcObjectInit(&ADCD1); adcObjectInit(&ADCD1);
ADCD1.adc = ADC1; ADCD1.adc = ADC1;
ADCD1.dmachp = STM32_DMA1_CH1; ADCD1.dmastp = STM32_DMA1_STREAM1;
ADCD1.dmaccr = (STM32_ADC_ADC1_DMA_PRIORITY << 12) | ADCD1.dmamode = STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) |
DMA_CCR1_EN | DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0 | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
DMA_CCR1_MINC | DMA_CCR1_TCIE | DMA_CCR1_TEIE; STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
STM32_DMA_CR_TEIE | STM32_DMA_CR_EN;
/* Temporary activation.*/ /* Temporary activation.*/
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
@ -132,11 +133,13 @@ void adc_lld_start(ADCDriver *adcp) {
if (adcp->state == ADC_STOP) { if (adcp->state == ADC_STOP) {
#if STM32_ADC_USE_ADC1 #if STM32_ADC_USE_ADC1
if (&ADCD1 == adcp) { if (&ADCD1 == adcp) {
dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_1, bool_t b;
(stm32_dmaisr_t)adc_lld_serve_rx_interrupt, (void *)adcp); b = dmaStreamAllocate(adcp->dmastp,
NVICEnableVector(DMA1_Channel1_IRQn, STM32_ADC_ADC1_IRQ_PRIORITY,
CORTEX_PRIORITY_MASK(STM32_ADC_ADC1_IRQ_PRIORITY)); (stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
dmaChannelSetPeripheral(adcp->dmachp, &ADC1->DR); (void *)adcp);
chDbgAssert(!b, "adc_lld_start(), #1", "stream already allocated");
dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR);
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
} }
#endif #endif
@ -163,8 +166,7 @@ void adc_lld_stop(ADCDriver *adcp) {
if (&ADCD1 == adcp) { if (&ADCD1 == adcp) {
ADC1->CR1 = 0; ADC1->CR1 = 0;
ADC1->CR2 = 0; ADC1->CR2 = 0;
NVICDisableVector(DMA1_Channel1_IRQn); dmaStreamRelease(adcp->dmastp);
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_1);
RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN; RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN;
} }
#endif #endif
@ -179,27 +181,28 @@ void adc_lld_stop(ADCDriver *adcp) {
* @notapi * @notapi
*/ */
void adc_lld_start_conversion(ADCDriver *adcp) { void adc_lld_start_conversion(ADCDriver *adcp) {
uint32_t ccr, n; uint32_t mode, n;
const ADCConversionGroup *grpp = adcp->grpp; const ADCConversionGroup *grpp = adcp->grpp;
/* DMA setup.*/ /* DMA setup.*/
ccr = adcp->dmaccr; mode = adcp->dmamode;
if (grpp->circular) if (grpp->circular)
ccr |= DMA_CCR1_CIRC; mode |= STM32_DMA_CR_CIRC;
if (adcp->depth > 1) { if (adcp->depth > 1) {
/* If the buffer depth is greater than one then the half transfer interrupt /* If the buffer depth is greater than one then the half transfer interrupt
interrupt is enabled in order to allows streaming processing.*/ 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; n = (uint32_t)grpp->num_channels * (uint32_t)adcp->depth;
} }
else else
n = (uint32_t)grpp->num_channels; 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.*/ /* ADC setup.*/
adcp->adc->CR1 = grpp->cr1 | ADC_CR1_SCAN; adcp->adc->CR1 = grpp->cr1 | ADC_CR1_SCAN;
adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON;
ADC_CR2_CONT | ADC_CR2_ADON;
adcp->adc->SMPR1 = grpp->smpr1; adcp->adc->SMPR1 = grpp->smpr1;
adcp->adc->SMPR2 = grpp->smpr2; adcp->adc->SMPR2 = grpp->smpr2;
adcp->adc->SQR1 = grpp->sqr1; adcp->adc->SQR1 = grpp->sqr1;
@ -207,8 +210,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) {
adcp->adc->SQR3 = grpp->sqr3; adcp->adc->SQR3 = grpp->sqr3;
/* ADC start by writing ADC_CR2_ADON a second time.*/ /* ADC start by writing ADC_CR2_ADON a second time.*/
adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON;
ADC_CR2_CONT | ADC_CR2_ADON;
} }
/** /**
@ -220,7 +222,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) {
*/ */
void adc_lld_stop_conversion(ADCDriver *adcp) { void adc_lld_stop_conversion(ADCDriver *adcp) {
dmaChannelDisable(adcp->dmachp); dmaStreamDisable(adcp->dmastp);
adcp->adc->CR2 = 0; adcp->adc->CR2 = 0;
} }

View File

@ -268,13 +268,13 @@ struct ADCDriver {
*/ */
ADC_TypeDef *adc; 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__) #if HAL_USE_ADC || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/ /*===========================================================================*/
/* Driver exported variables. */ /* Driver exported variables. */
/*===========================================================================*/ /*===========================================================================*/
@ -176,13 +180,14 @@ void adcStartConversionI(ADCDriver *adcp,
adcsample_t *samples, adcsample_t *samples,
size_t depth) { size_t depth) {
chDbgCheckClassI();
chDbgCheck((adcp != NULL) && (grpp != NULL) && (samples != NULL) && chDbgCheck((adcp != NULL) && (grpp != NULL) && (samples != NULL) &&
((depth == 1) || ((depth & 1) == 0)), ((depth == 1) || ((depth & 1) == 0)),
"adcStartConversionI"); "adcStartConversionI");
chDbgAssert((adcp->state == ADC_READY) || chDbgAssert((adcp->state == ADC_READY) ||
(adcp->state == ADC_COMPLETE), (adcp->state == ADC_COMPLETE),
"adcStartConversionI(), #1", "not ready"); "adcStartConversionI(), #1", "not ready");
adcp->samples = samples; adcp->samples = samples;
adcp->depth = depth; adcp->depth = depth;
adcp->grpp = grpp; adcp->grpp = grpp;
@ -229,12 +234,13 @@ void adcStopConversion(ADCDriver *adcp) {
*/ */
void adcStopConversionI(ADCDriver *adcp) { void adcStopConversionI(ADCDriver *adcp) {
chDbgCheckClassI();
chDbgCheck(adcp != NULL, "adcStopConversionI"); chDbgCheck(adcp != NULL, "adcStopConversionI");
chDbgAssert((adcp->state == ADC_READY) || chDbgAssert((adcp->state == ADC_READY) ||
(adcp->state == ADC_ACTIVE) || (adcp->state == ADC_ACTIVE) ||
(adcp->state == ADC_COMPLETE), (adcp->state == ADC_COMPLETE),
"adcStopConversionI(), #1", "invalid state"); "adcStopConversionI(), #1", "invalid state");
if (adcp->state != ADC_READY) { if (adcp->state != ADC_READY) {
adc_lld_stop_conversion(adcp); adc_lld_stop_conversion(adcp);
adcp->grpp = NULL; adcp->grpp = NULL;

View File

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

View File

@ -31,6 +31,10 @@
#if HAL_USE_GPT || defined(__DOXYGEN__) #if HAL_USE_GPT || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/ /*===========================================================================*/
/* Driver exported variables. */ /* Driver exported variables. */
/*===========================================================================*/ /*===========================================================================*/
@ -137,8 +141,11 @@ void gptStartContinuous(GPTDriver *gptp, gptcnt_t interval) {
*/ */
void gptStartContinuousI(GPTDriver *gptp, gptcnt_t interval) { void gptStartContinuousI(GPTDriver *gptp, gptcnt_t interval) {
chDbgCheckClassI();
chDbgCheck(gptp != NULL, "gptStartContinuousI");
chDbgAssert(gptp->state == GPT_READY, chDbgAssert(gptp->state == GPT_READY,
"gptStartContinuousI(), #1", "invalid state"); "gptStartContinuousI(), #1", "invalid state");
gptp->state = GPT_CONTINUOUS; gptp->state = GPT_CONTINUOUS;
gpt_lld_start_timer(gptp, interval); gpt_lld_start_timer(gptp, interval);
} }
@ -168,8 +175,11 @@ void gptStartOneShot(GPTDriver *gptp, gptcnt_t interval) {
*/ */
void gptStartOneShotI(GPTDriver *gptp, gptcnt_t interval) { void gptStartOneShotI(GPTDriver *gptp, gptcnt_t interval) {
chDbgCheckClassI();
chDbgCheck(gptp != NULL, "gptStartOneShotI");
chDbgAssert(gptp->state == GPT_READY, chDbgAssert(gptp->state == GPT_READY,
"gptStartOneShotI(), #1", "invalid state"); "gptStartOneShotI(), #1", "invalid state");
gptp->state = GPT_ONESHOT; gptp->state = GPT_ONESHOT;
gpt_lld_start_timer(gptp, interval); gpt_lld_start_timer(gptp, interval);
} }
@ -197,9 +207,12 @@ void gptStopTimer(GPTDriver *gptp) {
*/ */
void gptStopTimerI(GPTDriver *gptp) { void gptStopTimerI(GPTDriver *gptp) {
chDbgCheckClassI();
chDbgCheck(gptp != NULL, "gptStopTimerI");
chDbgAssert((gptp->state == GPT_READY) || (gptp->state == GPT_CONTINUOUS) || chDbgAssert((gptp->state == GPT_READY) || (gptp->state == GPT_CONTINUOUS) ||
(gptp->state == GPT_ONESHOT), (gptp->state == GPT_ONESHOT),
"gptStopTimerI(), #1", "invalid state"); "gptStopTimerI(), #1", "invalid state");
gptp->state = GPT_READY; gptp->state = GPT_READY;
gpt_lld_stop_timer(gptp); gpt_lld_stop_timer(gptp);
} }
@ -220,6 +233,7 @@ void gptPolledDelay(GPTDriver *gptp, gptcnt_t interval) {
chDbgAssert(gptp->state == GPT_READY, chDbgAssert(gptp->state == GPT_READY,
"gptPolledDelay(), #1", "invalid state"); "gptPolledDelay(), #1", "invalid state");
gptp->state = GPT_ONESHOT; gptp->state = GPT_ONESHOT;
gpt_lld_polled_delay(gptp, interval); gpt_lld_polled_delay(gptp, interval);
} }

View File

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

View File

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

View File

@ -31,6 +31,10 @@
#if HAL_USE_ICU || defined(__DOXYGEN__) #if HAL_USE_ICU || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/ /*===========================================================================*/
/* Driver exported variables. */ /* Driver exported variables. */
/*===========================================================================*/ /*===========================================================================*/
@ -121,6 +125,8 @@ void icuStop(ICUDriver *icup) {
*/ */
void icuEnable(ICUDriver *icup) { void icuEnable(ICUDriver *icup) {
chDbgCheck(icup != NULL, "icuEnable");
chSysLock(); chSysLock();
chDbgAssert(icup->state == ICU_READY, "icuEnable(), #1", "invalid state"); chDbgAssert(icup->state == ICU_READY, "icuEnable(), #1", "invalid state");
icu_lld_enable(icup); icu_lld_enable(icup);
@ -137,6 +143,8 @@ void icuEnable(ICUDriver *icup) {
*/ */
void icuDisable(ICUDriver *icup) { void icuDisable(ICUDriver *icup) {
chDbgCheck(icup != NULL, "icuDisable");
chSysLock(); chSysLock();
chDbgAssert((icup->state == ICU_READY) || (icup->state == ICU_WAITING) || chDbgAssert((icup->state == ICU_READY) || (icup->state == ICU_WAITING) ||
(icup->state == ICU_ACTIVE) || (icup->state == ICU_IDLE), (icup->state == ICU_ACTIVE) || (icup->state == ICU_IDLE),

View File

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

View File

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

View File

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

View File

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

View File

@ -31,6 +31,10 @@
#if HAL_USE_SDC || defined(__DOXYGEN__) #if HAL_USE_SDC || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/ /*===========================================================================*/
/* Driver exported variables. */ /* Driver exported variables. */
/*===========================================================================*/ /*===========================================================================*/
@ -54,7 +58,7 @@
* *
* @notapi * @notapi
*/ */
bool_t sdc_wait_for_transfer_state(SDCDriver *sdcp) { bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp) {
uint32_t resp[1]; uint32_t resp[1];
while (TRUE) { while (TRUE) {
@ -314,7 +318,7 @@ bool_t sdcDisconnect(SDCDriver *sdcp) {
chSysUnlock(); chSysUnlock();
/* Waits for eventual pending operations completion.*/ /* Waits for eventual pending operations completion.*/
if (sdc_wait_for_transfer_state(sdcp)) if (_sdc_wait_for_transfer_state(sdcp))
return TRUE; return TRUE;
/* Card clock stopped.*/ /* Card clock stopped.*/

View File

@ -31,6 +31,10 @@
#if HAL_USE_SERIAL || defined(__DOXYGEN__) #if HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/ /*===========================================================================*/
/* Driver exported variables. */ /* Driver exported variables. */
/*===========================================================================*/ /*===========================================================================*/
@ -207,6 +211,7 @@ void sdStop(SerialDriver *sdp) {
*/ */
void sdIncomingDataI(SerialDriver *sdp, uint8_t b) { void sdIncomingDataI(SerialDriver *sdp, uint8_t b) {
chDbgCheckClassI();
chDbgCheck(sdp != NULL, "sdIncomingDataI"); chDbgCheck(sdp != NULL, "sdIncomingDataI");
if (chIQIsEmptyI(&sdp->iqueue)) if (chIQIsEmptyI(&sdp->iqueue))
@ -233,6 +238,7 @@ void sdIncomingDataI(SerialDriver *sdp, uint8_t b) {
msg_t sdRequestDataI(SerialDriver *sdp) { msg_t sdRequestDataI(SerialDriver *sdp) {
msg_t b; msg_t b;
chDbgCheckClassI();
chDbgCheck(sdp != NULL, "sdRequestDataI"); chDbgCheck(sdp != NULL, "sdRequestDataI");
b = chOQGetI(&sdp->oqueue); b = chOQGetI(&sdp->oqueue);

View File

@ -33,6 +33,10 @@
#if HAL_USE_SERIAL_USB || defined(__DOXYGEN__) #if HAL_USE_SERIAL_USB || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/ /*===========================================================================*/
/* Driver exported variables. */ /* Driver exported variables. */
/*===========================================================================*/ /*===========================================================================*/
@ -120,7 +124,7 @@ static void inotify(GenericQueue *qp) {
emptied, then a whole packet is loaded in the queue.*/ emptied, then a whole packet is loaded in the queue.*/
if (chIQIsEmptyI(&sdup->iqueue)) { 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); sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE);
if (n != USB_ENDPOINT_BUSY) { if (n != USB_ENDPOINT_BUSY) {
chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE); 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 /* If there is any data in the output queue then it is sent within a
single packet and the queue is emptied.*/ single packet and the queue is emptied.*/
n = chOQGetFullI(&sdup->oqueue); 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); sdup->oqueue.q_buffer, n);
if (w != USB_ENDPOINT_BUSY) { if (w != USB_ENDPOINT_BUSY) {
chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY); chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY);
@ -207,10 +211,10 @@ void sduStart(SerialUSBDriver *sdup, const SerialUSBConfig *config) {
"sduStart(), #1", "sduStart(), #1",
"invalid state"); "invalid state");
sdup->config = config; sdup->config = config;
usbStart(config->usbp, &config->usb_config);
config->usbp->param = sdup; config->usbp->param = sdup;
sdup->state = SDU_READY; sdup->state = SDU_READY;
chSysUnlock(); chSysUnlock();
usbStart(config->usbp, &config->usb_config);
} }
/** /**
@ -230,9 +234,9 @@ void sduStop(SerialUSBDriver *sdup) {
chDbgAssert((sdup->state == SDU_STOP) || (sdup->state == SDU_READY), chDbgAssert((sdup->state == SDU_STOP) || (sdup->state == SDU_READY),
"sduStop(), #1", "sduStop(), #1",
"invalid state"); "invalid state");
usbStop(sdup->config->usbp);
sdup->state = SDU_STOP; sdup->state = SDU_STOP;
chSysUnlock(); chSysUnlock();
usbStop(sdup->config->usbp);
} }
/** /**

View File

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

View File

@ -31,6 +31,10 @@
#if HAL_USE_UART || defined(__DOXYGEN__) #if HAL_USE_UART || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/ /*===========================================================================*/
/* Driver exported variables. */ /* 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) { void uartStartSendI(UARTDriver *uartp, size_t n, const void *txbuf) {
chDbgCheckClassI();
chDbgCheck((uartp != NULL) && (n > 0) && (txbuf != NULL), chDbgCheck((uartp != NULL) && (n > 0) && (txbuf != NULL),
"uartStartSendI"); "uartStartSendI");
chDbgAssert((uartp->state == UART_READY) && chDbgAssert((uartp->state == UART_READY) &&
(uartp->txstate != UART_TX_ACTIVE), (uartp->txstate != UART_TX_ACTIVE),
"uartStartSendI(), #1", "not active"); "uartStartSendI(), #1", "not active");
uart_lld_start_send(uartp, n, txbuf); uart_lld_start_send(uartp, n, txbuf);
uartp->txstate = UART_TX_ACTIVE; uartp->txstate = UART_TX_ACTIVE;
} }
@ -216,8 +221,8 @@ size_t uartStopSend(UARTDriver *uartp) {
*/ */
size_t uartStopSendI(UARTDriver *uartp) { size_t uartStopSendI(UARTDriver *uartp) {
chDbgCheckClassI();
chDbgCheck(uartp != NULL, "uartStopSendI"); chDbgCheck(uartp != NULL, "uartStopSendI");
chDbgAssert(uartp->state == UART_READY, "uartStopSendI(), #1", "not active"); chDbgAssert(uartp->state == UART_READY, "uartStopSendI(), #1", "not active");
if (uartp->txstate == UART_TX_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) { void uartStartReceiveI(UARTDriver *uartp, size_t n, void *rxbuf) {
chDbgCheckClassI();
chDbgCheck((uartp != NULL) && (n > 0) && (rxbuf != NULL), chDbgCheck((uartp != NULL) && (n > 0) && (rxbuf != NULL),
"uartStartReceiveI"); "uartStartReceiveI");
chDbgAssert((uartp->state == UART_READY) && (uartp->rxstate == UART_RX_IDLE), chDbgAssert((uartp->state == UART_READY) && (uartp->rxstate == UART_RX_IDLE),
"uartStartReceiveI(), #1", "not active"); "uartStartReceiveI(), #1", "not active");
@ -322,8 +327,9 @@ size_t uartStopReceive(UARTDriver *uartp) {
* @iclass * @iclass
*/ */
size_t uartStopReceiveI(UARTDriver *uartp) { size_t uartStopReceiveI(UARTDriver *uartp) {
chDbgCheck(uartp != NULL, "uartStopReceiveI");
chDbgCheckClassI();
chDbgCheck(uartp != NULL, "uartStopReceiveI");
chDbgAssert(uartp->state == UART_READY, chDbgAssert(uartp->state == UART_READY,
"uartStopReceiveI(), #1", "not active"); "uartStopReceiveI(), #1", "not active");

View File

@ -34,6 +34,10 @@
#if HAL_USE_USB || defined(__DOXYGEN__) #if HAL_USE_USB || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/ /*===========================================================================*/
/* Driver exported variables. */ /* Driver exported variables. */
/*===========================================================================*/ /*===========================================================================*/
@ -301,6 +305,8 @@ void usbStop(USBDriver *usbp) {
void usbInitEndpointI(USBDriver *usbp, usbep_t ep, void usbInitEndpointI(USBDriver *usbp, usbep_t ep,
const USBEndpointConfig *epcp) { const USBEndpointConfig *epcp) {
chDbgCheckClassI();
chDbgCheck((usbp != NULL) && (epcp != NULL), "usbInitEndpointI");
chDbgAssert(usbp->state == USB_ACTIVE, chDbgAssert(usbp->state == USB_ACTIVE,
"usbEnableEndpointI(), #1", "invalid state"); "usbEnableEndpointI(), #1", "invalid state");
chDbgAssert(usbp->epc[ep] != NULL, chDbgAssert(usbp->epc[ep] != NULL,
@ -331,6 +337,8 @@ void usbInitEndpointI(USBDriver *usbp, usbep_t ep,
void usbDisableEndpointsI(USBDriver *usbp) { void usbDisableEndpointsI(USBDriver *usbp) {
unsigned i; unsigned i;
chDbgCheckClassI();
chDbgCheck(usbp != NULL, "usbDisableEndpointsI");
chDbgAssert(usbp->state == USB_SELECTED, chDbgAssert(usbp->state == USB_SELECTED,
"usbDisableEndpointsI(), #1", "invalid state"); "usbDisableEndpointsI(), #1", "invalid state");
@ -364,6 +372,9 @@ void usbDisableEndpointsI(USBDriver *usbp) {
size_t usbReadPacketI(USBDriver *usbp, usbep_t ep, size_t usbReadPacketI(USBDriver *usbp, usbep_t ep,
uint8_t *buf, size_t n) { uint8_t *buf, size_t n) {
chDbgCheckClassI();
chDbgCheck((usbp != NULL) && (buf != NULL), "usbReadPacketI");
if (usbGetReceiveStatusI(usbp, ep)) if (usbGetReceiveStatusI(usbp, ep))
return USB_ENDPOINT_BUSY; return USB_ENDPOINT_BUSY;
@ -391,6 +402,9 @@ size_t usbReadPacketI(USBDriver *usbp, usbep_t ep,
size_t usbWritePacketI(USBDriver *usbp, usbep_t ep, size_t usbWritePacketI(USBDriver *usbp, usbep_t ep,
const uint8_t *buf, size_t n) { const uint8_t *buf, size_t n) {
chDbgCheckClassI();
chDbgCheck((usbp != NULL) && (buf != NULL), "usbWritePacketI");
if (usbGetTransmitStatusI(usbp, ep)) if (usbGetTransmitStatusI(usbp, ep))
return USB_ENDPOINT_BUSY; return USB_ENDPOINT_BUSY;
@ -419,6 +433,9 @@ size_t usbWritePacketI(USBDriver *usbp, usbep_t ep,
bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep, bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep,
uint8_t *buf, size_t n) { uint8_t *buf, size_t n) {
chDbgCheckClassI();
chDbgCheck((usbp != NULL) && (buf != NULL), "usbStartReceiveI");
if (usbGetReceiveStatusI(usbp, ep)) if (usbGetReceiveStatusI(usbp, ep))
return TRUE; return TRUE;
@ -447,6 +464,9 @@ bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep,
bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep, bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep,
const uint8_t *buf, size_t n) { const uint8_t *buf, size_t n) {
chDbgCheckClassI();
chDbgCheck((usbp != NULL) && (buf != NULL), "usbStartTransmitI");
if (usbGetTransmitStatusI(usbp, ep)) if (usbGetTransmitStatusI(usbp, ep))
return TRUE; return TRUE;
@ -468,6 +488,9 @@ bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep,
*/ */
bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep) { bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep) {
chDbgCheckClassI();
chDbgCheck(usbp != NULL, "usbStallReceiveI");
if (usbGetReceiveStatusI(usbp, ep)) if (usbGetReceiveStatusI(usbp, ep))
return TRUE; return TRUE;
@ -488,6 +511,9 @@ bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep) {
*/ */
bool_t usbStallTransmitI(USBDriver *usbp, usbep_t ep) { bool_t usbStallTransmitI(USBDriver *usbp, usbep_t ep) {
chDbgCheckClassI();
chDbgCheck(usbp != NULL, "usbStallTransmitI");
if (usbGetTransmitStatusI(usbp, ep)) if (usbGetTransmitStatusI(usbp, ep))
return TRUE; return TRUE;

View File

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

View File

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

View File

@ -45,19 +45,6 @@
/* Driver pre-compile time settings. */ /* 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. */ /* Derived constants and error checks. */
/*===========================================================================*/ /*===========================================================================*/

View File

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

View File

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

View File

@ -34,6 +34,10 @@
#include "mcuconf.h" #include "mcuconf.h"
/**
* @name Drivers enable switches
* @{
*/
/** /**
* @brief Enables the PAL subsystem. * @brief Enables the PAL subsystem.
*/ */
@ -138,9 +142,13 @@
#if !defined(HAL_USE_USB) || defined(__DOXYGEN__) #if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
#define HAL_USE_USB TRUE #define HAL_USE_USB TRUE
#endif #endif
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* ADC driver related settings. */ /**
* @name ADC driver related setting
* @{
*/
/*===========================================================================*/ /*===========================================================================*/
/** /**
@ -158,9 +166,13 @@
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) #if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define ADC_USE_MUTUAL_EXCLUSION TRUE #define ADC_USE_MUTUAL_EXCLUSION TRUE
#endif #endif
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* CAN driver related settings. */ /**
* @name CAN driver related setting
* @{
*/
/*===========================================================================*/ /*===========================================================================*/
/** /**
@ -169,9 +181,13 @@
#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) #if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
#define CAN_USE_SLEEP_MODE TRUE #define CAN_USE_SLEEP_MODE TRUE
#endif #endif
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* I2C driver related settings. */ /**
* @name I2C driver related setting
* @{
*/
/*===========================================================================*/ /*===========================================================================*/
/** /**
@ -180,13 +196,21 @@
#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) #if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define I2C_USE_MUTUAL_EXCLUSION TRUE #define I2C_USE_MUTUAL_EXCLUSION TRUE
#endif #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__) #if !defined(MMC_USE_SPI_POLLING) || defined(__DOXYGEN__)
#define MMC_USE_SPI_POLLING TRUE #define MMC_USE_SPI_POLLING TRUE
#endif #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. * @brief Number of initialization attempts before rejecting the card.
@ -271,9 +307,13 @@
#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) #if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
#define SDC_NICE_WAITING TRUE #define SDC_NICE_WAITING TRUE
#endif #endif
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* SERIAL driver related settings. */ /**
* @name SERIAL driver related setting
* @{
*/
/*===========================================================================*/ /*===========================================================================*/
/** /**
@ -295,9 +335,32 @@
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) #if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_BUFFERS_SIZE 16 #define SERIAL_BUFFERS_SIZE 16
#endif #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__) #if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define SPI_USE_MUTUAL_EXCLUSION TRUE #define SPI_USE_MUTUAL_EXCLUSION TRUE
#endif #endif
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* UART driver related settings. */ /**
* @name UART driver related setting
* @{
*/
/*===========================================================================*/ /*===========================================================================*/
/** @} */
#endif /* _HALCONF_H_ */ #endif /* _HALCONF_H_ */

View File

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

View File

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

View File

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

View File

@ -39,27 +39,6 @@
/* Driver pre-compile time settings. */ /* 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. */ /* Derived constants and error checks. */
/*===========================================================================*/ /*===========================================================================*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -42,6 +42,10 @@
*/ */
#define CH_KERNEL_VERSION "2.3.3unstable" #define CH_KERNEL_VERSION "2.3.3unstable"
/**
* @name Kernel version
* @{
*/
/** /**
* @brief Kernel version major number. * @brief Kernel version major number.
*/ */
@ -56,6 +60,7 @@
* @brief Kernel version patch number. * @brief Kernel version patch number.
*/ */
#define CH_KERNEL_PATCH 3 #define CH_KERNEL_PATCH 3
/** @} */
/* /*
* Common values. * Common values.

View File

@ -84,6 +84,10 @@ typedef struct {
#define BSEMAPHORE_DECL(name, taken) \ #define BSEMAPHORE_DECL(name, taken) \
BinarySemaphore name = _BSEMAPHORE_DATA(name, taken) BinarySemaphore name = _BSEMAPHORE_DATA(name, taken)
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Initializes a binary semaphore. * @brief Initializes a binary semaphore.
* *
@ -238,6 +242,7 @@ typedef struct {
* @iclass * @iclass
*/ */
#define chBSemGetStateI(bsp) ((bsp)->bs_sem.s_cnt > 0 ? FALSE : TRUE) #define chBSemGetStateI(bsp) ((bsp)->bs_sem.s_cnt > 0 ? FALSE : TRUE)
/** @} */
#endif /* CH_USE_SEMAPHORES */ #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__) #if CH_DBG_ENABLE_CHECKS || defined(__DOXYGEN__)
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Function parameter check. * @brief Function parameter check.
* @details If the condition check fails then the kernel panics and halts. * @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)"()"); \ chDbgPanic(__QUOTE_THIS(func)"()"); \
} }
#endif /* !defined(chDbgCheck) */ #endif /* !defined(chDbgCheck) */
/** @} */
#else /* !CH_DBG_ENABLE_CHECKS */ #else /* !CH_DBG_ENABLE_CHECKS */
#define chDbgCheck(c, func) { \ #define chDbgCheck(c, func) { \
(void)(c), (void)__QUOTE_THIS(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__) #if CH_DBG_ENABLE_ASSERTS || defined(__DOXYGEN__)
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Condition assertion. * @brief Condition assertion.
* @details If the condition check fails then the kernel panics with the * @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); \ chDbgPanic(m); \
} }
#endif /* !defined(chDbgAssert) */ #endif /* !defined(chDbgAssert) */
/** @} */
#else /* !CH_DBG_ENABLE_ASSERTS */ #else /* !CH_DBG_ENABLE_ASSERTS */
#define chDbgAssert(c, m, r) {(void)(c);} #define chDbgAssert(c, m, r) {(void)(c);}
#endif /* !CH_DBG_ENABLE_ASSERTS */ #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) #define EVENTSOURCE_DECL(name) EventSource name = _EVENTSOURCE_DATA(name)
/** All events allowed mask.*/ /**
* @brief All events allowed mask.
*/
#define ALL_EVENTS ((eventmask_t)-1) #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))) #define EVENT_MASK(eid) ((eventmask_t)(1 << (eid)))
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Registers an Event Listener on an Event Source. * @brief Registers an Event Listener on an Event Source.
* @note Multiple Event Listeners can use the same event identifier, the * @note Multiple Event Listeners can use the same event identifier, the
@ -147,6 +155,7 @@ typedef void (*evhandler_t)(eventid_t);
* @iclass * @iclass
*/ */
#define chEvtBroadcastI(esp) chEvtBroadcastFlagsI(esp, 0) #define chEvtBroadcastI(esp) chEvtBroadcastFlagsI(esp, 0)
/** @} */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@ -74,6 +74,8 @@ typedef uint32_t fileoffset_t;
_base_sequential_stream_data _base_sequential_stream_data
/** /**
* @extends BaseSequentialStreamVMT
*
* @brief @p BaseFileStream virtual methods table. * @brief @p BaseFileStream virtual methods table.
*/ */
struct BaseFilelStreamVMT { struct BaseFilelStreamVMT {
@ -92,6 +94,10 @@ typedef struct {
_base_file_stream_data _base_file_stream_data
} BaseFileStream; } BaseFileStream;
/**
* @name Macro Functions (BaseFileStream)
* @{
*/
/** /**
* @brief Base file Stream close. * @brief Base file Stream close.
* @details The function closes a file stream. * @details The function closes a file stream.
@ -138,6 +144,7 @@ typedef struct {
* @api * @api
*/ */
#define chFileStreamSeek ((ip)->vmt->lseek(ip, offset)) #define chFileStreamSeek ((ip)->vmt->lseek(ip, offset))
/** @} */
#endif /* _CHFILES_H_ */ #endif /* _CHFILES_H_ */

View File

@ -67,6 +67,8 @@
_base_sequential_stream_data _base_sequential_stream_data
/** /**
* @extends BaseSequentialStreamVMT
*
* @brief @p BaseChannel virtual methods table. * @brief @p BaseChannel virtual methods table.
*/ */
struct BaseChannelVMT { \ struct BaseChannelVMT { \
@ -86,6 +88,10 @@ typedef struct {
_base_channel_data _base_channel_data
} BaseChannel; } BaseChannel;
/**
* @name Macro Functions (BaseChannel)
* @{
*/
/** /**
* @brief Channel output check. * @brief Channel output check.
* @details This function verifies if a subsequent put/write operation would * @details This function verifies if a subsequent put/write operation would
@ -227,9 +233,13 @@ typedef struct {
*/ */
#define chIOReadTimeout(ip, bp, n, time) \ #define chIOReadTimeout(ip, bp, n, time) \
((ip)->vmt->readt(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.*/ /** @brief No pending conditions.*/
#define IO_NO_ERROR 0 #define IO_NO_ERROR 0
/** @brief Connection happened.*/ /** @brief Connection happened.*/
@ -242,6 +252,7 @@ typedef struct {
#define IO_OUTPUT_EMPTY 8 #define IO_OUTPUT_EMPTY 8
/** @brief Transmission end.*/ /** @brief Transmission end.*/
#define IO_TRANSMISSION_END 16 #define IO_TRANSMISSION_END 16
/** @} */
/** /**
* @brief Type of an I/O condition flags mask. * @brief Type of an I/O condition flags mask.
@ -267,6 +278,8 @@ typedef uint_fast16_t ioflags_t;
ioflags_t flags; ioflags_t flags;
/** /**
* @extends BaseChannelVMT
*
* @brief @p BaseAsynchronousChannel virtual methods table. * @brief @p BaseAsynchronousChannel virtual methods table.
*/ */
struct BaseAsynchronousChannelVMT { struct BaseAsynchronousChannelVMT {
@ -286,6 +299,10 @@ typedef struct {
_base_asynchronous_channel_data _base_asynchronous_channel_data
} BaseAsynchronousChannel; } BaseAsynchronousChannel;
/**
* @name Macro Functions (BaseAsynchronousChannel)
* @{
*/
/** /**
* @brief Returns the I/O condition event source. * @brief Returns the I/O condition event source.
* @details The event source is broadcasted when an I/O condition happens. * @details The event source is broadcasted when an I/O condition happens.
@ -299,7 +316,7 @@ typedef struct {
#define chIOGetEventSource(ip) (&((ip)->event)) #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 * @details This function is usually called from the I/O ISTs in order to
* notify I/O conditions such as data events, errors, signal * notify I/O conditions such as data events, errors, signal
* changes etc. * 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 * @param[in] ip pointer to a @p BaseAsynchronousChannel or derived
* class * class
@ -326,6 +343,7 @@ typedef struct {
* @api * @api
*/ */
#define chIOGetAndClearFlags(ip) ((ip)->vmt->getflags(ip)) #define chIOGetAndClearFlags(ip) ((ip)->vmt->getflags(ip))
/** @} */
/** /**
* @brief Default implementation of the @p getflags virtual method. * @brief Default implementation of the @p getflags virtual method.

View File

@ -72,6 +72,10 @@ extern "C" {
} }
#endif #endif
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Returns the mailbox buffer size. * @brief Returns the mailbox buffer size.
* *
@ -120,6 +124,7 @@ extern "C" {
* @iclass * @iclass
*/ */
#define chMBPeekI(mbp) (*(mbp)->mb_rdptr) #define chMBPeekI(mbp) (*(mbp)->mb_rdptr)
/** @} */
/** /**
* @brief Data part of a static mailbox initializer. * @brief Data part of a static mailbox initializer.

View File

@ -36,6 +36,9 @@
*/ */
typedef void *(*memgetfunc_t)(size_t size); typedef void *(*memgetfunc_t)(size_t size);
/**
* @name Alignment support macros
*/
/** /**
* @brief Alignment size constant. * @brief Alignment size constant.
*/ */
@ -61,6 +64,7 @@ typedef void *(*memgetfunc_t)(size_t size);
* the type @p align_t. * the type @p align_t.
*/ */
#define MEM_IS_ALIGNED(p) (((size_t)(p) & MEM_ALIGN_MASK) == 0) #define MEM_IS_ALIGNED(p) (((size_t)(p) & MEM_ALIGN_MASK) == 0)
/** @} */
#if CH_USE_MEMCORE || defined(__DOXYGEN__) #if CH_USE_MEMCORE || defined(__DOXYGEN__)

View File

@ -31,6 +31,10 @@
#if CH_USE_MESSAGES || defined(__DOXYGEN__) #if CH_USE_MESSAGES || defined(__DOXYGEN__)
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Evaluates to TRUE if the thread has pending messages. * @brief Evaluates to TRUE if the thread has pending messages.
* *
@ -74,6 +78,7 @@
* @sclass * @sclass
*/ */
#define chMsgReleaseS(tp, msg) chSchWakeupS(tp, msg) #define chMsgReleaseS(tp, msg) chSchWakeupS(tp, msg)
/** @} */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@ -76,6 +76,10 @@ extern "C" {
*/ */
#define MUTEX_DECL(name) Mutex name = _MUTEX_DATA(name) #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 * @brief Returns @p TRUE if the mutex queue contains at least a waiting
* thread. * thread.
@ -83,6 +87,7 @@ extern "C" {
* @sclass * @sclass
*/ */
#define chMtxQueueNotEmptyS(mp) notempty(&(mp)->m_queue) #define chMtxQueueNotEmptyS(mp) notempty(&(mp)->m_queue)
/** @} */
#endif /* CH_USE_MUTEXES */ #endif /* CH_USE_MUTEXES */

View File

@ -31,16 +31,16 @@
#if CH_USE_QUEUES || defined(__DOXYGEN__) #if CH_USE_QUEUES || defined(__DOXYGEN__)
/** @brief Returned by the queue functions if the operation is successful.*/ /**
#define Q_OK RDY_OK * @name Queue functions returned status value
/** @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_OK RDY_OK /**< @brief Operation successful. */
#define Q_RESET RDY_RESET #define Q_TIMEOUT RDY_TIMEOUT /**< @brief Timeout condition. */
/** @brief Returned by the queue functions if the queue is empty.*/ #define Q_RESET RDY_RESET /**< @brief Queue has been reset. */
#define Q_EMPTY -3 #define Q_EMPTY -3 /**< @brief Queue empty. */
/** @brief Returned by the queue functions if the queue is full.*/ #define Q_FULL -4 /**< @brief Queue full, */
#define Q_FULL -4 /** @} */
/** /**
* @brief Type of a generic I/O queue structure. * @brief Type of a generic I/O queue structure.
@ -70,6 +70,10 @@ struct GenericQueue {
qnotify_t q_notify; /**< @brief Data notification callback. */ qnotify_t q_notify; /**< @brief Data notification callback. */
}; };
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Returns the queue's buffer size. * @brief Returns the queue's buffer size.
* *
@ -90,7 +94,8 @@ struct GenericQueue {
* *
* @iclass * @iclass
*/ */
#define chQSpaceI(qp) ((size_t)((qp)->q_counter)) #define chQSpaceI(qp) ((qp)->q_counter)
/** @} */
/** /**
* @extends GenericQueue * @extends GenericQueue
@ -105,6 +110,10 @@ struct GenericQueue {
*/ */
typedef GenericQueue InputQueue; typedef GenericQueue InputQueue;
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Returns the filled space into an input queue. * @brief Returns the filled space into an input queue.
* *
@ -165,6 +174,7 @@ typedef GenericQueue InputQueue;
* @api * @api
*/ */
#define chIQGet(iqp) chIQGetTimeout(iqp, TIME_INFINITE) #define chIQGet(iqp) chIQGetTimeout(iqp, TIME_INFINITE)
/** @} */
/** /**
* @brief Data part of a static input queue initializer. * @brief Data part of a static input queue initializer.
@ -212,6 +222,10 @@ typedef GenericQueue InputQueue;
*/ */
typedef GenericQueue OutputQueue; typedef GenericQueue OutputQueue;
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Returns the filled space into an output queue. * @brief Returns the filled space into an output queue.
* *
@ -274,6 +288,7 @@ typedef GenericQueue OutputQueue;
* @api * @api
*/ */
#define chOQPut(oqp, b) chOQPutTimeout(oqp, b, TIME_INFINITE) #define chOQPut(oqp, b) chOQPutTimeout(oqp, b, TIME_INFINITE)
/** @} */
/** /**
* @brief Data part of a static output queue initializer. * @brief Data part of a static output queue initializer.

View File

@ -30,6 +30,10 @@
#define _CHREGISTRY_H_ #define _CHREGISTRY_H_
#if CH_USE_REGISTRY || defined(__DOXYGEN__) #if CH_USE_REGISTRY || defined(__DOXYGEN__)
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Sets the current thread name. * @brief Sets the current thread name.
* @pre This function only stores the pointer to the name if the option * @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. * @retval NULL if the thread name has not been set.
*/ */
#define chRegGetThreadName(tp) ((tp)->p_name) #define chRegGetThreadName(tp) ((tp)->p_name)
/** @} */
#else /* !CH_USE_REGISTRY */ #else /* !CH_USE_REGISTRY */
#define chRegSetThreadName(p) #define chRegSetThreadName(p)
#define chRegGetThreadName(tp) NULL #define chRegGetThreadName(tp) NULL
#endif /* !CH_USE_REGISTRY */ #endif /* !CH_USE_REGISTRY */
#if CH_USE_REGISTRY || defined(__DOXYGEN__) #if CH_USE_REGISTRY || defined(__DOXYGEN__)
/** /**
* @brief Removes a thread from the registry list. * @brief Removes a thread from the registry list.
* @note This macro is not meant for use in application code. * @note This macro is not meant for use in application code.

View File

@ -29,22 +29,35 @@
#ifndef _CHSCHD_H_ #ifndef _CHSCHD_H_
#define _CHSCHD_H_ #define _CHSCHD_H_
/** @brief Default thread wakeup low level message.*/ /**
#define RDY_OK 0 * @name Wakeup status codes
/** @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_OK 0 /**< @brief Normal wakeup message. */
#define RDY_RESET -2 #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 NOPRIO 0 /**< @brief Ready list header priority. */
#define IDLEPRIO 1 /**< @brief Idle thread priority. */ #define IDLEPRIO 1 /**< @brief Idle thread priority. */
#define LOWPRIO 2 /**< @brief Lowest user priority. */ #define LOWPRIO 2 /**< @brief Lowest user priority. */
#define NORMALPRIO 64 /**< @brief Normal user priority. */ #define NORMALPRIO 64 /**< @brief Normal user priority. */
#define HIGHPRIO 127 /**< @brief Highest user priority. */ #define HIGHPRIO 127 /**< @brief Highest user priority. */
#define ABSPRIO 255 /**< @brief Greatest possible 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. * specification.
* @note Not all functions accept @p TIME_IMMEDIATE as timeout parameter, * @note Not all functions accept @p TIME_IMMEDIATE as timeout parameter,
* see the specific function documentation. * see the specific function documentation.
@ -52,10 +65,11 @@
#define TIME_IMMEDIATE ((systime_t)0) #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. * specification.
*/ */
#define TIME_INFINITE ((systime_t)-1) #define TIME_INFINITE ((systime_t)-1)
/** @} */
/** /**
* @brief Returns the priority of the first thread on the given ready list. * @brief Returns the priority of the first thread on the given ready list.
@ -147,6 +161,10 @@ extern "C" {
} }
#endif #endif
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Determines if the current thread must reschedule. * @brief Determines if the current thread must reschedule.
* @details This function returns @p TRUE if there is a ready thread with * @details This function returns @p TRUE if there is a ready thread with
@ -209,6 +227,7 @@ extern "C" {
chSchDoReschedule(); \ chSchDoReschedule(); \
} }
#endif /* CH_TIME_QUANTUM == 0 */ #endif /* CH_TIME_QUANTUM == 0 */
/** @} */
#endif /* _CHSCHD_H_ */ #endif /* _CHSCHD_H_ */

View File

@ -82,6 +82,10 @@ extern "C" {
*/ */
#define SEMAPHORE_DECL(name, n) Semaphore name = _SEMAPHORE_DATA(name, n) #define SEMAPHORE_DECL(name, n) Semaphore name = _SEMAPHORE_DATA(name, n)
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Decreases the semaphore counter. * @brief Decreases the semaphore counter.
* @details This macro can be used when the counter is known to be positive. * @details This macro can be used when the counter is known to be positive.
@ -105,6 +109,7 @@ extern "C" {
* @iclass * @iclass
*/ */
#define chSemGetCounterI(sp) ((sp)->s_cnt) #define chSemGetCounterI(sp) ((sp)->s_cnt)
/** @} */
#endif /* CH_USE_SEMAPHORES */ #endif /* CH_USE_SEMAPHORES */

View File

@ -73,6 +73,10 @@ typedef struct {
_base_sequential_stream_data _base_sequential_stream_data
} BaseSequentialStream; } BaseSequentialStream;
/**
* @name Macro Functions (BaseSequentialStream)
* @{
*/
/** /**
* @brief Sequential Stream write. * @brief Sequential Stream write.
* @details The function writes data from a buffer to a stream. * @details The function writes data from a buffer to a stream.
@ -103,6 +107,7 @@ typedef struct {
* @api * @api
*/ */
#define chSequentialStreamRead(ip, bp, n) ((ip)->vmt->read(ip, bp, n)) #define chSequentialStreamRead(ip, bp, n) ((ip)->vmt->read(ip, bp, n))
/** @} */
#endif /* _CHSTREAMS_H_ */ #endif /* _CHSTREAMS_H_ */

View File

@ -29,6 +29,10 @@
#ifndef _CHSYS_H_ #ifndef _CHSYS_H_
#define _CHSYS_H_ #define _CHSYS_H_
/**
* @name Macro Functions
* @{
*/
#if !CH_NO_IDLE_THREAD || defined(__DOXYGEN__) #if !CH_NO_IDLE_THREAD || defined(__DOXYGEN__)
/** /**
* @brief Returns a pointer to the idle thread. * @brief Returns a pointer to the idle thread.
@ -177,7 +181,11 @@
dbg_check_unlock_from_isr(); \ dbg_check_unlock_from_isr(); \
port_unlock_from_isr(); \ port_unlock_from_isr(); \
} }
/** @} */
/**
* @name ISRs abstraction macros
*/
/** /**
* @brief IRQ handler enter code. * @brief IRQ handler enter code.
* @note Usually IRQ handlers functions are also declared naked. * @note Usually IRQ handlers functions are also declared naked.
@ -211,7 +219,11 @@
* @special * @special
*/ */
#define CH_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id) #define CH_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id)
/** @} */
/**
* @name Fast ISRs abstraction macros
*/
/** /**
* @brief Standard fast IRQ handler declaration. * @brief Standard fast IRQ handler declaration.
* @note @p id can be a function name or a vector number depending on the * @note @p id can be a function name or a vector number depending on the
@ -221,6 +233,7 @@
* @special * @special
*/ */
#define CH_FAST_IRQ_HANDLER(id) PORT_FAST_IRQ_HANDLER(id) #define CH_FAST_IRQ_HANDLER(id) PORT_FAST_IRQ_HANDLER(id)
/** @} */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@ -29,6 +29,43 @@
#ifndef _CHTHREADS_H_ #ifndef _CHTHREADS_H_
#define _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 * @extends ThreadsQueue
* *
@ -163,51 +200,15 @@ struct Thread {
#endif #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. * @brief Thread function.
*/ */
typedef msg_t (*tfunc_t)(void *); typedef msg_t (*tfunc_t)(void *);
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Returns a pointer to the current @p Thread. * @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) #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 * @param[in] tp pointer to the thread
* *
@ -321,6 +322,7 @@ typedef msg_t (*tfunc_t)(void *);
* @api * @api
*/ */
#define chThdSleepMicroseconds(usec) chThdSleep(US2ST(usec)) #define chThdSleepMicroseconds(usec) chThdSleep(US2ST(usec))
/** @} */
/* /*
* Threads APIs. * Threads APIs.

View File

@ -30,25 +30,30 @@
#define _CHVT_H_ #define _CHVT_H_
/** /**
* @brief Time conversion utility. * @name Time conversion utilities
* @{
*/
/**
* @brief Seconds to system ticks.
* @details Converts from seconds to system ticks number. * @details Converts from seconds to system ticks number.
* @note The result is rounded upward to the next tick boundary. * @note The result is rounded upward to the next tick boundary.
*/ */
#define S2ST(sec) ((systime_t)((sec) * CH_FREQUENCY)) #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. * @details Converts from milliseconds to system ticks number.
* @note The result is rounded upward to the next tick boundary. * @note The result is rounded upward to the next tick boundary.
*/ */
#define MS2ST(msec) ((systime_t)(((((msec) - 1L) * CH_FREQUENCY) / 1000L) + 1L)) #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. * @details Converts from microseconds to system ticks number.
* @note The result is rounded upward to the next tick boundary. * @note The result is rounded upward to the next tick boundary.
*/ */
#define US2ST(usec) ((systime_t)(((((usec) - 1L) * CH_FREQUENCY) / 1000000L) + 1L)) #define US2ST(usec) ((systime_t)(((((usec) - 1L) * CH_FREQUENCY) / 1000000L) + 1L))
/** @} */
/** /**
* @brief Virtual Timer callback function. * @brief Virtual Timer callback function.
@ -94,6 +99,10 @@ typedef struct {
extern VTList vtlist; extern VTList vtlist;
/**
* @name Macro Functions
* @{
*/
/** /**
* @brief Virtual timers ticker. * @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. * @brief Returns TRUE if the speciified timer is armed.
* *
@ -148,6 +143,21 @@ extern "C" {
* @api * @api
*/ */
#define chTimeNow() (vtlist.vt_systime) #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_ */ #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 * @pre Invoke this function only after a message has been received
* using @p chMsgWait(). * using @p chMsgWait().
* *

View File

@ -80,9 +80,6 @@ Thread *_thread_init(Thread *tp, tprio_t prio) {
#if CH_USE_EVENTS #if CH_USE_EVENTS
tp->p_epending = 0; tp->p_epending = 0;
#endif #endif
#if CH_USE_NESTED_LOCKS
tp->p_locks = 0;
#endif
#if CH_DBG_THREADS_PROFILING #if CH_DBG_THREADS_PROFILING
tp->p_time = 0; tp->p_time = 0;
#endif #endif

View File

@ -32,6 +32,10 @@
#include <avr/io.h> #include <avr/io.h>
#include <avr/interrupt.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. * @brief If enabled allows the idle thread to enter a low power mode.
*/ */

View File

@ -32,6 +32,10 @@
#include <iomacros.h> #include <iomacros.h>
#include <msp430/common.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. * @brief Enables the use of a wait state in the idle thread loop.
*/ */

View File

@ -29,6 +29,10 @@
#ifndef _CHCORE_H_ #ifndef _CHCORE_H_
#define _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. * Port-related configuration parameters.
*/ */

View File

@ -26,6 +26,10 @@
#ifndef _CHCORE_H_ #ifndef _CHCORE_H_
#define _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. * Macro defining the a simulated architecture into x86.
*/ */

View File

@ -31,6 +31,10 @@
#include <intrins.h> #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. */ /* Port configurable parameters. */
/*===========================================================================*/ /*===========================================================================*/

View File

@ -29,6 +29,10 @@
#ifndef _CHCORE_H_ #ifndef _CHCORE_H_
#define _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. */ /* Port configurable parameters. */
/*===========================================================================*/ /*===========================================================================*/

View File

@ -89,6 +89,16 @@
(backported to 2.2.4). (backported to 2.2.4).
- FIX: Fixed timeout problem in the lwIP interface layer (bug 3302420) - FIX: Fixed timeout problem in the lwIP interface layer (bug 3302420)
(backported to 2.2.4). (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: Integrated new FatFs version 0.8b.
- NEW: Added a new hook THREAD_CONTEXT_SWITCH_HOOK() that allows to insert - 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 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. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__) #if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__)
#define CH_DBG_SYSTEM_STATE_CHECK FALSE #define CH_DBG_SYSTEM_STATE_CHECK TRUE
#endif #endif
/** /**
@ -372,7 +372,7 @@
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_CHECKS FALSE #define CH_DBG_ENABLE_CHECKS TRUE
#endif #endif
/** /**
@ -384,7 +384,7 @@
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_ASSERTS FALSE #define CH_DBG_ENABLE_ASSERTS TRUE
#endif #endif
/** /**
@ -395,7 +395,7 @@
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_TRACE FALSE #define CH_DBG_ENABLE_TRACE TRUE
#endif #endif
/** /**
@ -409,7 +409,7 @@
* @p panic_msg variable set to @p NULL. * @p panic_msg variable set to @p NULL.
*/ */
#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_STACK_CHECK FALSE #define CH_DBG_ENABLE_STACK_CHECK TRUE
#endif #endif
/** /**
@ -421,7 +421,7 @@
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__) #if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
#define CH_DBG_FILL_THREADS FALSE #define CH_DBG_FILL_THREADS TRUE
#endif #endif
/** /**

View File

@ -361,7 +361,7 @@
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__) #if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__)
#define CH_DBG_SYSTEM_STATE_CHECK FALSE #define CH_DBG_SYSTEM_STATE_CHECK TRUE
#endif #endif
/** /**
@ -372,7 +372,7 @@
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_CHECKS FALSE #define CH_DBG_ENABLE_CHECKS TRUE
#endif #endif
/** /**
@ -384,7 +384,7 @@
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_ASSERTS FALSE #define CH_DBG_ENABLE_ASSERTS TRUE
#endif #endif
/** /**
@ -395,7 +395,7 @@
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_TRACE FALSE #define CH_DBG_ENABLE_TRACE TRUE
#endif #endif
/** /**
@ -409,7 +409,7 @@
* @p panic_msg variable set to @p NULL. * @p panic_msg variable set to @p NULL.
*/ */
#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_STACK_CHECK FALSE #define CH_DBG_ENABLE_STACK_CHECK TRUE
#endif #endif
/** /**
@ -421,7 +421,7 @@
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__) #if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
#define CH_DBG_FILL_THREADS FALSE #define CH_DBG_FILL_THREADS TRUE
#endif #endif
/** /**

View File

@ -361,7 +361,7 @@
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__) #if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__)
#define CH_DBG_SYSTEM_STATE_CHECK FALSE #define CH_DBG_SYSTEM_STATE_CHECK TRUE
#endif #endif
/** /**
@ -372,7 +372,7 @@
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_CHECKS FALSE #define CH_DBG_ENABLE_CHECKS TRUE
#endif #endif
/** /**
@ -384,7 +384,7 @@
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_ASSERTS FALSE #define CH_DBG_ENABLE_ASSERTS TRUE
#endif #endif
/** /**
@ -395,7 +395,7 @@
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_TRACE FALSE #define CH_DBG_ENABLE_TRACE TRUE
#endif #endif
/** /**
@ -409,7 +409,7 @@
* @p panic_msg variable set to @p NULL. * @p panic_msg variable set to @p NULL.
*/ */
#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_STACK_CHECK FALSE #define CH_DBG_ENABLE_STACK_CHECK TRUE
#endif #endif
/** /**
@ -421,7 +421,7 @@
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__) #if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
#define CH_DBG_FILL_THREADS FALSE #define CH_DBG_FILL_THREADS TRUE
#endif #endif
/** /**

View File

@ -127,7 +127,7 @@
* SPI driver system settings. * SPI driver system settings.
*/ */
#define STM32_SPI_USE_SPI1 TRUE #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_USE_SPI3 FALSE
#define STM32_SPI_SPI1_DMA_PRIORITY 1 #define STM32_SPI_SPI1_DMA_PRIORITY 1
#define STM32_SPI_SPI2_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