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.

TM4C129ENCPDT: Main Application Loop and Timer Speed

Part Number: TM4C129ENCPDT

I am having an issue with a timer. When I setup the timer to run like this,

MAP_TimerLoadSet(TIMER0_BASE, TIMER_A, ui32SysClock/2);

The main application loop will no longer run and simple pings to the microcontroller will time out. Slowing down the timer will fix this issue,

MAP_TimerLoadSet(TIMER0_BASE, TIMER_A, ui32SysClock);

The timer runs the following code,

//=========================================================================
//          Auto Range Event Timer
//=========================================================================
void Timer0IntHandler(void)
{
   char cOne, cTwo;

   // Clear the timer interrupt.
   MAP_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
   // Toggle the flag for the first timer.
   HWREGBITW(&g_ui32Flags, FLAG_AUTORNG) ^= 1;

   uint32_t status_led_c;
   uint32_t status_led_a;
   uint32_t status_led_b;
   uint32_t status_led_d;

   uint32_t adc_count_a;
   uint32_t adc_count_b;
   uint32_t adc_count_c;
   uint32_t adc_count_d;

   //UARTprintf("==============================\n");
   //UARTprintf("CH A \t CH B \t CH C \t CH D \n");
   //UARTprintf("==============================\n");

   switch (STATE_A) {
      case 'R':
         //UARTprintf("KIRT CH A: STATE %c\n", STATE_A);
         UARTprintf("%c:%c \t\t|", R_CH_A, STATE_A);
         previous_range('A', CH_A_PRE_R);
         if (R_CH_A == '5' | R_CH_A == '6' | R_CH_A == '7') {
             STATE_A = 'M';
         }
         else {
             STATE_A = 'M';
         }
         break;
      case 'U':
         //UARTprintf("KIRT CH A: STATE %c\n", STATE_A);
         UARTprintf("%c:%c (UP) \t|", R_CH_A, STATE_A);
         set_range('A', R_CH_A+1);
         STATE_A = 'R';
         CH_A_PRE_R = R_CH_A+1;
         break;
      case 'D':
         //UARTprintf("KIRT CH A: STATE %c\n", STATE_A);
          UARTprintf("%c:%c (DWN) \t\t|", R_CH_A, STATE_A);
         set_range('A', R_CH_A-1);
         STATE_A = 'R';
         CH_A_PRE_R = R_CH_A-1;
         break;
      case 'S':
          //UARTprintf("KIRT CH A: STATE %c (%d)", STATE_A, SD_CH_A);
          adc_count_a = read_adc_A();
          //UARTprintf("   CH A: ADC Reading = %d\n", adc_count_a);
          if (SD_CH_A < 5) {
              SD_CH_A++;
          }
          else {
              STATE_A = 'M';
          }
          UARTprintf("%c:%c (%d)(%d) \t|", R_CH_A, STATE_A, SD_CH_A, adc_count_a);
          break;
      case 'M':
          //0. Reset stabilize delay.
          SD_CH_A = 0;
          //1. Channel A Toggle LED Status Light.
          status_led_a = ROM_GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_2);
          status_led_a ^= 1 << 2;
          ROM_GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_2, status_led_a);
          //UARTprintf("KIRT CH A: STATE %c\n", STATE_A);

          //2. Measure Channel A ADC.
          //Read the ADC
          adc_count_a = read_adc_A();
          M_R_CH_A = R_CH_A;
          //UARTprintf("   CH A: ADC Reading = %d\n", adc_count_a);
          CH_A = adc_count_a;
          //Read the PN.
          PN_CH_A = ROM_GPIOPinRead(GPIO_PORTN_BASE, GPIO_PIN_0);
          UARTprintf("%c:%c (%d) \t|", R_CH_A, STATE_A, adc_count_a);

          //3. Switch Range based on ADC Count.
          //a. Measurement in Range. -> adc_count_low < adc_count_c < adc_count_high
         if (adc_count_a > adc_count_low & adc_count_a < adc_count_high) {
             //UARTprintf("   CH A: CR = %d.IN\n", R_CH_A);
         }
         else {
             //b. Measurement To Low. Move Up in Range.
            if (adc_count_a < adc_count_low & R_CH_A != '7') //ADC Count Low, Move to Higher Range.
            {
                //UARTprintf("   CH A: SR = %d.L\n", R_CH_A);
                STATE_A = 'U';
            }
            //c. Measurement to High. Move Down in Range.
            if (adc_count_a > adc_count_high & R_CH_A != '1') //Too High, Move to Lower Range.
            {
                //UARTprintf("   CH A: SR = %d.H\n", R_CH_A);
                STATE_A = 'D';
            }
        break;
         }

      }

   switch (STATE_B) {
         case 'R':
            //UARTprintf("KIRT CH B: STATE %c\n", STATE_B);
            UARTprintf("%c:%c \t\t|", R_CH_B, STATE_B);
            previous_range('B', CH_B_PRE_R);
            STATE_B = 'M';
            if (R_CH_B == '5' | R_CH_B == '6' | R_CH_B == '7') {
                 STATE_B = 'M';
             }
             else {
                 STATE_B = 'M';
             }
            break;
         case 'U':
            //UARTprintf("KIRT CH B: STATE %c\n", STATE_B);
            UARTprintf("%c:%c (UP) \t|", R_CH_B, STATE_B);
            set_range('B', R_CH_B+1);
            STATE_B = 'R';
            CH_B_PRE_R = R_CH_B+1;
            break;
         case 'D':
            //UARTprintf("KIRT CH B: STATE %c\n", STATE_B);
             UARTprintf("%c:%c (DWN) \t\t|", R_CH_B, STATE_B);
            set_range('B', R_CH_B-1);
            STATE_B = 'R';
            CH_B_PRE_R = R_CH_B-1;
            break;
         case 'S':
           //UARTprintf("KIRT CH B: STATE %c (%d)", STATE_B, SD_CH_B);
           adc_count_b = read_adc_B();
           //UARTprintf("   CH B: ADC Reading = %d\n", adc_count_b);
           if (SD_CH_B < 5) {
               SD_CH_B++;
           }
           else {
               STATE_B = 'M';
           }
           UARTprintf("%c:%c (%d)(%d) \t|", R_CH_B, STATE_B, SD_CH_B, adc_count_b);
           break;
         case 'M':
             //0. Reset stabilize delay.
             SD_CH_B = 0;
             //1. Channel A Toggle LED Status Light.
             status_led_b = ROM_GPIOPinRead(GPIO_PORTN_BASE, GPIO_PIN_2);
             status_led_b ^= 1 << 2;
             ROM_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_2, status_led_b);
             //UARTprintf("KIRT CH B: STATE %c\n", STATE_B);

             //2. Measure Channel A ADC.
             uint32_t adc_count_b;
             adc_count_b = read_adc_B();
             M_R_CH_B = R_CH_B;
             //UARTprintf("   CH B: ADC Reading = %d\n", adc_count_b);
             CH_B = adc_count_b;
             PN_CH_B = ROM_GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_7);
             UARTprintf("%c:%c (%d) \t|", R_CH_B, STATE_B, adc_count_b);

             //3. Switch Range based on ADC Count.
             //a. Measurement in Range. -> adc_count_low < adc_count_c < adc_count_high
            if (adc_count_b > adc_count_low & adc_count_b < adc_count_high) {
                //UARTprintf("   CH B: CR = %d.IN\n", R_CH_B);
            }
            else {
                //b. Measurement To Low. Move Up in Range.
               if (adc_count_b < adc_count_low & R_CH_B != '7') //ADC Count Low, Move to Higher Range.
               {
                   //UARTprintf("   CH B: SR = %d.L\n", R_CH_B);
                   STATE_B = 'U';
               }
               //c. Measurement to High. Move Down in Range.
               if (adc_count_b > adc_count_high & R_CH_B != '1') //Too High, Move to Lower Range.
               {
                   //UARTprintf("   CH B: SR = %d.H\n", R_CH_B);
                   STATE_B = 'D';
               }
           break;
            }

         }

   switch (STATE_C) {
   case 'R':
      //UARTprintf("KIRT CH C: STATE %c\n", STATE_C);
       UARTprintf("%c:%c \t\t|", R_CH_C, STATE_C);
      previous_range('C', CH_C_PRE_R);
      STATE_C = 'M';
      if (R_CH_C == '5' | R_CH_C == '6' | R_CH_C == '7') {
           STATE_C = 'M'; //Changed to M from S.
       }
       else {
           STATE_C = 'M';
       }
      break;
   case 'U':
      //UARTprintf("KIRT CH C: STATE %c\n", STATE_C);
       UARTprintf("%c:%c (UP) \t|", R_CH_C, STATE_C);
      set_range('C', R_CH_C+1);
      STATE_C = 'R';
      CH_C_PRE_R = R_CH_C+1;
      break;
   case 'D':
      //UARTprintf("KIRT CH C: STATE %c\n", STATE_C);
       UARTprintf("%c:%c (DWN) \t\t|", R_CH_C, STATE_C);
      set_range('C', R_CH_C-1);
      STATE_C = 'R';
      CH_C_PRE_R = R_CH_C-1;
      break;
   case 'S':
      //UARTprintf("KIRT CH C: STATE %c (%d)", STATE_C, SD_CH_C);
      adc_count_c = read_adc_C();
      UARTprintf("%c:%c (%d)(%d) \t|", R_CH_C, STATE_C, SD_CH_C, adc_count_c);
      //UARTprintf("   CH C: ADC Reading = %d\n", adc_count_c);
      if (SD_CH_C < 5) {
          SD_CH_C++;
      }
      else {
          STATE_C = 'M';
      }
      break;
   case 'M':
       //0. Reset stabilize delay.
        SD_CH_C = 0;
        //1. Channel C Toggle LED Status Light.
       status_led_c = ROM_GPIOPinRead(GPIO_PORTE_BASE, GPIO_PIN_1);
       status_led_c ^= 1 << 1;
       ROM_GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_1, status_led_c);
       //UARTprintf("KIRT CH C: STATE %c\n", STATE_C);

       //2. Measure Channel C ADC.
       uint32_t adc_count_c;
       adc_count_c = read_adc_C();
       M_R_CH_C = R_CH_C;
       //UARTprintf("   CH C: ADC Reading = %d\n", adc_count_c);
       CH_C = adc_count_c;
       PN_CH_C = ROM_GPIOPinRead(GPIO_PORTH_BASE, GPIO_PIN_2);
       UARTprintf("%c:%c (%d) \t|", R_CH_C, STATE_C, adc_count_c);

       //3. Switch Range based on ADC Count.
       //a. Measurement in Range. -> adc_count_low < adc_count_c < adc_count_high
      if (adc_count_c > adc_count_low & adc_count_c < adc_count_high) {
          //UARTprintf("   CH C: CR = %d.IN\n", R_CH_C);
      }
      else {
          //b. Measurement To Low. Move Up in Range.
         if (adc_count_c < adc_count_low & R_CH_C != '7') //ADC Count Low, Move to Higher Range.
         {
             //UARTprintf("   CH C: SR = %d.L\n", R_CH_C);
             STATE_C = 'U';
         }
         //c. Measurement to High. Move Down in Range.
         if (adc_count_c > adc_count_high & R_CH_C != '1') //Too High, Move to Lower Range.
         {
             //UARTprintf("   CH C: SR = %d.H\n", R_CH_C);
             STATE_C = 'D';
         }
     break;
      }

   }

   switch (STATE_D) {
   case 'R':
      //UARTprintf("KIRT CH D: STATE %c\n", STATE_D);
       UARTprintf("%c:%c \t\t|", R_CH_D, STATE_D);
      previous_range('D', CH_D_PRE_R);
      STATE_D = 'M';
      if (R_CH_D == '5' | R_CH_D == '6' | R_CH_D == '7') {
           STATE_D = 'M';
       }
       else {
           STATE_D = 'M';
       }
      break;
   case 'U':
      //UARTprintf("KIRT CH D: STATE %c\n", STATE_D);
       UARTprintf("%c:%c (UP) \t|", R_CH_D, STATE_D);
      set_range('D', R_CH_D+1);
      STATE_D = 'R';
      CH_D_PRE_R = R_CH_D+1;
      break;
   case 'D':
      //UARTprintf("KIRT CH D: STATE %c\n", STATE_D);
       UARTprintf("%c:%c (DWN) \t\t|", R_CH_D, STATE_D);
      set_range('D', R_CH_D-1);
      STATE_D = 'R';
      CH_D_PRE_R = R_CH_D-1;
      break;
   case 'S':
     //UARTprintf("KIRT CH D: STATE %c (%d)", STATE_D, SD_CH_D);
     adc_count_d = read_adc_D();
     UARTprintf("%c:%c (%d)(%d) \t|", R_CH_D, STATE_D, SD_CH_D, adc_count_d);
     //UARTprintf("   CH D: ADC Reading = %d\n", adc_count_d);
     if (SD_CH_D < 5) {
         SD_CH_D++;
     }
     else {
         STATE_D = 'M';
     }
     break;
   case 'M':
       //0. Reset stabilize delay.
               SD_CH_D = 0;
        //1. Channel C Toggle LED Status Light.
       status_led_d = ROM_GPIOPinRead(GPIO_PORTM_BASE, GPIO_PIN_4);
       status_led_d ^= 1 << 4;
       ROM_GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_4, status_led_d);
       //UARTprintf("KIRT CH D: STATE %c\n", STATE_D);

       //2. Measure Channel C ADC.
       uint32_t adc_count_d;
       adc_count_d = read_adc_D();
       M_R_CH_D = R_CH_D;
       //UARTprintf("   CH D: ADC Reading = %d\n", adc_count_d);
       CH_D = adc_count_d;
       PN_CH_D = ROM_GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_3);
       UARTprintf("%c:%c (%d) \t|", R_CH_D, STATE_D, adc_count_d);

       //3. Switch Range based on ADC Count.
       //a. Measurement in Range. -> adc_count_low < adc_count_c < adc_count_high
      if (adc_count_d > adc_count_low & adc_count_d < adc_count_high) {
          //UARTprintf("   CH D: CR = %d.IN\n", R_CH_D);
      }
      else {
          //b. Measurement To Low. Move Up in Range.
         if (adc_count_d < adc_count_low & R_CH_D != '7') //ADC Count Low, Move to Higher Range.
         {
            //UARTprintf("   CH D: SR = %d.L\n", R_CH_D);
             STATE_D = 'U';
         }
         //c. Measurement to High. Move Down in Range.
         if (adc_count_d > adc_count_high & R_CH_D != '1') //Too High, Move to Lower Range.
         {
             //UARTprintf("   CH D: SR = %d.H\n", R_CH_D);
             STATE_D = 'D';
         }
     break;
      }

   }

   UARTprintf("\n");
}

Is there a way to increase the speed of Timer0IntHandler without affecting the main application loop. I have attached the CCS project if you would like to look at it.

Thanks,

Allanenet_uip.zip

  • Hello Allan,

    The problem you have is that your Timer ISR is taking too long to execute. So what happens when you try and slow it down is that another interrupt is waiting once you exit the current one.

    The primary culprit for this is using UARTprintf statements inside of an ISR. This should never be done as they are very slow API calls that block the ISR from processing further. You need to find a way to have the main application handle that via using flags that you set in the timer ISR to indicate when the UARTprintf needs to be executed.

    See our ISR Best Practices section of our Getting Started guide for more advice on how to optimize your ISR: https://www.ti.com/lit/pdf/spmu373

    Best Regards,
    Ralph