Skip to content

Commit

Permalink
Add AVRFIX
Browse files Browse the repository at this point in the history
  • Loading branch information
tilaktilak committed Apr 23, 2017
1 parent e690d9b commit 81bbbe5
Show file tree
Hide file tree
Showing 2 changed files with 297 additions and 0 deletions.
297 changes: 297 additions & 0 deletions avrfix.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
/****************************************************************
* *
* __ ____ _________ *
* /_ \\\ \/ /| \______ *
* // \\\ /|| D /_ /. *
* // \\\_ /.|| \ ___/. *
* /___/\___\\__/. |__|\__\__.___ ___ *
* .... ....... ...|| _/_\ \////. *
* || |.| |\ ///. *
* |__|.|_|/// \ *
* .... ./__/\__\ *
* ........ *
* Fixed Point Library *
* according to *
* ISO/IEC DTR 18037 *
* *
* Version 1.0.1 *
* Maximilan Rosenblattl, Andreas Wolf 2007-02-07 *
****************************************************************/

#ifndef _AVRFIX_H
#define _AVRFIX_H

#ifndef TEST_ON_PC
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/pgmspace.h>
#endif

/* Only two datatypes are used from the ISO/IEC standard:
* short _Accum with s7.8 bit format
* _Accum with s15.16 bit format
* long _Accum with s7.24 bit format
*/

typedef signed short _sAccum;
typedef signed long _Accum;
typedef signed long _lAccum;

/* Pragmas for defining overflow behaviour */

#define DEFAULT 0
#define SAT 1

#ifndef FX_ACCUM_OVERFLOW
#define FX_ACCUM_OVERFLOW DEFAULT
#endif

/* Pragmas for internal use */

#define SACCUM_IBIT 7
#define SACCUM_FBIT 8
#define ACCUM_IBIT 15
#define ACCUM_FBIT 16
#define LACCUM_IBIT 7
#define LACCUM_FBIT 24

#define SACCUM_MIN -32767
#define SACCUM_MAX 32767
#define ACCUM_MIN -2147483647L
#define ACCUM_MAX 2147483647L
#define LACCUM_MIN -2147483647L
#define LACCUM_MAX 2147483647L

#define SACCUM_FACTOR ((short)1 << SACCUM_FBIT)
#define ACCUM_FACTOR ((long)1 << ACCUM_FBIT)
#define LACCUM_FACTOR ((long)1 << LACCUM_FBIT)

/* Mathematical constants */

#define PIsk 804
#define PIk 205887
#define PIlk 52707179

#define LOG2k 45426
#define LOG2lk 11629080

#define LOG10k 150902
#define LOG10lk 38630967

#ifndef NULL
#define NULL ((void*)0)
#endif

/* conversion Functions */

#define itosk(i) ((_sAccum)(i) << SACCUM_FBIT)
#define itok(i) ((_Accum)(i) << ACCUM_FBIT)
#define itolk(i) ((_lAccum)(i) << LACCUM_FBIT)

#define sktoi(k) ((int8_t)((k) >> SACCUM_FBIT))
#define ktoi(k) ((signed short)((k) >> ACCUM_FBIT))
#define lktoi(k) ((int8_t)((k) >> LACCUM_FBIT))

#define sktok(sk) ( (_Accum)(sk) << (ACCUM_FBIT-SACCUM_FBIT))
#define ktosk(k) ((_sAccum)((k) >> (ACCUM_FBIT-SACCUM_FBIT)))

#define sktolk(sk) ((_lAccum)(sk) << (LACCUM_FBIT-SACCUM_FBIT))
#define lktosk(lk) ((_sAccum)((lk) >> (LACCUM_FBIT-SACCUM_FBIT)))

#define ktolk(k) ((_Accum)(k) << (LACCUM_FBIT-ACCUM_FBIT))
#define lktok(lk) ((_lAccum)(lk) >> (LACCUM_FBIT-ACCUM_FBIT))

#define ftosk(f) ((_Accum)(f) * (1 << SACCUM_FBIT))
#define ftok(f) ((_Accum)(f) * (1 << ACCUM_FBIT))
#define ftolk(f) ((_lAccum)(f) * (1 << LACCUM_FBIT))

