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_8h_source.html,v 1.1.1.4 2013/04/09 21:12:03 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() do{\
00120                         LED_DDR |= (LED_MASK); LED_PORT &= ~(LED_MASK);\
00121                      }while(0)
00122 # else
00123 #   define LED_INIT() do{\
00124                          LED_DDR |= (LED_MASK); LED_PORT |= (LED_MASK);\
00125                       }while(0)
00126 # endif
00127 #endif /* !defined(LED_INIT)*/
00128 
00129 #if defined(NO_LEDS) || defined (DOXYGEN)
00130 
00135 # define LED_SET_VALUE(x) do{}while(0)
00136 #elif !defined(LED_SET_VALUE)
00137 # if LEDS_INVERSE == 0
00138 #  define LED_SET_VALUE(x) \
00139             do {\
00140                 LED_PORT = (LED_PORT & ~LED_MASK) | ((x<<LED_SHIFT) & LED_MASK);\
00141             }while(0)
00142 # else
00143 #  define LED_SET_VALUE(x) do {\
00144             LED_PORT = (LED_PORT & ~LED_MASK) | ((~x<<LED_SHIFT) & LED_MASK);\
00145             }while(0)
00146 # endif
00147 #endif /* !defined(LED_SET_VALUE)*/
00148 
00149 #if defined(NO_LEDS) || defined (DOXYGEN)
00150 
00151 # define LED_GET_VALUE() 0
00152 #elif !defined(LED_GET_VALUE)
00153 # if LEDS_INVERSE == 0
00154 #  define LED_GET_VALUE()  ((LED_PORT & LED_MASK) >> LED_SHIFT)
00155 # else
00156 #  define LED_GET_VALUE()  ((~LED_PORT & LED_MASK) >> LED_SHIFT)
00157 # endif
00158 #endif /* !defined(LED_GET_VALUE)*/
00159 
00160 
00161 #if defined(NO_LEDS) || defined (DOXYGEN)
00162 
00163 # define LED_SET(ln) do{}while(0)
00164 #elif !defined(LED_SET)
00165 # if LEDS_INVERSE == 0
00166 #  define LED_SET(ln)      LED_PORT |= (_BV(ln+LED_SHIFT) & LED_MASK)
00167 # else
00168 #  define LED_SET(ln)      LED_PORT &= ~(_BV(ln+LED_SHIFT) & LED_MASK)
00169 # endif
00170 #endif /* !defined(LED_SET)*/
00171 
00172 
00173 #if defined(NO_LEDS) || defined (DOXYGEN)
00174 
00175 # define LED_CLR(ln) do{}while(0)
00176 #elif !defined(LED_CLR)
00177 # if LEDS_INVERSE == 0
00178 #  define LED_CLR(ln)      LED_PORT &= ~(_BV(ln+LED_SHIFT) & LED_MASK)
00179 # else
00180 #  define LED_CLR(ln)      LED_PORT |= (_BV(ln+LED_SHIFT) & LED_MASK)
00181 # endif
00182 #endif /* !defined(LED_CLR)*/
00183 
00184 #if defined(NO_LEDS) || defined (DOXYGEN)
00185 
00186 # define LED_VAL(msk,val) do{}while(0)
00187 #elif !defined(LED_VAL)
00188 # if LEDS_INVERSE == 0
00189 #  define LED_VAL(msk,val) LED_PORT |= ((LED_MASK|msk) << LED_SHIFT); \
00190                            LED_PORT |= ~((val << LED_SHIFT)& (LED_MASK|(msk<<LED_SHIFT)) )
00191 # else
00192 #  define LED_VAL(msk,val) LED_PORT &= ~(LED_MASK|(msk<<LED_SHIFT)); LED_PORT |= ~(val & (LED_MASK|msk))
00193 
00194 # endif
00195 #endif /* !defined(LED_VAL)*/
00196 
00197 #if defined(NO_LEDS) || defined (DOXYGEN)
00198 
00199 # define LED_TOGGLE(ln) do{}while(0)
00200 #elif !defined(LED_TOGGLE)
00201 # define LED_TOGGLE(ln) LED_PORT ^= (_BV(ln+LED_SHIFT) & LED_MASK)
00202 #endif /* !defined(LED_TOGGLE)*/
00203 
00205 #define LED_MAX_VALUE ((1<<LED_NUMBER)-1)
00206 
00210 /* === KEY Handling === */
00211 
00216 #if defined(NO_KEYS) || defined (DOXYGEN)
00217 
00218 # define KEY_INIT()
00219 
00221 # define KEY_GET() (0)
00222 
00223 #else /* defined(NO_KEYS) || defined (DOXYGEN) */
00224 # if PULLUP_KEYS != 0
00225 #  define PULL_MASK (MASK_KEY)
00226 # else /* PULLUP_KEYS != 0 */
00227 #  define PULL_MASK (0)
00228 # endif /* PULLUP_KEYS != 0 */
00229 # if !defined KEY_INIT
00230 #  define KEY_INIT()  do{PORT_KEY |= PULL_MASK; DDR_KEY &= ~(MASK_KEY); }while(0)
00231 # endif 
00232 # if !defined KEY_GET
00233 # if INVERSE_KEYS == 0
00234 #  define KEY_GET()\
00235                 ((PIN_KEY & MASK_KEY) >> SHIFT_KEY)
00236 # else /* INVERSE_KEYS == 0 */
00237 #  define KEY_GET()\
00238                 ((~PIN_KEY & MASK_KEY) >> SHIFT_KEY)
00239 # endif /* INVERSE_KEYS == 0 */
00240 # endif /* !defined KEY_GET */
00241 #endif /* defined(NO_KEYS) || defined (DOXYGEN) */
00242 
00243 
00244 
00249 static inline uint8_t keys_debounced(void)
00250 {
00251   static uint8_t key_state;        // debounced and inverted key state:
00252   static uint8_t ct0, ct1;      // holds two bit counter for each key
00253   uint8_t i;
00254 
00255 
00256   /*
00257    * read current state of keys (active-low),
00258    * clear corresponding bit in i when key has changed
00259    */
00260   i = key_state ^ KEY_GET();   // key changed ?
00261 
00262   /*
00263    * ct0 and ct1 form a two bit counter for each key,
00264    * where ct0 holds LSB and ct1 holds MSB
00265    * After a key is pressed longer than four times the
00266    * sampling period, the corresponding bit in key_state is set
00267    */
00268   ct0 = ~( ct0 & i );            // reset or count ct0
00269   ct1 = (ct0 ^ ct1) & i;        // reset or count ct1
00270   i &= ct0 & ct1;                // count until roll over ?
00271   key_state ^= i;                // then toggle debounced state
00272 
00273   /*
00274    * To notify main program of pressed key, the correspondig bit
00275    * in global variable key_press is set.
00276    * The main loop needs to clear this bit
00277    */
00278   return key_state & i;    // 0->1: key press detect
00279 
00280 }
00281 
00286 static inline void trap_if_key_pressed(void)
00287 {
00288 
00289     KEY_INIT();
00290     DELAY_MS(10);
00291     if (KEY_GET())
00292     {
00293         LED_INIT();
00294         while(1)
00295         {
00296             DELAY_MS(400);
00297             LED_SET(0);
00298             DELAY_MS(10);
00299             LED_CLR(0);
00300         }
00301     }
00302 }
00303 
00306 /* === Bootloader Interface === */
00307 #if BOOT_LOADER_ADDRESS != 0
00308 
00309 #define JUMP_BOOT_LOADER() \
00310     do {\
00311         void (*funcptr)( uint8_t flag ) = BOOT_LOADER_ADDRESS;\
00312         funcptr(42);\
00313     }while(0)
00314 #else /* BOOT_LOADER_ADDRESS != 0 */
00315 #define JUMP_BOOT_LOADER()
00316 #endif /* BOOT_LOADER_ADDRESS != 0 */
00317 
00318 
00319 
00320 
00321 /* === Prototypes ============================================================ */
00322 #ifdef __cplusplus
00323 extern "C" {
00324 #endif
00325 
00329 #if 0
00330 #define BUFFER_SET_USED(b) do{ATOMIC_BLOCK(ATOMIC_FORCEON){b->used|=1}}while(0)
00331 #define BUFFER_SET_UNUSED(b) do{ATOMIC_BLOCK(ATOMIC_FORCEON){b->used&=~1}}while(0)
00332 #define BUFFER_IS_USED(b) ((b->used&1)!=0)
00333 
00334 #define BUFFER_SET_LOCK(b) do{ATOMIC_BLOCK(ATOMIC_FORCEON){b->used|=2}}while(0)
00335 #define BUFFER_SET_UNLOCK(b) do{ATOMIC_BLOCK(ATOMIC_FORCEON){b->used&=~2}}while(0)
00336 #define BUFFER_IS_LOCKED(b) ((b->used&2)!=0)
00337 #endif
00338 
00339 #define BUFFER_SET_USED(b) do{b->used|=1;}while(0)
00340 #define BUFFER_SET_UNUSED(b) do{b->used&=~1;}while(0)
00341 #define BUFFER_IS_USED(b) ((b->used&1)!=0)
00342 
00343 #define BUFFER_SET_LOCK(b) do{b->used|=2;}while(0)
00344 #define BUFFER_SET_UNLOCK(b) do{b->used&=~2;}while(0)
00345 #define BUFFER_IS_LOCKED(b) ((b->used&2)!=0)
00346 
00347 
00348 #define BUFFER_SIZE(b) (b->iend - b->istart)
00349 #define BUFFER_PDATA(b) (b->data + b->istart)
00350 #define BUFFER_SEEK(b,offset) (b->data + (b->iend=offset))
00351 
00352 #define BUFFER_GET_MEMBLOCK(b,pmem,size) \
00353     do{\
00354         b->used = 1;\
00355         pmem = (b->data + b->iend);\
00356         size = (b->len - b->iend);\
00357     }while(0)
00358 
00359 #define BUFFER_UPDATE_MEMBLOCK(b,end) \
00360     do{\
00361         b->iend = end;\
00362         b->used = 0;\
00363     }while(0);
00364 
00365 #define BUFFER_LAST_CHAR(b) \
00366     (b->iend <= b->istart) ? EOF : (char)b->data[b->iend-1]
00367 #define BUFFER_FREE_AT_END(b) (b->len - b->iend)
00368 #define BUFFER_FREE_AT_START(b) (b->istart)
00369 #define BUFFER_ELSZ(x) (sizeof(buffer_t) + (x))
00370 #define BUFFER_RESET(b,start) do{ b->iend = b->istart = start;}while(0)
00371 #define BUFFER_ADVANCE(b,more) do{ b->istart += more;}while(0)
00372 
00374 buffer_t * buffer_init(void * pmem, uint8_t size, uint8_t start);
00376 int buffer_append_char(buffer_t *b, uint8_t c);
00378 int buffer_prepend_char(buffer_t *b, int c);
00380 int buffer_get_char(buffer_t *b);
00382 uint8_t buffer_append_block(buffer_t *b, void *pdata, uint8_t size);
00384 uint8_t buffer_prepend_block(buffer_t *b, void *pdata, uint8_t size);
00386 uint8_t buffer_get_block(buffer_t *b, void *pdata, uint8_t size);
00387 
00388 
00389 buffer_pool_t * buffer_pool_init(uint8_t *pmem, size_t memsz, uint8_t bsz);
00390 buffer_t * buffer_alloc(buffer_pool_t *ppool, uint8_t istart);
00391 void buffer_free(buffer_t * pbuf);
00392 
00393 
00394 
00395 /* buffer stream function */
00396 //typedef void (*incb)(buffer_t *pbuf) buffer_stream_incb_t;
00397 //typedef void (*outcb)(buffer_t *pbuf) buffer_stream_outcb_t;
00398 
00399 typedef struct
00400 {
00401     FILE bstream;
00402     buffer_t *pbufin;
00403     buffer_t *pbufout;
00404     void (*incb)(buffer_t *pbuf);
00405     void (*outcb)(buffer_t *pbuf);
00406 } buffer_stream_t;
00407 
00408 
00409 
00410 int buffer_stream_init( buffer_stream_t *pbs,
00411                         void (*incb)(buffer_t *pbuf),
00412                         void (*outcb)(buffer_t *pbuf));
00413 
00414 int buffer_stream_putchar(char c,FILE *f);
00415 int buffer_stream_getchar(FILE *f);
00416 
00417 
00418 
00420 #ifdef __cplusplus
00421 } /* extern "C" */
00422 #endif
00423 
00424 #endif  /* #ifndef IOUTIL_H */
00425 /* EOF */

This documentation for µracoli was generated on Tue Apr 9 2013 by  doxygen 1.7.1