board abstraction
This commit is contained in:
BIN
docs/uDCCD_Controller_R9V1_Schematic.PDF
Normal file
BIN
docs/uDCCD_Controller_R9V1_Schematic.PDF
Normal file
Binary file not shown.
35
firmware/src/board/ain.cpp
Normal file
35
firmware/src/board/ain.cpp
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/**** Includes ****/
|
||||||
|
#include "../utils/utils.h"
|
||||||
|
#include "mcu/mcu_hal.h"
|
||||||
|
#include "ain.h"
|
||||||
|
|
||||||
|
using namespace board;
|
||||||
|
|
||||||
|
/**** Private definitions ****/
|
||||||
|
/**** Private constants ****/
|
||||||
|
/**** Private variables ****/
|
||||||
|
/**** Private function declarations ****/
|
||||||
|
|
||||||
|
/**** Public function definitions ****/
|
||||||
|
board::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t board::AnalogIn::read(void)
|
||||||
|
{
|
||||||
|
//Read ADC
|
||||||
|
uint16_t raw = mcu::adc_read(this->adc_ch);
|
||||||
|
|
||||||
|
//Convert to mV
|
||||||
|
this->last_read = util::convert_muldivoff(raw, this->mul, this->div, this->offset);
|
||||||
|
|
||||||
|
return this->last_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**** Private function definitions ****/
|
||||||
|
|
||||||
37
firmware/src/board/ain.h
Normal file
37
firmware/src/board/ain.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef ANALOG_IN_H_
|
||||||
|
#define ANALOG_IN_H_
|
||||||
|
|
||||||
|
/**** Includes ****/
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace board {
|
||||||
|
|
||||||
|
/**** Public definitions ****/
|
||||||
|
static const uint8_t DEF_AIN_MUL = 215;
|
||||||
|
static const uint8_t DEF_AIN_DIV = 44;
|
||||||
|
static const int16_t DEF_AIN_OFFSET = 0;
|
||||||
|
|
||||||
|
class AnalogIn
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
uint8_t adc_ch;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AnalogIn(uint8_t adc_ch);
|
||||||
|
|
||||||
|
uint8_t mul;
|
||||||
|
uint8_t div;
|
||||||
|
int16_t offset;
|
||||||
|
uint16_t last_read;
|
||||||
|
|
||||||
|
uint16_t read(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**** Public function declarations ****/
|
||||||
|
|
||||||
|
#ifdef TESTING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} //namespace
|
||||||
|
|
||||||
|
#endif /* ANALOG_IN_H_ */
|
||||||
72
firmware/src/board/dio.cpp
Normal file
72
firmware/src/board/dio.cpp
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/**** Includes ****/
|
||||||
|
#include "../utils/utils.h"
|
||||||
|
#include "mcu/mcu_hal.h"
|
||||||
|
#include "dio.h"
|
||||||
|
|
||||||
|
using namespace board;
|
||||||
|
|
||||||
|
/**** Private definitions ****/
|
||||||
|
/**** Private constants ****/
|
||||||
|
/**** Private variables ****/
|
||||||
|
/**** Private function declarations ****/
|
||||||
|
|
||||||
|
/**** Public function definitions ****/
|
||||||
|
board::DigitalIO::DigitalIO(uint8_t gpio_ch, uint8_t init_read)
|
||||||
|
{
|
||||||
|
this->gpio_ch = gpio_ch;
|
||||||
|
|
||||||
|
if(init_read) this->last_read = (uint8_t)DIO_HIGH;
|
||||||
|
else this->last_read = (uint8_t)DIO_LOW;
|
||||||
|
|
||||||
|
this->write(DIO_HIZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
board::DigitalIO::~DigitalIO(void)
|
||||||
|
{
|
||||||
|
this->write(DIO_HIZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t board::DigitalIO::read(void)
|
||||||
|
{
|
||||||
|
uint8_t lvl = mcu::gpio_read(this->gpio_ch);
|
||||||
|
if(lvl>0) this->last_read = (uint8_t)DIO_HIGH;
|
||||||
|
else this->last_read = (uint8_t)DIO_LOW;
|
||||||
|
|
||||||
|
return this->last_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
void board::DigitalIO::write(int8_t level)
|
||||||
|
{
|
||||||
|
if(level > 0)
|
||||||
|
{
|
||||||
|
this->last_set = DIO_HIGH;
|
||||||
|
mcu::gpio_write(this->gpio_ch, mcu::LEVEL_HIGH);
|
||||||
|
}
|
||||||
|
else if(level < 0)
|
||||||
|
{
|
||||||
|
this->last_set = DIO_HIZ;
|
||||||
|
mcu::gpio_write(this->gpio_ch, mcu::LEVEL_HIZ);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->last_set = DIO_LOW;
|
||||||
|
mcu::gpio_write(this->gpio_ch, mcu::LEVEL_LOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t board::DigitalIO::is_io_match(void)
|
||||||
|
{
|
||||||
|
if(this->last_set == DIO_HIZ) return 1;
|
||||||
|
|
||||||
|
uint8_t read_lvl = this->read();
|
||||||
|
|
||||||
|
if(read_lvl == (uint8_t)this->last_set) return 1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t board::DigitalIO::get_set_level(void)
|
||||||
|
{
|
||||||
|
return this->last_set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**** Private function definitions ****/
|
||||||
39
firmware/src/board/dio.h
Normal file
39
firmware/src/board/dio.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef DIGITAL_OUT_H_
|
||||||
|
#define DIGITAL_OUT_H_
|
||||||
|
|
||||||
|
/**** Includes ****/
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace board {
|
||||||
|
|
||||||
|
/**** Public definitions ****/
|
||||||
|
const int8_t DIO_LOW = 0;
|
||||||
|
const int8_t DIO_HIGH = 1;
|
||||||
|
const int8_t DIO_HIZ = -1;
|
||||||
|
|
||||||
|
class DigitalIO
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
uint8_t gpio_ch;
|
||||||
|
int8_t last_set;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DigitalIO(uint8_t gpio_ch, uint8_t init_read);
|
||||||
|
~DigitalIO(void);
|
||||||
|
|
||||||
|
uint8_t last_read;
|
||||||
|
|
||||||
|
uint8_t read(void);
|
||||||
|
void write(int8_t level);
|
||||||
|
uint8_t is_io_match(void);
|
||||||
|
int8_t get_set_level(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**** Public function declarations ****/
|
||||||
|
|
||||||
|
#ifdef TESTING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} //namespace
|
||||||
|
|
||||||
|
#endif /* DIGITAL_OUT_H_ */
|
||||||
68
firmware/src/board/halfbridge.cpp
Normal file
68
firmware/src/board/halfbridge.cpp
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/**** Includes ****/
|
||||||
|
#include "../utils/utils.h"
|
||||||
|
#include "mcu/mcu_hal.h"
|
||||||
|
#include "halfbridge.h"
|
||||||
|
|
||||||
|
using namespace board;
|
||||||
|
|
||||||
|
/**** Private definitions ****/
|
||||||
|
/**** Private constants ****/
|
||||||
|
/**** Private variables ****/
|
||||||
|
/**** Private function declarations ****/
|
||||||
|
|
||||||
|
/**** Public function definitions ****/
|
||||||
|
board::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) this->max_dc = 100;
|
||||||
|
else this->max_dc = max_dc;
|
||||||
|
this->disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
board::Hafbridge::~Hafbridge(void)
|
||||||
|
{
|
||||||
|
this->last_duty = 0;
|
||||||
|
this->disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void board::Hafbridge::write(uint8_t duty)
|
||||||
|
{
|
||||||
|
// Limit duty
|
||||||
|
if(duty > this->max_dc) duty = this->max_dc;
|
||||||
|
this->last_duty = duty;
|
||||||
|
|
||||||
|
if(this->enabled == 0) return;
|
||||||
|
|
||||||
|
// Convert percent to 16b duty cycle
|
||||||
|
uint16_t dc = util::percent_to_16b(duty);
|
||||||
|
// Set PWM
|
||||||
|
mcu::pwm_write(this->pwm_ch, dc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void board::Hafbridge::enable(void)
|
||||||
|
{
|
||||||
|
mcu::gpio_write(this->gpio_ch, mcu::LEVEL_HIGH);
|
||||||
|
this->enabled = 1;
|
||||||
|
this->write(this->last_duty);
|
||||||
|
}
|
||||||
|
|
||||||
|
void board::Hafbridge::disable(void)
|
||||||
|
{
|
||||||
|
mcu::pwm_write(this->pwm_ch, 0);
|
||||||
|
mcu::gpio_write(this->gpio_ch, mcu::LEVEL_LOW);
|
||||||
|
this->enabled = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t board::Hafbridge::get_set_duty(void)
|
||||||
|
{
|
||||||
|
return this->last_duty;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t board::Hafbridge::is_enabled(void)
|
||||||
|
{
|
||||||
|
return this->enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**** Private function definitions ****/
|
||||||
37
firmware/src/board/halfbridge.h
Normal file
37
firmware/src/board/halfbridge.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef HALFBRIDGE_H_
|
||||||
|
#define HALFBRIDGE_H_
|
||||||
|
|
||||||
|
/**** Includes ****/
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace board {
|
||||||
|
|
||||||
|
/**** Public definitions ****/
|
||||||
|
class Hafbridge
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
uint8_t pwm_ch;
|
||||||
|
uint8_t gpio_ch;
|
||||||
|
uint8_t last_duty;
|
||||||
|
uint8_t enabled;
|
||||||
|
uint8_t max_dc;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Hafbridge(uint8_t hs_pwm_ch, uint8_t ls_gpio_ch, uint8_t max_dc);
|
||||||
|
~Hafbridge(void);
|
||||||
|
|
||||||
|
void write(uint8_t duty);
|
||||||
|
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_ */
|
||||||
37
firmware/src/board/hvdin.cpp
Normal file
37
firmware/src/board/hvdin.cpp
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/**** Includes ****/
|
||||||
|
#include "../utils/utils.h"
|
||||||
|
#include "mcu/mcu_hal.h"
|
||||||
|
#include "hvdin.h"
|
||||||
|
|
||||||
|
using namespace board;
|
||||||
|
|
||||||
|
/**** Private definitions ****/
|
||||||
|
/**** Private constants ****/
|
||||||
|
/**** Private variables ****/
|
||||||
|
/**** Private function declarations ****/
|
||||||
|
|
||||||
|
/**** Public function definitions ****/
|
||||||
|
board::HVDigitalIn::HVDigitalIn(uint8_t gpio_ch, uint8_t init_read)
|
||||||
|
{
|
||||||
|
this->gpio_ch = gpio_ch;
|
||||||
|
|
||||||
|
if(init_read) this->last_read = HVDIN_HIGH;
|
||||||
|
else this->last_read = HVDIN_LOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
board::HVDigitalIn::~HVDigitalIn(void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t board::HVDigitalIn::read(void)
|
||||||
|
{
|
||||||
|
// Auto inverts level to match board external connectors
|
||||||
|
uint8_t lvl = mcu::gpio_read(this->gpio_ch);
|
||||||
|
if(lvl>0) this->last_read = HVDIN_LOW;
|
||||||
|
else this->last_read = HVDIN_HIGH;
|
||||||
|
|
||||||
|
return this->last_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**** Private function definitions ****/
|
||||||
34
firmware/src/board/hvdin.h
Normal file
34
firmware/src/board/hvdin.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef HV_DIN_H_
|
||||||
|
#define HV_DIN_H_
|
||||||
|
|
||||||
|
/**** Includes ****/
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace board {
|
||||||
|
|
||||||
|
/**** Public definitions ****/
|
||||||
|
const uint8_t HVDIN_LOW = 0;
|
||||||
|
const uint8_t HVDIN_HIGH = 1;
|
||||||
|
|
||||||
|
class HVDigitalIn
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
uint8_t gpio_ch;
|
||||||
|
|
||||||
|
public:
|
||||||
|
HVDigitalIn(uint8_t gpio_ch, uint8_t init_read);
|
||||||
|
~HVDigitalIn(void);
|
||||||
|
|
||||||
|
uint8_t last_read;
|
||||||
|
|
||||||
|
uint8_t read(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**** Public function declarations ****/
|
||||||
|
|
||||||
|
#ifdef TESTING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} //namespace
|
||||||
|
|
||||||
|
#endif /* HV_DIN_H_ */
|
||||||
125
firmware/src/board/mcu/mcu_hal.h
Normal file
125
firmware/src/board/mcu/mcu_hal.h
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
#ifndef MCU_HAL_H_
|
||||||
|
#define MCU_HAL_H_
|
||||||
|
|
||||||
|
/**** Includes ****/
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace mcu {
|
||||||
|
|
||||||
|
/**** Public definitions ****/
|
||||||
|
/*
|
||||||
|
GPIO0 Down
|
||||||
|
GPIO1 Up
|
||||||
|
GPIO2 Mode
|
||||||
|
GPIO3 Handbrake
|
||||||
|
GPIO4 Brakes
|
||||||
|
GPIO5 Dimm
|
||||||
|
GPIO6 LED0
|
||||||
|
GPIO7 LED1
|
||||||
|
GPIO8 LED2
|
||||||
|
GPIO9 LED3
|
||||||
|
GPIO10 LED4
|
||||||
|
GPIO11 LED5
|
||||||
|
GPIO12 DCCD Enable
|
||||||
|
GPIO13 Handbrake pull
|
||||||
|
GPIO14 Speed pull
|
||||||
|
GPIO15 DCCD PWM
|
||||||
|
GPIO16 LED PWM
|
||||||
|
|
||||||
|
ADC0 Output current
|
||||||
|
ADC1 Output voltage
|
||||||
|
ADC2 Battery current
|
||||||
|
ADC3 Battery voltage
|
||||||
|
ADC4 Potentiometer
|
||||||
|
ADC5 Mode
|
||||||
|
ADC8 MCU temperature
|
||||||
|
ADC14 MCU internal reference
|
||||||
|
ADC15 MCU ground
|
||||||
|
*/
|
||||||
|
|
||||||
|
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 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 PWM0 = 0; //DCCD
|
||||||
|
const uint8_t PWM1 = 1; //LED
|
||||||
|
|
||||||
|
//ADC definitions
|
||||||
|
typedef enum {
|
||||||
|
ADC_DIV2 = 0x01,
|
||||||
|
ADC_DIV4 = 0x02,
|
||||||
|
ADC_DIV8 = 0x03,
|
||||||
|
ADC_DIV16 = 0x04,
|
||||||
|
ADC_DIV32 = 0x05,
|
||||||
|
ADC_DIV64 = 0x06,
|
||||||
|
ADC_DIV128 = 0x07
|
||||||
|
} adcClkDiv_t;
|
||||||
|
|
||||||
|
//Timer definitions
|
||||||
|
typedef enum {
|
||||||
|
TIM_DIV1 = 0x01,
|
||||||
|
TIM_DIV8 = 0x02,
|
||||||
|
TIM_DIV64 = 0x03,
|
||||||
|
TIM_DIV256 = 0x04,
|
||||||
|
TIM_DIV1024 = 0x05
|
||||||
|
} timerClkDiv_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
adcClkDiv_t adc_clk;
|
||||||
|
timerClkDiv_t pwm_clk;
|
||||||
|
uint16_t pwm_top;
|
||||||
|
uint8_t pwm_ch1_en;
|
||||||
|
} startupCfg_t;
|
||||||
|
|
||||||
|
/**** Public function declarations ****/
|
||||||
|
void startup(startupCfg_t* hwCfg);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
uint16_t adc_read(uint8_t ch);
|
||||||
|
|
||||||
|
void pwm_write(uint8_t ch, uint16_t dc);
|
||||||
|
uint16_t pwm_read(uint8_t ch);
|
||||||
|
|
||||||
|
uint8_t eeprom_read8b(uint16_t address);
|
||||||
|
uint16_t eeprom_read16b(uint16_t address);
|
||||||
|
uint32_t eeprom_read32b(uint16_t address);
|
||||||
|
|
||||||
|
void eeprom_write8b(uint16_t address, uint8_t value);
|
||||||
|
void eeprom_write16b(uint16_t address, uint16_t value);
|
||||||
|
void eeprom_write32b(uint16_t address, uint32_t value);
|
||||||
|
|
||||||
|
} //namespace
|
||||||
|
|
||||||
|
#endif /* MCU_HAL_H_ */
|
||||||
464
firmware/src/board/mcu/mcu_hal_r8.cpp
Normal file
464
firmware/src/board/mcu/mcu_hal_r8.cpp
Normal file
@@ -0,0 +1,464 @@
|
|||||||
|
/**** Includes ****/
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/eeprom.h>
|
||||||
|
#include "mcu_hal.h"
|
||||||
|
|
||||||
|
using namespace mcu;
|
||||||
|
|
||||||
|
/**** Private definitions ****/
|
||||||
|
/**** Private constants ****/
|
||||||
|
/**** Private variables ****/
|
||||||
|
/**** 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);
|
||||||
|
static uint16_t pwm_read_ocx(uint8_t ch);
|
||||||
|
|
||||||
|
/**** Public function definitions ****/
|
||||||
|
void mcu::startup(startupCfg_t* hwCfg)
|
||||||
|
{
|
||||||
|
// Fail-safe GPIO init
|
||||||
|
PORTB = 0xF8; // Set PORTB pull-ups
|
||||||
|
DDRB = 0x00; // Set all as inputs
|
||||||
|
|
||||||
|
PORTC = 0x40; // Set PORTC pull-ups
|
||||||
|
DDRC = 0x00; // Set all as inputs
|
||||||
|
|
||||||
|
PORTD = 0x80; // Set PORTD pull-ups
|
||||||
|
DDRD = 0x00; // Set all as inputs
|
||||||
|
|
||||||
|
PORTE = 0x0A; // Set PORTE pull-ups
|
||||||
|
DDRE = 0x00; // Set all as inputs
|
||||||
|
|
||||||
|
// Half-bridge related pins
|
||||||
|
PORTB &= ~0x03; //Set low
|
||||||
|
DDRB |= 0x03; //Set as output
|
||||||
|
|
||||||
|
// Common OD PWM pin
|
||||||
|
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)
|
||||||
|
DDRD |= 0x3F; //Set as outputs
|
||||||
|
|
||||||
|
// Handbrake pull-up pin
|
||||||
|
PORTB |= 0x20; //Set high
|
||||||
|
DDRB |= 0x20; //Set as output
|
||||||
|
|
||||||
|
// Handbrake and brakes pins
|
||||||
|
PORTB |= 0xC0; //Set pull-up on
|
||||||
|
DDRB &= ~0xC0; //Set as inputs
|
||||||
|
|
||||||
|
// Dimm
|
||||||
|
PORTD |= 0x80; //Set pull-up on
|
||||||
|
DDRD &= ~0x80; //Set as input
|
||||||
|
|
||||||
|
// Up and Down
|
||||||
|
PORTE |= 0x0A; //Set pull-up on
|
||||||
|
DDRE &= ~0x0A; //Set as inputs
|
||||||
|
|
||||||
|
// Internal ADC inputs
|
||||||
|
PORTC &= ~0x0F; //Pull-up off
|
||||||
|
DDRC &= ~0x0F; //Set as inputs
|
||||||
|
|
||||||
|
// Potentiometer & Mode
|
||||||
|
PORTC &= ~0x30; //Pull-up off
|
||||||
|
DDRC &= ~0x30; //Set as inputs
|
||||||
|
|
||||||
|
//ADC configuration
|
||||||
|
PRR0 &= ~0x01; //Enable ADC power
|
||||||
|
DIDR0 |= 0x0F; //Disable digital inputs, ADC0-ADC3
|
||||||
|
|
||||||
|
ADMUX = 0x40; //Set AVCC reference, Right adjust
|
||||||
|
ADCSRA = 0x00; //ADC Disabled, Single conversion, no IT
|
||||||
|
ADCSRA |= (uint8_t)hwCfg->adc_clk;
|
||||||
|
ADCSRB = 0x00; //no trigger input
|
||||||
|
|
||||||
|
ADCSRA |= 0x80; //Enable ADC
|
||||||
|
|
||||||
|
//DCCD and LED PWM configuration
|
||||||
|
PRR0 &= ~0x80; //Enable Timer1 power
|
||||||
|
TCCR1A = 0xC2; //Connect OC1A, 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;
|
||||||
|
OCR1A = 0xFFFF;
|
||||||
|
OCR1B = 0xFFFF;
|
||||||
|
ICR1 = hwCfg->pwm_top;
|
||||||
|
TIMSK1 = 0x00; //No interrupts
|
||||||
|
TIFR1 = 0x00; //Clear all flags
|
||||||
|
|
||||||
|
uint8_t tim1_prescaler = (uint8_t)hwCfg->pwm_clk;
|
||||||
|
TCCR1B |= tim1_prescaler; //Enable timer
|
||||||
|
}
|
||||||
|
|
||||||
|
// ADC Interface functions
|
||||||
|
uint16_t mcu::adc_read(uint8_t ch)
|
||||||
|
{
|
||||||
|
//check if ADC is enabled
|
||||||
|
if(!(ADCSRA&0x80)) return 0xFFFF;
|
||||||
|
|
||||||
|
//Safe guard mux
|
||||||
|
if(ch > 15) return 0xFFFF;
|
||||||
|
// Not available channels
|
||||||
|
if((ch > 8) && (ch<14)) return 0xFFFF;
|
||||||
|
|
||||||
|
ADMUX &= ~0x0F;
|
||||||
|
ADMUX |= ch;
|
||||||
|
ADCSRA |= 0x40;
|
||||||
|
while(ADCSRA&0x40); //wait to finish
|
||||||
|
return ADC;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PWM Timer Interface functions
|
||||||
|
void mcu::pwm_write(uint8_t ch, uint16_t dc)
|
||||||
|
{
|
||||||
|
dc = 0xFFFF - dc;
|
||||||
|
|
||||||
|
// Calculate value as % of TOP
|
||||||
|
uint32_t top = (uint32_t)ICR1;
|
||||||
|
uint32_t temp = (uint32_t)dc * top;
|
||||||
|
temp = temp/0x0000FFFF;
|
||||||
|
|
||||||
|
//Limit temp
|
||||||
|
if(temp>0x0000FFFF) temp = 0x0000FFFF;
|
||||||
|
uint16_t ocrx = (uint16_t)temp;
|
||||||
|
|
||||||
|
// Write register
|
||||||
|
pwm_write_ocx(ch, ocrx);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t mcu::pwm_read(uint8_t ch)
|
||||||
|
{
|
||||||
|
uint16_t ocrx = pwm_read_ocx(ch);
|
||||||
|
|
||||||
|
// Check easy answers
|
||||||
|
if(ocrx == 0) return 0;
|
||||||
|
if(ocrx >= ICR1) return 0xFFFF;
|
||||||
|
|
||||||
|
// Calculate
|
||||||
|
uint32_t top = (uint32_t)ICR1;
|
||||||
|
uint32_t temp = (uint32_t)ocrx * 0xFFFF;
|
||||||
|
temp = temp/top;
|
||||||
|
|
||||||
|
//Limit temp
|
||||||
|
if(temp>0x0000FFFF) return 0xFFFF;
|
||||||
|
return (uint16_t)temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t mcu::eeprom_read16b(uint16_t address)
|
||||||
|
{
|
||||||
|
return eeprom_read_word((uint16_t*)address);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t mcu::eeprom_read32b(uint16_t address)
|
||||||
|
{
|
||||||
|
return eeprom_read_dword((uint32_t*)address);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mcu::eeprom_write8b(uint16_t address, uint8_t value)
|
||||||
|
{
|
||||||
|
eeprom_write_byte((uint8_t*)address, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mcu::eeprom_write16b(uint16_t address, uint16_t value)
|
||||||
|
{
|
||||||
|
eeprom_write_word((uint16_t*)address, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mcu::eeprom_write32b(uint16_t address, uint32_t value)
|
||||||
|
{
|
||||||
|
eeprom_write_dword((uint32_t*)address, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**** Private function definitions ****/
|
||||||
|
static uint8_t gpio_read_level(uint8_t pin_reg, uint8_t mask)
|
||||||
|
{
|
||||||
|
if(pin_reg&mask) return LEVEL_HIGH;
|
||||||
|
else return LEVEL_LOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pwm_write_ocx(uint8_t ch, uint16_t value)
|
||||||
|
{
|
||||||
|
switch(ch)
|
||||||
|
{
|
||||||
|
case PWM0:
|
||||||
|
OCR1A = value;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case PWM1:
|
||||||
|
OCR1B = value;
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t pwm_read_ocx(uint8_t ch)
|
||||||
|
{
|
||||||
|
switch(ch)
|
||||||
|
{
|
||||||
|
case PWM0:
|
||||||
|
return OCR1A;
|
||||||
|
|
||||||
|
case PWM1:
|
||||||
|
return OCR1B ;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0x0000;
|
||||||
|
}
|
||||||
|
}
|
||||||
40
firmware/src/board/od_com.cpp
Normal file
40
firmware/src/board/od_com.cpp
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/**** Includes ****/
|
||||||
|
#include "../utils/utils.h"
|
||||||
|
#include "mcu/mcu_hal.h"
|
||||||
|
#include "od_com.h"
|
||||||
|
|
||||||
|
using namespace board;
|
||||||
|
|
||||||
|
/**** Private definitions ****/
|
||||||
|
/**** Private constants ****/
|
||||||
|
/**** Private variables ****/
|
||||||
|
/**** Private function declarations ****/
|
||||||
|
|
||||||
|
/**** Public function definitions ****/
|
||||||
|
board::ODCommon::ODCommon(uint8_t pwm_ch)
|
||||||
|
{
|
||||||
|
this->pwm_ch = pwm_ch;
|
||||||
|
this->write(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
board::ODCommon::~ODCommon(void)
|
||||||
|
{
|
||||||
|
this->write(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void board::ODCommon::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 board::ODCommon::get_set_duty(void)
|
||||||
|
{
|
||||||
|
return this->last_duty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**** Private function definitions ****/
|
||||||
31
firmware/src/board/od_com.h
Normal file
31
firmware/src/board/od_com.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef OD_COMMON_H_
|
||||||
|
#define OD_COMMON_H_
|
||||||
|
|
||||||
|
/**** Includes ****/
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace board {
|
||||||
|
|
||||||
|
/**** Public definitions ****/
|
||||||
|
class ODCommon
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
uint8_t pwm_ch;
|
||||||
|
uint8_t last_duty;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ODCommon(uint8_t pwm_ch);
|
||||||
|
~ODCommon(void);
|
||||||
|
|
||||||
|
void write(uint8_t duty);
|
||||||
|
uint8_t get_set_duty(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**** Public function declarations ****/
|
||||||
|
|
||||||
|
#ifdef TESTING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} //namespace
|
||||||
|
|
||||||
|
#endif /* OD_COMMON_H_ */
|
||||||
44
firmware/src/board/odout.cpp
Normal file
44
firmware/src/board/odout.cpp
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/**** Includes ****/
|
||||||
|
#include "../utils/utils.h"
|
||||||
|
#include "mcu/mcu_hal.h"
|
||||||
|
#include "odout.h"
|
||||||
|
|
||||||
|
using namespace board;
|
||||||
|
|
||||||
|
/**** Private definitions ****/
|
||||||
|
/**** Private constants ****/
|
||||||
|
/**** Private variables ****/
|
||||||
|
/**** Private function declarations ****/
|
||||||
|
|
||||||
|
/**** Public function definitions ****/
|
||||||
|
board::OpenDrainOut::OpenDrainOut(uint8_t gpio_ch)
|
||||||
|
{
|
||||||
|
this->gpio_ch = gpio_ch;
|
||||||
|
this->write(OD_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
board::OpenDrainOut::~OpenDrainOut(void)
|
||||||
|
{
|
||||||
|
this->write(OD_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void board::OpenDrainOut::write(uint8_t state)
|
||||||
|
{
|
||||||
|
if(state)
|
||||||
|
{
|
||||||
|
mcu::gpio_write(this->gpio_ch, mcu::LEVEL_HIGH);
|
||||||
|
this->last_set = OD_ON;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mcu::gpio_write(this->gpio_ch, mcu::LEVEL_LOW);
|
||||||
|
this->last_set = OD_OFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t board::OpenDrainOut::get_set_state(void)
|
||||||
|
{
|
||||||
|
return this->last_set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**** Private function definitions ****/
|
||||||
34
firmware/src/board/odout.h
Normal file
34
firmware/src/board/odout.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef OD_OUT_H_
|
||||||
|
#define OD_OUT_H_
|
||||||
|
|
||||||
|
/**** Includes ****/
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace board {
|
||||||
|
|
||||||
|
/**** Public definitions ****/
|
||||||
|
const uint8_t OD_OFF = 0;
|
||||||
|
const uint8_t OD_ON = 1;
|
||||||
|
|
||||||
|
class OpenDrainOut
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
uint8_t gpio_ch;
|
||||||
|
uint8_t last_set;
|
||||||
|
|
||||||
|
public:
|
||||||
|
OpenDrainOut(uint8_t gpio_ch);
|
||||||
|
~OpenDrainOut(void);
|
||||||
|
|
||||||
|
void write(uint8_t state);
|
||||||
|
uint8_t get_set_state(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**** Public function declarations ****/
|
||||||
|
|
||||||
|
#ifdef TESTING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} //namespace
|
||||||
|
|
||||||
|
#endif /* OD_OUT_H_ */
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
#ifndef UDCCD_R8_BSP_H_
|
|
||||||
#define UDCCD_R8_BSP_H_
|
|
||||||
|
|
||||||
/**** Includes ****/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "../common/level.h"
|
|
||||||
|
|
||||||
/**** Public definitions ****/
|
|
||||||
//ADC definitions
|
|
||||||
typedef enum {
|
|
||||||
ADC_ICOIL = 0x00,
|
|
||||||
ADC_UCOIL = 0x01,
|
|
||||||
ADC_UBAT = 0x02,
|
|
||||||
ADC_IBAT = 0x03,
|
|
||||||
ADC_POT = 0x04,
|
|
||||||
ADC_MODE = 0x05,
|
|
||||||
ADC_TEMP = 0x08,
|
|
||||||
ADC_INTREF = 0x0E,
|
|
||||||
ADC_GND = 0x0F
|
|
||||||
} adcCh_t;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
ADC_DIV2 = 0x01,
|
|
||||||
ADC_DIV4 = 0x02,
|
|
||||||
ADC_DIV8 = 0x03,
|
|
||||||
ADC_DIV16 = 0x04,
|
|
||||||
ADC_DIV32 = 0x05,
|
|
||||||
ADC_DIV64 = 0x06,
|
|
||||||
ADC_DIV128 = 0x07
|
|
||||||
} adcDiv_t;
|
|
||||||
|
|
||||||
//Timer definitions
|
|
||||||
typedef enum {
|
|
||||||
TIM_DIV1 = 0x01,
|
|
||||||
TIM_DIV8 = 0x02,
|
|
||||||
TIM_DIV64 = 0x03,
|
|
||||||
TIM_DIV256 = 0x04,
|
|
||||||
TIM_DIV1024 = 0x05
|
|
||||||
} timerDiv_t;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
PWM_COIL = 'A',
|
|
||||||
PWM_LED = 'B'
|
|
||||||
} pwmCh_t;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
SPEED_1 = 3,
|
|
||||||
SPEED_0 = 4
|
|
||||||
} speedCh_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
adcDiv_t adc_clk_prescaler;
|
|
||||||
uint8_t adc_auto_wake;
|
|
||||||
timerDiv_t pwm_timer_prescaler;
|
|
||||||
uint16_t pwm_timer_top;
|
|
||||||
timerDiv_t freq_timer_prescaler;
|
|
||||||
uint16_t uart_prescaler;
|
|
||||||
uint8_t systick_timer_top;
|
|
||||||
timerDiv_t systick_timer_prescaler;
|
|
||||||
uint8_t disable_unused;
|
|
||||||
uint8_t en_watchdog;
|
|
||||||
} hwConfig_t;
|
|
||||||
|
|
||||||
/**** Public function declarations ****/
|
|
||||||
void HAL_Init_Min(hwConfig_t* hwCfg);
|
|
||||||
void HAL_Init_Extra(hwConfig_t* hwCfg);
|
|
||||||
|
|
||||||
level_t HAL_ReadLvl_Handbrake(void);
|
|
||||||
level_t HAL_ReadLvl_Brake(void);
|
|
||||||
level_t HAL_ReadLvl_Dimm(void);
|
|
||||||
level_t HAL_ReadLvl_BtnUp(void);
|
|
||||||
level_t HAL_ReadLvl_BtnDown(void);
|
|
||||||
level_t HAL_ReadLvl_BtnMode(void);
|
|
||||||
level_t HAL_ReadLvl_HandbrakePull(void);
|
|
||||||
level_t HAL_ReadLvl_CoilLow(void);
|
|
||||||
level_t HAL_ReadLvl_CoilHigh(void);
|
|
||||||
level_t HAL_ReadLvl_LedsPwm(void);
|
|
||||||
level_t HAL_ReadLvl_Speed0(void);
|
|
||||||
level_t HAL_ReadLvl_Speed1(void);
|
|
||||||
level_t HAL_ReadLvl_SpeedPull(void);
|
|
||||||
|
|
||||||
void HAL_SetPull_Handbrake(level_t lvl);
|
|
||||||
void HAL_SetPull_Speed(level_t lvl);
|
|
||||||
|
|
||||||
void HAL_ADC_Wake(void);
|
|
||||||
void HAL_ADC_Sleep(void);
|
|
||||||
uint16_t HAL_ADC_Read(adcCh_t ch);
|
|
||||||
|
|
||||||
void HAL_Coil_SetLowSide(uint8_t on);
|
|
||||||
void HAL_Coil_SetPWM(uint8_t percent);
|
|
||||||
void HAL_Coil_SetPWM16b(uint16_t value);
|
|
||||||
|
|
||||||
void HAL_LEDS_Set(uint8_t image);
|
|
||||||
uint8_t HAL_LEDS_Get(void);
|
|
||||||
void HAL_LEDS_SetPWM(uint8_t percent);
|
|
||||||
|
|
||||||
void HAL_PWM_Wake(void);
|
|
||||||
void HAL_PWM_Sleep(void);
|
|
||||||
void HAL_PWM_SetDuty16b(pwmCh_t ch, uint16_t value);
|
|
||||||
void HAL_PWM_SetDuty100(pwmCh_t ch, uint8_t percent);
|
|
||||||
|
|
||||||
#endif /* UDCCD_R8_BSP_H_ */
|
|
||||||
@@ -1,463 +0,0 @@
|
|||||||
/**** Includes ****/
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include "udccd_hal.h"
|
|
||||||
|
|
||||||
/**** Private variables ****/
|
|
||||||
static uint8_t tim0_prescaler = 0x00;
|
|
||||||
static uint8_t tim1_prescaler = 0x00;
|
|
||||||
static uint8_t tim3_prescaler = 0x00;
|
|
||||||
static uint8_t tim4_prescaler = 0x00;
|
|
||||||
|
|
||||||
/**** Private function declarations ****/
|
|
||||||
static void PWM_SetOCx(pwmCh_t ch, uint16_t value);
|
|
||||||
|
|
||||||
/**** Public function definitions ****/
|
|
||||||
void HAL_Init_Min(hwConfig_t* hwCfg)
|
|
||||||
{
|
|
||||||
// PIN Configuration
|
|
||||||
//DCCD Enable and PWM
|
|
||||||
PORTB &= ~0x03; //Set low
|
|
||||||
DDRB |= 0x03; //Set as outputs
|
|
||||||
|
|
||||||
//LED PWM
|
|
||||||
PORTB &= ~0x04; //Set low
|
|
||||||
DDRB |= 0x04; //Set as output
|
|
||||||
|
|
||||||
//UART TX
|
|
||||||
PORTB |= 0x18; //Set high / pull-up on
|
|
||||||
DDRB |= 0x08; //Set as output
|
|
||||||
DDRB &= ~0x10; //Set as input
|
|
||||||
|
|
||||||
//Handbrake pull-up
|
|
||||||
PORTB |= 0x20; //Set high
|
|
||||||
DDRB |= 0x20; //Set as output
|
|
||||||
|
|
||||||
//Handbrake and Brake inputs
|
|
||||||
PORTB |= 0xC0; //Pull-up on
|
|
||||||
DDRB &= ~0xC0; //Set as input
|
|
||||||
|
|
||||||
// ADC inputs
|
|
||||||
PORTC &= ~0x3F; //Pull-up off
|
|
||||||
DDRC &= ~0x3F; //Set as inputs
|
|
||||||
|
|
||||||
// Reset
|
|
||||||
PORTC |= 0x40; //Pull-up on
|
|
||||||
DDRC &= ~0x40; //Set as input
|
|
||||||
|
|
||||||
// LED control
|
|
||||||
PORTD &= ~0x3F; //Set low
|
|
||||||
DDRD |= 0x3F; //Set as outputs
|
|
||||||
|
|
||||||
// Speed pull
|
|
||||||
PORTD &= ~0x40; //Set low
|
|
||||||
DDRD |= 0x40; //Set as outputs
|
|
||||||
|
|
||||||
// Dim input
|
|
||||||
PORTD |= 0x80; //Set pull-up on
|
|
||||||
DDRD &= ~0x80; //Set as input
|
|
||||||
|
|
||||||
// Speed inputs
|
|
||||||
PORTE &= ~0x05; //Set pull-down
|
|
||||||
DDRE |= 0x05; //Set as output
|
|
||||||
|
|
||||||
// Up/Down inputs
|
|
||||||
PORTE |= 0x0A; //Set pull-up on
|
|
||||||
DDRE &= ~0x0A; //Set as input
|
|
||||||
|
|
||||||
|
|
||||||
//ADC configuration
|
|
||||||
PRR0 &= ~0x01; //Enable ADC power
|
|
||||||
DIDR0 |= 0x1F; //Disable digital inputs, ADC0-ADC4
|
|
||||||
|
|
||||||
ADMUX = 0x40; //Set AVCC reference, Right adjust
|
|
||||||
ADCSRA = 0x00; //ADC Disabled, Single conversion, no IT
|
|
||||||
ADCSRA |= (uint8_t)hwCfg->adc_clk_prescaler;
|
|
||||||
ADCSRB = 0x00; //no trigger input
|
|
||||||
|
|
||||||
if(hwCfg->adc_auto_wake) ADCSRA |= 0x80; //Enable ADC
|
|
||||||
else PRR0 |= 0x01;
|
|
||||||
|
|
||||||
|
|
||||||
//DCCD and LED PWM configuration
|
|
||||||
PRR0 &= ~0x80; //Enable Timer1 power
|
|
||||||
TCCR1A = 0xF2; //Connect OC1A and OC1B, normal logic
|
|
||||||
TCCR1B = 0x18; //PWM, Phase & Frequency Correct ICR1 top, no clock, WGM:0xE
|
|
||||||
TCCR1C = 0x00;
|
|
||||||
TCNT1 = 0x0000;
|
|
||||||
OCR1A = 0x0000;
|
|
||||||
OCR1B = 0x0000;
|
|
||||||
ICR1 = (hwCfg->pwm_timer_top);
|
|
||||||
TIMSK1 = 0x00; //No interrupts
|
|
||||||
TIFR1 = 0x00; //Clear all flags
|
|
||||||
|
|
||||||
tim1_prescaler = (uint8_t)hwCfg->pwm_timer_prescaler;
|
|
||||||
TCCR1B |= tim1_prescaler; //Enable timer
|
|
||||||
}
|
|
||||||
|
|
||||||
void HAL_Init_Extra(hwConfig_t* hwCfg)
|
|
||||||
{
|
|
||||||
//Speed 1 input timer configuration
|
|
||||||
PRR1 &= ~0x01; //Enable Timer3 power
|
|
||||||
TCCR3A = 0x00; //OCx disconnected, WGM:0x0
|
|
||||||
TCCR3B = 0x80; //ICP Noise filter, Falling edge, no clock
|
|
||||||
TCCR3C = 0x00;
|
|
||||||
TCNT3 = 0x0000;
|
|
||||||
OCR3A = 0x0000;
|
|
||||||
OCR3B = 0x0000;
|
|
||||||
ICR3 = 0x0000;
|
|
||||||
TIMSK3 = 0x00;
|
|
||||||
//TIMSK3 |= 0x21; //ICP and OVF interrupts
|
|
||||||
TIFR3 = 0x00; //Clear all flags
|
|
||||||
|
|
||||||
tim3_prescaler = (uint8_t)hwCfg->freq_timer_prescaler;
|
|
||||||
TCCR3B |= tim3_prescaler; //Enable timer
|
|
||||||
|
|
||||||
|
|
||||||
//Speed 0 input timer configuration
|
|
||||||
PRR1 &= ~0x08; //Enable Timer4 power
|
|
||||||
TCCR4A = 0x00; //OCx disconnected, WGM:0x0
|
|
||||||
TCCR4B = 0x80; //ICP Noise filter, Falling edge, no clock
|
|
||||||
TCCR4C = 0x00;
|
|
||||||
TCNT4 = 0x0000;
|
|
||||||
OCR4A = 0x0000;
|
|
||||||
OCR4B = 0x0000;
|
|
||||||
ICR4 = 0x0000;
|
|
||||||
TIMSK4 = 0x00;
|
|
||||||
//TIMSK4 |= 0x21; //ICP and OVF interrupts
|
|
||||||
TIFR4 = 0x00; //Clear all flags
|
|
||||||
|
|
||||||
tim4_prescaler = (uint8_t)hwCfg->freq_timer_prescaler;
|
|
||||||
TCCR4B |= tim4_prescaler; //Enable timer
|
|
||||||
|
|
||||||
|
|
||||||
//UART1 configuration
|
|
||||||
PRR0 &= 0x10; //Enable UART1 power
|
|
||||||
UCSR1A = 0x00; //Clear flags, Single UART speed, Single processor mode
|
|
||||||
UCSR1B = 0x18; //Enable RX/TX hardware, 8bit char
|
|
||||||
//UCSR1B |= 0xC0; //Enable RX/TX interrupt,
|
|
||||||
UCSR1C = 0x06; ; //async, No parity, 1 stop bit, 8bit char,
|
|
||||||
UBRR1 = hwCfg->uart_prescaler; //UART baud rate select
|
|
||||||
|
|
||||||
|
|
||||||
//"Systick" timer configuration
|
|
||||||
PRR0 &= ~0x20; //Enable Timer0 power
|
|
||||||
TCCR0A = 0x02 ;//OC0x not connected, WGM 0x01-CTC OC0A TOP
|
|
||||||
TCCR0B = 0x00; //WGM 0x01-CTC, No clock
|
|
||||||
TIMSK0 = 0x00;
|
|
||||||
//TIMSK0 |= 0x01; //OVF interrupt enabled
|
|
||||||
TCNT0 = 0x00;
|
|
||||||
OCR0A = hwCfg->systick_timer_top;
|
|
||||||
OCR0B= 0x00;
|
|
||||||
TIFR0 = 0x00; //Reset all flags
|
|
||||||
|
|
||||||
tim0_prescaler = (uint8_t)hwCfg->systick_timer_prescaler;
|
|
||||||
TCCR0B |= tim0_prescaler;
|
|
||||||
|
|
||||||
|
|
||||||
//Disabled not used power configuration
|
|
||||||
if(hwCfg->disable_unused)
|
|
||||||
{
|
|
||||||
//Disable power to not used peripherals
|
|
||||||
PRR0 |= 0xC6; //Disable TWI0, TIM2, SPI0, UART0
|
|
||||||
PRR1 |= 0x34; //Disable TWI1, PRTC, SPI1
|
|
||||||
}
|
|
||||||
|
|
||||||
//Watchdog configuration
|
|
||||||
if(hwCfg->en_watchdog)
|
|
||||||
{
|
|
||||||
//watchdog timer setup
|
|
||||||
WDTCSR |= 0x10; //Change enable
|
|
||||||
WDTCSR |= 0x0D; //System reset mode, 0.5s period.
|
|
||||||
//use special instruction to reset watchdog timer
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Handbrake input
|
|
||||||
level_t HAL_ReadLvl_Handbrake(void)
|
|
||||||
{
|
|
||||||
if(PINB & 0x40) return HIGH;
|
|
||||||
else return LOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Brakes input
|
|
||||||
level_t HAL_ReadLvl_Brake(void)
|
|
||||||
{
|
|
||||||
if(PINB & 0x80) return HIGH;
|
|
||||||
else return LOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dimm input
|
|
||||||
level_t HAL_ReadLvl_Dimm(void)
|
|
||||||
{
|
|
||||||
if(PIND & 0x80) return HIGH;
|
|
||||||
else return LOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
// UP button
|
|
||||||
level_t HAL_ReadLvl_BtnUp(void)
|
|
||||||
{
|
|
||||||
if(PINE & 0x08) return HIGH;
|
|
||||||
else return LOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Down button
|
|
||||||
level_t HAL_ReadLvl_BtnDown(void)
|
|
||||||
{
|
|
||||||
if(PINE & 0x02) return HIGH;
|
|
||||||
else return LOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mode button
|
|
||||||
level_t HAL_ReadLvl_BtnMode(void)
|
|
||||||
{
|
|
||||||
if(PINC & 0x20) return HIGH;
|
|
||||||
else return LOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handbrake pull
|
|
||||||
level_t HAL_ReadLvl_HandbrakePull(void)
|
|
||||||
{
|
|
||||||
if(PINB & 0x20) return HIGH;
|
|
||||||
else return LOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Coil driver control low
|
|
||||||
level_t HAL_ReadLvl_CoilLow(void)
|
|
||||||
{
|
|
||||||
if(PINB & 0x01) return HIGH;
|
|
||||||
else return LOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Coil driver control high
|
|
||||||
level_t HAL_ReadLvl_CoilHigh(void)
|
|
||||||
{
|
|
||||||
if(PINB & 0x02) return HIGH;
|
|
||||||
else return LOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
// LED PWM control
|
|
||||||
level_t HAL_ReadLvl_LedsPwm(void)
|
|
||||||
{
|
|
||||||
if(PINB & 0x04) return HIGH;
|
|
||||||
else return LOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Speed 0 input pin
|
|
||||||
level_t HAL_ReadLvl_Speed0(void)
|
|
||||||
{
|
|
||||||
if(PINE & 0x04) return HIGH;
|
|
||||||
else return LOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Speed 1 input pin
|
|
||||||
level_t HAL_ReadLvl_Speed1(void)
|
|
||||||
{
|
|
||||||
if(PINE & 0x01) return HIGH;
|
|
||||||
else return LOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Speed common pull pin
|
|
||||||
level_t HAL_ReadLvl_SpeedPull(void)
|
|
||||||
{
|
|
||||||
if(PIND & 0x40) return HIGH;
|
|
||||||
else return LOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Set handbrake pull-up
|
|
||||||
void HAL_SetPull_Handbrake(level_t lvl)
|
|
||||||
{
|
|
||||||
switch(lvl)
|
|
||||||
{
|
|
||||||
case HIGH:
|
|
||||||
PORTB |= 0x20; //Set high
|
|
||||||
DDRB |= 0x20; //Set as output
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LOW:
|
|
||||||
PORTB &= ~0x20; //Set low
|
|
||||||
DDRB |= 0x20; //Set as output
|
|
||||||
|
|
||||||
default:
|
|
||||||
DDRB &= ~0x20; //Set as input
|
|
||||||
PORTB |= 0x20; //Set high
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set speed inputs common pull
|
|
||||||
void HAL_SetPull_Speed(level_t lvl)
|
|
||||||
{
|
|
||||||
switch(lvl)
|
|
||||||
{
|
|
||||||
case HIGH:
|
|
||||||
PORTD |= 0x40; //Set high
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
PORTD &= ~0x40; //Set low
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ADC Wake
|
|
||||||
void HAL_ADC_Wake(void)
|
|
||||||
{
|
|
||||||
//Enable ADC power
|
|
||||||
PRR0 &= ~0x01;
|
|
||||||
//Enable ADC
|
|
||||||
ADCSRA |= 0x80;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ADC Sleep
|
|
||||||
void HAL_ADC_Sleep(void)
|
|
||||||
{
|
|
||||||
//wait to finish
|
|
||||||
while(ADCSRA&0x40);
|
|
||||||
//Disable ADC
|
|
||||||
ADCSRA &= ~0x80;
|
|
||||||
//Disable ADC power
|
|
||||||
PRR0 |= 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ADC Read
|
|
||||||
uint16_t HAL_ADC_Read(adcCh_t ch)
|
|
||||||
{
|
|
||||||
//check if ADC is enabled
|
|
||||||
if(!(ADCSRA&0x80)) return 0xFFFF;
|
|
||||||
|
|
||||||
uint8_t mux = (uint8_t)ch;
|
|
||||||
//Safe guard mux
|
|
||||||
if(mux > 15) return 0xFFFF;
|
|
||||||
// Not available channels
|
|
||||||
if((mux > 8) && (mux<14)) return 0xFFFF;
|
|
||||||
|
|
||||||
ADMUX &= ~0x0F;
|
|
||||||
ADMUX |= mux;
|
|
||||||
ADCSRA |= 0x40;
|
|
||||||
while(ADCSRA&0x40); //wait to finish
|
|
||||||
return ADC;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Coil Driver Low Side control
|
|
||||||
void HAL_Coil_SetLowSide(uint8_t on)
|
|
||||||
{
|
|
||||||
if(on) PORTB |= 0x01;
|
|
||||||
else PORTB &= ~0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HAL_Coil_SetPWM(uint8_t percent)
|
|
||||||
{
|
|
||||||
HAL_PWM_SetDuty100(PWM_COIL, percent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HAL_Coil_SetPWM16b(uint16_t value)
|
|
||||||
{
|
|
||||||
HAL_PWM_SetDuty16b(PWM_COIL, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// LED Display
|
|
||||||
void HAL_LEDS_Set(uint8_t image)
|
|
||||||
{
|
|
||||||
//Read current PORTD pin6, pin7
|
|
||||||
uint8_t keep = PORTD & 0xC0;
|
|
||||||
|
|
||||||
//Safe guard display
|
|
||||||
image &= 0x3F;
|
|
||||||
|
|
||||||
//Calculate new PORTD
|
|
||||||
keep |= image;
|
|
||||||
|
|
||||||
//Set PORTD
|
|
||||||
PORTD = keep;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t HAL_LEDS_Get(void)
|
|
||||||
{
|
|
||||||
return (PIND & 0x3F);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HAL_LEDS_SetPWM(uint8_t percent)
|
|
||||||
{
|
|
||||||
HAL_PWM_SetDuty100(PWM_LED, percent);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// PWM Direct functions
|
|
||||||
void HAL_PWM_Wake(void)
|
|
||||||
{
|
|
||||||
//Enable Timer1 power
|
|
||||||
PRR0 &= ~0x80;
|
|
||||||
//Prepare Timer1 settings
|
|
||||||
TCNT1 = 0x0000;
|
|
||||||
OCR1A = 0x0000;
|
|
||||||
OCR1B = 0x0000;
|
|
||||||
//Enable clock
|
|
||||||
TCCR1B |= tim1_prescaler; //Enable timer
|
|
||||||
}
|
|
||||||
|
|
||||||
void HAL_PWM_Sleep(void)
|
|
||||||
{
|
|
||||||
// Turn off outputs
|
|
||||||
OCR1A = 0x0000;
|
|
||||||
OCR1B = 0x0000;
|
|
||||||
// Force timer to bottom
|
|
||||||
TCNT1 = (ICR1-1);
|
|
||||||
// Wait for outputs to be off
|
|
||||||
while((PINB&0x06)!=0x00) continue;
|
|
||||||
// Disable clock
|
|
||||||
TCCR1B &= ~0x07;
|
|
||||||
// Disable Timer1 power
|
|
||||||
PRR0 |= 0x80;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HAL_PWM_SetDuty16b(pwmCh_t ch, uint16_t value)
|
|
||||||
{
|
|
||||||
value = 0xFFFF - value;
|
|
||||||
|
|
||||||
uint32_t top = (uint32_t)ICR1;
|
|
||||||
uint32_t temp = (uint32_t)value * top;
|
|
||||||
temp = temp/0x0000FFFF;
|
|
||||||
//Limit temp
|
|
||||||
if(temp>0x0000FFFF) temp = 0x0000FFFF;
|
|
||||||
uint16_t ocrx = (uint16_t) temp;
|
|
||||||
|
|
||||||
PWM_SetOCx(ch, ocrx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HAL_PWM_SetDuty100(pwmCh_t ch, uint8_t percent)
|
|
||||||
{
|
|
||||||
if(percent > 100) percent = 100;
|
|
||||||
percent = 100 - percent;
|
|
||||||
|
|
||||||
uint32_t top = (uint32_t)ICR1;
|
|
||||||
uint32_t temp = (uint32_t)percent * top;
|
|
||||||
temp = temp/100;
|
|
||||||
//Limit temp
|
|
||||||
if(temp>0x0000FFFF) temp = 0x0000FFFF;
|
|
||||||
uint16_t ocrx = (uint16_t) temp;
|
|
||||||
|
|
||||||
PWM_SetOCx(ch, ocrx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**** Private function definitions ****/
|
|
||||||
static void PWM_SetOCx(pwmCh_t ch, uint16_t value)
|
|
||||||
{
|
|
||||||
switch(ch)
|
|
||||||
{
|
|
||||||
case PWM_COIL:
|
|
||||||
OCR1A = value;
|
|
||||||
return;
|
|
||||||
|
|
||||||
case PWM_LED:
|
|
||||||
OCR1B = value;
|
|
||||||
return;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,85 @@
|
|||||||
/*
|
/**** Includes ****/
|
||||||
* uDCCD.cpp
|
#include "utils/utils.h"
|
||||||
*
|
#include "board/mcu/mcu_hal.h"
|
||||||
* Created: 12.03.2024 20:39:27
|
#include "board/ain.h"
|
||||||
* Author : User
|
#include "board/dio.h"
|
||||||
*/
|
#include "board/hvdin.h"
|
||||||
|
#include "board/halfbridge.h"
|
||||||
|
#include "board/od_com.h"
|
||||||
|
#include "board/odout.h"
|
||||||
|
|
||||||
#include <avr/io.h>
|
/**** Private definitions ****/
|
||||||
|
/**** Private constants ****/
|
||||||
|
/**** Private variables ****/
|
||||||
|
static board::AnalogIn dccd_i(mcu::ADC0);
|
||||||
|
static board::AnalogIn dccd_u(mcu::ADC1);
|
||||||
|
static board::AnalogIn bat_u(mcu::ADC2);
|
||||||
|
static board::AnalogIn bat_i(mcu::ADC3);
|
||||||
|
|
||||||
|
static board::AnalogIn ain1(mcu::ADC5);
|
||||||
|
static board::AnalogIn ain2(mcu::ADC4);
|
||||||
|
|
||||||
|
static board::DigitalIO din1(mcu::GPIO0, board::DIO_HIGH);
|
||||||
|
static board::DigitalIO din2(mcu::GPIO1, board::DIO_HIGH);
|
||||||
|
static board::DigitalIO din3(mcu::GPIO2, board::DIO_HIGH);
|
||||||
|
static board::DigitalIO din4(mcu::GPIO3, board::DIO_HIGH);
|
||||||
|
|
||||||
|
static board::HVDigitalIn hvdin1(mcu::GPIO4, board::HVDIN_LOW);
|
||||||
|
static board::HVDigitalIn hvdin2(mcu::GPIO5, board::HVDIN_LOW);
|
||||||
|
static board::HVDigitalIn hvdin3(mcu::GPIO6, board::HVDIN_LOW);
|
||||||
|
|
||||||
|
/**** Private function declarations ****/
|
||||||
|
/**** Public function definitions ****/
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
/* Replace with your application code */
|
mcu::startupCfg_t mcu_cfg;
|
||||||
while (1)
|
mcu_cfg.adc_clk = mcu::ADC_DIV2;
|
||||||
{
|
mcu_cfg.pwm_clk = mcu::TIM_DIV1;
|
||||||
}
|
mcu_cfg.pwm_top = 200;
|
||||||
|
mcu_cfg.pwm_ch1_en = 1;
|
||||||
|
|
||||||
|
mcu::startup(&mcu_cfg);
|
||||||
|
|
||||||
|
dccd_i.mul = 1;
|
||||||
|
dccd_i.div = 1;
|
||||||
|
dccd_i.offset = 0;
|
||||||
|
|
||||||
|
dccd_u.mul = 1;
|
||||||
|
dccd_u.div = 1;
|
||||||
|
dccd_u.offset = 0;
|
||||||
|
|
||||||
|
bat_u.mul = 1;
|
||||||
|
bat_u.div = 1;
|
||||||
|
bat_u.offset = 0;
|
||||||
|
|
||||||
|
bat_i.mul = 1;
|
||||||
|
bat_i.div = 1;
|
||||||
|
bat_i.offset = 0;
|
||||||
|
|
||||||
|
// Super loop
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
dccd_i.read();
|
||||||
|
dccd_u.read();
|
||||||
|
bat_u.read();
|
||||||
|
bat_i.read();
|
||||||
|
ain1.read();
|
||||||
|
ain2.read();
|
||||||
|
|
||||||
|
din1.read();
|
||||||
|
din2.read();
|
||||||
|
din3.read();
|
||||||
|
din4.read();
|
||||||
|
|
||||||
|
hvdin1.read();
|
||||||
|
hvdin2.read();
|
||||||
|
hvdin3.read();
|
||||||
|
|
||||||
|
continue; // End of super loop
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escape the matrix
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**** Private function definitions ***/
|
||||||
|
|||||||
@@ -30,132 +30,191 @@
|
|||||||
<EraseKey />
|
<EraseKey />
|
||||||
<AsfFrameworkConfig>
|
<AsfFrameworkConfig>
|
||||||
<framework-data xmlns="">
|
<framework-data xmlns="">
|
||||||
<options />
|
<options />
|
||||||
<configurations />
|
<configurations />
|
||||||
<files />
|
<files />
|
||||||
<documentation help="" />
|
<documentation help="" />
|
||||||
<offline-documentation help="" />
|
<offline-documentation help="" />
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<content-extension eid="atmel.asf" uuidref="Atmel.ASF" version="3.52.0" />
|
<content-extension eid="atmel.asf" uuidref="Atmel.ASF" version="3.52.0" />
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</framework-data>
|
</framework-data>
|
||||||
</AsfFrameworkConfig>
|
</AsfFrameworkConfig>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||||
<ToolchainSettings>
|
<ToolchainSettings>
|
||||||
<AvrGccCpp>
|
<AvrGccCpp>
|
||||||
<avrgcc.common.Device>-mmcu=atmega328pb -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.7.374\gcc\dev\atmega328pb"</avrgcc.common.Device>
|
<avrgcc.common.Device>-mmcu=atmega328pb -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.7.374\gcc\dev\atmega328pb"</avrgcc.common.Device>
|
||||||
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
|
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
|
||||||
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
|
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
|
||||||
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
|
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
|
||||||
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
|
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
|
||||||
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
|
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
|
||||||
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
|
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||||
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
|
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||||
<avrgcc.compiler.symbols.DefSymbols>
|
<avrgcc.compiler.symbols.DefSymbols>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<Value>NDEBUG</Value>
|
<Value>NDEBUG</Value>
|
||||||
</ListValues>
|
</ListValues>
|
||||||
</avrgcc.compiler.symbols.DefSymbols>
|
</avrgcc.compiler.symbols.DefSymbols>
|
||||||
<avrgcc.compiler.directories.IncludePaths>
|
<avrgcc.compiler.directories.IncludePaths>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.7.374\include\</Value>
|
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.7.374\include\</Value>
|
||||||
</ListValues>
|
</ListValues>
|
||||||
</avrgcc.compiler.directories.IncludePaths>
|
</avrgcc.compiler.directories.IncludePaths>
|
||||||
<avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level>
|
<avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level>
|
||||||
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
|
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
|
||||||
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
|
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
|
||||||
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
|
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
|
||||||
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
|
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||||
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
|
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||||
<avrgcccpp.compiler.symbols.DefSymbols>
|
<avrgcccpp.compiler.symbols.DefSymbols>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<Value>NDEBUG</Value>
|
<Value>NDEBUG</Value>
|
||||||
</ListValues>
|
</ListValues>
|
||||||
</avrgcccpp.compiler.symbols.DefSymbols>
|
</avrgcccpp.compiler.symbols.DefSymbols>
|
||||||
<avrgcccpp.compiler.directories.IncludePaths>
|
<avrgcccpp.compiler.directories.IncludePaths>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.7.374\include\</Value>
|
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.7.374\include\</Value>
|
||||||
</ListValues>
|
</ListValues>
|
||||||
</avrgcccpp.compiler.directories.IncludePaths>
|
</avrgcccpp.compiler.directories.IncludePaths>
|
||||||
<avrgcccpp.compiler.optimization.level>Optimize for size (-Os)</avrgcccpp.compiler.optimization.level>
|
<avrgcccpp.compiler.optimization.level>Optimize for size (-Os)</avrgcccpp.compiler.optimization.level>
|
||||||
<avrgcccpp.compiler.optimization.PackStructureMembers>True</avrgcccpp.compiler.optimization.PackStructureMembers>
|
<avrgcccpp.compiler.optimization.PackStructureMembers>True</avrgcccpp.compiler.optimization.PackStructureMembers>
|
||||||
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
|
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
|
||||||
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
|
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
|
||||||
<avrgcccpp.linker.libraries.Libraries>
|
<avrgcccpp.linker.libraries.Libraries>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<Value>libm</Value>
|
<Value>libm</Value>
|
||||||
</ListValues>
|
</ListValues>
|
||||||
</avrgcccpp.linker.libraries.Libraries>
|
</avrgcccpp.linker.libraries.Libraries>
|
||||||
<avrgcccpp.assembler.general.IncludePaths>
|
<avrgcccpp.assembler.general.IncludePaths>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.7.374\include\</Value>
|
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.7.374\include\</Value>
|
||||||
</ListValues>
|
</ListValues>
|
||||||
</avrgcccpp.assembler.general.IncludePaths>
|
</avrgcccpp.assembler.general.IncludePaths>
|
||||||
</AvrGccCpp>
|
</AvrGccCpp>
|
||||||
</ToolchainSettings>
|
</ToolchainSettings>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
<ToolchainSettings>
|
<ToolchainSettings>
|
||||||
<AvrGccCpp>
|
<AvrGccCpp>
|
||||||
<avrgcc.common.Device>-mmcu=atmega328pb -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.7.374\gcc\dev\atmega328pb"</avrgcc.common.Device>
|
<avrgcc.common.Device>-mmcu=atmega328pb -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.7.374\gcc\dev\atmega328pb"</avrgcc.common.Device>
|
||||||
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
|
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
|
||||||
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
|
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
|
||||||
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
|
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
|
||||||
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
|
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
|
||||||
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
|
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
|
||||||
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
|
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||||
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
|
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||||
<avrgcc.compiler.symbols.DefSymbols>
|
<avrgcc.compiler.symbols.DefSymbols>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<Value>DEBUG</Value>
|
<Value>DEBUG</Value>
|
||||||
</ListValues>
|
</ListValues>
|
||||||
</avrgcc.compiler.symbols.DefSymbols>
|
</avrgcc.compiler.symbols.DefSymbols>
|
||||||
<avrgcc.compiler.directories.IncludePaths>
|
<avrgcc.compiler.directories.IncludePaths>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.7.374\include\</Value>
|
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.7.374\include\</Value>
|
||||||
</ListValues>
|
</ListValues>
|
||||||
</avrgcc.compiler.directories.IncludePaths>
|
</avrgcc.compiler.directories.IncludePaths>
|
||||||
<avrgcc.compiler.optimization.level>Optimize debugging experience (-Og)</avrgcc.compiler.optimization.level>
|
<avrgcc.compiler.optimization.level>Optimize debugging experience (-Og)</avrgcc.compiler.optimization.level>
|
||||||
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
|
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
|
||||||
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
|
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
|
||||||
<avrgcc.compiler.optimization.DebugLevel>Default (-g2)</avrgcc.compiler.optimization.DebugLevel>
|
<avrgcc.compiler.optimization.DebugLevel>Default (-g2)</avrgcc.compiler.optimization.DebugLevel>
|
||||||
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
|
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
|
||||||
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
|
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||||
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
|
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||||
<avrgcccpp.compiler.symbols.DefSymbols>
|
<avrgcccpp.compiler.symbols.DefSymbols>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<Value>DEBUG</Value>
|
<Value>DEBUG</Value>
|
||||||
</ListValues>
|
</ListValues>
|
||||||
</avrgcccpp.compiler.symbols.DefSymbols>
|
</avrgcccpp.compiler.symbols.DefSymbols>
|
||||||
<avrgcccpp.compiler.directories.IncludePaths>
|
<avrgcccpp.compiler.directories.IncludePaths>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.7.374\include\</Value>
|
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.7.374\include\</Value>
|
||||||
</ListValues>
|
</ListValues>
|
||||||
</avrgcccpp.compiler.directories.IncludePaths>
|
</avrgcccpp.compiler.directories.IncludePaths>
|
||||||
<avrgcccpp.compiler.optimization.level>Optimize debugging experience (-Og)</avrgcccpp.compiler.optimization.level>
|
<avrgcccpp.compiler.optimization.level>Optimize debugging experience (-Og)</avrgcccpp.compiler.optimization.level>
|
||||||
<avrgcccpp.compiler.optimization.PackStructureMembers>True</avrgcccpp.compiler.optimization.PackStructureMembers>
|
<avrgcccpp.compiler.optimization.PackStructureMembers>True</avrgcccpp.compiler.optimization.PackStructureMembers>
|
||||||
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
|
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
|
||||||
<avrgcccpp.compiler.optimization.DebugLevel>Default (-g2)</avrgcccpp.compiler.optimization.DebugLevel>
|
<avrgcccpp.compiler.optimization.DebugLevel>Default (-g2)</avrgcccpp.compiler.optimization.DebugLevel>
|
||||||
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
|
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
|
||||||
<avrgcccpp.linker.libraries.Libraries>
|
<avrgcccpp.linker.libraries.Libraries>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<Value>libm</Value>
|
<Value>libm</Value>
|
||||||
</ListValues>
|
</ListValues>
|
||||||
</avrgcccpp.linker.libraries.Libraries>
|
</avrgcccpp.linker.libraries.Libraries>
|
||||||
<avrgcccpp.assembler.general.IncludePaths>
|
<avrgcccpp.assembler.general.IncludePaths>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.7.374\include\</Value>
|
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.7.374\include\</Value>
|
||||||
</ListValues>
|
</ListValues>
|
||||||
</avrgcccpp.assembler.general.IncludePaths>
|
</avrgcccpp.assembler.general.IncludePaths>
|
||||||
<avrgcccpp.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcccpp.assembler.debugging.DebugLevel>
|
<avrgcccpp.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcccpp.assembler.debugging.DebugLevel>
|
||||||
</AvrGccCpp>
|
</AvrGccCpp>
|
||||||
</ToolchainSettings>
|
</ToolchainSettings>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="board\ain.cpp">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="board\ain.h">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="board\dio.cpp">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="board\dio.h">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="board\halfbridge.cpp">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="board\halfbridge.h">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="board\hvdin.cpp">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="board\hvdin.h">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="board\mcu\mcu_hal.h">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="board\mcu\mcu_hal_r8.cpp">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="board\odout.cpp">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="board\odout.h">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="board\od_com.cpp">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="board\od_com.h">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="main.cpp">
|
<Compile Include="main.cpp">
|
||||||
<SubType>compile</SubType>
|
<SubType>compile</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="utils\interpolate.cpp">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="utils\interpolate.h">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="utils\utils.cpp">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="utils\utils.h">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="board" />
|
||||||
|
<Folder Include="board\mcu" />
|
||||||
|
<Folder Include="utils" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
|
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
163
firmware/src/utils/interpolate.cpp
Normal file
163
firmware/src/utils/interpolate.cpp
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
/**** Includes ****/
|
||||||
|
#include "utils.h"
|
||||||
|
#include "interpolate.h"
|
||||||
|
|
||||||
|
using namespace util;
|
||||||
|
|
||||||
|
/**** Private definitions ****/
|
||||||
|
/**** Private constants ****/
|
||||||
|
/**** Private variables ****/
|
||||||
|
/**** Private function declarations ****/
|
||||||
|
/**** Public function definitions ****/
|
||||||
|
uint16_t util::interpolate_1d(uint16_t x, uint16_t* x_axis, uint16_t* y_values, uint8_t len_axis)
|
||||||
|
{
|
||||||
|
// validate axis length
|
||||||
|
if(len_axis==0) return 0; // Empty data set
|
||||||
|
if(len_axis==1) return y_values[0]; // Only one data point
|
||||||
|
|
||||||
|
uint16_t y;
|
||||||
|
|
||||||
|
uint8_t i = find_interval_end_index(x, x_axis, len_axis);
|
||||||
|
if(i==0)
|
||||||
|
{
|
||||||
|
//Less then start
|
||||||
|
y = y_values[0];
|
||||||
|
}
|
||||||
|
else if(i==len_axis)
|
||||||
|
{
|
||||||
|
//More than end
|
||||||
|
y = y_values[len_axis-1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Do interpolate
|
||||||
|
y = interpolate(x, x_axis[i-1], x_axis[i], y_values[i-1], y_values[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t util::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)
|
||||||
|
{
|
||||||
|
// validate axis length
|
||||||
|
if((len_x_axis==0)&&(len_y_axis==0)) return 0; // Empty data set
|
||||||
|
if((len_x_axis==1)&&(len_y_axis==1)) return z_values[0]; // Only one data point
|
||||||
|
|
||||||
|
uint8_t ix = find_interval_end_index(x, x_axis, len_x_axis);
|
||||||
|
uint8_t iy = find_interval_end_index(y, y_axis, len_y_axis);
|
||||||
|
|
||||||
|
// Check corners - easy answers
|
||||||
|
if((ix==0)&&(iy==0))
|
||||||
|
{
|
||||||
|
return z_values[0]; //[0][0] [Y][X]
|
||||||
|
}
|
||||||
|
else if((ix==len_x_axis)&&(iy==0))
|
||||||
|
{
|
||||||
|
return z_values[len_x_axis-1]; //[0][end]
|
||||||
|
}
|
||||||
|
else if((ix==0)&&(iy==len_y_axis))
|
||||||
|
{
|
||||||
|
uint16_t i = index2d_to_index1d(0, len_y_axis-1, len_x_axis);
|
||||||
|
return z_values[i]; //[end][0]
|
||||||
|
}
|
||||||
|
else if((ix==len_x_axis)&&(iy==len_y_axis))
|
||||||
|
{
|
||||||
|
uint16_t i = index2d_to_index1d(len_x_axis-1, len_y_axis-1, len_x_axis);
|
||||||
|
return z_values[i]; //[end][end]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check boundaries - 1D interpolation
|
||||||
|
if(ix==0)
|
||||||
|
{
|
||||||
|
// On ix=0 line
|
||||||
|
uint16_t i = 0;
|
||||||
|
uint16_t z0 = z_values[i];
|
||||||
|
i = index2d_to_index1d(0, len_y_axis-1, len_x_axis);
|
||||||
|
uint16_t z1 = z_values[i];
|
||||||
|
return interpolate(y, y_axis[0], y_axis[len_y_axis-1], z0, z1);
|
||||||
|
}
|
||||||
|
else if(ix==len_x_axis)
|
||||||
|
{
|
||||||
|
// On ix=END line
|
||||||
|
uint16_t i = len_x_axis-1;
|
||||||
|
uint16_t z0 = z_values[i];
|
||||||
|
i = index2d_to_index1d(len_x_axis-1, len_y_axis-1, len_x_axis);
|
||||||
|
uint16_t z1 = z_values[i];
|
||||||
|
return interpolate(y, y_axis[0], y_axis[len_y_axis-1], z0, z1);
|
||||||
|
}
|
||||||
|
else if(iy==0)
|
||||||
|
{
|
||||||
|
// On iy=0 line
|
||||||
|
uint16_t i = 0;
|
||||||
|
uint16_t z0 = z_values[i];
|
||||||
|
i = len_x_axis-1;
|
||||||
|
uint16_t z1 = z_values[i];
|
||||||
|
return interpolate(x, x_axis[0], x_axis[len_x_axis-1], z0, z1);
|
||||||
|
}
|
||||||
|
else if(iy==len_y_axis)
|
||||||
|
{
|
||||||
|
// On iy=END line
|
||||||
|
uint16_t i = index2d_to_index1d(0, len_y_axis-1, len_x_axis);
|
||||||
|
uint16_t z0 = z_values[i];
|
||||||
|
i = index2d_to_index1d(len_x_axis-1, len_y_axis-1, len_x_axis);
|
||||||
|
uint16_t z1 = z_values[i];
|
||||||
|
return interpolate(x, x_axis[0], x_axis[len_x_axis-1], z0, z1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do interpolation
|
||||||
|
// Get axis values
|
||||||
|
uint16_t x0 = x_axis[ix-1];
|
||||||
|
uint16_t x1 = x_axis[ix];
|
||||||
|
uint16_t y0 = y_axis[iy-1];
|
||||||
|
uint16_t y1 = y_axis[iy];
|
||||||
|
|
||||||
|
// Do y0 line calculation
|
||||||
|
// Get z values at x0 and x1 points on y0 line
|
||||||
|
uint16_t i = index2d_to_index1d(ix-1, iy-1, len_x_axis);
|
||||||
|
uint16_t z0 = z_values[i];
|
||||||
|
uint16_t z1 = z_values[i+1];
|
||||||
|
// Interpolate z value on y0 line
|
||||||
|
uint16_t zy0 = interpolate(x, x0, x1, z0, z1);
|
||||||
|
|
||||||
|
// Do y1 line calculation
|
||||||
|
// Get z values at x0 and x1 points on y1 line
|
||||||
|
i = index2d_to_index1d(ix-1, iy, len_x_axis);
|
||||||
|
z0 = z_values[i];
|
||||||
|
z1 = z_values[i+1];
|
||||||
|
// Interpolate z value on y0 line
|
||||||
|
uint16_t zy1 = interpolate(x, x0, x1, z0, z1);
|
||||||
|
|
||||||
|
// Do calculation in y axis on xz line
|
||||||
|
return interpolate(y, y0, y1, zy0, zy1);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
int32_t d = (int32_t)x - (int32_t)x0;
|
||||||
|
|
||||||
|
int32_t y = dy * d;
|
||||||
|
y /= dx;
|
||||||
|
y += y0;
|
||||||
|
|
||||||
|
return util::sat_cast(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
if(val < axis_values[i]) return i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len_axis;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t index2d_to_index1d(uint8_t ix, uint8_t iy, uint8_t len_x)
|
||||||
|
{
|
||||||
|
return ((uint16_t)len_x * iy) + ix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**** Private function definitions ****/
|
||||||
23
firmware/src/utils/interpolate.h
Normal file
23
firmware/src/utils/interpolate.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef UTILS_INTERPOLATE_H_
|
||||||
|
#define UTILS_INTERPOLATE_H_
|
||||||
|
|
||||||
|
/**** Includes ****/
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace util {
|
||||||
|
|
||||||
|
/**** Public definitions ****/
|
||||||
|
/**** Public function declarations ****/
|
||||||
|
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);
|
||||||
|
|
||||||
|
uint8_t find_interval_end_index(uint16_t val, uint16_t* axis_values, uint8_t len_axis);
|
||||||
|
uint16_t interpolate(uint16_t x, uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1);
|
||||||
|
uint16_t index2d_to_index1d(uint8_t ix, uint8_t iy, uint8_t len_x);
|
||||||
|
|
||||||
|
#ifdef TESTING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} //namespace
|
||||||
|
|
||||||
|
#endif /* UTILS_INTERPOLATE_H_ */
|
||||||
137
firmware/src/utils/utils.cpp
Normal file
137
firmware/src/utils/utils.cpp
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
/**** Includes ****/
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
using namespace util;
|
||||||
|
|
||||||
|
/**** Private definitions ****/
|
||||||
|
/**** Private constants ****/
|
||||||
|
/**** Private variables ****/
|
||||||
|
/**** Private function declarations ****/
|
||||||
|
#ifndef TESTING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**** Public function definitions ****/
|
||||||
|
uint8_t util::invert(uint8_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;
|
||||||
|
// Check for overflow
|
||||||
|
if((z < x)||(z < y)) return 0xFF;
|
||||||
|
else return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t util::sat_add(uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
uint16_t z = x + y;
|
||||||
|
// Check for overflow
|
||||||
|
if((z < x)||(z < y)) return 0xFF;
|
||||||
|
else return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t util::sat_add(uint32_t x, uint32_t y)
|
||||||
|
|
||||||
|
{
|
||||||
|
uint32_t z = x + y;
|
||||||
|
// Check for overflow
|
||||||
|
if((z < x)||(z < y)) return 0xFF;
|
||||||
|
else return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t util::sat_subtract(uint8_t x, uint8_t y)
|
||||||
|
{
|
||||||
|
uint8_t z = x - y;
|
||||||
|
// Check for underflow
|
||||||
|
if(z > x) return 0;
|
||||||
|
else return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t util::sat_subtract(uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
uint16_t z = x - y;
|
||||||
|
// Check for underflow
|
||||||
|
if(z > x) return 0;
|
||||||
|
else return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t util::sat_subtract(uint32_t x, uint32_t y)
|
||||||
|
{
|
||||||
|
uint32_t z = x - y;
|
||||||
|
// Check for underflow
|
||||||
|
if(z > x) return 0;
|
||||||
|
else return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t util::sat_cast(uint32_t x)
|
||||||
|
{
|
||||||
|
if(x > 0x0000FFFF) return 0xFFFF;
|
||||||
|
else return (uint16_t)x;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t util::sat_cast(int32_t x)
|
||||||
|
{
|
||||||
|
if(x < 0) return 0x0000;
|
||||||
|
else if(x > 0x0000FFFF) return 0xFFFF;
|
||||||
|
else return (uint16_t)x;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t util::convert_muldivoff(uint16_t raw, uint8_t mul, uint8_t div, int16_t offset)
|
||||||
|
{
|
||||||
|
int32_t temp = (int32_t)raw;
|
||||||
|
|
||||||
|
temp = temp * mul;
|
||||||
|
if(div>1) temp /= div;
|
||||||
|
temp += offset;
|
||||||
|
|
||||||
|
return sat_cast(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t util::sat_mul_kilo(uint16_t xk, uint16_t yk)
|
||||||
|
{
|
||||||
|
uint32_t temp = (uint32_t)xk * (uint32_t)yk;
|
||||||
|
temp /= 1000;
|
||||||
|
|
||||||
|
return sat_cast(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t util::sat_div_kilo(uint16_t top, uint16_t bot)
|
||||||
|
{
|
||||||
|
//Sanity check bot
|
||||||
|
if(bot==0) return 0xFFFF; //aka infinity
|
||||||
|
|
||||||
|
uint32_t temp = (uint32_t)top * 1000;
|
||||||
|
temp /= (uint32_t)bot;
|
||||||
|
|
||||||
|
return sat_cast(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t util::sat_ratio(uint16_t top, uint16_t bot)
|
||||||
|
{
|
||||||
|
//Sanity check bot
|
||||||
|
if(bot==0) return 0xFFFF; //aka infinity
|
||||||
|
|
||||||
|
//Easy option
|
||||||
|
if(top>=bot) return 0xFFFF;
|
||||||
|
|
||||||
|
uint32_t temp = (uint32_t)top * 0x0000FFFF;
|
||||||
|
temp /= (uint32_t)bot;
|
||||||
|
|
||||||
|
return sat_cast(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t util::percent_to_16b(uint8_t percent)
|
||||||
|
{
|
||||||
|
uint32_t temp = (uint32_t)percent * 0x0000FFFF;
|
||||||
|
temp /= 100;
|
||||||
|
|
||||||
|
// Limit to 16 bits
|
||||||
|
uint16_t pwm = sat_cast(temp);
|
||||||
|
|
||||||
|
return pwm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**** Private function definitions ****/
|
||||||
38
firmware/src/utils/utils.h
Normal file
38
firmware/src/utils/utils.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef UTILS_H_
|
||||||
|
#define UTILS_H_
|
||||||
|
|
||||||
|
/**** Includes ****/
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace util {
|
||||||
|
|
||||||
|
/**** Public definitions ****/
|
||||||
|
/**** Public function declarations ****/
|
||||||
|
uint8_t invert(uint8_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);
|
||||||
|
uint32_t sat_add(uint32_t x, uint32_t y);
|
||||||
|
|
||||||
|
uint8_t sat_subtract(uint8_t x, uint8_t y);
|
||||||
|
uint16_t sat_subtract(uint16_t x, uint16_t y);
|
||||||
|
uint32_t sat_subtract(uint32_t x, uint32_t y);
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
} //namespace
|
||||||
|
|
||||||
|
#endif /* UTILS_H_ */
|
||||||
Reference in New Issue
Block a user