Пример добавления третьего канала в стартовый комплект PIC32 «цепочка DMA и ШИМ»

Я только что получил свой стартовый комплект PIC32 и поиграл с демонстрационными версиями. Я никогда не использовал более совершенные uC, чем 8-битные PIC.

Одной из новых вещей в PIC32 для меня является DMA. Стартовый комплект поставляется с демонстрацией, в которой используются цепные передачи DMA для управления ШИМ и затемнения двух светодиодов.

Пробовал экспериментировать с добавлением третьего вывода в цепочку, но не вышло. Я считаю, что это потому, что я не знаю, как связать три канала прямого доступа к памяти.

В основном я пытаюсь получить цепочку: DMACh0 -> DMACh1 -> DMAch2 -> DMACh0 -> ...

Вот одна из модифицированных версий (некоторые стандартные комментарии и конфиг вырезаны, чтобы уменьшить размер):

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);
}

Я думаю, проблема в настройке DMA_OPEN_CHAIN_LOW и DMA_OPEN_CHAIN_HI. Я предполагаю, что эти HI и LOW означают приоритеты канала. Они только позволяют мне указать следующий канал с более высоким или более низким приоритетом. Как я могу перепрыгнуть через канал (ch2 -> ch0)?

Я использую Mplab C32 v2.02. Это вызывает воспоминания, пытаясь изменить примеры, чтобы получить еще одно мигание светодиода :)

Позвоните в службу технической поддержки PIC для получения образцов кода. Вот лист с ошибками, у вас может не быть . datasheetarchive.com/indexdl/Datasheet-075/DSAE005205.pdf
@TonyStewart Есть ли что-то важное в этой опечатке, которую я, кажется, не могу заметить? Это для конкретной версии dsPIC

Ответы (1)

Причина объясняется в справочном руководстве по контроллеру DMA PIC32MX (стр. 31-35):

Канал (ведомый канал) может быть связан с соседним каналом (главным каналом).

Это означает, что вы не можете связать вместе 3 канала DMA.

Но чтобы ответить на ваш вопрос о том, как работает эта цепочка, посмотрите на стр. 31-16 в руководстве:

CHCHNS: бит выбора канала цепочки (5)

1 = Привязка к каналу с более низким естественным приоритетом (канал 1 будет включен после завершения передачи канала 2)

0 = Привязка к каналу с более высоким естественным приоритетом (канал 1 будет включен после завершения передачи канала 0)

Канал 0 имеет самый высокий приоритет, а канал 3 — самый низкий (у Pic32MX360F512L 4 канала). Таким образом, установка первого канала DMA в цепочку в более низком порядке означает, что он запускается каналом 1 (в вашем примере).