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.

MSP430FR2476: Can ADC work in "repeat-single-channel mode" triggered by ADCSC (software trigger)?

Part Number: MSP430FR2476

Hi I'm recently trying to program the ADC in MSP430FR2476 with max. sampling rate but found some issues.

Steps:

1) configure the ADC at MCLK at 16 MHz;

2) configure the ADC in pulse-sample mode, repeat-single-channel, put the trigger source at ADCSC;

3) enable ADC interrupt and start the ADC sampling and conversion;

4) in the ADC interrupt service routine (ISR), check the ADCIFG and read the ADC data into a variable; check the index (# of samples) > N, and stop ADC.

However, the ADC doesn't jump into the ISR and gives nothing.

I attached the code below, please let me know if you guys can help. Thanks a lot.

// Code to debug Clock speeds and continous ADC sampling.
// Please refer the 'User guide for msp430fr2xxx family of micro controllers' from TI and 'msp430fr2476.h' to understand registers and their functions

#include <msp430fr2476.h>
#include <stdio.h>

unsigned int Mode, q, i, Rx_Data[2000];
void initGpio (void);

int main(void)
{
  WDTCTL = WDTPW | WDTHOLD;               // Stop Watch Dog Timer
  initGpio();                             // Call the GPIO initialization function
  i=0;
  //CSCTL4 |= SELA_1 | SELMS_3;           // MCLK = SMCLK = VLO; ACLK = REFO

  __bic_SR_register(0x0080);              // LPM3 --> LPM0
  CSCTL4 &= ~SELMS_3; 
  CSCTL4 |= SELMS_0 |SELA_0;              // DCOCLKDIV for MCLK = SMCLK, and XT1CLK for ACLK
  CSCTL3 |= SELREF_0;
  
//  CSCTL3 |= SELREF_1;
  CSCTL1 |= DISMOD_1 | DCOFTRIM | DCORSEL_5 | DCOFTRIMEN_1;  
  // Modulation disabled,  frequency trimmed to highest value, DCOf = 16 MHz, Trimming enabled

  __bic_SR_register(0x0040);                // enable FLL
  
  CSCTL0 |= 0x01FF;                         // DCO
  printf("1 \n");
   
  // Configure ADC
  ADCCTL0 |= ADCSHT_0 | ADCON | ADCMSC;                         // ADCON, S&H=16 ADC clks
  ADCCTL1 |= ADCSHP | ADCSHS_0 | ADCSSEL_2 | ADCCONSEQ_2;       // pulse and sampl mode; ADCSC bit trigger; ADCCLK = SMCLK; repeat single channel;
  ADCCTL2 &= ~ADCRES;                                           // clear ADCRES in ADCCTL i.e 8-bit 
  ADCMCTL0 |= ADCINCH_3;                                        // A3 ADC input select; Vref=DVCC
  ADCIE |= ADCIE0;                                              // Enable ADC conv complete interrupt                          
  ADCCTL0 |= ADCENC | ADCSC;                                    // Sampling and conversion start
}

void initGpio()
{
  // Configure GPIO
  P1DIR = 0xFF; 
  P2DIR = 0xFF;
  P3DIR = 0xFF;
  P4DIR = 0xFF;
  P5DIR = 0xFF;
  P6DIR = 0xFF;
  
  P1OUT = 0x00;
  P2OUT = 0x00;
  P3OUT = 0x00;
  P4OUT = 0x00;
  P5OUT = 0x00;
  P6OUT = 0x00;
  
  // Select ADC input function on P1.3/A3
  P1SEL0 |= BIT3;
  P1SEL1 |= BIT3;
  // Output MCLK and SMCLK on P1.3 and P1.7
  P1SEL0 &= ~( BIT7); 
  P1SEL1 |=  BIT7;
  // Configure XT1 oscillator
  P2SEL0 |= BIT0 | BIT1;                                    // P2.0~P2.1: crystal pins
  
  PM5CTL0 &= ~LOCKLPM5;
}

// ADC interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=ADC_VECTOR
__interrupt void ADC_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
#else
#error Compiler not supported!
#endif
{
    switch(__even_in_range(ADCIV,ADCIV_ADCIFG))
    {
        case ADCIV_NONE:
            break;
        case ADCIV_ADCOVIFG:
            break;
        case ADCIV_ADCTOVIFG:
            break;
        case ADCIV_ADCHIIFG:
            break;
        case ADCIV_ADCLOIFG:
            break;
        case ADCIV_ADCINIFG:
            break;
        case ADCIV_ADCIFG:
            Rx_Data[i] = ADCMEM0;
            ADCIFG = 0;
            i=i+1;
            if (i == 40){
            ADCCTL0 &= ~ADCENC;
             printf("2 \n");
             for (i=0; i<40; i++)
             {
              printf("%d \n",Rx_Data[i]);
              }
            }
            break;
        default:
            break;
    }
}

  • I don't see where you enable GIE. Insert "__enable_interrupt();" somewhere appropriate.

    [Edit: Since you're running at 16MHz, you probably should also "FRCTL0 = FRCTLPW | NWAITS_1;" before switching the clock. That said, it looks like (contrary to the UG) NWAITS=1 out of reset on the FR2476, which doesn't look right.]

  • sorry I missed the last line here:    

    __bis_SR_register(LPM0_bits | GIE);             

    But I also tried with this GIE, giving me the same results.

  • When I added __enable_interrupt(), I reached the ADC ISR (repeatedly).

    I encourage you to add "FRCTL0 = FRCTLPW | NWAITS_1;" before switching the clock. As I mentioned (in the Edit:) my chip seems to come out of reset with NWAITS=1 but maybe my particular chip is broken. When I deliberately set NWAITS=0, it reached the ISR but crashed in printf().

  • Thanks a lot for your help. I think I messed up with the "interrupt" code. Now I can achieve "repeat-single-channel-mode" using the interrupt. 

    Also, I noticed that the MCLK is not 16 MHz (test pin output only 10 MHz). So I added the "FRCTL0 = FRCTLPW | NWAITS_1;" before the clock setting (CSCTL4 &=~SELMS_3;)  as you suggested. This seems not to affect the frequency. Do you know the potential solution to this? Thanks.

  • NWAITS doesn't affect the clock speed, rather the other way around. If you run the clock faster than 8MHz with NWAITS=0, the MCU will (eventually) malfunction.

    I'm not quite clear what your clock setup is doing; at minimum I don't think you're setting the FLL properly. I suggest you just copy/paste the clock setup block from example msp430fr267x_CS_03.c. (That's what I do.)

    http://dev.ti.com/tirex/explore/node?node=APvIVv5fd5Ll-1STGfMp7Q__IOGqZri__LATEST

    If you're just working in the lab (constant temperature) you can probably leave out Software_Trim() [but you didn't hear that from me].

  • Thanks a lot for your response.

    " If you run the clock faster than 8MHz with NWAITS=0, the MCU will (eventually) malfunction." Will this cause some critical issues for the MCU?

    I tried the code (example msp430fr267x_CS_03.c).) while setting NWAITS = 0. Something bad happens to the MCU, and I don't know the reason.

    The uploading is successful without showing any errors. But the MCU stops responding even after reset. I've also tried some simple programs, such as the LED blinking example. It is just not working. I probe the SWData wire during the debug mode. It repeatedly sends out the same bitstreams to the MCU. Do you think it relates to the "NWAITS=0" setting? Any suggested method to fix this? Thanks

  • Running the CPU too fast for the FRAM causes mis-reads of the FRAM content -- notably the code you're running. I don't know that there's a predictable pattern, so you should assume almost anything can happen. According to User Guide (SLAU445I) Sec 6.5 you're supposed to get a reset (ACCTEIFG), but I'm not sure that always happens.

    It's the sort of thing where fooling around with it is unlikely to be enlightening.

**Attention** This is a public forum