Skip to content

Commit

Permalink
fix for #40: ignore PP reading while keep_power_on is off, and cyclic…
Browse files Browse the repository at this point in the history
…ally turn it on
  • Loading branch information
uhi22 committed Oct 21, 2024
1 parent 93d0634 commit 7d06d49
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 28 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ OBJSL = main.o hwinit.o stm32scheduler.o params.o terminal.o terminal_prj.o \
param_save.o errormessage.o stm32_can.o canhardware.o canmap.o cansdo.o \
picontroller.o terminalcommands.o \
ipv6.o tcp.o \
connMgr.o modemFinder.o pevStateMachine.o temperatures.o acOBC.o \
connMgr.o modemFinder.o pevStateMachine.o temperatures.o acOBC.o wakecontrol.o \
hardwareInterface.o hardwareVariants.o pushbutton.o udpChecksum.o \
homeplug.o myHelpers.o qca7000.o \
appHandEXIDatatypesDecoder.o ByteStream.o EncoderChannel.o \
Expand Down
6 changes: 6 additions & 0 deletions ccs/acOBC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ static void evaluateProximityPilot(void)
float U_refAdc, U_pull, U_meas, Rv, R;
float iLimit;
uint8_t blPlugPresent;

if (wakecontrol_isPpMeasurementInvalid()) {
/* in case there are conditions which corrupt the PP resistance measurement, we discard the measurement,
and just live with the last valid value. Strategy: Better an old, valid value than a corrupted value. */
return;
}

/* Step 1: Provide the raw AD value (0 to 4095) for analysis purposes. */
Param::SetFloat(Param::AdcProximityPilot, temp);
Expand Down
1 change: 1 addition & 0 deletions ccs/ccs32_globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "hwinit.h"
#include "errormessage.h"
#include "my_string.h"
#include "wakecontrol.h"

/* temporary stubs */
#define publishStatus(x, y)
Expand Down
1 change: 1 addition & 0 deletions ccs/hardwareInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ extern int16_t hardwareInterface_getChargingTargetVoltage(void);
extern int16_t hardwareInterface_getChargingTargetCurrent(void);
extern void hardwareInterface_WakeupOtherPeripherals();
extern void hardwareInterface_LogTheCpPpPhysicalData();
extern uint8_t hardwareInterface_isPpMeasurementInvalid(void);
extern void hardwareInterface_cyclic(void);
extern void hardwareInterface_init(void);

Expand Down
75 changes: 75 additions & 0 deletions ccs/wakecontrol.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* wakecontrol: controlling the keep_power_on and similar things */

#include "ccs32_globals.h"

uint8_t wakecontrol_timer;
uint8_t allowSleep;

#define WAKECONTROL_TIMER_MAX 20 /* 20*100ms = 2s cycle time */
#define WAKECONTROL_TIMER_NEARLY_EXPIRED 5 /* 5*100ms = 500ms keep_power_on activation time */
#define WAKECONTROL_TIMER_END_OF_CYCLE__MEASUREMENT_ALLOWED 3 /* after turning the keep_power_on, 200ms time for
in-rush and adc sampling until measurement is considered as valid. */

uint8_t wakecontrol_isPpMeasurementInvalid(void) {
/* The PP measurement is not valid, if the voltage on the PP is pulled up by the wakeup path.
Discussion was here: https://openinverter.org/forum/viewtopic.php?p=75629#p75629 */
if (allowSleep==0) return 0; /* as long as we are not ready to sleep, the PP is valid. */
if (wakecontrol_timer<=WAKECONTROL_TIMER_END_OF_CYCLE__MEASUREMENT_ALLOWED) return 0; /* valid because cyclic pulsing and sufficient propagation delay */
return 1; /* no PP measurement possible, because corrupted by KEEP_POWER_ON. */
}

