Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/locking #47

Merged
merged 2 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions ccs/acOBC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,19 +308,13 @@ static void triggerActions()
//Unlock connector when coming here from any other state
if (Param::GetInt(Param::LockState) == LOCK_CLOSED && Param::GetBool(Param::AllowUnlock))//only unlock if allowed and lock is locked
{
if(Param::GetInt(Param::ActuatorTest) == 0)
{
hardwareInterface_triggerConnectorUnlocking();
}
hardwareInterface_triggerConnectorUnlocking();
}
break;
case OBC_LOCK:
if (Param::GetInt(Param::LockState) == LOCK_OPEN)//only trigger is lock is open
{
if(Param::GetInt(Param::ActuatorTest) == 0)
{
hardwareInterface_triggerConnectorLocking();
}
hardwareInterface_triggerConnectorLocking();
}
break;
case OBC_PAUSE:
Expand Down
48 changes: 14 additions & 34 deletions ccs/hardwareInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#define CP_DUTY_VALID_TIMER_MAX 3 /* after 3 cycles with 30ms, we consider the CP connection lost, if
we do not see PWM interrupts anymore */
#define CONTACTOR_CYCLES_FOR_FULL_PWM (33/5) /* 33 cycles per second. ~200ms should be more than enough, see https://github.com/uhi22/ccs32clara/issues/22 */
#define CONTACTOR_CYCLES_SEQUENTIAL (33/3) /* ~300ms delay from one contactor to the other, to avoid high peak current consumption. https://github.com/uhi22/ccs32clara/issues/22 */
#define CONTACTOR_CYCLES_SEQUENTIAL (33/3) /* ~300ms delay from one contactor to the other, to avoid high peak current consumption. https://github.com/uhi22/ccs32clara/issues/22 */

static float cpDuty_Percent;
static uint8_t cpDutyValidTimer;
Expand All @@ -14,12 +14,10 @@ static int8_t ContactorOnTimer1, ContactorOnTimer2;
static uint16_t dutyContactor1, dutyContactor2;
static uint8_t LedBlinkDivider;
static LockStt lockRequest;
static LockStt lockState;
static LockStt lockTarget = LOCK_UNKNOWN;
static LockStt lockState = LOCK_OPEN; //In case we have no feedback we assume the lock is open
static uint16_t lockTimer;
static bool actuatorTestRunning = false;

