在spl代码中,用下面的代码替代sys_spi_flash_read函数,就可以最大速度加载app到ram执行。
我的AHB频率是200MHZ,SPI配置为50Mhz(100Mhz不太稳定),下面的代码启用DOUT模式传输,所以理论读取速度是12.5MB/秒。
BROM加载SPL大约150ms,而这段代码加载3MB的app代码仅需250ms,总共400毫秒就能启动3MB的应用程序。
void sys_spi_flash_read_dualout(int addr, void* buf, int count)
{
uint32_t reg_base = 0x01c05000;
uint8_t* rxbuf = buf;
uint8_t tx[5];
int n, i, c;
n = 0;
tx[n++] = 0x3b; // fast read dual-output
tx[n++] = (uint8_t)(addr >> 16);
tx[n++] = (uint8_t)(addr >> 8);
tx[n++] = (uint8_t)(addr >> 0);
tx[n++] = 0;
sys_spi_select();
write32(reg_base + SPI_MBC, n);
write32(reg_base + SPI_MTC, n);
write32(reg_base + SPI_BCC, n);
for (i = 0; i < n; i++) {
write8(reg_base + SPI_TXD, tx[i]);
}
write32(reg_base + SPI_TCR, read32(reg_base + SPI_TCR) | (1u << 31));
while (read32(reg_base + SPI_TCR) & (1u << 31));
write32(reg_base + SPI_FCR, read32(reg_base + SPI_FCR) | 0x80008000u);
while (count > 0) {
n = ((count <= 4096) ? count : 4096);
write32(reg_base + SPI_MBC, n);
write32(reg_base + SPI_MTC, 0);
write32(reg_base + SPI_BCC, (1 << 28)); // dual-mode
write32(reg_base + SPI_TCR, read32(reg_base + SPI_TCR) | (1u << 31));
for (i = n; i > 0;) {
// 这里代码看起来很累赘,但是这样却能快速读空RXFIFO!
if ((c = (read32(reg_base + SPI_FSR) & 0xff)) > 0) {
i -= c;
while (c-- > 0) {
*rxbuf++ = read8(reg_base + SPI_RXD);
}
}
}
count -= n;
}
sys_spi_deselect();
}
离线