1 // ********************************************************************* 2 // Custom DPA Handler code example - DDC-SE-01 and/or DDC-RE-01 * 3 // ********************************************************************* 4 // Copyright (c) MICRORISC s.r.o. 5 // 6 // File: $RCSfile: CustomDpaHandler-DDC-Core.c,v $ 7 // Version: $Revision: 1.24 $ 8 // Date: $Date: 2021/08/18 20:43:06 $ 9 // 10 // Revision history: 11 // 2021/08/18 Release for DPA 4.16 12 // 2020/01/02 Release for DPA 4.11 13 // 2017/03/13 Release for DPA 3.00 14 // 2016/12/22 Release for DPA 2.28 15 // 16 // ********************************************************************* 17 18 // Online DPA documentation https://doc.iqrf.org/DpaTechGuide/ 19 20 /* This example implements HWP for DDC-SE-01 and/or DDC-RE-01 21 22 DDC-SE-01: HWPID=0x001F 23 DDC-RE-01: HWPID=0x002F 24 DDC-SE-01 & DDC-RE-01: HWPID=0x003F 25 26 ----------- DDC-SE-01 27 Request: PNUM = 0x20, PCMD = 0x31 28 Response: 29 PData[0]=Temperature at [C] 30 PData[1]=Photoresistor value 0x00-0xFF 31 PData[2]=Potentiometer value 0x00-0xFF 32 returns ERROR_FAIL when error reading temperature 33 34 FRC=0xC0, returns temperature at C, 127 for 0 C, 0x80 for error reading temperature 35 FRC=0xC1, returns photoresistor value, returns 1 instead of 0 36 FRC=0xC2, returns potentiometer value, returns 1 instead of 0 37 38 ----------- DDC-RE-01 39 Request: PNUM = 0x20, PCMD = 0x32 40 PData[0]=Relay1Ctrl 41 PData[1]=Relay2Ctrl 42 43 Response: 44 PData[0]=Relay1State 45 PData[1]=Relay2State 46 47 RelayCtrl: 0=Switch the Relay off, 1=Switch the Relay on, Other=Do not control the Relay 48 RelayState: 0=Relay was off, 1=Relay was on 49 */ 50 51 // ********************************************************************* 52 53 // Default IQRF include (modify the path according to your setup) 54 #include "IQRF.h" 55 56 // Default DPA header (modify the path according to your setup) 57 #include "DPA.h" 58 // Default Custom DPA Handler header (modify the path according to your setup) 59 #include "DPAcustomHandler.h" 60 61 #if defined( DDC_SE_01 ) && defined( DDC_RE_01 ) 62 #define ThisHWPID 0x003F 63 #elif defined( DDC_SE_01 ) 64 #define ThisHWPID 0x001F 65 #elif defined( DDC_RE_01 ) 66 #define ThisHWPID 0x002F 67 #else 68 #error Symbol(s) DDC_SE_01 and/or DDC_RE_01 must be defined 69 #endif 70 71 //############################################################################################ 72 73 #if defined( DDC_SE_01 ) 74 75 // Special temperature value to indicate a sensor error 76 #define ERROR_TEMPERATURE 0xF800 77 78 // Sensor connected to PORT C.3 (compatible with DDC-SE-01) 79 #define OneWire_TRIS TRISC.3 80 #define OneWire_IO_IN PORTC.3 81 #define OneWire_IO_OUT LATC.3 82 83 // Writes sensor configuration (resolution) 84 bit Ds18B20WriteConfig( uns8 value ); 85 86 // Resets OneWire 87 bit OneWireReset(); 88 // Reads OneWire byte 89 uns8 OneWireReadByte(); 90 // Writes OneWire byte 91 void OneWireWriteByte( uns8 byte ); 92 93 // DS18B20 commands 94 #define CMD_READROM 0x33 95 #define CMD_CONVERTTEMP 0x44 96 #define CMD_CPYSCRATCHPAD 0x48 97 #define CMD_WSCRATCHPAD 0x4e 98 #define CMD_MATCHROM 0x55 99 #define CMD_RPWRSUPPLY 0xb4 100 #define CMD_RECEEPROM 0xb8 101 #define CMD_RSCRATCHPAD 0xbe 102 #define CMD_SKIPROM 0xcc 103 #define CMD_ALARMSEARCH 0xec 104 #define CMD_SEARCHROM 0xf0 105 106 // I2C SCL frequency [Hz] 107 #define I2Cfrequency 50000 108 109 // MCP9802 address 110 #define I2C_ADR 0b10010110 111 // Power pin 112 #define PWR_SENSOR_TRIS TRISC.7 113 #define PWR_SENSOR_IO LATC.7 114 115 // Sensors read routines 116 uns16 GetTemperature(); 117 uns8 ReadAdcPhotoresistor(); 118 uns8 ReadAdcPotentiometer(); 119 120 // TRUE if DS18B20 is enabled, FALSE in case of MCP9802 121 bit isDS18B20; 122 // Final DS18B20 temperature value 123 static uns16 temperature; 124 125 #endif 126 127 #if defined( DDC_RE_01 ) 128 129 // C.5 = C8 = Relay#1 130 #define RELAY1_LAT LATC.5 131 #define RELAY1_TRIS TRISC.5 132 133 // C.2 = C2 = Relay#2 134 #define RELAY2_LAT LATC.2 135 #define RELAY2_TRIS TRISC.2 136 137 #endif 138 139 // Must be the 1st defined function in the source code in order to be placed at the correct FLASH location! 140 //############################################################################################ 141 bit CustomDpaHandler() 142 //############################################################################################ 143 { 144 #if defined( DDC_SE_01 ) 145 // Finite machine states 146 typedef enum 147 { 148 S_ResetConvertT = 0, 149 S_SkipRomConvertT, 150 S_CmdConvertT, 151 152 S_WaitConvertT, 153 154 S_ResetReadTemp, 155 S_SkipRomReadTemp, 156 S_CmdReadTemp, 157 S_Byte1ReadTemp, 158 S_Byte2ReadTemp 159 } TState; 160 161 #endif 162 163 // Handler presence mark 164 clrwdt(); 165 166 #if defined( DDC_SE_01 ) 167 // Finite machine state 168 static uns8 state; // = S_ResetConvertT = 0 169 // Pre-read lower temperature byte 170 static uns8 temperatureByteLow; 171 // Conversion timeout counter 172 static uns8 timeout; 173 #endif 174 175 // Detect DPA event to handle 176 switch ( GetDpaEvent() ) 177 { 178 // ------------------------------------------------- 179 case DpaEvent_Interrupt: 180 // Do an extra quick background interrupt work 181 // ! 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. 182 // ! 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. 183 // ! 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. 184 // ! Only global variables or local ones marked by static keyword can be used to allow reentrancy. 185 // ! Make sure race condition does not occur when accessing those variables at other places. 186 // ! 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. 187 // ! Do not call any OS functions except setINDFx(). 188 // ! Do not use any OS variables especially for writing access. 189 // ! 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. 190 191 #if defined( DDC_SE_01 ) 192 #define TICKS_LEN 10 193 194 // If TMR6 interrupt occurred 195 if ( TMR6IF ) 196 { 197 // Unmask interrupt 198 TMR6IF = 0; 199 // Decrement count 200 if ( timeout != 0 ) 201 timeout--; 202 } 203 #endif 204 return Carry; 205 206 #if defined( DDC_SE_01 ) 207 // ------------------------------------------------- 208 case DpaEvent_Idle: 209 // Do a quick background work when RF packet is not received 210 211 // Run finite state machine to read temperature from DS18B20 at background so the temperature value is immediately ready for FRC 212 if ( !isDS18B20 ) 213 break; 214 215 // Make sure 1Wire data pin at LATX.y is low as it might be set by another PORTX.? pin manipulation 216 OneWire_IO_OUT = 0; 217 218 skip( state ); 219 #pragma computedGoto 1 220 goto _S_ResetConvertT; 221 goto _S_SkipRomConvertT; 222 goto _S_CmdConvertT; 223 goto _S_WaitConvertT; 224 goto _S_ResetReadTemp; 225 goto _S_SkipRomReadTemp; 226 goto _S_CmdReadTemp; 227 goto _S_Byte1ReadTemp; 228 goto _S_Byte2ReadTemp; 229 #pragma computedGoto 0 230 ; 231 // -------------- 232 _S_Byte2ReadTemp: 233 temperature.high8 = OneWireReadByte(); 234 temperature.low8 = temperatureByteLow; 235 236 ResetMachine: 237 state = S_ResetConvertT; 238 goto ExitMachine; 239 240 // -------------- 241 _S_ResetConvertT: 242 _S_ResetReadTemp: 243 if ( !OneWireReset() ) 244 { 245 _S_Error_Reset: 246 temperature = ERROR_TEMPERATURE; 247 goto ResetMachine; 248 } 249 goto NextState; 250 251 // -------------- 252 _S_SkipRomConvertT: 253 _S_SkipRomReadTemp: 254 // OneWire: Skip ROM 255 OneWireWriteByte( CMD_SKIPROM ); 256 goto NextState; 257 258 // -------------- 259 _S_CmdConvertT: 260 // OneWire: Convert temperature 261 OneWireWriteByte( CMD_CONVERTTEMP ); 262 // Setup timeout for approx 750 ms (the longest conversion time) 263 timeout = 2 + 750 / TICKS_LEN; 264 goto NextState; 265 266 // -------------- 267 _S_WaitConvertT: 268 if ( OneWireReadByte() == 0xff ) 269 goto NextState; 270 271 // Timeout? 272 if ( timeout == 0 ) 273 goto _S_Error_Reset; 274 275 goto ExitMachine; 276 277 // -------------- 278 _S_CmdReadTemp: 279 // OneWire: Read scratchpad 280 OneWireWriteByte( CMD_RSCRATCHPAD ); 281 goto NextState; 282 283 // -------------- 284 _S_Byte1ReadTemp: 285 temperatureByteLow = OneWireReadByte(); 286 goto NextState; 287 288 // -------------- 289 NextState: 290 ++state; 291 292 ExitMachine: 293 break; 294 295 // ------------------------------------------------- 296 case DpaEvent_FrcValue: 297 // Called to get FRC value 298 299 // Which FRC command? 300 switch ( _PCMD ) 301 { 302 case FRC_USER_BYTE_FROM + 0: 303 // Returns temperature 304 uns16 curTemperature = GetTemperature(); 305 if ( curTemperature == ERROR_TEMPERATURE ) 306 responseFRCvalue = 0x80; 307 else 308 { 309 responseFRCvalue = curTemperature.low8; 310 if ( responseFRCvalue == 0 ) 311 responseFRCvalue = 127; 312 } 313 break; 314 315 case FRC_USER_BYTE_FROM + 1: 316 // Returns photoresistor value 317 responseFRCvalue = ReadAdcPhotoresistor(); 318 _Zero2One: 319 if ( responseFRCvalue == 0 ) 320 responseFRCvalue |= 1; 321 break; 322 323 case FRC_USER_BYTE_FROM + 2: 324 // Returns potentiometer value 325 responseFRCvalue = ReadAdcPotentiometer(); 326 goto _Zero2One; 327 } 328 break; 329 330 // ------------------------------------------------- 331 case DpaEvent_FrcResponseTime: 332 // Called to get FRC response time 333 334 if ( DataOutBeforeResponseFRC[0] >= ( FRC_USER_BYTE_FROM + 0 ) && DataOutBeforeResponseFRC[0] <= ( FRC_USER_BYTE_FROM + 2 ) ) 335 responseFRCvalue = _FRC_RESPONSE_TIME_40_MS; 336 break; 337 #endif 338 339 // ------------------------------------------------- 340 case DpaEvent_DpaRequest: 341 { 342 // Called to interpret DPA request for peripherals 343 // ------------------------------------------------- 344 // Peripheral enumeration 345 if ( IsDpaEnumPeripheralsRequest() ) 346 { 347 // We implement 1 user peripheral 348 _DpaMessage.EnumPeripheralsAnswer.UserPerNr = 1; 349 #ifdef FlagUserPer // Get ready for upcoming DPA 3.00 350 FlagUserPer( _DpaMessage.EnumPeripheralsAnswer.UserPer, PNUM_USER + 0 ); 351 #endif 352 _DpaMessage.EnumPeripheralsAnswer.HWPID = ThisHWPID; 353 _DpaMessage.EnumPeripheralsAnswer.HWPIDver = 0x0000; 354 355 DpaHandleReturnTRUE: 356 return TRUE; 357 } 358 // ------------------------------------------------- 359 // Get information about peripheral 360 else if ( IsDpaPeripheralInfoRequest() ) 361 { 362 if ( _PNUM == PNUM_USER + 0 ) 363 { 364 _DpaMessage.PeripheralInfoAnswer.PerT = PERIPHERAL_TYPE_USER_AREA; 365 #if !defined( DDC_RE_01 ) 366 _DpaMessage.PeripheralInfoAnswer.PerTE = PERIPHERAL_TYPE_EXTENDED_READ; 367 #else 368 _DpaMessage.PeripheralInfoAnswer.PerTE = PERIPHERAL_TYPE_EXTENDED_READ_WRITE; 369 #endif 370 goto DpaHandleReturnTRUE; 371 } 372 373 break; 374 } 375 // ------------------------------------------------- 376 else 377 { 378 // Handle peripheral command 379 if ( _PNUM == PNUM_USER + 0 ) 380 { 381 switch ( _PCMD ) 382 { 383 #if defined( DDC_SE_01 ) 384 case 0x31: 385 // Read sensors 386 if ( _DpaDataLength != 0 ) 387 DpaApiReturnPeripheralError( ERROR_DATA_LEN ); 388 389 // Read temperature and check for an error 390 uns16 temperature = GetTemperature(); 391 if ( temperature == ERROR_TEMPERATURE ) 392 DpaApiReturnPeripheralError( ERROR_FAIL ); 393 _DpaMessage.Response.PData[0] = temperature.low8; 394 395 // Read other sensors 396 _DpaMessage.Response.PData[1] = ReadAdcPhotoresistor(); 397 _DpaMessage.Response.PData[2] = ReadAdcPotentiometer(); 398 399 // Return 3 bytes 400 _DpaDataLength = 3; 401 goto DpaHandleReturnTRUE; 402 #endif 403 404 #if defined( DDC_RE_01 ) 405 case 0x32: 406 // Control and return state of relays 407 if ( _DpaDataLength != 2 ) 408 DpaApiReturnPeripheralError( ERROR_DATA_LEN ); 409 410 // Relay #1 411 // Get 412 userReg0 = 0; 413 if ( RELAY1_LAT ) 414 userReg0.0 = 1; 415 416 // Set 417 switch ( _DpaMessage.Request.PData[0] ) 418 { 419 case 0: 420 RELAY1_LAT = 0; 421 break; 422 case 1: 423 RELAY1_LAT = 1; 424 break; 425 } 426 _DpaMessage.Response.PData[0] = userReg0; 427 428 // Relay #2 429 // Get 430 userReg0 = 0; 431 if ( RELAY2_LAT ) 432 userReg0.0 = 1; 433 434 // Set 435 switch ( _DpaMessage.Request.PData[1] ) 436 { 437 case 0: 438 RELAY2_LAT = 0; 439 break; 440 case 1: 441 RELAY2_LAT = 1; 442 break; 443 } 444 _DpaMessage.Response.PData[1] = userReg0; 445 // Receives and returns 2 bytes 446 goto DpaHandleReturnTRUE; 447 #endif 448 449 // Invalid command 450 default: 451 DpaApiReturnPeripheralError( ERROR_PCMD ); 452 break; 453 } 454 } 455 } 456 457 break; 458 } 459 460 // ------------------------------------------------- 461 case DpaEvent_Init: 462 // Do a one time initialization before main loop starts 463 464 #if defined( DDC_SE_01 ) 465 // Initialize sensors 466 467 // C5 (AN4) as input 468 moduleInfo(); 469 // Connected TR pins? 470 if ( !bufferINFO[5].7 ) 471 { 472 TRISC.6 = 1; 473 TRISB.4 = 1; 474 } 475 TRISA.5 = 1; 476 477 // C1 (AN0) as input 478 TRISA.0 = 1; 479 480 // Setup TMR6 to generate ticks on the background (ticks every 10ms) 481 #if F_OSC == 16000000 482 PR6 = 250 - 1; 483 T6CON = 0b0.1001.1.10; // Prescaler 16, Postscaler 10, 16 * 10 * 250 = 40000 = 4MHz * 10ms 484 #else 485 #error Unsupported oscillator frequency 486 #endif 487 488 // Setup DS18B20 for 9bit precision, conversion takes 94ms (see datasheet) 489 if ( Ds18B20WriteConfig( 0b0.00.00000 ) ) 490 // DS18B20 is enabled 491 isDS18B20 = TRUE; 492 else 493 { 494 // Expect MCP9802 is enabled 495 I2Ctimeout = 0xFF; 496 _DpaApiI2Cinit( I2CcomputeFrequency( I2Cfrequency ) ); 497 } 498 #endif 499 500 #if defined( DDC_RE_01 ) 501 // Initialize relays 502 RELAY1_LAT = 0; 503 RELAY2_LAT = 0; 504 RELAY1_TRIS = 0; 505 RELAY2_TRIS = 0; 506 507 #endif 508 break; 509 510 #if defined( DDC_SE_01 ) 511 // ------------------------------------------------- 512 case DpaEvent_AfterSleep: 513 // Called after woken up after sleep 514 if ( !isDS18B20 ) 515 _DpaApiI2Cinit( I2CcomputeFrequency( I2Cfrequency ) ); 516 517 // Called on wake-up from sleep 518 TMR6IE = TRUE; 519 TMR6ON = TRUE; 520 break; 521 522 // ------------------------------------------------- 523 case DpaEvent_BeforeSleep: 524 // Called before going to sleep 525 if ( !isDS18B20 ) 526 _DpaApiI2Cshutdown(); 527 528 // ------------------------------------------------- 529 case DpaEvent_DisableInterrupts: 530 // Called when device needs all hardware interrupts to be disabled (before Reset, Restart, LoadCode, Remove bond, and Run RFPGM) 531 // Must not use TMR6 any more 532 TMR6ON = FALSE; 533 TMR6IE = FALSE; 534 break; 535 #endif 536 } 537 return FALSE; 538 } 539 540 //############################################################################################ 541 #if defined( DDC_SE_01 ) 542 543 //############################################################################################ 544 // OneWire and Dallas 18B20 routines 545 //############################################################################################ 546 547 //############################################################################################ 548 void Delay5us( uns8 val @ W ) // Absolutely precise timing but val != 0 549 //############################################################################################ 550 { 551 // 16 MHz 552 // + 0.75us ( W=val, Call ) 553 for ( ;; ) 554 { // loop time 555 nop2(); // 0.50us 556 nop2(); // 1.00us 557 nop2(); // 1.50us 558 nop2(); // 2.00us 559 nop2(); // 2.50us 560 nop2(); // 3.00us 561 nop(); // 3.25us 562 if ( --val == 0 ) // + 0.75us (W--, BTFS ) 563 return; // + 0.25us 564 nop2(); // 4.50us 565 } // 5.00us (Goto) 566 } 567 //############################################################################################ 568 569 #define OneWireData0() { OneWire_TRIS = 0; } // 0.5us @ 16MHz 570 #define OneWireData1() { OneWire_TRIS = 1; } // 0.5us @ 16MHz 571 572 //############################################################################################ 573 void OneWireWriteByte( uns8 byte ) 574 //############################################################################################ 575 { 576 uns8 bitLoop = 8; 577 do 578 { 579 // Next sequence is time precision critical 580 GIE = FALSE; 581 582 OneWireData0(); 583 nop2(); // 1 us [0.5 us] 584 nop2(); // [1.0 us] 585 if ( byte.0 ) // 2.5 us [1.75us] 586 OneWireData1(); 587 588 // End of time precision critical sequence 589 GIE = TRUE; 590 591 // 60us minimum in total, does not have to be precise 592 Delay5us( ( 60 - 3 ) / 5 + 1 ); 593 594 OneWireData1(); 595 596 byte >>= 1; 597 } while ( --bitLoop != 0 ); 598 } 599 600 //############################################################################################ 601 uns8 OneWireReadByte() 602 //############################################################################################ 603 { 604 uns8 result; 605 uns8 bitLoop = 8; 606 do 607 { 608 // Next sequence is time precision critical 609 GIE = FALSE; 610 611 OneWireData0(); 612 nop2(); // 1 us [0.5 us] 613 #if F_OSC == 16000000 614 nop2(); // [1.0 us] 615 #endif 616 OneWireData1(); // 2 us [1.5 us] 617 Delay5us( 15 / 5 ); // 17 us [16.5 us] 618 619 Carry = 0; // 17.5 us [16.75 us] 620 if ( OneWire_IO_IN ) // 18.5 us [ 17.25 us] (condition must not modify Carry) 621 Carry = 1; 622 623 // End of time precision critical sequence 624 GIE = TRUE; // must not modify Carry 625 result = rr( result ); 626 627 // 60us minimum in total, does not have to be precise 628 Delay5us( ( 60 - 20 ) / 5 + 1 ); 629 } while ( --bitLoop != 0 ); 630 631 return result; 632 } 633 634 //############################################################################################ 635 bit OneWireReset() 636 //############################################################################################ 637 { 638 // Setting the pin once to low is enough 639 OneWire_IO_OUT = 0; 640 // Reset pulse 641 OneWireData0(); 642 Delay5us( 500 / 5 ); 643 // Reset pulse end 644 OneWireData1(); 645 // Next sequence is time precision critical 646 GIE = FALSE; 647 // Wait for presence pulse 648 Delay5us( 70 / 5 ); 649 // End of time precision critical sequence 650 GIE = TRUE; 651 // Presence pulse? 652 if ( OneWire_IO_IN ) 653 { 654 // No presence, finish initialization sequence 655 Delay5us( ( 500 - 70 ) / 5 ); 656 return FALSE; 657 } 658 else 659 { 660 // Presence OK, finish initialization sequence 661 Delay5us( ( 500 - 70 ) / 5 ); 662 return TRUE; 663 } 664 } 665 666 //############################################################################################ 667 void OneWireCmd( uns8 cmd ) 668 //############################################################################################ 669 { 670 // OneWire: Skip ROM 671 OneWireWriteByte( CMD_SKIPROM ); 672 // OneWire: Send command 673 OneWireWriteByte( cmd ); 674 } 675 676 //############################################################################################ 677 bit Ds18B20WriteConfig( uns8 value ) 678 //############################################################################################ 679 { 680 if ( OneWireReset() ) 681 { 682 // Write Scratchpad 683 OneWireCmd( CMD_WSCRATCHPAD ); 684 685 // Write TL = ? (we dot not care the value) 686 OneWireWriteByte( W ); 687 // Write TH = ? (we dot not care the value) 688 OneWireWriteByte( W ); 689 // Write Config byte 690 OneWireWriteByte( value ); 691 692 if ( OneWireReset() ) 693 { 694 // Copy Scratchpad 695 OneWireCmd( CMD_CPYSCRATCHPAD ); 696 return TRUE; 697 } 698 } 699 return FALSE; 700 } 701 702 //############################################################################################ 703 uns16 MCP9802GetTemp() 704 //############################################################################################ 705 { 706 // MCP9802 address 707 _DpaApiI2Cstart( I2C_ADR ); 708 if ( I2CwasTimeout ) 709 return ERROR_TEMPERATURE; 710 711 // pointer: 1 = configuration register 712 _DpaApiI2Cwrite( 0x01 ); 713 // configuration: 9-bit ADC 714 _DpaApiI2CwriteAndStop( 0x00 ); 715 716 // MCP9802 address 717 _DpaApiI2Cstart( I2C_ADR ); 718 // pointer: 0 = temperature 719 _DpaApiI2CwriteAndStop( 0 ); 720 721 // MCP9802 address + read 722 _DpaApiI2Cstart( I2C_ADR | 1 ); 723 uns16 temperature; 724 // store the result 725 temperature.high8 = _DpaApiI2Cread( TRUE ); 726 temperature.low8 = _DpaApiI2Cread( FALSE ); 727 _DpaApiI2Cstop(); 728 return temperature; 729 } 730 731 //############################################################################################ 732 uns16 GetTemperature() 733 //############################################################################################ 734 { 735 // Reads temperature from an enabled sensor 736 uns16 temperatureResult; 737 738 if ( isDS18B20 ) 739 { 740 // Temperature is ready at the background 741 temperatureResult = temperature; 742 if ( temperatureResult != ERROR_TEMPERATURE ) 743 { 744 temperatureResult += 0x08; 745 temperatureResult /= 0x10; 746 } 747 } 748 else 749 { 750 // Temperature value must be read from I2C sensor 751 temperatureResult = MCP9802GetTemp(); 752 if ( temperatureResult != ERROR_TEMPERATURE ) 753 { 754 temperatureResult += 0x80; 755 temperatureResult /= 0x100; 756 } 757 } 758 759 return temperatureResult; 760 } 761 762 //############################################################################################ 763 uns8 ReadAdc() 764 //############################################################################################ 765 { 766 // ADC result - left justified, Fosc/8 767 ADCON1 = 0b0001.0000; 768 // start ADC 769 GO = 1; 770 // wait for ADC finish 771 while ( GO ); 772 return ADRESH; 773 } 774 775 //############################################################################################ 776 uns8 ReadAdcPhotoresistor() 777 //############################################################################################ 778 { 779 // ADC initialization (for more info see PIC datasheet) pin C1 (AN0) as analog input 780 ANSELA.0 = 1; 781 // ADC setting (AN0 channel) 782 ADCON0 = 0b0.00000.01; 783 return ReadAdc(); 784 } 785 786 //############################################################################################ 787 uns8 ReadAdcPotentiometer() 788 //############################################################################################ 789 { 790 // ADC initialization (for more info see PIC datasheet) pin C5 (AN4) as analog input 791 ANSELA.5 = 1; 792 // ADC setting (AN4 channel) 793 ADCON0 = 0b0.00100.01; 794 return ReadAdc(); 795 } 796 //############################################################################################ 797 #endif 798 //############################################################################################ 799 // 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) 800 #include "DPAcustomHandler.h" 801 //############################################################################################