From 4e35a12a2a84afa813bf619df3bbb8146b98a973 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 20 Aug 2011 14:25:49 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3243 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chthreads.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 19accdb55..46039561b 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -80,9 +80,6 @@ Thread *_thread_init(Thread *tp, tprio_t prio) { #if CH_USE_EVENTS tp->p_epending = 0; #endif -#if CH_USE_NESTED_LOCKS - tp->p_locks = 0; -#endif #if CH_DBG_THREADS_PROFILING tp->p_time = 0; #endif -- cgit v1.2.3 From f23670b728189b4549091d355e38218b31c0a0ad Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 21 Aug 2011 13:19:48 +0000 Subject: Added I-class function checks to HAL APIs. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3244 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/src/adc.c | 6 ++++-- os/hal/src/gpt.c | 10 ++++++++++ os/hal/src/icu.c | 4 ++++ os/hal/src/serial.c | 2 ++ os/hal/src/uart.c | 10 ++++++---- os/hal/src/usb.c | 22 ++++++++++++++++++++++ 6 files changed, 48 insertions(+), 6 deletions(-) diff --git a/os/hal/src/adc.c b/os/hal/src/adc.c index 4843ca90b..f2bf4eadd 100644 --- a/os/hal/src/adc.c +++ b/os/hal/src/adc.c @@ -176,13 +176,14 @@ void adcStartConversionI(ADCDriver *adcp, adcsample_t *samples, size_t depth) { + chDbgCheckClassI(); chDbgCheck((adcp != NULL) && (grpp != NULL) && (samples != NULL) && ((depth == 1) || ((depth & 1) == 0)), "adcStartConversionI"); - chDbgAssert((adcp->state == ADC_READY) || (adcp->state == ADC_COMPLETE), "adcStartConversionI(), #1", "not ready"); + adcp->samples = samples; adcp->depth = depth; adcp->grpp = grpp; @@ -229,12 +230,13 @@ void adcStopConversion(ADCDriver *adcp) { */ void adcStopConversionI(ADCDriver *adcp) { + chDbgCheckClassI(); chDbgCheck(adcp != NULL, "adcStopConversionI"); - chDbgAssert((adcp->state == ADC_READY) || (adcp->state == ADC_ACTIVE) || (adcp->state == ADC_COMPLETE), "adcStopConversionI(), #1", "invalid state"); + if (adcp->state != ADC_READY) { adc_lld_stop_conversion(adcp); adcp->grpp = NULL; diff --git a/os/hal/src/gpt.c b/os/hal/src/gpt.c index e90a8911a..5f424453d 100644 --- a/os/hal/src/gpt.c +++ b/os/hal/src/gpt.c @@ -137,8 +137,11 @@ void gptStartContinuous(GPTDriver *gptp, gptcnt_t interval) { */ void gptStartContinuousI(GPTDriver *gptp, gptcnt_t interval) { + chDbgCheckClassI(); + chDbgCheck(gptp != NULL, "gptStartContinuousI"); chDbgAssert(gptp->state == GPT_READY, "gptStartContinuousI(), #1", "invalid state"); + gptp->state = GPT_CONTINUOUS; gpt_lld_start_timer(gptp, interval); } @@ -168,8 +171,11 @@ void gptStartOneShot(GPTDriver *gptp, gptcnt_t interval) { */ void gptStartOneShotI(GPTDriver *gptp, gptcnt_t interval) { + chDbgCheckClassI(); + chDbgCheck(gptp != NULL, "gptStartOneShotI"); chDbgAssert(gptp->state == GPT_READY, "gptStartOneShotI(), #1", "invalid state"); + gptp->state = GPT_ONESHOT; gpt_lld_start_timer(gptp, interval); } @@ -197,9 +203,12 @@ void gptStopTimer(GPTDriver *gptp) { */ void gptStopTimerI(GPTDriver *gptp) { + chDbgCheckClassI(); + chDbgCheck(gptp != NULL, "gptStopTimerI"); chDbgAssert((gptp->state == GPT_READY) || (gptp->state == GPT_CONTINUOUS) || (gptp->state == GPT_ONESHOT), "gptStopTimerI(), #1", "invalid state"); + gptp->state = GPT_READY; gpt_lld_stop_timer(gptp); } @@ -220,6 +229,7 @@ void gptPolledDelay(GPTDriver *gptp, gptcnt_t interval) { chDbgAssert(gptp->state == GPT_READY, "gptPolledDelay(), #1", "invalid state"); + gptp->state = GPT_ONESHOT; gpt_lld_polled_delay(gptp, interval); } diff --git a/os/hal/src/icu.c b/os/hal/src/icu.c index 3be67448e..79d38798e 100644 --- a/os/hal/src/icu.c +++ b/os/hal/src/icu.c @@ -121,6 +121,8 @@ void icuStop(ICUDriver *icup) { */ void icuEnable(ICUDriver *icup) { + chDbgCheck(icup != NULL, "icuEnable"); + chSysLock(); chDbgAssert(icup->state == ICU_READY, "icuEnable(), #1", "invalid state"); icu_lld_enable(icup); @@ -137,6 +139,8 @@ void icuEnable(ICUDriver *icup) { */ void icuDisable(ICUDriver *icup) { + chDbgCheck(icup != NULL, "icuDisable"); + chSysLock(); chDbgAssert((icup->state == ICU_READY) || (icup->state == ICU_WAITING) || (icup->state == ICU_ACTIVE) || (icup->state == ICU_IDLE), diff --git a/os/hal/src/serial.c b/os/hal/src/serial.c index 414689aac..03b74be54 100644 --- a/os/hal/src/serial.c +++ b/os/hal/src/serial.c @@ -207,6 +207,7 @@ void sdStop(SerialDriver *sdp) { */ void sdIncomingDataI(SerialDriver *sdp, uint8_t b) { + chDbgCheckClassI(); chDbgCheck(sdp != NULL, "sdIncomingDataI"); if (chIQIsEmptyI(&sdp->iqueue)) @@ -233,6 +234,7 @@ void sdIncomingDataI(SerialDriver *sdp, uint8_t b) { msg_t sdRequestDataI(SerialDriver *sdp) { msg_t b; + chDbgCheckClassI(); chDbgCheck(sdp != NULL, "sdRequestDataI"); b = chOQGetI(&sdp->oqueue); diff --git a/os/hal/src/uart.c b/os/hal/src/uart.c index 05fdbb168..372a3ad02 100644 --- a/os/hal/src/uart.c +++ b/os/hal/src/uart.c @@ -161,12 +161,13 @@ void uartStartSend(UARTDriver *uartp, size_t n, const void *txbuf) { */ void uartStartSendI(UARTDriver *uartp, size_t n, const void *txbuf) { + chDbgCheckClassI(); chDbgCheck((uartp != NULL) && (n > 0) && (txbuf != NULL), "uartStartSendI"); - chDbgAssert((uartp->state == UART_READY) && (uartp->txstate != UART_TX_ACTIVE), "uartStartSendI(), #1", "not active"); + uart_lld_start_send(uartp, n, txbuf); uartp->txstate = UART_TX_ACTIVE; } @@ -216,8 +217,8 @@ size_t uartStopSend(UARTDriver *uartp) { */ size_t uartStopSendI(UARTDriver *uartp) { + chDbgCheckClassI(); chDbgCheck(uartp != NULL, "uartStopSendI"); - chDbgAssert(uartp->state == UART_READY, "uartStopSendI(), #1", "not active"); if (uartp->txstate == UART_TX_ACTIVE) { @@ -267,9 +268,9 @@ void uartStartReceive(UARTDriver *uartp, size_t n, void *rxbuf) { */ void uartStartReceiveI(UARTDriver *uartp, size_t n, void *rxbuf) { + chDbgCheckClassI(); chDbgCheck((uartp != NULL) && (n > 0) && (rxbuf != NULL), "uartStartReceiveI"); - chDbgAssert((uartp->state == UART_READY) && (uartp->rxstate == UART_RX_IDLE), "uartStartReceiveI(), #1", "not active"); @@ -322,8 +323,9 @@ size_t uartStopReceive(UARTDriver *uartp) { * @iclass */ size_t uartStopReceiveI(UARTDriver *uartp) { - chDbgCheck(uartp != NULL, "uartStopReceiveI"); + chDbgCheckClassI(); + chDbgCheck(uartp != NULL, "uartStopReceiveI"); chDbgAssert(uartp->state == UART_READY, "uartStopReceiveI(), #1", "not active"); diff --git a/os/hal/src/usb.c b/os/hal/src/usb.c index 484590f3b..8493b6f41 100644 --- a/os/hal/src/usb.c +++ b/os/hal/src/usb.c @@ -301,6 +301,8 @@ void usbStop(USBDriver *usbp) { void usbInitEndpointI(USBDriver *usbp, usbep_t ep, const USBEndpointConfig *epcp) { + chDbgCheckClassI(); + chDbgCheck((usbp != NULL) && (epcp != NULL), "usbInitEndpointI"); chDbgAssert(usbp->state == USB_ACTIVE, "usbEnableEndpointI(), #1", "invalid state"); chDbgAssert(usbp->epc[ep] != NULL, @@ -331,6 +333,8 @@ void usbInitEndpointI(USBDriver *usbp, usbep_t ep, void usbDisableEndpointsI(USBDriver *usbp) { unsigned i; + chDbgCheckClassI(); + chDbgCheck(usbp != NULL, "usbDisableEndpointsI"); chDbgAssert(usbp->state == USB_SELECTED, "usbDisableEndpointsI(), #1", "invalid state"); @@ -364,6 +368,9 @@ void usbDisableEndpointsI(USBDriver *usbp) { size_t usbReadPacketI(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) { + chDbgCheckClassI(); + chDbgCheck((usbp != NULL) && (buf != NULL), "usbReadPacketI"); + if (usbGetReceiveStatusI(usbp, ep)) return USB_ENDPOINT_BUSY; @@ -391,6 +398,9 @@ size_t usbReadPacketI(USBDriver *usbp, usbep_t ep, size_t usbWritePacketI(USBDriver *usbp, usbep_t ep, const uint8_t *buf, size_t n) { + chDbgCheckClassI(); + chDbgCheck((usbp != NULL) && (buf != NULL), "usbWritePacketI"); + if (usbGetTransmitStatusI(usbp, ep)) return USB_ENDPOINT_BUSY; @@ -419,6 +429,9 @@ size_t usbWritePacketI(USBDriver *usbp, usbep_t ep, bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) { + chDbgCheckClassI(); + chDbgCheck((usbp != NULL) && (buf != NULL), "usbStartReceiveI"); + if (usbGetReceiveStatusI(usbp, ep)) return TRUE; @@ -447,6 +460,9 @@ bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep, bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep, const uint8_t *buf, size_t n) { + chDbgCheckClassI(); + chDbgCheck((usbp != NULL) && (buf != NULL), "usbStartTransmitI"); + if (usbGetTransmitStatusI(usbp, ep)) return TRUE; @@ -468,6 +484,9 @@ bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep, */ bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep) { + chDbgCheckClassI(); + chDbgCheck(usbp != NULL, "usbStallReceiveI"); + if (usbGetReceiveStatusI(usbp, ep)) return TRUE; @@ -488,6 +507,9 @@ bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep) { */ bool_t usbStallTransmitI(USBDriver *usbp, usbep_t ep) { + chDbgCheckClassI(); + chDbgCheck(usbp != NULL, "usbStallTransmitI"); + if (usbGetTransmitStatusI(usbp, ep)) return TRUE; -- cgit v1.2.3 From 24cad7ea0d6f06d892fd10c49fea06a7dde50fb9 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 22 Aug 2011 08:31:32 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3245 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARMCM3-GENERIC-KERNEL/Makefile | 192 ++++++++++++ demos/ARMCM3-GENERIC-KERNEL/chconf.h | 535 +++++++++++++++++++++++++++++++++ demos/ARMCM3-GENERIC-KERNEL/main.c | 83 +++++ demos/ARMCM3-GENERIC-KERNEL/readme.txt | 14 + readme.txt | 5 + todo.txt | 2 +- 6 files changed, 830 insertions(+), 1 deletion(-) create mode 100644 demos/ARMCM3-GENERIC-KERNEL/Makefile create mode 100644 demos/ARMCM3-GENERIC-KERNEL/chconf.h create mode 100644 demos/ARMCM3-GENERIC-KERNEL/main.c create mode 100644 demos/ARMCM3-GENERIC-KERNEL/readme.txt diff --git a/demos/ARMCM3-GENERIC-KERNEL/Makefile b/demos/ARMCM3-GENERIC-KERNEL/Makefile new file mode 100644 index 000000000..358d3474e --- /dev/null +++ b/demos/ARMCM3-GENERIC-KERNEL/Makefile @@ -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 diff --git a/demos/ARMCM3-GENERIC-KERNEL/chconf.h b/demos/ARMCM3-GENERIC-KERNEL/chconf.h new file mode 100644 index 000000000..a5d129956 --- /dev/null +++ b/demos/ARMCM3-GENERIC-KERNEL/chconf.h @@ -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 . +*/ + +/** + * @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 TRUE +#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 TRUE +#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 TRUE +#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 TRUE +#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 TRUE +#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 TRUE +#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_ */ + +/** @} */ diff --git a/demos/ARMCM3-GENERIC-KERNEL/main.c b/demos/ARMCM3-GENERIC-KERNEL/main.c new file mode 100644 index 000000000..deaab87d6 --- /dev/null +++ b/demos/ARMCM3-GENERIC-KERNEL/main.c @@ -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 . + + --- + + 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++; + } +} diff --git a/demos/ARMCM3-GENERIC-KERNEL/readme.txt b/demos/ARMCM3-GENERIC-KERNEL/readme.txt new file mode 100644 index 000000000..0c13627af --- /dev/null +++ b/demos/ARMCM3-GENERIC-KERNEL/readme.txt @@ -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. diff --git a/readme.txt b/readme.txt index 8de57cda7..ed9718089 100644 --- a/readme.txt +++ b/readme.txt @@ -89,6 +89,11 @@ (backported to 2.2.4). - FIX: Fixed timeout problem in the lwIP interface layer (bug 3302420) (backported to 2.2.4). +- NEW: Added a kernel-only Cortex-Mx demo as reference project for users not + interested in the HAL but just want to use the ChibiOS/RT kernel. + The demo is named ARMCM3-GENERIC-KERNEL and is defaulted to the STM32, in + order to use it on other families or on the ARM Cortex-M0 just change the + inclusion paths in the makefile. - NEW: Integrated new FatFs version 0.8b. - NEW: Added a new hook THREAD_CONTEXT_SWITCH_HOOK() that allows to insert code just before a context switch. For example this hook could be used diff --git a/todo.txt b/todo.txt index 8b2823a77..4cd406b16 100644 --- a/todo.txt +++ b/todo.txt @@ -13,6 +13,7 @@ Current Pipeline (2.3.x): * Move main stack to low memory in ARMCMx ports. * Eclipse plugin. * FatFs 0.8x integration. +* Kernel-only demo for users not interested in HAL (Cortex-Mx only). X STM32L support. X STM32L-Discovery demo and article. X File System infrastructure. @@ -26,7 +27,6 @@ X Implement the "transmission end" serial driver event on those platforms X I2C device driver class support and at least one implementation. - Reduce number of demos globally, add demos to a repository or on web site. Required in order to reduce support effort. -- Kernel-only demos for users not interested in HAL. - Add a CH_THREAD macro for threads declaration in order to hide compiler-specific optimizations for thread functions. All demos will have to be updated. -- cgit v1.2.3 From 151d1b7da5e6d5320cbf5d74e2e5da693108e1d9 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 22 Aug 2011 08:35:06 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3246 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARMCM3-GENERIC-KERNEL/chconf.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/demos/ARMCM3-GENERIC-KERNEL/chconf.h b/demos/ARMCM3-GENERIC-KERNEL/chconf.h index a5d129956..9dd831c96 100644 --- a/demos/ARMCM3-GENERIC-KERNEL/chconf.h +++ b/demos/ARMCM3-GENERIC-KERNEL/chconf.h @@ -361,7 +361,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_SYSTEM_STATE_CHECK TRUE +#define CH_DBG_SYSTEM_STATE_CHECK FALSE #endif /** @@ -372,7 +372,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_CHECKS TRUE +#define CH_DBG_ENABLE_CHECKS FALSE #endif /** @@ -384,7 +384,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_ASSERTS TRUE +#define CH_DBG_ENABLE_ASSERTS FALSE #endif /** @@ -395,7 +395,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_TRACE TRUE +#define CH_DBG_ENABLE_TRACE FALSE #endif /** @@ -409,7 +409,7 @@ * @p panic_msg variable set to @p NULL. */ #if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_STACK_CHECK TRUE +#define CH_DBG_ENABLE_STACK_CHECK FALSE #endif /** @@ -421,7 +421,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__) -#define CH_DBG_FILL_THREADS TRUE +#define CH_DBG_FILL_THREADS FALSE #endif /** -- cgit v1.2.3 From 334ee6970801e8b72f8a36daa3d42acda56ec15e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 22 Aug 2011 08:40:34 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3247 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/ports/GCC/AVR/chcore.h | 4 ++++ os/ports/GCC/MSP430/chcore.h | 4 ++++ os/ports/GCC/PPC/chcore.h | 4 ++++ os/ports/GCC/SIMIA32/chcore.h | 4 ++++ os/ports/RC/STM8/chcore.h | 4 ++++ os/ports/cosmic/STM8/chcore.h | 4 ++++ readme.txt | 2 ++ 7 files changed, 26 insertions(+) diff --git a/os/ports/GCC/AVR/chcore.h b/os/ports/GCC/AVR/chcore.h index 744502825..282ec5a16 100644 --- a/os/ports/GCC/AVR/chcore.h +++ b/os/ports/GCC/AVR/chcore.h @@ -32,6 +32,10 @@ #include #include +#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. */ diff --git a/os/ports/GCC/MSP430/chcore.h b/os/ports/GCC/MSP430/chcore.h index 3fb0f3591..c969a6b16 100644 --- a/os/ports/GCC/MSP430/chcore.h +++ b/os/ports/GCC/MSP430/chcore.h @@ -32,6 +32,10 @@ #include #include +#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. */ diff --git a/os/ports/GCC/PPC/chcore.h b/os/ports/GCC/PPC/chcore.h index 01b31bbb7..57ad8db27 100644 --- a/os/ports/GCC/PPC/chcore.h +++ b/os/ports/GCC/PPC/chcore.h @@ -29,6 +29,10 @@ #ifndef _CHCORE_H_ #define _CHCORE_H_ +#if CH_DBG_ENABLE_STACK_CHECK +#error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port" +#endif + /* * Port-related configuration parameters. */ diff --git a/os/ports/GCC/SIMIA32/chcore.h b/os/ports/GCC/SIMIA32/chcore.h index 2a9d3d452..8bfa719f8 100644 --- a/os/ports/GCC/SIMIA32/chcore.h +++ b/os/ports/GCC/SIMIA32/chcore.h @@ -26,6 +26,10 @@ #ifndef _CHCORE_H_ #define _CHCORE_H_ +#if CH_DBG_ENABLE_STACK_CHECK +#error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port" +#endif + /** * Macro defining the a simulated architecture into x86. */ diff --git a/os/ports/RC/STM8/chcore.h b/os/ports/RC/STM8/chcore.h index c8c2ebb16..6af456a55 100644 --- a/os/ports/RC/STM8/chcore.h +++ b/os/ports/RC/STM8/chcore.h @@ -31,6 +31,10 @@ #include +#if CH_DBG_ENABLE_STACK_CHECK +#error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port" +#endif + /*===========================================================================*/ /* Port configurable parameters. */ /*===========================================================================*/ diff --git a/os/ports/cosmic/STM8/chcore.h b/os/ports/cosmic/STM8/chcore.h index 9073592aa..6a261e00f 100644 --- a/os/ports/cosmic/STM8/chcore.h +++ b/os/ports/cosmic/STM8/chcore.h @@ -29,6 +29,10 @@ #ifndef _CHCORE_H_ #define _CHCORE_H_ +#if CH_DBG_ENABLE_STACK_CHECK +#error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port" +#endif + /*===========================================================================*/ /* Port configurable parameters. */ /*===========================================================================*/ diff --git a/readme.txt b/readme.txt index ed9718089..f47fead5a 100644 --- a/readme.txt +++ b/readme.txt @@ -89,6 +89,8 @@ (backported to 2.2.4). - FIX: Fixed timeout problem in the lwIP interface layer (bug 3302420) (backported to 2.2.4). +- 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 -- cgit v1.2.3 From 2d55ac3059fcca69cc9736db310b4521064c2b23 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 22 Aug 2011 17:18:52 +0000 Subject: Documentation improvements and code comments reformatting. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3248 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- docs/rsc/layout.xml | 2 +- os/kernel/include/ch.h | 5 +++ os/kernel/include/chevents.h | 8 +++-- os/kernel/include/chmemcore.h | 4 +++ os/kernel/include/chqueues.h | 20 ++++++------ os/kernel/include/chschd.h | 30 ++++++++++++----- os/kernel/include/chthreads.h | 76 ++++++++++++++++++++----------------------- os/kernel/include/chvt.h | 33 +++++++++++-------- 8 files changed, 103 insertions(+), 75 deletions(-) diff --git a/docs/rsc/layout.xml b/docs/rsc/layout.xml index 0a24b84a0..9ec514ba8 100644 --- a/docs/rsc/layout.xml +++ b/docs/rsc/layout.xml @@ -139,6 +139,7 @@ + @@ -150,7 +151,6 @@ - diff --git a/os/kernel/include/ch.h b/os/kernel/include/ch.h index db96d4338..35b01af2c 100644 --- a/os/kernel/include/ch.h +++ b/os/kernel/include/ch.h @@ -42,6 +42,10 @@ */ #define CH_KERNEL_VERSION "2.3.3unstable" +/** + * @name Kernel version + * @{ + */ /** * @brief Kernel version major number. */ @@ -56,6 +60,7 @@ * @brief Kernel version patch number. */ #define CH_KERNEL_PATCH 3 +/** @} */ /* * Common values. diff --git a/os/kernel/include/chevents.h b/os/kernel/include/chevents.h index e808caec3..f4314aeb2 100644 --- a/os/kernel/include/chevents.h +++ b/os/kernel/include/chevents.h @@ -78,10 +78,14 @@ typedef void (*evhandler_t)(eventid_t); */ #define EVENTSOURCE_DECL(name) EventSource name = _EVENTSOURCE_DATA(name) -/** All events allowed mask.*/ +/** + * @brief All events allowed mask. + */ #define ALL_EVENTS ((eventmask_t)-1) -/** Returns the event mask from the event identifier.*/ +/** + * @brief Returns an event mask from an event identifier. + */ #define EVENT_MASK(eid) ((eventmask_t)(1 << (eid))) /** diff --git a/os/kernel/include/chmemcore.h b/os/kernel/include/chmemcore.h index cf608c4e8..5f72a3585 100644 --- a/os/kernel/include/chmemcore.h +++ b/os/kernel/include/chmemcore.h @@ -36,6 +36,9 @@ */ typedef void *(*memgetfunc_t)(size_t size); +/** + * @name Alignment support macros + */ /** * @brief Alignment size constant. */ @@ -61,6 +64,7 @@ typedef void *(*memgetfunc_t)(size_t size); * the type @p align_t. */ #define MEM_IS_ALIGNED(p) (((size_t)(p) & MEM_ALIGN_MASK) == 0) +/** @} */ #if CH_USE_MEMCORE || defined(__DOXYGEN__) diff --git a/os/kernel/include/chqueues.h b/os/kernel/include/chqueues.h index a2df59dad..fa217710b 100644 --- a/os/kernel/include/chqueues.h +++ b/os/kernel/include/chqueues.h @@ -31,16 +31,16 @@ #if CH_USE_QUEUES || defined(__DOXYGEN__) -/** @brief Returned by the queue functions if the operation is successful.*/ -#define Q_OK RDY_OK -/** @brief Returned by the queue functions if a timeout occurs.*/ -#define Q_TIMEOUT RDY_TIMEOUT -/** @brief Returned by the queue functions if the queue has been reset.*/ -#define Q_RESET RDY_RESET -/** @brief Returned by the queue functions if the queue is empty.*/ -#define Q_EMPTY -3 -/** @brief Returned by the queue functions if the queue is full.*/ -#define Q_FULL -4 +/** + * @name Queue functions returned status value + * @{ + */ +#define Q_OK RDY_OK /**< @brief Operation successful. */ +#define Q_TIMEOUT RDY_TIMEOUT /**< @brief Timeout condition. */ +#define Q_RESET RDY_RESET /**< @brief Queue has been reset. */ +#define Q_EMPTY -3 /**< @brief Queue empty. */ +#define Q_FULL -4 /**< @brief Queue full, */ +/** @} */ /** * @brief Type of a generic I/O queue structure. diff --git a/os/kernel/include/chschd.h b/os/kernel/include/chschd.h index 0e933e8ba..27f6b9222 100644 --- a/os/kernel/include/chschd.h +++ b/os/kernel/include/chschd.h @@ -29,22 +29,35 @@ #ifndef _CHSCHD_H_ #define _CHSCHD_H_ -/** @brief Default thread wakeup low level message.*/ -#define RDY_OK 0 -/** @brief Low level message sent to a thread awakened by a timeout.*/ -#define RDY_TIMEOUT -1 -/** @brief Low level message sent to a thread awakened by a reset operation.*/ -#define RDY_RESET -2 +/** + * @name Wakeup status codes + * @{ + */ +#define RDY_OK 0 /**< @brief Normal wakeup message. */ +#define RDY_TIMEOUT -1 /**< @brief Wakeup caused by a timeout + condition. */ +#define RDY_RESET -2 /**< @brief Wakeup caused by a reset + condition. */ +/** @} */ +/** + * @name Priority constants + * @{ + */ #define NOPRIO 0 /**< @brief Ready list header priority. */ #define IDLEPRIO 1 /**< @brief Idle thread priority. */ #define LOWPRIO 2 /**< @brief Lowest user priority. */ #define NORMALPRIO 64 /**< @brief Normal user priority. */ #define HIGHPRIO 127 /**< @brief Highest user priority. */ #define ABSPRIO 255 /**< @brief Greatest possible priority. */ +/** @} */ /** - * @brief Zero time specification for some syscalls with a timeout + * @name Special time constants + * @{ + */ +/** + * @brief Zero time specification for some functions with a timeout * specification. * @note Not all functions accept @p TIME_IMMEDIATE as timeout parameter, * see the specific function documentation. @@ -52,10 +65,11 @@ #define TIME_IMMEDIATE ((systime_t)0) /** - * @brief Infinite time specification for all the syscalls with a timeout + * @brief Infinite time specification for all functions with a timeout * specification. */ #define TIME_INFINITE ((systime_t)-1) +/** @} */ /** * @brief Returns the priority of the first thread on the given ready list. diff --git a/os/kernel/include/chthreads.h b/os/kernel/include/chthreads.h index a0a668df4..eb3d8bb14 100644 --- a/os/kernel/include/chthreads.h +++ b/os/kernel/include/chthreads.h @@ -29,6 +29,42 @@ #ifndef _CHTHREADS_H_ #define _CHTHREADS_H_ +/** + * @name Thread states + * @{ + */ +#define THD_STATE_READY 0 /**< @brief Waiting on the ready list. */ +#define THD_STATE_CURRENT 1 /**< @brief Currently running. */ +#define THD_STATE_SUSPENDED 2 /**< @brief Created in suspended state. */ +#define THD_STATE_WTSEM 3 /**< @brief Waiting on a semaphore. */ +#define THD_STATE_WTMTX 4 /**< @brief Waiting on a mutex. */ +#define THD_STATE_WTCOND 5 /**< @brief Waiting on a condition + variable. */ +#define THD_STATE_SLEEPING 6 /**< @brief Waiting in @p chThdSleep() + or @p chThdSleepUntil(). */ +#define THD_STATE_WTEXIT 7 /**< @brief Waiting in @p chThdWait(). */ +#define THD_STATE_WTOREVT 8 /**< @brief Waiting for an event. */ +#define THD_STATE_WTANDEVT 9 /**< @brief Waiting for several events. */ +#define THD_STATE_SNDMSGQ 10 /**< @brief Sending a message, in queue.*/ +#define THD_STATE_SNDMSG 11 /**< @brief Sent a message, waiting + answer. */ +#define THD_STATE_WTMSG 12 /**< @brief Waiting for a message. */ +#define THD_STATE_WTQUEUE 13 /**< @brief Waiting on an I/O queue. */ +#define THD_STATE_FINAL 14 /**< @brief Thread terminated. */ +/** @} */ + +/** + * @name Thread flags and attributes + * @{ + */ +#define THD_MEM_MODE_MASK 3 /**< @brief Thread memory mode mask. */ +#define THD_MEM_MODE_STATIC 0 /**< @brief Static thread. */ +#define THD_MEM_MODE_HEAP 1 /**< @brief Thread allocated from Heap. */ +#define THD_MEM_MODE_MEMPOOL 2 /**< @brief Thread allocated from Memory + Pool. */ +#define THD_TERMINATE 4 /**< @brief Termination requested flag. */ +/** @} */ + /** * @extends ThreadsQueue * @@ -163,46 +199,6 @@ struct Thread { #endif }; -/** @brief Thread state: Ready to run, waiting on the ready list.*/ -#define THD_STATE_READY 0 -/** @brief Thread state: Currently running.*/ -#define THD_STATE_CURRENT 1 -/** @brief Thread state: Thread created in suspended state.*/ -#define THD_STATE_SUSPENDED 2 -/** @brief Thread state: Waiting on a semaphore.*/ -#define THD_STATE_WTSEM 3 -/** @brief Thread state: Waiting on a mutex.*/ -#define THD_STATE_WTMTX 4 -/** @brief Thread state: Waiting in @p chCondWait().*/ -#define THD_STATE_WTCOND 5 -/** @brief Thread state: Waiting in @p chThdSleep() or @p chThdSleepUntil().*/ -#define THD_STATE_SLEEPING 6 -/** @brief Thread state: Waiting in @p chThdWait().*/ -#define THD_STATE_WTEXIT 7 -/** @brief Thread state: Waiting in @p chEvtWaitXXX().*/ -#define THD_STATE_WTOREVT 8 -/** @brief Thread state: Waiting in @p chEvtWaitAllTimeout().*/ -#define THD_STATE_WTANDEVT 9 -/** @brief Thread state: Waiting in @p chMsgSend() (queued).*/ -#define THD_STATE_SNDMSGQ 10 -/** @brief Thread state: Waiting in @p chMsgSend() (not queued).*/ -#define THD_STATE_SNDMSG 11 -/** @brief Thread state: Waiting in @p chMsgWait().*/ -#define THD_STATE_WTMSG 12 -/** @brief Thread state: Waiting on an I/O queue.*/ -#define THD_STATE_WTQUEUE 13 -/** @brief Thread state: After termination.*/ -#define THD_STATE_FINAL 14 - -/* - * Various flags into the thread p_flags field. - */ -#define THD_MEM_MODE_MASK 3 /**< @brief Thread memory mode mask. */ -#define THD_MEM_MODE_STATIC 0 /**< @brief Thread memory mode: static. */ -#define THD_MEM_MODE_HEAP 1 /**< @brief Thread memory mode: heap. */ -#define THD_MEM_MODE_MEMPOOL 2 /**< @brief Thread memory mode: pool. */ -#define THD_TERMINATE 4 /**< @brief Termination requested. */ - /** * @brief Thread function. */ diff --git a/os/kernel/include/chvt.h b/os/kernel/include/chvt.h index e75e966d5..fe4ba11df 100644 --- a/os/kernel/include/chvt.h +++ b/os/kernel/include/chvt.h @@ -29,6 +29,10 @@ #ifndef _CHVT_H_ #define _CHVT_H_ +/** + * @name Time conversion utilities + * @{ + */ /** * @brief Time conversion utility. * @details Converts from seconds to system ticks number. @@ -49,6 +53,7 @@ * @note The result is rounded upward to the next tick boundary. */ #define US2ST(usec) ((systime_t)(((((usec) - 1L) * CH_FREQUENCY) / 1000000L) + 1L)) +/** @} */ /** * @brief Virtual Timer callback function. @@ -115,20 +120,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. * @@ -149,6 +140,20 @@ extern "C" { */ #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_ */ /** @} */ -- cgit v1.2.3 From c9be79def630f153b0b2d28e905939c15743f989 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 23 Aug 2011 10:09:08 +0000 Subject: Kernel documentation fixes and improvements. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3251 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/include/chbsem.h | 5 +++++ os/kernel/include/chdebug.h | 11 ++++++++++- os/kernel/include/chevents.h | 5 +++++ os/kernel/include/chfiles.h | 7 +++++++ os/kernel/include/chioch.h | 26 ++++++++++++++++++++++---- os/kernel/include/chmboxes.h | 5 +++++ os/kernel/include/chmsg.h | 5 +++++ os/kernel/include/chmtx.h | 5 +++++ os/kernel/include/chqueues.h | 35 +++++++++++++++++++++++++---------- os/kernel/include/chregistry.h | 6 +++++- os/kernel/include/chschd.h | 5 +++++ os/kernel/include/chsem.h | 5 +++++ os/kernel/include/chstreams.h | 5 +++++ os/kernel/include/chsys.h | 13 +++++++++++++ os/kernel/include/chthreads.h | 14 ++++++++++---- os/kernel/include/chvt.h | 11 ++++++++--- os/kernel/src/chmsg.c | 2 +- 17 files changed, 141 insertions(+), 24 deletions(-) diff --git a/os/kernel/include/chbsem.h b/os/kernel/include/chbsem.h index e0e1ca865..2d8815c3c 100644 --- a/os/kernel/include/chbsem.h +++ b/os/kernel/include/chbsem.h @@ -84,6 +84,10 @@ typedef struct { #define BSEMAPHORE_DECL(name, taken) \ BinarySemaphore name = _BSEMAPHORE_DATA(name, taken) +/** + * @name Macro Functions + * @{ + */ /** * @brief Initializes a binary semaphore. * @@ -238,6 +242,7 @@ typedef struct { * @iclass */ #define chBSemGetStateI(bsp) ((bsp)->bs_sem.s_cnt > 0 ? FALSE : TRUE) +/** @} */ #endif /* CH_USE_SEMAPHORES */ diff --git a/os/kernel/include/chdebug.h b/os/kernel/include/chdebug.h index f3bf6b026..d11eb2eb2 100644 --- a/os/kernel/include/chdebug.h +++ b/os/kernel/include/chdebug.h @@ -132,7 +132,10 @@ extern ch_trace_buffer_t dbg_trace_buffer; /*===========================================================================*/ #if CH_DBG_ENABLE_CHECKS || defined(__DOXYGEN__) - +/** + * @name Macro Functions + * @{ + */ /** * @brief Function parameter check. * @details If the condition check fails then the kernel panics and halts. @@ -150,6 +153,7 @@ extern ch_trace_buffer_t dbg_trace_buffer; chDbgPanic(__QUOTE_THIS(func)"()"); \ } #endif /* !defined(chDbgCheck) */ +/** @} */ #else /* !CH_DBG_ENABLE_CHECKS */ #define chDbgCheck(c, func) { \ (void)(c), (void)__QUOTE_THIS(func)"()"; \ @@ -161,6 +165,10 @@ extern ch_trace_buffer_t dbg_trace_buffer; /*===========================================================================*/ #if CH_DBG_ENABLE_ASSERTS || defined(__DOXYGEN__) +/** + * @name Macro Functions + * @{ + */ /** * @brief Condition assertion. * @details If the condition check fails then the kernel panics with the @@ -184,6 +192,7 @@ extern ch_trace_buffer_t dbg_trace_buffer; chDbgPanic(m); \ } #endif /* !defined(chDbgAssert) */ +/** @} */ #else /* !CH_DBG_ENABLE_ASSERTS */ #define chDbgAssert(c, m, r) {(void)(c);} #endif /* !CH_DBG_ENABLE_ASSERTS */ diff --git a/os/kernel/include/chevents.h b/os/kernel/include/chevents.h index f4314aeb2..de89118b4 100644 --- a/os/kernel/include/chevents.h +++ b/os/kernel/include/chevents.h @@ -88,6 +88,10 @@ typedef void (*evhandler_t)(eventid_t); */ #define EVENT_MASK(eid) ((eventmask_t)(1 << (eid))) +/** + * @name Macro Functions + * @{ + */ /** * @brief Registers an Event Listener on an Event Source. * @note Multiple Event Listeners can use the same event identifier, the @@ -151,6 +155,7 @@ typedef void (*evhandler_t)(eventid_t); * @iclass */ #define chEvtBroadcastI(esp) chEvtBroadcastFlagsI(esp, 0) +/** @} */ #ifdef __cplusplus extern "C" { diff --git a/os/kernel/include/chfiles.h b/os/kernel/include/chfiles.h index ff3f8274e..69a63965e 100644 --- a/os/kernel/include/chfiles.h +++ b/os/kernel/include/chfiles.h @@ -74,6 +74,8 @@ typedef uint32_t fileoffset_t; _base_sequential_stream_data /** + * @extends BaseSequentialStreamVMT + * * @brief @p BaseFileStream virtual methods table. */ struct BaseFilelStreamVMT { @@ -92,6 +94,10 @@ typedef struct { _base_file_stream_data } BaseFileStream; +/** + * @name Macro Functions (BaseFileStream) + * @{ + */ /** * @brief Base file Stream close. * @details The function closes a file stream. @@ -138,6 +144,7 @@ typedef struct { * @api */ #define chFileStreamSeek ((ip)->vmt->lseek(ip, offset)) +/** @} */ #endif /* _CHFILES_H_ */ diff --git a/os/kernel/include/chioch.h b/os/kernel/include/chioch.h index 02757c7e9..3361926e3 100644 --- a/os/kernel/include/chioch.h +++ b/os/kernel/include/chioch.h @@ -67,6 +67,8 @@ _base_sequential_stream_data /** + * @extends BaseSequentialStreamVMT + * * @brief @p BaseChannel virtual methods table. */ struct BaseChannelVMT { \ @@ -86,6 +88,10 @@ typedef struct { _base_channel_data } BaseChannel; +/** + * @name Macro Functions (BaseChannel) + * @{ + */ /** * @brief Channel output check. * @details This function verifies if a subsequent put/write operation would @@ -227,9 +233,13 @@ typedef struct { */ #define chIOReadTimeout(ip, bp, n, time) \ ((ip)->vmt->readt(ip, bp, n, time)) +/** @} */ -#if CH_USE_EVENTS - +#if CH_USE_EVENTS || defined(__DOXYGEN__) +/** + * @name I/O status flags + * @{ + */ /** @brief No pending conditions.*/ #define IO_NO_ERROR 0 /** @brief Connection happened.*/ @@ -242,6 +252,7 @@ typedef struct { #define IO_OUTPUT_EMPTY 8 /** @brief Transmission end.*/ #define IO_TRANSMISSION_END 16 +/** @} */ /** * @brief Type of an I/O condition flags mask. @@ -267,6 +278,8 @@ typedef uint_fast16_t ioflags_t; ioflags_t flags; /** + * @extends BaseChannelVMT + * * @brief @p BaseAsynchronousChannel virtual methods table. */ struct BaseAsynchronousChannelVMT { @@ -286,6 +299,10 @@ typedef struct { _base_asynchronous_channel_data } BaseAsynchronousChannel; +/** + * @name Macro Functions (BaseAsynchronousChannel) + * @{ + */ /** * @brief Returns the I/O condition event source. * @details The event source is broadcasted when an I/O condition happens. @@ -299,7 +316,7 @@ typedef struct { #define chIOGetEventSource(ip) (&((ip)->event)) /** - * @brief Adds condition flags to the channel's mask. + * @brief Adds status flags to the channel's mask. * @details This function is usually called from the I/O ISTs in order to * notify I/O conditions such as data events, errors, signal * changes etc. @@ -316,7 +333,7 @@ typedef struct { } /** - * @brief Returns and clears the errors mask associated to the channel. + * @brief Returns and clears the status flags associated to the channel. * * @param[in] ip pointer to a @p BaseAsynchronousChannel or derived * class @@ -326,6 +343,7 @@ typedef struct { * @api */ #define chIOGetAndClearFlags(ip) ((ip)->vmt->getflags(ip)) +/** @} */ /** * @brief Default implementation of the @p getflags virtual method. diff --git a/os/kernel/include/chmboxes.h b/os/kernel/include/chmboxes.h index 4a1706302..60cb7a5c1 100644 --- a/os/kernel/include/chmboxes.h +++ b/os/kernel/include/chmboxes.h @@ -72,6 +72,10 @@ extern "C" { } #endif +/** + * @name Macro Functions + * @{ + */ /** * @brief Returns the mailbox buffer size. * @@ -120,6 +124,7 @@ extern "C" { * @iclass */ #define chMBPeekI(mbp) (*(mbp)->mb_rdptr) +/** @} */ /** * @brief Data part of a static mailbox initializer. diff --git a/os/kernel/include/chmsg.h b/os/kernel/include/chmsg.h index 1803c719d..2bae02dea 100644 --- a/os/kernel/include/chmsg.h +++ b/os/kernel/include/chmsg.h @@ -31,6 +31,10 @@ #if CH_USE_MESSAGES || defined(__DOXYGEN__) +/** + * @name Macro Functions + * @{ + */ /** * @brief Evaluates to TRUE if the thread has pending messages. * @@ -74,6 +78,7 @@ * @sclass */ #define chMsgReleaseS(tp, msg) chSchWakeupS(tp, msg) +/** @} */ #ifdef __cplusplus extern "C" { diff --git a/os/kernel/include/chmtx.h b/os/kernel/include/chmtx.h index 9f2d5a0d3..831d48a89 100644 --- a/os/kernel/include/chmtx.h +++ b/os/kernel/include/chmtx.h @@ -76,6 +76,10 @@ extern "C" { */ #define MUTEX_DECL(name) Mutex name = _MUTEX_DATA(name) +/** + * @name Macro Functions + * @{ + */ /** * @brief Returns @p TRUE if the mutex queue contains at least a waiting * thread. @@ -83,6 +87,7 @@ extern "C" { * @sclass */ #define chMtxQueueNotEmptyS(mp) notempty(&(mp)->m_queue) +/** @} */ #endif /* CH_USE_MUTEXES */ diff --git a/os/kernel/include/chqueues.h b/os/kernel/include/chqueues.h index fa217710b..4917ac837 100644 --- a/os/kernel/include/chqueues.h +++ b/os/kernel/include/chqueues.h @@ -70,6 +70,10 @@ struct GenericQueue { qnotify_t q_notify; /**< @brief Data notification callback. */ }; +/** + * @name Macro Functions + * @{ + */ /** * @brief Returns the queue's buffer size. * @@ -90,7 +94,8 @@ struct GenericQueue { * * @iclass */ -#define chQSpaceI(qp) ((size_t)((qp)->q_counter)) +#define chQSpaceI(qp) ((qp)->q_counter) +/** @} */ /** * @extends GenericQueue @@ -105,6 +110,10 @@ struct GenericQueue { */ typedef GenericQueue InputQueue; +/** + * @name Macro Functions + * @{ + */ /** * @brief Returns the filled space into an input queue. * @@ -165,6 +174,7 @@ typedef GenericQueue InputQueue; * @api */ #define chIQGet(iqp) chIQGetTimeout(iqp, TIME_INFINITE) +/** @} */ /** * @brief Data part of a static input queue initializer. @@ -212,15 +222,19 @@ typedef GenericQueue InputQueue; */ typedef GenericQueue OutputQueue; - /** - * @brief Returns the filled space into an output queue. - * - * @param[in] oqp pointer to an @p OutputQueue structure - * @return The number of full bytes in the queue. - * @retval 0 if the queue is empty. - * - * @iclass - */ +/** + * @name Macro Functions + * @{ + */ +/** + * @brief Returns the filled space into an output queue. + * + * @param[in] oqp pointer to an @p OutputQueue structure + * @return The number of full bytes in the queue. + * @retval 0 if the queue is empty. + * + * @iclass + */ #define chOQGetFullI(oqp) (chQSizeI(oqp) - chQSpaceI(oqp)) /** @@ -274,6 +288,7 @@ typedef GenericQueue OutputQueue; * @api */ #define chOQPut(oqp, b) chOQPutTimeout(oqp, b, TIME_INFINITE) + /** @} */ /** * @brief Data part of a static output queue initializer. diff --git a/os/kernel/include/chregistry.h b/os/kernel/include/chregistry.h index 0967f699e..8f7ebd4b9 100644 --- a/os/kernel/include/chregistry.h +++ b/os/kernel/include/chregistry.h @@ -30,6 +30,10 @@ #define _CHREGISTRY_H_ #if CH_USE_REGISTRY || defined(__DOXYGEN__) +/** + * @name Macro Functions + * @{ + */ /** * @brief Sets the current thread name. * @pre This function only stores the pointer to the name if the option @@ -52,13 +56,13 @@ * @retval NULL if the thread name has not been set. */ #define chRegGetThreadName(tp) ((tp)->p_name) +/** @} */ #else /* !CH_USE_REGISTRY */ #define chRegSetThreadName(p) #define chRegGetThreadName(tp) NULL #endif /* !CH_USE_REGISTRY */ #if CH_USE_REGISTRY || defined(__DOXYGEN__) - /** * @brief Removes a thread from the registry list. * @note This macro is not meant for use in application code. diff --git a/os/kernel/include/chschd.h b/os/kernel/include/chschd.h index 27f6b9222..0e490c26a 100644 --- a/os/kernel/include/chschd.h +++ b/os/kernel/include/chschd.h @@ -161,6 +161,10 @@ extern "C" { } #endif +/** + * @name Macro Functions + * @{ + */ /** * @brief Determines if the current thread must reschedule. * @details This function returns @p TRUE if there is a ready thread with @@ -223,6 +227,7 @@ extern "C" { chSchDoReschedule(); \ } #endif /* CH_TIME_QUANTUM == 0 */ +/** @} */ #endif /* _CHSCHD_H_ */ diff --git a/os/kernel/include/chsem.h b/os/kernel/include/chsem.h index 04e079466..5f1c37a0a 100644 --- a/os/kernel/include/chsem.h +++ b/os/kernel/include/chsem.h @@ -82,6 +82,10 @@ extern "C" { */ #define SEMAPHORE_DECL(name, n) Semaphore name = _SEMAPHORE_DATA(name, n) +/** + * @name Macro Functions + * @{ + */ /** * @brief Decreases the semaphore counter. * @details This macro can be used when the counter is known to be positive. @@ -105,6 +109,7 @@ extern "C" { * @iclass */ #define chSemGetCounterI(sp) ((sp)->s_cnt) +/** @} */ #endif /* CH_USE_SEMAPHORES */ diff --git a/os/kernel/include/chstreams.h b/os/kernel/include/chstreams.h index 0bd763366..57883601d 100644 --- a/os/kernel/include/chstreams.h +++ b/os/kernel/include/chstreams.h @@ -73,6 +73,10 @@ typedef struct { _base_sequential_stream_data } BaseSequentialStream; +/** + * @name Macro Functions (BaseSequentialStream) + * @{ + */ /** * @brief Sequential Stream write. * @details The function writes data from a buffer to a stream. @@ -103,6 +107,7 @@ typedef struct { * @api */ #define chSequentialStreamRead(ip, bp, n) ((ip)->vmt->read(ip, bp, n)) +/** @} */ #endif /* _CHSTREAMS_H_ */ diff --git a/os/kernel/include/chsys.h b/os/kernel/include/chsys.h index f807182ac..b69736a1d 100644 --- a/os/kernel/include/chsys.h +++ b/os/kernel/include/chsys.h @@ -29,6 +29,10 @@ #ifndef _CHSYS_H_ #define _CHSYS_H_ +/** + * @name Macro Functions + * @{ + */ #if !CH_NO_IDLE_THREAD || defined(__DOXYGEN__) /** * @brief Returns a pointer to the idle thread. @@ -177,7 +181,11 @@ dbg_check_unlock_from_isr(); \ port_unlock_from_isr(); \ } +/** @} */ +/** + * @name ISRs abstraction macros + */ /** * @brief IRQ handler enter code. * @note Usually IRQ handlers functions are also declared naked. @@ -211,7 +219,11 @@ * @special */ #define CH_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id) +/** @} */ +/** + * @name Fast ISRs abstraction macros + */ /** * @brief Standard fast IRQ handler declaration. * @note @p id can be a function name or a vector number depending on the @@ -221,6 +233,7 @@ * @special */ #define CH_FAST_IRQ_HANDLER(id) PORT_FAST_IRQ_HANDLER(id) +/** @} */ #ifdef __cplusplus extern "C" { diff --git a/os/kernel/include/chthreads.h b/os/kernel/include/chthreads.h index eb3d8bb14..bd3f21296 100644 --- a/os/kernel/include/chthreads.h +++ b/os/kernel/include/chthreads.h @@ -59,9 +59,10 @@ */ #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 Heap. */ -#define THD_MEM_MODE_MEMPOOL 2 /**< @brief Thread allocated from Memory - Pool. */ +#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. */ /** @} */ @@ -204,6 +205,10 @@ struct Thread { */ typedef msg_t (*tfunc_t)(void *); +/** + * @name Macro Functions + * @{ + */ /** * @brief Returns a pointer to the current @p Thread. * @@ -258,7 +263,7 @@ typedef msg_t (*tfunc_t)(void *); #define chThdShouldTerminate() (currp->p_flags & THD_TERMINATE) /** - * @brief Resumes a thread created with @p chThdInit(). + * @brief Resumes a thread created with @p chThdCreateI(). * * @param[in] tp pointer to the thread * @@ -317,6 +322,7 @@ typedef msg_t (*tfunc_t)(void *); * @api */ #define chThdSleepMicroseconds(usec) chThdSleep(US2ST(usec)) +/** @} */ /* * Threads APIs. diff --git a/os/kernel/include/chvt.h b/os/kernel/include/chvt.h index fe4ba11df..0038e3d0a 100644 --- a/os/kernel/include/chvt.h +++ b/os/kernel/include/chvt.h @@ -34,21 +34,21 @@ * @{ */ /** - * @brief Time conversion utility. + * @brief Seconds to system ticks. * @details Converts from seconds to system ticks number. * @note The result is rounded upward to the next tick boundary. */ #define S2ST(sec) ((systime_t)((sec) * CH_FREQUENCY)) /** - * @brief Time conversion utility. + * @brief Milliseconds t0 system ticks. * @details Converts from milliseconds to system ticks number. * @note The result is rounded upward to the next tick boundary. */ #define MS2ST(msec) ((systime_t)(((((msec) - 1L) * CH_FREQUENCY) / 1000L) + 1L)) /** - * @brief Time conversion utility. + * @brief Microseconds to system ticks. * @details Converts from microseconds to system ticks number. * @note The result is rounded upward to the next tick boundary. */ @@ -99,6 +99,10 @@ typedef struct { extern VTList vtlist; +/** + * @name Macro Functions + * @{ + */ /** * @brief Virtual timers ticker. * @@ -139,6 +143,7 @@ extern VTList vtlist; * @api */ #define chTimeNow() (vtlist.vt_systime) +/** @} */ /* * Virtual Timers APIs. diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c index 5002a892a..403df1580 100644 --- a/os/kernel/src/chmsg.c +++ b/os/kernel/src/chmsg.c @@ -109,7 +109,7 @@ Thread *chMsgWait(void) { } /** - * @brief Releases the thread waiting on top of the messages queue. + * @brief Releases a sender thread specifying a response message. * @pre Invoke this function only after a message has been received * using @p chMsgWait(). * -- cgit v1.2.3 From 718dc5084f7719f91eaacfc99e8c7de654eb2ad8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 23 Aug 2011 13:36:25 +0000 Subject: HAL documentation improvements. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3252 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/adc.h | 10 +++++ os/hal/include/can.h | 18 +++++++++ os/hal/include/icu.h | 10 +++++ os/hal/include/mac.h | 5 +++ os/hal/include/mii.h | 6 --- os/hal/include/mmc_spi.h | 10 +++++ os/hal/include/pal.h | 15 ++++++++ os/hal/include/pwm.h | 15 ++++++++ os/hal/include/sdc.h | 20 ++++++++++ os/hal/include/serial.h | 32 +++++++++++----- os/hal/include/serial_usb.h | 7 ++++ os/hal/include/spi.h | 15 ++++++++ os/hal/include/uart.h | 23 ++++++------ os/hal/include/usb.h | 21 +++++++++++ os/hal/include/usb_cdc.h | 5 +++ os/hal/src/sdc.c | 4 +- os/hal/templates/can_lld.h | 13 ------- os/hal/templates/halconf.h | 90 +++++++++++++++++++++++++++++++++++++++------ os/hal/templates/mac_lld.h | 21 ----------- todo.txt | 1 + 20 files changed, 266 insertions(+), 75 deletions(-) diff --git a/os/hal/include/adc.h b/os/hal/include/adc.h index a236a040a..53c7c199a 100644 --- a/os/hal/include/adc.h +++ b/os/hal/include/adc.h @@ -39,6 +39,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name ADC configuration options + * @{ + */ /** * @brief Enables synchronous APIs. * @note Disabling this option saves both code and data space. @@ -54,6 +58,7 @@ #if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) #define ADC_USE_MUTUAL_EXCLUSION TRUE #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ @@ -84,6 +89,10 @@ typedef enum { /* Driver macros. */ /*===========================================================================*/ +/** + * @name Low Level driver helper macros + * @{ + */ #if ADC_USE_WAIT || defined(__DOXYGEN__) /** * @brief Resumes a thread waiting for a conversion completion. @@ -211,6 +220,7 @@ typedef enum { _adc_wakeup_isr(adcp); \ } \ } +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/can.h b/os/hal/include/can.h index 538284b3b..44d2cfb19 100644 --- a/os/hal/include/can.h +++ b/os/hal/include/can.h @@ -35,6 +35,10 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @name CAN status flags + * @{ + */ /** * @brief Errors rate warning. */ @@ -55,17 +59,26 @@ * @brief Overflow in receive queue. */ #define CAN_OVERFLOW_ERROR 16 +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name CAN configuration options + * @{ + */ /** * @brief Sleep mode related APIs inclusion switch. + * @details This option can only be enabled if the CAN implementation supports + * the sleep mode, see the macro @p CAN_SUPPORTS_SLEEP exported by + * the underlying implementation. */ #if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) #define CAN_USE_SLEEP_MODE TRUE #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ @@ -96,6 +109,10 @@ typedef enum { /* Driver macros. */ /*===========================================================================*/ +/** + * @name Macro Functions + * @{ + */ /** * @brief Adds some flags to the CAN status mask. * @@ -105,6 +122,7 @@ typedef enum { * @iclass */ #define canAddFlagsI(canp, mask) ((canp)->status |= (mask)) +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/icu.h b/os/hal/include/icu.h index 38fed2788..65d7794e5 100644 --- a/os/hal/include/icu.h +++ b/os/hal/include/icu.h @@ -77,6 +77,10 @@ typedef void (*icucallback_t)(ICUDriver *icup); /* Driver macros. */ /*===========================================================================*/ +/** + * @name Macro Functions + * @{ + */ /** * @brief Enables the input capture. * @@ -118,7 +122,12 @@ typedef void (*icucallback_t)(ICUDriver *icup); * @iclass */ #define icuGetPeriodI(icup) icu_lld_get_period(icup) +/** @} */ +/** + * @name Low Level driver helper macros + * @{ + */ /** * @brief Common ISR code, ICU width event. * @@ -144,6 +153,7 @@ typedef void (*icucallback_t)(ICUDriver *icup); if (previous_state != ICU_WAITING) \ (icup)->config->period_cb(icup); \ } +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/mac.h b/os/hal/include/mac.h index ad3c7b4dc..37d6bbe9b 100644 --- a/os/hal/include/mac.h +++ b/os/hal/include/mac.h @@ -56,6 +56,10 @@ /* Driver macros. */ /*===========================================================================*/ +/** + * @name Macro Functions + * @{ + */ /** * @brief Returns the received frames event source. * @@ -98,6 +102,7 @@ */ #define macReadReceiveDescriptor(rdp, buf, size) \ mac_lld_read_receive_descriptor(rdp, buf, size) +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/mii.h b/os/hal/include/mii.h index 7199ee86d..89ba69810 100644 --- a/os/hal/include/mii.h +++ b/os/hal/include/mii.h @@ -18,12 +18,6 @@ along with this program. If not, see . */ -/* - * Parts of this file have been borrowed from the Linux include file - * linux/mii.h: - * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com) - */ - /*-* * @file mii.h * @brief MII Driver macros and structures. diff --git a/os/hal/include/mmc_spi.h b/os/hal/include/mmc_spi.h index 6940ca479..f51bd6765 100644 --- a/os/hal/include/mmc_spi.h +++ b/os/hal/include/mmc_spi.h @@ -53,6 +53,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name MMC_SPI configuration options + * @{ + */ /** * @brief Block size for MMC transfers. */ @@ -86,6 +90,7 @@ #if !defined(MMC_POLLING_DELAY) || defined(__DOXYGEN__) #define MMC_POLLING_DELAY 10 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ @@ -181,6 +186,10 @@ typedef struct { /* Driver macros. */ /*===========================================================================*/ +/** + * @name Macro Functions + * @{ + */ /** * @brief Returns the driver state. * @@ -202,6 +211,7 @@ typedef struct { * @api */ #define mmcIsWriteProtected(mmcp) ((mmcp)->is_protected()) +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/pal.h b/os/hal/include/pal.h index 2e5b78c03..d844ca8b3 100644 --- a/os/hal/include/pal.h +++ b/os/hal/include/pal.h @@ -35,6 +35,10 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @name Pads mode constants + * @{ + */ /** * @brief After reset state. * @details The state itself is not specified and is architecture dependent, @@ -81,7 +85,12 @@ * @brief Open-drain output pad. */ #define PAL_MODE_OUTPUT_OPENDRAIN 7 +/** @} */ +/** + * @name Logic level constants + * @{ + */ /** * @brief Logical low state. */ @@ -91,6 +100,7 @@ * @brief Logical high state. */ #define PAL_HIGH 1 +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ @@ -177,6 +187,10 @@ typedef struct { #define IOBUS_DECL(name, port, width, offset) \ IOBus name = _IOBUS_DATA(name, port, width, offset) +/** + * @name Macro Functions + * @{ + */ /** * @brief PAL subsystem initialization. * @note This function is implicitly invoked by @p halInit(), there is @@ -499,6 +513,7 @@ typedef struct { #else #define palSetPadMode(port, pad, mode) pal_lld_setpadmode(port, pad, mode) #endif +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/pwm.h b/os/hal/include/pwm.h index 2ffd3599c..960ac2a69 100644 --- a/os/hal/include/pwm.h +++ b/os/hal/include/pwm.h @@ -35,6 +35,10 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @name PWM output mode macros + * @{ + */ /** * @brief Standard output modes mask. */ @@ -54,6 +58,7 @@ * @brief Inverse PWM logic, active is logic level zero. */ #define PWM_OUTPUT_ACTIVE_LOW 0x02 +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ @@ -94,6 +99,10 @@ typedef void (*pwmcallback_t)(PWMDriver *pwmp); /* Driver macros. */ /*===========================================================================*/ +/** + * @name PWM duty cycle conversion + * @{ + */ /** * @brief Converts from fraction to pulse width. * @note Be careful with rounding errors, this is integer math not magic. @@ -143,7 +152,12 @@ typedef void (*pwmcallback_t)(PWMDriver *pwmp); */ #define PWM_PERCENTAGE_TO_WIDTH(pwmp, percentage) \ PWM_FRACTION_TO_WIDTH(pwmp, 10000, percentage) +/** @} */ +/** + * @name Macro Functions + * @{ + */ /** * @brief Changes the period the PWM peripheral. * @details This function changes the period of a PWM unit that has already @@ -197,6 +211,7 @@ typedef void (*pwmcallback_t)(PWMDriver *pwmp); */ #define pwmDisableChannelI(pwmp, channel) \ pwm_lld_disable_channel(pwmp, channel) +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h index afc3a6aba..466c48fa6 100644 --- a/os/hal/include/sdc.h +++ b/os/hal/include/sdc.h @@ -42,11 +42,16 @@ */ #define SDC_CMD8_PATTERN 0x000001AA +/** + * @name SD cart types + * @{ + */ #define SDC_MODE_CARDTYPE_MASK 0xF /**< @brief Card type mask. */ #define SDC_MODE_CARDTYPE_SDV11 0 /**< @brief Card is SD V1.1.*/ #define SDC_MODE_CARDTYPE_SDV20 1 /**< @brief Card is SD V2.0.*/ #define SDC_MODE_CARDTYPE_MMC 2 /**< @brief Card is MMC. */ #define SDC_MODE_HIGH_CAPACITY 0x10 /**< @brief High cap.card. */ +/** @} */ /** * @brief Mask of error bits in R1 responses. @@ -87,6 +92,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name SDC configuration options + * @{ + */ /** * @brief Number of initialization attempts before rejecting the card. * @note Attempts are performed at 10mS intevals. @@ -113,6 +122,7 @@ #if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) #define SDC_NICE_WAITING TRUE #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ @@ -142,6 +152,10 @@ typedef enum { /* Driver macros. */ /*===========================================================================*/ +/** + * @name R1 response utilities + * @{ + */ /** * @brief Evaluates to @p TRUE if the R1 response contains error flags. * @@ -162,7 +176,12 @@ typedef enum { * @param[in] r1 the r1 response */ #define SDC_R1_IS_CARD_LOCKED(r1) (((r1) >> 21) & 1) +/** @} */ +/** + * @name Macro Functions + * @{ + */ /** * @brief Returns the driver state. * @@ -204,6 +223,7 @@ typedef enum { * @api */ #define sdcIsWriteProtected(sdcp) (sdc_lld_is_write_protected(sdcp)) +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/serial.h b/os/hal/include/serial.h index a8c3c1aca..8c610e29e 100644 --- a/os/hal/include/serial.h +++ b/os/hal/include/serial.h @@ -35,21 +35,25 @@ /* Driver constants. */ /*===========================================================================*/ -/** @brief Parity error happened.*/ -#define SD_PARITY_ERROR 32 -/** @brief Framing error happened.*/ -#define SD_FRAMING_ERROR 64 -/** @brief Overflow happened.*/ -#define SD_OVERRUN_ERROR 128 -/** @brief Noise on the line.*/ -#define SD_NOISE_ERROR 256 -/** @brief Break detected.*/ -#define SD_BREAK_DETECTED 512 +/** + * @name Serial status flags + * @{ + */ +#define SD_PARITY_ERROR 32 /**< @brief Parity error happened. */ +#define SD_FRAMING_ERROR 64 /**< @brief Framing error happened. */ +#define SD_OVERRUN_ERROR 128 /**< @brief Overflow happened. */ +#define SD_NOISE_ERROR 256 /**< @brief Noise on the line. */ +#define SD_BREAK_DETECTED 512 /**< @brief Break detected. */ +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Serial configuration options + * @{ + */ /** * @brief Default bit rate. * @details Configuration parameter, this is the baud rate selected for the @@ -69,6 +73,7 @@ #if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) #define SERIAL_BUFFERS_SIZE 16 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ @@ -105,6 +110,8 @@ typedef struct SerialDriver SerialDriver; _base_asynchronous_channel_methods /** + * @extends BaseAsynchronousChannelVMT + * * @brief @p SerialDriver virtual methods table. */ struct SerialDriverVMT { @@ -128,6 +135,10 @@ struct SerialDriver { /* Driver macros. */ /*===========================================================================*/ +/** + * @name Macro Functions + * @{ + */ /** * @brief Direct output check on a @p SerialDriver. * @note This function bypasses the indirect access to the channel and @@ -281,6 +292,7 @@ struct SerialDriver { */ #define sdAsynchronousRead(sdp, b, n) \ chIQReadTimeout(&(sdp)->iqueue, b, n, TIME_IMMEDIATE) +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/serial_usb.h b/os/hal/include/serial_usb.h index 8e518238d..09be9b708 100644 --- a/os/hal/include/serial_usb.h +++ b/os/hal/include/serial_usb.h @@ -39,6 +39,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name SERIAL_USB configuration options + * @{ + */ /** * @brief Serial over USB buffers size. * @details Configuration parameter, the buffer size must be a multiple of @@ -49,6 +53,7 @@ #if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) #define SERIAL_USB_BUFFERS_SIZE 64 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ @@ -119,6 +124,8 @@ typedef struct { _base_asynchronous_channel_methods /** + * @extends BaseAsynchronousChannelVMT + * * @brief @p SerialDriver virtual methods table. */ struct SerialUSBDriverVMT { diff --git a/os/hal/include/spi.h b/os/hal/include/spi.h index 104dd9d3e..a07d55cf7 100644 --- a/os/hal/include/spi.h +++ b/os/hal/include/spi.h @@ -39,6 +39,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name SPI configuration options + * @{ + */ /** * @brief Enables synchronous APIs. * @note Disabling this option saves both code and data space. @@ -54,6 +58,7 @@ #if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) #define SPI_USE_MUTUAL_EXCLUSION TRUE #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ @@ -84,6 +89,10 @@ typedef enum { /* Driver macros. */ /*===========================================================================*/ +/** + * @name Macro Functions + * @{ + */ /** * @brief Asserts the slave select signal and prepares for transfers. * @@ -201,7 +210,12 @@ typedef enum { * @return The received data frame from the SPI bus. */ #define spiPolledExchange(spip, frame) spi_lld_polled_exchange(spip, frame) +/** @} */ +/** + * @name Low Level driver helper macros + * @{ + */ #if SPI_USE_WAIT || defined(__DOXYGEN__) /** * @brief Waits for operation completion. @@ -268,6 +282,7 @@ typedef enum { (spip)->state = SPI_READY; \ _spi_wakeup_isr(spip); \ } +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/uart.h b/os/hal/include/uart.h index 148aa6877..6d3d12d5f 100644 --- a/os/hal/include/uart.h +++ b/os/hal/include/uart.h @@ -35,18 +35,17 @@ /* Driver constants. */ /*===========================================================================*/ -/** @brief No pending conditions.*/ -#define UART_NO_ERROR 0 -/** @brief Parity error happened.*/ -#define UART_PARITY_ERROR 4 -/** @brief Framing error happened.*/ -#define UART_FRAMING_ERROR 8 -/** @brief Overflow happened.*/ -#define UART_OVERRUN_ERROR 16 -/** @brief Noise on the line.*/ -#define UART_NOISE_ERROR 32 -/** @brief Break detected.*/ -#define UART_BREAK_DETECTED 64 +/** + * @name UART status flags + * @{ + */ +#define UART_NO_ERROR 0 /**< @brief No pending conditions. */ +#define UART_PARITY_ERROR 4 /**< @brief Parity error happened. */ +#define UART_FRAMING_ERROR 8 /**< @brief Framing error happened. */ +#define UART_OVERRUN_ERROR 16 /**< @brief Overflow happened. */ +#define UART_NOISE_ERROR 32 /**< @brief Noise on the line. */ +#define UART_BREAK_DETECTED 64 /**< @brief Break detected. */ +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ diff --git a/os/hal/include/usb.h b/os/hal/include/usb.h index c4cf68fe2..884b11e8d 100644 --- a/os/hal/include/usb.h +++ b/os/hal/include/usb.h @@ -77,6 +77,10 @@ #define USB_EARLY_SET_ADDRESS 0 #define USB_LATE_SET_ADDRESS 1 +/** + * @name Helper macros for USB descriptors + * @{ + */ /** * @brief Helper macro for index values into descriptor strings. */ @@ -166,12 +170,17 @@ USB_DESC_BYTE(bmAttributes), \ USB_DESC_WORD(wMaxPacketSize), \ USB_DESC_BYTE(bInterval) +/** @} */ /** * @brief Returned by some functions to report a busy endpoint. */ #define USB_ENDPOINT_BUSY ((size_t)0xFFFFFFFF) +/** + * @name Endpoint types and settings + * @{ + */ #define USB_EP_MODE_TYPE 0x0003 /**< Endpoint type mask. */ #define USB_EP_MODE_TYPE_CTRL 0x0000 /**< Control endpoint. */ #define USB_EP_MODE_TYPE_ISOC 0x0001 /**< Isochronous endpoint. */ @@ -179,6 +188,7 @@ #define USB_EP_MODE_TYPE_INTR 0x0003 /**< Interrupt endpoint. */ #define USB_EP_MODE_TRANSACTION 0x0000 /**< Transaction mode. */ #define USB_EP_MODE_PACKET 0x0010 /**< Packet mode enabled. */ +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ @@ -311,6 +321,11 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp, /*===========================================================================*/ /* Driver macros. */ /*===========================================================================*/ + +/** + * @name Macro Functions + * @{ + */ /** * @brief Returns the current frame number. * @@ -411,7 +426,12 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp, * @special */ #define usbReadSetup(usbp, ep, buf) usb_lld_read_setup(usbp, ep, buf) +/** @} */ +/** + * @name Low Level driver helper macros + * @{ + */ /** * @brief Common ISR code, usb event callback. * @@ -474,6 +494,7 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp, (usbp)->receiving &= ~(1 << (ep)); \ (usbp)->epc[ep]->out_cb(usbp, ep); \ } +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/usb_cdc.h b/os/hal/include/usb_cdc.h index a388f9f70..cd9d78f10 100644 --- a/os/hal/include/usb_cdc.h +++ b/os/hal/include/usb_cdc.h @@ -67,6 +67,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name USB_CDC configuration options + * @{ + */ /** * @brief Endpoint number for bulk IN. */ @@ -87,6 +91,7 @@ #if !defined(DATA_AVAILABLE_EP) || defined(__DOXYGEN__) #define DATA_AVAILABLE_EP 3 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c index 59d7db005..6bdaa2b5a 100644 --- a/os/hal/src/sdc.c +++ b/os/hal/src/sdc.c @@ -54,7 +54,7 @@ * * @notapi */ -bool_t sdc_wait_for_transfer_state(SDCDriver *sdcp) { +bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp) { uint32_t resp[1]; while (TRUE) { @@ -314,7 +314,7 @@ bool_t sdcDisconnect(SDCDriver *sdcp) { chSysUnlock(); /* Waits for eventual pending operations completion.*/ - if (sdc_wait_for_transfer_state(sdcp)) + if (_sdc_wait_for_transfer_state(sdcp)) return TRUE; /* Card clock stopped.*/ diff --git a/os/hal/templates/can_lld.h b/os/hal/templates/can_lld.h index d07bd78cc..d1f8d6044 100644 --- a/os/hal/templates/can_lld.h +++ b/os/hal/templates/can_lld.h @@ -45,19 +45,6 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ -/** - * @brief Sleep mode related APIs inclusion switch. - * @note This switch is enforced to @p FALSE if the driver implementation - * does not support the sleep mode. - */ -#if CAN_SUPPORTS_SLEEP || defined(__DOXYGEN__) -#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) -#define CAN_USE_SLEEP_MODE TRUE -#endif -#else /* !CAN_SUPPORTS_SLEEP */ -#define CAN_USE_SLEEP_MODE FALSE -#endif /* !CAN_SUPPORTS_SLEEP */ - /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ diff --git a/os/hal/templates/halconf.h b/os/hal/templates/halconf.h index da86f61ed..0e616d3d5 100644 --- a/os/hal/templates/halconf.h +++ b/os/hal/templates/halconf.h @@ -34,6 +34,10 @@ #include "mcuconf.h" +/** + * @name Drivers enable switches + * @{ + */ /** * @brief Enables the PAL subsystem. */ @@ -138,9 +142,13 @@ #if !defined(HAL_USE_USB) || defined(__DOXYGEN__) #define HAL_USE_USB TRUE #endif +/** @} */ /*===========================================================================*/ -/* ADC driver related settings. */ +/** + * @name ADC driver related setting + * @{ + */ /*===========================================================================*/ /** @@ -158,9 +166,13 @@ #if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) #define ADC_USE_MUTUAL_EXCLUSION TRUE #endif +/** @} */ /*===========================================================================*/ -/* CAN driver related settings. */ +/** + * @name CAN driver related setting + * @{ + */ /*===========================================================================*/ /** @@ -169,9 +181,13 @@ #if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) #define CAN_USE_SLEEP_MODE TRUE #endif +/** @} */ /*===========================================================================*/ -/* I2C driver related settings. */ +/** + * @name I2C driver related setting + * @{ + */ /*===========================================================================*/ /** @@ -180,13 +196,21 @@ #if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) #define I2C_USE_MUTUAL_EXCLUSION TRUE #endif +/** @} */ /*===========================================================================*/ -/* MAC driver related settings. */ +/** + * @name MAC driver related setting + * @{ + */ /*===========================================================================*/ +/** @} */ /*===========================================================================*/ -/* MMC_SPI driver related settings. */ +/** + * @name MMC_SPI driver related setting + * @{ + */ /*===========================================================================*/ /** @@ -233,17 +257,29 @@ #if !defined(MMC_USE_SPI_POLLING) || defined(__DOXYGEN__) #define MMC_USE_SPI_POLLING TRUE #endif +/** @} */ /*===========================================================================*/ -/* PAL driver related settings. */ +/** + * @name PAL driver related setting + * @{ + */ /*===========================================================================*/ +/** @} */ /*===========================================================================*/ -/* PWM driver related settings. */ +/** + * @name PWM driver related setting + * @{ + */ /*===========================================================================*/ +/** @} */ /*===========================================================================*/ -/* SDC driver related settings. */ +/** + * @name SDC driver related setting + * @{ + */ /*===========================================================================*/ /** * @brief Number of initialization attempts before rejecting the card. @@ -271,9 +307,13 @@ #if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) #define SDC_NICE_WAITING TRUE #endif +/** @} */ /*===========================================================================*/ -/* SERIAL driver related settings. */ +/** + * @name SERIAL driver related setting + * @{ + */ /*===========================================================================*/ /** @@ -295,9 +335,32 @@ #if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) #define SERIAL_BUFFERS_SIZE 16 #endif +/** @} */ + + +/*===========================================================================*/ +/** + * @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 +/** @} */ /*===========================================================================*/ -/* SPI driver related settings. */ +/** + * @name SPI driver related setting + * @{ + */ /*===========================================================================*/ /** @@ -315,10 +378,15 @@ #if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) #define SPI_USE_MUTUAL_EXCLUSION TRUE #endif +/** @} */ /*===========================================================================*/ -/* UART driver related settings. */ +/** + * @name UART driver related setting + * @{ + */ /*===========================================================================*/ +/** @} */ #endif /* _HALCONF_H_ */ diff --git a/os/hal/templates/mac_lld.h b/os/hal/templates/mac_lld.h index e8abe2941..e103128a9 100644 --- a/os/hal/templates/mac_lld.h +++ b/os/hal/templates/mac_lld.h @@ -39,27 +39,6 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ -/** - * @brief Number of available transmit buffers. - */ -#if !defined(MAC_TRANSMIT_BUFFERS) || defined(__DOXYGEN__) -#define MAC_TRANSMIT_BUFFERS 2 -#endif - -/** - * @brief Number of available receive buffers. - */ -#if !defined(MAC_RECEIVE_BUFFERS) || defined(__DOXYGEN__) -#define MAC_RECEIVE_BUFFERS 2 -#endif - -/** - * @brief Maximum supported frame size. - */ -#if !defined(MAC_BUFFERS_SIZE) || defined(__DOXYGEN__) -#define MAC_BUFFERS_SIZE 1518 -#endif - /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ diff --git a/todo.txt b/todo.txt index 4cd406b16..f64e907cb 100644 --- a/todo.txt +++ b/todo.txt @@ -18,6 +18,7 @@ X STM32L support. X STM32L-Discovery demo and article. X File System infrastructure. X STM32F2xx support. +- MMC_SPI driver revision and speedup. - Test suite overhaul, the API should be more generic in order to be used with different subsystems and not just the kernel. - STM32 USB support for double buffering. -- cgit v1.2.3 From 0aa2dd05114a68ac0e0a23fe8227215a13e2c77b Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 25 Aug 2011 15:14:09 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3253 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/sdc_lld.h | 2 +- os/hal/platforms/STM32/DMAv1/stm32_dma.c | 5 - os/hal/platforms/STM32/DMAv1/stm32_dma.h | 11 +- os/hal/platforms/STM32/DMAv2/stm32_dma.c | 487 +++++++++++++++++++++++++++++++ os/hal/platforms/STM32/DMAv2/stm32_dma.h | 235 +++++++++++++++ os/hal/platforms/STM32/GPIOv1/pal_lld.c | 4 +- os/hal/platforms/STM32/GPIOv1/pal_lld.h | 4 +- 7 files changed, 732 insertions(+), 16 deletions(-) create mode 100644 os/hal/platforms/STM32/DMAv2/stm32_dma.c create mode 100644 os/hal/platforms/STM32/DMAv2/stm32_dma.h diff --git a/os/hal/platforms/STM32/DMAv1/sdc_lld.h b/os/hal/platforms/STM32/DMAv1/sdc_lld.h index 5466eacad..eea76dadd 100644 --- a/os/hal/platforms/STM32/DMAv1/sdc_lld.h +++ b/os/hal/platforms/STM32/DMAv1/sdc_lld.h @@ -152,7 +152,7 @@ struct SDCDriver { uint32_t rca; /* End of the mandatory fields.*/ /** - * @brief Tthread waiting for I/O completion IRQ. + * @brief Thread waiting for I/O completion IRQ. */ Thread *thread; }; diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.c b/os/hal/platforms/STM32/DMAv1/stm32_dma.c index 2232df448..4ea8e99ee 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.c @@ -366,17 +366,12 @@ void dmaInit(void) { * @param[in] channel requested channel id * @param[in] func handling function pointer, can be @p NULL * @param[in] param a parameter to be passed to the handling function - * @return The operation status. - * @retval FALSE operation successfully allocated. - * @retval TRUE the channel was already in use. * * @special */ void dmaAllocate(uint32_t dma, uint32_t channel, stm32_dmaisr_t func, void *param) { - chDbgCheck(func != NULL, "dmaAllocate"); - #if STM32_HAS_DMA2 switch (dma) { case STM32_DMA1_ID: diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.h b/os/hal/platforms/STM32/DMAv1/stm32_dma.h index 66a2f8c69..7ef5ad8b9 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.h @@ -22,7 +22,7 @@ * @file stm32_dma.h * @brief STM32 DMA helper driver header. * @note This file requires definitions from the ST STM32 header file - * stm3232f10x.h. + * stm32f10x.h. * * @addtogroup STM32_DMA * @{ @@ -154,7 +154,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * data register. * @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] dmachp pointer to a stm32_dma_channel_t structure * @param[in] cndtr value to be written in the CNDTR register * @param[in] cmar value to be written in the CMAR register * @param[in] ccr value to be written in the CCR register @@ -171,7 +171,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * @brief DMA channel enable 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 + * @param[in] dmachp pointer to a stm32_dma_channel_t structure * * @special */ @@ -179,12 +179,11 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); (dmachp)->CCR |= DMA_CCR1_EN; \ } - /** * @brief DMA channel disable by channel pointer. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmachp dmachp to a stm32_dma_channel_t structure + * @param[in] dmachp pointer to a stm32_dma_channel_t structure * * @special */ @@ -256,7 +255,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * * @special */ -#define dmaClearChannel(dmap, ch){ \ +#define dmaClearChannel(dmap, ch) { \ (dmap)->IFCR = 1 << ((ch) * 4); \ } diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.c b/os/hal/platforms/STM32/DMAv2/stm32_dma.c new file mode 100644 index 000000000..d64cfc5f9 --- /dev/null +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.c @@ -0,0 +1,487 @@ +/* + 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 . +*/ + +/** + * @file DMAv2/stm32_dma.c + * @brief STM32F2xx 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 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[16] = { + {0, DMA1, DMA1_Stream0, &DMA1->LISR, &DMA1->LIFCR, 0}, + {1, DMA1, DMA1_Stream1, &DMA1->LISR, &DMA1->LIFCR, 6}, + {2, DMA1, DMA1_Stream2, &DMA1->LISR, &DMA1->LIFCR, 16}, + {3, DMA1, DMA1_Stream3, &DMA1->LISR, &DMA1->LIFCR, 22}, + {4, DMA1, DMA1_Stream4, &DMA1->HISR, &DMA1->HIFCR, 0}, + {5, DMA1, DMA1_Stream5, &DMA1->HISR, &DMA1->HIFCR, 6}, + {6, DMA1, DMA1_Stream6, &DMA1->HISR, &DMA1->HIFCR, 16}, + {7, DMA1, DMA1_Stream7, &DMA1->HISR, &DMA1->HIFCR, 22}, + {8, DMA2, DMA2_Stream0, &DMA2->LISR, &DMA2->LIFCR, 0}, + {9, DMA2, DMA2_Stream1, &DMA2->LISR, &DMA2->LIFCR, 6}, + {10, DMA2, DMA2_Stream2, &DMA2->LISR, &DMA2->LIFCR, 16}, + {11, DMA2, DMA2_Stream3, &DMA2->LISR, &DMA2->LIFCR, 22}, + {12, DMA2, DMA2_Stream4, &DMA2->HISR, &DMA2->HIFCR, 0}, + {13, DMA2, DMA2_Stream5, &DMA2->HISR, &DMA2->HIFCR, 6}, + {14, DMA2, DMA2_Stream6, &DMA2->HISR, &DMA2->HIFCR, 16}, + {15, DMA2, DMA2_Stream7, &DMA2->HISR, &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) { + stm32_dma_stream_t *stp; + + dma_streams_mask = 0; + for (i = 0 - 1; 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. + * Trying to allocate a stream already allocated is an illegal + * operation and is trapped if assertions are enabled. + * @pre The stream must not be already in use. + * @post The stream is allocated and the default ISR handler redirected + * to the specified function. + * @post The stream must be freed using @p dmaRelease() before it can + * be reused with another peripheral. + * @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 + * + * @special + */ +void dmaAllocate(stm32_dma_stream_t *dmastp, + stm32_dmaisr_t func, void *param) { + + chDbgCheck(dmastp != NULL, "dmaAllocate"); + + /* Checks if the stream is already taken.*/ + chDbgAssert((dma_streams_mask & dmastp->mask) == 0, + "dmaAllocate(), #1", "already allocated"); + + /* 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 & 0x000000FF) != 0) + RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; + if ((dma_streams_mask & 0x0000FF00) != 0) + RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; + + /* Making sure there are no spurious interrupts flags pending.*/ + dmaStreamClearInterrupt(); +} + +/** + * @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 dmaRequest(). + * @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 dmaRelease(stm32_dma_stream_t *dmastp) { + + /* Check if the streams is not taken.*/ + chDbgAssert((dma_streams_mask & dmastp->mask) != 0, + "dmaRelease(), #1", "not allocated"); + + /* 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 & 0x000000FF) == 0) + RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA1EN; + if ((dma_streams_mask & 0x0000FF00) == 0) + RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA2EN; +} + +#endif /* STM32_DMA_REQUIRED */ + +/** @} */ diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.h b/os/hal/platforms/STM32/DMAv2/stm32_dma.h new file mode 100644 index 000000000..805fd7c4b --- /dev/null +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.h @@ -0,0 +1,235 @@ +/* + 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 . +*/ + +/** + * @file DMAv2/stm32_dma.h + * @brief STM32F2xx 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]) +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief STM32 DMA stream descriptor structure. + */ +typedef struct { + uint32_t selfindex; /**< @brief Index to self in array. */ + DMA_TypeDef *dma; /**< @brief Associated DMA unit. */ + DMA_Stream_TypeDef *stream; /**< @brief Associated DMA stream. */ + volatile uint32_t *isr; /**< @brief Associated xISR reg. */ + volatile uint32_t *ifcr; /**< @brief Associated xIFCR reg. */ + uint32_t ishift; /**< @brief Bits offset in xISR and + xIFCR registers. */ +} 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 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] size value to be written in the NDTR register + * + * @special + */ +#define dmaStreamSetTransactionSize(dmastp, size) { \ + (dmastp)->stream->NDTR = (uint32_t)(size); \ +} + +/** + * @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] mode1 value to be written in the FCR register + * @param[in] mode2 value to be written in the CR register + * + * @special + */ +#define dmaStreamSetMode(dmastp, mode1, mode2) { \ + (dmastp)->stream->FCR = (uint32_t)(mode1); \ + (dmastp)->stream->CR = (uint32_t)(mode2); \ +} + +/** + * @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 |= DMA_SxCR_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 &= ~DMA_SxCR_EN; \ +} + +/** + * @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 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)->stream->ifcr = STM32_DMA_ISR_MASK << (dmastp)->stream->ishift; \ +} + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined() +extern _stm32_dma_streams[STM32_DMA_STREAMS]; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void dmaInit(void); + void dmaAllocate(stm32_dma_stream_t *dmastp, + stm32_dmaisr_t func, void *param); + void dmaRelease(stm32_dma_stream_t *dmastp); +#ifdef __cplusplus +} +#endif + +#endif /* _STM32_DMA_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32/GPIOv1/pal_lld.c b/os/hal/platforms/STM32/GPIOv1/pal_lld.c index a0a1fb6e5..81846fa58 100644 --- a/os/hal/platforms/STM32/GPIOv1/pal_lld.c +++ b/os/hal/platforms/STM32/GPIOv1/pal_lld.c @@ -19,8 +19,8 @@ */ /** - * @file STM32/pal_lld.c - * @brief STM32 GPIO low level driver code. + * @file STM32/GPIOv1/pal_lld.c + * @brief STM32F1xx GPIO low level driver code. * * @addtogroup PAL * @{ diff --git a/os/hal/platforms/STM32/GPIOv1/pal_lld.h b/os/hal/platforms/STM32/GPIOv1/pal_lld.h index fe2102637..65e660944 100644 --- a/os/hal/platforms/STM32/GPIOv1/pal_lld.h +++ b/os/hal/platforms/STM32/GPIOv1/pal_lld.h @@ -19,8 +19,8 @@ */ /** - * @file STM32/pal_lld.h - * @brief STM32 GPIO low level driver header. + * @file STM32/GPIOv1/pal_lld.h + * @brief STM32F1xx GPIO low level driver header. * * @addtogroup PAL * @{ -- cgit v1.2.3 From fe0093f795b6c88db8f12e2f7e45e11355fc3340 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 26 Aug 2011 13:47:22 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3254 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/stm32_dma.c | 2 +- os/hal/platforms/STM32/DMAv1/stm32_dma.h | 2 +- os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c | 239 ++++++++++++++++++++++++ os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h | 261 +++++++++++++++++++++++++++ os/hal/platforms/STM32/DMAv2/stm32_dma.c | 88 ++++++--- os/hal/platforms/STM32/DMAv2/stm32_dma.h | 150 +++++++++++---- os/hal/src/adc.c | 4 + os/hal/src/can.c | 4 + os/hal/src/gpt.c | 4 + os/hal/src/hal.c | 4 + os/hal/src/i2c.c | 4 + os/hal/src/icu.c | 4 + os/hal/src/mac.c | 4 + os/hal/src/mmc_spi.c | 4 + os/hal/src/pal.c | 4 + os/hal/src/pwm.c | 4 + os/hal/src/sdc.c | 4 + os/hal/src/serial.c | 4 + os/hal/src/serial_usb.c | 4 + os/hal/src/spi.c | 4 + os/hal/src/uart.c | 4 + os/hal/src/usb.c | 4 + os/hal/templates/adc_lld.c | 4 + os/hal/templates/can_lld.c | 4 + os/hal/templates/gpt_lld.c | 4 + os/hal/templates/hal_lld.c | 4 + os/hal/templates/i2c_lld.c | 4 + os/hal/templates/icu_lld.c | 4 + os/hal/templates/mac_lld.c | 4 + os/hal/templates/meta/driver.c | 4 + os/hal/templates/meta/driver_lld.c | 4 + os/hal/templates/pal_lld.c | 4 + os/hal/templates/pwm_lld.c | 4 + os/hal/templates/serial_lld.c | 4 + os/hal/templates/spi_lld.c | 4 + os/hal/templates/uart_lld.c | 4 + os/hal/templates/usb_lld.c | 4 + 37 files changed, 799 insertions(+), 67 deletions(-) create mode 100644 os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c create mode 100644 os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.c b/os/hal/platforms/STM32/DMAv1/stm32_dma.c index 4ea8e99ee..ae1a7170f 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.c @@ -19,7 +19,7 @@ */ /** - * @file stm32_dma.c + * @file DMAv1/stm32_dma.c * @brief STM32 DMA helper driver code. * * @addtogroup STM32_DMA diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.h b/os/hal/platforms/STM32/DMAv1/stm32_dma.h index 7ef5ad8b9..5ee06e939 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.h @@ -19,7 +19,7 @@ */ /** - * @file stm32_dma.h + * @file DMAv1/stm32_dma.h * @brief STM32 DMA helper driver header. * @note This file requires definitions from the ST STM32 header file * stm32f10x.h. diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c new file mode 100644 index 000000000..a1ade4409 --- /dev/null +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c @@ -0,0 +1,239 @@ +/* + 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 . +*/ + +/** + * @file DMAv1/stm32_dma.c + * @brief 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 0x0000007F + +/** + * @brief Mask of the DMA2 streams in @p dma_streams_mask. + */ +#define STM32_DMA2_STREAMS_MASK 0x00000F80 + +/*===========================================================================*/ +/* 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] = { + {0, DMA1, DMA1_Channel1, &DMA1->IFCR, 0}, + {1, DMA1, DMA1_Channel2, &DMA1->IFCR, 4}, + {2, DMA1, DMA1_Channel3, &DMA1->IFCR, 8}, + {3, DMA1, DMA1_Channel4, &DMA1->IFCR, 12}, + {4, DMA1, DMA1_Channel5, &DMA1->IFCR, 16}, + {5, DMA1, DMA1_Channel6, &DMA1->IFCR, 20}, + {6, DMA1, DMA1_Channel7, &DMA1->IFCR, 24}, +#if STM32_HAS_DMA2 || defined(__DOXYGEN__) + {7, DMA2, DMA2_Channel1, &DMA2->IFCR, 0}, + {8, DMA2, DMA2_Channel2, &DMA2->IFCR, 4}, + {9, DMA2, DMA2_Channel3, &DMA2->IFCR, 8}, + {10, DMA2, DMA2_Channel4, &DMA2->IFCR, 12}, + {11, DMA2, DMA2_Channel5, &DMA2->IFCR, 16}, +#endif +}; + +/*===========================================================================*/ +/* 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 1 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 0) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[0].dma_func) + dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/*===========================================================================*/ +/* 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].channel->CCR = 0; + dma_isr_redir[i].dma_func = NULL; + } + DMA1->IFCR = 0xFFFFFFFF; +#if STM32_HAS_DMA2 + DMA2->IFCR = 0xFFFFFFFF; +#endif +} + +/** + * @brief Allocates a DMA stream. + * @details The stream is allocated and, if required, the DMA clock enabled. + * Trying to allocate a stream already allocated is an illegal + * operation and is trapped if assertions are enabled. + * @pre The stream must not be already in use. + * @post The stream is allocated and the default ISR handler redirected + * to the specified function. + * @post The stream must be freed using @p dmaRelease() before it can + * be reused with another peripheral. + * @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 dmaAllocate(stm32_dma_stream_t *dmastp, + stm32_dmaisr_t func, void *param) { + + chDbgCheck(dmastp != NULL, "dmaAllocate"); + + /* Checks if the stream is already taken.*/ + if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0) + return TRUE; + + /* Marks the stream as allocated.*/ + dma_isr_redir[dmastp->selfindex].dma_func = func; + dma_isr_redir[dmastp->selfindex].dma_param = param; + dma_streams_mask |= (1 << dmastp->selfindex); + + /* Enabling DMA clocks required by the current streams set.*/ + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) + RCC->AHBENR |= RCC_AHBENR_DMA1EN; +#if STM32_HAS_DMA2 + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) + RCC->AHBENR |= RCC_AHBENR_DMA2EN; +#endif + + /* Making sure there are no spurious interrupts flags pending.*/ + dmaStreamClearInterrupt(dmastp); + 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 dmaRequest(). + * @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 dmaRelease(stm32_dma_stream_t *dmastp) { + + chDbgCheck(dmastp != NULL, "dmaRelease"); + + /* Check if the streams is not taken.*/ + chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0, + "dmaRelease(), #1", "not allocated"); + + /* Marks the stream as not allocated.*/ + dma_streams_mask &= ~(1 << dmastp->selfindex); + + /* Shutting down clocks that are no more required, if any.*/ + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) + RCC->AHBENR &= ~RCC_AHBENR_DMA1EN; +#if STM32_HAS_DMA2 + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) + RCC->AHBENR &= ~RCC_AHBENR_DMA2EN; +#endif +} + +#endif /* STM32_DMA_REQUIRED */ + +/** @} */ diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h new file mode 100644 index 000000000..45c683c07 --- /dev/null +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h @@ -0,0 +1,261 @@ +/* + 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 . +*/ + +/** + * @file DMAv1/stm32_dma.h + * @brief DMA helper driver header. + * @note This file requires definitions from the ST header files + * stm32f10x.h or stm32l1xx.h. + * @note This driver uses the new naming convention used for the STM32F2xx + * so the "DMA channels" are referred as "DMA streams". + * + * @addtogroup STM32_DMA + * @{ + */ + +#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. + */ +#if STM32_HAS_DMA2 || defined(__DOXYGEN__) +#define STM32_DMA_STREAMS 12 +#else +#define STM32_DMA_STREAMS 7 +#endif + +/** + * @brief Mask of the ISR bits passed to the DMA callback functions. + */ +#define STM32_DMA_ISR_MASK 0x0F + +/** + * @name DMA streams identifiers + * @{ + */ +#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[0]) +#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[1]) +#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[2]) +#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[3]) +#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[4]) +#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[5]) +#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[6]) +#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[8]) +#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[9]) +#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[10]) +#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[11]) +#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[12]) +/** @} */ + +/** + * @name CR register constants common to all DMA types + */ +#define STM32_DMA_CR_EN DMA_CCR1_EN +#define STM32_DMA_CR_TEIE DMA_CCR1_TEIE +#define STM32_DMA_CR_HTIE DMA_CCR1_HTIE +#define STM32_DMA_CR_TCIE DMA_CCR1_TCIE +#define STM32_DMA_CR_DIR_MASK (DMA_CCR1_DIR | DMA_CCR1_MEM2MEM) +#define STM32_DMA_CR_DIR_P2M 0 +#define STM32_DMA_CR_DIR_M2P DMA_CCR1_DIR +#define STM32_DMA_CR_DIR_M2M DMA_CCR1_MEM2MEM +#define STM32_DMA_CR_CIRC DMA_CCR1_CIRC +#define STM32_DMA_CR_PINC DMA_CCR1_PINC +#define STM32_DMA_CR_MINC DMA_CCR1_MINC +#define STM32_DMA_CR_PSIZE_MASK DMA_CCR1_PSIZE +#define STM32_DMA_CR_PSIZE_BYTE 0 +#define STM32_DMA_CR_PSIZE_HWORD DMA_CCR1_PSIZE_0 +#define STM32_DMA_CR_PSIZE_WORD DMA_CCR1_PSIZE_1 +#define STM32_DMA_CR_MSIZE_MASK DMA_CCR1_MSIZE +#define STM32_DMA_CR_MSIZE_BYTE 0 +#define STM32_DMA_CR_MSIZE_HWORD DMA_CCR1_MSIZE_0 +#define STM32_DMA_CR_MSIZE_WORD DMA_CCR1_MSIZE_1 +#define STM32_DMA_CR_PL_MASK DMA_CCR1_PL +#define STM32_DMA_CR_PL(n) ((n) << 16) +/** @} */ +/** + * @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. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief STM32 DMA stream descriptor structure. + */ +typedef struct { + uint32_t selfindex; /**< @brief Index to self in array. */ + DMA_TypeDef *dma; /**< @brief Associated DMA unit. */ + DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */ + volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */ + uint32_t ishift; /**< @brief Bits offset in xIFCR + register. */ +} stm32_dma_stream_t; + +/** + * @brief STM32 DMA ISR function type. + * + * @param[in] p parameter for the registered function + * @param[in] flags pre-shifted content of the ISR register, 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 CPAR register + * + * @special + */ +#define dmaStreamSetPeripheral(dmastp, addr) { \ + (dmastp)->channel->CPAR = (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 CMAR register + * + * @special + */ +#define dmaStreamSetMemory0(dmastp, addr) { \ + (dmastp)->channel->CMAR = (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] size value to be written in the CNDTR register + * + * @special + */ +#define dmaStreamSetTransactionSize(dmastp, size) { \ + (dmastp)->channel->CNDTR = (uint32_t)(size); \ +} + +/** + * @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)(mode2); \ +} + +/** + * @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)->channel->CCR |= 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)->channel->CCR &= ~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 dmaAllocate(stm32_dma_stream_t *dmastp, + stm32_dmaisr_t func, void *param); + void dmaRelease(stm32_dma_stream_t *dmastp); +#ifdef __cplusplus +} +#endif + +#endif /* _STM32_DMA_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.c b/os/hal/platforms/STM32/DMAv2/stm32_dma.c index d64cfc5f9..48c0d4e95 100644 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.c @@ -20,7 +20,7 @@ /** * @file DMAv2/stm32_dma.c - * @brief STM32F2xx Enhanced DMA helper driver code. + * @brief Enhanced DMA helper driver code. * * @addtogroup STM32_DMA * @details DMA sharing helper driver. In the STM32 the DMA streams are a @@ -40,6 +40,20 @@ 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 + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -51,23 +65,23 @@ * @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[16] = { - {0, DMA1, DMA1_Stream0, &DMA1->LISR, &DMA1->LIFCR, 0}, - {1, DMA1, DMA1_Stream1, &DMA1->LISR, &DMA1->LIFCR, 6}, - {2, DMA1, DMA1_Stream2, &DMA1->LISR, &DMA1->LIFCR, 16}, - {3, DMA1, DMA1_Stream3, &DMA1->LISR, &DMA1->LIFCR, 22}, - {4, DMA1, DMA1_Stream4, &DMA1->HISR, &DMA1->HIFCR, 0}, - {5, DMA1, DMA1_Stream5, &DMA1->HISR, &DMA1->HIFCR, 6}, - {6, DMA1, DMA1_Stream6, &DMA1->HISR, &DMA1->HIFCR, 16}, - {7, DMA1, DMA1_Stream7, &DMA1->HISR, &DMA1->HIFCR, 22}, - {8, DMA2, DMA2_Stream0, &DMA2->LISR, &DMA2->LIFCR, 0}, - {9, DMA2, DMA2_Stream1, &DMA2->LISR, &DMA2->LIFCR, 6}, - {10, DMA2, DMA2_Stream2, &DMA2->LISR, &DMA2->LIFCR, 16}, - {11, DMA2, DMA2_Stream3, &DMA2->LISR, &DMA2->LIFCR, 22}, - {12, DMA2, DMA2_Stream4, &DMA2->HISR, &DMA2->HIFCR, 0}, - {13, DMA2, DMA2_Stream5, &DMA2->HISR, &DMA2->HIFCR, 6}, - {14, DMA2, DMA2_Stream6, &DMA2->HISR, &DMA2->HIFCR, 16}, - {15, DMA2, DMA2_Stream7, &DMA2->HISR, &DMA2->HIFCR, 22}, +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}, }; /*===========================================================================*/ @@ -398,11 +412,11 @@ CH_IRQ_HANDLER(DMA2_Stream7_IRQHandler) { * @init */ void dmaInit(void) { - stm32_dma_stream_t *stp; + int i; dma_streams_mask = 0; - for (i = 0 - 1; i < STM32_DMA_STREAMS; i--) { - _stm32_dma_streams[i]->stream->CR = 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; @@ -426,17 +440,20 @@ void dmaInit(void) { * @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 */ -void dmaAllocate(stm32_dma_stream_t *dmastp, - stm32_dmaisr_t func, void *param) { +bool_t dmaAllocate(stm32_dma_stream_t *dmastp, + stm32_dmaisr_t func, void *param) { chDbgCheck(dmastp != NULL, "dmaAllocate"); /* Checks if the stream is already taken.*/ - chDbgAssert((dma_streams_mask & dmastp->mask) == 0, - "dmaAllocate(), #1", "already allocated"); + if ((dma_streams_mask & dmastp->mask) != 0) + return TRUE; /* Marks the stream as allocated.*/ dma_isr_redir[dmastp->selfindex].dma_func = func; @@ -444,13 +461,18 @@ void dmaAllocate(stm32_dma_stream_t *dmastp, dma_streams_mask |= (1 << dmastp->selfindex); /* Enabling DMA clocks required by the current streams set.*/ - if ((dma_streams_mask & 0x000000FF) != 0) + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) { RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; - if ((dma_streams_mask & 0x0000FF00) != 0) + RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA1LPEN; + } + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) { RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; + RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA2LPEN; + } /* Making sure there are no spurious interrupts flags pending.*/ - dmaStreamClearInterrupt(); + dmaStreamClearInterrupt(dmastp); + return FALSE; } /** @@ -468,6 +490,8 @@ void dmaAllocate(stm32_dma_stream_t *dmastp, */ void dmaRelease(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"); @@ -476,10 +500,14 @@ void dmaRelease(stm32_dma_stream_t *dmastp) { dma_streams_mask &= ~(1 << dmastp->selfindex); /* Shutting down clocks that are no more required, if any.*/ - if ((dma_streams_mask & 0x000000FF) == 0) + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) { RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA1EN; - if ((dma_streams_mask & 0x0000FF00) == 0) + 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 */ diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.h b/os/hal/platforms/STM32/DMAv2/stm32_dma.h index 805fd7c4b..5d87e67a9 100644 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.h @@ -20,7 +20,7 @@ /** * @file DMAv2/stm32_dma.h - * @brief STM32F2xx Enhanced DMA helper driver header. + * @brief Enhanced-DMA helper driver header. * @note This file requires definitions from the ST STM32F2xx header file * stm32f2xx.h. * @@ -39,33 +39,104 @@ * @brief Total number of DMA streams. * @note This is the total number of streams among all the DMA units. */ -#define STM32_DMA_STREAMS 16 +#define STM32_DMA_STREAMS 16 /** * @brief Mask of the ISR bits passed to the DMA callback functions. */ -#define STM32_DMA_ISR_MASK 0x3D +#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]) +#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 /** @} */ /*===========================================================================*/ @@ -89,8 +160,8 @@ typedef struct { DMA_Stream_TypeDef *stream; /**< @brief Associated DMA stream. */ volatile uint32_t *isr; /**< @brief Associated xISR reg. */ volatile uint32_t *ifcr; /**< @brief Associated xIFCR reg. */ - uint32_t ishift; /**< @brief Bits offset in xISR and - xIFCR registers. */ + uint32_t ishift; /**< @brief Bits offset in xIFCR + registers. */ } stm32_dma_stream_t; /** @@ -163,14 +234,25 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * @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] mode1 value to be written in the FCR register - * @param[in] mode2 value to be written in the CR register + * @param[in] mode value to be written in the CR register + * + * @special + */ +#define dmaStreamSetMode(dmastp, mode) { \ + (dmastp)->stream->CR = (uint32_t)(mode2); \ +} + +/** + * @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 dmaStreamSetMode(dmastp, mode1, mode2) { \ - (dmastp)->stream->FCR = (uint32_t)(mode1); \ - (dmastp)->stream->CR = (uint32_t)(mode2); \ +#define dmaStreamSetFIFO(dmastp, mode) { \ + (dmastp)->stream->FCR = (uint32_t)(mode); \ } /** @@ -182,7 +264,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * @special */ #define dmaStreamEnable(dmachp) { \ - (dmastp)->stream->CR |= DMA_SxCR_EN; \ + (dmastp)->stream->CR |= STM32_DMA_CR_EN; \ } /** @@ -194,13 +276,11 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * @special */ #define dmaStreamDisable(dmastp) { \ - (dmastp)->stream->CR &= ~DMA_SxCR_EN; \ + (dmastp)->stream->CR &= ~STM32_DMA_CR_EN; \ } /** * @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 This function can be invoked in both ISR or thread context. * * @param[in] dmastp pointer to a stm32_dma_stream_t structure @@ -208,23 +288,23 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * @special */ #define dmaStreamClearInterrupt(dmastp) { \ - *(dmastp)->stream->ifcr = STM32_DMA_ISR_MASK << (dmastp)->stream->ishift; \ + *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \ } /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ -#if !defined() -extern _stm32_dma_streams[STM32_DMA_STREAMS]; +#if !defined(__DOXYGEN__) +extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; #endif #ifdef __cplusplus extern "C" { #endif void dmaInit(void); - void dmaAllocate(stm32_dma_stream_t *dmastp, - stm32_dmaisr_t func, void *param); + bool_t dmaAllocate(stm32_dma_stream_t *dmastp, + stm32_dmaisr_t func, void *param); void dmaRelease(stm32_dma_stream_t *dmastp); #ifdef __cplusplus } diff --git a/os/hal/src/adc.c b/os/hal/src/adc.c index f2bf4eadd..c375818a6 100644 --- a/os/hal/src/adc.c +++ b/os/hal/src/adc.c @@ -31,6 +31,10 @@ #if HAL_USE_ADC || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/can.c b/os/hal/src/can.c index f9a827c4e..e888c2ae7 100644 --- a/os/hal/src/can.c +++ b/os/hal/src/can.c @@ -31,6 +31,10 @@ #if HAL_USE_CAN || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/gpt.c b/os/hal/src/gpt.c index 5f424453d..c677f5284 100644 --- a/os/hal/src/gpt.c +++ b/os/hal/src/gpt.c @@ -31,6 +31,10 @@ #if HAL_USE_GPT || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/hal.c b/os/hal/src/hal.c index 1a15988f5..ef7d7af8b 100644 --- a/os/hal/src/hal.c +++ b/os/hal/src/hal.c @@ -29,6 +29,10 @@ #include "ch.h" #include "hal.h" +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c index 86bfc16f6..260dcbb17 100644 --- a/os/hal/src/i2c.c +++ b/os/hal/src/i2c.c @@ -31,6 +31,10 @@ #if HAL_USE_I2C || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/icu.c b/os/hal/src/icu.c index 79d38798e..c73ea5106 100644 --- a/os/hal/src/icu.c +++ b/os/hal/src/icu.c @@ -31,6 +31,10 @@ #if HAL_USE_ICU || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/mac.c b/os/hal/src/mac.c index 4d6a9b2cd..0f1c47576 100644 --- a/os/hal/src/mac.c +++ b/os/hal/src/mac.c @@ -33,6 +33,10 @@ #if HAL_USE_MAC || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/mmc_spi.c b/os/hal/src/mmc_spi.c index e6dcf9287..34d111c2d 100644 --- a/os/hal/src/mmc_spi.c +++ b/os/hal/src/mmc_spi.c @@ -31,6 +31,10 @@ #if HAL_USE_MMC_SPI || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/pal.c b/os/hal/src/pal.c index 10e57e284..afb5c6b40 100644 --- a/os/hal/src/pal.c +++ b/os/hal/src/pal.c @@ -31,6 +31,10 @@ #if HAL_USE_PAL || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/pwm.c b/os/hal/src/pwm.c index e7dd6b64c..588b3df5c 100644 --- a/os/hal/src/pwm.c +++ b/os/hal/src/pwm.c @@ -31,6 +31,10 @@ #if HAL_USE_PWM || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c index 6bdaa2b5a..758edf8d8 100644 --- a/os/hal/src/sdc.c +++ b/os/hal/src/sdc.c @@ -31,6 +31,10 @@ #if HAL_USE_SDC || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/serial.c b/os/hal/src/serial.c index 03b74be54..d962bcdcd 100644 --- a/os/hal/src/serial.c +++ b/os/hal/src/serial.c @@ -31,6 +31,10 @@ #if HAL_USE_SERIAL || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c index 3f53d7df0..d9c25ecdf 100644 --- a/os/hal/src/serial_usb.c +++ b/os/hal/src/serial_usb.c @@ -33,6 +33,10 @@ #if HAL_USE_SERIAL_USB || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/spi.c b/os/hal/src/spi.c index aaf0115eb..b91b44507 100644 --- a/os/hal/src/spi.c +++ b/os/hal/src/spi.c @@ -31,6 +31,10 @@ #if HAL_USE_SPI || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/uart.c b/os/hal/src/uart.c index 372a3ad02..ed28ecb3b 100644 --- a/os/hal/src/uart.c +++ b/os/hal/src/uart.c @@ -31,6 +31,10 @@ #if HAL_USE_UART || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/usb.c b/os/hal/src/usb.c index 8493b6f41..44a772ab1 100644 --- a/os/hal/src/usb.c +++ b/os/hal/src/usb.c @@ -34,6 +34,10 @@ #if HAL_USE_USB || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/adc_lld.c b/os/hal/templates/adc_lld.c index eea062160..d5e8f5234 100644 --- a/os/hal/templates/adc_lld.c +++ b/os/hal/templates/adc_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_ADC || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/can_lld.c b/os/hal/templates/can_lld.c index ae0ca9607..2787591b2 100644 --- a/os/hal/templates/can_lld.c +++ b/os/hal/templates/can_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_CAN || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/gpt_lld.c b/os/hal/templates/gpt_lld.c index 1ee010603..308ce1921 100644 --- a/os/hal/templates/gpt_lld.c +++ b/os/hal/templates/gpt_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_GPT || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/hal_lld.c b/os/hal/templates/hal_lld.c index aead6dc43..3609f5fca 100644 --- a/os/hal/templates/hal_lld.c +++ b/os/hal/templates/hal_lld.c @@ -29,6 +29,10 @@ #include "ch.h" #include "hal.h" +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/i2c_lld.c b/os/hal/templates/i2c_lld.c index efd491857..ba8be9a45 100644 --- a/os/hal/templates/i2c_lld.c +++ b/os/hal/templates/i2c_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_I2C || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/icu_lld.c b/os/hal/templates/icu_lld.c index 23596bc97..3d6d2dc62 100644 --- a/os/hal/templates/icu_lld.c +++ b/os/hal/templates/icu_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_ICU || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/mac_lld.c b/os/hal/templates/mac_lld.c index c6cc7825b..62b8765d0 100644 --- a/os/hal/templates/mac_lld.c +++ b/os/hal/templates/mac_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_MAC || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/meta/driver.c b/os/hal/templates/meta/driver.c index c12103353..0c198e320 100644 --- a/os/hal/templates/meta/driver.c +++ b/os/hal/templates/meta/driver.c @@ -31,6 +31,10 @@ #if HAL_USE_XXX || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/meta/driver_lld.c b/os/hal/templates/meta/driver_lld.c index 2cf87bf1f..0e446808e 100644 --- a/os/hal/templates/meta/driver_lld.c +++ b/os/hal/templates/meta/driver_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_XXX || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/pal_lld.c b/os/hal/templates/pal_lld.c index 5314ef4b2..29336efda 100644 --- a/os/hal/templates/pal_lld.c +++ b/os/hal/templates/pal_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_PAL || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/pwm_lld.c b/os/hal/templates/pwm_lld.c index 67683d120..5a1977487 100644 --- a/os/hal/templates/pwm_lld.c +++ b/os/hal/templates/pwm_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_PWM || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/serial_lld.c b/os/hal/templates/serial_lld.c index 8fe70f628..26df9a38a 100644 --- a/os/hal/templates/serial_lld.c +++ b/os/hal/templates/serial_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_SERIAL || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/spi_lld.c b/os/hal/templates/spi_lld.c index c6162d7e0..138c5ceb7 100644 --- a/os/hal/templates/spi_lld.c +++ b/os/hal/templates/spi_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_SPI || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/uart_lld.c b/os/hal/templates/uart_lld.c index 21708858b..11fbc5ea5 100644 --- a/os/hal/templates/uart_lld.c +++ b/os/hal/templates/uart_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_UART || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/usb_lld.c b/os/hal/templates/usb_lld.c index 515fc5443..b451a9ecc 100644 --- a/os/hal/templates/usb_lld.c +++ b/os/hal/templates/usb_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_USB || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ -- cgit v1.2.3 From d2e9a52cf6b2997b9b6320434ea296bde79b3727 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Aug 2011 08:53:14 +0000 Subject: New DMA helper driver for STM32F1xx and STM32L1xx. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3255 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/sdc.h | 2 +- os/hal/platforms/STM32/DMAv1/sdc_lld.c | 86 ++++---- os/hal/platforms/STM32/DMAv1/spi_lld.c | 169 ++++++++------- os/hal/platforms/STM32/DMAv1/spi_lld.h | 32 +-- os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c | 303 +++++++++++++++++++++++++-- os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h | 33 ++- os/hal/platforms/STM32/DMAv1/uart_lld.c | 180 ++++++++-------- os/hal/platforms/STM32/DMAv1/uart_lld.h | 12 +- os/hal/platforms/STM32/DMAv2/stm32_dma.c | 6 +- os/hal/platforms/STM32/DMAv2/stm32_dma.h | 19 +- os/hal/platforms/STM32F1xx/adc_lld.c | 50 ++--- os/hal/platforms/STM32F1xx/adc_lld.h | 8 +- readme.txt | 3 + testhal/STM32F1xx/ADC/chconf.h | 12 +- testhal/STM32F1xx/SDIO/chconf.h | 12 +- testhal/STM32F1xx/SPI/chconf.h | 12 +- testhal/STM32F1xx/SPI/mcuconf.h | 2 +- testhal/STM32F1xx/UART/chconf.h | 12 +- testhal/STM32F1xx/UART/main.c | 4 +- testhal/STM32F1xx/UART/mcuconf.h | 4 +- 20 files changed, 632 insertions(+), 329 deletions(-) diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h index 466c48fa6..8de6de823 100644 --- a/os/hal/include/sdc.h +++ b/os/hal/include/sdc.h @@ -242,7 +242,7 @@ extern "C" { uint8_t *buffer, uint32_t n); bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk, const uint8_t *buffer, uint32_t n); - bool_t sdc_wait_for_transfer_state(SDCDriver *sdcp); + bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp); #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/STM32/DMAv1/sdc_lld.c b/os/hal/platforms/STM32/DMAv1/sdc_lld.c index a88ad53fa..b9e02a815 100644 --- a/os/hal/platforms/STM32/DMAv1/sdc_lld.c +++ b/os/hal/platforms/STM32/DMAv1/sdc_lld.c @@ -78,15 +78,17 @@ static bool_t sdc_lld_read_multiple(SDCDriver *sdcp, uint32_t startblk, uint32_t resp[1]; /* Checks for errors and waits for the card to be ready for reading.*/ - if (sdc_wait_for_transfer_state(sdcp)) + if (_sdc_wait_for_transfer_state(sdcp)) return TRUE; /* Prepares the DMA channel for reading.*/ - dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], - (n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf, - (STM32_SDC_SDIO_DMA_PRIORITY << 12) | - DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 | - DMA_CCR1_MINC); + dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); + dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, + (n * SDC_BLOCK_SIZE) / sizeof (uint32_t)); + dmaStreamSetMode(STM32_DMA2_STREAM4, + STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | + STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_PSIZE_WORD | + STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); /* Setting up data transfer. Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/ @@ -100,7 +102,7 @@ static bool_t sdc_lld_read_multiple(SDCDriver *sdcp, uint32_t startblk, SDIO_DCTRL_DTEN; /* DMA channel activation.*/ - dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamEnable(STM32_DMA2_STREAM4); /* Read multiple blocks command.*/ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) @@ -123,14 +125,14 @@ static bool_t sdc_lld_read_multiple(SDCDriver *sdcp, uint32_t startblk, chSysUnlock(); goto error; } - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->DCTRL = 0; chSysUnlock(); return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); error: - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->MASK = 0; SDIO->DCTRL = 0; @@ -156,15 +158,17 @@ static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk, uint32_t resp[1]; /* Checks for errors and waits for the card to be ready for reading.*/ - if (sdc_wait_for_transfer_state(sdcp)) + if (_sdc_wait_for_transfer_state(sdcp)) return TRUE; /* Prepares the DMA channel for reading.*/ - dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], - SDC_BLOCK_SIZE / sizeof (uint32_t), buf, - (STM32_SDC_SDIO_DMA_PRIORITY << 12) | - DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 | - DMA_CCR1_MINC); + dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); + dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, + SDC_BLOCK_SIZE / sizeof (uint32_t)); + dmaStreamSetMode(STM32_DMA2_STREAM4, + STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | + STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_PSIZE_WORD | + STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); /* Setting up data transfer. Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/ @@ -178,7 +182,7 @@ static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk, SDIO_DCTRL_DTEN; /* DMA channel activation.*/ - dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamEnable(STM32_DMA2_STREAM4); /* Read single block command.*/ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) @@ -201,14 +205,14 @@ static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk, chSysUnlock(); goto error; } - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->DCTRL = 0; chSysUnlock(); return FALSE; error: - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->MASK = 0; SDIO->DCTRL = 0; @@ -235,15 +239,17 @@ static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk, uint32_t resp[1]; /* Checks for errors and waits for the card to be ready for writing.*/ - if (sdc_wait_for_transfer_state(sdcp)) + if (_sdc_wait_for_transfer_state(sdcp)) return TRUE; /* Prepares the DMA channel for writing.*/ - dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], - (n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf, - (STM32_SDC_SDIO_DMA_PRIORITY << 12) | - DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 | - DMA_CCR1_MINC | DMA_CCR1_DIR); + dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); + dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, + (n * SDC_BLOCK_SIZE) / sizeof (uint32_t)); + dmaStreamSetMode(STM32_DMA2_STREAM4, + STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | + STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD | + STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); /* Write multiple blocks command.*/ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) @@ -265,7 +271,7 @@ static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk, SDIO_DCTRL_DTEN; /* DMA channel activation.*/ - dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamEnable(STM32_DMA2_STREAM4); /* Note the mask is checked before going to sleep because the interrupt may have occurred before reaching the critical zone.*/ @@ -282,14 +288,14 @@ static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk, chSysUnlock(); goto error; } - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->DCTRL = 0; chSysUnlock(); return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); error: - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->MASK = 0; SDIO->DCTRL = 0; @@ -316,15 +322,17 @@ static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk, uint32_t resp[1]; /* Checks for errors and waits for the card to be ready for writing.*/ - if (sdc_wait_for_transfer_state(sdcp)) + if (_sdc_wait_for_transfer_state(sdcp)) return TRUE; /* Prepares the DMA channel for writing.*/ - dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], - SDC_BLOCK_SIZE / sizeof (uint32_t), buf, - (STM32_SDC_SDIO_DMA_PRIORITY << 12) | - DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 | - DMA_CCR1_MINC | DMA_CCR1_DIR); + dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); + dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, + SDC_BLOCK_SIZE / sizeof (uint32_t)); + dmaStreamSetMode(STM32_DMA2_STREAM4, + STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | + STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD | + STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); /* Write single block command.*/ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) @@ -346,7 +354,7 @@ static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk, SDIO_DCTRL_DTEN; /* DMA channel activation.*/ - dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamEnable(STM32_DMA2_STREAM4); /* Note the mask is checked before going to sleep because the interrupt may have occurred before reaching the critical zone.*/ @@ -363,14 +371,14 @@ static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk, chSysUnlock(); goto error; } - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->DCTRL = 0; chSysUnlock(); return FALSE; error: - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->MASK = 0; SDIO->DCTRL = 0; @@ -431,8 +439,8 @@ void sdc_lld_start(SDCDriver *sdcp) { if (sdcp->state == SDC_STOP) { /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_4, NULL, NULL); - dmaChannelSetPeripheral(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], &SDIO->FIFO); + dmaStreamAllocate(STM32_DMA2_STREAM4, 0, NULL, NULL); + dmaStreamSetPeripheral(STM32_DMA2_STREAM4, &SDIO->FIFO); NVICEnableVector(SDIO_IRQn, CORTEX_PRIORITY_MASK(STM32_SDC_SDIO_IRQ_PRIORITY)); RCC->AHBENR |= RCC_AHBENR_SDIOEN; @@ -461,7 +469,7 @@ void sdc_lld_stop(SDCDriver *sdcp) { /* Clock deactivation.*/ NVICDisableVector(SDIO_IRQn); - dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_4); + dmaStreamRelease(STM32_DMA2_STREAM4); } } diff --git a/os/hal/platforms/STM32/DMAv1/spi_lld.c b/os/hal/platforms/STM32/DMAv1/spi_lld.c index d8ae657a7..9302b0102 100644 --- a/os/hal/platforms/STM32/DMAv1/spi_lld.c +++ b/os/hal/platforms/STM32/DMAv1/spi_lld.c @@ -67,8 +67,8 @@ static uint16_t dummyrx; * @param[in] spip pointer to the @p SPIDriver object */ #define dma_stop(spip) { \ - dmaChannelDisable(spip->dmatx); \ - dmaChannelDisable(spip->dmarx); \ + dmaStreamDisable(spip->dmatx); \ + dmaStreamDisable(spip->dmarx); \ } /** @@ -91,7 +91,7 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_SPI_DMA_ERROR_HOOK) - if ((flags & DMA_ISR_TEIF1) != 0) { + if ((flags & STM32_DMA_ISR_TEIF) != 0) { STM32_SPI_DMA_ERROR_HOOK(spip); } #else @@ -117,7 +117,7 @@ static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_SPI_DMA_ERROR_HOOK) (void)spip; - if ((flags & DMA_ISR_TEIF1) != 0) { + if ((flags & STM32_DMA_ISR_TEIF) != 0) { STM32_SPI_DMA_ERROR_HOOK(spip); } #else @@ -147,24 +147,24 @@ void spi_lld_init(void) { spiObjectInit(&SPID1); SPID1.thread = NULL; SPID1.spi = SPI1; - SPID1.dmarx = STM32_DMA1_CH2; - SPID1.dmatx = STM32_DMA1_CH3; + SPID1.dmarx = STM32_DMA1_STREAM2; + SPID1.dmatx = STM32_DMA1_STREAM3; #endif #if STM32_SPI_USE_SPI2 spiObjectInit(&SPID2); SPID2.thread = NULL; SPID2.spi = SPI2; - SPID2.dmarx = STM32_DMA1_CH4; - SPID2.dmatx = STM32_DMA1_CH5; + SPID2.dmarx = STM32_DMA1_STREAM4; + SPID2.dmatx = STM32_DMA1_STREAM5; #endif #if STM32_SPI_USE_SPI3 spiObjectInit(&SPID3); SPID3.thread = NULL; SPID3.spi = SPI3; - SPID3.dmarx = STM32_DMA2_CH1; - SPID3.dmatx = STM32_DMA2_CH2; + SPID3.dmarx = STM32_DMA2_STREAM1; + SPID3.dmatx = STM32_DMA2_STREAM2; #endif } @@ -181,60 +181,69 @@ void spi_lld_start(SPIDriver *spip) { if (spip->state == SPI_STOP) { #if STM32_SPI_USE_SPI1 if (&SPID1 == spip) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_2, - (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip); - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_3, - (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); - NVICEnableVector(DMA1_Channel2_IRQn, - CORTEX_PRIORITY_MASK(STM32_SPI_SPI1_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel3_IRQn, - CORTEX_PRIORITY_MASK(STM32_SPI_SPI1_IRQ_PRIORITY)); + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM2, + STM32_SPI_SPI1_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #1", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM3, + STM32_SPI_SPI1_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #2", "stream already allocated"); RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; } #endif #if STM32_SPI_USE_SPI2 if (&SPID2 == spip) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_4, - (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip); - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_5, - (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); - NVICEnableVector(DMA1_Channel4_IRQn, - CORTEX_PRIORITY_MASK(STM32_SPI_SPI2_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel5_IRQn, - CORTEX_PRIORITY_MASK(STM32_SPI_SPI2_IRQ_PRIORITY)); + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM4, + STM32_SPI_SPI2_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #3", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM5, + STM32_SPI_SPI2_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #4", "stream already allocated"); RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; } #endif #if STM32_SPI_USE_SPI3 if (&SPID3 == spip) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_1, - (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip); - dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_2, - (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); - NVICEnableVector(DMA2_Channel1_IRQn, - CORTEX_PRIORITY_MASK(STM32_SPI_SPI3_IRQ_PRIORITY)); - NVICEnableVector(DMA2_Channel2_IRQn, - CORTEX_PRIORITY_MASK(STM32_SPI_SPI3_IRQ_PRIORITY)); + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM1, + STM32_SPI_SPI3_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #5", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM2, + STM32_SPI_SPI3_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #6", "stream already allocated"); RCC->APB1ENR |= RCC_APB1ENR_SPI3EN; } #endif /* DMA setup.*/ - dmaChannelSetPeripheral(spip->dmarx, &spip->spi->DR); - dmaChannelSetPeripheral(spip->dmatx, &spip->spi->DR); + dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR); + dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR); } /* More DMA setup.*/ if ((spip->config->cr1 & SPI_CR1_DFF) == 0) - spip->dmaccr = (STM32_SPI_SPI2_DMA_PRIORITY << 12) | - DMA_CCR1_TEIE; /* 8 bits transfers. */ + spip->dmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) | + STM32_DMA_CR_TEIE | + STM32_DMA_CR_PSIZE_BYTE | + STM32_DMA_CR_MSIZE_BYTE; /* 8 bits transfers. */ else - spip->dmaccr = (STM32_SPI_SPI2_DMA_PRIORITY << 12) | - DMA_CCR1_TEIE | DMA_CCR1_MSIZE_0 | - DMA_CCR1_PSIZE_0; /* 16 bits transfers. */ + spip->dmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) | + STM32_DMA_CR_TEIE | + STM32_DMA_CR_PSIZE_HWORD | + STM32_DMA_CR_MSIZE_HWORD; /* 16 bits transfers. */ /* SPI setup and enable.*/ spip->spi->CR1 = 0; @@ -261,28 +270,22 @@ void spi_lld_stop(SPIDriver *spip) { #if STM32_SPI_USE_SPI1 if (&SPID1 == spip) { - NVICDisableVector(DMA1_Channel2_IRQn); - NVICDisableVector(DMA1_Channel3_IRQn); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_2); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_3); + dmaStreamRelease(STM32_DMA1_STREAM2); + dmaStreamRelease(STM32_DMA1_STREAM3); RCC->APB2ENR &= ~RCC_APB2ENR_SPI1EN; } #endif #if STM32_SPI_USE_SPI2 if (&SPID2 == spip) { - NVICDisableVector(DMA1_Channel4_IRQn); - NVICDisableVector(DMA1_Channel5_IRQn); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_4); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_5); + dmaStreamRelease(STM32_DMA1_STREAM4); + dmaStreamRelease(STM32_DMA1_STREAM5); RCC->APB1ENR &= ~RCC_APB1ENR_SPI2EN; } #endif #if STM32_SPI_USE_SPI3 if (&SPID3 == spip) { - NVICDisableVector(DMA2_Channel1_IRQn); - NVICDisableVector(DMA2_Channel2_IRQn); - dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_1); - dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_2); + dmaStreamRelease(STM32_DMA1_STREAM1); + dmaStreamRelease(STM32_DMA1_STREAM2); RCC->APB1ENR &= ~RCC_APB1ENR_SPI3EN; } #endif @@ -327,10 +330,14 @@ void spi_lld_unselect(SPIDriver *spip) { */ void spi_lld_ignore(SPIDriver *spip, size_t n) { - dmaChannelSetup(spip->dmarx, n, &dummyrx, - spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_EN); - dmaChannelSetup(spip->dmatx, n, &dummytx, - spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_EN); + dmaStreamSetMemory0(spip->dmarx, &dummyrx); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | STM32_DMA_CR_EN); + dmaStreamSetMemory0(spip->dmatx, &dummytx); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_EN); } /** @@ -351,12 +358,15 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) { void spi_lld_exchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf) { - dmaChannelSetup(spip->dmarx, n, rxbuf, - spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC | - DMA_CCR1_EN); - dmaChannelSetup(spip->dmatx, n, txbuf, - spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC | - DMA_CCR1_EN); + dmaStreamSetMemory0(spip->dmarx, rxbuf); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | STM32_DMA_CR_MINC | + STM32_DMA_CR_EN); + dmaStreamSetMemory0(spip->dmatx, txbuf); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_MINC | STM32_DMA_CR_EN); } /** @@ -374,11 +384,14 @@ void spi_lld_exchange(SPIDriver *spip, size_t n, */ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { - dmaChannelSetup(spip->dmarx, n, &dummyrx, - spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_EN); - dmaChannelSetup(spip->dmatx, n, txbuf, - spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC | - DMA_CCR1_EN); + dmaStreamSetMemory0(spip->dmarx, &dummyrx); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | STM32_DMA_CR_EN); + dmaStreamSetMemory0(spip->dmatx, txbuf); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_MINC | STM32_DMA_CR_EN); } /** @@ -396,11 +409,15 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { */ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { - dmaChannelSetup(spip->dmarx, n, rxbuf, - spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC | - DMA_CCR1_EN); - dmaChannelSetup(spip->dmatx, n, &dummytx, - spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_EN); + dmaStreamSetMemory0(spip->dmarx, rxbuf); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | STM32_DMA_CR_MINC | + STM32_DMA_CR_EN); + dmaStreamSetMemory0(spip->dmatx, &dummytx); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_EN); } /** diff --git a/os/hal/platforms/STM32/DMAv1/spi_lld.h b/os/hal/platforms/STM32/DMAv1/spi_lld.h index 6f1e94096..c8c1e0661 100644 --- a/os/hal/platforms/STM32/DMAv1/spi_lld.h +++ b/os/hal/platforms/STM32/DMAv1/spi_lld.h @@ -174,20 +174,20 @@ typedef struct { /** * @brief Operation complete callback or @p NULL. */ - spicallback_t end_cb; + spicallback_t end_cb; /* End of the mandatory fields.*/ /** * @brief The chip select line port. */ - ioportid_t ssport; + ioportid_t ssport; /** * @brief The chip select line pad number. */ - uint16_t sspad; + uint16_t sspad; /** * @brief SPI initialization data. */ - uint16_t cr1; + uint16_t cr1; } SPIConfig; /** @@ -197,25 +197,25 @@ struct SPIDriver{ /** * @brief Driver state. */ - spistate_t state; + spistate_t state; /** * @brief Current configuration data. */ - const SPIConfig *config; + const SPIConfig *config; #if SPI_USE_WAIT || defined(__DOXYGEN__) /** * @brief Waiting thread. */ - Thread *thread; + Thread *thread; #endif /* SPI_USE_WAIT */ #if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) #if CH_USE_MUTEXES || defined(__DOXYGEN__) /** * @brief Mutex protecting the bus. */ - Mutex mutex; + Mutex mutex; #elif CH_USE_SEMAPHORES - Semaphore semaphore; + Semaphore semaphore; #endif #endif /* SPI_USE_MUTUAL_EXCLUSION */ #if defined(SPI_DRIVER_EXT_FIELDS) @@ -225,19 +225,19 @@ struct SPIDriver{ /** * @brief Pointer to the SPIx registers block. */ - SPI_TypeDef *spi; + SPI_TypeDef *spi; /** - * @brief Pointer to the receive DMA channel registers block. + * @brief Receive DMA channel. */ - stm32_dma_channel_t *dmarx; + const stm32_dma_stream_t *dmarx; /** - * @brief Pointer to the transmit DMA channel registers block. + * @brief Transmit DMA channel. */ - stm32_dma_channel_t *dmatx; + const stm32_dma_stream_t *dmatx; /** - * @brief DMA priority bit mask. + * @brief DMA mode bit mask. */ - uint32_t dmaccr; + uint32_t dmamode; }; /*===========================================================================*/ diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c index a1ade4409..1df93bb2f 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c @@ -54,6 +54,11 @@ */ #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. */ /*===========================================================================*/ @@ -66,20 +71,25 @@ * instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc. */ const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { - {0, DMA1, DMA1_Channel1, &DMA1->IFCR, 0}, - {1, DMA1, DMA1_Channel2, &DMA1->IFCR, 4}, - {2, DMA1, DMA1_Channel3, &DMA1->IFCR, 8}, - {3, DMA1, DMA1_Channel4, &DMA1->IFCR, 12}, - {4, DMA1, DMA1_Channel5, &DMA1->IFCR, 16}, - {5, DMA1, DMA1_Channel6, &DMA1->IFCR, 20}, - {6, DMA1, DMA1_Channel7, &DMA1->IFCR, 24}, + {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__) - {7, DMA2, DMA2_Channel1, &DMA2->IFCR, 0}, - {8, DMA2, DMA2_Channel2, &DMA2->IFCR, 4}, - {9, DMA2, DMA2_Channel3, &DMA2->IFCR, 8}, - {10, DMA2, DMA2_Channel4, &DMA2->IFCR, 12}, - {11, DMA2, DMA2_Channel5, &DMA2->IFCR, 16}, -#endif + {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 */ }; /*===========================================================================*/ @@ -130,6 +140,239 @@ CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) { CH_IRQ_EPILOGUE(); } +/** + * @brief DMA1 stream 2 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 4; + if (dma_isr_redir[1].dma_func) + dma_isr_redir[1].dma_func(dma_isr_redir[1].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 3 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 8) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 8; + if (dma_isr_redir[2].dma_func) + dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 4 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[3].dma_func) + dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 5 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 16) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[4].dma_func) + dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 6 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 20) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 20; + if (dma_isr_redir[5].dma_func) + dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 7 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 24) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 24; + if (dma_isr_redir[6].dma_func) + dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +#if STM32_HAS_DMA2 || defined(__DOXYGEN__) +/** + * @brief DMA2 stream 1 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 0) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[7].dma_func) + dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 2 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 4) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 4; + if (dma_isr_redir[8].dma_func) + dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 3 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch3_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 8) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 8; + if (dma_isr_redir[9].dma_func) + dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +#if defined(STM32F10X_CL) || defined(__DOXYGEN__) +/** + * @brief DMA2 stream 4 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch4_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[10].dma_func) + dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 5 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[11].dma_func) + dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} +#else /* !STM32F10X_CL */ +/** + * @brief DMA2 streams 4 and 5 shared interrupt handler. + * @note This IRQ is shared between DMA2 channels 4 and 5 so it is a + * bit less efficient because an extra check. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + /* Check on channel 4.*/ + flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA2->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[10].dma_func) + dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); + } + + /* Check on channel 5.*/ + flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA2->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[11].dma_func) + dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); + } + + CH_IRQ_EPILOGUE(); +} +#endif /* !STM32F10X_CL */ +#endif /* STM32_HAS_DMA2 */ + /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -143,7 +386,7 @@ void dmaInit(void) { int i; dma_streams_mask = 0; - for (i = 0; i < STM32_DMA_STREAMS; i--) { + for (i = 0; i < STM32_DMA_STREAMS; i++) { _stm32_dma_streams[i].channel->CCR = 0; dma_isr_redir[i].dma_func = NULL; } @@ -156,13 +399,15 @@ void dmaInit(void) { /** * @brief Allocates a DMA stream. * @details The stream is allocated and, if required, the DMA clock enabled. - * Trying to allocate a stream already allocated is an illegal - * operation and is trapped if assertions are enabled. - * @pre The stream must not be already in use. + * 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 must be freed using @p dmaRelease() before it can + * @post The stream ISR vector is enabled and its priority configured. + * @post The stream must be freed using @p dmaStreamRelease() before it can * be reused with another peripheral. + * @post The stream is in its post-reset state. * @note This function can be invoked in both ISR or thread context. * * @param[in] dmastp pointer to a stm32_dma_stream_t structure @@ -174,8 +419,10 @@ void dmaInit(void) { * * @special */ -bool_t dmaAllocate(stm32_dma_stream_t *dmastp, - stm32_dmaisr_t func, void *param) { +bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param) { chDbgCheck(dmastp != NULL, "dmaAllocate"); @@ -196,8 +443,15 @@ bool_t dmaAllocate(stm32_dma_stream_t *dmastp, RCC->AHBENR |= RCC_AHBENR_DMA2EN; #endif - /* Making sure there are no spurious interrupts flags pending.*/ + /* 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; } @@ -206,7 +460,7 @@ bool_t dmaAllocate(stm32_dma_stream_t *dmastp, * @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 dmaRequest(). + * @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. * @@ -214,7 +468,7 @@ bool_t dmaAllocate(stm32_dma_stream_t *dmastp, * * @special */ -void dmaRelease(stm32_dma_stream_t *dmastp) { +void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { chDbgCheck(dmastp != NULL, "dmaRelease"); @@ -222,6 +476,9 @@ void dmaRelease(stm32_dma_stream_t *dmastp) { chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0, "dmaRelease(), #1", "not allocated"); + /* Disables the associated IRQ vector.*/ + NVICDisableVector(dmastp->vector); + /* Marks the stream as not allocated.*/ dma_streams_mask &= ~(1 << dmastp->selfindex); diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h index 45c683c07..0247c63cf 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h @@ -93,7 +93,7 @@ #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) << 16) +#define STM32_DMA_CR_PL(n) ((n) << 12) /** @} */ /** * @name CR register constants only found in enhanced DMA @@ -128,12 +128,12 @@ * @brief STM32 DMA stream descriptor structure. */ typedef struct { - uint32_t selfindex; /**< @brief Index to self in array. */ - DMA_TypeDef *dma; /**< @brief Associated DMA unit. */ DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */ volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */ - uint32_t ishift; /**< @brief Bits offset in xIFCR + 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; /** @@ -176,7 +176,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); } /** - * @brief Associates an alternate memory destination to a DMA stream. + * @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 @@ -188,6 +188,17 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); (dmastp)->channel->CNDTR = (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)->channel->CNDTR)) + /** * @brief Programs the stream mode settings. * @note This function can be invoked in both ISR or thread context. @@ -198,7 +209,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * @special */ #define dmaStreamSetMode(dmastp, mode) { \ - (dmastp)->channel->CCR = (uint32_t)(mode2); \ + (dmastp)->channel->CCR = (uint32_t)(mode); \ } /** @@ -209,7 +220,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * * @special */ -#define dmaStreamEnable(dmachp) { \ +#define dmaStreamEnable(dmastp) { \ (dmastp)->channel->CCR |= STM32_DMA_CR_EN; \ } @@ -249,9 +260,11 @@ extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; extern "C" { #endif void dmaInit(void); - bool_t dmaAllocate(stm32_dma_stream_t *dmastp, - stm32_dmaisr_t func, void *param); - void dmaRelease(stm32_dma_stream_t *dmastp); + 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 diff --git a/os/hal/platforms/STM32/DMAv1/uart_lld.c b/os/hal/platforms/STM32/DMAv1/uart_lld.c index e2f306302..a9303744d 100644 --- a/os/hal/platforms/STM32/DMAv1/uart_lld.c +++ b/os/hal/platforms/STM32/DMAv1/uart_lld.c @@ -87,17 +87,19 @@ static uartflags_t translate_errors(uint16_t sr) { * @param[in] uartp pointer to the @p UARTDriver object */ static void set_rx_idle_loop(UARTDriver *uartp) { - uint32_t ccr; + uint32_t mode; /* RX DMA channel preparation, if the char callback is defined then the TCIE interrupt is enabled too.*/ if (uartp->config->rxchar_cb == NULL) - ccr = DMA_CCR1_CIRC | DMA_CCR1_TEIE; + mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TEIE; else - ccr = DMA_CCR1_CIRC | DMA_CCR1_TEIE | DMA_CCR1_TCIE; - dmaSetupChannel(uartp->dmap, uartp->dmarx, 1, - &uartp->rxbuf, uartp->dmaccr | ccr); - dmaEnableChannel(uartp->dmap, uartp->dmarx); + mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TEIE | + STM32_DMA_CR_TCIE; + dmaStreamSetMemory0(uartp->dmarx, &uartp->rxbuf); + dmaStreamSetTransactionSize(uartp->dmarx, 1); + dmaStreamSetMode(uartp->dmarx, uartp->dmamode | mode); + dmaStreamEnable(uartp->dmarx); } /** @@ -109,10 +111,10 @@ static void set_rx_idle_loop(UARTDriver *uartp) { static void usart_stop(UARTDriver *uartp) { /* Stops RX and TX DMA channels.*/ - dmaDisableChannel(uartp->dmap, uartp->dmarx); - dmaDisableChannel(uartp->dmap, uartp->dmatx); - dmaClearChannel(uartp->dmap, uartp->dmarx); - dmaClearChannel(uartp->dmap, uartp->dmatx); + dmaStreamDisable(uartp->dmarx); + dmaStreamClearInterrupt(uartp->dmarx); + dmaStreamDisable(uartp->dmatx); + dmaStreamClearInterrupt(uartp->dmatx); /* Stops USART operations.*/ uartp->usart->CR1 = 0; @@ -154,7 +156,7 @@ static void usart_start(UARTDriver *uartp) { u->CR1 = uartp->config->cr1 | cr1; u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE; u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR | - USART_CR3_EIE; + USART_CR3_EIE; /* Starting the receiver idle loop.*/ set_rx_idle_loop(uartp); @@ -170,7 +172,7 @@ static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_UART_DMA_ERROR_HOOK) - if ((flags & DMA_ISR_TEIF1) != 0) { + if ((flags & STM32_DMA_ISR_TEIF) != 0) { STM32_UART_DMA_ERROR_HOOK(uartp); } #else @@ -186,7 +188,7 @@ static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) { else { /* Receiver in active state, a callback is generated, if enabled, after a completed transfer.*/ - dmaDisableChannel(uartp->dmap, uartp->dmarx); + dmaStreamDisable(uartp->dmarx); uartp->rxstate = UART_RX_COMPLETE; if (uartp->config->rxend_cb != NULL) uartp->config->rxend_cb(uartp); @@ -209,14 +211,14 @@ static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_UART_DMA_ERROR_HOOK) - if ((flags & DMA_ISR_TEIF1) != 0) { + if ((flags & STM32_DMA_ISR_TEIF) != 0) { STM32_UART_DMA_ERROR_HOOK(uartp); } #else (void)flags; #endif - dmaDisableChannel(uartp->dmap, uartp->dmatx); + dmaStreamDisable(uartp->dmatx); /* A callback is generated, if enabled, after a completed transfer.*/ uartp->txstate = UART_TX_COMPLETE; if (uartp->config->txend1_cb != NULL) @@ -318,28 +320,22 @@ void uart_lld_init(void) { #if STM32_UART_USE_USART1 uartObjectInit(&UARTD1); UARTD1.usart = USART1; - UARTD1.dmap = STM32_DMA1; - UARTD1.dmarx = STM32_DMA_CHANNEL_5; - UARTD1.dmatx = STM32_DMA_CHANNEL_4; - UARTD1.dmaccr = 0; + UARTD1.dmarx = STM32_DMA1_STREAM5; + UARTD1.dmatx = STM32_DMA1_STREAM4; #endif #if STM32_UART_USE_USART2 uartObjectInit(&UARTD2); UARTD2.usart = USART2; - UARTD2.dmap = STM32_DMA1; - UARTD2.dmarx = STM32_DMA_CHANNEL_6; - UARTD2.dmatx = STM32_DMA_CHANNEL_7; - UARTD2.dmaccr = 0; + UARTD2.dmarx = STM32_DMA1_STREAM6; + UARTD2.dmatx = STM32_DMA1_STREAM7; #endif #if STM32_UART_USE_USART3 uartObjectInit(&UARTD3); UARTD3.usart = USART3; - UARTD3.dmap = STM32_DMA1; - UARTD3.dmarx = STM32_DMA_CHANNEL_3; - UARTD3.dmatx = STM32_DMA_CHANNEL_2; - UARTD3.dmaccr = 0; + UARTD3.dmarx = STM32_DMA1_STREAM3; + UARTD3.dmatx = STM32_DMA1_STREAM2; #endif } @@ -355,64 +351,68 @@ void uart_lld_start(UARTDriver *uartp) { if (uartp->state == UART_STOP) { #if STM32_UART_USE_USART1 if (&UARTD1 == uartp) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_4, - (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_5, - (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM4, + STM32_UART_USART1_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #1", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM5, + STM32_UART_USART1_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #2", "stream already allocated"); + RCC->APB2ENR |= RCC_APB2ENR_USART1EN; NVICEnableVector(USART1_IRQn, CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel4_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel5_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY)); - RCC->APB2ENR |= RCC_APB2ENR_USART1EN; } #endif #if STM32_UART_USE_USART2 if (&UARTD2 == uartp) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_6, - (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_7, - (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM6, + STM32_UART_USART2_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #3", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM7, + STM32_UART_USART2_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #4", "stream already allocated"); + RCC->APB1ENR |= RCC_APB1ENR_USART2EN; NVICEnableVector(USART2_IRQn, CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel6_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel7_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY)); - RCC->APB1ENR |= RCC_APB1ENR_USART2EN; } #endif #if STM32_UART_USE_USART3 if (&UARTD3 == uartp) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_2, - (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_3, - (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM2, + STM32_UART_USART3_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #5", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM3, + STM32_UART_USART3_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #6", "stream already allocated"); + RCC->APB1ENR |= RCC_APB1ENR_USART3EN; NVICEnableVector(USART3_IRQn, CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel2_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel3_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY)); - RCC->APB1ENR |= RCC_APB1ENR_USART3EN; } #endif /* Static DMA setup, the transfer size depends on the USART settings, it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/ - uartp->dmaccr = STM32_UART_USART1_DMA_PRIORITY << 12; + uartp->dmamode = STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY); if ((uartp->config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M) - uartp->dmaccr |= DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0; - dmaChannelSetPeripheral(&uartp->dmap->channels[uartp->dmarx], - &uartp->usart->DR); - dmaChannelSetPeripheral(&uartp->dmap->channels[uartp->dmatx], - &uartp->usart->DR); + uartp->dmamode |= STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; + dmaStreamSetPeripheral(uartp->dmarx, &uartp->usart->DR); + dmaStreamSetPeripheral(uartp->dmatx, &uartp->usart->DR); uartp->rxbuf = 0; } @@ -435,11 +435,9 @@ void uart_lld_stop(UARTDriver *uartp) { #if STM32_UART_USE_USART1 if (&UARTD1 == uartp) { + dmaStreamRelease(STM32_DMA1_STREAM4); + dmaStreamRelease(STM32_DMA1_STREAM5); NVICDisableVector(USART1_IRQn); - NVICDisableVector(DMA1_Channel4_IRQn); - NVICDisableVector(DMA1_Channel5_IRQn); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_4); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_5); RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN; return; } @@ -447,11 +445,9 @@ void uart_lld_stop(UARTDriver *uartp) { #if STM32_UART_USE_USART2 if (&UARTD2 == uartp) { + dmaStreamRelease(STM32_DMA1_STREAM6); + dmaStreamRelease(STM32_DMA1_STREAM7); NVICDisableVector(USART2_IRQn); - NVICDisableVector(DMA1_Channel6_IRQn); - NVICDisableVector(DMA1_Channel7_IRQn); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_6); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_7); RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN; return; } @@ -459,11 +455,9 @@ void uart_lld_stop(UARTDriver *uartp) { #if STM32_UART_USE_USART3 if (&UARTD3 == uartp) { + dmaStreamRelease(STM32_DMA1_STREAM2); + dmaStreamRelease(STM32_DMA1_STREAM3); NVICDisableVector(USART3_IRQn); - NVICDisableVector(DMA1_Channel2_IRQn); - NVICDisableVector(DMA1_Channel3_IRQn); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_2); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_3); RCC->APB1ENR &= ~RCC_APB1ENR_USART3EN; return; } @@ -485,10 +479,12 @@ void uart_lld_stop(UARTDriver *uartp) { void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { /* TX DMA channel preparation and start.*/ - dmaSetupChannel(uartp->dmap, uartp->dmatx, n, txbuf, - uartp->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC | - DMA_CCR1_TEIE | DMA_CCR1_TCIE); - dmaEnableChannel(uartp->dmap, uartp->dmatx); + dmaStreamSetMemory0(uartp->dmatx, txbuf); + dmaStreamSetTransactionSize(uartp->dmatx, n); + dmaStreamSetMode(uartp->dmatx, uartp->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_MINC | STM32_DMA_CR_TEIE | + STM32_DMA_CR_TCIE); + dmaStreamEnable(uartp->dmatx); } /** @@ -504,9 +500,9 @@ void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { */ size_t uart_lld_stop_send(UARTDriver *uartp) { - dmaDisableChannel(uartp->dmap, uartp->dmatx); - dmaClearChannel(uartp->dmap, uartp->dmatx); - return (size_t)uartp->dmap->channels[uartp->dmatx].CNDTR; + dmaStreamDisable(uartp->dmatx); + dmaStreamClearInterrupt(uartp->dmatx); + return dmaStreamGetTransactionSize(uartp->dmatx); } /** @@ -523,14 +519,16 @@ size_t uart_lld_stop_send(UARTDriver *uartp) { void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) { /* Stopping previous activity (idle state).*/ - dmaDisableChannel(uartp->dmap, uartp->dmarx); - dmaClearChannel(uartp->dmap, uartp->dmarx); + dmaStreamDisable(uartp->dmarx); + dmaStreamClearInterrupt(uartp->dmarx); /* RX DMA channel preparation and start.*/ - dmaSetupChannel(uartp->dmap, uartp->dmarx, n, rxbuf, - uartp->dmaccr | DMA_CCR1_MINC | - DMA_CCR1_TEIE | DMA_CCR1_TCIE); - dmaEnableChannel(uartp->dmap, uartp->dmarx); + dmaStreamSetMemory0(uartp->dmarx, rxbuf); + dmaStreamSetTransactionSize(uartp->dmarx, n); + dmaStreamSetMode(uartp->dmarx, uartp->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_MINC | STM32_DMA_CR_TEIE | + STM32_DMA_CR_TCIE); + dmaStreamEnable(uartp->dmarx); } /** @@ -547,9 +545,9 @@ void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) { size_t uart_lld_stop_receive(UARTDriver *uartp) { size_t n; - dmaDisableChannel(uartp->dmap, uartp->dmarx); - dmaClearChannel(uartp->dmap, uartp->dmarx); - n = (size_t)uartp->dmap->channels[uartp->dmarx].CNDTR; + dmaStreamDisable(uartp->dmarx); + dmaStreamClearInterrupt(uartp->dmarx); + n = dmaStreamGetTransactionSize(uartp->dmarx); set_rx_idle_loop(uartp); return n; } diff --git a/os/hal/platforms/STM32/DMAv1/uart_lld.h b/os/hal/platforms/STM32/DMAv1/uart_lld.h index 9321df85c..aff7f52ba 100644 --- a/os/hal/platforms/STM32/DMAv1/uart_lld.h +++ b/os/hal/platforms/STM32/DMAv1/uart_lld.h @@ -260,21 +260,17 @@ struct UARTDriver { */ USART_TypeDef *usart; /** - * @brief Pointer to the DMA registers block. + * @brief DMA mode bit mask. */ - stm32_dma_t *dmap; - /** - * @brief DMA priority bit mask. - */ - uint32_t dmaccr; + uint32_t dmamode; /** * @brief Receive DMA channel. */ - uint8_t dmarx; + const stm32_dma_stream_t *dmarx; /** * @brief Transmit DMA channel. */ - uint8_t dmatx; + const stm32_dma_stream_t *dmatx; /** * @brief Default receive buffer while into @p UART_RX_IDLE state. */ diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.c b/os/hal/platforms/STM32/DMAv2/stm32_dma.c index 48c0d4e95..5d320dab3 100644 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.c @@ -415,7 +415,7 @@ void dmaInit(void) { int i; dma_streams_mask = 0; - for (i = 0; i < STM32_DMA_STREAMS; i--) { + for (i = 0; i < STM32_DMA_STREAMS; i++) { _stm32_dma_streams[i].stream->CR = 0; dma_isr_redir[i].dma_func = NULL; } @@ -446,7 +446,7 @@ void dmaInit(void) { * * @special */ -bool_t dmaAllocate(stm32_dma_stream_t *dmastp, +bool_t dmaAllocate(const stm32_dma_stream_t *dmastp, stm32_dmaisr_t func, void *param) { chDbgCheck(dmastp != NULL, "dmaAllocate"); @@ -488,7 +488,7 @@ bool_t dmaAllocate(stm32_dma_stream_t *dmastp, * * @special */ -void dmaRelease(stm32_dma_stream_t *dmastp) { +void dmaRelease(const stm32_dma_stream_t *dmastp) { chDbgCheck(dmastp != NULL, "dmaRelease"); diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.h b/os/hal/platforms/STM32/DMAv2/stm32_dma.h index 5d87e67a9..88f594eec 100644 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.h @@ -217,11 +217,11 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); } /** - * @brief Associates an alternate memory destination to a DMA stream. + * @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 NDTR register + * @param[in] size value to be written in the CNDTR register * * @special */ @@ -229,6 +229,17 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); (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. @@ -303,9 +314,9 @@ extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; extern "C" { #endif void dmaInit(void); - bool_t dmaAllocate(stm32_dma_stream_t *dmastp, + bool_t dmaAllocate(const stm32_dma_stream_t *dmastp, stm32_dmaisr_t func, void *param); - void dmaRelease(stm32_dma_stream_t *dmastp); + void dmaRelease(const stm32_dma_stream_t *dmastp); #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/STM32F1xx/adc_lld.c b/os/hal/platforms/STM32F1xx/adc_lld.c index 8a8027e55..52d43daa9 100644 --- a/os/hal/platforms/STM32F1xx/adc_lld.c +++ b/os/hal/platforms/STM32F1xx/adc_lld.c @@ -58,17 +58,17 @@ static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_ADC_DMA_ERROR_HOOK) - if ((flags & DMA_ISR_TEIF1) != 0) { + if ((flags & STM32_DMA_ISR_TEIF) != 0) { STM32_ADC_DMA_ERROR_HOOK(spip); } #else (void)flags; #endif - if ((flags & DMA_ISR_HTIF1) != 0) { + if ((flags & STM32_DMA_ISR_HTIF) != 0) { /* Half transfer processing.*/ _adc_isr_half_code(adcp); } - if ((flags & DMA_ISR_TCIF1) != 0) { + if ((flags & STM32_DMA_ISR_TCIF) != 0) { /* Transfer complete processing.*/ _adc_isr_full_code(adcp); } @@ -93,10 +93,11 @@ void adc_lld_init(void) { /* Driver initialization.*/ adcObjectInit(&ADCD1); ADCD1.adc = ADC1; - ADCD1.dmachp = STM32_DMA1_CH1; - ADCD1.dmaccr = (STM32_ADC_ADC1_DMA_PRIORITY << 12) | - DMA_CCR1_EN | DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0 | - DMA_CCR1_MINC | DMA_CCR1_TCIE | DMA_CCR1_TEIE; + ADCD1.dmastp = STM32_DMA1_STREAM1; + ADCD1.dmamode = STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) | + STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | + STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | + STM32_DMA_CR_TEIE | STM32_DMA_CR_EN; /* Temporary activation.*/ RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; @@ -132,11 +133,13 @@ void adc_lld_start(ADCDriver *adcp) { if (adcp->state == ADC_STOP) { #if STM32_ADC_USE_ADC1 if (&ADCD1 == adcp) { - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_1, - (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, (void *)adcp); - NVICEnableVector(DMA1_Channel1_IRQn, - CORTEX_PRIORITY_MASK(STM32_ADC_ADC1_IRQ_PRIORITY)); - dmaChannelSetPeripheral(adcp->dmachp, &ADC1->DR); + bool_t b; + b = dmaStreamAllocate(adcp->dmastp, + STM32_ADC_ADC1_IRQ_PRIORITY, + (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, + (void *)adcp); + chDbgAssert(!b, "adc_lld_start(), #1", "stream already allocated"); + dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR); RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; } #endif @@ -163,8 +166,7 @@ void adc_lld_stop(ADCDriver *adcp) { if (&ADCD1 == adcp) { ADC1->CR1 = 0; ADC1->CR2 = 0; - NVICDisableVector(DMA1_Channel1_IRQn); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_1); + dmaStreamRelease(adcp->dmastp); RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN; } #endif @@ -179,27 +181,28 @@ void adc_lld_stop(ADCDriver *adcp) { * @notapi */ void adc_lld_start_conversion(ADCDriver *adcp) { - uint32_t ccr, n; + uint32_t mode, n; const ADCConversionGroup *grpp = adcp->grpp; /* DMA setup.*/ - ccr = adcp->dmaccr; + mode = adcp->dmamode; if (grpp->circular) - ccr |= DMA_CCR1_CIRC; + mode |= STM32_DMA_CR_CIRC; if (adcp->depth > 1) { /* If the buffer depth is greater than one then the half transfer interrupt interrupt is enabled in order to allows streaming processing.*/ - ccr |= DMA_CCR1_HTIE; + mode |= STM32_DMA_CR_HTIE; n = (uint32_t)grpp->num_channels * (uint32_t)adcp->depth; } else n = (uint32_t)grpp->num_channels; - dmaChannelSetup(adcp->dmachp, n, adcp->samples, ccr); + dmaStreamSetMemory0(adcp->dmastp, adcp->samples); + dmaStreamSetTransactionSize(adcp->dmastp, n); + dmaStreamSetMode(adcp->dmastp, mode); /* ADC setup.*/ adcp->adc->CR1 = grpp->cr1 | ADC_CR1_SCAN; - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | - ADC_CR2_CONT | ADC_CR2_ADON; + adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON; adcp->adc->SMPR1 = grpp->smpr1; adcp->adc->SMPR2 = grpp->smpr2; adcp->adc->SQR1 = grpp->sqr1; @@ -207,8 +210,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) { adcp->adc->SQR3 = grpp->sqr3; /* ADC start by writing ADC_CR2_ADON a second time.*/ - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | - ADC_CR2_CONT | ADC_CR2_ADON; + adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON; } /** @@ -220,7 +222,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) { */ void adc_lld_stop_conversion(ADCDriver *adcp) { - dmaChannelDisable(adcp->dmachp); + dmaStreamDisable(adcp->dmastp); adcp->adc->CR2 = 0; } diff --git a/os/hal/platforms/STM32F1xx/adc_lld.h b/os/hal/platforms/STM32F1xx/adc_lld.h index ce93e60ed..43b16b738 100644 --- a/os/hal/platforms/STM32F1xx/adc_lld.h +++ b/os/hal/platforms/STM32F1xx/adc_lld.h @@ -268,13 +268,13 @@ struct ADCDriver { */ ADC_TypeDef *adc; /** - * @brief Pointer to the DMA registers block. + * @brief Pointer to associated SMA channel. */ - stm32_dma_channel_t *dmachp; + const stm32_dma_stream_t *dmastp; /** - * @brief DMA CCR register bit mask. + * @brief DMA mode bit mask. */ - uint32_t dmaccr; + uint32_t dmamode; }; /*===========================================================================*/ diff --git a/readme.txt b/readme.txt index f47fead5a..e0c1066fa 100644 --- a/readme.txt +++ b/readme.txt @@ -89,6 +89,9 @@ (backported to 2.2.4). - FIX: Fixed timeout problem in the lwIP interface layer (bug 3302420) (backported to 2.2.4). +- NEW: New DMA helper driver for STM32, it simplifies the use of the DMA + resources and hides most differences with the new enhanced DMA units + found in the STM32F2xx sub-family. - NEW: Now an error is generated at compile time when trying to enable the options CH_DBG_ENABLE_STACK_CHECK on ports that do not support it. - NEW: Added a kernel-only Cortex-Mx demo as reference project for users not diff --git a/testhal/STM32F1xx/ADC/chconf.h b/testhal/STM32F1xx/ADC/chconf.h index 9dd831c96..a5d129956 100644 --- a/testhal/STM32F1xx/ADC/chconf.h +++ b/testhal/STM32F1xx/ADC/chconf.h @@ -361,7 +361,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_SYSTEM_STATE_CHECK FALSE +#define CH_DBG_SYSTEM_STATE_CHECK TRUE #endif /** @@ -372,7 +372,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_CHECKS FALSE +#define CH_DBG_ENABLE_CHECKS TRUE #endif /** @@ -384,7 +384,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_ASSERTS FALSE +#define CH_DBG_ENABLE_ASSERTS TRUE #endif /** @@ -395,7 +395,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_TRACE FALSE +#define CH_DBG_ENABLE_TRACE TRUE #endif /** @@ -409,7 +409,7 @@ * @p panic_msg variable set to @p NULL. */ #if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_STACK_CHECK FALSE +#define CH_DBG_ENABLE_STACK_CHECK TRUE #endif /** @@ -421,7 +421,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__) -#define CH_DBG_FILL_THREADS FALSE +#define CH_DBG_FILL_THREADS TRUE #endif /** diff --git a/testhal/STM32F1xx/SDIO/chconf.h b/testhal/STM32F1xx/SDIO/chconf.h index 9dd831c96..a5d129956 100644 --- a/testhal/STM32F1xx/SDIO/chconf.h +++ b/testhal/STM32F1xx/SDIO/chconf.h @@ -361,7 +361,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_SYSTEM_STATE_CHECK FALSE +#define CH_DBG_SYSTEM_STATE_CHECK TRUE #endif /** @@ -372,7 +372,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_CHECKS FALSE +#define CH_DBG_ENABLE_CHECKS TRUE #endif /** @@ -384,7 +384,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_ASSERTS FALSE +#define CH_DBG_ENABLE_ASSERTS TRUE #endif /** @@ -395,7 +395,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_TRACE FALSE +#define CH_DBG_ENABLE_TRACE TRUE #endif /** @@ -409,7 +409,7 @@ * @p panic_msg variable set to @p NULL. */ #if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_STACK_CHECK FALSE +#define CH_DBG_ENABLE_STACK_CHECK TRUE #endif /** @@ -421,7 +421,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__) -#define CH_DBG_FILL_THREADS FALSE +#define CH_DBG_FILL_THREADS TRUE #endif /** diff --git a/testhal/STM32F1xx/SPI/chconf.h b/testhal/STM32F1xx/SPI/chconf.h index 9dd831c96..a5d129956 100644 --- a/testhal/STM32F1xx/SPI/chconf.h +++ b/testhal/STM32F1xx/SPI/chconf.h @@ -361,7 +361,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_SYSTEM_STATE_CHECK FALSE +#define CH_DBG_SYSTEM_STATE_CHECK TRUE #endif /** @@ -372,7 +372,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_CHECKS FALSE +#define CH_DBG_ENABLE_CHECKS TRUE #endif /** @@ -384,7 +384,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_ASSERTS FALSE +#define CH_DBG_ENABLE_ASSERTS TRUE #endif /** @@ -395,7 +395,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_TRACE FALSE +#define CH_DBG_ENABLE_TRACE TRUE #endif /** @@ -409,7 +409,7 @@ * @p panic_msg variable set to @p NULL. */ #if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_STACK_CHECK FALSE +#define CH_DBG_ENABLE_STACK_CHECK TRUE #endif /** @@ -421,7 +421,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__) -#define CH_DBG_FILL_THREADS FALSE +#define CH_DBG_FILL_THREADS TRUE #endif /** diff --git a/testhal/STM32F1xx/SPI/mcuconf.h b/testhal/STM32F1xx/SPI/mcuconf.h index ab96d8eef..558c0773d 100644 --- a/testhal/STM32F1xx/SPI/mcuconf.h +++ b/testhal/STM32F1xx/SPI/mcuconf.h @@ -127,7 +127,7 @@ * SPI driver system settings. */ #define STM32_SPI_USE_SPI1 TRUE -#define STM32_SPI_USE_SPI2 FALSE +#define STM32_SPI_USE_SPI2 TRUE #define STM32_SPI_USE_SPI3 FALSE #define STM32_SPI_SPI1_DMA_PRIORITY 1 #define STM32_SPI_SPI2_DMA_PRIORITY 1 diff --git a/testhal/STM32F1xx/UART/chconf.h b/testhal/STM32F1xx/UART/chconf.h index 9dd831c96..a5d129956 100644 --- a/testhal/STM32F1xx/UART/chconf.h +++ b/testhal/STM32F1xx/UART/chconf.h @@ -361,7 +361,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_SYSTEM_STATE_CHECK FALSE +#define CH_DBG_SYSTEM_STATE_CHECK TRUE #endif /** @@ -372,7 +372,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_CHECKS FALSE +#define CH_DBG_ENABLE_CHECKS TRUE #endif /** @@ -384,7 +384,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_ASSERTS FALSE +#define CH_DBG_ENABLE_ASSERTS TRUE #endif /** @@ -395,7 +395,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_TRACE FALSE +#define CH_DBG_ENABLE_TRACE TRUE #endif /** @@ -409,7 +409,7 @@ * @p panic_msg variable set to @p NULL. */ #if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_STACK_CHECK FALSE +#define CH_DBG_ENABLE_STACK_CHECK TRUE #endif /** @@ -421,7 +421,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__) -#define CH_DBG_FILL_THREADS FALSE +#define CH_DBG_FILL_THREADS TRUE #endif /** diff --git a/testhal/STM32F1xx/UART/main.c b/testhal/STM32F1xx/UART/main.c index 924338a77..b3ccd35fd 100644 --- a/testhal/STM32F1xx/UART/main.c +++ b/testhal/STM32F1xx/UART/main.c @@ -26,9 +26,7 @@ static VirtualTimer vt1, vt2; static void restart(void *p) { (void)p; - chSysLockFromIsr(); uartStartSendI(&UARTD2, 14, "Hello World!\r\n"); - chSysUnlockFromIsr(); } static void ledoff(void *p) { @@ -48,7 +46,7 @@ static void txend1(UARTDriver *uartp) { } /* - * This callback is invoked when a transmission has phisically completed. + * This callback is invoked when a transmission has physically completed. */ static void txend2(UARTDriver *uartp) { diff --git a/testhal/STM32F1xx/UART/mcuconf.h b/testhal/STM32F1xx/UART/mcuconf.h index 558c0773d..c8dd60ca1 100644 --- a/testhal/STM32F1xx/UART/mcuconf.h +++ b/testhal/STM32F1xx/UART/mcuconf.h @@ -140,9 +140,9 @@ /* * UART driver system settings. */ -#define STM32_UART_USE_USART1 FALSE +#define STM32_UART_USE_USART1 TRUE #define STM32_UART_USE_USART2 TRUE -#define STM32_UART_USE_USART3 FALSE +#define STM32_UART_USE_USART3 TRUE #define STM32_UART_USART1_IRQ_PRIORITY 12 #define STM32_UART_USART2_IRQ_PRIORITY 12 #define STM32_UART_USART3_IRQ_PRIORITY 12 -- cgit v1.2.3 From c1c1706005b56e75ae1cb02c9b7a12fb3a26fc18 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Aug 2011 08:55:48 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3256 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/stm32_dma.c | 411 +++++++++++++++++-------------- os/hal/platforms/STM32/DMAv1/stm32_dma.h | 269 ++++++++++---------- 2 files changed, 354 insertions(+), 326 deletions(-) diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.c b/os/hal/platforms/STM32/DMAv1/stm32_dma.c index ae1a7170f..1df93bb2f 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.c @@ -20,28 +20,78 @@ /** * @file DMAv1/stm32_dma.c - * @brief STM32 DMA helper driver code. + * @brief DMA helper driver code. * * @addtogroup STM32_DMA - * @details DMA sharing helper driver. In the STM32 the DMA channels are a + * @details DMA sharing helper driver. In the STM32 the DMA streams are a * shared resource, this driver allows to allocate and free DMA - * channels at runtime in order to allow all the other device + * streams at runtime in order to allow all the other device * drivers to coordinate the access to the resource. * @note The DMA ISR handlers are all declared into this module because * sharing, the various device drivers can associate a callback to - * IRSs when allocating channels. + * IRSs when allocating streams. * @{ */ #include "ch.h" #include "hal.h" +/* The following macro is only defined if some driver requiring DMA services + has been enabled.*/ #if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/** + * @brief Mask of the DMA1 streams in @p dma_streams_mask. + */ +#define STM32_DMA1_STREAMS_MASK 0x0000007F + +/** + * @brief Mask of the DMA2 streams in @p dma_streams_mask. + */ +#define STM32_DMA2_STREAMS_MASK 0x00000F80 + +/** + * @brief Post-reset value of the stream CCR register. + */ +#define STM32_DMA_CCR_RESET_VALUE 0x00000000 + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ +/** + * @brief DMA streams descriptors. + * @details This table keeps the association between an unique stream + * identifier and the involved physical registers. + * @note Don't use this array directly, use the appropriate wrapper macros + * instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc. + */ +const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { + {DMA1_Channel1, &DMA1->IFCR, 0, 0, DMA1_Channel1_IRQn}, + {DMA1_Channel2, &DMA1->IFCR, 4, 1, DMA1_Channel2_IRQn}, + {DMA1_Channel3, &DMA1->IFCR, 8, 2, DMA1_Channel3_IRQn}, + {DMA1_Channel4, &DMA1->IFCR, 12, 3, DMA1_Channel4_IRQn}, + {DMA1_Channel5, &DMA1->IFCR, 16, 4, DMA1_Channel5_IRQn}, + {DMA1_Channel6, &DMA1->IFCR, 20, 5, DMA1_Channel6_IRQn}, + {DMA1_Channel7, &DMA1->IFCR, 24, 6, DMA1_Channel7_IRQn}, +#if STM32_HAS_DMA2 || defined(__DOXYGEN__) + {DMA2_Channel1, &DMA2->IFCR, 0, 7, DMA2_Channel1_IRQn}, + {DMA2_Channel2, &DMA2->IFCR, 4, 8, DMA2_Channel2_IRQn}, + {DMA2_Channel3, &DMA2->IFCR, 8, 9, DMA2_Channel3_IRQn}, +#if defined(STM32F10X_CL) || defined(__DOXYGEN__) + {DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_IRQn}, + {DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel5_IRQn}, +#else /* !STM32F10X_CL */ + {DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_5_IRQn}, + {DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel4_5_IRQn}, +#endif /* !STM32F10X_CL */ +#endif /* STM32_HAS_DMA2 */ +}; + /*===========================================================================*/ /* Driver local variables and types. */ /*===========================================================================*/ @@ -50,17 +100,19 @@ * @brief DMA ISR redirector type. */ typedef struct { - stm32_dmaisr_t dmaisrfunc; - void *dmaisrparam; + stm32_dmaisr_t dma_func; + void *dma_param; } dma_isr_redir_t; -static uint32_t dmamsk1; -static dma_isr_redir_t dma1[7]; +/** + * @brief Mask of the allocated streams. + */ +static uint32_t dma_streams_mask; -#if STM32_HAS_DMA2 -static uint32_t dmamsk2; -static dma_isr_redir_t dma2[5]; -#endif +/** + * @brief DMA IRQ redirectors. + */ +static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS]; /*===========================================================================*/ /* Driver local functions. */ @@ -71,250 +123,249 @@ static dma_isr_redir_t dma2[5]; /*===========================================================================*/ /** - * @brief DMA1 channel 1 shared interrupt handler. + * @brief DMA1 stream 1 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_1 * 4); - dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_1); - if (dma1[0].dmaisrfunc) - dma1[0].dmaisrfunc(dma1[0].dmaisrparam, isr); + flags = (DMA1->ISR >> 0) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[0].dma_func) + dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags); CH_IRQ_EPILOGUE(); } /** - * @brief DMA1 channel 2 shared interrupt handler. + * @brief DMA1 stream 2 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_2 * 4); - dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_2); - if (dma1[1].dmaisrfunc) - dma1[1].dmaisrfunc(dma1[1].dmaisrparam, isr); + flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 4; + if (dma_isr_redir[1].dma_func) + dma_isr_redir[1].dma_func(dma_isr_redir[1].dma_param, flags); CH_IRQ_EPILOGUE(); } /** - * @brief DMA1 channel 3 shared interrupt handler. + * @brief DMA1 stream 3 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_3 * 4); - dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3); - if (dma1[2].dmaisrfunc) - dma1[2].dmaisrfunc(dma1[2].dmaisrparam, isr); + flags = (DMA1->ISR >> 8) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 8; + if (dma_isr_redir[2].dma_func) + dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags); CH_IRQ_EPILOGUE(); } /** - * @brief DMA1 channel 4 shared interrupt handler. + * @brief DMA1 stream 4 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_4 * 4); - dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_4); - if (dma1[3].dmaisrfunc) - dma1[3].dmaisrfunc(dma1[3].dmaisrparam, isr); + flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[3].dma_func) + dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags); CH_IRQ_EPILOGUE(); } /** - * @brief DMA1 channel 5 shared interrupt handler. + * @brief DMA1 stream 5 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_5 * 4); - dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5); - if (dma1[4].dmaisrfunc) - dma1[4].dmaisrfunc(dma1[4].dmaisrparam, isr); + flags = (DMA1->ISR >> 16) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[4].dma_func) + dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags); CH_IRQ_EPILOGUE(); } /** - * @brief DMA1 channel 6 shared interrupt handler. + * @brief DMA1 stream 6 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_6 * 4); - dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6); - if (dma1[5].dmaisrfunc) - dma1[5].dmaisrfunc(dma1[5].dmaisrparam, isr); + flags = (DMA1->ISR >> 20) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 20; + if (dma_isr_redir[5].dma_func) + dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags); CH_IRQ_EPILOGUE(); } /** - * @brief DMA1 channel 7 shared interrupt handler. + * @brief DMA1 stream 7 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_7 * 4); - dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_7); - if (dma1[6].dmaisrfunc) - dma1[6].dmaisrfunc(dma1[6].dmaisrparam, isr); + flags = (DMA1->ISR >> 24) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 24; + if (dma_isr_redir[6].dma_func) + dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags); CH_IRQ_EPILOGUE(); } #if STM32_HAS_DMA2 || defined(__DOXYGEN__) /** - * @brief DMA2 channel 1 shared interrupt handler. + * @brief DMA2 stream 1 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_1 * 4); - dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_1); - if (dma2[0].dmaisrfunc) - dma2[0].dmaisrfunc(dma2[0].dmaisrparam, isr); + flags = (DMA2->ISR >> 0) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[7].dma_func) + dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags); CH_IRQ_EPILOGUE(); } /** - * @brief DMA2 channel 2 shared interrupt handler. + * @brief DMA2 stream 2 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_2 * 4); - dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_2); - if (dma2[1].dmaisrfunc) - dma2[1].dmaisrfunc(dma2[1].dmaisrparam, isr); + flags = (DMA2->ISR >> 4) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 4; + if (dma_isr_redir[8].dma_func) + dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags); CH_IRQ_EPILOGUE(); } /** - * @brief DMA2 channel 3 shared interrupt handler. + * @brief DMA2 stream 3 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA2_Ch3_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_3 * 4); - dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_3); - if (dma2[2].dmaisrfunc) - dma2[2].dmaisrfunc(dma2[2].dmaisrparam, isr); + flags = (DMA2->ISR >> 8) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 8; + if (dma_isr_redir[9].dma_func) + dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags); CH_IRQ_EPILOGUE(); } #if defined(STM32F10X_CL) || defined(__DOXYGEN__) /** - * @brief DMA2 channel 4 shared interrupt handler. + * @brief DMA2 stream 4 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA2_Ch4_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_4 * 4); - dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); - if (dma2[3].dmaisrfunc) - dma2[3].dmaisrfunc(dma2[3].dmaisrparam, isr); + flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[10].dma_func) + dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); CH_IRQ_EPILOGUE(); } /** - * @brief DMA2 channel 5 shared interrupt handler. + * @brief DMA2 stream 5 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA2_Ch5_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_5 * 4); - dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5); - if (dma2[4].dmaisrfunc) - dma2[4].dmaisrfunc(dma2[4].dmaisrparam, isr); + flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[11].dma_func) + dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); CH_IRQ_EPILOGUE(); } - #else /* !STM32F10X_CL */ /** - * @brief DMA2 channels 4 and 5 shared interrupt handler. + * @brief DMA2 streams 4 and 5 shared interrupt handler. * @note This IRQ is shared between DMA2 channels 4 and 5 so it is a * bit less efficient because an extra check. * * @isr */ CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); /* Check on channel 4.*/ - isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_5 * 4); - if (isr & DMA_ISR_GIF1) { - dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5); - if (dma2[3].dmaisrfunc) - dma2[3].dmaisrfunc(dma2[3].dmaisrparam, isr); + flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA2->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[10].dma_func) + dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); } /* Check on channel 5.*/ - isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_4 * 4); - if (isr & DMA_ISR_GIF1) { - dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5); - if (dma2[4].dmaisrfunc) - dma2[4].dmaisrfunc(dma2[4].dmaisrparam, isr); + flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA2->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[11].dma_func) + dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); } CH_IRQ_EPILOGUE(); @@ -334,127 +385,109 @@ CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) { void dmaInit(void) { int i; - dmamsk1 = 0; - for (i = STM32_DMA_CHANNEL_7; i >= STM32_DMA_CHANNEL_1; i--) { - dmaDisableChannel(STM32_DMA1, i); - dma1[i].dmaisrfunc = NULL; + dma_streams_mask = 0; + for (i = 0; i < STM32_DMA_STREAMS; i++) { + _stm32_dma_streams[i].channel->CCR = 0; + dma_isr_redir[i].dma_func = NULL; } - STM32_DMA1->IFCR = 0xFFFFFFFF; + DMA1->IFCR = 0xFFFFFFFF; #if STM32_HAS_DMA2 - dmamsk2 = 0; - for (i = STM32_DMA_CHANNEL_5; i >= STM32_DMA_CHANNEL_1; i--) { - dmaDisableChannel(STM32_DMA2, i); - dma2[i].dmaisrfunc = NULL; - } - STM32_DMA1->IFCR = 0xFFFFFFFF; + DMA2->IFCR = 0xFFFFFFFF; #endif } /** - * @brief Allocates a DMA channel. - * @details The channel is allocated and, if required, the DMA clock enabled. - * Trying to allocate a channel already allocated is an illegal - * operation and is trapped if assertions are enabled. - * @pre The channel must not be already in use. - * @post The channel is allocated and the default ISR handler redirected + * @brief Allocates a DMA stream. + * @details The stream is allocated and, if required, the DMA clock enabled. + * The function also enables the IRQ vector associated to the stream + * and initializes its priority. + * @pre The stream must not be already in use or an error is returned. + * @post The stream is allocated and the default ISR handler redirected * to the specified function. - * @post The channel must be freed using @p dmaRelease() before it can + * @post The stream ISR vector is enabled and its priority configured. + * @post The stream must be freed using @p dmaStreamRelease() before it can * be reused with another peripheral. + * @post The stream is in its post-reset state. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dma DMA controller id - * @param[in] channel requested channel id + * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @param[in] func handling function pointer, can be @p NULL * @param[in] param a parameter to be passed to the handling function + * @return The operation status. + * @retval FALSE no error, stream taken. + * @retval TRUE error, stream already taken. * * @special */ -void dmaAllocate(uint32_t dma, uint32_t channel, - stm32_dmaisr_t func, void *param) { +bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param) { + chDbgCheck(dmastp != NULL, "dmaAllocate"); + + /* Checks if the stream is already taken.*/ + if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0) + return TRUE; + + /* Marks the stream as allocated.*/ + dma_isr_redir[dmastp->selfindex].dma_func = func; + dma_isr_redir[dmastp->selfindex].dma_param = param; + dma_streams_mask |= (1 << dmastp->selfindex); + + /* Enabling DMA clocks required by the current streams set.*/ + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) + RCC->AHBENR |= RCC_AHBENR_DMA1EN; #if STM32_HAS_DMA2 - switch (dma) { - case STM32_DMA1_ID: -#else - (void)dma; -#endif - /* Check if the channel is already taken.*/ - chDbgAssert((dmamsk1 & (1 << channel)) == 0, - "dmaAllocate(), #1", "already allocated"); - - /* If the DMA unit was idle then the clock is enabled.*/ - if (dmamsk1 == 0) { - RCC->AHBENR |= RCC_AHBENR_DMA1EN; - DMA1->IFCR = 0x0FFFFFFF; - } - - dmamsk1 |= 1 << channel; - dma1[channel].dmaisrfunc = func; - dma1[channel].dmaisrparam = param; -#if STM32_HAS_DMA2 - break; - case STM32_DMA2_ID: - /* Check if the channel is already taken.*/ - chDbgAssert((dmamsk2 & (1 << channel)) == 0, - "dmaAllocate(), #2", "already allocated"); - - /* If the DMA unit was idle then the clock is enabled.*/ - if (dmamsk2 == 0) { - RCC->AHBENR |= RCC_AHBENR_DMA2EN; - DMA2->IFCR = 0x0FFFFFFF; - } - - dmamsk2 |= 1 << channel; - dma2[channel].dmaisrfunc = func; - dma2[channel].dmaisrparam = param; - break; - } + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) + RCC->AHBENR |= RCC_AHBENR_DMA2EN; #endif + + /* Putting the stream in a safe state.*/ + dmaStreamDisable(dmastp); + dmaStreamClearInterrupt(dmastp); + dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; + + /* Enables the associated IRQ vector if a callback is defined.*/ + if (func != NULL) + NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority)); + + return FALSE; } /** - * @brief Releases a DMA channel. - * @details The channel is freed and, if required, the DMA clock disabled. - * Trying to release a unallocated channel is an illegal operation + * @brief Releases a DMA stream. + * @details The stream is freed and, if required, the DMA clock disabled. + * Trying to release a unallocated stream is an illegal operation * and is trapped if assertions are enabled. - * @pre The channel must have been allocated using @p dmaRequest(). - * @post The channel is again available. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post The stream is again available. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dma DMA controller id - * @param[in] channel requested channel id + * @param[in] dmastp pointer to a stm32_dma_stream_t structure * * @special */ -void dmaRelease(uint32_t dma, uint32_t channel) { +void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { + chDbgCheck(dmastp != NULL, "dmaRelease"); + + /* Check if the streams is not taken.*/ + chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0, + "dmaRelease(), #1", "not allocated"); + + /* Disables the associated IRQ vector.*/ + NVICDisableVector(dmastp->vector); + + /* Marks the stream as not allocated.*/ + dma_streams_mask &= ~(1 << dmastp->selfindex); + + /* Shutting down clocks that are no more required, if any.*/ + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) + RCC->AHBENR &= ~RCC_AHBENR_DMA1EN; #if STM32_HAS_DMA2 - switch (dma) { - case STM32_DMA1_ID: -#else - (void)dma; -#endif - /* Check if the channel is not taken.*/ - chDbgAssert((dmamsk1 & (1 << channel)) != 0, - "dmaRelease(), #1", "not allocated"); - - dma1[channel].dmaisrfunc = NULL; - dmamsk1 &= ~(1 << channel); - if (dmamsk1 == 0) - RCC->AHBENR &= ~RCC_AHBENR_DMA1EN; -#if STM32_HAS_DMA2 - break; - case STM32_DMA2_ID: - /* Check if the channel is not taken.*/ - chDbgAssert((dmamsk2 & (1 << channel)) != 0, - "dmaRelease(), #2", "not allocated"); - - dma2[channel].dmaisrfunc = NULL; - dmamsk2 &= ~(1 << channel); - if (dmamsk2 == 0) - RCC->AHBENR &= ~RCC_AHBENR_DMA2EN; - break; - } + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) + RCC->AHBENR &= ~RCC_AHBENR_DMA2EN; #endif } diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.h b/os/hal/platforms/STM32/DMAv1/stm32_dma.h index 5ee06e939..0247c63cf 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.h @@ -20,9 +20,11 @@ /** * @file DMAv1/stm32_dma.h - * @brief STM32 DMA helper driver header. - * @note This file requires definitions from the ST STM32 header file - * stm32f10x.h. + * @brief DMA helper driver header. + * @note This file requires definitions from the ST header files + * stm32f10x.h or stm32l1xx.h. + * @note This driver uses the new naming convention used for the STM32F2xx + * so the "DMA channels" are referred as "DMA streams". * * @addtogroup STM32_DMA * @{ @@ -35,14 +37,81 @@ /* Driver constants. */ /*===========================================================================*/ -/** @brief DMA1 identifier.*/ -#define STM32_DMA1_ID 0 - -/** @brief DMA2 identifier.*/ +/** + * @brief Total number of DMA streams. + * @note This is the total number of streams among all the DMA units. + */ #if STM32_HAS_DMA2 || defined(__DOXYGEN__) -#define STM32_DMA2_ID 1 +#define STM32_DMA_STREAMS 12 +#else +#define STM32_DMA_STREAMS 7 #endif +/** + * @brief Mask of the ISR bits passed to the DMA callback functions. + */ +#define STM32_DMA_ISR_MASK 0x0F + +/** + * @name DMA streams identifiers + * @{ + */ +#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[0]) +#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[1]) +#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[2]) +#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[3]) +#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[4]) +#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[5]) +#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[6]) +#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[8]) +#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[9]) +#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[10]) +#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[11]) +#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[12]) +/** @} */ + +/** + * @name CR register constants common to all DMA types + */ +#define STM32_DMA_CR_EN DMA_CCR1_EN +#define STM32_DMA_CR_TEIE DMA_CCR1_TEIE +#define STM32_DMA_CR_HTIE DMA_CCR1_HTIE +#define STM32_DMA_CR_TCIE DMA_CCR1_TCIE +#define STM32_DMA_CR_DIR_MASK (DMA_CCR1_DIR | DMA_CCR1_MEM2MEM) +#define STM32_DMA_CR_DIR_P2M 0 +#define STM32_DMA_CR_DIR_M2P DMA_CCR1_DIR +#define STM32_DMA_CR_DIR_M2M DMA_CCR1_MEM2MEM +#define STM32_DMA_CR_CIRC DMA_CCR1_CIRC +#define STM32_DMA_CR_PINC DMA_CCR1_PINC +#define STM32_DMA_CR_MINC DMA_CCR1_MINC +#define STM32_DMA_CR_PSIZE_MASK DMA_CCR1_PSIZE +#define STM32_DMA_CR_PSIZE_BYTE 0 +#define STM32_DMA_CR_PSIZE_HWORD DMA_CCR1_PSIZE_0 +#define STM32_DMA_CR_PSIZE_WORD DMA_CCR1_PSIZE_1 +#define STM32_DMA_CR_MSIZE_MASK DMA_CCR1_MSIZE +#define STM32_DMA_CR_MSIZE_BYTE 0 +#define STM32_DMA_CR_MSIZE_HWORD DMA_CCR1_MSIZE_0 +#define STM32_DMA_CR_MSIZE_WORD DMA_CCR1_MSIZE_1 +#define STM32_DMA_CR_PL_MASK DMA_CCR1_PL +#define STM32_DMA_CR_PL(n) ((n) << 12) +/** @} */ +/** + * @name CR register constants only found in enhanced DMA + */ +#define STM32_DMA_CR_CHSEL_MASK 0 /**< @brief Ignored by normal DMA. */ +#define STM32_DMA_CR_CHSEL(n) 0 /**< @brief Ignored by normal DMA. */ +/** @} */ + +/** + * @name Status flags passed to the ISR callbacks + */ +#define STM32_DMA_ISR_FEIF 0 +#define STM32_DMA_ISR_DMEIF 0 +#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1 +#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1 +#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1 +/** @} */ + /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ @@ -56,33 +125,23 @@ /*===========================================================================*/ /** - * @brief STM32 DMA channel memory structure type. - */ -typedef struct { - volatile uint32_t CCR; - volatile uint32_t CNDTR; - volatile uint32_t CPAR; - volatile uint32_t CMAR; - volatile uint32_t dummy; -} stm32_dma_channel_t; - -/** - * @brief STM32 DMA subsystem memory structure type. - * @note This structure has been redefined here because it is convenient to - * have the channels organized as an array, the ST header does not - * do that. + * @brief STM32 DMA stream descriptor structure. */ typedef struct { - volatile uint32_t ISR; - volatile uint32_t IFCR; - stm32_dma_channel_t channels[7]; -} stm32_dma_t; + DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */ + volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */ + uint8_t ishift; /**< @brief Bits offset in xIFCR + register. */ + uint8_t selfindex; /**< @brief Index to self in array. */ + uint8_t vector; /**< @brief Associated IRQ vector. */ +} stm32_dma_stream_t; /** * @brief STM32 DMA ISR function type. * * @param[in] p parameter for the registered function - * @param[in] flags pre-shifted content of the ISR register + * @param[in] flags pre-shifted content of the ISR register, the bits + * are aligned to bit zero */ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); @@ -90,186 +149,122 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /* Driver macros. */ /*===========================================================================*/ -/** DMA1 registers block numeric address.*/ -#define STM32_DMA1_BASE (AHBPERIPH_BASE + 0x0000) -/** Pointer to the DMA1 registers block.*/ -#define STM32_DMA1 ((stm32_dma_t *)STM32_DMA1_BASE) -/** Pointer to the DMA1 channel 1 registers block.*/ -#define STM32_DMA1_CH1 (&STM32_DMA1->channels[0]) -/** Pointer to the DMA1 channel 2 registers block.*/ -#define STM32_DMA1_CH2 (&STM32_DMA1->channels[1]) -/** Pointer to the DMA1 channel 3 registers block.*/ -#define STM32_DMA1_CH3 (&STM32_DMA1->channels[2]) -/** Pointer to the DMA1 channel 4 registers block.*/ -#define STM32_DMA1_CH4 (&STM32_DMA1->channels[3]) -/** Pointer to the DMA1 channel 5 registers block.*/ -#define STM32_DMA1_CH5 (&STM32_DMA1->channels[4]) -/** Pointer to the DMA1 channel 6 registers block.*/ -#define STM32_DMA1_CH6 (&STM32_DMA1->channels[5]) -/** Pointer to the DMA1 channel 7 registers block.*/ -#define STM32_DMA1_CH7 (&STM32_DMA1->channels[6]) - -#if STM32_HAS_DMA2 || defined(__DOXYGEN__) -/** DMA2 registers block numeric address.*/ -#define STM32_DMA2_BASE (AHBPERIPH_BASE + 0x0400) -/** Pointer to the DMA2 registers block.*/ -#define STM32_DMA2 ((stm32_dma_t *)STM32_DMA2_BASE) -/** Pointer to the DMA2 channel 1 registers block.*/ -#define STM32_DMA2_CH1 (&STM32_DMA2->channels[0]) -/** Pointer to the DMA2 channel 2 registers block.*/ -#define STM32_DMA2_CH2 (&STM32_DMA2->channels[1]) -/** Pointer to the DMA2 channel 3 registers block.*/ -#define STM32_DMA2_CH3 (&STM32_DMA2->channels[2]) -/** Pointer to the DMA2 channel 4 registers block.*/ -#define STM32_DMA2_CH4 (&STM32_DMA2->channels[3]) -/** Pointer to the DMA2 channel 5 registers block.*/ -#define STM32_DMA2_CH5 (&STM32_DMA2->channels[4]) -#endif - -#define STM32_DMA_CHANNEL_1 0 /**< @brief DMA channel 1. */ -#define STM32_DMA_CHANNEL_2 1 /**< @brief DMA channel 2. */ -#define STM32_DMA_CHANNEL_3 2 /**< @brief DMA channel 3. */ -#define STM32_DMA_CHANNEL_4 3 /**< @brief DMA channel 4. */ -#define STM32_DMA_CHANNEL_5 4 /**< @brief DMA channel 5. */ -#define STM32_DMA_CHANNEL_6 5 /**< @brief DMA channel 6. */ -#define STM32_DMA_CHANNEL_7 6 /**< @brief DMA channel 7. */ - /** - * @brief Associates a peripheral data register to a DMA channel. + * @brief Associates a peripheral data register to a DMA stream. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmachp dmachp to a stm32_dma_channel_t structure - * @param[in] cpar value to be written in the CPAR register + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the CPAR register * * @special */ -#define dmaChannelSetPeripheral(dmachp, cpar) { \ - (dmachp)->CPAR = (uint32_t)(cpar); \ +#define dmaStreamSetPeripheral(dmastp, addr) { \ + (dmastp)->channel->CPAR = (uint32_t)(addr); \ } /** - * @brief DMA channel setup by channel pointer. - * @note This macro does not change the CPAR register because that register - * value does not change frequently, it usually points to a peripheral - * data register. + * @brief Associates a memory destination to a DMA stream. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmachp pointer to a stm32_dma_channel_t structure - * @param[in] cndtr value to be written in the CNDTR register - * @param[in] cmar value to be written in the CMAR register - * @param[in] ccr value to be written in the CCR register + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the CMAR register * * @special */ -#define dmaChannelSetup(dmachp, cndtr, cmar, ccr) { \ - (dmachp)->CNDTR = (uint32_t)(cndtr); \ - (dmachp)->CMAR = (uint32_t)(cmar); \ - (dmachp)->CCR = (uint32_t)(ccr); \ +#define dmaStreamSetMemory0(dmastp, addr) { \ + (dmastp)->channel->CMAR = (uint32_t)(addr); \ } /** - * @brief DMA channel enable by channel pointer. + * @brief Sets the number of transfers to be performed. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmachp pointer to a stm32_dma_channel_t structure + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] size value to be written in the CNDTR register * * @special */ -#define dmaChannelEnable(dmachp) { \ - (dmachp)->CCR |= DMA_CCR1_EN; \ +#define dmaStreamSetTransactionSize(dmastp, size) { \ + (dmastp)->channel->CNDTR = (uint32_t)(size); \ } /** - * @brief DMA channel disable by channel pointer. + * @brief Returns the number of transfers to be performed. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmachp pointer to a stm32_dma_channel_t structure + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @return The number of transfers to be performed. * * @special */ -#define dmaChannelDisable(dmachp) { \ - (dmachp)->CCR = 0; \ -} +#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->channel->CNDTR)) /** - * @brief DMA channel setup by channel ID. - * @note This macro does not change the CPAR register because that register - * value does not change frequently, it usually points to a peripheral - * data register. - * @note Channels are numbered from 0 to 6, use the appropriate macro - * as parameter. + * @brief Programs the stream mode settings. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmap pointer to a stm32_dma_t structure - * @param[in] ch channel number - * @param[in] cndtr value to be written in the CNDTR register - * @param[in] cmar value to be written in the CMAR register - * @param[in] ccr value to be written in the CCR register + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] mode value to be written in the CCR register * * @special */ -#define dmaSetupChannel(dmap, ch, cndtr, cmar, ccr) { \ - dmaChannelSetup(&(dmap)->channels[ch], (cndtr), (cmar), (ccr)); \ +#define dmaStreamSetMode(dmastp, mode) { \ + (dmastp)->channel->CCR = (uint32_t)(mode); \ } /** - * @brief DMA channel enable by channel ID. - * @note Channels are numbered from 0 to 6, use the appropriate macro - * as parameter. + * @brief DMA stream enable. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmap pointer to a stm32_dma_t structure - * @param[in] ch channel number + * @param[in] dmachp pointer to a stm32_dma_stream_t structure * * @special */ -#define dmaEnableChannel(dmap, ch) { \ - dmaChannelEnable(&(dmap)->channels[ch]); \ +#define dmaStreamEnable(dmastp) { \ + (dmastp)->channel->CCR |= STM32_DMA_CR_EN; \ } /** - * @brief DMA channel disable by channel ID. - * @note Channels are numbered from 0 to 6, use the appropriate macro - * as parameter. + * @brief DMA stream disable. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmap pointer to a stm32_dma_t structure - * @param[in] ch channel number + * @param[in] dmastp pointer to a stm32_dma_stream_t structure * * @special */ -#define dmaDisableChannel(dmap, ch) { \ - dmaChannelDisable(&(dmap)->channels[ch]); \ +#define dmaStreamDisable(dmastp) { \ + (dmastp)->channel->CCR &= ~STM32_DMA_CR_EN; \ } /** - * @brief DMA channel interrupt sources clear. - * @details Sets the appropriate CGIF bit into the IFCR register in order to - * withdraw all the pending interrupt bits from the ISR register. - * @note Channels are numbered from 0 to 6, use the appropriate macro - * as parameter. + * @brief DMA stream interrupt sources clear. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmap pointer to a stm32_dma_t structure - * @param[in] ch channel number + * @param[in] dmastp pointer to a stm32_dma_stream_t structure * * @special */ -#define dmaClearChannel(dmap, ch) { \ - (dmap)->IFCR = 1 << ((ch) * 4); \ +#define dmaStreamClearInterrupt(dmastp) { \ + *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \ } /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ +#if !defined(__DOXYGEN__) +extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; +#endif + #ifdef __cplusplus extern "C" { #endif void dmaInit(void); - void dmaAllocate(uint32_t dma, uint32_t channel, - stm32_dmaisr_t func, void *param); - void dmaRelease(uint32_t dma, uint32_t channel); + bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param); + void dmaStreamRelease(const stm32_dma_stream_t *dmastp); #ifdef __cplusplus } #endif -- cgit v1.2.3 From fe65de0c91a2d74566dbeb1bf66961e917aee031 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Aug 2011 08:56:49 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3257 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c | 496 --------------------------- os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h | 274 --------------- 2 files changed, 770 deletions(-) delete mode 100644 os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c delete mode 100644 os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c deleted file mode 100644 index 1df93bb2f..000000000 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c +++ /dev/null @@ -1,496 +0,0 @@ -/* - 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 . -*/ - -/** - * @file DMAv1/stm32_dma.c - * @brief 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 0x0000007F - -/** - * @brief Mask of the DMA2 streams in @p dma_streams_mask. - */ -#define STM32_DMA2_STREAMS_MASK 0x00000F80 - -/** - * @brief Post-reset value of the stream CCR register. - */ -#define STM32_DMA_CCR_RESET_VALUE 0x00000000 - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief DMA streams descriptors. - * @details This table keeps the association between an unique stream - * identifier and the involved physical registers. - * @note Don't use this array directly, use the appropriate wrapper macros - * instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc. - */ -const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { - {DMA1_Channel1, &DMA1->IFCR, 0, 0, DMA1_Channel1_IRQn}, - {DMA1_Channel2, &DMA1->IFCR, 4, 1, DMA1_Channel2_IRQn}, - {DMA1_Channel3, &DMA1->IFCR, 8, 2, DMA1_Channel3_IRQn}, - {DMA1_Channel4, &DMA1->IFCR, 12, 3, DMA1_Channel4_IRQn}, - {DMA1_Channel5, &DMA1->IFCR, 16, 4, DMA1_Channel5_IRQn}, - {DMA1_Channel6, &DMA1->IFCR, 20, 5, DMA1_Channel6_IRQn}, - {DMA1_Channel7, &DMA1->IFCR, 24, 6, DMA1_Channel7_IRQn}, -#if STM32_HAS_DMA2 || defined(__DOXYGEN__) - {DMA2_Channel1, &DMA2->IFCR, 0, 7, DMA2_Channel1_IRQn}, - {DMA2_Channel2, &DMA2->IFCR, 4, 8, DMA2_Channel2_IRQn}, - {DMA2_Channel3, &DMA2->IFCR, 8, 9, DMA2_Channel3_IRQn}, -#if defined(STM32F10X_CL) || defined(__DOXYGEN__) - {DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_IRQn}, - {DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel5_IRQn}, -#else /* !STM32F10X_CL */ - {DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_5_IRQn}, - {DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel4_5_IRQn}, -#endif /* !STM32F10X_CL */ -#endif /* STM32_HAS_DMA2 */ -}; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/** - * @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 1 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 0) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 0; - if (dma_isr_redir[0].dma_func) - dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 2 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 4; - if (dma_isr_redir[1].dma_func) - dma_isr_redir[1].dma_func(dma_isr_redir[1].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 3 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 8) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 8; - if (dma_isr_redir[2].dma_func) - dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 4 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 12; - if (dma_isr_redir[3].dma_func) - dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 5 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 16) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 16; - if (dma_isr_redir[4].dma_func) - dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 6 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 20) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 20; - if (dma_isr_redir[5].dma_func) - dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 7 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 24) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 24; - if (dma_isr_redir[6].dma_func) - dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -#if STM32_HAS_DMA2 || defined(__DOXYGEN__) -/** - * @brief DMA2 stream 1 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->ISR >> 0) & STM32_DMA_ISR_MASK; - DMA2->IFCR = STM32_DMA_ISR_MASK << 0; - if (dma_isr_redir[7].dma_func) - dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA2 stream 2 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->ISR >> 4) & STM32_DMA_ISR_MASK; - DMA2->IFCR = STM32_DMA_ISR_MASK << 4; - if (dma_isr_redir[8].dma_func) - dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA2 stream 3 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Ch3_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->ISR >> 8) & STM32_DMA_ISR_MASK; - DMA2->IFCR = STM32_DMA_ISR_MASK << 8; - if (dma_isr_redir[9].dma_func) - dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -#if defined(STM32F10X_CL) || defined(__DOXYGEN__) -/** - * @brief DMA2 stream 4 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Ch4_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK; - DMA2->IFCR = STM32_DMA_ISR_MASK << 12; - if (dma_isr_redir[10].dma_func) - dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA2 stream 5 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Ch5_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK; - DMA2->IFCR = STM32_DMA_ISR_MASK << 16; - if (dma_isr_redir[11].dma_func) - dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} -#else /* !STM32F10X_CL */ -/** - * @brief DMA2 streams 4 and 5 shared interrupt handler. - * @note This IRQ is shared between DMA2 channels 4 and 5 so it is a - * bit less efficient because an extra check. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - /* Check on channel 4.*/ - flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK; - if (flags & STM32_DMA_ISR_MASK) { - DMA2->IFCR = STM32_DMA_ISR_MASK << 12; - if (dma_isr_redir[10].dma_func) - dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); - } - - /* Check on channel 5.*/ - flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK; - if (flags & STM32_DMA_ISR_MASK) { - DMA2->IFCR = STM32_DMA_ISR_MASK << 16; - if (dma_isr_redir[11].dma_func) - dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); - } - - CH_IRQ_EPILOGUE(); -} -#endif /* !STM32F10X_CL */ -#endif /* STM32_HAS_DMA2 */ - -/*===========================================================================*/ -/* 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].channel->CCR = 0; - dma_isr_redir[i].dma_func = NULL; - } - DMA1->IFCR = 0xFFFFFFFF; -#if STM32_HAS_DMA2 - DMA2->IFCR = 0xFFFFFFFF; -#endif -} - -/** - * @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 & (1 << dmastp->selfindex)) != 0) - return TRUE; - - /* Marks the stream as allocated.*/ - dma_isr_redir[dmastp->selfindex].dma_func = func; - dma_isr_redir[dmastp->selfindex].dma_param = param; - dma_streams_mask |= (1 << dmastp->selfindex); - - /* Enabling DMA clocks required by the current streams set.*/ - if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) - RCC->AHBENR |= RCC_AHBENR_DMA1EN; -#if STM32_HAS_DMA2 - if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) - RCC->AHBENR |= RCC_AHBENR_DMA2EN; -#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 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 & (1 << dmastp->selfindex)) != 0, - "dmaRelease(), #1", "not allocated"); - - /* Disables the associated IRQ vector.*/ - NVICDisableVector(dmastp->vector); - - /* Marks the stream as not allocated.*/ - dma_streams_mask &= ~(1 << dmastp->selfindex); - - /* Shutting down clocks that are no more required, if any.*/ - if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) - RCC->AHBENR &= ~RCC_AHBENR_DMA1EN; -#if STM32_HAS_DMA2 - if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) - RCC->AHBENR &= ~RCC_AHBENR_DMA2EN; -#endif -} - -#endif /* STM32_DMA_REQUIRED */ - -/** @} */ diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h deleted file mode 100644 index 0247c63cf..000000000 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h +++ /dev/null @@ -1,274 +0,0 @@ -/* - 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 . -*/ - -/** - * @file DMAv1/stm32_dma.h - * @brief DMA helper driver header. - * @note This file requires definitions from the ST header files - * stm32f10x.h or stm32l1xx.h. - * @note This driver uses the new naming convention used for the STM32F2xx - * so the "DMA channels" are referred as "DMA streams". - * - * @addtogroup STM32_DMA - * @{ - */ - -#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. - */ -#if STM32_HAS_DMA2 || defined(__DOXYGEN__) -#define STM32_DMA_STREAMS 12 -#else -#define STM32_DMA_STREAMS 7 -#endif - -/** - * @brief Mask of the ISR bits passed to the DMA callback functions. - */ -#define STM32_DMA_ISR_MASK 0x0F - -/** - * @name DMA streams identifiers - * @{ - */ -#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[0]) -#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[1]) -#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[2]) -#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[3]) -#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[4]) -#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[5]) -#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[6]) -#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[8]) -#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[9]) -#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[10]) -#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[11]) -#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[12]) -/** @} */ - -/** - * @name CR register constants common to all DMA types - */ -#define STM32_DMA_CR_EN DMA_CCR1_EN -#define STM32_DMA_CR_TEIE DMA_CCR1_TEIE -#define STM32_DMA_CR_HTIE DMA_CCR1_HTIE -#define STM32_DMA_CR_TCIE DMA_CCR1_TCIE -#define STM32_DMA_CR_DIR_MASK (DMA_CCR1_DIR | DMA_CCR1_MEM2MEM) -#define STM32_DMA_CR_DIR_P2M 0 -#define STM32_DMA_CR_DIR_M2P DMA_CCR1_DIR -#define STM32_DMA_CR_DIR_M2M DMA_CCR1_MEM2MEM -#define STM32_DMA_CR_CIRC DMA_CCR1_CIRC -#define STM32_DMA_CR_PINC DMA_CCR1_PINC -#define STM32_DMA_CR_MINC DMA_CCR1_MINC -#define STM32_DMA_CR_PSIZE_MASK DMA_CCR1_PSIZE -#define STM32_DMA_CR_PSIZE_BYTE 0 -#define STM32_DMA_CR_PSIZE_HWORD DMA_CCR1_PSIZE_0 -#define STM32_DMA_CR_PSIZE_WORD DMA_CCR1_PSIZE_1 -#define STM32_DMA_CR_MSIZE_MASK DMA_CCR1_MSIZE -#define STM32_DMA_CR_MSIZE_BYTE 0 -#define STM32_DMA_CR_MSIZE_HWORD DMA_CCR1_MSIZE_0 -#define STM32_DMA_CR_MSIZE_WORD DMA_CCR1_MSIZE_1 -#define STM32_DMA_CR_PL_MASK DMA_CCR1_PL -#define STM32_DMA_CR_PL(n) ((n) << 12) -/** @} */ -/** - * @name CR register constants only found in enhanced DMA - */ -#define STM32_DMA_CR_CHSEL_MASK 0 /**< @brief Ignored by normal DMA. */ -#define STM32_DMA_CR_CHSEL(n) 0 /**< @brief Ignored by normal DMA. */ -/** @} */ - -/** - * @name Status flags passed to the ISR callbacks - */ -#define STM32_DMA_ISR_FEIF 0 -#define STM32_DMA_ISR_DMEIF 0 -#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1 -#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1 -#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1 -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* 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 ISR 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 CPAR register - * - * @special - */ -#define dmaStreamSetPeripheral(dmastp, addr) { \ - (dmastp)->channel->CPAR = (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 CMAR register - * - * @special - */ -#define dmaStreamSetMemory0(dmastp, addr) { \ - (dmastp)->channel->CMAR = (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)->channel->CNDTR = (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)->channel->CNDTR)) - -/** - * @brief Programs the stream mode settings. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] mode value to be written in the CCR register - * - * @special - */ -#define dmaStreamSetMode(dmastp, mode) { \ - (dmastp)->channel->CCR = (uint32_t)(mode); \ -} - -/** - * @brief DMA 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(dmastp) { \ - (dmastp)->channel->CCR |= 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)->channel->CCR &= ~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_ */ - -/** @} */ -- cgit v1.2.3 From c5750b6977d7a45fe44c93df66c109ad446c5ce6 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Aug 2011 12:11:33 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3258 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/stm32_dma.c | 3 ++- os/hal/platforms/STM32/DMAv1/stm32_dma.h | 1 + os/hal/platforms/STM32/DMAv2/stm32_dma.c | 42 +++++++++++++++++++++++++------- os/hal/platforms/STM32/DMAv2/stm32_dma.h | 23 ++++++++--------- 4 files changed, 48 insertions(+), 21 deletions(-) diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.c b/os/hal/platforms/STM32/DMAv1/stm32_dma.c index 1df93bb2f..e24ef565b 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.c @@ -446,7 +446,8 @@ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, /* Putting the stream in a safe state.*/ dmaStreamDisable(dmastp); dmaStreamClearInterrupt(dmastp); - dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; + 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) diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.h b/os/hal/platforms/STM32/DMAv1/stm32_dma.h index 0247c63cf..473bbe851 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.h @@ -95,6 +95,7 @@ #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 */ diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.c b/os/hal/platforms/STM32/DMAv2/stm32_dma.c index 5d320dab3..05d6100c0 100644 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.c @@ -54,6 +54,16 @@ */ #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. */ /*===========================================================================*/ @@ -428,13 +438,15 @@ void dmaInit(void) { /** * @brief Allocates a DMA stream. * @details The stream is allocated and, if required, the DMA clock enabled. - * Trying to allocate a stream already allocated is an illegal - * operation and is trapped if assertions are enabled. - * @pre The stream must not be already in use. + * 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 must be freed using @p dmaRelease() before it can + * @post The stream ISR vector is enabled and its priority configured. + * @post The stream must be freed using @p dmaStreamRelease() before it can * be reused with another peripheral. + * @post The stream is in its post-reset state. * @note This function can be invoked in both ISR or thread context. * * @param[in] dmastp pointer to a stm32_dma_stream_t structure @@ -446,8 +458,10 @@ void dmaInit(void) { * * @special */ -bool_t dmaAllocate(const stm32_dma_stream_t *dmastp, - stm32_dmaisr_t func, void *param) { +bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param) { chDbgCheck(dmastp != NULL, "dmaAllocate"); @@ -470,8 +484,15 @@ bool_t dmaAllocate(const stm32_dma_stream_t *dmastp, RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA2LPEN; } - /* Making sure there are no spurious interrupts flags pending.*/ + /* 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; } @@ -480,7 +501,7 @@ bool_t dmaAllocate(const stm32_dma_stream_t *dmastp, * @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 dmaRequest(). + * @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. * @@ -488,7 +509,7 @@ bool_t dmaAllocate(const stm32_dma_stream_t *dmastp, * * @special */ -void dmaRelease(const stm32_dma_stream_t *dmastp) { +void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { chDbgCheck(dmastp != NULL, "dmaRelease"); @@ -496,6 +517,9 @@ void dmaRelease(const stm32_dma_stream_t *dmastp) { 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); diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.h b/os/hal/platforms/STM32/DMAv2/stm32_dma.h index 88f594eec..af18497fc 100644 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.h @@ -155,13 +155,12 @@ * @brief STM32 DMA stream descriptor structure. */ typedef struct { - uint32_t selfindex; /**< @brief Index to self in array. */ - DMA_TypeDef *dma; /**< @brief Associated DMA unit. */ - DMA_Stream_TypeDef *stream; /**< @brief Associated DMA stream. */ - volatile uint32_t *isr; /**< @brief Associated xISR reg. */ - volatile uint32_t *ifcr; /**< @brief Associated xIFCR reg. */ - uint32_t ishift; /**< @brief Bits offset in xIFCR - registers. */ + 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; /** @@ -250,7 +249,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * @special */ #define dmaStreamSetMode(dmastp, mode) { \ - (dmastp)->stream->CR = (uint32_t)(mode2); \ + (dmastp)->stream->CR = (uint32_t)(mode); \ } /** @@ -314,9 +313,11 @@ extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; extern "C" { #endif void dmaInit(void); - bool_t dmaAllocate(const stm32_dma_stream_t *dmastp, - stm32_dmaisr_t func, void *param); - void dmaRelease(const stm32_dma_stream_t *dmastp); + 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 -- cgit v1.2.3 From 8f5830dad86a26f92a293fc85a508a5b07c8f8e7 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Aug 2011 12:16:49 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3259 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/stm32_dma.c | 3 +-- os/hal/platforms/STM32/DMAv2/stm32_dma.c | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.c b/os/hal/platforms/STM32/DMAv1/stm32_dma.c index e24ef565b..1df93bb2f 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.c @@ -446,8 +446,7 @@ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, /* 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; + dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; /* Enables the associated IRQ vector if a callback is defined.*/ if (func != NULL) diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.c b/os/hal/platforms/STM32/DMAv2/stm32_dma.c index 05d6100c0..2b6851ad6 100644 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.c @@ -487,7 +487,8 @@ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, /* Putting the stream in a safe state.*/ dmaStreamDisable(dmastp); dmaStreamClearInterrupt(dmastp); - dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; + 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) -- cgit v1.2.3 From 339cbbd60e7c45bb21758cdfe264e8e1c78d4fd5 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Aug 2011 12:55:02 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3260 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/usb_cdc.h | 22 ++++++++++++++++------ os/hal/platforms/STM32/USBv1/usb_lld.c | 2 +- os/hal/src/serial_usb.c | 6 +++--- testhal/STM32F1xx/USB_CDC/chconf.h | 12 ++++++------ testhal/STM32F1xx/USB_CDC/main.c | 12 ++++++------ 5 files changed, 32 insertions(+), 22 deletions(-) diff --git a/os/hal/include/usb_cdc.h b/os/hal/include/usb_cdc.h index cd9d78f10..48a543642 100644 --- a/os/hal/include/usb_cdc.h +++ b/os/hal/include/usb_cdc.h @@ -33,6 +33,10 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @name CDC specific messages. + * @{ + */ #define CDC_SEND_ENCAPSULATED_COMMAND 0x00 #define CDC_GET_ENCAPSULATED_RESPONSE 0x01 #define CDC_SET_COMM_FEATURE 0x02 @@ -52,7 +56,12 @@ #define CDC_GET_RINGER_PARMS 0x31 #define CDC_SET_OPERATION_PARMS 0x32 #define CDC_GET_OPERATION_PARMS 0x33 +/** @} */ +/** + * @name Line Control bit definitions. + * @{ + */ #define LC_STOP_1 0 #define LC_STOP_1P5 1 #define LC_STOP_2 2 @@ -62,6 +71,7 @@ #define LC_PARITY_EVEN 2 #define LC_PARITY_MARK 3 #define LC_PARITY_SPACE 4 +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ @@ -74,22 +84,22 @@ /** * @brief Endpoint number for bulk IN. */ -#if !defined(DATA_REQUEST_EP) || defined(__DOXYGEN__) -#define DATA_REQUEST_EP 1 +#if !defined(USB_CDC_DATA_REQUEST_EP) || defined(__DOXYGEN__) +#define USB_CDC_DATA_REQUEST_EP 1 #endif /** * @brief Endpoint number for interrupt IN. */ -#if !defined(INTERRUPT_REQUEST_EP) || defined(__DOXYGEN__) -#define INTERRUPT_REQUEST_EP 2 +#if !defined(USB_CDC_INTERRUPT_REQUEST_EP) || defined(__DOXYGEN__) +#define USB_CDC_INTERRUPT_REQUEST_EP 2 #endif /** * @brief Endpoint number for bulk OUT. */ -#if !defined(DATA_AVAILABLE_EP) || defined(__DOXYGEN__) -#define DATA_AVAILABLE_EP 3 +#if !defined(USB_CDC_DATA_AVAILABLE_EP) || defined(__DOXYGEN__) +#define USB_CDC_DATA_AVAILABLE_EP 3 #endif /** @} */ diff --git a/os/hal/platforms/STM32/USBv1/usb_lld.c b/os/hal/platforms/STM32/USBv1/usb_lld.c index db0c558b6..34b8d9bf0 100644 --- a/os/hal/platforms/STM32/USBv1/usb_lld.c +++ b/os/hal/platforms/STM32/USBv1/usb_lld.c @@ -105,7 +105,7 @@ static uint32_t pm_alloc(USBDriver *usbp, size_t size) { next = usbp->pmnext; usbp->pmnext += size; - chDbgAssert(usbp->pmnext > USB_PMA_SIZE, "pm_alloc(), #1", "PMA overflow"); + chDbgAssert(usbp->pmnext <= USB_PMA_SIZE, "pm_alloc(), #1", "PMA overflow"); return next; } diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c index d9c25ecdf..237d8e027 100644 --- a/os/hal/src/serial_usb.c +++ b/os/hal/src/serial_usb.c @@ -124,7 +124,7 @@ static void inotify(GenericQueue *qp) { emptied, then a whole packet is loaded in the queue.*/ if (chIQIsEmptyI(&sdup->iqueue)) { - n = usbReadPacketI(sdup->config->usbp, DATA_AVAILABLE_EP, + n = usbReadPacketI(sdup->config->usbp, USB_CDC_DATA_AVAILABLE_EP, sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE); if (n != USB_ENDPOINT_BUSY) { chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE); @@ -146,7 +146,7 @@ static void onotify(GenericQueue *qp) { /* If there is any data in the output queue then it is sent within a single packet and the queue is emptied.*/ n = chOQGetFullI(&sdup->oqueue); - w = usbWritePacketI(sdup->config->usbp, DATA_REQUEST_EP, + w = usbWritePacketI(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP, sdup->oqueue.q_buffer, n); if (w != USB_ENDPOINT_BUSY) { chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY); @@ -211,10 +211,10 @@ void sduStart(SerialUSBDriver *sdup, const SerialUSBConfig *config) { "sduStart(), #1", "invalid state"); sdup->config = config; - usbStart(config->usbp, &config->usb_config); config->usbp->param = sdup; sdup->state = SDU_READY; chSysUnlock(); + usbStart(config->usbp, &config->usb_config); } /** diff --git a/testhal/STM32F1xx/USB_CDC/chconf.h b/testhal/STM32F1xx/USB_CDC/chconf.h index 9dd831c96..a5d129956 100644 --- a/testhal/STM32F1xx/USB_CDC/chconf.h +++ b/testhal/STM32F1xx/USB_CDC/chconf.h @@ -361,7 +361,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_SYSTEM_STATE_CHECK FALSE +#define CH_DBG_SYSTEM_STATE_CHECK TRUE #endif /** @@ -372,7 +372,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_CHECKS FALSE +#define CH_DBG_ENABLE_CHECKS TRUE #endif /** @@ -384,7 +384,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_ASSERTS FALSE +#define CH_DBG_ENABLE_ASSERTS TRUE #endif /** @@ -395,7 +395,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_TRACE FALSE +#define CH_DBG_ENABLE_TRACE TRUE #endif /** @@ -409,7 +409,7 @@ * @p panic_msg variable set to @p NULL. */ #if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_STACK_CHECK FALSE +#define CH_DBG_ENABLE_STACK_CHECK TRUE #endif /** @@ -421,7 +421,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__) -#define CH_DBG_FILL_THREADS FALSE +#define CH_DBG_FILL_THREADS TRUE #endif /** diff --git a/testhal/STM32F1xx/USB_CDC/main.c b/testhal/STM32F1xx/USB_CDC/main.c index a0a965bba..601b6ce0b 100644 --- a/testhal/STM32F1xx/USB_CDC/main.c +++ b/testhal/STM32F1xx/USB_CDC/main.c @@ -114,7 +114,7 @@ static const uint8_t vcom_configuration_descriptor_data[67] = { USB_DESC_BYTE (0x01), /* bSlaveInterface0 (Data Class Interface). */ /* Endpoint 2 Descriptor.*/ - USB_DESC_ENDPOINT (INTERRUPT_REQUEST_EP|0x80, /* bEndpointAddress. */ + USB_DESC_ENDPOINT (USB_CDC_INTERRUPT_REQUEST_EP|0x80, 0x03, /* bmAttributes (Interrupt). */ 0x0008, /* wMaxPacketSize. */ 0xFF), /* bInterval. */ @@ -130,12 +130,12 @@ static const uint8_t vcom_configuration_descriptor_data[67] = { 4.7). */ 0x00), /* iInterface. */ /* Endpoint 3 Descriptor.*/ - USB_DESC_ENDPOINT (DATA_AVAILABLE_EP, /* bEndpointAddress. */ + USB_DESC_ENDPOINT (USB_CDC_DATA_AVAILABLE_EP, /* bEndpointAddress.*/ 0x02, /* bmAttributes (Bulk). */ 0x0040, /* wMaxPacketSize. */ 0x00), /* bInterval. */ /* Endpoint 1 Descriptor.*/ - USB_DESC_ENDPOINT (DATA_REQUEST_EP|0x80, /* bEndpointAddress. */ + USB_DESC_ENDPOINT (USB_CDC_DATA_REQUEST_EP|0x80, /* bEndpointAddress.*/ 0x02, /* bmAttributes (Bulk). */ 0x0040, /* wMaxPacketSize. */ 0x00) /* bInterval. */ @@ -282,9 +282,9 @@ static void usb_event(USBDriver *usbp, usbevent_t event) { Note, this callback is invoked from an ISR so I-Class functions must be used.*/ chSysLockFromIsr(); - usbInitEndpointI(usbp, DATA_REQUEST_EP, &ep1config); - usbInitEndpointI(usbp, INTERRUPT_REQUEST_EP, &ep2config); - usbInitEndpointI(usbp, DATA_AVAILABLE_EP, &ep3config); + usbInitEndpointI(usbp, USB_CDC_DATA_REQUEST_EP, &ep1config); + usbInitEndpointI(usbp, USB_CDC_INTERRUPT_REQUEST_EP, &ep2config); + usbInitEndpointI(usbp, USB_CDC_DATA_AVAILABLE_EP, &ep3config); chSysUnlockFromIsr(); return; case USB_EVENT_SUSPEND: -- cgit v1.2.3 From 76f8d18aaf60c6d916a799ba3d8b09815da979b2 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Aug 2011 12:57:21 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3261 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/src/serial_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c index 237d8e027..16822502a 100644 --- a/os/hal/src/serial_usb.c +++ b/os/hal/src/serial_usb.c @@ -234,9 +234,9 @@ void sduStop(SerialUSBDriver *sdup) { chDbgAssert((sdup->state == SDU_STOP) || (sdup->state == SDU_READY), "sduStop(), #1", "invalid state"); - usbStop(sdup->config->usbp); sdup->state = SDU_STOP; chSysUnlock(); + usbStop(sdup->config->usbp); } /** -- cgit v1.2.3 From 663214d0e6728d153fd4118324e69c75c574327c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Aug 2011 13:00:56 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3262 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- todo.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/todo.txt b/todo.txt index f64e907cb..6cf27e77e 100644 --- a/todo.txt +++ b/todo.txt @@ -18,6 +18,8 @@ X STM32L support. X STM32L-Discovery demo and article. X File System infrastructure. X STM32F2xx support. +- USB and USB_SERIAL APIs reclassification (if needed), incorporate the USB + bus attach/detach handling in usbStart()/usbStop(). - MMC_SPI driver revision and speedup. - Test suite overhaul, the API should be more generic in order to be used with different subsystems and not just the kernel. -- cgit v1.2.3