summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Buren <braewoods+rb@braewoods.net>2020-10-29 21:29:05 +0000
committerWilliam Wilgus <me.theuser@yahoo.com>2020-10-29 23:01:25 +0000
commitf1bfbb52f1bc4f3afd12493c8e8b03317ae4058f (patch)
treef6b0d6006e44813aef1b5940b9e702f69aea2cf2
parent96f82f828a0be5ce099a7589bebcaae7261eea20 (diff)
downloadrockbox-f1bfbb52f1bc4f3afd12493c8e8b03317ae4058f.tar.gz
rockbox-f1bfbb52f1bc4f3afd12493c8e8b03317ae4058f.tar.bz2
rockbox-f1bfbb52f1bc4f3afd12493c8e8b03317ae4058f.zip
iriver_flash: revise cfi_read_id and cfi_get_flash_info
First neither of these functions can fail on supported targets so they have become void functions. Their return values were not being used anyway. Second support for other flash chips not even used on the supported targets has been removed. It appears they were only ever used on the discontinued Arch devices. Third cfi_read_id was restructured to remove obsolete code for error checking that is not necessary at all. The datasheets appear to indicate that the commands used cannot fail. Fourth cfi_get_flash_info was restructured to use a new approach to initializing the flash_info struct. It no longer initializes the structure twice. Fifth the relevant code has been updated to use the full 16 bits that are exposed by the flash rom ID interface. Change-Id: I25b1ada3d4621e2d80ac66d3d9a964964268cb3b
-rw-r--r--apps/plugins/iriver_flash.c104
1 files changed, 38 insertions, 66 deletions
diff --git a/apps/plugins/iriver_flash.c b/apps/plugins/iriver_flash.c
index 37bb3b3847..e33e422d01 100644
--- a/apps/plugins/iriver_flash.c
+++ b/apps/plugins/iriver_flash.c
@@ -49,9 +49,9 @@ ssize_t audiobuf_size;
struct flash_info
{
- uint8_t manufacturer;
- uint8_t id;
- int size;
+ uint16_t manufacturer;
+ uint16_t id;
+ uint32_t size;
char name[32];
};
@@ -67,36 +67,20 @@ static volatile uint16_t* FB = (uint16_t*)0x00000000; /* Flash base address */
#endif
/* read the manufacturer and device ID */
-static bool cfi_read_id(uint8_t* pManufacturerID, uint8_t* pDeviceID)
+static void cfi_read_id(struct flash_info* pInfo)
{
- uint8_t not_manu, not_id; /* read values before switching to ID mode */
- uint8_t manu, id; /* read values when in ID mode */
-
- /* read the normal content */
- not_manu = FB[0]; /* should be 'A' (0x41) and 'R' (0x52) */
- not_id = FB[1]; /* from the "ARCH" marker */
-
FB[0x5555] = 0xAA; /* enter command mode */
FB[0x2AAA] = 0x55;
- FB[0x5555] = 0x90; /* ID command */
- rb->sleep(HZ/50); /* Atmel wants 20ms pause here */
+ FB[0x5555] = 0x90; /* enter ID mode */
+ rb->sleep(HZ/100); /* we only need to sleep 150ns but 10ms is the minimum */
- manu = FB[0];
- id = FB[1];
+ pInfo->manufacturer = FB[0];
+ pInfo->id = FB[1];
- FB[0] = 0xF0; /* reset flash (back to normal read mode) */
- rb->sleep(HZ/50); /* Atmel wants 20ms pause here */
-
- /* I assume success if the obtained values are different from
- the normal flash content. This is not perfectly bulletproof, they
- could theoretically be the same by chance, causing us to fail. */
- if (not_manu != manu || not_id != id) /* a value has changed */
- {
- *pManufacturerID = manu; /* return the results */
- *pDeviceID = id;
- return true; /* success */
- }
- return false; /* fail */
+ FB[0x5555] = 0xAA; /* enter command mode */
+ FB[0x2AAA] = 0x55;
+ FB[0x5555] = 0xF0; /* exit ID mode */
+ rb->sleep(HZ/100); /* we only need to sleep 150ns but 10ms is the minimum */
}
/* wait until the rom signals completion of an operation */
@@ -148,44 +132,34 @@ static bool cfi_program_word(volatile uint16_t* pAddr, uint16_t data)
return cfi_wait_for_rom(pAddr);
}
-/* this returns true if supported and fills the info struct */
-bool cfi_get_flash_info(struct flash_info* pInfo)
+/* fills in the struct with data about the flash rom */
+static void cfi_get_flash_info(struct flash_info* pInfo)
{
- rb->memset(pInfo, 0, sizeof(struct flash_info));
+ uint32_t size = 0;
+ const char* name = "";
- if (!cfi_read_id(&pInfo->manufacturer, &pInfo->id))
- return false;
+ cfi_read_id(pInfo);
- if (pInfo->manufacturer == 0xBF) /* SST */
+ switch (pInfo->manufacturer)
{
- if (pInfo->id == 0xD6)
- {
- pInfo->size = 256* 1024; /* 256k */
- rb->strcpy(pInfo->name, "SST39VF020");
- return true;
- }
- else if (pInfo->id == 0xD7)
- {
- pInfo->size = 512* 1024; /* 512k */
- rb->strcpy(pInfo->name, "SST39VF040");
- return true;
- }
- else if (pInfo->id == 0x82)
- {
- pInfo->size = 2048* 1024; /* 2 MiB */
- rb->strcpy(pInfo->name, "SST39VF160");
- return true;
- }
- else if (pInfo->id == 0x5B)
- {
- pInfo->size = 4096* 1024; /* 4 MiB */
- rb->strcpy(pInfo->name, "SST39VF3201");
- return true;
- }
- else
- return false;
+ /* SST */
+ case 0x00BF:
+ switch (pInfo->id)
+ {
+ case 0x2782:
+ size = 2048 * 1024; /* 2 MiB */
+ name = "SST39VF160";
+ break;
+ case 0x235B:
+ size = 4096 * 1024; /* 4 MiB */
+ name = "SST39VF3201";
+ break;
+ }
+ break;
}
- return false;
+
+ pInfo->size = size;
+ rb->strcpy(pInfo->name, name);
}
/***************** User Interface Functions *****************/
@@ -206,25 +180,23 @@ void ShowFlashInfo(struct flash_info* pInfo)
{
if (!pInfo->manufacturer)
{
- rb->lcd_puts(0, 0, "Flash: M=?? D=??");
+ rb->lcd_puts(0, 0, "Flash: M=???? D=????");
rb->lcd_puts(0, 1, "Impossible to program");
}
else
{
- rb->lcd_putsf(0, 0, "Flash: M=%02x D=%02x",
+ rb->lcd_putsf(0, 0, "Flash: M=%04x D=%04x",
pInfo->manufacturer, pInfo->id);
-
if (pInfo->size)
{
rb->lcd_puts(0, 1, pInfo->name);
- rb->lcd_putsf(0, 2, "Size: %d KB", pInfo->size / 1024);
+ rb->lcd_putsf(0, 2, "Size: %u KB", pInfo->size / 1024);
}
else
{
rb->lcd_puts(0, 1, "Unsupported chip");
}
-
}
rb->lcd_update();