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
Lesezeichen