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