This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430FR58671: ADC12 Sequence of Channels issue

Part Number: MSP430FR58671


Tool/software:

Having an issue with ADC reading sequence of channels.

I have an 8x8 pixel array that I am reading. For troubleshooting all pixels are open. I ground individual pixels to verify correct memory location pointed to by ROIC. I have 4 16:1 multiplexers feeding into the 4 different ADC channels. So mux1 will go feed into ADC0, Mux2 to ADC1, Mux3 to ADC2 and Mux4 to ADC3. My for loop counts from 0 to 15 and outputs to 4 pins on port P3 for setting the switching on the Mux's. During the interrupt I read Mem0 first and Mem3 last.  The issue arises when I ground the last channel (channel 16) on Mux4. The issue is that it locks up. If I change the for loop counter to end on 14 instead of 15 the the lock up occurs when I ground channel 15 of Mux4 and grounding channel 16 has no effect.

uint16_t *ROIC[65];
uint16_t array[8][8];
uint16_t Color_Array[64];
unsigned int count,i,Row,Column;
void     matrix(void);
unsigned long counter;
unsigned long Color = 0xFFL;

int main(void)
{
	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer

      // Setup port pins
      P4DIR |= 0x40;                  // Set P4.6 to output direction -  LED
      P3DIR |= BIT4;                    // Set P3.4 to output direction - A0
      P3DIR |= BIT5;                    // Set P3.5 to output direction - A1
      P3DIR |= BIT6;                    // Set P3.6 to output direction - A2
      P3DIR |= BIT7;                    // Set P3.7 to output direction - A3
      P1SEL1 |= BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5;
      P1SEL0 |= BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5;

	  PM5CTL0 &= ~LOCKLPM5;

	  // Clock System Setup
	  CSCTL0_H = CSKEY >> 8;                    // Unlock CS registers
	  CSCTL1 = DCOFSEL_6;                       // Set DCO to 8MHz
	  CSCTL1 &= ~DCORSEL;
	  CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;
	  CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;     // Set all dividers
	  CSCTL4 &= ~LFXTOFF;                       // Enable LFXT1
	  CSCTL0_H = 0;                             // Lock CS registers

	  // ADC Setup
	  ADC12CTL0 = ADC12SHT0_2 | ADC12ON | ADC12MSC;
	  ADC12CTL1 |= ADC12SHP | ADC12CONSEQ_1;// | ADC12SSEL1;
	  ADC12CTL2 |= ADC12RES_2;
	  ADC12MCTL0 |= ADC12INCH_0;
      ADC12MCTL1 |= ADC12INCH_1;
      ADC12MCTL2 |= ADC12INCH_2;
      ADC12MCTL3 |= ADC12INCH_3 | ADC12EOS;
      ADC12IER0 |= ADC12IE3;                     // Interrupt MEM3
      ADC12CTL0 |= ADC12ENC;// | ADC12SC;                    // Enable conversions

	  ST7735_if_init();
	  ST7735_display_init();
	  matrix();
	  draw(0, 0, 128, 128, 0xFFFFFFL); //0L


	  drawimage(0,0,128,128,0xFFFFFFL);      // Display Srico image

	 // initialize Color_Array to one color
	  for (i = 65; i > 0; i--)
	      Color_Array[i-1] = 0xF00F;

  	while(1)
	    {
        P4OUT ^= BIT6;                // Toggle LED

	    drawMatrix(0,0,128,128,Color_Array);

	    for(i = 0; i < 16; i++)
	        {
	                count = i;
	                count = count << 4;        // Rotate left 4 bits
	                P3OUT = count;
	                counter = i * 4;
	                ADC12CTL0 |= ADC12ENC | ADC12SC;                    // Enable conversions
	                __bis_SR_register(GIE);
                   __no_operation(); // For debug only
   	        }

	          //adjust array color based on voltage level
	          Row = 7;
	          Column = 7;
	          for (i = 64; i > 0; i--)
	          {
	           //Temp1 = array[i];

                  if (array[Row][Column] >= 0xA00)
                      Color_Array[i-1] = 0xFF00;
                  if (array[Row][Column] < 0x0A00)
                      Color_Array[i-1] = 0xFFFF;
                  if (Column == 0)
                  {
                      Column = 8;
                      Row = Row - 1;
                  }
                  Column = Column - 1;

 	          }
	          __no_operation(); // For debug only
    }
	

}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = ADC12_VECTOR
__interrupt void ADC12_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(ADC12_VECTOR))) ADC12_ISR (void)
#else
#error Compiler not supported!
#endif
{
 switch (__even_in_range(ADC12IV, ADC12IV_ADC12RDYIFG))
 {
 case ADC12IV_ADC12IFG3: 

             *ROIC[counter+1] = ADC12MEM0;
             *ROIC[counter+2] = ADC12MEM1;
             *ROIC[counter+3] = ADC12MEM2;
             *ROIC[counter+4] = ADC12MEM3;

             ADC12CTL0 &=~ADC12SC;                // For sequence-of-Channels mode, ADC12SC must be cleared by software after each sequence to trigger another sequence

             __bic_SR_register_on_exit(GIE); // Exit CPU, clear interrupts


 break;
 default: break;
 }
}

  • >  __bis_SR_register(GIE);

    I suspect you meant:

    >  __bis_SR_register(LPM0_bits | GIE);  // Sleep until done

    Similarly:

    >  __bic_SR_register_on_exit(GIE); // Exit CPU, clear interrupts

    would be

    >  __bic_SR_register_on_exit(LPM0_bits); // Wake up CPU (main), clear interrupts

    ---------------

    As coded, the ADC is triggered (ADC12SC) repeatedly/rapidly, which probably trips over Erratum ADC42 [Ref Errata Sheet (SLAZ603Z), p. 5], not to mention not collecting the correct measurements.

  • I had tried that also and it did not fix it. Here is the code

    while(1)
    	    {
            P4OUT ^= BIT6;                // Toggle LED
    
    	    drawMatrix(0,0,128,128,Color_Array);
    
    	    for(i = 0; i < 16; i++)
    	        {
    	                count = i;
    	                count = count << 4;        // Rotate left 4 bits
    	                P3OUT = count;
    	                counter = i * 4;
                        while(ADC12CTL1 & ADC12BUSY);
    
    	                ADC12CTL0 |= ADC12ENC | ADC12SC;                    // Enable conversions
             	         __bis_SR_register(LPM0_bits | GIE);
    	                 __no_operation(); // For debug only
       	        }
    
    	          //adjust array color based on voltage level
    	          Row = 7;
    	          Column = 7;
    	          for (i = 64; i > 0; i--)
    	          {
    	           //Temp1 = array[i];
    
                      if (array[Row][Column] >= 0xA00)
                          Color_Array[i-1] = 0xFF00;
                      if (array[Row][Column] < 0x0A00)
                          Color_Array[i-1] = 0xFFFF;
                      if (Column == 0)
                      {
                          Column = 8;
                          Row = Row - 1;
                      }
                      Column = Column - 1;
    
     	          }
    	          __no_operation(); // For debug only
        }
    	
    
    }
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = ADC12_VECTOR
    __interrupt void ADC12_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(ADC12_VECTOR))) ADC12_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
     switch (__even_in_range(ADC12IV, ADC12IV_ADC12RDYIFG))
     {
     case ADC12IV_ADC12IFG3:
    
                 *ROIC[counter+1] = ADC12MEM0;
                 *ROIC[counter+2] = ADC12MEM1;
                 *ROIC[counter+3] = ADC12MEM2;
                 *ROIC[counter+4] = ADC12MEM3;
    
                 ADC12CTL0 &=~ADC12SC;
    
                 __bic_SR_register_on_exit(LPM0_bits); // Exit CPU, clear interrupts
    
    
     break;
     default: break;
     }
    }

  • How precisely do you know where it locks up? Maybe your description could be re-worded "some time during or after the final sampling" which could mean anywhere below.

    I don't see where ROIC[] (array of pointers) is initialized; are they still NULL? For that matter, how do the samples get to array[]?

  • Bruce, 

    That is a valid point I do not know the exact point that it locks up. I will see if i can figure that out. 

    As for the ROIC initialization I have a function that sets it up. Before testing of the ADC I verified that it works and points to the correct locations within the array. I did not include it as I did not find it relevant to the current issue.

  • Bruce,

    It works now by getting rid of toggling the LED (P4 Bit6). If the LED is on it will lock up, if it is off it works great. I have some more troubleshooting to perform.

    Thanks for your assistance.

**Attention** This is a public forum