Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
59a7e8c
Add and rename the Config files for IVY VESCs
TaixiLu Aug 10, 2024
458fddb
Edit the VIN in resister value of 100V versions
TaixiLu Aug 10, 2024
706e054
modified hw_IVY_80V_MINI.h
TaixiLu Aug 27, 2024
8e4a2ce
Merge branch 'vedderb:master' into master
TaixiLu Aug 27, 2024
6a5f670
Remove unnecessary Preprocessor commands
TaixiLu Sep 9, 2024
33b2b28
add boards, change deadtime
TaixiLu Jan 21, 2025
07903e2
Ivy Test
Jul 25, 2025
ce32510
Merge branch 'vedderb:master' into master
TaixiLu Jul 25, 2025
09c90f9
IVY Test board
Jul 25, 2025
4c08f0f
Merge branch 'master' of https://github.com/TaixiLu/bldc
Jul 25, 2025
4719736
IVY Test: add in curr sensor
Jul 25, 2025
7d77606
Add Kalman filter for input current sensor
Jul 30, 2025
d8bf1f7
fix input current sensor bug
Dec 1, 2025
83dc4b4
disable input current sensor for IVY_Test
Dec 1, 2025
7e19ea9
Add PPM throttle + ADC2 brake custom app for mksesc_100_300_hp
Jun 6, 2026
cae50c2
mksesc_100_300_hp: SmartSkate V7 hardware limit tuning
Jun 6, 2026
ac58095
Rename custom app app_ppm_brake -> app_ppm_adc_brake
Jun 6, 2026
448557a
app_ppm_adc_brake: add ppm_adc_dbg terminal command + USE_ADC1_GAIN s…
Jun 6, 2026
55699a8
app_adc: report live ADC pin voltage when the ADC app is not running
Jun 6, 2026
a22d8b0
Revert app_adc live-voltage change; keep all mods in app_ppm_adc_brake
Jun 6, 2026
a897d3a
app_ppm_adc_brake: add Experiment-plot streaming (ppm_adc_plot)
Jun 6, 2026
d661dad
app_ppm_adc_brake: fix PPM full-travel mapping; add USE_ADC2_BRAKE; b…
Jun 6, 2026
00dfc3b
app_ppm_adc_brake: fix timeout deadlock (needed VESC Tool); add safe-…
Jun 6, 2026
fef4fc5
mksesc_100_300_hp: dead time 300 -> 400 ns (SmartSkate V7)
Jun 6, 2026
d15b362
Add .clang-format DisableFormat guard
Jun 6, 2026
e1424b6
app_ppm_adc_brake: latch power ratio (ADC1) + reverse at standstill only
Jul 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# VESC firmware uses tab indentation and is NOT clang-formatted upstream
# (vedderb/bldc). DisableFormat makes clang-format leave files untouched, so
# editors with "format on save" stop churning whitespace in shared files -
# which otherwise produces huge noisy diffs and constant merge conflicts.
#
# Remove this file only if you deliberately want to reformat the whole tree.
DisableFormat: true
557 changes: 557 additions & 0 deletions applications/app_ppm_adc_brake.c

Large diffs are not rendered by default.

