#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) ; }