| Digital Power Starter Kit 3 Firmware dsPIC33C Boost Converter Voltage Mode Control Example |

p33c_pwm.c
1 /* Microchip Technology Inc. and its subsidiaries. You may use this software
2 * and any derivatives exclusively with Microchip products.
3 *
4 * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
5 * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
6 * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
7 * PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION
8 * WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.
9 *
10 * IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
11 * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
12 * WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
13 * BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
14 * FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS
15 * IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF
16 * ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
17 *
18 * MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE
19 * TERMS.
20 */
21
22 // Include standard header files
23 #include <xc.h> // include processor files - each processor file is guarded.
24 #include <stdint.h> // include standard integer data types
25 #include <stdbool.h> // include standard boolean data types
26 #include <stddef.h> // include standard definition data types
27
28 #include "p33c_pwm.h"
29
30 // Private arrays of register set start addresses
31 #if defined (PG8CONL)
32 volatile uint16_t* p33c_PwmGenerator_Handles[]={
33 &PG1CONL, &PG2CONL, &PG3CONL, &PG4CONL,
34 &PG5CONL, &PG6CONL, &PG7CONL, &PG8CONL
35 };
36 #elif defined (PG4CONL)
37 volatile uint16_t* p33c_PwmGenerator_Handles[]={
38 &PG1CONL, &PG2CONL, &PG3CONL, &PG4CONL
39 };
40 #else
41 #pragma message "selected device has no supported PWM generators"
42 #endif
43
44 /*********************************************************************************
45 * @fn uint16_t p33c_PwmModule_Initialize(void)
46 * @ingroup lib-layer-pral-functions-public-pwm
47 * @brief Initializes the PWM base module by resetting all its registers to default
48 * @return 0 = failure, disposing PWM generator was not successful
49 * @return 1 = success, disposing PWM generator was successful
50 *
51 * @details
52 * This function initializes the PWM module base registers with default
53 * values for maximum performance.
54 *
55 * Default configuration:
56 * - auxiliary clock is selected as main input clock source
57 * - all output logic functions are disabled
58 * - all output logic events are disabled
59 * - all master timing registers are cleared
60 * - all PWM register locks are removed, allowing unrestricted SFR writes
61 *
62 *********************************************************************************/
63
64 volatile uint16_t p33c_PwmModule_Initialize(void)
65 {
66 volatile uint16_t retval=1;
67
68 retval = p33c_PwmModule_ConfigWrite(pwmConfigDefault);
69
70 return(retval);
71 }
72
73 /*********************************************************************************
74 * @fn uint16_t p33c_PwmModule_Dispose(void)
75 * @ingroup lib-layer-pral-functions-public-pwm
76 * @brief Resets all PWM base module registers to their RESET default values
77 * @return 0 = failure, disposing PWM generator was not successful
78 * @return 1 = success, disposing PWM generator was successful
79 *
80 * @details
81 * This function clears all PWM module base registers to their
82 * default values set when the device comes out of RESET.
83 *
84 * Default configuration:
85 * - no main input clock source and scalers are selected
86 * - all output logic functions are disabled
87 * - all output logic events are disabled
88 * - all master timing registers are cleared
89 * - all PWM register locks are removed, allowing unrestricted SFR writes
90 *
91 *********************************************************************************/
92
93 volatile uint16_t p33c_PwmModule_Dispose(void)
94 {
95 volatile uint16_t retval=1;
96
97 retval = p33c_PwmModule_ConfigWrite(pwmConfigClear);
98
99 return(retval);
100 }
101
102 /*********************************************************************************
103 * @fn struct P33C_PWM_MODULE_s p33c_PwmModule_ConfigRead(void)
104 * @ingroup lib-layer-pral-functions-public-pwm
105 * @brief Read the current configuration from the PWM base module registers
106 * @return struct P33C_PWM_MODULE_s
107 *
108 * @details
109 * This function reads all registers with their current configuration into
110 * a data structure of type P33C_PWM_MODULE_s. Users can read and
111 * verify of modify the configuration to write it back to the PWM module
112 * base registers.
113 *
114 *********************************************************************************/
115
116 volatile struct P33C_PWM_MODULE_s p33c_PwmModule_ConfigRead(void)
117 {
118 volatile struct P33C_PWM_MODULE_s* pwm;
119
120 // Set pointer to memory address of desired PWM instance
121 pwm = p33c_PwmModule_GetHandle();
122
123 return(*pwm);
124
125 }
126
127 /*********************************************************************************
128 * @fn uint16_t p33c_PwmModule_ConfigWrite(volatile struct P33C_PWM_MODULE_s pwmConfig)
129 * @ingroup lib-layer-pral-functions-public-pwm
130 * @brief Writes a user-defined configuration to the PWM base module registers
131 * @param pwmConfig PWM module register set of type struct P33C_PWM_MODULE_s
132 * @return 0 = failure, disposing PWM generator was not successful
133 * @return 1 = success, disposing PWM generator was successful
134 *
135 * @details
136 * This function writes a user-defined PWM module configuration of type
137 * P33C_PWM_MODULE_s to the PWM module base registers. The
138 * individual register configurations have to be set in user-code
139 * before calling this function. To simplify the configuration process
140 * of standard functions, this driver provides templates, which can be
141 * loaded and written directly (see function p33c_PwmInitialize(void)
142 * for details)
143 *
144 *********************************************************************************/
145
146 volatile uint16_t p33c_PwmModule_ConfigWrite(volatile struct P33C_PWM_MODULE_s pwmConfig)
147 {
148 volatile uint16_t retval=1;
149 volatile struct P33C_PWM_MODULE_s* pwm;
150
151 // Set pointer to memory address of desired PWM instance
152 pwm = p33c_PwmModule_GetHandle();
153 *pwm = pwmConfig;
154
155 return(retval);
156
157 }
158
159 /*********************************************************************************
160 * @fn struct P33C_PWM_GENERATOR_s p33c_PwmGenerator_ConfigRead(volatile uint16_t pgInstance)
161 * @ingroup lib-layer-pral-functions-public-pwm
162 * @brief Disposes a given PWM generator by resetting all its registers to default
163 * @param pgInstance Instance of the PWM generator (e.g. 1 = PG1, 2=PG2, etc.) of type unsigned integer
164 * @return Generic PWM generator Special Function Register set of type struct P33C_PWM_GENERATOR_s
165 *
166 * @details
167 * This function copies the contents of all PWM generator registers of the
168 * specified generator instance (e.g. PG2) to a user variable of type
169 * P33C_PWM_GENERATOR_t. This 'virtual' PWM configuration can then , for
170 * example, be analyzed and/or modified in user code and applied to another
171 * PWM generator using the function p33c_PwmGenerator_ConfigWrite(...).
172 *
173 *********************************************************************************/
174
175 volatile struct P33C_PWM_GENERATOR_s p33c_PwmGenerator_ConfigRead(volatile uint16_t pgInstance)
176 {
177 volatile struct P33C_PWM_GENERATOR_s* pg;
178
179 // Set pointer to memory address of desired PWM instance
180 pg = p33c_PwmGenerator_GetHandle(pgInstance);
181
182 return(*pg);
183
184 }
185
186 /*********************************************************************************
187 * @fn uint16_t p33c_PwmGenerator_ConfigWrite(
188 volatile uint16_t pgInstance,
189 volatile struct P33C_PWM_GENERATOR_s pgConfig)
190 * @ingroup lib-layer-pral-functions-public-pwm
191 * @brief Disposes a given PWM generator by resetting all its registers to default
192 * @param pgInstance Instance of the PWM generator of type unsigned integer (e.g. 1=PG1, 2=PG2, etc.)
193 * @param pgConfig Generic PWM generator Special Function Register set of type struct P33C_PWM_GENERATOR_s
194 * @return 0 = failure, disposing PWM generator was not successful
195 * @return 1 = success, disposing PWM generator was successful
196 *
197 * @details
198 * This function writes a user-defined PWM generator configuration of type
199 * P33C_PWM_GENERATOR_t to the given PWM generator peripheral instance (e.g. PG2).
200 *
201 *********************************************************************************/
202
203 volatile uint16_t p33c_PwmGenerator_ConfigWrite(
204 volatile uint16_t pgInstance,
205 volatile struct P33C_PWM_GENERATOR_s pgConfig
206 )
207 {
208 volatile uint16_t retval=1;
209 volatile struct P33C_PWM_GENERATOR_s* pg;
210
211 // Set pointer to memory address of desired PWM instance
212 pg = p33c_PwmGenerator_GetHandle(pgInstance);
213 if (pg == NULL) return(0); // return error
214
215 *pg = pgConfig;
216
217 return(retval);
218
219 }
220
221 /*********************************************************************************
222 * @fn uint16_t p33c_PwmGenerator_Initialize(volatile uint16_t pgInstance)
223 * @ingroup lib-layer-pral-functions-public-pwm
224 * @brief Initializes a given PWM generator by resetting all its registers to default
225 * @param pgInstance Instance of the PWM generator of type unsigned integer (e.g. 1=PG1, 2=PG2, etc.)
226 * @return 0 = failure, disposing PWM generator was not successful
227 * @return 1 = success, disposing PWM generator was successful
228 *
229 * @details
230 * This function initializes the specified PWM Generator with default
231 * input clock settings and high resolution mode enabled. All other
232 * Special Function Registers (SFR) are reset to their RESET default
233 * values.
234 *
235 *********************************************************************************/
236
237 volatile uint16_t p33c_PwmGenerator_Initialize(volatile uint16_t pgInstance)
238 {
239 volatile uint16_t retval=1;
240 volatile struct P33C_PWM_GENERATOR_s* pg;
241
242
243 // Set pointer to memory address of desired PWM instance
244 pg = p33c_PwmGenerator_GetHandle(pgInstance);
245 if (pg == NULL) return(0); // return error
246
247 // Disable the PWM generator
248 retval &= p33c_PwmGenerator_Disable(pg);
249
250
251 // Reset all SFRs to default
252 retval &= p33c_PwmGenerator_ConfigWrite(pgInstance, pgConfigClear);
253
254 /* PWM GENERATOR CONTROL REGISTER LOW */
255 pg->PGxCONL.bits.ON = 0; // Disable PWM generator
256 pg->PGxCONL.bits.CLKSEL = 0b01; // Clock Selection: Selected by PWM module register PCLKCON.MCLKSEL bits
257 pg->PGxCONL.bits.MODSEL = 0b000; // Mode Selection: Independent Edge PWM mode
258 pg->PGxCONL.bits.TRGCNT = 0b000; // Trigger Count Selection: PWM Generator produces 1 PWM cycle after triggered
259 pg->PGxCONL.bits.HREN = 1; // PWM Generator 1 High-Resolution Enable bit: PWM Generator 1 operates in High-Resolution mode
260
261 return(retval);
262 }
263
264
265 /*********************************************************************************
266 * @fn uint16_t p33c_PwmGenerator_Dispose(volatile uint16_t pgInstance)
267 * @ingroup lib-layer-pral-functions-public-pwm
268 * @brief Disposes a given PWM generator by resetting all its registers to default
269 * @param pgInstance Instance of the PWM generator of type unsigned integer (e.g. 1=PG1, 2=PG2, etc.)
270 * @return 0 = failure, disposing PWM generator was not successful
271 * @return 1 = success, disposing PWM generator was successful
272 *
273 * @details
274 * This function disables the specified PWM Generator and clears all
275 * its Special Function Registers (SFR) to their RESET default values.
276 *
277 * ********************************************************************************/
278
279 volatile uint16_t p33c_PwmGenerator_Dispose(volatile uint16_t pgInstance)
280 {
281 volatile uint16_t retval=1;
282
283 // Clear all registers of pgInstance
284 p33c_PwmGenerator_ConfigWrite(pgInstance, pgConfigClear);
285
286 return(retval);
287 }
288
289 /*********************************************************************************
290 * @fn uint16_t p33c_PwmGenerator_Enable(volatile struct P33C_PWM_GENERATOR_s* pg)
291 * @ingroup lib-layer-pral-functions-public-pwm
292 * @brief Enables a given PWM generator with output pins disabled
293 * @param pg Pointer to PWM generator peripheral instance register set of type struct P33C_PWM_GENERATOR_s
294 * @return 0 = failure, enabling PWM generator was not successful
295 * @return 1 = success, enabling PWM generator was successful
296 *
297 * @details
298 * This function enables the PWM Generator and adds delay before enabling
299 * PWM output pins. After having successfully enabled the generator,
300 * users need to call function PWM_Generator_Resume to allow the PWM
301 * generator
302 *
303 *********************************************************************************/
304
305 volatile uint16_t p33c_PwmGenerator_Enable(volatile struct P33C_PWM_GENERATOR_s* pg)
306 {
307 volatile uint16_t retval=1;
308 volatile uint16_t timeout=0;
309
310 if(pg == NULL) return(0); // NULL pointer protection
311
312 // Set PWM generator override bits to prevent signals being generated outside the device
313 pg->PGxIOCONL.bits.OVRENH = 1;
314 pg->PGxIOCONL.bits.OVRENL = 1;
315
316 // Assign GPIO ownership to I/O module control
317 pg->PGxIOCONH.bits.PENH = 0;
318 pg->PGxIOCONH.bits.PENL = 0;
319
320 // Turn on the PWM generator
321 pg->PGxCONL.bits.ON = 1;
322
323 // enforce update of timing registers
324 pg->PGxSTAT.bits.UPDREQ = 1;
325
326 // If high resolution mode is enabled, check if clock has locked in without errors
327 if(pg->PGxCONL.bits.HREN)
328 {
329 while((!PCLKCONbits.HRRDY) && (timeout++<5000));
330 if ((timeout >= 5000) || (PCLKCONbits.HRERR)) // if there is an error
331 return(0); // return ERROR
332
333 }
334
335 // Assign GPIO ownership to given PWM generator
336 pg->PGxIOCONH.bits.PENH = 1;
337 pg->PGxIOCONH.bits.PENL = 1;
338
339 return(retval);
340
341 }
342
343 /*********************************************************************************
344 * @fn uint16_t p33c_PwmGenerator_Disable(volatile struct P33C_PWM_GENERATOR_s* pg)
345 * @ingroup lib-layer-pral-functions-public-pwm
346 * @brief Disables a given PWM generator
347 * @param pg Pointer to PWM generator peripheral instance register set of type struct P33C_PWM_GENERATOR_s
348 * @return 0 = failure, disabling PWM generator was not successful
349 * @return 1 = success, disabling PWM generator was successful
350 *
351 * @details
352 * This function disables the PWM Generator and locks its
353 * PWM output pins in a safe state.
354 *
355 *********************************************************************************/
356
357 volatile uint16_t p33c_PwmGenerator_Disable(volatile struct P33C_PWM_GENERATOR_s* pg)
358 {
359 volatile uint16_t retval=1;
360
361 if(pg == NULL) return(0); // NULL pointer protection
362
363 // Set PWM generator override bits to prevent signals being generated outside the device
364 pg->PGxIOCONL.bits.OVRENH = 1;
365 pg->PGxIOCONL.bits.OVRENL = 1;
366
367 // Assign GPIO ownership to I/O module control
368 pg->PGxIOCONH.bits.PENH = 0;
369 pg->PGxIOCONH.bits.PENL = 0;
370
371 // Turn on the PWM generator
372 pg->PGxCONL.bits.ON = 0;
373
374 return(retval);
375
376 }
377
378 /*********************************************************************************
379 * @fn uint16_t p33c_PwmGenerator_Resume(volatile struct P33C_PWM_GENERATOR_s* pg)
380 * @ingroup lib-layer-pral-functions-public-pwm
381 * @brief Disables a PWM generator IOs
382 * @param pg Pointer to PWM generator peripheral instance register set of type struct P33C_PWM_GENERATOR_s
383 * @return 0 = failure, enabling PWM generator IOs was not successful
384 * @return 1 = success, enabling PWM generator IOs was successful
385 *
386 * @details
387 * This function enables the PWM Generator IO instance allowing
388 * signals to be routed to the output pins. This on/off transition
389 * occurs synchronously to the PWM period.
390 *
391 *********************************************************************************/
392
393 volatile uint16_t p33c_PwmGenerator_Resume(volatile struct P33C_PWM_GENERATOR_s* pg)
394 {
395 volatile uint16_t retval=1;
396
397 if(pg == NULL) return(0); // NULL pointer protection
398
399 // Set PWM generator override bits to prevent signals being generated outside the device
400 pg->PGxIOCONL.bits.OVRENH = 0;
401 pg->PGxIOCONL.bits.OVRENL = 0;
402
403 return(retval);
404
405 }
406
407 /*********************************************************************************
408 * @fn uint16_t p33c_PwmGenerator_Suspend(volatile struct P33C_PWM_GENERATOR_s* pg)
409 * @ingroup lib-layer-pral-functions-public-pwm
410 * @brief Disables the PWM generator outputs but keeps the module running
411 * @param pg Pointer to PWM generator peripheral instance register set of type struct P33C_PWM_GENERATOR_s
412 * @return 0 = failure, enabling PWM generator IOs was not successful
413 * @return 1 = success, enabling PWM generator IOs was successful
414 *
415 * @details
416 * This function disables the PWM Generator IO instance preventing
417 * signals to be routed to the output pins. This on/off transition
418 * occurs synchronously to the PWM period.
419 *
420 *********************************************************************************/
421
422 volatile uint16_t p33c_PwmGenerator_Suspend(volatile struct P33C_PWM_GENERATOR_s* pg)
423 {
424 volatile uint16_t retval=1;
425
426 // Set PWM generator override bits to prevent signals being generated outside the device
427 pg->PGxIOCONL.bits.OVRENH = 1;
428 pg->PGxIOCONL.bits.OVRENL = 1;
429
430 return(retval);
431
432 }
433
434
435 /*********************************************************************************
436 * @fn uint16_t p33c_PwmGenerator_SetPeriod(volatile struct P33C_PWM_GENERATOR_s* pg, volatile uint16_t period )
437 * @ingroup lib-layer-pral-functions-public-pwm
438 * @brief Sets the period of a given PWM generator
439 * @param pg Pointer to PWM generator peripheral instance register set of type struct P33C_PWM_GENERATOR_s
440 * @param period Counter compare value of type unsigned integer of the PWM generator time base
441 * @return 0 = failure, disabling PWM generator was not successful
442 * @return 1 = success, disabling PWM generator was successful
443 *
444 * @details
445 * This function writes the value specified by 'period' to the PERIOD register
446 * of the specified PWM generator.
447 *
448 *********************************************************************************/
449
450 volatile uint16_t p33c_PwmGenerator_SetPeriod(
451 volatile struct P33C_PWM_GENERATOR_s* pg,
452 volatile uint16_t period
453 )
454 {
455 volatile uint16_t retval=1;
456
457 // Set PWM generator period
458 pg->PGxPER.value = period;
459
460 return(retval);
461
462 }
463
464
465 /*********************************************************************************
466 * @fn uint16_t p33c_PwmGenerator_SetDutyCycle(
467 volatile struct P33C_PWM_GENERATOR_s* pg,
468 volatile uint16_t duty
469 )
470 * @ingroup lib-layer-pral-functions-public-pwm
471 * @brief Sets the on-time of a given PWM generator
472 * @param pg Pointer to PWM generator peripheral instance register set of type struct P33C_PWM_GENERATOR_s
473 * @param duty Duty cycle counter value of type unsigned integer
474 * @return 0 = failure, disabling PWM generator was not successful
475 * @return 1 = success, disabling PWM generator was successful
476 *
477 * @details
478 * This function writes the value specified by 'duty' to the DUTY CYCLE register
479 * of the specified PWM generator.
480 *
481 *********************************************************************************/
482
483 volatile uint16_t p33c_PwmGenerator_SetDutyCycle(
484 volatile struct P33C_PWM_GENERATOR_s* pg,
485 volatile uint16_t duty
486 )
487 {
488 volatile uint16_t retval=1;
489
490 // Set PWM generator duty cycle
491 pg->PGxDC.value = duty;
492
493 return(retval);
494
495 }
496
497
498 /*********************************************************************************
499 * @fn uint16_t p33c_PwmGenerator_SetDeadTimes(
500 volatile struct P33C_PWM_GENERATOR_s* pg,
501 volatile uint16_t dead_time_rising,
502 volatile uint16_t dead_time_falling)
503 * @ingroup lib-layer-pral-functions-public-pwm
504 * @brief Sets the dead-times of a given PWM generator
505 * @param pg Pointer to PWM generator peripheral instance register set of type struct P33C_PWM_GENERATOR_s
506 * @param dead_time_rising Rising edge dead time counter value of type unsigned integer
507 / @param dead_time_falling Falling edge dead time counter value of type unsigned integer
508 * @return 0 = failure, disabling PWM generator was not successful
509 * @return 1 = success, disabling PWM generator was successful
510 *
511 * @details
512 * This function writes the value specified by 'duty' to the DUTY CYCLE register
513 * of the specified PWM generator.
514 *
515 *********************************************************************************/
516
517 volatile uint16_t p33c_PwmGenerator_SetDeadTimes(
518 volatile struct P33C_PWM_GENERATOR_s* pg,
519 volatile uint16_t dead_time_rising,
520 volatile uint16_t dead_time_falling
521 )
522 {
523 volatile uint16_t retval=1;
524
525 if(pg == NULL) return(0); // NULL pointer protection
526
527 // Set PWM generator period
528 pg->PGxDTH.value = dead_time_rising;
529 pg->PGxDTL.value = dead_time_falling;
530
531 return(retval);
532
533 }
534
535
536 /*********************************************************************************
537 * volatile uint16_t p33c_PwmGenerator_GetInstance(volatile struct P33C_PWM_GENERATOR_s* pg)
538 * @ingroup lib-layer-pral-functions-public-pwm
539 * @brief Get the PWM generator instance index of a known PWM object pointer address
540 * @param pg Pointer to PWM generator peripheral instance register set of type struct P33C_PWM_GENERATOR_s
541 * @return index of PWM generator instance of type unsigned integer
542 *
543 * @details
544 * This function returns the non-zero PWM generator instance index of the PWM generator of
545 * the PWM generator Special Function Register set referenced by the pointer address of
546 * function parameter pg. If the memory address does not match any available PWM generator
547 * instance start address, this function returns '0'.
548 *
549 *********************************************************************************/
550 volatile uint16_t p33c_PwmGenerator_GetInstance(volatile struct P33C_PWM_GENERATOR_s* pg)
551 {
552 volatile uint16_t retval=1;
553
554 // Null-pointer protection
555 if (pg == NULL)
556 return(0);
557
558 // Capture Instance: set pointer to memory address of desired PWM instance
559 retval = (volatile uint16_t)
560 (((volatile uint16_t)&pg->PGxCONL - (volatile uint16_t)&PG1CONL) / P33C_PWMGEN_SFR_OFFSET) + 1;
561
562 if (retval > P33C_PG_COUNT)
563 return(0); // PWM generator not member of a valid group
564
565 return(retval);
566 }
567
568 /*********************************************************************************
569 * volatile uint16_t p33c_PwmGenerator_GetGroup(volatile struct P33C_PWM_GENERATOR_s* pg)
570 * @ingroup lib-layer-pral-functions-public-pwm
571 * @brief Get the PWM generator group
572 * @param pg Pointer to PWM generator peripheral instance register set of type struct P33C_PWM_GENERATOR_s
573 * @return 0 = error, PWM generator group not found
574 * @return 1 = PWM generator is in group #1
575 * @return 2 = PWM generator is in group #2
576 *
577 * @details
578 * This function identify the group to which the PWM generator instance belongs
579 * (1 = [PG1-PG4], 2 = [PG5-PG8]) and verifies if the PWMgenerator group
580 * is valid and available. If no group is found, the function returns '0'
581 *********************************************************************************/
582 volatile uint16_t p33c_PwmGenerator_GetGroup(volatile struct P33C_PWM_GENERATOR_s* pg)
583 {
584 volatile uint16_t retval=1;
585 volatile uint16_t pgInstance;
586
587 // Null-pointer protection
588 if (pg == NULL)
589 return(0);
590
591 // Get group of PWM generator
592 pgInstance = p33c_PwmGenerator_GetInstance(pg);
593
594 // Verify PWM generator group is valid and available
595 if (pgInstance > P33C_PG_COUNT)
596 return(0); // PWM generator not member of a valid group
597 else if (pgInstance > 4)
598 retval = 2; // PWM generator is member of group #2 [PG5-PG8]
599 else
600 retval = 1; // PWM generator is member of group #1 [PG1-PG4]
601
602 return(retval);
603 }
604
605 /*********************************************************************************
606 * @fn uint16_t p33c_PwmGenerator_SyncGenerators(volatile struct P33C_PWM_GENERATOR_s* pgHandleMother, volatile uint16_t pgMotherTriggerOutput, volatile struct P33C_PWM_GENERATOR_s* pgHandleChild, volatile bool ChildImmediateUpdate)
607 * @ingroup lib-layer-pral-functions-public-pwm
608 * @brief Sets the synchronization triggers of two PWM generators, of which the Mother PWM generator is the trigger provider and the Child PWM generator is the synchronization trigger receiver.
609 * @param pgHandleMother Pointer to PWM generator object of type struct P33C_PWM_GENERATOR_s of triggering PWM generator (sync trigger provider)
610 * @param pgMotherTriggerOutput Trigger output selection of type unsigned integer of Sync Trigger Provider of the selected PWM generator instance
611 * 0 = EOC/SOC
612 * 1 = PGxTRIGA
613 * 2 = PGxTRIGB
614 * 3 = PGxTRIGC
615 * @param pgHandleChild Pointer to PWM generator object of type struct P33C_PWM_GENERATOR_s of triggered PWM generator (sync trigger receiver)
616 * @param ChildImmediateUpdate
617 * true = synchronization trigger synchronizes Child PWM generator at trigger edge
618 * false = synchronization trigger synchronizes Child PWM generator at EOC/SOC
619 * @return 0 = failure, PWM generator synchronization was not successful
620 * @return 1 = success, PWM generator synchronization was successful
621 *
622 * @details
623 * This function sets the synchronization triggers of two PWM generators,
624 * of which the Mother PWM generator is the trigger provider and the Child
625 * PWM generator is the synchronization trigger receiver.
626 *
627 * The Mother PWM generator is configured to broadcast its UPDATE bit and
628 * provides one of four, selectable synchronization trigger outputs (EOC/SOC,
629 * PGxTRIGA, PGxTRIGB or PGxTRIGC). The Mother PWM generator can be
630 * independent or being triggered by another PWM generator.
631 *
632 * The Child PWM generator is configured to trigger on the event generated
633 * by the Mother PWM generator as configured above. The optional selection
634 * of immediate synchronization or synchronization of the SOC event is set
635 * by parameter ChildImmediateUpdate.
636 *
637 *********************************************************************************/
638
639 volatile uint16_t p33c_PwmGenerator_SyncGenerators(
640 volatile struct P33C_PWM_GENERATOR_s* pgHandleMother,
641 volatile uint16_t pgMotherTriggerOutput,
642 volatile struct P33C_PWM_GENERATOR_s* pgHandleChild,
643 volatile bool ChildImmediateUpdate
644 )
645 {
646 volatile uint16_t retval=1;
647 volatile uint16_t pgMotherInstance=0;
648 volatile uint16_t pgChildInstance=0;
649 volatile uint16_t pgMotherGroup=0;
650 volatile uint16_t pgChildGroup=0;
651 volatile uint16_t pgInstance;
652
653 // Null-pointer protection
654 if ((pgHandleMother == NULL) || (pgHandleChild == NULL))
655 return(0);
656
657 // Capture PWM generator instances and groups for given handles
658 pgMotherInstance = p33c_PwmGenerator_GetInstance(pgHandleMother);
659 pgMotherGroup = p33c_PwmGenerator_GetGroup(pgHandleMother);
660
661 pgChildInstance = p33c_PwmGenerator_GetInstance(pgHandleChild);
662 pgChildGroup = p33c_PwmGenerator_GetGroup(pgHandleChild);
663
664 // Enable update trigger broadcast in Mother PWM
665 // PWM generator broadcasts software set/clear of the UPDREQ status bit and EOC signal
666 pgHandleMother->PGxCONH.bits.MSTEN = 1;
667
668 // PWM Generator Trigger Output Selection
669 // 0b011 = PGxTRIGC compare event is the PWM Generator trigger
670 // 0b010 = PGxTRIGB compare event is the PWM Generator trigger
671 // 0b001 = PGxTRIGA compare event is the PWM Generator trigger
672 // 0b000 = EOC event is the PWM Generator trigger
673 pgHandleMother->PGxEVTL.bits.PGTRGSEL = (pgMotherTriggerOutput & 0x0003);
674
675 // Configure child PWM in slaved mode, incorporating immediate of EOC selection
676 pgHandleChild->PGxCONH.bits.UPDMOD = (0b010 | ChildImmediateUpdate); // Slaved SOC update
677 pgHandleChild->PGxCONH.bits.TRGMOD = 1; // PWM Generator operates in Retriggerable mode
678 pgHandleChild->PGxEVTL.bits.UPDTRG = 0b00; // Timing register updates triggered through UPDREQ bit (PGxSTAT[3])
679 pgHandleChild->PGxCONL.bits.MODSEL = 0b000; // Independent Edge PWM mode;
680
681 /* Set sync trigger input to Child generator
682
683 SOCS[3:0]: Start-of-Cycle Selection bits(1,2,3)
684 1111 = TRIG bit or PCI Sync function only (no hardware trigger source is selected)
685 1110-0101 = Reserved
686 0100 = Trigger output selected by PG4 or PG8 PGTRGSEL[2:0] bits (PGxEVTL[2:0])
687 0011 = Trigger output selected by PG3 or PG7 PGTRGSEL[2:0] bits (PGxEVTL[2:0])
688 0010 = Trigger output selected by PG2 or PG6 PGTRGSEL[2:0] bits (PGxEVTL[2:0])
689 0001 = Trigger output selected by PG1 or PG5 PGTRGSEL[2:0] bits (PGxEVTL[2:0])
690 0000 = Local EOC ? PWM Generator is self-triggered
691
692 */
693
694 if (pgMotherGroup == pgChildGroup)
695 {
696 // If both PWM generators are member of the same group,
697 // direct synchronization can be used
698
699 if (pgMotherGroup == 1)
700 pgHandleChild->PGxCONH.bits.SOCS = pgMotherInstance;
701 else if (pgMotherGroup == 2)
702 pgHandleChild->PGxCONH.bits.SOCS = (pgMotherInstance - 4);
703 else
704 return(0); // Exit if PWM generator group is out of range
705
706 }
707 else
708 {
709 // Synchronization across PWM generator groups need to be routed
710 // through the PCI Sync function
711
712 pgInstance = p33c_PwmGenerator_GetInstance(pgHandleChild);
713
714 pgHandleChild->PGxCONH.bits.SOCS = 0b1111;
715 pgHandleChild->PGxSPCIL.bits.PSS = 0b00001; // Internally connected to the output of PWMPCI[2:0] MUX
716 pgHandleChild->PGxLEBH.bits.PWMPCI = pgInstance;
717 }
718
719
720 return(retval);
721
722 }
723
724 /* ********************************************************************************************* *
725 * PWM MODULE BASE CONFIGURATION TEMPLATES
726 * ********************************************************************************************* */
727
728 /*********************************************************************************
729 * @var struct P33C_PWM_MODULE_s pwmConfigClear
730 * @ingroup lib-layer-pral-properties-private-pwm
731 * @brief Default RESET configuration of the PWM module SFRs
732 *
733 * @details
734 * Default configuration of the PWM module SFRs with all its registers being
735 * reset to their default state when the device comes out of RESET.
736 * Programmers can use this template to reset (dispose) a previously used
737 * PWM module when it's not used anymore or to secure a known startup
738 * condition before writing individual configurations to its SFRs.
739 *
740 ********************************************************************************/
741
742 volatile struct P33C_PWM_MODULE_s pwmConfigClear = {
743
744 .vPCLKCON.value = 0x0000, // HRRDY=0, HRERR=0, LOCK=0, DIVSEL=0b00, MCLKSEL=0b00
745 .vFSCL.value = 0x0000, // FSCL=0
746 .vFSMINPER.value = 0x0000, // FSMINPER=0
747 .vMPHASE.value = 0x0000, // MPHASE=0
748 .vMDC.value = 0x0000, // MDC=0
749 .vMPER.value = 0x0000, // MPER=0
750 .vLFSR.value = 0x0000, // LFSR=0
751 .vCMBTRIGL.value = 0x0000, // CTA1EN=0, CTA2EN=0, CTA3EN=0, CTA4EN=0, CTA5EN=0, CTA6EN=0, CTA7EN=0, CTA8EN=0
752 .vCMBTRIGH.value = 0x0000, // CTB1EN=0, CTB2EN=0, CTB3EN=0, CTB4EN=0, CTB5EN=0, CTB6EN=0, CTB7EN=0, CTB8EN=0
753 .LOGCON_A.value = 0x0000, // PWMS1A=0b0000, PWMS2A=0b0000, S1APOL=0, S2APOL=0, PWMLFA=0b00, PWMLFAD=0b000
754 .LOGCON_B.value = 0x0000, // PWMS1B=0b0000, PWMS2B=0b0000, S1BPOL=0, S2BPOL=0, PWMLFB=0b00, PWMLFBD=0b000
755 .LOGCON_C.value = 0x0000, // PWMS1C=0b0000, PWMS2C=0b0000, S1CPOL=0, S2CPOL=0, PWMLFC=0b00, PWMLFCD=0b000
756 .LOGCON_D.value = 0x0000, // PWMS1D=0b0000, PWMS2D=0b0000, S1DPOL=0, S2DPOL=0, PWMLFD=0b00, PWMLFDD=0b000
757 .LOGCON_E.value = 0x0000, // PWMS1E=0b0000, PWMS2E=0b0000, S1EPOL=0, S2EPOL=0, PWMLFE=0b00, PWMLFED=0b000
758 .LOGCON_F.value = 0x0000, // PWMS1F=0b0000, PWMS2F=0b0000, S1FPOL=0, S2FPOL=0, PWMLFF=0b00, PWMLFFD=0b000
759 .PWMEVT_A.value = 0x0000, // EVTAOEN=0, EVTAPOL=0, EVTASTRD=0, EVTASYNC=0, EVTASEL=0b000, EVTAPGS=0b000
760 .PWMEVT_B.value = 0x0000, // EVTBOEN=0, EVTBPOL=0, EVTBSTRD=0, EVTBSYNC=0, EVTBSEL=0b000, EVTBPGS=0b000
761 .PWMEVT_C.value = 0x0000, // EVTCOEN=0, EVTCPOL=0, EVTCSTRD=0, EVTCSYNC=0, EVTCSEL=0b000, EVTCPGS=0b000
762 .PWMEVT_D.value = 0x0000, // EVTDOEN=0, EVTDPOL=0, EVTDSTRD=0, EVTDSYNC=0, EVTDSEL=0b000, EVTDPGS=0b000
763 .PWMEVT_E.value = 0x0000, // EVTEOEN=0, EVTEPOL=0, EVTESTRD=0, EVTESYNC=0, EVTESEL=0b000, EVTEPGS=0b000
764 .PWMEVT_F.value = 0x0000 // EVTFOEN=0, EVTFPOL=0, EVTFSTRD=0, EVTFSYNC=0, EVTFSEL=0b000, EVTFPGS=0b000
765 };
766
767 /*******************************************************************************
768 * @var struct P33C_PWM_MODULE_s pwmConfigDefault
769 * @ingroup lib-layer-pral-properties-private-pwm
770 * @brief Default initialization configuration of the PWM module SFRs
771 *
772 * @details
773 * Default configuration of the PWM module SFRs for normal operation at
774 * maximum performance using the auxiliary clock input, expecting a
775 * 500 MHz input clock. All other functions of the PWM module base registers,
776 * such as combinatorial logic blocks, are turned off.
777 * Programmers can use this template to initialize the PWM module
778 * in default mode before writing individual configurations to its SFRs.
779 *
780 ********************************************************************************/
781
782 volatile struct P33C_PWM_MODULE_s pwmConfigDefault = {
783
784 .vPCLKCON.value = 0x0003, // HRRDY=0, HRERR=0, LOCK=0, DIVSEL=0b00, MCLKSEL=0b11
785 .vFSCL.value = 0x0000, // FSCL=0
786 .vFSMINPER.value = 0x0000, // FSMINPER=0
787 .vMPHASE.value = 0x0000, // MPHASE=0
788 .vMDC.value = 0x0000, // MDC=0
789 .vMPER.value = 0x0000, // MPER=0
790 .vLFSR.value = 0x0000, // LFSR=0
791 .vCMBTRIGL.value = 0x0000, // CTA1EN=0, CTA2EN=0, CTA3EN=0, CTA4EN=0, CTA5EN=0, CTA6EN=0, CTA7EN=0, CTA8EN=0
792 .vCMBTRIGH.value = 0x0000, // CTB1EN=0, CTB2EN=0, CTB3EN=0, CTB4EN=0, CTB5EN=0, CTB6EN=0, CTB7EN=0, CTB8EN=0
793 .LOGCON_A.value = 0x0000, // PWMS1A=0b0000, PWMS2A=0b0000, S1APOL=0, S2APOL=0, PWMLFA=0b00, PWMLFAD=0b000
794 .LOGCON_B.value = 0x0000, // PWMS1B=0b0000, PWMS2B=0b0000, S1BPOL=0, S2BPOL=0, PWMLFB=0b00, PWMLFBD=0b000
795 .LOGCON_C.value = 0x0000, // PWMS1C=0b0000, PWMS2C=0b0000, S1CPOL=0, S2CPOL=0, PWMLFC=0b00, PWMLFCD=0b000
796 .LOGCON_D.value = 0x0000, // PWMS1D=0b0000, PWMS2D=0b0000, S1DPOL=0, S2DPOL=0, PWMLFD=0b00, PWMLFDD=0b000
797 .LOGCON_E.value = 0x0000, // PWMS1E=0b0000, PWMS2E=0b0000, S1EPOL=0, S2EPOL=0, PWMLFE=0b00, PWMLFED=0b000
798 .LOGCON_F.value = 0x0000, // PWMS1F=0b0000, PWMS2F=0b0000, S1FPOL=0, S2FPOL=0, PWMLFF=0b00, PWMLFFD=0b000
799 .PWMEVT_A.value = 0x0000, // EVTAOEN=0, EVTAPOL=0, EVTASTRD=0, EVTASYNC=0, EVTASEL=0b000, EVTAPGS=0b000
800 .PWMEVT_B.value = 0x0000, // EVTBOEN=0, EVTBPOL=0, EVTBSTRD=0, EVTBSYNC=0, EVTBSEL=0b000, EVTBPGS=0b000
801 .PWMEVT_C.value = 0x0000, // EVTCOEN=0, EVTCPOL=0, EVTCSTRD=0, EVTCSYNC=0, EVTCSEL=0b000, EVTCPGS=0b000
802 .PWMEVT_D.value = 0x0000, // EVTDOEN=0, EVTDPOL=0, EVTDSTRD=0, EVTDSYNC=0, EVTDSEL=0b000, EVTDPGS=0b000
803 .PWMEVT_E.value = 0x0000, // EVTEOEN=0, EVTEPOL=0, EVTESTRD=0, EVTESYNC=0, EVTESEL=0b000, EVTEPGS=0b000
804 .PWMEVT_F.value = 0x0000 // EVTFOEN=0, EVTFPOL=0, EVTFSTRD=0, EVTFSYNC=0, EVTFSEL=0b000, EVTFPGS=0b000
805 };
806
807 /* ********************************************************************************************* *
808 * PWM GENERATOR CONFIGURATION TEMPLATES
809 * ********************************************************************************************* */
810
811 /*********************************************************************************
812 * @var struct P33C_PWM_GENERATOR_s pgConfigClear
813 * @ingroup lib-layer-pral-properties-private-pwm
814 * @brief Default RESET configuration of one PWM generator instance SFRs
815 *
816 * @details
817 * Default configuration of the PWM generator SFRs with all its registers
818 * being reset to their default state when the device comes out of RESET.
819 * Programmers can use this template to reset (dispose) a previously used
820 * PWM generator when it's not used anymore or to secure a known startup
821 * condition before writing individual configurations to its SFRs.
822 *
823 ********************************************************************************/
824
825 volatile struct P33C_PWM_GENERATOR_s pgConfigClear = {
826
827 .PGxCONL.value = 0x0000, // ON=0, TRGCNT=0b000, HREN=0, CLKSEL=b00, MODSEL=0b000
828 .PGxCONH.value = 0x0000, // MDCSEL=0, MPERSEL=0, MPHSEL=0, MSTEN=0, UPDMOD=0b000, TRGMOD=0, SOCS=0b0000
829 .PGxSTAT.value = 0x0000, // SEVT=0, FLTEVT=0, CLEVT=0, FFEVT=0, SACT=0, FLTACT=0, CLACT=0, FFACT=0, TRSET=0, TRCLR=0, CAP=0, UPDATE=0, UPDREQ=0, STEER=0, CAHALF=0, TRIG=0
830 .PGxIOCONL.value = 0x0000, // CLMOD=0, SWAP=0, OVRENH=0, OVRENL=0, OVRDAT=0, OSYNC=0b00, FLTDAT=0, CLDAT=0, FFDAT=0, DBDAT=0
831 .PGxIOCONH.value = 0x0000, // CAPSRC=0b000, DTCMPSEL=0, PMOD=0b00, PENH=0, PENL=0, POLH=0, POLL=0
832 .PGxEVTL.value = 0x0000, // ADTR1PS=0b00000, ADTR1EN3=0, ADTR1EN2=0, ADTR1EN1=0, UPDTRG=0b00, PGTRGSEL=0b000
833 .PGxEVTH.value = 0x0000, // FLTIEN=0, CLIEN=0, FFIEN=0, SIEN=0, IEVTSEL=0b00, ADTR2EN3=0, ADTR2EN2=0, ADTR2EN1=0, ADTR1OFS=0b00000
834 .PGxFPCIL.value = 0x0000, // TSYNCDIS=0, TERM=0b000, AQPS=0, AQSS=0b000, SWTERM=0, PSYNC=0, PPS=0, PSS=0b00000
835 .PGxFPCIH.value = 0x0000, // BPEN=0, BPSEL=0b000, ACP0b000, SWPCI=0, SWPCIM=0b00, LATMOD=0, TQPS=0, TQSS=0b000
836 .PGxCLPCIL.value = 0x0000, // TSYNCDIS=0, TERM=0b000, AQPS=0, AQSS=0b000, SWTERM=0, PSYNC=0, PPS=0, PSS=0b00000
837 .PGxCLPCIH.value = 0x0000, // BPEN=0, BPSEL=0b000, ACP0b000, SWPCI=0, SWPCIM=0b00, LATMOD=0, TQPS=0, TQSS=0b000
838 .PGxFFPCIL.value = 0x0000, // TSYNCDIS=0, TERM=0b000, AQPS=0, AQSS=0b000, SWTERM=0, PSYNC=0, PPS=0, PSS=0b00000
839 .PGxFFPCIH.value = 0x0000, // BPEN=0, BPSEL=0b000, ACP0b000, SWPCI=0, SWPCIM=0b00, LATMOD=0, TQPS=0, TQSS=0b000
840 .PGxSPCIL.value = 0x0000, // TSYNCDIS=0, TERM=0b000, AQPS=0, AQSS=0b000, SWTERM=0, PSYNC=0, PPS=0, PSS=0b00000
841 .PGxSPCIH.value = 0x0000, // BPEN=0, BPSEL=0b000, ACP0b000, SWPCI=0, SWPCIM=0b00, LATMOD=0, TQPS=0, TQSS=0b000
842 .PGxLEBL.value = 0x0000, // LEB=0
843 .PGxLEBH.value = 0x0000, // PWMPCI=0b000, PHR=0, PHF=0, PLR=0, PLF=0,
844 .PGxPHASE.value = 0x0000, // PGxPHASE=0
845 .PGxDC.value = 0x0000, // PGxDC=0
846 .PGxDCA.value = 0x0000, // PGxDCA=0
847 .PGxPER.value = 0x0000, // PGxPER=0
848 .PGxTRIGA.value = 0x0000, // PGxTRIGA=0
849 .PGxTRIGB.value = 0x0000, // PGxTRIGB=0
850 .PGxTRIGC.value = 0x0000, // PGxTRIGC=0
851 .PGxDTL.value = 0x0000, // DTL=0
852 .PGxDTH.value = 0x0000, // DTH=0
853 .PGxCAP.value = 0x0000 // CAP=0
854 };
855
856
857
858 // end of file
P33C_PWM_GENERATOR_s::PGxSPCIL
union P33C_PWM_GENERATOR_s::@279 PGxSPCIL
P33C_PWM_MODULE_s::vPCLKCON
union P33C_PWM_MODULE_s::@212 vPCLKCON
P33C_PWM_GENERATOR_s::PGxIOCONH
union P33C_PWM_GENERATOR_s::@270 PGxIOCONH
P33C_PWM_GENERATOR_s::PGxPER
union P33C_PWM_GENERATOR_s::@286 PGxPER
P33C_PWM_GENERATOR_s::PGxEVTL
union P33C_PWM_GENERATOR_s::@271 PGxEVTL
P33C_PWM_GENERATOR_s::PGxCONL
union P33C_PWM_GENERATOR_s::@266 PGxCONL
P33C_PWM_GENERATOR_s::PGxIOCONL
union P33C_PWM_GENERATOR_s::@269 PGxIOCONL
P33C_PWM_GENERATOR_s::bits
struct tagPG1CONLBITS bits
Definition: p33c_pwm.h:208
P33C_PWM_GENERATOR_s::PGxDTL
union P33C_PWM_GENERATOR_s::@290 PGxDTL
P33C_PWM_GENERATOR_s::PGxLEBH
union P33C_PWM_GENERATOR_s::@282 PGxLEBH
P33C_PWM_GENERATOR_s::PGxDTH
union P33C_PWM_GENERATOR_s::@291 PGxDTH
P33C_PWM_GENERATOR_s::value
uint16_t value
Definition: p33c_pwm.h:209
P33C_PWM_MODULE_s
Definition: p33c_pwm.h:84
P33C_PWM_MODULE_s::value
uint16_t value
Definition: p33c_pwm.h:88
P33C_PWM_GENERATOR_s
Definition: p33c_pwm.h:206
P33C_PWM_GENERATOR_s::PGxSTAT
union P33C_PWM_GENERATOR_s::@268 PGxSTAT
P33C_PWM_GENERATOR_s::PGxCONH
union P33C_PWM_GENERATOR_s::@267 PGxCONH
P33C_PWM_GENERATOR_s::PGxDC
union P33C_PWM_GENERATOR_s::@284 PGxDC