[feat] add boot2_copy_self
This commit is contained in:
parent
f40cd252ef
commit
ec54eb19e3
50
driver/inc/reg/ssi_reg.h
Normal file
50
driver/inc/reg/ssi_reg.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef __HARDWARE_SSI_REG_H__
|
||||
#define __HARDWARE_SSI_REG_H__
|
||||
|
||||
#include "reg.h"
|
||||
|
||||
typedef struct {
|
||||
io_rw_32 ctrlr0;
|
||||
io_rw_32 ctrlr1;
|
||||
io_rw_32 ssienr;
|
||||
io_rw_32 mwcr;
|
||||
io_rw_32 ser;
|
||||
io_rw_32 baudr;
|
||||
io_rw_32 txftlr;
|
||||
io_rw_32 rxftlr;
|
||||
io_rw_32 txflr;
|
||||
io_rw_32 rxflr;
|
||||
io_rw_32 sr;
|
||||
io_rw_32 imr;
|
||||
io_rw_32 isr;
|
||||
io_rw_32 risr;
|
||||
io_rw_32 txoicr;
|
||||
io_rw_32 rxoicr;
|
||||
io_rw_32 rxuicr;
|
||||
io_rw_32 msticr;
|
||||
io_rw_32 icr;
|
||||
io_rw_32 dmacr;
|
||||
io_rw_32 dmatdlr;
|
||||
io_rw_32 dmardlr;
|
||||
io_rw_32 idr;
|
||||
io_rw_32 ssi_version_id;
|
||||
io_rw_32 dr0;
|
||||
uint32_t _pad[(0xf0 - 0x60) / 4 - 1];
|
||||
io_rw_32 rx_sample_dly;
|
||||
io_rw_32 spi_ctrlr0;
|
||||
io_rw_32 txd_drive_edge;
|
||||
} ssi_hw_t;
|
||||
|
||||
#define ssi_hw ((ssi_hw_t *const)XIP_SSI_BASE)
|
||||
#define ssi_hw_set ((ssi_hw_t *const)hw_set_alias_untyped(ssi_hw))
|
||||
#define ssi_hw_clear ((ssi_hw_t *const)hw_clear_alias_untyped(ssi_hw))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HARDWARE_SSI_REG_H__ */
|
||||
@ -34,6 +34,7 @@ SECTIONS
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_boot2_copy_self_start_addr = .;
|
||||
*(.text*)
|
||||
. = ALIGN(4);
|
||||
} >RAM AT > FLASH :text
|
||||
@ -52,6 +53,8 @@ SECTIONS
|
||||
. = ALIGN(4);
|
||||
} >RAM AT > FLASH :data
|
||||
|
||||
_boot2_copy_self_end_addr = .;
|
||||
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
|
||||
@ -11,6 +11,7 @@ boot2_pre:
|
||||
msr msp, r0
|
||||
bl boot2_copy_self
|
||||
bl main
|
||||
b .
|
||||
.word 0x11223344
|
||||
.word 0xabcdef58
|
||||
|
||||
|
||||
@ -1,6 +1,56 @@
|
||||
#include "gpio.h"
|
||||
#include "ssi_reg.h"
|
||||
|
||||
void __attribute__((section(".text.boot2_pre"))) boot2_copy_self(void)
|
||||
{
|
||||
return;
|
||||
#define BOOT2_FLASHCMD_READ_DATA (0x03)
|
||||
#define BOOT2_FLASH_OFFSET (256)
|
||||
extern uint32_t _boot2_copy_self_start_addr;
|
||||
extern uint32_t _boot2_copy_self_end_addr;
|
||||
|
||||
io_rw_32 *reg;
|
||||
uint32_t cmd;
|
||||
uint32_t length, tx_count, rx_count, rx_skip;
|
||||
uint8_t *copy_to_addr;
|
||||
uint8_t rxbyte;
|
||||
|
||||
/* force QSPI_CS low level as selected */
|
||||
reg = (io_rw_32 *)(IO_QSPI_BASE + GPIO_QSPI_CS_CTRL_OFFSET);
|
||||
*reg = GPIO_OVER_OUT_FORCE_LOW << GPIO_OVER_OUT_POS;
|
||||
|
||||
/* send command and length */
|
||||
cmd = (BOOT2_FLASHCMD_READ_DATA << 24) | BOOT2_FLASH_OFFSET;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
ssi_hw->dr0 = cmd >> 24;
|
||||
cmd <<= 8;
|
||||
}
|
||||
/* init parameter */
|
||||
length = (uint32_t)&_boot2_copy_self_end_addr - (uint32_t)&_boot2_copy_self_start_addr;
|
||||
tx_count = length;
|
||||
rx_count = length;
|
||||
rx_skip = 4;
|
||||
copy_to_addr = (uint8_t *)&_boot2_copy_self_start_addr;
|
||||
/* copy data from flash to ram */
|
||||
while (tx_count || rx_skip || rx_count) {
|
||||
uint32_t tx_level = ssi_hw->txflr;
|
||||
uint32_t rx_level = ssi_hw->rxflr;
|
||||
if (tx_count && tx_level + rx_level < 14) {
|
||||
ssi_hw->dr0 = 0;
|
||||
tx_count--;
|
||||
}
|
||||
if (rx_level) {
|
||||
rxbyte = ssi_hw->dr0;
|
||||
if (rx_skip) {
|
||||
rx_skip--;
|
||||
} else {
|
||||
*copy_to_addr++ = rxbyte;
|
||||
rx_count--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* force QSPI_CS high level as disselected */
|
||||
*reg = GPIO_OVER_OUT_FORCE_HIGH << GPIO_OVER_OUT_POS;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user