Details | Last modification | View Log | SVN | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 600 | nattgris | 1 | #include "protocols.h" |
| 2 | |||
| 3 | int8_t parseProtocol(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) { |
||
| 4 | /* Try all protocols in order. */ |
||
| 5 | #if (IR_PROTOCOLS_USE_SIRC) |
||
| 6 | if (parseSIRC(buf, len, proto)) return IR_OK; |
||
| 7 | #endif |
||
| 8 | #if (IR_PROTOCOLS_USE_RC5) |
||
| 9 | if (parseRC5(buf, len, proto)) return IR_OK; |
||
| 10 | #endif |
||
| 11 | #if (IR_PROTOCOLS_USE_SHARP) |
||
| 12 | if (parseSharp(buf, len, proto)) return IR_OK; |
||
| 13 | #endif |
||
| 14 | #if (IR_PROTOCOLS_USE_NEC) |
||
| 15 | if (parseNEC(buf, len, proto)) return IR_OK; |
||
| 16 | #endif |
||
| 17 | #if (IR_PROTOCOLS_USE_SAMSUNG) |
||
| 18 | if (parseSamsung(buf, len, proto)) return IR_OK; |
||
| 19 | #endif |
||
| 20 | /* No protocol matched. */ |
||
| 21 | return IR_NOT_CORRECT_DATA; |
||
| 22 | } |
||
| 23 | |||
| 24 | int8_t parseHash(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) { |
||
| 25 | //TODO: Transform the buffer in some clever way to a 32 bit word. */ |
||
| 26 | proto->protocol = IR_PROTO_HASH; |
||
| 27 | proto->timeout = 0; |
||
| 28 | proto->data = 0; |
||
| 29 | } |
||
| 30 | |||
| 31 | int8_t expandProtocol(uint16_t *buf, uint8_t len, const Ir_Protocol_Data_t *proto) { |
||
| 32 | /* Call the expand function for the specified protocol. */ |
||
| 33 | switch (proto->protocol) { |
||
| 34 | case IR_PROTO_SIRC: |
||
| 35 | return expandSIRC(buf, len, proto); |
||
| 36 | case IR_PROTO_RC5: |
||
| 37 | return expandRC5(buf, len, proto); |
||
| 38 | case IR_PROTO_SHARP: |
||
| 39 | return expandSharp(buf, len, proto); |
||
| 40 | case IR_PROTO_NEC: |
||
| 41 | return expandNEC(buf, len, proto); |
||
| 42 | case IR_PROTO_SAMSUNG: |
||
| 43 | return expandSamsung(buf, len, proto); |
||
| 44 | } |
||
| 45 | /* Invalid protocol specified. */ |
||
| 46 | return IR_NOT_CORRECT_DATA; |
||
| 47 | } |
||
| 48 | |||
| 49 | #if (IR_PROTOCOLS_USE_SIRC) |
||
| 50 | /** |
||
| 51 | * Test data on SIRC protocol, 12-bit version |
||
| 52 | * http://www.sbprojects.com/knowledge/ir/sirc.htm |
||
| 53 | * |
||
| 54 | * @param address |
||
| 55 | * Pointer to store the address of the received data |
||
| 56 | * @param command |
||
| 57 | * Pointer to store the command of the received data |
||
| 58 | * @return |
||
| 59 | * IR_OK if data parsed successfully, one of several errormessages if not |
||
| 60 | */ |
||
| 61 | int8_t parseSIRC(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) { |
||
| 62 | /* parse buf[], max is len */ |
||
| 63 | |||
| 64 | /* check if we have correct amount of data */ |
||
| 65 | if (len != 25) { |
||
| 66 | return IR_NOT_CORRECT_DATA; |
||
| 67 | } |
||
| 68 | |||
| 69 | /* check startbit */ |
||
| 70 | if (buf[0] > IR_SIRC_ST_BIT + IR_SIRC_ST_BIT/IR_SIRC_TOL_DIV || buf[0] < IR_SIRC_ST_BIT - IR_SIRC_ST_BIT/IR_SIRC_TOL_DIV) { |
||
| 71 | return IR_NOT_CORRECT_DATA; |
||
| 72 | } |
||
| 73 | |||
| 74 | uint16_t rawbits=0; |
||
| 75 | |||
| 76 | for (uint8_t i = 1; i < len; i++) { |
||
| 77 | if ((i&1) == 1) { /* if odd, ir-pause */ |
||
| 78 | /* check length of pause between bits */ |
||
| 79 | if (buf[i] > IR_SIRC_LOW + IR_SIRC_LOW/IR_SIRC_TOL_DIV || buf[i] < IR_SIRC_LOW - IR_SIRC_LOW/IR_SIRC_TOL_DIV) { |
||
| 80 | return IR_NOT_CORRECT_DATA; |
||
| 81 | } |
||
| 82 | } else { /* if even, ir-bit */ |
||
| 83 | if (buf[i] > IR_SIRC_HIGH_ONE - IR_SIRC_HIGH_ONE/IR_SIRC_TOL_DIV && buf[i] < IR_SIRC_HIGH_ONE + IR_SIRC_HIGH_ONE/IR_SIRC_TOL_DIV) { |
||
| 84 | /* write a one */ |
||
| 85 | rawbits |= 1<<((i-2)>>1); |
||
| 86 | } else if (buf[i] > IR_SIRC_HIGH_ZERO - IR_SIRC_HIGH_ZERO/IR_SIRC_TOL_DIV && buf[i] < IR_SIRC_HIGH_ZERO + IR_SIRC_HIGH_ZERO/IR_SIRC_TOL_DIV) { |
||
| 87 | /* do nothing, a zero is already in rawbits */ |
||
| 88 | } else { |
||
| 89 | return IR_NOT_CORRECT_DATA; |
||
| 90 | } |
||
| 91 | } |
||
| 92 | } |
||
| 93 | |||
| 94 | proto->protocol = IR_PROTO_SIRC; |
||
| 95 | proto->timeout = IR_SIRC_REPETITION; |
||
| 96 | proto->data = rawbits; //TODO: Should some other mapping be used? |
||
| 97 | |||
| 98 | return IR_OK; |
||
| 99 | } |
||
| 100 | |||
| 101 | int8_t expandSIRC(uint16_t *buf, uint8_t len, const Ir_Protocol_Data_t *proto) { |
||
| 102 | //TODO: Implement this function. |
||
| 103 | return IR_NOT_CORRECT_DATA; |
||
| 104 | } |
||
| 105 | #endif |
||
| 106 | |||
| 107 | #if (IR_PROTOCOLS_USE_RC5) |
||
| 108 | /** |
||
| 109 | * Test data on RC5 protocol |
||
| 110 | * http://www.sbprojects.com/knowledge/ir/rc5.htm |
||
| 111 | * |
||
| 112 | * @param address |
||
| 113 | * Pointer to store the address of the received data |
||
| 114 | * @param command |
||
| 115 | * Pointer to store the command of the received data |
||
| 116 | * @return |
||
| 117 | * IR_OK if data parsed successfully, one of several errormessages if not |
||
| 118 | */ |
||
| 119 | int8_t parseRC5(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) { |
||
| 120 | uint8_t halfbitscnt = 1; |
||
| 121 | uint16_t rawbits = 0; |
||
| 122 | |||
| 123 | for (uint8_t i = 0; i<len; i++) { |
||
| 124 | //halfbitscnt&1==1 in the middle of bits |
||
| 125 | //i&1==0 positive flank |
||
| 126 | |||
| 127 | if ((halfbitscnt&1)==1 && (i&1)==0) { /* in the middle of bit AND a positve flank */ |
||
| 128 | rawbits |= (1<<(13-(halfbitscnt>>1))); |
||
| 129 | } |
||
| 130 | |||
| 131 | if (buf[i] > IR_RC5_HALF_BIT - IR_RC5_HALF_BIT/IR_RC5_TOL_DIV && buf[i] < IR_RC5_HALF_BIT + IR_RC5_HALF_BIT/IR_RC5_TOL_DIV) { |
||
| 132 | halfbitscnt += 1; |
||
| 133 | } else if (buf[i] > IR_RC5_BIT - IR_RC5_BIT/IR_RC5_TOL_DIV && buf[i] < IR_RC5_BIT + IR_RC5_BIT/IR_RC5_TOL_DIV) { |
||
| 134 | halfbitscnt += 2; |
||
| 135 | } else { |
||
| 136 | return IR_NOT_CORRECT_DATA; |
||
| 137 | } |
||
| 138 | |||
| 139 | } |
||
| 140 | |||
| 141 | //TODO: Fix this parser to use the proto struct instead. |
||
| 142 | *command = ((uint8_t)rawbits&0x3f); |
||
| 143 | *address = ((uint8_t)(rawbits>>6)&0x7f); |
||
| 144 | |||
| 145 | //support RC5-extended by putting the inversion of startbit 2 as the 7th commandbit |
||
| 146 | *command |= (~(*address) & 0x40); |
||
| 147 | *address &= 0x1f; //remove togglebit and both startbits from address |
||
| 148 | |||
| 149 | return IR_OK; |
||
| 150 | } |
||
| 151 | |||
| 152 | int8_t expandRC5(uint16_t *buf, uint8_t len, const Ir_Protocol_Data_t *proto) { |
||
| 153 | //TODO: Implement this function. |
||
| 154 | return IR_NOT_CORRECT_DATA; |
||
| 155 | } |
||
| 156 | #endif |
||
| 157 | |||
| 158 | #if (IR_PROTOCOLS_USE_SHARP) |
||
| 159 | /** |
||
| 160 | * Test data on SHARP protocol |
||
| 161 | * http://www.sbprojects.com/knowledge/ir/sharp.htm |
||
| 162 | * |
||
| 163 | * @param address |
||
| 164 | * Pointer to store the address of the received data |
||
| 165 | * @param command |
||
| 166 | * Pointer to store the command of the received data |
||
| 167 | * @return |
||
| 168 | * IR_OK if data parsed successfully, one of several errormessages if not |
||
| 169 | */ |
||
| 170 | int8_t parseSharp(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) { |
||
| 171 | /* parse buf[], max is len */ |
||
| 172 | |||
| 173 | /* check if we have correct amount of data */ |
||
| 174 | if (len != 31) { |
||
| 175 | return IR_NOT_CORRECT_DATA; |
||
| 176 | } |
||
| 177 | |||
| 178 | uint16_t rawbits=0; |
||
| 179 | |||
| 180 | for (uint8_t i = 1; i < len; i++) { |
||
| 181 | if ((i&1) == 1) { /* if odd, ir-pause */ |
||
| 182 | /* check length of pause between bits */ |
||
| 183 | if (buf[i] > IR_SHARP_LOW_ONE - IR_SHARP_LOW_ONE/IR_SHARP_TOL_DIV && buf[i] < IR_SHARP_LOW_ONE + IR_SHARP_LOW_ONE/IR_SHARP_TOL_DIV) { |
||
| 184 | /* write a one */ |
||
| 185 | rawbits |= 1<<((i-1)>>1); |
||
| 186 | } else if (buf[i] > IR_SHARP_LOW_ZERO - IR_SHARP_LOW_ZERO/IR_SHARP_TOL_DIV && buf[i] < IR_SHARP_LOW_ZERO + IR_SHARP_LOW_ZERO/IR_SHARP_TOL_DIV) { |
||
| 187 | /* do nothing, a zero is already in rawbits */ |
||
| 188 | } else { |
||
| 189 | return IR_NOT_CORRECT_DATA; |
||
| 190 | } |
||
| 191 | } else { /* if even, ir-bit */ |
||
| 192 | if (buf[i] > IR_SHARP_HIGH + IR_SHARP_HIGH/IR_SHARP_TOL_DIV || buf[i] < IR_SHARP_HIGH - IR_SHARP_HIGH/IR_SHARP_TOL_DIV) { |
||
| 193 | return IR_NOT_CORRECT_DATA; |
||
| 194 | } |
||
| 195 | } |
||
| 196 | } |
||
| 197 | |||
| 198 | //TODO: Fix this parser to use the proto struct instead. |
||
| 199 | *command = ((uint8_t)(rawbits>>5)&0xff); |
||
| 200 | *address = ((uint8_t)rawbits&0x1f); |
||
| 201 | |||
| 202 | return IR_OK; |
||
| 203 | } |
||
| 204 | |||
| 205 | int8_t expandSharp(uint16_t *buf, uint8_t len, const Ir_Protocol_Data_t *proto) { |
||
| 206 | //TODO: Implement this function. |
||
| 207 | return IR_NOT_CORRECT_DATA; |
||
| 208 | } |
||
| 209 | #endif |
||
| 210 | |||
| 211 | #if (IR_PROTOCOLS_USE_NEC) |
||
| 212 | /** |
||
| 213 | * Test data on NEC protocol |
||
| 214 | * http://www.sbprojects.com/knowledge/ir/nec.htm |
||
| 215 | * |
||
| 216 | * @param address |
||
| 217 | * Pointer to store the address of the received data |
||
| 218 | * @param command |
||
| 219 | * Pointer to store the command of the received data |
||
| 220 | * @return |
||
| 221 | * IR_OK if data parsed successfully, one of several errormessages if not |
||
| 222 | */ |
||
| 223 | int8_t parseNEC(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) { |
||
| 224 | /* parse buf[], max is len */ |
||
| 225 | |||
| 226 | /* check if we have correct amount of data */ |
||
| 227 | if (len != 67) { |
||
| 228 | return IR_NOT_CORRECT_DATA; |
||
| 229 | } |
||
| 230 | |||
| 231 | /* check startbit */ |
||
| 232 | if (buf[0] > IR_NEC_ST_BIT + IR_NEC_ST_BIT/IR_NEC_TOL_DIV || buf[0] < IR_NEC_ST_BIT - IR_NEC_ST_BIT/IR_NEC_TOL_DIV) { |
||
| 233 | return IR_NOT_CORRECT_DATA; |
||
| 234 | } |
||
| 235 | |||
| 236 | /* check pause after startbit */ |
||
| 237 | if (buf[1] > IR_NEC_ST_PAUSE + IR_NEC_ST_PAUSE/IR_NEC_TOL_DIV || buf[1] < IR_NEC_ST_PAUSE - IR_NEC_ST_PAUSE/IR_NEC_TOL_DIV) { |
||
| 238 | return IR_NOT_CORRECT_DATA; |
||
| 239 | } |
||
| 240 | |||
| 241 | //TODO: Fix this parser to use the proto struct instead. Do not write to the struct unless IR_OK is returned, use temp variables. |
||
| 242 | *command = 0; |
||
| 243 | *address = 0; |
||
| 244 | |||
| 245 | for (uint8_t i = 3; i < len; i++) { |
||
| 246 | if ((i&1) == 1) { /* if odd, ir-pause */ |
||
| 247 | /* check length of pause between bits */ |
||
| 248 | if (buf[i] > IR_NEC_LOW_ONE - IR_NEC_LOW_ONE/IR_NEC_TOL_DIV && buf[i] < IR_NEC_LOW_ONE + IR_NEC_LOW_ONE/IR_NEC_TOL_DIV) { |
||
| 249 | if (i>2 && i<18) { |
||
| 250 | /* write a one */ |
||
| 251 | *address |= 1<<((i-3)>>1); |
||
| 252 | } |
||
| 253 | if (i>34 && i<50) { |
||
| 254 | /* write a one */ |
||
| 255 | *command |= 1<<((i-35)>>1); |
||
| 256 | } |
||
| 257 | } else if (buf[i] > IR_NEC_LOW_ZERO - IR_NEC_LOW_ZERO/IR_NEC_TOL_DIV && buf[i] < IR_NEC_LOW_ZERO + IR_NEC_LOW_ZERO/IR_NEC_TOL_DIV) { |
||
| 258 | /* do nothing, a zero is already in rawbits */ |
||
| 259 | } else { |
||
| 260 | return IR_NOT_CORRECT_DATA; |
||
| 261 | } |
||
| 262 | } else { /* if even, ir-bit */ |
||
| 263 | if (buf[i] > IR_NEC_HIGH + IR_NEC_HIGH/IR_NEC_TOL_DIV || buf[i] < IR_NEC_HIGH - IR_NEC_HIGH/IR_NEC_TOL_DIV) { |
||
| 264 | return IR_NOT_CORRECT_DATA; |
||
| 265 | } |
||
| 266 | } |
||
| 267 | } |
||
| 268 | |||
| 269 | return IR_OK; |
||
| 270 | } |
||
| 271 | |||
| 272 | int8_t expandNEC(uint16_t *buf, uint8_t len, const Ir_Protocol_Data_t *proto) { |
||
| 273 | //TODO: Implement this function. |
||
| 274 | return IR_NOT_CORRECT_DATA; |
||
| 275 | } |
||
| 276 | #endif |
||
| 277 | |||
| 278 | #if (IR_PROTOCOLS_USE_SAMSUNG) |
||
| 279 | /** |
||
| 280 | * Test data on Samsung protocol |
||
| 281 | * Very much like NEC, different start bit/pause lengths etc. |
||
| 282 | * http://www.sbprojects.com/knowledge/ir/nec.htm |
||
| 283 | * |
||
| 284 | * @param address |
||
| 285 | * Pointer to store the address of the received data |
||
| 286 | * @param command |
||
| 287 | * Pointer to store the command of the received data |
||
| 288 | * @return |
||
| 289 | * IR_OK if data parsed successfully, one of several errormessages if not |
||
| 290 | */ |
||
| 291 | int8_t parseSamsung(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) { |
||
| 292 | /* parse buf[], max is len */ |
||
| 293 | |||
| 294 | /* check if we have correct amount of data */ |
||
| 295 | if (len != 67) { |
||
| 296 | return IR_NOT_CORRECT_DATA; |
||
| 297 | } |
||
| 298 | |||
| 299 | /* check startbit */ |
||
| 300 | if (buf[0] > IR_SAMS_ST_BIT + IR_SAMS_ST_BIT/IR_SAMS_TOL_DIV || buf[0] < IR_SAMS_ST_BIT - IR_SAMS_ST_BIT/IR_SAMS_TOL_DIV) { |
||
| 301 | return IR_NOT_CORRECT_DATA; |
||
| 302 | } |
||
| 303 | |||
| 304 | /* check pause after startbit */ |
||
| 305 | if (buf[1] > IR_SAMS_ST_PAUSE + IR_SAMS_ST_PAUSE/IR_SAMS_TOL_DIV || buf[1] < IR_SAMS_ST_PAUSE - IR_SAMS_ST_PAUSE/IR_SAMS_TOL_DIV) { |
||
| 306 | return IR_NOT_CORRECT_DATA; |
||
| 307 | } |
||
| 308 | |||
| 309 | //TODO: Fix this parser to use the proto struct instead. Do not write to the struct unless IR_OK is returned, use temp variables. |
||
| 310 | *command = 0; |
||
| 311 | *address = 0; |
||
| 312 | |||
| 313 | for (uint8_t i = 3; i < len; i++) { |
||
| 314 | if ((i&1) == 1) { /* if odd, ir-pause */ |
||
| 315 | /* check length of pause between bits */ |
||
| 316 | if (buf[i] > IR_SAMS_LOW_ONE - IR_SAMS_LOW_ONE/IR_SAMS_TOL_DIV && buf[i] < IR_SAMS_LOW_ONE + IR_SAMS_LOW_ONE/IR_SAMS_TOL_DIV) { |
||
| 317 | if (i>2 && i<18) { |
||
| 318 | /* write a one */ |
||
| 319 | *address |= 1<<((i-3)>>1); |
||
| 320 | } |
||
| 321 | if (i>34 && i<50) { |
||
| 322 | /* write a one */ |
||
| 323 | *command |= 1<<((i-35)>>1); |
||
| 324 | } |
||
| 325 | } else if (buf[i] > IR_SAMS_LOW_ZERO - IR_SAMS_LOW_ZERO/IR_SAMS_TOL_DIV && buf[i] < IR_SAMS_LOW_ZERO + IR_SAMS_LOW_ZERO/IR_SAMS_TOL_DIV) { |
||
| 326 | /* do nothing, a zero is already in rawbits */ |
||
| 327 | } else { |
||
| 328 | return IR_NOT_CORRECT_DATA; |
||
| 329 | } |
||
| 330 | } else { /* if even, ir-bit */ |
||
| 331 | if (buf[i] > IR_SAMS_HIGH + IR_SAMS_HIGH/IR_SAMS_TOL_DIV || buf[i] < IR_SAMS_HIGH - IR_SAMS_HIGH/IR_SAMS_TOL_DIV) { |
||
| 332 | return IR_NOT_CORRECT_DATA; |
||
| 333 | } |
||
| 334 | } |
||
| 335 | } |
||
| 336 | |||
| 337 | return IR_OK; |
||
| 338 | } |
||
| 339 | |||
| 340 | int8_t expandSamsung(uint16_t *buf, uint8_t len, const Ir_Protocol_Data_t *proto) { |
||
| 341 | //TODO: Implement this function. |
||
| 342 | return IR_NOT_CORRECT_DATA; |
||
| 343 | } |
||
| 344 | #endif |
||
| 345 |