Is it possible to do this? Or is there a better way?
If it is possible to do this would anyone be able to guide me as to what I am doing wrong?
I'm trying to go through the Atmel documentation for the DMAC, but it is quite dense. I have seen a few examples through SPI, but some things are still unclear.
I have this so far, but it doesn't work.
int dataBlock[10] = {1,0,1,0,1,0,1,0,1,0};
void setup() {
pmc_set_writeprotect(false);
pmc_enable_periph_clk(ID_DMAC);
DMAC->DMAC_EN = DMAC_EN_ENABLE;
DMAC->DMAC_GCFG = DMAC_GCFG_ARB_CFG_FIXED;
DMAC->DMAC_CHDR = DMAC_CHDR_DIS0;
DMAC->DMAC_CH_NUM[0].DMAC_SADDR = (uint32_t)dataBlock;
DMAC->DMAC_CH_NUM[0].DMAC_DADDR = (uint32_t)REG_PIOC_SODR; //I know this is wrong (but im not sure what else would work here) since SODR will set pins high, but a 0 won't do anything.
DMAC->DMAC_CH_NUM[0].DMAC_DSCR = 0;
DMAC->DMAC_CH_NUM[0].DMAC_CTRLA = DMAC_CTRLA_SRC_WIDTH_BYTE //I labeled the array as an int would that affect this?
| DMAC_CTRLA_DST_WIDTH_BYTE;
DMAC->DMAC_CH_NUM[0].DMAC_CTRLB = DMAC_CTRLB_SRC_INCR_INCREMENTING
| DMAC_CTRLB_SRC_DSCR_FETCH_DISABLE
| DMAC_CTRLB_DST_INCR_FIXED
| DMAC_CTRLB_DST_DSCR_FETCH_DISABLE
| DMAC_CTRLB_FC_MEM2PER_DMA_FC;
DMAC->DMAC_CH_NUM[0].DMAC_CFG = DMAC_CFG_DST_H2SEL_HW
| DMAC_CFG_DST_PER(13); //(where can i find information on this? I thought this might be from chapter 9 of the Atmel Documentation, the instance ID of a periph, In this case ID 13 is related to PIOC)
DMAC->DMAC_CHER = DMAC_CHER_ENA0;
}
void loop() {}
A DMA would be useful if you would want to set or clear a pin repeatedly, although you would have to trigger an interrupt with a completed DMA action to pace the pin toggling, resulting in a lot of lost clock cycles, or copy a variable to a pin without a defined pace with an List Linked Item (LLI) . But if you want to toggle a pin only once, a DMA is useless.
Use PIO_ODSR with an XOR to toggle a pin, e.g; :
PIOB->PIO_ODSR ^= PIO_ODSR_P27; // Toggle PIOB27
Here is an example sketch (not fully tested though) to copy repeatedly a pin state to a variable with a DMA.
Yup, I am trying to see If I can toggle a digital pin multiple times with the DMA. (I guess another possibility would be to adjust the Duty cycle of a PWM wave, and store the duty cycle values in a DMA? Ideally I would like to be able to control how long a toggle duration is, if that makes sense)
Is there anyway to tie a timer to the DMA so that it only transfers once when the timer counter reaches a specific value? I know the DAC can be configured in a similar way where it outputs a new voltage level once the timer counter value has been reached,
I'd got the same problem with the SAM3 chip. It looks like that there isn't any possibility to trigger the DMA transfer from some timer (PWM or one of TCs). I wrote to the Microchip support https://microchipsupport.force.com/5001N00000iq9tm, but they didn't answered me anything useful so far.
First one, a PDC DMA with synchro channels. That is very useful whenever you want e.g. output 3 PWM waves, 120° out of phase from each other. This DMA is from a buffer to PWM channels.
Second one, a AHB DMA. BUT, a register is missing in the documentation AND in the PWM.h header file, BUT you can see a PWM AHB DMA in AHB DMA chapter. All you have to do is creat the missing PWM register (PWM_DMAR), the same you can find in SAM7 PWM header file ( I mean with the exact same offset). This register gives the same possibility to output and automatically dispatch a buffer to all synchro channels, plus the possibility of a transfer from a peripheral to the PWM peripheral.