Thxle nochmal für die Hinweise.
Das mit dem Code hab ich gerade mal ausprobiert.
Also Versuch 1: Bitfelder nur so gross, wie benötigt; Versuch 2: Bitfelder aufgerundet auf ganze Bytes/Word.
Die Codegrösse beim 2. Versuch ist um 1092 Bytes kleiner als beim ersten.

Hab den bisherigen Joystick-Teil auch mal hier als Code mit angehängt; ist für nen Microsoft Sidewinder Force Feedback Pro; evtl kanns ja jemand brauchen um nen Roboter anzusteuern.
Was später noch kommt, ist auch ne Rückmeldung per Force Feedback. Elektrisch kein Problem; lediglich ein Steuerprotokoll fehlt mir noch.

mit JS_SWFFP_Init() einfach 1x initialisieren; JS_SWFFP_GetData() fragt den Joystick ab und befördert die ausgewerteten Daten in die Struct js_ffb.

joystick.c:
Code:
#include "joystick.h"

void JS_SWFFP_GetData(void)
{
  js_rectripindex = 0;              // Reset triples index
  JS_SWFFP_Trigger();               // Trigger joystick measurement
  while(js_rectripindex < 17);      // Wait until data has been received

  js_ffb.buttons = 0;               // Reset variables
  js_ffb.axis0 = 0;
  js_ffb.axis1 = 0;
  js_ffb.axis2 = 0;
  js_ffb.axis3 = 0;
  js_ffb.hat = 0;

  js_ffb.buttons |= ((~js_rectriplets[0] & 0x0E) >> 1);      // mask out buttons
  js_ffb.buttons |= ((~js_rectriplets[1] & 0x0E) << 2);
  js_ffb.buttons |= ((~js_rectriplets[2] & 0x0E) << 5);
  
  js_ffb.axis0 |= ((js_rectriplets[3] & 0x0E) >> 1);         // mask out axis 0 (X)
  js_ffb.axis0 |= ((js_rectriplets[4] & 0x0E) << 2);
  js_ffb.axis0 |= ((js_rectriplets[5] & 0x0E) << 5);
  js_ffb.axis0 |= ((js_rectriplets[6] & 0x02) << 8);
  
  js_ffb.axis1 |= ((js_rectriplets[6] & 0x0C) >> 2);         // mask out axis 1 (Y)
  js_ffb.axis1 |= ((js_rectriplets[7] & 0x0E) << 1);
  js_ffb.axis1 |= ((js_rectriplets[8] & 0x0E) << 4);
  js_ffb.axis1 |= ((js_rectriplets[9] & 0x06) << 7);
  
  js_ffb.axis2 |= ((js_rectriplets[9] & 0x08) >> 3);         // mask out axis 2 (Throttle)
  js_ffb.axis2 |= ((js_rectriplets[10] & 0x0E) >> 0);
  js_ffb.axis2 |= ((js_rectriplets[11] & 0x0E) << 3);
  js_ffb.axis2 = 127 - js_ffb.axis2;                         // invert axis 2 (Throttle)
  
  js_ffb.axis3 |= ((js_rectriplets[12] & 0x0E) >> 1);        // mask out axis 3 (Rudder)
  js_ffb.axis3 |= ((js_rectriplets[13] & 0x0E) << 2);
  
  js_ffb.hat |= ((js_rectriplets[14] & 0x0E) >> 1);          // mask out hat
  js_ffb.hat |= ((js_rectriplets[15] & 0x02) << 2);
}

void JS_SWFFP_Init(void)
{
  EIMSK |=  (1 << INT3);                     // Enable INT3 (Pin D.3)
  EICRA |= ((1 << ISC31) | (1 << ISC30));    // Trigger: Rising edge
  js_rectripindex = 0;
}

void JS_SWFFP_DeInit(void)
{
  EIMSK &= ~(1 << INT3);                     // Disable INT3 (Pin D.3)
  EICRA &= ~((1 << ISC31) | (1 << ISC30));   // Trigger: Disabled
  js_rectripindex = 0;
}


