home_easy.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <malloc.h>
  4. #include <string.h>
  5. #include <wiringPi.h>
  6. #include "home_easy.h"
  7. #include "buffer.h"
  8. #include "utils.h"
  9. unsigned int timings[5][2] = {
  10. {275, 275}, // bit 0
  11. {275, 1300}, // bit 1
  12. {275, 9900}, // end of data
  13. {275, 2675}, // start of frame
  14. {275, 2675}, // end of data
  15. };
  16. unsigned char homeEasyPinOut = 0;
  17. unsigned char homeEasyPinIn = 2;
  18. /**
  19. * Encode bits with HomeEasy encoding (1 => 10, 0 => 01)
  20. *
  21. * @param buffer the buffuer to encode
  22. *
  23. * @return new buffer
  24. * */
  25. BYTE_BUFFER homeEasyEncode(BYTE_BUFFER *buffer)
  26. {
  27. BYTE_BUFFER result = createByteBuffer();
  28. unsigned int i;
  29. for(i=0; i<buffer->size; i++) {
  30. pushWord(&result, encodeByte(buffer->data[i]));
  31. }
  32. return result;
  33. }
  34. /**
  35. * Decode bits with HomeEasy encoding (1 => 10, 0 => 01)
  36. *
  37. * @param buffer the buffuer to decode
  38. *
  39. * @return new buffer
  40. * */
  41. BYTE_BUFFER homeEasyDecode(BYTE_BUFFER *buffer)
  42. {
  43. BYTE_BUFFER result = createByteBuffer();
  44. unsigned short int word;
  45. unsigned char *byte = (unsigned char*)&word;
  46. unsigned int i;
  47. for(i=0; i<(buffer->size+1)/2; i++) {
  48. byte[1] = buffer->data[2*i];
  49. byte[0] = (2*i+1 < buffer->size ? buffer->data[2*i+1]:0);
  50. pushByte(&result, decodeByte(word));
  51. }
  52. return result;
  53. }
  54. /**
  55. * Decode a byte according to HomeEasy
  56. *
  57. * @param byte the byte to decode
  58. *
  59. * @return the decoded byte
  60. */
  61. unsigned char decodeByte(unsigned short int word)
  62. {
  63. unsigned char decodedChar=0;
  64. int j;
  65. int shift = 7;
  66. for(j=0x8000;j>0; j>>=2) {
  67. decodedChar |= (((word & j) == j) ? 0x01 : 0x00) << shift;
  68. shift -=1;
  69. }
  70. return decodedChar;
  71. }
  72. /**
  73. * Encode a byte according to HomeEasy
  74. *
  75. * @param byte the byte to encode
  76. *
  77. * @return the encoded byte
  78. */
  79. unsigned short int encodeByte(unsigned char byte)
  80. {
  81. unsigned short int encodedChar=0;
  82. int j;
  83. int shift = 14;
  84. for(j=0x80;j>0; j>>=1) {
  85. encodedChar |= (((byte & j) == j) ? 0x02 : 0x01) << shift;
  86. shift -=2;
  87. }
  88. return encodedChar;
  89. }
  90. /**
  91. * Create a complete command according to Chacon protocole
  92. *
  93. * @param id command id (refer to your remote)
  94. * @param section button section ('A' | 'B' | 'C' | 'D' | 'G')
  95. * @param nb button number(1, 2, 3, 4)
  96. * @param on boolean for on/off
  97. */
  98. BYTE_BUFFER createHomeEasyCommand(unsigned char* id, char section, unsigned char nb, unsigned char on)
  99. {
  100. unsigned char last = id[3] & 0xc0;
  101. BYTE_BUFFER command;
  102. char formatedSection = (section<='Z' ? section : section + 'A' - 'a');
  103. // adding global
  104. last |= (formatedSection == 'G' ? 0x20 : 0);
  105. // adding on/off
  106. last |= (on ? 0x10 : 0);
  107. // adding section
  108. last |= ((formatedSection == 'G' ? 0 : formatedSection - 'A') << 2) & 0x0c;
  109. // adding num
  110. last |= (formatedSection == 'G' ? 0 : nb-1) & 0x03;;
  111. //Preparing output buffer
  112. command = createByteBuffer();
  113. pushBytes(&command, id, 3);
  114. pushByte(&command, last);
  115. return command;
  116. }
  117. /**
  118. * Send a complete command according to Chacon protocole
  119. *
  120. * @param id command id (refer to your remote)
  121. * @param section button section ('A' | 'B' | 'C' | 'D' | 'G')
  122. * @param nb button number(1, 2, 3, 4)
  123. * @param on boolean for on/off
  124. * @param repeat number of repeatition
  125. */
  126. void sendHomeEasyCommand(unsigned char* id, char section, unsigned char nb, unsigned char on, unsigned char repeat)
  127. {
  128. BYTE_BUFFER command;
  129. unsigned int i;
  130. command = createHomeEasyCommand(id, section, nb, on);
  131. sendHomeEasyBit(TRIGGER0);
  132. sendHomeEasyBit(TRIGGER1);
  133. for(i=0; i<repeat; i++) {
  134. sendHomeEasyBytes(command);
  135. sendHomeEasyBit(END_OF_FRAME);
  136. }
  137. }
  138. /**
  139. * Configure the GPIO output pin
  140. *
  141. * @param pinNumber wiringPi pin number
  142. */
  143. void setHomeEasyTransmittorPin(unsigned char pinNumber)
  144. {
  145. homeEasyPinOut = pinNumber;
  146. }
  147. /**
  148. * read the GPIO output pin
  149. *
  150. * @return wiringPi pin number
  151. */
  152. unsigned char getHomeEasyTransmittorPin()
  153. {
  154. return homeEasyPinOut;
  155. }
  156. /**
  157. * Configure the GPIO input pin
  158. *
  159. * @param pinNumber wiringPi pin number
  160. */
  161. void setHomeEasyReceptorPin(unsigned char pinNumber)
  162. {
  163. homeEasyPinIn = pinNumber;
  164. }
  165. /**
  166. * read the GPIO input pin
  167. *
  168. * @return wiringPi pin number
  169. */
  170. unsigned char getHomeEasyReceptorPin()
  171. {
  172. return homeEasyPinIn;
  173. }
  174. /**
  175. * Init input/output
  176. *
  177. * @return status
  178. */
  179. int initIO()
  180. {
  181. int status;
  182. status = wiringPiSetup();
  183. if (status != -1) {
  184. printf("Setting up GPIO\n");
  185. pinMode(homeEasyPinIn, INPUT);
  186. pinMode(homeEasyPinOut, OUTPUT);
  187. } else {
  188. printf("GPIO setup failed %d\n", status);
  189. }
  190. return status;
  191. }
  192. /**
  193. * Send a bit to the RF transmitter
  194. *
  195. * @param bit the bit to transmit (0 | 1 | TRIGGER0 | TRIGGER1 | END_OF_FRAME)
  196. */
  197. void sendHomeEasyBit(unsigned char bit)
  198. {
  199. digitalWrite(homeEasyPinOut, 1);
  200. delayMicroseconds(timings[bit][0]);
  201. digitalWrite(homeEasyPinOut, 0);
  202. delayMicroseconds(timings[bit][1]);
  203. }
  204. /**
  205. * Send a byte to the RF transmitter
  206. *
  207. * @param byte the byte to transmit
  208. */
  209. void sendHomeEasyByte(unsigned char byte)
  210. {
  211. int i;
  212. for(i=0x80;i>0; i>>=1) {
  213. sendHomeEasyBit((byte & i) == i);
  214. }
  215. }
  216. /**
  217. * Send the content of a buffer to the RF transmitter
  218. *
  219. * @param buffer the buffer to transmit
  220. */
  221. void sendHomeEasyBytes(BYTE_BUFFER buffer)
  222. {
  223. unsigned int i;
  224. for(i=0; i<buffer.size; i++) {
  225. sendHomeEasyByte(buffer.data[i]);
  226. }
  227. }
  228. /**
  229. * Calculate the length of the frame
  230. *
  231. * @param data data to scan (each byte represent a bit)
  232. * @param high length of high level
  233. * @param low length of low level
  234. *
  235. * @return total length of the frame
  236. */
  237. unsigned int frameSize(unsigned char* data, unsigned int* high, unsigned int* low)
  238. {
  239. unsigned int i=0;
  240. if (high) *high = 0;
  241. if (data[i] == 1) {
  242. for(i=0; data[i]; i++) ;
  243. if (high) *high = i;
  244. }
  245. for(; !data[i]; i++) ;
  246. if (low) *low = i - *high;
  247. return i;
  248. }
  249. /**
  250. * Reading data from GPIO
  251. *
  252. * @param samples number of samples to read
  253. * @param duration waiting time between samples
  254. *
  255. * @return buffer
  256. */
  257. BYTE_BUFFER readData(unsigned long int samples, unsigned int duration)
  258. {
  259. struct timeval* start;
  260. BYTE_BUFFER result;
  261. unsigned long int i;
  262. result = createByteBuffer();
  263. result.size = samples;
  264. result.data = (char*) realloc(result.data, samples);
  265. start = showTime(0);
  266. for(i=0; i<samples; i++) {
  267. result.data[i] = digitalRead(homeEasyPinIn);
  268. delayMicroseconds(duration);
  269. }
  270. showTime(start);
  271. return result;
  272. }