Browse Source

Emission module

Cyrille 10 years ago
parent
commit
45545b4783
7 changed files with 408 additions and 0 deletions
  1. 10 0
      emit/Makefile
  2. BIN
      emit/emit
  3. 142 0
      emit/emit.c
  4. BIN
      emit/emit.o
  5. 157 0
      emit/emitlib.c
  6. 99 0
      emit/emitlib.h
  7. BIN
      emit/emitlib.o

+ 10 - 0
emit/Makefile

@@ -0,0 +1,10 @@
+all : emit
+
+emit : emit.o emitlib.o
+	gcc -o emit emit.o emitlib.o -lwiringPi
+
+emit.o : emit.c
+	gcc -c emit.c
+
+emitlib.o : emitlib.c emitlib.h
+	gcc -c emitlib.c

BIN
emit/emit


+ 142 - 0
emit/emit.c

@@ -0,0 +1,142 @@
+#include <stdio.h>
+#include <wiringPiSPI.h>
+#include "emitlib.h"
+#include <malloc.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define DEFAULT_FREQ 20000
+
+
+
+/**
+ * Usage of this program
+ */
+void usage(char** argv)
+{
+    fprintf(stderr, "Chacon command V1.0\nC. Meichel\n2013, October\n");
+    fprintf(stderr, "Syntaxe : %s [options]\n", argv[0]);
+    fprintf(stderr, "\t-b button\n\t\tbutton (A-D1-4|G). For instance A1, G, D3\n");
+    fprintf(stderr, "\t-x:\n\t\tOff (default On)\n");
+    fprintf(stderr, "\t-r number:\n\t\tnumber of repeatitions\n");
+    fprintf(stderr, "\t-d id:\n\t\thexadecimal id from your command (13 letters <=> 52 bits)\n");
+    fprintf(stderr, "\t-f frequency: configuration frequency for the SPI (default %dHz)\n", DEFAULT_FREQ);
+    fprintf(stderr, "\t-v: verbose bits\n");
+}
+
+
+
+/**
+ * Main program
+ *
+ * @param argc number of arguments passed to the program
+ * @param argv array of arguments passed to the program
+ *
+ * @return status
+ */
+int main(int argc, char** argv)
+{
+    BUFFER buffer;
+    int i;
+    char optstring[] = "xvb:d:f:r:";
+    int option;
+    unsigned char global=NO_GLOBAL;
+    unsigned char number = NUMBER1;
+    unsigned char section = SECTION_A;
+    char *idString=0;
+    unsigned long int frequency = DEFAULT_FREQ;
+    unsigned char onOff = ON;
+    unsigned int verbose = 0;
+    unsigned repeat = 1;
+
+
+    /* reading options */
+    //opterr=0; /* Pas de message d'erreur automatique */
+    while ((option = getopt(argc, argv, optstring)) != -1) {
+        switch (option) {
+            case 'b':
+                // Decode the button ie : A3
+                section = optarg[0] - (optarg[0]<'Z' ? 'A' : 'a');
+                if (strlen(optarg)>1) {
+                    number =  optarg[1] - '0';
+                }
+                if (section== 6) {
+                    // G was requested
+                    global = GLOBAL;
+                }
+                break;
+            case 'r':
+                // repeatition code
+                sscanf(optarg, "%d", &repeat);
+                break;
+            case 'd':
+                // command id
+                idString = (char*)malloc(1+strlen(optarg)/2);
+                for(i=0; i<strlen(optarg)/2 + strlen(optarg) % 2; i++) {
+                    idString[i] = (optarg[i*2] - (optarg[i*2]<='9' ? '0' : (optarg[i*2]<='Z' ? 'A' : 'a')-10)) << 4;
+                    if (optarg[1+i*2]) {
+                        idString[i] += optarg[1+i*2] - (optarg[1+i*2]<='9' ? '0' : (optarg[1+i*2]<='Z' ? 'A' : 'a')-10);
+                    }
+                }
+                break;
+            case 'f':
+                // SPI frequency
+                sscanf(optarg, "%lu", &frequency);
+                break;
+            case 'x':
+                // OFF ?
+                onOff = OFF;
+                break;
+            case 'v':
+                // Show the bits to send ?
+                verbose = 1;
+                break;
+            default:
+                usage(argv);
+                return 0;
+                break;
+        }
+    }
+
+    // No ID specified, it will be "00 00 00 00 00 00 0"
+    if (!idString) {
+        idString = (char*)malloc(7);
+        memset(idString, 0, 7);
+    }
+
+    // Show informations
+    printf("Frequency config on SPI: %dHz\n", frequency);
+
+    if (global) {
+        printf("Sending command G: %s\n", (onOff == OFF) ? "OFF" : "ON");
+    } else {
+        printf("Sending command %c%d: %s\n", section+'A', number, (onOff == OFF) ? "OFF" : "ON");
+    }
+
+    // Preparing the buffer
+    buffer = createBuffer();
+
+    // Building the data
+    for (i=0; i<repeat; i++) {
+        pushCode(&buffer, idString, section, number, onOff, global, frequency);
+    }
+    printf("\n");
+
+    // Want to see the bits ?
+    if (verbose) {
+        printfBinaryBuffer(buffer);
+    }
+
+    // preparing the output
+    if (wiringPiSPISetup(0, frequency) < 0) {
+        printf("SPI Setup Failed: %s\n", strerror(errno));
+        return -1;
+    }
+    // Send data
+    wiringPiSPIDataRW(0, (unsigned char*)buffer.data, buffer.byteSize);
+
+    // release memory
+    destroyBuffer(buffer);
+    return 0;
+}

