1 /* 2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANALYZER_MANCHESTER_ENCODER_H 18 #define ANALYZER_MANCHESTER_ENCODER_H 19 20 #include <cstdint> 21 22 /** 23 * Encode bytes using Manchester Coding scheme. 24 * 25 * Manchester Code is self clocking. 26 * There is a transition in the middle of every bit. 27 * Zero is high then low. 28 * One is low then high. 29 * 30 * This avoids having long DC sections that would droop when 31 * passed though analog circuits with AC coupling. 32 * 33 * IEEE 802.3 compatible. 34 */ 35 36 class ManchesterEncoder { 37 public: ManchesterEncoder(int samplesPerPulse)38 ManchesterEncoder(int samplesPerPulse) 39 : mSamplesPerPulse(samplesPerPulse) 40 , mSamplesPerPulseHalf(samplesPerPulse / 2) 41 , mCursor(samplesPerPulse) { 42 } 43 44 virtual ~ManchesterEncoder() = default; 45 46 /** 47 * This will be called when the next byte is needed. 48 * @return 49 */ 50 virtual uint8_t onNextByte() = 0; 51 52 /** 53 * Generate the next floating point sample. 54 * @return 55 */ nextFloat()56 virtual float nextFloat() { 57 advanceSample(); 58 if (mCurrentBit) { 59 return (mCursor < mSamplesPerPulseHalf) ? -1.0f : 1.0f; // one 60 } else { 61 return (mCursor < mSamplesPerPulseHalf) ? 1.0f : -1.0f; // zero 62 } 63 } 64 65 protected: 66 /** 67 * This will be called when a new bit is ready to be encoded. 68 * It can be used to prepare the encoded samples. 69 * @param current 70 */ onNextBit(bool)71 virtual void onNextBit(bool /* current */) {}; 72 advanceSample()73 void advanceSample() { 74 // Are we ready for a new bit? 75 if (++mCursor >= mSamplesPerPulse) { 76 mCursor = 0; 77 if (mBitsLeft == 0) { 78 mCurrentByte = onNextByte(); 79 mBitsLeft = 8; 80 } 81 --mBitsLeft; 82 mCurrentBit = (mCurrentByte >> mBitsLeft) & 1; 83 onNextBit(mCurrentBit); 84 } 85 } 86 getCurrentBit()87 bool getCurrentBit() { 88 return mCurrentBit; 89 } 90 91 const int mSamplesPerPulse; 92 const int mSamplesPerPulseHalf; 93 int mCursor; 94 int mBitsLeft = 0; 95 uint8_t mCurrentByte = 0; 96 bool mCurrentBit = false; 97 }; 98 #endif //ANALYZER_MANCHESTER_ENCODER_H 99