33
34
Created by Marek Michalkiewicz <marekm@linux.org.pl>
34
eeprom_write_word and eeprom_write_block added by Artur Lipowski <LAL@pro.onet.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>.
37
41
#include "macros.inc"
38
42
#include "ctoasm.inc"
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__)))
40
91
/* the same library is used for 2313 and 8515 for now -
41
92
I hope writing 0 to non-existent EEARH doesn't hurt... */
43
94
#define EEARH (EEARL+1)
51
98
#ifdef L_eeprom_read_byte
52
/* read one byte from EEPROM */
53
/* uint8_t eeprom_read_byte(const uint8_t *addr); */
54
/* addr = r25:r24, result = r25(=0):r24 */
57
.global _U(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):
60
107
sbic _SFR_IO_ADDR(EECR), EEWE
61
rjmp _U(eeprom_read_byte) /* make sure EEPROM is ready */
108
rjmp _EELABEL(eeprom_read_byte) /* make sure EEPROM is ready */
63
out _SFR_IO_ADDR(EEARH), addr_hi
110
out _SFR_IO_ADDR(EEARH),r27
65
out _SFR_IO_ADDR(EEARL), addr_lo
112
out _SFR_IO_ADDR(EEARL),r26
66
113
sbi _SFR_IO_ADDR(EECR), EERE
67
clr res_hi /* gcc wants result extended to "int"? */
68
in res_lo, _SFR_IO_ADDR(EEDR)
114
adiw r26,1 /* Increment x register */
115
in __tmp_reg__, _SFR_IO_ADDR(EEDR)
70
117
#endif /* L_eeprom_read_byte */
72
119
#ifdef L_eeprom_read_word
73
/* read a little endian 16-bit word from EEPROM */
74
/* uint16_t eeprom_read_word(const uint16_t *addr); */
75
/* addr = r25:r24, result = r25:r24 */
77
.global _U(eeprom_read_word)
80
sbic _SFR_IO_ADDR(EECR), EEWE
81
rjmp _U(eeprom_read_word) /* make sure EEPROM is ready */
83
out _SFR_IO_ADDR(EEARH), addr_hi
85
out _SFR_IO_ADDR(EEARL), addr_lo
86
sbi _SFR_IO_ADDR(EECR), EERE
88
in __tmp_reg__, _SFR_IO_ADDR(EEDR)
90
out _SFR_IO_ADDR(EEARH), addr_hi
92
out _SFR_IO_ADDR(EEARL), addr_lo
93
sbi _SFR_IO_ADDR(EECR), EERE
94
mov res_lo, __tmp_reg__
95
in res_hi, _SFR_IO_ADDR(EEDR)
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)
97
#endif /* L_eeprom_read_word */
102
135
#ifdef L_eeprom_write_byte
103
/* write a byte to EEPROM */
104
/* void eeprom_write_byte(uint8_t *addr, uint8_t val); */
105
/* addr = r25:r24, val = r22 */
108
.global _U(eeprom_write_byte)
110
_U(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):
111
144
sbic _SFR_IO_ADDR(EECR), EEWE
112
rjmp _U(eeprom_write_byte) /* make sure EEPROM is ready */
145
rjmp _EELABEL(eeprom_write_byte) /* make sure EEPROM is ready */
114
out _SFR_IO_ADDR(EEARH), addr_hi
147
out _SFR_IO_ADDR(EEARH), r27
116
out _SFR_IO_ADDR(EEARL), addr_lo
117
out _SFR_IO_ADDR(EEDR), val
149
out _SFR_IO_ADDR(EEARL), r26
150
out _SFR_IO_ADDR(EEDR),__tmp_reg__
151
adiw r26,1 /* Increment x register */
118
152
in __tmp_reg__, _SFR_IO_ADDR(SREG)
119
153
cli ; /* no ints between setting EEMWE and EEWE */
120
154
sbi _SFR_IO_ADDR(EECR), EEMWE
125
159
#endif /* L_eeprom_write_byte */
127
161
#ifdef L_eeprom_write_word
128
/* write a word to EEPROM */
129
/* void eeprom_write_word (uint16_t *addr, uint16_t val); */
130
/* addr = r25:r24, val = r23:r22 */
134
.global _U(eeprom_write_word)
136
_U(eeprom_write_word):
137
ser rTI0 ; set flag to indicate that
138
; the first (LSB) byte will be written
139
in __tmp_reg__, _SFR_IO_ADDR(SREG)
140
eeprom_write_word_start:
141
sbic _SFR_IO_ADDR(EECR), EEWE
142
rjmp eeprom_write_word_start ; make sure EEPROM is ready
144
out _SFR_IO_ADDR(EEARH), addr_hi
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)
146
out _SFR_IO_ADDR(EEARL), addr_lo
147
out _SFR_IO_ADDR(EEDR), val_lo
148
cli ; no ints between setting EEMWE and EEWE
149
sbi _SFR_IO_ADDR(EECR), EEMWE
150
sbi _SFR_IO_ADDR(EECR), EEWE
151
out _SFR_IO_ADDR(SREG), __tmp_reg__
152
sbrs rTI0, 0 ; if flag is cleared it means that
153
ret ; we write both bytes
155
subi addr_lo, lo8(-1) ; prepare to writie MSB
156
sbci addr_hi, hi8(-1)
158
clr rTI0 ; clear flag to indicate that
159
rjmp eeprom_write_word_start ; the second (MSB) byte will be written
163
#endif /* L_eeprom_write_word */
175
177
#ifdef L_eeprom_read_block
176
/* read a block of bytes from EEPROM */
177
/* void eeprom_read_block(void *buf, const void *addr, size_t n); */
178
/* buf = r25:r24, addr = r23:r22, n = r21:r20 */
180
.global _U(eeprom_read_block)
182
_U(eeprom_read_block):
183
cp n_lo, __zero_reg__
184
cpc n_hi, __zero_reg__
185
breq eeprom_read_block_done
186
LOAD_X(buf_lo, buf_hi)
187
eeprom_read_block_busy:
188
sbic _SFR_IO_ADDR(EECR), EEWE
189
rjmp eeprom_read_block_busy /* make sure EEPROM is ready */
190
eeprom_read_block_loop:
192
out _SFR_IO_ADDR(EEARH), addr_hi
194
out _SFR_IO_ADDR(EEARL), addr_lo
195
sbi _SFR_IO_ADDR(EECR), EERE
196
subi addr_lo, lo8(-1)
197
sbci addr_hi, hi8(-1)
198
in __tmp_reg__, _SFR_IO_ADDR(EEDR)
202
brne eeprom_read_block_loop
203
eeprom_read_block_done:
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)
205
192
#endif /* L_eeprom_read_block */
207
194
#ifdef L_eeprom_write_block
208
/* write a block of bytes to EEPROM */
209
/* void eeprom_write_block (const void *buf, void *addr, size_t n); */
210
/* buf = r25:r24, addr = r23:r22, n = r21:r20 */
212
.global _U(eeprom_write_block)
214
_U(eeprom_write_block):
215
cp n_lo, __zero_reg__ ; check if really there is something to write
216
cpc n_hi, __zero_reg__
217
breq eeprom_write_block_done
218
LOAD_X(buf_lo, buf_hi)
219
in buf_lo, _SFR_IO_ADDR(SREG) ; reuse buf_lo as the SREG temporary storage
220
eeprom_write_block_busy:
221
sbic _SFR_IO_ADDR(EECR), EEWE
222
rjmp eeprom_write_block_busy ; make sure EEPROM is ready
224
out _SFR_IO_ADDR(EEARH), addr_hi
226
out _SFR_IO_ADDR(EEARL), addr_lo
228
out _SFR_IO_ADDR(EEDR), __tmp_reg__
229
cli ; no ints between setting EEMWE and EEWE
230
sbi _SFR_IO_ADDR(EECR), EEMWE
231
sbi _SFR_IO_ADDR(EECR), EEWE
232
out _SFR_IO_ADDR(SREG), buf_lo
233
subi addr_lo, lo8(-1)
234
sbci addr_hi, hi8(-1)
237
brne eeprom_write_block_busy
238
eeprom_write_block_done:
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)
240
209
#endif /* L_eeprom_write_block */