Atmel DataFlashes by default operate with pages with 1056 byte pages. They also have a "power of 2" mode where the pages are 1024 bytes in size. The latter mode is required in order to boot with a Blackfin processor, so many people wish to convert their DataFlashes on their development systems to this mode. This standalone application does just that.
Signed-off-by: Mike Frysinger <vap...@gentoo.org> --- examples/.gitignore | 1 + examples/Makefile | 4 + examples/atmel_df_pow2.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 211 insertions(+), 0 deletions(-) create mode 100644 examples/atmel_df_pow2.c diff --git a/examples/.gitignore b/examples/.gitignore index 0d1864c..7b783fc 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -1,4 +1,5 @@ /82559_eeprom +/atmel_df_pow2 /hello_world /interrupt /mem_to_mem_idma2intr diff --git a/examples/Makefile b/examples/Makefile index dbcfa92..9f67afd 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -86,6 +86,10 @@ ELF = hello_world SREC = hello_world.srec BIN = hello_world.bin +ELF += atmel_df_pow2 +SREC += atmel_df_pow2.srec +BIN += atmel_df_pow2.bin + ifeq ($(CPU),mpc8xx) ELF += test_burst SREC += test_burst.srec diff --git a/examples/atmel_df_pow2.c b/examples/atmel_df_pow2.c new file mode 100644 index 0000000..e6d02b1 --- /dev/null +++ b/examples/atmel_df_pow2.c @@ -0,0 +1,206 @@ +/* + * atmel_df_pow2.c - convert Atmel Dataflashes to Power of 2 mode + * + * Copyright 2009 Analog Devices Inc. + * + * Licensed under the 2-clause BSD. + */ + +#include <common.h> +#include <exports.h> + +#define CMD_ID 0x9f +#define CMD_STAT 0xd7 +#define CMD_CFG 0x3d + +static int flash_cmd(struct spi_slave *slave, uchar cmd, uchar *buf, int len) +{ + buf[0] = cmd; + return spi_xfer(slave, 8 * len, buf, buf, SPI_XFER_BEGIN | SPI_XFER_END); +} + +static int flash_status(struct spi_slave *slave) +{ + uchar buf[2]; + if (flash_cmd(slave, CMD_STAT, buf, sizeof(buf))) + return -1; + return buf[1]; +} + +static int flash_set_pow2(struct spi_slave *slave) +{ + int ret; + uchar buf[4]; + + buf[1] = 0x2a; + buf[2] = 0x80; + buf[3] = 0xa6; + + ret = flash_cmd(slave, CMD_CFG, buf, sizeof(buf)); + if (ret) + return ret; + + /* wait Tp, or 6 msec */ + udelay(6000x); + + ret = flash_status(slave); + if (ret == -1) + return 1; + + return ret & 0x1 ? 0 : 1; +} + +static int flash_check(struct spi_slave *slave) +{ + int ret; + uchar buf[4]; + + ret = flash_cmd(slave, CMD_ID, buf, sizeof(buf)); + if (ret) + return ret; + + if (buf[1] != 0x1F) { + printf("atmel flash not found (id[0] = %#x)\n", buf[1]); + return 1; + } + + if ((buf[2] >> 5) != 0x1) { + printf("AT45 flash not found (id[0] = %#x)\n", buf[2]); + return 2; + } + + return 0; +} + +static char *getline(void) +{ + static char buffer[100]; + char c; + size_t i; + + i = 0; + while (1) { + buffer[i] = '\0'; + + c = getc(); + + switch (c) { + case '\r': /* Enter/Return key */ + case '\n': + puts("\n"); + return buffer; + + case 0x03: /* ^C - break */ + return NULL; + + case 0x5F: + case 0x08: /* ^H - backspace */ + case 0x7F: /* DEL - backspace */ + if (i) { + puts("\b \b"); + i--; + } + break; + + default: + /* Ignore control characters */ + if (c < 0x20) + break; + /* Queue up all other characters */ + buffer[i++] = c; + printf("%c", c); + break; + } + } +} + +int atmel_df_pow2(int argc, char *argv[]) +{ + /* Print the ABI version */ + app_startup(argv); + if (XF_VERSION != get_version()) { + printf("Expects ABI version %d\n", XF_VERSION); + printf("Actual U-Boot ABI version %lu\n", get_version()); + printf("Can't run\n\n"); + return 1; + } + + spi_init(); + + while (1) { + struct spi_slave *slave; + char *line, *p; + int bus, cs, status; + + puts("\nenter the [BUS:]CS of the SPI flash: "); + line = getline(); + + /* CTRL+C */ + if (!line) + return 0; + if (line[0] == '\0') + continue; + + bus = cs = simple_strtoul(line, &p, 10); + if (*p) { + if (*p == ':') { + ++p; + cs = simple_strtoul(p, &p, 10); + } + if (*p) { + puts("invalid format, please try again\n"); + continue; + } + } else + bus = 0; + + printf("\ngoing to work with dataflash at %i:%i\n", bus, cs); + + /* use a low speed -- it'll work with all devices, and + * speed here doesn't really matter. + */ + slave = spi_setup_slave(bus, cs, 1000, SPI_MODE_3); + if (!slave) { + puts("unable to setup slave\n"); + continue; + } + + if (spi_claim_bus(slave)) { + spi_free_slave(slave); + continue; + } + + if (flash_check(slave)) { + puts("no flash found\n"); + goto done; + } + + status = flash_status(slave); + if (status == -1) { + puts("unable to read status register\n"); + goto done; + } + if (status & 0x1) { + puts("flash is already in power-of-2 mode!\n"); + goto done; + } + + puts("are you sure you wish to set power-of-2 mode?\n"); + puts("this operation is permanent and irreversible\n"); + printf("enter YES to continue: "); + line = getline(); + if (!line || strcmp(line, "YES")) + goto done; + + if (flash_set_pow2(slave)) { + puts("setting pow2 mode failed\n"); + goto done; + } + + puts("OK!\n"); + + done: + spi_release_bus(slave); + spi_free_slave(slave); + } +} -- 1.6.3.3 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot