Shop OBEX P1 Docs P2 Docs Learn Events
[resolved] Servo32v7 issue — Parallax Forums

[resolved] Servo32v7 issue

kuronekokuroneko Posts: 3,623
edited 2013-04-05 09:11 in Propeller 1
ATM I can't reach Parallax's support site so I dump this here. While I had a look at [thread=147151]this issue[/thread] it occurred to me to check the Servo32v7 object as well, just in case. Same problem.

What it boils down to is that an unsigned value is compared against another one with carry set being the exit condition (e.g. ZoneLoop in the servo object). It's fine as long as the first value is not the biggest one possible ($FFFFFFFF). This however can happen when the IOupdate loop is entered at a specific time and the hub window is aligned accordingly. In this case the object locks up (verified). I also have a feeling that the ZoneLoop may suffer from an overflow issue, e.g. temp = -30, tempcntn = -40 (no carry), tempcntn+1 = +40 (no carry). That needs to be verified.

Comments

  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2013-04-02 23:43
    "In this case the object locks up (verified)" - can you please provide a code example of this?

    Thank you

    -Beau Schwabe
  • kuronekokuroneko Posts: 3,623
    edited 2013-04-03 00:14
    I didn't go through the trouble of going back as far as cognew. The critical point is that the rdlong comes out at a specific time (enforced by waitcnt below). For the shown setup the reset is never executed (ZoneLoop never exits).
    IOupdate                rdlong  dira,                   PinDirectionAddress     'Get and set I/O pin directions
    
    '        15 insn until cnt sample ---------+   +------- adjust for waitcnt match vs cnt sample
    '                       target -1 ----+    |   |    +-- counter adjustment
    '                                     |    |   |    |
                            [COLOR="#FF0000"]neg     cnt, #1 + 60 + 1 + 260
                            sub     cnt, _ZoneClocks
                            waitcnt cnt, #0                                         'simulate rdlong exit time[/COLOR]
                            
    '--------------------------------------------------------------------------------------------------------------------
    Zone1                   mov     ZoneIndex,              Zone1Index              'Set Index Pointer for Zone1
                            call    #ResetZone
                            call    #ZoneCore
    
                            [COLOR="#FF0000"]hubop   $, #128[/COLOR]
    
    The chances of this happening are rather slim (sampling cnt after rdlong would have to be odd, i.e. $FFF9E443, then you need the right cog which has the proper alignment re: hub window, i.e. $xxxxxxxA etc).

    Note that I picked this error case because it was the easiest one to generate. There are 3 more zones to deal with which have their own reference points.
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2013-04-03 20:24
    kuroneko,

    There is already provision in the code to account for this cnt rollover "glitch"... Is the NoGlitch value being set correctly in your code?
    '---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    CON
    ...
    NoGlitchWindow = 3_000                                                      '3mS Glitch prevention window (set value larger than maximum servo width of 2.5mS)
    ...
    '---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    VAR
    ...
            long          ZoneClocks
            long          NoGlitch
    ...
    '---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    PUB Start
    ...
    NoGlitch   := $FFFF_FFFF-(clkfreq / _1uS * NoGlitchWindow)                  'calculate # of clocks for GlitchFree servos. Problem occurs when 'cnt' value rollover is less than the servo's pulse width.
    cognew(@ServoStart,@ZoneClocks)
    ...
    '---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    
  • kuronekokuroneko Posts: 3,623
    edited 2013-04-03 20:37
    NoGlitchWindow is set to 3000 and _ZonePeriod to 5000 (OBEX/PropTool release) which means that SyncPoint can be well below _NoGlitch (in ZoneSync) but still reach critical values. I'd say that the final value for temp should be around -81 so that ZoneLoop has a chance to exit the loop (80 cycle granularity). You can figure out _ZonePeriod from there.
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2013-04-03 20:53
    So would setting the value of NoGlitchWindow to 5000 solve the problem?
  • kuronekokuroneko Posts: 3,623
    edited 2013-04-03 21:06
    So would setting the value of NoGlitchWindow to 5000 solve the problem?
    No, this just means that SyncPoint could be equal _NoGlitch to escape realignment, adding _ZoneClocks (and 260 for some odd reason) would still allow it to do damage. Ignoring the 260 for now, -(81 + _ZoneClocks) would be an acceptable value for SyncPoint and therefore _NoGlitch. So using ZonePeriod = 5000 (400k cycles) would require NoGlitchWindow to be at least 5001.

    Wouldn't it be easier to apply some limits in code instead of picking odd looking values in the constant section?
  • kuronekokuroneko Posts: 3,623
    edited 2013-04-04 05:16
    That said, what about doing it entirely without relying on cnt, something like this maybe (with adjustments to hide updates etc):
    CON
      ZWidth = 64
    
    DAT
    
    ' ServoWidth# in {40000..200000} @80MHz
    '
                    long    6250                    ' 6250*64 = 400k (5ms)
                    mov     zcnt, $-1
    
    ZoneLoop        cmpsub  ServoWidth1, #ZWidth wc
                    muxc    ServoByte, ZoneShift1
                    cmpsub  ServoWidth2, #ZWidth wc
                    muxc    ServoByte, ZoneShift2
                    cmpsub  ServoWidth3, #ZWidth wc
                    muxc    ServoByte, ZoneShift3
                    cmpsub  ServoWidth4, #ZWidth wc
                    muxc    ServoByte, ZoneShift4
                    cmpsub  ServoWidth5, #ZWidth wc
                    muxc    ServoByte, ZoneShift5
                    cmpsub  ServoWidth6, #ZWidth wc
                    muxc    ServoByte, ZoneShift6
                    cmpsub  ServoWidth7, #ZWidth wc
                    muxc    ServoByte, ZoneShift7
                    mov     outa, ServoByte
                    djnz    zcnt, #ZoneLoop
    
    Another way to stay away from the overflow issue is to use a LOGIC always counter which is compared against all ServoWidth# values. Basically a local _ZoneClocks window far away from any troublesome overflow.
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2013-04-05 08:53
    Here is an update to the 'Servo32' program that eliminates the need to even set a a 'NoGlitch' variable.

    https://drive.google.com/folderview?id=0B0DJmXrvrE-IemxSdktUTmZHd2s&usp=sharing

    History:
    Version 1 - initial concept

    Version 2 - (03-08-2006) Beta release

    Version 3 - (11-04-2007) Improved servo resolution to 1uS

    Version 4 - (05-03-2009) Ability to disable a servo channel
    and remove channel preset requirement

    Version 5 - (05-08-2009) Added ramping ability

    Version 6 - (07-18-2009) Fixed slight timing skew in ZoneLoop and
    fixed overhead timing latency in ZoneCore

    Version 7 - (08-18-2009) Fixed servo jitter in ramping function when
    servo reached it's target position

    Version 8 - (12-20-2010) Added PUB method to retrieve servo position

    Version 9 - (04-05-2013) cnt rollover issue corrected with ZonePeriod
    by setting up Counter A and using the Phase
    accumulator instead of the cnt

    Note: This also eliminates the need to setup
    a 'NoGlitch' variable
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-04-05 09:06
    Beau, could you attach the new version to a post here?

    I'm getting an error message from the Google link.

    Thanks for fixing this. I use Servo32 in a lot of my projects.

    @kuroneko, Thanks for catching this error.
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2013-04-05 09:10
    The file is attached to this thread:

    http://forums.parallax.com/showthread.php/147219-CODE-UPDATE-Servo32v9?p=1175076#post1175076

    BTW) Google link in post #9 above fixed
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-04-05 09:11
    The file is attached to this thread:

    Thank you.
Sign In or Register to comment.