#include "W433DataReciver.h" #include "writepin.h" #include #include #include #include #include "serial.h" W433DataReciver* W433DataReciver::instance = nullptr; W433DataReciver::W433DataReciver(volatile unsigned char* const port , const unsigned char pin, volatile uint16_t * timerRegister, volatile uint8_t* const timerOverflowRegister, void (* const packetCallback)(uint32_t, void*), void* const userData ): _port(port), _pin(pin), _timerRegister(timerRegister), _timerOverflowRegister(timerOverflowRegister), _packetCallback(packetCallback), _userData(userData) { instance = this; for(uint8_t i = 0; i < 33; i++) timesBuffer[i] = 0; } W433DataReciver::~W433DataReciver() { instance = nullptr; } void W433DataReciver::staticInterrupt() { if(instance != nullptr) instance->interrupt(); } int8_t W433DataReciver::reciveBit(uint8_t index) { if( timesBuffer[index] < 0 && isTime(timesBuffer[index+1], SMALL_TIME, true) && isTime(timesBuffer[index+2], LARGE_TIME, false) && isTime(timesBuffer[index+3], SMALL_TIME, true) ) { return 1; } else if( timesBuffer[index] < 0 && isTime(timesBuffer[index+1], LARGE_TIME, true) && isTime(timesBuffer[index+2], SMALL_TIME, false) && isTime(timesBuffer[index+3], SMALL_TIME, true) ) { return 0; } else return -1; } bool W433DataReciver::isTime(int16_t input, const uint16_t time, const bool state, const uint16_t tollerance) { if((state && input < 0) || (!state && input > 0)) return false; input = abs(input); return input < (int16_t)(time+tollerance) && input > (int16_t)(time-tollerance); } bool W433DataReciver::reciveSync(const uint16_t elapsedTime) { if(elapsedTime < SYNC_TIME+50 && elapsedTime > SYNC_TIME-50) { ++syncCount; } else syncCount = 0; if(syncCount > 10) return true; else return false; } bool W433DataReciver::recivedByte(const uint16_t elapsedTime) { timesBuffer[timesBufferIndex] = readPin(_port, _pin) ? 0-elapsedTime : elapsedTime; ++timesBufferIndex; return timesBufferIndex == 32; } uint8_t W433DataReciver::assmbleByte() { uint8_t byte = 0; for(uint8_t i = 0; i < 8; ++i) { int8_t bit = reciveBit(i*4); if(bit >= 0) byte = byte | (bit << (7-i)); else setState(LOOKING_FOR_SYNC); } timesBufferIndex = 0; return byte; } void W433DataReciver::setState(const uint8_t stateIn) { state = stateIn; timesBufferIndex = 0; packetIndex = 0; } void W433DataReciver::interrupt() { uint16_t elapsedTime = polarity*(((*_timerOverflowRegister & 0x01) ? *_timerRegister+(UINT16_MAX - previousTime) : *_timerRegister - previousTime)/TICKS_PER_US); if(elapsedTime < SMALL_TIME/4) return; previousTime = *_timerRegister; *_timerOverflowRegister = *_timerOverflowRegister | 0x01; if(state == LOOKING_FOR_SYNC && reciveSync(elapsedTime)) { setState(LOOKING_FOR_SYNC_END); } else if(state == LOOKING_FOR_SYNC_END) { if(elapsedTime > SYNC_TIME + 50) { if(elapsedTime < LARGE_TIME + 50) setState(LOOKING_FOR_SYNC); else { timesBuffer[0] = -LARGE_TIME; setState(LOOKING_FOR_SIGNATURE); ++timesBufferIndex; } } } else if(state == LOOKING_FOR_SIGNATURE) { if(recivedByte(elapsedTime)) { uint8_t recivedSignature = assmbleByte(); if( recivedSignature == signature) setState(RECVING_PACKET); else setState(LOOKING_FOR_SYNC); } } else if( state == RECVING_PACKET ) { if(recivedByte(elapsedTime)) { uint8_t packetByte = assmbleByte(); packet = packet | ((uint32_t)packetByte) << ((3-packetIndex)*8); ++packetIndex; if(packetIndex > 3) { packetIndex = 0; timesBufferIndex = 0; setState(RECVING_PACKET_CHECKSUM); } } } else if(state == RECVING_PACKET_CHECKSUM) { if(recivedByte(elapsedTime)) { uint8_t recivedChecksum = assmbleByte(); volatile uint8_t* buffer = reinterpret_cast(&packet); uint8_t computedChecksum = 0; for(uint8_t j = 0; j < sizeof(packet); j++) for(uint8_t i = 0; i < 8; i++) computedChecksum = computedChecksum + (buffer[j] & ( 1 << (8 - i))); if(computedChecksum == recivedChecksum) { _ringBuffer.write(const_cast(buffer), sizeof(packet)); if(_packetCallback != nullptr)(*_packetCallback)(packet, _userData); } packet = 0; setState(LOOKING_FOR_SYNC); } } } RingBuffer* W433DataReciver::getRingBuffer() { return &_ringBuffer; }