Skip to content

Commit

Permalink
!! Fixed shoot-through when starting second time in active low mode !!
Browse files Browse the repository at this point in the history
Fixed Blue Pill break input - again
Changed PWM frequency handling - always same controller frequency and 3 possible PWM frequencies - 4.4, 8.8, 17.6kHz
Two different d-current controllers, one for regen, one for acceleration
  • Loading branch information
jsphuebner committed Nov 10, 2019
1 parent 98db0db commit 6dd6eec
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 42 deletions.
2 changes: 1 addition & 1 deletion include/digio_prj.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
DIG_IO_ENTRY(cruise_in, GPIOB, GPIO5, PinMode::INPUT_FLT) \
DIG_IO_ENTRY(mprot_in, GPIOB, GPIO1, PinMode::INPUT_FLT) \
DIG_IO_ENTRY(emcystop_in, GPIOB, GPIO1, PinMode::INPUT_FLT) \
DIG_IO_ENTRY(bk_in, GPIOB, GPIO12, PinMode::INPUT_FLT) \
DIG_IO_ENTRY(bk_in, GPIOB, GPIO12, PinMode::INPUT_PU) \
DIG_IO_ENTRY(bms_in, GPIOD, GPIO15, PinMode::INPUT_FLT) /* non-existant */ \
DIG_IO_ENTRY(ocur_in, GPIOD, GPIO15, PinMode::INPUT_FLT) /* non-existant */ \
DIG_IO_ENTRY(desat_in, GPIOD, GPIO15, PinMode::INPUT_FLT) /* non-existant */ \
Expand Down
8 changes: 4 additions & 4 deletions 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.64.R
#define VER 4.65.R

/* Entries must be ordered as follows:
1. Saveable parameters (id != 0)
Expand Down Expand Up @@ -47,7 +47,7 @@
PARAM_ENTRY(CAT_MOTOR, dirmode, DIRMODES, 0, 3, 1, 95 ) \
PARAM_ENTRY(CAT_MOTOR, syncofs, "dig", 0, 65535, 0, 70 ) \
PARAM_ENTRY(CAT_MOTOR, snsm, SNS_M, 12, 14, 12, 46 ) \
PARAM_ENTRY(CAT_INVERTER,pwmfrq, PWMFRQS, 0, 4, 1, 13 ) \
PARAM_ENTRY(CAT_INVERTER,pwmfrq, PWMFRQS, 0, 2, 1, 13 ) \
PARAM_ENTRY(CAT_INVERTER,pwmpol, PWMPOLS, 0, 1, 0, 52 ) \
PARAM_ENTRY(CAT_INVERTER,deadtime, "dig", 0, 255, 63, 14 ) \
PARAM_ENTRY(CAT_INVERTER,ocurlim, "A", -65536, 65536, 100, 22 ) \
Expand Down Expand Up @@ -168,7 +168,7 @@
PARAM_ENTRY(CAT_MOTOR, syncofs, "dig", 0, 65535, 0, 70 ) \
PARAM_ENTRY(CAT_MOTOR, syncadv, "dig/hz",-100, 100, 0, 101 ) \
PARAM_ENTRY(CAT_MOTOR, snsm, SNS_M, 12, 14, 12, 46 ) \
PARAM_ENTRY(CAT_INVERTER,pwmfrq, PWMFRQS, 0, 4, 1, 13 ) \
PARAM_ENTRY(CAT_INVERTER,pwmfrq, PWMFRQS, 0, 2, 1, 13 ) \
PARAM_ENTRY(CAT_INVERTER,pwmpol, PWMPOLS, 0, 1, 0, 52 ) \
PARAM_ENTRY(CAT_INVERTER,deadtime, "dig", 0, 255, 63, 14 ) \
PARAM_ENTRY(CAT_INVERTER,ocurlim, "A", -65536, 65536, 100, 22 ) \
Expand Down Expand Up @@ -273,7 +273,7 @@

/***** Enum String definitions *****/
#define OPMODES "0=Off, 1=Run, 2=ManualRun, 3=Boost, 4=Buck, 5=Sine, 6=AcHeat"
#define PWMFRQS "0=17.6kHz, 1=8.8kHz, 2=4.4KHz, 3=2.2kHz, 4=1.1kHz"
#define PWMFRQS "0=17.6kHz, 1=8.8kHz, 2=4.4KHz"
#define PWMPOLS "0=ACTHIGH, 1=ACTLOW"
#define DIRS "-1=Reverse, 0=Neutral, 1=Forward"
#define TRIPMODES "0=AllOff, 1=DcSwOn, 2=PrechargeOn"
Expand Down
2 changes: 1 addition & 1 deletion libopeninv
8 changes: 4 additions & 4 deletions sinus.cbp
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,11 @@
<Extensions>
<code_completion />
<debugger>
<remote_debugging target="FieldOrientedControl">
<options conn_type="0" serial_baud="115200" ip_address="localhost" ip_port="3333" />
</remote_debugging>
<remote_debugging target="SlipControl">
<options conn_type="0" serial_baud="115200" ip_address="localhost" ip_port="3333" />
<options conn_type="0" serial_baud="115200" ip_address="localhost" ip_port="3333" additional_cmds="load&#x0A;r" />
</remote_debugging>
<remote_debugging target="FieldOrientedControl">
<options conn_type="0" serial_baud="115200" ip_address="localhost" ip_port="3333" additional_cmds="load&#x0A;r" />
</remote_debugging>
<remote_debugging target="Test">
<options conn_type="0" serial_baud="115200" ip_address="localhost" ip_port="3333" />
Expand Down
38 changes: 23 additions & 15 deletions src/pwmgeneration-foc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ static bool regen = false;
static s32fp idref = 0;
static PiController qController;
static PiController dController;
static PiController dControllerRegen;
static PiController fwController;

