Browse Source

AntPlus polling and example (still incomplete)

main
PaulStoffregen 7 years ago
parent
commit
94b2decbca
3 changed files with 46 additions and 82 deletions
  1. +1
    -21
      USBHost_t36.h
  2. +27
    -61
      antplus.cpp
  3. +18
    -0
      examples/AntPlus/AntPlus.ino

+ 1
- 21
USBHost_t36.h View File

volatile uint16_t txtail; volatile uint16_t txtail;
volatile bool txready; volatile bool txready;
volatile uint8_t rxlen; volatile uint8_t rxlen;
volatile bool do_polling;
private: private:
enum _eventi { enum _eventi {
EVENTI_MESSAGE = 0, EVENTI_MESSAGE = 0,
uint8_t channelStatusOld; uint8_t channelStatusOld;
} flags; } flags;
} TDCONFIG; } TDCONFIG;
//typedef struct {
//int (*cbPtr) (const int channel, const int messageId,
//const uint8_t *payLoad, const size_t dataLength, void *userPtr);
//void *uPtr; // user variable sent with each event
//} TEVENTFUNC;
//typedef struct {
//void (*cbPtr) (TDCONFIG *cfg, const uint8_t *payLoad,
//const size_t dataLength, void *userPtr);
//void *uPtr; // user variable sent with each payload
//} TPAYLOADFUNC;
typedef struct { typedef struct {
uint8_t initOnce; uint8_t initOnce;
uint8_t key; // key index uint8_t key; // key index
int iDevice; // index to the antplus we're interested in, if > one found int iDevice; // index to the antplus we're interested in, if > one found
//TEVENTFUNC eventCb[EVENTI_TOTAL];
//TPAYLOADFUNC payloadCb[PROFILE_TOTAL];
TDCONFIG dcfg[PROFILE_TOTAL]; // channel config, we're using one channel per device TDCONFIG dcfg[PROFILE_TOTAL]; // channel config, we're using one channel per device
} TLIBANTPLUS; } TLIBANTPLUS;
TLIBANTPLUS ant; TLIBANTPLUS ant;
int (*callbackFunc)(uint32_t msg, intptr_t *value1, uint32_t value2); int (*callbackFunc)(uint32_t msg, intptr_t *value1, uint32_t value2);
//int dispatchMessage(const uint8_t *stream, const int len);
void dispatchPayload(TDCONFIG *cfg, const uint8_t *payload, const int len); void dispatchPayload(TDCONFIG *cfg, const uint8_t *payload, const int len);
static const uint8_t *getAntKey(const uint8_t keyIdx); static const uint8_t *getAntKey(const uint8_t keyIdx);
static uint8_t calcMsgChecksum (const uint8_t *buffer, const uint8_t len); static uint8_t calcMsgChecksum (const uint8_t *buffer, const uint8_t len);
static int msgCheckIntegrity(uint8_t *stream, const int len); static int msgCheckIntegrity(uint8_t *stream, const int len);
static int msgGetLength(uint8_t *stream); static int msgGetLength(uint8_t *stream);
int handleMessages(uint8_t *buffer, int tBytes); int handleMessages(uint8_t *buffer, int tBytes);
//int registerEventCallback(const int which, void *eventFunc, void *userPtr);
//int registerPayloadCallback(const int profile, void *eventFunc, void *userPtr);

void setCallbackFunc(int (*func)(uint32_t msg, intptr_t *value1, uint32_t value2)); void setCallbackFunc(int (*func)(uint32_t msg, intptr_t *value1, uint32_t value2));
void sendMessage(uint32_t msg, intptr_t *value1, uint32_t value2); void sendMessage(uint32_t msg, intptr_t *value1, uint32_t value2);
void sendMessageChannelStatus(TDCONFIG *cfg, const uint32_t channelStatus); void sendMessageChannelStatus(TDCONFIG *cfg, const uint32_t channelStatus);

void message_channel(const int chan, const int eventId, void message_channel(const int chan, const int eventId,
const uint8_t *payload, const size_t dataLength); const uint8_t *payload, const size_t dataLength);
void message_response(const int chan, const int msgId, void message_response(const int chan, const int msgId,
const uint8_t *payload, const size_t dataLength); const uint8_t *payload, const size_t dataLength);
void message_event(const int channel, const int msgId, void message_event(const int channel, const int msgId,
const uint8_t *payload, const size_t dataLength); const uint8_t *payload, const size_t dataLength);