BIN
emit/emit.o


+ 157 - 0
emit/emitlib.c

@@ -0,0 +1,157 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <malloc.h>
+#include "emitlib.h"
+
+
+unsigned int timings[4][2] = {
+    {250, 250},  //  bit 0
+    {250, 1200}, //  bit 1
+    {250, 2600}, //  start of frame
+    {250, 9900}  //  end of data
+};
+
+unsigned char numbering[4] = {0x05, 0x06, 0x09, 0x0A};
+
+/**
+ * Create a new buffer
+ *
+ * @return the created buffer
+ */
+BUFFER createBuffer()
+{
+    BUFFER buffer;
+    buffer.byteSize = 1;
+    buffer.bitSize = 0;
+    buffer.data = (char*) malloc(1);
+    buffer.data[0] = 0;
+    return buffer;
+}
+
+/**
+ * Release the memory
+ *
+ * @param buffer the buffer to destroy
+ */
+void destroyBuffer(BUFFER buffer)
+{
+    free(buffer.data);
+}
+
+/**
+ * Print all the bits from a buffer
+ *
+ * @param buffer the buffer holding the data
+ */
+void printfBinaryBuffer(BUFFER buffer)
+{
+    printf("bytes: %d\nbits: %d\n", buffer.byteSize, buffer.bitSize);
+    unsigned char byte;
+    unsigned char bit;
+    unsigned int x;
+    int i;
+    for(x=0; x<buffer.byteSize; x++) {
+        byte = buffer.data[x];
+        for(i=0x80; i>0; i>>=1) {
+            if ((bit==0) && (byte & i)) {
+                fprintf(stdout, "\n");
+            }
+            bit = ((byte & i) == i);
+            fprintf(stdout, "%d", bit);
+        }
+    }
+}
+
+/**
+ * Push a bit in a buffer
+ *
+ * @param buffer the buffer holding the data
+ * @param bit the bit to push
+ */
+void pushBit(BUFFER* buffer, unsigned char bit)
+{
+    buffer->data[buffer->byteSize-1] |= bit << (7-buffer->bitSize);
+    buffer->bitSize++;
+    if (buffer->bitSize == 8) {
+        buffer->bitSize = 0;
+        buffer->byteSize++;
+        buffer->data = (char*)realloc(buffer->data, buffer->byteSize);
+        buffer->data[buffer->byteSize-1] = 0;
+    }
+}
+
+/**
+ * Append a bit that will be emitted for a specific time
+ *
+ * @param buffer the buffer holding the data
+ * @param bit the bit to push
+ * @param usec time in µs
+ * @param clock frequency
+ */
+void appendBit(BUFFER* buffer, unsigned char bit, unsigned int usec, unsigned int freq)
+{
+    unsigned int i;
+    for(i=0; i<(usec * freq) / 1e6; i++) {
+        pushBit(buffer, bit);
+    }
+}
+
+/**
+ * Append data according to Chacon protocole
+ *
+ * @param buffer the buffer holding the data
+ * @param type data type (BIT0 | BIT1 | START_OF_FRAME | END_OF_DATA)
+ * @param clock frequency
+ */
+void appendData(BUFFER* buffer, unsigned int type, unsigned int freq)
+{
+    appendBit(buffer, 1, timings[type][0], freq);
+    appendBit(buffer, 0, timings[type][1], freq);
+}
+
+/**
+ * Append a byte according to Chacon protocole
+ *
+ * @param buffer the buffer holding the data
+ * @param byte the byte to append
+ * @param clock frequency
+ */
+void appendByte(BUFFER* buffer, unsigned char byte, unsigned int freq)
+{
+    int i;
+    for(i=0x80; i>0; i>>=1) {
+        appendData(buffer, ((byte & i) == i), freq);
+    }
+    printf("%02X ", byte);
+}
+
+
+/**
+ * Append a complete command according to Chacon protocole
+ *
+ * @param buffer the buffer holding the data
+ * @param id command id (refer to your remote)
+ * @param section button section (0:A, 1:B, 2:C, 3:D)
+ * @param nb button number(1, 2, 3, 4)
+ * @param on boolean for on/off
+ * @param global if true G button is selected (nb will be ignore)
+ * @param clock frequency
+ */
+void pushCode(BUFFER* buffer, unsigned char* id, unsigned char section, unsigned char nb, unsigned char on, unsigned char global, unsigned int freq)
+{
+    unsigned char byte6 = (id[6] & 0xf0) + numbering[on + (global ? 2 : 0)];
+    unsigned char byte7 = (numbering[section] << 4) + numbering[nb];
+    unsigned int i;
+    if (global) {
+        byte7 = 0x55;
+    }
+    appendData(buffer, START_OF_FRAME, freq);
+    printf("SOF ");
+    for(i=0; i<6; i++) {
+            appendByte(buffer, id[i], freq);
+    }
+    appendByte(buffer, byte6, freq);
+    appendByte(buffer, byte7, freq);
+    appendData(buffer, END_OF_DATA, freq);
+    printf("EOD ");
+}

