]> gitweb.hamatoma.de Git - cpidjinn/commitdiff
new: class Bcm2835
authorhama <hama@siduction.net>
Sun, 12 Jun 2016 09:10:43 +0000 (11:10 +0200)
committerhama <hama@siduction.net>
Sun, 12 Jun 2016 09:10:43 +0000 (11:10 +0200)
12 files changed:
Server/Makefile
Server/bcm2835.cpp [new file with mode: 0644]
Server/bcm2835.hpp [new file with mode: 0644]
Server/client.cpp
Server/cpidjinn.cpp
Server/cpidjinn.hpp
Server/gpioprocessor.cpp
Server/gpioprocessor.hpp
Server/gpiotimer.cpp
Server/gpiotimer.hpp
Server/tcpserver.hpp
util/util.hpp

index 7593f790fd65000836f31e8d76b71114e4b67789..35a8186a2b3c79135e8a91bc8407934c27ae9692 100644 (file)
@@ -4,7 +4,7 @@ CFLAGS = -Wall
 LDFLAGS = -lbcm2835 -lpthread
 
 OBJ_UTIL = timer.o thread.o dynbuffer.o logger.o
-OBJ = gpiotimer.o cpidjinn.o $(OBJ_UTIL) tcpserver.o gpioprocessor.o
+OBJ = systemonachip.o gpiotimer.o cpidjinn.o $(OBJ_UTIL) tcpserver.o gpioprocessor.o
 PROG = cpidjinn
 
 OBJ_CLIENT = $(OBJ_UTIL) tcpclient.o client.o
