aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
authorbarthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-08-28 13:39:56 +0000
committerbarthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-08-28 13:39:56 +0000
commitfc492c6d190610cc9537360edf44d6dc5d072a2c (patch)
tree53fb1786e058f872671fb3adca4e73c708716d54 /os/hal
parentda23780899ae4b9ce1bbe0cb9109da1c87fe0fa1 (diff)
parent663214d0e6728d153fd4118324e69c75c574327c (diff)
downloadChibiOS-fc492c6d190610cc9537360edf44d6dc5d072a2c.tar.gz
ChibiOS-fc492c6d190610cc9537360edf44d6dc5d072a2c.tar.bz2
ChibiOS-fc492c6d190610cc9537360edf44d6dc5d072a2c.zip
I2C. Merge code from trunk.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3263 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/include/adc.h10
-rw-r--r--os/hal/include/can.h18
-rw-r--r--os/hal/include/icu.h10
-rw-r--r--os/hal/include/mac.h5
-rw-r--r--os/hal/include/mii.h6
-rw-r--r--os/hal/include/mmc_spi.h10
-rw-r--r--os/hal/include/pal.h15
-rw-r--r--os/hal/include/pwm.h15
-rw-r--r--os/hal/include/sdc.h22
-rw-r--r--os/hal/include/serial.h32
-rw-r--r--os/hal/include/serial_usb.h7
-rw-r--r--os/hal/include/spi.h15
-rw-r--r--os/hal/include/uart.h23
-rw-r--r--os/hal/include/usb.h21
-rw-r--r--os/hal/include/usb_cdc.h27
-rw-r--r--os/hal/platforms/STM32/DMAv1/sdc_lld.c86
-rw-r--r--os/hal/platforms/STM32/DMAv1/sdc_lld.h2
-rw-r--r--os/hal/platforms/STM32/DMAv1/spi_lld.c169
-rw-r--r--os/hal/platforms/STM32/DMAv1/spi_lld.h32
-rw-r--r--os/hal/platforms/STM32/DMAv1/stm32_dma.c414
-rw-r--r--os/hal/platforms/STM32/DMAv1/stm32_dma.h273
-rw-r--r--os/hal/platforms/STM32/DMAv1/uart_lld.c180
-rw-r--r--os/hal/platforms/STM32/DMAv1/uart_lld.h12
-rw-r--r--os/hal/platforms/STM32/DMAv2/stm32_dma.c540
-rw-r--r--os/hal/platforms/STM32/DMAv2/stm32_dma.h327
-rw-r--r--os/hal/platforms/STM32/GPIOv1/pal_lld.c4
-rw-r--r--os/hal/platforms/STM32/GPIOv1/pal_lld.h4
-rw-r--r--os/hal/platforms/STM32/USBv1/usb_lld.c2
-rw-r--r--os/hal/platforms/STM32F1xx/adc_lld.c50
-rw-r--r--os/hal/platforms/STM32F1xx/adc_lld.h8
-rw-r--r--os/hal/src/adc.c10
-rw-r--r--os/hal/src/can.c4
-rw-r--r--os/hal/src/gpt.c14
-rw-r--r--os/hal/src/hal.c4
-rw-r--r--os/hal/src/i2c.c4
-rw-r--r--os/hal/src/icu.c8
-rw-r--r--os/hal/src/mac.c4
-rw-r--r--os/hal/src/mmc_spi.c4
-rw-r--r--os/hal/src/pal.c4
-rw-r--r--os/hal/src/pwm.c4
-rw-r--r--os/hal/src/sdc.c8
-rw-r--r--os/hal/src/serial.c6
-rw-r--r--os/hal/src/serial_usb.c12
-rw-r--r--os/hal/src/spi.c4
-rw-r--r--os/hal/src/uart.c14
-rw-r--r--os/hal/src/usb.c26
-rw-r--r--os/hal/templates/adc_lld.c4
-rw-r--r--os/hal/templates/can_lld.c4
-rw-r--r--os/hal/templates/can_lld.h13
-rw-r--r--os/hal/templates/gpt_lld.c4
-rw-r--r--os/hal/templates/hal_lld.c4
-rw-r--r--os/hal/templates/halconf.h90
-rw-r--r--os/hal/templates/i2c_lld.c4
-rw-r--r--os/hal/templates/icu_lld.c4
-rw-r--r--os/hal/templates/mac_lld.c4
-rw-r--r--os/hal/templates/mac_lld.h21
-rw-r--r--os/hal/templates/meta/driver.c4
-rw-r--r--os/hal/templates/meta/driver_lld.c4
-rw-r--r--os/hal/templates/pal_lld.c4
-rw-r--r--os/hal/templates/pwm_lld.c4
-rw-r--r--os/hal/templates/serial_lld.c4
-rw-r--r--os/hal/templates/spi_lld.c4
-rw-r--r--os/hal/templates/uart_lld.c4
-rw-r--r--os/hal/templates/usb_lld.c4
64 files changed, 1965 insertions, 688 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
@@ -40,6 +40,10 @@
/*===========================================================================*/
/**
+ * @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
@@ -36,6 +36,10 @@
/*===========================================================================*/
/**
+ * @name CAN status flags
+ * @{
+ */
+/**
* @brief Errors rate warning.
*/
#define CAN_LIMIT_WARNING 1
@@ -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. */
@@ -97,6 +110,10 @@ typedef enum {
/*===========================================================================*/
/**
+ * @name Macro Functions
+ * @{
+ */
+/**
* @brief Adds some flags to the CAN status mask.
*
* @param[in] canp pointer to the @p CANDriver object
@@ -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
@@ -78,6 +78,10 @@ typedef void (*icucallback_t)(ICUDriver *icup);
/*===========================================================================*/
/**
+ * @name Macro Functions
+ * @{
+ */
+/**
* @brief Enables the input capture.
*
* @param[in] icup pointer to the @p ICUDriver object
@@ -118,8 +122,13 @@ 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.
*
* @param[in] icup pointer to the @p ICUDriver object
@@ -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
@@ -57,6 +57,10 @@
/*===========================================================================*/
/**
+ * @name Macro Functions
+ * @{
+ */
+/**
* @brief Returns the received frames event source.
*
* @param[in] macp pointer to the @p MACDriver object
@@ -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 <http://www.gnu.org/licenses/>.
*/
-/*
- * Parts of this file have been borrowed from the Linux include file
- * linux/mii.h:
- * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com)
- */
-
/*-*
* @file mii.h
* @brief MII Driver macros and structures.
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
@@ -54,6 +54,10 @@
/*===========================================================================*/
/**
+ * @name MMC_SPI configuration options
+ * @{
+ */
+/**
* @brief Block size for MMC transfers.
*/
#if !defined(MMC_SECTOR_SIZE) || defined(__DOXYGEN__)
@@ -86,6 +90,7 @@
#if !defined(MMC_POLLING_DELAY) || defined(__DOXYGEN__)
#define MMC_POLLING_DELAY 10
#endif
+/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
@@ -182,6 +187,10 @@ typedef struct {
/*===========================================================================*/
/**
+ * @name Macro Functions
+ * @{
+ */
+/**
* @brief Returns the driver state.
*
* @param[in] mmcp pointer to the @p MMCDriver object
@@ -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
@@ -36,6 +36,10 @@
/*===========================================================================*/
/**
+ * @name Pads mode constants
+ * @{
+ */
+/**
* @brief After reset state.
* @details The state itself is not specified and is architecture dependent,
* it is guaranteed to be equal to the after-reset state. It is
@@ -81,8 +85,13 @@
* @brief Open-drain output pad.
*/
#define PAL_MODE_OUTPUT_OPENDRAIN 7
+/** @} */
/**
+ * @name Logic level constants
+ * @{
+ */
+/**
* @brief Logical low state.
*/
#define PAL_LOW 0
@@ -91,6 +100,7 @@
* @brief Logical high state.
*/
#define PAL_HIGH 1
+/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
@@ -178,6 +188,10 @@ typedef struct {
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
* no need to explicitly initialize the driver.
@@ -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
@@ -36,6 +36,10 @@
/*===========================================================================*/
/**
+ * @name PWM output mode macros
+ * @{
+ */
+/**
* @brief Standard output modes mask.
*/
#define PWM_OUTPUT_MASK 0x0F
@@ -54,6 +58,7 @@
* @brief Inverse PWM logic, active is logic level zero.
*/
#define PWM_OUTPUT_ACTIVE_LOW 0x02
+/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
@@ -95,6 +100,10 @@ typedef void (*pwmcallback_t)(PWMDriver *pwmp);
/*===========================================================================*/
/**
+ * @name PWM duty cycle conversion
+ * @{
+ */
+/**
* @brief Converts from fraction to pulse width.
* @note Be careful with rounding errors, this is integer math not magic.
* You can specify tenths of thousandth but make sure you have the
@@ -143,8 +152,13 @@ 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
* been activated using @p pwmStart().
@@ -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..8de6de823 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.
@@ -88,6 +93,10 @@
/*===========================================================================*/
/**
+ * @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. */
@@ -143,6 +153,10 @@ typedef enum {
/*===========================================================================*/
/**
+ * @name R1 response utilities
+ * @{
+ */
+/**
* @brief Evaluates to @p TRUE if the R1 response contains error flags.
*
* @param[in] r1 the r1 response
@@ -162,8 +176,13 @@ 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.
*
* @param[in] sdcp pointer to the @p SDCDriver object
@@ -204,6 +223,7 @@ typedef enum {
* @api
*/
#define sdcIsWriteProtected(sdcp) (sdc_lld_is_write_protected(sdcp))
+/** @} */
/*===========================================================================*/
/* External declarations. */
@@ -222,7 +242,7 @@ extern "C" {
uint8_t *buffer, uint32_t n);
bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk,
const uint8_t *buffer, uint32_t n);
- bool_t sdc_wait_for_transfer_state(SDCDriver *sdcp);
+ bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp);
#ifdef __cplusplus
}
#endif
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,22 +35,26 @@
/* 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
* default configuration.
@@ -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 {
@@ -129,6 +136,10 @@ struct SerialDriver {
/*===========================================================================*/
/**
+ * @name Macro Functions
+ * @{
+ */
+/**
* @brief Direct output check on a @p SerialDriver.
* @note This function bypasses the indirect access to the channel and
* checks directly the output queue. This is faster but cannot
@@ -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
@@ -40,6 +40,10 @@
/*===========================================================================*/
/**
+ * @name SERIAL_USB configuration options
+ * @{
+ */
+/**
* @brief Serial over USB buffers size.
* @details Configuration parameter, the buffer size must be a multiple of
* the USB data endpoint maximum packet size.
@@ -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
@@ -40,6 +40,10 @@
/*===========================================================================*/
/**
+ * @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. */
@@ -85,6 +90,10 @@ typedef enum {
/*===========================================================================*/
/**
+ * @name Macro Functions
+ * @{
+ */
+/**
* @brief Asserts the slave select signal and prepares for transfers.
*
* @param[in] spip pointer to the @p SPIDriver object
@@ -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
@@ -78,6 +78,10 @@
#define USB_LATE_SET_ADDRESS 1
/**
+ * @name Helper macros for USB descriptors
+ * @{
+ */
+/**
* @brief Helper macro for index values into descriptor strings.
*/
#define USB_DESC_INDEX(i) ((uint8_t)(i))
@@ -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,8 +426,13 @@ 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.
*
* @param[in] usbp pointer to the @p USBDriver object
@@ -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..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,31 +71,37 @@
#define LC_PARITY_EVEN 2
#define LC_PARITY_MARK 3
#define LC_PARITY_SPACE 4
+/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
+ * @name USB_CDC configuration options
+ * @{
+ */
+/**
* @brief Endpoint number for bulk IN.
*/
-#if !defined(DATA_REQUEST_EP) || defined(__DOXYGEN__)
-#define DATA_REQUEST_EP 1
+#if !defined(USB_CDC_DATA_REQUEST_EP) || defined(__DOXYGEN__)
+#define USB_CDC_DATA_REQUEST_EP 1
#endif
/**
* @brief Endpoint number for interrupt IN.
*/
-#if !defined(INTERRUPT_REQUEST_EP) || defined(__DOXYGEN__)
-#define INTERRUPT_REQUEST_EP 2
+#if !defined(USB_CDC_INTERRUPT_REQUEST_EP) || defined(__DOXYGEN__)
+#define USB_CDC_INTERRUPT_REQUEST_EP 2
#endif
/**
* @brief Endpoint number for bulk OUT.
*/
-#if !defined(DATA_AVAILABLE_EP) || defined(__DOXYGEN__)
-#define DATA_AVAILABLE_EP 3
+#if !defined(USB_CDC_DATA_AVAILABLE_EP) || defined(__DOXYGEN__)
+#define USB_CDC_DATA_AVAILABLE_EP 3
#endif
+/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
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/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/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.c b/os/hal/platforms/STM32/DMAv1/stm32_dma.c
index 2232df448..1df93bb2f 100644
--- a/os/hal/platforms/STM32/DMAv1/stm32_dma.c
+++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.c
@@ -19,29 +19,79 @@
*/
/**
- * @file stm32_dma.c
- * @brief STM32 DMA helper driver code.
+ * @file DMAv1/stm32_dma.c
+ * @brief DMA helper driver code.
*
* @addtogroup STM32_DMA
- * @details DMA sharing helper driver. In the STM32 the DMA channels are a
+ * @details DMA sharing helper driver. In the STM32 the DMA streams are a
* shared resource, this driver allows to allocate and free DMA
- * channels at runtime in order to allow all the other device
+ * streams at runtime in order to allow all the other device
* drivers to coordinate the access to the resource.
* @note The DMA ISR handlers are all declared into this module because
* sharing, the various device drivers can associate a callback to
- * IRSs when allocating channels.
+ * IRSs when allocating streams.
* @{
*/
#include "ch.h"
#include "hal.h"
+/* The following macro is only defined if some driver requiring DMA services
+ has been enabled.*/
#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__)
/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/**
+ * @brief Mask of the DMA1 streams in @p dma_streams_mask.
+ */
+#define STM32_DMA1_STREAMS_MASK 0x0000007F
+
+/**
+ * @brief Mask of the DMA2 streams in @p dma_streams_mask.
+ */
+#define STM32_DMA2_STREAMS_MASK 0x00000F80
+
+/**
+ * @brief Post-reset value of the stream CCR register.
+ */
+#define STM32_DMA_CCR_RESET_VALUE 0x00000000
+
+/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
+/**
+ * @brief DMA streams descriptors.
+ * @details This table keeps the association between an unique stream
+ * identifier and the involved physical registers.
+ * @note Don't use this array directly, use the appropriate wrapper macros
+ * instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc.
+ */
+const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
+ {DMA1_Channel1, &DMA1->IFCR, 0, 0, DMA1_Channel1_IRQn},
+ {DMA1_Channel2, &DMA1->IFCR, 4, 1, DMA1_Channel2_IRQn},
+ {DMA1_Channel3, &DMA1->IFCR, 8, 2, DMA1_Channel3_IRQn},
+ {DMA1_Channel4, &DMA1->IFCR, 12, 3, DMA1_Channel4_IRQn},
+ {DMA1_Channel5, &DMA1->IFCR, 16, 4, DMA1_Channel5_IRQn},
+ {DMA1_Channel6, &DMA1->IFCR, 20, 5, DMA1_Channel6_IRQn},
+ {DMA1_Channel7, &DMA1->IFCR, 24, 6, DMA1_Channel7_IRQn},
+#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
+ {DMA2_Channel1, &DMA2->IFCR, 0, 7, DMA2_Channel1_IRQn},
+ {DMA2_Channel2, &DMA2->IFCR, 4, 8, DMA2_Channel2_IRQn},
+ {DMA2_Channel3, &DMA2->IFCR, 8, 9, DMA2_Channel3_IRQn},
+#if defined(STM32F10X_CL) || defined(__DOXYGEN__)
+ {DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_IRQn},
+ {DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel5_IRQn},
+#else /* !STM32F10X_CL */
+ {DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_5_IRQn},
+ {DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel4_5_IRQn},
+#endif /* !STM32F10X_CL */
+#endif /* STM32_HAS_DMA2 */
+};
+
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
@@ -50,17 +100,19 @@
* @brief DMA ISR redirector type.
*/
typedef struct {
- stm32_dmaisr_t dmaisrfunc;
- void *dmaisrparam;
+ stm32_dmaisr_t dma_func;
+ void *dma_param;
} dma_isr_redir_t;
-static uint32_t dmamsk1;
-static dma_isr_redir_t dma1[7];
+/**
+ * @brief Mask of the allocated streams.
+ */
+static uint32_t dma_streams_mask;
-#if STM32_HAS_DMA2
-static uint32_t dmamsk2;
-static dma_isr_redir_t dma2[5];
-#endif
+/**
+ * @brief DMA IRQ redirectors.
+ */
+static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS];
/*===========================================================================*/
/* Driver local functions. */
@@ -71,250 +123,249 @@ static dma_isr_redir_t dma2[5];
/*===========================================================================*/
/**
- * @brief DMA1 channel 1 shared interrupt handler.
+ * @brief DMA1 stream 1 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) {
- uint32_t isr;
+ uint32_t flags;
CH_IRQ_PROLOGUE();
- isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_1 * 4);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_1);
- if (dma1[0].dmaisrfunc)
- dma1[0].dmaisrfunc(dma1[0].dmaisrparam, isr);
+ flags = (DMA1->ISR >> 0) & STM32_DMA_ISR_MASK;
+ DMA1->IFCR = STM32_DMA_ISR_MASK << 0;
+ if (dma_isr_redir[0].dma_func)
+ dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
- * @brief DMA1 channel 2 shared interrupt handler.
+ * @brief DMA1 stream 2 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) {
- uint32_t isr;
+ uint32_t flags;
CH_IRQ_PROLOGUE();
- isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_2 * 4);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
- if (dma1[1].dmaisrfunc)
- dma1[1].dmaisrfunc(dma1[1].dmaisrparam, isr);
+ flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK;
+ DMA1->IFCR = STM32_DMA_ISR_MASK << 4;
+ if (dma_isr_redir[1].dma_func)
+ dma_isr_redir[1].dma_func(dma_isr_redir[1].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
- * @brief DMA1 channel 3 shared interrupt handler.
+ * @brief DMA1 stream 3 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) {
- uint32_t isr;
+ uint32_t flags;
CH_IRQ_PROLOGUE();
- isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_3 * 4);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
- if (dma1[2].dmaisrfunc)
- dma1[2].dmaisrfunc(dma1[2].dmaisrparam, isr);
+ flags = (DMA1->ISR >> 8) & STM32_DMA_ISR_MASK;
+ DMA1->IFCR = STM32_DMA_ISR_MASK << 8;
+ if (dma_isr_redir[2].dma_func)
+ dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
- * @brief DMA1 channel 4 shared interrupt handler.
+ * @brief DMA1 stream 4 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) {
- uint32_t isr;
+ uint32_t flags;
CH_IRQ_PROLOGUE();
- isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_4 * 4);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
- if (dma1[3].dmaisrfunc)
- dma1[3].dmaisrfunc(dma1[3].dmaisrparam, isr);
+ flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK;
+ DMA1->IFCR = STM32_DMA_ISR_MASK << 12;
+ if (dma_isr_redir[3].dma_func)
+ dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
- * @brief DMA1 channel 5 shared interrupt handler.
+ * @brief DMA1 stream 5 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) {
- uint32_t isr;
+ uint32_t flags;
CH_IRQ_PROLOGUE();
- isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_5 * 4);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
- if (dma1[4].dmaisrfunc)
- dma1[4].dmaisrfunc(dma1[4].dmaisrparam, isr);
+ flags = (DMA1->ISR >> 16) & STM32_DMA_ISR_MASK;
+ DMA1->IFCR = STM32_DMA_ISR_MASK << 16;
+ if (dma_isr_redir[4].dma_func)
+ dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
- * @brief DMA1 channel 6 shared interrupt handler.
+ * @brief DMA1 stream 6 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) {
- uint32_t isr;
+ uint32_t flags;
CH_IRQ_PROLOGUE();
- isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_6 * 4);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
- if (dma1[5].dmaisrfunc)
- dma1[5].dmaisrfunc(dma1[5].dmaisrparam, isr);
+ flags = (DMA1->ISR >> 20) & STM32_DMA_ISR_MASK;
+ DMA1->IFCR = STM32_DMA_ISR_MASK << 20;
+ if (dma_isr_redir[5].dma_func)
+ dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
- * @brief DMA1 channel 7 shared interrupt handler.
+ * @brief DMA1 stream 7 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) {
- uint32_t isr;
+ uint32_t flags;
CH_IRQ_PROLOGUE();
- isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_7 * 4);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_7);
- if (dma1[6].dmaisrfunc)
- dma1[6].dmaisrfunc(dma1[6].dmaisrparam, isr);
+ flags = (DMA1->ISR >> 24) & STM32_DMA_ISR_MASK;
+ DMA1->IFCR = STM32_DMA_ISR_MASK << 24;
+ if (dma_isr_redir[6].dma_func)
+ dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags);
CH_IRQ_EPILOGUE();
}
#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
/**
- * @brief DMA2 channel 1 shared interrupt handler.
+ * @brief DMA2 stream 1 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) {
- uint32_t isr;
+ uint32_t flags;
CH_IRQ_PROLOGUE();
- isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_1 * 4);
- dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_1);
- if (dma2[0].dmaisrfunc)
- dma2[0].dmaisrfunc(dma2[0].dmaisrparam, isr);
+ flags = (DMA2->ISR >> 0) & STM32_DMA_ISR_MASK;
+ DMA2->IFCR = STM32_DMA_ISR_MASK << 0;
+ if (dma_isr_redir[7].dma_func)
+ dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
- * @brief DMA2 channel 2 shared interrupt handler.
+ * @brief DMA2 stream 2 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) {
- uint32_t isr;
+ uint32_t flags;
CH_IRQ_PROLOGUE();
- isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_2 * 4);
- dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_2);
- if (dma2[1].dmaisrfunc)
- dma2[1].dmaisrfunc(dma2[1].dmaisrparam, isr);
+ flags = (DMA2->ISR >> 4) & STM32_DMA_ISR_MASK;
+ DMA2->IFCR = STM32_DMA_ISR_MASK << 4;
+ if (dma_isr_redir[8].dma_func)
+ dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
- * @brief DMA2 channel 3 shared interrupt handler.
+ * @brief DMA2 stream 3 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA2_Ch3_IRQHandler) {
- uint32_t isr;
+ uint32_t flags;
CH_IRQ_PROLOGUE();
- isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_3 * 4);
- dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_3);
- if (dma2[2].dmaisrfunc)
- dma2[2].dmaisrfunc(dma2[2].dmaisrparam, isr);
+ flags = (DMA2->ISR >> 8) & STM32_DMA_ISR_MASK;
+ DMA2->IFCR = STM32_DMA_ISR_MASK << 8;
+ if (dma_isr_redir[9].dma_func)
+ dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags);
CH_IRQ_EPILOGUE();
}
#if defined(STM32F10X_CL) || defined(__DOXYGEN__)
/**
- * @brief DMA2 channel 4 shared interrupt handler.
+ * @brief DMA2 stream 4 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA2_Ch4_IRQHandler) {
- uint32_t isr;
+ uint32_t flags;
CH_IRQ_PROLOGUE();
- isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_4 * 4);
- dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
- if (dma2[3].dmaisrfunc)
- dma2[3].dmaisrfunc(dma2[3].dmaisrparam, isr);
+ flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK;
+ DMA2->IFCR = STM32_DMA_ISR_MASK << 12;
+ if (dma_isr_redir[10].dma_func)
+ dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
- * @brief DMA2 channel 5 shared interrupt handler.
+ * @brief DMA2 stream 5 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA2_Ch5_IRQHandler) {
- uint32_t isr;
+ uint32_t flags;
CH_IRQ_PROLOGUE();
- isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_5 * 4);
- dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5);
- if (dma2[4].dmaisrfunc)
- dma2[4].dmaisrfunc(dma2[4].dmaisrparam, isr);
+ flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK;
+ DMA2->IFCR = STM32_DMA_ISR_MASK << 16;
+ if (dma_isr_redir[11].dma_func)
+ dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags);
CH_IRQ_EPILOGUE();
}
-
#else /* !STM32F10X_CL */
/**
- * @brief DMA2 channels 4 and 5 shared interrupt handler.
+ * @brief DMA2 streams 4 and 5 shared interrupt handler.
* @note This IRQ is shared between DMA2 channels 4 and 5 so it is a
* bit less efficient because an extra check.
*
* @isr
*/
CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) {
- uint32_t isr;
+ uint32_t flags;
CH_IRQ_PROLOGUE();
/* Check on channel 4.*/
- isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_5 * 4);
- if (isr & DMA_ISR_GIF1) {
- dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5);
- if (dma2[3].dmaisrfunc)
- dma2[3].dmaisrfunc(dma2[3].dmaisrparam, isr);
+ flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK;
+ if (flags & STM32_DMA_ISR_MASK) {
+ DMA2->IFCR = STM32_DMA_ISR_MASK << 12;
+ if (dma_isr_redir[10].dma_func)
+ dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags);
}
/* Check on channel 5.*/
- isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_4 * 4);
- if (isr & DMA_ISR_GIF1) {
- dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5);
- if (dma2[4].dmaisrfunc)
- dma2[4].dmaisrfunc(dma2[4].dmaisrparam, isr);
+ flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK;
+ if (flags & STM32_DMA_ISR_MASK) {
+ DMA2->IFCR = STM32_DMA_ISR_MASK << 16;
+ if (dma_isr_redir[11].dma_func)
+ dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags);
}
CH_IRQ_EPILOGUE();
@@ -334,132 +385,109 @@ CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) {
void dmaInit(void) {
int i;
- dmamsk1 = 0;
- for (i = STM32_DMA_CHANNEL_7; i >= STM32_DMA_CHANNEL_1; i--) {
- dmaDisableChannel(STM32_DMA1, i);
- dma1[i].dmaisrfunc = NULL;
+ dma_streams_mask = 0;
+ for (i = 0; i < STM32_DMA_STREAMS; i++) {
+ _stm32_dma_streams[i].channel->CCR = 0;
+ dma_isr_redir[i].dma_func = NULL;
}
- STM32_DMA1->IFCR = 0xFFFFFFFF;
+ DMA1->IFCR = 0xFFFFFFFF;
#if STM32_HAS_DMA2
- dmamsk2 = 0;
- for (i = STM32_DMA_CHANNEL_5; i >= STM32_DMA_CHANNEL_1; i--) {
- dmaDisableChannel(STM32_DMA2, i);
- dma2[i].dmaisrfunc = NULL;
- }
- STM32_DMA1->IFCR = 0xFFFFFFFF;
+ DMA2->IFCR = 0xFFFFFFFF;
#endif
}
/**
- * @brief Allocates a DMA channel.
- * @details The channel is allocated and, if required, the DMA clock enabled.
- * Trying to allocate a channel already allocated is an illegal
- * operation and is trapped if assertions are enabled.
- * @pre The channel must not be already in use.
- * @post The channel is allocated and the default ISR handler redirected
+ * @brief Allocates a DMA stream.
+ * @details The stream is allocated and, if required, the DMA clock enabled.
+ * The function also enables the IRQ vector associated to the stream
+ * and initializes its priority.
+ * @pre The stream must not be already in use or an error is returned.
+ * @post The stream is allocated and the default ISR handler redirected
* to the specified function.
- * @post The channel must be freed using @p dmaRelease() before it can
+ * @post The stream ISR vector is enabled and its priority configured.
+ * @post The stream must be freed using @p dmaStreamRelease() before it can
* be reused with another peripheral.
+ * @post The stream is in its post-reset state.
* @note This function can be invoked in both ISR or thread context.
*
- * @param[in] dma DMA controller id
- * @param[in] channel requested channel id
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
* @param[in] func handling function pointer, can be @p NULL
* @param[in] param a parameter to be passed to the handling function
* @return The operation status.
- * @retval FALSE operation successfully allocated.
- * @retval TRUE the channel was already in use.
+ * @retval FALSE no error, stream taken.
+ * @retval TRUE error, stream already taken.
*
* @special
*/
-void dmaAllocate(uint32_t dma, uint32_t channel,
- stm32_dmaisr_t func, void *param) {
+bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
+ uint32_t priority,
+ stm32_dmaisr_t func,
+ void *param) {
- chDbgCheck(func != NULL, "dmaAllocate");
+ chDbgCheck(dmastp != NULL, "dmaAllocate");
+ /* Checks if the stream is already taken.*/
+ if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0)
+ return TRUE;
+
+ /* Marks the stream as allocated.*/
+ dma_isr_redir[dmastp->selfindex].dma_func = func;
+ dma_isr_redir[dmastp->selfindex].dma_param = param;
+ dma_streams_mask |= (1 << dmastp->selfindex);
+
+ /* Enabling DMA clocks required by the current streams set.*/
+ if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0)
+ RCC->AHBENR |= RCC_AHBENR_DMA1EN;
#if STM32_HAS_DMA2
- switch (dma) {
- case STM32_DMA1_ID:
-#else
- (void)dma;
-#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 66a2f8c69..473bbe851 100644
--- a/os/hal/platforms/STM32/DMAv1/stm32_dma.h
+++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.h
@@ -19,10 +19,12 @@
*/
/**
- * @file stm32_dma.h
- * @brief STM32 DMA helper driver header.
- * @note This file requires definitions from the ST STM32 header file
- * stm3232f10x.h.
+ * @file DMAv1/stm32_dma.h
+ * @brief DMA helper driver header.
+ * @note This file requires definitions from the ST header files
+ * stm32f10x.h or stm32l1xx.h.
+ * @note This driver uses the new naming convention used for the STM32F2xx
+ * so the "DMA channels" are referred as "DMA streams".
*
* @addtogroup STM32_DMA
* @{
@@ -35,14 +37,82 @@
/* Driver constants. */
/*===========================================================================*/
-/** @brief DMA1 identifier.*/
-#define STM32_DMA1_ID 0
-
-/** @brief DMA2 identifier.*/
+/**
+ * @brief Total number of DMA streams.
+ * @note This is the total number of streams among all the DMA units.
+ */
#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
-#define STM32_DMA2_ID 1
+#define STM32_DMA_STREAMS 12
+#else
+#define STM32_DMA_STREAMS 7
#endif
+/**
+ * @brief Mask of the ISR bits passed to the DMA callback functions.
+ */
+#define STM32_DMA_ISR_MASK 0x0F
+
+/**
+ * @name DMA streams identifiers
+ * @{
+ */
+#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[0])
+#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[1])
+#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[2])
+#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[3])
+#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[4])
+#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[5])
+#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[6])
+#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[8])
+#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[9])
+#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[10])
+#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[11])
+#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[12])
+/** @} */
+
+/**
+ * @name CR register constants common to all DMA types
+ */
+#define STM32_DMA_CR_EN DMA_CCR1_EN
+#define STM32_DMA_CR_TEIE DMA_CCR1_TEIE
+#define STM32_DMA_CR_HTIE DMA_CCR1_HTIE
+#define STM32_DMA_CR_TCIE DMA_CCR1_TCIE
+#define STM32_DMA_CR_DIR_MASK (DMA_CCR1_DIR | DMA_CCR1_MEM2MEM)
+#define STM32_DMA_CR_DIR_P2M 0
+#define STM32_DMA_CR_DIR_M2P DMA_CCR1_DIR
+#define STM32_DMA_CR_DIR_M2M DMA_CCR1_MEM2MEM
+#define STM32_DMA_CR_CIRC DMA_CCR1_CIRC
+#define STM32_DMA_CR_PINC DMA_CCR1_PINC
+#define STM32_DMA_CR_MINC DMA_CCR1_MINC
+#define STM32_DMA_CR_PSIZE_MASK DMA_CCR1_PSIZE
+#define STM32_DMA_CR_PSIZE_BYTE 0
+#define STM32_DMA_CR_PSIZE_HWORD DMA_CCR1_PSIZE_0
+#define STM32_DMA_CR_PSIZE_WORD DMA_CCR1_PSIZE_1
+#define STM32_DMA_CR_MSIZE_MASK DMA_CCR1_MSIZE
+#define STM32_DMA_CR_MSIZE_BYTE 0
+#define STM32_DMA_CR_MSIZE_HWORD DMA_CCR1_MSIZE_0
+#define STM32_DMA_CR_MSIZE_WORD DMA_CCR1_MSIZE_1
+#define STM32_DMA_CR_PL_MASK DMA_CCR1_PL
+#define STM32_DMA_CR_PL(n) ((n) << 12)
+/** @} */
+
+/**
+ * @name CR register constants only found in enhanced DMA
+ */
+#define STM32_DMA_CR_CHSEL_MASK 0 /**< @brief Ignored by normal DMA. */
+#define STM32_DMA_CR_CHSEL(n) 0 /**< @brief Ignored by normal DMA. */
+/** @} */
+
+/**
+ * @name Status flags passed to the ISR callbacks
+ */
+#define STM32_DMA_ISR_FEIF 0
+#define STM32_DMA_ISR_DMEIF 0
+#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1
+#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1
+#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1
+/** @} */
+
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
@@ -56,33 +126,23 @@
/*===========================================================================*/
/**
- * @brief STM32 DMA channel memory structure type.
- */
-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,187 +150,122 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
/* Driver macros. */
/*===========================================================================*/
-/** DMA1 registers block numeric address.*/
-#define STM32_DMA1_BASE (AHBPERIPH_BASE + 0x0000)
-/** Pointer to the DMA1 registers block.*/
-#define STM32_DMA1 ((stm32_dma_t *)STM32_DMA1_BASE)
-/** Pointer to the DMA1 channel 1 registers block.*/
-#define STM32_DMA1_CH1 (&STM32_DMA1->channels[0])
-/** Pointer to the DMA1 channel 2 registers block.*/
-#define STM32_DMA1_CH2 (&STM32_DMA1->channels[1])
-/** Pointer to the DMA1 channel 3 registers block.*/
-#define STM32_DMA1_CH3 (&STM32_DMA1->channels[2])
-/** Pointer to the DMA1 channel 4 registers block.*/
-#define STM32_DMA1_CH4 (&STM32_DMA1->channels[3])
-/** Pointer to the DMA1 channel 5 registers block.*/
-#define STM32_DMA1_CH5 (&STM32_DMA1->channels[4])
-/** Pointer to the DMA1 channel 6 registers block.*/
-#define STM32_DMA1_CH6 (&STM32_DMA1->channels[5])
-/** Pointer to the DMA1 channel 7 registers block.*/
-#define STM32_DMA1_CH7 (&STM32_DMA1->channels[6])
-
-#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
-/** DMA2 registers block numeric address.*/
-#define STM32_DMA2_BASE (AHBPERIPH_BASE + 0x0400)
-/** Pointer to the DMA2 registers block.*/
-#define STM32_DMA2 ((stm32_dma_t *)STM32_DMA2_BASE)
-/** Pointer to the DMA2 channel 1 registers block.*/
-#define STM32_DMA2_CH1 (&STM32_DMA2->channels[0])
-/** Pointer to the DMA2 channel 2 registers block.*/
-#define STM32_DMA2_CH2 (&STM32_DMA2->channels[1])
-/** Pointer to the DMA2 channel 3 registers block.*/
-#define STM32_DMA2_CH3 (&STM32_DMA2->channels[2])
-/** Pointer to the DMA2 channel 4 registers block.*/
-#define STM32_DMA2_CH4 (&STM32_DMA2->channels[3])
-/** Pointer to the DMA2 channel 5 registers block.*/
-#define STM32_DMA2_CH5 (&STM32_DMA2->channels[4])
-#endif
-
-#define STM32_DMA_CHANNEL_1 0 /**< @brief DMA channel 1. */
-#define STM32_DMA_CHANNEL_2 1 /**< @brief DMA channel 2. */
-#define STM32_DMA_CHANNEL_3 2 /**< @brief DMA channel 3. */
-#define STM32_DMA_CHANNEL_4 3 /**< @brief DMA channel 4. */
-#define STM32_DMA_CHANNEL_5 4 /**< @brief DMA channel 5. */
-#define STM32_DMA_CHANNEL_6 5 /**< @brief DMA channel 6. */
-#define STM32_DMA_CHANNEL_7 6 /**< @brief DMA channel 7. */
-
/**
- * @brief Associates a peripheral data register to a DMA channel.
+ * @brief Associates a peripheral data register to a DMA stream.
* @note This function can be invoked in both ISR or thread context.
*
- * @param[in] dmachp dmachp to a stm32_dma_channel_t structure
- * @param[in] cpar value to be written in the CPAR register
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] addr value to be written in the CPAR register
*
* @special
*/
-#define dmaChannelSetPeripheral(dmachp, cpar) { \
- (dmachp)->CPAR = (uint32_t)(cpar); \
+#define dmaStreamSetPeripheral(dmastp, addr) { \
+ (dmastp)->channel->CPAR = (uint32_t)(addr); \
}
/**
- * @brief DMA channel setup by channel pointer.
- * @note This macro does not change the CPAR register because that register
- * value does not change frequently, it usually points to a peripheral
- * data register.
+ * @brief Associates a memory destination to a DMA stream.
* @note This function can be invoked in both ISR or thread context.
*
- * @param[in] dmachp dmachp to a stm32_dma_channel_t structure
- * @param[in] cndtr value to be written in the CNDTR register
- * @param[in] cmar value to be written in the CMAR register
- * @param[in] ccr value to be written in the CCR register
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] addr value to be written in the CMAR register
*
* @special
*/
-#define dmaChannelSetup(dmachp, cndtr, cmar, ccr) { \
- (dmachp)->CNDTR = (uint32_t)(cndtr); \
- (dmachp)->CMAR = (uint32_t)(cmar); \
- (dmachp)->CCR = (uint32_t)(ccr); \
+#define dmaStreamSetMemory0(dmastp, addr) { \
+ (dmastp)->channel->CMAR = (uint32_t)(addr); \
}
/**
- * @brief DMA channel enable by channel pointer.
+ * @brief Sets the number of transfers to be performed.
* @note This function can be invoked in both ISR or thread context.
*
- * @param[in] dmachp dmachp to a stm32_dma_channel_t structure
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] size value to be written in the CNDTR register
*
* @special
*/
-#define dmaChannelEnable(dmachp) { \
- (dmachp)->CCR |= DMA_CCR1_EN; \
+#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 dmachp 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
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
new file mode 100644
index 000000000..2b6851ad6
--- /dev/null
+++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.c
@@ -0,0 +1,540 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file DMAv2/stm32_dma.c
+ * @brief Enhanced DMA helper driver code.
+ *
+ * @addtogroup STM32_DMA
+ * @details DMA sharing helper driver. In the STM32 the DMA streams are a
+ * shared resource, this driver allows to allocate and free DMA
+ * streams at runtime in order to allow all the other device
+ * drivers to coordinate the access to the resource.
+ * @note The DMA ISR handlers are all declared into this module because
+ * sharing, the various device drivers can associate a callback to
+ * IRSs when allocating streams.
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+/* The following macro is only defined if some driver requiring DMA services
+ has been enabled.*/
+#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/**
+ * @brief Mask of the DMA1 streams in @p dma_streams_mask.
+ */
+#define STM32_DMA1_STREAMS_MASK 0x000000FF
+
+/**
+ * @brief Mask of the DMA2 streams in @p dma_streams_mask.
+ */
+#define STM32_DMA2_STREAMS_MASK 0x0000FF00
+
+/**
+ * @brief Post-reset value of the stream CR register.
+ */
+#define STM32_DMA_CR_RESET_VALUE 0x00000000
+
+/**
+ * @brief Post-reset value of the stream FCR register.
+ */
+#define STM32_DMA_FCR_RESET_VALUE 0x00000021
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief DMA streams descriptors.
+ * @details This table keeps the association between an unique stream
+ * identifier and the involved physical registers.
+ * @note Don't use this array directly, use the appropriate wrapper macros
+ * instead: @p STM32_DMA1_STREAM0, @p STM32_DMA1_STREAM1 etc.
+ */
+const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
+ {0, DMA1, DMA1_Stream0, &DMA1->LIFCR, 0},
+ {1, DMA1, DMA1_Stream1, &DMA1->LIFCR, 6},
+ {2, DMA1, DMA1_Stream2, &DMA1->LIFCR, 16},
+ {3, DMA1, DMA1_Stream3, &DMA1->LIFCR, 22},
+ {4, DMA1, DMA1_Stream4, &DMA1->HIFCR, 0},
+ {5, DMA1, DMA1_Stream5, &DMA1->HIFCR, 6},
+ {6, DMA1, DMA1_Stream6, &DMA1->HIFCR, 16},
+ {7, DMA1, DMA1_Stream7, &DMA1->HIFCR, 22},
+ {8, DMA2, DMA2_Stream0, &DMA2->LIFCR, 0},
+ {9, DMA2, DMA2_Stream1, &DMA2->LIFCR, 6},
+ {10, DMA2, DMA2_Stream2, &DMA2->LIFCR, 16},
+ {11, DMA2, DMA2_Stream3, &DMA2->LIFCR, 22},
+ {12, DMA2, DMA2_Stream4, &DMA2->HIFCR, 0},
+ {13, DMA2, DMA2_Stream5, &DMA2->HIFCR, 6},
+ {14, DMA2, DMA2_Stream6, &DMA2->HIFCR, 16},
+ {15, DMA2, DMA2_Stream7, &DMA2->HIFCR, 22},
+};
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/**
+ * @brief DMA ISR redirector type.
+ */
+typedef struct {
+ stm32_dmaisr_t dma_func;
+ void *dma_param;
+} dma_isr_redir_t;
+
+/**
+ * @brief Mask of the allocated streams.
+ */
+static uint32_t dma_streams_mask;
+
+/**
+ * @brief DMA IRQ redirectors.
+ */
+static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS];
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/**
+ * @brief DMA1 stream 0 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Stream0_IRQHandler) {
+ uint32_t flags;
+
+ CH_IRQ_PROLOGUE();
+
+ flags = (DMA1->LISR >> 0) & STM32_DMA_ISR_MASK;
+ DMA1->LIFCR = STM32_DMA_ISR_MASK << 0;
+ if (dma_isr_redir[0].dma_func)
+ dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 stream 1 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Stream1_IRQHandler) {
+ uint32_t flags;
+
+ CH_IRQ_PROLOGUE();
+
+ flags = (DMA1->LISR >> 6) & STM32_DMA_ISR_MASK;
+ DMA1->LIFCR = STM32_DMA_ISR_MASK << 6;
+ if (dma_isr_redir[1].dma_func)
+ dma_isr_redir[1].dma_func(dma_isr_redir[0].dma_param, flags);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 stream 2 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Stream2_IRQHandler) {
+ uint32_t flags;
+
+ CH_IRQ_PROLOGUE();
+
+ flags = (DMA1->LISR >> 16) & STM32_DMA_ISR_MASK;
+ DMA1->LIFCR = STM32_DMA_ISR_MASK << 16;
+ if (dma_isr_redir[2].dma_func)
+ dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 stream 3 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Stream3_IRQHandler) {
+ uint32_t flags;
+
+ CH_IRQ_PROLOGUE();
+
+ flags = (DMA1->LISR >> 22) & STM32_DMA_ISR_MASK;
+ DMA1->LIFCR = STM32_DMA_ISR_MASK << 22;
+ if (dma_isr_redir[3].dma_func)
+ dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 stream 4 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Stream4_IRQHandler) {
+ uint32_t flags;
+
+ CH_IRQ_PROLOGUE();
+
+ flags = (DMA1->HISR >> 0) & STM32_DMA_ISR_MASK;
+ DMA1->HIFCR = STM32_DMA_ISR_MASK << 0;
+ if (dma_isr_redir[4].dma_func)
+ dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 stream 5 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Stream5_IRQHandler) {
+ uint32_t flags;
+
+ CH_IRQ_PROLOGUE();
+
+ flags = (DMA1->HISR >> 6) & STM32_DMA_ISR_MASK;
+ DMA1->HIFCR = STM32_DMA_ISR_MASK << 6;
+ if (dma_isr_redir[5].dma_func)
+ dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 stream 6 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Stream6_IRQHandler) {
+ uint32_t flags;
+
+ CH_IRQ_PROLOGUE();
+
+ flags = (DMA1->HISR >> 16) & STM32_DMA_ISR_MASK;
+ DMA1->HIFCR = STM32_DMA_ISR_MASK << 16;
+ if (dma_isr_redir[6].dma_func)
+ dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 stream 7 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Stream7_IRQHandler) {
+ uint32_t flags;
+
+ CH_IRQ_PROLOGUE();
+
+ flags = (DMA1->HISR >> 22) & STM32_DMA_ISR_MASK;
+ DMA1->HIFCR = STM32_DMA_ISR_MASK << 22;
+ if (dma_isr_redir[7].dma_func)
+ dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 stream 0 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Stream0_IRQHandler) {
+ uint32_t flags;
+
+ CH_IRQ_PROLOGUE();
+
+ flags = (DMA2->LISR >> 0) & STM32_DMA_ISR_MASK;
+ DMA2->LIFCR = STM32_DMA_ISR_MASK << 0;
+ if (dma_isr_redir[8].dma_func)
+ dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 stream 1 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Stream1_IRQHandler) {
+ uint32_t flags;
+
+ CH_IRQ_PROLOGUE();
+
+ flags = (DMA2->LISR >> 6) & STM32_DMA_ISR_MASK;
+ DMA2->LIFCR = STM32_DMA_ISR_MASK << 6;
+ if (dma_isr_redir[9].dma_func)
+ dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 stream 2 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Stream2_IRQHandler) {
+ uint32_t flags;
+
+ CH_IRQ_PROLOGUE();
+
+ flags = (DMA2->LISR >> 16) & STM32_DMA_ISR_MASK;
+ DMA2->LIFCR = STM32_DMA_ISR_MASK << 16;
+ if (dma_isr_redir[10].dma_func)
+ dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 stream 3 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Stream3_IRQHandler) {
+ uint32_t flags;
+
+ CH_IRQ_PROLOGUE();
+
+ flags = (DMA2->LISR >> 22) & STM32_DMA_ISR_MASK;
+ DMA2->LIFCR = STM32_DMA_ISR_MASK << 22;
+ if (dma_isr_redir[11].dma_func)
+ dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 stream 4 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Stream4_IRQHandler) {
+ uint32_t flags;
+
+ CH_IRQ_PROLOGUE();
+
+ flags = (DMA2->HISR >> 0) & STM32_DMA_ISR_MASK;
+ DMA2->HIFCR = STM32_DMA_ISR_MASK << 0;
+ if (dma_isr_redir[12].dma_func)
+ dma_isr_redir[12].dma_func(dma_isr_redir[12].dma_param, flags);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 stream 5 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Stream5_IRQHandler) {
+ uint32_t flags;
+
+ CH_IRQ_PROLOGUE();
+
+ flags = (DMA2->HISR >> 6) & STM32_DMA_ISR_MASK;
+ DMA2->HIFCR = STM32_DMA_ISR_MASK << 6;
+ if (dma_isr_redir[13].dma_func)
+ dma_isr_redir[13].dma_func(dma_isr_redir[13].dma_param, flags);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 stream 6 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Stream6_IRQHandler) {
+ uint32_t flags;
+
+ CH_IRQ_PROLOGUE();
+
+ flags = (DMA2->HISR >> 16) & STM32_DMA_ISR_MASK;
+ DMA2->HIFCR = STM32_DMA_ISR_MASK << 16;
+ if (dma_isr_redir[14].dma_func)
+ dma_isr_redir[14].dma_func(dma_isr_redir[14].dma_param, flags);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 stream 7 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Stream7_IRQHandler) {
+ uint32_t flags;
+
+ CH_IRQ_PROLOGUE();
+
+ flags = (DMA2->HISR >> 22) & STM32_DMA_ISR_MASK;
+ DMA2->HIFCR = STM32_DMA_ISR_MASK << 22;
+ if (dma_isr_redir[15].dma_func)
+ dma_isr_redir[15].dma_func(dma_isr_redir[15].dma_param, flags);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief STM32 DMA helper initialization.
+ *
+ * @init
+ */
+void dmaInit(void) {
+ int i;
+
+ dma_streams_mask = 0;
+ for (i = 0; i < STM32_DMA_STREAMS; i++) {
+ _stm32_dma_streams[i].stream->CR = 0;
+ dma_isr_redir[i].dma_func = NULL;
+ }
+ DMA1->LIFCR = 0xFFFFFFFF;
+ DMA1->HIFCR = 0xFFFFFFFF;
+ DMA2->LIFCR = 0xFFFFFFFF;
+ DMA2->HIFCR = 0xFFFFFFFF;
+}
+
+/**
+ * @brief Allocates a DMA stream.
+ * @details The stream is allocated and, if required, the DMA clock enabled.
+ * The function also enables the IRQ vector associated to the stream
+ * and initializes its priority.
+ * @pre The stream must not be already in use or an error is returned.
+ * @post The stream is allocated and the default ISR handler redirected
+ * to the specified function.
+ * @post The stream ISR vector is enabled and its priority configured.
+ * @post The stream must be freed using @p dmaStreamRelease() before it can
+ * be reused with another peripheral.
+ * @post The stream is in its post-reset state.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] func handling function pointer, can be @p NULL
+ * @param[in] param a parameter to be passed to the handling function
+ * @return The operation status.
+ * @retval FALSE no error, stream taken.
+ * @retval TRUE error, stream already taken.
+ *
+ * @special
+ */
+bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
+ uint32_t priority,
+ stm32_dmaisr_t func,
+ void *param) {
+
+ chDbgCheck(dmastp != NULL, "dmaAllocate");
+
+ /* Checks if the stream is already taken.*/
+ if ((dma_streams_mask & dmastp->mask) != 0)
+ return TRUE;
+
+ /* Marks the stream as allocated.*/
+ dma_isr_redir[dmastp->selfindex].dma_func = func;
+ dma_isr_redir[dmastp->selfindex].dma_param = param;
+ dma_streams_mask |= (1 << dmastp->selfindex);
+
+ /* Enabling DMA clocks required by the current streams set.*/
+ if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) {
+ RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
+ RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA1LPEN;
+ }
+ if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) {
+ RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
+ RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA2LPEN;
+ }
+
+ /* Putting the stream in a safe state.*/
+ dmaStreamDisable(dmastp);
+ dmaStreamClearInterrupt(dmastp);
+ dmastp->channel->CR = STM32_DMA_CR_RESET_VALUE;
+ dmastp->channel->FCR = STM32_DMA_FCR_RESET_VALUE;
+
+ /* Enables the associated IRQ vector if a callback is defined.*/
+ if (func != NULL)
+ NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority));
+
+ return FALSE;
+}
+
+/**
+ * @brief Releases a DMA stream.
+ * @details The stream is freed and, if required, the DMA clock disabled.
+ * Trying to release a unallocated stream is an illegal operation
+ * and is trapped if assertions are enabled.
+ * @pre The stream must have been allocated using @p dmaStreamAllocate().
+ * @post The stream is again available.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ *
+ * @special
+ */
+void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {
+
+ chDbgCheck(dmastp != NULL, "dmaRelease");
+
+ /* Check if the streams is not taken.*/
+ chDbgAssert((dma_streams_mask & dmastp->mask) != 0,
+ "dmaRelease(), #1", "not allocated");
+
+ /* Disables the associated IRQ vector.*/
+ NVICDisableVector(dmastp->vector);
+
+ /* Marks the stream as not allocated.*/
+ dma_streams_mask &= ~(1 << dmastp->selfindex);
+
+ /* Shutting down clocks that are no more required, if any.*/
+ if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) {
+ RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA1EN;
+ RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA1LPEN;
+ }
+ if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) {
+ RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA2EN;
+ RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA2LPEN;
+ }
+}
+
+#endif /* STM32_DMA_REQUIRED */
+
+/** @} */
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..af18497fc
--- /dev/null
+++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.h
@@ -0,0 +1,327 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file DMAv2/stm32_dma.h
+ * @brief Enhanced-DMA helper driver header.
+ * @note This file requires definitions from the ST STM32F2xx header file
+ * stm32f2xx.h.
+ *
+ * @addtogroup STM32_DMA
+ * @{
+ */
+
+#ifndef _STM32_DMA_H_
+#define _STM32_DMA_H_
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Total number of DMA streams.
+ * @note This is the total number of streams among all the DMA units.
+ */
+#define STM32_DMA_STREAMS 16
+
+/**
+ * @brief Mask of the ISR bits passed to the DMA callback functions.
+ */
+#define STM32_DMA_ISR_MASK 0x3D
+
+/**
+ * @name DMA streams identifiers
+ * @{
+ */
+#define STM32_DMA1_STREAM0 (&_stm32_dma_streams[0])
+#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[1])
+#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[2])
+#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[3])
+#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[4])
+#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[5])
+#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[6])
+#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[7])
+#define STM32_DMA2_STREAM0 (&_stm32_dma_streams[8])
+#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[9])
+#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[10])
+#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[11])
+#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[12])
+#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[13])
+#define STM32_DMA2_STREAM6 (&_stm32_dma_streams[14])
+#define STM32_DMA2_STREAM7 (&_stm32_dma_streams[15])
+/** @} */
+
+/**
+ * @name CR register constants common to all DMA types
+ */
+#define STM32_DMA_CR_EN DMA_SxCR_EN
+#define STM32_DMA_CR_TEIE DMA_SxCR_TEIE
+#define STM32_DMA_CR_HTIE DMA_SxCR_HTIE
+#define STM32_DMA_CR_TCIE DMA_SxCR_TCIE
+#define STM32_DMA_CR_DIR_MASK DMA_SxCR_DIR
+#define STM32_DMA_CR_DIR_P2M 0
+#define STM32_DMA_CR_DIR_M2P DMA_SxCR_DIR_0
+#define STM32_DMA_CR_DIR_M2M DMA_SxCR_DIR_1
+#define STM32_DMA_CR_CIRC DMA_SxCR_CIRC
+#define STM32_DMA_CR_PINC DMA_SxCR_PINC
+#define STM32_DMA_CR_MINC DMA_SxCR_MINC
+#define STM32_DMA_CR_PSIZE_MASK DMA_SxCR_PSIZE
+#define STM32_DMA_CR_PSIZE_BYTE 0
+#define STM32_DMA_CR_PSIZE_HWORD DMA_SxCR_PSIZE_0
+#define STM32_DMA_CR_PSIZE_WORD DMA_SxCR_PSIZE_1
+#define STM32_DMA_CR_MSIZE_MASK DMA_SxCR_MSIZE
+#define STM32_DMA_CR_MSIZE_BYTE 0
+#define STM32_DMA_CR_MSIZE_HWORD DMA_SxCR_MSIZE_0
+#define STM32_DMA_CR_MSIZE_WORD DMA_SxCR_MSIZE_1
+#define STM32_DMA_CR_PL_MASK DMA_SxCR_PL
+#define STM32_DMA_CR_PL(n) ((n) << 16)
+/** @} */
+
+/**
+ * @name CR register constants only found in STM32F2xx
+ */
+#define STM32_DMA_CR_DMEIE DMA_SxCR_DMEIE
+#define STM32_DMA_CR_PFCTRL DMA_SxCR_PFCTRL
+#define STM32_DMA_CR_PINCOS DMA_SxCR_PINCOS
+#define STM32_DMA_CR_DBM DMA_SxCR_DBM
+#define STM32_DMA_CR_CT DMA_SxCR_CT
+#define STM32_DMA_CR_PBURST_MASK DMA_SxCR_PBURST
+#define STM32_DMA_CR_PBURST_SINGLE 0
+#define STM32_DMA_CR_PBURST_INCR4 DMA_SxCR_PBURST_0
+#define STM32_DMA_CR_PBURST_INCR8 DMA_SxCR_PBURST_1
+#define STM32_DMA_CR_PBURST_INCR16 (DMA_SxCR_PBURST_0 | DMA_SxCR_PBURST_1)
+#define STM32_DMA_CR_MBURST_MASK DMA_SxCR_MBURST
+#define STM32_DMA_CR_MBURST_SINGLE 0
+#define STM32_DMA_CR_MBURST_INCR4 DMA_SxCR_MBURST_0
+#define STM32_DMA_CR_MBURST_INCR8 DMA_SxCR_MBURST_1
+#define STM32_DMA_CR_MBURST_INCR16 (DMA_SxCR_MBURST_0 | DMA_SxCR_MBURST_1)
+#define STM32_DMA_CR_CHSEL_MASK DMA_SxCR_CHSEL
+#define STM32_DMA_CR_CHSEL(n) ((n) << 25)
+/** @} */
+
+/**
+ * @name FCR register constants only found in STM32F2xx
+ */
+#define STM32_DMA_FCR_FEIE DMA_SxFCR_FEIE
+#define STM32_DMA_FCR_FS_MASK DMA_SxFCR_FS
+#define STM32_DMA_FCR_DMDIS DMA_SxFCR_DMDIS
+#define STM32_DMA_FCR_FTH_MASK DMA_SxFCR_FTH
+#define STM32_DMA_FCR_FTH_1Q 0
+#define STM32_DMA_FCR_FTH_HALF DMA_SxFCR_FTH_0
+#define STM32_DMA_FCR_FTH_3Q DMA_SxFCR_FTH_1
+#define STM32_DMA_FCR_FTH_FULL (DMA_SxFCR_FTH_0 | DMA_SxFCR_FTH_1)
+/** @} */
+
+/**
+ * @name Status flags passed to the ISR callbacks
+ */
+#define STM32_DMA_ISR_FEIF DMA_LISR_FEIF0
+#define STM32_DMA_ISR_DMEIF DMA_LISR_DMEIF0
+#define STM32_DMA_ISR_TEIF DMA_LISR_TEIF0
+#define STM32_DMA_ISR_HTIF DMA_LISR_HTIF0
+#define STM32_DMA_ISR_TCIF DMA_LISR_TCIF0
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief STM32 DMA stream descriptor structure.
+ */
+typedef struct {
+ DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */
+ volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */
+ uint8_t ishift; /**< @brief Bits offset in xIFCR
+ register. */
+ uint8_t selfindex; /**< @brief Index to self in array. */
+ uint8_t vector; /**< @brief Associated IRQ vector. */
+} stm32_dma_stream_t;
+
+/**
+ * @brief STM32 DMA ISR function type.
+ *
+ * @param[in] p parameter for the registered function
+ * @param[in] flags pre-shifted content of the xISR register, the bits
+ * are aligned to bit zero
+ */
+typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Associates a peripheral data register to a DMA stream.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] addr value to be written in the PAR register
+ *
+ * @special
+ */
+#define dmaStreamSetPeripheral(dmastp, addr) { \
+ (dmastp)->stream->PAR = (uint32_t)(addr); \
+}
+
+/**
+ * @brief Associates a memory destination to a DMA stream.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] addr value to be written in the M0AR register
+ *
+ * @special
+ */
+#define dmaStreamSetMemory0(dmastp, addr) { \
+ (dmastp)->stream->M0AR = (uint32_t)(addr); \
+}
+
+/**
+ * @brief Associates an alternate memory destination to a DMA stream.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] addr value to be written in the M1AR register
+ *
+ * @special
+ */
+#define dmaStreamSetMemory1(dmastp, addr) { \
+ (dmastp)->stream->M1AR = (uint32_t)(addr); \
+}
+
+/**
+ * @brief Sets the number of transfers to be performed.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] size value to be written in the CNDTR register
+ *
+ * @special
+ */
+#define dmaStreamSetTransactionSize(dmastp, size) { \
+ (dmastp)->stream->NDTR = (uint32_t)(size); \
+}
+
+/**
+ * @brief Returns the number of transfers to be performed.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @return The number of transfers to be performed.
+ *
+ * @special
+ */
+#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->stream->NDTR))
+
+/**
+ * @brief Programs the stream mode settings.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] mode value to be written in the CR register
+ *
+ * @special
+ */
+#define dmaStreamSetMode(dmastp, mode) { \
+ (dmastp)->stream->CR = (uint32_t)(mode); \
+}
+
+/**
+ * @brief Programs the stream FIFO settings.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] mode value to be written in the FCR register
+ *
+ * @special
+ */
+#define dmaStreamSetFIFO(dmastp, mode) { \
+ (dmastp)->stream->FCR = (uint32_t)(mode); \
+}
+
+/**
+ * @brief DMA stream enable.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @param[in] dmachp pointer to a stm32_dma_stream_t structure
+ *
+ * @special
+ */
+#define dmaStreamEnable(dmachp) { \
+ (dmastp)->stream->CR |= STM32_DMA_CR_EN; \
+}
+
+/**
+ * @brief DMA stream disable.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ *
+ * @special
+ */
+#define dmaStreamDisable(dmastp) { \
+ (dmastp)->stream->CR &= ~STM32_DMA_CR_EN; \
+}
+
+/**
+ * @brief DMA stream interrupt sources clear.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ *
+ * @special
+ */
+#define dmaStreamClearInterrupt(dmastp) { \
+ *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \
+}
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS];
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void dmaInit(void);
+ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
+ uint32_t priority,
+ stm32_dmaisr_t func,
+ void *param);
+ void dmaStreamRelease(const stm32_dma_stream_t *dmastp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STM32_DMA_H_ */
+
+/** @} */
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
* @{
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/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/os/hal/src/adc.c b/os/hal/src/adc.c
index 4843ca90b..c375818a6 100644
--- a/os/hal/src/adc.c
+++ b/os/hal/src/adc.c
@@ -32,6 +32,10 @@
#if HAL_USE_ADC || defined(__DOXYGEN__)
/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
@@ -176,13 +180,14 @@ void adcStartConversionI(ADCDriver *adcp,
adcsample_t *samples,
size_t depth) {
+ chDbgCheckClassI();
chDbgCheck((adcp != NULL) && (grpp != NULL) && (samples != NULL) &&
((depth == 1) || ((depth & 1) == 0)),
"adcStartConversionI");
-
chDbgAssert((adcp->state == ADC_READY) ||
(adcp->state == ADC_COMPLETE),
"adcStartConversionI(), #1", "not ready");
+
adcp->samples = samples;
adcp->depth = depth;
adcp->grpp = grpp;
@@ -229,12 +234,13 @@ void adcStopConversion(ADCDriver *adcp) {
*/
void adcStopConversionI(ADCDriver *adcp) {
+ chDbgCheckClassI();
chDbgCheck(adcp != NULL, "adcStopConversionI");
-
chDbgAssert((adcp->state == ADC_READY) ||
(adcp->state == ADC_ACTIVE) ||
(adcp->state == ADC_COMPLETE),
"adcStopConversionI(), #1", "invalid state");
+
if (adcp->state != ADC_READY) {
adc_lld_stop_conversion(adcp);
adcp->grpp = NULL;
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
@@ -32,6 +32,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 e90a8911a..c677f5284 100644
--- a/os/hal/src/gpt.c
+++ b/os/hal/src/gpt.c
@@ -32,6 +32,10 @@
#if HAL_USE_GPT || defined(__DOXYGEN__)
/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
@@ -137,8 +141,11 @@ void gptStartContinuous(GPTDriver *gptp, gptcnt_t interval) {
*/
void gptStartContinuousI(GPTDriver *gptp, gptcnt_t interval) {
+ chDbgCheckClassI();
+ chDbgCheck(gptp != NULL, "gptStartContinuousI");
chDbgAssert(gptp->state == GPT_READY,
"gptStartContinuousI(), #1", "invalid state");
+
gptp->state = GPT_CONTINUOUS;
gpt_lld_start_timer(gptp, interval);
}
@@ -168,8 +175,11 @@ void gptStartOneShot(GPTDriver *gptp, gptcnt_t interval) {
*/
void gptStartOneShotI(GPTDriver *gptp, gptcnt_t interval) {
+ chDbgCheckClassI();
+ chDbgCheck(gptp != NULL, "gptStartOneShotI");
chDbgAssert(gptp->state == GPT_READY,
"gptStartOneShotI(), #1", "invalid state");
+
gptp->state = GPT_ONESHOT;
gpt_lld_start_timer(gptp, interval);
}
@@ -197,9 +207,12 @@ void gptStopTimer(GPTDriver *gptp) {
*/
void gptStopTimerI(GPTDriver *gptp) {
+ chDbgCheckClassI();
+ chDbgCheck(gptp != NULL, "gptStopTimerI");
chDbgAssert((gptp->state == GPT_READY) || (gptp->state == GPT_CONTINUOUS) ||
(gptp->state == GPT_ONESHOT),
"gptStopTimerI(), #1", "invalid state");
+
gptp->state = GPT_READY;
gpt_lld_stop_timer(gptp);
}
@@ -220,6 +233,7 @@ void gptPolledDelay(GPTDriver *gptp, gptcnt_t interval) {
chDbgAssert(gptp->state == GPT_READY,
"gptPolledDelay(), #1", "invalid state");
+
gptp->state = GPT_ONESHOT;
gpt_lld_polled_delay(gptp, interval);
}
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
@@ -30,6 +30,10 @@
#include "hal.h"
/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c
index 8508bc682..9ce2cc76f 100644
--- a/os/hal/src/i2c.c
+++ b/os/hal/src/i2c.c
@@ -32,6 +32,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 3be67448e..c73ea5106 100644
--- a/os/hal/src/icu.c
+++ b/os/hal/src/icu.c
@@ -32,6 +32,10 @@
#if HAL_USE_ICU || defined(__DOXYGEN__)
/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
@@ -121,6 +125,8 @@ void icuStop(ICUDriver *icup) {
*/
void icuEnable(ICUDriver *icup) {
+ chDbgCheck(icup != NULL, "icuEnable");
+
chSysLock();
chDbgAssert(icup->state == ICU_READY, "icuEnable(), #1", "invalid state");
icu_lld_enable(icup);
@@ -137,6 +143,8 @@ void icuEnable(ICUDriver *icup) {
*/
void icuDisable(ICUDriver *icup) {
+ chDbgCheck(icup != NULL, "icuDisable");
+
chSysLock();
chDbgAssert((icup->state == ICU_READY) || (icup->state == ICU_WAITING) ||
(icup->state == ICU_ACTIVE) || (icup->state == ICU_IDLE),
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
@@ -34,6 +34,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
@@ -32,6 +32,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
@@ -32,6 +32,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
@@ -32,6 +32,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 59d7db005..758edf8d8 100644
--- a/os/hal/src/sdc.c
+++ b/os/hal/src/sdc.c
@@ -32,6 +32,10 @@
#if HAL_USE_SDC || defined(__DOXYGEN__)
/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
@@ -54,7 +58,7 @@
*
* @notapi
*/
-bool_t sdc_wait_for_transfer_state(SDCDriver *sdcp) {
+bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp) {
uint32_t resp[1];
while (TRUE) {
@@ -314,7 +318,7 @@ bool_t sdcDisconnect(SDCDriver *sdcp) {
chSysUnlock();
/* Waits for eventual pending operations completion.*/
- if (sdc_wait_for_transfer_state(sdcp))
+ if (_sdc_wait_for_transfer_state(sdcp))
return TRUE;
/* Card clock stopped.*/
diff --git a/os/hal/src/serial.c b/os/hal/src/serial.c
index 414689aac..d962bcdcd 100644
--- a/os/hal/src/serial.c
+++ b/os/hal/src/serial.c
@@ -32,6 +32,10 @@
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
@@ -207,6 +211,7 @@ void sdStop(SerialDriver *sdp) {
*/
void sdIncomingDataI(SerialDriver *sdp, uint8_t b) {
+ chDbgCheckClassI();
chDbgCheck(sdp != NULL, "sdIncomingDataI");
if (chIQIsEmptyI(&sdp->iqueue))
@@ -233,6 +238,7 @@ void sdIncomingDataI(SerialDriver *sdp, uint8_t b) {
msg_t sdRequestDataI(SerialDriver *sdp) {
msg_t b;
+ chDbgCheckClassI();
chDbgCheck(sdp != NULL, "sdRequestDataI");
b = chOQGetI(&sdp->oqueue);
diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c
index 3f53d7df0..16822502a 100644
--- a/os/hal/src/serial_usb.c
+++ b/os/hal/src/serial_usb.c
@@ -34,6 +34,10 @@
#if HAL_USE_SERIAL_USB || defined(__DOXYGEN__)
/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
@@ -120,7 +124,7 @@ static void inotify(GenericQueue *qp) {
emptied, then a whole packet is loaded in the queue.*/
if (chIQIsEmptyI(&sdup->iqueue)) {
- n = usbReadPacketI(sdup->config->usbp, DATA_AVAILABLE_EP,
+ n = usbReadPacketI(sdup->config->usbp, USB_CDC_DATA_AVAILABLE_EP,
sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE);
if (n != USB_ENDPOINT_BUSY) {
chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE);
@@ -142,7 +146,7 @@ static void onotify(GenericQueue *qp) {
/* If there is any data in the output queue then it is sent within a
single packet and the queue is emptied.*/
n = chOQGetFullI(&sdup->oqueue);
- w = usbWritePacketI(sdup->config->usbp, DATA_REQUEST_EP,
+ w = usbWritePacketI(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP,
sdup->oqueue.q_buffer, n);
if (w != USB_ENDPOINT_BUSY) {
chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY);
@@ -207,10 +211,10 @@ void sduStart(SerialUSBDriver *sdup, const SerialUSBConfig *config) {
"sduStart(), #1",
"invalid state");
sdup->config = config;
- usbStart(config->usbp, &config->usb_config);
config->usbp->param = sdup;
sdup->state = SDU_READY;
chSysUnlock();
+ usbStart(config->usbp, &config->usb_config);
}
/**
@@ -230,9 +234,9 @@ void sduStop(SerialUSBDriver *sdup) {
chDbgAssert((sdup->state == SDU_STOP) || (sdup->state == SDU_READY),
"sduStop(), #1",
"invalid state");
- usbStop(sdup->config->usbp);
sdup->state = SDU_STOP;
chSysUnlock();
+ usbStop(sdup->config->usbp);
}
/**
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
@@ -32,6 +32,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 05fdbb168..ed28ecb3b 100644
--- a/os/hal/src/uart.c
+++ b/os/hal/src/uart.c
@@ -32,6 +32,10 @@
#if HAL_USE_UART || defined(__DOXYGEN__)
/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
@@ -161,12 +165,13 @@ void uartStartSend(UARTDriver *uartp, size_t n, const void *txbuf) {
*/
void uartStartSendI(UARTDriver *uartp, size_t n, const void *txbuf) {
+ chDbgCheckClassI();
chDbgCheck((uartp != NULL) && (n > 0) && (txbuf != NULL),
"uartStartSendI");
-
chDbgAssert((uartp->state == UART_READY) &&
(uartp->txstate != UART_TX_ACTIVE),
"uartStartSendI(), #1", "not active");
+
uart_lld_start_send(uartp, n, txbuf);
uartp->txstate = UART_TX_ACTIVE;
}
@@ -216,8 +221,8 @@ size_t uartStopSend(UARTDriver *uartp) {
*/
size_t uartStopSendI(UARTDriver *uartp) {
+ chDbgCheckClassI();
chDbgCheck(uartp != NULL, "uartStopSendI");
-
chDbgAssert(uartp->state == UART_READY, "uartStopSendI(), #1", "not active");
if (uartp->txstate == UART_TX_ACTIVE) {
@@ -267,9 +272,9 @@ void uartStartReceive(UARTDriver *uartp, size_t n, void *rxbuf) {
*/
void uartStartReceiveI(UARTDriver *uartp, size_t n, void *rxbuf) {
+ chDbgCheckClassI();
chDbgCheck((uartp != NULL) && (n > 0) && (rxbuf != NULL),
"uartStartReceiveI");
-
chDbgAssert((uartp->state == UART_READY) && (uartp->rxstate == UART_RX_IDLE),
"uartStartReceiveI(), #1", "not active");
@@ -322,8 +327,9 @@ size_t uartStopReceive(UARTDriver *uartp) {
* @iclass
*/
size_t uartStopReceiveI(UARTDriver *uartp) {
- chDbgCheck(uartp != NULL, "uartStopReceiveI");
+ chDbgCheckClassI();
+ chDbgCheck(uartp != NULL, "uartStopReceiveI");
chDbgAssert(uartp->state == UART_READY,
"uartStopReceiveI(), #1", "not active");
diff --git a/os/hal/src/usb.c b/os/hal/src/usb.c
index 484590f3b..44a772ab1 100644
--- a/os/hal/src/usb.c
+++ b/os/hal/src/usb.c
@@ -35,6 +35,10 @@
#if HAL_USE_USB || defined(__DOXYGEN__)
/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
@@ -301,6 +305,8 @@ void usbStop(USBDriver *usbp) {
void usbInitEndpointI(USBDriver *usbp, usbep_t ep,
const USBEndpointConfig *epcp) {
+ chDbgCheckClassI();
+ chDbgCheck((usbp != NULL) && (epcp != NULL), "usbInitEndpointI");
chDbgAssert(usbp->state == USB_ACTIVE,
"usbEnableEndpointI(), #1", "invalid state");
chDbgAssert(usbp->epc[ep] != NULL,
@@ -331,6 +337,8 @@ void usbInitEndpointI(USBDriver *usbp, usbep_t ep,
void usbDisableEndpointsI(USBDriver *usbp) {
unsigned i;
+ chDbgCheckClassI();
+ chDbgCheck(usbp != NULL, "usbDisableEndpointsI");
chDbgAssert(usbp->state == USB_SELECTED,
"usbDisableEndpointsI(), #1", "invalid state");
@@ -364,6 +372,9 @@ void usbDisableEndpointsI(USBDriver *usbp) {
size_t usbReadPacketI(USBDriver *usbp, usbep_t ep,
uint8_t *buf, size_t n) {
+ chDbgCheckClassI();
+ chDbgCheck((usbp != NULL) && (buf != NULL), "usbReadPacketI");
+
if (usbGetReceiveStatusI(usbp, ep))
return USB_ENDPOINT_BUSY;
@@ -391,6 +402,9 @@ size_t usbReadPacketI(USBDriver *usbp, usbep_t ep,
size_t usbWritePacketI(USBDriver *usbp, usbep_t ep,
const uint8_t *buf, size_t n) {
+ chDbgCheckClassI();
+ chDbgCheck((usbp != NULL) && (buf != NULL), "usbWritePacketI");
+
if (usbGetTransmitStatusI(usbp, ep))
return USB_ENDPOINT_BUSY;
@@ -419,6 +433,9 @@ size_t usbWritePacketI(USBDriver *usbp, usbep_t ep,
bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep,
uint8_t *buf, size_t n) {
+ chDbgCheckClassI();
+ chDbgCheck((usbp != NULL) && (buf != NULL), "usbStartReceiveI");
+
if (usbGetReceiveStatusI(usbp, ep))
return TRUE;
@@ -447,6 +464,9 @@ bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep,
bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep,
const uint8_t *buf, size_t n) {
+ chDbgCheckClassI();
+ chDbgCheck((usbp != NULL) && (buf != NULL), "usbStartTransmitI");
+
if (usbGetTransmitStatusI(usbp, ep))
return TRUE;
@@ -468,6 +488,9 @@ bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep,
*/
bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep) {
+ chDbgCheckClassI();
+ chDbgCheck(usbp != NULL, "usbStallReceiveI");
+
if (usbGetReceiveStatusI(usbp, ep))
return TRUE;
@@ -488,6 +511,9 @@ bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep) {
*/
bool_t usbStallTransmitI(USBDriver *usbp, usbep_t ep) {
+ chDbgCheckClassI();
+ chDbgCheck(usbp != NULL, "usbStallTransmitI");
+
if (usbGetTransmitStatusI(usbp, ep))
return TRUE;
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
@@ -32,6 +32,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
@@ -32,6 +32,10 @@
#if HAL_USE_CAN || defined(__DOXYGEN__)
/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
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/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
@@ -32,6 +32,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
@@ -30,6 +30,10 @@
#include "hal.h"
/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
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
@@ -35,6 +35,10 @@
#include "mcuconf.h"
/**
+ * @name Drivers enable switches
+ * @{
+ */
+/**
* @brief Enables the PAL subsystem.
*/
#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
@@ -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/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
@@ -32,6 +32,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
@@ -32,6 +32,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
@@ -32,6 +32,10 @@
#if HAL_USE_MAC || defined(__DOXYGEN__)
/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
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/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
@@ -32,6 +32,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
@@ -32,6 +32,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
@@ -32,6 +32,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
@@ -32,6 +32,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
@@ -32,6 +32,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
@@ -32,6 +32,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
@@ -32,6 +32,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
@@ -32,6 +32,10 @@
#if HAL_USE_USB || defined(__DOXYGEN__)
/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/