Перейти к содержанию

PIC32 не срабатывает прерывание DMA запущенного от ADC

Коллеги, помогите, пожалуйста, понять в чем причина неработоспособности следующего кода:
Инициализация:
Код
AD1CSSL = (1<<_AD1CSSL_CSSL9_POSITION) | (1<<_AD1CSSL_CSSL8_POSITION)  | (1<<_AD1CSSL_CSSL7_POSITION) | (1<<_AD1CSSL_CSSL6_POSITION) | (1<<_AD1CSSL_CSSL5_POSITION)   | (1<<_AD1CSSL_CSSL4_POSITION) | (1<<_AD1CSSL_CSSL3_POSITION) | (1<<_AD1CSSL_CSSL2_POSITION) | (1<<_AD1CSSL_CSSL0_POSITION);
AD1CON3 = (0<<_AD1CON3_ADRC_POSITION)  | (2<<_AD1CON3_SAMC_POSITION)   | (2<<_AD1CON3_ADCS_POSITION) ;
AD1CON2 = (0<<_AD1CON2_VCFG_POSITION)  | (0<<_AD1CON2_OFFCAL_POSITION) | (1<<_AD1CON2_CSCNA_POSITION) | (8<<_AD1CON2_SMPI_POSITION)  | (0<<_AD1CON2_BUFM_POSITION)    | (0<<_AD1CON2_ALTS_POSITION) ;
AD1CON1 = (1<<_AD1CON1_ON_POSITION)    | (0<<_AD1CON1_SIDL_POSITION)   | (0<<_AD1CON1_FORM_POSITION)  | (1<<_AD1CON1_SSRC_POSITION)  | (1<<_AD1CON1_CLRASAM_POSITION) | (1<<_AD1CON1_ASAM_POSITION)  | (0<<_AD1CON1_SAMP_POSITION) ;

IPC0 = (5<<_IPC0_INT0IP_POSITION) | (0<<_IPC0_INT0IS_POSITION);
IPC6 = (6<<_IPC6_AD1IP_POSITION)  | (0<<_IPC6_AD1IS_POSITION) ;
IPC5 = (7<<_IPC5_T5IP_POSITION)   | (0<<_IPC5_T5IS_POSITION)  ;

IFS0CLR = (1<<_IFS0_T5IF_POSITION)  | (1<<_IFS0_INT0IF_POSITION);
IFS1CLR = (1<<_IFS1_AD1IF_POSITION);    

IEC0 = (1<<_IEC0_T5IE_POSITION)  | (0<<_IEC0_INT0IE_POSITION);
IEC1 = (0<<_IEC1_AD1IE_POSITION);
    
INTCONSET = (1<<_INTCON_INT0EP_POSITION);
    
int chn = 1;
DmaChnConfigure (chn, DMA_CHN_PRI2, DMA_CONFIG_DEFAULT);
DmaChnSetEventControl (chn, DMA_EV_START_IRQ_EN | DMA_EV_START_IRQ(_ADC_IRQ));
DmaChnSetTxfer (chn, (void*)&ADC1BUF0, (void*)ADC_DATA, 2, 18, 2);
DmaChnSetEvEnableFlags (chn, DMA_EV_BLOCK_DONE);
INTEnableSystemMultiVectoredInt ();
DmaChnSetIntPriority (chn, INT_PRIORITY_LEVEL_4, INT_SUB_PRIORITY_LEVEL_0);
DmaChnIntEnable (chn);
DmaChnEnable (chn);

Обработчики:
Код
void __ISR(_DMA_1_VECTOR, IPL4AUTO) DMA1_ISR (void)
{
    IFS1CLR = (1<<_IFS1_DMA1IF_POSITION);
    
    LATDINV = (1<<_LATD_LATD11_POSITION);
}
//-------------------------------------------------------------------
void __ISR(_EXTERNAL_0_VECTOR, IPL5AUTO) INT0_ISR (void)
{
    IFS0CLR = (1<<_IFS0_INT0IF_POSITION);
    
    LATDINV = (1<<_LATD_LATD11_POSITION);
}
//-------------------------------------------------------------------
void __ISR(_ADC_VECTOR, IPL6AUTO) ADC_ISR (void)
{
    ADC_DATA[0] = ADC1BUF0;
    ADC_DATA[1] = ADC1BUF1;
    ADC_DATA[2] = ADC1BUF2;
    ADC_DATA[3] = ADC1BUF3;
    ADC_DATA[4] = ADC1BUF4;
    ADC_DATA[5] = ADC1BUF5;
    ADC_DATA[6] = ADC1BUF6;
    ADC_DATA[7] = ADC1BUF7;
    ADC_DATA[8] = ADC1BUF8;
    IFS1CLR = (1<<_IFS1_AD1IF_POSITION);
    AD1CON1SET = (1<<_AD1CON1_ASAM_POSITION);
    
    LATDINV = (1<<_LATD_LATD11_POSITION);
}

