Skip to content

Commit

Permalink
added pin_finder firmware
Browse files Browse the repository at this point in the history
this allows for finding the pinout of an unknown ESC
  • Loading branch information
tridge committed Sep 5, 2024
1 parent 71f55e0 commit 35be60a
Show file tree
Hide file tree
Showing 2 changed files with 225 additions and 1 deletion.
44 changes: 43 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ endef
# list of targets formed using CREATE_BOOTLOADER_TARGET
ALL_BUILDS :=

####################################################################################
# create a bootloader build target given a build in the form MCU or MCU_nK and a PIN
define CREATE_BOOTLOADER_TARGET
$(eval BUILD := $(1))
Expand All @@ -129,7 +130,7 @@ $(eval xLDSCRIPT := $(if $($(MCU)_LDSCRIPT), $($(MCU)_LDSCRIPT), $(LDSCRIPT_BL))

-include $(DEP_FILE)

$(ELF_FILE): CFLAGS_BL := $$(MCU_$(MCU)) $$(CFLAGS_$(MCU)) $$(CFLAGS_BASE) -DBOOTLOADER -DUSE_$(PIN) $(EXTRA_CFLAGS)
$(ELF_FILE): CFLAGS_BL := $$(MCU_$(MCU)) $$(CFLAGS_$(MCU)) $$(CFLAGS_BASE) -DUSE_$(PIN) $(EXTRA_CFLAGS)
$(ELF_FILE): LDFLAGS_BL := $$(LDFLAGS_COMMON) $$(LDFLAGS_$(MCU)) -T$(xLDSCRIPT)
$(ELF_FILE): $$(SRC_$(MCU)_BL) $$(SRC_BL)
$$(QUIET)echo building bootloader for $(BUILD) with pin $(PIN)
Expand All @@ -151,8 +152,49 @@ $(TARGET): $(HEX_FILE)
ALL_BUILDS := $(ALL_BUILDS) $(TARGET)
endef


#############################################
# create a pinfinder build target given a MCU
define CREATE_PINFINDER_TARGET
$(eval MCU := $$(1))
$(eval ELF_FILE := $(BIN_DIR)/PINFINDER_$(MCU).elf)
$(eval HEX_FILE := $(ELF_FILE:.elf=.hex))
$(eval DEP_FILE := $(ELF_FILE:.elf=.d))
$(eval TARGET := PINFINDER_$(MCU))

# get MCU specific compiler, objcopy and link script or use the ARM SDK one
$(eval xCC := $(if $($(MCU)_CC), $($(MCU)_CC), $(CC)))
$(eval xOBJCOPY := $(if $($(MCU)_OBJCOPY), $($(MCU)_OBJCOPY), $(OBJCOPY)))
$(eval xLDSCRIPT := $(if $($(MCU)_LDSCRIPT), $($(MCU)_LDSCRIPT), $(LDSCRIPT_BL)))

-include $(DEP_FILE)

$(ELF_FILE): CFLAGS_BL := $$(MCU_$(MCU)) $$(CFLAGS_$(MCU)) $$(CFLAGS_BASE) $(EXTRA_CFLAGS)
$(ELF_FILE): LDFLAGS_BL := $$(LDFLAGS_COMMON) $$(LDFLAGS_$(MCU)) -T$(xLDSCRIPT)
$(ELF_FILE): $$(SRC_$(MCU)_BL) pin_finder/main.c
$$(QUIET)echo building pinfinder for $(MCU)
$$(QUIET)$$(MKDIR) -p $(OBJ)
$$(QUIET)echo Compiling $(notdir $$@)
$$(QUIET)$(xCC) $$(CFLAGS_BL) $$(LDFLAGS_BL) -MMD -MP -MF $(DEP_FILE) -o $$(@) $$(SRC_$(MCU)_BL) pin_finder/main.c
$$(QUIET)$$(CP) -f $$@ $$(OBJ)$$(DSEP)debug.elf
$$(QUIET)$$(CP) -f Mcu$(DSEP)$(call lc,$(MCU))$(DSEP)openocd.cfg $$(OBJ)$$(DSEP)openocd.cfg > $$(NUL)

# Generate bin and hex files
$(HEX_FILE): $(ELF_FILE)
$$(QUIET)echo Generating $(notdir $$@)
$$(QUIET)$(xOBJCOPY) -O binary $$(<) $$(@:.hex=.bin)
$$(QUIET)$(xOBJCOPY) $$(<) -O ihex $$(@:.bin=.hex)

$(TARGET): $(HEX_FILE)

# add to list
ALL_BUILDS := $(ALL_BUILDS) $(TARGET)
endef

$(foreach BUILD,$(MCU_BUILDS),$(foreach PIN,$(BOOTLOADER_PINS),$(eval $(call CREATE_BOOTLOADER_TARGET,$(BUILD),$(PIN)))))

$(foreach BUILD,$(MCU_TYPES),$(eval $(call CREATE_PINFINDER_TARGET,$(BUILD))))

bootloaders: $(ALL_BUILDS)

# include the targets for installing tools
Expand Down
182 changes: 182 additions & 0 deletions pin_finder/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/*
bootloader for AM32 ESC firmware
based on https://github.com/AlkaMotors/AT32F421_AM32_Bootloader
*/
#include <main.h>
#include <stdio.h>

#include <version.h>

/* Includes ------------------------------------------------------------------*/
#include <stdbool.h>
#include <stdio.h>

#pragma GCC optimize("O0")

#include <string.h>

#define GPIO_PORT_TYPE gpio_type

static GPIO_PORT_TYPE *input_port;
static uint32_t input_pin;

#define MCU_FLASH_START 0x08000000
#define FIRMWARE_RELATIVE_START 0x1000

#define BAUDRATE 19200
#define BITTIME 52 // 1000000/BAUDRATE
#define HALFBITTIME 26 // 500000/BAUDRATE

#include <blutil.h>

static void setTransmit()
{
gpio_set(input_pin);
gpio_mode_set_output(input_pin, GPIO_OUTPUT_PUSH_PULL);
}

static void delayMicroseconds(uint32_t micros)
{
while (micros > 0) {
uint32_t us = micros>10000?10000:micros;
bl_timer_reset();
while (bl_timer_us() < us) ;
micros -= us;
}
}

static void serialwriteChar(uint8_t data)
{
// start bit is low
gpio_clear(input_pin);
delayMicroseconds(BITTIME);

// send data bits
uint8_t bits_written = 0;
while (bits_written < 8) {
if (data & 0x01) {
gpio_set(input_pin);
} else {
// GPIO_BC(input_port) = input_pin;
gpio_clear(input_pin);
}
bits_written++;
data = data >> 1;
delayMicroseconds(BITTIME);
}

// send stop bit
gpio_set(input_pin);
delayMicroseconds(BITTIME);
}

static void sendString(const uint8_t *data, int len)
{
for(int i = 0; i < len; i++){
serialwriteChar(data[i]);
}
}

#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))

static bool is_debug(uint8_t portnum, uint32_t pin) {
return portnum == 0 && (pin == 13 || pin == 14);
}

static struct {
const char *pname;
GPIO_PORT_TYPE *port;
} ports[] = {
{ "PA", GPIOA },
{ "PB", GPIOB },
};

static void pin_scanner(void)
{
for (uint8_t i=0; i< ARRAY_SIZE(ports); i++) {
for (uint8_t p=0; p< 16; p++) {
if (is_debug(i, p)) {
continue;
}

for (uint8_t i2=0; i2< ARRAY_SIZE(ports); i2++) {
for (uint8_t p2=0; p2< 16; p2++) {
if (is_debug(i2, p2)) {
continue;
}

input_port = ports[i].port;
input_pin = GPIO_PIN(p);

/*
write the pin combination to the proposed signal pin
*/
char str[12];
str[0] = '[';
strncpy(&str[1], ports[i].pname, sizeof(str)-1);
str[3] = '0' + (p / 10);
str[4] = '0' + (p % 10);
str[5] = ':';
strncpy(&str[6], ports[i2].pname, sizeof(str)-6);
str[8] = '0' + (p2 / 10);
str[9] = '0' + (p2 % 10);
str[10] = ']';
str[11] = 0;

setTransmit();
delayMicroseconds(200);

sendString((const uint8_t *)str, strlen(str));

gpio_mode_set_input(input_pin, GPIO_PULL_NONE);

delayMicroseconds(200);

/*
oscillate the 2nd pin 10 times, 500us high, 1000us low
*/
input_port = ports[i2].port;
input_pin = GPIO_PIN(p2);
setTransmit();
delayMicroseconds(200);
for (uint16_t c=0;c<10;c++) {
gpio_set(input_pin);
delayMicroseconds(500);
gpio_clear(input_pin);
delayMicroseconds(1000);
}
gpio_mode_set_input(input_pin, GPIO_PULL_NONE);
delayMicroseconds(1000);
}
}
}
}
}

int main(void)
{
bl_clock_config();
bl_timer_init();

// give time for debugger to attach
delayMicroseconds(3000000);

// setup all as float input
for (uint8_t i=0; i< ARRAY_SIZE(ports); i++) {
for (uint8_t p=0; p< 16; p++) {
if (is_debug(i, p)) {
continue;
}
input_port = ports[i].port;
input_pin = GPIO_PIN(p);
bl_gpio_init();
gpio_mode_set_input(input_pin, GPIO_PULL_NONE);
}
}

while (true) {
pin_scanner();
}
return 0;
}

0 comments on commit 35be60a

Please sign in to comment.