Timer 3 working with slower clock and all 16 bits.
[fw/altos] / src / avr / ao_eeprom_avr.c
1 /*
2  * Copyright © 2012 Keith Packard <keithp@keithp.com>
3  * Copyright © 2011  Anthony Towns <aj@erisian.com.au>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; version 2 of the License.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #include <ao.h>
20 #include <ao_storage.h>
21
22 /* Total bytes of available storage */
23 __pdata ao_pos_t        ao_storage_total = 1024;
24
25 /* Block size - device is erased in these units. */
26 __pdata ao_pos_t        ao_storage_block = 1024;
27
28 /* Byte offset of config block. Will be ao_storage_block bytes long */
29 __pdata ao_pos_t        ao_storage_config = 0;
30
31 /* Storage unit size - device reads and writes must be within blocks of this size. */
32 __pdata uint16_t        ao_storage_unit = 1024;
33
34 /*
35  * The internal flash chip is arranged in 8 byte sectors; the
36  * chip cannot erase in units smaller than that.
37  *
38  * Writing happens in units of 2 bytes and
39  * can only change bits from 1 to 0. So, you can rewrite
40  * the same contents, or append to an existing page easily enough
41  */
42
43 /*
44  * Erase the specified sector
45  */
46 uint8_t
47 ao_storage_erase(ao_pos_t pos) __reentrant
48 {
49         /* Not necessary */
50         return 1;
51 }
52
53 #define ao_intflash_wait_idle() do {                                    \
54                 /* Wait for any outstanding writes to complete */       \
55                 while (EECR & (1 << EEPE))                              \
56                         ;                                               \
57         } while (0)                                                     \
58
59 static void
60 ao_intflash_write(uint16_t pos, uint8_t d)
61 {
62         ao_intflash_wait_idle();
63         EEAR = pos;
64         EEDR = d;
65         ao_arch_critical(
66                 EECR |= (1 << EEMPE);
67                 EECR |= (1 << EEPE);
68                 );
69 }
70
71 static uint8_t
72 ao_intflash_read(uint16_t pos)
73 {
74         ao_intflash_wait_idle();
75         EEAR = pos;
76
77         EECR |= (1 << EERE);
78         return EEDR;
79 }
80 /*
81  * Write to flash
82  */
83
84 uint8_t
85 ao_storage_device_write(ao_pos_t pos32, __xdata void *v, uint16_t len) __reentrant
86 {
87         uint16_t pos = pos32;
88         __xdata uint8_t *d = v;
89
90         if (pos >= ao_storage_total || pos + len > ao_storage_total)
91                 return 0;
92
93         while (len--)
94                 ao_intflash_write(pos++, *d++);
95
96         return 1;
97 }
98
99 /*
100  * Read from flash
101  */
102 uint8_t
103 ao_storage_device_read(ao_pos_t pos, __xdata void *v, uint16_t len) __reentrant
104 {
105         uint8_t *d = v;
106         
107         if (pos >= ao_storage_total || pos + len > ao_storage_total)
108                 return 0;
109         while (len--)
110                 *d++ = ao_intflash_read(pos++);
111         return 1;
112 }
113
114 void
115 ao_storage_flush(void) __reentrant
116 {
117 }
118
119 void
120 ao_storage_setup(void)
121 {
122 }
123
124 void
125 ao_storage_device_info(void) __reentrant
126 {
127         printf ("Using internal flash\n");
128 }
129
130 void
131 ao_storage_device_init(void)
132 {
133 }