DRUID Development Docs: gout_ser.inc

Gadget Sourcecode: gout_ser.inc

; Justice Unlimited Gadget Microcode
; (C) 2004 Nathan (Acorn) Pooley 
;
; gout_ser.inc
;
;@DOC@ code to interface to the display when using
;@DOC@ the serial port (I2C mode)
;



;
; functions for output to display - SERIAL
;

#if 0 && !OUTPUT_PARALLEL

;############################################
;############### MACROS #####################
;############################################

;
; SEND SERIAL START
;
SERIAL_START    macro
    bsf     b_sen
    SIMSERIAL_PUTC  0xE1
    endm

;
; SEND SERIAL STOP
;
SERIAL_STOP macro
    bsf     b_pen
    SIMSERIAL_PUTC  0xE2
    endm


;############################################
;############### DISABLE OUTPUT #############
;############################################

output_disable:
    rcall   output_wait     ; wait for preceding transmissions
    SERIAL_STOP
    rcall   output_wait     ; wait for stop to complete

    ;
    ; (re)start output (clears screen)
    ;
    rcall   output_enable   ; restart output (clears screen)

    ;
    ; Turn off display (save power)
    ;
    DISABLE_DISPLAY

    ;
    ; Turn off serial port (save power)
    ;
    clrf    SSPCON1
    return

;############################################
;############### ENABLE OUTPUT ##############
;############################################

output_retry:
#if DEBUG_BITS
    bcf     db_out_en_retry
#endif

    ;
    ; send STOP
    ;
    rcall   output_wait     ; wait for stuff complete
    SERIAL_STOP

    ;
    ; wait for display to stop being confused
    ;
    clrf    SSPCON1             ; turn off serial port

    SIMSERIAL_PUTC  0xE3

    rcall   pause_1sec          ; wait 1 second

    SIMSERIAL_PUTC  0xE4

#if DEBUG_BITS
    bsf     db_out_en_retry
#endif

    ; fall thru to output_enable


    ;
    ; setup serial port & buffer for sending
    ;
output_enable:
#if REPORT_ERRORS
    movlw   ERROR_OUT_EN
    movwf   v_hang_state
#endif

    ENABLE_DISPLAY

#if FIX_ENAB
    incf    v_en_cnt
#endif

    ;
    ; I2C SERIAL PORT
    ;
    clrf    SSPCON1         ; disable (reset) I2C circuitry
    movlw   0x28
    movwf   SSPCON1         ; Setup for I2C Master Mode
    clrf    SSPCON2         ; Setup for I2C Master Mode
    movlw   0xc0
    movwf   SSPSTAT         ; clear status
    clrf    SSPADD          ; fastest BAUD clock

    bcf     b_output_error

#if 0
    ;
    ; wait for display to stop being confused
    ;
#if DEBUG_BITS
    bcf     db_out_en_retry
#endif
    movlw   204         ; 1 second
output_enable_loop:
    bcf     b_output_error
    rcall   pause                   ; 26 cycles
    decfsz  WREG,f
    bra     output_enable_loop      ; 40 cycles per loop

#if DEBUG_BITS
    bsf     db_out_en_retry
    bsf     db_aa
    bsf     db_bb
    bsf     db_no_ack
#endif

#endif

#if FIX_ENAB
    movf    v_en_delay,w
output_enable_loop:
    nop
    nop
    nop
    nop

    nop
    nop
    nop
    nop

    nop
    nop
    nop
    nop

    nop
    nop
    nop
    nop

    nop
    nop
    nop
    nop

    nop
    nop
    nop
    nop

    nop
    nop
    nop
    nop

    nop
    decfsz  WREG,f
    bra     output_enable_loop

    
#endif

    ;
    ; send START
    ;
    rcall   pause           ; pause to allow settling
    bcf     b_sspif
    SERIAL_START

    ;
    ; wait for START to complete
    ; send ADDRESS
    ;
    movlw   SS_TX_ADDR
output_enable_loop2:
    btfsc   b_sspif
    bra     output_enable_loop2

    bcf     b_sspif
    movwf   SSPBUF          ; send address

    ;
    ; send init string
    ;
    movlw   str_init
    rcall   puts

#if 0 ; FIX_ENAB
    movlw   30
    rcall   put_position
    movf    v_en_cnt,w
    rcall   putnum_w
    movlw   ' '
    rcall   putc
    movf    v_en_delay,w
    rcall   putnum_w
    rcall   pause_1sec