static uint8_t actuatorTest_lockUnlockState; /* status of the actuator test for connector locking/unlocking */
#define ACTUTEST_STATUS_IDLE 0
#define ACTUTEST_STATUS_LOCKING_TRIGGERED 1
#define ACTUTEST_STATUS_UNLOCKING_TRIGGERED 2
Expand Down Expand Up @@ -362,26 +360,20 @@ static void hwIf_handleLockRequests()
}
else //lock drive without feedback
{
pwmNeg = 0;
pwmPos = CONTACT_LOCK_PERIOD;
/* connector lock just time-based, without evaluating the feedback */
if (lockRequest == LOCK_OPEN && lockTarget == LOCK_UNKNOWN)
if (lockRequest == LOCK_OPEN && lockState != LOCK_OPEN)
{
addToTrace(MOD_HWIF, "unlocking the connector");
//addToTrace(MOD_HWIF, "unlocking the connector");
Param::SetInt(Param::LockState, LOCK_OPENING);
hardwareInteface_setHBridge(pwmNeg, pwmPos);
lockTimer = Param::GetInt(Param::LockRunTime) / 30; /* in 30ms steps */
lockTarget = LOCK_OPEN;
lockRequest = LOCK_UNKNOWN;
lockTimer = lockTimer == 0 ? Param::GetInt(Param::LockRunTime) / 30 : lockTimer; /* in 30ms steps */
}
if (lockRequest == LOCK_CLOSED && lockTarget == LOCK_UNKNOWN)
if (lockRequest == LOCK_CLOSED && lockState != LOCK_CLOSED)
{
addToTrace(MOD_HWIF, "locking the connector");
//addToTrace(MOD_HWIF, "locking the connector");
Param::SetInt(Param::LockState, LOCK_CLOSING);
hardwareInteface_setHBridge(pwmPos, pwmNeg);
lockTimer = Param::GetInt(Param::LockRunTime) / 30; /* in 30ms steps */
lockTarget = LOCK_CLOSED;
lockRequest = LOCK_UNKNOWN;
lockTimer = lockTimer == 0 ? Param::GetInt(Param::LockRunTime) / 30 : lockTimer; /* in 30ms steps */
}
if (lockTimer>0)
{
Expand All @@ -391,9 +383,8 @@ static void hwIf_handleLockRequests()
{
/* if the time is expired, we turn off the lock motor and report the new state */
hardwareInteface_setHBridge(0, 0);
Param::SetInt(Param::LockState, lockTarget);
lockState = lockTarget;
lockTarget = LOCK_UNKNOWN;
lockState = lockRequest;
Param::SetInt(Param::LockState, lockState);
addToTrace(MOD_HWIF, "finished connector (un)locking");
}
}
Expand Down Expand Up @@ -495,46 +486,35 @@ static void ActuatorTest()
switch (Param::GetInt(Param::ActuatorTest))
{
case TEST_CLOSELOCK:
if (actuatorTest_lockUnlockState!=ACTUTEST_STATUS_LOCKING_TRIGGERED) {
hardwareInterface_triggerConnectorLocking();
actuatorTest_lockUnlockState = ACTUTEST_STATUS_LOCKING_TRIGGERED;
} /* else: locking was already triggered, do not trigger the same again, to avoid permanent actuation. */
hardwareInterface_triggerConnectorLocking();
Param::SetInt(Param::ActuatorTest, TEST_NONE); //Make sure we only trigger the test once
break;
case TEST_OPENLOCK:
if (actuatorTest_lockUnlockState!=ACTUTEST_STATUS_UNLOCKING_TRIGGERED) {
hardwareInterface_triggerConnectorUnlocking();
actuatorTest_lockUnlockState = ACTUTEST_STATUS_UNLOCKING_TRIGGERED;
} /* else: unlocking was already triggered, do not trigger the same again, to avoid permanent actuation. */
hardwareInterface_triggerConnectorUnlocking();
Param::SetInt(Param::ActuatorTest, TEST_NONE); //Make sure we only trigger the test once
break;
case TEST_CONTACTOR:
hardwareInterface_setPowerRelayOn();
actuatorTest_lockUnlockState = ACTUTEST_STATUS_IDLE;
break;
case TEST_STATEC:
hardwareInterface_setStateC();
actuatorTest_lockUnlockState = ACTUTEST_STATUS_IDLE;
break;
case TEST_LEDGREEN:
hardwareInterface_setRGB(2);
actuatorTest_lockUnlockState = ACTUTEST_STATUS_IDLE;
break;
case TEST_LEDRED:
hardwareInterface_setRGB(1);
actuatorTest_lockUnlockState = ACTUTEST_STATUS_IDLE;
break;
case TEST_LEDBLUE:
hardwareInterface_setRGB(4);
actuatorTest_lockUnlockState = ACTUTEST_STATUS_IDLE;
break;
default: /* all cases including TEST_NONE are stopping the actuator test */
blTestOngoing = false;
actuatorTest_lockUnlockState = ACTUTEST_STATUS_IDLE;
if (actuatorTestRunning) {
/* If the actuator test is just ending, then perform a clean up:
Return everything to default state. LEDs are reset anyway as soon as we leave test mode. */
hardwareInterface_setPowerRelayOff();
hardwareInterface_setStateB();
hardwareInterface_triggerConnectorUnlocking();
actuatorTestRunning = false;
} else {
/* actuator test was not ongoing and is not requested -> nothing to do */
Expand Down
17 changes: 7 additions & 10 deletions ccs/wakecontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

#include "ccs32_globals.h"

uint8_t wakecontrol_timer;
uint8_t allowSleep;
static uint8_t wakecontrol_timer;
static 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 */
Expand All @@ -15,7 +15,7 @@ uint8_t wakecontrol_isPpMeasurementInvalid(void) {
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. */
return 1; /* no PP measurement possible, because corrupted by KEEP_POWER_ON. */
}

void wakecontrol_mainfunction(void) /* runs in 100ms cycle */
Expand All @@ -33,15 +33,12 @@ void wakecontrol_mainfunction(void) /* runs in 100ms cycle */

//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)
{
if ((Param::GetInt(Param::WakeupPinFunc) & WAKEUP_ONVALIDPP) == 0 || !ppValid)
{
allowSleep = 1;
}
allowSleep = !CanActive;
}
}

if (!allowSleep) {
DigIo::keep_power_on.Set(); /* Keep the power on */
wakecontrol_timer=WAKECONTROL_TIMER_MAX;
Expand All @@ -63,7 +60,7 @@ void wakecontrol_mainfunction(void) /* runs in 100ms cycle */
/* just in the middle of the counting */
wakecontrol_timer--;
}

}
}

