Legacy branch migration

This commit is contained in:
2024-03-12 21:23:47 +02:00
parent 02cb3a9c70
commit ddf9d263b1
139 changed files with 2476 additions and 14269 deletions

125
firmware/drivers/display.c Normal file
View File

@@ -0,0 +1,125 @@
/**** Includes ****/
#include "display.h"
/**** Private definitions ****/
/**** Private variables ****/
static uint8_t PWM_DIMM = 50;
static uint8_t PWM_BRIGTH = 100;
static uint8_t set_image = 0x00;
static uint16_t lock_timer = 0;
/**** Private function declarations ****/
static uint8_t ImageGen_Dot10(uint8_t percent);
static uint8_t ImageGen_Dot20(uint8_t percent);
static uint8_t ImageGen_Bar(uint8_t percent);
/**** Public function definitions ****/
void Display_CfgBacklight(uint8_t brigth, uint8_t dimm)
{
//Limit values
if(brigth>100) brigth = 100;
else if(brigth==0) brigth = 1;
if(dimm>100) dimm = 100;
else if(dimm==0) dimm = 1;
//Save values
PWM_BRIGTH = brigth;
PWM_DIMM = dimm;
}
void Display_SetImage(uint8_t image)
{
if(lock_timer) return;
set_image = image & 0x3F;
}
void Display_SetPercent(uint8_t value, dspStyle_t style)
{
switch(style)
{
case BAR:
Display_SetImage(ImageGen_Bar(value));
break;
case DOT10:
Display_SetImage(ImageGen_Dot10(value));
break;
default:
Display_SetImage(ImageGen_Dot20(value));
break;
}
}
void Display_SetScale(uint16_t value, uint16_t max_value ,dspStyle_t style)
{
//Convert value to percent
uint32_t temp = (uint32_t)value *100;
temp /= max_value;
//Limit value to 100 percent
uint8_t percent = 0;
if(temp >= 100) percent = 100;
else if(temp == 0) percent = 0;
else percent = (uint8_t)temp;
Display_SetPercent(percent, style);
}
void Display_SetLock(uint16_t time)
{
lock_timer = time;
}
void Display_Update(inputs_t* inputs)
{
// Brightness control
if(inputs->dimm.is_active) LED_DSP_SetBrightness(PWM_DIMM);
else LED_DSP_SetBrightness(PWM_BRIGTH);
if(lock_timer) lock_timer--;
// Set image
LED_DSP_ShowImage(set_image);
}
/**** Private function definitions ****/
static uint8_t ImageGen_Dot10(uint8_t percent)
{
if(percent<6) return 0x01;
else if(percent<16) return 0x03;
else if(percent<26) return 0x02;
else if(percent<36) return 0x06;
else if(percent<46) return 0x04;
else if(percent<56) return 0x0C;
else if(percent<66) return 0x08;
else if(percent<76) return 0x18;
else if(percent<86) return 0x10;
else if(percent<96) return 0x30;
else return 0x20;
}
static uint8_t ImageGen_Dot20(uint8_t percent)
{
if(percent<11) return 0x01;
else if(percent<31) return 0x02;
else if(percent<51) return 0x04;
else if(percent<71) return 0x08;
else if(percent<91) return 0x10;
else return 0x20;
}
static uint8_t ImageGen_Bar(uint8_t percent)
{
if(percent<11) return 0x01;
else if(percent<31) return 0x03;
else if(percent<51) return 0x07;
else if(percent<71) return 0x0F;
else if(percent<91) return 0x1F;
else return 0x3F;
}

View File

