Generates a pulses train on the order of micro-seconds.

PulseGenerator.cpp

Committer:
aktk
Date:
2019-07-02
Revision:
2:583504323980
Parent:
1:1b5cd3c20187

File content as of revision 2:583504323980:

/**     Pulse Fenerator cpp file
 *
 *  \file   PulseFenerator.cpp
 *  \author Akifumi Takahashi
 *  \date   2018.nov.08-
 *  \version    1.0.2018.nov
 */
#include "PulseGenerator.h"
PulseGenerator::PulseGenerator():
    m_width(200),
    m_period(5000)
{
    m_clockperiod = GCD(m_width, m_period);
    m_rt = (m_period - m_width) / m_clockperiod;
    m_ft = m_width / m_clockperiod;
    m_wavestatus = false;
}

int8_t PulseGenerator::setWaveform(
    const uint16_t arg_pulsewidth,///< required in [us]
    const uint16_t arg_pulsefreq  ///< required in [Hz] > 15 [Hz]
)
{
    uint16_t tmp_width  = m_width;
    uint16_t tmp_period = m_period;

    m_width = arg_pulsewidth;
    //  freq is required over 15 due to the range of the type of the period
    m_period= Period_us(arg_pulsefreq > 15 ? arg_pulsefreq : 16);

    if(m_width > m_period / 2) {
        m_width  = tmp_width;
        m_period = tmp_period;
        return -1;
    }
    return 0;
}


void PulseGenerator::generatePulseWave()
{
    static uint16_t l_counter = 0;

    l_counter++;
    if(m_wavestatus == false && l_counter >= m_rt ) {
        m_wavestatus = true;
        l_counter = 0;
    } else 
    if (m_wavestatus == true && l_counter >= m_ft) {
        m_wavestatus = false;
        l_counter = 0;
    }
}

void PulseGenerator::startPulseWave()
{
    m_clockperiod = GCD(m_width, m_period);
    m_rt = (m_period - m_width) / m_clockperiod;
    m_ft = m_width / m_clockperiod;
    m_ticker.attach_us(callback(this, &PulseGenerator::generatePulseWave), m_clockperiod);
}

void PulseGenerator::stopPulseWave()
{
    m_wavestatus = false;
    m_ticker.detach();
}

uint16_t Period_us(const uint16_t arg_freq)
{
    uint16_t l_period, l_carried;

    //  culc integer part of 1/freq * 10^6
    l_period = (uint16_t)(1000000 / arg_freq);

    //  round factorial part of 1/freq * 10^6
    l_carried = (uint16_t)(((1000000 % arg_freq) > (arg_freq / 2)) ? 1 : 0);

    return l_period + l_carried;
}

uint16_t GCD(uint16_t arg1, uint16_t arg2)
{
    uint16_t a,b,r;

    if (arg1 == 0 || arg2 == 0) return 0;
    if(arg1 > arg2) {
        a = arg1;
        b = arg2;
    } else {
        a = arg2;
        b = arg1;
    }

    //Eukleides Algorithm
    r = a % b;
    while(r != 0) {
        a = b;
        b = r;
        r = a % b;
    }

    return b;
}