forked from Manawyrm/SolarCamPi
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
242 additions
and
31 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#include "crc.h" | ||
|
||
// Shamelessly stolen fron Stackoverflow (https://stackoverflow.com/questions/10564491/function-to-calculate-a-crc16-checksum) | ||
|
||
uint16_t crc16_8(const unsigned char* data, uint8_t len) { | ||
uint8_t x; | ||
uint16_t crc = 0xFFFF; | ||
|
||
while (len--) { | ||
x = crc >> 8 ^ *data++; | ||
x ^= x>>4; | ||
crc = (crc << 8) ^ ((uint16_t)(x << 12)) ^ ((uint16_t)(x <<5)) ^ ((uint16_t)x); | ||
} | ||
return crc; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#pragma once | ||
|
||
#include <stdint.h> | ||
|
||
uint16_t crc16_8(const unsigned char* data, uint8_t len); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
#include "eeprom.h" | ||
#include <avr/eeprom.h> | ||
#include <avr/interrupt.h> | ||
#include "crc.h" | ||
#include "util.h" | ||
|
||
static uint16_t next_log_entry; | ||
|
||
static unsigned char* write_data; | ||
uint8_t write_len; | ||
uint16_t write_addr; | ||
|
||
#define LOG_ENTRY_LEN (sizeof(struct eeprom_log_block)) | ||
#define LOG_DATA_LEN (sizeof(struct eeprom_log_data_priv)) | ||
#define DEV_DATA_LEN (sizeof(struct eeprom_device_block)) | ||
|
||
#define LOG_ENTRIES CLAMPH(((EEPROM_SIZE) / LOG_ENTRY_LEN), 255) | ||
|
||
EEMEM struct eeprom_log_block logdata[LOG_ENTRIES]; | ||
struct eeprom_log_data log_data; | ||
static struct eeprom_log_block log_block; | ||
|
||
void eeprom_init() { | ||
next_log_entry = 0; | ||
} | ||
|
||
static void inc_log() { | ||
next_log_entry++; | ||
if(next_log_entry >= ARRAY_LEN(logdata)) { | ||
next_log_entry = 0; | ||
} | ||
log_block.data.serial++; | ||
} | ||
|
||
// For some bizarre reason eeprom_read_block reads data backwards... | ||
static void eeprom_read_block_8(void* dst, void* src, uint8_t len) { | ||
while(len--) { | ||
*((unsigned char*)dst++) = eeprom_read_byte(src++); | ||
} | ||
} | ||
|
||
static uint8_t eeprom_read_log_block(struct eeprom_log_block* log, uint8_t entry) { | ||
eeprom_read_block_8(log, &logdata[entry], LOG_ENTRY_LEN); | ||
return log->crc == crc16_8((unsigned char*)&log->data, LOG_DATA_LEN); | ||
} | ||
|
||
uint8_t eeprom_find_log_block() { | ||
struct eeprom_log_block log; | ||
struct eeprom_log_block last_log; | ||
uint8_t entry = 0; | ||
uint8_t found = 0; | ||
if(eeprom_read_log_block(&last_log, ARRAY_LEN(logdata) - 1)) { | ||
found = 1; | ||
log_block = last_log; | ||
log_data = log_block.data.data; | ||
next_log_entry = entry; | ||
inc_log(); | ||
} | ||
while(entry < ARRAY_LEN(logdata)) { | ||
if(eeprom_read_log_block(&log, entry)) { | ||
if(found) { | ||
uint8_t expected_serial = last_log.data.serial; | ||
expected_serial++; | ||
// Sequence break, last log entry is most recent one | ||
if(log.data.serial != expected_serial) { | ||
uint8_t prev_entry = entry; | ||
prev_entry--; | ||
log_block = last_log; | ||
log_data = log_block.data.data; | ||
next_log_entry = prev_entry; | ||
inc_log(); | ||
break; | ||
} | ||
} | ||
log_block = log; | ||
log_data = log_block.data.data; | ||
next_log_entry = entry; | ||
inc_log(); | ||
found = 1; | ||
last_log = log; | ||
} | ||
entry++; | ||
} | ||
return found; | ||
} | ||
|
||
|
||
uint8_t eeprom_busy() { | ||
return write_len != 0; | ||
} | ||
|
||
void eeprom_write_next_byte() { | ||
EEARL = write_addr & 0xFF; | ||
EEARH = (write_addr >> 8); | ||
EEDR = *write_data; | ||
EECR |= BIT(EEMPE) | BIT(EERIE); | ||
EECR |= BIT(EEPE); | ||
} | ||
|
||
void eeprom_write_log_block() { | ||
log_block.data.data = log_data; | ||
write_addr = (uint16_t)&logdata[next_log_entry]; | ||
write_len = LOG_ENTRY_LEN; | ||
write_data = (unsigned char*)&log_block; | ||
log_block.crc = crc16_8((unsigned char*)&log_block.data, LOG_DATA_LEN); | ||
eeprom_write_next_byte(); | ||
} | ||
|
||
ISR(EE_READY_vect) { | ||
write_addr++; | ||
write_data++; | ||
write_len--; | ||
if(write_len) { | ||
// Enqueue next byte | ||
eeprom_write_next_byte(); | ||
} else { | ||
// Transfer finished, disable interrupts and increment serial | ||
EECR &= ~BIT(EERIE); | ||
inc_log(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#pragma once | ||
|
||
#include <stdint.h> | ||
#include "main.h" | ||
|
||
struct eeprom_log_data | ||
{ | ||
uint16_t voltage; | ||
uint16_t sleepInterval; | ||
uint16_t undervoltageLockout; | ||
uint16_t undervoltageHysteresis; | ||
uint8_t disableTimeout; | ||
uint16_t timeout; | ||
}; | ||
|
||
|
||
struct eeprom_log_data_priv { | ||
uint8_t serial; | ||
struct eeprom_log_data data; | ||
}; | ||
|
||
struct eeprom_log_block { | ||
struct eeprom_log_data_priv data; | ||
// Writing the data block can not be an atomic | ||
// operation, crc ensures integrity | ||
uint16_t crc; | ||
}; | ||
|
||
#define EEPROM_SIZE 1024 | ||
|
||
void eeprom_init(); | ||
uint8_t eeprom_find_log_block(); | ||
uint8_t eeprom_busy(); | ||
void eeprom_write_log_block(); | ||
|
||
extern struct eeprom_log_data log_data; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#pragma once | ||
|
||
#include <Arduino.h> | ||
#include "eeprom.h" | ||
|
||
void handleI2CReceive(volatile int numBytes); | ||
void handleI2CRequest(); | ||
void sleep(uint16_t sleepTime); | ||
void shutdownSignaled(); | ||
void setINAState(bool state); | ||
|
||
|
||
enum states { | ||
STATE_ACTIVE, | ||
STATE_SLEEP, | ||
STATE_UNDERVOLTAGE | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#pragma once | ||
#define BIT(x) (1<<(x)) | ||
|
||
#define ARRAY_LEN(arr) (sizeof(arr) / sizeof(*arr)) | ||
|
||
#define ATOMIC_BEGIN do { cli(); | ||
#define ATOMIC_END sei(); } while(0); | ||
|
||
#ifndef NULL | ||
#define NULL ((void*)0U) | ||
#endif | ||
|
||
#define CLAMPH(x, max) (((x) > (max) ? (max) : (x))) | ||
|
||
#define ABS(x) ((x) < 0 ? -(x) : (x)) |