update format and stuff

This commit is contained in:
Mateusz Faderewski 2022-08-15 20:33:05 +02:00
parent 9dd8fc7445
commit a72996dffb
23 changed files with 338 additions and 149 deletions

View File

@ -55,7 +55,7 @@ SECTIONS {
. = ALIGN(4);
*(.rodata)
*(.rodata*)
. = ALIGN(8);
. = ALIGN(4);
} > rom
_estack = ORIGIN(ram) + LENGTH(ram);

View File

@ -1,9 +1,9 @@
EXE_NAME = app
LD_SCRIPT = app.ld
BUILD_DIR = build_app
BUILD_DIR = build/app
SRC_FILES = \
app_startup.S \
app_main.c \
app.S \
app.c \
cfg.c \
cic.c \
dd.c \
@ -22,4 +22,4 @@ SRC_FILES = \
include common.mk
$(BUILD_DIR)/app_startup.S.o: ../build_loader/loader.bin
$(BUILD_DIR)/app.S.o: ../build/loader/loader.bin

View File

@ -58,7 +58,7 @@ SECTIONS {
_srodata = .;
*(.rodata)
*(.rodata*)
. = ALIGN(8);
. = ALIGN(4);
_erodata = .;
} > ram AT > rom

View File

@ -1,14 +1,12 @@
EXE_NAME = loader
LD_SCRIPT = loader.ld
BUILD_DIR = build_loader
BUILD_DIR = build/loader
SRC_FILES = \
loader_startup.S \
boot.c \
debug.c \
loader.S \
fpga.c \
hw.c \
lcmxo2.c \
loader_main.c \
loader.c \
update.c
include common.mk

View File

@ -6,7 +6,7 @@
.section .loader, "a", %progbits
.type g_pfnVectors, %object
loader:
.incbin "../build_loader/loader.bin"
.incbin "../build/loader/loader.bin"
.section .text.Reset_Handler
@ -43,7 +43,7 @@ init_bss:
bcc 1b
run:
bl app_main
bl app
loop:
b loop

View File

