diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 3df90fe4..9f944d03 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -9,7 +9,7 @@ jobs: image: alpine:3.16 strategy: matrix: - model: ["TS100", "TS80", "TS80P", "Pinecil", "MHP30", "Pinecilv2"] + model: ["TS100", "TS80", "TS80P", "Pinecil", "MHP30", "Pinecilv2", "S60", "TS101"] fail-fast: true steps: diff --git a/Translations/make_translation.py b/Translations/make_translation.py index 644f1cbc..157e63aa 100755 --- a/Translations/make_translation.py +++ b/Translations/make_translation.py @@ -181,6 +181,7 @@ def get_accel_names_list() -> List[str]: "MSA301", "SC7A20", "GPIO", + "LIS2 CLONE", ] diff --git a/source/Core/BSP/MHP30/Software_I2C.h b/source/Core/BSP/MHP30/Software_I2C.h index 411362f5..a9b1bdc4 100644 --- a/source/Core/BSP/MHP30/Software_I2C.h +++ b/source/Core/BSP/MHP30/Software_I2C.h @@ -10,14 +10,14 @@ #include "BSP.h" #include "configuration.h" #include "stm32f1xx_hal.h" -#ifdef I2C_SOFT +#ifdef I2C_SOFT_BUS_2 -#define SOFT_SCL_HIGH() HAL_GPIO_WritePin(SCL2_GPIO_Port, SCL2_Pin, GPIO_PIN_SET) -#define SOFT_SCL_LOW() HAL_GPIO_WritePin(SCL2_GPIO_Port, SCL2_Pin, GPIO_PIN_RESET) -#define SOFT_SDA_HIGH() HAL_GPIO_WritePin(SDA2_GPIO_Port, SDA2_Pin, GPIO_PIN_SET) -#define SOFT_SDA_LOW() HAL_GPIO_WritePin(SDA2_GPIO_Port, SDA2_Pin, GPIO_PIN_RESET) -#define SOFT_SDA_READ() (HAL_GPIO_ReadPin(SDA2_GPIO_Port, SDA2_Pin) == GPIO_PIN_SET ? 1 : 0) -#define SOFT_SCL_READ() (HAL_GPIO_ReadPin(SCL2_GPIO_Port, SCL2_Pin) == GPIO_PIN_SET ? 1 : 0) +#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) #define SOFT_I2C_DELAY() \ { \ for (int xx = 0; xx < 20; xx++) { \ diff --git a/source/Core/BSP/MHP30/configuration.h b/source/Core/BSP/MHP30/configuration.h index e42d23d6..c36687f4 100644 --- a/source/Core/BSP/MHP30/configuration.h +++ b/source/Core/BSP/MHP30/configuration.h @@ -64,10 +64,10 @@ * OLED Brightness * */ -#define MIN_BRIGHTNESS 0 // Min OLED brightness selectable -#define MAX_BRIGHTNESS 100 // Max OLED brightness selectable -#define BRIGHTNESS_STEP 25 // OLED brightness increment -#define DEFAULT_BRIGHTNESS 25 // default OLED brightness +#define MIN_BRIGHTNESS 0 // Min OLED brightness selectable +#define MAX_BRIGHTNESS 100 // Max OLED brightness selectable +#define BRIGHTNESS_STEP 25 // OLED brightness increment +#define DEFAULT_BRIGHTNESS 25 // default OLED brightness /** * Temp change settings @@ -159,9 +159,9 @@ #define POW_PD 1 #define TEMP_NTC -#define I2C_SOFT +#define I2C_SOFT_BUS_2 #define BATTFILTERDEPTH 8 -#define OLED_I2CBB +#define OLED_I2CBB2 #define ACCEL_EXITS_ON_MOVEMENT #define NEEDS_VBUS_PROBE 0 diff --git a/source/Core/BSP/MHP30/preRTOS.cpp b/source/Core/BSP/MHP30/preRTOS.cpp index f5fe84ae..7b449483 100644 --- a/source/Core/BSP/MHP30/preRTOS.cpp +++ b/source/Core/BSP/MHP30/preRTOS.cpp @@ -6,7 +6,7 @@ */ #include "BSP.h" -#include "I2CBB.hpp" +#include "I2CBB2.hpp" #include "Pins.h" #include "Setup.h" #include @@ -17,7 +17,7 @@ void preRToSInit() { HAL_Init(); Setup_HAL(); // Setup all the HAL objects BSPInit(); - I2CBB::init(); + I2CBB2::init(); /* Init the IPC objects */ FRToSI2C::FRToSInit(); } diff --git a/source/Core/BSP/Miniware/BSP.cpp b/source/Core/BSP/Miniware/BSP.cpp index 96e44dad..fed937e3 100644 --- a/source/Core/BSP/Miniware/BSP.cpp +++ b/source/Core/BSP/Miniware/BSP.cpp @@ -5,6 +5,7 @@ #include "Pins.h" #include "Setup.h" #include "TipThermoModel.h" +#include "USBPD.h" #include "configuration.h" #include "history.hpp" #include "main.hpp" @@ -17,7 +18,7 @@ const uint16_t powerPWM = 255; static const uint8_t holdoffTicks = 14; // delay of 8 ms static const uint8_t tempMeasureTicks = 14; -uint16_t totalPWM; // htim2.Init.Period, the full PWM cycle +uint16_t totalPWM; // htimADC.Init.Period, the full PWM cycle static bool fastPWM; static bool infastPWM; @@ -99,20 +100,20 @@ uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) { static void switchToFastPWM(void) { // 10Hz - infastPWM = true; - totalPWM = powerPWM + tempMeasureTicks + holdoffTicks; - htim2.Instance->ARR = totalPWM; - htim2.Instance->CCR1 = powerPWM + holdoffTicks; - htim2.Instance->PSC = 2690; + infastPWM = true; + totalPWM = powerPWM + tempMeasureTicks + holdoffTicks; + htimADC.Instance->ARR = totalPWM; + htimADC.Instance->CCR1 = powerPWM + holdoffTicks; + htimADC.Instance->PSC = 2690; } static void switchToSlowPWM(void) { // 5Hz - infastPWM = false; - totalPWM = powerPWM + tempMeasureTicks / 2 + holdoffTicks / 2; - htim2.Instance->ARR = totalPWM; - htim2.Instance->CCR1 = powerPWM + holdoffTicks / 2; - htim2.Instance->PSC = 2690 * 2; + infastPWM = false; + totalPWM = powerPWM + tempMeasureTicks / 2 + holdoffTicks / 2; + htimADC.Instance->ARR = totalPWM; + htimADC.Instance->CCR1 = powerPWM + holdoffTicks / 2; + htimADC.Instance->PSC = 2690 * 2; } void setTipPWM(const uint8_t pulse, const bool shouldUseFastModePWM) { @@ -126,20 +127,30 @@ void setTipPWM(const uint8_t pulse, const bool shouldUseFastModePWM) { void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { // Period has elapsed - if (htim->Instance == TIM2) { + if (htim->Instance == ADC_CONTROL_TIMER) { // we want to turn on the output again PWMSafetyTimer--; - // We decrement this safety value so that lockups in the - // scheduler will not cause the PWM to become locked in an - // active driving state. - // While we could assume this could never happen, its a small price for - // increased safety - htim2.Instance->CCR4 = pendingPWM; - if (htim2.Instance->CCR4 && PWMSafetyTimer) { - HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); +// We decrement this safety value so that lockups in the +// scheduler will not cause the PWM to become locked in an +// active driving state. +// While we could assume this could never happen, its a small price for +// increased safety +#ifdef TIP_HAS_DIRECT_PWM + htimADC.Instance->CCR4 = powerPWM; + if (pendingPWM && PWMSafetyTimer) { + htimTip.Instance->CCR1 = pendingPWM; + HAL_TIM_PWM_Start(&htimTip, PWM_Out_CHANNEL); } else { - HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1); + HAL_TIM_PWM_Stop(&htimTip, PWM_Out_CHANNEL); } +#else + htimADC.Instance->CCR4 = pendingPWM; + if (htimADC.Instance->CCR4 && PWMSafetyTimer) { + HAL_TIM_PWM_Start(&htimTip, PWM_Out_CHANNEL); + } else { + HAL_TIM_PWM_Stop(&htimTip, PWM_Out_CHANNEL); + } +#endif if (fastPWM != infastPWM) { if (fastPWM) { switchToFastPWM(); @@ -157,10 +168,11 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) { // This was a when the PWM for the output has timed out if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4) { - HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1); + HAL_TIM_PWM_Stop(&htimTip, PWM_Out_CHANNEL); } } void unstick_I2C() { +#ifndef I2C_SOFT_BUS_1 GPIO_InitTypeDef GPIO_InitStruct; int timeout = 100; int timeout_cnt = 0; @@ -227,6 +239,7 @@ void unstick_I2C() { // Call initialization function. HAL_I2C_Init(&hi2c1); +#endif } uint8_t getButtonA() { return HAL_GPIO_ReadPin(KEY_A_GPIO_Port, KEY_A_Pin) == GPIO_PIN_RESET ? 1 : 0; } @@ -238,25 +251,148 @@ void reboot() { NVIC_SystemReset(); } void delay_ms(uint16_t count) { HAL_Delay(count); } -bool isTipDisconnected() { +uint8_t lastTipResistance = 0; // default to unknown +const uint8_t numTipResistanceReadings = 3; +uint32_t tipResistanceReadings[3] = {0, 0, 0}; +uint8_t tipResistanceReadingSlot = 0; +bool isTipDisconnected() { uint16_t tipDisconnectedThres = TipThermoModel::getTipMaxInC() - 5; uint32_t tipTemp = TipThermoModel::getTipInC(); return tipTemp > tipDisconnectedThres; } -void setStatusLED(const enum StatusLED state) {} -void setBuzzer(bool on) {} -uint8_t preStartChecks() { return 1; } +void setStatusLED(const enum StatusLED state) {} +void setBuzzer(bool on) {} +#ifdef TIP_RESISTANCE_SENSE_Pin +// We want to calculate lastTipResistance +// If tip is connected, and the tip is cold and the tip is not being heated +// We can use the GPIO to inject a small current into the tip and measure this +// The gpio is 100k -> diode -> tip -> gnd +// Source is 3.3V-0.5V +// Which is around 0.028mA this will induce: +// 6 ohm tip -> 3.24mV (Real world ~= 3320) +// 8 ohm tip -> 4.32mV (Real world ~= 4500) +// Which is definitely measureable +// Taking shortcuts here as we know we only really have to pick apart 6 and 8 ohm tips +// These are reported as 60 and 75 respectively +void performTipResistanceSampleReading() { + // 0 = read then turn on pullup, 1 = read then turn off pullup, 2 = read again + tipResistanceReadings[tipResistanceReadingSlot] = TipThermoModel::convertTipRawADCTouV(getTipRawTemp(1)); + + HAL_GPIO_WritePin(TIP_RESISTANCE_SENSE_GPIO_Port, TIP_RESISTANCE_SENSE_Pin, (tipResistanceReadingSlot == 0) ? GPIO_PIN_SET : GPIO_PIN_RESET); + + tipResistanceReadingSlot++; +} +void FinishMeasureTipResistance() { + + // Otherwise we now have the 4 samples; + // _^_ order, 2 delta's, combine these + + int32_t calculatedSkew = tipResistanceReadings[0] - tipResistanceReadings[2]; // If positive tip is cooling + calculatedSkew /= 2; // divide by two to get offset per time constant + + int32_t reading = (((tipResistanceReadings[1] - tipResistanceReadings[0]) + calculatedSkew) // jump 1 - skew + + // + + ((tipResistanceReadings[1] - tipResistanceReadings[2]) + calculatedSkew) // jump 2 - skew + ) // + / 2; // Take average + // // As we are only detecting two resistances; we can split the difference for now + uint8_t newRes = 0; + if (reading > 1200) { + // return; // Change nothing as probably disconnected tip + tipResistanceReadingSlot = lastTipResistance = 0; + return; + } else if (reading < 800) { + newRes = 62; + } else { + newRes = 80; + } + lastTipResistance = newRes; +} +volatile bool tipMeasurementOccuring = true; +volatile TickType_t nextTipMeasurement = 100; + +void performTipMeasurementStep() { + + // Wait 200ms for settle time + if (xTaskGetTickCount() < (nextTipMeasurement)) { + return; + } + nextTipMeasurement = xTaskGetTickCount() + (TICKS_100MS * 5); + if (tipResistanceReadingSlot < numTipResistanceReadings) { + performTipResistanceSampleReading(); + return; + } + + // We are sensing the resistance + FinishMeasureTipResistance(); + + tipMeasurementOccuring = false; +} +#endif +uint8_t preStartChecks() { +#ifdef TIP_RESISTANCE_SENSE_Pin + performTipMeasurementStep(); + if (preStartChecksDone() != 1) { + return 0; + } +#endif +#ifdef HAS_SPLIT_POWER_PATH + + // We want to enable the power path that has the highest voltage + // Nominally one will be ~=0 and one will be high. Unless you jamb both in, then both _may_ be high, or device may be dead + { + uint16_t dc = getRawDCVin(); + uint16_t pd = getRawPDVin(); + if (dc > pd) { + HAL_GPIO_WritePin(DC_SELECT_GPIO_Port, DC_SELECT_Pin, GPIO_PIN_SET); + HAL_GPIO_WritePin(PD_SELECT_GPIO_Port, PD_SELECT_Pin, GPIO_PIN_RESET); + } else { + HAL_GPIO_WritePin(PD_SELECT_GPIO_Port, PD_SELECT_Pin, GPIO_PIN_SET); + HAL_GPIO_WritePin(DC_SELECT_GPIO_Port, DC_SELECT_Pin, GPIO_PIN_RESET); + } + } + +#endif +#ifdef POW_PD + // If we are in the middle of negotiating PD, wait until timeout + // Before turning on the heater + if (!USBPowerDelivery::negotiationComplete()) { + return 0; + } + +#endif + return 1; +} uint64_t getDeviceID() { // return HAL_GetUIDw0() | ((uint64_t)HAL_GetUIDw1() << 32); } -uint8_t getTipResistanceX10() { return TIP_RESISTANCE; } +uint8_t preStartChecksDone() { +#ifdef TIP_RESISTANCE_SENSE_Pin + return (lastTipResistance == 0 || tipResistanceReadingSlot < numTipResistanceReadings || tipMeasurementOccuring) ? 0 : 1; +#else + return 1; +#endif +} -uint8_t preStartChecksDone() { return 1; } +uint8_t getTipResistanceX10() { + // Return tip resistance in x10 ohms + // We can measure this using the op-amp + return lastTipResistance; +} -uint8_t getTipThermalMass() { return TIP_THERMAL_MASS; } - -uint8_t getTipInertia() { return TIP_THERMAL_MASS; } \ No newline at end of file +uint8_t getTipThermalMass() { + if (lastTipResistance >= 80) { + return TIP_THERMAL_MASS; + } + return 45; +} +uint8_t getTipInertia() { + if (lastTipResistance >= 80) { + return TIP_THERMAL_MASS; + } + return 10; +} \ No newline at end of file diff --git a/source/Core/BSP/Miniware/Pins.h b/source/Core/BSP/Miniware/Pins.h index fd89dea3..a97c9f65 100644 --- a/source/Core/BSP/Miniware/Pins.h +++ b/source/Core/BSP/Miniware/Pins.h @@ -6,87 +6,145 @@ */ #ifndef BSP_MINIWARE_PINS_H_ - #define BSP_MINIWARE_PINS_H_ - #include "configuration.h" +#define BSP_MINIWARE_PINS_H_ +#include "configuration.h" - #ifdef MODEL_TS100 +#ifdef MODEL_TS100 - #define KEY_B_Pin GPIO_PIN_6 - #define KEY_B_GPIO_Port GPIOA - #define TMP36_INPUT_Pin GPIO_PIN_7 - #define TMP36_INPUT_GPIO_Port GPIOA - #define TMP36_ADC1_CHANNEL ADC_CHANNEL_7 - #define TMP36_ADC2_CHANNEL ADC_CHANNEL_7 - #define TIP_TEMP_Pin GPIO_PIN_0 - #define TIP_TEMP_GPIO_Port GPIOB - #define TIP_TEMP_ADC1_CHANNEL ADC_CHANNEL_8 - #define TIP_TEMP_ADC2_CHANNEL ADC_CHANNEL_8 - #define VIN_Pin GPIO_PIN_1 - #define VIN_GPIO_Port GPIOB - #define VIN_ADC1_CHANNEL ADC_CHANNEL_9 - #define VIN_ADC2_CHANNEL ADC_CHANNEL_9 - #define OLED_RESET_Pin GPIO_PIN_8 - #define OLED_RESET_GPIO_Port GPIOA - #define KEY_A_Pin GPIO_PIN_9 - #define KEY_A_GPIO_Port GPIOA - #define INT_Orientation_Pin GPIO_PIN_3 - #define INT_Orientation_GPIO_Port GPIOB - #define PWM_Out_Pin GPIO_PIN_4 - #define PWM_Out_GPIO_Port GPIOB - #define PWM_Out_CHANNEL TIM_CHANNEL_1 - #define PWM_Out_CCR - #define INT_Movement_Pin GPIO_PIN_5 - #define INT_Movement_GPIO_Port GPIOB - #define SCL_Pin GPIO_PIN_6 - #define SCL_GPIO_Port GPIOB - #define SDA_Pin GPIO_PIN_7 - #define SDA_GPIO_Port GPIOB - #endif +#define KEY_B_Pin GPIO_PIN_6 +#define KEY_B_GPIO_Port GPIOA +#define TMP36_INPUT_Pin GPIO_PIN_7 +#define TMP36_INPUT_GPIO_Port GPIOA +#define TMP36_ADC1_CHANNEL ADC_CHANNEL_7 +#define TMP36_ADC2_CHANNEL ADC_CHANNEL_7 +#define TIP_TEMP_Pin GPIO_PIN_0 +#define TIP_TEMP_GPIO_Port GPIOB +#define TIP_TEMP_ADC1_CHANNEL ADC_CHANNEL_8 +#define TIP_TEMP_ADC2_CHANNEL ADC_CHANNEL_8 +#define VIN_Pin GPIO_PIN_1 +#define VIN_GPIO_Port GPIOB +#define VIN_ADC1_CHANNEL ADC_CHANNEL_9 +#define VIN_ADC2_CHANNEL ADC_CHANNEL_9 +#define OLED_RESET_Pin GPIO_PIN_8 +#define OLED_RESET_GPIO_Port GPIOA +#define KEY_A_Pin GPIO_PIN_9 +#define KEY_A_GPIO_Port GPIOA +#define INT_Orientation_Pin GPIO_PIN_3 +#define INT_Orientation_GPIO_Port GPIOB +#define PWM_Out_Pin GPIO_PIN_4 +#define PWM_Out_GPIO_Port GPIOB +#define PWM_Out_CHANNEL TIM_CHANNEL_1 +#define TIP_CONTROL_TIMER TIM3 +#define ADC_CONTROL_TIMER TIM2 +#define ADC_CONTROL_TIMER_IRQ TIM2_IRQn +#define ADC_TRIGGER ADC_EXTERNALTRIGINJECCONV_T2_TRGO +#define INT_Movement_Pin GPIO_PIN_5 +#define INT_Movement_GPIO_Port GPIOB +#define SCL_Pin GPIO_PIN_6 +#define SCL_GPIO_Port GPIOB +#define SDA_Pin GPIO_PIN_7 +#define SDA_GPIO_Port GPIOB +#endif - #if defined(MODEL_TS80) + defined(MODEL_TS80P) > 0 - // TS80 & TS80P pin map - #define KEY_B_Pin GPIO_PIN_0 - #define KEY_B_GPIO_Port GPIOB - #define TMP36_INPUT_Pin GPIO_PIN_4 - #define TMP36_INPUT_GPIO_Port GPIOA - #define TMP36_ADC1_CHANNEL ADC_CHANNEL_4 - #define TMP36_ADC2_CHANNEL ADC_CHANNEL_4 - #define TIP_TEMP_Pin GPIO_PIN_3 - #define TIP_TEMP_GPIO_Port GPIOA - #define TIP_TEMP_ADC1_CHANNEL ADC_CHANNEL_3 - #define TIP_TEMP_ADC2_CHANNEL ADC_CHANNEL_3 +#ifdef MODEL_TS101 - #define VIN_Pin GPIO_PIN_2 - #define VIN_GPIO_Port GPIOA - #define VIN_ADC1_CHANNEL ADC_CHANNEL_2 - #define VIN_ADC2_CHANNEL ADC_CHANNEL_2 - #define OLED_RESET_Pin GPIO_PIN_15 - #define OLED_RESET_GPIO_Port GPIOA - #define KEY_A_Pin GPIO_PIN_1 - #define KEY_A_GPIO_Port GPIOB - #define INT_Orientation_Pin GPIO_PIN_4 - #define INT_Orientation_GPIO_Port GPIOB - #define PWM_Out_Pin GPIO_PIN_6 - #define PWM_Out_GPIO_Port GPIOA - #define PWM_Out_CHANNEL TIM_CHANNEL_1 - #define INT_Movement_Pin GPIO_PIN_5 - #define INT_Movement_GPIO_Port GPIOB - #define SCL_Pin GPIO_PIN_6 - #define SCL_GPIO_Port GPIOB - #define SDA_Pin GPIO_PIN_7 - #define SDA_GPIO_Port GPIOB - #define SCL2_Pin GPIO_PIN_5 - #define SCL2_GPIO_Port GPIOA - #define SDA2_Pin GPIO_PIN_1 - #define SDA2_GPIO_Port GPIOA +#define KEY_B_Pin GPIO_PIN_10 +#define KEY_B_GPIO_Port GPIOA +#define TMP36_INPUT_Pin GPIO_PIN_4 +#define TMP36_INPUT_GPIO_Port GPIOA +#define TMP36_ADC1_CHANNEL ADC_CHANNEL_4 +#define TMP36_ADC2_CHANNEL ADC_CHANNEL_4 +#define TIP_TEMP_Pin GPIO_PIN_3 +#define TIP_TEMP_GPIO_Port GPIOA +#define TIP_TEMP_ADC1_CHANNEL ADC_CHANNEL_3 +#define TIP_TEMP_ADC2_CHANNEL ADC_CHANNEL_3 +#define VIN_Pin GPIO_PIN_2 +#define VIN_GPIO_Port GPIOA +#define VIN_ADC1_CHANNEL ADC_CHANNEL_2 +#define VIN_ADC2_CHANNEL ADC_CHANNEL_2 +#define PD_VIN_Pin GPIO_PIN_6 +#define PD_VIN_GPIO_Port GPIOA +#define PD_VIN_ADC1_CHANNEL ADC_CHANNEL_6 +#define PD_VIN_ADC2_CHANNEL ADC_CHANNEL_6 +#define OLED_RESET_Pin GPIO_PIN_7 +#define OLED_RESET_GPIO_Port GPIOA +#define KEY_A_Pin GPIO_PIN_8 +#define KEY_A_GPIO_Port GPIOA +#define PWM_Out_Pin GPIO_PIN_0 +#define PWM_Out_GPIO_Port GPIOA +#define PWM_Out_CHANNEL TIM_CHANNEL_1 +#define TIP_CONTROL_TIMER TIM2 +#define ADC_CONTROL_TIMER TIM4 +#define ADC_CONTROL_TIMER_IRQ TIM4_IRQn +#define ADC_TRIGGER ADC_EXTERNALTRIGINJECCONV_T4_TRGO +#define SCL_Pin GPIO_PIN_0 +#define SCL_GPIO_Port GPIOB +#define SDA_Pin GPIO_PIN_1 +#define SDA_GPIO_Port GPIOB +// PD controller +#define SCL2_Pin GPIO_PIN_6 +#define SCL2_GPIO_Port GPIOB +#define SDA2_Pin GPIO_PIN_5 +#define SDA2_GPIO_Port GPIOB +#define INT_PD_Pin GPIO_PIN_7 +#define INT_PD_GPIO_Port GPIOB +// Selecting the DC source to route to theg +#define DC_SELECT_Pin GPIO_PIN_4 +#define DC_SELECT_GPIO_Port GPIOB +#define PD_SELECT_Pin GPIO_PIN_15 +#define PD_SELECT_GPIO_Port GPIOA - #endif +#define TIP_RESISTANCE_SENSE_Pin GPIO_PIN_1 +#define TIP_RESISTANCE_SENSE_GPIO_Port GPIOA - #ifdef MODEL_TS80P - // TS80P pin map - #define INT_PD_Pin GPIO_PIN_9 - #define INT_PD_GPIO_Port GPIOA - - #endif +#endif +#if defined(MODEL_TS80) + defined(MODEL_TS80P) > 0 +// TS80 & TS80P pin map +#define KEY_B_Pin GPIO_PIN_0 +#define KEY_B_GPIO_Port GPIOB +#define TMP36_INPUT_Pin GPIO_PIN_4 +#define TMP36_INPUT_GPIO_Port GPIOA +#define TMP36_ADC1_CHANNEL ADC_CHANNEL_4 +#define TMP36_ADC2_CHANNEL ADC_CHANNEL_4 +#define TIP_TEMP_Pin GPIO_PIN_3 +#define TIP_TEMP_GPIO_Port GPIOA +#define TIP_TEMP_ADC1_CHANNEL ADC_CHANNEL_3 +#define TIP_TEMP_ADC2_CHANNEL ADC_CHANNEL_3 +#define VIN_Pin GPIO_PIN_2 +#define VIN_GPIO_Port GPIOA +#define VIN_ADC1_CHANNEL ADC_CHANNEL_2 +#define VIN_ADC2_CHANNEL ADC_CHANNEL_2 +#define OLED_RESET_Pin GPIO_PIN_15 +#define OLED_RESET_GPIO_Port GPIOA +#define KEY_A_Pin GPIO_PIN_1 +#define KEY_A_GPIO_Port GPIOB +#define INT_Orientation_Pin GPIO_PIN_4 +#define INT_Orientation_GPIO_Port GPIOB +#define PWM_Out_Pin GPIO_PIN_6 +#define PWM_Out_GPIO_Port GPIOA +#define PWM_Out_CHANNEL TIM_CHANNEL_1 +#define TIP_CONTROL_TIMER TIM3 +#define ADC_CONTROL_TIMER TIM2 +#define ADC_CONTROL_TIMER_IRQ TIM2_IRQn +#define ADC_TRIGGER ADC_EXTERNALTRIGINJECCONV_T2_TRGO +#define INT_Movement_Pin GPIO_PIN_5 +#define INT_Movement_GPIO_Port GPIOB +#define SCL_Pin GPIO_PIN_6 +#define SCL_GPIO_Port GPIOB +#define SDA_Pin GPIO_PIN_7 +#define SDA_GPIO_Port GPIOB +#define SCL2_Pin GPIO_PIN_5 +#define SCL2_GPIO_Port GPIOA +#define SDA2_Pin GPIO_PIN_1 +#define SDA2_GPIO_Port GPIOA + +#endif + +#ifdef MODEL_TS80P +// TS80P pin map +#define INT_PD_Pin GPIO_PIN_9 +#define INT_PD_GPIO_Port GPIOA + +#endif #endif /* BSP_MINIWARE_PINS_H_ */ diff --git a/source/Core/BSP/Miniware/Power.cpp b/source/Core/BSP/Miniware/Power.cpp index 69bcd59a..423fe528 100644 --- a/source/Core/BSP/Miniware/Power.cpp +++ b/source/Core/BSP/Miniware/Power.cpp @@ -25,7 +25,10 @@ bool getIsPoweredByDCIN() { #if defined(MODEL_TS80) + defined(MODEL_TS80P) > 0 return false; #endif - +#ifdef MODEL_TS101 + // TODO have to check what we are using + return false; +#endif #ifdef MODEL_TS100 return true; #endif diff --git a/source/Core/BSP/Miniware/Setup.cpp b/source/Core/BSP/Miniware/Setup.cpp index b86c86ff..2bdc7a89 100644 --- a/source/Core/BSP/Miniware/Setup.cpp +++ b/source/Core/BSP/Miniware/Setup.cpp @@ -18,8 +18,8 @@ DMA_HandleTypeDef hdma_i2c1_rx; DMA_HandleTypeDef hdma_i2c1_tx; IWDG_HandleTypeDef hiwdg; -TIM_HandleTypeDef htim2; -TIM_HandleTypeDef htim3; +TIM_HandleTypeDef htimADC; +TIM_HandleTypeDef htimTip; #define ADC_FILTER_LEN 4 #define ADC_SAMPLES 16 uint16_t ADCReadings[ADC_SAMPLES]; // Used to store the adc readings for the handle cold junction temp @@ -29,8 +29,8 @@ static void SystemClock_Config(void); static void MX_ADC1_Init(void); static void MX_I2C1_Init(void); static void MX_IWDG_Init(void); -static void MX_TIM3_Init(void); -static void MX_TIM2_Init(void); +static void MX_TIP_CONTROL_TIMER_Init(void); +static void MX_ADC_CONTROL_TIMER_Init(void); static void MX_DMA_Init(void); static void MX_GPIO_Init(void); static void MX_ADC2_Init(void); @@ -45,11 +45,13 @@ void Setup_HAL() { MX_GPIO_Init(); MX_DMA_Init(); +#ifndef I2C_SOFT_BUS_1 MX_I2C1_Init(); +#endif MX_ADC1_Init(); MX_ADC2_Init(); - MX_TIM3_Init(); - MX_TIM2_Init(); + MX_TIP_CONTROL_TIMER_Init(); + MX_ADC_CONTROL_TIMER_Init(); MX_IWDG_Init(); HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADCReadings, (ADC_SAMPLES)); // start DMA of normal readings HAL_ADCEx_InjectedStart(&hadc1); // enable injected readings @@ -68,7 +70,41 @@ uint16_t getADCHandleTemp(uint8_t sample) { return filter.average() >> 1; } +#ifdef HAS_SPLIT_POWER_PATH +static history filteredDC = {{0}, 0, 0}; +static history filteredPD = {{0}, 0, 0}; + +uint16_t getRawDCVin() { return filteredDC.average(); } +uint16_t getRawPDVin() { return filteredPD.average(); } +#endif + uint16_t getADCVin(uint8_t sample) { +#ifdef HAS_SPLIT_POWER_PATH + // In split power path operation, we need to read both inputs, and return the larger + + if (sample) { + { + uint16_t latestADC = 0; + latestADC += hadc2.Instance->JDR1; + latestADC += hadc2.Instance->JDR2; + latestADC <<= 3; + filteredDC.update(latestADC); + } + { + uint16_t latestADC = 0; + latestADC += hadc2.Instance->JDR3; + latestADC += hadc2.Instance->JDR4; + latestADC <<= 3; + filteredPD.update(latestADC); + } + } + uint16_t dc = filteredDC.average(); + uint16_t pd = filteredPD.average(); + if (dc > pd) { + return dc; + } + return pd; +#else static history filter = {{0}, 0, 0}; if (sample) { uint16_t latestADC = 0; @@ -81,6 +117,7 @@ uint16_t getADCVin(uint8_t sample) { filter.update(latestADC); } return filter.average(); +#endif } // Returns either average or instant value. When sample is set the samples from the injected ADC are copied to the filter and then the raw reading is returned uint16_t getTipRawTemp(uint8_t sample) { @@ -178,7 +215,7 @@ static void MX_ADC1_Init(void) { sConfigInjected.InjectedRank = 1; sConfigInjected.InjectedNbrOfConversion = 4; sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_28CYCLES_5; - sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_T2_TRGO; + sConfigInjected.ExternalTrigInjecConv = ADC_TRIGGER; sConfigInjected.AutoInjectedConv = DISABLE; sConfigInjected.InjectedDiscontinuousConvMode = DISABLE; sConfigInjected.InjectedOffset = 0; @@ -203,7 +240,7 @@ static void MX_ADC2_Init(void) { /**Common config */ hadc2.Instance = ADC2; - hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE; + hadc2.Init.ScanConvMode = ADC_SCAN_ENABLE; hadc2.Init.ContinuousConvMode = ENABLE; hadc2.Init.DiscontinuousConvMode = DISABLE; hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START; @@ -217,13 +254,18 @@ static void MX_ADC2_Init(void) { sConfigInjected.InjectedRank = ADC_INJECTED_RANK_1; sConfigInjected.InjectedNbrOfConversion = 4; sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_28CYCLES_5; - sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_T2_TRGO; + sConfigInjected.ExternalTrigInjecConv = ADC_TRIGGER; sConfigInjected.AutoInjectedConv = DISABLE; sConfigInjected.InjectedDiscontinuousConvMode = DISABLE; sConfigInjected.InjectedOffset = 0; HAL_ADCEx_InjectedConfigChannel(&hadc2, &sConfigInjected); sConfigInjected.InjectedRank = ADC_INJECTED_RANK_2; HAL_ADCEx_InjectedConfigChannel(&hadc2, &sConfigInjected); + +#ifdef HAS_SPLIT_POWER_PATH + sConfigInjected.InjectedChannel = PD_VIN_ADC2_CHANNEL; +#endif + sConfigInjected.InjectedRank = ADC_INJECTED_RANK_3; HAL_ADCEx_InjectedConfigChannel(&hadc2, &sConfigInjected); sConfigInjected.InjectedRank = ADC_INJECTED_RANK_4; @@ -259,35 +301,43 @@ static void MX_IWDG_Init(void) { } /* TIM3 init function */ -static void MX_TIM3_Init(void) { +static void MX_TIP_CONTROL_TIMER_Init(void) { TIM_ClockConfigTypeDef sClockSourceConfig; TIM_MasterConfigTypeDef sMasterConfig; TIM_OC_InitTypeDef sConfigOC; - htim3.Instance = TIM3; - htim3.Init.Prescaler = 8; - htim3.Init.CounterMode = TIM_COUNTERMODE_UP; - htim3.Init.Period = 100; // 5 Khz PWM freq - htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4; // 4mhz before div - htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; // Preload the ARR register (though we dont use this) - HAL_TIM_Base_Init(&htim3); + htimTip.Instance = TIP_CONTROL_TIMER; +#ifdef TIP_HAS_DIRECT_PWM + htimTip.Init.Prescaler = 100; +#else + htimTip.Init.Prescaler = 3; +#endif + htimTip.Init.CounterMode = TIM_COUNTERMODE_UP; + htimTip.Init.Period = 255; // 5 Khz PWM freq + htimTip.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4; // 4mhz before div + htimTip.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; // Preload the ARR register (though we dont use this) + HAL_TIM_Base_Init(&htimTip); sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; - HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig); + HAL_TIM_ConfigClockSource(&htimTip, &sClockSourceConfig); - HAL_TIM_PWM_Init(&htim3); + HAL_TIM_PWM_Init(&htimTip); - HAL_TIM_OC_Init(&htim3); + HAL_TIM_OC_Init(&htimTip); sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; - HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig); + HAL_TIMEx_MasterConfigSynchronization(&htimTip, &sMasterConfig); - sConfigOC.OCMode = TIM_OCMODE_PWM1; - sConfigOC.Pulse = 50; // 50% duty cycle, that is AC coupled through the cap + sConfigOC.OCMode = TIM_OCMODE_PWM1; +#ifdef TIP_HAS_DIRECT_PWM + sConfigOC.Pulse = 0; // PWM is direct to tip +#else + sConfigOC.Pulse = 127; // 50% duty cycle, that is AC coupled through the cap to provide an on signal (This does not do tip at 50% duty cycle) +#endif sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_ENABLE; - HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, PWM_Out_CHANNEL); + HAL_TIM_PWM_ConfigChannel(&htimTip, &sConfigOC, PWM_Out_CHANNEL); GPIO_InitTypeDef GPIO_InitStruct; @@ -302,12 +352,12 @@ static void MX_TIM3_Init(void) { // Remap TIM3_CH1 to be on PB4 __HAL_AFIO_REMAP_TIM3_PARTIAL(); #else - // No re-map required + // No re-map required #endif - HAL_TIM_PWM_Start(&htim3, PWM_Out_CHANNEL); + HAL_TIM_PWM_Start(&htimTip, PWM_Out_CHANNEL); } /* TIM3 init function */ -static void MX_TIM2_Init(void) { +static void MX_ADC_CONTROL_TIMER_Init(void) { /* * We use the channel 1 to trigger the ADC at end of PWM period * And we use the channel 4 as the PWM modulation source using Interrupts @@ -318,30 +368,30 @@ static void MX_TIM2_Init(void) { // Timer 2 is fairly slow as its being used to run the PWM and trigger the ADC // in the PWM off time. - htim2.Instance = TIM2; + htimADC.Instance = ADC_CONTROL_TIMER; // dummy value, will be reconfigured by BSPInit() - htim2.Init.Prescaler = 2000; // 2 MHz timer clock/2000 = 1 kHz tick rate + htimADC.Init.Prescaler = 2000; // 2 MHz timer clock/2000 = 1 kHz tick rate // pwm out is 10k from tim3, we want to run our PWM at around 10hz or slower on the output stage // These values give a rate of around 3.5 Hz for "fast" mode and 1.84 Hz for "slow" - htim2.Init.CounterMode = TIM_COUNTERMODE_UP; + htimADC.Init.CounterMode = TIM_COUNTERMODE_UP; // dummy value, will be reconfigured by BSPInit() - htim2.Init.Period = powerPWM + 14 * 2; + htimADC.Init.Period = powerPWM + 14 * 2; - htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4; // 8 MHz (x2 APB1) before divide - htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; - htim2.Init.RepetitionCounter = 0; - HAL_TIM_Base_Init(&htim2); + htimADC.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4; // 8 MHz (x2 APB1) before divide + htimADC.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + htimADC.Init.RepetitionCounter = 0; + HAL_TIM_Base_Init(&htimADC); sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; - HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig); + HAL_TIM_ConfigClockSource(&htimADC, &sClockSourceConfig); - HAL_TIM_PWM_Init(&htim2); - HAL_TIM_OC_Init(&htim2); + HAL_TIM_PWM_Init(&htimADC); + HAL_TIM_OC_Init(&htimADC); sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; - HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig); + HAL_TIMEx_MasterConfigSynchronization(&htimADC, &sMasterConfig); sConfigOC.OCMode = TIM_OCMODE_PWM1; // dummy value, will be reconfigured by BSPInit() in the BSP.cpp @@ -354,15 +404,15 @@ static void MX_TIM2_Init(void) { * */ sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_ENABLE; - HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1); + HAL_TIM_PWM_ConfigChannel(&htimADC, &sConfigOC, TIM_CHANNEL_1); sConfigOC.Pulse = 0; // default to entirely off - HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4); + HAL_TIM_OC_ConfigChannel(&htimADC, &sConfigOC, TIM_CHANNEL_4); - HAL_TIM_Base_Start_IT(&htim2); - HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); - HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_4); - HAL_NVIC_SetPriority(TIM2_IRQn, 15, 0); - HAL_NVIC_EnableIRQ(TIM2_IRQn); + HAL_TIM_Base_Start_IT(&htimADC); + HAL_TIM_PWM_Start(&htimADC, TIM_CHANNEL_1); + HAL_TIM_PWM_Start_IT(&htimADC, TIM_CHANNEL_4); + HAL_NVIC_SetPriority(ADC_CONTROL_TIMER_IRQ, 15, 0); + HAL_NVIC_EnableIRQ(ADC_CONTROL_TIMER_IRQ); } /** @@ -446,8 +496,8 @@ static void MX_GPIO_Init(void) { HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); #endif #else - /* TS80 */ - /* Leave USB lines open circuit*/ + /* TS80 */ + /* Leave USB lines open circuit*/ #endif @@ -462,12 +512,45 @@ static void MX_GPIO_Init(void) { GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(OLED_RESET_GPIO_Port, &GPIO_InitStruct); - HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_RESET); // Pull down LCD reset HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_RESET); HAL_Delay(30); HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_SET); + +#ifdef DC_SELECT_Pin + GPIO_InitStruct.Pin = DC_SELECT_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(DC_SELECT_GPIO_Port, &GPIO_InitStruct); + HAL_GPIO_WritePin(DC_SELECT_GPIO_Port, DC_SELECT_Pin, GPIO_PIN_RESET); +#endif + +#ifdef PD_SELECT_Pin + GPIO_InitStruct.Pin = PD_SELECT_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(PD_SELECT_GPIO_Port, &GPIO_InitStruct); + HAL_GPIO_WritePin(PD_SELECT_GPIO_Port, PD_SELECT_Pin, GPIO_PIN_RESET); + +#endif + +#ifdef TIP_RESISTANCE_SENSE_Pin + GPIO_InitStruct.Pin = TIP_RESISTANCE_SENSE_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(TIP_RESISTANCE_SENSE_GPIO_Port, &GPIO_InitStruct); + HAL_GPIO_WritePin(TIP_RESISTANCE_SENSE_GPIO_Port, TIP_RESISTANCE_SENSE_Pin, GPIO_PIN_RESET); + +#endif + +#ifdef INT_PD_Pin + GPIO_InitStruct.Pin = INT_PD_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLUP; + HAL_GPIO_Init(INT_PD_GPIO_Port, &GPIO_InitStruct); + +#endif } #ifdef USE_FULL_ASSERT void assert_failed(uint8_t *file, uint32_t line) { asm("bkpt"); } diff --git a/source/Core/BSP/Miniware/Setup.h b/source/Core/BSP/Miniware/Setup.h index cf157c1d..94864f8f 100644 --- a/source/Core/BSP/Miniware/Setup.h +++ b/source/Core/BSP/Miniware/Setup.h @@ -7,7 +7,7 @@ #ifndef SETUP_H_ #define SETUP_H_ - +#include "configuration.h" #ifdef __cplusplus extern "C" { #endif @@ -24,13 +24,18 @@ extern I2C_HandleTypeDef hi2c1; extern IWDG_HandleTypeDef hiwdg; -extern TIM_HandleTypeDef htim2; -extern TIM_HandleTypeDef htim3; +extern TIM_HandleTypeDef htimADC; +extern TIM_HandleTypeDef htimTip; void Setup_HAL(); uint16_t getADCHandleTemp(uint8_t sample); uint16_t getADCVin(uint8_t sample); void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); // Since the hal header file does not define this one +#ifdef HAS_SPLIT_POWER_PATH +uint16_t getRawDCVin(); +uint16_t getRawPDVin(); +#endif + #ifdef __cplusplus } #endif diff --git a/source/Core/BSP/Miniware/Software_I2C.h b/source/Core/BSP/Miniware/Software_I2C.h index 5b2924ab..3b40f517 100644 --- a/source/Core/BSP/Miniware/Software_I2C.h +++ b/source/Core/BSP/Miniware/Software_I2C.h @@ -10,22 +10,34 @@ #include "BSP.h" #include "configuration.h" #include "stm32f1xx_hal.h" -#ifdef I2C_SOFT +#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 + +#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 -#define SOFT_SCL_HIGH() HAL_GPIO_WritePin(SCL2_GPIO_Port, SCL2_Pin, GPIO_PIN_SET) -#define SOFT_SCL_LOW() HAL_GPIO_WritePin(SCL2_GPIO_Port, SCL2_Pin, GPIO_PIN_RESET) -#define SOFT_SDA_HIGH() HAL_GPIO_WritePin(SDA2_GPIO_Port, SDA2_Pin, GPIO_PIN_SET) -#define SOFT_SDA_LOW() HAL_GPIO_WritePin(SDA2_GPIO_Port, SDA2_Pin, GPIO_PIN_RESET) -#define SOFT_SDA_READ() (HAL_GPIO_ReadPin(SDA2_GPIO_Port, SDA2_Pin) == GPIO_PIN_SET ? 1 : 0) -#define SOFT_SCL_READ() (HAL_GPIO_ReadPin(SCL2_GPIO_Port, SCL2_Pin) == GPIO_PIN_SET ? 1 : 0) #define SOFT_I2C_DELAY() \ { \ - for (int xx = 0; xx < 15; xx++) { \ + for (int xx = 0; xx < 10; xx++) { \ asm("nop"); \ } \ } -#endif // 40 ~= 100kHz; 15 gives around 250kHz or so which is fast _and_ stable #endif /* BSP_MINIWARE_SOFTWARE_I2C_H_ */ diff --git a/source/Core/BSP/Miniware/configuration.h b/source/Core/BSP/Miniware/configuration.h index a3c41f40..9be7918b 100644 --- a/source/Core/BSP/Miniware/configuration.h +++ b/source/Core/BSP/Miniware/configuration.h @@ -130,9 +130,9 @@ // Vin_max = (3.3*(r1+r2))/(r2) // vdiv = (32768*4)/(vin_max*10) -#if defined(MODEL_TS100) + defined(MODEL_TS80) + defined(MODEL_TS80P) > 1 +#if defined(MODEL_TS100) + defined(MODEL_TS80) + defined(MODEL_TS80P) + defined(MODEL_TS101) > 1 #error "Multiple models defined!" -#elif defined(MODEL_TS100) + defined(MODEL_TS80) + defined(MODEL_TS80P) == 0 +#elif defined(MODEL_TS100) + defined(MODEL_TS80) + defined(MODEL_TS80P) + defined(MODEL_TS101) == 0 #error "No model defined!" #endif #define NEEDS_VBUS_PROBE 0 @@ -174,6 +174,39 @@ #define TEMP_TMP36 #endif +#ifdef MODEL_TS101 +#define VOLTAGE_DIV 700 // 700 - Default divider from schematic +#define CALIBRATION_OFFSET 900 // 900 - Default adc offset in uV +#define PID_POWER_LIMIT 100 // Sets the max pwm power limit +#define POWER_LIMIT 0 // 0 watts default limit +#define MAX_POWER_LIMIT 100 +#define POWER_LIMIT_STEPS 5 +#define OP_AMP_GAIN_STAGE OP_AMP_GAIN_STAGE_TS100 +#define TEMP_uV_LOOKUP_HAKKO + +#define HARDWARE_MAX_WATTAGE_X10 1000 +#define TIP_THERMAL_MASS 65 // X10 watts to raise 1 deg C in 1 second +#define TIP_RESISTANCE 75 // x10 ohms, 7.5 typical for ts100 tips + +#define TIP_HAS_DIRECT_PWM 1 +#define POW_DC 1 +#define POW_PD 1 +#define I2C_SOFT_BUS_2 1 +#define I2C_SOFT_BUS_1 1 +#define OLED_I2CBB1 1 +#define USB_PD_I2CBB2 1 +#define USB_PD_VMAX 28 // Device supposedly can do 28V; looks like vmax is 33 ish +#define OLED_128x32 1 +#define OLED_FLIP 1 +#define HAS_SPLIT_POWER_PATH 1 +#define TEMP_NTC 1 +#define ACCEL_I2CBB1 1 +#define POW_EPR 1 +#define HAS_POWER_DEBUG_MENU +#define DEBUG_POWER_MENU_BUTTON_B + +#endif + #if defined(MODEL_TS80) + defined(MODEL_TS80P) > 0 #define MAX_POWER_LIMIT 40 #define POWER_LIMIT_STEPS 2 @@ -212,10 +245,20 @@ #define POW_PD 1 #define POW_QC 1 #define TEMP_NTC -#define I2C_SOFT +#define I2C_SOFT_BUS_2 1 #define SC7_ORI_FLIP #endif #endif +#ifdef MODEL_TS101 +#define FLASH_LOGOADDR (0x08000000 + (126 * 1024)) + +#else #define FLASH_LOGOADDR (0x08000000 + (62 * 1024)) +#endif + +#ifdef MODEL_TS101 +#define SETTINGS_START_PAGE (0x08000000 + (127 * 1024)) +#else #define SETTINGS_START_PAGE (0x08000000 + (63 * 1024)) +#endif \ No newline at end of file diff --git a/source/Core/BSP/Miniware/flash.c b/source/Core/BSP/Miniware/flash.c index c6a8793e..ab29e67a 100644 --- a/source/Core/BSP/Miniware/flash.c +++ b/source/Core/BSP/Miniware/flash.c @@ -10,6 +10,7 @@ #include "stm32f1xx_hal.h" #include "string.h" + void flash_save_buffer(const uint8_t *buffer, const uint16_t length) { FLASH_EraseInitTypeDef pEraseInit; pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES; @@ -30,10 +31,9 @@ void flash_save_buffer(const uint8_t *buffer, const uint16_t length) { HAL_FLASH_Unlock(); for (uint16_t i = 0; i < (length / 2); i++) { resetWatchdog(); - HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, SETTINGS_START_PAGE+ (i*sizeof(uint16_t)), data[i]); + HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, SETTINGS_START_PAGE + (i * sizeof(uint16_t)), data[i]); } HAL_FLASH_Lock(); - } -void flash_read_buffer(uint8_t *buffer, const uint16_t length) { memcpy(buffer, (uint8_t*)SETTINGS_START_PAGE, length); } +void flash_read_buffer(uint8_t *buffer, const uint16_t length) { memcpy(buffer, (uint8_t *)SETTINGS_START_PAGE, length); } diff --git a/source/Core/BSP/Miniware/fusb_user.cpp b/source/Core/BSP/Miniware/fusb_user.cpp index 09681dd7..c24e06ed 100644 --- a/source/Core/BSP/Miniware/fusb_user.cpp +++ b/source/Core/BSP/Miniware/fusb_user.cpp @@ -1,12 +1,12 @@ #include "configuration.h" #ifdef POW_PD #include "BSP.h" -#include "I2CBB.hpp" +#include "I2CBB2.hpp" #include "Setup.h" -bool fusb_read_buf(const uint8_t deviceAddr, const uint8_t registerAdd, const uint8_t size, uint8_t *buf) { return I2CBB::Mem_Read(deviceAddr, registerAdd, buf, size); } +bool fusb_read_buf(const uint8_t deviceAddr, const uint8_t registerAdd, const uint8_t size, uint8_t *buf) { return I2CBB2::Mem_Read(deviceAddr, registerAdd, buf, size); } -bool fusb_write_buf(const uint8_t deviceAddr, const uint8_t registerAdd, const uint8_t size, uint8_t *buf) { return I2CBB::Mem_Write(deviceAddr, registerAdd, buf, size); } +bool fusb_write_buf(const uint8_t deviceAddr, const uint8_t registerAdd, const uint8_t size, uint8_t *buf) { return I2CBB2::Mem_Write(deviceAddr, registerAdd, buf, size); } void setupFUSBIRQ() { GPIO_InitTypeDef GPIO_InitStruct; diff --git a/source/Core/BSP/Miniware/preRTOS.cpp b/source/Core/BSP/Miniware/preRTOS.cpp index f355984e..290b2a67 100644 --- a/source/Core/BSP/Miniware/preRTOS.cpp +++ b/source/Core/BSP/Miniware/preRTOS.cpp @@ -6,20 +6,27 @@ */ #include "BSP.h" -#include "I2CBB.hpp" +#include "I2CBB1.hpp" +#include "I2CBB2.hpp" #include "Pins.h" #include "Setup.h" +#include "configuration.h" #include + void preRToSInit() { /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); Setup_HAL(); // Setup all the HAL objects BSPInit(); -#ifdef I2C_SOFT - I2CBB::init(); +#ifdef I2C_SOFT_BUS_2 + I2CBB2::init(); #endif +#ifdef I2C_SOFT_BUS_1 + I2CBB1::init(); +#endif + /* Init the IPC objects */ FRToSI2C::FRToSInit(); } diff --git a/source/Core/BSP/Miniware/stm32f1xx_hal_msp.c b/source/Core/BSP/Miniware/stm32f1xx_hal_msp.c index 37bd47c2..b3b6007d 100644 --- a/source/Core/BSP/Miniware/stm32f1xx_hal_msp.c +++ b/source/Core/BSP/Miniware/stm32f1xx_hal_msp.c @@ -58,14 +58,23 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc) { */ GPIO_InitStruct.Pin = TIP_TEMP_Pin; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(TIP_TEMP_GPIO_Port, &GPIO_InitStruct); + GPIO_InitStruct.Pin = TMP36_INPUT_Pin; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; HAL_GPIO_Init(TMP36_INPUT_GPIO_Port, &GPIO_InitStruct); + GPIO_InitStruct.Pin = VIN_Pin; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; HAL_GPIO_Init(VIN_GPIO_Port, &GPIO_InitStruct); +#ifdef PD_VIN_Pin + + GPIO_InitStruct.Pin = PD_VIN_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + HAL_GPIO_Init(PD_VIN_GPIO_Port, &GPIO_InitStruct); +#endif /* ADC2 interrupt Init */ HAL_NVIC_SetPriority(ADC1_2_IRQn, 15, 0); HAL_NVIC_EnableIRQ(ADC1_2_IRQn); @@ -83,7 +92,7 @@ void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) { GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct); /* Peripheral clock enable */ __HAL_RCC_I2C1_CLK_ENABLE(); @@ -128,5 +137,8 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim_base) { } else if (htim_base->Instance == TIM2) { /* Peripheral clock enable */ __HAL_RCC_TIM2_CLK_ENABLE(); + } else if (htim_base->Instance == TIM4) { + /* Peripheral clock enable */ + __HAL_RCC_TIM4_CLK_ENABLE(); } } diff --git a/source/Core/BSP/Miniware/stm32f1xx_it.c b/source/Core/BSP/Miniware/stm32f1xx_it.c index 41569410..4e1b04ca 100644 --- a/source/Core/BSP/Miniware/stm32f1xx_it.c +++ b/source/Core/BSP/Miniware/stm32f1xx_it.c @@ -1,5 +1,6 @@ // This is the stock standard STM interrupt file full of handlers #include "stm32f1xx_it.h" +#include "Pins.h" #include "Setup.h" #include "cmsis_os.h" #include "stm32f1xx.h" @@ -11,7 +12,6 @@ extern TIM_HandleTypeDef htim1; // used for the systick /* Cortex-M3 Processor Interruption and Exception Handlers */ /******************************************************************************/ - // Systick is used by FreeRTOS tick void SysTick_Handler(void) { osSystickHandler(); } @@ -29,11 +29,33 @@ void ADC1_2_IRQHandler(void) { HAL_ADC_IRQHandler(&hadc1); } // Timer 1 has overflowed, used for HAL ticks void TIM1_UP_IRQHandler(void) { HAL_TIM_IRQHandler(&htim1); } + // Timer 3 is used for the PWM output to the tip -void TIM3_IRQHandler(void) { HAL_TIM_IRQHandler(&htim3); } +void TIM3_IRQHandler(void) { + TIM_HandleTypeDef *handle = &htimADC; + if (htimTip.Instance == TIM3) { + handle = &htimTip; + } + HAL_TIM_IRQHandler(handle); +} // Timer 2 is used for co-ordination of PWM & ADC -void TIM2_IRQHandler(void) { HAL_TIM_IRQHandler(&htim2); } +void TIM2_IRQHandler(void) { + TIM_HandleTypeDef *handle = &htimADC; + if (htimTip.Instance == TIM2) { + handle = &htimTip; + } + HAL_TIM_IRQHandler(handle); +} + +// Timer 2 is used for co-ordination of PWM & ADC +void TIM4_IRQHandler(void) { + TIM_HandleTypeDef *handle = &htimADC; + if (htimTip.Instance == TIM4) { + handle = &htimTip; + } + HAL_TIM_IRQHandler(handle); +} void I2C1_EV_IRQHandler(void) { HAL_I2C_EV_IRQHandler(&hi2c1); } void I2C1_ER_IRQHandler(void) { HAL_I2C_ER_IRQHandler(&hi2c1); } @@ -41,4 +63,9 @@ void I2C1_ER_IRQHandler(void) { HAL_I2C_ER_IRQHandler(&hi2c1); } void DMA1_Channel6_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma_i2c1_tx); } void DMA1_Channel7_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma_i2c1_rx); } -void EXTI9_5_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9); } + +void EXTI9_5_IRQHandler(void) { +#ifdef INT_PD_Pin + HAL_GPIO_EXTI_IRQHandler(INT_PD_Pin); +#endif +} diff --git a/source/Core/BSP/Miniware/system_stm32f1xx.c b/source/Core/BSP/Miniware/system_stm32f1xx.c index 19a323e4..2fd8e60e 100644 --- a/source/Core/BSP/Miniware/system_stm32f1xx.c +++ b/source/Core/BSP/Miniware/system_stm32f1xx.c @@ -12,12 +12,8 @@ #if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG) /* #define DATA_IN_ExtSRAM */ #endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */ - #ifndef VECT_TAB_OFFSET -#define VECT_TAB_OFFSET \ - 0x00004000U /*!< Vector Table base offset field. \ - This value must be a multiple of 0x200. */ -// We offset this by 0x4000 to because of the bootloader +#error VECT_TAB_OFFSET #endif /******************************************************************************* diff --git a/source/Core/BSP/Sequre_S60/Software_I2C.h b/source/Core/BSP/Sequre_S60/Software_I2C.h index 4c4f5b40..65a51fad 100644 --- a/source/Core/BSP/Sequre_S60/Software_I2C.h +++ b/source/Core/BSP/Sequre_S60/Software_I2C.h @@ -10,14 +10,14 @@ #include "BSP.h" #include "configuration.h" #include "stm32f1xx_hal.h" -#ifdef I2C_SOFT +#ifdef I2C_SOFT_BUS_2 -#define SOFT_SCL_HIGH() HAL_GPIO_WritePin(SCL2_GPIO_Port, SCL2_Pin, GPIO_PIN_SET) -#define SOFT_SCL_LOW() HAL_GPIO_WritePin(SCL2_GPIO_Port, SCL2_Pin, GPIO_PIN_RESET) -#define SOFT_SDA_HIGH() HAL_GPIO_WritePin(SDA2_GPIO_Port, SDA2_Pin, GPIO_PIN_SET) -#define SOFT_SDA_LOW() HAL_GPIO_WritePin(SDA2_GPIO_Port, SDA2_Pin, GPIO_PIN_RESET) -#define SOFT_SDA_READ() (HAL_GPIO_ReadPin(SDA2_GPIO_Port, SDA2_Pin) == GPIO_PIN_SET ? 1 : 0) -#define SOFT_SCL_READ() (HAL_GPIO_ReadPin(SCL2_GPIO_Port, SCL2_Pin) == GPIO_PIN_SET ? 1 : 0) +#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) #define SOFT_I2C_DELAY() \ { \ for (int xx = 0; xx < 12; xx++) { \ diff --git a/source/Core/BSP/Sequre_S60/configuration.h b/source/Core/BSP/Sequre_S60/configuration.h index a624fc01..50ea3d86 100644 --- a/source/Core/BSP/Sequre_S60/configuration.h +++ b/source/Core/BSP/Sequre_S60/configuration.h @@ -155,10 +155,11 @@ #define OLED_128x32 #define GPIO_VIBRATION -#define POW_PD_EXT 1 +#define POW_PD_EXT 1 +#define DEBUG_POWER_MENU_BUTTON_B 1 #define HAS_POWER_DEBUG_MENU #define TEMP_NTC -#define I2C_SOFT // For now we are doing software I2C to get around hardware chip issues +#define I2C_SOFT_BUS_2 // For now we are doing software I2C to get around hardware chip issues #define OLED_I2CBB #define MODEL_HAS_DCDC // We dont have DC/DC but have reallly fast PWM that gets us roughly the same place diff --git a/source/Core/BSP/Sequre_S60/preRTOS.cpp b/source/Core/BSP/Sequre_S60/preRTOS.cpp index f355984e..24bc7707 100644 --- a/source/Core/BSP/Sequre_S60/preRTOS.cpp +++ b/source/Core/BSP/Sequre_S60/preRTOS.cpp @@ -6,7 +6,7 @@ */ #include "BSP.h" -#include "I2CBB.hpp" +#include "I2CBB2.hpp" #include "Pins.h" #include "Setup.h" #include @@ -17,8 +17,8 @@ void preRToSInit() { HAL_Init(); Setup_HAL(); // Setup all the HAL objects BSPInit(); -#ifdef I2C_SOFT - I2CBB::init(); +#ifdef I2C_SOFT_BUS_2 + I2CBB2::init(); #endif /* Init the IPC objects */ FRToSI2C::FRToSInit(); diff --git a/source/Core/Drivers/Font.h b/source/Core/Drivers/Font.h index 7875b3a0..0bd08c82 100644 --- a/source/Core/Drivers/Font.h +++ b/source/Core/Drivers/Font.h @@ -93,7 +93,7 @@ const uint8_t WarningBlock24[] = { 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_TS100) + defined(MODEL_Pinecil) + defined(MODEL_Pinecilv2) > 0 +#if defined(MODEL_TS100) + defined(MODEL_Pinecil) + defined(MODEL_Pinecilv2) +defined(MODEL_TS101) > 0 const uint8_t buttonA[] = { // width = 42 // height = 16 diff --git a/source/Core/Drivers/HUB238.cpp b/source/Core/Drivers/HUB238.cpp index 32fa0ec9..fe5bf52d 100644 --- a/source/Core/Drivers/HUB238.cpp +++ b/source/Core/Drivers/HUB238.cpp @@ -1,20 +1,20 @@ #include "HUB238.hpp" -#include "I2CBB.hpp" +#include "I2CBB2.hpp" #include "Utils.h" #include "configuration.h" #if POW_PD_EXT == 1 -bool hub238_probe() { return I2CBB::probe(HUB238_ADDR); } +bool hub238_probe() { return I2CBB2::probe(HUB238_ADDR); } extern int32_t powerSupplyWattageLimit; uint16_t hub238_debug_state() { uint8_t status0 = 0; uint8_t status1 = 0; - if (!I2CBB::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS0, &status0, 1)) { + if (!I2CBB2::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS0, &status0, 1)) { return 0xFFFF; } - if (!I2CBB::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS1, &status1, 1)) { + if (!I2CBB2::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS1, &status1, 1)) { return 0xFFFF; } return status1 | (((uint16_t)status0) << 8); @@ -81,7 +81,7 @@ uint16_t hub238_getVoltagePDOCurrent(uint8_t voltage) { return 0; } uint8_t temp = 0; - if (I2CBB::Mem_Read(HUB238_ADDR, reg, &temp, 1) == true) { + if (I2CBB2::Mem_Read(HUB238_ADDR, reg, &temp, 1) == true) { if (temp & HUB238_PDO_DETECTED) { return pdo_slot_to_currentx100(temp); } @@ -156,17 +156,17 @@ void hub238_check_negotiation() { uint8_t bestPDO = findBestPDO(); - if (I2CBB::Mem_Read(HUB238_ADDR, HUB238_REG_SRC_PDO, ¤tPDO, 1) == true) { + if (I2CBB2::Mem_Read(HUB238_ADDR, HUB238_REG_SRC_PDO, ¤tPDO, 1) == true) { currentPDO >>= 4; // grab upper bits if (currentPDO == bestPDO) { haveSelected = bestPDO; return; } currentPDO = bestPDO << 4; - if (I2CBB::Mem_Write(HUB238_ADDR, HUB238_REG_SRC_PDO, ¤tPDO, 1) == true) { + if (I2CBB2::Mem_Write(HUB238_ADDR, HUB238_REG_SRC_PDO, ¤tPDO, 1) == true) { currentPDO = 0x01; // request for new PDO - if (I2CBB::Mem_Write(HUB238_ADDR, HUB238_REG_GO_COMMAND, ¤tPDO, 1) == true) { + if (I2CBB2::Mem_Write(HUB238_ADDR, HUB238_REG_GO_COMMAND, ¤tPDO, 1) == true) { haveSelected = bestPDO; vTaskDelay(50); @@ -179,7 +179,7 @@ bool hub238_has_run_selection() { return haveSelected != 0xFF; } bool hub238_has_negotiated() { uint8_t temp = 0; - if (I2CBB::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS1, &temp, 1) == true) { + if (I2CBB2::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS1, &temp, 1) == true) { temp >>= 3; return (temp & 0b111) == 0b001; // success } @@ -189,7 +189,7 @@ bool hub238_has_negotiated() { // Return selected source voltage in V uint16_t hub238_source_voltage() { uint8_t temp = 0; - if (I2CBB::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS0, &temp, 1) == true) { + if (I2CBB2::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS0, &temp, 1) == true) { temp >>= 4; switch (temp) { case 0b0001: @@ -211,7 +211,7 @@ uint16_t hub238_source_voltage() { // Return selected source current in Amps * 100 uint8_t hub238_source_currentX100() { uint8_t temp = 0; - if (I2CBB::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS0, &temp, 1) == true) { + if (I2CBB2::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS0, &temp, 1) == true) { temp &= 0b1111; return pdo_slot_to_currentx100(temp); } diff --git a/source/Core/Drivers/I2CBB1.cpp b/source/Core/Drivers/I2CBB1.cpp new file mode 100644 index 00000000..bda0da18 --- /dev/null +++ b/source/Core/Drivers/I2CBB1.cpp @@ -0,0 +1,317 @@ +/* + * I2CBB1.cpp + * + * Created on: 12 Jun 2020 + * Author: Ralim + */ +#include "configuration.h" +#ifdef I2C_SOFT_BUS_1 +#include "FreeRTOS.h" +#include +SemaphoreHandle_t I2CBB1::I2CSemaphore = NULL; +StaticSemaphore_t I2CBB1::xSemaphoreBuffer; +void I2CBB1::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 = SDA_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + HAL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct); + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; + GPIO_InitStruct.Pin = SCL_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct); + SOFT_SDA1_HIGH(); + SOFT_SCL1_HIGH(); + // To ensure bus is unlocked; we toggle the Clock a bunch of times to make things error out + for (int i = 0; i < 128; i++) { + SOFT_SCL1_LOW(); + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + SOFT_SCL1_HIGH(); + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + } + I2CSemaphore = xSemaphoreCreateMutexStatic(&xSemaphoreBuffer); + unlock(); +} + +bool I2CBB1::probe(uint8_t address) { + if (!lock()) + return false; + start(); + bool ack = send(address); + stop(); + unlock(); + return ack; +} + +bool I2CBB1::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, uint16_t Size) { + if (!lock()) + return false; + start(); + bool ack = send(DevAddress); + if (!ack) { + stop(); + unlock(); + return false; + } + ack = send(MemAddress); + if (!ack) { + stop(); + unlock(); + return false; + } + SOFT_SCL1_LOW(); + SOFT_I2C_DELAY(); + // stop(); + start(); + ack = send(DevAddress | 1); + if (!ack) { + stop(); + unlock(); + return false; + } + while (Size) { + pData[0] = read(Size > 1); + pData++; + Size--; + } + stop(); + unlock(); + return true; +} + +bool I2CBB1::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, const uint8_t *pData, uint16_t Size) { + if (!lock()) + return false; + start(); + bool ack = send(DevAddress); + if (!ack) { + stop(); + unlock(); + return false; + } + ack = send(MemAddress); + if (!ack) { + stop(); + unlock(); + return false; + } + while (Size) { + resetWatchdog(); + ack = send(pData[0]); + if (!ack) { + stop(); + unlock(); + return false; + } + pData++; + Size--; + } + stop(); + unlock(); + return true; +} + +void I2CBB1::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) { + if (!lock()) + return; + start(); + bool ack = send(DevAddress); + if (!ack) { + stop(); + unlock(); + return; + } + while (Size) { + ack = send(pData[0]); + if (!ack) { + stop(); + unlock(); + return; + } + pData++; + Size--; + } + stop(); + unlock(); +} + +void I2CBB1::Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size) { + if (!lock()) + return; + start(); + bool ack = send(DevAddress | 1); + if (!ack) { + stop(); + unlock(); + return; + } + while (Size) { + pData[0] = read(Size > 1); + pData++; + Size--; + } + stop(); + unlock(); +} + +void I2CBB1::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx, uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx) { + if (Size_tx == 0 && Size_rx == 0) + return; + if (lock() == false) + return; + if (Size_tx) { + start(); + bool ack = send(DevAddress); + if (!ack) { + stop(); + unlock(); + return; + } + while (Size_tx) { + ack = send(pData_tx[0]); + if (!ack) { + stop(); + unlock(); + return; + } + pData_tx++; + Size_tx--; + } + } + if (Size_rx) { + start(); + bool ack = send(DevAddress | 1); + if (!ack) { + stop(); + unlock(); + return; + } + while (Size_rx) { + pData_rx[0] = read(Size_rx > 1); + pData_rx++; + Size_rx--; + } + } + stop(); + unlock(); +} + +void I2CBB1::start() { + /* I2C Start condition, data line goes low when clock is high */ + SOFT_SCL1_HIGH(); + SOFT_SDA1_HIGH(); + SOFT_I2C_DELAY(); + SOFT_SDA1_LOW(); + SOFT_I2C_DELAY(); + SOFT_SCL1_LOW(); + SOFT_I2C_DELAY(); + SOFT_SDA1_HIGH(); +} + +void I2CBB1::stop() { + /* I2C Stop condition, clock goes high when data is low */ + SOFT_SDA1_LOW(); + SOFT_I2C_DELAY(); + SOFT_SCL1_HIGH(); + SOFT_I2C_DELAY(); + SOFT_SDA1_HIGH(); + SOFT_I2C_DELAY(); +} + +bool I2CBB1::send(uint8_t value) { + + for (uint8_t i = 0; i < 8; i++) { + write_bit(value & 0x80); // write the most-significant bit + value <<= 1; + } + + SOFT_SDA1_HIGH(); + bool ack = (read_bit() == 0); + return ack; +} + +uint8_t I2CBB1::read(bool ack) { + uint8_t B = 0; + + uint8_t i; + for (i = 0; i < 8; i++) { + B <<= 1; + B |= read_bit(); + } + + SOFT_SDA1_HIGH(); + if (ack) + write_bit(0); + else + write_bit(1); + return B; +} + +uint8_t I2CBB1::read_bit() { + uint8_t b; + + SOFT_SDA1_HIGH(); + SOFT_I2C_DELAY(); + SOFT_SCL1_HIGH(); + SOFT_I2C_DELAY(); + + if (SOFT_SDA1_READ()) + b = 1; + else + b = 0; + + SOFT_SCL1_LOW(); + return b; +} + +void I2CBB1::unlock() { xSemaphoreGive(I2CSemaphore); } + +bool I2CBB1::lock() { + if (I2CSemaphore == NULL) {} + bool a = xSemaphoreTake(I2CSemaphore, (TickType_t)100) == pdTRUE; + return a; +} + +bool I2CBB1::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) { return Mem_Write(address, reg, &data, 1); } + +uint8_t I2CBB1::I2C_RegisterRead(uint8_t address, uint8_t reg) { + uint8_t temp = 0; + Mem_Read(address, reg, &temp, 1); + return temp; +} + +void I2CBB1::write_bit(uint8_t val) { + if (val) { + SOFT_SDA1_HIGH(); + } else { + SOFT_SDA1_LOW(); + } + + SOFT_I2C_DELAY(); + SOFT_SCL1_HIGH(); + SOFT_I2C_DELAY(); + SOFT_SCL1_LOW(); +} + +bool I2CBB1::writeRegistersBulk(const uint8_t address, const I2C_REG *registers, const uint8_t registersLength) { + for (int index = 0; index < registersLength; index++) { + if (!I2C_RegisterWrite(address, registers[index].reg, registers[index].val)) { + return false; + } + if (registers[index].pause_ms) + delay_ms(registers[index].pause_ms); + } + return true; +} +#endif diff --git a/source/Core/Drivers/I2CBB.hpp b/source/Core/Drivers/I2CBB1.hpp similarity index 91% rename from source/Core/Drivers/I2CBB.hpp rename to source/Core/Drivers/I2CBB1.hpp index a66d5954..40656051 100644 --- a/source/Core/Drivers/I2CBB.hpp +++ b/source/Core/Drivers/I2CBB1.hpp @@ -1,14 +1,14 @@ /* - * I2CBB.hpp + * I2CBB1.hpp * * Created on: 12 Jun 2020 * Author: Ralim */ -#ifndef BSP_MINIWARE_I2CBB_HPP_ -#define BSP_MINIWARE_I2CBB_HPP_ +#ifndef BSP_MINIWARE_I2CBB1_HPP_ +#define BSP_MINIWARE_I2CBB1_HPP_ #include "configuration.h" -#ifdef I2C_SOFT +#ifdef I2C_SOFT_BUS_1 #include "BSP.h" #include "FreeRTOS.h" #include "Pins.h" @@ -16,7 +16,7 @@ #include "Software_I2C.h" #include "semphr.h" -class I2CBB { +class I2CBB1 { public: static void init(); // Probe if device ACK's address or not diff --git a/source/Core/Drivers/I2CBB.cpp b/source/Core/Drivers/I2CBB2.cpp similarity index 68% rename from source/Core/Drivers/I2CBB.cpp rename to source/Core/Drivers/I2CBB2.cpp index 25af2882..2d268b49 100644 --- a/source/Core/Drivers/I2CBB.cpp +++ b/source/Core/Drivers/I2CBB2.cpp @@ -1,16 +1,16 @@ /* - * I2CBB.cpp + * I2CBB2.cpp * * Created on: 12 Jun 2020 * Author: Ralim */ #include "configuration.h" -#ifdef I2C_SOFT +#ifdef I2C_SOFT_BUS_2 #include "FreeRTOS.h" -#include -SemaphoreHandle_t I2CBB::I2CSemaphore = NULL; -StaticSemaphore_t I2CBB::xSemaphoreBuffer; -void I2CBB::init() { +#include +SemaphoreHandle_t I2CBB2::I2CSemaphore = NULL; +StaticSemaphore_t I2CBB2::xSemaphoreBuffer; +void I2CBB2::init() { // Set GPIO's to output open drain GPIO_InitTypeDef GPIO_InitStruct; __HAL_RCC_GPIOA_CLK_ENABLE(); @@ -24,16 +24,16 @@ void I2CBB::init() { GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(SCL2_GPIO_Port, &GPIO_InitStruct); - SOFT_SDA_HIGH(); - SOFT_SCL_HIGH(); + SOFT_SDA2_HIGH(); + SOFT_SCL2_HIGH(); // To ensure bus is unlocked; we toggle the Clock a bunch of times to make things error out for (int i = 0; i < 128; i++) { - SOFT_SCL_LOW(); + SOFT_SCL2_LOW(); asm("nop"); asm("nop"); asm("nop"); asm("nop"); - SOFT_SCL_HIGH(); + SOFT_SCL2_HIGH(); asm("nop"); asm("nop"); asm("nop"); @@ -43,7 +43,7 @@ void I2CBB::init() { unlock(); } -bool I2CBB::probe(uint8_t address) { +bool I2CBB2::probe(uint8_t address) { if (!lock()) return false; start(); @@ -53,7 +53,7 @@ bool I2CBB::probe(uint8_t address) { return ack; } -bool I2CBB::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, uint16_t Size) { +bool I2CBB2::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, uint16_t Size) { if (!lock()) return false; start(); @@ -69,7 +69,7 @@ bool I2CBB::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, u unlock(); return false; } - SOFT_SCL_LOW(); + SOFT_SCL2_LOW(); SOFT_I2C_DELAY(); // stop(); start(); @@ -89,7 +89,7 @@ bool I2CBB::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, u return true; } -bool I2CBB::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, const uint8_t *pData, uint16_t Size) { +bool I2CBB2::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, const uint8_t *pData, uint16_t Size) { if (!lock()) return false; start(); @@ -121,7 +121,7 @@ bool I2CBB::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, const uint8_t *p return true; } -void I2CBB::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) { +void I2CBB2::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) { if (!lock()) return; start(); @@ -145,7 +145,7 @@ void I2CBB::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) { unlock(); } -void I2CBB::Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size) { +void I2CBB2::Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size) { if (!lock()) return; start(); @@ -164,7 +164,7 @@ void I2CBB::Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size) { unlock(); } -void I2CBB::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx, uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx) { +void I2CBB2::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx, uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx) { if (Size_tx == 0 && Size_rx == 0) return; if (lock() == false) @@ -206,41 +206,41 @@ void I2CBB::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx, uint16_t Siz unlock(); } -void I2CBB::start() { +void I2CBB2::start() { /* I2C Start condition, data line goes low when clock is high */ - SOFT_SCL_HIGH(); - SOFT_SDA_HIGH(); + SOFT_SCL2_HIGH(); + SOFT_SDA2_HIGH(); SOFT_I2C_DELAY(); - SOFT_SDA_LOW(); + SOFT_SDA2_LOW(); SOFT_I2C_DELAY(); - SOFT_SCL_LOW(); + SOFT_SCL2_LOW(); SOFT_I2C_DELAY(); - SOFT_SDA_HIGH(); + SOFT_SDA2_HIGH(); } -void I2CBB::stop() { +void I2CBB2::stop() { /* I2C Stop condition, clock goes high when data is low */ - SOFT_SDA_LOW(); + SOFT_SDA2_LOW(); SOFT_I2C_DELAY(); - SOFT_SCL_HIGH(); + SOFT_SCL2_HIGH(); SOFT_I2C_DELAY(); - SOFT_SDA_HIGH(); + SOFT_SDA2_HIGH(); SOFT_I2C_DELAY(); } -bool I2CBB::send(uint8_t value) { +bool I2CBB2::send(uint8_t value) { for (uint8_t i = 0; i < 8; i++) { write_bit(value & 0x80); // write the most-significant bit value <<= 1; } - SOFT_SDA_HIGH(); + SOFT_SDA2_HIGH(); bool ack = (read_bit() == 0); return ack; } -uint8_t I2CBB::read(bool ack) { +uint8_t I2CBB2::read(bool ack) { uint8_t B = 0; uint8_t i; @@ -249,7 +249,7 @@ uint8_t I2CBB::read(bool ack) { B |= read_bit(); } - SOFT_SDA_HIGH(); + SOFT_SDA2_HIGH(); if (ack) write_bit(0); else @@ -257,53 +257,53 @@ uint8_t I2CBB::read(bool ack) { return B; } -uint8_t I2CBB::read_bit() { +uint8_t I2CBB2::read_bit() { uint8_t b; - SOFT_SDA_HIGH(); + SOFT_SDA2_HIGH(); SOFT_I2C_DELAY(); - SOFT_SCL_HIGH(); + SOFT_SCL2_HIGH(); SOFT_I2C_DELAY(); - if (SOFT_SDA_READ()) + if (SOFT_SDA2_READ()) b = 1; else b = 0; - SOFT_SCL_LOW(); + SOFT_SCL2_LOW(); return b; } -void I2CBB::unlock() { xSemaphoreGive(I2CSemaphore); } +void I2CBB2::unlock() { xSemaphoreGive(I2CSemaphore); } -bool I2CBB::lock() { +bool I2CBB2::lock() { if (I2CSemaphore == NULL) {} bool a = xSemaphoreTake(I2CSemaphore, (TickType_t)100) == pdTRUE; return a; } -bool I2CBB::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) { return Mem_Write(address, reg, &data, 1); } +bool I2CBB2::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) { return Mem_Write(address, reg, &data, 1); } -uint8_t I2CBB::I2C_RegisterRead(uint8_t address, uint8_t reg) { +uint8_t I2CBB2::I2C_RegisterRead(uint8_t address, uint8_t reg) { uint8_t temp = 0; Mem_Read(address, reg, &temp, 1); return temp; } -void I2CBB::write_bit(uint8_t val) { +void I2CBB2::write_bit(uint8_t val) { if (val) { - SOFT_SDA_HIGH(); + SOFT_SDA2_HIGH(); } else { - SOFT_SDA_LOW(); + SOFT_SDA2_LOW(); } SOFT_I2C_DELAY(); - SOFT_SCL_HIGH(); + SOFT_SCL2_HIGH(); SOFT_I2C_DELAY(); - SOFT_SCL_LOW(); + SOFT_SCL2_LOW(); } -bool I2CBB::writeRegistersBulk(const uint8_t address, const I2C_REG *registers, const uint8_t registersLength) { +bool I2CBB2::writeRegistersBulk(const uint8_t address, const I2C_REG *registers, const uint8_t registersLength) { for (int index = 0; index < registersLength; index++) { if (!I2C_RegisterWrite(address, registers[index].reg, registers[index].val)) { return false; diff --git a/source/Core/Drivers/I2CBB2.hpp b/source/Core/Drivers/I2CBB2.hpp new file mode 100644 index 00000000..389a6a63 --- /dev/null +++ b/source/Core/Drivers/I2CBB2.hpp @@ -0,0 +1,53 @@ +/* + * I2CBB2.hpp + * + * Created on: 12 Jun 2020 + * Author: Ralim + */ + +#ifndef BSP_MINIWARE_I2CBB2_HPP_ +#define BSP_MINIWARE_I2CBB2_HPP_ +#include "configuration.h" +#ifdef I2C_SOFT_BUS_2 +#include "BSP.h" +#include "FreeRTOS.h" +#include "Pins.h" +#include "Setup.h" +#include "Software_I2C.h" +#include "semphr.h" + +class I2CBB2 { +public: + static void init(); + // Probe if device ACK's address or not + static bool probe(uint8_t address); + // Issues a complete 8bit register read + static bool Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, uint16_t Size); + // Implements a register write + static bool Mem_Write(uint16_t DevAddress, uint16_t MemAddress, const uint8_t *pData, uint16_t Size); + static void Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size); + static void Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size); + static void TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx, uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx); + static bool I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data); + static uint8_t I2C_RegisterRead(uint8_t address, uint8_t reg); + typedef struct { + const uint8_t reg; // The register to write to + uint8_t val; // The value to write to this register + const uint8_t pause_ms; // How many ms to pause _after_ writing this reg + } I2C_REG; + static bool writeRegistersBulk(const uint8_t address, const I2C_REG *registers, const uint8_t registersLength); + +private: + static SemaphoreHandle_t I2CSemaphore; + static StaticSemaphore_t xSemaphoreBuffer; + static void unlock(); + static bool lock(); + static void start(); + static void stop(); + static bool send(uint8_t value); + static uint8_t read(bool ack); + static uint8_t read_bit(); + static void write_bit(uint8_t val); +}; +#endif +#endif /* BSP_MINIWARE_I2CBB_HPP_ */ diff --git a/source/Core/Drivers/LIS2DH12.cpp b/source/Core/Drivers/LIS2DH12.cpp index a75f8028..2abb0216 100644 --- a/source/Core/Drivers/LIS2DH12.cpp +++ b/source/Core/Drivers/LIS2DH12.cpp @@ -10,26 +10,26 @@ #include "LIS2DH12.hpp" #include "cmsis_os.h" -static const FRToSI2C::I2C_REG i2c_registers[] = {{LIS_CTRL_REG1, 0x17, 0}, // 25Hz - {LIS_CTRL_REG2, 0b00001000, 0}, // Highpass filter off - {LIS_CTRL_REG3, 0b01100000, 0}, // Setup interrupt pins - {LIS_CTRL_REG4, 0b00001000, 0}, // Block update mode off, HR on - {LIS_CTRL_REG5, 0b00000010, 0}, // - {LIS_CTRL_REG6, 0b01100010, 0}, - // Basically setup the unit to run, and enable 4D orientation detection - {LIS_INT2_CFG, 0b01111110, 0}, // setup for movement detection - {LIS_INT2_THS, 0x28, 0}, // - {LIS_INT2_DURATION, 64, 0}, // - {LIS_INT1_CFG, 0b01111110, 0}, // - {LIS_INT1_THS, 0x28, 0}, // - {LIS_INT1_DURATION, 64, 0}}; +static const ACCEL_I2C_CLASS::I2C_REG i2c_registers[] = {{LIS_CTRL_REG1, 0x17, 0}, // 25Hz + {LIS_CTRL_REG2, 0b00001000, 0}, // Highpass filter off + {LIS_CTRL_REG3, 0b01100000, 0}, // Setup interrupt pins + {LIS_CTRL_REG4, 0b00001000, 0}, // Block update mode off, HR on + {LIS_CTRL_REG5, 0b00000010, 0}, // + {LIS_CTRL_REG6, 0b01100010, 0}, + // Basically setup the unit to run, and enable 4D orientation detection + {LIS_INT2_CFG, 0b01111110, 0}, // setup for movement detection + {LIS_INT2_THS, 0x28, 0}, // + {LIS_INT2_DURATION, 64, 0}, // + {LIS_INT1_CFG, 0b01111110, 0}, // + {LIS_INT1_THS, 0x28, 0}, // + {LIS_INT1_DURATION, 64, 0}}; -bool LIS2DH12::initalize() { return FRToSI2C::writeRegistersBulk(LIS2DH_I2C_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0])); } +bool LIS2DH12::initalize() { return ACCEL_I2C_CLASS::writeRegistersBulk(LIS2DH_I2C_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0])); } void LIS2DH12::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) { std::array sensorData; - FRToSI2C::Mem_Read(LIS2DH_I2C_ADDRESS, 0xA8, reinterpret_cast(sensorData.begin()), sensorData.size() * sizeof(int16_t)); + ACCEL_I2C_CLASS::Mem_Read(LIS2DH_I2C_ADDRESS, 0xA8, reinterpret_cast(sensorData.begin()), sensorData.size() * sizeof(int16_t)); x = sensorData[0]; y = sensorData[1]; @@ -37,13 +37,21 @@ void LIS2DH12::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) { } bool LIS2DH12::detect() { - if (!FRToSI2C::probe(LIS2DH_I2C_ADDRESS)) { + if (!ACCEL_I2C_CLASS::probe(LIS2DH_I2C_ADDRESS)) { return false; } // Read chip id to ensure its not an address collision uint8_t id = 0; - if (FRToSI2C::Mem_Read(LIS2DH_I2C_ADDRESS, LIS2DH_WHOAMI_REG, &id, 1)) { - return id == LIS2DH_WHOAMI_ID; + if (ACCEL_I2C_CLASS::Mem_Read(LIS2DH_I2C_ADDRESS, LIS2DH_WHOAMI_REG, &id, 1)) { + return (id == LIS2DH_WHOAMI_ID) || (id == LIS2DH_CLONE_WHOAMI_ID); } return false; // cant read ID } + +bool LIS2DH12::isClone() { + uint8_t id = 0; + if (ACCEL_I2C_CLASS::Mem_Read(LIS2DH_I2C_ADDRESS, LIS2DH_WHOAMI_REG, &id, 1)) { + return (id == LIS2DH_CLONE_WHOAMI_ID); + } + return false; +} \ No newline at end of file diff --git a/source/Core/Drivers/LIS2DH12.hpp b/source/Core/Drivers/LIS2DH12.hpp index eca1cd0d..edb268b8 100644 --- a/source/Core/Drivers/LIS2DH12.hpp +++ b/source/Core/Drivers/LIS2DH12.hpp @@ -8,17 +8,19 @@ #ifndef LIS2DH12_HPP_ #define LIS2DH12_HPP_ #include "BSP.h" -#include "I2C_Wrapper.hpp" + #include "LIS2DH12_defines.hpp" +#include "accelerometers_common.h" class LIS2DH12 { public: static bool detect(); + static bool isClone(); static bool initalize(); // 1 = rh, 2,=lh, 8=flat static Orientation getOrientation() { #ifdef LIS_ORI_FLIP - uint8_t val = (FRToSI2C::I2C_RegisterRead(LIS2DH_I2C_ADDRESS, LIS_INT2_SRC) >> 2); + uint8_t val = (ACCEL_I2C_CLASS::I2C_RegisterRead(LIS2DH_I2C_ADDRESS, LIS_INT2_SRC) >> 2); if (val == 8) val = 3; else if (val == 1) @@ -29,7 +31,7 @@ public: val = 3; return static_cast(val); #else - return static_cast((FRToSI2C::I2C_RegisterRead(LIS2DH_I2C_ADDRESS, LIS_INT2_SRC) >> 2) - 1); + return static_cast((ACCEL_I2C_CLASS::I2C_RegisterRead(LIS2DH_I2C_ADDRESS, LIS_INT2_SRC) >> 2) - 1); #endif } static void getAxisReadings(int16_t &x, int16_t &y, int16_t &z); diff --git a/source/Core/Drivers/LIS2DH12_defines.hpp b/source/Core/Drivers/LIS2DH12_defines.hpp index 99053f84..a907f405 100644 --- a/source/Core/Drivers/LIS2DH12_defines.hpp +++ b/source/Core/Drivers/LIS2DH12_defines.hpp @@ -11,6 +11,7 @@ #define LIS2DH_I2C_ADDRESS (25 << 1) #define LIS2DH_WHOAMI_REG 0x0F #define LIS2DH_WHOAMI_ID (0b00110011) +#define LIS2DH_CLONE_WHOAMI_ID 0x11 #define LIS_CTRL_REG1 0x20 | 0x80 #define LIS_CTRL_REG2 0x21 | 0x80 #define LIS_CTRL_REG3 0x22 | 0x80 diff --git a/source/Core/Drivers/OLED.hpp b/source/Core/Drivers/OLED.hpp index 8574d0bf..fc35ebc6 100644 --- a/source/Core/Drivers/OLED.hpp +++ b/source/Core/Drivers/OLED.hpp @@ -24,9 +24,12 @@ extern "C" { } #endif -#ifdef OLED_I2CBB -#include "I2CBB.hpp" -#define I2C_CLASS I2CBB +#if defined(OLED_I2CBB2) +#include "I2CBB2.hpp" +#define I2C_CLASS I2CBB2 +#elif defined(OLED_I2CBB1) +#include "I2CBB1.hpp" +#define I2C_CLASS I2CBB1 #else #define I2C_CLASS FRToSI2C #include "I2C_Wrapper.hpp" @@ -44,7 +47,8 @@ extern "C" { #define OLED_VCOM_LAYOUT 0x12 #define OLED_SEGMENT_MAP_REVERSED -#warning "S60 Not fully supported" + +#warning "128x32 OLED's Not fully supported" #else #define OLED_WIDTH 96 #define OLED_HEIGHT 16 diff --git a/source/Core/Drivers/accelerometers_common.h b/source/Core/Drivers/accelerometers_common.h new file mode 100644 index 00000000..8c0f1aa9 --- /dev/null +++ b/source/Core/Drivers/accelerometers_common.h @@ -0,0 +1,15 @@ +#ifndef CORE_DRIVERS_ACCELEROMTERS_COMMON_H_ +#define CORE_DRIVERS_ACCELEROMTERS_COMMON_H_ + +#if defined(ACCEL_I2CBB2) +#include "I2CBB2.hpp" +#define ACCEL_I2C_CLASS I2CBB2 +#elif defined(ACCEL_I2CBB1) +#include "I2CBB1.hpp" +#define ACCEL_I2C_CLASS I2CBB1 +#else +#include "I2C_Wrapper.hpp" +#define ACCEL_I2C_CLASS FRToSI2C +#endif + +#endif \ No newline at end of file diff --git a/source/Core/Inc/main.hpp b/source/Core/Inc/main.hpp index ed65a108..bd2eef41 100644 --- a/source/Core/Inc/main.hpp +++ b/source/Core/Inc/main.hpp @@ -25,14 +25,15 @@ extern TickType_t lastMovementTime; } // Accelerometer type enum class AccelType { - Scanning = 0, - None = 1, - MMA = 2, - LIS = 3, - BMA = 4, - MSA = 5, - SC7 = 6, - GPIO = 7, + Scanning = 0, + None = 1, + MMA = 2, + LIS = 3, + BMA = 4, + MSA = 5, + SC7 = 6, + GPIO = 7, + LIS_CLONE = 8, }; extern AccelType DetectedAccelerometerVersion; diff --git a/source/Core/Threads/GUIThread.cpp b/source/Core/Threads/GUIThread.cpp index 235656a3..97b0eddc 100644 --- a/source/Core/Threads/GUIThread.cpp +++ b/source/Core/Threads/GUIThread.cpp @@ -9,7 +9,7 @@ extern "C" { } #include "BootLogo.h" #include "Buttons.hpp" -#include "I2CBB.hpp" +#include "I2CBB2.hpp" #include "LIS2DH12.hpp" #include "MMA8652FC.hpp" #include "OLED.hpp" @@ -50,14 +50,13 @@ void startGUITask(void const *argument) { OLED::setRotation(getSettingValue(SettingsOptions::OrientationMode) & 1); // If the front button is held down, on supported devices, show PD debugging metrics #ifdef HAS_POWER_DEBUG_MENU -#ifdef POW_PD +#ifdef DEBUG_POWER_MENU_BUTTON_B + if (getButtonB()) { +#else if (getButtonA()) { #endif -#if POW_PD_EXT == 1 - if (getButtonB()) { -#endif - showPDDebug(); - } + showPDDebug(); + } #endif if (getSettingValue(SettingsOptions::CalibrateCJC) > 0) { diff --git a/source/Core/Threads/MOVThread.cpp b/source/Core/Threads/MOVThread.cpp index 1dea9881..456266bd 100644 --- a/source/Core/Threads/MOVThread.cpp +++ b/source/Core/Threads/MOVThread.cpp @@ -12,6 +12,7 @@ #include "LIS2DH12.hpp" #include "MMA8652FC.hpp" #include "MSA301.h" +#include "Pins.h" #include "QC3.h" #include "SC7A20.hpp" #include "Settings.h" @@ -43,7 +44,11 @@ void detectAccelerometerVersion() { if (LIS2DH12::detect()) { // Setup the ST Accelerometer if (LIS2DH12::initalize()) { - DetectedAccelerometerVersion = AccelType::LIS; + if (LIS2DH12::isClone()) { + DetectedAccelerometerVersion = AccelType::LIS_CLONE; + } else { + DetectedAccelerometerVersion = AccelType::LIS; + } return; } } @@ -95,7 +100,7 @@ inline void readAccelerometer(int16_t &tx, int16_t &ty, int16_t &tz, Orientation } else #endif #ifdef ACCEL_LIS - if (DetectedAccelerometerVersion == AccelType::LIS) { + if (DetectedAccelerometerVersion == AccelType::LIS || DetectedAccelerometerVersion == AccelType::LIS_CLONE) { LIS2DH12::getAxisReadings(tx, ty, tz); rotation = LIS2DH12::getOrientation(); } else diff --git a/source/Core/Threads/OperatingModes/ShowStartupWarnings.cpp b/source/Core/Threads/OperatingModes/ShowStartupWarnings.cpp index 5f04e758..5fc67ef9 100644 --- a/source/Core/Threads/OperatingModes/ShowStartupWarnings.cpp +++ b/source/Core/Threads/OperatingModes/ShowStartupWarnings.cpp @@ -18,6 +18,7 @@ void showWarnings(void) { // So only show first 2 times while (DetectedAccelerometerVersion == AccelType::Scanning) { osDelay(5); + resetWatchdog(); } // Display alert if accelerometer is not detected if (DetectedAccelerometerVersion == AccelType::None) { @@ -29,6 +30,7 @@ void showWarnings(void) { } #ifdef POW_PD // We expect pd to be present + resetWatchdog(); if (!USBPowerDelivery::fusbPresent()) { if (getSettingValue(SettingsOptions::PDMissingWarningCounter) < 2) { nextSettingValue(SettingsOptions::PDMissingWarningCounter); @@ -36,7 +38,7 @@ void showWarnings(void) { warnUser(translatedString(Tr->NoPowerDeliveryMessage), 10 * TICKS_SECOND); } } -#endif +#endif /*POW_PD*/ #if POW_PD_EXT == 1 if (!hub238_probe()) { if (getSettingValue(SettingsOptions::PDMissingWarningCounter) < 2) { @@ -45,6 +47,6 @@ void showWarnings(void) { warnUser(translatedString(Tr->NoPowerDeliveryMessage), 10 * TICKS_SECOND); } } -#endif -#endif +#endif /*POW_PD_EXT==1*/ +#endif /*NO_WARN_MISSING*/ } \ No newline at end of file diff --git a/source/Makefile b/source/Makefile index 6c104c88..ddbf4ed8 100644 --- a/source/Makefile +++ b/source/Makefile @@ -2,7 +2,7 @@ ifndef model model:=Pinecil endif -ALL_MINIWARE_MODELS=TS100 TS80 TS80P +ALL_MINIWARE_MODELS=TS100 TS80 TS80P TS101 ALL_PINECIL_MODELS=Pinecil ALL_PINECIL_V2_MODELS=Pinecilv2 ALL_MHP30_MODELS=MHP30 @@ -189,6 +189,16 @@ DEVICE_INCLUDES = -I$(MINIWARE_INC_DIR) \ DEVICE_BSP_DIR = ./Core/BSP/Miniware S_SRCS := $(shell find $(MINIWARE_STARTUP_DIR) -type f -name '*.S') LDSCRIPT=$(MINIWARE_LD_FILE) +ifeq ($(model),$(filter $(model),TS101)) +flash_size=126k +bootldr_size=0x8000 +DEVICE_DFU_ADDRESS=0x08008000 +else +flash_size=62k +bootldr_size=0x4000 +DEVICE_DFU_ADDRESS=0x08004000 +endif + DEV_GLOBAL_DEFS= -D STM32F103T8Ux -D STM32F1 -D STM32 -D USE_HAL_DRIVER -D STM32F103xB -D USE_RTOS_SYSTICK -D GCC_ARMCM3 \ -D ARM_MATH_CM3 \ -D STM32F10X_MD -finline-limit=9999999 @@ -199,9 +209,6 @@ DEV_CXXFLAGS= CPUFLAGS= -mcpu=cortex-m3 \ -mthumb \ -mfloat-abi=soft -flash_size=62k -bootldr_size=0x4000 -DEVICE_DFU_ADDRESS=0x08004000 DEVICE_DFU_VID_PID=0x1209:0xDB42 endif ifeq ($(model),$(filter $(model),$(ALL_SEQURE_MODELS))) diff --git a/source/build.sh b/source/build.sh index b9538f12..902618c5 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") +AVAILABLE_MODELS=("TS100" "TS80" "TS80P" "Pinecil" "MHP30" "Pinecilv2" "S60" "TS101") BUILD_MODELS=() builder_info() {