Browse Source

Merge branch 'master' of https://github.com/landru29/chacon-rpi

Cyrille 10 years ago
parent
commit
7b425f3237
13 changed files with 1220 additions and 61 deletions
  1. 2 1
      .gitignore
  2. 5 5
      emit/Makefile
  3. 125 0
      emit/buffer.c
  4. 83 0
      emit/buffer.h
  5. 30 17
      emit/emit.c
  6. 234 16
      emit/emitlib.c
  7. 124 22
      emit/emitlib.h
  8. 274 0
      emit/home_easy.c
  9. 143 0
      emit/home_easy.h
  10. 13 0
      emit/test/Makefile
  11. 141 0
      emit/test/test.c
  12. 28 0
      emit/utils.c
  13. 18 0
      emit/utils.h

+ 2 - 1
.gitignore

@@ -1,5 +1,6 @@
-listen/*.o
+**.o
 listen/listen
 listen/*.txt
 emit/*.o
 emit/emit
+emit/test/test

+ 5 - 5
emit/Makefile

@@ -1,13 +1,13 @@
 all : emit
 
-emit : emit.o emitlib.o
-	gcc -o emit emit.o emitlib.o -lwiringPi
+emit : emit.o buffer.o home_easy.o utils.o
+	gcc -o $@ $^ -lwiringPi
 
 emit.o : emit.c
-	gcc -c emit.c
+	gcc -c $< -o $@
 
-emitlib.o : emitlib.c emitlib.h
-	gcc -c emitlib.c
+%.o : %.c %.h
+	gcc -c $< -o $@
 
 clean:
 	rm -f emit *.o

+ 125 - 0
emit/buffer.c

@@ -0,0 +1,125 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <string.h>
+#include "buffer.h"
+
+/**
+ * Create a new byte buffer
+ *
+ * @return the created buffer
+ */
+BYTE_BUFFER createByteBuffer()
+{
+    BYTE_BUFFER buffer;
+    buffer.size = 0;
+    buffer.data = (char*) malloc(1);
+    return buffer;
+}
+
+/**
+ * Release the memory
+ *
+ * @param buffer the buffer to destroy
+ */
+void destroyByteBuffer(BYTE_BUFFER buffer)
+{
+    free(buffer.data);
+}
+
+/**
+ * Print all the bits from a buffer
+ *
+ * @param buffer the buffer holding the data
+ */
+void printfBitBuffer(BYTE_BUFFER buffer)
+{
+    printf("bytes: %lu\nbits: %lu\n", buffer.size, buffer.size*8);
+    unsigned int x;
+    for(x=0; x<buffer.size ; x++) {
+        printfBit(buffer.data[x]);
+        printf("\n");
+    }
+}
+
+/**
+ * Print a byte in binary
+ * 
+ * @param byte the byte to print
+ */
+void printfBit(unsigned char byte)
+{
+    int i;
+    for(i=0x80; i>0; i>>=1) {
+        fprintf(stdout, "%d", ((byte & i) == i));
+    }
+}
+
+
+/**
+ * Print all the bytes from a buffer
+ *
+ * @param buffer the buffer holding the data
+ */
+void printfByteBuffer(BYTE_BUFFER buffer)
+{
+    unsigned int i;
+    for(i=0; i<buffer.size; i++) {
+        fprintf(stdout, "%02X ", (unsigned char)buffer.data[i]);
+    }
+    fprintf(stdout, "\n");
+}
+
+/**
+ * Push a byte in a buffer
+ *
+ * @param buffer the buffer holding the data
+ * @param byte the byte to push
+ */
+void pushByte(BYTE_BUFFER* buffer, unsigned char byte)
+{
+    buffer->size++;
+    buffer->data = (char*)realloc(buffer->data, buffer->size);
+    buffer->data[buffer->size-1] = byte;
+}
+
+/**
+ * Push a word in a buffer
+ *
+ * @param buffer the buffer holding the data
+ * @param word the word to push
+ */
+void pushWord(BYTE_BUFFER* buffer, unsigned short int word)
+{
+    unsigned char* data = (unsigned char*)&word;
+    pushByte(buffer, data[1]);
+    pushByte(buffer, data[0]);
+}
+/**
+ * Push some bytes in a buffer
+ *
+ * @param buffer the buffer holding the data
+ * @param bytes the bytes to push
+ * @param len the number of bytes to push
+ */
+void pushBytes(BYTE_BUFFER* buffer, unsigned char *byte, unsigned int len)
+{
+    buffer->data = (char*)realloc(buffer->data, buffer->size+len);
+    memcpy(&buffer->data[buffer->size], byte, len);
+    buffer->size += len;
+}
+
+/**
+ * Gives the bit at a specific position
+ * 
+ * @param buffer the buffer to evaluate
+ * @param n the bit position
+ * 
+ * @return the bit value
+ */
+unsigned int bitAt(BYTE_BUFFER buffer, unsigned long int n)
+{
+    unsigned char byte = buffer.data[n / 8];
+    return (byte & (0x80 >> (n % 8)) != 0);
+}
+

+ 83 - 0
emit/buffer.h

