avr-libc-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-libc-dev] mint8 fixups, crc16_hdlc, timer macros


From: Tomas Vanek
Subject: [avr-libc-dev] mint8 fixups, crc16_hdlc, timer macros
Date: Mon, 20 Oct 2003 11:31:03 +0200
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.2a) Gecko/20020910

Hi all,
I searched all avr-libc headers for keywords int, short, signed and unsigned and looked for -mint8 incompatibilities. Headers avr/crc16.h and avr/delay.h should be obviously switched to inttypes.h types. Other headers seem to be just a case Joerg mailed about: API versus ABI incompatibility.

crc16.h:
I also included a new inline function _crc16_hdlc() for polynomial used in PPP and IrDA protocols. I recommend changing name of _crc16_update() function to something what describes protocol a polynomial is used for.

delay.h:
I would write macros _DELAY_CLKS(cyc), _DELAY_USEC(usec) and _DELAY_MSEC(msec), based on F_OSC. If it still is on TODO list, let me know.

timer.h:
inttypes.h should be used here, however I have not fixed it. Usability of that header seems to be rather low. Only TMR0 served and the functions timer0_start/stop probably should use TCCR0 instead TCNT0?! Also I do not see any reason to alias timer0_source(CK) as timer0_start(). The argument of timer0_source() sould be uint8_t.

Well, there are my macros for computing prescaler setup, use them if they suit. They are rather complicated, but as far as I know they are universal for all timers in all AVR mcus except high speed TMR1 of ATtiny26.

Tom
/*
   Macro _PRESCALE_TO_CK(tmr, rate)
   Returns value of CS bits to set in TCCR/TCCRB register of tmr timer to setup 
prescale ratio rate
      or _PRESCALE_RATE_ERROR if requested prescaler rate is not available.
   Parameter tmr, timer number is pasted as text - it have to be one digit or 
macro expanding to one digit.
   Parameter rate, requested prescaler ratio can be constant or variable 
expression.
 */

extern uint8_t _CONST_PRESCALE_RATE_ERROR; /* intentionally undefined variable 
*/
/* Used in folowing macros to show an error when requested constant prescaler 
rate is not available */
#define _PRESCALE_RATE_ERROR -1
/* Check result of macro for _PRESCALE_RATE_ERROR when variable rate is entered 
*/