void JS_SWFFP_Trigger(void)
{
  // Trigger measurement by generating a short pulse
  JS_PORT_TRIGGER |= (1 << JS_PIN_TRIGGER);
  _delay_us(50);
  JS_PORT_TRIGGER &= ~(1 << JS_PIN_TRIGGER);
}


SIGNAL (SIG_INTERRUPT3)
{
  // Get triplets
  js_rectriplets[js_rectripindex] = (PINA & 0x0E);
  js_rectripindex++;
}
joystick.h:
Code:
#ifndef _JOYSTICK_H_
#define _JOYSTICK_H_

#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include <util/delay.h>
#include "glob_type.h"

/* Ports & Pins, where the data input lines are connected */
#define JS_PORT_BIT1  PINA
#define JS_PORT_BIT2  PINA
#define JS_PORT_BIT3  PINA
#define JS_PIN_BIT1   1     // Button 1
#define JS_PIN_BIT2   2     // Button 2
#define JS_PIN_BIT3   3     // Button 3

/* Measurement trigger output */
#define JS_PORT_TRIGGER PORTA
#define JS_PIN_TRIGGER  4

/* MIDI Tx; Not used yet; for implementing Force Feedback functionalities later via UART*/
#define JS_PORT_FFB PORTA
#define JS_PIN_FFB  5

volatile ui8_t js_rectriplets[16];    // Array for triplet reception
volatile ui8_t js_rectripindex;       // Triplet array index

void JS_SWFFP_GetData(void);
void JS_SWFFP_Trigger(void);
void JS_SWFFP_DeInit(void);
void JS_SWFFP_Init(void);


/*
  Microsoft Sidewinder Force Feedback Pro
  Triplets: 16 (= Total 48 bits)
	[00 - 08]: Buttons            ( 9 bits)
	[09 - 18]: Axis 0 (X)         (10 bits)
	[19 - 28]: Axis 1 (Y)         (10 bits)
	[29 - 35]: Axis 2 (Throttle)  ( 7 bits)
	[36 - 41]: Axis 3 (Rudder)    ( 6 bits)
	[42 - 45]: Hat			          ( 4 bits)
	     [46]: Always 1           (ignored)
	     [47]: Parity             (ignored)
*/


/* 
  No bit 'cutting' used in this struct; using a whole byte/word instead of needed number of bits
  saves about 1k flash memory.
*/
typedef struct {
  ui16_t  buttons;
  ui16_t  axis0;     
  ui16_t  axis1;
  ui8_t   axis2;
  ui8_t   axis3;
  ui8_t   hat;
} stc_js_swffp;


/*

typedef struct {
  union {
    elemente typ : bit;
  };
} stc_name;

*/


volatile stc_js_swffp js_ffb;

#endif
glob_types.h
Code:
#ifndef _GLOB_TYPE_H_
#define _GLOB_TYPE_H_

/* This header file contains global types */

// Standard 
typedef signed char           i8_t;
typedef unsigned char        ui8_t;
typedef short                i16_t;
typedef unsigned short      ui16_t;
typedef long                 i32_t;
typedef unsigned long       ui32_t;
typedef long long            i64_t;
typedef unsigned long long  ui64_t;

// Precise time
typedef struct{
  ui8_t hour;
  ui8_t min;
  ui8_t sec;
  ui8_t msec;
} stc_timeprec;

// Standard time
typedef struct{
  ui8_t hour;
  ui8_t min;
  ui8_t sec;
} stc_timestd;

// Standard date
typedef struct{
  ui16_t year;
  ui8_t  month;
  ui8_t  day;
} stc_date;

// Timestamp
typedef struct{
  stc_date      date;
  stc_timeprec  time;
} stc_timestamp;

// Item for Menu State Machine
typedef struct{
  ui16_t s_current;
  ui16_t s_keyfunc;
  ui16_t s_next;
} stc_menuitem;


#endif