Import revision 9 from svn
authorEbersold Andre <aebersol@LAPTOP-DEDE.localdomain>
Tue, 21 Dec 2021 18:45:51 +0000 (19:45 +0100)
committerEbersold Andre <aebersol@LAPTOP-DEDE.localdomain>
Tue, 21 Dec 2021 18:45:51 +0000 (19:45 +0100)
113 files changed:
Application/CMakeLists.txt [new file with mode: 0644]
Application/DCMotor/328p_DCMotor.cpp [new file with mode: 0644]
Application/DCMotor/32u4_DCMotor.cpp [new file with mode: 0644]
Application/DCMotor/CMakeLists.txt [new file with mode: 0644]
Application/DCMotor/DCM_InterruptActivity.cpp [new file with mode: 0644]
Application/DCMotor/DCM_InterruptActivity.h [new file with mode: 0644]
Application/DCMotor/DCMotor.cpp [new file with mode: 0644]
Application/DCMotor/DCMotor.h [new file with mode: 0644]
Application/DCMotor/Led0.cpp [new file with mode: 0644]
Application/DCMotor/Led0.h [new file with mode: 0644]
Application/DCMotor/MotorHandler.cpp [new file with mode: 0644]
Application/DCMotor/MotorHandler.h [new file with mode: 0644]
Application/DCMotor/main.cpp [new file with mode: 0644]
Application/ICommandHandler.h [new file with mode: 0644]
Application/ITask.h [new file with mode: 0644]
Application/Led0/CMakeLists.txt [new file with mode: 0644]
Application/Led0/Led0.cpp [new file with mode: 0644]
Application/Led0/Led0.h [new file with mode: 0644]
Application/Led0/main.cpp [new file with mode: 0644]
Application/PowerSwitch/CMakeLists.txt [new file with mode: 0644]
Application/PowerSwitch/Led0.cpp [new file with mode: 0644]
Application/PowerSwitch/Led0.h [new file with mode: 0644]
Application/PowerSwitch/PowerswitchHandler.cpp [new file with mode: 0644]
Application/PowerSwitch/PowerswitchHandler.h [new file with mode: 0644]
Application/PowerSwitch/Switch.cpp [new file with mode: 0644]
Application/PowerSwitch/Switch.h [new file with mode: 0644]
Application/PowerSwitch/main.cpp [new file with mode: 0644]
Application/Scheduler/Scheduler.h [new file with mode: 0644]
Application/ShutterCtrl/CMakeLists.txt [new file with mode: 0644]
Application/ShutterCtrl/Led0.cpp [new file with mode: 0644]
Application/ShutterCtrl/Led0.h [new file with mode: 0644]
Application/ShutterCtrl/ShutterHandler.cpp [new file with mode: 0644]
Application/ShutterCtrl/ShutterHandler.h [new file with mode: 0644]
Application/ShutterCtrl/TouchScrHandler.cpp [new file with mode: 0644]
Application/ShutterCtrl/TouchScrHandler.h [new file with mode: 0644]
Application/ShutterCtrl/main.cpp [new file with mode: 0644]
CMakeLists.txt [new file with mode: 0644]
Communication/CMakeLists.txt [new file with mode: 0644]
Communication/CommunicationHandler.cpp [new file with mode: 0644]
Communication/CommunicationHandler.h [new file with mode: 0644]
Communication/ICommunication.h [new file with mode: 0644]
Communication/ModbusSerial/ModbusSerial.h [new file with mode: 0644]
HAL/AVR/328p_Pwm.cpp [new file with mode: 0644]
HAL/AVR/328p_Timer0.cpp [new file with mode: 0644]
HAL/AVR/32u4_Pwm.cpp [new file with mode: 0644]
HAL/AVR/32u4_Timer0.cpp [new file with mode: 0644]
HAL/AVR/AvrAdc.cpp [new file with mode: 0644]
HAL/AVR/AvrAdc.h [new file with mode: 0644]
HAL/AVR/AvrEeprom.cpp [new file with mode: 0644]
HAL/AVR/AvrEeprom.h [new file with mode: 0644]
HAL/AVR/AvrInterrupt.h [new file with mode: 0644]
HAL/AVR/AvrPwm.cpp [new file with mode: 0644]
HAL/AVR/AvrPwm.h [new file with mode: 0644]
HAL/AVR/AvrSpi.cpp [new file with mode: 0644]
HAL/AVR/AvrSpi.h [new file with mode: 0644]
HAL/AVR/AvrTimer0.cpp [new file with mode: 0644]
HAL/AVR/AvrTimer0.h [new file with mode: 0644]
HAL/AVR/AvrTimer1.cpp [new file with mode: 0644]
HAL/AVR/AvrTimer1.h [new file with mode: 0644]
HAL/AVR/AvrTimer3.cpp [new file with mode: 0644]
HAL/AVR/AvrTimer3.h [new file with mode: 0644]
HAL/AVR/AvrUart.cpp [new file with mode: 0644]
HAL/AVR/AvrUart.h [new file with mode: 0644]
HAL/AVR/CMakeLists.txt [new file with mode: 0644]
HAL/Abstract/IAdc.h [new file with mode: 0644]
HAL/Abstract/IEeprom.h [new file with mode: 0644]
HAL/Abstract/IInterruptActivity.h [new file with mode: 0644]
HAL/Abstract/IIo.h [new file with mode: 0644]
HAL/Abstract/IProtocolLayer2.h [new file with mode: 0644]
HAL/Abstract/IPwm.h [new file with mode: 0644]
HAL/Abstract/ISPI.h [new file with mode: 0644]
HAL/Abstract/ISwitch.h [new file with mode: 0644]
HAL/Abstract/ITimer.h [new file with mode: 0644]
HAL/Abstract/IUart.h [new file with mode: 0644]
HAL/CMakeLists.txt [new file with mode: 0644]
HAL/Drivers/CMakeLists.txt [new file with mode: 0644]
HAL/Drivers/Eeprom.h [new file with mode: 0644]
HAL/Drivers/Ili9341.cpp [new file with mode: 0644]
HAL/Drivers/Ili9341.h [new file with mode: 0644]
HAL/Drivers/NetString.cpp [new file with mode: 0644]
HAL/Drivers/NetString.h [new file with mode: 0644]
HAL/Drivers/Rs485.h [new file with mode: 0644]
HAL/Drivers/XPT2046_Touchscreen.cpp [new file with mode: 0644]
HAL/Drivers/XPT2046_Touchscreen.h [new file with mode: 0644]
HAL/Drivers/glcdfont.c [new file with mode: 0644]
Metadata/CMakeLists.txt [new file with mode: 0644]
Metadata/DCMotorParamIds.h [new file with mode: 0644]
Metadata/DCMotorParameterTable.cpp [new file with mode: 0644]
Metadata/DCMotorParameterTable.h [new file with mode: 0644]
Metadata/Metadata.h [new file with mode: 0644]
Metadata/PowerswitchParamIds.h [new file with mode: 0644]
Metadata/PowerswitchParameterTable.cpp [new file with mode: 0644]
Metadata/PowerswitchParameterTable.h [new file with mode: 0644]
Metadata/ShutterCtrlParamIds.h [new file with mode: 0644]
Metadata/ShutterCtrlParameterTable.cpp [new file with mode: 0644]
Metadata/ShutterCtrlParameterTable.h [new file with mode: 0644]
Platform/CMakeLists.txt [new file with mode: 0644]
Platform/DCMotorParameterHandler.cpp [new file with mode: 0644]
Platform/DCMotorParameterHandler.h [new file with mode: 0644]
Platform/ErrorHandler.h [new file with mode: 0644]
Platform/Errors.h [new file with mode: 0644]
Platform/IErrorHandler.h [new file with mode: 0644]
Platform/IParameterHandler.h [new file with mode: 0644]
Platform/PersistentStorage.cpp [new file with mode: 0644]
Platform/PersistentStorage.h [new file with mode: 0644]
Platform/PowerswitchParameterHandler.cpp [new file with mode: 0644]
Platform/PowerswitchParameterHandler.h [new file with mode: 0644]
Platform/ShutterCtrlParameterHandler.cpp [new file with mode: 0644]
Platform/ShutterCtrlParameterHandler.h [new file with mode: 0644]
README [new file with mode: 0644]
Utils/StdTypes.h [new file with mode: 0644]
rules/gcc-avr-common.cmake [new file with mode: 0644]
rules/gcc-avr-generic.cmake [new file with mode: 0644]

