@@ -91,6 +91,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
91
91
pwm -> CTRL &= ~(0x7F << 5 );
92
92
pwm -> CTRL |= (((SystemCoreClock /1000000 - 1 ) & 0x7F ) << 5 );
93
93
94
+ // Set event number
94
95
pwm -> OUT [sct_n ].SET = (1 << ((sct_n * 2 ) + 0 ));
95
96
pwm -> OUT [sct_n ].CLR = (1 << ((sct_n * 2 ) + 1 ));
96
97
@@ -99,10 +100,6 @@ void pwmout_init(pwmout_t* obj, PinName pin)
99
100
pwm -> EVENT [(sct_n * 2 ) + 1 ].CTRL = (1 << 12 ) | ((sct_n * 2 ) + 1 );
100
101
pwm -> EVENT [(sct_n * 2 ) + 1 ].STATE = 0xFFFFFFFF ;
101
102
102
- // unhalt the counter:
103
- // - clearing bit 2 of the CTRL register
104
- pwm -> CTRL &= ~(1 << 2 );
105
-
106
103
// default to 20ms: standard for servos, and fine for e.g. brightness control
107
104
pwmout_period_ms (obj , 20 );
108
105
pwmout_write (obj , 0 );
@@ -120,16 +117,27 @@ void pwmout_write(pwmout_t* obj, float value)
120
117
if (value < 0.0f ) {
121
118
value = 0.0 ;
122
119
} else if (value > 1.0f ) {
123
- value = 1.0 ;
120
+ value = 1.0f ;
121
+ }
122
+ uint32_t t_on = (uint32_t )((float )(obj -> pwm -> MATCHREL [obj -> pwm_ch * 2 ] + 1 ) * value );
123
+ if (t_on > 0 ) {
124
+ if (value != 1.0f ) {
125
+ obj -> pwm -> MATCHREL [(obj -> pwm_ch * 2 ) + 1 ] = t_on - 1 ;
126
+ obj -> pwm -> CTRL &= ~(1 << 2 );
127
+ } else {
128
+ obj -> pwm -> CTRL |= (1 << 2 ) | (1 << 3 );
129
+ obj -> pwm -> OUTPUT |= (1 << obj -> pwm_ch );
130
+ }
131
+ } else {
132
+ obj -> pwm -> CTRL |= (1 << 2 ) | (1 << 3 );
133
+ obj -> pwm -> OUTPUT &= ~(1 << obj -> pwm_ch );
124
134
}
125
- uint32_t t_on = (uint32_t )((float )(obj -> pwm -> MATCHREL [obj -> pwm_ch * 2 ]) * value );
126
- obj -> pwm -> MATCHREL [(obj -> pwm_ch * 2 ) + 1 ] = t_on ;
127
135
}
128
136
129
137
float pwmout_read (pwmout_t * obj )
130
138
{
131
- uint32_t t_off = obj -> pwm -> MATCHREL [(obj -> pwm_ch * 2 ) + 0 ];
132
- uint32_t t_on = obj -> pwm -> MATCHREL [(obj -> pwm_ch * 2 ) + 1 ];
139
+ uint32_t t_off = obj -> pwm -> MATCHREL [(obj -> pwm_ch * 2 ) + 0 ] + 1 ;
140
+ uint32_t t_on = obj -> pwm -> MATCHREL [(obj -> pwm_ch * 2 ) + 1 ] + 1 ;
133
141
float v = (float )t_on /(float )t_off ;
134
142
return (v > 1.0f ) ? (1.0f ) : (v );
135
143
}
@@ -147,11 +155,17 @@ void pwmout_period_ms(pwmout_t* obj, int ms)
147
155
// Set the PWM period, keeping the duty cycle the same.
148
156
void pwmout_period_us (pwmout_t * obj , int us )
149
157
{
150
- uint32_t t_off = obj -> pwm -> MATCHREL [(obj -> pwm_ch * 2 ) + 0 ];
151
- uint32_t t_on = obj -> pwm -> MATCHREL [(obj -> pwm_ch * 2 ) + 1 ];
158
+ uint32_t t_off = obj -> pwm -> MATCHREL [(obj -> pwm_ch * 2 ) + 0 ] + 1 ;
159
+ uint32_t t_on = obj -> pwm -> MATCHREL [(obj -> pwm_ch * 2 ) + 1 ] + 1 ;
152
160
float v = (float )t_on /(float )t_off ;
153
- obj -> pwm -> MATCHREL [(obj -> pwm_ch * 2 ) + 0 ] = (uint32_t )us ;
154
- obj -> pwm -> MATCHREL [(obj -> pwm_ch * 2 ) + 1 ] = (uint32_t )((float )us * (float )v );
161
+ obj -> pwm -> MATCHREL [(obj -> pwm_ch * 2 ) + 0 ] = (uint32_t )us - 1 ;
162
+ if (us > 0 ) {
163
+ obj -> pwm -> MATCHREL [(obj -> pwm_ch * 2 ) + 1 ] = (uint32_t )((float )us * (float )v ) - 1 ;
164
+ obj -> pwm -> CTRL &= ~(1 << 2 );
165
+ } else {
166
+ obj -> pwm -> CTRL |= (1 << 2 ) | (1 << 3 );
167
+ obj -> pwm -> OUTPUT &= ~(1 << obj -> pwm_ch );
168
+ }
155
169
}
156
170
157
171
void pwmout_pulsewidth (pwmout_t * obj , float seconds )
@@ -166,7 +180,13 @@ void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
166
180
167
181
void pwmout_pulsewidth_us (pwmout_t * obj , int us )
168
182
{
169
- obj -> pwm -> MATCHREL [(obj -> pwm_ch * 2 ) + 1 ] = (uint32_t )us ;
183
+ if (us > 0 ) {
184
+ obj -> pwm -> MATCHREL [(obj -> pwm_ch * 2 ) + 1 ] = (uint32_t )us - 1 ;
185
+ obj -> pwm -> CTRL &= ~(1 << 2 );
186
+ } else {
187
+ obj -> pwm -> CTRL |= (1 << 2 ) | (1 << 3 );
188
+ obj -> pwm -> OUTPUT &= ~(1 << obj -> pwm_ch );
189
+ }
170
190
}
171
191
172
192
#endif
0 commit comments