Shop OBEX P1 Docs P2 Docs Learn Events
Help with Potatotext12 on non-standard hardware — Parallax Forums

Help with Potatotext12 on non-standard hardware

nyjenyje Posts: 35
edited 2010-11-29 12:47 in Propeller 1
Hi guys,
Have been banging my head off this one for two days now, I wonder if anyone can help...
Am trying to run potatotext on my home brew propeller card, which has non standard everything compared to the common prop boards. With most code, a quick fiddle with the _clkfreq & _clkmode and of course the pinouts and I'm golden, but potatotext uses coley's hardware detect routine, and I can't seem to reverse engineer it from the comments.

My question:
What values of these :
clkset( )
ivcfg :=
ifrqa :=
idira :=

do i need to plug in to the code in place of the hwdetect 'case' selector for my card? The specs of my board are:

xtal 6.25Mhz with pll16x (ie 100_000_000 Mhz)
video pins (standard pin order) 16,17,18,19

Thanks in advance for any help,
Nige.

Comments

  • jazzedjazzed Posts: 11,803
    edited 2010-11-28 22:06
    nyje wrote: »
    Hi guys,
    Have been banging my head off this one for two days now, I wonder if anyone can help...
    Am trying to run potatotext on my home brew propeller card, which has non standard everything compared to the common prop boards. With most code, a quick fiddle with the _clkfreq & _clkmode and of course the pinouts and I'm golden, but potatotext uses coley's hardware detect routine, and I can't seem to reverse engineer it from the comments.

    My question:
    What values of these :
    clkset( )
    ivcfg :=
    ifrqa :=
    idira :=

    do i need to plug in to the code in place of the hwdetect 'case' selector for my card? The specs of my board are:

    xtal 6.25Mhz with pll16x (ie 100_000_000 Mhz)
    video pins (standard pin order) 16,17,18,19

    Thanks in advance for any help,
    Nige.

    You're not the only one who has trouble with this. If you just buy one of the 3 supported products it would be easy and Coley, etal would be happy :)

    Don't worry about clkset(...) remove it. Just use _xinfreq = 6_250_000 and _clkmode = xtal1 + pll16x. idira should be $70000.

    I think ivcfg should be %0_10_1_0_1_000_00000000000_010_0_00000111.

    I have no idea what ifrqa should be, but I bet it's very close to $1317_45D1 (96MHz). I can't figure out how the values are derived. Maybe someone else can help with that.
  • potatoheadpotatohead Posts: 10,261
    edited 2010-11-28 22:49
    The calculation for that is in the comments:

    (7,159,090.9Hz/96MHz)<<32

    That can be input into SPIN directly, by expanding 96 MHZ

    The value for 100Mhz is = $1253C824 or $1253C820 with the lower order "1" removed.

    Or you can compute it on your calculator. I used the windows one. You may also consider rounding off the first few ones, to reduce PLL jitter. The lower 4 bits at least, are safe to do. Some frequency / clock combinations are nice, in that they have few ones to begin with. Others... not so nice, meaning you might have to compromise a little.

    That value is the number accumulated to PLLA so that it operates at the frequency given. In the Parallax driver, there is some math in PASM that also does this, but I was unable to make it work. That's a project for another day. (math in general)

    Also, I think that's a older version of the driver. Version 1.1 is in the OBEX.

    http://obex.parallax.com/objects/550/
  • nyjenyje Posts: 35
    edited 2010-11-29 03:12
    Guys 1000x thanks for the help ;-) Normally I have no probs getting stuff to run on my board, just didn't grok what was going on - all seemed like low level pasm magic to me ;-)

    @potatohead Thanks first of all for the driver, and I checked this out of the obex#550 which confusingly says 1.1 in the description and 1.2 in the version (to the right)

    Will try this as soon as I get home from work ;-)

    any chance of an explanation of where 7,159,090.9Hz comes from, as this is why I didn't realize that the comment was the calculation...
  • ericballericball Posts: 774
    edited 2010-11-29 04:23
    nyje wrote: »
    any chance of an explanation of where 7,159,090.9Hz comes from, as this is why I didn't realize that the comment was the calculation...

    7,159,090.9Hz is 2x the NTSC colorburst frequency. For composite video the color difference signals are quadrature modulated at the colorburst frequency. The counter PLL in the Propeller has an input frequency range of 4-8MHz, so twice the colorburst frequency is used. 16x the colorburst frequnecy is fed into the video generator so it can create 16 colors via phase shifter.
  • nyjenyje Posts: 35
    edited 2010-11-29 06:34
    @ericball thankyou kindly sir, i feel the veil of ignorance of the magic of prop video lifting ;-)

    On a similar note is ayone aware of an 80 column PAL tv driver except for pullmoll's tv80? (which i am fiddling with also). I understand from various other threads that monochrome PAL may give better results for this kind of display.
  • jazzedjazzed Posts: 11,803
    edited 2010-11-29 07:27
    potatohead wrote: »
    The calculation for that is in the comments:

    (7,159,090.9Hz/96MHz)<<32

    That can be input into SPIN directly, by expanding 96 MHZ
    That does not work in SPIN. Please write a CON expression that works.
  • potatoheadpotatohead Posts: 10,261
    edited 2010-11-29 09:23
    Well that really sucks. I thought I had done that at one point. The division dies to 0 though, so I clearly haven't.

    A CON directive would be something like:

    fvalue = 7_159_090.9/96_000_000 * 32
    real_value = int(value)

    But, I would much rather solve the problem in PASM math. I tried this, and didn't get all that far. Anyone have a idea on how do do a computation like that in PASM? Maybe express the above differently first?

    If some effort has to go that direction, that's where I would like to see it go. That way, a driver can be binary packaged, without needing the SPIN wrapper. Could be applied to older code too. That particular computation for the counters could eliminate the need for constants on lots of things, getting a lot closer to just working on a lot of setups.

    ??
  • Ding-BattyDing-Batty Posts: 302
    edited 2010-11-29 12:18
    Well, I don't have my Propeller board with me (nor the development environment), so I can't give you the PASM code to do it, but here is how I looked at the problem:

    We want X := 7_159_090.9 / CLKFRQ << 32

    First, get rid of that pesky decimal: X := 71_590_909 / (CLKFRQ * 10) << 32

    That's just dividing a 64-bit number (71_590_909 * 2^32) by a 32-bit number (CLKFRQ * 10). And since all the low-order 32-bits are zero, we can just store the high-order bits.

    So I wrote "pseudo-code" in Perl, that does in fact match the calculations (also attached). It should be very easy to translate this into PASM -- all the primitive operations in the calculation map directly to PASM instructions.
    # calculate 7_159_090.9 / CLKFRQ << 32
    #
    # This is the same as:
    #
    #    ((7_159_090.9 * 10) * 2^32) / (CLKFRQ * 10)
    #
    # So we calculate the quotient of dividing a 32=bit number into a 64-bit number.
    #
    # (71_590_909 * 2^32) / (CLKFRQ * 10)
    #
    # Since the low-order 32 bits of the 64-bit value are zero, we don't really have
    # to store them -- we just shift zeros in during the subtraction loop.
    
    use strict;
    use warnings;
    
    # We can't "use integer;" here because 0x8000_0000 >> 1 does not become 0x4000_0000,
    # it becomes "0xC000_0000 (it preserves the sign of the result).
    # But in assembly language we can control that.
    #use integer;
    
    sub DoCalc($)
    {
        my $CLKFRQ = shift;
    
        my $dividend = 71_590_909 << 1; # the "<< 1" adjusts for the first bit,
                                        # because we assume that $dividend < $divisor
                                        # this is (7_159_090.9 * 10) << 1
        my $divisor  = $CLKFRQ * 10;
    
        my $quotient = 0;
        my $bit      = 0x8000_0000;     # because we assume that $dividend < $divisor,
                                        # see above.
    
        while ( $bit != 0 )
        {
            if ( $dividend >= $divisor )
            {
                $dividend -= $divisor;
                $quotient |= $bit;
            }
            $bit      >>= 1;
            $dividend <<= 1;
        }
    
        return $quotient;
    }
    
    # Test program:
    
    my $CLK = 100_000_000;
    my $num = DoCalc( $CLK );
    printf "For clock freq \%9u computed: 0x\%.8X\n",
           $CLK, $num;
    
    $CLK =  96_000_000;
    $num = DoCalc( $CLK );
    printf "For clock freq \%9u computed: 0x\%.8X\n",
           $CLK, $num;
    
    exit 0;
    
    The output:
    C:\src\propeller>perl t.pl
    For clock freq 100000000 computed: 0x1253C824
    For clock freq  96000000 computed: 0x131745D1
    

    BTW, I don't think you can write a CON expression that will do the right thing, and get all the bits right.
  • jazzedjazzed Posts: 11,803
    edited 2010-11-29 12:19
    potatohead wrote: »
    Well that really sucks. I thought I had done that at one point. The division dies to 0 though, so I clearly haven't.

    A CON directive would be something like:

    fvalue = 7_159_090.9/96_000_000 * 32
    real_value = int(value)

    This is very close for a range of values and actually works on my dinky DVD LCD TV:
    CON
      sysclock = _xinfreq*16
      ntsc  = 7_159_090_9
      ntscm = 268_435_456/(sysclock/1000)
      ifrqa = (ntsc/10000*ntscm)<<4
    
    More accurate values would be better of course.
  • nyjenyje Posts: 35
    edited 2010-11-29 12:47
    Btw, It works - rock solid and crystal clear - Thank you all again ;-)
Sign In or Register to comment.