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