; ; keysleds.inc: key and led handling ; ; Lights up the leds in ledbus according to ; the bits in memory location leds_busa_1, ; leds_busa_2 and leds_busb_1. Additionally ; reads the pressed key from keybus. The pressed ; key is stored in memory location last_key as ; a key code defined in constants.h. ; ; author: Marko Kanala, raato ]a t[ mulletronic.com ; ; 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). ; do_keysleds: ; call pattern display 12 times / column to light up the ; pattern display leds ; note: pattern display column mux ; is tied to same port as key/led mux decf led_scaler bn change_led_column bra do_patterndisplay change_led_column: btfss PORT_KEYBUS, KEYBUS_A_PIN bra check_key_b ; decode keybus a movlw KEY_S1 ; bus a starts from step key 1 addwf led_counter, W ; store pressed key in bus a movwf irq_key check_key_b: btfss PORT_KEYBUS, KEYBUS_B_PIN bra keys_checked ; key in keybus b was pressed ; decode keybus b movlw KEY_BANKA ; bus b starts from bank a key addwf led_counter, W movwf lp_irq_temp ; store to temp ; check specially for keys that can be held down movlw KEY_SHIFTFUNC cpfseq lp_irq_temp ; is the bus b key shift ? bra not_shift bsf irq_downkey, DOWNKEY_SHIFTFUNC bra keys_checked not_shift: movlw KEY_CLEAR ; clear ? cpfseq lp_irq_temp bra not_clear bsf irq_downkey, DOWNKEY_CLEAR bra keys_checked not_clear: movlw KEY_LASTSTEP ; laststep? cpfseq lp_irq_temp bra not_laststep bsf irq_downkey, DOWNKEY_LASTSTEP bra keys_checked not_laststep: movlw KEY_INSTRSEL ; instrsel ? cpfseq lp_irq_temp bra not_instrsel bsf irq_downkey, DOWNKEY_INSTRSEL bra keys_checked not_instrsel: movlw KEY_SHUFFLEFLAM ; shuffleflam ? cpfseq lp_irq_temp bra not_downkey bsf irq_downkey, DOWNKEY_SHUFFLEFLAM bra keys_checked ; note: downkeys do NOT generate key events ; and must be checked separately if so ; desired not_downkey: ; store pressed key in bus b movff lp_irq_temp, irq_key keys_checked: ; if we're in the last key of the bus process the keypress(es) movlw 15 cpfseq led_counter bra keys_done ; compare the current key with last key movlw KEY_NONE ; key pressed ? xorwf irq_key, W btfsc STATUS, Z bra irq_no_key ; nope movf irq_key, W ; new key pressed ? xorwf last_key, W btfsc STATUS, Z bra lk_no_new_key ; nope ; current key differs movf irq_key, W movwf last_key movwf keypress ; generate key event bsf event, EVENT_KEY bra irq_keycheckdone irq_no_key: clrf last_key ; no key was pressed clrf keypress bra irq_keycheckdone lk_no_new_key: clrf irq_key ; no NEW key was pressed irq_keycheckdone: ; get the pressed downkeys movff irq_downkey, downkeys ; clear downkey temp for next round clrf irq_downkey keys_done: ; increment led counter and rollover at 16 incf led_counter movlw 16 cpfslt led_counter ; last led / key clrf led_counter ; reset pattern display scaler counter movlw 11 movwf led_scaler ; bsf port_ledbus, pat_disp_lit_pin ; clear lit pd movlw -8 addwf led_counter, W ; W = led_counter - 8 bn first_half ; second half of the leds lfsr FSR0, leds_busa_2 bra go_leds first_half: ; check for lit leds in first half lfsr FSR0, leds_busa_1 movf led_counter, W ; W = led_counter go_leds: call get_bit movwf led_counter_tmp ; store "bit-byte" ; switch off bus a led bsf PORT_LEDBUS, LEDBUS_A_PIN ; W = bit, note that we advance to bus b with post-increment andwf POSTINC0, W bz bus_a_not_lit ; led lit in bus a bcf PORT_LEDBUS, LEDBUS_A_PIN bus_a_not_lit: movf led_counter_tmp, W ; switch off bus b led bsf PORT_LEDBUS, LEDBUS_B_PIN ; W = bit andwf INDF0, W bz bus_b_not_lit ; led lit in bus b bcf PORT_LEDBUS, LEDBUS_B_PIN bus_b_not_lit: ; retain upper 4 bits of led mux (pattern display) and ; select the correct column from led 4067 swapf led_scaler, W iorwf led_counter, W movwf LAT_LEDMUX ; set pattern display immediately on column change bra do_patterndisplay
get_bit