/* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ /* This is part of the LED light controller program. * It handles the IR NEC protocol decoding. * More information at http://www.sbprojects.com/knowledge/ir/nec.php */ #include /* Standard Integer Types */ #include /* Standard IO facilities */ #include /* General utilities */ #include /* Boolean */ #include "ir_nec.h" const uint16_t MARKS[2]={9000,560}; const uint16_t SPACES[4]={4500,2250,1680,560}; void time2nec(uint16_t* burst, uint8_t pulses) { uint8_t i,j; for (i=0; i((MARKS[j]+MARKS[j+1])/2)) { burst[i] = j; found = true; break; } } if (!found) { burst[i] = j; } } else { /* space */ /* fine the nearest NEC space time */ bool found = false; for (j=0; j<(sizeof(SPACES)/sizeof(uint16_t))-1; j++) { if (burst[i]>((SPACES[j]+SPACES[j+1])/2)) { burst[i] = j; found = true; break; } } if (!found) { burst[i] = j; } } } } struct nec nec2data(uint16_t* burst, uint8_t pulses) { struct nec to_return; to_return.valid = false; if (67==pulses) { /* normal burst */ to_return.repeat = false; if (0==burst[0] && 0==burst[1] && 1==burst[pulses-1]) { /* mark start, space start, trailing mark bit */ uint32_t data = 0; /* complete data */ to_return.valid = true; for (uint8_t i=2; i>24)&0xff; /* first byte is the address */ uint8_t naddress = (data>>16)&0xff; /* second byte is the inverted address */ uint8_t command = (data>>8)&0xff; /* third byte is the command */ uint8_t ncommand = (data>>0)&0xff; /* fourth byte is the inverted command */ if (0xff==(address^naddress)) { /* check if the data is not corrupted (the address comes also inverted) */ to_return.address = address; } else { to_return.valid = false; } if (0xff==(command^ncommand)) { /* check if the data is not corrupted (the command comes also inverted) */ to_return.command = command; } else { to_return.valid = false; } } } } else if (3==pulses) { /* repeat burst */ if (0==burst[0] && 1==burst[1] && 1==burst[2]) { /* mark start, space repeat, mark bit */ to_return.valid = true; to_return.repeat = true; } } return to_return; }