Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
FtControlSetReceiver.cpp
00001 #include "FtControlSetReceiver.h" 00002 00003 #include "us_ticker_api.h" 00004 00005 /// message timeout depends on selected sender frequency 00006 const uint32_t FtControlSetReceiver::c_messageTimeout[2] = {89000+20*c_maxPulseTime,118000+20*c_maxPulseTime}; 00007 /// di-bit discrimination times 00008 const uint32_t FtControlSetReceiver::c_pulseWidthLimits[5] = {740,860,940,1055,1150}; 00009 00010 FtControlSetReceiver::FtControlSetReceiver(PinName in): 00011 m_pulseIRQ(in), 00012 m_rxBuffer(0), 00013 m_nPulses(0), 00014 m_timeOfLastEdge(0), 00015 m_nOnes(0), 00016 m_errorCount(0), 00017 m_nGracefullyIgnoredErrors(0), 00018 m_lastMessage(0) 00019 { 00020 m_pulseIRQ.mode(PullNone); // the CHQ0038 does't like the default pull down 00021 m_pulseIRQ.fall(this, &FtControlSetReceiver::pulseISR); // we are measuring the distances of falling edges 00022 00023 // attch the callbacks 00024 m_messageTimeout.attach(this,&FtControlSetReceiver::messageTimeoutISR); 00025 m_receiveTimeout.attach(this,&FtControlSetReceiver::handleReceiveError); 00026 m_recoverTimeout.attach(this,&FtControlSetReceiver::recoverISR); 00027 } 00028 00029 /// called on each falling edge on the IR receivers signal line 00030 void FtControlSetReceiver::pulseISR() 00031 { 00032 // takes 1µs-5µs, 4.1µs on average 00033 if(m_nPulses) { 00034 // received a messge pulse 00035 uint32_t now = us_ticker_read(); 00036 m_receiveTimeout.remove(); 00037 uint32_t width = now - m_timeOfLastEdge; 00038 m_timeOfLastEdge = now; 00039 if(width>=c_pulseWidthLimits[0] && width<c_pulseWidthLimits[4]) { 00040 if(width<c_pulseWidthLimits[1]){ 00041 // m_rxBuffer|=0x0; 00042 }else if(width<c_pulseWidthLimits[2]) { 00043 m_rxBuffer|=0x1; 00044 ++m_nOnes; 00045 } else if(width<c_pulseWidthLimits[3]) { 00046 m_rxBuffer|=0x2; 00047 ++m_nOnes; 00048 } else { 00049 m_rxBuffer|=0x3; 00050 } 00051 m_rxBuffer<<=2; 00052 if(++m_nPulses<=15) { 00053 // still receiving re-attach the pulse timeout 00054 m_receiveTimeout.insert(m_timeOfLastEdge+c_maxPulseTime); 00055 } else { 00056 // we have got a full message 00057 FtControlSetMessage::Status status; 00058 if(m_nOnes&1) { // message ones + parity one has to be even 00059 status = FtControlSetMessage::ParityKO; 00060 } else if(m_rxBuffer>>28!=8 || m_rxBuffer&4) { // check header=8 and tail=0 00061 status = FtControlSetMessage::FrameKO; 00062 } else { // happyhappyjoyjoy 00063 status = FtControlSetMessage::OK; 00064 } 00065 // detach and reattach the message timeout 00066 m_messageTimeout.remove(); 00067 m_messageTimeout.insert(m_timeOfLastEdge+c_messageTimeout[1]);//just take the longer timeout here, otherwise we run into problems 00068 if(status == FtControlSetMessage::OK) { 00069 m_nGracefullyIgnoredErrors = 0; 00070 m_lastMessage = m_rxBuffer; 00071 } else { 00072 if(++m_nGracefullyIgnoredErrors <= c_errorsToBeGracefullyIgnored) { 00073 m_lastMessage &= ~0x3; // just indicate the error but keep the old message 00074 m_lastMessage |= status; 00075 } else { 00076 m_lastMessage = status; // reset the message and indicate the error 00077 } 00078 ++m_errorCount; 00079 } 00080 m_callback.call(); 00081 m_rxBuffer=0; 00082 m_nPulses=0; 00083 m_nOnes=0; 00084 } 00085 } else { 00086 handleReceiveError(); 00087 } 00088 } else { 00089 // the very first edge of a potential message, just memorize time stamp 00090 m_timeOfLastEdge = us_ticker_read(); 00091 m_receiveTimeout.insert(m_timeOfLastEdge+c_maxPulseTime); 00092 ++m_nPulses; 00093 } 00094 } 00095 00096 void FtControlSetReceiver::messageTimeoutISR() 00097 { 00098 m_lastMessage = 0; 00099 m_callback.call(); 00100 } 00101 00102 // called on errors detected in pulseISR or on pulse timeouts 00103 void FtControlSetReceiver::handleReceiveError() 00104 { 00105 // receive errors are not reported via the status bits and the message is not reset here, 00106 // because it might have been just a disturbance between two messages. 00107 // On severe transmission problems the message timeout will bail us out 00108 ++m_errorCount; 00109 //m_errorCount+=10000; 00110 m_rxBuffer=0; 00111 m_nPulses=0; 00112 m_nOnes=0; 00113 // to be graceful in case of high frequency noise disconnect the ISR for some time 00114 m_pulseIRQ.fall(0); 00115 m_recoverTimeout.insert(us_ticker_read()+c_recoverTimeout); 00116 } 00117 00118 void FtControlSetReceiver::recoverISR() 00119 { 00120 // reattach the pulse handler 00121 m_pulseIRQ.fall(this, &FtControlSetReceiver::pulseISR); 00122 }
Generated on Fri Jul 15 2022 03:15:46 by
1.7.2