summaryrefslogtreecommitdiff
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.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;
49 49
50struct flash_info 50struct 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 */
70static bool cfi_read_id(uint8_t* pManufacturerID, uint8_t* pDeviceID) 70static 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 */
152bool cfi_get_flash_info(struct flash_info* pInfo) 136static 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();