X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=protocols%2Fnokia32protocol.cpp;fp=protocols%2Fnokia32protocol.cpp;h=63c36adf2bad9688d11fba5e07e67d02e683529a;hb=d724312c55dabe2c72175e88abf694880312fac4;hp=0000000000000000000000000000000000000000;hpb=fb8932101ae4f67f18ffa31073d51823cc872ac8;p=pierogi diff --git a/protocols/nokia32protocol.cpp b/protocols/nokia32protocol.cpp new file mode 100644 index 0000000..63c36ad --- /dev/null +++ b/protocols/nokia32protocol.cpp @@ -0,0 +1,251 @@ +#include "nokia32protocol.h" + +#include "pirrx51hardware.h" + +#include "pirexception.h" + +// Some global communications stuff: +#include +extern bool commandInFlight; +extern QMutex commandIFMutex; + +// The Nokia 32 protocol has a 2-bit space encoding system, and appears to +// work like this: +// A "zero" is encoded with a 164 usec pulse, 276 usec space. +// A "one" is encoded with a 164 usec pulse, 445 usec space. +// A "two" is encoded with a 164 usec pulse, 614 usec space. +// A "three" is encoded with a 164 usec pulse, 783 usec space. +// The header is a 412 usec pulse, 276 usec space. +// Commands end with a trailing 164 usec pulse. +// The entire pulse train is re-sent when repeating. +// There is a 100000 usec gap between commands. (? not sure here) +// The carrier frequency is presumably 36 kHz. +// The duty cycle is presumably 1/3. + +Nokia32Protocol::Nokia32Protocol( + QObject *guiObject, + unsigned int index) + : PIRProtocol(guiObject, index, 100000, false), + zeroPulse(164), + zeroSpace(276), + onePulse(164), + oneSpace(445), + twoPulse(164), + twoSpace(614), + threePulse(164), + threeSpace(783), + headerPulse(412), + headerSpace(276), + trailerPulse(164), + keypressCount(0) +{ +} + + +void Nokia32Protocol::startSendingCommand( + unsigned int threadableID, + PIRKeyName command) +{ + // Exceptions here are problematic; I'll try to weed them out by putting the + // whole thing in a try/catch block: + try + { + // First, check if we are meant to be the recipient of this command: + if (threadableID != id) return; + + clearRepeatFlag(); + + KeycodeCollection::const_iterator i = keycodes.find(command); + + // Do we even have this key defined? + if (i == keycodes.end()) + { + std::string s = "Tried to send a non-existent command.\n"; + throw PIRException(s); + } + + // construct the device: + PIRRX51Hardware rx51device(carrierFrequency, dutyCycle); + + int repeatCount = 0; + int commandDuration = 0; + while (repeatCount < MAX_REPEAT_COUNT) + { + commandDuration = generateStandardCommand((*i).second, rx51device); + + // Now, tell the device to send the whole command: + rx51device.sendCommandToDevice(); + + // sleep until the next repetition of command: + sleepUntilRepeat(commandDuration); + + // Check whether we've reached the minimum required number of repetitons: + if (repeatCount >= minimumRepetitions) + { + // Check whether we've been asked to stop: + if (checkRepeatFlag()) + { + QMutexLocker cifLocker(&commandIFMutex); + commandInFlight = false; + ++keypressCount; + return; + } + } + + ++repeatCount; + } + } + catch (PIRException e) + { + // inform the gui: + emit commandFailed(e.getError().c_str()); + } + + QMutexLocker cifLocker(&commandIFMutex); + commandInFlight = false; + ++keypressCount; +} + + +int Nokia32Protocol::generateStandardCommand( + const PIRKeyBits &pkb, + PIRRX51Hardware &rx51device) +{ + int duration = 0; + + // First, the "header" pulse: + rx51device.addPair(headerPulse, headerSpace); + duration += (headerPulse + headerSpace); + + // The layout of the Nokia 32 protocol is as follows: + // 1) an 8-bit "device code" + // 2) an 8-bit "sub-device code" + // 3) one toggle bit + // 4) seven more bits somehow associated with the device + // 5) an 8-bit command code. + // All are sent in MSB order. + + // It's a bit of a hack, but I'll store the first 16 bits of address in the + // preData, the next 7 bits of address in the postData, and the 8 bits + // of command in the firstCode: + + duration += pushBits(preData, rx51device); + duration += pushToggleAndBits(postData, rx51device); + duration += pushBits(pkb.firstCode, rx51device); + + // Finally add the "trail": + rx51device.addSingle(trailerPulse); + duration += trailerPulse; + + return duration; +} + + +int Nokia32Protocol::pushBits( + const CommandSequence &bits, + PIRRX51Hardware &rx51device) +{ + int duration = 0; + bool firstBit; + bool secondBit; + + CommandSequence::const_iterator i = bits.begin(); + while (i != bits.end()) + { + firstBit = *i; + ++i; + if (i == bits.end()) break; + secondBit = *i; + + duration += pushDoubleBit(firstBit, secondBit, rx51device); + + ++i; + } + + return duration; +} + + +int Nokia32Protocol::pushToggleAndBits( + const CommandSequence &bits, + PIRRX51Hardware &rx51device) +{ + int duration = 0; + bool firstBit; + bool secondBit; + + // The first bit is the toggle bit: + if (keypressCount % 2) + { + firstBit = 1; + } + else + { + firstBit = 0; + } + + CommandSequence::const_iterator i = bits.begin(); + if (i == bits.end()) return 0; + + secondBit = *i; + + duration += pushDoubleBit(firstBit, secondBit, rx51device); + + ++i; + + while (i != bits.end()) + { + firstBit = *i; + ++i; + if (i == bits.end()) break; + secondBit = *i; + + duration += pushDoubleBit(firstBit, secondBit, rx51device); + + ++i; + } + + return duration; +} + + +int Nokia32Protocol::pushDoubleBit( + bool firstBit, + bool secondBit, + PIRRX51Hardware &rx51device) +{ + int duration = 0; + + if (firstBit == 0) + { + if (secondBit == 0) + { + // Send the pulse for "Zero": + rx51device.addPair(zeroPulse, zeroSpace); + duration += (zeroPulse + zeroSpace); + } + else + { + // Send the pulse for "One": + rx51device.addPair(onePulse, oneSpace); + duration += (onePulse + oneSpace); + } + } + else + { + if (secondBit == 0) + { + // Send the pulse for "Two": + rx51device.addPair(twoPulse, twoSpace); + duration += (twoPulse + twoSpace); + } + else + { + // Send the pulse for "Three": + rx51device.addPair(threePulse, threeSpace); + duration += (threePulse + threeSpace); + } + } + + return duration; +}