2222
2323static float pwm_clock = 0 ;
2424
25- void pwmout_init (pwmout_t * obj , PinName pin ) {
25+ void pwmout_init (pwmout_t * obj , PinName pin )
26+ {
2627 // determine the channel
2728 PWMName pwm = (PWMName )pinmap_peripheral (pin , PinMap_PWM );
2829 MBED_ASSERT (pwm != (PWMName )NC );
@@ -36,8 +37,9 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
3637 while (clkval > 1 ) {
3738 clkdiv ++ ;
3839 clkval /= 2.0 ;
39- if (clkdiv == 7 )
40+ if (clkdiv == 7 ) {
4041 break ;
42+ }
4143 }
4244
4345 pwm_clock = clkval ;
@@ -53,7 +55,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
5355 ftm -> MODE = FTM_MODE_FTMEN_MASK ;
5456 ftm -> SYNC = FTM_SYNC_CNTMIN_MASK ;
5557 ftm -> SYNCONF = FTM_SYNCONF_SYNCMODE_MASK | FTM_SYNCONF_SWSOC_MASK | FTM_SYNCONF_SWWRBUF_MASK ;
56-
58+
5759 //Without SYNCEN set CnV does not seem to update
5860 ftm -> COMBINE = FTM_COMBINE_SYNCEN0_MASK | FTM_COMBINE_SYNCEN1_MASK | FTM_COMBINE_SYNCEN2_MASK | FTM_COMBINE_SYNCEN3_MASK ;
5961
@@ -64,60 +66,86 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
6466 // default to 20ms: standard for servos, and fine for e.g. brightness control
6567 pwmout_period_ms (obj , 20 );
6668 pwmout_write (obj , 0.0 );
67-
69+
6870 // Wire pinout
6971 pinmap_pinout (pin , PinMap_PWM );
7072}
7173
72- void pwmout_free (pwmout_t * obj ) {}
74+ void pwmout_free (pwmout_t * obj ) {}
7375
74- void pwmout_write (pwmout_t * obj , float value ) {
76+ void pwmout_write (pwmout_t * obj , float value )
77+ {
7578 if (value < 0.0 ) {
7679 value = 0.0 ;
7780 } else if (value > 1.0 ) {
7881 value = 1.0 ;
7982 }
80-
81- while (* obj -> SYNC & FTM_SYNC_SWSYNC_MASK );
83+
84+ while (* obj -> SYNC & FTM_SYNC_SWSYNC_MASK );
8285 * obj -> CnV = (uint32_t )((float )(* obj -> MOD + 1 ) * value );
83- * obj -> SYNC |= FTM_SYNC_SWSYNC_MASK ;
86+ * obj -> SYNC |= FTM_SYNC_SWSYNC_MASK ;
8487}
8588
86- float pwmout_read (pwmout_t * obj ) {
87- while (* obj -> SYNC & FTM_SYNC_SWSYNC_MASK );
89+ float pwmout_read (pwmout_t * obj )
90+ {
91+ while (* obj -> SYNC & FTM_SYNC_SWSYNC_MASK );
8892 float v = (float )(* obj -> CnV ) / (float )(* obj -> MOD + 1 );
8993 return (v > 1.0 ) ? (1.0 ) : (v );
9094}
9195
92- void pwmout_period (pwmout_t * obj , float seconds ) {
96+ void pwmout_period (pwmout_t * obj , float seconds )
97+ {
9398 pwmout_period_us (obj , seconds * 1000000.0f );
9499}
95100
96- void pwmout_period_ms (pwmout_t * obj , int ms ) {
101+ void pwmout_period_ms (pwmout_t * obj , int ms )
102+ {
97103 pwmout_period_us (obj , ms * 1000 );
98104}
99105
100106// Set the PWM period, keeping the duty cycle the same.
101- void pwmout_period_us (pwmout_t * obj , int us ) {
107+ void pwmout_period_us (pwmout_t * obj , int us )
108+ {
102109 float dc = pwmout_read (obj );
103110 * obj -> MOD = (uint32_t )(pwm_clock * (float )us ) - 1 ;
104111 * obj -> SYNC |= FTM_SYNC_SWSYNC_MASK ;
105112 pwmout_write (obj , dc );
106113}
107114
108- void pwmout_pulsewidth (pwmout_t * obj , float seconds ) {
115+ int pwmout_read_period_us (pwmout_t * obj )
116+ {
117+ uint32_t pwm_period = 0 ;
118+ if (pwm_clock > 0 ) {
119+ pwm_period = ((* obj -> MOD ) + 1 ) / pwm_clock ;
120+ }
121+ return pwm_period ;
122+ }
123+
124+ void pwmout_pulsewidth (pwmout_t * obj , float seconds )
125+ {
109126 pwmout_pulsewidth_us (obj , seconds * 1000000.0f );
110127}
111128
112- void pwmout_pulsewidth_ms (pwmout_t * obj , int ms ) {
129+ void pwmout_pulsewidth_ms (pwmout_t * obj , int ms )
130+ {
113131 pwmout_pulsewidth_us (obj , ms * 1000 );
114132}
115133
116- void pwmout_pulsewidth_us (pwmout_t * obj , int us ) {
134+ void pwmout_pulsewidth_us (pwmout_t * obj , int us )
135+ {
117136 * obj -> CnV = (uint32_t )(pwm_clock * (float )us );
118137 * obj -> SYNC |= FTM_SYNC_SWSYNC_MASK ;
119138}
120139
140+ int pwmout_read_pulsewidth_us (pwmout_t * obj )
141+ {
142+ uint32_t pwm_pulsewidth = 0 ;
143+ if (pwm_clock > 0 ) {
144+ pwm_pulsewidth = (* obj -> CnV ) / pwm_clock ;
145+ }
146+ return pwm_pulsewidth ;
147+ }
148+
121149const PinMap * pwmout_pinmap ()
122150{
123151 return PinMap_PWM ;
0 commit comments