mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Cleanup of flash code
Fix several bugs found in the write-flash code during installer coding. Move all flash functions into CODE0. This is required to share these functions with the installer image (currently they are duplicated so they are not within the CODE1 segment). De-magics all Flash command codes based on the Winbond W25Q32JV datasheet.
This commit is contained in:
+1
-1
@@ -514,7 +514,7 @@ void cmd_parser(void) __banked
|
||||
}
|
||||
if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'e') {
|
||||
print_string("\nFLASH erase\n");
|
||||
flash_block_erase(0x20000);
|
||||
flash_sector_erase(0x20000);
|
||||
}
|
||||
if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'w') {
|
||||
print_string("\nFLASH write\n");
|
||||
|
||||
+60
-50
@@ -11,7 +11,16 @@ __xdata uint8_t dio_enabled;
|
||||
__xdata uint8_t markbuf[16];
|
||||
extern __xdata uint16_t mpos;
|
||||
|
||||
#pragma codeseg BANK1
|
||||
// For the flash commands, see e.g. Windbond W25Q32JV datasheet
|
||||
#define CMD_WRITE_STATUS 0x01
|
||||
#define CMD_PAGE_PROGRAM 0x02
|
||||
#define CMD_WRITE_ENABLE 0x06
|
||||
#define CMD_FREAD 0x0b
|
||||
#define CMD_SECTOR_ERASE 0x20
|
||||
#define CMD_READ_SECURITY_REGS 0x48
|
||||
#define CMD_READ_UNIQUE_ID 0x4b
|
||||
#define CMD_READ_JEDEC_ID 0x9f
|
||||
#define CMD_FREAD_DIO 0xbb
|
||||
|
||||
/*
|
||||
* Configure Memory Managed IO
|
||||
@@ -21,14 +30,14 @@ void flash_configure_mmio(void)
|
||||
// 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;
|
||||
SFR_FLASH_CMD_R = CMD_FREAD_DIO; // By default we read with Dual speed
|
||||
SFR_FLASH_DUMMYCYCLES = 4;
|
||||
return;
|
||||
}
|
||||
|
||||
SFR_FLASH_MODEB = 0x0;
|
||||
SFR_FLASH_CMD_R = 0xb; // By default we read with single speed
|
||||
SFR_FLASH_DUMMYCICLES = 8;
|
||||
SFR_FLASH_CMD_R = 0xb; // Default is Single IO
|
||||
SFR_FLASH_DUMMYCYCLES = 8;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,27 +48,26 @@ void flash_configure_mmio(void)
|
||||
* This configures 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(uint8_t enable_dio) __banked
|
||||
void flash_init(uint8_t enable_dio)
|
||||
{
|
||||
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_RCMD = CMD_FREAD_DIO;
|
||||
SFR_FLASH_CONF_DIV = 4;
|
||||
} else {
|
||||
// Configure fast read via divider = 8 and read-cmd being 0xb (for mmio)
|
||||
// Configure fast read via divider = 8 and read-cmd being CMD_FREAD (for mmio)
|
||||
SFR_FLASH_CONFIG = 9;
|
||||
SFR_FLASH_CONF_RCMD = 0xb;
|
||||
SFR_FLASH_CONF_RCMD = CMD_FREAD;
|
||||
SFR_FLASH_CONF_DIV = 8;
|
||||
}
|
||||
// Test Controller Busy
|
||||
while(SFR_FLASH_EXEC_BUSY);
|
||||
|
||||
// Write 0 to status register
|
||||
SFR_FLASH_DUMMYCICLES = 8;
|
||||
SFR_FLASH_DUMMYCYCLES = 8;
|
||||
SFR_FLASH_MODEB = 0;
|
||||
SFR_FLASH_TCONF = 0x19;
|
||||
SFR_FLASH_CMD = 1;
|
||||
SFR_FLASH_CMD = CMD_WRITE_STATUS;
|
||||
SFR_FLASH_DATA0 = 0;
|
||||
SFR_FLASH_EXEC_GO = 1;
|
||||
while(SFR_FLASH_EXEC_BUSY);
|
||||
@@ -86,14 +94,14 @@ uint8_t flash_read_status(void)
|
||||
}
|
||||
|
||||
|
||||
void flash_read_uid(void) __banked
|
||||
void flash_read_uid(void)
|
||||
{
|
||||
while (flash_read_status() & 0x1);
|
||||
|
||||
// Set slow read mode for UID
|
||||
SFR_FLASH_MODEB = 0x0;
|
||||
SFR_FLASH_CMD_R = 0x4b;
|
||||
SFR_FLASH_DUMMYCICLES = 8;
|
||||
SFR_FLASH_CMD_R = CMD_READ_UNIQUE_ID;
|
||||
SFR_FLASH_DUMMYCYCLES = 8;
|
||||
|
||||
// Transfer 4 bytes (command + 3 dummy bytes)
|
||||
SFR_FLASH_TCONF = 4;
|
||||
@@ -110,7 +118,7 @@ void flash_read_uid(void) __banked
|
||||
print_byte(SFR_FLASH_DATA24);
|
||||
|
||||
SFR_FLASH_EXEC_GO = 1;
|
||||
SFR_FLASH_DUMMYCICLES = 24;
|
||||
SFR_FLASH_DUMMYCYCLES = 24;
|
||||
while(SFR_FLASH_EXEC_BUSY);
|
||||
|
||||
print_byte(SFR_FLASH_DATA0);
|
||||
@@ -122,14 +130,14 @@ void flash_read_uid(void) __banked
|
||||
}
|
||||
|
||||
|
||||
void flash_read_jedecid(void) __banked
|
||||
void flash_read_jedecid(void)
|
||||
{
|
||||
while (flash_read_status() & 0x1);
|
||||
|
||||
// Set read mode for JEDEC ID
|
||||
SFR_FLASH_MODEB = 0x0;
|
||||
SFR_FLASH_CMD_R = 0x9f;
|
||||
SFR_FLASH_DUMMYCICLES = 0;
|
||||
SFR_FLASH_CMD_R = CMD_READ_JEDEC_ID;
|
||||
SFR_FLASH_DUMMYCYCLES = 0;
|
||||
|
||||
// Transfer 3 bytes back
|
||||
SFR_FLASH_TCONF = 0x13;
|
||||
@@ -144,12 +152,12 @@ void flash_read_jedecid(void) __banked
|
||||
|
||||
// Reset slow read mode
|
||||
SFR_FLASH_MODEB = 0x0;
|
||||
SFR_FLASH_CMD_R = 0xb;
|
||||
SFR_FLASH_DUMMYCICLES = 8;
|
||||
SFR_FLASH_CMD_R = CMD_FREAD;
|
||||
SFR_FLASH_DUMMYCYCLES = 8;
|
||||
}
|
||||
|
||||
|
||||
void flash_write_enable(void) __banked
|
||||
void flash_write_enable(void)
|
||||
{
|
||||
short status;
|
||||
|
||||
@@ -157,14 +165,16 @@ void flash_write_enable(void) __banked
|
||||
do {
|
||||
status = flash_read_status();
|
||||
} while (status & 0x1);
|
||||
// while (flash_read_status() & 0x1);
|
||||
|
||||
SFR_FLASH_TCONF = 0x18;
|
||||
SFR_FLASH_CMD = 6;
|
||||
/* The following is explicitly set for SIO, is this necessary?:
|
||||
SFR_FLASH_CMD = CMD_WRITE_ENABLE;
|
||||
|
||||
/* The following makes sure that the PAGE_PROGRAM command,
|
||||
* where the data to be written follows the command word directly
|
||||
* works properly
|
||||
*/
|
||||
SFR_FLASH_DUMMYCYCLES = 0;
|
||||
SFR_FLASH_MODEB = 0;
|
||||
*/
|
||||
|
||||
SFR_FLASH_EXEC_GO = 1;
|
||||
// Wait for write status enabled
|
||||
@@ -174,7 +184,7 @@ void flash_write_enable(void) __banked
|
||||
}
|
||||
|
||||
|
||||
void flash_dump(register uint32_t addr, register uint8_t len) __banked
|
||||
void flash_dump(register uint32_t addr, register uint8_t len)
|
||||
{
|
||||
short status;
|
||||
do {
|
||||
@@ -185,12 +195,12 @@ void flash_dump(register uint32_t addr, register uint8_t len) __banked
|
||||
// Set fast read mode
|
||||
if (dio_enabled) {
|
||||
SFR_FLASH_MODEB = 0x18;
|
||||
SFR_FLASH_CMD_R = 0xbb;
|
||||
SFR_FLASH_DUMMYCICLES = 4;
|
||||
SFR_FLASH_CMD_R = CMD_FREAD_DIO;
|
||||
SFR_FLASH_DUMMYCYCLES = 4;
|
||||
} else {
|
||||
SFR_FLASH_MODEB = 0x0;
|
||||
SFR_FLASH_CMD_R = 0xb; // Fast read
|
||||
SFR_FLASH_DUMMYCICLES = 8; // Add 8 dummy clocks after read?
|
||||
SFR_FLASH_CMD_R = CMD_FREAD; // Fast read
|
||||
SFR_FLASH_DUMMYCYCLES = 8; // Add 8 dummy clocks after read?
|
||||
}
|
||||
// Read 4 bytes
|
||||
SFR_FLASH_TCONF = 4;
|
||||
@@ -222,7 +232,7 @@ void flash_dump(register uint32_t addr, register uint8_t len) __banked
|
||||
* Reads bulk data of length len from the flash memory starging at address src
|
||||
* and writes the data into a buffer pointed to by dst in XMEM
|
||||
*/
|
||||
void flash_read_bulk(register __xdata uint8_t *dst, __xdata uint32_t src, register uint16_t len) __banked
|
||||
void flash_read_bulk(register __xdata uint8_t *dst, __xdata uint32_t src, register uint16_t len)
|
||||
{
|
||||
short status;
|
||||
do {
|
||||
@@ -232,12 +242,12 @@ void flash_read_bulk(register __xdata uint8_t *dst, __xdata uint32_t src, regist
|
||||
// Set fast read mode
|
||||
if (dio_enabled) {
|
||||
SFR_FLASH_MODEB = 0x18;
|
||||
SFR_FLASH_CMD_R = 0xbb;
|
||||
SFR_FLASH_DUMMYCICLES = 4;
|
||||
SFR_FLASH_CMD_R = CMD_FREAD_DIO;
|
||||
SFR_FLASH_DUMMYCYCLES = 4;
|
||||
} else {
|
||||
SFR_FLASH_MODEB = 0x0;
|
||||
SFR_FLASH_CMD_R = 0xb; // Fast read
|
||||
SFR_FLASH_DUMMYCICLES = 8; // Add 8 dummy clocks after read?
|
||||
SFR_FLASH_CMD_R = CMD_FREAD; // Fast read
|
||||
SFR_FLASH_DUMMYCYCLES = 8; // Add 8 dummy clocks after read?
|
||||
}
|
||||
// Read 4 bytes
|
||||
SFR_FLASH_TCONF = 4;
|
||||
@@ -266,7 +276,7 @@ void flash_read_bulk(register __xdata uint8_t *dst, __xdata uint32_t src, regist
|
||||
}
|
||||
|
||||
|
||||
void flash_find_mark(__xdata uint32_t src, register uint16_t len, __code uint8_t *mark) __banked
|
||||
void flash_find_mark(__xdata uint32_t src, register uint16_t len, __code uint8_t *mark)
|
||||
{
|
||||
uint16_t status;
|
||||
do {
|
||||
@@ -276,12 +286,12 @@ void flash_find_mark(__xdata uint32_t src, register uint16_t len, __code uint8_t
|
||||
// Set fast read mode
|
||||
if (dio_enabled) {
|
||||
SFR_FLASH_MODEB = 0x18;
|
||||
SFR_FLASH_CMD_R = 0xbb;
|
||||
SFR_FLASH_DUMMYCICLES = 4;
|
||||
SFR_FLASH_CMD_R = CMD_FREAD_DIO;
|
||||
SFR_FLASH_DUMMYCYCLES = 4;
|
||||
} else {
|
||||
SFR_FLASH_MODEB = 0x0;
|
||||
SFR_FLASH_CMD_R = 0xb; // Fast read
|
||||
SFR_FLASH_DUMMYCICLES = 8; // Add 8 dummy clocks after read?
|
||||
SFR_FLASH_CMD_R = CMD_FREAD; // Fast read
|
||||
SFR_FLASH_DUMMYCYCLES = 8; // Add 8 dummy clocks after read?
|
||||
}
|
||||
|
||||
uint8_t i = 0;
|
||||
@@ -348,14 +358,14 @@ void flash_find_mark(__xdata uint32_t src, register uint16_t len, __code uint8_t
|
||||
}
|
||||
|
||||
|
||||
void flash_read_security(uint32_t addr, uint8_t len) __banked
|
||||
void flash_read_security(uint32_t addr, uint8_t len)
|
||||
{
|
||||
while (flash_read_status() & 0x1);
|
||||
|
||||
// Set slow read mode
|
||||
SFR_FLASH_MODEB = 0x0;
|
||||
SFR_FLASH_CMD_R = 0x48; // read security register
|
||||
SFR_FLASH_DUMMYCICLES = 8; // Add 8 dummy clocks as for fast read
|
||||
SFR_FLASH_CMD_R = CMD_READ_SECURITY_REGS; // read security register
|
||||
SFR_FLASH_DUMMYCYCLES = 8; // Add 8 dummy clocks as for fast read
|
||||
|
||||
// Transfer 4 bytes (command + 3byte address)
|
||||
SFR_FLASH_TCONF = 4;
|
||||
@@ -384,11 +394,11 @@ void flash_read_security(uint32_t addr, uint8_t len) __banked
|
||||
}
|
||||
|
||||
|
||||
void flash_block_erase(uint32_t addr) __banked
|
||||
void flash_sector_erase(uint32_t addr)
|
||||
{
|
||||
flash_write_enable();
|
||||
SFR_FLASH_TCONF = 8;
|
||||
SFR_FLASH_CMD = 0x20;
|
||||
SFR_FLASH_CMD = CMD_SECTOR_ERASE;
|
||||
|
||||
SFR_FLASH_ADDR16 = addr >> 16;
|
||||
SFR_FLASH_ADDR8 = addr >> 8;
|
||||
@@ -402,14 +412,14 @@ void flash_block_erase(uint32_t addr) __banked
|
||||
}
|
||||
|
||||
|
||||
void flash_write_bytes(__xdata uint32_t addr, __xdata uint8_t *ptr, uint16_t len) __banked
|
||||
void flash_write_bytes(__xdata uint32_t addr, __xdata uint8_t *ptr, uint16_t len)
|
||||
{
|
||||
static __xdata uint8_t exit_loop = 0;
|
||||
uint8_t 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
|
||||
SFR_FLASH_CMD = CMD_PAGE_PROGRAM;
|
||||
SFR_FLASH_TCONF = 0x40 | 8 | 4; // Bytes written is is 4, 8 enables write, 0x40 is unkown
|
||||
// Last transfer?
|
||||
if (len < 5) {
|
||||
SFR_FLASH_TCONF = 8 | len;
|
||||
|
||||
+10
-10
@@ -1,14 +1,14 @@
|
||||
#ifndef _RTL837X_FLASH_H_
|
||||
#define _RTL837X_FLASH_H_
|
||||
|
||||
void flash_init(uint8_t enable_dio) __banked;
|
||||
void flash_read_uid(void) __banked;
|
||||
void flash_write_enable(void)__banked ;
|
||||
void flash_dump(register uint32_t addr, register uint8_t len) __banked;
|
||||
void flash_read_jedecid(void) __banked;
|
||||
void flash_read_security(uint32_t addr, uint8_t len)__banked ;
|
||||
void flash_block_erase(uint32_t addr) __banked;
|
||||
void flash_read_bulk(register __xdata uint8_t *dst, __xdata uint32_t src, register uint16_t len) __banked;
|
||||
void flash_write_bytes(__xdata uint32_t addr, register __xdata uint8_t *ptr, register uint16_t len)__banked;
|
||||
void flash_find_mark(__xdata uint32_t src, register uint16_t len, __code uint8_t *mark) __banked;
|
||||
void flash_init(uint8_t enable_dio);
|
||||
void flash_read_uid(void);
|
||||
void flash_write_enable(void);
|
||||
void flash_dump(register uint32_t addr, register uint8_t len);
|
||||
void flash_read_jedecid(void);
|
||||
void flash_read_security(uint32_t addr, uint8_t len);
|
||||
void flash_sector_erase(uint32_t addr);
|
||||
void flash_read_bulk(register __xdata uint8_t *dst, __xdata uint32_t src, register uint16_t len);
|
||||
void flash_write_bytes(__xdata uint32_t addr, register __xdata uint8_t *ptr, register uint16_t len);
|
||||
void flash_find_mark(__xdata uint32_t src, register uint16_t len, __code uint8_t *mark);
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ __sfr __at(0xbc) SFR_FLASH_CONFIG;
|
||||
|
||||
__sfr __at(0x9b) SFR_FLASH_CONF_DIV;
|
||||
__sfr __at(0x9c) SFR_FLASH_CONF_RCMD;
|
||||
__sfr __at(0x9d) SFR_FLASH_DUMMYCICLES;
|
||||
__sfr __at(0x9d) SFR_FLASH_DUMMYCYCLES;
|
||||
__sfr __at(0x9a) SFR_FLASH_MODEB;
|
||||
|
||||
__sfr __at(0x9e) SFR_FLASH_TCONF;
|
||||
|
||||
Reference in New Issue
Block a user