Bar Logo 4kW dsPIC33C PSFB DC-DC DA (Part-No. )
 
Content
     
Loading...
Searching...
No Matches
os_scheduler_100us.c
1//=======================================================================================================
2// Copyright(c) 2018 Microchip Technology Inc. and its subsidiaries.
3// Subject to your compliance with these terms, you may use Microchip software and any derivatives
4// exclusively with Microchip products. It is your responsibility to comply with third party license
5// terms applicable to your use of third-party software (including open source software) that may
6// accompany Microchip software.
7// THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY,
8// APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND
9// FITNESS FOR A PARTICULAR PURPOSE.
10// IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
11// LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF
12// MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
13// ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT
14// EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
15//=======================================================================================================
16
17//=======================================================================================================
18// @file os_scheduler_100us.c
19//
20// @brief contains the 100�s scheduler that calls all the tasks that need to be called regularly
21// two different timing priorities are available:
22// 1. 100�s and 1ms Tasks called from the scheduler interrupt
23// the jitter that you will have in the 100�s realtime tasks called by the interrupt depends
24// on other interrupts that have a higher interrupt priority
25// the jitter that you will have in the 1ms realtime tasks called by the interrupt depends
26// on other interrupts that have a higher interrupt priority amd by the duration of the
27// 100�s realtime task
28// 2. 100�s, 1ms, 10ms, 100ms, 1s Tasks called from the main loop
29// these tasks are for soft realtime and not for hard realtime
30// so in average they are called with the required timing but the jitter can be very huge,
31// depending on the calls before.
32// use this for your non-timing critical application state machines
33//
34// @note put your application specific code in main/main_scheduler.c
35//
36// @version v1.0
37// @date 2019-08-29
38// @author M52409
39//
40//=======================================================================================================
41
42#include <stdint.h>
43#include <xc.h>
44#include "../project_settings.h"
45#include "os/os_sys_time.h"
46#if OS_FEATURE_WATCHDOG_ENABLED == 1
47#include "os_watchdog.h"
48#endif
49
50#if OS_USE_SCHEDULER_100us == 1
51
52#ifndef OS_TIMER_NUMBER_OF_TIMERS
53#warning OS_TIMER_NUMBER_OF_TIMERS needs to be defined in main/project_setting.h
54#endif
55#ifndef OS_USE_SYSTIME
56#warning OS_USE_SYSTIME needs to be defined in main/project_setting.h
57#endif
58#include "os/os_scheduler.h"
59#include "timer/tmr1.h"
60
61//=======================================================================================================
62// The following extern Tasks_... functions should be placed in the file main/main_tasks.c
63// call OS_Scheduler_Run() in the main loop or call OS_Scheduler_RunForever() in main.c
64//=======================================================================================================
65//void Tasks_Realtime_100us(void);
66//void Tasks_Realtime_1ms(void);
67//void Tasks_100us(void);
68//void Tasks_1ms(void);
69//void Tasks_10ms(void);
70//void Tasks_100ms(void);
71//void Tasks_1s(void);
72//void Tasks_Background(void);
73
74void TMR1_CallBack(void);
75
76//=======================================================================================================
77//
78// put your application specific code in the file main/main_scheduler.c in the following functions:
79// choose wisely between real-time and non-realtime!
80//
81// Interrupt Realtime Functions:
82// Tasks_Realtime_100us: is called by the 100�s interrupt - for time critical low jitter stuff
83// Tasks_Realtime_1ms : is called by the interrupt every ms - for time critical low jitter stuff
84//
85//
86// Mainloop Non-Realtime Functions:
87// Tasks_100us : function is called by the main loop in average every 100�s
88// Tasks_1ms : function is called by the main loop in average every 1ms
89// Tasks_10ms : function is called by the main loop in average every 10ms
90// Tasks_100ms : function is called by the main loop in average every 100ms
91// Tasks_1s : function is called by the main loop in average every second
92//
93// @note there could be some jitter here because it is not called directly by a timer interrupt
94// the timing in average is exact (keep in mind: in average), the jitter depends on the
95// called functions before
96//=======================================================================================================
97
98#if OS_TIMER_NUMBER_OF_TIMERS > 0
99 void OS_Timer_Tick(void);
100#endif
101
102static volatile uint16_t scheduler_interrupt_leader_100us = 0;
103static volatile uint16_t scheduler_interrupt_follower_100us = 0;
104static volatile uint8_t scheduler_interrupt_realtime_counter_1ms = 0;
105
106#if OS_USE_MCC_TIMER1 == 0
107static inline void OS_Scheduler_Init_Timer1_100us(void)
108{
109 //Switch off Timer 1
110 T1CONbits.TON = 0; // Disable Timer1
111 IEC0bits.T1IE = 0; // Disable Timer1 interrupt
112
113 //Configure Timer 1
114 T1CONbits.TSIDL = 0; // Timer1 Stop in Idle Mode: Continues module operation in Idle mode
115 T1CONbits.TMWDIS = 0; // Asynchronous Timer1 Write Disable: Back-to-back writes are enabled in Asynchronous mode
116 T1CONbits.TMWIP = 0; // Asynchronous Timer1 Write in Progress: Write to the timer in Asynchronous mode is complete
117 T1CONbits.PRWIP = 0; // Asynchronous Period Write in Progress: Write to the Period register in Asynchronous mode is complete
118 T1CONbits.TECS = 0b11; // Timer1 Extended Clock Select: FRC clock
119 T1CONbits.TGATE = 0; // Timer1 Gated Time Accumulation Enable: Gated time accumulation is disabled when TCS = 0
120 T1CONbits.TCKPS = 0; // Timer1 Input Clock Prescale Select: 1:1
121 T1CONbits.TCKPS = 0; // Timer1 Input Clock Prescale Select: 1:1
122 T1CONbits.TSYNC = 0; // Timer1 External Clock Input Synchronization Select: Does not synchronize the External Clock input
123 T1CONbits.TCS = 0; // Timer1 Clock Source Select: Internal peripheral clock
124
125 TMR1 = 0x00; // Reset Timer Counter Register TMR to Zero;
126 PR1 = 9999; // Period = 0.0001 s; Frequency = 100000000 Hz; PR 9999
127
128 IPC0bits.T1IP = 1; // Set interrupt priority to one (cpu is running on ip zero)
129 IFS0bits.T1IF = 0; // Reset interrupt flag bit
130
131 //Switch on Timer 1
132 IEC0bits.T1IE = 1; // Enable Timer1 interrupt
133 T1CONbits.TON = 1; // Enable Timer1
134
135}
136#endif
137
138//=======================================================================================================
143//=======================================================================================================
144void OS_Scheduler_Init(void)
145{
146 #if OS_USE_MCC_TIMER1 == 0
147 OS_Scheduler_Init_Timer1_100us();
148 #endif
149#if OS_USE_SYSTIME == 1
150 OS_SysTime_ResetTime();
151#endif //OS_USE_SYSTIME
152 scheduler_interrupt_leader_100us = 0U; // reset directly before calling the Scheduler Loop
153 scheduler_interrupt_follower_100us = 0U; // reset directly before calling the Scheduler Loop
154
155 //TMR1_TimeoutCallbackRegister (TMR1_CallBack); // melody breaks the naming convention, therefore manually registering the name.
156}
157
158
159//=======================================================================================================
165//=======================================================================================================
166#if OS_USE_MCC_TIMER1 == 1
167/* TMR1_CallBack is a weak linked function in the tmr1.c */
168/* LDRA_EXCLUDE 34 D */
169void TMR1_CallBack(void)
170#else
171void __attribute__((__interrupt__,no_auto_psv)) _T1Interrupt(void)
172#endif
173{
174 scheduler_interrupt_leader_100us++; //increment our counter for the scheduler, no tick gets lost
175 _T1IF = 0; //clear Timer1 interrupt flag
176#if OS_TIMER_NUMBER_OF_TIMERS > 0
177 OS_Timer_Tick();
178#endif
179 Tasks_Realtime_100us();
180 scheduler_interrupt_realtime_counter_1ms += 1U;
181 if (scheduler_interrupt_realtime_counter_1ms >= 10U)
182 {
183#if OS_USE_SYSTIME == 1
184 OS_SysTime_IncrementTime_1ms();
185#endif //OS_USE_SYSTIME
186 Tasks_Realtime_1ms();
187 scheduler_interrupt_realtime_counter_1ms = 0U;
188 }
189}
190
191
192//=======================================================================================================
199//=======================================================================================================
200/* OS_Scheduler_RunOnce() is not called in this application, but is
201 available to do so */
202/* LDRA_EXCLUDE 61 D */
203void OS_Scheduler_RunOnce(void)
204 {
205 volatile static uint16_t scheduler_1ms_timer = 0U; // local counter for 1ms tasks
206 volatile static uint16_t scheduler_10ms_timer = 0U; // local counter for 10ms tasks
207 volatile static uint16_t scheduler_100ms_timer = 0U; // local counter for 100ms tasks
208 volatile static uint16_t scheduler_1s_timer = 0U; // local counter for 1s tasks
209
210 //TODO: should we implement a Watchdog that gets triggered in one of the Task-Routines?
211
212 if (scheduler_interrupt_follower_100us != scheduler_interrupt_leader_100us)
213 {
214 scheduler_interrupt_follower_100us += 1U;
215 Tasks_100us(); //call 100�s tasks
216 scheduler_1ms_timer += 1U;
217 if (scheduler_1ms_timer >= 10U)
218 {
219 scheduler_1ms_timer = 0U; //reset 1 ms timer
220 Tasks_1ms(); //call 1 ms tasks
221 scheduler_10ms_timer += 1U;
222 if (scheduler_10ms_timer >= 10U)
223 {
224 scheduler_10ms_timer = 0U; //reset 10 ms timer
225 Tasks_10ms(); //call 10 ms tasks
226 scheduler_100ms_timer += 1U;
227 if (scheduler_100ms_timer >= 10U)
228 {
229 scheduler_100ms_timer = 0U; //reset 100 ms timer
230 Tasks_100ms(); //call 100 ms tasks
231 scheduler_1s_timer += 1U;
232 if (scheduler_1s_timer >= 10U)
233 {
234 scheduler_1s_timer = 0U;
235 #if OS_FEATURE_WATCHDOG_ENABLED == 1
236 OS_Watchdog_KeepAlivePing();
237 #endif
238 Tasks_1s(); //call 1 s tasks
239 }
240 }
241 }
242 }
243 }
244 else
245 {
246 Tasks_Background(); // run the background tasks with their own timing
247 }
248}
249
250
251//=======================================================================================================
258//=======================================================================================================
259void OS_Scheduler_RunForever(void)
260{
261 // do some initialization
262 scheduler_interrupt_leader_100us = 0U; // reset directly before calling the Scheduler Loop
263 scheduler_interrupt_follower_100us = 0U; // reset directly before calling the Scheduler Loop
264
265 /*The while loop below is intended to run forever therefore 28 D is
266 excluded */
267 /* LDRA_EXCLUDE 28 D */
268 while (1) // run that loop forever
269 {
270 OS_Scheduler_RunOnce();
271#if (X2CDEBUG_ENABLED == 1)
272 X2CScope_Communicate();
273#endif
274
275 }
276}
277
278#endif //OS_USE_SCHEDULER_100us
This is the generated driver header file for the TMR1 driver.
void __attribute__((__interrupt__, auto_psv))
Executes the power converter control loop.
Definition main.c:101