Akifumi Takahashi / AMPulseTrain

Dependents:   Interference_Simple

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PulseTrain.cpp Source File

PulseTrain.cpp

00001 #include "PulseTrain.h"
00002 
00003 PulseTrain::PulseTrain(
00004     uint32_t const arg_freq_init,
00005     float const arg_duty_init,
00006     uint32_t const arg_freq_max
00007 ):
00008     FREQ_MAX(arg_freq_max),
00009     m_freq(velidateRange<uint32_t>(arg_freq_init, 1, FREQ_MAX)),
00010     m_duty(velidateRange<float>(arg_duty_init, 0.0, 1.0))
00011 {
00012     m_period_us = 1000000 / m_freq + (1000000 % m_freq > m_freq / 2 ? 1 : 0);
00013     init();
00014     m_callback_asClock = doNothing;
00015     m_callback_asPulseEdge = doNothing;
00016 
00017 }
00018 
00019 void PulseTrain::attachCallback_asClock(Callback<void(bool)> arg_callback)
00020 {
00021     m_callback_asClock = arg_callback;
00022 }
00023 
00024 void PulseTrain::attachCallback_asPulseEdge (Callback<void(bool)> arg_callback)
00025 {
00026     m_callback_asPulseEdge = arg_callback;
00027 }
00028 
00029 void PulseTrain::setFrequency(uint32_t const arg_freq)
00030 {
00031     m_freq = velidateRange<uint32_t>(arg_freq, 1, FREQ_MAX);
00032     m_period_us = 1000000 / m_freq + (1000000 % m_freq > m_freq / 2 ? 1 : 0);
00033     init();
00034 }
00035 
00036 void PulseTrain::setDutycycle(float const arg_duty)
00037 {
00038     m_duty = velidateRange<float>(arg_duty, 0.0, 1.0);
00039     init();
00040 }
00041 
00042 template <typename T>
00043 T PulseTrain::velidateRange(T const arg_val, T const arg_min, T const arg_max)
00044 {
00045     if(arg_val < arg_min) return arg_min;
00046     else if (arg_val <=  arg_max) return arg_val;
00047     else return arg_max;
00048 }
00049 
00050 void PulseTrain::init()
00051 {
00052     int a, b, r;
00053     a = m_period_us;
00054     b = a * m_duty;
00055     r = a % b;
00056     while ( r != 0 ) {
00057         a = b;
00058         b = r;
00059         r = a % b;
00060     }
00061     m_clock_period_us = b;
00062     
00063      m_period_pcp = m_period_us / m_clock_period_us;
00064      m_falling = m_period_pcp * m_duty;
00065 }
00066 
00067 void PulseTrain::incrementClock()
00068 {
00069     static unsigned int l_itr = 0;
00070 
00071     if (l_itr == m_raising) {
00072         m_pulsestate = true;
00073         m_callback_asPulseEdge(m_pulsestate);
00074     } else if (l_itr == m_falling) {
00075         m_pulsestate = false;
00076         m_callback_asPulseEdge(m_pulsestate);
00077     }
00078 
00079     l_itr = (l_itr + 1) % m_period_pcp;
00080 
00081     m_callback_asClock(m_pulsestate);
00082 }
00083 
00084 
00085 bool PulseTrain::getState()
00086 {
00087     return m_pulsestate;
00088 }
00089 
00090 uint32_t PulseTrain::getFrequency()
00091 {
00092     return m_freq;
00093 }
00094 
00095 float PulseTrain::getDutycycle()
00096 {
00097     return m_duty;
00098 }
00099 
00100 uint32_t PulseTrain::getPeriod_us()
00101 {
00102     return m_period_us;
00103 }
00104 
00105 uint32_t PulseTrain::getClockperiod_us()
00106 {
00107     return m_clock_period_us;
00108 }