void PwmGeneration::Run()
Expand All @@ -48,7 +49,7 @@ void PwmGeneration::Run()
int dir = Param::GetInt(Param::dir);
uint16_t dc[3];
s32fp id, iq;
static int32_t offsetRamped = 0, fwIdRef = 0;
static int32_t fwIdRef = 0, udRamped = 0;

Encoder::UpdateRotorAngle(dir);

Expand All @@ -61,47 +62,50 @@ void PwmGeneration::Run()

ProcessCurrents(id, iq);

int32_t dofs = regen ? 0 : FP_TOINT(-Param::GetInt(Param::frqfac) * frq);
int32_t dofs = FP_TOINT(-Param::GetInt(Param::frqfac) * frq);
int32_t qofs = FP_TOINT(Param::GetInt(Param::frqfac) * frq);

if (dofs < offsetRamped)
dController.SetOffset(dofs);
qController.SetOffset(qofs);

dController.SetRef(idref + fwIdRef);
dControllerRegen.SetRef(idref + fwIdRef);
int32_t ud = regen ? dControllerRegen.Run(id) : dController.Run(id);

if (ud < udRamped)
{
offsetRamped = RAMPDOWN(offsetRamped, dofs, Param::GetInt(Param::dofsramp));
udRamped = RAMPDOWN(udRamped, ud, Param::GetInt(Param::dofsramp));
}
else
{
offsetRamped = RAMPUP(offsetRamped, dofs, Param::GetInt(Param::dofsramp));
udRamped = RAMPUP(udRamped, ud, Param::GetInt(Param::dofsramp));
}

dController.SetOffset(offsetRamped);
qController.SetOffset(qofs);

dController.SetRef(idref + fwIdRef);
int32_t ud = dController.Run(id);
int32_t qlimit = FOC::GetQLimit(ud);
int32_t qlimit = FOC::GetQLimit(udRamped);
qController.SetMinMaxY(-qlimit, qlimit);
int32_t uq = qController.Run(iq);
FOC::InvParkClarke(ud, uq, angle);
FOC::InvParkClarke(udRamped, uq, angle);
//Calculate extra field weakening current for the next cycle
fwIdRef = fwController.Run(FOC::GetTotalVoltage(ud, uq) >> 5);
fwIdRef = fwController.Run(FOC::GetTotalVoltage(udRamped, uq) >> 5);

