Initial commit
This commit is contained in:
223
src/opst.cpp
Normal file
223
src/opst.cpp
Normal file
@@ -0,0 +1,223 @@
|
||||
/**
|
||||
* @file opst.cpp
|
||||
*
|
||||
* @author Pascal Lais (pascal_lais@gmx.de)
|
||||
*
|
||||
* @version 0.1
|
||||
* @date 2020-08-02
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Includes
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#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++;
|
||||
|
||||
if(mOpstFiFo.mOut == mOpstFiFo.mIn)
|
||||
{
|
||||
mOpstFiFo.mOverrun = true;
|
||||
}
|
||||
if(OPST_FIFO_SIZE <= mOpstFiFo.mIn)
|
||||
{
|
||||
mOpstFiFo.mIn = 0;
|
||||
}
|
||||
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
|
||||
|
||||
if(OPST_FIFO_SIZE > (mOpstFiFo.mOut + 1))
|
||||
{
|
||||
nextOut = mOpstFiFo.mOut + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextOut = 0;
|
||||
}
|
||||
|
||||
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
|
||||
//-----------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user