µracoli Manual  Version foo
ioutil.h
1 /* Copyright (c) 2007 Axel Wachtler
2  All rights reserved.
3 
4  Redistribution and use in source and binary forms, with or without
5  modification, are permitted provided that the following conditions
6  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 the
12  documentation and/or other materials provided with the distribution.
13  * Neither the name of the authors nor the names of its contributors
14  may be used to endorse or promote products derived from this software
15  without specific prior written permission.
16 
17  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  POSSIBILITY OF SUCH DAMAGE. */
28 
29 /* The function keys_debounced() use the code given in Peter Fleury's
30  avr-gcc examples. File: avrgcc-examples/debounce_keys.c */
31 
32 /****************************************************************************
33  Title: Debouncing 8 Keys
34  Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury,
35  based on algorithm of Peter Dannegger <danni@specs.de>
36  Date: December 2003
37  Software: AVR-GCC 3.3
38  Hardware: AT90S8515 at 4 Mhz, STK200 compatible starter kit
39 
40 *****************************************************************************/
41 
42 /* $Id$ */
48 #ifndef IOUTIL_H
49 #define IOUTIL_H
50 
51 /* === Includes ============================================================== */
52 #include <stdlib.h>
53 #include <stdio.h>
54 //#include <util/atomic.h>
55 
56 #include "board.h"
57 #include "hif.h"
58 #include "timer.h"
59 
60 /* === Externals ============================================================= */
61 
62 /* === Types ================================================================= */
63 
72 typedef struct
73 {
75  void * next;
77  uint8_t used;
79  uint8_t len;
81  uint8_t istart;
83  uint8_t iend;
85  uint8_t data[];
86 } buffer_t;
87 
88 
89 typedef struct
90 {
92  uint8_t nb;
94  uint8_t elsz;
96  uint8_t pool[];
97 } buffer_pool_t;
98 
101 /* === Macros ================================================================ */
102 
103 /* === LED Handling === */
104 
108 #if defined(NO_LEDS) || defined (DOXYGEN)
109 # undef LED_NUMBER
110 
111 # define LED_NUMBER (0)
112 #endif
113 
114 #if defined(NO_LEDS) || defined (DOXYGEN)
115 
116 # define LED_INIT() do{}while(0)
117 #elif !defined(LED_INIT)
118 # if LEDS_INVERSE == 0
119 # define LED_INIT() do{\
120  LED_DDR |= (LED_MASK); LED_PORT &= ~(LED_MASK);\
121  }while(0)
122 # else
123 # define LED_INIT() do{\
124  LED_DDR |= (LED_MASK); LED_PORT |= (LED_MASK);\
125  }while(0)
126 # endif
127 #endif /* !defined(LED_INIT)*/
128 
129 #if defined(NO_LEDS) || defined (DOXYGEN)
130 
135 # define LED_SET_VALUE(x) do{}while(0)
136 #elif !defined(LED_SET_VALUE)
137 # if LEDS_INVERSE == 0
138 # define LED_SET_VALUE(x) \
139  do {\
140  LED_PORT = (LED_PORT & ~LED_MASK) | ((x<<LED_SHIFT) & LED_MASK);\
141  }while(0)
142 # else
143 # define LED_SET_VALUE(x) do {\
144  LED_PORT = (LED_PORT & ~LED_MASK) | ((~x<<LED_SHIFT) & LED_MASK);\
145  }while(0)
146 # endif
147 #endif /* !defined(LED_SET_VALUE)*/
148 
149 #if defined(NO_LEDS) || defined (DOXYGEN)
150 
151 # define LED_GET_VALUE() 0
152 #elif !defined(LED_GET_VALUE)
153 # if LEDS_INVERSE == 0
154 # define LED_GET_VALUE() ((LED_PORT & LED_MASK) >> LED_SHIFT)
155 # else
156 # define LED_GET_VALUE() ((~LED_PORT & LED_MASK) >> LED_SHIFT)
157 # endif
158 #endif /* !defined(LED_GET_VALUE)*/
159 
160 
161 #if defined(NO_LEDS) || defined (DOXYGEN)
162 
163 # define LED_SET(ln) do{}while(0)
164 #elif !defined(LED_SET)
165 # if LEDS_INVERSE == 0
166 # define LED_SET(ln) LED_PORT |= (_BV(ln+LED_SHIFT) & LED_MASK)
167 # else
168 # define LED_SET(ln) LED_PORT &= ~(_BV(ln+LED_SHIFT) & LED_MASK)
169 # endif
170 #endif /* !defined(LED_SET)*/
171 
172 
173 #if defined(NO_LEDS) || defined (DOXYGEN)
174 
175 # define LED_CLR(ln) do{}while(0)
176 #elif !defined(LED_CLR)
177 # if LEDS_INVERSE == 0
178 # define LED_CLR(ln) LED_PORT &= ~(_BV(ln+LED_SHIFT) & LED_MASK)
179 # else
180 # define LED_CLR(ln) LED_PORT |= (_BV(ln+LED_SHIFT) & LED_MASK)
181 # endif
182 #endif /* !defined(LED_CLR)*/
183 
184 #if defined(NO_LEDS) || defined (DOXYGEN)
185 
186 # define LED_VAL(msk,val) do{}while(0)
187 #elif !defined(LED_VAL)
188 # if LEDS_INVERSE == 0
189 # define LED_VAL(msk,val) LED_PORT |= ((LED_MASK|msk) << LED_SHIFT); \
190  LED_PORT |= ~((val << LED_SHIFT)& (LED_MASK|(msk<<LED_SHIFT)) )
191 # else
192 # define LED_VAL(msk,val) LED_PORT &= ~(LED_MASK|(msk<<LED_SHIFT)); LED_PORT |= ~(val & (LED_MASK|msk))
193 
194 # endif
195 #endif /* !defined(LED_VAL)*/
196 
197 #if defined(NO_LEDS) || defined (DOXYGEN)
198 
199 # define LED_TOGGLE(ln) do{}while(0)
200 #elif !defined(LED_TOGGLE)
201 # define LED_TOGGLE(ln) LED_PORT ^= (_BV(ln+LED_SHIFT) & LED_MASK)
202 #endif /* !defined(LED_TOGGLE)*/
203 
205 #define LED_MAX_VALUE ((1<<LED_NUMBER)-1)
206 
210 /* === KEY Handling === */
211 
216 #if defined(NO_KEYS) || defined (DOXYGEN)
217 
218 # define KEY_INIT()
219 
221 # define KEY_GET() (0)
222 
223 #else /* defined(NO_KEYS) || defined (DOXYGEN) */
224 # if PULLUP_KEYS != 0
225 # define PULL_MASK (MASK_KEY)
226 # else /* PULLUP_KEYS != 0 */
227 # define PULL_MASK (0)
228 # endif /* PULLUP_KEYS != 0 */
229 # if !defined KEY_INIT
230 # define KEY_INIT() do{PORT_KEY |= PULL_MASK; DDR_KEY &= ~(MASK_KEY); }while(0)
231 # endif
232 # if !defined KEY_GET
233 # if INVERSE_KEYS == 0
234 # define KEY_GET()\
235  ((PIN_KEY & MASK_KEY) >> SHIFT_KEY)
236 # else /* INVERSE_KEYS == 0 */
237 # define KEY_GET()\
238  ((~PIN_KEY & MASK_KEY) >> SHIFT_KEY)
239 # endif /* INVERSE_KEYS == 0 */
240 # endif /* !defined KEY_GET */
241 #endif /* defined(NO_KEYS) || defined (DOXYGEN) */
242 
243 
244 
249 static inline uint8_t keys_debounced(void)
250 {
251  static uint8_t key_state; // debounced and inverted key state:
252  static uint8_t ct0, ct1; // holds two bit counter for each key
253  uint8_t i;
254 
255 
256  /*
257  * read current state of keys (active-low),
258  * clear corresponding bit in i when key has changed
259  */
260  i = key_state ^ KEY_GET(); // key changed ?
261 
262  /*
263  * ct0 and ct1 form a two bit counter for each key,
264  * where ct0 holds LSB and ct1 holds MSB
265  * After a key is pressed longer than four times the
266  * sampling period, the corresponding bit in key_state is set
267  */
268  ct0 = ~( ct0 & i ); // reset or count ct0
269  ct1 = (ct0 ^ ct1) & i; // reset or count ct1
270  i &= ct0 & ct1; // count until roll over ?
271  key_state ^= i; // then toggle debounced state
272 
273  /*
274  * To notify main program of pressed key, the correspondig bit
275  * in global variable key_press is set.
276  * The main loop needs to clear this bit
277  */
278  return key_state & i; // 0->1: key press detect
279 
280 }
281 
286 static inline void trap_if_key_pressed(void)
287 {
288 
289  KEY_INIT();
290  DELAY_MS(10);
291  if (KEY_GET())
292  {
293  LED_INIT();
294  while(1)
295  {
296  DELAY_MS(400);
297  LED_SET(0);
298  DELAY_MS(10);
299  LED_CLR(0);
300  }
301  }
302 }
303 
306 /* === Bootloader Interface === */
307 #if BOOTLOADER_ADDRESS != 0
308 
309 #define JUMP_BOOT_LOADER() \
310  do {\
311  void (*funcptr)( uint8_t flag ) = BOOTLOADER_ADDRESS;\
312  funcptr(42);\
313  }while(0)
314 #else /* BOOTLOADER_ADDRESS != 0 */
315 #define JUMP_BOOT_LOADER()
316 #endif /* BOOTLOADER_ADDRESS != 0 */
317 
318 
319 
320 
321 /* === Prototypes ============================================================ */
322 #ifdef __cplusplus
323 extern "C" {
324 #endif
325 
329 #if 0
330 #define BUFFER_SET_USED(b) do{ATOMIC_BLOCK(ATOMIC_FORCEON){b->used|=1}}while(0)
331 #define BUFFER_SET_UNUSED(b) do{ATOMIC_BLOCK(ATOMIC_FORCEON){b->used&=~1}}while(0)
332 #define BUFFER_IS_USED(b) ((b->used&1)!=0)
333 
334 #define BUFFER_SET_LOCK(b) do{ATOMIC_BLOCK(ATOMIC_FORCEON){b->used|=2}}while(0)
335 #define BUFFER_SET_UNLOCK(b) do{ATOMIC_BLOCK(ATOMIC_FORCEON){b->used&=~2}}while(0)
336 #define BUFFER_IS_LOCKED(b) ((b->used&2)!=0)
337 #endif
338 
339 #define BUFFER_SET_USED(b) do{b->used|=1;}while(0)
340 #define BUFFER_SET_UNUSED(b) do{b->used&=~1;}while(0)
341 #define BUFFER_IS_USED(b) ((b->used&1)!=0)
342 
343 #define BUFFER_SET_LOCK(b) do{b->used|=2;}while(0)
344 #define BUFFER_SET_UNLOCK(b) do{b->used&=~2;}while(0)
345 #define BUFFER_IS_LOCKED(b) ((b->used&2)!=0)
346 
347 
348 #define BUFFER_SIZE(b) (b->iend - b->istart)
349 #define BUFFER_PDATA(b) (b->data + b->istart)
350 #define BUFFER_SEEK(b,offset) (b->data + (b->iend=offset))
351 
352 #define BUFFER_GET_MEMBLOCK(b,pmem,size) \
353  do{\
354  b->used = 1;\
355  pmem = (b->data + b->iend);\
356  size = (b->len - b->iend);\
357  }while(0)
358 
359 #define BUFFER_UPDATE_MEMBLOCK(b,end) \
360  do{\
361  b->iend = end;\
362  b->used = 0;\
363  }while(0);
364 
365 #define BUFFER_LAST_CHAR(b) \
366  (b->iend <= b->istart) ? EOF : (char)b->data[b->iend-1]
367 #define BUFFER_FREE_AT_END(b) (b->len - b->iend)
368 #define BUFFER_FREE_AT_START(b) (b->istart)
369 #define BUFFER_ELSZ(x) (sizeof(buffer_t) + (x))
370 #define BUFFER_RESET(b,start) do{ b->iend = b->istart = start;}while(0)
371 #define BUFFER_ADVANCE(b,more) do{ b->istart += more;}while(0)
372 
374 buffer_t * buffer_init(void * pmem, uint8_t size, uint8_t start);
376 int buffer_append_char(buffer_t *b, uint8_t c);
378 int buffer_prepend_char(buffer_t *b, int c);
380 int buffer_get_char(buffer_t *b);
382 uint8_t buffer_append_block(buffer_t *b, void *pdata, uint8_t size);
384 uint8_t buffer_prepend_block(buffer_t *b, void *pdata, uint8_t size);
386 uint8_t buffer_get_block(buffer_t *b, void *pdata, uint8_t size);
387 
388 
389 buffer_pool_t * buffer_pool_init(uint8_t *pmem, size_t memsz, uint8_t bsz);
390 buffer_t * buffer_alloc(buffer_pool_t *ppool, uint8_t istart);
391 void buffer_free(buffer_t * pbuf);
392 
393 
394 
395 /* buffer stream function */
396 //typedef void (*incb)(buffer_t *pbuf) buffer_stream_incb_t;
397 //typedef void (*outcb)(buffer_t *pbuf) buffer_stream_outcb_t;
398 
399 typedef struct
400 {
401  FILE bstream;
402  buffer_t *pbufin;
403  buffer_t *pbufout;
404  void (*incb)(buffer_t *pbuf);
405  void (*outcb)(buffer_t *pbuf);
406 } buffer_stream_t;
407 
408 
409 
410 int buffer_stream_init( buffer_stream_t *pbs,
411  void (*incb)(buffer_t *pbuf),
412  void (*outcb)(buffer_t *pbuf));
413 
414 int buffer_stream_putchar(char c,FILE *f);
415 int buffer_stream_getchar(FILE *f);
416 
417 
418 
420 #ifdef __cplusplus
421 } /* extern "C" */
422 #endif
423 
424 #endif /* #ifndef IOUTIL_H */
425 /* EOF */
#define KEY_GET()
Definition: ioutil.h:221
#define LED_INIT()
Definition: ioutil.h:116
int buffer_get_char(buffer_t *b)
int buffer_append_char(buffer_t *b, uint8_t c)
#define KEY_INIT()
Definition: ioutil.h:218
uint8_t used
Definition: ioutil.h:77
uint8_t buffer_append_block(buffer_t *b, void *pdata, uint8_t size)
void * next
Definition: ioutil.h:75
#define LED_CLR(ln)
Definition: ioutil.h:175
static uint8_t keys_debounced(void)
Debounce Key values, returned from the macro KEY_GET()
Definition: ioutil.h:249
uint8_t buffer_get_block(buffer_t *b, void *pdata, uint8_t size)
uint8_t istart
Definition: ioutil.h:81
uint8_t len
Definition: ioutil.h:79
uint8_t buffer_prepend_block(buffer_t *b, void *pdata, uint8_t size)
int buffer_prepend_char(buffer_t *b, int c)
buffer_t * buffer_init(void *pmem, uint8_t size, uint8_t start)
#define DELAY_MS(x)
Macro for delays with ms resolution.
Definition: board.h:93
static void trap_if_key_pressed(void)
Debounce Key values, returned from the macro KEY_GET()
Definition: ioutil.h:286
uint8_t iend
Definition: ioutil.h:83
#define LED_SET(ln)
Definition: ioutil.h:163