Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
arcadien committed Nov 23, 2023
1 parent bdaa92f commit b146299
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 18 deletions.
28 changes: 16 additions & 12 deletions lib/Cross/Gun/SSD1306Ui.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ static Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
/**
* @brief UI on a SSD1306 OLED display wired over I²C bus
*
* Used https://rickkas7.github.io/DisplayGenerator/index.html for prototyping
*/
class SSD1306Ui : public IGunUi {
public:
Expand All @@ -57,46 +58,49 @@ class SSD1306Ui : public IGunUi {
display.display();
delay(timeoutMs);
display.clearDisplay();
display.display();
}

void displayBatteryStatus(uint16_t mv, uint8_t percent) override {
display.setFont(NULL);
display.fillRect(79, 0, 59, 24, 0); // clear
display.fillRect(100, 0, 25, 9, 0); // clear
display.setCursor(100, 2);
display.print(percent);
display.println("%");

// prepare font for next shoot count display
display.setFont(&FreeMonoBold18pt7b);
}

void displayChargingStatus(bool isCharging) override {
display.setCursor(80, 15);
if (isCharging) {
display.setFont(NULL);
display.setCursor(80, 15);
display.println("charging");
} else {
display.println(" ");
display.fillRect(80, 12, 47, 11, 0); // clear
}
}

void displayShootCount(uint16_t count) override {
display.fillRect(11, 0, 68, 30, 0); // clear

if (count > 999)
display.setFont(&FreeMonoBold18pt7b);
if (count > 999) {
count = 0;

}
if (count < 10) {
display.setCursor(15, 25);
} else {
display.setCursor(10, 25);
}
display.setFont(&FreeMonoBold18pt7b);
display.print(count);
display.display();
}

void clearCalibration() override {
display.fillRect(2, 10, 126, 14, 0); // clear
}

void displayCalibration() override {
display.fillRect(11, 0, 68, 30, 0); // clear
display.setCursor(15, 25);
display.clearDisplay();
display.setCursor(2, 25);
display.setFont(&FreeMonoOblique9pt7b);
display.print("Calibration");
display.display();
Expand Down
2 changes: 1 addition & 1 deletion lib/Domain/Gun/Button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@
#include <Gun/Gun.hpp>

void Button::setGun(Gun *gun) { this->gun = gun; }
void Button::onShortPress() { gun->shootCount = 0; }
void Button::onShortPress() { gun->resetShoots(); }
void Button::onLongPress() { gun->toggleCalibrationMode(); }
11 changes: 9 additions & 2 deletions lib/Domain/Gun/Gun.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,19 @@ void Gun::toggleCalibrationMode() {
ui->displayCalibration();
} else {
hal->laserOff();
ui->clearCalibration();
ui->displayShootCount(shootCount);
batteryDisplayCycleCountdown = 0;
}
}

void Gun::resetShoots() {
shootCount = 0;
ui->displayShootCount(shootCount);
}

void Gun::activateShoot() {
if (shootCycleCountdown == 0) {
if (!calibrationMode && shootCycleCountdown == 0) {
shootCount += 1;
hal->laserOn();
hal->vibrationOn();
Expand Down Expand Up @@ -74,14 +81,14 @@ void Gun::loop(void) {
shootCycleCountdown--;
}
}

if (batteryDisplayCycleCountdown > 0) {
batteryDisplayCycleCountdown--;
} else {
ui->displayBatteryStatus(hal->getBatteryVoltageMv(),
hal->getBatteryVoltagePercent());
batteryDisplayCycleCountdown = TICKS_BETWEEN_BATTERY_UI_UPDATE;
}
hal->sleep();
}

void Gun::setup(void) {
Expand Down
8 changes: 8 additions & 0 deletions lib/Domain/Gun/Gun.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ class Gun {

Gun(IGunHal *hal, IGunUi *ui);

/**
* Reset shoot count and redisplay
*/
void resetShoots();

/**
* Activate laser and vibrator
*/
void activateShoot();

void toggleCalibrationMode();
Expand Down
1 change: 1 addition & 0 deletions lib/Domain/Gun/IGunUi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ class IGunUi {
virtual void displayChargingStatus(bool isCharging) = 0;
virtual void displayShootCount(uint16_t shootCount) = 0;
virtual void displayCalibration() = 0;
virtual void clearCalibration() = 0;
};
14 changes: 12 additions & 2 deletions src/GunApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,32 @@ ISR(TIMER2_COMPA_vect) { tick = true; }

volatile Contactor::Event pendingTriggerEvent;
void triggerInterruptHandler() {
if (bit_is_set(PIND, PD2)) {
if (hal.triggerIsUp()) {
pendingTriggerEvent = Contactor::Event::Released;
} else {
pendingTriggerEvent = Contactor::Event::Pressed;
}
tick = true;
}

volatile Contactor::Event pendingButtonEvent;
void buttonInterruptHandler() {
if (bit_is_set(PIND, PD3)) {
if (hal.buttonIsUp()) {
pendingButtonEvent = Contactor::Event::Released;
} else {
pendingButtonEvent = Contactor::Event::Pressed;
}
tick = true;
}

void loop(void) {

// other interrupt may wakeup the board
// and trigger loop(). Especially counter0
// and counter1, used internally by the Arduino
// framework. Avoid processing these wakeups as
// applicative events using 'tick' control variable.

if (tick) {
// wire interrupt-based events with main code
gun.trigger.pendingEvent = pendingTriggerEvent;
Expand All @@ -55,12 +63,14 @@ void loop(void) {

gun.loop();
tick = false;
hal.sleep();
}
}

void setup(void) {
hal.setGun(&gun);
ui.setup();
gun.setup();
hal.configureInputCallbacks();
hal.setupHeartbeat();
}
55 changes: 54 additions & 1 deletion test/native/test_gun/gun.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ using namespace fakeit;
When(Method(mockUi, displayBatteryStatus)).AlwaysReturn(); \
When(Method(mockUi, displayShootCount)).AlwaysReturn(); \
When(Method(mockUi, displayCalibration)).AlwaysReturn(); \
When(Method(mockUi, clearCalibration)).AlwaysReturn(); \
When(Method(mockUi, displaySplash)).AlwaysReturn();

void tearDown() {}
Expand Down Expand Up @@ -85,8 +86,8 @@ void expect_gun_to_shoot_50ms_on_trigger_down() {
Verify(Method(mockHal, vibrationOn)).Once();
Verify(Method(mockHal, vibrationOff)).Once();
Verify(Method(mockHal, laserOff)).Once();
Verify(Method(mockHal, sleep)).Exactly(7);
}

void expect_ui_to_display_battery_state_at_boot_and_each_1s() {
Mock<IGunUi> mockUi;
Mock<IGunHal> mockHal;
Expand Down Expand Up @@ -137,15 +138,67 @@ void expect_switch_to_maintenance_after_2s_button_continuous_press() {

// back to normal
Verify(Method(mockHal, laserOff)).Exactly(1);
Verify(Method(mockUi, clearCalibration)).Exactly(1);
Verify(Method(mockUi, displayShootCount)).Exactly(1);
}

void expect_button_press_to_reset_shoot_count_and_redisplay() {
Mock<IGunUi> mockUi;
Mock<IGunHal> mockHal;
MOCK_ALL();
IGunUi &ui = mockUi.get();
IGunHal &hal = mockHal.get();

Gun gun(&hal, &ui);

gun.shootCount = 10;

gun.button.pendingEvent = Contactor::Event::Pressed;
gun.loop();
gun.button.pendingEvent = Contactor::Event::Released;
gun.loop();

TEST_ASSERT_EQUAL_MESSAGE(0, gun.shootCount, "Shoot count shall be reset");
Verify(Method(mockUi, displayShootCount)).Exactly(1);
}

void expect_trigger_to_have_no_effect_in_calibration_mode() {
Mock<IGunUi> mockUi;
Mock<IGunHal> mockHal;

MOCK_ALL();

IGunUi &ui = mockUi.get();
IGunHal &hal = mockHal.get();

Gun gun(&hal, &ui);

gun.button.pendingEvent = Contactor::Event::Pressed;
for (uint8_t tickCounter = 0; tickCounter <= 200; tickCounter++) {
// long press shall be accounted after 2s, 200 ticks
gun.loop();
}

gun.button.pendingEvent = Contactor::Event::Released;
gun.loop();

gun.trigger.pendingEvent = Contactor::Event::Pressed;
gun.loop();
gun.trigger.pendingEvent = Contactor::Event::Released;
gun.loop();

Verify(Method(mockHal, laserOn)).Exactly(1);
Verify(Method(mockHal, laserOff)).Exactly(0);
}

int main(int, char **) {
UNITY_BEGIN();
RUN_TEST(expect_gun_to_loop);
RUN_TEST(expect_gun_to_shoot_50ms_on_trigger_down);
RUN_TEST(expect_ui_to_display_battery_state_at_boot_and_each_1s);
RUN_TEST(expect_switch_to_maintenance_after_2s_button_continuous_press);
RUN_TEST(expect_button_press_to_reset_shoot_count_and_redisplay);
RUN_TEST(expect_trigger_to_have_no_effect_in_calibration_mode);

UNITY_END();
return 0;
Expand Down

0 comments on commit b146299

Please sign in to comment.