mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[apps/hardware_test] Remove POST from hardware tests
This commit is contained in:
@@ -1,15 +1,12 @@
|
||||
app_src += $(addprefix apps/hardware_test/,\
|
||||
app.cpp \
|
||||
arrow_view.cpp \
|
||||
battery_test_controller.cpp \
|
||||
centered_screen_test_controller.cpp \
|
||||
code_128b_view.cpp \
|
||||
dead_pixels_test_controller.cpp \
|
||||
keyboard_test_controller.cpp \
|
||||
keyboard_view.cpp \
|
||||
lcd_data_test_controller.cpp \
|
||||
led_test_controller.cpp \
|
||||
pop_up_controller.cpp \
|
||||
serial_number_controller.cpp \
|
||||
vblank_test_controller.cpp \
|
||||
)
|
||||
|
||||
@@ -20,14 +20,11 @@ App::App(Container * container, Snapshot * snapshot) :
|
||||
|
||||
App::WizardViewController::WizardViewController(Responder * parentResponder) :
|
||||
BankViewController(parentResponder),
|
||||
m_batteryTestController(this),
|
||||
m_centeredScreenTestController(this),
|
||||
m_deadPixelsTestController(this),
|
||||
m_keyboardController(this),
|
||||
m_lcdDataTestController(this),
|
||||
m_ledTestController(this),
|
||||
m_serialNumberController(this),
|
||||
m_vBlankTestController(this)
|
||||
m_serialNumberController(this)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -37,13 +34,10 @@ int App::WizardViewController::numberOfChildren() {
|
||||
|
||||
ViewController * App::WizardViewController::childAtIndex(int i) {
|
||||
ViewController * children[] = {
|
||||
&m_vBlankTestController,
|
||||
&m_lcdDataTestController,
|
||||
&m_centeredScreenTestController,
|
||||
&m_deadPixelsTestController,
|
||||
&m_ledTestController,
|
||||
&m_keyboardController,
|
||||
&m_batteryTestController,
|
||||
&m_serialNumberController
|
||||
};
|
||||
return children[i];
|
||||
|
||||
@@ -2,14 +2,11 @@
|
||||
#define HARDWARE_TEST_APP_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "battery_test_controller.h"
|
||||
#include "centered_screen_test_controller.h"
|
||||
#include "dead_pixels_test_controller.h"
|
||||
#include "keyboard_test_controller.h"
|
||||
#include "lcd_data_test_controller.h"
|
||||
#include "led_test_controller.h"
|
||||
#include "serial_number_controller.h"
|
||||
#include "vblank_test_controller.h"
|
||||
|
||||
class AppsContainer;
|
||||
|
||||
@@ -30,14 +27,11 @@ private:
|
||||
ViewController * childAtIndex(int i) override;
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
private:
|
||||
BatteryTestController m_batteryTestController;
|
||||
CenteredScreenTestController m_centeredScreenTestController;
|
||||
DeadPixelsTestController m_deadPixelsTestController;
|
||||
KeyboardTestController m_keyboardController;
|
||||
LCDDataTestController m_lcdDataTestController;
|
||||
LEDTestController m_ledTestController;
|
||||
SerialNumberController m_serialNumberController;
|
||||
VBlankTestController m_vBlankTestController;
|
||||
};
|
||||
|
||||
App(Container * container, Snapshot * snapshot);
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
#include "battery_test_controller.h"
|
||||
#include "../constant.h"
|
||||
#include "app.h"
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
}
|
||||
#include <poincare/print_float.h>
|
||||
#include <poincare/preferences.h>
|
||||
|
||||
using namespace Poincare;
|
||||
|
||||
namespace HardwareTest {
|
||||
|
||||
BatteryTestController::BatteryTestController(Responder * parentResponder) :
|
||||
ViewController(parentResponder),
|
||||
m_view()
|
||||
{
|
||||
}
|
||||
|
||||
View * BatteryTestController::view() {
|
||||
return &m_view;
|
||||
}
|
||||
|
||||
bool BatteryTestController::handleEvent(Ion::Events::Event event) {
|
||||
if (event == Ion::Events::OK) {
|
||||
if (strcmp(m_view.batteryStateTextView()->text(), k_batteryOKText) == 0) {
|
||||
// Handled in WizardViewController
|
||||
return false;
|
||||
}
|
||||
}
|
||||
updateBatteryState(Ion::Battery::voltage(), Ion::Battery::isCharging());
|
||||
return true;
|
||||
}
|
||||
|
||||
void BatteryTestController::viewWillAppear() {
|
||||
const char * text = Ion::Battery::level() != Ion::Battery::Charge::FULL ? k_batteryNeedChargingText : k_batteryOKText;
|
||||
KDColor color = Ion::Battery::level() != Ion::Battery::Charge::FULL ? KDColorRed : KDColorGreen;
|
||||
m_view.setColor(color);
|
||||
m_view.batteryStateTextView()->setText(text);
|
||||
updateBatteryState(Ion::Battery::voltage(), Ion::Battery::isCharging());
|
||||
}
|
||||
|
||||
void BatteryTestController::updateBatteryState(float batteryLevel, bool batteryCharging) {
|
||||
constexpr size_t bufferLevelSize = ContentView::k_maxNumberOfCharacters + PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits);
|
||||
char bufferLevel[bufferLevelSize];
|
||||
const char * legend = "Battery level: ";
|
||||
int legendLength = strlcpy(bufferLevel, legend, bufferLevelSize);
|
||||
PrintFloat::convertFloatToText<float>(batteryLevel, bufferLevel+legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal);
|
||||
m_view.batteryLevelTextView()->setText(bufferLevel);
|
||||
|
||||
constexpr size_t bufferChargingSize = ContentView::k_maxNumberOfCharacters + PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits);
|
||||
char bufferCharging[bufferChargingSize];
|
||||
int numberOfChars = 0;
|
||||
legend = "Battery charging: ";
|
||||
numberOfChars += strlcpy(bufferCharging, legend, bufferChargingSize);
|
||||
legend = "no";
|
||||
if (batteryCharging) {
|
||||
legend = "yes";
|
||||
}
|
||||
numberOfChars += strlcpy(bufferCharging+numberOfChars, legend, bufferChargingSize);
|
||||
bufferCharging[numberOfChars] = 0;
|
||||
m_view.batteryChargingTextView()->setText(bufferCharging);
|
||||
}
|
||||
|
||||
BatteryTestController::ContentView::ContentView() :
|
||||
SolidColorView(KDColorWhite),
|
||||
m_batteryStateView(KDFont::LargeFont),
|
||||
m_batteryLevelView(KDFont::SmallFont),
|
||||
m_batteryChargingView(KDFont::SmallFont)
|
||||
{
|
||||
}
|
||||
|
||||
BufferTextView * BatteryTestController::ContentView::batteryStateTextView() {
|
||||
return &m_batteryStateView;
|
||||
}
|
||||
|
||||
BufferTextView * BatteryTestController::ContentView::batteryLevelTextView() {
|
||||
return &m_batteryLevelView;
|
||||
}
|
||||
|
||||
BufferTextView * BatteryTestController::ContentView::batteryChargingTextView() {
|
||||
return &m_batteryChargingView;
|
||||
}
|
||||
|
||||
void BatteryTestController::ContentView::setColor(KDColor color) {
|
||||
SolidColorView::setColor(color);
|
||||
m_batteryStateView.setBackgroundColor(color);
|
||||
m_batteryLevelView.setBackgroundColor(color);
|
||||
m_batteryChargingView.setBackgroundColor(color);
|
||||
}
|
||||
|
||||
void BatteryTestController::ContentView::layoutSubviews() {
|
||||
m_batteryStateView.setFrame(KDRect(0, 0, Ion::Display::Width, Ion::Display::Height/2));
|
||||
KDSize textSize = KDFont::SmallFont->glyphSize();
|
||||
m_batteryLevelView.setFrame(KDRect(0, Ion::Display::Height-2*textSize.height(), Ion::Display::Width, textSize.height()));
|
||||
m_batteryChargingView.setFrame(KDRect(0, Ion::Display::Height-textSize.height(), Ion::Display::Width, textSize.height()));
|
||||
}
|
||||
|
||||
int BatteryTestController::ContentView::numberOfSubviews() const {
|
||||
return 3;
|
||||
}
|
||||
|
||||
View * BatteryTestController::ContentView::subviewAtIndex(int index) {
|
||||
if (index == 0) {
|
||||
return &m_batteryStateView;
|
||||
}
|
||||
if (index == 1) {
|
||||
return &m_batteryLevelView;
|
||||
}
|
||||
return &m_batteryChargingView;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
#ifndef HARDWARE_TEST_BATTERY_TEST_CONTROLLER_H
|
||||
#define HARDWARE_TEST_BATTERY_TEST_CONTROLLER_H
|
||||
|
||||
#include <escher.h>
|
||||
|
||||
namespace HardwareTest {
|
||||
|
||||
class BatteryTestController : public ViewController {
|
||||
public:
|
||||
BatteryTestController(Responder * parentResponder);
|
||||
View * view() override;
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
void viewWillAppear() override;
|
||||
private:
|
||||
class ContentView : public SolidColorView {
|
||||
public:
|
||||
ContentView();
|
||||
BufferTextView * batteryStateTextView();
|
||||
BufferTextView * batteryLevelTextView();
|
||||
BufferTextView * batteryChargingTextView();
|
||||
constexpr static int k_maxNumberOfCharacters = 20;
|
||||
void setColor(KDColor color) override;
|
||||
private:
|
||||
void layoutSubviews() override;
|
||||
int numberOfSubviews() const override;
|
||||
View * subviewAtIndex(int index) override;
|
||||
constexpr static int k_margin = 4;
|
||||
BufferTextView m_batteryStateView;
|
||||
BufferTextView m_batteryLevelView;
|
||||
BufferTextView m_batteryChargingView;
|
||||
};
|
||||
constexpr static const char * k_batteryOKText = "BATTERY: OK";
|
||||
constexpr static const char * k_batteryNeedChargingText = "BATTERY: NEED RECHARGE";
|
||||
void updateBatteryState(float batteryLevel, bool batteryCharging);
|
||||
ContentView m_view;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
#include "lcd_data_test_controller.h"
|
||||
#include <ion/display.h>
|
||||
|
||||
using namespace Poincare;
|
||||
|
||||
namespace HardwareTest {
|
||||
|
||||
bool LCDDataTestController::handleEvent(Ion::Events::Event event) {
|
||||
if (event == Ion::Events::OK && strcmp(m_view.lcdDataStateTextView()->text(), k_lcdDataOKText) == 0) {
|
||||
// Handled in WizardViewController
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void LCDDataTestController::viewWillAppear() {
|
||||
bool testOK = test();
|
||||
m_view.lcdDataStateTextView()->setText(testOK ? k_lcdDataOKText : k_lcdDataFailTest);
|
||||
m_view.setColor(testOK ? KDColorGreen : KDColorRed);
|
||||
}
|
||||
|
||||
LCDDataTestController::ContentView::ContentView() :
|
||||
SolidColorView(KDColorWhite),
|
||||
m_lcdDataStateView(KDFont::LargeFont)
|
||||
{
|
||||
}
|
||||
|
||||
void LCDDataTestController::ContentView::setColor(KDColor color) {
|
||||
SolidColorView::setColor(color);
|
||||
m_lcdDataStateView.setBackgroundColor(color);
|
||||
}
|
||||
|
||||
void LCDDataTestController::ContentView::layoutSubviews() {
|
||||
m_lcdDataStateView.setFrame(KDRect(0, 0, Ion::Display::Width, Ion::Display::Height));
|
||||
}
|
||||
|
||||
void colorPixelBuffer(KDColor * pixels, int numberOfPixels, KDColor c) {
|
||||
for (int i = 0; i < numberOfPixels; i++) {
|
||||
pixels[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
bool LCDDataTestController::test() {
|
||||
KDColor testColors[] = {
|
||||
KDColorRed, KDColorGreen, KDColorBlue,
|
||||
KDColor::RGB24(0xFFFF00), KDColor::RGB24(0xFF00FF), KDColor::RGB24(0x00FFFF),
|
||||
KDColorWhite, KDColorBlack};
|
||||
for (KDColor c : testColors) {
|
||||
if (!testDisplayColor(c)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return testDisplayBlackWhite();
|
||||
}
|
||||
|
||||
bool LCDDataTestController::testDisplayColor(KDColor c) {
|
||||
constexpr int stampHeight = 10;
|
||||
constexpr int stampWidth = 10;
|
||||
static_assert(Ion::Display::Width % stampWidth == 0, "Stamps must tesselate the display");
|
||||
static_assert(Ion::Display::Height % stampHeight == 0, "Stamps must tesselate the display");
|
||||
static_assert(stampHeight % 2 == 0 || stampWidth % 2 == 0, "Even number of XOR needed.");
|
||||
|
||||
KDColor stamp[stampWidth*stampHeight];
|
||||
|
||||
// Tiling test with pushRect
|
||||
colorPixelBuffer(stamp, stampWidth * stampHeight, c);
|
||||
for (int i = 0; i < Ion::Display::Width / stampWidth; i++) {
|
||||
for (int j = 0; j < Ion::Display::Height / stampHeight; j++) {
|
||||
Ion::Display::pushRect(KDRect(i * stampWidth, j * stampHeight, stampWidth, stampHeight), stamp);
|
||||
}
|
||||
}
|
||||
if (numberOfNonColoredPixels(c) > invalidPixelsLimit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test with pushRectUniform
|
||||
Ion::Display::pushRectUniform(KDRect(KDPointZero, Ion::Display::Width, Ion::Display::Height), c);
|
||||
if (numberOfNonColoredPixels(c) > invalidPixelsLimit) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int LCDDataTestController::numberOfNonColoredPixels(KDColor wantedColor) {
|
||||
constexpr int stampHeight = 10;
|
||||
constexpr int stampWidth = 10;
|
||||
static_assert(Ion::Display::Width % stampWidth == 0, "Stamps must tesselate the display");
|
||||
static_assert(Ion::Display::Height % stampHeight == 0, "Stamps must tesselate the display");
|
||||
static_assert(stampHeight % 2 == 0 || stampWidth % 2 == 0, "Even number of XOR needed.");
|
||||
|
||||
KDColor stamp[stampWidth*stampHeight];
|
||||
|
||||
int numberOfInvalidPixels = 0;
|
||||
for (int i = 0; i < Ion::Display::Width / stampWidth; i++) {
|
||||
for (int j = 0; j < Ion::Display::Height / stampHeight; j++) {
|
||||
colorPixelBuffer(stamp, stampWidth * stampHeight, wantedColor == KDColorBlack ? KDColorRed : KDColorBlack);
|
||||
Ion::Display::pullRect(KDRect(i * stampWidth, j * stampHeight, stampWidth, stampHeight), stamp);
|
||||
for (int k = 0; k < stampWidth * stampHeight; k++) {
|
||||
if (stamp[k] != wantedColor) {
|
||||
numberOfInvalidPixels++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return numberOfInvalidPixels;
|
||||
}
|
||||
|
||||
bool LCDDataTestController::testDisplayBlackWhite() {
|
||||
Ion::Display::POSTPushBlackWhite();
|
||||
constexpr int stampHeight = Ion::Display::Height;
|
||||
constexpr int stampWidth = 2;
|
||||
static_assert(Ion::Display::Width % stampWidth == 0, "Stamps must tesselate the display");
|
||||
static_assert(Ion::Display::Height % stampHeight == 0, "Stamps must tesselate the display");
|
||||
static_assert(stampHeight % 2 == 0 || stampWidth % 2 == 0, "Even number of XOR needed.");
|
||||
KDColor stamp[stampWidth*stampHeight];
|
||||
int numberOfInvalidPixels = 0;
|
||||
for (int i = 0; i < Ion::Display::Width/stampWidth; i++) {
|
||||
colorPixelBuffer(stamp, stampWidth * stampHeight, KDColorRed);
|
||||
Ion::Display::pullRect(KDRect(i*stampWidth, 0, stampWidth, stampHeight), stamp);
|
||||
for (int k = 0; k < stampWidth * stampHeight; k++) {
|
||||
if (stamp[k] != ((k%2 == 0) ? KDColorWhite : KDColorBlack)) {
|
||||
numberOfInvalidPixels++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return numberOfInvalidPixels <= invalidPixelsLimit;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
#ifndef LCD_DATA_TEST_CONTROLLER_H
|
||||
#define LCD_DATA_TEST_CONTROLLER_H
|
||||
|
||||
#include <escher.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace HardwareTest {
|
||||
|
||||
class LCDDataTestController : public ViewController {
|
||||
|
||||
/* There are three types of tests, where a pattern is pushed to the screen and
|
||||
* the number of invalid pixels then counted.
|
||||
* - Test 1: Tile the screen with color patches. Tiling increases the number
|
||||
* of border mistakes.
|
||||
* - Test 2: Push one color to the whole screen in one step. It shows errors
|
||||
* that appear on large and fast pushes.
|
||||
* - Test 3: Color the screen by alterning one pixel black and one pixel
|
||||
* white (maximal data difference), at maximal data writing speed.
|
||||
* Tests 1 and 2 are done for a few different colors. */
|
||||
|
||||
public:
|
||||
LCDDataTestController(Responder * parentResponder) :
|
||||
ViewController(parentResponder),
|
||||
m_view()
|
||||
{}
|
||||
View * view() override { return &m_view; }
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
void viewWillAppear() override;
|
||||
private:
|
||||
class ContentView : public SolidColorView {
|
||||
public:
|
||||
ContentView();
|
||||
BufferTextView * lcdDataStateTextView() { return &m_lcdDataStateView; }
|
||||
void setColor(KDColor color) override;
|
||||
private:
|
||||
void layoutSubviews() override;
|
||||
int numberOfSubviews() const override { return 1; }
|
||||
View * subviewAtIndex(int index) override {
|
||||
assert(index == 0);
|
||||
return &m_lcdDataStateView;
|
||||
}
|
||||
BufferTextView m_lcdDataStateView;
|
||||
};
|
||||
constexpr static const char * k_lcdDataOKText = "LCD DATA: OK";
|
||||
constexpr static const char * k_lcdDataFailTest = "LCD DATA: FAIL";
|
||||
constexpr static int invalidPixelsLimit = 2;
|
||||
|
||||
bool test();
|
||||
bool testDisplayColor(KDColor c);
|
||||
int numberOfNonColoredPixels(KDColor wantedColor);
|
||||
bool testDisplayBlackWhite();
|
||||
|
||||
ContentView m_view;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
#include "vblank_test_controller.h"
|
||||
#include "../apps_container.h"
|
||||
|
||||
using namespace Poincare;
|
||||
|
||||
namespace HardwareTest {
|
||||
|
||||
bool VBlankTestController::handleEvent(Ion::Events::Event event) {
|
||||
if (event == Ion::Events::OK) {
|
||||
if (strcmp(m_view.vBlankStateTextView()->text(), k_vBlankOKText) == 0) {
|
||||
// Handled in WizardViewController
|
||||
return false;
|
||||
}
|
||||
assert(strcmp(m_view.vBlankStateTextView()->text(), k_vBlankLaunchTest) == 0);
|
||||
m_view.setColor(KDColorRed);
|
||||
m_view.vBlankStateTextView()->setText(k_vBlankFailTest);
|
||||
static_cast<AppsContainer *>(const_cast<Container *>(app()->container()))->redrawWindow();
|
||||
/* We redraw the window with "VBLANK FAIL" before lauching the test. This
|
||||
* test might end up in an infinite loop, in which case "VBLANK fail" keeps
|
||||
* being displayed. If the test succeeds, the screen should change very
|
||||
* quickly to "VBLANK OK". */
|
||||
for (int i=0; i<6; i++) {
|
||||
Ion::Display::waitForVBlank();
|
||||
}
|
||||
m_view.setColor(KDColorGreen);
|
||||
m_view.vBlankStateTextView()->setText(k_vBlankOKText);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void VBlankTestController::viewWillAppear() {
|
||||
m_view.vBlankStateTextView()->setText(k_vBlankLaunchTest);
|
||||
}
|
||||
|
||||
VBlankTestController::ContentView::ContentView() :
|
||||
SolidColorView(KDColorWhite),
|
||||
m_vBlankStateView(KDFont::LargeFont)
|
||||
{
|
||||
}
|
||||
|
||||
void VBlankTestController::ContentView::setColor(KDColor color) {
|
||||
SolidColorView::setColor(color);
|
||||
m_vBlankStateView.setBackgroundColor(color);
|
||||
}
|
||||
|
||||
void VBlankTestController::ContentView::layoutSubviews() {
|
||||
m_vBlankStateView.setFrame(KDRect(0, 0, Ion::Display::Width, Ion::Display::Height));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
#ifndef HARDWARE_TEST_VBLANK_TEST_CONTROLLER_H
|
||||
#define HARDWARE_TEST_VBLANK_TEST_CONTROLLER_H
|
||||
|
||||
#include <escher.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace HardwareTest {
|
||||
|
||||
class VBlankTestController : public ViewController {
|
||||
public:
|
||||
VBlankTestController(Responder * parentResponder) :
|
||||
ViewController(parentResponder),
|
||||
m_view()
|
||||
{}
|
||||
View * view() override { return &m_view; }
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
void viewWillAppear() override;
|
||||
private:
|
||||
class ContentView : public SolidColorView {
|
||||
public:
|
||||
ContentView();
|
||||
BufferTextView * vBlankStateTextView() { return &m_vBlankStateView; }
|
||||
void setColor(KDColor color) override;
|
||||
private:
|
||||
void layoutSubviews() override;
|
||||
int numberOfSubviews() const override { return 1; }
|
||||
View * subviewAtIndex(int index) override {
|
||||
assert(index == 0);
|
||||
return &m_vBlankStateView;
|
||||
}
|
||||
BufferTextView m_vBlankStateView;
|
||||
};
|
||||
constexpr static const char * k_vBlankOKText = "VBLANK: OK";
|
||||
constexpr static const char * k_vBlankFailTest = "VBLANK: FAIL";
|
||||
constexpr static const char * k_vBlankLaunchTest = "Launch VBLANK test";
|
||||
ContentView m_view;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user