62 lines
1.4 KiB
C
62 lines
1.4 KiB
C
|
#include "fsk_osc.h"
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
struct FSKOsc {
|
||
|
uint16_t freq[2];
|
||
|
uint16_t osc_phase_max;
|
||
|
int32_t osc_phase_current;
|
||
|
|
||
|
uint32_t pulse;
|
||
|
};
|
||
|
|
||
|
FSKOsc* fsk_osc_alloc(uint32_t freq_low, uint32_t freq_hi, uint32_t osc_phase_max) {
|
||
|
FSKOsc* osc = malloc(sizeof(FSKOsc));
|
||
|
osc->freq[0] = freq_low;
|
||
|
osc->freq[1] = freq_hi;
|
||
|
osc->osc_phase_max = osc_phase_max;
|
||
|
osc->osc_phase_current = 0;
|
||
|
osc->pulse = 0;
|
||
|
return osc;
|
||
|
}
|
||
|
|
||
|
void fsk_osc_free(FSKOsc* osc) {
|
||
|
free(osc);
|
||
|
}
|
||
|
|
||
|
void fsk_osc_reset(FSKOsc* osc) {
|
||
|
osc->osc_phase_current = 0;
|
||
|
osc->pulse = 0;
|
||
|
}
|
||
|
|
||
|
bool fsk_osc_next(FSKOsc* osc, bool bit, uint32_t* period) {
|
||
|
bool advance = false;
|
||
|
*period = osc->freq[bit];
|
||
|
osc->osc_phase_current += *period;
|
||
|
|
||
|
if(osc->osc_phase_current > osc->osc_phase_max) {
|
||
|
advance = true;
|
||
|
osc->osc_phase_current -= osc->osc_phase_max;
|
||
|
}
|
||
|
|
||
|
return advance;
|
||
|
}
|
||
|
|
||
|
bool fsk_osc_next_half(FSKOsc* osc, bool bit, bool* level, uint32_t* duration) {
|
||
|
bool advance = false;
|
||
|
|
||
|
// if pulse is zero, we need to output high, otherwise we need to output low
|
||
|
if(osc->pulse == 0) {
|
||
|
uint32_t length;
|
||
|
advance = fsk_osc_next(osc, bit, &length);
|
||
|
*duration = length / 2;
|
||
|
osc->pulse = *duration;
|
||
|
*level = true;
|
||
|
} else {
|
||
|
// output low half and reset pulse
|
||
|
*duration = osc->pulse;
|
||
|
osc->pulse = 0;
|
||
|
*level = false;
|
||
|
}
|
||
|
|
||
|
return advance;
|
||
|
}
|