1 // *********************************************************************
    2 //   Custom DPA Handler code example - Self Load Code                  *
    3 // *********************************************************************
    4 // Copyright (c) IQRF Tech s.r.o.
    5 //
    6 // File:    $RCSfile: CustomDpaHandler-SelfLoadCode.c,v $
    7 // Version: $Revision: 1.4 $
    8 // Date:    $Date: 2018/10/25 09:51:28 $
    9 //
   10 // Revision history:
   11 //   2018/10/25  Release for DPA 3.03
   12 //
   13 // *********************************************************************
   14 
   15 // Online DPA documentation http://www.iqrf.org/DpaTechGuide/
   16 
   17 // This example demonstrates loading other Custom DPA Handler from the existing one.
   18 // It exists in two variants. The "red" or "green" (see RED below). Based on the variant the corresponding LED is on all the time.
   19 // When a button is pressed the other Custom DPA Handler variant is loaded and started. 
   20 // The example expects that both variants of the example are preloaded at the external EEPROM in the way they can be loaded by CMD_OS_LOAD_CODE command.
   21 // Also, the example expects that there are parameters for CMD_OS_LOAD_CODE for loading the handlers stored at the external EEPROM too.
   22 // Parameters for the "red: variant must be stored at address 0 and for the "green" variant at the address 6 respectively.
   23 // Each set of parameters takes 6 bytes. Parameters have the following format (see https://www.iqrf.org/DpaTechGuide/#3.4.13%20LoadCode for details):
   24 // offset   name          value
   25 // 0        addrLow       lower byte of the corresponding driver .hex image in the external EEPROM
   26 // 1        addrHigh      same as above but higher byte
   27 // 2        lengthLow     lower byte of the corresponding driver .hex image length in the external EEPROM
   28 // 3        lengthHigh    same as above but higher byte
   29 // 4        checksumLow   lower byte of the corresponding driver .hex image checksum in the external EEPROM
   30 // 5        checksumHigh  same as above but higher byte
   31 // 
   32 // IQRF IDE Tools / IQRF Network Manager / Control / Upload can be used to upload both .hex images into the external EEPROM.
   33 // Then Terminal in DPA mode is used to write LoadCode parameters into external EEPROM too.
   34 
   35 // Default IQRF include (modify the path according to your setup)
   36 #include "IQRF.h"
   37 
   38 // Default DPA header (modify the path according to your setup)
   39 #include "DPA.h"
   40 // Default Custom DPA Handler header (modify the path according to your setup)
   41 #include "DPAcustomHandler.h"
   42 
   43 //############################################################################################
   44 
   45 // Defined for the "RED" variant otherwise "GREEN" variant is compiled
   46 #define RED
   47 
   48 // Based on the variant define the variant specific symbols 
   49 #ifdef RED
   50 #define setLED()              setLEDR()
   51 #define pulseOtherLED()       pulseLEDG()
   52 #define OTHER_HANDLER_ADDRESS 6
   53 
   54 #else // #ifdef RED
   55 #define setLED()              setLEDG()
   56 #define pulseOtherLED()       pulseLEDR()
   57 #define OTHER_HANDLER_ADDRESS 0
   58 
   59 #endif
   60 
   61 // Must be the 1st defined function in the source code in order to be placed at the correct FLASH location!
   62 //############################################################################################
   63 bit CustomDpaHandler()
   64 //############################################################################################
   65 {
   66   // Handler presence mark
   67   clrwdt();
   68 
   69   // Detect DPA event to handle (unused event handlers can be commented out or even deleted)
   70   switch ( GetDpaEvent() )
   71   {
   72     // -------------------------------------------------
   73     case DpaEvent_Idle:
   74     {
   75       // Do a quick background work when RF packet is not received
   76 
   77       // Light your LED all the time
   78       setLED();
   79 
   80       // Variable to save last 8 states of the IQRF button to avoid "pressing" button at CK-USB-04x or a button bouncing in general
   81       static uns8 lastButton;
   82       // bit.0 will hold the current button state, so let's make a room for it
   83       lastButton <<= 1;
   84       // Set bit.0 if the button is pressed
   85       if ( buttonPressed )
   86         lastButton |= 1;
   87 
   88       // Was the button kept pressed for the last 7 Idle events?
   89       if ( lastButton == ( (uns8)-1 >> 1 ) )
   90       {
   91         // Read CMD_OS_LOAD_CODE parameters (address, length, checksum) into bufferINFO for loading the other driver
   92         eeeReadData( OTHER_HANDLER_ADDRESS );
   93         // Copy CMD_OS_LOAD_CODE parameters to the correct offset at the DPA request
   94         memoryOffsetTo = offsetof( TPerOSLoadCode_Request, Address );
   95         // Copy loaded parameters from bufferINFO into bufferRF where actually _DpaMessage is
   96         copyBufferINFO2RF();
   97         // We load custom DPA handler stored at .hex format and want to really load it
   98         _DpaMessage.PerOSLoadCode_Request.Flags = 0x01;
   99         // Set peripheral and its command for LoadCode
  100         _PNUM = PNUM_OS;
  101         _PCMD = CMD_OS_LOAD_CODE;
  102         // Length of the DPA request
  103         _DpaDataLength = sizeof( _DpaMessage.PerOSLoadCode_Request );
  104         // Perform LoadCode, if it succeeds the device resets
  105         DpaApiLocalRequest();
  106         // If the LoadCode failed (reason: .hex not loaded at the external EEPROM memory or the LoadCode parameters stored at external EEPROM are incorrect) ...
  107         if ( !_DpaMessage.Response.PData[0].0 )
  108           // Pulse the other LED to indicate error when loading other handler
  109           pulseOtherLED();
  110       }
  111 
  112       break;
  113     }
  114   }
  115 
  116   return FALSE;
  117 }
  118 //############################################################################################
  119 // 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) 
  120 #include "DPAcustomHandler.h"
  121 //############################################################################################