Use bus probing for W29EE011
This peculiar probing function is only used for a single chip in our
database. Hence, we run it only for its 128KiB chip size. Because it
can cause trouble with other chips, it gets a lower priority, and is
only called if no higher-priority probing function returned any data.
Change-Id: I90fb5aaea73e610a53b183383ebfe76a748ddffd
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/443
diff --git a/flashchips.c b/flashchips.c
index 0c7fa95..be57f0a 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -25369,7 +25369,7 @@
.page_size = 128,
.feature_bits = FEATURE_LONG_RESET,
.tested = TEST_OK_PREW,
- .probe = probe_w29ee011,
+ .probe = probe_buses,
.probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (w29ee011.c) */
.block_erasers =
{
diff --git a/include/chipdrivers/memory_bus.h b/include/chipdrivers/memory_bus.h
index c0c13ab..02794ee 100644
--- a/include/chipdrivers/memory_bus.h
+++ b/include/chipdrivers/memory_bus.h
@@ -83,7 +83,7 @@
int printlock_at49f(struct flashprog_flashctx *);
/* w29ee011.c */
-int probe_w29ee011(struct flashprog_flashctx *);
+struct found_id *probe_w29ee011(const struct bus_probe *, const struct master_common *, const struct flashchip *);
/* stm50.c */
int erase_sector_stm50(struct flashprog_flashctx *, unsigned int block, unsigned int blocksize);
diff --git a/parallel.c b/parallel.c
index e5c39a7..e182394 100644
--- a/parallel.c
+++ b/parallel.c
@@ -79,6 +79,9 @@
static const struct bus_probe memory_probes[] = {
/* prio. type function function argument */
{ 0, ID_82802AB, probe_82802ab, NULL },
+ /* Old Winbond W29* probe method w/ low priority because the
+ probing sequence puts the AMIC A49LF040A in a funky state. */
+ { 1, ID_W29EE011, probe_w29ee011, NULL },
};
static bool memory_probe_match(const struct flashchip *chip, const struct id_info_ext *found)
diff --git a/w29ee011.c b/w29ee011.c
index 6def570..0342e98 100644
--- a/w29ee011.c
+++ b/w29ee011.c
@@ -14,56 +14,71 @@
* GNU General Public License for more details.
*/
-#include <string.h>
-#include "flash.h"
+#include <stdint.h>
+
+#include "programmer.h"
#include "chipdrivers/memory_bus.h"
/* According to the Winbond W29EE011, W29EE012, W29C010M, W29C011A
* datasheets this is the only valid probe function for those chips.
*/
-int probe_w29ee011(struct flashctx *flash)
+struct found_id *probe_w29ee011(const struct bus_probe *probe,
+ const struct master_common *mst,
+ const struct flashchip *chip)
{
- chipaddr bios = flash->virtual_memory;
- uint8_t id1, id2;
+ const struct par_master *const par = (const struct par_master *)mst;
+ const chipsize_t chip_size = chip ? chip->total_size * KiB : 128*KiB;
+ uint8_t raw[2];
- if (!chip_to_probe || strcmp(chip_to_probe, flash->chip->name)) {
- msg_cdbg("Old Winbond W29* probe method disabled because "
- "the probing sequence puts the AMIC A49LF040A in "
- "a funky state. Use 'flashprog -c %s' if you "
- "have a board with such a chip.\n", flash->chip->name);
- return 0;
- }
+ const chipaddr bios = (chipaddr)programmer_map_flash_data(par, chip_size, "");
+ if (bios == (chipaddr)ERROR_PTR)
+ return NULL;
/* Issue JEDEC Product ID Entry command */
- chip_writeb(flash, 0xAA, bios + 0x5555);
+ par->chip_writeb(par, 0xAA, bios + 0x5555);
programmer_delay(10);
- chip_writeb(flash, 0x55, bios + 0x2AAA);
+ par->chip_writeb(par, 0x55, bios + 0x2AAA);
programmer_delay(10);
- chip_writeb(flash, 0x80, bios + 0x5555);
+ par->chip_writeb(par, 0x80, bios + 0x5555);
programmer_delay(10);
- chip_writeb(flash, 0xAA, bios + 0x5555);
+ par->chip_writeb(par, 0xAA, bios + 0x5555);
programmer_delay(10);
- chip_writeb(flash, 0x55, bios + 0x2AAA);
+ par->chip_writeb(par, 0x55, bios + 0x2AAA);
programmer_delay(10);
- chip_writeb(flash, 0x60, bios + 0x5555);
+ par->chip_writeb(par, 0x60, bios + 0x5555);
programmer_delay(10);
/* Read product ID */
- id1 = chip_readb(flash, bios);
- id2 = chip_readb(flash, bios + 0x01);
+ raw[0] = par->chip_readb(par, bios);
+ raw[1] = par->chip_readb(par, bios + 0x01);
/* Issue JEDEC Product ID Exit command */
- chip_writeb(flash, 0xAA, bios + 0x5555);
+ par->chip_writeb(par, 0xAA, bios + 0x5555);
programmer_delay(10);
- chip_writeb(flash, 0x55, bios + 0x2AAA);
+ par->chip_writeb(par, 0x55, bios + 0x2AAA);
programmer_delay(10);
- chip_writeb(flash, 0xF0, bios + 0x5555);
+ par->chip_writeb(par, 0xF0, bios + 0x5555);
programmer_delay(10);
- msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2);
+ programmer_unmap_flash_region(par, (void *)bios, chip_size);
- if (id1 == flash->chip->id.manufacture && id2 == flash->chip->id.model)
- return 1;
+ if (flashprog_no_data(raw, sizeof(raw)))
+ return NULL;
- return 0;
+ msg_cdbg("%s (%uKiB): id1 0x%02x, id2 0x%02x\n",
+ __func__, chip_size / KiB, raw[0], raw[1]);
+
+ struct memory_found_id *const found = alloc_memory_found_id();
+ if (!found) {
+ msg_cerr("Out of memory!\n");
+ return NULL;
+ }
+
+ found->generic.info.id.manufacture = raw[0];
+ found->generic.info.id.model = raw[1];
+ found->generic.info.id.type = ID_W29EE011;
+ found->memory_info.chip_size = chip_size;
+ found->memory_info.chip_features = 0;
+
+ return &found->generic;
}