Shop OBEX P1 Docs P2 Docs Learn Events
[Abandoned] Porting keyboard.spin for P2 (keyboard2.spin2) — Parallax Forums

[Abandoned] Porting keyboard.spin for P2 (keyboard2.spin2)

doggiedocdoggiedoc Posts: 2,239
edited 2020-12-24 18:20 in Propeller 2
For the last few days I have spent way too much time trying to get Chip's PS/2 keyboard driver for P1 to compile and work in for P2. I'm starting to think I'm in way over my paygrade.

I've got it to compile in PropTool 2.4 now but it is does not function.

Changes (may not be complete list):
(1)added ( ) to each method

(2)replaced cognew statement:
P1
okay := cog := cognew(@entry, @par_tail) + 1
P2
okay := cog := coginit(COGEXEC_NEW, @entry, @par_tail) + 1

(3)changed pasm subroutines ":" to p2asm "."

(4)replaced movd with setd and par with pa
P1
entry                   movd    :par,#_dpin             'load input parameters _dpin/_cpin/_locks/_auto
                        mov     x,par
                        add     x,#11*4
                        mov     y,#4
:par                    rdlong  0,x
                        add     :par,dlsb
                        add     x,#4
                        djnz    y,#:par
P2
entry                   setd    .par,#_dpin             'load input parameters _dpin/_cpin/_locks/_auto
                        mov     x,pa                                                                          
                        add     x,#11*4
                        mov     y,#4
.par                    rdlong  0,x
                        add     .par,dlsb
                        add     x,#4
                        djnz    y,#.par

(5)edited "data" to "dayta" in each occurrence and "configure" to "cnfigure" because PropTool 2.4 change code blocks incorrectly. (may be other examples)

(6)modified rev
P1
.                       rev     data,#-3 & $1F
P2
.                       rev     dayta
                        zerox   dayta,#-3 & $1F



(7)there is no if_never prefix in p2asm
so this block is troublesome: I removed if_never prefix so it compiles but I don't think it executes properly.
The (if_never replacements) code is part of the original driver
'
'
' Wait for clock/data to be in required state(s)
'
wait_c0                 mov     wcond,c0                '(wait until clock low)

wait                    mov     y,tenms                 'set timeout to 10ms

wloop                   movs    napshr,#18              'nap ~4us
                        call    #nap
_c3                     test    cmask,ina       wc      'check required state(s)
_d4                     test    dmask,ina       wz      'loop until got state(s) or timeout
wcond   if_never        djnz    y,#wloop                '(replaced with c0/c1/c0d0/c1d1)

                        tjz     y,#reset                'if timeout, reset keyboard
wait_ret
wait_c0_ret             ret


c0      if_c            djnz    y,#wloop                '(if_never replacements)
c1      if_nc           djnz    y,#wloop
c0d0    if_c_or_nz      djnz    y,#wloop
c1d1    if_nc_or_z      djnz    y,#wloop


(8) added 2 zero-bytes to shift1, else get "cog symbol must be long-aligned" error
keypad1                 byte    $CA, $C5, $C3, $C7, $C0, 0, $C1, $C4, $C2, $C6, $C9, $0D, "+-*/"

keypad2                 byte    "0123456789.", $0D, "+-*/"

shift1                  byte    "{|}", 0, 0, "~", 0 ,0                  ' ------> add 2 "zero bytes" to long-align

shift2                  byte    $22, 0, 0, 0, 0, "<_>?)!@#$%^&*(", 0, ":", 0, "+"




Any advice or insight would be greatly appreciated!
I've attached the modified file below and demo with supporting files.

Paul

Comments

  • Wuerfel_21Wuerfel_21 Posts: 4,510
    edited 2020-12-22 15:11
    Being semi-familiar with this driver, but not having a P2, i can tell you:

    - PAR must be replaced with PTRA (or was it PTRB?), not PA
    - the line with the if_never is never actually executed, you can just put a NOP there if you really want
    - the way you replaced REV is incorrect, I think. I think the second instruction must be SHR, not ZEROX
    - you might want to re-do all the I/O related stuff, as is it wont work on port B (pins 32..63)

  • @Wuerfel_21 - Thanks! I know I'm in way over my head but it's been a good exercise in learning!

    I had PTRA at first but will change it back. I'll to the NOP you suggested and SHR instead of ZEROX

    I'll have to study up on the I/O changes.

    Thanks again, your expertise is truly appreciated!
  • doggiedocdoggiedoc Posts: 2,239
    edited 2020-12-22 15:34
    Another change I made in this block:

    (9)waitcnt changed to getct ct and add t,ct and waitx t:
    '
    '
    ' Nap
    '
    nap                     rdlong  t,#0                    'get clkfreq
    napshr                  shr     t,#18/16/13             'shr scales time
                            fge     t,#3                    'ensure waitcnt won't snag
                            getct   ct
                            add     t,ct                  'add cnt to time                             ''  ----> added "getct and var ct"  
                            'waitcnt t,#0                    'wait until time elapses (nap)
                            waitx   t
    nap_ret                 ret
    
  • I'm in over my head on this one. I will have to give up at this point.

    Project abandoned.

    Paul
  • I looked at the P1 keyboard code; it's kind of complicated. That said, the P2 tends to make things easier -- once you know its secrets. For example, the first part of the code copies pin numbers from the hub to the code.

    P1
    entry                   movd    :par,#_dpin             'load input parameters _dpin/_cpin/_locks/_auto
                            mov     x,par
                            add     x,#11*4
                            mov     y,#4
    :par                    rdlong  0,x
                            add     :par,dlsb
                            add     x,#4
                            djnz    y,#:par
    

    This how to do it on the P2:
    entry           setq      #4-1                                  ' get 4 parameters from hub
                    rdlong    _dpin, ptra[11]                       ' load input parameters _dpin/_cpin/_locks/_auto
    

    For me, the trick is to spend time looking through Chip's code, and PASM2 drivers written by others to learn these little tricks.
  • I’ve been studying your code in jm_fullduplexserial and I noticed that. I still think I’m in over my head.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2020-12-25 02:13
    One of the first things I did to test out TAQOZ was interface a PS/2 keyboard. Even though they output a clock that's also used for handshaking, normally you can ignore this and just treat the data as an asynch bit stream. All you need to know is the baud rate and you can either autobaud or just measure it once. Since it is crystal locked, it won't change.

    This is the tiny bit of code (50 bytes) I use in TAQOZ to initialize the keyboard and then to receive data from it on a smartpin.
    12250 := kbb --- my keyboard baud rate ( typical 10 KHz to 16.7 KHz but fixed for each keyboard)
    
    --- Init PS/2 mode - setup pin for PS/2 keyboard data
    pri !KEYB			KBDAT PIN 0 WRPIN F R 0EXIT 9 -bit kbb RXD H ;
    
    --- receive PS/2 data from smartpin and right justify
    pri RXKB ( -- scancode )		KBDAT PIN R IF RDPIN 23 >> ELSE 0 THEN >B ;
    


    Where PS/2 gets more complicated is in handling the scancodes, the makes and the breaks, and then generating an ASCII code for that key. I allocate a 256 byte table for the scancode conversion table and simply assign hex values $F1 to $FC for the function keys etc. Altogether including some demo code and the table, the PS/2 "driver" takes 636 bytes.

    Don't give up, just get the basics functional first.
Sign In or Register to comment.