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.32 $
    8 // Date:    $Date: 2024/10/25 13:21:28 $
    9 //
   10 // Revision history:
   11 //   2022/02/24  Release for DPA 4.17
   12 //   2021/08/20  Release for DPA 4.16
   13 //   2020/01/02  Release for DPA 4.11
   14 //   2017/03/13  Release for DPA 3.00
   15 //   2015/12/01  Release for DPA 2.24
   16 //   2015/08/05  Release for DPA 2.20
   17 //
   18 // *********************************************************************
   19 
   20 // Online DPA documentation https://doc.iqrf.org/DpaTechGuide/
   21 
   22 // This example implements the user peripheral reading from MCP9802 at DDC-SE-01
   23 // PNUM = 0x20 and PCMD = 0 returns 2 bytes with result read from MCP9802
   24 // Based on example DDC-SE-01-i2c.c
   25 
   26 // Default IQRF include (modify the path according to your setup)
   27 #include "IQRF.h"
   28 
   29 // Default DPA header (modify the path according to your setup)
   30 #include "DPA.h"
   31 // Default Custom DPA Handler header (modify the path according to your setup)
   32 #include "DPAcustomHandler.h"
   33 
   34 //############################################################################################
   35 
   36 // I2C SCL frequency [Hz]
   37 #define I2Cfrequency        50000
   38 
   39 #define I2C_ADR             0b10010110
   40 
   41 // Must be the 1st defined function in the source code in order to be placed at the correct FLASH location!
   42 //############################################################################################
   43 bit CustomDpaHandler()
   44 //############################################################################################
   45 {
   46   // Handler presence mark
   47   clrwdt();
   48 
   49   // Detect DPA event to handle
   50   switch ( GetDpaEvent() )
   51   {
   52     // -------------------------------------------------
   53     case DpaEvent_Interrupt:
   54       // Do an extra quick background interrupt work
   55 
   56       return Carry;
   57 
   58       // -------------------------------------------------
   59     case DpaEvent_Init:
   60       // Do a one time initialization before main loop starts
   61     case DpaEvent_AfterSleep:
   62       // Called after woken up after sleep
   63 
   64 #if defined( TR7xG )
   65       // Do PPS for I2C
   66       unlockPPS();
   67       SSP1CLKPPS = 0x13;  // RC3
   68       SSP1DATPPS = 0x14;  // RC4
   69       RC3PPS = 0x14;      // SCK1/SCL1
   70       RC4PPS = 0x15;      // SD01/SDA1
   71       lockPPS();
   72 #endif
   73       I2Ctimeout = 0xFF;
   74       DpaApiI2Cinit( I2CcomputeFrequency( I2Cfrequency ) );
   75 
   76       break;
   77 
   78       // -------------------------------------------------
   79     case DpaEvent_BeforeSleep:
   80       // Called before going to sleep
   81 
   82       DpaApiI2Cshutdown();
   83       break;
   84 
   85       // -------------------------------------------------
   86     case DpaEvent_DpaRequest:
   87       // Called to interpret DPA request for peripherals
   88       // -------------------------------------------------
   89       // Peripheral enumeration
   90       if ( IsDpaEnumPeripheralsRequest() )
   91       {
   92         // We implement 1 user peripheral
   93         _DpaMessage.EnumPeripheralsAnswer.UserPerNr |= 1;
   94         FlagUserPer( _DpaMessage.EnumPeripheralsAnswer.UserPer, PNUM_USER + 0 );
   95         _DpaMessage.EnumPeripheralsAnswer.HWPID |= 0x000F;
   96         _DpaMessage.EnumPeripheralsAnswer.HWPIDver |= 0xAbCd;
   97 
   98 DpaHandleReturnTRUE:
   99         return TRUE;
  100       }
  101       // -------------------------------------------------
  102       // Get information about peripheral
  103       else if ( IsDpaPeripheralInfoRequest() )
  104       {
  105         if ( _PNUM == PNUM_USER + 0 )
  106         {
  107           _DpaMessage.PeripheralInfoAnswer.PerT = PERIPHERAL_TYPE_USER_AREA;
  108           _DpaMessage.PeripheralInfoAnswer.PerTE = PERIPHERAL_TYPE_EXTENDED_READ;
  109           goto DpaHandleReturnTRUE;
  110         }
  111 
  112         break;
  113       }
  114       // -------------------------------------------------
  115       else
  116       {
  117         // Handle peripheral command
  118         if ( _PNUM == PNUM_USER + 0 )
  119         {
  120           // Check command
  121           switch ( _PCMD )
  122           {
  123             case 0:
  124               // -------------------------------------------------
  125               // Read temperature
  126               if ( _DpaDataLength != 0 )
  127                 DpaApiReturnPeripheralError( ERROR_DATA_LEN );
  128 
  129               _DpaApiI2Cstart( I2C_ADR );                 // MCP9802 address
  130               _DpaApiI2Cwrite( 0x01 );                    // pointer: 1 = configuration register
  131               _DpaApiI2CwriteAndStop( 0x60 );             // configuration: 12-bit ADC
  132 
  133               _DpaApiI2Cstart( I2C_ADR );                 // MCP9802 address
  134               _DpaApiI2CwriteAndStop( 0 );                // pointer: 0 = temperature
  135 
  136               _DpaApiI2Cstart( I2C_ADR | 1 );             // MCP9802 address + read
  137               uns16 temperature @ _DpaMessage.Response.PData;
  138               temperature.high8 = _DpaApiI2Cread( TRUE );  // store the result
  139               temperature.low8 = _DpaApiI2Cread( FALSE );
  140               _DpaApiI2Cstop();
  141 
  142               _DpaDataLength = sizeof( temperature );
  143               goto DpaHandleReturnTRUE;
  144           }
  145         }
  146       }
  147   }
  148 
  149   return FALSE;
  150 }
  151 
  152 //############################################################################################
  153 // Default Custom DPA Handler header; 2nd include implementing a Code bumper to detect too long code of the Custom DPA Handler (modify the path according to your setup)
  154 #include "DPAcustomHandler.h"
  155 //############################################################################################