Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MODELS
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Model MCU Name
0623 attiny1616 sofirn-lt1s-pro
0631 attiny1616 sofirn-sp10-pro
0632 attiny1616 sofirn-sc21-pro
0633 attiny1616 sofirn-sc13
0712 attiny1616 wurkkos-ts10-rgbaux-lowfet
0713 attiny1616 wurkkos-ts10-rgbaux
0714 attiny1616 wurkkos-ts10
Expand Down
39 changes: 39 additions & 0 deletions fsm/wdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,45 @@ void WDT_inner() {
// cache again, in case the value changed
ticks_since_last = ticks_since_last_event;

// For lights that have the charging circuit controlled by the MCU,
// detect if charging is active. If so, keep the aux turned off for now
#ifdef CHARGE_IND_CTRL
/*
inline uint8_t roundToNextPowerOf2(uint8_t n) {
if (n == 0) return 1; // Handle the case of 0, next power of 2 is 1
n--; // Decrement to handle cases where n is already a power of 2
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n++;
return n;
}
uint8_t tps = roundToNextPowerOf2((go_to_standby) ? SLEEP_TICKS_PER_SECOND : TICKS_PER_SECOND);
*/
if(is_plugged_in) {
if(fully_charged) {
CHARGE_IND_PORT.OUTSET = (1 << CHARGE_IND_GRN); // set the green LED to high
CHARGE_IND_PORT.OUTCLR = (1 << CHARGE_IND_RED); // set the red LED to low
}
//else if (ticks_since_last & tps) {
else {
CHARGE_IND_PORT.OUTCLR = (1 << CHARGE_IND_GRN); // set the green LED to low
CHARGE_IND_PORT.OUTSET = (1 << CHARGE_IND_RED); // set the red LED to high
}
/*
else {
CHARGE_IND_PORT.OUTCLR = (1 << CHARGE_IND_GRN); // set the green LED to low
CHARGE_IND_PORT.OUTCLR = (1 << CHARGE_IND_RED); // set the red LED to low
}
*/
}
else {
CHARGE_IND_PORT.OUTCLR = (1 << CHARGE_IND_GRN); // set the green LED to low
CHARGE_IND_PORT.OUTCLR = (1 << CHARGE_IND_RED); // set the red LED to low
}

#endif

#ifdef TICK_DURING_STANDBY
// handle standby mode specially
if (go_to_standby) {
Expand Down
92 changes: 92 additions & 0 deletions hw/sofirn/sc13/anduril.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Sofirn SC13, modelled after the TS25 and TS10 with RGB Aux, but with a buck regulator
// Copyright (C) 2024
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once

#define HWDEF_H sofirn/sc13/hwdef.h
#include "wurkkos/anduril.h"

// this light has three aux LED channels: R, G, B
#define USE_AUX_RGB_LEDS

// don't turn on the aux LEDs while main LEDs are on
#ifdef USE_INDICATOR_LED_WHILE_RAMPING
#undef USE_INDICATOR_LED_WHILE_RAMPING
#endif

#define RAMP_SIZE 150

// Use 4/4096 as the lowest level (~3 lm) ... anything lower than that seems to flicker
// level_calc.py 5.8 1 150 7135 4 3 1800 --pwm dyn:74:4096:255
#define PWM1_LEVELS 4,5,5,5,6,6,7,9,9,10,11,12,13,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,30,31,32,33,34,35,37,38,38,39,40,41,42,44,45,46,47,48,48,49,50,51,51,52,53,53,53,53,53,53,53,53,52,52,51,50,49,47,46,44,41,39,36,33,30,27,28,29,30,31,32,33,34,35,37,38,39,40,42,43,45,46,48,49,51,52,54,56,58,59,61,63,65,67,70,72,74,76,79,81,84,86,89,91,94,97,100,103,106,109,112,116,119,123,126,130,134,137,141,145,149,154,158,162,167,171,176,181,186,191,196,202,207,213,218,224,230,236,242,249,255
#define PWM_TOPS 4095,2941,3765,2556,3480,2623,3210,3517,2950,3192,3334,3414,3453,3088,3125,3137,3130,3110,3080,3042,2998,2948,2896,2840,2783,2723,2663,2603,2542,2584,2518,2453,2388,2325,2263,2273,2210,2148,2088,2030,1973,1918,1912,1858,1805,1754,1704,1619,1575,1531,1489,1418,1380,1343,1280,1222,1166,1114,1064,1017,973,912,872,818,767,719,658,617,563,500,455,399,348,300,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255


#define MAX_1x7135 75
#define DEFAULT_LEVEL 50
#define MIN_THERM_STEPDOWN 60
#define HALFSPEED_LEVEL 20
#define QUARTERSPEED_LEVEL 5

#define RAMP_SMOOTH_FLOOR 1
#define RAMP_SMOOTH_CEIL 150
// 20 38 56 [75] 93 111 130
#define RAMP_DISCRETE_FLOOR 5
#define RAMP_DISCRETE_CEIL 130
#define RAMP_DISCRETE_STEPS 7

// 25 50 [75] 100 125
#define SIMPLE_UI_FLOOR 5
#define SIMPLE_UI_CEIL 150
#define SIMPLE_UI_STEPS 5

// and finally, set the default ramp style to Stepped
#undef RAMP_STYLE
#define RAMP_STYLE 1 // 0 = smooth, 1 = stepped

#define STROBE_OFF_LEVEL 1 // keep the regulator chip on between pulses

// use the brightest setting for strobe
#define STROBE_BRIGHTNESS MAX_LEVEL
// slow down party strobe; this driver can't pulse very fast
#define PARTY_STROBE_ONTIME 12
#define BIKE_STROBE_ONTIME 8

#define BLINK_BRIGHTNESS 30
#define BLINK_ONCE_TIME 48 // longer blink, since LEDs are slow
#define BLIP_LEVEL 10
#define BUZZ_SPEED 36 // default buzz of 16ms is too fast to turn LEDs on, slow it down to 36ms

// the default of 26 looks a bit flat, so increase it
#define CANDLE_AMPLITUDE 42

// stop panicking at ~50% power
#define THERM_FASTER_LEVEL 120 // throttle back faster when high
#undef DEFAULT_THERM_CEIL
#define DEFAULT_THERM_CEIL 50

// show each channel while it scroll by in the menu
#define USE_CONFIG_COLORS

// blink numbers on the main LEDs by default
// (so battcheck will be visible while charging)
#define DEFAULT_BLINK_CHANNEL CM_MAIN
// blink numbers on the aux LEDs by default
//#define DEFAULT_BLINK_CHANNEL CM_AUXWHT

// Just blink volts plus tenths, not the extra digit
#ifdef USE_EXTRA_BATTCHECK_DIGIT
#undef USE_EXTRA_BATTCHECK_DIGIT
#endif

// don't blink mid-ramp
#ifdef BLINK_AT_RAMP_MIDDLE
#undef BLINK_AT_RAMP_MIDDLE
#endif

// Barry isn't a fan of the voltage-based aux for fear of red LEDs drawing customer concerns, so override the default
#ifdef RGB_LED_OFF_DEFAULT
#undef RGB_LED_OFF_DEFAULT
#endif
#define RGB_LED_OFF_DEFAULT 0x13 // 0x19 = low, voltage; 0x13 = low, cyan; 0x12 = low, green; 0x14 = low, blue
//#define RGB_LED_LOCKOUT_DEFAULT 0x39 // blinking, voltage
1 change: 1 addition & 0 deletions hw/sofirn/sc13/arch
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
attiny1616
58 changes: 58 additions & 0 deletions hw/sofirn/sc13/hwdef.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Sofirn SC13 helper functions
// Copyright (C) 2024
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include "fsm/chan-rgbaux.c"

void set_level_zero();

void set_level_main(uint8_t level);
bool gradual_tick_main(uint8_t gt);


Channel channels[] = {
{ // channel 1 only
.set_level = set_level_main,
.gradual_tick = gradual_tick_main
},
RGB_AUX_CHANNELS
};


void set_level_zero() {
CH1_PWM = 0;
PWM_CNT = 0; // reset phase
BCK_ENABLE_PORT &= ~(1 << BCK_ENABLE_PIN); // disable buck regulator
}

// single set of LEDs with 1 regulated power channels
void set_level_main(uint8_t level) {

BCK_ENABLE_PORT |= (1 << BCK_ENABLE_PIN); // enable buck regulator

PWM_DATATYPE ch1_pwm = PWM_GET(pwm1_levels, level);
// pulse frequency modulation, a.k.a. dynamic PWM
uint16_t top = PWM_GET16(pwm_tops, level);

CH1_PWM = ch1_pwm;
// wait to sync the counter and avoid flashes
// (unnecessary w/ buffered registers)
//while(actual_level && (PWM_CNT > (top - 32))) {}
PWM_TOP = top;
// force reset phase when turning on from zero
// (because otherwise the initial response is inconsistent)
if (! actual_level) PWM_CNT = 0;
}

bool gradual_tick_main(uint8_t gt) {
PWM_DATATYPE pwm1 = PWM_GET(pwm1_levels, gt);

//GRADUAL_ADJUST_STACKED(pwm1, CH1_PWM, PWM_TOP_INIT);
GRADUAL_ADJUST_SIMPLE (pwm1, CH1_PWM);

if (pwm1 == CH1_PWM) return true; // done

return false; // not done yet
}
Loading