mirror of
https://github.com/RfidResearchGroup/ChameleonMini.git
synced 2026-05-12 11:20:37 -07:00
227 lines
6.7 KiB
C
227 lines
6.7 KiB
C
#include "Log.h"
|
|
#include "Settings.h"
|
|
#include "Terminal/Terminal.h"
|
|
#include "System.h"
|
|
#include "Map.h"
|
|
#include "LEDHook.h"
|
|
|
|
static uint8_t LogMem[LOG_SIZE];
|
|
static uint8_t *LogMemPtr;
|
|
static uint16_t LogMemLeft;
|
|
static uint16_t LogFRAMAddr = FRAM_LOG_START_ADDR;
|
|
static uint8_t EEMEM LogFRAMAddrValid = false;
|
|
static bool EnableLogSRAMtoFRAM = false;
|
|
LogFuncType CurrentLogFunc;
|
|
|
|
static const MapEntryType PROGMEM LogModeMap[] = {
|
|
{ .Id = LOG_MODE_OFF, .Text = "OFF" },
|
|
{ .Id = LOG_MODE_MEMORY, .Text = "MEMORY" },
|
|
{ .Id = LOG_MODE_LIVE, .Text = "LIVE" }
|
|
};
|
|
|
|
static void LogFuncOff(LogEntryEnum Entry, const void *Data, uint8_t Length) {
|
|
/* Do nothing */
|
|
}
|
|
|
|
static void LogFuncMemory(LogEntryEnum Entry, const void *Data, uint8_t Length) {
|
|
uint16_t SysTick = SystemGetSysTick();
|
|
|
|
if (LogMemLeft >= (Length + 4)) {
|
|
LogMemLeft -= Length + 4;
|
|
|
|
uint8_t *DataPtr = (uint8_t *) Data;
|
|
|
|
/* Write down Entry Id, Data length and Timestamp */
|
|
*LogMemPtr++ = (uint8_t) Entry;
|
|
*LogMemPtr++ = (uint8_t) Length;
|
|
*LogMemPtr++ = (uint8_t)(SysTick >> 8);
|
|
*LogMemPtr++ = (uint8_t)(SysTick >> 0);
|
|
|
|
/* Write down data bytes */
|
|
while (Length--) {
|
|
*LogMemPtr++ = *DataPtr++;
|
|
}
|
|
} else {
|
|
/* If memory full. Deactivate logmode */
|
|
LogSetModeById(LOG_MODE_OFF);
|
|
LEDHook(LED_LOG_MEM_FULL, LED_ON);
|
|
}
|
|
}
|
|
|
|
static void LogFuncLive(LogEntryEnum Entry, const void *Data, uint8_t Length) {
|
|
uint16_t SysTick = SystemGetSysTick();
|
|
|
|
TerminalSendByte((uint8_t) Entry);
|
|
TerminalSendByte((uint8_t) Length);
|
|
TerminalSendByte((uint8_t)(SysTick >> 8));
|
|
TerminalSendByte((uint8_t)(SysTick >> 0));
|
|
TerminalSendBlock(Data, Length);
|
|
}
|
|
|
|
void LogInit(void) {
|
|
LogSetModeById(GlobalSettings.ActiveSettingPtr->LogMode);
|
|
LogMemPtr = LogMem;
|
|
LogMemLeft = sizeof(LogMem);
|
|
|
|
uint8_t result;
|
|
ReadEEPBlock((uint16_t) &LogFRAMAddrValid, &result, 1);
|
|
memset(LogMemPtr, LOG_EMPTY, LOG_SIZE);
|
|
if (result) {
|
|
MemoryReadBlock(&LogFRAMAddr, FRAM_LOG_ADDR_ADDR, 2);
|
|
} else {
|
|
LogFRAMAddr = FRAM_LOG_START_ADDR;
|
|
MemoryWriteBlock(&LogFRAMAddr, FRAM_LOG_ADDR_ADDR, 2);
|
|
result = true;
|
|
WriteEEPBlock((uint16_t) &LogFRAMAddrValid, &result, 1);
|
|
}
|
|
|
|
LogEntry(LOG_INFO_SYSTEM_BOOT, NULL, 0);
|
|
}
|
|
|
|
void LogTick(void) {
|
|
if (EnableLogSRAMtoFRAM)
|
|
LogSRAMToFRAM();
|
|
}
|
|
|
|
void LogTask(void) {
|
|
|
|
}
|
|
|
|
bool LogMemLoadBlock(void *Buffer, uint32_t BlockAddress, uint16_t ByteCount) {
|
|
if (BlockAddress < sizeof(LogMem) + (LogFRAMAddr - FRAM_LOG_START_ADDR)) {
|
|
bool overflow = false;
|
|
uint16_t remainderByteCount = 0;
|
|
uint16_t SizeInFRAMStored = LogFRAMAddr - FRAM_LOG_START_ADDR;
|
|
// prevent buffer overflows:
|
|
if ((BlockAddress + ByteCount) >= sizeof(LogMem) + SizeInFRAMStored) {
|
|
overflow = true;
|
|
uint16_t tmp = sizeof(LogMem) + SizeInFRAMStored - BlockAddress;
|
|
remainderByteCount = ByteCount - tmp;
|
|
ByteCount = tmp;
|
|
}
|
|
|
|
/*
|
|
* 1. case: The whole block is in FRAM.
|
|
* 2. case: The block wraps from FRAM to SRAM
|
|
* 3. case: The whole block is in SRAM.
|
|
*/
|
|
if (BlockAddress < SizeInFRAMStored && (BlockAddress + ByteCount) < SizeInFRAMStored) {
|
|
MemoryReadBlock(Buffer, BlockAddress + FRAM_LOG_START_ADDR, ByteCount);
|
|
} else if (BlockAddress < SizeInFRAMStored) {
|
|
uint16_t FramByteCount = SizeInFRAMStored - BlockAddress;
|
|
MemoryReadBlock(Buffer, BlockAddress + FRAM_LOG_START_ADDR, FramByteCount);
|
|
memcpy(Buffer + FramByteCount, LogMem, ByteCount - FramByteCount);
|
|
} else {
|
|
memcpy(Buffer, LogMem + BlockAddress - SizeInFRAMStored, ByteCount);
|
|
}
|
|
|
|
if (overflow) {
|
|
while (remainderByteCount--)
|
|
((uint8_t *) Buffer)[ByteCount + remainderByteCount] = 0x00;
|
|
}
|
|
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
INLINE void LogSRAMClear(void) {
|
|
uint16_t i, until = LOG_SIZE - LogMemLeft;
|
|
|
|
for (i = 0; i < until; i++) {
|
|
LogMem[i] = (uint8_t) LOG_EMPTY;
|
|
}
|
|
|
|
LogMemPtr = LogMem;
|
|
LogMemLeft = sizeof(LogMem);
|
|
}
|
|
|
|
void LogMemClear(void) {
|
|
LogSRAMClear();
|
|
LogFRAMAddr = FRAM_LOG_START_ADDR;
|
|
MemoryWriteBlock(&LogFRAMAddr, FRAM_LOG_ADDR_ADDR, 2);
|
|
LEDHook(LED_LOG_MEM_FULL, LED_OFF);
|
|
}
|
|
|
|
uint16_t LogMemFree(void) {
|
|
return LogMemLeft + FRAM_LOG_SIZE - LogFRAMAddr + FRAM_LOG_START_ADDR;
|
|
}
|
|
|
|
|
|
void LogSetModeById(LogModeEnum Mode) {
|
|
#ifndef LOG_SETTING_GLOBAL
|
|
GlobalSettings.ActiveSettingPtr->LogMode = Mode;
|
|
#else
|
|
/* Write Log settings globally */
|
|
for (uint8_t i = 0; i < SETTINGS_COUNT; i++) {
|
|
GlobalSettings.Settings[i].LogMode = Mode;
|
|
}
|
|
#endif
|
|
|
|
switch (Mode) {
|
|
case LOG_MODE_OFF:
|
|
EnableLogSRAMtoFRAM = false;
|
|
CurrentLogFunc = LogFuncOff;
|
|
break;
|
|
|
|
case LOG_MODE_MEMORY:
|
|
EnableLogSRAMtoFRAM = true;
|
|
CurrentLogFunc = LogFuncMemory;
|
|
break;
|
|
|
|
case LOG_MODE_LIVE:
|
|
EnableLogSRAMtoFRAM = false;
|
|
CurrentLogFunc = LogFuncLive;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
bool LogSetModeByName(const char *Mode) {
|
|
MapIdType Id;
|
|
|
|
if (MapTextToId(LogModeMap, ARRAY_COUNT(LogModeMap), Mode, &Id)) {
|
|
LogSetModeById(Id);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void LogGetModeByName(char *Mode, uint16_t BufferSize) {
|
|
MapIdToText(LogModeMap, ARRAY_COUNT(LogModeMap),
|
|
GlobalSettings.ActiveSettingPtr->LogMode, Mode, BufferSize);
|
|
}
|
|
|
|
void LogGetModeList(char *List, uint16_t BufferSize) {
|
|
MapToString(LogModeMap, ARRAY_COUNT(LogModeMap), List, BufferSize);
|
|
}
|
|
|
|
void LogSRAMToFRAM(void) {
|
|
if (LogMemLeft < LOG_SIZE) {
|
|
uint16_t FRAM_Free = FRAM_LOG_SIZE - (LogFRAMAddr - FRAM_LOG_START_ADDR);
|
|
|
|
if (FRAM_Free >= LOG_SIZE - LogMemLeft) {
|
|
MemoryWriteBlock(LogMem, LogFRAMAddr, LOG_SIZE - LogMemLeft);
|
|
LogFRAMAddr += LOG_SIZE - LogMemLeft;
|
|
LogSRAMClear();
|
|
MemoryWriteBlock(&LogFRAMAddr, FRAM_LOG_ADDR_ADDR, 2);
|
|
} else if (FRAM_Free > 0) {
|
|
// not everything fits in FRAM, simply write as much as possible to FRAM
|
|
MemoryWriteBlock(LogMem, LogFRAMAddr, FRAM_Free);
|
|
memmove(LogMem, LogMem + FRAM_Free, LOG_SIZE - FRAM_Free); // FRAM_Free is < LOG_SIZE - LogMemLeft and thus also < LOG_SIZE
|
|
|
|
LogMemPtr -= FRAM_Free;
|
|
LogMemLeft += FRAM_Free;
|
|
LogFRAMAddr += FRAM_Free;
|
|
MemoryWriteBlock(&LogFRAMAddr, FRAM_LOG_ADDR_ADDR, 2);
|
|
} else {
|
|
// TODO handle the case in which the FRAM is full
|
|
}
|
|
}
|
|
}
|