diff options
Diffstat (limited to 'firmware/target/coldfire')
-rw-r--r-- | firmware/target/coldfire/debug-coldfire.c | 108 | ||||
-rw-r--r-- | firmware/target/coldfire/debug-target.h | 1 |
2 files changed, 109 insertions, 0 deletions
diff --git a/firmware/target/coldfire/debug-coldfire.c b/firmware/target/coldfire/debug-coldfire.c index 14221d6f02..b021cd19c0 100644 --- a/firmware/target/coldfire/debug-coldfire.c +++ b/firmware/target/coldfire/debug-coldfire.c | |||
@@ -29,6 +29,58 @@ | |||
29 | #include "adc.h" | 29 | #include "adc.h" |
30 | #include "debug-target.h" | 30 | #include "debug-target.h" |
31 | #include "lcd-remote.h" | 31 | #include "lcd-remote.h" |
32 | #ifdef IAUDIO_X5 | ||
33 | #include "ds2411.h" | ||
34 | #endif | ||
35 | |||
36 | /* Tool function to read the flash manufacturer and type, if available. | ||
37 | Only chips which could be reprogrammed in system will return values. | ||
38 | (The mode switch addresses vary between flash manufacturers, hence addr1/2) */ | ||
39 | /* In IRAM to avoid problems when running directly from Flash */ | ||
40 | static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device, | ||
41 | unsigned addr1, unsigned addr2) | ||
42 | ICODE_ATTR __attribute__((noinline)); | ||
43 | static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device, | ||
44 | unsigned addr1, unsigned addr2) | ||
45 | |||
46 | { | ||
47 | unsigned not_manu, not_id; /* read values before switching to ID mode */ | ||
48 | unsigned manu, id; /* read values when in ID mode */ | ||
49 | |||
50 | volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */ | ||
51 | int old_level; /* saved interrupt level */ | ||
52 | |||
53 | not_manu = flash[0]; /* read the normal content */ | ||
54 | not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */ | ||
55 | |||
56 | /* disable interrupts, prevent any stray flash access */ | ||
57 | old_level = disable_irq_save(); | ||
58 | |||
59 | flash[addr1] = 0xAA; /* enter command mode */ | ||
60 | flash[addr2] = 0x55; | ||
61 | flash[addr1] = 0x90; /* ID command */ | ||
62 | /* Atmel wants 20ms pause here */ | ||
63 | /* sleep(HZ/50); no sleeping possible while interrupts are disabled */ | ||
64 | manu = flash[0]; /* read the IDs */ | ||
65 | id = flash[1]; | ||
66 | |||
67 | flash[0] = 0xF0; /* reset flash (back to normal read mode) */ | ||
68 | /* Atmel wants 20ms pause here */ | ||
69 | /* sleep(HZ/50); no sleeping possible while interrupts are disabled */ | ||
70 | |||
71 | restore_irq(old_level); /* enable interrupts again */ | ||
72 | |||
73 | /* I assume success if the obtained values are different from | ||
74 | the normal flash content. This is not perfectly bulletproof, they | ||
75 | could theoretically be the same by chance, causing us to fail. */ | ||
76 | if (not_manu != manu || not_id != id) /* a value has changed */ | ||
77 | { | ||
78 | *p_manufacturer = manu; /* return the results */ | ||
79 | *p_device = id; | ||
80 | return true; /* success */ | ||
81 | } | ||
82 | return false; /* fail */ | ||
83 | } | ||
32 | 84 | ||
33 | bool dbg_ports(void) | 85 | bool dbg_ports(void) |
34 | { | 86 | { |
@@ -105,3 +157,59 @@ bool dbg_ports(void) | |||
105 | } | 157 | } |
106 | return false; | 158 | return false; |
107 | } | 159 | } |
160 | |||
161 | bool dbg_hw_info(void) | ||
162 | { | ||
163 | unsigned manu, id; /* flash IDs */ | ||
164 | int got_id; /* flag if we managed to get the flash IDs */ | ||
165 | int oldmode; /* saved memory guard mode */ | ||
166 | int line = 0; | ||
167 | |||
168 | oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */ | ||
169 | |||
170 | /* get flash ROM type */ | ||
171 | got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */ | ||
172 | if (!got_id) | ||
173 | got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */ | ||
174 | |||
175 | system_memory_guard(oldmode); /* re-enable memory guard */ | ||
176 | |||
177 | lcd_setfont(FONT_SYSFIXED); | ||
178 | lcd_clear_display(); | ||
179 | |||
180 | lcd_puts(0, line++, "[Hardware info]"); | ||
181 | |||
182 | if (got_id) | ||
183 | lcd_putsf(0, line++, "Flash: M=%04x D=%04x", manu, id); | ||
184 | else | ||
185 | lcd_puts(0, line++, "Flash: M=???? D=????"); /* unknown, sorry */ | ||
186 | |||
187 | #ifdef IAUDIO_X5 | ||
188 | { | ||
189 | struct ds2411_id id; | ||
190 | |||
191 | lcd_puts(0, ++line, "Serial Number:"); | ||
192 | |||
193 | got_id = ds2411_read_id(&id); | ||
194 | |||
195 | if (got_id == DS2411_OK) | ||
196 | { | ||
197 | lcd_putsf(0, ++line, " FC=%02x", (unsigned)id.family_code); | ||
198 | lcd_putsf(0, ++line, " ID=%02X %02X %02X %02X %02X %02X", | ||
199 | (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2], | ||
200 | (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]); | ||
201 | lcd_putsf(0, ++line, " CRC=%02X", (unsigned)id.crc); | ||
202 | } | ||
203 | else | ||
204 | { | ||
205 | lcd_putsf(0, ++line, "READ ERR=%d", got_id); | ||
206 | } | ||
207 | } | ||
208 | #endif | ||
209 | |||
210 | /* wait for exit */ | ||
211 | while (button_get_w_tmo(HZ/10) != (DEBUG_CANCEL|BUTTON_REL)); | ||
212 | |||
213 | lcd_setfont(FONT_UI); | ||
214 | return false; | ||
215 | } | ||
diff --git a/firmware/target/coldfire/debug-target.h b/firmware/target/coldfire/debug-target.h index 8d01cdd6f1..71ff75360c 100644 --- a/firmware/target/coldfire/debug-target.h +++ b/firmware/target/coldfire/debug-target.h | |||
@@ -33,3 +33,4 @@ | |||
33 | # define DEBUG_CANCEL BUTTON_REC | 33 | # define DEBUG_CANCEL BUTTON_REC |
34 | #endif | 34 | #endif |
35 | bool dbg_ports(void); | 35 | bool dbg_ports(void); |
36 | bool dbg_hw_info(void); | ||