Did I miss something subtle with hub RAM?
ke4pjw
Posts: 1,155
in Propeller 2
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.
It compiles and seems to work, kind of. Here is the spin code that passes information to the above code:
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
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
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:
but this works fine:
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.
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