mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-12-28 05:51:53 +01:00
added mcu update
This commit is contained in:
parent
9c710a2019
commit
a0105c4523
4
build.sh
4
build.sh
@ -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
|
||||
|
3
sw/controller/.gitignore
vendored
3
sw/controller/.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
/build
|
||||
/build_app
|
||||
/build_loader
|
||||
*.svd
|
||||
|
@ -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
25
sw/controller/app.mk
Normal 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
13
sw/controller/build.sh
Normal 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
|
@ -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
68
sw/controller/loader.ld
Normal 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
13
sw/controller/loader.mk
Normal 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
|
@ -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();
|
||||
|
@ -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
12
sw/controller/src/boot.c
Normal 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);
|
||||
}
|
@ -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++) {
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
37
sw/controller/src/loader_main.c
Normal file
37
sw/controller/src/loader_main.c
Normal 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);
|
||||
}
|
||||
}
|
99
sw/controller/src/loader_startup.S
Normal file
99
sw/controller/src/loader_startup.S
Normal 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
|
49
sw/controller/src/update.c
Normal file
49
sw/controller/src/update.c
Normal 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);
|
||||
}
|
||||
}
|
21
sw/controller/src/update.h
Normal file
21
sw/controller/src/update.h
Normal 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
|
@ -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();
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user