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 @@
+
@@ -102,6 +104,7 @@
+
@@ -200,6 +203,7 @@
+
@@ -229,6 +233,7 @@
+
@@ -249,6 +254,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/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();
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_ */