Browse Source

Fix DMA on K66

teensy4-core
PaulStoffregen 8 years ago
parent
commit
be42e0574e
2 changed files with 20 additions and 13 deletions
  1. +18
    -13
      teensy3/DMAChannel.cpp
  2. +2
    -0
      teensy3/kinetis.h

+ 18
- 13
teensy3/DMAChannel.cpp View File

@@ -1,8 +1,9 @@
#include "DMAChannel.h"

#if DMA_NUM_CHANNELS > 16
#undef DMA_NUM_CHANNELS
#define DMA_NUM_CHANNELS 16
#if DMA_NUM_CHANNELS <= 16
#define DMA_MAX_CHANNELS DMA_NUM_CHANNELS
#else
#define DMA_MAX_CHANNELS 16
#endif


@@ -22,7 +23,7 @@ void DMAChannel::begin(bool force_initialization)
uint32_t ch = 0;

__disable_irq();
if (!force_initialization && TCD && channel < DMA_NUM_CHANNELS
if (!force_initialization && TCD && channel < DMA_MAX_CHANNELS
&& (dma_channel_allocated_mask & (1 << channel))
&& (uint32_t)TCD == (uint32_t)(0x40009000 + channel * 32)) {
// DMA channel already allocated
@@ -35,10 +36,10 @@ void DMAChannel::begin(bool force_initialization)
__enable_irq();
break;
}
if (++ch >= DMA_NUM_CHANNELS) {
if (++ch >= DMA_MAX_CHANNELS) {
__enable_irq();
TCD = (TCD_t *)0;
channel = DMA_NUM_CHANNELS;
channel = DMA_MAX_CHANNELS;
return; // no more channels available
// attempts to use this object will hardfault
}
@@ -46,7 +47,11 @@ void DMAChannel::begin(bool force_initialization)
channel = ch;
SIM_SCGC7 |= SIM_SCGC7_DMA;
SIM_SCGC6 |= SIM_SCGC6_DMAMUX;
DMA_CR = DMA_CR_EMLM | DMA_CR_EDBG ; // minor loop mapping is available
#if DMA_NUM_CHANNELS <= 16
DMA_CR = DMA_CR_EMLM | DMA_CR_EDBG; // minor loop mapping is available
#else
DMA_CR = DMA_CR_GRP1PRI| DMA_CR_EMLM | DMA_CR_EDBG;
#endif
DMA_CERQ = ch;
DMA_CERR = ch;
DMA_CEEI = ch;
@@ -65,12 +70,12 @@ void DMAChannel::begin(bool force_initialization)

void DMAChannel::release(void)
{
if (channel >= DMA_NUM_CHANNELS) return;
if (channel >= DMA_MAX_CHANNELS) return;
DMA_CERQ = channel;
__disable_irq();
dma_channel_allocated_mask &= ~(1 << channel);
__enable_irq();
channel = DMA_NUM_CHANNELS;
channel = DMA_MAX_CHANNELS;
TCD = (TCD_t *)0;
}

@@ -106,7 +111,7 @@ void DMAChannel::begin(bool force_initialization)
uint32_t ch = 0;

__disable_irq();
if (!force_initialization && CFG && channel < DMA_NUM_CHANNELS
if (!force_initialization && CFG && channel < DMA_MAX_CHANNELS
&& (dma_channel_allocated_mask & (1 << channel))
&& (uint32_t)CFG == (uint32_t)(0x40008100 + channel * 16)) {
// DMA channel already allocated
@@ -119,10 +124,10 @@ void DMAChannel::begin(bool force_initialization)
__enable_irq();
break;
}
if (++ch >= DMA_NUM_CHANNELS) {
if (++ch >= DMA_MAX_CHANNELS) {
__enable_irq();
CFG = (CFG_t *)0;
channel = DMA_NUM_CHANNELS;
channel = DMA_MAX_CHANNELS;
return; // no more channels available
// attempts to use this object will hardfault
}
@@ -139,7 +144,7 @@ void DMAChannel::begin(bool force_initialization)

void DMAChannel::release(void)
{
if (channel >= DMA_NUM_CHANNELS) return;
if (channel >= DMA_MAX_CHANNELS) return;
CFG->DSR_BCR = DMA_DSR_BCR_DONE;
__disable_irq();
dma_channel_allocated_mask &= ~(1 << channel);

+ 2
- 0
teensy3/kinetis.h View File

@@ -1820,6 +1820,8 @@ enum IRQ_NUMBER_t {
#define DMA_DCHPRI30 (*(volatile uint8_t *)0x4000811D) // Channel n Priority Register
#define DMA_DCHPRI29 (*(volatile uint8_t *)0x4000811E) // Channel n Priority Register
#define DMA_DCHPRI28 (*(volatile uint8_t *)0x4000811F) // Channel n Priority Register
#define DMA_CR_GRP0PRI ((uint32_t)0x100)
#define DMA_CR_GRP1PRI ((uint32_t)0x400)
#endif

#define DMA_TCD_ATTR_SMOD(n) (((n) & 0x1F) << 11)

Loading…
Cancel
Save