Bar Logo 4kW dsPIC33C PSFB DC-DC DA (Part-No. )
 
Content
     
Loading...
Searching...
No Matches
os_scheduler_1ms.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/os_scheduler_1ms.c
19//
20// @brief contains the main scheduler that calls all the tasks that need to be called regularly
21// two different timings priorities are available:
22// 1. 1ms Tasks called from the scheduler interrupt
23// the jitter that you will have in the 1ms realtime tasks called by the interrupt depends
24// on other interrupts that have a higher interrupt priority
25// 2. 1ms, 10ms, 100ms, 1s Tasks called from the main loop
26// these tasks are for soft realtime and not for hard realtime
27// so in average they are called with the required timing but the jitter can be very huge,
28// depending on the calls before.
29// use this for your non-timing critical application state machines
30//
31// @note put your application specific code in main/main_tasks.c
32// @note you might consider to implement a watchdog and put the watchdog triggering into some Task
33//
34// @version v1.0
35// @date 2019-08-09
36// @author M52409
37//
38//=======================================================================================================
39
40#include <stdint.h>
41#include <xc.h>
42#include "../project_settings.h"
43#if OS_FEATURE_WATCHDOG_ENABLED == 1
44#include "os_watchdog.h"
45#endif
46
47#if OS_USE_SCHEDULER_1ms == 1
48
49#ifndef OS_TIMER_NUMBER_OF_TIMERS
50#warning OS_TIMER_NUMBER_OF_TIMERS needs to be defined in main/project_setting.h
51#endif
52#ifndef OS_USE_SYSTIME
53#warning OS_USE_SYSTIME needs to be defined in main/project_setting.h
54#else
55#include "os_sys_time.h"
56#endif
57#include "os_scheduler.h"
58
63//extern void Tasks_Realtime_1ms(void);
64//extern void Tasks_1ms(void);
65//extern void Tasks_10ms(void);
66//extern void Tasks_100ms(void);
67//extern void Tasks_1s(void);
68//extern void Tasks_Background(void);
69
70//=======================================================================================================
71//
72// put your application specific code in the following functions in main/main_tasks.c
73// choose wisely between real-time and non-realtime!
74//
75// Interrupt Realtime Functions:
76// Tasks_Realtime_1ms : is called by the interrupt every ms - for time critical low jitter stuff
77//
78//
79// Mainloop Non-Realtime Functions:
80// Tasks_1ms : function is called by the main loop in average every 1ms
81// Tasks_10ms : function is called by the main loop in average every 10ms
82// Tasks_100ms : function is called by the main loop in average every 100ms
83// Tasks_1s : function is called by the main loop in average every second
84//
85// @note there could be some jitter here because it is not called directly by a timer interrupt
86// the timing in average is exact (keep in mind: in average), the jitter depends on the
87// called functions before
88//=======================================================================================================
89
90#if OS_TIMER_NUMBER_OF_TIMERS > 0
91 void OS_Timer_Tick(void);
92#endif
93
94static volatile uint16_t scheduler_interrupt_leader_1ms = 0;
95static volatile uint16_t scheduler_interrupt_follower_1ms = 0;
96volatile static uint16_t scheduler_1ms_timer = 0; // local counter for 1ms tasks
97volatile static uint16_t scheduler_10ms_timer = 0; // local counter for 10ms tasks
98volatile static uint16_t scheduler_100ms_timer = 0; // local counter for 100ms tasks
99volatile static uint16_t scheduler_1s_timer = 0; // local counter for 1s tasks
100
101// Timer 1 bit field settings
102#define T1ON 1 // 1 = En, 0 = disabled
103#define T1TCS 0 // 1 = External Clock, 0 = Peripheral Clock
104#define T1TCKPS 1 // 3 = 1:256, 2 = 1:64, 1 = 1:8, 0 = 1:1
105
106#if OS_USE_MCC_TIMER1 == 0
107static inline void OS_Scheduler_Init_Timer1(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.TECS = 0b01; //FCY
120 //T1CONbits.TGATE = 0; // Timer1 Gated Time Accumulation Enable: Gated time accumulation is disabled when TCS = 0
121 //T1CONbits.TCKPS = 0; // Timer1 Input Clock Prescale Select: 1:1
122 T1CONbits.TCKPS = 0b01; // Timer1 Input Clock Prescale Select: 1:8
123 T1CONbits.TSYNC = 0; // Timer1 External Clock Input Synchronization Select: Does not synchronize the External Clock input
124 //T1CONbits.TCS = 0; // Timer1 Clock Source Select: Internal peripheral clock
125 T1CONbits.TCS = 1; // Timer1 Clock Source Select: based on TECS value
126
127 TMR1 = 0x00; // Reset Timer Counter Register TMR to Zero;
128 PR1 = 9999; // Period = 0.0001 s; Frequency = 100000000 Hz; PR 9999
129
130 //TODO: these two lines are from the qi initialization: check/synchronize with the above init
131 // Initialize Timer 1 - Period: 1 ms
132 PR1 = (FCY / 1000 / 8);
133 T1CON = ((T1ON << 15) | (T1TCKPS << 4) | (T1TCS));
134
135 // in the master/slave version the slave had priority 4
136 IPC0bits.T1IP = 1; // Set interrupt priority to one (cpu is running on ip zero)
137 IFS0bits.T1IF = 0; // Reset interrupt flag bit
138
139 //Switch on Timer 1
140 IEC0bits.T1IE = 1; // Enable Timer1 interrupt
141 T1CONbits.TON = 1; // Enable Timer1
142}
143#endif
144
145//=======================================================================================================
146// @brief Initializes Scheduler
147// @note call this function in your main routine before calling the RunForever function
148//=======================================================================================================
149void OS_Scheduler_Init(void)
150{
151#if OS_USE_MCC_TIMER1 == 0
152 OS_Scheduler_Init_Timer1();
153#endif
154
155#if OS_USE_SYSTIME == 1
156 OS_SysTime_ResetTime();
157#endif //OS_USE_SYSTIME
158 scheduler_interrupt_leader_1ms = 0U; // reset directly before calling the Scheduler Loop
159 scheduler_interrupt_follower_1ms = 0U; // reset directly before calling the Scheduler Loop
160}
161
162//=======================================================================================================
163// @brief 1ms Timer 1 interrupt routine for generating the timing for the scheduler
164// @note with this simple implementation we do not lose any tick from the timer, even when the tasks
165// in the main loop take longer than 1ms
166//=======================================================================================================
167#if OS_USE_MCC_TIMER1 == 1
168/* TMR1_CallBack is a weak linked function in the tmr1.c */
169/* LDRA_EXCLUDE 34 D */
170void TMR1_CallBack(void)
171#else
172void __attribute__((__interrupt__,no_auto_psv)) _T1Interrupt(void)
173#endif
174{
175 scheduler_interrupt_leader_1ms++; //increment our counter for the scheduler, no tick gets lost
176 _T1IF = 0; //clear Timer1 interrupt flag
177#if OS_TIMER_NUMBER_OF_TIMERS > 0
178 OS_Timer_Tick();
179#endif
180#if OS_USE_SYSTIME == 1
181 OS_SysTime_IncrementTime_1ms();
182#endif //OS_USE_SYSTIME
183 Tasks_Realtime_1ms();
184}
185
186//=======================================================================================================
187// @brief Scheduler function for calling all the Tasks regularly ( 1ms, 10ms, 100ms, 1s )
188// @note call this function in your main loop in main.c after calling the Init-function
189// if you have nothing else to call in your main loop then you can call the function
190// Main_Scheduler_RunForever() instead.
191// please consider that the timing of the calls are dependent on the duration of the last call
192// the resulting jitter therefore depends on the timing of the calls before
193//=======================================================================================================
194/* OS_Scheduler_RunOnce is called in main. But is being reported as not being
195 called */
196/* LDRA_EXCLUDE 61 D */
197void OS_Scheduler_RunOnce(void)
198{
199 if (scheduler_interrupt_follower_1ms != scheduler_interrupt_leader_1ms)
200 {
201 scheduler_interrupt_follower_1ms++;
202 Tasks_1ms(); //call 1 ms tasks
203 scheduler_10ms_timer += 1U;
204 if (scheduler_10ms_timer >= 10U)
205 {
206 scheduler_10ms_timer = 0U; //reset 10 ms timer
207 Tasks_10ms(); //call 10 ms tasks
208 scheduler_100ms_timer += 1U;
209 if (scheduler_100ms_timer >= 10U)
210 {
211 scheduler_100ms_timer = 0U; //reset 100 ms timer
212 Tasks_100ms(); //call 100 ms tasks
213 scheduler_1s_timer += 1U;
214 if (scheduler_1s_timer >= 10U)
215 {
216 scheduler_1s_timer = 0U;
217 #if OS_FEATURE_WATCHDOG_ENABLED == 1
218 OS_Watchdog_KeepAlivePing();
219 #endif
220 Tasks_1s(); //call 1 s tasks
221 }
222 }
223 }
224 }
225 else
226 {
227 Tasks_Background(); // run the background tasks with their own timing
228 }
229}
230
231//=======================================================================================================
232// @brief Scheduler function for calling all the Tasks regularly ( 1ms, 10ms, 100ms, 1s )
233// @note call this function as last function in main.c after calling the Init-function
234// please consider that the timing of the calls are dependent on the duration of the last call
235// the resulting jitter therefore depends on the timing of the calls before
236//=======================================================================================================
237void OS_Scheduler_RunForever(void)
238{
239 // do some initialization
240 scheduler_interrupt_leader_1ms = 0U; // reset directly before calling the Scheduler Loop
241 scheduler_interrupt_follower_1ms = 0U; // reset directly before calling the Scheduler Loop
242
243 /* LDRA_EXCLUDE 28 D */
244 while (1) // run that loop forever
245 {
246 /* OS_Scheduler_RunOnce() is not called in this application, but is
247 available to do so */
248 /* LDRA_EXCLUDE 61 D */
249 OS_Scheduler_RunOnce();
250 }
251}
252
253#endif //OS_USE_SCHEDULER_1ms
void __attribute__((__interrupt__, auto_psv))
Executes the power converter control loop.
Definition main.c:101