Shop OBEX P1 Docs P2 Docs Learn Events
Assembly code may not be working — Parallax Forums

Assembly code may not be working

Hello everyone, I am a first time poster and I wanted to see if I could get some assistance working on Spin and Assembly code. I am new to Spin and Assembly code and I was having some trouble executing the Assembly code. I am using the P8x32a-d40 to control an LED sequence. There is a portion of the code that is written in Assembly for speed purposes. However, the Spin portion executes perfectly, but the Assembly portion does not appear to run when I use the cognew command to call it. Has anyone experienced this or can anyone provide me with a way to just test the Assembly portion?

Comments

  • tomcrawfordtomcrawford Posts: 1,126
    edited 2017-06-25 22:37
    Pretty much have to use spin to launch the first PASM cog.
    Post your code so we can see what is wrong. You can use the "C" button in the format bar.
    Program goes here.
    

    Welcome to the forum.
  • [CON
    _clkmode = xtal1 + pll16x
    _xinfreq = 5_000_000

    VAR
    byte datin[3], dp
    byte light1status, light2status, light3status, light4status
    word dtemp1, dout1, dtemp2, dout2, dtemp3, dout3, dtemp4, dout4

    long Command
    long pulsecount

    PUB LightControl_main

    ' UM245R communication Lines
    dira[7..0] := %00000000 ' input byte form UM245R
    dira[8] := 0 'input, RXF
    dira[9] := 1 ' output, RD#
    dira[10] := 0 'input, TXE
    dira[11] := 1 ' output, WR#

    'Digital output communication lines, SN74HC595

    dira[12] := 1 ' output, clock
    dira[13] := 1 ' output, data line 1
    dira[14] := 1 ' output, latch 1
    dira[15] := 1 ' output, data line 2
    dira[16] := 1 ' output, latch 2
    dira[17] := 1 'output, data line 3
    dira[18] := 1 'output, latch 3
    dira[19] := 1 ' output, data line 4
    dira[20] := 1 ' output, latch 4

    dira[21] := 1 ' output, analog MUX 1
    dira[22] := 1 ' output, analog MUX 2
    dira[23] := 1 ' output, analog MUX 3
    dira[24] := 1 ' output, analog MUX 4

    dira[25] := 0 ' input, camera frame exposure signal

    'Assembly code for 4 light pulsing
    Command:=0
    cognew(@Asm, @Command) ' set up another processor

    outa[9] := 1
    outa[11] := 0
    outa[12] := 0
    outa[13] := 0
    outa[14] := 0
    outa[15] := 0
    outa[16] := 0
    outa[17] := 0
    outa[18] := 0
    outa[19] := 0
    outa[20] := 0
    outa[21] := 0
    outa[22] := 0
    outa[23] := 0
    outa[24] := 0


    light1status := 0
    light2status := 0
    light3status := 0
    light4status := 0

    ' set 4 LED drive voltage outputs to 0

    repeat 16
    outa[12] := 1 ' clock it in
    outa[12] := 0
    outa[14] := 1 ' latch it in
    outa[14] := 0
    outa[16] := 1 ' latch it in
    outa[16] := 0
    outa[18] := 1 ' latch it in
    outa[18] := 0
    outa[20] := 1 ' latch it in
    outa[20] := 0

    repeat

    repeat dp from 0 to 2
    repeat until ina[8]==0
    outa[9] := 0
    datin[dp] := ina[7..0]
    outa[9] := 1

    'change lightlevel1
    if datin[0]==2
    dout1 := datin[1] + datin[2]*256
    dtemp1 := dout1
    repeat 12
    if (dtemp1 & %0000100000000000)==%0000100000000000
    outa[13] := 1
    else
    outa[13] := 0
    outa[12] := 1 ' clock it in
    outa[12] := 0
    dtemp1 <<= 1 ' shift left 1
    outa[14]:=1 'latch it in
    outa[14]:=0

    ' turn on light1
    elseif datin[0]==3
    if light1status==0
    outa[21] := 1
    light1status := 1
    elseif light1status==1
    outa[21] := 0
    light1status := 0

    'change lightlevel2
    elseif datin[0]==4
    dout2 := datin[1] + datin[2]*256
    dtemp2 := dout2
    repeat 12
    if (dtemp2 & %0000100000000000)==%0000100000000000
    outa[15] := 1
    else
    outa[15] := 0
    outa[12] := 1 ' clock it in
    outa[12] := 0
    dtemp2 <<= 1 ' shift left 1
    outa[16]:=1 ' latch it in
    outa[16]:=0

    ' turn on light2
    elseif datin[0]==5
    if light2status==0
    outa[22] := 1
    light2status := 1
    elseif light2status==1
    outa[22] := 0
    light2status := 0

    ' change lightlevel3
    elseif datin[0]==6
    dout3 := datin[1] + datin[2]*256
    dtemp3 := dout3
    repeat 12
    if (dtemp3 & %0000100000000000)==%0000100000000000
    outa[17] := 1
    else
    outa[17] := 0
    outa[12] := 1 ' clock it in
    outa[12] := 0
    dtemp3 <<= 1 ' shift left 1
    outa[18]:=1 ' latch it in
    outa[18]:=0

    ' turn on light3
    elseif datin[0]==7
    if light3status==0
    outa[23] := 1
    light3status := 1
    elseif light3status==1
    outa[23] := 0
    light3status := 0

    ' change lightlevel4
    elseif datin[0]==8
    dout4 := datin[1] + datin[2]*256
    dtemp4 := dout4
    repeat 12
    if (dtemp4 & %0000100000000000)==%0000100000000000
    outa[19] := 1
    else
    outa[19] := 0
    outa[12] := 1 ' clock it in
    outa[12] := 0
    dtemp4 <<= 1 ' shift left 1
    outa[20]:=1 ' latch it in
    outa[20]:=0

    ' turn on light4
    elseif datin[0]==9
    if light4status==0
    outa[24] := 1
    light4status := 1
    elseif light4status==1
    outa[24] := 0
    light4status := 0

    ' Run Light Pulsing (Round-Robbin) with Processor 2
    elseif datin[0]==10
    pulsecount := datin[1] + datin[2]*256
    Command:=1
    repeat until Command==0

    elseif datin[0]==255
    reboot

    DAT

    ' Processor 2 code: Simple Round-Robbin Sequence

    org 0
    Asm mov CmdAddr, par
    mov VarAddr, par
    add VarAddr, #4
    mov dira, Pin

    WaitForCmd rdlong Temp, CmdAddr
    tjz Temp, #WaitForCmd

    rdlong Count, VarAddr

    Loop1 mov Temp, ina
    and Temp, Exposurein wz
    if_z jmp #Loop1
    or outa, Plight1or ' turn on light 1
    Lp1 mov Temp, ina
    and Temp, Exposurein wz
    if_nz jmp #Lp1
    and outa, Plight1and ' turn off light 1
    Loop2 mov Temp, ina
    and Temp, Exposurein wz
    if_z jmp #Loop2
    or outa, Plight2or ' turn on light2
    Lp2 mov Temp, ina
    and Temp, Exposurein wz
    if_nz jmp #Lp2
    and outa, Plight2and ' turn off light2
    Loop3 mov Temp, ina
    and Temp, Exposurein wz
    if_z jmp #Loop3
    or outa, Plight3or ' turn on light3
    Lp3 mov Temp, ina
    and Temp, Exposurein wz
    if_nz jmp #Lp3
    and outa, Plight3and ' turn off light 3
    Loop4 mov Temp, ina
    and Temp, Exposurein wz
    if_z jmp #Loop4
    or outa, Plight4or 'turn on light4
    Lp4 mov Temp, ina
    and Temp, Exposurein wz
    if_nz jmp #Lp4
    and outa, Plight4and ' turn off light4
    djnz Count, #Loop1
    wrlong Zero, CmdAddr
    jmp #WaitForCmd



    CmdAddr long 0
    VarAddr long 0
    Temp long 0
    Zero long 0
    Count long 0
    Pin long %00000001_11111111_11111010_00000000
    Plight1or long %00000000_00100000_00000000_00000000 ' Pin 21
    Plight1and long %11111111_11011111_11111111_11111111 ' Pin 21
    Plight2or long %00000000_01000000_00000000_00000000 ' Pin 22
    Plight2and long %11111111_10111111_11111111_11111111 ' Pin 22
    Plight3or long %00000000_10000000_00000000_00000000 ' Pin 23
    Plight3and long %11111111_01111111_11111111_11111111 ' Pin 23
    Plight4or long %00000001_00000000_00000000_00000000 ' Pin 24
    Plight4and long %11111110_11111111_11111111_11111111 ' Pin 24
    Exposurein long %00000010_00000000_00000000_00000000
    ]
  • It is best to put code within a code format block.
    see the C in the formatting bar
    
    That way, all the formatting is maintained. It is especially important in spin where indents count.

    I don't see anything obvious wrong. I assume it all compiles and loads and the spin part is turning its light on.

    I see you are loading DIRA in the PASM cog; not doing this is a common error.

    I would simplify the PASM to turn on a light to make sure it is being executed and the add the command part later.
  • Everything compiles and the Spin code does the light turn on. I am having trouble executing the Assembly code. I don't know if I'm missing a couple lines of code or if cognew is actually setting up the cog.
    
    CON
    _clkmode = xtal1 + pll16x
    _xinfreq = 5_000_000
    
    VAR
    byte datin[3], dp
    byte light1status, light2status, light3status, light4status
    word dtemp1, dout1, dtemp2, dout2, dtemp3, dout3, dtemp4, dout4
    
    long Command
    long pulsecount
    
    PUB LightControl_main
    
       ' UM245R communication Lines
      dira[7..0] := %00000000   ' input byte form UM245R
      dira[8] := 0               'input, RXF
      dira[9] := 1                 ' output, RD#
      dira[10] := 0              'input, TXE
      dira[11] := 1              ' output, WR#
    
      'Digital output communication lines, SN74HC595
    
      dira[12] := 1               ' output, clock
      dira[13] := 1               ' output, data line 1
      dira[14] := 1                ' output, latch 1
      dira[15] := 1                 ' output, data line 2
      dira[16] := 1                ' output, latch 2
      dira[17] := 1                'output, data line 3
      dira[18] := 1                'output, latch 3
      dira[19] := 1                 ' output, data line 4
      dira[20] := 1                 ' output, latch 4
    
      dira[21] := 1                    ' output, analog MUX 1
      dira[22] := 1                    ' output, analog MUX 2
      dira[23] := 1                    ' output, analog MUX 3
      dira[24] := 1                    ' output, analog MUX 4
    
      dira[25] := 0                    ' input, camera frame exposure signal
    
      'Assembly code for 4 light pulsing
      Command:=0
      cognew(@Asm, @Command)       ' set up another processor
    
      outa[9] := 1
      outa[11] := 0
      outa[12] := 0
      outa[13] := 0
      outa[14] := 0
      outa[15] := 0
      outa[16] := 0
      outa[17] := 0
      outa[18] := 0
      outa[19] := 0
      outa[20] := 0
      outa[21] := 0
      outa[22] := 0
      outa[23] := 0
      outa[24] := 0
    
      
      light1status := 0
      light2status := 0
      light3status := 0
      light4status := 0
    
       ' set 4 LED drive voltage outputs to 0
    
      repeat 16
        outa[12] := 1           ' clock it in
        outa[12] := 0
      outa[14] := 1              ' latch it in
      outa[14] := 0
      outa[16] := 1              ' latch it in
      outa[16] := 0
      outa[18] := 1               ' latch it in
      outa[18] := 0
      outa[20] := 1                ' latch it in
      outa[20] := 0
    
    repeat
    
      repeat dp from 0 to 2
        repeat until ina[8]==0
        outa[9] := 0
        datin[dp] := ina[7..0]
        outa[9] := 1
    
        'change lightlevel1
      if datin[0]==2
        dout1 := datin[1] + datin[2]*256
        dtemp1 := dout1
        repeat 12
          if (dtemp1 & %0000100000000000)==%0000100000000000
            outa[13] := 1
          else
            outa[13] := 0
          outa[12] := 1   ' clock it in
          outa[12] := 0
          dtemp1 <<= 1    ' shift left 1
        outa[14]:=1      'latch it in
        outa[14]:=0
    
        ' turn on light1
      elseif datin[0]==3
        if light1status==0
          outa[21] := 1
          light1status := 1
        elseif light1status==1
          outa[21] := 0
          light1status := 0
    
          'change lightlevel2
      elseif datin[0]==4
        dout2 := datin[1] + datin[2]*256
        dtemp2 := dout2
        repeat 12
          if (dtemp2 & %0000100000000000)==%0000100000000000
            outa[15] := 1
          else
            outa[15] := 0
          outa[12] := 1   ' clock it in
          outa[12] := 0
          dtemp2 <<= 1    ' shift left 1
        outa[16]:=1     ' latch it in
        outa[16]:=0
    
        ' turn on light2
      elseif datin[0]==5
        if light2status==0
          outa[22] := 1
          light2status := 1
        elseif light2status==1
          outa[22] := 0
          light2status := 0
    
         ' change lightlevel3
      elseif datin[0]==6
        dout3 := datin[1] + datin[2]*256
        dtemp3 := dout3
        repeat 12
          if (dtemp3 & %0000100000000000)==%0000100000000000
            outa[17] := 1
          else
            outa[17] := 0
          outa[12] := 1         ' clock it in
          outa[12] := 0
          dtemp3 <<= 1          ' shift left 1  
        outa[18]:=1              ' latch it in
        outa[18]:=0
    
        ' turn on light3
      elseif datin[0]==7
        if light3status==0
          outa[23] := 1
          light3status := 1
        elseif light3status==1
          outa[23] := 0
          light3status := 0
    
          ' change lightlevel4
      elseif datin[0]==8
        dout4 := datin[1] + datin[2]*256
        dtemp4 := dout4
        repeat 12
          if (dtemp4 & %0000100000000000)==%0000100000000000
            outa[19] := 1
          else
            outa[19] := 0
          outa[12] := 1   ' clock it in
          outa[12] := 0
          dtemp4 <<= 1  ' shift left 1
        outa[20]:=1   ' latch it in
        outa[20]:=0
    
        ' turn on light4
      elseif datin[0]==9
        if light4status==0
          outa[24] := 1
          light4status := 1
        elseif light4status==1
          outa[24] := 0
          light4status := 0
    
          ' Run Light Pulsing (Round-Robbin) with Processor 2
      elseif datin[0]==10
        pulsecount := datin[1] + datin[2]*256
        Command:=1
        repeat until Command==0
    
      elseif datin[0]==255
        reboot
    
    DAT
    
    ' Processor 2 code: Simple Round-Robbin Sequence
    
                           org      0
    Asm                    mov      CmdAddr, par
                           mov      VarAddr, par
                           add      VarAddr, #4
                           mov      dira, Pin
    
    WaitForCmd             rdlong   Temp, CmdAddr
                           tjz      Temp, #WaitForCmd
    
                           rdlong   Count, VarAddr
    
    Loop1                  mov      Temp, ina
                           and      Temp, Exposurein wz
                   if_z    jmp      #Loop1
                           or       outa, Plight1or          '  turn on light 1
    Lp1                    mov      Temp, ina
                           and      Temp, Exposurein wz
                  if_nz    jmp      #Lp1
                           and      outa, Plight1and        ' turn off light 1
    Loop2                  mov      Temp, ina
                           and      Temp, Exposurein wz
                  if_z     jmp      #Loop2
                           or       outa, Plight2or   ' turn on light2
    Lp2                    mov      Temp, ina
                           and      Temp, Exposurein wz
                  if_nz    jmp      #Lp2
                           and      outa, Plight2and   ' turn off light2
    Loop3                  mov      Temp, ina
                           and      Temp, Exposurein wz
                  if_z     jmp      #Loop3
                           or       outa, Plight3or      ' turn on light3
    Lp3                    mov      Temp, ina
                           and      Temp, Exposurein wz
                  if_nz    jmp      #Lp3
                           and      outa, Plight3and         ' turn off light 3
    Loop4                  mov      Temp, ina
                           and      Temp, Exposurein wz
                  if_z     jmp      #Loop4
                           or       outa, Plight4or        'turn on light4
    Lp4                    mov      Temp, ina
                           and      Temp, Exposurein wz
                  if_nz    jmp      #Lp4
                           and      outa, Plight4and        ' turn off light4
                           djnz     Count, #Loop1
                           wrlong   Zero, CmdAddr
                           jmp      #WaitForCmd
                           
                  
    
    CmdAddr   long   0
    VarAddr   long   0
    Temp      long   0
    Zero      long   0
    Count     long   0
    Pin        long   %00000001_11111111_11111010_00000000
    Plight1or  long   %00000000_00100000_00000000_00000000  ' Pin 21
    Plight1and long   %11111111_11011111_11111111_11111111  ' Pin 21
    Plight2or  long   %00000000_01000000_00000000_00000000  ' Pin 22
    Plight2and long   %11111111_10111111_11111111_11111111  ' Pin 22
    Plight3or  long   %00000000_10000000_00000000_00000000  ' Pin 23
    Plight3and long   %11111111_01111111_11111111_11111111  ' Pin 23
    Plight4or  long   %00000001_00000000_00000000_00000000  ' Pin 24
    Plight4and long   %11111110_11111111_11111111_11111111  ' Pin 24
    Exposurein long   %00000010_00000000_00000000_00000000 
              
    
  • tomcrawfordtomcrawford Posts: 1,126
    edited 2017-06-26 00:02
    I would try making the pasm really simple, say just blink a led forever. That way, you can be sure you are setting up a cog. If so, then you can add to it.
  • You are setting Pins 21-24 both in your assembly cog and your Spin Cog to output and writing to them with outa also.

    So your spin cog is colliding with your pasm cog on pins 21-24.

    Remove or comment out all references to Pin 21-24 out of your Spin-Cog.

    my 2 cents.

    Mike


  • In general, when dealing with DIRA and OUTA, you should change only the pins needed and avoid changing the states of any other pins.
    mov dira, Pin
    
    should be
    or dira, Pin
    
    and your Plight... masks could look like this:
    Plight1 long |<21
    Plight2 long |<22
    Plight3 long |<23
    Plight4 long |<24
    
    You'd then turn on light 1 with
    or outa, Plight1
    
    and turn off light 1 with
    andn outa, Plight1
    
    Note the "andn" instead of the "and". This means that *only* the bit(s) set in the mask are turned off.

    Regarding your issue with the code not running... I agree with Mike. You're trying to control a light from 2 cogs. Not a good idea.

    If you set any of the lights on with the SPIN code, then it is impossible to turn them off with the assembly code. The OUTA bits from all cogs are OR'd together to set the pin states. This means that if any cog turns on a pin then no other cog can turn it off.

    I suspect that the issue is that one or more of the lights is turned on via a command, which will cause the assembly code that waits for the corresponding light to be turned off to go into an infinite loop when you attempt to pulse the lights.

    A possible fix would be to have the "Run light pulsing" SPIN code do the following before setting Command to 1:
    outa[21..24]~    ' Turn off all lights
    light1status := 0
    light2status := 0
    light3status := 0
    light4status := 0
    
    Of course, this would override any previous commands that turned on a light.

    But ultimately, IMHO, only one cog should manipulate a pin (light).

    Walter


  • Thank you all for your input. I tried to run a small piece of assembly code and it works just fine. The way I have the code set up, it is supposed to interface with MATLAB via UM245R. So wherever you see datin[0]==#, that corresponds to a function in MATLAB that either controls the voltage output or turns the LED on/off. However, I am still having trouble executing the round-robin sequence in the assembly code.
Sign In or Register to comment.