#define sktof(sk) ((float)((_sAccum)(sk) / (1 << SACCUM_FBIT)))
#define ktod(k) ((double)((_sAccum)(k) / (1 << SACCUM_FBIT)))
#define lktod(lk) ((double)((_sAccum)(lk) / (1 << SACCUM_FBIT)))

/* Main Functions */

extern _sAccum smulskD(_sAccum, _sAccum);
extern _Accum mulkD(_Accum, _Accum);
extern _lAccum lmullkD(_lAccum, _lAccum);

extern _sAccum sdivskD(_sAccum, _sAccum);
extern _Accum divkD(_Accum, _Accum);
extern _lAccum ldivlkD(_lAccum, _lAccum);

extern _sAccum smulskS(_sAccum, _sAccum);
extern _Accum mulkS(_Accum, _Accum);
extern _lAccum lmullkS(_lAccum, _lAccum);

extern _sAccum sdivskS(_sAccum, _sAccum);
extern _Accum divkS(_Accum, _Accum);
extern _lAccum ldivlkS(_lAccum, _lAccum);

#if FX_ACCUM_OVERFLOW == DEFAULT
#define smulsk(a,b) smulskD((a),(b))
#define mulk(a,b) mulkD((a),(b))
#define lmullk(a,b) lmullkD((a), (b))
#define sdivsk(a,b) sdivskD((a), (b))
#define divk(a,b) divkD((a), (b))
#define ldivlk(a,b) ldivlkD((a), (b))
#elif FX_ACCUM_OVERFLOW == SAT
#define smulsk(a,b) smulskS((a),(b))
#define mulk(a,b) mulkS((a),(b))
#define lmullk(a,b) lmullkS((a), (b))
#define sdivsk(a,b) sdivskS((a), (b))
#define divk(a,b) divkS((a), (b))
#define ldivlk(a,b) ldivlkS((a), (b))
#endif

/* Support Functions */

#define mulikD(i,k) ktoi((i) * (k))
#define mulilkD(i,lk) lktoi((i) * (lk))

#define divikD(i,k) ktoi(divkD(itok(i),(k)))
#define divilkD(i,lk) lktoi(ldivlkD(itolk(i),(lk)))

#define kdiviD(a,b) divkD(itok(a),itok(b))
#define lkdiviD(a,b) ldivlkD(itolk(a),itolk(b))

#define idivkD(a,b) ktoi(divkD((a),(b)))
#define idivlkD(a,b) lktoi(ldivlkD((a),(b)))

#define mulikS(i,k) ktoi(mulkS(itok(i),(k)))
#define mulilkS(i,lk) lktoi(lmullkS(itolk(i),(lk)))

#define divikS(i,k) ktoi(divkS(itok(i),(k)))
#define divilkS(i,lk) lktoi(ldivlkS(itolk(i),(lk)))

#define kdiviS(a,b) divkS(itok(a),itok(b))
#define lkdiviS(a,b) ldivlkS(itolk(a),itolk(b))

#define idivkS(a,b) ktoi(divkS((a),(b)))
#define idivlkS(a,b) lktoi(ldivlkS((a),(b)))

#if FX_ACCUM_OVERFLOW == DEFAULT
#define mulik(a,b) mulikD((a),(b))
#define mulilk(a,b) mulilkD((a),(b))
#define divik(a,b) divikD((a),(b))
#define divilk(a,b) divilkD((a),(b))
#define kdivi(a,b) kdiviD((a),(b))
#define lkdivi(a,b) lkdiviD((a),(b))
#define idivk(a,b) idivkD((a),(b))
#define idivlk(a,b) idivlkD((a),(b))
#elif FX_ACCUM_OVERFLOW == SAT
#define mulik(a,b) mulikS((a),(b))
#define mulilk(a,b) mulilkS((a),(b))
#define divik(a,b) divikS((a),(b))
#define divilk(a,b) divilkS((a),(b))
#define kdivi(a,b) kdiviS((a),(b))
#define lkdivi(a,b) lkdiviS((a),(b))
#define idivk(a,b) idivkS((a),(b))
#define idivlk(a,b) idivlkS((a),(b))
#endif

/* Abs Functions */

#define sabssk(f) ((f) < 0 ? (-(f)) : (f))
#define absk(f) ((f) < 0 ? (-(f)) : (f))
#define labslk(f) ((f) < 0 ? (-(f)) : (f))

/* Rounding Functions */

extern _sAccum roundskD(_sAccum f, uint8_t n);
extern _Accum roundkD(_Accum f, uint8_t n);
extern _lAccum roundlkD(_lAccum f, uint8_t n);

extern _sAccum roundskS(_sAccum f, uint8_t n);
extern _Accum roundkS(_Accum f, uint8_t n);
extern _lAccum roundlkS(_lAccum f, uint8_t n);

#if FX_ACCUM_OVERFLOW == DEFAULT
#define roundsk(f, n) roundskD((f), (n))
#define roundk(f, n) roundkD((f), (n))
#define roundlk(f, n) roundlkD((f), (n))
#elif FX_ACCUM_OVERFLOW == SAT
#define roundsk(f, n) roundskS((f), (n))
#define roundk(f, n) roundkS((f), (n))
#define roundlk(f, n) roundlkS((f), (n))
#endif

/* countls Functions */

extern uint8_t countlssk(_sAccum f);
extern uint8_t countlsk(_Accum f);
#define countlslk(f) countlsk((f))

/* Special Functions */

#define CORDICC_GAIN 10188012
#define CORDICH_GAIN 20258445

extern _Accum sqrtk_uncorrected(_Accum,int8_t,uint8_t);

#define sqrtkD(a) mulkD(sqrtk_uncorrected(a, -8, 17), CORDICH_GAIN/256)
#define lsqrtlkD(a) lmullkD(sqrtk_uncorrected(a, 0, 24), CORDICH_GAIN)

#define sqrtkS(a) mulkS(sqrtk_uncorrected(a, -8, 17), CORDICH_GAIN/256)
#define lsqrtlkS(a) lmullkS(sqrtk_uncorrected(a, 0, 24), CORDICH_GAIN)

#if FX_ACCUM_OVERFLOW == DEFAULT
#define sqrtk(a) sqrtkD(a)
#define lsqrtlk(a) lsqrtlkD(a)
#else
#define sqrtk(a) sqrtkS(a)
#define lsqrtlk(a) lsqrtlkS(a)
#endif

extern _Accum sincosk(_Accum, _Accum*);
extern _lAccum lsincoslk(_lAccum, _lAccum*);
extern _lAccum lsincosk(_Accum, _lAccum*);
extern _sAccum ssincossk(_sAccum, _sAccum*);

#define sink(a) sincosk((a), NULL)
#define lsinlk(a) lsincoslk((a), NULL)
#define lsink(a) lsincosk((a), NULL)
#define ssinsk(a) ssincossk((a), NULL)

#define cosk(a) sink((a) + PIk/2 + 1)
#define lcoslk(a) lsinlk((a) + PIlk/2)
#define lcosk(a) lsink((a) + PIk/2 + 1)
#define scossk(a) ssinsk((a) + PIsk/2)

extern _Accum tankD(_Accum);
extern _lAccum ltanlkD(_lAccum);
extern _lAccum ltankD(_Accum);

extern _Accum tankS(_Accum);
extern _lAccum ltanlkS(_lAccum);
extern _lAccum ltankS(_Accum);

#if FX_ACCUM_OVERFLOW == DEFAULT
#define tank(a) tankD((a))
#define ltanlk(a) ltanlkD((a))
#define ltank(a) ltankD((a))
#elif FX_ACCUM_OVERFLOW == SAT
#define tank(a) tankS((a))
#define ltanlk(a) ltanlkS((a))
#define ltank(a) ltankS((a))
#endif

extern _Accum atan2k(_Accum, _Accum);
extern _lAccum latan2lk(_lAccum, _lAccum);

#define atank(a) atan2k(itok(1), (a))
#define latanlk(a) latan2lk(itolk(1), (a))

extern _Accum logk(_Accum);
extern _lAccum lloglk(_lAccum);

#define log2k(x) (divk(logk((x)), LOG2k))
#define log10k(x) (divk(logk((x)), LOG10k))
#define logak(a, x) (divk(logk((x)), logk((a))))

#define llog2lk(x) (ldivlk(lloglk((x)), LOG2lk))
#define llog10lk(x) (ldivlk(lloglk((x)), LOG10lk))
#define llogalk(a, x) (ldivlk(lloglk((x)), lloglk((a))))

#endif /* _AVRFIX_H */

Binary file added libavrfix.a
Binary file not shown.

0 comments on commit 81bbbe5

Please sign in to comment.