You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
3.8 KiB
151 lines
3.8 KiB
#pragma once
|
|
|
|
#include "Arduino.h"
|
|
#include "ITimerChannel.h"
|
|
|
|
namespace TeensyTimerTool
|
|
{
|
|
class PIT_t;
|
|
|
|
class PITChannel : public ITimerChannel
|
|
{
|
|
public:
|
|
inline PITChannel(unsigned nr);
|
|
inline virtual ~PITChannel();
|
|
|
|
inline errorCode begin(callback_t cb, float tcnt, bool periodic) override;
|
|
//inline errorCode begin(callback_t cb, uint32_t tcnt, bool periodic) override;
|
|
inline errorCode start() override;
|
|
inline errorCode stop() override;
|
|
|
|
//inline errorCode trigger(uint32_t) override;
|
|
inline errorCode trigger(float) override;
|
|
inline errorCode setNextPeriod(float us) override;
|
|
inline errorCode setPeriod(float us) override;
|
|
|
|
inline float getMaxPeriod() const override;
|
|
|
|
bool isPeriodic;
|
|
|
|
protected:
|
|
//IMXRT_GPT_t* regs;
|
|
//uint32_t reload;
|
|
|
|
inline void isr();
|
|
|
|
PITChannel() = delete;
|
|
PITChannel(const PITChannel &) = delete;
|
|
|
|
const unsigned chNr;
|
|
callback_t callback = nullptr;
|
|
|
|
static uint32_t clockFactor;
|
|
|
|
friend PIT_t;
|
|
};
|
|
|
|
// IMPLEMENTATION ==============================================
|
|
|
|
PITChannel::PITChannel(unsigned nr)
|
|
: ITimerChannel(nullptr), chNr(nr)
|
|
{
|
|
callback = nullptr;
|
|
clockFactor = (CCM_CSCMR1 & CCM_CSCMR1_PERCLK_CLK_SEL) ? 24 : (F_BUS_ACTUAL / 1000000);
|
|
}
|
|
|
|
errorCode PITChannel::begin(callback_t cb, float micros, bool periodic)
|
|
{
|
|
isPeriodic = periodic;
|
|
callback = cb;
|
|
|
|
if (isPeriodic)
|
|
{
|
|
IMXRT_PIT_CHANNELS[chNr].TCTRL = 0;
|
|
IMXRT_PIT_CHANNELS[chNr].TFLG = 1;
|
|
|
|
setNextPeriod(micros);
|
|
// float tmp = micros * clockFactor;
|
|
// if (tmp > 0xFFFF'FFFF)
|
|
// {
|
|
// postError(errorCode::periodOverflow);
|
|
// IMXRT_PIT_CHANNELS[chNr].LDVAL = 0xFFFF'FFFE;
|
|
// } else
|
|
// {
|
|
// IMXRT_PIT_CHANNELS[chNr].LDVAL = (uint32_t)tmp - 1;
|
|
// }
|
|
}
|
|
return errorCode::OK;
|
|
}
|
|
|
|
errorCode PITChannel::start()
|
|
{
|
|
IMXRT_PIT_CHANNELS[chNr].TCTRL = PIT_TCTRL_TEN | PIT_TCTRL_TIE;
|
|
return errorCode::OK;
|
|
}
|
|
|
|
errorCode PITChannel::stop()
|
|
{
|
|
IMXRT_PIT_CHANNELS[chNr].TCTRL = 0;
|
|
return errorCode::OK;
|
|
}
|
|
|
|
errorCode PITChannel::setNextPeriod(float us)
|
|
{
|
|
float cts = us * clockFactor;
|
|
if (cts > 0xFFFF'FFFF)
|
|
{
|
|
postError(errorCode::periodOverflow);
|
|
IMXRT_PIT_CHANNELS[chNr].LDVAL = 0xFFFF'FFFE;
|
|
} else
|
|
{
|
|
IMXRT_PIT_CHANNELS[chNr].LDVAL = (uint32_t)cts - 1;
|
|
}
|
|
return errorCode::OK;
|
|
}
|
|
|
|
errorCode PITChannel::setPeriod(float us)
|
|
{
|
|
stop(); // need to stop/start timer to change current period (see ch 53.9.5.4)
|
|
setNextPeriod(us);
|
|
start();
|
|
return errorCode::OK;
|
|
}
|
|
|
|
void PITChannel::isr()
|
|
{
|
|
if (callback != nullptr)
|
|
{
|
|
callback();
|
|
if (!isPeriodic) IMXRT_PIT_CHANNELS[chNr].TCTRL = 0; // switch off timer
|
|
}
|
|
}
|
|
|
|
PITChannel::~PITChannel()
|
|
{
|
|
callback = nullptr;
|
|
}
|
|
|
|
errorCode PITChannel::trigger(float delay) //should be optimized somehow
|
|
{
|
|
IMXRT_PIT_CHANNELS[chNr].TCTRL = 0;
|
|
IMXRT_PIT_CHANNELS[chNr].TFLG = 1;
|
|
|
|
float tmp = delay * clockFactor;
|
|
if (tmp > 0xFFFF'FFFF)
|
|
{
|
|
postError(errorCode::periodOverflow);
|
|
IMXRT_PIT_CHANNELS[chNr].LDVAL = 0xFFFF'FFFE;
|
|
} else
|
|
IMXRT_PIT_CHANNELS[chNr].LDVAL = (uint32_t)tmp - 1;
|
|
|
|
start();
|
|
|
|
return errorCode::OK;
|
|
}
|
|
|
|
float PITChannel::getMaxPeriod() const
|
|
{
|
|
return (float)0xFFFF'FFFE / clockFactor / 1'000'000;
|
|
}
|
|
|
|
} // namespace TeensyTimerTool
|