~ubuntu-branches/ubuntu/raring/avr-libc/raring-proposed

« back to all changes in this revision

Viewing changes to libc/misc/eeprom.S

  • Committer: Bazaar Package Importer
  • Author(s): Hakan Ardo
  • Date: 2008-04-04 17:05:32 UTC
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20080404170532-t84huz4qk2928pt3
Tags: upstream-1.6.2
ImportĀ upstreamĀ versionĀ 1.6.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2002, Marek Michalkiewicz
2
 
   Copyright (c) 2005, Bjoern Haase
3
 
   All rights reserved.
4
 
 
5
 
   Redistribution and use in source and binary forms, with or without
6
 
   modification, are permitted provided that the following conditions are met:
7
 
 
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
13
 
     distribution.
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.
17
 
 
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. */
29
 
 
30
 
/*
31
 
   eeprom.S
32
 
 
33
 
   Contributors:
34
 
     Created by Marek Michalkiewicz <marekm@linux.org.pl>
35
 
     eeprom_write_word and eeprom_write_block added by Artur Lipowski
36
 
     <LAL@pro.onet.pl>
37
 
     Complete rewrite using the original interface by Bjoern Haase
38
 
     <bjoern.haase@de.bosch.com>.
39
 
 */
40
 
 
41
 
#include "macros.inc"
42
 
#include "ctoasm.inc"
43
 
#include "avr/io.h"
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
47
 
   subroutines.
48
 
   First two letters:  EECR address.
49
 
   Second two letters: EEDR address.
50
 
   Last two letters:   EEAR address.  */
51
 
#define __EEPROM_REG_LOCATIONS__ 1C1D1E
52
 
#endif
53
 
 
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
57
 
 
58
 
#undef  __EEPROM_REG_LOCATIONS__
59
 
#define __EEPROM_REG_LOCATIONS__ EEPROM_REG_LOCATIONS_OVERRIDE
60
 
 
61
 
#define HEXNR CONCAT1(0x , EEPROM_REG_LOCATIONS_OVERRIDE)
62
 
 
63
 
#ifdef EECR
64
 
#undef EECR
65
 
#define EECR _SFR_IO8((HEXNR >> 16) & 0xFF)
66
 
#endif
67
 
 
68
 
#ifdef EEDR
69
 
#undef EEDR
70
 
#define EEDR _SFR_IO8((HEXNR >> 8) & 0xFF )
71
 
#endif
72
 
 
73
 
#ifdef EEAR
74
 
#undef EEAR
75
 
#define EEAR _SFR_IO8(HEXNR & 0xFF)
76
 
#endif
77
 
 
78
 
#ifdef EEARH
79
 
#undef EEARH
80
 
#endif
81
 
 
82
 
#ifdef EEARL
83
 
#undef EEARL
84
 
#define EEARL EEAR
85
 
#endif
86
 
 
87
 
#endif
88
 
 
89
 
#define _EELABEL(x) CONCAT1(__,CONCAT1(x, CONCAT1 (_,__EEPROM_REG_LOCATIONS__)))
90
 
 
91
 
/* the same library is used for 2313 and 8515 for now -
92
 
   I hope writing 0 to non-existent EEARH doesn't hurt... */
93
 
#ifndef EEARH
94
 
#define EEARH (EEARL+1)
95
 
#endif
96
 
 
97
 
 
98
 
#ifdef L_eeprom_read_byte
99
 
/* read one byte from EEPROM.
100
 
   addr = r26:r27, result = __tmp_reg__ 
101
 
   Post increment r26:r27.  */
102
 
 
103
 
        .section .text.eeprom, "ax", @progbits
104
 
        .global _EELABEL(eeprom_read_byte)
105
 
 
106
 
_EELABEL(eeprom_read_byte):
107
 
        sbic    _SFR_IO_ADDR(EECR), EEWE
108
 
        rjmp    _EELABEL(eeprom_read_byte)      /* make sure EEPROM is ready */
109
 
#ifdef EEARH
110
 
        out     _SFR_IO_ADDR(EEARH),r27
111
 
#endif
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)
116
 
        ret
117
 
#endif /* L_eeprom_read_byte */
118
 
 
119
 
#ifdef L_eeprom_read_word
120
 
/* read one word from EEPROM.
121
 
   addr = r26:r27, result = r30:r31
122
 
   Post increment r26:r27.  */
123
 
 
124
 
        .section .text.eeprom, "ax", @progbits
125
 
        .global _EELABEL(eeprom_read_word)
126
 
 
127
 
_EELABEL(eeprom_read_word):
128
 
        rcall _EELABEL(eeprom_read_byte)
129
 
        mov r30,__tmp_reg__
130
 
        rcall _EELABEL(eeprom_read_byte)
131
 
        mov r31,__tmp_reg__
132
 
        ret
133
 
#endif
134
 
 
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.  */
139
 
 
140
 
        .section .text.eeprom, "ax", @progbits
141
 
        .global _EELABEL(eeprom_write_byte)
142
 
 
143
 
_EELABEL(eeprom_write_byte):
144
 
        sbic    _SFR_IO_ADDR(EECR), EEWE
145
 
        rjmp    _EELABEL(eeprom_write_byte)     /* make sure EEPROM is ready */
146
 
#ifdef EEARH
147
 
        out     _SFR_IO_ADDR(EEARH), r27
148
 
#endif
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__
157
 
        ret
158
 
#undef val
159
 
#endif /* L_eeprom_write_byte */
160
 
 
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.  */
165
 
 
166
 
        .section .text.eeprom, "ax", @progbits
167
 
        .global _EELABEL(eeprom_write_word)
168
 
 
169
 
_EELABEL(eeprom_write_word):
170
 
        rcall _EELABEL(eeprom_write_byte)
171
 
        mov __tmp_reg__,__zero_reg__
172
 
        rcall _EELABEL(eeprom_write_byte)
173
 
        clr __zero_reg__
174
 
        ret
175
 
#endif
176
 
 
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. */
181
 
 
182
 
        .section .text.eeprom, "ax", @progbits
183
 
        .global _EELABEL(eeprom_read_block)
184
 
        .global _EELABEL(eeprom_read_byte)
185
 
 
186
 
_EELABEL(eeprom_read_block):
187
 
        rcall _EELABEL(eeprom_read_byte)
188
 
        st z+,__tmp_reg__
189
 
        dec __zero_reg__
190
 
        brne _EELABEL(eeprom_read_block)
191
 
        ret
192
 
#endif /* L_eeprom_read_block */
193
 
 
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. */
198
 
 
199
 
        .section .text.eeprom, "ax", @progbits
200
 
        .global _EELABEL(eeprom_write_block)
201
 
        .global _EELABEL(eeprom_write_byte)
202
 
 
203
 
_EELABEL(eeprom_write_block):
204
 
        ld __tmp_reg__,z+
205
 
        rcall _EELABEL(eeprom_write_byte)
206
 
        dec __zero_reg__
207
 
        brne _EELABEL(eeprom_write_block)
208
 
        ret
209
 
#endif /* L_eeprom_write_block */
210
 
 
211
 
.end