diff --git a/Application/CMakeLists.txt b/Application/CMakeLists.txt
new file mode 100644 (file)
index 0000000..cd6f986
--- /dev/null
@@ -0,0 +1 @@
+subdirs(Led0 DCMotor PowerSwitch ShutterCtrl)
diff --git a/Application/DCMotor/328p_DCMotor.cpp b/Application/DCMotor/328p_DCMotor.cpp
new file mode 100644 (file)
index 0000000..19d897a
--- /dev/null
@@ -0,0 +1,214 @@
+/**
+ * \brief simple application to test the C++ toolchain
+ *
+ * \file main.cc
+ * \author Andre Ebersold
+ */
+
+#include <Utils/StdTypes.h>
+
+
+#include <Platform/IParameterHandler.h>
+#include <Metadata/DCMotorParamIds.h>
+#include "Led0.h"
+
+#include "DCMotor.h"
+#if  defined (__AVR_ATmega32U4__)
+#define PIN_MOTOR_ENABLE PINB2
+#else
+#define PIN_MOTOR_ENABLE PIND2
+#endif
+/**
+ *  \brief 
+ *
+ */
+Motor::Motor(volatile uint8_t *OCR,volatile uint8_t *ttcr,pinMapping_t _pin,uint8_t dirShift,IParameterHandler *_param)
+    : m_OCR(OCR)
+    , m_Tccr(ttcr)
+#if  ! defined (__AVR_ATmega32U4__)
+    , m_Port(&PORTD)
+    , m_Ddr(&DDRD)
+#else
+    , m_Port(&PORTB)
+    , m_Ddr(&DDRB)
+#endif
+    , m_Mapping(_pin)
+    , m_DirShift(dirShift)
+    , m_Params(_param)
+    , m_DeltaD(0.0)
+    , m_DeltaI(0.0)
+    , m_DeltaPrev(0.0)
+{
+    init();
+}
+
+void 
+Motor::init()
+{
+  Uint8_t l_Mode;
+
+   *(m_Ddr) |= _BV(m_Mapping.pinPwm) | _BV(m_Mapping.pinOut); //either PIND7 or PIND4
+   *(m_Ddr) |= _BV(PIN_MOTOR_ENABLE);
+
+   (*m_Tccr)  |= (2<<m_DirShift);
+   m_Params->registerListener(PID_MotorState,this); /* State on or off */
+
+   if ( m_DirShift == COM0A0)
+   {
+       m_Params->registerListener(PID_MotorPwm,this); /* State on or off */
+       m_Params->registerListener(PID_MotorDir,this); /* State on or off */
+   }
+#if ! defined (__AVR_ATmega32U4__)
+   else 
+   {
+       TCCR2A  |= (2<<COM2B0); // direction !!!
+       m_Params->registerListener(PID_MotorBPwm,this); /* State on or off */
+       m_Params->registerListener(PID_MotorBDir,this); /* State on or off */
+   }
+#else
+   // Compare Modulator set to OR
+   (*m_Port) |= _BV(PINB7);
+#endif
+   // Read Motor State
+   m_Params->readValue(PID_MotorState,l_Mode);
+   enable(l_Mode);
+}
+
+void 
+Motor::onWriteValue(const uint8_t paramID,const uint8_t _val)
+{
+    switch (paramID)
+    {
+        case PID_MotorState:/* State on or off */
+            enable((bool)_val);
+            break;
+        case PID_MotorMode: /* DC Open loop,DC Closed loop, Stepper, brushless */
+            break;
+        case PID_MotorBPwm:
+        case PID_MotorPwm:  /* Used In case of open loop   10 - 90 % */
+            *m_OCR =_val;
+            break;
+        case PID_MotorRpm:  /* Used In case of closed loop uint16 I think */
+            break;
+        case PID_MotorBDir:
+        case PID_MotorDir:  /* 0 or 1 */
+           direction( (bool)_val);
+            break;
+        default:
+            ;
+    };
+}
+
+
+//! IParameterListener call
+void 
+Motor::onWriteValue(const uint8_t paramID,const Float32_t _val)
+{
+}
+
+void 
+Motor::enable(bool _val)
+
+    if ( _val != 0 )
+    {
+       (*m_Port)  |= _BV( PIN_MOTOR_ENABLE);
+        // reset PID contants
+        m_DeltaD    = 0.0f;
+        m_DeltaI    = 0.0f;
+        m_DeltaPrev = 0.0f;
+    } else 
+    {
+       (*m_Port)  &= ~_BV( PIN_MOTOR_ENABLE);
+    }
+}
+
+void
+Motor::direction(bool _val)
+{
+    if ( _val != 0 )
+    {
+       (*m_Port)  |= _BV( m_Mapping.pinOut);
+        (*m_Tccr)  |= (3<<m_DirShift); // direction !!!
+    } else 
+    {
+       (*m_Port)  &= ~_BV( m_Mapping.pinOut);
+        (*m_Tccr)  &= ~(3<<m_DirShift); // direction !!!
+        (*m_Tccr)  |= (2<<m_DirShift); // direction !!!
+    }
+}
+
+const bool 
+Motor::enabled() const
+{
+    return ( ((*m_Port)  & _BV( PIN_MOTOR_ENABLE) ) == 0 );
+}
+
+void
+Motor::update()
+{
+    Uint8_t l_Mode;
+
+    if  (  ((*m_Port)  & _BV( PIN_MOTOR_ENABLE) ) == 0 )
+    {
+        // don't do anything if motor is disabled
+        return ;
+    }
+    m_Params->readValue(PID_MotorMode,l_Mode);
+    if (l_Mode == 1)
+    { // In case of closed loop mode compute correction
+        updateUsingPID();
+    } else if (l_Mode == 2)
+    {
+       updateUsingPot0();
+    }
+
+}
+
+
+/// update motor using PID close loop computation
+void 
+Motor::updateUsingPID()
+{
+
+        Uint16_t countRpm,consigneRpm;
+        Uint8_t  consigne;
+        m_Params->readValue(PID_MotorRpm,countRpm);
+        m_Params->readValue(PID_MAConsRpm,consigneRpm);
+        Float32_t delta = static_cast<Float32_t>( consigneRpm )- static_cast<Float32_t>(countRpm);
+        Float32_t Kp,Ki,Kd;
+        m_Params->readValue(PID_Kp,Kp);
+        m_Params->readValue(PID_Ki,Ki);
+        m_Params->readValue(PID_Kd,Kd);
+      
+        m_DeltaI+=delta;
+        m_DeltaD = delta - m_DeltaPrev;
+        Float32_t newConsigne = delta * Kp;
+        
+        newConsigne += ( m_DeltaI * Ki + m_DeltaD * Kd );
+
+        m_DeltaPrev = delta;
+        // Update consigne :
+        if ( newConsigne < 10) 
+        {
+            consigne = 10;
+        } else if (newConsigne > 250)
+        {
+            consigne = 250;
+        } else
+        {
+            consigne = static_cast<Uint8_t>(newConsigne);
+        }
+        m_Params->writeValue(PID_MotorPwm,consigne);
+
+}
+
+/// update motor pwm using Pot0 value
+void
+Motor::updateUsingPot0()
+{
+    Uint16_t l_Pot;
+    m_Params->readValue(PID_Pot0,l_Pot);
+    l_Pot = static_cast<Uint16_t>(static_cast<Float32_t>(l_Pot) * 256.0 / 1024.0);
+    m_Params->writeValue(PID_MotorPwm,l_Pot);
+}
diff --git a/Application/DCMotor/32u4_DCMotor.cpp b/Application/DCMotor/32u4_DCMotor.cpp
new file mode 100644 (file)
index 0000000..f7ee8c6
--- /dev/null
@@ -0,0 +1,210 @@
+/**
+ * \brief simple application to test the C++ toolchain
+ *
+ * \file main.cc
+ * \author Andre Ebersold
+ */
+
+#include <Utils/StdTypes.h>
+
+
+#include <Platform/IParameterHandler.h>
+#include <Metadata/DCMotorParamIds.h>
+
+#include "DCMotor.h"
+#if  defined (__AVR_ATmega32U4__)
+#define PIN_MOTOR_ENABLE PINB2
+#else
+#define PIN_MOTOR_ENABLE PIND2
+#endif
+/**
+ *  \brief 
+ *
+ */
+Motor::Motor(IPwm *_pwm,pinMapping_t _pin,uint8_t dirShift,IParameterHandler *_param)
+    : m_Pwm(_pwm)
+#if  ! defined (__AVR_ATmega32U4__)
+    , m_Port(&PORTD)
+    , m_Ddr(&DDRD)
+#else
+    , m_Port(&PORTB)
+    , m_Ddr(&DDRB)
+#endif
+    , m_Mapping(_pin)
+    , m_DirShift(dirShift)
+    , m_Params(_param)
+    , m_DeltaD(0.0)
+    , m_DeltaI(0.0)
+    , m_DeltaPrev(0.0)
+{
+    init();
+}
+
+void 
+Motor::init()
+{
+  Uint8_t l_Mode;
+
+   *(m_Ddr) |= _BV(m_Mapping.pinPwm) | _BV(m_Mapping.pinOut); //either PIND7 or PIND4
+   *(m_Ddr) |= _BV(PIN_MOTOR_ENABLE);
+
+   //(*m_Tccr)  |= (2<<m_DirShift);
+   m_Params->registerListener(PID_MotorState,this); /* State on or off */
+
+   if ( m_DirShift == COM0A0)
+   {
+       m_Params->registerListener(PID_MotorPwm,this); /* State on or off */
+       m_Params->registerListener(PID_MotorDir,this); /* State on or off */
+   }
+   // Compare Modulator set to OR
+   (*m_Port) |= _BV(PINB7);
+   // Read Motor State
+   m_Params->readValue(PID_MotorState,l_Mode);
+   enable(l_Mode);
+}
+
+void 
+Motor::onWriteValue(const uint8_t paramID,const uint8_t _val)
+{
+    switch (paramID)
+    {
+        case PID_MotorState:/* State on or off */
+            enable((bool)_val);
+            break;
+        case PID_MotorMode: /* DC Open loop,DC Closed loop, Stepper, brushless */
+            break;
+        case PID_MotorBPwm:
+        case PID_MotorPwm:  /* Used In case of open loop   10 - 90 % */
+           m_Pwm->setDutyCycle(_val);
+            break;
+        case PID_MotorRpm:  /* Used In case of closed loop uint16 I think */
+            break;
+        case PID_MotorBDir:
+        case PID_MotorDir:  /* 0 or 1 */
+           direction( (bool)_val);
+            break;
+        default:
+            ;
+    };
+}
+
+
+//! IParameterListener call
+void 
+Motor::onWriteValue(const uint8_t paramID,const Float32_t _val)
+{
+}
+
+void 
+Motor::enable(bool _val)
+{
+    if ( _val != 0 )
+    {
+       (*m_Port)  |= _BV( PIN_MOTOR_ENABLE);
+        // reset PID contants
+        m_DeltaD    = 0.0f;
+        m_DeltaI    = 0.0f;
+        m_DeltaPrev = 0.0f;
+    } else 
+    {
+       (*m_Port)  &= ~_BV( PIN_MOTOR_ENABLE);
+    }
+}
+
+void
+Motor::direction(bool _val)
+{
+    if ( _val != 0 )
+    {
+       (*m_Port)  |= _BV( m_Mapping.pinOut);
+#if 0
+        (*m_Tccr)  |= (3<<m_DirShift); // direction !!!
+#else
+#endif
+    } else 
+    {
+       (*m_Port)  &= ~_BV( m_Mapping.pinOut);
+#if 0
+       (*m_Tccr)  &= ~(3<<m_DirShift); // direction !!!
+        (*m_Tccr)  |= (2<<m_DirShift); // direction !!!
+#else
+#endif
+    }
+}
+
+const bool 
+Motor::enabled() const
+{
+    return ( ((*m_Port)  & _BV( PIN_MOTOR_ENABLE) ) == 0 );
+}
+
+void
+Motor::update()
+{
+    Uint8_t l_Mode;
+
+    updateUsingPot0();
+    if  (  ((*m_Port)  & _BV( PIN_MOTOR_ENABLE) ) == 0 )
+    {
+        // don't do anything if motor is disabled
+        return ;
+    }
+    m_Params->readValue(PID_MotorMode,l_Mode);
+    if (l_Mode == 1)
+    { // In case of closed loop mode compute correction
+        updateUsingPID();
+    } else if (l_Mode == 2)
+    {
+       updateUsingPot0();
+    }
+
+}
+
+
+/// update motor using PID close loop computation
+void 
+Motor::updateUsingPID()
+{
+
+        Uint16_t countRpm,consigneRpm;
+        Uint8_t  consigne;
+        m_Params->readValue(PID_MotorRpm,countRpm);
+        m_Params->readValue(PID_MAConsRpm,consigneRpm);
+        Float32_t delta = static_cast<Float32_t>( consigneRpm )- static_cast<Float32_t>(countRpm);
+        Float32_t Kp,Ki,Kd;
+        m_Params->readValue(PID_Kp,Kp);
+        m_Params->readValue(PID_Ki,Ki);
+        m_Params->readValue(PID_Kd,Kd);
+      
+        m_DeltaI+=delta;
+        m_DeltaD = delta - m_DeltaPrev;
+        Float32_t newConsigne = delta * Kp;
+        
+        newConsigne += ( m_DeltaI * Ki + m_DeltaD * Kd );
+
+        m_DeltaPrev = delta;
+        // Update consigne :
+        if ( newConsigne < 10) 
+        {
+            consigne = 10;
+        } else if (newConsigne > 250)
+        {
+            consigne = 250;
+        } else
+        {
+            consigne = static_cast<Uint8_t>(newConsigne);
+        }
+        m_Params->writeValue(PID_MotorPwm,consigne);
+
+}
+
+/// update motor pwm using Pot0 value
+void
+Motor::updateUsingPot0()
+{
+    Uint16_t l_Pot;
+    m_Params->readValue(PID_Pot0,l_Pot);
+    l_Pot = static_cast<Uint16_t>(static_cast<Float32_t>(l_Pot) * 256.0 / 1024.0);
+    m_Params->writeValue(PID_MotorPwm,l_Pot);
+}
diff --git a/Application/DCMotor/CMakeLists.txt b/Application/DCMotor/CMakeLists.txt
new file mode 100644 (file)
index 0000000..624792c
--- /dev/null
@@ -0,0 +1,36 @@
+#####################################################################
+# simple AVR executable
+#####################################################################
+add_avr_executable(
+   dcmotor
+   main.cpp
+   Led0.cpp
+   DCMotor.cpp
+   MotorHandler.cpp
+   )
+
+target_link_libraries(
+  dcmotor-${AVR_MCU}.elf
+  avrHAL-${AVR_MCU}
+  avrDrivers-${AVR_MCU}
+  avrComm-${AVR_MCU}
+  avrPtf-${AVR_MCU}
+  avrDCMotorParameters-${AVR_MCU}
+)
+
+IF (${AVR_MCU} EQUAL "atmega328p")
+ SET(AVRPROG arduino)
+ SET(AVRPROG_MCU Atmega328p)
+ELSE(${AVR_MCU} EQUAL "atmega328p")
+ SET(AVRPROG avr109)
+ SET(AVRPROG_MCU m32u4)
+ENDIF(${AVR_MCU} EQUAL "atmega328p")
+
+add_custom_target(
+      flash_dcmotor
+      COMMAND
+      # avrdude -c arduino -P ${AVRDUDE_PORT} -p Atmega328p -b 57600 -Uflash:w:${CMAKE_CURRENT_BINARY_DIR}/dcmotor-${AVR_MCU}.hex:i
+      avrdude -c ${AVRPROG} -P ${AVRDUDE_PORT} -p ${AVRPROG_MCU} -b 57600 -Uflash:w:${CMAKE_CURRENT_BINARY_DIR}/dcmotor-${AVR_MCU}.hex:i
+      DEPENDS dcmotor-${AVR_MCU}.hex
+    )
+
diff --git a/Application/DCMotor/DCM_InterruptActivity.cpp b/Application/DCMotor/DCM_InterruptActivity.cpp
new file mode 100644 (file)
index 0000000..4747003
--- /dev/null
@@ -0,0 +1,21 @@
+#include "HAL/Abstract/IInterruptActivity.h"
+#include "DCM_InterruptActivity.h"
+/**
+ * Interrupt Activity Implementation for
+ * DC motor...
+ *   call tick method for all classes controled by 
+ *   Interupt activity.
+ *   -> The scheduler must be able to 
+ *   make the processing in the given time line !!! 500us
+ */
+DCM_InterrupttActivity(IScheduler &_scheduler)
+  : m_Scheduler(_scheduler)
+{
+}
+
+void 
+DCM_InterruptyActivity::tick()
+{
+  m_Scheduler.tick();
+}
+
diff --git a/Application/DCMotor/DCM_InterruptActivity.h b/Application/DCMotor/DCM_InterruptActivity.h
new file mode 100644 (file)
index 0000000..7cbfddf
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef DCM_INTERRUPT_ACTIVITY_H__
+#define DCM_INTERRUPT_ACTIVITY_H__
+/**
+ * Interrupt Activity Implementation for
+ * DC motor...
+ *   call tick method for all classes controled by 
+ *   Interupt activity.
+ *   -> The scheduler must be able to 
+ *   make the processing in the given time line !!! 500us
+ */
+
+class DCM_InterruptActivity : public IInterruptActivity
+{
+  public:
+    DCM_InterrupttActivity(IScheduler &_scheduler)
+
+    void tick();
+
+};
+
+#endif
diff --git a/Application/DCMotor/DCMotor.cpp b/Application/DCMotor/DCMotor.cpp
new file mode 100644 (file)
index 0000000..e57ff36
--- /dev/null
@@ -0,0 +1,21 @@
+/**
+ * \brief simple application to test the C++ toolchain
+ *
+ * \file main.cc
+ * \author Andre Ebersold
+ */
+
+#include <Utils/StdTypes.h>
+
+
+#include <Platform/IParameterHandler.h>
+#include <Metadata/DCMotorParamIds.h>
+#include "Led0.h"
+#include "Abstract/IPwm.h"
+#include "DCMotor.h"
+
+#if  defined (__AVR_ATmega32U4__)
+#include "32u4_DCMotor.cpp"
+#else
+#include "328p_DCMotor.cpp"
+#endif
diff --git a/Application/DCMotor/DCMotor.h b/Application/DCMotor/DCMotor.h
new file mode 100644 (file)
index 0000000..854c286
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef __DCMOTOR_H__
+#define __DCMOTOR_H__
+/**
+ * \brief simple class for port access for DCMotor
+ *  Motor is PWM.
+ *  controls enable / direction 
+ *  2 output pins ocrA (Fast PWM) + Port D 
+ *                ocrB ()
+ *
+ * direction is controled my 
+ * \file Motor.h
+ * \author Ebersold Andre
+ */
+
+/**
+ * \brief 
+ */
+class Motor : public virtual IParameterListener
+{
+    public:
+      typedef struct _PinMapping_t
+      {
+         uint8_t pinPwm:3;
+         uint8_t pinOut:3;
+         uint8_t unused:2;
+      } pinMapping_t;
+      /**
+       * \brief constructor of LED access class
+       * \param PORT to access the LED
+       * \param DDR  to set the LED port pin to output
+       * \param PIN  to access the LED
+       */
+#if defined (__AVR_ATmega32U4__)
+      Motor(IPwm *pwm,pinMapping_t  PIN,uint8_t _dirshift,IParameterHandler *);
+#else
+      Motor(volatile uint8_t *OCR, volatile uint8_t *tccr,pinMapping_t  PIN,uint8_t _dirshift,IParameterHandler *);
+#endif
+      //! destructor
+      ~Motor();
+
+      void init();
+      /**
+       * \brief in case of close loop, update PWM according to measured value
+       * to get as close as possible to order.
+       *
+       */
+      void update();
+      //! IParameterListener call
+      void onWriteValue(const uint8_t paramID,const uint8_t _val) ;
+      //! IParameterListener call
+      void onWriteValue(const uint8_t paramID,const Float32_t _val) ;
+    private:
+      //! enable disable motor
+      void enable(bool _on);
+      //! returns true if motor is enabled
+      const bool enabled() const;
+      //! change motor direction
+      void direction(bool _on);
+      /// update motor using PID close loop computation
+      void updateUsingPID();
+      /// update motor pwm using Pot0 value
+      void updateUsingPot0();
+    private:
+#if defined (__AVR_ATmega32U4__)
+      IPwm             *m_Pwm;
+#else
+      //! pointer to the Motor pwm register OCR0A or OCR0B 
+      volatile uint8_t *m_OCR;
+      //! pointer to pwm direction 
+      volatile uint8_t *m_Tccr;
+#endif
+      //! pointer to the Motor port (direction )
+      volatile uint8_t *m_Port;
+      //! pointer to the LED port's data direction register
+      volatile uint8_t *m_Ddr;
+      //! pin the LED is connected to
+      pinMapping_t      m_Mapping;
+      //! position for compare direction shift position
+      uint8_t           m_DirShift;
+      //! Parameter handler
+      IParameterHandler *m_Params;
+      //! Previous delta error
+      Float32_t          m_DeltaD;
+      //! Integral 
+      Float32_t          m_DeltaI;
+      //! Keep n-1 error
+      Float32_t          m_DeltaPrev;
+};
+
+#endif
diff --git a/Application/DCMotor/Led0.cpp b/Application/DCMotor/Led0.cpp
new file mode 100644 (file)
index 0000000..a2b7de8
--- /dev/null
@@ -0,0 +1,81 @@
+/**
+ * \brief simple class for port access for LEDs
+ *
+ * \file Led0.cpp
+ * \author Ebersold Andre
+ */
+
+//#include <avr/io.h>
+#include <Utils/StdTypes.h>
+#include <Platform/IParameterHandler.h>
+#include <Metadata/DCMotorParamIds.h>
+#include "Led0.h"
+
+/**
+ * \brief constructor of LED access class
+ * \param PORT to access the LED
+ * \param DDR  to set the LED port pin to output
+ * \param PIN  to access the LED
+ */
+Led0::Led0(volatile uint8_t *PORT, volatile uint8_t *DDR, uint8_t PIN,IParameterHandler *_ph)
+: m_Port(PORT)
+, m_Ddr(DDR)
+, m_Pin(PIN)
+, m_Counter(0)
+, m_Param(_ph)
+{
+  uint16_t cycle = 350;
+  _ph->writeValue(PID_LedCycle,cycle);
+   *(m_Ddr) |= (1 << m_Pin);
+}
+
+//! destructor
+Led0::~Led0()
+{
+}
+
+//! switches the LED on
+void Led0::on(void)
+{
+   *(m_Port) |= (1 << m_Pin);
+}
+
+//! switches the LED off
+void Led0::off(void)
+{
+   *(m_Port) &= ~(1 << m_Pin);
+}
+
+//! toggles the LED
+void Led0::toggle(void)
+{
+   *(m_Port) ^= (1 << m_Pin);
+}
+
+///
+void 
+Led0::setCycle(uint16_t _cycle)
+{
+    m_Param->writeValue(PID_LedCycle,_cycle);
+}
+///
+void 
+Led0::reloadCounter()
+{
+    uint16_t cycle = 100;
+    m_Param->readValue(PID_LedCycle,cycle);
+    m_Counter = cycle;
+}
+///
+void 
+Led0::tick()
+{
+    if (m_Counter > 0)
+    {
+        m_Counter--;
+    } else
+    {
+        toggle();
+        reloadCounter();
+    }
+}
diff --git a/Application/DCMotor/Led0.h b/Application/DCMotor/Led0.h
new file mode 100644 (file)
index 0000000..e8f4209
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+ * \brief simple class for port access for LEDs
+ *
+ * \file Led0.h
+ * \author Ebersold Andre
+ */
+
+/**
+ * \brief simple access class for LEDs
+ */
+class Led0
+{
+   public:
+      /**
+       * \brief constructor of LED access class
+       * \param PORT to access the LED
+       * \param DDR  to set the LED port pin to output
+       * \param PIN  to access the LED
+       */
+      Led0(volatile uint8_t *PORT, volatile uint8_t *DDR, uint8_t PIN,IParameterHandler *);
+      //! destructor
+      ~Led0();
+
+      //! switches the LED on
+      void on(void);
+      //! switches the LED off
+      void off(void);
+      //! toggles the LED
+      void toggle(void);
+      ///
+      void setCycle(uint16_t _cycle);
+      ///
+      void reloadCounter();
+      ///
+      void tick();
+   private:
+      Led0();
+      Led0( Led0 const &src );
+      Led0& operator=(const Led0 &src ) ;
+
+      //! pointer to the LED port
+      volatile uint8_t *m_Port;
+      //! pointer to the LED port's data direction register
+      volatile uint8_t *m_Ddr;
+      //! pin the LED is connected to
+      uint8_t m_Pin;
+      //! reset count
+      uint16_t m_Counter;
+      ///
+      IParameterHandler *m_Param;
+};
+
diff --git a/Application/DCMotor/MotorHandler.cpp b/Application/DCMotor/MotorHandler.cpp
new file mode 100644 (file)
index 0000000..e1d8e3c
--- /dev/null
@@ -0,0 +1,81 @@
+#include "Utils/StdTypes.h"
+
+#include "Application/ITask.h"
+#include "Abstract/IAdc.h"
+#include "Abstract/IPwm.h"
+#include <Platform/IParameterHandler.h>
+
+#include <AVR/AvrTimer1.h>
+#include <Metadata/DCMotorParamIds.h>
+#include "DCMotor.h"
+#include "MotorHandler.h"
+
+
+#if ! defined (__AVR_ATmega32U4__)
+static Motor::pinMapping_t GmA = {PIND6,PIND7,0};
+static Motor::pinMapping_t GmB = {PIND3,PIND4,0};
+#else
+static Motor::pinMapping_t GmA = {PINB7,PINB6,0};
+#endif
+
+MotorHandler::MotorHandler(IParameterHandler *_p,IAdc *_adc,Timer1 *_t1,IPwm *_pwma)
+  : m_Params(_p)
+  , m_Adc(_adc)
+  , m_Counter(_t1) 
+#if defined (__AVR_ATmega32U4__)
+  , m_MotorA(_pwma,GmA,COM0A0,_p) 
+#else
+  , m_MotorA(&OCR0A,&TCCR0A,GmA,COM0A0,_p) 
+  , m_MotorB(&OCR2B,&TCCR2A,GmB,COM2B0,_p)
+#endif
+  , m_Ticks(0)
+{
+}
+
+#define TICK_COUNT 20
+/**
+ * Well try processing evey 2ms
+ */
+void
+MotorHandler::run()
+{
+    Uint8_t l_Mode;
+    m_Ticks = (m_Ticks < TICK_COUNT)
+              ? m_Ticks + 1
+              : 0;
+
+    m_Params->readValue(PID_MotorMode,l_Mode);
+    if ( m_Ticks == 0)
+    { // In case of closed loop mode compute correction
+#if defined (__AVR_ATmega32U4__)
+        Uint16_t _Rpm = 0;
+        Uint16_t count = m_Counter->readCounter(true);
+        // convert to Rpm !
+        computeRpm(static_cast<Float32_t>(count),_Rpm);
+        m_Params->writeValue(PID_MotorRpm,_Rpm);
+
+#endif
+       updatePot0();
+        m_MotorA.update();
+    }
+}
+        
+void
+MotorHandler::updatePot0()
+{
+  Uint16_t l_pot = m_Adc->read(0);
+  m_Params->writeValue(PID_Pot0,l_pot);
+}
+
+
+void 
+MotorHandler::computeRpm(const Float32_t count,Uint16_t &_rpm)
+{
+    Uint16_t l_cpr;
+
+    m_Params->readValue(PID_CPR,l_cpr);
+    Float32_t _conv = 100.0/static_cast<Float32_t>(l_cpr);
+    _conv *= 60.0;
+    _conv *= count;
+    _rpm   = static_cast<Uint16_t>(_conv);
+}
diff --git a/Application/DCMotor/MotorHandler.h b/Application/DCMotor/MotorHandler.h
new file mode 100644 (file)
index 0000000..1cb74b5
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef MOTORHANDLER_H__
+#define MOTORHANDLER_H__
+
+/**
+ * \brief Controls the motor behavior depending
+ * on the motor mode.
+ *
+ */
+class MotorHandler : public ITask
+{
+    public:
+        MotorHandler(IParameterHandler *_ph,IAdc *_adc,Timer1 *_t1,IPwm *_pwma );
+
+        virtual void run();
+    private:
+       /** 
+        * Read Adc channel 0 and update Pot0 parameter
+        * with the read value
+        */
+       void updatePot0();
+       /**
+        *
+        */
+        void computeRpm(const Float32_t count,Uint16_t &_rpm);
+    private:
+        IParameterHandler *m_Params;
+       IAdc              *m_Adc;
+        Timer1            *m_Counter;
+        Motor              m_MotorA;
+#if ! defined (__AVR_ATmega32U4__)
+        Motor              m_MotorB;
+#endif
+        Uint8_t            m_Ticks; // 500us ticks
+};
+
+#endif
diff --git a/Application/DCMotor/main.cpp b/Application/DCMotor/main.cpp
new file mode 100644 (file)
index 0000000..6d313af
--- /dev/null
@@ -0,0 +1,201 @@
+/**
+ * \brief simple application to test the C++ toolchain
+ *
+ * \file main.cc
+ * \author Andre Ebersold
+ */
+
+#include <Utils/StdTypes.h>
+#include <util/delay.h>
+
+#include <Abstract/IInterruptActivity.h>
+#include <Abstract/IProtocolLayer2.h>
+#include <Abstract/IUart.h>
+#include <Abstract/IAdc.h>
+#include <Abstract/IEeprom.h>
+#include <Abstract/IPwm.h>
+#include <Application/ITask.h>
+#include <AVR/AvrTimer0.h>
+#include <AVR/AvrTimer1.h>
+#include <AVR/AvrUart.h>
+#include <AVR/AvrAdc.h>
+#include <AVR/AvrEeprom.h>
+#include <AVR/AvrPwm.h>
+#include <Platform/IParameterHandler.h>
+#include <Metadata/DCMotorParamIds.h>
+#include <Platform/DCMotorParameterHandler.h>
+#include <Platform/PersistentStorage.h>
+#include <Communication/CommunicationHandler.h>
+
+
+#include <Drivers/NetString.h>
+#include "Led0.h"
+#include "DCMotor.h"
+#include "MotorHandler.h"
+
+/**
+ * @brief the scheduler will still slice the execution
+ * flow. The whole cycle is now 40 ticks !
+ * 40 * 
+ * 250ns * 4 = 1us * 10 = 10 us. On fast devices.
+ *
+ * 16MHz / 8 / 256 = 100us each tick
+ *
+ */
+class Scheduler : public IInterruptActivity
+{
+  private:
+      enum TIME_SLOTS {
+              FIRST_TIME_SLOT        =  0,
+              BLOCK2_FIRST_TIME_SLOT =  1,
+              BLOCK3_FIRST_TIME_SLOT =  3,
+              LAST_TIME_SLOT         =  5,
+              TIME_SLOT_COUNT        =  5
+      };
+      enum ETASK_ID {
+              TASK1      = 0,
+              TASK2      = 1,
+              TASK3      = 2,
+              TASK_COUNT = 3
+      };
+      typedef struct Task_t {
+          TIME_SLOTS  m_FirstTimeslot;
+          ETASK_ID    m_NextTask;
+      } Task_type ;
+
+      static Task_type gTasks[TASK_COUNT];
+  public:
+    Scheduler(Led0 *_led,IProtocolLayer2 *_net,CommunicationHandler *_com,MotorHandler *_mh
+                   ,ITask *_Adc
+                   ,ITask *_Storage
+                   )
+      : 
+              m_Led(_led)
+              , m_Netstring(_net)
+              , m_Com(_com)
+              , m_Motor(_mh)
+             , m_Adc(_Adc)
+             , m_Storage(_Storage)
+              , m_CurrentTimeslot(FIRST_TIME_SLOT)
+              , m_CurrentTask(TASK1)
+    {
+    }
+    // main entry point
+    void schedule()
+    {
+        waitForTimeslot();
+        m_Com->run();
+        switch (m_CurrentTask)
+        {
+            case TASK1:
+               m_Adc->run();
+            break;
+            case TASK2:
+                m_Motor->run();
+            break;
+            case TASK3:
+                m_Led->tick();
+               m_Storage->run();
+            break;
+            default:
+            ;
+        
+        }
+        m_CurrentTask = gTasks[m_CurrentTask].m_NextTask;
+    }
+    // called  by the interrupt timer handler
+    virtual void tick()
+    {
+            m_CurrentTimeslot = (m_CurrentTimeslot < LAST_TIME_SLOT)
+                                ? (TIME_SLOTS)(m_CurrentTimeslot+1) 
+                                : (FIRST_TIME_SLOT);
+            m_Netstring->tick();
+    }
+
+  private:
+    void waitForTimeslot( void )
+    {
+            /// prevent instant scheduling 
+            while (m_CurrentTimeslot  == gTasks[m_CurrentTask].m_FirstTimeslot )
+            {
+                ;
+            }
+            // beginning of the timeslot
+            while (m_CurrentTimeslot  != gTasks[m_CurrentTask].m_FirstTimeslot ) 
+            {
+                ;
+            }
+    }
+  private:
+    Led0                   *m_Led;
+    IProtocolLayer2        *m_Netstring;
+    CommunicationHandler   *m_Com;
+    MotorHandler           *m_Motor;
+    ITask                  *m_Adc;
+    ITask                  *m_Storage;
+    volatile TIME_SLOTS     m_CurrentTimeslot;
+    ETASK_ID                m_CurrentTask;
+
+
+};
+
+Scheduler::Task_type Scheduler::gTasks[TASK_COUNT] = {
+    { FIRST_TIME_SLOT , TASK2 }
+  , { BLOCK2_FIRST_TIME_SLOT, TASK3 }
+  , { BLOCK3_FIRST_TIME_SLOT, TASK1 }
+};
+
+/**
+ * \brief Init database ....
+ */
+void init(IParameterHandler *m_Param)
+{
+   m_Param->writeValue(PID_MotorPwm,(uint8_t)60);
+   m_Param->writeValue(PID_CPR,static_cast<Uint16_t >(500));
+   m_Param->writeValue(PID_MAConsRpm,(uint8_t)600);
+   m_Param->writeValue(PID_Kp,0.08f);
+   m_Param->writeValue(PID_Kp,0.003f);
+   m_Param->writeValue(PID_Kp,0.004f);
+}
+
+
+/**
+ * \brief main loop
+ */
+int main(void)
+{
+   Timer1     lCounter;
+   DCMotorParameterHandler gParam; 
+#if defined (__AVR_ATmega32U4__)
+   Led0                 led(&PORTC, &DDRC, PINB7,&gParam);
+   AvrPwm               pwmA;               
+#else
+   Led0                 led(&PORTB, &DDRB, PINB5,&gParam);
+#endif   
+   AvrUart              uart(IUart::BAUD_9600,IUart::PARITY_NONE,IUart::STB_ONE);
+   AvrADC               gAdc;
+   AvrEeprom            gEeprom;
+   NetString            netstring(&uart);
+   CommunicationHandler gCom(&netstring,&gParam);
+   PersistentStorage    gStorage(&gEeprom,&gParam);
+   MotorHandler         motorH(&gParam,&gAdc,&lCounter,&pwmA);
+   Scheduler            sched(&led,&netstring,&gCom,&motorH,&gAdc,&gStorage);
+
+   uart.init();
+   netstring.init();
+
+   Timer0 lTimer(sched);
+   led.on();
+    _delay_ms(300);
+   led.off();
+    _delay_ms(300);
+
+   lTimer.init();
+   init(&gParam);
+   gEeprom.init();
+   while(1)
+   {
+      sched.schedule();
+   }
+}
diff --git a/Application/ICommandHandler.h b/Application/ICommandHandler.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Application/ITask.h b/Application/ITask.h
new file mode 100644 (file)
index 0000000..e06be46
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __ITASK_H__
+#define __ITASK_H__
+
+/**
+ * Abstract class for all Handlers.
+ * Only run can be invoked 
+ * Maybe add a parameter for tasks that might need
+ * an event  or state information to be able to run.
+ * For example multiple runs during a global cycle
+ */
+class ITask
+{
+    public:
+        ITask() {}
+
+        virtual void run() = 0;
+};
+#endif
diff --git a/Application/Led0/CMakeLists.txt b/Application/Led0/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8da43c8
--- /dev/null
@@ -0,0 +1,9 @@
+#####################################################################
+# simple AVR executable
+#####################################################################
+add_avr_executable(
+   toggle-led-cpp
+   main.cpp
+   Led0.cpp
+   )
+
diff --git a/Application/Led0/Led0.cpp b/Application/Led0/Led0.cpp
new file mode 100644 (file)
index 0000000..149eab0
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * \brief simple class for port access for LEDs
+ *
+ * \file Led0.cpp
+ * \author Ebersold Andre
+ */
+
+#include <avr/io.h>
+
+#include "Led0.h"
+
+/**
+ * \brief constructor of LED access class
+ * \param PORT to access the LED
+ * \param DDR  to set the LED port pin to output
+ * \param PIN  to access the LED
+ */
+Led0::Led0(volatile uint8_t *PORT, volatile uint8_t *DDR, uint8_t PIN)
+: m_Port(PORT)
+, m_Ddr(DDR)
+, m_Pin(PIN)
+{
+   *(m_Ddr) |= (1 << m_Pin);
+}
+
+//! destructor
+Led0::~Led0()
+{
+}
+
+//! switches the LED on
+void Led0::on(void)
+{
+   *(m_Port) |= (1 << m_Pin);
+}
+
+//! switches the LED off
+void Led0::off(void)
+{
+   *(m_Port) &= ~(1 << m_Pin);
+}
+
+//! toggles the LED
+void Led0::toggle(void)
+{
+   *(m_Port) ^= (1 << m_Pin);
+}
+
diff --git a/Application/Led0/Led0.h b/Application/Led0/Led0.h
new file mode 100644 (file)
index 0000000..2e26073
--- /dev/null
@@ -0,0 +1,43 @@
+/**
+ * \brief simple class for port access for LEDs
+ *
+ * \file Led0.h
+ * \author Ebersold Andre
+ */
+
+/**
+ * \brief simple access class for LEDs
+ */
+class Led0
+{
+   public:
+      /**
+       * \brief constructor of LED access class
+       * \param PORT to access the LED
+       * \param DDR  to set the LED port pin to output
+       * \param PIN  to access the LED
+       */
+      Led0(volatile uint8_t *PORT, volatile uint8_t *DDR, uint8_t PIN);
+      //! destructor
+      ~Led0();
+
+      //! switches the LED on
+      void on(void);
+      //! switches the LED off
+      void off(void);
+      //! toggles the LED
+      void toggle(void);
+
+   private:
+      Led0();
+      Led0( Led0 const &src );
+      Led0& operator=(const Led0 &src );
+
+      //! pointer to the LED port
+      volatile uint8_t *m_Port;
+      //! pointer to the LED port's data direction register
+      volatile uint8_t *m_Ddr;
+      //! pin the LED is connected to
+      uint8_t m_Pin;
+};
+
diff --git a/Application/Led0/main.cpp b/Application/Led0/main.cpp
new file mode 100644 (file)
index 0000000..37da27e
--- /dev/null
@@ -0,0 +1,25 @@
+/**
+ * \brief simple application to test the C++ toolchain
+ *
+ * \file main.cc
+ * \author Andre Ebersold
+ */
+
+#include <avr/io.h>
+#include <util/delay.h>
+
+#include "Led0.h"
+
+/**
+ * \brief main loop
+ */
+int main(void)
+{
+   Led0 led(&PORTB, &DDRB, PINB1);
+
+   while(1)
+   {
+      led.toggle();
+      _delay_ms(500);
+   }
+}
diff --git a/Application/PowerSwitch/CMakeLists.txt b/Application/PowerSwitch/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ee360ec
--- /dev/null
@@ -0,0 +1,38 @@
+#####################################################################
+# simple AVR executable
+#####################################################################
+add_avr_executable(
+   powerswitch
+   main.cpp
+   Led0.cpp
+   Switch.cpp
+   PowerswitchHandler.cpp
+   )
+
+target_link_libraries(
+  powerswitch-${AVR_MCU}.elf
+  avrHAL-${AVR_MCU}
+  avrDrivers-${AVR_MCU}
+  avrComm-${AVR_MCU}
+  avrPS-Ptf-${AVR_MCU}
+  avrPowerswitchParameters-${AVR_MCU}
+)
+
+IF ( "${AVR_MCU}" STREQUAL "atmega328p")
+ SET(AVRPROG arduino)
+ SET(AVRPROG_MCU Atmega328p)
+ MESSAGE("AVR_MCU = ${AVR_MCU} Yes atmega")
+ELSE( "${AVR_MCU}" STREQUAL "atmega32u4")
+ SET(AVRPROG avr109)
+ SET(AVRPROG_MCU m32u4)
+ MESSAGE("AVR_MCU = '${AVR_MCU}' if atmega328p not goot at all")
+ENDIF("${AVR_MCU}" STREQUAL "atmega328p")
+
+add_custom_target(
+      flash_powerswitch
+      COMMAND
+      # avrdude -c arduino -P ${AVRDUDE_PORT} -p Atmega328p -b 57600 -Uflash:w:${CMAKE_CURRENT_BINARY_DIR}/dcmotor-${AVR_MCU}.hex:i
+      avrdude -c ${AVRPROG} -P ${AVRDUDE_PORT} -p ${AVRPROG_MCU} -b 57600 -Uflash:w:${CMAKE_CURRENT_BINARY_DIR}/powerswitch-${AVR_MCU}.hex:i
+      DEPENDS powerswitch-${AVR_MCU}.hex
+    )
+
diff --git a/Application/PowerSwitch/Led0.cpp b/Application/PowerSwitch/Led0.cpp
new file mode 100644 (file)
index 0000000..22a9c5c
--- /dev/null
@@ -0,0 +1,81 @@
+/**
+ * \brief simple class for port access for LEDs
+ *
+ * \file Led0.cpp
+ * \author Ebersold Andre
+ */
+
+//#include <avr/io.h>
+#include <Utils/StdTypes.h>
+#include <Platform/IParameterHandler.h>
+#include <Metadata/PowerswitchParamIds.h>
+#include "Led0.h"
+
+/**
+ * \brief constructor of LED access class
+ * \param PORT to access the LED
+ * \param DDR  to set the LED port pin to output
+ * \param PIN  to access the LED
+ */
+Led0::Led0(volatile uint8_t *PORT, volatile uint8_t *DDR, uint8_t PIN,IParameterHandler *_ph)
+: m_Port(PORT)
+, m_Ddr(DDR)
+, m_Pin(PIN)
+, m_Counter(0)
+, m_Param(_ph)
+{
+  uint16_t cycle = 350;
+  _ph->writeValue(PID_LedCycle,cycle);
+   *(m_Ddr) |= (1 << m_Pin);
+}
+
+//! destructor
+Led0::~Led0()
+{
+}
+
+//! switches the LED on
+void Led0::on(void)
+{
+   *(m_Port) |= (1 << m_Pin);
+}
+
+//! switches the LED off
+void Led0::off(void)
+{
+   *(m_Port) &= ~(1 << m_Pin);
+}
+
+//! toggles the LED
+void Led0::toggle(void)
+{
+   *(m_Port) ^= (1 << m_Pin);
+}
+
+///
+void 
+Led0::setCycle(uint16_t _cycle)
+{
+    m_Param->writeValue(PID_LedCycle,_cycle);
+}
+///
+void 
+Led0::reloadCounter()
+{
+    uint16_t cycle = 100;
+    m_Param->readValue(PID_LedCycle,cycle);
+    m_Counter = cycle;
+}
+///
+void 
+Led0::tick()
+{
+    if (m_Counter > 0)
+    {
+        m_Counter--;
+    } else
+    {
+        toggle();
+        reloadCounter();
+    }
+}
diff --git a/Application/PowerSwitch/Led0.h b/Application/PowerSwitch/Led0.h
new file mode 100644 (file)
index 0000000..e8f4209
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+ * \brief simple class for port access for LEDs
+ *
+ * \file Led0.h
+ * \author Ebersold Andre
+ */
+
+/**
+ * \brief simple access class for LEDs
+ */
+class Led0
+{
+   public:
+      /**
+       * \brief constructor of LED access class
+       * \param PORT to access the LED
+       * \param DDR  to set the LED port pin to output
+       * \param PIN  to access the LED
+       */
+      Led0(volatile uint8_t *PORT, volatile uint8_t *DDR, uint8_t PIN,IParameterHandler *);
+      //! destructor
+      ~Led0();
+
+      //! switches the LED on
+      void on(void);
+      //! switches the LED off
+      void off(void);
+      //! toggles the LED
+      void toggle(void);
+      ///
+      void setCycle(uint16_t _cycle);
+      ///
+      void reloadCounter();
+      ///
+      void tick();
+   private:
+      Led0();
+      Led0( Led0 const &src );
+      Led0& operator=(const Led0 &src ) ;
+
+      //! pointer to the LED port
+      volatile uint8_t *m_Port;
+      //! pointer to the LED port's data direction register
+      volatile uint8_t *m_Ddr;
+      //! pin the LED is connected to
+      uint8_t m_Pin;
+      //! reset count
+      uint16_t m_Counter;
+      ///
+      IParameterHandler *m_Param;
+};
+
diff --git a/Application/PowerSwitch/PowerswitchHandler.cpp b/Application/PowerSwitch/PowerswitchHandler.cpp
new file mode 100644 (file)
index 0000000..e2ad9a1
--- /dev/null
@@ -0,0 +1,94 @@
+#include "Utils/StdTypes.h"
+
+#include "Application/ITask.h"
+#include "Abstract/ISwitch.h"
+#include <Platform/IParameterHandler.h>
+
+#include <Metadata/PowerswitchParamIds.h>
+#include "Switch.h"
+#include "PowerswitchHandler.h"
+
+
+PowerswitchHandler::PowerswitchHandler(IParameterHandler *_p)
+  : m_Params(_p)
+  , m_Ticks(0)
+{
+    //DDRD |= 0x7C;
+    DDRD &= ~0x7C;
+    //PIND = 0x7C;
+    PORTD = 0x7C;
+    DDRC = 0x0F;
+    PORTC = 0XFF;
+    m_Params->registerListener(PID_SwitchAll,this); /* State on or off */
+    m_Params->registerListener(PID_Switch1,this); /* State on or off */
+    m_Params->registerListener(PID_Switch2,this); /* State on or off */
+    m_Params->registerListener(PID_Switch3,this); /* State on or off */
+    m_Params->registerListener(PID_Switch4,this); /* State on or off */
+}
+
+#define TICK_COUNT 200
+/**
+ * Well try processing evey 2s
+ */
+void
+PowerswitchHandler::run()
+{
+    m_Ticks = (m_Ticks < TICK_COUNT)
+              ? m_Ticks + 1
+              : 0;
+
+    if ( m_Ticks == 0)
+    { // In case of closed loop mode compute correction
+       readPushButtons();
+        // convert to Rpm !
+        //m_Params->writeValue(PID_PowerswitchRpm,_Rpm);
+    }
+}
+        
+void 
+PowerswitchHandler::readPushButtons()
+{
+    Uint8_t pids[SWITCH_NUMBER + 1 ]  = { PID_SwitchAll,PID_Switch4,PID_Switch3,PID_Switch2,PID_Switch1 };
+    Uint8_t mask = 0;
+
+    for (Uint8_t i = 0 ; i < SWITCH_NUMBER + 1; ++i)
+    {
+        mask = 1<<(i + 2);
+       /* Button press */
+       if ( (PIND & mask) == 0)
+       {
+           Uint8_t val = 0;
+            m_Params->readValue(pids[i],val);
+            if (val > 0) 
+           {
+             val = 0;
+           } else  val = 1;
+           m_Params->writeValue(pids[i],val);
+       }
+    }  
+}
+
+void 
+PowerswitchHandler::onWriteValue(const uint8_t paramID,const uint8_t _val)
+{
+    switch (paramID)
+    {
+       case  PID_Switch1:
+           PORTC ^= _BV(PINC0);
+       break;
+       case  PID_Switch2:
+           PORTC ^= _BV(PINC1);
+       break;
+       case  PID_Switch3:
+           PORTC ^= _BV(PINC2);
+       break;
+       case  PID_Switch4:
+           PORTC ^= _BV(PINC3);
+       break;
+       case  PID_SwitchAll:
+           PORTC = 0xFF;
+       break;
+       default:
+       ;
+    }
+}
diff --git a/Application/PowerSwitch/PowerswitchHandler.h b/Application/PowerSwitch/PowerswitchHandler.h
new file mode 100644 (file)
index 0000000..80b34f3
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef POWERSWITCHHANDLER_H__
+#define POWERSWITCHHANDLER_H__
+
+#define SWITCH_NUMBER  4
+/**
+ * \brief Controls the motor behavior depending
+ * on the motor mode.
+ *
+ */
+class PowerswitchHandler : public ITask, public IParameterListener
+{
+    public:
+        PowerswitchHandler(IParameterHandler *_ph);
+
+        virtual void run();
+    private:
+       /** 
+        * Read Input pins
+        * with the read value
+        */
+       void readPushButtons();
+       /**
+        *
+        */
+        virtual void onWriteValue(const uint8_t paramID,const uint8_t _val) ;
+        //! IParameterListener call
+        virtual void onWriteValue(const uint8_t paramID,const Float32_t _val) {};
+    private:
+        IParameterHandler *m_Params;
+        Switch            *m_Switchs;
+        Uint8_t            m_Ticks; // 500us ticks
+};
+
+#endif
diff --git a/Application/PowerSwitch/Switch.cpp b/Application/PowerSwitch/Switch.cpp
new file mode 100644 (file)
index 0000000..ee10f61
--- /dev/null
@@ -0,0 +1,60 @@
+
+/**
+ * \brief simple class for port access for LEDs
+ *
+ * \file Switch.cpp
+ * \author Ebersold Andre
+ */
+
+//#include <avr/io.h>
+#include <Utils/StdTypes.h>
+#include <Abstract/ISwitch.h>
+#include <Platform/IParameterHandler.h>
+#include <Metadata/PowerswitchParamIds.h>
+#include "Switch.h"
+
+/**
+ * \brief constructor of LED access class
+ * \param PORT to access the LED
+ * \param DDR  to set the LED port pin to output
+ * \param PIN  to access the LED
+ */
+Switch::Switch(volatile uint8_t *PORT, volatile uint8_t *DDR, uint8_t PIN,IParameterHandler *_ph)
+: m_Port(PORT)
+, m_Ddr(DDR)
+, m_Pin(PIN)
+, m_Param(_ph)
+{
+   *(m_Ddr) |= (1 << m_Pin);
+}
+
+//! destructor
+Switch::~Switch()
+{
+}
+
+//! switches the LED on
+void Switch::set(State e)
+{
+    if (e == SwitchOn)
+    {
+      *(m_Port) |= (1 << m_Pin);
+    } else
+    {
+      *(m_Port) &= ~(1 << m_Pin);
+    }
+}
+
+
+//! toggles the LED
+void Switch::toggle(void)
+{
+   *(m_Port) ^= (1 << m_Pin);
+}
+
+ISwitch::State
+Switch::state(void) const
+{
+   return SwitchOff;
+}
+
diff --git a/Application/PowerSwitch/Switch.h b/Application/PowerSwitch/Switch.h
new file mode 100644 (file)
index 0000000..5d6e569
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * \brief simple class for port access for LEDs
+ *
+ * \file Led0.h
+ * \author Ebersold Andre
+ */
+
+/**
+ * \brief simple access class for LEDs
+ */
+class Switch : public ISwitch
+{
+   public:
+      /**
+       * \brief constructor of LED access class
+       * \param PORT to access the LED
+       * \param DDR  to set the LED port pin to output
+       * \param PIN  to access the LED
+       */
+      Switch(volatile uint8_t *PORT, volatile uint8_t *DDR, uint8_t PIN,IParameterHandler *);
+      //! destructor
+      ~Switch();
+
+      //! switches the LED on
+      virtual void set(State _eState);
+      //! switches the LED off
+      //! toggles the LED
+      virtual void toggle(void);
+      ///
+      virtual State state() const;
+   private:
+      Switch();
+      Switch( Switch const &src );
+      Switch& operator=(const Switch &src ) ;
+
+      //! pointer to the LED port
+      volatile uint8_t *m_Port;
+      //! pointer to the LED port's data direction register
+      volatile uint8_t *m_Ddr;
+      //! pin the LED is connected to
+      uint8_t m_Pin;
+      ///
+      IParameterHandler *m_Param;
+};
diff --git a/Application/PowerSwitch/main.cpp b/Application/PowerSwitch/main.cpp
new file mode 100644 (file)
index 0000000..6ede18c
--- /dev/null
@@ -0,0 +1,186 @@
+/**
+ * \brief simple application to test the C++ toolchain
+ *
+ * \file main.cc
+ * \author Andre Ebersold
+ */
+
+#include <Utils/StdTypes.h>
+#include <util/delay.h>
+
+#include <Abstract/IInterruptActivity.h>
+#include <Abstract/IProtocolLayer2.h>
+#include <Abstract/IUart.h>
+#include <Abstract/ISwitch.h>
+#include <Abstract/IEeprom.h>
+#include <Application/ITask.h>
+#include <AVR/AvrTimer0.h>
+#include <AVR/AvrTimer1.h>
+#include <AVR/AvrUart.h>
+#include <AVR/AvrEeprom.h>
+#include <Platform/IParameterHandler.h>
+#include <Metadata/PowerswitchParamIds.h>
+#include <Platform/PowerswitchParameterHandler.h>
+#include <Platform/PersistentStorage.h>
+#include <Communication/CommunicationHandler.h>
+
+
+#include <Drivers/NetString.h>
+#include "Led0.h"
+#include "Switch.h"
+#include "PowerswitchHandler.h"
+
+/**
+ * @brief the scheduler will still slice the execution
+ * flow. The whole cycle is now 40 ticks !
+ * 40 * 
+ * 250ns * 4 = 1us * 10 = 10 us. On fast devices.
+ *
+ * 16MHz / 8 / 256 = 100us each tick
+ *
+ */
+class Scheduler : public IInterruptActivity
+{
+  private:
+      enum TIME_SLOTS {
+              FIRST_TIME_SLOT        =  0,
+              BLOCK2_FIRST_TIME_SLOT =  1,
+              BLOCK3_FIRST_TIME_SLOT =  3,
+              LAST_TIME_SLOT         =  5,
+              TIME_SLOT_COUNT        =  5
+      };
+      enum ETASK_ID {
+              TASK1      = 0,
+              TASK2      = 1,
+              TASK3      = 2,
+              TASK_COUNT = 3
+      };
+      typedef struct Task_t {
+          TIME_SLOTS  m_FirstTimeslot;
+          ETASK_ID    m_NextTask;
+      } Task_type ;
+
+      static Task_type gTasks[TASK_COUNT];
+  public:
+    Scheduler(Led0 *_led,IProtocolLayer2 *_net,CommunicationHandler *_com,PowerswitchHandler *_mh
+                   ,ITask *_Storage
+                   )
+      : 
+              m_Led(_led)
+              , m_Netstring(_net)
+              , m_Com(_com)
+              , m_Powerswitch(_mh)
+             , m_Storage(_Storage)
+              , m_CurrentTimeslot(FIRST_TIME_SLOT)
+              , m_CurrentTask(TASK1)
+    {
+    }
+    // main entry point
+    void schedule()
+    {
+        waitForTimeslot();
+        m_Com->run();
+        switch (m_CurrentTask)
+        {
+            case TASK1:
+               //m_Adc->run();
+            break;
+            case TASK2:
+                m_Powerswitch->run();
+            break;
+            case TASK3:
+                m_Led->tick();
+               m_Storage->run();
+            break;
+            default:
+            ;
+        
+        }
+        m_CurrentTask = gTasks[m_CurrentTask].m_NextTask;
+    }
+    // called  by the interrupt timer handler
+    virtual void tick()
+    {
+            m_CurrentTimeslot = (m_CurrentTimeslot < LAST_TIME_SLOT)
+                                ? (TIME_SLOTS)(m_CurrentTimeslot+1) 
+                                : (FIRST_TIME_SLOT);
+            m_Netstring->tick();
+    }
+
+  private:
+    void waitForTimeslot( void )
+    {
+            /// prevent instant scheduling 
+            while (m_CurrentTimeslot  == gTasks[m_CurrentTask].m_FirstTimeslot )
+            {
+                ;
+            }
+            // beginning of the timeslot
+            while (m_CurrentTimeslot  != gTasks[m_CurrentTask].m_FirstTimeslot ) 
+            {
+                ;
+            }
+    }
+  private:
+    Led0                   *m_Led;
+    IProtocolLayer2        *m_Netstring;
+    CommunicationHandler   *m_Com;
+    PowerswitchHandler     *m_Powerswitch;
+    ITask                  *m_Storage;
+    volatile TIME_SLOTS     m_CurrentTimeslot;
+    ETASK_ID                m_CurrentTask;
+
+
+};
+
+Scheduler::Task_type Scheduler::gTasks[TASK_COUNT] = {
+    { FIRST_TIME_SLOT , TASK2 }
+  , { BLOCK2_FIRST_TIME_SLOT, TASK3 }
+  , { BLOCK3_FIRST_TIME_SLOT, TASK1 }
+};
+
+/**
+ * \brief Init database ....
+ */
+void init(IParameterHandler *m_Param)
+{
+}
+
+
+/**
+ * \brief main loop
+ */
+int main(void)
+{
+   PowerswitchParameterHandler gParam; 
+#if defined (__AVR_ATmega32U4__)
+   Led0                 led(&PORTC, &DDRC, PINB7,&gParam);
+#else
+   Led0                 led(&PORTB, &DDRB, PINB5,&gParam);
+#endif   
+   AvrUart              uart(IUart::BAUD_9600,IUart::PARITY_NONE,IUart::STB_ONE);
+   AvrEeprom            gEeprom;
+   NetString            netstring(&uart);
+   CommunicationHandler gCom(&netstring,&gParam);
+   PersistentStorage    gStorage(&gEeprom,&gParam);
+   PowerswitchHandler   motorH(&gParam);
+   Scheduler            sched(&led,&netstring,&gCom,&motorH,&gStorage);
+
+   uart.init();
+   netstring.init();
+
+   Timer0 lTimer(sched);
+   led.on();
+    _delay_ms(300);
+   led.off();
+    _delay_ms(300);
+
+   lTimer.init();
+   init(&gParam);
+   gEeprom.init();
+   while(1)
+   {
+      sched.schedule();
+   }
+}
diff --git a/Application/Scheduler/Scheduler.h b/Application/Scheduler/Scheduler.h
new file mode 100644 (file)
index 0000000..bc19cc7
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef __AVR_SCHEDULER_H__
+#define __AVR_SCHEDULER_H__
+
+class Scheduler : IInterruptActivity
+{
+  public:
+    Scheduler();
+    // main entry point
+    void schedule();
+    // called  by the interrupt timer handler
+    virtual tick();
+  private:
+};
+#endif
diff --git a/Application/ShutterCtrl/CMakeLists.txt b/Application/ShutterCtrl/CMakeLists.txt
new file mode 100644 (file)
index 0000000..647737e
--- /dev/null
@@ -0,0 +1,36 @@
+#####################################################################
+# simple AVR executable
+#####################################################################
+add_avr_executable(
+   shutterctrl
+   main.cpp
+   Led0.cpp
+   ShutterHandler.cpp
+   TouchScrHandler.cpp
+   )
+
+target_link_libraries(
+  shutterctrl-${AVR_MCU}.elf
+  avrHAL-${AVR_MCU}
+  avrDrivers-${AVR_MCU}
+  avrComm-${AVR_MCU}
+  avrSC-Ptf-${AVR_MCU}
+  avrShutterCtrlParameters-${AVR_MCU}
+)
+
+IF (${AVR_MCU} EQUAL "atmega328p")
+ SET(AVRPROG arduino)
+ SET(AVRPROG_MCU Atmega328p)
+ELSE(${AVR_MCU} EQUAL "atmega328p")
+ SET(AVRPROG avr109)
+ SET(AVRPROG_MCU m32u4)
+ENDIF(${AVR_MCU} EQUAL "atmega328p")
+
+add_custom_target(
+      flash_shutter
+      COMMAND
+      # avrdude -c arduino -P ${AVRDUDE_PORT} -p Atmega328p -b 57600 -Uflash:w:${CMAKE_CURRENT_BINARY_DIR}/dcmotor-${AVR_MCU}.hex:i
+      avrdude -c ${AVRPROG} -P ${AVRDUDE_PORT} -p ${AVRPROG_MCU} -b 57600 -Uflash:w:${CMAKE_CURRENT_BINARY_DIR}/dcmotor-${AVR_MCU}.hex:i
+      DEPENDS dcmotor-${AVR_MCU}.hex
+    )
+
diff --git a/Application/ShutterCtrl/Led0.cpp b/Application/ShutterCtrl/Led0.cpp
new file mode 100644 (file)
index 0000000..06df758
--- /dev/null
@@ -0,0 +1,81 @@
+/**
+ * \brief simple class for port access for LEDs
+ *
+ * \file Led0.cpp
+ * \author Ebersold Andre
+ */
+
+//#include <avr/io.h>
+#include <Utils/StdTypes.h>
+#include <Platform/IParameterHandler.h>
+#include <Metadata/ShutterCtrlParamIds.h>
+#include "Led0.h"
+
+/**
+ * \brief constructor of LED access class
+ * \param PORT to access the LED
+ * \param DDR  to set the LED port pin to output
+ * \param PIN  to access the LED
+ */
+Led0::Led0(volatile uint8_t *PORT, volatile uint8_t *DDR, uint8_t PIN,IParameterHandler *_ph)
+: m_Port(PORT)
+, m_Ddr(DDR)
+, m_Pin(PIN)
+, m_Counter(0)
+, m_Param(_ph)
+{
+  uint16_t cycle = 350;
+  _ph->writeValue(PID_LedCycle,cycle);
+   *(m_Ddr) |= (1 << m_Pin);
+}
+
+//! destructor
+Led0::~Led0()
+{
+}
+
+//! switches the LED on
+void Led0::on(void)
+{
+   *(m_Port) |= (1 << m_Pin);
+}
+
+//! switches the LED off
+void Led0::off(void)
+{
+   *(m_Port) &= ~(1 << m_Pin);
+}
+
+//! toggles the LED
+void Led0::toggle(void)
+{
+   *(m_Port) ^= (1 << m_Pin);
+}
+
+///
+void 
+Led0::setCycle(uint16_t _cycle)
+{
+    m_Param->writeValue(PID_LedCycle,_cycle);
+}
+///
+void 
+Led0::reloadCounter()
+{
+    uint16_t cycle = 100;
+    m_Param->readValue(PID_LedCycle,cycle);
+    m_Counter = cycle;
+}
+///
+void 
+Led0::tick()
+{
+    if (m_Counter > 0)
+    {
+        m_Counter--;
+    } else
+    {
+        toggle();
+        reloadCounter();
+    }
+}
diff --git a/Application/ShutterCtrl/Led0.h b/Application/ShutterCtrl/Led0.h
new file mode 100644 (file)
index 0000000..e8f4209
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+ * \brief simple class for port access for LEDs
+ *
+ * \file Led0.h
+ * \author Ebersold Andre
+ */
+
+/**
+ * \brief simple access class for LEDs
+ */
+class Led0
+{
+   public:
+      /**
+       * \brief constructor of LED access class
+       * \param PORT to access the LED
+       * \param DDR  to set the LED port pin to output
+       * \param PIN  to access the LED
+       */
+      Led0(volatile uint8_t *PORT, volatile uint8_t *DDR, uint8_t PIN,IParameterHandler *);
+      //! destructor
+      ~Led0();
+
+      //! switches the LED on
+      void on(void);
+      //! switches the LED off
+      void off(void);
+      //! toggles the LED
+      void toggle(void);
+      ///
+      void setCycle(uint16_t _cycle);
+      ///
+      void reloadCounter();
+      ///
+      void tick();
+   private:
+      Led0();
+      Led0( Led0 const &src );
+      Led0& operator=(const Led0 &src ) ;
+
+      //! pointer to the LED port
+      volatile uint8_t *m_Port;
+      //! pointer to the LED port's data direction register
+      volatile uint8_t *m_Ddr;
+      //! pin the LED is connected to
+      uint8_t m_Pin;
+      //! reset count
+      uint16_t m_Counter;
+      ///
+      IParameterHandler *m_Param;
+};
+
diff --git a/Application/ShutterCtrl/ShutterHandler.cpp b/Application/ShutterCtrl/ShutterHandler.cpp
new file mode 100644 (file)
index 0000000..b25b331
--- /dev/null
@@ -0,0 +1,103 @@
+#include "Utils/StdTypes.h"
+
+#include "Application/ITask.h"
+#include <Platform/IParameterHandler.h>
+
+#include <AVR/AvrTimer1.h>
+#include <Metadata/ShutterCtrlParamIds.h>
+#include "ShutterHandler.h"
+
+
+/**
+*
+*/
+Shutter::Shutter(volatile uint8_t *_port,volatile uint8_t *_ddr,uint8_t _pin)
+  : m_Port(_port),m_Ddr(_ddr),m_Pin(_pin)
+{
+   idle(); // Be sure, the signal is high
+   *(m_Ddr) |= _BV(m_Pin);
+   *(m_Ddr) |= _BV(m_Pin+1);
+}
+/**
+*
+*/
+void 
+Shutter::open()
+{
+  *m_Port &= ~_BV(m_Pin);
+}
+
+/**
+*
+*/
+void 
+Shutter::close()
+{
+  *m_Port &= ~_BV(m_Pin+1);
+}
+/**
+*
+*/
+void 
+Shutter::idle()
+{
+  *m_Port |= _BV(m_Pin);
+  *m_Port |= _BV(m_Pin+1);
+}
+
+
+
+
+ShutterHandler::ShutterHandler(IParameterHandler *_ph,Timer1 *_t1)
+ : m_Params(_ph),m_Counter(_t1)
+  ,m_Shutter1(&PORTD,&DDRD,PIN2)
+  ,m_Shutter2(&PORTD,&DDRD,PIN4)
+  ,m_Shutter3(&PORTD,&DDRD,PIN6)
+  ,m_Shutter4(&PORTB,&DDRB,PIN0)
+{
+  m_Shutters[0] = &m_Shutter1;
+  m_Shutters[1] = &m_Shutter2;
+  m_Shutters[2] = &m_Shutter3;
+  m_Shutters[3] = &m_Shutter4;
+  for (uint8_t i = 0 ; i < 4 ; ++i)
+         m_Shutters[i]-> idle();
+}
+
+void ShutterHandler::run()
+{
+    Uint8_t l_Mode;
+
+    m_Ticks = (m_Ticks < TICK_COUNT)
+              ? m_Ticks + 1
+              : 0;
+
+    m_Params->readValue(PID_Shutter1,l_Mode);
+    Shutter *shutter = m_Shutters[l_Mode & 0x03];
+    return ;
+    if ( m_Ticks == 0)
+    { // In case of closed loop mode compute correction
+      //updatePot0();
+        //m_MotorA.update();
+      switch (m_State) 
+      {
+          case 0:
+          shutter->open();
+          m_State++;
+          break;
+          case 1:
+          shutter->idle();
+          shutter->close();
+          m_State++;
+          break;
+          case 2:
+          shutter->idle();
+          m_State++;
+          break;
+          default:
+         l_Mode = (l_Mode + 1) & 0x03;
+          m_Params->writeValue(PID_Shutter1,l_Mode );
+          m_State = 0;
+          break;
+      } 
+    }
+}
diff --git a/Application/ShutterCtrl/ShutterHandler.h b/Application/ShutterCtrl/ShutterHandler.h
new file mode 100644 (file)
index 0000000..1c8a170
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef __SHUTTER_HANDLER_H__
+#define __SHUTTER_HANDLER_H__
+
+#define TICK_COUNT 3000
+
+
+class Shutter 
+{
+  public:
+    /**
+     *
+     */
+    Shutter(volatile uint8_t *_port,volatile uint8_t *_ddr,uint8_t _pin);
+    /**
+     *
+     */
+    void open();
+    /**
+     *
+     */
+    void close();
+    /**
+     *
+     */
+    void idle();
+
+  private:
+    //! pointer to the LED port
+    volatile uint8_t *m_Port;
+    //! pointer to the LED port's data direction register
+    volatile uint8_t *m_Ddr;
+    //! pin the LED is connected to
+    uint8_t m_Pin;
+
+};
+
+
+class ShutterHandler : public ITask
+{
+  public:
+    /// Default constructor
+    ShutterHandler(IParameterHandler *_ph,Timer1 *_t1);
+
+    virtual void run();
+  private:
+    IParameterHandler *m_Params;
+    Timer1            *m_Counter;
+    uint16_t           m_Ticks;
+    uint8_t            m_State; // ShutterHandlerState
+    Shutter            m_Shutter1;
+    Shutter            m_Shutter2;
+    Shutter            m_Shutter3;
+    Shutter            m_Shutter4;
+    Shutter           *m_Shutters[4];
+};
+#endif
diff --git a/Application/ShutterCtrl/TouchScrHandler.cpp b/Application/ShutterCtrl/TouchScrHandler.cpp
new file mode 100644 (file)
index 0000000..75429e7
--- /dev/null
@@ -0,0 +1,42 @@
+#include <Utils/StdTypes.h>
+#include <util/delay.h>
+
+#include <Abstract/IProtocolLayer2.h>
+#include <Abstract/IUart.h>
+#include <Abstract/ISPI.h>
+#include <Application/ITask.h>
+#include <AVR/AvrSpi.h>
+#include <Platform/IParameterHandler.h>
+#include <Metadata/ShutterCtrlParamIds.h>
+#include <Platform/ShutterCtrlParameterHandler.h>
+#include <Communication/CommunicationHandler.h>
+
+
+#include <Drivers/XPT2046_Touchscreen.h>
+#include "TouchScrHandler.h"
+
+    
+TouchScreenHandler::TouchScreenHandler(XPT2046Touchscreen *_tc, IParameterHandler *_param)
+  : m_Tc(_tc),m_Param(_param) ,m_Counter(0)
+{
+}
+
+void 
+TouchScreenHandler::run()
+{
+  if ((m_Counter % 200) == 0)
+  {
+    if (m_Tc->isTouched())
+    {
+      // Read Position and update X / Y position
+      TSPoint p = m_Tc->getPoint();
+      m_Param->writeValue(PID_Px,static_cast<uint16_t>(p.x));
+      m_Param->writeValue(PID_Py,static_cast<uint16_t>(p.y));
+      m_Param->writeValue(PID_Pz,static_cast<uint16_t>(p.z));
+    }
+  } else
+  {
+    m_Counter++;
+  }
+}
diff --git a/Application/ShutterCtrl/TouchScrHandler.h b/Application/ShutterCtrl/TouchScrHandler.h
new file mode 100644 (file)
index 0000000..8df11b4
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef __TOUCHSCRHANDLER_H__
+#define __TOUCHSCRHANDLER_H__
+
+class TouchScreenHandler : virtual public ITask
+{
+  public:
+    TouchScreenHandler(XPT2046Touchscreen *_tc, IParameterHandler *_param);
+
+    virtual void run();
+  private:
+   XPT2046Touchscreen *m_Tc;
+   IParameterHandler  *m_Param;
+   uint32_t            m_Counter;
+};
+
+#endif
diff --git a/Application/ShutterCtrl/main.cpp b/Application/ShutterCtrl/main.cpp
new file mode 100644 (file)
index 0000000..e0ee6d3
--- /dev/null
@@ -0,0 +1,218 @@
+/**
+ * \brief simple application to test the C++ toolchain
+ *
+ * \file main.cc
+ * \author Andre Ebersold
+ */
+
+#include <Utils/StdTypes.h>
+#include <util/delay.h>
+
+#include <Abstract/IInterruptActivity.h>
+#include <Abstract/IProtocolLayer2.h>
+#include <Abstract/IUart.h>
+#include <Abstract/IAdc.h>
+#include <Abstract/IEeprom.h>
+#include <Abstract/ISPI.h>
+#include <Application/ITask.h>
+#include <AVR/AvrTimer0.h>
+#include <AVR/AvrTimer1.h>
+#include <AVR/AvrUart.h>
+#include <AVR/AvrAdc.h>
+#include <AVR/AvrEeprom.h>
+#include <AVR/AvrSpi.h>
+//#include <AVR/AvrPwm.h>
+#include <Platform/IParameterHandler.h>
+#include <Metadata/ShutterCtrlParamIds.h>
+#include <Platform/ShutterCtrlParameterHandler.h>
+#include <Platform/PersistentStorage.h>
+#include <Communication/CommunicationHandler.h>
+
+
+#include <Drivers/NetString.h>
+#include <Drivers/Ili9341.h>
+#include <Drivers/XPT2046_Touchscreen.h>
+#include "Led0.h"
+
+#include "TouchScrHandler.h"
+#include "ShutterHandler.h"
+
+/**
+ * @brief the scheduler will still slice the execution
+ * flow. The whole cycle is now 40 ticks !
+ * 40 * 
+ * 250ns * 4 = 1us * 10 = 10 us. On fast devices.
+ *
+ * 16MHz / 8 / 256 = 100us each tick
+ *
+ */
+class Scheduler : public IInterruptActivity
+{
+  private:
+      enum TIME_SLOTS {
+              FIRST_TIME_SLOT        =  0,
+              BLOCK2_FIRST_TIME_SLOT =  1,
+              BLOCK3_FIRST_TIME_SLOT =  3,
+              LAST_TIME_SLOT         =  5,
+              TIME_SLOT_COUNT        =  5
+      };
+      enum ETASK_ID {
+              TASK1      = 0,
+              TASK2      = 1,
+              TASK3      = 2,
+              TASK_COUNT = 3
+      };
+      typedef struct Task_t {
+          TIME_SLOTS  m_FirstTimeslot;
+          ETASK_ID    m_NextTask;
+      } Task_type ;
+
+      static Task_type gTasks[TASK_COUNT];
+  public:
+    Scheduler(Led0 *_led,IProtocolLayer2 *_net
+                   ,CommunicationHandler *_com
+                   ,ShutterHandler *_mh
+                   ,ITask *_Storage
+                   ,TouchScreenHandler *_tch
+                   )
+      : 
+              m_Led(_led)
+              , m_Netstring(_net)
+              , m_Com(_com)
+              , m_Shutter(_mh)
+             , m_Storage(_Storage)
+             , m_Tch(_tch)
+              , m_CurrentTimeslot(FIRST_TIME_SLOT)
+              , m_CurrentTask(TASK1)
+    {
+    }
+    // main entry point
+    void schedule()
+    {
+        waitForTimeslot();
+        m_Com->run();
+        switch (m_CurrentTask)
+        {
+            case TASK1:
+               //m_Adc->run();
+               m_Tch->run();
+            break;
+            case TASK2:
+                m_Shutter->run();
+            break;
+            case TASK3:
+                //m_Led->tick();
+                m_Storage->run();
+            break;
+            default:
+            ;
+        
+        }
+        m_CurrentTask = gTasks[m_CurrentTask].m_NextTask;
+    }
+    // called  by the interrupt timer handler
+    virtual void tick()
+    {
+            m_CurrentTimeslot = (m_CurrentTimeslot < LAST_TIME_SLOT)
+                                ? (TIME_SLOTS)(m_CurrentTimeslot+1) 
+                                : (FIRST_TIME_SLOT);
+            m_Netstring->tick();
+    }
+
+  private:
+    void waitForTimeslot( void )
+    {
+            /// prevent instant scheduling 
+            while (m_CurrentTimeslot  == gTasks[m_CurrentTask].m_FirstTimeslot )
+            {
+                ;
+            }
+            // beginning of the timeslot
+            while (m_CurrentTimeslot  != gTasks[m_CurrentTask].m_FirstTimeslot ) 
+            {
+                ;
+            }
+    }
+  private:
+    Led0                   *m_Led;
+    IProtocolLayer2        *m_Netstring;
+    CommunicationHandler   *m_Com;
+    ShutterHandler         *m_Shutter;
+    ITask                  *m_Storage;
+    TouchScreenHandler     *m_Tch;
+    volatile TIME_SLOTS     m_CurrentTimeslot;
+    ETASK_ID                m_CurrentTask;
+
+
+};
+
+Scheduler::Task_type Scheduler::gTasks[TASK_COUNT] = {
+    { FIRST_TIME_SLOT , TASK2 }
+  , { BLOCK2_FIRST_TIME_SLOT, TASK3 }
+  , { BLOCK3_FIRST_TIME_SLOT, TASK1 }
+};
+
+/**
+ * \brief Init database ....
+ */
+void init(IParameterHandler *m_Param)
+{
+//   m_Param->writeValue(PID_MotorPwm,(uint8_t)60);
+//   m_Param->writeValue(PID_CPR,static_cast<Uint16_t >(500));
+}
+
+
+/**
+ * \brief main loop
+ */
+int main(void)
+{
+   Timer1     lCounter;
+   ShutterCtrlParameterHandler gParam; 
+   Led0                 led(&PORTB, &DDRB, PINB5,&gParam);
+   AvrUart              uart(IUart::BAUD_9600,IUart::PARITY_NONE,IUart::STB_ONE);
+   AvrEeprom            gEeprom;
+   AvrSpi               gSpi;
+   NetString            netstring(&uart);
+   CommunicationHandler gCom(&netstring,&gParam);
+   PersistentStorage    gStorage(&gEeprom,&gParam);
+   ShutterHandler       shutterH(&gParam,&lCounter);
+   XPT2046Touchscreen   tc(&gSpi,PINC2);
+   TouchScreenHandler   tch(&tc,&gParam);
+   Scheduler            sched(&led,&netstring,&gCom,&shutterH,&gStorage,&tch);
+
+   Ili9341                ili(&gSpi);
+
+   //ili.fillrect(10,60,50,50,0x07E0);
+
+   uart.init();
+   netstring.init();
+   ili.init();
+   //ili.clear(ILI9341_NAVY);
+   ili.clear(0x0);
+   ili.setRotation(0);
+   ili.drawhline(5,5,225,ILI9341_WHITE);
+   ili.drawhline(5,315,225,ILI9341_WHITE);
+   ili.drawvline(5,5,310,ILI9341_GREEN);
+   ili.drawvline(230,5,310,ILI9341_GREEN);
+   ili.fillrect(10,10,50,50,0xF800);
+   ili.fillrect(10,70,50,50,ILI9341_GREEN);
+   ili.fillrect(10,130,50,50,ILI9341_CYAN);
+   ili.fillrect(10,190,50,50,ILI9341_ORANGE);
+   ili.fillrect(10,250,50,50,ILI9341_PINK);
+   Timer0 lTimer(sched);
+#if 0 
+   led.on();
+    _delay_ms(300);
+   led.off();
+    _delay_ms(300);
+#endif
+   lTimer.init();
+   init(&gParam);
+   gEeprom.init();
+   while(1)
+   {
+      sched.schedule();
+      //ili.drawhline(15,15,50,ILI9341_RED);
+   }
+}
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1c74b10
--- /dev/null
@@ -0,0 +1,51 @@
+cmake_minimum_required(VERSION 2.8)
+
+
+##########################################################################
+# tools to beused for programming the AVR
+##########################################################################
+set(AVR_UPLOADTOOL avrdude)
+set(AVR_PROGRAMMER arduino)
+set(AVR_UPLOADTOOL_PORT /dev/ttyS5)
+set(AVR_UPLOADTOOL_BAUDRATE 57600)
+
+##########################################################################
+# AVR and fuses needs to be set
+##########################################################################
+#set(AVR_MCU atmega32)
+set(AVR_MCU atmega328p CACHE STRING "AVR MCU type choose between atmega32_p or atmega32 atmega328p")
+set(AVR_H_FUSE 0xd9)
+set(AVR_L_FUSE 0xc3)
+
+### END TOOLCHAIN SETUP AREA #############################################
+
+include(${CMAKE_CURRENT_SOURCE_DIR}/rules/gcc-avr-generic.cmake)
+
+PROJECT(tinyapp)
+
+include(${CMAKE_CURRENT_SOURCE_DIR}/rules/gcc-avr-common.cmake)
+
+IF(NOT CMAKE_BUILD_TYPE)
+  SET(CMAKE_BUILD_TYPE "Debug")
+ENDIF(NOT CMAKE_BUILD_TYPE)
+
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
+
+SUBDIRS(HAL Application Platform Communication Metadata)
+
+INCLUDE_DIRECTORIES("${tinyapp_SOURCE_DIR}")
+INCLUDE_DIRECTORIES("${tinyapp_SOURCE_DIR}/HAL")
+INCLUDE_DIRECTORIES("${tinyapp_BINARY_DIR}")
+INCLUDE_DIRECTORIES("${tinyapp_BINARY_DIR}/Application")
+
+
+
+OPTION(TINYAPP_LED0        "Build Led application" ON)
+OPTION(TINYAPP_DC_MOTOR    "Build DC Motor application" OFF)
+OPTION(TINYAPP_SHUTTERCTRL "Build Shutter Handler application" ON)
+
+SET(AVRDUDE_PORT "/dev/ttyS3" CACHE STRING "Avrdude port to use for flashing")
+
+# new way
+#CONFIGURE_FILE(${antcc_SOURCE_DIR}/src/antcc/config.h.cmake
+#      ${antcc_BINARY_DIR}/src/antcc/config.h)
diff --git a/Communication/CMakeLists.txt b/Communication/CMakeLists.txt
new file mode 100644 (file)
index 0000000..bc83acd
--- /dev/null
@@ -0,0 +1,8 @@
+#####################################################################
+# simple AVR library
+#####################################################################
+add_avr_library(
+    avrComm
+    CommunicationHandler.cpp
+   )
+
diff --git a/Communication/CommunicationHandler.cpp b/Communication/CommunicationHandler.cpp
new file mode 100644 (file)
index 0000000..587de6d
--- /dev/null
@@ -0,0 +1,145 @@
+
+#include <Utils/StdTypes.h>
+#include <stdlib.h> // for itoa
+#include <Abstract/IProtocolLayer2.h>
+#if 0
+#include <Metadata/DCMotorParamIds.h> // To be removed
+#endif
+#include <Platform/IParameterHandler.h>
+#include <Communication/CommunicationHandler.h>
+
+CommunicationHandler::CommunicationHandler(IProtocolLayer2 *_l2,IParameterHandler *_p)
+    : m_L2(_l2), m_Params(_p)
+{
+}
+
+void
+CommunicationHandler::run()
+{
+    const Uint8_t len  = m_L2->getRxSize();
+    const uint8_t *msg = m_L2->receiveMsg();
+    if ( msg != 0)
+    {
+        switch (msg[0])
+        {
+#if 0
+            case 'G':
+              {
+                  uint16_t nv = 650;
+                  m_Params->writeValue(PID_LedCycle,nv);
+                  m_L2->setTxMsg((const uint8_t *)"OK Go",5);
+              }
+              break;
+            case 'D':
+              m_L2->setTxMsg((const uint8_t *)"OK Dir",6);
+              break;
+            case 'S':
+              {
+                  uint16_t nv = 150;
+                  m_Params->writeValue(PID_LedCycle,nv);
+                  m_L2->setTxMsg((const uint8_t *)"OK SPEED",8);
+              }
+              break;
+            case 'R':
+              {
+                  uint16_t nv = 0;
+                  parse_num(msg+1,len -1,nv);
+                  m_Params->writeValue(PID_LedCycle,nv);
+                  m_L2->setTxMsg((const uint8_t *)"OK RPM",6);
+              }
+              break;
+#endif
+            case 'M':
+              {
+                  parse_msg(msg,len ,IParameterHandler::TYPE_U16);
+              }
+              break;
+            case 'F':
+              {
+                  parse_msg(msg,len ,IParameterHandler::TYPE_FLOAT);
+              }
+              break;
+            default:
+              m_L2->setTxMsg((const uint8_t *)"KO MSG",10);
+        }
+        m_L2->transmitMsg();
+    } 
+}
+
+#define OUTPUT_BUFFER_SIZE 16 
+void 
+CommunicationHandler::parse_msg(const Uint8_t *_msg,const Uint8_t len,IParameterHandler::eParameterType _eType)
+{
+    uint16_t nv  = 0;
+    uint16_t val = 0;
+    uint8_t  pos = 0;
+
+    parse_num(_msg+1,len -1,nv);
+    if ( nv < 0xA)
+    {
+        pos = 2;
+    } else {
+        pos = 3;
+    }
+    if ( _msg[pos] == '=' )
+    {
+        if (_eType == IParameterHandler::TYPE_FLOAT)
+        {
+            Float32_t result;
+            result = atof((const char *)(_msg+1+pos));
+            m_Params->writeValue(nv,result);
+        }
+        else 
+        {
+            parse_num(_msg+1+pos,len - 1 - pos,val);
+            m_Params->writeValue(nv,val);
+        }
+        m_L2->setTxMsg((const uint8_t *)"OK\r\n",4);
+    } else if (_msg[pos] == '?')
+    {
+        char l_OutBuffer[OUTPUT_BUFFER_SIZE];
+        for (Uint8_t i = 0 ; i < OUTPUT_BUFFER_SIZE; i++) l_OutBuffer[i] = '\0';
+        if (_eType == IParameterHandler::TYPE_FLOAT)
+        {
+            Float32_t fval;
+            m_Params->readValue(nv,fval);
+            //dtostre(fval,(char *)l_OutBuffer,4,0);
+            dtostrf(fval,8,4,(char *)l_OutBuffer);
+        } else
+        {
+            m_Params->readValue(nv,val);
+            itoa(val,(char *)l_OutBuffer,10);
+        }
+        nv = 0;
+        while ( l_OutBuffer[nv] != '\0' && nv < OUTPUT_BUFFER_SIZE) nv++;
+        l_OutBuffer[nv++] = '\r';
+        l_OutBuffer[nv++] = '\n';
+        m_L2->setTxMsg((const uint8_t *)l_OutBuffer,nv);
+    } else
+    {
+        m_L2->setTxMsg((const uint8_t *)"KO\r\n",4);
+    }
+}
+
+void 
+CommunicationHandler::parse_num(const Uint8_t *_msg,const Uint8_t len,Uint16_t &_out)
+{
+    Uint8_t chr = 0x00;
+    Uint8_t pchr = 0x00;
+    _out = 0;
+    Uint8_t i = len;
+    while ((*_msg) != 0x00 &&  i--)
+    {
+        chr = *_msg - 0x30;
+        if (chr < 0x0A)
+        {
+          _out *= 0x0A;
+          _out += chr;
+        } else if (pchr < 0x0A )
+        {
+          break;
+        }
+        pchr = chr;
+        _msg++;
+    }
+}
diff --git a/Communication/CommunicationHandler.h b/Communication/CommunicationHandler.h
new file mode 100644 (file)
index 0000000..2d7ba92
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __COMMUNICATIONHANDLER_H__
+#define  __COMMUNICATIONHANDLER_H__
+
+class CommunicationHandler 
+/* : public ITask */
+{
+    public:
+        CommunicationHandler(IProtocolLayer2 *_l2,IParameterHandler *_p);
+
+        virtual void run();
+    private:
+        void parse_msg(const Uint8_t *_msg,const Uint8_t len,IParameterHandler::eParameterType _eT);
+        ///
+        void parse_num(const Uint8_t *_msg,const Uint8_t len,  Uint16_t &_out);
+    private:
+        IProtocolLayer2   *m_L2;
+        IParameterHandler *m_Params;
+};
+#endif
diff --git a/Communication/ICommunication.h b/Communication/ICommunication.h
new file mode 100644 (file)
index 0000000..cfec6bd
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef __ICOMMUNICATION_H__
+#define __ICOMMUNICATION_H__
+
+/**
+ * Commuinication application interface to
+ * be used by the application to send
+ * received messages over the selected 
+ * physical interface. (Eg: the physical layer
+ * cannot be changed dynamically.
+ *
+ */
+class  ICommunication
+{
+  public:
+
+    ICommuncation() = 0;
+
+    /**
+     * @brief transmit the message
+     * to the physical interface
+     */
+    virtual void transmit() = 0;
+    /**
+     * @brief receive message from
+     * thephysical layer.
+     */
+    virtual void receive() = 0;
+    /**
+     * @brief retrieve message received.
+     *
+     */
+    virtual const uint8_t *getPayload( )   const = 0;
+
+    virtual const uint8_t getPayloadSize() const = 0;
+    /**
+     * @brief set message to be sent
+     */
+    virtual void setPayload(uint8_t *_msg,const uint_8 _length) = 0;
+};
+
+#endif
diff --git a/Communication/ModbusSerial/ModbusSerial.h b/Communication/ModbusSerial/ModbusSerial.h
new file mode 100644 (file)
index 0000000..1b574d2
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef __MODBUSERIAL_H__
+#ifndef __MODBUSERIAL_H__
+
+/**
+ * @brief Modbus application layer
+ * implementation.
+ *
+ */
+class ModbusSerial : public ICommunication
+{
+  public:
+
+    /**
+     * @brief constructor....
+     * @param Layer2 protocol stack Rs485
+     * @param Error handler ?
+     */
+    ModbusSerial();
+    /**
+     * @brief transmit the message
+     * to the physical interface
+     */
+    virtual void transmit() ;
+    /**
+     * @brief receive message from
+     * thephysical layer.
+     */
+    virtual void receive() ;
+    /**
+     * @brief retrieve message received.
+     *
+     */
+    virtual const uint8_t *getPayload( )   const ;
+
+    /**
+     * @brief return payload size of
+     * the received message
+     */
+    virtual const uint8_t getPayloadSize() const ;
+    /**
+     * @brief set message to be sent
+     */
+    virtual void setPayload(uint8_t *_msg,const uint_8 _length) ;
+
+};
+
+#endif
diff --git a/HAL/AVR/328p_Pwm.cpp b/HAL/AVR/328p_Pwm.cpp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/HAL/AVR/328p_Timer0.cpp b/HAL/AVR/328p_Timer0.cpp
new file mode 100644 (file)
index 0000000..5a88bbc
--- /dev/null
@@ -0,0 +1,63 @@
+
+#include <avr/interrupt.h>
+
+#include "Abstract/IInterruptActivity.h"
+#include "AVR/AvrTimer0.h"
+
+
+Timer0*  Timer0::gTimer0 = 0;
+
+ISR(TIMER0_OVF_vect)
+{
+  Timer0::gTimer0->process_interrupt();
+  //TCNT0 = 0x01;
+  TIFR0 &= ~(1<<TOV0);
+}
+
+
+Timer0::Timer0(IInterruptActivity &_int)
+ : m_Interrupt(&_int)
+{
+  Timer0::gTimer0 = this;
+}
+#define MY_COUNT_FROM 0xF8
+void 
+Timer0::init()
+{
+    cli();
+    // Enable Overflow Interrupt Enable
+    TIMSK0 = (1<<TOIE0);
+    // Set Control Register 16MHz / 1024 = 15,625KHz
+    // Tick = 1/15,625KHz = 64us
+    // So overflow every 16ms
+    //TCCR0B = (1<<CS00) | (1<<CS02); 
+    //Division / 8 
+    TCCR0B = (0<<CS00) | (1<<CS01); 
+    //TCCR0A = (1<< WGM01); 
+    TCCR0A |= (3<< WGM00);
+    // Initialize counter
+    TCNT0 = MY_COUNT_FROM;
+    PRR   &= ~(1<<PRTIM0);
+    initT2();
+    sei();
+}
+
+void 
+Timer0::initT2()
+{
+    //Division / 8 
+    TCCR2B = (0<<CS00) | (1<<CS01); 
+    //TCCR0A = (1<< WGM01); 
+    TCCR2A |= (3<< WGM00);
+    // Initialize counter
+    TCNT2 = MY_COUNT_FROM;
+    PRR   &= ~(1<<PRTIM2);
+}
+
+///
+void 
+Timer0::process_interrupt()
+{
+    m_Interrupt->tick();
+}
+
diff --git a/HAL/AVR/32u4_Pwm.cpp b/HAL/AVR/32u4_Pwm.cpp
new file mode 100644 (file)
index 0000000..bb55a0f
--- /dev/null
@@ -0,0 +1,63 @@
+
+#include "HAL/Abstract/IPwm.h"
+
+
+#if 0
+static Motor::pinMapping_t GmA = {PINB7,PINB6,0};
+
+  , m_MotorA(&OCR0A,&TCCR0A,GmA,COM0A0,_p) 
+#if ! defined (__AVR_ATmega32U4__)
+  , m_MotorB(&OCR2B,&TCCR2A,GmB,COM2B0,_p)
+#endif
+#endif
+
+#define USE_T1 1
+///
+AvrPwm::AvrPwm() 
+       : IPwm()
+{
+  _init();
+}
+
+void AvrPwm::_init()
+{
+#ifdef USE_T1
+    TCCR1A |= (3 << WGM10);
+    OCR1C   = 150;
+
+    TCCR1A |= (2 << COM1C0);
+    TCCR0A &= ~(3 << COM0A0);
+#else
+    TCCR1B &= ~(7<<CS00); // Disable Clock for Timer 1
+    TCCR1A &= ~(3 << WGM10);
+    TCCR0A |= (2 << COM0A0);
+#endif
+}
+
+
+/// From Interface
+void
+AvrPwm::enable(const Bool_t _OnOff) const 
+{
+}
+
+
+/// From Interface
+void
+AvrPwm::setFreq(Uint16_t freq) const
+{
+}
+
+
+/// From Interface
+void
+AvrPwm::setDutyCycle(const Uint8_t _d) const
+{
+#ifdef USE_T1
+    OCR1C =   (4 * _d);
+#else
+    OCR0A = _d;
+#endif
+}
+
+
diff --git a/HAL/AVR/32u4_Timer0.cpp b/HAL/AVR/32u4_Timer0.cpp
new file mode 100644 (file)
index 0000000..ccabee6
--- /dev/null
@@ -0,0 +1,68 @@
+#include <avr/interrupt.h>
+
+#include "Abstract/IInterruptActivity.h"
+#include "AVR/AvrTimer0.h"
+
+
+Timer0*  Timer0::gTimer0 = 0;
+
+ISR(TIMER0_OVF_vect)
+{
+  Timer0::gTimer0->process_interrupt();
+  TIFR0 &= ~(1<<TOV0);
+}
+
+
+Timer0::Timer0(IInterruptActivity &_int)
+ : m_Interrupt(&_int)
+{
+  Timer0::gTimer0 = this;
+}
+#define MY_COUNT_FROM 0xF8
+void 
+Timer0::init()
+{
+    cli();
+    // Enable Overflow Interrupt Enable
+    TIMSK0 = (1<<TOIE0);
+    // Set Control Register 16MHz / 1024 = 15,625KHz
+    // Tick = 1/15,625KHz = 64us
+    // So overflow every 16ms
+    //TCCR0B = (1<<CS00) | (1<<CS02); 
+    //Division / 8 
+    TCCR0B = (0<<CS00) | (1<<CS01); 
+#if 1
+    TCCR0A |= (3<< WGM00);
+#else
+    //TCCR0A = (1<< WGM01); 
+#endif
+    // Initialize counter
+    TCNT0 = MY_COUNT_FROM;
+    PRR0   &= ~(1<<PRTIM0);
+    initT2();
+    sei();
+}
+
+void 
+Timer0::initT2()
+{
+#if defined (__AVR_ATmega32U4__)
+    PRR0   &= ~(1<<PRTIM0);
+#else
+    //Division / 8 
+    TCCR2B = (0<<CS00) | (1<<CS01); 
+    //TCCR0A = (1<< WGM01); 
+    TCCR2A |= (3<< WGM00);
+    // Initialize counter
+    TCNT2 = MY_COUNT_FROM;
+    PRR   &= ~(1<<PRTIM2);
+#endif
+}
+
+///
+void 
+Timer0::process_interrupt()
+{
+    m_Interrupt->tick();
+}
+
diff --git a/HAL/AVR/AvrAdc.cpp b/HAL/AVR/AvrAdc.cpp
new file mode 100644 (file)
index 0000000..cb7d1d7
--- /dev/null
@@ -0,0 +1,63 @@
+
+#include <Utils/StdTypes.h>
+
+#include <Abstract/IAdc.h>
+#include <Application/ITask.h>
+#include <AVR/AvrAdc.h>
+
+
+AvrADC::AvrADC()
+  : m_Value(0),m_Channel(0),m_State(ADC_IDLE)
+{
+  init();
+}
+
+void 
+AvrADC::init()
+{
+  // Select Vref = AVcc
+  ADMUX |= (1<<REFS0);
+
+  // Set prescaller to 128 and enable ADC
+  ADCSRA |= (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0) |(1<<ADEN) ; 
+}
+
+/**
+*
+*/
+void 
+AvrADC::run()
+{
+  switch (m_State)
+  {
+    case ADC_IDLE:
+      m_State = ADC_START;
+      break;
+    case ADC_START:
+      ADMUX = (ADMUX &  0xF0) | (m_Channel & 0x0F);
+      // Start single conversion mode
+      ADCSRA |= (1<<ADSC);
+      m_State = ADC_CONVERTING;
+      break;
+    case ADC_CONVERTING:
+      if ( !(ADCSRA & (1<<ADSC) ) ) 
+      {
+        // Conversion done
+        m_Value = ADC;
+        m_State = ADC_START;
+      }
+      break;
+    default:
+      m_State = ADC_IDLE;  
+
+  };
+}
+
+/**
+*
+*/
+Uint16_t 
+AvrADC::read(Uint8_t _channel) const
+{
+  return read();
+}
diff --git a/HAL/AVR/AvrAdc.h b/HAL/AVR/AvrAdc.h
new file mode 100644 (file)
index 0000000..82736ea
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef AVR_ADC_H__
+#define AVR_ADC_H__
+
+/**
+ * \brief Adc interface is responsible to continously read 
+ * the ADC value. Not that read value will return an already
+ * converted value.
+ *
+ *
+ */
+class AvrADC  : public virtual IAdc , public virtual ITask
+{
+
+  private:
+    enum _AdcState {ADC_IDLE, ADC_START,ADC_CONVERTING, ADC_READ};
+  public:
+    AvrADC();
+
+    void init();
+    /**
+     *
+     */
+    virtual void run();
+
+    /**
+     *
+     */
+    virtual Uint16_t read(const Uint8_t) const; 
+    /**
+     *
+     */
+    Uint16_t read() const { return m_Value; };
+  private:
+    Uint16_t  m_Value;
+    Uint8_t   m_Channel;
+    _AdcState m_State;
+};
+
+#endif
diff --git a/HAL/AVR/AvrEeprom.cpp b/HAL/AVR/AvrEeprom.cpp
new file mode 100644 (file)
index 0000000..cd6042f
--- /dev/null
@@ -0,0 +1,50 @@
+#include <Utils/StdTypes.h>
+
+#include <Abstract/IEeprom.h>
+#include <AVR/AvrEeprom.h>
+
+
+AvrEeprom::AvrEeprom()
+{
+}
+
+
+void
+AvrEeprom::init()
+{
+}
+
+/// Is eeprom busy, might be of interest, as eeprom access is performed through
+/// SPI 
+Bool_t 
+AvrEeprom::isBusy() 
+{
+    return EECR  & _BV(EEPE);
+}
+
+/// read values from Eeprom
+void 
+AvrEeprom::read(const Uint16_t _addr,const Uint16_t _len,Uint8_t *_dest)
+{
+    // Not sure  if this is a good idea
+    while (isBusy() ) ; 
+    EEAR = _addr;
+    EECR |= _BV(EERE);
+    *_dest = EEDR;
+}
+
+/// Interesting that eeprom is written page wise
+void
+AvrEeprom::writePage(const Uint8_t pageCount,const Uint8_t _Offset,const Uint8_t byteCount,Uint8_t *_data)
+{
+    // Not sure  if this is a good idea
+    while (isBusy() ) ; 
+    //
+    EEAR = (16 * pageCount) + _Offset;
+    EEDR = _data[0];
+    // Start Programming Sequence
+    EECR |= _BV(EEMPE);
+    EECR |= _BV(EEPE);
+}
+
+
diff --git a/HAL/AVR/AvrEeprom.h b/HAL/AVR/AvrEeprom.h
new file mode 100644 (file)
index 0000000..0f6841e
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef AVR_EEPROM_H__
+#define AVR_EEPROM_H__
+
+/**
+ *
+ *
+ */
+class AvrEeprom : public IEeprom
+{
+    public:
+        ///
+        AvrEeprom();
+
+        /// 
+        virtual void init();
+
+        /// Is eeprom busy, might be of interest, as eeprom access
+        ///
+        virtual Bool_t isBusy();
+
+        /// read values from Eeprom
+        virtual void read( const Uint16_t _addr
+                         , const Uint16_t _len
+                         , Uint8_t *_dest);
+
+        /// Interesting that eeprom is written page wise
+        virtual void writePage( const Uint8_t pageCount
+                              , const Uint8_t _Offset
+                              , const Uint8_t byteCount
+                              , Uint8_t *_data);
+};
+
+
+#endif
diff --git a/HAL/AVR/AvrInterrupt.h b/HAL/AVR/AvrInterrupt.h
new file mode 100644 (file)
index 0000000..674616c
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef __AVRINTERRUPT_H__
+
+class AvrInterrupt
+{
+  public:
+    AvrInterrupt(IInterruptActivity *);
+
+    /**
+     * Initialize timer so that a scheduling
+     * will occure every 500us
+     */
+    void init();
+  private:
+};
+#endif
diff --git a/HAL/AVR/AvrPwm.cpp b/HAL/AVR/AvrPwm.cpp
new file mode 100644 (file)
index 0000000..8a81bcd
--- /dev/null
@@ -0,0 +1,11 @@
+#include <avr/interrupt.h>
+
+#include "Utils/StdTypes.h"
+#include "HAL/Abstract/IPwm.h"
+#include "AVR/AvrPwm.h"
+
+#if defined (__AVR_ATmega32U4__)
+#include "32u4_Pwm.cpp"
+#else
+#include "328p_Pwm.cpp"
+#endif
diff --git a/HAL/AVR/AvrPwm.h b/HAL/AVR/AvrPwm.h
new file mode 100644 (file)
index 0000000..27a19b8
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef AVR_PWM_H__
+#define AVR_PWM_H__
+
+/**
+ *
+ *
+ */
+//template <typename _ioTimer>
+class AvrPwm : public IPwm
+{
+  public:
+    ///
+    AvrPwm();
+
+    /// From Interface
+    virtual void enable(const Bool_t _OnOff) const;
+    
+    /// From Interface
+    virtual void setFreq(Uint16_t freq) const;
+
+    /// From Interface
+    virtual void setDutyCycle(const Uint8_t _OnOff) const;
+  private:
+    void _init();
+};
+#endif
diff --git a/HAL/AVR/AvrSpi.cpp b/HAL/AVR/AvrSpi.cpp
new file mode 100644 (file)
index 0000000..05450b4
--- /dev/null
@@ -0,0 +1,82 @@
+
+#include <Utils/StdTypes.h>
+#include <Abstract/ISPI.h>
+#include <AVR/AvrSpi.h>
+
+        
+AvrSpi::AvrSpi()
+{
+    init();
+}
+
+void 
+AvrSpi::init( void )
+{
+  /* initial SPI */
+  /* atmega88: PB3=MOSI, PB5=SCK, PB2=nSS, PB4=MISO */
+  PORTB |= _BV( PIN2) | _BV( PIN3) | _BV( PIN5);
+  DDRB |= _BV( PIN2 ) | _BV( PIN3 ) | _BV( PIN5) ;
+  DDRB &= ~_BV( PIN4 );
+  /* enable SPI as Master */
+  SPCR = (1<<SPE) | (1<<MSTR);
+#if 0
+  SPSR |=(1<<SPI2X);                           // doubling spi speed.i.e final spi speed-fosc/2
+
+  LCD_CSN_PORT |= (1<<LCD_CSN);        // cs(low active) off during startup
+#endif
+}
+    
+void 
+AvrSpi::begin(const SPISettings &_settings)
+{
+    /* Set mode */
+    SPCR |= (_settings.m_Mode<<2);
+    switch(_settings.m_Freq)
+    {
+        case 8000000: SPSR |= _BV(SPI2X); break; 
+        case 4000000: break; 
+        case 2000000: SPSR |= _BV(SPI2X); SPCR |= _BV(SPR0); break;
+        case 1000000: SPCR |= _BV(SPR0) ; break;
+        case 500000:  SPSR |= _BV(SPI2X); SPCR |= _BV(SPR1); break;
+        case 250000:  SPSR |= _BV(SPI2X); SPCR |= (_BV(SPR1) | _BV(SPR0)) ; break;
+        case 125000:  SPCR |= _BV(SPR1) | _BV(SPR1); break;
+        default: ;
+    }
+}
+  
+
+void AvrSpi::end()
+{
+  /* disable SPI */
+  //SPCR &= ~(_BV(SPE) | _BV(MSTR));
+  SPSR &= ~_BV(SPI2X); SPCR &= ~(_BV(SPR1) | _BV(SPR0)) ; // Be sure everyting is back to 0
+}      
+
+
+/// 8 bits data tx/rx
+void 
+AvrSpi::transceive(const Uint8_t txData,Uint8_t * const &rxData)
+{
+  SPDR = txData;
+  while ( !(SPSR & (1<<SPIF)) );
+  *rxData = SPDR;
+}
+
+/// 16 bits data tx / rx
+void 
+AvrSpi::transceive(const Uint16_t txData,Uint16_t *const &rxData)
+{
+  union {
+    uint16_t val;
+    struct {
+           uint8_t msb;
+           uint8_t lsb;
+    } s;
+  } in,out;
+  in.val = txData;
+
+  transceive(in.s.msb,&out.s.msb);
+  transceive(in.s.lsb,&out.s.lsb);
+  //*rxData = *rxData | static_cast<uint16_t>(0x00FF & result);
+  *rxData = out.val;
+}
diff --git a/HAL/AVR/AvrSpi.h b/HAL/AVR/AvrSpi.h
new file mode 100644 (file)
index 0000000..808d7ee
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef AVR_SPI_H__
+#define AVR_SPI_H__
+
+/**
+ * \brief SPI interface for ATMEGA 328p
+ * should be simple and fast
+ *
+ */
+class AvrSpi : public ISpi
+{
+    public:
+        AvrSpi();
+
+        virtual void init( void );
+        // Begin SPI transaction
+               virtual void begin(const SPISettings &_settings) ;
+        /// End SPI transaction
+       virtual void end();
+        /// 8 bits data tx/rx
+        virtual void transceive(const Uint8_t txData,Uint8_t *const &rxData);
+        /// 16 bits data tx / rx
+        virtual void transceive(const Uint16_t txData,Uint16_t *const &rxData);
+};
+#endif
diff --git a/HAL/AVR/AvrTimer0.cpp b/HAL/AVR/AvrTimer0.cpp
new file mode 100644 (file)
index 0000000..b363895
--- /dev/null
@@ -0,0 +1,11 @@
+
+#include <avr/interrupt.h>
+
+#include "Abstract/IInterruptActivity.h"
+#include "AVR/AvrTimer0.h"
+
+#if defined (__AVR_ATmega32U4__)
+#include "32u4_Timer0.cpp"
+#else
+#include "328p_Timer0.cpp"
+#endif
diff --git a/HAL/AVR/AvrTimer0.h b/HAL/AVR/AvrTimer0.h
new file mode 100644 (file)
index 0000000..7c0fcfd
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef __AVR_TIMER0_H__
+#define __AVR_TIMER0_H__
+
+class Timer0 
+{
+  public:
+    Timer0(IInterruptActivity &_int);
+    /// setup timer 
+    void init();
+    ///
+    void process_interrupt();
+    /// Global pointer for ISR processing
+    static Timer0* gTimer0;
+  private:
+    /// setup timer 
+    void initT2();
+    IInterruptActivity *m_Interrupt;
+};
+
+
+#endif
diff --git a/HAL/AVR/AvrTimer1.cpp b/HAL/AVR/AvrTimer1.cpp
new file mode 100644 (file)
index 0000000..8831a40
--- /dev/null
@@ -0,0 +1,52 @@
+#include <Utils/StdTypes.h>
+
+#include "AVR/AvrTimer1.h"
+
+
+Timer1::Timer1()
+{
+    init();
+}
+void 
+Timer1::init()
+{
+    //cli();
+
+    // Set Control Register 16MHz / 1024 = 15,625KHz
+    // Tick = 1/15,625KHz = 64us
+    // So overflow every 16ms
+    // No Division  
+    TCCR1B = 3<< CS10  ;
+    //TCCR1B = _BV(CS10) | _BV(CS11) | _BV(CS12); 
+    //TCCR0A = (1<< WGM01); 
+#if 0
+    TCCR1A |= (3<< WGM10);
+    TCCR1B |= (1<< WGM12);
+#endif
+    // Initialize counter
+    TCNT1 = 0;
+#if defined (__AVR_ATmega32U4__)
+    PRR0   &= ~(1<<PRTIM1);
+#else
+    PRR   &= ~(1<<PRTIM1);
+#endif
+    //sei();
+}
+
+///
+Uint16_t 
+Timer1::readCounter(bool _reset)
+{
+    //Uint8_t  _sreg=SREG;
+    //cli();
+    Uint16_t _ret = TCNT1;
+#if 0
+    if (_reset == true)
+    {
+        TCNT1 =0;
+    }
+#endif
+    //SREG = sreg;
+    return _ret;
+}
+
diff --git a/HAL/AVR/AvrTimer1.h b/HAL/AVR/AvrTimer1.h
new file mode 100644 (file)
index 0000000..05d6077
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __AVR_TIMER1_H__
+#define __AVR_TIMER1_H__
+
+class Timer1 
+{
+  public:
+    Timer1();
+    /// setup timer 
+    void init();
+    ///
+    Uint16_t readCounter(bool _reset = false);
+    ///
+
+  private:
+};
+
+
+#endif
diff --git a/HAL/AVR/AvrTimer3.cpp b/HAL/AVR/AvrTimer3.cpp
new file mode 100644 (file)
index 0000000..59fc1aa
--- /dev/null
@@ -0,0 +1,41 @@
+#include <Utils/StdTypes.h>
+
+#include "AVR/AvrTimer3.h"
+
+
+Timer3::Timer3()
+{
+    init();
+}
+void 
+Timer3::init()
+{
+    //cli();
+
+    // Set Control Register 16MHz / 1024 = 15,625KHz
+    // Tick = 1/15,625KHz = 64us
+    // So overflow every 16ms
+    // No Division  
+    TCCR3B = _BV(CS30) | _BV(CS31) | _BV(CS32); 
+    //TCCR0A = (1<< WGM01); 
+    TCCR3A |= (3<< WGM00);
+    // Initialize counter
+    TCNT3 = 0;
+    PRR0   &= ~(1<<PRTIM3);
+}
+
+///
+Uint16_t 
+Timer3::readCounter(bool _reset)
+{
+    //Uint8_t  _sreg=SREG;
+    //cli();
+    Uint16_t _ret = TCNT3;
+    if (_reset == true)
+    {
+        TCNT1 =0;
+    }
+    //SREG = sreg;
+    return _ret;
+}
+
diff --git a/HAL/AVR/AvrTimer3.h b/HAL/AVR/AvrTimer3.h
new file mode 100644 (file)
index 0000000..05d6077
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __AVR_TIMER1_H__
+#define __AVR_TIMER1_H__
+
+class Timer1 
+{
+  public:
+    Timer1();
+    /// setup timer 
+    void init();
+    ///
+    Uint16_t readCounter(bool _reset = false);
+    ///
+
+  private:
+};
+
+
+#endif
diff --git a/HAL/AVR/AvrUart.cpp b/HAL/AVR/AvrUart.cpp
new file mode 100644 (file)
index 0000000..151743e
--- /dev/null
@@ -0,0 +1,175 @@
+
+#include <avr/interrupt.h>
+
+#include <Abstract/IUart.h>
+#include <AVR/AvrUart.h>
+
+
+
+AvrUart::AvrUart(Baudrate_t _baud,Parity_t _p,StopBits_t _stb)
+  : m_Baudrate(_baud),m_Parity(_p),m_StopBits(_stb)
+{
+  init();
+}
+
+void 
+AvrUart::init()
+{
+       
+#if defined (__AVR_ATmega32U4__)
+       PRR1   &= ~(1<<PRUSART1);
+#else
+       PRR   &= ~(1<<PRUSART0);
+#endif
+  setParameters(m_Baudrate,m_Parity,m_StopBits);
+  enableReceive(true);
+
+  return;
+}
+
+/**
+*
+*
+*/
+void 
+AvrUart::transmit(uint8_t tx)
+{
+#if defined (__AVR_ATmega32U4__)
+    UDR1 = tx;
+#else
+    UDR0 = tx;
+#endif
+}
+
+/**
+* \brief get the character received
+*
+*/
+uint8_t 
+AvrUart::receive()
+{
+#if defined (__AVR_ATmega32U4__)
+  return UDR1;
+#else
+  return UDR0;
+#endif
+}
+
+
+/**
+* \brief return true when data can
+* be sent. Eg previous character was sent.
+*/
+bool 
+AvrUart::transmit_ready()
+{
+#if defined (__AVR_ATmega32U4__)
+  return (UCSR1A & _BV(UDRE1)) ;
+#else
+  return (UCSR0A & _BV(UDRE0)) ;
+#endif
+}
+
+/**
+* \brief return true when data have been
+* received
+*/
+bool 
+AvrUart::receive_ready()
+{
+#if defined (__AVR_ATmega32U4__)
+  return (UCSR1A & _BV(RXC1));
+#else
+  return (UCSR0A & _BV(RXC0));
+#endif
+}
+
+/**
+*
+*/
+void 
+AvrUart::switchSetup(const Baudrate_t _baud,const Parity_t _p,StopBits_t _stb)
+{
+}
+
+/// Allow / Disable ReceiveInterrupt
+void 
+AvrUart::enableReceive(bool _set)
+{
+#if defined (__AVR_ATmega32U4__)
+  if (_set)
+    UCSR1B |= (1 <<  RXEN1);
+  else
+    UCSR1B &= ~(1<< RXEN1);
+#else
+  if (_set)
+    UCSR0B |= (1 <<  RXEN0);
+  else
+    UCSR0B &= ~(1<< RXEN0);
+#endif
+}
+
+
+/// Allow Transmit interrupt vector to
+// be triggered
+void 
+AvrUart::enableTransmit(bool _set)
+{
+#if defined (__AVR_ATmega32U4__)
+  if (_set)
+    UCSR1B |= _BV(  TXEN1);
+  else
+    UCSR1B &= ~_BV( TXEN1);
+#else
+  if (_set)
+    UCSR0B |= _BV(  TXEN0);
+  else
+    UCSR0B &= ~_BV( TXEN0);
+#endif
+}
+
+void 
+AvrUart::setParameters(IUart::Baudrate_t _baud,IUart::Parity_t _parity, IUart::StopBits_t _bits)
+{
+    // Enable Rx / Tx
+#if defined (__AVR_ATmega32U4__)
+  UCSR1B = (1 <<  TXEN1) | ( 1 <<  RXEN1 );
+#else
+  UCSR0B = (1 <<  TXEN0) | ( 1 <<  RXEN0 );
+#endif
+    uint16_t speed = 103;
+    switch (_baud)
+    {
+        case BAUD_9600  : speed = 103; break;
+        case BAUD_19200 : speed = 51 ; break;
+        case BAUD_57600 : speed = 16 ; break;
+        case BAUD_115200: speed = 16 ; break;
+        break;
+        default: ;
+    }
+#if defined (__AVR_ATmega32U4__)
+    UBRR1H = speed >> 8;
+    UBRR1L = speed;
+    // Set  8 bits and Stop bits
+    if (_bits == STB_TWO)
+    {
+      UCSR1C =  (1<<USBS1) | (3<<UCSZ10);
+    }
+    else 
+    {
+      UCSR1C =  (3<<UCSZ10);
+    }
+#else
+    UBRR0H = speed >> 8;
+    UBRR0L = speed;
+    // Set  8 bits and Stop bits
+    if (_bits == STB_TWO)
+    {
+      UCSR0C =  (1<<USBS0) | (3<<UCSZ00);
+    }
+    else 
+    {
+      UCSR0C =  (3<<UCSZ00);
+    }
+#endif    
+}
diff --git a/HAL/AVR/AvrUart.h b/HAL/AVR/AvrUart.h
new file mode 100644 (file)
index 0000000..6195583
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef AVR_UART_H__
+#define AVR_UART_H__
+
+
+class AvrUart : public IUart
+{
+  public:
+    
+    AvrUart(Baudrate_t _baud,Parity_t _p,StopBits_t _stb);
+
+    virtual void init();
+    /**
+     *
+     *
+     */
+    virtual void transmit(uint8_t tx);
+    
+    /**
+     * \brief get the character received
+     *
+     */
+    virtual uint8_t receive() ;
+
+    /**
+     * \brief return true when data can
+     * be sent. Eg previous character was sent.
+     */
+    virtual bool transmit_ready() ;
+    /**
+     * \brief return true when data have been
+     * received
+     */
+    virtual bool receive_ready() ;
+
+    /**
+     *
+     */
+    void switchSetup(const Baudrate_t _baud,const Parity_t _p,StopBits_t _stb) ;
+    /// Allow / Disable ReceiveInterrupt
+    virtual void enableReceive(bool _set);
+    /// Allow Transmit interrupt vector to
+    // be triggered
+    virtual void enableTransmit(bool _set);
+
+    virtual void setParameters(IUart::Baudrate_t _baud,IUart::Parity_t _parity, IUart::StopBits_t _bits);
+  private:
+    Baudrate_t m_Baudrate;
+    Parity_t   m_Parity;
+    StopBits_t m_StopBits;
+};
+
+#endif
diff --git a/HAL/AVR/CMakeLists.txt b/HAL/AVR/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6854211
--- /dev/null
@@ -0,0 +1,14 @@
+#####################################################################
+# simple AVR library
+#####################################################################
+add_avr_library(
+  avrHAL
+  AvrTimer0.cpp
+  AvrTimer1.cpp
+  AvrUart.cpp
+  AvrEeprom.cpp
+  AvrAdc.cpp
+  AvrPwm.cpp
+  AvrSpi.cpp
+   )
+
diff --git a/HAL/Abstract/IAdc.h b/HAL/Abstract/IAdc.h
new file mode 100644 (file)
index 0000000..94bf724
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef __IADC_H__
+#define __IADC_H__
+
+class IAdc 
+{
+  public:
+    IAdc() {} ;
+
+    virtual Uint16_t read(const Uint8_t _channel) const = 0;
+};
+
+#endif
diff --git a/HAL/Abstract/IEeprom.h b/HAL/Abstract/IEeprom.h
new file mode 100644 (file)
index 0000000..d9cac0a
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef __IEEPROM_H__
+#define __IEEPROM_H__
+
+/**
+ * \brief Eeprom interface exposed for all Eeprom implementation. 
+ * can be usefull so that at the hight level I don't have to be
+ * bother with low level access issues. 
+ *
+ */
+class IEeprom 
+{
+    public:
+        ///
+        IEeprom() {};
+        /// Initialize 
+        virtual void init() = 0;
+        /// Is eeprom busy, might be of interest, as eeprom access is performed through
+        /// SPI 
+        virtual Bool_t isBusy() = 0;
+        /// read values from Eeprom
+        virtual void read(const Uint16_t _addr,const Uint16_t _len,Uint8_t *_dest);
+        /// Interesting that eeprom is written page wise
+        virtual void writePage(const Uint8_t pageCount,const Uint8_t _Offset,const Uint8_t byteCount,Uint8_t *_data);
+};
+#endif
diff --git a/HAL/Abstract/IInterruptActivity.h b/HAL/Abstract/IInterruptActivity.h
new file mode 100644 (file)
index 0000000..73cc50c
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef __IINTERRUPTACTIVITY_H__
+#define __IINTERRUPTACTIVITY_H__
+
+class IInterruptActivity
+{
+  public:
+    IInterruptActivity() {}
+
+    virtual void tick() = 0;
+
+};
+
+#endif
diff --git a/HAL/Abstract/IIo.h b/HAL/Abstract/IIo.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/HAL/Abstract/IProtocolLayer2.h b/HAL/Abstract/IProtocolLayer2.h
new file mode 100644 (file)
index 0000000..b59030b
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef  __IProtocolLayer2_H__
+#define  __IProtocolLayer2_H__
+
+/**
+ * \brief Interface for Layer2 protocols
+ *
+ */
+class IProtocolLayer2
+{
+  public:
+    IProtocolLayer2() {};
+
+    virtual void init() = 0;
+    /**
+     * @return the size of the receiveMessage.
+     */
+    virtual const uint8_t getRxSize() const;
+    /**
+     * @return a pointer to the received message
+     * if no message is available, return NULL.
+     * a message is considered to be received on CR.
+     *  If message is too long ? erase or error
+     */
+    virtual const uint8_t *receiveMsg() = 0;
+
+    virtual void setTxMsg(const uint8_t *_src,uint8_t _length) = 0;
+    /**
+     * \bried transmit message stored in m_Buffer.
+     * The message must previously be set by
+     * setTxMsg()
+     */
+    virtual void transmitMsg() = 0;
+    /**
+     * @brief called by scheduler I think.
+     */
+    virtual void tick() = 0;
+
+};
+
+#endif
diff --git a/HAL/Abstract/IPwm.h b/HAL/Abstract/IPwm.h
new file mode 100644 (file)
index 0000000..383b965
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef __IPWM_H__
+#define __IPWM_H__
+
+/**
+ * @brief General interface for PWM pins.
+ *
+ */
+class IPwm 
+{
+  public:
+    IPwm() {} ;
+
+    virtual void enable(const Bool_t _OnOff) const = 0;
+    
+    virtual void setFreq(Uint16_t freq) const = 0;
+
+    virtual void setDutyCycle(const Uint8_t _OnOff) const = 0;
+
+};
+
+#endif
diff --git a/HAL/Abstract/ISPI.h b/HAL/Abstract/ISPI.h
new file mode 100644 (file)
index 0000000..9f384eb
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef __ISPI_H__
+#define __ISPI_H__
+
+#define SPI_MODE0 0x0
+#define SPI_MODE1 0x1
+#define SPI_MODE2 0x2
+#define SPI_MODE3 0x3
+
+#define MSBFIRST  0x0
+#define LSBFIRST  0x1
+/**
+ * For transaction based SPI commands.
+ * 
+ */
+struct SPISettings
+{
+  public:
+    SPISettings(const uint32_t _freq
+              ,const uint8_t _endian
+              ,const uint8_t _mode
+              ) 
+           : m_Freq(_freq),m_Mode(_mode),m_Endian(_endian) {}
+  uint32_t  m_Freq;
+  uint8_t   m_Mode;
+  uint8_t   m_Endian;
+};
+
+/**
+ *
+ *
+ */
+class ISpi
+{
+  public:
+    ISpi()  {};
+
+    /// Initialize Spi interface
+    virtual void init() = 0;
+
+    virtual void begin(const SPISettings &_settings) = 0;
+  
+    virtual void end() = 0 ;
+    /// 8 bits data tx/rx
+    virtual void transceive(const uint8_t txData,uint8_t *const &rxData) = 0;
+    /// 16 bits data tx / rx
+    virtual void transceive(const uint16_t txData,uint16_t *const &rxData) = 0;
+};
+
+#endif
diff --git a/HAL/Abstract/ISwitch.h b/HAL/Abstract/ISwitch.h
new file mode 100644 (file)
index 0000000..4d33a88
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef ISWITCH_H__
+#define ISWITCH_H__
+
+class ISwitch 
+{
+  public:
+    enum State { SwitchOff = 0 , SwitchOn = 1 };
+
+    ISwitch() {};
+
+    virtual void  set(State _state) = 0;
+    virtual void  toggle() = 0;
+    virtual State state() const = 0;
+};
+
+#endif
diff --git a/HAL/Abstract/ITimer.h b/HAL/Abstract/ITimer.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/HAL/Abstract/IUart.h b/HAL/Abstract/IUart.h
new file mode 100644 (file)
index 0000000..f308173
--- /dev/null
@@ -0,0 +1,72 @@
+#ifndef __IUART_H__
+#define __IUART_H__
+
+
+/**
+ * \brief Abstrasct UArt Interface 
+ * will be used by upper classes to
+ * send and transmit data
+ */
+class IUart
+{
+  public:
+#if 0
+      enum Baudrate_t { BAUD_2400 = 2400
+          ,BAUD_9600    = 9600
+          ,BAUD_19200   = 19200
+          ,BAUD_33600   = 33600
+          ,BAUD_57600   = 57600
+          ,BAUD_115200  = 115200
+    };
+#else
+      enum Baudrate_t { BAUD_2400 = 0
+          ,BAUD_9600    = 1
+          ,BAUD_19200   = 2
+          ,BAUD_57600   = 4
+          ,BAUD_115200  = 6
+    };
+#endif
+    
+    enum Parity_t { PARITY_ODD,PARITY_EVEN,PARITY_NONE };
+
+    enum StopBits_t { STB_ONE = 0 ,STB_TWO = 1};
+
+    IUart() {}; 
+
+    virtual void init() = 0;
+    /**
+     *
+     *
+     */
+    virtual void transmit(uint8_t tx) = 0;
+    
+    /**
+     * \brief get the character received
+     *
+     */
+    virtual uint8_t receive() = 0;
+
+    /**
+     * \brief return true when data can
+     * be sent. Eg previous character was sent.
+     */
+    virtual bool transmit_ready() = 0;
+    /**
+     * \brief return true when data have been
+     * received
+     */
+    virtual bool receive_ready() = 0;
+
+    /// Allow / Disable ReceiveInterrupt
+    virtual void enableReceive(bool _set) = 0;
+    /// Allow Transmit interrupt vector to
+    // be triggered
+    virtual void enableTransmit(bool _set) = 0;
+
+    /**
+     *
+     */
+    virtual void switchSetup(const Baudrate_t _baud,const Parity_t _p,StopBits_t _stb) = 0;
+};
+
+#endif
diff --git a/HAL/CMakeLists.txt b/HAL/CMakeLists.txt
new file mode 100644 (file)
index 0000000..fa592cd
--- /dev/null
@@ -0,0 +1 @@
+subdirs(AVR Drivers)
diff --git a/HAL/Drivers/CMakeLists.txt b/HAL/Drivers/CMakeLists.txt
new file mode 100644 (file)
index 0000000..fe4b380
--- /dev/null
@@ -0,0 +1,10 @@
+#####################################################################
+# simple AVR library
+#####################################################################
+add_avr_library(
+  avrDrivers
+  NetString.cpp
+  Ili9341.cpp
+  XPT2046_Touchscreen.cpp
+   )
+
diff --git a/HAL/Drivers/Eeprom.h b/HAL/Drivers/Eeprom.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/HAL/Drivers/Ili9341.cpp b/HAL/Drivers/Ili9341.cpp
new file mode 100644 (file)
index 0000000..74cef2d
--- /dev/null
@@ -0,0 +1,531 @@
+#include <Utils/StdTypes.h>
+#include <util/delay.h>
+
+#include "Abstract/ISPI.h"
+#include "Ili9341.h"
+
+
+
+
+#define TianMa_2_4inch_ILI9341 1
+#define CMD_ACTIF_LOW          1
+#define SPI_SETTINGS SPISettings(8000000,MSBFIRST,SPI_MODE0)
+
+volatile uint16_t LCD_W=ILI9341_TFTWIDTH;
+volatile uint16_t LCD_H=ILI9341_TFTHEIGHT;
+
+Ili9341::Ili9341(ISpi *_spi)
+ : m_Spi(_spi)
+{
+}
+
+void Ili9341::hard_init(void)//init hardware
+{
+       /* initial hardware bit */
+       // set port C/ D & E to output
+       LCD_CSN_DDR     |= (1<<LCD_CSN);        // set nCS for output port
+       LCD_CMD_DDR     |= (1<<LCD_CMD);        // set D/C for output port
+       LCD_RST_DDR     |= (1<<LCD_RST);        // set reset pin for output port        
+       
+       LCD_RST_PORT |= (1<<LCD_RST);   // pull high reset pin for normal operation
+}
+
+
+void Ili9341::spi_init(void)//set spi speed and settings 
+{
+#if 0
+       /* initial SPI */
+       /* atmega88: PB3=MOSI, PB5=SCK, PB2=nSS, PB4=MISO */
+       //PORTB |= ( 1<<2 ) | ( 1<<1 ) | ( 1<<6 );
+       PORTB |= _BV( PIN2) | _BV( PIN3) | _BV( PIN5);
+       //DDRB |= ( 1<<2 ) | ( 1<<1 ) | ( 1<<6 ) | ( 1<<3 );
+       DDRB |= _BV( PIN2 ) | _BV( PIN3 ) | _BV( PIN5) ;
+       DDRB &= ~_BV( PIN4 );
+       SPCR = (1<<SPE) | (1<<MSTR);    // mode 0,fosc/4
+       SPSR |=(1<<SPI2X);                              // doubling spi speed.i.e final spi speed-fosc/2
+#else
+       m_Spi->begin(SPI_SETTINGS);
+#endif
+       LCD_CSN_PORT |= (1<<LCD_CSN);   // cs(low active) off during startup
+}
+
+
+void Ili9341::writecommand8(uint8_t com)//command write
+{
+#if CMD_ACTIF_LOW
+       LCD_CMD_PORT &=~(1<<LCD_CMD);                   // dc low to send command
+#else
+       LCD_CMD_PORT |= (1<<LCD_CMD);                   // dc high to send command
+#endif
+       _delay_us(1);                                                   // little delay
+       LCD_CSN_PORT &=~(1<<LCD_CSN);                   // cs low to send command
+       
+       _delay_us(5);                                                   // little delay
+       SPI_ExchangeByte(com);
+       LCD_CSN_PORT |=(1<<LCD_CSN);                    // pull high cs
+}
+
+uint8_t  Ili9341::SPI_ExchangeByte( uint8_t  input )
+{
+#if 0
+       SPDR = input;
+       while ( !(SPSR & (1<<SPIF)) );
+       return SPDR;
+#else
+    uint8_t result;
+    m_Spi->transceive(input,&result);
+    return result;
+#endif
+}
+
+void Ili9341::writedata8(uint8_t data)//data write
+{
+#if CMD_ACTIF_LOW
+       LCD_CMD_PORT |= (1<<LCD_CMD);                   // dc high to send data
+#else
+       LCD_CMD_PORT &=~(1<<LCD_CMD);                   // dc low to send data
+#endif
+       LCD_CSN_PORT &=~(1<<LCD_CSN);                   // cs low to send data
+       
+       _delay_us(5);                                                   // little delay
+       SPI_ExchangeByte(data);
+       LCD_CSN_PORT |=(1<<LCD_CSN);                    // pull high cs
+}
+
+void Ili9341::setaddress(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2)//set coordinate for print or other function
+{
+       writecommand8(0x2A);
+       writedata8(x1>>8);
+       writedata8(x1);
+       writedata8(x2>>8);
+       writedata8(x2);
+
+       writecommand8(0x2B);
+       writedata8(y1>>8);
+       writedata8(y1);
+       writedata8(y2>>8);
+       writedata8(y2);
+
+       writecommand8(0x2C);//meory write
+}
+
+
+void Ili9341::hard_reset(void)//hard reset display
+{      
+       LCD_RST_PORT |= (1<<LCD_RST);   // pull high if low previously
+       _delay_ms(2);
+       LCD_RST_PORT &= ~(1<<LCD_RST);  // pull high if low previously
+       _delay_ms(2);
+       LCD_RST_PORT |= (1<<LCD_RST);   // again pull high for normal operation
+       _delay_ms(2);
+       
+       writecommand8(0x01);    // soft reset
+       _delay_ms(10);
+}
+
+
+void Ili9341::init(void)//set up display using predefined command sequence
+{
+       hard_init();
+       spi_init();
+       hard_reset();
+       writecommand8(0x01);//soft reset
+       _delay_ms(1000);
+
+#ifdef LG_2_8inch_ILI9341
+       // LG 2.8" ILI9341 Initial Code
+       //power control A
+       writecommand8(0xCB);
+       writedata8(0x39);
+       writedata8(0x2C);
+       writedata8(0x00);
+       writedata8(0x34);
+       writedata8(0x02);
+
+       //power control B
+       writecommand8(0xCF);
+       writedata8(0x00);
+       writedata8(0xC1);
+       writedata8(0x30);
+
+       //driver timing control A
+       writecommand8(0xE8);
+       writedata8(0x85);
+       writedata8(0x00);
+       writedata8(0x78);
+
+       //driver timing control B
+       writecommand8(0xEA);
+       writedata8(0x00);
+       writedata8(0x00);
+
+       //power on sequence control
+       writecommand8(0xED);
+       writedata8(0x64);
+       writedata8(0x03);
+       writedata8(0x12);
+       writedata8(0x81);
+
+       //pump ratio control
+       writecommand8(0xF7);
+       writedata8(0x20);
+
+       //power control,VRH[5:0]
+       writecommand8(0xC0);
+       writedata8(0x23);
+
+       //Power control,SAP[2:0];BT[3:0]
+       writecommand8(0xC1);
+       writedata8(0x10);
+
+       //vcm control
+       writecommand8(0xC5);
+       writedata8(0x3E);
+       writedata8(0x28);
+
+       //vcm control 2
+       writecommand8(0xC7);
+       writedata8(0x86);
+
+       //memory access control
+       writecommand8(0x36);
+       writedata8(0x48);
+
+       //pixel format
+       writecommand8(0x3A);
+       writedata8(0x55);
+
+       //frameration control,normal mode full colours
+       writecommand8(0xB1);
+       writedata8(0x00);
+       writedata8(0x18);
+
+       //display function control
+       writecommand8(0xB6);
+       writedata8(0x08);
+       writedata8(0x82);
+       writedata8(0x27);
+
+       //3gamma function disable
+       writecommand8(0xF2);
+       writedata8(0x00);
+
+       //gamma curve selected
+       writecommand8(0x26);
+       writedata8(0x01);
+
+       //set positive gamma correction
+       writecommand8(0xE0);
+       writedata8(0x0F);
+       writedata8(0x31);
+       writedata8(0x2B);
+       writedata8(0x0C);
+       writedata8(0x0E);
+       writedata8(0x08);
+       writedata8(0x4E);
+       writedata8(0xF1);
+       writedata8(0x37);
+       writedata8(0x07);
+       writedata8(0x10);
+       writedata8(0x03);
+       writedata8(0x0E);
+       writedata8(0x09);
+       writedata8(0x00);
+
+       //set negative gamma correction
+       writecommand8(0xE1);
+       writedata8(0x00);
+       writedata8(0x0E);
+       writedata8(0x14);
+       writedata8(0x03);
+       writedata8(0x11);
+       writedata8(0x07);
+       writedata8(0x31);
+       writedata8(0xC1);
+       writedata8(0x48);
+       writedata8(0x08);
+       writedata8(0x0F);
+       writedata8(0x0C);
+       writedata8(0x31);
+       writedata8(0x36);
+       writedata8(0x0F);
+#endif
+
+#ifdef TianMa_2_4inch_ILI9341
+       // TianMa 2.4" ILI9341 Initial Code
+       
+       // xxxx
+       writecommand8(0xEF);
+       writedata8(0x03);
+       writedata8(0x80);
+       //writedata8(0x30);
+       writedata8(0x02);
+
+       //power control B
+       writecommand8(0xCF);
+       writedata8(0x00);
+       //writedata8(0x81);
+       writedata8(0xC1);
+       writedata8(0x30);
+
+       //power on sequence control
+       writecommand8(0xED);
+       writedata8(0x64);
+       writedata8(0x03);
+       writedata8(0x12);
+       writedata8(0x81);
+
+       //driver timing control A
+       writecommand8(0xE8);
+       writedata8(0x85);
+       //writedata8(0x10);
+       writedata8(0x00);
+       //writedata8(0x7A);
+       writedata8(0x78);
+
+       //power control A
+       writecommand8(0xCB);
+       writedata8(0x39);
+       writedata8(0x2C);
+       writedata8(0x00);
+       writedata8(0x34);
+       writedata8(0x02);
+
+       //pump ratio control
+       writecommand8(0xF7);
+       writedata8(0x20);
+
+       //driver timing control B
+       writecommand8(0xEA);
+       writedata8(0x00);
+       writedata8(0x00);
+
+       //power control,VRH[5:0]
+       writecommand8(0xC0);
+       //writedata8(0x21);
+       writedata8(0x23);
+
+       //Power control,SAP[2:0];BT[3:0]
+       writecommand8(0xC1);
+       writedata8(0x10);
+
+       //vcm control
+       writecommand8(0xC5);
+       //writedata8(0x3F);
+       //writedata8(0x3C);
+       writedata8(0x3E);
+       writedata8(0x28);
+
+       //vcm control 2
+       writecommand8(0xC7);
+       //writedata8(0xA7);
+       writedata8(0x86);
+
+       //memory access control
+       writecommand8(0x36);
+       writedata8(0x48);
+
+       //frameration control,normal mode full colours
+       writecommand8(0xB1);
+       writedata8(0x00);
+       //writedata8(0x1B);
+       writedata8(0x18);
+       
+       //display function control
+       writecommand8(0xB6);
+       //writedata8(0x0A);
+       writedata8(0x08);
+       //writedata8(0xA2);
+       writedata8(0x82);
+       writedata8(0x27);       
+       
+       //3gamma function disable
+       writecommand8(0xF2);
+       writedata8(0x00);       
+       
+       //gamma curve selected
+       writecommand8(0x26);
+       writedata8(0x01);
+       
+       //set positive gamma correction
+       writecommand8(0xE0);
+       writedata8(0x0F);
+       writedata8(0x23);
+       writedata8(0x1F);
+       writedata8(0x0B);
+       writedata8(0x0E);
+       writedata8(0x08);
+       writedata8(0x4B);
+       writedata8(0xA8);
+       writedata8(0x3B);
+       writedata8(0x0A);
+       writedata8(0x14);
+       writedata8(0x09);
+       writedata8(0x10);
+       writedata8(0x09);
+       writedata8(0x00);
+       
+       //set negative gamma correction
+       writecommand8(0xE1);
+       writedata8(0x00);
+       writedata8(0x1C);
+       writedata8(0x20);
+       writedata8(0x04);
+       writedata8(0x10);
+       writedata8(0x08);
+       writedata8(0x34);
+       writedata8(0x47);
+       writedata8(0x44);
+       writedata8(0x05);
+       writedata8(0x0B);
+       writedata8(0x09);
+       writedata8(0x2F);
+       writedata8(0x36);
+       writedata8(0x0F);
+       
+       //pixel format
+       writecommand8(0x3A);
+       writedata8(0x55);
+#endif
+
+       //exit sleep
+       writecommand8(0x11);
+       _delay_ms(150);
+       //display on
+       writecommand8(0x29);
+       _delay_ms(150);
+       m_Spi->end();
+}
+
+//set colour for drawing
+void Ili9341::pushcolour(uint16_t colour)
+{
+    writedata8(colour>>8);
+    writedata8(colour);
+}
+
+
+//clear lcd and fill with colour
+void Ili9341::clear(uint16_t colour)
+{
+       uint16_t i,j;
+    m_Spi->begin(SPI_SETTINGS);
+
+    setaddress(0,0,LCD_W-1,LCD_H-1);
+
+       for(i=0;i<LCD_W;i++)
+       {
+               for(j=0;j<LCD_H;j++)
+               {
+                       pushcolour(colour);
+               }
+       }
+
+    m_Spi->end();
+}
+
+
+
+//draw pixel
+void Ili9341::drawpixel(uint16_t x3,uint16_t y3,uint16_t colour1) //pixels will always be counted from right side.x is representing LCD width which will always be less tha 240.Y is representing LCD height which will always be less than 320
+{
+       if((x3 < 0) ||(x3 >=LCD_W) || (y3 < 0) || (y3 >=LCD_H)) return;
+
+    m_Spi->begin(SPI_SETTINGS);
+       setaddress(x3,y3,x3+1,y3+1);
+
+       pushcolour(colour1);
+   m_Spi->end();
+}
+
+
+//draw vertical line
+void Ili9341::drawvline(uint16_t x,uint16_t y,uint16_t h,uint16_t colour)//basically we will see this line horizental if we see the display 320*240
+{
+       if((x >=LCD_W) || (y >=LCD_H)) return;
+       if((y+h-1)>=LCD_H)
+       h=LCD_H-y;
+    m_Spi->begin(SPI_SETTINGS);
+       setaddress(x,y,x,y+h-1);
+       while(h--)
+       {
+               pushcolour(colour);
+       }
+   m_Spi->end();
+}
+
+
+//draw horizental line
+
+void Ili9341::drawhline(uint16_t x,uint16_t y,uint16_t w,uint16_t colour)
+{
+       if((x >=LCD_W) || (y >=LCD_H)) return;
+       if((x+w-1)>=LCD_W)
+       w=LCD_W-x;
+    m_Spi->begin(SPI_SETTINGS);
+       setaddress(x,y,x+w-1,y);
+       while(w--)
+       {
+               pushcolour(colour);
+       }
+   m_Spi->end();
+}
+
+
+//draw colour filled rectangle
+void Ili9341::fillrect(uint16_t x,uint16_t y,uint16_t w,uint16_t h,uint16_t colour)
+{
+       if((x >=LCD_W) || (y >=LCD_H)) return;
+       if((x+w-1)>=LCD_W)
+       w=LCD_W-x;
+       if((y+h-1)>=LCD_H)
+       h=LCD_H-y;
+
+    m_Spi->begin(SPI_SETTINGS);
+       setaddress(x, y, x+w-1, y+h-1);
+
+       for(y=h; y>0; y--) 
+       {
+               for(x=w; x>0; x--)
+               {
+                       pushcolour(colour);
+               }
+       }
+   m_Spi->end();
+}
+
+//rotate screen at desired orientation
+void Ili9341::setRotation(uint8_t m) 
+{
+       uint8_t rotation;
+    m_Spi->begin(SPI_SETTINGS);
+       writecommand8(0x36);
+       rotation=m%4;
+       switch (rotation) 
+       {
+               case 0:
+               writedata8(0x40|0x08);
+               LCD_W = 240;
+               LCD_H = 320;
+               break;
+               
+               case 1:
+               writedata8(0x20|0x08);
+               LCD_W  = 320;
+               LCD_H = 240;
+               break;
+
+               case 2:
+               writedata8(0x80|0x08);
+               LCD_W  = 240;
+               LCD_H = 320;
+               break;
+
+               case 3:
+               writedata8(0x40|0x80|0x20|0x08);
+               LCD_W  = 320;
+               LCD_H = 240;
+               break;
+       }
+    m_Spi->end();
+}
diff --git a/HAL/Drivers/Ili9341.h b/HAL/Drivers/Ili9341.h
new file mode 100644 (file)
index 0000000..6d5d7a4
--- /dev/null
@@ -0,0 +1,87 @@
+#ifndef __ILI9341_H__
+#define __ILI9341_H__
+
+#define ILI9341_TFTWIDTH  240
+#define ILI9341_TFTHEIGHT 320
+
+#define LCD_CSN_PORT PORTB
+#define LCD_CSN_DDR  DDRB
+#define LCD_CSN      PIN2
+
+#define LCD_CMD_PORT PORTC
+#define LCD_CMD_DDR  DDRC
+#define LCD_CMD      PIN0
+
+#define LCD_RST_PORT PORTC
+#define LCD_RST_DDR  DDRC
+#define LCD_RST      PIN1
+/**
+ *
+ */
+#define ILI9341_BLACK     0x0000
+#define ILI9341_NAVY      0x000F
+#define ILI9341_DARKGREEN 0x03E0
+#define ILI9341_DARKCYAN  0x03EF
+#define ILI9341_MAROON    0x7800
+#define ILI9341_PURPLE    0x780F
+#define ILI9341_OLIVE     0x7BE0
+#define ILI9341_LIGHTGREY 0xC618
+#define ILI9341_DARKGREY  0x7BEF
+#define ILI9341_BLUE      0x001F
+#define ILI9341_GREEN     0x07E0
+#define ILI9341_CYAN      0x07FF
+#define ILI9341_RED       0xF800
+#define ILI9341_MAGENTA   0xF81F
+#define ILI9341_YELLOW    0xFFE0
+#define ILI9341_WHITE     0xFFFF
+#define ILI9341_ORANGE    0xFD20
+#define ILI9341_GREENYELLOW 0xAFE5
+#define ILI9341_PINK      0xFC18
+
+
+
+/**
+ * ILI 9341 LDC 2.2" LDC driver
+ */
+class Ili9341
+{
+  public:
+    Ili9341(ISpi *_spi);
+  public:
+
+    void hard_reset(void) ; //hard reset display
+
+    void init(void) ; //set up display using predefined command sequence
+    //clear lcd and fill with colour
+    void clear(uint16_t colour);
+    //draw pixel
+    void drawpixel(uint16_t x3,uint16_t y3,uint16_t colour1); //pixels will always be counted from right side.x is representing LCD width which will always be less tha 240.Y is representing LCD height which will always be less than 320
+    //draw vertical line
+    void drawvline(uint16_t x,uint16_t y,uint16_t h,uint16_t colour); //basically we will see this line horizental if we see the display 320*240
+    /// draw horizental line
+    void drawhline(uint16_t x,uint16_t y,uint16_t w,uint16_t colour);
+    /// draw colour filled rectangle
+    void fillrect(uint16_t x,uint16_t y,uint16_t w,uint16_t h,uint16_t colour);
+
+    void setRotation(uint8_t m); 
+  protected:
+    //set colour for drawing
+    void pushcolour(uint16_t colour);
+    
+    void setaddress(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2); //set coordinate for print or other function
+  private:
+    void hard_init();
+
+    void spi_init();
+
+    uint8_t SPI_ExchangeByte( uint8_t input );
+
+    void writedata8(uint8_t data);//data write
+    
+    void writecommand8(uint8_t com);//command write
+
+  private:
+    ISpi *m_Spi;
+};
+
+#endif
diff --git a/HAL/Drivers/NetString.cpp b/HAL/Drivers/NetString.cpp
new file mode 100644 (file)
index 0000000..1ca77f4
--- /dev/null
@@ -0,0 +1,310 @@
+
+#include <avr/interrupt.h>
+
+#include "Abstract/IInterruptActivity.h"
+#include "Abstract/IUart.h"
+#include "Abstract/IProtocolLayer2.h"
+#include "AVR/AvrUart.h"
+#include "Drivers/NetString.h"
+
+
+NetString::NetString(IUart *_Uart)
+ : m_Uart(_Uart) 
+    , m_TxFrameSize(0)
+    , m_CurrentState(STATE_INIT)
+    , m_RxByteCount(0)
+    , m_TxByteCount(0)
+    , m_CharTickCount(3)
+    , m_CharTimeout(0)
+    , m_RxLength(0)
+{
+    init();
+}
+
+void
+NetString::init()
+{
+    uint8_t i = 0;
+    // Copy buffer
+    for ( ; i < BUFFER_SIZE ; i++)
+    {
+        m_RxBuffer[i] = 0;
+        m_TxBuffer[i] = 0;
+    }
+    setMode(MODE_RX);
+    m_Uart->enableReceive(false);
+    m_Uart->enableReceive(true);
+}
+/**
+ * @return a pointer to the received message
+ * if no message is available, return NULL.
+ */
+void 
+NetString::setTxMsg(const uint8_t *_src,uint8_t _length)
+{
+   // guard, dont overwrite 
+    if ( (_length < BUFFER_SIZE ) 
+         && ( m_TxFrameSize == 0)
+       )
+    {
+        uint8_t i = 0;
+        // Copy buffer
+        for ( ; i < _length ; i++)
+        {
+            m_TxBuffer[i] = _src[i];
+        }
+        m_TxFrameSize = _length;
+
+        m_TxByteCount = 0;
+    }
+}
+
+
+const uint8_t 
+NetString::getRxSize() const
+{
+    return m_RxLength;
+}
+/**
+ * @brief be sure that the state machine is in state
+ * IDle or else the upper layer will not be
+ * able to send data.
+ */
+const uint8_t *
+NetString::receiveMsg()
+{
+  // Only return the the buffer if the message is complete eg CRLF
+  if (( m_RxLength > 0 ) 
+     )
+  {
+      m_RxLength     = 0;
+      m_RxByteCount  = 0;
+      return &m_RxBuffer[0];
+  } else 
+  {
+      return 0;
+  }
+}
+
+/**
+ * \brief transmit message stored in m_RxBuffer.
+ * The message must previously be set by
+ * setTxMsg()
+ */
+void 
+NetString::transmitMsg()
+{
+  if (m_TxFrameSize > 0)
+  {
+    updateState(EVT_TRANSMIT);
+  }
+}
+/**
+ * @brief called by scheduler I think.
+ */
+
+void 
+NetString::tick()
+{
+    //  Is a character ready ? 
+    m_CharReceived = m_Uart->receive_ready();
+    if (m_CharReceived == true)
+    {
+        if (m_RxByteCount < BUFFER_SIZE)
+        {
+            m_RxBuffer[m_RxByteCount] = m_Uart->receive();
+            m_RxByteCount++;
+        } else
+        {
+            m_RxByteCount = 0;
+        }
+    }
+    if ( m_CharTimeout != 0)
+    {
+      m_CharTimeout--;
+    }
+    updateState(EVT_TICK);
+}
+
+/* State Machine actions */
+NetString::State_t
+NetString::doEntry(const Event_t _Event)
+{
+  State_t newState = STATE_INIT;
+  return newState;
+}
+
+NetString::State_t
+NetString::doInit(const Event_t _Event)
+{
+  State_t newState = STATE_INIT;
+
+  if (_Event == EVT_TICK)
+  {
+    if (! m_CharReceived)
+    {
+         newState = STATE_IDLE;
+    }
+  }
+  return newState;
+}
+
+NetString::State_t
+NetString::doIDle(const Event_t _Event)
+{
+  State_t newState = STATE_IDLE;
+  if (_Event == EVT_TRANSMIT)
+  {
+     setMode(MODE_TX);
+     newState = STATE_SEND;
+
+  } else if (_Event == EVT_TICK)
+  {
+      if (m_CharReceived ) 
+      {
+          startCharTimer();
+          newState = STATE_RECEIVE;
+      }
+  }
+  return newState;
+}
+
+NetString::State_t
+NetString::doSend(const Event_t _Event)
+{
+  State_t newState = STATE_SEND;
+  if (_Event == EVT_TICK)
+  {
+      if (m_Uart->transmit_ready())
+      {
+          if (m_TxByteCount < m_TxFrameSize)
+          {
+              m_Uart->transmit(m_TxBuffer[m_TxByteCount]);
+              m_TxByteCount ++;
+          } else 
+          {
+              m_TxFrameSize = 0;
+              m_TxByteCount = 0;
+              newState = STATE_IDLE;
+              setMode(MODE_RX);
+          }
+
+      } else
+      {
+      }
+  }
+  return newState;
+}
+
+NetString::State_t
+NetString::doReceive(const Event_t _Event)
+{
+  State_t newState = STATE_RECEIVE;
+  if (_Event == EVT_TICK)
+  {
+      // Check If char Received
+      if (!m_CharReceived)
+      {
+          if (charTimeout())
+          {
+              newState = STATE_CONTROL;
+          }
+      } 
+      else 
+      {   // char received, reset timer 
+          startCharTimer();
+      }
+  } else
+  {
+  }
+  return newState;
+}
+
+NetString::State_t
+NetString::doControl(const Event_t _Event)
+{
+  State_t newState = STATE_CONTROL;
+  if (_Event == EVT_TICK)
+  {
+      // Check If char Received
+      if ( ! m_CharReceived)
+      {     // Ok, no more char 
+            if (
+                    (m_RxBuffer[m_RxByteCount - 1] == 0x0A)
+                    || (m_RxBuffer[m_RxByteCount - 1] == 0x0D)
+               )
+            {
+                m_RxLength = m_RxByteCount;
+            }
+            newState = STATE_IDLE;
+      } else 
+      {     // Ok, that's an error.
+            if (
+                    (m_RxBuffer[m_RxByteCount - 1] == 0x0A)
+                    || (m_RxBuffer[m_RxByteCount - 1] == 0x0D)
+               )
+            {
+                m_RxLength = m_RxByteCount;
+                newState = STATE_IDLE;
+            } else
+            {
+                startCharTimer();
+                newState = STATE_RECEIVE;
+            }
+      }
+  } else
+  {
+  }
+  return newState;
+}
+
+void
+NetString::updateState(const Event_t _evt)
+{
+  State_t oldState = m_CurrentState;
+  // Does work on AVR!?        
+  static const NetString::pFunction_t laction[5] = {
+    &NetString::doInit
+    ,&NetString::doIDle
+    ,&NetString::doSend
+    ,&NetString::doReceive
+    ,&NetString::doControl
+  };
+
+  m_CurrentState = (this->*(laction[m_CurrentState]))(_evt);
+  if (oldState != m_CurrentState)
+  {
+    // Run entry action ....
+    (this->*(laction[m_CurrentState]))(EVT_ENTRY);
+  }
+}
+
+// Timing control
+
+bool 
+NetString::charTimeout() const
+{
+  
+  return m_CharTimeout == 0;
+}
+//
+void 
+NetString::startCharTimer()
+{
+  m_CharTimeout = m_CharTickCount;
+}
+    
+void 
+NetString::setMode(const Mode_t _mode)
+{
+  if (_mode == MODE_TX)
+  {
+    m_Uart->enableReceive(false);
+    m_Uart->enableTransmit(true);
+  }
+  else
+  {  // Ok, it's RX mode
+    m_Uart->enableTransmit(false);
+    m_Uart->enableReceive(true);
+  }
+}
diff --git a/HAL/Drivers/NetString.h b/HAL/Drivers/NetString.h
new file mode 100644 (file)
index 0000000..abf3c41
--- /dev/null
@@ -0,0 +1,88 @@
+#ifndef __NETSTRING_H__
+#define __NETSTRING_H__
+
+const uint8_t BUFFER_SIZE = 64;
+
+/**
+ * \brief this class is responsible to arbitrat
+ * between send and receive request. A state
+ * machine controls the behavior.
+ * On reception of a character, we start a timer
+ * to limit the receive time. CR return shall
+ * be sent before time out
+ *
+ */
+class NetString : public IProtocolLayer2
+{
+    enum State_t {  
+                   STATE_INIT = 0
+                 , STATE_IDLE = 1
+                 , STATE_SEND = 2
+                 , STATE_RECEIVE = 3
+                 , STATE_CONTROL = 4
+                 };
+    enum Event_t { EVT_NONE,EVT_TICK,EVT_TRANSMIT,EVT_ENTRY};
+
+    enum Mode_t { MODE_RX, MODE_TX};
+
+    typedef State_t (NetString::*pFunction_t)(const Event_t);
+  public:
+    NetString(IUart *_uart);
+
+    virtual void init();
+
+    virtual const uint8_t getRxSize() const;
+    /**
+     * @return a pointer to the received message
+     * if no message is available, return NULL.
+     */
+    virtual const uint8_t *receiveMsg();
+
+    virtual void setTxMsg(const uint8_t *_src,uint8_t _length);
+    /**
+     * \bried transmit message stored in m_Buffer.
+     * The message must previously be set by
+     * setTxMsg()
+     */
+    virtual void transmitMsg();
+    /**
+     * @brief called by scheduler I think.
+     */
+    virtual void tick();
+
+  private:
+    /* State Machine actions */
+    State_t doEntry(const Event_t _Event);
+    State_t doInit(const Event_t _Event);
+    State_t doIDle(const Event_t _Event);
+    State_t doSend(const Event_t _Event);
+    State_t doReceive(const Event_t _Event);
+    State_t doControl(const Event_t _Event);
+
+    void updateState(const Event_t _Event);
+    // Timing control
+    ///
+    void startCharTimer();
+    /// 
+    bool charTimeout() const;
+    ///
+    void setMode(const Mode_t _mode);
+  private:
+    IUart  *m_Uart;
+    uint8_t m_RxBuffer[BUFFER_SIZE];
+    uint8_t m_TxBuffer[BUFFER_SIZE];
+    uint8_t m_TxFrameSize;
+    State_t m_CurrentState;
+    bool    m_CharReceived;
+    uint8_t m_RxByteCount;
+    uint8_t m_TxByteCount;
+    /// Number of ticks for char input timeout
+    uint8_t m_CharTickCount;
+    /// If zero reached timeout for char input.
+    /// State machine goes back to state Idle
+    uint8_t m_CharTimeout;
+    /// Set to RxByteCount once check complete 
+    uint8_t m_RxLength;
+};
+
+#endif
diff --git a/HAL/Drivers/Rs485.h b/HAL/Drivers/Rs485.h
new file mode 100644 (file)
index 0000000..d6931a9
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef __RS485_H__
+#define __RS485_H__
+
+/**
+ * @brief Layer 2 protocol stack,
+ * Maybe I should inherit from a so called
+ * layer 2 interface that only exports 
+ * methods required by layer 3.
+ *
+ */
+class Rs485 : public IProtocolLayer2
+{
+  public:
+    Rs485(IUart &_itsUart);
+
+    /**
+     * @return a pointer to the received message
+     * if no message is available, return NULL.
+     */
+    virtual const uint8_t *receiveMsg();
+    /**
+     *
+     */
+    virtual void transmitMsg();
+    /**
+     * @brief called by scheduler I think.
+     */
+    void tick();
+  private:
+    IUart &m_Uart;
+};
+
+#endif
diff --git a/HAL/Drivers/XPT2046_Touchscreen.cpp b/HAL/Drivers/XPT2046_Touchscreen.cpp
new file mode 100644 (file)
index 0000000..ddce05a
--- /dev/null
@@ -0,0 +1,149 @@
+
+
+#include <Utils/StdTypes.h>
+#include <Abstract/ISPI.h>
+#include <Drivers/XPT2046_Touchscreen.h>
+
+#define Z_THRESHOLD    400
+#define MSEC_THRESHOLD 3
+//#define SPI_SETTING SPISettings(2000000,MSBFIRST,SPI_MODE0)
+#define SPI_SETTING SPISettings(1000000,MSBFIRST,SPI_MODE0)
+
+#define CS_HIGH() (PORTC |= _BV(m_CsPin))
+#define CS_LOW()  (PORTC &= ~_BV(m_CsPin))
+
+XPT2046Touchscreen::XPT2046Touchscreen(ISpi *_spi,uint8_t _cspin)
+  : m_Spi(_spi), m_x(0),m_y(0),m_z(0),m_CsPin(_cspin)
+{
+  PORTC |= _BV(_cspin);
+  DDRC |= _BV(_cspin);
+}
+
+
+bool
+XPT2046Touchscreen::isTouched()
+{
+  update();
+  return (m_z >= Z_THRESHOLD);
+}
+
+
+TSPoint
+XPT2046Touchscreen::getPoint()
+{
+  update();
+  return TSPoint(m_x,m_y,m_z);
+}
+
+
+void
+XPT2046Touchscreen::setRotation(uint8_t _r)
+{
+  m_Rotation = _r;
+}
+
+/**
+ * Try to find out what this does
+ */
+static int16_t besttwoavg( int16_t x , int16_t y , int16_t z )
+{
+  int16_t da, db, dc;
+  int16_t reta = 0;
+
+  if ( x > y ) da = x - y; else da = y - x;
+  if ( x > z ) db = x - z; else db = z - x;
+  if ( z > y ) dc = z - y; else dc = y - z;
+
+  if ( da <= db && da <= dc ) reta = (x + y) >> 1;
+  else if ( db <= da && db <= dc ) reta = (x + z) >> 1;
+  else reta = (y + z) >> 1;   //    else if ( dc <= da && dc <= db ) reta = (x + y) >> 1;
+
+  return (reta);
+}
+
+void 
+XPT2046Touchscreen::update()
+{
+  int16_t data[6],z1,z2,z,dummy;
+  uint8_t result8;
+  /* Verify last update. In ms */
+  uint32_t now = 1 ; //millis();
+  //if ( (now - m_ms)  < MSEC_THRESHOLD) return;
+
+  /**/
+  if (m_Spi)
+  {
+    m_Spi->begin(SPI_SETTING);
+    // low csPin
+    CS_LOW();
+    // Read Z1
+    m_Spi->transceive(static_cast<uint8_t>(0xB1),(uint8_t *)&result8);
+
+    m_Spi->transceive(static_cast<uint16_t>(0xC100),(uint16_t *)&z1);
+    z1>>=3;
+    z = z1 + 4095;
+
+    m_Spi->transceive(static_cast<uint16_t>(0x9100),(uint16_t *)&z2);
+    z2>>=3;
+    z -= z2;
+
+    if (z >= Z_THRESHOLD)
+    {
+      // Dummy read
+      m_Spi->transceive(static_cast<uint16_t>(0x9100),(uint16_t *)&dummy); 
+      // Read Y
+      m_Spi->transceive(static_cast<uint16_t>(0xD100),(uint16_t *)&data[0]); data[0]>>=3;
+      // Read X
+      m_Spi->transceive(static_cast<uint16_t>(0x9100),(uint16_t *)&data[1]); data[1]>>=3;
+      // Read Y
+      m_Spi->transceive(static_cast<uint16_t>(0xD100),(uint16_t *)&data[2]); data[2]>>=3;
+      // Read X
+      m_Spi->transceive(static_cast<uint16_t>(0x9100),(uint16_t *)&data[3]); data[3]>>=3;
+    } else 
+    {
+       for (uint8_t i = 0 ; i < 4 ; ++i) data[i] = 0;
+    }
+
+    m_Spi->transceive(static_cast<uint16_t>(0xD000),(uint16_t *)&data[4]); data[4]>>=3;
+    m_Spi->transceive(static_cast<uint16_t>(0x0000),(uint16_t *)(&data[5])); data[5]>>=3;
+    // Ok, low cs
+    CS_HIGH();
+    m_Spi->end();
+  } else
+    return ; // No SPI do nothing
+
+  if (z < 0) z = 0; // No negatif value for z
+  
+  if ( z < Z_THRESHOLD) // isTouched
+  {
+    m_z = 0;
+    return ; 
+  }
+  // Ok, touched update raw values
+  m_z = z;
+
+  int16_t x = besttwoavg( data[0], data[2], data[4] );
+  int16_t y = besttwoavg( data[1], data[3], data[5] );
+
+  m_ms = now;
+  switch (m_Rotation)
+  {
+    case 0:
+      m_x = 4095 -y;
+      m_y = x;
+    break;
+    case 1:
+      m_x = x;
+      m_y = y;
+    break;
+    case 2:
+      m_x = 4095 -y;
+      m_y = x;
+    break;
+    default:
+      m_x = 4095 - x;
+      m_y = 4095 - y;
+    break;
+  }
+}
+  
diff --git a/HAL/Drivers/XPT2046_Touchscreen.h b/HAL/Drivers/XPT2046_Touchscreen.h
new file mode 100644 (file)
index 0000000..23a5ee5
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef __XPT2046_TOUCHSCREEN__
+#define __XPT2046_TOUCHSCREEN__
+
+class TSPoint {
+  public:
+  TSPoint(void) : x(0), y(0), z(0) {}
+  TSPoint(int16_t x, int16_t y, int16_t z) : x(x), y(y), z(z) {}
+  bool operator==(TSPoint p) { return ((p.x == x) && (p.y == y) && (p.z == z)); }
+  bool operator!=(TSPoint p) { return ((p.x != x) || (p.y != y) || (p.z != z)); }
+  int16_t x, y, z;
+};
+
+/**
+ * XPT2046 Touch screen implementation.
+ *
+ */
+class XPT2046Touchscreen
+{
+  public:
+    XPT2046Touchscreen(ISpi *_spi,const uint8_t _cspin);
+
+    bool isTouched();
+
+    TSPoint getPoint();
+
+    void    setRotation(const uint8_t _r);
+    void    tick();
+  private:
+    void update();  
+  private:
+    ISpi *m_Spi;
+    int16_t  m_x,m_y,m_z;
+    uint32_t m_ms;
+    uint8_t  m_Rotation;
+    uint8_t  m_CsPin;
+    uint32_t m_Ticks;
+};
+#endif
diff --git a/HAL/Drivers/glcdfont.c b/HAL/Drivers/glcdfont.c
new file mode 100644 (file)
index 0000000..ae45aa6
--- /dev/null
@@ -0,0 +1,263 @@
+#ifndef FONT5X7_H
+#define FONT5X7_H
+
+// Standard ASCII 5x7 font
+
+const unsigned char glcdfont[] = {
+        0x00, 0x00, 0x00, 0x00, 0x00,
+       0x3E, 0x5B, 0x4F, 0x5B, 0x3E,
+       0x3E, 0x6B, 0x4F, 0x6B, 0x3E,
+       0x1C, 0x3E, 0x7C, 0x3E, 0x1C,
+       0x18, 0x3C, 0x7E, 0x3C, 0x18,
+       0x1C, 0x57, 0x7D, 0x57, 0x1C,
+       0x1C, 0x5E, 0x7F, 0x5E, 0x1C,
+       0x00, 0x18, 0x3C, 0x18, 0x00,
+       0xFF, 0xE7, 0xC3, 0xE7, 0xFF,
+       0x00, 0x18, 0x24, 0x18, 0x00,
+       0xFF, 0xE7, 0xDB, 0xE7, 0xFF,
+       0x30, 0x48, 0x3A, 0x06, 0x0E,
+       0x26, 0x29, 0x79, 0x29, 0x26,
+       0x40, 0x7F, 0x05, 0x05, 0x07,
+       0x40, 0x7F, 0x05, 0x25, 0x3F,
+       0x5A, 0x3C, 0xE7, 0x3C, 0x5A,
+       0x7F, 0x3E, 0x1C, 0x1C, 0x08,
+       0x08, 0x1C, 0x1C, 0x3E, 0x7F,
+       0x14, 0x22, 0x7F, 0x22, 0x14,
+       0x5F, 0x5F, 0x00, 0x5F, 0x5F,
+       0x06, 0x09, 0x7F, 0x01, 0x7F,
+       0x00, 0x66, 0x89, 0x95, 0x6A,
+       0x60, 0x60, 0x60, 0x60, 0x60,
+       0x94, 0xA2, 0xFF, 0xA2, 0x94,
+       0x08, 0x04, 0x7E, 0x04, 0x08,
+       0x10, 0x20, 0x7E, 0x20, 0x10,
+       0x08, 0x08, 0x2A, 0x1C, 0x08,
+       0x08, 0x1C, 0x2A, 0x08, 0x08,
+       0x1E, 0x10, 0x10, 0x10, 0x10,
+       0x0C, 0x1E, 0x0C, 0x1E, 0x0C,
+       0x30, 0x38, 0x3E, 0x38, 0x30,
+       0x06, 0x0E, 0x3E, 0x0E, 0x06,
+       0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x5F, 0x00, 0x00,
+       0x00, 0x07, 0x00, 0x07, 0x00,
+       0x14, 0x7F, 0x14, 0x7F, 0x14,
+       0x24, 0x2A, 0x7F, 0x2A, 0x12,
+       0x23, 0x13, 0x08, 0x64, 0x62,
+       0x36, 0x49, 0x56, 0x20, 0x50,
+       0x00, 0x08, 0x07, 0x03, 0x00,
+       0x00, 0x1C, 0x22, 0x41, 0x00,
+       0x00, 0x41, 0x22, 0x1C, 0x00,
+       0x2A, 0x1C, 0x7F, 0x1C, 0x2A,
+       0x08, 0x08, 0x3E, 0x08, 0x08,
+       0x00, 0x80, 0x70, 0x30, 0x00,
+       0x08, 0x08, 0x08, 0x08, 0x08,
+       0x00, 0x00, 0x60, 0x60, 0x00,
+       0x20, 0x10, 0x08, 0x04, 0x02,
+       0x3E, 0x51, 0x49, 0x45, 0x3E,
+       0x00, 0x42, 0x7F, 0x40, 0x00,
+       0x72, 0x49, 0x49, 0x49, 0x46,
+       0x21, 0x41, 0x49, 0x4D, 0x33,
+       0x18, 0x14, 0x12, 0x7F, 0x10,
+       0x27, 0x45, 0x45, 0x45, 0x39,
+       0x3C, 0x4A, 0x49, 0x49, 0x31,
+       0x41, 0x21, 0x11, 0x09, 0x07,
+       0x36, 0x49, 0x49, 0x49, 0x36,
+       0x46, 0x49, 0x49, 0x29, 0x1E,
+       0x00, 0x00, 0x14, 0x00, 0x00,
+       0x00, 0x40, 0x34, 0x00, 0x00,
+       0x00, 0x08, 0x14, 0x22, 0x41,
+       0x14, 0x14, 0x14, 0x14, 0x14,
+       0x00, 0x41, 0x22, 0x14, 0x08,
+       0x02, 0x01, 0x59, 0x09, 0x06,
+       0x3E, 0x41, 0x5D, 0x59, 0x4E,
+       0x7C, 0x12, 0x11, 0x12, 0x7C,
+       0x7F, 0x49, 0x49, 0x49, 0x36,
+       0x3E, 0x41, 0x41, 0x41, 0x22,
+       0x7F, 0x41, 0x41, 0x41, 0x3E,
+       0x7F, 0x49, 0x49, 0x49, 0x41,
+       0x7F, 0x09, 0x09, 0x09, 0x01,
+       0x3E, 0x41, 0x41, 0x51, 0x73,
+       0x7F, 0x08, 0x08, 0x08, 0x7F,
+       0x00, 0x41, 0x7F, 0x41, 0x00,
+       0x20, 0x40, 0x41, 0x3F, 0x01,
+       0x7F, 0x08, 0x14, 0x22, 0x41,
+       0x7F, 0x40, 0x40, 0x40, 0x40,
+       0x7F, 0x02, 0x1C, 0x02, 0x7F,
+       0x7F, 0x04, 0x08, 0x10, 0x7F,
+       0x3E, 0x41, 0x41, 0x41, 0x3E,
+       0x7F, 0x09, 0x09, 0x09, 0x06,
+       0x3E, 0x41, 0x51, 0x21, 0x5E,
+       0x7F, 0x09, 0x19, 0x29, 0x46,
+       0x26, 0x49, 0x49, 0x49, 0x32,
+       0x03, 0x01, 0x7F, 0x01, 0x03,
+       0x3F, 0x40, 0x40, 0x40, 0x3F,
+       0x1F, 0x20, 0x40, 0x20, 0x1F,
+       0x3F, 0x40, 0x38, 0x40, 0x3F,
+       0x63, 0x14, 0x08, 0x14, 0x63,
+       0x03, 0x04, 0x78, 0x04, 0x03,
+       0x61, 0x59, 0x49, 0x4D, 0x43,
+       0x00, 0x7F, 0x41, 0x41, 0x41,
+       0x02, 0x04, 0x08, 0x10, 0x20,
+       0x00, 0x41, 0x41, 0x41, 0x7F,
+       0x04, 0x02, 0x01, 0x02, 0x04,
+       0x40, 0x40, 0x40, 0x40, 0x40,
+       0x00, 0x03, 0x07, 0x08, 0x00,
+       0x20, 0x54, 0x54, 0x78, 0x40,
+       0x7F, 0x28, 0x44, 0x44, 0x38,
+       0x38, 0x44, 0x44, 0x44, 0x28,
+       0x38, 0x44, 0x44, 0x28, 0x7F,
+       0x38, 0x54, 0x54, 0x54, 0x18,
+       0x00, 0x08, 0x7E, 0x09, 0x02,
+       0x18, 0xA4, 0xA4, 0x9C, 0x78,
+       0x7F, 0x08, 0x04, 0x04, 0x78,
+       0x00, 0x44, 0x7D, 0x40, 0x00,
+       0x20, 0x40, 0x40, 0x3D, 0x00,
+       0x7F, 0x10, 0x28, 0x44, 0x00,
+       0x00, 0x41, 0x7F, 0x40, 0x00,
+       0x7C, 0x04, 0x78, 0x04, 0x78,
+       0x7C, 0x08, 0x04, 0x04, 0x78,
+       0x38, 0x44, 0x44, 0x44, 0x38,
+       0xFC, 0x18, 0x24, 0x24, 0x18,
+       0x18, 0x24, 0x24, 0x18, 0xFC,
+       0x7C, 0x08, 0x04, 0x04, 0x08,
+       0x48, 0x54, 0x54, 0x54, 0x24,
+       0x04, 0x04, 0x3F, 0x44, 0x24,
+       0x3C, 0x40, 0x40, 0x20, 0x7C,
+       0x1C, 0x20, 0x40, 0x20, 0x1C,
+       0x3C, 0x40, 0x30, 0x40, 0x3C,
+       0x44, 0x28, 0x10, 0x28, 0x44,
+       0x4C, 0x90, 0x90, 0x90, 0x7C,
+       0x44, 0x64, 0x54, 0x4C, 0x44,
+       0x00, 0x08, 0x36, 0x41, 0x00,
+       0x00, 0x00, 0x77, 0x00, 0x00,
+       0x00, 0x41, 0x36, 0x08, 0x00,
+       0x02, 0x01, 0x02, 0x04, 0x02,
+       0x3C, 0x26, 0x23, 0x26, 0x3C,
+       0x1E, 0xA1, 0xA1, 0x61, 0x12,
+       0x3A, 0x40, 0x40, 0x20, 0x7A,
+       0x38, 0x54, 0x54, 0x55, 0x59,
+       0x21, 0x55, 0x55, 0x79, 0x41,
+       0x21, 0x54, 0x54, 0x78, 0x41,
+       0x21, 0x55, 0x54, 0x78, 0x40,
+       0x20, 0x54, 0x55, 0x79, 0x40,
+       0x0C, 0x1E, 0x52, 0x72, 0x12,
+       0x39, 0x55, 0x55, 0x55, 0x59,
+       0x39, 0x54, 0x54, 0x54, 0x59,
+       0x39, 0x55, 0x54, 0x54, 0x58,
+       0x00, 0x00, 0x45, 0x7C, 0x41,
+       0x00, 0x02, 0x45, 0x7D, 0x42,
+       0x00, 0x01, 0x45, 0x7C, 0x40,
+       0xF0, 0x29, 0x24, 0x29, 0xF0,
+       0xF0, 0x28, 0x25, 0x28, 0xF0,
+       0x7C, 0x54, 0x55, 0x45, 0x00,
+       0x20, 0x54, 0x54, 0x7C, 0x54,
+       0x7C, 0x0A, 0x09, 0x7F, 0x49,
+       0x32, 0x49, 0x49, 0x49, 0x32,
+       0x32, 0x48, 0x48, 0x48, 0x32,
+       0x32, 0x4A, 0x48, 0x48, 0x30,
+       0x3A, 0x41, 0x41, 0x21, 0x7A,
+       0x3A, 0x42, 0x40, 0x20, 0x78,
+       0x00, 0x9D, 0xA0, 0xA0, 0x7D,
+       0x39, 0x44, 0x44, 0x44, 0x39,
+       0x3D, 0x40, 0x40, 0x40, 0x3D,
+       0x3C, 0x24, 0xFF, 0x24, 0x24,
+       0x48, 0x7E, 0x49, 0x43, 0x66,
+       0x2B, 0x2F, 0xFC, 0x2F, 0x2B,
+       0xFF, 0x09, 0x29, 0xF6, 0x20,
+       0xC0, 0x88, 0x7E, 0x09, 0x03,
+       0x20, 0x54, 0x54, 0x79, 0x41,
+       0x00, 0x00, 0x44, 0x7D, 0x41,
+       0x30, 0x48, 0x48, 0x4A, 0x32,
+       0x38, 0x40, 0x40, 0x22, 0x7A,
+       0x00, 0x7A, 0x0A, 0x0A, 0x72,
+       0x7D, 0x0D, 0x19, 0x31, 0x7D,
+       0x26, 0x29, 0x29, 0x2F, 0x28,
+       0x26, 0x29, 0x29, 0x29, 0x26,
+       0x30, 0x48, 0x4D, 0x40, 0x20,
+       0x38, 0x08, 0x08, 0x08, 0x08,
+       0x08, 0x08, 0x08, 0x08, 0x38,
+       0x2F, 0x10, 0xC8, 0xAC, 0xBA,
+       0x2F, 0x10, 0x28, 0x34, 0xFA,
+       0x00, 0x00, 0x7B, 0x00, 0x00,
+       0x08, 0x14, 0x2A, 0x14, 0x22,
+       0x22, 0x14, 0x2A, 0x14, 0x08,
+       0xAA, 0x00, 0x55, 0x00, 0xAA,
+       0xAA, 0x55, 0xAA, 0x55, 0xAA,
+       0x00, 0x00, 0x00, 0xFF, 0x00,
+       0x10, 0x10, 0x10, 0xFF, 0x00,
+       0x14, 0x14, 0x14, 0xFF, 0x00,
+       0x10, 0x10, 0xFF, 0x00, 0xFF,
+       0x10, 0x10, 0xF0, 0x10, 0xF0,
+       0x14, 0x14, 0x14, 0xFC, 0x00,
+       0x14, 0x14, 0xF7, 0x00, 0xFF,
+       0x00, 0x00, 0xFF, 0x00, 0xFF,
+       0x14, 0x14, 0xF4, 0x04, 0xFC,
+       0x14, 0x14, 0x17, 0x10, 0x1F,
+       0x10, 0x10, 0x1F, 0x10, 0x1F,
+       0x14, 0x14, 0x14, 0x1F, 0x00,
+       0x10, 0x10, 0x10, 0xF0, 0x00,
+       0x00, 0x00, 0x00, 0x1F, 0x10,
+       0x10, 0x10, 0x10, 0x1F, 0x10,
+       0x10, 0x10, 0x10, 0xF0, 0x10,
+       0x00, 0x00, 0x00, 0xFF, 0x10,
+       0x10, 0x10, 0x10, 0x10, 0x10,
+       0x10, 0x10, 0x10, 0xFF, 0x10,
+       0x00, 0x00, 0x00, 0xFF, 0x14,
+       0x00, 0x00, 0xFF, 0x00, 0xFF,
+       0x00, 0x00, 0x1F, 0x10, 0x17,
+       0x00, 0x00, 0xFC, 0x04, 0xF4,
+       0x14, 0x14, 0x17, 0x10, 0x17,
+       0x14, 0x14, 0xF4, 0x04, 0xF4,
+       0x00, 0x00, 0xFF, 0x00, 0xF7,
+       0x14, 0x14, 0x14, 0x14, 0x14,
+       0x14, 0x14, 0xF7, 0x00, 0xF7,
+       0x14, 0x14, 0x14, 0x17, 0x14,
+       0x10, 0x10, 0x1F, 0x10, 0x1F,
+       0x14, 0x14, 0x14, 0xF4, 0x14,
+       0x10, 0x10, 0xF0, 0x10, 0xF0,
+       0x00, 0x00, 0x1F, 0x10, 0x1F,
+       0x00, 0x00, 0x00, 0x1F, 0x14,
+       0x00, 0x00, 0x00, 0xFC, 0x14,
+       0x00, 0x00, 0xF0, 0x10, 0xF0,
+       0x10, 0x10, 0xFF, 0x10, 0xFF,
+       0x14, 0x14, 0x14, 0xFF, 0x14,
+       0x10, 0x10, 0x10, 0x1F, 0x00,
+       0x00, 0x00, 0x00, 0xF0, 0x10,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
+       0xFF, 0xFF, 0xFF, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0xFF, 0xFF,
+       0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
+       0x38, 0x44, 0x44, 0x38, 0x44,
+       0x7C, 0x2A, 0x2A, 0x3E, 0x14,
+       0x7E, 0x02, 0x02, 0x06, 0x06,
+       0x02, 0x7E, 0x02, 0x7E, 0x02,
+       0x63, 0x55, 0x49, 0x41, 0x63,
+       0x38, 0x44, 0x44, 0x3C, 0x04,
+       0x40, 0x7E, 0x20, 0x1E, 0x20,
+       0x06, 0x02, 0x7E, 0x02, 0x02,
+       0x99, 0xA5, 0xE7, 0xA5, 0x99,
+       0x1C, 0x2A, 0x49, 0x2A, 0x1C,
+       0x4C, 0x72, 0x01, 0x72, 0x4C,
+       0x30, 0x4A, 0x4D, 0x4D, 0x30,
+       0x30, 0x48, 0x78, 0x48, 0x30,
+       0xBC, 0x62, 0x5A, 0x46, 0x3D,
+       0x3E, 0x49, 0x49, 0x49, 0x00,
+       0x7E, 0x01, 0x01, 0x01, 0x7E,
+       0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
+       0x44, 0x44, 0x5F, 0x44, 0x44,
+       0x40, 0x51, 0x4A, 0x44, 0x40,
+       0x40, 0x44, 0x4A, 0x51, 0x40,
+       0x00, 0x00, 0xFF, 0x01, 0x03,
+       0xE0, 0x80, 0xFF, 0x00, 0x00,
+       0x08, 0x08, 0x6B, 0x6B, 0x08,
+       0x36, 0x12, 0x36, 0x24, 0x36,
+       0x06, 0x0F, 0x09, 0x0F, 0x06,
+       0x00, 0x00, 0x18, 0x18, 0x00,
+       0x00, 0x00, 0x10, 0x10, 0x00,
+       0x30, 0x40, 0xFF, 0x01, 0x01,
+       0x00, 0x1F, 0x01, 0x01, 0x1E,
+       0x00, 0x19, 0x1D, 0x17, 0x12,
+       0x00, 0x3C, 0x3C, 0x3C, 0x3C,
+       0x00, 0x00, 0x00, 0x00, 0x00
+};
+#endif // FONT5X7_H
\ No newline at end of file
diff --git a/Metadata/CMakeLists.txt b/Metadata/CMakeLists.txt
new file mode 100644 (file)
index 0000000..37acbe5
--- /dev/null
@@ -0,0 +1,18 @@
+#####################################################################
+# simple AVR library
+#####################################################################
+add_avr_library(
+       avrPowerswitchParameters
+       PowerswitchParameterTable.cpp
+   )
+
+add_avr_library(
+       avrDCMotorParameters
+       DCMotorParameterTable.cpp
+   )
+
+add_avr_library(
+       avrShutterCtrlParameters
+       ShutterCtrlParameterTable.cpp
+   )
+
diff --git a/Metadata/DCMotorParamIds.h b/Metadata/DCMotorParamIds.h
new file mode 100644 (file)
index 0000000..08dd5a1
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef __DCMOTORPARAMIDS_H__
+#define __DCMOTORPARAMIDS_H__
+
+
+/**
+ * Maybe put this in an include file
+ * DCMotorParamIds.h
+ */
+enum ParameterIds {
+      PID_MotorState =  0 /* State on or off */
+    , PID_MotorMode  =  1 /* DC Open loop,DC Closed loop, Stepper, brushless */
+    , PID_MotorPwm   =  2 /* Used In case of open loop   10 - 90 % */
+    , PID_MotorRpm   =  3 /* Used In case of closed loop uint16 I think */
+    , PID_MotorDir   =  4 /* 0 or 1 */
+    , PID_MotorBPwm  =  5
+    , PID_MotorBDir  =  6
+    , PID_LedCycle   =  7 /* Ye Blinking led cycle. 0 is off */
+    , PID_LedState   =  8 /* Set let state ... */
+    , PID_CPR        =  9 /* Cycle Per rotation used in closed loop  */
+    , PID_Kp         = 10 /* Set PID constant factor   */
+    , PID_Ki         = 11 /* Set PID integral factor   */
+    , PID_Kd         = 12 /* Set PID derivation factor */
+    , PID_MAConsPwm  = 13 /* Pwm modulation instruction, Applied in open loop, ignore in closed loop */
+    , PID_MAConsRpm  = 14 /* Rpm instruction used as reference in closed loop */
+    , PID_LowLevelError1  = 15 /* Low Level Error1  up to 32 errors */
+    , PID_LowLevelError2  = 16 /* Low Level Error2  up to 32 errors */
+    , PID_Pot0            = 17 /* Potentiometer value of Adc 0 */
+    , PID_MAX        = 18
+};
+#endif
diff --git a/Metadata/DCMotorParameterTable.cpp b/Metadata/DCMotorParameterTable.cpp
new file mode 100644 (file)
index 0000000..59386a6
--- /dev/null
@@ -0,0 +1,30 @@
+#include <Utils/StdTypes.h>
+#include <stdlib.h> // for itoa
+#include "Metadata/Metadata.h"
+#include "Platform/IParameterHandler.h"
+#include "DCMotorParamIds.h"
+#include "DCMotorParameterTable.h"
+
+
+ParameterValue m_Values[PID_MAX] =
+{
+  {1,NULL}
+  ,{2,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+
+};
diff --git a/Metadata/DCMotorParameterTable.h b/Metadata/DCMotorParameterTable.h
new file mode 100644 (file)
index 0000000..d6788fd
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef DCMOTORPARAMETERTABLE_H__
+#define DCMOTORPARAMETERTABLE_H__
+
+#include "Metadata/Metadata.h"
+extern
+ParameterValue m_Values[PID_MAX]; 
+#endif
diff --git a/Metadata/Metadata.h b/Metadata/Metadata.h
new file mode 100644 (file)
index 0000000..e630bec
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef __METADATA_H__
+#define __METADATA_H__
+
+/* Forward declaration */
+class IParameterListener;
+
+/**
+ * ParameterTable Structure
+ */
+typedef struct _ParameterValue_t 
+{
+  union ParameterValue 
+  {
+      uint8_t    m_U8;
+      uint16_t   m_U16;
+      uint32_t   m_U32;
+      Float32_t  m_Float;
+  } u;
+  IParameterListener *m_Listener;
+} ParameterValue;
+#endif
diff --git a/Metadata/PowerswitchParamIds.h b/Metadata/PowerswitchParamIds.h
new file mode 100644 (file)
index 0000000..78a641f
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef __DCMOTORPARAMIDS_H__
+#define __DCMOTORPARAMIDS_H__
+
+
+/**
+ * Maybe put this in an include file
+ * DCMotorParamIds.h
+ */
+enum ParameterIds {
+      PID_SwitchAll  =  0 /* State on or off */
+    , PID_Switch1    =  1 /* On / Off Socket 1 */
+    , PID_Switch2    =  2 /* On / Off Socket 2 */
+    , PID_Switch3    =  3 /* On / Off Socket 3 */
+    , PID_Switch4    =  4 /* On / Off Socket 4 */
+    , PID_LedCycle   =  5 /* Ye Blinking led cycle. 0 is off */
+    , PID_LedState   =  6 /* Set let state ... */
+    , PID_DelayP1    =  7
+    , PID_DelayP2    =  8
+    , PID_DelayP3    =  9 /* Cycle Per rotation used in closed loop  */
+    , PID_DelayP4    = 10 /* Set PID constant factor   */
+    , PID_Ki         = 11 /* Set PID integral factor   */
+    , PID_Kd         = 12 /* Set PID derivation factor */
+    , PID_MAConsPwm  = 13 /* Pwm modulation instruction, Applied in open loop, ignore in closed loop */
+    , PID_MAConsRpm  = 14 /* Rpm instruction used as reference in closed loop */
+    , PID_LowLevelError1  = 15 /* Low Level Error1  up to 32 errors */
+    , PID_LowLevelError2  = 16 /* Low Level Error2  up to 32 errors */
+    , PID_MAX        = 17
+};
+#endif
diff --git a/Metadata/PowerswitchParameterTable.cpp b/Metadata/PowerswitchParameterTable.cpp
new file mode 100644 (file)
index 0000000..46f94c8
--- /dev/null
@@ -0,0 +1,30 @@
+#include <Utils/StdTypes.h>
+#include <stdlib.h> // for itoa
+#include "Metadata/Metadata.h"
+#include "Platform/IParameterHandler.h"
+#include "DCMotorParamIds.h"
+#include "DCMotorParameterTable.h"
+
+
+ParameterValue m_Values[PID_MAX] =
+{
+  {0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+
+};
diff --git a/Metadata/PowerswitchParameterTable.h b/Metadata/PowerswitchParameterTable.h
new file mode 100644 (file)
index 0000000..45a52d0
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef POWERSWITCHPARAMETERTABLE_H__
+#define POWERSWITCHPARAMETERTABLE_H__
+
+#include "Metadata/Metadata.h"
+extern
+ParameterValue m_Values[PID_MAX]; 
+#endif
diff --git a/Metadata/ShutterCtrlParamIds.h b/Metadata/ShutterCtrlParamIds.h
new file mode 100644 (file)
index 0000000..84a9c7d
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef __DCMOTORPARAMIDS_H__
+#define __DCMOTORPARAMIDS_H__
+
+
+/**
+ * Maybe put this in an include file
+ * DCMotorParamIds.h
+ */
+enum ParameterIds {
+      PID_SwitchAll  =  0 /* State on or off */
+    , PID_Shutter1    =  1 /* On / Off Socket 1 */
+    , PID_Shutter2    =  2 /* On / Off Socket 2 */
+    , PID_Shutter3    =  3 /* On / Off Socket 3 */
+    , PID_Shutter4    =  4 /* On / Off Socket 4 */
+    , PID_LedCycle   =  5 /* Ye Blinking led cycle. 0 is off */
+    , PID_LedState   =  6 /* Set let state ... */
+    , PID_DelayP1    =  7
+    , PID_DelayP2    =  8
+    , PID_DelayP3    =  9 /* Cycle Per rotation used in closed loop  */
+    , PID_DelayP4    = 10 /* Set PID constant factor   */
+    , PID_Px         = 11 /* Set PID integral factor   */
+    , PID_Py         = 12 /* Set PID derivation factor */
+    , PID_Pz         = 13 /* Pwm modulation instruction, Applied in open loop, ignore in closed loop */
+    , PID_MAConsRpm  = 14 /* Rpm instruction used as reference in closed loop */
+    , PID_LowLevelError1  = 15 /* Low Level Error1  up to 32 errors */
+    , PID_LowLevelError2  = 16 /* Low Level Error2  up to 32 errors */
+    , PID_MAX        = 17
+};
+#endif
diff --git a/Metadata/ShutterCtrlParameterTable.cpp b/Metadata/ShutterCtrlParameterTable.cpp
new file mode 100644 (file)
index 0000000..46f94c8
--- /dev/null
@@ -0,0 +1,30 @@
+#include <Utils/StdTypes.h>
+#include <stdlib.h> // for itoa
+#include "Metadata/Metadata.h"
+#include "Platform/IParameterHandler.h"
+#include "DCMotorParamIds.h"
+#include "DCMotorParameterTable.h"
+
+
+ParameterValue m_Values[PID_MAX] =
+{
+  {0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+  ,{0,NULL}
+
+};
diff --git a/Metadata/ShutterCtrlParameterTable.h b/Metadata/ShutterCtrlParameterTable.h
new file mode 100644 (file)
index 0000000..45a52d0
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef POWERSWITCHPARAMETERTABLE_H__
+#define POWERSWITCHPARAMETERTABLE_H__
+
+#include "Metadata/Metadata.h"
+extern
+ParameterValue m_Values[PID_MAX]; 
+#endif
diff --git a/Platform/CMakeLists.txt b/Platform/CMakeLists.txt
new file mode 100644 (file)
index 0000000..244b2d2
--- /dev/null
@@ -0,0 +1,21 @@
+#####################################################################
+# simple AVR library
+#####################################################################
+add_avr_library(
+    avrPtf
+    DCMotorParameterHandler.cpp
+    PersistentStorage.cpp
+   )
+
+add_avr_library(
+    avrPS-Ptf
+    PowerswitchParameterHandler.cpp
+    PersistentStorage.cpp
+   )
+
+add_avr_library(
+    avrSC-Ptf
+    ShutterCtrlParameterHandler.cpp
+    PersistentStorage.cpp
+   )
+
diff --git a/Platform/DCMotorParameterHandler.cpp b/Platform/DCMotorParameterHandler.cpp
new file mode 100644 (file)
index 0000000..d7e4f5f
--- /dev/null
@@ -0,0 +1,96 @@
+#include <Utils/StdTypes.h>
+
+#include <Platform/IParameterHandler.h>
+#include <Metadata/DCMotorParamIds.h>
+#include <Metadata/DCMotorParameterTable.h>
+#include <Platform/DCMotorParameterHandler.h>
+
+#if 0
+DCMotorParameterHandler::ParameterValue 
+DCMotorParameterHandler::m_Values[PID_MAX] = { 0 };
+#endif
+DCMotorParameterHandler::DCMotorParameterHandler()
+{
+  
+}
+///
+void
+DCMotorParameterHandler::readValue(const uint8_t paramID,uint8_t &_val)
+{
+    if (paramID < PID_MAX)
+    {
+        _val = m_Values[paramID].u.m_U8;
+    } 
+}
+
+///
+void
+DCMotorParameterHandler::writeValue(const uint8_t paramID,const uint8_t _val)
+{
+    if (paramID < PID_MAX)
+    {
+        m_Values[paramID].u.m_U8 = _val;
+        if (m_Values[paramID].m_Listener != 0 )
+        {
+            m_Values[paramID].m_Listener->onWriteValue(paramID,_val);
+        }
+    } 
+}
+
+/// Handle UInt16_t
+void
+DCMotorParameterHandler::readValue(const uint8_t paramID,uint16_t &_val)
+{
+    if (paramID < PID_MAX)
+    {
+        _val = m_Values[paramID].u.m_U16;
+    } 
+}
+
+///
+void
+DCMotorParameterHandler::writeValue(const uint8_t paramID,const uint16_t _val)
+{
+    if (paramID < PID_MAX)
+    {
+        m_Values[paramID].u.m_U16 = _val;
+        if (m_Values[paramID].m_Listener != 0 )
+        {
+            m_Values[paramID].m_Listener->onWriteValue(paramID,m_Values[paramID].u.m_U8);
+        }
+    } 
+}
+
+/// Handle Float32_t
+void
+DCMotorParameterHandler::readValue(const uint8_t paramID,Float32_t &_val)
+{
+    if (paramID < PID_MAX)
+    {
+        _val = m_Values[paramID].u.m_Float;
+    } 
+}
+
+///
+void
+DCMotorParameterHandler::writeValue(const uint8_t paramID,const Float32_t _val)
+{
+    if (paramID < PID_MAX)
+    {
+        m_Values[paramID].u.m_Float = _val;
+        if (m_Values[paramID].m_Listener != 0 )
+        {
+            m_Values[paramID].m_Listener->onWriteValue(paramID,m_Values[paramID].u.m_Float);
+        }
+    } 
+}
+
+void 
+DCMotorParameterHandler::registerListener(const uint8_t paramID,IParameterListener *_val)
+{
+    if (paramID < PID_MAX)
+    {
+        m_Values[paramID].m_Listener = _val;
+    } 
+
+}
diff --git a/Platform/DCMotorParameterHandler.h b/Platform/DCMotorParameterHandler.h
new file mode 100644 (file)
index 0000000..42a80d4
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef __DCMOTOR_PARAMETERHANDLER_H__
+#define __DCMOTOR_PARAMETERHANDLER_H__
+
+
+/**
+ * @brief storage class 
+ *
+ */
+class DCMotorParameterHandler : public IParameterHandler
+{
+#if 0
+    typedef struct _ParameterValue_t 
+    {
+        union ParameterValue 
+        {
+            uint8_t    m_U8;
+            uint16_t   m_U16;
+            uint32_t   m_U32;
+            Float32_t  m_Float;
+        } u;
+        IParameterListener *m_Listener;
+    } ParameterValue;
+#endif
+    public:
+        DCMotorParameterHandler();
+        ///
+        virtual void readValue(const uint8_t paramID,uint8_t &_val);
+        ///
+        virtual void writeValue(const uint8_t paramID,const uint8_t _val);
+        ///
+        virtual void readValue(const uint8_t paramID,uint16_t &_val);
+        ///
+        virtual void writeValue(const uint8_t paramID,const uint16_t _val);
+        
+       ///
+        virtual void readValue(const uint8_t paramID,Float32_t &_val) ;
+        ///
+        virtual void writeValue(const uint8_t paramID,const Float32_t _val) ;
+        ///
+        ///
+        virtual void registerListener(const uint8_t paramID,IParameterListener *_val);
+
+
+    private:
+};
+
+#endif
diff --git a/Platform/ErrorHandler.h b/Platform/ErrorHandler.h
new file mode 100644 (file)
index 0000000..ff03c17
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef __ERROR_HANDLER_H__
+#define __ERROR_HANDLER_H__
+
+/**
+ * \brief good, lets implement basic error handler
+ * that reports the error through the serial communication
+ * May be I have to got through the communication handler
+ *
+ *
+ */
+class ErrorHandler : public IErrorHandler , public ITask
+{
+    public:
+        ErrorHandler();
+        /// Method available to modules so that errors can be reported
+        virtual void setError(Uint16_t _error);
+        /// Alright process some stuff in case an errors has been raised
+        virtual void run();
+};
+
+#endif
diff --git a/Platform/Errors.h b/Platform/Errors.h
new file mode 100644 (file)
index 0000000..c457426
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef __ERRORS_H__
+#define __ERRORS_H__
+
+enum ErrorIds_t {
+   ERROR_Application_Starting        = 0
+  ,ERROR_Eeprom_Read_Invalid_Length  = 1
+  ,ERROR_Eeprom_Read_Invalid_Address = 2
+  ,ERROR_Eeprom_Write_Invalid_Length  = 3
+  ,ERROR_Eeprom_Write_Invalid_Address = 4
+  ,ERROR_MAX = 5
+};
+#endif
diff --git a/Platform/IErrorHandler.h b/Platform/IErrorHandler.h
new file mode 100644 (file)
index 0000000..6f7c9b0
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef __IERROR_HANDLER_H__
+#define __IERROR_HANDLER_H__
+
+/**
+ * \brief well, except setting an error, there is not mutch to be
+ * done there. The handler might eventually trigger the communication
+ * handler to report the error or what ever.
+ */
+class IErrorHandler 
+{
+    public:
+        IErrorHandler() {};
+        /// 
+        virtual setError(Uint16_t error_id) = 0 ;
+};
+#endif
diff --git a/Platform/IParameterHandler.h b/Platform/IParameterHandler.h
new file mode 100644 (file)
index 0000000..af19049
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef __IPARAMETER_HANDLER_H__
+#define __IPARAMETER_HANDLER_H__
+
+/**
+ * \brief interface to be implemented by
+ * objects that need to be informed that a parameter
+ * value has changed or that a command needs to be 
+ * executed
+ */
+class IParameterListener
+{
+    public:
+        IParameterListener() {};
+        
+       virtual void onWriteValue(const uint8_t paramID,const uint8_t   _val) = 0;
+
+        virtual void onWriteValue(const uint8_t paramID,const Float32_t _val) = 0;
+};
+
+/**
+ * \brief Parameter Handling interface. Offer a unique space for
+ * dynamic storage.
+ *
+ */
+class IParameterHandler
+{
+    public:
+        enum eParameterType {
+              TYPE_U8    = 0
+            , TYPE_U16   = 1
+            , TYPE_FLOAT = 2
+        };
+    public:
+        IParameterHandler() {};
+        
+        virtual void readValue(const uint8_t paramID,uint8_t &_val) = 0;
+        ///
+        virtual void writeValue(const uint8_t paramID,const uint8_t _val) = 0;
+        ///
+        virtual void readValue(const uint8_t paramID,uint16_t &_val) = 0;
+        ///
+        virtual void writeValue(const uint8_t paramID,const uint16_t _val) = 0;
+        ///
+        virtual void readValue(const uint8_t paramID,Float32_t &_val) = 0;
+        ///
+        virtual void writeValue(const uint8_t paramID,const Float32_t _val) = 0;
+        ///
+        virtual void registerListener(const uint8_t paramID,IParameterListener *_val) = 0;
+};
+#endif
diff --git a/Platform/PersistentStorage.cpp b/Platform/PersistentStorage.cpp
new file mode 100644 (file)
index 0000000..526ba3a
--- /dev/null
@@ -0,0 +1,60 @@
+#include <Utils/StdTypes.h>
+
+#include <HAL/Abstract/IEeprom.h>
+#include <Application/ITask.h>
+#include <Platform/IParameterHandler.h>
+#include <Platform/PersistentStorage.h>
+
+PersistentStorage::PersistentStorage(IEeprom *_eeprom,IParameterHandler *_params)
+   : m_Eeprom(_eeprom),m_ParameterHandler(_params) , m_State(PS_Idle),m_CurrentParamId(0)
+{
+}
+
+void
+PersistentStorage::run()
+{
+  switch (m_State)
+  {
+    case PS_Idle:
+      doIdle();
+      break;
+    case PS_Init:
+      doInit();
+      break;
+    case PS_Saving:
+      doSave();
+      break;
+    case PS_Reading:
+      doRead();
+      break;
+    case PS_Done:
+      doDone();
+      break;
+    default:
+      ;
+  }
+}
+
+void
+PersistentStorage::doSave()
+{
+}
+
+void
+PersistentStorage::doRead()
+{
+}
+
+void
+PersistentStorage::doInit()
+{
+}
+
+void
+PersistentStorage::doIdle()
+{
+}
+void
+PersistentStorage::doDone()
+{
+}
diff --git a/Platform/PersistentStorage.h b/Platform/PersistentStorage.h
new file mode 100644 (file)
index 0000000..50d4eb6
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef __PERSISTENT_STORAGE_H__
+#define __PERSISTENT_STORAGE_H__
+
+/**
+ * \brief This class is responsible to store 
+ * parameters into eeprom. Parameters flaged as modified
+ * will be stored.
+ *
+ */
+class PersistentStorage : public virtual ITask
+{
+    enum eState {PS_Idle, PS_Init,PS_Saving, PS_Reading,PS_Done };
+    public:
+        /**
+         * Well, need the EEProm Interface and the ParameterHandler
+         */
+        PersistentStorage(IEeprom *_eeprom,IParameterHandler *_params);
+
+        virtual void run();
+    private:
+        /// Methods that will perform the  work
+       void doSave();
+       /// Read parameters from Eeprom
+       void doRead();
+       ///  Start Reading of Saving process 
+       void doInit();
+       ///  Check if save or read command is activated
+       void doIdle();
+       ///  Command completed
+       void doDone();
+    private:
+        /// Private Attributes
+       IEeprom           *m_Eeprom;
+       IParameterHandler *m_ParameterHandler;
+       eState             m_State;
+       Uint8_t            m_CurrentParamId;
+};
+#endif
diff --git a/Platform/PowerswitchParameterHandler.cpp b/Platform/PowerswitchParameterHandler.cpp
new file mode 100644 (file)
index 0000000..7797a0c
--- /dev/null
@@ -0,0 +1,92 @@
+#include <Utils/StdTypes.h>
+
+#include <Platform/IParameterHandler.h>
+#include <Metadata/PowerswitchParamIds.h>
+#include <Metadata/PowerswitchParameterTable.h>
+#include <Platform/PowerswitchParameterHandler.h>
+
+PowerswitchParameterHandler::PowerswitchParameterHandler()
+{
+  
+}
+///
+void
+PowerswitchParameterHandler::readValue(const uint8_t paramID,uint8_t &_val)
+{
+    if (paramID < PID_MAX)
+    {
+        _val = m_Values[paramID].u.m_U8;
+    } 
+}
+
+///
+void
+PowerswitchParameterHandler::writeValue(const uint8_t paramID,const uint8_t _val)
+{
+    if (paramID < PID_MAX)
+    {
+        m_Values[paramID].u.m_U8 = _val;
+        if (m_Values[paramID].m_Listener != 0 )
+        {
+            m_Values[paramID].m_Listener->onWriteValue(paramID,_val);
+        }
+    } 
+}
+
+/// Handle UInt16_t
+void
+PowerswitchParameterHandler::readValue(const uint8_t paramID,uint16_t &_val)
+{
+    if (paramID < PID_MAX)
+    {
+        _val = m_Values[paramID].u.m_U16;
+    } 
+}
+
+///
+void
+PowerswitchParameterHandler::writeValue(const uint8_t paramID,const uint16_t _val)
+{
+    if (paramID < PID_MAX)
+    {
+        m_Values[paramID].u.m_U16 = _val;
+        if (m_Values[paramID].m_Listener != 0 )
+        {
+            m_Values[paramID].m_Listener->onWriteValue(paramID,m_Values[paramID].u.m_U8);
+        }
+    } 
+}
+
+/// Handle Float32_t
+void
+PowerswitchParameterHandler::readValue(const uint8_t paramID,Float32_t &_val)
+{
+    if (paramID < PID_MAX)
+    {
+        _val = m_Values[paramID].u.m_Float;
+    } 
+}
+
+///
+void
+PowerswitchParameterHandler::writeValue(const uint8_t paramID,const Float32_t _val)
+{
+    if (paramID < PID_MAX)
+    {
+        m_Values[paramID].u.m_Float = _val;
+        if (m_Values[paramID].m_Listener != 0 )
+        {
+            m_Values[paramID].m_Listener->onWriteValue(paramID,m_Values[paramID].u.m_Float);
+        }
+    } 
+}
+
+void 
+PowerswitchParameterHandler::registerListener(const uint8_t paramID,IParameterListener *_val)
+{
+    if (paramID < PID_MAX)
+    {
+        m_Values[paramID].m_Listener = _val;
+    } 
+
+}
diff --git a/Platform/PowerswitchParameterHandler.h b/Platform/PowerswitchParameterHandler.h
new file mode 100644 (file)
index 0000000..13f48e8
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef __DCMOTOR_PARAMETERHANDLER_H__
+#define __DCMOTOR_PARAMETERHANDLER_H__
+
+
+/**
+ * @brief storage class 
+ *
+ */
+class PowerswitchParameterHandler : public IParameterHandler
+{
+    public:
+        PowerswitchParameterHandler();
+        ///
+        virtual void readValue(const uint8_t paramID,uint8_t &_val);
+        ///
+        virtual void writeValue(const uint8_t paramID,const uint8_t _val);
+        ///
+        virtual void readValue(const uint8_t paramID,uint16_t &_val);
+        ///
+        virtual void writeValue(const uint8_t paramID,const uint16_t _val);
+        
+       ///
+        virtual void readValue(const uint8_t paramID,Float32_t &_val) ;
+        ///
+        virtual void writeValue(const uint8_t paramID,const Float32_t _val) ;
+        ///
+        ///
+        virtual void registerListener(const uint8_t paramID,IParameterListener *_val);
+
+
+    private:
+};
+
+#endif
diff --git a/Platform/ShutterCtrlParameterHandler.cpp b/Platform/ShutterCtrlParameterHandler.cpp
new file mode 100644 (file)
index 0000000..1d2d863
--- /dev/null
@@ -0,0 +1,92 @@
+#include <Utils/StdTypes.h>
+
+#include <Platform/IParameterHandler.h>
+#include <Metadata/ShutterCtrlParamIds.h>
+#include <Metadata/ShutterCtrlParameterTable.h>
+#include <Platform/ShutterCtrlParameterHandler.h>
+
+ShutterCtrlParameterHandler::ShutterCtrlParameterHandler()
+{
+  
+}
+///
+void
+ShutterCtrlParameterHandler::readValue(const uint8_t paramID,uint8_t &_val)
+{
+    if (paramID < PID_MAX)
+    {
+        _val = m_Values[paramID].u.m_U8;
+    } 
+}
+
+///
+void
+ShutterCtrlParameterHandler::writeValue(const uint8_t paramID,const uint8_t _val)
+{
+    if (paramID < PID_MAX)
+    {
+        m_Values[paramID].u.m_U8 = _val;
+        if (m_Values[paramID].m_Listener != 0 )
+        {
+            m_Values[paramID].m_Listener->onWriteValue(paramID,_val);
+        }
+    } 
+}
+
+/// Handle UInt16_t
+void
+ShutterCtrlParameterHandler::readValue(const uint8_t paramID,uint16_t &_val)
+{
+    if (paramID < PID_MAX)
+    {
+        _val = m_Values[paramID].u.m_U16;
+    } 
+}
+
+///
+void
+ShutterCtrlParameterHandler::writeValue(const uint8_t paramID,const uint16_t _val)
+{
+    if (paramID < PID_MAX)
+    {
+        m_Values[paramID].u.m_U16 = _val;
+        if (m_Values[paramID].m_Listener != 0 )
+        {
+            m_Values[paramID].m_Listener->onWriteValue(paramID,m_Values[paramID].u.m_U8);
+        }
+    } 
+}
+
+/// Handle Float32_t
+void
+ShutterCtrlParameterHandler::readValue(const uint8_t paramID,Float32_t &_val)
+{
+    if (paramID < PID_MAX)
+    {
+        _val = m_Values[paramID].u.m_Float;
+    } 
+}
+
+///
+void
+ShutterCtrlParameterHandler::writeValue(const uint8_t paramID,const Float32_t _val)
+{
+    if (paramID < PID_MAX)
+    {
+        m_Values[paramID].u.m_Float = _val;
+        if (m_Values[paramID].m_Listener != 0 )
+        {
+            m_Values[paramID].m_Listener->onWriteValue(paramID,m_Values[paramID].u.m_Float);
+        }
+    } 
+}
+
+void 
+ShutterCtrlParameterHandler::registerListener(const uint8_t paramID,IParameterListener *_val)
+{
+    if (paramID < PID_MAX)
+    {
+        m_Values[paramID].m_Listener = _val;
+    } 
+
+}
diff --git a/Platform/ShutterCtrlParameterHandler.h b/Platform/ShutterCtrlParameterHandler.h
new file mode 100644 (file)
index 0000000..d448d6e
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef __DCMOTOR_PARAMETERHANDLER_H__
+#define __DCMOTOR_PARAMETERHANDLER_H__
+
+
+/**
+ * @brief storage class 
+ *
+ */
+class ShutterCtrlParameterHandler : public IParameterHandler
+{
+    public:
+        ShutterCtrlParameterHandler();
+        ///
+        virtual void readValue(const uint8_t paramID,uint8_t &_val);
+        ///
+        virtual void writeValue(const uint8_t paramID,const uint8_t _val);
+        ///
+        virtual void readValue(const uint8_t paramID,uint16_t &_val);
+        ///
+        virtual void writeValue(const uint8_t paramID,const uint16_t _val);
+        
+       ///
+        virtual void readValue(const uint8_t paramID,Float32_t &_val) ;
+        ///
+        virtual void writeValue(const uint8_t paramID,const Float32_t _val) ;
+        ///
+        ///
+        virtual void registerListener(const uint8_t paramID,IParameterListener *_val);
+
+
+    private:
+};
+
+#endif
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..d34ea4c
--- /dev/null
+++ b/README
@@ -0,0 +1,12 @@
+Packages to install on linux
+----------------------------
+sudo apt-get install gcc-avr avr-libc avrdude
+
+Create Build environment:
+------------------------
+Create a Build dir and launch the command below:
+
+cmake -DCMAKE_TOOLCHAIN_FILE=/home/aebersol/Devs/avr/rules/gcc-avr-generic.cmake  ../
+
+Flashing instruction
+--------------------
diff --git a/Utils/StdTypes.h b/Utils/StdTypes.h
new file mode 100644 (file)
index 0000000..4b53b30
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef __STD_TYPES_H__
+#define __STD_TYPES_H__
+#include <avr/io.h>
+/**
+ * @ brief Abstract all native types to be
+ * platform / compiler type independant
+ *
+ */
+
+///
+typedef void     Void;
+
+/// 
+typedef bool     Bool_t;
+
+///
+typedef uint8_t  Uint8_t;
+
+///
+typedef uint16_t Uint16_t;
+
+///
+typedef uint32_t Uint32_t;
+
+///
+typedef int8_t   Int8_t;
+
+///
+typedef int16_t  Int16_t;
+
+///
+typedef double   Float32_t;
+
+#endif
diff --git a/rules/gcc-avr-common.cmake b/rules/gcc-avr-common.cmake
new file mode 100644 (file)
index 0000000..fa27335
--- /dev/null
@@ -0,0 +1,73 @@
+
+##########################################################################
+# needs to be defined for AVR toolchain
+##########################################################################
+#set(MCU_SPEED "4000000UL")
+set(MCU_SPEED "16000000UL")
+
+##########################################################################
+# some cmake cross-compile necessities
+##########################################################################
+
+if(DEFINED ENV{AVR_FIND_ROOT_PATH})
+    set(CMAKE_FIND_ROOT_PATH $ENV{AVR_FIND_ROOT_PATH})
+else(DEFINED ENV{AVR_FIND_ROOT_PATH})
+    if(EXISTS "/opt/local/avr")
+      set(CMAKE_FIND_ROOT_PATH "/opt/local/avr")
+    elseif(EXISTS "/usr/avr")
+      set(CMAKE_FIND_ROOT_PATH "/usr/avr")
+    elseif(EXISTS "/usr/lib/avr")
+      set(CMAKE_FIND_ROOT_PATH "/usr/lib/avr")
+    elseif(EXISTS "/usr/local/CrossPack-AVR")
+      set(CMAKE_FIND_ROOT_PATH "/usr/local/CrossPack-AVR")
+    else(EXISTS "/opt/local/avr")
+      message(FATAL_ERROR "Please set AVR_FIND_ROOT_PATH in your environment.")
+    endif(EXISTS "/opt/local/avr")
+endif(DEFINED ENV{AVR_FIND_ROOT_PATH})
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+# not added automatically, since CMAKE_SYSTEM_NAME is "generic"
+set(CMAKE_SYSTEM_INCLUDE_PATH "${CMAKE_FIND_ROOT_PATH}/include")
+set(CMAKE_SYSTEM_LIBRARY_PATH "${CMAKE_FIND_ROOT_PATH}/lib")
+
+##########################################################################
+# status messages for generating
+##########################################################################
+message(STATUS "Set CMAKE_FIND_ROOT_PATH to ${CMAKE_FIND_ROOT_PATH}")
+message(STATUS "Set CMAKE_SYSTEM_INCLUDE_PATH to ${CMAKE_SYSTEM_INCLUDE_PATH}")
+message(STATUS "Set CMAKE_SYSTEM_LIBRARY_PATH to ${CMAKE_SYSTEM_LIBRARY_PATH}")
+
+##########################################################################
+# set compiler options for build types
+##########################################################################
+if(CMAKE_BUILD_TYPE MATCHES Release)
+   set(CMAKE_C_FLAGS_RELEASE "-Os")
+   set(CMAKE_CXX_FLAGS_RELEASE "-Os")
+endif(CMAKE_BUILD_TYPE MATCHES Release)
+
+if(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
+   set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Os -save-temps -g -gdwarf-3 -gstrict-dwarf")
+   set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Os -save-temps -g -gdwarf-3 -gstrict-dwarf")
+endif(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
+
+if(CMAKE_BUILD_TYPE MATCHES Debug)
+   set(CMAKE_C_FLAGS_DEBUG "-O0 -save-temps -g -gdwarf-3 -gstrict-dwarf")
+   set(CMAKE_CXX_FLAGS_DEBUG "-O0 -save-temps -g -gdwarf-3 -gstrict-dwarf")
+endif(CMAKE_BUILD_TYPE MATCHES Debug)
+
+##########################################################################
+# compiler options for all build types
+##########################################################################
+add_definitions("-DF_CPU=${MCU_SPEED}")
+add_definitions("-fpack-struct")
+add_definitions("-fshort-enums")
+add_definitions("-Wall")
+add_definitions("-Werror")
+add_definitions("-pedantic")
+add_definitions("-pedantic-errors")
+add_definitions("-funsigned-char")
+add_definitions("-funsigned-bitfields")
+add_definitions("-ffunction-sections")
+add_definitions("-c")
+
diff --git a/rules/gcc-avr-generic.cmake b/rules/gcc-avr-generic.cmake
new file mode 100644 (file)
index 0000000..e59850a
--- /dev/null
@@ -0,0 +1,404 @@
+##########################################################################
+# "THE ANY BEVERAGE-WARE LICENSE" (Revision 42 - based on beer-ware
+# license):
+# <dev@layer128.net> wrote this file. As long as you retain this notice
+# you can do whatever you want with this stuff. If we meet some day, and
+# you think this stuff is worth it, you can buy me a be(ve)er(age) in
+# return. (I don't like beer much.)
+#
+# Matthias Kleemann
+##########################################################################
+
+##########################################################################
+# The toolchain requires some variables set.
+#
+# AVR_MCU (default: atmega8)
+#     the type of AVR the application is built for
+# AVR_L_FUSE (NO DEFAULT)
+#     the LOW fuse value for the MCU used
+# AVR_H_FUSE (NO DEFAULT)
+#     the HIGH fuse value for the MCU used
+# AVR_UPLOADTOOL (default: avrdude)
+#     the application used to upload to the MCU
+#     NOTE: The toolchain is currently quite specific about
+#           the commands used, so it needs tweaking.
+# AVR_UPLOADTOOL_PORT (default: usb)
+#     the port used for the upload tool, e.g. usb
+# AVR_PROGRAMMER (default: avrispmkII)
+#     the programmer hardware used, e.g. avrispmkII
+##########################################################################
+
+##########################################################################
+# options
+##########################################################################
+option(WITH_MCU "Add the mCU type to the target file name." ON)
+
+##########################################################################
+# executables in use
+##########################################################################
+find_program(AVR_CC avr-gcc)
+find_program(AVR_CXX avr-g++)
+find_program(AVR_OBJCOPY avr-objcopy)
+find_program(AVR_SIZE_TOOL avr-size)
+find_program(AVR_OBJDUMP avr-objdump)
+
+##########################################################################
+# toolchain starts with defining mandatory variables
+##########################################################################
+set(CMAKE_SYSTEM_NAME Generic)
+set(CMAKE_SYSTEM_PROCESSOR avr)
+set(CMAKE_C_COMPILER ${AVR_CC})
+set(CMAKE_CXX_COMPILER ${AVR_CXX})
+
+##########################################################################
+# Identification
+##########################################################################
+set(AVR 1)
+
+##########################################################################
+# some necessary tools and variables for AVR builds, which may not
+# defined yet
+# - AVR_UPLOADTOOL
+# - AVR_UPLOADTOOL_PORT
+# - AVR_PROGRAMMER
+# - AVR_MCU
+# - AVR_SIZE_ARGS
+##########################################################################
+
+# default upload tool
+if(NOT AVR_UPLOADTOOL)
+    set(
+            AVR_UPLOADTOOL avrdude
+            CACHE STRING "Set default upload tool: avrdude"
+    )
+    find_program(AVR_UPLOADTOOL avrdude)
+endif(NOT AVR_UPLOADTOOL)
+
+# default upload tool port
+if(NOT AVR_UPLOADTOOL_PORT)
+    set(
+            AVR_UPLOADTOOL_PORT usb
+            CACHE STRING "Set default upload tool port: usb"
+    )
+endif(NOT AVR_UPLOADTOOL_PORT)
+
+# default programmer (hardware)
+if(NOT AVR_PROGRAMMER)
+    set(
+            AVR_PROGRAMMER avrispmkII
+            CACHE STRING "Set default programmer hardware model: avrispmkII"
+    )
+endif(NOT AVR_PROGRAMMER)
+
+# default MCU (chip)
+if(NOT AVR_MCU)
+    set(
+            AVR_MCU atmega8
+            CACHE STRING "Set default MCU: atmega8 (see 'avr-gcc --target-help' for valid values)"
+    )
+endif(NOT AVR_MCU)
+
+#default avr-size args
+if(NOT AVR_SIZE_ARGS)
+    if(APPLE)
+        set(AVR_SIZE_ARGS -B)
+    else(APPLE)
+        set(AVR_SIZE_ARGS -C;--mcu=${AVR_MCU})
+    endif(APPLE)
+endif(NOT AVR_SIZE_ARGS)
+
+# prepare base flags for upload tool
+set(AVR_UPLOADTOOL_BASE_OPTIONS -p ${AVR_MCU} -c ${AVR_PROGRAMMER})
+
+# use AVR_UPLOADTOOL_BAUDRATE as baudrate for upload tool (if defined)
+if(AVR_UPLOADTOOL_BAUDRATE)
+    set(AVR_UPLOADTOOL_BASE_OPTIONS ${AVR_UPLOADTOOL_BASE_OPTIONS} -b ${AVR_UPLOADTOOL_BAUDRATE})
+endif()
+
+##########################################################################
+# check build types:
+# - Debug
+# - Release
+# - RelWithDebInfo
+#
+# Release is chosen, because of some optimized functions in the
+# AVR toolchain, e.g. _delay_ms().
+##########################################################################
+if(NOT ((CMAKE_BUILD_TYPE MATCHES Release) OR
+(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) OR
+(CMAKE_BUILD_TYPE MATCHES Debug) OR
+(CMAKE_BUILD_TYPE MATCHES MinSizeRel)))
+    set(
+            CMAKE_BUILD_TYPE Release
+            CACHE STRING "Choose cmake build type: Debug Release RelWithDebInfo MinSizeRel"
+            FORCE
+    )
+endif(NOT ((CMAKE_BUILD_TYPE MATCHES Release) OR
+(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) OR
+(CMAKE_BUILD_TYPE MATCHES Debug) OR
+(CMAKE_BUILD_TYPE MATCHES MinSizeRel)))
+
+
+
+##########################################################################
+
+##########################################################################
+# target file name add-on
+##########################################################################
+if(WITH_MCU)
+    set(MCU_TYPE_FOR_FILENAME "-${AVR_MCU}")
+else(WITH_MCU)
+    set(MCU_TYPE_FOR_FILENAME "")
+endif(WITH_MCU)
+
+##########################################################################
+# add_avr_executable
+# - IN_VAR: EXECUTABLE_NAME
+#
+# Creates targets and dependencies for AVR toolchain, building an
+# executable. Calls add_executable with ELF file as target name, so
+# any link dependencies need to be using that target, e.g. for
+# target_link_libraries(<EXECUTABLE_NAME>-${AVR_MCU}.elf ...).
+##########################################################################
+function(add_avr_executable EXECUTABLE_NAME)
+
+   if(NOT ARGN)
+      message(FATAL_ERROR "No source files given for ${EXECUTABLE_NAME}.")
+   endif(NOT ARGN)
+
+   # set file names
+   set(elf_file ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}.elf)
+   set(hex_file ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}.hex)
+   set(lst_file ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}.lst)
+   set(map_file ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}.map)
+   set(eeprom_image ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}-eeprom.hex)
+
+   # elf file
+   add_executable(${elf_file} EXCLUDE_FROM_ALL ${ARGN})
+
+   set_target_properties(
+      ${elf_file}
+      PROPERTIES
+         COMPILE_FLAGS "-mmcu=${AVR_MCU}"
+         LINK_FLAGS "-mmcu=${AVR_MCU} -Wl,--gc-sections -mrelax -Wl,-Map,${map_file}"
+   )
+
+   add_custom_command(
+      OUTPUT ${hex_file}
+      COMMAND
+         ${AVR_OBJCOPY} -j .text -j .data -O ihex ${elf_file} ${hex_file}
+      COMMAND
+         ${AVR_SIZE_TOOL} ${AVR_SIZE_ARGS} ${elf_file}
+      DEPENDS ${elf_file}
+   )
+
+   add_custom_command(
+      OUTPUT ${lst_file}
+      COMMAND
+         ${AVR_OBJDUMP} -d ${elf_file} > ${lst_file}
+      DEPENDS ${elf_file}
+   )
+
+   # eeprom
+   add_custom_command(
+      OUTPUT ${eeprom_image}
+      COMMAND
+         ${AVR_OBJCOPY} -j .eeprom --set-section-flags=.eeprom=alloc,load
+            --change-section-lma .eeprom=0 --no-change-warnings
+            -O ihex ${elf_file} ${eeprom_image}
+      DEPENDS ${elf_file}
+   )
+
+   add_custom_target(
+      ${EXECUTABLE_NAME}
+      ALL
+      DEPENDS ${hex_file} ${lst_file} ${eeprom_image}
+   )
+
+   set_target_properties(
+      ${EXECUTABLE_NAME}
+      PROPERTIES
+         OUTPUT_NAME "${elf_file}"
+   )
+
+   # clean
+   get_directory_property(clean_files ADDITIONAL_MAKE_CLEAN_FILES)
+   set_directory_properties(
+      PROPERTIES
+         ADDITIONAL_MAKE_CLEAN_FILES "${map_file}"
+   )
+
+   # upload - with avrdude
+   add_custom_target(
+      upload_${EXECUTABLE_NAME}
+      ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} ${AVR_UPLOADTOOL_OPTIONS}
+         -U flash:w:${hex_file}
+         -P ${AVR_UPLOADTOOL_PORT}
+      DEPENDS ${hex_file}
+      COMMENT "Uploading ${hex_file} to ${AVR_MCU} using ${AVR_PROGRAMMER}"
+   )
+
+   # upload eeprom only - with avrdude
+   # see also bug http://savannah.nongnu.org/bugs/?40142
+   add_custom_target(
+      upload_${EXECUTABLE_NAME}_eeprom
+      ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} ${AVR_UPLOADTOOL_OPTIONS}
+         -U eeprom:w:${eeprom_image}
+         -P ${AVR_UPLOADTOOL_PORT}
+      DEPENDS ${eeprom_image}
+      COMMENT "Uploading ${eeprom_image} to ${AVR_MCU} using ${AVR_PROGRAMMER}"
+   )
+
+   # disassemble
+   add_custom_target(
+      disassemble_${EXECUTABLE_NAME}
+      ${AVR_OBJDUMP} -h -S ${elf_file} > ${EXECUTABLE_NAME}.lst
+      DEPENDS ${elf_file}
+   )
+endfunction(add_avr_executable)
+
+
+##########################################################################
+# add_avr_library
+# - IN_VAR: LIBRARY_NAME
+#
+# Calls add_library with an optionally concatenated name
+# <LIBRARY_NAME>${MCU_TYPE_FOR_FILENAME}.
+# This needs to be used for linking against the library, e.g. calling
+# target_link_libraries(...).
+##########################################################################
+function(add_avr_library LIBRARY_NAME)
+    if(NOT ARGN)
+        message(FATAL_ERROR "No source files given for ${LIBRARY_NAME}.")
+    endif(NOT ARGN)
+
+    set(lib_file ${LIBRARY_NAME}${MCU_TYPE_FOR_FILENAME})
+
+    add_library(${lib_file} STATIC ${ARGN})
+
+    set_target_properties(
+            ${lib_file}
+            PROPERTIES
+            COMPILE_FLAGS "-mmcu=${AVR_MCU}"
+            OUTPUT_NAME "${lib_file}"
+    )
+
+    if(NOT TARGET ${LIBRARY_NAME})
+        add_custom_target(
+                ${LIBRARY_NAME}
+                ALL
+                DEPENDS ${lib_file}
+        )
+
+        set_target_properties(
+                ${LIBRARY_NAME}
+                PROPERTIES
+                OUTPUT_NAME "${lib_file}"
+        )
+    endif(NOT TARGET ${LIBRARY_NAME})
+
+endfunction(add_avr_library)
+
+##########################################################################
+# avr_target_link_libraries
+# - IN_VAR: EXECUTABLE_TARGET
+# - ARGN  : targets and files to link to
+#
+# Calls target_link_libraries with AVR target names (concatenation,
+# extensions and so on.
+##########################################################################
+function(avr_target_link_libraries EXECUTABLE_TARGET)
+   if(NOT ARGN)
+      message(FATAL_ERROR "Nothing to link to ${EXECUTABLE_TARGET}.")
+   endif(NOT ARGN)
+
+   get_target_property(TARGET_LIST ${EXECUTABLE_TARGET} OUTPUT_NAME)
+
+   foreach(TGT ${ARGN})
+      if(TARGET ${TGT})
+         get_target_property(ARG_NAME ${TGT} OUTPUT_NAME)
+         list(APPEND NON_TARGET_LIST ${ARG_NAME})
+      else(TARGET ${TGT})
+         list(APPEND NON_TARGET_LIST ${TGT})
+      endif(TARGET ${TGT})
+   endforeach(TGT ${ARGN})
+
+   target_link_libraries(${TARGET_LIST} ${NON_TARGET_LIST})
+endfunction(avr_target_link_libraries EXECUTABLE_TARGET)
+
+##########################################################################
+# avr_target_include_directories
+#
+# Calls target_include_directories with AVR target names
+##########################################################################
+
+function(avr_target_include_directories EXECUTABLE_TARGET)
+    if(NOT ARGN)
+        message(FATAL_ERROR "No include directories to add to ${EXECUTABLE_TARGET}.")
+    endif()
+
+    get_target_property(TARGET_LIST ${EXECUTABLE_TARGET} OUTPUT_NAME)
+    set(extra_args ${ARGN})
+
+    target_include_directories(${TARGET_LIST} ${extra_args})
+endfunction()
+
+##########################################################################
+# avr_target_compile_definitions
+#
+# Calls target_compile_definitions with AVR target names
+##########################################################################
+
+function(avr_target_compile_definitions EXECUTABLE_TARGET)
+    if(NOT ARGN)
+        message(FATAL_ERROR "No compile definitions to add to ${EXECUTABLE_TARGET}.")
+    endif()
+
+    get_target_property(TARGET_LIST ${EXECUTABLE_TARGET} OUTPUT_NAME)
+    set(extra_args ${ARGN})
+
+   target_compile_definitions(${TARGET_LIST} ${extra_args})
+endfunction()
+
+function(avr_generate_fixed_targets)
+   # get status
+   add_custom_target(
+      get_status
+      ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT} -n -v
+      COMMENT "Get status from ${AVR_MCU}"
+   )
+   
+   # get fuses
+   add_custom_target(
+      get_fuses
+      ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT} -n
+         -U lfuse:r:-:b
+         -U hfuse:r:-:b
+      COMMENT "Get fuses from ${AVR_MCU}"
+   )
+   
+   # set fuses
+   add_custom_target(
+      set_fuses
+      ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT}
+         -U lfuse:w:${AVR_L_FUSE}:m
+         -U hfuse:w:${AVR_H_FUSE}:m
+         COMMENT "Setup: High Fuse: ${AVR_H_FUSE} Low Fuse: ${AVR_L_FUSE}"
+   )
+   
+   # get oscillator calibration
+   add_custom_target(
+      get_calibration
+         ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT}
+         -U calibration:r:${AVR_MCU}_calib.tmp:r
+         COMMENT "Write calibration status of internal oscillator to ${AVR_MCU}_calib.tmp."
+   )
+   
+   # set oscillator calibration
+   add_custom_target(
+      set_calibration
+      ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT}
+         -U calibration:w:${AVR_MCU}_calib.hex
+         COMMENT "Program calibration status of internal oscillator from ${AVR_MCU}_calib.hex."
+   )
+endfunction()
\ No newline at end of file