mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-10-29 17:54:14 +08:00
Merge pull request #427 from bennydiamond/Flash_SingleIO_ReadStatus
Temporary revert to SingleIO for Flash operations (except data read)
This commit is contained in:
2 files changed
+97
-93
No files matched your search
+97
-92
@@ -28,11 +28,16 @@ __xdata uint8_t flash_capacity_code;
|
||||
#define CMD_READ_JEDEC_ID 0x9f
|
||||
#define CMD_FREAD_DIO 0xbb
|
||||
|
||||
#define STATUS_REG_BUSY_MASK 0x01
|
||||
#define STATUS_REG_WEL_MASK 0x02
|
||||
|
||||
/*
|
||||
* Configure Memory Managed IO
|
||||
*/
|
||||
void flash_configure_mmio(void)
|
||||
static void flash_configure_mmio(void)
|
||||
{
|
||||
while(SFR_FLASH_EXEC_BUSY);
|
||||
|
||||
// Set configuration for MMIO access by controller
|
||||
if (dio_enabled) {
|
||||
SFR_FLASH_MODEB = 0x18;
|
||||
@@ -46,6 +51,54 @@ void flash_configure_mmio(void)
|
||||
SFR_FLASH_DUMMYCYCLES = 8;
|
||||
}
|
||||
|
||||
static void flash_configure_sio(void)
|
||||
{
|
||||
while(SFR_FLASH_EXEC_BUSY);
|
||||
|
||||
// Set configuration for SIO access by controller
|
||||
SFR_FLASH_MODEB = 0x0;
|
||||
SFR_FLASH_DUMMYCYCLES = 0;
|
||||
}
|
||||
|
||||
static uint8_t flash_read_status(void)
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t old_cmd_r;
|
||||
uint8_t old_tconf;
|
||||
|
||||
while(SFR_FLASH_EXEC_BUSY);
|
||||
|
||||
// SAVE SPI peripheral state at entry
|
||||
old_cmd_r = SFR_FLASH_CMD_R;
|
||||
old_tconf = SFR_FLASH_TCONF;
|
||||
|
||||
SFR_FLASH_TCONF = 0x11;
|
||||
SFR_FLASH_CMD_R = CMD_READ_STATUS;
|
||||
|
||||
SFR_FLASH_EXEC_GO = 1;
|
||||
while(SFR_FLASH_EXEC_BUSY);
|
||||
status = SFR_FLASH_DATA0;
|
||||
|
||||
// RESTORE SPI peripheral state
|
||||
SFR_FLASH_CMD_R = old_cmd_r;
|
||||
SFR_FLASH_TCONF = old_tconf;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void flash_write_enable(void)
|
||||
{
|
||||
while (flash_read_status() & STATUS_REG_BUSY_MASK);
|
||||
while(SFR_FLASH_EXEC_BUSY);
|
||||
|
||||
SFR_FLASH_TCONF = 0x18;
|
||||
SFR_FLASH_CMD = CMD_WRITE_ENABLE;
|
||||
|
||||
SFR_FLASH_EXEC_GO = 1;
|
||||
while (SFR_FLASH_EXEC_BUSY);
|
||||
while (!(flash_read_status() & STATUS_REG_WEL_MASK));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initializes the flash controller for programmed control
|
||||
@@ -82,30 +135,12 @@ void flash_init(uint8_t enable_dio)
|
||||
flash_configure_mmio();
|
||||
}
|
||||
|
||||
|
||||
uint8_t flash_read_status(void)
|
||||
{
|
||||
// Test Controller Busy (we might call this directly after executing a command)
|
||||
while(SFR_FLASH_EXEC_BUSY);
|
||||
|
||||
// setup status read command
|
||||
SFR_FLASH_TCONF = 0x11;
|
||||
SFR_FLASH_CMD_R = CMD_READ_STATUS;
|
||||
|
||||
// execute and wait for controller done
|
||||
SFR_FLASH_EXEC_GO = 1;
|
||||
while(SFR_FLASH_EXEC_BUSY);
|
||||
|
||||
return SFR_FLASH_DATA0;
|
||||
}
|
||||
|
||||
|
||||
void flash_read_uid(void)
|
||||
{
|
||||
while (flash_read_status() & 0x1);
|
||||
flash_configure_sio();
|
||||
while (flash_read_status() & STATUS_REG_BUSY_MASK);
|
||||
|
||||
// Set slow read mode for UID
|
||||
SFR_FLASH_MODEB = 0x0;
|
||||
SFR_FLASH_CMD_R = CMD_READ_UNIQUE_ID;
|
||||
SFR_FLASH_DUMMYCYCLES = 8;
|
||||
|
||||
@@ -152,12 +187,12 @@ __code char* get_flash_size_str(void)
|
||||
|
||||
void flash_read_jedecid(void)
|
||||
{
|
||||
while (flash_read_status() & 0x1);
|
||||
flash_configure_sio();
|
||||
|
||||
while (flash_read_status() & STATUS_REG_BUSY_MASK);
|
||||
|
||||
// Set read mode for JEDEC ID
|
||||
SFR_FLASH_MODEB = 0x0;
|
||||
SFR_FLASH_CMD_R = CMD_READ_JEDEC_ID;
|
||||
SFR_FLASH_DUMMYCYCLES = 0;
|
||||
|
||||
// Transfer 3 bytes back
|
||||
SFR_FLASH_TCONF = 0x13;
|
||||
@@ -180,32 +215,6 @@ void flash_read_jedecid(void)
|
||||
}
|
||||
|
||||
|
||||
void flash_write_enable(void)
|
||||
{
|
||||
short status;
|
||||
|
||||
// Wait until busy bit clear
|
||||
do {
|
||||
status = flash_read_status();
|
||||
} while (status & 0x1);
|
||||
|
||||
SFR_FLASH_TCONF = 0x18;
|
||||
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
|
||||
do {
|
||||
status = flash_read_status();
|
||||
} while (!(status & 0x2));
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
@@ -213,20 +222,9 @@ void flash_write_enable(void)
|
||||
void flash_read_bulk(__xdata uint8_t *dst)
|
||||
{
|
||||
short status;
|
||||
do {
|
||||
status = flash_read_status();
|
||||
} while (status & 0x1);
|
||||
|
||||
// Set fast read mode
|
||||
if (dio_enabled) {
|
||||
SFR_FLASH_MODEB = 0x18;
|
||||
SFR_FLASH_CMD_R = CMD_FREAD_DIO;
|
||||
SFR_FLASH_DUMMYCYCLES = 4;
|
||||
} else {
|
||||
SFR_FLASH_MODEB = 0x0;
|
||||
SFR_FLASH_CMD_R = CMD_FREAD; // Fast read
|
||||
SFR_FLASH_DUMMYCYCLES = 8; // Add 8 dummy clocks
|
||||
}
|
||||
flash_configure_sio();
|
||||
while (flash_read_status() & STATUS_REG_BUSY_MASK);
|
||||
flash_configure_mmio();
|
||||
|
||||
|
||||
// Read 4 bytes
|
||||
@@ -260,12 +258,12 @@ void flash_read_bulk(__xdata uint8_t *dst)
|
||||
|
||||
void flash_read_security(void)
|
||||
{
|
||||
while (flash_read_status() & 0x1);
|
||||
flash_configure_sio();
|
||||
|
||||
while (flash_read_status() & STATUS_REG_BUSY_MASK);
|
||||
|
||||
// Set slow read mode
|
||||
SFR_FLASH_MODEB = 0x0;
|
||||
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;
|
||||
@@ -298,6 +296,7 @@ void flash_read_security(void)
|
||||
|
||||
void flash_sector_erase(void)
|
||||
{
|
||||
flash_configure_sio();
|
||||
flash_write_enable();
|
||||
SFR_FLASH_TCONF = 8;
|
||||
SFR_FLASH_CMD = CMD_SECTOR_ERASE;
|
||||
@@ -307,7 +306,7 @@ void flash_sector_erase(void)
|
||||
SFR_FLASH_ADDR0 = flash_region.addr;
|
||||
|
||||
SFR_FLASH_EXEC_GO = 1;
|
||||
while (flash_read_status() & 0x1);
|
||||
while (flash_read_status() & STATUS_REG_BUSY_MASK);
|
||||
|
||||
flash_configure_mmio();
|
||||
}
|
||||
@@ -315,33 +314,39 @@ void flash_sector_erase(void)
|
||||
|
||||
void flash_write_bytes(__xdata uint8_t *ptr)
|
||||
{
|
||||
// write_char('\n'); write_char('>'); print_long(flash_region.addr); write_char(':'); print_short(flash_region.len); write_char('-'); print_byte(*ptr); // write_char('\n');
|
||||
while(1) {
|
||||
flash_write_enable();
|
||||
SFR_FLASH_CMD = CMD_PAGE_PROGRAM;
|
||||
SFR_FLASH_TCONF = 0x40 | 8 | 4; // Bytes written is 4, 8 enables write, 0x40 is unknown
|
||||
flash_configure_sio();
|
||||
|
||||
while(1) {
|
||||
flash_write_enable();
|
||||
SFR_FLASH_CMD = CMD_PAGE_PROGRAM;
|
||||
|
||||
// Last transfer?
|
||||
if (flash_region.len < 5) {
|
||||
SFR_FLASH_TCONF = 8 | flash_region.len;
|
||||
}
|
||||
if (flash_region.len < 5) {
|
||||
SFR_FLASH_TCONF = 8 | flash_region.len;
|
||||
} else {
|
||||
SFR_FLASH_TCONF = 0x40 | 8 | 4; // Bytes written is 4, 8 enables write, 0x40 is unknown
|
||||
}
|
||||
|
||||
SFR_FLASH_ADDR16 = flash_region.addr >> 16;
|
||||
SFR_FLASH_ADDR8 = flash_region.addr >> 8;
|
||||
SFR_FLASH_ADDR0 = flash_region.addr;
|
||||
SFR_FLASH_DATA0 = *ptr++;
|
||||
SFR_FLASH_DATA8 = *ptr++;
|
||||
SFR_FLASH_DATA16 = *ptr++;
|
||||
SFR_FLASH_DATA24 = *ptr++;
|
||||
SFR_FLASH_ADDR16 = flash_region.addr >> 16;
|
||||
SFR_FLASH_ADDR8 = flash_region.addr >> 8;
|
||||
SFR_FLASH_ADDR0 = flash_region.addr;
|
||||
|
||||
// Safely load only the valid bytes remaining in the buffer
|
||||
SFR_FLASH_DATA0 = *ptr++;
|
||||
if (flash_region.len > 1) SFR_FLASH_DATA8 = *ptr++;
|
||||
if (flash_region.len > 2) SFR_FLASH_DATA16 = *ptr++;
|
||||
if (flash_region.len > 3) SFR_FLASH_DATA24 = *ptr++;
|
||||
|
||||
// Execute transfer, we wait for completion at top of loop
|
||||
SFR_FLASH_EXEC_GO = 1;
|
||||
// Execute transfer, wait for completion at top of loop
|
||||
SFR_FLASH_EXEC_GO = 1;
|
||||
|
||||
if (flash_region.len < 5)
|
||||
break;
|
||||
if (flash_region.len < 5)
|
||||
break;
|
||||
|
||||
flash_region.len -= 4;
|
||||
flash_region.addr += 4;
|
||||
};
|
||||
while (flash_read_status() & 0x1);
|
||||
flash_configure_mmio();
|
||||
flash_region.len -= 4;
|
||||
flash_region.addr += 4;
|
||||
};
|
||||
|
||||
while (flash_read_status() & STATUS_REG_BUSY_MASK);
|
||||
flash_configure_mmio();
|
||||
}
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
void flash_init(uint8_t enable_dio);
|
||||
void flash_read_uid(void);
|
||||
void flash_write_enable(void);
|
||||
void flash_dump(uint8_t len);
|
||||
void flash_read_jedecid(void);
|
||||
void flash_read_security(void);
|
||||
|
||||
Reference in new issue
Block a user