Skip to content

Commit

Permalink
Firmware revision 2
Browse files Browse the repository at this point in the history
+ Temperature/voltage/current protection
+ Analog input
+ Extended DSHOT telemetry
+ iBUS/S.Port telemetry
+ KISS auto telemetry
+ Proper turtle mode
+ 250ms zero throttle arming interval
+ DSHOT/serial link recovery
+ DSHOT commands for changing "timing" and "duty_ramp"
+ CLI audio feedback mode
+ LED control

Bootloader revision 2
+ Flash write protection

Support for AT32F421 and GD32E230
G071 hardware comp blanking
G071 PA2 input
Swap functions of IWDG and WWDG
Always use input pull-up
Calibrate throttle within 6.25% margin
Bug fixes, optimizations and cosmetics
Refactored target names
Default dead time 750ns (550ns MCU + 200ns FD6288)
Drop LTO
  • Loading branch information
neoxic committed May 16, 2023
1 parent 50f36ec commit 9ea8014
Show file tree
Hide file tree
Showing 37 changed files with 2,437 additions and 826 deletions.
30 changes: 23 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@ set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_C_FLAGS "-Os -g")
set(CMAKE_C_FLAGS_DEBUG "-O0")
set(CMAKE_C_FLAGS_DEBUG "-Og")
set(OBJCOPY arm-none-eabi-objcopy)
if(NOT CMAKE_BUILD_TYPE MATCHES "^(DEBUG|Debug)$") # Enable LTO
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
endif()
if(UNIX AND NOT CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) # Use 'CMAKE_INSTALL_PREFIX' as alternative root
set(CMAKE_PREFIX_PATH ${CMAKE_INSTALL_PREFIX})
include(GNUInstallDirs)
Expand All @@ -21,7 +18,7 @@ add_compile_options(-ffreestanding -ffunction-sections -fdata-sections -fsingle-
-Wno-variadic-macros -Wno-unused-result -Wno-unused-parameter)
add_link_options(-nostartfiles -Wl,--gc-sections)

function(add_target mcu name)
function(add_target name mcu)
include(mcu/${mcu}/config.cmake)
file(READ src/main.c main_c)
string(REGEX MATCH "REVISION [0-9]+" rev ${main_c})
Expand All @@ -43,9 +40,28 @@ function(add_target mcu name)
DEPENDS ${elf}
)
add_custom_target(${name} ALL DEPENDS ${hex})
add_custom_target(flash-${name} COMMAND ${FLASH} --reset --connect-under-reset --format ihex write ${hex} DEPENDS ${hex})
if(mcu MATCHES "^STM32")
add_custom_target(flash-${name} COMMAND ${FLASH} --reset --connect-under-reset --format ihex write ${hex} DEPENDS ${hex})
endif()
endfunction()

add_subdirectory(boot)

include(targets.cmake)
add_target(AIKON1 STM32G071 DEAD_TIME=35 COMP_MAP=213 IO_PA6)
add_target(AIRBOT1 AT32F421 DEAD_TIME=66 COMP_MAP=321 SENS_MAP=0xA3A6 VOLT_MUL=74 CURR_MUL=20 LED_MAP=0xA15B3B4)
add_target(EMAX1 STM32F051 DEAD_TIME=26 COMP_MAP=123 IO_PA2)
add_target(HAKRC1 STM32F051 DEAD_TIME=26 COMP_MAP=213 SENS_MAP=0xA3 VOLT_MUL=110 LED_MAP=0xA15B5B3 LED_INV)
add_target(HAKRC2 AT32F421 DEAD_TIME=66 COMP_MAP=213 SENS_MAP=0xA3 VOLT_MUL=110 LED_MAP=0xA15B5B3 LED_INV)
add_target(HGLRC1 STM32F051 DEAD_TIME=26 COMP_MAP=123 SENS_MAP=0xA6 VOLT_MUL=210 IO_PA2)
add_target(IFLIGHT1 STM32F051 DEAD_TIME=26 COMP_MAP=321 SENS_MAP=0xA3A6 VOLT_MUL=110 CURR_MUL=20 LED_MAP=0xB8B5B3 LED_INV)
add_target(IFLIGHT2 STM32G071 DEAD_TIME=35 COMP_MAP=213 SENS_MAP=0xA5A4 VOLT_MUL=110 CURR_MUL=20 LED_WS2812 IO_PA6)
add_target(IFLIGHT3 STM32G071 DEAD_TIME=35 COMP_MAP=132 SENS_MAP=0xA0 VOLT_MUL=110 LED_WS2812)
add_target(NEUTRONRC1 STM32G071 DEAD_TIME=35 COMP_MAP=123)
add_target(SKYSTARS1 GD32E230 DEAD_TIME=40 COMP_MAP=321 SENS_MAP=0xA3 VOLT_MUL=110 LED_MAP=0xB5B3A15)
add_target(TMOTOR1 STM32F051 DEAD_TIME=26 COMP_MAP=132 IO_PA2)
add_target(TMOTOR2 STM32F051 DEAD_TIME=26 COMP_MAP=321)
add_target(TMOTOR3 STM32G071 DEAD_TIME=35 COMP_MAP=231 IO_PA6)

