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 //############################################################################################