190 lines
6.4 KiB
C
190 lines
6.4 KiB
C
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <tim.h>
|
|
|
|
#include <counter.h>
|
|
#include <show.h>
|
|
#include <logger.h>
|
|
#include <PontCoopScheduler.h>
|
|
#include <config.h>
|
|
#include <sinkStruct.h>
|
|
#include <sha256.h>
|
|
#include <eeprom.h>
|
|
#include <networkAbstractionLayer.h>
|
|
|
|
|
|
|
|
const uint32_t COUNTER_FREQUENCY = 1.0e6;
|
|
|
|
// 100: 2 digits behind decimal point
|
|
// 1000: 3 digits behind decimal point
|
|
const uint32_t PRECISION = 1000;
|
|
|
|
volatile static uint32_t mainsCntSum = 0;
|
|
volatile static uint32_t mainsCntCnt = 0;
|
|
|
|
static t_seconds *seconds;
|
|
static t_deviceStats *deviceStats;
|
|
|
|
|
|
|
|
#define NUM_OF_MINUTE_BUFFERS 2
|
|
t_minuteBuffer minuteBuffers[NUM_OF_MINUTE_BUFFERS];
|
|
bool minuteBufferReady[NUM_OF_MINUTE_BUFFERS];
|
|
uint8_t activeMinuteBuffer;
|
|
|
|
static t_configBlock *config;
|
|
|
|
|
|
void counterMinuteTick(void *handle) {
|
|
for (uint8_t minuteBufferIdx = 0; minuteBufferIdx < NUM_OF_MINUTE_BUFFERS; minuteBufferIdx++) {
|
|
t_minuteBuffer *minuteBuffer = &(minuteBuffers[minuteBufferIdx]);
|
|
|
|
if (minuteBufferReady[minuteBufferIdx] == 1) {
|
|
coloredMsg(LOG_BLUE, "cmt, buffer %d is done, handle it", minuteBufferIdx);
|
|
|
|
minuteBuffer->s.totalRunningHours = deviceStats->totalRunningHours;
|
|
minuteBuffer->s.totalPowercycles = deviceStats->totalPowercycles;
|
|
minuteBuffer->s.totalWatchdogResets = deviceStats->totalWatchdogResets;
|
|
minuteBuffer->s.version = strtoll(VERSION, NULL, 16);
|
|
|
|
|
|
memset(minuteBuffer->s.deviceId, 0, sizeof(minuteBuffer->s.deviceId));
|
|
strcpy(minuteBuffer->s.deviceId, config->deviceId);
|
|
|
|
memcpy(minuteBuffer->s.hash, config->sharedSecret, SHA256_BLOCK_SIZE);
|
|
SHA256_CTX ctx;
|
|
sha256_init(&ctx);
|
|
sha256_update(&ctx, minuteBuffer->b, sizeof(minuteBuffer->b));
|
|
sha256_final(&ctx, minuteBuffer->s.hash);
|
|
coloredMsg(LOG_BLUE, "cmt, hash, 1. half is %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
|
minuteBuffer->s.hash[0],
|
|
minuteBuffer->s.hash[1],
|
|
minuteBuffer->s.hash[2],
|
|
minuteBuffer->s.hash[3],
|
|
minuteBuffer->s.hash[4],
|
|
minuteBuffer->s.hash[5],
|
|
minuteBuffer->s.hash[6],
|
|
minuteBuffer->s.hash[7],
|
|
minuteBuffer->s.hash[8],
|
|
minuteBuffer->s.hash[9],
|
|
minuteBuffer->s.hash[10],
|
|
minuteBuffer->s.hash[11],
|
|
minuteBuffer->s.hash[12],
|
|
minuteBuffer->s.hash[13],
|
|
minuteBuffer->s.hash[14],
|
|
minuteBuffer->s.hash[15]
|
|
);
|
|
coloredMsg(LOG_BLUE, "cmt, hash, 2. half is %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
|
minuteBuffer->s.hash[16],
|
|
minuteBuffer->s.hash[17],
|
|
minuteBuffer->s.hash[18],
|
|
minuteBuffer->s.hash[19],
|
|
minuteBuffer->s.hash[20],
|
|
minuteBuffer->s.hash[21],
|
|
minuteBuffer->s.hash[22],
|
|
minuteBuffer->s.hash[23],
|
|
minuteBuffer->s.hash[24],
|
|
minuteBuffer->s.hash[25],
|
|
minuteBuffer->s.hash[26],
|
|
minuteBuffer->s.hash[27],
|
|
minuteBuffer->s.hash[28],
|
|
minuteBuffer->s.hash[29],
|
|
minuteBuffer->s.hash[30],
|
|
minuteBuffer->s.hash[31]
|
|
);
|
|
|
|
int8_t res = networkSendMinuteBuffer(minuteBuffer);
|
|
if (res == 1) {
|
|
coloredMsg(LOG_BLUE, "cmt, successfully sent");
|
|
minuteBufferReady[minuteBufferIdx] = false;
|
|
} else {
|
|
coloredMsg(LOG_BLUE, "cmt, not successfully sent, try again");
|
|
schAdd(counterMinuteTick, NULL, 1000, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void counterSecondTick(void *handle) {
|
|
static uint8_t bufferIdx = 0;
|
|
uint32_t tmpSum = 0;
|
|
uint32_t tmpCnt = 0;
|
|
|
|
HAL_NVIC_DisableIRQ(TIM1_CC_IRQn);
|
|
tmpSum = mainsCntSum;
|
|
mainsCntSum = 0;
|
|
tmpCnt = mainsCntCnt;
|
|
mainsCntCnt = 0;
|
|
HAL_NVIC_EnableIRQ(TIM1_CC_IRQn);
|
|
|
|
uint32_t cnt = tmpSum / tmpCnt;
|
|
uint32_t freq = PRECISION * COUNTER_FREQUENCY / cnt;
|
|
|
|
coloredMsg(LOG_GREEN, "cst, Freq: %lu", freq);
|
|
coloredMsg(LOG_GREEN, "cst, Tick: %d %lu %lu", seconds->valid, seconds->missedUpdates, seconds->seconds);
|
|
|
|
if (! seconds->valid) {
|
|
coloredMsg(LOG_RED, "cst, time is not yet valid");
|
|
} else if (minuteBufferReady[activeMinuteBuffer]) {
|
|
coloredMsg(LOG_RED, "cst, minute buffer overrun");
|
|
} else {
|
|
if (bufferIdx == 0) {
|
|
minuteBuffers[activeMinuteBuffer].s.timestamp = seconds->seconds;
|
|
}
|
|
minuteBuffers[activeMinuteBuffer].s.frequency[bufferIdx] = freq;
|
|
coloredMsg(LOG_GREEN, "cst, added to buffer %d, slot %d", activeMinuteBuffer, bufferIdx);
|
|
bufferIdx += 1;
|
|
if (bufferIdx == SECONDS_PER_MINUTE) {
|
|
coloredMsg(LOG_GREEN, "cst, buffer %d is done", activeMinuteBuffer);
|
|
minuteBufferReady[activeMinuteBuffer] = true;
|
|
activeMinuteBuffer += 1;
|
|
bufferIdx = 0;
|
|
if (activeMinuteBuffer >= NUM_OF_MINUTE_BUFFERS) {
|
|
activeMinuteBuffer = 0;
|
|
}
|
|
schAdd(counterMinuteTick, NULL, 1000, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void mainsCntsInputCaptureCallback(TIM_HandleTypeDef *htim) {
|
|
static uint8_t state = 0;
|
|
static uint32_t savedV = 0;
|
|
|
|
uint32_t v = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
|
|
if (state == 0) {
|
|
show(DEBUG_2, ON);
|
|
savedV = v;
|
|
state = 1;
|
|
} else if (state == 1) {
|
|
show(DEBUG_2, OFF);
|
|
uint32_t captured = (savedV < v) ? (v - savedV) : ((htim->Init.Period - savedV) + v);
|
|
mainsCntSum += captured;
|
|
mainsCntCnt += 1;
|
|
state = 0;
|
|
} else {
|
|
state = 0;
|
|
}
|
|
}
|
|
|
|
|
|
void counterInit() {
|
|
deviceStats = getGlobalDeviceStats();
|
|
|
|
seconds = networkGetSeconds();
|
|
for (uint8_t i = 0; i < NUM_OF_MINUTE_BUFFERS; i++) {
|
|
minuteBufferReady[i] = false;
|
|
}
|
|
activeMinuteBuffer = 0;
|
|
|
|
|
|
config = getConfig();
|
|
|
|
schAdd(counterSecondTick, NULL, 0, 1000);
|
|
|
|
HAL_TIM_IC_Start_IT(&mainsCnt, TIM_CHANNEL_1);
|
|
}
|