tests pass, not building recover

master
Firmware Batman 2017-07-22 14:18:00 -07:00
parent d9fc3b372c
commit 5fd041e011
3 changed files with 153 additions and 146 deletions

View File

@ -1,128 +0,0 @@
#define ENTER_BOOTLOADER_MAGIC 0xdeadbeef
#define POST_BOOTLOADER_MAGIC 0xdeadb111
#define PULL_EFFECTIVE_DELAY 10
#define PANDA_REV_AB 0
#define PANDA_REV_C 1
extern uint32_t enter_bootloader_mode;
extern void *_app_start[];
extern void *g_pfnVectors;
#include "config.h"
#include "llgpio.h"
int has_external_debug_serial = 0;
int is_giant_panda = 0;
int revision = PANDA_REV_AB;
void *g_pfnVectors;
// must call again from main because BSS is zeroed
void detect() {
volatile int i;
// detect has_external_debug_serial
GPIOA->PUPDR |= GPIO_PUPDR_PUPDR3_1;
for (i=0;i<PULL_EFFECTIVE_DELAY;i++);
has_external_debug_serial = (GPIOA->IDR & (1 << 3)) == (1 << 3);
#ifdef PANDA
// detect is_giant_panda
set_gpio_pullup(GPIOB, 1, PULL_DOWN);
for (i=0;i<PULL_EFFECTIVE_DELAY;i++);
is_giant_panda = get_gpio_input(GPIOB, 1);
// detect panda REV C.
// A13 floats in REV AB. In REV C, A13 is pulled up to 5V with a 10K
// resistor and attached to the USB power control chip CTRL
// line. Pulling A13 down with an internal 50k resistor in REV C
// will produce a voltage divider that results in a high logic
// level. Checking if this pin reads high with a pull down should
// differentiate REV AB from C.
set_gpio_mode(GPIOA, 13, MODE_INPUT);
set_gpio_pullup(GPIOA, 13, PULL_DOWN);
for (i=0;i<PULL_EFFECTIVE_DELAY;i++);
if(get_gpio_input(GPIOA, 13))
revision = PANDA_REV_C;
// RESET pull up/down
set_gpio_pullup(GPIOA, 13, PULL_NONE);
#endif
}
void early() {
// after it's been in the bootloader, things are initted differently, so we reset
if (enter_bootloader_mode == POST_BOOTLOADER_MAGIC) {
enter_bootloader_mode = 0;
NVIC_SystemReset();
}
volatile int i;
// if wrong chip, reboot
volatile unsigned int id = DBGMCU->IDCODE;
#ifdef STM32F4
if ((id&0xFFF) != 0x463) enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC;
#else
if ((id&0xFFF) != 0x411) enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC;
#endif
// setup interrupt table
SCB->VTOR = (uint32_t)&g_pfnVectors;
// early GPIOs
RCC->AHB1ENR = RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN;
GPIOA->MODER = 0; GPIOB->MODER = 0; GPIOC->MODER = 0;
GPIOA->ODR = 0; GPIOB->ODR = 0; GPIOC->ODR = 0;
GPIOA->PUPDR = 0; GPIOB->PUPDR = 0; GPIOC->PUPDR = 0;
detect();
#ifdef PANDA
// enable the ESP, disable ESP boot mode
// unless we are on a giant panda, then there's no ESP
if (!is_giant_panda) {
GPIOC->ODR = (1 << 14) | (1 << 5);
}
// these are outputs to control the ESP
GPIOC->MODER = GPIO_MODER_MODER14_0 | GPIO_MODER_MODER5_0;
// check if the ESP is trying to put me in boot mode
// enable pull up
GPIOB->PUPDR |= GPIO_PUPDR_PUPDR0_0;
for (i=0;i<PULL_EFFECTIVE_DELAY;i++);
#ifdef BOOTSTUB
// if it's driven low, jump to spi flasher
if (!(GPIOB->IDR & 1)) {
spi_flasher();
}
#endif
#endif
if (enter_bootloader_mode == ENTER_BOOTLOADER_MAGIC) {
// ESP OFF
GPIOC->ODR &= ~((1 << 14) | (1 << 5));
// green LED on
// sadly, on the NEO board the bootloader turns it off
#ifdef PANDA
GPIOC->MODER |= GPIO_MODER_MODER7_0;
GPIOC->ODR &= ~(1 << (6 + 1));
#else
GPIOB->MODER |= GPIO_MODER_MODER11_0;
GPIOB->ODR &= ~(1 << (10 + 1));
#endif
// do enter bootloader
enter_bootloader_mode = POST_BOOTLOADER_MAGIC;
void (*bootloader)(void) = (void (*)(void)) (*((uint32_t *)0x1fff0004));
// jump to bootloader
bootloader();
// LOOP
while(1);
}
}

View File

