Choco OS  V.0.16.9.0
Join to the chocolate world
oc_timer.c
Go to the documentation of this file.
1 
27 #include <oc_timer.h>
28 #define DRIVER_NAME TIMER
29 #define DRIVER_FILE_NAME "timer"
30 #define DRIVER_VERSION oC_Driver_MakeVersion(0,1,0)
31 #define REQUIRED_DRIVERS
32 #define REQUIRED_BOOT_LEVEL oC_Boot_Level_0
33 #define DRIVER_SOURCE
34 
35 // DRIVER INTERFACE
36 #define DRIVER_CONFIGURE oC_TIMER_Configure
37 #define DRIVER_UNCONFIGURE oC_TIMER_Unconfigure
38 #define DRIVER_TURN_ON oC_TIMER_TurnOn
39 #define DRIVER_TURN_OFF oC_TIMER_TurnOff
40 #define IS_TURNED_ON oC_TIMER_IsTurnedOn
41 #include <oc_driver.h>
42 #include <oc_memman.h>
43 #include <oc_mutex.h>
44 #include <oc_threadman.h>
45 #include <oc_gpio_lld.h>
46 #include <oc_stdlib.h>
47 #include <oc_object.h>
48 #include <oc_array.h>
49 #include <oc_intman.h>
50 
56 #define _________________________________________TYPES_SECTION______________________________________________________________________________
57 
58 struct Context_t
59 {
61  oC_TIMER_Channel_t Channel;
62  oC_TIMER_LLD_SubTimer_t SubTimer;
63 };
64 
65 #undef _________________________________________TYPES_SECTION______________________________________________________________________________
66 
72 #define _________________________________________LOCAL_PROTOTYPES_SECTION___________________________________________________________________
73 
74 static void EventHandler ( void * Address , MemoryEventFlags_t Event , const char * Function, uint32_t LineNumber );
75 static bool IsModeCorrect ( oC_TIMER_Mode_t Mode );
76 static bool IsContextCorrect ( oC_TIMER_Context_t Context );
77 static bool PinMustBeConnected ( const oC_TIMER_Config_t * Config );
78 static oC_ErrorCode_t ConnectPeripheralPin ( oC_TIMER_Channel_t Channel , oC_TIMER_LLD_SubTimer_t SubTimer , const oC_TIMER_Config_t * Config );
79 
80 #undef _________________________________________LOCAL_PROTOTYPES_SECTION___________________________________________________________________
81 
82 
83 
89 #define _________________________________________VARIABLES_SECTION__________________________________________________________________________
90 
91 static const oC_Allocator_t ModuleAllocator = {
92  .Name = "timer" ,
93  .EventHandler = EventHandler ,
94  .EventFlags = MemoryEventFlags_MemoryReleased
95 };
96 
97 static bool ModuleEnabledFlag = false;
98 static oC_Mutex_t ModuleBusyMutex = NULL;
99 
100 #undef _________________________________________VARIABLES_SECTION__________________________________________________________________________
101 
102 
108 #define _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
109 
112 //==========================================================================================================================================
113 //==========================================================================================================================================
114 oC_ErrorCode_t oC_TIMER_TurnOn( void )
115 {
116  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
117 
118  if(oC_AssignErrorCodeIfFalse(&errorCode , !ModuleEnabledFlag , oC_ErrorCode_ModuleIsTurnedOn))
119  {
120  errorCode = oC_TIMER_LLD_TurnOnDriver();
121 
122  if((errorCode == oC_ErrorCode_ModuleIsTurnedOn) || (errorCode == oC_ErrorCode_None))
123  {
124  ModuleBusyMutex = oC_Mutex_New(oC_Mutex_Type_Normal,&ModuleAllocator,AllocationFlags_NoWait);
125  ModuleEnabledFlag = true;
126  errorCode = oC_ErrorCode_None;
127  }
128  }
129 
130  return errorCode;
131 }
132 
133 //==========================================================================================================================================
134 //==========================================================================================================================================
135 oC_ErrorCode_t oC_TIMER_TurnOff( void )
136 {
137  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
138 
139  if(oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag , oC_ErrorCode_ModuleNotStartedYet))
140  {
141  ModuleEnabledFlag = false;
142  errorCode = oC_TIMER_LLD_TurnOffDriver();
143 
144  oC_Mutex_Delete(&ModuleBusyMutex,AllocationFlags_CanWaitForever);
145 
146  oC_MemMan_FreeAllMemoryOfAllocator(&ModuleAllocator);
147 
148  if((errorCode == oC_ErrorCode_ModuleNotStartedYet) || (errorCode == oC_ErrorCode_None))
149  {
150  errorCode = oC_ErrorCode_None;
151  }
152  }
153 
154  return errorCode;
155 }
156 
157 //==========================================================================================================================================
158 //==========================================================================================================================================
159 bool oC_TIMER_IsTurnedOn( void )
160 {
161  return ModuleEnabledFlag;
162 }
163 
164 //==========================================================================================================================================
165 //==========================================================================================================================================
166 oC_ErrorCode_t oC_TIMER_Configure( const oC_TIMER_Config_t * Config , oC_TIMER_Context_t * outContext )
167 {
168  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
169 
170  if(
171  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag , oC_ErrorCode_ModuleNotStartedYet ) &&
172  oC_AssignErrorCodeIfFalse(&errorCode , oC_MemMan_IsRamAddress(outContext) , oC_ErrorCode_OutputAddressNotInRAM ) &&
173  oC_AssignErrorCodeIfFalse(&errorCode , oC_MemMan_IsAddressCorrect(Config) , oC_ErrorCode_WrongConfigAddress) &&
174  oC_AssignErrorCodeIfFalse(&errorCode , IsModeCorrect(Config->Mode) , oC_ErrorCode_TIMERModeNotCorrect) &&
175  oC_AssignErrorCodeIfFalse(&errorCode , oC_Mutex_Take(ModuleBusyMutex,Config->MaximumTimeForWait) , oC_ErrorCode_ModuleIsBusy)
176  )
177  {
178  static const oC_TIMER_LLD_SubTimer_t subTimers[] = {
179  oC_TIMER_LLD_SubTimer_TimerA ,
180  oC_TIMER_LLD_SubTimer_TimerB ,
181  oC_TIMER_LLD_SubTimer_Both
182  };
183 
184  errorCode = oC_ErrorCode_NoChannelAvailable;
185 
186  oC_ARRAY_FOREACH_IN_ARRAY(subTimers,subTimer)
187  {
188  oC_TIMER_LLD_ForEachChannel(channel)
189  {
190  oC_IntMan_EnterCriticalSection();
191  if(
192  oC_ErrorOccur(errorCode) &&
193  oC_TIMER_LLD_IsChannelUsed(channel,*subTimer) == false &&
194  oC_AssignErrorCode(&errorCode , oC_TIMER_LLD_SetChannelUsed(channel,*subTimer)))
195  {
196  oC_IntMan_ExitCriticalSection();
197 
198  if(
199  oC_AssignErrorCode(&errorCode , oC_TIMER_LLD_SetPower(channel,oC_Power_On) ) &&
200  oC_AssignErrorCode(&errorCode , oC_TIMER_LLD_ChangeMode(channel,*subTimer,Config->Mode) ) &&
201  oC_AssignErrorCode(&errorCode , oC_TIMER_LLD_ChangeFrequency(channel,*subTimer,Config->Frequency,Config->PermissibleDifference) ) &&
202  oC_AssignErrorCode(&errorCode , oC_TIMER_LLD_ChangeCountDirection(channel,*subTimer,Config->CountDirection) ) &&
203  oC_AssignErrorCode(&errorCode , oC_TIMER_LLD_ChangeMaximumValue(channel,*subTimer,Config->MaximumValue) ) &&
204  oC_AssignErrorCode(&errorCode , oC_TIMER_LLD_ChangeMatchValue(channel,*subTimer,Config->MatchValue) ) &&
205  (Config->EventHandler == NULL ||
206  oC_AssignErrorCode(&errorCode , oC_TIMER_LLD_ChangeEventHandler(channel,*subTimer,Config->EventHandler,Config->EventFlags) )
207  ) &&
208  (PinMustBeConnected(Config) == false ||
209  oC_AssignErrorCode(&errorCode , ConnectPeripheralPin(channel,*subTimer,Config))
210  ) &&
211  (Config->Mode != oC_TIMER_Mode_PWM ||
212  oC_AssignErrorCode(&errorCode , oC_TIMER_LLD_ChangeStartPwmState(channel,*subTimer,Config->StartPwmState))
213  ) &&
214  ((Config->Mode != oC_TIMER_Mode_InputEdgeCount && Config->Mode != oC_TIMER_Mode_InputEdgeTime) ||
215  oC_AssignErrorCode(&errorCode , oC_TIMER_LLD_ChangeTrigger(channel,*subTimer,Config->InputTrigger))
216  )
217  )
218  {
219  struct Context_t * context = ksmartalloc(sizeof(struct Context_t) , &ModuleAllocator ,AllocationFlags_NoWait);
220 
221  if(context)
222  {
223  context->Channel = channel;
224  context->SubTimer = *subTimer;
225  context->ObjectControl = oC_CountObjectControl(context,oC_ObjectId_TimerContext);
226  errorCode = oC_ErrorCode_None;
227  *outContext = context;
228 
229  oC_ARRAY_FOREACH_BREAK(subTimers);
230  break;
231  }
232  else
233  {
234  errorCode = oC_ErrorCode_AllocationError;
235  }
236  }
237 
238  if(errorCode != oC_ErrorCode_None)
239  {
240  if(!oC_TIMER_LLD_RestoreDefaultStateOnChannel(channel,*subTimer))
241  {
242  errorCode = oC_ErrorCode_CannotRestoreDefaultState;
243  break;
244  }
245  }
246 
247  }
248  else
249  {
250  oC_IntMan_ExitCriticalSection();
251  }
252  }
253  }
254 
255  oC_Mutex_Give(ModuleBusyMutex);
256  }
257 
258  return errorCode;
259 }
260 
261 //==========================================================================================================================================
262 //==========================================================================================================================================
263 oC_ErrorCode_t oC_TIMER_Unconfigure( const oC_TIMER_Config_t * Config , oC_TIMER_Context_t * outContext )
264 {
265  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
266 
267  if(
268  oC_AssignErrorCodeIfFalse(&errorCode, ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet) &&
269  oC_AssignErrorCodeIfFalse(&errorCode, IsContextCorrect(*outContext) , oC_ErrorCode_ContextNotCorrect) &&
270  oC_AssignErrorCodeIfFalse(&errorCode, oC_MemMan_IsAddressCorrect(Config) , oC_ErrorCode_WrongConfigAddress)
271  )
272  {
273  oC_TIMER_Context_t context = *outContext;
274 
275  if(oC_TIMER_LLD_RestoreDefaultStateOnChannel(context->Channel,context->SubTimer))
276  {
277  if(ksmartfree(context,sizeof(struct Context_t),AllocationFlags_CanWaitForever))
278  {
279  *outContext = NULL;
280  errorCode = oC_ErrorCode_None;
281  }
282  else
283  {
284  errorCode = oC_ErrorCode_ReleaseError;
285  }
286  }
287  else
288  {
289  errorCode = oC_ErrorCode_CannotRestoreDefaultState;
290  }
291  }
292 
293  return errorCode;
294 }
295 
296 //==========================================================================================================================================
297 //==========================================================================================================================================
298 oC_ErrorCode_t oC_TIMER_ReadValue( oC_TIMER_Context_t Context , uint64_t * outValue )
299 {
300  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
301 
302  if(
303  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ) &&
304  oC_AssignErrorCodeIfFalse(&errorCode , IsContextCorrect(Context) , oC_ErrorCode_ContextNotCorrect ) &&
305  oC_AssignErrorCodeIfFalse(&errorCode , isram(outValue) , oC_ErrorCode_OutputAddressNotInRAM )
306  )
307  {
308  errorCode = oC_TIMER_LLD_ReadCurrentValue(Context->Channel,Context->SubTimer,outValue);
309  }
310 
311  return errorCode;
312 }
313 
314 //==========================================================================================================================================
315 //==========================================================================================================================================
316 oC_ErrorCode_t oC_TIMER_SetValue( oC_TIMER_Context_t Context , uint64_t Value )
317 {
318  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
319 
320  if(oC_AssignErrorCodeIfFalse(&errorCode , IsContextCorrect(Context) , oC_ErrorCode_ContextNotCorrect))
321  {
322  errorCode = oC_TIMER_LLD_ChangeCurrentValue(Context->Channel,Context->SubTimer,Value);
323  }
324 
325  return errorCode;
326 }
327 
328 //==========================================================================================================================================
329 //==========================================================================================================================================
330 oC_ErrorCode_t oC_TIMER_ReadMatchValue( oC_TIMER_Context_t Context , uint64_t * outValue )
331 {
332  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
333 
334  if(
335  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ) &&
336  oC_AssignErrorCodeIfFalse(&errorCode , IsContextCorrect(Context) , oC_ErrorCode_ContextNotCorrect ) &&
337  oC_AssignErrorCodeIfFalse(&errorCode , isram(outValue) , oC_ErrorCode_OutputAddressNotInRAM )
338  )
339  {
340  errorCode = oC_TIMER_LLD_ReadMatchValue(Context->Channel,Context->SubTimer,outValue);
341  }
342 
343  return errorCode;
344 }
345 
346 //==========================================================================================================================================
347 //==========================================================================================================================================
348 oC_ErrorCode_t oC_TIMER_SetMatchValue( oC_TIMER_Context_t Context , uint64_t Value )
349 {
350  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
351 
352  if(oC_AssignErrorCodeIfFalse(&errorCode , IsContextCorrect(Context) , oC_ErrorCode_ContextNotCorrect))
353  {
354  errorCode = oC_TIMER_LLD_ChangeMatchValue(Context->Channel,Context->SubTimer,Value);
355  }
356 
357  return errorCode;
358 }
359 
360 //==========================================================================================================================================
361 //==========================================================================================================================================
362 oC_ErrorCode_t oC_TIMER_ReadMaxValue( oC_TIMER_Context_t Context , uint64_t * outValue )
363 {
364  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
365 
366  if(
367  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ) &&
368  oC_AssignErrorCodeIfFalse(&errorCode , IsContextCorrect(Context) , oC_ErrorCode_ContextNotCorrect ) &&
369  oC_AssignErrorCodeIfFalse(&errorCode , isram(outValue) , oC_ErrorCode_OutputAddressNotInRAM )
370  )
371  {
372  errorCode = oC_TIMER_LLD_ReadMaximumValue(Context->Channel,Context->SubTimer,outValue);
373  }
374 
375  return errorCode;
376 }
377 
378 //==========================================================================================================================================
379 //==========================================================================================================================================
380 oC_ErrorCode_t oC_TIMER_SetMaxValue( oC_TIMER_Context_t Context , uint64_t Value )
381 {
382  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
383 
384  if(oC_AssignErrorCodeIfFalse(&errorCode , IsContextCorrect(Context) , oC_ErrorCode_ContextNotCorrect))
385  {
386  errorCode = oC_TIMER_LLD_ChangeMaximumValue(Context->Channel,Context->SubTimer,Value);
387  }
388 
389  return errorCode;
390 }
391 
392 //==========================================================================================================================================
393 //==========================================================================================================================================
394 oC_ErrorCode_t oC_TIMER_Start( oC_TIMER_Context_t Context )
395 {
396  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
397 
398  if(
399  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ) &&
400  oC_AssignErrorCodeIfFalse(&errorCode , IsContextCorrect(Context) , oC_ErrorCode_ContextNotCorrect )
401  )
402  {
403  errorCode = oC_TIMER_LLD_TimerStart(Context->Channel,Context->SubTimer);
404  }
405 
406  return errorCode;
407 }
408 
409 //==========================================================================================================================================
410 //==========================================================================================================================================
411 oC_ErrorCode_t oC_TIMER_Stop( oC_TIMER_Context_t Context )
412 {
413  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
414 
415  if(
416  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ) &&
417  oC_AssignErrorCodeIfFalse(&errorCode , IsContextCorrect(Context) , oC_ErrorCode_ContextNotCorrect )
418  )
419  {
420  errorCode = oC_TIMER_LLD_TimerStop(Context->Channel,Context->SubTimer);
421  }
422 
423  return errorCode;
424 }
425 
426 
427 #undef _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
428 
435 #define _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
436 
437 //==========================================================================================================================================
438 //==========================================================================================================================================
439 static void EventHandler( void * Address , MemoryEventFlags_t Event , const char * Function, uint32_t LineNumber )
440 {
441 
442 }
443 
444 //==========================================================================================================================================
445 //==========================================================================================================================================
446 static bool IsModeCorrect( oC_TIMER_Mode_t Mode )
447 {
448  return Mode <= oC_TIMER_Mode_PWM;
449 }
450 
451 //==========================================================================================================================================
452 //==========================================================================================================================================
453 static bool IsContextCorrect( oC_TIMER_Context_t Context )
454 {
455  return oC_MemMan_IsDynamicAllocatedAddress(Context) && oC_CheckObjectControl(Context,oC_ObjectId_TimerContext,Context->ObjectControl);
456 }
457 
458 //==========================================================================================================================================
459 //==========================================================================================================================================
460 static bool PinMustBeConnected( const oC_TIMER_Config_t * Config )
461 {
462  return Config->Mode == oC_TIMER_Mode_PWM || Config->Mode == oC_TIMER_Mode_InputEdgeCount || Config->Mode == oC_TIMER_Mode_InputEdgeTime;
463 }
464 
465 //==========================================================================================================================================
466 //==========================================================================================================================================
467 static oC_ErrorCode_t ConnectPeripheralPin( oC_TIMER_Channel_t Channel , oC_TIMER_LLD_SubTimer_t SubTimer , const oC_TIMER_Config_t * Config )
468 {
469  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
470  oC_TIMER_Pin_t pin = 0;
471  uint32_t size = 1;
472  bool pinUsed = false;
473 
474  oC_IntMan_EnterCriticalSection();
475  if(
476  oC_AssignErrorCode(&errorCode , oC_TIMER_LLD_ReadModulePinsOfPin(Config->Pin,&pin,&size)) &&
477  oC_AssignErrorCode(&errorCode , oC_GPIO_LLD_CheckIsPinUsed(Config->Pin,&pinUsed)) &&
478  oC_AssignErrorCodeIfFalse(&errorCode , pinUsed == false , oC_ErrorCode_PinIsUsed) &&
479  oC_AssignErrorCode(&errorCode , oC_GPIO_LLD_SetPinsUsed(Config->Pin)) &&
480  oC_AssignErrorCode(&errorCode , oC_TIMER_LLD_ConnectModulePin(pin))
481  )
482  {
483  errorCode = oC_ErrorCode_None;
484  }
485  oC_IntMan_ExitCriticalSection();
486 
487  return errorCode;
488 }
489 
490 
491 #undef _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
Something is powered on.
Definition: oc_stdtypes.h:252
static bool ModuleEnabledFlag
Definition: oc_memman.c:211
const char * Name
Definition: oc_stdlib.h:161
The file with interface for the timer driver.
bool oC_MemMan_IsRamAddress(const void *Address)
checks if address is in ram section
Definition: oc_memman.c:1542
identifier for allocations
Definition: oc_stdlib.h:159
bool oC_MemMan_FreeAllMemoryOfAllocator(Allocator_t Allocator)
release all memory of allocator
Definition: oc_memman.c:985
The file with LLD interface for the GPIO driver.
The file with helper macros for managing objects.
The file with interface for driver creating.
bool oC_MemMan_IsDynamicAllocatedAddress(const void *Address)
checks if address is in dynamic allocated section
Definition: oc_memman.c:1552
bool oC_MemMan_IsAddressCorrect(const void *Address)
checks if address is correct - in RAM or in FLASH
Definition: oc_memman.c:1577
uint32_t oC_ObjectControl_t
stores object control value
Definition: oc_object.h:141
The file with interface for interrupt manager.
static oC_ObjectControl_t oC_CountObjectControl(void *ObjectPointer, oC_ObjectId_t ObjectId)
counts object control for object
Definition: oc_object.h:168
static bool oC_CheckObjectControl(void *ObjectPointer, oC_ObjectId_t ObjectId, oC_ObjectControl_t ObjectControl)
checks if object control is correct
Definition: oc_object.h:203
The file with interface for mutex managing.
oC_ObjectControl_t ObjectControl
Definition: oc_eth.c:100
stores ETH context
Definition: oc_eth.c:97
Static array definitions.
The file with memory manager interface.
The file with interface for Thread Manager.
#define NULL
pointer to a zero
Definition: oc_null.h:37