//int SetPayloadHandler(const int profile, void *eventFunc, void *userPtr);
//int SetEventHandler(const int which, void *eventFunc, void *userPtr);
int ResetSystem(); int ResetSystem();
int RequestMessage(const int channel, const int message); int RequestMessage(const int channel, const int message);
int SetNetworkKey(const int netNumber, const uint8_t *key); int SetNetworkKey(const int netNumber, const uint8_t *key);

+ 27
- 61
antplus.cpp View File

updatetimer.start(500000); updatetimer.start(500000);
queue_Data_Transfer(rxpipe, rxpacket, 64, this); queue_Data_Transfer(rxpipe, rxpacket, 64, this);
rxlen = 0; rxlen = 0;
do_polling = false;
return true; return true;
} }
return false; return false;
rxlen = 0; rxlen = 0;
} else { } else {
rxlen = len; // signal arrival of data to Task() rxlen = len; // signal arrival of data to Task()
// TODO: should someday use EventResponder to call from yield()
} }
} }


if (first_update) { if (first_update) {
ResetSystem(); ResetSystem();
first_update = false; first_update = false;
} else {
do_polling = true;
} }
//println("ant update timer"); //println("ant update timer");
} }
rxlen = 0; rxlen = 0;
NVIC_ENABLE_IRQ(IRQ_USBHS); NVIC_ENABLE_IRQ(IRQ_USBHS);
} }



if (do_polling) {
do_polling = false;
for (int i = 0; i < PROFILE_TOTAL; i++) {
TDCONFIG *cfg = &ant.dcfg[i];
if (!(cfg->flags.profileValid)) continue;
//printf("#### %i %i: %i %i %i ####", i, cfg->channel,
// cfg->flags.channelStatus, cfg->flags.keyAccepted,
// cfg->flags.chanIdOnce);
if (cfg->flags.channelStatus) {
RequestMessage(cfg->channel, MESG_CHANNEL_STATUS_ID);
} else {
AssignChannel(cfg->channel, cfg->channelType, cfg->networkNumber);
RequestMessage(cfg->channel, MESG_CHANNEL_STATUS_ID);
if (!cfg->flags.keyAccepted && !cfg->flags.chanIdOnce) {
SetNetworkKey(cfg->networkNumber, getAntKey(ant.key));
}
}
}
}
} }









enum _akeys { enum _akeys {
KEY_ANTSPORT, KEY_ANTSPORT,
KEY_SUUNTO, KEY_SUUNTO,
}; };





/*int AntPlus::dispatchMessage(const uint8_t *stream, const int len)
{
return ant.eventCb[EVENTI_MESSAGE].cbPtr(stream[STREAM_CHANNEL],
stream[STREAM_MESSAGE], &stream[STREAM_DATA],
(size_t)stream[STREAM_LENGTH], ant.eventCb[EVENTI_MESSAGE].uPtr);
}*/

uint8_t AntPlus::calcMsgChecksum(const uint8_t *buffer, const uint8_t len) uint8_t AntPlus::calcMsgChecksum(const uint8_t *buffer, const uint8_t len)
{ {
uint8_t checksum = 0x00; uint8_t checksum = 0x00;
message_event(stream[STREAM_CHANNEL], stream[STREAM_MESSAGE], message_event(stream[STREAM_CHANNEL], stream[STREAM_MESSAGE],
&stream[STREAM_DATA], (size_t)stream[STREAM_LENGTH]); &stream[STREAM_DATA], (size_t)stream[STREAM_LENGTH]);




int len = msgGetLength(stream); int len = msgGetLength(stream);
stream += len; stream += len;
tBytes -= len; tBytes -= len;
return 1; return 1;
} }


/*int AntPlus::registerEventCallback(const int which, void *eventFunc, void *userPtr)
{
if (which < EVENTI_TOTAL) {
ant.eventCb[which].cbPtr = (int (*)(int, int, const uint8_t*, size_t, void*))eventFunc;
ant.eventCb[which].uPtr = userPtr;
return 1;
}
//printf("invalid callback id {%i}\n.", which);
return 0;
}*/

/*int AntPlus::registerPayloadCallback(const int profile, void *eventFunc, void *userPtr)
{
if (profile < PROFILE_TOTAL) {
ant.payloadCb[profile].cbPtr = (void (*)(TDCONFIG*, const uint8_t*, size_t, void*))eventFunc;
ant.payloadCb[profile].uPtr = userPtr;
return 1;
}
//printf("invalid callback id {%i}\n.", profile);
return 0;
}*/