#endif

    ;
    ; set backlight mode
    ;
    rcall   light_set

    ;
    ; check for errors - retry if errors occurred
    ;
    rcall   output_err_check
    btfsc   b_output_error
    bra     output_retry    ; retry if failed

#if REPORT_ERRORS
    clrf    v_hang_state
    incf    v_cnt_outenab,f
#endif
    return

;############################################
;############### OUTPUT CHARACTER ###########
;############################################

    ;
    ; send a character
    ; w = character to send
    ;
putc:
    movwf   v_putc_save_w
    andlw   0xe0
    addlw   LOW -0x80
    btfsc   STATUS,Z
    bra     putc_special        ; special character? (0x80-0x9f)
    movf    v_putc_save_w,w
    
    ;
    ; send character (do not check for special characters)
    ;
putc_raw:

#if USE_PUTL
    incf    v_putc_cnt,f        ; count characters
#endif


#if SIMULATE_SERIAL
    movff   FSR0L, v_ss_save_fsr0l
    movff   FSR0H, v_ss_save_fsr0h
    lfsr    FSR0, BUF_SIMSERIAL
    movff   v_ssbuf_ptr,FSR0L
    incf    v_ssbuf_ptr,f
    movwf   INDF0
    incf    FSR0L,f
    setf    INDF0
    incf    FSR0L,f
    setf    INDF0
    incf    FSR0L,f
    setf    INDF0
    incf    FSR0L,f
    setf    INDF0
    incf    FSR0L,f
    setf    INDF0
    incf    FSR0L,f
    setf    INDF0
    incf    FSR0L,f
    setf    INDF0
    incf    FSR0L,f
    setf    INDF0
    incf    FSR0L,f
    setf    INDF0
    incf    FSR0L,f
    setf    INDF0
    incf    FSR0L,f
    clrf    INDF0
    movff   v_ss_save_fsr0l,FSR0L
    movff   v_ss_save_fsr0h,FSR0H
    return
#endif

#if REPORT_ERRORS
    movwf   v_putc_save_w
    movlw   ERROR_OUT_PUTC
    movwf   v_hang_state
    movf    v_putc_save_w,w
#endif

    ;
    ; wait for previous transmit to complete
    ;
putc_wait:
    btfss   b_sspif
    rcall   output_wait

    btfsc   b_ackstat
    bra     putc_noack

    ;
    ; transmit DATA
    ;
    bcf     b_sspif
    movwf   SSPBUF          ; send this data byte

#if REPORT_ERRORS
    clrf    v_hang_state
#endif

    return


putc_noack:
#if DEBUG_BITS
    bcf     db_no_ack
#endif
#if REPORT_ERRORS
    incf    v_oerrcnt_noack,f
#endif
    bsf     b_output_error
    return


;############################################
;############### PAUSE ######################
;############################################

    ;
    ; pause briefly (26 cycles)
    ; (also check errors)
    ; (preserves W)
    ;
pause:
    movwf   v_putc_save_w
    movlw   2
pause_loop:
    rcall   output_err_check        ; 6 cycles
    decfsz  WREG,f
    bra     pause_loop              ; 2+2+2x11 = 26 cycles

    movf    v_putc_save_w,w
    return

    ;
    ; pause for 1 full second
    ; (preserves W)
    ; (USES v_tmp)
    ;
pause_1sec:
    clrf    v_tmp                   ; 1 second
pause_1sec_loop:
    bcf     b_output_error
    rcall   pause                   ; 26 cycles
    decfsz  v_tmp,f
    bra     pause_1sec_loop         ; 6+26 = 32 cycles per loop
    return


    ;
    ; wait for sspif to be set
    ; (alsow check for errors)
    ; (preserves W)
    ;
output_wait:
    btfsc   b_sspif
    bra     output_wait_done2

    movwf   v_putc_save_w
    movlw   5
    movwf   v_tmp
output_wait_loop:
    btfss   b_sspif
    bra     output_wait_more

output_wait_done1:
    movf    v_putc_save_w,w
output_wait_done2:
    bcf     b_sspif
    return

output_wait_more:
    rcall   output_err_check

    btfsc   b_output_error
    bra     output_wait_done1

#if SIMULATE_SERIAL
    bsf     b_sspif
#endif

    decfsz  v_tmp,f
    bra     output_wait_loop

    ;
    ; if we reach here we expected a sspif but did not get one
    ;
    bsf     b_output_error
#if REPORT_ERRORS
    rcall   output_err_check
    incf    v_oerrcnt_nosspif,f
#endif
    bra     output_wait_done1

    ;
    ; check errors in output
    ;
output_err_check:
    btfss   b_wcol
    bra     output_err_check2

    bsf     b_output_error
    bcf     b_wcol
