,

MCU – Timer and Interrupts in LPC2378

Overview

  • Timer is used to create delays and synchronization
  • A pre-scaler converts clock frequency (say 1 MHZ) to required frequecny (say 500khz). So the pre-scalar will simply listen to clock frequecny and send input after listening to 2 pulses

Features of timers in LPC23xx

  • 4 timers/counters
    • timer module measure the passage of time using internal clock signals. example: raise an intrrupt every 1ms
    • counter keeps tracks of external events such as pulses. example: number of revolutions of a button press
  • 4 channels/timers
  • min 2 capture inputs and 2 match output pins for all 4 timers
  • 32 bit timerc/counter with programmable prescalar
  • counter/timer operation

Timer

Timer Register Map

  • 0-3 regiters – 4 registers
  • Interuppt register
    • Shows interrupt status for each match/capture.
    • Write 1 to clear interrupts.
    • Example: Clear MR0 interrupt:
      • cIR = (1 << 0); // Clear interrupt for MR0
  • Timer Control Register (TCR)
    • Enables or resets the timer/counter
    • Example: To start the timer and clear it to zero,
      • cTCR = 0x02; // Reset timer counter
      • TCR = 0x01; // Enable timer
  • Timer Counter
    • Holds the current count value of the timer/counter
    • Example: You can read the elapsed time by reading TC:
      • cuint32_t elapsed_time = TC;
    • incremented by PR+1 cycles of PCLK (peripheral clock)
    • By default PR =0 in which case timer counter is incremented at every clock frequency
    • If PR =1 then Timer counter is incremented by 1 every 2 clock frequency
  • Prescale Register (PR)
    • Sets the division factor for the input clock to slow down the timer increment rate
    • Example: Setting the prescaler to 100 means the timer increments every 100 clock cycles:
      • cPR = 99; // Since count starts from 0
  • Prescale Counter
    • Counts from 0 up to PR and then increments TC. Read-only; you typically don’t write to this
  • Match Control Register
    • Configures the behavior when the timer matches a specified value (generate interrupt, reset, stop, etc.)
    • Example: Generate interrupt and reset timer on MR0 match:
      • cMCR = (1 << 0) | (1 << 1); // Interrupt and reset on match channel 0
  • MR0/1/2/3
    • Store values to be compared against the timer count; actions in MCR are triggered when TC equals an MRx value
    • Example: Set MR0 for 10000 ticks:
      • cMR0 = 10000;
  • Capture Control Register
    • Controls if and how the timer captures external events for measurement (such as edge detection on pins)
    • Example: Capture on rising edge of CAP0 pin and generate interrupt:
      • cCCR = (1 << 0) | (1 << 1); // Capture on rising edge + interrupt enable for CAP0
  • Capture Register 0/1
    • Store the counter values when capture events occur
    • Example: Read captured timer on CAP0 event:
      • cuint32_t captured_value = CR0;
  • External Match Register
    • Controls external output changes based on match events, often tied to physical pins for PWM or signaling
    • Example: Toggle output on match on channel 0:
    • cEMR |= (3 << 4); // Bits 5:4 set to 11 to toggle output on match channel 0
  • Count Control Register

Example

Calculation of time delay

  • PCLK= Peripheral Frequency = CPU Clock / APB Divider
    • CPU Clock = 48 MHZ
    • APB Divider = 4 (by default)
  • Timer Tick period (interval for 1 increment of TC)
    • T tick = T0PR + 1 / PCLCK
    • so if 1 want 1 ms interval then
      • T0PR + 1 = (1ms x 12 MHZ)
      • T0PR + 1 = (1000 micro seconds x (12 x 1 micro second))
      • T0PR + 1 = 12000 micro seconds
      • T0PR = 12000-1
  • Calculate T0MR0 value to generate required delay by matching
    • T = (MR0+1)Ttick
    • If I want delay of 1 second
      • MR0+1 = 1000ms /1ms
      • MR0+1 = 1000ms
      • MR0 = 1000-1
      • MR0=999

Timer Programming

  • Reset the timer0 initially to deactivate counting
  • Load calculated values in Prescalar register T0PR and Match register T0MR0
  • Initialize T0PC and T0TC register
  • select operations using match registers when match encountered
  • Start Timer by enabling through T0TCR register
  • Wait till the interrupt and clear the flag by writing T0IR register

This is based on polling method since in while loop it continusly tries to match to a value and on matching moves further

