Shop OBEX P1 Docs P2 Docs Learn Events
Did I miss something subtle with hub RAM? — Parallax Forums

Did I miss something subtle with hub RAM?

Before I rip this code up and "do it my way", can you guys take a look at this and see if I missed something subtle? I am attempting to make changes so this code is PASM2 compliant and am getting unusual results. ie Can't pass a #2 command and data from the #1 command is non-nonsensical. The correct pins do seem to be passed.

This is an adaptation of an SPI driver written by Beau. There is a data structure in hub RAM that gets passed to the COG via PTRA (I assume that is the same as PTR, but am not sure if it directly translates)

The changes I made are as follows:

Changing local labels to start with "." ie ".arg"
Changed PTR to PTRA.
Changed movd to setd.

See code below.
DAT           org
''****************************** 
'' SPI Engine - Command dispatch
''******************************

loop          rdlong  DataPin,        ptra         wz    '' Wait for command via ptra
        if_z  jmp     #loop                             '' No command (0), keep looking
              setd    .arg,           #arg0             '' Get 5 arguments ; arg0 to arg4
              mov     ClkPin,         DataPin           ''    │
              mov     DataVal,        #5                ''───┘
.arg          rdlong  arg0,           ClkPin            '' mov arg
              add     .arg,           d0                '' It adds 512 because that is a 1 for the destination field.
                                                        '' This increments the destination to point at each of the
                                                        '' arg destinations.
              add     ClkPin,         #4                '' Main memory addresses go up by 4 (for long)
              djnz    DataVal,        #.arg             '' Keep going until done

              shr     DataPin,        #16               '' The command is the upper 16 bits. Slide it down to the lower 16 bits
              cmp     DataPin,        #1          wz    '' Jump to the single SPI shift routine
 


        if_z  jmp     #SHIFTONE_             


            cmp     DataPin,        #2          wz    '' Jump to the write buffer routine

        if_z  jmp     #WRITEBUFF_             


              wrlong  zero,ptra                          ''     Zero command to signify command received
NotUsed_      jmp     #loop

It compiles and seems to work, kind of. Here is the spin code that passes information to the above code:
PUB ssd1331_command(thecmd)|tmp 'Send a byte as a command to the display
  ''Write SPI command to the OLED
  LOW(DC)
  SHIFTOUT(DATA, CLK, CS ,@tmp, thecmd)   

PUB ssd1331_Data(thedata)|tmp   'Send a byte as data to the display
  ''Write SPI data to the OLED
  HIGH(DC)
  SHIFTOUT(DATA, CLK, CS ,@tmp, thedata)   

PUB SHIFTOUT(Dpin, Cpin, CSpin, Bits, Value)             
    setcommand(1, @Dpin)

PUB WRITEBUFF(Dpin, Cpin, CSpin, Bits, Addr)
    setcommand(2, @Dpin)

PRI setcommand(cmd, argptr)
    command := cmd << 16 + argptr                       '' Write command and pointer
    repeat while command                                '' Wait for command to be cleared, signifying receipt

PUB start:okay

'' Start SPI Engine - starts a cog
'' returns false if no cog available
    stop
    okay := cog := cognew(@loop, @command) + 1

PUB stop
'' Stop SPI Engine - frees a cog
    if cog
       cogstop(cog~ - 1)
    command~

PUB init(ChipSelect,DataCommand,TheData,TheClock,Reset)
  ''Startup the SPI system
  start

  ''Initialize variables and initialize the display
  CS:=ChipSelect
  DC:=DataCommand
  DATA:=TheData
  CLK:=TheClock
  RST:=Reset

Another set of eyes might help, so I appreciate any help. Otherwise I am ripping this all apart and re-writing it more like FullDuplexSerial in the way that it passes pin parameters (only once).

Thanks in advance.

--Terry

Comments

  • Cluso99Cluso99 Posts: 18,069
    Just a thought. Have you checked that the data is correctly passed from SETQ to PTRA? In particular, not shifted or bits zeroed?

  • I've been running into similar difficulties converting my P1 code for the P2: Things "almost" working, "Random" operation when a single instruction is modified, etc.

    I finally got my first programs working exactly the way I intended them to work for the first time last night. I think that most of my own difficulty has been from two things: not quite understanding the compiler and issues with timing when passing data from one cog to another.

    Sometimes I would compile new code and things worked fine. Sometimes the same code with a single NOP instruction added was completely different.
    Most of THOSE problems were from the not shutting the startup (cog 0) down immediately after it starts my two main cogs. I had the cog1 and cog2 variables in line with the startup code before doing a cogstop 0.

    This didn't work:
    coginit	cognum2,#@blink      ' init a single cog to use the blink program 
    coginit	cognum1, #@Move6   ' init  cog1 for the movement function
    
    cognum1		long   2
    cognum2  	long   3
    
                    cogstop #0                 ' terminate the startup cog. 
    
    


    but this works fine:
    coginit	cognum2,#@blink  ' init a single cog to use the blink program 
    coginit	cognum1, #@Move6  ' init  cog1 for the movement function
    
                    cogstop #0                 ' terminate the startup cog. 
    
    cognum1	        long   2
    cognum2  	long   3
    
    

    Some other clues about what I was doing wrong came from watching my O-scope when downloading a new compile. One cog was still running data from the PREVIOUS run even though new data had been downloaded. On another download the second cog might go into an endless loop.

    I realized that I was modifying variables of a program THAT WAS ALREADY RUNNING which is always a good way to do "random" things.

    first I had to change the startup sequence and timing of my cogs and to make sure that one cog "plays well" with the other, I had to build a series of "stop and go" flags so that both cogs wait until they are "Darn good and sure" that everything has been setup or done correctly by the other cog before they try to run more code. ( they also immediately overwrites these "Go" flags before continuing) This seems to have stopped the "Random" operation on a new download.

    One other thing I THINK I needed was a WAITX #20 after doing a random read/write to hub ram and possibly a NOP when passing data through the LUT.
    If I knew how to setup the fifo pipeline this might change... but that's for another day.

    I don't know if you might be running into any of these things, but they sure had me banging my head against the wall for a while.
    Good luck, we'll get there eventually. There's just going to be a lot of banged up heads and walls between here and there.

    KB.



  • Cluso99Cluso99 Posts: 18,069
    In P1 the longs you defined would be treated as nips whereas in P2 they execute as some instruction plus typically a _RET_ because here the condition bits 0000 is the _RET_.
  • Cluso99 wrote: »
    Just a thought. Have you checked that the data is correctly passed from SETQ to PTRA? In particular, not shifted or bits zeroed?

    Thanks Cluso! I need to look at the fastspin compiler output and see if it is doing what I expect. I may need to learn how to use your debugger :)
Sign In or Register to comment.