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.

CCS/MSP430FR5969: How to make an ISR quicker?

Part Number: MSP430FR5969

Tool/software: Code Composer Studio

Hello!

My name is Trujillo and I'm from Spain. First of all, my apologies for any English writing mistake I could probably do.

Actually I'm working with a MSP430FR5969 and I'm trying to generate a PWM signal (Timer B) (in the range of audible frequencies) from a Timer A Interrupt. The problem I find is that the PWM signal from the Timer B appears correctly but I need that the PWM from Timer A keeps working. An the last thing doesn't happen. It's seems that the ISR has a lot of thing to do and the CPU can't handle it as quicker as I need. Here is the code, if someone can help me I will be truly grateful.

#include <msp430.h> 
#include <msp430fr5969.h>
unsigned int mostra(void);
unsigned int valor=0;
unsigned long resultat=0.0;
unsigned int vector[48]={0};
unsigned int puntero=0;
unsigned long mitja=0.0;

/*
 * main.c
 */
int main(void) {

	 WDTCTL = WDTPW | WDTHOLD;                 // Stop WDT

	  // Configure GPIO
//---------------------------------------------------------------------------------------------//

	  P1DIR |= BIT2; 
	  P1SEL0 |= BIT2;

	  P1DIR |= BIT5;	
	  P1SEL0 &= ~BIT5;

	  P1DIR = 0x10;	
	  P1SEL0 = 0x10;

	  P4SEL0 |= BIT4; 
	  P4SEL1 |= BIT4;


	  // Disable the GPIO power-on default high-impedance mode to activate
	  // previously configured port settings
	  PM5CTL0 &= ~LOCKLPM5;


//----------------------------------------------------------------------------------------------------------------//
	  // CONFIGURACIÓN DE LOS CLOCKS
//-----------------------------------------------------------------------------------------------------------------//
	  CSCTL0_H = CSKEY >> 8;                    // Unlock CS registers
	  CSCTL1 = DCOFSEL_6;                       
	  CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;
	  CSCTL3 = DIVA__8 | DIVS__8 | DIVM__1;     
	  CSCTL0_H = 0;
//-----------------------------------------------------------------------------------------------------------------//
	  //CONFIGURACIÓN DEL ADC12
//-----------------------------------------------------------------------------------------------------------------//

	  ADC12CTL0 = ADC12SHT1_0 | ADC12ON;
	  ADC12CTL1 = ADC12SHP | ADC12SSEL_3 | ADC12PDIV_1 | ADC12CONSEQ_0;
	  ADC12CTL2 =ADC12RES_2;
	  ADC12CTL3 = ADC12CSTARTADD_10;
	  ADC12MCTL10 = ADC12INCH_10 | ADC12VRSEL_0;             

//--------------------------------------------------------------------------------------------------//
	  //CONFIGURACIÓN DE LA SEÑAL PWM Principal
//--------------------------------------------------------------------------------------------------//
	  TA1CTL = TASSEL__SMCLK | MC__UP | TACLR;
	  TA1CCR0 = 2325-1;      
	  TA1CCTL1 = OUTMOD_7;    
	  TA1CCR1 = 1850;         
	  TA1CCTL2 = CCIE;		  
	  TA1CCR2 = 1965;		  
//--------------------------------------------------------------------------------------------------//


	  __bis_SR_register(LPM0_bits+GIE);   // Enter LPM0 y generamos la ISR


	  while(1){};
}
//----------------ISR--------------------------------------------------------------------------//
#pragma vector=TIMER1_A1_VECTOR //INTERRUPCIÓN EN TIMER1: TA1.1
	__interrupt void Temp(void)
	  	  {
		 	 switch (TA1IV) 
		 	 {
		 	 	 case 4: // interrupción en TA1CCR2


		 	 		mostra();
		 	 		int i;
		 	 		vector[puntero]=mostra();
		 	 		if(puntero==47){
		 	 			puntero=0;
		 	 			for(i=0;i<48;i++){
		 	 				mitja=mitja+vector[i];
		 	 			}

		 	 			resultat=mitja/48;
			 	 		if (resultat<<205){
			 	 			resultat=205.0;
			 	 		}
//--------------- CONFIGURACIÓN DE LA SEÑAL PWM de salida de AUDIO para LOCALIZACIÓN----------------//

			 	 		TB0CTL = TBSSEL__SMCLK | MC__UP | CNTL_1 | TBCLR;
			 	 		TB0CCTL1 = OUTMOD_7;
			 	 		TB0CCR0 = (409600/resultat)-1;
			 	 		TB0CCR1 = TB0CCR0/2;
			 	 		mitja=0;
			 	 		resultat=0.0;

		 	 		}
		 	 		else
		 	 		puntero++;

		 		 break;
		 	 }
		 	TA1CTL &= ~TAIFG; 
	  	  }
//--------------ADC12---------------------------------------------------------------------------------//
unsigned int mostra(void) 
{

	ADC12MEM10=0; 
	ADC12CTL0 |= ADC12ENC | ADC12SC;     
	while((ADC12CTL0&ADC12SC)==ADC12SC){}; 
	valor=ADC12MEM10; 
	ADC12CTL0 &= ~ADC12ENC; 
	return valor;

}

Thank you so much!

Trujillo

  • Hi Trujillo,

    Your main clock frequency is currently 8 MHz, you could increase this to 16 MHz to service the ISR more quickly. But the main issue is that there is way too much going on inside your ISR in the first place. The MSP430FR5969 has five timers (TA0-3, TB0) and you should be using these to divide up your tasks. TA1 continues to create the PWM output, one internal timer (TA2/3) triggers an ADC conversion, and another internal timer starts the TB0 PWM output when needed. All ISRs should be reduced to do small tasks and return to active or LPM as soon as possible.

    Regards,
    Ryan
  • Hello Mr. Brown,

    First of all, thank you very much for the time you spend to answering me. I'm very thankful.
    About your answer, I thought that the MCLK cannot work for frequencies higher than 8MHz. I was mistaken.
    On the other hand, I have already modified my code and when I go to the laboratory I will test it and I will feedback you. Just thinking about the code, could be another possible solution create different ISR in every TA1CCRx, from 3 to 6, in my case? I want to test if this way may work or not, but the CCS cannot identify the TA1CCTL3, TA1CCTL4, TA1CCR3 and TA1CCR4. Do I have to include some library that enables the recognition of those registers? I'm not pretty sure if this thread is the proper way to make this question. If it's not, please don't hesitate to tell me.

    Thank you again.

    Trujillo.
  • Hello Trujillo,

    MCLK can go up to 16 MHz but you must make sure to adjust the FRAM wait states accordingly, you can refer to msp430fr59xx_cs_02.c for an example of how to do this. TA1 CCR[3-6] does not exist on the MSP430FR5969, but TB0 has the number of CCRx registers you are looking for.

    Regards,
    Ryan
  • Something human audible is pretty slow.

    Hardware pwm never miss a beat, could it skip a change due to a ISR hogging the system, yes.

    You are using timerB hardware PWM to generate a tone in the 1-2 KHz range?
    You need to change the tone depending on the ADC12 sample value?

    Could you not use timerB IRQ to read last ADC sample and then fire off another ADC12 sampling?
    Could use: if (!++skip & 7) if you want to only do it every eight time the ISR is run.

    Don't do complicated math inside a ISR.
    And never do function calls from a ISR that do hardware polling of a flag.

    A running-average split up the math in smaller snippets, less risk of hogging the system:
    unsigned int temp = ADC12MEM;
    battery.volt=(temp+battery.volt*3)/4; // averaging 3/4 old + 1/4 new

  • Hello!

    Until now, I cannot been able to perform the necessary test in order to verify if the changes I've made were correct or not. I've done every modification that you, Mr. Brown and Mr. Philipsson, recommended to me. I've used different timers, different CCR, different frequencies, different everything, but nothing happen. So, having in mind that I'm not an experienced guy in MSP430, I decided to begin from zero. What really happened was that the Port configuration was not properly done. Concretely:

    P1DIR = 0x10;
    P1SEL0 = 0x10;

    It's a silly mistake but I didn't be able to see it. When I've changed this, everything work, obviously. I'm really sorry for not seeing this before and for wasting your time.

    I hope that, in the future, I will be able to make more serious contributions.

    Thank you so much.

    Trujillo

**Attention** This is a public forum