commit
39a297c8a8
@ -50,7 +50,9 @@
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/common}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/master}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/user_interface}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/threads/rotary}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/threads/manager}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/peripherals}""/>
|
||||
</option>
|
||||
<option id="com.crt.advproject.cpp.misc.dialect.4036734" name="Language standard" superClass="com.crt.advproject.cpp.misc.dialect" useByScannerDiscovery="true" value="com.crt.advproject.misc.dialect.cpp17" valueType="enumerated"/>
|
||||
@ -82,6 +84,7 @@
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/common}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/master}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/user_interface}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/peripherals}""/>
|
||||
</option>
|
||||
<option id="com.crt.advproject.c.misc.dialect.82852045" name="Language standard" superClass="com.crt.advproject.c.misc.dialect" useByScannerDiscovery="true" value="com.crt.advproject.misc.dialect.c17" valueType="enumerated"/>
|
||||
@ -101,6 +104,7 @@
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/common}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/master}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/user_interface}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/peripherals}""/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1836378919" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
@ -199,6 +203,7 @@
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/peripherals}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/FreeRTOSCPP}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/common}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/user_interface}""/>
|
||||
</option>
|
||||
<inputType id="com.crt.advproject.compiler.cpp.input.903614193" superClass="com.crt.advproject.compiler.cpp.input"/>
|
||||
</tool>
|
||||
@ -228,6 +233,7 @@
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/peripherals}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/FreeRTOSCPP}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/common}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/user_interface}""/>
|
||||
</option>
|
||||
<option id="com.crt.advproject.c.misc.dialect.1008527937" name="Language standard" superClass="com.crt.advproject.c.misc.dialect" useByScannerDiscovery="true" value="com.crt.advproject.misc.dialect.c17" valueType="enumerated"/>
|
||||
<inputType id="com.crt.advproject.compiler.input.246185412" superClass="com.crt.advproject.compiler.input"/>
|
||||
@ -248,6 +254,7 @@
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/peripherals}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/FreeRTOSCPP}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/common}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/user_interface}""/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1117166373" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
<inputType id="com.crt.advproject.assembler.input.2071009798" name="Additional Assembly Source Files" superClass="com.crt.advproject.assembler.input"/>
|
||||
|
||||
@ -3,13 +3,13 @@
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include <cr_section_macros.h>
|
||||
#include "retarget_uart.h"
|
||||
|
||||
#include "ThreadCommon.h"
|
||||
#include "Master.h"
|
||||
#include "Rotary.h"
|
||||
#include "retarget_uart.h"
|
||||
#include "LiquidCrystal.h"
|
||||
|
||||
void lcd_starting();
|
||||
#include "Manager.h"
|
||||
#include "UserInterface.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
@ -20,19 +20,30 @@ int main(void)
|
||||
|
||||
printf("Hello there!\r\n");
|
||||
|
||||
lcd_starting();
|
||||
|
||||
ThreadCommon::ThreadManager* manager = new ThreadCommon::ThreadManager;
|
||||
ThreadCommon::QueueManager* qmanager = new ThreadCommon::QueueManager;
|
||||
//Creating queues
|
||||
qmanager->createQueue(100,
|
||||
sizeof(Event),
|
||||
ThreadCommon::QueueManager::master_event_all);
|
||||
qmanager->createQueue(20,
|
||||
sizeof(Event),
|
||||
ThreadCommon::QueueManager::manager_event_master);
|
||||
qmanager->createQueue(20,
|
||||
sizeof(UserInterface::InterfaceWithData),
|
||||
ThreadCommon::QueueManager::ui_event_manager);
|
||||
|
||||
//Creating tasks
|
||||
manager->createTask(master_thread, "master",
|
||||
manager->createTask(thread_master, "master",
|
||||
configMINIMAL_STACK_SIZE * 10,tskIDLE_PRIORITY + 1UL,
|
||||
static_cast<void*>(qmanager));
|
||||
manager->createTask(rotary_thread, "rotary",
|
||||
manager->createTask(thread_manager, "manager",
|
||||
configMINIMAL_STACK_SIZE * 10,tskIDLE_PRIORITY + 1UL,
|
||||
static_cast<void*>(qmanager));
|
||||
manager->createTask(thread_rotary, "rotary",
|
||||
configMINIMAL_STACK_SIZE * 10,tskIDLE_PRIORITY + 1UL,
|
||||
static_cast<void*>(qmanager));
|
||||
manager->createTask(thread_user_interface, "user_interface",
|
||||
configMINIMAL_STACK_SIZE * 10,tskIDLE_PRIORITY + 1UL,
|
||||
static_cast<void*>(qmanager));
|
||||
|
||||
@ -41,44 +52,3 @@ int main(void)
|
||||
|
||||
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...");
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
@ -193,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)
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -23,9 +23,16 @@ public:
|
||||
Rotary,
|
||||
InternalTemp,
|
||||
ExternalTemp,
|
||||
SetPoint
|
||||
SetPoint,
|
||||
NotifyUI
|
||||
};
|
||||
|
||||
typedef struct _EventPair
|
||||
{
|
||||
EventRawData rd;
|
||||
EventType et;
|
||||
} EventPair;
|
||||
|
||||
Event(Event::EventType type, EventRawData data)
|
||||
{
|
||||
events.insert({type, data});
|
||||
|
||||
102
source/shoh/src/threads/manager/Counter.h
Normal file
102
source/shoh/src/threads/manager/Counter.h
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Counter.h
|
||||
*
|
||||
* Created on: Sep 1, 2022
|
||||
* Author: tylen
|
||||
*/
|
||||
|
||||
#ifndef COUNTER_H_
|
||||
#define COUNTER_H_
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
template <class CounterDataType> class Counter
|
||||
{
|
||||
|
||||
public:
|
||||
Counter (CounterDataType lower_boundary, CounterDataType upper_boundary,
|
||||
CounterDataType step);
|
||||
void inc ();
|
||||
void dec ();
|
||||
CounterDataType getCurrent ();
|
||||
void setCurrent (CounterDataType num);
|
||||
~Counter () = default;
|
||||
|
||||
private:
|
||||
CounterDataType init;
|
||||
CounterDataType up_lim;
|
||||
CounterDataType down_lim;
|
||||
CounterDataType _step;
|
||||
};
|
||||
|
||||
|
||||
template <class CounterDataType>
|
||||
void
|
||||
Counter<CounterDataType>::inc ()
|
||||
{
|
||||
if ((init + _step) <= up_lim)
|
||||
{
|
||||
init += _step;
|
||||
}
|
||||
}
|
||||
|
||||
template <class CounterDataType>
|
||||
void
|
||||
Counter<CounterDataType>::dec ()
|
||||
{
|
||||
if (init - _step >= down_lim)
|
||||
{
|
||||
init -= _step;
|
||||
}
|
||||
}
|
||||
|
||||
template <class CounterDataType>
|
||||
CounterDataType
|
||||
Counter<CounterDataType>::getCurrent ()
|
||||
{
|
||||
return this->init;
|
||||
}
|
||||
|
||||
template <class CounterDataType>
|
||||
Counter<CounterDataType>::Counter (CounterDataType lower_boundary,
|
||||
CounterDataType upper_boundary,
|
||||
CounterDataType step)
|
||||
{
|
||||
up_lim = upper_boundary;
|
||||
down_lim = lower_boundary;
|
||||
_step = step;
|
||||
if (down_lim > up_lim)
|
||||
{
|
||||
init = up_lim;
|
||||
}
|
||||
else if (down_lim < 0)
|
||||
{
|
||||
init = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
init = down_lim;
|
||||
}
|
||||
}
|
||||
|
||||
template <class CounterDataType>
|
||||
void
|
||||
Counter<CounterDataType>::setCurrent (CounterDataType num)
|
||||
{
|
||||
if (num > up_lim)
|
||||
{
|
||||
init = up_lim;
|
||||
}
|
||||
else if (num < down_lim)
|
||||
{
|
||||
init = down_lim;
|
||||
}
|
||||
else
|
||||
{
|
||||
init = num;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* COUNTER_H_ */
|
||||
54
source/shoh/src/threads/manager/Manager.cpp
Normal file
54
source/shoh/src/threads/manager/Manager.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Manager.cpp
|
||||
*
|
||||
* Created on: 29 Apr 2023
|
||||
* Author: dave
|
||||
*/
|
||||
|
||||
#include "Manager.h"
|
||||
#include "ThreadCommon.h"
|
||||
|
||||
Manager::Manager(ThreadCommon::QueueManager* qm)
|
||||
: _qm(qm), _menu{qm}
|
||||
{
|
||||
}
|
||||
|
||||
Manager::~Manager()
|
||||
{
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
Event::EventPair Manager::parseEvent(Event* e)
|
||||
{
|
||||
EventRawData raw_data;
|
||||
for(Event::EventType i :
|
||||
{Event::Rotary, Event::InternalTemp,
|
||||
Event::ExternalTemp})
|
||||
{
|
||||
raw_data = e->getDataOf(i);
|
||||
if(raw_data != ERROR_RETURN)
|
||||
{
|
||||
Event::EventPair p = {raw_data, i};
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return {ERROR_RETURN, Event::Null};
|
||||
}
|
||||
|
||||
void Manager::taskFunction()
|
||||
{
|
||||
Event data(Event::Null, 0);
|
||||
Event::EventPair event_pair = {0, Event::EventType::Null};
|
||||
for(;;)
|
||||
{
|
||||
_qm->receive<Event>(ThreadCommon::QueueManager::manager_event_master, &data, portMAX_DELAY);
|
||||
event_pair= this->parseEvent(&data);
|
||||
_menu.HandleEventPair(&event_pair);
|
||||
}
|
||||
}
|
||||
|
||||
void thread_manager(void* pvParams)
|
||||
{
|
||||
Manager m(static_cast<ThreadCommon::QueueManager*>(pvParams));
|
||||
m.taskFunction();
|
||||
}
|
||||
32
source/shoh/src/threads/manager/Manager.h
Normal file
32
source/shoh/src/threads/manager/Manager.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Manager.h
|
||||
*
|
||||
* Created on: 29 Apr 2023
|
||||
* Author: dave
|
||||
*/
|
||||
|
||||
#ifndef THREADS_MANAGER_MANAGER_H_
|
||||
#define THREADS_MANAGER_MANAGER_H_
|
||||
|
||||
#include "ThreadCommon.h"
|
||||
#include "Event.h"
|
||||
#include "Counter.h"
|
||||
#include "Menu.h"
|
||||
|
||||
|
||||
class Manager {
|
||||
public:
|
||||
Manager(ThreadCommon::QueueManager* qm);
|
||||
virtual ~Manager();
|
||||
void taskFunction();
|
||||
private:
|
||||
Event::EventPair parseEvent(Event* e);
|
||||
ThreadCommon::QueueManager* _qm;
|
||||
Menu _menu;
|
||||
|
||||
EventRawData rotary_action;
|
||||
};
|
||||
|
||||
void thread_manager(void* pvParams);
|
||||
|
||||
#endif /* THREADS_MANAGER_MANAGER_H_ */
|
||||
182
source/shoh/src/threads/manager/Menu.cpp
Normal file
182
source/shoh/src/threads/manager/Menu.cpp
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Menu.cpp
|
||||
*
|
||||
* Created on: 29 Apr 2023
|
||||
* Author: dave
|
||||
*/
|
||||
|
||||
#include "Menu.h"
|
||||
#include <assert.h>
|
||||
#include "UserInterface.h"
|
||||
|
||||
Menu::Menu(ThreadCommon::QueueManager* qm): _qm(qm),
|
||||
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);
|
||||
}
|
||||
|
||||
Menu::~Menu()
|
||||
{
|
||||
}
|
||||
|
||||
void Menu::HandleEventPair (Event::EventPair *ep)
|
||||
{
|
||||
switch(ep->et/*EventType*/)
|
||||
{
|
||||
case Event::Rotary:
|
||||
// can be wrapped in a function, but this was found to be more clear solution,
|
||||
// since we are still handling eventpair here, although nested
|
||||
switch(static_cast<ThreadCommon::RotaryAction>(ep->rd)/*RawData*/)
|
||||
{
|
||||
case ThreadCommon::RotaryAction::Right:
|
||||
this->HandleObj(MenuObjEvent (MenuObjEvent::eRollClockWise));
|
||||
break;
|
||||
case ThreadCommon::RotaryAction::Left:
|
||||
this->HandleObj(MenuObjEvent (MenuObjEvent::eRollCClockWise));
|
||||
break;
|
||||
case ThreadCommon::RotaryAction::Press:
|
||||
this->HandleObj(MenuObjEvent (MenuObjEvent::eClick));
|
||||
break;
|
||||
case ThreadCommon::RotaryAction::Idle:
|
||||
/*I guess this is left for debugging purposes ;D*/
|
||||
this->HandleObj(MenuObjEvent (MenuObjEvent::eRefresh));
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
/* Pretty damn bad code if reached here */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Event::ExternalTemp:
|
||||
//Change ExternalTemp value. -99 <= ext_temp <= 99
|
||||
this->ext_temp.setCurrent(ep->rd);
|
||||
//Refresh the menu screen.
|
||||
this->HandleObj(MenuObjEvent (MenuObjEvent::eRefresh));
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
/* Manager has big issues... */
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* States */
|
||||
void Menu::sInitView(const MenuObjEvent &e)
|
||||
{
|
||||
switch (e.type)
|
||||
{
|
||||
case MenuObjEvent::eFocus:
|
||||
this->NotifyAndRefreshUI("Loading...");
|
||||
break;
|
||||
case MenuObjEvent::eUnFocus:
|
||||
printf("NOTE: leave sInitView\n");
|
||||
this->NotifyAndRefreshUI("");
|
||||
break;
|
||||
case MenuObjEvent::eRollClockWise:
|
||||
break;
|
||||
case MenuObjEvent::eRollCClockWise:
|
||||
break;
|
||||
case MenuObjEvent::eClick:
|
||||
this->SetState(&Menu::sMainView);
|
||||
break;
|
||||
case MenuObjEvent::eRefresh:
|
||||
printf("NOTE: sInitView handled eRefresh.\n");
|
||||
this->SetState(&Menu::sMainView);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Menu::sMainView(const MenuObjEvent &e)
|
||||
{
|
||||
static char screen_text[64];
|
||||
switch (e.type)
|
||||
{
|
||||
case MenuObjEvent::eFocus:
|
||||
sprintf(screen_text, main_text, this->ext_temp.getCurrent(),
|
||||
this->set_point.getCurrent());
|
||||
this->NotifyAndRefreshUI(screen_text);
|
||||
break;
|
||||
case MenuObjEvent::eUnFocus:
|
||||
this->NotifyAndRefreshUI("");
|
||||
break;
|
||||
case MenuObjEvent::eRollClockWise:
|
||||
break;
|
||||
case MenuObjEvent::eRollCClockWise:
|
||||
break;
|
||||
case MenuObjEvent::eClick:
|
||||
this->SetState(&Menu::sSetPointMod);
|
||||
break;
|
||||
case MenuObjEvent::eRefresh:
|
||||
sprintf(screen_text, main_text, this->ext_temp.getCurrent(),
|
||||
this->set_point.getCurrent());
|
||||
this->NotifyAndRefreshUI(screen_text);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Menu::sSetPointMod(const MenuObjEvent &e)
|
||||
{
|
||||
static char screen_text[64];
|
||||
switch (e.type)
|
||||
{
|
||||
case MenuObjEvent::eFocus:
|
||||
sprintf(screen_text, set_point_text, this->ext_temp.getCurrent(),
|
||||
this->set_point.getCurrent());
|
||||
this->NotifyAndRefreshUI(screen_text);
|
||||
break;
|
||||
case MenuObjEvent::eUnFocus:
|
||||
this->NotifyAndRefreshUI("");
|
||||
break;
|
||||
case MenuObjEvent::eRollClockWise:
|
||||
set_point.inc();
|
||||
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.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.getCurrent(),
|
||||
this->set_point.getCurrent());
|
||||
this->NotifyAndRefreshUI(screen_text);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Menu::SetState (p_state new_state)
|
||||
{
|
||||
(this->*current) (MenuObjEvent (MenuObjEvent::eUnFocus));
|
||||
current = new_state;
|
||||
(this->*current) (MenuObjEvent (MenuObjEvent::eFocus));
|
||||
}
|
||||
|
||||
void Menu::HandleObj (const MenuObjEvent &event)
|
||||
{
|
||||
(this->*current) (event);
|
||||
}
|
||||
|
||||
void Menu::NotifyAndRefreshUI (const char *str)
|
||||
{
|
||||
//Send string on a queue to UI task.
|
||||
UserInterface::InterfaceWithData ud = {UserInterface::LCD1, str};
|
||||
this->_qm->send<UserInterface::InterfaceWithData>(
|
||||
ThreadCommon::QueueManager::ui_event_manager, &ud, portMAX_DELAY);
|
||||
}
|
||||
44
source/shoh/src/threads/manager/Menu.h
Normal file
44
source/shoh/src/threads/manager/Menu.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Menu.h
|
||||
*
|
||||
* Created on: 29 Apr 2023
|
||||
* Author: dave
|
||||
*/
|
||||
|
||||
#ifndef THREADS_MANAGER_MENU_H_
|
||||
#define THREADS_MANAGER_MENU_H_
|
||||
|
||||
#include "Counter.h"
|
||||
#include "MenuObjEvent.h"
|
||||
#include "ThreadCommon.h"
|
||||
#include "Event.h"
|
||||
|
||||
class Menu;
|
||||
typedef void (Menu::*p_state) (const MenuObjEvent &);
|
||||
|
||||
class Menu
|
||||
{
|
||||
public:
|
||||
Menu (ThreadCommon::QueueManager* qm);
|
||||
virtual ~Menu ();
|
||||
void HandleEventPair (Event::EventPair *ep);
|
||||
|
||||
private:
|
||||
/* Variables and objects */
|
||||
ThreadCommon::QueueManager* _qm;
|
||||
p_state current;
|
||||
Counter<EventRawData> ext_temp;
|
||||
Counter<EventRawData> set_point;
|
||||
const char main_text[64];
|
||||
const char set_point_text[64];
|
||||
/* States */
|
||||
void sInitView(const MenuObjEvent &e);
|
||||
void sMainView(const MenuObjEvent &e);
|
||||
void sSetPointMod(const MenuObjEvent &e);
|
||||
/* Methods */
|
||||
void SetState (p_state new_state);
|
||||
void HandleObj (const MenuObjEvent &event);
|
||||
void NotifyAndRefreshUI (const char *str);
|
||||
};
|
||||
|
||||
#endif /* THREADS_MANAGER_MENU_H_ */
|
||||
37
source/shoh/src/threads/manager/MenuObjEvent.h
Normal file
37
source/shoh/src/threads/manager/MenuObjEvent.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* MenuObjEvent.h
|
||||
*
|
||||
* Created on: Dec 11, 2022
|
||||
* Author: tylen
|
||||
*/
|
||||
|
||||
#ifndef MENU_MENUOBJEVENT_H_
|
||||
#define MENU_MENUOBJEVENT_H_
|
||||
|
||||
class MenuObjEvent
|
||||
{
|
||||
public:
|
||||
virtual ~MenuObjEvent (){};
|
||||
|
||||
enum EventType
|
||||
{
|
||||
/** Start of the event */
|
||||
eFocus,
|
||||
/** End of the event*/
|
||||
eUnFocus,
|
||||
/** Refresh event */
|
||||
eRefresh,
|
||||
/** Button toggle event type */
|
||||
eClick,
|
||||
/** Rotary clockwise */
|
||||
eRollClockWise,
|
||||
/** Rotary counter clockwise */
|
||||
eRollCClockWise,
|
||||
};
|
||||
MenuObjEvent (EventType e = eFocus) : type (e){};
|
||||
EventType type;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* MENU_MENUOBJEVENT_H_ */
|
||||
@ -16,24 +16,29 @@ void Master::taskFunction() {
|
||||
Event data(Event::Null, 0);
|
||||
bool LedState = true;
|
||||
for (;;) {
|
||||
_qm->receive<Event>(ThreadCommon::QueueManager::master_event_all, &data, portMAX_DELAY);
|
||||
if(!_qm->receive<Event>(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<Event>(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<Event>(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<Event>(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<Event>(ThreadCommon::QueueManager::manager_event_master, &data, 0);
|
||||
break;
|
||||
}
|
||||
LedState = !LedState;
|
||||
@ -41,7 +46,7 @@ void Master::taskFunction() {
|
||||
}
|
||||
|
||||
|
||||
void master_thread(void* pvParams) {
|
||||
void thread_master(void* pvParams) {
|
||||
Master m(static_cast<ThreadCommon::QueueManager*>(pvParams));
|
||||
m.taskFunction();
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ private:
|
||||
ThreadCommon::QueueManager* _qm;
|
||||
};
|
||||
|
||||
void master_thread(void* pvParams);
|
||||
void thread_master(void* pvParams);
|
||||
|
||||
|
||||
#endif /* THREADS_MASTER_MASTER_H_ */
|
||||
|
||||
@ -64,7 +64,7 @@ void Rotary::taskFunction()
|
||||
}
|
||||
}
|
||||
|
||||
void rotary_thread(void* pvParams)
|
||||
void thread_rotary(void* pvParams)
|
||||
{
|
||||
// Special case for ISR
|
||||
QueueHandle_t rotary_isr_q = xQueueCreate(15, sizeof(char));
|
||||
|
||||
@ -25,6 +25,6 @@ private:
|
||||
{ 1, 8, true, false, false, true, PIN_INT2_IRQn} };
|
||||
};
|
||||
|
||||
void rotary_thread(void* pvParams);
|
||||
void thread_rotary(void* pvParams);
|
||||
|
||||
#endif /* THREADS_ROTARY_ROTARY_H_ */
|
||||
|
||||
97
source/shoh/src/threads/user_interface/UserInterface.cpp
Normal file
97
source/shoh/src/threads/user_interface/UserInterface.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* UserInterface.cpp
|
||||
*
|
||||
* Created on: 8 May 2023
|
||||
*/
|
||||
|
||||
#include "UserInterface.h"
|
||||
#include <cstring>
|
||||
|
||||
UserInterface::UserInterface(ThreadCommon::QueueManager* qm) :
|
||||
_qm(qm), lcd1(nullptr)
|
||||
{
|
||||
this->initLCD1();
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
InterfaceWithData ui_with_data;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
this->_qm->receive<UserInterface::InterfaceWithData>(ThreadCommon::QueueManager::ui_event_manager, &ui_with_data, portMAX_DELAY);
|
||||
this->handleEvent(&ui_with_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.\n");
|
||||
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::initLCD1()
|
||||
{
|
||||
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);
|
||||
|
||||
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.
|
||||
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.
|
||||
this->lcd1->begin(16, 2);
|
||||
this->lcd1->setCursor (0, 0);
|
||||
}
|
||||
|
||||
void thread_user_interface(void* pvParams)
|
||||
{
|
||||
UserInterface ui(static_cast<ThreadCommon::QueueManager*>(pvParams));
|
||||
ui.taskFunction();
|
||||
}
|
||||
52
source/shoh/src/threads/user_interface/UserInterface.h
Normal file
52
source/shoh/src/threads/user_interface/UserInterface.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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
|
||||
{
|
||||
const char* str;
|
||||
};
|
||||
|
||||
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 initLCD1();
|
||||
};
|
||||
|
||||
void thread_user_interface(void* pvParams);
|
||||
|
||||
#endif /* THREADS_USER_INTERFACE_USERINTERFACE_H_ */
|
||||
Loading…
x
Reference in New Issue
Block a user