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