diff --git a/Server/bcm2835.cpp b/Server/bcm2835.cpp
new file mode 100644 (file)
index 0000000..d328c55
--- /dev/null
@@ -0,0 +1,321 @@
+#include "cpidjinn.hpp"
+#include <fcntl.h>
+#include <sys/mman.h>
+
+Bcm2835* Bcm2835::m_instance = NULL;
+
+/**
+ * Constructor.
+ *
+ * @param logger               the logger
+ * @param simulation   <i>true</i>: the SoC will be simulated.
+ */
+Bcm2835::Bcm2835(Announcer* logger, bool simulation) :
+       m_valid(false),
+       m_simulation(simulation),
+       m_bcmBase(NULL),
+       m_sizeBcmBase(0),
+       m_systemTimerBase(NULL),
+       m_gpioPadsBase(NULL),
+       m_clockBase(NULL),
+       m_gpioBase(NULL),
+       m_spioBase(NULL),
+       m_bscoBase(NULL),
+       m_pwmBase(NULL),
+       m_bsc1Base(NULL),
+       m_simulatorMemory(NULL),
+       m_logger(logger)
+{
+       for (int ix = 0; ix < pinCount; ix++)
+               m_pins[ix].m_pin = (PinNumber) ix;
+
+    /* Figure out the base and size of the peripheral address block
+    // using the device-tree. Required for RPi2, optional for RPi 1
+    */
+       if (m_simulation){
+               int blocksize = 256;
+               m_sizeBcmBase = 8 * blocksize;
+               m_simulatorMemory = new uint32_t[m_sizeBcmBase];
+               m_bcmBase = m_simulatorMemory;
+
+               m_systemTimerBase = m_bcmBase + 0 * blocksize;
+               m_gpioPadsBase = m_systemTimerBase + blocksize;
+               m_clockBase = m_gpioPadsBase + blocksize;
+               m_gpioBase = m_clockBase + blocksize;
+               m_spioBase = m_gpioBase + blocksize;
+               m_bscoBase = m_spioBase + blocksize;
+               m_pwmBase = m_bscoBase + blocksize;
+               m_bsc1Base = m_pwmBase + blocksize;
+               m_valid = true;
+       // for RasPI2 we find the data in the device tree:
+       } else {
+               FILE* fp;
+               const char* fn = "/proc/device-tree/soc/ranges";
+               uint32_t base = 0;
+               if ((fp = fopen(fn, "rb")) == NULL){
+                       m_logger->sayf(LOG_ERROR, "not found (%d): %fn", errno, fn);
+                       // assuming RasPi1:
+                       base = 0x20000000;
+                       m_sizeBcmBase = 0x01000000;
+               } else {
+                       const int baseOffset = 4;
+                       const int sizeOffset = 8;
+
+                       ubyte_t buffer[sizeOffset + sizeof (uint32_t)];
+                       int readBytes;
+                       if ( (readBytes = fread(buffer, 1, sizeof buffer, fp)) != sizeof buffer){
+                               m_logger->sayf(LOG_INFO, "cannot read %s (%d): %d instead of %d",
+                                       errno, fn, readBytes, sizeof buffer);
+                       } else {
+                               ubyte_t* ptr = buffer + baseOffset;
+                               base = ((ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3]);
+                               ptr = buffer + sizeOffset;
+                               m_sizeBcmBase = (uint32_t) ((ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3]);
+                               fclose(fp);
+                               m_valid = true;
+                       }
+               }
+               if (m_valid){
+                       fn = "/dev/mem";
+                       int handle = open(fn, O_RDWR | O_SYNC);
+                       if (handle < 0){
+                               m_logger->sayf(LOG_ERROR, "cannot open %s (%d): %d", fn, errno, handle);
+                       } else {
+                               m_bcmBase = (uint32_t*) mmap(NULL, m_sizeBcmBase, (PROT_READ | PROT_WRITE), MAP_SHARED, handle, base);
+                               if (m_bcmBase == MAP_FAILED){
+                                       m_logger->say(LOG_ERROR, "cannot map GPIO region:");
+                               } else {
+                                       m_systemTimerBase = m_bcmBase + 0x3000 / sizeof (uint32_t);
+                                       m_gpioPadsBase = m_bcmBase + 0x100000 / sizeof (uint32_t);
+                                       m_clockBase = m_bcmBase + 0x101000 / sizeof (uint32_t);
+                                       m_gpioBase = m_bcmBase + 0x200000 / sizeof (uint32_t);
+                                       m_spioBase = m_bcmBase + 0x204000 / sizeof (uint32_t);
+                                       m_bscoBase = m_bcmBase + 0x205000 / sizeof (uint32_t);
+                                       m_pwmBase = m_bcmBase + 0x20C000 / sizeof (uint32_t);
+                                       m_bsc1Base = m_bcmBase + 0x804000 / sizeof (uint32_t);
+                                       m_valid = true;
+                               }
+                       }
+               }
+       }
+}
+
+/**
+ * Destructor.
+ */
+Bcm2835::~Bcm2835() {
+}
+
+Bcm2835* Bcm2835::instance(Announcer* logger){
+       if (m_instance == NULL)
+               m_instance = new Bcm2835(logger);
+       return m_instance;
+}
+
+/**
+ * Converts a name of a pin into its number.
+ *
+ * @param name the name of the pin
+ * @return             <i>pinUndef</i>: not a name<br>
+ *                             otherwise: the pin number
+ */
+PinNumber nameToNumber(const char* name){
+       PinNumber rc = pinUndef;
+       if (strnicmp(name, "rpi2_")){
+               int no = atol(name, 5);
+               switch(no){
+               case 3:
+                       rc = pinRPi2_03;
+                       break;
+               case 5:
+                       rc = pinRPi2_05;
+                       break;
+               case 7:
+                       rc = pinRPi2_07;
+                       break;
+               case 8:
+                       rc = pinRPi2_08;
+                       break;
+               case 10:
+                       rc = pinRPi2_10;
+                       break;
+               case 11:
+                       rc = pinRPi2_11;
+                       break;
+               case 12:
+                       rc = pinRPi2_12;
+                       break;
+               case 13:
+                       rc = pinRPi2_13;
+                       break;
+               case 15:
+                       rc = pinRPi2_15;
+                       break;
+               case 16:
+                       rc = pinRPi2_16;
+                       break;
+               case 18:
+                       rc = pinRPi2_18;
+                       break;
+               case 19:
+                       rc = pinRPi2_19;
+                       break;
+               case 21:
+                       rc = pinRPi2_21;
+                       break;
+               case 22:
+                       rc = pinRPi2_22;
+                       break;
+               case 23:
+                       rc = pinRPi2_23;
+                       break;
+               case 24:
+                       rc = pinRPi2_24;
+                       break;
+               case 26:
+                       rc = pinRPi2_26;
+                       break;
+               case 29:
+                       rc = pinRPi2_29;
+                       break;
+               case 31:
+                       rc = pinRPi2_31;
+                       break;
+               case 32:
+                       rc = pinRPi2_32;
+                       break;
+               case 33:
+                       rc = pinRPi2_33;
+                       break;
+               case 35:
+                       rc = pinRPi2_35;
+                       break;
+               case 36:
+                       rc = pinRPi2_36;
+                       break;
+               case 37:
+                       rc = pinRPi2_37;
+                       break;
+               case 38:
+                       rc = pinRPi2_38;
+                       break;
+               case 40:
+                       rc = pinRPi2_40;
+                       break;
+               default:
+                       break;
+               }
+       }
+       return rc;
+}
+/**
+ * Reads a word from a memory mapped register.
+ *
+ * @param address      the address for reading
+ */
+uint32_t Bcm2835::readWord(volatile uint32_t* address){
+       // atomic access:
+       __sync_synchronize();
+       uint32_t rc = *address;
+       __sync_synchronize();
+       return rc;
+}
+
+/**
+ * Sets some bits of a memory mapped register.
+ *
+ * @param address      the address of the register
+ * @param value                the bits to setBits
+ * @param mask         only those bits will be changed which are set in this mask
+ */
+void Bcm2835::setBits(volatile uint32_t* address, uint32_t value, uint32_t mask){
+    uint32_t old = readWord(address);
+    value = (value & mask) | (old & ~mask);
+    writeWord(address, value);
+}
+
+/**
+ * Sets the input/output mode of a pin.
+ *
+ * @param pin  the pin which mode has to be changed
+ * @param mode the mode to set
+ */
+void Bcm2835::setMode(PinNumber pin, PinMode mode)
+{
+       ubyte_t mode2 = 255;
+       switch (mode){
+               case mInput:
+                       mode2 = 0;
+                       break;
+               case mOutput:
+                       mode2 = 1;
+                       break;
+               default:
+                       break;
+       }
+       // mode2 has only 3 bits:
+       if (mode2 >= (1<<3)){
+               m_logger->sayf(LOG_ERROR, "invalid mode: %d", mode);
+       } else {
+               /* Function selects are 10 pins per 32 bit word, 3 bits per pin */
+               const int FUNCTION_SELECT_0 = 0;
+               const int FUNCTION_SELECT_MASK = 0x7;
+               volatile uint32_t* address = m_gpioBase + FUNCTION_SELECT_0/4 + (pin/10);
+               uint8_t   shift = (pin % 10) * 3;
+
+               uint32_t  mask = FUNCTION_SELECT_MASK << shift;
+               uint32_t  bits = mode2 << shift;
+               setBits(address, bits, mask);
+       }
+}
+
+/**
+ * Sets the state of an output pin.
+ *
+ * @param pin  the pin number
+ * @param state        <i>psHigh</i> or <i>psLow</i>
+ */
+void Bcm2835::setState(PinNumber pin, PinState state){
+       if (pin < 0 || pin >= pinCount){
+               m_logger->sayf(LOG_ERROR, "unknown pin: %d", pin);
+       } else {
+               switch (m_pins[pin].m_mode){
+               case mOutput:
+                       break;
+               case mUndef:
+               case mInput:
+               default:
+                       setMode(pin, mOutput);
+                       break;
+               }
+               writeToGPIO(pin, state);
+       }
+}
+
+/**
+ * Sets the state of a pin in output mode.
+ *
+ * @param pin  output pin
+ * @param state        the new state
+ */
+void Bcm2835::writeToGPIO(PinNumber pin, PinState state){
+       const int GPinSet0 = 0x001c  / sizeof(uint32_t);
+       const int GPinClear0 = 0x0028  / sizeof(uint32_t);
+    volatile uint32_t* addr = m_gpioBase + (state == psHigh ? GPinSet0 : GPinClear0) + pin / 32;
+    uint32_t value = (1 << (pin % 32));
+    writeWord(addr, value);
+
+}
+/**
+ * Writes a 4 byte word to a given address (memory mapped register).
+ *
+ * @param address      the target address
+ * @param value                value to write
+ */
+void Bcm2835::writeWord(volatile uint32_t* address, uint32_t value){
+       // atomic access:
+       __sync_synchronize();
+       *address = value;
+       __sync_synchronize();
+}
+
diff --git a/Server/bcm2835.hpp b/Server/bcm2835.hpp
new file mode 100644 (file)
index 0000000..33e51a4
--- /dev/null
@@ -0,0 +1,167 @@
+#ifndef SYSTEMONACHIP_H
+#define SYSTEMONACHIP_H
+enum PinNumber {
+       pinUndef = -1,
+       // numbering like BCM22835:
+       pinGPIO_00 = 0,
+       pinGPIO_01,
+       pinGPIO_02,
+       pinGPIO_03,
+       pinGPIO_04,
+       pinGPIO_05,
+       pinGPIO_06,
+       pinGPIO_07,
+       pinGPIO_08,
+       pinGPIO_09,
+       pinGPIO_10,
+       pinGPIO_11,
+       pinGPIO_12,
+       pinGPIO_13,
+       pinGPIO_14,
+       pinGPIO_15,
+       pinGPIO_16,
+       pinGPIO_17,
+       pinGPIO_18,
+       pinGPIO_19,
+       pinGPIO_20,
+       pinGPIO_21,
+       pinGPIO_22,
+       pinGPIO_23,
+       pinGPIO_24,
+       pinGPIO_25,
+       pinGPIO_26,
+       pinGPIO_27,
+       pinGPIO_28,
+       pinGPIO_29,
+       pinGPIO_30,
+       pinGPIO_31,
+       pinCount,
+       // RaspberryPi B, B+:
+       pinRPi2_03 = 2,
+       pinRPi2_05 = 3,
+       pinRPi2_07 = 4,
+       pinRPi2_08 = 14,
+       pinRPi2_10 = 15,
+       pinRPi2_11 = 17,
+       pinRPi2_12 = 18,
+       pinRPi2_13 = 27,
+       pinRPi2_15 = 22,
+       pinRPi2_16 = 23,
+       pinRPi2_18 = 24,
+       pinRPi2_19 = 10,
+       pinRPi2_21 = 9,
+       pinRPi2_22 = 25,
+       pinRPi2_23 = 11,
+       pinRPi2_24 = 8,
+       pinRPi2_26 = 7,
+       pinRPi2_29 = 5,
+       pinRPi2_31 = 6,
+       pinRPi2_32 = 12,
+       pinRPi2_33 = 13,
+       pinRPi2_35 = 19,
+       pinRPi2_36 = 16,
+       pinRPi2_37 = 26,
+       pinRPi2_38 = 20,
+       pinRPi2_40 = 21,
+
+       pinWiring_00 = 17,
+       pinWiring_01 = 18,
+       pinWiring_02 = 27,
+       pinWiring_03 = 15,
+       pinWiring_04 = 23,
+       pinWiring_05 = 24,
+       pinWiring_06 = 25,
+       pinWiring_07 = 4,
+       pinWiring_08 = 2,
+       pinWiring_09 = 3,
+       pinWiring_10 = 8,
+       pinWiring_11 = 7,
+       pinWiring_12 = 10,
+       pinWiring_13 = 9,
+       pinWiring_14 = 11,
+       pinWiring_15 = 14,
+       pinWiring_16 = 15,
+};
+enum PinState {
+       psLow,
+       psHigh
+};
+enum PinMode {
+       mUndef,
+       mInput,
+       mOutput
+};
+
+/**
+ * Stores the state and features of a pin.
+ */
+class PinInfo {
+public:
+       /**
+        * Constructor.
+        */
+       PinInfo() :
+               m_pin(pinUndef),
+               m_mode(mUndef),
+               m_timerId(0),
+               m_lastOutputState(psLow)
+       {}
+public:
+       PinNumber m_pin;
+       PinMode m_mode;
+       int m_timerId;
+       PinState m_lastOutputState;
+};
+
+/**
+ * Controlls the access to the periphery of the system on the chip BCM2835.
+ * This is the heart of the raspberry pi.
+ */
+class Bcm2835 {
+protected:
+    Bcm2835(Announcer* logger, bool simulation = false);
+public:
+    ~Bcm2835();
+private:
+       // not implemented. private to avoid usage:
+    Bcm2835 ( const SystemOnAChip& other );
+    SystemOnAChip& operator= ( const SystemOnAChip& other );
+public:
+       SystemOnAChip* instance(Announcer* logger);
+public:
+       uint32_t readWord(volatile uint32_t* addr);
+       void setMode(PinNumber pin, PinMode mode);
+       void setState(PinNumber pin, PinState state);
+       /**
+        * Returns whether the instance is valid.
+        * @return <i>true</code>: the instance is valid (can work)
+        */
+       bool valid() const{
+               return m_valid;
+       }
+       void writeToGPIO(PinNumber pin, PinState state);
+protected:
+       void setBits(volatile uint32_t* addr, uint32_t value, uint32_t mask);
+    void writeWord(volatile uint32_t* addr, uint32_t value);
+private:
+       static PinNumber nameToNumber(const char* name);
+       static SystemOnAChip* m_instance;
+private:
+       bool m_valid;
+       bool m_simulation;
+       uint32_t* m_bcmBase;
+       uint32_t m_sizeBcmBase;
+       volatile uint32_t* m_systemTimerBase;
+       volatile uint32_t* m_gpioPadsBase;
+       volatile uint32_t* m_clockBase;
+       volatile uint32_t* m_gpioBase;
+       volatile uint32_t* m_spioBase;
+       volatile uint32_t* m_bscoBase;
+       volatile uint32_t* m_pwmBase;
+       volatile uint32_t* m_bsc1Base;
+       uint32_t* m_simulatorMemory;
+       Announcer* m_logger;
+       PinInfo m_pins[pinCount];
+};
+
+#endif // SYSTEMONACHIP_H
index f914f5009b1a6a5ba2e4f9d4506d3bcd5a7cd28b..83a7441b5858afba1791dcc3efc97e1efc8b6cf8 100644 (file)
@@ -1,4 +1,4 @@
-#include "util.hpp"
+#include "cpidjinn.hpp"
 #include "tcpclient.hpp"
 
 #if 0
