I just received my PIC32 starter kit, and played with the demos. I have never used any higher-end uCs than the 8-bit PICs.
One of the new things to me in the PIC32 is DMA. The starter kit came with demo that uses chained DMA transfers to control the pwms and dim two of the leds.
I tried to experiment adding the third led to the chain, but it didn't work out. I believe it is because I don't know how to chain the three DMA channels.
Basically I am trying to get a chain: DMACh0 -> DMACh1 -> DMAch2 -> DMACh0 -> ...
Here is one of the modified versions (Some stock comments and config cut out to get it smaller):
const unsigned short pwm_duty_cycles[] = {...};
#define ARRAY_SIZE (sizeof(pwm_duty_cycles))
#define DMA0 (0)
#define DMA1 (1)
#define DMA2 (2) // Added this line
unsigned char srcSize = ARRAY_SIZE;
unsigned char cellSize = 2;
unsigned int dstSize = 2;
unsigned short* volatile pDma_0_Dst = (void*) &OC1RS;
unsigned short* volatile pDma_1_Dst = (void*) &OC2RS;
unsigned short* volatile pDma_2_Dst = (void*) &OC3RS; // Also added this
const unsigned short* pDmaSrc = pwm_duty_cycles;
#define SYS_FREQ (80000000)
#define PWM_PERIOD (25000)
// pwm_dma application code
int main(void)
{
SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
DmaChnOpen(DMA0, 0, DMA_OPEN_CHAIN_LOW);
DmaChnOpen(DMA1, 0, DMA_OPEN_CHAIN_HI);
DmaChnOpen(DMA2, 0, DMA_OPEN_CHAIN_HI); // Added this line, I'm not sure how to set up the
// chaining. What should be LOW and what should be HIGH
DmaChnSetEventControl(DMA0, DMA_EV_START_IRQ(_TIMER_4_IRQ));
DmaChnSetEventControl(DMA1, DMA_EV_START_IRQ(_TIMER_4_IRQ));
DmaChnSetEventControl(DMA1, DMA_EV_START_IRQ(_TIMER_4_IRQ)); // Added
DmaChnSetTxfer(DMA0, pDmaSrc, pDma_0_Dst, srcSize, dstSize, cellSize);
DmaChnSetTxfer(DMA1, pDmaSrc, pDma_1_Dst, srcSize, dstSize, cellSize);
DmaChnSetTxfer(DMA2, pDmaSrc, pDma_2_Dst, srcSize, dstSize, cellSize); // Added
OpenOC1(OC_ON | OC_TIMER_MODE16 | OC_TIMER3_SRC | OC_PWM_FAULT_PIN_DISABLE, 0,0);
OpenOC2(OC_ON | OC_TIMER_MODE16 | OC_TIMER3_SRC | OC_PWM_FAULT_PIN_DISABLE, 0,0);
OpenOC3(OC_ON | OC_TIMER_MODE16 | OC_TIMER3_SRC | OC_PWM_FAULT_PIN_DISABLE, 0,0); // Added
OpenTimer3(T3_ON | T3_PS_1_64, PWM_PERIOD);
OpenTimer4(T4_ON | T4_PS_1_256, 100000);
DmaChnEnable(DMA0);
while(1);
}
I think the problem is with setting DMA_OPEN_CHAIN_LOWs and DMA_OPEN_CHAIN_HIs. I assume these HI and LOW mean the channel priorities. These only allow me to specify the next channel with either higher or lower priority. How can I make it jump over a channel (ch2 -> ch0)?
I am using Mplab C32 v2.02. This brings up memories, trying to modify the examples to get one more led blink :)