Skip to content

Commit

Permalink
Removed Prius MG1 detection, wasn't reliable
Browse files Browse the repository at this point in the history
Added support for CAN scaling < 1. But now you cannot scale up more than 32!
FOC: running offset calibration continously while idle
Custom charge PWM handling for Prius hardware
Bugfix in temp calc module when reaching lower limit of lookup table
  • Loading branch information
jsphuebner committed Jan 7, 2021
1 parent 249f00b commit 1aa6b4e
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 34 deletions.
2 changes: 1 addition & 1 deletion include/param_prj.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#define VER 4.96.R
#define VER 4.97.R

/* Entries must be ordered as follows:
1. Saveable parameters (id != 0)
Expand Down
4 changes: 3 additions & 1 deletion include/pwmgeneration.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class PwmGeneration
static void Run();
static uint16_t GetAngle();
static bool Tripped();
static void SetOpmode(int);
static void SetOpmode(int opmode);
static void SetAmpnom(s32fp amp);
static void SetFslip(s32fp fslip);
static void SetTorquePercent(s32fp torque);
Expand All @@ -46,6 +46,7 @@ class PwmGeneration
static void PwmInit();
static void EnableOutput();
static void DisableOutput();
static void EnableChargeOutput();
static uint16_t TimerSetup(uint16_t deadtime, bool activeLow);
static void AcHeatTimerSetup();
static s32fp ProcessCurrents();
Expand All @@ -59,6 +60,7 @@ class PwmGeneration
static s32fp GetCurrent(AnaIn& input, s32fp offset, s32fp gain);
static s32fp LimitCurrent();
static EdgeType CalcRms(s32fp il, EdgeType& lastEdge, s32fp& max, s32fp& rms, int& samples, s32fp prevRms);
static void RunOffsetCalibration();

static uint16_t pwmfrq;
static uint16_t angle;
Expand Down
2 changes: 1 addition & 1 deletion libopeninv
9 changes: 7 additions & 2 deletions src/hwinit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ HWREV detect_hw()
{
if (!is_existent(GPIOC, GPIO12)) //Olimex LED pin does not exist
return HW_BLUEPILL;
else if (is_floating(GPIOC, GPIO1))
return HW_PRIUSMG1;
/*else if (is_floating(GPIOC, GPIO1))
return HW_PRIUSMG1;*/
else if (gpio_get(GPIOB, GPIO1)) //On Tesla M3 board precharge output is tied to Vcc
return HW_TESLAM3;
else if (is_floating(GPIOC, GPIO9)) //Desat pin is floating
Expand All @@ -120,14 +120,19 @@ void write_bootloader_pininit()
commands.pindef[0].port = GPIOC;
commands.pindef[0].inout = PIN_OUT;
commands.pindef[0].level = 0;
commands.pindef[1].port = GPIOB;
commands.pindef[1].inout = PIN_OUT;
commands.pindef[1].level = 0;

if (hwRev == HW_BLUEPILL)
{
commands.pindef[0].pin = GPIO15;
commands.pindef[1].pin = GPIO4;
}
else
{
commands.pindef[0].pin = GPIO13;
commands.pindef[1].pin = GPIO1;
}

crc_reset();
Expand Down
41 changes: 21 additions & 20 deletions src/pwmgeneration-foc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ static int initwait = 0;
static int fwBaseGain = 0;
static s32fp idref = 0;
static int curki = 0;
static int idleCounter = 0;
static tim_oc_id ocChannels[3];
static PiController qController;
static PiController dController;
Expand Down Expand Up @@ -100,12 +99,11 @@ void PwmGeneration::Run()
dController.ResetIntegrator();
qController.ResetIntegrator();
fwController.ResetIntegrator();
idleCounter++;
RunOffsetCalibration();
}
else
{
timer_enable_break_main_output(PWM_TIMER);
idleCounter = 0;
}

for (int i = 0; i < 3; i++)
Expand Down Expand Up @@ -229,8 +227,6 @@ void PwmGeneration::PwmInit()

s32fp PwmGeneration::ProcessCurrents(s32fp& id, s32fp& iq)
{
static int il1Avg = 0, il2Avg = 0;
const int offsetSamples = 64;

if (initwait > 0)
{
Expand All @@ -240,21 +236,6 @@ s32fp PwmGeneration::ProcessCurrents(s32fp& id, s32fp& iq)
s32fp il1 = GetCurrent(AnaIn::il1, ilofs[0], Param::Get(Param::il1gain));
s32fp il2 = GetCurrent(AnaIn::il2, ilofs[1], Param::Get(Param::il2gain));

//250ms after motor standstill
if (idleCounter >= (pwmfrq / 4) && idleCounter < ((pwmfrq / 4) + offsetSamples))
{
il1Avg += AnaIn::il1.Get();
il2Avg += AnaIn::il2.Get();
}
else if (idleCounter == ((pwmfrq / 4) + offsetSamples))
{
SetCurrentOffset(il1Avg / offsetSamples, il2Avg / offsetSamples);
}
else
{
il1Avg = il2Avg = 0;
}

if ((Param::GetInt(Param::pinswap) & SWAP_CURRENTS) > 0)
FOC::ParkClarke(il2, il1, angle);
else
Expand Down Expand Up @@ -288,4 +269,24 @@ void PwmGeneration::CalcNextAngleSync(int dir)
frq = fslip;
angle += dir * FRQ_TO_ANGLE(fslip);
}
}

