ELEC-C7222
Libraries for ELEC C7222 Course Work
Loading...
Searching...
No Matches
gpio.hpp File Reference

GPIO abstraction split into explicit input and output classes. More...

#include <cstdint>
#include <functional>
#include "non_copyable.hpp"
Include dependency graph for gpio.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  c7222::GpioIn
 GPIO input-only wrapper with pull configuration and optional IRQ. More...
 
struct  c7222::GpioIn::Config
 Configuration structure for input GPIO setup. More...
 
class  c7222::GpioOut
 GPIO output-only wrapper with output configuration and drive strength. More...
 
struct  c7222::GpioOut::Config
 Configuration structure for output GPIO setup. More...
 

Namespaces

namespace  c7222
 C7222 course abstractions namespace.
 

Enumerations

enum class  c7222::GpioPullMode { c7222::None , c7222::PullUp , c7222::PullDown }
 GPIO pull configuration. More...
 
enum class  c7222::GpioOutputType { c7222::HighZ , c7222::PushPull , c7222::OpenDrain }
 GPIO output type. More...
 
enum class  c7222::GpioDriveStrength { c7222::mA2 , c7222::mA4 , c7222::mA8 , c7222::mA12 }
 GPIO drive strength. More...
 
enum class  c7222::GpioInputEvent : uint32_t {
  c7222::None = 0x00 , c7222::LevelLow = 0x01 , c7222::LevelHigh = 0x02 , c7222::BothLevels = 0x03 ,
  c7222::FallingEdge = 0x04 , c7222::RisingEdge = 0x08 , c7222::BothEdges = 0x0c , c7222::All = 0x0f
}
 GPIO input event bitmask for IRQ configuration. More...
 

Detailed Description

GPIO abstraction split into explicit input and output classes.

Design principles:

  • Separate input and output roles: GpioIn and GpioOut are distinct classes. This prevents accidental misuse (e.g., writing to inputs or reconfiguring outputs as inputs) and keeps configuration options focused on what each direction actually needs.
  • Single ownership per pin: Each GPIO pin is owned by at most one GpioIn or GpioOut instance at a time. Platform backends track pin ownership and assert if a second object is constructed for the same pin.
  • Config-as-state: Each class has a Config struct that captures all relevant configuration fields. The object stores a cached config and Configure() reapplies it on the platform backend.
  • Minimal, explicit API: Inputs expose Read() and IRQ management; outputs expose Write() and Toggle(). This keeps the surface small for junior programmers and reduces ambiguous behaviors.

Platform integration (Raspberry Pi Pico W):

  • The Pico backend lives in platform/rpi_pico/gpio.cpp and maps these abstractions onto the Pico SDK (hardware/gpio.h).
  • Input handling:
    • gpio_init() initializes the pin.
    • Pull configuration uses gpio_disable_pulls, gpio_pull_up, or gpio_pull_down.
    • Direction is set to input (GPIO_IN).
    • Optional IRQs are enabled via gpio_set_irq_enabled_with_callback. The backend stores a per-pin map from GPIO number to a single GpioIn instance. This enforces one input object per pin and ensures a single callback dispatch target.
  • Output handling:
    • gpio_set_drive_strength() applies pad drive strength.
    • For push-pull output, the pin is set GPIO_OUT and driven high/low.
    • For open-drain output, the SDK has no native open-drain mode; the backend emulates it by switching direction:
      • Drive low: set output low and GPIO_OUT.
      • Release high: set GPIO_IN (high-Z) so an external/internal pull-up can pull the line high.
    • The backend tracks one GpioOut per pin and asserts on duplicates.

Platform integration (grader backend):

  • The grader backend provides stub implementations that compile and mirror the API shape without touching hardware.
  • It also enforces the same one-object-per-pin rule for consistency.