;====================================================================== ; common.inc ; common macros & equs etc. ; generally include this at the top of each file. ;---------------------------------------------------------------------- ; COMMON INCLUDES and BOILERPLATE include p18f458.inc radix dec include panic.inc include morse+auto.inc include ../iwjpictest/insn-aliases.inc include ../iwjpictest/clockvaries.inc include variables+vars.inc include pindata.inc include program+clocks.inc include i2clib.incm tickdiv equ 16 tickdiv_us equ tick_us * tickdiv ;---------------------------------------------------------------------- ; Common conventions for function register notation: ; Master Slave ; Registers etc. ; W Trashed Trashed ; STATUS Trashed Trashed ; BSR Not used Not used ; t,u,v Low ISR Low ISR ; TBLPTR*,TABLAT Low ISR Low ISR ; PROD* Low ISR Low ISR ; FSR0 Low ISR Low ISR ; PCLATU Always set to 0 Not used ; PCLATH Low ISR Not used ; t_dolocal Low ISR High ISR ; FSR1 Low ISR High ISR (detect[1]) ; FSR2 High ISR (nmra[1]) High ISR (detect[1]) ; ; Main loop detection scan detection scan ; High ISR NMRA output I2C service ; Low ISRs everything else everything else ; ; Trashed May be trashed by any routine anywhere. Saved ; during every ISR entry/exit. ; ; Low ISR May be used/trashed by any routine run in low-priority ; interrupt, or any routine run during initialisation. ; May therefore not be used in background loop with ; interrupts enabled. May not be used by high-priority ; ISR (unless explicitly saved, eg isrh_fsr0_{save,restore}). ; ; High ISR May be used/trashed by any routine run in high-priority ; interrupt, or any routine run during initialisation. ; May therefore not be used elsewhere with interrupts ; enabled. ; ; Only the routines specially noted as intended to ; be called from the High ISR are safe. ; ; ... (subsystem) ; Register is reserved for use by this subsystem, which ; is allowed to expect the value to be preserved. ; Anything else which uses it must save and restore (and ; may also need to disable interrupts, depending on its ; relative status). ; ; Not High May be used by any routine not running in high-priority ; interrupt. Not saved by high-priority interrupt ; entry/exit, so any high-priority interrupt routine which ; uses this register must save and restore it. ; ; A routine which is allowed to trash a register may document that it ; saves that register for the benefit of its callers. ; ; [1] FSR1 and FSR2 on slave pics are reserved exclusively for the ; I2C response and detection code (detect.asm), after ; detect_slave_init. Likewise FSR2 is reserved exclusively ; for the NMRA output ISR after nmra_init. ; ; General-purpose hardware allocation: ; ; Master Slave ; Timer 0 nmra Disabled ; Timer 2 tick, int. low - ; Timer 1 - - ; CCP1 - - ; Timer 3 point fire timer point fire timer ; ECCP - - ; ; (...) indicates that this is a projected use, NYI ;---------------------------------------------------------------------- ; Conventional routine names: ; ; _local_do Process a master-to-slave command to activate ; a local peripheral, in High ISR. Also called ; on master in Low ISR to activate its own ; local peripherals. NB strange calling convention! ; ; _local_init Initialises RAM tables for local peripheral ; and arranges for pins to be set in appropriate ; quiescent state. Configures pic built-in ; peripherals. ; ; _local_intrl Low ISR service routine for peripheral (see below). ; ; command_ Called when an appropriate message has been ; received from the host. ; ; _intrl Low ISR service routine. ; Checks for any relevant interrupt. ; If not, just returns. ; If found, services it and then does either ; intrl_handled or intrl_handled_nostack ; neither of which return; the latter is ; faster but implies a promise ; ;---------------------------------------------------------------------- ; MACROS @ macro endm ;---------------------------------------- ; For adding a byte to the debug buffer. ; Not for use in High ISR. In all cases: ; ; STATUS any trashed ; all others any preserved ifndef NDEBUG ;---------- Dv macro ; sorry, but assembler's dw directive isn't case-sensitive ; ; W message byte preserved ; call debugbyte endm ;---------- Dl macro debug_literal_value ; ; W any literal value as specified ; mov_lw debug_literal_value Dv endm ;---------- Df macro debug_register_file_address ; ; W any value from specified memory location ; mov_fw debug_register_file_address Dv endm else Dv macro endm Dl macro debug_literal_value endm Df macro debug_register_file_address endm endif ;---------------------------------------- ; For entering and leaving Low ISR, saving and restoring STATUS and W ; See above under _intrl, and {master,slave}_interrupt_low enter_interrupt_low macro mov_ff STATUS, isr_low_save_status mov_wf isr_low_save_w mov_ff STKPTR, isr_low_save_stkptr endm intrh_fsr0_save macro mov_ff FSR0L, isr_high_save_fsr0 mov_ff FSR0H, isr_high_save_fsr0+1 endm intrh_fsr0_restore macro mov_ff isr_high_save_fsr0, FSR0L mov_ff isr_high_save_fsr0+1, FSR0H endm intrl_handled_core macro ; for internal use only mov_fw isr_low_save_w mov_ff isr_low_save_status, STATUS retfie endm intrl_handled_nostack macro pop ; undo the `call' from the original ISR intrl_handled_core endm intrl_handled macro goto intrl_handled_routine endm ;---------------------------------------- ; For disabling all interrupts, to make a critical section: ; (for use from main program and Low ISR only) ; ; GIEH modified appropriately ; everything else preserved intrh_mask macro bc_f INTCON,GIEH endm intrh_unmask macro bs_f INTCON,GIEH endm ;---------------------------------------- ; For the fix specified in the silicon errata: ; silicon revision B4 issue 4 ; ; Before After ; TABLAT any data from flash ; TBLPTR* correct incremented/decremented ; everything else any preserved tblrd_postinc_fixup macro tblrd *+ dw 0xffff endm tblrd_postdec_fixup macro tblrd *- dw 0xffff endm ;---------------------------------------- ; For setting up TBLPTR load_tblptr macro value ; ; Before After ; TBLPTR* any set ; W, STATUS any undefined ; mov_lw value & 0xff mov_wf TBLPTRL mov_lw value >> 8 mov_wf TBLPTRH if value > 0xffff mov_lw value >> 16 mov_wf TBLPTRU else clr_f TBLPTRU endif endm load_perpic_tblptr macro flash_map_base, perpic_entry_size ; ; Before After ; TBLPTR* any set ; W, STATUS, PROD* any undefined ; everything else any preserved ; mov_lw perpic_entry_size mul_wf picno mov_lw flash_map_base & 0xff add_wfw PRODL mov_wf TBLPTRL mov_lw flash_map_base >> 8 addc_wfw PRODH mov_wf TBLPTRH clr_f TBLPTRU ; TBLPTR* -> our point data endm ;---------------------------------------------------------------------- ; PINSPECS stuff ; ; A PINSPEC is a constant 0x where is a b c d e ; and is 0 1 2 3 4 5 6 7. Generally p__ ; are equ'd for this. radix hex p0_cdu_enable equ 5b p0_rs232_fcin equ 4b p0_booster_shutdown equ 2b p0_booster_overload equ 1b p0_booster_userfault equ 0b p0_spare2 equ 6d p0_spare1 equ 5d p0_rs232_fcout equ 5c pall_perpicled equ 2d pall_pt0reverse equ 7b p0_spare0 equ 0a p0_booster_dirn equ 0c p0_booster_pwm equ 1c radix dec ; ; LAT* may be subject to read-modify-write, see below ; TRIS* may be subject to read-modify-write, see below ; PORT* may be read, see below ; everything else untouched ; ; LAT* TRIS* PORT* ; pin_z untouched set untouched ; pin_h set cleared untouched ; pin_l cleared cleared untouched ; pin_nz untouched cleared untouched ; pin_vh set untouched untouched ; pin_vl cleared untouched untouched ; pin_ifh untouched untouched read ; pin_ifl untouched untouched read pin_z macro pinspec bs_f TRISA + (TRISB-TRISA)*((pinspec-0xa) & 15), pinspec >> 4 endm pin_nz macro pinspec bc_f TRISA + (TRISB-TRISA)*((pinspec-0xa) & 15), pinspec >> 4 endm pin_znz macro pinspec btg_f TRISA + (TRISB-TRISA)*((pinspec-0xa) & 15), pinspec >> 4 endm pin_vh macro pinspec bs_f LATA + (LATB-LATA)*((pinspec-0xa) & 15), pinspec >> 4 endm pin_vl macro pinspec bc_f LATA + (LATB-LATA)*((pinspec-0xa) & 15), pinspec >> 4 endm pin_vhl macro pinspec btg_f LATA + (LATB-LATA)*((pinspec-0xa) & 15), pinspec >> 4 endm pin_h macro pinspec pin_vh pinspec pin_nz pinspec endm pin_l macro pinspec pin_vl pinspec pin_nz pinspec endm pin_ifh macro pinspec bt_f_if1 PORTA + (PORTB-PORTA)*((pinspec-0xa) & 15), pinspec >> 4 endm pin_ifl macro pinspec bt_f_if0 PORTA + (PORTB-PORTA)*((pinspec-0xa) & 15), pinspec >> 4 endm pinlat_ifh macro pinspec bt_f_if1 LATA + (LATB-LATA)*((pinspec-0xa) & 15), pinspec >> 4 endm pinlat_ifl macro pinspec bt_f_if0 LATA + (LATB-LATA)*((pinspec-0xa) & 15), pinspec >> 4 endm ;----------------------------------------------------------------------