// TODO: replace this with multiple Arduino style OnXYZ callbacks // TODO: replace this with multiple Arduino style OnXYZ callbacks
void AntPlus::setCallbackFunc(int (*func)(uint32_t msg, intptr_t *value1, uint32_t value2)) void AntPlus::setCallbackFunc(int (*func)(uint32_t msg, intptr_t *value1, uint32_t value2))
//printf(" $ chan event: chan:%i, msgId:0x%.2X, payload:%p, dataLen:%i, uPtr:%p", chan, eventId, payload, (int)dataLength, uPtr); //printf(" $ chan event: chan:%i, msgId:0x%.2X, payload:%p, dataLen:%i, uPtr:%p", chan, eventId, payload, (int)dataLength, uPtr);
//dump_hexbytes(payload, dataLength); //dump_hexbytes(payload, dataLength);


//TLIBANTPLUS *ant = (AntPlus::TLIBANTPLUS*)uPtr;
TDCONFIG *cfg = &(ant.dcfg[chan]); TDCONFIG *cfg = &(ant.dcfg[chan]);


switch (eventId){ switch (eventId){
//printf(" @ msg event cb: Chan:%i, Id:0x%.2X, payload:%p, len:%i, ptr:%p", channel, msgId, payload, (int)dataLength, uPtr); //printf(" @ msg event cb: Chan:%i, Id:0x%.2X, payload:%p, len:%i, ptr:%p", channel, msgId, payload, (int)dataLength, uPtr);
//dump_hexbytes(payload, dataLength); //dump_hexbytes(payload, dataLength);


//TLIBANTPLUS *ant = (TLIBANTPLUS*)uPtr;
uint8_t chan = 0; uint8_t chan = 0;
if (channel >= 0 && channel < PROFILE_TOTAL) chan = channel; if (channel >= 0 && channel < PROFILE_TOTAL) chan = channel;


} }




//int AntPlus::SetPayloadHandler(const int profile, void *eventFunc, void *userPtr)
//{
//return registerPayloadCallback(profile, eventFunc, userPtr);
//}

//int AntPlus::SetEventHandler(const int which, void *eventFunc, void *userPtr)
//{
//return registerEventCallback(which, eventFunc, userPtr);
//}

int AntPlus::ResetSystem() int AntPlus::ResetSystem()
{ {
//println("libantplus_ResetSystem"); //println("libantplus_ResetSystem");
return ret; return ret;
} }


//const uint8_t *libantplus_GetNetworkKey (const uint8_t keyIdx)
//{
//return antplus_getAntKey(keyIdx);
//}






void AntPlus::profileSetup_HRM(TDCONFIG *cfg, const uint32_t deviceId) void AntPlus::profileSetup_HRM(TDCONFIG *cfg, const uint32_t deviceId)
int deviceId = 0; // TODO: user API to set this? int deviceId = 0; // TODO: user API to set this?
profileSetup_HRM(&ant.dcfg[PROFILE_HRM], deviceId); profileSetup_HRM(&ant.dcfg[PROFILE_HRM], deviceId);
profileSetup_SPDCAD(&ant.dcfg[PROFILE_SPDCAD], deviceId); profileSetup_SPDCAD(&ant.dcfg[PROFILE_SPDCAD], deviceId);
profileSetup_POWER(&ant.dcfg[PROFILE_POWER], deviceId);
profileSetup_STRIDE(&ant.dcfg[PROFILE_STRIDE], deviceId);
profileSetup_SPEED(&ant.dcfg[PROFILE_SPEED], deviceId);
profileSetup_CADENCE(&ant.dcfg[PROFILE_CADENCE], deviceId);
//profileSetup_POWER(&ant.dcfg[PROFILE_POWER], deviceId);
//profileSetup_STRIDE(&ant.dcfg[PROFILE_STRIDE], deviceId);
//profileSetup_SPEED(&ant.dcfg[PROFILE_SPEED], deviceId);
//profileSetup_CADENCE(&ant.dcfg[PROFILE_CADENCE], deviceId);


//ant.eventCb[EVENTI_MESSAGE].cbPtr = &message_event; //ant.eventCb[EVENTI_MESSAGE].cbPtr = &message_event;
//SetEventHandler(EVENTI_MESSAGE, (void*)message_event, (void*)ant); //SetEventHandler(EVENTI_MESSAGE, (void*)message_event, (void*)ant);

+ 18
- 0
examples/AntPlus/AntPlus.ino View File

#include <USBHost_t36.h>

USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
AntPlus ant1(myusb);

void setup() {
while (!Serial) ; // wait for Arduino Serial Monitor
Serial.println("Ant+ USB Test");
myusb.begin();
ant1.begin();

}

void loop() {
myusb.Task();
}

Loading…
Cancel
Save