
;*F***************************************************************************
; NAME:     autobaud
;-----------------------------------------------------------------------------
; PARAMS:
;
; RETURN:
;
;-----------------------------------------------------------------------------
; PURPOSE:  check speed reception of a 'U' char and program the baud
;           generator according to it
; 
;*****************************************************************************
$if BRG_IBG
autobaud:                       ; autobaud with internal baud rate generator
    anl     TCON,#0Fh
    mov     TMOD,#10h           ; timer 1 in 16 bits mode
    jb      P3.0,$              ; wait for start bit
    jnb     P3.0,$              ; wait for data bit 0 'H'
    setb    TR1                 ; start timer
    mov     R0,#02h
auto_bit:
    jb      P3.0,$              ; wait for data bit 1/3 'L'
    jnb     P3.0,$              ; wait for data bit 2/4 'H'
    djnz    R0,auto_bit
    jb      P3.0,$              ; wait for data bit 5 'L'
    jnb     P3.0,$              ; wait for data bit 6 'H'
    clr     TR1                 ; stop timer
    jb      P3.0,$              ; wait for data bit 7 'L'
    jnb     P3.0,$              ; wait for stop bit 'H'

    ; BRL = ~(T1 / 16) + 1
    ; T1 / 16 : 2 shift left and keep MSB
    mov     A,TH1
    anl     A,#00Fh
    mov     R0,A
    mov     A,TL1
    mov     A,TL1
    jnb     ACC.3,auto_correct  ; take care of round
    add     A,#010h
auto_correct:
    anl     A,#0F0h
    orl     A,R0
    swap    A                   ; ACC = T1 / 16
    ; ~() + 1
    cpl     A
    inc     A
    mov     BRL,A               ; set the reload register
    mov     SCON,#052h          ; TI= 1, RI= 0, uart mode 1  
    orl     PCON,#080h          ; SMOD1= 1
    mov     BDRCON,#01Fh        ; SPD= 1, BRR = 1
    ret
$endif  ; BRG_IBG

$if BRG_T2
autobaud:                       ; autobaud with timer 2
    mov     T2CON,#00h
    mov     TL2, #00h           ; RLe Autobaud improvement first reset cpt
    mov     TH2, #00h
    jnb     P3.0,$              ; Check for '1' on RxD line: bug 0007 modification
    jb      P3.0,$              ; wait for start bit
    setb    TR2                 ; start timer
    jnb     P3.0,$              ; wait for data bit 0 'H'
    jb      TF2, autobaud       ; RLe: Timeout : Buggly UART Laptop
    jb      P3.0,$              ; wait for data bit 1 'L'
    jnb     P3.0,$              ; wait for data bit 2 'H'
    jb      P3.0,$              ; wait for data bit 3 'L'
    jnb     P3.0,$              ; wait for data bit 4 'H'
    jb      P3.0,$              ; wait for data bit 5 'L'
    jnb     P3.0,$              ; wait for data bit 6 'H'
    jb      P3.0,$              ; wait for data bit 7 'L'
    clr     TR2                 ; stop timer
    jnb     P3.0,$              ; wait for stop bit 'H'
    mov     R0, #7              ; RLe Modif: measure correction
dec_measure:
    dec     TL2                 ; remove one cycle of measurement
    mov     A,TL2
    cjne    A,#0FFh,next_dec
    dec     TH2                 ; remove 1 to TH2 if initially TL2 was equal 00h
; (TH2,TL2:0200h--> 01FFh)
next_dec:
    djnz    R0, dec_measure

TH2_00:
    mov     A,TH2
    mov     R6,A
    mov     A,TL2
    clr     C                   ; first multiply by 2
    rlc     A
    xch     A,R6
    rlc     A
    xch     A,R6
    add     A,TL2               ; and then add the original value
    xch     A,R6
    addc    A,TH2
    ;
    ; a,r6 = (a,r6)/64
    ;
    mov     R0,#6
div64:
    clr     C
    rrc     A
    xch     A,R6
    rrc     A
    xch     A,R6
    djnz    R0,div64
 
    cpl     A
    mov     RCAP2H,A
    mov     A,R6
    cpl     A
    mov     RCAP2L,A
           
    mov     SCON,#052h          ; serial port in 8 bits UART
    mov     T2CON,#034h         ; Timer2 in Baud rate Generator mode

    setb    TR2                 ; start Timer2
    ret
$endif  ; BRG_T2
