4
Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
6
This file is part of simavr.
8
simavr is free software: you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation, either version 3 of the License, or
11
(at your option) any later version.
13
simavr is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with simavr. If not, see <http://www.gnu.org/licenses/>.
22
#ifndef __SIM_REGBIT_H__
23
#define __SIM_REGBIT_H__
31
#define ARRAY_SIZE(_aa) (sizeof(_aa) / sizeof((_aa)[0]))
35
* These accessors are inlined and are used to perform the operations on
36
* avr_regbit_t definitions. This is the "official" way to access bits into registers
37
* The small footprint costs brings much better versatility for functions/bits that are
38
* not always defined in the same place on real AVR cores
41
* set/get/clear io register bits in one operation
43
static inline uint8_t avr_regbit_set(avr_t * avr, avr_regbit_t rb)
50
m = rb.mask << rb.bit;
51
avr_core_watch_write(avr, a, avr->data[a] | m);
52
return (avr->data[a] >> rb.bit) & rb.mask;
55
static inline uint8_t avr_regbit_setto( avr_t* avr, avr_regbit_t rb, uint8_t v )
62
m = rb.mask << rb.bit;
63
avr_core_watch_write(avr, a, (avr->data[a] & ~(m)) | ((v << rb.bit) & m));
64
return (avr->data[a] >> rb.bit) & rb.mask;
68
* Set the 'raw' bits, if 'v' is the unshifted value of the bits
70
static inline uint8_t avr_regbit_setto_raw( avr_t* avr, avr_regbit_t rb, uint8_t v )
77
m = rb.mask << rb.bit;
78
avr_core_watch_write(avr, a, (avr->data[a] & ~(m)) | ((v) & m));
79
return (avr->data[a]) & (rb.mask << rb.bit);
82
static inline uint8_t avr_regbit_get(avr_t * avr, avr_regbit_t rb)
87
//uint8_t m = rb.mask << rb.bit;
88
return (avr->data[a] >> rb.bit) & rb.mask;
92
* Using regbit from value eliminates some of the
93
* set to test then clear register operations.
94
* makes cheking register bits before setting easier.
96
static inline uint8_t avr_regbit_from_value(
97
avr_t * avr __attribute__((unused)),
104
return (value >> rb.bit) & rb.mask;
108
* Return the bit(s) 'in position' instead of zero based
110
static inline uint8_t avr_regbit_get_raw(avr_t * avr, avr_regbit_t rb)
115
//uint8_t m = rb.mask << rb.bit;
116
return (avr->data[a]) & (rb.mask << rb.bit);
119
static inline uint8_t avr_regbit_clear(avr_t * avr, avr_regbit_t rb)
122
uint8_t m = rb.mask << rb.bit;
123
avr_core_watch_write(avr, a, avr->data[a] & ~m);
129
* This reads the bits for an array of avr_regbit_t, make up a "byte" with them.
130
* This allows reading bits like CS0, CS1, CS2 etc even if they are not in the same
131
* physical IO register.
133
static inline uint8_t avr_regbit_get_array(avr_t * avr, avr_regbit_t *rb, int count)
138
for (i = 0; i < count; i++, rb++) if (rb->reg) {
139
uint16_t a = rb->reg;
140
res |= ((avr->data[a] >> rb->bit) & rb->mask) << i;
146
* Does the reverse of avr_regbit_get_array
148
static inline void avr_regbit_set_array_from_value(
155
for (i = 0; i < count; i++, rb++) if (rb->reg) {
156
uint8_t rbv = (value >> (count - i)) & 1;
157
avr_regbit_setto(avr, *rb, rbv);
161
#define AVR_IO_REGBIT(_io, _bit) { . reg = (_io), .bit = (_bit), .mask = 1 }
162
#define AVR_IO_REGBITS(_io, _bit, _mask) { . reg = (_io), .bit = (_bit), .mask = (_mask) }
168
#endif /* __SIM_REGBIT_H__ */