Interrupts

  • An interrupt is a signal sent to CPU that an event has occurred that requires immediate attention
  • Iterrupt Request (IRQ) is a special request sent to CPU to execute a small function
  • Interrupt Service Routine: is a small piece of code in a function
  • In LPC23 xx VIC is external to CPU connected via a high performance bus

Features

  • ARM PrimeCell Vectored INterrupt Controller
  • Mapped to AHB address space for fast access
  • Supports 32 vectored IRQ interrupts
  • 16 programmable interrupt priority levels
  • Fixed hardware priority within each programmable priority level
  • Hardware priority level masking
  • Any input can be assigned to FIQ interrupt
  • Software interrupt generation

VIC Interrupt structure

  • Component from ARM prime cell
  • Highly optimized interrupt controller
  • Handles all on-chip interrupt sources from peripherals
    • all interrupt sources are connected to VIC on fixed channel

VIC Register Map

  • VICIRQStatus – IRQ Status Register: reads out the state of the interrupt requests that are enabled and classified as IRQ
  • VICFIQStatus – FIQ Status Register: reads out the state of the interrupt requests that are enabled and classified as FIQ
  • VICRawIntr – Raw Interrupt Status Register: reads out the state of the 32 interrupt requests regardless of enabling or classification
  • VICIntSelect – Interrupt Select Register: classifies each of the 32 interrupt requests as contributing to FIQ or IRQ
  • VICIntEnable – Interrupt Enable Register: controls which of the 32 interrupt requests and software interrupts are enabled to contribute to FIQ or IRQ
  • VICIntEnClr – Interrupt Enable Clear Register: allows software to clear one or more bits in the Interrupt Enable Register
  • VICSoftInt – Software Interrupt Register: contents of this are ORed with the 32 interrupt requests from various peripherals
  • VICSoftIntClear – Software Interrupt Clear Register: allows software to clear one or more bits in the Software Interrupt Register
  • VICProtection – Protection enable register: allows limiting access to VIC registers by software running in privileged mode
  • VICVectAddr0-31 – Vector address 0-31 register: holds the address of ISR for the 32 vectored IRQ slots
  • VICVectPriority0-31 – designates the priority of each of the corresponding vectored IRQ slot
  • VICAddress – Vector address register: When an IRQ occurs, it holds the address of the currently active interrupt

How are interrupts processed?

  • ARM processor core has 2 interrupt inputs called FIQ (Fast Interrupt Request) and IRQ (Interrupt request)
  • VIC takes 32 interrupt requests and programmatically assigns to FIQ or vectored IRQ
  • FIQ has highest priority
  • In case more than 1 interrupt is assigned to FIQ then VIC ORs the request to produce the FIQ signal
  • Vectored IRQs have programmable priorities and VIC ORs the requests from all vectored IRQs to produce IRQ signal for the processor

Working with FIQ Interrupts

  • Any interrupt source can be assigned to FIQ interrupt
    • Several FIQ sources slows entry into the ISR code
  • Step 1: VIC Interrupt Select Register has a unique bit for each interrupt (see manual)
  • Step 2: Once FIQ source is selected then interrupt can be enabled in the VIC Interrupt Enable Register
  • Step 3: Once FIQ interrupt is generated the processor will switch to FIQ mode and vector to FIQ vector
  • Step 4: Jump to ISR routine to server the interrupt
  • Once ISR routine is complete and ready to exit
  • Step 5: clear any interrupt status flags in the peripheral
    • else will get continous interrupts
    • to clear flag write logic 1 not logic 0
  • VIC FIQ Status Register can be examined to know the Interrupt source

Working with Vectored IRQ

  • VIC provides a programmable h/w lookup table that can contain address of C function to run for a interrupt source
  • VIC contains 32 slots for vector addressing with each slot containing
    • Vector Priority Register – assign priority to each slot
      • total 16 priority levels 0-15 (0 being highest)
      • after reset priority of all VIC slots is set to 15
    • Vector Address Register – address of the ISR
  • Step 1: initialize Vector Address Register to address of C function to run on interrupt
  • Step 2: ARM CPU will enter into IRQ mode and jump to IRQ vector
  • Once ISR routine is complete and ready to exit
  • Step 3: clear any interrupt status flags in the peripheral
  • Step 4: write a dummy write to the Vector Address Register
    • this signals the end of the interrupt to VIC and any pending IRQ interrupt will be asserted

Interrupt Programming

See below how the interrupt generated by Timer0 (line 21 above) goes to CPU which then calls the T0isr routine