mirror of
https://github.com/stnolting/neorv32.git
synced 2025-04-23 21:57:33 -04:00
[bootloader] split TWI/SPI flash configuration
This commit is contained in:
parent
86bd1461cb
commit
7ff344df51
5 changed files with 41 additions and 83 deletions
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
/***********************
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue