text: // Timer3A.c
  // Runs on LM4F120/TM4C123
  // Use Timer3 in 32-bit periodic mode to request interrupts at a periodic rate
  // Daniel Valvano
  // Jan 1, 2020
  
  /* This example accompanies the book
     "Embedded Systems: Real Time Interfacing to Arm Cortex M Microcontrollers",
     ISBN: 978-1463590154, Jonathan Valvano, copyright (c) 2020
    Program 7.5, example 7.6
  
   Copyright 2020 by Jonathan W. Valvano, valvano@mail.utexas.edu
      You may use, edit, run or distribute this file
      as long as the above copyright notice remains
   THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
   OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
   VALVANO SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
   OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
   For more information about my classes, my research, and my books, see
   http://users.ece.utexas.edu/~valvano/
   */
  #include <stdint.h>
  #include "../inc/tm4c123gh6pm.h"
  
  void (*PeriodicTask3)(void);   // user function
  
  // ***************** Timer3A_Init ****************
  // Activate Timer3 interrupts to run user task periodically
  // Inputs:  task is a pointer to a user function
  //          period in units (1/clockfreq)
  //          priority 0 (highest) to 7 (lowest)
  // Outputs: none
  void Timer3A_Init(void(*task)(void), uint32_t period, uint32_t priority){
    SYSCTL_RCGCTIMER_R |= 0x08;   // 0) activate TIMER3
    PeriodicTask3 = task;         // user function
    TIMER3_CTL_R = 0x00000000;    // 1) disable TIMER3A during setup
    TIMER3_CFG_R = 0x00000000;    // 2) configure for 32-bit mode
    TIMER3_TAMR_R = 0x00000002;   // 3) configure for periodic mode, default down-count settings
    TIMER3_TAILR_R = period-1;    // 4) reload value
    TIMER3_TAPR_R = 0;            // 5) bus clock resolution
    TIMER3_ICR_R = 0x00000001;    // 6) clear TIMER3A timeout flag
    TIMER3_IMR_R = 0x00000001;    // 7) arm timeout interrupt
    NVIC_PRI8_R = (NVIC_PRI8_R&0x00FFFFFF)|(priority<<29); // priority  
  // interrupts enabled in the main program after all devices initialized
  // vector number 51, interrupt number 35
    NVIC_EN1_R = 1<<(35-32);      // 9) enable IRQ 35 in NVIC
    TIMER3_CTL_R = 0x00000001;    // 10) enable TIMER3A
  }
  
  void Timer3A_Handler(void){
    TIMER3_ICR_R = TIMER_ICR_TATOCINT;// acknowledge TIMER3A timeout
    (*PeriodicTask3)();                // execute user task
  }
  
  void Timer3A_Stop(void){
    NVIC_DIS1_R = 1<<(35-32);        // 9) disable interrupt 35in NVIC
    TIMER3_CTL_R = 0x00000000;       // 10) disable timer4A
  }
  