Skip to content

Commit

Permalink
Adding the last examples.
Browse files Browse the repository at this point in the history
  • Loading branch information
LuckyResistor committed Jul 14, 2019
1 parent d86326e commit 9f59ad0
Show file tree
Hide file tree
Showing 32 changed files with 2,039 additions and 0 deletions.
162 changes: 162 additions & 0 deletions fade_demo_05/Animation.cpp
@@ -0,0 +1,162 @@
#include "Animation.hpp"

// Warning: This is a code example for the article "guideline for modular firmware".
// It is code in a transition phase, do not use it as it is!

#include "Display.hpp"


namespace Animation {


const uint8_t cModeCount = 4;
const uint8_t cShiftSpeed = 8;
const uint8_t cBlinkSpeed = 10;
Mode gLedMode = Mode::Fade;
uint8_t gLedIndex = 0;
uint8_t gLedCounter = 0;
bool gLedDirection = false;
bool gOrangeDirection = true;
bool gGreenDirection = true;
bool gRedDirection = true;


void initialize()
{
// nothing to do.
}


void initializeMode()
{
if (gLedMode == Mode::Fade) {
Display::setLevel(Display::Color::Orange, 0x0c);
Display::setLevel(Display::Color::Green, 0x12);
Display::setLevel(Display::Color::Red, 0x18);
} else if (gLedMode == Mode::RollLeft) {
gLedIndex = 0;
gLedDirection = true;
Display::setLevel(Display::Color::Orange, (gLedIndex & 0x3) * 8);
Display::setLevel(Display::Color::Green, ((gLedIndex + 1) & 0x3) * 8);
Display::setLevel(Display::Color::Red, ((gLedIndex + 2) & 0x3) * 8);
gLedCounter = 0;
} else if (gLedMode == Mode::RollRight) {
gLedIndex = 0;
gLedDirection = false;
Display::setLevel(Display::Color::Orange, (gLedIndex & 0x3) * 8);
Display::setLevel(Display::Color::Green, ((gLedIndex + 1) & 0x3) * 8);
Display::setLevel(Display::Color::Red, ((gLedIndex + 2) & 0x3) * 8);
gLedCounter = 0;
}
}


void setMode(Mode mode)
{
if (gLedMode != mode) {
gLedMode = mode;
initializeMode();
}
}


void cycleMode(CycleDirection cycleDirection)
{
uint8_t mode = static_cast<uint8_t>(gLedMode);
if (cycleDirection == Next) {
++mode;
} else {
--mode;
}
mode &= 0x3;
setMode(static_cast<Mode>(mode));
}


void progress()
{
if (gLedMode == Mode::Fade) {
if (gOrangeDirection) {
auto level = Display::getLevel(Display::Color::Orange);
++level;
Display::setLevel(Display::Color::Orange, level);
if (level == Display::getMaximumLevel()) {
gOrangeDirection = false;
}
} else {
auto level = Display::getLevel(Display::Color::Orange);
--level;
Display::setLevel(Display::Color::Orange, level);
if (level == 0) {
gOrangeDirection = true;
}
}
if (gGreenDirection) {
auto level = Display::getLevel(Display::Color::Green);
++level;
Display::setLevel(Display::Color::Green, level);
if (level == Display::getMaximumLevel()) {
gGreenDirection = false;
}
} else {
auto level = Display::getLevel(Display::Color::Green);
--level;
Display::setLevel(Display::Color::Green, level);
if (level == 0) {
gGreenDirection = true;
}
}
if (!gRedDirection) {
auto level = Display::getLevel(Display::Color::Red);
--level;
Display::setLevel(Display::Color::Red, level);
if (level == 0) {
gRedDirection = true;
}
} else {
auto level = Display::getLevel(Display::Color::Red);
++level;
Display::setLevel(Display::Color::Red, level);
if (level == Display::getMaximumLevel()) {
gRedDirection = !gRedDirection;
}
}
} else if (gLedMode == Mode::RollRight) {
++gLedCounter;
if (gLedCounter >= cShiftSpeed) {
gLedCounter = 0;
gLedIndex = ((gLedIndex + 1) & 0x3);
Display::setLevel(Display::Color::Green, ((gLedIndex + 1) & 0x3) * 8);
Display::setLevel(Display::Color::Orange, (gLedIndex & 0x3) * 8);
Display::setLevel(Display::Color::Red, ((gLedIndex + 2) & 0x3) * 8);
}
} else if (gLedMode == Mode::RollLeft) {
++gLedCounter;
if (gLedCounter >= cShiftSpeed) {
--gLedIndex;
gLedIndex &= 0x3;
gLedCounter = 0;
Display::setLevel(Display::Color::Orange, (gLedIndex & 0x3) * 8);
Display::setLevel(Display::Color::Green, ((gLedIndex + 1) & 0x3) * 8);
Display::setLevel(Display::Color::Red, ((gLedIndex + 2) & 0x3) * 8);
}
} else if (gLedMode == Mode::Blink) {
++gLedCounter;
if (gLedCounter >= cBlinkSpeed) {
gLedCounter = 0;
auto orangeLevel = Display::getLevel(Display::Color::Orange);
if (orangeLevel != 0) {
Display::setLevel(Display::Color::Orange, 0);
Display::setLevel(Display::Color::Green, 0);
Display::setLevel(Display::Color::Red, 0);
} else {
Display::setLevel(Display::Color::Orange, Display::getMaximumLevel());
Display::setLevel(Display::Color::Green, Display::getMaximumLevel());
Display::setLevel(Display::Color::Red, Display::getMaximumLevel());
}
}
}
}


}
52 changes: 52 additions & 0 deletions fade_demo_05/Animation.hpp
@@ -0,0 +1,52 @@
#pragma once

