chiark / gitweb /
minor changes
authorceb <ceb>
Mon, 3 Jan 2005 19:17:44 +0000 (19:17 +0000)
committerceb <ceb>
Mon, 3 Jan 2005 19:17:44 +0000 (19:17 +0000)
Use bit7 for 'last packet' indicator in NMRA packets, not bit0; changed
in README.protocol and nmra-stream.asm

cebpic/README.protocol
cebpic/nmra-stream.asm
detpic/nmra-stream.asm

index 928fd41ef6f055a6c1ce66c16cebf675614fa821..cbe2672bd86e285a6adbc5612ab6942c4e2b7d13 100644 (file)
@@ -1,10 +1,10 @@
 NMRA packets from the computer to the PIC should consist of 8-bit bytes.
 
-bits 7-1 contain the data to be sent to the track
-bit 0 is 1 if the byte is the last in the packet and 0 otherwise
+bits 6-0 contain the data to be sent to the track
+bit 7 is 1 if the byte is the last in the packet and 0 otherwise
  
 The first 14 data bits in the NMRA packet should be 1s.
-(i.e. the first two complete bytes should be 11111110 11111110)
+(i.e. the first two complete bytes should be 01111111 01111111)
 (packets beginning with some other sequence are reserved for non-NMRA messages)
 
 Maximum NMRA message length = 16 bytes (i.e. 112 bits).
index 51a1b9565f865c919d29fec673b64da461935d7e..6d1592cfcb3acc25ac7fceb41c7c7e7cb4a82031 100644 (file)
@@ -1,19 +1,7 @@
-;ERRORS:
-
-; 1red = high interrupt bit set
-; 2red = low interrupt bit set by something which isn't timer0 or the USART
-
-
 
 ; pin 21 (per-pic-led, RD2/PSP2/C1IN) states: high H = green, low L = red, float Z = black
 
 
-; *******will need to deal with initial short circuit first
-
-
-
-
-
 
         include         /usr/share/gputils/header/p18f458.inc
 
@@ -50,24 +38,6 @@ TOTRACKBIT   equ     0x3     ; byte 3: bit location of pointer within byte
 
 initialise
 
-; 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
-       bsf     PIE1,5,0        ; enable USART receive interrupt (p85)
-       bsf     IPR1,5,0        ; set to low-priority interrupt
-
-; interrupt set-up for timer0 interrupt p79/80
-       bsf     INTCON,5,0      ; enable timer0 interrupts
-       bcf     INTCON2,2,0     ; timer0 overflow low priority
-
-
-;-----------------------------------------------------------------------------------------
-
-
 ; serial set-up
 
 ; initial config - TXSTA register p181
@@ -89,7 +59,7 @@ initialise
 ;-----------------------------------------------------------------------------------------
 
 
-; timer set-up
+; timer set-up
 ; LED pin (21) initialisation
         bcf     TRISE,4,0       ; turn off PSPMODE (Data Sheet p100/101)
 
@@ -108,45 +78,63 @@ initialise
 ; initialise buffers (for BSR5, for nmra from-serial/to-track buffers)
 
        movlw   5
-       movwf   BSR,0           ; set BRS to 5
+       movwf   BSR,0           ; set BSR to 5
 
        clrf    NMRACTRL,0      ; for bits relevant to control of nmra stream
        clrf    FROMSERIAL,0    ; for location of write-from-usart pointer within BSR5
        clrf    TOTRACK,0       ; for location of send-to-track pointer within BSR5
                                ; all in access bank
 
+
 ;-----------------------------------------------------------------------------------------
 
+
+; initialise next action/transmit bit
+       bsf     NMRACTRL,NEXTACTION,0
+       bsf     NMRACTRL,TRANSMITBIT,0
+
+; initialise TOTRACKBIT bitmask
+       movlw   0x80
+       movwf   TOTRACKBIT,0    ; make bit mask be 1000 0000
+
+; initialise booster direction
+       bsf     TRISC,0,0       ; make pin 0 (booster direction) output
+       bcf     PORTC,0,0       ; set low initially
+
 ; set booster pwm high
        bsf     TRISC,1,0       ; make pin 1 (booster pwm) output
        bsf     PORTC,1,0       ; booster pwm high
 
-; *** also need to deal with initial short circuit state ***
 
-; initialise booster direction
-       bsf     TRISC,0,0       ; make pin 0 (booster direction) output
+;-----------------------------------------------------------------------------------------
 
