2 * Copyright © 2012 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19 #include <ao_storage.h>
21 /* Total bytes of available storage */
22 ao_pos_t ao_storage_total = 4096;
24 /* Block size - device is erased in these units. */
25 ao_pos_t ao_storage_block = 1024;
27 /* Byte offset of config block. Will be ao_storage_block bytes long */
28 ao_pos_t ao_storage_config = 0;
30 /* Storage unit size - device reads and writes must be within blocks of this size. */
31 uint16_t ao_storage_unit = 1024;
33 /* Location of eeprom in address space */
34 #define stm_eeprom ((uint8_t *) 0x08080000)
37 * The internal flash chip is arranged in 8 byte sectors; the
38 * chip cannot erase in units smaller than that.
40 * Writing happens in units of 2 bytes and
41 * can only change bits from 1 to 0. So, you can rewrite
42 * the same contents, or append to an existing page easily enough
46 * Erase the specified sector
49 ao_storage_erase(ao_pos_t pos) __reentrant
56 ao_intflash_unlock(void)
58 /* Unlock Data EEPROM and FLASH_PECR register */
59 stm_flash.pekeyr = STM_FLASH_PEKEYR_PEKEY1;
60 stm_flash.pekeyr = STM_FLASH_PEKEYR_PEKEY2;
62 /* Configure the FTDW bit (FLASH_PECR[8]) to execute
63 * word write, whatever the previous value of the word
66 stm_flash.pecr = ((0 << STM_FLASH_PECR_OBL_LAUNCH) |
67 (0 << STM_FLASH_PECR_ERRIE) |
68 (0 << STM_FLASH_PECR_EOPIE) |
69 (0 << STM_FLASH_PECR_FPRG) |
70 (0 << STM_FLASH_PECR_ERASE) |
71 (0 << STM_FLASH_PECR_FTDW) |
72 (1 << STM_FLASH_PECR_DATA) |
73 (0 << STM_FLASH_PECR_PROG) |
74 (0 << STM_FLASH_PECR_OPTLOCK) |
75 (0 << STM_FLASH_PECR_PRGLOCK) |
76 (0 << STM_FLASH_PECR_PELOCK));
80 ao_intflash_lock(void)
82 stm_flash.pecr |= (1 << STM_FLASH_PECR_PELOCK);
86 ao_intflash_wait(void)
88 /* Wait for the flash unit to go idle */
89 while (stm_flash.sr & (1 << STM_FLASH_SR_BSY))
94 ao_intflash_write32(uint16_t pos, uint32_t w)
96 volatile uint32_t *addr;
98 addr = (uint32_t *) (stm_eeprom + pos);
100 /* Erase previous word */
105 /* Write a word to a valid address in the data EEPROM */
112 ao_intflash_write8(uint16_t pos, uint8_t d)
114 uint32_t w, *addr, mask;
117 addr = (uint32_t *) (stm_eeprom + (pos & ~3));
119 /* Compute word to be written */
120 shift = (pos & 3) << 3;
121 mask = 0xff << shift;
122 w = (*addr & ~mask) | (d << shift);
124 ao_intflash_write32(pos & ~3, w);
128 ao_intflash_read(uint16_t pos)
130 return stm_eeprom[pos];
138 ao_storage_device_write(ao_pos_t pos32, __xdata void *v, uint16_t len) __reentrant
140 uint16_t pos = pos32;
141 __xdata uint8_t *d = v;
143 if (pos >= ao_storage_total || pos + len > ao_storage_total)
146 ao_intflash_unlock();
148 if ((pos & 3) == 0 && len >= 4) {
151 w = d[0] | (d[1] << 8) | (d[2] << 16) | (d[3] << 24);
152 ao_intflash_write32(pos, w);
157 ao_intflash_write8(pos, *d);
172 ao_storage_device_read(ao_pos_t pos, __xdata void *v, uint16_t len) __reentrant
176 if (pos >= ao_storage_total || pos + len > ao_storage_total)
179 *d++ = ao_intflash_read(pos++);
184 ao_storage_flush(void) __reentrant
189 ao_storage_setup(void)
194 ao_storage_device_info(void) __reentrant
197 printf ("Using internal flash\n");
201 ao_storage_device_init(void)