#include #include #include #include #include #include #include #include #include #include #include #include #include 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 = strtol(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); }