Shop OBEX P1 Docs P2 Docs Learn Events
ASM wont work...Help Please !! — Parallax Forums

ASM wont work...Help Please !!

BTXBTX Posts: 674
edited 2006-12-29 00:58 in Propeller 1
Hi all !!
I've just beggining trying to understand assembly code, and I try with this.
Talking some PWM examples from Counters doccument, I want to·dimmer two differents LED at· different pins, I just write this simple spin code trying to use two cogs one for each LED, like still I can't see..how to pass different pins from spin to asm code,·I duplicate twice the PWM code with differents pin assigment, but this wont work !!.
First question is : ...what is the concept ? that I'm not seeing ? If I'm starting only two cogs with different pins ...why it seems to be that the first call to PWM1.go never returns..·and let start the PWM2 object ??
Second question is :· The parameter address is the only way to pass data from spin to asm started cog ?, I'd try to understand FullDuplex Serial object...where you must pass some·variables (like rxpin, txpin, mode, etc), and I can't, these variables appears "for me" like from the "sky" in the cog. (making· "understood" some calculations with PAR register...)
In this PWM example @parameter address, is passed to the cog, and then taken by vallue variable...but·it is only one...how to pass two variables ?

This is the code that I'm talking.
Thanks in advance for your time !!
CON _clkmode = xtal1 + pll16x
    _xinfreq = 5_000_000
OBJ
   R : "PWM1"
   B : "PWM2"
  
PUB Vamos
   R.go
   B.go
      
repeat      

VAR long parameter
PUB go | x
  cognew(@entry, @parameter)
  repeat
    repeat x from 0 to period          'linearly advance parameter from 0 to 100
      parameter := x                   'a constant here locks to value x percent high
      waitcnt(1_000_000 + cnt)         'wait a little while before next update
DAT
        org
entry   mov dira, diraval              'set APIN to output
        mov ctra, ctraval              'establish counter A mode and APIN
        mov frqa, #1                   'set counter to increment 1 each cycle
        mov time, cnt                  'record current time
        add time, period               'establish next period
:loop   rdlong value, par              'get an up to date pulse width
        waitcnt time, period           'wait until next period
        neg phsa, value                'back up phsa so that it
        jmp #:loop                     'loop for next cycle
diraval long |< 6                      'APIN=6
ctraval long %00100 << 26 + 6          'NCO/PWM APIN=6
period  long 100                       '800kHz (1.25µS period) (_clkfreq / period)                      
time    res 1
value   res 1


VAR long parameter
PUB go | x
  cognew(@entry, @parameter)
  repeat
    repeat x from 0 to period          'linearly advance parameter from 0 to 100
      parameter := x                   'a constant here locks to value x percent high
      waitcnt(1_000_000 + cnt)         'wait a little while before next update
DAT
        org
entry   mov dira, diraval              'set APIN to output
        mov ctra, ctraval              'establish counter A mode and APIN
        mov frqa, #1                   'set counter to increment 1 each cycle
        mov time, cnt                  'record current time
        add time, period               'establish next period
:loop   rdlong value, par              'get an up to date pulse width
        waitcnt time, period           'wait until next period
        neg phsa, value                'back up phsa so that it
        jmp #:loop                     'loop for next cycle
diraval long |< 5                      'APIN=5
ctraval long %00100 << 26 + 5          'NCO/PWM APIN=5
period  long 100                       '800kHz (1.25µS period) (_clkfreq / period)                      
time    res 1
value   res 1


Regards
Alberto.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

