demo.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014
  1. /*
  2. This software is subject to the license described in the License.txt file
  3. included with this software distribution. You may not use this file except
  4. in compliance with this license.
  5. Copyright (c) Dynastream Innovations Inc. 2016
  6. All rights reserved.
  7. */
  8. #include "demo.h"
  9. #include "types.h"
  10. #include "dsi_framer_ant.hpp"
  11. #include "dsi_thread.h"
  12. #include "dsi_serial_generic.hpp"
  13. #include "dsi_debug.hpp"
  14. #include <stdio.h>
  15. #include <assert.h>
  16. #include <string.h>
  17. #define ENABLE_EXTENDED_MESSAGES
  18. #define USER_BAUDRATE (50000) // For AT3/AP2, use 57600
  19. #define USER_RADIOFREQ (35)
  20. #define USER_ANTCHANNEL (0)
  21. #define USER_DEVICENUM (49)
  22. #define USER_DEVICETYPE (1)
  23. #define USER_TRANSTYPE (1)
  24. #define USER_NETWORK_KEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}
  25. #define USER_NETWORK_NUM (0) // The network key is assigned to this network number
  26. #define MESSAGE_TIMEOUT (1000)
  27. // Indexes into message recieved from ANT
  28. #define MESSAGE_BUFFER_DATA1_INDEX ((UCHAR) 0)
  29. #define MESSAGE_BUFFER_DATA2_INDEX ((UCHAR) 1)
  30. #define MESSAGE_BUFFER_DATA3_INDEX ((UCHAR) 2)
  31. #define MESSAGE_BUFFER_DATA4_INDEX ((UCHAR) 3)
  32. #define MESSAGE_BUFFER_DATA5_INDEX ((UCHAR) 4)
  33. #define MESSAGE_BUFFER_DATA6_INDEX ((UCHAR) 5)
  34. #define MESSAGE_BUFFER_DATA7_INDEX ((UCHAR) 6)
  35. #define MESSAGE_BUFFER_DATA8_INDEX ((UCHAR) 7)
  36. #define MESSAGE_BUFFER_DATA9_INDEX ((UCHAR) 8)
  37. #define MESSAGE_BUFFER_DATA10_INDEX ((UCHAR) 9)
  38. #define MESSAGE_BUFFER_DATA11_INDEX ((UCHAR) 10)
  39. #define MESSAGE_BUFFER_DATA12_INDEX ((UCHAR) 11)
  40. #define MESSAGE_BUFFER_DATA13_INDEX ((UCHAR) 12)
  41. #define MESSAGE_BUFFER_DATA14_INDEX ((UCHAR) 13)
  42. ////////////////////////////////////////////////////////////////////////////////
  43. // main
  44. //
  45. // Usage:
  46. //
  47. // c:\DEMO_LIB.exe [device_no] [channel_type]
  48. //
  49. // ... where
  50. //
  51. // device_no: USB Device port, starting at 0
  52. // channel_type: Master = 0, Slave = 1
  53. //
  54. // ... example
  55. //
  56. // c:\Demo_LIB.exe 0 0
  57. //
  58. // Comment to USB port 0 and open a Master channel
  59. //
  60. // If optional arguements are not supplied, user will
  61. // be prompted to enter these after the program starts.
  62. //
  63. ////////////////////////////////////////////////////////////////////////////////
  64. int main(int argc, char **argv)
  65. {
  66. Demo* pclDemo = new Demo();
  67. UCHAR ucDeviceNumber = 0xFF;
  68. UCHAR ucChannelType = CHANNEL_TYPE_INVALID;
  69. if(argc > 2)
  70. {
  71. ucDeviceNumber = (UCHAR) atoi(argv[1]);
  72. ucChannelType = (UCHAR) atoi(argv[2]);
  73. }
  74. if(pclDemo->Init(ucDeviceNumber,ucChannelType))
  75. pclDemo->Start();
  76. else
  77. delete pclDemo;
  78. return 0;
  79. }
  80. ////////////////////////////////////////////////////////////////////////////////
  81. // Demo
  82. //
  83. // Constructor, intializes Demo class
  84. //
  85. ////////////////////////////////////////////////////////////////////////////////
  86. Demo::Demo()
  87. {
  88. ucChannelType = CHANNEL_TYPE_INVALID;
  89. pclSerialObject = (DSISerialGeneric*)NULL;
  90. pclMessageObject = (DSIFramerANT*)NULL;
  91. uiDSIThread = (DSI_THREAD_ID)NULL;
  92. bMyDone = FALSE;
  93. bDone = FALSE;
  94. bDisplay = TRUE;
  95. bBroadcasting = FALSE;
  96. memset(aucTransmitBuffer,0,ANT_STANDARD_DATA_PAYLOAD_SIZE);
  97. }
  98. ////////////////////////////////////////////////////////////////////////////////
  99. // ~Demo
  100. //
  101. // Destructor, clean up and loose memory
  102. //
  103. ////////////////////////////////////////////////////////////////////////////////
  104. Demo::~Demo()
  105. {
  106. if(pclMessageObject)
  107. delete pclMessageObject;
  108. if(pclSerialObject)
  109. delete pclSerialObject;
  110. }
  111. ////////////////////////////////////////////////////////////////////////////////
  112. // Init
  113. //
  114. // Initize the Demo and ANT Library.
  115. //
  116. // ucDeviceNumber_: USB Device Number (0 for first USB stick plugged and so on)
  117. // If not specified on command line, 0xFF is passed in as invalid.
  118. // ucChannelType_: ANT Channel Type. 0 = Master, 1 = Slave
  119. // If not specified, 2 is passed in as invalid.
  120. //
  121. ////////////////////////////////////////////////////////////////////////////////
  122. BOOL Demo::Init(UCHAR ucDeviceNumber_, UCHAR ucChannelType_)
  123. {
  124. BOOL bStatus;
  125. // Initialize condition var and mutex
  126. UCHAR ucCondInit = DSIThread_CondInit(&condTestDone);
  127. assert(ucCondInit == DSI_THREAD_ENONE);
  128. UCHAR ucMutexInit = DSIThread_MutexInit(&mutexTestDone);
  129. assert(ucMutexInit == DSI_THREAD_ENONE);
  130. #if defined(DEBUG_FILE)
  131. // Enable logging
  132. DSIDebug::Init();
  133. DSIDebug::SetDebug(TRUE);
  134. #endif
  135. // Create Serial object.
  136. pclSerialObject = new DSISerialGeneric();
  137. assert(pclSerialObject);
  138. // NOTE: Will fail if the module is not available.
  139. // If no device number was specified on the command line,
  140. // prompt the user for input.
  141. if(ucDeviceNumber_ == 0xFF)
  142. {
  143. printf("USB Device number?\n"); fflush(stdout);
  144. char st[1024];
  145. fgets(st, sizeof(st), stdin);
  146. sscanf(st, "%u", &ucDeviceNumber_);
  147. }
  148. ucChannelType = ucChannelType_;
  149. // Initialize Serial object.
  150. // The device number depends on how many USB sticks have been
  151. // plugged into the PC. The first USB stick plugged will be 0
  152. // the next 1 and so on.
  153. //
  154. // The Baud Rate depends on the ANT solution being used. AP1
  155. // is 50000, all others are 57600
  156. bStatus = pclSerialObject->Init(USER_BAUDRATE, ucDeviceNumber_);
  157. assert(bStatus);
  158. // Create Framer object.
  159. pclMessageObject = new DSIFramerANT(pclSerialObject);
  160. assert(pclMessageObject);
  161. // Initialize Framer object.
  162. bStatus = pclMessageObject->Init();
  163. assert(bStatus);
  164. // Let Serial know about Framer.
  165. pclSerialObject->SetCallback(pclMessageObject);
  166. // Open Serial.
  167. bStatus = pclSerialObject->Open();
  168. // If the Open function failed, most likely the device
  169. // we are trying to access does not exist, or it is connected
  170. // to another program
  171. if(!bStatus)
  172. {
  173. printf("Failed to connect to device at USB port %d\n", ucDeviceNumber_);
  174. return FALSE;
  175. }
  176. // Create message thread.
  177. uiDSIThread = DSIThread_CreateThread(&Demo::RunMessageThread, this);
  178. assert(uiDSIThread);
  179. printf("Initialization was successful!\n"); fflush(stdout);
  180. return TRUE;
  181. }
  182. ////////////////////////////////////////////////////////////////////////////////
  183. // Close
  184. //
  185. // Close connection to USB stick.
  186. //
  187. ////////////////////////////////////////////////////////////////////////////////
  188. void Demo::Close()
  189. {
  190. //Wait for test to be done
  191. DSIThread_MutexLock(&mutexTestDone);
  192. bDone = TRUE;
  193. UCHAR ucWaitResult = DSIThread_CondTimedWait(&condTestDone, &mutexTestDone, DSI_THREAD_INFINITE);
  194. assert(ucWaitResult == DSI_THREAD_ENONE);
  195. DSIThread_MutexUnlock(&mutexTestDone);
  196. //Destroy mutex and condition var
  197. DSIThread_MutexDestroy(&mutexTestDone);
  198. DSIThread_CondDestroy(&condTestDone);
  199. //Close all stuff
  200. if(pclSerialObject)
  201. pclSerialObject->Close();
  202. #if defined(DEBUG_FILE)
  203. DSIDebug::Close();
  204. #endif
  205. }
  206. ////////////////////////////////////////////////////////////////////////////////
  207. // Start
  208. //
  209. // Starts the Demo
  210. //
  211. ////////////////////////////////////////////////////////////////////////////////
  212. void Demo::Start()
  213. {
  214. BOOL bStatus;
  215. // Print out the menu to start
  216. PrintMenu();
  217. // If the channel type has not been set at the command line,
  218. // prompt the user to specify now.
  219. do
  220. {
  221. if(ucChannelType == CHANNEL_TYPE_INVALID)
  222. {
  223. printf("Channel Type? (Master = 0, Slave = 1)\n"); fflush(stdout);
  224. char st[1024];
  225. fgets(st, sizeof(st), stdin);
  226. sscanf(st, "%u", &ucChannelType);
  227. }
  228. if(ucChannelType != 0 && ucChannelType != 1)
  229. {
  230. ucChannelType = CHANNEL_TYPE_INVALID;
  231. printf("Error: invalid channel type\n");
  232. }
  233. } while(ucChannelType == CHANNEL_TYPE_INVALID);
  234. // Start ANT channel setup
  235. bStatus = InitANT();
  236. while(!bMyDone)
  237. {
  238. UCHAR ucChar;
  239. char st[1024];
  240. fgets(st, sizeof(st), stdin);
  241. sscanf(st, "%c", &ucChar);
  242. switch(ucChar)
  243. {
  244. case 'M':
  245. case 'm':
  246. {
  247. // Printout options
  248. PrintMenu();
  249. break;
  250. }
  251. case 'Q':
  252. case 'q':
  253. {
  254. // Quit
  255. printf("Closing channel...\n");
  256. bBroadcasting = FALSE;
  257. pclMessageObject->CloseChannel(USER_ANTCHANNEL, MESSAGE_TIMEOUT);
  258. break;
  259. }
  260. case 'A':
  261. case 'a':
  262. {
  263. // Send Acknowledged data
  264. UCHAR aucTempBuffer[] = {1,2,3,4,5,6,7,8};
  265. pclMessageObject->SendAcknowledgedData( USER_ANTCHANNEL, aucTempBuffer, MESSAGE_TIMEOUT);
  266. break;
  267. }
  268. case 'B':
  269. case 'b':
  270. {
  271. // Send Burst Data (10 packets)
  272. UCHAR ucSizeBytes = 8*10;
  273. UCHAR aucTempBuffer[8*10];
  274. for (int i = 0; i < ucSizeBytes; i++)
  275. aucTempBuffer[i] = i;
  276. pclMessageObject->SendTransfer( USER_ANTCHANNEL, aucTempBuffer, ucSizeBytes, MESSAGE_TIMEOUT);
  277. break;
  278. }
  279. case 'r':
  280. case 'R':
  281. {
  282. // Reset the system and start over the test
  283. bStatus = InitANT();
  284. break;
  285. }
  286. case 'c':
  287. case 'C':
  288. {
  289. // Request capabilites.
  290. ANT_MESSAGE_ITEM stResponse;
  291. pclMessageObject->SendRequest(MESG_CAPABILITIES_ID, USER_ANTCHANNEL, &stResponse, 0);
  292. break;
  293. }
  294. case 'v':
  295. case 'V':
  296. {
  297. // Request version
  298. ANT_MESSAGE_ITEM stResponse;
  299. pclMessageObject->SendRequest(MESG_VERSION_ID, USER_ANTCHANNEL, &stResponse, 0);
  300. break;
  301. }
  302. case 'S':
  303. case 's':
  304. {
  305. // Request channel status
  306. ANT_MESSAGE_ITEM stResponse;
  307. pclMessageObject->SendRequest(MESG_CHANNEL_STATUS_ID, USER_ANTCHANNEL, &stResponse, 0);
  308. break;
  309. }
  310. case 'I':
  311. case 'i':
  312. {
  313. // Request channel ID
  314. ANT_MESSAGE_ITEM stResponse;
  315. pclMessageObject->SendRequest(MESG_CHANNEL_ID_ID, USER_ANTCHANNEL, &stResponse, 0);
  316. break;
  317. }
  318. case 'd':
  319. case 'D':
  320. {
  321. // Toggle display of data messages
  322. bDisplay = !bDisplay;
  323. break;
  324. }
  325. case 'u':
  326. case 'U':
  327. {
  328. // Print out information about the device we are connected to
  329. printf("USB Device Description\n");
  330. USHORT usDevicePID;
  331. USHORT usDeviceVID;
  332. UCHAR aucDeviceDescription[USB_MAX_STRLEN];
  333. UCHAR aucDeviceSerial[USB_MAX_STRLEN];
  334. // Retrieve info
  335. if(pclMessageObject->GetDeviceUSBVID(usDeviceVID))
  336. {
  337. printf(" VID: 0x%X\n", usDeviceVID);
  338. }
  339. if(pclMessageObject->GetDeviceUSBPID(usDevicePID))
  340. {
  341. printf(" PID: 0x%X\n", usDevicePID);
  342. }
  343. if(pclMessageObject->GetDeviceUSBInfo(pclSerialObject->GetDeviceNumber(), aucDeviceDescription, aucDeviceSerial, USB_MAX_STRLEN))
  344. {
  345. printf(" Product Description: %s\n", aucDeviceDescription);
  346. printf(" Serial String: %s\n", aucDeviceSerial);
  347. }
  348. break;
  349. }
  350. default:
  351. {
  352. break;
  353. }
  354. }
  355. DSIThread_Sleep(0);
  356. }
  357. //Disconnecting from module
  358. printf("Disconnecting module...\n");
  359. this->Close();
  360. printf("Demo has completed successfully!\n");
  361. return;
  362. }
  363. ////////////////////////////////////////////////////////////////////////////////
  364. // InitANT
  365. //
  366. // Resets the system and starts the test
  367. //
  368. ////////////////////////////////////////////////////////////////////////////////
  369. BOOL Demo::InitANT(void)
  370. {
  371. BOOL bStatus;
  372. // Reset system
  373. printf("Resetting module...\n");
  374. bStatus = pclMessageObject->ResetSystem();
  375. DSIThread_Sleep(1000);
  376. // Start the test by setting network key
  377. printf("Setting network key...\n");
  378. UCHAR ucNetKey[8] = USER_NETWORK_KEY;
  379. bStatus = pclMessageObject->SetNetworkKey(USER_NETWORK_NUM, ucNetKey, MESSAGE_TIMEOUT);
  380. return bStatus;
  381. }
  382. ////////////////////////////////////////////////////////////////////////////////
  383. // RunMessageThread
  384. //
  385. // Callback function that is used to create the thread. This is a static
  386. // function.
  387. //
  388. ////////////////////////////////////////////////////////////////////////////////
  389. DSI_THREAD_RETURN Demo::RunMessageThread(void *pvParameter_)
  390. {
  391. ((Demo*) pvParameter_)->MessageThread();
  392. return NULL;
  393. }
  394. ////////////////////////////////////////////////////////////////////////////////
  395. // MessageThread
  396. //
  397. // Run message thread
  398. ////////////////////////////////////////////////////////////////////////////////
  399. void Demo::MessageThread()
  400. {
  401. ANT_MESSAGE stMessage;
  402. USHORT usSize;
  403. bDone = FALSE;
  404. while(!bDone)
  405. {
  406. if(pclMessageObject->WaitForMessage(1000))
  407. {
  408. usSize = pclMessageObject->GetMessage(&stMessage);
  409. if(bDone)
  410. break;
  411. if(usSize == DSI_FRAMER_ERROR)
  412. {
  413. // Get the message to clear the error
  414. usSize = pclMessageObject->GetMessage(&stMessage, MESG_MAX_SIZE_VALUE);
  415. continue;
  416. }
  417. if(usSize != DSI_FRAMER_ERROR && usSize != DSI_FRAMER_TIMEDOUT && usSize != 0)
  418. {
  419. ProcessMessage(stMessage, usSize);
  420. }
  421. }
  422. }
  423. DSIThread_MutexLock(&mutexTestDone);
  424. UCHAR ucCondResult = DSIThread_CondSignal(&condTestDone);
  425. assert(ucCondResult == DSI_THREAD_ENONE);
  426. DSIThread_MutexUnlock(&mutexTestDone);
  427. }
  428. ////////////////////////////////////////////////////////////////////////////////
  429. // ProcessMessage
  430. //
  431. // Process ALL messages that come from ANT, including event messages.
  432. //
  433. // stMessage: Message struct containing message recieved from ANT
  434. // usSize_:
  435. ////////////////////////////////////////////////////////////////////////////////
  436. void Demo::ProcessMessage(ANT_MESSAGE stMessage, USHORT usSize_)
  437. {
  438. BOOL bStatus;
  439. BOOL bPrintBuffer = FALSE;
  440. UCHAR ucDataOffset = MESSAGE_BUFFER_DATA2_INDEX; // For most data messages
  441. switch(stMessage.ucMessageID)
  442. {
  443. //RESPONSE MESG
  444. case MESG_RESPONSE_EVENT_ID:
  445. {
  446. //RESPONSE TYPE
  447. switch(stMessage.aucData[1])
  448. {
  449. case MESG_NETWORK_KEY_ID:
  450. {
  451. if(stMessage.aucData[2] != RESPONSE_NO_ERROR)
  452. {
  453. printf("Error configuring network key: Code 0%d\n", stMessage.aucData[2]);
  454. break;
  455. }
  456. printf("Network key set.\n");
  457. printf("Assigning channel...\n");
  458. if(ucChannelType == CHANNEL_TYPE_MASTER)
  459. {
  460. bStatus = pclMessageObject->AssignChannel(USER_ANTCHANNEL, PARAMETER_TX_NOT_RX, 0, MESSAGE_TIMEOUT);
  461. }
  462. else if(ucChannelType == CHANNEL_TYPE_SLAVE)
  463. {
  464. bStatus = pclMessageObject->AssignChannel(USER_ANTCHANNEL, 0, 0, MESSAGE_TIMEOUT);
  465. }
  466. break;
  467. }
  468. case MESG_ASSIGN_CHANNEL_ID:
  469. {
  470. if(stMessage.aucData[2] != RESPONSE_NO_ERROR)
  471. {
  472. printf("Error assigning channel: Code 0%d\n", stMessage.aucData[2]);
  473. break;
  474. }
  475. printf("Channel assigned\n");
  476. printf("Setting Channel ID...\n");
  477. bStatus = pclMessageObject->SetChannelID(USER_ANTCHANNEL, USER_DEVICENUM, USER_DEVICETYPE, USER_TRANSTYPE, MESSAGE_TIMEOUT);
  478. break;
  479. }
  480. case MESG_CHANNEL_ID_ID:
  481. {
  482. if(stMessage.aucData[2] != RESPONSE_NO_ERROR)
  483. {
  484. printf("Error configuring Channel ID: Code 0%d\n", stMessage.aucData[2]);
  485. break;
  486. }
  487. printf("Channel ID set\n");
  488. printf("Setting Radio Frequency...\n");
  489. bStatus = pclMessageObject->SetChannelRFFrequency(USER_ANTCHANNEL, USER_RADIOFREQ, MESSAGE_TIMEOUT);
  490. break;
  491. }
  492. case MESG_CHANNEL_RADIO_FREQ_ID:
  493. {
  494. if(stMessage.aucData[2] != RESPONSE_NO_ERROR)
  495. {
  496. printf("Error configuring Radio Frequency: Code 0%d\n", stMessage.aucData[2]);
  497. break;
  498. }
  499. printf("Radio Frequency set\n");
  500. printf("Opening channel...\n");
  501. bBroadcasting = TRUE;
  502. bStatus = pclMessageObject->OpenChannel(USER_ANTCHANNEL, MESSAGE_TIMEOUT);
  503. break;
  504. }
  505. case MESG_OPEN_CHANNEL_ID:
  506. {
  507. if(stMessage.aucData[2] != RESPONSE_NO_ERROR)
  508. {
  509. printf("Error opening channel: Code 0%d\n", stMessage.aucData[2]);
  510. bBroadcasting = FALSE;
  511. break;
  512. }
  513. printf("Chanel opened\n");
  514. #if defined (ENABLE_EXTENDED_MESSAGES)
  515. printf("Enabling extended messages...\n");
  516. pclMessageObject->RxExtMesgsEnable(TRUE);
  517. #endif
  518. break;
  519. }
  520. case MESG_RX_EXT_MESGS_ENABLE_ID:
  521. {
  522. if(stMessage.aucData[2] == INVALID_MESSAGE)
  523. {
  524. printf("Extended messages not supported in this ANT product\n");
  525. break;
  526. }
  527. else if(stMessage.aucData[2] != RESPONSE_NO_ERROR)
  528. {
  529. printf("Error enabling extended messages: Code 0%d\n", stMessage.aucData[2]);
  530. break;
  531. }
  532. printf("Extended messages enabled\n");
  533. break;
  534. }
  535. case MESG_UNASSIGN_CHANNEL_ID:
  536. {
  537. if(stMessage.aucData[2] != RESPONSE_NO_ERROR)
  538. {
  539. printf("Error unassigning channel: Code 0%d\n", stMessage.aucData[2]);
  540. break;
  541. }
  542. printf("Channel unassigned\n");
  543. printf("Press enter to exit\n");
  544. bMyDone = TRUE;
  545. break;
  546. }
  547. case MESG_CLOSE_CHANNEL_ID:
  548. {
  549. if(stMessage.aucData[2] == CHANNEL_IN_WRONG_STATE)
  550. {
  551. // We get here if we tried to close the channel after the search timeout (slave)
  552. printf("Channel is already closed\n");
  553. printf("Unassigning channel...\n");
  554. bStatus = pclMessageObject->UnAssignChannel(USER_ANTCHANNEL, MESSAGE_TIMEOUT);
  555. break;
  556. }
  557. else if(stMessage.aucData[2] != RESPONSE_NO_ERROR)
  558. {
  559. printf("Error closing channel: Code 0%d\n", stMessage.aucData[2]);
  560. break;
  561. }
  562. // If this message was successful, wait for EVENT_CHANNEL_CLOSED to confirm channel is closed
  563. break;
  564. }
  565. case MESG_REQUEST_ID:
  566. {
  567. if(stMessage.aucData[2] == INVALID_MESSAGE)
  568. {
  569. printf("Requested message not supported in this ANT product\n");
  570. }
  571. break;
  572. }
  573. case MESG_EVENT_ID:
  574. {
  575. switch(stMessage.aucData[2])
  576. {
  577. case EVENT_CHANNEL_CLOSED:
  578. {
  579. printf("Channel Closed\n");
  580. printf("Unassigning channel...\n");
  581. bStatus = pclMessageObject->UnAssignChannel(USER_ANTCHANNEL, MESSAGE_TIMEOUT);
  582. break;
  583. }
  584. case EVENT_TX:
  585. {
  586. // This event indicates that a message has just been
  587. // sent over the air. We take advantage of this event to set
  588. // up the data for the next message period.
  589. static UCHAR ucIncrement = 0; // Increment the first byte of the buffer
  590. aucTransmitBuffer[0] = ucIncrement++;
  591. // Broadcast data will be sent over the air on
  592. // the next message period.
  593. if(bBroadcasting)
  594. {
  595. pclMessageObject->SendBroadcastData(USER_ANTCHANNEL, aucTransmitBuffer);
  596. // Echo what the data will be over the air on the next message period.
  597. if(bDisplay)
  598. {
  599. printf("Tx:(%d): [%02x],[%02x],[%02x],[%02x],[%02x],[%02x],[%02x],[%02x]\n",
  600. USER_ANTCHANNEL,
  601. aucTransmitBuffer[MESSAGE_BUFFER_DATA1_INDEX],
  602. aucTransmitBuffer[MESSAGE_BUFFER_DATA2_INDEX],
  603. aucTransmitBuffer[MESSAGE_BUFFER_DATA3_INDEX],
  604. aucTransmitBuffer[MESSAGE_BUFFER_DATA4_INDEX],
  605. aucTransmitBuffer[MESSAGE_BUFFER_DATA5_INDEX],
  606. aucTransmitBuffer[MESSAGE_BUFFER_DATA6_INDEX],
  607. aucTransmitBuffer[MESSAGE_BUFFER_DATA7_INDEX],
  608. aucTransmitBuffer[MESSAGE_BUFFER_DATA8_INDEX]);
  609. }
  610. else
  611. {
  612. static int iIndex = 0;
  613. static char ac[] = {'|','/','-','\\'};
  614. printf("Tx: %c\r",ac[iIndex++]); fflush(stdout);
  615. iIndex &= 3;
  616. }
  617. }
  618. break;
  619. }
  620. case EVENT_RX_SEARCH_TIMEOUT:
  621. {
  622. printf("Search Timeout\n");
  623. break;
  624. }
  625. case EVENT_RX_FAIL:
  626. {
  627. printf("Rx Fail\n");
  628. break;
  629. }
  630. case EVENT_TRANSFER_RX_FAILED:
  631. {
  632. printf("Burst receive has failed\n");
  633. break;
  634. }
  635. case EVENT_TRANSFER_TX_COMPLETED:
  636. {
  637. printf("Tranfer Completed\n");
  638. break;
  639. }
  640. case EVENT_TRANSFER_TX_FAILED:
  641. {
  642. printf("Tranfer Failed\n");
  643. break;
  644. }
  645. case EVENT_RX_FAIL_GO_TO_SEARCH:
  646. {
  647. printf("Go to Search\n");
  648. break;
  649. }
  650. case EVENT_CHANNEL_COLLISION:
  651. {
  652. printf("Channel Collision\n");
  653. break;
  654. }
  655. case EVENT_TRANSFER_TX_START:
  656. {
  657. printf("Burst Started\n");
  658. break;
  659. }
  660. default:
  661. {
  662. printf("Unhandled channel event: 0x%X\n", stMessage.aucData[2]);
  663. break;
  664. }
  665. }
  666. break;
  667. }
  668. default:
  669. {
  670. printf("Unhandled response 0%d to message 0x%X\n", stMessage.aucData[2], stMessage.aucData[1]);
  671. break;
  672. }
  673. }
  674. break;
  675. }
  676. case MESG_STARTUP_MESG_ID:
  677. {
  678. printf("RESET Complete, reason: ");
  679. UCHAR ucReason = stMessage.aucData[MESSAGE_BUFFER_DATA1_INDEX];
  680. if(ucReason == RESET_POR)
  681. printf("RESET_POR");
  682. if(ucReason & RESET_SUSPEND)
  683. printf("RESET_SUSPEND ");
  684. if(ucReason & RESET_SYNC)
  685. printf("RESET_SYNC ");
  686. if(ucReason & RESET_CMD)
  687. printf("RESET_CMD ");
  688. if(ucReason & RESET_WDT)
  689. printf("RESET_WDT ");
  690. if(ucReason & RESET_RST)
  691. printf("RESET_RST ");
  692. printf("\n");
  693. break;
  694. }
  695. case MESG_CAPABILITIES_ID:
  696. {
  697. printf("CAPABILITIES:\n");
  698. printf(" Max ANT Channels: %d\n",stMessage.aucData[MESSAGE_BUFFER_DATA1_INDEX]);
  699. printf(" Max ANT Networks: %d\n",stMessage.aucData[MESSAGE_BUFFER_DATA2_INDEX]);
  700. UCHAR ucStandardOptions = stMessage.aucData[MESSAGE_BUFFER_DATA3_INDEX];
  701. UCHAR ucAdvanced = stMessage.aucData[MESSAGE_BUFFER_DATA4_INDEX];
  702. UCHAR ucAdvanced2 = stMessage.aucData[MESSAGE_BUFFER_DATA5_INDEX];
  703. printf("Standard Options:\n");
  704. if( ucStandardOptions & CAPABILITIES_NO_RX_CHANNELS )
  705. printf("CAPABILITIES_NO_RX_CHANNELS\n");
  706. if( ucStandardOptions & CAPABILITIES_NO_TX_CHANNELS )
  707. printf("CAPABILITIES_NO_TX_CHANNELS\n");
  708. if( ucStandardOptions & CAPABILITIES_NO_RX_MESSAGES )
  709. printf("CAPABILITIES_NO_RX_MESSAGES\n");
  710. if( ucStandardOptions & CAPABILITIES_NO_TX_MESSAGES )
  711. printf("CAPABILITIES_NO_TX_MESSAGES\n");
  712. if( ucStandardOptions & CAPABILITIES_NO_ACKD_MESSAGES )
  713. printf("CAPABILITIES_NO_ACKD_MESSAGES\n");
  714. if( ucStandardOptions & CAPABILITIES_NO_BURST_TRANSFER )
  715. printf("CAPABILITIES_NO_BURST_TRANSFER\n");
  716. printf("Advanced Options:\n");
  717. if( ucAdvanced & CAPABILITIES_OVERUN_UNDERRUN )
  718. printf("CAPABILITIES_OVERUN_UNDERRUN\n");
  719. if( ucAdvanced & CAPABILITIES_NETWORK_ENABLED )
  720. printf("CAPABILITIES_NETWORK_ENABLED\n");
  721. if( ucAdvanced & CAPABILITIES_AP1_VERSION_2 )
  722. printf("CAPABILITIES_AP1_VERSION_2\n");
  723. if( ucAdvanced & CAPABILITIES_SERIAL_NUMBER_ENABLED )
  724. printf("CAPABILITIES_SERIAL_NUMBER_ENABLED\n");
  725. if( ucAdvanced & CAPABILITIES_PER_CHANNEL_TX_POWER_ENABLED )
  726. printf("CAPABILITIES_PER_CHANNEL_TX_POWER_ENABLED\n");
  727. if( ucAdvanced & CAPABILITIES_LOW_PRIORITY_SEARCH_ENABLED )
  728. printf("CAPABILITIES_LOW_PRIORITY_SEARCH_ENABLED\n");
  729. if( ucAdvanced & CAPABILITIES_SCRIPT_ENABLED )
  730. printf("CAPABILITIES_SCRIPT_ENABLED\n");
  731. if( ucAdvanced & CAPABILITIES_SEARCH_LIST_ENABLED )
  732. printf("CAPABILITIES_SEARCH_LIST_ENABLED\n");
  733. if(usSize_ > 4)
  734. {
  735. printf("Advanced 2 Options 1:\n");
  736. if( ucAdvanced2 & CAPABILITIES_LED_ENABLED )
  737. printf("CAPABILITIES_LED_ENABLED\n");
  738. if( ucAdvanced2 & CAPABILITIES_EXT_MESSAGE_ENABLED )
  739. printf("CAPABILITIES_EXT_MESSAGE_ENABLED\n");
  740. if( ucAdvanced2 & CAPABILITIES_SCAN_MODE_ENABLED )
  741. printf("CAPABILITIES_SCAN_MODE_ENABLED\n");
  742. if( ucAdvanced2 & CAPABILITIES_RESERVED )
  743. printf("CAPABILITIES_RESERVED\n");
  744. if( ucAdvanced2 & CAPABILITIES_PROX_SEARCH_ENABLED )
  745. printf("CAPABILITIES_PROX_SEARCH_ENABLED\n");
  746. if( ucAdvanced2 & CAPABILITIES_EXT_ASSIGN_ENABLED )
  747. printf("CAPABILITIES_EXT_ASSIGN_ENABLED\n");
  748. if( ucAdvanced2 & CAPABILITIES_FS_ANTFS_ENABLED)
  749. printf("CAPABILITIES_FREE_1\n");
  750. if( ucAdvanced2 & CAPABILITIES_FIT1_ENABLED )
  751. printf("CAPABILITIES_FIT1_ENABLED\n");
  752. }
  753. break;
  754. }
  755. case MESG_CHANNEL_STATUS_ID:
  756. {
  757. printf("Got Status\n");
  758. char astrStatus[][32] = { "STATUS_UNASSIGNED_CHANNEL",
  759. "STATUS_ASSIGNED_CHANNEL",
  760. "STATUS_SEARCHING_CHANNEL",
  761. "STATUS_TRACKING_CHANNEL" };
  762. UCHAR ucStatusByte = stMessage.aucData[MESSAGE_BUFFER_DATA2_INDEX] & STATUS_CHANNEL_STATE_MASK; // MUST MASK OFF THE RESERVED BITS
  763. printf("STATUS: %s\n",astrStatus[ucStatusByte]);
  764. break;
  765. }
  766. case MESG_CHANNEL_ID_ID:
  767. {
  768. // Channel ID of the device that we just recieved a message from.
  769. USHORT usDeviceNumber = stMessage.aucData[MESSAGE_BUFFER_DATA2_INDEX] | (stMessage.aucData[MESSAGE_BUFFER_DATA3_INDEX] << 8);
  770. UCHAR ucDeviceType = stMessage.aucData[MESSAGE_BUFFER_DATA4_INDEX];
  771. UCHAR ucTransmissionType = stMessage.aucData[MESSAGE_BUFFER_DATA5_INDEX];
  772. printf("CHANNEL ID: (%d/%d/%d)\n", usDeviceNumber, ucDeviceType, ucTransmissionType);
  773. break;
  774. }
  775. case MESG_VERSION_ID:
  776. {
  777. printf("VERSION: %s\n", (char*) &stMessage.aucData[MESSAGE_BUFFER_DATA1_INDEX]);
  778. break;
  779. }
  780. case MESG_ACKNOWLEDGED_DATA_ID:
  781. case MESG_BURST_DATA_ID:
  782. case MESG_BROADCAST_DATA_ID:
  783. {
  784. // The flagged and unflagged data messages have the same
  785. // message ID. Therefore, we need to check the size to
  786. // verify of a flag is present at the end of a message.
  787. // To enable flagged messages, must call ANT_RxExtMesgsEnable first.
  788. if(usSize_ > MESG_DATA_SIZE)
  789. {
  790. UCHAR ucFlag = stMessage.aucData[MESSAGE_BUFFER_DATA10_INDEX];
  791. if(bDisplay && ucFlag & ANT_EXT_MESG_BITFIELD_DEVICE_ID)
  792. {
  793. // Channel ID of the device that we just recieved a message from.
  794. USHORT usDeviceNumber = stMessage.aucData[MESSAGE_BUFFER_DATA11_INDEX] | (stMessage.aucData[MESSAGE_BUFFER_DATA12_INDEX] << 8);
  795. UCHAR ucDeviceType = stMessage.aucData[MESSAGE_BUFFER_DATA13_INDEX];
  796. UCHAR ucTransmissionType = stMessage.aucData[MESSAGE_BUFFER_DATA14_INDEX];
  797. printf("Chan ID(%d/%d/%d) - ", usDeviceNumber, ucDeviceType, ucTransmissionType);
  798. }
  799. }
  800. // Display recieved message
  801. bPrintBuffer = TRUE;
  802. ucDataOffset = MESSAGE_BUFFER_DATA2_INDEX; // For most data messages
  803. if(bDisplay)
  804. {
  805. if(stMessage.ucMessageID == MESG_ACKNOWLEDGED_DATA_ID )
  806. printf("Acked Rx:(%d): ", stMessage.aucData[MESSAGE_BUFFER_DATA1_INDEX]);
  807. else if(stMessage.ucMessageID == MESG_BURST_DATA_ID)
  808. printf("Burst(0x%02x) Rx:(%d): ", ((stMessage.aucData[MESSAGE_BUFFER_DATA1_INDEX] & 0xE0) >> 5), stMessage.aucData[MESSAGE_BUFFER_DATA1_INDEX] & 0x1F );
  809. else
  810. printf("Rx:(%d): ", stMessage.aucData[MESSAGE_BUFFER_DATA1_INDEX]);
  811. }
  812. break;
  813. }
  814. case MESG_EXT_BROADCAST_DATA_ID:
  815. case MESG_EXT_ACKNOWLEDGED_DATA_ID:
  816. case MESG_EXT_BURST_DATA_ID:
  817. {
  818. // The "extended" part of this message is the 4-byte channel
  819. // id of the device that we recieved this message from. This message
  820. // is only available on the AT3. The AP2 uses flagged versions of the
  821. // data messages as shown above.
  822. // Channel ID of the device that we just recieved a message from.
  823. USHORT usDeviceNumber = stMessage.aucData[MESSAGE_BUFFER_DATA2_INDEX] | (stMessage.aucData[MESSAGE_BUFFER_DATA3_INDEX] << 8);
  824. UCHAR ucDeviceType = stMessage.aucData[MESSAGE_BUFFER_DATA4_INDEX];
  825. UCHAR ucTransmissionType = stMessage.aucData[MESSAGE_BUFFER_DATA5_INDEX];
  826. bPrintBuffer = TRUE;
  827. ucDataOffset = MESSAGE_BUFFER_DATA6_INDEX; // For most data messages
  828. if(bDisplay)
  829. {
  830. // Display the channel id
  831. printf("Chan ID(%d/%d/%d) ", usDeviceNumber, ucDeviceType, ucTransmissionType );
  832. if(stMessage.ucMessageID == MESG_EXT_ACKNOWLEDGED_DATA_ID)
  833. printf("- Acked Rx:(%d): ", stMessage.aucData[MESSAGE_BUFFER_DATA1_INDEX]);
  834. else if(stMessage.ucMessageID == MESG_EXT_BURST_DATA_ID)
  835. printf("- Burst(0x%02x) Rx:(%d): ", ((stMessage.aucData[MESSAGE_BUFFER_DATA1_INDEX] & 0xE0) >> 5), stMessage.aucData[MESSAGE_BUFFER_DATA1_INDEX] & 0x1F );
  836. else
  837. printf("- Rx:(%d): ", stMessage.aucData[MESSAGE_BUFFER_DATA1_INDEX]);
  838. }
  839. break;
  840. }
  841. default:
  842. {
  843. break;
  844. }
  845. }
  846. // If we recieved a data message, diplay its contents here.
  847. if(bPrintBuffer)
  848. {
  849. if(bDisplay)
  850. {
  851. printf("[%02x],[%02x],[%02x],[%02x],[%02x],[%02x],[%02x],[%02x]\n",
  852. stMessage.aucData[ucDataOffset + 0],
  853. stMessage.aucData[ucDataOffset + 1],
  854. stMessage.aucData[ucDataOffset + 2],
  855. stMessage.aucData[ucDataOffset + 3],
  856. stMessage.aucData[ucDataOffset + 4],
  857. stMessage.aucData[ucDataOffset + 5],
  858. stMessage.aucData[ucDataOffset + 6],
  859. stMessage.aucData[ucDataOffset + 7]);
  860. }
  861. else
  862. {
  863. static int iIndex = 0;
  864. static char ac[] = {'|','/','-','\\'};
  865. printf("Rx: %c\r",ac[iIndex++]); fflush(stdout);
  866. iIndex &= 3;
  867. }
  868. }
  869. return;
  870. }
  871. ////////////////////////////////////////////////////////////////////////////////
  872. // PrintMenu
  873. //
  874. // Start the Test program.
  875. //
  876. ////////////////////////////////////////////////////////////////////////////////
  877. void Demo::PrintMenu()
  878. {
  879. // Printout options
  880. printf("\n");
  881. printf("M - Print this menu\n");
  882. printf("A - Send Acknowledged message\n");
  883. printf("B - Send Burst message\n");
  884. printf("R - Reset\n");
  885. printf("C - Request Capabilites\n");
  886. printf("V - Request Version\n");
  887. printf("I - Request Channel ID\n");
  888. printf("S - Request Status\n");
  889. printf("U - Request USB Descriptor\n");
  890. printf("D - Toggle Display\n");
  891. printf("Q - Quit\n");
  892. printf("\n");
  893. fflush(stdout);
  894. }