// meindef.h // meine Defs allgemein // Vers von 14.02.2025 #ifndef _MEINDEF_H_ #define _MEINDEF_H_ #include // typedefs typedef uint8_t u8; typedef int8_t s8; typedef uint16_t u16; typedef int16_t s16; typedef uint32_t u32; typedef int32_t s32; typedef uint64_t u64; typedef int64_t s64; typedef __uint24 u24; typedef __int24 s24; // unions, die Arbeit mit Bytes und Bits innerhalb des Wortes erleichtern typedef struct{ u8 bit0:1; u8 bit1:1; u8 bit2:1; u8 bit3:1; u8 bit4:1; u8 bit5:1; u8 bit6:1; u8 bit7:1; } bitfeld8; typedef struct{ u8 bit0:1; u8 bit1:1; u8 bit2:1; u8 bit3:1; u8 bit4:1; u8 bit5:1; u8 bit6:1; u8 bit7:1; u8 bit8:1; u8 bit9:1; u8 bit10:1; u8 bit11:1; u8 bit12:1; u8 bit13:1; u8 bit14:1; u8 bit15:1; } bitfeld16; typedef struct{ u8 bit0:1; u8 bit1:1; u8 bit2:1; u8 bit3:1; u8 bit4:1; u8 bit5:1; u8 bit6:1; u8 bit7:1; u8 bit8:1; u8 bit9:1; u8 bit10:1; u8 bit11:1; u8 bit12:1; u8 bit13:1; u8 bit14:1; u8 bit15:1; u8 bit16:1; u8 bit17:1; u8 bit18:1; u8 bit19:1; u8 bit20:1; u8 bit21:1; u8 bit22:1; u8 bit23:1; } bitfeld24; typedef struct{ u8 bit0:1; u8 bit1:1; u8 bit2:1; u8 bit3:1; u8 bit4:1; u8 bit5:1; u8 bit6:1; u8 bit7:1; u8 bit8:1; u8 bit9:1; u8 bit10:1; u8 bit11:1; u8 bit12:1; u8 bit13:1; u8 bit14:1; u8 bit15:1; u8 bit16:1; u8 bit17:1; u8 bit18:1; u8 bit19:1; u8 bit20:1; u8 bit21:1; u8 bit22:1; u8 bit23:1; u8 bit24:1; u8 bit25:1; u8 bit26:1; u8 bit27:1; u8 bit28:1; u8 bit29:1; u8 bit30:1; u8 bit31:1; } bitfeld32; typedef struct{ u8 bit0:1; u8 bit1:1; u8 bit2:1; u8 bit3:1; u8 bit4:1; u8 bit5:1; u8 bit6:1; u8 bit7:1; u8 bit8:1; u8 bit9:1; u8 bit10:1; u8 bit11:1; u8 bit12:1; u8 bit13:1; u8 bit14:1; u8 bit15:1; u8 bit16:1; u8 bit17:1; u8 bit18:1; u8 bit19:1; u8 bit20:1; u8 bit21:1; u8 bit22:1; u8 bit23:1; u8 bit24:1; u8 bit25:1; u8 bit26:1; u8 bit27:1; u8 bit28:1; u8 bit29:1; u8 bit30:1; u8 bit31:1; u8 bit32:1; u8 bit33:1; u8 bit34:1; u8 bit35:1; u8 bit36:1; u8 bit37:1; u8 bit38:1; u8 bit39:1; u8 bit40:1; u8 bit41:1; u8 bit42:1; u8 bit43:1; u8 bit44:1; u8 bit45:1; u8 bit46:1; u8 bit47:1; u8 bit48:1; u8 bit49:1; u8 bit50:1; u8 bit51:1; u8 bit52:1; u8 bit53:1; u8 bit54:1; u8 bit55:1; u8 bit56:1; u8 bit57:1; u8 bit58:1; u8 bit59:1; u8 bit60:1; u8 bit61:1; u8 bit62:1; u8 bit63:1; } bitfeld64; typedef union{ u8 b; // b as BYTE bitfeld8 btf; // btf als Bitfeld } union8; typedef union{ u16 h ; // h as HALF-WORD u8 b[2]; // b as BYTE bitfeld8 btf[2]; // btf als Bitfeld bitfeld16 btfh; } union16; typedef union{ u24 t ; // t as Drei u16 h ; // h as HALF-WORD u8 b[3]; // b as BYTE bitfeld8 btf[3]; // btf als Bitfeld bitfeld16 btfh; } union24; typedef union{ u32 w ; // w as WORD u16 h[2]; // h as HALF-WORD u8 b[4]; // b as BYTE bitfeld8 btf[4]; // btf als Bitfeld bitfeld16 btfh[2]; bitfeld32 btfw; } union32; typedef union{ u32 w ; // w as WORD u24 t[2]; // t as Drei u16 h[3]; // h as HALF-WORD u8 b[6]; // b as BYTE bitfeld8 btf[6]; // btf als Bitfeld bitfeld16 btfh[3]; bitfeld32 btfw; } union48; typedef union{ u64 d ; // d as DOUBLE-WORD u32 w[2]; // w as WORD u16 h[4]; // h as HALF-WORD u8 b[8]; // b as BYTE bitfeld8 btf[8]; // btf als Bitfeld bitfeld16 btfh[4]; bitfeld32 btfw[2]; bitfeld64 btfd; } union64; typedef union{ u64 d[2]; // d as DOUBLE-WORD u32 w[4]; // w as WORD u16 h[8]; // h as HALF-WORD u8 b[16]; // b as BYTE bitfeld8 btf[16]; // btf als Bitfeld bitfeld16 btfh[8]; bitfeld32 btfw[4]; bitfeld64 btfd[2]; } union128; typedef union{ u64 d[4]; // d as DOUBLE-WORD u32 w[8]; // w as WORD u16 h[16]; // h as HALF-WORD u8 b[32]; // b as BYTE bitfeld8 btf[32]; // btf als Bitfeld bitfeld16 btfh[16]; bitfeld32 btfw[8]; bitfeld64 btfd[4]; } union256; // Beispiel: // union8 temp; // union32 temp1; // temp.b = 0; // temp1.w = 0; // temp.b = ~spi_master_transmit(0); // if(temp.btf.bit6 == 1) temp1.btf[3].bit5 = 1; // return temp1.w; // Für 16 bit Farbe (so wie ILI9341) typedef struct{ u8 farbeB:5; // Farbe blau, bit 4:0 u8 farbeG:6; // Farbe grün, bit 10:5 u8 farbeR:5; // Farbe rot, bit 15:11 } bitfarbe565; typedef union{ u16 h ; // Farbe 16bit bitfarbe565 frb; // Farbe einzeln } farbe16; // aus Arduino.h, Name korrigiert, BYTE2(w) - BYTE7(w) von mir änlich // langsam! #define BYTE0(w) ((uint8_t) ((w) & 0xff)) #define BYTE1(w) ((uint8_t) ((w) >> 8UL)) #define BYTE2(w) ((uint8_t) ((w) >> 16UL)) #define BYTE3(w) ((uint8_t) ((w) >> 24UL)) #define BYTE4(w) ((uint8_t) ((w) >> 32UL)) #define BYTE5(w) ((uint8_t) ((w) >> 40UL)) #define BYTE6(w) ((uint8_t) ((w) >> 48UL)) #define BYTE7(w) ((uint8_t) ((w) >> 56UL)) // bitmacros #define Bit(bit) (1UL << (bit)) #define ClearBit(reg, bit) reg &= (~(1<<(bit))) //Beispiel: ClearBit(PORTB, 1); // bit 1 PORTB löschen #define SetBit(reg, bit) reg |= (1<<(bit)) //Beispiel: SetBit(PORTB, 3); // bit 3 PORTB setzen #define SetBitVal(reg, bit, val) do{if ((val&1)==0) reg &= (~(1<<(bit)));\ else reg |= (1<<(bit));}while(0) //Beispiel: SetBitVal(PORTB, 3, 1); // bit 3 PORTB setzen //Beispiel SetBitVal(PORTB, 2, 0); // bit 2 PORTB löschen #define BitIsClear(reg, bit) ((reg & (1<<(bit))) == 0) //Beispiel: if (BitIsClear(PORTB,1)) {...} //wenn bit gelöscht #define BitIsSet(reg, bit) ((reg & (1<<(bit))) != 0) //Beispiel: if(BitIsSet(PORTB,2)) {...} //wenn bit gesetzt #define InvBit(reg, bit) reg ^= (1<<(bit)) //Beispiel: InvBit(PORTB, 1); // bit 1 PORTB invertieren /* Macro */ // rotieren #define ROL(x) ((x << 1UL) | (x >> 7UL)) #define ROR(x) ((x >> 1UL) | (x << 7UL)) #define ROL16(x) ((x << 1UL) | (x >> 15UL)) #define ROR16(x) ((x >> 1UL) | (x << 15UL)) #define ROL24(x) ((x << 1UL) | (x >> 23UL)) #define ROR24(x) ((x >> 1UL) | (x << 23UL)) #define ROL32(x) ((x << 1UL) | (x >> 31UL)) #define ROR32(x) ((x >> 1UL) | (x << 31UL)) #define ROL64(x) ((x << 1UL) | (x >> 63UL)) #define ROR64(x) ((x >> 1UL) | (x << 63UL)) /* Beispiel: count_dat = ROL(count_dat); */ // Constants #define PI 3.1415926535897932384626433832795 #define HALF_PI 1.5707963267948966192313216916398 #define TWO_PI 6.283185307179586476925286766559 #define DEG_TO_RAD 0.017453292519943295769236907684886 #define RAD_TO_DEG 57.295779513082320876798154814105 #define EULER 2.718281828459045235360287471352 // maximum value that can be held // by unsigned data types (8,16,32bits) #define MAX_U8 255 #define MAX_U16 65535 #define MAX_U24 16777215 #define MAX_U32 4294967295 #define MAX_U64 18446744073709551615 // maximum values that can be held // by signed data types (8,16,32bits) #define MAX_S8 INT8_MAX //127 #define MIN_S8 INT8_MIN //-128 #define MAX_S16 INT16_MAX //32767 #define MIN_S16 INT16_MIN //-32768 #define MAX_S24 0x7fffff // 8388607 #define MIN_S24 (-MAX_S24 - 1) //-8388608 #define MAX_S32 INT32_MAX //2147483647 #define MIN_S32 INT32_MIN //-2147483648 #define MAX_S64 INT64_MAX //9223372036854775807 #define MIN_S64 INT64_MIN //-9223372036854775808 // min(a, b): Nimm das Maximum zwischen a und b // max(a, b): Nimm das Minimum zwischen a und b // Align_up(val, n): Um (bis) die Zahl (val) an der (n)-Grenze // Align_down(val, n): Um (nach unten) die Zahl (val) an der (n)-Grenze #define min(a,b) ((ab)?(a):(b)) // undefine stdlib's abs if encountered #ifdef abs #undef abs #endif #define abs(x) ((x>0)?(x):(-x)) #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) #define rnd(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) #define radians(deg) ((deg)*DEG_TO_RAD) #define degrees(rad) ((rad)*RAD_TO_DEG) #define sq(x) ((x)*(x)) #define Align_up(val, n) (((val)+(n)-1) & ~((n)-1)) #define Align_down(val, n) ((val) & ~((n)-1)) // Zähler mit max-Modul #define ROLLOVER( x, max ) x = ++x >= max ? 0 : x // Beispiel: ROLLOVER( tx_out, TX0_SIZE ); x = (0...(max-1)) #define ROLLUNDER( x, max ) x = x-- == 0 ? (max-1) : x // Beispiel: ROLLUNDER( tx_out, TX0_SIZE ); x = ((max-1)...0) // aus: ATmega32_ExploreUltraAvrDevKit-master // Makros für die Konvertierung von Dec2Ascii, Hec2Ascii und Acsii2Hex #define DEC2ASCII(Dec) ((Dec)+0x30) #define ASCII2DEC(Asc) ((Asc)-0x30) #define HEX2ASCII(Hex) (((Hex)>0x09) ? ((Hex) + 0x37): ((Hex) + 0x30)) #define ASCII2HEX(Asc) (((Asc)>0x39) ? ((Asc) - 0x37): ((Asc) - 0x30)) // Makros zum Finden des Mods einer Zahl #define GETMOD8(dividend,divisor) (u8) ((dividend) - ((divisor) * (u8) ((dividend)/(divisor)))) #define GETMOD16(dividend,divisor) (u16)((dividend) - ((divisor) * (u16)((dividend)/(divisor)))) #define GETMOD24(dividend,divisor) (u24)((dividend) - ((divisor) * (u24)((dividend)/(divisor)))) #define GETMOD32(dividend,divisor) (u32)((dividend) - ((divisor) * (u32)((dividend)/(divisor)))) #define GETMOD64(dividend,divisor) (u64)((dividend) - ((divisor) * (u64)((dividend)/(divisor)))) // selbst zugefügt #define GETRND8(dividend,divisor) (u8)((divisor) * (u8) ((dividend)/(divisor))) #define GETRND16(dividend,divisor) (u16)((divisor) * (u16) ((dividend)/(divisor))) #define GETRND24(dividend,divisor) (u24)((divisor) * (u24) ((dividend)/(divisor))) #define GETRND32(dividend,divisor) (u32)((divisor) * (u32) ((dividend)/(divisor))) #define GETRND64(dividend,divisor) (u64)((divisor) * (u64) ((dividend)/(divisor))) // Makros zum Extrahieren der Nibbles #define EXTRACTNIBBLE_0TO3(x) (uint8_t) ((x) & 0x0Fu) #define EXTRACTNIBBLE_4TO7(x) (uint8_t) (((x)>>4) & 0x0Fu) #define EXTRACTNIBBLE_8TO11(x) (uint8_t) (((x)>>8) & 0x0Fu) #define EXTRACTNIBBLE_12TO15(x) (uint8_t) (((x)>>12) & 0x0Fu) // Makros zum Extrahieren des Bytes #define EXTRACTBYTE_0TO7(x) (uint8_t) ((x) & 0xFFu) #define EXTRACTBYTE_8TO15(x) (uint8_t) (((x)>>8) & 0xFFu) #define EXTRACTBYTE_16TO23(x) (uint8_t) (((x)>>16) & 0xFFu) #define EXTRACTBYTE_24TO31(x) (uint8_t) (((x)>>24) & 0xFFu) // Andere Makros #define USWAP(x,y) (x ^= y ^= x ^= y) //////////// // always inline function x: #define AIL(x) static x __attribute__ ((always_inline)); static x // never inline function x: #define NIL(x) x __attribute__ ((noinline)); x // volatile access (reject unwanted removing access // = Unerwünschten Löschzugriff ablehnen): #define vu8(x) (*(volatile u8*)&(x)) #define vs8(x) (*(volatile s8*)&(x)) #define vu16(x) (*(volatile u16*)&(x)) #define vs16(x) (*(volatile s16*)&(x)) #define vu32(x) (*(volatile u32*)&(x)) #define vs32(x) (*(volatile s32*)&(x)) #define vu64(x) (*(volatile u64*)&(x)) #define vs64(x) (*(volatile s64*)&(x)) #define vu24(x) (*(volatile u24*)&(x)) #define vs24(x) (*(volatile s24*)&(x)) // Swap-Inline-Funktionen static __inline__ u8 swap(u8 x) __attribute__((__always_inline__)); /* Beispiel: PORTA = swap(PORTA); */ static __inline__ void swapb(volatile u8 *x, volatile u8 *y) __attribute__((__always_inline__)); /* Beispiel: swapb(&PORTC, &PORTA); */ static __inline__ void swaph (volatile u16 *x, volatile u16 *y) __attribute__((__always_inline__)); /* Beispiel: swaph(&a, &b); */ static __inline__ void swapt (volatile u24 *x, volatile u24 *y) __attribute__((__always_inline__)); /* Beispiel: swapt(&a, &b); */ static __inline__ void swapw (volatile u32 *x, volatile u32 *y) __attribute__((__always_inline__)); /* Beispiel: swapw(&a, &b); */ static __inline__ void swapd (volatile u64 *x, volatile u64 *y) __attribute__((__always_inline__)); /* Beispiel: swapd(&a, &b); */ static __inline__ void swapsb(volatile s8 *x, volatile s8 *y) __attribute__((__always_inline__)); /* Beispiel: swapsb(&PORTC, &PORTA); */ static __inline__ void swapsh (volatile s16 *x, volatile s16 *y) __attribute__((__always_inline__)); /* Beispiel: swapsh(&a, &b); */ static __inline__ void swapst (volatile s24 *x, volatile s24 *y) __attribute__((__always_inline__)); /* Beispiel: swapst(&a, &b); */ static __inline__ void swapsw (volatile s32 *x, volatile s32 *y) __attribute__((__always_inline__)); /* Beispiel: swapsw(&a, &b); */ static __inline__ void swapsd (volatile s64 *x, volatile s64 *y) __attribute__((__always_inline__)); /* Beispiel: swapsd(&a, &b); */ u8 swap (u8 x){ asm ("swap %0" : "+r" (x)); return x; } /* Beispiel: PORTA = swap(PORTA); */ void swapb (volatile u8 *x, volatile u8 *y){ u8 temp; temp = *y; *y = *x; *x = temp; } /* Beispiel: swapb(&PORTC, &PORTA); */ void swaph (volatile u16 *x, volatile u16 *y){ // H as HALF-WORD u16 temp; temp = *y; *y = *x; *x = temp; } /* Beispiel: swaph(&a, &b); */ void swapt (volatile u24 *x, volatile u24 *y){ // T as 3b-WORD u24 temp; temp = *y; *y = *x; *x = temp; } /* Beispiel: swapt(&a, &b); */ void swapw (volatile u32 *x, volatile u32 *y){ // W as WORD u32 temp; temp = *y; *y = *x; *x = temp; } /* Beispiel: swapw(&a, &b); */ void swapd (volatile u64 *x, volatile u64 *y){ // D as DOUBLE-WORD u64 temp; temp = *y; *y = *x; *x = temp; } /* Beispiel: swapd(&a, &b); */ void swapsb (volatile s8 *x, volatile s8 *y){ s8 temp; temp = *y; *y = *x; *x = temp; } /* Beispiel: swapsb(&PORTC, &PORTA); */ void swapsh (volatile s16 *x, volatile s16 *y){ // H as HALF-WORD s16 temp; temp = *y; *y = *x; *x = temp; } /* Beispiel: swapsh(&a, &b); */ void swapst (volatile s24 *x, volatile s24 *y){ // T as 3b-WORD s24 temp; temp = *y; *y = *x; *x = temp; } /* Beispiel: swapst(&a, &b); */ void swapsw (volatile s32 *x, volatile s32 *y){ // W as WORD s32 temp; temp = *y; *y = *x; *x = temp; } /* Beispiel: swapsw(&a, &b); */ void swapsd (volatile s64 *x, volatile s64 *y){ // D as DOUBLE-WORD s64 temp; temp = *y; *y = *x; *x = temp; } /* Beispiel: swapsd(&a, &b); */ // Verzögerungen // avr-libc defines _NOP() since 1.6.2 **avr-libc definiert _NOP() seit 1.6.2 // aus Arduino.h #define _NOP() do { __asm__ volatile ("nop"); } while (0) #define _NOP2() \ do { asm volatile( \ "rjmp .+0" "\n" \ ::); } while (0) #define _NOP3() \ do { asm volatile( \ "rjmp .+0" "\n\t" \ "nop" "\n" \ ::); } while (0) #define _NOP4() \ do { asm volatile( \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n" \ ::); } while (0) #define _NOP5() \ do { asm volatile( \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n\t" \ "nop" "\n" \ ::); } while (0) #define _NOP6() \ do { asm volatile( \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n" \ ::); } while (0) #define _NOP7() \ do { asm volatile( \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n\t" \ "nop" "\n" \ ::); } while (0) #define _NOP8() \ do { asm volatile( \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n" \ ::); } while (0) #define _NOP9() \ do { asm volatile( \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n\t" \ "nop" "\n" \ ::); } while (0) #define _NOP10() \ do { asm volatile( \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n" \ ::); } while (0) #define _NOP12() \ do { asm volatile( \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n" \ "rjmp .+0" "\n" \ ::); } while (0) #define _NOP14() \ do { asm volatile( \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n\t" \ "rjmp .+0" "\n" \ "rjmp .+0" "\n" \ "rjmp .+0" "\n" \ ::); } while (0) static __inline__ void delayloop8(u8 count) __attribute__((__always_inline__)); /* Die Schleife dauert 3 * count + 3 Ticks, bei F_CPU=16 MHz (255*3+3)/16000000 = 48us */ static __inline__ void delayloop16(u16 count) __attribute__((__always_inline__)); /* Die Schleife dauert 4 * count + 4 Ticks, bei F_CPU=16 MHz (65535*4+4)/16000000 = 16,384 ms */ static __inline__ void delayloop24(u24 count) __attribute__((__always_inline__)); /* Die Schleife dauert 5 * count + 6 Ticks, bei F_CPU=16 MHz (16777215*5+6)/16000000 = 5,2428800625 s */ void delayloop8 (u8 count) { /* Die Schleife dauert 3 * count + 3 Ticks, bei F_CPU=16 MHz (255*3+3)/16000000 = 48us */ asm volatile ("1:" "\n\t" "subi %A0,1" "\n\t" "brcc 1b" : "+d" (count)); } void delayloop16 (u16 count) { /* Die Schleife dauert 4 * count + 4 Ticks */ /* bei F_CPU=16 MHz (65535*4+4)/16000000 = 16,384 ms */ asm volatile ("1:" "\n\t" "sbiw %0,1" "\n\t" "brcc 1b" : "+w" (count)); } void delayloop24 (u24 count) { /* Die Schleife dauert 5 * count + 6 Ticks */ /* bei F_CPU=16 MHz (16777215*5+6)/16000000 = 5,2428800625 s */ asm volatile ("1:" "\n\t" "subi %A0,1" "\n\t" "sbci %B0,0" "\n\t" "sbci %C0,0" "\n\t" "brcc 1b" : "+d" (count)); } #endif /* _MEINDEF_H_ */