diff options
author | James Buren <braewoods+rb@braewoods.net> | 2020-10-29 21:29:05 +0000 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2020-10-29 23:01:25 +0000 |
commit | f1bfbb52f1bc4f3afd12493c8e8b03317ae4058f (patch) | |
tree | f6b0d6006e44813aef1b5940b9e702f69aea2cf2 | |
parent | 96f82f828a0be5ce099a7589bebcaae7261eea20 (diff) | |
download | rockbox-f1bfbb52f1bc4f3afd12493c8e8b03317ae4058f.tar.gz 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.c | 104 |
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; | |||
49 | 49 | ||
50 | struct flash_info | 50 | struct flash_info |
51 | { | 51 | { |
52 | uint8_t manufacturer; | 52 | uint16_t manufacturer; |
53 | uint8_t id; | 53 | uint16_t id; |
54 | int size; | 54 | uint32_t size; |
55 | char name[32]; | 55 | char name[32]; |
56 | }; | 56 | }; |
57 | 57 | ||
@@ -67,36 +67,20 @@ static volatile uint16_t* FB = (uint16_t*)0x00000000; /* Flash base address */ | |||
67 | #endif | 67 | #endif |
68 | 68 | ||
69 | /* read the manufacturer and device ID */ | 69 | /* read the manufacturer and device ID */ |
70 | static bool cfi_read_id(uint8_t* pManufacturerID, uint8_t* pDeviceID) | 70 | static void cfi_read_id(struct flash_info* pInfo) |
71 | { | 71 | { |
72 | uint8_t not_manu, not_id; /* read values before switching to ID mode */ | ||
73 | uint8_t manu, id; /* read values when in ID mode */ | ||
74 | |||
75 | /* read the normal content */ | ||
76 | not_manu = FB[0]; /* should be 'A' (0x41) and 'R' (0x52) */ | ||
77 | not_id = FB[1]; /* from the "ARCH" marker */ | ||
78 | |||
79 | FB[0x5555] = 0xAA; /* enter command mode */ | 72 | FB[0x5555] = 0xAA; /* enter command mode */ |
80 | FB[0x2AAA] = 0x55; | 73 | FB[0x2AAA] = 0x55; |
81 | FB[0x5555] = 0x90; /* ID command */ | 74 | FB[0x5555] = 0x90; /* enter ID mode */ |
82 | rb->sleep(HZ/50); /* Atmel wants 20ms pause here */ | 75 | rb->sleep(HZ/100); /* we only need to sleep 150ns but 10ms is the minimum */ |
83 | 76 | ||
84 | manu = FB[0]; | 77 | pInfo->manufacturer = FB[0]; |
85 | id = FB[1]; | 78 | pInfo->id = FB[1]; |
86 | 79 | ||
87 | FB[0] = 0xF0; /* reset flash (back to normal read mode) */ | 80 | FB[0x5555] = 0xAA; /* enter command mode */ |
88 | rb->sleep(HZ/50); /* Atmel wants 20ms pause here */ | 81 | FB[0x2AAA] = 0x55; |
89 | 82 | FB[0x5555] = 0xF0; /* exit ID mode */ | |
90 | /* I assume success if the obtained values are different from | 83 | rb->sleep(HZ/100); /* we only need to sleep 150ns but 10ms is the minimum */ |
91 | the normal flash content. This is not perfectly bulletproof, they | ||
92 | could theoretically be the same by chance, causing us to fail. */ | ||
93 | if (not_manu != manu || not_id != id) /* a value has changed */ | ||
94 | { | ||
95 | *pManufacturerID = manu; /* return the results */ | ||
96 | *pDeviceID = id; | ||
97 | return true; /* success */ | ||
98 | } | ||
99 | return false; /* fail */ | ||
100 | } | 84 | } |
101 | 85 | ||
102 | /* wait until the rom signals completion of an operation */ | 86 | /* 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) | |||
148 | return cfi_wait_for_rom(pAddr); | 132 | return cfi_wait_for_rom(pAddr); |
149 | } | 133 | } |
150 | 134 | ||
151 | /* this returns true if supported and fills the info struct */ | 135 | /* fills in the struct with data about the flash rom */ |
152 | bool cfi_get_flash_info(struct flash_info* pInfo) | 136 | static void cfi_get_flash_info(struct flash_info* pInfo) |
153 | { | 137 | { |
154 | rb->memset(pInfo, 0, sizeof(struct flash_info)); | 138 | uint32_t size = 0; |
139 | const char* name = ""; | ||
155 | 140 | ||
156 | if (!cfi_read_id(&pInfo->manufacturer, &pInfo->id)) | 141 | cfi_read_id(pInfo); |
157 | return false; | ||
158 | 142 | ||
159 | if (pInfo->manufacturer == 0xBF) /* SST */ | 143 | switch (pInfo->manufacturer) |
160 | { | 144 | { |
161 | if (pInfo->id == 0xD6) | 145 | /* SST */ |
162 | { | 146 | case 0x00BF: |
163 | pInfo->size = 256* 1024; /* 256k */ | 147 | switch (pInfo->id) |
164 | rb->strcpy(pInfo->name, "SST39VF020"); | 148 | { |
165 | return true; | 149 | case 0x2782: |
166 | } | 150 | size = 2048 * 1024; /* 2 MiB */ |
167 | else if (pInfo->id == 0xD7) | 151 | name = "SST39VF160"; |
168 | { | 152 | break; |
169 | pInfo->size = 512* 1024; /* 512k */ | 153 | case 0x235B: |
170 | rb->strcpy(pInfo->name, "SST39VF040"); | 154 | size = 4096 * 1024; /* 4 MiB */ |
171 | return true; | 155 | name = "SST39VF3201"; |
172 | } | 156 | break; |
173 | else if (pInfo->id == 0x82) | 157 | } |
174 | { | 158 | break; |
175 | pInfo->size = 2048* 1024; /* 2 MiB */ | ||
176 | rb->strcpy(pInfo->name, "SST39VF160"); | ||
177 | return true; | ||
178 | } | ||
179 | else if (pInfo->id == 0x5B) | ||
180 | { | ||
181 | pInfo->size = 4096* 1024; /* 4 MiB */ | ||
182 | rb->strcpy(pInfo->name, "SST39VF3201"); | ||
183 | return true; | ||
184 | } | ||
185 | else | ||
186 | return false; | ||
187 | } | 159 | } |
188 | return false; | 160 | |
161 | pInfo->size = size; | ||
162 | rb->strcpy(pInfo->name, name); | ||
189 | } | 163 | } |
190 | 164 | ||
191 | /***************** User Interface Functions *****************/ | 165 | /***************** User Interface Functions *****************/ |
@@ -206,25 +180,23 @@ void ShowFlashInfo(struct flash_info* pInfo) | |||
206 | { | 180 | { |
207 | if (!pInfo->manufacturer) | 181 | if (!pInfo->manufacturer) |
208 | { | 182 | { |
209 | rb->lcd_puts(0, 0, "Flash: M=?? D=??"); | 183 | rb->lcd_puts(0, 0, "Flash: M=???? D=????"); |
210 | rb->lcd_puts(0, 1, "Impossible to program"); | 184 | rb->lcd_puts(0, 1, "Impossible to program"); |
211 | } | 185 | } |
212 | else | 186 | else |
213 | { | 187 | { |
214 | rb->lcd_putsf(0, 0, "Flash: M=%02x D=%02x", | 188 | rb->lcd_putsf(0, 0, "Flash: M=%04x D=%04x", |
215 | pInfo->manufacturer, pInfo->id); | 189 | pInfo->manufacturer, pInfo->id); |
216 | 190 | ||
217 | |||
218 | if (pInfo->size) | 191 | if (pInfo->size) |
219 | { | 192 | { |
220 | rb->lcd_puts(0, 1, pInfo->name); | 193 | rb->lcd_puts(0, 1, pInfo->name); |
221 | rb->lcd_putsf(0, 2, "Size: %d KB", pInfo->size / 1024); | 194 | rb->lcd_putsf(0, 2, "Size: %u KB", pInfo->size / 1024); |
222 | } | 195 | } |
223 | else | 196 | else |
224 | { | 197 | { |
225 | rb->lcd_puts(0, 1, "Unsupported chip"); | 198 | rb->lcd_puts(0, 1, "Unsupported chip"); |
226 | } | 199 | } |
227 | |||
228 | } | 200 | } |
229 | 201 | ||
230 | rb->lcd_update(); | 202 | rb->lcd_update(); |