diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index bbd3949b..229030fd 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -26,6 +26,7 @@ jobs: "S60", "S60P", "T55", + "S99", "TS101", ] fail-fast: true diff --git a/Documentation/DebugMenu.md b/Documentation/DebugMenu.md index c18018a9..1a5a0bf8 100644 --- a/Documentation/DebugMenu.md +++ b/Documentation/DebugMenu.md @@ -104,7 +104,7 @@ This can be used for checking performance of the movement detection code. This indicates the tip resistance that the device is currently using. For devices with multiple possible values to choose from (Pinecil V2), the appropriate value is automatically detected at every boot-up. Tip should be installed before boot-up or reading can not be done. -### Tip R +### Tip uV This is the raw tip reading in μV. Tip must be installed or reading will be high/inaccurate. At cool, the range of 700-1000 is normal for larger tips and ~1500 for smaller tips (TS80). This is used to evaluate the calibration routines. diff --git a/Makefile b/Makefile index c22f6718..00f75b75 100644 --- a/Makefile +++ b/Makefile @@ -52,7 +52,7 @@ DOCKER_CMD=$(DOCKER_BIN) -f $(DOCKER_YML) run --rm builder MKDOCS_YML=$(CURDIR)/scripts/IronOS-mkdocs.yml # supported models -MODELS=TS100 TS80 TS80P Pinecil MHP30 Pinecilv2 S60 TS101 S60P T55 # target names & dir names +MODELS=TS100 TS80 TS80P Pinecil MHP30 Pinecilv2 S60 TS101 S60P T55 S99 # target names & dir names MODELS_ML=Pinecil Pinecilv2 # target names MODELS_MULTILANG=Pinecil_multi-lang Pinecilv2_multi-lang # dir names diff --git a/README.md b/README.md index e4f118cc..ae9579ea 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,8 @@ _This firmware does **NOT** support the USB port while running for changing sett | Pinecil V2 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | | | Miniware TS101 | ✔️ | ❌ | ✔️ | ✔️ | ❌ | ✔️ | ✔️ | Full OLED resolution not yet supported. | | Sequre S60 | ❌ | ❌ | ✔️ | ❌ | ❌ | ❌ | ✔️ | Full OLED resolution not yet supported. | -| Sequre S60P | ❌ | ❌ | ✔️ | ❌ | ❌ | ❌ | ✔️ | Full OLED resolution not yet supported. | +| Sequre S60P | ✔️ | ❌ | ✔️ | ❌ | ❌ | ❌ | ✔️ | Full OLED resolution not yet supported. | +| Sequre S99 | ✔️ | ❌ | ✔️ | ❌ | ❌ | ❌ | ✔️ | Full OLED resolution not yet supported. | | Sequre T55 | ❌ | ❌ | ✔️ | ❌ | ❌ | N/A | ✔️ | Full OLED resolution not yet supported. | | Miniware TS80P | ❌ | ✔️ | ✔️ | ❌ | ❌ | N/A | ✔️ | | | Miniware TS100 | ✔️ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌\*\* | | diff --git a/Translations/make_translation.py b/Translations/make_translation.py index 8608ee51..d502a7ff 100755 --- a/Translations/make_translation.py +++ b/Translations/make_translation.py @@ -163,7 +163,7 @@ def get_debug_menu() -> List[str]: "UpTime ", "Move ", "Tip Res", - "Tip R ", + "Tip uV ", "Tip O ", "HW G ", "HW M ", diff --git a/Translations/translations_definitions.json b/Translations/translations_definitions.json index e473ca34..fa7c629b 100644 --- a/Translations/translations_definitions.json +++ b/Translations/translations_definitions.json @@ -18,7 +18,7 @@ }, { "id": "NoPowerDeliveryMessage", - "include": ["POW_PD"], + "include": ["POW_PD", "POW_PD_EXT"], "description": "The IC required for USB-PD could not be communicated with. This is an error warning that USB-PD WILL NOT FUNCTION. Generally indicative of either a hardware or software issues." }, { @@ -264,14 +264,14 @@ "id": "PDNegTimeout", "maxLen": 8, "maxLen2": 15, - "include": ["POW_PD"], + "include": ["POW_PD", "POW_PD_EXT"], "description": "How long until firmware stops trying to negotiate for USB-PD and tries QC instead. Longer times may help dodgy / old PD adapters, faster times move onto PD quickly. Units of 100ms. Recommended to keep small values." }, { "id": "USBPDMode", "maxLen": 7, "maxLen2": 15, - "include": ["POW_PD"], + "include": ["POW_PD", "POW_PD_EXT"], "description": "No Dynamic disables EPR & PPS, Safe mode does not use padding resistance" }, { diff --git a/source/Core/BSP/MHP30/configuration.h b/source/Core/BSP/MHP30/configuration.h index 8698a857..9f76510e 100644 --- a/source/Core/BSP/MHP30/configuration.h +++ b/source/Core/BSP/MHP30/configuration.h @@ -153,6 +153,7 @@ #define PROFILE_SUPPORT #define OLED_96x16 1 #define POW_PD 1 +#define USB_PD_TIMEOUT 20 // Default Timeout for USB-PD Protocol negotiation in x100ms #define POW_PD_EXT 0 #define USB_PD_EPR_WATTAGE 0 /*No EPR*/ #define TEMP_NTC diff --git a/source/Core/BSP/Miniware/configuration.h b/source/Core/BSP/Miniware/configuration.h index 6aebed15..57d1815f 100644 --- a/source/Core/BSP/Miniware/configuration.h +++ b/source/Core/BSP/Miniware/configuration.h @@ -132,6 +132,7 @@ #define ADC_VDD_MV 3300 // ADC max reading millivolts #define POW_PD_EXT 0 +#define USB_PD_TIMEOUT 20 // Default Timeout for USB-PD Protocol negotiation in x100ms // Deriving the Voltage div: // Vin_max = (3.3*(r1+r2))/(r2) diff --git a/source/Core/BSP/Pinecil/configuration.h b/source/Core/BSP/Pinecil/configuration.h index bef59a93..1f94799e 100644 --- a/source/Core/BSP/Pinecil/configuration.h +++ b/source/Core/BSP/Pinecil/configuration.h @@ -149,6 +149,7 @@ #define POW_PD 1 #define USB_PD_EPR_WATTAGE 0 /*No EPR (Yet?) */ #define POW_PD_EXT 0 +#define USB_PD_TIMEOUT 20 // Default Timeout for USB-PD Protocol negotiation in x100ms #define POW_QC 1 #define POW_DC 1 #define POW_QC_20V 1 diff --git a/source/Core/BSP/Pinecilv2/configuration.h b/source/Core/BSP/Pinecilv2/configuration.h index e50b7225..96b0d5e1 100644 --- a/source/Core/BSP/Pinecilv2/configuration.h +++ b/source/Core/BSP/Pinecilv2/configuration.h @@ -148,6 +148,7 @@ #define POW_PD 1 // Supported features #define USB_PD_EPR_WATTAGE 140 // USB PD EPR Wattage #define POW_PD_EXT 0 // Future-proof macro for other models with other PD modes +#define USB_PD_TIMEOUT 20 // Default Timeout for USB-PD Protocol negotiation in x100ms #define POW_QC 1 // Supported features #define POW_DC 1 // Supported features #define POW_QC_20V 1 // Supported features diff --git a/source/Core/BSP/Sequre/BSP.cpp b/source/Core/BSP/Sequre/BSP.cpp index 32daec13..313d170f 100644 --- a/source/Core/BSP/Sequre/BSP.cpp +++ b/source/Core/BSP/Sequre/BSP.cpp @@ -126,77 +126,7 @@ void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) { } } -void unstick_I2C() { -#ifdef SCL_Pin - GPIO_InitTypeDef GPIO_InitStruct; - int timeout = 100; - int timeout_cnt = 0; - - // 1. Clear PE bit. - hi2c1.Instance->CR1 &= ~(0x0001); - /**I2C1 GPIO Configuration - PB6 ------> I2C1_SCL - PB7 ------> I2C1_SDA - */ - // 2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR). - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - - GPIO_InitStruct.Pin = SCL_Pin; - HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct); - HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET); - - GPIO_InitStruct.Pin = SDA_Pin; - HAL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct); - HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_SET); - - while (GPIO_PIN_SET != HAL_GPIO_ReadPin(SDA_GPIO_Port, SDA_Pin)) { - // Move clock to release I2C - HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_RESET); - asm("nop"); - asm("nop"); - asm("nop"); - asm("nop"); - HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET); - - timeout_cnt++; - if (timeout_cnt > timeout) { - return; - } - } - - // 12. Configure the SCL and SDA I/Os as Alternate function Open-Drain. - GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - - GPIO_InitStruct.Pin = SCL_Pin; - HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = SDA_Pin; - HAL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct); - - HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET); - HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_SET); - - // 13. Set SWRST bit in I2Cx_CR1 register. - hi2c1.Instance->CR1 |= 0x8000; - - asm("nop"); - - // 14. Clear SWRST bit in I2Cx_CR1 register. - hi2c1.Instance->CR1 &= ~0x8000; - - asm("nop"); - - // 15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register - hi2c1.Instance->CR1 |= 0x0001; - - // Call initialization function. - HAL_I2C_Init(&hi2c1); -#endif -} +void unstick_I2C() {} uint8_t getButtonA() { return HAL_GPIO_ReadPin(KEY_A_GPIO_Port, KEY_A_Pin) == GPIO_PIN_RESET ? 1 : 0; } uint8_t getButtonB() { return HAL_GPIO_ReadPin(KEY_B_GPIO_Port, KEY_B_Pin) == GPIO_PIN_RESET ? 1 : 0; } diff --git a/source/Core/BSP/Sequre/Pins.h b/source/Core/BSP/Sequre/Pins.h index f00be339..b740f913 100644 --- a/source/Core/BSP/Sequre/Pins.h +++ b/source/Core/BSP/Sequre/Pins.h @@ -5,8 +5,8 @@ * Author: Ralim */ -#ifndef BSP_MINIWARE_PINS_H_ -#define BSP_MINIWARE_PINS_H_ +#ifndef BSP_SEQURE_PINS_H_ +#define BSP_SEQURE_PINS_H_ #include "configuration.h" #ifdef MODEL_S60 @@ -65,6 +65,45 @@ #define SCL2_GPIO_Port GPIOB #define SDA2_Pin GPIO_PIN_7 #define SDA2_GPIO_Port GPIOB +#define SCL_Pin GPIO_PIN_11 +#define SCL_GPIO_Port GPIOB +#define SDA_Pin GPIO_PIN_10 +#define SDA_GPIO_Port GPIOB +// Pin gets pulled high on movement +#define MOVEMENT_Pin GPIO_PIN_3 +#define MOVEMENT_GPIO_Port GPIOA + +#endif + +#ifdef MODEL_S99 + +#define KEY_B_Pin GPIO_PIN_1 +#define KEY_B_GPIO_Port GPIOB +#define TMP36_INPUT_Pin GPIO_PIN_5 +#define TMP36_INPUT_GPIO_Port GPIOA +#define TMP36_ADC1_CHANNEL ADC_CHANNEL_5 +#define TMP36_ADC2_CHANNEL ADC_CHANNEL_5 +#define TIP_TEMP_Pin GPIO_PIN_0 +#define TIP_TEMP_GPIO_Port GPIOA +#define TIP_TEMP_ADC1_CHANNEL ADC_CHANNEL_0 +#define TIP_TEMP_ADC2_CHANNEL ADC_CHANNEL_0 +#define VIN_Pin GPIO_PIN_4 +#define VIN_GPIO_Port GPIOA +#define VIN_ADC1_CHANNEL ADC_CHANNEL_4 +#define VIN_ADC2_CHANNEL ADC_CHANNEL_4 +#define KEY_A_Pin GPIO_PIN_0 +#define KEY_A_GPIO_Port GPIOB +#define PWM_Out_Pin GPIO_PIN_8 +#define PWM_Out_GPIO_Port GPIOB +#define PWM_Out_CHANNEL TIM_CHANNEL_3 // Timer 4; channel 3 +#define SCL2_Pin GPIO_PIN_6 +#define SCL2_GPIO_Port GPIOB +#define SDA2_Pin GPIO_PIN_7 +#define SDA2_GPIO_Port GPIOB +#define SCL_Pin GPIO_PIN_11 +#define SCL_GPIO_Port GPIOB +#define SDA_Pin GPIO_PIN_10 +#define SDA_GPIO_Port GPIOB // Pin gets pulled high on movement #define MOVEMENT_Pin GPIO_PIN_3 #define MOVEMENT_GPIO_Port GPIOA @@ -98,4 +137,4 @@ #endif // MODEL_T55 -#endif /* BSP_MINIWARE_PINS_H_ */ +#endif /* BSP_SEQURE_PINS_H_ */ diff --git a/source/Core/BSP/Sequre/Power.cpp b/source/Core/BSP/Sequre/Power.cpp index a6b1f7c7..649bf370 100644 --- a/source/Core/BSP/Sequre/Power.cpp +++ b/source/Core/BSP/Sequre/Power.cpp @@ -1,5 +1,6 @@ #include "BSP.h" #include "BSP_Power.h" +#include "FS2711.hpp" #include "Pins.h" #include "QC3.h" #include "Settings.h" @@ -16,9 +17,26 @@ void power_check() { return; // We are using PD } #endif +#if POW_PD_EXT == 2 + if (FS2711::has_run_selection()) { + return; + } +#endif #ifdef POW_QC QC_resync(); #endif } -bool getIsPoweredByDCIN() { return false; } +bool getIsPoweredByDCIN() { +#if POW_PD_EXT == 2 && defined(POW_DC) + if (!FS2711::has_run_selection()) { + return true; + } else if (FS2711::debug_get_state().source_voltage > 0) { + return false; + } else { + return true; + } +#else + return false; +#endif +} diff --git a/source/Core/BSP/Sequre/README.md b/source/Core/BSP/Sequre/README.md index bb9de245..41604352 100644 --- a/source/Core/BSP/Sequre/README.md +++ b/source/Core/BSP/Sequre/README.md @@ -1,6 +1,6 @@ -# BSP section for STM32F103 based Miniware products +# BSP section for STM32F103 based Sequre products -This folder contains the hardware abstractions required for the TS100, TS80 and probably TS80P soldering irons. +This folder contains the hardware abstractions required for the S60, S60P and S99 soldering irons. ## Main abstractions diff --git a/source/Core/BSP/Sequre/Software_I2C.h b/source/Core/BSP/Sequre/Software_I2C.h index d80bbfcb..a28d0ce0 100644 --- a/source/Core/BSP/Sequre/Software_I2C.h +++ b/source/Core/BSP/Sequre/Software_I2C.h @@ -5,19 +5,32 @@ * Author: Ralim */ -#ifndef BSP_MINIWARE_SOFTWARE_I2C_H_ -#define BSP_MINIWARE_SOFTWARE_I2C_H_ +#ifndef BSP_SEQURE_SOFTWARE_I2C_H_ +#define BSP_SEQURE_SOFTWARE_I2C_H_ #include "BSP.h" #include "configuration.h" #include "stm32f1xx_hal.h" -#ifdef I2C_SOFT_BUS_2 +#ifdef I2C_SOFT_BUS_1 +#define SOFT_SCL1_HIGH() HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET) +#define SOFT_SCL1_LOW() HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_RESET) +#define SOFT_SDA1_HIGH() HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_SET) +#define SOFT_SDA1_LOW() HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_RESET) +#define SOFT_SDA1_READ() (HAL_GPIO_ReadPin(SDA_GPIO_Port, SDA_Pin) == GPIO_PIN_SET ? 1 : 0) +#define SOFT_SCL1_READ() (HAL_GPIO_ReadPin(SCL_GPIO_Port, SCL_Pin) == GPIO_PIN_SET ? 1 : 0) + +#endif /* I2C_SOFT_BUS_1 */ + +#ifdef I2C_SOFT_BUS_2 #define SOFT_SCL2_HIGH() HAL_GPIO_WritePin(SCL2_GPIO_Port, SCL2_Pin, GPIO_PIN_SET) #define SOFT_SCL2_LOW() HAL_GPIO_WritePin(SCL2_GPIO_Port, SCL2_Pin, GPIO_PIN_RESET) #define SOFT_SDA2_HIGH() HAL_GPIO_WritePin(SDA2_GPIO_Port, SDA2_Pin, GPIO_PIN_SET) #define SOFT_SDA2_LOW() HAL_GPIO_WritePin(SDA2_GPIO_Port, SDA2_Pin, GPIO_PIN_RESET) #define SOFT_SDA2_READ() (HAL_GPIO_ReadPin(SDA2_GPIO_Port, SDA2_Pin) == GPIO_PIN_SET ? 1 : 0) #define SOFT_SCL2_READ() (HAL_GPIO_ReadPin(SCL2_GPIO_Port, SCL2_Pin) == GPIO_PIN_SET ? 1 : 0) + +#endif /* I2C_SOFT_BUS_2 */ + // clang-format off #define SOFT_I2C_DELAY() \ { \ @@ -27,7 +40,6 @@ } // clang-format on -#endif // 40 ~= 100kHz; 15 gives around 250kHz or so which is fast _and_ stable -#endif /* BSP_MINIWARE_SOFTWARE_I2C_H_ */ +#endif /* BSP_SEQURE_SOFTWARE_I2C_H_ */ diff --git a/source/Core/BSP/Sequre/ThermoModel.cpp b/source/Core/BSP/Sequre/ThermoModel.cpp index 8e49b985..f3bb3c3b 100644 --- a/source/Core/BSP/Sequre/ThermoModel.cpp +++ b/source/Core/BSP/Sequre/ThermoModel.cpp @@ -83,3 +83,10 @@ TemperatureType_t TipThermoModel::convertuVToDegC(uint32_t tipuVDelta) { #ifdef TEMP_uV_LOOKUP_S60 TemperatureType_t TipThermoModel::convertuVToDegC(uint32_t tipuVDelta) { return (tipuVDelta * 50) / 485; } #endif // TEMP_uV_LOOKUP_S60 + +#ifdef TEMP_uV_LOOKUP_S99 +// 42.85 uV / K -> 1/42.85 K/uV = 20/857 +// TemperatureType_t TipThermoModel::convertuVToDegC(uint32_t tipuVDelta) { return (tipuVDelta * 20) / 857; } +// Measurement is probably with heating element in series, thats why the reading differs from the approx 42.85 uV/K +TemperatureType_t TipThermoModel::convertuVToDegC(uint32_t tipuVDelta) { return (tipuVDelta * 1) / 30; } +#endif // TEMP_uV_LOOKUP_S99 diff --git a/source/Core/BSP/Sequre/configuration.h b/source/Core/BSP/Sequre/configuration.h index df06f68e..86d87d5b 100644 --- a/source/Core/BSP/Sequre/configuration.h +++ b/source/Core/BSP/Sequre/configuration.h @@ -116,7 +116,7 @@ // Vin_max = (3.3*(r1+r2))/(r2) // vdiv = (32768*4)/(vin_max*10) -#if defined(MODEL_S60) + defined(MODEL_S60P) + defined(MODEL_T55) == 0 +#if defined(MODEL_S60) + defined(MODEL_S60P) + defined(MODEL_T55) + defined(MODEL_S99) == 0 #error "No model defined!" #endif @@ -131,9 +131,10 @@ #define POWER_LIMIT_STEPS 5 #define OP_AMP_GAIN_STAGE 536 #define TEMP_uV_LOOKUP_S60 -#define USB_PD_VMAX 12 // Maximum voltage for PD to negotiate +#define USB_PD_VMAX 12 // Maximum voltage for PD to negotiate #define THERMAL_RUNAWAY_TIME_SEC 20 #define THERMAL_RUNAWAY_TEMP_C 3 +#define USB_PD_TIMEOUT 1 // Default Timeout for USB-PD Protocol negotiation in x100ms #define HARDWARE_MAX_WATTAGE_X10 600 @@ -165,9 +166,10 @@ #define POWER_LIMIT_STEPS 5 #define OP_AMP_GAIN_STAGE 536 #define TEMP_uV_LOOKUP_S60 -#define USB_PD_VMAX 20 // Maximum voltage for PD to negotiate +#define USB_PD_VMAX 20 // Maximum voltage for PD to negotiate #define THERMAL_RUNAWAY_TIME_SEC 20 #define THERMAL_RUNAWAY_TEMP_C 3 +#define USB_PD_TIMEOUT 1 // Default Timeout for USB-PD Protocol negotiation in x100ms #define HARDWARE_MAX_WATTAGE_X10 600 @@ -180,10 +182,13 @@ #define GPIO_VIBRATION #define POW_PD_EXT 2 #define USB_PD_EPR_WATTAGE 0 /*No EPR*/ +#define POW_DC #define DEBUG_POWER_MENU_BUTTON_B 1 #define HAS_POWER_DEBUG_MENU #define TEMP_NTC #define I2C_SOFT_BUS_2 // For now we are doing software I2C to get around hardware chip issues +#define I2C_PROBE_POW_PD // For now we are doing software I2C to get around hardware chip issues +#define I2C_SOFT_BUS_1 // For now we are doing software I2C to get around hardware chip issues #define OLED_I2CBB2 #define FILTER_DISPLAYED_TIP_TEMP 4 // Filtering for GUI display @@ -206,6 +211,8 @@ #define OP_AMP_GAIN_STAGE 1 #define TEMP_uV_LOOKUP_PT1000 #define USB_PD_VMAX 20 // Maximum voltage for PD to negotiate +#define USB_PD_TIMEOUT 1 // Default Timeout for USB-PD Protocol negotiation in x100ms + #define NO_DISPLAY_ROTATE // Disable OLED rotation by accel #define MAX_TEMP_C 350 // Max soldering temp selectable °C #define MAX_TEMP_F 660 // Max soldering temp selectable °F @@ -239,6 +246,44 @@ #define MODEL_HAS_DCDC // We dont have DC/DC but have reallly fast PWM that gets us roughly the same place #endif /* T55 */ +#ifdef MODEL_S99 +#define VOLTAGE_DIV 460 // Default divider scaler +#define CALIBRATION_OFFSET 200 // Default adc offset in uV +#define PID_POWER_LIMIT 70 // Sets the max pwm power limit +#define POWER_LIMIT 0 // 0 watts default limit +#define MAX_POWER_LIMIT 70 +#define POWER_LIMIT_STEPS 5 +#define OP_AMP_GAIN_STAGE 237 // Two sequential op-amps 1st: 1+(9k29/997R)=10.31 2nd: 1+(22k/1k)=23 -> 10.31*23=237 +#define TEMP_uV_LOOKUP_S99 +#define USB_PD_VMAX 20 // Maximum voltage for PD to negotiate +#define USB_PD_TIMEOUT 1 // Default Timeout for USB-PD Protocol negotiation in x100ms + +#define HARDWARE_MAX_WATTAGE_X10 1300 + +#define TIP_THERMAL_MASS 8 // X10 watts to raise 1 deg C in 1 second +#define TIP_THERMAL_INERTIA 128 // We use a large inertia value to smooth out the drive to the tip since its stupidly sensitive +#define THERMAL_RUNAWAY_TIME_SEC 20 +#define THERMAL_RUNAWAY_TEMP_C 10 + +#define TIP_RESISTANCE 20 //(actually 2.5 ish but we need to be more conservative on pwm'ing watt limit) x10 ohms + +#define OLED_128x32 +#define GPIO_VIBRATION +#define POW_PD_EXT 2 +#define USB_PD_EPR_WATTAGE 0 /*No EPR*/ +#define POW_DC +#define DEBUG_POWER_MENU_BUTTON_B 1 +#define HAS_POWER_DEBUG_MENU +#define TEMP_NTC +#define I2C_SOFT_BUS_2 // For now we are doing software I2C to get around hardware chip issues +#define I2C_PROBE_POW_PD // For now we are doing software I2C to get around hardware chip issues +#define I2C_SOFT_BUS_1 // For now we are doing software I2C to get around hardware chip issues +#define OLED_I2CBB2 +#define FILTER_DISPLAYED_TIP_TEMP 4 // Filtering for GUI display + +#define MODEL_HAS_DCDC // We dont have DC/DC but have reallly fast PWM that gets us roughly the same place +#endif /* S99 */ + #define FLASH_LOGOADDR (0x08000000 + (62 * 1024)) #define SETTINGS_START_PAGE (0x08000000 + (63 * 1024)) diff --git a/source/Core/BSP/Sequre/preRTOS.cpp b/source/Core/BSP/Sequre/preRTOS.cpp index 3a8fa4f4..83574ca4 100644 --- a/source/Core/BSP/Sequre/preRTOS.cpp +++ b/source/Core/BSP/Sequre/preRTOS.cpp @@ -6,10 +6,14 @@ */ #include "BSP.h" +#include "I2CBB1.hpp" #include "I2CBB2.hpp" #include "Pins.h" #include "Setup.h" #include +#if defined(I2C_PROBE_POW_PD) && POW_PD_EXT == 2 +#include "FS2711.hpp" +#endif void preRToSInit() { /* Reset of all peripherals, Initializes the Flash interface and the Systick. @@ -17,7 +21,14 @@ void preRToSInit() { HAL_Init(); Setup_HAL(); // Setup all the HAL objects BSPInit(); +#ifdef I2C_SOFT_BUS_1 + I2CBB1::init(); +#endif /* I2C_SOFT_BUS_1 */ #ifdef I2C_SOFT_BUS_2 I2CBB2::init(); -#endif +#endif /* I2C_SOFT_BUS_2 */ +#if defined(I2C_PROBE_POW_PD) && POW_PD_EXT == 2 + // Detect and set FS2711 I2C bus num + FS2711::detect_i2c_bus_num(); +#endif /* defined(I2C_PROBE_POW_PD) && POW_PD_EXT == 2 */ } diff --git a/source/Core/Drivers/FS2711.cpp b/source/Core/Drivers/FS2711.cpp index e6624b30..ebad9904 100644 --- a/source/Core/Drivers/FS2711.cpp +++ b/source/Core/Drivers/FS2711.cpp @@ -4,8 +4,10 @@ #include "BSP.h" #include "FS2711.hpp" #include "FS2711_defines.h" +#include "I2CBB1.hpp" #include "I2CBB2.hpp" #include "Settings.h" +#include "Utils.h" #include "cmsis_os.h" #include #include @@ -15,31 +17,61 @@ #error Max PD Voltage must be defined #endif -#define PROTOCOL_TIMEOUT 100 // ms - extern int32_t powerSupplyWattageLimit; +uint8_t I2C_PORT = 2; + fs2711_state_t FS2711::state; -inline void i2c_write(uint8_t addr, uint8_t data) { I2CBB2::Mem_Write(FS2711_ADDR, addr, &data, 1); } +void i2c_write(uint8_t addr, uint8_t data) { + if (I2C_PORT == 2) { + I2CBB2::Mem_Write(FS2711_ADDR, addr, &data, 1); + } else if (I2C_PORT == 1) { + I2CBB1::Mem_Write(FS2711_ADDR, addr, &data, 1); + } +} -inline uint8_t i2c_read(uint8_t addr) { +uint8_t i2c_read(uint8_t addr) { uint8_t data = 0; - I2CBB2::Mem_Read(FS2711_ADDR, addr, &data, 1); + if (I2C_PORT == 2) { + I2CBB2::Mem_Read(FS2711_ADDR, addr, &data, 1); + } else if (I2C_PORT == 1) { + I2CBB1::Mem_Read(FS2711_ADDR, addr, &data, 1); + } return data; } -inline bool i2c_probe(uint8_t addr) { return I2CBB2::probe(addr); } +bool i2c_probe(uint8_t addr) { + bool probing_state = false; + if (I2C_PORT == 2) { + probing_state = I2CBB2::probe(addr); + } else if (I2C_PORT == 1) { + probing_state = I2CBB1::probe(addr); + } + return probing_state; +} + +uint8_t FS2711::detect_i2c_bus_num() { + I2CBB2::probe(88); + I2CBB2::probe(89); + if (I2CBB2::probe(FS2711_ADDR)) { + I2C_PORT = 2; + } else { + I2C_PORT = 1; + } + return I2C_PORT; +} void FS2711::start() { memset(&state, 0, sizeof(fs2711_state_t)); state.req_pdo_num = 0xFF; enable_protocol(false); - osDelay(PROTOCOL_TIMEOUT); + // PDNegTimeout is in 100ms, so x100 for ms + osDelay(getSettingValue(SettingsOptions::PDNegTimeout) * 100); select_protocol(FS2711_PROTOCOL_PD); enable_protocol(true); - osDelay(PROTOCOL_TIMEOUT); + osDelay(getSettingValue(SettingsOptions::PDNegTimeout) * 100); } uint8_t FS2711::selected_protocol() { return i2c_read(FS2711_REG_SELECT_PROTOCOL); } @@ -163,6 +195,11 @@ void FS2711::negotiate() { if (getSettingValue(SettingsOptions::USBPDMode) == usbpdMode_t::DEFAULT) { tip_resistance += 5; } +#ifdef MODEL_HAS_DCDC + // If this device has step down DC/DC inductor to smooth out current spikes + // We can instead ignore resistance and go for max voltage we can accept; and rely on the DC/DC regulation to keep under current limit + tip_resistance = 255; // (Push to 25.5 ohms to effectively disable this check) +#endif uint16_t pdo_min_mv = 0, pdo_max_mv = 0, pdo_max_curr = 0, pdo_type = 0; @@ -228,7 +265,7 @@ bool FS2711::has_run_selection() { return state.req_pdo_num != 0xFF; } uint16_t FS2711::source_voltage() { return state.source_voltage / 1000; } -// FS2711 does current in mV so it needs to be converted to x100 intead of x1000 +// FS2711 does current in mA so it needs to be converted to x100 intead of x1000 uint16_t FS2711::source_currentx100() { return state.source_current / 10; } uint16_t FS2711::debug_pdo_max_voltage(uint8_t pdoid) { return state.pdo_max_volt[pdoid]; } diff --git a/source/Core/Drivers/FS2711.hpp b/source/Core/Drivers/FS2711.hpp index 9fb2ae83..11a6943d 100644 --- a/source/Core/Drivers/FS2711.hpp +++ b/source/Core/Drivers/FS2711.hpp @@ -19,6 +19,8 @@ typedef struct { class FS2711 { public: + static uint8_t detect_i2c_bus_num(); + static bool probe(); static void start(); diff --git a/source/Core/Drivers/Font.h b/source/Core/Drivers/Font.h index 0d0943ff..6eb50444 100644 --- a/source/Core/Drivers/Font.h +++ b/source/Core/Drivers/Font.h @@ -93,8 +93,8 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x30, 0x0C, 0x02, 0xF1, 0xF1, 0xF1, 0x02, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xB0, 0x8C, 0x83, 0x80, 0x80, 0x80, 0x80, 0xB3, 0xB3, 0xB3, 0x80, 0x80, 0x80, 0x80, 0x83, 0x8C, 0xB0, 0xC0, 0x00, 0x00}; - #if defined(MODEL_S60) || defined(MODEL_S60P) || defined(MODEL_TS101) || defined(MODEL_T55) - #if defined(MODEL_S60) || defined(MODEL_S60P) + #if defined(MODEL_S60) || defined(MODEL_S60P) || defined(MODEL_TS101) || defined(MODEL_T55) || defined(MODEL_S99) + #if defined(MODEL_S60) || defined(MODEL_S60P) || defined(MODEL_S99) const uint8_t buttonA[] = { // width = 56 // height = 32 diff --git a/source/Core/Drivers/I2CBB2.cpp b/source/Core/Drivers/I2CBB2.cpp index fee68bd1..adf9c94f 100644 --- a/source/Core/Drivers/I2CBB2.cpp +++ b/source/Core/Drivers/I2CBB2.cpp @@ -14,6 +14,7 @@ void I2CBB2::init() { // Set GPIO's to output open drain GPIO_InitTypeDef GPIO_InitStruct; __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; GPIO_InitStruct.Pin = SDA2_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; diff --git a/source/Core/Src/Settings.cpp b/source/Core/Src/Settings.cpp index 49b86153..8253d9ce 100644 --- a/source/Core/Src/Settings.cpp +++ b/source/Core/Src/Settings.cpp @@ -54,7 +54,7 @@ typedef struct { } SettingConstants; static const SettingConstants settingsConstants[(int)SettingsOptions::SettingsOptionsLength] = { - //{ min, max, increment, default} + //{ min, max, increment, default} { MIN_TEMP_C, MAX_TEMP_F, 5, SOLDERING_TEMP}, // SolderingTemp { MIN_TEMP_C, MAX_TEMP_F, 5, 150}, // SleepTemp { 0, 15, 1, SLEEP_TIME}, // SleepTime @@ -87,7 +87,7 @@ static const SettingConstants settingsConstants[(int)SettingsOptions::SettingsOp { 0, 9, 1, 0}, // AccelMissingWarningCounter { 0, 9, 1, 0}, // PDMissingWarningCounter { 0, 0xFFFF, 0, 41431 /*EN*/}, // UILanguage - { 0, 50, 1, 20}, // PDNegTimeout + { 0, 50, 1, USB_PD_TIMEOUT}, // PDNegTimeout { 0, 1, 1, 0}, // OLEDInversion { MIN_BRIGHTNESS, MAX_BRIGHTNESS, BRIGHTNESS_STEP, DEFAULT_BRIGHTNESS}, // OLEDBrightness { 0, 6, 1, 1}, // LOGOTime diff --git a/source/Core/Src/settingsGUI.cpp b/source/Core/Src/settingsGUI.cpp index cba9853e..7ed88adb 100644 --- a/source/Core/Src/settingsGUI.cpp +++ b/source/Core/Src/settingsGUI.cpp @@ -26,7 +26,7 @@ static void displayInputMinVRange(void); static void displayQCInputV(void); #endif /* POW_QC */ -#ifdef POW_PD +#if defined(POW_PD) || POW_PD_EXT == 2 static void displayPDNegTimeout(void); static void displayUSBPDMode(void); #endif /* POW_PD */ @@ -123,9 +123,9 @@ static bool showSolderingTipType(void); // Menu functions -#if defined(POW_DC) || defined(POW_QC) || defined(POW_PD) +#if defined(POW_DC) || defined(POW_QC) || defined(POW_PD) || defined(POW_PD) || POW_PD_EXT == 2 static void displayPowerMenu(void); -#endif /* POW_DC or POW_QC */ +#endif /* POW_DC or POW_QC or POW_PD or POD_PD_EXT 2*/ static void displaySolderingMenu(void); static void displayPowerSavingMenu(void); @@ -236,7 +236,7 @@ const menuitem rootSettingsMenu[] { /* ^^^^ end of menu marker. DO NOT REMOVE ^^^^ */ }; -#if defined(POW_DC) || defined(POW_QC) || defined(POW_PD) +#if defined(POW_DC) || defined(POW_QC) || defined(POW_PD) || POW_PD_EXT == 2 const menuitem powerMenu[] = { /* * Power Source @@ -255,7 +255,7 @@ const menuitem powerMenu[] = { /* Voltage input */ {SETTINGS_DESC(SettingsItemIndex::QCMaxVoltage), nullptr, displayQCInputV, nullptr, SettingsOptions::QCIdealVoltage, SettingsItemIndex::QCMaxVoltage, 4}, #endif -#ifdef POW_PD +#if defined(POW_PD) || POW_PD_EXT == 2 /* PD timeout setup */ {SETTINGS_DESC(SettingsItemIndex::PDNegTimeout), nullptr, displayPDNegTimeout, nullptr, SettingsOptions::PDNegTimeout, SettingsItemIndex::PDNegTimeout, 6}, /* Toggle PPS & EPR */ @@ -451,7 +451,7 @@ const menuitem advancedMenu[] = { /* clang-format on */ const menuitem *subSettingsMenus[] { -#if defined(POW_DC) || defined(POW_QC) || defined(POW_PD) +#if defined(POW_DC) || defined(POW_QC) || defined(POW_PD) || POW_PD_EXT == 2 powerMenu, #endif solderingMenu, PowerSavingMenu, UIMenu, advancedMenu, @@ -536,7 +536,7 @@ static void displayQCInputV(void) { #endif /* POW_QC */ -#ifdef POW_PD /* POW_PD */ +#if defined(POW_PD) || POW_PD_EXT == 2 /* POW_PD */ static void displayPDNegTimeout(void) { auto value = getSettingValue(SettingsOptions::PDNegTimeout); diff --git a/source/Core/Threads/UI/logic/OperatingModes.h b/source/Core/Threads/UI/logic/OperatingModes.h index 379094e4..56ca6264 100644 --- a/source/Core/Threads/UI/logic/OperatingModes.h +++ b/source/Core/Threads/UI/logic/OperatingModes.h @@ -23,6 +23,10 @@ extern "C" { #include "USBPD.h" #include "pd.h" #endif +#if POW_PD_EXT == 2 +#include "FS2711.hpp" +#include "FS2711_defines.h" +#endif enum class OperatingMode { StartupLogo=10, // Showing the startup logo diff --git a/source/Core/Threads/UI/logic/utils/SolderingCommon.cpp b/source/Core/Threads/UI/logic/utils/SolderingCommon.cpp index 9425c90f..5fe84461 100644 --- a/source/Core/Threads/UI/logic/utils/SolderingCommon.cpp +++ b/source/Core/Threads/UI/logic/utils/SolderingCommon.cpp @@ -63,6 +63,13 @@ int8_t getPowerSourceNumber(void) { #endif } } +#endif +#if POW_PD_EXT == 2 + if (FS2711::has_run_selection()) { + poweredbyPD = true; + // FS2711IC has VBUS always connected + pdHasVBUSConnected = true; + } #endif if (poweredbyPD) { if (pdHasVBUSConnected) { diff --git a/source/Makefile b/source/Makefile index d7990c79..17dd0640 100644 --- a/source/Makefile +++ b/source/Makefile @@ -6,7 +6,7 @@ ALL_MINIWARE_MODELS=TS100 TS80 TS80P TS101 ALL_PINECIL_MODELS=Pinecil ALL_PINECIL_V2_MODELS=Pinecilv2 ALL_MHP30_MODELS=MHP30 -ALL_SEQURE_MODELS=S60 S60P T55 +ALL_SEQURE_MODELS=S60 S60P T55 S99 ALL_MODELS=$(ALL_MINIWARE_MODELS) $(ALL_PINECIL_MODELS) $(ALL_MHP30_MODELS) $(ALL_PINECIL_V2_MODELS) $(ALL_SEQURE_MODELS) ifneq ($(model),$(filter $(model),$(ALL_MODELS))) @@ -145,6 +145,9 @@ flash_size=62k ifeq ($(model), S60P) bootldr_size=0x5000 DEVICE_DFU_ADDRESS=0x08005000 +else ifeq ($(model), S99) +bootldr_size=0x4c00 +DEVICE_DFU_ADDRESS=0x08004c00 else # S60 or T55 bootldr_size=0x4400 diff --git a/source/build.sh b/source/build.sh index 415e1f94..a57c3436 100755 --- a/source/build.sh +++ b/source/build.sh @@ -6,7 +6,7 @@ TRANSLATION_DIR="../Translations" # AVAILABLE_LANGUAGES will be calculating according to json files in $TRANSLATION_DIR AVAILABLE_LANGUAGES=() BUILD_LANGUAGES=() -AVAILABLE_MODELS=("TS100" "TS80" "TS80P" "Pinecil" "MHP30" "Pinecilv2" "S60" "S60P" "T55" "TS101") +AVAILABLE_MODELS=("TS100" "TS80" "TS80P" "Pinecil" "MHP30" "Pinecilv2" "S60" "S60P" "T55" "S99" "TS101") BUILD_MODELS=() builder_info() {