Shop OBEX P1 Docs P2 Docs Learn Events
Pass 6 digit ascII from spin obj to asm ? — Parallax Forums

Pass 6 digit ascII from spin obj to asm ?

tonyp12tonyp12 Posts: 1,951
edited 2011-03-14 08:48 in Propeller 1
I have never wrote any code in spin yet, I'm pretty good at pasm.

I understand when you start a new cog, you can pass one value that is an single address in hub ram.

PUB LedDisplay (text)
cognew(@asm_entry, text) 'launch assembly program in a COG

And to access it you would use something like rdlong mytext,par

You could only squeeze in four bytes (letters) in an long.
So the par would instead need to point to the first hub address of a 6 bytes/longs table?

And how do you use LedDisplay("HELLO9") to be broken up in 6 bytes/longs in spin?
not using "H","E"... as it need to support to.string(value) for temprature etc

Later it should also support a dot and then have 7 letters as a dot does not use up a digit.

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-03-11 09:28
    I'm wondering if you'd be better off treating this as a serial driver. Use a head and tail pointer and read the bytes in from a buffer.

    Lately I've been spending a lot of time with Tim Moore's four port serial driver. I've modified it to increase the buffers size, to set end of message flags and detect wireless tx acknowledgments.

    I'm hoping of using the same starting point (Tim's driver) but make one the serial ports drive the LED display. The display wouldn't need to run faster than 80 bps and wouldn't require checking for any rx signal. It would probably end up slowing the serial driver but most of my serial devices aren't very fast.

    I'm not sure if this is possible (especially for me) but it would be nice if the LED driver didn't take up a whole cog. I think it would be great if the cog could also drive a few serial lines.
  • tonyp12tonyp12 Posts: 1,951
    edited 2011-03-11 09:35
    It's recommended to dedicate a cog due to the multiplexing.
    The led driver needs to move on the next digit on a regulary time interval and do so at least 200 times/sec.

    But if you look at driver v0.6 you see a 4000 cycle delay (will use waitcnt later)
    so you could squeeze in your program there and not waste a cog.
    as long you don't use waitpne etc that wait for long periods.

    And I may even write a driver made in spin,
    so you could squeeze in your spin code and not waste a cog.

    But now back the original question.
  • tonyp12tonyp12 Posts: 1,951
    edited 2011-03-11 14:54
    I'm getting close, I added a @ in front of text

    PUB Display (text)
    cognew(@asm_entry, @text) 'launch assembly program in a COG
    added these lines of code

    mov buffer,par
    rdlong mytext,buffer

    created a new spin program
    OBJ
    LED : "LED17"
    PUB DisplayText
    LED.Display("W")

    And it will change the first letter H to W.
    But how do I change the spin program so it will accept 6 numbers inside LED.Display(1,2,3,4,5,6)?
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-03-11 15:27
    instead of
    LED.Display("W")

    I think you'll want
    LED.Display(@textBuffer)
     
    DAT
    textBuffer  byte "World1", 0  ' add a zero in case you want to treat it as a string.
    

    I think you'd be better off using bytes instead of longs. You could read one byte in at a time and place it in the appropriate place inside the cog.
    I'd add an incrementing pointers "t1" and "t2".

    EDIT: I think I did this wrong. I'm fixing it now. Fixed, I think. I needed the movd instructions. It's harder to use pointers in PASM.
                      mov buffer,par
                      mov t1, buffer
                      mov t2, #mytext
     
                      movd  modify1, t2
                      rdbyte t3,t1
    modify1       mov 0-0, t3
                      add t1, #1
                      add t2, #1
                      movd  modify2, t2
                      rdbyte t3,t1
    modify2       mov 0-0, t3
                      add t1, #1
                      add t2, #1
                      movd  modify3, t2
                      rdbyte t3,t1
    modify3       mov 0-0, t3
                      add t1, #1
                      add t2, #1
                      movd  modify4, t2
                      rdbyte t3,t1
    modify4       mov 0-0, t3
                      add t1, #1
                      add t2, #1
                      movd  modify5, t2
                      rdbyte t3,t1
    modify6       mov 0-0, t3
                      add t1, #1
                      add t2, #1
                      movd  modify7, t2
                      rdbyte t3,t1
    modify7       mov 0-0, t3
    
    I think that would get the six characters into the cog.
    I think it would work if you left mytext as longs. I'm not sure how to deal with bytes vs longs within the cog.
    In hub RAM you increment by one for each byte and by four for each long. Inside a cog you increment longs by one. I'm not sure how one increments by bytes inside the cog.

    Edit: I think I've fixed it.
  • tonyp12tonyp12 Posts: 1,951
    edited 2011-03-11 15:43
    I got it working what I think in a dirty way, as I added tx2, tx3 etc,
    {{
    ***************************************
    *    LED17Demo, needs LED17.spin      *
    ***************************************
     }}
    OBJ
      LED    : "LED17"
    
    PUB DisplayText 
        
        LED.Display("W","O","R","K","I","T")
      
    DAT
    {{
    }}
    
    {{
    *****************************************
    * LED driver v0.7                       *
    * Author: Tony Philipsson               *
    * Copyright 2011 Electrons Engineering  *
    *****************************************
    }}
    CON
        CLK = 4                     'pin for clock   (P2)
        LAT = 2                     'pin for latc    (P1)
        SER = 1                     'pin for serial  (P0)
     
        A1= %1<<19                  'LED Segments
        A2= %1<<20
        B=  %1<<21
        C=  %1<<22
        D1= %1<<23
        D2= %1<<10
        E=  %1<<11
        F=  %1<<12
        G1= %1<<6
        G2= %1<<2
        H=  %1<<13
        I=  %1<<14
        J=  %1<<15
        K=  %1<<3
        L=  %1<<4
        M=  %1<<5
        DP= %1<<7
    
    PUB Display (text,tx2,tx3,tx4,tx5,tx6)
        cognew(@asm_entry, @text)   'launch assembly program in a COG    
    
    DAT
                  org
    
    asm_entry     mov       dira,#7                         'make pin 0, 1, 2 pin an output
                  mov       outa,#0                         'set all pins to off
    main          mov       digit,#6                        'we have 6 digits to multiplex
                  mov       buffer,par                      'reset buffer (par=hub address of first letter)
                  movs      sinkpnt,#sink                   'reset transistor sink table
    loop1         rdlong    mytext,buffer                   'get ascII char from hub ram.
                  movs      fontpnt,#font                   'reset font pointer
                  add       fontpnt,mytext                  'add ascii code that mytext have, to font pointer
                  sub       fontpnt,#48                     'subtract as our ascii table start at char(48)
                  nop                                       'needed as above code mod code below
    fontpnt       mov       serial,0-0                      'start a new serial data 
    sinkpnt       add       serial,0-0                      'fuse in the transistor sink bit.        
                  mov       bit_test,#1                     'reset bit mask       
                  shl       bit_test,#24                    'we have 24 bits to shift out
    
    loop2         test      serial,bit_test wz              'test serial data bitwize
                  muxnz     outa,#SER                       'answer in z, use it to set Serial pin
                  or        outa,#CLK                       'turn pin on  (clock) 
                  andn      outa,#CLK                       'turn pin off (clock)
                  sar       bit_test,#1 wz                  'shift right
            if_nz jmp       #loop2                          'if not zero, jmp 
                  or        outa,#LAT                       'turn pin on  (latch) 
                  andn      outa,#LAT                       'turn pin off (latch)
    
                  mov       delay, #500                     'delay cycles
                  shl       delay, #3                       'make it a 8 times bigger value(use #10 for slowmotion)
    loop3         djnz      delay,#loop3                    'a slight delay could not hurt before next digit.
                 
                  
                  add       sinkpnt,#1                      'next digit
                  add       buffer,#4                       'next text char
                  djnz      digit, #loop1                   'have we done 6 digits?
                  
                  jmp       #main                           'restart
    
    font          long      A1+A2+B+C+D1+D2+E+F+J+M         '0
                  long      B+C                             '1
                  long      A1+A2+B+D1+D2+E+G1+G2           '2
                  long      A1+A2+B+C+D1+D2+G2              '3
                  long      B+C+F+G1+G2                     '4
                  long      A1+A2+D1+D2+F+G1+K              '5
                  long      A1+A2+C+D1+D2+E+F+G1+G2         '6
                  long      A1+A2+B+C                       '7
                  long      A1+A2+B+C+D1+D2+E+F+G1+G2       '8
                  long      A1+A2+B+C+D1+D2+F+G1+G2         '9
                  long      0,0,0,0,0,0,0                   'unused
                  long      A1+A2+B+C+E+F+G1+G2             'A
                  long      A1+A2+B+C+D1+D2+G2+I+L          'B
                  long      A1+A2+D1+D2+E+F                 'C
                  long      A1+A2+B+C+D1+D2+I+L             'D
                  long      A1+A2+D1+D2+E+F+G1+G2           'E
                  long      A1+A2+E+F+G1                    'F
                  long      A1+A2+C+D1+D2+E+F+G2            'G
                  long      B+C+E+F+G1+G2                   'H
                  long      I+L                             'I
                  long      B+C+D1+D2+E                     'J
                  long      E+F+G1+J+K                      'K
                  long      D1+D2+E+F                       'L
                  long      B+C+E+F+H+J                     'M
                  long      B+C+E+F+H+K                     'N
                  long      A1+A2+B+C+D1+D2+E+F             'O
                  long      A1+A2+B+E+F+G1+G2               'P
                  long      A1+A2+B+C+D1+D2+E+F+K           'Q
                  long      A1+A2+B+E+F+G1+G2+K             'R
                  long      A1+A2+C+D1+D2+F+G1+G2           'S
                  long      A1+A2+I+L                       'T
                  long      B+C+D1+D2+E+F                   'U
                  long      E+F+J+M                         'V
                  long      B+C+E+F+K+M                     'W
                  long      H+J+K+M                         'X
                  long      H+J+L                           'Y
                  long      A1+A2+D1+D2+J+M                 'Z
    sink          long      %10,%01,%10<<8,%01<<8,%10<<16,%01<<16     'what transistor to sink.
    mytext        res       1
    buffer        res       1
    bit_test      res       1
    serial        res       1
    digit         res       1                               
    delay         res       1                             
    

    I tried this flashing text, but it's gets garbled when it tries to update to LUCKY7

    Repeat
    LED.Display("W","O","R","K","I","T")
    waitcnt(15000000+cnt)
    LED.Display("L","U","C","K","Y","7")
    waitcnt(15000000+cnt)
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-03-11 16:03
    I'm relatively new to PASM so maybe it's not so unusual but I haven't seen this trick before:

    add sinkpnt,#1 'next digit

    I'm guessing it's the same as incrementing the source by one. Interesting.

    I suppose one could add an appropriate number to increment the destination field as well. This self modifying code stuff is a trip.
  • tonyp12tonyp12 Posts: 1,951
    edited 2011-03-11 16:24
    there is no subd or addd but this should work,
    if you add %1000000000 to it and that would be the same as +1 without effecting the sourcefield.

    lable mov 0-0,#255
    add lable,destfield

    destfield long %1<<9 'declaring needed as highest number inline is 511
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-03-11 16:34
    Are you stopping the old cog before you launch a new one?

    I think the driver should read the characters in from the hub in a similar way to many of the serial drivers.
  • tonyp12tonyp12 Posts: 1,951
    edited 2011-03-11 16:51
    That is probaly what happens, it's driving me crazy.
    So every time I use LED.Display in the spin cog it starts a new cog.
    This works:
    OBJ
      LED    : "LED17"
    
    PUB DisplayText 
    
       Repeat
          LED.Display("W","O","R","K","I","T")
          waitcnt(15000000+cnt)
          cogstop(1)
                LED.Display("L","U","C","K","Y","7")
          waitcnt(15000000+cnt)
          cogstop(1)
    

    But how do I create a spin method of updating the text on the fly?
    I guess I need to create seperate LED.Start and LED.Display
  • max72max72 Posts: 1,155
    edited 2011-03-12 01:42
    Check the "coprocessor" style objects, like float in the obex.
    In the PASM COG you simply loop checking a memory address, and if it changes you jump to a dedicated code.
    Moreover, consider a string as an array. You pass the address of the first char. If you had an array (say array[10]) you would pass to the COG the address of the array as @array[0]. Then you iteratively add 1, 2 or 4 (byte, word, long) to have the address of the next one.
    With a string you pass the string address, so part of the job is done.
    With a formatted string the last byte is 0, so you can check for it for ending the routine.

    Massimo
  • tonyp12tonyp12 Posts: 1,951
    edited 2011-03-14 08:48
    I endeded up using bytemove, it's that the best way?
    {{
    ***************************************
    *    LED17Demo, needs LED17.spin      *
    ***************************************
     }}
    OBJ
      LED    : "LED17"
    
    PUB DisplayText 
    
        
    LED.Display(@textBuffer)
    repeat
     waitcnt($FF0000+cnt)
     bytemove(@textBuffer,@text1,7)
     waitcnt($FF0000+cnt)
     bytemove(@textBuffer,@text2,7)
     
    DAT
    textBuffer  byte "1 1 1 ",0  ' added a zero to treat it as a string.
    text1 byte "OH MY",0
    text2 byte "WORKIT",0
    
    needs LED17.spin (version 0.72 or higher.) attached to this post.
    Supports zero terminated text of any lenght and also space char.
Sign In or Register to comment.