From 546178c70066ea5900399f4eb076c3a002586b0c Mon Sep 17 00:00:00 2001 From: Alessandro Mauri Date: Fri, 15 May 2026 21:31:21 +0200 Subject: [PATCH 1/8] moved isqrt to filter.h --- fw/filter.h | 21 +++++++++++++++++++++ fw/main.c | 20 -------------------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/fw/filter.h b/fw/filter.h index e7055fa..bbad041 100644 --- a/fw/filter.h +++ b/fw/filter.h @@ -2,6 +2,7 @@ #define _FILTER_H #include +#include #define MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -23,4 +24,24 @@ static_assert(-4 >> 1 == -2, ">> doesn't do sign extension"); #define I16_FP_EMA_K8(x, s) (int16_t)((((int32_t)(x)<<8) - (x) + (s)) >> 8) #define I16_FP_EMA_K16(x, s) (int16_t)((((int32_t)(x)<<16) - (x) + (s)) >> 16) +// Integer square root (binary search) +// https://en.wikipedia.org/wiki/Integer_square_root +static inline uint16_t isqrt(uint32_t x) +{ + uint16_t l = 0; // lower bound of the square root + uint16_t r = x + 1; // upper bound of the square root + + while (l != r - 1) { + uint32_t m = (l + r) / 2; // midpoint to test + if (m * m <= x) { + l = m; + } else { + r = m; + } + } + + return l; +} + + #endif // _FILTER_H diff --git a/fw/main.c b/fw/main.c index 7a33d74..a2897c9 100644 --- a/fw/main.c +++ b/fw/main.c @@ -345,26 +345,6 @@ static inline void pwm_set(uint16_t pulse_width) } -// Integer square root (binary search) -// https://en.wikipedia.org/wiki/Integer_square_root -static inline uint16_t isqrt(uint32_t x) -{ - uint16_t l = 0; // lower bound of the square root - uint16_t r = x + 1; // upper bound of the square root - - while (l != r - 1) { - uint32_t m = (l + r) / 2; // midpoint to test - if (m * m <= x) { - l = m; - } else { - r = m; - } - } - - return l; -} - - // Input: temperature difference // Output: duty-cycle 0-max_duty uint16_t pid(int16_t delta, int16_t max_duty) From 2a61c07a150c719b9c3c0e6c0fa5cee04344f869 Mon Sep 17 00:00:00 2001 From: Alessandro Mauri Date: Fri, 15 May 2026 22:30:29 +0200 Subject: [PATCH 2/8] moved ui stuff --- fw/main.c | 60 +++++++++++++------------------------------------------ 1 file changed, 14 insertions(+), 46 deletions(-) diff --git a/fw/main.c b/fw/main.c index a2897c9..eb94091 100644 --- a/fw/main.c +++ b/fw/main.c @@ -457,12 +457,17 @@ __attribute__((noreturn)) int main(void) // Init USBPD bool has_pd = pd_negotiate(eUSBPD_VCC_3V3); if (has_pd == false) { - u8g2_ClearBuffer(u8g2); - u8g2_SetFont(u8g2, u8g2_font_5x8_tr); - u8g2_DrawStr(u8g2, x_off+0, y_off+7, "Negotiation FAILED"); - u8g2_DrawStr(u8g2, x_off+0, y_off+14, USBPD_ResultToStr(pd_get_result())); - u8g2_SendBuffer(u8g2); - Delay_Ms(5000); + while (true) { + // No Power Delivery, maybe we are attached to a computer, so poll the input + poll_input(); + + u8g2_ClearBuffer(u8g2); + u8g2_SetFont(u8g2, u8g2_font_5x8_tr); + u8g2_DrawStr(u8g2, x_off+0, y_off+7, "Negotiation FAILED"); + u8g2_DrawStr(u8g2, x_off+0, y_off+14, USBPD_ResultToStr(pd_get_result())); + u8g2_SendBuffer(u8g2); + Delay_Ms(100); + } } else { pd_get_profile(&pd_profile, 60); @@ -474,25 +479,6 @@ __attribute__((noreturn)) int main(void) (100*(u32)isqrt(( MIN(pd_profile.set_power, pd_profile.power_avail)*pd_profile.tip_r)/1000) * 1000) / pd_profile.voltage , 100); - -#if 0 - u8g2_ClearBuffer(u8g2); - u8g2_SetFont(u8g2, u8g2_font_5x8_tr); - // Display tip temperature - u8g2_DrawStr(u8g2, x_off+0, y_off+7, "A:"); - u8g2_DrawStr(u8g2, x_off+10, y_off+7, u8g2_u16toa(pd_profile.max_current, 4)); - // Display bus voltage - u8g2_DrawStr(u8g2, x_off+45, y_off+7, "V:"); - u8g2_DrawStr(u8g2, x_off+55, y_off+7, u8g2_u16toa(pd_profile.voltage, 5)); - // Display power - u8g2_DrawStr(u8g2, x_off+0, y_off+15, "W:"); - u8g2_DrawStr(u8g2, x_off+10, y_off+15, u8g2_u16toa(pd_profile.power_avail, 3)); - // Display current - u8g2_DrawStr(u8g2, x_off+45, y_off+15, "D:"); - u8g2_DrawStr(u8g2, x_off+55, y_off+15, u8g2_u16toa(pd_profile.max_duty, 3)); - u8g2_SendBuffer(u8g2); - Delay_Ms(5000); -#endif } @@ -502,7 +488,6 @@ __attribute__((noreturn)) int main(void) } state = STATE_MENU; for (;;) { u32 start = funSysTick32(); - poll_input(); // usb u8g2_ClearBuffer(u8g2); u8g2_SetFont(u8g2, u8g2_font_5x8_tr); @@ -559,32 +544,15 @@ __attribute__((noreturn)) int main(void) } break; case STATE_HEATING: -#if 0 - // Display tip temperature - u8g2_DrawStr(u8g2, x_off+0, y_off+7, "TIP:"); - u8g2_DrawStr(u8g2, x_off+20, y_off+7, i16toa(tip_temp_c)); - // Display bus voltage - u8g2_DrawStr(u8g2, x_off+45, y_off+7, "V:"); - u8g2_DrawStr(u8g2, x_off+55, y_off+7, u16toa(vbus_mv/1000)); - // Display power - //u8g2_DrawStr(u8g2, x_off+0, y_off+15, "W:"); - //u8g2_DrawStr(u8g2, x_off+10, y_off+15, u8g2_u16toa(power, 3)); - u8g2_DrawStr(u8g2, x_off+0, y_off+15, u16toa(duty)); - // Display current - // u8g2_DrawStr(u8g2, x_off+45, y_off+15, "A:"); - // u8g2_DrawStr(u8g2, x_off+55, y_off+15, u16toa(current_ma)); - u8g2_DrawStr(u8g2, x_off+45, y_off+15, "W:"); - u8g2_DrawStr(u8g2, x_off+55, y_off+15, u16toa(power)); -#else + // Draw UI draw_temp(u8g2, x_off+0, y_off+0, tip_temp_c, true); - u8g2_DrawStr(u8g2, x_off+32, y_off+6, "W:"); - u8g2_DrawStr(u8g2, x_off+42, y_off+6, u16toa(power)); + u8g2_DrawStr(u8g2, x_off+32, y_off+6, "A:"); + u8g2_DrawStr(u8g2, x_off+42, y_off+6, u16toa((current_ma+500)/1000)); u8g2_DrawStr(u8g2, x_off+60, y_off+6, "V:"); u8g2_DrawStr(u8g2, x_off+70, y_off+6, u16toa((vbus_mv+500)/1000)); uint8_t p = (power*100)/pd_profile.set_power; uint8_t w = (uint16_t)(p*54)/100; u8g2_DrawBox(u8g2, x_off+42, y_off+14, w, 5); -#endif if (enabled) { funDigitalWrite(PIN_12V, 1); From 52d67f3cf338f8fe8041fb1b3ae98dccd27fd178 Mon Sep 17 00:00:00 2001 From: Alessandro Mauri Date: Sat, 16 May 2026 16:58:06 +0200 Subject: [PATCH 3/8] one comment on encoder --- fw/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fw/main.c b/fw/main.c index eb94091..247795e 100644 --- a/fw/main.c +++ b/fw/main.c @@ -77,6 +77,7 @@ void handle_usbfs_input(int numbytes, uint8_t *data) * B: ____| |____| |____| * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ * f r r f f r r f f r + * |<---->| single detent */ void update_encoder(void) { From 5688dfb8c5bb12098b24d939105b8337d190bf20 Mon Sep 17 00:00:00 2001 From: Alessandro Mauri Date: Sat, 16 May 2026 17:23:28 +0200 Subject: [PATCH 4/8] moved setup to it's own function --- fw/main.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/fw/main.c b/fw/main.c index 247795e..47312e6 100644 --- a/fw/main.c +++ b/fw/main.c @@ -389,17 +389,21 @@ uint16_t pid(int16_t delta, int16_t max_duty) } -__attribute__((noreturn)) int main(void) +// Board Setup +static inline void setup(void) { + // Generic system setup SystemInit(); funGpioInitAll(); USBFSSetup(); + // Analog pin configuration funPinMode(PIN_VBUS, GPIO_CFGLR_IN_ANALOG); funPinMode(PIN_CURRENT, GPIO_CFGLR_IN_ANALOG); funPinMode(PIN_NTC, GPIO_CFGLR_IN_ANALOG); funPinMode(PIN_TEMP, GPIO_CFGLR_IN_ANALOG); + // Analog inputs setup (dma and injection conversion) uint8_t adc_channels[3] = { VBUS_ADC_CHANNEL, CURRENT_ADC_CHANNEL, @@ -410,6 +414,7 @@ __attribute__((noreturn)) int main(void) }; setup_adc_and_dma(adc_channels, 3, adc_injected, 1); + // Digital pin configuration funPinMode(PIN_12V, GPIO_CFGLR_OUT_10Mhz_PP); funDigitalWrite(PIN_12V, 0); funPinMode(PIN_HEATER, GPIO_CFGLR_OUT_10Mhz_AF_PP); @@ -423,9 +428,11 @@ __attribute__((noreturn)) int main(void) funDigitalWrite(PIN_ENC_B, 1); // specify pull-up funPinMode(PIN_BTN, GPIO_CFGLR_IN_FLOAT); + // Setup PWM timer setup_pwm(); pwm_off(); + // Setup i2c line, includes setting the pin alternate mode setup_i2c(); // Configure the IO as an interrupt. @@ -445,11 +452,14 @@ __attribute__((noreturn)) int main(void) // enable interrupt NVIC_EnableIRQ(EXTI7_0_IRQn); - Delay_Ms(500); - + // Start i2c peripherals u8g2 = display_init(); sc7a20_init(); +} + +__attribute__((noreturn)) int main(void) +{ u8g2_ClearBuffer(u8g2); u8g2_SetFont(u8g2, u8g2_font_5x8_tr); u8g2_DrawStr(u8g2, x_off+0, y_off+7, "Negotiating..."); From a7d3ceaffe37eb1b311101817d7ac45dd7453fb0 Mon Sep 17 00:00:00 2001 From: Alessandro Mauri Date: Sat, 16 May 2026 17:30:18 +0200 Subject: [PATCH 5/8] some comments and attribution --- fw/fpmath.h | 4 ++++ fw/lib_i2c.h | 6 +++--- fw/sc7a20.c | 8 ++++++++ fw/sc7a20.h | 9 +++++---- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/fw/fpmath.h b/fw/fpmath.h index 927dace..3ae082b 100644 --- a/fw/fpmath.h +++ b/fw/fpmath.h @@ -4,6 +4,10 @@ #include #include +/* + * Minimal Fixed-Point math library implementation + */ + // This library depends on sign extension static_assert(-4 >> 1 == -2, ">> doesn't do sign extension"); diff --git a/fw/lib_i2c.h b/fw/lib_i2c.h index dd51640..c3bf8fd 100644 --- a/fw/lib_i2c.h +++ b/fw/lib_i2c.h @@ -1,10 +1,10 @@ -#ifndef _LIB_I2C_H -#define _LIB_I2C_H - // MIT License // Copyright (c) 2025 UniTheCat // Tested with Ch32X03x and CH32V30x +#ifndef _LIB_I2C_H +#define _LIB_I2C_H + #include diff --git a/fw/sc7a20.c b/fw/sc7a20.c index e2239cd..d787b95 100644 --- a/fw/sc7a20.c +++ b/fw/sc7a20.c @@ -1,3 +1,11 @@ +/* + * Register functions for the SC7A20 accellerometer + * Original Author: + * Ralim + * Created on: 18 Sep. 2020 + * https://github.com/Ralim/IronOS.git + */ + #include #include "lib_i2c.h" diff --git a/fw/sc7a20.h b/fw/sc7a20.h index 75b9f88..533418b 100644 --- a/fw/sc7a20.h +++ b/fw/sc7a20.h @@ -1,8 +1,9 @@ /* - * SC7A20_defines.h - * - * Created on: 18 Sep. 2020 - * Author: Ralim + * Defines for the SC7A20 accellerometer + * Original Author: + * Ralim + * Created on: 18 Sep. 2020 + * https://github.com/Ralim/IronOS.git */ #ifndef _SC7A20_H_ From d875568d9ad76220c6c98af83352bcb980eb129a Mon Sep 17 00:00:00 2001 From: Alessandro Mauri Date: Sat, 16 May 2026 18:34:04 +0200 Subject: [PATCH 6/8] oops, actually call setup() --- fw/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fw/main.c b/fw/main.c index 47312e6..d492037 100644 --- a/fw/main.c +++ b/fw/main.c @@ -460,6 +460,8 @@ static inline void setup(void) __attribute__((noreturn)) int main(void) { + setup(); + u8g2_ClearBuffer(u8g2); u8g2_SetFont(u8g2, u8g2_font_5x8_tr); u8g2_DrawStr(u8g2, x_off+0, y_off+7, "Negotiating..."); From ccdf7e9981eeb5a61439ea335b56919f5d16162f Mon Sep 17 00:00:00 2001 From: Alessandro Mauri Date: Sat, 16 May 2026 18:34:24 +0200 Subject: [PATCH 7/8] tweak pid for less overshoot --- fw/main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fw/main.c b/fw/main.c index d492037..4e4b4dd 100644 --- a/fw/main.c +++ b/fw/main.c @@ -353,7 +353,7 @@ uint16_t pid(int16_t delta, int16_t max_duty) // PID coefficients const fp16_t Kp = num2fp( 1, 1700, 4); const fp16_t Ti = num2fp(10, 0000, 4); - const fp16_t Td = num2fp( 0, 700, 4); + const fp16_t Td = num2fp( 0, 1500, 4); static fp16_t err_p, err_i, intgrt, err_d, dt, prev_err; static u32 t, prev_t; @@ -361,6 +361,9 @@ uint16_t pid(int16_t delta, int16_t max_duty) t = funSysTick32(); dt = fp_div(i2fp((t-prev_t)/DELAY_MS_TIME), i2fp(1000)); + // if pid was paused, reset the integrator + if (dt > num2fp(0, 2, 1)) intgrt = 0; + fp16_t err = i2fp(delta); // temperature delta as fixed point number err_p = err; From b4086ddea039ff1d87a1f95421e9e58e007ef00b Mon Sep 17 00:00:00 2001 From: Alessandro Mauri Date: Sat, 16 May 2026 18:34:34 +0200 Subject: [PATCH 8/8] 100W --- fw/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fw/main.c b/fw/main.c index 4e4b4dd..53e11ec 100644 --- a/fw/main.c +++ b/fw/main.c @@ -485,11 +485,11 @@ __attribute__((noreturn)) int main(void) Delay_Ms(100); } } else { - pd_get_profile(&pd_profile, 60); + pd_get_profile(&pd_profile, 100); // TODO: let the user decide the power profile pd_profile.set_temp = 200; - pd_profile.set_power = 60; // Slightly below max power to avoid overloading + pd_profile.set_power = 95; // Slightly below max power to avoid overloading pd_profile.tip_r = 2500; // TODO: tip check and resistance calculator pd_profile.max_duty = MIN( (100*(u32)isqrt((