17 Commits

Author SHA1 Message Date
5bb3ebe1bf Created current fuse logic 2024-04-12 11:51:21 +03:00
22ac8240a2 Added absolute subtract 2024-04-12 11:51:10 +03:00
Andis Zīle
f1edc6e15a Changed logic 2024-04-11 23:03:33 +03:00
Andis Zīle
a05c53401f Saved work 2024-04-10 22:44:02 +03:00
Andis Zīle
8bac1f4787 Finished const voltage output 2024-04-10 21:04:31 +03:00
4adcb7eba9 saved work 2024-04-10 17:53:54 +03:00
f320bfefb7 Changes 2024-04-10 15:46:26 +03:00
8f7e5036e7 Started coil driver class 2024-04-10 15:46:17 +03:00
78de20e05b Created pot class 2024-04-10 15:46:07 +03:00
417ecf4128 Created LED display class 2024-04-10 15:46:00 +03:00
dda6c7a2ad Created button class 2024-04-10 15:45:50 +03:00
6199f3c43f Created default mapping 2024-04-10 15:45:32 +03:00
6d5c8d226f Created OD common pwm class 2024-04-10 15:45:17 +03:00
0b9d6fa780 Created digital IO classes 2024-04-10 15:45:03 +03:00
989d5a1f13 Will redo this 2024-04-10 15:44:41 +03:00
c50b3d90bf board abstraction 2024-04-08 19:40:48 +03:00
dd4ff43515 Prepared for Cpp version 2024-03-12 21:27:25 +02:00
68 changed files with 1189 additions and 4587 deletions

View File

