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$ */
    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 */