Hi,
As I'm using DMA to transfer data from ADC10 to memory, occasionally (only observed twice in the past 6 months) I have noticed ADC module getting stuck and unable to function. I'm not able to determine if this is due to a loss of interrupt or a stuck module. In ADC function watchdog timer is cleared, but it does not recover after watchdog reset, but when I turn off main board power ON and OFF it does recover.
Below is my code ADC10 -
// Initializing ADC10 module void initAdc10(void) { // Disable DMA and ADC ADC10_A_disable(ADC10_A_BASE); ADC10_A_clearInterrupt(ADC10_A_BASE, 0xff); DMA_clearInterrupt(DMA_CHANNEL_0); DMA_clearNMIAbort(DMA_CHANNEL_0); DMA_disableInterrupt(DMA_CHANNEL_0); DMA_disableTransfers(DMA_CHANNEL_0); /* Delay */ __delay_cycles(2560000); // Setup P1.2 A0, 1.1 A1, 1.0 A2 P1SEL |= BIT0 | BIT1 | BIT2; // Set P1.0,.1,.2 to non-IO __disable_interrupt(); // Disable interrupts; Port Map cnfg PMAPKEYID = PMAPKEY; // Enable access Port Mapping regs P1MAP2 = PM_ANALOG; // Enable A0 P1MAP1 = PM_ANALOG; // Enable A1 P1MAP0 = PM_ANALOG; // Enable A2 PMAPKEYID = 0; // Disable access Port Mapping regs __enable_interrupt(); // Re-enable all interrupts // Setup ADC10 ADC10CTL0 = ADC10SHT_2 | ADC10MSC | ADC10ON; // 16ADCclks, MSC, ADC ON ADC10CTL1 = ADC10SHP | ADC10CONSEQ_3; // pulse sample mode, repeated sequence ADC10CTL2 = ADC10RES; // 10-bit resolution ADC10MCTL0 = ADC10INCH_2; // A0,A1,A2(EoS), AVCC reference // Setup DMA0 (ADC10IFG trigger) DMACTL0 = DMA0TSEL_24; // ADC10IFG trigger /* Read-modify-write disable */ //DMACTL0 = DMARMWDIS; /* clear DMA interrupt flag */ DMA0CTL &= ~DMAIFG; DMA0SZ = 192; // 192 conversions __data20_write_long((uintptr_t) &DMA0SA, (uintptr_t) &ADC10MEM0); // Source single address __data20_write_long((uintptr_t) &DMA0DA, (uintptr_t) &ADC_Result[0]); // Destination array address DMA0CTL = DMADT_4 | DMADSTINCR_3 | DMASWDW | DMAEN | DMAIE; } Interrupt Code: #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=DMA_VECTOR __interrupt void DMA0_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(DMA_VECTOR))) DMA0_ISR (void) #else #error Compiler not supported! #endif { switch (__even_in_range(DMAIV, 16)) { case DMAIV_NONE: break; // No interrupts case DMAIV_DMA0IFG: // DMA0IFG = DMA Channel 0 ADC10CTL0 &= ~ADC10ENC; // conversions complete dma_adc_flag = 2; break; case DMAIV_DMA1IFG: break; // DMA1IFG = DMA Channel 1 case DMAIV_DMA2IFG: break; // DMA2IFG = DMA Channel 2 case 8: break; // Reserved case 10: break; // Reserved case 12: break; // Reserved case 14: break; // Reserved case 16: break; // Reserved default: break; } } Main Function: int dma_adc_flag = 0; void Adc10Main(void) { if (ADC10CTL1 & ADC10BUSY) { return; } if (!dma_adc_flag) { ADC10CTL0 |= ADC10ENC | ADC10SC; // Sampling and conversion start dma_adc_flag = 1; return; } else if (dma_adc_flag == 1) { return; } dma_adc_flag = 0; /* Clear Watchdog Timer */ WDT_A_resetTimer(WDT_A_BASE); }
Could you please help me with this? Thanks in advance.
Rahul