Skip to content

Commit

Permalink
Merge pull request #91 from 708yamaguchi/available-modes-pr
Browse files Browse the repository at this point in the history
[Refactor] Manage mode creation and transition in AtomS3ModeManager class
  • Loading branch information
708yamaguchi authored Nov 25, 2024
2 parents 6c2cb6c + 9ca137d commit 72e99c3
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 52 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#include <atom_s3_mode_manager.h>

AtomS3ModeManager* AtomS3ModeManager::instance = nullptr;

std::vector<Mode*> AtomS3ModeManager::allModes = {};
int AtomS3ModeManager::current_mode_index = 0;

AtomS3ModeManager::AtomS3ModeManager(AtomS3LCD &lcd, AtomS3Button &button, AtomS3I2C &i2c)
: atoms3lcd(lcd), atoms3button(button), atoms3i2c(i2c)
{
instance = this;
createTask(0);
}

void AtomS3ModeManager::task(void *parameter) {
if (instance == nullptr) {
return;
}

instance->atoms3lcd.printWaitMessage(instance->atoms3i2c.i2c_slave_addr);
while (true) {
// Check if Mode is forced to change
bool isModeForced = false;
int forced_mode_index;
for (int i = 0; i < allModes.size(); i++) {
if (allModes[i]->getModeName() == instance->atoms3i2c.forcedMode) {
isModeForced = true;
forced_mode_index = i;
break;
}
}
// Force mode change
if (isModeForced) {
instance->changeMode(current_mode_index, forced_mode_index);
current_mode_index = forced_mode_index;
instance->atoms3i2c.forcedMode = "";
}
// Change mode by long click
if (instance->atoms3button.wasLongPressed()) {
int next_mode_index = (current_mode_index + 1) % allModes.size();
instance->changeMode(current_mode_index, next_mode_index);
current_mode_index = next_mode_index;
}
vTaskDelay(pdMS_TO_TICKS(500));
}
}

void AtomS3ModeManager::createTask(uint8_t xCoreID) {
xTaskCreatePinnedToCore(task, "Mode Manager Task", 2048, this, 24, NULL, xCoreID);
}

void AtomS3ModeManager::initializeAllModes(uint8_t xCoreID) {
// Start user-defined mode
for (int i = 0; i < allModes.size(); i++) {
if (!allModes[i]->isTaskCreated()) {
allModes[i]->createTask(xCoreID);
}
allModes[i]->suspendTask();
}
}

void AtomS3ModeManager::startCurrentMode() {
allModes[current_mode_index]->resumeTask();
}

void AtomS3ModeManager::changeMode(int suspend_mode_index, int resume_mode_index) {
// Suspend
allModes[suspend_mode_index]->suspendTask();
// Transition
allModes[suspend_mode_index]->waitForTaskSuspended();
instance->atoms3i2c.stopReceiveEvent();
instance->atoms3lcd.drawBlack();
instance->atoms3lcd.printMessage("Wait for mode switch ...");
vTaskDelay(pdMS_TO_TICKS(1000));
instance->atoms3lcd.resetLcdData();
// Resume
allModes[resume_mode_index]->resumeTask();
instance->atoms3i2c.startReceiveEvent();
}