@@ -0,0 +1,27 @@
#ifndef DISPLAY_DRV_H_
#define DISPLAY_DRV_H_
/**** Includes ****/
#include <avr/io.h>
#include "../devices/led_display.h"
#include "../devices/inputs.h"
/**** Public definitions ****/
typedef enum {
DOT20,
DOT10,
BAR
} dspStyle_t;
/**** Public function declarations ****/
void Display_SetImage(uint8_t image);
void Display_SetPercent(uint8_t value, dspStyle_t style);
void Display_SetScale(uint16_t value, uint16_t max_value ,dspStyle_t style);
void Display_SetLock(uint16_t time);
void Display_Update(inputs_t* inputs);
void Display_CfgBacklight(uint8_t brigth, uint8_t dimm);
#endif /* DISPLAY_DRV_H_ */

341
firmware/drivers/output.c Normal file
View File

@@ -0,0 +1,341 @@
/**** Includes ****/
#include "output.h"
/**** Private definitions ****/
typedef struct {
uint8_t active;
uint8_t time;
} warn_t;
typedef struct {
warn_t supply_voltage;
warn_t supply_current;
warn_t supply_power;
warn_t output_voltage;
warn_t output_current;
warn_t output_power;
warn_t output_open;
warn_t output_short;
warn_t output_mismatch;
} warnings_t;
typedef struct {
uint8_t supply_uvlo;
uint8_t supply_ovp;
uint8_t supply_ocp;
uint8_t supply_opp;
uint8_t output_ovp;
uint8_t output_ocp;
uint8_t output_opp;
uint8_t output_open;
uint8_t output_short;
} faults_t;
/**** Private constants ****/
static const uint16_t LIM_SUPPLY_UVLO = 8000; //mV
static const uint16_t LIM_SUPPLY_OVP = 18000; //mV
static const uint16_t LIM_SUPPLY_OCP = 7000; //mA
static const uint16_t LIM_SUPPLY_OPP = 40000; //mW
static const uint16_t LIM_OUTPUT_OVP = 12000; //mV
static const uint16_t LIM_OUTPUT_OCP = 7000; //mA
static const uint16_t LIM_OUTPUT_OPP = 40000; //mW
static const uint16_t LIM_OUTPUT_OPEN = 40000; //mR
static const uint16_t LIM_OUTPUT_SHORT = 750; //mR
static const uint16_t LIM_OUTPUT_MATCH = 100; //mV
static const uint8_t OCP_WARNING_LIMIT = 10; //cycles
static const uint8_t SHORT_WARNING_LIMIT = 50; //cycles
static const uint16_t MAX_OUTPUT_VOLTAGE = 10000; //mV
static const uint16_t MIN_OUTPUT_VOLTAGE = 100; //mV
static const uint16_t COOLDOWN_TIME = 5000;
/**** Private variables ****/
static warnings_t warnings;
static faults_t faults;
static uint16_t target_output = 0;
static uint16_t adj_target = 0;
static int32_t hb_volt_sum = 0;
static uint8_t new_target = 1;
static uint8_t steady_state = 0;
static faultState_t fault_state = F_NONE;
static uint16_t cooldown_timer = 0;
static outState_t out_state = O_OFF;
/**** Private function declarations ****/
static void Process_Warnings(analog_t* meas);
static uint8_t Process_Faults(void);
static void ProcessWarningTime(warn_t* w);
static uint8_t isAnyFaultActive(faults_t* f);
static uint8_t isFaultWarningActive(warnings_t* w, faults_t* f);
static void ResetFaults(faults_t* f);
/**** Public function definitions ****/
void Output_Enable(void)
{
ResetFaults(&faults);
target_output = 0;
out_state = O_ACTIVE;
HB_SetTarget(0) ;
HB_SetLowSide(1);
HB_Enable();
}
void Output_Update(analog_t* meas)
{
Process_Warnings(meas);
// Convert Warnings to Faults
uint8_t active_fault = Process_Faults();
/// Ignore faults
active_fault = 0;
// Determine coil state
switch(out_state)
{
case O_ACTIVE:
if(active_fault)
{
// Disable output
HB_Disable();
out_state = O_FAULTED;
break;
};
//Do target adjustment logic
if(steady_state >= 10)
{
//Calculate average HB voltage
hb_volt_sum /= 11;
// Calculate feedback adjusted HB output
int32_t error = hb_volt_sum - (int32_t)target_output;
int32_t temp = (int32_t)adj_target - error;
// Limit to 16bits
if(temp<=0) adj_target = 0;
else if(temp >= 0x0000FFFF) adj_target = 0xFFFF;
else adj_target = (uint16_t)temp;
steady_state = 0;
hb_volt_sum = 0;
}
else
{
hb_volt_sum += meas->hb_voltage;
steady_state++;
}
// Closed loop or open loop target set
if(new_target)
{
// Set open-loop HB output
HB_SetTarget(target_output);
adj_target = target_output;
steady_state = 0;
new_target = 0;
hb_volt_sum = 0;
}
else
{
HB_SetTarget(adj_target);
}
// Update output
HB_UpdateOutput(meas->supply_voltage);
break;
case O_FAULTED:
if(!active_fault)
{
//Return to normal state
HB_Enable();
out_state = O_ACTIVE;
}
break;
default: //OFF
if(HB_IsEnabled()) HB_Disable();
break;
}
}
void Output_SetTarget(uint16_t voltage)
{
if(voltage > MAX_OUTPUT_VOLTAGE) voltage = MAX_OUTPUT_VOLTAGE;
else if((voltage > 0)&&(voltage < MIN_OUTPUT_VOLTAGE)) voltage = MIN_OUTPUT_VOLTAGE;
if(voltage != target_output) new_target = 1;
target_output = voltage;
}
outState_t Output_GetOutputState(void)
{
return out_state;
}
/**** Private function definitions ****/
static void Process_Warnings(analog_t* meas)
{
// Supply UVLO and OVP
if((meas->supply_voltage > LIM_SUPPLY_OVP)||(meas->supply_voltage < LIM_SUPPLY_UVLO)) warnings.supply_voltage.active = 1;
else warnings.supply_voltage.active = 0;
// Supply OCP
if(meas->supply_current > LIM_SUPPLY_OCP) warnings.supply_current.active = 1;
else warnings.supply_current.active = 0;
// Supply OPP
if(meas->supply_power > LIM_SUPPLY_OPP) warnings.supply_power.active = 1;
else warnings.supply_power.active = 0;
// Halfbridge output conditions
// Output Target mismatch
if(HB_IsOutputMatch(meas->hb_voltage, LIM_OUTPUT_MATCH) == 0) warnings.output_mismatch.active = 1;
else warnings.output_mismatch.active = 0;
// Output OCP
if((HB_IsLowOn())&&(meas->hb_currnet > LIM_OUTPUT_OCP)) warnings.output_current.active = 1;
else warnings.output_current.active = 0;
// Output OVP
if((HB_IsLowOn())&&(meas->hb_voltage > LIM_OUTPUT_OVP)) warnings.output_voltage.active = 1;
else warnings.output_voltage.active = 0;
// Output OPP
if((HB_IsEnabled())&&(meas->hb_power > LIM_OUTPUT_OPP)) warnings.output_power.active = 1;
else warnings.output_power.active = 0;
// Output Short
if((HB_IsEnabled())&&(meas->hb_resistance < LIM_OUTPUT_SHORT)) warnings.output_short.active = 1;
else warnings.output_short.active = 0;
// Output Open - Load loss
if((HB_IsEnabled())&&(meas->hb_resistance > LIM_OUTPUT_OPEN)) warnings.output_open.active = 1;
else warnings.output_open.active = 0;
ProcessWarningTime(&warnings.supply_voltage);
ProcessWarningTime(&warnings.supply_current);
ProcessWarningTime(&warnings.supply_power);
ProcessWarningTime(&warnings.output_mismatch);
ProcessWarningTime(&warnings.output_voltage);
ProcessWarningTime(&warnings.output_current);
ProcessWarningTime(&warnings.output_power);
ProcessWarningTime(&warnings.output_open);
ProcessWarningTime(&warnings.output_short);
}
static uint8_t Process_Faults(void)
{
// Check warnings to escalate to fault
// Supply OCP
if(warnings.supply_current.time > OCP_WARNING_LIMIT) faults.supply_ocp = 1;
// Output OCP
if(warnings.output_current.time > OCP_WARNING_LIMIT) faults.output_ocp = 1;
// Output short
if(warnings.output_short.time > SHORT_WARNING_LIMIT) faults.output_short = 1;
switch(fault_state)
{
case F_ACTIVE:
// Check if fault still active
if(!isFaultWarningActive(&warnings, &faults))
{
// Fault cause ended, go to cooldown
cooldown_timer = COOLDOWN_TIME;
fault_state = F_COOLDOWN;
};
break;
case F_COOLDOWN:
// Check if fault reoccurs
if(isFaultWarningActive(&warnings, &faults))
{
fault_state = F_ACTIVE;
break;
};
// Wait for cooldown timer, reset fault flags
if(cooldown_timer) cooldown_timer--;
else
{
ResetFaults(&faults);
fault_state = F_NONE;
}
break;
default: //NONE
// Check for new faults
if(isAnyFaultActive(&faults))
{
// Start fault process
fault_state = F_ACTIVE;
};
break;
}
if(fault_state != F_NONE) return 1;
else return 0;
}
static void ProcessWarningTime(warn_t* w)
{
if((w->active)&&(w->time < 0xFF)) w->time++;
else if(w->active == 0) w->time = 0;
}
static uint8_t isAnyFaultActive(faults_t* f)
{
if(f->supply_uvlo) return 1;
if(f->supply_ovp) return 1;
if(f->supply_ocp) return 1;
if(f->supply_opp) return 1;
if(f->output_ovp) return 1;
if(f->output_ocp) return 1;
if(f->output_opp) return 1;
if(f->output_open) return 1;
if(f->output_short) return 1;
return 0;
}
static uint8_t isFaultWarningActive(warnings_t* w, faults_t* f)
{
if((f->supply_uvlo) && (w->supply_voltage.active)) return 1;
if((f->supply_ovp) && (w->supply_voltage.active)) return 1;
if((f->supply_ocp) && (w->supply_current.active)) return 1;
if((f->supply_opp) && (w->supply_power.active) ) return 1;
if((f->output_ovp) && (w->output_voltage.active)) return 1;
if((f->output_ocp) && (w->output_current.active)) return 1;
if((f->output_opp) && (w->output_power.active) ) return 1;
if((f->output_open) && (w->output_open.active) ) return 1;
if((f->output_short) && (w->output_short.active) ) return 1;
return 0;
}
static void ResetFaults(faults_t* f)
{
f->supply_uvlo = 0;
f->supply_ovp = 0;
f->supply_ocp = 0;
f->supply_opp = 0;
f->output_ovp = 0;
f->output_ocp = 0;
f->output_opp = 0;
f->output_open = 0;
f->output_short = 0;
}

30
firmware/drivers/output.h Normal file
View File

@@ -0,0 +1,30 @@
#ifndef OUTPUT_DRV_H_
#define OUTPUT_DRV_H_
/**** Includes ****/
#include <avr/io.h>
#include "../devices/analog.h"
#include "../devices/halfbridge.h"
/**** Public definitions ****/
typedef enum {
F_NONE,
F_ACTIVE,
F_COOLDOWN
} faultState_t;
typedef enum {
O_OFF,
O_ACTIVE,
O_FAULTED
} outState_t;
/**** Public function declarations ****/
void Output_Enable(void);
void Output_Update(analog_t* meas);
void Output_SetTarget(uint16_t voltage);
outState_t Output_GetOutputState(void);
#endif /* OUTPUT_DRV_H_ */