From 9e34b0ebedae1c82c24d6e99f068e8bd37eb9e4d Mon Sep 17 00:00:00 2001 From: Nélio Laranjeiro Date: Wed, 28 Jan 2009 23:43:19 +0100 Subject: digital/avr/modules/flash: Wrote a flash stub to avoid the card use. (See #59) --- digital/avr/modules/flash/stub/Makefile.module | 1 + digital/avr/modules/flash/stub/doc/stub.txt | 11 ++ digital/avr/modules/flash/stub/flash.c | 240 +++++++++++++++++++++++ digital/avr/modules/flash/stub/test/Makefile | 12 ++ digital/avr/modules/flash/stub/test/test_flash.c | 57 ++++++ 5 files changed, 321 insertions(+) create mode 100644 digital/avr/modules/flash/stub/Makefile.module create mode 100644 digital/avr/modules/flash/stub/doc/stub.txt create mode 100644 digital/avr/modules/flash/stub/flash.c create mode 100644 digital/avr/modules/flash/stub/test/Makefile create mode 100644 digital/avr/modules/flash/stub/test/test_flash.c diff --git a/digital/avr/modules/flash/stub/Makefile.module b/digital/avr/modules/flash/stub/Makefile.module new file mode 100644 index 00000000..f35b0ca8 --- /dev/null +++ b/digital/avr/modules/flash/stub/Makefile.module @@ -0,0 +1 @@ +flash_stub_SOURCES=flash.c diff --git a/digital/avr/modules/flash/stub/doc/stub.txt b/digital/avr/modules/flash/stub/doc/stub.txt new file mode 100644 index 00000000..59a42c2f --- /dev/null +++ b/digital/avr/modules/flash/stub/doc/stub.txt @@ -0,0 +1,11 @@ +Flash Stub +========== + +The flash stub is a source file which emulate the flash memory of the bot in +a simple text file. + +To use the stub a default file shall be create in the current directory using +touch for example. + +The source stub memory use a file flash.apb, to use it correctly create the +file with this name. diff --git a/digital/avr/modules/flash/stub/flash.c b/digital/avr/modules/flash/stub/flash.c new file mode 100644 index 00000000..d3751502 --- /dev/null +++ b/digital/avr/modules/flash/stub/flash.c @@ -0,0 +1,240 @@ +/* flash.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 "modules/flash/flash.h" +#include "stdio.h" +#include "string.h" +#include "unistd.h" +#include "sys/types.h" +#include "fcntl.h" +#include "stdlib.h" + +#define FLASH_STUB_DATA_LEN (2 * sizeof (uint8_t)) + +struct flash_t +{ + /* The file descriptor simulating the Flash memory. */ + int file; + /* The flash current status. */ + uint8_t status; +}; +typedef struct flash_t flash_t; + + +/* Global declaration. */ +static flash_t flash_global; + +void +flash_erase (uint8_t cmd, uint32_t start_addr) +{ + const char data = 'F'; + uint8_t res; + + if (flash_global.status) + { + if (cmd == FLASH_ERASE_FULL) + { + uint32_t i; + res = 1; + + lseek (flash_global.file, 0, SEEK_SET); + for (i = 0; i <= (FLASH_ADDRESS_HIGH * 2) && res != 0; i++) + res = write (flash_global.file, &data, sizeof (char)); + } + else + { + uint32_t i; + uint32_t length; + + switch (cmd) + { + case FLASH_ERASE_4K: + length = 4096 * 2; + break; + case FLASH_ERASE_32K: + length = 32768 * 2; + break; + case FLASH_ERASE_64K: + length = 65536 * 2; + break; + default: + length = 0; + } + + res = lseek (flash_global.file, FLASH_PAGE (start_addr), SEEK_SET); + for (i = 0, res = 1; i <= length && res == 1; i++) + res = write (flash_global.file, &data, sizeof (char)); + res = lseek (flash_global.file, FLASH_PAGE (start_addr), SEEK_SET); + } + } +} + +uint8_t +flash_read_status (void) +{ + return flash_global.status; +} + +uint8_t +flash_init (void) +{ + uint8_t res = 0x0; + uint8_t nb_bytes; + + memset (&flash_global, 0, sizeof (flash_t)); + + /* Open the file. */ + flash_global.file = open ("flash.apb", O_CREAT | O_RDWR); + + if (flash_global.file) + { + lseek (flash_global.file, 0, SEEK_SET); + nb_bytes = read (flash_global.file, &res, 1); + lseek (flash_global.file, 0, SEEK_SET); + + flash_global.status = !(flash_global.file == -1); + } + + return flash_global.status; +} + +uint32_t +flash_first_sector (void) +{ + uint32_t addr; + + for (addr = 0x0; + addr < FLASH_ADDRESS_HIGH + && flash_read (addr) != 0xFF; + addr += FLASH_PAGE_SIZE); + + return addr; +} + +/** convert a 4 bits value to the character associated in ASCII. + * \param data the value to convert. + * \return the character corresponding to the data. + */ +char +flash_data_convert_to_char (uint8_t data) +{ + char res = '0'; + + if (data <= 9) + res = data + '0'; + else + res = (data - 10) + 'A'; + + return res; +} + +/** convert a ASCII value to the 4 bytes value. + * \param data the character to convert. + * \return the 4 bits value corresponding to the data. + */ +uint8_t +flash_data_convert_from_char (char data) +{ + uint8_t res = 0x0; + + if ((data >= '0') && (data <= '9')) + res = data - '0'; + else + res = (data + 10) - 'A'; + + return res; +} + +void +flash_write (uint32_t addr, uint8_t data) +{ + char car[2]; + + /* Multiply per two the addr. */ + addr *= 2; + + car[0] = flash_data_convert_to_char (data & 0xF); + car[1] = flash_data_convert_to_char (data >> 4); + + if (flash_global.status + && FLASH_ADDRESS_HIGH > addr) + { + uint8_t nb_bytes; + + /* Jump to the address requested. */ + lseek (flash_global.file, addr, SEEK_SET); + nb_bytes = write (flash_global.file, car, 2 * sizeof (uint8_t)); + + flash_global.status = !(nb_bytes == 0); + } +} + +uint8_t +flash_read (uint32_t addr) +{ + uint8_t res = 0x0; + addr *= 2; + + if (flash_global.status + && FLASH_ADDRESS_HIGH > addr) + { + uint8_t nb_bytes = 0; + uint8_t error_nb; + char car[2]; + + /* Jump to the address requested. */ + lseek (flash_global.file, addr, SEEK_SET); + for (error_nb = 0; (error_nb < 3) && (nb_bytes == 0); error_nb ++) + { + nb_bytes = read (flash_global.file, car, 2 * sizeof (uint8_t)); + } + + res = flash_data_convert_from_char (car[0]); + res |= (flash_data_convert_from_char (car[1]) << 4); + + if (nb_bytes == 2) + return res; + else + return 0xFF; + } + + return res; +} + +void +flash_read_array (uint32_t addr, uint8_t *buffer, uint32_t length) +{ + uint32_t i; + + if (buffer != NULL && length != 0) + { + for (i = 0; i < length; i++) + { + buffer[i] = flash_read (addr + i); + } + } +} + +void +flash_write_array (uint32_t addr, uint8_t *data, uint32_t length); diff --git a/digital/avr/modules/flash/stub/test/Makefile b/digital/avr/modules/flash/stub/test/Makefile new file mode 100644 index 00000000..096fbe3f --- /dev/null +++ b/digital/avr/modules/flash/stub/test/Makefile @@ -0,0 +1,12 @@ +BASE = ../../../.. +HOST_PROGS = test_flash + +test_flash_SOURCES = test_flash.c + +MODULES = utils flash/stub +OPTIMIZE = -O2 + +include $(BASE)/make/Makefile.gen + +all: + touch flash.apb diff --git a/digital/avr/modules/flash/stub/test/test_flash.c b/digital/avr/modules/flash/stub/test/test_flash.c new file mode 100644 index 00000000..4c7cfb16 --- /dev/null +++ b/digital/avr/modules/flash/stub/test/test_flash.c @@ -0,0 +1,57 @@ +/* test-flash.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 "modules/flash/flash.h" +#include + +int +main (void) +{ + uint8_t status; + uint32_t addr; + uint8_t i; + + status = flash_init (); + printf ("Flash status : %d\n", status); + + flash_erase (FLASH_ERASE_FULL, 0); + + for (i = 0; i < 10; i++) + { + status = flash_init (); + printf ("Flash status : %d\n", status); + + // Get the first sector to begin. + addr = flash_first_sector (); + printf ("First sector : %x\n", addr); + + flash_write (addr, 0xA); + flash_write (addr + 1, 0xB); + + printf ("First data in the flash memory : %x\n", flash_read (addr)); + printf ("Second data in the flash memory : %x\n", flash_read (addr + 1)); + } + + return 0; +} -- cgit v1.2.3