Legacy branch migration
This commit is contained in:
120
firmware/devices/analog.c
Normal file
120
firmware/devices/analog.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/**** Includes ****/
|
||||
#include "hal/udccd_hal.h"
|
||||
#include "analog.h"
|
||||
|
||||
/**** Private variables ****/
|
||||
static const uint8_t ICOIL_MUL = 215;
|
||||
static const uint8_t ICOIL_DIV = 22;
|
||||
static const int16_t ICOIL_OFF = 0;
|
||||
static const uint8_t ICOIL_CNT = 1;
|
||||
|
||||
static const uint8_t UCOIL_MUL = 20;
|
||||
static const uint8_t UCOIL_DIV = 1;
|
||||
static const int16_t UCOIL_OFF = 0;
|
||||
static const uint8_t UCOIL_CNT = 1;
|
||||
|
||||
static const uint8_t UBAT_MUL = 20;
|
||||
static const uint8_t UBAT_DIV = 1;
|
||||
static const int16_t UBAT_OFF = 0;
|
||||
static const uint8_t UBAT_CNT = 1;
|
||||
|
||||
static const uint8_t IBAT_MUL = 235;
|
||||
static const uint8_t IBAT_DIV = 6;
|
||||
static const int16_t IBAT_OFF = 0;
|
||||
static const uint8_t IBAT_CNT = 1;
|
||||
|
||||
static const uint8_t POT_MUL = 215;
|
||||
static const uint8_t POT_DIV = 44;
|
||||
static const int16_t POT_OFF = 0;
|
||||
static const uint8_t POT_CNT = 1;
|
||||
|
||||
static const uint8_t MODE_MUL = 215;
|
||||
static const uint8_t MODE_DIV = 44;
|
||||
static const int16_t MODE_OFF = 0;
|
||||
static const uint8_t MODE_CNT = 1;
|
||||
|
||||
|
||||
/**** Private function declarations ****/
|
||||
static uint16_t ConvertSIntShort(int32_t in);
|
||||
static uint16_t ConvertUintShort(uint32_t in);
|
||||
static uint16_t read_ch(adcCh_t ch, uint16_t gnd_raw, uint8_t mul, uint8_t div, int16_t offset, uint8_t samples);
|
||||
|
||||
/**** Public function definitions ****/
|
||||
void Analog_UpdateAll(analog_t* meas)
|
||||
{
|
||||
uint16_t gnd_lvl = HAL_ADC_Read(ADC_GND);
|
||||
|
||||
meas->hb_currnet = read_ch(ADC_ICOIL, 0, ICOIL_MUL, ICOIL_DIV, ICOIL_OFF, ICOIL_CNT ); //mA
|
||||
meas->hb_voltage = read_ch(ADC_UCOIL, 0, UCOIL_MUL, UCOIL_DIV, UCOIL_OFF, UCOIL_CNT ); //mV
|
||||
meas->supply_current = read_ch(ADC_IBAT , 0, IBAT_MUL , IBAT_DIV , IBAT_OFF , IBAT_CNT ); //mA
|
||||
meas->supply_voltage = read_ch(ADC_UBAT , 0, UBAT_MUL , UBAT_DIV , UBAT_OFF , UBAT_CNT ); //mV
|
||||
meas->pot_voltage = read_ch(ADC_POT , 0, POT_MUL , POT_DIV , POT_OFF , POT_CNT ); //mV
|
||||
meas->mode_voltage = read_ch(ADC_MODE , 0, MODE_MUL , MODE_DIV , MODE_OFF , MODE_CNT ); //mV
|
||||
|
||||
// Calculate derived measurements
|
||||
// Halfbridge output power
|
||||
uint32_t temp = (uint32_t)meas->hb_currnet * (uint32_t)meas->hb_voltage;
|
||||
temp /= 1000;
|
||||
meas->hb_power = ConvertUintShort(temp);
|
||||
|
||||
// Halfbridge output resistance
|
||||
if(meas->hb_currnet == 0) meas->hb_resistance = 0xFFFF;
|
||||
else if(meas->hb_voltage == 0) meas->hb_resistance = 0;
|
||||
else
|
||||
{
|
||||
temp = (uint32_t)meas->hb_voltage * 1000;
|
||||
temp /= (uint32_t)meas->hb_currnet;
|
||||
meas->hb_resistance = ConvertUintShort(temp);
|
||||
}
|
||||
|
||||
// Supply power
|
||||
temp = (uint32_t)meas->supply_current * (uint32_t)meas->supply_voltage;
|
||||
temp /= 1000;
|
||||
meas->supply_power = ConvertUintShort(temp);
|
||||
}
|
||||
|
||||
static uint16_t read_ch(adcCh_t ch, uint16_t gnd_raw, uint8_t mul, uint8_t div, int16_t offset, uint8_t samples)
|
||||
{
|
||||
//Sanity check
|
||||
if(div==0) return 0xFFFF;
|
||||
|
||||
// Do at least one sample
|
||||
if(samples<1) samples = 1;
|
||||
|
||||
// Read ADC value
|
||||
int32_t raw = 0;
|
||||
for(uint8_t i=0; i<samples; i++)
|
||||
{
|
||||
raw += (int32_t)HAL_ADC_Read(ch);
|
||||
}
|
||||
|
||||
// Do average
|
||||
if(samples != 1)
|
||||
{
|
||||
raw /= samples;
|
||||
};
|
||||
|
||||
// Remove GND level
|
||||
if(gnd_raw) raw = raw - (int32_t)gnd_raw;
|
||||
|
||||
// Convert to target units
|
||||
raw = raw * mul;
|
||||
if(div!=1) raw /= div;
|
||||
raw += offset;
|
||||
|
||||
return ConvertSIntShort(raw);
|
||||
}
|
||||
|
||||
static uint16_t ConvertSIntShort(int32_t in)
|
||||
{
|
||||
if(in <= 0) return 0;
|
||||
else if(in >= 0x0000FFFF) return 0xFFFF;
|
||||
else return (uint16_t)in;
|
||||
}
|
||||
|
||||
static uint16_t ConvertUintShort(uint32_t in)
|
||||
{
|
||||
if(in == 0) return 0;
|
||||
else if(in >= 0x0000FFFF) return 0xFFFF;
|
||||
else return (uint16_t)in;
|
||||
}
|
||||
23
firmware/devices/analog.h
Normal file
23
firmware/devices/analog.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef ANALOG_H_
|
||||
#define ANALOG_H_
|
||||
|
||||
/**** Includes ****/
|
||||
#include <stdint.h>
|
||||
|
||||
/**** Public definitions ****/
|
||||
typedef struct {
|
||||
uint16_t hb_currnet;
|
||||
uint16_t hb_voltage;
|
||||
uint16_t hb_power;
|
||||
uint16_t hb_resistance;
|
||||
uint16_t supply_current;
|
||||
uint16_t supply_voltage;
|
||||
uint16_t supply_power;
|
||||
uint16_t pot_voltage;
|
||||
uint16_t mode_voltage;
|
||||
} analog_t;
|
||||
|
||||
/**** Public function declarations ****/
|
||||
void Analog_UpdateAll(analog_t* meas);
|
||||
|
||||
#endif /* ANALOG_H_ */
|
||||
11
firmware/devices/common/level.h
Normal file
11
firmware/devices/common/level.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef LEVEL_T_H_
|
||||
#define LEVEL_T_H_
|
||||
|
||||
/**** Public definitions ****/
|
||||
typedef enum {
|
||||
HIZ = -1,
|
||||
LOW = 0,
|
||||
HIGH = 1
|
||||
} level_t;
|
||||
|
||||
#endif /* LEVEL_T_H_ */
|
||||
24
firmware/devices/config.c
Normal file
24
firmware/devices/config.c
Normal file
@@ -0,0 +1,24 @@
|
||||
/**** Includes ****/
|
||||
#include "hal/udccd_hal.h"
|
||||
#include "config.h"
|
||||
|
||||
/**** Public function definitions ****/
|
||||
void Init_HW(void)
|
||||
{
|
||||
hwConfig_t hwCfg;
|
||||
hwCfg.adc_clk_prescaler = ADC_DIV2;
|
||||
hwCfg.adc_auto_wake = 1;
|
||||
// 64kHz PWM
|
||||
hwCfg.pwm_timer_prescaler = TIM_DIV1;
|
||||
hwCfg.pwm_timer_top = 0x01FF;
|
||||
// 1.9Hz..62.5kHz Speed input
|
||||
hwCfg.freq_timer_prescaler = TIM_DIV64;
|
||||
// 1kHz systick
|
||||
hwCfg.systick_timer_top = 125;
|
||||
hwCfg.systick_timer_prescaler = TIM_DIV64;
|
||||
// No extra features
|
||||
hwCfg.uart_prescaler = 0;
|
||||
hwCfg.disable_unused = 0;
|
||||
hwCfg.en_watchdog = 0;
|
||||
HAL_Init_Min(&hwCfg);
|
||||
}
|
||||
10
firmware/devices/config.h
Normal file
10
firmware/devices/config.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef CONFIG_H_
|
||||
#define CONFIG_H_
|
||||
|
||||
/**** Includes ****/
|
||||
#include <stdint.h>
|
||||
|
||||
/**** Public function declarations ****/
|
||||
void Init_HW(void);
|
||||
|
||||
#endif /* CONFIG_H_ */
|
||||
21
firmware/devices/filter_iir_lpf.c
Normal file
21
firmware/devices/filter_iir_lpf.c
Normal file
@@ -0,0 +1,21 @@
|
||||
/**** Includes ****/
|
||||
#include "filter_iir_lpf.h"
|
||||
|
||||
/**** Private variables ****/
|
||||
|
||||
/**** Public function definitions ****/
|
||||
uint16_t LPF_Update(uint16_t new, uint16_t last, uint8_t strength)
|
||||
{
|
||||
if(strength==0) return new;
|
||||
else if(strength==255) return last;
|
||||
else
|
||||
{
|
||||
uint32_t temp = (uint32_t)last * strength;
|
||||
temp += new * (255-strength);
|
||||
temp /= 255;
|
||||
|
||||
//Limit to 16bits
|
||||
if(temp > 0x0000FFFF) return 0xFFFF;
|
||||
else return (uint16_t) temp;
|
||||
}
|
||||
}
|
||||
10
firmware/devices/filter_iir_lpf.h
Normal file
10
firmware/devices/filter_iir_lpf.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef FILTER_IIR_LPF_H_
|
||||
#define FILTER_IIR_LPF_H_
|
||||
|
||||
/**** Includes ****/
|
||||
#include <stdint.h>
|
||||
|
||||
/**** Public function declarations ****/
|
||||
uint16_t LPF_Update(uint16_t new, uint16_t last, uint8_t strength);
|
||||
|
||||
#endif /* FILTER_IIR_LPF_H_ */
|
||||
102
firmware/devices/hal/udccd_hal.h
Normal file
102
firmware/devices/hal/udccd_hal.h
Normal file
@@ -0,0 +1,102 @@
|
||||
#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_ */
|
||||
463
firmware/devices/hal/udccd_r7_hal.c
Normal file
463
firmware/devices/hal/udccd_r7_hal.c
Normal file
@@ -0,0 +1,463 @@
|
||||
/**** 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;
|
||||
}
|
||||
}
|
||||
127
firmware/devices/halfbridge.c
Normal file
127
firmware/devices/halfbridge.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/**** Includes ****/
|
||||
#include "hal/udccd_hal.h"
|
||||
#include "halfbridge.h"
|
||||
|
||||
/**** Private variables ****/
|
||||
static const uint16_t min_dc = 3277; //5%
|
||||
static const uint16_t max_dc = 62258; //95%
|
||||
|
||||
static uint16_t target = 0;
|
||||
static uint8_t low_side_on = 1;
|
||||
|
||||
static uint16_t active_dc = 0;
|
||||
|
||||
static uint8_t is_en = 0;
|
||||
|
||||
/**** Private function declarations ****/
|
||||
static uint16_t CalculateDuty16b(uint16_t target, uint16_t supply);
|
||||
|
||||
/**** Public function definitions ****/
|
||||
void HB_SetTarget(uint16_t voltage)
|
||||
{
|
||||
target = voltage;
|
||||
}
|
||||
|
||||
void HB_SetLowSide(uint8_t on)
|
||||
{
|
||||
low_side_on = on;
|
||||
}
|
||||
|
||||
uint16_t HB_GetTarget(void)
|
||||
{
|
||||
return target;
|
||||
}
|
||||
|
||||
void HB_UpdateOutput(uint16_t supply)
|
||||
{
|
||||
uint16_t temp_dc = CalculateDuty16b(target, supply);
|
||||
|
||||
HB_SetDirect(temp_dc);
|
||||
}
|
||||
|
||||
void HB_SetDirect(uint16_t duty)
|
||||
{
|
||||
/// Limit duty cycle
|
||||
if(duty > max_dc) active_dc = max_dc;
|
||||
else if(duty < min_dc) active_dc = 0;
|
||||
else active_dc = duty;
|
||||
|
||||
// Set duty cycle
|
||||
if(!is_en) return;
|
||||
HAL_Coil_SetLowSide(low_side_on);
|
||||
HAL_Coil_SetPWM16b(active_dc);
|
||||
}
|
||||
|
||||
uint8_t HB_IsLowOn(void)
|
||||
{
|
||||
if(HAL_ReadLvl_CoilLow() == HIGH) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
void HB_Enable(void)
|
||||
{
|
||||
// Restore low side
|
||||
if(low_side_on) HAL_Coil_SetLowSide(1);
|
||||
// Restore duty cycle
|
||||
HAL_Coil_SetPWM(active_dc);
|
||||
is_en = 1;
|
||||
}
|
||||
|
||||
void HB_Disable(void)
|
||||
{
|
||||
// Set 0 DC
|
||||
HAL_Coil_SetPWM(0);
|
||||
// Disable low side
|
||||
HAL_Coil_SetLowSide(0);
|
||||
is_en = 0;
|
||||
}
|
||||
|
||||
uint8_t HB_IsEnabled(void)
|
||||
{
|
||||
if(is_en) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
int8_t HB_IsOutputMatch(uint16_t fb_output_voltage, uint16_t limit)
|
||||
{
|
||||
// No fault if output not enabled
|
||||
if(!is_en) return -1;
|
||||
|
||||
// Can't check voltage if low side is off
|
||||
if(!low_side_on) return -1;
|
||||
|
||||
if(target==0)
|
||||
{
|
||||
// Output can be only 0
|
||||
if(fb_output_voltage != 0) return 0;
|
||||
else return 1;
|
||||
};
|
||||
|
||||
// Calculate upper and lower bounds
|
||||
uint16_t max = target + limit;
|
||||
uint16_t min = target - limit;
|
||||
|
||||
//Sanity check
|
||||
if(max < target) max = 0xFFFF;
|
||||
if(min > target) min = 0;
|
||||
|
||||
//Do check
|
||||
if((fb_output_voltage < min)||(fb_output_voltage > max)) return 0;
|
||||
else return 1;
|
||||
}
|
||||
|
||||
/**** Private function definitions ****/
|
||||
static uint16_t CalculateDuty16b(uint16_t target, uint16_t supply)
|
||||
{
|
||||
if(target==0) return 0;
|
||||
if(supply==0) return 0;
|
||||
if(target > supply) return 0xFFFF;
|
||||
|
||||
// Calculate Duty cycle, in 16bit format
|
||||
uint32_t temp = (uint32_t)target * 0x0000FFFF;
|
||||
temp = temp / supply;
|
||||
|
||||
//Limit output to 16 bits
|
||||
if(temp > 0x0000FFFF) return 0xFFFF;
|
||||
else return (uint16_t)temp;
|
||||
}
|
||||
24
firmware/devices/halfbridge.h
Normal file
24
firmware/devices/halfbridge.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef HALFBRIDGE_H_
|
||||
#define HALFBRIDGE_H_
|
||||
|
||||
/**** Includes ****/
|
||||
#include <stdint.h>
|
||||
|
||||
/**** Public function declarations ****/
|
||||
void HB_UpdateOutput(uint16_t supply);
|
||||
|
||||
void HB_SetTarget(uint16_t voltage);
|
||||
void HB_SetLowSide(uint8_t on);
|
||||
|
||||
void HB_SetDirect(uint16_t duty);
|
||||
|
||||
void HB_Enable(void);
|
||||
void HB_Disable(void);
|
||||
|
||||
uint16_t HB_GetTarget(void);
|
||||
|
||||
uint8_t HB_IsLowOn(void);
|
||||
uint8_t HB_IsEnabled(void);
|
||||
int8_t HB_IsOutputMatch(uint16_t fb_output_voltage, uint16_t limit);
|
||||
|
||||
#endif /* HALFBRIDGE_H_ */
|
||||
82
firmware/devices/inputs.c
Normal file
82
firmware/devices/inputs.c
Normal file
@@ -0,0 +1,82 @@
|
||||
/**** Includes ****/
|
||||
#include "hal/udccd_hal.h"
|
||||
#include "inputs.h"
|
||||
|
||||
/**** Private definitions ****/
|
||||
|
||||
/**** Private variables ****/
|
||||
static const uint8_t def_debounce_lim = 10;
|
||||
|
||||
/**** Private function declarations ****/
|
||||
static void InitDefaultInput(inCh_t* inp);
|
||||
static void ProcessInput(uint8_t read_lvl, inCh_t* inp);
|
||||
|
||||
/**** Public function definitions ****/
|
||||
void Inputs_DefInit(inputs_t* inputs)
|
||||
{
|
||||
InitDefaultInput(&inputs->handbrake);
|
||||
InitDefaultInput(&inputs->brakes);
|
||||
InitDefaultInput(&inputs->dimm);
|
||||
InitDefaultInput(&inputs->up);
|
||||
InitDefaultInput(&inputs->down);
|
||||
InitDefaultInput(&inputs->mode);
|
||||
}
|
||||
|
||||
void Inputs_UpdateAll(inputs_t* inputs)
|
||||
{
|
||||
// Chassis inputs
|
||||
ProcessInput(HAL_ReadLvl_Handbrake(), &inputs->handbrake);
|
||||
ProcessInput(HAL_ReadLvl_Brake(), &inputs->brakes);
|
||||
ProcessInput(HAL_ReadLvl_Dimm(), &inputs->dimm);
|
||||
|
||||
// User inputs
|
||||
ProcessInput(HAL_ReadLvl_BtnUp(), &inputs->up);
|
||||
ProcessInput(HAL_ReadLvl_BtnDown(), &inputs->down);
|
||||
ProcessInput(HAL_ReadLvl_BtnMode(), &inputs->mode);
|
||||
}
|
||||
|
||||
void Inputs_SetHanbrakePullUp(uint8_t on)
|
||||
{
|
||||
if(on) HAL_SetPull_Handbrake(HIGH);
|
||||
else HAL_SetPull_Handbrake(HIZ);
|
||||
}
|
||||
|
||||
/**** Private function definitions ****/
|
||||
static void InitDefaultInput(inCh_t* inp)
|
||||
{
|
||||
inp->is_active = 0;
|
||||
inp->is_new = 0;
|
||||
inp->state_timer = 0;
|
||||
inp->cfg.act_level = LOW;
|
||||
inp->cfg.dbnc_treshold = def_debounce_lim;
|
||||
inp->proc.level = LOW;
|
||||
inp->proc.dbnc_counter = 0;
|
||||
}
|
||||
|
||||
static void ProcessInput(uint8_t read_lvl, inCh_t* inp)
|
||||
{
|
||||
if(inp->state_timer < 0xFFFF) inp->state_timer++;
|
||||
|
||||
if(read_lvl != inp->proc.level)
|
||||
{
|
||||
//Debounce ongoing
|
||||
inp->proc.dbnc_counter++;
|
||||
if(inp->proc.dbnc_counter < inp->cfg.dbnc_treshold) return;
|
||||
|
||||
//Save level
|
||||
inp->proc.level = read_lvl;
|
||||
//Change state
|
||||
if(inp->proc.level == inp->cfg.act_level) inp->is_active = 1;
|
||||
else inp->is_active = 0;
|
||||
// Update new flag
|
||||
inp->is_new = 1;
|
||||
// Reset state timer
|
||||
inp->state_timer = 0;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Debounce failed
|
||||
if(inp->proc.dbnc_counter) inp->proc.dbnc_counter = 0;
|
||||
}
|
||||
}
|
||||
43
firmware/devices/inputs.h
Normal file
43
firmware/devices/inputs.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef INPUTS_H_
|
||||
#define INPUTS_H_
|
||||
|
||||
/**** Includes ****/
|
||||
#include <stdint.h>
|
||||
#include "common/level.h"
|
||||
|
||||
/**** Public definitions ****/
|
||||
typedef struct {
|
||||
level_t act_level;
|
||||
uint8_t dbnc_treshold;
|
||||
} inChCfg_t;
|
||||
|
||||
typedef struct {
|
||||
level_t level;
|
||||
uint8_t dbnc_counter;
|
||||
} inChRaw_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t is_active;
|
||||
uint8_t is_new;
|
||||
uint16_t state_timer;
|
||||
inChRaw_t proc;
|
||||
inChCfg_t cfg;
|
||||
} inCh_t;
|
||||
|
||||
typedef struct {
|
||||
inCh_t handbrake;
|
||||
inCh_t brakes;
|
||||
inCh_t dimm;
|
||||
inCh_t up;
|
||||
inCh_t down;
|
||||
inCh_t mode;
|
||||
} inputs_t;
|
||||
|
||||
/**** Public function declarations ****/
|
||||
void Inputs_DefInit(inputs_t* inputs);
|
||||
|
||||
void Inputs_UpdateAll(inputs_t* inputs);
|
||||
|
||||
void Inputs_SetHanbrakePullUp(uint8_t on);
|
||||
|
||||
#endif /* INPUTS_H_ */
|
||||
20
firmware/devices/led_display.c
Normal file
20
firmware/devices/led_display.c
Normal file
@@ -0,0 +1,20 @@
|
||||
/**** Includes ****/
|
||||
#include "hal/udccd_hal.h"
|
||||
#include "led_display.h"
|
||||
|
||||
/**** Private variables ****/
|
||||
|
||||
/**** Private function declarations ****/
|
||||
|
||||
/**** Public function definitions ****/
|
||||
void LED_DSP_ShowImage(uint8_t image)
|
||||
{
|
||||
HAL_LEDS_Set(image);
|
||||
}
|
||||
|
||||
void LED_DSP_SetBrightness(uint8_t percent)
|
||||
{
|
||||
HAL_LEDS_SetPWM(percent);
|
||||
}
|
||||
|
||||
/**** Private function definitions ****/
|
||||
13
firmware/devices/led_display.h
Normal file
13
firmware/devices/led_display.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef LED_DISPLAY_H_
|
||||
#define LED_DISPLAY_H_
|
||||
|
||||
/**** Includes ****/
|
||||
#include <stdint.h>
|
||||
|
||||
/**** Public definitions ****/
|
||||
|
||||
/**** Public function declarations ****/
|
||||
void LED_DSP_ShowImage(uint8_t image);
|
||||
void LED_DSP_SetBrightness(uint8_t percent);
|
||||
|
||||
#endif /* LED_DISPLAY_H_ */
|
||||
34
firmware/devices/memory.c
Normal file
34
firmware/devices/memory.c
Normal file
@@ -0,0 +1,34 @@
|
||||
/**** Includes ****/
|
||||
#include <avr/eeprom.h>
|
||||
#include "memory.h"
|
||||
|
||||
/**** Public function definitions ****/
|
||||
uint8_t MEM_Read8b(uint8_t address)
|
||||
{
|
||||
return eeprom_read_byte((uint8_t*)address);
|
||||
}
|
||||
|
||||
uint16_t MEM_Read16b(uint8_t address)
|
||||
{
|
||||
return eeprom_read_word((uint8_t*)address);
|
||||
}
|
||||
|
||||
uint32_t MEM_Read32b(uint8_t address)
|
||||
{
|
||||
return eeprom_read_dword((uint8_t*)address);
|
||||
}
|
||||
|
||||
void MEM_Write8b(uint8_t address, uint8_t value)
|
||||
{
|
||||
return eeprom_write_byte((uint8_t*)address, value);
|
||||
}
|
||||
|
||||
void MEM_Write16b(uint8_t address, uint16_t value)
|
||||
{
|
||||
return eeprom_write_word((uint8_t*)address, value);
|
||||
}
|
||||
|
||||
void MEM_Write32b(uint8_t address, uint32_t value)
|
||||
{
|
||||
return eeprom_write_dword((uint8_t*)address, value);
|
||||
}
|
||||
16
firmware/devices/memory.h
Normal file
16
firmware/devices/memory.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef MEMORY_H_
|
||||
#define MEMORY_H_
|
||||
|
||||
/**** Includes ****/
|
||||
#include <stdint.h>
|
||||
|
||||
/**** Public function declarations ****/
|
||||
uint8_t MEM_Read8b(uint8_t address);
|
||||
uint16_t MEM_Read16b(uint8_t address);
|
||||
uint32_t MEM_Read32b(uint8_t address);
|
||||
|
||||
void MEM_Write8b(uint8_t address, uint8_t value);
|
||||
void MEM_Write16b(uint8_t address, uint16_t value);
|
||||
void MEM_Write32b(uint8_t address, uint32_t value);
|
||||
|
||||
#endif /* MEMORY_H_ */
|
||||
Reference in New Issue
Block a user