added mcu update

This commit is contained in:
Polprzewodnikowy 2022-08-03 08:53:30 +02:00
parent 9c710a2019
commit a0105c4523
19 changed files with 544 additions and 110 deletions

View File

@ -47,9 +47,9 @@ build_controller () {
pushd sw/controller > /dev/null
if [ "$FORCE_CLEAN" = true ]; then
make clean
./build.sh clean
fi
make all -j USER_FLAGS="$USER_FLAGS"
USER_FLAGS="$USER_FLAGS" ./build.sh all
popd > /dev/null
BUILT_CONTROLLER=true

View File

@ -1,2 +1,3 @@
/build
/build_app
/build_loader
*.svd

View File

@ -1,11 +1,18 @@
MEMORY {
rom (rx) : org = 0x08000000, len = 32k
loader (rx) : org = 0x08000000, len = 4k
rom (rx) : org = 0x08001000, len = 28k
ram (rwx) : org = 0x20000000, len = 8k
}
ENTRY(Reset_Handler)
SECTIONS {
.loader : {
. = ALIGN(4);
KEEP(*(.loader))
. = ALIGN(4);
} > loader
.isr_vector : {
. = ALIGN(4);
KEEP(*(.isr_vector))
@ -22,23 +29,6 @@ SECTIONS {
_etext = .;
} > rom
.rodata : {
. = ALIGN(4);
*(.rodata)
*(.rodata*)
. = ALIGN(4);
} > rom
.data : {
_sidata = LOADADDR(.data);
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
} > ram AT > rom
.bss : {
. = ALIGN(4);
_sbss = .;
@ -51,5 +41,22 @@ SECTIONS {
__bss_end__ = _ebss;
} > ram
.data : {
_sidata = LOADADDR(.data);
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
} > ram AT > rom
.rodata : {
. = ALIGN(4);
*(.rodata)
*(.rodata*)
. = ALIGN(8);
} > rom
_estack = ORIGIN(ram) + LENGTH(ram);
}

25
sw/controller/app.mk Normal file
View File

@ -0,0 +1,25 @@
EXE_NAME = app
LD_SCRIPT = app.ld
BUILD_DIR = build_app
SRC_FILES = \
app_startup.S \
app_main.c \
cfg.c \
cic.c \
dd.c \
debug.c \
flash.c \
flashram.c \
fpga.c \
gvr.c \
hw.c \
isv.c \
lcmxo2.c \
rtc.c \
task.c \
update.c \
usb.c
include common.mk
$(BUILD_DIR)/app_startup.S.o: ../build_loader/loader.bin

13
sw/controller/build.sh Normal file
View File

@ -0,0 +1,13 @@
#!/bin/bash
case "$1" in
all)
make all -j -f loader.mk USER_FLAGS="$USER_FLAGS"
make all -j -f app.mk USER_FLAGS="$USER_FLAGS"
;;
clean)
make clean -f loader.mk
make clean -f app.mk
;;
esac

View File

@ -10,25 +10,6 @@ CFLAGS = -Og -Wall -ffunction-sections -fdata-sections -ffreestanding -MMD -MP -
LDFLAGS = -nostartfiles -Wl,--gc-sections
SRC_DIR = src
BUILD_DIR = build
SRC_FILES = \
startup.S \
cfg.c \
cic.c \
dd.c \
debug.c \
flash.c \
flashram.c \
fpga.c \
gvr.c \
hw.c \
isv.c \
lcmxo2.c \
main.c \
rtc.c \
task.c \
usb.c
SRCS = $(addprefix $(SRC_DIR)/, $(SRC_FILES))
OBJS = $(addprefix $(BUILD_DIR)/, $(notdir $(patsubst %,%.o,$(SRCS))))
@ -44,23 +25,23 @@ $(BUILD_DIR)/%.S.o: %.S
$(BUILD_DIR)/%.c.o: %.c
$(CC) $(FLAGS) $(CFLAGS) -c $< -o $@
$(BUILD_DIR)/controller.elf: $(OBJS) STM32G030F6Px_FLASH.ld
$(CXX) $(FLAGS) $(LDFLAGS) -TSTM32G030F6Px_FLASH.ld $(OBJS) -o $@
@$(OBJDUMP) -S -D $@ > $(BUILD_DIR)/controller.lst
$(BUILD_DIR)/$(EXE_NAME).elf: $(OBJS) $(LD_SCRIPT)
$(CXX) $(FLAGS) $(LDFLAGS) -T$(LD_SCRIPT) $(OBJS) -o $@
@$(OBJDUMP) -S -D $@ > $(BUILD_DIR)/$(EXE_NAME).lst
$(BUILD_DIR)/controller.bin: $(BUILD_DIR)/controller.elf
@$(OBJCOPY) -O binary $< $@
$(BUILD_DIR)/$(EXE_NAME).bin: $(BUILD_DIR)/$(EXE_NAME).elf
$(OBJCOPY) -O binary $< $@
$(BUILD_DIR)/controller.hex: $(BUILD_DIR)/controller.bin
$(BUILD_DIR)/$(EXE_NAME).hex: $(BUILD_DIR)/$(EXE_NAME).bin
@$(OBJCOPY) -I binary -O ihex $< $@
print_size: $(BUILD_DIR)/controller.elf
print_size: $(BUILD_DIR)/$(EXE_NAME).elf
@echo 'Size of modules:'
@$(SIZE) -B -d -t --common $(OBJS)
@echo 'Size of controller:'
@echo 'Size of $(EXE_NAME):'
@$(SIZE) -B -d $<
all: $(BUILD_DIR)/controller.hex print_size
all: $(BUILD_DIR)/$(EXE_NAME).hex print_size
clean:
@rm -rf ./$(BUILD_DIR)/*

68
sw/controller/loader.ld Normal file
View File

@ -0,0 +1,68 @@
MEMORY {
rom (rx) : org = 0x08000000, len = 4k
ram (rwx) : org = 0x20000000, len = 8k
}
ENTRY(Reset_Handler)
SECTIONS {
.isr_vector : {
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} > rom
.startup : {
. = ALIGN(4);
*(.text.Reset_Handler)
. = ALIGN(4);
} > rom
.text : {
_sitext = LOADADDR(.text);
. = ALIGN(4);
_stext = .;
*(.text)
*(.text*)
*(.glue_7)
*(.glue_7t)
. = ALIGN(4);
_etext = .;
} > ram AT > rom
.bss : {
. = ALIGN(4);
_sbss = .;
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end__ = _ebss;
} > ram
.data : {
_sidata = LOADADDR(.data);
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
} > ram AT > rom
.rodata : {
_sirodata = LOADADDR(.rodata);
. = ALIGN(4);
_srodata = .;
*(.rodata)
*(.rodata*)
. = ALIGN(8);
_erodata = .;
} > ram AT > rom
_app_header = ORIGIN(rom) + LENGTH(rom);
_app_magic = _app_header + 16;
_estack = ORIGIN(ram) + LENGTH(ram);
}

13
sw/controller/loader.mk Normal file
View File

@ -0,0 +1,13 @@
EXE_NAME = loader
LD_SCRIPT = loader.ld
BUILD_DIR = build_loader
SRC_FILES = \
loader_startup.S \
boot.c \
debug.c \
fpga.c \
hw.c \
lcmxo2.c \
loader_main.c
include common.mk

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 main (void) {
void app_main (void) {
hw_init();
cic_hw_init();

View File

@ -3,6 +3,12 @@
.fpu softvfp
.thumb
.section .loader, "a", %progbits
.type g_pfnVectors, %object
loader:
.incbin "../build_loader/loader.bin"
.section .text.Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
@ -37,7 +43,7 @@ init_bss:
bcc 1b
run:
bl main
bl app_main
loop:
b loop
@ -57,7 +63,7 @@ g_pfnVectors:
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word 0
.word 0x34364353
.word 0
.word 0
.word 0

12
sw/controller/src/boot.c Normal file
View File

@ -0,0 +1,12 @@
#include <stdint.h>
#include <stm32g030xx.h>
#include "hw.h"
void no_valid_image (void) {
hw_gpio_set(GPIO_ID_LED);
}
void set_vector_table_offset (uint32_t offset) {
SCB->VTOR = (__IOM uint32_t) (offset);
}

View File

@ -55,7 +55,7 @@ static const TIM_TypeDef *tims[] = { TIM14, TIM16, TIM17, TIM3 };
static void (*volatile tim_callbacks[4])(void);
void hw_gpio_init (gpio_id_t id, gpio_mode_t mode, gpio_ot_t ot, gpio_ospeed_t ospeed, gpio_pupd_t pupd, gpio_af_t af, int value) {
static void hw_gpio_init (gpio_id_t id, gpio_mode_t mode, gpio_ot_t ot, gpio_ospeed_t ospeed, gpio_pupd_t pupd, gpio_af_t af, int value) {
GPIO_TypeDef tmp;
GPIO_TypeDef *gpio = ((GPIO_TypeDef *) (gpios[(id >> 4) & 0x07]));
uint8_t pin = (id & 0x0F);
@ -258,7 +258,71 @@ void hw_tim_stop (tim_id_t id) {
tim_callbacks[id] = 0;
}
void hw_init (void) {
static void hw_flash_unlock (void) {
while (FLASH->SR & FLASH_SR_BSY1);
if (FLASH->CR & FLASH_CR_LOCK) {
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;
}
}
void hw_flash_erase (void) {
hw_flash_unlock();
FLASH->CR |= FLASH_CR_MER1;
FLASH->CR |= FLASH_CR_STRT;
while (FLASH->SR & FLASH_SR_BSY1);
FLASH->CR &= ~(FLASH_CR_MER1);
}
void hw_flash_program (uint32_t address, uint64_t value) {
hw_flash_unlock();
FLASH->CR |= FLASH_CR_PG;
*(__IO uint32_t *) (address) = ((value) & 0xFFFFFFFF);
__ISB();
*(__IO uint32_t *) (address + 4) = ((value >> 32) & 0xFFFFFFFF);
while (FLASH->SR & FLASH_SR_BSY1);
if (FLASH->SR & FLASH_SR_EOP) {
FLASH->SR |= FLASH_SR_EOP;
}
FLASH->CR &= ~(FLASH_CR_PG);
}
void hw_loader_reset (uint32_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++;
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) {
RCC->APBENR1 |= RCC_APBENR1_PWREN | RCC_APBENR1_RTCAPBEN;
PWR->CR1 |= PWR_CR1_DBP;
TAMP->BKP0R = 0;
TAMP->BKP1R = 0;
TAMP->BKP2R = 0;
TAMP->BKP3R = 0;
TAMP->BKP4R = 0;
PWR->CR1 &= ~(PWR_CR1_DBP);
RCC->APBENR1 &= ~(RCC_APBENR1_PWREN | RCC_APBENR1_RTCAPBEN);
}
static void hw_init_mcu (void) {
FLASH->ACR |= (FLASH_ACR_PRFTEN | (2 << FLASH_ACR_LATENCY_Pos));
while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != (2 << FLASH_ACR_LATENCY_Pos));
@ -276,37 +340,21 @@ void hw_init (void) {
RCC->CFGR = RCC_CFGR_SW_1;
while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_1);
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
RCC->APBENR1 |= (
RCC_APBENR1_DBGEN |
RCC_APBENR1_I2C1EN |
RCC_APBENR1_TIM3EN
);
RCC->APBENR2 |= (
RCC_APBENR2_TIM17EN |
RCC_APBENR2_TIM16EN |
RCC_APBENR2_TIM14EN |
RCC_APBENR2_USART1EN |
RCC_APBENR2_SPI1EN |
RCC_APBENR2_SYSCFGEN
);
DBG->APBFZ2 = (
DBG_APB_FZ2_DBG_TIM17_STOP |
DBG_APB_FZ2_DBG_TIM16_STOP |
DBG_APB_FZ2_DBG_TIM14_STOP
);
RCC->IOPENR |= RCC_IOPENR_GPIOAEN | RCC_IOPENR_GPIOBEN;
hw_gpio_init(GPIO_ID_LED, GPIO_OUTPUT, GPIO_PP, GPIO_SPEED_VLOW, GPIO_PULL_NONE, GPIO_AF_0, 0);
}
static void hw_init_spi (void) {
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
RCC->APBENR2 |= RCC_APBENR2_SPI1EN;
DMAMUX1_Channel0->CCR = (16 << DMAMUX_CxCR_DMAREQ_ID_Pos);
DMAMUX1_Channel1->CCR = (17 << DMAMUX_CxCR_DMAREQ_ID_Pos);
DMA1_Channel1->CPAR = (uint32_t) (&SPI1->DR);
DMA1_Channel2->CPAR = (uint32_t) (&SPI1->DR);
SYSCFG->CFGR1 |= (SYSCFG_CFGR1_PA12_RMP | SYSCFG_CFGR1_PA11_RMP);
SPI1->CR2 = (
SPI_CR2_FRXTH |
(8 - 1) << SPI_CR2_DS_Pos |
@ -322,32 +370,68 @@ void hw_init (void) {
SPI_CR1_CPHA
);
USART1->BRR = (64000000UL) / 1000000;
USART1->CR1 = USART_CR1_FIFOEN | USART_CR1_TE | USART_CR1_UE;
I2C1->TIMINGR = 0x10B17DB5UL;
I2C1->CR1 |= (I2C_CR1_TCIE | I2C_CR1_STOPIE | I2C_CR1_RXIE | I2C_CR1_TXIE | I2C_CR1_PE);
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);
hw_gpio_init(GPIO_ID_LED, GPIO_OUTPUT, GPIO_PP, GPIO_SPEED_VLOW, GPIO_PULL_NONE, GPIO_AF_0, 0);
hw_gpio_init(GPIO_ID_SPI_CS, GPIO_OUTPUT, GPIO_PP, GPIO_SPEED_HIGH, GPIO_PULL_NONE, GPIO_AF_0, 1);
hw_gpio_init(GPIO_ID_SPI_CLK, GPIO_ALT, GPIO_PP, GPIO_SPEED_HIGH, GPIO_PULL_NONE, GPIO_AF_0, 0);
hw_gpio_init(GPIO_ID_SPI_MISO, GPIO_ALT, GPIO_PP, GPIO_SPEED_HIGH, GPIO_PULL_DOWN, GPIO_AF_0, 0);
hw_gpio_init(GPIO_ID_SPI_MOSI, GPIO_ALT, GPIO_PP, GPIO_SPEED_HIGH, GPIO_PULL_NONE, GPIO_AF_0, 0);
hw_gpio_init(GPIO_ID_FPGA_INT, GPIO_INPUT, GPIO_PP, GPIO_SPEED_VLOW, GPIO_PULL_UP, GPIO_AF_0, 0);
}
hw_gpio_init(GPIO_ID_UART_TX, GPIO_ALT, GPIO_PP, GPIO_SPEED_LOW, GPIO_PULL_NONE, GPIO_AF_1, 0);
hw_gpio_init(GPIO_ID_UART_RX, GPIO_ALT, GPIO_PP, GPIO_SPEED_LOW, GPIO_PULL_NONE, GPIO_AF_1, 0);
static void hw_init_i2c (void) {
RCC->APBENR1 |= RCC_APBENR1_I2C1EN;
I2C1->TIMINGR = 0x10B17DB5UL;
I2C1->CR1 |= (I2C_CR1_TCIE | I2C_CR1_STOPIE | I2C_CR1_RXIE | I2C_CR1_TXIE | I2C_CR1_PE);
hw_gpio_init(GPIO_ID_I2C_SCL, GPIO_ALT, GPIO_OD, GPIO_SPEED_VLOW, GPIO_PULL_NONE, GPIO_AF_6, 0);
hw_gpio_init(GPIO_ID_I2C_SDA, GPIO_ALT, GPIO_OD, GPIO_SPEED_VLOW, GPIO_PULL_NONE, GPIO_AF_6, 0);
hw_gpio_init(GPIO_ID_RTC_MFP, GPIO_INPUT, GPIO_PP, GPIO_SPEED_VLOW, GPIO_PULL_UP, GPIO_AF_0, 0);
}
static void hw_init_uart (void) {
RCC->APBENR2 |= (RCC_APBENR2_USART1EN | RCC_APBENR2_SYSCFGEN);
SYSCFG->CFGR1 |= (SYSCFG_CFGR1_PA12_RMP | SYSCFG_CFGR1_PA11_RMP);
USART1->BRR = (64000000UL) / 1000000;
USART1->CR1 = USART_CR1_FIFOEN | USART_CR1_TE | USART_CR1_UE;
hw_gpio_init(GPIO_ID_UART_TX, GPIO_ALT, GPIO_PP, GPIO_SPEED_LOW, GPIO_PULL_NONE, GPIO_AF_1, 0);
hw_gpio_init(GPIO_ID_UART_RX, GPIO_ALT, GPIO_PP, GPIO_SPEED_LOW, GPIO_PULL_NONE, GPIO_AF_1, 0);
}
static void hw_init_tim (void) {
RCC->APBENR1 |= (
RCC_APBENR1_DBGEN |
RCC_APBENR1_TIM3EN
);
RCC->APBENR2 |= (
RCC_APBENR2_TIM17EN |
RCC_APBENR2_TIM16EN |
RCC_APBENR2_TIM14EN |
RCC_APBENR2_USART1EN
);
DBG->APBFZ2 |= (
DBG_APB_FZ2_DBG_TIM17_STOP |
DBG_APB_FZ2_DBG_TIM16_STOP |
DBG_APB_FZ2_DBG_TIM14_STOP
);
}
static void hw_init_misc (void) {
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);
}
void hw_init (void) {
hw_init_mcu();
hw_init_spi();
hw_init_i2c();
hw_init_uart();
hw_init_tim();
hw_init_misc();
NVIC_SetPriority(EXTI0_1_IRQn, 0);
NVIC_SetPriority(EXTI2_3_IRQn, 1);
@ -367,6 +451,11 @@ void hw_init (void) {
NVIC_EnableIRQ(TIM3_IRQn);
}
void hw_loader_init (void) {
hw_init_mcu();
hw_init_spi();
}
void EXTI0_1_IRQHandler (void) {
for (int i = 0; i <= 1; i++) {

View File

@ -5,6 +5,10 @@
#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 {
@ -59,6 +63,12 @@ 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_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_init (void);

View File

@ -0,0 +1,37 @@
#include <stdint.h>
#include "fpga.h"
#include "hw.h"
#include "vendor.h"
void loader_main (void) {
uint32_t parameters[5];
uint64_t buffer;
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);
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);
}
}
if (parameters[4] != 0) {
vendor_update(parameters[3], parameters[4]);
vendor_reconfigure();
}
hw_gpio_reset(GPIO_ID_LED);
parameters[0] = HW_UPDATE_DONE_MAGIC;
hw_loader_reset(parameters);
}
}

View File

@ -0,0 +1,99 @@
.syntax unified
.cpu cortex-m0plus
.fpu softvfp
.thumb
.section .text.Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
.global Reset_Handler
cpsid i
init_text:
ldr r0, =_stext
ldr r1, =_etext
ldr r2, =_sitext
bl copy_section
init_rodata:
ldr r0, =_srodata
ldr r1, =_erodata
ldr r2, =_sirodata
bl copy_section
init_data:
ldr r0, =_sdata
ldr r1, =_edata
ldr r2, =_sidata
bl copy_section
init_bss:
ldr r2, =_sbss
ldr r4, =_ebss
movs r3, #0
b 2f
1:
str r3, [r2]
adds r2, r2, #4
2:
cmp r2, r4
bcc 1b
run:
bl loader_main
boot:
ldr r0, =_app_magic
ldr r0, [r0]
ldr r1, =0x34364353
cmp r0, r1
bne empty_image
ldr r0, =_app_header
push {r0}
bl set_vector_table_offset
pop {r0}
ldr r1, [r0, #0]
msr MSP, r1
ldr r1, [r0, #4]
blx r1
empty_image:
bl no_valid_image
loop:
b loop
copy_section:
movs r3, #0
b 2f
1:
ldr r4, [r2, r3]
str r4, [r0, r3]
adds r3, r3, #4
2:
adds r4, r0, r3
cmp r4, r1
bcc 1b
bx lr
.section .text.Default_Handler, "ax", %progbits
Default_Handler:
.global Default_Handler
b Default_Handler
.section .isr_vector, "a", %progbits
.type g_pfnVectors, %object
g_pfnVectors:
.global g_pfnVectors
.word _estack
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.weak NMI_Handler
.thumb_set NMI_Handler, Default_Handler
.weak HardFault_Handler
.thumb_set HardFault_Handler, Default_Handler

View File

@ -0,0 +1,49 @@
#include <stdint.h>
#include "hw.h"
#include "update.h"
#include "usb.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;
uint32_t update_backup (uint32_t address) {
// TODO: create backup
return 0;
}
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;
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);
}
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);
}
}

View File

@ -0,0 +1,21 @@
#ifndef UPDATE_H__
#define UPDATE_H__
#include <stdint.h>
typedef enum {
UPDATE_OK,
UPDATE_ERROR_INVALID_HEADER,
UPDATE_ERROR_CHECKSUM,
} update_error_t;
uint32_t update_backup (uint32_t address);
update_error_t update_prepare (uint32_t address, uint32_t length);
void update_start (void);
void update_notify_done (void);
#endif

View File

@ -6,8 +6,8 @@
#include "flash.h"
#include "fpga.h"
#include "rtc.h"
#include "update.h"
#include "usb.h"
#include "vendor.h"
enum rx_state {
@ -251,21 +251,20 @@ static void usb_rx_process (void) {
break;
case 'f':
p.response_info.data[0] = vendor_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 = 8;
if (p.response_info.data[0] != VENDOR_OK) {
p.response_error = true;
}
break;
case 'F':
p.response_info.data[0] = vendor_update(p.rx_args[0], p.rx_args[1]);
p.response_info.data[0] = update_backup(p.rx_args[0]);
p.rx_state = RX_STATE_IDLE;
p.response_pending = true;
p.response_info.data_length = 4;
if (p.response_info.data[0] != VENDOR_OK) {
break;
case 'F':
p.response_info.data[0] = update_prepare(p.rx_args[0], p.rx_args[1]);
p.rx_state = RX_STATE_IDLE;
p.response_pending = true;
p.response_info.data_length = 4;
if (p.response_info.data[0] == UPDATE_OK) {
p.response_info.done_callback = update_start;
} else {
p.response_error = true;
}
break;
@ -371,10 +370,8 @@ bool usb_enqueue_packet (usb_tx_info_t *info) {
if (p.packet_pending) {
return false;
}
p.packet_pending = true;
p.packet_info = *info;
return true;
}
@ -397,7 +394,7 @@ void usb_get_read_info (uint32_t *args) {
args[0] |= (p.read_length > 0) ? (1 << 24) : 0;
}
void usb_init (void) {
static void usb_reinit (void) {
fpga_reg_set(REG_USB_DMA_SCR, DMA_SCR_STOP);
fpga_reg_set(REG_USB_SCR, USB_SCR_FIFO_FLUSH);
@ -417,12 +414,17 @@ void usb_init (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_init();
usb_reinit();
fpga_reg_set(REG_USB_SCR, USB_SCR_RESET_ACK);
} else {
usb_rx_process();

View File

@ -10,6 +10,7 @@ typedef enum packet_cmd {
PACKET_CMD_DD_REQUEST = 'D',
PACKET_CMD_ISV_OUTPUT = 'I',
PACKET_CMD_USB_OUTPUT = 'U',
PACKET_CMD_UPDATE_DONE = 'F',
} usb_packet_cmd_e;