Skip to content

Commit 35be60a

Browse files
committed
added pin_finder firmware
this allows for finding the pinout of an unknown ESC
1 parent 71f55e0 commit 35be60a

File tree

2 files changed

+225
-1
lines changed

2 files changed

+225
-1
lines changed

Makefile

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ endef
111111
# list of targets formed using CREATE_BOOTLOADER_TARGET
112112
ALL_BUILDS :=
113113

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

130131
-include $(DEP_FILE)
131132

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

155+
156+
#############################################
157+
# create a pinfinder build target given a MCU
158+
define CREATE_PINFINDER_TARGET
159+
$(eval MCU := $$(1))
160+
$(eval ELF_FILE := $(BIN_DIR)/PINFINDER_$(MCU).elf)
161+
$(eval HEX_FILE := $(ELF_FILE:.elf=.hex))
162+
$(eval DEP_FILE := $(ELF_FILE:.elf=.d))
163+
$(eval TARGET := PINFINDER_$(MCU))
164+
165+
# get MCU specific compiler, objcopy and link script or use the ARM SDK one
166+
$(eval xCC := $(if $($(MCU)_CC), $($(MCU)_CC), $(CC)))
167+
$(eval xOBJCOPY := $(if $($(MCU)_OBJCOPY), $($(MCU)_OBJCOPY), $(OBJCOPY)))
168+
$(eval xLDSCRIPT := $(if $($(MCU)_LDSCRIPT), $($(MCU)_LDSCRIPT), $(LDSCRIPT_BL)))
169+
170+
-include $(DEP_FILE)
171+
172+
$(ELF_FILE): CFLAGS_BL := $$(MCU_$(MCU)) $$(CFLAGS_$(MCU)) $$(CFLAGS_BASE) $(EXTRA_CFLAGS)
173+
$(ELF_FILE): LDFLAGS_BL := $$(LDFLAGS_COMMON) $$(LDFLAGS_$(MCU)) -T$(xLDSCRIPT)
174+
$(ELF_FILE): $$(SRC_$(MCU)_BL) pin_finder/main.c
175+
$$(QUIET)echo building pinfinder for $(MCU)
176+
$$(QUIET)$$(MKDIR) -p $(OBJ)
177+
$$(QUIET)echo Compiling $(notdir $$@)
178+
$$(QUIET)$(xCC) $$(CFLAGS_BL) $$(LDFLAGS_BL) -MMD -MP -MF $(DEP_FILE) -o $$(@) $$(SRC_$(MCU)_BL) pin_finder/main.c
179+
$$(QUIET)$$(CP) -f $$@ $$(OBJ)$$(DSEP)debug.elf
180+
$$(QUIET)$$(CP) -f Mcu$(DSEP)$(call lc,$(MCU))$(DSEP)openocd.cfg $$(OBJ)$$(DSEP)openocd.cfg > $$(NUL)
181+
182+
# Generate bin and hex files
183+
$(HEX_FILE): $(ELF_FILE)
184+
$$(QUIET)echo Generating $(notdir $$@)
185+
$$(QUIET)$(xOBJCOPY) -O binary $$(<) $$(@:.hex=.bin)
186+
$$(QUIET)$(xOBJCOPY) $$(<) -O ihex $$(@:.bin=.hex)
187+
188+
$(TARGET): $(HEX_FILE)
189+
190+
# add to list
191+
ALL_BUILDS := $(ALL_BUILDS) $(TARGET)
192+
endef
193+
154194
$(foreach BUILD,$(MCU_BUILDS),$(foreach PIN,$(BOOTLOADER_PINS),$(eval $(call CREATE_BOOTLOADER_TARGET,$(BUILD),$(PIN)))))
155195

196+
$(foreach BUILD,$(MCU_TYPES),$(eval $(call CREATE_PINFINDER_TARGET,$(BUILD))))
197+
156198
bootloaders: $(ALL_BUILDS)
157199

158200
# include the targets for installing tools

