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