[bootloader] split TWI/SPI flash configuration

This commit is contained in:
stnolting 2025-03-25 21:37:26 +01:00
parent 86bd1461cb
commit 7ff344df51
5 changed files with 41 additions and 83 deletions

View file

@ -89,6 +89,21 @@
#define SPI_FLASH_CLK_PRSC CLK_PRSC_64 // see #NEORV32_CLOCK_PRSC_enum
#endif
// SPI flash base address
#ifndef SPI_FLASH_BASE_ADDR
#define SPI_FLASH_BASE_ADDR 0x00400000U
#endif
// SPI flash address width (number of bytes: 1,2,3,4)
#ifndef SPI_FLASH_ADDR_BYTES
#define SPI_FLASH_ADDR_BYTES 3 // default = 3 address bytes = 24-bit
#endif
// SPI flash sector size in bytes
#ifndef SPI_FLASH_SECTOR_SIZE
#define SPI_FLASH_SECTOR_SIZE 65536 // default = 64kB
#endif
/**********************************************************************
* TWI configuration
**********************************************************************/
@ -113,28 +128,14 @@
#define TWI_DEVICE_ID 0x50
#endif
/**********************************************************************
* Flash configuration (SPI / TWI)
**********************************************************************/
// SPI flash base address
#ifndef FLASH_SPI_BASE_ADDR
#define FLASH_SPI_BASE_ADDR 0x00400000U
#endif
// TWI flash base address
#ifndef FLASH_TWI_BASE_ADDR
#define FLASH_TWI_BASE_ADDR 0x00000000U
#ifndef TWI_FLASH_BASE_ADDR
#define TWI_FLASH_BASE_ADDR 0x00000000U
#endif
// Flash address width (number of bytes: 1,2,3,4)
#ifndef FLASH_ADDR_BYTES
#define FLASH_ADDR_BYTES 3 // default = 3 address bytes = 24-bit
#endif
// Flash sector size in bytes
#ifndef FLASH_SECTOR_SIZE
#define FLASH_SECTOR_SIZE 65536 // default = 64kB
// TWI flash address width (number of bytes: 1,2,3,4)
#ifndef TWI_FLASH_ADDR_BYTES
#define TWI_FLASH_ADDR_BYTES 3 // default = 3 address bytes = 24-bit
#endif
#endif // CONFIG_H

View file