pin_finder/main.c

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
/*
2+
bootloader for AM32 ESC firmware
3+
4+
based on https://github.com/AlkaMotors/AT32F421_AM32_Bootloader
5+
*/
6+
#include <main.h>
7+
#include <stdio.h>
8+
9+
#include <version.h>
10+
11+
/* Includes ------------------------------------------------------------------*/
12+
#include <stdbool.h>
13+
#include <stdio.h>
14+
15+
#pragma GCC optimize("O0")
16+
17+
#include <string.h>
18+
19+
#define GPIO_PORT_TYPE gpio_type
20+
21+
static GPIO_PORT_TYPE *input_port;
22+
static uint32_t input_pin;
23+
24+
#define MCU_FLASH_START 0x08000000
25+
#define FIRMWARE_RELATIVE_START 0x1000
26+
27+
#define BAUDRATE 19200
28+
#define BITTIME 52 // 1000000/BAUDRATE
29+
#define HALFBITTIME 26 // 500000/BAUDRATE
30+
31+
#include <blutil.h>
32+
33+
static void setTransmit()
34+
{
35+
gpio_set(input_pin);
36+
gpio_mode_set_output(input_pin, GPIO_OUTPUT_PUSH_PULL);
37+
}
38+
39+
static void delayMicroseconds(uint32_t micros)
40+
{
41+
while (micros > 0) {
42+
uint32_t us = micros>10000?10000:micros;
43+
bl_timer_reset();
44+
while (bl_timer_us() < us) ;
45+
micros -= us;
46+
}
47+
}
48+
49+
static void serialwriteChar(uint8_t data)
50+
{
51+
// start bit is low
52+
gpio_clear(input_pin);
53+
delayMicroseconds(BITTIME);
54+
55+
// send data bits
56+
uint8_t bits_written = 0;
57+
while (bits_written < 8) {
58+
if (data & 0x01) {
59+
gpio_set(input_pin);
60+
} else {
61+
// GPIO_BC(input_port) = input_pin;
62+
gpio_clear(input_pin);
63+
}
64+
bits_written++;
65+
data = data >> 1;
66+
delayMicroseconds(BITTIME);
67+
}
68+
69+
// send stop bit
70+
gpio_set(input_pin);
71+
delayMicroseconds(BITTIME);
72+
}
73+
74+
static void sendString(const uint8_t *data, int len)
75+
{
76+
for(int i = 0; i < len; i++){
77+
serialwriteChar(data[i]);
78+
}
79+
}
80+
81+
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
82+
83+
static bool is_debug(uint8_t portnum, uint32_t pin) {
84+
return portnum == 0 && (pin == 13 || pin == 14);
85+
}
86+
87+
static struct {
88+
const char *pname;
89+
GPIO_PORT_TYPE *port;
90+
} ports[] = {
91+
{ "PA", GPIOA },
92+
{ "PB", GPIOB },
93+
};
94+
95+
static void pin_scanner(void)
96+
{
97+
for (uint8_t i=0; i< ARRAY_SIZE(ports); i++) {
98+
for (uint8_t p=0; p< 16; p++) {
99+
if (is_debug(i, p)) {
100+
continue;
101+
}
102+
103+
for (uint8_t i2=0; i2< ARRAY_SIZE(ports); i2++) {
104+
for (uint8_t p2=0; p2< 16; p2++) {
105+
if (is_debug(i2, p2)) {
106+
continue;
107+
}
108+
109+
input_port = ports[i].port;
110+
input_pin = GPIO_PIN(p);
111+
112+
/*
113+
write the pin combination to the proposed signal pin
114+
*/
115+
char str[12];
116+
str[0] = '[';
117+
strncpy(&str[1], ports[i].pname, sizeof(str)-1);
118+
str[3] = '0' + (p / 10);
119+
str[4] = '0' + (p % 10);
120+
str[5] = ':';
121+
strncpy(&str[6], ports[i2].pname, sizeof(str)-6);
122+
str[8] = '0' + (p2 / 10);
123+
str[9] = '0' + (p2 % 10);
124+
str[10] = ']';
125+
str[11] = 0;
126+
127+
setTransmit();
128+
delayMicroseconds(200);
129+
130+
sendString((const uint8_t *)str, strlen(str));
131+
132+
gpio_mode_set_input(input_pin, GPIO_PULL_NONE);
133+
134+
delayMicroseconds(200);
135+
136+
/*
137+
oscillate the 2nd pin 10 times, 500us high, 1000us low
138+
*/
139+
input_port = ports[i2].port;
140+
input_pin = GPIO_PIN(p2);
141+
setTransmit();
142+
delayMicroseconds(200);
143+
for (uint16_t c=0;c<10;c++) {
144+
gpio_set(input_pin);
145+
delayMicroseconds(500);
146+
gpio_clear(input_pin);
147+
delayMicroseconds(1000);
148+
}
149+
gpio_mode_set_input(input_pin, GPIO_PULL_NONE);
150+
delayMicroseconds(1000);
151+
}
152+
}
153+
}
154+
}
155+
}
156+
157+
int main(void)
158+
{
159+
bl_clock_config();
160+
bl_timer_init();
161+
162+
// give time for debugger to attach
163+
delayMicroseconds(3000000);
164+
165+
// setup all as float input
166+
for (uint8_t i=0; i< ARRAY_SIZE(ports); i++) {
167+
for (uint8_t p=0; p< 16; p++) {
168+
if (is_debug(i, p)) {
169+
continue;
170+
}
171+
input_port = ports[i].port;
172+
input_pin = GPIO_PIN(p);
173+
bl_gpio_init();
174+
gpio_mode_set_input(input_pin, GPIO_PULL_NONE);
175+
}
176+
}
177+
178+
while (true) {
179+
pin_scanner();
180+
}
181+
return 0;
182+
}

0 commit comments

Comments
 (0)