#if REPORT_ERRORS
    incf    v_oerrcnt_wcol,f
    bcf     db_aa
#endif

output_err_check2:
    btfss   b_bclif
    return

    bsf     b_output_error
    bcf     b_bclif
#if REPORT_ERRORS
    incf    v_oerrcnt_bus,f
    bcf     db_bb
#endif

    return


;############################################
;############### POSITION CURSOR ############
;############################################

; position cursor
; w should contain desired position (0-39)
;
;  Sends 0xfe 0x47 <col> <row>
;  col = 1...20
;  row = 1 or 2
;
put_position:
    movwf   v_cpos
    movlw   str_pos         ; 0xfe, 0x47
    rcall   puts
    movlw   2
    movwf   v_tmp2          ; row = 2
    movf    v_cpos,w
    addlw   LOW -20
    bnn     put_position2       ; w>20 ?

    ;
    ; row 1
    ;
    decf    v_tmp2,f        ; row = 1
    addlw   20

put_position2:
    incf    WREG,w          ; from 0...19 -> 1...20
    rcall   putc_raw        ; Row
    movf    v_tmp2,w
    rcall   putc_raw        ; Column
    return


;############################################
;############### BACKSPACE ##################
;############################################

    ;
    ; this is an error in serial mode
    ;
sc_bs:
    bra     error_bad_sc        ; bad special character error

;############################################
;############### CONFIG #####################
;############################################

    ;
    ; permanently configure the display (do this only rarely)
    ;
#if ALLOW_CONFIG
config:
    movlw   str_config1
    rcall   puts
    rcall   pause_1sec

    movlw   str_config2
    rcall   puts
    rcall   pause_1sec

    movlw   str_config3
    rcall   puts
    rcall   pause_1sec

    movlw   str_config4
    rcall   puts
    rcall   pause_1sec

    movlw   str_config5
    rcall   puts
    rcall   pause_1sec

    movlw   str_config6
    rcall   puts
    rcall   pause_1sec

    movlw   str_config7
    rcall   puts
    rcall   pause_1sec

    movlw   str_config8
    rcall   puts
    rcall   pause_1sec

    movlw   str_config9
    rcall   puts
    rcall   pause_1sec

    movlw   str_configa
    rcall   puts
    rcall   pause_1sec

    movlw   str_configb
    rcall   puts
    rcall   pause_1sec

    movlw   str_configc
    rcall   puts
    rcall   pause_1sec

    movlw   str_configd
    rcall   puts
    rcall   pause_1sec

    movlw   str_confige
    rcall   puts
    rcall   pause_1sec

    movlw   str_configf
    rcall   puts
    rcall   pause_1sec

    movlw   str_configg
    rcall   puts
    rcall   pause_1sec

    movlw   str_configh
    rcall   puts
    rcall   pause_1sec

    movlw   str_configi
    rcall   puts
    rcall   pause_1sec


    movlw   10
    movwf   v_tmp2
config_loop:
    movlw   '0'-1
    addwf   v_tmp2,w
    rcall   putc
    movlw   0xfe
    rcall   putc
    movlw   0x4c
    rcall   putc
    rcall   time
    rcall   pause_1sec
    decfsz  v_tmp2,f
    bra     config_loop

    movlw   mode_didconfig
    btfsc   b_output_error
    bra     mode_failconfig
    bra     set_mode
#endif ; ALLOW_CONFIG

#if ALLOW_DEBUG
en_delay:
    rcall   parse_dec
    decf    v_num_bits,w
    btfsc   STATUS,Z
    movff   v_num_lo, v_en_delay

en_delay_end:
    movlw   mode_main_menu
    bra     set_mode

#endif ; ALLOW_DEBUG

;############################################
;############### CLEAR SCREEN ###############
;############################################
putc_clr:
    movlw   str_clear               ; clear screen
    bra     puts

;############################################
;############### BACKLIGHT ##################
;############################################

light_toggle_held:
    bcf     v_bheld,7           ; clear held bit that caused this

light_toggle:
    btg     b_light             ; toggle light

light_set:
    movlw   str_light_on
    btfss   b_light
light_off:
    movlw   str_light_off
    bra     puts





#endif

This file Copyright (C) 2004 by Nathan (Acorn) Pooley
Go to DRUID Development page
Go to DRUID page
Go to JU Gadgets page
Go to Justice Unlimited homepage
Go to Acorn's personal webpage
Contact Acorn
See comments from others
Post your own comments
File created by do_doc at Wed Aug 4 17:55:51 2004