#define _PRESCALE_TO_CK_NORMAL_TIMER(tmr, rate) ( \
    ((rate) == 1)    ? (                  0 |                   0 | _BV(CS ## 
tmr ## 0)) \
  : ((rate) == 8)    ? (                  0 | _BV(CS ## tmr ## 1) |             
      0) \
  : ((rate) == 64)   ? (                  0 | _BV(CS ## tmr ## 1) | _BV(CS ## 
tmr ## 0)) \
  : ((rate) == 256)  ? (_BV(CS ## tmr ## 2) |                   0 |             
      0) \
  : ((rate) == 1024) ? (_BV(CS ## tmr ## 2) |                   0 | _BV(CS ## 
tmr ## 0)) \
  : __builtin_constant_p(rate) ? _CONST_PRESCALE_RATE_ERROR : 
_PRESCALE_RATE_ERROR )

#define _PRESCALE_TO_CK_ASYNC_TIMER(tmr, rate) ( \
    ((rate) == 1)    ? (                  0 |                   0 | _BV(CS ## 
tmr ## 0)) \
  : ((rate) == 8)    ? (                  0 | _BV(CS ## tmr ## 1) |             
      0) \
  : ((rate) == 32)   ? (                  0 | _BV(CS ## tmr ## 1) | _BV(CS ## 
tmr ## 0)) \
  : ((rate) == 64)   ? (_BV(CS ## tmr ## 2) |                   0 |             
      0) \
  : ((rate) == 128)  ? (_BV(CS ## tmr ## 2) |                   0 | _BV(CS ## 
tmr ## 0)) \
  : ((rate) == 256)  ? (_BV(CS ## tmr ## 2) | _BV(CS ## tmr ## 1) |             
      0) \
  : ((rate) == 1024) ? (_BV(CS ## tmr ## 2) | _BV(CS ## tmr ## 1) | _BV(CS ## 
tmr ## 0)) \
  : __builtin_constant_p(rate) ? _CONST_PRESCALE_RATE_ERROR : 
_PRESCALE_RATE_ERROR )

#ifdef AS0
#define _PRESCALE_TO_CK(tmr, rate) ( \
  (tmr == 0)  \
    ? _PRESCALE_TO_CK_ASYNC_TIMER(tmr, rate)  \
    : _PRESCALE_TO_CK_NORMAL_TIMER(tmr, rate))
#elif defined(AS2)
#define _PRESCALE_TO_CK(tmr, rate) ( \
  (tmr == 2)  \
    ? _PRESCALE_TO_CK_ASYNC_TIMER(tmr, rate)  \
    : _PRESCALE_TO_CK_NORMAL_TIMER(tmr, rate))
#else
#define _PRESCALE_TO_CK(tmr, rate) _PRESCALE_TO_CK_NORMAL_TIMER(tmr, rate)
#endif
diff -urN /c/TEMP/avr-libc-1.0/include/avr/crc16.h 
avr-libc-1.0/include/avr/crc16.h
--- /c/TEMP/avr-libc-1.0/include/avr/crc16.h    2002-12-12 11:41:02.000000000 
+0100
+++ avr-libc-1.0/include/avr/crc16.h    2003-10-20 11:21:49.000000000 +0200
@@ -27,7 +27,14 @@
 
 /*
    avr/crc16.h - optimized CRC-16
+ */
+
+#ifndef _AVR_CRC16_H_
+#define _AVR_CRC16_H_
 
+#include <inttypes.h>
+
+/*
    Polynomial: x^16 + x^15 + x^2 + 1 (0xa001)
    Initial value: 0xffff
 
@@ -35,14 +42,11 @@
    and general CRC optimization suggestions.
  */
 
-#ifndef _AVR_CRC16_H_
-#define _AVR_CRC16_H_
-
-static inline unsigned int
-_crc16_update(unsigned int __crc, unsigned char __data)
+static inline uint16_t
+_crc16_update(uint16_t __crc, uint8_t __data)
 {
-       unsigned char __tmp;
-       unsigned int __ret;
+       uint8_t __tmp;
+       uint16_t __ret;
 
        __asm__ (
                "eor %A0,%2" "\n\t"
@@ -75,4 +79,55 @@
        return __ret;
 }
 
+/*
+   HLDC Polynomial: x^16 + x^12 + x^5 + 1 (0x8408)
+
+   See RFC1171 (PPP protocol) and IrDA IrLAP 1.1
+ */
+
+#define HDLC_FCS_INIT                  0xFFFF
+#define HDLC_FCS_GOOD                  0xF0B8
+
+static inline uint16_t
+_crc16_hdlc(uint16_t __fcs, uint8_t __data)
+{
+       uint16_t __ret;
+
+/*
+  data^= lo8(fcs);
+  data^= data << 4;
+  return (((uint16_t)data << 8) | hi8(fcs)) ^ (uint8_t)(data >> 4) ^ 
((uint16_t)data << 3);
+*/
+       __asm__ (
+               "eor %A0,%1" "\n\t"
+
+               "mov __tmp_reg__,%A0" "\n\t"
+               "swap %A0" "\n\t"
+               "andi %A0,0xf0" "\n\t"
+               "eor %A0,__tmp_reg__" "\n\t"
+
+               "mov __tmp_reg__,%B0" "\n\t"
+
+               "mov %B0,%A0" "\n\t"
+
+               "swap %A0" "\n\t"
+               "andi %A0,0x0f" "\n\t"
+               "eor __tmp_reg__,%A0" "\n\t"
+
+               "lsr %A0" "\n\t"
+               "eor %B0,%A0" "\n\t"
+
+               "eor %A0,%B0" "\n\t"
+               "lsl %A0" "\n\t"
+               "lsl %A0" "\n\t"
+               "lsl %A0" "\n\t"
+               "eor %A0,__tmp_reg__"
+
+               : "=d" (__ret)
+               : "r" (__data), "0" (__fcs)
+               : "r0"
+       );
+       return __ret;
+}
+
 #endif /* _AVR_CRC16_H_ */
diff -urN /c/TEMP/avr-libc-1.0/include/avr/delay.h 
avr-libc-1.0/include/avr/delay.h
--- /c/TEMP/avr-libc-1.0/include/avr/delay.h    2002-12-12 11:41:02.000000000 
+0100
+++ avr-libc-1.0/include/avr/delay.h    2003-10-14 01:48:40.000000000 +0200
@@ -32,9 +32,11 @@
 #ifndef _AVR_DELAY_H_
 #define _AVR_DELAY_H_ 1
 
+#include <inttypes.h>
+
 /* 8-bit count, 3 cycles/loop */
 static inline void
-_delay_loop_1(unsigned char __count)
+_delay_loop_1(uint8_t __count)
 {
        asm volatile (
                "1: dec %0" "\n\t"
@@ -46,7 +48,7 @@
 
 /* 16-bit count, 4 cycles/loop */
 static inline void
-_delay_loop_2(unsigned int __count)
+_delay_loop_2(uint16_t __count)
 {
        asm volatile (
                "1: sbiw %0,1" "\n\t"


reply via email to

[Prev in Thread] Current Thread [Next in Thread]