-
+;======================================================================
+; NMRA DATA TO TRACK - also, initially deals with all incoming RS232
+;
+;======================================================================
+; TESTING INSTRUCTIONS
+;
; can be tested with liberator's mic input:
; 1k1, 110k resistor divider from track gives 1/100 track
; voltage to mic input
; perl -pe '$_= m/\-/ ? "_" : "~"' <t.dat | fold -290 | perl -pe 's/$/\n\n\n/' >u
; in an xterm showing font "tiny" and then resized to eg 295x54
; less u
+;
+;======================================================================
-; pin 21 (per-pic-led, RD2/PSP2/C1IN) states:
-; high H = green, low L = red, float Z = black
-
-
-
- include /usr/share/gputils/header/p18f458.inc
- radix dec
+clock equ mclock ; this part runs really only on master
-clock equ mclock
- include ../iwjpictest/clockvaries.inc
+ include common.inc
+ udata_acs
-NMRACTRL equ 0x4 ; byte 4: state relevant to NMRA control
-TRANSMITBIT equ 0x7 ; bit 7: 0/1 bit currently being transmitted
-NEXTACTION equ 0x6 ; bit 6: change polarity on next interrupt y/n
+nmractrl res 1 ; byte 4: state relevant to NMRA control
+transmitbit res 1 ; bit 7: 0/1 bit currently being transmitted
+nextaction res 1 ; bit 0: change polarity on next interrupt y/n
-FROMSERIAL equ 0x1 ; byte 1: from-serial buffer location (in BSR5)
-TOTRACK equ 0x2 ; byte 2: to-track buffer location (in BSR5)
-TOTRACKBIT equ 0x3 ; byte 3: bit location of pointer within byte
+fromserial res 1 ; from-serial buffer location (in buffer bank)
+totrack res 1 ; to-track buffer location (in buffer bank)
+totrackbit res 1 ; bit location of pointer within byte
-BUFFERPAGE equ 5
+bufferpage equ 5
- extern led_green
- extern led_red
- extern led_black
-
- ifdef SLOW_VERSION
- messg "hello this is the slow version"
- endif
-
- ifndef SLOW_VERSION
- messg "hello this is the fast version"
- endif
-
- ifdef SLOW_VERSION
- messg "with an if"
- else
- messg "and an else"
- endif
+ udata bufferpage << 256
+buffers res
- org 0
- goto initialise
-
-;****************************************************************************
-
-; high priority interrupt
-
- org 000008h
- goto interrupt_high
-
-; low priority interrupt
-
- org 000018h
- goto interrupt_low
-
-;****************************************************************************
-
- code
+ code
;****************************************************************************
;****************************************************************************
-initialise
-
+serial_init
; serial set-up
-
; initial config - TXSTA register p181
bcf TXSTA,6,0 ; p181, set 8-bit mode
bsf TXSTA,5,0 ; transmit enable
; set SPBRG to get correct baud rate according to table top right p186
; (Tosc = 20MHz, desired baud rate = 9600)
movlw_movwf_spbrg
+ return
- debug 0x0A ; LF to terminak
- debug 'a' ; write 'a' to serial port
-;----------------------------------------------------------------------------
+serial_interrupts_init
+ mov_lw ~((1<<RCIP) | (1<<TXIP))
+ and_wf IPR1 ; serial interrupts: low priority
+ mov_lw (1<<RCIE) | (1<<TXIE)
+ ior_wf PIE1 ; serial interrupt: interrupt enable
+ return
+;----------------------------------------------------------------------------
-; timer 0 set-up
-; LED pin (21) initialisation
bcf TRISE,4,0 ; turn off PSPMODE (Data Sheet p100/101)
+ ; fixme eh ? where should this go ?
-
+nmra_init
+; timer 0 set-up
; timer0 initial config for NMRA timer
ifdef SLOW_VERSION
; initialise buffers (for BSR5, for nmra from-serial/to-track buffers)
- movlw BUFFERPAGE
+ movlw bufferpage
movwf BSR,0 ; set BSR to point to buffer page
- clrf NMRACTRL,0 ; for bits relevant to control of nmra stream
- clrf FROMSERIAL,0 ; for loc'n of write-from-usart ptr in buffers
- clrf TOTRACK,0 ; for loc'n of send-to-track ptr in buffers
+ clrf nmractrl,0 ; for bits relevant to control of nmra stream
+ clrf fromserial,0 ; for loc'n of write-from-usart ptr in buffers
+ clrf totrack,0 ; for loc'n of send-to-track ptr in buffers
; all in access bank
; initialise next action/transmit bit
- bsf NMRACTRL,NEXTACTION,0
- bsf NMRACTRL,TRANSMITBIT,0
+ bsf nmractrl,nextaction,0
+ bsf nmractrl,transmitbit,0
-; initialise TOTRACKBIT bitmask
+; initialise totrackbit bitmask
movlw 0x80
- movwf TOTRACKBIT,0 ; make bit mask be 1000 0000
+ movwf totrackbit,0 ; make bit mask be 1000 0000
; initialise booster direction
bcf TRISC,0,0 ; make pin 0 (booster direction) output
bsf PORTC,1,0 ; booster pwm high
bcf TRISC,1,0 ; make pin 1 (booster pwm) output
- bcf PORTB,2,0 ; booster shutdown L
- bcf TRISB,2,0 ; booster shutdown not-Z
-
- bcf PORTB,0,0 ; user fault L or Z
-
debug 'd' ; write 'd' to serial port
;----------------------------------------------------------------------------
; interrupt set-up
-; globally enable interrupts - p77
- bsf RCON,7,0 ; enable priority levels
- bsf INTCON,7,0 ; enable high-priority interrupts
- bsf INTCON,6,0 ; enable low-priority interrupts
-
-; interrupt set-up for serial receive
- bcf IPR1,5,0 ; set to low-priority interrupt
- bsf PIE1,5,0 ; enable USART receive interrupt (p85)
-
; interrupt set-up for timer0 interrupt p79/80
- bcf INTCON2,2,0 ; timer0 overflow low priority
+ bsf INTCON2,2,0 ; timer0 overflow high priority
bsf INTCON,5,0 ; enable timer0 interrupts
debug 'e' ; write 'e' to serial port
-;****************************************************************************
-
- call led_green
-main_loop_led
- goto main_loop_led
-
-;****************************************************************************
-
-interrupt_high
- debug 'H'
- goto panic
+ return
;****************************************************************************
-interrupt_low
-
-; check which interrupt. Branch to serial_receive or timer or return
-
- debug '*' ; write 'f' to serial port
- btfsc INTCON,2,0 ; check whether timer0 interrupt set
- goto timer0_interrupt
- debug 'g' ; write 'g' to serial port
- btfsc PIR1,5,0 ; check whether serial recv interrupt bit set
- goto serial_receive
- debug 'L'
- goto panic
-
-; if 2 interrupts are set at once the 2nd will generate a new
-; interrupt on leaving the interrupt routine
-; *** we hope and trust -iwj
+nmra_serialrx_intrl
+ bt_f_if0 PIR1,5,0 ; check whether serial recv interrupt bit set
+ return
+fixme need to check both interrupt handlers here and look for refies too
-;****************************************************************************
+ ; serial_receive:
-serial_receive
; debug 'h' ; write 'h' to serial port
btfsc RCSTA,FERR,0 ; if FERR set (= framing error), then panic
goto panic
btfsc RCSTA,OERR,0 ; if OERR set (= overrun error), then panic
goto panic
- movff FROMSERIAL,FSR0L ; set low byte of INDF0 pointer
- movlw BUFFERPAGE
+ movff fromserial,FSR0L ; set low byte of INDF0 pointer
+ movlw bufferpage
movwf FSR0H,0 ; set high byte of INDF0 pointer
; debug '1' ; write 'h' to serial port
movff RCREG,INDF0 ; copy to received register
; If not, move to next byte
btfss INDF0,7,0 ; check if bit 7 is set
- incf FROMSERIAL,1,0 ; advance FROMSERIAL pointer by 1 byte
+ incf fromserial,1,0 ; advance fromserial pointer by 1 byte
; debug '4' ; write 'h' to serial port
bcf PIR1,RCIF,0 ; unset interrupt
- retfie 1
+ goto intrl_handled_nostack
; *** I *think* the interrupt bit is cleared by reading out of RCREG
; but this may be something to try in debugging if stuff doesn't work
advance_write_buffer
-; clear low 4 bits of FROMSERIAL and increment top 4 bits
+; clear low 4 bits of fromserial and increment top 4 bits
; aaaabbbb -> bbbbaaaa -> bbbb(aaaa+1) -> 0000(aaaa+1) -> (aaaa+1)0000
debug '5' ; write 'h' to serial port
- swapf FROMSERIAL,1,0
- incf FROMSERIAL,1,0
+ swapf fromserial,1,0
+ incf fromserial,1,0
movlw 0xF
- andwf FROMSERIAL,1,0
- swapf FROMSERIAL,1,0
+ andwf fromserial,1,0
+ swapf fromserial,1,0
; clear bit 6 (will set back to buffer 0 if has overflowed to 4)
debug '6' ; write 'h' to serial port
- bcf FROMSERIAL,6,0
+ bcf fromserial,6,0
return
;****************************************************************************
-timer0_interrupt
+nmra_interrupt_timer
+ bt_f_if0 INTCON,2,0 ; check whether timer0 interrupt set
+ return
+ ; timer0 interrupt
debug ',' ; write 'j' to serial port
bcf INTCON,2,0 ; clear interrupt-set bit
debug 'k' ; write 'k' to serial port
; check next action - if 0, change to 1 and return
- btfsc NMRACTRL,NEXTACTION,0
+ btfsc nmractrl,nextaction,0
goto toggle_output
- bsf NMRACTRL,NEXTACTION,0
+ bsf nmractrl,nextaction,0
debug '1' ; write 'k' to serial port
retfie 1
mid_bit
debug 'm' ; write 'm' to serial port
- btfsc NMRACTRL,TRANSMITBIT,0
- bsf NMRACTRL,NEXTACTION,0
- btfss NMRACTRL,TRANSMITBIT,0
- bcf NMRACTRL,NEXTACTION,0
+ btfsc nmractrl,transmitbit,0
+ bsf nmractrl,nextaction,0
+ btfss nmractrl,transmitbit,0
+ bcf nmractrl,nextaction,0
debug '2' ; write 'k' to serial port
retfie 1
; check whether current to-track buffer = current from-serial buffer
; if yes, transmit 1s (set transmitbit=1, nextaction=1 and return)
- movff FROMSERIAL,WREG
- xorwf TOTRACK,0,0
+ movff fromserial,WREG
+ xorwf totrack,0,0
andlw 0x30
bnz read_from_buffer
- bsf NMRACTRL,TRANSMITBIT,0
- bsf NMRACTRL,NEXTACTION,0
+ bsf nmractrl,transmitbit,0
+ bsf nmractrl,nextaction,0
debug '3'
bsf TRISB,0,0 ; user fault Z (red)
retfie 1
; if currently on bit 7, want to skip to bit 6
;*** wouldn't it be easier to start on bit 6 ? :-) -iwj
- btfsc TOTRACKBIT,7,0
- rrncf TOTRACKBIT,1,0 ; rotate mask right
+ btfsc totrackbit,7,0
+ rrncf totrackbit,1,0 ; rotate mask right
; if not on bit 7 ,
-; set na=cb=bit value, advance bit (i.e. rotate TRANSMITBIT right),
+; set na=cb=bit value, advance bit (i.e. rotate transmitbit right),
; check if bit7, if so, advance byte, return
debug 'p'
- movff TOTRACK,FSR1L ; set low byte of IND1 pointer
- movlw BUFFERPAGE
+ movff totrack,FSR1L ; set low byte of IND1 pointer
+ movlw bufferpage
movwf FSR1H,0 ; set high byte of IND1 pointer
movff INDF1,WREG
- andwf TOTRACKBIT,0,0 ; select bit to be transmitted
+ andwf totrackbit,0,0 ; select bit to be transmitted
bz zero_bit_to_track
bra one_bit_to_track
debug '_' ; write 'q' to serial port
debug '0' ; write 'q' to serial port
debug '_' ; write 'q' to serial port
- bcf NMRACTRL,TRANSMITBIT,0
- bcf NMRACTRL,NEXTACTION,0
+ bcf nmractrl,transmitbit,0
+ bcf nmractrl,nextaction,0
goto advance_bit
one_bit_to_track
debug '_' ; write 'q' to serial port
debug '1' ; write 'r' to serial port
debug '_' ; write 'q' to serial port
- bsf NMRACTRL,TRANSMITBIT,0
- bsf NMRACTRL,NEXTACTION,0
+ bsf nmractrl,transmitbit,0
+ bsf nmractrl,nextaction,0
goto advance_bit
; rotate transmitbit to next position
debug 's' ; write 's' to serial port
- rrncf TOTRACKBIT,1,0 ; rotate mask right
+ rrncf totrackbit,1,0 ; rotate mask right
;*** surely rrnc (`rotate right not through carry' I assume)
;*** will leave a copy of the top bit in the N flag ? Then you
;*** can use branch if negative. -iwj
- btfsc TOTRACKBIT,7,0
+ btfsc totrackbit,7,0
call advance_pointer
debug '5' ; write 's' to serial port
; currently on bit 7 of the byte, after having read rest of byte to
; track; check whether it is 1 or 0
- movff TOTRACK,FSR1L
- movlw BUFFERPAGE
+ movff totrack,FSR1L
+ movlw bufferpage
movwf FSR1H,0
; if set, move to next buffer
btfsc INDF1,7,0
call advance_read_buffer
-; if not set, move to next byte of samebuffer (increment TOTRACK)
-; (will be on bit 7 at this point anyway so no need to change TOTRACKBIT)
+; if not set, move to next byte of samebuffer (increment totrack)
+; (will be on bit 7 at this point anyway so no need to change totrackbit)
btfss INDF1,7,0
- incf TOTRACK,1,0
+ incf totrack,1,0
return
advance_read_buffer
; move pointer to next buffer
-; clear low 4 bits of TOTRACK and increment top 4 bits
+; clear low 4 bits of totrack and increment top 4 bits
; aaaabbbb -> bbbbaaaa -> bbbb(aaaa+1) -> 0000(aaaa+1) -> (aaaa+1)0000
debug '7' ; write 'v' to serial port
- swapf TOTRACK,1,0
- incf TOTRACK,1,0
+ swapf totrack,1,0
+ incf totrack,1,0
movlw 0xF
- andwf TOTRACK,1,0
- swapf TOTRACK,1,0
+ andwf totrack,1,0
+ swapf totrack,1,0
debug '8' ; write 'v' to serial port
; clear bit 6 (will set back to buffer 0 if has overflowed to 4)
- bcf TOTRACK,6,0
+ bcf totrack,6,0
debug '9' ; write 'v' to serial port
return
;****************************************************************************
- end
+ include final.inc