189 lines
3.9 KiB
C
189 lines
3.9 KiB
C
#include "counter.h"
|
|
#include <stdint.h>
|
|
#include <ssd1306xled.h>
|
|
#include "state.h"
|
|
#include "../buttons.h"
|
|
#include "../power.h"
|
|
|
|
|
|
#define CounterMinValue -99
|
|
#define CounterMaxValue 999
|
|
|
|
int16_t lastDrawnCounter = 9999;
|
|
int16_t counter = 0;
|
|
|
|
|
|
// Forward declarations
|
|
void drawCounter();
|
|
void drawDigit(uint8_t* column, uint8_t digit);
|
|
void drawMinusSign(uint8_t* column);
|
|
void blankDigitColumn(uint8_t* column, uint8_t width);
|
|
|
|
|
|
void handleCounterScreen()
|
|
{
|
|
if (button_is_pressed_short(&buttonOption))
|
|
{
|
|
// Turn off power to the screen
|
|
if (powerState == On)
|
|
setPowerState(ManualOff);
|
|
|
|
return;
|
|
}
|
|
|
|
if (button_is_pressed_long(&buttonOption))
|
|
{
|
|
setCurrentScreen(Menu);
|
|
return;
|
|
}
|
|
|
|
|
|
if (button_is_pressed_or_repeated(&buttonUp))
|
|
{
|
|
if (counter < CounterMaxValue)
|
|
counter++;
|
|
}
|
|
else if (button_is_pressed_or_repeated(&buttonDown))
|
|
{
|
|
if (counter > CounterMinValue)
|
|
counter--;
|
|
}
|
|
|
|
uint8_t invalidated = getScreenInvalidated();
|
|
if (counter != lastDrawnCounter || invalidated)
|
|
{
|
|
if (invalidated)
|
|
ssd1306_clear();
|
|
|
|
drawCounter();
|
|
lastDrawnCounter = counter;
|
|
}
|
|
}
|
|
|
|
|
|
void resetCounter()
|
|
{
|
|
counter = 0;
|
|
}
|
|
|
|
|
|
void drawCounter()
|
|
{
|
|
uint8_t column = DigitFullOffset;
|
|
|
|
if (counter < -9)
|
|
{
|
|
// Two digit negative, blank left and right (minimizes flicker) and spacing
|
|
blankDigitColumn(&column, SpacingNegativeLeft2);
|
|
drawMinusSign(&column);
|
|
blankDigitColumn(&column, DigitSpacing);
|
|
|
|
drawDigit(&column, (-counter) / 10);
|
|
blankDigitColumn(&column, DigitSpacing);
|
|
drawDigit(&column, (-counter) % 10);
|
|
|
|
blankDigitColumn(&column, SpacingNegativeRight2);
|
|
}
|
|
else if (counter < 0)
|
|
{
|
|
// Single digit negative, similar
|
|
blankDigitColumn(&column, SpacingNegativeLeft1);
|
|
drawMinusSign(&column);
|
|
blankDigitColumn(&column, DigitSpacing);
|
|
drawDigit(&column, -counter);
|
|
blankDigitColumn(&column, SpacingNegativeRight1);
|
|
}
|
|
else if (counter < 10)
|
|
{
|
|
// Single digit, blank left and right only
|
|
blankDigitColumn(&column, SpacingLeft1);
|
|
drawDigit(&column, counter);
|
|
blankDigitColumn(&column, SpacingRight1);
|
|
}
|
|
else if (counter < 100)
|
|
{
|
|
// Two digits, you know the drill by now
|
|
blankDigitColumn(&column, SpacingLeft2);
|
|
|
|
drawDigit(&column, counter / 10);
|
|
blankDigitColumn(&column, DigitSpacing);
|
|
drawDigit(&column, counter % 10);
|
|
|
|
blankDigitColumn(&column, SpacingRight2);
|
|
}
|
|
else
|
|
{
|
|
// Three digits
|
|
drawDigit(&column, counter / 100);
|
|
blankDigitColumn(&column, DigitSpacing);
|
|
drawDigit(&column, (counter % 100) / 10);
|
|
blankDigitColumn(&column, DigitSpacing);
|
|
drawDigit(&column, counter % 10);
|
|
}
|
|
}
|
|
|
|
|
|
void drawDigit(uint8_t* column, uint8_t digit)
|
|
{
|
|
if (digit > 9) return;
|
|
|
|
uint8_t yEnd = DigitPage + DigitRows;
|
|
uint16_t bitmapOffset = digit * DigitBytesPerChar;
|
|
|
|
for (uint8_t y = DigitPage; y < yEnd; y++)
|
|
{
|
|
ssd1306_setpos(*column, y);
|
|
ssd1306_send_data_start();
|
|
|
|
for (uint8_t x = 0; x < DigitWidth; x++)
|
|
{
|
|
ssd1306_send_byte(pgm_read_byte(&Digits[bitmapOffset]));
|
|
bitmapOffset++;
|
|
}
|
|
|
|
ssd1306_send_data_stop();
|
|
}
|
|
|
|
(*column) += DigitWidth;
|
|
}
|
|
|
|
|
|
void drawMinusSign(uint8_t* column)
|
|
{
|
|
uint8_t yEnd = DigitPage + DigitRows;
|
|
uint16_t bitmapOffset = 0;
|
|
|
|
for (uint8_t y = DigitPage; y < yEnd; y++)
|
|
{
|
|
ssd1306_setpos(*column, y);
|
|
ssd1306_send_data_start();
|
|
|
|
for (uint8_t x = 0; x < MinusSignWidth; x++)
|
|
{
|
|
ssd1306_send_byte(pgm_read_byte(&MinusSign[bitmapOffset]));
|
|
bitmapOffset++;
|
|
}
|
|
|
|
ssd1306_send_data_stop();
|
|
}
|
|
|
|
(*column) += MinusSignWidth;
|
|
}
|
|
|
|
|
|
void blankDigitColumn(uint8_t* column, uint8_t width)
|
|
{
|
|
uint8_t yEnd = DigitPage + DigitRows;
|
|
for (uint8_t y = DigitPage; y < yEnd; y++)
|
|
{
|
|
ssd1306_setpos(*column, y);
|
|
ssd1306_send_data_start();
|
|
|
|
for (uint8_t i = 0; i < width; i++)
|
|
ssd1306_send_byte(0);
|
|
|
|
ssd1306_send_data_stop();
|
|
}
|
|
|
|
(*column) += width;
|
|
} |