diff --git a/source/shoh/.cproject b/source/shoh/.cproject
index aa180f6..c20b11d 100644
--- a/source/shoh/.cproject
+++ b/source/shoh/.cproject
@@ -50,6 +50,7 @@
+
@@ -303,31 +304,31 @@
- <?xml version="1.0" encoding="UTF-8"?>
-<TargetConfig>
-<Properties property_2="LPC11U6x_256K.cfx" property_3="NXP" property_4="LPC11U68" property_count="5" version="100300"/>
-<infoList vendor="NXP">
-<info chip="LPC11U68" flash_driver="LPC11U6x_256K.cfx" match_id="0x0" name="LPC11U68" stub="crt_emu_cm3_gen">
-<chip>
-<name>LPC11U68</name>
-<family>LPC11U6x</family>
-<vendor>NXP (formerly Philips)</vendor>
-<reset board="None" core="Real" sys="Real"/>
-<clock changeable="TRUE" freq="12MHz" is_accurate="TRUE"/>
-<memory can_program="true" id="Flash" is_ro="true" type="Flash"/>
-<memory id="RAM" type="RAM"/>
-<memory id="Periph" is_volatile="true" type="Peripheral"/>
-<memoryInstance derived_from="Flash" id="MFlash256" location="0x0" size="0x40000"/>
-<memoryInstance derived_from="RAM" id="Ram0_32" location="0x10000000" size="0x8000"/>
-<memoryInstance derived_from="RAM" id="Ram1_2" location="0x20000000" size="0x800"/>
-<memoryInstance derived_from="RAM" id="Ram2USB_2" location="0x20004000" size="0x800"/>
-</chip>
-<processor>
-<name gcc_name="cortex-m0">Cortex-M0</name>
-<family>Cortex-M</family>
-</processor>
-</info>
-</infoList>
+ <?xml version="1.0" encoding="UTF-8"?>
+<TargetConfig>
+<Properties property_2="LPC11U6x_256K.cfx" property_3="NXP" property_4="LPC11U68" property_count="5" version="100300"/>
+<infoList vendor="NXP">
+<info chip="LPC11U68" flash_driver="LPC11U6x_256K.cfx" match_id="0x0" name="LPC11U68" stub="crt_emu_cm3_gen">
+<chip>
+<name>LPC11U68</name>
+<family>LPC11U6x</family>
+<vendor>NXP (formerly Philips)</vendor>
+<reset board="None" core="Real" sys="Real"/>
+<clock changeable="TRUE" freq="12MHz" is_accurate="TRUE"/>
+<memory can_program="true" id="Flash" is_ro="true" type="Flash"/>
+<memory id="RAM" type="RAM"/>
+<memory id="Periph" is_volatile="true" type="Peripheral"/>
+<memoryInstance derived_from="Flash" id="MFlash256" location="0x0" size="0x40000"/>
+<memoryInstance derived_from="RAM" id="Ram0_32" location="0x10000000" size="0x8000"/>
+<memoryInstance derived_from="RAM" id="Ram1_2" location="0x20000000" size="0x800"/>
+<memoryInstance derived_from="RAM" id="Ram2USB_2" location="0x20004000" size="0x800"/>
+</chip>
+<processor>
+<name gcc_name="cortex-m0">Cortex-M0</name>
+<family>Cortex-M</family>
+</processor>
+</info>
+</infoList>
</TargetConfig>
diff --git a/source/shoh/src/main.cpp b/source/shoh/src/main.cpp
index bf1f949..91d24cd 100644
--- a/source/shoh/src/main.cpp
+++ b/source/shoh/src/main.cpp
@@ -5,6 +5,7 @@
#include
#include "ThreadCommon.h"
#include "Master.h"
+#include "Rotary.h"
int main(void)
@@ -17,20 +18,15 @@ int main(void)
qmanager->createQueue(100,
sizeof(Event),
ThreadCommon::QueueManager::master_event_all);
-
//Creating tasks
manager->createTask(master_thread, "master",
- configMINIMAL_STACK_SIZE * 10,tskIDLE_PRIORITY + 1UL,
- static_cast(qmanager));
+ configMINIMAL_STACK_SIZE * 10,tskIDLE_PRIORITY + 1UL,
+ static_cast(qmanager));
+ manager->createTask(rotary_thread, "rotary",
+ configMINIMAL_STACK_SIZE * 10,tskIDLE_PRIORITY + 1UL,
+ static_cast(qmanager));
- //
- Event* e = new Event(Event::Rotary, 1);
-
- qmanager->send(ThreadCommon::QueueManager::master_event_all, e, 1000);
- //
-
// Start the real time kernel with preemption.
- //FreeRTOS::Kernel::startScheduler();
vTaskStartScheduler ();
return 1;
diff --git a/source/shoh/src/peripherals/DigitalIoPin.cpp b/source/shoh/src/peripherals/DigitalIoPin.cpp
index 8255644..51d4021 100644
--- a/source/shoh/src/peripherals/DigitalIoPin.cpp
+++ b/source/shoh/src/peripherals/DigitalIoPin.cpp
@@ -8,7 +8,7 @@
#include "DigitalIoPin.h"
DigitalIoPin::DigitalIoPin (int port, int pin, bool input, bool pullup,
- bool invert)
+ bool invert, bool isr, IRQn_Type isr_index)
{
assert ((port <= UINT8_MAX_VALUE) && (pin <= UINT8_MAX_VALUE));
_io._port = (uint8_t)port;
@@ -18,7 +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;
- setIoPin ();
+ if (isr){
+ _io.isr_i = isr_index;
+ setIsr();
+ } else {
+ setIoPin ();
+ }
}
DigitalIoPin::~DigitalIoPin ()
@@ -48,6 +53,52 @@ DigitalIoPin::setIoPin ()
Chip_GPIO_SetPinDIR (LPC_GPIO, _io._port, _io._pin, direction);
}
+void
+DigitalIoPin::setIsr ()
+{
+ bool direction = true;
+ if (_io._input)
+ {
+ direction = false;
+ _io.IOCON_mode = IOCON_MODE_PULLUP;
+ if (!_io._pullup)
+ {
+ _io.IOCON_mode = IOCON_MODE_PULLDOWN;
+ }
+ if (_io._invert)
+ {
+ _io.IOCON_inv = IOCON_INV_EN;
+ }
+ }
+ /* We'll use an optional IOCON filter (0) with a divider of 64 for the
+ input pin to be used for PININT */
+ 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)));
+ /** False direction equals input */
+ Chip_GPIO_SetPinDIR (LPC_GPIO, _io._port, _io._pin, direction);
+
+ /* Enable PININT clock if it was not enabled before */
+ if ((LPC_SYSCTL->SYSAHBCLKCTRL & (1 << SYSCTL_CLOCK_PINT)) == 0)
+ {
+ Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_PINT);
+ }
+ /* Configure interrupt channel for the GPIO pin in SysCon block */
+ Chip_SYSCTL_SetPinInterrupt(_io.isr_i, _io._port, _io._pin);
+
+ /* Configure channel interrupt as edge sensitive and falling edge interrupt */
+ Chip_PININT_ClearIntStatus(LPC_PININT, PININTCH(_io.isr_i));
+ Chip_PININT_SetPinModeEdge(LPC_PININT, PININTCH(_io.isr_i));
+ Chip_PININT_EnableIntLow(LPC_PININT, PININTCH(_io.isr_i));
+
+ /* Enable interrupt in the NVIC */
+ NVIC_ClearPendingIRQ(_io.isr_i);
+ NVIC_EnableIRQ(_io.isr_i);
+}
+
bool
DigitalIoPin::read ()
{
diff --git a/source/shoh/src/peripherals/DigitalIoPin.h b/source/shoh/src/peripherals/DigitalIoPin.h
index de004af..19c6c7b 100644
--- a/source/shoh/src/peripherals/DigitalIoPin.h
+++ b/source/shoh/src/peripherals/DigitalIoPin.h
@@ -23,13 +23,14 @@ typedef struct DigitalIOConfigStruct
uint32_t IOCON_mode;
uint32_t IOCON_inv;
uint32_t DigitalEn;
+ IRQn_Type isr_i;
} DigitalIOConfigStruct;
class DigitalIoPin
{
public:
DigitalIoPin (int port, int pin, bool input = true, bool pullup = true,
- bool invert = false);
+ bool invert = false, bool isr = false, IRQn_Type isr_index = PIN_INT0_IRQn);
DigitalIoPin (const DigitalIoPin &) = delete;
virtual ~DigitalIoPin ();
bool read ();
@@ -38,6 +39,7 @@ public:
private:
DigitalIOConfigStruct _io = { 0, 0, false, false, false, 0, 0, IOCON_DIGMODE_EN};
void setIoPin ();
+ void setIsr();
};
#endif /* DIGITALIOPIN_H_ */
diff --git a/source/shoh/src/threads/common/Event.h b/source/shoh/src/threads/common/Event.h
index 30c9dea..5577b00 100644
--- a/source/shoh/src/threads/common/Event.h
+++ b/source/shoh/src/threads/common/Event.h
@@ -47,6 +47,11 @@ public:
return pos->second;
}
+ void inline setDataOf(Event::EventType e, EventRawData data)
+ {
+ events[e] = data;
+ }
+
private:
std::map events;
};
diff --git a/source/shoh/src/threads/common/ThreadCommon.h b/source/shoh/src/threads/common/ThreadCommon.h
index 73a5b72..2e6040b 100644
--- a/source/shoh/src/threads/common/ThreadCommon.h
+++ b/source/shoh/src/threads/common/ThreadCommon.h
@@ -18,6 +18,13 @@
namespace ThreadCommon
{
+ enum RotaryAction
+ {
+ Right,
+ Left,
+ Press,
+ Idle
+ };
class ThreadManager
{
public:
diff --git a/source/shoh/src/threads/master/Master.cpp b/source/shoh/src/threads/master/Master.cpp
index 34f86d9..2a7e094 100644
--- a/source/shoh/src/threads/master/Master.cpp
+++ b/source/shoh/src/threads/master/Master.cpp
@@ -14,13 +14,25 @@ Master::Master(ThreadCommon::QueueManager* qm) : _qm(qm)
void Master::taskFunction() {
Event data(Event::Null, 0);
- int led = 0;
bool LedState = true;
for (;;) {
_qm->receive(ThreadCommon::QueueManager::master_event_all, &data, portMAX_DELAY);
- if(data.getDataOf(Event::Rotary) == 1){
- Board_LED_Set(led, LedState);
+ switch(data.getDataOf(Event::Rotary))
+ {
+ case ThreadCommon::RotaryAction::Right:
+ Board_LED_Set(ThreadCommon::RotaryAction::Right, LedState);
+ break;
+ case ThreadCommon::RotaryAction::Left:
+ Board_LED_Set(ThreadCommon::RotaryAction::Left, LedState);
+ break;
+ case ThreadCommon::RotaryAction::Press:
+ Board_LED_Set(ThreadCommon::RotaryAction::Press, LedState);
+ break;
+ case ThreadCommon::RotaryAction::Idle:
+ Board_LED_Set(ThreadCommon::RotaryAction::Right, LedState);
+ break;
}
+ LedState = !LedState;
}
}
diff --git a/source/shoh/src/threads/master/Master.h b/source/shoh/src/threads/master/Master.h
index aa59969..e5dceae 100644
--- a/source/shoh/src/threads/master/Master.h
+++ b/source/shoh/src/threads/master/Master.h
@@ -21,8 +21,6 @@ public:
virtual ~Master() = default;
void taskFunction();
- //Master(Master&&) noexcept = default;
- //Master& operator=(Master&&) noexcept = default;
private:
Event* message;
ThreadCommon::QueueManager* _qm;
diff --git a/source/shoh/src/threads/rotary/Rotary.cpp b/source/shoh/src/threads/rotary/Rotary.cpp
new file mode 100644
index 0000000..da1d8ed
--- /dev/null
+++ b/source/shoh/src/threads/rotary/Rotary.cpp
@@ -0,0 +1,75 @@
+/*
+ * Rotary.cpp
+ *
+ * Created on: 26 Apr 2023
+ * Author: tylen
+ */
+
+#include "Rotary.h"
+#include "board.h"
+#include "queue.h"
+
+static QueueHandle_t * p_rotary_isr_q;
+
+extern "C"
+{
+ void
+ PIN_INT0_IRQHandler (void)
+ {
+ Chip_PININT_ClearIntStatus (LPC_PININT, PININTCH (PIN_INT0_IRQn));
+ portBASE_TYPE xHigherPriorityWoken = pdFALSE;
+ uint8_t data = ThreadCommon::RotaryAction::Right;
+ xQueueSendFromISR (*p_rotary_isr_q, &data, &xHigherPriorityWoken);
+ portEND_SWITCHING_ISR(xHigherPriorityWoken);
+ }
+
+ void
+ PIN_INT1_IRQHandler (void)
+ {
+ Chip_PININT_ClearIntStatus (LPC_PININT, PININTCH (PIN_INT1_IRQn));
+ portBASE_TYPE xHigherPriorityWoken = pdFALSE;
+ uint8_t data = ThreadCommon::RotaryAction::Left;
+ xQueueSendFromISR (*p_rotary_isr_q, &data, &xHigherPriorityWoken);
+ portEND_SWITCHING_ISR(xHigherPriorityWoken);
+ }
+
+ void
+ PIN_INT2_IRQHandler (void)
+ {
+ Chip_PININT_ClearIntStatus (LPC_PININT, PININTCH (PIN_INT2_IRQn));
+ portBASE_TYPE xHigherPriorityWoken = pdFALSE;
+ uint8_t data = ThreadCommon::RotaryAction::Press;
+ xQueueSendFromISR (*p_rotary_isr_q, &data, &xHigherPriorityWoken);
+ portEND_SWITCHING_ISR(xHigherPriorityWoken);
+ }
+}
+
+Rotary::Rotary(ThreadCommon::QueueManager* qm) : _qm(qm)
+{
+
+}
+
+Rotary::~Rotary() {}
+
+void Rotary::taskFunction()
+{
+ auto action_from_rotary_isr = ThreadCommon::RotaryAction::Idle;
+ Event * p_e= new Event(Event::EventType::Rotary, action_from_rotary_isr);
+
+ for (;;)
+ {
+ xQueueReceive(*p_rotary_isr_q, &action_from_rotary_isr, portMAX_DELAY);
+ p_e->setDataOf(Event::EventType::Rotary, action_from_rotary_isr);
+ _qm->send(ThreadCommon::QueueManager::master_event_all, p_e, 10);
+ }
+}
+
+void rotary_thread(void* pvParams)
+{
+ // Special case for ISR
+ QueueHandle_t rotary_isr_q = xQueueCreate(15, sizeof(char));
+ p_rotary_isr_q = &rotary_isr_q;
+
+ Rotary r(static_cast(pvParams));
+ r.taskFunction();
+}
diff --git a/source/shoh/src/threads/rotary/Rotary.h b/source/shoh/src/threads/rotary/Rotary.h
new file mode 100644
index 0000000..56fdf17
--- /dev/null
+++ b/source/shoh/src/threads/rotary/Rotary.h
@@ -0,0 +1,30 @@
+/*
+ * Rotary.h
+ *
+ * Created on: 26 Apr 2023
+ * Author: tylen
+ */
+
+#ifndef THREADS_ROTARY_ROTARY_H_
+#define THREADS_ROTARY_ROTARY_H_
+
+#include "Event.h"
+#include "ThreadCommon.h"
+#include "DigitalIoPin.h"
+
+class Rotary {
+public:
+ Rotary(ThreadCommon::QueueManager* qm);
+ virtual ~Rotary();
+ void taskFunction();
+private:
+ Event* message;
+ ThreadCommon::QueueManager* _qm;
+ DigitalIoPin signal[3] = { { 0, 1, true, true, false, true, PIN_INT0_IRQn}, //SW1
+ { 0, 16, true, true, false, true, PIN_INT1_IRQn}, //SW2
+ { 1, 8, true, false, false, true, PIN_INT2_IRQn} };
+};
+
+void rotary_thread(void* pvParams);
+
+#endif /* THREADS_ROTARY_ROTARY_H_ */