Adding more flash functionality and image documentation

This commit is contained in:
logicog
2025-05-14 20:40:44 +02:00
parent 7493089c39
commit 73a6f0f311
5 changed files with 120 additions and 94 deletions
+90 -80
View File
@@ -7,43 +7,28 @@
#include "rtl837x_stdio.h"
#include "rtl837x_sfr.h"
// DE62B415D3155829
// JEDEC-ID: ef 40 16
__xdata unsigned char dio_enabled;
/*
* Initializes the flash controller for programmed control
* The configuration options are not really understood, the SPI speed
* seems to be directly linked to the CPU frequency
* This configures uses fast double IO at 20.8 MHz when the CPU clock is at 20.8MHz
* and 62.5MHz when the CPU clock is configured at 125MHz
* Configure Memory Managed IO
*/
void flash_init_dio()
void flash_configure_mmio(void)
{
// Configure fast DIO via divider/DIO/SIOconfig = 4 and read-cmd being 0xbb (for mmio)
SFR_FLASH_CONFIG = 9; // There may be a chip-select in here
SFR_FLASH_CONF_RCMD = 0xbb;
SFR_FLASH_CONF_DIV = 4;
// Set configuration for MMIO access by controller
if (dio_enabled) {
SFR_FLASH_MODEB = 0x18;
SFR_FLASH_CMD_R = 0xbb; // By default we read with Dual speed
SFR_FLASH_DUMMYCICLES = 4;
return;
}
// Test Controller Busy
while(SFR_FLASH_EXEC_BUSY);
// Write 0 to status register
SFR_FLASH_DUMMYCICLES = 0;
SFR_FLASH_MODEB = 0;
SFR_FLASH_TLEN = 0x19;
SFR_FLASH_CMD = 1;
SFR_FLASH_DATA0 = 0;
SFR_FLASH_EXEC_GO = 1;
while(SFR_FLASH_EXEC_BUSY);
// Set some idle mode
SFR_FLASH_MODEB = 0x18;
SFR_FLASH_CMD_R = 0xbb; // By default we read with Dual speed
SFR_FLASH_DUMMYCICLES = 4;
SFR_FLASH_MODEB = 0x0;
SFR_FLASH_CMD_R = 0xb; // By default we read with single speed
SFR_FLASH_DUMMYCICLES = 8;
}
/*
* Initializes the flash controller for programmed control
* The configuration options are not really understood, the SPI speed
@@ -51,29 +36,33 @@ void flash_init_dio()
* This configures uses fast single IO at 20.8 MHz when the CPU clock is at 20.8MHz
* and 62.5MHz when the CPU clock is configured at 125MHz
*/
void flash_init(void)
void flash_init(unsigned char enable_dio)
{
// Configure fast read via divider = 8 and read-cmd being 0xb (for mmio)
SFR_FLASH_CONFIG = 9;
SFR_FLASH_CONF_RCMD = 0xb;
SFR_FLASH_CONF_DIV = 8;
if (enable_dio) {
// Configure fast DIO via divider/DIO/SIOconfig = 4 and read-cmd being 0xbb (for mmio)
SFR_FLASH_CONFIG = 9; // There may be a chip-select in here
SFR_FLASH_CONF_RCMD = 0xbb;
SFR_FLASH_CONF_DIV = 4;
} else {
// Configure fast read via divider = 8 and read-cmd being 0xb (for mmio)
SFR_FLASH_CONFIG = 9;
SFR_FLASH_CONF_RCMD = 0xb;
SFR_FLASH_CONF_DIV = 8;
}
// Test Controller Busy
while(SFR_FLASH_EXEC_BUSY);
// Write 0 to status register
SFR_FLASH_DUMMYCICLES = 8;
SFR_FLASH_MODEB = 0;
SFR_FLASH_TLEN = 0x19;
SFR_FLASH_TCONF = 0x19;
SFR_FLASH_CMD = 1;
SFR_FLASH_DATA0 = 0;
SFR_FLASH_EXEC_GO = 1;
while(SFR_FLASH_EXEC_BUSY);
// Set some idle mode
SFR_FLASH_MODEB = 0x0;
SFR_FLASH_CMD_R = 0xb; // By default we read with single speed
SFR_FLASH_DUMMYCICLES = 8;
dio_enabled = enable_dio;
flash_configure_mmio();
}
uint8_t flash_read_status(void)
@@ -82,7 +71,7 @@ uint8_t flash_read_status(void)
while(SFR_FLASH_EXEC_BUSY);
// setup status read command
SFR_FLASH_TLEN = 0x11;
SFR_FLASH_TCONF = 0x11;
SFR_FLASH_CMD_R = 5;
// execute and wait for controller done
@@ -103,7 +92,7 @@ void flash_read_uid(void)
SFR_FLASH_DUMMYCICLES = 8;
// Transfer 4 bytes (command + 3 dummy bytes)
SFR_FLASH_TLEN = 4;
SFR_FLASH_TCONF = 4;
SFR_FLASH_ADDR16 = 0;
SFR_FLASH_ADDR8 = 0;
SFR_FLASH_ADDR0 = 0;
@@ -125,10 +114,7 @@ void flash_read_uid(void)
print_byte(SFR_FLASH_DATA16);
print_byte(SFR_FLASH_DATA24);
// Reset slow read mode
SFR_FLASH_MODEB = 0x0;
SFR_FLASH_CMD_R = 0xb;
SFR_FLASH_DUMMYCICLES = 8;
flash_configure_mmio();
}
@@ -142,7 +128,7 @@ void flash_read_jedecid(void)
SFR_FLASH_DUMMYCICLES = 0;
// Transfer 3 bytes back
SFR_FLASH_TLEN = 0x13;
SFR_FLASH_TCONF = 0x13;
SFR_FLASH_EXEC_GO = 1;
while(SFR_FLASH_EXEC_BUSY);
@@ -166,23 +152,25 @@ void flash_write_enable(void)
// Wait until busy bit clear
do {
status = flash_read_status();
print_short(status);
} while (status & 0x1);
// while (flash_read_status() & 0x1);
print_string("\r\n -setting- \r\n");
SFR_FLASH_TLEN = 0x18;
SFR_FLASH_TCONF = 0x18;
SFR_FLASH_CMD = 6;
/* The following is explicitly set for SIO, is this necessary?:
SFR_FLASH_DUMMYCYCLES = 0;
SFR_FLASH_MODEB = 0;
*/
SFR_FLASH_EXEC_GO = 1;
// Wait for write status enabled
do {
status = flash_read_status();
print_short(status);
} while (!(status & 0x2));
}
void flash_dump_dio(uint32_t addr, uint8_t len)
void flash_dump(uint32_t addr, uint8_t len)
{
short status;
do {
@@ -191,12 +179,17 @@ void flash_dump_dio(uint32_t addr, uint8_t len)
} while (status & 0x1);
// Set fast read mode
SFR_FLASH_MODEB = 0x18;
SFR_FLASH_CMD_R = 0xbb;
SFR_FLASH_DUMMYCICLES = 4;
if (dio_enabled) {
SFR_FLASH_MODEB = 0x18;
SFR_FLASH_CMD_R = 0xbb;
SFR_FLASH_DUMMYCICLES = 4;
} else {
SFR_FLASH_MODEB = 0x0;
SFR_FLASH_CMD_R = 0xb; // Fast read
SFR_FLASH_DUMMYCICLES = 8; // Add 8 dummy clocks after read?
}
// Read 4 bytes
SFR_FLASH_TLEN = 4;
SFR_FLASH_TCONF = 4;
while (len) {
SFR_FLASH_ADDR16 = addr >> 16;
SFR_FLASH_ADDR8 = addr >> 8;
@@ -232,7 +225,7 @@ void flash_read_security(uint32_t addr, uint8_t len)
SFR_FLASH_DUMMYCICLES = 8; // Add 8 dummy clocks as for fast read
// Transfer 4 bytes (command + 3byte address)
SFR_FLASH_TLEN = 4;
SFR_FLASH_TCONF = 4;
while (len) {
SFR_FLASH_ADDR16 = addr >> 16;
SFR_FLASH_ADDR8 = addr >> 8;
@@ -258,37 +251,54 @@ void flash_read_security(uint32_t addr, uint8_t len)
}
void flash_dump(uint32_t addr, uint8_t len)
void flash_block_erase(uint32_t addr)
{
flash_write_enable();
SFR_FLASH_TCONF = 8;
SFR_FLASH_CMD = 0x20;
SFR_FLASH_ADDR16 = addr >> 16;
SFR_FLASH_ADDR8 = addr >> 8;
SFR_FLASH_ADDR0 = addr;
SFR_FLASH_EXEC_GO = 1;
while (flash_read_status() & 0x1);
// Set slow read mode
SFR_FLASH_MODEB = 0x0;
SFR_FLASH_CMD_R = 0xb; // Fast read
SFR_FLASH_DUMMYCICLES = 8; // Add 8 dummy clocks after read?
flash_configure_mmio();
}
void flash_write_bytes(uint32_t addr, __xdata uint8_t *ptr, uint8_t len)
{
unsigned char exit_loop = 0;
while(1) {
flash_write_enable();
SFR_FLASH_CMD = 2;
SFR_FLASH_TCONF = 0x40 | 8 | 2; // Bytes written is is 4, 8 enables write, 0x2 is unkown
// Last transfer?
if (len < 5) {
SFR_FLASH_TCONF = 8 | len;
exit_loop = 1;
}
// Transfer 4 bytes (command + 3byte address)
SFR_FLASH_TLEN = 4;
while (len) {
SFR_FLASH_ADDR16 = addr >> 16;
SFR_FLASH_ADDR8 = addr >> 8;
SFR_FLASH_ADDR0 = addr;
addr += 4;
SFR_FLASH_DATA0 = *ptr++;
SFR_FLASH_DATA8 = *ptr++;
SFR_FLASH_DATA16 = *ptr++;
SFR_FLASH_DATA24 = *ptr++;
// Execute transfer, we wait for completion at top of loop
SFR_FLASH_EXEC_GO = 1;
while(SFR_FLASH_EXEC_BUSY);
print_byte(SFR_FLASH_DATA0);
if (len == 1)
return;
print_byte(SFR_FLASH_DATA8);
if (len == 2)
return;
print_byte(SFR_FLASH_DATA16);
if (len == 3)
return;
print_byte(SFR_FLASH_DATA24);
if (exit_loop)
break;
len -= 4;
addr += 4;
}
while (flash_read_status() & 0x1);
flash_configure_mmio();
}