665 lines
20 KiB
C
665 lines
20 KiB
C
/*
|
|
* dbw.c
|
|
*
|
|
* Created on: May 5, 2021
|
|
* Author: Dmitrijs
|
|
*/
|
|
|
|
#include "main.h"
|
|
|
|
|
|
volatile config_t config_ram;
|
|
volatile var_t var;
|
|
volatile config_t *config;
|
|
|
|
volatile uint32_t ac_timer = 100, ac_mode = 0;
|
|
|
|
const config_t config_flash __attribute__((section(".config"), used)) = {
|
|
PPS2_CALC_OPTION_LINEAR,
|
|
TPS2_CALC_OPTION_LINEAR,
|
|
|
|
100, 3990,
|
|
|
|
100, 2048, 500, 3990,
|
|
|
|
100, 3990,
|
|
|
|
100, 2048, 500, 3990,
|
|
|
|
PPS2TPS_OPTION_CURVE,
|
|
IDLE_OPTION_NO_IDLE_INPUT,
|
|
|
|
{ 0, 67, 132, 198, 264, 330, 396, 462, 528, 594, 660, 726, 792, 858,
|
|
924, 1000 }, { 0, 67, 132, 198, 264, 330, 396, 462, 528, 594,
|
|
660, 726, 792, 858, 924, 1000 },
|
|
|
|
// Idle pps modifier curve. when Idle input is used. it modifies tps target
|
|
{ 0, 142, 284, 426, 568, 710, 852, 1000 }, //input pwm duty [0.1%]
|
|
{ 0, 8, 17, 25, 34, 42, 51, 60 },
|
|
|
|
1000, // frequency in Hz
|
|
10, // ctl_teriod in [100uS]
|
|
MOTOR_PID_OPTION_STATIC,// PID static coefs, static coef, but different for forward and backward moving
|
|
// 3D table
|
|
|
|
// PID COEFICIENTS for forward and reward
|
|
700, 50, 10, 700, 50, 10,
|
|
|
|
{ 0, 67, 132, 198, 264, 330, 396, 462, 528, 594, 660, 726, 792, 858,
|
|
924, 1000 }, { -325, -281, -239, -196, -153, -110, -67, -24, 18,
|
|
61, 104, 146, 189, 232, 275, 325 }, { { 700, 700, 700, 700, 700,
|
|
700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700 }, { 700,
|
|
700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700,
|
|
700, 700 }, { 700, 700, 700, 700, 700, 700, 700, 700, 700, 700,
|
|
700, 700, 700, 700, 700, 700 }, { 700, 700, 700, 700, 700, 700,
|
|
700, 700, 700, 700, 700, 700, 700, 700, 700, 700 }, { 700, 700,
|
|
700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700,
|
|
700 }, { 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700,
|
|
700, 700, 700, 700, 700 }, { 700, 700, 700, 700, 700, 700, 700,
|
|
700, 700, 700, 700, 700, 700, 700, 700, 700 },
|
|
{ 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700,
|
|
700, 700, 700, 700 }, { 700, 700, 700, 700, 700, 700,
|
|
700, 700, 700, 700, 700, 700, 700, 700, 700, 700 }, {
|
|
700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700,
|
|
700, 700, 700, 700, 700 }, { 700, 700, 700, 700, 700,
|
|
700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700 },
|
|
{ 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700,
|
|
700, 700, 700, 700 }, { 700, 700, 700, 700, 700, 700,
|
|
700, 700, 700, 700, 700, 700, 700, 700, 700, 700 }, {
|
|
700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700,
|
|
700, 700, 700, 700, 700 }, { 700, 700, 700, 700, 700,
|
|
700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700 },
|
|
{ 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700,
|
|
700, 700, 700, 700 }, },
|
|
|
|
//PID limmits
|
|
100, 10000, -10000,
|
|
|
|
//DC offset curve
|
|
{ 0, 67, 132, 198, 264, 330, 396, 462, 528, 594, 660, 726, 792, 858,
|
|
924, 1000 }, // tps bins [0.1%]
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // DC
|
|
|
|
//Battery voltage correction curve
|
|
{ 0, 585, 1170, 1755, 2340, 2925, 3510, 4095 }, // battery voltage ADC bins []
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // motor pwm correction [0.1%]
|
|
|
|
30, 0x100, 0x5e8, 0x00,
|
|
|
|
//limmits
|
|
30, 30, 15, 30, 30, 15, 100, 500, 10, 5000,
|
|
|
|
5, 7, // my MS CAN ID
|
|
1, 0, 100, 0x300 };
|
|
|
|
volatile unsigned short ctl_period;
|
|
volatile pwm_t ttl1_pwm;
|
|
volatile float pps1_gain, pps1_offset, pps2_gain, pps2_offset, tps1_gain,
|
|
tps1_offset, tps2_gain, tps2_offset;
|
|
volatile uint16_t dbw_fast_process_timer, dbw_slow_process_timer;
|
|
volatile int32_t vbat_corr, tps_slow_t, p_comp, i_comp, d_comp, tps_error_t,
|
|
can_target, spring_preload, idle_adder;
|
|
|
|
void Apply_Sensor_Calibration(void) {
|
|
pps1_gain = (1000.0F / (float) (config->pps1_max - config->pps1_min));
|
|
pps1_offset = (config->pps1_min * 1000.0F
|
|
/ (config->pps1_min - config->pps1_max));
|
|
|
|
pps2_gain = (1000.0F / (float) (config->pps2_max - config->pps2_min));
|
|
pps2_offset = (config->pps2_min * 1000.0F
|
|
/ (config->pps2_min - config->pps2_max));
|
|
|
|
tps1_gain = (1000.0F / (float) (config->tps1_max - config->tps1_min));
|
|
tps1_offset = (short) (config->tps1_min * 1000.0F
|
|
/ (config->tps1_min - config->tps1_max));
|
|
|
|
tps2_gain = (1000.0F / (float) (config->tps2_max - config->tps2_min));
|
|
tps2_offset = (config->tps2_min * 1000.0F
|
|
/ (config->tps2_min - config->tps2_max));
|
|
|
|
}
|
|
|
|
void DBW_Init(void) {
|
|
dbw_fast_process_timer = 1;
|
|
dbw_slow_process_timer = config->motor_ctl_period;
|
|
vbat_corr = 0;
|
|
tps_slow_t = var.tps;
|
|
p_comp = 0;
|
|
i_comp = 0;
|
|
d_comp = 0;
|
|
tps_error_t = var.tps_error;
|
|
can_target = 0;
|
|
spring_preload = 0;
|
|
idle_adder = 0;
|
|
}
|
|
|
|
int DBW_Process(void) {
|
|
|
|
int32_t pwm_output = 0;
|
|
int32_t pct = 0;
|
|
if (dbw_fast_process_timer == 0) {
|
|
//process DBW every 1 mS
|
|
dbw_fast_process_timer = 1;
|
|
|
|
// Read all sensors and calculate error
|
|
// calculate PPS sensor reading
|
|
var.pps1_adc = LPF(700, Adc_Read(0), var.pps1_adc);
|
|
var.pps1 = var.pps1_adc * pps1_gain + pps1_offset;
|
|
|
|
var.pps2_adc = LPF(700, Adc_Read(3), var.pps2_adc); //orig 1
|
|
var.pps2 = var.pps2_adc * pps2_gain + pps2_offset;
|
|
|
|
var.pps_delta = var.pps1 - var.pps2;
|
|
var.pps = (var.pps1 + var.pps2) >> 1;
|
|
|
|
//Calculate TPS sensor reading
|
|
var.tps1_adc = LPF(700, Adc_Read(2), var.tps1_adc);
|
|
var.tps1 = var.tps1_adc * tps1_gain + tps1_offset;
|
|
|
|
var.tps2_adc = LPF(700, Adc_Read(1), var.tps2_adc); //orig 3
|
|
var.tps2 = var.tps2_adc * tps2_gain + tps2_offset;
|
|
|
|
// calculate tps and pps delta and values
|
|
var.tps_delta = var.tps1 - var.tps2;
|
|
var.tps = (var.tps1 + var.tps2) >> 1;
|
|
|
|
var.pps_delta = var.pps1 - var.pps2;
|
|
var.pps = (var.pps1 + var.pps2) >> 1;
|
|
|
|
// set tps target
|
|
if (config->pps2tps_option == PPS2TPS_OPTION_CURVE) {
|
|
var.tps_target = intrp_1d_ss_table(var.pps, 16,
|
|
(signed short*) config->pps_bins, 1,
|
|
(signed short*) config->tps_bins);
|
|
}
|
|
// if MS3 DBW protocol is used
|
|
else if (config->pps2tps_option == PPS2TPS_OPTION_MS3_CAN) {
|
|
// if no RX errors
|
|
//if(var.status0 & DBW_STATUS0_CAN_MSDBW_F)
|
|
if (config->pps2tps_option == PPS2TPS_OPTION_MS3_CAN) {
|
|
// use MS3 TPS TARGET
|
|
var.tps_target = can_target;
|
|
} else {
|
|
// on CAN error fall back to internal curve
|
|
var.tps_target = intrp_1d_ss_table(var.pps, 16,
|
|
(signed short*) config->pps_bins, 1,
|
|
(signed short*) config->tps_bins);
|
|
}
|
|
}
|
|
|
|
else {
|
|
// All other TPS target options are considered as fault
|
|
Error_Handler();
|
|
}
|
|
|
|
// add idle TPS target adder
|
|
var.tps_target += idle_adder;
|
|
//limit TPS target
|
|
if (var.tps_target > 1000)
|
|
var.tps_target = 1000;
|
|
if (var.tps_target < 0)
|
|
var.tps_target = 0;
|
|
|
|
//calculate regulation error
|
|
var.tps_error = var.tps_target - var.tps;
|
|
|
|
// Proportional regulator
|
|
p_comp = (((int32_t) var.tps_error) * (int32_t) config->motor_fw_p)
|
|
/ 10;
|
|
|
|
// calculate spring preload compensation using interpolation
|
|
spring_preload = intrp_1d_ss_table(var.tps_target, 16,
|
|
(signed short*) config->tps_dc_tps_bins, 1,
|
|
(signed short*) config->tps_dc_offset_bins);
|
|
|
|
if (dbw_slow_process_timer > 0) {
|
|
dbw_slow_process_timer--;
|
|
if (dbw_slow_process_timer == 0) {
|
|
dbw_slow_process_timer = config->motor_ctl_period;
|
|
//calculate slow changing thinks
|
|
|
|
//read Battery voltage and apply corrections
|
|
var.vbat_adc = LPF(700, Adc_Read(5), var.vbat_adc);
|
|
pct = intrp_1d_ss_table(var.vbat_adc, 8,
|
|
(signed short*) config->vbat_bins, 1,
|
|
(signed short*) config->motor_pwm_corr_bins);
|
|
|
|
//read motor current
|
|
var.motor_current_adc = LPF(700, Adc_Read(4),
|
|
var.motor_current_adc);
|
|
|
|
// calculate I component
|
|
|
|
i_comp += ((int32_t) var.tps_error
|
|
* (int32_t) config->motor_fw_i) / 100;
|
|
if (i_comp > config->i_limmit)
|
|
i_comp = config->i_limmit;
|
|
if (i_comp < (-config->i_limmit))
|
|
i_comp = (-config->i_limmit);
|
|
|
|
// calculate D component
|
|
d_comp = (((int32_t) var.tps_error - tps_error_t)
|
|
* (int32_t) config->motor_fw_d) / 10;
|
|
tps_error_t = var.tps_error;
|
|
|
|
// calculate single shot
|
|
//single_shot = var.tps_error *
|
|
|
|
// Calculate Idle adder
|
|
if (config->idle_input_option == IDLE_OPTION_NO_IDLE_INPUT)
|
|
idle_adder = 0;
|
|
else if (config->idle_input_option == IDLE_OPTION_MS_CAN) {
|
|
idle_adder = intrp_1d_ss_table(var.idle_dc, 8,
|
|
(signed short*) config->idle_input_bins, 1,
|
|
(signed short*) config->idle_tps_adder_bins);
|
|
|
|
} else if (config->idle_input_option == IDLE_OPTION_PWM_INPUT1) {
|
|
|
|
idle_adder = intrp_1d_ss_table(var.idle_dc, 8,
|
|
(signed short*) config->idle_input_bins, 1,
|
|
(signed short*) config->idle_tps_adder_bins)
|
|
- (var.pps / 5);
|
|
if (idle_adder < 0) {
|
|
idle_adder = 0;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
pwm_output = p_comp + i_comp + d_comp + spring_preload;
|
|
|
|
vbat_corr = (int16_t) (((int32_t) var.motor_pwm) * vbat_corr / 1000);
|
|
|
|
pwm_output += pct;
|
|
|
|
//limmit pwm
|
|
if (pwm_output > config->motor_dc_max)
|
|
pwm_output = config->motor_dc_max;
|
|
if (pwm_output < config->motor_dc_min)
|
|
pwm_output = config->motor_dc_min;
|
|
|
|
//apply pwm
|
|
DBW_Pwm_Set_Duty((signed short) (pwm_output), (pwm_t*) &ttl1_pwm);
|
|
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void DBW_Pwm_Init(void) {
|
|
|
|
// Setup PWM ports
|
|
ttl1_pwm.pos_port = GPIOB;
|
|
ttl1_pwm.pos_pin = 10;
|
|
|
|
ttl1_pwm.neg_port = GPIOB;
|
|
ttl1_pwm.neg_pin = 11;
|
|
|
|
// setup pwm status default -> no drive
|
|
ttl1_pwm.status = PWM_STATUS_DEFAULT;
|
|
|
|
// calculate how many tick are in given freq period
|
|
ttl1_pwm.period_ticks = (unsigned int) 1000000UL / config->motor_pwm_fq;
|
|
|
|
// set initian pwm from current settings
|
|
ttl1_pwm.pwm = var.motor_pwm;
|
|
ttl1_pwm.pwm_t = var.motor_pwm;
|
|
ttl1_pwm.single_pulse = 0;
|
|
|
|
//tmp = (float)ttl1_pwm.period_ticks * (float)ttl1_pwm.pwm/10000.0F;
|
|
//ttl1_pwm.duty_ticks = (unsigned int) tmp;
|
|
|
|
DBW_Pwm_Set_Duty(var.motor_pwm, (pwm_t*) &ttl1_pwm);
|
|
|
|
if (var.motor_pwm < 0)
|
|
ttl1_pwm.state = PWM_STATE_NEGATIVE_INACTIVE;
|
|
else if (var.motor_pwm > 0)
|
|
ttl1_pwm.state = PWM_STATE_POSITIVE_INACTIVE;
|
|
else
|
|
ttl1_pwm.state = PWM_STATE_POSITIVE_INACTIVE;
|
|
|
|
ttl1_pwm.status = PWM_STATUS_IDLE;
|
|
|
|
DBW_Stop();
|
|
|
|
ttl1_pwm.pos_port->BSRR = (1 << (16 + ttl1_pwm.pos_pin));
|
|
ttl1_pwm.neg_port->BSRR = (1 << (16 + ttl1_pwm.neg_pin));
|
|
|
|
// configure TIM2 to 1uS / tick timer
|
|
// setup CCR interrupt happen after sturtup delay is over
|
|
|
|
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
|
|
TIM2->CNT = 0xFFFFFFFE;
|
|
TIM2->PSC = 48; //2400; // (1uS precision)
|
|
|
|
TIM2->ARR = 0xFFFFFFFF;
|
|
|
|
TIM2->CR1 = (TIM_CR1_URS | TIM_CR1_CEN);
|
|
TIM2->CCER = 0x0000;
|
|
TIM2->CCMR1 = 0x0000;
|
|
|
|
TIM2->CCR1 = (unsigned int) 20000; // startup delay
|
|
TIM2->CCR2 = 0;
|
|
TIM2->SR &= ~TIM_SR_CC1IF;
|
|
TIM2->DIER |= TIM_DIER_CC1IE;
|
|
NVIC_EnableIRQ(TIM2_IRQn);
|
|
|
|
}
|
|
|
|
void TIM2_IRQHandler(void) {
|
|
if (TIM2->SR & TIM_SR_CC1IF) {
|
|
// capture compare intrrupt
|
|
TIM2->SR &= ~TIM_SR_CC1IF;
|
|
if (ttl1_pwm.status == PWM_STATUS_DEFAULT) {
|
|
// here ends startup delay
|
|
// enable drive here
|
|
ttl1_pwm.status = PWM_STATUS_STARTED;
|
|
}
|
|
|
|
//Set duty
|
|
if (ttl1_pwm.pwm > 0) {
|
|
// pwm > 0
|
|
if ((ttl1_pwm.pwm > 0) && (ttl1_pwm.pwm_t < 0)) {
|
|
// if changeing PWM polarity insert dead time
|
|
ttl1_pwm.state = PWM_STATE_POSITIVE_INACTIVE;
|
|
ttl1_pwm.pos_port->BSRR = (1 << (16 + ttl1_pwm.pos_pin));
|
|
ttl1_pwm.neg_port->BSRR = (1 << (16 + ttl1_pwm.neg_pin));
|
|
TIM2->CCR1 = TIM2->CNT + config->pwm_deadtime;
|
|
} else if (ttl1_pwm.state == PWM_STATE_POSITIVE_INACTIVE) {
|
|
ttl1_pwm.state = PWM_STATE_POSITIVE_ACTIVE;
|
|
ttl1_pwm.pos_port->BSRR = (1 << ttl1_pwm.pos_pin);
|
|
ttl1_pwm.neg_port->BSRR = (1 << (16 + ttl1_pwm.neg_pin));
|
|
|
|
TIM2->CCR1 = TIM2->CNT + ttl1_pwm.duty_ticks;
|
|
} else {
|
|
ttl1_pwm.state = PWM_STATE_POSITIVE_INACTIVE;
|
|
ttl1_pwm.pos_port->BSRR = (1 << (16 + ttl1_pwm.pos_pin));
|
|
ttl1_pwm.neg_port->BSRR = (1 << (16 + ttl1_pwm.neg_pin));
|
|
TIM2->CCR1 = TIM2->CNT
|
|
+ (ttl1_pwm.period_ticks - ttl1_pwm.duty_ticks);
|
|
|
|
}
|
|
} else if (ttl1_pwm.pwm < 0) {
|
|
//pwm < 0
|
|
//if((ttl1_pwm.state == PWM_STATE_POSITIVE_INACTIVE) && (ttl1_pwm.state == PWM_STATE_POSITIVE_ACTIVE))
|
|
if ((ttl1_pwm.pwm < 0) && (ttl1_pwm.pwm_t > 0)) {
|
|
// if changeing PWM polarity insert dead time
|
|
ttl1_pwm.state = PWM_STATE_NEGATIVE_INACTIVE;
|
|
ttl1_pwm.pos_port->BSRR = (1 << (16 + ttl1_pwm.pos_pin));
|
|
ttl1_pwm.neg_port->BSRR = (1 << (16 + ttl1_pwm.neg_pin));
|
|
TIM2->CCR1 = TIM2->CNT + config->pwm_deadtime;
|
|
} else if (ttl1_pwm.state == PWM_STATE_NEGATIVE_INACTIVE) {
|
|
ttl1_pwm.state = PWM_STATE_NEGATIVE_ACTIVE;
|
|
ttl1_pwm.pos_port->BSRR = (1 << (16 + ttl1_pwm.pos_pin));
|
|
ttl1_pwm.neg_port->BSRR = (1 << ttl1_pwm.neg_pin);
|
|
TIM2->CCR1 = TIM2->CNT + ttl1_pwm.duty_ticks;
|
|
} else {
|
|
ttl1_pwm.state = PWM_STATE_NEGATIVE_INACTIVE;
|
|
ttl1_pwm.pos_port->BSRR = (1 << (16 + ttl1_pwm.pos_pin));
|
|
ttl1_pwm.neg_port->BSRR = (1 << (16 + ttl1_pwm.neg_pin));
|
|
TIM2->CCR1 = TIM2->CNT
|
|
+ (ttl1_pwm.period_ticks - ttl1_pwm.duty_ticks);
|
|
}
|
|
} else {
|
|
// if pwm == 0
|
|
ttl1_pwm.pos_port->BSRR = (1 << (16 + ttl1_pwm.pos_pin));
|
|
ttl1_pwm.neg_port->BSRR = (1 << (16 + ttl1_pwm.neg_pin));
|
|
TIM2->CCR1 = TIM2->CNT + ttl1_pwm.period_ticks;
|
|
if (ttl1_pwm.state == PWM_STATE_POSITIVE_ACTIVE
|
|
|| ttl1_pwm.state == PWM_STATE_POSITIVE_INACTIVE) {
|
|
ttl1_pwm.state = PWM_STATE_POSITIVE_INACTIVE;
|
|
} else {
|
|
ttl1_pwm.state = PWM_STATE_NEGATIVE_INACTIVE;
|
|
}
|
|
|
|
}
|
|
// store new pwm value as old pwm value for the nex iteration
|
|
ttl1_pwm.pwm_t = ttl1_pwm.pwm;
|
|
}
|
|
if (TIM2->SR & TIM_SR_UIF) {
|
|
//TIM2 overflow interrupt jaust clear update interrupt flag
|
|
TIM2->SR &= ~TIM_SR_UIF;
|
|
|
|
}
|
|
|
|
}
|
|
void DBW_Pwm_Set_Duty(signed int duty, pwm_t *ttl) {
|
|
float tmp;
|
|
unsigned int period_ticks;
|
|
|
|
//check limmits
|
|
if (duty > 10000)
|
|
duty = 10000;
|
|
else if (duty < -10000)
|
|
duty = -10000;
|
|
|
|
//calculate period - needed to change frequency on-the-fly
|
|
period_ticks = (unsigned int) 1000000UL / config->motor_pwm_fq;
|
|
if (duty > 0)
|
|
tmp = (float) period_ticks * (float) duty / 10000.0F;
|
|
else if (duty < 0)
|
|
tmp = (float) period_ticks * (0 - ((float) duty)) / 10000.0F;
|
|
else
|
|
tmp = 20;
|
|
|
|
// check minimum duty period;
|
|
|
|
// do not allow duty cylce <20uS
|
|
if ((period_ticks - (unsigned int) tmp) < 20) {
|
|
tmp = period_ticks - 20;
|
|
if (duty > 0)
|
|
duty = (signed int) tmp * 10000.0F / ttl->period_ticks;
|
|
else if (duty < 0)
|
|
duty = 0 - (signed int) tmp * 10000.0F / ttl->period_ticks;
|
|
} else if (tmp < 20) {
|
|
tmp = 20;
|
|
duty = 0;
|
|
}
|
|
|
|
//update variables
|
|
var.motor_pwm = duty;
|
|
|
|
//apply new settings
|
|
__disable_irq();
|
|
ttl->duty_ticks = (unsigned int) tmp;
|
|
ttl->period_ticks = period_ticks;
|
|
ttl->pwm = duty;
|
|
__enable_irq();
|
|
|
|
}
|
|
|
|
unsigned int intrp_1d_uitable(unsigned int x, unsigned char nx,
|
|
unsigned int *x_table, unsigned int *z_table) {
|
|
int ix;
|
|
long interp, interp3;
|
|
// bound input arguments
|
|
|
|
if (x > x_table[nx - 1])
|
|
return (z_table[nx - 1]);
|
|
else if (x < x_table[0])
|
|
return (z_table[0]);
|
|
// Find bounding indiex in table
|
|
for (ix = nx - 2; ix > -1; ix--) { // Start w highest index
|
|
// because will generally have least time for calculations at hi y
|
|
if (x > x_table[ix]) {
|
|
break;
|
|
}
|
|
}
|
|
if (ix < 0)
|
|
ix = 0;
|
|
// do 1D interpolate
|
|
interp = (long) (x_table[ix + 1] - x_table[ix]);
|
|
if (interp != 0) {
|
|
interp3 = (long) (x - x_table[ix]);
|
|
interp3 = (100 * interp3);
|
|
interp = interp3 / interp;
|
|
}
|
|
return ((unsigned int) (z_table[ix]
|
|
+ interp * (int) (z_table[ix + 1] - z_table[ix]) / 100));
|
|
}
|
|
|
|
signed short intrp_1d_ss_table(signed short x, unsigned char n,
|
|
signed short *x_table, char sgn, signed short *z_table) {
|
|
int ix;
|
|
int interp, interp3;
|
|
// bound input arguments
|
|
if (x > x_table[n - 1])
|
|
return z_table[n - 1];
|
|
|
|
if (x < x_table[0])
|
|
return z_table[0];
|
|
|
|
for (ix = n - 2; ix > -1; ix--) {
|
|
if (x > x_table[ix]) {
|
|
break;
|
|
}
|
|
}
|
|
if (ix < 0)
|
|
ix = 0;
|
|
|
|
interp = x_table[ix + 1] - x_table[ix];
|
|
if (interp != 0) {
|
|
interp3 = (x - x_table[ix]);
|
|
interp3 = (100 * interp3);
|
|
interp = interp3 / interp;
|
|
}
|
|
|
|
return ((short) ((int) z_table[ix]
|
|
+ interp * ((int) z_table[ix + 1] - (int) z_table[ix]) / 100));
|
|
}
|
|
|
|
int intrp_1dstable(signed short x, unsigned char n, signed short *x_table,
|
|
char sgn, signed short *z_table) {
|
|
int ix;
|
|
long interp, interp3;
|
|
// bound input arguments
|
|
if (x > x_table[n - 1]) {
|
|
if (!sgn)
|
|
return ((int) z_table[n - 1]);
|
|
else
|
|
return ((signed int) ((signed short) z_table[n - 1]));
|
|
}
|
|
if (x < x_table[0]) {
|
|
if (!sgn)
|
|
return ((signed int) z_table[0]);
|
|
else
|
|
return ((signed int) ((signed short) z_table[0]));
|
|
}
|
|
for (ix = n - 2; ix > -1; ix--) {
|
|
if (x > x_table[ix]) {
|
|
break;
|
|
}
|
|
}
|
|
if (ix < 0)
|
|
ix = 0;
|
|
|
|
interp = x_table[ix + 1] - x_table[ix];
|
|
if (interp != 0) {
|
|
interp3 = (x - x_table[ix]);
|
|
interp3 = (100 * interp3);
|
|
interp = interp3 / interp;
|
|
}
|
|
if (!sgn)
|
|
return ((signed int) (z_table[ix]
|
|
+ interp * (z_table[ix + 1] - z_table[ix]) / 100));
|
|
else
|
|
return ((int) ((signed short) z_table[ix]
|
|
+ interp
|
|
* ((signed short) z_table[ix + 1]
|
|
- (signed short) z_table[ix]) / 100));
|
|
}
|
|
|
|
void DBW_Start(void) {
|
|
GPIOB->ODR &= ~D1_Pin;
|
|
GPIOB->ODR |= D2_Pin;
|
|
}
|
|
void DBW_Stop(void) {
|
|
GPIOB->ODR |= D1_Pin;
|
|
GPIOB->ODR &= ~D2_Pin;
|
|
|
|
}
|
|
|
|
void DBW_TPS_AutoCal(void) {
|
|
// if time to process autocal
|
|
if ((ac_timer == 0) && (ac_mode != 0)) {
|
|
if (ac_mode == 1) {
|
|
var.status0 |= DBW_STATUS0_PPSTPS_CAL_F;
|
|
DBW_Pwm_Set_Duty((signed short) (-6000), (pwm_t*) &ttl1_pwm);
|
|
DBW_Start();
|
|
ac_timer = 1500;
|
|
ac_mode = 2;
|
|
} else if (ac_mode == 2) {
|
|
uint32_t tmp = 0;
|
|
for (int i = 0; i < 16; i++)
|
|
tmp += Adc_Read(2);
|
|
config->tps1_min = tmp >> 4;
|
|
tmp = 0;
|
|
for (int i = 0; i < 16; i++)
|
|
tmp += Adc_Read(3);
|
|
config->tps2_min = tmp >> 4;
|
|
DBW_Stop();
|
|
ac_timer = 2000;
|
|
ac_mode = 3;
|
|
} else if (ac_mode == 3) {
|
|
DBW_Pwm_Set_Duty((signed short) (9000), (pwm_t*) &ttl1_pwm);
|
|
DBW_Start();
|
|
ac_timer = 1500;
|
|
ac_mode = 4;
|
|
} else if (ac_mode == 4) {
|
|
uint32_t tmp = 0;
|
|
for (int i = 0; i < 16; i++)
|
|
tmp += Adc_Read(2);
|
|
config->tps1_max = tmp >> 4;
|
|
tmp = 0;
|
|
for (int i = 0; i < 16; i++)
|
|
tmp += Adc_Read(3);
|
|
config->tps2_max = tmp >> 4;
|
|
DBW_Stop();
|
|
DBW_Pwm_Set_Duty((signed short) (0), (pwm_t*) &ttl1_pwm);
|
|
Apply_Sensor_Calibration();
|
|
Write_Config();
|
|
ac_timer = 10000;
|
|
ac_mode = 5;
|
|
Comms_Reset(&RX);
|
|
Comms_Reset(&TX);
|
|
USART1->ICR &= ~USART_CR1_RXNEIE;
|
|
NVIC_DisableIRQ(USART1_IRQn);
|
|
|
|
} else if (ac_mode == 5) {
|
|
ac_mode = 0;
|
|
var.status0 &= ~DBW_STATUS0_PPSTPS_CAL_F;
|
|
USART1->ICR |= USART_CR1_RXNEIE;
|
|
NVIC_EnableIRQ(USART1_IRQn);
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void DBW_Read_sensors(void) {
|
|
var.pps1_adc = LPF(700, Adc_Read(0), var.pps1_adc);
|
|
var.pps1 = var.pps1_adc * pps1_gain + pps1_offset;
|
|
|
|
var.pps2_adc = LPF(700, Adc_Read(3), var.pps2_adc); // 1 is orig
|
|
var.pps2 = var.pps2_adc * pps2_gain + pps2_offset;
|
|
|
|
var.pps_delta = var.pps1 - var.pps2;
|
|
var.pps = (var.pps1 + var.pps2) >> 1;
|
|
|
|
//Calculate TPS sensor reading
|
|
var.tps1_adc = LPF(700, Adc_Read(2), var.tps1_adc);
|
|
var.tps1 = var.tps1_adc * tps1_gain + tps1_offset;
|
|
|
|
var.tps2_adc = LPF(700, Adc_Read(1), var.tps2_adc); //3 is orig
|
|
var.tps2 = var.tps2_adc * tps2_gain + tps2_offset;
|
|
|
|
// calculate tps and pps delta and values
|
|
var.tps_delta = var.tps1 - var.tps2;
|
|
var.tps = (var.tps1 + var.tps2) >> 1;
|
|
|
|
var.pps_delta = var.pps1 - var.pps2;
|
|
var.pps = (var.pps1 + var.pps2) >> 1;
|
|
}
|