1
// thefreeman's Linear 16 driver using DAC control
2
// Copyright (C) 2021-2023 thefreeman, Selene ToyKeeper
3
// SPDX-License-Identifier: GPL-3.0-or-later
7
* PA6 - DAC for LED brightness control
8
* PA7 - Op-amp enable pin
10
* PB4 - Switch pin, internal pullup
11
* PB3 - HDR control, set High to enable the high power channel, set Low for low power
12
* Read voltage from VCC pin, has PFET so no drop
18
#define HWDEF_C_FILE hwdef-thefreeman-lin16dac.c
20
// allow using aux LEDs as extra channel modes
26
#define NUM_CHANNEL_MODES 2
32
#define DEFAULT_CHANNEL_MODE CM_MAIN
34
// right-most bit first, modes are in fedcba9876543210 order
35
#define CHANNEL_MODES_ENABLED 0b0000000000000001
38
#define PWM_CHANNELS 1 // old, remove this
40
#define PWM_BITS 8 // 8-bit DAC
41
#define PWM_GET PWM_GET8
42
#define PWM_DATATYPE uint8_t
43
#define PWM_DATATYPE2 uint16_t // only needs 32-bit if ramp values go over 255
44
#define PWM1_DATATYPE uint8_t // main LED ramp
47
#define DAC_LVL DAC0.DATA // 0 to 255, for 0V to Vref
48
#define DAC_VREF VREF.CTRLA // 0.55V or 2.5V
49
#define PWM_TOP_INIT 255 // highest value used in top half of ramp (unused?)
58
// For turning on and off the op-amp
59
#define OPAMP_ENABLE_PIN PIN7_bp
60
#define OPAMP_ENABLE_PORT PORTA_OUT
61
// how many ms to delay turning on the lights after enabling the channel
62
// (FIXME: 80 is long enough it's likely to cause bugs elsewhere,
63
// as events stack up unhandled for 5 consecutive WDT ticks)
64
#define OPAMP_ON_DELAY 80
67
// turns on HDR FET for the high current range
68
#define HDR_ENABLE_PIN PIN3_bp
69
#define HDR_ENABLE_PORT PORTB_OUT
72
#define SWITCH_PIN PIN4_bp
73
#define SWITCH_PORT VPORTB.IN
74
#define SWITCH_ISC_REG PORTB.PIN2CTRL
75
#define SWITCH_VECT PORTB_PORT_vect
76
#define SWITCH_INTFLG VPORTB.INTFLAGS
78
// average drop across diode on this hardware
79
#ifndef VOLTAGE_FUDGE_FACTOR
80
#define VOLTAGE_FUDGE_FACTOR 0 // using a PFET so no appreciable drop
84
#define AUXLED_PIN PIN5_bp
85
#define AUXLED_PORT PORTB
88
inline void hwdef_setup() {
90
// set up the system clock to run at 10 MHz instead of the default 3.33 MHz
91
// (it'll get underclocked to 2.5 MHz later)
92
// TODO: maybe run even slower?
93
_PROTECTED_WRITE( CLKCTRL.MCLKCTRLB,
94
CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm );
96
VPORTA.DIR = PIN6_bm // DAC
98
VPORTB.DIR = PIN3_bm; // HDR
99
//VPORTC.DIR = 0b00000000;
101
// enable pullups on the input pins to reduce power
102
PORTA.PIN0CTRL = PORT_PULLUPEN_bm;
103
PORTA.PIN1CTRL = PORT_PULLUPEN_bm;
104
PORTA.PIN2CTRL = PORT_PULLUPEN_bm;
105
PORTA.PIN3CTRL = PORT_PULLUPEN_bm;
106
PORTA.PIN4CTRL = PORT_PULLUPEN_bm;
107
PORTA.PIN5CTRL = PORT_PULLUPEN_bm;
108
//PORTA.PIN6CTRL = PORT_PULLUPEN_bm; // DAC ouput
109
//PORTA.PIN7CTRL = PORT_PULLUPEN_bm; // Op-amp enable pin
111
PORTB.PIN0CTRL = PORT_PULLUPEN_bm;
112
PORTB.PIN1CTRL = PORT_PULLUPEN_bm;
113
PORTB.PIN2CTRL = PORT_PULLUPEN_bm;
114
//PORTB.PIN3CTRL = PORT_PULLUPEN_bm; // HDR channel selection
115
PORTB.PIN4CTRL = PORT_PULLUPEN_bm
116
| PORT_ISC_BOTHEDGES_gc; // e-switch
117
//PORTB.PIN5CTRL = PORT_PULLUPEN_bm; // Aux LED
119
PORTC.PIN0CTRL = PORT_PULLUPEN_bm;
120
PORTC.PIN1CTRL = PORT_PULLUPEN_bm;
121
PORTC.PIN2CTRL = PORT_PULLUPEN_bm;
122
PORTC.PIN3CTRL = PORT_PULLUPEN_bm;
125
// https://ww1.microchip.com/downloads/en/DeviceDoc/ATtiny1614-16-17-DataSheet-DS40002204A.pdf
126
// DAC ranges from 0V to (255 * Vref) / 256
127
// also VREF_DAC0REFSEL_0V55_gc and VREF_DAC0REFSEL_1V1_gc and VREF_DAC0REFSEL_2V5_gc
128
VREF.CTRLA |= VREF_DAC0REFSEL_2V5_gc;
129
VREF.CTRLB |= VREF_DAC0REFEN_bm;
130
DAC0.CTRLA = DAC_ENABLE_bm | DAC_OUTEN_bm;
131
DAC0.DATA = 255; // set the output voltage
136
#define LAYOUT_DEFINED