// Warning: This is a code example for the article "guideline for modular firmware".
// It is code in a transition phase, do not use it as it is!

#include <Arduino.h>

/// The module to animate the LEDs
///
namespace Animation {


/// The animation mode.
///
enum class Mode : uint8_t {
Fade = 0,
RollRight = 1,
RollLeft = 2,
Blink = 3
};


/// The Cycle Direction.
///
enum CycleDirection : uint8_t {
Next,
Previous
};


/// Initialize the animation module.
///
void initialize();

/// Set the current animation mode.
///
void setMode(Mode mode);

/// Cycle the current mode.
///
void cycleMode(CycleDirection cycleDirection);

/// Get the current animation mode.
///
Mode getMode();

/// Progress the current animation.
///
void progress();


}
58 changes: 58 additions & 0 deletions fade_demo_05/Buttons.cpp
@@ -0,0 +1,58 @@
#include "Buttons.hpp"

// Warning: This is a code example for the article "guideline for modular firmware".
// It is code in a transition phase, do not use it as it is!

namespace Buttons {


bool gLastButtonA = true;
bool gLastButtonB = true;
Function gPlusCallback = nullptr;
Function gMinusCallback = nullptr;


void initialize()
{
DDRB &= ~0b00000110;
PORTB |= 0b00000110;
}


void setCallback(Button button, Function fn)
{
switch (button) {
case Plus: gPlusCallback = fn; break;
case Minus: gMinusCallback = fn; break;
default: break;
}
}


void poll()
{
Button pressedButton = NoButton;
const uint8_t pinInput = PINB;
const bool buttonPressA = ((pinInput & 0b00000100) != 0);
if (buttonPressA != gLastButtonA) {
if (!buttonPressA) {
pressedButton = Plus;
}
gLastButtonA = buttonPressA;
}
bool buttonPressB = (pinInput & 0b00000010);
if (buttonPressB != gLastButtonB) {
if (!buttonPressB) {
pressedButton = Minus;
}
gLastButtonB = buttonPressB;
}
switch (pressedButton) {
case Plus: gPlusCallback(); break;
case Minus: gMinusCallback(); break;
default: break;
}
}


}
38 changes: 38 additions & 0 deletions fade_demo_05/Buttons.hpp
@@ -0,0 +1,38 @@
#pragma once

#include <Arduino.h>

// Warning: This is a code example for the article "guideline for modular firmware".
// It is code in a transition phase, do not use it as it is!

/// A module to handle button presses.
///
namespace Buttons {

/// The callback function.
///
typedef void (*Function)();

/// The button.
///
enum Button : uint8_t {
NoButton = 0,
Plus = 1,
Minus = 2
};


/// Initialize the buttons module.
///
void initialize();

/// Set a callback if the given button is pressed.
///
void setCallback(Button button, Function fn);

/// Poll the button states.
///
void poll();


}
75 changes: 75 additions & 0 deletions fade_demo_05/Display.cpp
@@ -0,0 +1,75 @@
#include "Display.hpp"

// Warning: This is a code example for the article "guideline for modular firmware".
// It is code in a transition phase, do not use it as it is!

namespace Display {


const uint8_t cMaximumLevel = 0x20;
const uint8_t cLedCount = 3;
const uint8_t cOrangeMask = 0b00001000u;
const uint8_t cGreenMask = 0b00010000u;
const uint8_t cRedMask = 0b00100000u;
const uint8_t cAllLedsMask = cOrangeMask|cGreenMask|cRedMask;
const uint8_t cLedMask[cLedCount] = {cOrangeMask, cGreenMask, cRedMask};

volatile uint8_t gFadeCounter = 0;
volatile uint8_t gLevel[cLedCount];


void initialize()
{
// Initialize the time and enable the interrupt.
TCCR2A = 0;
TCCR2B = 1;
OCR2A = 0;
OCR2B = 0;
TIMSK2 = _BV(TOIE2);
// Set all LED pins in output mode.
DDRB |= cAllLedsMask;
PORTB &= ~cAllLedsMask;
// Set all levels to zero.
memset(gLevel, 0, sizeof gLevel);
}


uint8_t getMaximumLevel()
{
return cMaximumLevel;
}


uint8_t getLevel(Color color)
{
return gLevel[static_cast<uint8_t>(color)];
}


void setLevel(Color color, uint8_t level)
{
gLevel[static_cast<uint8_t>(color)] = level;
}


inline void timerInterrupt()
{
++gFadeCounter;
gFadeCounter &= 0x1f;
uint8_t mask = 0;
for (uint8_t i = 0; i < cLedCount; ++i) {
if (gFadeCounter < gLevel[i]) {
mask |= cLedMask[i];
}
}
PORTB = ((PORTB & ~cAllLedsMask) | mask);
}


}


ISR(TIMER2_OVF_vect)
{
Display::timerInterrupt();
}

0 comments on commit 9f59ad0

Please sign in to comment.