1 // *********************************************************************
    2 //   Custom DPA Handler code example - Using TMR6 MCU timer            *
    3 // *********************************************************************
    4 // Copyright (c) IQRF Tech s.r.o.
    5 //
    6 // File:    $RCSfile: CustomDpaHandler-Timer.c,v $
    7 // Version: $Revision: 1.28 $
    8 // Date:    $Date: 2017/08/09 12:24:47 $
    9 //
   10 // Revision history:
   11 //   2017/03/13  Release for DPA 3.00
   12 //   2016/09/12  Release for DPA 2.28
   13 //   2015/08/05  Release for DPA 2.20
   14 //   2014/10/31  Release for DPA 2.10
   15 //   2014/04/30  Release for DPA 2.00
   16 //
   17 // *********************************************************************
   18 
   19 // Online DPA documentation http://www.iqrf.org/DpaTechGuide/
   20 
   21 // Default IQRF include (modify the path according to your setup)
   22 #include "IQRF.h"
   23 
   24 // Default DPA header (modify the path according to your setup)
   25 #include "DPA.h"
   26 // Default Custom DPA Handler header (modify the path according to your setup)
   27 #include "DPAcustomHandler.h"
   28 
   29 // This example initializes TMR6 (at Reset or Init event) and uses it to pulse LED at Idle event
   30 // This example works only at STD mode, not at LP mode
   31 
   32 // If next symbol is defined then initialize timer at Reset event so it could be used already during Reset events (custom un/bonding)
   33 //#define   EARLY_INITIALIZATION
   34 
   35 // The example will not work at demo DPA version because demo DPA does not support the following Custom DPA Handler events: DpaEvent_Interrupt, DpaEvent_BeforeSleep, DpaEvent_AfterSleep, DpaEvent_Reset, DpaEvent_DisableInterrupts, DpaEvent_ReceiveDpaResponse, DpaEvent_IFaceReceive, DpaEvent_ReceiveDpaRequest, DpaEvent_BeforeSendingDpaResponse
   36 
   37 // Must be the 1st defined function in the source code in order to be placed at the correct FLASH location!
   38 //############################################################################################
   39 bit CustomDpaHandler()
   40 //############################################################################################
   41 {
   42   // Handler presence mark
   43   clrwdt();
   44 
   45   // Place for local static variables used only within CustomDpaHandler() among more events
   46   static uns8 tmrCounter;
   47 
   48   // Detect DPA event to handle
   49   switch ( GetDpaEvent() )
   50   {
   51     // -------------------------------------------------
   52     case DpaEvent_Interrupt:
   53       // Do an extra quick background interrupt work
   54       // ! 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.
   55       // ! 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.
   56       // ! 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.
   57       // ! Only global variables or local ones marked by static keyword can be used to allow reentrancy.
   58       // ! Make sure race condition does not occur when accessing those variables at other places.
   59       // ! 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.
   60       // ! Do not call any OS functions except setINDFx().
   61       // ! Do not use any OS variables especially for writing access.
   62       // ! 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.
   63 
   64       //  If TMR6 interrupt occurred
   65       if ( TMR6IF )
   66       {
   67         // Unmask interrupt
   68         TMR6IF = 0;
   69         // Decrement count
   70         if ( tmrCounter != 0 )
   71           tmrCounter--;
   72       }
   73 
   74 DpaHandleReturnTRUE:
   75       return TRUE;
   76 
   77     // -------------------------------------------------
   78     case DpaEvent_Idle:
   79       // Do a quick background work when RF packet is not received
   80 
   81       if ( tmrCounter == 0 )
   82       {
   83         // Pulse LEDR every 1.0 s
   84         tmrCounter = 1000 / 10;
   85         pulseLEDG();
   86       }
   87 
   88       break;
   89 
   90     // -------------------------------------------------
   91 #ifdef EARLY_INITIALIZATION
   92     case DpaEvent_Reset:
   93       // Called after module is reset
   94       // Could be called more times, but initialize Timer only once
   95       if ( !TMR6IE )
   96 #else
   97     // -------------------------------------------------
   98     case DpaEvent_Init:
   99       // Do a one time initialization work before main loop starts
  100 #endif
  101     {
  102       // Setup TMR6 to generate ticks on the background (ticks every 10ms)
  103 #if F_OSC == 16000000
  104       PR6 = 250 - 1;
  105       T6CON = 0b0.1001.1.10;    // Prescaler 16, Postscaler 10, 16 * 10 * 250 = 40000 = 4MHz * 10ms
  106 #else
  107 #error Unsupported oscillator frequency
  108 #endif
  109 
  110       TMR6IE = TRUE;
  111     }
  112     break;
  113 
  114     // -------------------------------------------------
  115     case DpaEvent_AfterSleep:
  116       // Called on wake-up from sleep
  117       TMR6IE = TRUE;
  118       TMR6ON = TRUE;
  119       break;
  120 
  121     // -------------------------------------------------
  122     case DpaEvent_BeforeSleep:
  123       // Called before going to sleep   (the same handling as DpaEvent_DisableInterrupts event)
  124       // To minimize the power consumption, no MCU pin must be left as a digital input without defined input level value.
  125       //   So, unused pins in given hardware should be set as outputs:
  126                                 // Generated by IQRF IDE according to the TR selection in a project
  127 #if defined(TR72D)
  128                                 // TR pin C1 (MCU pin RA0): should be set as an output
  129       LATA.0 = 0;                   // Low level
  130       TRISA.0 = 0;                  // Output
  131 
  132                                 // TR pin C2 (MCU pin RC2): should be set as an output
  133       LATC.2 = 0;                   // Low level
  134       TRISC.2 = 0;                  // Output
  135 
  136                                 // TR pin C5 (MCU pins RA5, RB4 and RC6 connected in parallel):
  137                                 //   All MCU pins can be set as an input, but pin RB4 must be configured with internal pull-up (default activated).
  138       TRISA.5 = 1;                  // Input
  139       TRISB.4 = 1;                  // Input
  140       TRISC.6 = 1;                  // Input
  141 
  142                                 // TR pin C6 (MCU pin RC3): should be set as an output
  143       LATC.3 = 0;                   // Low level
  144       TRISC.3 = 0;                  // Output
  145 
  146                                 // TR pin C7 (MCU pin RC4): should be set as an output
  147       LATC.4 = 0;                   // Low level
  148       TRISC.4 = 0;                  // Output
  149 
  150                                 // TR pin C8 (MCU pins RC5 and RC7 connected in parallel):
  151                                 //   Only one MCU pin should be set as an output
  152       LATC.5 = 0;                   // Low level
  153       TRISC.5 = 0;                  // Output
  154       TRISC.7 = 1;                  // Input
  155 
  156 #elif defined(TR76D)
  157                                 // TR pin Q14 (MCU pin RA0): should be set as an output
  158       LATA.0 = 0;                   // Low level
  159       TRISA.0 = 0;                  // Output
  160 
  161                                 // TR pin Q15 (MCU pin RC2): should be set as an output
  162       LATC.2 = 0;                   // Low level
  163       TRISC.2 = 0;                  // Output
  164 
  165                                 // TR pin Q4 (MCU pin RC6): should be set as an output
  166       LATC.6 = 0;                   // Low level
  167       TRISC.6 = 0;                  // Output
  168 
  169                                 // TR pin Q5 (MCU pin RC7): should be set as an output
  170       LATC.7 = 0;                   // Low level
  171       TRISC.7 = 0;                  // Output
  172 
  173                                 // TR pin Q6 (MCU pin RC3): should be set as an output
  174       LATC.3 = 0;                   // Low level
  175       TRISC.3 = 0;                  // Output
  176 
  177                                 // TR pin Q7 (MCU pin RC4): should be set as an output
  178       LATC.4 = 0;                   // Low level
  179       TRISC.4 = 0;                  // Output
  180 
  181                                 // TR pin Q8 (MCU pin RC5): should be set as an output
  182       LATC.5 = 0;                   // Low level
  183       TRISC.5 = 0;                  // Output
  184 
  185                                 // TR pin Q9 (MCU pin RA5): should be set as an output
  186       LATA.5 = 0;                   // Low level
  187       TRISA.5 = 0;                  // Output
  188 
  189                                 // TR LED pins Q10 and Q11 (MCU pins RB7 and RA2) are set as outputs by OS.
  190                                 // TR pin Q12 (MCU pin RB4) is set as an input with internal pull-up activated as default.
  191 #else
  192       #warning Unsupported TR module selected. Modify the pin setting.
  193 #endif
  194     // -------------------------------------------------
  195     case DpaEvent_DisableInterrupts:
  196       // Called when device needs all hardware interrupts to be disabled (before Reset, Restart and RFPGM)
  197       // Must not use TMR6 any more
  198       TMR6ON = FALSE;
  199       TMR6IE = FALSE;
  200       break;
  201   }
  202 
  203   return FALSE;
  204 }
  205 //############################################################################################
  206 // 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) 
  207 #include "DPAcustomHandler.h"
  208 //############################################################################################