Choco OS  V.0.16.9.0
Join to the chocolate world
oc_pwm.c
Go to the documentation of this file.
1 
27 #include <oc_pwm.h>
28 #include <oc_timer.h>
29 #include <oc_object.h>
30 #include <oc_stdlib.h>
31 
37 #define _________________________________________DRIVER_DEFINITIONS_SECTION_________________________________________________________________
38 
39 #define DRIVER_SOURCE
40 
41 /* Driver basic definitions */
42 #define DRIVER_NAME PWM
43 #define DRIVER_FILE_NAME "pwm"
44 #define DRIVER_VERSION oC_Driver_MakeVersion(1,0,0)
45 #define REQUIRED_DRIVERS &TIMER,&GPIO
46 #define REQUIRED_BOOT_LEVEL oC_Boot_Level_RequireClock | oC_Boot_Level_RequireMemoryManager | oC_Boot_Level_RequireDriversManager
47 
48 /* Driver interface definitions */
49 #define DRIVER_CONFIGURE oC_PWM_Configure
50 #define DRIVER_UNCONFIGURE oC_PWM_Unconfigure
51 
52 #undef _________________________________________DRIVER_DEFINITIONS_SECTION_________________________________________________________________
53 
54 /* This header must be always at the end of include list */
55 #include <oc_driver.h>
56 
62 #define _________________________________________TYPES_SECTION______________________________________________________________________________
63 
64 struct Context_t
65 {
67  oC_TIMER_Context_t TimerContext;
68  uint64_t MaximumValue;
69 };
70 
71 #undef _________________________________________TYPES_SECTION______________________________________________________________________________
72 
78 #define _________________________________________LOCAL_PROTOTYPES_SECTION___________________________________________________________________
79 
80 static bool IsContextCorrect( oC_PWM_Context_t Context );
81 
82 #undef _________________________________________LOCAL_PROTOTYPES_SECTION___________________________________________________________________
83 
84 
90 #define _________________________________________VARIABLES_SECTION__________________________________________________________________________
91 
92 static const oC_Allocator_t Allocator = {
93  .Name = "pwm"
94 };
95 
96 #undef _________________________________________VARIABLES_SECTION__________________________________________________________________________
97 
98 
104 #define _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
105 
106 //==========================================================================================================================================
107 //==========================================================================================================================================
108 oC_ErrorCode_t oC_PWM_Configure( const oC_PWM_Config_t * Config , oC_PWM_Context_t * outContext )
109 {
110  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
111 
112  if(
113  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(Config) , oC_ErrorCode_WrongConfigAddress ) &&
114  oC_AssignErrorCodeIfFalse(&errorCode , isram(outContext) , oC_ErrorCode_OutputAddressNotInRAM ) &&
115  oC_AssignErrorCodeIfFalse(&errorCode , Config->MaximumValue > 0 , oC_ErrorCode_MaximumValueNotCorrect )
116  )
117  {
118  oC_PWM_Context_t context = ksmartalloc(sizeof(struct Context_t) , &Allocator , AllocationFlags_CanWait1Second);
119 
120  if(oC_AssignErrorCodeIfFalse(&errorCode , isram(context) , oC_ErrorCode_AllocationError))
121  {
122  oC_TIMER_Config_t config = {
123  .Mode = oC_TIMER_Mode_PWM ,
124  .MaximumTimeForWait = s(1) ,
125  .Frequency = Config->TickFrequency,
126  .PermissibleDifference = Config->PermissibleDiffernece ,
127  .MaximumValue = Config->MaximumValue ,
128  .MatchValue = 0 ,
129  .EventFlags = 0 ,
130  .EventHandler = NULL ,
131  .Pin = Config->Pin ,
132  .CountDirection = oC_TIMER_CountDirection_DoesntMatter
133  };
134 
135  if(
136  oC_AssignErrorCode(&errorCode , oC_TIMER_Configure(&config,&context->TimerContext)) &&
137  oC_AssignErrorCode(&errorCode , oC_TIMER_Start(context->TimerContext))
138  )
139  {
140  context->ObjectControl = oC_CountObjectControl(context,oC_ObjectId_PwmContext);
141  context->MaximumValue = Config->MaximumValue;
142  *outContext = context;
143  errorCode = oC_ErrorCode_None;
144  }
145  else if(ksmartfree(context,sizeof(struct Context_t),AllocationFlags_CanWaitForever)==false)
146  {
147  errorCode = oC_ErrorCode_ReleaseError;
148  }
149  }
150  }
151 
152  return errorCode;
153 }
154 
155 //==========================================================================================================================================
156 //==========================================================================================================================================
157 oC_ErrorCode_t oC_PWM_Unconfigure( const oC_PWM_Config_t * Config , oC_PWM_Context_t * outContext )
158 {
159  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
160 
161  if(
162  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(Config) , oC_ErrorCode_WrongConfigAddress ) &&
163  oC_AssignErrorCodeIfFalse(&errorCode , isram(outContext) , oC_ErrorCode_OutputAddressNotInRAM ) &&
164  oC_AssignErrorCodeIfFalse(&errorCode , IsContextCorrect(*outContext) , oC_ErrorCode_ContextNotCorrect )
165  )
166  {
167  oC_PWM_Context_t context = *outContext;
168  oC_TIMER_Config_t config = {
169  .Mode = oC_TIMER_Mode_PWM ,
170  .MaximumTimeForWait = s(1) ,
171  .Frequency = Config->TickFrequency,
172  .PermissibleDifference = Config->PermissibleDiffernece ,
173  .MaximumValue = Config->MaximumValue ,
174  .MatchValue = 0 ,
175  .EventFlags = 0 ,
176  .EventHandler = NULL ,
177  .Pin = Config->Pin ,
178  .CountDirection = oC_TIMER_CountDirection_DoesntMatter
179  };
180 
181  context->ObjectControl = 0;
182 
183  if(oC_AssignErrorCode(&errorCode , oC_TIMER_Unconfigure(&config,&context->TimerContext)))
184  {
185  context->ObjectControl = oC_CountObjectControl(context,oC_ObjectId_PwmContext);
186  *outContext = context;
187  errorCode = oC_ErrorCode_None;
188  }
189 
190  if(ksmartfree(context,sizeof(struct Context_t),AllocationFlags_CanWaitForever)==false)
191  {
192  errorCode = oC_ErrorCode_ReleaseError;
193  }
194  }
195 
196  return errorCode;
197 }
198 
199 //==========================================================================================================================================
200 //==========================================================================================================================================
201 oC_ErrorCode_t oC_PWM_SetDuty( oC_PWM_Context_t Context , float PercentDuty )
202 {
203  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
204 
205  if(
206  oC_AssignErrorCodeIfFalse(&errorCode , IsContextCorrect(Context) , oC_ErrorCode_ContextNotCorrect ) &&
207  oC_AssignErrorCodeIfFalse(&errorCode , PercentDuty <= 100 , oC_ErrorCode_ValueTooBig )
208  )
209  {
210  errorCode = oC_TIMER_SetMatchValue(Context,(uint64_t)((PercentDuty/100)*(float)Context->MaximumValue));
211  }
212 
213  return errorCode;
214 }
215 
216 //==========================================================================================================================================
217 //==========================================================================================================================================
218 oC_ErrorCode_t oC_PWM_ReadDuty( oC_PWM_Context_t Context , float * outPercentDuty )
219 {
220  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
221 
222  if(
223  oC_AssignErrorCodeIfFalse(&errorCode , IsContextCorrect(Context) , oC_ErrorCode_ContextNotCorrect ) &&
224  oC_AssignErrorCodeIfFalse(&errorCode , isram(outPercentDuty) , oC_ErrorCode_OutputAddressNotInRAM ) &&
225  oC_AssignErrorCodeIfFalse(&errorCode , Context->MaximumValue > 0 , oC_ErrorCode_MaximumValueNotCorrect )
226  )
227  {
228  uint64_t value = 0;
229  if(oC_AssignErrorCode(&errorCode , oC_TIMER_ReadMatchValue(Context,&value)))
230  {
231  *outPercentDuty = (((float)value)/((float)Context->MaximumValue))*100;
232  errorCode = oC_ErrorCode_None;
233  }
234 
235  }
236 
237  return errorCode;
238 }
239 
240 //==========================================================================================================================================
241 //==========================================================================================================================================
242 oC_ErrorCode_t oC_PWM_SetValue( oC_PWM_Context_t Context , uint64_t Value )
243 {
244  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
245 
246  if(oC_AssignErrorCodeIfFalse(&errorCode , IsContextCorrect(Context) , oC_ErrorCode_ContextNotCorrect ))
247  {
248  errorCode = oC_TIMER_SetMatchValue(Context,Value);
249  }
250 
251  return errorCode;
252 }
253 
254 //==========================================================================================================================================
255 //==========================================================================================================================================
256 oC_ErrorCode_t oC_PWM_ReadValue( oC_PWM_Context_t Context , uint64_t * outValue )
257 {
258  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
259 
260  if(
261  oC_AssignErrorCodeIfFalse(&errorCode , IsContextCorrect(Context) , oC_ErrorCode_ContextNotCorrect ) &&
262  oC_AssignErrorCodeIfFalse(&errorCode , isram(outValue) , oC_ErrorCode_OutputAddressNotInRAM )
263  )
264  {
265  if(oC_AssignErrorCode(&errorCode , oC_TIMER_ReadMatchValue(Context,outValue)))
266  {
267  errorCode = oC_ErrorCode_None;
268  }
269  }
270 
271  return errorCode;
272 }
273 
274 #undef _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
275 
281 #define _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
282 
283 //==========================================================================================================================================
284 //==========================================================================================================================================
285 static bool IsContextCorrect( oC_PWM_Context_t Context )
286 {
287  return isram(Context) && oC_CheckObjectControl(Context,oC_ObjectId_PwmContext,Context->ObjectControl);
288 }
289 
290 #undef _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
#define s(time)
Number of s.
Definition: oc_cfg.h:133
const char * Name
Definition: oc_stdlib.h:161
The file with interface for the timer driver.
identifier for allocations
Definition: oc_stdlib.h:159
The file with interface for the PWM driver.
PWM driver configuration structure.
Definition: oc_pwm.h:61
The file with helper macros for managing objects.
The file with interface for driver creating.
uint32_t oC_ObjectControl_t
stores object control value
Definition: oc_object.h:141
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
oC_ObjectControl_t ObjectControl
Definition: oc_eth.c:100
stores ETH context
Definition: oc_eth.c:97
#define NULL
pointer to a zero
Definition: oc_null.h:37