I take that by this you mean that the delays provided by the instructions execution themselves are never long enough. (including the time your finger takes).
The reference was very interesting but if I had to provide a 1/6 second delay to cover all cases, that did seem onerous.
Typically you can get by with delay of 10 mS to verify the press/release for clean debounce. Most setups I have seen will see a transition, delay 10 ms or so, recheck to see if the state is still the same and accept that a real transition has occured. Some will do this longer as a "did you really mean to press the switch?" test. And yet even longer checks as whe setting values once per press, slow count up/down for short hold press and fast count up/down for longer press and holds.
Onerous would be trying to chase down mystery behaviors due to poor/missing debounce methods either electronic or in sofgtware. Debounce the UI. Cost $0.00 in software. In hardware a few cents. Continued sanity, priceless.
[FONT=Arial, sans-serif]Here is a bit of code I developed to look at what was going on in the Propeller as I shifted the data left and right and reversed bits etc. As set up now, it lets to look at the data at three locations in the program. It can be expanded to whatever you like.[/FONT]
[FONT=Arial, sans-serif]The data appears on the PST.[/FONT]
[FONT=Arial, sans-serif]As set up,the code takes the data in the third byte of a long and reverses the bits. All other bits are erased. Then one erased bit is set. I need to reverse the bits because as my LCD was hooked up to the Propeller, the pins were in the reverse order to what was required.[/FONT]
[FONT=Arial, sans-serif]It is also useful for looking at what the MUX instructions do.[/FONT]
[FONT=Arial, sans-serif]H[/FONT]
[FONT=Lucida Console, monospace][SIZE=2]{{ Program 017 PASM minimum PAR.spin[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]This program is a minimal implementation for two variables and PAR.[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]There are two Cogs in this program, one in SPIN and one in PASM[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Cog 1 in SPIN displays the variables on the console[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Cog 2 in PASM sets the variables [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Finds the location of PAR and moves it to mem1[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Then mem2 is set to mem1 +4. [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]The two variables are transferred to mem1 and mem2[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]and become available to the SPIN environment[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Loop.[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]}} [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]CON[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]_clkmode = xtal1 + pll16x[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]_xinfreq = 5_000_000[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]VAR[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]long eightlongs[3],shared[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]OBJ[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds: "FullDuplexSerial"[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]PUB FirstCog 'displays values on console[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.start(31,30,0,115200) 'start console at 115200 for debug output[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]cognew(@SecondCog, @eightlongs) 'start the second Cog in PASM [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]waitcnt(clkfreq/4+cnt) 'wait 1/4 for everything to stabilize.[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]repeat'loop [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared:=eightlongs [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx($1) 'home to 0,0[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first value[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first value [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx(" ") 'display first value[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx($0d) 'new line [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared:=eightlongs[1] [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'fds.tx($1) 'home to 0,0[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first value[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first value [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx(" ") 'display first value[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx($0d) 'new line[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared:=eightlongs[2] [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'fds.tx($1) 'home to 0,0[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first value[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first value [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx(" ") 'display first value[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx($d) 'new line[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'fds.dec(eightlongs[1]) 'display second value [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]waitcnt(clkfreq/60+cnt) 'flicker free wait[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'************************************************************************************************ [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]DAT[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]org0'start at 0 location in the cog [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]SecondCog 'start point identification[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov mem1, par[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov mem2, mem1 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]add mem2, #4[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov mem3, mem2 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]add mem3, #4[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]loop call #start[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]jmp #loop[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Start[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]movdira, setdira [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov timer, onesec '40 000 000[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]:loop djnz timer, #:loop [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]movouta, databyte [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]wrlongouta, mem1[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov timer, onesec '40 000 000[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]:loop1 djnz timer, #:loop1[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]movouta, databyte[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shlouta, #16 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shrouta, #24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shlouta, #8 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]rorouta, #8[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]revouta, #0[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]rorouta, #16 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]wrlongouta, mem2 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov timer, onesec '40 000 000[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]:loop2 djnz timer, #:loop2 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]orouta, enablebit [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]wrlongouta, mem3 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Start_ret ret [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]dataByte long%00000000_00000000_1001_1110_00000000 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]setdira long%00000000_00000111_00000000_0000000[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]SelectBit long%00000000_00000100_00000010_00000000 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]ReadBit long%00000000_00000010_00000000_00000000 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]EnableBit long%00000000_00000001_00000000_00000000 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]onesec long80_000_00[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mem1 res1'first address storage space[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mem2 res1'second address storage space[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mem3 res1[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]timer res1[/SIZE][/FONT]
@Harprit: Your recent code postings have lost their useful formatting. Simply copying the code into the prop tool isn't working anymore (extra column on the left side). This is not helping people evaluating your stuff.
Also, your timing loops are confusing. Relative to clkfreq the variable onesec holds the clock count for 1/10th of a second, the comment (40M) suggests 1/2 a second and the actual loop delays for 4/10th of a second. What is it going to be?
I managed to burn out one of the pins on my propeller as I developed PASM and had one heck of a time figuring out why things would not work. Finally got it replaced so hope to move on now
However here is the revised code for the program I posted last time with proper commenting and formatting as requested by kuroneko and stephan. These guys keep me honest!
[FONT=Lucida Console, monospace][SIZE=2]{{ Program 017 PASM minimum PAR.spin[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]This program allow you to look at data manipulations on PST.[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]There are two Cogs in this program, one in SPIN and one in PASM[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Cog 1 in SPIN displays the data on the console[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Cog 2 in PASM sets the data and manupulates it[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Finds the location of PAR and moves it to mem1[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Then mem2 is set to mem1 +4. mem3 is set to mem1+8[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]The data is transferred to mem1, mem2 and mem3 where selected by user[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]and become available to the SPIN environment for display[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Loop.[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]}}[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]CON[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]_clkmode = xtal1 + pll16x[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]_xinfreq = 5_000_000[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]VAR[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]long eightlongs[3],shared[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]OBJ[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds: "FullDuplexSerial"[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]PUB FirstCog 'displays values on console[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.start(31,30,0,115200) 'start console at 115200 for debug output[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]cognew(@SecondCog, @eightlongs) 'start the second Cog in PASM [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]waitcnt(clkfreq/4+cnt) 'wait 1/4 for everything to stabilize.[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'shared:=eightlongs[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]repeat'loop [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared:=eightlongs [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx($1) 'home to 0,0[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first byte[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display second byte [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display third byte[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display fourth byte[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx(" ") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx($0d) [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared:=eightlongs[1] 'repeat for second long[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'fds.tx($1) [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx(" ") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx($0d)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared:=eightlongs[2] 'repeat for third long[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'fds.tx($1) [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx(" ") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx($d) [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]waitcnt(clkfreq/60+cnt) 'flicker free wait[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'************************************************************************************************ [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]DAT[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]org0'start at 0 location in the cog [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]SecondCog 'start point identification[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov mem1, par'find par address[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov mem2, mem1 'store it in mem2[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]add mem2, #4'add 4 to mem1 to get second address[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov mem3, mem1 'store mem1 in mem3[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]add mem3, #8'add 8 to mem1 to get third address[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]:loop call #start 'repeating loop[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]jmp #:loop '[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Start movdira, setdira 'set diretion of DIRA [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]movouta, databyte 'read data into outa[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]wrlongouta, mem1 'write result into mem1[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]movouta, databyte 'read data into outa[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shlouta, #16'manupulate outa, shift left 16 to clear bits[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shrouta, #24'manupulate outa, shift right 24 to celar bits[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shlouta, #8'manupulate outa, move back to original position [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]rorouta, #8'manupulate outa, rotate to rightmost bits[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]revouta, #0'manupulate outa, reverse bits[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]rorouta, #16'manupulate outa, rotate back to original bits[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]wrlongouta, mem2 'write result into mem[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]orouta, enablebit 'manupulate outa[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]wrlongouta, mem3 'write result into mem[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Start_ret ret [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'various constants I was using in my particular experiments[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]dataByte long%00000110_00011000_10001100_00111000 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]setdira long%00001111_00000111_00001111_00111110[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]SelectBit long%00000000_00000100_00000010_00000000 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]ReadBit long%00000000_00000010_00000000_00000000 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]EnableBit long%00000000_00000001_00000000_00000000 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mem1 res1'first address storage space[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mem2 res1'second address storage space[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mem3 res1'third address storage space[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]timer res1'for delays[/SIZE][/FONT]
I am not sure I understand the reason for using outa for the manipulations of the data as written. It would seem better (not to mention safer for the prop and any attached devices) to create a location in memory to carry out the manipulations. The comment text says that the values resulting from the manipulations will be output via the PST, so any non-spr memory location in the cog could be used to hold/manipulate the data.
Currently there are no delays or stored results between the manipulations that are taking place, and thus no way to actually see the results at each step; only the end result in the terminal. Consider breaking this into two exercises, one using an internal memory location, and terminal output with additional shared locations to hold/display the intermediate results (with additional text labels indicating the output is for___), and a second using outa, long delays, and perhaps a VERY slow system clock rate so that the results of each manipulation can be seen in the leds. With the caveat the user understands this is only for seeing the effects of the instructions in question as a learning exercise, and not a normal use of outa in practice.
I am not sure I understand the reason for using outa for the manipulations of the data as written. It would seem better (not to mention safer for the prop and any attached devices) to create a location in memory to carry out the manipulations.
Seconded. Especially with an active dira setup. otherwise it doesn't really matter.
@Harprit: Wouldn't the following sequence be easier to understand?
and outx, mask ' isolate required byterev outx, #{32 -}8' reverse data
...
mask long$FF << 8
As always, you guys are of course right
My problem is that I am not conversant or comfortable with binary manipulations
I need to write that chapter now
This was suggested to me earlier but I did not take the advise as I should have.
Same ole same ole.
Will spend time on binary chapter in the next week or so to see if I cant learn something.
Needs getting done.
In my beginner primer, there are the very basics of binary manipulations. Get the truth tables and work them on paper. Every one of the Propeller bit operation instructions can be easily written down and processed on paper, one digit at a time, using the truth table. When you've done that, do some addition and subtraction exactly the same way.
And, or, not, xor, rol, ror, shl, shr, mux (for the prop, and is a cool instruction), rev (again for the prop), are the core of assembly language.
All of these are not very complex. It's the use cases and short cuts they bring to the table that makes all the difference in the world. Of those the "and, or, shx" instructions see near constant use. They are the ones that break longs into chunks that one can work with and make decisions on.
[FONT=Arial, sans-serif]Read the material on binary math.[/FONT]
[FONT=Arial, sans-serif]Here is what I found specially as being specially relevant to a beginner.[/FONT]
[FONT=Arial, sans-serif]Binary mathematics are not particularly difficult. However, you have to pay exquisite detail to what you are doing, because beginners do not have a good feel for things that happen as we shift registers to the left and to the right and reverse bits to manipulate the I/O to get the results that we are seeking. It is best to lay it out on paper as you go along.[/FONT]
[FONT=Arial, sans-serif]At the level that I am working, I am not quite ready to add the shorthand notation that adds even more power to binary manipulations. That absolutely has to come later as the comfort level increases.[/FONT]
[FONT=Arial, sans-serif]Here is the code for activating a 2 x 16 character liquid crystal display with a standard Hitachi controller. The code is not particularly long, which surprised me, and is not particularly complicated once one figures out what needs to be done. How long it takes to figure out what needs to be done is a whole other matter complicated by that fact that the Hitachi controller manual has some difficult phraseology in it and some of the help material on the internet has mistakes in it.[/FONT]
[FONT=Arial, sans-serif]I am still not comfortable with the routine that reads the busy bit. Experts please examine and advise. Seems to me that I should not need a delay in this routine.[/FONT]
The first line should probably work on outa given that enablebit is a mask which is previously set for output (i.e. inputs & enablebit <> 0) and not be part of the loop. As for the second line, ina needs to in the source slot to be useful here. I'd suggest:
test bits1000_0000, inawz
under the assumption that busy means not equal zero. Later you might want to get rid of the loop and simply use:
waitpne bits1000_0000, bits1000_0000 ' wait for high/low transition
I still am not happy with my check busybit routine in 435. Could some one please rewrite the routine for me. As it is, it works but it seems to me that it should not need the delay.
A book I always planned on writing but never got around to was a college text on propeller/asm/spin to an extent.
A good thing to look at is a typical college text, how the architecture is approached for a controller, then getting into ASM and internal peripherals.
Please do not expect a college text from me. I have neither the expertise of the desire to do a college text. I hope this will be an introduction for hobbyists, no more no less. I hope it will be an adequate one. So a detailed discussion of the architecture etc does not seem to be in the cards.
I got to thinking that maybe a delay is needed to allow the
The delay is required because your loop never loops and the delay artificially - I'm guessing here - covers the timeout (that's why it seems to work). This is all because in this context
andnina, busymask wz
will always set the Z flag. You're using ina in the wrong slot (src vs dst). That's why I suggested this earlier:
[FONT=Arial, sans-serif]But I still need the delay and the delay cannot be less[/FONT]
[FONT=Arial, sans-serif]I still cannot get it right in my mind.[/FONT]
As a matter of fact the only thing that matters is the delay.
Everything else can be deleted. So the BUSY flag is not being read
I have come to the conclusion that I am not reading the busy bit right.
I need someone to explain it in detail to me.
What should be set to what when etc. or a code listing would help.
Everything works fine with a delay but tha's not the goal here.
The data sheet says that the condition of the BB can be read by making the register select line low and the read/write bit high. The BB is available when the enable bit is made low.
After that if I read ina into temp can I isolate the bit from that? I am having difficulty with that. Apparently I am doing something wrong.
I still am not happy with my check busybit routine in 435. Could some one please rewrite the routine for me. As it is, it works but it seems to me that it should not need the delay.
I haven't finished porting my [ working ] Spin LCD driver to PASM, but this is the port of the code that waits for the busy flag to clear -- perhaps it will help you.
Here's the working Spin routine:
pubwaitbusy | addr'' Reads busy flag and cursor address'' -- returns cursor address when busy flag has cleareddira[db7..db4] := %0000' make buss pins inputsouta[rs] := 0' command modeouta[rw] := 1' readrepeatouta[e] := 1' request bf + high nib
addr := ina[db7..db4] << 4' bf + high nib of addressouta[e] := 0' finish nib readouta[e] := 1' request low nibble
addr |= ina[db7..db4] ' low nib of addressouta[e] := 0while (addr & %1000_0000) ' check busy flagreturn addr
And here's my PASM conversion:
' waits for busy flag to clear' -- leaves cursor address in "crsrpos"
wait_busy andndira, bussmask ' make buss pins inputsandnouta, rsmask ' low (command)orouta, rwmask ' high (read)
:loop orouta, emask ' e pin highmov delay, #1' 1us delaycall #us_delay
mov tmp1, ina' get bf + high bits of address and tmp1, bussmask ' mask off non-buss pinsshr tmp1, db4pin ' align lsbshl tmp1, #4' move to high nib positionmov crsrpos, tmp1 ' copy to resultandnouta, emask ' e pin lowmov delay, #1' 1us delay call #us_delay
orouta, emask ' e pin highmov delay, #1' 1us delaycall #us_delay
mov tmp1, ina' get low nib of addressand tmp1, bussmask
shr tmp1, db4pin
or crsrpos, tmp1 ' add low nibandnouta, emask ' e pin lowmov delay, #1' 1us delay call #us_delay
test crsrpos, BIT7 wc' check busy flagif_cjmp #:loop ' wait until busy clears
wait_busy_ret ret
When the object is finished and testing I'll post in ObEx.
The website is german but the manual is in english.
With this tool you can single-step through PASM-code and lookup the value of each long in the COG-RAM.
very helpful for analysing what is going on.
keep the questions coming
best regards
Stefan
if using chrome when you goto your link up top near the address bar, google asks you if you want to translate the page from German. Does a pretty good job. I use chrome to make sense of Chinese/Taiwan/Japan web pages..
I still consider myself something of a noob with the propeller, though I already had experience with assembly in other micros (SX28, 8051, PIC16) when I started, though that also gave me some preconceptions to deal with on the prop. The issues that I had the most trouble wrapping my mind around were working without interrupts, calling subroutines without having a stack to push or pop, literals being limited to less than the full value of the register--having to store a constant value in a variable if it exceeds nine bits, and figuring out how the prop handles indirect addressing through self-modifying code, and memory management between the hub and the cogs. The octothorpe # still manages to bite me on the butt occasionally.
Reading through this thread has also shown me a few tricks that I missed, so it's been a help for me already. One concern I have is your reliance on pre-compiled objects, specifically the FullDuplexSerial object. It's a wonderful object, no doubt, but I vastly prefer building my own objects so I know exactly how it works, and a UART is a really simple routine, good for a beginner, if you don't try to make it too fancy right away.
I go through the same basic routines whenever I pick up a new microcontroller; start be flashing a LED, flashing at a calculated frequency, building a binary LED counter, a ring counter, etc, just to get a feel for manipulating bits. Next I'll try reading pins, measuring a RC circuit and lighting LEDs depending on the time it takes to charge. After that it's usually a UART transmitter (having an o'scope admittedly does make this easier), and once the UART transmitter is displaying "A"s I'll create a string lookup routine to display messages, then a HEX to ASCII routine so I can display a counter, and a HEX to BCD to ASCII routine to see the counters in decimal. Then I get into stuff like a SPI driver for reading an ADC chip, I2C for reading and writing to the EEPROM, and parallel LCD drivers.
And on that note, here's the guts of a routine I managed to whip up yesterday, inspired by this thread. Hopefully the formatting doesn't get mangled again; it looks fine in preview.
{{Parallel LCD Driver
The LCD D4, D5, D6, D7 lines must be connected to sequential pins on prop in the same order
To execute an instruction (CLS, move cursor...):
load the instruction into LCD_Byte
jmpret Return_add,#LCD_Command
To display a character:
load the character into LCD_Byte
jmpret Return_add,#LCD_Text
}}
'-------------------------------------------------------------------------------CON_clkmode = xtal1 + pll16x_xinfreq = 5_000_000
E_Pin = 19
RW_Pin = 18
RS_Pin = 17
D4_Pin = 20
D7_Pin = D4_Pin + 3
LCD_Offset = D4_Pin
'-------------------------------------------------------------------------------PUBMaincognew(@LCD_Init, 0)
'-------------------------------------------------------------------------------DATorg
LCD_Init
ordira,LCD_mask
ordira,E_mask
ordira,RW_mask
ordira,RS_mask
mov LCD_Temp,#%0010' 4-bit modecall #LCD_Send_Nibble
mov LCD_Byte,#%0010_1000' 4-bit mode, 2-line, 5x8 pixel charactersjmpret Return_add,#LCD_Command
mov LCD_Byte,#%0000_1100' Turn display on, no cursorjmpret Return_add,#LCD_Command
mov LCD_Byte,#%0000_0001' Clear LCDjmpret Return_add,#LCD_Command
'Display_Messages mov LCD_Byte,#"H"jmpret Return_add,#LCD_Text
mov LCD_Byte,#"i"jmpret Return_add,#LCD_Text
mov LCD_Byte,#%1100_0000' Line 2 column 1jmpret Return_add,#LCD_Command
mov LCD_Byte,#"W"jmpret Return_add,#LCD_Text
mov LCD_Byte,#"o"jmpret Return_add,#LCD_Text
mov LCD_Byte,#"l"jmpret Return_add,#LCD_Text
mov LCD_Byte,#"d"jmpret Return_add,#LCD_Text
mov LCD_Byte,#"!"jmpret Return_add,#LCD_Text
jmp #$
'-------------------------------------------------------------------------------
LCD_Command
call #Check_Busy_Flag
' andn outa,RS_mask ' Send a commandjmp #LCD_Prepare_Byte
LCD_Text
call #Check_Busy_Flag
orouta,RS_mask ' Send text
LCD_Prepare_Byte
mov LCD_Temp,LCD_Byte ' Make a copy of the LCD_Byteshr LCD_Temp,#4' Move high nibble into low nibble locationcall #LCD_Send_Nibble ' Send fist nibblemov LCD_Temp,LCD_Byte ' Reload LCD_Bytecall #LCD_Send_Nibble ' Send second nibblejmp Return_add
LCD_Send_Nibble
and LCD_Temp,#$0F' Preserve the low nibbleshl LCD_Temp,#LCD_offset ' Move the low nibble to the LCD pin locationsandnouta,LCD_mask ' Clear the LCD pinsorouta,LCD_Temp ' Update the LCD pinscall #Clock
LCD_Send_Nibble_ret ret'-------------------------------------------------------------------------------
Check_Busy_Flag
andndira,D7_mask ' Make D7 an inputandnouta,RS_mask ' Command modeorouta,RW_mask ' Read mode
:Loop
call #Clock ' Clock the Enable linetest D7_mask,inawz' Read the busy flagcall #Clock ' Clock again for the low nibbleif_nejmp #:Loop ' Loop until busy flag goes lowordira,D7_mask ' Make D7 an outputandnouta,RW_mask ' Write mode
Check_Busy_Flag_ret ret'-------------------------------------------------------------------------------
Clock
orouta,E_mask
mov Delay_cnt,#5' 250ns delaydjnz Delay_cnt,#$
andnouta,E_mask
Clock_ret ret'-------------------------------------------------------------------------------
RS_mask long1<<RS_pin
E_mask long1<<E_pin
RW_mask long1<<RW_pin
D7_mask long1<<D7_pin
LCD_mask long$F<<LCD_Offset
LCD_Byte res1
LCD_Temp res1
Return_add res1
Delay_cnt res1
I had read your OBEX you sited above but could not convert it to PASM successfully. Of course I think I can now! Thanks.
Why do we need the delays you have inserted in the PASM routine?
We need to be able to look at things as we go along. I use the FDS object for its ease of use by a beginner. I stick with using FDS to keep it simple. As beginners we are not capable of creating something like the FDS or even a simpler version right now. May be later.
I could not agree more with you on the difficulties you had getting going with the PASM. I have had pretty much the same problems myself. Good to know that we share that! I am making a special effort to cover these areas in the book in that I am sure beginners will share our experiences.
Why do we need the delays you have inserted in the PASM routine?
According to the HD44780 data sheet (hint, hint), the minimum time before data is ready after the rising edge of the E pin is 160ns (0.16us). As my code has a delay routine that works in microseconds, I'm using the minimum delay; it's more than required which will not hurt anything.
I am sensitive and accepting of the the fact that the data sheets need to be read and understood.
I have/had the data sheet in front of me as I programmed the LCD. The way I read it, it clearly says that there is no wait required for reading the busy flag. And after that all instructions can be executed one after the other, as I understand it, and as worked just fine for my implementation of the LCD. The executions time delays apply only to the initialization sequence. But obviously I have it wrong. What am I not under standing right and where is the information I am skipping or misunderstanding. I feel that this is important to my proper understanding of reading the data sheets and so I ask for your further help.
Look in the timing diagrams. You will see that there is an offset between the low-to-high transition on E and having valid data on the buss. In the docs I'm using -- the original HD44780 data sheet on which most character LCDs are based -- Figure 28 (pdf page 59) shows buss read timing. The delta from E high to data ready is called Tddr; you can find the spec on pdf page 53 -- 160ns max.
Comments
http://www.ganssle.com/debouncing.htm
I take that by this you mean that the delays provided by the instructions execution themselves are never long enough. (including the time your finger takes).
The reference was very interesting but if I had to provide a 1/6 second delay to cover all cases, that did seem onerous.
H
Onerous would be trying to chase down mystery behaviors due to poor/missing debounce methods either electronic or in sofgtware. Debounce the UI. Cost $0.00 in software. In hardware a few cents. Continued sanity, priceless.
Frank
[FONT=Arial, sans-serif]The data appears on the PST.[/FONT]
[FONT=Arial, sans-serif]As set up,the code takes the data in the third byte of a long and reverses the bits. All other bits are erased. Then one erased bit is set. I need to reverse the bits because as my LCD was hooked up to the Propeller, the pins were in the reverse order to what was required.[/FONT]
[FONT=Arial, sans-serif]It is also useful for looking at what the MUX instructions do.[/FONT]
[FONT=Arial, sans-serif]H[/FONT]
[FONT=Lucida Console, monospace][SIZE=2]{{ Program 017 PASM minimum PAR.spin[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]This program is a minimal implementation for two variables and PAR.[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]There are two Cogs in this program, one in SPIN and one in PASM[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Cog 1 in SPIN displays the variables on the console[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Cog 2 in PASM sets the variables [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Finds the location of PAR and moves it to mem1[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Then mem2 is set to mem1 +4. [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]The two variables are transferred to mem1 and mem2[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]and become available to the SPIN environment[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Loop.[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]}} [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]CON[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]_clkmode = xtal1 + pll16x[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]_xinfreq = 5_000_000[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]VAR[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]long eightlongs[3],shared[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]OBJ[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds: "FullDuplexSerial"[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]PUB FirstCog 'displays values on console[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.start(31,30,0,115200) 'start console at 115200 for debug output[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]cognew(@SecondCog, @eightlongs) 'start the second Cog in PASM [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]waitcnt(clkfreq/4+cnt) 'wait 1/4 for everything to stabilize.[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]repeat 'loop [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared:=eightlongs [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx($1) 'home to 0,0[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first value[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first value [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx(" ") 'display first value[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx($0d) 'new line [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared:=eightlongs[1] [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'fds.tx($1) 'home to 0,0[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first value[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first value [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx(" ") 'display first value[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx($0d) 'new line[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared:=eightlongs[2] [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'fds.tx($1) 'home to 0,0[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first value[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first value [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx(" ") 'display first value[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx($d) 'new line[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'fds.dec(eightlongs[1]) 'display second value [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]waitcnt(clkfreq/60+cnt) 'flicker free wait[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'************************************************************************************************ [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]DAT[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]org 0 'start at 0 location in the cog [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]SecondCog 'start point identification[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov mem1, par[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov mem2, mem1 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]add mem2, #4[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov mem3, mem2 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]add mem3, #4[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]loop call #start[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]jmp #loop[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Start[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov dira, setdira [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov timer, onesec '40 000 000[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]:loop djnz timer, #:loop [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov outa, databyte [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]wrlong outa, mem1[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov timer, onesec '40 000 000[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]:loop1 djnz timer, #:loop1[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov outa, databyte[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shl outa, #16 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shr outa, #24 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shl outa, #8 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]ror outa, #8[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]rev outa, #0[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]ror outa, #16 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]wrlong outa, mem2 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov timer, onesec '40 000 000[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]:loop2 djnz timer, #:loop2 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]or outa, enablebit [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]wrlong outa, mem3 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Start_ret ret [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]dataByte long %00000000_00000000_1001_1110_00000000 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]setdira long %00000000_00000111_00000000_0000000[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]SelectBit long %00000000_00000100_00000010_00000000 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]ReadBit long %00000000_00000010_00000000_00000000 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]EnableBit long %00000000_00000001_00000000_00000000 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]onesec long 80_000_00[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mem1 res 1 'first address storage space[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mem2 res 1 'second address storage space[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mem3 res 1[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]timer res 1[/SIZE][/FONT]
Also, your timing loops are confusing. Relative to clkfreq the variable onesec holds the clock count for 1/10th of a second, the comment (40M) suggests 1/2 a second and the actual loop delays for 4/10th of a second. What is it going to be?
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 DAT ... mov timer, onesec '40 000 000 :loop2 djnz timer, #:loop2 ... onesec long 80_000_00
However here is the revised code for the program I posted last time with proper commenting and formatting as requested by kuroneko and stephan. These guys keep me honest!
[FONT=Lucida Console, monospace][SIZE=2]{{ Program 017 PASM minimum PAR.spin[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]This program allow you to look at data manipulations on PST.[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]There are two Cogs in this program, one in SPIN and one in PASM[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Cog 1 in SPIN displays the data on the console[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Cog 2 in PASM sets the data and manupulates it[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Finds the location of PAR and moves it to mem1[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Then mem2 is set to mem1 +4. mem3 is set to mem1+8[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]The data is transferred to mem1, mem2 and mem3 where selected by user[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]and become available to the SPIN environment for display[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Loop.[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]}}[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]CON[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]_clkmode = xtal1 + pll16x[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]_xinfreq = 5_000_000[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]VAR[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]long eightlongs[3],shared[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]OBJ[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds: "FullDuplexSerial"[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]PUB FirstCog 'displays values on console[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.start(31,30,0,115200) 'start console at 115200 for debug output[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]cognew(@SecondCog, @eightlongs) 'start the second Cog in PASM [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]waitcnt(clkfreq/4+cnt) 'wait 1/4 for everything to stabilize.[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'shared:=eightlongs[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]repeat 'loop [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared:=eightlongs [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx($1) 'home to 0,0[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first byte[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display second byte [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display third byte[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display fourth byte[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx(" ") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx($0d) [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared:=eightlongs[1] 'repeat for second long[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'fds.tx($1) [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx(" ") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx($0d)[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared:=eightlongs[2] 'repeat for third long[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'fds.tx($1) [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx(" ") [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]fds.tx($d) [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]waitcnt(clkfreq/60+cnt) 'flicker free wait[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'************************************************************************************************ [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]DAT[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]org 0 'start at 0 location in the cog [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]SecondCog 'start point identification[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov mem1, par 'find par address[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov mem2, mem1 'store it in mem2[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]add mem2, #4 'add 4 to mem1 to get second address[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov mem3, mem1 'store mem1 in mem3[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]add mem3, #8 'add 8 to mem1 to get third address[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]:loop call #start 'repeating loop[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]jmp #:loop '[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Start mov dira, setdira 'set diretion of DIRA [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov outa, databyte 'read data into outa[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]wrlong outa, mem1 'write result into mem1[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov outa, databyte 'read data into outa[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shl outa, #16 'manupulate outa, shift left 16 to clear bits[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shr outa, #24 'manupulate outa, shift right 24 to celar bits[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shl outa, #8 'manupulate outa, move back to original position [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]ror outa, #8 'manupulate outa, rotate to rightmost bits[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]rev outa, #0 'manupulate outa, reverse bits[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]ror outa, #16 'manupulate outa, rotate back to original bits[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]wrlong outa, mem2 'write result into mem[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]or outa, enablebit 'manupulate outa[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]wrlong outa, mem3 'write result into mem[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Start_ret ret [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'various constants I was using in my particular experiments[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]dataByte long %00000110_00011000_10001100_00111000 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]setdira long %00001111_00000111_00001111_00111110[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]SelectBit long %00000000_00000100_00000010_00000000 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]ReadBit long %00000000_00000010_00000000_00000000 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]EnableBit long %00000000_00000001_00000000_00000000 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mem1 res 1 'first address storage space[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mem2 res 1 'second address storage space[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mem3 res 1 'third address storage space[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]timer res 1 'for delays[/SIZE][/FONT]
Currently there are no delays or stored results between the manipulations that are taking place, and thus no way to actually see the results at each step; only the end result in the terminal. Consider breaking this into two exercises, one using an internal memory location, and terminal output with additional shared locations to hold/display the intermediate results (with additional text labels indicating the output is for___), and a second using outa, long delays, and perhaps a VERY slow system clock rate so that the results of each manipulation can be seen in the leds. With the caveat the user understands this is only for seeing the effects of the instructions in question as a learning exercise, and not a normal use of outa in practice.
Frank
@Harprit: Wouldn't the following sequence be easier to understand?
and outx, mask ' isolate required byte rev outx, #{32 -}8 ' reverse data ... mask long $FF << 8
My problem is that I am not conversant or comfortable with binary manipulations
I need to write that chapter now
This was suggested to me earlier but I did not take the advise as I should have.
Same ole same ole.
Will spend time on binary chapter in the next week or so to see if I cant learn something.
Needs getting done.
Harprit
And, or, not, xor, rol, ror, shl, shr, mux (for the prop, and is a cool instruction), rev (again for the prop), are the core of assembly language.
All of these are not very complex. It's the use cases and short cuts they bring to the table that makes all the difference in the world. Of those the "and, or, shx" instructions see near constant use. They are the ones that break longs into chunks that one can work with and make decisions on.
http://www.math.grin.edu/~rebelsky/Courses/152/97F/Readings/student-binary
I would add to that, bit, nibble, byte, word, long, hex, octal, decimal notations and conversions.
[FONT=Arial, sans-serif]Here is what I found specially as being specially relevant to a beginner.[/FONT]
[FONT=Arial, sans-serif]Binary mathematics are not particularly difficult. However, you have to pay exquisite detail to what you are doing, because beginners do not have a good feel for things that happen as we shift registers to the left and to the right and reverse bits to manipulate the I/O to get the results that we are seeking. It is best to lay it out on paper as you go along.[/FONT]
[FONT=Arial, sans-serif]At the level that I am working, I am not quite ready to add the shorthand notation that adds even more power to binary manipulations. That absolutely has to come later as the comfort level increases.[/FONT]
[FONT=Arial, sans-serif]Here is the code for activating a 2 x 16 character liquid crystal display with a standard Hitachi controller. The code is not particularly long, which surprised me, and is not particularly complicated once one figures out what needs to be done. How long it takes to figure out what needs to be done is a whole other matter complicated by that fact that the Hitachi controller manual has some difficult phraseology in it and some of the help material on the internet has mistakes in it.[/FONT]
[FONT=Arial, sans-serif]I am still not comfortable with the routine that reads the busy bit. Experts please examine and advise. Seems to me that I should not need a delay in this routine.[/FONT]
[FONT=Arial, sans-serif]Here is the code[/FONT]
[FONT=Lucida Console, monospace][SIZE=2]{{ Program 019 PASM 2x16 LCD[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]PASM interface for 2x16 LCD[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]This program is a minimal implementation for a 2x16 LCD in PASM[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]There are two Cogs in this program, one in SPIN and one in PASM[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Cog 1 in SPIN starts PASM Cog[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Cog 2 in PASM sets the LCD up and displays 32 character fill.[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Connections are[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]pin 13 lcd 11 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]pin 14 lcd 12 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]pin 15 lcd 13[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]pin 16 lcd 14[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]pin 17 lcd 6 enable[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]pin 18 lcd 5 read/write[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]pin 19 lcd 4 select reg[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]ground lcd 3[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]power 5V lcd 2[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]ground lcd 1[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]}}[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]CON[/SIZE][/FONT] _clkmo[FONT=Lucida Console, monospace][SIZE=2]de = XTAL1 + PLL16x[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]_xinfreq = 5_000_000[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]PUB FirstCog 'displays values on console[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]cognew(@SecondCog, 0) 'start the second Cog in PASM [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]waitcnt(clkfreq/4+cnt) 'wait 1/4 for everything to stabilize. [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]repeat 'loop [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]DAT[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]org 0 'start at 0 location in the cog [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]SecondCog 'start point identification[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov dira, setdira[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov del_time, delay_sec 'startup delay[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #delay[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]:loop call #startLCD [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov del_time, delay_sec [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #delay [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]jmp #:loop[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]StartLCD [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov databits, bits0000_0011 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #sendinstr [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov del_time, delay5ms [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #delay [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov databits, bits0000_0011 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #sendinstr[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov databits, bits0000_0011 [/SIZE][/FONT] call #sendinst[FONT=Lucida Console, monospace][SIZE=2]r[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov databits, bits0000_0010 'enable 4 bit mode, interface not set. [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #sendinstr [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'ooooooooooooooooo[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov databits, bits0010_1000 'interface now set to 4 bits [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #sendinstr2[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov databits, bits0000_0010 'turn on display [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #sendinstr2 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov databits, bits0000_0110 'cursor motion[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #sendinstr2 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov databits, bits0000_1111 'cursor selection [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #sendinstr2 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov databits, bits0000_0001 'clear display[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #sendinstr2[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov del_time, delay_sec [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #delay [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov del_time, delay_sec [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #delay [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'ooooooooooooooooo[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'send out characters to the LCD [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov counter, #39[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov databits, charA [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #sendchar [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]:loop add databits, #264 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #sendchar [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]sub counter, #1 wz [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]if_nz jmp #:loop[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov counter, #16[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov databits, charQ [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #sendchar [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]:loop1 add databits, #264 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #sendchar [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]sub counter, #1 wz [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]if_nz jmp #:loop1 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]StartLCD_ret ret [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Toggle or outa, enablebit 'hi[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov del_time, #5[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #delay [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]andn outa, enablebit 'lo[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Toggle_ret ret[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]CheckBusyBit[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov dira, inputs[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]or outa, readbit 'hi [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]andn outa, selectbit 'low[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]:loop andn ina, enablebit [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov del_time, delay160us [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #delay [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]andn ina, busymask wz 'or ' outa, enablebit [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]if_nz jmp #:loop[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov dira, setdira[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]CheckBusyBit_ret ret[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'sends instruction as two 4 bit nibbles, high first[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]SendInstr2[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #CheckBusyBit[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov outa, databits [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]andn outa, selectbit 'low[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]andn outa, readbit 'lo[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #toggle [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov del_time, delay46us[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #delay[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov outa, databits [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shl outa, #4 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]andn outa, selectbit 'low[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]andn outa, readbit 'lo[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #toggle [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov del_time, delay46us [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #delay [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]SendInstr2_ret ret [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'shifts 4 bits left and send instruction[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]SendInstr[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #CheckBusyBit [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov outa, databits[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shl outa, #4 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]andn outa, selectbit 'low[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]andn outa, readbit 'lo[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #toggle [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov del_time, delay46us [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #delay [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]SendInstr_ret ret [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]Sendchar[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #CheckBusyBit [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov outa, databits [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]or outa, selectbit 'hi [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]andn outa, readbit 'lo [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #toggle [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov del_time, delay46us [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #delay [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov outa, databits [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]shl outa, #4 [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]or outa, selectbit 'hi [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]andn outa, readbit 'lo[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #toggle [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov del_time, delay46us [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #delay [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]SendChar_ret ret[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]delay[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]:loop djnz del_time, #:loop[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]delay_ret ret [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]delay_sec long 5_000_000[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]delay20ms long 1_600_000[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]delay5ms long 400_000[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]delay160us long 12_800[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]delay100us long 8_000[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]delay46us long 3_680[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]delay1us long 80[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]SetDira long %00000000_00001111_1111_1111_00000000[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]inputs long %00000000_00000111_0000_0000_00000000[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]bits0000_0001 long %00000000_00000000_0000_0001_00000000 'clear [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]bits0000_0010 long %00000000_00000000_0000_0010_00000000 'home [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]bits0000_0011 long %00000000_00000000_0000_0011_00000000 'clear and home[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]bits0000_0110 long %00000000_00000000_0000_0110_00000000 'cursor inc, diaploy stays[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]bits0000_1111 long %00000000_00000000_0000_1110_00000000 'displ on, cursor on, blink off [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]bits0001_1100 long %00000000_00000000_0001_1100_00000000 'cursor shift right [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]bits0010_1000 long %00000000_00000000_0010_1000_00000000 '4 bits, 2 lines, 5x7 dots[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]bits1000_0000 long %00000000_00000000_1000_0000_00000000 'busy flag read [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]bits0000_0000 long %00000000_00000000_0000_0000_00000000 'zero[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]charA long %00000000_00000000_0100_0001_00000000 ' "A"[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]charQ long %00000000_00000000_0101_0001_00000000 ' "Q"[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]SelectBit long %00000000_00000100_00000000_00000000 'control bits[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]ReadBit long %00000000_00000010_00000000_00000000 'control bits [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]EnableBit long %00000000_00000001_00000000_00000000 'control bits [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]busyMask long %11111111_11111111_01111111_11111111 'busy bit mask[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]databits res 1[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]del_time res 1[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]temp res 1[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]counter res 1[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]alpha_count res 1[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]'oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo[/SIZE][/FONT]
[FONT=Lucida Console, monospace]Harprit
[/FONT]
CheckBusyBit mov dira, inputs or outa, readbit 'hi andn outa, selectbit 'low [COLOR="red"]:loop andn ina, enablebit [/COLOR] mov del_time, delay160us call #delay [COLOR="red"]andn ina, busymask wz[/COLOR] 'or ' outa, enablebit if_nz jmp #:loop mov dira, setdira CheckBusyBit_ret ret
The first line should probably work on outa given that enablebit is a mask which is previously set for output (i.e. inputs & enablebit <> 0) and not be part of the loop. As for the second line, ina needs to in the source slot to be useful here. I'd suggest:test bits1000_0000, ina wz
under the assumption that busy means not equal zero. Later you might want to get rid of the loop and simply use:waitpne bits1000_0000, bits1000_0000 ' wait for high/low transition
H
A good thing to look at is a typical college text, how the architecture is approached for a controller, then getting into ASM and internal peripherals.
I enjoy teaching the 8051 mainly because of the text - It's extremely important that the CPU & internal hardware is covered since ASM/Machine code ties in so closely to the internals. For the 8051 I use this text - check it out as to a sample approach.
http://www.amazon.com/8051-Microcontroller-Embedded-Systems-2nd/dp/013119402X/ref=sr_1_1?ie=UTF8&qid=1315882829&sr=8-1
-Martin
Please do not expect a college text from me. I have neither the expertise of the desire to do a college text. I hope this will be an introduction for hobbyists, no more no less. I hope it will be an adequate one. So a detailed discussion of the architecture etc does not seem to be in the cards.
Those interested will take it from there.
H
I got to thinking that maybe a delay is needed to allow the
loop andn ina, enablebit
instruction to complete. Am I right on this?
Still seems odd to me.
H
andn ina, busymask wz
will always set the Z flag. You're using ina in the wrong slot (src vs dst). That's why I suggested this earlier:test bits1000_0000, ina wz
[FONT=Arial, sans-serif]I tried what you suggested but just could not get it to work.[/FONT]
[FONT=Arial, sans-serif]However this does work[/FONT]
[FONT=Lucida Console, monospace][SIZE=2]CheckBusyBit[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov dira, inputs[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]or outa, readbit 'hi [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]andn outa, selectbit 'low[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]:loop mov temp, ina[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]andn outa, enablebit 'lo[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]or outa, enablebit 'hi [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov del_time, delay160us [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]call #delay[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]test bits1000_0000, temp wz [/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]if_nz jmp #:loop[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]mov dira, setdira[/SIZE][/FONT] [FONT=Lucida Console, monospace][SIZE=2]CheckBusyBit_ret ret[/SIZE][/FONT]
[FONT=Arial, sans-serif]But I still need the delay and the delay cannot be less[/FONT][FONT=Arial, sans-serif]I still cannot get it right in my mind.[/FONT]
As a matter of fact the only thing that matters is the delay.
Everything else can be deleted. So the BUSY flag is not being read
[FONT=Arial, sans-serif]HSS[/FONT]
I need someone to explain it in detail to me.
What should be set to what when etc. or a code listing would help.
Everything works fine with a delay but tha's not the goal here.
H
After that if I read ina into temp can I isolate the bit from that? I am having difficulty with that. Apparently I am doing something wrong.
H
I haven't finished porting my [ working ] Spin LCD driver to PASM, but this is the port of the code that waits for the busy flag to clear -- perhaps it will help you.
Here's the working Spin routine:
pub waitbusy | addr '' Reads busy flag and cursor address '' -- returns cursor address when busy flag has cleared dira[db7..db4] := %0000 ' make buss pins inputs outa[rs] := 0 ' command mode outa[rw] := 1 ' read repeat outa[e] := 1 ' request bf + high nib addr := ina[db7..db4] << 4 ' bf + high nib of address outa[e] := 0 ' finish nib read outa[e] := 1 ' request low nibble addr |= ina[db7..db4] ' low nib of address outa[e] := 0 while (addr & %1000_0000) ' check busy flag return addr
And here's my PASM conversion:
' waits for busy flag to clear ' -- leaves cursor address in "crsrpos" wait_busy andn dira, bussmask ' make buss pins inputs andn outa, rsmask ' low (command) or outa, rwmask ' high (read) :loop or outa, emask ' e pin high mov delay, #1 ' 1us delay call #us_delay mov tmp1, ina ' get bf + high bits of address and tmp1, bussmask ' mask off non-buss pins shr tmp1, db4pin ' align lsb shl tmp1, #4 ' move to high nib position mov crsrpos, tmp1 ' copy to result andn outa, emask ' e pin low mov delay, #1 ' 1us delay call #us_delay or outa, emask ' e pin high mov delay, #1 ' 1us delay call #us_delay mov tmp1, ina ' get low nib of address and tmp1, bussmask shr tmp1, db4pin or crsrpos, tmp1 ' add low nib andn outa, emask ' e pin low mov delay, #1 ' 1us delay call #us_delay test crsrpos, BIT7 wc ' check busy flag if_c jmp #:loop ' wait until busy clears wait_busy_ret ret
When the object is finished and testing I'll post in ObEx.
if using chrome when you goto your link up top near the address bar, google asks you if you want to translate the page from German. Does a pretty good job. I use chrome to make sense of Chinese/Taiwan/Japan web pages..
Reading through this thread has also shown me a few tricks that I missed, so it's been a help for me already. One concern I have is your reliance on pre-compiled objects, specifically the FullDuplexSerial object. It's a wonderful object, no doubt, but I vastly prefer building my own objects so I know exactly how it works, and a UART is a really simple routine, good for a beginner, if you don't try to make it too fancy right away.
I go through the same basic routines whenever I pick up a new microcontroller; start be flashing a LED, flashing at a calculated frequency, building a binary LED counter, a ring counter, etc, just to get a feel for manipulating bits. Next I'll try reading pins, measuring a RC circuit and lighting LEDs depending on the time it takes to charge. After that it's usually a UART transmitter (having an o'scope admittedly does make this easier), and once the UART transmitter is displaying "A"s I'll create a string lookup routine to display messages, then a HEX to ASCII routine so I can display a counter, and a HEX to BCD to ASCII routine to see the counters in decimal. Then I get into stuff like a SPI driver for reading an ADC chip, I2C for reading and writing to the EEPROM, and parallel LCD drivers.
And on that note, here's the guts of a routine I managed to whip up yesterday, inspired by this thread. Hopefully the formatting doesn't get mangled again; it looks fine in preview.
{{Parallel LCD Driver The LCD D4, D5, D6, D7 lines must be connected to sequential pins on prop in the same order To execute an instruction (CLS, move cursor...): load the instruction into LCD_Byte jmpret Return_add,#LCD_Command To display a character: load the character into LCD_Byte jmpret Return_add,#LCD_Text }} '------------------------------------------------------------------------------- CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 E_Pin = 19 RW_Pin = 18 RS_Pin = 17 D4_Pin = 20 D7_Pin = D4_Pin + 3 LCD_Offset = D4_Pin '------------------------------------------------------------------------------- PUB Main cognew(@LCD_Init, 0) '------------------------------------------------------------------------------- DAT org LCD_Init or dira,LCD_mask or dira,E_mask or dira,RW_mask or dira,RS_mask mov LCD_Temp,#%0010 ' 4-bit mode call #LCD_Send_Nibble mov LCD_Byte,#%0010_1000 ' 4-bit mode, 2-line, 5x8 pixel characters jmpret Return_add,#LCD_Command mov LCD_Byte,#%0000_1100 ' Turn display on, no cursor jmpret Return_add,#LCD_Command mov LCD_Byte,#%0000_0001 ' Clear LCD jmpret Return_add,#LCD_Command 'Display_Messages mov LCD_Byte,#"H" jmpret Return_add,#LCD_Text mov LCD_Byte,#"i" jmpret Return_add,#LCD_Text mov LCD_Byte,#%1100_0000 ' Line 2 column 1 jmpret Return_add,#LCD_Command mov LCD_Byte,#"W" jmpret Return_add,#LCD_Text mov LCD_Byte,#"o" jmpret Return_add,#LCD_Text mov LCD_Byte,#"l" jmpret Return_add,#LCD_Text mov LCD_Byte,#"d" jmpret Return_add,#LCD_Text mov LCD_Byte,#"!" jmpret Return_add,#LCD_Text jmp #$ '------------------------------------------------------------------------------- LCD_Command call #Check_Busy_Flag ' andn outa,RS_mask ' Send a command jmp #LCD_Prepare_Byte LCD_Text call #Check_Busy_Flag or outa,RS_mask ' Send text LCD_Prepare_Byte mov LCD_Temp,LCD_Byte ' Make a copy of the LCD_Byte shr LCD_Temp,#4 ' Move high nibble into low nibble location call #LCD_Send_Nibble ' Send fist nibble mov LCD_Temp,LCD_Byte ' Reload LCD_Byte call #LCD_Send_Nibble ' Send second nibble jmp Return_add LCD_Send_Nibble and LCD_Temp,#$0F ' Preserve the low nibble shl LCD_Temp,#LCD_offset ' Move the low nibble to the LCD pin locations andn outa,LCD_mask ' Clear the LCD pins or outa,LCD_Temp ' Update the LCD pins call #Clock LCD_Send_Nibble_ret ret '------------------------------------------------------------------------------- Check_Busy_Flag andn dira,D7_mask ' Make D7 an input andn outa,RS_mask ' Command mode or outa,RW_mask ' Read mode :Loop call #Clock ' Clock the Enable line test D7_mask,ina wz ' Read the busy flag call #Clock ' Clock again for the low nibble if_ne jmp #:Loop ' Loop until busy flag goes low or dira,D7_mask ' Make D7 an output andn outa,RW_mask ' Write mode Check_Busy_Flag_ret ret '------------------------------------------------------------------------------- Clock or outa,E_mask mov Delay_cnt,#5 ' 250ns delay djnz Delay_cnt,#$ andn outa,E_mask Clock_ret ret '------------------------------------------------------------------------------- RS_mask long 1<<RS_pin E_mask long 1<<E_pin RW_mask long 1<<RW_pin D7_mask long 1<<D7_pin LCD_mask long $F<<LCD_Offset LCD_Byte res 1 LCD_Temp res 1 Return_add res 1 Delay_cnt res 1
I had read your OBEX you sited above but could not convert it to PASM successfully. Of course I think I can now! Thanks.
Why do we need the delays you have inserted in the PASM routine?
H
We need to be able to look at things as we go along. I use the FDS object for its ease of use by a beginner. I stick with using FDS to keep it simple. As beginners we are not capable of creating something like the FDS or even a simpler version right now. May be later.
I could not agree more with you on the difficulties you had getting going with the PASM. I have had pretty much the same problems myself. Good to know that we share that! I am making a special effort to cover these areas in the book in that I am sure beginners will share our experiences.
I'll take a careful look at your code. Thanks
HSS.
According to the HD44780 data sheet (hint, hint), the minimum time before data is ready after the rising edge of the E pin is 160ns (0.16us). As my code has a delay routine that works in microseconds, I'm using the minimum delay; it's more than required which will not hurt anything.
Disregard, I see you're past that.
I am sensitive and accepting of the the fact that the data sheets need to be read and understood.
I have/had the data sheet in front of me as I programmed the LCD. The way I read it, it clearly says that there is no wait required for reading the busy flag. And after that all instructions can be executed one after the other, as I understand it, and as worked just fine for my implementation of the LCD. The executions time delays apply only to the initialization sequence. But obviously I have it wrong. What am I not under standing right and where is the information I am skipping or misunderstanding. I feel that this is important to my proper understanding of reading the data sheets and so I ask for your further help.
H