From ddc9be976aa1459c9adad242b6e158623f951dbe Mon Sep 17 00:00:00 2001 From: Vasily Davydov Date: Sat, 29 Apr 2023 06:32:52 +0300 Subject: [PATCH 01/18] manager: [#25] init simple task --- source/shoh/.cproject | 1 + source/shoh/src/main.cpp | 4 +++ source/shoh/src/threads/manager/Manager.cpp | 34 +++++++++++++++++++++ source/shoh/src/threads/manager/Manager.h | 26 ++++++++++++++++ 4 files changed, 65 insertions(+) create mode 100644 source/shoh/src/threads/manager/Manager.cpp create mode 100644 source/shoh/src/threads/manager/Manager.h diff --git a/source/shoh/.cproject b/source/shoh/.cproject index c20b11d..b1e8833 100644 --- a/source/shoh/.cproject +++ b/source/shoh/.cproject @@ -51,6 +51,7 @@ + @@ -200,6 +203,7 @@ + @@ -229,6 +233,7 @@ + diff --git a/source/shoh/src/main.cpp b/source/shoh/src/main.cpp index 7104c1e..4bb8f6e 100644 --- a/source/shoh/src/main.cpp +++ b/source/shoh/src/main.cpp @@ -3,14 +3,13 @@ #include "FreeRTOS.h" #include "task.h" #include +#include "retarget_uart.h" + #include "ThreadCommon.h" #include "Master.h" #include "Rotary.h" -#include "retarget_uart.h" -#include "LiquidCrystal.h" #include "Manager.h" - -void lcd_starting(); +#include "UserInterface.h" int main(void) { @@ -20,8 +19,6 @@ int main(void) retarget_init(); printf("Hello there!\r\n"); - - lcd_starting(); ThreadCommon::ThreadManager* manager = new ThreadCommon::ThreadManager; ThreadCommon::QueueManager* qmanager = new ThreadCommon::QueueManager; @@ -32,6 +29,9 @@ int main(void) qmanager->createQueue(20, sizeof(Event), ThreadCommon::QueueManager::manager_event_master); + qmanager->createQueue(20, + sizeof(Event), + ThreadCommon::QueueManager::ui_event_manager); //Creating tasks manager->createTask(thread_master, "master", @@ -43,50 +43,12 @@ int main(void) manager->createTask(thread_rotary, "rotary", configMINIMAL_STACK_SIZE * 10,tskIDLE_PRIORITY + 1UL, static_cast(qmanager)); + manager->createTask(thread_user_interface, "user_interface", + configMINIMAL_STACK_SIZE * 10,tskIDLE_PRIORITY + 1UL, + static_cast(qmanager)); // Start the real time kernel with preemption. vTaskStartScheduler (); return 1; } - -/** - * @brief While we don't have UI, this should do for LCD. - * - */ -void lcd_starting() { - // LCD pins init. - //Well, this lpc is a bit different with those. Table 83 from UM10732-11u68.pdf - DigitalIoPin *rs = new DigitalIoPin(1, 9, false); - Chip_IOCON_PinMuxSet (LPC_IOCON, 1, 9, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); - - DigitalIoPin *en = new DigitalIoPin(0, 14, false); - Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 14, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); - - DigitalIoPin *d4 = new DigitalIoPin(0, 13, false); - Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 13, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); - - DigitalIoPin *d5 = new DigitalIoPin(0, 12, false); - Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 12, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); - - DigitalIoPin *d6 = new DigitalIoPin(0, 23, false); - Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 23, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); - - DigitalIoPin *d7 = new DigitalIoPin(0, 11, false); - Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 11, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); - - rs->write(false); - en->write(false); - d4->write(false); - d5->write(false); - d6->write(false); - d7->write(false); - // LCD init. - LiquidCrystal *lcd = new LiquidCrystal(rs, en, d4, d5, d6, d7); - // LCD configure display geometry. - lcd->begin(16, 2); - lcd->setCursor (0, 0); - lcd->print("Hello there"); - lcd->setCursor (0, 1); - lcd->print("Starting..."); -} diff --git a/source/shoh/src/threads/common/Event.h b/source/shoh/src/threads/common/Event.h index 87b535c..34a242a 100644 --- a/source/shoh/src/threads/common/Event.h +++ b/source/shoh/src/threads/common/Event.h @@ -23,7 +23,8 @@ public: Rotary, InternalTemp, ExternalTemp, - SetPoint + SetPoint, + NotifyUI }; typedef struct _EventPair diff --git a/source/shoh/src/threads/user_interface/UserInterface.cpp b/source/shoh/src/threads/user_interface/UserInterface.cpp new file mode 100644 index 0000000..e3dc7e1 --- /dev/null +++ b/source/shoh/src/threads/user_interface/UserInterface.cpp @@ -0,0 +1,114 @@ +/* + * UserInterface.cpp + * + * Created on: 8 May 2023 + */ + +#include "UserInterface.h" +#include + +UserInterface::UserInterface(ThreadCommon::QueueManager* qm) : +_qm(qm), lcd1(nullptr) +{ +} + +UserInterface::~UserInterface() +{ + delete this->lcd1; + delete this->lcd1_rs; + delete this->lcd1_en; + delete this->lcd1_d4; + delete this->lcd1_d5; + delete this->lcd1_d6; + delete this->lcd1_d7; +} + +void UserInterface::taskFunction() +{ + Event data(Event::Null, 0); + //LCD1 init. + this->initLCD(this->lcd1, this->lcd1_rs, this->lcd1_en, this->lcd1_d4, + this->lcd1_d5, this->lcd1_d6, this->lcd1_d7); + + for (;;) + { + this->_qm->receive(ThreadCommon::QueueManager::ui_event_manager, &data, portMAX_DELAY); + //Don't mind the type, we care only about the raw_data. + EventRawData ed = data.getDataOf(Event::NotifyUI); + if(ed != ERROR_RETURN) + this->handleEvent(reinterpret_cast(&ed)); + else + printf("ERROR: [UserInterface::taskFunction] Event gave ERROR_RETURN data."); + } + +} + +void UserInterface::handleEvent(InterfaceWithData* ui_data) +{ + switch (ui_data->display) + { + case LCD1: + this->handleLCD(this->lcd1, ui_data->data.str); + break; + default: + //Should never happen. + printf("WARNING: [UserInterface::handleEvent] executed default case."); + break; + } +} + +/******************************/ +/*Interface specific functions*/ +/******************************/ + +void UserInterface::handleLCD(LiquidCrystal *lcd, const char *str) +{ + //Interpret empty string as clear. + if(!strlen(str)) + lcd->clear(); + //Print the text otherwise. + else + { + lcd->setCursor(0, 0); + lcd->print(str); + } +} + +void UserInterface::initLCD(LiquidCrystal *lcd, + DigitalIoPin *rs, DigitalIoPin *en, + DigitalIoPin *d4, DigitalIoPin *d5, + DigitalIoPin *d6, DigitalIoPin *d7) +{ + rs = new DigitalIoPin(1, 9, false); + en = new DigitalIoPin(0, 14, false); + d4 = new DigitalIoPin(0, 13, false); + d5 = new DigitalIoPin(0, 12, false); + d6 = new DigitalIoPin(0, 23, false); + d7 = new DigitalIoPin(0, 11, false); + + //Fix Pin Muxing. + Chip_IOCON_PinMuxSet (LPC_IOCON, 1, 9, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 14, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 13, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 12, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 23, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 11, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + + rs->write(false); + en->write(false); + d4->write(false); + d5->write(false); + d6->write(false); + d7->write(false); + // LCD init. + lcd = new LiquidCrystal(rs, en, d4, d5, d6, d7); + // LCD configure display geometry. + lcd->begin(16, 2); + lcd->setCursor (0, 0); +} + +void thread_user_interface(void* pvParams) +{ + UserInterface ui(static_cast(pvParams)); + ui.taskFunction(); +} diff --git a/source/shoh/src/threads/user_interface/UserInterface.h b/source/shoh/src/threads/user_interface/UserInterface.h new file mode 100644 index 0000000..1f8df5b --- /dev/null +++ b/source/shoh/src/threads/user_interface/UserInterface.h @@ -0,0 +1,55 @@ +/* + * UserInterface.h + * + * Created on: 8 May 2023 + */ + +#ifndef THREADS_USER_INTERFACE_USERINTERFACE_H_ +#define THREADS_USER_INTERFACE_USERINTERFACE_H_ + +#include "ThreadCommon.h" +#include "Event.h" +#include "LiquidCrystal.h" + +class UserInterface { +public: + UserInterface(ThreadCommon::QueueManager* qm); + virtual ~UserInterface(); + + enum Interface + { + LCD1 + }; + + union InterfaceData + { + char str[64]; + }; + + struct InterfaceWithData + { + Interface display; + InterfaceData data; + }; + + void taskFunction(); +private: + /* Variables */ + ThreadCommon::QueueManager* _qm; + LiquidCrystal* lcd1; + DigitalIoPin *lcd1_rs, *lcd1_en, *lcd1_d4, *lcd1_d5, *lcd1_d6, *lcd1_d7; + + /* Methods */ + void handleEvent(InterfaceWithData* ui_data); + + //UIs + void handleLCD(LiquidCrystal *lcd, const char *str); + void initLCD(LiquidCrystal *lcd, + DigitalIoPin *rs, DigitalIoPin *en, + DigitalIoPin *d4, DigitalIoPin *d5, + DigitalIoPin *d6, DigitalIoPin *d7); +}; + +void thread_user_interface(void* pvParams); + +#endif /* THREADS_USER_INTERFACE_USERINTERFACE_H_ */ From 052d01542505aaa8bb367264c7b1d01aa586a60b Mon Sep 17 00:00:00 2001 From: RedHawk Date: Mon, 8 May 2023 15:35:46 +0300 Subject: [PATCH 12/18] LiquidCrystal: Added destructor. --- source/shoh/src/peripherals/LiquidCrystal.cpp | 2 ++ source/shoh/src/peripherals/LiquidCrystal.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/source/shoh/src/peripherals/LiquidCrystal.cpp b/source/shoh/src/peripherals/LiquidCrystal.cpp index 2b9b636..3a7988b 100644 --- a/source/shoh/src/peripherals/LiquidCrystal.cpp +++ b/source/shoh/src/peripherals/LiquidCrystal.cpp @@ -104,6 +104,8 @@ LiquidCrystal::LiquidCrystal(DigitalIoPin *rs, DigitalIoPin *enable, begin(16, 2); // default to 16x2 display } +LiquidCrystal::~LiquidCrystal() {} + void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { if (lines > 1) { _displayfunction |= LCD_2LINE; diff --git a/source/shoh/src/peripherals/LiquidCrystal.h b/source/shoh/src/peripherals/LiquidCrystal.h index 6954c3a..a33fcd9 100644 --- a/source/shoh/src/peripherals/LiquidCrystal.h +++ b/source/shoh/src/peripherals/LiquidCrystal.h @@ -50,6 +50,8 @@ public: LiquidCrystal(DigitalIoPin *rs, DigitalIoPin *enable, DigitalIoPin *d0, DigitalIoPin *d1, DigitalIoPin *d2, DigitalIoPin *d3); + virtual ~LiquidCrystal(); + void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS); void clear(); From f0bbfb22abd8885529a9553b7c5c866b08abf15a Mon Sep 17 00:00:00 2001 From: RedHawk Date: Mon, 8 May 2023 16:08:34 +0300 Subject: [PATCH 13/18] Menu & UI: [#25, #35]Communication between these tasks. * The code is a mess for now. I'm not sure if there is any reason to send a whole event to UI, it's better to send InterfaceWithData. * Sending to queue from Menu isn't great as well. --- source/shoh/src/threads/manager/Manager.cpp | 9 ++++----- source/shoh/src/threads/manager/Manager.h | 4 ++-- source/shoh/src/threads/manager/Menu.cpp | 7 ++++++- source/shoh/src/threads/manager/Menu.h | 3 ++- source/shoh/src/threads/user_interface/UserInterface.cpp | 2 +- source/shoh/src/threads/user_interface/UserInterface.h | 2 +- 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/source/shoh/src/threads/manager/Manager.cpp b/source/shoh/src/threads/manager/Manager.cpp index b5eee38..2f4e9ca 100644 --- a/source/shoh/src/threads/manager/Manager.cpp +++ b/source/shoh/src/threads/manager/Manager.cpp @@ -8,8 +8,8 @@ #include "Manager.h" #include "ThreadCommon.h" -Manager::Manager(ThreadCommon::QueueManager* qm, Menu * menu) -: _qm(qm), _menu(menu) +Manager::Manager(ThreadCommon::QueueManager* qm) +: _qm(qm), _menu{qm} { } @@ -43,13 +43,12 @@ void Manager::taskFunction() { _qm->receive(ThreadCommon::QueueManager::manager_event_master, &data, portMAX_DELAY); event_pair= this->parseEvent(&data); - _menu->HandleEventPair(&event_pair); + _menu.HandleEventPair(&event_pair); } } void thread_manager(void* pvParams) { - Menu menu; - Manager m(static_cast(pvParams), &menu); + Manager m(static_cast(pvParams)); m.taskFunction(); } diff --git a/source/shoh/src/threads/manager/Manager.h b/source/shoh/src/threads/manager/Manager.h index 8ab2884..7a8e844 100644 --- a/source/shoh/src/threads/manager/Manager.h +++ b/source/shoh/src/threads/manager/Manager.h @@ -16,13 +16,13 @@ class Manager { public: - Manager(ThreadCommon::QueueManager* qm, Menu * menu); + Manager(ThreadCommon::QueueManager* qm); virtual ~Manager(); void taskFunction(); private: Event::EventPair parseEvent(Event* e); ThreadCommon::QueueManager* _qm; - Menu* _menu; + Menu _menu; EventRawData rotary_action; }; diff --git a/source/shoh/src/threads/manager/Menu.cpp b/source/shoh/src/threads/manager/Menu.cpp index 2b15825..52c95d6 100644 --- a/source/shoh/src/threads/manager/Menu.cpp +++ b/source/shoh/src/threads/manager/Menu.cpp @@ -7,8 +7,10 @@ #include "Menu.h" #include +#include "UserInterface.h" -Menu::Menu(): current(&Menu::sInitView), set_point(0, 100, 1), +Menu::Menu(ThreadCommon::QueueManager* qm): _qm(qm), +current(&Menu::sInitView), set_point(0, 100, 1), main_text ("CURRENT %2d DESIRED %2d "), set_point_text("CURRENT %2d DESIRED[%2d] ") { @@ -164,4 +166,7 @@ void Menu::HandleObj (const MenuObjEvent &event) void Menu::NotifyAndRefreshUI (const char *str) { //Send string on a queue to UI task. + UserInterface::InterfaceWithData ud = {UserInterface::LCD1, *str}; + Event * p_e = new Event(Event::EventType::NotifyUI, *(reinterpret_cast(&ud))); + this->_qm->send(ThreadCommon::QueueManager::ui_event_manager, p_e, portMAX_DELAY); } \ No newline at end of file diff --git a/source/shoh/src/threads/manager/Menu.h b/source/shoh/src/threads/manager/Menu.h index a8a3d7f..bc5177d 100644 --- a/source/shoh/src/threads/manager/Menu.h +++ b/source/shoh/src/threads/manager/Menu.h @@ -19,12 +19,13 @@ typedef void (Menu::*p_state) (const MenuObjEvent &); class Menu { public: - Menu (); + Menu (ThreadCommon::QueueManager* qm); virtual ~Menu (); void HandleEventPair (Event::EventPair *ep); private: /* Variables and objects */ + ThreadCommon::QueueManager* _qm; p_state current; int ext_temp; Counter set_point; diff --git a/source/shoh/src/threads/user_interface/UserInterface.cpp b/source/shoh/src/threads/user_interface/UserInterface.cpp index e3dc7e1..ebc87b4 100644 --- a/source/shoh/src/threads/user_interface/UserInterface.cpp +++ b/source/shoh/src/threads/user_interface/UserInterface.cpp @@ -32,7 +32,7 @@ void UserInterface::taskFunction() for (;;) { - this->_qm->receive(ThreadCommon::QueueManager::ui_event_manager, &data, portMAX_DELAY); + this->_qm->receive(ThreadCommon::QueueManager::ui_event_manager, &data, portMAX_DELAY); //Don't mind the type, we care only about the raw_data. EventRawData ed = data.getDataOf(Event::NotifyUI); if(ed != ERROR_RETURN) diff --git a/source/shoh/src/threads/user_interface/UserInterface.h b/source/shoh/src/threads/user_interface/UserInterface.h index 1f8df5b..85befe5 100644 --- a/source/shoh/src/threads/user_interface/UserInterface.h +++ b/source/shoh/src/threads/user_interface/UserInterface.h @@ -23,7 +23,7 @@ public: union InterfaceData { - char str[64]; + const char str[64]; }; struct InterfaceWithData From ea1139567ab6ccc6249a4215638de8c39d899aae Mon Sep 17 00:00:00 2001 From: RedHawk Date: Tue, 9 May 2023 01:14:47 +0300 Subject: [PATCH 14/18] UI: [#35] Fixing issues. *Send UserInterface::InterfaceWithData in the queue instead of Event. *Remove pointer madness for LCD. *Timeout for Idle Event from Master thread. --- source/shoh/src/main.cpp | 2 +- source/shoh/src/threads/manager/Menu.cpp | 9 ++-- source/shoh/src/threads/manager/Menu.h | 2 +- source/shoh/src/threads/master/Master.cpp | 9 +++- .../threads/user_interface/UserInterface.cpp | 53 +++++++++---------- .../threads/user_interface/UserInterface.h | 7 +-- 6 files changed, 40 insertions(+), 42 deletions(-) diff --git a/source/shoh/src/main.cpp b/source/shoh/src/main.cpp index 4bb8f6e..740e2b4 100644 --- a/source/shoh/src/main.cpp +++ b/source/shoh/src/main.cpp @@ -30,7 +30,7 @@ int main(void) sizeof(Event), ThreadCommon::QueueManager::manager_event_master); qmanager->createQueue(20, - sizeof(Event), + sizeof(UserInterface::InterfaceWithData), ThreadCommon::QueueManager::ui_event_manager); //Creating tasks diff --git a/source/shoh/src/threads/manager/Menu.cpp b/source/shoh/src/threads/manager/Menu.cpp index 52c95d6..ac002ae 100644 --- a/source/shoh/src/threads/manager/Menu.cpp +++ b/source/shoh/src/threads/manager/Menu.cpp @@ -82,6 +82,7 @@ void Menu::sInitView(const MenuObjEvent &e) case MenuObjEvent::eClick: break; case MenuObjEvent::eRefresh: + printf("NOTE: sInitView handled eRefresh.\n"); this->SetState(&Menu::sMainView); break; default: @@ -166,7 +167,7 @@ void Menu::HandleObj (const MenuObjEvent &event) void Menu::NotifyAndRefreshUI (const char *str) { //Send string on a queue to UI task. - UserInterface::InterfaceWithData ud = {UserInterface::LCD1, *str}; - Event * p_e = new Event(Event::EventType::NotifyUI, *(reinterpret_cast(&ud))); - this->_qm->send(ThreadCommon::QueueManager::ui_event_manager, p_e, portMAX_DELAY); -} \ No newline at end of file + UserInterface::InterfaceWithData ud = {UserInterface::LCD1, str}; + //Event * p_e = new Event(Event::EventType::NotifyUI, *(reinterpret_cast(&ud))); + this->_qm->send(ThreadCommon::QueueManager::ui_event_manager, &ud, portMAX_DELAY); +} diff --git a/source/shoh/src/threads/manager/Menu.h b/source/shoh/src/threads/manager/Menu.h index bc5177d..c35a1fd 100644 --- a/source/shoh/src/threads/manager/Menu.h +++ b/source/shoh/src/threads/manager/Menu.h @@ -27,7 +27,7 @@ private: /* Variables and objects */ ThreadCommon::QueueManager* _qm; p_state current; - int ext_temp; + short ext_temp; Counter set_point; const char main_text[64]; const char set_point_text[64]; diff --git a/source/shoh/src/threads/master/Master.cpp b/source/shoh/src/threads/master/Master.cpp index 76acb12..aaf4588 100644 --- a/source/shoh/src/threads/master/Master.cpp +++ b/source/shoh/src/threads/master/Master.cpp @@ -16,24 +16,29 @@ void Master::taskFunction() { Event data(Event::Null, 0); bool LedState = true; for (;;) { - _qm->receive(ThreadCommon::QueueManager::master_event_all, &data, portMAX_DELAY); + if(!_qm->receive(ThreadCommon::QueueManager::master_event_all, &data, 10000)) + data.setDataOf(Event::Rotary, ThreadCommon::RotaryAction::Idle); switch(data.getDataOf(Event::Rotary)) { case ThreadCommon::RotaryAction::Right: Board_LED_Set(ThreadCommon::RotaryAction::Right, LedState); printf("Right\r\n"); + _qm->send(ThreadCommon::QueueManager::manager_event_master, &data, 0); break; case ThreadCommon::RotaryAction::Left: Board_LED_Set(ThreadCommon::RotaryAction::Left, LedState); printf("Left\r\n"); + _qm->send(ThreadCommon::QueueManager::manager_event_master, &data, 0); break; case ThreadCommon::RotaryAction::Press: Board_LED_Set(ThreadCommon::RotaryAction::Press, LedState); printf("Press\r\n"); + _qm->send(ThreadCommon::QueueManager::manager_event_master, &data, 0); break; case ThreadCommon::RotaryAction::Idle: - Board_LED_Set(ThreadCommon::RotaryAction::Right, LedState); + //Board_LED_Set(ThreadCommon::RotaryAction::Right, LedState); printf("Idle\r\n"); + _qm->send(ThreadCommon::QueueManager::manager_event_master, &data, 0); break; } LedState = !LedState; diff --git a/source/shoh/src/threads/user_interface/UserInterface.cpp b/source/shoh/src/threads/user_interface/UserInterface.cpp index ebc87b4..f75634e 100644 --- a/source/shoh/src/threads/user_interface/UserInterface.cpp +++ b/source/shoh/src/threads/user_interface/UserInterface.cpp @@ -10,6 +10,7 @@ UserInterface::UserInterface(ThreadCommon::QueueManager* qm) : _qm(qm), lcd1(nullptr) { + this->initLCD1(); } UserInterface::~UserInterface() @@ -26,19 +27,15 @@ UserInterface::~UserInterface() void UserInterface::taskFunction() { Event data(Event::Null, 0); - //LCD1 init. - this->initLCD(this->lcd1, this->lcd1_rs, this->lcd1_en, this->lcd1_d4, - this->lcd1_d5, this->lcd1_d6, this->lcd1_d7); + InterfaceWithData ui_with_data; for (;;) { - this->_qm->receive(ThreadCommon::QueueManager::ui_event_manager, &data, portMAX_DELAY); + this->_qm->receive(ThreadCommon::QueueManager::ui_event_manager, &ui_with_data, portMAX_DELAY); //Don't mind the type, we care only about the raw_data. - EventRawData ed = data.getDataOf(Event::NotifyUI); - if(ed != ERROR_RETURN) - this->handleEvent(reinterpret_cast(&ed)); - else - printf("ERROR: [UserInterface::taskFunction] Event gave ERROR_RETURN data."); + //EventRawData ed = data.getDataOf(Event::NotifyUI); + //if(ed != ERROR_RETURN) + this->handleEvent(&ui_with_data); } } @@ -52,7 +49,7 @@ void UserInterface::handleEvent(InterfaceWithData* ui_data) break; default: //Should never happen. - printf("WARNING: [UserInterface::handleEvent] executed default case."); + printf("WARNING: [UserInterface::handleEvent] executed default case.\n"); break; } } @@ -74,17 +71,14 @@ void UserInterface::handleLCD(LiquidCrystal *lcd, const char *str) } } -void UserInterface::initLCD(LiquidCrystal *lcd, - DigitalIoPin *rs, DigitalIoPin *en, - DigitalIoPin *d4, DigitalIoPin *d5, - DigitalIoPin *d6, DigitalIoPin *d7) +void UserInterface::initLCD1() { - rs = new DigitalIoPin(1, 9, false); - en = new DigitalIoPin(0, 14, false); - d4 = new DigitalIoPin(0, 13, false); - d5 = new DigitalIoPin(0, 12, false); - d6 = new DigitalIoPin(0, 23, false); - d7 = new DigitalIoPin(0, 11, false); + this->lcd1_rs = new DigitalIoPin(1, 9, false); + this->lcd1_en = new DigitalIoPin(0, 14, false); + this->lcd1_d4 = new DigitalIoPin(0, 13, false); + this->lcd1_d5 = new DigitalIoPin(0, 12, false); + this->lcd1_d6 = new DigitalIoPin(0, 23, false); + this->lcd1_d7 = new DigitalIoPin(0, 11, false); //Fix Pin Muxing. Chip_IOCON_PinMuxSet (LPC_IOCON, 1, 9, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); @@ -94,17 +88,18 @@ void UserInterface::initLCD(LiquidCrystal *lcd, Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 23, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 11, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); - rs->write(false); - en->write(false); - d4->write(false); - d5->write(false); - d6->write(false); - d7->write(false); + this->lcd1_rs->write(false); + this->lcd1_en->write(false); + this->lcd1_d4->write(false); + this->lcd1_d5->write(false); + this->lcd1_d6->write(false); + this->lcd1_d7->write(false); // LCD init. - lcd = new LiquidCrystal(rs, en, d4, d5, d6, d7); + this->lcd1 = new LiquidCrystal(this->lcd1_rs, this->lcd1_en, this->lcd1_d4, + this->lcd1_d5, this->lcd1_d6, this->lcd1_d7); // LCD configure display geometry. - lcd->begin(16, 2); - lcd->setCursor (0, 0); + this->lcd1->begin(16, 2); + this->lcd1->setCursor (0, 0); } void thread_user_interface(void* pvParams) diff --git a/source/shoh/src/threads/user_interface/UserInterface.h b/source/shoh/src/threads/user_interface/UserInterface.h index 85befe5..5974c5b 100644 --- a/source/shoh/src/threads/user_interface/UserInterface.h +++ b/source/shoh/src/threads/user_interface/UserInterface.h @@ -23,7 +23,7 @@ public: union InterfaceData { - const char str[64]; + const char* str; }; struct InterfaceWithData @@ -44,10 +44,7 @@ private: //UIs void handleLCD(LiquidCrystal *lcd, const char *str); - void initLCD(LiquidCrystal *lcd, - DigitalIoPin *rs, DigitalIoPin *en, - DigitalIoPin *d4, DigitalIoPin *d5, - DigitalIoPin *d6, DigitalIoPin *d7); + void initLCD1(); }; void thread_user_interface(void* pvParams); From 2b02a786fa3ff229c8db6317eec6eeeec00c493f Mon Sep 17 00:00:00 2001 From: RedHawk Date: Wed, 10 May 2023 13:11:41 +0300 Subject: [PATCH 15/18] Menu & UI: [#25, #35] Fixed UI. *String in Menu are static. Temperature is limited by -99 and 99 bounds. *UserInterface cleaned a bit. --- source/shoh/src/threads/manager/Menu.cpp | 39 ++++++++++++------- source/shoh/src/threads/manager/Menu.h | 2 +- .../threads/user_interface/UserInterface.cpp | 4 -- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/source/shoh/src/threads/manager/Menu.cpp b/source/shoh/src/threads/manager/Menu.cpp index ac002ae..b7765f1 100644 --- a/source/shoh/src/threads/manager/Menu.cpp +++ b/source/shoh/src/threads/manager/Menu.cpp @@ -10,11 +10,12 @@ #include "UserInterface.h" Menu::Menu(ThreadCommon::QueueManager* qm): _qm(qm), -current(&Menu::sInitView), set_point(0, 100, 1), -main_text ("CURRENT %2d DESIRED %2d "), -set_point_text("CURRENT %2d DESIRED[%2d] ") +current(&Menu::sInitView), ext_temp(-99, 99, 1), set_point(-99, 99, 1), +main_text ("CURRENT %3d DESIRED %3d "), +set_point_text("CURRENT %3d DESIRED[%3d] ") { this->SetState(&Menu::sInitView); + ext_temp.setCurrent(0); set_point.setCurrent(0); } @@ -51,8 +52,8 @@ void Menu::HandleEventPair (Event::EventPair *ep) } break; case Event::ExternalTemp: - //Change ExternalTemp value. - this->ext_temp = ep->rd; + //Change ExternalTemp value. -99 <= ext_temp <= 99 + this->ext_temp.setCurrent(ep->rd); //Refresh the menu screen. this->HandleObj(MenuObjEvent (MenuObjEvent::eRefresh)); break; @@ -73,6 +74,7 @@ void Menu::sInitView(const MenuObjEvent &e) this->NotifyAndRefreshUI("Loading..."); break; case MenuObjEvent::eUnFocus: + printf("NOTE: leave sInitView\n"); this->NotifyAndRefreshUI(""); break; case MenuObjEvent::eRollClockWise: @@ -80,6 +82,7 @@ void Menu::sInitView(const MenuObjEvent &e) case MenuObjEvent::eRollCClockWise: break; case MenuObjEvent::eClick: + this->SetState(&Menu::sMainView); break; case MenuObjEvent::eRefresh: printf("NOTE: sInitView handled eRefresh.\n"); @@ -92,11 +95,12 @@ void Menu::sInitView(const MenuObjEvent &e) void Menu::sMainView(const MenuObjEvent &e) { - char screen_text[64]; + static char screen_text[64]; switch (e.type) { case MenuObjEvent::eFocus: - sprintf(screen_text, main_text, this->ext_temp, this->set_point.getCurrent()); + sprintf(screen_text, main_text, this->ext_temp.getCurrent(), + this->set_point.getCurrent()); this->NotifyAndRefreshUI(screen_text); break; case MenuObjEvent::eUnFocus: @@ -110,7 +114,8 @@ void Menu::sMainView(const MenuObjEvent &e) this->SetState(&Menu::sSetPointMod); break; case MenuObjEvent::eRefresh: - sprintf(screen_text, main_text, this->ext_temp, this->set_point.getCurrent()); + sprintf(screen_text, main_text, this->ext_temp.getCurrent(), + this->set_point.getCurrent()); this->NotifyAndRefreshUI(screen_text); break; default: @@ -120,11 +125,12 @@ void Menu::sMainView(const MenuObjEvent &e) void Menu::sSetPointMod(const MenuObjEvent &e) { - char screen_text[64]; + static char screen_text[64]; switch (e.type) { case MenuObjEvent::eFocus: - sprintf(screen_text, set_point_text, this->ext_temp, this->set_point.getCurrent()); + sprintf(screen_text, set_point_text, this->ext_temp.getCurrent(), + this->set_point.getCurrent()); this->NotifyAndRefreshUI(screen_text); break; case MenuObjEvent::eUnFocus: @@ -132,19 +138,22 @@ void Menu::sSetPointMod(const MenuObjEvent &e) break; case MenuObjEvent::eRollClockWise: set_point.inc(); - sprintf(screen_text, set_point_text, this->ext_temp, this->set_point.getCurrent()); + sprintf(screen_text, set_point_text, this->ext_temp.getCurrent(), + this->set_point.getCurrent()); this->NotifyAndRefreshUI(screen_text); break; case MenuObjEvent::eRollCClockWise: set_point.dec(); - sprintf(screen_text, set_point_text, this->ext_temp, this->set_point.getCurrent()); + sprintf(screen_text, set_point_text, this->ext_temp.getCurrent(), + this->set_point.getCurrent()); this->NotifyAndRefreshUI(screen_text); break; case MenuObjEvent::eClick: this->SetState(&Menu::sMainView); break; case MenuObjEvent::eRefresh: - sprintf(screen_text, set_point_text, this->ext_temp, this->set_point.getCurrent()); + sprintf(screen_text, set_point_text, this->ext_temp.getCurrent(), + this->set_point.getCurrent()); this->NotifyAndRefreshUI(screen_text); break; default: @@ -168,6 +177,6 @@ void Menu::NotifyAndRefreshUI (const char *str) { //Send string on a queue to UI task. UserInterface::InterfaceWithData ud = {UserInterface::LCD1, str}; - //Event * p_e = new Event(Event::EventType::NotifyUI, *(reinterpret_cast(&ud))); - this->_qm->send(ThreadCommon::QueueManager::ui_event_manager, &ud, portMAX_DELAY); + this->_qm->send( + ThreadCommon::QueueManager::ui_event_manager, &ud, portMAX_DELAY); } diff --git a/source/shoh/src/threads/manager/Menu.h b/source/shoh/src/threads/manager/Menu.h index c35a1fd..676ceb0 100644 --- a/source/shoh/src/threads/manager/Menu.h +++ b/source/shoh/src/threads/manager/Menu.h @@ -27,7 +27,7 @@ private: /* Variables and objects */ ThreadCommon::QueueManager* _qm; p_state current; - short ext_temp; + Counter ext_temp; Counter set_point; const char main_text[64]; const char set_point_text[64]; diff --git a/source/shoh/src/threads/user_interface/UserInterface.cpp b/source/shoh/src/threads/user_interface/UserInterface.cpp index f75634e..7a31991 100644 --- a/source/shoh/src/threads/user_interface/UserInterface.cpp +++ b/source/shoh/src/threads/user_interface/UserInterface.cpp @@ -26,15 +26,11 @@ UserInterface::~UserInterface() void UserInterface::taskFunction() { - Event data(Event::Null, 0); InterfaceWithData ui_with_data; for (;;) { this->_qm->receive(ThreadCommon::QueueManager::ui_event_manager, &ui_with_data, portMAX_DELAY); - //Don't mind the type, we care only about the raw_data. - //EventRawData ed = data.getDataOf(Event::NotifyUI); - //if(ed != ERROR_RETURN) this->handleEvent(&ui_with_data); } From 356b3ebbe95473b06ffa86e42ff01346c2b43718 Mon Sep 17 00:00:00 2001 From: RedHawk Date: Wed, 10 May 2023 13:12:13 +0300 Subject: [PATCH 16/18] LiquidCrystal.cpp: [#35] LCD now wraps text. --- source/shoh/src/peripherals/LiquidCrystal.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/source/shoh/src/peripherals/LiquidCrystal.cpp b/source/shoh/src/peripherals/LiquidCrystal.cpp index 3a7988b..ac49f8d 100644 --- a/source/shoh/src/peripherals/LiquidCrystal.cpp +++ b/source/shoh/src/peripherals/LiquidCrystal.cpp @@ -195,15 +195,17 @@ void LiquidCrystal::home() void LiquidCrystal::print(std::string const &s) { - print(s.c_str()); + print(s.c_str()); } void LiquidCrystal::print(const char *s) { - while(*s) { - write(*s); - ++s; - } + for (uint8_t i = 0; *s != '\0' && i <= 1; i++) { + for (size_t q = 0; *s != '\0' && q < 16; q++, s++) { + this->setCursor(q, i); + this->write(*s); + } + } } void LiquidCrystal::setCursor(uint8_t col, uint8_t row) From 0e64099a56fcb6d77d8be8d2902c38e4582264fa Mon Sep 17 00:00:00 2001 From: RedHawk Date: Wed, 10 May 2023 13:45:47 +0300 Subject: [PATCH 17/18] DigitalIoPin: Added LPC11U68 specific pin functions *In order for pin to act as IO, it must be configured with according function. Usually it is IOCON_FUNC0, but some pins on port 0 are an exception (IOCON_FUNC1). --- source/shoh/src/peripherals/DigitalIoPin.cpp | 14 ++++++++++---- source/shoh/src/peripherals/DigitalIoPin.h | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/source/shoh/src/peripherals/DigitalIoPin.cpp b/source/shoh/src/peripherals/DigitalIoPin.cpp index 51d4021..1028d3c 100644 --- a/source/shoh/src/peripherals/DigitalIoPin.cpp +++ b/source/shoh/src/peripherals/DigitalIoPin.cpp @@ -18,6 +18,12 @@ DigitalIoPin::DigitalIoPin (int port, int pin, bool input, bool pullup, _io._invert = invert; _io.IOCON_mode = IOCON_MODE_INACT; _io.IOCON_inv = IOCON_FUNC0; + //Table 83 from UM10732-11u68.pdf + if(port == 0 && ((pin >= 10 && pin <= 15) || pin == 0)) + _io.IOFunction = IOCON_FUNC1; + else + _io.IOFunction = IOCON_FUNC0; + if (isr){ _io.isr_i = isr_index; setIsr(); @@ -48,7 +54,7 @@ DigitalIoPin::setIoPin () } } Chip_IOCON_PinMuxSet (LPC_IOCON, _io._port, _io._pin, - (_io.IOCON_mode | _io.DigitalEn | _io.IOCON_inv)); + (_io.IOFunction | _io.IOCON_mode | _io.DigitalEn | _io.IOCON_inv)); /** False direction equals input */ Chip_GPIO_SetPinDIR (LPC_GPIO, _io._port, _io._pin, direction); } @@ -75,9 +81,9 @@ DigitalIoPin::setIsr () Chip_Clock_SetIOCONFiltClockDiv(0, 64); Chip_IOCON_PinMuxSet (LPC_IOCON, _io._port, _io._pin, - (_io.IOCON_mode | _io.DigitalEn - | _io.IOCON_inv | IOCON_CLKDIV(0) - | IOCON_S_MODE(3))); + (_io.IOFunction | _io.IOCON_mode + | _io.DigitalEn | _io.IOCON_inv + | IOCON_CLKDIV(0) | IOCON_S_MODE(3))); /** False direction equals input */ Chip_GPIO_SetPinDIR (LPC_GPIO, _io._port, _io._pin, direction); diff --git a/source/shoh/src/peripherals/DigitalIoPin.h b/source/shoh/src/peripherals/DigitalIoPin.h index 19c6c7b..6241aa9 100644 --- a/source/shoh/src/peripherals/DigitalIoPin.h +++ b/source/shoh/src/peripherals/DigitalIoPin.h @@ -23,6 +23,7 @@ typedef struct DigitalIOConfigStruct uint32_t IOCON_mode; uint32_t IOCON_inv; uint32_t DigitalEn; + uint32_t IOFunction; IRQn_Type isr_i; } DigitalIOConfigStruct; From 80a89806f74c15e8bc73ddc9191bcc2891dc3787 Mon Sep 17 00:00:00 2001 From: RedHawk Date: Wed, 10 May 2023 13:47:06 +0300 Subject: [PATCH 18/18] UI: [#35] Remove redundant fix. *DigitalIoPin now handles pin muxing properly. --- source/shoh/src/threads/user_interface/UserInterface.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/source/shoh/src/threads/user_interface/UserInterface.cpp b/source/shoh/src/threads/user_interface/UserInterface.cpp index 7a31991..bafd5d4 100644 --- a/source/shoh/src/threads/user_interface/UserInterface.cpp +++ b/source/shoh/src/threads/user_interface/UserInterface.cpp @@ -76,14 +76,6 @@ void UserInterface::initLCD1() this->lcd1_d6 = new DigitalIoPin(0, 23, false); this->lcd1_d7 = new DigitalIoPin(0, 11, false); - //Fix Pin Muxing. - Chip_IOCON_PinMuxSet (LPC_IOCON, 1, 9, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); - Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 14, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); - Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 13, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); - Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 12, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); - Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 23, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); - Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 11, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); - this->lcd1_rs->write(false); this->lcd1_en->write(false); this->lcd1_d4->write(false);