void PwmGeneration::RunOffsetCalibration()
{
static int il1Avg = 0, il2Avg = 0, samples = 0;
const int offsetSamples = 512;

if (samples < offsetSamples)
{
il1Avg += AnaIn::il1.Get();
il2Avg += AnaIn::il2.Get();
}
else
{
SetCurrentOffset(il1Avg / offsetSamples, il2Avg / offsetSamples);
il1Avg = il2Avg = 0;
samples = 0;
}

samples++;
}
30 changes: 28 additions & 2 deletions src/pwmgeneration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,13 @@ void PwmGeneration::SetOpmode(int _opmode)
break;
case MOD_BOOST:
DisableOutput();
timer_enable_oc_output(PWM_TIMER, TIM_OC2N);
EnableChargeOutput();
timer_enable_break_main_output(PWM_TIMER);
ConfigureChargeController();
break;
case MOD_BUCK:
DisableOutput();
timer_enable_oc_output(PWM_TIMER, TIM_OC2);
EnableChargeOutput();
timer_enable_break_main_output(PWM_TIMER);
ConfigureChargeController();
break;
Expand Down Expand Up @@ -214,6 +214,32 @@ void PwmGeneration::DisableOutput()
timer_disable_oc_output(PWM_TIMER, TIM_OC1N);
timer_disable_oc_output(PWM_TIMER, TIM_OC2N);
timer_disable_oc_output(PWM_TIMER, TIM_OC3N);
}

void PwmGeneration::EnableChargeOutput()
{
/* Prius GEN2 inverter only has one control signal for the buck/boost converter
* When we output a "high" the upper IGBT is switched on. So for bucking
* output current and duty cycle are proportional
* For boosting we need to output a "low" to enable the low side IGBT and
* thus the output current and duty cycle are inverse proportional.
*/
if (hwRev == HW_PRIUS)
{
timer_enable_oc_output(PWM_TIMER, TIM_OC2N);

if (opmode == MOD_BOOST)
timer_set_oc_polarity_low(PWM_TIMER, TIM_OC2N);
else if (opmode == MOD_BUCK)
timer_set_oc_polarity_high(PWM_TIMER, TIM_OC2N);
}
else
{
if (opmode == MOD_BOOST)
timer_enable_oc_output(PWM_TIMER, TIM_OC2N);
else if (opmode == MOD_BUCK)
timer_enable_oc_output(PWM_TIMER, TIM_OC2);
}
}

void PwmGeneration::SetCurrentLimitThreshold(s32fp ocurlim)
Expand Down
1 change: 0 additions & 1 deletion src/stm32_sine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@

HWREV hwRev; //Hardware variant of board we are running on

//Precise control of executing the boost controller
static Stm32Scheduler* scheduler;
static Can* can;

Expand Down
4 changes: 3 additions & 1 deletion src/temp_meas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,15 @@ s32fp TempMeas::Lookup(int digit, Sensors sensorId)
int index = sensorId >= TEMP_KTY83 ? sensorId - TEMP_KTY83 + NUM_HS_SENSORS : sensorId;

const TEMP_SENSOR * sensor = &sensors[index];
uint16_t last = sensor->lookup[0] + (sensor->coeff == NTC?-1:+1);
uint16_t last;

for (uint32_t i = 0; i < sensor->tabSize; i++)
{
uint16_t cur = sensor->lookup[i];
if ((sensor->coeff == NTC && cur >= digit) || (sensor->coeff == PTC && cur <= digit))
{
//we are outside the lookup table range, return minimum
if (0 == i) return FP_FROMINT(sensor->tempMin);
s32fp a = FP_FROMINT(sensor->coeff == NTC?cur - digit:digit - cur);
s32fp b = FP_FROMINT(sensor->coeff == NTC?cur - last:last - cur);
return FP_FROMINT(sensor->step * i + sensor->tempMin) - sensor->step * FP_DIV(a, b);
Expand Down
24 changes: 19 additions & 5 deletions src/terminal_prj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,22 @@ static void MapCan(char *arg)
}

*ending = 0;
int iVal = my_atoi(arg);

//allow gain values < 1 and re-interpret them
if (i == (numArgs - 1) && iVal == 0)
{
values[i] = fp_atoi(arg, 16);
//The can values interprets abs(values) < 32 as gain and > 32 as divider
//e.g. 0.25 means integer division by 4 so we need to calculate div = 1/value
//0.25 with 16 decimals is 16384, 65536/16384 = 4
values[i] = (32 << 16) / values[i];
}
else
{
values[i] = iVal;
}

values[i] = my_atoi(arg);
arg = my_trim(ending + 1);
}

Expand Down Expand Up @@ -403,7 +417,7 @@ static void ParamSet(char *arg)
*pParamVal = 0;
pParamVal++;

val = fp_atoi(pParamVal);
val = fp_atoi(pParamVal, FRAC_DIGITS);
idx = Param::NumFromString(arg);

if (Param::PARAM_INVALID != idx)
Expand Down Expand Up @@ -491,10 +505,10 @@ static void StopInverter(char *arg)
static void StartInverter(char *arg)
{
arg = my_trim(arg);
s32fp val = fp_atoi(arg);
if (val < FP_FROMINT(MOD_LAST))
int val = my_atoi(arg);
if (val < MOD_LAST)
{
Param::SetFlt(Param::opmode, val);
Param::SetInt(Param::opmode, val);
PwmGeneration::SetOpmode(FP_TOINT(val));
printf("Inverter started\r\n");
}
Expand Down

0 comments on commit 1aa6b4e

Please sign in to comment.