diff --git a/source/shoh/.cproject b/source/shoh/.cproject index b1e8833..ff20bcd 100644 --- a/source/shoh/.cproject +++ b/source/shoh/.cproject @@ -50,6 +50,7 @@ + @@ -83,6 +84,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_ */