Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
arcadien committed Nov 22, 2023
1 parent deffd74 commit 87bf553
Show file tree
Hide file tree
Showing 12 changed files with 169 additions and 188 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@
#define MIN_BAT_VOLTAGE 3000
#define MAX_BAT_VOLTAGE 4120

ISR(TIMER2_COMPA_vect) {}

Atmega328pHal::Atmega328pHal() {

pinMode(VIBRATOR_PIN, OUTPUT);
pinMode(LASER_PIN, OUTPUT);
}

bool Atmega328pHal::triggerIsUp() { return bit_is_set(PIND, PD2); }
bool Atmega328pHal::buttonIsUp() { return bit_is_set(PIND, PD3); }

/*
* the 'loop' method shall be called each 10ms
*
Expand All @@ -48,7 +50,7 @@ Atmega328pHal::Atmega328pHal() {
void Atmega328pHal::setupHeartbeat() {
TCCR2A = (1U << WGM21) | (0U << WGM20); // set Timer2 in CTC mode
TCCR2B = (1U << CS22) | (1U << CS21) | (1U << CS20); // 1/1024 prescaler
TIMSK2 = (1U << OCIE2A); // enable compare Interrupt
TIMSK2 = (1U << OCIE2A); // enable compare Interrupt
ASSR &= ~(1U << AS2);
TCNT2 = 0U;

Expand Down Expand Up @@ -83,7 +85,7 @@ bool Atmega328pHal::isCharging() {
}

void Atmega328pHal::sleep() {
LowPower.idle(SLEEP_15MS, ADC_OFF, TIMER2_ON, TIMER1_ON, TIMER0_ON, SPI_OFF,
LowPower.idle(SLEEP_15MS, ADC_OFF, TIMER2_ON, TIMER1_OFF, TIMER0_OFF, SPI_OFF,
USART0_OFF, TWI_OFF);
}

Expand All @@ -96,7 +98,7 @@ void Atmega328pHal::configureInputCallbacks() {
attachInterrupt(digitalPinToInterrupt(BUTTON2_PIN), buttonInterruptHandler,
CHANGE);

extern void triggerInterruptHandler();
extern void triggerInterruptHandler();
pinMode(TRIGGER_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(TRIGGER_PIN), triggerInterruptHandler,
CHANGE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,11 @@ class Atmega328pHal : public IGunHal {
void laserOff() override;
void vibrationOn() override;
void vibrationOff() override;

bool triggerIsUp() override;
bool buttonIsUp() override;
uint16_t getBatteryVoltageMv() override;

uint8_t getBatteryVoltagePercent() override;
bool isCharging() override;

void configureInputCallbacks() override;

void sleep() override;
};
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class SSD1306Ui : public IGunUi {
; // Don't proceed, loop forever
}
}

void displaySplash(uint16_t timeoutMs) override {
display.clearDisplay();
display.setTextColor(WHITE);
Expand Down
1 change: 1 addition & 0 deletions lib/Domain/Gun/Button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
#include <Gun/Button.hpp>
#include <Gun/Gun.hpp>

void Button::setGun(Gun *gun) { this->gun = gun; }
void Button::onShortPress() { gun->shootCount = 0; }
void Button::onLongPress() { gun->toggleCalibrationMode(); }
2 changes: 1 addition & 1 deletion lib/Domain/Gun/Button.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ class Button : public Contactor {

void onShortPress() override;
void onLongPress() override;
void setGun(Gun *gun) { gun = gun; }
void setGun(Gun *gun);
};
48 changes: 37 additions & 11 deletions lib/Domain/Gun/Gun.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,39 @@
*/
#include <Gun/Gun.hpp>

#define TICKS_BETWEEN_UI_UPDATE 10
#define TICKS_BETWEEN_BATTERY_UI_UPDATE 100

// counter for ticks between battery display update
uint16_t updateBatteryDisplayCycleCount;

long now = 0;

