2 * Copyright Droids Corporation, Microb Technology, Eirbot (2007)
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * Revision : $Id: aversive.h,v 1.1.2.6 2009-05-18 12:19:51 zer0 Exp $
23 * here are some cute little macros, and other stuff, microcontroller
34 #include <avr/interrupt.h>
38 #include <aversive/types.h>
39 #include <aversive/errno.h>
40 #include <aversive/irq_lock.h>
43 #ifndef __AVR_LIBC_VERSION__ /* version.h should be included by avr/io.h */
44 #define __AVR_LIBC_VERSION__ 0UL
48 #if __AVR_LIBC_VERSION__ < 10403UL
49 #include <avr/signal.h>
53 #define F_CPU ((unsigned long)CONFIG_QUARTZ)
62 * a few "mathematical" macros : maximums and minimums
66 * signed maxmimum : both signs are tested
68 #define S_MAX(to_saturate, value_max) \
70 if (to_saturate > value_max) \
71 to_saturate = value_max; \
72 else if (to_saturate < -value_max) \
73 to_saturate = -value_max; \
77 * unsigned maximum : result >0 is forced
79 #define U_MAX(to_saturate, value_max) \
81 if (to_saturate > value_max) \
82 to_saturate = value_max; \
83 else if (to_saturate < 0) \
90 #define MAX(to_saturate, value_max) \
92 if (to_saturate > value_max) \
93 to_saturate = value_max; \
99 #define MIN(to_saturate, value_min) \
101 if (to_saturate < value_min) \
102 to_saturate = value_min; \
107 * while the abs() function in the libc works only with int type
108 * this macro works with every numerical type including floats
110 #define ABS(val) ({ \
111 __typeof(val) __val = (val); \
118 * Extract bytes and u16 from larger integer
121 #if __BYTE_ORDER != __LITTLE_ENDIAN && __BYTE_ORDER != __BIG_ENDIAN
122 # error "Endianness not defined"
128 #if __BYTE_ORDER == __LITTLE_ENDIAN
133 #elif __BYTE_ORDER == __BIG_ENDIAN
139 } __attribute__ ((packed)) u8;
141 #if __BYTE_ORDER == __LITTLE_ENDIAN
144 #elif __BYTE_ORDER == __BIG_ENDIAN
148 } __attribute__ ((packed)) u16;
150 #if __BYTE_ORDER == __LITTLE_ENDIAN
154 #elif __BYTE_ORDER == __BIG_ENDIAN
159 } __attribute__ ((packed)) u16_b;
161 } __attribute__ ((packed)) u;
162 } __attribute__ ((packed));
164 #define extr32_08_0(i) ({ struct extract32 __x; __x.u.u32 = i; __x.u.u8.u8_0; })
165 #define extr32_08_1(i) ({ struct extract32 __x; __x.u.u32 = i; __x.u.u8.u8_1; })
166 #define extr32_08_2(i) ({ struct extract32 __x; __x.u.u32 = i; __x.u.u8.u8_2; })
167 #define extr32_08_3(i) ({ struct extract32 __x; __x.u.u32 = i; __x.u.u8.u8_3; })
169 #define extr32_16_0(i) ({ struct extract32 __x; __x.u.u32 = i; __x.u.u16.u16_0; })
170 #define extr32_16_1(i) ({ struct extract32 __x; __x.u.u32 = i; __x.u.u16.u16_1; })
171 #define extr32_16_mid(i) ({ struct extract32 __x; __x.u.u32 = i; __x.u.u16_b.u16_mid; })
177 #if __BYTE_ORDER == __LITTLE_ENDIAN
180 #elif __BYTE_ORDER == __BIG_ENDIAN
184 } __attribute__ ((packed)) u8;
186 } __attribute__ ((packed)) u;
187 } __attribute__ ((packed));
189 #define extr16_08_0(i) ({ struct extract16 __x; __x.u.u16 = i; __x.u.u8.u8_0; })
190 #define extr16_08_1(i) ({ struct extract16 __x; __x.u.u16 = i; __x.u.u8.u8_1; })
194 /* a few asm utilities */
198 #define nop() __asm__ __volatile__ ("NOP\n") /** nop instruction, 1 CPU cycle consumed */
201 #define nothing() __asm__ __volatile__ (" \n") /** nothing */
204 #define cli() __asm__ __volatile__ ("CLI\n") /** disable interrupts */
207 #define sei() __asm__ __volatile__ ("SEI\n") /** enable interrupts */
209 /** simple software reset, but doesn't initialize the registers */
213 __asm__ __volatile__ ("ldi r30,0\n"); \
214 __asm__ __volatile__ ("ldi r31,0\n"); \
215 __asm__ __volatile__ ("ijmp\n"); \
219 #else /* HOST_VERSION */
220 #define nop() do {} while(0)
221 #define nothing() do {} while(0)
222 #define cli() do {} while(0)
223 #define sei() do {} while(0)
224 #define reset() exit(1)
225 #endif /* HOST_VERSION */
228 * little bit toggeling macro
232 * BIT_TOGGLE(PORTB,2) to make the pin 2 of PORTB toggle
234 #define BIT_TOGGLE(port,bit) do {\
235 if(bit_is_set(PIN(port),bit)) \
251 /** DDR and PINS from port adress */
252 #define DDR(port) (*(&(port) -1))
253 #define PIN(port) (*(&(port) -2))
255 /** open collector simulation macros */
256 #define OPEN_CO_INIT(port, bit) sbi(port,bit)
257 #define OPEN_CO_HIGH(port, bit) cbi(DDR(port),bit)
258 #define OPEN_CO_LOW(port, bit) cbi(DDR(port),bit)
260 /** deprecated macros in libc, but they're almost used, so we implement them again ;) */
262 #define cbi(sfr, bit) ( sfr &= ~ _BV(bit))
265 #define sbi(sfr, bit) ( sfr |= _BV(bit))
269 #endif /* ifndef _AVERSIVE_H_ */