void AtomS3ModeManager::addMode(Mode &mode) {
allModes.push_back(&mode);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifndef ATOM_S3_MODE_MANAGER_H
#define ATOM_S3_MODE_MANAGER_H

#include <vector>

#include <atom_s3_button.h>
#include <atom_s3_lcd.h>
#include <atom_s3_i2c.h>

#include <mode.h>

class AtomS3ModeManager {
public:
AtomS3ModeManager(AtomS3LCD &lcd, AtomS3Button &button, AtomS3I2C &i2c);
void createTask(uint8_t xCoreID);
void initializeAllModes(uint8_t xCoreID);
void startCurrentMode();
void addMode(Mode &mode);

private:
static AtomS3ModeManager* instance; /**< Singleton instance of AtomS3ModeManager. */
// Common tasks for AtomS3
AtomS3Button &atoms3button;
AtomS3LCD &atoms3lcd;
AtomS3I2C &atoms3i2c;

static std::vector<Mode*> allModes;
static int current_mode_index;

static void task(void *parameter);
void changeMode(int suspend_mode_index, int resume_mode_index);
};

#endif
6 changes: 5 additions & 1 deletion firmware/atom_s3_i2c_display/lib/mode/mode.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,13 @@ class Mode {
return eTaskGetState(taskHandle) == eSuspended;
}

bool isTaskCreated() {
return taskHandle != NULL;
}

void waitForTaskSuspended() {
while (!isTaskSuspended()) {
delay(100);
vTaskDelay(pdMS_TO_TICKS(100));
}
}

Expand Down
61 changes: 10 additions & 51 deletions firmware/atom_s3_i2c_display/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,72 +1,31 @@
#include <atom_s3_lcd.h>
#include <atom_s3_i2c.h>
#include <atom_s3_button.h>

#include <atom_s3_mode_manager.h>
#include <display_information_mode.h>
#include <display_qrcode_mode.h>
#include <display_image_mode.h>

// Common tasks for AtomS3
AtomS3Button atoms3button;
AtomS3LCD atoms3lcd;
AtomS3I2C atoms3i2c(atoms3lcd, atoms3button);
AtomS3ModeManager atoms3modemanager(atoms3lcd, atoms3button, atoms3i2c);

// User-defined modes:
DisplayInformationMode display_information_mode(atoms3lcd, atoms3i2c);
DisplayQRcodeMode display_qrcode_mode(atoms3lcd, atoms3i2c);
DisplayImageMode display_image_mode(atoms3lcd, atoms3i2c);
Mode* modes[] = { &display_information_mode, &display_qrcode_mode, &display_image_mode };
int current_mode_index = 0;
int num_modes = sizeof(modes) / sizeof(modes[0]);

void changeMode(int suspend_mode_index, int resume_mode_index) {
// Suspend
modes[suspend_mode_index]->suspendTask();
// Transition
modes[suspend_mode_index]->waitForTaskSuspended();
atoms3i2c.stopReceiveEvent();
atoms3lcd.drawBlack();
atoms3lcd.printMessage("Wait for mode switch ...");
delay(1000);
atoms3lcd.resetLcdData();
// Resume
modes[resume_mode_index]->resumeTask();
atoms3i2c.startReceiveEvent();
}

void setup() {
atoms3lcd.printWaitMessage(atoms3i2c.i2c_slave_addr);
atoms3modemanager.addMode(display_information_mode);
atoms3modemanager.addMode(display_qrcode_mode);
atoms3modemanager.addMode(display_image_mode);

// Start user-defined mode
for (int i = 0; i < num_modes; i++) {
uint8_t xCoreID = 1;
modes[i]->createTask(xCoreID);
modes[i]->suspendTask();
}
modes[current_mode_index]->resumeTask();
// Start one of the user-defined modes
uint8_t eachModeCoreID = 1;
atoms3modemanager.initializeAllModes(eachModeCoreID);
atoms3modemanager.startCurrentMode();
}

void loop() {
// Check if Mode is forced to change
bool isModeForced = false;
int forced_mode_index;
for (int i = 0; i < num_modes; i++) {
if (modes[i]->getModeName() == atoms3i2c.forcedMode) {
isModeForced = true;
forced_mode_index = i;
break;
}
}
// Force mode change
if (isModeForced) {
changeMode(current_mode_index, forced_mode_index);
current_mode_index = forced_mode_index;
atoms3i2c.forcedMode = "";
}
// Change mode by long click
if (atoms3button.wasLongPressed()) {
int next_mode_index = (current_mode_index + 1) % num_modes;
changeMode(current_mode_index, next_mode_index);
current_mode_index = next_mode_index;
}
delay(500);
}

0 comments on commit 72e99c3

Please sign in to comment.