# Experimental targets
add_target(_SPIN32 STSPIN32F0 DEAD_TIME=26)
add_target(_G071PA2 STM32G071 DEAD_TIME=35 COMP_MAP=123 LED_WS2812 IO_PA2)
26 changes: 15 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
ESCape32
========

Firmware for 32-bit BLDC motor electronic speed controllers that aims to Keep-It-Super-Simple. It is designed to deliver smooth and efficient motor drive, fast transitions from a complete stop to full throttle, robust direction reversals, and maximum hardware support.
Firmware for 32-bit BLDC motor electronic speed controllers that aims at simplicity. It is designed to deliver smooth and efficient motor drive, fast transitions from a complete stop to full throttle, robust direction reversals, and maximum hardware support.


Features
--------

+ Servo PWM with automatic throttle calibration
+ iBUS, S.BUS, DSHOT 300/600, bidirectional DSHOT
+ Proportional brake / drag brake
+ Variable PWM frequency
+ KISS telemetry
+ Servo PWM up to 400Hz, automatic throttle calibration
+ DSHOT 300/600, bidirectional DSHOT, extended telemetry
+ Analog/serial/iBUS/SBUS input mode
+ KISS/iBUS/S.Port telemetry
+ DSHOT 3D mode, turtle mode, beacon, LED, direction change
+ Proportional brake, drag brake
+ Temperature/voltage/current protection
+ Variable PWM frequency, active freewheeling
+ Customizable sounds
+ Configuration/firmware updates over the signal wire using a generic USB-TTL adapter
+ Configuration via CLI using a USB-TTL adapter or Betaflight passthrough


Installation
------------

