GPIO Programming:

Now with Interrupts!

Computing Machinery II Tutorial:

Week of March 25th

Review

  • Breadboard circuits (LED + 2 types of button)
  • C programs to control GPIO pins (gpio.h)
    • Setup pin to be output, have LED Blink when set
    • Setup pin to be input, have button change variable

GPIO C Programming

  • lets just use gpio.h in C
    • why do it in ARM Assembly?
  • we read and write to specific memory addresses to control the Pi's GPIO pin voltages
    • GPFSEL0, GPFSEL1,..., GPSEL5
    • GPSET0, GPSET1
    • GPCLR0, GPSET1
    • GPLEV0, GPLEV1

Assignment 3

Today:

  • Interrupt-driven programming
    • see what assignment 3 demo should look like
    • 05_GPIO_PushButton_Interrupt as toy example
      • wire breadboard for this program
      • compile and run code
      • review code
      • add switch A, falling edge type, interrupt control to decrement counter
    • extra time? outline steps to do assignment

Breakdown of interrupt code

  • includes
    • "sysreg.h" for enableIRQ();
    • "irq.h" for IRQ_ENABLE_IRQS_2
  • sharedValue
    • outside of main, in main, and in handlers.c
  • while loop
    • main take away: the sharedValue can change at any time, i.e. during the busy loop
  • init_GPIO_to_risingEdgeInterrupt()
    • *GPREN0 = (0x1 << 17);
    • *IRQ_ENABLE_IRQS_2 = (0x1 << 20);
  • handers.c
    • IRQ_handler() runs for all of our interrupts
    • sharedValue++

Add decrement button interrupt

  • places to modify code:
    • main.c
      • define init_GPIO18_to_fallingEdgeInterrupt()
        • copy code from init_GPIO17_to_....
        • GPREN0 should be replaced with GPFED0
        • 17 should be replaced with 18
      • in main()
        • add your new init function
    • handler.c
      • add condition for ( *GPEDS0 == (0x1 << 18) ) to decrement sharedValue

Recommended assignment steps

  • start with GPIO_PushButtonInterrupt code
  • get single state program running
    • remove printing of program and exception state info
    • add back LED control functions from other toy examples.
      • init_GPIO_to_output(), set_GPIO(), and clear_GPIO()
      • either replicate these LED control functions (and calls in main()) for each LED pin numbers or abstract the functions to take pin number argument.
    • infinite loop in main() just calls light_next(current_LED)
int light_next(current LED) {
    busy_loop();
    clear_GPIO(current LED);
    set_GPIO(previous LED);
    return next LED
}

More steps...

  • add states
    • sharedValue -> current state
    • modify handler.c
....
if (*IQR_PENDING_2 == 0x00100000) {
    if (interrupt pin is 23) {current_state set to 2}
    else if (interrupt pin is 24) {current_state set to 1}
    write GPEDS0 value back to itself to indicate the interrupt has been serviced
}
....
  • reparameterize light_next and busy_loop functions to also take state parameters i.e., speed and order
  • write helper functions e.g. busy_loop(int time)
  • rewrite infinite loop
while (true) {
    if (current state is 1) {
        current LED = light_next(state parameters, current LED)
    }
    else if (current state is 2) {
        current LED = light_next(state parameters, current LED)
    }
    
}

Final steps...

  • fill in all the details I missed
  • test and debug from the beginning
  • submit on D2L

Thursday..

do assignment 3 and ask questions

Pi_4

By pathomas

Pi_4

  • 700