Преглед изворни кода

usb_flightsim changes for XPlaneRefs with names >58 chars

main
Jorg Bliesener пре 9 година
родитељ
комит
32d841e418
4 измењених фајлова са 260 додато и 19 уклоњено
  1. +139
    -3
      teensy3/usb_flightsim.cpp
  2. +23
    -2
      teensy3/usb_flightsim.h
  3. +74
    -11
      usb_flightsim/usb_api.cpp
  4. +24
    -3
      usb_flightsim/usb_api.h

+ 139
- 3
teensy3/usb_flightsim.cpp Прегледај датотеку

*/ */


#include "usb_dev.h" #include "usb_dev.h"
#include "usb_desc.h"
#include "usb_flightsim.h" #include "usb_flightsim.h"
#include "core_pins.h" // for yield(), millis() #include "core_pins.h" // for yield(), millis()
#include <string.h> // for memcpy() #include <string.h> // for memcpy()
next = NULL; next = NULL;
value = 0; value = 0;
change_callback = NULL; change_callback = NULL;
callbackInfo = NULL;
hasCallbackInfo = false;
FlightSimClass::request_id_messages = 1; FlightSimClass::request_id_messages = 1;
} }


void FlightSimInteger::update(long val) void FlightSimInteger::update(long val)
{ {
value = val; value = val;
if (change_callback) (*change_callback)(val);
if (change_callback) {
if (!hasCallbackInfo) {
(*change_callback)(val);
} else {
(*(void(*)(long,void*))change_callback)(val,callbackInfo);
}
}
} }


FlightSimInteger * FlightSimInteger::find(unsigned int n) FlightSimInteger * FlightSimInteger::find(unsigned int n)
next = NULL; next = NULL;
value = 0; value = 0;
change_callback = NULL; change_callback = NULL;
hasCallbackInfo = false;
callbackInfo = NULL;
FlightSimClass::request_id_messages = 1; FlightSimClass::request_id_messages = 1;
} }


void FlightSimFloat::update(float val) void FlightSimFloat::update(float val)
{ {
value = val; value = val;
if (change_callback) (*change_callback)(val);
if (change_callback) { // add: JB
if (!hasCallbackInfo) {
(*change_callback)(val);
} else {
(*(void(*)(long,void*))change_callback)(val,callbackInfo);
}
}
} }