Если разрешить INT0IE или AD1IE, то соответствующие прерывания срабатывают, но вот когда пытаюсь поймать прерывание от DMA запускаемого от ADC, то ничего не происходит.
Похоже на косяк в инициализации DMA, но только я никак не могу понять где именно sad.gif

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Решил наконец проблему sm.gif
МК PIC32MX575F256H.
Дело было в том, что функции через которые я настраивал DMA почему-то не устанавливали бит ON в регистре DMACON.
Проблема решилась ручной установкой данного бита.
Вот какая в итоге получилась процедура инициализации:
Код
AD1CSSL = (1<<_AD1CSSL_CSSL9_POSITION) | (1<<_AD1CSSL_CSSL8_POSITION)  | (1<<_AD1CSSL_CSSL7_POSITION) | (1<<_AD1CSSL_CSSL6_POSITION) | (1<<_AD1CSSL_CSSL5_POSITION)   | (1<<_AD1CSSL_CSSL4_POSITION) | (1<<_AD1CSSL_CSSL3_POSITION) | (1<<_AD1CSSL_CSSL2_POSITION) | (1<<_AD1CSSL_CSSL0_POSITION);
AD1CON3 = (0<<_AD1CON3_ADRC_POSITION)  | (2<<_AD1CON3_SAMC_POSITION)   | (2<<_AD1CON3_ADCS_POSITION) ;
AD1CON2 = (0<<_AD1CON2_VCFG_POSITION)  | (0<<_AD1CON2_OFFCAL_POSITION) | (1<<_AD1CON2_CSCNA_POSITION) | (8<<_AD1CON2_SMPI_POSITION)  | (0<<_AD1CON2_BUFM_POSITION)    | (0<<_AD1CON2_ALTS_POSITION) ;
AD1CON1 = (1<<_AD1CON1_ON_POSITION)    | (0<<_AD1CON1_SIDL_POSITION)   | (0<<_AD1CON1_FORM_POSITION)  | (1<<_AD1CON1_SSRC_POSITION)  | (0<<_AD1CON1_CLRASAM_POSITION) | (1<<_AD1CON1_ASAM_POSITION)  | (0<<_AD1CON1_SAMP_POSITION) ;

IPC0    = (5<<_IPC0_INT0IP_POSITION) | (0<<_IPC0_INT0IS_POSITION);
IPC6    = (6<<_IPC6_AD1IP_POSITION)  | (0<<_IPC6_AD1IS_POSITION) ;
IPC5    = (7<<_IPC5_T5IP_POSITION)   | (0<<_IPC5_T5IS_POSITION)  ;
    
IFS0CLR = (1<<_IFS0_T5IF_POSITION)   | (1<<_IFS0_INT0IF_POSITION);
IFS1CLR = (1<<_IFS1_AD1IF_POSITION)  | (1<<_IFS1_DMA0IF_POSITION);    
    
IEC0    = (1<<_IEC0_T5IE_POSITION)   | (0<<_IEC0_INT0IE_POSITION);
IEC1    = (0<<_IEC1_AD1IE_POSITION)  | (0<<_IEC1_DMA0IE_POSITION);

INTCONSET = (1<<_INTCON_INT0EP_POSITION);

DMACONbits.ON = 1;

DmaChnConfigure (DMA_CHANNEL0, DMA_CHN_PRI3, DMA_CONFIG_AUTO);
DmaChnSetTxfer (DMA_CHANNEL0, (void*)(&ADC1BUF0), (void*)ADC_BUF, 16*9, 16*9*128, 16*9);
DmaChnSetEventControl (DMA_CHANNEL0, DMA_EV_START_IRQ_EN | DMA_EV_START_IRQ(_ADC_IRQ));
DmaChnSetEvEnableFlags (DMA_CHANNEL0, DMA_EV_CELL_DONE);
DmaChnSetIntPriority (DMA_CHANNEL0, INT_PRIORITY_LEVEL_4, INT_SUB_PRIORITY_LEVEL_0);
DmaChnClrIntFlag (DMA_CHANNEL0);

INTEnableSystemMultiVectoredInt ();

DmaChnIntEnable (DMA_CHANNEL0);
DmaChnEnable (DMA_CHANNEL0);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Как-то раз сталкивался с неправильным define маски. Т.е. все по логике выставляется правильно, регистры и пр. но не работает. Нашел только проверкой в дебаггере состояния нужных регистров, как должно стоять и как стоит.

Еще на днях выловил ошибку, xc32 v.1.42 не работает atof, всегда 0 возвращает. На форуме Микрочипа куча вайна, обходные пути вроде есть. Но я не пробовал, перевел все в целые числа, логика позволяет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация