emitlib.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <malloc.h>
  4. #include <string.h>
  5. #include "emitlib.h"
  6. unsigned int timings[4][2] = {
  7. {250, 250}, // bit 0
  8. {250, 1200}, // bit 1
  9. {250, 2600}, // start of frame
  10. {250, 9900} // end of data
  11. };
  12. unsigned char numbering[4] = {0x05, 0x06, 0x09, 0x0A};
  13. /**
  14. * Create a new buffer
  15. *
  16. * @return the created buffer
  17. */
  18. BIT_BUFFER createBitBuffer()
  19. {
  20. BIT_BUFFER buffer;
  21. buffer.byteSize = 1;
  22. buffer.bitSize = 0;
  23. buffer.data = (char*) malloc(1);
  24. buffer.data[0] = 0;
  25. return buffer;
  26. }
  27. /**
  28. * Release the memory
  29. *
  30. * @param buffer the buffer to destroy
  31. */
  32. void destroyBitBuffer(BIT_BUFFER buffer)
  33. {
  34. free(buffer.data);
  35. }
  36. /**
  37. * Create a new byte buffer
  38. *
  39. * @return the created buffer
  40. */
  41. BYTE_BUFFER createByteBuffer()
  42. {
  43. BYTE_BUFFER buffer;
  44. buffer.size = 0;
  45. buffer.data = (char*) malloc(1);
  46. return buffer;
  47. }
  48. /**
  49. * Release the memory
  50. *
  51. * @param buffer the buffer to destroy
  52. */
  53. void destroyByteBuffer(BYTE_BUFFER buffer)
  54. {
  55. free(buffer.data);
  56. }
  57. /**
  58. * Print all the bits from a buffer
  59. *
  60. * @param buffer the buffer holding the data
  61. */
  62. /*void printfBitBuffer(BIT_BUFFER buffer)
  63. {
  64. printf("bytes: %lu\nbits: %d\n", buffer.byteSize, buffer.bitSize);
  65. unsigned char byte;
  66. unsigned char bit;
  67. unsigned int x;
  68. int i;
  69. for(x=0; x<(buffer.bitSize ? buffer.byteSize : buffer.byteSize-1) ; x++) {
  70. byte = buffer.data[x];
  71. for(i=0x80; i>0; i>>=1) {
  72. if ((bit==0) && (byte & i)) {
  73. fprintf(stdout, "\n");
  74. }
  75. bit = ((byte & i) == i);
  76. fprintf(stdout, "%d", bit);
  77. }
  78. }
  79. }*/
  80. void printfBitBuffer(BYTE_BUFFER buffer)
  81. {
  82. printf("bytes: %lu\nbits: %lu\n", buffer.size, buffer.size*8);
  83. unsigned int x;
  84. for(x=0; x<buffer.size ; x++) {
  85. printfBit(buffer.data[x]);
  86. printf("\n");
  87. }
  88. }
  89. /**
  90. * Print a byte in binary
  91. *
  92. * @param byte the byte to print
  93. */
  94. void printfBit(unsigned char byte)
  95. {
  96. int i;
  97. for(i=0x80; i>0; i>>=1) {
  98. fprintf(stdout, "%d", ((byte & i) == i));
  99. }
  100. }
  101. /**
  102. * Print all the bytes from a buffer
  103. *
  104. * @param buffer the buffer holding the data
  105. */
  106. void printfByteBuffer(BYTE_BUFFER buffer)
  107. {
  108. unsigned int i;
  109. for(i=0; i<buffer.size; i++) {
  110. fprintf(stdout, "%02X ", (unsigned char)buffer.data[i]);
  111. }
  112. fprintf(stdout, "\n");
  113. }
  114. /**
  115. * Push a bit in a buffer
  116. *
  117. * @param buffer the buffer holding the data
  118. * @param bit the bit to push
  119. */
  120. /*void bitPushBit(BIT_BUFFER* buffer, unsigned char bit)
  121. {
  122. buffer->data[buffer->byteSize-1] |= bit << (7-buffer->bitSize);
  123. buffer->bitSize++;
  124. if (buffer->bitSize == 8) {
  125. buffer->bitSize = 0;
  126. buffer->byteSize++;
  127. buffer->data = (char*)realloc(buffer->data, buffer->byteSize);
  128. buffer->data[buffer->byteSize-1] = 0;
  129. }
  130. }*/
  131. /**
  132. * Push a byte in a buffer
  133. *
  134. * @param buffer the buffer holding the data
  135. * @param byte the byte to push
  136. */
  137. void pushByte(BYTE_BUFFER* buffer, unsigned char byte)
  138. {
  139. buffer->size++;
  140. buffer->data = (char*)realloc(buffer->data, buffer->size);
  141. buffer->data[buffer->size-1] = byte;
  142. }
  143. /**
  144. * Push a word in a buffer
  145. *
  146. * @param buffer the buffer holding the data
  147. * @param word the word to push
  148. */
  149. void pushWord(BYTE_BUFFER* buffer, unsigned short int word)
  150. {
  151. unsigned char* data = (unsigned char*)&word;
  152. pushByte(buffer, data[1]);
  153. pushByte(buffer, data[0]);
  154. }
  155. /**
  156. * Push some bytes in a buffer
  157. *
  158. * @param buffer the buffer holding the data
  159. * @param bytes the bytes to push
  160. * @param len the number of bytes to push
  161. */
  162. void pushBytes(BYTE_BUFFER* buffer, unsigned char *byte, unsigned int len)
  163. {
  164. buffer->data = (char*)realloc(buffer->data, buffer->size+len);
  165. memcpy(&buffer->data[buffer->size], byte, len);
  166. buffer->size += len;
  167. }
  168. /**
  169. * Encode bits with HomeEasy encoding (1 => 10, 0 => 01)
  170. *
  171. * @param buffer the buffuer to encode
  172. *
  173. * @return new buffer
  174. * */
  175. BYTE_BUFFER homeEasyEncode(BYTE_BUFFER *buffer)
  176. {
  177. BYTE_BUFFER result = createByteBuffer();
  178. unsigned int i;
  179. for(i=0; i<buffer->size; i++) {
  180. pushWord(&result, encodeByte(buffer->data[i]));
  181. }
  182. return result;
  183. }
  184. /**
  185. * Decode bits with HomeEasy encoding (1 => 10, 0 => 01)
  186. *
  187. * @param buffer the buffuer to decode
  188. *
  189. * @return new buffer
  190. * */
  191. BYTE_BUFFER homeEasyDecode(BYTE_BUFFER *buffer)
  192. {
  193. BYTE_BUFFER result = createByteBuffer();
  194. unsigned short int word;
  195. unsigned char *byte = (unsigned char*)&word;
  196. unsigned int i;
  197. for(i=0; i<(buffer->size+1)/2; i++) {
  198. byte[1] = buffer->data[2*i];
  199. byte[0] = (2*i+1 < buffer->size ? buffer->data[2*i+1]:0);
  200. pushByte(&result, decodeByte(word));
  201. }
  202. return result;
  203. }
  204. /**
  205. * Decode a byte according to HomeEasy
  206. *
  207. * @param byte the byte to decode
  208. *
  209. * @return the decoded byte
  210. */
  211. unsigned char decodeByte(unsigned short int word)
  212. {
  213. unsigned char decodedChar=0;
  214. int j;
  215. int shift = 7;
  216. for(j=0x8000;j>0; j>>=2) {
  217. decodedChar |= (((word & j) == j) ? 0x01 : 0x00) << shift;
  218. shift -=1;
  219. }
  220. return decodedChar;
  221. }
  222. /**
  223. * Encode a byte according to HomeEasy
  224. *
  225. * @param byte the byte to encode
  226. *
  227. * @return the encoded byte
  228. */
  229. unsigned short int encodeByte(unsigned char byte)
  230. {
  231. unsigned short int encodedChar=0;
  232. int j;
  233. int shift = 14;
  234. for(j=0x80;j>0; j>>=1) {
  235. encodedChar |= (((byte & j) == j) ? 0x02 : 0x01) << shift;
  236. shift -=2;
  237. }
  238. return encodedChar;
  239. }
  240. /**
  241. * Gives the bit at a specific position
  242. *
  243. * @param buffer the buffer to evaluate
  244. * @param n the bit position
  245. *
  246. * @return the bit value
  247. */
  248. unsigned int bitAt(BYTE_BUFFER buffer, unsigned long int n)
  249. {
  250. unsigned char byte = buffer.data[n / 8];
  251. return (byte & (0x80 >> (n % 8)) != 0);
  252. }
  253. /**
  254. * Append a complete command according to Chacon protocole
  255. *
  256. * @param id command id (refer to your remote)
  257. * @param section button section ('A' | 'B' | 'C' | 'D' | 'G')
  258. * @param nb button number(1, 2, 3, 4)
  259. * @param on boolean for on/off
  260. */
  261. BYTE_BUFFER createHomeEasyCommand(unsigned char* id, char section, unsigned char nb, unsigned char on)
  262. {
  263. unsigned char last = id[3] & 0xc0;
  264. BYTE_BUFFER command;
  265. char formatedSection = (section<='Z' ? section : section + 'A' - 'a');
  266. // adding global
  267. last |= (formatedSection == 'G' ? 0x20 : 0);
  268. // adding on/off
  269. last |= (on ? 0x10 : 0);
  270. // adding section
  271. last |= ((formatedSection == 'G' ? 0 : formatedSection - 'A') << 2) & 0x0c;
  272. // adding num
  273. last |= (formatedSection == 'G' ? 0 : nb-1) & 0x03;;
  274. //Preparing output buffer
  275. command = createByteBuffer();
  276. pushBytes(&command, id, 3);
  277. pushByte(&command, last);
  278. return command;
  279. }
  280. /**
  281. * Append a bit that will be emitted for a specific time
  282. *
  283. * @param buffer the buffer holding the data
  284. * @param bit the bit to push
  285. * @param usec time in µs
  286. * @param clock frequency
  287. */
  288. /*void appendBit(BIT_BUFFER* buffer, unsigned char bit, unsigned int usec, unsigned int freq)
  289. {
  290. unsigned int i;
  291. for(i=0; i<(usec * freq) / 1e6; i++) {
  292. bitPushBit(buffer, bit);
  293. }
  294. }*/
  295. /**
  296. * Append data according to Chacon protocole
  297. *
  298. * @param buffer the buffer holding the data
  299. * @param type data type (BIT0 | BIT1 | START_OF_FRAME | END_OF_DATA)
  300. * @param clock frequency
  301. */
  302. /*void appendData(BIT_BUFFER* buffer, unsigned int type, unsigned int freq)
  303. {
  304. appendBit(buffer, 1, timings[type][0], freq);
  305. appendBit(buffer, 0, timings[type][1], freq);
  306. }*/
  307. /**
  308. * Append a byte according to Chacon protocole
  309. *
  310. * @param buffer the buffer holding the data
  311. * @param byte the byte to append
  312. * @param clock frequency
  313. */
  314. /*void appendByte(BIT_BUFFER* buffer, unsigned char byte, unsigned int freq)
  315. {
  316. int i;
  317. for(i=0x80; i>0; i>>=1) {
  318. appendData(buffer, ((byte & i) == i), freq);
  319. }
  320. printf("%02X ", byte);
  321. }*/
  322. /**
  323. * Append a complete command according to Chacon protocole
  324. *
  325. * @param buffer the buffer holding the data
  326. * @param id command id (refer to your remote)
  327. * @param section button section (0:A, 1:B, 2:C, 3:D)
  328. * @param nb button number(1, 2, 3, 4)
  329. * @param on boolean for on/off
  330. * @param global if true G button is selected (nb will be ignore)
  331. * @param clock frequency
  332. */
  333. /*void pushCode(BIT_BUFFER* buffer, unsigned char* id, unsigned char section, unsigned char nb, unsigned char on, unsigned char global, unsigned int freq)
  334. {
  335. unsigned char byte6 = (id[6] & 0xf0) + numbering[on + (global ? 2 : 0)];
  336. unsigned char byte7 = (numbering[section] << 4) + numbering[nb];
  337. unsigned int i;
  338. if (global) {
  339. byte7 = 0x55;
  340. }
  341. appendData(buffer, START_OF_FRAME, freq);
  342. printf("SOF ");
  343. for(i=0; i<6; i++) {
  344. appendByte(buffer, id[i], freq);
  345. }
  346. appendByte(buffer, byte6, freq);
  347. appendByte(buffer, byte7, freq);
  348. appendData(buffer, END_OF_DATA, freq);
  349. printf("EOD ");
  350. }*/