ShiboSoftwareDev/linux-gameboy-advance

A multilayer PCB carrier board routing a USB-C, battery/charging and buck-boost power system, MCU/SoC, LCD/SD/UART/I²C/SPI interfaces, audio controls, backlight, and RGB status indicators with vias and ground pours.

Version
1.0.132
License
unset
Stars
0

firmware/rgb-demo.py

#!/usr/bin/env python3
"""Drive the board's active-low PCF8575 RGB status LED with libgpiod 2.x.

The three channels are intentionally digital status outputs, not a timing-
sensitive addressable LED or a PWM display.  Run ``gpioinfo`` to identify the
PCF8575 gpiochip if it is not /dev/gpiochip1.
"""
import argparse
import time

COLORS = {
    'off': (False, False, False),
    'red': (True, False, False),
    'green': (False, True, False),
    'blue': (False, False, True),
    'yellow': (True, True, False),
    'cyan': (False, True, True),
    'magenta': (True, False, True),
    'white': (True, True, True),
}


def main():
    p = argparse.ArgumentParser(description=__doc__)
    p.add_argument('--chip', default='/dev/gpiochip1', help='PCF8575 GPIO chip from gpioinfo')
    p.add_argument('--color', choices=COLORS, default='green')
    p.add_argument('--seconds', type=float, default=3)
    p.add_argument('--demo', action='store_true', help='cycle primary colors and white')
    p.add_argument('--dry-run', action='store_true', help='print the requested line states')
    args = p.parse_args()
    if args.seconds < 0:
        p.error('--seconds must be nonnegative')
    if args.dry_run:
        print(dict(zip(('STATUS_R_N', 'STATUS_G_N', 'STATUS_B_N'), COLORS[args.color])))
        return
    import gpiod
    from gpiod.line import Direction, Value
    low, high = Value.INACTIVE, Value.ACTIVE
    names = ('STATUS_R_N', 'STATUS_G_N', 'STATUS_B_N')
    # Named lines prevent silently targeting a game-control input if gpiochip
    # numbering changes between BSP and mainline kernels.
    with gpiod.request_lines(args.chip, consumer='gba-status-indicator', config={
        names: gpiod.LineSettings(direction=Direction.OUTPUT, output_value=high)
    }) as req:
        def show(color):
            # Common anode: low turns a channel on, high turns it off.
            req.set_values({name: low if on else high for name, on in zip(names, COLORS[color])})
        try:
            colors = ('red', 'green', 'blue', 'white') if args.demo else (args.color,)
            for color in colors:
                show(color)
                time.sleep(args.seconds)
        finally:
            show('off')


if __name__ == '__main__':
    main()