Files
TX/source/sys_chk.c
Brent Perteet 658cedfa3b Added software timers
Accessory state machine framework functional
2025-06-18 17:53:00 -05:00

407 lines
7.9 KiB
C

#include "arm_math.h"
#include "fsl_gpio.h"
#include "spi.h"
#include "utils.h"
#include "battery.h"
#include "main.h"
#include "display.h"
#include "timer.h"
#include "lcd.h"
#include "mode.h"
#include "ports.h"
#include "utils.h"
#include "safety_key.h"
#include "sys_chk.h"
#include "pwr_level.h"
#include "init.h"
#include "frq.h"
#include "adc.h"
#include "taps.h"
#include "amps.h"
#include "stdbool.h"
#include "System/system.h"
extern uint8_t Task,Cur_Mode,Power_Level,catch_up_flag;
extern uint8_t Over_Voltage_Flag,Bat_Type,Suspend_Step_Chk;
extern uint16_t Pot_Value_CLAMP_AB[];
extern uint16_t Pot_Value_AB[],Over_Voltage_tmr,ByPass_tmr;
extern uint8_t Dds_Pot_Val[]; // 2 byte Data for SPI
extern uint16_t Vchktmr, Pot_Value[];
//extern float Requested_Current[];
extern uint8_t Port_State[];
uint8_t Ports_Cleared_Flag,step_count;
extern uint8_t frequency,Over_Current_Flag, Taps_Flag;
extern FREQUENCY_t freqArray[FREQ_MAX_NUM];
extern float32_t Watts_Filt;
extern SYSTEM_DATA_t sys;
uint16_t Power_tmr, Display_warning_tmr;
void System_Check()
{
if(freqArray[frequency].frequency1 <= MAX_DTYPE)
{
Check_Over_Power(); // check for excessive power setting
}
else
{
if(step_count >= 10)
Check_Over_Power();
}
// Check_Power_Monitor(); // Check for persistent condition longer than 3 seconds
// Vchktmr = 0;
Check_Live_Voltage(); // Check Live voltage external source
// Safety_Check(); redundant code
Check_Over_Voltage(); // Check Direct Connect Over voltage
Check_Clamp_OverVoltage();
Check_Over_Current(); // Check if current > 1 Amp 9/4/24 temp
// Check_PSU_Short(); // Checks if PSU rail is short
//######## temporarily removed 9/3/24 for debugging
// if(Watts_Filt > Get_Power_Limit())
// Check_Over_Power(); // check for excessive power setting
// else
// {
if(Cur_Mode != BROADCAST && step_count < 10)
// Check_Selected_Current(); //Checks for current output > Selected Value
Chk_Selected_Current2();
// }
//#########
Check_Trickle_Current();
Chk_Bat_Level();
#if 1 //## 9/24/24
if(Short_Circuit_Chk()) // Check for short in High gain.
{
Over_Current_Flag = true;
Power_Level = 0;
Cut_Signal_To_Min();
// Update_Amp_Pot();
}
#endif
}
void Safety_Check(void)
{
Check_Live_Voltage();
if(Task == SAFETY_TASK)
{
Task = SAFETY_TASK;
LCD_Clear();
while(1)
{
safe_key();
Display_Update();
Delay_Ticks(10);
}
}
}
void Normal_Bypass_Chk(void)
{
if(!sys.status[OVERVOLTAGE])
Select_Bypass(ON);
}
void Check_For_Open_Circuit(void)
{
if(Open_Circuit_Chk()) // if open Circuit
{ // Switch blocking Cap ON
Select_Bypass(OFF);
ByPass_tmr = DELAY_5S;
}
else if (sys.adc.V_CHK < MAX_BYPASS_VOLTS2) // else if NOT HVP
{ // Switch Blocking cap off
Delay_Ticks(10); // Check again after delay
if (sys.adc.V_CHK < MAX_BYPASS_VOLTS2 && ByPass_tmr == 0)
{
Select_Bypass(ON);
step_count = 0;
Display_warning_tmr = DELAY_5S; // Allow voltage surge to drop before displaying warning
}
}
if (sys.adc.V_CHK > MAX_BYPASS_VOLTS2)
sys.status[OVERVOLTAGE] = true;
else
sys.status[OVERVOLTAGE] = false; // added 1/6/25
if (Compare_Voltage(sys.adc.V_CHK, MAX_OP_VOLTS)) //Potentially fatal voltage
{
Select_Estop(ISOLATED); // Fault condition disable output
Select_Bypass(OFF); // Force into blocked state.
Task = SAFETY_TASK;
}
}
bool Open_Circuit_Chk(void)
{
if(sys.adc.I_OUT_FastFilt <= OPEN_CIRCUIT_CURRENT)
return(true);
else
return(false);
}
void Check_For_Connected_Volts(void)
{
Vchktmr = 0;
// Check_Live_Voltage(); // Check Live voltage external source
Safety_Check();
if(sys.status[OVERVOLTAGE])
Select_Bypass(OFF);
else
{
Select_Bypass(ON);
//Scale down standby pot value for frequency: compensate for blocking cap
float32_t scale = 0.6 * freqArray[frequency].frequency1 / 20000.0 + 0.4;
if(scale > 1.0)
{
scale = 1.0;
}
Dds_Pot_Val[0] = 0; // address
Dds_Pot_Val[1] = (uint8_t)(scale * Dds_Pot_Val[1]);
SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE);
Delay_Ticks(50);
Taps_Flag = false;
Check_Taps(); // Check for optimum Taps before making jump
Delay_Ticks(30);
#if 0
for(uint32_t i = 0; i < 10; i++)
{
Current1[i] = sys.adc.I_OUT_FastFilt;
Delay_Ticks(10); //100mS to stabilize measurement after cap bypassed
}
uint32_t moo = 0;
moo++; //place for breakpoint
#endif
}
// if((ACCY_GetConnectedAccessory(1) != ID_CLAMP) && (ACCY_GetConnectedAccessory(2) != ID_CLAMP))
if((!Check_For_Clamp()))
{
Request_Current_Change(); // Normal running no clamp
}
}
void Check_Trickle_Current(void)
{
float32_t x;
uint8_t y,z;
if(Power_Level == 0 && sys.adc.I_OUT_SlowFilt > 0.050)
{
z = Dds_Pot_Val[1];
x = 0.050 /sys.adc.I_OUT_SlowFilt;
y = (Dds_Pot_Val[1]*x);
if (y < 3)
y=3;
Dds_Pot_Val[1] = y;
Dds_Pot_Val[0] = 0; // address
// Adjust_Pot_Val();
SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE);
// Pot_Value[0] = 3;
// Init_Amplitude();
}
}
void Check_Selected_Current(void)
{
if(!Check_For_Clamp())
{
if((!Suspend_Step_Chk) && (!sys.status[OVERVOLTAGE]))
{
if(Demand_Check() && Power_Level > 0) //
{
if(!Check_Maxed_Out())
{
Request_Current_Change();
catch_up_flag = false;
step_count++;
}
}
}
}
}
bool Demand_Check(void)
{
float32_t current,num;
uint8_t xval;
xval = Dds_Pot_Val[1];
// num = Requested_Current[Power_Level] * 1.2; 3/8/24
num = Requested_Current(Bat_Type);
current = sys.adc.I_OUT_SlowFilt; //
// if(current > (Requested_Current[Power_Level] * 1.2) && Power_Level > 0) 3/8/24
if(current > (num * 1.1) && Power_Level > 0)
return(true);
else
{//######
// if(current < (Requested_Current[Power_Level] * 0.8))
if(current < (num * 0.9) && Power_Level > 0)
return(true);
else
return(false);
}
}
void Chk_Selected_Current2(void)
{
if(!Check_For_Clamp() && (!Suspend_Step_Chk) && (!sys.status[OVERVOLTAGE]))
{
if(sys.adc.I_OUT_SlowFilt > (Requested_Current(Bat_Type) * 1.05) || (Watts_Filt > Get_Power_Limit()))
{
Request_Current_Change(); // reduce current
catch_up_flag = false;
step_count++;
}
else
{
if (sys.adc.I_OUT_SlowFilt < (Requested_Current(Bat_Type) * 0.95))
{
if(!Check_Maxed_Out())
{
Request_Current_Change(); //increase current
catch_up_flag = false;
step_count++;
}
}
}
}
}
void Check_For_Usb(void)
{
if(GPIO_PinRead(GPIO,1,6))
Clear_All_Bits();
}
void Clear_All_Bits(void)
{
//clear shift registers to known state
Port_State[MID_SR] = USB_STATE_MID; //
Port_State[BOTTOM_SR] = USB_STATE_BOT; //
Port_State[TOP_SR] = USB_STATE_TOP;
SPI0_SendBytes(Port_State, 3, EXPANDER); // Update shift register
Delay_Ticks(1);
Send_Ctrl_Word(SLP_CTRL_WRD2,SIGNAL); // Switch signal off
Ports_Cleared_Flag = true;
}
bool Short_Circuit_Chk(void)
{
float32_t x;
if((Port_State[MID_SR] & I_GAIN) > 0)
{ // High Gain
if(sys.adc.I_OUT_FastFilt > 0.05 && sys.adc.V_OUT_FastFilt < 1 && Power_Level > 1)
return(true);
else
return(false);
}
else
{ // Low GAIN
x = Get_Max_Current();
if(sys.adc.I_OUT_FastFilt * 1000 > x)
return(true);
else
return(false);
}
}
bool Check_Maxed_Out(void)
{
float32_t x,Power_Limit,Current_Request;
if (freqArray[frequency].frequency1 < MAX_DTYPE)
Power_Limit = sys.maxPowerLimit;
else
Power_Limit = 1.0;
x = Get_Max_Current(); // HF 250mA LF 950mA
Current_Request = Requested_Current(Bat_Type);
if(sys.adc.I_OUT_FastFilt * 1000 > x)
return(true);
else if (sys.adc.V_OUT > (MAX_DC_VOLTAGE * 0.95))
return(true);
else if (Watts_Filt > (Power_Limit * 0.95))
return(true);
else if ((Current_Request * sys.adc.V_OUT_SlowFilt) > Power_Limit)
return (true);
else
return(false);
}
void Check_Power_Monitor(void)
{
#define MAX_PWR_TIME 300 // 3 Seconds
if(Watts_Filt > Get_Power_Limit() * 1.2)
{
Power_tmr++;
if(Power_tmr > MAX_PWR_TIME)
{
Power_Level = 0;
Cut_Signal_To_Min();
}
else
Power_tmr = 0;
}
}