@@ -9,37 +9,19 @@ using namespace bsp;
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
bsp::AnalogIn::AnalogIn(void)
{
this->is_init_done = 0;
return;
}
bsp::AnalogIn::~AnalogIn(void)
{
return;
}
void bsp::AnalogIn::init(uint8_t adc_ch)
bsp::AnalogIn::AnalogIn(uint8_t adc_ch)
{
this->adc_ch = adc_ch;
this->mul = DEF_AIN_MUL;
this->div = DEF_AIN_DIV;
this->offset = DEF_AIN_OFFSET;
this->last_read = 0;
this->is_init_done = 1;
}
uint8_t bsp::AnalogIn::is_init(void)
{
return this->is_init_done;
}
uint16_t bsp::AnalogIn::read(void)
{
if(this->is_init_done==0) return 0;
//Read ADC
uint16_t raw = mcu::adc_read(this->adc_ch);

View File

@@ -12,13 +12,12 @@ static const uint8_t DEF_AIN_DIV = 44;
static const int16_t DEF_AIN_OFFSET = 0;
class AnalogIn
{
public:
AnalogIn(void);
~AnalogIn(void);
{
protected:
uint8_t adc_ch;
void init(uint8_t adc_ch);
uint8_t is_init(void);
public:
AnalogIn(uint8_t adc_ch);
uint8_t mul;
uint8_t div;
@@ -26,12 +25,6 @@ class AnalogIn
uint16_t last_read;
uint16_t read(void);
#ifndef TESTING
protected:
#endif
uint8_t adc_ch;
uint8_t is_init_done;
};
/**** Public function declarations ****/

View File

@@ -1,56 +0,0 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "mcu/mcu_hal.h"
#include "ain_lpf.h"
using namespace bsp;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
bsp::AnalogInLfp::AnalogInLfp(void)
{
this->is_init_done = 0;
return;
}
bsp::AnalogInLfp::~AnalogInLfp(void)
{
return;
}
void bsp::AnalogInLfp::init(uint8_t adc_ch)
{
this->adc_ch = adc_ch;
this->mul = DEF_AIN_MUL;
this->div = DEF_AIN_DIV;
this->offset = DEF_AIN_OFFSET;
this->strength = 0;
this->last_read = 0;
this->last_read_direct = 0;
this->is_init_done = 1;
}
uint16_t bsp::AnalogInLfp::read(void)
{
if(this->is_init_done==0) return 0;
//Read ADC
uint16_t raw = mcu::adc_read(this->adc_ch);
//Convert to mV
this->last_read_direct = util::convert_muldivoff(raw, this->mul, this->div, this->offset);
// Do filtering
uint32_t td0 = ((uint32_t)(255 - this->strength) * this->last_read_direct);
uint32_t td1 = ((uint32_t)(this->strength) * this->last_read);
uint32_t out = (td0 + td1)/255;
this->last_read = util::sat_cast(out);
return this->last_read;
}
/**** Private function definitions ****/

View File

@@ -1,36 +0,0 @@
#ifndef ANALOG_IN_LPF_H_
#define ANALOG_IN_LPF_H_
/**** Includes ****/
#include <stdint.h>
#include "ain.h"
namespace bsp {
/**** Public definitions ****/
class AnalogInLfp : public AnalogIn
{
public:
// New stuff
AnalogInLfp(void);
~AnalogInLfp(void);
void init(uint8_t adc_ch);
uint16_t read(void);
uint8_t strength;
uint16_t last_read_direct;
#ifndef TESTING
protected:
#endif
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* ANALOG_IN_LPF_H_ */

View File

@@ -1,118 +0,0 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "mcu/mcu_hal.h"
#include "board.h"
using namespace bsp;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
bsp::Board::Board(void)
{
this->is_init_done = 0;
return;
}
bsp::Board::~Board(void)
{
return;
}
void bsp::Board::init(boardCfg_t* cfg)
{
// Calculate settings
// Controller setup
mcu::startupCfg_t mcu_cfg;
mcu_cfg.adc_clk = mcu::ADC_DIV64; // 8MHz/64=125kHz
mcu_cfg.pwm_clk = mcu::TIM_DIV1; // 8MHz/1 = 8MHz
mcu_cfg.pwm_top = 4000/(uint16_t)cfg->pwm_f_khz;
mcu_cfg.od_common_is_pwm = cfg->od_common_is_pwm;
mcu::startup(&mcu_cfg);
// Analog inputs
this->out_voltage.init(mcu::ADC_VOUT);
this->out_voltage.mul = 20;
this->out_voltage.div = 1;
this->out_voltage.offset = 0;
this->out_current.init(mcu::ADC_IOUT);
this->out_current.mul = 215;
this->out_current.div = 22;
this->out_current.offset = 0;
this->battery_voltage.init(mcu::ADC_VBAT);
this->battery_voltage.mul = 20;
this->battery_voltage.div = 1;
this->battery_voltage.offset = 0;
this->battery_current.init(mcu::ADC_IBAT);
this->battery_current.mul = 235;
this->battery_current.div = 6;
this->battery_current.offset = 0;
this->ain1.init(mcu::ADC_AIN1);
this->ain2.init(mcu::ADC_AIN2);
// Digital inputs
this->din1.init(mcu::GPIO_DIN1, 0);
this->din2.init(mcu::GPIO_DIN2, 0);
this->din3.init(mcu::GPIO_DIN3, 0);
this->din4.init(mcu::GPIO_DIN4, 0);
this->hvdin1.init(mcu::GPIO_HVDIN1, 1);
this->hvdin2.init(mcu::GPIO_HVDIN2, 1);
this->hvdin3.init(mcu::GPIO_HVDIN3, 1);
this->hvdin3_pull.init(mcu::GPIO_HVDIN3_PULL, 0);
this->freq_pull.init(mcu::GPIO_FREQ_PULL, 0);
// Open-drain outputs
this->od1.init(mcu::GPIO_OD1, 1);
this->od2.init(mcu::GPIO_OD2, 1);
this->od3.init(mcu::GPIO_OD3, 1);
this->od4.init(mcu::GPIO_OD4, 1);
this->od5.init(mcu::GPIO_OD5, 1);
this->od6.init(mcu::GPIO_OD6, 1);
this->od_pwm.init(mcu::PWM_OD, 100);
// PWM driver output
this->out_pwm.init(mcu::PWM_OUT, 95);
this->out_low.init(mcu::GPIO_OUT_LOW, 0);
this->is_init_done = 1;
}
uint8_t bsp::Board::is_init(void)
{
return this->is_init_done;
}
void bsp::Board::read(void)
{
if(this->is_init_done==0) return;
// Update all analog inputs
this->out_voltage.read();
this->out_current.read();
this->battery_voltage.read();
this->battery_current.read();
this->ain1.read();
this->ain2.read();
// Update all digital inputs
this->din1.read();
this->din2.read();
this->din3.read();
this->din4.read();
this->hvdin1.read();
this->hvdin2.read();
this->hvdin3.read();
}
/**** Private function definitions ****/

View File

@@ -1,77 +0,0 @@
#ifndef UDCCD_BOARD_H_
#define UDCCD_BOARD_H_
/**** Includes ****/
#include <stdint.h>
#include "ain.h"
#include "ain_lpf.h"
#include "din.h"
#include "dout.h"
#include "pwm_out.h"
#include "memory.h"
namespace bsp {
/**** Public definitions ****/
class Board
{
public:
typedef struct {
uint8_t pwm_f_khz;
uint8_t od_common_is_pwm;
} boardCfg_t;
Board(void);
~Board(void);
void init(boardCfg_t* cfg);
uint8_t is_init(void);
AnalogIn out_voltage;
AnalogIn out_current;
AnalogIn battery_voltage;
AnalogIn battery_current;
AnalogIn ain1;
AnalogIn ain2;
DigitalIn din1;
DigitalIn din2;
DigitalIn din3;
DigitalIn din4;
DigitalIn hvdin1;
DigitalIn hvdin2;
DigitalIn hvdin3;
DigitalOut hvdin3_pull;
DigitalOut freq_pull;
DigitalOut od1;
DigitalOut od2;
DigitalOut od3;
DigitalOut od4;
DigitalOut od5;
DigitalOut od6;
PwmOut od_pwm;
PwmOut out_pwm;
DigitalOut out_low;
Memory nvmem;
void read(void);
#ifndef TESTING
protected:
#endif
uint8_t is_init_done;
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* UDCCD_BOARD_H_ */

View File

@@ -9,11 +9,15 @@ using namespace bsp;
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
bsp::DigitalIn::DigitalIn(void)
bsp::DigitalIn::DigitalIn(uint8_t gpio_ch, uint8_t inverted, uint8_t init_value)
{
this->is_init_done = 0;
return;
this->gpio_ch = gpio_ch;
this->invert = inverted;
if(init_value) this->last_read = DIN_HIGH;
else this->last_read = DIN_LOW;
}
bsp::DigitalIn::~DigitalIn(void)
@@ -21,36 +25,16 @@ bsp::DigitalIn::~DigitalIn(void)
return;
}
void bsp::DigitalIn::init(uint8_t gpio_ch, uint8_t inverted)
{
this->gpio_ch = gpio_ch;
if(inverted == 0) this->is_inverted = 0;
else this->is_inverted = 1;
this->last_read = 0;
this->is_init_done = 1;
}
uint8_t bsp::DigitalIn::is_init(void)
{
return this->is_init_done;
}
uint8_t bsp::DigitalIn::read(void)
{
if(this->is_init_done==0) return 0;
uint8_t lvl = mcu::gpio_read(this->gpio_ch);
// Read GPIO
this->last_read = mcu::gpio_read(this->gpio_ch);
if(this->invert) lvl = util::invert(lvl);
// Invert if necessary
if(this->is_inverted)
{
if(this->last_read==0) this->last_read = 1;
else this->last_read = 0;
};
if(lvl>0) this->last_read = DIN_HIGH;
else this->last_read = DIN_LOW;
return this->last_read;
}
/**** Private function definitions ****/

View File

@@ -1,5 +1,5 @@
#ifndef DIGITAL_IN_H_
#define DIGITAL_IN_H_
#ifndef DIGITAL_INPUT_H_
#define DIGITAL_INPUT_H_
/**** Includes ****/
#include <stdint.h>
@@ -7,25 +7,22 @@
namespace bsp {
/**** Public definitions ****/
const uint8_t DIN_LOW = 0;
const uint8_t DIN_HIGH = 1;
class DigitalIn
{
public:
DigitalIn(void);
~DigitalIn(void);
{
protected:
uint8_t gpio_ch;
uint8_t invert;
void init(uint8_t gpio_ch, uint8_t inverted);
uint8_t is_init(void);
public:
DigitalIn(uint8_t gpio_ch, uint8_t inverted, uint8_t init_value);
~DigitalIn(void);
uint8_t last_read;
uint8_t read(void);
#ifndef TESTING
protected:
#endif
uint8_t gpio_ch;
uint8_t is_inverted;
uint8_t is_init_done;
};
/**** Public function declarations ****/
@@ -35,4 +32,4 @@ class DigitalIn
} //namespace
#endif /* DIGITAL_IN_H_ */
#endif /* DIGITAL_INPUT_H_ */

34
firmware/src/bsp/dio.cpp Normal file
View File

@@ -0,0 +1,34 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "mcu/mcu_hal.h"
#include "dio.h"
using namespace bsp;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
bsp::DigitalIO::DigitalIO(uint8_t gpio_ch, uint8_t init_value) : DigitalIn(gpio_ch, 0, init_value), DigitalOut(gpio_ch, 0)
{
return;
}
bsp::DigitalIO::~DigitalIO(void)
{
this->write(DOUT_HIZ);
}
uint8_t bsp::DigitalIO::is_io_match(void)
{
if(this->last_set == DOUT_HIZ) return 1;
uint8_t read_lvl = this->read();
if(read_lvl == (uint8_t)this->last_set) return 1;
else return 0;
}
/**** Private function definitions ****/

32
firmware/src/bsp/dio.h Normal file
View File

@@ -0,0 +1,32 @@
#ifndef DIGITAL_IO_H_
#define DIGITAL_IO_H_
/**** Includes ****/
#include <stdint.h>
#include "din.h"
#include "dout.h"
namespace bsp {
/**** Public definitions ****/
const int8_t DIO_LOW = 0;
const int8_t DIO_HIGH = 1;
const int8_t DIO_HIZ = -1;
class DigitalIO : public DigitalIn, public DigitalOut
{
public:
DigitalIO(uint8_t gpio_ch, uint8_t init_value);
~DigitalIO(void);
uint8_t is_io_match(void);
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* DIGITAL_IO_H_ */

View File

@@ -9,32 +9,44 @@ using namespace bsp;
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
bsp::DigitalOut::DigitalOut(void)
bsp::DigitalOut::DigitalOut(uint8_t gpio_ch, uint8_t inverted)
{
this->is_init_done = 0;
return;
this->gpio_ch = gpio_ch;
this->invert = inverted;
this->write(DOUT_HIZ);
}
bsp::DigitalOut::~DigitalOut(void)
{
return;
this->write(DOUT_HIZ);
}
void bsp::DigitalOut::write(int8_t level)
{
if(this->is_init_done==0) return;
if(this->is_inverted)
if(level > 0)
{
if(level==0) level = 1;
else if (level > 0) level = 0;
};
mcu::gpio_write(this->gpio_ch, level);
this->last_writen = level;
this->last_set = DOUT_HIGH;
if(this->invert) mcu::gpio_write(this->gpio_ch, mcu::LEVEL_LOW);
else mcu::gpio_write(this->gpio_ch, mcu::LEVEL_HIGH);
}
else if(level == 0)
{
this->last_set = DOUT_LOW;
if(this->invert) mcu::gpio_write(this->gpio_ch, mcu::LEVEL_HIGH);
else mcu::gpio_write(this->gpio_ch, mcu::LEVEL_LOW);
}
else
{
this->last_set = DOUT_HIZ;
mcu::gpio_write(this->gpio_ch, mcu::LEVEL_HIZ);
}
}
int8_t bsp::DigitalOut::get_set_level(void)
{
return this->last_set;
}
/**** Private function definitions ****/

View File

@@ -1,27 +1,29 @@
#ifndef DIGITAL_OUT_H_
#define DIGITAL_OUT_H_
#ifndef DIGITAL_OUTPUT_H_
#define DIGITAL_OUTPUT_H_
/**** Includes ****/
#include <stdint.h>
#include "din.h"
namespace bsp {
/**** Public definitions ****/
class DigitalOut : public DigitalIn
{
const int8_t DOUT_LOW = 0;
const int8_t DOUT_HIGH = 1;
const int8_t DOUT_HIZ = -1;
class DigitalOut
{
protected:
uint8_t gpio_ch;
uint8_t invert;
int8_t last_set;
public:
// New or redefined stuff
DigitalOut(void);
DigitalOut(uint8_t gpio_ch, uint8_t inverted);
~DigitalOut(void);
int8_t last_writen;
void write(int8_t level);
#ifndef TESTING
protected:
#endif
int8_t get_set_level(void);
};
/**** Public function declarations ****/
@@ -31,4 +33,4 @@ class DigitalOut : public DigitalIn
} //namespace
#endif /* DIGITAL_OUT_H_ */
#endif /* DIGITAL_OUTPUT_H_ */

View File

@@ -0,0 +1,74 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "mcu/mcu_hal.h"
#include "halfbridge.h"
using namespace bsp;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
bsp::Hafbridge::Hafbridge(uint8_t hs_pwm_ch, uint8_t ls_gpio_ch, uint8_t max_dc)
{
this->pwm_ch = hs_pwm_ch;
this->gpio_ch = ls_gpio_ch;
if(max_dc>100) max_dc = 100;
this->max_dc = util::percent_to_16b(max_dc);
this->disable();
}
bsp::Hafbridge::~Hafbridge(void)
{
this->last_duty = 0;
this->disable();
}
void bsp::Hafbridge::write(uint16_t dividend)
{
// Limit duty
if(dividend > this->max_dc) dividend = this->max_dc;
this->last_duty = dividend;
if(this->enabled == 0) return;
// Set PWM
mcu::pwm_write(this->pwm_ch, dividend);
}
void bsp::Hafbridge::write(uint8_t percent)
{
// Convert to dividend/0xFFFF
this->write(util::percent_to_16b(percent));
}
void bsp::Hafbridge::enable(void)
{
mcu::gpio_write(this->gpio_ch, mcu::LEVEL_HIGH);
this->enabled = 1;
this->write(this->last_duty);
}
void bsp::Hafbridge::disable(void)
{
mcu::pwm_write(this->pwm_ch, 0);
mcu::gpio_write(this->gpio_ch, mcu::LEVEL_LOW);
this->enabled = 0;
}
uint8_t bsp::Hafbridge::get_set_duty(void)
{
return this->last_duty;
}
uint8_t bsp::Hafbridge::is_enabled(void)
{
return this->enabled;
}
/**** Private function definitions ****/

View File

@@ -0,0 +1,38 @@
#ifndef HALFBRIDGE_H_
#define HALFBRIDGE_H_
/**** Includes ****/
#include <stdint.h>
namespace bsp {
/**** Public definitions ****/
class Hafbridge
{
protected:
uint8_t pwm_ch;
uint8_t gpio_ch;
uint16_t last_duty;
uint8_t enabled;
uint16_t max_dc;
public:
Hafbridge(uint8_t hs_pwm_ch, uint8_t ls_gpio_ch, uint8_t max_dc);
~Hafbridge(void);
void write(uint16_t dividend);
void write(uint8_t percent);
void enable(void);
void disable(void);
uint8_t get_set_duty(void);
uint8_t is_enabled(void);
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* HALFBRIDGE_H_ */

View File

@@ -9,45 +9,42 @@ namespace mcu {
/**** Public definitions ****/
/*
*/
const uint8_t GPIO0 = 0; //PC5 Mode
const uint8_t GPIO1 = 1; //PC4 Pot
const uint8_t GPIO2 = 2; //PE1 Down
const uint8_t GPIO3 = 3; //PE3 Up
const uint8_t GPIO4 = 4; //PD7 Dimm
const uint8_t GPIO5 = 5; //PB7 Brakes
const uint8_t GPIO6 = 6; //PB6 Handbrake
const uint8_t GPIO7 = 7; //PB5 Handbrake pull
const uint8_t GPIO8 = 8; //PD6 Speed pull
const uint8_t GPIO9 = 9; //PD0 LED0
const uint8_t GPIO10 = 10; //PD1 LED1
const uint8_t GPIO11 = 11; //PD2 LED2
const uint8_t GPIO12 = 12; //PD3 LED3
const uint8_t GPIO13 = 13; //PD4 LED4
const uint8_t GPIO14 = 14; //PD5 LED5
const uint8_t GPIO15 = 15; //PB0 DCCD Enable
const uint8_t GPIO16 = 16; //PB1 DCCD PWM
const uint8_t GPIO17 = 17; //PB2 LED PWM
const uint8_t LEVEL_LOW = 0;
const uint8_t LEVEL_HIGH = 1;
const int8_t LEVEL_HIZ = -1;
const int8_t LEVEL_HIZ = -1;
const uint8_t GPIO_DIN1 = 0;
const uint8_t GPIO_DIN2 = 1;
const uint8_t GPIO_DIN3 = 2;
const uint8_t GPIO_DIN4 = 3;
const uint8_t GPIO_HVDIN1 = 4;
const uint8_t GPIO_HVDIN2 = 5;
const uint8_t GPIO_HVDIN3 = 6;
const uint8_t GPIO_HVDIN3_PULL = 7;
const uint8_t GPIO_OD1 = 8;
const uint8_t GPIO_OD2 = 9;
const uint8_t GPIO_OD3 = 10;
const uint8_t GPIO_OD4 = 11;
const uint8_t GPIO_OD5 = 12;
const uint8_t GPIO_OD6 = 13;
const uint8_t GPIO_OUT_LOW = 14;
const uint8_t GPIO_OUT_HIGH = 15;
const uint8_t GPIO_OD_PWM = 16;
const uint8_t GPIO_FREQ1 = 17;
const uint8_t GPIO_FREQ2 = 18;
const uint8_t GPIO_FREQ_PULL = 19;
const uint8_t GPIO_TX = 20;
const uint8_t GPIO_RX = 21;
const uint8_t ADC0 = 0; //Output current
const uint8_t ADC1 = 1; //Output voltage
const uint8_t ADC2 = 2; //Battery voltage
const uint8_t ADC3 = 3; //Battery current
const uint8_t ADC4 = 4; //Potentiometer
const uint8_t ADC5 = 5; //Mode
const uint8_t ADC8 = 8; //MCU temperature
const uint8_t ADC14 = 14; //MCU internal reference
const uint8_t ADC15 = 15; //MCU ground
const uint8_t ADC_IOUT = 0; //Output current
const uint8_t ADC_VOUT = 1; //Output voltage
const uint8_t ADC_VBAT = 2; //Battery voltage
const uint8_t ADC_IBAT = 3; //Battery current
const uint8_t ADC_AIN2 = 4; //Potentiometer
const uint8_t ADC_AIN1 = 5; //Mode
const uint8_t ADC_TEMP = 8; //MCU temperature
const uint8_t ADC_IVREF = 14; //MCU internal reference
const uint8_t ADC_GND = 15; //MCU ground
const uint8_t PWM_OUT = 0; //DCCD
const uint8_t PWM_OD = 1; //LED
const uint8_t PWM0 = 0; //DCCD
const uint8_t PWM1 = 1; //LED
//ADC definitions
typedef enum {
@@ -73,35 +70,21 @@ typedef struct {
adcClkDiv_t adc_clk;
timerClkDiv_t pwm_clk;
uint16_t pwm_top;
uint8_t od_common_is_pwm;
uint8_t pwm_ch1_en;
} startupCfg_t;
/**** Public function declarations ****/
void startup(startupCfg_t* hwCfg);
uint8_t is_init(void);
void rtc_set_calibration(uint16_t coef);
uint8_t gpio_read(uint8_t ch);
void gpio_write(uint8_t ch, int8_t lvl);
void gpio_write_pull(uint8_t ch, int8_t lvl);
void adc_start(uint8_t ch);
uint8_t adc_is_running(void);
uint8_t adc_is_new(void);
uint16_t adc_read(void);
uint16_t adc_read(uint8_t ch);
void pwm_write(uint8_t ch, uint16_t dc);
uint16_t pwm_read(uint8_t ch);
void timer_reset(uint8_t ch);
uint16_t timer_read(uint8_t ch);
uint16_t timer_read_top(uint8_t ch);
uint32_t timer_convert_us(uint8_t ch, uint16_t raw);
uint32_t timer_convert_ms(uint8_t ch, uint16_t raw);
uint8_t eeprom_read8b(uint16_t address);
uint16_t eeprom_read16b(uint16_t address);
uint32_t eeprom_read32b(uint16_t address);

View File

@@ -7,12 +7,7 @@ using namespace mcu;
/**** Private definitions ****/
/**** Private constants ****/
static const uint8_t def_gpio_read = 0;
/**** Private variables ****/
static volatile uint16_t rtc_ms = 1000;
static volatile uint8_t is_init_done = 0;
/**** Private function declarations ****/
static uint8_t gpio_read_level(uint8_t pin_reg, uint8_t mask);
static void pwm_write_ocx(uint8_t ch, uint16_t value);
@@ -21,8 +16,6 @@ static uint16_t pwm_read_ocx(uint8_t ch);
/**** Public function definitions ****/
void mcu::startup(startupCfg_t* hwCfg)
{
is_init_done = 0;
// Fail-safe GPIO init
PORTB = 0xF8; // Set PORTB pull-ups
DDRB = 0x00; // Set all as inputs
@@ -41,9 +34,9 @@ void mcu::startup(startupCfg_t* hwCfg)
DDRB |= 0x03; //Set as output
// Common OD PWM pin
if(hwCfg->od_common_is_pwm) PORTB &= ~0x04; //Set low
else PORTB |= 0x04; //Set high
DDRB |= 0x04; //Set as output
if(hwCfg->pwm_ch1_en) PORTB &= ~0x04; //Set low
else PORTB |= 0x04; //Set high
DDRB |= 0x04; //Set as output
// OD control pins
PORTD &= ~0x3F; //Set low (off)
@@ -73,10 +66,6 @@ void mcu::startup(startupCfg_t* hwCfg)
PORTC &= ~0x30; //Pull-up off
DDRC &= ~0x30; //Set as inputs
// Freq-pull control pins
PORTD &= ~0x40; //Set low
DDRD |= 0x40; //Set as output
//ADC configuration
PRR0 &= ~0x01; //Enable ADC power
DIDR0 |= 0x0F; //Disable digital inputs, ADC0-ADC3
@@ -91,7 +80,7 @@ void mcu::startup(startupCfg_t* hwCfg)
//DCCD and LED PWM configuration
PRR0 &= ~0x80; //Enable Timer1 power
TCCR1A = 0xC2; //Connect OC1A, inverted mode
if(hwCfg->od_common_is_pwm) TCCR1A |= 0x30; //Connect OC1B, inverted mode
if(hwCfg->pwm_ch1_en) TCCR1A |= 0x30; //Connect OC1B, inverted mode
TCCR1B = 0x18; //PWM, Phase & Frequency Correct ICR1 top, no clock, WGM:0xE
TCCR1C = 0x00;
TCNT1 = 0x0000;
@@ -103,332 +92,11 @@ void mcu::startup(startupCfg_t* hwCfg)
uint8_t tim1_prescaler = (uint8_t)hwCfg->pwm_clk;
TCCR1B |= tim1_prescaler; //Enable timer
is_init_done = 1;
}
uint8_t mcu::is_init(void)
{
return is_init_done;
}
void mcu::rtc_set_calibration(uint16_t coef)
{
rtc_ms = coef;
}
// GPIO interface functions
uint8_t mcu::gpio_read(uint8_t ch)
{
if(is_init_done==0) return def_gpio_read;
switch(ch)
{
case GPIO_DIN1: // Mode DIN1
return gpio_read_level(PINC,0x20);
case GPIO_DIN2: // Pot DIN2
return gpio_read_level(PINC,0x10);
case GPIO_DIN3: // Down DIN3
return gpio_read_level(PINE,0x02);
case GPIO_DIN4: // Up DIN4
return gpio_read_level(PINE,0x08);
case GPIO_HVDIN1: // Dimm DIN5
return gpio_read_level(PIND,0x80);
case GPIO_HVDIN2: // Brakes DIN6
return gpio_read_level(PINB,0x80);
case GPIO_HVDIN3: // Handbrake DIN7
return gpio_read_level(PINB,0x40);
case GPIO_HVDIN3_PULL: // Handbrake pull DIN8
return gpio_read_level(PINB,0x20);
case GPIO_OD1: // LED 0
return gpio_read_level(PIND,0x01);
case GPIO_OD2: // LED 1
return gpio_read_level(PIND,0x02);
case GPIO_OD3: // LED 2
return gpio_read_level(PIND,0x04);
case GPIO_OD4: // LED 3
return gpio_read_level(PIND,0x08);
case GPIO_OD5: // LED 4
return gpio_read_level(PIND,0x10);
case GPIO_OD6: // LED 5
return gpio_read_level(PIND,0x20);
case GPIO_OUT_LOW: // DCCD Enable
return gpio_read_level(PINB,0x01);
case GPIO_OUT_HIGH: // DCCD PWM
return gpio_read_level(PINB,0x02);
case GPIO_OD_PWM: // LED PWM
return gpio_read_level(PINB,0x04);
case GPIO_FREQ1: // Speed 1
return gpio_read_level(PINE,0x04);
case GPIO_FREQ2: // Speed 2
return gpio_read_level(PINE,0x01);
case GPIO_FREQ_PULL: // Speed-pull
return gpio_read_level(PIND,0x40);
case GPIO_TX: //
return gpio_read_level(PINB,0x08);
case GPIO_RX: //
return gpio_read_level(PINB,0x10);
default:
return def_gpio_read;
}
}
void mcu::gpio_write(uint8_t ch, int8_t lvl)
{
if(is_init_done==0) return;
switch(ch)
{
case GPIO_DIN1: // Mode DIN1
if(lvl>0)
{
PORTC |= 0x20;
DDRC |= 0x20;
}
else if(lvl<0)
{
DDRC &= ~0x20;
PORTC &= ~0x20;
}
else
{
PORTC &= ~0x20;
DDRC |= 0x20;
}
return;
case GPIO_DIN2: // Pot DIN2
if(lvl>0)
{
PORTC |= 0x10;
DDRC |= 0x10;
}
else if(lvl<0)
{
DDRC &= ~0x10;
PORTC &= ~0x10;
}
else
{
PORTC &= ~0x10;
DDRC |= 0x10;
}
return;
case GPIO_DIN3: // Down DIN3
if(lvl>0)
{
PORTE |= 0x02;
DDRE |= 0x02;
}
else if(lvl<0)
{
DDRE &= ~0x02;
PORTE &= ~0x02;
}
else
{
PORTE &= ~0x02;
DDRE |= 0x02;
}
return;
case GPIO_DIN4: // Up DIN4
if(lvl>0)
{
PORTE |= 0x08;
DDRE |= 0x08;
}
else if(lvl<0)
{
DDRE &= ~0x08;
PORTE &= ~0x08;
}
else
{
PORTE &= ~0x08;
DDRE |= 0x08;
}
return;
case GPIO_HVDIN3_PULL: // Handbrake pull DIN
if(lvl>0)
{
PORTB |= 0x20;
DDRB |= 0x20;
}
else if(lvl<0)
{
DDRB &= ~0x20;
PORTB &= ~0x20;
}
else
{
PORTB &= ~0x20;
DDRB |= 0x20;
}
return;
case GPIO_OD1: // LED 0
if(lvl>0) PORTD |= 0x01;
else PORTD &= ~0x01;
return;
case GPIO_OD2: // LED 1
if(lvl>0) PORTD |= 0x02;
else PORTD &= ~0x02;
return;
case GPIO_OD3: // LED 2
if(lvl>0) PORTD |= 0x04;
else PORTD &= ~0x04;
return;
case GPIO_OD4: // LED 3
if(lvl>0) PORTD |= 0x08;
else PORTD &= ~0x08;
return;
case GPIO_OD5: // LED 4
if(lvl>0) PORTD |= 0x10;
else PORTD &= ~0x10;
return;
case GPIO_OD6: // LED 5
if(lvl>0) PORTD |= 0x20;
else PORTD &= ~0x20;
return;
case GPIO_OUT_LOW: // DCCD Enable
if(lvl>0) PORTB |= 0x01;
else PORTB &= ~0x01;
return;
case GPIO_FREQ_PULL: // Speed-pull
if(lvl>0) PORTD |= 0x40;
else PORTD &= ~0x40;
return;
default:
return;
}
}
void mcu::gpio_write_pull(uint8_t ch, int8_t lvl)
{
if(is_init_done==0) return;
switch(ch)
{
case GPIO_DIN1: // Mode DIN1
if(lvl>0) PORTC |= 0x20;
else PORTC &= ~0x20;
return;
case GPIO_DIN2: // Pot DIN2
if(lvl>0) PORTC |= 0x10;
else PORTC &= ~0x10;
return;
case GPIO_DIN3: // Down DIN3
if(lvl>0) PORTE |= 0x02;
else PORTE &= ~0x02;
return;
case GPIO_DIN4: // Up DIN4
if(lvl>0) PORTE |= 0x08;
else PORTE &= ~0x08;
return;
case GPIO_HVDIN1: // Dimm
if(lvl>0) PORTD |= 0x80;
else PORTD &= ~0x80;
return;
case GPIO_HVDIN2: // Brakes
if(lvl>0) PORTB |= 0x80;
else PORTB &= ~0x80;
return;
case GPIO_HVDIN3: // Handbrake
if(lvl>0) PORTB |= 0x40;
else PORTB &= ~0x40;
return;
default:
return;
}
}
// ADC interface functions
void mcu::adc_start(uint8_t ch)
{
if(is_init_done==0) return;
// check if already running
if(ADCSRA&0x40) return;
//check if ADC is enabled
if(!(ADCSRA&0x80)) return;
//Safe guard mux
if(ch > 15) return;
// Not available channels
if((ch > 8) && (ch<14)) return;
ADMUX &= ~0x0F;
ADMUX |= ch;
ADCSRA |= 0x10; // Reset int. flag
ADCSRA |= 0x40;
}
uint8_t mcu::adc_is_running(void)
{
if(ADCSRA&0x40) return 1;
else return 0;
}
uint8_t mcu::adc_is_new(void)
{
if(ADCSRA&0x10) return 1;
else return 0;
}
uint16_t mcu::adc_read(void)
{
if(is_init_done==0) return 0;
ADCSRA |= 0x10; // Reset int. flag
return ADC;
}
// ADC Interface functions
uint16_t mcu::adc_read(uint8_t ch)
{
if(is_init_done==0) return 0;
//check if ADC is enabled
if(!(ADCSRA&0x80)) return 0xFFFF;
@@ -444,11 +112,9 @@ uint16_t mcu::adc_read(uint8_t ch)
return ADC;
}
// PWM interface functions
// PWM Timer Interface functions
void mcu::pwm_write(uint8_t ch, uint16_t dc)
{
if(is_init_done==0) return;
dc = 0xFFFF - dc;
// Calculate value as % of TOP
@@ -466,8 +132,6 @@ void mcu::pwm_write(uint8_t ch, uint16_t dc)
uint16_t mcu::pwm_read(uint8_t ch)
{
if(is_init_done==0) return 0;
uint16_t ocrx = pwm_read_ocx(ch);
// Check easy answers
@@ -484,7 +148,252 @@ uint16_t mcu::pwm_read(uint8_t ch)
return (uint16_t)temp;
}
// EEPROM interface functions
uint8_t mcu::gpio_read(uint8_t ch)
{
switch(ch)
{
case GPIO0: // Mode DIN1
return gpio_read_level(PINC,0x20);
case GPIO1: // Pot DIN2
return gpio_read_level(PINC,0x10);
case GPIO2: // Down DIN3
return gpio_read_level(PINE,0x02);
case GPIO3: // Up DIN4
return gpio_read_level(PINE,0x08);
case GPIO4: // Dimm DIN5
return gpio_read_level(PIND,0x80);
case GPIO5: // Brakes DIN6
return gpio_read_level(PINB,0x80);
case GPIO6: // Handbrake DIN7
return gpio_read_level(PINB,0x40);
case GPIO7: // Handbrake pull DIN8
return gpio_read_level(PINB,0x20);
case GPIO8: // Speed-pull
return gpio_read_level(PIND,0x40);
case GPIO9: // LED 0
return gpio_read_level(PIND,0x01);
case GPIO10: // LED 1
return gpio_read_level(PIND,0x02);
case GPIO11: // LED 2
return gpio_read_level(PIND,0x04);
case GPIO12: // LED 3
return gpio_read_level(PIND,0x08);
case GPIO13: // LED 4
return gpio_read_level(PIND,0x10);
case GPIO14: // LED 5
return gpio_read_level(PIND,0x20);
case GPIO15: // DCCD Enable
return gpio_read_level(PINB,0x01);
case GPIO16: // DCCD PWM
return gpio_read_level(PINB,0x02);
case GPIO17: // LED PWM
return gpio_read_level(PINB,0x04);
default:
return 0;
}
}
void mcu::gpio_write(uint8_t ch, int8_t lvl)
{
switch(ch)
{
case GPIO0: // Mode DIN1
if(lvl>0)
{
PORTC |= 0x20;
DDRC |= 0x20;
}
else if(lvl<0)
{
DDRC &= ~0x20;
PORTC &= ~0x20;
}
else
{
PORTC &= ~0x20;
DDRC |= 0x20;
}
return;
case GPIO1: // Pot DIN2
if(lvl>0)
{
PORTC |= 0x10;
DDRC |= 0x10;
}
else if(lvl<0)
{
DDRC &= ~0x10;
PORTC &= ~0x10;
}
else
{
PORTC &= ~0x10;
DDRC |= 0x10;
}
return;
case GPIO2: // Down DIN3
if(lvl>0)
{
PORTE |= 0x02;
DDRE |= 0x02;
}
else if(lvl<0)
{
DDRE &= ~0x02;
PORTE &= ~0x02;
}
else
{
PORTE &= ~0x02;
DDRE |= 0x02;
}
return;
case GPIO3: // Up DIN4
if(lvl>0)
{
PORTE |= 0x08;
DDRE |= 0x08;
}
else if(lvl<0)
{
DDRE &= ~0x08;
PORTE &= ~0x08;
}
else
{
PORTE &= ~0x08;
DDRE |= 0x08;
}
return;
case GPIO7: // Handbrake pull DIN
if(lvl>0)
{
PORTB |= 0x20;
DDRB |= 0x20;
}
else if(lvl<0)
{
DDRB &= ~0x20;
PORTB &= ~0x20;
}
else
{
PORTB &= ~0x20;
DDRB |= 0x20;
}
return;
case GPIO8: // Speed-pull
if(lvl>0) PORTD |= 0x40;
else PORTD &= ~0x40;
return;
case GPIO9: // LED 0
if(lvl>0) PORTD |= 0x01;
else PORTD &= ~0x01;
return;
case GPIO10: // LED 1
if(lvl>0) PORTD |= 0x02;
else PORTD &= ~0x02;
return;
case GPIO11: // LED 2
if(lvl>0) PORTD |= 0x04;
else PORTD &= ~0x04;
return;
case GPIO12: // LED 3
if(lvl>0) PORTD |= 0x08;
else PORTD &= ~0x08;
return;
case GPIO13: // LED 4
if(lvl>0) PORTD |= 0x10;
else PORTD &= ~0x10;
return;
case GPIO14: // LED 5
if(lvl>0) PORTD |= 0x20;
else PORTD &= ~0x20;
return;
case GPIO15: // DCCD Enable
if(lvl>0) PORTB |= 0x01;
else PORTB &= ~0x01;
return;
default:
return;
}
}
void mcu::gpio_write_pull(uint8_t ch, int8_t lvl)
{
switch(ch)
{
case GPIO0: // Mode DIN1
if(lvl>0) PORTC |= 0x20;
else PORTC &= ~0x20;
return;
case GPIO1: // Pot DIN2
if(lvl>0) PORTC |= 0x10;
else PORTC &= ~0x10;
return;
case GPIO2: // Down DIN3
if(lvl>0) PORTE |= 0x02;
else PORTE &= ~0x02;
return;
case GPIO3: // Up DIN4
if(lvl>0) PORTE |= 0x08;
else PORTE &= ~0x08;
return;
case GPIO4: // Dimm
if(lvl>0) PORTD |= 0x80;
else PORTD &= ~0x80;
return;
case GPIO5: // Brakes
if(lvl>0) PORTB |= 0x80;
else PORTB &= ~0x80;
return;
case GPIO6: // Handbrake
if(lvl>0) PORTB |= 0x40;
else PORTB &= ~0x40;
return;
default:
return;
}
}
uint8_t mcu::eeprom_read8b(uint16_t address)
{
return eeprom_read_byte((uint8_t*)address);
@@ -526,11 +435,11 @@ static void pwm_write_ocx(uint8_t ch, uint16_t value)
{
switch(ch)
{
case PWM_OUT:
case PWM0:
OCR1A = value;
return;
case PWM_OD:
case PWM1:
OCR1B = value;
return;
@@ -543,10 +452,10 @@ static uint16_t pwm_read_ocx(uint8_t ch)
{
switch(ch)
{
case PWM_OUT:
case PWM0:
return OCR1A;
case PWM_OD:
case PWM1:
return OCR1B ;
default:

View File

@@ -1,55 +0,0 @@
/**** Includes ****/
#include "mcu/mcu_hal.h"
#include "memory.h"
using namespace bsp;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
bsp::Memory::Memory(void)
{
return;
}
bsp::Memory::~Memory(void)
{
return;
}
uint8_t bsp::Memory::read_8b(uint16_t address)
{
return mcu::eeprom_read8b(address);
}
uint16_t bsp::Memory::read_16b(uint16_t address)
{
return mcu::eeprom_read16b(address);
}
uint32_t bsp::Memory::read_32b(uint16_t address)
{
return mcu::eeprom_read32b(address);
}
void bsp::Memory::write_8b(uint16_t address, uint8_t value)
{
mcu::eeprom_write8b(address, value);
}
void bsp::Memory::write_16b(uint16_t address, uint16_t value)
{
mcu::eeprom_write16b(address, value);
}
void bsp::Memory::write_32b(uint16_t address, uint32_t value)
{
mcu::eeprom_write32b(address, value);
}
/**** Private function definitions ****/

View File

@@ -1,36 +0,0 @@
#ifndef MEMORY_IN_H_
#define MEMORY_IN_H_
/**** Includes ****/
#include <stdint.h>
namespace bsp {
/**** Public definitions ****/
class Memory
{
public:
Memory(void);
~Memory(void);
uint8_t read_8b(uint16_t address);
uint16_t read_16b(uint16_t address);
uint32_t read_32b(uint16_t address);
void write_8b(uint16_t address, uint8_t value);
void write_16b(uint16_t address, uint16_t value);
void write_32b(uint16_t address, uint32_t value);
#ifndef TESTING
protected:
#endif
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* MEMORY_IN_H_ */

40
firmware/src/bsp/pwm.cpp Normal file
View File

@@ -0,0 +1,40 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "mcu/mcu_hal.h"
#include "pwm.h"
using namespace bsp;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
bsp::PWMout::PWMout(uint8_t pwm_ch)
{
this->pwm_ch = pwm_ch;
this->write(0);
}
bsp::PWMout::~PWMout(void)
{
this->write(0);
}
void bsp::PWMout::write(uint8_t duty)
{
// Convert percent to 16b duty cycle
uint16_t dc = util::percent_to_16b(duty);
// Set PWM
mcu::pwm_write(this->pwm_ch, dc);
this->last_duty = duty;
}
uint8_t bsp::PWMout::get_set_duty(void)
{
return this->last_duty;
}
/**** Private function definitions ****/

31
firmware/src/bsp/pwm.h Normal file
View File

@@ -0,0 +1,31 @@
#ifndef PWM_H_
#define PWM_H_
/**** Includes ****/
#include <stdint.h>
namespace bsp {
/**** Public definitions ****/
class PWMout
{
protected:
uint8_t pwm_ch;
uint8_t last_duty;
public:
PWMout(uint8_t pwm_ch);
~PWMout(void);
void write(uint8_t duty);
uint8_t get_set_duty(void);
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* PWM_H_ */

View File

@@ -1,68 +0,0 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "mcu/mcu_hal.h"
#include "pwm_out.h"
using namespace bsp;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
bsp::PwmOut::PwmOut(void)
{
this->is_init_done = 0;
return;
}
bsp::PwmOut::~PwmOut(void)
{
this->last_duty = 0;
}
void bsp::PwmOut::init(uint8_t pwm_ch, uint8_t max_dc)
{
this->pwm_ch = pwm_ch;
this->last_duty = 0;
if(max_dc>100) max_dc = 100;
this->max_dc = util::percent_to_16b(max_dc);
this->is_init_done = 1;
}
uint8_t bsp::PwmOut::is_init(void)
{
return this->is_init_done;
}
void bsp::PwmOut::write(uint16_t numerator)
{
if(this->is_init_done==0) return;
// Update target
if(numerator > this->max_dc) numerator = this->max_dc;
this->last_duty = numerator;
// Set PWM
mcu::pwm_write(this->pwm_ch, numerator);
}
void bsp::PwmOut::write(uint8_t percent)
{
if(this->is_init_done==0) return;
// Convert to numerator/0xFFFF
this->write(util::percent_to_16b(percent));
}
uint16_t bsp::PwmOut::get_set_duty(void)
{
return this->last_duty;
}
/**** Private function definitions ****/

View File

@@ -1,39 +0,0 @@
#ifndef PWM_OUT_H_
#define PWM_OUT_H_
/**** Includes ****/
#include <stdint.h>
namespace bsp {
/**** Public definitions ****/
class PwmOut
{
public:
PwmOut(void);
~PwmOut(void);
void init(uint8_t pwm_ch, uint8_t max_dc);
uint8_t is_init(void);
void write(uint16_t numerator);
void write(uint8_t percent);
uint16_t get_set_duty(void);
#ifndef TESTING
protected:
#endif
uint8_t pwm_ch;
uint16_t last_duty;
uint16_t max_dc;
uint8_t is_init_done;
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* PWM_OUT_H_ */

View File

@@ -1,117 +0,0 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "brakes.h"
using namespace dccd;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
dccd::Brakes::Brakes(void)
{
return;
}
dccd::Brakes::~Brakes(void)
{
return;
}
void dccd::Brakes::init(dccd::DccdHw* dccd_hw)
{
this->hardware = dccd_hw;
this->mode = OPEN;
this->is_new_mode = 0;
this->is_active = 0;
}
void dccd::Brakes::cfg_debounce(uint16_t dbnc_time)
{
this->hardware->brakes.dbnc_lim = dbnc_time;
}
uint8_t dccd::Brakes::process(void)
{
if(this->hardware->brakes.state > 0)
{
this->is_active = 1;
}
else
{
this->is_active = 0;
}
return this->is_active;
}
Brakes::bmode_t dccd::Brakes::cycle_mode(void)
{
switch(this->mode)
{
case OPEN:
this->mode = KEEP;
break;
case KEEP:
this->mode = LOCK;
break;
case LOCK:
this->mode = OPEN;
break;
default:
this->mode = OPEN;
break;
}
this->is_new_mode = 1;
return this->mode;
}
uint8_t dccd::Brakes::get_mode_int(void)
{
switch(this->mode)
{
case OPEN:
return 0;
case KEEP:
return 1;
case LOCK:
return 2;
default:
return 0;
}
}
void dccd::Brakes::set_mode_int(uint8_t mode_int)
{
switch(mode_int)
{
case 0:
this->mode = OPEN;
break;
case 1:
this->mode = KEEP;
break;
case 2:
this->mode = LOCK;
break;
default:
this->mode = OPEN;
break;
}
}
/**** Private function definitions ***/

View File

@@ -1,49 +0,0 @@
#ifndef DCCD_BRAKES_H_
#define DCCD_BRAKES_H_
/**** Includes ****/
#include <stdint.h>
#include "dccd_hw.h"
namespace dccd {
/**** Public definitions ****/
class Brakes
{
public:
typedef enum
{
OPEN = 0,
KEEP = 1,
LOCK = 2
}bmode_t;
Brakes(void);
~Brakes(void);
void init(dccd::DccdHw* dccd_hw);
bmode_t mode;
uint8_t is_active;
uint8_t is_new_mode;
void cfg_debounce(uint16_t dbnc_time);
bmode_t cycle_mode(void);
uint8_t process(void);
uint8_t get_mode_int(void);
void set_mode_int(uint8_t mode_int);
#ifdef TESTING
protected:
#endif
dccd::DccdHw* hardware;
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* DCCD_BRAKES_H_ */

View File

@@ -1,115 +0,0 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "coil_reg.h"
using namespace dccd;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
dccd::CoilReg::CoilReg(void)
{
return;
}
dccd::CoilReg::~CoilReg(void)
{
return;
}
void dccd::CoilReg::init(dccd::DccdHw* dccd_hw)
{
this->hardware = dccd_hw;
this->lock_current = 4500;
this->ref_resistance = 1500;
this->cc_max_resistance = 2000;
this->cc_min_resistance = 1000;
this->target_force = 0;
this->set_force = 0;
this->disable_protection = 0;
// Config output protection
this->hardware->out_voltage.under_treshold = 0;
this->hardware->out_voltage.over_treshold = 0xFFFF;
this->hardware->out_voltage.hold_time = 200;
this->hardware->out_voltage.cooldown_time = 1000;
this->hardware->out_voltage.auto_reset = 1;
}
void dccd::CoilReg::process(void)
{
// Fix target force
if(this->target_force > 100) this->target_force = 100;
// Check protection
if((this->disable_protection==0)&&(this->hardware->out_voltage.fault!=0))
{
// HiZ
this->hardware->outreg.write_voltage(0);
this->hardware->outreg.write_current(0);
this->hardware->outreg.write_on(0);
this->hardware->out_voltage.under_treshold = 0;
this->set_force = -1;
return;
};
// Check for target changes
if(this->target_force == this->set_force) return;
// Update set force
this->set_force = this->target_force;
if(this->set_force < 0)
{
// HiZ
this->hardware->outreg.write_voltage(0);
this->hardware->outreg.write_current(0);
this->hardware->outreg.write_on(0);
this->hardware->out_voltage.under_treshold = 0;
}
else if(this->set_force == 0)
{
// Open
this->hardware->outreg.write_voltage(0);
this->hardware->outreg.write_current(0);
this->hardware->outreg.write_on(1);
this->hardware->out_voltage.under_treshold = 0;
}
else
{
// Calculate current and voltage settings
this->hardware->outreg.write_current(util::percent_of((uint8_t)this->set_force, this->lock_current));
uint16_t resistance = this->ref_resistance;
if(this->hardware->outreg.cc_mode_en) resistance = this->cc_max_resistance;
this->hardware->outreg.write_voltage(util::sat_mul_kilo(this->hardware->outreg.read_current(), resistance));
this->hardware->outreg.write_on(1);
// Calculate min. voltage
if(this->disable_protection==0) this->hardware->out_voltage.under_treshold = util::sat_mul_kilo(this->hardware->outreg.read_current(), cc_min_resistance);
}
}
uint8_t dccd::CoilReg::is_fault(void)
{
if(this->disable_protection!=0) return 0;
return this->hardware->out_voltage.fault;
}
uint8_t dccd::CoilReg::read_act_force(void)
{
if(this->set_force < 0) return 0;
else return (uint8_t)this->set_force;
}
void dccd::CoilReg::cfg_set_cv_mode(void)
{
this->hardware->outreg.cc_mode_en = 0;
}
void dccd::CoilReg::cfg_set_cc_mode(void)
{
this->hardware->outreg.cc_mode_en = 1;
}
/**** Private function definitions ***/

View File

@@ -1,47 +0,0 @@
#ifndef DCCD_COIL_REG_H_
#define DCCD_COIL_REG_H_
/**** Includes ****/
#include <stdint.h>
#include "dccd_hw.h"
namespace dccd {
/**** Public definitions ****/
class CoilReg
{
public:
CoilReg(void);
~CoilReg(void);
void init(dccd::DccdHw* dccd_hw);
uint16_t lock_current;
uint16_t ref_resistance;
uint16_t cc_max_resistance;
uint16_t cc_min_resistance;
uint8_t disable_protection;
int8_t target_force;
void process(void);
uint8_t read_act_force(void);
void cfg_set_cv_mode(void);
void cfg_set_cc_mode(void);
uint8_t is_fault(void);
#ifdef TESTING
protected:
#endif
dccd::DccdHw* hardware;
int8_t set_force;
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* DCCD_COIL_REG_H_ */

View File

@@ -1,438 +0,0 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "dccd.h"
using namespace dccd;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
dccd::DccdApp::DccdApp(void)
{
return;
}
dccd::DccdApp::~DccdApp(void)
{
return;
}
void dccd::DccdApp::init(DccdHw* dccd_hw, cfg_app_t* def_cfg)
{
this->hardware = dccd_hw;
this->config = def_cfg;
// Memory
this->nvmem.init(dccd_hw);
this->read_nvmem_cfg();
// Set config
this->user_force.init(dccd_hw);
this->user_force.btn_repeat_time = this->config->user_btn_repeat_time;
this->user_force.pot_mode = this->config->pot_mode;
this->user_force.btn_step = this->config->btn_step;
this->user_force.cfg_debounce(this->config->user_btn_dbnc);
this->mode_btn.init(dccd_hw);
this->mode_btn.btn_repeat_time = this->config->mode_btn_repeat_time;
this->mode_btn.cfg_debounce(this->config->user_btn_dbnc);
this->tps.init(dccd_hw);
this->tps.treshold_on = this->config->tps_treshold_on;
this->tps.treshold_off = this->config->tps_treshold_off;
this->tps.timeout_time = this->config->tps_timeout;
this->tps.mode = Thtrottle::MODE0;
this->hbrake.init(dccd_hw);
this->hbrake.latch_time_1 = this->config->hbrake_latch_time_1;
this->hbrake.latch_time_2 = this->config->hbrake_latch_time_2;
this->hbrake.latch_time_3 = this->config->hbrake_latch_time_3;
this->hbrake.mode = Handbrake::LATCH0;
this->hbrake.cfg_debounce(this->config->hbrake_dbnc);
this->brakes.init(dccd_hw);
this->brakes.mode = Brakes::OPEN;
this->brakes.cfg_debounce(this->config->brakes_dbnc);
this->coil_reg.init(dccd_hw);
this->coil_reg.lock_current = this->config->coil_lock_current;
this->coil_reg.ref_resistance = this->config->coil_ref_resistance;
this->coil_reg.cc_max_resistance = this->config->coil_out_max_resistance;
this->coil_reg.cc_min_resistance = this->config->coil_out_min_resistance;
this->coil_reg.target_force = 0;
this->coil_reg.disable_protection = this->config->coil_disable_protection;
if(this->config->coil_cc_mode) this->coil_reg.cfg_set_cc_mode();
else this->coil_reg.cfg_set_cv_mode();
this->dsp.init(dccd_hw);
this->dsp.brigth_pwm = this->config->dsp_brigth_pwm;
this->dsp.dimm_pwm = this->config->dsp_dimm_pwm;
this->dsp.next_image = 0x01;
this->dsp.next_lock_lvl = 0;
this->dsp.next_lock_time = 0;
// Variable config
if(this->user_force.pot_mode!=0) this->config->tps_enabled = 0;
// Restore saved user config
this->user_force.btn_force = this->nvmem.dynamic_cfg.btn_force;
if(this->user_force.btn_force > 100)
{
this->user_force.btn_force = 100;
this->nvmem.dynamic_cfg.btn_force = 100;
};
this->tps.set_mode_int(this->nvmem.dynamic_cfg.tps_mode);
this->hbrake.set_mode_int(this->nvmem.dynamic_cfg.hbrake_mode);
this->brakes.set_mode_int(this->nvmem.dynamic_cfg.brakes_mode);
// Initialize state
this->hardware->read();
this->coil_reg.process();
this->dsp.force_backlight(this->dsp.brigth_pwm);
this->dsp.process();
this->hardware->write();
}
void dccd::DccdApp::process(void)
{
// Update all inputs
this->hardware->read();
// Process pedals
this->tps.process();
this->hbrake.process();
this->brakes.process();
// Process mode
this->mode_btn.process();
if(this->mode_btn.is_new)
{
this->mode_btn.is_new = 0;
if(this->hbrake.is_active)
{
this->hbrake.cycle_mode();
this->nvmem.dynamic_cfg.hbrake_mode = this->hbrake.get_mode_int();
}
else if (this->brakes.is_active)
{
this->brakes.cycle_mode();
this->nvmem.dynamic_cfg.brakes_mode = this->brakes.get_mode_int();
}
else if(this->user_force.pot_mode==0)
{
this->tps.cycle_mode();
this->nvmem.dynamic_cfg.tps_mode = this->tps.get_mode_int();
}
else
{
this->brakes.cycle_mode();
this->nvmem.dynamic_cfg.brakes_mode = this->brakes.get_mode_int();
}
};
// Process user force
this->user_force.process();
if(this->user_force.is_new_btn_force)
{
this->nvmem.dynamic_cfg.btn_force = this->user_force.btn_force;
};
// Calculate new output force
this->coil_reg.target_force = this->calc_next_force();
// Process coil driver
this->coil_reg.process();
// Process display logic
this->dsp_logic();
// Execute outputs
this->hardware->write();
// Save new user config
this->nvmem.update();
}
/**** Private function definitions ***/
int8_t dccd::DccdApp::calc_next_force(void)
{
if(this->hbrake.is_active)
{
return this->config->hbrake_force;
}
else if(this->brakes.is_active)
{
switch(this->brakes.mode)
{
case Brakes::OPEN:
return this->config->brakes_open_force;
case Brakes::KEEP:
return (int8_t)(this->user_force.force);
case Brakes::LOCK:
return this->config->brakes_lock_force;
default:
return 0;
}
}
else
{
// Determine TPS force override
int8_t tps_force = 0;
if((this->config->tps_enabled)&&(this->tps.is_active()))
{
switch(this->tps.mode)
{
case Thtrottle::MODE0:
tps_force = 0;
break;
case Thtrottle::MODE1:
tps_force = this->config->tps_force_1;
break;
case Thtrottle::MODE2:
tps_force = this->config->tps_force_2;
break;
case Thtrottle::MODE3:
tps_force = this->config->tps_force_3;
break;
default:
tps_force = 0;
break;
}
};
// Return biggest of two sources
if(tps_force > (int8_t)this->user_force.force) return tps_force;
else return (int8_t)(this->user_force.force);
}
}
void dccd::DccdApp::dsp_logic(void)
{
// Display image
if(this->hbrake.is_new_mode)
{
this->hbrake.is_new_mode = 0;
uint8_t hbmode_image;
switch(this->hbrake.mode)
{
case Handbrake::LATCH0:
hbmode_image = 0x07;
break;
case Handbrake::LATCH1:
hbmode_image = 0x0E;
break;
case Handbrake::LATCH2:
hbmode_image = 0x1C;
break;
case Handbrake::LATCH3:
hbmode_image = 0x38;
break;
default:
hbmode_image = 0x07;
this->hbrake.mode = Handbrake::LATCH0;
break;
}
this->dsp.write(hbmode_image, 3, this->config->dsp_mode_lock_time);
}
else if(this->brakes.is_new_mode)
{
this->brakes.is_new_mode = 0;
uint8_t bmode_image;
switch(this->brakes.mode)
{
case Brakes::OPEN:
bmode_image = 0x07;
break;
case Brakes::KEEP:
bmode_image = 0x1E;
break;
case Brakes::LOCK:
bmode_image = 0x38;
break;
default:
bmode_image = 0x07;
this->brakes.mode = Brakes::OPEN;
break;
}
this->dsp.write(bmode_image, 3, this->config->dsp_mode_lock_time);
}
else if(this->tps.is_new_mode)
{
this->tps.is_new_mode = 0;
uint8_t tpsmode_image;
switch(this->tps.mode)
{
case Thtrottle::MODE0:
tpsmode_image = 20;
break;
case Thtrottle::MODE1:
tpsmode_image = 60;
break;
case Thtrottle::MODE2:
tpsmode_image = 80;
break;
case Thtrottle::MODE3:
tpsmode_image = 100;
break;
default:
tpsmode_image = 0;
this->tps.mode = Thtrottle::MODE0;
break;
}
this->dsp.write_percent(tpsmode_image, DccdDisplay::BAR20, 3, this->config->dsp_mode_lock_time);
}
else if(this->user_force.is_new_btn_force)
{
this->user_force.is_new_btn_force = 0;
this->dsp.write_percent(this->user_force.force, DccdDisplay::DOT10, 2, this->config->dsp_force_lock_time);
}
else if(this->coil_reg.is_fault())
{
this->dsp.write(0x33, 1, 0);
}
else
{
this->dsp.write_percent(this->coil_reg.read_act_force(), DccdDisplay::DOT10, 0, 0);
};
// Process display
this->dsp.process();
}
void dccd::DccdApp::read_nvmem_cfg(void)
{
if(this->config->force_def_config!=0) return;
Memory::staticmem_t mem_cfg;
this->nvmem.read_static(&mem_cfg);
// Process raw saved config
if(mem_cfg.is_nvmem_cfg != 0x01) return; // No valid config in memory
// Input mode
if((mem_cfg.inp_mode == 0x00)||(mem_cfg.inp_mode == 0x01))
{
this->config->pot_mode = mem_cfg.inp_mode;
};
// Handbrake
this->config->hbrake_latch_time_1 = (uint16_t)mem_cfg.hbrake_t1 * 100;
this->config->hbrake_latch_time_2 = (uint16_t)mem_cfg.hbrake_t2 * 100;
this->config->hbrake_latch_time_3 = (uint16_t)mem_cfg.hbrake_t3 * 100;
this->config->hbrake_dbnc = (uint16_t)mem_cfg.hbrake_dbnc * 10;
if((mem_cfg.hbrake_force <= 100)||(mem_cfg.hbrake_force == 0xFF))
{
this->config->hbrake_force = (int8_t)mem_cfg.hbrake_force;
};
// Brakes
this->config->brakes_dbnc = (uint16_t)mem_cfg.brakes_dnbc * 10;
if((mem_cfg.brakes_open_force <= 100)||(mem_cfg.brakes_open_force == 0xFF))
{
this->config->brakes_open_force = (int8_t)mem_cfg.brakes_open_force;
};
if((mem_cfg.brakes_lock_force <= 100)||(mem_cfg.brakes_lock_force == 0xFF))
{
this->config->brakes_lock_force = (int8_t)mem_cfg.brakes_lock_force;
};
// Throttle position
if((mem_cfg.tps_en == 0x00)||(mem_cfg.tps_en == 0x01))
{
this->config->tps_enabled = mem_cfg.tps_en;
};
if(mem_cfg.tps_on_th <= 100)
{
this->config->tps_treshold_on = mem_cfg.tps_on_th;
};
if(mem_cfg.tps_off_th <= 100)
{
this->config->tps_treshold_off = mem_cfg.tps_off_th;
};
this->config->tps_timeout = (uint16_t)mem_cfg.tps_timeout * 100;
if(mem_cfg.tps_force_1 <= 100)
{
this->config->tps_force_1 = (int8_t)mem_cfg.tps_force_1;
};
if(mem_cfg.tps_force_2 <= 100)
{
this->config->tps_force_2 = (int8_t)mem_cfg.tps_force_2;
};
if(mem_cfg.tps_force_3 <= 100)
{
this->config->tps_force_3 = (int8_t)mem_cfg.tps_force_3;
};
// Coil
if(mem_cfg.coil_lock_current <= 60)
{
this->config->coil_lock_current = (uint16_t)mem_cfg.coil_lock_current * 100;
};
if((mem_cfg.coil_ccm_resistance >= 10)&&(mem_cfg.coil_ccm_resistance <= 20))
{
this->config->coil_ref_resistance = (uint16_t)mem_cfg.coil_ccm_resistance * 100;
};
if((mem_cfg.coil_cvm_resistance >= 10)&&(mem_cfg.coil_cvm_resistance <= 30))
{
this->config->coil_out_max_resistance = (uint16_t)mem_cfg.coil_cvm_resistance * 100;
};
if((mem_cfg.coil_protection_dis == 0x00)||(mem_cfg.coil_protection_dis == 0x01))
{
this->config->coil_disable_protection = mem_cfg.coil_protection_dis;
};
if((mem_cfg.coil_cc_mode_en == 0x00)||(mem_cfg.coil_cc_mode_en == 0x01))
{
this->config->coil_cc_mode = mem_cfg.coil_cc_mode_en;
};
// Display
if(mem_cfg.dsp_brigth_pwm <= 100)
{
this->config->dsp_brigth_pwm = mem_cfg.dsp_brigth_pwm;
};
if(mem_cfg.dsp_dimm_pwm <= 100)
{
this->config->dsp_dimm_pwm = mem_cfg.dsp_dimm_pwm;
};
}

View File

@@ -1,90 +0,0 @@
#ifndef DCCD_APP_H_
#define DCCD_APP_H_
/**** Includes ****/
#include <stdint.h>
#include "dccd_hw.h"
#include "user_force.h"
#include "mode.h"
#include "handbrake.h"
#include "brakes.h"
#include "coil_reg.h"
#include "display.h"
#include "tps.h"
#include "memory.h"
namespace dccd {
/**** Public definitions ****/
class DccdApp
{
public:
typedef struct{
uint16_t user_btn_dbnc;
uint16_t user_btn_repeat_time;
uint8_t pot_mode;
uint8_t btn_step;
uint16_t mode_btn_repeat_time;
uint8_t tps_treshold_on;
uint8_t tps_treshold_off;
uint16_t tps_timeout;
uint16_t hbrake_latch_time_1;
uint16_t hbrake_latch_time_2;
uint16_t hbrake_latch_time_3;
uint16_t hbrake_dbnc;
uint16_t brakes_dbnc;
uint16_t coil_lock_current;
uint16_t coil_ref_resistance;
uint16_t coil_out_max_resistance;
uint16_t coil_out_min_resistance;
uint8_t coil_disable_protection;
uint8_t coil_cc_mode;
uint8_t dsp_brigth_pwm;
uint8_t dsp_dimm_pwm;
int8_t hbrake_force;
int8_t brakes_open_force;
int8_t brakes_lock_force;
uint8_t tps_enabled;
int8_t tps_force_1;
int8_t tps_force_2;
int8_t tps_force_3;
uint16_t dsp_mode_lock_time;
uint16_t dsp_force_lock_time;
uint8_t force_def_config;
} cfg_app_t;
DccdApp(void);
~DccdApp(void);
void init(DccdHw* dccd_hw, cfg_app_t* def_cfg);
void process(void);
UserForce user_force;
ModeBtn mode_btn;
Handbrake hbrake;
Brakes brakes;
CoilReg coil_reg;
DccdDisplay dsp;
Thtrottle tps;
Memory nvmem;
cfg_app_t* config;
#ifdef TESTING
protected:
#endif
DccdHw* hardware;
int8_t calc_next_force(void);
void dsp_logic(void);
void read_nvmem_cfg(void);
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* DCCD_APP_H_ */

View File

@@ -1,190 +0,0 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "dccd_hw.h"
using namespace dccd;
/**** Private definitions ****/
/**** Private constants ****/
static const uint8_t def_dbnc_time = 10;
static const uint16_t def_pot_dead_bot = 500;
static const uint16_t def_pot_dead_top = 4500;
static const uint8_t def_cc_mode_en = 1;
static const uint16_t def_cnter_us = 900;
static const uint16_t def_out_voltage_under_treshold = 0;
static const uint16_t def_out_voltage_over_treshold = 9000;
static const uint16_t def_out_voltage_hold_time = 1000;
static const uint16_t def_out_voltage_cooldown_time = 0;
static const uint16_t def_out_current_under_treshold = 0;
static const uint16_t def_out_current_over_treshold = 6000;
static const uint16_t def_out_current_hold_time = 200;
static const uint16_t def_out_current_cooldown_time = 1000;
static const uint16_t def_battery_voltage_under_treshold = 9000;
static const uint16_t def_battery_voltage_over_treshold = 18000;
static const uint16_t def_battery_voltage_hold_time = 1000;
static const uint16_t def_battery_voltage_cooldown_time = 0;
static const uint16_t def_battery_current_under_treshold = 0;
static const uint16_t def_battery_current_over_treshold = 8000;
static const uint16_t def_battery_current_hold_time = 200;
static const uint16_t def_battery_current_cooldown_time = 1000;
static const uint16_t def_inital_bat_voltage = 12000;
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
dccd::DccdHw::DccdHw(void)
{
return;
}
dccd::DccdHw::~DccdHw(void)
{
return;
}
void dccd::DccdHw::init(dccdHwCfg_t* cfg)
{
// Apply config
bsp::Board::boardCfg_t board_cfg;
board_cfg.pwm_f_khz = cfg->pwm_f_khz;
board_cfg.od_common_is_pwm = 1;
this->board_hw.init(&board_cfg);
this->counter.init(0xFFFF, cfg->counter_step_us);
this->counter.disabled = 0;
this->out_voltage.init(&(this->board_hw.out_voltage), &(this->counter));
this->out_voltage.under_treshold = def_out_voltage_under_treshold;
this->out_voltage.over_treshold = def_out_voltage_over_treshold;
this->out_voltage.hold_time = def_out_voltage_hold_time;
this->out_voltage.cooldown_time = def_out_voltage_cooldown_time;
this->out_voltage.update_ain = 0;
this->out_voltage.auto_reset = 1;
this->out_current.init(&(this->board_hw.out_current), &(this->counter));
this->out_current.under_treshold = def_out_current_under_treshold;
this->out_current.over_treshold = def_out_current_over_treshold;
this->out_current.hold_time = def_out_current_hold_time;
this->out_current.cooldown_time = def_out_current_cooldown_time;
this->out_current.update_ain = 0;
this->out_current.auto_reset = 1;
this->battery_voltage.init(&(this->board_hw.battery_voltage), &(this->counter));
this->battery_voltage.under_treshold = def_battery_voltage_under_treshold;
this->battery_voltage.over_treshold = def_battery_voltage_over_treshold;
this->battery_voltage.hold_time = def_battery_voltage_hold_time;
this->battery_voltage.cooldown_time = def_battery_voltage_cooldown_time;
this->battery_voltage.update_ain = 0;
this->battery_voltage.auto_reset = 1;
this->battery_voltage.last_read = def_inital_bat_voltage;
this->battery_current.init(&(this->board_hw.battery_current), &(this->counter));
this->battery_current.under_treshold = def_battery_current_under_treshold;
this->battery_current.over_treshold = def_battery_current_over_treshold;
this->battery_current.hold_time = def_battery_current_hold_time;
this->battery_current.cooldown_time = def_battery_current_cooldown_time;
this->battery_current.update_ain = 0;
this->battery_current.auto_reset = 1;
this->btn_up.init(&(this->board_hw.din4), 0, &(this->counter), def_dbnc_time);
this->btn_up.update_din = 0;
this->btn_down.init(&(this->board_hw.din3), 0, &(this->counter), def_dbnc_time);
this->btn_down.update_din = 0;
this->btn_mode.init(&(this->board_hw.din1), 0, &(this->counter), def_dbnc_time);
this->btn_mode.update_din = 0;
this->handbrake.init(&(this->board_hw.hvdin3), 0, &(this->counter), def_dbnc_time);
this->handbrake.update_din = 0;
this->brakes.init(&(this->board_hw.hvdin2), 1, &(this->counter), def_dbnc_time);
this->brakes.update_din = 0;
this->dimm.init(&(this->board_hw.hvdin1), 1, &(this->counter), def_dbnc_time);
this->dimm.update_din = 0;
this->pot.init(&(this->board_hw.ain2), def_pot_dead_bot, def_pot_dead_top);
this->pot.update_ain = 0;
hw::OutReg::outRegCfg_t outreg_cfg;
outreg_cfg.pwm_high = &this->board_hw.out_pwm;
outreg_cfg.dout_low = &this->board_hw.out_low;
outreg_cfg.ubat = &this->board_hw.battery_voltage;
outreg_cfg.uout = &this->board_hw.out_voltage;
outreg_cfg.iout = &this->board_hw.out_current;
this->outreg.init(&outreg_cfg);
this->outreg.cc_mode_en = def_cc_mode_en;
this->outreg.update_ain = 0;
hw::LedDisplay::doutCfg_t dsp_cfg;
dsp_cfg.led0_dout_ch = &(this->board_hw.od1);
dsp_cfg.led1_dout_ch = &(this->board_hw.od2);
dsp_cfg.led2_dout_ch = &(this->board_hw.od3);
dsp_cfg.led3_dout_ch = &(this->board_hw.od4);
dsp_cfg.led4_dout_ch = &(this->board_hw.od5);
dsp_cfg.led5_dout_ch = &(this->board_hw.od6);
this->display.init(&dsp_cfg, 0, &(this->counter), &(this->board_hw.od_pwm));
// Apply configuration
if(cfg->handbrake_pull_up)
{
this->board_hw.hvdin3_pull.write(1);
}
else this->board_hw.hvdin3_pull.write(0);
if(cfg->speed_hall)
{
this->board_hw.freq_pull.write(1);
}
else this->board_hw.freq_pull.write(0);
// Set initial output states
this->outreg.write_voltage(0);
this->outreg.write_current(0);
this->outreg.write_on(0);
this->outreg.write_lock(0);
this->outreg.process();
this->display.write_backlight(100);
this->display.write(0x00);
}
void dccd::DccdHw::read(void)
{
// Update low level inputs
this->board_hw.read();
this->counter.increment();
this->out_voltage.process();
this->out_current.process();
this->battery_voltage.process();
this->battery_current.process();
this->btn_up.process();
this->btn_down.process();
this->btn_mode.process();
this->handbrake.process();
this->brakes.process();
this->dimm.process();
this->pot.read();
}
void dccd::DccdHw::write(void)
{
this->display.process();
this->outreg.process();
}
/**** Private function definitions ***/

View File

@@ -1,69 +0,0 @@
#ifndef DCCD_HW_H_
#define DCCD_HW_H_
/**** Includes ****/
#include <stdint.h>
#include "../bsp/board.h"
#include "../utils/vcounter.h"
#include "../hw/button.h"
#include "../hw/led_display.h"
#include "../hw/potentiometer.h"
#include "../hw/out_driver.h"
#include "../hw/safe_ain.h"
#include "../hw/out_reg.h"
namespace dccd {
/**** Public definitions ****/
class DccdHw
{
public:
typedef struct {
uint8_t pwm_f_khz;
uint8_t handbrake_pull_up;
uint8_t speed_hall;
uint16_t counter_step_us;
} dccdHwCfg_t;
DccdHw(void);
~DccdHw(void);
void init(dccdHwCfg_t* cfg);
// Inputs
hw::SafeAin out_voltage;
hw::SafeAin out_current;
hw::SafeAin battery_voltage;
hw::SafeAin battery_current;
hw::Button btn_up;
hw::Button btn_down;
hw::Button btn_mode;
hw::Button handbrake;
hw::Button brakes;
hw::Button dimm;
hw::Potentiometer pot;
// Outputs
hw::LedDisplay display;
hw::OutReg outreg;
void read(void);
void write(void);
#ifdef TESTING
protected:
#endif
bsp::Board board_hw;
util::VCounter counter;
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* DCCD_HW_H_ */

View File

@@ -1,208 +0,0 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "display.h"
using namespace dccd;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
static uint8_t img_gen_dot10(uint8_t percent);
static uint8_t img_gen_dot20(uint8_t percent);
static uint8_t img_gen_bar(uint8_t percent);
/**** Public function definitions ****/
dccd::DccdDisplay::DccdDisplay(void)
{
return;
}
dccd::DccdDisplay::~DccdDisplay(void)
{
return;
}
void dccd::DccdDisplay::init(dccd::DccdHw* dccd_hw)
{
this->hardware = dccd_hw;
this->brigth_pwm = 50;
this->dimm_pwm = 25;
this->next_image = 0x00;
this->next_lock_lvl = 0;
this->next_lock_time = 0;
this->act_image = 0x00;
this->act_lock_lvl = 0;
}
void dccd::DccdDisplay::cfg_debounce(uint16_t dbnc_time)
{
this->hardware->dimm.dbnc_lim = dbnc_time;
}
void dccd::DccdDisplay::write(uint8_t image, uint8_t lock_lvl, uint16_t lock_time)
{
this->next_image = image;
this->next_lock_lvl = lock_lvl;
this->next_lock_time = lock_time;
}
void dccd::DccdDisplay::write_percent(uint8_t percent, dspstyle_t style, uint8_t lock_lvl, uint16_t lock_time)
{
uint8_t img = 0x01;
switch(style)
{
case DOT20:
img = img_gen_dot20(percent);
break;
case BAR20:
img = img_gen_bar(percent);
break;
default:
img = img_gen_dot10(percent);
break;
}
this->write(img, lock_lvl, lock_time);
}
void dccd::DccdDisplay::force_backlight(uint8_t percent)
{
if(percent > this->brigth_pwm) percent = this->brigth_pwm;
this->hardware->display.write_backlight(percent);
}
void dccd::DccdDisplay::process(void)
{
// Process DIMM switch
if(this->hardware->dimm.is_new)
{
this->hardware->dimm.is_new = 0;
if(this->hardware->dimm.state) this->hardware->display.write_backlight(this->dimm_pwm);
else this->hardware->display.write_backlight(this->brigth_pwm);
};
// Image processor
uint8_t update_img = 0;
if(this->next_lock_lvl >= this->act_lock_lvl) update_img = 1;
else if(this->hardware->display.is_cycle_end()) update_img = 1;
if(update_img)
{
this->act_image = this->next_image;
this->act_lock_lvl = this->next_lock_lvl;
this->next_lock_lvl = 0;
if(this->next_lock_time > 0)
{
this->hardware->display.write(this->act_image, this->next_lock_time+1, this->next_lock_time, 1);
}
else
{
this->hardware->display.write(this->act_image);
this->act_lock_lvl = 0;
}
};
}
/**** Private function definitions ***/
static uint8_t img_gen_dot10(uint8_t percent)
{
switch(percent)
{
case 0 ... 5:
return 0x01;
case 6 ... 15:
return 0x03;
case 16 ... 25:
return 0x02;
case 26 ... 35:
return 0x06;
case 36 ... 45:
return 0x04;
case 46 ... 55:
return 0x0C;
case 56 ... 65:
return 0x08;
case 66 ... 75:
return 0x18;
case 76 ... 85:
return 0x10;
case 86 ... 95:
return 0x30;
case 96 ... 100:
return 0x20;
default:
return 0x20;
}
}
static uint8_t img_gen_dot20(uint8_t percent)
{
switch(percent)
{
case 0 ... 10:
return 0x01;
case 11 ... 30:
return 0x02;
case 31 ... 50:
return 0x04;
case 51 ... 70:
return 0x08;
case 71 ... 90:
return 0x10;
case 91 ... 100:
return 0x20;
default:
return 0x20;
}
}
static uint8_t img_gen_bar(uint8_t percent)
{
switch(percent)
{
case 0 ... 10:
return 0x01;
case 11 ... 30:
return 0x03;
case 31 ... 50:
return 0x07;
case 51 ... 70:
return 0x0F;
case 71 ... 90:
return 0x1F;
case 91 ... 100:
return 0x3F;
default:
return 0x3F;
}
}

View File

@@ -1,55 +0,0 @@
#ifndef DCCD_DISPLAY_H_
#define DCCD_DISPLAY_H_
/**** Includes ****/
#include <stdint.h>
#include "dccd_hw.h"
namespace dccd {
/**** Public definitions ****/
class DccdDisplay
{
public:
typedef enum
{
DOT10 = 0,
DOT20 = 1,
BAR20 = 2
} dspstyle_t;
DccdDisplay(void);
~DccdDisplay(void);
void init(dccd::DccdHw* dccd_hw);
void cfg_debounce(uint16_t dbnc_time);
uint8_t brigth_pwm;
uint8_t dimm_pwm;
uint8_t next_image;
uint8_t next_lock_lvl;
uint16_t next_lock_time;
void write(uint8_t image, uint8_t lock_lvl, uint16_t lock_time);
void write_percent(uint8_t percent, dspstyle_t style, uint8_t lock_lvl, uint16_t lock_time);
void force_backlight(uint8_t percent);
void process(void);
#ifdef TESTING
protected:
#endif
dccd::DccdHw* hardware;
uint8_t act_image;
uint8_t act_lock_lvl;
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* DCCD_MODE_BTN_H_ */

View File

@@ -1,175 +0,0 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "handbrake.h"
using namespace dccd;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
dccd::Handbrake::Handbrake(void)
{
return;
}
dccd::Handbrake::~Handbrake(void)
{
return;
}
void dccd::Handbrake::init(dccd::DccdHw* dccd_hw)
{
this->hardware = dccd_hw;
this->latch_time_1 = 750;
this->latch_time_2 = 1500;
this->latch_time_3 = 3000;
this->mode = LATCH0;
this->is_new_mode = 0;
this->is_active = 0;
this->latch_act = 0;
this->start_ts = 0;
}
void dccd::Handbrake::cfg_debounce(uint16_t dbnc_time)
{
this->hardware->handbrake.dbnc_lim = dbnc_time;
}
Handbrake::hbmode_t dccd::Handbrake::cycle_mode(void)
{
switch(this->mode)
{
case LATCH0:
this->mode = LATCH1;
break;
case LATCH1:
this->mode = LATCH2;
break;
case LATCH2:
this->mode = LATCH3;
break;
case LATCH3:
this->mode = LATCH0;
break;
default:
this->mode = LATCH0;
break;
}
this->is_new_mode = 1;
return this->mode;
}
uint8_t dccd::Handbrake::process(void)
{
uint16_t ts_now = this->hardware->counter.read();
if(this->hardware->handbrake.state > 0)
{
if(this->hardware->handbrake.is_new)
{
this->hardware->handbrake.is_new = 0;
// Note start time
this->start_ts = ts_now;
this->latch_act = 1;
};
this->is_active = 1;
}
else if((this->latch_act != 0)&&(this->act_latch_time() != 0))
{
uint16_t td = util::time_delta(this->start_ts, ts_now);
uint32_t td_ms = this->hardware->counter.convert_ms(td);
if(td_ms >= this->act_latch_time())
{
this->latch_act = 0;
if(this->hardware->handbrake.state > 0) this->is_active = 1;
else this->is_active = 0;
};
}
else
{
this->is_active = 0;
}
return this->is_active;
}
uint8_t dccd::Handbrake::get_mode_int(void)
{
switch(this->mode)
{
case LATCH0:
return 0;
case LATCH1:
return 1;
case LATCH2:
return 2;
case LATCH3:
return 3;
default:
return 0;
}
}
void dccd::Handbrake::set_mode_int(uint8_t mode_int)
{
switch(mode_int)
{
case 0:
this->mode = LATCH0;
break;
case 1:
this->mode = LATCH1;
break;
case 2:
this->mode = LATCH2;
break;
case 3:
this->mode = LATCH3;
break;
default:
this->mode = LATCH0;
break;
}
}
/**** Private function definitions ***/
uint16_t dccd::Handbrake::act_latch_time(void)
{
switch(this->mode)
{
case LATCH0:
return 0;
case LATCH1:
return this->latch_time_1;
case LATCH2:
return this->latch_time_2;
case LATCH3:
return this->latch_time_3;
default:
this->mode = LATCH0;
return 0;
}
}

View File

@@ -1,57 +0,0 @@
#ifndef DCCD_HANDBRAKE_H_
#define DCCD_HANDBRAKE_H_
/**** Includes ****/
#include <stdint.h>
#include "dccd_hw.h"
namespace dccd {
/**** Public definitions ****/
class Handbrake
{
public:
typedef enum
{
LATCH0 = 0,
LATCH1 = 1,
LATCH2 = 2,
LATCH3 = 3
}hbmode_t;
Handbrake(void);
~Handbrake(void);
void init(dccd::DccdHw* dccd_hw);
hbmode_t mode;
uint16_t latch_time_1;
uint16_t latch_time_2;
uint16_t latch_time_3;
uint8_t is_new_mode;
uint8_t is_active;
uint8_t process(void);
void cfg_debounce(uint16_t dbnc_time);
hbmode_t cycle_mode(void);
uint8_t get_mode_int(void);
void set_mode_int(uint8_t mode_int);
#ifdef TESTING
protected:
#endif
dccd::DccdHw* hardware;
uint8_t latch_act;
uint16_t start_ts;
uint16_t act_latch_time(void);
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* DCCD_HANDBRAKE_H_ */

View File

@@ -1,257 +0,0 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "memory.h"
using namespace dccd;
/**** Private definitions ****/
/**** Private constants ****/
static uint16_t static_cfg_addr_offset = 0x0000; //0-127
static uint16_t dynamic_cgf_addr_offset = 0x0080; //128+
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
dccd::Memory::Memory(void)
{
return;
}
dccd::Memory::~Memory(void)
{
return;
}
void dccd::Memory::init(dccd::DccdHw* dccd_hw)
{
this->hardware = dccd_hw;
this->read_from_nvmem();
}
void dccd::Memory::update(void)
{
uint16_t addr = dynamic_cgf_addr_offset;
if(this->dynamic_cfg.btn_force != this->dyn_cfg_shadow.btn_force)
{
this->hardware->board_hw.nvmem.write_8b(addr, this->dynamic_cfg.btn_force);
this->dyn_cfg_shadow.btn_force = this->dynamic_cfg.btn_force;
};
addr++;
if(this->dynamic_cfg.tps_mode != this->dyn_cfg_shadow.tps_mode)
{
this->hardware->board_hw.nvmem.write_8b(addr, this->dynamic_cfg.tps_mode);
this->dyn_cfg_shadow.tps_mode = this->dynamic_cfg.tps_mode;
};
addr++;
if(this->dynamic_cfg.hbrake_mode != this->dyn_cfg_shadow.hbrake_mode)
{
this->hardware->board_hw.nvmem.write_8b(addr, this->dynamic_cfg.hbrake_mode);
this->dyn_cfg_shadow.hbrake_mode = this->dynamic_cfg.hbrake_mode;
};
addr++;
if(this->dynamic_cfg.brakes_mode != this->dyn_cfg_shadow.brakes_mode)
{
this->hardware->board_hw.nvmem.write_8b(addr, this->dynamic_cfg.brakes_mode);
this->dyn_cfg_shadow.brakes_mode = this->dynamic_cfg.brakes_mode;
};
addr++;
}
void dccd::Memory::read_static(staticmem_t* cfg_out)
{
uint16_t addr = static_cfg_addr_offset;
cfg_out->is_nvmem_cfg = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->inp_mode = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->hbrake_t1 = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->hbrake_t2 = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->hbrake_t3 = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->hbrake_dbnc = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->brakes_dnbc = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->tps_en = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->tps_on_th = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->tps_off_th = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->tps_timeout = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->tps_force_1 = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->tps_force_2 = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->tps_force_3 = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->hbrake_force = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->brakes_open_force = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->brakes_lock_force = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->coil_lock_current = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->coil_ccm_resistance = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->coil_cvm_resistance = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->coil_protection_dis = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->coil_cc_mode_en = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->dsp_brigth_pwm = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
cfg_out->dsp_dimm_pwm = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
}
void dccd::Memory::write_static(staticmem_t* cfg_in)
{
uint16_t addr = static_cfg_addr_offset;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->is_nvmem_cfg);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->inp_mode);;
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->hbrake_t1);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->hbrake_t2);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->hbrake_t3);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->is_nvmem_cfg);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->brakes_dnbc);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->tps_en);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->tps_on_th);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->tps_off_th);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->tps_timeout);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->tps_force_1);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->tps_force_2);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->tps_force_3);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->hbrake_force);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->brakes_open_force);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->brakes_lock_force);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->coil_lock_current);;
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->coil_ccm_resistance);;
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->coil_cvm_resistance);;
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->coil_protection_dis);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->coil_cc_mode_en);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->dsp_brigth_pwm);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, cfg_in->dsp_dimm_pwm);
addr++;
}
/**** Private function definitions ***/
void dccd::Memory::read_from_nvmem(void)
{
uint16_t addr = dynamic_cgf_addr_offset;
this->dyn_cfg_shadow.btn_force = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
this->dyn_cfg_shadow.tps_mode = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
this->dyn_cfg_shadow.hbrake_mode = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
this->dyn_cfg_shadow.brakes_mode = this->hardware->board_hw.nvmem.read_8b(addr);
addr++;
this->dynamic_cfg.btn_force = this->dyn_cfg_shadow.btn_force;
this->dynamic_cfg.tps_mode = this->dyn_cfg_shadow.tps_mode;
this->dynamic_cfg.hbrake_mode = this->dyn_cfg_shadow.hbrake_mode;
this->dynamic_cfg.brakes_mode = this->dyn_cfg_shadow.brakes_mode;
}
void dccd::Memory::write_to_nvmem(void)
{
uint16_t addr = dynamic_cgf_addr_offset;
this->hardware->board_hw.nvmem.write_8b(addr, this->dyn_cfg_shadow.btn_force);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, this->dyn_cfg_shadow.tps_mode);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, this->dyn_cfg_shadow.hbrake_mode);
addr++;
this->hardware->board_hw.nvmem.write_8b(addr, this->dyn_cfg_shadow.brakes_mode);
addr++;
}

View File

@@ -1,76 +0,0 @@
#ifndef DCCD_MEMORY_H_
#define DCCD_MEMORY_H_
/**** Includes ****/
#include <stdint.h>
#include "dccd_hw.h"
namespace dccd {
/**** Public definitions ****/
class Memory
{
public:
typedef struct{
uint8_t is_nvmem_cfg;
uint8_t inp_mode;
uint8_t hbrake_t1;
uint8_t hbrake_t2;
uint8_t hbrake_t3;
uint8_t hbrake_dbnc;
uint8_t hbrake_force;
uint8_t brakes_dnbc;
uint8_t brakes_open_force;
uint8_t brakes_lock_force;
uint8_t tps_en;
uint8_t tps_on_th;
uint8_t tps_off_th;
uint8_t tps_timeout;
uint8_t tps_force_1;
uint8_t tps_force_2;
uint8_t tps_force_3;
uint8_t coil_lock_current;
uint8_t coil_ccm_resistance;
uint8_t coil_cvm_resistance;
uint8_t coil_protection_dis;
uint8_t coil_cc_mode_en;
uint8_t dsp_brigth_pwm;
uint8_t dsp_dimm_pwm;
} staticmem_t;
typedef struct{
uint8_t btn_force;
uint8_t tps_mode;
uint8_t hbrake_mode;
uint8_t brakes_mode;
} dynamicmem_t;
Memory(void);
~Memory(void);
void init(dccd::DccdHw* dccd_hw);
dynamicmem_t dynamic_cfg;
void update(void);
void read_static(staticmem_t* cfg_out);
void write_static(staticmem_t* cfg_in);
#ifdef TESTING
protected:
#endif
DccdHw* hardware;
dynamicmem_t dyn_cfg_shadow;
void read_from_nvmem(void);
void write_to_nvmem(void);
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* DCCD_MEMORY_H_ */

View File

@@ -1,45 +0,0 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "mode.h"
using namespace dccd;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
dccd::ModeBtn::ModeBtn(void)
{
return;
}
dccd::ModeBtn::~ModeBtn(void)
{
return;
}
void dccd::ModeBtn::init(dccd::DccdHw* dccd_hw)
{
this->hardware = dccd_hw;
this->btn_repeat_time = 0;
this->is_new = 0;
}
void dccd::ModeBtn::cfg_debounce(uint16_t dbnc_time)
{
this->hardware->btn_mode.dbnc_lim = dbnc_time;
}
void dccd::ModeBtn::process(void)
{
if((this->hardware->btn_mode.state==1)&&((this->hardware->btn_mode.is_new)||((this->hardware->btn_mode.time_read() >= this->btn_repeat_time)&&(this->btn_repeat_time!=0))))
{
this->hardware->btn_mode.time_reset();
this->hardware->btn_mode.is_new = 0;
this->is_new = 1;
};
}
/**** Private function definitions ***/

View File

@@ -1,39 +0,0 @@
#ifndef DCCD_MODE_BTN_H_
#define DCCD_MODE_BTN_H_
/**** Includes ****/
#include <stdint.h>
#include "dccd_hw.h"
namespace dccd {
/**** Public definitions ****/
class ModeBtn
{
public:
ModeBtn(void);
~ModeBtn(void);
void init(dccd::DccdHw* dccd_hw);
void cfg_debounce(uint16_t dbnc_time);
uint16_t btn_repeat_time;
uint8_t is_new;
void process(void);
#ifdef TESTING
protected:
#endif
dccd::DccdHw* hardware;
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* DCCD_MODE_BTN_H_ */

View File

@@ -1,158 +0,0 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "tps.h"
using namespace dccd;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
dccd::Thtrottle::Thtrottle(void)
{
return;
}
dccd::Thtrottle::~Thtrottle(void)
{
return;
}
void dccd::Thtrottle::init(dccd::DccdHw* dccd_hw)
{
this->hardware = dccd_hw;
this->treshold_on = 55;
this->treshold_off = 45;
this->timeout_time = 0;
this->start_ts = 0;
this->is_timed_out = 0;
this->mode = MODE0;
this->is_new_mode = 0;
this->is_new = 0;
this->active = 0;
}
Thtrottle::tpsmode_t dccd::Thtrottle::cycle_mode(void)
{
switch(this->mode)
{
case MODE0:
this->mode = MODE1;
break;
case MODE1:
this->mode = MODE2;
break;
case MODE2:
this->mode = MODE3;
break;
case MODE3:
this->mode = MODE0;
break;
default:
this->mode = MODE0;
break;
}
this->is_new_mode = 1;
return this->mode;
}
void dccd::Thtrottle::process(void)
{
uint16_t ts_now = this->hardware->counter.read();
if(this->active)
{
uint16_t td = util::time_delta(this->start_ts, ts_now);
uint32_t td_ms = this->hardware->counter.convert_ms(td);
if((td_ms >= this->timeout_time)&&(this->timeout_time != 0))
{
this->is_timed_out = 1;
this->is_new = 1;
};
if(this->hardware->pot.last_percent <= this->treshold_off)
{
this->active = 0;
this->is_timed_out = 0;
this->start_ts = 0;
this->is_new = 1;
}
else this->active = 1;
}
else
{
if(this->hardware->pot.last_percent >= this->treshold_on)
{
this->start_ts = ts_now;
this->active = 1;
this->is_new = 1;
}
else this->active = 0;
}
}
uint8_t dccd::Thtrottle::get_mode_int(void)
{
switch(this->mode)
{
case MODE0:
return 0;
case MODE1:
return 1;
case MODE2:
return 2;
case MODE3:
return 3;
default:
return 0;
}
}
void dccd::Thtrottle::set_mode_int(uint8_t mode_int)
{
switch(mode_int)
{
case 0:
this->mode = MODE0;
break;
case 1:
this->mode = MODE1;
break;
case 2:
this->mode = MODE2;
break;
case 3:
this->mode = MODE3;
break;
default:
this->mode = MODE0;
break;
}
}
uint8_t dccd::Thtrottle::is_active(void)
{
if(this->is_timed_out) return 0;
else return this->active;
}
/**** Private function definitions ***/

View File

@@ -1,58 +0,0 @@
#ifndef DCCD_TPS_H_
#define DCCD_TPS_H_
/**** Includes ****/
#include <stdint.h>
#include "dccd_hw.h"
namespace dccd {
/**** Public definitions ****/
class Thtrottle
{
public:
typedef enum
{
MODE0 = 0,
MODE1 = 1,
MODE2 = 2,
MODE3 = 3
}tpsmode_t;
Thtrottle(void);
~Thtrottle(void);
void init(dccd::DccdHw* dccd_hw);
uint8_t treshold_on;
uint8_t treshold_off;
uint16_t timeout_time;
tpsmode_t mode;
uint8_t is_new_mode;
uint8_t is_new;
uint8_t is_active(void);
void process(void);
tpsmode_t cycle_mode(void);
uint8_t get_mode_int(void);
void set_mode_int(uint8_t mode_int);
#ifdef TESTING
protected:
#endif
dccd::DccdHw* hardware;
uint16_t start_ts;
uint8_t is_timed_out;
uint8_t active;
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* DCCD_TPS_H_ */

View File

@@ -1,86 +0,0 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "user_force.h"
using namespace dccd;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
dccd::UserForce::UserForce(void)
{
return;
}
dccd::UserForce::~UserForce(void)
{
return;
}
void dccd::UserForce::init(dccd::DccdHw* dccd_hw)
{
this->hardware = dccd_hw;
this->is_new_btn_force = 0;
this->btn_repeat_time = 0;
this->force = 0;
this->pot_mode = 0;
this->btn_force = 0;
this->btn_step = 20;
}
void dccd::UserForce::cfg_debounce(uint16_t dbnc_time)
{
this->hardware->btn_up.dbnc_lim = dbnc_time;
this->hardware->btn_down.dbnc_lim = dbnc_time;
}
void dccd::UserForce::cfg_pot(uint16_t dead_bot, uint16_t dead_top)
{
if(this->pot_mode==0) return;
this->hardware->pot.high_deadzone = dead_top;
this->hardware->pot.low_deadzone = dead_bot;
}
void dccd::UserForce::write_force(uint8_t force)
{
if(force > 100) force = 100;
this->btn_force = force;
this->force = force;
}
uint8_t dccd::UserForce::process(void)
{
if(this->pot_mode)
{
this->force = this->hardware->pot.last_percent;
return this->force;
};
if((this->hardware->btn_up.state==1)&&((this->hardware->btn_up.is_new)||((this->hardware->btn_up.time_read() >= this->btn_repeat_time)&&(this->btn_repeat_time!=0))))
{
this->hardware->btn_up.time_reset();
this->hardware->btn_up.is_new = 0;
// Increase user force
this->btn_force += this->btn_step;
if(this->btn_force > 100) this->btn_force = 100;
is_new_btn_force = 1;
};
if((this->hardware->btn_down.state==1)&&((this->hardware->btn_down.is_new)||((this->hardware->btn_down.time_read() >= this->btn_repeat_time)&&(this->btn_repeat_time!=0))))
{
this->hardware->btn_down.time_reset();
this->hardware->btn_down.is_new = 0;
// Decrease user force
this->btn_force -= this->btn_step;
if(this->btn_force > 100) this->btn_force = 0;
is_new_btn_force = 1;
};
this->force = this->btn_force;
return this->force;
}
/**** Private function definitions ***/

View File

@@ -1,45 +0,0 @@
#ifndef DCCD_USER_FORCE_H_
#define DCCD_USER_FORCE_H_
/**** Includes ****/
#include <stdint.h>
#include "dccd_hw.h"
namespace dccd {
/**** Public definitions ****/
class UserForce
{
public:
UserForce(void);
~UserForce(void);
void init(dccd::DccdHw* dccd_hw);
void cfg_debounce(uint16_t dbnc_time);
void cfg_pot(uint16_t dead_bot, uint16_t dead_top);
uint16_t btn_repeat_time;
uint8_t pot_mode;
uint8_t btn_step;
uint8_t force;
uint8_t is_new_btn_force;
uint8_t process(void);
void write_force(uint8_t force);
#ifdef TESTING
protected:
#endif
dccd::DccdHw* hardware;
uint8_t btn_force;
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* DCCD_USER_FORCE_H_ */

View File

@@ -8,10 +8,23 @@ using namespace hw;
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
hw::Button::Button(void)
hw::Button::Button(bsp::DigitalIn* din_ch, uint8_t act_lvl, uint8_t dbnc_lim, uint8_t init_state)
{
return;
this->din_ch = din_ch;
if(act_lvl) this->act_lvl = bsp::DIN_HIGH;
else this->act_lvl = bsp::DIN_LOW;
this->dbnc_cnter = 0;
this->dbnc_lim = dbnc_lim;
if(init_state) this->state = BUTTON_ON;
else this->state = BUTTON_OFF;
this->time = 0;
this->is_new = 0;
}
hw::Button::~Button(void)
@@ -19,67 +32,41 @@ hw::Button::~Button(void)
return;
}
void hw::Button::init(bsp::DigitalIn* din_ch, uint8_t act_lvl, util::VCounter* timer, uint16_t dbnc_lim)
uint8_t hw::Button::update(void)
{
this->din_ch = din_ch;
this->timer = timer;
if(act_lvl) this->act_lvl = 1;
else this->act_lvl = 0;
this->state_start_ts = 0;
this->dbnc_ts = 0;
this->dbnc_lim = dbnc_lim;
this->state = BUTTON_OFF;
this->is_new = 0;
}
uint8_t hw::Button::process(void)
{
// Read din
if(this->update_din) this->din_ch->read();
// Get last read level
// Read din level
uint8_t lvl = this->din_ch->last_read;
// Increase state counter
this->time = util::sat_add(this->time, 1);
// Determine next state
uint8_t next_state = BUTTON_OFF;
if(lvl==this->act_lvl) next_state = BUTTON_ON;
// Advance debounce sample counter
uint16_t ts_now = this->timer->read();
if(next_state != this->state) this->dbnc_cnter++;
else this->dbnc_cnter = 0;
// Check for debounce end
if(this->dbnc_cnter < this->dbnc_lim) return this->state;
// Debounce end. Apply new state.
this->state = next_state;
this->time = 0;
this->is_new = 1;
this->dbnc_cnter = 0;
if(next_state != this->state)
{
if(this->dbnc_ts == 0) this->dbnc_ts = ts_now;
uint16_t td = util::time_delta(this->dbnc_ts, ts_now);
uint32_t td_ms = this->timer->convert_ms(td);
// Check for debounce end
if(td_ms >= this->dbnc_lim)
{
// Debounce end. Apply new state.
this->dbnc_ts = 0;
this->state = next_state;
this->state_start_ts = ts_now;
this->is_new = 1;
};
}
else this->dbnc_ts = 0;
return this->state;
}
uint8_t hw::Button::force_read(void)
uint8_t hw::Button::force_update(void)
{
// Read din
if(this->update_din) this->din_ch->read();
// Get last read level
uint8_t lvl = this->din_ch->last_read;
// Read din level
uint8_t lvl = this->din_ch->read();
// Cancels active debounce
this->dbnc_ts = 0;
this->dbnc_cnter = 0;
// Determine next state
uint8_t next_state = BUTTON_OFF;
@@ -87,30 +74,12 @@ uint8_t hw::Button::force_read(void)
if(next_state != this->state)
{
this->state_start_ts = this->timer->read();
this->state = next_state;
this->time = 0;
this->is_new = 1;
};
return this->state;
}
uint32_t hw::Button::time_read(void)
{
uint16_t ts_now = this->timer->read();
uint16_t td = util::time_delta(this->state_start_ts, ts_now);
return this->timer->convert_ms(td);
}
void hw::Button::time_reset(void)
{
this->state_start_ts = this->timer->read();
}
uint32_t hw::Button::time_read_max(void)
{
uint16_t ts_max = this->timer->read_top();
return this->timer->convert_ms(ts_max);
}
/**** Private function definitions ****/

View File

@@ -1,49 +1,41 @@
#ifndef BUTTONS_H_
#define BUTTONS_H_
#ifndef BUTTON_H_
#define BUTTON_H_
/**** Includes ****/
#include <stdint.h>
#include "../utils/vcounter.h"
#include "../bsp/board.h"
#include "../bsp/din.h"
namespace hw {
/**** Public definitions ****/
const uint8_t BUTTON_OFF = 0;
const uint8_t BUTTON_ON = 1;
const uint8_t BUTTON_OFF = 0;
const uint8_t BUTTON_ON = 1;
class Button
{
protected:
bsp::DigitalIn* din_ch;
uint8_t act_lvl;
uint8_t dbnc_cnter;
public:
Button(void);
Button(bsp::DigitalIn* din_ch, uint8_t act_lvl, uint8_t dbnc_lim, uint8_t init_state);
~Button(void);
uint8_t state;
uint16_t dbnc_lim;
uint16_t time;
uint8_t dbnc_lim;
uint8_t is_new;
uint8_t update_din;
void init(bsp::DigitalIn* din_ch, uint8_t act_lvl, util::VCounter* timer, uint16_t dbnc_lim);
uint8_t process(void);
uint8_t force_read(void);
uint32_t time_read(void);
void time_reset(void);
uint32_t time_read_max(void);
#ifndef TESTING
protected:
#endif
bsp::DigitalIn* din_ch;
util::VCounter* timer;
uint8_t act_lvl;
uint16_t state_start_ts;
uint16_t dbnc_ts;
uint8_t update(void);
uint8_t force_update(void);
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* BUTTONS_H_ */
#endif /* BUTTON_H_ */

View File

@@ -0,0 +1,53 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "cv_output.h"
using namespace hw;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
hw::CVoutput::CVoutput(bsp::Hafbridge* hbridge, bsp::AnalogIn* supply_u)
{
this->hbridge = hbridge;
this->supply = supply_u;
this->target = 0;
this->min_out = 0;
this->hbridge->disable();
}
hw::CVoutput::~CVoutput(void)
{
this->hbridge->write((uint16_t)0x0000);
this->hbridge->disable();
return;
}
void hw::CVoutput::update(void)
{
// Check target
if((this->target < this->min_out)&&(this->target > 0)) this->target = this->min_out;
// Set output
this->hbridge->write(util::sat_ratio(this->target, this->supply->last_read));
}
void hw::CVoutput::enable(void)
{
this->hbridge->enable();
}
void hw::CVoutput::disable(void)
{
this->hbridge->disable();
}
uint8_t hw::CVoutput::is_enabled(void)
{
return this->hbridge->is_enabled();
}
/**** Private function definitions ****/

View File

@@ -0,0 +1,39 @@
#ifndef CONST_VOLTAGE_OUTPUT_H_
#define CONST_VOLTAGE_OUTPUT_H_
/**** Includes ****/
#include <stdint.h>
#include "../bsp/ain.h"
#include "../bsp/halfbridge.h"
namespace hw {
/**** Public definitions ****/
class CVoutput
{
protected:
bsp::Hafbridge* hbridge;
bsp::AnalogIn* supply;
public:
CVoutput(bsp::Hafbridge* hbridge, bsp::AnalogIn* supply_u);
~CVoutput(void);
uint16_t target;
uint16_t min_out;
void update(void);
void enable(void);
void disable(void);
uint8_t is_enabled(void);
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* CONST_VOLTAGE_OUTPUT_H_ */

View File

@@ -0,0 +1,180 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "display_led.h"
using namespace hw;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
static uint8_t img_gen_dot10(uint8_t percent);
static uint8_t img_gen_dot20(uint8_t percent);
static uint8_t img_gen_bar(uint8_t percent);
/**** Public function definitions ****/
hw::DisplayLed::DisplayLed(bsp::DigitalOut* led0, bsp::DigitalOut* led1, bsp::DigitalOut* led2, bsp::DigitalOut* led3, bsp::DigitalOut* led4, bsp::DigitalOut* led5, bsp::PWMout* common)
{
this->led0 = led0;
this->led1 = led1;
this->led2 = led2;
this->led3 = led3;
this->led4 = led4;
this->led5 = led5;
this->common = common;
this->led0->write(0);
this->led1->write(0);
this->led2->write(0);
this->led3->write(0);
this->led4->write(0);
this->led5->write(0);
this->common->write(0);
}
hw::DisplayLed::~DisplayLed(void)
{
this->led0->write(0);
this->led1->write(0);
this->led2->write(0);
this->led3->write(0);
this->led4->write(0);
this->led5->write(0);
this->common->write(0);
}
void hw::DisplayLed::show_percent(uint8_t percent, style_t style)
{
uint8_t image = 0x00;
switch(style)
{
case LED_DSP_BAR:
image = img_gen_bar(percent);
break;
case LED_DSP_DOT10:
image = img_gen_dot10(percent);
break;
default:
image = img_gen_dot20(percent);
break;
}
this->write(image);
}
void hw::DisplayLed::write(uint8_t image)
{
if(image&0x01) this->led0->write(1);
else this->led0->write(0);
if(image&0x02) this->led1->write(1);
else this->led1->write(0);
if(image&0x04) this->led2->write(1);
else this->led2->write(0);
if(image&0x08) this->led3->write(1);
else this->led3->write(0);
if(image&0x10) this->led4->write(1);
else this->led4->write(0);
if(image&0x20) this->led5->write(1);
else this->led5->write(0);
}
void hw::DisplayLed::set_brigthness(uint8_t percent)
{
this->common->write(percent);
}
/**** Private function definitions ****/
static uint8_t img_gen_dot10(uint8_t percent)
{
switch(percent)
{
case 0 ... 5:
return 0x01;
case 6 ... 15:
return 0x03;
case 16 ... 25:
return 0x02;
case 26 ... 35:
return 0x06;
case 36 ... 45:
return 0x04;
case 46 ... 55:
return 0x0C;
case 56 ... 65:
return 0x08;
case 66 ... 75:
return 0x18;
case 76 ... 85:
return 0x10;
case 86 ... 95:
return 0x30;
default:
return 0x20;
}
}
static uint8_t img_gen_dot20(uint8_t percent)
{
switch(percent)
{
case 0 ... 10:
return 0x01;
case 11 ... 30:
return 0x02;
case 31 ... 50:
return 0x04;
case 51 ... 70:
return 0x08;
case 71 ... 90:
return 0x10;
default:
return 0x20;
}
}
static uint8_t img_gen_bar(uint8_t percent)
{
switch(percent)
{
case 0 ... 10:
return 0x01;
case 11 ... 30:
return 0x03;
case 31 ... 50:
return 0x07;
case 51 ... 70:
return 0x0F;
case 71 ... 90:
return 0x1F;
default:
return 0x3F;
}
}

View File

@@ -0,0 +1,47 @@
#ifndef DISPLAY_LED_H_
#define DISPLAY_LED_H_
/**** Includes ****/
#include <stdint.h>
#include "../bsp/dout.h"
#include "../bsp/pwm.h"
namespace hw {
/**** Public definitions ****/
class DisplayLed
{
protected:
bsp::DigitalOut* led0;
bsp::DigitalOut* led1;
bsp::DigitalOut* led2;
bsp::DigitalOut* led3;
bsp::DigitalOut* led4;
bsp::DigitalOut* led5;
bsp::PWMout* common;
public:
typedef enum {
LED_DSP_DOT20,
LED_DSP_DOT10,
LED_DSP_BAR
} style_t;
DisplayLed(bsp::DigitalOut* led0, bsp::DigitalOut* led1, bsp::DigitalOut* led2, bsp::DigitalOut* led3, bsp::DigitalOut* led4, bsp::DigitalOut* led5, bsp::PWMout* common);
~DisplayLed(void);
void show_percent(uint8_t percent, style_t style);
void write(uint8_t image);
void set_brigthness(uint8_t percent);
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* DISPLAY_LED_H_ */

67
firmware/src/hw/fuse.cpp Normal file
View File

@@ -0,0 +1,67 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "../utils/interpolate.h"
#include "fuse.h"
using namespace hw;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
hw::Fuse::Fuse(bsp::AnalogIn* ain_ch)
{
this->hold_current = 0;
this->trip_cycles = 0;
this->warning = 0;
this->fault = 0;
this->cooldown_counter = 0;
this->cooldown_cycles = 0;
this->retry_cnt = 0;
}
hw::Fuse::~Fuse(void)
{
return;
}
void hw::Fuse::update(void)
{
// Under threshold
if(this->ain_ch->last_read <= this->hold_current)
{
// Clear warning flag
this->warning = 0;
// OC energy counter
if(this->oc_counter > 0) this->oc_counter--;
// Cool down fuse
if(this->cooldown_counter > 0) this->cooldown_counter--;
// Auto reset logic
if((this->fault)&&(this->cooldown_counter==0))
{
this->fault = 0;
this->retry_cnt = util::sat_add(this->retry_cnt, 1);
};
return;
};
// Over current condition
this->warning = 1;
// PC energy counter
this->oc_counter = util::sat_add(this->oc_counter, 1);
// Check for trip threshold
if(this->oc_counter < this->trip_cycles) return;
// Trip fuse
this->fault = 1;
this->cooldown_counter = this->cooldown_cycles;
}
/**** Private function definitions ****/

40
firmware/src/hw/fuse.h Normal file
View File

@@ -0,0 +1,40 @@
#ifndef FUSE_H_
#define FUSE_H_
/**** Includes ****/
#include <stdint.h>
#include "../bsp/ain.h"
namespace hw {
/**** Public definitions ****/
class Fuse
{
protected:
bsp::AnalogIn* ain_ch;
uint16_t oc_counter;
uint16_t cooldown_counter;
public:
Fuse(bsp::AnalogIn* ain_ch);
~Fuse(void);
uint16_t hold_current;
uint16_t trip_cycles;
uint8_t warning;
uint8_t fault;
uint16_t cooldown_cycles;
uint8_t retry_cnt;
void update(void);
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* POTENTIOMETER_H_ */

View File

@@ -1,160 +0,0 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "led_display.h"
using namespace hw;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
hw::LedDisplay::LedDisplay(void)
{
return;
}
hw::LedDisplay::~LedDisplay(void)
{
this->force(0x00);
this->write_backlight(0);
}
void hw::LedDisplay::init(doutCfg_t* dout_chs, uint8_t act_lvl, util::VCounter* timer, bsp::PwmOut* pwm_ch)
{
this->led0_dout_ch = dout_chs->led0_dout_ch;
this->led1_dout_ch = dout_chs->led1_dout_ch;
this->led2_dout_ch = dout_chs->led2_dout_ch;
this->led3_dout_ch = dout_chs->led3_dout_ch;
this->led4_dout_ch = dout_chs->led4_dout_ch;
this->led5_dout_ch = dout_chs->led5_dout_ch;
if(act_lvl) this->act_lvl = 1;
else this->act_lvl = 0;
this->timer = timer;
this->pwm_ch = pwm_ch;
this->on_time = 0;
this->period = 0;
this->cycle_cnt = 0;
this->cycle_limit = 0;
this->timestamp_start = 0;
this->image = 0x00;
this->force(0x00);
this->write_backlight(0);
}
void hw::LedDisplay::force(uint8_t image)
{
uint8_t led_state;
if(image&0x01) led_state = 1;
else led_state = 0;
this->set_single_led(led_state, this->led0_dout_ch);
if(image&0x02) led_state = 1;
else led_state = 0;
this->set_single_led(led_state, this->led1_dout_ch);
if(image&0x04) led_state = 1;
else led_state = 0;
this->set_single_led(led_state, this->led2_dout_ch);
if(image&0x08) led_state = 1;
else led_state = 0;
this->set_single_led(led_state, this->led3_dout_ch);
if(image&0x10) led_state = 1;
else led_state = 0;
this->set_single_led(led_state, this->led4_dout_ch);
if(image&0x20) led_state = 1;
else led_state = 0;
this->set_single_led(led_state, this->led5_dout_ch);
}
void hw::LedDisplay::write(uint8_t image)
{
// Static mode
this->on_time = 1;
this->period = 0;
this->cycle_cnt = 0;
this->cycle_limit = 0;
this->timestamp_start = 0;
this->image = image;
// Set initial state
this->force(this->image);
}
void hw::LedDisplay::write(uint8_t image, uint16_t on_time, uint16_t period, uint8_t cycle_limit)
{
// "PWM" mode
this->on_time = on_time;
this->period = period;
this->cycle_cnt = 0;
this->cycle_limit = cycle_limit;
this->image = image;
// Set initial state
if(this->on_time > 0) this->force(this->image);
else this->force(0x00);
// Cycle start time
this->timestamp_start = this->timer->read();
}
void hw::LedDisplay::process(void)
{
if(this->period == 0) return; // Nothing to do
// Update cycle timing
uint16_t ts_now = this->timer->read();
uint16_t td = util::time_delta(this->timestamp_start, ts_now);
uint32_t td_ms = this->timer->convert_ms(td);
if(td_ms >= this->period)
{
this->timestamp_start = ts_now;
this->cycle_cnt++;
};
// Check cycle limit
if((this->cycle_cnt >= this->cycle_limit)&&(this->cycle_limit))
{
this->on_time = 0;
this->period = 0;
this->timestamp_start = 0;
this->force(0x00);
return;
};
// Do output compare
if(td_ms < this->on_time) this->force(this->image);
else this->force(0x00);
}
uint8_t hw::LedDisplay::is_cycle_end(void)
{
if(this->cycle_cnt >= this->cycle_limit) return 1;
else return 0;
}
void hw::LedDisplay::write_backlight(uint8_t percent)
{
this->pwm_ch->write(percent);
}
void hw::LedDisplay::set_single_led(uint8_t state, bsp::DigitalOut* led_ch)
{
uint8_t lvl = 0;
if(((state==0)&&(this->act_lvl==0))||((state!=0)&&(this->act_lvl==1))) lvl = 1;
led_ch->write(lvl);
}
/**** Private function definitions ***/

View File

@@ -1,66 +0,0 @@
#ifndef LED_DISPLAY_H_
#define LED_DISPLAY_H_
/**** Includes ****/
#include <stdint.h>
#include "../utils/vcounter.h"
#include "../bsp/board.h"
namespace hw {
/**** Public definitions ****/
class LedDisplay
{
public:
typedef struct {
bsp::DigitalOut* led0_dout_ch;
bsp::DigitalOut* led1_dout_ch;
bsp::DigitalOut* led2_dout_ch;
bsp::DigitalOut* led3_dout_ch;
bsp::DigitalOut* led4_dout_ch;
bsp::DigitalOut* led5_dout_ch;
} doutCfg_t;
LedDisplay(void);
~LedDisplay(void);
uint16_t on_time;
uint16_t period;
uint8_t cycle_cnt;
uint8_t cycle_limit;
void init(doutCfg_t* dout_chs, uint8_t act_lvl, util::VCounter* timer, bsp::PwmOut* pwm_ch);
void write(uint8_t image);
void write(uint8_t image, uint16_t on_time, uint16_t period, uint8_t cycle_limit);
void process(void);
uint8_t is_cycle_end(void);
void force(uint8_t image);
void write_backlight(uint8_t percent);
#ifdef TESTING
protected:
#endif
bsp::DigitalOut* led0_dout_ch;
bsp::DigitalOut* led1_dout_ch;
bsp::DigitalOut* led2_dout_ch;
bsp::DigitalOut* led3_dout_ch;
bsp::DigitalOut* led4_dout_ch;
bsp::DigitalOut* led5_dout_ch;
uint8_t act_lvl;
util::VCounter* timer;
bsp::PwmOut* pwm_ch;
uint16_t timestamp_start;
uint8_t image;
void set_single_led(uint8_t state, bsp::DigitalOut* led_ch);
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* LED_DISPLAY_H_ */

View File

@@ -1,105 +0,0 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "out_driver.h"
using namespace hw;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
hw::OutDriver::OutDriver(void)
{
return;
}
hw::OutDriver::~OutDriver(void)
{
return;
}
void hw::OutDriver::init(bsp::PwmOut* pwm_high, bsp::DigitalOut* dout_low)
{
this->pwm_high = pwm_high;
this->dout_low = dout_low;
this->target_duty = 0;
this->target_low = 0;
this->disabled = 1;
}
void hw::OutDriver::write(uint16_t numerator)
{
this->target_duty = numerator;
this->target_low = 1;
// Check if enabled
if(this->disabled)
{
return;
};
// Set low side
if(this->dout_low->last_writen == 0)
{
this->dout_low->write(this->target_low);
};
// Set PWM
this->pwm_high->write(this->target_duty);
}
void hw::OutDriver::write(uint8_t percent)
{
// Convert to numerator/0xFFFF
this->write(util::percent_to_16b(percent));
}
void hw::OutDriver::write_hiz(void)
{
this->target_duty = 0;
this->target_low = 0;
// Check if enabled
if(this->disabled)
{
return;
};
// Set PWM
this->pwm_high->write((uint16_t)0);
// Set low side
this->dout_low->write(0);
}
void hw::OutDriver::enable(void)
{
if(this->disabled==0) return;
this->disabled = 0;
if(this->target_low==0) this->write_hiz();
else this->write(this->target_duty);
}
void hw::OutDriver::disable(void)
{
if(this->disabled!=0) return;
// Set PWM
this->pwm_high->write((uint16_t)0);
// Set low side
this->dout_low->write(0);
this->disabled = 1;
}
uint8_t hw::OutDriver::is_disabled(void)
{
return this->disabled;
}
/**** Private function definitions ****/

View File

@@ -1,45 +0,0 @@
#ifndef OUT_DRIVER_H_
#define OUT_DRIVER_H_
/**** Includes ****/
#include <stdint.h>
#include "../bsp/board.h"
namespace hw {
/**** Public definitions ****/
class OutDriver
{
public:
OutDriver(void);
~OutDriver(void);
void init(bsp::PwmOut* pwm_high, bsp::DigitalOut* dout_low);
uint16_t target_duty;
uint8_t target_low;
void write(uint16_t numerator);
void write(uint8_t percent);
void write_hiz(void);
void enable(void);
void disable(void);
uint8_t is_disabled(void);
#ifndef TESTING
protected:
#endif
bsp::PwmOut* pwm_high;
bsp::DigitalOut* dout_low;
uint8_t disabled;
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* OUT_DRIVER_H_ */

View File

@@ -1,139 +0,0 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "out_reg.h"
using namespace bsp;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
hw::OutReg::OutReg(void)
{
return;
}
hw::OutReg::~OutReg(void)
{
return;
}
void hw::OutReg::init(outRegCfg_t* cfg)
{
this->pwm_high = cfg->pwm_high;
this->dout_low = cfg->dout_low;
this->ubat = cfg->ubat;
this->uout = cfg->uout;
this->iout = cfg->iout;
this->voltage = 0;
this->current = 0;
this->out_on = 0;
this->lock = 0;
this->cc_mode_en = 0;
this->update_ain = 0;
this->cc_tolerance = 75;
}
void hw::OutReg::write_voltage(uint16_t voltage)
{
this->voltage = voltage;
}
void hw::OutReg::write_current(uint16_t current)
{
this->current = current;
this->current_bot = util::sat_subtract(current, this->cc_tolerance);
this->current_top = util::sat_add(current, this->cc_tolerance);
}
void hw::OutReg::write_on(uint8_t state)
{
this->out_on = state;
}
void hw::OutReg::write_lock(uint8_t state)
{
this->lock = state;
}
uint16_t hw::OutReg::read_voltage(void)
{
return this->voltage;
}
uint16_t hw::OutReg::read_current(void)
{
return this->current;
}
void hw::OutReg::process(void)
{
// Update analog input
if(this->update_ain)
{
this->ubat->read();
this->uout->read();
this->iout->read();
};
// Check if turned off
if((out_on == 0)||(this->lock != 0))
{
this->pwm_high->write((uint16_t)0);
this->dout_low->write(0);
return;
}
else if(this->dout_low->last_writen == 0)
{
this->dout_low->write(1);
};
// Calculate next duty cycle setting
uint16_t next_duty = this->pwm_high->get_set_duty();
if((this->voltage==0)||(this->current==0))
{
// Off but not HiZ
next_duty = 0;
}
else if((this->cc_mode_en)&&(this->iout->last_read > this->current_bot))
{
// Constant current mode - Change voltage to be within current limit
if(util::is_in_range(this->iout->last_read, this->current_bot, this->current_top)==0)
{
// Current outside of tolerance. Recalculate duty cycle.
uint32_t temp = (uint32_t)this->pwm_high->get_set_duty() * (uint32_t)this->current;
temp /= this->iout->last_read;
next_duty = util::sat_cast(temp);
};
}
else
{
// Constant voltage mode
next_duty = util::sat_ratio(this->voltage, this->ubat->last_read);
}
this->pwm_high->write(next_duty);
return;
}
void hw::OutReg::force_off(void)
{
// Turn off output - HiZ
this->pwm_high->write((uint16_t)0);
this->dout_low->write(0);
// Update targets
this->voltage = 0;
this->current = 0;
this->out_on = 0;
this->lock = 1;
}
/**** Private function definitions ****/

View File

@@ -1,66 +0,0 @@
#ifndef OUTPUT_REGULATOR_H_
#define OUTPUT_REGULATOR_H_
/**** Includes ****/
#include <stdint.h>
#include "../bsp/board.h"
namespace hw {
/**** Public definitions ****/
class OutReg
{
public:
typedef struct {
bsp::PwmOut* pwm_high;
bsp::DigitalOut* dout_low;
bsp::AnalogIn* ubat;
bsp::AnalogIn* uout;
bsp::AnalogIn* iout;
} outRegCfg_t;
OutReg(void);
~OutReg(void);
void init(outRegCfg_t* cfg);
uint8_t cc_mode_en;
uint8_t update_ain;
uint16_t cc_tolerance;
void write_voltage(uint16_t voltage);
void write_current(uint16_t current);
void write_on(uint8_t state);
void write_lock(uint8_t state);
uint16_t read_voltage(void);
uint16_t read_current(void);
void process(void);
void force_off(void);
#ifndef TESTING
protected:
#endif
bsp::PwmOut* pwm_high;
bsp::DigitalOut* dout_low;
bsp::AnalogIn* ubat;
bsp::AnalogIn* uout;
bsp::AnalogIn* iout;
uint16_t voltage;
uint16_t current;
uint16_t current_top;
uint16_t current_bot;
uint8_t out_on;
uint8_t lock;
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* OUTPUT_REGULATOR_H_ */

View File

@@ -11,9 +11,12 @@ using namespace hw;
/**** Private function declarations ****/
/**** Public function definitions ****/
hw::Potentiometer::Potentiometer(void)
hw::Potentiometer::Potentiometer(bsp::AnalogIn* ain_ch, uint16_t low_deadzone, uint16_t high_deadzone)
{
return;
this->ain_ch = ain_ch;
this->low_deadzone = low_deadzone;
this->high_deadzone = high_deadzone;
this->percent = 0;
}
hw::Potentiometer::~Potentiometer(void)
@@ -21,26 +24,12 @@ hw::Potentiometer::~Potentiometer(void)
return;
}
void hw::Potentiometer::init(bsp::AnalogIn* ain_ch, uint16_t low_deadzone, uint16_t high_deadzone)
uint8_t hw::Potentiometer::update(void)
{
this->ain_ch = ain_ch;
this->low_deadzone = low_deadzone;
this->high_deadzone = high_deadzone;
this->last_percent = 0;
this->update_ain = 1;
}
uint8_t hw::Potentiometer::read(void)
{
// Update analog input
if(this->update_ain) this->ain_ch->read();
// Calculate percent
if(this->ain_ch->last_read <= this->low_deadzone) this->last_percent = 0;
else if(this->ain_ch->last_read >= this->high_deadzone ) this->last_percent = 100;
else this->last_percent = util::interpolate(this->ain_ch->last_read, this->low_deadzone, this->high_deadzone, 0, 100);
this->percent = util::interpolate(this->ain_ch->last_read, this->low_deadzone, this->high_deadzone, 0, 100);
return this->last_percent;
return this->percent;
}
/**** Private function definitions ****/

View File

@@ -3,31 +3,26 @@
/**** Includes ****/
#include <stdint.h>
#include "../bsp/board.h"
#include "../bsp/ain.h"
namespace hw {
/**** Public definitions ****/
class Potentiometer
{
public:
Potentiometer(void);
~Potentiometer(void);
{
protected:
bsp::AnalogIn* ain_ch;
void init(bsp::AnalogIn* ain_ch, uint16_t low_deadzone, uint16_t high_deadzone);
public:
Potentiometer(bsp::AnalogIn* ain_ch, uint16_t low_deadzone, uint16_t high_deadzone);
~Potentiometer(void);
uint16_t low_deadzone;
uint16_t high_deadzone;
uint8_t last_percent;
uint8_t update_ain;
uint8_t percent;
uint8_t read(void);
#ifndef TESTING
protected:
#endif
bsp::AnalogIn* ain_ch;
uint8_t update(void);
};
/**** Public function declarations ****/

View File

@@ -1,107 +0,0 @@
/**** Includes ****/
#include "../utils/utils.h"
#include "safe_ain.h"
using namespace hw;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
hw::SafeAin::SafeAin(void)
{
return;
}
hw::SafeAin::~SafeAin(void)
{
return;
}
void hw::SafeAin::init(bsp::AnalogIn* ain_ch, util::VCounter* timer)
{
this->ain_ch = ain_ch;
this->timer = timer;
this->under_treshold = 0;
this->over_treshold = 0xFFFF;
this->hold_time = 0;
this->cooldown_time = 0;
this->update_ain = 0;
this->auto_reset = 0;
this->warning = 0;
this->fault = 0;
this->last_read = 0;
this->ts_state_chnage = 0;
}
void hw::SafeAin::process(void)
{
// Update analog input
if(this->update_ain) this->ain_ch->read();
this->last_read = this->ain_ch->last_read;
// Get current time
uint16_t ts_now = this->timer->read();
// Update over current and warning condition
uint8_t is_outside = 0;
if(this->last_read < this->under_treshold) is_outside = 1;
if(this->last_read > this->over_treshold) is_outside = 1;
// Note start time if new OC condition
if((is_outside!=0)&&(this->warning==0))
{
this->ts_state_chnage = ts_now;
};
// Update warning
if(this->warning)
{
if(is_outside == 0)
{
this->warning = 0;
};
}
else
{
if(is_outside == 1)
{
this->warning = 1;
};
}
//this->warning = is_outside;
if((this->warning==0)&&(this->fault==0)) return;
// Calculate warning condition time
uint16_t td = util::time_delta(this->ts_state_chnage, ts_now);
uint32_t time_ms = this->timer->convert_ms(td);
// Check for fault set
if((this->fault==0)&&(time_ms > (uint32_t)this->hold_time)&&(this->warning!=0))
{
this->fault = 1;
return;
};
// Check if allowed auto reset
if(this->auto_reset==0) return;
// Check for fault reset
if((this->fault!=0)&&(time_ms > (uint32_t)this->cooldown_time))
{
this->fault = 0;
return;
};
}
/**** Private function definitions ****/

View File

@@ -1,50 +0,0 @@
#ifndef SAFE_AIN_H_
#define SAFE_AIN_H_
/**** Includes ****/
#include <stdint.h>
#include "../utils/vcounter.h"
#include "../bsp/board.h"
namespace hw {
/**** Public definitions ****/
class SafeAin
{
public:
SafeAin(void);
~SafeAin(void);
void init(bsp::AnalogIn* ain_ch, util::VCounter* timer);
uint8_t warning;
uint8_t fault;
uint16_t last_read;
uint16_t under_treshold;
uint16_t over_treshold;
uint16_t hold_time;
uint16_t cooldown_time;
uint8_t update_ain;
uint8_t auto_reset;
void process(void);
#ifndef TESTING
protected:
#endif
bsp::AnalogIn* ain_ch;
util::VCounter* timer;
uint16_t ts_state_chnage;
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* SAFE_AIN_H_ */

View File

@@ -1,75 +1,71 @@
/**** Includes ****/
#include "utils/utils.h"
#include "dccd/dccd_hw.h"
#include "dccd/dccd.h"
#include "bsp/mcu/mcu_hal.h"
#include "bsp/ain.h"
#include "bsp/din.h"
#include "bsp/dout.h"
#include "bsp/dio.h"
#include "bsp/halfbridge.h"
#include "bsp/pwm.h"
#include "hw/button.h"
#include "hw/potentiometer.h"
#include "hw/display_led.h"
#include "hw/cv_output.h"
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
static dccd::DccdHw dccd_hw;
static dccd::DccdApp dccd_app;
static dccd::DccdApp::cfg_app_t def_cfg;
static bsp::AnalogIn dccd_i(mcu::ADC0);
static bsp::AnalogIn dccd_u(mcu::ADC1);
static bsp::AnalogIn bat_u(mcu::ADC2);
static bsp::AnalogIn bat_i(mcu::ADC3);
static bsp::Hafbridge hbridge(mcu::PWM0, mcu::GPIO15, 95);
static bsp::AnalogIn ain1(mcu::ADC5); // mode
static bsp::AnalogIn ain2(mcu::ADC4); // pot
static bsp::DigitalIn din1(mcu::GPIO0, 0, bsp::DIN_HIGH); //mode
static bsp::DigitalIn din2(mcu::GPIO1, 0, bsp::DIN_HIGH); //pot
static bsp::DigitalIn din3(mcu::GPIO2, 0, bsp::DIN_HIGH); //down
static bsp::DigitalIn din4(mcu::GPIO3, 0, bsp::DIN_HIGH); //up
static bsp::DigitalIn hvdin1(mcu::GPIO4, 1, bsp::DIN_LOW); //dimm
static bsp::DigitalIn hvdin2(mcu::GPIO5, 1, bsp::DIN_LOW); //brakes
static bsp::DigitalIn hvdin3(mcu::GPIO6, 1, bsp::DIN_LOW); //hbrake
static bsp::DigitalIO hvdin3_pull(mcu::GPIO7, bsp::DIN_HIGH); //hbrake pull
static bsp::DigitalOut odout1(mcu::GPIO9, 1);
static bsp::DigitalOut odout2(mcu::GPIO10, 1);
static bsp::DigitalOut odout3(mcu::GPIO11, 1);
static bsp::DigitalOut odout4(mcu::GPIO12, 1);
static bsp::DigitalOut odout5(mcu::GPIO13, 1);
static bsp::DigitalOut odout6(mcu::GPIO14, 1);
static bsp::PWMout od_pwm(mcu::PWM1);
static hw::Button btn_mode(&din1, bsp::DIN_LOW, 10, hw::BUTTON_OFF);
static hw::Button btn_up(&din4, bsp::DIN_LOW, 10, hw::BUTTON_OFF);
static hw::Button btn_down(&din3, bsp::DIN_LOW, 10, hw::BUTTON_OFF);
static hw::Button sw_dimm(&hvdin1, bsp::DIN_HIGH, 10, hw::BUTTON_OFF);
static hw::Button sw_brakes(&hvdin2, bsp::DIN_HIGH, 10, hw::BUTTON_OFF);
static hw::Button sw_hbrake(&hvdin3, bsp::DIN_LOW, 10, hw::BUTTON_OFF);
static hw::Potentiometer pot(&ain2, 500, 4500);
static hw::DisplayLed display(&odout1, &odout2, &odout3, &odout4, &odout5, &odout6, &od_pwm);
static hw::CVoutput cvout(&hbridge, &bat_u);
/**** Private function declarations ****/
/**** Public function definitions ****/
int main(void)
{
// Hardware setup
dccd::DccdHw::dccdHwCfg_t cfg;
cfg.handbrake_pull_up = 1;
cfg.pwm_f_khz = 16;
cfg.speed_hall = 0;
cfg.counter_step_us = 2000;
dccd_hw.init(&cfg);
// App default config
def_cfg.user_btn_dbnc = 10;
def_cfg.user_btn_repeat_time = 500;
def_cfg.pot_mode = 1;
def_cfg.btn_step = 10;
def_cfg.mode_btn_repeat_time = 700;
def_cfg.tps_treshold_on = 65;
def_cfg.tps_treshold_off = 55;
def_cfg.tps_timeout = 0;
def_cfg.hbrake_latch_time_1 = 750;
def_cfg.hbrake_latch_time_2 = 1500;
def_cfg.hbrake_latch_time_3 = 3000;
def_cfg.hbrake_dbnc = 100;
def_cfg.brakes_dbnc = 100;
def_cfg.coil_lock_current = 4500;
def_cfg.coil_ref_resistance = 1500;
def_cfg.coil_out_max_resistance = 2000;
def_cfg.coil_out_min_resistance = 1000;
def_cfg.coil_disable_protection = 1;
def_cfg.coil_cc_mode = 1;
def_cfg.dsp_brigth_pwm = 40;
def_cfg.dsp_dimm_pwm = 25;
def_cfg.hbrake_force = -1;
def_cfg.brakes_open_force = -1;
def_cfg.brakes_lock_force = 100;
def_cfg.tps_enabled = 0;
def_cfg.tps_force_1 = 60;
def_cfg.tps_force_2 = 80;
def_cfg.tps_force_3 = 100;
def_cfg.dsp_mode_lock_time = 2000;
def_cfg.dsp_force_lock_time = 1000;
def_cfg.force_def_config = 0;
// App setup
dccd_app.init(&dccd_hw, &def_cfg);
// Super loop
while(1)
{
// Do stuff
dccd_app.process();
// End of super loop
continue;
{
continue; // End of super loop
}
// Escape the matrix
return 0;
}
/**** Private function definitions ***/
/**** Private function definitions ***/

View File

@@ -20,10 +20,10 @@
<OverrideVtor>false</OverrideVtor>
<CacheFlash>true</CacheFlash>
<ProgFlashFromRam>true</ProgFlashFromRam>
<RamSnippetAddress>0x20000000</RamSnippetAddress>
<RamSnippetAddress />
<UncachedRange />
<preserveEEPROM>true</preserveEEPROM>
<OverrideVtorValue>exception_table</OverrideVtorValue>
<OverrideVtorValue />
<BootSegment>2</BootSegment>
<ResetRule>0</ResetRule>
<eraseonlaunchrule>0</eraseonlaunchrule>
@@ -40,22 +40,6 @@
</dependencies>
</framework-data>
</AsfFrameworkConfig>
<avrtool>com.atmel.avrdbg.tool.atmelice</avrtool>
<avrtoolserialnumber>J42700001490</avrtoolserialnumber>
<avrdeviceexpectedsignature>0x1E9516</avrdeviceexpectedsignature>
<com_atmel_avrdbg_tool_atmelice>
<ToolOptions>
<InterfaceProperties>
<IspClock>125000</IspClock>
</InterfaceProperties>
<InterfaceName>ISP</InterfaceName>
</ToolOptions>
<ToolType>com.atmel.avrdbg.tool.atmelice</ToolType>
<ToolNumber>J42700001490</ToolNumber>
<ToolName>Atmel-ICE</ToolName>
</com_atmel_avrdbg_tool_atmelice>
<avrtoolinterface>ISP</avrtoolinterface>
<avrtoolinterfaceclock>125000</avrtoolinterfaceclock>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<ToolchainSettings>
@@ -175,40 +159,22 @@
<Compile Include="bsp\ain.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="bsp\ain_lpf.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="bsp\ain_lpf.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="bsp\board.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="bsp\board.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="bsp\din.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="bsp\din.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="bsp\dout.cpp">
<Compile Include="bsp\dio.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="bsp\dout.h">
<Compile Include="bsp\dio.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="bsp\memory.cpp">
<Compile Include="bsp\halfbridge.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="bsp\memory.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="bsp\pwm_out.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="bsp\pwm_out.h">
<Compile Include="bsp\halfbridge.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="bsp\mcu\mcu_hal.h">
@@ -217,64 +183,16 @@
<Compile Include="bsp\mcu\mcu_hal_r8.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\brakes.cpp">
<Compile Include="bsp\dout.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\brakes.h">
<Compile Include="bsp\dout.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\dccd.cpp">
<Compile Include="bsp\pwm.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\dccd.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\dccd_hw.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\dccd_hw.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\display.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\display.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\coil_reg.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\coil_reg.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\handbrake.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\handbrake.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\memory.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\memory.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\mode.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\mode.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\tps.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\tps.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\user_force.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="dccd\user_force.h">
<Compile Include="bsp\pwm.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="hw\button.cpp">
@@ -283,28 +201,22 @@
<Compile Include="hw\button.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="hw\led_display.cpp">
<Compile Include="hw\cv_otput.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="hw\led_display.h">
<Compile Include="hw\cv_output.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="hw\out_reg.cpp">
<Compile Include="hw\display_led.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="hw\out_reg.h">
<Compile Include="hw\display_led.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="hw\safe_ain.cpp">
<Compile Include="hw\fuse.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="hw\safe_ain.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="hw\out_driver.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="hw\out_driver.h">
<Compile Include="hw\fuse.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="hw\potentiometer.cpp">
@@ -328,18 +240,11 @@
<Compile Include="utils\utils.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="utils\vcounter.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="utils\vcounter.h">
<SubType>compile</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Folder Include="bsp" />
<Folder Include="bsp\mcu" />
<Folder Include="hw" />
<Folder Include="dccd" />
<Folder Include="utils" />
</ItemGroup>
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />

View File

@@ -131,7 +131,7 @@ uint16_t util::interpolate_2d(uint16_t x, uint16_t y, uint16_t* x_axis, uint8_t
return interpolate(y, y0, y1, zy0, zy1);
}
uint16_t util::interpolate(uint16_t x, uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1)
uint16_t interpolate(uint16_t x, uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1)
{
int32_t dy = (int32_t)y1 - (int32_t)y0;
int32_t dx = (int32_t)x1 - (int32_t)x0;
@@ -144,7 +144,7 @@ uint16_t util::interpolate(uint16_t x, uint16_t x0, uint16_t x1, uint16_t y0, u
return util::sat_cast(y);
}
uint8_t util::find_interval_end_index(uint16_t val, uint16_t* axis_values, uint8_t len_axis)
uint8_t find_interval_end_index(uint16_t val, uint16_t* axis_values, uint8_t len_axis)
{
for(uint8_t i=0; i<len_axis; i++)
{
@@ -155,7 +155,7 @@ uint8_t util::find_interval_end_index(uint16_t val, uint16_t* axis_values, uint
return len_axis;
}
uint16_t util::index2d_to_index1d(uint8_t ix, uint8_t iy, uint8_t len_x)
uint16_t index2d_to_index1d(uint8_t ix, uint8_t iy, uint8_t len_x)
{
return ((uint16_t)len_x * iy) + ix;
}

View File

@@ -17,18 +17,6 @@ uint8_t util::invert(uint8_t x)
else return 1;
}
uint16_t util::invert(uint16_t x)
{
if(x!=0) return 0;
else return 1;
}
uint32_t util::invert(uint32_t x)
{
if(x!=0) return 0;
else return 1;
}
uint8_t util::sat_add(uint8_t x, uint8_t y)
{
uint8_t z = x + y;
@@ -109,46 +97,6 @@ uint16_t util::sat_cast(int32_t x)
else return (uint16_t)x;
}
uint8_t util::is_timed_out(uint16_t time, uint16_t limit)
{
if(time >= limit) return 1;
else return 0;
}
uint8_t util::is_in_range(uint16_t value, uint16_t min, uint16_t max)
{
if((value >= min)&&(value <= max)) return 1;
else return 0;
}
uint16_t util::time_delta(uint16_t start, uint16_t end)
{
if(end >= start) return (end-start);
uint16_t temp = 0xFFFF - start;
return temp + end;
}
uint32_t util::time_delta(uint32_t start, uint32_t end)
{
if(end >= start) return (end-start);
uint32_t temp = 0xFFFFFFFF - start;
return temp + end;
}
uint16_t util::time_delta(uint16_t start, uint16_t end, uint16_t max)
{
if(end >= start) return (end-start);
uint16_t temp = max - start;
return temp + end;
}
uint32_t util::time_delta(uint32_t start, uint32_t end, uint32_t max)
{
if(end >= start) return (end-start);
uint32_t temp = max - start;
return temp + end;
}
uint16_t util::convert_muldivoff(uint16_t raw, uint8_t mul, uint8_t div, int16_t offset)
{
int32_t temp = (int32_t)raw;
@@ -204,13 +152,4 @@ uint16_t util::percent_to_16b(uint8_t percent)
return pwm;
}
uint16_t util::percent_of(uint8_t percent, uint16_t value)
{
if(percent == 0) return 0;
else if(percent >= 100) return value;
uint32_t temp = (uint32_t)value * percent;
return temp/100;
}
/**** Private function definitions ****/

View File

@@ -9,8 +9,15 @@ namespace util {
/**** Public definitions ****/
/**** Public function declarations ****/
uint8_t invert(uint8_t x);
uint16_t invert(uint16_t x);
uint32_t invert(uint32_t x);
uint16_t sat_cast(uint32_t x);
uint16_t sat_cast(int32_t x);
uint16_t convert_muldivoff(uint16_t raw, uint8_t mul, uint8_t div, int16_t offset);
uint16_t sat_mul_kilo(uint16_t xk, uint16_t yk);
uint16_t sat_div_kilo(uint16_t top, uint16_t bot);
uint16_t sat_ratio(uint16_t top, uint16_t bot);
uint16_t percent_to_16b(uint8_t percent);
uint8_t sat_add(uint8_t x, uint8_t y);
uint16_t sat_add(uint16_t x, uint16_t y);
@@ -24,25 +31,8 @@ uint8_t abs_subtract(uint8_t x, uint8_t y);
uint16_t abs_subtract(uint16_t x, uint16_t y);
uint32_t abs_subtract(uint32_t x, uint32_t y);
uint16_t sat_cast(uint32_t x);
uint16_t sat_cast(int32_t x);
uint8_t is_timed_out(uint16_t time, uint16_t limit);
uint8_t is_in_range(uint16_t value, uint16_t min, uint16_t max);
uint16_t time_delta(uint16_t start, uint16_t end);
uint32_t time_delta(uint32_t start, uint32_t end);
uint16_t time_delta(uint16_t start, uint16_t end, uint16_t max);
uint32_t time_delta(uint32_t start, uint32_t end, uint32_t max);
uint16_t convert_muldivoff(uint16_t raw, uint8_t mul, uint8_t div, int16_t offset);
uint16_t sat_mul_kilo(uint16_t xk, uint16_t yk);
uint16_t sat_div_kilo(uint16_t top, uint16_t bot);
uint16_t sat_ratio(uint16_t top, uint16_t bot);
uint16_t percent_to_16b(uint8_t percent);
uint16_t percent_of(uint8_t percent, uint16_t value);
uint16_t interpolate_1d(uint16_t x, uint16_t* x_axis, uint16_t* y_values, uint8_t len_axis);
uint16_t interpolate_2d(uint16_t x, uint16_t y, uint16_t* x_axis, uint8_t len_x_axis, uint16_t* y_axis, uint8_t len_y_axis, uint16_t* z_values);
#ifdef TESTING
#endif

View File

@@ -1,71 +0,0 @@
/**** Includes ****/
#include "utils.h"
#include "vcounter.h"
using namespace util;
/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
util::VCounter::VCounter(void)
{
this->counter = 0;
this->top = 0xFFFF;
this->step_us = 1;
this->disabled = 1;
return;
}
util::VCounter::~VCounter(void)
{
return;
}
void util::VCounter::init(uint16_t top, uint16_t step_us)
{
this->counter = 0;
this->top = top;
this->step_us = step_us;
this->disabled = 1;
}
void util::VCounter::reset(void)
{
this->counter = 0;
}
void util::VCounter::increment(void)
{
if(this->disabled) return;
this->counter++;
if(this->counter > this->top) this->counter = 0;
}
uint16_t util::VCounter::read(void)
{
return this->counter;
}
uint32_t util::VCounter::read_ms(void)
{
return this->convert_ms(this->counter);
}
uint16_t util::VCounter::read_top(void)
{
return this->top;
}
uint32_t util::VCounter::convert_ms(uint16_t raw)
{
if(this->step_us==0) return 0;
uint32_t out = (uint32_t)raw * (uint32_t)this->step_us;
return out/1000;
}
/**** Private function definitions ****/

View File

@@ -1,42 +0,0 @@
#ifndef VIRTUAL_COUNTER_H_
#define VIRTUAL_COUNTER_H_
/**** Includes ****/
#include <stdint.h>
namespace util {
/**** Public definitions ****/
class VCounter
{
public:
VCounter(void);
~VCounter(void);
void init(uint16_t top, uint16_t step_us);
uint8_t disabled;
void reset(void);
void increment(void);
uint16_t read(void);
uint32_t read_ms(void);
uint16_t read_top(void);
uint32_t convert_ms(uint16_t raw);
#ifndef TESTING
protected:
#endif
uint16_t step_us;
uint16_t counter;
uint16_t top;
};
/**** Public function declarations ****/
#ifdef TESTING
#endif
} //namespace
#endif /* VIRTUAL_COUNTER_H_ */

Binary file not shown.