addTone(duration, 659255, buffer);
}
static void prepareBlink(PinNumber pin, int count, int high, int low, DynBuffer& buffer){
- printf("pin: %d count: %d high: %d low: %d\n", pin, count, high, low);
+ printf("blink: pin: %d count: %d high: %d low: %d\n", pin, count, high, low);
buffer.clear().append("BLNK");
buffer.appendAsLE((int) pin, 1);
buffer.appendAsLE(count, 4);
buffer.appendAsLE(high * 1000, 4);
buffer.appendAsLE(low * 1000, 4);
}
+static void prepareTrace(PinNumber pin, int count, int delay){
+ printf("trace: pin: %d count: %d delay: %d\n", pin, count, delay);
+ buffer.clear().append("TRAC");
+ buffer.appendAsLE((int) pin, 1);
+ buffer.appendAsLE(count, 4);
+ buffer.appendAsLE(delay, 4);
+}
+static void prepareGetBuffer(const char* bufferName){
+ printf("getbuffer: %s\n", buffername);
+ buffer.clear().append("GETB");
+ buffer.append(bufferName);
+}
void usage(const char* msg, const char* argument){
printf("Usage: client <opts> <command> [<args>]\n"
"<opts>\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"
+ " trace <pin> <count> <delay>\n"
+ " inspects in a fix time raster the input state of a pin <count> times.\n"
+ " the pause between two checks is <delay> microseconds\n"
+ " returns the name of a buffer which can be requested by 'getbuffer'\n"
+ " getbuffer <buffer> <wait>\n"
+ " returns the content of the buffer filled by 'trace'\n"
+ " if <wait> is 't': the server waits for a full buffer\n"
+ " otherwise the current content of the buffer is returned\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"
+ "client trace rpi2_21 100 1000\n"
+ "client getbuffer #A t\n"
"+++ %s%s%s\n",
msg, argument == NULL ? "" : " ", argument == NULL ? "" : argument);
exit(1);
Logger logger;
DynBuffer buffer;
PinNumber pin;
- if (strcmp(argv[1], "blink") == 0){
+ int count;
+ int length = 0;
+ const char* command = argv[1];
+ if (strcmp(command, "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;
+ count = 100;
if (argc > 2 && (count = toNumber(argv[2], length)) == 0)
usage("invalid count", argv[2]);
int high = 1000;
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){
+ } else if (strcmp(command, "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 if (strcmp(command, "trace") == 0){
+ if (argc < 3)
+ usage("missing pin", NULL);
+ else if ( (pin = pinNameToNumber(argv[2])) == pinUndef)
+ usage("unknown pin:", argv[2]);
+ count = 100;
+ if (argc > 2 && (count = toNumber(argv[2], length)) == 0)
+ usage("invalid count", argv[2]);
+ int delay = 1000;
+ if (argc > 3 && (count = toNumber(argv[3], length)) == 0)
+ usage("invalid delay", argv[3]);
+ prepareTrace(pin, count, delay);
+ } else if (strcmp(command, "getbuffer") == 0){
+ if (argc < 3)
+ usage("missing buffername", NULL);
+ prepareGetBuffer(argv[2]);
} else {
- usage("unknown command:", argv[1]);
+ usage("unknown command:", command);
}
TcpClient client(&logger);
printf("connection to %s:%d\n", host, port);
}
}
+/**
+ * Gets a buffer with data assembled from 'trace'.
+ *
+ * Syntax: GETB <name><b>
+ * <name>: '#' 'A'..'Z'
+ *
+ * @param buffer IN: contains the command describing a melody to play<br>
+ * OUT: answer for the client
+ */
+void GPIOProcessor::getBuffer(DynBuffer& buffer){
+ char name;
+ if (buffer.length() != 4 + 2 || buffer[4] != '#' || buffer[5] < 'A' || (name = buffer[5]) > 'Z'){
+ DynBuffer name(buffer.str() + 4);
+ buffer.set("ERROR wrong buffername: ").append(name);
+ } else if(m_buffers[name] == NULL) {
+ buffer.set("ERROR unknown buffername: #").append(name);
+ } else {
+ buffer.set("OK ").append(*m_buffers[name]);
+ }
+}
/**
* "Writes" a melody to a GPIO pin.
*
}
return rc;
}
+
+/**
+ * Inspects the input state of a GPIO pin in a timer loop.
+ *
+ * Syntax: TRAC[pin][count][delay]<br>
+ * [pin]: 1 byte. Numbering like <i>PinNumber</i><br>
+ * [count]: 2 byte<br>
+ * [duration]: 4 byte little endian, number of microseconds<br>
+ *
+ * @param buffer IN: contains the command describing a melody to play<br>
+ * OUT: answer for the client
+ */
+void TcpProcessor::trace(DynBuffer& buffer){
+
+}
* @param state <i>psLow</i> or <i>psHigh</i>
*/
void GPIOTimer::switchState(PinState state){
- m_logger->sayf(LOG_DEBUG, "pin %d: %c", m_pin, psHigh ? 'H' : 'L');
+ m_logger->sayf(LOG_DEBUG, "pin %d: %c", m_pin, state ? 'H' : 'L');
m_processor->writeToGPIO(m_pin, state);
}
/**
switchState(m_nextHigh ? psHigh : psLow);
m_delay = m_nextHigh ? m_high : m_low;
}
+
+/**
+ * Constructor.
+ *
+ * @param pin the target pin
+ * @param pause the pause (in microseconds) to wait between two reads
+ * @param count the number of reads
+ * @param buffer OUT: for each read the state is stored in this buffer
+ * @param gpioProcessor access to the SoC
+ * @param logger the logger
+ * @param pool the pool managing the timer threads
+ */
+TraceInputTimer::TraceInputTimer(PinNumber pin, uint64_t pause, int count, DynBuffer* buffer,
+ GPIOProcessor* gpioProcessor, Announcer* logger, ThreadPool* pool) :
+ GPIOTimer(pin, pause, gpioProcessor, logger, pool),
+ m_buffer(buffer),
+ m_lastState(psLow){
+ m_taskCount = count;
+ m_processor->setMode(pin, mInput);
+}
+
+/**
+ * The action done from the timer.
+ */
+void TraceInputTimer::timerTask(){
+ PinState current = m_processor->readFromGPIO(m_pin);
+ if (current != m_lastState){
+ printf("pin: %d changed to %c\n", m_pin, current == psHigh ? 'H' : 'L');
+ m_lastState = current;
+ }
+ if (m_buffer != NULL)
+ m_buffer->append((char) current);
+}
+