panda/board/flasher.h

158 lines
3.6 KiB
C

// from the linker script
#ifdef STM32H7
#define APP_START_ADDRESS 0x8020000U
#elif defined(STM32F4)
#define APP_START_ADDRESS 0x8004000U
#endif
// flasher state variables
uint32_t *prog_ptr = NULL;
bool unlocked = false;
void spi_init(void);
int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
int resp_len = 0;
// flasher machine
memset(resp, 0, 4);
memcpy(resp+4, "\xde\xad\xd0\x0d", 4);
resp[0] = 0xff;
resp[2] = req->request;
resp[3] = ~req->request;
*((uint32_t **)&resp[8]) = prog_ptr;
resp_len = 0xc;
int sec;
switch (req->request) {
// **** 0xb0: flasher echo
case 0xb0:
resp[1] = 0xff;
break;
// **** 0xb1: unlock flash
case 0xb1:
if (flash_is_locked()) {
flash_unlock();
resp[1] = 0xff;
}
current_board->set_led(LED_GREEN, 1);
unlocked = true;
prog_ptr = (uint32_t *)APP_START_ADDRESS;
break;
// **** 0xb2: erase sector
case 0xb2:
sec = req->param1;
if (flash_erase_sector(sec, unlocked)) {
resp[1] = 0xff;
}
break;
// **** 0xc1: get hardware type
case 0xc1:
resp[0] = hw_type;
resp_len = 1;
break;
// **** 0xc3: fetch MCU UID
case 0xc3:
(void)memcpy(resp, ((uint8_t *)UID_BASE), 12);
resp_len = 12;
break;
// **** 0xd0: fetch serial number
case 0xd0:
// addresses are OTP
if (req->param1 == 1) {
memcpy(resp, (void *)DEVICE_SERIAL_NUMBER_ADDRESS, 0x10);
resp_len = 0x10;
} else {
get_provision_chunk(resp);
resp_len = PROVISION_CHUNK_LEN;
}
break;
// **** 0xd1: enter bootloader mode
case 0xd1:
// this allows reflashing of the bootstub
switch (req->param1) {
case 0:
print("-> entering bootloader\n");
enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC;
NVIC_SystemReset();
break;
case 1:
print("-> entering softloader\n");
enter_bootloader_mode = ENTER_SOFTLOADER_MAGIC;
NVIC_SystemReset();
break;
}
break;
// **** 0xd6: get version
case 0xd6:
COMPILE_TIME_ASSERT(sizeof(gitversion) <= USBPACKET_MAX_SIZE);
memcpy(resp, gitversion, sizeof(gitversion));
resp_len = sizeof(gitversion);
break;
// **** 0xd8: reset ST
case 0xd8:
flush_write_buffer();
NVIC_SystemReset();
break;
}
return resp_len;
}
void comms_can_write(const uint8_t *data, uint32_t len) {
UNUSED(data);
UNUSED(len);
}
int comms_can_read(uint8_t *data, uint32_t max_len) {
UNUSED(data);
UNUSED(max_len);
return 0;
}
void refresh_can_tx_slots_available(void) {}
void comms_endpoint2_write(const uint8_t *data, uint32_t len) {
current_board->set_led(LED_RED, 0);
for (uint32_t i = 0; i < len/4; i++) {
flash_write_word(prog_ptr, *(uint32_t*)(data+(i*4)));
//*(uint64_t*)(&spi_tx_buf[0x30+(i*4)]) = *prog_ptr;
prog_ptr++;
}
current_board->set_led(LED_RED, 1);
}
void soft_flasher_start(void) {
print("\n\n\n************************ FLASHER START ************************\n");
enter_bootloader_mode = 0;
flasher_peripherals_init();
gpio_usart2_init();
gpio_usb_init();
// enable USB
usb_init();
// enable SPI
if (current_board->has_spi) {
gpio_spi_init();
spi_init();
}
// green LED on for flashing
current_board->set_led(LED_GREEN, 1);
enable_interrupts();
for (;;) {
// blink the green LED fast
current_board->set_led(LED_GREEN, 0);
delay(500000);
current_board->set_led(LED_GREEN, 1);
delay(500000);
}
}