static void handle_nores_packet(unsigned char *data, unsigned char len) { COMM_NORES_PACKET_ID car_nores_packet; (void)len; car_nores_packet = data[0]; data++; len--; switch (car_nores_packet) { case COMM_FULL_BRAKE: mcpwm_brake_now(); break; case COMM_SERVO_OFFSET: servos[0].offset = data[0]; break; case COMM_CAN_TEST: break; case COMM_TERMINAL_CMD: data[len] = '\0'; terminal_process_string((char*)data); break; case COMM_RELEASE: mcpwm_release_motor(); break; default: break; } }
uint16_t flash_helper_erase_new_app(uint32_t new_app_size) { FLASH_Unlock(); FLASH_ClearFlag(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); new_app_size += flash_addr[NEW_APP_BASE]; mcpwm_unlock(); mcpwm_release_motor(); utils_sys_lock_cnt(); RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, DISABLE); for (int i = 0;i < NEW_APP_SECTORS;i++) { if (new_app_size > flash_addr[NEW_APP_BASE + i]) { uint16_t res = FLASH_EraseSector(flash_sector[NEW_APP_BASE + i], VoltageRange_3); if (res != FLASH_COMPLETE) { return res; } } else { break; } } RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); utils_sys_unlock_cnt(); return FLASH_COMPLETE; }
/** * Stop the system and jump to the bootloader. */ void flash_helper_jump_to_bootloader(void) { typedef void (*pFunction)(void); mcpwm_unlock(); mcpwm_release_motor(); usbDisconnectBus(&USBD1); usbStop(&USBD1); uartStop(&HW_UART_DEV); palSetPadMode(HW_UART_TX_PORT, HW_UART_TX_PIN, PAL_MODE_INPUT); palSetPadMode(HW_UART_RX_PORT, HW_UART_RX_PIN, PAL_MODE_INPUT); // Disable watchdog RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, DISABLE); chSysDisable(); pFunction jump_to_bootloader; // Variable that will be loaded with the start address of the application vu32* jump_address; const vu32* bootloader_address = (vu32*)0x080E0000; // Get jump address from application vector table jump_address = (vu32*) bootloader_address[1]; // Load this address into function pointer jump_to_bootloader = (pFunction) jump_address; // Clear pending interrupts SCB_ICSR = ICSR_PENDSVCLR; // Disable all interrupts for(int i = 0;i < 8;i++) { NVIC->ICER[i] = NVIC->IABR[i]; } // Set stack pointer __set_MSP((u32) (bootloader_address[0])); // Jump to the bootloader jump_to_bootloader(); }
uint16_t flash_helper_write_new_app_data(uint32_t offset, uint8_t *data, uint32_t len) { FLASH_ClearFlag(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); mcpwm_unlock(); mcpwm_release_motor(); utils_sys_lock_cnt(); RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, DISABLE); for (uint32_t i = 0;i < len;i++) { uint16_t res = FLASH_ProgramByte(flash_addr[NEW_APP_BASE] + offset + i, data[i]); if (res != FLASH_COMPLETE) { return res; } } RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); utils_sys_unlock_cnt(); return FLASH_COMPLETE; }