21 #DEFINE TMRSS_CLK 24e6
33 CONSTRUCTOR TimerUdt(
BYVAL T
AS Pruio_
PTR)
38 i += 1 : .DRam[i] = &h48044000uL
39 i += 1 : .DRam[i] =
IIF(.DevAct
AND PRUIO_ACT_TIM4, &h44E00088uL, 0)
41 i += 1 : .DRam[i] = &h48046000uL
42 i += 1 : .DRam[i] =
IIF(.DevAct
AND PRUIO_ACT_TIM5, &h44E000ECuL, 0)
44 i += 1 : .DRam[i] = &h48048000uL
45 i += 1 : .DRam[i] =
IIF(.DevAct
AND PRUIO_ACT_TIM6, &h44E000F0uL, 0)
47 i += 1 : .DRam[i] = &h4804A000uL
48 i += 1 : .DRam[i] =
IIF(.DevAct
AND PRUIO_ACT_TIM7, &h44E0007CuL, 0)
66 VAR p_mem = .MOffs + .DRam[InitParA] _
67 , p_raw =
CAST(
ANY PTR, .DRam) + PRUIO_DAT_TIMER
69 FOR i
AS LONG = 0
TO PRUIO_AZ_TIMER
71 p_raw +=
SIZEOF(TimerArr)
74 Conf(i) = p_mem + .DSize
79 .DeAd = 0 : .ClVa = &h30000 : p_mem += 16 : _
80 Init(i)->DeAd = 0 : Init(i)->ClAd = 0 :
CONTINUE FOR
91 p_mem +=
SIZEOF(TimerSet)
158 BYVAL Ball
AS UInt8 _
159 ,
BYVAL Dur1
AS Float_t _
160 ,
BYVAL Dur2
AS Float_t = 0. _
161 ,
BYVAL Mode
AS SHORT = 0)
AS ZSTRING PTR
163 STATIC AS CONST Float_t _
164 d_min = 1000. * &h4 / TMRSS_CLK
168 SELECT CASE AS CONST Ball
169 CASE &h24 : nr = 0 :
IF ModeCheck(Ball,2)
THEN ModeSet(Ball, &h0A)
170 CASE &h25 : nr = 3 :
IF ModeCheck(Ball,2)
THEN ModeSet(Ball, &h0A)
171 CASE &h26 : nr = 2 :
IF ModeCheck(Ball,2)
THEN ModeSet(Ball, &h0A)
172 CASE &h27 : nr = 1 :
IF ModeCheck(Ball,2)
THEN ModeSet(Ball, &h0A)
173 CASE &h5A : nr = 3 :
IF ModeCheck(Ball,5)
THEN ModeSet(Ball, &h0D)
174 CASE &h6C : nr = 0 :
IF ModeCheck(Ball,2)
THEN ModeSet(Ball, &h0A)
175 CASE &h67 :
IF ModeCheck(Ball,4)
THEN ModeSet(Ball, &h0C)
176 RETURN .PwmSS->cap_tim_set(2, Dur1, Dur2, Mode)
177 CASE &h5D :
IF ModeCheck(Ball,4)
THEN ModeSet(Ball, &h0C)
178 RETURN .PwmSS->cap_tim_set(1, Dur1, Dur2, Mode)
179 CASE &h59 :
IF ModeCheck(Ball,0)
THEN ModeSet(Ball, &h08)
180 RETURN .PwmSS->cap_tim_set(0, Dur1, Dur2, Mode)
181 CASE ELSE : .Errr = E1 :
RETURN E1
184 IF 2 <> Conf(nr)->ClVa
THEN .Errr = E0 :
RETURN E0
187 VAR dur = Dur1 + Dur2
191 CASE IS <= 0. : .TCLR =
IIF(Mode
AND &b01, TimHigh, Tim_Low)
192 CASE IS < d_min :
Top->Errr = E3 :
RETURN E3
194 VAR cnt =
CULNGINT(.001 * dur * TMRSS_CLK)
195 SELECT CASE AS CONST (cnt
SHR 32)
196 CASE 0 : .TCLR = TimMode
197 CASE 1 : .TCLR = TimMode
OR &b100000 : cnt
SHR= 1
198 CASE 2 TO 3 : .TCLR = TimMode
OR &b100100 : cnt
SHR= 2
199 CASE 4 TO 7 : .TCLR = TimMode
OR &b101000 : cnt
SHR= 3
200 CASE 8 TO 15 : .TCLR = TimMode
OR &b101100 : cnt
SHR= 4
201 CASE 16 TO 31 : .TCLR = TimMode
OR &b110000 : cnt
SHR= 5
202 CASE 32 TO 63 : .TCLR = TimMode
OR &b110100 : cnt
SHR= 6
203 CASE 64 TO 127 : .TCLR = TimMode
OR &b111000 : cnt
SHR= 7
204 CASE 128 TO 255 : .TCLR = TimMode
OR &b111100 : cnt
SHR= 8
205 CASE ELSE :
Top->Errr = E4 :
RETURN E4
207 .TLDR = &hFFFFFFFFuL - cnt
209 VAR match =
CULNG(Dur1 / dur * cnt)
211 CASE IS <= 2 : .TMAR = &hFFFFFFFEuL : .TCRR = .TMAR : .TLDR += 1
212 .TCLR
XOR= &b0110000000000
213 CASE IS > cnt - 2 : .TMAR = .TLDR + 2 : .TCRR = .TMAR + 2 : .TLDR += 1
214 .TCLR
XOR= &b1110000000000
215 CASE ELSE : .TMAR = &hFFFFFFFFuL - match : .TCRR = .TMAR + 2
218 IF Mode
AND &b01
THEN .TCLR
XOR= &b0000010000000
220 IF 0.01 >= Dur1
THEN Top->Errr = E3 :
RETURN Top->Errr
221 Raw(nr)->CMax = (Mode
AND &b111111110)
SHR 1
222 .TCLR
OR= &b100000000
227 IF .DRam[0] > PRUIO_MSG_IO_OK
THEN RETURN 0
230 .DRam[5] = Conf(nr)->TMAR
231 .DRam[4] = Conf(nr)->TLDR
232 .DRam[3] = Conf(nr)->TCRR
233 .DRam[2] = Conf(nr)->DeAd
234 .DRam[1] = Conf(nr)->TCLR
OR (PRUIO_COM_TIM_TIM
SHL 24)
258 BYVAL Ball
AS UInt8 _
259 ,
BYVAL Dur1
AS Float_t
PTR _
260 ,
BYVAL Dur2
AS Float_t
PTR)
AS ZSTRING PTR
262 IF Dur1 = 0
ORELSE Dur2 = 0
THEN Top->Errr = @
"pass pointers" :
RETURN Top->Errr
265 SELECT CASE AS CONST Ball
266 CASE &h24 : nr = 0 :
IF ModeCheck(Ball,2)
THEN RETURN E2
267 CASE &h25 : nr = 3 :
IF ModeCheck(Ball,2)
THEN RETURN E2
268 CASE &h26 : nr = 2 :
IF ModeCheck(Ball,2)
THEN RETURN E2
269 CASE &h27 : nr = 1 :
IF ModeCheck(Ball,2)
THEN RETURN E2
270 CASE &h5A : nr = 3 :
IF ModeCheck(Ball,5)
THEN RETURN E2
271 CASE &h6C : nr = 0 :
IF ModeCheck(Ball,2)
THEN RETURN E2
272 CASE &h67 :
RETURN IIF(ModeCheck(Ball,4), E2, .PwmSS->cap_tim_get(2, Dur1, Dur2))
273 CASE &h5D :
RETURN IIF(ModeCheck(Ball,4), E2, .PwmSS->cap_tim_get(1, Dur1, Dur2))
274 CASE &h59 :
RETURN IIF(ModeCheck(Ball,0), E2, .PwmSS->cap_tim_get(0, Dur1, Dur2))
275 CASE ELSE : .Errr = E1 :
RETURN E1
279 VAR dur = *Dur1 + *Dur2 _
280 , dmax = 1000. * &hFFFFFFFF00uLL / TMRSS_CLK _
281 , dmin = 1000. * 4 / TMRSS_CLK
284 IF 2 <> .ClVa
THEN Top->Errr = E0 :
RETURN E0
285 IF BIT(.TCLR, 13)
THEN Top->Errr = E2 :
RETURN E2
286 IF BIT(.TCLR, 6)
THEN
287 VAR f =
IIF(
BIT(.TCLR, 5), (1
SHL ((.TCLR
SHR 2)
AND &b111)) * 2000., 1000.)
288 *Dur1 = f * ( .TMAR - .TLDR) / TMRSS_CLK
289 *Dur2 = f * (&hFFFFFFFFuL - .TMAR) / TMRSS_CLK
298 *Dur1 = *Dur1 / dur * dmax
299 *Dur2 = *Dur2 / dur * dmax
301 VAR cnt =
CULNGINT(.001 * dur * TMRSS_CLK), n = cnt
SHR 32
302 IF n
THEN n =
LOG(n) / LOG2 : cnt = (cnt
SHR n)
SHL n
303 *Dur1 = 1000. *
CULNGINT(*Dur1 / dur * cnt) / TMRSS_CLK
304 *Dur2 = 1000. *
CULNGINT(*Dur2 / dur * cnt) / TMRSS_CLK
330 ,
BYVAL Freq
AS Float_t _
331 ,
BYVAL Duty
AS Float_t = 0.)
AS ZSTRING PTR
333 STATIC AS CONST Float_t _
334 f_min = TMRSS_CLK / &hFFFFFFFF00uLL _
335 , f_max = TMRSS_CLK / &h4
336 STATIC AS UInt32 r = 0 _
337 , cnt(...) = {0, 0, 0, 0} _
338 , cmp(...) = {0, 0, 0, 0}
341 IF 2 <> Conf(Nr)->ClVa
THEN .Errr = E0 :
RETURN E0
344 IF 0 = cnt(Nr)
THEN .Errr = .PwmSS->E1 :
RETURN .Errr
345 r = PwmMode
OR (Conf(Nr)->TCLR
AND &b111100)
347 IF Freq < f_min
ORELSE _
348 Freq > f_max
THEN .Errr = .PwmSS->E2 :
RETURN .Errr
349 VAR x =
CULNGINT(TMRSS_CLK / Freq)
350 SELECT CASE AS CONST x
SHR 32
351 CASE 0 : cnt(Nr) = x : r = PwmMode
352 CASE 1 : cnt(Nr) = x
SHR 1 : r = PwmMode
OR &b100000
353 CASE 2 TO 3 : cnt(Nr) = x
SHR 2 : r = PwmMode
OR &b100100
354 CASE 4 TO 7 : cnt(Nr) = x
SHR 3 : r = PwmMode
OR &b101000
355 CASE 8 TO 15 : cnt(Nr) = x
SHR 4 : r = PwmMode
OR &b101100
356 CASE 16 TO 31 : cnt(Nr) = x
SHR 5 : r = PwmMode
OR &b110000
357 CASE 32 TO 63 : cnt(Nr) = x
SHR 6 : r = PwmMode
OR &b110100
358 CASE 64 TO 127 : cnt(Nr) = x
SHR 7 : r = PwmMode
OR &b111000
359 CASE 128 TO 255 : cnt(Nr) = x
SHR 8 : r = PwmMode
OR &b111100
360 CASE ELSE : .Errr = .PwmSS->E2 :
RETURN .Errr
363 Conf(Nr)->TLDR = &hFFFFFFFFuL - cnt(Nr)
366 cmp(Nr) =
IIF(Duty >= 1., cnt(Nr),
CUINT(cnt(Nr) * Duty))
368 CASE IS <= 1 : r = Tim_Low
369 CASE IS >= cnt(Nr) - 1 : r = TimHigh
370 CASE ELSE : Conf(Nr)->TMAR = Conf(Nr)->TLDR + cmp(Nr) - 1
374 IF Conf(Nr)->TCLR = r
THEN
378 Conf(Nr)->TCRR = &hFFFFFFFEuL
381 IF .DRam[0] > PRUIO_MSG_IO_OK
THEN RETURN 0
384 .DRam[5] = Conf(Nr)->TCRR
385 .DRam[4] = Conf(Nr)->TMAR
386 .DRam[3] = Conf(Nr)->TLDR
387 .DRam[2] = Conf(Nr)->DeAd
388 .DRam[1] = r
OR (PRUIO_COM_TIM_PWM
SHL 24)
410 ,
BYVAL Freq
AS Float_t
PTR = 0 _
411 ,
BYVAL Duty
AS Float_t
PTR = 0)
AS ZSTRING PTR
414 IF 2 <> .ClVa
THEN Top->Errr = E0 :
RETURN E0
416 VAR cnt = &hFFFFFFFFuLL - .TLDR + 1 _
417 , pre = (.TCLR
AND &b111100)
SHR 2
419 CASE TimHigh :
IF Duty
THEN *Duty = 1.
420 CASE Tim_Low :
IF Duty
THEN *Duty = 0.
422 IF (PwmMode
AND .TCLR) <> PwmMode
THEN Top->Errr = E2 :
RETURN E2
423 IF Duty
THEN *Duty = (.TMAR -.TLDR + 1) / cnt
425 IF Freq
THEN *Freq = TMRSS_CLK / (cnt
SHL IIF(pre, (pre
AND &b111) + 1, 0))