1 // *********************************************************************************** 2 // Custom DPA Handler code example - User peripheral implementation - i2c * 3 // *********************************************************************************** 4 // Copyright (c) IQRF Tech s.r.o. 5 // 6 // File: $RCSfile: CustomDpaHandler-UserPeripheral-i2c.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 // 2015/12/01 Release for DPA 2.24 14 // 2015/08/05 Release for DPA 2.20 15 // 16 // ********************************************************************* 17 18 // Online DPA documentation https://doc.iqrf.org/DpaTechGuide/ 19 20 // This example implements the user peripheral reading from MCP9802 at DDC-SE-01 21 // PNUM = 0x20 and PCMD = 0 returns 2 bytes with result read from MCP9802 22 // Based on example DDC-SE-01-i2c.c 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 // I2C Master library 32 #include "lib/I2Cmaster.c" 33 34 //############################################################################################ 35 36 // I2C SCL frequency [Hz] 37 #define I2Cfrequency 50000 38 39 #define I2C_ADR 0b10010110 40 #define PWR_SENSOR_TRIS TRISC.7 41 #define PWR_SENSOR_IO LATC.7 42 43 // Must be the 1st defined function in the source code in order to be placed at the correct FLASH location! 44 //############################################################################################ 45 bit CustomDpaHandler() 46 //############################################################################################ 47 { 48 // Handler presence mark 49 clrwdt(); 50 51 // Detect DPA event to handle 52 switch ( GetDpaEvent() ) 53 { 54 // ------------------------------------------------- 55 case DpaEvent_Interrupt: 56 // Do an extra quick background interrupt work 57 // ! 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. 58 // ! 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. 59 // ! 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. 60 // ! Only global variables or local ones marked by static keyword can be used to allow reentrancy. 61 // ! Make sure race condition does not occur when accessing those variables at other places. 62 // ! 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. 63 // ! Do not call any OS functions except setINDFx(). 64 // ! Do not use any OS variables especially for writing access. 65 // ! 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. 66 67 DpaHandleReturnTRUE: 68 return TRUE; 69 70 // ------------------------------------------------- 71 case DpaEvent_Init: 72 // Do a one time initialization before main loop starts 73 case DpaEvent_AfterSleep: 74 // Called after woken up after sleep 75 76 PORTC = 0x80; // port 77 78 PWR_SENSOR_TRIS = 0; // sensor power as output (SIM C8) 79 TRISC.5 = 1; // shared with SIM C8 80 81 TRISA.5 = 1; // sensor ALERT as input (SIM C5) 82 TRISB.4 = 1; // shared with SIM C5 83 TRISC.6 = 1; // shared with SIM C5 84 i2c_init(); 85 86 break; 87 88 // ------------------------------------------------- 89 case DpaEvent_BeforeSleep: 90 // Called before going to sleep 91 92 i2c_shutdown(); 93 break; 94 95 // ------------------------------------------------- 96 case DpaEvent_DpaRequest: 97 // Called to interpret DPA request for peripherals 98 // ------------------------------------------------- 99 // Peripheral enumeration 100 if ( IsDpaEnumPeripheralsRequest() ) 101 { 102 // We implement 1 user peripheral 103 _DpaMessage.EnumPeripheralsAnswer.UserPerNr = 1; 104 FlagUserPer( _DpaMessage.EnumPeripheralsAnswer.UserPer, PNUM_USER + 0 ); 105 _DpaMessage.EnumPeripheralsAnswer.HWPID = 0x000F; 106 _DpaMessage.EnumPeripheralsAnswer.HWPIDver = 0xAbCd; 107 108 goto DpaHandleReturnTRUE; 109 } 110 // ------------------------------------------------- 111 // Get information about peripheral 112 else if ( IsDpaPeripheralInfoRequest() ) 113 { 114 if ( _PNUM == PNUM_USER + 0 ) 115 { 116 _DpaMessage.PeripheralInfoAnswer.PerT = PERIPHERAL_TYPE_USER_AREA; 117 _DpaMessage.PeripheralInfoAnswer.PerTE = PERIPHERAL_TYPE_EXTENDED_READ; 118 goto DpaHandleReturnTRUE; 119 } 120 121 break; 122 } 123 // ------------------------------------------------- 124 else 125 { 126 // Handle peripheral command 127 if ( _PNUM == PNUM_USER + 0 ) 128 { 129 // Check command 130 switch ( _PCMD ) 131 { 132 case 0: 133 // ------------------------------------------------- 134 // Read temperature 135 if ( _DpaDataLength != 0 ) 136 DpaApiReturnPeripheralError( ERROR_DATA_LEN ); 137 138 i2c_start( I2C_ADR ); // MCP9802 address 139 i2c_write( 0x01 ); // pointer: 1 = configuration register 140 i2c_write( 0x60 ); // configuration: 12-bit ADC 141 i2c_stop(); 142 143 i2c_start( I2C_ADR ); // MCP9802 address 144 i2c_write( 0 ); // pointer: 0 = temperature 145 i2c_stop(); 146 147 i2c_start( I2C_ADR | 1 ); // MCP9802 address + read 148 uns16 temperature @ _DpaMessage.Response.PData; 149 temperature.high8 = i2c_read( TRUE ); // store the result 150 temperature.low8 = i2c_read( FALSE ); 151 i2c_stop(); 152 153 _DpaDataLength = sizeof( temperature ); 154 goto DpaHandleReturnTRUE; 155 156 default: 157 // ------------------------------------------------- 158 // Invalid command 159 DpaApiReturnPeripheralError( ERROR_PCMD ); 160 } 161 } 162 } 163 } 164 165 return FALSE; 166 } 167 168 //############################################################################################ 169 // I2C Master library 170 #include "lib/I2Cmaster.c" 171 // 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) 172 #include "DPAcustomHandler.h" 173 //############################################################################################