From 7e1e72e29349a8248901d4d4f466d1c9b556344d Mon Sep 17 00:00:00 2001 From: Nélio Laranjeiro Date: Thu, 13 Mar 2008 00:35:33 +0100 Subject: Flash module... Still a problem with the write array... --- digital/avr/modules/flash/flash.c | 76 ++++++++-------------- digital/avr/modules/flash/flash.h | 22 ++++++- digital/avr/modules/flash/test/Makefile | 3 +- digital/avr/modules/flash/test/test-flash.c | 75 +++++++++++++++++++++ digital/avr/modules/flash/test/test-init.c | 3 +- .../avr/modules/flash/test/test-write-anarray.c | 34 ++++++++-- .../avr/modules/flash/test/test-write-onebyte.c | 25 ++++++- 7 files changed, 174 insertions(+), 64 deletions(-) create mode 100644 digital/avr/modules/flash/test/test-flash.c diff --git a/digital/avr/modules/flash/flash.c b/digital/avr/modules/flash/flash.c index 24526f26..61403e35 100644 --- a/digital/avr/modules/flash/flash.c +++ b/digital/avr/modules/flash/flash.c @@ -66,19 +66,19 @@ flash_erase (uint8_t cmd, uint32_t start_addr) } /** Poll the busy bit in the Software Status Register of the flash memory. - * \return the busy bit state. + * \return the status register. */ uint8_t -flash_is_busy (void) +flash_read_status (void) { - uint8_t busy; + uint8_t res; AC_FLASH_PORT &= ~_BV(AC_FLASH_BIT_SS); spi_send (FLASH_RDSR); - busy = spi_recv() & 0x1; + res = spi_recv(); AC_FLASH_PORT |= _BV(AC_FLASH_BIT_SS); - return busy; + return res; } /** Initialise the flsah memory. @@ -107,27 +107,18 @@ flash_init (void) AC_FLASH_PORT |= _BV(AC_FLASH_BIT_SS); proto_send3b ('f',rsp[0], rsp[1], rsp[2]); + proto_send1b ('s', flash_read_status()); - /* configure the flash to allow the access on all the memory. */ - flash_send_command (FLASH_WREN); - flash_send_command (FLASH_EWSR); - - - AC_FLASH_PORT &= ~_BV(AC_FLASH_BIT_SS); - spi_send (FLASH_WRSR); - spi_send (0x2); - AC_FLASH_PORT |= _BV(AC_FLASH_BIT_SS); + if (flash_status_aai()) + { + flash_send_command (FLASH_WEDI); + } /* Enables the flash to be writable. */ flash_send_command (FLASH_WREN); /* Read the flash status. */ - AC_FLASH_PORT &= ~_BV(AC_FLASH_BIT_SS); - spi_send (FLASH_RDSR); - rsp[0] = spi_recv(); - AC_FLASH_PORT |= _BV(AC_FLASH_BIT_SS); - - proto_send1b ('s',rsp[0]); + proto_send1b ('s', flash_read_status()); /* TODO: disable flash usage if no flash is found? */ @@ -142,7 +133,6 @@ flash_init (void) flash_address (addr); rsp[0] = spi_recv(); AC_FLASH_PORT |= _BV(AC_FLASH_BIT_SS); - proto_send1b ('r',rsp[0]); } flash_global.addr = addr - FLASH_PAGE_SIZE + 1; @@ -167,6 +157,9 @@ flash_send_command (uint8_t cmd) void flash_write (uint32_t addr, uint8_t data) { + flash_send_command (FLASH_WREN); + while (flash_is_busy ()); + AC_FLASH_PORT &= ~_BV(AC_FLASH_BIT_SS); /* Write instruction. */ spi_send (FLASH_WRITE); @@ -206,17 +199,23 @@ flash_read_array (uint32_t addr, uint8_t *buffer, uint32_t length) { uint8_t i; - AC_FLASH_PORT &= ~_BV(AC_FLASH_BIT_SS); - /* Send the read instruction. */ +/* AC_FLASH_PORT &= ~_BV(AC_FLASH_BIT_SS); spi_send (FLASH_READ); flash_address (addr); for (i = 0; i < length; i++) { buffer[i] = spi_recv (); - /* Wait for the flash until it is busy */ while (flash_is_busy()); + proto_send1b ('r', buffer[i]); } AC_FLASH_PORT |= _BV(AC_FLASH_BIT_SS); + */ + + for (i = 0; i < length; i++) + { + buffer[i] = flash_read (addr + i); + while (flash_is_busy()); + } } /** Write in the flash byte provided in parameter. @@ -230,33 +229,10 @@ flash_write_array (uint32_t addr, uint8_t *data, uint32_t length) { uint32_t i; - if (length < 2) - return; - - AC_FLASH_PORT &= ~_BV(AC_FLASH_BIT_SS); - spi_send (FLASH_AAI); - /* send the start address */ - flash_address (addr); - spi_send (data[0]); - spi_send (data[1]); - AC_FLASH_PORT |= _BV(AC_FLASH_BIT_SS); - proto_send2b ('j', data[i], data[i+1]); - - /* Wait for the flash until it is busy */ - while (flash_is_busy()); - - /* Send two bytes */ - for (i = 2; i < length; i += 2) + for (i = 0; i < length; i++) { - AC_FLASH_PORT &= ~_BV(AC_FLASH_BIT_SS); - spi_send (FLASH_AAI); - spi_send (data[i]); - spi_send (data[i+1]); - AC_FLASH_PORT |= _BV(AC_FLASH_BIT_SS); - - /* Wait for the flash until it is busy */ - while (flash_is_busy()); - proto_send2b ('j', data[i], data[i+1]); + flash_write (addr + i, data[i]); + proto_send2b ('w', data[i], flash_read (addr + i)); } } diff --git a/digital/avr/modules/flash/flash.h b/digital/avr/modules/flash/flash.h index 5ff4e8ce..39fd366c 100644 --- a/digital/avr/modules/flash/flash.h +++ b/digital/avr/modules/flash/flash.h @@ -94,10 +94,28 @@ void flash_send_command (uint8_t cmd); /** Poll the busy bit in the Software Status Register of the flash memory. - * \return the busy bit state. + * \return the status register. */ uint8_t -flash_is_busy (void); +flash_read_status (void); + +/** Poll the busy bit in the Software Status Register of the flash memory. + * \return the busy bit state. + */ +extern inline uint8_t +flash_is_busy (void) +{ + return flash_read_status () & 0x1; +} + +/** Return the AAI status flag of the register. + * \return the AAI status. + */ +extern inline uint8_t +flash_status_aai (void) +{ + return flash_read_status () >> 6; +} /** Write in the flash byte provided in parameter. * \param data the buffer to store the data. diff --git a/digital/avr/modules/flash/test/Makefile b/digital/avr/modules/flash/test/Makefile index 1ae64f7f..422e7b54 100644 --- a/digital/avr/modules/flash/test/Makefile +++ b/digital/avr/modules/flash/test/Makefile @@ -1,10 +1,11 @@ BASE = ../../.. -AVR_PROGS = test-write-onbyte test-erase test-write-anarray test-init +AVR_PROGS = test-flash test-write-onbyte test-erase test-write-anarray test-init test-write-onbyte_SOURCES = test-write-onebyte.c test-erase_SOURCES = test-erase.c test-write-anarray_SOURCES = test-write-anarray.c test-init_SOURCES = test-init.c +test-flash_SOURCES = test-flash.c MODULES = utils spi flash proto uart CONFIGFILE = avrconfig.h diff --git a/digital/avr/modules/flash/test/test-flash.c b/digital/avr/modules/flash/test/test-flash.c new file mode 100644 index 00000000..fc786858 --- /dev/null +++ b/digital/avr/modules/flash/test/test-flash.c @@ -0,0 +1,75 @@ +/* test-erase.c */ +/* avr.flash - AVR Flash SPI use. {{{ + * + * Copyright (C) 2008 Nélio Laranjeiro + * + * APBTeam: + * Web: http://apbteam.org/ + * Email: team AT apbteam DOT org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * }}} */ +#include "common.h" +#include "io.h" +#include "../flash.h" +#include "modules/proto/proto.h" +#include "modules/utils/utils.h" +#include "modules/uart/uart.h" + +#define TEST_BASE 0x300 + +void +proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) +{ +#define c(cmd, size) (cmd << 8 | size) + switch (c (cmd, size)) + { + case c ('z', 0): + /* Reset */ + utils_reset (); + break; + case c ('e', 0): + /* Erase full */ + flash_erase (FLASH_ERASE_FULL, 0); + break; + case c ('s', 0): + /* print flash status */ + proto_send1b ('s', flash_read_status()); + case c ('w', 0): + /* Send the write enable flash command. */ + flash_send_command (FLASH_WREN); + default: + /* Error */ + proto_send0 ('?'); + return; + } + /* Acknowledge what has been done */ + proto_send (cmd, size, args); +} + +int +main (void) +{ + uart0_init (); + proto_send0 ('z'); + proto_send0 ('c'); + flash_init (); + proto_send0 ('f'); + + while (1) + proto_accept (uart0_getc ()); +} + diff --git a/digital/avr/modules/flash/test/test-init.c b/digital/avr/modules/flash/test/test-init.c index ef9e410d..ec8c3e83 100644 --- a/digital/avr/modules/flash/test/test-init.c +++ b/digital/avr/modules/flash/test/test-init.c @@ -29,8 +29,6 @@ #include "modules/utils/utils.h" #include "modules/uart/uart.h" -#define FLASH_DEBUG 1 - void proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) { @@ -61,6 +59,7 @@ main (void) flash = flash_init (); proto_send0 ('f'); + proto_send1b ('s', flash_read_status()); proto_send3b ('e', (flash->addr >> 16) & 0x1f, (flash->addr >> 8), flash->addr); while (1) diff --git a/digital/avr/modules/flash/test/test-write-anarray.c b/digital/avr/modules/flash/test/test-write-anarray.c index 52b7d529..65540cea 100644 --- a/digital/avr/modules/flash/test/test-write-anarray.c +++ b/digital/avr/modules/flash/test/test-write-anarray.c @@ -29,7 +29,7 @@ #include "modules/utils/utils.h" #include "modules/uart/uart.h" -#define TEST_BASE 0x38 +uint32_t addr = 0; void proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) @@ -41,6 +41,20 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) /* Reset */ utils_reset (); break; + case c ('e', 0): + /* Erase full */ + flash_erase (FLASH_ERASE_FULL, 0); + break; + case c ('s', 0): + /* print flash status */ + proto_send1b ('s', flash_read_status()); + case c ('w', 0): + /* Send the write enable flash command. */ + flash_send_command (FLASH_WREN); + case c ('a', 3): + /* get the addr */ + addr = ((uint32_t) (args[0] & 0x1F) << 16) | ((uint32_t) args[1] << 8) + | args[2]; default: /* Error */ proto_send0 ('?'); @@ -53,8 +67,8 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) int main (void) { - uint8_t data[26]; - uint8_t data_rsp[26]; + uint8_t data[5]; + uint8_t data_rsp[5]; uint8_t i; uart0_init (); @@ -62,20 +76,26 @@ main (void) proto_send0 ('c'); flash_init (); proto_send0 ('f'); + + proto_send1b ('s', flash_read_status ()); - for (i = 0; i < 26; i++) + for (i = 0; i < 5; i++) { data[i] = i + 'a'; } /* Write a full array. */ - flash_write_array (TEST_BASE , data, 26); + flash_write_array (addr, data, 5); + + proto_send1b ('p', flash_read_status()); /* Read a full array. */ - flash_read_array (TEST_BASE , data_rsp, 26); + flash_read_array (addr , data_rsp, 5); /* Print the data_rsp to the i2c */ - proto_send ('g', 26, data_rsp); + proto_send ('g', 5, data_rsp); + + addr += 5; while (1) proto_accept (uart0_getc ()); diff --git a/digital/avr/modules/flash/test/test-write-onebyte.c b/digital/avr/modules/flash/test/test-write-onebyte.c index 7ab5094c..0c27c86a 100644 --- a/digital/avr/modules/flash/test/test-write-onebyte.c +++ b/digital/avr/modules/flash/test/test-write-onebyte.c @@ -29,7 +29,7 @@ #include "modules/utils/utils.h" #include "modules/uart/uart.h" -#define TEST_BASE 0x00 +#define TEST_BASE 0x224 void proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) @@ -41,6 +41,16 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) /* Reset */ utils_reset (); break; + case c ('e', 0): + /* Erase full */ + flash_erase (FLASH_ERASE_FULL, 0); + break; + case c ('s', 0): + /* print flash status */ + proto_send1b ('s', flash_read_status()); + case c ('w', 0): + /* Send the write enable flash command. */ + flash_send_command (FLASH_WREN); default: /* Error */ proto_send0 ('?'); @@ -58,8 +68,19 @@ main (void) proto_send0 ('c'); flash_init (); proto_send0 ('f'); + + flash_send_command (FLASH_WREN); + proto_send1b ('s', flash_read_status ()); + flash_write (TEST_BASE, 'a'); - proto_send1b ('o',flash_read(TEST_BASE)); + proto_send2b ('o', flash_read_status (), flash_read(TEST_BASE)); + + flash_write (TEST_BASE + 1, 'a'); + proto_send2b ('o', flash_read_status (), flash_read(TEST_BASE + 1)); + + /* read */ + proto_send1b ('r', flash_read (TEST_BASE)); + proto_send1b ('r', flash_read (TEST_BASE + 1)); while (1) proto_accept (uart0_getc ()); -- cgit v1.2.3