@@ -45,16 +45,21 @@ struct pwm_sam0_config {
4545};
4646
4747#define COUNTER_8BITS 8U
48+ #define COUNTER_16BITS 16U
49+ #define SYNC_WAIT_TIMEOUT 5U
50+
4851
4952/* Wait for the peripheral to finish all commands */
5053static void wait_synchronization (Tc * regs , uint8_t counter_size )
5154{
5255 if (COUNTER_8BITS == counter_size ) {
5356 while (regs -> COUNT8 .SYNCBUSY .reg != 0 ) {
5457 }
55- } else {
58+ } else if ( COUNTER_16BITS == counter_size ) {
5659 while (regs -> COUNT16 .SYNCBUSY .reg != 0 ) {
5760 }
61+ } else {
62+ WAIT_FOR ((regs -> COUNT32 .SYNCBUSY .reg != 0 ), SYNC_WAIT_TIMEOUT , NULL );
5863 }
5964}
6065
@@ -78,15 +83,14 @@ static int pwm_sam0_set_cycles(const struct device *dev, uint32_t channel, uint3
7883 const struct pwm_sam0_config * const cfg = dev -> config ;
7984 Tc * regs = cfg -> regs ;
8085 uint8_t counter_size = cfg -> counter_size ;
81- uint32_t top = 1 << counter_size ;
86+ uint64_t top = BIT64 ( counter_size ) ;
8287 uint32_t invert_mask = 1 << channel ;
8388 bool invert = ((flags & PWM_POLARITY_INVERTED ) != 0 );
8489 bool inverted ;
85-
8690 if (channel >= cfg -> channels ) {
8791 return - EINVAL ;
8892 }
89- if (period_cycles >= top || pulse_cycles >= top ) {
93+ if (( uint64_t ) period_cycles >= top || pulse_cycles >= top ) {
9094 return - EINVAL ;
9195 }
9296
@@ -108,7 +112,7 @@ static int pwm_sam0_set_cycles(const struct device *dev, uint32_t channel, uint3
108112 regs -> COUNT8 .CTRLA .bit .ENABLE = 1 ;
109113 wait_synchronization (regs , counter_size );
110114 }
111- } else {
115+ } else if ( COUNTER_16BITS == counter_size ) {
112116 inverted = ((regs -> COUNT16 .DRVCTRL .vec .INVEN & invert_mask ) != 0 );
113117 regs -> COUNT16 .CCBUF [0 ].reg = TC_COUNT16_CCBUF_CCBUF (period_cycles );
114118 regs -> COUNT16 .CCBUF [1 ].reg = TC_COUNT16_CCBUF_CCBUF (pulse_cycles );
@@ -122,6 +126,20 @@ static int pwm_sam0_set_cycles(const struct device *dev, uint32_t channel, uint3
122126 regs -> COUNT16 .CTRLA .bit .ENABLE = 1 ;
123127 wait_synchronization (regs , counter_size );
124128 }
129+ } else {
130+ inverted = ((regs -> COUNT32 .DRVCTRL .vec .INVEN & invert_mask ) != 0 );
131+ regs -> COUNT32 .CCBUF [0 ].reg = TC_COUNT32_CCBUF_CCBUF (period_cycles );
132+ regs -> COUNT32 .CCBUF [1 ].reg = TC_COUNT32_CCBUF_CCBUF (pulse_cycles );
133+ wait_synchronization (regs , counter_size );
134+
135+ if (invert != inverted ) {
136+ regs -> COUNT32 .CTRLA .bit .ENABLE = 0 ;
137+ wait_synchronization (regs , counter_size );
138+
139+ regs -> COUNT32 .DRVCTRL .vec .INVEN ^= invert_mask ;
140+ regs -> COUNT32 .CTRLA .bit .ENABLE = 1 ;
141+ wait_synchronization (regs , counter_size );
142+ }
125143 }
126144
127145 return 0 ;
@@ -161,7 +179,7 @@ static int pwm_sam0_init(const struct device *dev)
161179
162180 regs -> COUNT8 .CTRLA .bit .ENABLE = 1 ;
163181 wait_synchronization (regs , counter_size );
164- } else {
182+ } else if ( COUNTER_16BITS == counter_size ) {
165183 regs -> COUNT16 .CTRLA .bit .SWRST = 1 ;
166184 wait_synchronization (regs , counter_size );
167185
@@ -172,6 +190,16 @@ static int pwm_sam0_init(const struct device *dev)
172190
173191 regs -> COUNT16 .CTRLA .bit .ENABLE = 1 ;
174192 wait_synchronization (regs , cfg -> counter_size );
193+ } else {
194+ regs -> COUNT32 .CTRLA .bit .SWRST = 1 ;
195+ wait_synchronization (regs , counter_size );
196+ regs -> COUNT32 .CTRLA .reg = cfg -> prescaler | TC_CTRLA_MODE_COUNT32 |
197+ TC_CTRLA_PRESCSYNC_PRESC ;
198+ regs -> COUNT32 .WAVE .reg = TC_WAVE_WAVEGEN_MPWM ;
199+ regs -> COUNT32 .CC [0 ].reg = TC_COUNT32_CC_CC (1 );
200+
201+ regs -> COUNT32 .CTRLA .bit .ENABLE = 1 ;
202+ wait_synchronization (regs , counter_size );
175203 }
176204
177205 return 0 ;
0 commit comments