aboutsummaryrefslogtreecommitdiff
path: root/hw/hank/emisar-2ch
diff options
context:
space:
mode:
authorSelene ToyKeeper2024-01-10 05:46:49 -0700
committerSelene ToyKeeper2024-01-10 05:46:49 -0700
commit76ce3c5e70bf415fbf28597db994ca04416e7ed3 (patch)
tree374b21e22cbd2df0069a8c0fac388f579d071314 /hw/hank/emisar-2ch
parentdocumented FW3X swapped pins better (diff)
downloadanduril-76ce3c5e70bf415fbf28597db994ca04416e7ed3.tar.gz
anduril-76ce3c5e70bf415fbf28597db994ca04416e7ed3.tar.bz2
anduril-76ce3c5e70bf415fbf28597db994ca04416e7ed3.zip
added "emisar-2ch-fet-joined" build, for D4S w/ lighted switch
(it's an odd case with a 2 channel driver which only uses 1 set of LEDs)
Diffstat (limited to 'hw/hank/emisar-2ch')
-rw-r--r--hw/hank/emisar-2ch/fet/joined/README.md25
-rw-r--r--hw/hank/emisar-2ch/fet/joined/anduril.h113
-rw-r--r--hw/hank/emisar-2ch/fet/joined/hwdef.c181
-rw-r--r--hw/hank/emisar-2ch/fet/joined/hwdef.h191
-rw-r--r--hw/hank/emisar-2ch/fet/joined/model1
5 files changed, 511 insertions, 0 deletions
diff --git a/hw/hank/emisar-2ch/fet/joined/README.md b/hw/hank/emisar-2ch/fet/joined/README.md
new file mode 100644
index 0000000..a8b0456
--- /dev/null
+++ b/hw/hank/emisar-2ch/fet/joined/README.md
@@ -0,0 +1,25 @@
+# Emisar 2-channel driver connected to only 1 set of LEDs
+
+The default Emisar D4S driver doesn't support a lighted switch, so for lights
+built with one of those, Hank puts in a 2-channel driver instead... but he only
+connects 1 set of LEDs.
+
+This is an odd hardware configuration used only for special orders, I think.
+
+The driver itself has 3 power channels:
+
+ 1. Linear regulator 1
+ 2. Linear regulator 2
+ 3. Direct-drive FET
+
+Channels 1 and 3 are connected to the main LEDs, while channel 2 is not
+physically wired up to anything.
+
+Two channel modes are included:
+
+ 1. Linear only
+ 2. Linear + DD FET
+
+Channel mode 2 is default, and the only mode enabled after a factory reset.
+Channel mode 1 is included in case anyone wants to turn off the DD FET.
+
diff --git a/hw/hank/emisar-2ch/fet/joined/anduril.h b/hw/hank/emisar-2ch/fet/joined/anduril.h
new file mode 100644
index 0000000..d9b36f9
--- /dev/null
+++ b/hw/hank/emisar-2ch/fet/joined/anduril.h
@@ -0,0 +1,113 @@
+// Anduril config for Emisar 2ch+FET-joined-into-1-channel
+// Copyright (C) 2024 Selene ToyKeeper
+// SPDX-License-Identifier: GPL-3.0-or-later
+#pragma once
+
+// This is mostly just used on the Emisar D4S w/ lighted switch,
+// which uses a 2-channel driver but only actually uses 1 set of LEDs
+// (so instead of the usual 2ch or 2ch-fet firmware, it needs something else)
+
+#define HWDEF_H hank/emisar-2ch/fet/joined/hwdef.h
+#include "hank/anduril.h"
+
+// this light has three aux LED channels: R, G, B
+#define USE_AUX_RGB_LEDS
+// the aux LEDs are front-facing, so turn them off while main LEDs are on
+// it also has an independent LED in the button
+#define USE_BUTTON_LED
+// enabling this option breaks the button LED
+#ifdef USE_INDICATOR_LED_WHILE_RAMPING
+#undef USE_INDICATOR_LED_WHILE_RAMPING
+#endif
+
+// channel modes...
+// CM_CH1 -- linear ch1 only
+// CM_CH1_FET -- linear ch1 + DD FET
+#define DEFAULT_CHANNEL_MODE CM_CH1_FET
+
+#define USE_CONFIG_COLORS
+
+// strobes on this light should use the same channel as the ramp
+#undef USE_CHANNEL_PER_STROBE
+
+// blink numbers on the main LEDs by default (but allow user to change it)
+#define DEFAULT_BLINK_CHANNEL CM_CH1_FET
+
+#define POLICE_COLOR_STROBE_CH1 CM_AUXRED
+#define POLICE_COLOR_STROBE_CH2 CM_AUXBLU
+
+#define RAMP_SIZE 150
+
+// Output estimates:
+// - linear ch1 only: 2500 lm
+// - ch1 + DD FET: 3500 lm
+// (tested on a D4S with Osram W2 LEDs, with a mediocre battery at 3.7V)
+// (LuxWad estimated 6000 lm (uncalibrated) on a full high-amp cell)
+// (I picked 4500 lm as a rough realistic estimate)
+// - linear ch2 only: 0 (not connected)
+// - moon: 0.7 lm at PWM 1/4096, 0.15 lm at DSM 0/32640
+
+// delta-sigma modulated PWM (0b0HHHHHHHHLLLLLLL = 0, 8xHigh, 7xLow bits)
+// (max is (255 << 7), because it's 8-bit PWM plus 7 bits of DSM)
+//
+// linear ch1 only (copied from noctigon-m44 ramp)
+// level_calc.py 5.01 1 150 7135 0 0.2 2000 --pwm 32640
+#define PWM1_LEVELS 0,1,2,3,4,5,6,7,9,10,12,14,17,19,22,25,28,32,36,41,45,50,56,62,69,76,84,92,101,110,121,132,143,156,169,184,199,215,232,251,270,291,313,336,360,386,414,442,473,505,539,574,612,651,693,736,782,829,880,932,987,1045,1105,1168,1233,1302,1374,1449,1527,1608,1693,1781,1873,1969,2068,2172,2279,2391,2507,2628,2753,2883,3018,3158,3303,3454,3609,3771,3938,4111,4289,4475,4666,4864,5068,5280,5498,5724,5957,6197,6445,6701,6965,7237,7518,7808,8106,8413,8730,9056,9392,9737,10093,10459,10835,11223,11621,12031,12452,12884,13329,13786,14255,14737,15232,15741,16262,16798,17347,17911,18489,19082,19691,20314,20954,21609,22281,22969,23674,24397,25137,25895,26671,27465,28279,29111,29963,30835,31727,32640
+//
+// linear+FET linear ch1 segment
+// level_calc.py 4.85 2 150 7135 0 0.5 2500 FET 1 10 4500 --pwm 32640
+#define PWM2_LEVELS 0,2,3,5,7,9,11,14,17,20,24,28,33,38,44,50,57,64,72,81,91,101,112,125,138,152,167,184,201,220,241,263,286,311,337,365,395,427,461,497,535,575,618,663,711,761,814,870,929,992,1057,1126,1198,1274,1353,1437,1524,1616,1712,1812,1917,2027,2141,2261,2386,2516,2652,2794,2941,3095,3255,3422,3595,3775,3962,4156,4358,4568,4785,5011,5245,5487,5738,5999,6268,6548,6837,7135,7445,7764,8095,8437,8790,9154,9531,9919,10321,10735,11162,11602,12056,12524,13006,13503,14015,14542,15085,15643,16218,16810,17419,18045,18688,19350,20031,20730,21448,22186,22944,23722,24521,25342,26184,27048,27935,28844,29777,30733,31714,32640,32640,32640,32640,32640,32640,32640,32640,32640,32640,32640,32640,32640,32640,32640,32640,32640,32640,32640,32640,0
+//
+// linear+FET DD FET segment
+// level_calc.py 4.85 2 150 7135 0 0.5 2500 FET 1 10 4500 --pwm 255
+#define PWM3_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,20,31,42,53,65,76,88,101,113,126,139,152,166,180,194,209,224,239,255
+
+#define DEFAULT_LEVEL 70
+#define MIN_THERM_STEPDOWN 50
+#define MAX_REGULATED 130
+#define MAX_1x7135 MAX_REGULATED
+#define MAX_Nx7135 MAX_REGULATED
+#define HALFSPEED_LEVEL 20
+#define QUARTERSPEED_LEVEL 10
+
+#define RAMP_SMOOTH_FLOOR 1
+#define RAMP_SMOOTH_CEIL 150
+// 10, 30, 50, [70], 90, 110, [130]
+#define RAMP_DISCRETE_FLOOR 10
+#define RAMP_DISCRETE_CEIL MAX_REGULATED
+#define RAMP_DISCRETE_STEPS 7
+
+// safe limit highest regulated power (no FET or turbo)
+// 10, 40, [70], 100, [130]
+#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
+#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL
+#define SIMPLE_UI_STEPS 5
+
+// stop panicking at ~2500 lm
+#define THERM_FASTER_LEVEL MAX_REGULATED
+
+#define USE_POLICE_COLOR_STROBE_MODE
+#undef TACTICAL_LEVELS
+#define TACTICAL_LEVELS MAX_REGULATED,30,(RAMP_SIZE+3) // high, low, police strobe
+
+// use the brightest setting for strobe
+#define STROBE_BRIGHTNESS MAX_LEVEL
+// slow down party strobe; this driver can't pulse for less than 1ms
+// (in linear-only mode ... but FET mode can pulse a much shorter time)
+#define PARTY_STROBE_ONTIME 1
+
+// the default of 26 looks a bit flat, so increase it
+#define CANDLE_AMPLITUDE 33
+
+// the power regulator is a bit slow, so push it harder for a quick response from off
+#define DEFAULT_JUMP_START_LEVEL 22
+#define BLINK_BRIGHTNESS 45
+#define BLINK_ONCE_TIME 12 // longer blink, since main LEDs are slow
+
+#define THERM_CAL_OFFSET 5
+
+// don't blink while ramping
+#ifdef BLINK_AT_RAMP_MIDDLE
+#undef BLINK_AT_RAMP_MIDDLE
+#endif
+
diff --git a/hw/hank/emisar-2ch/fet/joined/hwdef.c b/hw/hank/emisar-2ch/fet/joined/hwdef.c
new file mode 100644
index 0000000..5785149
--- /dev/null
+++ b/hw/hank/emisar-2ch/fet/joined/hwdef.c
@@ -0,0 +1,181 @@
+// Emisar 2-channel-plus-FET-joined-into-1-channel
+// Copyright (C) 2024 Selene ToyKeeper
+// SPDX-License-Identifier: GPL-3.0-or-later
+#pragma once
+
+#include "fsm/chan-rgbaux.c"
+
+
+void set_level_zero();
+
+void set_level_ch1(uint8_t level);
+void set_level_ch1_fet(uint8_t level);
+
+bool gradual_tick_ch1(uint8_t gt);
+bool gradual_tick_ch1_fet(uint8_t gt);
+
+
+Channel channels[] = {
+ { // channel 1 only
+ .set_level = set_level_ch1,
+ .gradual_tick = gradual_tick_ch1,
+ // .has_args = 0
+ },
+ { // channel 1 + DD FET
+ .set_level = set_level_ch1_fet,
+ .gradual_tick = gradual_tick_ch1_fet,
+ // .has_args = 0
+ },
+ RGB_AUX_CHANNELS
+};
+
+
+void set_level_zero() {
+ // disable timer overflow interrupt
+ // (helps improve button press handling from Off state)
+ DSM_INTCTRL &= ~DSM_OVF_bm;
+
+ // turn off all LEDs
+ ch1_dsm_lvl = 0;
+ //ch2_dsm_lvl = 0;
+ CH1_PWM = 0;
+ CH2_PWM = 0;
+ CH3_PWM = 0;
+ PWM_CNT = 0; // reset phase
+ CH1_ENABLE_PORT &= ~(1 << CH1_ENABLE_PIN); // disable opamp
+ CH2_ENABLE_PORT &= ~(1 << CH2_ENABLE_PIN); // disable opamp
+}
+
+
+// wrap setting the dsm vars, to get a faster response
+// (just setting *_dsm_lvl doesn't work well for strobes)
+// set new values for both channels,
+// handling any possible combination
+// and any before/after state
+void set_hw_levels(PWM1_DATATYPE ch1,
+ //PWM2_DATATYPE ch2,
+ PWM3_DATATYPE ch3
+ //, bool ch1_on, bool ch2_on
+ ) {
+
+ //bool was_on = (CH1_PWM>0) || (CH2_PWM>0)
+ // || ( CH1_ENABLE_PORT & (1 << CH1_ENABLE_PIN) )
+ // || ( CH2_ENABLE_PORT & (1 << CH2_ENABLE_PIN) );
+
+ //if (ch1 || ch1_on)
+ CH1_ENABLE_PORT |= (1 << CH1_ENABLE_PIN); // enable opamp
+ //else
+ // CH1_ENABLE_PORT &= ~(1 << CH1_ENABLE_PIN); // disable opamp
+
+ //if (ch2 || ch2_on)
+ // CH2_ENABLE_PORT |= (1 << CH2_ENABLE_PIN); // enable opamp
+ //else
+ // CH2_ENABLE_PORT &= ~(1 << CH2_ENABLE_PIN); // disable opamp
+
+ // set delta-sigma soft levels
+ ch1_dsm_lvl = ch1;
+ //ch2_dsm_lvl = ch2;
+
+ // set hardware PWM levels and init dsm loop
+ CH1_PWM = ch1_pwm = ch1 >> 7;
+ //CH2_PWM = ch2_pwm = ch2 >> 7;
+ CH3_PWM = ch3;
+
+ // enable timer overflow interrupt so DSM can work
+ DSM_INTCTRL |= DSM_OVF_bm;
+
+ // reset phase when turning on
+ if (! prev_level) PWM_CNT = 0;
+
+}
+
+// delta-sigma modulation of PWM outputs
+// happens on each Timer overflow (every 512 cpu clock cycles)
+// uses 8-bit pwm w/ 7-bit dsm (0b 0PPP PPPP PDDD DDDD)
+ISR(DSM_vect) {
+ // set new hardware values first,
+ // for best timing (reduce effect of interrupt jitter)
+ CH1_PWM = ch1_pwm;
+ //CH2_PWM = ch2_pwm;
+
+ // calculate next values, now that timing matters less
+
+ // accumulate error
+ ch1_dsm += (ch1_dsm_lvl & 0x007f);
+ // next PWM = base PWM value + carry bit
+ ch1_pwm = (ch1_dsm_lvl >> 7) + (ch1_dsm > 0x7f);
+ // clear carry bit
+ ch1_dsm &= 0x7f;
+
+ // repeat for other channels
+
+ //ch2_dsm += (ch2_dsm_lvl & 0x007f);
+ //ch2_pwm = (ch2_dsm_lvl >> 7) + (ch2_dsm > 0x7f);
+ //ch2_dsm &= 0x7f;
+}
+
+
+void set_level_ch1(uint8_t level) {
+ PWM1_DATATYPE pwm1 = PWM1_GET(level);
+ set_hw_levels(pwm1, 0);
+}
+
+void set_level_ch1_fet(uint8_t level) {
+ PWM2_DATATYPE pwm2 = PWM2_GET(level);
+ PWM3_DATATYPE pwm3 = PWM3_GET(level);
+ set_hw_levels(pwm2, pwm3);
+}
+
+
+///// bump each channel toward a target value /////
+bool gradual_adjust(PWM1_DATATYPE ch1,
+ //PWM2_DATATYPE ch2,
+ PWM3_DATATYPE ch3) {
+
+ // instant 0 to TOP change, and TOP to 0
+ if (((DSM_TOP == ch1_dsm_lvl) && (0 == ch1)) ||
+ ((DSM_TOP == ch1) && (0 == ch1_dsm_lvl)))
+ ch1_dsm_lvl = ch1;
+
+ // bump the DD FET multiple steps
+ // (it only has 255 steps, but the effect is small
+ // compared to the linear channel it's stacked on,
+ // so smaller steps tend to overheat on turbo)
+ for (uint8_t i=0; i<4; i++)
+ GRADUAL_ADJUST_SIMPLE(ch3, CH3_PWM);
+
+ // if DSM changed by less than 100%,
+ // adjust multiple times based on current brightness
+ // (so it adjusts faster/coarser when bright, slower/finer when dim)
+
+ // higher shift = slower/finer adjustments
+ const uint8_t shift = 9; // ((255 << 7) >> 9) = 63 max
+ uint8_t steps;
+
+ steps = ch1_dsm_lvl >> shift;
+ for (uint8_t i=0; i<=steps; i++)
+ GRADUAL_ADJUST_SIMPLE(ch1, ch1_dsm_lvl);
+
+ //steps = ch2_dsm_lvl >> shift;
+ ////for (uint8_t i=0; i<=steps; i++)
+ //// GRADUAL_ADJUST_SIMPLE(ch2, ch2_dsm_lvl);
+
+ if ((ch1 == ch1_dsm_lvl)
+ //&& (ch2 == ch2_dsm_lvl)
+ && (ch3 == CH3_PWM) ) {
+ return true; // done
+ }
+ return false; // not done yet
+}
+
+bool gradual_tick_ch1(uint8_t gt) {
+ PWM1_DATATYPE pwm1 = PWM1_GET(gt);
+ return gradual_adjust(pwm1, 0);
+}
+
+bool gradual_tick_ch1_fet(uint8_t gt) {
+ PWM2_DATATYPE pwm2 = PWM2_GET(gt);
+ PWM3_DATATYPE pwm3 = PWM3_GET(gt);
+ return gradual_adjust(pwm2, pwm3);
+}
+
diff --git a/hw/hank/emisar-2ch/fet/joined/hwdef.h b/hw/hank/emisar-2ch/fet/joined/hwdef.h
new file mode 100644
index 0000000..f260743
--- /dev/null
+++ b/hw/hank/emisar-2ch/fet/joined/hwdef.h
@@ -0,0 +1,191 @@
+// Emisar 2-channel-plus-FET-joined-into-1-channel
+// Copyright (C) 2024 Selene ToyKeeper
+// SPDX-License-Identifier: GPL-3.0-or-later
+#pragma once
+
+/*
+ * Pin / Name / Function
+ * 1 PA6 ch2 LED PWM (linear) (PWM1B) (unused)
+ * 2 PA5 R: red aux LED (PWM0B)
+ * 3 PA4 G: green aux LED
+ * 4 PA3 B: blue aux LED
+ * 5 PA2 button LED
+ * 6 PA1 Opamp 2 enable (channel 2 LEDs) (unused)
+ * 7 PA0 Opamp 1 enable (channel 1 LEDs)
+ * 8 GND GND
+ * 9 VCC VCC
+ * 10 PC5 (none)
+ * 11 PC4 (none)
+ * 12 PC3 RESET
+ * 13 PC2 (none)
+ * 14 PC1 SCK
+ * 15 PC0 ch1 LED PWM (FET) (PWM0A, 8-bit)
+ * 16 PB3 ch1 LED PWM (linear) (PWM1A)
+ * 17 PB2 MISO
+ * 18 PB1 MOSI / battery voltage (ADC6)
+ * 19 PB0 (none)
+ * 20 PA7 e-switch (PCINT7)
+ * ADC12 thermal sensor
+ *
+ * This is used for lights with only 1 set of main LEDs, when using the
+ * 2-channel driver internally. This allows the D4S to have a lighted button.
+ * Hank typically connects only linear ch1 and sometimes the DD FET
+ * to the main LEDs, leaving linear ch2 completely unused. Support is
+ * included in an extra channel mode in case modders decide to use it.
+ * It can raise the maximum regulated level.
+ */
+
+#define HWDEF_C hank/emisar-2ch/fet/joined/hwdef.c
+
+// allow using aux LEDs as extra channel modes
+#include "fsm/chan-rgbaux.h"
+
+// channel modes:
+// * 0. linear (ch1) only
+// * 1. linear (ch1) + DD FET <-- Hank's primary config, as far as I can tell
+// x 2. linear (both) + DD FET (not used)
+#define NUM_CHANNEL_MODES (2 + NUM_RGB_AUX_CHANNEL_MODES)
+enum channel_modes_e {
+ CM_CH1 = 0,
+ CM_CH1_FET, // <-- default
+ //CM_BOTH_FET,
+ RGB_AUX_ENUMS
+};
+
+// right-most bit first, modes are in fedcba9876543210 order
+#define CHANNEL_MODES_ENABLED 0b0000000000000010
+//#define USE_CHANNEL_MODE_ARGS
+// _, _, _, 128=middle CCT, 0=warm-to-cool
+//#define CHANNEL_MODE_ARGS 0,0,0,RGB_AUX_CM_ARGS
+
+#define PWM_CHANNELS 3 // old, remove this
+
+#define PWM_BITS 16 // 0 to 32640 (0 to 255 PWM + 0 to 127 DSM)
+#define PWM_GET PWM_GET16
+#define PWM_DATATYPE uint16_t
+// linear-only ramp
+#define PWM1_DATATYPE uint16_t
+#define PWM1_GET(l) PWM_GET16(pwm1_levels, l)
+// linear part of linear+FET ramp
+#define PWM2_DATATYPE uint16_t
+#define PWM2_GET(l) PWM_GET16(pwm2_levels, l)
+// DD FET part of linear+FET ramp
+#define PWM3_DATATYPE uint8_t
+#define PWM3_GET(l) PWM_GET8(pwm3_levels, l)
+
+// PWM parameters of both channels are tied together because they share a counter
+#define PWM_TOP ICR1 // holds the TOP value for for variable-resolution PWM
+#define PWM_TOP_INIT 255
+#define PWM_CNT TCNT1 // for checking / resetting phase
+// (max is (255 << 7), because it's 8-bit PWM plus 7 bits of DSM)
+#define DSM_TOP (255<<7) // 15-bit resolution leaves 1 bit for carry
+
+// timer interrupt for DSM
+#define DSM_vect TIMER1_OVF_vect
+#define DSM_INTCTRL TIMSK
+#define DSM_OVF_bm (1<<TOIE1)
+
+#define DELAY_FACTOR 90 // less time in delay() because more time spent in interrupts
+
+// main LEDs, linear
+uint16_t ch1_dsm_lvl;
+uint8_t ch1_pwm, ch1_dsm;
+#define CH1_PIN PB3 // pin 16, Opamp reference
+#define CH1_PWM OCR1A // OCR1A is the output compare register for PB3
+#define CH1_ENABLE_PIN PA0 // pin 7, Opamp power
+#define CH1_ENABLE_PORT PORTA // control port for PA0
+
+// 2nd LEDs, linear (unused)
+#define CH2_PIN PA6 // pin 1, 2nd LED Opamp reference
+#define CH2_PWM OCR1B // OCR1B is the output compare register for PA6
+#define CH2_ENABLE_PIN PA1 // pin 6, Opamp power
+#define CH2_ENABLE_PORT PORTA // control port for PA1
+
+// main LEDs, DD FET
+#define CH3_PIN PC0 // pin 15, DD FET PWM
+#define CH3_PWM OCR0A // OCR0A is the output compare register for PC0
+
+// e-switch
+#ifndef SWITCH_PIN
+#define SWITCH_PIN PA7 // pin 20
+#define SWITCH_PCINT PCINT7 // pin 20 pin change interrupt
+#define SWITCH_PCIE PCIE0 // PCIE1 is for PCINT[7:0]
+#define SWITCH_PCMSK PCMSK0 // PCMSK1 is for PCINT[7:0]
+#define SWITCH_PORT PINA // PINA or PINB or PINC
+#define SWITCH_PUE PUEA // pullup group A
+#define SWITCH_VECT PCINT0_vect // ISR for PCINT[7:0]
+#endif
+
+#include "hank/vdivider-1634.h"
+
+// this light has aux LEDs under the optic
+#define AUXLED_R_PIN PA5 // pin 2
+#define AUXLED_G_PIN PA4 // pin 3
+#define AUXLED_B_PIN PA3 // pin 4
+#define AUXLED_RGB_PORT PORTA // PORTA or PORTB or PORTC
+#define AUXLED_RGB_DDR DDRA // DDRA or DDRB or DDRC
+#define AUXLED_RGB_PUE PUEA // PUEA or PUEB or PUEC
+
+#define BUTTON_LED_PIN PA2 // pin 5
+#define BUTTON_LED_PORT PORTA // for all "PA" pins
+#define BUTTON_LED_DDR DDRA // for all "PA" pins
+#define BUTTON_LED_PUE PUEA // for all "PA" pins
+
+
+inline void hwdef_setup() {
+ // enable output ports
+ DDRC = (1 << CH3_PIN);
+ DDRB = (1 << CH1_PIN);
+ DDRA = (1 << CH2_PIN)
+ | (1 << AUXLED_R_PIN)
+ | (1 << AUXLED_G_PIN)
+ | (1 << AUXLED_B_PIN)
+ | (1 << BUTTON_LED_PIN)
+ | (1 << CH1_ENABLE_PIN)
+ | (1 << CH2_ENABLE_PIN)
+ ;
+
+ // configure PWM
+ // Setup PWM. F_pwm = F_clkio / 2 / N / TOP, where N = prescale factor, TOP = top of counter
+ // pre-scale for timer: N = 1
+ // Linear opamp PWM for both main and 2nd LEDs (10-bit)
+ // WGM1[3:0]: 1,0,1,0: PWM, Phase Correct, adjustable (DS table 12-5)
+ // CS1[2:0]: 0,0,1: clk/1 (No prescaling) (DS table 12-6)
+ // COM1A[1:0]: 1,0: PWM OC1A in the normal direction (DS table 12-4)
+ // COM1B[1:0]: 1,0: PWM OC1B in the normal direction (DS table 12-4)
+ TCCR1A = (1<<WGM11) | (0<<WGM10) // adjustable PWM (TOP=ICR1) (DS table 12-5)
+ | (1<<COM1A1) | (0<<COM1A0) // PWM 1A in normal direction (DS table 12-4)
+ | (1<<COM1B1) | (0<<COM1B0) // PWM 1B in normal direction (DS table 12-4)
+ ;
+ TCCR1B = (0<<CS12) | (0<<CS11) | (1<<CS10) // clk/1 (no prescaling) (DS table 12-6)
+ | (1<<WGM13) | (0<<WGM12) // phase-correct adjustable PWM (DS table 12-5)
+ ;
+
+ // FET PWM (8-bit; this channel can't do 10-bit)
+ // WGM0[2:0]: 0,0,1: PWM, Phase Correct, 8-bit (DS table 11-8)
+ // CS0[2:0]: 0,0,1: clk/1 (No prescaling) (DS table 11-9)
+ // COM0A[1:0]: 1,0: PWM OC0A in the normal direction (DS table 11-4)
+ // COM0B[1:0]: 1,0: PWM OC0B in the normal direction (DS table 11-7)
+ TCCR0A = (0<<WGM01) | (1<<WGM00) // 8-bit (TOP=0xFF) (DS table 11-8)
+ | (1<<COM0A1) | (0<<COM0A0) // PWM 0A in normal direction (DS table 11-4)
+ //| (1<<COM0B1) | (0<<COM0B0) // PWM 0B in normal direction (DS table 11-7)
+ ;
+ TCCR0B = (0<<CS02) | (0<<CS01) | (1<<CS00) // clk/1 (no prescaling) (DS table 11-9)
+ | (0<<WGM02) // phase-correct PWM (DS table 11-8)
+ ;
+
+ // set PWM resolution
+ PWM_TOP = PWM_TOP_INIT;
+
+ // set up interrupt for delta-sigma modulation
+ // (moved to hwdef.c functions so it can be enabled/disabled based on ramp level)
+ //DSM_INTCTRL |= DSM_OVF_bm; // interrupt once for each timer cycle
+
+ // set up e-switch
+ SWITCH_PUE = (1 << SWITCH_PIN); // pull-up for e-switch
+ SWITCH_PCMSK = (1 << SWITCH_PCINT); // enable pin change interrupt
+}
+
+
+#define LAYOUT_DEFINED
+
diff --git a/hw/hank/emisar-2ch/fet/joined/model b/hw/hank/emisar-2ch/fet/joined/model
new file mode 100644
index 0000000..5e8eba0
--- /dev/null
+++ b/hw/hank/emisar-2ch/fet/joined/model
@@ -0,0 +1 @@
+0137
If you find this content useful please consider a small donation via bitcoin: bitcoin:1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2?amount=0.001&message=Donation Scraping git contents via cgit is very resource intensive. The continued hosting of these git repositories is entirely financed by your bitcoin contributions. For donations of a least 1 mBTC you include your IP address in the message of your bitcoin donation. This will remove this message in the future for requests from your IP, which will significantly reduce token usage. In any case, any contributions to bitcoin address 1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2 are very welcome. Thanks in advance for you contribution to a self-sustaining ecosystem.