81 lines
5.1 KiB
Markdown
81 lines
5.1 KiB
Markdown
# GPIO 7-Segment Output
|
|
## Introduction
|
|
This is a GPIO push-pull output demo application for driving a 7-segment display on the Flipper Zero. The goal of this project is to show application developers how GPIO works for push-pull output. This project was derived from the [\plugins\basic](..\..\plugins\basic\README.md) tutorial.
|
|
|
|
|
|
## Installation Directions
|
|
This project is intended to be overlayed on top of an existing firmware repo.
|
|
- Clone, Build & Deploy an existing flipper zero firmware repo. See this [tutorial](/firmware/updating/README.md) for updating firmware.
|
|
- Copy the "gpio_7segment" [folder](..) to the \applications\plugins\gpio_7segment folder in your firmware.
|
|
- Build & deploy the firmware. See this [tutorial](/firmware/updating/README.md) for updating firmware.
|
|
- NOTE: You can also extract the gpio_output_demo.FAP from resources.tar file and use qFlipper to copy the file to the SD Card/apps/Misc folder.
|
|
|
|
|
|
## Running the updated firmware
|
|
These directions assume you are starting at the flipper desktop. If not, please press the back button until you are at the desktop.
|
|
|
|
- Press the OK button on the flipper to pull up the main menu.
|
|
- Choose "Applications" from the menu.
|
|
- Choose "Gpio" from the sub-menu.
|
|
- Choose "GPIO 7-Segment Output"
|
|
|
|
- The flipper should say "GPIO 7-Segment".
|
|
- Click the "OK" button to display a random number from 1-6.
|
|
|
|
- Press the BACK button to exit.
|
|
|
|
|
|
## How it works
|
|
- application.fam
|
|
- specifies the settings for our application.
|
|
- adds "gpio" to requires.
|
|
|
|
- gpio_7segment.png
|
|
- The icon for our application that shows up in the "Misc" folder.
|
|
|
|
- gpio_7segment_app.c
|
|
- Similar to the plugin\basic tutorial.
|
|
- bool digits[70] is defined to store the segments to glow for different digits.
|
|
- each group of 7 booleans represents a number.
|
|
- note: in production code you could replace with a single byte [8-bits] to represent the segments to turn on/off. Like bit 0 is middle LED, bit 1 is bottom right, etc.
|
|
- gpio_7segment_render_callback(...) callback paints the canvas.
|
|
- Title of application
|
|
- two boxes (looks like a 7-segment display)
|
|
- index is set to the first index with our LED information
|
|
- for example to draw a 2 we index at 7*2 = 14 (which is the 15th bool, since it starts at a count of 0.)
|
|
- digits[index++] ? "A7" : "a7"
|
|
- digits[index] is the bool (true/false) from our digits table.
|
|
- if it is true we will use the text "A7" (CAPS to show on)
|
|
- if it is false we will use the text "a7" (lowercase)
|
|
- index++ will increment index to the next number.
|
|
- data->invert ? "GND" : "3.3v"
|
|
- if invert is set to true we show the text "GND" (pins will GND to glow.)
|
|
- if invert is set to false we show the text "3.3v" (pins will 3.3 to glow.)
|
|
- We show the number we are displaying on the 7-segment display.
|
|
- gpio_7segment_show(...) displays a number.
|
|
- index is set to the first index with our LED information
|
|
- for example to draw a 2 we index at 7*2 = 14 (which is the 15th bool, since it starts at a count of 0.)
|
|
- furi_hal_gpio_write(&gpio_ext_pa7, digits[index++] ^ invert);
|
|
- THIS IS THE CODE THAT CHANGES THE STATE OF THE PIN!
|
|
- gpio_ext_pa7 is the pin (a7). You can see all pin names at \firmware\targets\f7\furi_hal\furi_hal_resources.c
|
|
- digits[index++] ^ invert
|
|
- digits[index] is the bool (true/false) from our digits table.
|
|
- if invert is false, (digits[index++] ^ false) == digits[index++] (so same as table.)
|
|
- if invert it true, (digits[index++] ^ true) == !digits[index++] (so inverted from table value. This is needed for common anode 7-segment LEDs.)
|
|
- gpio_7segment_disconnect_pin(...) disconnects a pin.
|
|
- GpioModeOutputOpenDrain means that when the value is false the pin will be GND, but when the value is true the pin will be disconnected.
|
|
- GpioPullNo means there is no pull-up resistor between 3.3v and pin & there is no pull-down resistor between GND and pin.
|
|
- we write a true, so pin is disconnected.
|
|
- Some people use Input with Push/Pull-No to disconnect pins while others use OutputOpenDrain. I'm not sure if the pins are really disconnected just because you aren't reading, so I think I would prefer to use OutputOpenDrain.
|
|
- gpio_7segment_app(...) is our entry point
|
|
- furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull);
|
|
- this sets the A7 pin to be OutputPushPull.
|
|
- PushPull means pin will either be GND or 3.3volts.
|
|
- (As opposed to OutputOpenDrain when pin is GND or disconnected.)
|
|
- We use "init_simple" instead of "init", because other params aren't needed.
|
|
- context->data->digit = (furi_hal_random_get() % 6) + 1;
|
|
- when OK button is pressed we use furi_hal_random_get() to get a random number (I think from the secure random number generator).
|
|
- (x % 6) will return the remainder from dividing x by 6. Which should be a number between 0 and 5. We then add 1 to the value so we get a value between 1 and 6.
|
|
- gpio_7segment_disconnect_pin(&gpio_ext_pa7);
|
|
- when our app exits, we disconnect the pins. If we didn't the number would still show.
|