FlightSimFloat * FlightSimFloat::find(unsigned int n) FlightSimFloat * FlightSimFloat::find(unsigned int n)
switch (p[2]) { switch (p[2]) {
case 1: case 1:
request_id_messages = 1; request_id_messages = 1;
/* no break */
case 2: case 2:
enable(); enable();
frameCount++; frameCount++;
uint8_t total; uint8_t total;


total = n1 + n2; total = n1 + n2;
if (total > FLIGHTSIM_TX_SIZE) return;
if (total > FLIGHTSIM_TX_SIZE) {
xmit_big_packet(p1, n1, p2, n2);
return;
}
if (!enabled || !usb_configuration) return; if (!enabled || !usb_configuration) return;
tx_noautoflush = 1; tx_noautoflush = 1;
if (tx_packet) { if (tx_packet) {
tx_noautoflush = 0; tx_noautoflush = 0;
} }


void FlightSimClass::xmit_big_packet(const void *p1, uint16_t n1, const void *p2, uint16_t n2)
{
if (!enabled || !usb_configuration) return;
bool part2 = false;
uint16_t remainingPart1 = n1;
uint16_t remaining;
const void *dataPtr = p1;
bool needAdditionalFragment = false;
uint8_t fragmentCounter = 1;

tx_noautoflush =1; // don't mess with my data, I'm working on it!

if (tx_packet) {
// If we have a current packet, fill it with whatever fits
uint8_t partLen = FLIGHTSIM_TX_SIZE - tx_packet->index;
if (partLen > n1) partLen=n1;
// copy first part
memcpy(tx_packet->buf + tx_packet->index, dataPtr, partLen);
remainingPart1 -= partLen;
tx_packet->index += partLen;
if (remainingPart1) {
remaining = remainingPart1+n2;
dataPtr += partLen;
} else {
// maybe we have space for more
part2=true;
partLen = FLIGHTSIM_TX_SIZE - tx_packet->index;
remaining = n2;
if (partLen) {
memcpy(tx_packet->buf + tx_packet->index, p2, partLen);
remaining -= partLen;
tx_packet->index += partLen;
dataPtr = p2 + partLen;
}
}
// Packet padding should not be necessary, as xmit_big_packet
// will only be called for data that doesn't fit in a single
// packet. So, the previous code should always fill up the
// first packet. Right?
for (int i = tx_packet->index; i < FLIGHTSIM_TX_SIZE; i++) {
tx_packet->buf[i] = 0;
}
tx_packet->len = FLIGHTSIM_TX_SIZE;
usb_tx(FLIGHTSIM_TX_ENDPOINT, tx_packet);
tx_packet = NULL;
needAdditionalFragment = true;
} else {
remaining = n1+n2;
}
while (remaining >0) {
while (1) {
if (usb_tx_packet_count(FLIGHTSIM_TX_ENDPOINT) < TX_PACKET_LIMIT) {
tx_packet = usb_malloc();
if (tx_packet) break;
}
if (!enabled || !usb_configuration) {
tx_noautoflush = 0;
return;
}
tx_noautoflush = 0; // you can pick up my data, if you like
yield();
tx_noautoflush = 1; // wait, I'm working on the packet data
}

if (needAdditionalFragment) {
// fragment header
tx_packet->buf[0]=(remaining+3 <= FLIGHTSIM_TX_SIZE) ? (byte) remaining+3 : FLIGHTSIM_TX_SIZE;
tx_packet->buf[1]=0xff;
tx_packet->buf[2]=fragmentCounter++;
tx_packet->index=3;
}
if (!part2) {
// we still need to send the first part
uint8_t partLen = FLIGHTSIM_TX_SIZE - tx_packet->index;
if (partLen > remainingPart1)
partLen=remainingPart1;
memcpy(tx_packet->buf + tx_packet->index, dataPtr, partLen);
dataPtr += partLen;
remainingPart1 -= partLen;
tx_packet->index += partLen;
remaining -= partLen;
if (!remainingPart1) {
part2=true;
dataPtr = p2;
}
}

if (part2) {
uint8_t partLen = FLIGHTSIM_TX_SIZE - tx_packet->index;
if (partLen) {
if (partLen > remaining)
partLen=remaining;
memcpy(tx_packet->buf + tx_packet->index, dataPtr, partLen);
remaining -= partLen;
tx_packet->index += partLen;
dataPtr += partLen;
}
}
needAdditionalFragment = true;
if (tx_packet->index >= FLIGHTSIM_TX_SIZE) {
tx_packet->len = FLIGHTSIM_TX_SIZE;
usb_tx(FLIGHTSIM_TX_ENDPOINT, tx_packet);
tx_packet = NULL;
}
}
tx_noautoflush = 0; // data is ready to be transmitted on start of USB token
}


extern "C" { extern "C" {
// This gets called when a USB start token arrives.
// If we have a packet to transmit AND transmission isn't disabled
// by tx_noautoflush, we fill it up with zeros and send it out
// to USB
void usb_flightsim_flush_callback(void) void usb_flightsim_flush_callback(void)
{ {
if (tx_noautoflush || !tx_packet || tx_packet->index == 0) return; if (tx_noautoflush || !tx_packet || tx_packet->index == 0) return;

+ 23
- 2
teensy3/usb_flightsim.h Прегледај датотеку

static void enable(void) { enabled = 1; enableTimeout = 0; } static void enable(void) { enabled = 1; enableTimeout = 0; }
static void disable(void) { enabled = 0; } static void disable(void) { enabled = 0; }
static void xmit(const void *p1, uint8_t n1, const void *p2, uint8_t n2); static void xmit(const void *p1, uint8_t n1, const void *p2, uint8_t n2);
static void xmit_big_packet(const void *p1, uint16_t n1, const void *p2, uint16_t n2);
friend class FlightSimCommand; friend class FlightSimCommand;
friend class FlightSimInteger; friend class FlightSimInteger;
friend class FlightSimFloat; friend class FlightSimFloat;
void identify(void); void identify(void);
void update(long val); void update(long val);
static FlightSimInteger * find(unsigned int n); static FlightSimInteger * find(unsigned int n);
void onChange(void (*fptr)(long)) { change_callback = fptr; }
void onChange(void (*fptr)(long)) {
hasCallbackInfo=false;
change_callback = fptr;
}
void onChange(void (*fptr)(long,void*), void* info) {
hasCallbackInfo=true;
change_callback = (void (*)(long))fptr;
callbackInfo = info;
}
// TODO: math operators.... + - * / % ++ -- // TODO: math operators.... + - * / % ++ --
private: private:
unsigned int id; unsigned int id;
const _XpRefStr_ *name; const _XpRefStr_ *name;
long value; long value;
void (*change_callback)(long); void (*change_callback)(long);
void* callbackInfo;
bool hasCallbackInfo;
FlightSimInteger *next; FlightSimInteger *next;
static FlightSimInteger *first; static FlightSimInteger *first;
static FlightSimInteger *last; static FlightSimInteger *last;
void identify(void); void identify(void);
void update(float val); void update(float val);
static FlightSimFloat * find(unsigned int n); static FlightSimFloat * find(unsigned int n);
void onChange(void (*fptr)(float)) { change_callback = fptr; }
void onChange(void (*fptr)(float)) {
hasCallbackInfo=false;
change_callback = fptr;
}
void onChange(void (*fptr)(float,void*), void* info) {
hasCallbackInfo=true;
change_callback = (void (*)(float))fptr;
callbackInfo = info;
}
// TODO: math operators.... + - * / % ++ -- // TODO: math operators.... + - * / % ++ --
private: private:
unsigned int id; unsigned int id;
const _XpRefStr_ *name; const _XpRefStr_ *name;
float value; float value;
void (*change_callback)(float); void (*change_callback)(float);
void* callbackInfo;
bool hasCallbackInfo;
FlightSimFloat *next; FlightSimFloat *next;
static FlightSimFloat *first; static FlightSimFloat *first;
static FlightSimFloat *last; static FlightSimFloat *last;

+ 74
- 11
usb_flightsim/usb_api.cpp Прегледај датотеку



void FlightSimCommand::identify(void) void FlightSimCommand::identify(void)
{ {
uint8_t len, buf[6];
uint16_t len;
uint8_t buf[6];


if (!FlightSim.enabled || !name) return; if (!FlightSim.enabled || !name) return;
len = strlen_P((const char *)name); len = strlen_P((const char *)name);


void FlightSimInteger::identify(void) void FlightSimInteger::identify(void)
{ {
uint8_t len, buf[6];
uint16_t len;
uint8_t buf[6];


if (!FlightSim.enabled || !name) return; if (!FlightSim.enabled || !name) return;
len = strlen_P((const char *)name); len = strlen_P((const char *)name);
void FlightSimInteger::update(long val) void FlightSimInteger::update(long val)
{ {
value = val; value = val;
if (change_callback) (*change_callback)(val);
if (change_callback) {
if (!hasCallbackInfo) {
(*change_callback)(val);
} else {
(*(void(*)(long,void*))change_callback)(val,callbackInfo);
}
}
} }


FlightSimInteger * FlightSimInteger::find(unsigned int n) FlightSimInteger * FlightSimInteger::find(unsigned int n)


void FlightSimFloat::identify(void) void FlightSimFloat::identify(void)
{ {
uint8_t len, buf[6];
uint16_t len;
uint8_t buf[6];


if (!FlightSim.enabled || !name) return; if (!FlightSim.enabled || !name) return;
len = strlen_P((const char *)name); len = strlen_P((const char *)name);
void FlightSimFloat::update(float val) void FlightSimFloat::update(float val)
{ {
value = val; value = val;
if (change_callback) (*change_callback)(val);
if (change_callback) {
if (!hasCallbackInfo) {
(*change_callback)(val);
} else {
(*(void(*)(long,void*))change_callback)(val,callbackInfo);
}
}
} }


FlightSimFloat * FlightSimFloat::find(unsigned int n) FlightSimFloat * FlightSimFloat::find(unsigned int n)
{ {
uint8_t intr_state, avail; uint8_t intr_state, avail;


if (n1 > FLIGHTSIM_TX_SIZE) return;
if (!enabled || !usb_configuration) return; if (!enabled || !usb_configuration) return;
intr_state = SREG; intr_state = SREG;
cli(); cli();
uint8_t intr_state, total, avail; uint8_t intr_state, total, avail;


total = n1 + n2; total = n1 + n2;
if (total > FLIGHTSIM_TX_SIZE) return;
if (!enabled || !usb_configuration) return; if (!enabled || !usb_configuration) return;
intr_state = SREG; intr_state = SREG;
cli(); cli();
} }




void FlightSimClass::xmit(const uint8_t *p1, uint8_t n1, const _XpRefStr_ *p2, uint8_t n2)
{
void FlightSimClass::xmit(const uint8_t *p1, uint8_t n1, const _XpRefStr_ *p2, uint16_t n2) {
uint8_t intr_state, total, avail; uint8_t intr_state, total, avail;
const char *s2 = (const char *)p2;
const char * PROGMEM s2 = (const char *)p2;


total = n1 + n2; total = n1 + n2;
if (total > FLIGHTSIM_TX_SIZE) return;
if (total > FLIGHTSIM_TX_SIZE) {
xmit_big_packet(p1, n1, p2, n2);
return;
}
if (!enabled || !usb_configuration) return; if (!enabled || !usb_configuration) return;
intr_state = SREG; intr_state = SREG;
cli(); cli();
SREG = intr_state; SREG = intr_state;
} }


void FlightSimClass::xmit_big_packet(const uint8_t *p1, uint8_t n1, const _XpRefStr_ *p2, uint16_t n2) {
uint8_t intr_state, avail;
uint16_t total;

bool part1 = true;
const char * PROGMEM s2 = (const char *)p2;
uint8_t packet_id = 1;

total = n1 + n2;

if (!enabled || !usb_configuration) return;
intr_state = SREG;
cli();
UENUM = FLIGHTSIM_TX_ENDPOINT;
avail = FLIGHTSIM_TX_SIZE - UEBCLX;

while (total>0) {
if (part1) {
UEDATX = *p1++;
part1 = (--n1 != 0);
} else {
pgm_read_byte_postinc(UEDATX, s2);
n2--;
}
total--;

if (!--avail) {
// transmit packet
UEINTX = 0x3A;
while (1) {
if (UEINTX & (1<<RWAL)) break;
SREG = intr_state;
if (!enabled || !usb_configuration) return;
intr_state = SREG;
cli();
UENUM = FLIGHTSIM_TX_ENDPOINT;
}

// start new fragment with length and fragment ID
UEDATX = (total<(FLIGHTSIM_TX_SIZE-3) ? total+3 : FLIGHTSIM_TX_SIZE); // length byte
UEDATX = 0xff;
UEDATX = packet_id++;
avail = FLIGHTSIM_TX_SIZE - 3;
}
}
if (UEBCLX == FLIGHTSIM_TX_SIZE) UEINTX = 0x3A;
SREG = intr_state;
}




FlightSimClass FlightSim; FlightSimClass FlightSim;

+ 24
- 3
usb_flightsim/usb_api.h Прегледај датотеку

static uint8_t recv(uint8_t *buffer); static uint8_t recv(uint8_t *buffer);
static void xmit(const uint8_t *p1, uint8_t n1); static void xmit(const uint8_t *p1, uint8_t n1);
static void xmit(const uint8_t *p1, uint8_t n1, const uint8_t *p2, uint8_t n2); static void xmit(const uint8_t *p1, uint8_t n1, const uint8_t *p2, uint8_t n2);
static void xmit(const uint8_t *p1, uint8_t n1, const _XpRefStr_ *p2, uint8_t n2);
static void xmit(const uint8_t *p1, uint8_t n1, const _XpRefStr_ *p2, uint16_t n2);
static void xmit_big_packet(const uint8_t *p1, uint8_t n1, const _XpRefStr_ *p2, uint16_t n2);
friend class FlightSimCommand; friend class FlightSimCommand;
friend class FlightSimInteger; friend class FlightSimInteger;
friend class FlightSimFloat; friend class FlightSimFloat;
void identify(void); void identify(void);
void update(long val); void update(long val);
static FlightSimInteger * find(unsigned int n); static FlightSimInteger * find(unsigned int n);
void onChange(void (*fptr)(long)) { change_callback = fptr; }
void onChange(void (*fptr)(long)) {
hasCallbackInfo=false;
change_callback = fptr;
}
void onChange(void (*fptr)(long,void*), void* info) {
hasCallbackInfo=true;
change_callback = (void (*)(long))fptr;
callbackInfo = info;
}
// TODO: math operators.... + - * / % ++ -- // TODO: math operators.... + - * / % ++ --
private: private:
unsigned int id; unsigned int id;
const _XpRefStr_ *name; const _XpRefStr_ *name;
long value; long value;
void (*change_callback)(long); void (*change_callback)(long);
void* callbackInfo;
bool hasCallbackInfo;
FlightSimInteger *next; FlightSimInteger *next;
static FlightSimInteger *first; static FlightSimInteger *first;
static FlightSimInteger *last; static FlightSimInteger *last;
void identify(void); void identify(void);
void update(float val); void update(float val);
static FlightSimFloat * find(unsigned int n); static FlightSimFloat * find(unsigned int n);
void onChange(void (*fptr)(float)) { change_callback = fptr; }
void onChange(void (*fptr)(float)) {
hasCallbackInfo=false;
change_callback = fptr;
}
void onChange(void (*fptr)(float,void*), void* info) {
hasCallbackInfo=true;
change_callback = (void (*)(float))fptr;
callbackInfo = info;
}
// TODO: math operators.... + - * / % ++ -- // TODO: math operators.... + - * / % ++ --
private: private:
unsigned int id; unsigned int id;
const _XpRefStr_ *name; const _XpRefStr_ *name;
float value; float value;
void (*change_callback)(float); void (*change_callback)(float);
void* callbackInfo;
bool hasCallbackInfo;
FlightSimFloat *next; FlightSimFloat *next;
static FlightSimFloat *first; static FlightSimFloat *first;
static FlightSimFloat *last; static FlightSimFloat *last;

Loading…
Откажи
Сачувај