emitlib.c 7.0 KB

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