-; initialise next action/transmit bit
-       bsf     NMRACTRL,NEXTACTION,0
-       bsf     NMRACTRL,TRANSMITBIT,0
+; 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
+       bsf     PIE1,5,0        ; enable USART receive interrupt (p85)
+       bsf     IPR1,5,0        ; set to low-priority interrupt
+
+; interrupt set-up for timer0 interrupt p79/80
+       bsf     INTCON,5,0      ; enable timer0 interrupts
+       bcf     INTCON2,2,0     ; timer0 overflow low priority
 
 
 ;*****************************************************************************************
 
 main_loop_led
        call    led_green
-       call    waiting
-       call    led_black
-       call    waiting
-       goto    main_loop_led
+       goto    main_loop_led
 
 
 ;*****************************************************************************************
 
 interrupt_high
-       call    led_red
-       call    waiting
-       retfie  1
+       goto    panic
 
 ;*****************************************************************************************
 
@@ -158,10 +146,11 @@ interrupt_low
        goto    serial_receive
        btfss   INTCON,2,0      ; check whether timer0 interrupt set
        goto    timer0_interrupt
-       call    led_red
-       call    waiting
-       call    led_red
-        retfie  1               ; return from interrupt to main if spurious interrupt
+       goto    panic
+
+; if 2 interrupts are set at once the 2nd will generate a new interrupt on leaving
+; the interrupt routine
+
 
 ;*****************************************************************************************
 
@@ -171,18 +160,18 @@ serial_receive
        movwf   FSR0H,0                 ; set high byte of IND0 pointer
        movff   RCREG,IND0              ; copy to received register
        incf    FROMSERIAL,1,0          ; advance FROMSERIAL pointer by 1 byte
-       btfss   RCREG,0,0               ; check if bit 0 is set
+       btfss   RCREG,7,0               ; check if bit 7 is set
        call    advance_write_buffer    ; if so, move to next buffer
-       call    led_red
-       call    waiting
-       return
+       retfie  1
 
+; *** 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
 
 ; check if on 1st byte of new buffer anyway (i.e. last 4 bits = 0)
-       movff   FROMSERIAL,W    ; copy FROMSERIAL pointer location to W
+       movf    FROMSERIAL,0,0  ; copy FROMSERIAL pointer location to W
        andlw   0xF             ; investigate last 4 bits
 
 ; if zero (i.e. overflowed to next buffer), branch to overflow check
@@ -195,7 +184,7 @@ advance_write_buffer
        movlw   0xF
        andwf   FROMSERIAL,1,0
        swapf   FROMSERIAL,1,0
-       
+
 fromserial_overflow
 ; clear bit 6 (will set back to buffer 0 if has overflowed to 4)
        bcf     FROMSERIAL,6,0
@@ -215,7 +204,7 @@ timer0_interrupt
 ; check next action - if 0, change to 1 and return
        btfsc   NMRACTRL,NEXTACTION,0
        goto    toggle_output
-       bsf     
+       bsf     NMRACTRL,NEXTACTION,0
        retfie  1
 
 
@@ -255,19 +244,14 @@ decide_next_bit
 
 read_from_buffer
 
-; if no, find current to-track byte and bit
-; (and TRANSMITBIT with 0x1)
-
-       movff   TOTRACKBIT,W,0
-       andlw   0x1
+; if currently on bit 7, want to skip to bit 6
 
