/* log.c */ #include "types.h" #include "sdcard.h" #include "uart.h" #include "timer.h" #include "log.h" /* This is shared with sdcard.c */ bool log_enabled; char log_buffer[LOG_BUFFERSIZE]; unsigned int log_bufferstart; unsigned int log_bufferend; unsigned int log_generation; /* DO NOT call when the buffer is empty */ /* This should be safe against writes to the buffer, as the writes only * affect log_bufferend. So no blocking of interrupts is necessary. */ char log_get_byte(void) { char i; i = log_buffer[log_bufferstart++]; log_bufferstart = log_bufferstart % LOG_BUFFERSIZE; return i; } void log_put_byte(char c) { if (!log_enabled) return; /* If the buffer is full, we just discard data. * Better than overrunning. */ if (((log_bufferend + 1) % LOG_BUFFERSIZE) == log_bufferstart) return; log_buffer[log_bufferend++] = c; log_bufferend = log_bufferend % LOG_BUFFERSIZE; #if 0 putint(c); putch(' '); #endif } void log_put_uint16(unsigned int i) { log_put_byte(i & 0xff); log_put_byte((i >> 8) & 0xff); } void log_put_uint(unsigned int i) { log_put_byte(i & 0xff); log_put_byte((i >> 8) & 0xff); log_put_byte((i >> 16) & 0xff); log_put_byte((i >> 24) & 0xff); } void log_put_header(unsigned int timestamp) { log_put_uint(LOG_MAGIC); log_put_uint(log_generation); log_put_uint(timestamp); log_put_uint(log_read_busytime()); } void log_put_array(char *data, int length) { int i; for (i = 0; i < length; i++) log_put_byte(data[i]); } void log_put_float(float f) { union { float f; unsigned int i; } data; data.f = f; log_put_uint(data.i); } unsigned int log_busystamp; unsigned int log_busytime; void log_mark_busy(void) { unsigned int time = timer_read(); log_busystamp = time; } void log_mark_idle(void) { unsigned int time = timer_read(); unsigned int diff = time - log_busystamp; log_busytime += diff; } unsigned int log_read_busytime(void) { unsigned int time = log_busytime; log_busytime = 0; return time; }