// Keypad interface // // A to D and weak pull ups constant AD1PCFG% 0xbf809060 constant CPNUE% 0xbf8861e0 // Ports used // INPUT // Port rb0 row 1 // Port rb1 row 2 // Port rb2 row 3 // Port rb3 row 4 // OUTPUT // Port re5 col 1 // Port re6 col 2 // Port re7 col 3 // initialise ports including setting the AtoD channels // to digital function kp_start pokei(AD1PCFG%+8)=0x0f // just set the ones used pokei(CPNUE%+8)=0x3c // weak pull ups on CN5:2 portw "bts" 0x0f // port b 3:0 = i/p portw "etc" 0xe0 // port e 7:5 = o/p portw "eos" 0xe0 // all high endf // scans the keypad by successively lowering the column // and checking port b for not being all high // returns a code based on the input function kp_scan dim i,p% for i = 1 to 3 portb "eoc" 4+i // col 5-7 low portw "bi" p% // get data p%=and(p%,0x0f) portb "eos" 4+i // col 5-7 high breakif p% <> 0x0f next result p%*i*i endf // inserts any keypress into buffer, this relies on the interval // for debounce so needs tuning to application, suggest // start with an interval of 250 function kp_proc_scan dim k k=kp_scan if kp_count > 1 then if k = 240 then kbuf&[kp_ibptr]=kp_value kp_ibptr=kp_ibptr+1 if kp_ibptr>30 then kp_ibptr=1 endif kp_count=0 endif else if k <> 240 then kp_count=kp_count+1 kp_value=k endif endif endf // this returns a value depending on the scan // code, the codes received are, in number order // input 14,56,126,13,52,117,11,44,99,7,28,63 and 240 for no key // output 1,2, 3, 4, 5, 6, 7, 8, 9,10,0, 11 and 12 function kp_translate(scancode&) dim rv, keyp& // only character storage needed dim k&[13] k&[1]=28:k&[2]=14:k&[3]=56:k&[4]=126:k&[5]=13:k&[6]=52 k&[7]=117:k&[8]=11:k&[9]=44:k&[10]=99:k&[11]=7:k&[12]=63 k&[13]=240 // kp_start // for a larger program put this with the other init code for rv = 1 to 13 breakif scancode&=k&[rv] next result rv-1 endf function kp_init_process kp_start dim kp_count=0, kp_value, kp_ibptr=1, kp_obptr=1 dim kbuf&[31] keep endf // checks to see if there is a key in the buffer // retunrs 1 if there is, 0 otherwise function kp_get? dim rv=0 if kp_ibptr <> kp_obptr then rv=1 endif result rv endf // gets 1 key from pad, will not return until // a key is pressed function kp_get dim rv while kp_get?=0:wend // wait rv=kp_translate(kbuf&[kp_obptr]) kp_obptr=kp_obptr+1 if kp_obptr > 30 then kp_obptr =1 endif result rv endf // initialises the globals and starts the process // can be called more than once as vexists prevents duplication function kp_go if vexists("kp_flag")=0 then kp_init_process process kp_proc_scan every 35 // 35 ms debounce keep endif endf