board abstraction

This commit is contained in:
2024-04-08 19:40:48 +03:00
parent dd4ff43515
commit c50b3d90bf
23 changed files with 1705 additions and 686 deletions

View 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
View 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_ */

View 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
View 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_ */

View 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 ****/

View 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_ */

View 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 ****/

View 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_ */

View 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_ */

View 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;
}
}

View 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 ****/

View 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_ */

View 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 ****/

View 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_ */