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