DMA to PLL?

Status
Not open for further replies.

Frank B

Senior Member
Hi,

i can't get DMA to PLL working.. the destination is CCM_ANALOG_PLL_VIDEO_NUM (0x400D80B0)
Is there any special reason that prevents DMA-writes (uint32_t) to this address ?

(i need this for a special kind of application..)
 
It should work.

Is the DMA transfer ending with error status? Or does it complete but without any observable effect?
 
yes, always post complete code:
Code:
#include <DMAChannel.h>

#define SAMPLES 128
__attribute__((aligned(32))) static uint32_t fm_tx_buffer[SAMPLES];

DMAChannel dma(false);
volatile uint32_t target;

#define TEST 0 // or 1 for variable

void setup() {

  target = 0;
  for (int i = 0; i < SAMPLES; i++) 
   fm_tx_buffer[i] = i | (i<<8) | (i<< 16) | (i<<24);
   
  dma.begin(true);
  dma.TCD->SADDR = fm_tx_buffer;
  dma.TCD->SOFF = 4;
  dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(2) | DMA_TCD_ATTR_DSIZE(2);
  dma.TCD->NBYTES_MLNO = 4;
  dma.TCD->SLAST = -sizeof(fm_tx_buffer);
  dma.TCD->DOFF = 0;
  dma.TCD->CITER_ELINKNO = sizeof(fm_tx_buffer) / 4;
  dma.TCD->DLASTSGA = 0;
  dma.TCD->BITER_ELINKNO = sizeof(fm_tx_buffer) / 4;
  
#if TEST
  dma.TCD->DADDR = &target;
#else  
  dma.TCD->DADDR = (void *)((uint32_t)&CCM_ANALOG_PLL_VIDEO_NUM);
#endif
  dma.enable();
  dma.clearError();
}

int z = 0;
void loop() {  
  
  Serial.printf("%x %0x %0x",z, dma.TCD->SADDR, dma.TCD->DADDR);
  dma.triggerManual();   z++;  
  Serial.printf(": %0x\n", target);  
  if (dma.error()) Serial.println("ERROR");
  delay(500); 
}

with #define TEST 0 it uses the PLL as target. use 1 for working demo with variable.
 
Looks like it's working but you're printing the wrong thing in loop().

Run this...

Code:
#include <DMAChannel.h>

#define SAMPLES 128
__attribute__((aligned(32))) static uint32_t fm_tx_buffer[SAMPLES];

DMAChannel dma(false);

#define TEST 0 // or 0 for PLL

#if TEST != 0
// don't even create this variable when using TEST is 0
// so it can't be accidentally used by mistake from leftover code
volatile uint32_t target = 0;
#endif

void setup() {

  for (int i = 0; i < SAMPLES; i++) 
   fm_tx_buffer[i] = i | (i<<8) | (i<< 16) | (i<<24);
   
  dma.begin(true);
  dma.TCD->SADDR = fm_tx_buffer;
  dma.TCD->SOFF = 4;
  dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(2) | DMA_TCD_ATTR_DSIZE(2);
  dma.TCD->NBYTES_MLNO = 4;
  dma.TCD->SLAST = -sizeof(fm_tx_buffer);
  dma.TCD->DOFF = 0;
  dma.TCD->CITER_ELINKNO = sizeof(fm_tx_buffer) / 4;
  dma.TCD->DLASTSGA = 0;
  dma.TCD->BITER_ELINKNO = sizeof(fm_tx_buffer) / 4;
  
#if TEST
  dma.TCD->DADDR = &target;
#else  
  dma.TCD->DADDR = (void *)((uint32_t)&CCM_ANALOG_PLL_VIDEO_NUM);
#endif
  dma.enable();
}

int z = 0;
void loop() {  
  
  Serial.printf("%x %0x %0x",z, dma.TCD->SADDR, dma.TCD->DADDR);
  dma.triggerManual();   z++;
#if TEST
  Serial.printf(": %0x\n", target);  
#else
  Serial.printf(": %0x\n", CCM_ANALOG_PLL_VIDEO_NUM); 
#endif
  delay(500); 
}
 
LOL

Your're right, of course.
That comes from too much editing...

THANK YOU

I stop editing code for today.
 
Status
Not open for further replies.
Back
Top