@@ -0,0 +1,83 @@
+#ifndef __BUFFER_H__
+#define __BUFFER_H__
+
+
+typedef struct {
+    char* data;
+    unsigned long int size;
+} BYTE_BUFFER;
+
+
+/**
+ * Create a new byte buffer
+ *
+ * @return the created buffer
+ */
+BYTE_BUFFER createByteBuffer();
+
+/**
+ * Release the memory
+ *
+ * @param buffer the buffer to destroy
+ */
+void destroyByteBuffer(BYTE_BUFFER buffer);
+
+/**
+ * Print a byte in binary
+ * 
+ * @param byte the byte to print
+ */
+void printfBit(unsigned char byte);
+
+/**
+ * Print all the bytes from a buffer
+ *
+ * @param buffer the buffer holding the data
+ */
+void printfByteBuffer(BYTE_BUFFER buffer);
+
+/**
+ * Push a byte in a buffer
+ *
+ * @param buffer the buffer holding the data
+ * @param byt the byte to push
+ */
+void pushByte(BYTE_BUFFER* buffer, unsigned char byte);
+
+/**
+ * Push a word in a buffer
+ *
+ * @param buffer the buffer holding the data
+ * @param word the word to push
+ */
+void pushWord(BYTE_BUFFER* buffer, unsigned short int word);
+
+/**
+ * Push some bytes in a buffer
+ *
+ * @param buffer the buffer holding the data
+ * @param bytes the bytes to push
+ * @param len the number of bytes to push
+ */
+void pushBytes(BYTE_BUFFER* buffer, unsigned char *byte, unsigned int len);
+
+/**
+ * Gives the bit at a specific position
+ * 
+ * @param buffer the buffer to evaluate
+ * @param n the bit position
+ * 
+ * @return the bit value
+ */
+unsigned int bitAt(BYTE_BUFFER buffer, unsigned long int n);
+
+
+/**
+ * Print all the bits from a buffer
+ *
+ * @param buffer the buffer holding the data
+ */
+//void printfBitBuffer(BIT_BUFFER buffer);
+void printfBitBuffer(BYTE_BUFFER buffer);
+
+#endif

+ 30 - 17
emit/emit.c

@@ -1,6 +1,9 @@
 #include <stdio.h>
-#include <wiringPiSPI.h>
-#include "emitlib.h"
+#ifdef __arm__
+    #include <wiringPiSPI.h>
+#endif
+#include "home_easy.h"
+#include "buffer.h"
 #include <malloc.h>
 #include <string.h>
 #include <unistd.h>
@@ -37,13 +40,14 @@ void usage(char** argv)
  */
 int main(int argc, char** argv)
 {
-    BUFFER buffer;
+    //BIT_BUFFER buffer;
+    BYTE_BUFFER command;
+    BYTE_BUFFER encoded;
     int i;
     char optstring[] = "xvb:d:f:r:";
     int option;
-    unsigned char global=NO_GLOBAL;
-    unsigned char number = NUMBER1;
-    unsigned char section = SECTION_A;
+    unsigned char number = 1;
+    unsigned char section = 'A';
     char *idString=0;
     unsigned long int frequency = DEFAULT_FREQ;
     unsigned char onOff = ON;
@@ -57,14 +61,10 @@ int main(int argc, char** argv)
         switch (option) {
             case 'b':
                 // Decode the button ie : A3
-                section = optarg[0] - (optarg[0]<'Z' ? 'A' : 'a');
+                section = optarg[0] - (optarg[0]<'Z' ? 0 : 'a' - 'A');
                 if (strlen(optarg)>1) {
                     number =  optarg[1] - '0';
                 }
-                if (section== 6) {
-                    // G was requested
-                    global = GLOBAL;
-                }
                 break;
             case 'r':
                 // repeatition code
@@ -106,16 +106,26 @@ int main(int argc, char** argv)
     }
 
     // Show informations
-    printf("Frequency config on SPI: %dHz\n", frequency);
+    printf("Frequency config on SPI: %luHz\n", frequency);
 
-    if (global) {
+    if (section == 'G') {
         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");
+        printf("Sending command %c%d: %s\n", section, number, (onOff == OFF) ? "OFF" : "ON");
     }
+    
+    command = createHomeEasyCommand(idString, section, number, onOff);
+    printfByteBuffer(command);
+    
+    printf("Code to emit:\n");
+    encoded = homeEasyEncode(&command);
+    printfByteBuffer(encoded);
+    
+    destroyByteBuffer(command);
+    destroyByteBuffer(encoded);
 
     // Preparing the buffer
-    buffer = createBuffer();
+    /*buffer = createBitBuffer();
 
     // Building the data
     for (i=0; i<repeat; i++) {
@@ -125,9 +135,10 @@ int main(int argc, char** argv)
 
     // Want to see the bits ?
     if (verbose) {
-        printfBinaryBuffer(buffer);
+        printfBitBuffer(buffer);
     }
 
+#ifdef __arm__
     // preparing the output
     if (wiringPiSPISetup(0, frequency) < 0) {
         printf("SPI Setup Failed: %s\n", strerror(errno));
@@ -135,8 +146,10 @@ int main(int argc, char** argv)
     }
     // Send data
     wiringPiSPIDataRW(0, (unsigned char*)buffer.data, buffer.byteSize);
+#endif
 
     // release memory
-    destroyBuffer(buffer);
+    destroyBitBuffer(buffer);*/
+    
     return 0;
 }

+ 234 - 16
emit/emitlib.c

@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <malloc.h>
+#include <string.h>
 #include "emitlib.h"
 
 
@@ -26,9 +27,9 @@ unsigned char numbering[4] = {0x05, 0x06, 0x09, 0x0A};
  *
  * @return the created buffer
  */
-BUFFER createBuffer()
+BIT_BUFFER createBitBuffer()
 {
-    BUFFER buffer;
+    BIT_BUFFER buffer;
     buffer.byteSize = 1;
     buffer.bitSize = 0;
     buffer.data = (char*) malloc(1);
@@ -41,7 +42,30 @@ BUFFER createBuffer()
  *
  * @param buffer the buffer to destroy
  */
-void destroyBuffer(BUFFER buffer)
+void destroyBitBuffer(BIT_BUFFER buffer)
+{
+    free(buffer.data);
+}
+
+/**
+ * Create a new byte buffer
+ *
+ * @return the created buffer
+ */
+BYTE_BUFFER createByteBuffer()
+{
+    BYTE_BUFFER buffer;
+    buffer.size = 0;
+    buffer.data = (char*) malloc(1);
+    return buffer;
+}
+
+/**
+ * Release the memory
+ *
+ * @param buffer the buffer to destroy
+ */
+void destroyByteBuffer(BYTE_BUFFER buffer)
 {
     free(buffer.data);
 }
@@ -51,14 +75,14 @@ void destroyBuffer(BUFFER buffer)
  *
  * @param buffer the buffer holding the data
  */
-void printfBinaryBuffer(BUFFER buffer)
+/*void printfBitBuffer(BIT_BUFFER buffer)
 {
-    printf("bytes: %d\nbits: %d\n", buffer.byteSize, buffer.bitSize);
+    printf("bytes: %lu\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++) {
+    for(x=0; x<(buffer.bitSize ? buffer.byteSize : buffer.byteSize-1) ; x++) {
         byte = buffer.data[x];
         for(i=0x80; i>0; i>>=1) {
             if ((bit==0) && (byte & i)) {
@@ -68,6 +92,43 @@ void printfBinaryBuffer(BUFFER buffer)
             fprintf(stdout, "%d", bit);
         }
     }
+}*/
+void printfBitBuffer(BYTE_BUFFER buffer)
+{
+    printf("bytes: %lu\nbits: %lu\n", buffer.size, buffer.size*8);
+    unsigned int x;
+    for(x=0; x<buffer.size ; x++) {
+        printfBit(buffer.data[x]);
+        printf("\n");
+    }
+}
+
+/**
+ * Print a byte in binary
+ * 
+ * @param byte the byte to print
+ */
+void printfBit(unsigned char byte)
+{
+    int i;
+    for(i=0x80; i>0; i>>=1) {
+        fprintf(stdout, "%d", ((byte & i) == i));
+    }
+}
+
+
+/**
+ * Print all the bytes from a buffer
+ *
+ * @param buffer the buffer holding the data
+ */
+void printfByteBuffer(BYTE_BUFFER buffer)
+{
+    unsigned int i;
+    for(i=0; i<buffer.size; i++) {
+        fprintf(stdout, "%02X ", (unsigned char)buffer.data[i]);
+    }
+    fprintf(stdout, "\n");
 }
 
 /**
@@ -76,7 +137,7 @@ void printfBinaryBuffer(BUFFER buffer)
  * @param buffer the buffer holding the data
  * @param bit the bit to push
  */
-void pushBit(BUFFER* buffer, unsigned char bit)
+/*void bitPushBit(BIT_BUFFER* buffer, unsigned char bit)
 {
     buffer->data[buffer->byteSize-1] |= bit << (7-buffer->bitSize);
     buffer->bitSize++;
@@ -86,6 +147,163 @@ void pushBit(BUFFER* buffer, unsigned char bit)
         buffer->data = (char*)realloc(buffer->data, buffer->byteSize);
         buffer->data[buffer->byteSize-1] = 0;
     }
+}*/
+
+/**
+ * Push a byte in a buffer
+ *
+ * @param buffer the buffer holding the data
+ * @param byte the byte to push
+ */
+void pushByte(BYTE_BUFFER* buffer, unsigned char byte)
+{
+    buffer->size++;
+    buffer->data = (char*)realloc(buffer->data, buffer->size);
+    buffer->data[buffer->size-1] = byte;
+}
+
+/**
+ * Push a word in a buffer
+ *
+ * @param buffer the buffer holding the data
+ * @param word the word to push
+ */
+void pushWord(BYTE_BUFFER* buffer, unsigned short int word)
+{
+    unsigned char* data = (unsigned char*)&word;
+    pushByte(buffer, data[1]);
+    pushByte(buffer, data[0]);
+}
+/**
+ * Push some bytes in a buffer
+ *
+ * @param buffer the buffer holding the data
+ * @param bytes the bytes to push
+ * @param len the number of bytes to push
+ */
+void pushBytes(BYTE_BUFFER* buffer, unsigned char *byte, unsigned int len)
+{
+    buffer->data = (char*)realloc(buffer->data, buffer->size+len);
+    memcpy(&buffer->data[buffer->size], byte, len);
+    buffer->size += len;
+}
+
+/**
+ * Encode bits with HomeEasy encoding (1 => 10, 0 => 01)
+ * 
+ * @param buffer the buffuer to encode
+ * 
+ * @return new buffer
+ * */
+BYTE_BUFFER homeEasyEncode(BYTE_BUFFER *buffer)
+{
+    BYTE_BUFFER result = createByteBuffer();
+    unsigned int i;
+    for(i=0; i<buffer->size; i++) {
+        pushWord(&result, encodeByte(buffer->data[i]));
+    }
+    return result;
+}
+
+/**
+ * Decode bits with HomeEasy encoding (1 => 10, 0 => 01)
+ * 
+ * @param buffer the buffuer to decode
+ * 
+ * @return new buffer
+ * */
+BYTE_BUFFER homeEasyDecode(BYTE_BUFFER *buffer)
+{
+    BYTE_BUFFER result = createByteBuffer();
+    unsigned short int word;
+    unsigned char *byte = (unsigned char*)&word;
+    unsigned int i;
+    for(i=0; i<(buffer->size+1)/2; i++) {
+        byte[1] = buffer->data[2*i];
+        byte[0] = (2*i+1 < buffer->size ? buffer->data[2*i+1]:0);
+        pushByte(&result, decodeByte(word));
+    }
+    return result;
+}
+
+/**
+ * Decode a byte according to HomeEasy
+ * 
+ * @param byte the byte to decode
+ * 
+ * @return the decoded byte
+ */
+unsigned char decodeByte(unsigned short int word)
+{
+    unsigned char decodedChar=0;
+    int j;
+    int shift = 7;
+    for(j=0x8000;j>0; j>>=2) {
+      decodedChar |= (((word & j) == j) ? 0x01 : 0x00) << shift;
+      shift -=1;
+    }
+    return decodedChar;
+}
+
+/**
+ * Encode a byte according to HomeEasy
+ * 
+ * @param byte the byte to encode
+ * 
+ * @return the encoded byte
+ */
+unsigned short int encodeByte(unsigned char byte)
+{
+    unsigned short int encodedChar=0;
+    int j;
+    int shift = 14;
+    for(j=0x80;j>0; j>>=1) {
+      encodedChar |= (((byte & j) == j) ? 0x02 : 0x01) << shift;
+      shift -=2;
+    }
+    return encodedChar;
+}
+
+/**
+ * Gives the bit at a specific position
+ * 
+ * @param buffer the buffer to evaluate
+ * @param n the bit position
+ * 
+ * @return the bit value
+ */
+unsigned int bitAt(BYTE_BUFFER buffer, unsigned long int n)
+{
+    unsigned char byte = buffer.data[n / 8];
+    return (byte & (0x80 >> (n % 8)) != 0);
+}
+
+/**
+ * Append a complete command according to Chacon protocole
+ *
+ * @param id command id (refer to your remote)
+ * @param section button section ('A' | 'B'  | 'C'  | 'D'  | 'G')
+ * @param nb button number(1, 2, 3, 4)
+ * @param on boolean for on/off
+ */
+BYTE_BUFFER createHomeEasyCommand(unsigned char* id, char section, unsigned char nb, unsigned char on)
+{
+    unsigned char last = id[3] & 0xc0;
+    BYTE_BUFFER command;
+    char formatedSection = (section<='Z' ? section : section + 'A' - 'a');
+    // adding global
+    last |= (formatedSection == 'G' ? 0x20 : 0);
+    // adding on/off
+    last |= (on ? 0x10 : 0);
+    // adding section
+    last |= ((formatedSection == 'G' ? 0 : formatedSection - 'A') << 2) & 0x0c;
+    // adding num
+    last |= (formatedSection == 'G' ? 0 : nb-1) & 0x03;;
+    //Preparing output buffer
+    command = createByteBuffer();
+    pushBytes(&command, id, 3);
+    pushByte(&command, last);
+    return command;
 }
 
 /**
@@ -96,13 +314,13 @@ void pushBit(BUFFER* buffer, unsigned char bit)
  * @param usec time in µs
  * @param clock frequency
  */
-void appendBit(BUFFER* buffer, unsigned char bit, unsigned int usec, unsigned int freq)
+/*void appendBit(BIT_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);
+        bitPushBit(buffer, bit);
     }
-}
+}*/
 
 /**
  * Append data according to Chacon protocole
@@ -111,11 +329,11 @@ void appendBit(BUFFER* buffer, unsigned char bit, unsigned int usec, unsigned in
  * @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)
+/*void appendData(BIT_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
@@ -124,14 +342,14 @@ void appendData(BUFFER* buffer, unsigned int type, unsigned int freq)
  * @param byte the byte to append
  * @param clock frequency
  */
-void appendByte(BUFFER* buffer, unsigned char byte, unsigned int freq)
+/*void appendByte(BIT_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);
-}
+}*/
 
 
 /**
@@ -145,7 +363,7 @@ void appendByte(BUFFER* buffer, unsigned char byte, unsigned int freq)
  * @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)
+/*void pushCode(BIT_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];
@@ -163,4 +381,4 @@ void pushCode(BUFFER* buffer, unsigned char* id, unsigned char section, unsigned
     appendByte(buffer, byte7, freq);
     appendData(buffer, START_OF_FRAME, freq);
     printf("EOD ");
-}
+}*/

+ 124 - 22
emit/emitlib.h

@@ -2,10 +2,15 @@
 
 
 typedef struct {
+    char* data;
     unsigned long int byteSize;
     unsigned int bitSize;
+} BIT_BUFFER;
+
+typedef struct {
     char* data;
-} BUFFER;
+    unsigned long int size;
+} BYTE_BUFFER;
 
 #define BIT0 0
 #define BIT1 1
@@ -15,39 +20,55 @@ typedef struct {
 #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 bit buffer
+ *
+ * @return the created buffer
+ */
+BIT_BUFFER createBitBuffer();
 
 /**
- * Create a new buffer
+ * Create a new byte buffer
  *
  * @return the created buffer
  */
-BUFFER createBuffer();
+BYTE_BUFFER createByteBuffer();
+
+/**
+ * Release the memory
+ *
+ * @param buffer the buffer to destroy
+ */
+void destroyBitBuffer(BIT_BUFFER buffer);
 
 /**
  * Release the memory
  *
  * @param buffer the buffer to destroy
  */
-void destroyBuffer(BUFFER buffer);
+void destroyByteBuffer(BYTE_BUFFER buffer);
 
 /**
  * Print all the bits from a buffer
  *
  * @param buffer the buffer holding the data
  */
-void printfBinaryBuffer(BUFFER buffer);
+//void printfBitBuffer(BIT_BUFFER buffer);
+void printfBitBuffer(BYTE_BUFFER buffer);
+
+/**
+ * Print a byte in binary
+ * 
+ * @param byte the byte to print
+ */
+void printfBit(unsigned char byte);
+
+/**
+ * Print all the bytes from a buffer
+ *
+ * @param buffer the buffer holding the data
+ */
+void printfByteBuffer(BYTE_BUFFER buffer);
 
 /**
  * Push a bit in a buffer
@@ -55,7 +76,88 @@ void printfBinaryBuffer(BUFFER buffer);
  * @param buffer the buffer holding the data
  * @param bit the bit to push
  */
-void pushBit(BUFFER* buffer, unsigned char bit);
+//void bitPushBit(BIT_BUFFER* buffer, unsigned char bit);
+
+/**
+ * Push a byte in a buffer
+ *
+ * @param buffer the buffer holding the data
+ * @param byt the byte to push
+ */
+void pushByte(BYTE_BUFFER* buffer, unsigned char byte);
+
+/**
+ * Push a word in a buffer
+ *
+ * @param buffer the buffer holding the data
+ * @param word the word to push
+ */
+void pushWord(BYTE_BUFFER* buffer, unsigned short int word);
+
+/**
+ * Push some bytes in a buffer
+ *
+ * @param buffer the buffer holding the data
+ * @param bytes the bytes to push
+ * @param len the number of bytes to push
+ */
+void pushBytes(BYTE_BUFFER* buffer, unsigned char *byte, unsigned int len);
+
+/**
+ * Encode bits with HomeEasy encoding (1 => 10, 0 => 01)
+ * 
+ * @param buffer the buffuer to encode
+ * 
+ * @return new buffer
+ * */
+BYTE_BUFFER homeEasyEncode(BYTE_BUFFER *buffer);
+
+/**
+ * Decode bits with HomeEasy encoding (1 => 10, 0 => 01)
+ * 
+ * @param buffer the buffuer to decode
+ * 
+ * @return new buffer
+ * */
+BYTE_BUFFER homeEasyDecode(BYTE_BUFFER *buffer);
+
+/**
+ * Encode a byte according to HomeEasy
+ * 
+ * @param byte the byte to encode
+ * 
+ * @return the encoded byte
+ */
+unsigned short int encodeByte(unsigned char byte);
+
+/**
+ * Decode a byte according to HomeEasy
+ * 
+ * @param byte the byte to decode
+ * 
+ * @return the decoded byte
+ */
+unsigned char decodeByte(unsigned short int word);
+
+/**
+ * Gives the bit at a specific position
+ * 
+ * @param buffer the buffer to evaluate
+ * @param n the bit position
+ * 
+ * @return the bit value
+ */
+unsigned int bitAt(BYTE_BUFFER buffer, unsigned long int n);
+
+/**
+ * Append a complete command according to Chacon protocole
+ *
+ * @param id command id (refer to your remote)
+ * @param section button section ('A' | 'B'  | 'C'  | 'D'  | 'G')
+ * @param nb button number(1, 2, 3, 4)
+ * @param on boolean for on/off
+ */
+BYTE_BUFFER createHomeEasyCommand(unsigned char* id, char section, unsigned char nb, unsigned char on);
 
 /**
  * Append a bit that will be emitted for a specific time
@@ -65,7 +167,7 @@ void pushBit(BUFFER* buffer, unsigned char bit);
  * @param usec time in µs
  * @param clock frequency
  */
-void appendBit(BUFFER* buffer, unsigned char bit, unsigned int usec, unsigned int freq);
+//void appendBit(BIT_BUFFER* buffer, unsigned char bit, unsigned int usec, unsigned int freq);
 
 /**
  * Append data according to Chacon protocole
@@ -74,7 +176,7 @@ void appendBit(BUFFER* buffer, unsigned char bit, unsigned int usec, unsigned in
  * @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);
+//void appendData(BIT_BUFFER* buffer, unsigned int type, unsigned int freq);
 
 /**
  * Append a byte according to Chacon protocole
@@ -83,7 +185,7 @@ void appendData(BUFFER* buffer, unsigned int type, unsigned int freq);
  * @param byte the byte to append
  * @param clock frequency
  */
-void appendByte(BUFFER* buffer, unsigned char byte, unsigned int freq);
+//void appendByte(BIT_BUFFER* buffer, unsigned char byte, unsigned int freq);
 
 /**
  * Append a complete command according to Chacon protocole
@@ -96,4 +198,4 @@ void appendByte(BUFFER* buffer, unsigned char byte, unsigned int freq);
  * @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);
+//void pushCode(BIT_BUFFER* buffer, unsigned char* id, unsigned char section, unsigned char nb, unsigned char on, unsigned char global, unsigned int freq);

+ 274 - 0
emit/home_easy.c

@@ -0,0 +1,274 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <string.h>
+#include <wiringPi.h>
+#include "home_easy.h"
+#include "buffer.h"
+#include "utils.h"
+
+unsigned int timings[5][2] = {
+    {275, 275},  //  bit 0
+    {275, 1300}, //  bit 1
+    {275, 9900},  //  end of data
+    {275, 2675}, //  start of frame
+    {275, 2675},  //  end of data
+};
+
+unsigned char homeEasyPinOut = 0;
+unsigned char homeEasyPinIn = 1;
+
+
+/**
+ * Encode bits with HomeEasy encoding (1 => 10, 0 => 01)
+ * 
+ * @param buffer the buffuer to encode
+ * 
+ * @return new buffer
+ * */
+BYTE_BUFFER homeEasyEncode(BYTE_BUFFER *buffer)
+{
+    BYTE_BUFFER result = createByteBuffer();
+    unsigned int i;
+    for(i=0; i<buffer->size; i++) {
+        pushWord(&result, encodeByte(buffer->data[i]));
+    }
+    return result;
+}
+
+/**
+ * Decode bits with HomeEasy encoding (1 => 10, 0 => 01)
+ * 
+ * @param buffer the buffuer to decode
+ * 
+ * @return new buffer
+ * */
+BYTE_BUFFER homeEasyDecode(BYTE_BUFFER *buffer)
+{
+    BYTE_BUFFER result = createByteBuffer();
+    unsigned short int word;
+    unsigned char *byte = (unsigned char*)&word;
+    unsigned int i;
+    for(i=0; i<(buffer->size+1)/2; i++) {
+        byte[1] = buffer->data[2*i];
+        byte[0] = (2*i+1 < buffer->size ? buffer->data[2*i+1]:0);
+        pushByte(&result, decodeByte(word));
+    }
+    return result;
+}
+
+/**
+ * Decode a byte according to HomeEasy
+ * 
+ * @param byte the byte to decode
+ * 
+ * @return the decoded byte
+ */
+unsigned char decodeByte(unsigned short int word)
+{
+    unsigned char decodedChar=0;
+    int j;
+    int shift = 7;
+    for(j=0x8000;j>0; j>>=2) {
+	    decodedChar |= (((word & j) == j) ? 0x01 : 0x00) << shift;
+		shift -=1;
+    }
+    return decodedChar;
+}
+
+/**
+ * Encode a byte according to HomeEasy
+ * 
+ * @param byte the byte to encode
+ * 
+ * @return the encoded byte
+ */
+unsigned short int encodeByte(unsigned char byte)
+{
+    unsigned short int encodedChar=0;
+    int j;
+    int shift = 14;
+    for(j=0x80;j>0; j>>=1) {
+	      encodedChar |= (((byte & j) == j) ? 0x02 : 0x01) << shift;
+	      shift -=2;
+    }
+    return encodedChar;
+}
+
+/**
+ * Create a complete command according to Chacon protocole
+ *
+ * @param id command id (refer to your remote)
+ * @param section button section ('A' | 'B'  | 'C'  | 'D'  | 'G')
+ * @param nb button number(1, 2, 3, 4)
+ * @param on boolean for on/off
+ */
+BYTE_BUFFER createHomeEasyCommand(unsigned char* id, char section, unsigned char nb, unsigned char on)
+{
+    unsigned char last = id[3] & 0xc0;
+    BYTE_BUFFER command;
+    char formatedSection = (section<='Z' ? section : section + 'A' - 'a');
+    // adding global
+    last |= (formatedSection == 'G' ? 0x20 : 0);
+    // adding on/off
+    last |= (on ? 0x10 : 0);
+    // adding section
+    last |= ((formatedSection == 'G' ? 0 : formatedSection - 'A') << 2) & 0x0c;
+    // adding num
+    last |= (formatedSection == 'G' ? 0 : nb-1) & 0x03;;
+    //Preparing output buffer
+    command = createByteBuffer();
+    pushBytes(&command, id, 3);
+    pushByte(&command, last);
+    return command;
+}
+
+/**
+ * Send a complete command according to Chacon protocole
+ *
+ * @param id command id (refer to your remote)
+ * @param section button section ('A' | 'B'  | 'C'  | 'D'  | 'G')
+ * @param nb button number(1, 2, 3, 4)
+ * @param on boolean for on/off
+ * @param repeat number of repeatition
+ */
+void SendHomeEasyCommand(unsigned char* id, char section, unsigned char nb, unsigned char on, unsigned char repeat)
+{
+	BYTE_BUFFER command;
+	unsigned int i;
+	command = createHomeEasyCommand(id, section, nb, on);
+	sendHomeEasyBit(TRIGGER0);
+	sendHomeEasyBit(TRIGGER1);
+	for(i=0; i<repeat; i++) {
+		sendHomeEasyBytes(command);
+		sendHomeEasyBit(END_OF_FRAME);
+	}
+}
+
+/**
+ * Configure the GPIO output pin
+ *
+ * @param pinNumber wiringPi pin number
+ */
+void setHomeEasyTransmittorPin(unsigned char pinNumber)
+{
+	homeEasyPinOut = pinNumber;
+}
+
+/**
+ * read the GPIO output pin
+ *
+ * @return wiringPi pin number
+ */
+unsigned char getHomeEasyTransmittorPin()
+{
+	return homeEasyPinOut;
+}
+
+/**
+ * Configure the GPIO input pin
+ *
+ * @param pinNumber wiringPi pin number
+ */
+void setHomeEasyReceptorPin(unsigned char pinNumber)
+{
+	homeEasyPinIn = pinNumber;
+}
+
+/**
+ * read the GPIO input pin
+ *
+ * @return wiringPi pin number
+ */
+unsigned char getHomeEasyReceptorPin()
+{
+	return homeEasyPinIn;
+}
+
+/**
+ * Send a bit to the RF transmitter
+ * 
+ * @param bit the bit to transmit (0 | 1 | TRIGGER0 | TRIGGER1 | END_OF_FRAME)
+ */
+void sendHomeEasyBit(unsigned char bit)
+{
+	digitalWrite(homeEasyPinOut, 1);
+    delayMicroseconds(timings[bit][0]);
+   	digitalWrite(homeEasyPinOut, 0);
+    delayMicroseconds(timings[bit][1]);
+}
+
+/**
+ * Send a byte to the RF transmitter
+ * 
+ * @param byte the byte to transmit
+ */
+void sendHomeEasyByte(unsigned char byte)
+{
+    int i;
+    for(i=0x80;i>0; i>>=1) {
+    	sendHomeEasyBit((byte & i) == i);
+    }
+}
+
+/**
+ * Send the content of a buffer to the RF transmitter
+ * 
+ * @param buffer the buffer to transmit
+ */
+void sendHomeEasyBytes(BYTE_BUFFER buffer)
+{
+	unsigned int i;
+	for(i=0; i<buffer.size; i++) {
+		sendHomeEasyByte(buffer.data[i]);
+	}
+}
+
+/**
+ * Calculate the length of the frame
+ *
+ * @param data data to scan (each byte represent a bit)
+ * @param high length of high level
+ * @param low length of low level
+ *
+ * @return total length of the frame
+ */
+unsigned int frameSize(unsigned char* data, unsigned int* high, unsigned int* low)
+{
+    unsigned int i=0;
+    if (high) *high = 0;
+    if (data[i] == 1) {
+        for(i=0; data[i]; i++) ;
+        if (high) *high = i;
+    }
+    for(;  !data[i]; i++) ;
+    if (low) *low = i - *high;
+    return i;
+}
+
+/**
+ * Reading data from GPIO
+ *
+ * @param samples number of samples to read
+ * @param duration waiting time between samples
+ *
+ * @return buffer
+ */
+BYTE_BUFFER readData(unsigned long int samples, unsigned int duration)
+{
+    struct timeval* start;
+    BYTE_BUFFER result;
+    unsigned long int i;
+    
+    result = createByteBuffer();
+    result.size = samples;
+    result.data = (char*) realloc(result.data, samples);
+
+    start = showTime(0);
+    for(i=0; i<samples; i++) {
+        result.data[i] = digitalRead(homeEasyPinIn);
+        delayMicroseconds(duration);
+    }
+    showTime(start);
+    return result;
+}

+ 143 - 0
emit/home_easy.h

@@ -0,0 +1,143 @@
+#ifndef __HOME_EASY_H__
+#define __HOME_EASY_H__
+
+#include <stdio.h>
+#include "buffer.h"
+
+#define BIT0 0
+#define BIT1 1
+#define TRIGGER0 2
+#define TRIGGER1 3
+#define END_OF_FRAME 3
+
+#define ON 1
+#define OFF 0
+
+/**
+ * Encode bits with HomeEasy encoding (1 => 10, 0 => 01)
+ * 
+ * @param buffer the buffuer to encode
+ * 
+ * @return new buffer
+ * */
+BYTE_BUFFER homeEasyEncode(BYTE_BUFFER *buffer);
+
+/**
+ * Decode bits with HomeEasy encoding (1 => 10, 0 => 01)
+ * 
+ * @param buffer the buffuer to decode
+ * 
+ * @return new buffer
+ * */
+BYTE_BUFFER homeEasyDecode(BYTE_BUFFER *buffer);
+
+/**
+ * Encode a byte according to HomeEasy
+ * 
+ * @param byte the byte to encode
+ * 
+ * @return the encoded byte
+ */
+unsigned short int encodeByte(unsigned char byte);
+
+/**
+ * Decode a byte according to HomeEasy
+ * 
+ * @param byte the byte to decode
+ * 
+ * @return the decoded byte
+ */
+unsigned char decodeByte(unsigned short int word);
+
+/**
+ * Creata a complete command according to Chacon protocole
+ *
+ * @param id command id (refer to your remote)
+ * @param section button section ('A' | 'B'  | 'C'  | 'D'  | 'G')
+ * @param nb button number(1, 2, 3, 4)
+ * @param on boolean for on/off
+ */
+BYTE_BUFFER createHomeEasyCommand(unsigned char* id, char section, unsigned char nb, unsigned char on);
+
+/**
+ * Send a complete command according to Chacon protocole
+ *
+ * @param id command id (refer to your remote)
+ * @param section button section ('A' | 'B'  | 'C'  | 'D'  | 'G')
+ * @param nb button number(1, 2, 3, 4)
+ * @param on boolean for on/off
+ * @param repeat number of repeatition
+ */
+void SendHomeEasyCommand(unsigned char* id, char section, unsigned char nb, unsigned char on, unsigned char repeat);
+
+/**
+ * Configure the GPIO output pin
+ *
+ * @param pinNumber wiringPi pin number
+ */
+void setHomeEasyTransmittorPin(unsigned char pinNumber);
+
+/**
+ * read the GPIO output pin
+ *
+ * @return wiringPi pin number
+ */
+unsigned char getHomeEasyTransmittorPin();
+
+/**
+ * Configure the GPIO input pin
+ *
+ * @param pinNumber wiringPi pin number
+ */
+void setHomeEasyReceptorPin(unsigned char pinNumber);
+
+/**
+ * read the GPIO input pin
+ *
+ * @return wiringPi pin number
+ */
+unsigned char getHomeEasyReceptorPin();
+
+/**
+ * Send a bit to the RF transmitter
+ * 
+ * @param bit the bit to transmit (0 | 1 | TRIGGER0 | TRIGGER1 | END_OF_FRAME)
+ */
+void sendHomeEasyBit(unsigned char bit);
+
+/**
+ * Send a byte to the RF transmitter
+ * 
+ * @param byte the byte to transmit
+ */
+void sendHomeEasyByte(unsigned char byte);
+
+/**
+ * Send the content of a buffer to the RF transmitter
+ * 
+ * @param buffer the buffer to transmit
+ */
+void sendHomeEasyBytes(BYTE_BUFFER buffer);
+
+/**
+ * Calculate the length of the frame
+ *
+ * @param data data to scan (each byte represent a bit)
+ * @param high length of high level
+ * @param low length of low level
+ *
+ * @return total length of the frame
+ */
+unsigned int frameSize(unsigned char* data, unsigned int* high, unsigned int* low);
+
+/**
+ * Reading data from GPIO
+ *
+ * @param samples number of samples to read
+ * @param duration waiting time between samples
+ *
+ * @return buffer
+ */
+BYTE_BUFFER readData(unsigned long int samples, unsigned int duration);
+
+ #endif

+ 13 - 0
emit/test/Makefile

@@ -0,0 +1,13 @@
+all : test
+
+test : test.o buffer.o home_easy.o utils.o
+	gcc -o $@ $^
+
+test.o : test.c
+	gcc -c $< -o $@
+
+%.o : ../%.c ../%.h
+	gcc -c $< -o $@
+
+clean:
+	rm -f test *.o

+ 141 - 0
emit/test/test.c

@@ -0,0 +1,141 @@
+#include <stdio.h>
+#include "../home_easy.h"
+#include "../buffer.h"
+
+#define TEST_START printf("\n=== %s ===\n", __FUNCTION__)
+
+
+void testByteBuffer()
+{
+    BYTE_BUFFER buffer;
+    char bytes[] = {0xcd, 0xef, 0x12};
+    TEST_START;
+    
+    buffer = createByteBuffer();
+    
+    pushByte(&buffer, 0xab);
+    pushBytes(&buffer, bytes, 3);
+    pushWord(&buffer, 0x3456);
+    
+    printf("Should: AB CD EF 12 34 56\nGet: ");
+    printfByteBuffer(buffer);
+    
+    destroyByteBuffer(buffer);
+}
+
+void testPrintBits()
+{
+    BYTE_BUFFER buffer;
+    char bytes[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
+    TEST_START;
+    
+    buffer = createByteBuffer();
+    pushBytes(&buffer, bytes, 8);
+
+    printfBitBuffer(buffer);
+    
+    destroyByteBuffer(buffer);
+}
+
+void testEncode()
+{
+    unsigned char srcByte = 0x28;
+    unsigned short int encWord;
+    TEST_START;
+    
+    encWord = encodeByte(srcByte);
+    printf("Input: %02X\nShould: 0x5995\nGet: %04X\n", srcByte, encWord);
+    
+}
+
+
+void testDecode()
+{
+    unsigned short int srcWord = 0x5995;
+    unsigned char decByte;
+    TEST_START;
+    
+    decByte = decodeByte(srcWord);
+    printf("Input: %04X\nShould: 0x28\nGet: %02X\n", srcWord, decByte);
+    
+}
+
+void testHomeEasyEncode()
+{
+    BYTE_BUFFER source;
+    BYTE_BUFFER encoded;
+    unsigned char bytes[] = {0x28, 0x28, 0x01};
+    TEST_START;
+    
+    source = createByteBuffer();
+    pushBytes(&source, bytes, 3);
+    printf("Input: ");
+    printfByteBuffer(source);
+    printf("Should: 59 95 59 95 55 56\nGet:    ");
+    
+    encoded = homeEasyEncode(&source);
+    printfByteBuffer(encoded);
+    
+    destroyByteBuffer(source);
+    destroyByteBuffer(encoded);
+}
+
+void testHomeEasyDecode()
+{
+    BYTE_BUFFER source;
+    BYTE_BUFFER decoded;
+    unsigned char bytes[] = {0x59, 0x95, 0x59, 0x95, 0x55, 0x56};
+    TEST_START;
+    
+    source = createByteBuffer();
+    pushBytes(&source, bytes, 6);
+    printf("Input: ");
+    printfByteBuffer(source);
+    printf("Should: 28 28 01\nGet:    ");
+    
+    decoded = homeEasyDecode(&source);
+    printfByteBuffer(decoded);
+    
+    destroyByteBuffer(source);
+    destroyByteBuffer(decoded);
+}
+
+
+void testHomeEasyCommand(char section, unsigned char num, unsigned char onOff)
+{
+    BYTE_BUFFER command;
+    BYTE_BUFFER encoded;
+    unsigned char id[] = {0x28, 0x28, 0x01, 0x80};
+    TEST_START;
+    
+    command = createHomeEasyCommand(id, section, num, onOff);
+    printfByteBuffer(command);
+    
+    encoded = homeEasyEncode(&command);
+    printfByteBuffer(encoded);
+    
+    destroyByteBuffer(command);
+    destroyByteBuffer(encoded);
+}
+
+int main()
+{
+    printf("Test\n");
+    
+    testByteBuffer();
+    
+    //testBitBuffer();
+    testPrintBits();
+    
+    testEncode();
+    
+    testDecode();
+    
+    testHomeEasyEncode();
+    
+    testHomeEasyDecode();
+    
+    testHomeEasyCommand('D', 4, ON);
+    
+    return 0;
+}

+ 28 - 0
emit/utils.c

@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include "utils.h"
+
+
+
+/**
+ * Calculate a duration
+ *
+ * @param start start of the computing or null if
+ * this is the first time this function is inoked
+ *
+ * @return current time
+ */
+struct timeval* showTime(struct timeval* start)
+{
+    struct timeval* stop;
+    long tv_sec;
+    long tv_usec;
+    stop = (struct timeval*)malloc(sizeof(struct timeval));
+    gettimeofday(stop, 0);
+    if (!start) return stop;
+    tv_sec = (start->tv_usec > stop->tv_usec) ? stop->tv_sec - start->tv_sec - 1 : stop->tv_sec - start->tv_sec;
+    tv_usec = (start->tv_usec > stop->tv_usec) ? 1000000 + stop->tv_usec - start->tv_usec : stop->tv_usec - start->tv_usec;
+    fprintf(stderr, "%lus %lums %luµs\n", tv_sec, tv_usec/1000, tv_sec % 1000);
+    return stop;
+}

+ 18 - 0
emit/utils.h

@@ -0,0 +1,18 @@
+#ifndef __UTILS_H__
+#define __UTILS_H__
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+/**
+ * Calculate a duration
+ *
+ * @param start start of the computing or null if
+ * this is the first time this function is inoked
+ *
+ * @return current time
+ */
+struct timeval* showTime(struct timeval* start);
+
+#endif