瀏覽代碼

Merge pull request #85 from jbliesener/master

Long datarefs for USB flight sim controls
teensy4-core
Paul Stoffregen 9 年之前
父節點
當前提交
9468d51258
共有 4 個文件被更改,包括 275 次插入20 次删除
  1. +154
    -4
      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

+ 154
- 4
teensy3/usb_flightsim.cpp 查看文件

@@ -106,6 +106,8 @@ FlightSimInteger::FlightSimInteger()
next = NULL;
value = 0;
change_callback = NULL;
callbackInfo = NULL;
hasCallbackInfo = false;
FlightSimClass::request_id_messages = 1;
}

@@ -142,7 +144,13 @@ void FlightSimInteger::write(long val)
void FlightSimInteger::update(long 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)
@@ -169,6 +177,8 @@ FlightSimFloat::FlightSimFloat()
next = NULL;
value = 0;
change_callback = NULL;
hasCallbackInfo = false;
callbackInfo = NULL;
FlightSimClass::request_id_messages = 1;
}

@@ -205,7 +215,13 @@ void FlightSimFloat::write(float val)
void FlightSimFloat::update(float 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)
@@ -282,6 +298,7 @@ void FlightSimClass::update(void)
switch (p[2]) {
case 1:
request_id_messages = 1;
/* no break */
case 2:
enable();
frameCount++;
@@ -329,10 +346,13 @@ static volatile uint8_t tx_noautoflush=0;

void FlightSimClass::xmit(const void *p1, uint8_t n1, const void *p2, uint8_t n2)
{
uint8_t total;
uint16_t total;

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;
tx_noautoflush = 1;
if (tx_packet) {
@@ -372,8 +392,138 @@ send:
tx_noautoflush = 0;
}

void FlightSimClass::xmit_big_packet(const void *p1, uint8_t n1, const void *p2, uint8_t n2)
{
if (!enabled || !usb_configuration) return;

uint16_t remaining = n1 + n2;
if (remaining > 255) return;
bool part2 = false;
uint8_t remainingPart1 = n1;
const uint8_t *dataPtr = (const uint8_t*)p1;
bool writeFragmentHeader = 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, containing total packet length
memcpy(tx_packet->buf + tx_packet->index, dataPtr, partLen);
remainingPart1 -= partLen;
tx_packet->index += partLen;
if (remainingPart1) {
// there still is data from the first part that
// will go to the next packet. The boolean variable
// part2 remains false
remaining = remainingPart1+n2;
dataPtr += partLen;
} else {
// maybe we have space for some data from the second part
part2=true;
partLen = FLIGHTSIM_TX_SIZE - tx_packet->index;
// there is no need here to check whether partLen is
// bigger than n2. It's not. If it were, all the data
// would have fit in a single packet and xmit_big_packet
// would never have been called...
remaining = n2;
if (partLen) {
memcpy(tx_packet->buf + tx_packet->index, p2, partLen);
remaining -= partLen;
tx_packet->index += partLen;
}
dataPtr = (const uint8_t*)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;
}

// queue first packet for sending
tx_packet->len = FLIGHTSIM_TX_SIZE;
usb_tx(FLIGHTSIM_TX_ENDPOINT, tx_packet);
tx_packet = NULL;
writeFragmentHeader = true;
} else {
remaining = n1+n2;
}
while (remaining >0) {
while (1) {
// get memory for next packet
if (usb_tx_packet_count(FLIGHTSIM_TX_ENDPOINT) < TX_PACKET_LIMIT) {
tx_packet = usb_malloc();
if (tx_packet) {
break;
}
}

if (!enabled || !usb_configuration) {
// teensy disconnected
tx_noautoflush = 0;
return;
}
tx_noautoflush = 0; // you can pick up my data, if you like
yield(); // do other things and wait for memory to become free
tx_noautoflush = 1; // wait, I'm working on the packet data
}

if (writeFragmentHeader) {
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 = (const uint8_t*)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;
}
}
writeFragmentHeader = true;
if (tx_packet->index >= FLIGHTSIM_TX_SIZE) {
// queue packet for sending
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" {
// This gets called from usb_isr 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)
{
if (tx_noautoflush || !tx_packet || tx_packet->index == 0) return;

+ 23
- 2
teensy3/usb_flightsim.h 查看文件

@@ -66,6 +66,7 @@ private:
static void enable(void) { enabled = 1; enableTimeout = 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_big_packet(const void *p1, uint8_t n1, const void *p2, uint8_t n2);
friend class FlightSimCommand;
friend class FlightSimInteger;
friend class FlightSimFloat;
@@ -114,13 +115,23 @@ public:
void identify(void);
void update(long val);
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.... + - * / % ++ --
private:
unsigned int id;
const _XpRefStr_ *name;
long value;
void (*change_callback)(long);
void* callbackInfo;
bool hasCallbackInfo;
FlightSimInteger *next;
static FlightSimInteger *first;
static FlightSimInteger *last;
@@ -148,13 +159,23 @@ public:
void identify(void);
void update(float val);
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.... + - * / % ++ --
private:
unsigned int id;
const _XpRefStr_ *name;
float value;
void (*change_callback)(float);
void* callbackInfo;
bool hasCallbackInfo;
FlightSimFloat *next;
static FlightSimFloat *first;
static FlightSimFloat *last;

+ 74
- 11
usb_flightsim/usb_api.cpp 查看文件

@@ -64,7 +64,8 @@ FlightSimCommand::FlightSimCommand()

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

if (!FlightSim.enabled || !name) return;
len = strlen_P((const char *)name);
@@ -108,7 +109,8 @@ FlightSimInteger::FlightSimInteger()

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

if (!FlightSim.enabled || !name) return;
len = strlen_P((const char *)name);
@@ -139,7 +141,13 @@ void FlightSimInteger::write(long val)
void FlightSimInteger::update(long 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)
@@ -171,7 +179,8 @@ FlightSimFloat::FlightSimFloat()

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

if (!FlightSim.enabled || !name) return;
len = strlen_P((const char *)name);
@@ -202,7 +211,13 @@ void FlightSimFloat::write(float val)
void FlightSimFloat::update(float 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)
@@ -337,7 +352,6 @@ void FlightSimClass::xmit(const uint8_t *p1, uint8_t n1)
{
uint8_t intr_state, avail;

if (n1 > FLIGHTSIM_TX_SIZE) return;
if (!enabled || !usb_configuration) return;
intr_state = SREG;
cli();
@@ -374,7 +388,6 @@ void FlightSimClass::xmit(const uint8_t *p1, uint8_t n1, const uint8_t *p2, uint
uint8_t intr_state, total, avail;

total = n1 + n2;
if (total > FLIGHTSIM_TX_SIZE) return;
if (!enabled || !usb_configuration) return;
intr_state = SREG;
cli();
@@ -409,13 +422,15 @@ send:
}


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;
const char *s2 = (const char *)p2;
const char * PROGMEM s2 = (const char *)p2;

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;
intr_state = SREG;
cli();
@@ -449,6 +464,54 @@ send:
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;

+ 24
- 3
usb_flightsim/usb_api.h 查看文件

@@ -31,7 +31,8 @@ private:
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, 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 FlightSimInteger;
friend class FlightSimFloat;
@@ -80,13 +81,23 @@ public:
void identify(void);
void update(long val);
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.... + - * / % ++ --
private:
unsigned int id;
const _XpRefStr_ *name;
long value;
void (*change_callback)(long);
void* callbackInfo;
bool hasCallbackInfo;
FlightSimInteger *next;
static FlightSimInteger *first;
static FlightSimInteger *last;
@@ -114,13 +125,23 @@ public:
void identify(void);
void update(float val);
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.... + - * / % ++ --
private:
unsigned int id;
const _XpRefStr_ *name;
float value;
void (*change_callback)(float);
void* callbackInfo;
bool hasCallbackInfo;
FlightSimFloat *next;
static FlightSimFloat *first;
static FlightSimFloat *last;

Loading…
取消
儲存