Shop OBEX P1 Docs P2 Docs Learn Events
Help debugging basic assembly code — Parallax Forums

Help debugging basic assembly code

SRLMSRLM Posts: 5,045
edited 2009-08-12 08:17 in Propeller 1
Well, this is my first dive into PASM. I'm trying to modify the MCP3208 3 chip driver to automatically sample all channels (as opposed to sample on command). The original driver can be found here: http://obex.parallax.com/objects/403/

What I've done is take out everything in the spin sections except the start and stop methods. In the assembly, I've modified it to call the setup routine, then take readings in the average routine for all the channels, then write the results to the hub, then go back to the average routine.

Somewhere, the code has hung up. I haven't really figured out how to use the PASD debugger yet, but (assuming that I've got it correct so far) one problem might be in the very beginning. The PAR that is passed is supposed to be the pin definitions, but according to PASD (screenshot attached) the actual pin definitions are a couple dozen memory locations down.

The serial terminal output remains constant, although I have chip one hooked up on all eight channels:
ADC 24 Channel Test (chip numbers start at 1) 
Cycle: 23 
Chip 1, Channel 0 : 25 
Chip 1, Channel 1 : 25 
Chip 1, Channel 2 : 0 
Chip 1, Channel 3 : 0 
Chip 1, Channel 4 : 0 
[noparse][[/noparse] ... the rest of the values are 0 ]

Does anybody have an ideas on how to fix the code?

Post Edited (SRLM) : 8/11/2009 4:16:58 AM GMT

Comments

  • AribaAriba Posts: 2,690
    edited 2009-08-11 12:44
    What I see at a first view is that your parameter passing is wrong. Every long in a long array is 4 addresses
    higher than the previous, so your start methode must pass the parameters like this:
      long[noparse][[/noparse]dataaddr+0]  := dpin1             ' initialize for call to _setup
      long[noparse][[/noparse]dataaddr+4]  := cpin1
      long[noparse][[/noparse]dataaddr+8]  := spin1
      ....
    
    


    But because you get the parameters in the right order, this is much simpler and does the same:
      longmove(dataaddr, @dpin1, 9)     ' initialize 9 longs with pin numbers for call to _setup
    
    



    And in the assembly section you also need an offset of 4 for every long to read:
                            mov     t3, par
                            rdlong  t1, t3
                            call    #param                  ' setup DIN/DOUT1 pin
                            mov     dmask1,t2
    
                            add     t3, #4                   '<-- 4 not 1
                            rdlong  t1, t3
                            call    #param                  ' setup CLK1 pin
                            mov     cmask1,t2
    
                            add     t3, #4
                            rdlong  t1, t3
                            call    #param                  ' setup CS1 pin
                            mov     smask1,t2
    
                           .....
    
    


    You also need to change the write_results with:
    add count,#4
    but I have not looked deeper in the assembly code yet.

    After these changes you should see the right values at the right positions inside PASD.

    Andy
  • SRLMSRLM Posts: 5,045
    edited 2009-08-12 00:01
    Okay, some more progress. One thing that I've noticed when I used PASD is that it doesn't seem to keep the variable order and size information? In the attached screenshot, values is 24 longs at the end of the program, but in the cog ram viewer it shows values as 6 long spots, surrounded on either side by more labels (even though in the source there's no labels afterward. Is this a bug or what am I missing? Source code attached.

    Anyway, I did some more work on the program and it works now! At least, as far as I can tell. Thanks for your help.
  • AribaAriba Posts: 2,690
    edited 2009-08-12 01:59
    I can not reproduce this.
    Attached is a screenshot of how it looks on my Computer.

    How do you pass the Source code?
    In the PropTool, I select the Tab with the ..._test.spin file and press F10 to download, then I select the Tab with the ..._autoample.spin file and switch to PASD and press F2 (the first time, later I only minimize PASD while downloading).


    Andy
    1024 x 768 - 33K
  • SRLMSRLM Posts: 5,045
    edited 2009-08-12 02:33
    I've been following the same process except that after I maximize (or give control to) PASD I always click the get ASM code. I've been keeping the same PASD window open all day, so I tried closing it and reopening (with a repeat of the download following the same process as you described). The problem was fixed (values was at the end).

    However, I noticed that the first two labels were missing (entry and setup_). Screenshot attached, but the same source code as before. I got it to reproduce (both with minimization of PASD and redownload, and a clean start).

    Also, I meant for the code that I posted to have the PASD stuff uncommented and the FullDuplexSerial stuff commented so that they don't interfere. I guess you did that, but just in case...
    1600 x 1200 - 370K
  • SRLMSRLM Posts: 5,045
    edited 2009-08-12 05:52
    write_results
                            't1 = hub pointer
                            't2 = cog pointer
                            't3 = loop counter
    
                            mov     t1, par                 ' Get base address in Hub
                            add     t1, #4                  ' Move to start of array in Hub
                            movs    :wr_loop, t1            ' Store the hub address in the instruction
                            movd    :wr_loop, #values       ' Get Cog array address and store in instruction
                            mov     t3, #24                 ' 24 channels to record
    :wr_loop                wrlong  0-0, 0-0                ' Write the value to the hub
                            add     :wr_loop, address_mask
                            djnz    t3, #:wr_loop
    
                            add     count, #1
                            wrlong  count, par
                            
                            jmp     #average_               ' Return to take more samples
    
    



    I got my code to work, but I thought I could make it go faster. This is what I came up with. Unfortunately, it doesn't work since I can't just add a mask to the wrlong. So, I'd have to have two separate add instructions (one for the hub pointer, one for the cog pointer), and the djnz instruction. So, that's three instructions that forces the wrlong to miss the window of opportunity, which in turn halves the data rate.

    Does anybody have any solutions for how to write an array to the hub with a single wrlong and two more instructions?

    I'm sure it must have been done somewhere...
  • TimmooreTimmoore Posts: 1,031
    edited 2009-08-12 08:17
    I would look at 3 things
    1. create a variable containing the inc - both source and dest inc so you can add in 1 instruction
    2. unroll the loop once - you have some spare cycles butnot enough, unroll the loop and you have 2x the spare cycles
    3. also dont forget the pipeline you can put an add before the instruction you are adding and it will not take effect until net time round the loop
Sign In or Register to comment.