/** * @file opst.cpp * * @author Pascal Lais (pascal_lais@gmx.de) * * @version 0.1 * @date 2020-08-02 */ //----------------------------------------------------------------------------- // Includes //----------------------------------------------------------------------------- #include #include "opst.h" //----------------------------------------------------------------------------- // Defines //----------------------------------------------------------------------------- #define OPST_FIFO_SIZE 32 //----------------------------------------------------------------------------- // Datatypes //----------------------------------------------------------------------------- typedef struct tagPwmInPulse { uint32_t mRising; uint32_t mFalling; }tPwmInPulse; typedef struct tagOpstInFiFo { uint32_t mIn; uint32_t mOut; tPwmInPulse mData[OPST_FIFO_SIZE]; bool mOverrun; }tOpstFiFo; //----------------------------------------------------------------------------- // Variables //----------------------------------------------------------------------------- static uint8_t mOpstPin; static volatile tOpstFiFo mOpstFiFo; static uint32_t mOpstState = OPST_STATE_NONE; static int32_t mOpstTemp = 0; static int32_t mOpstPressure = 0; //----------------------------------------------------------------------------- // Function prototypes //----------------------------------------------------------------------------- /** * Interrupt service routine to handle a rising edge on pwm input * */ void pwmInRisingEdgeISR(); /** * Interrupt service routine to handle a falling edge on pwm input * */ void pwmInFallingEdgeISR(); //----------------------------------------------------------------------------- // Function implementation //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void pwmInRisingEdgeISR() //----------------------------------------------------------------------------- { mOpstFiFo.mData[mOpstFiFo.mIn].mRising = micros(); mOpstFiFo.mData[mOpstFiFo.mIn].mFalling = 0; attachInterrupt(digitalPinToInterrupt(mOpstPin), pwmInFallingEdgeISR, FALLING); } //----------------------------------------------------------------------------- void pwmInFallingEdgeISR() //----------------------------------------------------------------------------- { mOpstFiFo.mData[mOpstFiFo.mIn].mFalling = micros(); mOpstFiFo.mIn++; mOpstFiFo.mIn %= OPST_FIFO_SIZE; if(mOpstFiFo.mOut == mOpstFiFo.mIn) { mOpstFiFo.mOverrun = true; } attachInterrupt(digitalPinToInterrupt(mOpstPin), pwmInRisingEdgeISR, RISING); } //----------------------------------------------------------------------------- void opstInit(uint8_t pin) //----------------------------------------------------------------------------- { mOpstFiFo.mIn = 0; mOpstFiFo.mOut = 0; mOpstPin = pin; pinMode(pin, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(mOpstPin), pwmInRisingEdgeISR, RISING); } //----------------------------------------------------------------------------- void opstUpdate() //----------------------------------------------------------------------------- { if(mOpstFiFo.mIn != mOpstFiFo.mOut) { uint32_t behind; // the number reported values that have not been processed uint32_t in = mOpstFiFo.mIn; // We need to store the in counter in case interrupts occur during update and it gets changed inside the struct if(in > mOpstFiFo.mOut) { behind = in - mOpstFiFo.mOut; } else { behind = (OPST_FIFO_SIZE - mOpstFiFo.mOut) + in; } while(behind > 1) // cannot process last pulse because we need the time between current and next rising edge { uint32_t nextOut; // index of following fifo entry uint32_t pulseInterval = 0; // time between rising edge of current pulse and rising edge of following pulse uint32_t pulseLen = 0; // time between rising edge of current pulse and falling edge of current pulse nextOut = mOpstFiFo.mOut + 1; nextOut %= OPST_FIFO_SIZE; pulseInterval = mOpstFiFo.mData[nextOut].mRising - mOpstFiFo.mData[mOpstFiFo.mOut].mRising; pulseLen = mOpstFiFo.mData[mOpstFiFo.mOut].mFalling - mOpstFiFo.mData[mOpstFiFo.mOut].mRising; if(((1024 - 103) < pulseInterval) && ((1024 + 103) > pulseInterval)) // +-10% Tolerance { // S1 pulseLen = pulseLen * 1024 / pulseInterval; // pulse length is relative to interval length if(((256 - 25) < pulseLen) && ((256 + 25) > pulseLen)) { mOpstState = OPST_STATE_REPORT_TEMP; } else if(((384 - 25) < pulseLen) && ((384 + 25) > pulseLen)) { mOpstState = OPST_STATE_TEMP_FAULT; } else if(((512 - 25) < pulseLen) && ((512 + 25) > pulseLen)) { mOpstState = OPST_STATE_PRESSURE_FAULT; } else if(((640 - 25) < pulseLen) && ((640 + 25) > pulseLen)) { mOpstState = OPST_STATE_HARDWARE_FAULT; } } else if(((4096 - 410) < pulseInterval) && ((4096 + 410) > pulseInterval)) // +-10% Tolerance { if(OPST_STATE_REPORT_TEMP == mOpstState) { // T1 pulseLen = pulseLen * 4096 / pulseInterval; // pulse length is relative to interval length mOpstTemp = (((pulseLen) - 128) * 10 / 19.2) - 400; mOpstState = OPST_STATE_REPORT_PRESSURE; //Next pulse is pressure } else if(OPST_STATE_REPORT_PRESSURE == mOpstState) { // T2 pulseLen = pulseLen * 4096 / pulseInterval; //pulse length is relative to interval length mOpstPressure = ((pulseLen - 128) * 1000 / 384) + 500; mOpstState = OPST_STATE_NONE; } } mOpstFiFo.mOut = nextOut; behind--; } } } //----------------------------------------------------------------------------- uint32_t opstGetState() //----------------------------------------------------------------------------- { return mOpstState; } //----------------------------------------------------------------------------- int32_t opstGetTemp() //----------------------------------------------------------------------------- { return mOpstTemp; } //----------------------------------------------------------------------------- int32_t opstGetPressure() //----------------------------------------------------------------------------- { return mOpstPressure; } //----------------------------------------------------------------------------- bool opstFiFoOverrunDetected() //----------------------------------------------------------------------------- { return mOpstFiFo.mOverrun; } //----------------------------------------------------------------------------- // EOF //-----------------------------------------------------------------------------