; ; keyboard.inc: handles the "cell phone" style quick ; text input ; ; author: Marko Kanala, raato ]a t[ mulletronic.com ; enters the naming mode - step keys are used in the ; same way as the sms writing in cell phones ie. ; step key 1 == abc ; step key 2 == def ; ... ; step key 9 == number ; step key 14 == delete char ; step key 15 == previous char ; step key 16 == next char ; enter == done ; ; LICENSE ; Creative Commons Attribution-NonCommercial-ShareALike 2.5 ; ; You are free: ; ; * to copy, distribute, display, and perform the work ; * to make derivative works ; ; Under the following conditions: ; ; 1. Attribution. You must attribute the work in the manner specified by the ; author or licensor. ; 2. Noncommercial. You may not use this work for commercial purposes. ; 3. Share Alike. If you alter, transform, or build upon this work, you may ; distribute the resulting work only under a license identical to this one. ; ; * For any reuse or distribution, you must make clear to others the license ; terms of this work. ; * Any of these conditions can be waived if you get permission from the ; copyright holder. ; ; Your fair use and other rights are in no way affected by the above. ; ; This is a human-readable summary of the Legal Code. ; See full license at http://creativecommons.org/licenses/by-nc-sa/2.5/legalcode ; ; Copyright: Marko Kanala (raato@mulletronic.com). ; ; load FSR1 for destination addr keyboard: clrf cursorpos clrf keyboardbuf call lcd_cursor_on ; enable cursor keyboard_loop: ; refresh screen movff FSR1L, temp2 ; backup FSR1 FORCEDISPLAYREFRESH call lcd_refresh movff temp2, FSR1L ; restore FSR1 ; refresh cursor position movf cursorpos, W addlw LCD_LINE1 + 4 call lcd_set_cursor CLEAREVENT EVENT_KEY ; wait for "roll presses" clrf temp keyboard_waitkey: IFEVENT EVENT_KEY, keyboard_gotkey ; if no key event delay call lcd_delay2ms decfsz temp bra keyboard_waitkey ; delay passed without key ; if keyboardbuf has a value we need to advance ; to the next position clrf WREG cpfsgt keyboardbuf bra keyboard_loop ; advance call keyboard_advance ; and clear keyboardbuf clrf keyboardbuf bra keyboard_loop keyboard_gotkey: KEYEVENT KEY_ENTER, keyboard_done ; decode only step keys KEYEVENT KEY_S14, keyboard_delete KEYEVENT KEY_S15, keyboard_prev KEYEVENT KEY_S16, keyboard_next KEYEVENT KEY_S10, keyboard_space ; decode keys 1 - 9 movff keypress, temp movlw KEY_NONE cpfsgt temp bra keyboard_loop ; > KEY_NONE movlw KEY_S10 cpfslt temp bra keyboard_loop ; key 1 - 9 (key 9 == number) ; check if keyboardbuf matches with the keypress movf keyboardbuf, W cpfseq temp bra keyboard_insertnew ; current keypress == previous keypress, roll key characters ; W == keypress call get_keyboard_char ; W == upper limit for character roll movwf temp2 incf INDF1, W ; curr pos char + 1 cpfseq temp2 bra keyboard_setchar ; upper limit reached, roll over movlw "9" + 1 cpfseq temp2 bra keyboard_normalcharroll ; a number, reset to "0" movlw "0" bra keyboard_setchar keyboard_normalcharroll: decf temp, W ; keypress - 1 call get_keyboard_char keyboard_setchar: ; just set the new char without insertion movwf INDF1 bra keyboard_handled keyboard_insertnew: ; if keyboardbuf != 0 we need to advance before inserting tstfsz keyboardbuf call keyboard_advance ; insert at current position movff temp, keyboardbuf ; store keypress to keyboardbuf movlw KEY_S9 cpfseq temp bra keyboard_insertnormal ; a number, insert "0" movlw "0" bra keyboard_doinsert keyboard_insertnormal: decf temp, W ; keypress - 1 call get_keyboard_char keyboard_doinsert: call keyboard_insert keyboard_handled: ; loop until enter pressed CLEAREVENT EVENT_KEY bra keyboard_loop ; advances to cursor to the next position keyboard_advance: movlw 11 ; 12 chars in max cpfslt cursorpos return incf cursorpos incf FSR1L return ; insert a char from WREG to the current position ; note: keyboardbuf gets cleared if there is no space ; for the character keyboard_insert: movwf temp2 ; temp2 == char movff FSR1L, temp ; advance to the last char movf cursorpos, W subwf FSR1L, W addlw 11 movwf FSR1L ; FSR1L + 11 - cursorpos movlw " " cpfseq POSTINC1 ; "pat_name + 12" bra keyboard_insnospace ; shift chars after the insertion position keyboard_insloop: decf FSR1L movf temp, W cpfseq FSR1L bra keyboard_contins ; shift done, insert char movff temp2, INDF1 return keyboard_contins: decf FSR1L movf POSTINC1, W movwf INDF1 bra keyboard_insloop keyboard_insnospace: ; restore FSR1L movff temp, FSR1L clrf keyboardbuf return ; deletes a character at the previous position keyboard_delete: clrf keyboardbuf clrf WREG cpfsgt cursorpos bra keyboard_deletedone movff FSR1L, temp ; backup FSR1L movff cursorpos, temp2 ; pos > 0, delete ok ; shift chars from this position to the left and ; pad right side with " " keyboard_delloop: movlw 12 ; are we done yet ? cpfslt cursorpos bra keyboard_delloopdone movf POSTDEC1, W ; no, move from current to prev movwf POSTINC1 incf FSR1L ; advance to next incf cursorpos bra keyboard_delloop keyboard_delloopdone: ; shift done, insert " " at the end decf FSR1L movlw " " movwf INDF1 decf temp, W movwf FSR1L ; restore FSR1L decf temp2, W movwf cursorpos keyboard_deletedone: CLEAREVENT EVENT_KEY bra keyboard_loop ; moves cursor to previous position keyboard_prev: clrf keyboardbuf CLEAREVENT EVENT_KEY ; cursorpos from 0 to 12 clrf WREG cpfsgt cursorpos bra keyboard_loop decf FSR1L decf cursorpos bra keyboard_loop ; moves cursor to next position keyboard_next: clrf keyboardbuf CLEAREVENT EVENT_KEY call keyboard_advance bra keyboard_loop ; enters a space to the current position keyboard_space: clrf keyboardbuf movlw " " call keyboard_insert call keyboard_advance CLEAREVENT EVENT_KEY bra keyboard_loop ; name enter done! keyboard_done: call lcd_cursor_off return
lcd_cursor_on lcd_refresh lcd_set_cursor lcd_delay2ms keyboard_advance get_keyboard_char keyboard_insert lcd_cursor_off