void wakecontrol_mainfunction(void) /* runs in 100ms cycle */
{
static uint32_t lastValidCp = 0;
if (Param::GetInt(Param::ControlPilotDuty) > 3)
lastValidCp = rtc_get_counter_val();

//If no frequency on CP we allow shut down after 10s
if ((rtc_get_counter_val() - lastValidCp) > 1000)
{
bool ppValid = Param::GetInt(Param::ResistanceProxPilot) < 2000;

bool CanActive = Param::GetInt(Param::CanAwake);

//WAKEUP_ONVALIDPP implies that we use PP for wakeup. So as long as PP is valid
//Do not clear the supply pin as that will skew the PP measurement and we can't turn off anyway
if(!CanActive)
{
if ((Param::GetInt(Param::WakeupPinFunc) & WAKEUP_ONVALIDPP) == 0 || !ppValid)
{
allowSleep = 1;
}
}
}

if (!allowSleep) {
DigIo::keep_power_on.Set(); /* Keep the power on */
wakecontrol_timer=WAKECONTROL_TIMER_MAX;
} else {
/* we could go to sleep. But there may be hardware situations, when we keep running, even if we turned-off the keep_power_on.
In this case, we need to set the keep_power_on to active, to allow correct PP resistance measurement. */
if (wakecontrol_timer==WAKECONTROL_TIMER_MAX) {
/* at the beginning of the "sleep allowed" phase, we try to shutdown */
DigIo::keep_power_on.Clear();
wakecontrol_timer--;
} else if (wakecontrol_timer==WAKECONTROL_TIMER_NEARLY_EXPIRED) {
/* we tried to shut down, but something keeps us running. So turn the keep_power_on active for a moment. */
DigIo::keep_power_on.Set();
wakecontrol_timer--;
} else if (wakecontrol_timer==0) {
/* timer is expired. Start a new cycle. */
wakecontrol_timer = WAKECONTROL_TIMER_MAX;
} else {
/* just in the middle of the counting */
wakecontrol_timer--;
}

}
}

void wakecontrol_init(void) {
DigIo::keep_power_on.Set(); /* Make sure board stays awake. */
allowSleep=0;
}


18 changes: 18 additions & 0 deletions ccs/wakecontrol.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* Interface header for wakecontrol.c */

/* Global Defines */

/* Global Variables */

/* Global Functions */
#ifdef __cplusplus
extern "C" {
#endif

extern uint8_t wakecontrol_isPpMeasurementInvalid(void);
extern void wakecontrol_mainfunction(void);
extern void wakecontrol_init(void);

#ifdef __cplusplus
}
#endif
30 changes: 3 additions & 27 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
#include "pushbutton.h"
#include "hardwareVariants.h"
#include "acOBC.h"

#include "wakecontrol.h"

#define PRINT_JSON 0

Expand All @@ -72,8 +72,6 @@ static CanSdo* canSdo;

static void Ms100Task(void)
{
static uint32_t lastValidCp = 0;

DigIo::led_alive.Toggle();
//The boot loader enables the watchdog, we have to reset it
//at least every 2s or otherwise the controller is hard reset.
Expand Down Expand Up @@ -141,29 +139,7 @@ static void Ms100Task(void)
{
Param::SetInt(Param::CanAwake,0);
}


if (Param::GetInt(Param::ControlPilotDuty) > 3)
lastValidCp = rtc_get_counter_val();

//If no frequency on CP shut down after 10s
if ((rtc_get_counter_val() - lastValidCp) > 1000)
{
bool ppValid = Param::GetInt(Param::ResistanceProxPilot) < 2000;

bool CanActive = Param::GetInt(Param::CanAwake);

//WAKEUP_ONVALIDPP implies that we use PP for wakeup. So as long as PP is valid
//Do not clear the supply pin as that will skew the PP measurement and we can't turn off anyway
if(!CanActive)
{
if ((Param::GetInt(Param::WakeupPinFunc) & WAKEUP_ONVALIDPP) == 0 || !ppValid)
{
DigIo::keep_power_on.Clear();
}
}
}

wakecontrol_mainfunction();
canMap->SendAll();
}

Expand Down Expand Up @@ -261,7 +237,7 @@ extern "C" int main(void)
write_bootloader_pininit(); //Instructs boot loader to initialize certain pins
gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON, AFIO_MAPR_TIM3_REMAP_FULL_REMAP | AFIO_MAPR_TIM2_REMAP_FULL_REMAP);

DigIo::keep_power_on.Set(); //Make sure board stays awake
wakecontrol_init(); //Make sure board stays awake

hardwareInterface_setStateB();
hw_evaluateHardwareVariants();
Expand Down

0 comments on commit 7d06d49

Please sign in to comment.