mirror of
https://github.com/dragonpilot/dragonpilot.git
synced 2026-09-15 03:53:43 +08:00
098e304118
67d5208 fix signedness issue in toyota safety fe15d3f bump pandacan 11c2b08 add fault invalid 2c26e45 add sleep 27c7637 forgot the counter 3a6d7db don't hang bfa7d2e canloader works b259e2a can flasher is close to working 83f2edf isotp can support in softloader 7ae7c79 typo e85cc47 forgot the selfs 190b4f6 start work on canflasher 5c655c9 add recover support ae3457f usbflash is reliable f7a0ab0 pedal usbflash works 585d0f9 add way to call isotp be82899 despite it being bad code, move isotp 000715b start work on pedal canloader 626e312 pedal has a bootstub now 3662d1e redundant check 81e6b0d fix bug 083cd12 should have bounty to refactor that ish b65d30c bad asserts b2e6c3f isotp untested support for subaddr 30fd66a Merge pull request #93 from vntarasov/volt 06f5109 Merge pull request #94 from gregjhogan/can-printer-hex c7d098c Merge pull request #95 from gregjhogan/setup-script 22fe250 Merge pull request #99 from gregjhogan/bit-transition-example ba16ba3 Merge pull request #100 from gregjhogan/j2534-troubleshooting-instructions ad08ea4 Merge pull request #90 from gregjhogan/can-forwarding f3b6f5d added j2534 troubleshooting instructions 858d150 added script to find bits that transition from 0 to 1 c6acac8 added checking pedal interceptor message length f7226ff added brake safety checks d0c2634 added gas safety checks d378e4a removed bosch safety forwarding restriction on 29 bit addresses 5c7ef9e added bosch safety hooks and forwarding 90c64b6 add note 23de8d4 Merge pull request #97 from commaai/pedal_improvements 0261641 added missing python packages b92b235 fix bytearray encode issue 2434f1c Tweak Volt's brake pedal stickiness e2f73d2 enable has a whole byte to itself d5a9e1e correct checksum f8ed9fa better names 986a14c don't alias pointers 9b8472e add watchdog support 8f0add9 handle faults 1d917f8 split gas set into 2 values, and have a fault state 1b77026 j2534 isn't alpha anymore fbcc872 Merge pull request #92 from commaai/pedal 8a6f44b pedal is sending messages 08f464c python 3 bro is bad bro 9390961 kline checksum algo was broken... 3b7c33b add kline debug support aa622bc init values 631ea9f better refactor eb1fd75 add PEDAL adc sets ccaa310 don't build with usb 8d4d763 debug console works bd09883 comma pedal is building 75a29d5 Merge pull request #84 from gregjhogan/j2534-hds eece37d only the panda has gmlan 9f43abe Merge pull request #89 from vntarasov/volt 5364d43 Merge pull request #88 from vntarasov/smaller-firmware 377a1ec bump version for descriptor fix 4fabdf0 Merge pull request #87 from gregjhogan/usb-multi-packet-control 8580773 fix sending WinUSB Extended Properties Feature Descriptor 6908feb Chevy Volt safety 786a004 Enable optimization to reduce firmware size d70f43b hack to fix thinkpad 95ab1ae fixed flow control message padding bbd04d1 updated installer 62216d0 single standalone DLL for J2534 driver 5c9138d fixed 11 bit address issue f3b0ad2 fix LOOPBACK getting set when DATA_RATE is set b750d36 updated README a9a097f lowered CPU utilization 7c26a70 TIS needs unsupported protocols to return an error 42692b4 TIS doesn't like ChannelID being zero cf126bb SET_CONFIG return error for reserved parameters 2e99dbf fix HDS issues 8203cc8 add is_grey e946a54 add insecure_okay flag 4363b3e check webpage 4f59ded add secure mode note 6b11fb5 add autosecuring to tests b27d185 Merge pull request #86 from commaai/better_pairing 4b53b42 elm wifi isn't an automated test 99f85cb Merge pull request #85 from gregjhogan/usb-wcid 0d38060 auto-install WinUSB device driver c6653ca from python import 38cc0ee add wifi_secure_mode, boots in insecure mode git-subtree-dir: panda git-subtree-split: 67d52089a1300b86800d897f2b271e0a24cf6dd6
478 lines
13 KiB
C
478 lines
13 KiB
C
#ifdef STM32F4
|
|
#include "stm32f4xx_hal_gpio_ex.h"
|
|
#else
|
|
#include "stm32f2xx_hal_gpio_ex.h"
|
|
#endif
|
|
|
|
// ********************* 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 is_grey_panda = 0;
|
|
|
|
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(GPIO, pin, PULL_NONE);
|
|
return ret;
|
|
}
|
|
|
|
// must call again from main because BSS is zeroed
|
|
void detect() {
|
|
// 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);
|
|
|
|
// check if it's a grey panda by seeing if the SPI lines are floating
|
|
// TODO: is this reliable?
|
|
is_grey_panda = !(detect_with_pull(GPIOA, 4, PULL_DOWN) | detect_with_pull(GPIOA, 5, PULL_DOWN) | detect_with_pull(GPIOA, 6, PULL_DOWN) | detect_with_pull(GPIOA, 7, PULL_DOWN));
|
|
#else
|
|
// need to do this for early detect
|
|
is_giant_panda = 0;
|
|
is_grey_panda = 0;
|
|
revision = PANDA_REV_AB;
|
|
is_entering_bootmode = 0;
|
|
#endif
|
|
}
|
|
|
|
// ********************* bringup *********************
|
|
|
|
void clock_init() {
|
|
// enable external oscillator
|
|
RCC->CR |= RCC_CR_HSEON;
|
|
while ((RCC->CR & RCC_CR_HSERDY) == 0);
|
|
|
|
// divide shit
|
|
RCC->CFGR = RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_PPRE1_DIV4;
|
|
#ifdef PANDA
|
|
RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 |
|
|
RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLSRC_HSE;
|
|
#else
|
|
#ifdef PEDAL
|
|
// comma pedal has a 16mhz crystal
|
|
RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 |
|
|
RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLSRC_HSE;
|
|
#else
|
|
// NEO board has a 8mhz crystal
|
|
RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 |
|
|
RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLSRC_HSE;
|
|
#endif
|
|
#endif
|
|
|
|
// start PLL
|
|
RCC->CR |= RCC_CR_PLLON;
|
|
while ((RCC->CR & RCC_CR_PLLRDY) == 0);
|
|
|
|
// Configure Flash prefetch, Instruction cache, Data cache and wait state
|
|
// *** without this, it breaks ***
|
|
FLASH->ACR = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS;
|
|
|
|
// switch to PLL
|
|
RCC->CFGR |= RCC_CFGR_SW_PLL;
|
|
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
|
|
|
|
// *** running on PLL ***
|
|
}
|
|
|
|
void periph_init() {
|
|
// enable GPIOB, UART2, CAN, USB clock
|
|
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
|
|
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
|
|
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
|
|
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
|
|
|
|
RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
|
|
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
|
|
RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
|
|
#ifdef PANDA
|
|
RCC->APB1ENR |= RCC_APB1ENR_UART5EN;
|
|
#endif
|
|
RCC->APB1ENR |= RCC_APB1ENR_CAN1EN;
|
|
RCC->APB1ENR |= RCC_APB1ENR_CAN2EN;
|
|
#ifdef CAN3
|
|
RCC->APB1ENR |= RCC_APB1ENR_CAN3EN;
|
|
#endif
|
|
RCC->APB1ENR |= RCC_APB1ENR_DACEN;
|
|
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
|
|
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
|
//RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
|
|
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
|
|
RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
|
|
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
|
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
|
|
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
|
|
|
|
// needed?
|
|
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
|
|
}
|
|
|
|
// ********************* setters *********************
|
|
|
|
void set_can_enable(CAN_TypeDef *CAN, int enabled) {
|
|
// enable CAN busses
|
|
if (CAN == CAN1) {
|
|
#ifdef PANDA
|
|
// CAN1_EN
|
|
set_gpio_output(GPIOC, 1, !enabled);
|
|
#else
|
|
#ifdef PEDAL
|
|
// CAN1_EN (not flipped)
|
|
set_gpio_output(GPIOB, 3, !enabled);
|
|
#else
|
|
// CAN1_EN
|
|
set_gpio_output(GPIOB, 3, enabled);
|
|
#endif
|
|
#endif
|
|
} else if (CAN == CAN2) {
|
|
#ifdef PANDA
|
|
// CAN2_EN
|
|
set_gpio_output(GPIOC, 13, !enabled);
|
|
#else
|
|
// CAN2_EN
|
|
set_gpio_output(GPIOB, 4, enabled);
|
|
#endif
|
|
#ifdef CAN3
|
|
} else if (CAN == CAN3) {
|
|
// CAN3_EN
|
|
set_gpio_output(GPIOA, 0, !enabled);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
#ifdef PANDA
|
|
#define LED_RED 9
|
|
#define LED_GREEN 7
|
|
#define LED_BLUE 6
|
|
#else
|
|
#define LED_RED 10
|
|
#define LED_GREEN 11
|
|
#define LED_BLUE -1
|
|
#endif
|
|
|
|
void set_led(int led_num, int on) {
|
|
if (led_num == -1) return;
|
|
|
|
#ifdef PANDA
|
|
set_gpio_output(GPIOC, led_num, !on);
|
|
#else
|
|
set_gpio_output(GPIOB, led_num, !on);
|
|
#endif
|
|
}
|
|
|
|
void set_can_mode(int can, int use_gmlan) {
|
|
// connects to CAN2 xcvr or GMLAN xcvr
|
|
if (use_gmlan) {
|
|
if (can == 1) {
|
|
// B5,B6: disable normal mode
|
|
set_gpio_mode(GPIOB, 5, MODE_INPUT);
|
|
set_gpio_mode(GPIOB, 6, MODE_INPUT);
|
|
|
|
// B12,B13: gmlan mode
|
|
set_gpio_alternate(GPIOB, 12, GPIO_AF9_CAN2);
|
|
set_gpio_alternate(GPIOB, 13, GPIO_AF9_CAN2);
|
|
#ifdef CAN3
|
|
} else if (revision == PANDA_REV_C && can == 2) {
|
|
// A8,A15: disable normal mode
|
|
set_gpio_mode(GPIOA, 8, MODE_INPUT);
|
|
set_gpio_mode(GPIOA, 15, MODE_INPUT);
|
|
|
|
// B3,B4: enable gmlan mode
|
|
set_gpio_alternate(GPIOB, 3, GPIO_AF11_CAN3);
|
|
set_gpio_alternate(GPIOB, 4, GPIO_AF11_CAN3);
|
|
#endif
|
|
}
|
|
} else {
|
|
if (can == 1) {
|
|
// B12,B13: disable gmlan mode
|
|
set_gpio_mode(GPIOB, 12, MODE_INPUT);
|
|
set_gpio_mode(GPIOB, 13, MODE_INPUT);
|
|
|
|
// B5,B6: normal mode
|
|
set_gpio_alternate(GPIOB, 5, GPIO_AF9_CAN2);
|
|
set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2);
|
|
#ifdef CAN3
|
|
} else if (can == 2) {
|
|
if(revision == PANDA_REV_C){
|
|
// B3,B4: disable gmlan mode
|
|
set_gpio_mode(GPIOB, 3, MODE_INPUT);
|
|
set_gpio_mode(GPIOB, 4, MODE_INPUT);
|
|
}
|
|
// A8,A15: normal mode
|
|
set_gpio_alternate(GPIOA, 8, GPIO_AF11_CAN3);
|
|
set_gpio_alternate(GPIOA, 15, GPIO_AF11_CAN3);
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
#define USB_POWER_NONE 0
|
|
#define USB_POWER_CLIENT 1
|
|
#define USB_POWER_CDP 2
|
|
#define USB_POWER_DCP 3
|
|
|
|
int usb_power_mode = USB_POWER_NONE;
|
|
|
|
void set_usb_power_mode(int mode) {
|
|
switch (mode) {
|
|
case USB_POWER_CLIENT:
|
|
// B2,A13: set client mode
|
|
set_gpio_output(GPIOB, 2, 0);
|
|
set_gpio_output(GPIOA, 13, 1);
|
|
break;
|
|
case USB_POWER_CDP:
|
|
// B2,A13: set CDP mode
|
|
set_gpio_output(GPIOB, 2, 1);
|
|
set_gpio_output(GPIOA, 13, 1);
|
|
break;
|
|
case USB_POWER_DCP:
|
|
// B2,A13: set DCP mode on the charger (breaks USB!)
|
|
set_gpio_output(GPIOB, 2, 0);
|
|
set_gpio_output(GPIOA, 13, 0);
|
|
break;
|
|
}
|
|
usb_power_mode = 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:
|
|
// ESP ON
|
|
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
|
|
void gpio_init() {
|
|
// pull low to hold ESP in reset??
|
|
// enable OTG out tied to ground
|
|
GPIOA->ODR = 0;
|
|
GPIOB->ODR = 0;
|
|
GPIOA->PUPDR = 0;
|
|
//GPIOC->ODR = 0;
|
|
GPIOB->AFR[0] = 0;
|
|
GPIOB->AFR[1] = 0;
|
|
|
|
// C2,C3: analog mode, voltage and current sense
|
|
set_gpio_mode(GPIOC, 2, MODE_ANALOG);
|
|
set_gpio_mode(GPIOC, 3, MODE_ANALOG);
|
|
|
|
#ifdef PEDAL
|
|
// comma pedal has inputs on C0 and C1
|
|
set_gpio_mode(GPIOC, 0, MODE_ANALOG);
|
|
set_gpio_mode(GPIOC, 1, MODE_ANALOG);
|
|
// DAC outputs on A4 and A5
|
|
// apparently they don't need GPIO setup
|
|
#endif
|
|
|
|
// C8: FAN aka TIM3_CH4
|
|
set_gpio_alternate(GPIOC, 8, GPIO_AF2_TIM3);
|
|
|
|
// turn off LEDs and set mode
|
|
set_led(LED_RED, 0);
|
|
set_led(LED_GREEN, 0);
|
|
set_led(LED_BLUE, 0);
|
|
|
|
// A11,A12: USB
|
|
set_gpio_alternate(GPIOA, 11, GPIO_AF10_OTG_FS);
|
|
set_gpio_alternate(GPIOA, 12, GPIO_AF10_OTG_FS);
|
|
GPIOA->OSPEEDR = GPIO_OSPEEDER_OSPEEDR11 | GPIO_OSPEEDER_OSPEEDR12;
|
|
|
|
#ifdef PANDA
|
|
// enable started_alt on the panda
|
|
set_gpio_pullup(GPIOA, 1, PULL_UP);
|
|
|
|
// A2,A3: USART 2 for debugging
|
|
set_gpio_alternate(GPIOA, 2, GPIO_AF7_USART2);
|
|
set_gpio_alternate(GPIOA, 3, GPIO_AF7_USART2);
|
|
|
|
// A9,A10: USART 1 for talking to the ESP
|
|
set_gpio_alternate(GPIOA, 9, GPIO_AF7_USART1);
|
|
set_gpio_alternate(GPIOA, 10, GPIO_AF7_USART1);
|
|
|
|
// B12: GMLAN, ignition sense, pull up
|
|
set_gpio_pullup(GPIOB, 12, PULL_UP);
|
|
|
|
// A4,A5,A6,A7: setup SPI
|
|
set_gpio_alternate(GPIOA, 4, GPIO_AF5_SPI1);
|
|
set_gpio_alternate(GPIOA, 5, GPIO_AF5_SPI1);
|
|
set_gpio_alternate(GPIOA, 6, GPIO_AF5_SPI1);
|
|
set_gpio_alternate(GPIOA, 7, GPIO_AF5_SPI1);
|
|
#endif
|
|
|
|
// B8,B9: CAN 1
|
|
#ifdef STM32F4
|
|
set_gpio_alternate(GPIOB, 8, GPIO_AF8_CAN1);
|
|
set_gpio_alternate(GPIOB, 9, GPIO_AF8_CAN1);
|
|
#else
|
|
set_gpio_alternate(GPIOB, 8, GPIO_AF9_CAN1);
|
|
set_gpio_alternate(GPIOB, 9, GPIO_AF9_CAN1);
|
|
#endif
|
|
set_can_enable(CAN1, 1);
|
|
|
|
// B5,B6: CAN 2
|
|
set_can_mode(1, 0);
|
|
set_can_enable(CAN2, 1);
|
|
|
|
// A8,A15: CAN 3
|
|
#ifdef CAN3
|
|
set_can_mode(2, 0);
|
|
set_can_enable(CAN3, 1);
|
|
#endif
|
|
|
|
/* GMLAN mode pins:
|
|
M0(B15) M1(B14) mode
|
|
=======================
|
|
0 0 sleep
|
|
1 0 100kbit
|
|
0 1 high voltage wakeup
|
|
1 1 33kbit (normal)
|
|
*/
|
|
|
|
// put gmlan transceiver in normal mode
|
|
set_gpio_output(GPIOB, 14, 1);
|
|
set_gpio_output(GPIOB, 15, 1);
|
|
|
|
#ifdef PANDA
|
|
// K-line enable moved from B4->B7 to make room for GMLAN on CAN3
|
|
if (revision == PANDA_REV_C) {
|
|
set_gpio_output(GPIOB, 7, 1); // REV C
|
|
} else {
|
|
set_gpio_output(GPIOB, 4, 1); // REV AB
|
|
}
|
|
|
|
// C12,D2: K-Line setup on UART 5
|
|
set_gpio_alternate(GPIOC, 12, GPIO_AF8_UART5);
|
|
set_gpio_alternate(GPIOD, 2, GPIO_AF8_UART5);
|
|
set_gpio_pullup(GPIOD, 2, PULL_UP);
|
|
|
|
// L-line enable
|
|
set_gpio_output(GPIOA, 14, 1);
|
|
|
|
// C10,C11: L-Line setup on USART 3
|
|
set_gpio_alternate(GPIOC, 10, GPIO_AF7_USART3);
|
|
set_gpio_alternate(GPIOC, 11, GPIO_AF7_USART3);
|
|
set_gpio_pullup(GPIOC, 11, PULL_UP);
|
|
#endif
|
|
|
|
if (revision == PANDA_REV_C) {
|
|
set_usb_power_mode(USB_POWER_CLIENT);
|
|
}
|
|
}
|
|
|
|
// ********************* early bringup *********************
|
|
|
|
#define ENTER_BOOTLOADER_MAGIC 0xdeadbeef
|
|
#define ENTER_SOFTLOADER_MAGIC 0xdeadc0de
|
|
#define BOOT_NORMAL 0xdeadb111
|
|
|
|
extern void *g_pfnVectors;
|
|
extern uint32_t enter_bootloader_mode;
|
|
|
|
void jump_to_bootloader() {
|
|
// do enter bootloader
|
|
enter_bootloader_mode = 0;
|
|
void (*bootloader)(void) = (void (*)(void)) (*((uint32_t *)0x1fff0004));
|
|
|
|
// jump to bootloader
|
|
bootloader();
|
|
|
|
// reset on exit
|
|
enter_bootloader_mode = BOOT_NORMAL;
|
|
NVIC_SystemReset();
|
|
}
|
|
|
|
void early() {
|
|
// after it's been in the bootloader, things are initted differently, so we reset
|
|
if (enter_bootloader_mode != BOOT_NORMAL &&
|
|
enter_bootloader_mode != ENTER_BOOTLOADER_MAGIC &&
|
|
enter_bootloader_mode != ENTER_SOFTLOADER_MAGIC) {
|
|
enter_bootloader_mode = BOOT_NORMAL;
|
|
NVIC_SystemReset();
|
|
}
|
|
|
|
// 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;
|
|
|
|
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) {
|
|
set_esp_mode(ESP_DISABLED);
|
|
} else {
|
|
set_esp_mode(ESP_ENABLED);
|
|
}
|
|
#endif
|
|
|
|
|
|
if (enter_bootloader_mode == ENTER_BOOTLOADER_MAGIC) {
|
|
#ifdef PANDA
|
|
set_esp_mode(ESP_DISABLED);
|
|
#endif
|
|
set_led(LED_GREEN, 1);
|
|
jump_to_bootloader();
|
|
}
|
|
|
|
if (is_entering_bootmode) {
|
|
enter_bootloader_mode = ENTER_SOFTLOADER_MAGIC;
|
|
}
|
|
}
|
|
|