diff options
Diffstat (limited to 'apps/debug_menu.c')
-rw-r--r-- | apps/debug_menu.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c index e7c2923f55..f1645bf5d4 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c | |||
@@ -240,25 +240,39 @@ unsigned short crc_16(unsigned char* buf, unsigned len) | |||
240 | /* Tool function to read the flash manufacturer and type, if available. | 240 | /* Tool function to read the flash manufacturer and type, if available. |
241 | Only chips which could be reprogrammed in system will return values. | 241 | Only chips which could be reprogrammed in system will return values. |
242 | (The mode switch addresses vary between flash manufacturers, hence addr1/2) */ | 242 | (The mode switch addresses vary between flash manufacturers, hence addr1/2) */ |
243 | bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device, unsigned addr1, unsigned addr2) | 243 | /* In IRAM to avoid problems when running directly from Flash */ |
244 | bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device, | ||
245 | unsigned addr1, unsigned addr2) | ||
246 | __attribute__ ((section (".icode"))); | ||
247 | bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device, | ||
248 | unsigned addr1, unsigned addr2) | ||
249 | |||
244 | { | 250 | { |
245 | unsigned not_manu, not_id; /* read values before switching to ID mode */ | 251 | unsigned not_manu, not_id; /* read values before switching to ID mode */ |
246 | unsigned manu, id; /* read values when in ID mode */ | 252 | unsigned manu, id; /* read values when in ID mode */ |
247 | volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */ | 253 | volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */ |
254 | int old_level; /* saved interrupt level */ | ||
248 | 255 | ||
249 | not_manu = flash[0]; /* read the normal content */ | 256 | not_manu = flash[0]; /* read the normal content */ |
250 | not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */ | 257 | not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */ |
251 | 258 | ||
259 | /* disable interrupts, prevent any stray flash access */ | ||
260 | old_level = set_irq_level(HIGHEST_IRQ_LEVEL); | ||
261 | |||
252 | flash[addr1] = 0xAA; /* enter command mode */ | 262 | flash[addr1] = 0xAA; /* enter command mode */ |
253 | flash[addr2] = 0x55; | 263 | flash[addr2] = 0x55; |
254 | flash[addr1] = 0x90; /* ID command */ | 264 | flash[addr1] = 0x90; /* ID command */ |
255 | sleep(HZ/50); /* Atmel wants 20ms pause here */ | 265 | /* Atmel wants 20ms pause here */ |
266 | /* sleep(HZ/50); no sleeping possible while interrupts are disabled */ | ||
256 | 267 | ||
257 | manu = flash[0]; /* read the IDs */ | 268 | manu = flash[0]; /* read the IDs */ |
258 | id = flash[1]; | 269 | id = flash[1]; |
259 | 270 | ||
260 | flash[0] = 0xF0; /* reset flash (back to normal read mode) */ | 271 | flash[0] = 0xF0; /* reset flash (back to normal read mode) */ |
261 | sleep(HZ/50); /* Atmel wants 20ms pause here */ | 272 | /* Atmel wants 20ms pause here */ |
273 | /* sleep(HZ/50); no sleeping possible while interrupts are disabled */ | ||
274 | |||
275 | set_irq_level(old_level); /* enable interrupts again */ | ||
262 | 276 | ||
263 | /* I assume success if the obtained values are different from | 277 | /* I assume success if the obtained values are different from |
264 | the normal flash content. This is not perfectly bulletproof, they | 278 | the normal flash content. This is not perfectly bulletproof, they |