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