Actions

Difference between revisions of "Arduino-like pin definitions in C++"

From Just in Time

(Created page with "We regularly design "bare" AVR devices (meaning: non-Arduino). While we're doing that, we often need to do some of the following: * When designing a single-sided PCB, complete...")
 
Line 12: Line 12:
 
This page describes our pin-definition library, that breaks the false dichotomy of either fast or readable pin usage.
 
This page describes our pin-definition library, that breaks the false dichotomy of either fast or readable pin usage.
  
==TLDR==
+
==TL;DR==
 +
Pin-definitions is a header-only library, you can find the sources on [https://github.com/DannyHavenith/avr_utilities GitHub], in file [https://github.com/DannyHavenith/avr_utilities/blob/master/avr_utilities/pin_definitions.hpp pin_definitions.hpp]
 
<source lang='cpp'>
 
<source lang='cpp'>
 
#include "avr_utilities/pin_definitions.hpp"
 
#include "avr_utilities/pin_definitions.hpp"

Revision as of 00:13, 27 July 2014

We regularly design "bare" AVR devices (meaning: non-Arduino). While we're doing that, we often need to do some of the following:

  • When designing a single-sided PCB, completely re-assign many pins in order to avoid bridges.
  • Create a library for commonly used components like a hd44780 LCD display, or NRF24L01+ transceiver, making the pins that connect to these devices configurable.
  • Implement non-trivial signaling protocols while keeping the source code readable.

All of these scenarios require us to allocate pins or groups of pins to functions in such a way that we don't have to re-write our code when that allocation changes for some reason. At the same time we need to keep the code that actually uses these pins as clean as possible.

In AVR-land, there are two main schools of defining your pins:

  • The C-style way, using #defines for the register and bit positions of a pin, which results in code that performs well, but can be somewhat combersome and does not score high on readability.
  • The Arduino way, using digitalWrite( pin, value) and a single integer to designate a pin, which is arguably easier to read and easier to re-allocate, but can take many clock cycles to do something simple like setting a single bit.

This page describes our pin-definition library, that breaks the false dichotomy of either fast or readable pin usage.

TL;DR

Pin-definitions is a header-only library, you can find the sources on GitHub, in file pin_definitions.hpp <source lang='cpp'>

  1. include "avr_utilities/pin_definitions.hpp"

// declare a single pin DECLARE_PIN( led1, D, 6); DECLARE_PIN( led2, B, 0);

// declare a consecutive range of pins in a single register DECLARE_PIN_GROUP( counter, D, 2, 3); // D2, D3 and D4 are a counter DECLARE_PIN_GROUP( quad_rotary, D, 5, 2); // D5, D6 are some inpt, e.g. from a quadrature rotary encoder

void do_stuff() { // initialize data direction for the output pins. init_as_output(led1 | led2 | counter);

while (true) { write( counter, read(quad_rotary)); if (read(quad_rotary) == 10) { set( led1); reset( led2); } else { set( led2); reset( led1); } } } </source>