- Main Page
- Related Pages
- Modules
- Data Structures
- Files

# 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.14 2009/11/04 21:25:01 joerg_wunsch 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
    00071 typedef struct
    00072 {
    00074     void * next;
    00076     uint8_t used;
    00078     uint8_t len;
    00080     uint8_t istart;
    00082     uint8_t iend;
    00084     uint8_t data[];
    00085 } buffer_t;
    00086
    00087
    00088 typedef struct
    00089 {
    00091     uint8_t nb;
    00093     uint8_t elsz;
    00095     uint8_t pool[];
    00096 } buffer_pool_t;
    00097
    00100 /* === Macros ================================================================ */
    00101
    00102 /* === LED Handling === */
    00103
    00107 #if defined(NO_LEDS) || defined (DOXYGEN)
    00108 # undef LED_NUMBER
    00109
    00110 # define LED_NUMBER    (0)
    00111 #endif
    00112
    00113 #if defined(NO_LEDS) || defined (DOXYGEN)
    00114
    00115 # define LED_INIT() do{}while(0)
    00116 #elif !defined(LED_INIT)
    00117 # if LEDS_INVERSE == 0
    00118 #  define LED_INIT() LED_DDR |= (LED_MASK); LED_PORT &= ~(LED_MASK)
    00119 # else
    00120 #   define LED_INIT() LED_DDR |= (LED_MASK); LED_PORT |= (LED_MASK)
    00121 # endif
    00122 #endif /* !defined(LED_INIT)*/
    00123
    00124 #if defined(NO_LEDS) || defined (DOXYGEN)
    00125
    00130 # define LED_SET_VALUE(x) do{}while(0)
    00131 #elif !defined(LED_SET_VALUE)
    00132 # if LEDS_INVERSE == 0
    00133 #  define LED_SET_VALUE(x) \
    00134             do {\
    00135                 LED_PORT = (LED_PORT & ~LED_MASK) | ((x<<LED_SHIFT) & LED_MASK);\
    00136             }while(0)
    00137 # else
    00138 #  define LED_SET_VALUE(x) do {\
    00139             LED_PORT = (LED_PORT & ~LED_MASK) | ((~x<<LED_SHIFT) & LED_MASK);\
    00140             }while(0)
    00141 # endif
    00142 #endif /* !defined(LED_SET_VALUE)*/
    00143
    00144 #if defined(NO_LEDS) || defined (DOXYGEN)
    00145
    00146 # define LED_GET_VALUE() 0
    00147 #elif !defined(LED_GET_VALUE)
    00148 # if LEDS_INVERSE == 0
    00149 #  define LED_GET_VALUE()  ((LED_PORT & LED_MASK) >> LED_SHIFT)
    00150 # else
    00151 #  define LED_GET_VALUE()  ((~LED_PORT & LED_MASK) >> LED_SHIFT)
    00152 # endif
    00153 #endif /* !defined(LED_GET_VALUE)*/
    00154
    00155
    00156 #if defined(NO_LEDS) || defined (DOXYGEN)
    00157
    00158 # define LED_SET(ln) do{}while(0)
    00159 #elif !defined(LED_SET)
    00160 # if LEDS_INVERSE == 0
    00161 #  define LED_SET(ln)      LED_PORT |= (_BV(ln+LED_SHIFT) & LED_MASK)
    00162 # else
    00163 #  define LED_SET(ln)      LED_PORT &= ~(_BV(ln+LED_SHIFT) & LED_MASK)
    00164 # endif
    00165 #endif /* !defined(LED_SET)*/
    00166
    00167
    00168 #if defined(NO_LEDS) || defined (DOXYGEN)
    00169
    00170 # define LED_CLR(ln) do{}while(0)
    00171 #elif !defined(LED_CLR)
    00172 # if LEDS_INVERSE == 0
    00173 #  define LED_CLR(ln)      LED_PORT &= ~(_BV(ln+LED_SHIFT) & LED_MASK)
    00174 # else
    00175 #  define LED_CLR(ln)      LED_PORT |= (_BV(ln+LED_SHIFT) & LED_MASK)
    00176 # endif
    00177 #endif /* !defined(LED_CLR)*/
    00178
    00179 #if defined(NO_LEDS) || defined (DOXYGEN)
    00180
    00181 # define LED_VAL(msk,val) do{}while(0)
    00182 #elif !defined(LED_VAL)
    00183 # if LEDS_INVERSE == 0
    00184 #  define LED_VAL(msk,val) LED_PORT |= ((LED_MASK|msk) << LED_SHIFT); \
    00185                            LED_PORT |= ~((val << LED_SHIFT)& (LED_MASK|(msk<<LED_SHIFT)) )
    00186 # else
    00187 #  define LED_VAL(msk,val) LED_PORT &= ~(LED_MASK|(msk<<LED_SHIFT)); LED_PORT |= ~(val & (LED_MASK|msk))
    00188
    00189 # endif
    00190 #endif /* !defined(LED_VAL)*/
    00191
    00192 #if defined(NO_LEDS) || defined (DOXYGEN)
    00193
    00194 # define LED_TOGGLE(ln) do{}while(0)
    00195 #elif !defined(LED_TOGGLE)
    00196 # define LED_TOGGLE(ln) LED_PORT ^= (_BV(ln+LED_SHIFT) & LED_MASK)
    00197 #endif /* !defined(LED_TOGGLE)*/
    00198
    00200 #define LED_MAX_VALUE ((1<<LED_NUMBER)-1)
    00201
    00205 /* === KEY Handling === */
    00206
    00210 #if defined(NO_KEYS) || defined (DOXYGEN)
    00211
    00212 # define KEY_INIT()
    00213
    00215 # define KEY_GET() (0)
    00216
    00217 #else /* defined(NO_KEYS) || defined (DOXYGEN) */
    00218 # if PULLUP_KEYS != 0
    00219 #  define PULL_MASK (MASK_KEY)
    00220 # else /* PULLUP_KEYS != 0 */
    00221 #  define PULL_MASK (0)
    00222 # endif /* PULLUP_KEYS != 0 */
    00223 # if !defined KEY_INIT
    00224 #  define KEY_INIT()  do{PORT_KEY |= PULL_MASK; DDR_KEY &= ~(MASK_KEY); }while(0)
    00225 # endif
    00226 # if INVERSE_KEYS == 0
    00227 #  define KEY_GET()\
    00228                 ((PIN_KEY & MASK_KEY) >> SHIFT_KEY)
    00229 # else /* INVERSE_KEYS == 0 */
    00230 #  define KEY_GET()\
    00231                 ((~PIN_KEY & MASK_KEY) >> SHIFT_KEY)
    00232 # endif /* INVERSE_KEYS == 0 */
    00233 #endif /* defined(NO_KEYS) || defined (DOXYGEN) */
    00234
    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
    00281 static inline void trap_if_key_pressed(void)
    00282 {
    00283
    00284     KEY_INIT();
    00285     DELAY_MS(10);
    00286     if (KEY_GET())
    00287     {
    00288         LED_INIT();
    00289         while(1)
    00290         {
    00291             DELAY_MS(400);
    00292             LED_SET(0);
    00293             DELAY_MS(10);
    00294             LED_CLR(0);
    00295         }
    00296     }
    00297 }
    00298 /* === Bootloader Interface === */
    00299 #if BOOT_LOADER_ADDRESS != 0
    00300
    00301 #define JUMP_BOOT_LOADER() \
    00302     do {\
    00303         void (*funcptr)( uint8_t flag ) = BOOT_LOADER_ADDRESS;\
    00304         funcptr(42);\
    00305     }while(0)
    00306 #else /* BOOT_LOADER_ADDRESS != 0 */
    00307 #define JUMP_BOOT_LOADER()
    00308 #endif /* BOOT_LOADER_ADDRESS != 0 */
    00309
    00310
    00311
    00312
    00313 /* === Prototypes ============================================================ */
    00314 #ifdef __cplusplus
    00315 extern "C" {
    00316 #endif
    00317
    00321 #if 0
    00322 #define BUFFER_SET_USED(b) do{ATOMIC_BLOCK(ATOMIC_FORCEON){b->used|=1}}while(0)
    00323 #define BUFFER_SET_UNUSED(b) do{ATOMIC_BLOCK(ATOMIC_FORCEON){b->used&=~1}}while(0)
    00324 #define BUFFER_IS_USED(b) ((b->used&1)!=0)
    00325
    00326 #define BUFFER_SET_LOCK(b) do{ATOMIC_BLOCK(ATOMIC_FORCEON){b->used|=2}}while(0)
    00327 #define BUFFER_SET_UNLOCK(b) do{ATOMIC_BLOCK(ATOMIC_FORCEON){b->used&=~2}}while(0)
    00328 #define BUFFER_IS_LOCKED(b) ((b->used&2)!=0)
    00329 #endif
    00330
    00331 #define BUFFER_SET_USED(b) do{b->used|=1;}while(0)
    00332 #define BUFFER_SET_UNUSED(b) do{b->used&=~1;}while(0)
    00333 #define BUFFER_IS_USED(b) ((b->used&1)!=0)
    00334
    00335 #define BUFFER_SET_LOCK(b) do{b->used|=2;}while(0)
    00336 #define BUFFER_SET_UNLOCK(b) do{b->used&=~2;}while(0)
    00337 #define BUFFER_IS_LOCKED(b) ((b->used&2)!=0)
    00338
    00339
    00340 #define BUFFER_SIZE(b) (b->iend - b->istart)
    00341 #define BUFFER_PDATA(b) (b->data + b->istart)
    00342 #define BUFFER_SEEK(b,offset) (b->data + (b->iend=offset))
    00343
    00344 #define BUFFER_GET_MEMBLOCK(b,pmem,size) \
    00345     do{\
    00346         b->used = 1;\
    00347         pmem = (b->data + b->iend);\
    00348         size = (b->len - b->iend);\
    00349     }while(0)
    00350
    00351 #define BUFFER_UPDATE_MEMBLOCK(b,end) \
    00352     do{\
    00353         b->iend = end;\
    00354         b->used = 0;\
    00355     }while(0);
    00356
    00357 #define BUFFER_LAST_CHAR(b) \
    00358     (b->iend <= b->istart) ? EOF : (char)b->data[b->iend-1]
    00359 #define BUFFER_FREE_AT_END(b) (b->len - b->iend)
    00360 #define BUFFER_FREE_AT_START(b) (b->istart)
    00361 #define BUFFER_ELSZ(x) (sizeof(buffer_t) + (x))
    00362 #define BUFFER_RESET(b,start) do{ b->iend = b->istart = start;}while(0)
    00363 #define BUFFER_ADVANCE(b,more) do{ b->istart += more;}while(0)
    00364
    00366 buffer_t * buffer_init(void * pmem, uint8_t size, uint8_t start);
    00368 int buffer_append_char(buffer_t *b, uint8_t c);
    00370 int buffer_prepend_char(buffer_t *b, int c);
    00372 int buffer_get_char(buffer_t *b);
    00374 uint8_t buffer_append_block(buffer_t *b, void *pdata, uint8_t size);
    00376 uint8_t buffer_prepend_block(buffer_t *b, void *pdata, uint8_t size);
    00378 uint8_t buffer_get_block(buffer_t *b, void *pdata, uint8_t size);
    00379
    00380
    00381 buffer_pool_t * buffer_pool_init(uint8_t *pmem, size_t memsz, uint8_t bsz);
    00382 buffer_t * buffer_alloc(buffer_pool_t *ppool, uint8_t istart);
    00383 void buffer_free(buffer_t * pbuf);
    00384
    00385
    00386
    00387 /* buffer stream function */
    00388 //typedef void (*incb)(buffer_t *pbuf) buffer_stream_incb_t;
    00389 //typedef void (*outcb)(buffer_t *pbuf) buffer_stream_outcb_t;
    00390
    00391 typedef struct
    00392 {
    00393     FILE bstream;
    00394     buffer_t *pbufin;
    00395     buffer_t *pbufout;
    00396     void (*incb)(buffer_t *pbuf);
    00397     void (*outcb)(buffer_t *pbuf);
    00398 } buffer_stream_t;
    00399
    00400
    00401
    00402 int buffer_stream_init( buffer_stream_t *pbs,
    00403                         void (*incb)(buffer_t *pbuf),
    00404                         void (*outcb)(buffer_t *pbuf));
    00405
    00406 int buffer_stream_putchar(char c,FILE *f);
    00407 int buffer_stream_getchar(FILE *f);
    00408
    00409
    00410
    00412 #ifdef __cplusplus
    00413 } /* extern "C" */
    00414 #endif
    00415
    00416 #endif  /* #ifndef IOUTIL_H */
    00417 /* EOF */