From 9f375243dd288e9897270a8d0c7dd3bd969770bd Mon Sep 17 00:00:00 2001 From: lincomatic Date: Thu, 19 Jan 2017 16:32:19 -0800 Subject: [PATCH] AUTH_LOCK fix + $G0 --- firmware/open_evse/CHANGELOG | 6 ++- firmware/open_evse/J1772EvseController.cpp | 59 +++++++++++++++------- firmware/open_evse/J1772EvseController.h | 31 ++++++++++-- firmware/open_evse/open_evse.h | 2 +- firmware/open_evse/rapi_proc.cpp | 17 ++++++- firmware/open_evse/rapi_proc.h | 4 ++ 6 files changed, 94 insertions(+), 25 deletions(-) diff --git a/firmware/open_evse/CHANGELOG b/firmware/open_evse/CHANGELOG index 24cb0ecf..9312d30d 100644 --- a/firmware/open_evse/CHANGELOG +++ b/firmware/open_evse/CHANGELOG @@ -1,7 +1,11 @@ Change Log -20170118 +vD4.6.0 20170119 SCL - get rid of superfluous loopcnt arg in ReadPilot() +- fix problem with AUTH_LOCK - Tesla didn't like PWM when locked. Turn + off PWM when locked +- added AUTH_LOCK_REG code - for hardware auth lock via hardware pin +- added RAPI $G0 - get EV connect state vD4.5.1 20161214 SCL - minor #ifdef code cleanup diff --git a/firmware/open_evse/J1772EvseController.cpp b/firmware/open_evse/J1772EvseController.cpp index 611c8ba6..ff963176 100644 --- a/firmware/open_evse/J1772EvseController.cpp +++ b/firmware/open_evse/J1772EvseController.cpp @@ -170,10 +170,11 @@ void J1772EVSEController::SaveSettings() #ifdef AUTH_LOCK -void J1772EVSEController::AuthLock(int8_t tf) +void J1772EVSEController::AuthLock(uint8_t tf) { - if (tf) m_bVFlags |= ECVF_AUTH_LOCKED; - else m_bVFlags &= ~ECVF_AUTH_LOCKED; + if (tf) setVFlags(ECVF_AUTH_LOCKED); + else clrVFlags(ECVF_AUTH_LOCKED); + Update(1); g_OBD.Update(OBD_UPD_FORCE); } #endif // AUTH_LOCK @@ -305,12 +306,11 @@ void J1772EVSEController::HardFault() #endif // MENNEKES_LOCK while (1) { ProcessInputs(); // spin forever or until user resets via menu - // if we're in P12 state, we can recover from the hard fault when EV + // if pilot not in N12 state, we can recover from the hard fault when EV // is unplugged - if (m_Pilot.GetState() == PILOT_STATE_P12) { - uint16_t plow,phigh; - ReadPilot(&plow,&phigh); - if (phigh >= m_ThreshData.m_ThreshAB) { + if (m_Pilot.GetState() != PILOT_STATE_N12) { + ReadPilot(); // update EV connect state + if (!EvConnected()) { // EV disconnected - cancel fault m_EvseState = EVSE_STATE_UNKNOWN; break; @@ -934,6 +934,7 @@ void J1772EVSEController::Init() #endif m_bVFlags = ECVF_DEFAULT; + m_bVFlags2 = ECVF2_DEFAULT; #ifdef GFI m_GfiRetryCnt = 0; m_GfiTripCnt = eeprom_read_byte((uint8_t*)EOFS_GFI_TRIP_CNT); @@ -1024,8 +1025,16 @@ void J1772EVSEController::ReadPilot(uint16_t *plow,uint16_t *phigh) } } - *plow = pl; - *phigh = ph; + if (m_Pilot.GetState() != PILOT_STATE_N12) { + // can determine connected state only if not -12VDC + if (ph >= m_ThreshData.m_ThreshAB) ClrEvConnected(); + else SetEvConnected(); + } + + if (plow) { + *plow = pl; + *phigh = ph; + } } @@ -1036,7 +1045,7 @@ void J1772EVSEController::ReadPilot(uint16_t *plow,uint16_t *phigh) //Positive Voltage, State C 5.48 6.00 6.49 //Positive Voltage, State D 2.62 3.00 3.25 //Negative Voltage - States B, C, D, and F -11.40 -12.00 -12.60 -void J1772EVSEController::Update() +void J1772EVSEController::Update(uint8_t forcetransition) { uint16_t plow; uint16_t phigh = 0xffff; @@ -1048,9 +1057,10 @@ void J1772EVSEController::Update() return; } else if (m_EvseState == EVSE_STATE_SLEEPING) { + ReadPilot(&plow,&phigh); // always read so we can update EV connect state, too + int8_t cancelTransition = 1; if (chargingIsOn()) { - ReadPilot(&plow,&phigh); // wait for pilot voltage to go > STATE C. This will happen if // a) EV reacts and goes back to state B (opens its contacts) // b) user pulls out the charge connector @@ -1072,8 +1082,8 @@ void J1772EVSEController::Update() } #if defined(TIME_LIMIT) || defined(CHARGE_LIMIT) else if (LimitSleepIsSet()) { - ReadPilot(&plow,&phigh); - if (phigh >= m_ThreshData.m_ThreshAB) { + ReadPilot(); // update EV connect state + if (!EvConnected()) { // if we went into sleep due to time/charge limit met, then // automatically cancel the sleep when the car is unplugged cancelTransition = 0; @@ -1130,9 +1140,9 @@ void J1772EVSEController::Update() if (prevevsestate == EVSE_STATE_NO_GROUND) { // check to see if EV disconnected if (phigh == 0xffff) { - ReadPilot(&plow,&phigh); + ReadPilot(); } - if (phigh >= m_ThreshData.m_ThreshAB) { + if (!EvConnected()) { // EV disconnected - cancel fault m_EvseState = EVSE_STATE_UNKNOWN; return; @@ -1187,8 +1197,8 @@ void J1772EVSEController::Update() } else { // was already in GFI fault // check to see if EV disconnected - ReadPilot(&plow,&phigh); - if (phigh >= m_ThreshData.m_ThreshAB) { + ReadPilot(); // update EV connect state + if (!EvConnected()) { // EV disconnected - cancel fault m_EvseState = EVSE_STATE_UNKNOWN; m_Gfi.Reset(); @@ -1366,6 +1376,7 @@ if (TempChkEnabled()) { if (locked != (m_bVFlags & ECVF_AUTH_LOCKED)) { AuthLock(locked); g_OBD.Update(OBD_UPD_FORCE); + forcetransition = 1; } } #endif // AUTH_LOCK_REG @@ -1393,7 +1404,7 @@ if (TempChkEnabled()) { // state transition - if (m_EvseState != prevevsestate) { + if (forcetransition || (m_EvseState != prevevsestate)) { #ifdef MENNEKES_LOCK if (m_EvseState == MENNEKES_LOCK_STATE) { m_MennekesLock.Lock(); @@ -1420,7 +1431,17 @@ if (TempChkEnabled()) { } else if (m_EvseState == EVSE_STATE_B) { // connected chargingOff(); // turn off charging current +#ifdef AUTH_LOCK + // if locked, don't turn on PWM + if (AuthLockIsOn()) { + m_Pilot.SetState(PILOT_STATE_P12); + } + else { + m_Pilot.SetPWM(m_CurrentCapacity); + } +#else m_Pilot.SetPWM(m_CurrentCapacity); +#endif // AUTH_LOCK } else if (m_EvseState == EVSE_STATE_C) { m_Pilot.SetPWM(m_CurrentCapacity); diff --git a/firmware/open_evse/J1772EvseController.h b/firmware/open_evse/J1772EvseController.h index b5dcd4e1..cb7ada29 100644 --- a/firmware/open_evse/J1772EvseController.h +++ b/firmware/open_evse/J1772EvseController.h @@ -95,6 +95,12 @@ typedef uint8_t (*EvseStateTransitionReqFunc)(uint8_t prevPilotState,uint8_t cur #define ECVF_DEFAULT 0x00 #endif +// J1772EVSEController volatile m_bVFlags2 bits - not saved to EEPROM +#define ECVF2_EV_CONNECTED 0x01 // EV connected - valid only when pilot not N12 + +#define ECVF2_DEFAULT 0x00 + + class J1772EVSEController { J1772Pilot m_Pilot; #ifdef GFI @@ -141,6 +147,7 @@ class J1772EVSEController { #endif // ADVPWR uint16_t m_wFlags; // ECF_xxx uint8_t m_bVFlags; // ECVF_xxx + uint8_t m_bVFlags2; // ECVF2_xxx THRESH_DATA m_ThreshData; uint8_t m_EvseState; uint8_t m_PrevEvseState; @@ -188,6 +195,18 @@ class J1772EVSEController { void clrFlags(uint16_t flags) { m_wFlags &= ~flags; } + void setVFlags(uint8_t flags) { + m_bVFlags |= flags; + } + void clrVFlags(uint8_t flags) { + m_bVFlags &= ~flags; + } + void setVFlags2(uint8_t flags) { + m_bVFlags2 |= flags; + } + void clrVFlags2(uint8_t flags) { + m_bVFlags2 &= ~flags; + } #ifdef TIME_LIMIT uint8_t m_timeLimit; // minutes * 15 @@ -221,6 +240,7 @@ class J1772EVSEController { uint16_t GetFlags() { return m_wFlags; } uint8_t GetVFlags() { return m_bVFlags; } + uint8_t GetVFlags2() { return m_bVFlags2; } uint8_t GetState() { return m_EvseState; } @@ -393,7 +413,7 @@ class J1772EVSEController { void SetTimeLimit(uint8_t mind15) { m_timeLimit = mind15; } uint8_t GetTimeLimit() { return m_timeLimit; } #endif // TIME_LIMIT - void ReadPilot(uint16_t *plow,uint16_t *phigh); + void ReadPilot(uint16_t *plow=NULL,uint16_t *phigh=NULL); void Reboot(); #ifdef SHOW_DISABLED_TESTS void DisabledTest_P(PGM_P message); @@ -419,9 +439,14 @@ class J1772EVSEController { } uint8_t RelayIsClosed() { return m_bVFlags & ECVF_CHARGING_ON; } #ifdef AUTH_LOCK - void AuthLock(int8_t tf); - int8_t AuthLockIsOn() { return (int8_t)((m_bVFlags & ECVF_AUTH_LOCKED)?1:0); } + void AuthLock(uint8_t tf); + uint8_t AuthLockIsOn() { return m_bVFlags & ECVF_AUTH_LOCKED; } #endif // AUTH_LOCK + + void SetEvConnected() { setVFlags2(ECVF2_EV_CONNECTED); } + void ClrEvConnected() { clrVFlags2(ECVF2_EV_CONNECTED); } + // EvConnected value valid when pilot state not N12 + uint8_t EvConnected() { return m_bVFlags2 & ECVF2_EV_CONNECTED; } }; #ifdef FT_ENDURANCE diff --git a/firmware/open_evse/open_evse.h b/firmware/open_evse/open_evse.h index b350ccc2..192c220d 100644 --- a/firmware/open_evse/open_evse.h +++ b/firmware/open_evse/open_evse.h @@ -37,7 +37,7 @@ #else #include "WProgram.h" // shouldn't need this but arduino sometimes messes up and puts inside an #ifdef #endif // ARDUINO -#define VERSION "D4.5.1" +#define VERSION "D4.6.0" #include "Language_default.h" //Default language should always be included as bottom layer diff --git a/firmware/open_evse/rapi_proc.cpp b/firmware/open_evse/rapi_proc.cpp index bb43f98b..2ca37f8e 100644 --- a/firmware/open_evse/rapi_proc.cpp +++ b/firmware/open_evse/rapi_proc.cpp @@ -457,6 +457,21 @@ int EvseRapiProcessor::processCmd() case 'G': // get parameter switch(*s) { + case '0': // get EV connect state + { + uint8_t connstate; + if (g_EvseController.GetPilot()->GetState() == PILOT_STATE_N12) { + connstate = 2; // unknown + } + else { + if (g_EvseController.EvConnected()) connstate = 1; + else connstate = 0; + } + sprintf(buffer,"%d",(int)connstate); + } + bufCnt = 1; // flag response text output + rc = 0; + break; #ifdef TIME_LIMIT case '3': // get time limit sprintf(buffer,"%d",(int)g_EvseController.GetTimeLimit()); @@ -466,7 +481,7 @@ int EvseRapiProcessor::processCmd() #endif // TIME_LIMIT #if defined(AUTH_LOCK) && !defined(AUTH_LOCK_REG) case '4': // get auth lock - sprintf(buffer,"%d",(int)g_EvseController.AuthLockIsOn()); + sprintf(buffer,"%d",(int)g_EvseController.AuthLockIsOn() ? 1 : 0); bufCnt = 1; // flag response text output rc = 0; break; diff --git a/firmware/open_evse/rapi_proc.h b/firmware/open_evse/rapi_proc.h index f6da1e68..7e70b349 100644 --- a/firmware/open_evse/rapi_proc.h +++ b/firmware/open_evse/rapi_proc.h @@ -152,6 +152,10 @@ SV 0|1 - disable/enable vent required $SV 0*1D $SV 1*1E +G0 - get EV connect state + response: $OK connectstate + connectstate: 0=not connected, 1=connected, 2=unknown + -> connectstate is unknown when EVSE pilot is -12VDC G3 - get time limit response: $OK cnt cnt*15 = minutes