The list of compatible ESCs can be found [here](https://github.com/neoxic/ESCape32/wiki/Targets).

The latest release can be downloaded [here](https://github.com/neoxic/ESCape32/releases).

Visit the [Wiki](https://github.com/neoxic/ESCape32/wiki) to get started with ESCape32.
Visit the [ESCape32 Wiki](https://github.com/neoxic/ESCape32/wiki) for more information.


Dependencies
Expand All @@ -46,9 +51,8 @@ cd build
make
```

To flash a particular target using an ST-LINK probe, run for example:
To flash a particular target using an ST-LINK programmer, run:

```
make flash-BOOT_F0_PA2
make flash-F051_PA2_A
make flash-<target>
```
16 changes: 8 additions & 8 deletions boot/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Tweaks for '.ramtext' sections
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION OFF)
add_link_options(-Wl,--no-warn-rwx-segments)
add_target(BOOT1_PA2 STM32F0 IO_PA2)
add_target(BOOT1_PB4 STM32F0)
add_target(BOOT2_PA6 STM32G0 IO_PA6)
add_target(BOOT2_PB4 STM32G0)
add_target(BOOT3_PA2 STM32F0 IO_PA2 USARTv1)

add_target(STM32F0 BOOT_F0_PA2 IO_PA2)
add_target(STM32F0 BOOT_F0_PA6 IO_PA6)
add_target(STM32F0 BOOT_F0_PB4)
add_target(STM32G0 BOOT_G0_PA6 IO_PA6)
add_target(STM32G0 BOOT_G0_PB4)
# Experimental targets
add_target(_BOOT1_PA6 STM32F0 IO_PA6)
add_target(_BOOT2_PA2 STM32G0 IO_PA2)
33 changes: 18 additions & 15 deletions boot/mcu/STM32F0/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,32 @@
#include "common.h"

void init(void) {
rcc_clock_setup_in_hsi_out_48mhz();
FLASH_ACR = FLASH_ACR_LATENCY_1WS | FLASH_ACR_PRFTEN;
RCC_CFGR = RCC_CFGR_PLLMUL_MUL12;
RCC_CR |= RCC_CR_PLLON;
while (!(RCC_CR & RCC_CR_PLLRDY));
RCC_CFGR |= RCC_CFGR_SW_PLL;

RCC_AHBENR = RCC_AHBENR_CRCEN;
RCC_APB1ENR = RCC_APB1ENR_TIM2EN;
RCC_AHBENR = RCC_AHBENR_CRCEN | RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN;
RCC_APB1ENR = RCC_APB1ENR_TIM14EN;

GPIOA_MODER = 0xebffffff;
GPIOB_MODER = 0xffffffff;
#ifdef IO_PA2
RCC_AHBENR |= RCC_AHBENR_GPIOAEN;
RCC_APB1ENR |= RCC_APB1ENR_USART2EN;
GPIOA_AFRL = 0x00000100; // A2 (USART2_TX)
GPIOA_PUPDR = 0x24000010; // A2 (pull-up)
GPIOA_MODER = 0xebffffef; // A2 (USART2_TX)
GPIOA_AFRL |= 0x100; // A2 (USART2_TX)
GPIOA_PUPDR |= 0x10; // A2 (pull-up)
GPIOA_MODER &= ~0x10; // A2 (USART2_TX)
#else
RCC_APB1ENR |= RCC_APB1ENR_TIM3EN;
#ifdef IO_PA6
RCC_AHBENR |= RCC_AHBENR_GPIOAEN;
GPIOA_AFRL = 0x01000000; // A6 (TIM3_CH1)
GPIOA_PUPDR = 0x24001000; // A6 (pull-up)
GPIOA_MODER = 0xebffefff; // A6 (TIM3_CH1)
GPIOA_AFRL |= 0x1000000; // A6 (TIM3_CH1)
GPIOA_PUPDR |= 0x1000; // A6 (pull-up)
GPIOA_MODER &= ~0x1000; // A6 (TIM3_CH1)
#else
RCC_AHBENR |= RCC_AHBENR_GPIOBEN;
GPIOB_AFRL = 0x00010000; // B4 (TIM3_CH1)
GPIOB_PUPDR = 0x00000100; // B4 (pull-up)
GPIOB_MODER = 0xfffffeff; // B4 (TIM3_CH1)
GPIOB_AFRL |= 0x10000; // B4 (TIM3_CH1)
GPIOB_PUPDR |= 0x100; // B4 (pull-up)
GPIOB_MODER &= ~0x100; // B4 (TIM3_CH1)
#endif
#endif
}
9 changes: 3 additions & 6 deletions boot/mcu/STM32F0/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,10 @@

#pragma once

#define PCLK1 48000000
#define CLK 48000000
#define PAGE_SIZE 1024

#ifdef IO_PA6
#define TIM3_IDR GPIOA_IDR
#define TIM3_PIN 0x40 // A6
#define TIM3_IDR (GPIOA_IDR & 0x40) // A6
#else
#define TIM3_IDR GPIOB_IDR
#define TIM3_PIN 0x10 // B4
#define TIM3_IDR (GPIOB_IDR & 0x10) // B4
#endif
31 changes: 21 additions & 10 deletions boot/mcu/STM32G0/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,31 @@
#include "common.h"

void init(void) {
rcc_clock_setup(&rcc_clock_config[RCC_CLOCK_CONFIG_HSI_PLL_64MHZ]);
FLASH_ACR = FLASH_ACR_LATENCY_2WS | FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DBG_SWEN;
RCC_PLLCFGR = RCC_PLLCFGR_PLLSRC_HSI16 | 8 << RCC_PLLCFGR_PLLN_SHIFT | RCC_PLLCFGR_PLLREN | 1 << RCC_PLLCFGR_PLLR_SHIFT;
RCC_CR |= RCC_CR_PLLON;
while (!(RCC_CR & RCC_CR_PLLRDY));
RCC_CFGR = RCC_CFGR_SW_PLLRCLK;

RCC_IOPENR = 0x3; // GPIOAEN=1, GPIOBEN=1
RCC_AHBENR = RCC_AHBENR_FLASHEN | RCC_AHBENR_CRCEN;
RCC_APBENR1 = RCC_APBENR1_TIM2EN | RCC_APBENR1_TIM3EN;
RCC_APBENR2 = RCC_APBENR2_TIM14EN;

#ifdef IO_PA2
RCC_APBENR1 |= RCC_APBENR1_USART2EN;
GPIOA_AFRL |= 0x100; // A2 (USART2_TX)
GPIOA_PUPDR |= 0x10; // A2 (pull-up)
GPIOA_MODER &= ~0x10; // A2 (USART2_TX)
#else
RCC_APBENR1 |= RCC_APBENR1_TIM3EN;
#ifdef IO_PA6
RCC_IOPENR = 0x01; // GPIOAEN=1
GPIOA_AFRL = 0x01000000; // A6 (TIM3_CH1)
GPIOA_PUPDR = 0x24001000; // A6 (pull-up)
GPIOA_MODER = 0xebffefff; // A6 (TIM3_CH1)
GPIOA_AFRL |= 0x1000000; // A6 (TIM3_CH1)
GPIOA_PUPDR |= 0x1000; // A6 (pull-up)
GPIOA_MODER &= ~0x1000; // A6 (TIM3_CH1)
#else
RCC_IOPENR = 0x02; // GPIOBEN=1
GPIOB_AFRL = 0x00010000; // B4 (TIM3_CH1)
GPIOB_PUPDR = 0x00000100; // B4 (pull-up)
GPIOB_MODER = 0xfffffeff; // B4 (TIM3_CH1)
GPIOB_AFRL |= 0x10000; // B4 (TIM3_CH1)
GPIOB_PUPDR |= 0x100; // B4 (pull-up)
GPIOB_MODER &= ~0x100; // B4 (TIM3_CH1)
#endif
#endif
}
9 changes: 3 additions & 6 deletions boot/mcu/STM32G0/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,10 @@

#pragma once

#define PCLK1 64000000
#define CLK 64000000
#define PAGE_SIZE 2048

#ifdef IO_PA6
#define TIM3_IDR GPIOA_IDR
#define TIM3_PIN 0x40 // A6
#define TIM3_IDR (GPIOA_IDR & 0x40) // A6
#else
#define TIM3_IDR GPIOB_IDR
#define TIM3_PIN 0x10 // B4
#define TIM3_IDR (GPIOB_IDR & 0x10) // B4
#endif
13 changes: 9 additions & 4 deletions boot/src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,17 @@
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/timer.h>
#ifdef USARTv1
#include <libopencm3/cm3/common.h>
#include <libopencm3/stm32/f1/usart.h>
#else
#include <libopencm3/stm32/usart.h>
#endif
#include <libopencm3/stm32/flash.h>
#include <libopencm3/stm32/wwdg.h>
#include <libopencm3/stm32/crc.h>
#include "config.h"

#define CNT(clk, rate) (((clk) + ((rate) >> 1)) / (rate)) // Rate-based clock count
#define CLK_CNT(rate) ((CLK + ((rate) >> 1)) / (rate))

extern char _rom[], _rom_end[], _ram_end[]; // Linker exports

Expand All @@ -42,5 +46,6 @@ int recvdata(char *buf);
void senddata(const char *buf, int len);

uint32_t crc32(const char *buf, int len);
int writeflash(char *dst, const char *src, int len) __attribute__((__long_call__));
void updateflash(char *dst, const char *src, int len) __attribute__((__long_call__, __noreturn__));
int write(char *dst, const char *src, int len) __attribute__((__long_call__));
void update(char *dst, const char *src, int len) __attribute__((__long_call__));
void setwrp(int type);
Loading

0 comments on commit 9ea8014

Please sign in to comment.