1
/* Copyright (c) 2002, Marek Michalkiewicz
2
Copyright (c) 2005, Bjoern Haase
5
Redistribution and use in source and binary forms, with or without
6
modification, are permitted provided that the following conditions are met:
8
* Redistributions of source code must retain the above copyright
9
notice, this list of conditions and the following disclaimer.
10
* Redistributions in binary form must reproduce the above copyright
11
notice, this list of conditions and the following disclaimer in
12
the documentation and/or other materials provided with the
14
* Neither the name of the copyright holders nor the names of
15
contributors may be used to endorse or promote products derived
16
from this software without specific prior written permission.
18
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
POSSIBILITY OF SUCH DAMAGE. */
34
Created by Marek Michalkiewicz <marekm@linux.org.pl>
35
eeprom_write_word and eeprom_write_block added by Artur Lipowski
37
Complete rewrite using the original interface by Bjoern Haase
38
<bjoern.haase@de.bosch.com>.
44
#ifndef __EEPROM_REG_LOCATIONS__
45
/* 6-byte string denoting where to find the EEPROM registers in memory space.
46
Adresses denoted in hex syntax with uppercase letters. Used by the EEPROM
48
First two letters: EECR address.
49
Second two letters: EEDR address.
50
Last two letters: EEAR address. */
51
#define __EEPROM_REG_LOCATIONS__ 1C1D1E
54
/* As long as we don't have a proper multilib environment: Let's make it
55
possible to override the locations defined in the io headers. */
56
#ifdef EEPROM_REG_LOCATIONS_OVERRIDE
58
#undef __EEPROM_REG_LOCATIONS__
59
#define __EEPROM_REG_LOCATIONS__ EEPROM_REG_LOCATIONS_OVERRIDE
61
#define HEXNR CONCAT1(0x , EEPROM_REG_LOCATIONS_OVERRIDE)
65
#define EECR _SFR_IO8((HEXNR >> 16) & 0xFF)
70
#define EEDR _SFR_IO8((HEXNR >> 8) & 0xFF )
75
#define EEAR _SFR_IO8(HEXNR & 0xFF)
89
#define _EELABEL(x) CONCAT1(__,CONCAT1(x, CONCAT1 (_,__EEPROM_REG_LOCATIONS__)))
91
/* the same library is used for 2313 and 8515 for now -
92
I hope writing 0 to non-existent EEARH doesn't hurt... */
94
#define EEARH (EEARL+1)
98
#ifdef L_eeprom_read_byte
99
/* read one byte from EEPROM.
100
addr = r26:r27, result = __tmp_reg__
101
Post increment r26:r27. */
103
.section .text.eeprom, "ax", @progbits
104
.global _EELABEL(eeprom_read_byte)
106
_EELABEL(eeprom_read_byte):
107
sbic _SFR_IO_ADDR(EECR), EEWE
108
rjmp _EELABEL(eeprom_read_byte) /* make sure EEPROM is ready */
110
out _SFR_IO_ADDR(EEARH),r27
112
out _SFR_IO_ADDR(EEARL),r26
113
sbi _SFR_IO_ADDR(EECR), EERE
114
adiw r26,1 /* Increment x register */
115
in __tmp_reg__, _SFR_IO_ADDR(EEDR)
117
#endif /* L_eeprom_read_byte */
119
#ifdef L_eeprom_read_word
120
/* read one word from EEPROM.
121
addr = r26:r27, result = r30:r31
122
Post increment r26:r27. */
124
.section .text.eeprom, "ax", @progbits
125
.global _EELABEL(eeprom_read_word)
127
_EELABEL(eeprom_read_word):
128
rcall _EELABEL(eeprom_read_byte)
130
rcall _EELABEL(eeprom_read_byte)
135
#ifdef L_eeprom_write_byte
136
/* write a byte to EEPROM
137
Address in r26:r27, value in __tmp_reg__
138
Post increment r26:r27. */
140
.section .text.eeprom, "ax", @progbits
141
.global _EELABEL(eeprom_write_byte)
143
_EELABEL(eeprom_write_byte):
144
sbic _SFR_IO_ADDR(EECR), EEWE
145
rjmp _EELABEL(eeprom_write_byte) /* make sure EEPROM is ready */
147
out _SFR_IO_ADDR(EEARH), r27
149
out _SFR_IO_ADDR(EEARL), r26
150
out _SFR_IO_ADDR(EEDR),__tmp_reg__
151
adiw r26,1 /* Increment x register */
152
in __tmp_reg__, _SFR_IO_ADDR(SREG)
153
cli ; /* no ints between setting EEMWE and EEWE */
154
sbi _SFR_IO_ADDR(EECR), EEMWE
155
sbi _SFR_IO_ADDR(EECR), EEWE
156
out _SFR_IO_ADDR(SREG), __tmp_reg__
159
#endif /* L_eeprom_write_byte */
161
#ifdef L_eeprom_write_word
162
/* write a word to EEPROM
163
Address in r26:r27, value in __tmp_reg__ (LSB) and __zero_reg__ (MSB)
164
Post increment r26:r27. */
166
.section .text.eeprom, "ax", @progbits
167
.global _EELABEL(eeprom_write_word)
169
_EELABEL(eeprom_write_word):
170
rcall _EELABEL(eeprom_write_byte)
171
mov __tmp_reg__,__zero_reg__
172
rcall _EELABEL(eeprom_write_byte)
177
#ifdef L_eeprom_read_block
178
/* read a block of n (maximum 256) bytes from EEPROM
179
ram_buffer = r30:r31, eeprom_addr = r26:r27, n = __zero_reg__
180
an initial value of 0 in __zero_reg__ corresponds to a value of n == 256. */
182
.section .text.eeprom, "ax", @progbits
183
.global _EELABEL(eeprom_read_block)
184
.global _EELABEL(eeprom_read_byte)
186
_EELABEL(eeprom_read_block):
187
rcall _EELABEL(eeprom_read_byte)
190
brne _EELABEL(eeprom_read_block)
192
#endif /* L_eeprom_read_block */
194
#ifdef L_eeprom_write_block
195
/* Write a block of n (maximum 256) bytes to EEPROM
196
ram_pointer = r30:r31, eeprom_addr = r26:r27, n = __zero_reg__
197
an initial value of 0 in __zero_reg__ correspond to a value of n == 256. */
199
.section .text.eeprom, "ax", @progbits
200
.global _EELABEL(eeprom_write_block)
201
.global _EELABEL(eeprom_write_byte)
203
_EELABEL(eeprom_write_block):
205
rcall _EELABEL(eeprom_write_byte)
207
brne _EELABEL(eeprom_write_block)
209
#endif /* L_eeprom_write_block */