@ -6,6 +6,52 @@
#include "llgpio.h"
// ********************* dynamic configuration detection *********************
#define PANDA_REV_AB 0
#define PANDA_REV_C 1
#define PULL_EFFECTIVE_DELAY 10
int has_external_debug_serial = 0;
int is_giant_panda = 0;
int is_entering_bootmode = 0;
int revision = PANDA_REV_AB;
int detect_with_pull(GPIO_TypeDef *GPIO, int pin, int mode) {
set_gpio_mode(GPIO, pin, MODE_INPUT);
set_gpio_pullup(GPIO, pin, mode);
for (volatile int i=0; i<PULL_EFFECTIVE_DELAY; i++);
int ret = get_gpio_input(GPIO, pin);
set_gpio_pullup(GPIOB, pin, PULL_NONE);
return ret;
}
// must call again from main because BSS is zeroed
void detect() {
volatile int i;
// detect has_external_debug_serial
has_external_debug_serial = detect_with_pull(GPIOA, 3, PULL_DOWN);
#ifdef PANDA
// detect is_giant_panda
is_giant_panda = detect_with_pull(GPIOB, 1, PULL_DOWN);
// detect panda REV C.
// A13 floats in REV AB. In REV C, A13 is pulled up to 5V with a 10K
// resistor and attached to the USB power control chip CTRL
// line. Pulling A13 down with an internal 50k resistor in REV C
// will produce a voltage divider that results in a high logic
// level. Checking if this pin reads high with a pull down should
// differentiate REV AB from C.
revision = detect_with_pull(GPIOA, 13, PULL_DOWN) ? PANDA_REV_C : PANDA_REV_AB;
// check if the ESP is trying to put me in boot mode
is_entering_bootmode = detect_with_pull(GPIOB, 0, PULL_UP);
#endif
}
// ********************* bringup *********************
void clock_init() {
@ -187,6 +233,28 @@ void set_usb_power_mode(int mode) {
}
}
#define ESP_DISABLED 0
#define ESP_ENABLED 1
#define ESP_BOOTMODE 2
void set_esp_mode(int mode) {
switch (mode) {
case ESP_DISABLED:
// ESP OFF
set_gpio_output(GPIOC, 14, 0);
set_gpio_output(GPIOC, 5, 0);
break;
case ESP_ENABLED:
set_gpio_output(GPIOC, 14, 1);
set_gpio_output(GPIOC, 5, 1);
break;
case ESP_BOOTMODE:
set_gpio_output(GPIOC, 14, 1);
set_gpio_output(GPIOC, 5, 0);
break;
}
}
// ********************* big init function *********************
// board specific
@ -299,3 +367,76 @@ void gpio_init() {
}
}
// ********************* early bringup *********************
#define ENTER_BOOTLOADER_MAGIC 0xdeadbeef
#define POST_BOOTLOADER_MAGIC 0xdeadb111
extern void *g_pfnVectors;
extern uint32_t enter_bootloader_mode;
void jump_to_bootloader() {
// do enter bootloader
enter_bootloader_mode = POST_BOOTLOADER_MAGIC;
void (*bootloader)(void) = (void (*)(void)) (*((uint32_t *)0x1fff0004));
// jump to bootloader
bootloader();
// LOOP
while(1);
}
void early() {
// after it's been in the bootloader, things are initted differently, so we reset
if (enter_bootloader_mode == POST_BOOTLOADER_MAGIC) {
enter_bootloader_mode = 0;
NVIC_SystemReset();
}
volatile int i;
// if wrong chip, reboot
volatile unsigned int id = DBGMCU->IDCODE;
#ifdef STM32F4
if ((id&0xFFF) != 0x463) enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC;
#else
if ((id&0xFFF) != 0x411) enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC;
#endif
// setup interrupt table
SCB->VTOR = (uint32_t)&g_pfnVectors;
// early GPIOs float everything
RCC->AHB1ENR = RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN;
GPIOA->MODER = 0; GPIOB->MODER = 0; GPIOC->MODER = 0;
GPIOA->ODR = 0; GPIOB->ODR = 0; GPIOC->ODR = 0;
GPIOA->PUPDR = 0; GPIOB->PUPDR = 0; GPIOC->PUPDR = 0;
#ifdef PANDA
detect();
// enable the ESP, disable ESP boot mode
// unless we are on a giant panda, then there's no ESP
if (is_giant_panda) {
set_esp_mode(ESP_DISABLED);
} else {
set_esp_mode(ESP_ENABLED);
}
#ifdef BOOTSTUB
if (is_entering_bootmode) {
spi_flasher();
}
#endif
#endif
if (enter_bootloader_mode == ENTER_BOOTLOADER_MAGIC) {
set_esp_mode(ESP_DISABLED);
set_led(LED_GREEN, 1);
jump_to_bootloader();
}
}

View File

@ -1,5 +1,4 @@
#include "config.h"
#include "early.h"
#include <stdbool.h>
// *** end config ***
@ -177,6 +176,8 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
break;
// **** 0xd1: enter bootloader mode
case 0xd1:
// this allows reflashing of the bootstub
// so it's blocked over wifi
if (hardwired) {
enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC;
NVIC_SystemReset();
@ -203,31 +204,22 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
// **** 0xd9: set ESP power
case 0xd9:
if (setup->b.wValue.w == 1) {
// on
GPIOC->ODR |= (1 << 14);
set_esp_mode(ESP_ENABLED);
} else {
// off
GPIOC->ODR &= ~(1 << 14);
set_esp_mode(ESP_DISABLED);
}
break;
// **** 0xda: reset ESP, with optional boot mode
case 0xda:
// pull low for ESP boot mode
if (setup->b.wValue.w == 1) {
GPIOC->ODR &= ~(1 << 5);
}
// do ESP reset
GPIOC->ODR &= ~(1 << 14);
set_esp_mode(ESP_DISABLED);
delay(1000000);
GPIOC->ODR |= (1 << 14);
delay(1000000);
// reset done, no more boot mode
// TODO: ESP doesn't seem to listen here
if (setup->b.wValue.w == 1) {
GPIOC->ODR |= (1 << 5);
set_esp_mode(ESP_BOOTMODE);
} else {
set_esp_mode(ESP_ENABLED);
}
delay(1000000);
set_esp_mode(ESP_ENABLED);
break;
// **** 0xdb: set GMLAN multiplexing mode
case 0xdb:
@ -247,6 +239,8 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
break;
// **** 0xdc: set safety mode
case 0xdc:
// this is the only way to leave silent mode
// and it's blocked over WiFi
if (hardwired) {
safety_set_mode(setup->b.wValue.w);
can_silent = (setup->b.wValue.w == SAFETY_NOOUTPUT);