ANTChannel.cpp 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276
  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 in compliance
  4. with this license.
  5. Copyright (c) Dynastream Innovations Inc. 2012
  6. All rights reserved.
  7. */
  8. #include "StdAfx.h"
  9. #include "ANTChannel.h"
  10. #include "ANTPlus.h"
  11. #include "ANTClass.h"
  12. /**************************************************************************
  13. * ANTChannel::ANTChannel
  14. *
  15. * ANT CHannel constructor - called for each channel allocated to a
  16. * device.
  17. *
  18. * Params:
  19. *
  20. * ucInstanceNum_: Corressponds to channel number.
  21. * ucSimType_: Type of simulator this channel will represent - either sensor or display.
  22. *
  23. * returns: N/A
  24. *
  25. **************************************************************************/
  26. ANTChannel::ANTChannel(UCHAR ucInstanceNum_, UCHAR ucSimType_, ANTPlatform eHWType_, CapabilitiesStruct sCapabilities_)
  27. {
  28. System::Windows::Forms::Control::CheckForIllegalCrossThreadCalls = FALSE;
  29. InitializeComponent();
  30. bTXPowerUIEnabled = FALSE;
  31. ucSimType = ucSimType_;
  32. ucMyChannelNum = ucInstanceNum_;
  33. ucMyTxType = 1;
  34. ucMyDeviceType = 1; // Transmission Type and Device Type will be set by simulator once loaded
  35. usMyMsgPeriod = 8192; // 4Hz, set to specific simulator value once loaded
  36. dCurEventTime = 0;
  37. bPairingBit = FALSE; // Pairing bit is disabled by default
  38. bDisplayHex = TRUE; // Display raw data in hex by default
  39. eMyChannelState = STATE_CHANNEL_CLOSED; // Channel is initially closed
  40. bMyCheckInternalRaise = FALSE;
  41. bAlreadyUnAssigned = FALSE; // For dealing with differences in how AP2 search timeouts
  42. this->tabPage_ChannelTab->Text = String::Concat("Channel ", System::Convert::ToString(ucMyChannelNum));
  43. // Create timer to handle event simulation
  44. this->timer_SimEvent = (gcnew System::Timers::Timer(500));
  45. this->timer_SimEvent->Elapsed += gcnew System::Timers::ElapsedEventHandler(this, &ANTChannel::timer_SimEvent_Tick);
  46. // Store the capabilities bytes
  47. sMyCapabilities.ucStandardOptions = sCapabilities_.ucStandardOptions;
  48. sMyCapabilities.ucAdvancedOptions = sCapabilities_.ucAdvancedOptions;
  49. sMyCapabilities.ucAdvancedOptions2 = sCapabilities_.ucAdvancedOptions2;
  50. switch(ucSimType)
  51. {
  52. case SIM_SENSOR:
  53. {
  54. // Display simulator list on combo box
  55. this->comboBox_SimSelect->Items->AddRange(gcnew cli::array< System::Object^ >(UNSELECTED) SUPPORTED_SENSORS);
  56. // Create a device ID based on channelNum to prevent duplicates
  57. usMyDeviceNum = (ucMyChannelNum*137)+100;
  58. this->textBox_DeviceID->Text = System::Convert::ToString(usMyDeviceNum);
  59. // Simulator is transmitter
  60. this->checkBox_TxEnable->Text = L"Transmitting";
  61. // Disable functionality for getting Channel ID of paired device
  62. this->button_getChannelID->Visible = false;
  63. // Keep timer alive
  64. System::GC::KeepAlive(timer_SimEvent);
  65. break;
  66. }
  67. case SIM_DISPLAY:
  68. {
  69. // Display simulator list on combo box
  70. this->comboBox_SimSelect->Items->AddRange(gcnew cli::array< System::Object^ >(UNSELECTED) SUPPORTED_DISPLAYS);
  71. // Wildcard Channel ID
  72. usMyDeviceNum = 0;
  73. this->textBox_DeviceID->Text = System::Convert::ToString(usMyDeviceNum);
  74. // Simulator is receiver
  75. this->checkBox_TxEnable->Text = L"Receiving";
  76. // Enable functionality for getting Channel ID of paired device
  77. this->button_getChannelID->Visible = true;
  78. // Ensure timer is disabled
  79. this->timer_SimEvent->Stop();
  80. // Disable display of simulated time (display simulation is not timer-driven)
  81. this->label_TxTime->Visible = false;
  82. this->label_TxTimeDisplay->Visible = false;
  83. break;
  84. }
  85. default:
  86. {
  87. // Ensure timer is disabled
  88. this->timer_SimEvent->Stop();
  89. break;
  90. }
  91. }
  92. // Init the TX Power Select Dropdown based on which HW platform was found
  93. switch (eHWType_)
  94. {
  95. case PLATFORM_AP1_ANT11TR:
  96. {
  97. this->comboBox_TxPowerSelect->Items->AddRange(gcnew cli::array< System::Object^ > TXPOWER_SETTINGS1);
  98. break;
  99. }
  100. case PLATFORM_AP2_USB2_AT3:
  101. {
  102. this->comboBox_TxPowerSelect->Items->AddRange(gcnew cli::array< System::Object^ > TXPOWER_SETTINGS2);
  103. break;
  104. }
  105. case PLATFORM_C7:
  106. {
  107. this->comboBox_TxPowerSelect->Items->AddRange(gcnew cli::array< System::Object^ > TXPOWER_SETTINGS3);
  108. break;
  109. }
  110. case PLATFORM_UNKNOWN:
  111. // fall through
  112. default:
  113. {
  114. this->comboBox_TxPowerSelect->Items->AddRange(gcnew cli::array< System::Object^ > TXPOWER_SETTINGS_UNKNOWN);
  115. break;
  116. }
  117. }
  118. // Make sure the dropdown starts showing the default power
  119. this->comboBox_TxPowerSelect->SelectedIndex = DEFAULT_RADIO_TX_POWER;
  120. bTXPowerUIEnabled = TRUE;
  121. }
  122. /**************************************************************************
  123. * ANTChannel::~ANTChannel
  124. *
  125. * ANT CHannel deconstructor - called after channels are destroyed.
  126. *
  127. * returns: N/A
  128. *
  129. **************************************************************************/
  130. ANTChannel::~ANTChannel()
  131. {
  132. if(curSimulator)
  133. {
  134. delete curSimulator;
  135. }
  136. delete timer_SimEvent;
  137. this->tabPage_ChannelTab->Controls->Clear();
  138. delete this->tabPage_ChannelTab;
  139. delete this->tabControl1;
  140. //clean up floating resources with the garbage collector
  141. GC::Collect(2);
  142. if (components)
  143. {
  144. delete components;
  145. }
  146. }
  147. /**************************************************************************
  148. * ANTChannel::ANTProtocolEvent
  149. *
  150. * MainForm ANT Protocol Event handler - Handles ANT responses to ANT commands and
  151. * requested messages from ANT
  152. *
  153. * Params:
  154. *
  155. * ucMessageCode_: Message ID of packet recieved from ANT.
  156. * pcBuffer_: Pointer to message buffer recieved from ANT.
  157. *
  158. * returns: N/A
  159. *
  160. **************************************************************************/
  161. void ANTChannel::ANTProtocolEvent(UCHAR ucMessageCode_, UCHAR* pcBuffer_)
  162. {
  163. if(ucMessageCode_ == MESG_CHANNEL_ID_ID)
  164. {
  165. // Requesting the Channel ID is only available on the receiver
  166. if(ucSimType == SIM_DISPLAY)
  167. {
  168. // Update Channel Parameters
  169. usMyDeviceNum = (USHORT) pcBuffer_[1] + ((USHORT) pcBuffer_[2] << 8);
  170. ucMyDeviceType = (UCHAR) pcBuffer_[3];
  171. ucMyTxType = (UCHAR) pcBuffer_[4];
  172. // Display Channel ID
  173. this->textBox_DeviceID->ReadOnly = FALSE;
  174. this->textBox_DeviceID->Text = System::Convert::ToString(usMyDeviceNum);
  175. this->textBox_DeviceID->ReadOnly = TRUE;
  176. this->textBox_DeviceType->ReadOnly = FALSE;
  177. this->textBox_DeviceType->Text = System::Convert::ToString(ucMyDeviceType);
  178. this->textBox_DeviceType->ReadOnly = TRUE;
  179. this->textBox_TransmissionType->ReadOnly = FALSE;
  180. this->textBox_TransmissionType->Text = System::Convert::ToString(ucMyTxType);
  181. this->textBox_TransmissionType->ReadOnly = TRUE;
  182. }
  183. }
  184. else if(ucMessageCode_ == MESG_RESPONSE_EVENT_ID)
  185. {
  186. // Check if this was a successful response.
  187. // Otherwise handle the error condition.
  188. if(pcBuffer_[2] == RESPONSE_NO_ERROR)
  189. {
  190. switch (pcBuffer_[1])
  191. {
  192. case MESG_ASSIGN_CHANNEL_ID:
  193. {
  194. if(eMyChannelState == STATE_CHANNEL_OPENING)
  195. {
  196. // Set RF Freq.
  197. ANTClass::SetChannelRFFreq(ucMyChannelNum, ANTPLUS_RF_FREQ);
  198. }
  199. else
  200. {
  201. System::Diagnostics::Debug::Assert(FALSE, "Invalid State");
  202. }
  203. break;
  204. }
  205. case MESG_UNASSIGN_CHANNEL_ID:
  206. {
  207. this->checkBox_TxEnable->Enabled = TRUE;
  208. break;
  209. }
  210. case MESG_CHANNEL_ID_ID:
  211. {
  212. if(eMyChannelState == STATE_CHANNEL_OPENING)
  213. {
  214. ANTClass::SetChannelPeriod(ucMyChannelNum, usMyMsgPeriod);
  215. }
  216. else
  217. {
  218. System::Diagnostics::Debug::Assert(FALSE, "Invalid State");
  219. }
  220. break;
  221. }
  222. case MESG_CHANNEL_MESG_PERIOD_ID:
  223. {
  224. if(eMyChannelState == STATE_CHANNEL_OPENING)
  225. {
  226. ANTClass::OpenChannel(ucMyChannelNum);
  227. }
  228. #ifdef INC_GEOCACHE
  229. else if(eMyChannelState == STATE_CHANNEL_OPEN)
  230. {
  231. // Do Nothing - this is the Response from the Dynamic Mesg Period change
  232. // specific to Geocache Profile ...
  233. }
  234. #endif // INC_GEOCACHE
  235. else
  236. {
  237. System::Diagnostics::Debug::Assert(FALSE, "Invalid State");
  238. }
  239. break;
  240. }
  241. case MESG_CHANNEL_RADIO_FREQ_ID:
  242. {
  243. if(eMyChannelState == STATE_CHANNEL_OPENING)
  244. {
  245. ANTClass::SetChannelId(ucMyChannelNum, usMyDeviceNum, ucMyDeviceType, ucMyTxType);
  246. }
  247. else
  248. {
  249. System::Diagnostics::Debug::Assert(FALSE, "Invalid State");
  250. }
  251. break;
  252. }
  253. case MESG_OPEN_CHANNEL_ID:
  254. {
  255. if(eMyChannelState == STATE_CHANNEL_OPENING)
  256. {
  257. eMyChannelState = STATE_CHANNEL_OPEN;
  258. UpdateRawTxDisplay("\nChannel Opened...", NULL);
  259. this->checkBox_TxEnable->Enabled = TRUE;
  260. if(ucSimType == SIM_SENSOR)
  261. {
  262. // Enable timer for sensor simulation
  263. this->timer_SimEvent->Enabled = TRUE;
  264. #ifdef INC_WEIGHT_SCALE
  265. if(comboBox_SimSelect->SelectedIndex == WEIGHT_SCALE)
  266. curSimulator->ANT_eventNotification(MESG_OPEN_CHANNEL_ID, NULL);
  267. #endif // INC_WEIGHT_SCALE
  268. }
  269. if(ucSimType == SIM_DISPLAY)
  270. {
  271. // Enable capability of obtaining channel ID of paired device on display devices
  272. this->button_getChannelID->Enabled = TRUE;
  273. #ifdef INC_GEOCACHE
  274. if(this->comboBox_SimSelect->SelectedIndex == GEOCACHE)
  275. {
  276. ANTClass::SetChannelSearchTimeout(ucMyChannelNum, 45); // !!! 45sec Search Timeout for Geocache Display !!!
  277. }
  278. #endif // INC_GEOCACHE
  279. }
  280. #ifdef INC_TEMPERATURE
  281. if(comboBox_SimSelect->SelectedIndex == TEMPERATURE)
  282. curSimulator->ANT_eventNotification(MESG_OPEN_CHANNEL_ID, NULL);
  283. #endif // INC_TEMPERATURE
  284. //Don't allow changes to channel configuration while channel is open
  285. this->checkBox_PairingOn->Enabled = FALSE;
  286. textBox_DeviceID->ReadOnly = TRUE;
  287. textBox_TransmissionType->ReadOnly = TRUE;
  288. #ifdef INC_CUSTOM
  289. if(this->comboBox_SimSelect->SelectedIndex == CUSTOM)
  290. {
  291. textBox_DeviceType->ReadOnly = TRUE;
  292. textBox_TransmissionType->ReadOnly = TRUE;
  293. textBox_TransmitPeriod->ReadOnly = TRUE;
  294. }
  295. #endif // INC_CUSTOM
  296. }
  297. else
  298. {
  299. System::Diagnostics::Debug::Assert(FALSE, "Invalid State");
  300. }
  301. break;
  302. }
  303. case MESG_CLOSE_CHANNEL_ID:
  304. {
  305. eMyChannelState = STATE_CHANNEL_CLOSED;
  306. timer_SimEvent->Enabled = FALSE;
  307. // Re-enable changes to the configuration
  308. textBox_DeviceID->ReadOnly = FALSE;
  309. textBox_TransmissionType->ReadOnly = FALSE;
  310. this->checkBox_PairingOn->Enabled = TRUE; // Start by default without setting the pairing bit
  311. this->checkBox_PairingOn->Checked = FALSE;
  312. bPairingBit = FALSE;
  313. #ifdef INC_CUSTOM
  314. if(this->comboBox_SimSelect->SelectedIndex == CUSTOM)
  315. {
  316. this->textBox_TransmissionType->ReadOnly = FALSE;
  317. this->textBox_TransmitPeriod->ReadOnly = FALSE;
  318. }
  319. #endif // INC_CUSTOM
  320. #ifdef INC_WEIGHT_SCALE
  321. if(this->comboBox_SimSelect->SelectedIndex == WEIGHT_SCALE)
  322. curSimulator->ANT_eventNotification(MESG_CLOSE_CHANNEL_ID, NULL);
  323. #endif // INC_WEIGHT_SCALE
  324. #ifdef INC_GEOCACHE
  325. if(this->comboBox_SimSelect->SelectedIndex == GEOCACHE)
  326. curSimulator->ANT_eventNotification(MESG_CLOSE_CHANNEL_ID, NULL);
  327. #endif // INC_GEOCACHE
  328. #ifdef INC_TEMPERATURE
  329. if(this->comboBox_SimSelect->SelectedIndex == TEMPERATURE)
  330. curSimulator->ANT_eventNotification(MESG_CLOSE_CHANNEL_ID, NULL);
  331. #endif // INC_TEMPERATURE
  332. break;
  333. }
  334. }
  335. }
  336. else
  337. {
  338. if(eMyChannelState == STATE_CHANNEL_OPENING)
  339. {
  340. ChannelOpenFailed();
  341. }
  342. if( pcBuffer_[2] == EVENT_COMMAND_TIMEOUT)
  343. {
  344. UpdateRawTxDisplay("\nCOMMAND TIMEOUT!!!!!", NULL);
  345. }
  346. }
  347. }
  348. }
  349. /**************************************************************************
  350. * ANTChannel::ANTChannelEvent
  351. *
  352. * Process ANT event
  353. * The display is updated accordingly, and the event is forwarded to
  354. * the simulator for device specific handling
  355. * !! IMPORTANT: only events defined here are processed by simulators
  356. *
  357. * ucEvent_: event code
  358. * pcBuffer_: pointer to buffer containing data received from ANT
  359. *
  360. * returns: N/A
  361. *
  362. **************************************************************************/
  363. void ANTChannel::ANTChannelEvent(UCHAR ucEvent_, UCHAR* pcBuffer_)
  364. {
  365. UCHAR ucBufferIndex = 1;
  366. switch(ucEvent_)
  367. {
  368. case EVENT_TX:
  369. {
  370. // Simulated sensors update the transmit buffer every message period
  371. if(ucSimType == SIM_SENSOR)
  372. {
  373. sendSimMsg();
  374. }
  375. break;
  376. }
  377. case EVENT_RX_BROADCAST:
  378. {
  379. UpdateRawTxDisplay("\nRX:", (UCHAR*) &pcBuffer_[ucBufferIndex]);
  380. // Forward to simulator for further processing
  381. curSimulator->ANT_eventNotification(ucEvent_, (UCHAR*) &pcBuffer_[ucBufferIndex]);
  382. break;
  383. }
  384. case EVENT_RX_SEARCH_TIMEOUT:
  385. {
  386. // This event should only take place on a receiver
  387. if(ucSimType == SIM_DISPLAY)
  388. {
  389. eMyChannelState = STATE_CHANNEL_CLOSED;
  390. this->checkBox_TxEnable->Checked = FALSE;
  391. this->checkBox_PairingOn->Enabled = TRUE;
  392. this->textBox_DeviceID->Enabled = TRUE;
  393. UpdateRawTxDisplay("\nReceiver Search Timeout", NULL);
  394. ANTClass::UnAssignChannel(ucMyChannelNum); // Necessary for ARCT functionality
  395. // the AP2 chip sends 2 commands on timeout: EVENT_RX_SEARCH_TIMEOUT AND EVENT_CHANNEL_CLOSED
  396. // beacuse the preceding line just unassigned the channel, for AP2, the EVENT_CHANNEL_CLOSED
  397. // will happen next and try to close / unassign an already unassigned channel. This flag prevents this.
  398. bAlreadyUnAssigned = TRUE;
  399. }
  400. break;
  401. }
  402. case EVENT_RX_ACKNOWLEDGED:
  403. {
  404. UpdateRawTxDisplay("\nRX Acknowledged Msg:\n ", (UCHAR*) &pcBuffer_[1]);
  405. // Forward to simulator for further processing
  406. curSimulator->ANT_eventNotification(ucEvent_, (UCHAR*) &pcBuffer_[1]);
  407. break;
  408. }
  409. case EVENT_RX_FAIL:
  410. {
  411. UpdateRawTxDisplay("\nRX Failure!", NULL);
  412. // Forward to simulator for further processing
  413. curSimulator->ANT_eventNotification(ucEvent_, pcBuffer_);
  414. break;
  415. }
  416. case EVENT_TRANSFER_TX_COMPLETED:
  417. {
  418. UpdateRawTxDisplay("\nTX Success!", NULL);
  419. // Forward to simulator for further processing
  420. curSimulator->ANT_eventNotification(ucEvent_, pcBuffer_);
  421. break;
  422. }
  423. case EVENT_TRANSFER_TX_FAILED:
  424. {
  425. UpdateRawTxDisplay("\nTX Failure!", NULL);
  426. // Forward to simulator for further processing
  427. curSimulator->ANT_eventNotification(ucEvent_, pcBuffer_);
  428. break;
  429. }
  430. case EVENT_CHANNEL_CLOSED:
  431. {
  432. if (bAlreadyUnAssigned == FALSE) // only unassign the channel if it is not already done
  433. ANTClass::UnAssignChannel(ucMyChannelNum);
  434. UpdateRawTxDisplay("\n...Channel Closed", NULL);
  435. bAlreadyUnAssigned = FALSE; // reset the flag
  436. break;
  437. }
  438. case EVENT_RX_FAIL_GO_TO_SEARCH:
  439. {
  440. // This event should only take place on a receiver
  441. if(ucSimType == SIM_DISPLAY)
  442. {
  443. UpdateRawTxDisplay("\nRepeated RX Failure,\nSearching for Signal...", NULL);
  444. }
  445. break;
  446. }
  447. case EVENT_ACK_TIMEOUT:
  448. {
  449. UpdateRawTxDisplay("Ack timeout...", NULL);
  450. // Forward to simulator for further processing
  451. // Only forward to receivers, as a master would get an EVENT_TRANSFER_TX_FAILED instead
  452. if(ucSimType == SIM_DISPLAY)
  453. {
  454. curSimulator->ANT_eventNotification(ucEvent_, NULL);
  455. }
  456. break;
  457. }
  458. default:
  459. {
  460. // Look up event in table
  461. int iIndex = Array::IndexOf(ANTEventTable::aucCode, ucEvent_);
  462. if(iIndex >=0 && iIndex < ANTEventTable::aucCode->Length)
  463. UpdateRawTxDisplay(String::Concat("\nEvent: ", ANTEventTable::aucDescr[iIndex]), NULL);
  464. else
  465. UpdateRawTxDisplay(String::Concat("\nUnknown Event:", System::Convert::ToString(ucEvent_)), NULL);
  466. break;
  467. }
  468. }
  469. }
  470. /**************************************************************************
  471. * ANTChannel::sendSimMsg
  472. *
  473. * Handle update of transmit buffer every message period, and
  474. * transmission of broadcast message
  475. * Only performed in sensor simulators
  476. * The pointer to the transmit buffer is provided to the simulator
  477. * specific ANT event handler so that it can be updated
  478. *
  479. * returns: N/A
  480. *
  481. **************************************************************************/
  482. void ANTChannel::sendSimMsg()
  483. {
  484. UCHAR aucTxBuffer[8] = {0,0,0,0,0,0,0,0};
  485. if(eMyChannelState == STATE_CHANNEL_OPEN && ucSimType == SIM_SENSOR)
  486. {
  487. // Call simulator to update transmit buffer
  488. curSimulator->ANT_eventNotification(EVENT_TX, aucTxBuffer);
  489. {
  490. // Update display
  491. UpdateRawTxDisplay("\nTX:", (UCHAR*) aucTxBuffer);
  492. // Send broadcast data
  493. ANTClass::SendBroadcastData(ucMyChannelNum, (UCHAR*) aucTxBuffer);
  494. }
  495. }
  496. }
  497. /**************************************************************************
  498. * ANTChannel::updateMesgPeriod
  499. *
  500. * Allows simulators to update message period on demand
  501. *
  502. * usMesgRate_: new message period
  503. *
  504. * returns: N/A
  505. *
  506. **************************************************************************/
  507. void ANTChannel::updateMesgPeriod(USHORT usMesgPeriod_)
  508. {
  509. // Update display
  510. UpdateRawTxDisplay(String::Concat("\nMessage Period Changed: ", usMesgPeriod_.ToString()), NULL);
  511. // Update Message Period
  512. usMyMsgPeriod = usMesgPeriod_;
  513. ANTClass::SetChannelPeriod(ucMyChannelNum, usMyMsgPeriod);
  514. }
  515. /**************************************************************************
  516. * ANTChannel::sendAckMsg
  517. *
  518. * Allows simulators to send acknowledged messages on demand
  519. *
  520. * pucTxBuffer_: pointer to buffer containing data to send
  521. *
  522. * returns: N/A
  523. *
  524. **************************************************************************/
  525. void ANTChannel::sendAckMsg(UCHAR* pucTxBuffer_)
  526. {
  527. USHORT usAckTimeout = (USHORT) (((ULONG) usMyMsgPeriod * 1000)/32768); // Timeout = 1 message period
  528. if(pucTxBuffer_)
  529. {
  530. // Update display
  531. UpdateRawTxDisplay("\nTX Acknowledged Msg:\n ", (UCHAR*) pucTxBuffer_);
  532. // Send acknowledged data
  533. if(ucSimType == SIM_DISPLAY)
  534. ANTClass::SendAcknowledgedData(ucMyChannelNum, (UCHAR*) pucTxBuffer_, usAckTimeout); // Timeout only required for receiver
  535. else if(ucSimType == SIM_SENSOR)
  536. ANTClass::SendAcknowledgedData(ucMyChannelNum, (UCHAR*) pucTxBuffer_);
  537. }
  538. }
  539. /**************************************************************************
  540. * ANTChannel::sendBroadcastMsg
  541. *
  542. * Allows simulators to send broadcast messages on demand
  543. * Used in display simulators when sending responses to received messages
  544. *
  545. * pucTxBuffer_: pointer to buffer containing data to send
  546. *
  547. * returns: N/A
  548. *
  549. **************************************************************************/
  550. void ANTChannel::sendBroadcastMsg(UCHAR* pucTxBuffer_)
  551. {
  552. if(pucTxBuffer_)
  553. {
  554. // Update display
  555. UpdateRawTxDisplay("\nTX:", (UCHAR*) pucTxBuffer_);
  556. // Send broadcast data
  557. ANTClass::SendBroadcastData(ucMyChannelNum, (UCHAR*) pucTxBuffer_);
  558. }
  559. }
  560. /**************************************************************************
  561. * ANTChannel::timer_SimEvent_Tick
  562. *
  563. * Called every timer event, for event driven simulators (sensors)
  564. * The timer interval is updated after updating device specific simulated
  565. * data
  566. *
  567. * returns: N/A
  568. *
  569. **************************************************************************/
  570. System::Void ANTChannel::timer_SimEvent_Tick(System::Object^ sender, System::Timers::ElapsedEventArgs^ e)
  571. {
  572. if(eMyChannelState == STATE_CHANNEL_OPEN && ucSimType == SIM_SENSOR)
  573. {
  574. // Update current event time (for display purposes)
  575. dCurEventTime += timer_SimEvent->Interval;
  576. this->label_TxTimeDisplay->Text = System::TimeSpan::FromSeconds(System::Math::Round(dCurEventTime/1000)).ToString();
  577. // Simulator specific event-driven behavior
  578. curSimulator->onTimerTock((USHORT) dCurEventTime);
  579. // Update timer interval (as per simulator)
  580. this->timer_SimEvent->Interval = curSimulator->getTimerInterval();
  581. }
  582. }
  583. /**************************************************************************
  584. * ANTChannel::UpdateRawTxDisplay
  585. *
  586. * Displays current event in raw box
  587. *
  588. * strLabel_: label identifying the event
  589. * pucBuffer_: pointer to buffer with data to display
  590. *
  591. * returns: N/A
  592. *
  593. **************************************************************************/
  594. System::Void ANTChannel::UpdateRawTxDisplay(System::String^ strLabel_, UCHAR* pucBuffer_)
  595. {
  596. UCHAR i;
  597. richTextBox_RawTxDisplay->AppendText(strLabel_);
  598. if(pucBuffer_)
  599. {
  600. for(i=0; i<8; ++i)
  601. {
  602. if(bDisplayHex)
  603. {
  604. System::String^ strTemp = System::Convert::ToString(pucBuffer_[i], 16);
  605. if(strTemp->Length == 1)
  606. richTextBox_RawTxDisplay->AppendText(System::String::Concat("[","0",strTemp, "]"));
  607. else
  608. richTextBox_RawTxDisplay->AppendText(System::String::Concat("[",strTemp, "]"));
  609. }
  610. else
  611. {
  612. richTextBox_RawTxDisplay->AppendText(System::String::Concat("[", pucBuffer_[i], "]"));
  613. }
  614. }
  615. }
  616. }
  617. /**************************************************************************
  618. * ANTChannel::button_Clear_Click
  619. *
  620. * Clears raw text box
  621. *
  622. * returns: N/A
  623. *
  624. **************************************************************************/
  625. System::Void ANTChannel::button_Clear_Click(System::Object^ sender, System::EventArgs^ e)
  626. {
  627. richTextBox_RawTxDisplay->Text ="";
  628. }
  629. /**************************************************************************
  630. * ANTChannel::checkBox_TxEnable_CheckedChanged
  631. *
  632. * Opens and closes the channel, as selected by the user
  633. *
  634. * returns: N/A
  635. *
  636. **************************************************************************/
  637. System::Void ANTChannel::checkBox_TxEnable_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
  638. {
  639. // Return if value of checkbox was changed internally and not by the user
  640. if(bMyCheckInternalRaise)
  641. {
  642. bMyCheckInternalRaise = FALSE;
  643. return;
  644. }
  645. // Disable changes while performing checks
  646. this->checkBox_TxEnable->Enabled = FALSE;
  647. if(!curSimulator)
  648. {
  649. // Disable opening the channel if no simulator was loaded
  650. bMyCheckInternalRaise=TRUE;
  651. this->checkBox_TxEnable->Checked = FALSE;
  652. this->checkBox_TxEnable->Enabled = TRUE;
  653. UpdateRawTxDisplay("\nChoose Simulator First ...", NULL);
  654. }
  655. else if(checkBox_TxEnable->Checked && curSimulator)
  656. {
  657. // Check channel parameters are valid (in case they were modified by the user)
  658. if(!ValidateChannelID())
  659. {
  660. // Return if channel parameters are incorrect
  661. UpdateRawTxDisplay("\nChannel Setup Failed: Bad Channel Parameters", NULL);
  662. bMyCheckInternalRaise = TRUE;
  663. this->checkBox_TxEnable->Checked = FALSE;
  664. this->checkBox_TxEnable->Enabled = TRUE;
  665. eMyChannelState = STATE_CHANNEL_CLOSED;
  666. return;
  667. }
  668. switch(ucSimType)
  669. {
  670. // Open Channel
  671. case SIM_SENSOR:
  672. OpenChannel(PARAMETER_TX_NOT_RX);
  673. break;
  674. case SIM_DISPLAY:
  675. OpenChannel(PARAMETER_RX_NOT_TX);
  676. break;
  677. default:
  678. eMyChannelState = STATE_CHANNEL_CLOSED;
  679. break;
  680. }
  681. // Reassert the TX Power level in case the user selected
  682. comboBox_TxPowerSelect_SelectedIndexChanged(sender, e);
  683. }
  684. else
  685. {
  686. if(eMyChannelState == STATE_CHANNEL_OPEN)
  687. {
  688. // Only close if channel was previously open
  689. ANTClass::CloseChannel(ucMyChannelNum);
  690. }
  691. }
  692. }
  693. /**************************************************************************
  694. * ANTChannel::comboBox_SimSelect_SelectedIndexChanged
  695. *
  696. * Handles selection of simulator to load.
  697. * Selecting the same simulator will cause it to reload, resetting to
  698. * initial values
  699. *
  700. * returns: N/A
  701. *
  702. **************************************************************************/
  703. System::Void ANTChannel::comboBox_SimSelect_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e) {
  704. //Delete last simulator
  705. if(curSimulator)
  706. delete curSimulator;
  707. // By default, unset pairing bit
  708. this->checkBox_PairingOn->Checked = FALSE;
  709. bPairingBit = FALSE;
  710. // Reset simulation timer
  711. dCurEventTime = 0;
  712. if(SIM_SENSOR)
  713. {
  714. this->label_TxTimeDisplay->Text = "0";
  715. }
  716. // Load simulator
  717. switch(comboBox_SimSelect->SelectedIndex)
  718. {
  719. #ifdef INC_HRM
  720. case HEART_RATE_MONITOR:
  721. switch(ucSimType)
  722. {
  723. #ifdef SIM_TX
  724. case SIM_SENSOR:
  725. curSimulator = gcnew HRMSensor(timer_SimEvent);
  726. break;
  727. #endif // SIM_TX
  728. #ifdef SIM_RX
  729. case SIM_DISPLAY:
  730. curSimulator = gcnew HRMDisplay();
  731. break;
  732. #endif // SIM_RX
  733. default:
  734. break;
  735. }
  736. break;
  737. #endif // INC_HRM
  738. #ifdef INC_SDM
  739. case SPEED_DISTANCE_MONITOR:
  740. switch(ucSimType)
  741. {
  742. #ifdef SIM_TX
  743. case SIM_SENSOR:
  744. curSimulator = gcnew SDMSensor(timer_SimEvent,gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg));
  745. break;
  746. #endif // SIM_TX
  747. #ifdef SIM_RX
  748. case SIM_DISPLAY:
  749. curSimulator = gcnew SDMDisplay(gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg)); // modified to add Tx
  750. break;
  751. #endif // SIM_RX
  752. default:
  753. break;
  754. }
  755. break;
  756. #endif // INC_HRM
  757. #ifdef INC_BIKE_POWER
  758. case BIKE_POWER:
  759. switch(ucSimType)
  760. {
  761. #ifdef SIM_TX
  762. case SIM_SENSOR:
  763. curSimulator = gcnew BikePowerSensor(timer_SimEvent, gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg));
  764. break;
  765. #endif // SIM_TX
  766. #ifdef SIM_RX
  767. case SIM_DISPLAY:
  768. curSimulator = gcnew BikePowerDisplay(gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg));
  769. break;
  770. #endif // SIM_RX
  771. default:
  772. break;
  773. }
  774. break;
  775. #endif // INC_BIKE_POWER
  776. #ifdef INC_BIKE_SPEED_CADENCE
  777. case BIKE_SPDCAD:
  778. switch(ucSimType)
  779. {
  780. #ifdef SIM_TX
  781. case SIM_SENSOR:
  782. curSimulator = gcnew BikeSpdCadSensor(timer_SimEvent);
  783. break;
  784. #endif // SIM_TX
  785. #ifdef SIM_RX
  786. case SIM_DISPLAY:
  787. curSimulator = gcnew BikeSpdCadDisplay();
  788. break;
  789. #endif // SIM_RX
  790. default:
  791. break;
  792. }
  793. break;
  794. #endif // INC_BIKE_SPEED_CADENCE
  795. #ifdef INC_BIKE_CADENCE
  796. case BIKE_CADENCE:
  797. switch(ucSimType)
  798. {
  799. #ifdef SIM_TX
  800. case SIM_SENSOR:
  801. curSimulator = gcnew BikeCadenceSensor(timer_SimEvent);
  802. break;
  803. #endif // SIM_TX
  804. #ifdef SIM_RX
  805. case SIM_DISPLAY:
  806. curSimulator = gcnew BikeCadenceDisplay();
  807. #endif // SIM_RX
  808. default:
  809. break;
  810. }
  811. break;
  812. #endif // BIKE_CADENCE
  813. #ifdef INC_BIKE_SPEED
  814. case BIKE_SPEED:
  815. switch(ucSimType)
  816. {
  817. #ifdef SIM_TX
  818. case SIM_SENSOR:
  819. curSimulator = gcnew BikeSpeedSensor(timer_SimEvent);
  820. break;
  821. #endif // SIM_TX
  822. #ifdef SIM_RX
  823. case SIM_DISPLAY:
  824. curSimulator = gcnew BikeSpeedDisplay();
  825. break;
  826. #endif // SIM_RX
  827. default:
  828. break;
  829. }
  830. break;
  831. #endif // INC_BIKE_SPEED
  832. #ifdef INC_WEIGHT_SCALE
  833. case WEIGHT_SCALE:
  834. switch(ucSimType)
  835. {
  836. #ifdef SIM_TX
  837. case SIM_SENSOR:
  838. curSimulator = gcnew WeightScaleSensor(timer_SimEvent);
  839. break;
  840. #endif // SIM_TX
  841. #ifdef SIM_RX
  842. case SIM_DISPLAY:
  843. curSimulator = gcnew WeightScaleDisplay(gcnew dRequestBcastMsg(this,&ANTChannel::sendBroadcastMsg));
  844. break;
  845. #endif // SIM_RX
  846. default:
  847. break;
  848. }
  849. break;
  850. #endif //INC_WEIGHT_SCALE
  851. #ifdef INC_MSM
  852. case MULTISPORT_SPEED_DISTANCE:
  853. switch(ucSimType)
  854. {
  855. #ifdef SIM_TX
  856. case SIM_SENSOR:
  857. curSimulator = gcnew MSMSensor(timer_SimEvent, gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg));
  858. break;
  859. #endif // SIM_TX
  860. #ifdef SIM_RX
  861. case SIM_DISPLAY:
  862. curSimulator = gcnew MSMDisplay(gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg));
  863. break;
  864. #endif // SIM_RX
  865. default:
  866. break;
  867. }
  868. break;
  869. #endif //INC_MSM
  870. #ifdef INC_LEV
  871. case LIGHT_ELECTRIC_VEHICLE:
  872. switch(ucSimType)
  873. {
  874. #ifdef SIM_TX
  875. case SIM_SENSOR:
  876. curSimulator = gcnew LEVSensor(timer_SimEvent, gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg));
  877. break;
  878. #endif // SIM_TX
  879. #ifdef SIM_RX
  880. case SIM_DISPLAY:
  881. curSimulator = gcnew LEVDisplay(gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg), gcnew dRequestBcastMsg(this,&ANTChannel::sendBroadcastMsg));
  882. break;
  883. #endif // SIM_RX
  884. default:
  885. break;
  886. }
  887. break;
  888. #endif //INC_LEV
  889. #ifdef INC_GEOCACHE
  890. case GEOCACHE:
  891. switch(ucSimType)
  892. {
  893. #ifdef SIM_TX
  894. case SIM_SENSOR:
  895. curSimulator = gcnew GeocacheSensor(timer_SimEvent, gcnew dRequestAckMsg(this, &ANTChannel::sendAckMsg), gcnew dRequestUpdateMesgPeriod(this, &ANTChannel::updateMesgPeriod));
  896. break;
  897. #endif // SIM_TX
  898. #ifdef SIM_RX
  899. case SIM_DISPLAY:
  900. curSimulator = gcnew GeocacheDisplay(timer_SimEvent, gcnew dRequestAckMsg(this, &ANTChannel::sendAckMsg), gcnew dRequestBcastMsg(this, &ANTChannel::sendBroadcastMsg));
  901. break;
  902. #endif // SIM_RX
  903. default:
  904. break;
  905. }
  906. break;
  907. #endif //INC_GEOCACHE
  908. #ifdef INC_RACQUET
  909. case RACQUET:
  910. switch(ucSimType)
  911. {
  912. #ifdef SIM_TX
  913. case SIM_SENSOR:
  914. curSimulator = gcnew RacquetSensor(timer_SimEvent, gcnew dRequestAckMsg(this, &ANTChannel::sendAckMsg));
  915. break;
  916. #endif // SIM_TX
  917. #ifdef SIM_RX
  918. case SIM_DISPLAY:
  919. curSimulator = gcnew RacquetDisplay(timer_SimEvent, gcnew dRequestAckMsg(this, &ANTChannel::sendAckMsg), gcnew dRequestBcastMsg(this, &ANTChannel::sendBroadcastMsg));
  920. break;
  921. #endif // SIM_RX
  922. default:
  923. break;
  924. }
  925. break;
  926. #endif // INC_RACQUET
  927. #ifdef INC_TEMPERATURE
  928. case TEMPERATURE:
  929. switch(ucSimType)
  930. {
  931. #ifdef SIM_TX
  932. case SIM_SENSOR:
  933. curSimulator = gcnew TemperatureSensor(timer_SimEvent, gcnew dRequestUpdateMesgPeriod(this, &ANTChannel::updateMesgPeriod));
  934. break;
  935. #endif // SIM_TX
  936. #ifdef SIM_RX
  937. case SIM_DISPLAY:
  938. curSimulator = gcnew TemperatureDisplay(timer_SimEvent, gcnew dRequestAckMsg(this, &ANTChannel::sendAckMsg), gcnew dRequestUpdateMesgPeriod(this, &ANTChannel::updateMesgPeriod));
  939. break;
  940. #endif // SIM_RX
  941. default:
  942. break;
  943. }
  944. break;
  945. #endif // INC_TEMPERATURE
  946. #ifdef INC_CUSTOM
  947. case CUSTOM:
  948. switch(ucSimType)
  949. {
  950. #ifdef SIM_TX
  951. case SIM_SENSOR:
  952. curSimulator = gcnew CustomSensor(timer_SimEvent, gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg));
  953. break;
  954. #endif // SIM_TX
  955. #ifdef SIM_RX
  956. case SIM_DISPLAY:
  957. curSimulator = gcnew CustomDisplay(gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg));
  958. break;
  959. #endif // SIM_RX
  960. default:
  961. break;
  962. }
  963. break;
  964. #endif // INC_CUSTOM
  965. default:
  966. return;
  967. }
  968. // Obtain channel parameters from simulator
  969. ucMyDeviceType = curSimulator->getDeviceType();
  970. ucMyTxType = curSimulator->getTransmissionType();
  971. usMyMsgPeriod = curSimulator->getTransmitPeriod();
  972. // Update display of channel parameters
  973. this->textBox_DeviceType->Text = ucMyDeviceType.ToString();
  974. this->textBox_DeviceType->ReadOnly = TRUE;
  975. this->textBox_TransmissionType->Text = ucMyTxType.ToString();
  976. this->textBox_TransmitPeriod->Text = usMyMsgPeriod.ToString();
  977. this->textBox_TransmitPeriod->ReadOnly = TRUE;
  978. this->tabPage_ChannelTab->Controls->Add(curSimulator->getSimSettingsPanel());
  979. this->tabPage_ChannelTab->Controls->Add(curSimulator->getSimTranslatedDisplay());
  980. // Ensure channel is closed
  981. this->checkBox_TxEnable->Checked = FALSE;
  982. eMyChannelState = STATE_CHANNEL_CLOSED;
  983. if(ucSimType == SIM_SENSOR)
  984. {
  985. this->timer_SimEvent->Interval = curSimulator->getTimerInterval();
  986. }
  987. }
  988. /**************************************************************************
  989. * ANTChannel::checkBox_PairingOn_CheckedChange
  990. *
  991. * Enables/disables pairing bit, per user input (GUI)
  992. *
  993. * returns: N/A
  994. *
  995. **************************************************************************/
  996. System::Void ANTChannel::checkBox_PairingOn_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
  997. {
  998. if(this->checkBox_PairingOn->Checked)
  999. {
  1000. bPairingBit = TRUE;
  1001. }
  1002. else
  1003. {
  1004. bPairingBit = FALSE;
  1005. }
  1006. SetPairingBit();
  1007. }
  1008. /**************************************************************************
  1009. * ANTChannel::checkBox_DisplayAsHex_CheckedChanged
  1010. *
  1011. * Selects whether data is displayed as hex or decimal, per user input (GUI)
  1012. *
  1013. * returns: N/A
  1014. *
  1015. **************************************************************************/
  1016. System::Void ANTChannel::checkBox_DisplayAsHex_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
  1017. {
  1018. if(this->checkBox_DisplayAsHex->Checked)
  1019. {
  1020. bDisplayHex = TRUE;
  1021. }
  1022. else
  1023. {
  1024. bDisplayHex = FALSE;
  1025. }
  1026. }
  1027. /**************************************************************************
  1028. * ANTChannel::button_getChannelID_Click
  1029. *
  1030. * Requests channel ID
  1031. *
  1032. * returns: N/A
  1033. *
  1034. **************************************************************************/
  1035. System::Void ANTChannel::button_getChannelID_Click(System::Object^ sender, System::EventArgs^ e) {
  1036. // Request Device Number of device we are pairing to, response is handled in main function that handles incoming events
  1037. if(ucSimType == SIM_DISPLAY)
  1038. {
  1039. ANTClass::RequestMessage(ucMyChannelNum, MESG_CHANNEL_ID_ID);
  1040. }
  1041. }
  1042. /**************************************************************************
  1043. * ValidateChannelID
  1044. *
  1045. * Validates input boxes for Channel ID and Message Period
  1046. *
  1047. * returns: TRUE if the parameters are valid
  1048. *
  1049. **************************************************************************/
  1050. BOOL ANTChannel::ValidateChannelID()
  1051. {
  1052. BOOL bSuccess = TRUE;
  1053. try
  1054. {
  1055. ucMyDeviceType = System::Convert::ToByte(this->textBox_DeviceType->Text);
  1056. ucMyTxType = System::Convert::ToByte(this->textBox_TransmissionType->Text);
  1057. usMyDeviceNum = System::Convert::ToUInt16(this->textBox_DeviceID->Text);
  1058. usMyMsgPeriod = System::Convert::ToUInt16(this->textBox_TransmitPeriod->Text);
  1059. SetPairingBit();
  1060. }
  1061. catch(...)
  1062. {
  1063. bSuccess = FALSE;
  1064. //MessageBox::Show("Invalid Input", "Invalid Channel Parameters", MessageBoxButtons::OK,MessageBoxIcon::Error, MessageBoxDefaultButton::Button1);
  1065. }
  1066. return bSuccess;
  1067. }
  1068. /**************************************************************************
  1069. * SetPairingBit
  1070. *
  1071. * Sets/unsets pairing bit in Channel ID
  1072. *
  1073. * returns: N/A
  1074. *
  1075. **************************************************************************/
  1076. void ANTChannel::SetPairingBit()
  1077. {
  1078. if(bPairingBit)
  1079. ucMyDeviceType |= 0x80; // set pairing bit
  1080. else
  1081. ucMyDeviceType &= ~0x80; // clear pairing bit
  1082. // Update text box
  1083. //this->textBox_DeviceType->Text = System::Convert::ToString(ucMyDeviceType);
  1084. }
  1085. /**************************************************************************
  1086. * OpenChannel
  1087. *
  1088. * Initiates the opening of a channel by setting the proper state and sending
  1089. * an assign channel command.
  1090. *
  1091. * Params:
  1092. *
  1093. * ucChannelType_: ANT Channel type as either MASTER (0x10) or SLAVE (0x00)
  1094. *
  1095. * returns: TRUE if the parameters are valid
  1096. *
  1097. **************************************************************************/
  1098. BOOL ANTChannel::OpenChannel(UCHAR ucChannelType_)
  1099. {
  1100. //!! Verify input parameters
  1101. eMyChannelState = STATE_CHANNEL_OPENING;
  1102. ANTClass::AssignChannel(ucMyChannelNum, ucChannelType_, ANTPLUS_NETWORK_NUMBER);
  1103. return TRUE;
  1104. }
  1105. /**************************************************************************
  1106. * ChannelOpenFailed
  1107. *
  1108. * Called when opening of the ANT channel fails. Resets the proper state
  1109. * variables and displays error message.
  1110. *
  1111. * returns: N/A
  1112. *
  1113. **************************************************************************/
  1114. void ANTChannel::ChannelOpenFailed()
  1115. {
  1116. UpdateRawTxDisplay("\nChannel Setup Failed", NULL);
  1117. bMyCheckInternalRaise = TRUE;
  1118. checkBox_TxEnable->Checked = FALSE;
  1119. checkBox_TxEnable->Enabled = TRUE;
  1120. eMyChannelState = STATE_CHANNEL_CLOSED;
  1121. }
  1122. /**************************************************************************
  1123. * comboBox_TxPowerSelect_SelectedIndexChanged
  1124. *
  1125. * User may change TxPower level if desired before opening channel. If
  1126. * device reports PER_CHANNEL_TX_POWER the SetChannelTXPower() command
  1127. * is used affecting . Otherwise SetTransmitPower command is used and
  1128. * all channel tabs must be updated.
  1129. *
  1130. * returns: N/A
  1131. *
  1132. **************************************************************************/
  1133. System::Void ANTChannel::comboBox_TxPowerSelect_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e)
  1134. {
  1135. UCHAR ucNewPower;
  1136. ucNewPower = this->comboBox_TxPowerSelect->SelectedIndex;
  1137. // Only generate commands in response to user events, not init or other programmatic changes to index
  1138. if (bTXPowerUIEnabled == TRUE)
  1139. {
  1140. // Assert the new power
  1141. // Use Per Channel TX Power command if possible
  1142. if (sMyCapabilities.ucAdvancedOptions & CAPABILITIES_PER_CHANNEL_TX_POWER_ENABLED)
  1143. {
  1144. ANTClass::SetChannelTxPower(ucMyChannelNum, ucNewPower);
  1145. }
  1146. else
  1147. {
  1148. ANTClass::SetTransmitPower(ucNewPower);
  1149. ANTChannel::iTheTXPowerLevel = ucNewPower;
  1150. }
  1151. }
  1152. }
  1153. /**************************************************************************
  1154. * tabPage_ChannelTab_Enter
  1155. *
  1156. * Update the TX Power dropdown if needed. This could be caused if both the
  1157. * Channel TX Power Command is not supported and the user may have adjusted
  1158. * the TX Power on another channel.
  1159. *
  1160. * returns: N/A
  1161. *
  1162. **************************************************************************/
  1163. System::Void ANTChannel::tabPage_ChannelTab_Enter(System::Object^ sender, System::EventArgs^ e)
  1164. {
  1165. // Are we using the global TX Power Command (=>per channel not supported)?
  1166. if (~sMyCapabilities.ucAdvancedOptions & CAPABILITIES_PER_CHANNEL_TX_POWER_ENABLED)
  1167. {
  1168. // Has another channel changed the power level?
  1169. if (this->comboBox_TxPowerSelect->SelectedIndex != ANTChannel::iTheTXPowerLevel)
  1170. {
  1171. // Disable the TX Power Select Dropdown handler and update the index
  1172. bTXPowerUIEnabled = FALSE;
  1173. this->comboBox_TxPowerSelect->SelectedIndex = ANTChannel::iTheTXPowerLevel;
  1174. bTXPowerUIEnabled = TRUE;
  1175. }
  1176. }
  1177. }