-; checking whether TRANSMITBIT (bit mask) is at bit 0 
-; (i.e. whether andlw 0x1 is 1 (on bit 0) or 0 (not on bit 0)
+       btfss   TOTRACKBIT,7,0
+       rrncf   TOTRACKBIT,1,0          ; rotate mask right
 
-       bnz     advance_pointer
-
-; if not on bit 0 (i.e. if the and above results in 0), 
-; set na=cb=bit value, advance bit (i.e. rotate TRANSMITBIT left), return
+; 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
 
        movff   TOTRACK,FSR1L           ; set low byte of IND1 pointer
        movlw   5
@@ -281,35 +265,45 @@ read_from_buffer
 zero_bit_to_track
        bcf     NMRACTRL,TRANSMITBIT,0
        bcf     NMRACTRL,NEXTACTION,0
-       call    advance_bit
-       retfie  1
+       goto    advance_bit
        
 one_bit_to_track
        bsf     NMRACTRL,TRANSMITBIT,0
        bsf     NMRACTRL,NEXTACTION,0
-       call    advance_bit
+       goto    advance_bit
+
+
+
+advance_bit
+; rotate tranmitbit to next position 
+
+       rrncf   TOTRACKBIT,1,0          ; rotate mask right
+
+       btfss   TOTRACKBIT,7,0
+       call    advance_pointer
+
        retfie  1
 
 
 
 advance_pointer
 
-; if currently on the last bit of the byte (bit 0), then check whether it is 1 or 0
+; 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,0
-       andlw   0x1
+       andlw   0x80
 
-       bnz     advance_write_buffer
-       bra     advance_write_byte
+       bnz     advance_read_buffer
+       bra     advance_read_byte
 
 
 
-advance_write_buffer
+advance_read_buffer
 
-; move pointer to next buffer byte 0
+; 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
@@ -329,11 +323,6 @@ advance_write_buffer
 totrack_overflow
 ; clear bit 6 (will set back to buffer 0 if has overflowed to 4)
        bcf     TOTRACK,6,0
-       
-; advance to bit7 
-
-       movlw   0x1
-       movwf   TOTRACKBIT,0
 
 ; write na=cb=1 and return
 
@@ -341,15 +330,12 @@ totrack_overflow
        
 
        
-advance_write_byte
+advance_read_byte
 ; advance to next byte of buffer (increment TOTRACK)
+; (will be on bit 7 at this point anyway so no need to change TOTRACKBIT)
 
        incf    TOTRACK,1,0
 
-; advance to bit7
-
-       movlw   0x1
-       movwf   TOTRACKBIT,0
 
 ; set na=cb=new bit value
 
@@ -364,35 +350,9 @@ advance_write_byte
        
 
 
-advance_bit
-; rotate tranmitbit to next position 
-
-       rlncf   TOTRACKBIT,1,0          ; rotate mask left
-
-
-
-; use rotate through carry?
-; rotate mask register for anding? would also provide easy check for which bit I'm on
-; use top bit for last byte? signed integer arithmetic possible (branch if -ve etc.)
-
-
 
 ;*****************************************************************************************
 
-waiting
-; change - timer0 now for NMRA timer; run this off timer0+counter
-
-        bcf     INTCON,2,0      ; clear timer0 interrupt bit (p109)
-        clrf    TMR0H,0         ; p107 set high bit of timer0 to 0 (buffered,
-                                ; so only actually set when write to tmr0l occurs)
-        clrf    TMR0L,0         ; set low bit o timer0 - timer now set to 0000h
-loop
-        btfss   INTCON,2,0      ; check whethr tiomer0 interrupt has been set -
-                                ; skip next instruction if so
-        bra     loop
-        return
-
-
 
 led_green
         bcf     TRISD,2,0       ; make pin RD2 an output (DS100)
@@ -409,6 +369,14 @@ led_red
         return
 
 
+panic
+       bcf     INTCON,7,0      ; disable high-priority interrupts
+       bcf     INTCON,6,0      ; disable low-priority interrupts
+       bcf     PORTC,1,0       ; switch off booster
+panic_loop
+       call    led_red
+       goto    panic_loop
+       
 ;*****************************************************************************************
 
        end
index 51a1b9565f865c919d29fec673b64da461935d7e..6d1592cfcb3acc25ac7fceb41c7c7e7cb4a82031 100644 (file)
@@ -1,19 +1,7 @@
-;ERRORS:
-
-; 1red = high interrupt bit set
-; 2red = low interrupt bit set by something which isn't timer0 or the USART
-
-
 
 ; pin 21 (per-pic-led, RD2/PSP2/C1IN) states: high H = green, low L = red, float Z = black
 
 
-; *******will need to deal with initial short circuit first
-
-
-
-
-
 
         include         /usr/share/gputils/header/p18f458.inc
 
@@ -50,24 +38,6 @@ TOTRACKBIT   equ     0x3     ; byte 3: bit location of pointer within byte
 
 initialise
 
-; 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
-       bsf     PIE1,5,0        ; enable USART receive interrupt (p85)
-       bsf     IPR1,5,0        ; set to low-priority interrupt
-
-; interrupt set-up for timer0 interrupt p79/80
-       bsf     INTCON,5,0      ; enable timer0 interrupts
-       bcf     INTCON2,2,0     ; timer0 overflow low priority
-
-
-;-----------------------------------------------------------------------------------------
-
-
 ; serial set-up
 
 ; initial config - TXSTA register p181
@@ -89,7 +59,7 @@ initialise
 ;-----------------------------------------------------------------------------------------
 
 
-; timer set-up
+; timer set-up
 ; LED pin (21) initialisation
         bcf     TRISE,4,0       ; turn off PSPMODE (Data Sheet p100/101)
 
@@ -108,45 +78,63 @@ initialise
 ; initialise buffers (for BSR5, for nmra from-serial/to-track buffers)
 
        movlw   5
-       movwf   BSR,0           ; set BRS to 5
+       movwf   BSR,0           ; set BSR to 5
 
        clrf    NMRACTRL,0      ; for bits relevant to control of nmra stream
        clrf    FROMSERIAL,0    ; for location of write-from-usart pointer within BSR5
        clrf    TOTRACK,0       ; for location of send-to-track pointer within BSR5
                                ; all in access bank
 
+
 ;-----------------------------------------------------------------------------------------
 
+
+; initialise next action/transmit bit
+       bsf     NMRACTRL,NEXTACTION,0
+       bsf     NMRACTRL,TRANSMITBIT,0
+
+; initialise TOTRACKBIT bitmask
+       movlw   0x80
+       movwf   TOTRACKBIT,0    ; make bit mask be 1000 0000
+
+; initialise booster direction
+       bsf     TRISC,0,0       ; make pin 0 (booster direction) output
+       bcf     PORTC,0,0       ; set low initially
+
 ; set booster pwm high
        bsf     TRISC,1,0       ; make pin 1 (booster pwm) output
        bsf     PORTC,1,0       ; booster pwm high
 
-; *** also need to deal with initial short circuit state ***
 
-; initialise booster direction
-       bsf     TRISC,0,0       ; make pin 0 (booster direction) output
+;-----------------------------------------------------------------------------------------
 
-; initialise next action/transmit bit
-       bsf     NMRACTRL,NEXTACTION,0
-       bsf     NMRACTRL,TRANSMITBIT,0
+; 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
+       bsf     PIE1,5,0        ; enable USART receive interrupt (p85)
+       bsf     IPR1,5,0        ; set to low-priority interrupt
+
+; interrupt set-up for timer0 interrupt p79/80
+       bsf     INTCON,5,0      ; enable timer0 interrupts
+       bcf     INTCON2,2,0     ; timer0 overflow low priority
 
 
 ;*****************************************************************************************
 
 main_loop_led
        call    led_green
-       call    waiting
-       call    led_black
-       call    waiting
-       goto    main_loop_led
+       goto    main_loop_led
 
 
 ;*****************************************************************************************
 
 interrupt_high
-       call    led_red
-       call    waiting
-       retfie  1
+       goto    panic
 
 ;*****************************************************************************************
 
@@ -158,10 +146,11 @@ interrupt_low
        goto    serial_receive
        btfss   INTCON,2,0      ; check whether timer0 interrupt set
        goto    timer0_interrupt
-       call    led_red
-       call    waiting
-       call    led_red
-        retfie  1               ; return from interrupt to main if spurious interrupt
+       goto    panic
+
+; if 2 interrupts are set at once the 2nd will generate a new interrupt on leaving
+; the interrupt routine
+
 
 ;*****************************************************************************************
 
@@ -171,18 +160,18 @@ serial_receive
        movwf   FSR0H,0                 ; set high byte of IND0 pointer
        movff   RCREG,IND0              ; copy to received register
        incf    FROMSERIAL,1,0          ; advance FROMSERIAL pointer by 1 byte
-       btfss   RCREG,0,0               ; check if bit 0 is set
+       btfss   RCREG,7,0               ; check if bit 7 is set
        call    advance_write_buffer    ; if so, move to next buffer
-       call    led_red
-       call    waiting
-       return
+       retfie  1
 
+; *** 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
 
 ; check if on 1st byte of new buffer anyway (i.e. last 4 bits = 0)
-       movff   FROMSERIAL,W    ; copy FROMSERIAL pointer location to W
+       movf    FROMSERIAL,0,0  ; copy FROMSERIAL pointer location to W
        andlw   0xF             ; investigate last 4 bits
 
 ; if zero (i.e. overflowed to next buffer), branch to overflow check
@@ -195,7 +184,7 @@ advance_write_buffer
        movlw   0xF
        andwf   FROMSERIAL,1,0
        swapf   FROMSERIAL,1,0
-       
+
 fromserial_overflow
 ; clear bit 6 (will set back to buffer 0 if has overflowed to 4)
        bcf     FROMSERIAL,6,0
@@ -215,7 +204,7 @@ timer0_interrupt
 ; check next action - if 0, change to 1 and return
        btfsc   NMRACTRL,NEXTACTION,0
        goto    toggle_output
-       bsf     
+       bsf     NMRACTRL,NEXTACTION,0
        retfie  1
 
 
@@ -255,19 +244,14 @@ decide_next_bit
 
 read_from_buffer
 
-; if no, find current to-track byte and bit
-; (and TRANSMITBIT with 0x1)
-
-       movff   TOTRACKBIT,W,0
-       andlw   0x1
+; if currently on bit 7, want to skip to bit 6
 
-; checking whether TRANSMITBIT (bit mask) is at bit 0 
-; (i.e. whether andlw 0x1 is 1 (on bit 0) or 0 (not on bit 0)
+       btfss   TOTRACKBIT,7,0
+       rrncf   TOTRACKBIT,1,0          ; rotate mask right
 
-       bnz     advance_pointer
-
-; if not on bit 0 (i.e. if the and above results in 0), 
-; set na=cb=bit value, advance bit (i.e. rotate TRANSMITBIT left), return
+; 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
 
        movff   TOTRACK,FSR1L           ; set low byte of IND1 pointer
        movlw   5
@@ -281,35 +265,45 @@ read_from_buffer
 zero_bit_to_track
        bcf     NMRACTRL,TRANSMITBIT,0
        bcf     NMRACTRL,NEXTACTION,0
-       call    advance_bit
-       retfie  1
+       goto    advance_bit
        
 one_bit_to_track
        bsf     NMRACTRL,TRANSMITBIT,0
        bsf     NMRACTRL,NEXTACTION,0
-       call    advance_bit
+       goto    advance_bit
+
+
+
+advance_bit
+; rotate tranmitbit to next position 
+
+       rrncf   TOTRACKBIT,1,0          ; rotate mask right
+
+       btfss   TOTRACKBIT,7,0
+       call    advance_pointer
+
        retfie  1
 
 
 
 advance_pointer
 
-; if currently on the last bit of the byte (bit 0), then check whether it is 1 or 0
+; 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,0
-       andlw   0x1
+       andlw   0x80
 
-       bnz     advance_write_buffer
-       bra     advance_write_byte
+       bnz     advance_read_buffer
+       bra     advance_read_byte
 
 
 
-advance_write_buffer
+advance_read_buffer
 
-; move pointer to next buffer byte 0
+; 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
@@ -329,11 +323,6 @@ advance_write_buffer
 totrack_overflow
 ; clear bit 6 (will set back to buffer 0 if has overflowed to 4)
        bcf     TOTRACK,6,0
-       
-; advance to bit7 
-
-       movlw   0x1
-       movwf   TOTRACKBIT,0
 
 ; write na=cb=1 and return
 
@@ -341,15 +330,12 @@ totrack_overflow
        
 
        
-advance_write_byte
+advance_read_byte
 ; advance to next byte of buffer (increment TOTRACK)
+; (will be on bit 7 at this point anyway so no need to change TOTRACKBIT)
 
        incf    TOTRACK,1,0
 
-; advance to bit7
-
-       movlw   0x1
-       movwf   TOTRACKBIT,0
 
 ; set na=cb=new bit value
 
@@ -364,35 +350,9 @@ advance_write_byte
        
 
 
-advance_bit
-; rotate tranmitbit to next position 
-
-       rlncf   TOTRACKBIT,1,0          ; rotate mask left
-
-
-
-; use rotate through carry?
-; rotate mask register for anding? would also provide easy check for which bit I'm on
-; use top bit for last byte? signed integer arithmetic possible (branch if -ve etc.)
-
-
 
 ;*****************************************************************************************
 
-waiting
-; change - timer0 now for NMRA timer; run this off timer0+counter
-
-        bcf     INTCON,2,0      ; clear timer0 interrupt bit (p109)
-        clrf    TMR0H,0         ; p107 set high bit of timer0 to 0 (buffered,
-                                ; so only actually set when write to tmr0l occurs)
-        clrf    TMR0L,0         ; set low bit o timer0 - timer now set to 0000h
-loop
-        btfss   INTCON,2,0      ; check whethr tiomer0 interrupt has been set -
-                                ; skip next instruction if so
-        bra     loop
-        return
-
-
 
 led_green
         bcf     TRISD,2,0       ; make pin RD2 an output (DS100)
@@ -409,6 +369,14 @@ led_red
         return
 
 
+panic
+       bcf     INTCON,7,0      ; disable high-priority interrupts
+       bcf     INTCON,6,0      ; disable low-priority interrupts
+       bcf     PORTC,1,0       ; switch off booster
+panic_loop
+       call    led_red
+       goto    panic_loop
+       
 ;*****************************************************************************************
 
        end