@@ -110,9 +110,27 @@ uint32_t analogRead(uint32_t ulPin)
110110 return ulValue ;
111111}
112112
113+ static void TC_SetRA (Tc * tc , uint32_t chan , uint32_t v )
114+ {
115+ TcChannel * ch = tc -> TC_CHANNEL + chan ;
116+ ch -> TC_RA = v ;
117+ }
118+
119+ static void TC_SetRB (Tc * tc , uint32_t chan , uint32_t v )
120+ {
121+ TcChannel * ch = & tc -> TC_CHANNEL + chan ;
122+ ch -> TC_RB = v ;
123+ }
124+
125+ static void TC_SetRC (Tc * tc , uint32_t chan , uint32_t v )
126+ {
127+ TcChannel * ch = & tc -> TC_CHANNEL + chan ;
128+ ch -> TC_RC = v ;
129+ }
130+
113131static uint8_t PWMEnabled = 0 ;
114- static uint8_t TCEnabled = 0 ;
115132static uint8_t pinEnabled [PINS_COUNT ];
133+ static uint8_t TCChanEnabled [] = {0 , 0 , 0 };
116134
117135void analogOutputInit () {
118136 uint8_t i ;
@@ -130,7 +148,7 @@ void analogWrite(uint32_t ulPin, uint32_t ulValue) {
130148 if ((attr & PIN_ATTR_PWM ) == PIN_ATTR_PWM ) {
131149 if (!PWMEnabled ) {
132150 // PWM Startup code
133- PMC_EnablePeripheral (ID_PWM );
151+ PMC_EnablePeripheral (PWM_INTERFACE_ID );
134152 PWMC_ConfigureClocks (PWM_FREQUENCY * PWM_MAX_DUTY_CYCLE , 0 , VARIANT_MCK );
135153 PWMEnabled = 1 ;
136154 }
@@ -147,25 +165,57 @@ void analogWrite(uint32_t ulPin, uint32_t ulValue) {
147165 PWMC_SetDutyCycle (PWM_INTERFACE , chan , ulValue );
148166 PWMC_EnableChannel (PWM_INTERFACE , chan );
149167 pinEnabled [ulPin ] = 1 ;
150- } else {
151- PWMC_SetDutyCycle (PWM_INTERFACE , chan , ulValue );
152168 }
169+
170+ PWMC_SetDutyCycle (PWM_INTERFACE , chan , ulValue );
153171 return ;
154172 }
155173
156174 if ((attr & PIN_ATTR_TIMER ) == PIN_ATTR_TIMER ) {
157- // TODO
158- /*
159- if (!TCEnabled) {
160- TCEnabled = 1;
161- }
175+ // We use MCLK/2 => 96Mhz/2 => 48Mhz as clock.
176+ // To get 1KHz we should use 48000 as TC
177+ // 48Mhz/48000 = 1KHz
178+ const uint32_t TC = VARIANT_MCK / 2 / TC_FREQUENCY ;
179+
180+ // Map value to Timer ranges 0..255=>0..48000
181+ ulValue = ulValue * TC ;
182+ ulValue = ulValue / TC_MAX_DUTY_CYCLE ;
162183
163184 // Setup Timer for this pin
185+ ETCChannel channel = g_APinDescription [ulPin ].ulTCChannel ;
186+ static const channelToChNo [] = { 0 , 0 , 1 , 1 , 2 , 2 };
187+ static const channelToAB [] = { 1 , 0 , 1 , 0 , 1 , 0 };
188+ uint32_t chNo = channelToChNo [channel ];
189+ uint32_t chA = channelToAB [channel ];
190+
191+ if (!TCChanEnabled [chNo ]) {
192+ PMC_EnablePeripheral (TC_INTERFACE_ID + chNo );
193+ TC_Configure (TC_INTERFACE , chNo ,
194+ TC_CMR_TCCLKS_TIMER_CLOCK1 |
195+ TC_CMR_WAVE |
196+ TC_CMR_WAVSEL_UP_RC |
197+ TC_CMR_ACPA_CLEAR | // RA Compare Effect on OA: clear
198+ TC_CMR_ACPC_SET | // RC Compare Effect on OA: set
199+ TC_CMR_BCPB_CLEAR | // RB Compare Effect on OB: clear
200+ TC_CMR_BCPC_SET ); // RC Compare Effect on OB: set
201+ TC_SetRC (TC_INTERFACE , chNo , TC );
202+ }
203+ if (chA )
204+ TC_SetRA (TC_INTERFACE , chNo , ulValue );
205+ else
206+ TC_SetRB (TC_INTERFACE , chNo , ulValue );
164207 if (!pinEnabled [ulPin ]) {
165- } else {
208+ PIO_Configure (g_APinDescription [ulPin ].pPort ,
209+ g_APinDescription [ulPin ].ulPinType ,
210+ g_APinDescription [ulPin ].ulPin ,
211+ g_APinDescription [ulPin ].ulPinConfiguration );
212+ pinEnabled [ulPin ] = 1 ;
213+ }
214+ if (!TCChanEnabled [chNo ]) {
215+ TC_Start (TC_INTERFACE , chNo );
216+ TCChanEnabled [chNo ] = 1 ;
166217 }
167218 return ;
168- */
169219 }
170220
171221 // Default to digital write
0 commit comments