473 lines
13 KiB
C
473 lines
13 KiB
C
/* ----------------------------------------------------------------------
|
|
* Copyright (C) 2015 ARM Limited. All rights reserved.
|
|
*
|
|
* $Date: 27. August 2013
|
|
* $Revision: V1.2
|
|
*
|
|
* Project: DMA Driver for ST STM32F10x
|
|
* -------------------------------------------------------------------- */
|
|
|
|
/* History:
|
|
* Version 1.2
|
|
* DMAx_Channel variable is checked for initialized channels in DMA_ChannelUninitialize function
|
|
* Version 1.1
|
|
* DMA2 peripheral added to build when HD, XL, HD_VL or CL device is used
|
|
* Version 1.0
|
|
* Initial release
|
|
*/
|
|
|
|
#include "DMA_STM32F10x.h"
|
|
|
|
#if defined(STM32F10X_HD) || defined(STM32F10X_XL) || \
|
|
defined(STM32F10X_HD_VL) || defined(STM32F10X_CL)
|
|
/* DMA2 peripheral exists on HD, XL, HD_VL and CL devices */
|
|
#define STM32F10X_ENABLE_DMA2
|
|
#endif
|
|
|
|
/// DMA Variables
|
|
static uint8_t DMA1_Channel; // Used DMA1 Channels
|
|
#if defined (STM32F10X_ENABLE_DMA2)
|
|
static uint8_t DMA2_Channel; // Used DMA2 Channels
|
|
#endif
|
|
|
|
|
|
/// DMA Functions
|
|
|
|
/**
|
|
\fn void DMA_ChannelInitialize (uint32_t dma, uint32_t channel)
|
|
\brief Initialize DMA Channel
|
|
\param[in] dma DMA number
|
|
\param[in] channel DMA channel number
|
|
*/
|
|
void DMA_ChannelInitialize (uint32_t dma, uint32_t channel) {
|
|
|
|
switch (dma) {
|
|
case 1:
|
|
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
|
|
switch (channel) {
|
|
case 1:
|
|
DMA1_Channel1->CCR = 0;
|
|
DMA1->IFCR = DMA_IFCR_CGIF1 | DMA_IFCR_CTEIF1 |
|
|
DMA_IFCR_CHTIF1 | DMA_IFCR_CTCIF1;
|
|
NVIC_ClearPendingIRQ(DMA1_Channel1_IRQn);
|
|
NVIC_EnableIRQ(DMA1_Channel1_IRQn);
|
|
break;
|
|
case 2:
|
|
DMA1_Channel2->CCR = 0;
|
|
DMA1->IFCR = DMA_IFCR_CGIF2 | DMA_IFCR_CTEIF2 |
|
|
DMA_IFCR_CHTIF2 | DMA_IFCR_CTCIF2;
|
|
NVIC_ClearPendingIRQ(DMA1_Channel2_IRQn);
|
|
NVIC_EnableIRQ(DMA1_Channel2_IRQn);
|
|
break;
|
|
case 3:
|
|
DMA1_Channel3->CCR = 0;
|
|
DMA1->IFCR = DMA_IFCR_CGIF3 | DMA_IFCR_CTEIF3 |
|
|
DMA_IFCR_CHTIF3 | DMA_IFCR_CTCIF3;
|
|
NVIC_ClearPendingIRQ(DMA1_Channel3_IRQn);
|
|
NVIC_EnableIRQ(DMA1_Channel3_IRQn);
|
|
break;
|
|
case 4:
|
|
DMA1_Channel4->CCR = 0;
|
|
DMA1->IFCR = DMA_IFCR_CGIF4 | DMA_IFCR_CTEIF4 |
|
|
DMA_IFCR_CHTIF4 | DMA_IFCR_CTCIF4;
|
|
NVIC_ClearPendingIRQ(DMA1_Channel4_IRQn);
|
|
NVIC_EnableIRQ(DMA1_Channel4_IRQn);
|
|
break;
|
|
case 5:
|
|
DMA1_Channel5->CCR = 0;
|
|
DMA1->IFCR = DMA_IFCR_CGIF5 | DMA_IFCR_CTEIF5 |
|
|
DMA_IFCR_CHTIF5 | DMA_IFCR_CTCIF5;
|
|
NVIC_ClearPendingIRQ(DMA1_Channel5_IRQn);
|
|
NVIC_EnableIRQ(DMA1_Channel5_IRQn);
|
|
break;
|
|
case 6:
|
|
DMA1_Channel6->CCR = 0;
|
|
DMA1->IFCR = DMA_IFCR_CGIF6 | DMA_IFCR_CTEIF6 |
|
|
DMA_IFCR_CHTIF6 | DMA_IFCR_CTCIF6;
|
|
NVIC_ClearPendingIRQ(DMA1_Channel6_IRQn);
|
|
NVIC_EnableIRQ(DMA1_Channel6_IRQn);
|
|
break;
|
|
case 7:
|
|
DMA1_Channel7->CCR = 0;
|
|
DMA1->IFCR = DMA_IFCR_CGIF7 | DMA_IFCR_CTEIF7 |
|
|
DMA_IFCR_CHTIF7 | DMA_IFCR_CTCIF7;
|
|
NVIC_ClearPendingIRQ(DMA1_Channel7_IRQn);
|
|
NVIC_EnableIRQ(DMA1_Channel7_IRQn);
|
|
break;
|
|
}
|
|
DMA1_Channel |= 1 << channel;
|
|
break;
|
|
|
|
#if defined (STM32F10X_ENABLE_DMA2)
|
|
case 2:
|
|
RCC->AHBENR |= RCC_AHBENR_DMA2EN;
|
|
switch (channel) {
|
|
case 1:
|
|
DMA2_Channel1->CCR = 0;
|
|
DMA2->IFCR = DMA_IFCR_CGIF1 | DMA_IFCR_CTEIF1 |
|
|
DMA_IFCR_CHTIF1 | DMA_IFCR_CTCIF1;
|
|
NVIC_ClearPendingIRQ(DMA2_Channel1_IRQn);
|
|
NVIC_EnableIRQ(DMA2_Channel1_IRQn);
|
|
break;
|
|
case 2:
|
|
DMA2_Channel2->CCR = 0;
|
|
DMA2->IFCR = DMA_IFCR_CGIF2 | DMA_IFCR_CTEIF2 |
|
|
DMA_IFCR_CHTIF2 | DMA_IFCR_CTCIF2;
|
|
NVIC_ClearPendingIRQ(DMA2_Channel2_IRQn);
|
|
NVIC_EnableIRQ(DMA2_Channel2_IRQn);
|
|
break;
|
|
case 3:
|
|
DMA2_Channel3->CCR = 0;
|
|
DMA2->IFCR = DMA_IFCR_CGIF3 | DMA_IFCR_CTEIF3 |
|
|
DMA_IFCR_CHTIF3 | DMA_IFCR_CTCIF3;
|
|
NVIC_ClearPendingIRQ(DMA2_Channel3_IRQn);
|
|
NVIC_EnableIRQ(DMA2_Channel3_IRQn);
|
|
break;
|
|
case 4:
|
|
DMA2_Channel4->CCR = 0;
|
|
DMA2->IFCR = DMA_IFCR_CGIF4 | DMA_IFCR_CTEIF4 |
|
|
DMA_IFCR_CHTIF4 | DMA_IFCR_CTCIF4;
|
|
|
|
#if defined (STM32F10X_CL)
|
|
NVIC_ClearPendingIRQ(DMA2_Channel4_IRQn);
|
|
NVIC_EnableIRQ(DMA2_Channel4_IRQn);
|
|
#else
|
|
NVIC_ClearPendingIRQ(DMA2_Channel4_5_IRQn);
|
|
NVIC_EnableIRQ(DMA2_Channel4_5_IRQn);
|
|
#endif
|
|
break;
|
|
case 5:
|
|
DMA2_Channel5->CCR = 0;
|
|
DMA2->IFCR = DMA_IFCR_CGIF5 | DMA_IFCR_CTEIF5 |
|
|
DMA_IFCR_CHTIF5 | DMA_IFCR_CTCIF5;
|
|
|
|
#if defined (STM32F10X_CL)
|
|
NVIC_ClearPendingIRQ(DMA2_Channel5_IRQn);
|
|
NVIC_EnableIRQ(DMA2_Channel5_IRQn);
|
|
#elif defined (STM32F10X_HD_VL)
|
|
if (AFIO->MAPR2 & AFIO_MAPR2_MISC_REMAP) {
|
|
/* DMA2 Channel 5 mapped at position 60 */
|
|
NVIC_ClearPendingIRQ(DMA2_Channel5_IRQn);
|
|
NVIC_EnableIRQ(DMA2_Channel5_IRQn);
|
|
}
|
|
else {
|
|
NVIC_ClearPendingIRQ(DMA2_Channel4_5_IRQn);
|
|
NVIC_EnableIRQ(DMA2_Channel4_5_IRQn);
|
|
}
|
|
#else
|
|
NVIC_ClearPendingIRQ(DMA2_Channel4_5_IRQn);
|
|
NVIC_EnableIRQ(DMA2_Channel4_5_IRQn);
|
|
#endif
|
|
break;
|
|
}
|
|
DMA2_Channel |= 1 << channel;
|
|
break;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/**
|
|
\fn void DMA_ChannelUninitialize (uint32_t dma, uint32_t channel)
|
|
\brief Uninitialize DMA Channel
|
|
\param[in] dma DMA number
|
|
\param[in] channel DMA channel number
|
|
*/
|
|
void DMA_ChannelUninitialize (uint32_t dma, uint32_t channel) {
|
|
|
|
switch (dma) {
|
|
case 1:
|
|
if (DMA1_Channel == 0) {
|
|
// All DMA1 Channels are uninitialized
|
|
return;
|
|
}
|
|
switch (channel) {
|
|
case 1:
|
|
NVIC_DisableIRQ(DMA1_Channel1_IRQn);
|
|
DMA1_Channel1->CCR = 0;
|
|
break;
|
|
case 2:
|
|
NVIC_DisableIRQ(DMA1_Channel2_IRQn);
|
|
DMA1_Channel2->CCR = 0;
|
|
break;
|
|
case 3:
|
|
NVIC_DisableIRQ(DMA1_Channel3_IRQn);
|
|
DMA1_Channel3->CCR = 0;
|
|
break;
|
|
case 4:
|
|
NVIC_DisableIRQ(DMA1_Channel4_IRQn);
|
|
DMA1_Channel4->CCR = 0;
|
|
break;
|
|
case 5:
|
|
NVIC_DisableIRQ(DMA1_Channel5_IRQn);
|
|
DMA1_Channel5->CCR = 0;
|
|
break;
|
|
case 6:
|
|
NVIC_DisableIRQ(DMA1_Channel6_IRQn);
|
|
DMA1_Channel6->CCR = 0;
|
|
break;
|
|
case 7:
|
|
NVIC_DisableIRQ(DMA1_Channel7_IRQn);
|
|
DMA1_Channel7->CCR = 0;
|
|
break;
|
|
}
|
|
DMA1_Channel &= ~(1 << channel);
|
|
if (DMA1_Channel == 0){
|
|
RCC->AHBENR &= ~RCC_AHBENR_DMA1EN;
|
|
}
|
|
break;
|
|
|
|
#if defined (STM32F10X_ENABLE_DMA2)
|
|
case 2:
|
|
if (DMA2_Channel == 0) {
|
|
// All DMA2 Channels are uninitialized
|
|
return;
|
|
}
|
|
switch (channel) {
|
|
case 1:
|
|
NVIC_DisableIRQ(DMA2_Channel1_IRQn);
|
|
DMA2_Channel1->CCR = 0;
|
|
break;
|
|
case 2:
|
|
NVIC_DisableIRQ(DMA2_Channel2_IRQn);
|
|
DMA2_Channel2->CCR = 0;
|
|
break;
|
|
case 3:
|
|
NVIC_DisableIRQ(DMA2_Channel3_IRQn);
|
|
DMA2_Channel3->CCR = 0;
|
|
break;
|
|
case 4:
|
|
#if defined (STM32F10X_CL)
|
|
NVIC_DisableIRQ(DMA2_Channel4_IRQn);
|
|
#else
|
|
/* If Channel 5 disabled, disable also Channel 4 */
|
|
if (!(DMA2_Channel & (1 << 5))) {
|
|
NVIC_DisableIRQ(DMA2_Channel4_5_IRQn);
|
|
}
|
|
#endif
|
|
DMA2_Channel4->CCR = 0;
|
|
break;
|
|
case 5:
|
|
#if defined (STM32F10X_CL)
|
|
NVIC_DisableIRQ(DMA2_Channel5_IRQn);
|
|
#elif defined (STM32F10X_HD_VL)
|
|
if (AFIO->MAPR2 & AFIO_MAPR2_MISC_REMAP) {
|
|
/* DMA2 Channel 5 mapped at position 60 */
|
|
NVIC_DisableIRQ(DMA2_Channel5_IRQn);
|
|
}
|
|
else {
|
|
/* If Channel 4 disabled, disable also Channel 5 */
|
|
if (!(DMA2_Channel & (1 << 4))) {
|
|
NVIC_DisableIRQ(DMA2_Channel4_5_IRQn);
|
|
}
|
|
}
|
|
#else
|
|
/* If Channel 4 disabled, disable also Channel 5 */
|
|
if (!(DMA2_Channel & (1 << 4))) {
|
|
NVIC_DisableIRQ(DMA2_Channel4_5_IRQn);
|
|
}
|
|
#endif
|
|
DMA2_Channel5->CCR = 0;
|
|
break;
|
|
}
|
|
DMA2_Channel &= ~(1 << channel);
|
|
if (DMA2_Channel == 0){
|
|
RCC->AHBENR &= ~RCC_AHBENR_DMA2EN;
|
|
}
|
|
break;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
/// DMA1 Channel Events
|
|
__weak void DMA1_Channel1_Event (uint32_t event) {;}
|
|
__weak void DMA1_Channel2_Event (uint32_t event) {;}
|
|
__weak void DMA1_Channel3_Event (uint32_t event) {;}
|
|
__weak void DMA1_Channel4_Event (uint32_t event) {;}
|
|
__weak void DMA1_Channel5_Event (uint32_t event) {;}
|
|
__weak void DMA1_Channel6_Event (uint32_t event) {;}
|
|
__weak void DMA1_Channel7_Event (uint32_t event) {;}
|
|
|
|
|
|
#if defined (STM32F10X_ENABLE_DMA2)
|
|
/// DMA2 Channel Events
|
|
__weak void DMA2_Channel1_Event (uint32_t event) {;}
|
|
__weak void DMA2_Channel2_Event (uint32_t event) {;}
|
|
__weak void DMA2_Channel3_Event (uint32_t event) {;}
|
|
__weak void DMA2_Channel4_Event (uint32_t event) {;}
|
|
__weak void DMA2_Channel5_Event (uint32_t event) {;}
|
|
#endif
|
|
|
|
/**
|
|
\fn void DMA1_Channel1_IRQHandler (void)
|
|
\brief DMA1 Channel0 interrupt handler
|
|
*/
|
|
void DMA1_Channel1_IRQHandler (void) {
|
|
uint32_t events;
|
|
|
|
events = (DMA1->ISR >> 0) & DMA_CHANNEL_FLAGS;
|
|
DMA1->IFCR = events << 0;
|
|
DMA1_Channel1_Event(events);
|
|
}
|
|
|
|
/**
|
|
\fn void DMA1_Channel2_IRQHandler (void)
|
|
\brief DMA1 Channel2 interrupt handler
|
|
*/
|
|
void DMA1_Channel2_IRQHandler (void) {
|
|
uint32_t events;
|
|
|
|
events = (DMA1->ISR >> 4) & DMA_CHANNEL_FLAGS;
|
|
DMA1->IFCR = events << 4;
|
|
DMA1_Channel2_Event(events);
|
|
}
|
|
|
|
/**
|
|
\fn void DMA1_Channel3_IRQHandler (void)
|
|
\brief DMA1 Channel3 interrupt handler
|
|
*/
|
|
void DMA1_Channel3_IRQHandler (void) {
|
|
uint32_t events;
|
|
|
|
events = (DMA1->ISR >> 8) & DMA_CHANNEL_FLAGS;
|
|
DMA1->IFCR = events << 8;
|
|
DMA1_Channel3_Event(events);
|
|
}
|
|
|
|
/**
|
|
\fn void DMA1_Channel4_IRQHandler (void)
|
|
\brief DMA1 Channel4 interrupt handler
|
|
*/
|
|
void DMA1_Channel4_IRQHandler (void) {
|
|
uint32_t events;
|
|
|
|
events = (DMA1->ISR >> 12) & DMA_CHANNEL_FLAGS;
|
|
DMA1->IFCR = events << 12;
|
|
DMA1_Channel4_Event(events);
|
|
}
|
|
|
|
/**
|
|
\fn void DMA1_Channel5_IRQHandler (void)
|
|
\brief DMA1 Channel5 interrupt handler
|
|
*/
|
|
void DMA1_Channel5_IRQHandler (void) {
|
|
uint32_t events;
|
|
|
|
events = (DMA1->ISR >> 16) & DMA_CHANNEL_FLAGS;
|
|
DMA1->IFCR = events << 16;
|
|
DMA1_Channel5_Event(events);
|
|
}
|
|
|
|
/**
|
|
\fn void DMA1_Channel6_IRQHandler (void)
|
|
\brief DMA1 Channel6 interrupt handler
|
|
*/
|
|
void DMA1_Channel6_IRQHandler (void) {
|
|
uint32_t events;
|
|
|
|
events = (DMA1->ISR >> 20) & DMA_CHANNEL_FLAGS;
|
|
DMA1->IFCR = events << 20;
|
|
DMA1_Channel6_Event(events);
|
|
}
|
|
|
|
/**
|
|
\fn void DMA1_Channel7_IRQHandler (void)
|
|
\brief DMA1 Channel7 interrupt handler
|
|
*/
|
|
void DMA1_Channel7_IRQHandler (void) {
|
|
uint32_t events;
|
|
|
|
events = (DMA1->ISR >> 24) & DMA_CHANNEL_FLAGS;
|
|
DMA1->IFCR = events << 24;
|
|
DMA1_Channel7_Event(events);
|
|
}
|
|
|
|
|
|
#if defined (STM32F10X_ENABLE_DMA2)
|
|
/**
|
|
\fn void DMA2_Channel1_IRQHandler (void)
|
|
\brief DMA2 Channel1 interrupt handler
|
|
*/
|
|
void DMA2_Channel1_IRQHandler (void) {
|
|
uint32_t events;
|
|
|
|
events = (DMA2->ISR >> 0) & DMA_CHANNEL_FLAGS;
|
|
DMA2->IFCR = events << 0;
|
|
DMA2_Channel1_Event(events);
|
|
}
|
|
|
|
/**
|
|
\fn void DMA2_Channel2_IRQHandler (void)
|
|
\brief DMA2 Channel2 interrupt handler
|
|
*/
|
|
void DMA2_Channel2_IRQHandler (void) {
|
|
uint32_t events;
|
|
|
|
events = (DMA2->ISR >> 4) & DMA_CHANNEL_FLAGS;
|
|
DMA2->IFCR = events << 4;
|
|
DMA2_Channel2_Event(events);
|
|
}
|
|
|
|
/**
|
|
\fn void DMA2_Channel3_IRQHandler (void)
|
|
\brief DMA2 Channel3 interrupt handler
|
|
*/
|
|
void DMA2_Channel3_IRQHandler (void) {
|
|
uint32_t events;
|
|
|
|
events = (DMA2->ISR >> 8) & DMA_CHANNEL_FLAGS;
|
|
DMA2->IFCR = events << 8;
|
|
DMA2_Channel3_Event(events);
|
|
}
|
|
|
|
#if !defined(STM32F10X_CL)
|
|
/**
|
|
\fn void DMA2_Channel4_IRQHandler (void)
|
|
\brief DMA2 Channel4 interrupt handler
|
|
*/
|
|
void DMA2_Channel4_IRQHandler (void) {
|
|
uint32_t events;
|
|
|
|
events = (DMA2->ISR >> 12) & DMA_CHANNEL_FLAGS;
|
|
DMA2->IFCR = events << 12;
|
|
DMA2_Channel4_Event(events);
|
|
}
|
|
#endif
|
|
|
|
#if defined(STM32F10X_HD_VL) || defined (STM32F10X_CL)
|
|
/**
|
|
\fn void DMA2_Channel5_IRQHandler (void)
|
|
\brief DMA2 Channel5 interrupt handler
|
|
*/
|
|
void DMA2_Channel5_IRQHandler (void) {
|
|
uint32_t events;
|
|
|
|
events = (DMA2->ISR >> 16) & DMA_CHANNEL_FLAGS;
|
|
DMA2->IFCR = events << 16;
|
|
DMA2_Channel5_Event(events);
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
\fn void DMA2_Channel4_5_IRQHandler (void)
|
|
\brief DMA2 Channel 4 and 5 interrupt handler
|
|
*/
|
|
void DMA2_Channel4_5_IRQHandler (void) {
|
|
uint32_t events;
|
|
|
|
events = (DMA2->ISR >> 12) & DMA_CHANNEL_FLAGS;
|
|
if (events) {
|
|
/* Channel 4 events */
|
|
DMA2->IFCR = events << 12;
|
|
DMA2_Channel4_Event(events);
|
|
}
|
|
|
|
events = (DMA2->ISR >> 16) & DMA_CHANNEL_FLAGS;
|
|
if (events) {
|
|
/* Channel 5 events */
|
|
DMA2->IFCR = events << 16;
|
|
DMA2_Channel5_Event(events);
|
|
}
|
|
}
|
|
#endif
|