AfRApay/AfRApay.MateCard/src/oled.cpp

199 lines
5.5 KiB
C++
Raw Normal View History

2023-02-06 02:23:00 +01:00
#include <WiFi.h>
#include <ESPDateTime.h>
2023-04-20 15:18:00 +02:00
#include <utility>
2023-02-06 02:23:00 +01:00
#include "Arduino.h"
#include "U8g2lib.h"
#include "logos.h"
#include "utils.h"
#include "vars.h"
2023-04-20 15:18:00 +02:00
#include "oled.h"
2023-04-22 03:08:11 +02:00
#include "readers.h"
2023-04-20 15:18:00 +02:00
OLED::OLED(U8G2 u8g2) {
this->u8g2 = std::move(u8g2);
}
void OLED::begin() {
u8g2.begin();
2023-04-21 19:27:59 +02:00
// default value is 0x80, clock divide ratio (0x00=1) and oscillator frequency (0x8)
u8g2.sendF("ca", 0xd5, 0xF0); // set the clock divider to something faster (so we get a better framerate)
2023-04-20 15:18:00 +02:00
u8g2.setFont(u8g2_font_bpixel_te);
u8g2_uint_t maxLength = 127 - u8g2.getUTF8Width("00:00:00 ");
if (u8g2.getUTF8Width(AFRAPAY_GIT_BRANCH "-" AFRAPAY_GIT_COMMIT) < maxLength) {
revision = AFRAPAY_GIT_BRANCH "-" AFRAPAY_GIT_COMMIT;
}
else if (u8g2.getUTF8Width(AFRAPAY_GIT_BRANCH) < maxLength) {
revision = AFRAPAY_GIT_BRANCH;
}
else if (u8g2.getUTF8Width(AFRAPAY_GIT_COMMIT) < maxLength) {
revision = AFRAPAY_GIT_COMMIT;
}
2023-02-06 02:23:00 +01:00
2023-04-20 15:18:00 +02:00
drawLogo(LOGO_MATECARD);
u8g2.sendBuffer();
}
void OLED::drawCurvedLineV(int xStart, int yStart, int vert, int horiz) {
2023-02-08 16:42:47 +01:00
u8g2.drawVLine(xStart, yStart + 1, vert);
u8g2.drawVLine(xStart + 1, yStart, vert);
2023-02-06 02:23:00 +01:00
2023-02-08 16:42:47 +01:00
u8g2.drawHLine(xStart, yStart + vert, horiz);
u8g2.drawHLine(xStart + 1, yStart + vert + 1, horiz);
2023-02-06 02:23:00 +01:00
}
2023-04-20 15:18:00 +02:00
void OLED::drawCurvedLine(int xStart, int yStart, int horiz, int vert) {
2023-02-08 16:42:47 +01:00
u8g2.drawHLine(xStart, yStart, horiz);
u8g2.drawHLine(xStart, yStart + 1, horiz);
2023-02-06 02:23:00 +01:00
2023-02-08 16:42:47 +01:00
u8g2.drawVLine(xStart + horiz, yStart, vert);
u8g2.drawVLine(xStart + horiz + 1, yStart + 1, vert);
2023-02-06 02:23:00 +01:00
}
2023-04-20 15:18:00 +02:00
void OLED::drawLogoAfraPay() {
2023-02-08 16:42:47 +01:00
u8g2.setFontMode(1);
u8g2.setFontDirection(0);
2023-02-06 02:23:00 +01:00
2023-02-08 16:42:47 +01:00
int xOffset = 12;
int yOffset = 23;
2023-02-06 02:23:00 +01:00
2023-02-08 16:42:47 +01:00
u8g2.setFont(u8g2_font_maniac_tr);
u8g2.drawStr(xOffset, yOffset, "AfRA");
2023-02-06 02:23:00 +01:00
2023-02-08 16:42:47 +01:00
u8g2.setFont(u8g2_font_tenthinguys_tr);
u8g2.drawStr(xOffset + 73, yOffset + 3, "pay");
2023-02-06 02:23:00 +01:00
2023-02-08 16:42:47 +01:00
// uncomment to verify distance to screen gap is equal on both sides
//u8g2.drawHLine(0, yOffset-12, xOffset);
//u8g2.drawHLine(127-xOffset-1, yOffset, xOffset);
2023-02-06 02:23:00 +01:00
2023-04-20 15:18:00 +02:00
drawCurvedLineV(xOffset + 69, yOffset, 7, 32);
drawCurvedLine(xOffset + 73, yOffset - 8, 28, 15);
2023-02-08 16:42:47 +01:00
u8g2.drawPixel(xOffset + 101, yOffset + 7);
2023-02-06 02:23:00 +01:00
}
2023-04-20 15:18:00 +02:00
void OLED::drawLogoBitmap(int width, int height, unsigned char bits[], int yOffset) {
2023-02-08 16:42:47 +01:00
int offset = (128 - width) / 2;
u8g2.drawXBM(offset, yOffset, width, height, bits);
2023-02-06 02:23:00 +01:00
}
2023-04-20 15:18:00 +02:00
void OLED::drawLogo(e_logo logo) {
2023-02-08 16:42:47 +01:00
switch (logo) {
case LOGO_AFRAPAY:
2023-04-20 15:18:00 +02:00
drawLogoAfraPay();
2023-02-08 16:42:47 +01:00
break;
case LOGO_CONTACTLESS:
2023-04-20 15:18:00 +02:00
drawLogoBitmap( contactless_width, contactless_height, contactless_bits);
2023-02-08 16:42:47 +01:00
break;
2023-04-22 03:08:11 +02:00
case LOGO_FELICA:
drawLogoBitmap( felica_width, felica_height, felica_bits);
break;
2023-02-08 16:42:47 +01:00
case LOGO_MATECARD:
2023-04-20 15:18:00 +02:00
drawLogoBitmap(matecard_width, matecard_height, matecard_bits, 5);
2023-02-08 16:42:47 +01:00
u8g2.setFont(u8g2_font_bpixeldouble_tr);
u8g2.drawStr((126 - u8g2.getStrWidth("matecard")) / 2, 57, "matecard");
break;
case LOGO_PENDING:
2023-04-20 15:18:00 +02:00
drawLogoBitmap(pending_width, pending_height, pending_bits, 5);
2023-02-08 16:42:47 +01:00
break;
case LOGO_SUCCESS:
2023-04-20 15:18:00 +02:00
drawLogoBitmap(success_width, success_height, success_bits, 5);
2023-02-08 16:42:47 +01:00
break;
case LOGO_FAILURE:
2023-04-20 15:18:00 +02:00
drawLogoBitmap(failure_width, failure_height, failure_bits, 5);
2023-02-08 16:42:47 +01:00
break;
}
2023-02-06 02:23:00 +01:00
}
2023-04-22 15:10:26 +02:00
void OLED::drawStatusText(const String& status, const String& statusRightAligned, bool japan) {
if (japan)
u8g2.setFont(u8g2_font_b12_t_japanese2);
else
u8g2.setFont(u8g2_font_bpixel_te);
2023-02-08 16:42:47 +01:00
u8g2.drawUTF8(0, 61, status.c_str());
2023-02-06 02:23:00 +01:00
2023-02-08 16:42:47 +01:00
if (!statusRightAligned.isEmpty()) {
2023-04-22 15:10:26 +02:00
if (japan)
u8g2.setFont(u8g2_font_bpixel_te);
2023-02-08 16:42:47 +01:00
int textWidth = u8g2.getUTF8Width(statusRightAligned.c_str());
u8g2.drawUTF8(126 - textWidth, 61, statusRightAligned.c_str());
}
2023-02-06 02:23:00 +01:00
}
2023-04-20 15:18:00 +02:00
void OLED::drawFullScreenText(const String& textTop, const String& textBottom) {
2023-02-08 16:42:47 +01:00
u8g2.setFont(u8g2_font_chargen_92_tr);
u8g2.drawUTF8((127-u8g2.getUTF8Width(textTop.c_str()))/2, 13, textTop.c_str());
u8g2.setFont(u8g2_font_maniac_te);
u8g2.drawUTF8((127-u8g2.getUTF8Width(textBottom.c_str()))/2, 45, textBottom.c_str());
2023-02-06 02:23:00 +01:00
}
2023-04-22 15:10:26 +02:00
void OLED::updateOLED(e_state state, const String& statusText, const String& statusTextRightAligned, bool japan) {
2023-02-08 16:42:47 +01:00
u8g2.clearBuffer();
switch (state) {
case STATE_IDLE:
2023-04-20 15:18:00 +02:00
drawLogo(LOGO_AFRAPAY);
2023-02-08 16:42:47 +01:00
break;
case STATE_TRANSACT_CARDSCAN:
case STATE_BALANCE_CARDSCAN:
case STATE_LINK_CARD_SCAN:
case STATE_LINK_CARD_RESCAN:
2023-04-22 03:08:11 +02:00
if (PN532Reader::mode == PN532_MIFARE_ISO14443A)
drawLogo(LOGO_CONTACTLESS);
else
drawLogo(LOGO_FELICA);
2023-02-08 16:42:47 +01:00
break;
case STATE_RESULT_SUCCESS:
2023-04-20 15:18:00 +02:00
drawLogo(LOGO_SUCCESS);
2023-02-08 16:42:47 +01:00
break;
case STATE_RESULT_FAILURE:
2023-04-20 15:18:00 +02:00
drawLogo(LOGO_FAILURE);
2023-02-08 16:42:47 +01:00
break;
case STATE_RESULT_DISPLAY:
2023-04-22 15:28:25 +02:00
if (japan) {
String balance = splitString(statusText, ':', 1);
balance.replace(",", "");
if (balance.startsWith("-")) {
balance.replace("-00", "-");
balance.replace("-0", "-");
balance.replace("-", "");
}
else {
if (balance.startsWith("00"))
balance = balance.substring(2);
else if (balance.startsWith("0"))
balance = balance.substring(1);
balance = "¥" + balance;
}
drawFullScreenText(splitString(statusText, ':', 0), balance);
}
else
drawFullScreenText(splitString(statusText, ':', 0), splitString(statusText, ':', 1) + "");
2023-04-20 15:18:00 +02:00
drawStatusText(splitString(statusText, ':', 2), statusTextRightAligned);
2023-02-08 16:42:47 +01:00
u8g2.sendBuffer();
return;
case STATE_TRANSACT_VERIFY:
case STATE_BALANCE_VERIFY:
case STATE_LINK_VERIFY:
2023-04-20 15:18:00 +02:00
drawLogo(LOGO_PENDING);
2023-02-08 16:42:47 +01:00
break;
}
2023-04-22 15:10:26 +02:00
drawStatusText(statusText, statusTextRightAligned, japan);
2023-02-08 16:42:47 +01:00
u8g2.sendBuffer();
2023-02-06 02:23:00 +01:00
}
2023-04-20 15:18:00 +02:00
void OLED::updateOLED(e_state state) {
2023-02-08 16:42:47 +01:00
String time = DateTime.format(DateFormatter::TIME_ONLY);
2023-04-20 15:18:00 +02:00
if (!digitalRead(PIN_INTERRUPT_CANCEL) || millis()%20000 < 10000) {
updateOLED(state, time, revision);
}
else {
updateOLED(state, time, WiFi.localIP().toString());
}
2023-02-08 16:42:47 +01:00
}