ioutil.h

Go to the documentation of this file.
00001 /* Copyright (c) 2007 Axel Wachtler
00002    All rights reserved.
00003 
00004    Redistribution and use in source and binary forms, with or without
00005    modification, are permitted provided that the following conditions
00006    are met:
00007 
00008    * Redistributions of source code must retain the above copyright
00009      notice, this list of conditions and the following disclaimer.
00010    * Redistributions in binary form must reproduce the above copyright
00011      notice, this list of conditions and the following disclaimer in the
00012      documentation and/or other materials provided with the distribution.
00013    * Neither the name of the authors nor the names of its contributors
00014      may be used to endorse or promote products derived from this software
00015      without specific prior written permission.
00016 
00017    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027    POSSIBILITY OF SUCH DAMAGE. */
00028 
00029 /* The function keys_debounced() use the code given in Peter Fleury's
00030    avr-gcc examples. File: avrgcc-examples/debounce_keys.c */
00031 
00032 /****************************************************************************
00033  Title:    Debouncing 8 Keys
00034  Author:   Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury,
00035            based on algorithm of Peter Dannegger <danni@specs.de>
00036  Date:     December 2003
00037  Software: AVR-GCC 3.3
00038  Hardware: AT90S8515 at 4 Mhz, STK200 compatible starter kit
00039 
00040 *****************************************************************************/
00041 
00042 /* $Id: ioutil.h,v 1.15 2010/12/05 20:21:54 awachtler Exp $ */
00048 #ifndef IOUTIL_H
00049 #define IOUTIL_H
00050 
00051 /* === Includes ============================================================== */
00052 #include <stdlib.h>
00053 #include <stdio.h>
00054 //#include <util/atomic.h>
00055 
00056 #include "board.h"
00057 #include "hif.h"
00058 #include "timer.h"
00059 
00060 /* === Externals ============================================================= */
00061 
00062 /* === Types ================================================================= */
00063 
00072 typedef struct
00073 {
00075     void * next;
00077     uint8_t used;
00079     uint8_t len;
00081     uint8_t istart;
00083     uint8_t iend;
00085     uint8_t data[];
00086 } buffer_t;
00087 
00088 
00089 typedef struct
00090 {
00092     uint8_t nb;
00094     uint8_t elsz;
00096     uint8_t pool[];
00097 } buffer_pool_t;
00098 
00101 /* === Macros ================================================================ */
00102 
00103 /* === LED Handling === */
00104 
00108 #if defined(NO_LEDS) || defined (DOXYGEN)
00109 # undef LED_NUMBER
00110 
00111 # define LED_NUMBER    (0)
00112 #endif
00113 
00114 #if defined(NO_LEDS) || defined (DOXYGEN)
00115 
00116 # define LED_INIT() do{}while(0)
00117 #elif !defined(LED_INIT)
00118 # if LEDS_INVERSE == 0
00119 #  define LED_INIT() LED_DDR |= (LED_MASK); LED_PORT &= ~(LED_MASK)
00120 # else
00121 #   define LED_INIT() LED_DDR |= (LED_MASK); LED_PORT |= (LED_MASK)
00122 # endif
00123 #endif /* !defined(LED_INIT)*/
00124 
00125 #if defined(NO_LEDS) || defined (DOXYGEN)
00126 
00131 # define LED_SET_VALUE(x) do{}while(0)
00132 #elif !defined(LED_SET_VALUE)
00133 # if LEDS_INVERSE == 0
00134 #  define LED_SET_VALUE(x) \
00135             do {\
00136                 LED_PORT = (LED_PORT & ~LED_MASK) | ((x<<LED_SHIFT) & LED_MASK);\
00137             }while(0)
00138 # else
00139 #  define LED_SET_VALUE(x) do {\
00140             LED_PORT = (LED_PORT & ~LED_MASK) | ((~x<<LED_SHIFT) & LED_MASK);\
00141             }while(0)
00142 # endif
00143 #endif /* !defined(LED_SET_VALUE)*/
00144 
00145 #if defined(NO_LEDS) || defined (DOXYGEN)
00146 
00147 # define LED_GET_VALUE() 0
00148 #elif !defined(LED_GET_VALUE)
00149 # if LEDS_INVERSE == 0
00150 #  define LED_GET_VALUE()  ((LED_PORT & LED_MASK) >> LED_SHIFT)
00151 # else
00152 #  define LED_GET_VALUE()  ((~LED_PORT & LED_MASK) >> LED_SHIFT)
00153 # endif
00154 #endif /* !defined(LED_GET_VALUE)*/
00155 
00156 
00157 #if defined(NO_LEDS) || defined (DOXYGEN)
00158 
00159 # define LED_SET(ln) do{}while(0)
00160 #elif !defined(LED_SET)
00161 # if LEDS_INVERSE == 0
00162 #  define LED_SET(ln)      LED_PORT |= (_BV(ln+LED_SHIFT) & LED_MASK)
00163 # else
00164 #  define LED_SET(ln)      LED_PORT &= ~(_BV(ln+LED_SHIFT) & LED_MASK)
00165 # endif
00166 #endif /* !defined(LED_SET)*/
00167 
00168 
00169 #if defined(NO_LEDS) || defined (DOXYGEN)
00170 
00171 # define LED_CLR(ln) do{}while(0)
00172 #elif !defined(LED_CLR)
00173 # if LEDS_INVERSE == 0
00174 #  define LED_CLR(ln)      LED_PORT &= ~(_BV(ln+LED_SHIFT) & LED_MASK)
00175 # else
00176 #  define LED_CLR(ln)      LED_PORT |= (_BV(ln+LED_SHIFT) & LED_MASK)
00177 # endif
00178 #endif /* !defined(LED_CLR)*/
00179 
00180 #if defined(NO_LEDS) || defined (DOXYGEN)
00181 
00182 # define LED_VAL(msk,val) do{}while(0)
00183 #elif !defined(LED_VAL)
00184 # if LEDS_INVERSE == 0
00185 #  define LED_VAL(msk,val) LED_PORT |= ((LED_MASK|msk) << LED_SHIFT); \
00186                            LED_PORT |= ~((val << LED_SHIFT)& (LED_MASK|(msk<<LED_SHIFT)) )
00187 # else
00188 #  define LED_VAL(msk,val) LED_PORT &= ~(LED_MASK|(msk<<LED_SHIFT)); LED_PORT |= ~(val & (LED_MASK|msk))
00189 
00190 # endif
00191 #endif /* !defined(LED_VAL)*/
00192 
00193 #if defined(NO_LEDS) || defined (DOXYGEN)
00194 
00195 # define LED_TOGGLE(ln) do{}while(0)
00196 #elif !defined(LED_TOGGLE)
00197 # define LED_TOGGLE(ln) LED_PORT ^= (_BV(ln+LED_SHIFT) & LED_MASK)
00198 #endif /* !defined(LED_TOGGLE)*/
00199 
00201 #define LED_MAX_VALUE ((1<<LED_NUMBER)-1)
00202 
00206 /* === KEY Handling === */
00207 
00212 #if defined(NO_KEYS) || defined (DOXYGEN)
00213 
00214 # define KEY_INIT()
00215 
00217 # define KEY_GET() (0)
00218 
00219 #else /* defined(NO_KEYS) || defined (DOXYGEN) */
00220 # if PULLUP_KEYS != 0
00221 #  define PULL_MASK (MASK_KEY)
00222 # else /* PULLUP_KEYS != 0 */
00223 #  define PULL_MASK (0)
00224 # endif /* PULLUP_KEYS != 0 */
00225 # if !defined KEY_INIT
00226 #  define KEY_INIT()  do{PORT_KEY |= PULL_MASK; DDR_KEY &= ~(MASK_KEY); }while(0)
00227 # endif 
00228 # if INVERSE_KEYS == 0
00229 #  define KEY_GET()\
00230                 ((PIN_KEY & MASK_KEY) >> SHIFT_KEY)
00231 # else /* INVERSE_KEYS == 0 */
00232 #  define KEY_GET()\
00233                 ((~PIN_KEY & MASK_KEY) >> SHIFT_KEY)
00234 # endif /* INVERSE_KEYS == 0 */
00235 #endif /* defined(NO_KEYS) || defined (DOXYGEN) */
00236 
00237 
00238 
00243 static inline uint8_t keys_debounced(void)
00244 {
00245   static uint8_t key_state;     // debounced and inverted key state:
00246   static uint8_t ct0, ct1;      // holds two bit counter for each key
00247   uint8_t i;
00248 
00249 
00250   /*
00251    * read current state of keys (active-low),
00252    * clear corresponding bit in i when key has changed
00253    */
00254   i = key_state ^ KEY_GET();   // key changed ?
00255 
00256   /*
00257    * ct0 and ct1 form a two bit counter for each key,
00258    * where ct0 holds LSB and ct1 holds MSB
00259    * After a key is pressed longer than four times the
00260    * sampling period, the corresponding bit in key_state is set
00261    */
00262   ct0 = ~( ct0 & i );           // reset or count ct0
00263   ct1 = (ct0 ^ ct1) & i;        // reset or count ct1
00264   i &= ct0 & ct1;               // count until roll over ?
00265   key_state ^= i;               // then toggle debounced state
00266 
00267   /*
00268    * To notify main program of pressed key, the correspondig bit
00269    * in global variable key_press is set.
00270    * The main loop needs to clear this bit
00271    */
00272   return key_state & i; // 0->1: key press detect
00273 
00274 }
00275 
00280 static inline void trap_if_key_pressed(void)
00281 {
00282 
00283     KEY_INIT();
00284     DELAY_MS(10);
00285     if (KEY_GET())
00286     {
00287         LED_INIT();
00288         while(1)
00289         {
00290             DELAY_MS(400);
00291             LED_SET(0);
00292             DELAY_MS(10);
00293             LED_CLR(0);
00294         }
00295     }
00296 }
00297 
00300 /* === Bootloader Interface === */
00301 #if BOOT_LOADER_ADDRESS != 0
00302 
00303 #define JUMP_BOOT_LOADER() \
00304     do {\
00305         void (*funcptr)( uint8_t flag ) = BOOT_LOADER_ADDRESS;\
00306         funcptr(42);\
00307     }while(0)
00308 #else /* BOOT_LOADER_ADDRESS != 0 */
00309 #define JUMP_BOOT_LOADER()
00310 #endif /* BOOT_LOADER_ADDRESS != 0 */
00311 
00312 
00313 
00314 
00315 /* === Prototypes ============================================================ */
00316 #ifdef __cplusplus
00317 extern "C" {
00318 #endif
00319 
00323 #if 0
00324 #define BUFFER_SET_USED(b) do{ATOMIC_BLOCK(ATOMIC_FORCEON){b->used|=1}}while(0)
00325 #define BUFFER_SET_UNUSED(b) do{ATOMIC_BLOCK(ATOMIC_FORCEON){b->used&=~1}}while(0)
00326 #define BUFFER_IS_USED(b) ((b->used&1)!=0)
00327 
00328 #define BUFFER_SET_LOCK(b) do{ATOMIC_BLOCK(ATOMIC_FORCEON){b->used|=2}}while(0)
00329 #define BUFFER_SET_UNLOCK(b) do{ATOMIC_BLOCK(ATOMIC_FORCEON){b->used&=~2}}while(0)
00330 #define BUFFER_IS_LOCKED(b) ((b->used&2)!=0)
00331 #endif
00332 
00333 #define BUFFER_SET_USED(b) do{b->used|=1;}while(0)
00334 #define BUFFER_SET_UNUSED(b) do{b->used&=~1;}while(0)
00335 #define BUFFER_IS_USED(b) ((b->used&1)!=0)
00336 
00337 #define BUFFER_SET_LOCK(b) do{b->used|=2;}while(0)
00338 #define BUFFER_SET_UNLOCK(b) do{b->used&=~2;}while(0)
00339 #define BUFFER_IS_LOCKED(b) ((b->used&2)!=0)
00340 
00341 
00342 #define BUFFER_SIZE(b) (b->iend - b->istart)
00343 #define BUFFER_PDATA(b) (b->data + b->istart)
00344 #define BUFFER_SEEK(b,offset) (b->data + (b->iend=offset))
00345 
00346 #define BUFFER_GET_MEMBLOCK(b,pmem,size) \
00347     do{\
00348         b->used = 1;\
00349         pmem = (b->data + b->iend);\
00350         size = (b->len - b->iend);\
00351     }while(0)
00352 
00353 #define BUFFER_UPDATE_MEMBLOCK(b,end) \
00354     do{\
00355         b->iend = end;\
00356         b->used = 0;\
00357     }while(0);
00358 
00359 #define BUFFER_LAST_CHAR(b) \
00360     (b->iend <= b->istart) ? EOF : (char)b->data[b->iend-1]
00361 #define BUFFER_FREE_AT_END(b) (b->len - b->iend)
00362 #define BUFFER_FREE_AT_START(b) (b->istart)
00363 #define BUFFER_ELSZ(x) (sizeof(buffer_t) + (x))
00364 #define BUFFER_RESET(b,start) do{ b->iend = b->istart = start;}while(0)
00365 #define BUFFER_ADVANCE(b,more) do{ b->istart += more;}while(0)
00366 
00368 buffer_t * buffer_init(void * pmem, uint8_t size, uint8_t start);
00370 int buffer_append_char(buffer_t *b, uint8_t c);
00372 int buffer_prepend_char(buffer_t *b, int c);
00374 int buffer_get_char(buffer_t *b);
00376 uint8_t buffer_append_block(buffer_t *b, void *pdata, uint8_t size);
00378 uint8_t buffer_prepend_block(buffer_t *b, void *pdata, uint8_t size);
00380 uint8_t buffer_get_block(buffer_t *b, void *pdata, uint8_t size);
00381 
00382 
00383 buffer_pool_t * buffer_pool_init(uint8_t *pmem, size_t memsz, uint8_t bsz);
00384 buffer_t * buffer_alloc(buffer_pool_t *ppool, uint8_t istart);
00385 void buffer_free(buffer_t * pbuf);
00386 
00387 
00388 
00389 /* buffer stream function */
00390 //typedef void (*incb)(buffer_t *pbuf) buffer_stream_incb_t;
00391 //typedef void (*outcb)(buffer_t *pbuf) buffer_stream_outcb_t;
00392 
00393 typedef struct
00394 {
00395     FILE bstream;
00396     buffer_t *pbufin;
00397     buffer_t *pbufout;
00398     void (*incb)(buffer_t *pbuf);
00399     void (*outcb)(buffer_t *pbuf);
00400 } buffer_stream_t;
00401 
00402 
00403 
00404 int buffer_stream_init( buffer_stream_t *pbs,
00405                         void (*incb)(buffer_t *pbuf),
00406                         void (*outcb)(buffer_t *pbuf));
00407 
00408 int buffer_stream_putchar(char c,FILE *f);
00409 int buffer_stream_getchar(FILE *f);
00410 
00411 
00412 
00414 #ifdef __cplusplus
00415 } /* extern "C" */
00416 #endif
00417 
00418 #endif  /* #ifndef IOUTIL_H */
00419 /* EOF */

This documentation for µracoli was generated on Wed Feb 2 2011 by  doxygen 1.7.1