Replaced command system with more robust system that talks to an upload utility
This commit is contained in:
parent
96058f06c2
commit
0e90b84d2e
|
@ -15,6 +15,10 @@ uint8_t memory_map_1[16] = {0b00001000, 0b10001000, 0b01001000, 0b11001000, 0b00
|
|||
|
||||
Control control;
|
||||
|
||||
extern UART_HandleTypeDef huart2;
|
||||
extern uint8_t ack[1];
|
||||
extern uint8_t nack[1];
|
||||
|
||||
// @todo For some reason increasing SD_PAGES does not work
|
||||
#define SD_PAGES 1
|
||||
#define CPM_PAGE_SIZE 128
|
||||
|
@ -49,15 +53,11 @@ uint32_t calculate_lba() {
|
|||
|
||||
void control_program_eeprom(uint8_t* data, uint16_t length) {
|
||||
// Take control of the bus
|
||||
printf("Taking control of bus...\n\r");
|
||||
send_busrq(1);
|
||||
while (!has_busak()) {
|
||||
control_execute_state();
|
||||
}
|
||||
|
||||
printf("Done!\n\r");
|
||||
printf("Writing to ROM...\n\r");
|
||||
|
||||
enable_address_out(1);
|
||||
|
||||
select_device(memory_map_0[0]);
|
||||
|
@ -74,8 +74,6 @@ void control_program_eeprom(uint8_t* data, uint16_t length) {
|
|||
enable_data_out(0);
|
||||
send_rd(1);
|
||||
|
||||
printf("%i/%i\r", i+1, length);
|
||||
|
||||
for (;;) {
|
||||
uint8_t d = read_data();
|
||||
if (d == data[i]) {
|
||||
|
@ -85,6 +83,9 @@ void control_program_eeprom(uint8_t* data, uint16_t length) {
|
|||
|
||||
send_rd(0);
|
||||
send_memrq(0);
|
||||
|
||||
uint8_t progress[] = {(i+1) & 0xFF, (i+1) >> 8};
|
||||
HAL_UART_Transmit(&huart2, progress, sizeof(progress), HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
enable_address_out(0);
|
||||
|
@ -95,7 +96,7 @@ void control_program_eeprom(uint8_t* data, uint16_t length) {
|
|||
// Restart the z80
|
||||
control_reset();
|
||||
|
||||
printf("\n");
|
||||
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
void handle_memrq() {
|
||||
|
|
|
@ -15,49 +15,60 @@ typedef enum {
|
|||
TARGET_I2C
|
||||
} UpdateTarget;
|
||||
|
||||
extern uint8_t ack[1];
|
||||
extern uint8_t nack[1];
|
||||
void firmware_update() {
|
||||
printf("FIRMWARE UPDATE\n\r");
|
||||
|
||||
UpdateTarget target;
|
||||
HAL_UART_Receive(&huart2, &target, 1, 1000);
|
||||
printf("T: %i\n\r", target);
|
||||
|
||||
uint8_t address = 0;
|
||||
if (target == TARGET_I2C) {
|
||||
HAL_UART_Receive(&huart2, &address, 1, 1000);
|
||||
printf("A: %i\n\r", address);
|
||||
}
|
||||
HAL_UART_Receive(&huart2, &target, 1, 1000);
|
||||
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
|
||||
|
||||
uint8_t length_buffer[2];
|
||||
HAL_UART_Receive(&huart2, length_buffer, 2, 1000);
|
||||
HAL_UART_Receive(&huart2, length_buffer, sizeof(length_buffer), HAL_MAX_DELAY);
|
||||
HAL_UART_Transmit(&huart2, length_buffer, sizeof(length_buffer), HAL_MAX_DELAY);
|
||||
uint16_t length = length_buffer[0] + (length_buffer[1] << 8);
|
||||
printf("L: %i\n\r", length);
|
||||
|
||||
uint8_t* data = malloc(length);
|
||||
HAL_UART_Receive(&huart2, data, length, 1000);
|
||||
|
||||
printf("Firmware received!\n\r");
|
||||
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
|
||||
|
||||
switch (target) {
|
||||
case TARGET_ROM:
|
||||
control_program_eeprom(data, length);
|
||||
break;
|
||||
|
||||
case TARGET_I2C: {
|
||||
printf("Restarting target to bootloader...\n\r");
|
||||
// @todo Make sure that the address to reset to bootloader is the same as the bootloader address
|
||||
uint8_t reboot_command[] = {0x07};
|
||||
uint8_t address = 0;
|
||||
HAL_UART_Receive(&huart2, &address, 1, 1000);
|
||||
HAL_UART_Transmit(&huart2, &address, sizeof(ack), HAL_MAX_DELAY);
|
||||
|
||||
if (HAL_I2C_IsDeviceReady(&hi2c1, 0x29 << 1, 10, 1000) != HAL_OK) {
|
||||
HAL_UART_Transmit(&huart2, nack, sizeof(nack), HAL_MAX_DELAY);
|
||||
return;
|
||||
}
|
||||
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
|
||||
|
||||
// @todo This assumes that the target it not already in bootloader mode, otherwise this will mess things up
|
||||
uint8_t reboot_command[] = {0xFF};
|
||||
HAL_I2C_Master_Transmit(&hi2c1, address << 1, reboot_command, sizeof(reboot_command), 1000);
|
||||
|
||||
for (volatile int i = 0; i < 10000000; ++i) {}
|
||||
while (HAL_I2C_IsDeviceReady(&hi2c1, 0x29 << 1, 10, 1000) != HAL_OK);
|
||||
|
||||
printf("Uploading to target...\n\r");
|
||||
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
|
||||
|
||||
uint8_t upload_command[4 + length];
|
||||
uint8_t abort_command[] = {0x00};
|
||||
HAL_I2C_Master_Transmit(&hi2c1, address << 1, abort_command, sizeof(abort_command), 1000);
|
||||
|
||||
uint8_t version_command[] = {0x01};
|
||||
HAL_I2C_Master_Transmit(&hi2c1, address << 1, version_command, sizeof(version_command), 1000);
|
||||
uint8_t version_string[16] = {0};
|
||||
HAL_I2C_Master_Receive(&hi2c1, address << 1, version_string, sizeof(version_string), 1000);
|
||||
HAL_UART_Transmit(&huart2, version_string, sizeof(version_string), HAL_MAX_DELAY);
|
||||
|
||||
uint8_t upload_command[4 + 0x80];
|
||||
upload_command[0] = 0x02;
|
||||
upload_command[1] = 0x01;
|
||||
|
||||
printf("0/%i\r", length);
|
||||
|
||||
uint16_t remaining = length;
|
||||
for (uint8_t offset = 0; remaining > 0; ++offset) {
|
||||
upload_command[2] = ((offset*0x80) >> 8) & 0xFF;
|
||||
|
@ -71,14 +82,18 @@ void firmware_update() {
|
|||
|
||||
HAL_I2C_Master_Transmit(&hi2c1, address << 1, upload_command, sizeof(upload_command), 1000);
|
||||
|
||||
printf("%i/%i\r", length-remaining, length);
|
||||
}
|
||||
while (HAL_I2C_IsDeviceReady(&hi2c1, 0x29 << 1, 10, 1000) != HAL_OK);
|
||||
|
||||
printf("\n");
|
||||
uint8_t progress[] = {(length-remaining) & 0xFF, (length-remaining) >> 8};
|
||||
HAL_UART_Transmit(&huart2, progress, sizeof(progress), HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
// Start application
|
||||
uint8_t start_command[] = {0x01, 0x80};
|
||||
HAL_I2C_Master_Transmit(&hi2c1, address << 1, start_command, sizeof(start_command), 1000);
|
||||
|
||||
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
85
Src/main.c
85
Src/main.c
|
@ -74,94 +74,43 @@ static void MX_SDIO_SD_Init(void);
|
|||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
uint8_t byte;
|
||||
uint8_t ack[] = {0x01};
|
||||
uint8_t nack[] = {0xFE};
|
||||
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
|
||||
if (huart->Instance == USART2) {
|
||||
static uint8_t cmd_buffer[128];
|
||||
static uint32_t cmd_buffer_len = 0;
|
||||
static uint8_t command_mode = 0;
|
||||
|
||||
if (cmd_buffer_len+1 > 128) {
|
||||
printf("\n\rCommand is too long!\n\r");
|
||||
cmd_buffer_len = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
int handle_command = 0;
|
||||
static int is_command = 0;
|
||||
if (command_mode) {
|
||||
switch (byte) {
|
||||
// @todo Handle \t
|
||||
// Backspace
|
||||
case 0x08:
|
||||
if (is_command) {
|
||||
if (cmd_buffer_len) {
|
||||
cmd_buffer_len--;
|
||||
} else {
|
||||
is_command = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// else falltrough
|
||||
|
||||
// Newline
|
||||
case '\r':
|
||||
case '\n':
|
||||
if (is_command) {
|
||||
handle_command = 1;
|
||||
break;
|
||||
}
|
||||
// else falltrough
|
||||
|
||||
default:
|
||||
if (!is_command && cmd_buffer_len == 0 && byte == '#') {
|
||||
is_command = 1;
|
||||
} else {
|
||||
cmd_buffer[cmd_buffer_len] = byte;
|
||||
cmd_buffer_len++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!is_command) {
|
||||
// ONLY SEND THE FIRST CHAR
|
||||
if (cmd_buffer_len > 0) {
|
||||
HAL_I2C_Master_Transmit(&hi2c1, 0x29 << 1, &byte, 1, 1000);
|
||||
}
|
||||
cmd_buffer_len = 0;
|
||||
} else if (handle_command && is_command) {
|
||||
if (cmd_buffer_len == 1) {
|
||||
switch (cmd_buffer[0]) {
|
||||
case 'r':
|
||||
control_reset();
|
||||
printf("Starting...\n\r");
|
||||
break;
|
||||
|
||||
// Reboot to bootloader
|
||||
case 'b':
|
||||
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
|
||||
request_restart_to_bootloader();
|
||||
printf("Restarting... (bootloader)\n\r");
|
||||
break;
|
||||
|
||||
// Upload firmware
|
||||
case 'u':
|
||||
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
|
||||
firmware_update();
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
printf("#r - (Re)start program\n\r#b - Restart (Bootloader)\n\r#u - Update\n\r#m - Mount the sd card to pc\n\r#h - Show this menu\n\r");
|
||||
break;
|
||||
|
||||
case '#':
|
||||
HAL_I2C_Master_Transmit(&hi2c1, 0x29 << 1, &byte, 1, 1000);
|
||||
// Send over for bload
|
||||
case 'l':
|
||||
// @todo Implement this
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unknown command: %c!\n\r", cmd_buffer[0]);
|
||||
HAL_UART_Transmit(&huart2, nack, sizeof(nack), HAL_MAX_DELAY);
|
||||
break;
|
||||
}
|
||||
command_mode = 0;
|
||||
} else if (byte == 0xFF) {
|
||||
command_mode = 1;
|
||||
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
|
||||
} else {
|
||||
printf("Unknown command!\n\r");
|
||||
HAL_I2C_Master_Transmit(&hi2c1, 0x29 << 1, &byte, 1, 1000);
|
||||
}
|
||||
|
||||
cmd_buffer_len = 0;
|
||||
is_command = 0;
|
||||
}
|
||||
HAL_UART_Receive_IT(&huart2, &byte, 1);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user