CFLAGS = -Wall
LDFLAGS = -lbcm2835 -lpthread
-OBJ_UTIL = timer.o thread.o dynbuffer.o logger.o
-OBJ = systemonachip.o gpiotimer.o cpidjinn.o $(OBJ_UTIL) tcpserver.o gpioprocessor.o
+OBJ_UTIL_MINIMAL = dynbuffer.o logger.o
+OBJ_UTIL = timer.o thread.o $(OBJ_UTIL_MINIMAL)
+OBJ = bcm2835def.o bcm2835.o gpiotimer.o cpidjinn.o $(OBJ_UTIL) tcpserver.o gpioprocessor.o
PROG = cpidjinn
-OBJ_CLIENT = $(OBJ_UTIL) tcpclient.o client.o
+OBJ_CLIENT = $(OBJ_UTIL_MINIMAL) tcpclient.o client.o bcm2835def.o
CLIENT = client
all: $(PROG)
.PHONY: clean
clean:
- rm -vfr *~ $(PROG) $(OBJ)
+ rm -vfr *~ $(PROG) $(OBJ) *.gch
$(PROG): $(OBJ)
$(CL) $(LDFLAGS) -o $(PROG) $(OBJ)
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.
*
-#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,
-};
+#ifndef BCM2835_HPP
+#define BCM2835_HPP
+#include "bcm2835def.hpp"
enum PinState {
psLow,
psHigh
~Bcm2835();
private:
// not implemented. private to avoid usage:
- Bcm2835 ( const SystemOnAChip& other );
- SystemOnAChip& operator= ( const SystemOnAChip& other );
+ Bcm2835 ( const Bcm2835& other );
+ Bcm2835& operator= ( const Bcm2835& other );
public:
- SystemOnAChip* instance(Announcer* logger);
+ static Bcm2835* instance(Announcer* logger);
public:
uint32_t readWord(volatile uint32_t* addr);
void setMode(PinNumber pin, PinMode mode);
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;
+ static Bcm2835* m_instance;
private:
bool m_valid;
bool m_simulation;
PinInfo m_pins[pinCount];
};
-#endif // SYSTEMONACHIP_H
+#endif // BCM2835_HPP
--- /dev/null
+#include "string.h"
+#include "stdlib.h"
+#include "bcm2835def.hpp"
+/**
+ * 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 pinNameToNumber(const char* name){
+ PinNumber rc = pinUndef;
+ if (strncasecmp(name, "rpi2_", 5) == 0){
+ 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;
+}
--- /dev/null
+#ifndef BCM2835DEF_HPP
+#define BCM2835DEF_HPP
+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,
+};
+extern PinNumber pinNameToNumber(const char* name);
+#endif // BCM2835DEF_HPP
#include "cpidjinn.hpp"
#include "tcpclient.hpp"
+#include "ctype.h"
-#if 0
-static void prepareBlink(DynBuffer& buffer){
-
+int toNumber(const char* value, int &length){
+ int number = 0;
+ length = 0;
+ while(isdigit(value[0])){
+ length++;
+ number = number * 10 + value[0] - '0';
+ value++;
+ }
+ return number;
}
-#endif
-
static void addTone(int duration, int millihz, DynBuffer& buffer){
int high, low;
high = low = 1000*1000*1000 / millihz / 2 + 1;
buffer.appendAsLE(low, 3);
}
-static void prepareMelody(const char* name, DynBuffer& buffer){
+static void prepareMelody(PinNumber pin, DynBuffer& buffer){
int duration = 2000;
- 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);
// tone e: 659,255 Hz
addTone(duration, 659255, buffer);
}
-static void prepareblink(const char* name, int count, int high, int low, DynBuffer& buffer){
+static void prepareBlink(PinNumber pin, int count, int high, int low, DynBuffer& buffer){
buffer.clear().append("MELO");
- buffer.appendAsLE(pin, 1);
+ buffer.appendAsLE((int) pin, 1);
+ buffer.appendAsLE(count, 4);
+ buffer.appendAsLE(high * 1000, 4);
+ buffer.appendAsLE(low * 1000, 4);
+
}
void usage(const char* msg, const char* argument){
- print("Usage: client <opts> <command> [<args>]\n",
+ printf("Usage: client <opts> <command> [<args>]\n"
"<opts>\n"
" -p<port> or --port=<port>:\n"
" server port. Default: 15000\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>
+ " change <count> times the state of the output pin <pin>\n"
" <pin>: rpi2_<number>\n"
" <number>: 5 7..8 10..16 18..19 21.. 24 26 29 31..33 35..38 40\n"
" melody\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";
+ int port = 15000;
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);
+ 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])){
+ host = arg + (arg[1] == '-' ? 2 : 7);
+ int length;
+ int node = toNumber(host, length);
+ if (length == 0 || host[length] != '.' || node >= 255){
usage("not a numeric ip:", arg);
}
+ } else {
+ usage("unknown option:", argv[1]);
+ }
argc--;
argv++;
}
- int port = 15000;
+ if (argc < 2)
+ usage("missing command", NULL);
Logger logger;
DynBuffer buffer;
+ PinNumber pin;
+ if (strcmp(argv[1], "blink") == 0){
+ argv++;
+ argc--;
+ int length = 0;
+ if (argc < 2)
+ usage("missing pin", NULL);
+ else if ( (pin = pinNameToNumber(argv[1])) == pinUndef)
+ usage("unknown pin:", argv[1]);
+ int count = 100;
+ if (argc > 2 && (count = toNumber(argv[2], length)) == 0)
+ usage("invalid count", argv[2]);
+ int high = 1000;
+ if (argc > 3 && (high = toNumber(argv[3], length)) == 0)
+ usage("invalid high_msec", argv[3]);
+ int low = high;
+ if (argc > 4 && (low = toNumber(argv[4], length)) == 0)
+ usage("invalid high_msec", argv[4]);
+ prepareBlink(pin, count, high, low, buffer);
+ } else if (strcmp(argv[1], "melody") == 0){
+ if (argc < 3)
+ usage("missing pin", NULL);
+ else if ( (pin = pinNameToNumber(argv[2])) == pinUndef)
+ usage("unknown pin:", argv[2]);
+ prepareMelody(pin, buffer);
+ } else {
+ usage("unknown command:", argv[1]);
+ }
TcpClient client(&logger);
if (client.connect(host, port)){
- prepareMelody(buffer);
client.sendAndReceive(buffer);
}
client.disconnect();
return 0;
}
+
#ifndef CPIDJINN_HPP
#include "util.hpp"
#include "tcpserver.hpp"
-#include "systemonachip.hpp"
+#include "bcm2835.hpp"
#include "gpioprocessor.hpp"
#include "gpiotimer.hpp"
#endif
* Constructor.
*/
GPIOProcessor::GPIOProcessor(Announcer* logger, bool simulation) :
- SystemOnAChip(logger, simulation),
+ Bcm2835(logger, simulation),
TcpProcessor(),
m_pins(),
m_logger(logger),
/**
* Lets a GPIO pin blink.
*
- * Syntax: BLNK[pin][period_high][period_low]<br>
- * [pin]: 1 byte. Numbering like WiringPi: 0 is GPIO17...<br>
+ * Syntax: BLNK[pin][count][period_high][period_low]<br>
+ * [pin]: 1 byte. Numbering like <i>PinNumber</i>.<br>
+ * [count]: 4 byte little endian. Number of high states.<br>
* [period_x]: 4 byte little endian, in microseconds (< 35 minutes)
*
* @param buffer IN: contains the blink command<br>
buffer.clear().appendFormatted("ERR wrong packet length %d instead of %d",
buffer.length(), 4 + 1 + 2*4);
} else {
- int pin = buffer.str()[4];
- int periodHigh = buffer.valueOfLE(4, 5);
- int periodLow = buffer.valueOfLE(4, 5 + 4);
- printf("Pin: %d high: %d low: %d\n", pin, periodHigh, periodLow);
+ PinNumber pin = (PinNumber) buffer.str()[4];
+ int count = buffer.valueOfLE(4, 5);
+ int periodHigh = buffer.valueOfLE(4, 5 + 4);
+ int periodLow = buffer.valueOfLE(4, 5 + 2*4);
+ new SquareWaveTimer(pin, 0, count, periodHigh, periodLow, m_logger, &m_pool);
+ printf("Pin: %d count: %d high: %d low: %d\n", (int) pin, count, periodHigh, periodLow);
buffer.set("OK ");
}
}
* "Writes" a melody to a GPIO pin.
*
* Syntax: MELO[pin][count_tones][duration_1][period_high_1][period_high_1]...<br>
- * [pin]: 1 byte. Numbering like WiringPi: 0 is GPIO17...<br>
+ * [pin]: 1 byte. Numbering lNumbering like <i>PinNumber</i><br>
* [count_tones]: 1 byte<br>
* [duration_y]: 2 byte little endian, number of millisec (1 msec - 65 sec)<br>
* [period_x_y]: 3 byte little endian, unit: microsec (1 usec - 16.8 sec)
#define GPIOPROCESSOR_H
#define MAX_PINS 64
-class GPIOProcessor : public SystemOnAChip, public TcpProcessor
+class GPIOProcessor : public Bcm2835, public TcpProcessor
{
public:
GPIOProcessor(Announcer* logger, bool simulation = false);