@@ -15,9 +15,13 @@ static void addTone(int duration, int millihz, DynBuffer& buffer){
        buffer.appendAsLE(low, 3);
 }
 
-static void prepareMelody(DynBuffer& buffer){
+static void prepareMelody(const char* name, DynBuffer& buffer){
        int duration = 2000;
-       int pin = 0;
+       PinNumber pin = Bcm2835::nameToNumber(name);
+       if (pin == pinUndef){
+               printf("unknown pin: %s! Assuming RPi2_11\n", name);
+               ping = pinRPi2_11;
+       }
        int countTones = 3;
        buffer.clear().append("MELO");
        buffer.appendAsLE(pin, 1);
@@ -29,8 +33,49 @@ static void prepareMelody(DynBuffer& buffer){
        // tone e: 659,255 Hz
        addTone(duration, 659255, buffer);
 }
+static void prepareblink(const char* name, int count, int high, int low, DynBuffer& buffer){
+       buffer.clear().append("MELO");
+       buffer.appendAsLE(pin, 1);
+}
+void usage(const char* msg, const char* argument){
+       print("Usage: client <opts> <command> [<args>]\n",
+               "<opts>\n"
+               "  -p<port> or --port=<port>:\n"
+               "    server port. Default: 15000\n"
+               "  -h<host> or --host=<host>\n"
+               "    server ip. Default: 127.0.0.1\n"
+               "<command>:\n"
+               "  blink <count> <pin> <high_millisec> [<low_millisec>]\n"
+               "    change <count> times the state of the output pin <pin>
+               "  <pin>: rpi2_<number>\n"
+               "  <number>: 5 7..8 10..16 18..19 21.. 24 26 29 31..33 35..38 40\n"
+               "  melody\n"
+               "Examples:\n"
+               "client -p21222 -h192.168.178.3 blink rpi2_11 99 500\n"
+               "client --port=21222 --host=192.168.178.3 blink rpi2_11 99 500 250\n"
+               "client melody rpi2_12\n"
+               "+++ %s%s%s\n",
+          msg, argument == NULL ? "" : " ", argument == NULL ? "" : argument);
+       exit(1);
+}
 int main (int argc, char **argv) {
        const char* host = "127.0.0.1";
+       const char* pin = "RPi2_11";
+       while(argc > 1 && argv[1][0] == '-'){
+               const char* arg = argv[1];
+               if (strncmp(arg, "-p", 2) == 0 || strncmp(arg, "--port=", 7)){
+                       port = atol(arg + (arg[1] == '-' ? 2 : 7);
+                       if (port <= 0 || port >= 0xffff){
+                               usage("illegal port:", arg);
+                       }
+               } else if (strncmp(arg, "-h", 2) == 0 || strncmp(arg, "--host=", 7)){
+                       host = arg + (arg[1] == '-' ? 2 : 7;
+                       if (! isdigit(host[0])){
+                               usage("not a numeric ip:", arg);
+                       }
+               argc--;
+               argv++;
+       }
        int port = 15000;
        Logger logger;
        DynBuffer buffer;
index 4ab53d5b7ef3af1e243f0918282c5c5c3cf0d0e9..cfa5c8f481967130b8c23344252e7c55dfc25141 100644 (file)
@@ -9,9 +9,23 @@
  */
 int main(int argc, char** argv){
        Logger logger;
-       int port = argc < 2 ? 15000 : atol(argv[1]);
+       bool simulation = false;
        logger.say(LOG_INFO, "start");
-       GPIOProcessor processor;
+
+       while(argc > 1 && argv[1][0] == '-'){
+               char* arg = argv[1];
+               if (strcmp(arg, "-s") == 0 || strcmp(arg, "--simulation")){
+                       simulation = true;
+               } else {
+                       logger.sayf(LOG_ERROR, "unknown option: %s", arg);
+               }
+               argc--;
+               argv++;
+       }
+       if (simulation)
+               logger.say(LOG_INFO, "GPIO will be simulated");
+       int port = argc < 2 ? 15000 : atol(argv[1]);
+       GPIOProcessor processor(&logger, simulation);
        TcpServer server(port, &logger);
        server.addProcessor(processor);
        // interpreter for the standard commands:
index c4cd173aa3e39634c3b38c6ff6831f64185292b8..14490b58a09a3ed25ba05f2718200ad5dac7e19a 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef CPIDJINN_HPP
 #include "util.hpp"
 #include "tcpserver.hpp"
+#include "systemonachip.hpp"
 #include "gpioprocessor.hpp"
 #include "gpiotimer.hpp"
 #endif
index d2ca966ac23b5441e84c23c884ce339506fbdab3..bf69c878b4fc4141cfeaa9f93be42428a4b51c4f 100644 (file)
@@ -1,10 +1,14 @@
 #include "cpidjinn.hpp"
-#include "bcm2835.h"
 
 /**
  * Constructor.
  */
-GPIOProcessor::GPIOProcessor()
+GPIOProcessor::GPIOProcessor(Announcer* logger, bool simulation) :
+       SystemOnAChip(logger, simulation),
+       TcpProcessor(),
+       m_pins(),
+       m_logger(logger),
+       m_pool(128, logger)
 {
 }
 /**
@@ -12,7 +16,6 @@ GPIOProcessor::GPIOProcessor()
  */
 GPIOProcessor::~GPIOProcessor()
 {
-
 }
 /**
  * Lets a GPIO pin blink.
index d8b855b0c9112a33036b7a24f58ab20440e7447f..e0b7a9cfbb88343b91e04e0d38b5cb027ac48ef2 100644 (file)
@@ -1,21 +1,28 @@
 #ifndef GPIOPROCESSOR_H
 #define GPIOPROCESSOR_H
 
-class GPIOProcessor : public TcpProcessor
+#define MAX_PINS 64
+class GPIOProcessor : public SystemOnAChip, public TcpProcessor
 {
 public:
-       GPIOProcessor();
+       GPIOProcessor(Announcer* logger, bool simulation = false);
        ~GPIOProcessor();
+public:
+       void setState(int pin, bool high);
 private:
        // not implemented, private use only
        GPIOProcessor(const GPIOProcessor& other);
        GPIOProcessor& operator=(const GPIOProcessor& other);
+private:
        void blink(DynBuffer& buffer);
        void melody(DynBuffer& buffer);
        void pulseWidthModulation(DynBuffer& buffer);
 public:
        virtual State process(DynBuffer& buffer);
-
+private:
+       PinInfo m_pins[MAX_PINS];
+       Announcer* m_logger;
+       ThreadPool m_pool;
 };
 
 #endif // GPIOPROCESSOR_H
index 50c984739b7e7e7f48d50fbf30a1dab13ff31b33..9d168535945d60d48b7c11d1c35066d42d2b2c31 100644 (file)
@@ -6,9 +6,10 @@
  * @param pin          the pin where the data will be transferred
  * @param pause                pause in microseconds befor starting the first hight state
  * @param logger       the logger
+ * @param pool         the pool managing the timer threads
  */
-GPIOTimer::GPIOTimer(int pin, uint64_t pause, Announcer* logger) :
-       Timer(1, 0, pause, uMicroSeconds, true, logger),
+GPIOTimer::GPIOTimer(PinNumber pin, uint64_t pause, Announcer* logger, ThreadPool* pool) :
+       Timer(1, 0, pause, uMicroSeconds, true, logger, pool),
        m_pin(pin)
 {
 }
@@ -23,10 +24,11 @@ GPIOTimer::~GPIOTimer() {
 /**
  * Switches the state of a pin.
  *
- * @param high         <i>true</i>: the state will be set to high
+ * @param state                <i>psLow</i> or <i>psHigh</i>
  */
-void GPIOTimer::switchState(bool high){
-       m_logger->sayf(LOG_DEBUG, "%d: %c", m_pin, high ? 'H' : 'L');
+void GPIOTimer::switchState(PinState state){
+       m_logger->sayf(LOG_DEBUG, "%d: %c", m_pin, psHigh ? 'H' : 'L');
+       m_processor->writeToGPIO(m_pin, state);
 }
 /**
  * Constructor.
@@ -36,10 +38,12 @@ void GPIOTimer::switchState(bool high){
  * @param count                the number of high states to create
  * @param high         the duration of the high state in microseconds
  * @param low          the duration of the low state in microseconds
+ * @param logger       the logger
+ * @param pool         the pool managing the timer threads
  */
-SquareWaveTimer::SquareWaveTimer(int pin, uint64_t pause, int count,
-                                                                uint64_t high, uint64_t low, Announcer* logger) :
-       GPIOTimer(pin, pause, logger),
+SquareWaveTimer::SquareWaveTimer(PinNumber pin, uint64_t pause, int count,
+                                                                uint64_t high, uint64_t low, Announcer* logger, ThreadPool* pool) :
+       GPIOTimer(pin, pause, logger, pool),
        m_pause(pause),
        m_high(high),
        m_low(low),
@@ -53,6 +57,6 @@ SquareWaveTimer::SquareWaveTimer(int pin, uint64_t pause, int count,
  */
 void SquareWaveTimer::timerTask(){
        m_nextHigh = ! m_nextHigh;
-       switchState(m_nextHigh);
+       switchState(m_nextHigh ? psHigh : psLow);
        m_delay = m_nextHigh ? m_high : m_low;
 }
index 42054195246b7d6cac77d2f0545fc787e304a418..9834b75cf396a67a4a912968389cae3011b0ff70 100644 (file)
@@ -6,16 +6,17 @@
  */
 class GPIOTimer : public Timer {
 public:
-    GPIOTimer(int pin, uint64_t pause, Announcer* logger);
+    GPIOTimer(PinNumber pin, uint64_t pause, Announcer* logger, ThreadPool* pool);
     virtual ~GPIOTimer();
 private:
        // not implemented, private to avoid usage
     GPIOTimer ( const GPIOTimer& other );
     GPIOTimer& operator= ( const GPIOTimer& other );
 protected:
-       void switchState(bool high);
+       void switchState(PinState state);
 protected:
-       int m_pin;
+       PinNumber m_pin;
+       GPIOProcessor* m_processor;
 };
 
 /**
@@ -23,8 +24,8 @@ protected:
  */
 class SquareWaveTimer : public GPIOTimer{
 public:
-       SquareWaveTimer(int pin, uint64_t pause, int count,
-                                                                uint64_t high, uint64_t low, Announcer* logger);
+       SquareWaveTimer(PinNumber pin, uint64_t pause, int count,
+                                                                uint64_t high, uint64_t low, Announcer* logger, ThreadPool* pool);
 public:
        virtual void timerTask();
 private:
@@ -42,7 +43,7 @@ private:
  */
 class MelodyTimer : public GPIOTimer{
 public:
-       MelodyTimer(int pin, DynBuffer& melody);
+       MelodyTimer(int pin, DynBuffer& melody, ThreadPool* pool);
 public:
        virtual void timerTask();
 };
index d64516c4b50dd74c1cea2a0c7db93e9b7f2a8df4..1ee3df62aecde56dca4855cdff75e0ee0909c967 100644 (file)
@@ -1,6 +1,5 @@
 #ifndef TCPSERVER_H
 #define TCPSERVER_H
-typedef unsigned char ubyte_t;
 
 class TcpProcessor {
 public:
index b3e983bda8407c9e18eeb09a9cebc5650c2410cc..3ed542d7870423c9d14ca940ee68babbcb69824f 100644 (file)
@@ -8,9 +8,9 @@
 #include <sys/time.h>
 #include <errno.h>
 #include <pthread.h>
+#include <stdint.h>
 
 typedef unsigned char ubyte_t;
-typedef long long unsigned uint64_t;
 #include "dynbuffer.hpp"
 #include "timeutils.hpp"
 #include "logger.hpp"