@ -16,7 +16,7 @@ uint8_t rtc_stack[RTC_STACK_SIZE] __attribute__((aligned(8)));
uint8_t gvr_stack[GVR_STACK_SIZE] __attribute__((aligned(8)));
void app_main (void) {
void app (void) {
hw_init();
cic_hw_init();
@ -25,6 +25,4 @@ void app_main (void) {
task_create(TASK_ID_GVR, gvr_task, gvr_stack, GVR_STACK_SIZE);
task_scheduler_start();
while (1);
}

View File

@ -1,4 +1,3 @@
#include <stdbool.h>
#include "cfg.h"
#include "dd.h"
#include "flash.h"
@ -346,7 +345,7 @@ void cfg_process (void) {
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
return;
}
usb_create_packet(&packet_info, PACKET_CMD_USB_OUTPUT);
usb_create_packet(&packet_info, PACKET_CMD_DEBUG_OUTPUT);
packet_info.dma_length = args[1];
packet_info.dma_address = args[0];
packet_info.done_callback = cfg_set_usb_output_ready;

View File

@ -2,6 +2,7 @@
#define CFG_H__
#include <stdbool.h>
#include <stdint.h>

View File

@ -1,3 +1,5 @@
// Original code from https://github.com/jago85/UltraCIC_C licensed under the MIT License
#include <stdbool.h>
#include "cic.h"
#include "hw.h"

View File

@ -1,6 +1,4 @@
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "dd.h"
#include "fpga.h"
#include "hw.h"

View File

@ -1,4 +1,3 @@
#include <stdbool.h>
#include <stdint.h>
#include "fpga.h"

View File

@ -1,5 +1,5 @@
#include "dd.h"
#include "cfg.h"
#include "dd.h"
#include "flashram.h"
#include "fpga.h"
#include "isv.h"

View File

@ -45,7 +45,7 @@ typedef struct {
} gpio_irq_callback_t;
static const GPIO_TypeDef *gpios[] = { GPIOA, GPIOB };
static const GPIO_TypeDef *gpios[] = { GPIOA, GPIOB, 0, 0, 0, 0, 0, 0 };
static gpio_irq_callback_t gpio_irq_callbacks[16];
static volatile uint8_t *i2c_data_txptr;
static volatile uint8_t *i2c_data_rxptr;
@ -61,10 +61,6 @@ static void hw_gpio_init (gpio_id_t id, gpio_mode_t mode, gpio_ot_t ot, gpio_osp
uint8_t pin = (id & 0x0F);
uint8_t afr = ((pin < 8) ? 0 : 1);
if (!gpio) {
return;
}
tmp.MODER = (gpio->MODER & ~(GPIO_MODER_MODE0_Msk << (pin * 2)));
tmp.OTYPER = (gpio->OTYPER & ~(GPIO_OTYPER_OT0_Msk << pin));
tmp.OSPEEDR = (gpio->OSPEEDR & ~(GPIO_OSPEEDR_OSPEED0_Msk << (pin * 2)));
@ -81,7 +77,7 @@ static void hw_gpio_init (gpio_id_t id, gpio_mode_t mode, gpio_ot_t ot, gpio_osp
}
void hw_gpio_irq_setup (gpio_id_t id, gpio_irq_t irq, void (*callback)(void)) {
uint8_t port = ((id >> 4) & 0x0F);
uint8_t port = ((id >> 4) & 0x07);
uint8_t pin = (id & 0x0F);
if (irq == GPIO_IRQ_FALLING) {
EXTI->FTSR1 |= (EXTI_FTSR1_FT0 << pin);
@ -214,6 +210,12 @@ void hw_tim_setup (tim_id_t id, uint16_t delay, void (*callback)(void)) {
tim_callbacks[id] = callback;
}
void hw_tim_stop (tim_id_t id) {
TIM_TypeDef *tim = ((TIM_TypeDef *) (tims[id]));
tim->CR1 &= ~(TIM_CR1_CEN);
tim_callbacks[id] = 0;
}
void hw_tim_disable_irq (tim_id_t id) {
switch (id) {
case TIM_ID_CIC:
@ -252,10 +254,26 @@ void hw_tim_enable_irq (tim_id_t id) {
}
}
void hw_tim_stop (tim_id_t id) {
TIM_TypeDef *tim = ((TIM_TypeDef *) (tims[id]));
tim->CR1 &= ~(TIM_CR1_CEN);
tim_callbacks[id] = 0;
void hw_delay_ms (uint32_t ms) {
SysTick->VAL = 0;
for (uint32_t i = 0; i < ms; i++) {
while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));
}
}
void hw_crc32_reset (void) {
CRC->CR |= CRC_CR_RESET;
}
uint32_t hw_crc32_calculate (uint8_t *data, uint32_t length) {
for (uint32_t i = 0; i < length; i++) {
*(__IO uint8_t *) (CRC->DR) = data[i];
}
return CRC->DR;
}
uint32_t hw_flash_size (void) {
return FLASH_SIZE;
}
static void hw_flash_unlock (void) {
@ -274,12 +292,12 @@ void hw_flash_erase (void) {
FLASH->CR &= ~(FLASH_CR_MER1);
}
void hw_flash_program (uint32_t address, uint64_t value) {
void hw_flash_program (uint32_t offset, hw_flash_t value) {
hw_flash_unlock();
FLASH->CR |= FLASH_CR_PG;
*(__IO uint32_t *) (address) = ((value) & 0xFFFFFFFF);
*(__IO uint32_t *) (FLASH_BASE + offset) = ((value) & 0xFFFFFFFF);
__ISB();
*(__IO uint32_t *) (address + 4) = ((value >> 32) & 0xFFFFFFFF);
*(__IO uint32_t *) (FLASH_BASE + offset + 4) = ((value >> 32) & 0xFFFFFFFF);
while (FLASH->SR & FLASH_SR_BSY1);
if (FLASH->SR & FLASH_SR_EOP) {
FLASH->SR |= FLASH_SR_EOP;
@ -287,31 +305,30 @@ void hw_flash_program (uint32_t address, uint64_t value) {
FLASH->CR &= ~(FLASH_CR_PG);
}
void hw_loader_reset (uint32_t *parameters) {
hw_flash_t hw_flash_read (uint32_t offset) {
return *(uint64_t *) (FLASH_BASE + offset);
}
void hw_loader_reset (loader_parameters_t *parameters) {
RCC->APBENR1 |= RCC_APBENR1_PWREN | RCC_APBENR1_RTCAPBEN;
PWR->CR1 |= PWR_CR1_DBP;
TAMP->BKP0R = *parameters++;
TAMP->BKP1R = *parameters++;
TAMP->BKP2R = *parameters++;
TAMP->BKP3R = *parameters++;
TAMP->BKP4R = *parameters++;
TAMP->BKP0R = parameters->magic;
TAMP->BKP1R = parameters->mcu_address;
TAMP->BKP2R = parameters->mcu_length;
TAMP->BKP3R = parameters->fpga_address;
TAMP->BKP4R = parameters->fpga_length;
PWR->CR1 &= ~(PWR_CR1_DBP);
RCC->APBENR1 &= ~(RCC_APBENR1_PWREN | RCC_APBENR1_RTCAPBEN);
NVIC_SystemReset();
}
void hw_loader_get_parameters (uint32_t *parameters) {
RCC->APBENR1 |= RCC_APBENR1_PWREN | RCC_APBENR1_RTCAPBEN;
*parameters++ = TAMP->BKP0R;
*parameters++ = TAMP->BKP1R;
*parameters++ = TAMP->BKP2R;
*parameters++ = TAMP->BKP3R;
*parameters++ = TAMP->BKP4R;
RCC->APBENR1 &= ~(RCC_APBENR1_PWREN | RCC_APBENR1_RTCAPBEN);
}
void hw_loader_clear_parameters (void) {
void hw_loader_get_parameters (loader_parameters_t *parameters) {
RCC->APBENR1 |= RCC_APBENR1_PWREN | RCC_APBENR1_RTCAPBEN;
parameters->magic = TAMP->BKP0R;
parameters->mcu_address = TAMP->BKP1R;
parameters->mcu_length = TAMP->BKP2R;
parameters->fpga_address = TAMP->BKP3R;
parameters->fpga_length = TAMP->BKP4R;
PWR->CR1 |= PWR_CR1_DBP;
TAMP->BKP0R = 0;
TAMP->BKP1R = 0;
@ -420,6 +437,12 @@ static void hw_init_tim (void) {
}
static void hw_init_misc (void) {
SysTick->LOAD = (((64000000 / 1000)) - 1);
SysTick->VAL = 0;
SysTick->CTRL = (SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk);
RCC->AHBENR |= RCC_AHBENR_CRCEN;
hw_gpio_init(GPIO_ID_N64_RESET, GPIO_INPUT, GPIO_PP, GPIO_SPEED_VLOW, GPIO_PULL_DOWN, GPIO_AF_0, 0);
hw_gpio_init(GPIO_ID_N64_CIC_CLK, GPIO_INPUT, GPIO_PP, GPIO_SPEED_VLOW, GPIO_PULL_DOWN, GPIO_AF_0, 0);
hw_gpio_init(GPIO_ID_N64_CIC_DQ, GPIO_OUTPUT, GPIO_OD, GPIO_SPEED_VLOW, GPIO_PULL_UP, GPIO_AF_0, 1);

View File

@ -5,10 +5,6 @@
#include <stdint.h>
#define HW_UPDATE_START_MAGIC (0x54535055)
#define HW_UPDATE_DONE_MAGIC (0x4B4F5055)
#define HW_FLASH_ADDRESS (0x08000000)
#define GPIO_PORT_PIN(p, n) ((((p) & 0x07) << 4) | ((n) & 0x0F))
typedef enum {
@ -45,6 +41,16 @@ typedef enum {
SPI_RX,
} spi_direction_t;
typedef uint64_t hw_flash_t;
typedef struct {
uint32_t magic;
uint32_t mcu_address;
uint32_t mcu_length;
uint32_t fpga_address;
uint32_t fpga_length;
} loader_parameters_t;
void hw_gpio_irq_setup (gpio_id_t id, gpio_irq_t irq, void (*callback)(void));
uint32_t hw_gpio_get (gpio_id_t id);
@ -63,13 +69,17 @@ void hw_tim_setup (tim_id_t id, uint16_t delay, void (*callback)(void));
void hw_tim_stop (tim_id_t id);
void hw_tim_disable_irq (tim_id_t id);
void hw_tim_enable_irq (tim_id_t id);
void hw_delay_ms (uint32_t ms);
void hw_crc32_reset (void);
uint32_t hw_crc32_calculate (uint8_t *data, uint32_t length);
uint32_t hw_flash_size (void);
void hw_flash_erase (void);
void hw_flash_program (uint32_t address, uint64_t value);
void hw_loader_reset (uint32_t *parameters);
void hw_loader_get_parameters (uint32_t *parameters);
void hw_loader_clear_parameters (void);
void hw_loader_init (void);
void hw_flash_program (uint32_t offset, hw_flash_t value);
hw_flash_t hw_flash_read (uint32_t offset);
void hw_loader_reset (loader_parameters_t *parameters);
void hw_loader_get_parameters (loader_parameters_t *parameters);
void hw_init (void);
void hw_loader_init (void);
#endif

View File

@ -1,3 +1,4 @@
#include <stdint.h>
#include "fpga.h"
#include "isv.h"
#include "usb.h"

View File

@ -40,7 +40,7 @@ init_bss:
bcc 1b
run:
bl loader_main
bl loader
boot:
ldr r0, =_app_magic

View File

@ -1,8 +1,16 @@
#include <stdint.h>
#include <stm32g030xx.h>
#include "hw.h"
#include "update.h"
void loader (void) {
if (update_check()) {
hw_loader_init();
update_perform();
}
}
void no_valid_image (void) {
hw_gpio_set(GPIO_ID_LED);
}

View File

@ -1,24 +0,0 @@
#include <stdint.h>
#include "hw.h"
#include "update.h"
void loader_main (void) {
uint32_t parameters[5];
hw_loader_get_parameters(parameters);
if (parameters[0] == HW_UPDATE_START_MAGIC) {
hw_loader_clear_parameters();
hw_loader_init();
hw_gpio_set(GPIO_ID_LED);
update_perform(parameters);
hw_gpio_reset(GPIO_ID_LED);
parameters[0] = HW_UPDATE_DONE_MAGIC;
hw_loader_reset(parameters);
}
}

View File

@ -1,3 +1,4 @@
#include <stdint.h>
#include <stm32g0xx.h>
#include "task.h"

View File

@ -1,4 +1,3 @@
#include <stdint.h>
#include "fpga.h"
#include "hw.h"
#include "update.h"
@ -6,64 +5,243 @@
#include "vendor.h"
static uint32_t update_mcu_address;
static uint32_t update_mcu_length;
static uint32_t update_fpga_address;
static uint32_t update_fpga_length;
#define UPDATE_MAGIC_START (0x54535055)
uint32_t update_backup (uint32_t address) {
// TODO: create backup
return 0;
typedef enum {
UPDATE_STATUS_NONE = 0,
UPDATE_STATUS_START = 1,
UPDATE_STATUS_MCU_START = 2,
UPDATE_STATUS_MCU_DONE = 3,
UPDATE_STATUS_FPGA_START = 4,
UPDATE_STATUS_FPGA_DONE = 5,
UPDATE_STATUS_DONE = 6,
UPDATE_STATUS_ERROR = 0xFF,
} update_status_t;
typedef enum {
CHUNK_ID_UPDATE_INFO = 1,
CHUNK_ID_MCU_DATA = 2,
CHUNK_ID_FPGA_DATA = 3,
} chunk_id_t;
static loader_parameters_t parameters;
static const uint8_t update_token[16] = "SC64 Update v2.0";
static uint8_t status_data[12] = {
'P', 'K', 'T', PACKET_CMD_UPDATE_STATUS,
0, 0, 0, 4,
0, 0, 0, UPDATE_STATUS_NONE,
};
static uint32_t update_checksum (uint32_t address, uint32_t length) {
uint32_t remaining = length;
uint32_t block_size;
uint32_t checksum;
uint8_t buffer[32];
hw_crc32_reset();
for (uint32_t i = 0; i < length; i += sizeof(buffer)) {
block_size = (remaining > sizeof(buffer)) ? sizeof(buffer) : remaining;
fpga_mem_read(address, block_size, buffer);
checksum = hw_crc32_calculate(buffer, sizeof(buffer));
remaining -= block_size;
}
return checksum;
}
static uint32_t update_write_token (uint32_t *address) {
uint32_t length = sizeof(update_token);
fpga_mem_write(*address, sizeof(update_token), update_token);
*address += length;
return length;
}
static uint32_t update_prepare_chunk (uint32_t *address, chunk_id_t chunk_id) {
uint32_t id = (uint32_t) (chunk_id);
uint32_t length = sizeof(id) + (2 * sizeof(uint32_t));
fpga_mem_write(*address, sizeof(id), (uint8_t *) (&id));
*address += length;
return length;
}
static uint32_t update_finalize_chunk (uint32_t *address, uint32_t length) {
uint32_t checksum = update_checksum(*address, length);
fpga_mem_write(*address - (2 * sizeof(uint32_t)), sizeof(length), (uint8_t *) (&length));
fpga_mem_write(*address - sizeof(uint32_t), sizeof(checksum), (uint8_t *) (&checksum));
*address += length;
return length;
}
static bool update_check_token (uint32_t *address) {
uint8_t buffer[sizeof(update_token)];
fpga_mem_read(*address, sizeof(update_token), buffer);
for (int i = 0; i < sizeof(update_token); i++) {
if (buffer[i] != update_token[i]) {
return true;
}
}
*address += sizeof(update_token);
return false;
}
static bool update_get_chunk (uint32_t *address, chunk_id_t *chunk_id, uint32_t *data_address, uint32_t *data_length) {
uint32_t id;
uint32_t checksum;
fpga_mem_read(*address, sizeof(id), (uint8_t *) (id));
*address += sizeof(id);
fpga_mem_read(*address, sizeof(*data_length), (uint8_t *) (data_length));
*address += sizeof(*data_length);
fpga_mem_read(*address, sizeof(checksum), (uint8_t *) (checksum));
*address += sizeof(checksum);
*data_address = *address;
*address += *data_length;
if (checksum != update_checksum(*data_address, *data_length)) {
return true;
}
return false;
}
static void update_blink_led (uint32_t on, uint32_t off, int repeat) {
for (int i = 0; i < repeat; i++) {
hw_gpio_set(GPIO_ID_LED);
hw_delay_ms(on);
hw_gpio_reset(GPIO_ID_LED);
hw_delay_ms(off);
}
}
static void update_status_notify (update_status_t status) {
status_data[sizeof(status_data) - 1] = (uint8_t) (status);
for (int i = 0; i < sizeof(status_data); i++) {
while (!(fpga_usb_status_get() & USB_STATUS_TXE));
fpga_usb_push(status_data[i]);
}
fpga_reg_set(REG_USB_SCR, USB_SCR_WRITE_FLUSH);
if (status != UPDATE_STATUS_ERROR) {
update_blink_led(100, 250, status);
hw_delay_ms(1000);
} else {
update_blink_led(1000, 1000, 30);
}
}
update_error_t update_backup (uint32_t address, uint32_t *length) {
hw_flash_t buffer;
uint32_t fpga_length;
*length += update_write_token(&address);
*length += update_prepare_chunk(&address, CHUNK_ID_MCU_DATA);
for (uint32_t offset = 0; offset < hw_flash_size(); offset += sizeof(hw_flash_t)) {
buffer = hw_flash_read(offset);
fpga_mem_write(address + offset, sizeof(hw_flash_t), (uint8_t *) (&buffer));
}
*length += update_finalize_chunk(&address, hw_flash_size());
*length += update_prepare_chunk(&address, CHUNK_ID_FPGA_DATA);
if (vendor_backup(address, &fpga_length) != VENDOR_OK) {
return UPDATE_ERROR_READ;
}
*length += update_finalize_chunk(&address, fpga_length);
return UPDATE_OK;
}
update_error_t update_prepare (uint32_t address, uint32_t length) {
// TODO: validate image
update_mcu_address = 0;
update_mcu_length = 0;
update_fpga_address = 0;
update_fpga_length = 0;
uint32_t end_address = address + length;
chunk_id_t id;
uint32_t data_address;
uint32_t data_length;
if (update_check_token(&address)) {
return UPDATE_ERROR_TOKEN;
}
parameters.mcu_address = 0;
parameters.mcu_length = 0;
parameters.fpga_address = 0;
parameters.fpga_length = 0;
while (address < end_address) {
if (update_get_chunk(&address, &id, &data_address, &data_length)) {
return UPDATE_ERROR_CHECKSUM;
}
switch (id) {
case CHUNK_ID_UPDATE_INFO:
break;
case CHUNK_ID_MCU_DATA:
parameters.mcu_address = data_address;
parameters.mcu_length = data_length;
break;
case CHUNK_ID_FPGA_DATA:
parameters.fpga_address = data_address;
parameters.fpga_length = data_length;
break;
default:
return UPDATE_ERROR_UNKNOWN_CHUNK;
}
}
return UPDATE_OK;
}
void update_start (void) {
uint32_t parameters[5] = {
HW_UPDATE_START_MAGIC,
update_mcu_address,
update_mcu_length,
update_fpga_address,
update_fpga_length,
};
hw_loader_reset(parameters);
parameters.magic = UPDATE_MAGIC_START;
hw_loader_reset(&parameters);
}
void update_perform (uint32_t *parameters) {
uint64_t buffer;
bool update_check (void) {
hw_loader_get_parameters(&parameters);
return (parameters.magic == UPDATE_MAGIC_START);
}
void update_perform (void) {
hw_flash_t buffer;
update_status_notify(UPDATE_STATUS_START);
if (parameters.mcu_length != 0) {
update_status_notify(UPDATE_STATUS_MCU_START);
if (parameters[2] != 0) {
hw_flash_erase();
for (int i = 0; i < parameters[2]; i += sizeof(buffer)) {
fpga_mem_read(parameters[1] + i, sizeof(buffer), (uint8_t *) (&buffer));
hw_flash_program(HW_FLASH_ADDRESS + i, buffer);
for (uint32_t offset = 0; offset < parameters.mcu_length; offset += sizeof(hw_flash_t)) {
fpga_mem_read(parameters.mcu_address + offset, sizeof(hw_flash_t), (uint8_t *) (&buffer));
hw_flash_program(offset, buffer);
if (hw_flash_read(offset) != buffer) {
update_status_notify(UPDATE_STATUS_ERROR);
while (1); // TODO: jump to STM32 bootloader?
}
}
update_status_notify(UPDATE_STATUS_MCU_DONE);
}
if (parameters[4] != 0) {
vendor_update(parameters[3], parameters[4]);
if (parameters.fpga_length != 0) {
update_status_notify(UPDATE_STATUS_FPGA_START);
if (vendor_update(parameters.fpga_address, parameters.fpga_length) != VENDOR_OK) {
update_status_notify(UPDATE_STATUS_ERROR);
while (1); // TODO: jump to STM32 bootloader?
}
update_status_notify(UPDATE_STATUS_FPGA_DONE);
}
update_status_notify(UPDATE_STATUS_DONE);
vendor_reconfigure();
}
void update_notify_done (void) {
uint32_t parameters[5];
usb_tx_info_t packet;
hw_loader_get_parameters(parameters);
if (parameters[0] == HW_UPDATE_DONE_MAGIC) {
hw_loader_clear_parameters();
usb_create_packet(&packet, PACKET_CMD_UPDATE_DONE);
usb_enqueue_packet(&packet);
}
parameters.magic = 0;
hw_loader_reset(&parameters);
}

View File

@ -2,21 +2,24 @@
#define UPDATE_H__
#include <stdbool.h>
#include <stdint.h>
typedef enum {
UPDATE_OK,
UPDATE_ERROR_INVALID_HEADER,
UPDATE_ERROR_TOKEN,
UPDATE_ERROR_CHECKSUM,
UPDATE_ERROR_UNKNOWN_CHUNK,
UPDATE_ERROR_READ,
} update_error_t;
uint32_t update_backup (uint32_t address);
update_error_t update_backup (uint32_t address, uint32_t *length);
update_error_t update_prepare (uint32_t address, uint32_t length);
void update_start (void);
void update_perform (uint32_t *parameters);
void update_notify_done (void);
bool update_check (void);
void update_perform (void);
#endif

View File

@ -1,5 +1,3 @@
#include <stdbool.h>
#include <stdint.h>
#include "cfg.h"
#include "cic.h"
#include "dd.h"
@ -211,8 +209,8 @@ static void usb_rx_process (void) {
p.response_info.dma_length = p.rx_args[1];
break;
case 'M':
case 'D':
case 'M':
if (usb_dma_ready()) {
if (!p.rx_dma_running) {
fpga_reg_set(REG_USB_DMA_ADDRESS, p.rx_args[0]);
@ -251,10 +249,11 @@ static void usb_rx_process (void) {
break;
case 'f':
p.response_info.data[0] = update_backup(p.rx_args[0]);
p.response_info.data[0] = update_backup(p.rx_args[0], &p.response_info.data[1]);
p.rx_state = RX_STATE_IDLE;
p.response_pending = true;
p.response_info.data_length = 4;
p.response_error = (p.response_info.data[0] != UPDATE_OK);
p.response_info.data_length = 8;
break;
case 'F':
@ -355,8 +354,8 @@ static void usb_tx_process (void) {
}
void usb_create_packet (usb_tx_info_t *info, uint8_t cmd) {
info->cmd = cmd;
void usb_create_packet (usb_tx_info_t *info, usb_packet_cmd_e cmd) {
info->cmd = (uint8_t) (cmd);
info->data_length = 0;
for (int i = 0; i < 4; i++) {
info->data[i] = 0;
@ -394,7 +393,7 @@ void usb_get_read_info (uint32_t *args) {
args[0] |= (p.read_length > 0) ? (1 << 24) : 0;
}
static void usb_reinit (void) {
void usb_init (void) {
fpga_reg_set(REG_USB_DMA_SCR, DMA_SCR_STOP);
fpga_reg_set(REG_USB_SCR, USB_SCR_FIFO_FLUSH);
@ -414,17 +413,12 @@ static void usb_reinit (void) {
usb_rx_cmd_counter = 0;
}
void usb_init (void) {
usb_reinit();
update_notify_done();
}
void usb_process (void) {
if (fpga_reg_get(REG_USB_SCR) & USB_SCR_RESET_PENDING) {
if (p.tx_state != TX_STATE_IDLE && p.tx_info.done_callback) {
p.tx_info.done_callback();
}
usb_reinit();
usb_init();
fpga_reg_set(REG_USB_SCR, USB_SCR_RESET_ACK);
} else {
usb_rx_process();

View File

@ -8,9 +8,9 @@
typedef enum packet_cmd {
PACKET_CMD_DD_REQUEST = 'D',
PACKET_CMD_DEBUG_OUTPUT = 'U',
PACKET_CMD_ISV_OUTPUT = 'I',
PACKET_CMD_USB_OUTPUT = 'U',
PACKET_CMD_UPDATE_DONE = 'F',
PACKET_CMD_UPDATE_STATUS = 'F',
} usb_packet_cmd_e;
@ -24,7 +24,7 @@ typedef struct usb_tx_info {
} usb_tx_info_t;
void usb_create_packet (usb_tx_info_t *info, uint8_t cmd);
void usb_create_packet (usb_tx_info_t *info, usb_packet_cmd_e cmd);
bool usb_enqueue_packet (usb_tx_info_t *info);
bool usb_prepare_read (uint32_t *args);
void usb_get_read_info (uint32_t *args);