270 changes: 270 additions & 0 deletions hwconf/IVY_Esk8/650_330/hw_650_330.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
/*
Copyright 2018 Benjamin Vedder benjamin@vedder.se
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

// V2

#include "hw.h"
#include "hw_650_330.h"

#include "ch.h"
#include "hal.h"
#include "stm32f4xx_conf.h"
#include "utils.h"
#include <math.h>
#include "mc_interface.h"

// Variables
static volatile bool i2c_running = false;
static mutex_t shutdown_mutex;
static float bt_diff = 0.0;

// I2C configuration
static const I2CConfig i2cfg = {
OPMODE_I2C,
100000,
STD_DUTY_CYCLE};

void hw_init_gpio(void)
{
chMtxObjectInit(&shutdown_mutex);
// GPIO clock enable
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

// LEDs
palSetPadMode(LED_GREEN_GPIO, LED_GREEN_PIN,
PAL_MODE_OUTPUT_PUSHPULL |
PAL_STM32_OSPEED_HIGHEST);
palSetPadMode(LED_RED_GPIO, LED_RED_PIN,
PAL_MODE_OUTPUT_PUSHPULL |
PAL_STM32_OSPEED_HIGHEST);

// GPIOA Configuration: Channel 1 to 3 as alternate function push-pull
palSetPadMode(GPIOA, 8, PAL_MODE_ALTERNATE(GPIO_AF_TIM1) | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUDR_FLOATING);
palSetPadMode(GPIOA, 9, PAL_MODE_ALTERNATE(GPIO_AF_TIM1) | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUDR_FLOATING);
palSetPadMode(GPIOA, 10, PAL_MODE_ALTERNATE(GPIO_AF_TIM1) | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUDR_FLOATING);

palSetPadMode(GPIOB, 13, PAL_MODE_ALTERNATE(GPIO_AF_TIM1) | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUDR_FLOATING);
palSetPadMode(GPIOB, 14, PAL_MODE_ALTERNATE(GPIO_AF_TIM1) | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUDR_FLOATING);
palSetPadMode(GPIOB, 15, PAL_MODE_ALTERNATE(GPIO_AF_TIM1) | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUDR_FLOATING);

// Hall sensors
palSetPadMode(HW_HALL_ENC_GPIO1, HW_HALL_ENC_PIN1, PAL_MODE_INPUT_PULLUP);
palSetPadMode(HW_HALL_ENC_GPIO2, HW_HALL_ENC_PIN2, PAL_MODE_INPUT_PULLUP);
palSetPadMode(HW_HALL_ENC_GPIO3, HW_HALL_ENC_PIN3, PAL_MODE_INPUT_PULLUP);

#ifdef HW_HAS_PHASE_FILTERS
// Phase filters
palSetPadMode(PHASE_FILTER_GPIO, PHASE_FILTER_PIN,
PAL_MODE_OUTPUT_PUSHPULL |
PAL_STM32_OSPEED_HIGHEST);
PHASE_FILTER_OFF();
#endif

#ifdef HW_HAS_CURR_FILTERS
// Current filter
palSetPadMode(GPIOD, 2,
PAL_MODE_OUTPUT_PUSHPULL |
PAL_STM32_OSPEED_HIGHEST);

CURRENT_FILTER_OFF();
#endif

// AUX pin
// AUX_OFF();
// palSetPadMode(AUX_GPIO, AUX_PIN,
// PAL_MODE_OUTPUT_PUSHPULL |
// PAL_STM32_OSPEED_HIGHEST);

// ADC Pins
palSetPadMode(GPIOA, 0, PAL_MODE_INPUT_ANALOG);
palSetPadMode(GPIOA, 1, PAL_MODE_INPUT_ANALOG);
palSetPadMode(GPIOA, 2, PAL_MODE_INPUT_ANALOG);
palSetPadMode(GPIOA, 3, PAL_MODE_INPUT_ANALOG);
palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG);
palSetPadMode(GPIOA, 6, PAL_MODE_INPUT_ANALOG);

palSetPadMode(GPIOB, 0, PAL_MODE_INPUT_ANALOG);
palSetPadMode(GPIOB, 1, PAL_MODE_INPUT_ANALOG);

palSetPadMode(GPIOC, 0, PAL_MODE_INPUT_ANALOG);
palSetPadMode(GPIOC, 1, PAL_MODE_INPUT_ANALOG);
palSetPadMode(GPIOC, 2, PAL_MODE_INPUT_ANALOG);
palSetPadMode(GPIOC, 3, PAL_MODE_INPUT_ANALOG);
palSetPadMode(GPIOC, 4, PAL_MODE_INPUT_ANALOG);
}

void hw_setup_adc_channels(void)
{
// ADC1 regular channels
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 2, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 3, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 4, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_Vrefint, 5, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 6, ADC_SampleTime_15Cycles);

// ADC2 regular channels
ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 2, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_6, 3, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_15, 4, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_0, 5, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_9, 6, ADC_SampleTime_15Cycles);

// ADC3 regular channels
ADC_RegularChannelConfig(ADC3, ADC_Channel_2, 1, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 2, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC3, ADC_Channel_3, 3, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC3, ADC_Channel_13, 4, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC3, ADC_Channel_1, 5, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC3, ADC_Channel_2, 6, ADC_SampleTime_15Cycles);

// Injected channels
ADC_InjectedChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_15Cycles);
ADC_InjectedChannelConfig(ADC2, ADC_Channel_11, 1, ADC_SampleTime_15Cycles);
ADC_InjectedChannelConfig(ADC3, ADC_Channel_12, 1, ADC_SampleTime_15Cycles);
ADC_InjectedChannelConfig(ADC1, ADC_Channel_10, 2, ADC_SampleTime_15Cycles);
ADC_InjectedChannelConfig(ADC2, ADC_Channel_11, 2, ADC_SampleTime_15Cycles);
ADC_InjectedChannelConfig(ADC3, ADC_Channel_12, 2, ADC_SampleTime_15Cycles);
ADC_InjectedChannelConfig(ADC1, ADC_Channel_10, 3, ADC_SampleTime_15Cycles);
ADC_InjectedChannelConfig(ADC2, ADC_Channel_11, 3, ADC_SampleTime_15Cycles);
ADC_InjectedChannelConfig(ADC3, ADC_Channel_12, 3, ADC_SampleTime_15Cycles);
}

void hw_start_i2c(void)
{
i2cAcquireBus(&HW_I2C_DEV);

if (!i2c_running)
{
palSetPadMode(HW_I2C_SCL_PORT, HW_I2C_SCL_PIN,
PAL_MODE_ALTERNATE(HW_I2C_GPIO_AF) |
PAL_STM32_OTYPE_OPENDRAIN |
PAL_STM32_OSPEED_MID1 |
PAL_STM32_PUDR_PULLUP);
palSetPadMode(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN,
PAL_MODE_ALTERNATE(HW_I2C_GPIO_AF) |
PAL_STM32_OTYPE_OPENDRAIN |
PAL_STM32_OSPEED_MID1 |
PAL_STM32_PUDR_PULLUP);

i2cStart(&HW_I2C_DEV, &i2cfg);
i2c_running = true;
}

i2cReleaseBus(&HW_I2C_DEV);
}

void hw_stop_i2c(void)
{
i2cAcquireBus(&HW_I2C_DEV);

if (i2c_running)
{
palSetPadMode(HW_I2C_SCL_PORT, HW_I2C_SCL_PIN, PAL_MODE_INPUT);
palSetPadMode(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN, PAL_MODE_INPUT);

i2cStop(&HW_I2C_DEV);
i2c_running = false;
}

i2cReleaseBus(&HW_I2C_DEV);
}

/**
* Try to restore the i2c bus
*/
void hw_try_restore_i2c(void)
{
if (i2c_running)
{
i2cAcquireBus(&HW_I2C_DEV);

palSetPadMode(HW_I2C_SCL_PORT, HW_I2C_SCL_PIN,
PAL_STM32_OTYPE_OPENDRAIN |
PAL_STM32_OSPEED_MID1 |
PAL_STM32_PUDR_PULLUP);

palSetPadMode(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN,
PAL_STM32_OTYPE_OPENDRAIN |
PAL_STM32_OSPEED_MID1 |
PAL_STM32_PUDR_PULLUP);

palSetPad(HW_I2C_SCL_PORT, HW_I2C_SCL_PIN);
palSetPad(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN);

chThdSleep(1);

for (int i = 0; i < 16; i++)
{
palClearPad(HW_I2C_SCL_PORT, HW_I2C_SCL_PIN);
chThdSleep(1);
palSetPad(HW_I2C_SCL_PORT, HW_I2C_SCL_PIN);
chThdSleep(1);
}

// Generate start then stop condition
palClearPad(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN);
chThdSleep(1);
palClearPad(HW_I2C_SCL_PORT, HW_I2C_SCL_PIN);
chThdSleep(1);
palSetPad(HW_I2C_SCL_PORT, HW_I2C_SCL_PIN);
chThdSleep(1);
palSetPad(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN);

palSetPadMode(HW_I2C_SCL_PORT, HW_I2C_SCL_PIN,
PAL_MODE_ALTERNATE(HW_I2C_GPIO_AF) |
PAL_STM32_OTYPE_OPENDRAIN |
PAL_STM32_OSPEED_MID1 |
PAL_STM32_PUDR_PULLUP);

palSetPadMode(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN,
PAL_MODE_ALTERNATE(HW_I2C_GPIO_AF) |
PAL_STM32_OTYPE_OPENDRAIN |
PAL_STM32_OSPEED_MID1 |
PAL_STM32_PUDR_PULLUP);

HW_I2C_DEV.state = I2C_STOP;
i2cStart(&HW_I2C_DEV, &i2cfg);

i2cReleaseBus(&HW_I2C_DEV);
}
}

bool hw_sample_shutdown_button(void)
{
chMtxLock(&shutdown_mutex);

bt_diff = 0.0;

for (int i = 0; i < 3; i++)
{
palSetPadMode(HW_SHUTDOWN_GPIO, HW_SHUTDOWN_PIN, PAL_MODE_INPUT_ANALOG);
chThdSleep(5);
float val1 = ADC_VOLTS(ADC_IND_SHUTDOWN);
chThdSleepMilliseconds(1);
float val2 = ADC_VOLTS(ADC_IND_SHUTDOWN);
palSetPadMode(HW_SHUTDOWN_GPIO, HW_SHUTDOWN_PIN, PAL_MODE_OUTPUT_PUSHPULL);
chThdSleepMilliseconds(1);

bt_diff += (val1 - val2);
}

chMtxUnlock(&shutdown_mutex);

return (bt_diff > 0.12);
}
Loading