Expand Down
2 changes: 1 addition & 1 deletion include/param_prj.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
VALUE_ENTRY(StopReason, STOPREASONS, 2017 ) \
VALUE_ENTRY(checkpoint, "dig", 2015 ) \
VALUE_ENTRY(CanWatchdog, "dig", 2016 ) \
VALUE_ENTRY(CanAwake, OFFON, 2032 ) \
VALUE_ENTRY(CanAwake, OFFON, 2032 ) \
VALUE_ENTRY(ButtonPushed, OFFON, 2033 ) \
VALUE_ENTRY(cpuload, "%", 2094 )

Expand Down
20 changes: 9 additions & 11 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,7 @@ static void Ms100Task(void)
}

//CAN bus a sleep !!!to decide
if(Param::GetInt(Param::CanWatchdog) < (CAN_TIMEOUT-10))
{
Param::SetInt(Param::CanAwake,1);
}
else
{
Param::SetInt(Param::CanAwake,0);
}
Param::SetInt(Param::CanAwake, (rtc_get_counter_val() - can->GetLastRxTimestamp()) < 200);
wakecontrol_mainfunction();
canMap->SendAll();
}
Expand Down Expand Up @@ -178,6 +171,8 @@ static void SetMacAddress()
/** This function is called when the user changes a parameter */
void Param::Change(Param::PARAM_NUM paramNum)
{
static bool enableReceived = false;

switch (paramNum)
{
case Param::CanSpeed:
Expand All @@ -190,12 +185,14 @@ void Param::Change(Param::PARAM_NUM paramNum)
//Charge current is the single most important item that must be constantly updated
//by the BMS or VCU. Whenever it is updated we feed the dog
//When it is no longer updated the dog will bark and stop the charge session
Param::SetInt(Param::CanWatchdog, 0);
if (enableReceived)
Param::SetInt(Param::CanWatchdog, 0);
enableReceived = false; //this will be set back to true once enable is received again
break;
case Param::enable:
//by the BMS or VCU. Whenever it is updated we feed the dog
//by the BMS or VCU. Whenever this AND ChargeCurrent is updated we feed the dog
//When it is no longer updated the dog will bark and stop the charge session
Param::SetInt(Param::CanWatchdog, 0);
enableReceived = true;
break;
default:
//Handle general parameter changes here. Add paramNum labels for handling specific parameters
Expand Down Expand Up @@ -272,6 +269,7 @@ extern "C" int main(void)

//backward compatibility, version 4 was the first to support the "stream" command
Param::SetInt(Param::version, 4);
Param::SetInt(Param::LockState, LOCK_OPEN); //Assume lock open
Param::Change(Param::PARAM_LAST); //Call callback one for general parameter propagation
//Now all our main() does is running the terminal
//All other processing takes place in the scheduler or other interrupt service routines
Expand Down
2 changes: 2 additions & 0 deletions stm32-ccs.cbp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
<Unit filename="ccs/temperatures.h" />
<Unit filename="ccs/udpChecksum.cpp" />
<Unit filename="ccs/udpChecksum.h" />
<Unit filename="ccs/wakecontrol.cpp" />
<Unit filename="ccs/wakecontrol.h" />
<Unit filename="exi/BitInputStream.c">
<Option compilerVar="CC" />
</Unit>
Expand Down