void Gun::loop(void) {
Gun::Gun(IGunHal *hal, IGunUi *ui) {
this->hal = hal;
this->ui = ui;
calibrationMode = false;
shootCount = 0;
shootCycleCountdown = 0;

button.setGun(this);
trigger.setGun(this);
}

void Gun::activateShoot() {
if (shootCycleCountdown == 0) {
shootCount += 1;
hal->laserOn();
hal->vibrationOn();

now += 10; // 10ms per loop thanks to timer2
// add 1 to allow easy detection of last tick
shootCycleCountdown = Gun::SHOOT_DURATION_TICKS + 1;
}
}

void Gun::loop(void) {

decreaseShootCycleCount();
// 10ms per loop thanks to timer2
now += 10;

trigger.processPendingEvent(now);
button.processPendingEvent(now);
Expand All @@ -39,10 +60,15 @@ void Gun::loop(void) {
hal->vibrationOff();

} else {
if (shootCycleCountdown == 0) {
hal->laserOff();
hal->vibrationOff();
ui->displayShootCount(shootCount);

if (shootCycleCountdown > 0) {
shootCycleCountdown--;
if (shootCycleCountdown == 1) {
hal->laserOff();
hal->vibrationOff();
ui->displayShootCount(shootCount);
shootCycleCountdown--;
}
}

if (updateBatteryDisplayCycleCount > 0) {
Expand All @@ -51,7 +77,7 @@ void Gun::loop(void) {
if (updateBatteryDisplayCycleCount == 0) {
ui->displayBatteryStatus(hal->getBatteryVoltageMv(),
hal->getBatteryVoltagePercent());
updateBatteryDisplayCycleCount = TICKS_BETWEEN_UI_UPDATE;
updateBatteryDisplayCycleCount = TICKS_BETWEEN_BATTERY_UI_UPDATE;
}
}
hal->sleep();
Expand All @@ -60,10 +86,10 @@ void Gun::loop(void) {
void Gun::setup(void) {

shootCount = 0;
updateBatteryDisplayCycleCount = TICKS_BETWEEN_UI_UPDATE;
updateBatteryDisplayCycleCount = TICKS_BETWEEN_BATTERY_UI_UPDATE;

ui->displaySplash(2000);

// mV is not used
ui->displayBatteryStatus(0, hal->getBatteryVoltagePercent());

Expand Down
18 changes: 5 additions & 13 deletions lib/Domain/Gun/Gun.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

class Gun {

uint8_t shootCycleCountdown;

public:
/* 50 ms */
static const uint8_t SHOOT_DURATION_TICKS = 5;
Expand All @@ -34,20 +36,10 @@ class Gun {
Trigger trigger;
bool calibrationMode;
uint16_t shootCount;
uint8_t shootCycleCountdown;

Gun(IGunHal *hal, IGunUi *ui)
: hal(hal), ui(ui), calibrationMode(false), shootCount(0),
shootCycleCountdown(0) {
button.setGun(this);
trigger.setGun(this);
}

void decreaseShootCycleCount() {
if (shootCycleCountdown > 0) {
shootCycleCountdown--;
}
}
Gun(IGunHal *hal, IGunUi *ui);

void activateShoot();

void toggleCalibrationMode() { calibrationMode = !calibrationMode; }

Expand Down
3 changes: 2 additions & 1 deletion lib/Domain/Gun/IGunHal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ class IGunHal {
* the 'loop' method shall be called each 10ms
*/
virtual void setupHeartbeat() = 0;

virtual bool triggerIsUp() = 0;
virtual bool buttonIsUp() = 0;
virtual void laserOn() = 0;
virtual void laserOff() = 0;
virtual void vibrationOn() = 0;
Expand Down
11 changes: 4 additions & 7 deletions lib/Domain/Gun/Trigger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,12 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Gun/Trigger.hpp>
#include <Gun/Gun.hpp>
#include <Gun/Trigger.hpp>

void Trigger::setGun(Gun *gun) { this->gun = gun; }

void Trigger::onDown(long now) {
if (gun->shootCycleCountdown == 0) {
gun->shootCount += 1;
gun->hal->laserOn();
gun->hal->vibrationOn();
gun->shootCycleCountdown = Gun::SHOOT_DURATION_TICKS;
}
gun->activateShoot();
Contactor::onDown(now);
}
2 changes: 1 addition & 1 deletion lib/Domain/Gun/Trigger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ class Trigger : public Contactor {

public:
Trigger() : Contactor() {}
void setGun(Gun *gun) { gun = gun; }
void setGun(Gun *gun);
void onDown(long now) override;
};
18 changes: 12 additions & 6 deletions src/GunApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ SSD1306Ui ui;
Atmega328pHal hal;
Gun gun(&hal, &ui);

volatile bool tick = false;
ISR(TIMER2_COMPA_vect) { tick = true; }

volatile Contactor::Event pendingTriggerEvent;
void triggerInterruptHandler() {
if (bit_is_set(PIND, PD2)) {
Expand All @@ -43,13 +46,16 @@ void buttonInterruptHandler() {

void loop(void) {

// wire interrupt-based events with main code
gun.trigger.pendingEvent = pendingTriggerEvent;
gun.button.pendingEvent = pendingButtonEvent;
pendingTriggerEvent = Contactor::Event::NoEvent;
pendingButtonEvent = Contactor::Event::NoEvent;
if (tick) {
// wire interrupt-based events with main code
gun.trigger.pendingEvent = pendingTriggerEvent;
gun.button.pendingEvent = pendingButtonEvent;
pendingTriggerEvent = Contactor::Event::NoEvent;
pendingButtonEvent = Contactor::Event::NoEvent;

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

void setup(void) {
Expand Down
Loading

0 comments on commit 87bf553

Please sign in to comment.