s32fp idc = (iq * uq) / FOC::GetMaximumModulationIndex();

Param::SetFlt(Param::fstat, frq);
Param::SetFlt(Param::angle, DIGIT_TO_DEGREE(angle));
Param::SetInt(Param::ud, ud);
Param::SetInt(Param::ud, udRamped);
Param::SetInt(Param::uq, uq);
Param::SetInt(Param::qofs, qofs);
Param::SetInt(Param::dofs, dofs);
Param::SetFlt(Param::idc, idc);
Param::SetFlt(Param::dspnt, dController.GetRef());
Param::SetFlt(Param::dspnt, fwIdRef);
Param::SetFlt(Param::qspnt, qController.GetRef());

/* Shut down PWM on stopped motor, neutral gear or init phase */
if ((0 == frq && 0 == idref) || 0 == dir || initwait > 0)
{
timer_disable_break_main_output(PWM_TIMER);
dController.ResetIntegrator();
dControllerRegen.ResetIntegrator();
qController.ResetIntegrator();
fwController.ResetIntegrator();
}
Expand Down Expand Up @@ -178,6 +182,7 @@ void PwmGeneration::SetControllerGains(int kp, int ki, int fwkp)
{
qController.SetGains(kp, ki);
dController.SetGains(kp, ki);
dControllerRegen.SetGains(kp, ki);
fwController.SetGains(fwkp, 0);
}

Expand All @@ -194,6 +199,9 @@ void PwmGeneration::PwmInit()
dController.ResetIntegrator();
dController.SetCallingFrequency(pwmfrq);
dController.SetMinMaxY(-maxVd, maxVd);
dControllerRegen.ResetIntegrator();
dControllerRegen.SetCallingFrequency(pwmfrq);
dControllerRegen.SetMinMaxY(-maxVd, maxVd);
fwController.ResetIntegrator();
fwController.SetCallingFrequency(pwmfrq);
fwController.SetMinMaxY(-FP_FROMINT(500), 0);
Expand Down
48 changes: 31 additions & 17 deletions src/pwmgeneration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#define SHIFT_90DEG (uint16_t)16384
#define FRQ_TO_ANGLE(frq) FP_TOINT((frq << SineCore::BITS) / pwmfrq)
#define DIGIT_TO_DEGREE(a) FP_FROMINT(angle) / (65536 / 360)
#define FRQ_DIVIDER 8192 //PWM ISR callback frequency divider

uint16_t PwmGeneration::pwmfrq;
uint16_t PwmGeneration::angle;
Expand Down Expand Up @@ -89,7 +90,7 @@ void PwmGeneration::SetCurrentOffset(int offset1, int offset2)
int PwmGeneration::GetCpuLoad()
{
//PWM period 2x counter because of center aligned mode
return (1000 * execTicks) / (2 << pwmdigits);
return (1000 * execTicks) / FRQ_DIVIDER;
}

void PwmGeneration::SetOpmode(int _opmode)
Expand Down Expand Up @@ -153,7 +154,7 @@ extern "C" void tim1_brk_isr(void)
}

