1 // ********************************************************************* 2 // Custom DPA Handler code example - Standard Sensors - Template * 3 // ********************************************************************* 4 // Copyright (c) IQRF Tech s.r.o. 5 // 6 // File: $RCSfile: 1402_Sensor-Template.c,v $ 7 // Version: $Revision: 1.21 $ 8 // Date: $Date: 2019/03/21 13:40:34 $ 9 // 10 // Revision history: 11 // 2018/10/25 Release for DPA 3.03 12 // 2017/11/16 Release for DPA 3.02 13 // 2017/08/14 Release for DPA 3.01 14 // 15 // ********************************************************************* 16 17 // Online DPA documentation http://www.iqrf.org/DpaTechGuide/ 18 // IQRF Standards documentation https://www.iqrfalliance.org/techDocs/ 19 20 // This example implements 6 sensors according to the IQRF Sensors standard. The example does not implement writing data to the sensors. 21 22 // Default IQRF include (modify the path according to your setup) 23 #include "IQRF.h" 24 25 // Uncomment to implement Custom DPA Handler for Coordinator 26 //#define COORDINATOR_CUSTOM_HANDLER 27 28 // Default DPA header (modify the path according to your setup) 29 #include "DPA.h" 30 // Default Custom DPA Handler header (modify the path according to your setup) 31 #include "DPAcustomHandler.h" 32 // IQRF standards header (modify the path according to your setup) 33 #include "IQRFstandard.h" 34 #include "IQRF_HWPID.h" 35 36 //############################################################################################ 37 38 // Number of implemented sensors 39 #define SENSORS_COUNT 7 40 41 // Variables to store sensor value at Get?_????() methods. 42 uns16 sensorValue @ param3; 43 uns16 sensorValueHighWord @ param4; 44 45 // Reads sensor value to the sensorValue variable and to responseFRCvalue(2B,4B) variable(s) based on FR command @ _PCMD 46 // Returns TRUE if the FRC is prepared 47 bit Get0_Temperature(); 48 bit Get1_CO2(); 49 bit Get2_VOC(); 50 bit Get3_Humidity(); 51 bit Get4_Binary7(); 52 bit Get5_DataBlock(); 53 bit Get6_Binary30(); 54 55 // Stores sensor value byte(s) to the FSR1[+1...], in case of PCMD_STD_SENSORS_READ_TYPES_AND_VALUES sensor type is stored before value byte(s) 56 void StoreValue( uns8 sensorType ); 57 58 // FRC parameter 59 uns8 sensorIndexAndData; 60 61 // Must be the 1st defined function in the source code in order to be placed at the correct FLASH location! 62 //############################################################################################ 63 bit CustomDpaHandler() 64 //############################################################################################ 65 { 66 // This forces CC5X to wisely use MOVLB instructions (doc says: The 'default' bank is used by the compiler for loops and labels when the algorithm gives up finding the optimal choice) 67 #pragma updateBank default = UserBank_01 68 69 // Handler presence mark 70 clrwdt(); 71 72 // Sleeping parameters, valid when Time != 0 73 static TPerOSSleep_Request PerOSSleep_Request; 74 75 // Detect DPA event to handle 76 switch ( GetDpaEvent() ) 77 { 78 // ------------------------------------------------- 79 case DpaEvent_Interrupt: 80 // Do an extra quick background interrupt work 81 // ! The time spent handling this event is critical.If there is no interrupt to handle return immediately otherwise keep the code as fast as possible. 82 // ! Make sure the event is the 1st case in the main switch statement at the handler routine.This ensures that the event is handled as the 1st one. 83 // ! It is desirable that this event is handled with immediate return even if it is not used by the custom handler because the Interrupt event is raised on every MCU interrupt and the “empty” return handler ensures the shortest possible interrupt routine response time. 84 // ! Only global variables or local ones marked by static keyword can be used to allow reentrancy. 85 // ! Make sure race condition does not occur when accessing those variables at other places. 86 // ! Make sure( inspect.lst file generated by C compiler ) compiler does not create any hidden temporary local variable( occurs when using division, multiplication or bit shifts ) at the event handler code.The name of such variable is usually Cnumbercnt. 87 // ! Do not call any OS functions except setINDFx(). 88 // ! Do not use any OS variables especially for writing access. 89 // ! All above rules apply also to any other function being called from the event handler code, although calling any function from Interrupt event is not recommended because of additional MCU stack usage. 90 return Carry; 91 92 // ------------------------------------------------- 93 case DpaEvent_Idle: 94 // Do a quick background work when RF packet is not received 95 96 // Should go to sleep? 97 if ( PerOSSleep_Request.Time != 0 ) 98 { 99 // Copy sleep parameters to the DPA request 100 _DpaMessage.PerOSSleep_Request.Time = PerOSSleep_Request.Time; 101 _DpaMessage.PerOSSleep_Request.Control = PerOSSleep_Request.Control; 102 // Switch off sleeping time=flag 103 PerOSSleep_Request.Time = 0; 104 // Finalize OS Sleep DPA Request 105 _DpaDataLength = sizeof( _DpaMessage.PerOSSleep_Request ); 106 _PNUM = PNUM_OS; 107 _PCMD = CMD_OS_SLEEP; 108 // Perform local DPA Request to go to sleep 109 DpaApiLocalRequest(); 110 } 111 break; 112 113 // ------------------------------------------------- 114 case DpaEvent_DpaRequest: 115 // Called to interpret DPA request for peripherals 116 // ------------------------------------------------- 117 // Peripheral enumeration 118 if ( IsDpaEnumPeripheralsRequest() ) 119 { 120 // We implement 1 standard peripheral 121 _DpaMessage.EnumPeripheralsAnswer.UserPerNr = 1; 122 FlagUserPer( _DpaMessage.EnumPeripheralsAnswer.UserPer, PNUM_STD_SENSORS ); 123 // ToDo: use actual IQRF Alliance allocated HWPID and current version of this handler 124 _DpaMessage.EnumPeripheralsAnswer.HWPID = HWPID_IQRF_TECH__DEMO_SENSOR_TEMPLATE; 125 _DpaMessage.EnumPeripheralsAnswer.HWPIDver = 0x0002; 126 127 DpaHandleReturnTRUE: 128 return TRUE; 129 } 130 // ------------------------------------------------- 131 // Get information about peripheral 132 else if ( IsDpaPeripheralInfoRequest() ) 133 { 134 if ( _PNUM == PNUM_STD_SENSORS ) 135 { 136 _DpaMessage.PeripheralInfoAnswer.PerT = PERIPHERAL_TYPE_STD_SENSORS; 137 _DpaMessage.PeripheralInfoAnswer.PerTE = PERIPHERAL_TYPE_EXTENDED_READ_WRITE; 138 // Set standard version 139 _DpaMessage.PeripheralInfoAnswer.Par1 = 13; 140 goto DpaHandleReturnTRUE; 141 } 142 143 break; 144 } 145 // ------------------------------------------------- 146 else 147 { 148 // Handle peripheral command 149 150 // Supported peripheral number? 151 if ( _PNUM == PNUM_STD_SENSORS ) 152 { 153 // Supported commands? 154 switch ( _PCMD ) 155 { 156 // Invalid command 157 default: 158 // Return error 159 DpaApiReturnPeripheralError( ERROR_PCMD ); 160 161 // Sensor enumeration 162 case PCMD_STD_ENUMERATE: 163 if ( _DpaDataLength != 0 ) 164 goto _ERROR_DATA_LEN; 165 166 // Then just enumerate their types 167 _DpaMessage.Response.PData[0] = STD_SENSOR_TYPE_TEMPERATURE; 168 _DpaMessage.Response.PData[1] = STD_SENSOR_TYPE_CO2; 169 _DpaMessage.Response.PData[2] = STD_SENSOR_TYPE_VOC; 170 _DpaMessage.Response.PData[3] = STD_SENSOR_TYPE_HUMIDITY; 171 _DpaMessage.Response.PData[4] = STD_SENSOR_TYPE_BINARYDATA7; 172 _DpaMessage.Response.PData[5] = STD_SENSOR_TYPE_DATA_BLOCK; 173 _DpaMessage.Response.PData[6] = STD_SENSOR_TYPE_BINARYDATA30; 174 W = SENSORS_COUNT; 175 goto _W2_DpaDataLength; 176 177 // Supported commands. They are handled the same way except one "if" at StoreValue() method 178 case PCMD_STD_SENSORS_READ_VALUES: 179 case PCMD_STD_SENSORS_READ_TYPES_AND_VALUES: 180 { 181 // No sensor bitmap specified? W = _DpaDataLength. Note: W is used to avoid MOVLB at next if 182 W = _DpaDataLength; 183 if ( W == 0 ) // Note: must not modify W 184 { 185 // Actually clears the bitmap 186 #if &_DpaMessage.Request.PData[0] != &bufferRF[0] 187 #error 188 #endif 189 clearBufferRF(); 190 // Simulate 1st only sensor in the bitmap (states of the other unimplemented sensors do not care) 191 _DpaMessage.Request.PData[0].0 = 1; 192 // Bitmap is 32 bits long = 4 193 _DpaDataLength = W = 4; 194 } 195 196 // Invalid bitmap (data) length (W = _DpaDataLength)? 197 if ( W != 4 ) 198 { 199 _ERROR_DATA_LEN: 200 // Return error 201 DpaApiReturnPeripheralError( ERROR_DATA_LEN ); 202 } 203 204 // Now read the sensors 205 206 // Prepare pointer (minus 1, see below) to store sensor (types and) values to 207 // Note: 5 sensors at this example cannot return more than DPA_MAX_DATA_LENGTH bytes of data, so it does not have to be checked... 208 // ... If it would be the case, then ERROR_FAIL must be returned 209 FSR1 = &_DpaMessage.Response.PData[-1]; 210 211 // Store bitmap of sensors to get values from 212 uns8 sensorsBitmap = FSR1[1]; 213 214 // 1st sensor (index 0) selected? 215 if ( sensorsBitmap.0 ) 216 { 217 Get0_Temperature(); 218 StoreValue( STD_SENSOR_TYPE_TEMPERATURE ); 219 } 220 221 // 2nd sensor (index 1) selected? 222 if ( sensorsBitmap.1 ) 223 { 224 Get1_CO2(); 225 StoreValue( STD_SENSOR_TYPE_CO2 ); 226 } 227 228 // 3rd sensor (index 2) selected? 229 if ( sensorsBitmap.2 ) 230 { 231 Get2_VOC(); 232 StoreValue( STD_SENSOR_TYPE_VOC ); 233 } 234 235 // 4th sensor (index 3) selected? 236 if ( sensorsBitmap.3 ) 237 { 238 Get3_Humidity(); 239 StoreValue( STD_SENSOR_TYPE_HUMIDITY ); 240 } 241 242 // 5th sensor (index 4) selected? 243 if ( sensorsBitmap.4 ) 244 { 245 Get4_Binary7(); 246 StoreValue( STD_SENSOR_TYPE_BINARYDATA7 ); 247 } 248 249 // 6th sensor (index 5) selected? 250 if ( sensorsBitmap.5 ) 251 { 252 Get5_DataBlock(); 253 StoreValue( STD_SENSOR_TYPE_DATA_BLOCK ); 254 } 255 256 // 6th sensor (index 5) selected? 257 if ( sensorsBitmap.6 ) 258 { 259 Get6_Binary30(); 260 StoreValue( STD_SENSOR_TYPE_BINARYDATA30 ); 261 } 262 263 // Compute returned data bytes count 264 W = FSR1L - ( (uns16)&_DpaMessage.Response.PData[0] & 0xFF ) + 1; 265 // Optimization: return W long block of bytes at response 266 _W2_DpaDataLength: 267 _DpaDataLength = W; 268 goto DpaHandleReturnTRUE; 269 } 270 } 271 } 272 273 break; 274 } 275 276 // ------------------------------------------------- 277 case DpaEvent_FrcValue: 278 // Called to get FRC value 279 280 // FSR1 for optimization purposes (avoid MOVLB) will be used to point to DataOutBeforeResponseFRC[0...] 281 FSR1 = &DataOutBeforeResponseFRC[0]; 282 // Check for correct FRC user data 283 if ( *FSR1++ /*DataOutBeforeResponseFRC[0]*/ == PNUM_STD_SENSORS ) 284 { 285 // Data and index 286 sensorIndexAndData = FSR1[1]; /*DataOutBeforeResponseFRC[2]*/ 287 // Actually used sensor index 288 uns8 sensorIndex = FSR1[1] /*DataOutBeforeResponseFRC[2]*/ & 0x1f; 289 // Test sensor type 290 switch ( *FSR1++ /*DataOutBeforeResponseFRC[1]*/ ) 291 { 292 default: 293 goto DpaHandleReturnFALSE; 294 295 // No type specified, use specified index value 296 case 0x00: 297 goto _KeepSensorIndex; 298 299 // For other types make the index value based on the requested index value and sensor type 300 case STD_SENSOR_TYPE_TEMPERATURE: 301 if ( sensorIndex > 0 ) 302 goto DpaHandleReturnFALSE; 303 W = 0; 304 break; 305 306 case STD_SENSOR_TYPE_CO2: 307 if ( sensorIndex > 0 ) 308 goto DpaHandleReturnFALSE; 309 W = 1; 310 break; 311 312 case STD_SENSOR_TYPE_VOC: 313 if ( sensorIndex > 0 ) 314 goto DpaHandleReturnFALSE; 315 W = 2; 316 break; 317 318 case STD_SENSOR_TYPE_HUMIDITY: 319 if ( sensorIndex > 0 ) 320 goto DpaHandleReturnFALSE; 321 W = 3; 322 break; 323 324 case STD_SENSOR_TYPE_BINARYDATA7: 325 if ( sensorIndex > 0 ) 326 goto DpaHandleReturnFALSE; 327 W = 4; 328 break; 329 330 case STD_SENSOR_TYPE_BINARYDATA30: 331 if ( sensorIndex > 0 ) 332 goto DpaHandleReturnFALSE; 333 W = 6; 334 break; 335 } 336 337 // New sensor index based on type and requested index 338 sensorIndex = W; 339 _KeepSensorIndex: 340 341 // Test for supported FRC commands 342 switch ( _PCMD ) 343 { 344 default: 345 goto DpaHandleReturnFALSE; 346 347 case FRC_STD_SENSORS_BIT: 348 case FRC_STD_SENSORS_1B: 349 case FRC_STD_SENSORS_2B: 350 case FRC_STD_SENSORS_4B: 351 switch ( sensorIndex ) 352 { 353 default: 354 goto DpaHandleReturnFALSE; 355 356 case 0: 357 Carry = Get0_Temperature(); 358 break; 359 360 case 1: 361 Carry = Get1_CO2(); 362 break; 363 364 case 2: 365 Carry = Get2_VOC(); 366 break; 367 368 case 3: 369 Carry = Get3_Humidity(); 370 break; 371 372 case 4: 373 Carry = Get4_Binary7(); 374 break; 375 376 case 6: 377 Carry = Get6_Binary30(); 378 break; 379 } 380 381 // This type of FRC is not valid for the specified sensor 382 if ( !Carry ) 383 goto DpaHandleReturnFALSE; 384 385 break; 386 } 387 388 // Some sensor was measured by FRC, check if there is a sleep request 389 FSR1++; 390 if ( INDF1.0 ) // Note: same as DataOutBeforeResponseFRC[3].0 391 { 392 // Remember sleep parameters to go to sleep at the Idle event later 393 PerOSSleep_Request.Time.low8 = FSR1[4 - 3]; // Note: same as DataOutBeforeResponseFRC[4]; 394 PerOSSleep_Request.Time.high8 = FSR1[5 - 3]; // Note: same as DataOutBeforeResponseFRC[5]; 395 PerOSSleep_Request.Control = FSR1[6 - 3]; // Note: same as DataOutBeforeResponseFRC[6]; 396 } 397 } 398 399 break; 400 401 // ------------------------------------------------- 402 case DpaEvent_FrcResponseTime: 403 // Called to get FRC response time 404 405 // In this example the FRC commands are fast 406 switch ( DataOutBeforeResponseFRC[0] ) 407 { 408 case FRC_STD_SENSORS_BIT: 409 case FRC_STD_SENSORS_1B: 410 case FRC_STD_SENSORS_2B: 411 case FRC_STD_SENSORS_4B: 412 responseFRCvalue = _FRC_RESPONSE_TIME_40_MS; 413 break; 414 } 415 break; 416 } 417 DpaHandleReturnFALSE: 418 return FALSE; 419 } 420 421 //############################################################################################ 422 // Increases FSR1 and then stores the byte 423 void setPlusPlusINDF1( uns8 data @ W ) 424 //############################################################################################ 425 { 426 FSR1++; // Note: must not modify W 427 setINDF1( data ); 428 } 429 430 //############################################################################################ 431 // Stores measured sensor value byte(s) and optionally sensor type to the FSR[+1...] 432 void StoreValue( uns8 sensorType ) 433 //############################################################################################ 434 { 435 // Is the sensor type to be stored too? 436 if ( _PCMD == PCMD_STD_SENSORS_READ_TYPES_AND_VALUES ) 437 setPlusPlusINDF1( sensorType ); 438 439 // Store lower value byte (or length in case of multiple bytes) 440 setPlusPlusINDF1( sensorValue.low8 ); 441 442 // 2 bytes? 443 if ( sensorType.7 == 0 ) 444 { 445 // Store higher value byte 446 setPlusPlusINDF1( sensorValue.high8 ); 447 return; 448 } 449 450 // 4 bytes? 451 if ( ( sensorType & 0b1110.0000 ) == 0b1010.0000 ) 452 { 453 setPlusPlusINDF1( sensorValue.high8 ); 454 setPlusPlusINDF1( sensorValueHighWord.low8 ); 455 setPlusPlusINDF1( sensorValueHighWord.high8 ); 456 return; 457 } 458 459 // Multiple bytes? 460 if ( ( sensorType & 0b1100.0000 ) == 0b1100.0000 ) 461 { 462 // Data is expected at bufferINFO, length at sensorValue.low8 463 setFSR0( _FSR_INFO ); 464 do 465 { 466 // Store all data 467 setPlusPlusINDF1( *FSR0++ ); 468 } while ( --sensorValue.low8 != 0 ); 469 return; 470 } 471 } 472 473 //############################################################################################ 474 bit setFRCerror() 475 //############################################################################################ 476 { 477 #ifndef __CC5XFREE__ 478 responseFRCvalue4B = 2; 479 #else 480 responseFRCvalue4B.low16 = 2; 481 responseFRCvalue4B.high16 = 0; 482 #endif 483 return TRUE; 484 } 485 486 //############################################################################################ 487 // Sensor index 0: measure temperature using the TR sensor 488 bit Get0_Temperature() 489 //############################################################################################ 490 { 491 // Make sure FSR1 is not modified 492 493 // Measure temperature using TR sensor 494 bit sensorError = FALSE; 495 // When error, then adjust the standard error values 496 if ( getTemperature() == -128 ) 497 { 498 sensorError = TRUE; 499 param3 = 0x8000; 500 } 501 502 // Return sensor value 503 sensorValue = param3; 504 505 // Test for supported FRC commands 506 switch ( _PCMD ) 507 { 508 default: 509 return FALSE; 510 511 case FRC_STD_SENSORS_1B: 512 // Return sensor FRC value 1B 513 // Check for out of limits 514 if ( sensorError || (int16)sensorValue > (int16)( 105.5 * 16 ) || (int16)sensorValue < ( (int16)-20 * 16 ) ) 515 return setFRCerror(); 516 517 // Convert to the "F = ( T + 22 ) * 2 " from 1/16 resolution 518 uns16 _sensorValue = sensorValue + 4; // Note: do rounding when /8 519 responseFRCvalue = (uns8)( _sensorValue / 8 ) + 44; 520 break; 521 522 case FRC_STD_SENSORS_2B: 523 // Return sensor FRC value 2B 524 if ( sensorError ) 525 return setFRCerror(); 526 527 responseFRCvalue2B = sensorValue ^ 0x8000; 528 break; 529 } 530 531 return TRUE; 532 } 533 534 //############################################################################################ 535 // Sensor index 1: simulate measuring CO2 536 bit Get1_CO2() 537 //############################################################################################ 538 { 539 // Make sure FSR1 is not modified 540 541 bit sensorError = FALSE; 542 // Fake CO2 return value 543 sensorValue = 0x0987; 544 // When error, return standard (FRC) error value(s) 545 if ( sensorValue == 0x8000 ) 546 sensorError = TRUE; 547 548 // Test for supported FRC commands 549 switch ( _PCMD ) 550 { 551 default: 552 return FALSE; 553 554 case FRC_STD_SENSORS_1B: 555 // Return sensor FRC value 1B 556 // Check for out of limits 557 if ( sensorError || sensorValue > 4016 ) 558 return setFRCerror(); 559 560 responseFRCvalue = sensorValue / 16 + 4; 561 break; 562 563 case FRC_STD_SENSORS_2B: 564 // Return sensor FRC value 2B 565 if ( sensorError ) 566 return setFRCerror(); 567 568 responseFRCvalue2B = sensorValue + 4; 569 break; 570 } 571 572 return TRUE; 573 } 574 575 //############################################################################################ 576 // Sensor index 2: simulate measuring VOC 577 bit Get2_VOC() 578 //############################################################################################ 579 { 580 // Make sure FSR1 is not modified 581 582 bit sensorError = FALSE; 583 // Fake VOC return value 584 sensorValue = 0x0123; 585 // When error, return standard (FRC) error value(s) 586 if ( sensorValue == 0x8000 ) 587 sensorError = TRUE; 588 589 // Test for supported FRC commands 590 switch ( _PCMD ) 591 { 592 default: 593 return FALSE; 594 595 case FRC_STD_SENSORS_1B: 596 // Return sensor FRC value 1B 597 // Check for out of limits 598 if ( sensorError || sensorValue > 4016 ) 599 return setFRCerror(); 600 601 responseFRCvalue = sensorValue / 16 + 4; 602 break; 603 604 case FRC_STD_SENSORS_2B: 605 // Return sensor FRC value 2B 606 if ( sensorError ) 607 return setFRCerror(); 608 609 responseFRCvalue2B = sensorValue + 4; 610 break; 611 } 612 613 return TRUE; 614 } 615 616 //############################################################################################ 617 // Sensor index 3: simulate measuring humidity 618 bit Get3_Humidity() 619 //############################################################################################ 620 { 621 // Make sure FSR1 is not modified 622 623 // Fake humidity return value 624 sensorValue.low8 = 50 * 2; 625 626 // Test for supported FRC commands 627 switch ( _PCMD ) 628 { 629 default: 630 return FALSE; 631 632 case FRC_STD_SENSORS_1B: 633 // Return sensor FRC value 1B 634 if ( sensorValue.low8 == 0xEE ) 635 return setFRCerror(); 636 637 responseFRCvalue = sensorValue.low8 + 4; 638 break; 639 } 640 return TRUE; 641 } 642 643 //############################################################################################ 644 // Sensor index 4: simulate binary data 645 bit Get4_Binary7() 646 //############################################################################################ 647 { 648 // Make sure FSR1 is not modified 649 650 bit sensorError = FALSE; 651 // Fake humidity return value 652 sensorValue.low8 = lastRSSI & 0x7F; 653 // When error, return standard (FRC) error value(s) 654 if ( sensorValue.low8 == 0x80 ) 655 sensorError = TRUE; 656 657 // Test for supported FRC commands 658 switch ( _PCMD ) 659 { 660 default: 661 return FALSE; 662 663 case FRC_STD_SENSORS_BIT: 664 // If there is a sensor error, 2-bit FRC cannot indicate it, it returns [01] 665 if ( !sensorError ) 666 { 667 // Number of shifts to get the bit out of the return value 668 uns8 bitLoop = ( INDF1 >> 5 ) + 1; 669 // Value to get the bit from 670 W = sensorValue.low8; 671 do 672 { 673 // Get the bit to Carry 674 W = rr( W ); 675 // Next bit 676 } while ( --bitLoop != 0 ); // Note: must not modify W and Carry 677 // Current (prepared by DPA) FRC value is [01], change it to [11] (means bit is set) 678 responseFRCvalue.1 = 1; // Note: must not modify Carry 679 // Is bit set? 680 if ( !Carry ) 681 // Bit is NOT set, return [10] 682 responseFRCvalue.0 = 0; 683 } 684 break; 685 686 case FRC_STD_SENSORS_1B: 687 // Return sensor FRC value 1B 688 if ( sensorError ) 689 return setFRCerror(); 690 691 responseFRCvalue = sensorValue.low8 + 4; 692 break; 693 } 694 return TRUE; 695 } 696 697 //############################################################################################ 698 // Sensor index 5: simulate data block 699 bit Get5_DataBlock() 700 //############################################################################################ 701 { 702 // Make sure FSR1 is not modified 703 uns16 saveFSR1 = FSR1; 704 705 // Get data to bufferINFO 706 moduleInfo(); 707 // Return length 708 sensorValue.low8 = sizeof( TModuleInfo ); 709 710 FSR1 = saveFSR1; 711 return FALSE; 712 } 713 714 //############################################################################################ 715 // Sensor index 6: simulate 30 bit data 716 bit Get6_Binary30() 717 //############################################################################################ 718 { 719 // Make sure FSR1 is not modified 720 uns16 saveFSR1 = FSR1; 721 moduleInfo(); 722 sensorValue.low8 = ModuleInfo.MID[0]; 723 sensorValue.high8 = ModuleInfo.MID[1]; 724 sensorValueHighWord.low8 = ModuleInfo.MID[2]; 725 sensorValueHighWord.high8 = ModuleInfo.MID[3]; 726 FSR1 = saveFSR1; 727 728 // Test for supported FRC commands 729 switch ( _PCMD ) 730 { 731 default: 732 return FALSE; 733 734 case FRC_STD_SENSORS_2B: 735 if ( ( sensorIndexAndData & 0b10.0000 ) != 0 ) 736 #ifndef __CC5XFREE__ 737 responseFRCvalue4B >>= 15; 738 #else 739 { 740 // Carry = responseFRCvalue4B.15 741 W = rl( responseFRCvalue4B.midH8 ); 742 responseFRCvalue4B.midL8 = rl( responseFRCvalue4B.midL8 ); 743 responseFRCvalue4B.low8 = rl( responseFRCvalue4B.low8 ); 744 responseFRCvalue4B.low16 = responseFRCvalue4B.high16; 745 } 746 #endif 747 748 responseFRCvalue2B.15 = 0; 749 responseFRCvalue2B += 4; 750 break; 751 752 case FRC_STD_SENSORS_4B: 753 responseFRCvalue4B.low16 = sensorValue; 754 responseFRCvalue4B.high16 = sensorValueHighWord; 755 #ifndef __CC5XFREE__ 756 responseFRCvalue4B += 4; 757 #else 758 W = 4; 759 responseFRCvalue4B.low8 += W; 760 W = 0; 761 responseFRCvalue4B.midL8 = addWFC( responseFRCvalue4B.midL8 ); 762 responseFRCvalue4B.midH8 = addWFC( responseFRCvalue4B.midH8 ); 763 responseFRCvalue4B.high8 = addWFC( responseFRCvalue4B.high8 ); 764 #endif 765 break; 766 } 767 return TRUE; 768 } 769 //############################################################################################ 770 771 // Default Custom DPA Handler header; 2nd include to implement Code bumper to detect too long code of the Custom DPA Handler (modify the path according to your setup) 772 #include "DPAcustomHandler.h" 773 //############################################################################################