From f23670b728189b4549091d355e38218b31c0a0ad Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 21 Aug 2011 13:19:48 +0000 Subject: Added I-class function checks to HAL APIs. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3244 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/src/adc.c | 6 ++++-- os/hal/src/gpt.c | 10 ++++++++++ os/hal/src/icu.c | 4 ++++ os/hal/src/serial.c | 2 ++ os/hal/src/uart.c | 10 ++++++---- os/hal/src/usb.c | 22 ++++++++++++++++++++++ 6 files changed, 48 insertions(+), 6 deletions(-) (limited to 'os/hal') diff --git a/os/hal/src/adc.c b/os/hal/src/adc.c index 4843ca90b..f2bf4eadd 100644 --- a/os/hal/src/adc.c +++ b/os/hal/src/adc.c @@ -176,13 +176,14 @@ void adcStartConversionI(ADCDriver *adcp, adcsample_t *samples, size_t depth) { + chDbgCheckClassI(); chDbgCheck((adcp != NULL) && (grpp != NULL) && (samples != NULL) && ((depth == 1) || ((depth & 1) == 0)), "adcStartConversionI"); - chDbgAssert((adcp->state == ADC_READY) || (adcp->state == ADC_COMPLETE), "adcStartConversionI(), #1", "not ready"); + adcp->samples = samples; adcp->depth = depth; adcp->grpp = grpp; @@ -229,12 +230,13 @@ void adcStopConversion(ADCDriver *adcp) { */ void adcStopConversionI(ADCDriver *adcp) { + chDbgCheckClassI(); chDbgCheck(adcp != NULL, "adcStopConversionI"); - chDbgAssert((adcp->state == ADC_READY) || (adcp->state == ADC_ACTIVE) || (adcp->state == ADC_COMPLETE), "adcStopConversionI(), #1", "invalid state"); + if (adcp->state != ADC_READY) { adc_lld_stop_conversion(adcp); adcp->grpp = NULL; diff --git a/os/hal/src/gpt.c b/os/hal/src/gpt.c index e90a8911a..5f424453d 100644 --- a/os/hal/src/gpt.c +++ b/os/hal/src/gpt.c @@ -137,8 +137,11 @@ void gptStartContinuous(GPTDriver *gptp, gptcnt_t interval) { */ void gptStartContinuousI(GPTDriver *gptp, gptcnt_t interval) { + chDbgCheckClassI(); + chDbgCheck(gptp != NULL, "gptStartContinuousI"); chDbgAssert(gptp->state == GPT_READY, "gptStartContinuousI(), #1", "invalid state"); + gptp->state = GPT_CONTINUOUS; gpt_lld_start_timer(gptp, interval); } @@ -168,8 +171,11 @@ void gptStartOneShot(GPTDriver *gptp, gptcnt_t interval) { */ void gptStartOneShotI(GPTDriver *gptp, gptcnt_t interval) { + chDbgCheckClassI(); + chDbgCheck(gptp != NULL, "gptStartOneShotI"); chDbgAssert(gptp->state == GPT_READY, "gptStartOneShotI(), #1", "invalid state"); + gptp->state = GPT_ONESHOT; gpt_lld_start_timer(gptp, interval); } @@ -197,9 +203,12 @@ void gptStopTimer(GPTDriver *gptp) { */ void gptStopTimerI(GPTDriver *gptp) { + chDbgCheckClassI(); + chDbgCheck(gptp != NULL, "gptStopTimerI"); chDbgAssert((gptp->state == GPT_READY) || (gptp->state == GPT_CONTINUOUS) || (gptp->state == GPT_ONESHOT), "gptStopTimerI(), #1", "invalid state"); + gptp->state = GPT_READY; gpt_lld_stop_timer(gptp); } @@ -220,6 +229,7 @@ void gptPolledDelay(GPTDriver *gptp, gptcnt_t interval) { chDbgAssert(gptp->state == GPT_READY, "gptPolledDelay(), #1", "invalid state"); + gptp->state = GPT_ONESHOT; gpt_lld_polled_delay(gptp, interval); } diff --git a/os/hal/src/icu.c b/os/hal/src/icu.c index 3be67448e..79d38798e 100644 --- a/os/hal/src/icu.c +++ b/os/hal/src/icu.c @@ -121,6 +121,8 @@ void icuStop(ICUDriver *icup) { */ void icuEnable(ICUDriver *icup) { + chDbgCheck(icup != NULL, "icuEnable"); + chSysLock(); chDbgAssert(icup->state == ICU_READY, "icuEnable(), #1", "invalid state"); icu_lld_enable(icup); @@ -137,6 +139,8 @@ void icuEnable(ICUDriver *icup) { */ void icuDisable(ICUDriver *icup) { + chDbgCheck(icup != NULL, "icuDisable"); + chSysLock(); chDbgAssert((icup->state == ICU_READY) || (icup->state == ICU_WAITING) || (icup->state == ICU_ACTIVE) || (icup->state == ICU_IDLE), diff --git a/os/hal/src/serial.c b/os/hal/src/serial.c index 414689aac..03b74be54 100644 --- a/os/hal/src/serial.c +++ b/os/hal/src/serial.c @@ -207,6 +207,7 @@ void sdStop(SerialDriver *sdp) { */ void sdIncomingDataI(SerialDriver *sdp, uint8_t b) { + chDbgCheckClassI(); chDbgCheck(sdp != NULL, "sdIncomingDataI"); if (chIQIsEmptyI(&sdp->iqueue)) @@ -233,6 +234,7 @@ void sdIncomingDataI(SerialDriver *sdp, uint8_t b) { msg_t sdRequestDataI(SerialDriver *sdp) { msg_t b; + chDbgCheckClassI(); chDbgCheck(sdp != NULL, "sdRequestDataI"); b = chOQGetI(&sdp->oqueue); diff --git a/os/hal/src/uart.c b/os/hal/src/uart.c index 05fdbb168..372a3ad02 100644 --- a/os/hal/src/uart.c +++ b/os/hal/src/uart.c @@ -161,12 +161,13 @@ void uartStartSend(UARTDriver *uartp, size_t n, const void *txbuf) { */ void uartStartSendI(UARTDriver *uartp, size_t n, const void *txbuf) { + chDbgCheckClassI(); chDbgCheck((uartp != NULL) && (n > 0) && (txbuf != NULL), "uartStartSendI"); - chDbgAssert((uartp->state == UART_READY) && (uartp->txstate != UART_TX_ACTIVE), "uartStartSendI(), #1", "not active"); + uart_lld_start_send(uartp, n, txbuf); uartp->txstate = UART_TX_ACTIVE; } @@ -216,8 +217,8 @@ size_t uartStopSend(UARTDriver *uartp) { */ size_t uartStopSendI(UARTDriver *uartp) { + chDbgCheckClassI(); chDbgCheck(uartp != NULL, "uartStopSendI"); - chDbgAssert(uartp->state == UART_READY, "uartStopSendI(), #1", "not active"); if (uartp->txstate == UART_TX_ACTIVE) { @@ -267,9 +268,9 @@ void uartStartReceive(UARTDriver *uartp, size_t n, void *rxbuf) { */ void uartStartReceiveI(UARTDriver *uartp, size_t n, void *rxbuf) { + chDbgCheckClassI(); chDbgCheck((uartp != NULL) && (n > 0) && (rxbuf != NULL), "uartStartReceiveI"); - chDbgAssert((uartp->state == UART_READY) && (uartp->rxstate == UART_RX_IDLE), "uartStartReceiveI(), #1", "not active"); @@ -322,8 +323,9 @@ size_t uartStopReceive(UARTDriver *uartp) { * @iclass */ size_t uartStopReceiveI(UARTDriver *uartp) { - chDbgCheck(uartp != NULL, "uartStopReceiveI"); + chDbgCheckClassI(); + chDbgCheck(uartp != NULL, "uartStopReceiveI"); chDbgAssert(uartp->state == UART_READY, "uartStopReceiveI(), #1", "not active"); diff --git a/os/hal/src/usb.c b/os/hal/src/usb.c index 484590f3b..8493b6f41 100644 --- a/os/hal/src/usb.c +++ b/os/hal/src/usb.c @@ -301,6 +301,8 @@ void usbStop(USBDriver *usbp) { void usbInitEndpointI(USBDriver *usbp, usbep_t ep, const USBEndpointConfig *epcp) { + chDbgCheckClassI(); + chDbgCheck((usbp != NULL) && (epcp != NULL), "usbInitEndpointI"); chDbgAssert(usbp->state == USB_ACTIVE, "usbEnableEndpointI(), #1", "invalid state"); chDbgAssert(usbp->epc[ep] != NULL, @@ -331,6 +333,8 @@ void usbInitEndpointI(USBDriver *usbp, usbep_t ep, void usbDisableEndpointsI(USBDriver *usbp) { unsigned i; + chDbgCheckClassI(); + chDbgCheck(usbp != NULL, "usbDisableEndpointsI"); chDbgAssert(usbp->state == USB_SELECTED, "usbDisableEndpointsI(), #1", "invalid state"); @@ -364,6 +368,9 @@ void usbDisableEndpointsI(USBDriver *usbp) { size_t usbReadPacketI(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) { + chDbgCheckClassI(); + chDbgCheck((usbp != NULL) && (buf != NULL), "usbReadPacketI"); + if (usbGetReceiveStatusI(usbp, ep)) return USB_ENDPOINT_BUSY; @@ -391,6 +398,9 @@ size_t usbReadPacketI(USBDriver *usbp, usbep_t ep, size_t usbWritePacketI(USBDriver *usbp, usbep_t ep, const uint8_t *buf, size_t n) { + chDbgCheckClassI(); + chDbgCheck((usbp != NULL) && (buf != NULL), "usbWritePacketI"); + if (usbGetTransmitStatusI(usbp, ep)) return USB_ENDPOINT_BUSY; @@ -419,6 +429,9 @@ size_t usbWritePacketI(USBDriver *usbp, usbep_t ep, bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) { + chDbgCheckClassI(); + chDbgCheck((usbp != NULL) && (buf != NULL), "usbStartReceiveI"); + if (usbGetReceiveStatusI(usbp, ep)) return TRUE; @@ -447,6 +460,9 @@ bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep, bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep, const uint8_t *buf, size_t n) { + chDbgCheckClassI(); + chDbgCheck((usbp != NULL) && (buf != NULL), "usbStartTransmitI"); + if (usbGetTransmitStatusI(usbp, ep)) return TRUE; @@ -468,6 +484,9 @@ bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep, */ bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep) { + chDbgCheckClassI(); + chDbgCheck(usbp != NULL, "usbStallReceiveI"); + if (usbGetReceiveStatusI(usbp, ep)) return TRUE; @@ -488,6 +507,9 @@ bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep) { */ bool_t usbStallTransmitI(USBDriver *usbp, usbep_t ep) { + chDbgCheckClassI(); + chDbgCheck(usbp != NULL, "usbStallTransmitI"); + if (usbGetTransmitStatusI(usbp, ep)) return TRUE; -- cgit v1.2.3 From 718dc5084f7719f91eaacfc99e8c7de654eb2ad8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 23 Aug 2011 13:36:25 +0000 Subject: HAL documentation improvements. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3252 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/adc.h | 10 +++++ os/hal/include/can.h | 18 +++++++++ os/hal/include/icu.h | 10 +++++ os/hal/include/mac.h | 5 +++ os/hal/include/mii.h | 6 --- os/hal/include/mmc_spi.h | 10 +++++ os/hal/include/pal.h | 15 ++++++++ os/hal/include/pwm.h | 15 ++++++++ os/hal/include/sdc.h | 20 ++++++++++ os/hal/include/serial.h | 32 +++++++++++----- os/hal/include/serial_usb.h | 7 ++++ os/hal/include/spi.h | 15 ++++++++ os/hal/include/uart.h | 23 ++++++------ os/hal/include/usb.h | 21 +++++++++++ os/hal/include/usb_cdc.h | 5 +++ os/hal/src/sdc.c | 4 +- os/hal/templates/can_lld.h | 13 ------- os/hal/templates/halconf.h | 90 +++++++++++++++++++++++++++++++++++++++------ os/hal/templates/mac_lld.h | 21 ----------- 19 files changed, 265 insertions(+), 75 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/adc.h b/os/hal/include/adc.h index a236a040a..53c7c199a 100644 --- a/os/hal/include/adc.h +++ b/os/hal/include/adc.h @@ -39,6 +39,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name ADC configuration options + * @{ + */ /** * @brief Enables synchronous APIs. * @note Disabling this option saves both code and data space. @@ -54,6 +58,7 @@ #if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) #define ADC_USE_MUTUAL_EXCLUSION TRUE #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ @@ -84,6 +89,10 @@ typedef enum { /* Driver macros. */ /*===========================================================================*/ +/** + * @name Low Level driver helper macros + * @{ + */ #if ADC_USE_WAIT || defined(__DOXYGEN__) /** * @brief Resumes a thread waiting for a conversion completion. @@ -211,6 +220,7 @@ typedef enum { _adc_wakeup_isr(adcp); \ } \ } +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/can.h b/os/hal/include/can.h index 538284b3b..44d2cfb19 100644 --- a/os/hal/include/can.h +++ b/os/hal/include/can.h @@ -35,6 +35,10 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @name CAN status flags + * @{ + */ /** * @brief Errors rate warning. */ @@ -55,17 +59,26 @@ * @brief Overflow in receive queue. */ #define CAN_OVERFLOW_ERROR 16 +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name CAN configuration options + * @{ + */ /** * @brief Sleep mode related APIs inclusion switch. + * @details This option can only be enabled if the CAN implementation supports + * the sleep mode, see the macro @p CAN_SUPPORTS_SLEEP exported by + * the underlying implementation. */ #if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) #define CAN_USE_SLEEP_MODE TRUE #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ @@ -96,6 +109,10 @@ typedef enum { /* Driver macros. */ /*===========================================================================*/ +/** + * @name Macro Functions + * @{ + */ /** * @brief Adds some flags to the CAN status mask. * @@ -105,6 +122,7 @@ typedef enum { * @iclass */ #define canAddFlagsI(canp, mask) ((canp)->status |= (mask)) +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/icu.h b/os/hal/include/icu.h index 38fed2788..65d7794e5 100644 --- a/os/hal/include/icu.h +++ b/os/hal/include/icu.h @@ -77,6 +77,10 @@ typedef void (*icucallback_t)(ICUDriver *icup); /* Driver macros. */ /*===========================================================================*/ +/** + * @name Macro Functions + * @{ + */ /** * @brief Enables the input capture. * @@ -118,7 +122,12 @@ typedef void (*icucallback_t)(ICUDriver *icup); * @iclass */ #define icuGetPeriodI(icup) icu_lld_get_period(icup) +/** @} */ +/** + * @name Low Level driver helper macros + * @{ + */ /** * @brief Common ISR code, ICU width event. * @@ -144,6 +153,7 @@ typedef void (*icucallback_t)(ICUDriver *icup); if (previous_state != ICU_WAITING) \ (icup)->config->period_cb(icup); \ } +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/mac.h b/os/hal/include/mac.h index ad3c7b4dc..37d6bbe9b 100644 --- a/os/hal/include/mac.h +++ b/os/hal/include/mac.h @@ -56,6 +56,10 @@ /* Driver macros. */ /*===========================================================================*/ +/** + * @name Macro Functions + * @{ + */ /** * @brief Returns the received frames event source. * @@ -98,6 +102,7 @@ */ #define macReadReceiveDescriptor(rdp, buf, size) \ mac_lld_read_receive_descriptor(rdp, buf, size) +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/mii.h b/os/hal/include/mii.h index 7199ee86d..89ba69810 100644 --- a/os/hal/include/mii.h +++ b/os/hal/include/mii.h @@ -18,12 +18,6 @@ along with this program. If not, see . */ -/* - * Parts of this file have been borrowed from the Linux include file - * linux/mii.h: - * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com) - */ - /*-* * @file mii.h * @brief MII Driver macros and structures. diff --git a/os/hal/include/mmc_spi.h b/os/hal/include/mmc_spi.h index 6940ca479..f51bd6765 100644 --- a/os/hal/include/mmc_spi.h +++ b/os/hal/include/mmc_spi.h @@ -53,6 +53,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name MMC_SPI configuration options + * @{ + */ /** * @brief Block size for MMC transfers. */ @@ -86,6 +90,7 @@ #if !defined(MMC_POLLING_DELAY) || defined(__DOXYGEN__) #define MMC_POLLING_DELAY 10 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ @@ -181,6 +186,10 @@ typedef struct { /* Driver macros. */ /*===========================================================================*/ +/** + * @name Macro Functions + * @{ + */ /** * @brief Returns the driver state. * @@ -202,6 +211,7 @@ typedef struct { * @api */ #define mmcIsWriteProtected(mmcp) ((mmcp)->is_protected()) +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/pal.h b/os/hal/include/pal.h index 2e5b78c03..d844ca8b3 100644 --- a/os/hal/include/pal.h +++ b/os/hal/include/pal.h @@ -35,6 +35,10 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @name Pads mode constants + * @{ + */ /** * @brief After reset state. * @details The state itself is not specified and is architecture dependent, @@ -81,7 +85,12 @@ * @brief Open-drain output pad. */ #define PAL_MODE_OUTPUT_OPENDRAIN 7 +/** @} */ +/** + * @name Logic level constants + * @{ + */ /** * @brief Logical low state. */ @@ -91,6 +100,7 @@ * @brief Logical high state. */ #define PAL_HIGH 1 +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ @@ -177,6 +187,10 @@ typedef struct { #define IOBUS_DECL(name, port, width, offset) \ IOBus name = _IOBUS_DATA(name, port, width, offset) +/** + * @name Macro Functions + * @{ + */ /** * @brief PAL subsystem initialization. * @note This function is implicitly invoked by @p halInit(), there is @@ -499,6 +513,7 @@ typedef struct { #else #define palSetPadMode(port, pad, mode) pal_lld_setpadmode(port, pad, mode) #endif +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/pwm.h b/os/hal/include/pwm.h index 2ffd3599c..960ac2a69 100644 --- a/os/hal/include/pwm.h +++ b/os/hal/include/pwm.h @@ -35,6 +35,10 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @name PWM output mode macros + * @{ + */ /** * @brief Standard output modes mask. */ @@ -54,6 +58,7 @@ * @brief Inverse PWM logic, active is logic level zero. */ #define PWM_OUTPUT_ACTIVE_LOW 0x02 +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ @@ -94,6 +99,10 @@ typedef void (*pwmcallback_t)(PWMDriver *pwmp); /* Driver macros. */ /*===========================================================================*/ +/** + * @name PWM duty cycle conversion + * @{ + */ /** * @brief Converts from fraction to pulse width. * @note Be careful with rounding errors, this is integer math not magic. @@ -143,7 +152,12 @@ typedef void (*pwmcallback_t)(PWMDriver *pwmp); */ #define PWM_PERCENTAGE_TO_WIDTH(pwmp, percentage) \ PWM_FRACTION_TO_WIDTH(pwmp, 10000, percentage) +/** @} */ +/** + * @name Macro Functions + * @{ + */ /** * @brief Changes the period the PWM peripheral. * @details This function changes the period of a PWM unit that has already @@ -197,6 +211,7 @@ typedef void (*pwmcallback_t)(PWMDriver *pwmp); */ #define pwmDisableChannelI(pwmp, channel) \ pwm_lld_disable_channel(pwmp, channel) +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h index afc3a6aba..466c48fa6 100644 --- a/os/hal/include/sdc.h +++ b/os/hal/include/sdc.h @@ -42,11 +42,16 @@ */ #define SDC_CMD8_PATTERN 0x000001AA +/** + * @name SD cart types + * @{ + */ #define SDC_MODE_CARDTYPE_MASK 0xF /**< @brief Card type mask. */ #define SDC_MODE_CARDTYPE_SDV11 0 /**< @brief Card is SD V1.1.*/ #define SDC_MODE_CARDTYPE_SDV20 1 /**< @brief Card is SD V2.0.*/ #define SDC_MODE_CARDTYPE_MMC 2 /**< @brief Card is MMC. */ #define SDC_MODE_HIGH_CAPACITY 0x10 /**< @brief High cap.card. */ +/** @} */ /** * @brief Mask of error bits in R1 responses. @@ -87,6 +92,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name SDC configuration options + * @{ + */ /** * @brief Number of initialization attempts before rejecting the card. * @note Attempts are performed at 10mS intevals. @@ -113,6 +122,7 @@ #if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) #define SDC_NICE_WAITING TRUE #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ @@ -142,6 +152,10 @@ typedef enum { /* Driver macros. */ /*===========================================================================*/ +/** + * @name R1 response utilities + * @{ + */ /** * @brief Evaluates to @p TRUE if the R1 response contains error flags. * @@ -162,7 +176,12 @@ typedef enum { * @param[in] r1 the r1 response */ #define SDC_R1_IS_CARD_LOCKED(r1) (((r1) >> 21) & 1) +/** @} */ +/** + * @name Macro Functions + * @{ + */ /** * @brief Returns the driver state. * @@ -204,6 +223,7 @@ typedef enum { * @api */ #define sdcIsWriteProtected(sdcp) (sdc_lld_is_write_protected(sdcp)) +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/serial.h b/os/hal/include/serial.h index a8c3c1aca..8c610e29e 100644 --- a/os/hal/include/serial.h +++ b/os/hal/include/serial.h @@ -35,21 +35,25 @@ /* Driver constants. */ /*===========================================================================*/ -/** @brief Parity error happened.*/ -#define SD_PARITY_ERROR 32 -/** @brief Framing error happened.*/ -#define SD_FRAMING_ERROR 64 -/** @brief Overflow happened.*/ -#define SD_OVERRUN_ERROR 128 -/** @brief Noise on the line.*/ -#define SD_NOISE_ERROR 256 -/** @brief Break detected.*/ -#define SD_BREAK_DETECTED 512 +/** + * @name Serial status flags + * @{ + */ +#define SD_PARITY_ERROR 32 /**< @brief Parity error happened. */ +#define SD_FRAMING_ERROR 64 /**< @brief Framing error happened. */ +#define SD_OVERRUN_ERROR 128 /**< @brief Overflow happened. */ +#define SD_NOISE_ERROR 256 /**< @brief Noise on the line. */ +#define SD_BREAK_DETECTED 512 /**< @brief Break detected. */ +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name Serial configuration options + * @{ + */ /** * @brief Default bit rate. * @details Configuration parameter, this is the baud rate selected for the @@ -69,6 +73,7 @@ #if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) #define SERIAL_BUFFERS_SIZE 16 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ @@ -105,6 +110,8 @@ typedef struct SerialDriver SerialDriver; _base_asynchronous_channel_methods /** + * @extends BaseAsynchronousChannelVMT + * * @brief @p SerialDriver virtual methods table. */ struct SerialDriverVMT { @@ -128,6 +135,10 @@ struct SerialDriver { /* Driver macros. */ /*===========================================================================*/ +/** + * @name Macro Functions + * @{ + */ /** * @brief Direct output check on a @p SerialDriver. * @note This function bypasses the indirect access to the channel and @@ -281,6 +292,7 @@ struct SerialDriver { */ #define sdAsynchronousRead(sdp, b, n) \ chIQReadTimeout(&(sdp)->iqueue, b, n, TIME_IMMEDIATE) +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/serial_usb.h b/os/hal/include/serial_usb.h index 8e518238d..09be9b708 100644 --- a/os/hal/include/serial_usb.h +++ b/os/hal/include/serial_usb.h @@ -39,6 +39,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name SERIAL_USB configuration options + * @{ + */ /** * @brief Serial over USB buffers size. * @details Configuration parameter, the buffer size must be a multiple of @@ -49,6 +53,7 @@ #if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) #define SERIAL_USB_BUFFERS_SIZE 64 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ @@ -119,6 +124,8 @@ typedef struct { _base_asynchronous_channel_methods /** + * @extends BaseAsynchronousChannelVMT + * * @brief @p SerialDriver virtual methods table. */ struct SerialUSBDriverVMT { diff --git a/os/hal/include/spi.h b/os/hal/include/spi.h index 104dd9d3e..a07d55cf7 100644 --- a/os/hal/include/spi.h +++ b/os/hal/include/spi.h @@ -39,6 +39,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name SPI configuration options + * @{ + */ /** * @brief Enables synchronous APIs. * @note Disabling this option saves both code and data space. @@ -54,6 +58,7 @@ #if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) #define SPI_USE_MUTUAL_EXCLUSION TRUE #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ @@ -84,6 +89,10 @@ typedef enum { /* Driver macros. */ /*===========================================================================*/ +/** + * @name Macro Functions + * @{ + */ /** * @brief Asserts the slave select signal and prepares for transfers. * @@ -201,7 +210,12 @@ typedef enum { * @return The received data frame from the SPI bus. */ #define spiPolledExchange(spip, frame) spi_lld_polled_exchange(spip, frame) +/** @} */ +/** + * @name Low Level driver helper macros + * @{ + */ #if SPI_USE_WAIT || defined(__DOXYGEN__) /** * @brief Waits for operation completion. @@ -268,6 +282,7 @@ typedef enum { (spip)->state = SPI_READY; \ _spi_wakeup_isr(spip); \ } +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/uart.h b/os/hal/include/uart.h index 148aa6877..6d3d12d5f 100644 --- a/os/hal/include/uart.h +++ b/os/hal/include/uart.h @@ -35,18 +35,17 @@ /* Driver constants. */ /*===========================================================================*/ -/** @brief No pending conditions.*/ -#define UART_NO_ERROR 0 -/** @brief Parity error happened.*/ -#define UART_PARITY_ERROR 4 -/** @brief Framing error happened.*/ -#define UART_FRAMING_ERROR 8 -/** @brief Overflow happened.*/ -#define UART_OVERRUN_ERROR 16 -/** @brief Noise on the line.*/ -#define UART_NOISE_ERROR 32 -/** @brief Break detected.*/ -#define UART_BREAK_DETECTED 64 +/** + * @name UART status flags + * @{ + */ +#define UART_NO_ERROR 0 /**< @brief No pending conditions. */ +#define UART_PARITY_ERROR 4 /**< @brief Parity error happened. */ +#define UART_FRAMING_ERROR 8 /**< @brief Framing error happened. */ +#define UART_OVERRUN_ERROR 16 /**< @brief Overflow happened. */ +#define UART_NOISE_ERROR 32 /**< @brief Noise on the line. */ +#define UART_BREAK_DETECTED 64 /**< @brief Break detected. */ +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ diff --git a/os/hal/include/usb.h b/os/hal/include/usb.h index c4cf68fe2..884b11e8d 100644 --- a/os/hal/include/usb.h +++ b/os/hal/include/usb.h @@ -77,6 +77,10 @@ #define USB_EARLY_SET_ADDRESS 0 #define USB_LATE_SET_ADDRESS 1 +/** + * @name Helper macros for USB descriptors + * @{ + */ /** * @brief Helper macro for index values into descriptor strings. */ @@ -166,12 +170,17 @@ USB_DESC_BYTE(bmAttributes), \ USB_DESC_WORD(wMaxPacketSize), \ USB_DESC_BYTE(bInterval) +/** @} */ /** * @brief Returned by some functions to report a busy endpoint. */ #define USB_ENDPOINT_BUSY ((size_t)0xFFFFFFFF) +/** + * @name Endpoint types and settings + * @{ + */ #define USB_EP_MODE_TYPE 0x0003 /**< Endpoint type mask. */ #define USB_EP_MODE_TYPE_CTRL 0x0000 /**< Control endpoint. */ #define USB_EP_MODE_TYPE_ISOC 0x0001 /**< Isochronous endpoint. */ @@ -179,6 +188,7 @@ #define USB_EP_MODE_TYPE_INTR 0x0003 /**< Interrupt endpoint. */ #define USB_EP_MODE_TRANSACTION 0x0000 /**< Transaction mode. */ #define USB_EP_MODE_PACKET 0x0010 /**< Packet mode enabled. */ +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ @@ -311,6 +321,11 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp, /*===========================================================================*/ /* Driver macros. */ /*===========================================================================*/ + +/** + * @name Macro Functions + * @{ + */ /** * @brief Returns the current frame number. * @@ -411,7 +426,12 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp, * @special */ #define usbReadSetup(usbp, ep, buf) usb_lld_read_setup(usbp, ep, buf) +/** @} */ +/** + * @name Low Level driver helper macros + * @{ + */ /** * @brief Common ISR code, usb event callback. * @@ -474,6 +494,7 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp, (usbp)->receiving &= ~(1 << (ep)); \ (usbp)->epc[ep]->out_cb(usbp, ep); \ } +/** @} */ /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/include/usb_cdc.h b/os/hal/include/usb_cdc.h index a388f9f70..cd9d78f10 100644 --- a/os/hal/include/usb_cdc.h +++ b/os/hal/include/usb_cdc.h @@ -67,6 +67,10 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name USB_CDC configuration options + * @{ + */ /** * @brief Endpoint number for bulk IN. */ @@ -87,6 +91,7 @@ #if !defined(DATA_AVAILABLE_EP) || defined(__DOXYGEN__) #define DATA_AVAILABLE_EP 3 #endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c index 59d7db005..6bdaa2b5a 100644 --- a/os/hal/src/sdc.c +++ b/os/hal/src/sdc.c @@ -54,7 +54,7 @@ * * @notapi */ -bool_t sdc_wait_for_transfer_state(SDCDriver *sdcp) { +bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp) { uint32_t resp[1]; while (TRUE) { @@ -314,7 +314,7 @@ bool_t sdcDisconnect(SDCDriver *sdcp) { chSysUnlock(); /* Waits for eventual pending operations completion.*/ - if (sdc_wait_for_transfer_state(sdcp)) + if (_sdc_wait_for_transfer_state(sdcp)) return TRUE; /* Card clock stopped.*/ diff --git a/os/hal/templates/can_lld.h b/os/hal/templates/can_lld.h index d07bd78cc..d1f8d6044 100644 --- a/os/hal/templates/can_lld.h +++ b/os/hal/templates/can_lld.h @@ -45,19 +45,6 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ -/** - * @brief Sleep mode related APIs inclusion switch. - * @note This switch is enforced to @p FALSE if the driver implementation - * does not support the sleep mode. - */ -#if CAN_SUPPORTS_SLEEP || defined(__DOXYGEN__) -#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) -#define CAN_USE_SLEEP_MODE TRUE -#endif -#else /* !CAN_SUPPORTS_SLEEP */ -#define CAN_USE_SLEEP_MODE FALSE -#endif /* !CAN_SUPPORTS_SLEEP */ - /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ diff --git a/os/hal/templates/halconf.h b/os/hal/templates/halconf.h index da86f61ed..0e616d3d5 100644 --- a/os/hal/templates/halconf.h +++ b/os/hal/templates/halconf.h @@ -34,6 +34,10 @@ #include "mcuconf.h" +/** + * @name Drivers enable switches + * @{ + */ /** * @brief Enables the PAL subsystem. */ @@ -138,9 +142,13 @@ #if !defined(HAL_USE_USB) || defined(__DOXYGEN__) #define HAL_USE_USB TRUE #endif +/** @} */ /*===========================================================================*/ -/* ADC driver related settings. */ +/** + * @name ADC driver related setting + * @{ + */ /*===========================================================================*/ /** @@ -158,9 +166,13 @@ #if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) #define ADC_USE_MUTUAL_EXCLUSION TRUE #endif +/** @} */ /*===========================================================================*/ -/* CAN driver related settings. */ +/** + * @name CAN driver related setting + * @{ + */ /*===========================================================================*/ /** @@ -169,9 +181,13 @@ #if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) #define CAN_USE_SLEEP_MODE TRUE #endif +/** @} */ /*===========================================================================*/ -/* I2C driver related settings. */ +/** + * @name I2C driver related setting + * @{ + */ /*===========================================================================*/ /** @@ -180,13 +196,21 @@ #if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) #define I2C_USE_MUTUAL_EXCLUSION TRUE #endif +/** @} */ /*===========================================================================*/ -/* MAC driver related settings. */ +/** + * @name MAC driver related setting + * @{ + */ /*===========================================================================*/ +/** @} */ /*===========================================================================*/ -/* MMC_SPI driver related settings. */ +/** + * @name MMC_SPI driver related setting + * @{ + */ /*===========================================================================*/ /** @@ -233,17 +257,29 @@ #if !defined(MMC_USE_SPI_POLLING) || defined(__DOXYGEN__) #define MMC_USE_SPI_POLLING TRUE #endif +/** @} */ /*===========================================================================*/ -/* PAL driver related settings. */ +/** + * @name PAL driver related setting + * @{ + */ /*===========================================================================*/ +/** @} */ /*===========================================================================*/ -/* PWM driver related settings. */ +/** + * @name PWM driver related setting + * @{ + */ /*===========================================================================*/ +/** @} */ /*===========================================================================*/ -/* SDC driver related settings. */ +/** + * @name SDC driver related setting + * @{ + */ /*===========================================================================*/ /** * @brief Number of initialization attempts before rejecting the card. @@ -271,9 +307,13 @@ #if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) #define SDC_NICE_WAITING TRUE #endif +/** @} */ /*===========================================================================*/ -/* SERIAL driver related settings. */ +/** + * @name SERIAL driver related setting + * @{ + */ /*===========================================================================*/ /** @@ -295,9 +335,32 @@ #if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) #define SERIAL_BUFFERS_SIZE 16 #endif +/** @} */ + + +/*===========================================================================*/ +/** + * @name SERIAL_USB driver related setting + * @{ + */ +/*===========================================================================*/ +/** + * @brief Serial over USB buffers size. + * @details Configuration parameter, the buffer size must be a multiple of + * the USB data endpoint maximum packet size. + * @note The default is 64 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_USB_BUFFERS_SIZE 64 +#endif +/** @} */ /*===========================================================================*/ -/* SPI driver related settings. */ +/** + * @name SPI driver related setting + * @{ + */ /*===========================================================================*/ /** @@ -315,10 +378,15 @@ #if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) #define SPI_USE_MUTUAL_EXCLUSION TRUE #endif +/** @} */ /*===========================================================================*/ -/* UART driver related settings. */ +/** + * @name UART driver related setting + * @{ + */ /*===========================================================================*/ +/** @} */ #endif /* _HALCONF_H_ */ diff --git a/os/hal/templates/mac_lld.h b/os/hal/templates/mac_lld.h index e8abe2941..e103128a9 100644 --- a/os/hal/templates/mac_lld.h +++ b/os/hal/templates/mac_lld.h @@ -39,27 +39,6 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ -/** - * @brief Number of available transmit buffers. - */ -#if !defined(MAC_TRANSMIT_BUFFERS) || defined(__DOXYGEN__) -#define MAC_TRANSMIT_BUFFERS 2 -#endif - -/** - * @brief Number of available receive buffers. - */ -#if !defined(MAC_RECEIVE_BUFFERS) || defined(__DOXYGEN__) -#define MAC_RECEIVE_BUFFERS 2 -#endif - -/** - * @brief Maximum supported frame size. - */ -#if !defined(MAC_BUFFERS_SIZE) || defined(__DOXYGEN__) -#define MAC_BUFFERS_SIZE 1518 -#endif - /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ -- cgit v1.2.3 From 0aa2dd05114a68ac0e0a23fe8227215a13e2c77b Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 25 Aug 2011 15:14:09 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3253 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/sdc_lld.h | 2 +- os/hal/platforms/STM32/DMAv1/stm32_dma.c | 5 - os/hal/platforms/STM32/DMAv1/stm32_dma.h | 11 +- os/hal/platforms/STM32/DMAv2/stm32_dma.c | 487 +++++++++++++++++++++++++++++++ os/hal/platforms/STM32/DMAv2/stm32_dma.h | 235 +++++++++++++++ os/hal/platforms/STM32/GPIOv1/pal_lld.c | 4 +- os/hal/platforms/STM32/GPIOv1/pal_lld.h | 4 +- 7 files changed, 732 insertions(+), 16 deletions(-) create mode 100644 os/hal/platforms/STM32/DMAv2/stm32_dma.c create mode 100644 os/hal/platforms/STM32/DMAv2/stm32_dma.h (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/DMAv1/sdc_lld.h b/os/hal/platforms/STM32/DMAv1/sdc_lld.h index 5466eacad..eea76dadd 100644 --- a/os/hal/platforms/STM32/DMAv1/sdc_lld.h +++ b/os/hal/platforms/STM32/DMAv1/sdc_lld.h @@ -152,7 +152,7 @@ struct SDCDriver { uint32_t rca; /* End of the mandatory fields.*/ /** - * @brief Tthread waiting for I/O completion IRQ. + * @brief Thread waiting for I/O completion IRQ. */ Thread *thread; }; diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.c b/os/hal/platforms/STM32/DMAv1/stm32_dma.c index 2232df448..4ea8e99ee 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.c @@ -366,17 +366,12 @@ void dmaInit(void) { * @param[in] channel requested channel id * @param[in] func handling function pointer, can be @p NULL * @param[in] param a parameter to be passed to the handling function - * @return The operation status. - * @retval FALSE operation successfully allocated. - * @retval TRUE the channel was already in use. * * @special */ void dmaAllocate(uint32_t dma, uint32_t channel, stm32_dmaisr_t func, void *param) { - chDbgCheck(func != NULL, "dmaAllocate"); - #if STM32_HAS_DMA2 switch (dma) { case STM32_DMA1_ID: diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.h b/os/hal/platforms/STM32/DMAv1/stm32_dma.h index 66a2f8c69..7ef5ad8b9 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.h @@ -22,7 +22,7 @@ * @file stm32_dma.h * @brief STM32 DMA helper driver header. * @note This file requires definitions from the ST STM32 header file - * stm3232f10x.h. + * stm32f10x.h. * * @addtogroup STM32_DMA * @{ @@ -154,7 +154,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * data register. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmachp dmachp to a stm32_dma_channel_t structure + * @param[in] dmachp pointer to a stm32_dma_channel_t structure * @param[in] cndtr value to be written in the CNDTR register * @param[in] cmar value to be written in the CMAR register * @param[in] ccr value to be written in the CCR register @@ -171,7 +171,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * @brief DMA channel enable by channel pointer. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmachp dmachp to a stm32_dma_channel_t structure + * @param[in] dmachp pointer to a stm32_dma_channel_t structure * * @special */ @@ -179,12 +179,11 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); (dmachp)->CCR |= DMA_CCR1_EN; \ } - /** * @brief DMA channel disable by channel pointer. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmachp dmachp to a stm32_dma_channel_t structure + * @param[in] dmachp pointer to a stm32_dma_channel_t structure * * @special */ @@ -256,7 +255,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * * @special */ -#define dmaClearChannel(dmap, ch){ \ +#define dmaClearChannel(dmap, ch) { \ (dmap)->IFCR = 1 << ((ch) * 4); \ } diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.c b/os/hal/platforms/STM32/DMAv2/stm32_dma.c new file mode 100644 index 000000000..d64cfc5f9 --- /dev/null +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.c @@ -0,0 +1,487 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file DMAv2/stm32_dma.c + * @brief STM32F2xx Enhanced DMA helper driver code. + * + * @addtogroup STM32_DMA + * @details DMA sharing helper driver. In the STM32 the DMA streams are a + * shared resource, this driver allows to allocate and free DMA + * streams at runtime in order to allow all the other device + * drivers to coordinate the access to the resource. + * @note The DMA ISR handlers are all declared into this module because + * sharing, the various device drivers can associate a callback to + * IRSs when allocating streams. + * @{ + */ + +#include "ch.h" +#include "hal.h" + +/* The following macro is only defined if some driver requiring DMA services + has been enabled.*/ +#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief DMA streams descriptors. + * @details This table keeps the association between an unique stream + * identifier and the involved physical registers. + * @note Don't use this array directly, use the appropriate wrapper macros + * instead: @p STM32_DMA1_STREAM0, @p STM32_DMA1_STREAM1 etc. + */ +const stm32_dma_stream_t _stm32_dma_streams[16] = { + {0, DMA1, DMA1_Stream0, &DMA1->LISR, &DMA1->LIFCR, 0}, + {1, DMA1, DMA1_Stream1, &DMA1->LISR, &DMA1->LIFCR, 6}, + {2, DMA1, DMA1_Stream2, &DMA1->LISR, &DMA1->LIFCR, 16}, + {3, DMA1, DMA1_Stream3, &DMA1->LISR, &DMA1->LIFCR, 22}, + {4, DMA1, DMA1_Stream4, &DMA1->HISR, &DMA1->HIFCR, 0}, + {5, DMA1, DMA1_Stream5, &DMA1->HISR, &DMA1->HIFCR, 6}, + {6, DMA1, DMA1_Stream6, &DMA1->HISR, &DMA1->HIFCR, 16}, + {7, DMA1, DMA1_Stream7, &DMA1->HISR, &DMA1->HIFCR, 22}, + {8, DMA2, DMA2_Stream0, &DMA2->LISR, &DMA2->LIFCR, 0}, + {9, DMA2, DMA2_Stream1, &DMA2->LISR, &DMA2->LIFCR, 6}, + {10, DMA2, DMA2_Stream2, &DMA2->LISR, &DMA2->LIFCR, 16}, + {11, DMA2, DMA2_Stream3, &DMA2->LISR, &DMA2->LIFCR, 22}, + {12, DMA2, DMA2_Stream4, &DMA2->HISR, &DMA2->HIFCR, 0}, + {13, DMA2, DMA2_Stream5, &DMA2->HISR, &DMA2->HIFCR, 6}, + {14, DMA2, DMA2_Stream6, &DMA2->HISR, &DMA2->HIFCR, 16}, + {15, DMA2, DMA2_Stream7, &DMA2->HISR, &DMA2->HIFCR, 22}, +}; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/** + * @brief DMA ISR redirector type. + */ +typedef struct { + stm32_dmaisr_t dma_func; + void *dma_param; +} dma_isr_redir_t; + +/** + * @brief Mask of the allocated streams. + */ +static uint32_t dma_streams_mask; + +/** + * @brief DMA IRQ redirectors. + */ +static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS]; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/** + * @brief DMA1 stream 0 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream0_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->LISR >> 0) & STM32_DMA_ISR_MASK; + DMA1->LIFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[0].dma_func) + dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 1 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream1_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->LISR >> 6) & STM32_DMA_ISR_MASK; + DMA1->LIFCR = STM32_DMA_ISR_MASK << 6; + if (dma_isr_redir[1].dma_func) + dma_isr_redir[1].dma_func(dma_isr_redir[0].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 2 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream2_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->LISR >> 16) & STM32_DMA_ISR_MASK; + DMA1->LIFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[2].dma_func) + dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 3 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream3_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->LISR >> 22) & STM32_DMA_ISR_MASK; + DMA1->LIFCR = STM32_DMA_ISR_MASK << 22; + if (dma_isr_redir[3].dma_func) + dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 4 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream4_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->HISR >> 0) & STM32_DMA_ISR_MASK; + DMA1->HIFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[4].dma_func) + dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 5 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->HISR >> 6) & STM32_DMA_ISR_MASK; + DMA1->HIFCR = STM32_DMA_ISR_MASK << 6; + if (dma_isr_redir[5].dma_func) + dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 6 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream6_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->HISR >> 16) & STM32_DMA_ISR_MASK; + DMA1->HIFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[6].dma_func) + dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 7 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream7_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->HISR >> 22) & STM32_DMA_ISR_MASK; + DMA1->HIFCR = STM32_DMA_ISR_MASK << 22; + if (dma_isr_redir[7].dma_func) + dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 0 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream0_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->LISR >> 0) & STM32_DMA_ISR_MASK; + DMA2->LIFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[8].dma_func) + dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 1 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream1_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->LISR >> 6) & STM32_DMA_ISR_MASK; + DMA2->LIFCR = STM32_DMA_ISR_MASK << 6; + if (dma_isr_redir[9].dma_func) + dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 2 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream2_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->LISR >> 16) & STM32_DMA_ISR_MASK; + DMA2->LIFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[10].dma_func) + dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 3 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream3_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->LISR >> 22) & STM32_DMA_ISR_MASK; + DMA2->LIFCR = STM32_DMA_ISR_MASK << 22; + if (dma_isr_redir[11].dma_func) + dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 4 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream4_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->HISR >> 0) & STM32_DMA_ISR_MASK; + DMA2->HIFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[12].dma_func) + dma_isr_redir[12].dma_func(dma_isr_redir[12].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 5 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->HISR >> 6) & STM32_DMA_ISR_MASK; + DMA2->HIFCR = STM32_DMA_ISR_MASK << 6; + if (dma_isr_redir[13].dma_func) + dma_isr_redir[13].dma_func(dma_isr_redir[13].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 6 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream6_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->HISR >> 16) & STM32_DMA_ISR_MASK; + DMA2->HIFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[14].dma_func) + dma_isr_redir[14].dma_func(dma_isr_redir[14].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 7 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream7_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->HISR >> 22) & STM32_DMA_ISR_MASK; + DMA2->HIFCR = STM32_DMA_ISR_MASK << 22; + if (dma_isr_redir[15].dma_func) + dma_isr_redir[15].dma_func(dma_isr_redir[15].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief STM32 DMA helper initialization. + * + * @init + */ +void dmaInit(void) { + stm32_dma_stream_t *stp; + + dma_streams_mask = 0; + for (i = 0 - 1; i < STM32_DMA_STREAMS; i--) { + _stm32_dma_streams[i]->stream->CR = 0; + dma_isr_redir[i].dma_func = NULL; + } + DMA1->LIFCR = 0xFFFFFFFF; + DMA1->HIFCR = 0xFFFFFFFF; + DMA2->LIFCR = 0xFFFFFFFF; + DMA2->HIFCR = 0xFFFFFFFF; +} + +/** + * @brief Allocates a DMA stream. + * @details The stream is allocated and, if required, the DMA clock enabled. + * Trying to allocate a stream already allocated is an illegal + * operation and is trapped if assertions are enabled. + * @pre The stream must not be already in use. + * @post The stream is allocated and the default ISR handler redirected + * to the specified function. + * @post The stream must be freed using @p dmaRelease() before it can + * be reused with another peripheral. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] func handling function pointer, can be @p NULL + * @param[in] param a parameter to be passed to the handling function + * + * @special + */ +void dmaAllocate(stm32_dma_stream_t *dmastp, + stm32_dmaisr_t func, void *param) { + + chDbgCheck(dmastp != NULL, "dmaAllocate"); + + /* Checks if the stream is already taken.*/ + chDbgAssert((dma_streams_mask & dmastp->mask) == 0, + "dmaAllocate(), #1", "already allocated"); + + /* Marks the stream as allocated.*/ + dma_isr_redir[dmastp->selfindex].dma_func = func; + dma_isr_redir[dmastp->selfindex].dma_param = param; + dma_streams_mask |= (1 << dmastp->selfindex); + + /* Enabling DMA clocks required by the current streams set.*/ + if ((dma_streams_mask & 0x000000FF) != 0) + RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; + if ((dma_streams_mask & 0x0000FF00) != 0) + RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; + + /* Making sure there are no spurious interrupts flags pending.*/ + dmaStreamClearInterrupt(); +} + +/** + * @brief Releases a DMA stream. + * @details The stream is freed and, if required, the DMA clock disabled. + * Trying to release a unallocated stream is an illegal operation + * and is trapped if assertions are enabled. + * @pre The stream must have been allocated using @p dmaRequest(). + * @post The stream is again available. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +void dmaRelease(stm32_dma_stream_t *dmastp) { + + /* Check if the streams is not taken.*/ + chDbgAssert((dma_streams_mask & dmastp->mask) != 0, + "dmaRelease(), #1", "not allocated"); + + /* Marks the stream as not allocated.*/ + dma_streams_mask &= ~(1 << dmastp->selfindex); + + /* Shutting down clocks that are no more required, if any.*/ + if ((dma_streams_mask & 0x000000FF) == 0) + RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA1EN; + if ((dma_streams_mask & 0x0000FF00) == 0) + RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA2EN; +} + +#endif /* STM32_DMA_REQUIRED */ + +/** @} */ diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.h b/os/hal/platforms/STM32/DMAv2/stm32_dma.h new file mode 100644 index 000000000..805fd7c4b --- /dev/null +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.h @@ -0,0 +1,235 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file DMAv2/stm32_dma.h + * @brief STM32F2xx Enhanced DMA helper driver header. + * @note This file requires definitions from the ST STM32F2xx header file + * stm32f2xx.h. + * + * @addtogroup STM32_DMA + * @{ + */ + +#ifndef _STM32_DMA_H_ +#define _STM32_DMA_H_ + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Total number of DMA streams. + * @note This is the total number of streams among all the DMA units. + */ +#define STM32_DMA_STREAMS 16 + +/** + * @brief Mask of the ISR bits passed to the DMA callback functions. + */ +#define STM32_DMA_ISR_MASK 0x3D + +/** + * @name DMA streams identifiers + * @{ + */ +#define STM32_DMA1_STREAM0 (&_stm32_dma_streams[0]) +#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[1]) +#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[2]) +#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[3]) +#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[4]) +#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[5]) +#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[6]) +#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[7]) +#define STM32_DMA2_STREAM0 (&_stm32_dma_streams[8]) +#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[9]) +#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[10]) +#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[11]) +#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[12]) +#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[13]) +#define STM32_DMA2_STREAM6 (&_stm32_dma_streams[14]) +#define STM32_DMA2_STREAM7 (&_stm32_dma_streams[15]) +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief STM32 DMA stream descriptor structure. + */ +typedef struct { + uint32_t selfindex; /**< @brief Index to self in array. */ + DMA_TypeDef *dma; /**< @brief Associated DMA unit. */ + DMA_Stream_TypeDef *stream; /**< @brief Associated DMA stream. */ + volatile uint32_t *isr; /**< @brief Associated xISR reg. */ + volatile uint32_t *ifcr; /**< @brief Associated xIFCR reg. */ + uint32_t ishift; /**< @brief Bits offset in xISR and + xIFCR registers. */ +} stm32_dma_stream_t; + +/** + * @brief STM32 DMA ISR function type. + * + * @param[in] p parameter for the registered function + * @param[in] flags pre-shifted content of the xISR register, the bits + * are aligned to bit zero + */ +typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Associates a peripheral data register to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the PAR register + * + * @special + */ +#define dmaStreamSetPeripheral(dmastp, addr) { \ + (dmastp)->stream->PAR = (uint32_t)(addr); \ +} + +/** + * @brief Associates a memory destination to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the M0AR register + * + * @special + */ +#define dmaStreamSetMemory0(dmastp, addr) { \ + (dmastp)->stream->M0AR = (uint32_t)(addr); \ +} + +/** + * @brief Associates an alternate memory destination to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the M1AR register + * + * @special + */ +#define dmaStreamSetMemory1(dmastp, addr) { \ + (dmastp)->stream->M1AR = (uint32_t)(addr); \ +} + +/** + * @brief Associates an alternate memory destination to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] size value to be written in the NDTR register + * + * @special + */ +#define dmaStreamSetTransactionSize(dmastp, size) { \ + (dmastp)->stream->NDTR = (uint32_t)(size); \ +} + +/** + * @brief Programs the stream mode settings. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] mode1 value to be written in the FCR register + * @param[in] mode2 value to be written in the CR register + * + * @special + */ +#define dmaStreamSetMode(dmastp, mode1, mode2) { \ + (dmastp)->stream->FCR = (uint32_t)(mode1); \ + (dmastp)->stream->CR = (uint32_t)(mode2); \ +} + +/** + * @brief DMA stream enable. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmachp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamEnable(dmachp) { \ + (dmastp)->stream->CR |= DMA_SxCR_EN; \ +} + +/** + * @brief DMA stream disable. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamDisable(dmastp) { \ + (dmastp)->stream->CR &= ~DMA_SxCR_EN; \ +} + +/** + * @brief DMA stream interrupt sources clear. + * @details Sets the appropriate CGIF bit into the IFCR register in order to + * withdraw all the pending interrupt bits from the ISR register. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamClearInterrupt(dmastp) { \ + *(dmastp)->stream->ifcr = STM32_DMA_ISR_MASK << (dmastp)->stream->ishift; \ +} + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined() +extern _stm32_dma_streams[STM32_DMA_STREAMS]; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void dmaInit(void); + void dmaAllocate(stm32_dma_stream_t *dmastp, + stm32_dmaisr_t func, void *param); + void dmaRelease(stm32_dma_stream_t *dmastp); +#ifdef __cplusplus +} +#endif + +#endif /* _STM32_DMA_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32/GPIOv1/pal_lld.c b/os/hal/platforms/STM32/GPIOv1/pal_lld.c index a0a1fb6e5..81846fa58 100644 --- a/os/hal/platforms/STM32/GPIOv1/pal_lld.c +++ b/os/hal/platforms/STM32/GPIOv1/pal_lld.c @@ -19,8 +19,8 @@ */ /** - * @file STM32/pal_lld.c - * @brief STM32 GPIO low level driver code. + * @file STM32/GPIOv1/pal_lld.c + * @brief STM32F1xx GPIO low level driver code. * * @addtogroup PAL * @{ diff --git a/os/hal/platforms/STM32/GPIOv1/pal_lld.h b/os/hal/platforms/STM32/GPIOv1/pal_lld.h index fe2102637..65e660944 100644 --- a/os/hal/platforms/STM32/GPIOv1/pal_lld.h +++ b/os/hal/platforms/STM32/GPIOv1/pal_lld.h @@ -19,8 +19,8 @@ */ /** - * @file STM32/pal_lld.h - * @brief STM32 GPIO low level driver header. + * @file STM32/GPIOv1/pal_lld.h + * @brief STM32F1xx GPIO low level driver header. * * @addtogroup PAL * @{ -- cgit v1.2.3 From fe0093f795b6c88db8f12e2f7e45e11355fc3340 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 26 Aug 2011 13:47:22 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3254 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/stm32_dma.c | 2 +- os/hal/platforms/STM32/DMAv1/stm32_dma.h | 2 +- os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c | 239 ++++++++++++++++++++++++ os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h | 261 +++++++++++++++++++++++++++ os/hal/platforms/STM32/DMAv2/stm32_dma.c | 88 ++++++--- os/hal/platforms/STM32/DMAv2/stm32_dma.h | 150 +++++++++++---- os/hal/src/adc.c | 4 + os/hal/src/can.c | 4 + os/hal/src/gpt.c | 4 + os/hal/src/hal.c | 4 + os/hal/src/i2c.c | 4 + os/hal/src/icu.c | 4 + os/hal/src/mac.c | 4 + os/hal/src/mmc_spi.c | 4 + os/hal/src/pal.c | 4 + os/hal/src/pwm.c | 4 + os/hal/src/sdc.c | 4 + os/hal/src/serial.c | 4 + os/hal/src/serial_usb.c | 4 + os/hal/src/spi.c | 4 + os/hal/src/uart.c | 4 + os/hal/src/usb.c | 4 + os/hal/templates/adc_lld.c | 4 + os/hal/templates/can_lld.c | 4 + os/hal/templates/gpt_lld.c | 4 + os/hal/templates/hal_lld.c | 4 + os/hal/templates/i2c_lld.c | 4 + os/hal/templates/icu_lld.c | 4 + os/hal/templates/mac_lld.c | 4 + os/hal/templates/meta/driver.c | 4 + os/hal/templates/meta/driver_lld.c | 4 + os/hal/templates/pal_lld.c | 4 + os/hal/templates/pwm_lld.c | 4 + os/hal/templates/serial_lld.c | 4 + os/hal/templates/spi_lld.c | 4 + os/hal/templates/uart_lld.c | 4 + os/hal/templates/usb_lld.c | 4 + 37 files changed, 799 insertions(+), 67 deletions(-) create mode 100644 os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c create mode 100644 os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.c b/os/hal/platforms/STM32/DMAv1/stm32_dma.c index 4ea8e99ee..ae1a7170f 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.c @@ -19,7 +19,7 @@ */ /** - * @file stm32_dma.c + * @file DMAv1/stm32_dma.c * @brief STM32 DMA helper driver code. * * @addtogroup STM32_DMA diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.h b/os/hal/platforms/STM32/DMAv1/stm32_dma.h index 7ef5ad8b9..5ee06e939 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.h @@ -19,7 +19,7 @@ */ /** - * @file stm32_dma.h + * @file DMAv1/stm32_dma.h * @brief STM32 DMA helper driver header. * @note This file requires definitions from the ST STM32 header file * stm32f10x.h. diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c new file mode 100644 index 000000000..a1ade4409 --- /dev/null +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c @@ -0,0 +1,239 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file DMAv1/stm32_dma.c + * @brief DMA helper driver code. + * + * @addtogroup STM32_DMA + * @details DMA sharing helper driver. In the STM32 the DMA streams are a + * shared resource, this driver allows to allocate and free DMA + * streams at runtime in order to allow all the other device + * drivers to coordinate the access to the resource. + * @note The DMA ISR handlers are all declared into this module because + * sharing, the various device drivers can associate a callback to + * IRSs when allocating streams. + * @{ + */ + +#include "ch.h" +#include "hal.h" + +/* The following macro is only defined if some driver requiring DMA services + has been enabled.*/ +#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/** + * @brief Mask of the DMA1 streams in @p dma_streams_mask. + */ +#define STM32_DMA1_STREAMS_MASK 0x0000007F + +/** + * @brief Mask of the DMA2 streams in @p dma_streams_mask. + */ +#define STM32_DMA2_STREAMS_MASK 0x00000F80 + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief DMA streams descriptors. + * @details This table keeps the association between an unique stream + * identifier and the involved physical registers. + * @note Don't use this array directly, use the appropriate wrapper macros + * instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc. + */ +const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { + {0, DMA1, DMA1_Channel1, &DMA1->IFCR, 0}, + {1, DMA1, DMA1_Channel2, &DMA1->IFCR, 4}, + {2, DMA1, DMA1_Channel3, &DMA1->IFCR, 8}, + {3, DMA1, DMA1_Channel4, &DMA1->IFCR, 12}, + {4, DMA1, DMA1_Channel5, &DMA1->IFCR, 16}, + {5, DMA1, DMA1_Channel6, &DMA1->IFCR, 20}, + {6, DMA1, DMA1_Channel7, &DMA1->IFCR, 24}, +#if STM32_HAS_DMA2 || defined(__DOXYGEN__) + {7, DMA2, DMA2_Channel1, &DMA2->IFCR, 0}, + {8, DMA2, DMA2_Channel2, &DMA2->IFCR, 4}, + {9, DMA2, DMA2_Channel3, &DMA2->IFCR, 8}, + {10, DMA2, DMA2_Channel4, &DMA2->IFCR, 12}, + {11, DMA2, DMA2_Channel5, &DMA2->IFCR, 16}, +#endif +}; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/** + * @brief DMA ISR redirector type. + */ +typedef struct { + stm32_dmaisr_t dma_func; + void *dma_param; +} dma_isr_redir_t; + +/** + * @brief Mask of the allocated streams. + */ +static uint32_t dma_streams_mask; + +/** + * @brief DMA IRQ redirectors. + */ +static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS]; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/** + * @brief DMA1 stream 1 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 0) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[0].dma_func) + dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief STM32 DMA helper initialization. + * + * @init + */ +void dmaInit(void) { + int i; + + dma_streams_mask = 0; + for (i = 0; i < STM32_DMA_STREAMS; i--) { + _stm32_dma_streams[i].channel->CCR = 0; + dma_isr_redir[i].dma_func = NULL; + } + DMA1->IFCR = 0xFFFFFFFF; +#if STM32_HAS_DMA2 + DMA2->IFCR = 0xFFFFFFFF; +#endif +} + +/** + * @brief Allocates a DMA stream. + * @details The stream is allocated and, if required, the DMA clock enabled. + * Trying to allocate a stream already allocated is an illegal + * operation and is trapped if assertions are enabled. + * @pre The stream must not be already in use. + * @post The stream is allocated and the default ISR handler redirected + * to the specified function. + * @post The stream must be freed using @p dmaRelease() before it can + * be reused with another peripheral. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] func handling function pointer, can be @p NULL + * @param[in] param a parameter to be passed to the handling function + * @return The operation status. + * @retval FALSE no error, stream taken. + * @retval TRUE error, stream already taken. + * + * @special + */ +bool_t dmaAllocate(stm32_dma_stream_t *dmastp, + stm32_dmaisr_t func, void *param) { + + chDbgCheck(dmastp != NULL, "dmaAllocate"); + + /* Checks if the stream is already taken.*/ + if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0) + return TRUE; + + /* Marks the stream as allocated.*/ + dma_isr_redir[dmastp->selfindex].dma_func = func; + dma_isr_redir[dmastp->selfindex].dma_param = param; + dma_streams_mask |= (1 << dmastp->selfindex); + + /* Enabling DMA clocks required by the current streams set.*/ + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) + RCC->AHBENR |= RCC_AHBENR_DMA1EN; +#if STM32_HAS_DMA2 + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) + RCC->AHBENR |= RCC_AHBENR_DMA2EN; +#endif + + /* Making sure there are no spurious interrupts flags pending.*/ + dmaStreamClearInterrupt(dmastp); + return FALSE; +} + +/** + * @brief Releases a DMA stream. + * @details The stream is freed and, if required, the DMA clock disabled. + * Trying to release a unallocated stream is an illegal operation + * and is trapped if assertions are enabled. + * @pre The stream must have been allocated using @p dmaRequest(). + * @post The stream is again available. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +void dmaRelease(stm32_dma_stream_t *dmastp) { + + chDbgCheck(dmastp != NULL, "dmaRelease"); + + /* Check if the streams is not taken.*/ + chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0, + "dmaRelease(), #1", "not allocated"); + + /* Marks the stream as not allocated.*/ + dma_streams_mask &= ~(1 << dmastp->selfindex); + + /* Shutting down clocks that are no more required, if any.*/ + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) + RCC->AHBENR &= ~RCC_AHBENR_DMA1EN; +#if STM32_HAS_DMA2 + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) + RCC->AHBENR &= ~RCC_AHBENR_DMA2EN; +#endif +} + +#endif /* STM32_DMA_REQUIRED */ + +/** @} */ diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h new file mode 100644 index 000000000..45c683c07 --- /dev/null +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h @@ -0,0 +1,261 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file DMAv1/stm32_dma.h + * @brief DMA helper driver header. + * @note This file requires definitions from the ST header files + * stm32f10x.h or stm32l1xx.h. + * @note This driver uses the new naming convention used for the STM32F2xx + * so the "DMA channels" are referred as "DMA streams". + * + * @addtogroup STM32_DMA + * @{ + */ + +#ifndef _STM32_DMA_H_ +#define _STM32_DMA_H_ + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Total number of DMA streams. + * @note This is the total number of streams among all the DMA units. + */ +#if STM32_HAS_DMA2 || defined(__DOXYGEN__) +#define STM32_DMA_STREAMS 12 +#else +#define STM32_DMA_STREAMS 7 +#endif + +/** + * @brief Mask of the ISR bits passed to the DMA callback functions. + */ +#define STM32_DMA_ISR_MASK 0x0F + +/** + * @name DMA streams identifiers + * @{ + */ +#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[0]) +#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[1]) +#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[2]) +#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[3]) +#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[4]) +#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[5]) +#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[6]) +#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[8]) +#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[9]) +#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[10]) +#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[11]) +#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[12]) +/** @} */ + +/** + * @name CR register constants common to all DMA types + */ +#define STM32_DMA_CR_EN DMA_CCR1_EN +#define STM32_DMA_CR_TEIE DMA_CCR1_TEIE +#define STM32_DMA_CR_HTIE DMA_CCR1_HTIE +#define STM32_DMA_CR_TCIE DMA_CCR1_TCIE +#define STM32_DMA_CR_DIR_MASK (DMA_CCR1_DIR | DMA_CCR1_MEM2MEM) +#define STM32_DMA_CR_DIR_P2M 0 +#define STM32_DMA_CR_DIR_M2P DMA_CCR1_DIR +#define STM32_DMA_CR_DIR_M2M DMA_CCR1_MEM2MEM +#define STM32_DMA_CR_CIRC DMA_CCR1_CIRC +#define STM32_DMA_CR_PINC DMA_CCR1_PINC +#define STM32_DMA_CR_MINC DMA_CCR1_MINC +#define STM32_DMA_CR_PSIZE_MASK DMA_CCR1_PSIZE +#define STM32_DMA_CR_PSIZE_BYTE 0 +#define STM32_DMA_CR_PSIZE_HWORD DMA_CCR1_PSIZE_0 +#define STM32_DMA_CR_PSIZE_WORD DMA_CCR1_PSIZE_1 +#define STM32_DMA_CR_MSIZE_MASK DMA_CCR1_MSIZE +#define STM32_DMA_CR_MSIZE_BYTE 0 +#define STM32_DMA_CR_MSIZE_HWORD DMA_CCR1_MSIZE_0 +#define STM32_DMA_CR_MSIZE_WORD DMA_CCR1_MSIZE_1 +#define STM32_DMA_CR_PL_MASK DMA_CCR1_PL +#define STM32_DMA_CR_PL(n) ((n) << 16) +/** @} */ +/** + * @name CR register constants only found in enhanced DMA + */ +#define STM32_DMA_CR_CHSEL_MASK 0 /**< @brief Ignored by normal DMA. */ +#define STM32_DMA_CR_CHSEL(n) 0 /**< @brief Ignored by normal DMA. */ +/** @} */ + +/** + * @name Status flags passed to the ISR callbacks + */ +#define STM32_DMA_ISR_FEIF 0 +#define STM32_DMA_ISR_DMEIF 0 +#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1 +#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1 +#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1 +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief STM32 DMA stream descriptor structure. + */ +typedef struct { + uint32_t selfindex; /**< @brief Index to self in array. */ + DMA_TypeDef *dma; /**< @brief Associated DMA unit. */ + DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */ + volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */ + uint32_t ishift; /**< @brief Bits offset in xIFCR + register. */ +} stm32_dma_stream_t; + +/** + * @brief STM32 DMA ISR function type. + * + * @param[in] p parameter for the registered function + * @param[in] flags pre-shifted content of the ISR register, the bits + * are aligned to bit zero + */ +typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Associates a peripheral data register to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the CPAR register + * + * @special + */ +#define dmaStreamSetPeripheral(dmastp, addr) { \ + (dmastp)->channel->CPAR = (uint32_t)(addr); \ +} + +/** + * @brief Associates a memory destination to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the CMAR register + * + * @special + */ +#define dmaStreamSetMemory0(dmastp, addr) { \ + (dmastp)->channel->CMAR = (uint32_t)(addr); \ +} + +/** + * @brief Associates an alternate memory destination to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] size value to be written in the CNDTR register + * + * @special + */ +#define dmaStreamSetTransactionSize(dmastp, size) { \ + (dmastp)->channel->CNDTR = (uint32_t)(size); \ +} + +/** + * @brief Programs the stream mode settings. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] mode value to be written in the CCR register + * + * @special + */ +#define dmaStreamSetMode(dmastp, mode) { \ + (dmastp)->channel->CCR = (uint32_t)(mode2); \ +} + +/** + * @brief DMA stream enable. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmachp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamEnable(dmachp) { \ + (dmastp)->channel->CCR |= STM32_DMA_CR_EN; \ +} + +/** + * @brief DMA stream disable. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamDisable(dmastp) { \ + (dmastp)->channel->CCR &= ~STM32_DMA_CR_EN; \ +} + +/** + * @brief DMA stream interrupt sources clear. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamClearInterrupt(dmastp) { \ + *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \ +} + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void dmaInit(void); + bool_t dmaAllocate(stm32_dma_stream_t *dmastp, + stm32_dmaisr_t func, void *param); + void dmaRelease(stm32_dma_stream_t *dmastp); +#ifdef __cplusplus +} +#endif + +#endif /* _STM32_DMA_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.c b/os/hal/platforms/STM32/DMAv2/stm32_dma.c index d64cfc5f9..48c0d4e95 100644 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.c @@ -20,7 +20,7 @@ /** * @file DMAv2/stm32_dma.c - * @brief STM32F2xx Enhanced DMA helper driver code. + * @brief Enhanced DMA helper driver code. * * @addtogroup STM32_DMA * @details DMA sharing helper driver. In the STM32 the DMA streams are a @@ -40,6 +40,20 @@ has been enabled.*/ #if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/** + * @brief Mask of the DMA1 streams in @p dma_streams_mask. + */ +#define STM32_DMA1_STREAMS_MASK 0x000000FF + +/** + * @brief Mask of the DMA2 streams in @p dma_streams_mask. + */ +#define STM32_DMA2_STREAMS_MASK 0x0000FF00 + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -51,23 +65,23 @@ * @note Don't use this array directly, use the appropriate wrapper macros * instead: @p STM32_DMA1_STREAM0, @p STM32_DMA1_STREAM1 etc. */ -const stm32_dma_stream_t _stm32_dma_streams[16] = { - {0, DMA1, DMA1_Stream0, &DMA1->LISR, &DMA1->LIFCR, 0}, - {1, DMA1, DMA1_Stream1, &DMA1->LISR, &DMA1->LIFCR, 6}, - {2, DMA1, DMA1_Stream2, &DMA1->LISR, &DMA1->LIFCR, 16}, - {3, DMA1, DMA1_Stream3, &DMA1->LISR, &DMA1->LIFCR, 22}, - {4, DMA1, DMA1_Stream4, &DMA1->HISR, &DMA1->HIFCR, 0}, - {5, DMA1, DMA1_Stream5, &DMA1->HISR, &DMA1->HIFCR, 6}, - {6, DMA1, DMA1_Stream6, &DMA1->HISR, &DMA1->HIFCR, 16}, - {7, DMA1, DMA1_Stream7, &DMA1->HISR, &DMA1->HIFCR, 22}, - {8, DMA2, DMA2_Stream0, &DMA2->LISR, &DMA2->LIFCR, 0}, - {9, DMA2, DMA2_Stream1, &DMA2->LISR, &DMA2->LIFCR, 6}, - {10, DMA2, DMA2_Stream2, &DMA2->LISR, &DMA2->LIFCR, 16}, - {11, DMA2, DMA2_Stream3, &DMA2->LISR, &DMA2->LIFCR, 22}, - {12, DMA2, DMA2_Stream4, &DMA2->HISR, &DMA2->HIFCR, 0}, - {13, DMA2, DMA2_Stream5, &DMA2->HISR, &DMA2->HIFCR, 6}, - {14, DMA2, DMA2_Stream6, &DMA2->HISR, &DMA2->HIFCR, 16}, - {15, DMA2, DMA2_Stream7, &DMA2->HISR, &DMA2->HIFCR, 22}, +const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { + {0, DMA1, DMA1_Stream0, &DMA1->LIFCR, 0}, + {1, DMA1, DMA1_Stream1, &DMA1->LIFCR, 6}, + {2, DMA1, DMA1_Stream2, &DMA1->LIFCR, 16}, + {3, DMA1, DMA1_Stream3, &DMA1->LIFCR, 22}, + {4, DMA1, DMA1_Stream4, &DMA1->HIFCR, 0}, + {5, DMA1, DMA1_Stream5, &DMA1->HIFCR, 6}, + {6, DMA1, DMA1_Stream6, &DMA1->HIFCR, 16}, + {7, DMA1, DMA1_Stream7, &DMA1->HIFCR, 22}, + {8, DMA2, DMA2_Stream0, &DMA2->LIFCR, 0}, + {9, DMA2, DMA2_Stream1, &DMA2->LIFCR, 6}, + {10, DMA2, DMA2_Stream2, &DMA2->LIFCR, 16}, + {11, DMA2, DMA2_Stream3, &DMA2->LIFCR, 22}, + {12, DMA2, DMA2_Stream4, &DMA2->HIFCR, 0}, + {13, DMA2, DMA2_Stream5, &DMA2->HIFCR, 6}, + {14, DMA2, DMA2_Stream6, &DMA2->HIFCR, 16}, + {15, DMA2, DMA2_Stream7, &DMA2->HIFCR, 22}, }; /*===========================================================================*/ @@ -398,11 +412,11 @@ CH_IRQ_HANDLER(DMA2_Stream7_IRQHandler) { * @init */ void dmaInit(void) { - stm32_dma_stream_t *stp; + int i; dma_streams_mask = 0; - for (i = 0 - 1; i < STM32_DMA_STREAMS; i--) { - _stm32_dma_streams[i]->stream->CR = 0; + for (i = 0; i < STM32_DMA_STREAMS; i--) { + _stm32_dma_streams[i].stream->CR = 0; dma_isr_redir[i].dma_func = NULL; } DMA1->LIFCR = 0xFFFFFFFF; @@ -426,17 +440,20 @@ void dmaInit(void) { * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @param[in] func handling function pointer, can be @p NULL * @param[in] param a parameter to be passed to the handling function + * @return The operation status. + * @retval FALSE no error, stream taken. + * @retval TRUE error, stream already taken. * * @special */ -void dmaAllocate(stm32_dma_stream_t *dmastp, - stm32_dmaisr_t func, void *param) { +bool_t dmaAllocate(stm32_dma_stream_t *dmastp, + stm32_dmaisr_t func, void *param) { chDbgCheck(dmastp != NULL, "dmaAllocate"); /* Checks if the stream is already taken.*/ - chDbgAssert((dma_streams_mask & dmastp->mask) == 0, - "dmaAllocate(), #1", "already allocated"); + if ((dma_streams_mask & dmastp->mask) != 0) + return TRUE; /* Marks the stream as allocated.*/ dma_isr_redir[dmastp->selfindex].dma_func = func; @@ -444,13 +461,18 @@ void dmaAllocate(stm32_dma_stream_t *dmastp, dma_streams_mask |= (1 << dmastp->selfindex); /* Enabling DMA clocks required by the current streams set.*/ - if ((dma_streams_mask & 0x000000FF) != 0) + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) { RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; - if ((dma_streams_mask & 0x0000FF00) != 0) + RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA1LPEN; + } + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) { RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; + RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA2LPEN; + } /* Making sure there are no spurious interrupts flags pending.*/ - dmaStreamClearInterrupt(); + dmaStreamClearInterrupt(dmastp); + return FALSE; } /** @@ -468,6 +490,8 @@ void dmaAllocate(stm32_dma_stream_t *dmastp, */ void dmaRelease(stm32_dma_stream_t *dmastp) { + chDbgCheck(dmastp != NULL, "dmaRelease"); + /* Check if the streams is not taken.*/ chDbgAssert((dma_streams_mask & dmastp->mask) != 0, "dmaRelease(), #1", "not allocated"); @@ -476,10 +500,14 @@ void dmaRelease(stm32_dma_stream_t *dmastp) { dma_streams_mask &= ~(1 << dmastp->selfindex); /* Shutting down clocks that are no more required, if any.*/ - if ((dma_streams_mask & 0x000000FF) == 0) + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) { RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA1EN; - if ((dma_streams_mask & 0x0000FF00) == 0) + RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA1LPEN; + } + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) { RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA2EN; + RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA2LPEN; + } } #endif /* STM32_DMA_REQUIRED */ diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.h b/os/hal/platforms/STM32/DMAv2/stm32_dma.h index 805fd7c4b..5d87e67a9 100644 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.h @@ -20,7 +20,7 @@ /** * @file DMAv2/stm32_dma.h - * @brief STM32F2xx Enhanced DMA helper driver header. + * @brief Enhanced-DMA helper driver header. * @note This file requires definitions from the ST STM32F2xx header file * stm32f2xx.h. * @@ -39,33 +39,104 @@ * @brief Total number of DMA streams. * @note This is the total number of streams among all the DMA units. */ -#define STM32_DMA_STREAMS 16 +#define STM32_DMA_STREAMS 16 /** * @brief Mask of the ISR bits passed to the DMA callback functions. */ -#define STM32_DMA_ISR_MASK 0x3D +#define STM32_DMA_ISR_MASK 0x3D /** * @name DMA streams identifiers * @{ */ -#define STM32_DMA1_STREAM0 (&_stm32_dma_streams[0]) -#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[1]) -#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[2]) -#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[3]) -#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[4]) -#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[5]) -#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[6]) -#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[7]) -#define STM32_DMA2_STREAM0 (&_stm32_dma_streams[8]) -#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[9]) -#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[10]) -#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[11]) -#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[12]) -#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[13]) -#define STM32_DMA2_STREAM6 (&_stm32_dma_streams[14]) -#define STM32_DMA2_STREAM7 (&_stm32_dma_streams[15]) +#define STM32_DMA1_STREAM0 (&_stm32_dma_streams[0]) +#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[1]) +#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[2]) +#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[3]) +#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[4]) +#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[5]) +#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[6]) +#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[7]) +#define STM32_DMA2_STREAM0 (&_stm32_dma_streams[8]) +#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[9]) +#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[10]) +#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[11]) +#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[12]) +#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[13]) +#define STM32_DMA2_STREAM6 (&_stm32_dma_streams[14]) +#define STM32_DMA2_STREAM7 (&_stm32_dma_streams[15]) +/** @} */ + +/** + * @name CR register constants common to all DMA types + */ +#define STM32_DMA_CR_EN DMA_SxCR_EN +#define STM32_DMA_CR_TEIE DMA_SxCR_TEIE +#define STM32_DMA_CR_HTIE DMA_SxCR_HTIE +#define STM32_DMA_CR_TCIE DMA_SxCR_TCIE +#define STM32_DMA_CR_DIR_MASK DMA_SxCR_DIR +#define STM32_DMA_CR_DIR_P2M 0 +#define STM32_DMA_CR_DIR_M2P DMA_SxCR_DIR_0 +#define STM32_DMA_CR_DIR_M2M DMA_SxCR_DIR_1 +#define STM32_DMA_CR_CIRC DMA_SxCR_CIRC +#define STM32_DMA_CR_PINC DMA_SxCR_PINC +#define STM32_DMA_CR_MINC DMA_SxCR_MINC +#define STM32_DMA_CR_PSIZE_MASK DMA_SxCR_PSIZE +#define STM32_DMA_CR_PSIZE_BYTE 0 +#define STM32_DMA_CR_PSIZE_HWORD DMA_SxCR_PSIZE_0 +#define STM32_DMA_CR_PSIZE_WORD DMA_SxCR_PSIZE_1 +#define STM32_DMA_CR_MSIZE_MASK DMA_SxCR_MSIZE +#define STM32_DMA_CR_MSIZE_BYTE 0 +#define STM32_DMA_CR_MSIZE_HWORD DMA_SxCR_MSIZE_0 +#define STM32_DMA_CR_MSIZE_WORD DMA_SxCR_MSIZE_1 +#define STM32_DMA_CR_PL_MASK DMA_SxCR_PL +#define STM32_DMA_CR_PL(n) ((n) << 16) +/** @} */ + +/** + * @name CR register constants only found in STM32F2xx + */ +#define STM32_DMA_CR_DMEIE DMA_SxCR_DMEIE +#define STM32_DMA_CR_PFCTRL DMA_SxCR_PFCTRL +#define STM32_DMA_CR_PINCOS DMA_SxCR_PINCOS +#define STM32_DMA_CR_DBM DMA_SxCR_DBM +#define STM32_DMA_CR_CT DMA_SxCR_CT +#define STM32_DMA_CR_PBURST_MASK DMA_SxCR_PBURST +#define STM32_DMA_CR_PBURST_SINGLE 0 +#define STM32_DMA_CR_PBURST_INCR4 DMA_SxCR_PBURST_0 +#define STM32_DMA_CR_PBURST_INCR8 DMA_SxCR_PBURST_1 +#define STM32_DMA_CR_PBURST_INCR16 (DMA_SxCR_PBURST_0 | DMA_SxCR_PBURST_1) +#define STM32_DMA_CR_MBURST_MASK DMA_SxCR_MBURST +#define STM32_DMA_CR_MBURST_SINGLE 0 +#define STM32_DMA_CR_MBURST_INCR4 DMA_SxCR_MBURST_0 +#define STM32_DMA_CR_MBURST_INCR8 DMA_SxCR_MBURST_1 +#define STM32_DMA_CR_MBURST_INCR16 (DMA_SxCR_MBURST_0 | DMA_SxCR_MBURST_1) +#define STM32_DMA_CR_CHSEL_MASK DMA_SxCR_CHSEL +#define STM32_DMA_CR_CHSEL(n) ((n) << 25) +/** @} */ + +/** + * @name FCR register constants only found in STM32F2xx + */ +#define STM32_DMA_FCR_FEIE DMA_SxFCR_FEIE +#define STM32_DMA_FCR_FS_MASK DMA_SxFCR_FS +#define STM32_DMA_FCR_DMDIS DMA_SxFCR_DMDIS +#define STM32_DMA_FCR_FTH_MASK DMA_SxFCR_FTH +#define STM32_DMA_FCR_FTH_1Q 0 +#define STM32_DMA_FCR_FTH_HALF DMA_SxFCR_FTH_0 +#define STM32_DMA_FCR_FTH_3Q DMA_SxFCR_FTH_1 +#define STM32_DMA_FCR_FTH_FULL (DMA_SxFCR_FTH_0 | DMA_SxFCR_FTH_1) +/** @} */ + +/** + * @name Status flags passed to the ISR callbacks + */ +#define STM32_DMA_ISR_FEIF DMA_LISR_FEIF0 +#define STM32_DMA_ISR_DMEIF DMA_LISR_DMEIF0 +#define STM32_DMA_ISR_TEIF DMA_LISR_TEIF0 +#define STM32_DMA_ISR_HTIF DMA_LISR_HTIF0 +#define STM32_DMA_ISR_TCIF DMA_LISR_TCIF0 /** @} */ /*===========================================================================*/ @@ -89,8 +160,8 @@ typedef struct { DMA_Stream_TypeDef *stream; /**< @brief Associated DMA stream. */ volatile uint32_t *isr; /**< @brief Associated xISR reg. */ volatile uint32_t *ifcr; /**< @brief Associated xIFCR reg. */ - uint32_t ishift; /**< @brief Bits offset in xISR and - xIFCR registers. */ + uint32_t ishift; /**< @brief Bits offset in xIFCR + registers. */ } stm32_dma_stream_t; /** @@ -163,14 +234,25 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * @note This function can be invoked in both ISR or thread context. * * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] mode1 value to be written in the FCR register - * @param[in] mode2 value to be written in the CR register + * @param[in] mode value to be written in the CR register + * + * @special + */ +#define dmaStreamSetMode(dmastp, mode) { \ + (dmastp)->stream->CR = (uint32_t)(mode2); \ +} + +/** + * @brief Programs the stream FIFO settings. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] mode value to be written in the FCR register * * @special */ -#define dmaStreamSetMode(dmastp, mode1, mode2) { \ - (dmastp)->stream->FCR = (uint32_t)(mode1); \ - (dmastp)->stream->CR = (uint32_t)(mode2); \ +#define dmaStreamSetFIFO(dmastp, mode) { \ + (dmastp)->stream->FCR = (uint32_t)(mode); \ } /** @@ -182,7 +264,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * @special */ #define dmaStreamEnable(dmachp) { \ - (dmastp)->stream->CR |= DMA_SxCR_EN; \ + (dmastp)->stream->CR |= STM32_DMA_CR_EN; \ } /** @@ -194,13 +276,11 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * @special */ #define dmaStreamDisable(dmastp) { \ - (dmastp)->stream->CR &= ~DMA_SxCR_EN; \ + (dmastp)->stream->CR &= ~STM32_DMA_CR_EN; \ } /** * @brief DMA stream interrupt sources clear. - * @details Sets the appropriate CGIF bit into the IFCR register in order to - * withdraw all the pending interrupt bits from the ISR register. * @note This function can be invoked in both ISR or thread context. * * @param[in] dmastp pointer to a stm32_dma_stream_t structure @@ -208,23 +288,23 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * @special */ #define dmaStreamClearInterrupt(dmastp) { \ - *(dmastp)->stream->ifcr = STM32_DMA_ISR_MASK << (dmastp)->stream->ishift; \ + *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \ } /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ -#if !defined() -extern _stm32_dma_streams[STM32_DMA_STREAMS]; +#if !defined(__DOXYGEN__) +extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; #endif #ifdef __cplusplus extern "C" { #endif void dmaInit(void); - void dmaAllocate(stm32_dma_stream_t *dmastp, - stm32_dmaisr_t func, void *param); + bool_t dmaAllocate(stm32_dma_stream_t *dmastp, + stm32_dmaisr_t func, void *param); void dmaRelease(stm32_dma_stream_t *dmastp); #ifdef __cplusplus } diff --git a/os/hal/src/adc.c b/os/hal/src/adc.c index f2bf4eadd..c375818a6 100644 --- a/os/hal/src/adc.c +++ b/os/hal/src/adc.c @@ -31,6 +31,10 @@ #if HAL_USE_ADC || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/can.c b/os/hal/src/can.c index f9a827c4e..e888c2ae7 100644 --- a/os/hal/src/can.c +++ b/os/hal/src/can.c @@ -31,6 +31,10 @@ #if HAL_USE_CAN || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/gpt.c b/os/hal/src/gpt.c index 5f424453d..c677f5284 100644 --- a/os/hal/src/gpt.c +++ b/os/hal/src/gpt.c @@ -31,6 +31,10 @@ #if HAL_USE_GPT || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/hal.c b/os/hal/src/hal.c index 1a15988f5..ef7d7af8b 100644 --- a/os/hal/src/hal.c +++ b/os/hal/src/hal.c @@ -29,6 +29,10 @@ #include "ch.h" #include "hal.h" +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c index 86bfc16f6..260dcbb17 100644 --- a/os/hal/src/i2c.c +++ b/os/hal/src/i2c.c @@ -31,6 +31,10 @@ #if HAL_USE_I2C || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/icu.c b/os/hal/src/icu.c index 79d38798e..c73ea5106 100644 --- a/os/hal/src/icu.c +++ b/os/hal/src/icu.c @@ -31,6 +31,10 @@ #if HAL_USE_ICU || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/mac.c b/os/hal/src/mac.c index 4d6a9b2cd..0f1c47576 100644 --- a/os/hal/src/mac.c +++ b/os/hal/src/mac.c @@ -33,6 +33,10 @@ #if HAL_USE_MAC || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/mmc_spi.c b/os/hal/src/mmc_spi.c index e6dcf9287..34d111c2d 100644 --- a/os/hal/src/mmc_spi.c +++ b/os/hal/src/mmc_spi.c @@ -31,6 +31,10 @@ #if HAL_USE_MMC_SPI || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/pal.c b/os/hal/src/pal.c index 10e57e284..afb5c6b40 100644 --- a/os/hal/src/pal.c +++ b/os/hal/src/pal.c @@ -31,6 +31,10 @@ #if HAL_USE_PAL || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/pwm.c b/os/hal/src/pwm.c index e7dd6b64c..588b3df5c 100644 --- a/os/hal/src/pwm.c +++ b/os/hal/src/pwm.c @@ -31,6 +31,10 @@ #if HAL_USE_PWM || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c index 6bdaa2b5a..758edf8d8 100644 --- a/os/hal/src/sdc.c +++ b/os/hal/src/sdc.c @@ -31,6 +31,10 @@ #if HAL_USE_SDC || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/serial.c b/os/hal/src/serial.c index 03b74be54..d962bcdcd 100644 --- a/os/hal/src/serial.c +++ b/os/hal/src/serial.c @@ -31,6 +31,10 @@ #if HAL_USE_SERIAL || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c index 3f53d7df0..d9c25ecdf 100644 --- a/os/hal/src/serial_usb.c +++ b/os/hal/src/serial_usb.c @@ -33,6 +33,10 @@ #if HAL_USE_SERIAL_USB || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/spi.c b/os/hal/src/spi.c index aaf0115eb..b91b44507 100644 --- a/os/hal/src/spi.c +++ b/os/hal/src/spi.c @@ -31,6 +31,10 @@ #if HAL_USE_SPI || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/uart.c b/os/hal/src/uart.c index 372a3ad02..ed28ecb3b 100644 --- a/os/hal/src/uart.c +++ b/os/hal/src/uart.c @@ -31,6 +31,10 @@ #if HAL_USE_UART || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/src/usb.c b/os/hal/src/usb.c index 8493b6f41..44a772ab1 100644 --- a/os/hal/src/usb.c +++ b/os/hal/src/usb.c @@ -34,6 +34,10 @@ #if HAL_USE_USB || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/adc_lld.c b/os/hal/templates/adc_lld.c index eea062160..d5e8f5234 100644 --- a/os/hal/templates/adc_lld.c +++ b/os/hal/templates/adc_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_ADC || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/can_lld.c b/os/hal/templates/can_lld.c index ae0ca9607..2787591b2 100644 --- a/os/hal/templates/can_lld.c +++ b/os/hal/templates/can_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_CAN || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/gpt_lld.c b/os/hal/templates/gpt_lld.c index 1ee010603..308ce1921 100644 --- a/os/hal/templates/gpt_lld.c +++ b/os/hal/templates/gpt_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_GPT || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/hal_lld.c b/os/hal/templates/hal_lld.c index aead6dc43..3609f5fca 100644 --- a/os/hal/templates/hal_lld.c +++ b/os/hal/templates/hal_lld.c @@ -29,6 +29,10 @@ #include "ch.h" #include "hal.h" +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/i2c_lld.c b/os/hal/templates/i2c_lld.c index efd491857..ba8be9a45 100644 --- a/os/hal/templates/i2c_lld.c +++ b/os/hal/templates/i2c_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_I2C || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/icu_lld.c b/os/hal/templates/icu_lld.c index 23596bc97..3d6d2dc62 100644 --- a/os/hal/templates/icu_lld.c +++ b/os/hal/templates/icu_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_ICU || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/mac_lld.c b/os/hal/templates/mac_lld.c index c6cc7825b..62b8765d0 100644 --- a/os/hal/templates/mac_lld.c +++ b/os/hal/templates/mac_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_MAC || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/meta/driver.c b/os/hal/templates/meta/driver.c index c12103353..0c198e320 100644 --- a/os/hal/templates/meta/driver.c +++ b/os/hal/templates/meta/driver.c @@ -31,6 +31,10 @@ #if HAL_USE_XXX || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/meta/driver_lld.c b/os/hal/templates/meta/driver_lld.c index 2cf87bf1f..0e446808e 100644 --- a/os/hal/templates/meta/driver_lld.c +++ b/os/hal/templates/meta/driver_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_XXX || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/pal_lld.c b/os/hal/templates/pal_lld.c index 5314ef4b2..29336efda 100644 --- a/os/hal/templates/pal_lld.c +++ b/os/hal/templates/pal_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_PAL || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/pwm_lld.c b/os/hal/templates/pwm_lld.c index 67683d120..5a1977487 100644 --- a/os/hal/templates/pwm_lld.c +++ b/os/hal/templates/pwm_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_PWM || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/serial_lld.c b/os/hal/templates/serial_lld.c index 8fe70f628..26df9a38a 100644 --- a/os/hal/templates/serial_lld.c +++ b/os/hal/templates/serial_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_SERIAL || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/spi_lld.c b/os/hal/templates/spi_lld.c index c6162d7e0..138c5ceb7 100644 --- a/os/hal/templates/spi_lld.c +++ b/os/hal/templates/spi_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_SPI || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/uart_lld.c b/os/hal/templates/uart_lld.c index 21708858b..11fbc5ea5 100644 --- a/os/hal/templates/uart_lld.c +++ b/os/hal/templates/uart_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_UART || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ diff --git a/os/hal/templates/usb_lld.c b/os/hal/templates/usb_lld.c index 515fc5443..b451a9ecc 100644 --- a/os/hal/templates/usb_lld.c +++ b/os/hal/templates/usb_lld.c @@ -31,6 +31,10 @@ #if HAL_USE_USB || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ -- cgit v1.2.3 From d2e9a52cf6b2997b9b6320434ea296bde79b3727 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Aug 2011 08:53:14 +0000 Subject: New DMA helper driver for STM32F1xx and STM32L1xx. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3255 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/sdc.h | 2 +- os/hal/platforms/STM32/DMAv1/sdc_lld.c | 86 ++++---- os/hal/platforms/STM32/DMAv1/spi_lld.c | 169 ++++++++------- os/hal/platforms/STM32/DMAv1/spi_lld.h | 32 +-- os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c | 303 +++++++++++++++++++++++++-- os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h | 33 ++- os/hal/platforms/STM32/DMAv1/uart_lld.c | 180 ++++++++-------- os/hal/platforms/STM32/DMAv1/uart_lld.h | 12 +- os/hal/platforms/STM32/DMAv2/stm32_dma.c | 6 +- os/hal/platforms/STM32/DMAv2/stm32_dma.h | 19 +- os/hal/platforms/STM32F1xx/adc_lld.c | 50 ++--- os/hal/platforms/STM32F1xx/adc_lld.h | 8 +- 12 files changed, 601 insertions(+), 299 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h index 466c48fa6..8de6de823 100644 --- a/os/hal/include/sdc.h +++ b/os/hal/include/sdc.h @@ -242,7 +242,7 @@ extern "C" { uint8_t *buffer, uint32_t n); bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk, const uint8_t *buffer, uint32_t n); - bool_t sdc_wait_for_transfer_state(SDCDriver *sdcp); + bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp); #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/STM32/DMAv1/sdc_lld.c b/os/hal/platforms/STM32/DMAv1/sdc_lld.c index a88ad53fa..b9e02a815 100644 --- a/os/hal/platforms/STM32/DMAv1/sdc_lld.c +++ b/os/hal/platforms/STM32/DMAv1/sdc_lld.c @@ -78,15 +78,17 @@ static bool_t sdc_lld_read_multiple(SDCDriver *sdcp, uint32_t startblk, uint32_t resp[1]; /* Checks for errors and waits for the card to be ready for reading.*/ - if (sdc_wait_for_transfer_state(sdcp)) + if (_sdc_wait_for_transfer_state(sdcp)) return TRUE; /* Prepares the DMA channel for reading.*/ - dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], - (n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf, - (STM32_SDC_SDIO_DMA_PRIORITY << 12) | - DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 | - DMA_CCR1_MINC); + dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); + dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, + (n * SDC_BLOCK_SIZE) / sizeof (uint32_t)); + dmaStreamSetMode(STM32_DMA2_STREAM4, + STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | + STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_PSIZE_WORD | + STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); /* Setting up data transfer. Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/ @@ -100,7 +102,7 @@ static bool_t sdc_lld_read_multiple(SDCDriver *sdcp, uint32_t startblk, SDIO_DCTRL_DTEN; /* DMA channel activation.*/ - dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamEnable(STM32_DMA2_STREAM4); /* Read multiple blocks command.*/ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) @@ -123,14 +125,14 @@ static bool_t sdc_lld_read_multiple(SDCDriver *sdcp, uint32_t startblk, chSysUnlock(); goto error; } - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->DCTRL = 0; chSysUnlock(); return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); error: - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->MASK = 0; SDIO->DCTRL = 0; @@ -156,15 +158,17 @@ static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk, uint32_t resp[1]; /* Checks for errors and waits for the card to be ready for reading.*/ - if (sdc_wait_for_transfer_state(sdcp)) + if (_sdc_wait_for_transfer_state(sdcp)) return TRUE; /* Prepares the DMA channel for reading.*/ - dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], - SDC_BLOCK_SIZE / sizeof (uint32_t), buf, - (STM32_SDC_SDIO_DMA_PRIORITY << 12) | - DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 | - DMA_CCR1_MINC); + dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); + dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, + SDC_BLOCK_SIZE / sizeof (uint32_t)); + dmaStreamSetMode(STM32_DMA2_STREAM4, + STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | + STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_PSIZE_WORD | + STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); /* Setting up data transfer. Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/ @@ -178,7 +182,7 @@ static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk, SDIO_DCTRL_DTEN; /* DMA channel activation.*/ - dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamEnable(STM32_DMA2_STREAM4); /* Read single block command.*/ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) @@ -201,14 +205,14 @@ static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk, chSysUnlock(); goto error; } - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->DCTRL = 0; chSysUnlock(); return FALSE; error: - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->MASK = 0; SDIO->DCTRL = 0; @@ -235,15 +239,17 @@ static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk, uint32_t resp[1]; /* Checks for errors and waits for the card to be ready for writing.*/ - if (sdc_wait_for_transfer_state(sdcp)) + if (_sdc_wait_for_transfer_state(sdcp)) return TRUE; /* Prepares the DMA channel for writing.*/ - dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], - (n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf, - (STM32_SDC_SDIO_DMA_PRIORITY << 12) | - DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 | - DMA_CCR1_MINC | DMA_CCR1_DIR); + dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); + dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, + (n * SDC_BLOCK_SIZE) / sizeof (uint32_t)); + dmaStreamSetMode(STM32_DMA2_STREAM4, + STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | + STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD | + STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); /* Write multiple blocks command.*/ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) @@ -265,7 +271,7 @@ static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk, SDIO_DCTRL_DTEN; /* DMA channel activation.*/ - dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamEnable(STM32_DMA2_STREAM4); /* Note the mask is checked before going to sleep because the interrupt may have occurred before reaching the critical zone.*/ @@ -282,14 +288,14 @@ static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk, chSysUnlock(); goto error; } - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->DCTRL = 0; chSysUnlock(); return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); error: - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->MASK = 0; SDIO->DCTRL = 0; @@ -316,15 +322,17 @@ static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk, uint32_t resp[1]; /* Checks for errors and waits for the card to be ready for writing.*/ - if (sdc_wait_for_transfer_state(sdcp)) + if (_sdc_wait_for_transfer_state(sdcp)) return TRUE; /* Prepares the DMA channel for writing.*/ - dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], - SDC_BLOCK_SIZE / sizeof (uint32_t), buf, - (STM32_SDC_SDIO_DMA_PRIORITY << 12) | - DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 | - DMA_CCR1_MINC | DMA_CCR1_DIR); + dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); + dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, + SDC_BLOCK_SIZE / sizeof (uint32_t)); + dmaStreamSetMode(STM32_DMA2_STREAM4, + STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | + STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD | + STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); /* Write single block command.*/ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) @@ -346,7 +354,7 @@ static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk, SDIO_DCTRL_DTEN; /* DMA channel activation.*/ - dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamEnable(STM32_DMA2_STREAM4); /* Note the mask is checked before going to sleep because the interrupt may have occurred before reaching the critical zone.*/ @@ -363,14 +371,14 @@ static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk, chSysUnlock(); goto error; } - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->DCTRL = 0; chSysUnlock(); return FALSE; error: - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->MASK = 0; SDIO->DCTRL = 0; @@ -431,8 +439,8 @@ void sdc_lld_start(SDCDriver *sdcp) { if (sdcp->state == SDC_STOP) { /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_4, NULL, NULL); - dmaChannelSetPeripheral(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], &SDIO->FIFO); + dmaStreamAllocate(STM32_DMA2_STREAM4, 0, NULL, NULL); + dmaStreamSetPeripheral(STM32_DMA2_STREAM4, &SDIO->FIFO); NVICEnableVector(SDIO_IRQn, CORTEX_PRIORITY_MASK(STM32_SDC_SDIO_IRQ_PRIORITY)); RCC->AHBENR |= RCC_AHBENR_SDIOEN; @@ -461,7 +469,7 @@ void sdc_lld_stop(SDCDriver *sdcp) { /* Clock deactivation.*/ NVICDisableVector(SDIO_IRQn); - dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_4); + dmaStreamRelease(STM32_DMA2_STREAM4); } } diff --git a/os/hal/platforms/STM32/DMAv1/spi_lld.c b/os/hal/platforms/STM32/DMAv1/spi_lld.c index d8ae657a7..9302b0102 100644 --- a/os/hal/platforms/STM32/DMAv1/spi_lld.c +++ b/os/hal/platforms/STM32/DMAv1/spi_lld.c @@ -67,8 +67,8 @@ static uint16_t dummyrx; * @param[in] spip pointer to the @p SPIDriver object */ #define dma_stop(spip) { \ - dmaChannelDisable(spip->dmatx); \ - dmaChannelDisable(spip->dmarx); \ + dmaStreamDisable(spip->dmatx); \ + dmaStreamDisable(spip->dmarx); \ } /** @@ -91,7 +91,7 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_SPI_DMA_ERROR_HOOK) - if ((flags & DMA_ISR_TEIF1) != 0) { + if ((flags & STM32_DMA_ISR_TEIF) != 0) { STM32_SPI_DMA_ERROR_HOOK(spip); } #else @@ -117,7 +117,7 @@ static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_SPI_DMA_ERROR_HOOK) (void)spip; - if ((flags & DMA_ISR_TEIF1) != 0) { + if ((flags & STM32_DMA_ISR_TEIF) != 0) { STM32_SPI_DMA_ERROR_HOOK(spip); } #else @@ -147,24 +147,24 @@ void spi_lld_init(void) { spiObjectInit(&SPID1); SPID1.thread = NULL; SPID1.spi = SPI1; - SPID1.dmarx = STM32_DMA1_CH2; - SPID1.dmatx = STM32_DMA1_CH3; + SPID1.dmarx = STM32_DMA1_STREAM2; + SPID1.dmatx = STM32_DMA1_STREAM3; #endif #if STM32_SPI_USE_SPI2 spiObjectInit(&SPID2); SPID2.thread = NULL; SPID2.spi = SPI2; - SPID2.dmarx = STM32_DMA1_CH4; - SPID2.dmatx = STM32_DMA1_CH5; + SPID2.dmarx = STM32_DMA1_STREAM4; + SPID2.dmatx = STM32_DMA1_STREAM5; #endif #if STM32_SPI_USE_SPI3 spiObjectInit(&SPID3); SPID3.thread = NULL; SPID3.spi = SPI3; - SPID3.dmarx = STM32_DMA2_CH1; - SPID3.dmatx = STM32_DMA2_CH2; + SPID3.dmarx = STM32_DMA2_STREAM1; + SPID3.dmatx = STM32_DMA2_STREAM2; #endif } @@ -181,60 +181,69 @@ void spi_lld_start(SPIDriver *spip) { if (spip->state == SPI_STOP) { #if STM32_SPI_USE_SPI1 if (&SPID1 == spip) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_2, - (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip); - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_3, - (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); - NVICEnableVector(DMA1_Channel2_IRQn, - CORTEX_PRIORITY_MASK(STM32_SPI_SPI1_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel3_IRQn, - CORTEX_PRIORITY_MASK(STM32_SPI_SPI1_IRQ_PRIORITY)); + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM2, + STM32_SPI_SPI1_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #1", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM3, + STM32_SPI_SPI1_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #2", "stream already allocated"); RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; } #endif #if STM32_SPI_USE_SPI2 if (&SPID2 == spip) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_4, - (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip); - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_5, - (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); - NVICEnableVector(DMA1_Channel4_IRQn, - CORTEX_PRIORITY_MASK(STM32_SPI_SPI2_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel5_IRQn, - CORTEX_PRIORITY_MASK(STM32_SPI_SPI2_IRQ_PRIORITY)); + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM4, + STM32_SPI_SPI2_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #3", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM5, + STM32_SPI_SPI2_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #4", "stream already allocated"); RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; } #endif #if STM32_SPI_USE_SPI3 if (&SPID3 == spip) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_1, - (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip); - dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_2, - (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); - NVICEnableVector(DMA2_Channel1_IRQn, - CORTEX_PRIORITY_MASK(STM32_SPI_SPI3_IRQ_PRIORITY)); - NVICEnableVector(DMA2_Channel2_IRQn, - CORTEX_PRIORITY_MASK(STM32_SPI_SPI3_IRQ_PRIORITY)); + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM1, + STM32_SPI_SPI3_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #5", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM2, + STM32_SPI_SPI3_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #6", "stream already allocated"); RCC->APB1ENR |= RCC_APB1ENR_SPI3EN; } #endif /* DMA setup.*/ - dmaChannelSetPeripheral(spip->dmarx, &spip->spi->DR); - dmaChannelSetPeripheral(spip->dmatx, &spip->spi->DR); + dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR); + dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR); } /* More DMA setup.*/ if ((spip->config->cr1 & SPI_CR1_DFF) == 0) - spip->dmaccr = (STM32_SPI_SPI2_DMA_PRIORITY << 12) | - DMA_CCR1_TEIE; /* 8 bits transfers. */ + spip->dmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) | + STM32_DMA_CR_TEIE | + STM32_DMA_CR_PSIZE_BYTE | + STM32_DMA_CR_MSIZE_BYTE; /* 8 bits transfers. */ else - spip->dmaccr = (STM32_SPI_SPI2_DMA_PRIORITY << 12) | - DMA_CCR1_TEIE | DMA_CCR1_MSIZE_0 | - DMA_CCR1_PSIZE_0; /* 16 bits transfers. */ + spip->dmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) | + STM32_DMA_CR_TEIE | + STM32_DMA_CR_PSIZE_HWORD | + STM32_DMA_CR_MSIZE_HWORD; /* 16 bits transfers. */ /* SPI setup and enable.*/ spip->spi->CR1 = 0; @@ -261,28 +270,22 @@ void spi_lld_stop(SPIDriver *spip) { #if STM32_SPI_USE_SPI1 if (&SPID1 == spip) { - NVICDisableVector(DMA1_Channel2_IRQn); - NVICDisableVector(DMA1_Channel3_IRQn); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_2); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_3); + dmaStreamRelease(STM32_DMA1_STREAM2); + dmaStreamRelease(STM32_DMA1_STREAM3); RCC->APB2ENR &= ~RCC_APB2ENR_SPI1EN; } #endif #if STM32_SPI_USE_SPI2 if (&SPID2 == spip) { - NVICDisableVector(DMA1_Channel4_IRQn); - NVICDisableVector(DMA1_Channel5_IRQn); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_4); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_5); + dmaStreamRelease(STM32_DMA1_STREAM4); + dmaStreamRelease(STM32_DMA1_STREAM5); RCC->APB1ENR &= ~RCC_APB1ENR_SPI2EN; } #endif #if STM32_SPI_USE_SPI3 if (&SPID3 == spip) { - NVICDisableVector(DMA2_Channel1_IRQn); - NVICDisableVector(DMA2_Channel2_IRQn); - dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_1); - dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_2); + dmaStreamRelease(STM32_DMA1_STREAM1); + dmaStreamRelease(STM32_DMA1_STREAM2); RCC->APB1ENR &= ~RCC_APB1ENR_SPI3EN; } #endif @@ -327,10 +330,14 @@ void spi_lld_unselect(SPIDriver *spip) { */ void spi_lld_ignore(SPIDriver *spip, size_t n) { - dmaChannelSetup(spip->dmarx, n, &dummyrx, - spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_EN); - dmaChannelSetup(spip->dmatx, n, &dummytx, - spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_EN); + dmaStreamSetMemory0(spip->dmarx, &dummyrx); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | STM32_DMA_CR_EN); + dmaStreamSetMemory0(spip->dmatx, &dummytx); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_EN); } /** @@ -351,12 +358,15 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) { void spi_lld_exchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf) { - dmaChannelSetup(spip->dmarx, n, rxbuf, - spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC | - DMA_CCR1_EN); - dmaChannelSetup(spip->dmatx, n, txbuf, - spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC | - DMA_CCR1_EN); + dmaStreamSetMemory0(spip->dmarx, rxbuf); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | STM32_DMA_CR_MINC | + STM32_DMA_CR_EN); + dmaStreamSetMemory0(spip->dmatx, txbuf); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_MINC | STM32_DMA_CR_EN); } /** @@ -374,11 +384,14 @@ void spi_lld_exchange(SPIDriver *spip, size_t n, */ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { - dmaChannelSetup(spip->dmarx, n, &dummyrx, - spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_EN); - dmaChannelSetup(spip->dmatx, n, txbuf, - spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC | - DMA_CCR1_EN); + dmaStreamSetMemory0(spip->dmarx, &dummyrx); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | STM32_DMA_CR_EN); + dmaStreamSetMemory0(spip->dmatx, txbuf); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_MINC | STM32_DMA_CR_EN); } /** @@ -396,11 +409,15 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { */ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { - dmaChannelSetup(spip->dmarx, n, rxbuf, - spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC | - DMA_CCR1_EN); - dmaChannelSetup(spip->dmatx, n, &dummytx, - spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_EN); + dmaStreamSetMemory0(spip->dmarx, rxbuf); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | STM32_DMA_CR_MINC | + STM32_DMA_CR_EN); + dmaStreamSetMemory0(spip->dmatx, &dummytx); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_EN); } /** diff --git a/os/hal/platforms/STM32/DMAv1/spi_lld.h b/os/hal/platforms/STM32/DMAv1/spi_lld.h index 6f1e94096..c8c1e0661 100644 --- a/os/hal/platforms/STM32/DMAv1/spi_lld.h +++ b/os/hal/platforms/STM32/DMAv1/spi_lld.h @@ -174,20 +174,20 @@ typedef struct { /** * @brief Operation complete callback or @p NULL. */ - spicallback_t end_cb; + spicallback_t end_cb; /* End of the mandatory fields.*/ /** * @brief The chip select line port. */ - ioportid_t ssport; + ioportid_t ssport; /** * @brief The chip select line pad number. */ - uint16_t sspad; + uint16_t sspad; /** * @brief SPI initialization data. */ - uint16_t cr1; + uint16_t cr1; } SPIConfig; /** @@ -197,25 +197,25 @@ struct SPIDriver{ /** * @brief Driver state. */ - spistate_t state; + spistate_t state; /** * @brief Current configuration data. */ - const SPIConfig *config; + const SPIConfig *config; #if SPI_USE_WAIT || defined(__DOXYGEN__) /** * @brief Waiting thread. */ - Thread *thread; + Thread *thread; #endif /* SPI_USE_WAIT */ #if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) #if CH_USE_MUTEXES || defined(__DOXYGEN__) /** * @brief Mutex protecting the bus. */ - Mutex mutex; + Mutex mutex; #elif CH_USE_SEMAPHORES - Semaphore semaphore; + Semaphore semaphore; #endif #endif /* SPI_USE_MUTUAL_EXCLUSION */ #if defined(SPI_DRIVER_EXT_FIELDS) @@ -225,19 +225,19 @@ struct SPIDriver{ /** * @brief Pointer to the SPIx registers block. */ - SPI_TypeDef *spi; + SPI_TypeDef *spi; /** - * @brief Pointer to the receive DMA channel registers block. + * @brief Receive DMA channel. */ - stm32_dma_channel_t *dmarx; + const stm32_dma_stream_t *dmarx; /** - * @brief Pointer to the transmit DMA channel registers block. + * @brief Transmit DMA channel. */ - stm32_dma_channel_t *dmatx; + const stm32_dma_stream_t *dmatx; /** - * @brief DMA priority bit mask. + * @brief DMA mode bit mask. */ - uint32_t dmaccr; + uint32_t dmamode; }; /*===========================================================================*/ diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c index a1ade4409..1df93bb2f 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c @@ -54,6 +54,11 @@ */ #define STM32_DMA2_STREAMS_MASK 0x00000F80 +/** + * @brief Post-reset value of the stream CCR register. + */ +#define STM32_DMA_CCR_RESET_VALUE 0x00000000 + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -66,20 +71,25 @@ * instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc. */ const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { - {0, DMA1, DMA1_Channel1, &DMA1->IFCR, 0}, - {1, DMA1, DMA1_Channel2, &DMA1->IFCR, 4}, - {2, DMA1, DMA1_Channel3, &DMA1->IFCR, 8}, - {3, DMA1, DMA1_Channel4, &DMA1->IFCR, 12}, - {4, DMA1, DMA1_Channel5, &DMA1->IFCR, 16}, - {5, DMA1, DMA1_Channel6, &DMA1->IFCR, 20}, - {6, DMA1, DMA1_Channel7, &DMA1->IFCR, 24}, + {DMA1_Channel1, &DMA1->IFCR, 0, 0, DMA1_Channel1_IRQn}, + {DMA1_Channel2, &DMA1->IFCR, 4, 1, DMA1_Channel2_IRQn}, + {DMA1_Channel3, &DMA1->IFCR, 8, 2, DMA1_Channel3_IRQn}, + {DMA1_Channel4, &DMA1->IFCR, 12, 3, DMA1_Channel4_IRQn}, + {DMA1_Channel5, &DMA1->IFCR, 16, 4, DMA1_Channel5_IRQn}, + {DMA1_Channel6, &DMA1->IFCR, 20, 5, DMA1_Channel6_IRQn}, + {DMA1_Channel7, &DMA1->IFCR, 24, 6, DMA1_Channel7_IRQn}, #if STM32_HAS_DMA2 || defined(__DOXYGEN__) - {7, DMA2, DMA2_Channel1, &DMA2->IFCR, 0}, - {8, DMA2, DMA2_Channel2, &DMA2->IFCR, 4}, - {9, DMA2, DMA2_Channel3, &DMA2->IFCR, 8}, - {10, DMA2, DMA2_Channel4, &DMA2->IFCR, 12}, - {11, DMA2, DMA2_Channel5, &DMA2->IFCR, 16}, -#endif + {DMA2_Channel1, &DMA2->IFCR, 0, 7, DMA2_Channel1_IRQn}, + {DMA2_Channel2, &DMA2->IFCR, 4, 8, DMA2_Channel2_IRQn}, + {DMA2_Channel3, &DMA2->IFCR, 8, 9, DMA2_Channel3_IRQn}, +#if defined(STM32F10X_CL) || defined(__DOXYGEN__) + {DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_IRQn}, + {DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel5_IRQn}, +#else /* !STM32F10X_CL */ + {DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_5_IRQn}, + {DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel4_5_IRQn}, +#endif /* !STM32F10X_CL */ +#endif /* STM32_HAS_DMA2 */ }; /*===========================================================================*/ @@ -130,6 +140,239 @@ CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) { CH_IRQ_EPILOGUE(); } +/** + * @brief DMA1 stream 2 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 4; + if (dma_isr_redir[1].dma_func) + dma_isr_redir[1].dma_func(dma_isr_redir[1].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 3 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 8) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 8; + if (dma_isr_redir[2].dma_func) + dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 4 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[3].dma_func) + dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 5 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 16) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[4].dma_func) + dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 6 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 20) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 20; + if (dma_isr_redir[5].dma_func) + dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 7 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 24) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 24; + if (dma_isr_redir[6].dma_func) + dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +#if STM32_HAS_DMA2 || defined(__DOXYGEN__) +/** + * @brief DMA2 stream 1 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 0) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[7].dma_func) + dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 2 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 4) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 4; + if (dma_isr_redir[8].dma_func) + dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 3 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch3_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 8) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 8; + if (dma_isr_redir[9].dma_func) + dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +#if defined(STM32F10X_CL) || defined(__DOXYGEN__) +/** + * @brief DMA2 stream 4 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch4_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[10].dma_func) + dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 5 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[11].dma_func) + dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} +#else /* !STM32F10X_CL */ +/** + * @brief DMA2 streams 4 and 5 shared interrupt handler. + * @note This IRQ is shared between DMA2 channels 4 and 5 so it is a + * bit less efficient because an extra check. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + /* Check on channel 4.*/ + flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA2->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[10].dma_func) + dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); + } + + /* Check on channel 5.*/ + flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA2->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[11].dma_func) + dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); + } + + CH_IRQ_EPILOGUE(); +} +#endif /* !STM32F10X_CL */ +#endif /* STM32_HAS_DMA2 */ + /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -143,7 +386,7 @@ void dmaInit(void) { int i; dma_streams_mask = 0; - for (i = 0; i < STM32_DMA_STREAMS; i--) { + for (i = 0; i < STM32_DMA_STREAMS; i++) { _stm32_dma_streams[i].channel->CCR = 0; dma_isr_redir[i].dma_func = NULL; } @@ -156,13 +399,15 @@ void dmaInit(void) { /** * @brief Allocates a DMA stream. * @details The stream is allocated and, if required, the DMA clock enabled. - * Trying to allocate a stream already allocated is an illegal - * operation and is trapped if assertions are enabled. - * @pre The stream must not be already in use. + * The function also enables the IRQ vector associated to the stream + * and initializes its priority. + * @pre The stream must not be already in use or an error is returned. * @post The stream is allocated and the default ISR handler redirected * to the specified function. - * @post The stream must be freed using @p dmaRelease() before it can + * @post The stream ISR vector is enabled and its priority configured. + * @post The stream must be freed using @p dmaStreamRelease() before it can * be reused with another peripheral. + * @post The stream is in its post-reset state. * @note This function can be invoked in both ISR or thread context. * * @param[in] dmastp pointer to a stm32_dma_stream_t structure @@ -174,8 +419,10 @@ void dmaInit(void) { * * @special */ -bool_t dmaAllocate(stm32_dma_stream_t *dmastp, - stm32_dmaisr_t func, void *param) { +bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param) { chDbgCheck(dmastp != NULL, "dmaAllocate"); @@ -196,8 +443,15 @@ bool_t dmaAllocate(stm32_dma_stream_t *dmastp, RCC->AHBENR |= RCC_AHBENR_DMA2EN; #endif - /* Making sure there are no spurious interrupts flags pending.*/ + /* Putting the stream in a safe state.*/ + dmaStreamDisable(dmastp); dmaStreamClearInterrupt(dmastp); + dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; + + /* Enables the associated IRQ vector if a callback is defined.*/ + if (func != NULL) + NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority)); + return FALSE; } @@ -206,7 +460,7 @@ bool_t dmaAllocate(stm32_dma_stream_t *dmastp, * @details The stream is freed and, if required, the DMA clock disabled. * Trying to release a unallocated stream is an illegal operation * and is trapped if assertions are enabled. - * @pre The stream must have been allocated using @p dmaRequest(). + * @pre The stream must have been allocated using @p dmaStreamAllocate(). * @post The stream is again available. * @note This function can be invoked in both ISR or thread context. * @@ -214,7 +468,7 @@ bool_t dmaAllocate(stm32_dma_stream_t *dmastp, * * @special */ -void dmaRelease(stm32_dma_stream_t *dmastp) { +void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { chDbgCheck(dmastp != NULL, "dmaRelease"); @@ -222,6 +476,9 @@ void dmaRelease(stm32_dma_stream_t *dmastp) { chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0, "dmaRelease(), #1", "not allocated"); + /* Disables the associated IRQ vector.*/ + NVICDisableVector(dmastp->vector); + /* Marks the stream as not allocated.*/ dma_streams_mask &= ~(1 << dmastp->selfindex); diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h index 45c683c07..0247c63cf 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h @@ -93,7 +93,7 @@ #define STM32_DMA_CR_MSIZE_HWORD DMA_CCR1_MSIZE_0 #define STM32_DMA_CR_MSIZE_WORD DMA_CCR1_MSIZE_1 #define STM32_DMA_CR_PL_MASK DMA_CCR1_PL -#define STM32_DMA_CR_PL(n) ((n) << 16) +#define STM32_DMA_CR_PL(n) ((n) << 12) /** @} */ /** * @name CR register constants only found in enhanced DMA @@ -128,12 +128,12 @@ * @brief STM32 DMA stream descriptor structure. */ typedef struct { - uint32_t selfindex; /**< @brief Index to self in array. */ - DMA_TypeDef *dma; /**< @brief Associated DMA unit. */ DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */ volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */ - uint32_t ishift; /**< @brief Bits offset in xIFCR + uint8_t ishift; /**< @brief Bits offset in xIFCR register. */ + uint8_t selfindex; /**< @brief Index to self in array. */ + uint8_t vector; /**< @brief Associated IRQ vector. */ } stm32_dma_stream_t; /** @@ -176,7 +176,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); } /** - * @brief Associates an alternate memory destination to a DMA stream. + * @brief Sets the number of transfers to be performed. * @note This function can be invoked in both ISR or thread context. * * @param[in] dmastp pointer to a stm32_dma_stream_t structure @@ -188,6 +188,17 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); (dmastp)->channel->CNDTR = (uint32_t)(size); \ } +/** + * @brief Returns the number of transfers to be performed. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @return The number of transfers to be performed. + * + * @special + */ +#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->channel->CNDTR)) + /** * @brief Programs the stream mode settings. * @note This function can be invoked in both ISR or thread context. @@ -198,7 +209,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * @special */ #define dmaStreamSetMode(dmastp, mode) { \ - (dmastp)->channel->CCR = (uint32_t)(mode2); \ + (dmastp)->channel->CCR = (uint32_t)(mode); \ } /** @@ -209,7 +220,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * * @special */ -#define dmaStreamEnable(dmachp) { \ +#define dmaStreamEnable(dmastp) { \ (dmastp)->channel->CCR |= STM32_DMA_CR_EN; \ } @@ -249,9 +260,11 @@ extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; extern "C" { #endif void dmaInit(void); - bool_t dmaAllocate(stm32_dma_stream_t *dmastp, - stm32_dmaisr_t func, void *param); - void dmaRelease(stm32_dma_stream_t *dmastp); + bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param); + void dmaStreamRelease(const stm32_dma_stream_t *dmastp); #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/STM32/DMAv1/uart_lld.c b/os/hal/platforms/STM32/DMAv1/uart_lld.c index e2f306302..a9303744d 100644 --- a/os/hal/platforms/STM32/DMAv1/uart_lld.c +++ b/os/hal/platforms/STM32/DMAv1/uart_lld.c @@ -87,17 +87,19 @@ static uartflags_t translate_errors(uint16_t sr) { * @param[in] uartp pointer to the @p UARTDriver object */ static void set_rx_idle_loop(UARTDriver *uartp) { - uint32_t ccr; + uint32_t mode; /* RX DMA channel preparation, if the char callback is defined then the TCIE interrupt is enabled too.*/ if (uartp->config->rxchar_cb == NULL) - ccr = DMA_CCR1_CIRC | DMA_CCR1_TEIE; + mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TEIE; else - ccr = DMA_CCR1_CIRC | DMA_CCR1_TEIE | DMA_CCR1_TCIE; - dmaSetupChannel(uartp->dmap, uartp->dmarx, 1, - &uartp->rxbuf, uartp->dmaccr | ccr); - dmaEnableChannel(uartp->dmap, uartp->dmarx); + mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TEIE | + STM32_DMA_CR_TCIE; + dmaStreamSetMemory0(uartp->dmarx, &uartp->rxbuf); + dmaStreamSetTransactionSize(uartp->dmarx, 1); + dmaStreamSetMode(uartp->dmarx, uartp->dmamode | mode); + dmaStreamEnable(uartp->dmarx); } /** @@ -109,10 +111,10 @@ static void set_rx_idle_loop(UARTDriver *uartp) { static void usart_stop(UARTDriver *uartp) { /* Stops RX and TX DMA channels.*/ - dmaDisableChannel(uartp->dmap, uartp->dmarx); - dmaDisableChannel(uartp->dmap, uartp->dmatx); - dmaClearChannel(uartp->dmap, uartp->dmarx); - dmaClearChannel(uartp->dmap, uartp->dmatx); + dmaStreamDisable(uartp->dmarx); + dmaStreamClearInterrupt(uartp->dmarx); + dmaStreamDisable(uartp->dmatx); + dmaStreamClearInterrupt(uartp->dmatx); /* Stops USART operations.*/ uartp->usart->CR1 = 0; @@ -154,7 +156,7 @@ static void usart_start(UARTDriver *uartp) { u->CR1 = uartp->config->cr1 | cr1; u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE; u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR | - USART_CR3_EIE; + USART_CR3_EIE; /* Starting the receiver idle loop.*/ set_rx_idle_loop(uartp); @@ -170,7 +172,7 @@ static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_UART_DMA_ERROR_HOOK) - if ((flags & DMA_ISR_TEIF1) != 0) { + if ((flags & STM32_DMA_ISR_TEIF) != 0) { STM32_UART_DMA_ERROR_HOOK(uartp); } #else @@ -186,7 +188,7 @@ static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) { else { /* Receiver in active state, a callback is generated, if enabled, after a completed transfer.*/ - dmaDisableChannel(uartp->dmap, uartp->dmarx); + dmaStreamDisable(uartp->dmarx); uartp->rxstate = UART_RX_COMPLETE; if (uartp->config->rxend_cb != NULL) uartp->config->rxend_cb(uartp); @@ -209,14 +211,14 @@ static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_UART_DMA_ERROR_HOOK) - if ((flags & DMA_ISR_TEIF1) != 0) { + if ((flags & STM32_DMA_ISR_TEIF) != 0) { STM32_UART_DMA_ERROR_HOOK(uartp); } #else (void)flags; #endif - dmaDisableChannel(uartp->dmap, uartp->dmatx); + dmaStreamDisable(uartp->dmatx); /* A callback is generated, if enabled, after a completed transfer.*/ uartp->txstate = UART_TX_COMPLETE; if (uartp->config->txend1_cb != NULL) @@ -318,28 +320,22 @@ void uart_lld_init(void) { #if STM32_UART_USE_USART1 uartObjectInit(&UARTD1); UARTD1.usart = USART1; - UARTD1.dmap = STM32_DMA1; - UARTD1.dmarx = STM32_DMA_CHANNEL_5; - UARTD1.dmatx = STM32_DMA_CHANNEL_4; - UARTD1.dmaccr = 0; + UARTD1.dmarx = STM32_DMA1_STREAM5; + UARTD1.dmatx = STM32_DMA1_STREAM4; #endif #if STM32_UART_USE_USART2 uartObjectInit(&UARTD2); UARTD2.usart = USART2; - UARTD2.dmap = STM32_DMA1; - UARTD2.dmarx = STM32_DMA_CHANNEL_6; - UARTD2.dmatx = STM32_DMA_CHANNEL_7; - UARTD2.dmaccr = 0; + UARTD2.dmarx = STM32_DMA1_STREAM6; + UARTD2.dmatx = STM32_DMA1_STREAM7; #endif #if STM32_UART_USE_USART3 uartObjectInit(&UARTD3); UARTD3.usart = USART3; - UARTD3.dmap = STM32_DMA1; - UARTD3.dmarx = STM32_DMA_CHANNEL_3; - UARTD3.dmatx = STM32_DMA_CHANNEL_2; - UARTD3.dmaccr = 0; + UARTD3.dmarx = STM32_DMA1_STREAM3; + UARTD3.dmatx = STM32_DMA1_STREAM2; #endif } @@ -355,64 +351,68 @@ void uart_lld_start(UARTDriver *uartp) { if (uartp->state == UART_STOP) { #if STM32_UART_USE_USART1 if (&UARTD1 == uartp) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_4, - (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_5, - (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM4, + STM32_UART_USART1_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #1", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM5, + STM32_UART_USART1_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #2", "stream already allocated"); + RCC->APB2ENR |= RCC_APB2ENR_USART1EN; NVICEnableVector(USART1_IRQn, CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel4_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel5_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY)); - RCC->APB2ENR |= RCC_APB2ENR_USART1EN; } #endif #if STM32_UART_USE_USART2 if (&UARTD2 == uartp) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_6, - (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_7, - (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM6, + STM32_UART_USART2_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #3", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM7, + STM32_UART_USART2_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #4", "stream already allocated"); + RCC->APB1ENR |= RCC_APB1ENR_USART2EN; NVICEnableVector(USART2_IRQn, CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel6_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel7_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY)); - RCC->APB1ENR |= RCC_APB1ENR_USART2EN; } #endif #if STM32_UART_USE_USART3 if (&UARTD3 == uartp) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_2, - (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_3, - (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM2, + STM32_UART_USART3_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #5", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM3, + STM32_UART_USART3_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #6", "stream already allocated"); + RCC->APB1ENR |= RCC_APB1ENR_USART3EN; NVICEnableVector(USART3_IRQn, CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel2_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel3_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY)); - RCC->APB1ENR |= RCC_APB1ENR_USART3EN; } #endif /* Static DMA setup, the transfer size depends on the USART settings, it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/ - uartp->dmaccr = STM32_UART_USART1_DMA_PRIORITY << 12; + uartp->dmamode = STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY); if ((uartp->config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M) - uartp->dmaccr |= DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0; - dmaChannelSetPeripheral(&uartp->dmap->channels[uartp->dmarx], - &uartp->usart->DR); - dmaChannelSetPeripheral(&uartp->dmap->channels[uartp->dmatx], - &uartp->usart->DR); + uartp->dmamode |= STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; + dmaStreamSetPeripheral(uartp->dmarx, &uartp->usart->DR); + dmaStreamSetPeripheral(uartp->dmatx, &uartp->usart->DR); uartp->rxbuf = 0; } @@ -435,11 +435,9 @@ void uart_lld_stop(UARTDriver *uartp) { #if STM32_UART_USE_USART1 if (&UARTD1 == uartp) { + dmaStreamRelease(STM32_DMA1_STREAM4); + dmaStreamRelease(STM32_DMA1_STREAM5); NVICDisableVector(USART1_IRQn); - NVICDisableVector(DMA1_Channel4_IRQn); - NVICDisableVector(DMA1_Channel5_IRQn); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_4); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_5); RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN; return; } @@ -447,11 +445,9 @@ void uart_lld_stop(UARTDriver *uartp) { #if STM32_UART_USE_USART2 if (&UARTD2 == uartp) { + dmaStreamRelease(STM32_DMA1_STREAM6); + dmaStreamRelease(STM32_DMA1_STREAM7); NVICDisableVector(USART2_IRQn); - NVICDisableVector(DMA1_Channel6_IRQn); - NVICDisableVector(DMA1_Channel7_IRQn); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_6); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_7); RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN; return; } @@ -459,11 +455,9 @@ void uart_lld_stop(UARTDriver *uartp) { #if STM32_UART_USE_USART3 if (&UARTD3 == uartp) { + dmaStreamRelease(STM32_DMA1_STREAM2); + dmaStreamRelease(STM32_DMA1_STREAM3); NVICDisableVector(USART3_IRQn); - NVICDisableVector(DMA1_Channel2_IRQn); - NVICDisableVector(DMA1_Channel3_IRQn); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_2); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_3); RCC->APB1ENR &= ~RCC_APB1ENR_USART3EN; return; } @@ -485,10 +479,12 @@ void uart_lld_stop(UARTDriver *uartp) { void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { /* TX DMA channel preparation and start.*/ - dmaSetupChannel(uartp->dmap, uartp->dmatx, n, txbuf, - uartp->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC | - DMA_CCR1_TEIE | DMA_CCR1_TCIE); - dmaEnableChannel(uartp->dmap, uartp->dmatx); + dmaStreamSetMemory0(uartp->dmatx, txbuf); + dmaStreamSetTransactionSize(uartp->dmatx, n); + dmaStreamSetMode(uartp->dmatx, uartp->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_MINC | STM32_DMA_CR_TEIE | + STM32_DMA_CR_TCIE); + dmaStreamEnable(uartp->dmatx); } /** @@ -504,9 +500,9 @@ void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { */ size_t uart_lld_stop_send(UARTDriver *uartp) { - dmaDisableChannel(uartp->dmap, uartp->dmatx); - dmaClearChannel(uartp->dmap, uartp->dmatx); - return (size_t)uartp->dmap->channels[uartp->dmatx].CNDTR; + dmaStreamDisable(uartp->dmatx); + dmaStreamClearInterrupt(uartp->dmatx); + return dmaStreamGetTransactionSize(uartp->dmatx); } /** @@ -523,14 +519,16 @@ size_t uart_lld_stop_send(UARTDriver *uartp) { void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) { /* Stopping previous activity (idle state).*/ - dmaDisableChannel(uartp->dmap, uartp->dmarx); - dmaClearChannel(uartp->dmap, uartp->dmarx); + dmaStreamDisable(uartp->dmarx); + dmaStreamClearInterrupt(uartp->dmarx); /* RX DMA channel preparation and start.*/ - dmaSetupChannel(uartp->dmap, uartp->dmarx, n, rxbuf, - uartp->dmaccr | DMA_CCR1_MINC | - DMA_CCR1_TEIE | DMA_CCR1_TCIE); - dmaEnableChannel(uartp->dmap, uartp->dmarx); + dmaStreamSetMemory0(uartp->dmarx, rxbuf); + dmaStreamSetTransactionSize(uartp->dmarx, n); + dmaStreamSetMode(uartp->dmarx, uartp->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_MINC | STM32_DMA_CR_TEIE | + STM32_DMA_CR_TCIE); + dmaStreamEnable(uartp->dmarx); } /** @@ -547,9 +545,9 @@ void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) { size_t uart_lld_stop_receive(UARTDriver *uartp) { size_t n; - dmaDisableChannel(uartp->dmap, uartp->dmarx); - dmaClearChannel(uartp->dmap, uartp->dmarx); - n = (size_t)uartp->dmap->channels[uartp->dmarx].CNDTR; + dmaStreamDisable(uartp->dmarx); + dmaStreamClearInterrupt(uartp->dmarx); + n = dmaStreamGetTransactionSize(uartp->dmarx); set_rx_idle_loop(uartp); return n; } diff --git a/os/hal/platforms/STM32/DMAv1/uart_lld.h b/os/hal/platforms/STM32/DMAv1/uart_lld.h index 9321df85c..aff7f52ba 100644 --- a/os/hal/platforms/STM32/DMAv1/uart_lld.h +++ b/os/hal/platforms/STM32/DMAv1/uart_lld.h @@ -260,21 +260,17 @@ struct UARTDriver { */ USART_TypeDef *usart; /** - * @brief Pointer to the DMA registers block. + * @brief DMA mode bit mask. */ - stm32_dma_t *dmap; - /** - * @brief DMA priority bit mask. - */ - uint32_t dmaccr; + uint32_t dmamode; /** * @brief Receive DMA channel. */ - uint8_t dmarx; + const stm32_dma_stream_t *dmarx; /** * @brief Transmit DMA channel. */ - uint8_t dmatx; + const stm32_dma_stream_t *dmatx; /** * @brief Default receive buffer while into @p UART_RX_IDLE state. */ diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.c b/os/hal/platforms/STM32/DMAv2/stm32_dma.c index 48c0d4e95..5d320dab3 100644 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.c @@ -415,7 +415,7 @@ void dmaInit(void) { int i; dma_streams_mask = 0; - for (i = 0; i < STM32_DMA_STREAMS; i--) { + for (i = 0; i < STM32_DMA_STREAMS; i++) { _stm32_dma_streams[i].stream->CR = 0; dma_isr_redir[i].dma_func = NULL; } @@ -446,7 +446,7 @@ void dmaInit(void) { * * @special */ -bool_t dmaAllocate(stm32_dma_stream_t *dmastp, +bool_t dmaAllocate(const stm32_dma_stream_t *dmastp, stm32_dmaisr_t func, void *param) { chDbgCheck(dmastp != NULL, "dmaAllocate"); @@ -488,7 +488,7 @@ bool_t dmaAllocate(stm32_dma_stream_t *dmastp, * * @special */ -void dmaRelease(stm32_dma_stream_t *dmastp) { +void dmaRelease(const stm32_dma_stream_t *dmastp) { chDbgCheck(dmastp != NULL, "dmaRelease"); diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.h b/os/hal/platforms/STM32/DMAv2/stm32_dma.h index 5d87e67a9..88f594eec 100644 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.h @@ -217,11 +217,11 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); } /** - * @brief Associates an alternate memory destination to a DMA stream. + * @brief Sets the number of transfers to be performed. * @note This function can be invoked in both ISR or thread context. * * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] size value to be written in the NDTR register + * @param[in] size value to be written in the CNDTR register * * @special */ @@ -229,6 +229,17 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); (dmastp)->stream->NDTR = (uint32_t)(size); \ } +/** + * @brief Returns the number of transfers to be performed. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @return The number of transfers to be performed. + * + * @special + */ +#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->stream->NDTR)) + /** * @brief Programs the stream mode settings. * @note This function can be invoked in both ISR or thread context. @@ -303,9 +314,9 @@ extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; extern "C" { #endif void dmaInit(void); - bool_t dmaAllocate(stm32_dma_stream_t *dmastp, + bool_t dmaAllocate(const stm32_dma_stream_t *dmastp, stm32_dmaisr_t func, void *param); - void dmaRelease(stm32_dma_stream_t *dmastp); + void dmaRelease(const stm32_dma_stream_t *dmastp); #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/STM32F1xx/adc_lld.c b/os/hal/platforms/STM32F1xx/adc_lld.c index 8a8027e55..52d43daa9 100644 --- a/os/hal/platforms/STM32F1xx/adc_lld.c +++ b/os/hal/platforms/STM32F1xx/adc_lld.c @@ -58,17 +58,17 @@ static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_ADC_DMA_ERROR_HOOK) - if ((flags & DMA_ISR_TEIF1) != 0) { + if ((flags & STM32_DMA_ISR_TEIF) != 0) { STM32_ADC_DMA_ERROR_HOOK(spip); } #else (void)flags; #endif - if ((flags & DMA_ISR_HTIF1) != 0) { + if ((flags & STM32_DMA_ISR_HTIF) != 0) { /* Half transfer processing.*/ _adc_isr_half_code(adcp); } - if ((flags & DMA_ISR_TCIF1) != 0) { + if ((flags & STM32_DMA_ISR_TCIF) != 0) { /* Transfer complete processing.*/ _adc_isr_full_code(adcp); } @@ -93,10 +93,11 @@ void adc_lld_init(void) { /* Driver initialization.*/ adcObjectInit(&ADCD1); ADCD1.adc = ADC1; - ADCD1.dmachp = STM32_DMA1_CH1; - ADCD1.dmaccr = (STM32_ADC_ADC1_DMA_PRIORITY << 12) | - DMA_CCR1_EN | DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0 | - DMA_CCR1_MINC | DMA_CCR1_TCIE | DMA_CCR1_TEIE; + ADCD1.dmastp = STM32_DMA1_STREAM1; + ADCD1.dmamode = STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) | + STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | + STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | + STM32_DMA_CR_TEIE | STM32_DMA_CR_EN; /* Temporary activation.*/ RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; @@ -132,11 +133,13 @@ void adc_lld_start(ADCDriver *adcp) { if (adcp->state == ADC_STOP) { #if STM32_ADC_USE_ADC1 if (&ADCD1 == adcp) { - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_1, - (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, (void *)adcp); - NVICEnableVector(DMA1_Channel1_IRQn, - CORTEX_PRIORITY_MASK(STM32_ADC_ADC1_IRQ_PRIORITY)); - dmaChannelSetPeripheral(adcp->dmachp, &ADC1->DR); + bool_t b; + b = dmaStreamAllocate(adcp->dmastp, + STM32_ADC_ADC1_IRQ_PRIORITY, + (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, + (void *)adcp); + chDbgAssert(!b, "adc_lld_start(), #1", "stream already allocated"); + dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR); RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; } #endif @@ -163,8 +166,7 @@ void adc_lld_stop(ADCDriver *adcp) { if (&ADCD1 == adcp) { ADC1->CR1 = 0; ADC1->CR2 = 0; - NVICDisableVector(DMA1_Channel1_IRQn); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_1); + dmaStreamRelease(adcp->dmastp); RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN; } #endif @@ -179,27 +181,28 @@ void adc_lld_stop(ADCDriver *adcp) { * @notapi */ void adc_lld_start_conversion(ADCDriver *adcp) { - uint32_t ccr, n; + uint32_t mode, n; const ADCConversionGroup *grpp = adcp->grpp; /* DMA setup.*/ - ccr = adcp->dmaccr; + mode = adcp->dmamode; if (grpp->circular) - ccr |= DMA_CCR1_CIRC; + mode |= STM32_DMA_CR_CIRC; if (adcp->depth > 1) { /* If the buffer depth is greater than one then the half transfer interrupt interrupt is enabled in order to allows streaming processing.*/ - ccr |= DMA_CCR1_HTIE; + mode |= STM32_DMA_CR_HTIE; n = (uint32_t)grpp->num_channels * (uint32_t)adcp->depth; } else n = (uint32_t)grpp->num_channels; - dmaChannelSetup(adcp->dmachp, n, adcp->samples, ccr); + dmaStreamSetMemory0(adcp->dmastp, adcp->samples); + dmaStreamSetTransactionSize(adcp->dmastp, n); + dmaStreamSetMode(adcp->dmastp, mode); /* ADC setup.*/ adcp->adc->CR1 = grpp->cr1 | ADC_CR1_SCAN; - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | - ADC_CR2_CONT | ADC_CR2_ADON; + adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON; adcp->adc->SMPR1 = grpp->smpr1; adcp->adc->SMPR2 = grpp->smpr2; adcp->adc->SQR1 = grpp->sqr1; @@ -207,8 +210,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) { adcp->adc->SQR3 = grpp->sqr3; /* ADC start by writing ADC_CR2_ADON a second time.*/ - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | - ADC_CR2_CONT | ADC_CR2_ADON; + adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON; } /** @@ -220,7 +222,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) { */ void adc_lld_stop_conversion(ADCDriver *adcp) { - dmaChannelDisable(adcp->dmachp); + dmaStreamDisable(adcp->dmastp); adcp->adc->CR2 = 0; } diff --git a/os/hal/platforms/STM32F1xx/adc_lld.h b/os/hal/platforms/STM32F1xx/adc_lld.h index ce93e60ed..43b16b738 100644 --- a/os/hal/platforms/STM32F1xx/adc_lld.h +++ b/os/hal/platforms/STM32F1xx/adc_lld.h @@ -268,13 +268,13 @@ struct ADCDriver { */ ADC_TypeDef *adc; /** - * @brief Pointer to the DMA registers block. + * @brief Pointer to associated SMA channel. */ - stm32_dma_channel_t *dmachp; + const stm32_dma_stream_t *dmastp; /** - * @brief DMA CCR register bit mask. + * @brief DMA mode bit mask. */ - uint32_t dmaccr; + uint32_t dmamode; }; /*===========================================================================*/ -- cgit v1.2.3 From c1c1706005b56e75ae1cb02c9b7a12fb3a26fc18 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Aug 2011 08:55:48 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3256 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/stm32_dma.c | 411 +++++++++++++++++-------------- os/hal/platforms/STM32/DMAv1/stm32_dma.h | 269 ++++++++++---------- 2 files changed, 354 insertions(+), 326 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.c b/os/hal/platforms/STM32/DMAv1/stm32_dma.c index ae1a7170f..1df93bb2f 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.c @@ -20,28 +20,78 @@ /** * @file DMAv1/stm32_dma.c - * @brief STM32 DMA helper driver code. + * @brief DMA helper driver code. * * @addtogroup STM32_DMA - * @details DMA sharing helper driver. In the STM32 the DMA channels are a + * @details DMA sharing helper driver. In the STM32 the DMA streams are a * shared resource, this driver allows to allocate and free DMA - * channels at runtime in order to allow all the other device + * streams at runtime in order to allow all the other device * drivers to coordinate the access to the resource. * @note The DMA ISR handlers are all declared into this module because * sharing, the various device drivers can associate a callback to - * IRSs when allocating channels. + * IRSs when allocating streams. * @{ */ #include "ch.h" #include "hal.h" +/* The following macro is only defined if some driver requiring DMA services + has been enabled.*/ #if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/** + * @brief Mask of the DMA1 streams in @p dma_streams_mask. + */ +#define STM32_DMA1_STREAMS_MASK 0x0000007F + +/** + * @brief Mask of the DMA2 streams in @p dma_streams_mask. + */ +#define STM32_DMA2_STREAMS_MASK 0x00000F80 + +/** + * @brief Post-reset value of the stream CCR register. + */ +#define STM32_DMA_CCR_RESET_VALUE 0x00000000 + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ +/** + * @brief DMA streams descriptors. + * @details This table keeps the association between an unique stream + * identifier and the involved physical registers. + * @note Don't use this array directly, use the appropriate wrapper macros + * instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc. + */ +const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { + {DMA1_Channel1, &DMA1->IFCR, 0, 0, DMA1_Channel1_IRQn}, + {DMA1_Channel2, &DMA1->IFCR, 4, 1, DMA1_Channel2_IRQn}, + {DMA1_Channel3, &DMA1->IFCR, 8, 2, DMA1_Channel3_IRQn}, + {DMA1_Channel4, &DMA1->IFCR, 12, 3, DMA1_Channel4_IRQn}, + {DMA1_Channel5, &DMA1->IFCR, 16, 4, DMA1_Channel5_IRQn}, + {DMA1_Channel6, &DMA1->IFCR, 20, 5, DMA1_Channel6_IRQn}, + {DMA1_Channel7, &DMA1->IFCR, 24, 6, DMA1_Channel7_IRQn}, +#if STM32_HAS_DMA2 || defined(__DOXYGEN__) + {DMA2_Channel1, &DMA2->IFCR, 0, 7, DMA2_Channel1_IRQn}, + {DMA2_Channel2, &DMA2->IFCR, 4, 8, DMA2_Channel2_IRQn}, + {DMA2_Channel3, &DMA2->IFCR, 8, 9, DMA2_Channel3_IRQn}, +#if defined(STM32F10X_CL) || defined(__DOXYGEN__) + {DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_IRQn}, + {DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel5_IRQn}, +#else /* !STM32F10X_CL */ + {DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_5_IRQn}, + {DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel4_5_IRQn}, +#endif /* !STM32F10X_CL */ +#endif /* STM32_HAS_DMA2 */ +}; + /*===========================================================================*/ /* Driver local variables and types. */ /*===========================================================================*/ @@ -50,17 +100,19 @@ * @brief DMA ISR redirector type. */ typedef struct { - stm32_dmaisr_t dmaisrfunc; - void *dmaisrparam; + stm32_dmaisr_t dma_func; + void *dma_param; } dma_isr_redir_t; -static uint32_t dmamsk1; -static dma_isr_redir_t dma1[7]; +/** + * @brief Mask of the allocated streams. + */ +static uint32_t dma_streams_mask; -#if STM32_HAS_DMA2 -static uint32_t dmamsk2; -static dma_isr_redir_t dma2[5]; -#endif +/** + * @brief DMA IRQ redirectors. + */ +static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS]; /*===========================================================================*/ /* Driver local functions. */ @@ -71,250 +123,249 @@ static dma_isr_redir_t dma2[5]; /*===========================================================================*/ /** - * @brief DMA1 channel 1 shared interrupt handler. + * @brief DMA1 stream 1 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_1 * 4); - dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_1); - if (dma1[0].dmaisrfunc) - dma1[0].dmaisrfunc(dma1[0].dmaisrparam, isr); + flags = (DMA1->ISR >> 0) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[0].dma_func) + dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags); CH_IRQ_EPILOGUE(); } /** - * @brief DMA1 channel 2 shared interrupt handler. + * @brief DMA1 stream 2 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_2 * 4); - dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_2); - if (dma1[1].dmaisrfunc) - dma1[1].dmaisrfunc(dma1[1].dmaisrparam, isr); + flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 4; + if (dma_isr_redir[1].dma_func) + dma_isr_redir[1].dma_func(dma_isr_redir[1].dma_param, flags); CH_IRQ_EPILOGUE(); } /** - * @brief DMA1 channel 3 shared interrupt handler. + * @brief DMA1 stream 3 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_3 * 4); - dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3); - if (dma1[2].dmaisrfunc) - dma1[2].dmaisrfunc(dma1[2].dmaisrparam, isr); + flags = (DMA1->ISR >> 8) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 8; + if (dma_isr_redir[2].dma_func) + dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags); CH_IRQ_EPILOGUE(); } /** - * @brief DMA1 channel 4 shared interrupt handler. + * @brief DMA1 stream 4 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_4 * 4); - dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_4); - if (dma1[3].dmaisrfunc) - dma1[3].dmaisrfunc(dma1[3].dmaisrparam, isr); + flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[3].dma_func) + dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags); CH_IRQ_EPILOGUE(); } /** - * @brief DMA1 channel 5 shared interrupt handler. + * @brief DMA1 stream 5 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_5 * 4); - dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5); - if (dma1[4].dmaisrfunc) - dma1[4].dmaisrfunc(dma1[4].dmaisrparam, isr); + flags = (DMA1->ISR >> 16) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[4].dma_func) + dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags); CH_IRQ_EPILOGUE(); } /** - * @brief DMA1 channel 6 shared interrupt handler. + * @brief DMA1 stream 6 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_6 * 4); - dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6); - if (dma1[5].dmaisrfunc) - dma1[5].dmaisrfunc(dma1[5].dmaisrparam, isr); + flags = (DMA1->ISR >> 20) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 20; + if (dma_isr_redir[5].dma_func) + dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags); CH_IRQ_EPILOGUE(); } /** - * @brief DMA1 channel 7 shared interrupt handler. + * @brief DMA1 stream 7 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_7 * 4); - dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_7); - if (dma1[6].dmaisrfunc) - dma1[6].dmaisrfunc(dma1[6].dmaisrparam, isr); + flags = (DMA1->ISR >> 24) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 24; + if (dma_isr_redir[6].dma_func) + dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags); CH_IRQ_EPILOGUE(); } #if STM32_HAS_DMA2 || defined(__DOXYGEN__) /** - * @brief DMA2 channel 1 shared interrupt handler. + * @brief DMA2 stream 1 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_1 * 4); - dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_1); - if (dma2[0].dmaisrfunc) - dma2[0].dmaisrfunc(dma2[0].dmaisrparam, isr); + flags = (DMA2->ISR >> 0) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[7].dma_func) + dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags); CH_IRQ_EPILOGUE(); } /** - * @brief DMA2 channel 2 shared interrupt handler. + * @brief DMA2 stream 2 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_2 * 4); - dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_2); - if (dma2[1].dmaisrfunc) - dma2[1].dmaisrfunc(dma2[1].dmaisrparam, isr); + flags = (DMA2->ISR >> 4) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 4; + if (dma_isr_redir[8].dma_func) + dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags); CH_IRQ_EPILOGUE(); } /** - * @brief DMA2 channel 3 shared interrupt handler. + * @brief DMA2 stream 3 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA2_Ch3_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_3 * 4); - dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_3); - if (dma2[2].dmaisrfunc) - dma2[2].dmaisrfunc(dma2[2].dmaisrparam, isr); + flags = (DMA2->ISR >> 8) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 8; + if (dma_isr_redir[9].dma_func) + dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags); CH_IRQ_EPILOGUE(); } #if defined(STM32F10X_CL) || defined(__DOXYGEN__) /** - * @brief DMA2 channel 4 shared interrupt handler. + * @brief DMA2 stream 4 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA2_Ch4_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_4 * 4); - dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); - if (dma2[3].dmaisrfunc) - dma2[3].dmaisrfunc(dma2[3].dmaisrparam, isr); + flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[10].dma_func) + dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); CH_IRQ_EPILOGUE(); } /** - * @brief DMA2 channel 5 shared interrupt handler. + * @brief DMA2 stream 5 shared interrupt handler. * * @isr */ CH_IRQ_HANDLER(DMA2_Ch5_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); - isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_5 * 4); - dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5); - if (dma2[4].dmaisrfunc) - dma2[4].dmaisrfunc(dma2[4].dmaisrparam, isr); + flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[11].dma_func) + dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); CH_IRQ_EPILOGUE(); } - #else /* !STM32F10X_CL */ /** - * @brief DMA2 channels 4 and 5 shared interrupt handler. + * @brief DMA2 streams 4 and 5 shared interrupt handler. * @note This IRQ is shared between DMA2 channels 4 and 5 so it is a * bit less efficient because an extra check. * * @isr */ CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) { - uint32_t isr; + uint32_t flags; CH_IRQ_PROLOGUE(); /* Check on channel 4.*/ - isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_5 * 4); - if (isr & DMA_ISR_GIF1) { - dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5); - if (dma2[3].dmaisrfunc) - dma2[3].dmaisrfunc(dma2[3].dmaisrparam, isr); + flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA2->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[10].dma_func) + dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); } /* Check on channel 5.*/ - isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_4 * 4); - if (isr & DMA_ISR_GIF1) { - dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5); - if (dma2[4].dmaisrfunc) - dma2[4].dmaisrfunc(dma2[4].dmaisrparam, isr); + flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA2->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[11].dma_func) + dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); } CH_IRQ_EPILOGUE(); @@ -334,127 +385,109 @@ CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) { void dmaInit(void) { int i; - dmamsk1 = 0; - for (i = STM32_DMA_CHANNEL_7; i >= STM32_DMA_CHANNEL_1; i--) { - dmaDisableChannel(STM32_DMA1, i); - dma1[i].dmaisrfunc = NULL; + dma_streams_mask = 0; + for (i = 0; i < STM32_DMA_STREAMS; i++) { + _stm32_dma_streams[i].channel->CCR = 0; + dma_isr_redir[i].dma_func = NULL; } - STM32_DMA1->IFCR = 0xFFFFFFFF; + DMA1->IFCR = 0xFFFFFFFF; #if STM32_HAS_DMA2 - dmamsk2 = 0; - for (i = STM32_DMA_CHANNEL_5; i >= STM32_DMA_CHANNEL_1; i--) { - dmaDisableChannel(STM32_DMA2, i); - dma2[i].dmaisrfunc = NULL; - } - STM32_DMA1->IFCR = 0xFFFFFFFF; + DMA2->IFCR = 0xFFFFFFFF; #endif } /** - * @brief Allocates a DMA channel. - * @details The channel is allocated and, if required, the DMA clock enabled. - * Trying to allocate a channel already allocated is an illegal - * operation and is trapped if assertions are enabled. - * @pre The channel must not be already in use. - * @post The channel is allocated and the default ISR handler redirected + * @brief Allocates a DMA stream. + * @details The stream is allocated and, if required, the DMA clock enabled. + * The function also enables the IRQ vector associated to the stream + * and initializes its priority. + * @pre The stream must not be already in use or an error is returned. + * @post The stream is allocated and the default ISR handler redirected * to the specified function. - * @post The channel must be freed using @p dmaRelease() before it can + * @post The stream ISR vector is enabled and its priority configured. + * @post The stream must be freed using @p dmaStreamRelease() before it can * be reused with another peripheral. + * @post The stream is in its post-reset state. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dma DMA controller id - * @param[in] channel requested channel id + * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @param[in] func handling function pointer, can be @p NULL * @param[in] param a parameter to be passed to the handling function + * @return The operation status. + * @retval FALSE no error, stream taken. + * @retval TRUE error, stream already taken. * * @special */ -void dmaAllocate(uint32_t dma, uint32_t channel, - stm32_dmaisr_t func, void *param) { +bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param) { + chDbgCheck(dmastp != NULL, "dmaAllocate"); + + /* Checks if the stream is already taken.*/ + if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0) + return TRUE; + + /* Marks the stream as allocated.*/ + dma_isr_redir[dmastp->selfindex].dma_func = func; + dma_isr_redir[dmastp->selfindex].dma_param = param; + dma_streams_mask |= (1 << dmastp->selfindex); + + /* Enabling DMA clocks required by the current streams set.*/ + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) + RCC->AHBENR |= RCC_AHBENR_DMA1EN; #if STM32_HAS_DMA2 - switch (dma) { - case STM32_DMA1_ID: -#else - (void)dma; -#endif - /* Check if the channel is already taken.*/ - chDbgAssert((dmamsk1 & (1 << channel)) == 0, - "dmaAllocate(), #1", "already allocated"); - - /* If the DMA unit was idle then the clock is enabled.*/ - if (dmamsk1 == 0) { - RCC->AHBENR |= RCC_AHBENR_DMA1EN; - DMA1->IFCR = 0x0FFFFFFF; - } - - dmamsk1 |= 1 << channel; - dma1[channel].dmaisrfunc = func; - dma1[channel].dmaisrparam = param; -#if STM32_HAS_DMA2 - break; - case STM32_DMA2_ID: - /* Check if the channel is already taken.*/ - chDbgAssert((dmamsk2 & (1 << channel)) == 0, - "dmaAllocate(), #2", "already allocated"); - - /* If the DMA unit was idle then the clock is enabled.*/ - if (dmamsk2 == 0) { - RCC->AHBENR |= RCC_AHBENR_DMA2EN; - DMA2->IFCR = 0x0FFFFFFF; - } - - dmamsk2 |= 1 << channel; - dma2[channel].dmaisrfunc = func; - dma2[channel].dmaisrparam = param; - break; - } + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) + RCC->AHBENR |= RCC_AHBENR_DMA2EN; #endif + + /* Putting the stream in a safe state.*/ + dmaStreamDisable(dmastp); + dmaStreamClearInterrupt(dmastp); + dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; + + /* Enables the associated IRQ vector if a callback is defined.*/ + if (func != NULL) + NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority)); + + return FALSE; } /** - * @brief Releases a DMA channel. - * @details The channel is freed and, if required, the DMA clock disabled. - * Trying to release a unallocated channel is an illegal operation + * @brief Releases a DMA stream. + * @details The stream is freed and, if required, the DMA clock disabled. + * Trying to release a unallocated stream is an illegal operation * and is trapped if assertions are enabled. - * @pre The channel must have been allocated using @p dmaRequest(). - * @post The channel is again available. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post The stream is again available. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dma DMA controller id - * @param[in] channel requested channel id + * @param[in] dmastp pointer to a stm32_dma_stream_t structure * * @special */ -void dmaRelease(uint32_t dma, uint32_t channel) { +void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { + chDbgCheck(dmastp != NULL, "dmaRelease"); + + /* Check if the streams is not taken.*/ + chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0, + "dmaRelease(), #1", "not allocated"); + + /* Disables the associated IRQ vector.*/ + NVICDisableVector(dmastp->vector); + + /* Marks the stream as not allocated.*/ + dma_streams_mask &= ~(1 << dmastp->selfindex); + + /* Shutting down clocks that are no more required, if any.*/ + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) + RCC->AHBENR &= ~RCC_AHBENR_DMA1EN; #if STM32_HAS_DMA2 - switch (dma) { - case STM32_DMA1_ID: -#else - (void)dma; -#endif - /* Check if the channel is not taken.*/ - chDbgAssert((dmamsk1 & (1 << channel)) != 0, - "dmaRelease(), #1", "not allocated"); - - dma1[channel].dmaisrfunc = NULL; - dmamsk1 &= ~(1 << channel); - if (dmamsk1 == 0) - RCC->AHBENR &= ~RCC_AHBENR_DMA1EN; -#if STM32_HAS_DMA2 - break; - case STM32_DMA2_ID: - /* Check if the channel is not taken.*/ - chDbgAssert((dmamsk2 & (1 << channel)) != 0, - "dmaRelease(), #2", "not allocated"); - - dma2[channel].dmaisrfunc = NULL; - dmamsk2 &= ~(1 << channel); - if (dmamsk2 == 0) - RCC->AHBENR &= ~RCC_AHBENR_DMA2EN; - break; - } + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) + RCC->AHBENR &= ~RCC_AHBENR_DMA2EN; #endif } diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.h b/os/hal/platforms/STM32/DMAv1/stm32_dma.h index 5ee06e939..0247c63cf 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.h @@ -20,9 +20,11 @@ /** * @file DMAv1/stm32_dma.h - * @brief STM32 DMA helper driver header. - * @note This file requires definitions from the ST STM32 header file - * stm32f10x.h. + * @brief DMA helper driver header. + * @note This file requires definitions from the ST header files + * stm32f10x.h or stm32l1xx.h. + * @note This driver uses the new naming convention used for the STM32F2xx + * so the "DMA channels" are referred as "DMA streams". * * @addtogroup STM32_DMA * @{ @@ -35,14 +37,81 @@ /* Driver constants. */ /*===========================================================================*/ -/** @brief DMA1 identifier.*/ -#define STM32_DMA1_ID 0 - -/** @brief DMA2 identifier.*/ +/** + * @brief Total number of DMA streams. + * @note This is the total number of streams among all the DMA units. + */ #if STM32_HAS_DMA2 || defined(__DOXYGEN__) -#define STM32_DMA2_ID 1 +#define STM32_DMA_STREAMS 12 +#else +#define STM32_DMA_STREAMS 7 #endif +/** + * @brief Mask of the ISR bits passed to the DMA callback functions. + */ +#define STM32_DMA_ISR_MASK 0x0F + +/** + * @name DMA streams identifiers + * @{ + */ +#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[0]) +#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[1]) +#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[2]) +#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[3]) +#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[4]) +#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[5]) +#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[6]) +#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[8]) +#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[9]) +#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[10]) +#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[11]) +#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[12]) +/** @} */ + +/** + * @name CR register constants common to all DMA types + */ +#define STM32_DMA_CR_EN DMA_CCR1_EN +#define STM32_DMA_CR_TEIE DMA_CCR1_TEIE +#define STM32_DMA_CR_HTIE DMA_CCR1_HTIE +#define STM32_DMA_CR_TCIE DMA_CCR1_TCIE +#define STM32_DMA_CR_DIR_MASK (DMA_CCR1_DIR | DMA_CCR1_MEM2MEM) +#define STM32_DMA_CR_DIR_P2M 0 +#define STM32_DMA_CR_DIR_M2P DMA_CCR1_DIR +#define STM32_DMA_CR_DIR_M2M DMA_CCR1_MEM2MEM +#define STM32_DMA_CR_CIRC DMA_CCR1_CIRC +#define STM32_DMA_CR_PINC DMA_CCR1_PINC +#define STM32_DMA_CR_MINC DMA_CCR1_MINC +#define STM32_DMA_CR_PSIZE_MASK DMA_CCR1_PSIZE +#define STM32_DMA_CR_PSIZE_BYTE 0 +#define STM32_DMA_CR_PSIZE_HWORD DMA_CCR1_PSIZE_0 +#define STM32_DMA_CR_PSIZE_WORD DMA_CCR1_PSIZE_1 +#define STM32_DMA_CR_MSIZE_MASK DMA_CCR1_MSIZE +#define STM32_DMA_CR_MSIZE_BYTE 0 +#define STM32_DMA_CR_MSIZE_HWORD DMA_CCR1_MSIZE_0 +#define STM32_DMA_CR_MSIZE_WORD DMA_CCR1_MSIZE_1 +#define STM32_DMA_CR_PL_MASK DMA_CCR1_PL +#define STM32_DMA_CR_PL(n) ((n) << 12) +/** @} */ +/** + * @name CR register constants only found in enhanced DMA + */ +#define STM32_DMA_CR_CHSEL_MASK 0 /**< @brief Ignored by normal DMA. */ +#define STM32_DMA_CR_CHSEL(n) 0 /**< @brief Ignored by normal DMA. */ +/** @} */ + +/** + * @name Status flags passed to the ISR callbacks + */ +#define STM32_DMA_ISR_FEIF 0 +#define STM32_DMA_ISR_DMEIF 0 +#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1 +#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1 +#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1 +/** @} */ + /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ @@ -56,33 +125,23 @@ /*===========================================================================*/ /** - * @brief STM32 DMA channel memory structure type. - */ -typedef struct { - volatile uint32_t CCR; - volatile uint32_t CNDTR; - volatile uint32_t CPAR; - volatile uint32_t CMAR; - volatile uint32_t dummy; -} stm32_dma_channel_t; - -/** - * @brief STM32 DMA subsystem memory structure type. - * @note This structure has been redefined here because it is convenient to - * have the channels organized as an array, the ST header does not - * do that. + * @brief STM32 DMA stream descriptor structure. */ typedef struct { - volatile uint32_t ISR; - volatile uint32_t IFCR; - stm32_dma_channel_t channels[7]; -} stm32_dma_t; + DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */ + volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */ + uint8_t ishift; /**< @brief Bits offset in xIFCR + register. */ + uint8_t selfindex; /**< @brief Index to self in array. */ + uint8_t vector; /**< @brief Associated IRQ vector. */ +} stm32_dma_stream_t; /** * @brief STM32 DMA ISR function type. * * @param[in] p parameter for the registered function - * @param[in] flags pre-shifted content of the ISR register + * @param[in] flags pre-shifted content of the ISR register, the bits + * are aligned to bit zero */ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); @@ -90,186 +149,122 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); /* Driver macros. */ /*===========================================================================*/ -/** DMA1 registers block numeric address.*/ -#define STM32_DMA1_BASE (AHBPERIPH_BASE + 0x0000) -/** Pointer to the DMA1 registers block.*/ -#define STM32_DMA1 ((stm32_dma_t *)STM32_DMA1_BASE) -/** Pointer to the DMA1 channel 1 registers block.*/ -#define STM32_DMA1_CH1 (&STM32_DMA1->channels[0]) -/** Pointer to the DMA1 channel 2 registers block.*/ -#define STM32_DMA1_CH2 (&STM32_DMA1->channels[1]) -/** Pointer to the DMA1 channel 3 registers block.*/ -#define STM32_DMA1_CH3 (&STM32_DMA1->channels[2]) -/** Pointer to the DMA1 channel 4 registers block.*/ -#define STM32_DMA1_CH4 (&STM32_DMA1->channels[3]) -/** Pointer to the DMA1 channel 5 registers block.*/ -#define STM32_DMA1_CH5 (&STM32_DMA1->channels[4]) -/** Pointer to the DMA1 channel 6 registers block.*/ -#define STM32_DMA1_CH6 (&STM32_DMA1->channels[5]) -/** Pointer to the DMA1 channel 7 registers block.*/ -#define STM32_DMA1_CH7 (&STM32_DMA1->channels[6]) - -#if STM32_HAS_DMA2 || defined(__DOXYGEN__) -/** DMA2 registers block numeric address.*/ -#define STM32_DMA2_BASE (AHBPERIPH_BASE + 0x0400) -/** Pointer to the DMA2 registers block.*/ -#define STM32_DMA2 ((stm32_dma_t *)STM32_DMA2_BASE) -/** Pointer to the DMA2 channel 1 registers block.*/ -#define STM32_DMA2_CH1 (&STM32_DMA2->channels[0]) -/** Pointer to the DMA2 channel 2 registers block.*/ -#define STM32_DMA2_CH2 (&STM32_DMA2->channels[1]) -/** Pointer to the DMA2 channel 3 registers block.*/ -#define STM32_DMA2_CH3 (&STM32_DMA2->channels[2]) -/** Pointer to the DMA2 channel 4 registers block.*/ -#define STM32_DMA2_CH4 (&STM32_DMA2->channels[3]) -/** Pointer to the DMA2 channel 5 registers block.*/ -#define STM32_DMA2_CH5 (&STM32_DMA2->channels[4]) -#endif - -#define STM32_DMA_CHANNEL_1 0 /**< @brief DMA channel 1. */ -#define STM32_DMA_CHANNEL_2 1 /**< @brief DMA channel 2. */ -#define STM32_DMA_CHANNEL_3 2 /**< @brief DMA channel 3. */ -#define STM32_DMA_CHANNEL_4 3 /**< @brief DMA channel 4. */ -#define STM32_DMA_CHANNEL_5 4 /**< @brief DMA channel 5. */ -#define STM32_DMA_CHANNEL_6 5 /**< @brief DMA channel 6. */ -#define STM32_DMA_CHANNEL_7 6 /**< @brief DMA channel 7. */ - /** - * @brief Associates a peripheral data register to a DMA channel. + * @brief Associates a peripheral data register to a DMA stream. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmachp dmachp to a stm32_dma_channel_t structure - * @param[in] cpar value to be written in the CPAR register + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the CPAR register * * @special */ -#define dmaChannelSetPeripheral(dmachp, cpar) { \ - (dmachp)->CPAR = (uint32_t)(cpar); \ +#define dmaStreamSetPeripheral(dmastp, addr) { \ + (dmastp)->channel->CPAR = (uint32_t)(addr); \ } /** - * @brief DMA channel setup by channel pointer. - * @note This macro does not change the CPAR register because that register - * value does not change frequently, it usually points to a peripheral - * data register. + * @brief Associates a memory destination to a DMA stream. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmachp pointer to a stm32_dma_channel_t structure - * @param[in] cndtr value to be written in the CNDTR register - * @param[in] cmar value to be written in the CMAR register - * @param[in] ccr value to be written in the CCR register + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the CMAR register * * @special */ -#define dmaChannelSetup(dmachp, cndtr, cmar, ccr) { \ - (dmachp)->CNDTR = (uint32_t)(cndtr); \ - (dmachp)->CMAR = (uint32_t)(cmar); \ - (dmachp)->CCR = (uint32_t)(ccr); \ +#define dmaStreamSetMemory0(dmastp, addr) { \ + (dmastp)->channel->CMAR = (uint32_t)(addr); \ } /** - * @brief DMA channel enable by channel pointer. + * @brief Sets the number of transfers to be performed. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmachp pointer to a stm32_dma_channel_t structure + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] size value to be written in the CNDTR register * * @special */ -#define dmaChannelEnable(dmachp) { \ - (dmachp)->CCR |= DMA_CCR1_EN; \ +#define dmaStreamSetTransactionSize(dmastp, size) { \ + (dmastp)->channel->CNDTR = (uint32_t)(size); \ } /** - * @brief DMA channel disable by channel pointer. + * @brief Returns the number of transfers to be performed. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmachp pointer to a stm32_dma_channel_t structure + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @return The number of transfers to be performed. * * @special */ -#define dmaChannelDisable(dmachp) { \ - (dmachp)->CCR = 0; \ -} +#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->channel->CNDTR)) /** - * @brief DMA channel setup by channel ID. - * @note This macro does not change the CPAR register because that register - * value does not change frequently, it usually points to a peripheral - * data register. - * @note Channels are numbered from 0 to 6, use the appropriate macro - * as parameter. + * @brief Programs the stream mode settings. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmap pointer to a stm32_dma_t structure - * @param[in] ch channel number - * @param[in] cndtr value to be written in the CNDTR register - * @param[in] cmar value to be written in the CMAR register - * @param[in] ccr value to be written in the CCR register + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] mode value to be written in the CCR register * * @special */ -#define dmaSetupChannel(dmap, ch, cndtr, cmar, ccr) { \ - dmaChannelSetup(&(dmap)->channels[ch], (cndtr), (cmar), (ccr)); \ +#define dmaStreamSetMode(dmastp, mode) { \ + (dmastp)->channel->CCR = (uint32_t)(mode); \ } /** - * @brief DMA channel enable by channel ID. - * @note Channels are numbered from 0 to 6, use the appropriate macro - * as parameter. + * @brief DMA stream enable. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmap pointer to a stm32_dma_t structure - * @param[in] ch channel number + * @param[in] dmachp pointer to a stm32_dma_stream_t structure * * @special */ -#define dmaEnableChannel(dmap, ch) { \ - dmaChannelEnable(&(dmap)->channels[ch]); \ +#define dmaStreamEnable(dmastp) { \ + (dmastp)->channel->CCR |= STM32_DMA_CR_EN; \ } /** - * @brief DMA channel disable by channel ID. - * @note Channels are numbered from 0 to 6, use the appropriate macro - * as parameter. + * @brief DMA stream disable. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmap pointer to a stm32_dma_t structure - * @param[in] ch channel number + * @param[in] dmastp pointer to a stm32_dma_stream_t structure * * @special */ -#define dmaDisableChannel(dmap, ch) { \ - dmaChannelDisable(&(dmap)->channels[ch]); \ +#define dmaStreamDisable(dmastp) { \ + (dmastp)->channel->CCR &= ~STM32_DMA_CR_EN; \ } /** - * @brief DMA channel interrupt sources clear. - * @details Sets the appropriate CGIF bit into the IFCR register in order to - * withdraw all the pending interrupt bits from the ISR register. - * @note Channels are numbered from 0 to 6, use the appropriate macro - * as parameter. + * @brief DMA stream interrupt sources clear. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmap pointer to a stm32_dma_t structure - * @param[in] ch channel number + * @param[in] dmastp pointer to a stm32_dma_stream_t structure * * @special */ -#define dmaClearChannel(dmap, ch) { \ - (dmap)->IFCR = 1 << ((ch) * 4); \ +#define dmaStreamClearInterrupt(dmastp) { \ + *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \ } /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ +#if !defined(__DOXYGEN__) +extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; +#endif + #ifdef __cplusplus extern "C" { #endif void dmaInit(void); - void dmaAllocate(uint32_t dma, uint32_t channel, - stm32_dmaisr_t func, void *param); - void dmaRelease(uint32_t dma, uint32_t channel); + bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param); + void dmaStreamRelease(const stm32_dma_stream_t *dmastp); #ifdef __cplusplus } #endif -- cgit v1.2.3 From fe65de0c91a2d74566dbeb1bf66961e917aee031 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Aug 2011 08:56:49 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3257 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c | 496 --------------------------- os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h | 274 --------------- 2 files changed, 770 deletions(-) delete mode 100644 os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c delete mode 100644 os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c deleted file mode 100644 index 1df93bb2f..000000000 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c +++ /dev/null @@ -1,496 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file DMAv1/stm32_dma.c - * @brief DMA helper driver code. - * - * @addtogroup STM32_DMA - * @details DMA sharing helper driver. In the STM32 the DMA streams are a - * shared resource, this driver allows to allocate and free DMA - * streams at runtime in order to allow all the other device - * drivers to coordinate the access to the resource. - * @note The DMA ISR handlers are all declared into this module because - * sharing, the various device drivers can associate a callback to - * IRSs when allocating streams. - * @{ - */ - -#include "ch.h" -#include "hal.h" - -/* The following macro is only defined if some driver requiring DMA services - has been enabled.*/ -#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/** - * @brief Mask of the DMA1 streams in @p dma_streams_mask. - */ -#define STM32_DMA1_STREAMS_MASK 0x0000007F - -/** - * @brief Mask of the DMA2 streams in @p dma_streams_mask. - */ -#define STM32_DMA2_STREAMS_MASK 0x00000F80 - -/** - * @brief Post-reset value of the stream CCR register. - */ -#define STM32_DMA_CCR_RESET_VALUE 0x00000000 - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief DMA streams descriptors. - * @details This table keeps the association between an unique stream - * identifier and the involved physical registers. - * @note Don't use this array directly, use the appropriate wrapper macros - * instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc. - */ -const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { - {DMA1_Channel1, &DMA1->IFCR, 0, 0, DMA1_Channel1_IRQn}, - {DMA1_Channel2, &DMA1->IFCR, 4, 1, DMA1_Channel2_IRQn}, - {DMA1_Channel3, &DMA1->IFCR, 8, 2, DMA1_Channel3_IRQn}, - {DMA1_Channel4, &DMA1->IFCR, 12, 3, DMA1_Channel4_IRQn}, - {DMA1_Channel5, &DMA1->IFCR, 16, 4, DMA1_Channel5_IRQn}, - {DMA1_Channel6, &DMA1->IFCR, 20, 5, DMA1_Channel6_IRQn}, - {DMA1_Channel7, &DMA1->IFCR, 24, 6, DMA1_Channel7_IRQn}, -#if STM32_HAS_DMA2 || defined(__DOXYGEN__) - {DMA2_Channel1, &DMA2->IFCR, 0, 7, DMA2_Channel1_IRQn}, - {DMA2_Channel2, &DMA2->IFCR, 4, 8, DMA2_Channel2_IRQn}, - {DMA2_Channel3, &DMA2->IFCR, 8, 9, DMA2_Channel3_IRQn}, -#if defined(STM32F10X_CL) || defined(__DOXYGEN__) - {DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_IRQn}, - {DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel5_IRQn}, -#else /* !STM32F10X_CL */ - {DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_5_IRQn}, - {DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel4_5_IRQn}, -#endif /* !STM32F10X_CL */ -#endif /* STM32_HAS_DMA2 */ -}; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/** - * @brief DMA ISR redirector type. - */ -typedef struct { - stm32_dmaisr_t dma_func; - void *dma_param; -} dma_isr_redir_t; - -/** - * @brief Mask of the allocated streams. - */ -static uint32_t dma_streams_mask; - -/** - * @brief DMA IRQ redirectors. - */ -static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS]; - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/** - * @brief DMA1 stream 1 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 0) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 0; - if (dma_isr_redir[0].dma_func) - dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 2 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 4; - if (dma_isr_redir[1].dma_func) - dma_isr_redir[1].dma_func(dma_isr_redir[1].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 3 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 8) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 8; - if (dma_isr_redir[2].dma_func) - dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 4 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 12; - if (dma_isr_redir[3].dma_func) - dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 5 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 16) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 16; - if (dma_isr_redir[4].dma_func) - dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 6 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 20) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 20; - if (dma_isr_redir[5].dma_func) - dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA1 stream 7 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA1->ISR >> 24) & STM32_DMA_ISR_MASK; - DMA1->IFCR = STM32_DMA_ISR_MASK << 24; - if (dma_isr_redir[6].dma_func) - dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -#if STM32_HAS_DMA2 || defined(__DOXYGEN__) -/** - * @brief DMA2 stream 1 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->ISR >> 0) & STM32_DMA_ISR_MASK; - DMA2->IFCR = STM32_DMA_ISR_MASK << 0; - if (dma_isr_redir[7].dma_func) - dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA2 stream 2 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->ISR >> 4) & STM32_DMA_ISR_MASK; - DMA2->IFCR = STM32_DMA_ISR_MASK << 4; - if (dma_isr_redir[8].dma_func) - dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA2 stream 3 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Ch3_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->ISR >> 8) & STM32_DMA_ISR_MASK; - DMA2->IFCR = STM32_DMA_ISR_MASK << 8; - if (dma_isr_redir[9].dma_func) - dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -#if defined(STM32F10X_CL) || defined(__DOXYGEN__) -/** - * @brief DMA2 stream 4 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Ch4_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK; - DMA2->IFCR = STM32_DMA_ISR_MASK << 12; - if (dma_isr_redir[10].dma_func) - dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief DMA2 stream 5 shared interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Ch5_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK; - DMA2->IFCR = STM32_DMA_ISR_MASK << 16; - if (dma_isr_redir[11].dma_func) - dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); - - CH_IRQ_EPILOGUE(); -} -#else /* !STM32F10X_CL */ -/** - * @brief DMA2 streams 4 and 5 shared interrupt handler. - * @note This IRQ is shared between DMA2 channels 4 and 5 so it is a - * bit less efficient because an extra check. - * - * @isr - */ -CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) { - uint32_t flags; - - CH_IRQ_PROLOGUE(); - - /* Check on channel 4.*/ - flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK; - if (flags & STM32_DMA_ISR_MASK) { - DMA2->IFCR = STM32_DMA_ISR_MASK << 12; - if (dma_isr_redir[10].dma_func) - dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); - } - - /* Check on channel 5.*/ - flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK; - if (flags & STM32_DMA_ISR_MASK) { - DMA2->IFCR = STM32_DMA_ISR_MASK << 16; - if (dma_isr_redir[11].dma_func) - dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); - } - - CH_IRQ_EPILOGUE(); -} -#endif /* !STM32F10X_CL */ -#endif /* STM32_HAS_DMA2 */ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief STM32 DMA helper initialization. - * - * @init - */ -void dmaInit(void) { - int i; - - dma_streams_mask = 0; - for (i = 0; i < STM32_DMA_STREAMS; i++) { - _stm32_dma_streams[i].channel->CCR = 0; - dma_isr_redir[i].dma_func = NULL; - } - DMA1->IFCR = 0xFFFFFFFF; -#if STM32_HAS_DMA2 - DMA2->IFCR = 0xFFFFFFFF; -#endif -} - -/** - * @brief Allocates a DMA stream. - * @details The stream is allocated and, if required, the DMA clock enabled. - * The function also enables the IRQ vector associated to the stream - * and initializes its priority. - * @pre The stream must not be already in use or an error is returned. - * @post The stream is allocated and the default ISR handler redirected - * to the specified function. - * @post The stream ISR vector is enabled and its priority configured. - * @post The stream must be freed using @p dmaStreamRelease() before it can - * be reused with another peripheral. - * @post The stream is in its post-reset state. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] func handling function pointer, can be @p NULL - * @param[in] param a parameter to be passed to the handling function - * @return The operation status. - * @retval FALSE no error, stream taken. - * @retval TRUE error, stream already taken. - * - * @special - */ -bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, - uint32_t priority, - stm32_dmaisr_t func, - void *param) { - - chDbgCheck(dmastp != NULL, "dmaAllocate"); - - /* Checks if the stream is already taken.*/ - if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0) - return TRUE; - - /* Marks the stream as allocated.*/ - dma_isr_redir[dmastp->selfindex].dma_func = func; - dma_isr_redir[dmastp->selfindex].dma_param = param; - dma_streams_mask |= (1 << dmastp->selfindex); - - /* Enabling DMA clocks required by the current streams set.*/ - if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) - RCC->AHBENR |= RCC_AHBENR_DMA1EN; -#if STM32_HAS_DMA2 - if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) - RCC->AHBENR |= RCC_AHBENR_DMA2EN; -#endif - - /* Putting the stream in a safe state.*/ - dmaStreamDisable(dmastp); - dmaStreamClearInterrupt(dmastp); - dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; - - /* Enables the associated IRQ vector if a callback is defined.*/ - if (func != NULL) - NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority)); - - return FALSE; -} - -/** - * @brief Releases a DMA stream. - * @details The stream is freed and, if required, the DMA clock disabled. - * Trying to release a unallocated stream is an illegal operation - * and is trapped if assertions are enabled. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post The stream is again available. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * - * @special - */ -void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { - - chDbgCheck(dmastp != NULL, "dmaRelease"); - - /* Check if the streams is not taken.*/ - chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0, - "dmaRelease(), #1", "not allocated"); - - /* Disables the associated IRQ vector.*/ - NVICDisableVector(dmastp->vector); - - /* Marks the stream as not allocated.*/ - dma_streams_mask &= ~(1 << dmastp->selfindex); - - /* Shutting down clocks that are no more required, if any.*/ - if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) - RCC->AHBENR &= ~RCC_AHBENR_DMA1EN; -#if STM32_HAS_DMA2 - if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) - RCC->AHBENR &= ~RCC_AHBENR_DMA2EN; -#endif -} - -#endif /* STM32_DMA_REQUIRED */ - -/** @} */ diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h deleted file mode 100644 index 0247c63cf..000000000 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h +++ /dev/null @@ -1,274 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file DMAv1/stm32_dma.h - * @brief DMA helper driver header. - * @note This file requires definitions from the ST header files - * stm32f10x.h or stm32l1xx.h. - * @note This driver uses the new naming convention used for the STM32F2xx - * so the "DMA channels" are referred as "DMA streams". - * - * @addtogroup STM32_DMA - * @{ - */ - -#ifndef _STM32_DMA_H_ -#define _STM32_DMA_H_ - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @brief Total number of DMA streams. - * @note This is the total number of streams among all the DMA units. - */ -#if STM32_HAS_DMA2 || defined(__DOXYGEN__) -#define STM32_DMA_STREAMS 12 -#else -#define STM32_DMA_STREAMS 7 -#endif - -/** - * @brief Mask of the ISR bits passed to the DMA callback functions. - */ -#define STM32_DMA_ISR_MASK 0x0F - -/** - * @name DMA streams identifiers - * @{ - */ -#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[0]) -#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[1]) -#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[2]) -#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[3]) -#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[4]) -#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[5]) -#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[6]) -#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[8]) -#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[9]) -#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[10]) -#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[11]) -#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[12]) -/** @} */ - -/** - * @name CR register constants common to all DMA types - */ -#define STM32_DMA_CR_EN DMA_CCR1_EN -#define STM32_DMA_CR_TEIE DMA_CCR1_TEIE -#define STM32_DMA_CR_HTIE DMA_CCR1_HTIE -#define STM32_DMA_CR_TCIE DMA_CCR1_TCIE -#define STM32_DMA_CR_DIR_MASK (DMA_CCR1_DIR | DMA_CCR1_MEM2MEM) -#define STM32_DMA_CR_DIR_P2M 0 -#define STM32_DMA_CR_DIR_M2P DMA_CCR1_DIR -#define STM32_DMA_CR_DIR_M2M DMA_CCR1_MEM2MEM -#define STM32_DMA_CR_CIRC DMA_CCR1_CIRC -#define STM32_DMA_CR_PINC DMA_CCR1_PINC -#define STM32_DMA_CR_MINC DMA_CCR1_MINC -#define STM32_DMA_CR_PSIZE_MASK DMA_CCR1_PSIZE -#define STM32_DMA_CR_PSIZE_BYTE 0 -#define STM32_DMA_CR_PSIZE_HWORD DMA_CCR1_PSIZE_0 -#define STM32_DMA_CR_PSIZE_WORD DMA_CCR1_PSIZE_1 -#define STM32_DMA_CR_MSIZE_MASK DMA_CCR1_MSIZE -#define STM32_DMA_CR_MSIZE_BYTE 0 -#define STM32_DMA_CR_MSIZE_HWORD DMA_CCR1_MSIZE_0 -#define STM32_DMA_CR_MSIZE_WORD DMA_CCR1_MSIZE_1 -#define STM32_DMA_CR_PL_MASK DMA_CCR1_PL -#define STM32_DMA_CR_PL(n) ((n) << 12) -/** @} */ -/** - * @name CR register constants only found in enhanced DMA - */ -#define STM32_DMA_CR_CHSEL_MASK 0 /**< @brief Ignored by normal DMA. */ -#define STM32_DMA_CR_CHSEL(n) 0 /**< @brief Ignored by normal DMA. */ -/** @} */ - -/** - * @name Status flags passed to the ISR callbacks - */ -#define STM32_DMA_ISR_FEIF 0 -#define STM32_DMA_ISR_DMEIF 0 -#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1 -#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1 -#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1 -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief STM32 DMA stream descriptor structure. - */ -typedef struct { - DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */ - volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */ - uint8_t ishift; /**< @brief Bits offset in xIFCR - register. */ - uint8_t selfindex; /**< @brief Index to self in array. */ - uint8_t vector; /**< @brief Associated IRQ vector. */ -} stm32_dma_stream_t; - -/** - * @brief STM32 DMA ISR function type. - * - * @param[in] p parameter for the registered function - * @param[in] flags pre-shifted content of the ISR register, the bits - * are aligned to bit zero - */ -typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/** - * @brief Associates a peripheral data register to a DMA stream. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] addr value to be written in the CPAR register - * - * @special - */ -#define dmaStreamSetPeripheral(dmastp, addr) { \ - (dmastp)->channel->CPAR = (uint32_t)(addr); \ -} - -/** - * @brief Associates a memory destination to a DMA stream. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] addr value to be written in the CMAR register - * - * @special - */ -#define dmaStreamSetMemory0(dmastp, addr) { \ - (dmastp)->channel->CMAR = (uint32_t)(addr); \ -} - -/** - * @brief Sets the number of transfers to be performed. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] size value to be written in the CNDTR register - * - * @special - */ -#define dmaStreamSetTransactionSize(dmastp, size) { \ - (dmastp)->channel->CNDTR = (uint32_t)(size); \ -} - -/** - * @brief Returns the number of transfers to be performed. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @return The number of transfers to be performed. - * - * @special - */ -#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->channel->CNDTR)) - -/** - * @brief Programs the stream mode settings. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] mode value to be written in the CCR register - * - * @special - */ -#define dmaStreamSetMode(dmastp, mode) { \ - (dmastp)->channel->CCR = (uint32_t)(mode); \ -} - -/** - * @brief DMA stream enable. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmachp pointer to a stm32_dma_stream_t structure - * - * @special - */ -#define dmaStreamEnable(dmastp) { \ - (dmastp)->channel->CCR |= STM32_DMA_CR_EN; \ -} - -/** - * @brief DMA stream disable. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * - * @special - */ -#define dmaStreamDisable(dmastp) { \ - (dmastp)->channel->CCR &= ~STM32_DMA_CR_EN; \ -} - -/** - * @brief DMA stream interrupt sources clear. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * - * @special - */ -#define dmaStreamClearInterrupt(dmastp) { \ - *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \ -} - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if !defined(__DOXYGEN__) -extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void dmaInit(void); - bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, - uint32_t priority, - stm32_dmaisr_t func, - void *param); - void dmaStreamRelease(const stm32_dma_stream_t *dmastp); -#ifdef __cplusplus -} -#endif - -#endif /* _STM32_DMA_H_ */ - -/** @} */ -- cgit v1.2.3 From c5750b6977d7a45fe44c93df66c109ad446c5ce6 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Aug 2011 12:11:33 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3258 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/stm32_dma.c | 3 ++- os/hal/platforms/STM32/DMAv1/stm32_dma.h | 1 + os/hal/platforms/STM32/DMAv2/stm32_dma.c | 42 +++++++++++++++++++++++++------- os/hal/platforms/STM32/DMAv2/stm32_dma.h | 23 ++++++++--------- 4 files changed, 48 insertions(+), 21 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.c b/os/hal/platforms/STM32/DMAv1/stm32_dma.c index 1df93bb2f..e24ef565b 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.c @@ -446,7 +446,8 @@ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, /* Putting the stream in a safe state.*/ dmaStreamDisable(dmastp); dmaStreamClearInterrupt(dmastp); - dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; + dmastp->channel->CR = STM32_DMA_CR_RESET_VALUE; + dmastp->channel->FCR = STM32_DMA_FCR_RESET_VALUE; /* Enables the associated IRQ vector if a callback is defined.*/ if (func != NULL) diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.h b/os/hal/platforms/STM32/DMAv1/stm32_dma.h index 0247c63cf..473bbe851 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.h @@ -95,6 +95,7 @@ #define STM32_DMA_CR_PL_MASK DMA_CCR1_PL #define STM32_DMA_CR_PL(n) ((n) << 12) /** @} */ + /** * @name CR register constants only found in enhanced DMA */ diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.c b/os/hal/platforms/STM32/DMAv2/stm32_dma.c index 5d320dab3..05d6100c0 100644 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.c @@ -54,6 +54,16 @@ */ #define STM32_DMA2_STREAMS_MASK 0x0000FF00 +/** + * @brief Post-reset value of the stream CR register. + */ +#define STM32_DMA_CR_RESET_VALUE 0x00000000 + +/** + * @brief Post-reset value of the stream FCR register. + */ +#define STM32_DMA_FCR_RESET_VALUE 0x00000021 + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -428,13 +438,15 @@ void dmaInit(void) { /** * @brief Allocates a DMA stream. * @details The stream is allocated and, if required, the DMA clock enabled. - * Trying to allocate a stream already allocated is an illegal - * operation and is trapped if assertions are enabled. - * @pre The stream must not be already in use. + * The function also enables the IRQ vector associated to the stream + * and initializes its priority. + * @pre The stream must not be already in use or an error is returned. * @post The stream is allocated and the default ISR handler redirected * to the specified function. - * @post The stream must be freed using @p dmaRelease() before it can + * @post The stream ISR vector is enabled and its priority configured. + * @post The stream must be freed using @p dmaStreamRelease() before it can * be reused with another peripheral. + * @post The stream is in its post-reset state. * @note This function can be invoked in both ISR or thread context. * * @param[in] dmastp pointer to a stm32_dma_stream_t structure @@ -446,8 +458,10 @@ void dmaInit(void) { * * @special */ -bool_t dmaAllocate(const stm32_dma_stream_t *dmastp, - stm32_dmaisr_t func, void *param) { +bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param) { chDbgCheck(dmastp != NULL, "dmaAllocate"); @@ -470,8 +484,15 @@ bool_t dmaAllocate(const stm32_dma_stream_t *dmastp, RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA2LPEN; } - /* Making sure there are no spurious interrupts flags pending.*/ + /* Putting the stream in a safe state.*/ + dmaStreamDisable(dmastp); dmaStreamClearInterrupt(dmastp); + dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; + + /* Enables the associated IRQ vector if a callback is defined.*/ + if (func != NULL) + NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority)); + return FALSE; } @@ -480,7 +501,7 @@ bool_t dmaAllocate(const stm32_dma_stream_t *dmastp, * @details The stream is freed and, if required, the DMA clock disabled. * Trying to release a unallocated stream is an illegal operation * and is trapped if assertions are enabled. - * @pre The stream must have been allocated using @p dmaRequest(). + * @pre The stream must have been allocated using @p dmaStreamAllocate(). * @post The stream is again available. * @note This function can be invoked in both ISR or thread context. * @@ -488,7 +509,7 @@ bool_t dmaAllocate(const stm32_dma_stream_t *dmastp, * * @special */ -void dmaRelease(const stm32_dma_stream_t *dmastp) { +void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { chDbgCheck(dmastp != NULL, "dmaRelease"); @@ -496,6 +517,9 @@ void dmaRelease(const stm32_dma_stream_t *dmastp) { chDbgAssert((dma_streams_mask & dmastp->mask) != 0, "dmaRelease(), #1", "not allocated"); + /* Disables the associated IRQ vector.*/ + NVICDisableVector(dmastp->vector); + /* Marks the stream as not allocated.*/ dma_streams_mask &= ~(1 << dmastp->selfindex); diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.h b/os/hal/platforms/STM32/DMAv2/stm32_dma.h index 88f594eec..af18497fc 100644 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.h @@ -155,13 +155,12 @@ * @brief STM32 DMA stream descriptor structure. */ typedef struct { - uint32_t selfindex; /**< @brief Index to self in array. */ - DMA_TypeDef *dma; /**< @brief Associated DMA unit. */ - DMA_Stream_TypeDef *stream; /**< @brief Associated DMA stream. */ - volatile uint32_t *isr; /**< @brief Associated xISR reg. */ - volatile uint32_t *ifcr; /**< @brief Associated xIFCR reg. */ - uint32_t ishift; /**< @brief Bits offset in xIFCR - registers. */ + DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */ + volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */ + uint8_t ishift; /**< @brief Bits offset in xIFCR + register. */ + uint8_t selfindex; /**< @brief Index to self in array. */ + uint8_t vector; /**< @brief Associated IRQ vector. */ } stm32_dma_stream_t; /** @@ -250,7 +249,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * @special */ #define dmaStreamSetMode(dmastp, mode) { \ - (dmastp)->stream->CR = (uint32_t)(mode2); \ + (dmastp)->stream->CR = (uint32_t)(mode); \ } /** @@ -314,9 +313,11 @@ extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; extern "C" { #endif void dmaInit(void); - bool_t dmaAllocate(const stm32_dma_stream_t *dmastp, - stm32_dmaisr_t func, void *param); - void dmaRelease(const stm32_dma_stream_t *dmastp); + bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param); + void dmaStreamRelease(const stm32_dma_stream_t *dmastp); #ifdef __cplusplus } #endif -- cgit v1.2.3 From 8f5830dad86a26f92a293fc85a508a5b07c8f8e7 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Aug 2011 12:16:49 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3259 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/stm32_dma.c | 3 +-- os/hal/platforms/STM32/DMAv2/stm32_dma.c | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.c b/os/hal/platforms/STM32/DMAv1/stm32_dma.c index e24ef565b..1df93bb2f 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.c @@ -446,8 +446,7 @@ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, /* Putting the stream in a safe state.*/ dmaStreamDisable(dmastp); dmaStreamClearInterrupt(dmastp); - dmastp->channel->CR = STM32_DMA_CR_RESET_VALUE; - dmastp->channel->FCR = STM32_DMA_FCR_RESET_VALUE; + dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; /* Enables the associated IRQ vector if a callback is defined.*/ if (func != NULL) diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.c b/os/hal/platforms/STM32/DMAv2/stm32_dma.c index 05d6100c0..2b6851ad6 100644 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.c @@ -487,7 +487,8 @@ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, /* Putting the stream in a safe state.*/ dmaStreamDisable(dmastp); dmaStreamClearInterrupt(dmastp); - dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; + dmastp->channel->CR = STM32_DMA_CR_RESET_VALUE; + dmastp->channel->FCR = STM32_DMA_FCR_RESET_VALUE; /* Enables the associated IRQ vector if a callback is defined.*/ if (func != NULL) -- cgit v1.2.3 From 339cbbd60e7c45bb21758cdfe264e8e1c78d4fd5 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Aug 2011 12:55:02 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3260 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/usb_cdc.h | 22 ++++++++++++++++------ os/hal/platforms/STM32/USBv1/usb_lld.c | 2 +- os/hal/src/serial_usb.c | 6 +++--- 3 files changed, 20 insertions(+), 10 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/usb_cdc.h b/os/hal/include/usb_cdc.h index cd9d78f10..48a543642 100644 --- a/os/hal/include/usb_cdc.h +++ b/os/hal/include/usb_cdc.h @@ -33,6 +33,10 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @name CDC specific messages. + * @{ + */ #define CDC_SEND_ENCAPSULATED_COMMAND 0x00 #define CDC_GET_ENCAPSULATED_RESPONSE 0x01 #define CDC_SET_COMM_FEATURE 0x02 @@ -52,7 +56,12 @@ #define CDC_GET_RINGER_PARMS 0x31 #define CDC_SET_OPERATION_PARMS 0x32 #define CDC_GET_OPERATION_PARMS 0x33 +/** @} */ +/** + * @name Line Control bit definitions. + * @{ + */ #define LC_STOP_1 0 #define LC_STOP_1P5 1 #define LC_STOP_2 2 @@ -62,6 +71,7 @@ #define LC_PARITY_EVEN 2 #define LC_PARITY_MARK 3 #define LC_PARITY_SPACE 4 +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ @@ -74,22 +84,22 @@ /** * @brief Endpoint number for bulk IN. */ -#if !defined(DATA_REQUEST_EP) || defined(__DOXYGEN__) -#define DATA_REQUEST_EP 1 +#if !defined(USB_CDC_DATA_REQUEST_EP) || defined(__DOXYGEN__) +#define USB_CDC_DATA_REQUEST_EP 1 #endif /** * @brief Endpoint number for interrupt IN. */ -#if !defined(INTERRUPT_REQUEST_EP) || defined(__DOXYGEN__) -#define INTERRUPT_REQUEST_EP 2 +#if !defined(USB_CDC_INTERRUPT_REQUEST_EP) || defined(__DOXYGEN__) +#define USB_CDC_INTERRUPT_REQUEST_EP 2 #endif /** * @brief Endpoint number for bulk OUT. */ -#if !defined(DATA_AVAILABLE_EP) || defined(__DOXYGEN__) -#define DATA_AVAILABLE_EP 3 +#if !defined(USB_CDC_DATA_AVAILABLE_EP) || defined(__DOXYGEN__) +#define USB_CDC_DATA_AVAILABLE_EP 3 #endif /** @} */ diff --git a/os/hal/platforms/STM32/USBv1/usb_lld.c b/os/hal/platforms/STM32/USBv1/usb_lld.c index db0c558b6..34b8d9bf0 100644 --- a/os/hal/platforms/STM32/USBv1/usb_lld.c +++ b/os/hal/platforms/STM32/USBv1/usb_lld.c @@ -105,7 +105,7 @@ static uint32_t pm_alloc(USBDriver *usbp, size_t size) { next = usbp->pmnext; usbp->pmnext += size; - chDbgAssert(usbp->pmnext > USB_PMA_SIZE, "pm_alloc(), #1", "PMA overflow"); + chDbgAssert(usbp->pmnext <= USB_PMA_SIZE, "pm_alloc(), #1", "PMA overflow"); return next; } diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c index d9c25ecdf..237d8e027 100644 --- a/os/hal/src/serial_usb.c +++ b/os/hal/src/serial_usb.c @@ -124,7 +124,7 @@ static void inotify(GenericQueue *qp) { emptied, then a whole packet is loaded in the queue.*/ if (chIQIsEmptyI(&sdup->iqueue)) { - n = usbReadPacketI(sdup->config->usbp, DATA_AVAILABLE_EP, + n = usbReadPacketI(sdup->config->usbp, USB_CDC_DATA_AVAILABLE_EP, sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE); if (n != USB_ENDPOINT_BUSY) { chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE); @@ -146,7 +146,7 @@ static void onotify(GenericQueue *qp) { /* If there is any data in the output queue then it is sent within a single packet and the queue is emptied.*/ n = chOQGetFullI(&sdup->oqueue); - w = usbWritePacketI(sdup->config->usbp, DATA_REQUEST_EP, + w = usbWritePacketI(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP, sdup->oqueue.q_buffer, n); if (w != USB_ENDPOINT_BUSY) { chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY); @@ -211,10 +211,10 @@ void sduStart(SerialUSBDriver *sdup, const SerialUSBConfig *config) { "sduStart(), #1", "invalid state"); sdup->config = config; - usbStart(config->usbp, &config->usb_config); config->usbp->param = sdup; sdup->state = SDU_READY; chSysUnlock(); + usbStart(config->usbp, &config->usb_config); } /** -- cgit v1.2.3 From 76f8d18aaf60c6d916a799ba3d8b09815da979b2 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Aug 2011 12:57:21 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3261 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/src/serial_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c index 237d8e027..16822502a 100644 --- a/os/hal/src/serial_usb.c +++ b/os/hal/src/serial_usb.c @@ -234,9 +234,9 @@ void sduStop(SerialUSBDriver *sdup) { chDbgAssert((sdup->state == SDU_STOP) || (sdup->state == SDU_READY), "sduStop(), #1", "invalid state"); - usbStop(sdup->config->usbp); sdup->state = SDU_STOP; chSysUnlock(); + usbStop(sdup->config->usbp); } /** -- cgit v1.2.3