@ -357,7 +357,7 @@ int load_exe(int src) {
// get image from SPI flash?
#if (SPI_EN != 0)
if (src == EXE_STREAM_SPI) {
src_addr = FLASH_SPI_BASE_ADDR;
src_addr = SPI_FLASH_BASE_ADDR;
uart_puts("Loading from SPI flash @");
uart_puth(src_addr);
uart_puts("... ");
@ -368,7 +368,7 @@ int load_exe(int src) {
// get image from TWI flash?
#if (TWI_EN)
if (src == EXE_STREAM_TWI) {
src_addr = FLASH_TWI_BASE_ADDR;
src_addr = TWI_FLASH_BASE_ADDR;
uart_puts("Loading from TWI flash ");
uart_puth(TWI_DEVICE_ID);
uart_puts(" @");
@ -451,7 +451,7 @@ void save_exe(int dst) {
uart_puts("Write ");
uart_puth(size);
uart_puts(" bytes to SPI flash @");
uart_puth((uint32_t)FLASH_SPI_BASE_ADDR);
uart_puth((uint32_t)SPI_FLASH_BASE_ADDR);
uart_puts(" (y/n)?\n");
if (uart_getc() != 'y') {
return;
@ -466,17 +466,17 @@ void save_exe(int dst) {
}
// clear memory before writing
uint32_t num_sectors = (size / (FLASH_SECTOR_SIZE)) + 1; // clear at least 1 sector
uint32_t sector_base_addr = (uint32_t)FLASH_SPI_BASE_ADDR ;
uint32_t num_sectors = (size / (SPI_FLASH_SECTOR_SIZE)) + 1; // clear at least 1 sector
uint32_t sector_base_addr = (uint32_t)SPI_FLASH_BASE_ADDR ;
while (num_sectors--) {
spi_flash_erase_sector(sector_base_addr);
sector_base_addr += FLASH_SECTOR_SIZE;
sector_base_addr += SPI_FLASH_SECTOR_SIZE;
}
// store data from memory and update checksum
uint32_t checksum = 0, i = 0;
uint32_t *pnt = (uint32_t*)EXE_BASE_ADDR;
uint32_t src_addr = (uint32_t)FLASH_SPI_BASE_ADDR + EXE_OFFSET_DATA;
uint32_t src_addr = (uint32_t)SPI_FLASH_BASE_ADDR + EXE_OFFSET_DATA;
while (i < size) { // in chunks of 4 bytes
uint32_t d = (uint32_t)*pnt++;
checksum += d;
@ -486,9 +486,9 @@ void save_exe(int dst) {
}
// write header
spi_flash_write_word(FLASH_SPI_BASE_ADDR + EXE_OFFSET_SIGNATURE, EXE_SIGNATURE);
spi_flash_write_word(FLASH_SPI_BASE_ADDR + EXE_OFFSET_SIZE, size);
spi_flash_write_word(FLASH_SPI_BASE_ADDR + EXE_OFFSET_CHECKSUM, (~checksum)+1);
spi_flash_write_word(SPI_FLASH_BASE_ADDR + EXE_OFFSET_SIGNATURE, EXE_SIGNATURE);
spi_flash_write_word(SPI_FLASH_BASE_ADDR + EXE_OFFSET_SIZE, size);
spi_flash_write_word(SPI_FLASH_BASE_ADDR + EXE_OFFSET_CHECKSUM, (~checksum)+1);
uart_puts("OK\n");
}

View file

@ -1,43 +0,0 @@
// ================================================================================ //
// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
// Copyright (c) NEORV32 contributors. //
// Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. //
// Licensed under the BSD-3-Clause license, see LICENSE for details. //
// SPDX-License-Identifier: BSD-3-Clause //
// ================================================================================ //
/**
* @file main.h
* @brief Helper macros and defines.
*/
#ifndef MAIN_H
#define MAIN_H
#include <stdint.h>
/**********************************************************************//**
Executable stream source select
**************************************************************************/
#define EXE_STREAM_UART 0 // Get executable via UART
#define EXE_STREAM_SPI 1 // Get executable from SPI flash
#define EXE_STREAM_TWI 2 // Get executable from TWI device
/**********************************************************************//**
* NEORV32 executable
**************************************************************************/
#define EXE_OFFSET_SIGNATURE (0) // Offset in bytes from start to signature (32-bit)
#define EXE_OFFSET_SIZE (4) // Offset in bytes from start to size (32-bit)
#define EXE_OFFSET_CHECKSUM (8) // Offset in bytes from start to checksum (32-bit)
#define EXE_OFFSET_DATA (12) // Offset in bytes from start to data (32-bit)
#define EXE_SIGNATURE 0x4788CAFEU // valid executable identifier
/**********************************************************************//**
* Helper macros
**************************************************************************/
#define xstr(a) str(a)
#define str(a) #a
#endif // MAIN_H

View file

@ -80,22 +80,22 @@ void spi_flash_send_addr(uint32_t addr) {
subwords32_t address;
address.uint32 = addr;
#if (FLASH_ADDR_BYTES == 1)
#if (SPI_FLASH_ADDR_BYTES == 1)
neorv32_spi_transfer(address.uint8[0]);
#elif (FLASH_ADDR_BYTES == 2)
#elif (SPI_FLASH_ADDR_BYTES == 2)
neorv32_spi_transfer(address.uint8[1]);
neorv32_spi_transfer(address.uint8[0]);
#elif (FLASH_ADDR_BYTES == 3)
#elif (SPI_FLASH_ADDR_BYTES == 3)
neorv32_spi_transfer(address.uint8[2]);
neorv32_spi_transfer(address.uint8[1]);
neorv32_spi_transfer(address.uint8[0]);
#elif (FLASH_ADDR_BYTES == 4)
#elif (SPI_FLASH_ADDR_BYTES == 4)
neorv32_spi_transfer(address.uint8[3]);
neorv32_spi_transfer(address.uint8[2]);
neorv32_spi_transfer(address.uint8[1]);
neorv32_spi_transfer(address.uint8[0]);
#else
#error "Invalid FLASH_ADDR_BYTES configuration!"
#error "Invalid SPI_FLASH_ADDR_BYTES configuration!"
#endif
}

View file

@ -40,27 +40,27 @@ int twi_flash_read_word(uint32_t addr, uint32_t* rdata) {
neorv32_twi_generate_start();
// send device address
uint8_t device_id = address.uint8[FLASH_ADDR_BYTES] + TWI_DEVICE_ID;
uint8_t device_id = TWI_DEVICE_ID;
transfer = device_id << 1;
device_nack |= neorv32_twi_transfer(&transfer, 0);
// send read access address
#if (FLASH_ADDR_BYTES == 1)
#if (TWI_FLASH_ADDR_BYTES == 1)
transfer = address.uint8[0];
device_nack |= neorv32_twi_transfer(&transfer, 0);
#elif (FLASH_ADDR_BYTES == 2)
#elif (TWI_FLASH_ADDR_BYTES == 2)
transfer = address.uint8[1];
device_nack |= neorv32_twi_transfer(&transfer, 0);
transfer = address.uint8[0];
device_nack |= neorv32_twi_transfer(&transfer, 0);
#elif (FLASH_ADDR_BYTES == 3)
#elif (TWI_FLASH_ADDR_BYTES == 3)
transfer = address.uint8[2];
device_nack |= neorv32_twi_transfer(&transfer, 0);
transfer = address.uint8[1];
device_nack |= neorv32_twi_transfer(&transfer, 0);
transfer = address.uint8[0];
device_nack |= neorv32_twi_transfer(&transfer, 0);
#elif (FLASH_ADDR_BYTES == 4)
#elif (TWI_FLASH_ADDR_BYTES == 4)
transfer = address.uint8[3];
device_nack |= neorv32_twi_transfer(&transfer, 0);
transfer = address.uint8[2];
@ -70,7 +70,7 @@ int twi_flash_read_word(uint32_t addr, uint32_t* rdata) {
transfer = address.uint8[0];
device_nack |= neorv32_twi_transfer(&transfer, 0);
#else
#error "Invalid FLASH_ADDR_BYTES configuration!"
#error "Invalid TWI_FLASH_ADDR_BYTES configuration!"
#endif
/***********************