Files
hpw421/component/boot2/bsp/bsp_xip_normal.c
2026-07-03 18:08:25 +08:00

213 lines
6.0 KiB
C

#include "Includes.h"
#include "bsp_xip_normal.h"
// #include "test_config.h"
#define CMD_PWRDWN 0xB9
#define CMD_RELEASE_PWRDWN 0xAB
#define CMD_WRITE_ENABLE 0x06
#define CMD_WRITE_STATUS1 0x01
#define CMD_READ_STATUS 0x05
#define CMD_WRITE_STATUS2 0x31
#define CMD_READ_STATUS2 0x35
#define SPI0_D2_WP 33
#define SPI0_D3_HOLD 34
#define printf(...) (0)
typedef void (*iapfun)(void); // 定义一个函数类型的参数.
iapfun jump2app;
__asm void MSR_MSP(uint32_t addr) // 设置栈顶地址 addr:栈顶地址
{
MSR MSP, r0 // set Main Stack value
BX r14
}
//void close_ssi0(void)
//{
// __write_hw_reg32(CPR_SPIx_MCLK_CTL(0), 0x110000); // close ssi0 mclk
// __write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL, (0x1000000)); // close ssi0 pclk
// __write_hw_reg32(CPR_RSTCTL_SUBRST_SW, 0x040000); // 复位ssi0
// __write_hw_reg32(CPR_RSTCTL_SUBRST_SW, 0x040004); // 复位ssi0
//}
// #define QUAD_ENABLE
#ifdef QUAD_ENABLE
#define CMD_WRITE_STATUS 0x01
void spi_flash_quad_en(void)
{
uint32_t bWk, cWk;
__read_hw_reg32(SSI0_CTRL0, bWk);
__write_hw_reg32(SSI0_EN, 0x00);
__write_hw_reg32(SSI0_DMAS, 0x00);
__write_hw_reg32(SSI0_CTRL0, 0x07); /* 8bit SPI data */
__write_hw_reg32(SSI0_EN, 0x01);
__write_hw_reg32(SSI0_DATA, CMD_WRITE_STATUS);
__write_hw_reg32(SSI0_DATA, 0);
__write_hw_reg32(SSI0_DATA, 0x02);
do
{
__read_hw_reg32(SSI0_STS, cWk);
} while ((cWk & 0x05) != 0x04);
__write_hw_reg32(SSI0_EN, 0x00);
__write_hw_reg32(SSI0_CTRL0, bWk);
}
#define CMD_READ_STATUS2 0x35
uint8_t spi_flash_read_stat(void)
{
uint32_t bWk, cWk;
uint8_t s8_15;
__read_hw_reg32(SSI0_CTRL0, bWk);
__write_hw_reg32(SSI0_EN, 0x00);
__write_hw_reg32(SSI0_DMAS, 0x00);
__write_hw_reg32(SSI0_CTRL0, 0x07); /* 8bit SPI data */
__write_hw_reg32(SSI0_EN, 0x01);
__write_hw_reg32(SSI0_DATA, CMD_READ_STATUS2);
__write_hw_reg32(SSI0_DATA, 0xff);
do
{
__read_hw_reg32(SSI0_STS, cWk);
} while ((cWk & 0x05) != 0x04);
cWk = *SSI0_DATA; // no use
s8_15 = *SSI0_DATA;
// printf("s8_15=%#X\n" , s8_15);
__write_hw_reg32(SSI0_EN, 0x00);
__write_hw_reg32(SSI0_CTRL0, bWk);
return s8_15;
}
uint8_t spi_flash_wait_till_ready(void)
{
uint16_t cmd = (CMD_READ_STATUS << 8);
uint32_t iWK = 0;
uint16_t dWK = 0;
__write_hw_reg32(SSI0_EN, 0x00);
__write_hw_reg32(SSI0_DMAS, 0x00); /* turn off dma*/
__write_hw_reg32(SSI0_DMATDL, 0x0); //-
__write_hw_reg32(SSI0_DMARDL, 0x0); //-
__write_hw_reg32(SSI0_EN, 0x01);
__write_hw_reg32(SSI0_DATA, cmd);
do
{
__read_hw_reg32(SSI0_STS, iWK);
} while ((iWK & 0x05) != 0x04);
__read_hw_reg32(SSI0_DATA, dWK);
__write_hw_reg32(SSI0_EN, 0x00);
return (uint8_t)(dWK & 0x01);
}
extern void spi_flash_write_enable(void)
{
uint32_t bWk, cWk;
__read_hw_reg32(SSI0_CTRL0, bWk);
__write_hw_reg32(SSI0_EN, 0x00);
__write_hw_reg32(SSI0_DMAS, 0x00);
__write_hw_reg32(SSI0_CTRL0, 0x07); /* 8bit SPI data */
__write_hw_reg32(SSI0_EN, 0x01);
__write_hw_reg32(SSI0_DATA, CMD_WRITE_ENABLE);
do
{
__read_hw_reg32(SSI0_STS, cWk);
} while ((cWk & 0x05) != 0x04);
__write_hw_reg32(SSI0_EN, 0x00);
__write_hw_reg32(SSI0_CTRL0, bWk);
}
#endif
void delay_wait(uint8_t cn)
{
for (int i = 0; i < cn; i++)
for (int j = 0; j < 0x200; j++)
;
}
void init_xip_normal(void)
{
__write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL, 0x40004); /*gpio_pclk enable*/
__write_hw_reg32(CPR_OTHERCLKEN_GRCTL, 0x10001); /*gpio_clk enable*/
// bootrom init spi0,
#ifdef QUAD_ENABLE
// spi_flash_quad_en();
if ((spi_flash_read_stat() & 0x02) == 0)
{
spi_flash_write_enable();
spi_flash_quad_en();
while (spi_flash_wait_till_ready())
;
}
#endif
close_ssi0(); // close ssi0
// config fmc pin
gpio_mux_ctl_u(33, 1); // d2
gpio_mux_ctl_u(34, 1); // d3
gpio_mux_ctl_u(35, 2); // clk
gpio_mux_ctl_u(36, 2); // cs
gpio_mux_ctl_u(37, 2); // d0 rx
gpio_mux_ctl_u(38, 2); // d1 tx
// open fmc clk
__write_hw_reg32(FMC_CTL, 0x0503 | (0 << 11)); //
delay_wait(1);
__write_hw_reg32(FMC_CTL, 0x3503 | (0 << 11)); //
delay_wait(1);
// config cache
__write_hw_reg32(CACHE_CCR, 0x00);
delay_wait(6);
__write_hw_reg32(CACHE_CCR, 0x21);
delay_wait(6);
// config fmc contrl
__write_hw_reg32(FMC_EN, 0x00); // Disables DWC_ssi
__write_hw_reg32(FMC_IE, 0x00);
__write_hw_reg32(FMC_CTRL0, 0x1F); /* 32bit SPI data */
__write_hw_reg32(FMC_SE, 0x01);
__write_hw_reg32(FMC_RXFTL, 0x00);
__write_hw_reg32(FMC_TXFTL, 0x00);
__write_hw_reg32(FMC_XIP_SER, 0x01);
__write_hw_reg32(FMC_XIP_CNT_TIME_OUT, 0xFF); // XIP time out
__write_hw_reg32(FMC_BAUD, 0x2); // SSI Clock Divider= 2 --mclk/2
#ifdef QUAD_ENABLE // 1 //quad
__write_hw_reg32(FMC_XIP_CTRL, (2) | (6 << 4) | (2 << 9) | (1 << 22) | (1 << 29) | (1 << 23) | (0 << 24) | (8 << 13));
__write_hw_reg32(FMC_XIP_INCR_INST, 0x6b); // quad read cmd
__write_hw_reg32(FMC_XIP_WRAP_INST, 0x6b); // quad read cmd
#else // dual
__write_hw_reg32(FMC_XIP_CTRL, (1) | (6 << 4) | (2 << 9) | (1 << 22) | (1 << 29) | (1 << 23) | (0) | (8 << 13));
__write_hw_reg32(FMC_XIP_INCR_INST, 0x3b); // dual read cmd
__write_hw_reg32(FMC_XIP_WRAP_INST, 0x3b); // dual read cmd
#endif
__write_hw_reg32(FMC_EN, 0x01); // Enables DWC_ssi
__write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL, 0x100000);
__write_hw_reg32(CPR_RSTCTL_SUBRST_SW, 0x10000);
jump2app = (iapfun) * (uint32_t *)(0x11001000 + 4); // 用户代码区第二个字为程序开始地址(复位地址)
MSR_MSP(*(uint32_t *)(0x11001000)); // 设置栈顶地址 addr:栈顶地址 (用户代码区第一个字为程序的栈顶地址)
jump2app(); // 设置好栈顶地址后 二级bootloder跳转到新的程序
while (1)
;
}