Files
mains-frequency-counter-rpi/src/counter.c
2021-03-04 15:44:27 +01:00

125 lines
2.6 KiB
C

#include <wiringPi.h>
#include <wiringPiSPI.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <libconfig.h>
#include <math.h>
#include <time.h>
#include "LS7366R.h"
#include "ringbuffer.h"
#include "led.h"
#include "logging.h"
extern char VERSION[];
extern uint32_t REFCNT;
const int CTRL_OUT = 16;
const int INTR_IN = 19;
const int SPI_CHAN = 0;
const int SPI_SPEED = 1000000;
const uint32_t PRECISION = 1000;
const uint32_t COUNTER_FREQUENCY = 1e6;
config_t cfg;
void isr() {
static uint32_t lastCounter = 0;
uint32_t currentCounter = ls7366rReadOTR();
uint32_t diff = currentCounter - lastCounter;
lastCounter = currentCounter;
ringbufferPut(diff);
led(E_GREEN, true);
}
void init() {
wiringPiSetupGpio();
wiringPiSPISetup(SPI_CHAN, SPI_SPEED);
pinMode(CTRL_OUT, OUTPUT);
digitalWrite(CTRL_OUT, 0);
pinMode(INTR_IN, INPUT);
}
void readConfig() {
config_init(&cfg);
if (! config_read_file(&cfg, "/opt/etc/counter.cfg")) {
logmsg(LOG_ERR, "failed to read config file: %s:%d - %s\n",
config_error_file(&cfg), config_error_line(&cfg),
config_error_text(&cfg));
config_destroy(&cfg);
exit(-1);
}
}
void start() {
wiringPiISR(INTR_IN, INT_EDGE_RISING, isr);
}
int main (void) {
fprintf(stderr, "VERSION: %s, REFCNT: %u\n", VERSION, REFCNT);
readConfig();
init();
ledInit();
ls7366rInit(SPI_CHAN);
start();
uint8_t ledTick = 0;
struct timespec timestamp;
uint32_t last_seconds = 0;
uint32_t last_milliseconds = 0;
uint32_t mainsCntSum = 0;
uint32_t mainsCntCnt = 0;
while (1) {
uint32_t period = ringbufferGet();
clock_gettime(CLOCK_REALTIME, &timestamp);
uint32_t current_seconds = timestamp.tv_sec;
uint32_t current_milliseconds = timestamp.tv_nsec / 1e6;
uint32_t duration = ((current_seconds - last_seconds) * 1000) + (current_milliseconds - last_milliseconds);
// logmsg(LOG_DEBUG, "s: %lu, ns: %lu, d: %lu, p: %lu", current_seconds, current_milliseconds, duration, period);
mainsCntSum += period;
mainsCntCnt += 1;
if (duration >= 1000) {
logmsg(LOG_DEBUG, "one second is over");
last_seconds = current_seconds;
last_milliseconds = current_milliseconds;
uint32_t cnt = mainsCntSum / mainsCntCnt;
mainsCntSum = 0;
mainsCntCnt = 0;
uint32_t freq = PRECISION * COUNTER_FREQUENCY / cnt;
logmsg(LOG_DEBUG, "s: %lu, f: %lu", current_seconds, freq);
}
ledTick++;
if (ledTick == 50) {
ledTick = 0;
led(E_GREEN, false);
}
}
// will never be reached
config_destroy(&cfg);
}