transmitting byte.
include /usr/share/gputils/header/p18f458.inc
-NMRACTRL equ 0x0 ; byte 0: state relevant to NMRA control
+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
; bcf T0CON,0,0 ; } (not-testing)
bsf T0CON,2,0 ; }
- bcf T0CON,1,0 ; } prescale value 1:32
- bsf T0CON,0,0 ; } (testing)
+ bcf T0CON,1,0 ; } prescale value 1:16
+ bcf T0CON,0,0 ; } (testing)
debug 'b' ; write 'b' to serial port
;----------------------------------------------------------------------------
bsf INTCON,6,0 ; enable low-priority interrupts
; interrupt set-up for serial receive
- bsf IPR1,5,0 ; set to low-priority interrupt
+ 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
;****************************************************************************
interrupt_high
+ debug 'H'
goto panic
;****************************************************************************
; check which interrupt. Branch to serial_receive or timer or return
- debug 146 ; write 'f' to serial port
- btfss PIR1,5,0 ; check whether serial recv interrupt bit set
+ debug '*' ; write 'f' to serial port
+ btfsc PIR1,5,0 ; check whether serial recv interrupt bit set
goto serial_receive
- debug 147 ; write 'g' to serial port
- btfss INTCON,2,0 ; check whether timer0 interrupt set
+ debug 'g' ; write 'g' to serial port
+ btfsc INTCON,2,0 ; check whether timer0 interrupt set
goto timer0_interrupt
+ debug 'L'
goto panic
; if 2 interrupts are set at once the 2nd will generate a new
;****************************************************************************
serial_receive
- debug 148 ; write 'h' to serial port
+ debug 'h' ; write 'h' to serial port
movff FROMSERIAL,FSR0L ; set low byte of INDF0 pointer
movlw 5
movwf FSR0H,0 ; set high byte of INDF0 pointer
+ debug '1' ; write 'h' to serial port
movff RCREG,INDF0 ; copy to received register
+ debug '2' ; write 'h' to serial port
incf FROMSERIAL,1,0 ; advance FROMSERIAL pointer by 1 byte
+ debug '3' ; write 'h' to serial port
; *** check for overrun and do something sensible
- btfss RCREG,7,0 ; check if bit 7 is set
+ btfss INDF0,7,0 ; check if bit 7 is set
+ debug '4' ; write 'h' to serial port
call advance_write_buffer ; if so, move to next buffer
+ debug '5' ; write 'h' to serial port
retfie 1
; *** I *think* the interrupt bit is cleared by reading out of RCREG
advance_write_buffer
- debug 149 ; write 'i' to serial port
+ debug 'i' ; write 'i' to serial port
; check if on 1st byte of new buffer anyway (i.e. last 4 bits = 0)
movf FROMSERIAL,0,0 ; copy FROMSERIAL pointer location to W
andlw 0xF ; investigate last 4 bits
timer0_interrupt
- debug 150 ; write 'j' to serial port
+ debug ',' ; write 'j' to serial port
bcf INTCON,2,0 ; clear interrupt-set bit
movlw 0x01 ; (testing)
; movlw 0x6E ; (not-testing)
movwf TMR0L,0 ; set timer0 to 0x6E (so interrupt takes 58us)
- debug 151 ; write 'k' to serial port
+ debug 'k' ; write 'k' to serial port
; check next action - if 0, change to 1 and return
btfsc NMRACTRL,NEXTACTION,0
goto toggle_output
; if next action = 1, then toggle output
toggle_output
- debug 152 ; write 'l' to serial port
+ debug 'l' ; write 'l' to serial port
btg PORTC,0,0 ; toggle booster output pin
btfss PORTC,0,0
goto decide_next_bit
; nextaction in preparation for 2nd half of bit and then return
mid_bit
- debug 153 ; write 'm' to serial port
+ debug 'm' ; write 'm' to serial port
btfsc NMRACTRL,TRANSMITBIT,0
bsf NMRACTRL,NEXTACTION,0
btfss NMRACTRL,TRANSMITBIT,0
decide_next_bit
- debug 154 ; write 'n' to serial port
+ debug 'n' ; write 'n' to serial port
; check whether current to-track buffer = current from-serial buffer
; if yes, transmit 1s (set transmitbit=1, nextaction=1 and return)
- movff FROMSERIAL,W
+ movff FROMSERIAL,WREG
xorwf TOTRACK,0,0
andlw 0x30
bnz read_from_buffer
read_from_buffer
- debug 155 ; write 'o' to serial port
+ debug 'o' ; write 'o' to serial port
; if currently on bit 7, want to skip to bit 6
;*** wouldn't it be easier to start on bit 6 ? :-) -iwj
- btfss TOTRACKBIT,7,0
+ 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),
; check if bit7, if so, advance byte, return
- debug 156 ; write 'p' to serial port
+ debug 'p' ; write 'p' to serial port
movff TOTRACK,FSR1L ; set low byte of IND1 pointer
movlw 5
movwf FSR1H,0 ; set high byte of IND1 pointer
- movff INDF1,W
+ movff INDF1,WREG
andwf TOTRACKBIT,0,0 ; mask out bit to be transmitted
;*** to `mask out' means to clear, eg
;*** if you were to `mask out bit 0 of 0xff' you'd get 0xfe
bra one_bit_to_track
zero_bit_to_track
- debug 157 ; write 'q' to serial port
+ debug 'q' ; write 'q' to serial port
bcf NMRACTRL,TRANSMITBIT,0
bcf NMRACTRL,NEXTACTION,0
goto advance_bit
one_bit_to_track
- debug 158 ; write 'r' to serial port
+ debug 'r' ; write 'r' to serial port
bsf NMRACTRL,TRANSMITBIT,0
bsf NMRACTRL,NEXTACTION,0
goto advance_bit
advance_bit
; rotate transmitbit to next position
- debug 159 ; write 's' to serial port
+ debug 's' ; write 's' to serial port
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
- btfss TOTRACKBIT,7,0
+ btfsc TOTRACKBIT,7,0
call advance_pointer
retfie 1
advance_pointer
- debug 160 ; write 't' to serial port
+ debug 't' ; write 't' 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 5
movwf FSR1H,0
- movff INDF1,W
- andlw 0x80
-;*** bit test bit 7 of INDF1 ? That's simpler than load into W and AND. -iwj
-
- bnz advance_read_buffer
+ btfsc INDF1,7,0
+ bra advance_read_buffer
bra advance_read_byte
advance_read_buffer
- debug 161 ; write 'u' to serial port
+ debug 'u' ; write 'u' to serial port
;*** I suggest swapping this and advance_read_byte round, since
;*** advance_read_byte is a more `inner' bit of the `loop' -iwj
; move pointer to next buffer
; check if on 1st byte of new buffer anyway (i.e. last 4 bits = 0)
- movff TOTRACK,W ; copy TOTRACK pointer location to W
+ movff TOTRACK,WREG ; copy TOTRACK pointer location to W
andlw 0xF ; investigate last 4 bits
; if zero (i.e. overflowed to next buffer), branch to overflow check
; write na=cb=1 and return
- bra one_bit_to_track
+; bra one_bit_to_track
;*** oh, we always introduce a one bit in between ? *confused* -iwj
; (will be on bit 7 at this point anyway so no need to change TOTRACKBIT)
incf TOTRACK,1,0
+ retfie 1
; set na=cb=new bit value
- movff TOTRACK,FSR1L ; set low byte of IND1 pointer
- movlw 5
- movwf FSR1H,0 ; set high byte of IND1 pointer
- movff INDF1,W
- andwf TOTRACKBIT,0,0 ; mask out bit to be transmitted
+; movff TOTRACK,FSR1L ; set low byte of IND1 pointer
+; movlw 5
+; movwf FSR1H,0 ; set high byte of IND1 pointer
+; movff INDF1,WREG
+; andwf TOTRACKBIT,0,0 ; mask out bit to be transmitted
;*** This is the same code as the 2nd stanza in read_from_buffer,
;*** above. Surely it should be made common (eg a subroutine) ? -iwj
- bz zero_bit_to_track
- bra one_bit_to_track
+; bz zero_bit_to_track
+; bra one_bit_to_track
;*** zero_bit_to_track and one_bit_to_track end up calling advance_bit -
;*** is that right ? *confused* -iwj
panic
- bcf INTCON,7,0 ; disable high-priority interrupts
- bcf INTCON,6,0 ; disable low-priority interrupts
+ debug 'x'
+ clrf INTCON,0 ; disable all interrupts EVER
+ debug 'y'
bcf PORTC,1,0 ; switch off booster
-panic_loop
+ debug 'z'
call led_red
+panic_loop
goto panic_loop
;****************************************************************************
include /usr/share/gputils/header/p18f458.inc
-NMRACTRL equ 0x0 ; byte 0: state relevant to NMRA control
+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
; bcf T0CON,0,0 ; } (not-testing)
bsf T0CON,2,0 ; }
- bcf T0CON,1,0 ; } prescale value 1:32
- bsf T0CON,0,0 ; } (testing)
+ bcf T0CON,1,0 ; } prescale value 1:16
+ bcf T0CON,0,0 ; } (testing)
debug 'b' ; write 'b' to serial port
;----------------------------------------------------------------------------
bsf INTCON,6,0 ; enable low-priority interrupts
; interrupt set-up for serial receive
- bsf IPR1,5,0 ; set to low-priority interrupt
+ 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
;****************************************************************************
interrupt_high
+ debug 'H'
goto panic
;****************************************************************************
; check which interrupt. Branch to serial_receive or timer or return
- debug 146 ; write 'f' to serial port
- btfss PIR1,5,0 ; check whether serial recv interrupt bit set
+ debug '*' ; write 'f' to serial port
+ btfsc PIR1,5,0 ; check whether serial recv interrupt bit set
goto serial_receive
- debug 147 ; write 'g' to serial port
- btfss INTCON,2,0 ; check whether timer0 interrupt set
+ debug 'g' ; write 'g' to serial port
+ btfsc INTCON,2,0 ; check whether timer0 interrupt set
goto timer0_interrupt
+ debug 'L'
goto panic
; if 2 interrupts are set at once the 2nd will generate a new
;****************************************************************************
serial_receive
- debug 148 ; write 'h' to serial port
+ debug 'h' ; write 'h' to serial port
movff FROMSERIAL,FSR0L ; set low byte of INDF0 pointer
movlw 5
movwf FSR0H,0 ; set high byte of INDF0 pointer
+ debug '1' ; write 'h' to serial port
movff RCREG,INDF0 ; copy to received register
+ debug '2' ; write 'h' to serial port
incf FROMSERIAL,1,0 ; advance FROMSERIAL pointer by 1 byte
+ debug '3' ; write 'h' to serial port
; *** check for overrun and do something sensible
- btfss RCREG,7,0 ; check if bit 7 is set
+ btfss INDF0,7,0 ; check if bit 7 is set
+ debug '4' ; write 'h' to serial port
call advance_write_buffer ; if so, move to next buffer
+ debug '5' ; write 'h' to serial port
retfie 1
; *** I *think* the interrupt bit is cleared by reading out of RCREG
advance_write_buffer
- debug 149 ; write 'i' to serial port
+ debug 'i' ; write 'i' to serial port
; check if on 1st byte of new buffer anyway (i.e. last 4 bits = 0)
movf FROMSERIAL,0,0 ; copy FROMSERIAL pointer location to W
andlw 0xF ; investigate last 4 bits
timer0_interrupt
- debug 150 ; write 'j' to serial port
+ debug ',' ; write 'j' to serial port
bcf INTCON,2,0 ; clear interrupt-set bit
movlw 0x01 ; (testing)
; movlw 0x6E ; (not-testing)
movwf TMR0L,0 ; set timer0 to 0x6E (so interrupt takes 58us)
- debug 151 ; write 'k' to serial port
+ debug 'k' ; write 'k' to serial port
; check next action - if 0, change to 1 and return
btfsc NMRACTRL,NEXTACTION,0
goto toggle_output
; if next action = 1, then toggle output
toggle_output
- debug 152 ; write 'l' to serial port
+ debug 'l' ; write 'l' to serial port
btg PORTC,0,0 ; toggle booster output pin
btfss PORTC,0,0
goto decide_next_bit
; nextaction in preparation for 2nd half of bit and then return
mid_bit
- debug 153 ; write 'm' to serial port
+ debug 'm' ; write 'm' to serial port
btfsc NMRACTRL,TRANSMITBIT,0
bsf NMRACTRL,NEXTACTION,0
btfss NMRACTRL,TRANSMITBIT,0
decide_next_bit
- debug 154 ; write 'n' to serial port
+ debug 'n' ; write 'n' to serial port
; check whether current to-track buffer = current from-serial buffer
; if yes, transmit 1s (set transmitbit=1, nextaction=1 and return)
- movff FROMSERIAL,W
+ movff FROMSERIAL,WREG
xorwf TOTRACK,0,0
andlw 0x30
bnz read_from_buffer
read_from_buffer
- debug 155 ; write 'o' to serial port
+ debug 'o' ; write 'o' to serial port
; if currently on bit 7, want to skip to bit 6
;*** wouldn't it be easier to start on bit 6 ? :-) -iwj
- btfss TOTRACKBIT,7,0
+ 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),
; check if bit7, if so, advance byte, return
- debug 156 ; write 'p' to serial port
+ debug 'p' ; write 'p' to serial port
movff TOTRACK,FSR1L ; set low byte of IND1 pointer
movlw 5
movwf FSR1H,0 ; set high byte of IND1 pointer
- movff INDF1,W
+ movff INDF1,WREG
andwf TOTRACKBIT,0,0 ; mask out bit to be transmitted
;*** to `mask out' means to clear, eg
;*** if you were to `mask out bit 0 of 0xff' you'd get 0xfe
bra one_bit_to_track
zero_bit_to_track
- debug 157 ; write 'q' to serial port
+ debug 'q' ; write 'q' to serial port
bcf NMRACTRL,TRANSMITBIT,0
bcf NMRACTRL,NEXTACTION,0
goto advance_bit
one_bit_to_track
- debug 158 ; write 'r' to serial port
+ debug 'r' ; write 'r' to serial port
bsf NMRACTRL,TRANSMITBIT,0
bsf NMRACTRL,NEXTACTION,0
goto advance_bit
advance_bit
; rotate transmitbit to next position
- debug 159 ; write 's' to serial port
+ debug 's' ; write 's' to serial port
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
- btfss TOTRACKBIT,7,0
+ btfsc TOTRACKBIT,7,0
call advance_pointer
retfie 1
advance_pointer
- debug 160 ; write 't' to serial port
+ debug 't' ; write 't' 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 5
movwf FSR1H,0
- movff INDF1,W
- andlw 0x80
-;*** bit test bit 7 of INDF1 ? That's simpler than load into W and AND. -iwj
-
- bnz advance_read_buffer
+ btfsc INDF1,7,0
+ bra advance_read_buffer
bra advance_read_byte
advance_read_buffer
- debug 161 ; write 'u' to serial port
+ debug 'u' ; write 'u' to serial port
;*** I suggest swapping this and advance_read_byte round, since
;*** advance_read_byte is a more `inner' bit of the `loop' -iwj
; move pointer to next buffer
; check if on 1st byte of new buffer anyway (i.e. last 4 bits = 0)
- movff TOTRACK,W ; copy TOTRACK pointer location to W
+ movff TOTRACK,WREG ; copy TOTRACK pointer location to W
andlw 0xF ; investigate last 4 bits
; if zero (i.e. overflowed to next buffer), branch to overflow check
; write na=cb=1 and return
- bra one_bit_to_track
+; bra one_bit_to_track
;*** oh, we always introduce a one bit in between ? *confused* -iwj
; (will be on bit 7 at this point anyway so no need to change TOTRACKBIT)
incf TOTRACK,1,0
+ retfie 1
; set na=cb=new bit value
- movff TOTRACK,FSR1L ; set low byte of IND1 pointer
- movlw 5
- movwf FSR1H,0 ; set high byte of IND1 pointer
- movff INDF1,W
- andwf TOTRACKBIT,0,0 ; mask out bit to be transmitted
+; movff TOTRACK,FSR1L ; set low byte of IND1 pointer
+; movlw 5
+; movwf FSR1H,0 ; set high byte of IND1 pointer
+; movff INDF1,WREG
+; andwf TOTRACKBIT,0,0 ; mask out bit to be transmitted
;*** This is the same code as the 2nd stanza in read_from_buffer,
;*** above. Surely it should be made common (eg a subroutine) ? -iwj
- bz zero_bit_to_track
- bra one_bit_to_track
+; bz zero_bit_to_track
+; bra one_bit_to_track
;*** zero_bit_to_track and one_bit_to_track end up calling advance_bit -
;*** is that right ? *confused* -iwj
panic
- bcf INTCON,7,0 ; disable high-priority interrupts
- bcf INTCON,6,0 ; disable low-priority interrupts
+ debug 'x'
+ clrf INTCON,0 ; disable all interrupts EVER
+ debug 'y'
bcf PORTC,1,0 ; switch off booster
-panic_loop
+ debug 'z'
call led_red
+panic_loop
goto panic_loop
;****************************************************************************