diff --git a/app/system/CMakeLists.txt b/app/system/CMakeLists.txt index 97e38ce053b2e93b795d794f7c4f74253ed76a31..a9d33bffbd20a1533e2d3fd92e5541b25f7d3f4f 100644 --- a/app/system/CMakeLists.txt +++ b/app/system/CMakeLists.txt @@ -19,4 +19,11 @@ DOSEK_BINARY( LIBS libtest timing TEST_ISO test_context_save.cc +) +DOSEK_BINARY( + NAME test_interrupt + SYSTEM_DESC test_interrupt.oil + LIBS libtest timing + TEST_ISO + test_interrupt.cc ) \ No newline at end of file diff --git a/app/system/test_dispatch_complex.cc b/app/system/test_dispatch_complex.cc index 6495fec2583c8045f1b39729295f755fc93f8e7d..77753aeacf207038c481659ec5da0785d8ac23a7 100644 --- a/app/system/test_dispatch_complex.cc +++ b/app/system/test_dispatch_complex.cc @@ -18,21 +18,30 @@ DeclareTask(T2); DeclareTask(T3); DeclareEvent(E1); +DeclareEvent(E2); TEST_MAKE_OS_MAIN(StartOS(0)); TASK(T1) { ActivateTask(T3); + for (int i = 0; i < 5; i++) { + kout << "T1 triggers E2" << endl; + SetEvent(T2, E2); + } + kout << "T1 finished execution" << endl; TerminateTask(); } TASK(T2) { for (int i = 0; i < 5; i++) { - kout << "T2 triggers E1 " << endl; + kout << "T2 triggers E1" << endl; + WaitEvent(E2); + ClearEvent(E2); SetEvent(T3, E1); } + kout << "T2 finished execution" << endl; TerminateTask(); } @@ -46,6 +55,7 @@ TASK(T3) { WaitEvent(E1); ClearEvent(E1); } + kout << "T3 finished execution" << endl; TerminateTask(); } diff --git a/app/system/test_dispatch_complex.oil b/app/system/test_dispatch_complex.oil index 575f29b8c5f7a6f09ba494f0f226f919d4a6241c..8416777451a8d4dfc31951826a5a8d68d86801be 100644 --- a/app/system/test_dispatch_complex.oil +++ b/app/system/test_dispatch_complex.oil @@ -20,6 +20,7 @@ CPU TestSystem { PRIORITY = 2; ACTIVATION = 1; AUTOSTART = FALSE; + EVENT = E2; }; TASK T3 { @@ -34,5 +35,9 @@ CPU TestSystem { MASK = AUTO; }; + EVENT E2 { + MASK = AUTO; + }; + }; diff --git a/app/system/test_interrupt.cc b/app/system/test_interrupt.cc new file mode 100644 index 0000000000000000000000000000000000000000..ec4ce23d7c8d72c3d3da50aaaa4d3dda57e3c02d --- /dev/null +++ b/app/system/test_interrupt.cc @@ -0,0 +1,76 @@ +/** + * @defgroup apps Applications + * @brief The applications... + */ + +/** + * @file + * @ingroup apps + * @brief Just a simple test application + */ +#include <arch/armv7/gpio.h> +#include <arch/armv7/syscall.h> +#include "os.h" +#include "test/test.h" +#include "machine.h" +#include "os/timing.h" + +DeclareTask(T1); +DeclareTask(T2); + +DeclareEvent(E1); + +TEST_MAKE_OS_MAIN(StartOS(0)); + + +volatile int val1; +volatile int val2; + +#define PORT0_BASE 0x48028100UL + +GPIO_Port gpioPort; + +int button_count = 0; + +extern "C" void configure_gpio_irq() { + // enable irqs on button 2 of the xmc4500 board + gpioPort.init(reinterpret_cast<void *>(PORT0_BASE), 15, true); + gpioPort.enable_input_irq(15); +} + +TASK(T1) { + arch::syscall(configure_gpio_irq); + kout << "GPIO init successfull" << endl; + + ActivateTask(T2); + while (true) { + WaitEvent(E1); + ClearEvent(E1); + kout << "Event processed: " << ++button_count << endl; + } + + + TerminateTask(); + +} + + +ISR2(ISR1) { + kout << "isr running" << endl; + SetEvent(T1, E1); +} + + +TASK(T2) { + while (true) { + + } + TerminateTask(); +} + + +void PreIdleHook() { + /* Dump and Shutdown */ + timing_dump(); + ShutdownMachine(); +} diff --git a/app/system/test_interrupt.oil b/app/system/test_interrupt.oil new file mode 100644 index 0000000000000000000000000000000000000000..41f19e762fef3b9871e0bd990ae81986a650e7fc --- /dev/null +++ b/app/system/test_interrupt.oil @@ -0,0 +1,36 @@ +CPU TestSystem { + OS TestSystem { + STATUS = STANDARD; + ERRORHOOK = FALSE; + STARTUPHOOK = FALSE; + SHUTDOWNHOOK = FALSE; + PRETASKHOOK = FALSE; + POSTTASKHOOK = FALSE; + }; + + TASK T1 { + SCHEDULE = FULL; + PRIORITY = 4; + ACTIVATION = 1; + AUTOSTART = TRUE; + EVENT = E1; + }; + + TASK T2 { + SCHEDULE = FULL; + PRIORITY = 3; + ACTIVATION = 1; + AUTOSTART = FALSE; + }; + + ISR ISR1 { + CATEGORY = 2; + DEVICE = 5; + PRIORITY = 1337; + }; + + EVENT E1 { + MASK = AUTO; + }; +}; + diff --git a/arch/armv7/dispatch.cc b/arch/armv7/dispatch.cc index 5513394cba270567354f507b76a10ba703408456..23e12381b44eab2ea0f0d0e8bc01cdde91deb349 100644 --- a/arch/armv7/dispatch.cc +++ b/arch/armv7/dispatch.cc @@ -33,7 +33,7 @@ namespace arch { // save context asm volatile ( "mrs r0, msp \n" // store the msp in r0 - "mrs r1, psp \n" // store the psp in r0 + "mrs r1, psp \n" // store the psp in r1 "cmp r1, #0 \n" // check if the psp is 0 "itt ne \n" // next 2 lines are conditional executed "mrsne r12, psp \n" // move program stack pointer to r12 diff --git a/arch/armv7/gpio.h b/arch/armv7/gpio.h index b075d9fb4a3aaca8bec4e496164430566d34e8a9..9758d7755443a1570f5477b555015f14829f5cde 100644 --- a/arch/armv7/gpio.h +++ b/arch/armv7/gpio.h @@ -8,11 +8,17 @@ #include <stdint.h> class GPIO_Port { + void* m_port; +public: + void init(void *port, uint8_t pin, bool input); - virtual void init(uint8_t pin) = 0; - virtual void setHigh(uint8_t pin)= 0; - virtual void setLow(uint8_t pin)= 0; - virtual void toggle(uint8_t pin)= 0; + void setHigh(uint8_t pin); + + void setLow(uint8_t pin); + + void toggle(uint8_t pin); + + void enable_input_irq(uint8_t pin); }; diff --git a/arch/armv7/platforms/xmc4500/CMakeLists.txt b/arch/armv7/platforms/xmc4500/CMakeLists.txt index 9a8823a37180a156db2c6913034fc851980f4320..c46a520be1450913b8bf114fa09e9f5ff4927a01 100644 --- a/arch/armv7/platforms/xmc4500/CMakeLists.txt +++ b/arch/armv7/platforms/xmc4500/CMakeLists.txt @@ -43,6 +43,8 @@ set(SRCS ${SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/gpio_xmc4500.cc ${CMAKE_CURRENT_SOURCE_DIR}/libs/CMSIS/Infineon/XMC4500_series/Source/system_XMC4500.c ${CMAKE_CURRENT_SOURCE_DIR}/libs/XMCLib/src/xmc4_gpio.c + ${CMAKE_CURRENT_SOURCE_DIR}/libs/XMCLib/src/xmc4_eru.c + ${CMAKE_CURRENT_SOURCE_DIR}/libs/XMCLib/src/xmc_eru.c ${CMAKE_CURRENT_SOURCE_DIR}/libs/XMCLib/src/xmc4_scu.c ${CMAKE_CURRENT_SOURCE_DIR}/libs/XMCLib/src/xmc_usbd.c ${LIB_USB_CDC} diff --git a/arch/armv7/platforms/xmc4500/boot.cc b/arch/armv7/platforms/xmc4500/boot.cc index fd32487286fca997714b51d1770d58eab1664b65..cd1a55fb4535650d9a1bd79c77308be25bf62092 100644 --- a/arch/armv7/platforms/xmc4500/boot.cc +++ b/arch/armv7/platforms/xmc4500/boot.cc @@ -1,5 +1,5 @@ #include <arch/arm/output.h> -#include <arch/armv7/platforms/xmc4500/gpio_xmc4500.h> +#include <arch/armv7/gpio.h> #include <arch/armv7/machine.h> #include "XMC4500.h" #include "stddef.h" diff --git a/arch/armv7/platforms/xmc4500/gpio_xmc4500.cc b/arch/armv7/platforms/xmc4500/gpio_xmc4500.cc index c8b86b846e3429423cac3274c51821c85b2e291d..2d6020f02be3fb1cb3d9ca77b5e2e4da9df64f59 100644 --- a/arch/armv7/platforms/xmc4500/gpio_xmc4500.cc +++ b/arch/armv7/platforms/xmc4500/gpio_xmc4500.cc @@ -2,60 +2,106 @@ // Created by fabian on 05.01.18. // -#include "gpio_xmc4500.h" +#include <platform.h> +#include <arch/armv7/output.h> +#include <arch/armv7/gpio.h> +#include <arch/armv7/platforms/xmc4500/libs/XMCLib/inc/xmc_gpio.h> +#include <arch/armv7/platforms/xmc4500/libs/XMCLib/inc/xmc4_gpio.h> +#include <arch/armv7/platforms/xmc4500/libs/XMCLib/inc/xmc_eru.h> #define PORT_IOCR_PC_Size (8U) #define PORT_PDR_Size (4U) -XMC4500_GPIO_Port::XMC4500_GPIO_Port(XMC_GPIO_PORT_t *const port) : m_port(port) { +#define PORT (static_cast<XMC_GPIO_PORT_t *const>(this->m_port)) -} - -void XMC4500_GPIO_Port::init(uint8_t pin) { - - /* Switch to input */ - this->m_port->IOCR[pin >> 2U] &= (uint32_t) ~(PORT0_IOCR0_PC0_Msk << (PORT_IOCR_PC_Size * (pin & 0x3U))); - - /* HW port control is disabled */ - this->m_port->HWSEL &= ~(uint32_t) ((uint32_t) PORT0_HWSEL_HW0_Msk << ((uint32_t) pin << 1U)); +XMC_GPIO_MODE_t m_outputMode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL; +XMC_GPIO_OUTPUT_STRENGTH_t m_outputStrength = XMC_GPIO_OUTPUT_STRENGTH_STRONG_SHARP_EDGE; +void GPIO_Port::init(void *port, uint8_t pin, bool input) { + this->m_port = port; + if (!input) { + /* Switch to input */ + PORT->IOCR[pin >> 2U] &= (uint32_t) ~(PORT0_IOCR0_PC0_Msk << (PORT_IOCR_PC_Size * (pin & 0x3U))); + /* HW port control is disabled */ + PORT->HWSEL &= ~(uint32_t) ((uint32_t) PORT0_HWSEL_HW0_Msk << ((uint32_t) pin << 1U)); - /* Set output level */ - this->m_port->OMR = (uint32_t) XMC_GPIO_OUTPUT_LEVEL_LOW << pin; - /* Set output driver strength */ - this->m_port->PDR[pin >> 3U] &= (uint32_t) ~(PORT0_PDR0_PD0_Msk - << ((uint32_t) PORT_PDR_Size * ((uint32_t) pin & 0x7U))); - this->m_port->PDR[pin >> 3U] |= - (uint32_t) this->m_outputStrength << ((uint32_t) PORT_PDR_Size * ((uint32_t) pin & 0x7U)); + /* Set output level */ + PORT->OMR = (uint32_t) XMC_GPIO_OUTPUT_LEVEL_LOW << pin; + /* Set output driver strength */ + PORT->PDR[pin >> 3U] &= (uint32_t) ~(PORT0_PDR0_PD0_Msk + << ((uint32_t) PORT_PDR_Size * ((uint32_t) pin & 0x7U))); + PORT->PDR[pin >> 3U] |= + (uint32_t) m_outputStrength << ((uint32_t) PORT_PDR_Size * ((uint32_t) pin & 0x7U)); - /* Set mode */ - this->m_port->IOCR[pin >> 2U] |= - (uint32_t) this->m_outputMode << ((uint32_t) PORT_IOCR_PC_Size * ((uint32_t) pin & 0x3U)); + /* Set mode */ + PORT->IOCR[pin >> 2U] |= + (uint32_t) m_outputMode << ((uint32_t) PORT_IOCR_PC_Size * ((uint32_t) pin & 0x3U)); + } } -void XMC4500_GPIO_Port::setOuput(uint8_t pin, XMC_GPIO_OUTPUT_LEVEL_t level) { - this->m_port->OMR = (uint32_t) level << pin; +void GPIO_Port::setHigh(uint8_t pin) { + PORT->OMR = (uint32_t) XMC_GPIO_OUTPUT_LEVEL_HIGH << pin; } -void XMC4500_GPIO_Port::setHigh(uint8_t pin) { - setOuput(pin, XMC_GPIO_OUTPUT_LEVEL_HIGH); +void GPIO_Port::setLow(uint8_t pin) { + PORT->OMR = (uint32_t) XMC_GPIO_OUTPUT_LEVEL_LOW << pin; } -void XMC4500_GPIO_Port::setLow(uint8_t pin) { - setOuput(pin, XMC_GPIO_OUTPUT_LEVEL_LOW); +void GPIO_Port::toggle(uint8_t pin) { + PORT->OMR = 0x10001U << pin; } -void XMC4500_GPIO_Port::toggle(uint8_t pin) { - this->m_port->OMR = 0x10001U << pin; +void GPIO_Port::enable_input_irq(uint8_t pin) { + + if (this->m_port == reinterpret_cast<XMC_GPIO_PORT_t *const>(PORT1_BASE)) { + // Ereignis-Quelle konfigurieren + XMC_ERU_ETL_CONFIG_t eruInit; + // Initialisierungsstruktur aufräumen + memset(&eruInit, 0, sizeof(XMC_ERU_ETL_CONFIG_t)); + + // Eingabekanal und PIN laut Matrix festlegen + if(pin == 15) { + eruInit.input_a = ERU1_ETL1_INPUTA_P1_15; + }else{ + kout << "i don't know how to enable interrupts on this pin" << endl; + } + + // Triggerlogik festlegen + eruInit.edge_detection = XMC_ERU_ETL_EDGE_DETECTION_FALLING; + // Triggerausgabe erlauben + eruInit.enable_output_trigger = true; + // Triggerausgabe-Ziel festlegen + eruInit.output_trigger_channel = XMC_ERU_ETL_OUTPUT_TRIGGER_CHANNEL0; + + // Ereignis Ziel konfigurieren + XMC_ERU_OGU_CONFIG_t oguInit; + // Initialisierungsstruktur aufräumen + memset(&oguInit, 0, sizeof(XMC_ERU_OGU_CONFIG_t)); + // Interrupt erlauben + oguInit.service_request = true; + + // ERU Eingangsseite Konfigurieren + XMC_ERU_ETL_Init(ERU1_ETL1, &eruInit); + // ERU Ausgangsseite Konfigurieren + XMC_ERU_OGU_Init(ERU1_OGU0, &oguInit); + + NVIC_SetPriority(ERU1_0_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 63, 0)); + + NVIC_EnableIRQ(ERU1_0_IRQn); + + PORT1_BASE; + } else { + kout << "i don't know how to enable this interrupt" << endl; + } } // //XMC4500_GPIO_Port GPIO_PORT0((XMC_GPIO_PORT_t *) PORT0_BASE); -XMC4500_GPIO_Port GPIO_PORT1((XMC_GPIO_PORT_t *) PORT1_BASE); +// GPIO_Port GPIO_PORT1; //XMC4500_GPIO_Port GPIO_PORT2((XMC_GPIO_PORT_t *) PORT2_BASE); //XMC4500_GPIO_Port GPIO_PORT3((XMC_GPIO_PORT_t *) PORT3_BASE); //XMC4500_GPIO_Port GPIO_PORT4((XMC_GPIO_PORT_t *) PORT4_BASE); diff --git a/arch/armv7/platforms/xmc4500/gpio_xmc4500.h b/arch/armv7/platforms/xmc4500/gpio_xmc4500.h deleted file mode 100644 index fe65c91aa0b01ee8d392017086cc7a5b4a3bcba7..0000000000000000000000000000000000000000 --- a/arch/armv7/platforms/xmc4500/gpio_xmc4500.h +++ /dev/null @@ -1,42 +0,0 @@ -// -// Created by fabian on 05.01.18. -// - -#ifndef DOSEK_GPIO_XMC4500_H -#define DOSEK_GPIO_XMC4500_H - -#include <platform.h> -#include <xmc_common.h> -#include <xmc_gpio.h> -#include <arch/armv7/gpio.h> - -class XMC4500_GPIO_Port : public GPIO_Port { -private: - XMC_GPIO_MODE_t m_outputMode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL; - XMC_GPIO_OUTPUT_STRENGTH_t m_outputStrength = XMC_GPIO_OUTPUT_STRENGTH_STRONG_SHARP_EDGE; - - XMC_GPIO_PORT_t *const m_port; - void setOuput(uint8_t pin, XMC_GPIO_OUTPUT_LEVEL_t level); - -public: - explicit XMC4500_GPIO_Port(XMC_GPIO_PORT_t *const m_port); - - void init(uint8_t pin) override; - - void setHigh(uint8_t pin) override; - - void setLow(uint8_t pin) override; - - void toggle(uint8_t pin) override; - -}; -// -//extern XMC4500_GPIO_Port GPIO_PORT0; -extern XMC4500_GPIO_Port GPIO_PORT1; -//extern XMC4500_GPIO_Port GPIO_PORT2; -//extern XMC4500_GPIO_Port GPIO_PORT3; -//extern XMC4500_GPIO_Port GPIO_PORT4; -//extern XMC4500_GPIO_Port GPIO_PORT5; -//extern XMC4500_GPIO_Port GPIO_PORT6; - -#endif //DOSEK_GPIO_H_H diff --git a/arch/armv7/platforms/xmc4500/machine_impl.cc b/arch/armv7/platforms/xmc4500/machine_impl.cc index 1a2396c7e578488818422a83a3354b9076f225f6..939f82e1f3a52b8cb702b2b5778cc53d457e4f43 100644 --- a/arch/armv7/platforms/xmc4500/machine_impl.cc +++ b/arch/armv7/platforms/xmc4500/machine_impl.cc @@ -3,19 +3,10 @@ #include "nvic.h" #include "machine.h" -#include "gpio_xmc4500.h" void Machine::reset(void) { kout << "Reset called" << endl; - - // Flash light before reset - GPIO_PORT1.init(0); - GPIO_PORT1.setHigh(0); - for(volatile int i = 0; i < 1000000; ++i); - GPIO_PORT1.setLow(0); - for(volatile int i = 0; i < 1000000; ++i); - NVIC_SystemReset(); }