Choco OS  V.0.16.9.0
Join to the chocolate world
oc_led.c
Go to the documentation of this file.
1 
27 #include <oc_led.h>
28 #include <oc_gpio.h>
29 #include <oc_pwm.h>
30 #include <oc_module.h>
31 #include <oc_stdlib.h>
32 #include <oc_string.h>
33 #include <oc_stdio.h>
34 
40 #define _________________________________________DRIVER_DEFINITIONS_SECTION_________________________________________________________________
41 
42 #define DRIVER_SOURCE
43 
44 /* Driver basic definitions */
45 #define DRIVER_NAME LED
46 #define DRIVER_FILE_NAME "led"
47 #define DRIVER_VERSION oC_Driver_MakeVersion(1,0,0)
48 #define REQUIRED_DRIVERS &GPIO,&PWM
49 #define REQUIRED_BOOT_LEVEL oC_Boot_Level_RequireClock | oC_Boot_Level_RequireMemoryManager | oC_Boot_Level_RequireDriversManager
50 
51 /* Driver interface definitions */
52 #define DRIVER_CONFIGURE oC_LED_Configure
53 #define DRIVER_UNCONFIGURE oC_LED_Unconfigure
54 #define WRITE_TO_DRIVER oC_LED_Write
55 #define HANDLE_IOCTL oC_LED_Ioctl
56 
57 #undef _________________________________________DRIVER_DEFINITIONS_SECTION_________________________________________________________________
58 
59 /* This header must be always at the end of include list */
60 #include <oc_driver.h>
61 
67 #define _________________________________________TYPES_SECTION______________________________________________________________________________
68 
69 struct Context_t
70 {
72  oC_LED_Config_t Config;
73  oC_PWM_Context_t PwmContexts[oC_LED_Index_NumberOfElements];
74 };
75 
76 #undef _________________________________________TYPES_SECTION______________________________________________________________________________
77 
83 #define _________________________________________VARIABLES_SECTION__________________________________________________________________________
84 
85 static oC_Allocator_t Allocator = {
86  .Name = "led"
87 };
88 
89 #undef _________________________________________VARIABLES_SECTION__________________________________________________________________________
90 
91 
97 #define _________________________________________LOCAL_PROTOTYPES_SECTION___________________________________________________________________
98 
99 static oC_ErrorCode_t ConfigureLeds ( oC_LED_Context_t Context );
100 static oC_ErrorCode_t UnconfigureLeds ( oC_LED_Context_t Context );
101 static bool IsContextContext ( oC_LED_Context_t Context );
102 static oC_ErrorCode_t SetLight ( oC_LED_Context_t Context , oC_LED_Index_t LedIndex , uint8_t Light );
103 
104 #undef _________________________________________LOCAL_PROTOTYPES_SECTION___________________________________________________________________
105 
106 
112 #define _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
113 
114 //==========================================================================================================================================
125 //==========================================================================================================================================
126 oC_ErrorCode_t oC_LED_Configure( const oC_LED_Config_t * Config , oC_LED_Context_t * outContext )
127 {
128  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
129 
130  if(
131  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(Config) , oC_ErrorCode_WrongConfigAddress) &&
132  oC_AssignErrorCodeIfFalse(&errorCode , isram(outContext) , oC_ErrorCode_OutputAddressNotInRAM) &&
133  oC_AssignErrorCodeIfFalse(&errorCode , Config->Mode & oC_LED_Mode_RGB , oC_ErrorCode_ModeNotCorrect )
134  )
135  {
136  oC_LED_Context_t context = ksmartalloc(sizeof(struct Context_t) , &Allocator , AllocationFlags_CanWait1Second);
137 
138  if(oC_AssignErrorCodeIfFalse(&errorCode , isram(context) , oC_ErrorCode_AllocationError ))
139  {
140  memcpy(&context->Config,Config,sizeof(oC_LED_Config_t));
141 
142  if(oC_AssignErrorCode(&errorCode , ConfigureLeds(context)))
143  {
144  context->ObjectControl = oC_CountObjectControl(context,oC_ObjectId_LedContext);
145  *outContext = context;
146  errorCode = oC_ErrorCode_None;
147 
148  }
149  else
150  {
151  if(ksmartfree(context,sizeof(struct Context_t),AllocationFlags_CanWaitForever)==false)
152  {
153  errorCode = oC_ErrorCode_ReleaseError;
154  }
155  }
156  }
157  }
158 
159  return errorCode;
160 }
161 
162 //==========================================================================================================================================
171 //==========================================================================================================================================
172 oC_ErrorCode_t oC_LED_Unconfigure( const oC_LED_Config_t * Config , oC_LED_Context_t * outContext )
173 {
174  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
175 
176  if(
177  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(Config) , oC_ErrorCode_WrongConfigAddress) &&
178  oC_AssignErrorCodeIfFalse(&errorCode , isram(outContext) , oC_ErrorCode_OutputAddressNotInRAM) &&
179  oC_AssignErrorCodeIfFalse(&errorCode , IsContextContext(*outContext) , oC_ErrorCode_ContextNotCorrect )
180  )
181  {
182  oC_LED_Context_t context = *outContext;
183  context->ObjectControl = 0;
184 
185  if(ksmartfree(*outContext,sizeof(struct Context_t),AllocationFlags_CanWaitForever))
186  {
187  if(oC_AssignErrorCode(&errorCode , UnconfigureLeds(context)))
188  {
189  *outContext = NULL;
190  errorCode = oC_ErrorCode_None;
191  }
192  }
193  else
194  {
195  errorCode = oC_ErrorCode_ReleaseError;
196  }
197  }
198 
199  return errorCode;
200 }
201 
202 //==========================================================================================================================================
203 //==========================================================================================================================================
204 oC_ErrorCode_t oC_LED_Write( oC_LED_Context_t Context , const char * Buffer , uint32_t * Size , oC_Time_t Timeout )
205 {
206  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
207 
208  if(
209  oC_AssignErrorCodeIfFalse(&errorCode , IsContextContext(Context) , oC_ErrorCode_ContextNotCorrect ) &&
210  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(Buffer) , oC_ErrorCode_WrongAddress ) &&
211  oC_AssignErrorCodeIfFalse(&errorCode , isram(Size) , oC_ErrorCode_OutputAddressNotInRAM) &&
212  oC_AssignErrorCodeIfFalse(&errorCode , (*Size) > 0 , oC_ErrorCode_SizeNotCorrect )
213  )
214  {
215  char * tempBuffer = ksmartalloc(*Size,&Allocator,AllocationFlags_CanWait1Second);
216 
217  if(oC_AssignErrorCodeIfFalse(&errorCode , isram(tempBuffer) , oC_ErrorCode_AllocationError))
218  {
219  unsigned int color = 0;
220 
221  errorCode = sscanf(Buffer,"%x",&color);
222 
223  oC_AssignErrorCodeIfFalse(&errorCode,ksmartfree(tempBuffer,*Size,AllocationFlags_CanWaitForever),oC_ErrorCode_ReleaseError);
224  oC_AssignErrorCode(&errorCode,oC_LED_SetColor(Context,(oC_Color_t)color));
225  }
226  }
227 
228  return errorCode;
229 }
230 
231 //==========================================================================================================================================
232 //==========================================================================================================================================
233 oC_ErrorCode_t oC_LED_Ioctl( oC_LED_Context_t Context , oC_Ioctl_Command_t Command , void * Data )
234 {
235  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
236 
237  if(
238  oC_AssignErrorCodeIfFalse(&errorCode , IsContextContext(Context) , oC_ErrorCode_ContextNotCorrect) &&
239  oC_AssignErrorCodeIfFalse(&errorCode , oC_Ioctl_IsCorrectCommand(Command) , oC_ErrorCode_CommandNotCorrect)
240  )
241  {
242  switch(Command)
243  {
244  //==============================================================================================================================
245  /*
246  * Not handled commands
247  */
248  //==============================================================================================================================
249  default:
250  errorCode = oC_ErrorCode_CommandNotHandled;
251  break;
252  }
253  }
254 
255  return errorCode;
256 }
257 
258 //==========================================================================================================================================
259 //==========================================================================================================================================
260 oC_ErrorCode_t oC_LED_SetColor( oC_LED_Context_t Context , oC_Color_t Color )
261 {
262  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
263 
264  if(oC_AssignErrorCodeIfFalse(&errorCode , IsContextContext(Context) , oC_ErrorCode_ContextNotCorrect))
265  {
266  oC_LED_Mode_t mode = Context->Config.Mode;
267 
268  errorCode = oC_ErrorCode_None;
269 
270  for(oC_LED_Index_t ledIndex = 0 ; ledIndex < oC_LED_Index_NumberOfElements && !oC_ErrorOccur(errorCode); ledIndex++)
271  {
272  if(oC_Bits_IsBitSetU32(mode,ledIndex))
273  {
274  errorCode = SetLight(Context , ledIndex , (uint8_t)((Color & 0xff0000) >> 16 ) );
275  }
276  Color = Color << 8;
277  }
278  }
279 
280  return errorCode;
281 }
282 
283 //==========================================================================================================================================
284 //==========================================================================================================================================
285 oC_ErrorCode_t oC_LED_SetLight( oC_LED_Context_t Context , oC_LED_Index_t LedIndex , uint8_t Light )
286 {
287  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
288 
289  if(
290  oC_AssignErrorCodeIfFalse(&errorCode , IsContextContext(Context) , oC_ErrorCode_ContextNotCorrect) &&
291  oC_AssignErrorCodeIfFalse(&errorCode , LedIndex < oC_LED_Index_NumberOfElements , oC_ErrorCode_IndexNotCorrect)
292  )
293  {
294  errorCode = SetLight(Context,LedIndex,Light);
295  }
296 
297  return errorCode;
298 }
299 
300 #undef _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
301 
307 #define _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
308 
309 //==========================================================================================================================================
310 //==========================================================================================================================================
311 static oC_ErrorCode_t ConfigureLeds( oC_LED_Context_t Context )
312 {
313  oC_ErrorCode_t errorCode = oC_ErrorCode_None;
314  oC_LED_Mode_t mode = Context->Config.Mode;
315  bool usePwm = oC_Bits_AreBitsSetU32(mode,oC_LED_Mode_UsePWM);
316 
317  for(oC_LED_Index_t ledIndex = 0 ; ledIndex < oC_LED_Index_NumberOfElements && !oC_ErrorOccur(errorCode) ; ledIndex++ )
318  {
319  oC_Pins_t pin = Context->Config.Pins[ledIndex];
320  bool lowActive = oC_Bits_AreBitsSetU32(mode,oC_LED_Mode_RedActiveLow<<ledIndex);
321 
322  if(oC_Bits_IsBitSetU32(mode,ledIndex))
323  {
324  if(usePwm)
325  {
326  oC_PWM_Config_t pwmConfig = {
327  .Pin = pin ,
328  .ActiveState = (lowActive) ? oC_PWM_ActiveState_Low : oC_PWM_ActiveState_High ,
329  .MaximumValue = 255 ,
330  .TickFrequency = oC_kHz(26) ,
331  .PermissibleDiffernece = oC_kHz(5)
332  };
333  errorCode = oC_PWM_Configure(&pwmConfig,&Context->PwmContexts[ledIndex]);
334  }
335  else
336  {
337  errorCode = oC_GPIO_QuickOutput(pin);
338  }
339  }
340  }
341 
342  return errorCode;
343 }
344 
345 //==========================================================================================================================================
346 //==========================================================================================================================================
347 static oC_ErrorCode_t UnconfigureLeds( oC_LED_Context_t Context )
348 {
349  oC_ErrorCode_t errorCode = oC_ErrorCode_None;
350  oC_LED_Mode_t mode = Context->Config.Mode;
351  bool usePwm = oC_Bits_AreBitsSetU32(mode,oC_LED_Mode_UsePWM);
352 
353  for(oC_LED_Index_t ledIndex = 0 ; ledIndex < oC_LED_Index_NumberOfElements && !oC_ErrorOccur(errorCode) ; ledIndex++ )
354  {
355  oC_Pins_t pin = Context->Config.Pins[ledIndex];
356  bool lowActive = oC_Bits_AreBitsSetU32(mode,oC_LED_Mode_RedActiveLow<<ledIndex);
357 
358  if(oC_Bits_IsBitSetU32(mode,ledIndex))
359  {
360  if(usePwm)
361  {
362  oC_PWM_Config_t pwmConfig = {
363  .Pin = pin ,
364  .ActiveState = (lowActive) ? oC_PWM_ActiveState_Low : oC_PWM_ActiveState_High ,
365  .MaximumValue = 255 ,
366  .TickFrequency = oC_kHz(26) ,
367  .PermissibleDiffernece = oC_kHz(5)
368  };
369  errorCode = oC_PWM_Unconfigure(&pwmConfig,&Context->PwmContexts[ledIndex]);
370  }
371  else
372  {
373  errorCode = oC_GPIO_QuickUnconfigure(pin);
374  }
375  }
376  }
377 
378  return errorCode;
379 }
380 
381 //==========================================================================================================================================
382 //==========================================================================================================================================
383 static bool IsContextContext ( oC_LED_Context_t Context )
384 {
385  return isram(Context) && oC_CheckObjectControl(Context,oC_ObjectId_LedContext,Context->ObjectControl);
386 }
387 
388 //==========================================================================================================================================
389 //==========================================================================================================================================
390 static oC_ErrorCode_t SetLight( oC_LED_Context_t Context , oC_LED_Index_t LedIndex , uint8_t Light )
391 {
392  oC_ErrorCode_t errorCode = oC_ErrorCode_None;
393  oC_LED_Mode_t mode = Context->Config.Mode;
394  bool usePwm = oC_Bits_AreBitsSetU32(mode,oC_LED_Mode_UsePWM);
395  oC_Pins_t pin = Context->Config.Pins[LedIndex];
396 
397  if(usePwm)
398  {
399  errorCode = oC_PWM_SetValue(Context->PwmContexts[LedIndex],Light);
400  }
401  else
402  {
403  if(Light == 0)
404  {
405  errorCode = oC_GPIO_WriteData(pin,0);
406  }
407  else
408  {
409  errorCode = oC_GPIO_WriteData(pin,oC_GPIO_LLD_PinsState_AllHigh);
410  }
411  }
412 
413  return errorCode;
414 }
415 
416 #undef _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
static bool oC_Bits_AreBitsSetU32(uint32_t BitMask, uint32_t BitsToCheck)
checks if all bits in field are set
Definition: oc_bits.h:884
const char * Name
Definition: oc_stdlib.h:161
The file with interface for the GPIO driver.
identifier for allocations
Definition: oc_stdlib.h:159
The file with interface for the PWM driver.
oC_ErrorCode_t oC_GPIO_WriteData(oC_Pins_t Pins, oC_PinsMask_t Data)
write data in port
PWM driver configuration structure.
Definition: oc_pwm.h:61
The file with interface for driver creating.
The file with interface for the module library.
uint32_t oC_ObjectControl_t
stores object control value
Definition: oc_object.h:141
oC_ErrorCode_t oC_LED_Unconfigure(const oC_LED_Config_t *Config, oC_LED_Context_t *outContext)
Restores default state on pins.
Definition: oc_led.c:172
LED driver configuration structure.
Definition: oc_led.h:81
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_ErrorCode_t oC_LED_Configure(const oC_LED_Config_t *Config, oC_LED_Context_t *outContext)
configures LED pins to work
Definition: oc_led.c:126
oC_ObjectControl_t ObjectControl
Definition: oc_eth.c:100
stores ETH context
Definition: oc_eth.c:97
The file with interface for the LED driver.
static bool oC_Bits_IsBitSetU32(uint32_t BitMask, uint8_t BitIndex)
checks if bit is set
Definition: oc_bits.h:679
The file with interface for string library.
The file with standard input/output operations.
#define NULL
pointer to a zero
Definition: oc_null.h:37