Compare commits

...

4 Commits

Author SHA1 Message Date
Sebastian H. Gabrielli
ae1c50ee09 Writing config works 2024-04-27 15:39:46 +02:00
Sebastian H. Gabrielli
f654ae96f6 Add case structure for better handling of future config params
A case structure to send the correct config value has been added.
2024-04-27 14:55:44 +02:00
Sebastian H. Gabrielli
dd624d4d48 Reading config parameter works 2024-04-27 14:52:46 +02:00
Sebastian H. Gabrielli
fb24365469 Prepare for write config 2024-04-24 15:50:58 +02:00
5 changed files with 90 additions and 14 deletions

View File

@ -54,7 +54,7 @@ void parse_command(uint8_t command[], uint8_t command_len) {
return; return;
} }
// Validate that we have a first parameter, else requirements for command are // Validate that we have a second parameter, else requirements for command are
// not fulfilled. return unknown command. // not fulfilled. return unknown command.
if (command_len < 2) { if (command_len < 2) {
context.command = UNKNOWN_COMMAND; context.command = UNKNOWN_COMMAND;
@ -69,7 +69,11 @@ void parse_command(uint8_t command[], uint8_t command_len) {
// Configuration parameters // Configuration parameters
case 0x11: // Read config case 0x11: // Read config
case 0x21: // Write config case 0x21: // Write config
// TODO: Handle parameters for config if (param == 0x01) {
context.conf = SAMPLE_TIME;
} else {
context.conf = CNF_NONE;
}
break; break;
// Voltage parameters // Voltage parameters
@ -104,9 +108,9 @@ void parse_command(uint8_t command[], uint8_t command_len) {
break; break;
} }
//////////////////////////////// /////////////////////////////////
// Second parameter selection // // Third parameter selection //
//////////////////////////////// /////////////////////////////////
// Check if the command does not require a second parameter. If it does not, // Check if the command does not require a second parameter. If it does not,
// return. Only config write requires a second parameter. // return. Only config write requires a second parameter.
@ -114,7 +118,7 @@ void parse_command(uint8_t command[], uint8_t command_len) {
return; return;
} }
// Validate that we have a first parameter, else requirements for command are // Validate that we have a third parameter, else requirements for command are
// not fulfilled. return unknown command. // not fulfilled. return unknown command.
if (command_len < 3) { if (command_len < 3) {
context.command = UNKNOWN_COMMAND; context.command = UNKNOWN_COMMAND;
@ -124,7 +128,31 @@ void parse_command(uint8_t command[], uint8_t command_len) {
// Store the parameter // Store the parameter
param = command[2]; param = command[2];
// TODO: Handle the config parameters context.conf = param;
////////////////////////////////
// Fourth parameter selection //
////////////////////////////////
// Validate that we have a fourth parameter, else requirements for command are
// not fulfilled. return unknown command. Second parameter is u16, thus two bytes.
if (command_len < 4) {
context.command = UNKNOWN_COMMAND;
return;
}
// Extract the value
union {
uint16_t value;
uint8_t bytes[2];
} config_value;
config_value.bytes[0] = command[3];
config_value.bytes[1] = command[4];
// Store the value
context.conf_val = config_value.value;
// exit // exit
return; return;
@ -133,9 +161,40 @@ void parse_command(uint8_t command[], uint8_t command_len) {
uint8_t route_command(int pos) { uint8_t route_command(int pos) {
switch (context.command) { switch (context.command) {
case WRITE_CONFIG: case WRITE_CONFIG:
return WRITE_CONFIG; switch (context.conf) {
case SAMPLE_TIME:
// Overwrite the config value
config.ms_fanspeed_sample_rate = context.conf_val;
// Set the flag to store it in the EEPROM
store_config = true;
break;
}
break;
case READ_CONFIG: case READ_CONFIG:
return READ_CONFIG; {
switch (context.conf) {
case SAMPLE_TIME:
{
// Validate that pos is within the valid range
if (pos >= 2) { return 0x00; }
// Config only has one parameter so we sent that parameter
// Create a union to store the data
union {
uint16_t value;
uint8_t bytes[2];
} config_value;
config_value.value = config.ms_fanspeed_sample_rate;
// Return the corresponding data byte
return config_value.bytes[1-pos];
}
break;
}
}
break;
case READ_VOLTAGE: case READ_VOLTAGE:
{ {
// Create a union to store the data // Create a union to store the data

View File

@ -42,6 +42,7 @@ typedef enum {
// Enum of all valid config options // Enum of all valid config options
// TODO: Move into config header file // TODO: Move into config header file
typedef enum { typedef enum {
SAMPLE_TIME = 0x01, // Time between each fan speed sample
CNF_NONE, // No config option CNF_NONE, // No config option
} config_option_t; } config_option_t;
@ -59,13 +60,17 @@ typedef struct {
src_voltage_t src_voltage; // The selected voltage source src_voltage_t src_voltage; // The selected voltage source
fans_t fan; // The selected fan fans_t fan; // The selected fan
config_option_t conf; // The configuration option to cange config_option_t conf; // The configuration option to cange
// TODO: Add config value field for writing uint16_t conf_val; // The value of the config option to change
} command_context_t; } command_context_t;
// Fan history variables // Fan history variables
extern volatile uint16_t fan1_history[512]; extern volatile uint16_t fan1_history[512];
extern volatile uint16_t fan2_history[512]; extern volatile uint16_t fan2_history[512];
// Config
extern volatile config_t config;
extern volatile bool store_config;
// Parses the input string and outputs one of the valid commands // Parses the input string and outputs one of the valid commands
void parse_command(uint8_t *command, uint8_t command_len); void parse_command(uint8_t *command, uint8_t command_len);

View File

@ -23,7 +23,7 @@ extern "C" {
// Struct for information on the controller. // Struct for information on the controller.
typedef struct { typedef struct {
uint8_t fanSpeed; uint16_t ms_fanspeed_sample_rate;
} config_t; } config_t;
// Check if EEPROM is ready to be written in // Check if EEPROM is ready to be written in

View File

@ -68,7 +68,7 @@ void i2c_stop_handler() {
// Parse the received command data // Parse the received command data
parse_command(i2c_recv, i2c_recv_len); parse_command(i2c_recv, i2c_recv_len);
if (i2c_recv[0] == 0x22) { if (i2c_recv[0] == CLEAR_BULK_FAN_SPEED || i2c_recv[0] == WRITE_CONFIG) {
route_command(0); route_command(0);
} }
} }

View File

@ -27,18 +27,30 @@
volatile uint16_t fan1_history[512] = {1, 2, 3, 4}; volatile uint16_t fan1_history[512] = {1, 2, 3, 4};
volatile uint16_t fan2_history[512] = {2, 3, 4, 5}; volatile uint16_t fan2_history[512] = {2, 3, 4, 5};
// Default config is 500ms sample rate
volatile config_t config = { 500 };
volatile bool store_config = false;
int main() { int main() {
// Initialize functionality
init_uart((uint16_t)9600); init_uart((uint16_t)9600);
ADC0_init(); ADC0_init();
init_led(); init_led();
init_i2c(); init_i2c();
stdout = &USART_stream; stdout = &USART_stream;
// Read the stored config struct
config = read_struct_from_EEPROM();
PORTB.DIRSET = PIN3_bm; PORTB.DIRSET = PIN3_bm;
sei(); sei();
while (1) { while (1) {
; // If we have made a config change, store it.
if (store_config) {
write_struct_from_EEPROM(config);
store_config = false;
}
} }
} }