; ; irq_hipri.inc: high priority interrupt handling ; ; bpm ticks, trigger falling edge and midi signals. ; ; 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). ; hp_irq: movwf hp_irq_wtmp movff STATUS, hp_irq_statustmp movff BSR, hp_irq_bsrtmp ; which interrupt occurred ? hp_check_irq: ; USART receive interrupt ? (midi sync) btfsc PIR1, RCIF bra hp_irq_midi_in ; ccp1 interrupt ? (din sync) btfsc PIR1, CCP1IF bra hp_irq_din_tick ; timer 1 interrupt ? (internal clock) btfsc PIR1, TMR1IF bra hp_irq_bpm_tick ; trigger / din falling edge interrupt ? btfsc PIR2, TMR3IF bra hp_irq_trig_end movff hp_irq_bsrtmp, BSR movf hp_irq_wtmp, W movff hp_irq_statustmp, STATUS retfie ; ; external din sync tick ; hp_irq_din_tick: ; bypass din input if set off IFSETTINGOFF SETTING_DIN_IN, hp_irq_din_tick_stopped ; if we are syncing to midi ignore din sync IFEVENT EVENT_MIDIRUN, hp_irq_din_tick_stopped ; check if run/stop is up ? call hp_irq_check_dinsync IFNOEVENT EVENT_DINRUN, hp_irq_din_tick_stopped ; echo sync to din out ; call din_clock IFSETTINGONCALL SETTING_DIN_OUT, din_clock ; din sync 24 ppqn, so call player twice call player_tick call player_tick ; send midi clock ; call midi_out_clock IFSETTINGONCALL SETTING_MIDIS_OUT, midi_out_clock hp_irq_din_tick_stopped: ; clear interrupt bcf PIR1, CCP1IF bra hp_check_irq ; ; internal clock tick (note: 48ppqn) ; hp_irq_bpm_tick: ; if we are syncing to midi or din ignore internal ticks IFEVENT EVENT_MIDIRUN, hp_irq_bpm_done IFEVENT EVENT_DINRUN, hp_irq_bpm_done ; send syncs out if applicable IFNOTINMODE MODE_RUN, hp_irq_bpm_tick_cont movlw 1 andwf bpmtick, W bnz hp_irq_bpm_tick_cont ; send din clock ;call din_clock IFSETTINGONCALL SETTING_DIN_OUT, din_clock ; send midi clock ;call midi_out_clock IFSETTINGONCALL SETTING_MIDIS_OUT, midi_out_clock ; note: sync start/stop is set in 9090.inc hp_irq_bpm_tick_cont: ; player_tick gets called 48 ppqn call player_tick hp_irq_bpm_skip: ; store table pointers movff TBLPTRH, hp_irq_tblptrh movff TBLPTRL, hp_irq_tblptrl movff TABLAT, hp_irq_tablat ; reset timer 1 according to ; tempo value movf tempo, W clrf TBLPTRH bcf STATUS, C rlcf WREG, W ; tempo * 2 btfsc STATUS, C incf TBLPTRH ; +$100 if >127 addlw bpm_table & 0xff movwf TBLPTRL movlw bpm_table >> 8 addwfc TBLPTRH, F TBLRD*+ ; read high byte and increment movff TABLAT, TMR1H TBLRD* ; read low byte movff TABLAT, TMR1L ; restore table pointers movff hp_irq_tblptrl, TBLPTRL movff hp_irq_tblptrh, TBLPTRH movff hp_irq_tablat, TABLAT hp_irq_bpm_done: ; clear interrupt bcf PIR1, TMR1IF bra hp_check_irq ; ; midi in (midi clock in) ; hp_irq_midi_in: ; if we are slaving to din sync, ignore midi ; note: this should not be skipped anymore because ; midi is listened for more than the sync ; IFEVENT EVENT_DINRUN, hp_irq_midi_ignore call midi_handlemidi hp_irq_midi_ignore: ; clear interrupt bcf PIR1, RCIF bra hp_check_irq ; ; trigger width timer, we should clear triggers ; hp_irq_trig_end: call player_trig_off ; clear interrupt bcf PIR2, TMR3IF bra hp_check_irq ; ; handles the din sync run/stop checking ; ; note: this function does not get called if din sync input ; is set off hp_irq_check_dinsync: ; check if run/stop in din sync is clear (+5 sent) ? btfsc DIN_IN_PORT, DIN_IN_STARTSTOP_PIN bra hp_irq_nodinrun ; din was running, just started ? IFNOEVENT EVENT_DINRUN, hp_irq_dimrun_started return hp_irq_dimrun_started: ; din sync started call player_start SETEVENT EVENT_DINRUN return hp_irq_nodinrun: ; din is stopped but DINRUN-event was set ; => din sync was stopped IFEVENT EVENT_DINRUN, hp_irq_nodinrun_reset return hp_irq_nodinrun_reset: call player_stop CLEAREVENT EVENT_DINRUN return
hp_irq_check_dinsync player_tick midi_handlemidi player_trig_off player_start player_stop