Comments

  • CJCJ Posts: 470
    edited 2006-12-26 16:17
    try using cognew on the first go call, your code as it is now, the main cog gets into the infinite loop in the go method and never gets to the second go call

    you will also need some stack space set aside for it

    cognew(R.go, @stack_array)

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Who says you have to have knowledge to use it?

    I've killed a fly with my bare mind.
  • BTXBTX Posts: 674
    edited 2006-12-26 16:32
    Hi Cj.
    Thanks for your help.
    I'd try with this...but doesn't work confused.gif
    Is this correct·? .. only one LED continue fadding ..like in my original code....
    CON _clkmode = xtal1 + pll16x
        _xinfreq = 5_000_000
    VAR
       long Stack[noparse][[/noparse]20]
       long Dstack[noparse][[/noparse]20]
       
    OBJ
       R : "PWM1"
       B : "PWM2"
      
    PUB Vamos
       cognew(R.go, @Stack)
       cognew(B.go, @Dstack)
          
          
    



    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • CJCJ Posts: 470
    edited 2006-12-26 16:56
    I don't see anything wrong with the code, you may want to check your wiring, possibly switch the LEDs to make sure they both work

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Who says you have to have knowledge to use it?

    I've killed a fly with my bare mind.
  • Mike GreenMike Green Posts: 23,101
    edited 2006-12-26 17:49
    I don't think you can use COGNEW with methods in other objects (R.go/B.go). In your example, you don't need the COGNEW anyway since it is already provided in PWM1 and PWM2. Just use
    PUB Vamos
      R.go
      B.go
    
    
  • BTXBTX Posts: 674
    edited 2006-12-26 18:10
    Right Mike.
    Just see my original code, it's like you said but doesn't work.

    With :
    PUB vamos
     
        R.go
        B.go
    
    

    · Please !! read my first question to see all original code posted. Only R.go works and never return.
    Regards
    Alberto.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • Charlie JohnsonCharlie Johnson Posts: 147
    edited 2006-12-26 18:22
    Could it be the repeat?

    PUB Vamos
    R.go
    B.go

    repeat <
    Maybe try removing this.

    Just a SWAG

    Charlie
  • nutsonnutson Posts: 242
    edited 2006-12-26 18:54
    repeat
        repeat x from 0 to period          'linearly advance parameter from 0 to 100
          parameter := x                   'a constant here locks to value x percent high
          waitcnt(1_000_000 + cnt)         'wait a little while before next update  
    

    This is an endless loop,·you never return to the main program to execute the "B.GO" statement.



    Nico
  • BTXBTX Posts: 674
    edited 2006-12-27 00:57
    Charlie
    I'd try that ...but stil wont work...

    Nico.
    You're right with the effect, but I'm starting a new cog !! in B.go...first "go" is not the same as 2nd.....

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • BTXBTX Posts: 674
    edited 2006-12-27 04:14
    Original code wont work.......(at first post)

    And this simple code works.
    CON
      _CLKMODE = XTAL1 + PLL16X     'Set to ext low-speed crystal, 4x PLL
      _XINFREQ = 5_000_000         'Frequency on XIN pin is 5 MHz
    OBJ
       R : "Pru1"
       B : "Pru2"
    PUB Main
       R.go                       
       B.go                       
      
    

    {Pru1.spin}
    VAR
      long  Stack[noparse][[/noparse]9]                       'Stack space for new cog
    PUB go
      cognew(Toggle, @Stack) 
    
    PRI Toggle                       ' BLINK LED
      dira[noparse][[/noparse]16]~~                     'Set I/O pin to output direction 
      repeat                         'Repeat the following
        !outa[noparse][[/noparse]16]                    'Toggle I/O Pin 
        waitcnt(clkfreq / 10 + cnt)  'Wait     
     
    

    {Pru2.spin}
    VAR
      long  Stack[noparse][[/noparse]9]                       'Stack space for new cog
    PUB go
      cognew(Toggle, @Stack) 
    
    PRI Toggle                       ' BLINK LED
      dira[noparse][[/noparse]23]~~                     'Set I/O pin to output direction 
      repeat                         'Repeat the following
        !outa[noparse][[/noparse]23]                    'Toggle I/O Pin
        waitcnt(clkfreq / 20 + cnt)  'Wait     
     
    

    In fact, the problem seems to be, the repeat loop into the original code, but it hasn't the same effect, into this last code.

    When I call "R.go" in the spin version it start a new cog, and continue running from it in spin, then return to the Main method, but when I do the same with the assembler code, it wont return !!

    WHY PLEASE !! How to solve this ???

    My target is to fade two differents LED,·at different pins, and with different speed, just only to learn, for future objects.

    Regards.

    Alberto.

    EDIT: All wired is fine, the last code works with the demo board LED, Pins 16 and 23, when the first post code, is executed, only one LED works fading.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Envio editado por (BTX) : 12/27/2006 4:20:40 AM GMT
  • bambinobambino Posts: 789
    edited 2006-12-28 15:41
    Mike,BTX,
    I think what we are not seeing here is the fact that each oject is running a cognew(assembly with Stack space) AND some spin(without Stack space from the TopObject).
    Also, each par return is going to write to one global variable"Paremater"

    BTX,
    Try moving:

    · repeat
    ··· repeat x from 0 to period········· 'linearly advance parameter from 0 to 100
    ····· parameter := x·················· 'a constant here locks to value x percent high
    ····· waitcnt(1_000_000 + cnt)········ 'wait a little while before next update

    : up to the top object and monitor your variables from there.


    Post Edited (bambino) : 12/28/2006 4:35:07 PM GMT
  • BTXBTX Posts: 674
    edited 2006-12-28 17:14
    Hi Bambino.

    Thanks for the suggest, I did all test that I can imagine, and never got a correct work for this.
    After 3 or 4 days trying, I was getting some frustrating, just do it, only for learn to deal with cogs, and some of asm code.
    I thought that it could be a simple task...but nobody has solution for that problem...It seems that Parallax people is at "vacations" or similar and can't help...and, at this morning (here), I can solve it.
    Just about a few minutes I get the correct work...I've now the solution....but I'm waiting to finish a complete task to post it code.
    1- The problem solved code.
    2- A demo code, of how to fade 3 LEDS (RGB) at differents rates, at different times, and at different pins.

    Thanks again.
    Regards.
    Alberto.

    PS: Chi vediamo dopo...

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • bambinobambino Posts: 789
    edited 2006-12-28 17:24
    Glad to hear it,
    And yes I am glad to hear from anyone actually, I thought I might have become a ghost writter.
    Tell me, was it this
      repeat
        repeat x from 0 to period          'linearly advance parameter from 0 to 100
          parameter := x                   'a constant here locks to value x percent high
          waitcnt(1_000_000 + cnt)         'wait a little while before next update
    

    causing your problem?
  • BTXBTX Posts: 674
    edited 2006-12-28 18:17
    Hi Bambino.
    Bambino said...
    And yes I am glad to hear from anyone actually, I thought I might have become a ghost writter.
    · hahaha...me too lol.gif
    ·The answer is:
    PUB start(Level,Pin) : Pass 
     
        Stop
        Pass := (Cog := cognew(Auto(Level,Pin), @Stack) + 1)
     
     
    PRI Auto(Level,Pin)   | x
     
      cognew(@entry, @Level_Cog)
        Level_Cog := Level
        pin_cog   := Pin
     
      repeat
        repeat x from 0 to period                 'linearly advance level_cog from 0 to 100
          Level_Cog := x                          'a constant here locks to value x percent high
          waitcnt(1_000_000 + cnt)                'wait before next update
    DAT
    

    entry "asm code here"
    


    So when you call "start", it returns, an let original spin code to continue running.

    If you run Auto method like me "before", it never ends....simple but my confusion was that I have one cog for asm code and now I have one more to lunch it. In a minutes I'll be uploading final RGB LED fade code.

    I could say that is a "mix" of many answers...that I have.

    Be patient....here's is 15:15 and I've not lunch...still....

    Regards.

    Alberto.





    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • BTXBTX Posts: 674
    edited 2006-12-28 18:26
    Hi all.

    Here's the final working code !!!!

    Regards.
    ALberto.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • BTXBTX Posts: 674
    edited 2006-12-28 21:01
    Hi.
    Now it has a bit more to play, Using the unused variable, you can fix the bright at each LED.
    Take a look at the code now and try it.

    A good question for experts could be .....is it·possible to do the same ..but with no so many cog's ?? easily ........
    It is too much, to fade 3 led, using 6 cog's...cry.gif
    I think to include the "repeat loops" into the assembler code.....but it sounds me, hard to do, while maintain the counters working.
    And it seems a commonly serial programming....just not for propeller.

    Regards.
    Alberto.


    Here's the code:

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • Mike GreenMike Green Posts: 23,101
    edited 2006-12-28 22:22
    Alberto,
    You are actually doing 6 independent functions, but one of them is being done by a CTRx register with your assembly routine doing the reloading of the PHSx register. It would be possible to combine the PWM and fading functions into one cog. You have:
    :loop   rdlong value, par              'get an up to date pulse width
            waitcnt time, period           'wait until next period
            neg phsa, value                'back up phsa so that it
            jmp #:loop                     'loop for next cycle
    
    


    You could count periods and decrease the count with each period (or something similar):
    :get  rdlong value,par            ' Upper word has pulse width
            mov    delta,value         ' Lower word has period decrease
            shr      value,#16
            and     value,mask
            and     delta,mask
    :loop waitcnt time,period       ' Wait for period
            neg     phsa,value         ' Restart pulse width
            sub     value,delta         ' Decrease pulse width
            tjnz     value,#:loop      ' Stop when width is zero
            jmp    #:get                 ' Start over again
    mask long   $FFFF
    period long  100
    value res    1
    delta  res    1
    time  res    1
    
    


    This only goes from on to off. You can add another loop that goes from off to on and stops when the width is the same value as supplied in the upper word of the long passed to the routine.
  • Mike GreenMike Green Posts: 23,101
    edited 2006-12-28 22:26
    If you have only one value to pass to an assembly routine, PAR is convenient. If you want to pass several values or a "control block", you pass the address of the first value to the assembly program in PAR, then do arithmetic on that value to get to other parameters like:
    begin     mov   temp,par         ' address of first long
                 rdlong value1,temp
                 add    temp,#4         ' address of 2nd long
                 rdlong value2,temp
                 add    temp,#4         ' address of 3rd long
    '           ......                          ' more if you need it
    
    
  • BTXBTX Posts: 674
    edited 2006-12-29 00:58
    Oh Mike...thanks so much.


    I understand perfect your example.... I wrote that could be possible to do some similar, but at this point of my learn.. I wont, cause I was 3 or 4 days to get it work, "with 6 cogs".
    (Hope you understand me).
    In fact, I was discover your example method, to pass many variables to the asm code, but you write it generically very well !!
    This is my first try in asm...I took the CTRs example and modify it a bit.. I'll be continue trying every time I'd have some time...

    Thanks so much again
    Alberto.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Sign In or Register to comment.