+ 99 - 0
emit/emitlib.h

@@ -0,0 +1,99 @@
+#include <stdio.h>
+
+
+typedef struct {
+    unsigned long int byteSize;
+    unsigned int bitSize;
+    char* data;
+} BUFFER;
+
+#define BIT0 0
+#define BIT1 1
+#define START_OF_FRAME  2
+#define END_OF_DATA 3
+
+#define ON 1
+#define OFF 0
+
+#define NUMBER1 0
+#define NUMBER2 1
+#define NUMBER3 2
+#define NUMBER4 3
+
+#define SECTION_A 0
+#define SECTION_B 1
+#define SECTION_C 2
+#define SECTION_D 3
+
+#define GLOBAL 1
+#define NO_GLOBAL 0
+
+/**
+ * Create a new buffer
+ *
+ * @return the created buffer
+ */
+BUFFER createBuffer();
+
+/**
+ * Release the memory
+ *
+ * @param buffer the buffer to destroy
+ */
+void destroyBuffer(BUFFER buffer);
+
+/**
+ * Print all the bits from a buffer
+ *
+ * @param buffer the buffer holding the data
+ */
+void printfBinaryBuffer(BUFFER buffer);
+
+/**
+ * Push a bit in a buffer
+ *
+ * @param buffer the buffer holding the data
+ * @param bit the bit to push
+ */
+void pushBit(BUFFER* buffer, unsigned char bit);
+
+/**
+ * Append a bit that will be emitted for a specific time
+ *
+ * @param buffer the buffer holding the data
+ * @param bit the bit to push
+ * @param usec time in µs
+ * @param clock frequency
+ */
+void appendBit(BUFFER* buffer, unsigned char bit, unsigned int usec, unsigned int freq);
+
+/**
+ * Append data according to Chacon protocole
+ *
+ * @param buffer the buffer holding the data
+ * @param type data type (BIT0 | BIT1 | START_OF_FRAME | END_OF_DATA)
+ * @param clock frequency
+ */
+void appendData(BUFFER* buffer, unsigned int type, unsigned int freq);
+
+/**
+ * Append a byte according to Chacon protocole
+ *
+ * @param buffer the buffer holding the data
+ * @param byte the byte to append
+ * @param clock frequency
+ */
+void appendByte(BUFFER* buffer, unsigned char byte, unsigned int freq);
+
+/**
+ * Append a complete command according to Chacon protocole
+ *
+ * @param buffer the buffer holding the data
+ * @param id command id (refer to your remote)
+ * @param section button section (0:A, 1:B, 2:C, 3:D)
+ * @param nb button number(1, 2, 3, 4)
+ * @param on boolean for on/off
+ * @param global if true G button is selected (nb will be ignore)
+ * @param clock frequency
+ */
+void pushCode(BUFFER* buffer, unsigned char* id, unsigned char section, unsigned char nb, unsigned char on, unsigned char global, unsigned int freq);

BIN
emit/emitlib.o