extern "C" void pwm_timer_isr(void)
{
{
int start = timer_get_counter(PWM_TIMER);
/* Clear interrupt pending flag */
timer_clear_flag(PWM_TIMER, TIM_SR_UIF);
Expand Down Expand Up @@ -301,19 +302,33 @@ s32fp PwmGeneration::GetCurrent(AnaIn::AnaIns input, s32fp offset, s32fp gain)
*
* @param[in] deadtime Deadtime between bottom and top (coded value, consult STM32 manual)
* @param[in] pwmpol Output Polarity. 0=Active High, 1=Active Low
* @return PWM frequency
* @return PWM ISR callback frequency
*/
uint16_t PwmGeneration::TimerSetup(uint16_t deadtime, int pwmpol)
{
{
///There are two update events per PWM period
///One when counter reaches top, one when it reaches bottom
///We set the repetition counter in a way, that the ISR
///Callback frequency is constant i.e. independent from PWM frequency
///- for 17.6 kHz: call ISR every four update events (that is every other period)
///- for 8.8kHz: call ISR every other update event (that is once per PWM period)
///- for 4.4kHz: call ISR on every update event (that is twice per period)
const uint8_t repCounters[] = { 3, 1, 0 };
const uint16_t pwmmax = 1U << pwmdigits;
uint8_t outputMode = pwmpol ? GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN : GPIO_CNF_OUTPUT_ALTFN_PUSHPULL;
const uint8_t outputMode = pwmpol ? GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN : GPIO_CNF_OUTPUT_ALTFN_PUSHPULL;

//Disable output in active low mode before resetting timer, otherwise shoot through will occur!
if (pwmpol)
{
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO8 | GPIO9 | GPIO10);
gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO13 | GPIO14 | GPIO15);
}

rcc_periph_reset_pulse(PWM_TIMRST);

rcc_periph_reset_pulse(PWM_TIMRST);
/* disable timer */
timer_disable_counter(PWM_TIMER);
/* Center aligned PWM */
timer_set_alignment(PWM_TIMER, TIM_CR1_CMS_CENTER_1);
timer_enable_preload(PWM_TIMER);
timer_enable_preload(PWM_TIMER);

for (int channel = TIM_OC1; channel <= TIM_OC3N; channel++)
{
Expand All @@ -322,7 +337,7 @@ uint16_t PwmGeneration::TimerSetup(uint16_t deadtime, int pwmpol)
timer_set_oc_idle_state_unset(PWM_TIMER, (tim_oc_id)channel);
timer_set_oc_value(PWM_TIMER, (tim_oc_id)channel, 0);

if (pwmpol)
if (pwmpol) //Active low
timer_set_oc_polarity_low(PWM_TIMER, (tim_oc_id)channel);
else
timer_set_oc_polarity_high(PWM_TIMER, (tim_oc_id)channel);
Expand All @@ -339,23 +354,22 @@ uint16_t PwmGeneration::TimerSetup(uint16_t deadtime, int pwmpol)
timer_set_enabled_off_state_in_run_mode(PWM_TIMER);
timer_set_enabled_off_state_in_idle_mode(PWM_TIMER);
timer_set_deadtime(PWM_TIMER, deadtime);
timer_clear_flag(PWM_TIMER, TIM_SR_BIF);
timer_enable_irq(PWM_TIMER, TIM_DIER_UIE);
timer_enable_irq(PWM_TIMER, TIM_DIER_BIE);
timer_clear_flag(PWM_TIMER, TIM_SR_UIF | TIM_SR_BIF);
timer_enable_irq(PWM_TIMER, TIM_DIER_UIE | TIM_DIER_BIE);

timer_set_prescaler(PWM_TIMER, 0);
/* PWM frequency */
timer_set_period(PWM_TIMER, pwmmax);
timer_set_repetition_counter(PWM_TIMER, 1);
timer_set_period(PWM_TIMER, pwmmax);
timer_set_repetition_counter(PWM_TIMER, repCounters[pwmdigits - MIN_PWM_DIGITS]);

timer_generate_event(PWM_TIMER, TIM_EGR_UG);

timer_enable_counter(PWM_TIMER);

gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, outputMode, GPIO8 | GPIO9 | GPIO10);
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, outputMode, GPIO13 | GPIO14 | GPIO15);

return rcc_apb2_frequency / (uint32_t)(2 * pwmmax);
//Callback frequency is constant because we use the repetition counter
return rcc_apb2_frequency / FRQ_DIVIDER;
}

void PwmGeneration::AcHeatTimerSetup()
Expand Down

0 comments on commit 6dd6eec

Please sign in to comment.