;
;          "mlan_3a.txt" файл обработчика шины microLAN
; под магистральный адаптер, обеспечивающий подтяжку к +5 и к GND
;           с модулем обработки CRC8
;
; заготовка для работы с DS18...20 или аналогичныой ИС
; используются акумулятор
; и регистры текущего РБ
;
;------------------------------------------------------
; используется "паразитное питание" посредством сигнала L_APD=0
; при активации портов модуля соблюдать последовательность:
; установить комбинацию в порту, обеспечивающем выходной сигнал
;        L_APU=1, L_APD=0 и M_DAT=1
; перевести порт в режим вывода данных по L_APU и L_APU
; и ввода данных по M_DAT
; выдать L_APU=0 (подать питание на шину "паразитки")
;
;------------------------------------------------------
;
; ------------ константы ------------
;
; tm20      equ 7
; tm26      equ 9
; tm46      equ 16
; tm80      equ 27
; tm86      equ 29
; tm400     equ 134
; tm480     equ 161 ; константы из соображений 1 цикл=1uS
; m_cfg9      equ 0b00011111 ; разрешение 9 бит, время преобразования 93,75 mS
; m_cfg10     equ 0b00111111 ; разрешение 10 бит, время преобразования 187,5 mS
; m_cfg11     equ 0b01011111 ; разрешение 11 бит, время преобразования 375 mS
; m_cfg12     equ 0b01111111 ; разрешение 12 бит, время преобразования 750 mS
; mk_conv_t   equ 0x44 ; (CONVERT T) команда запуска преобразования температуры
; mk_rd_spad  equ 0xBE ; (READ SCRATCHPAD) команда чтения "блокнота" из DS18B20
; mk_wr_spad  equ 0x4E ; (WRITE SCRATCHPAD) команда записи Th:Tl:Config в блокнот DS18B20
; mk_wr_eep   equ 0x48 ; (COPY SCRATCHPAD) команда записи Th:Tl:Config
;                      ; из блокнота DS18B20 в EEPROM DS18B20
; mk_rd_eep   equ 0xB8 ; (RECALL E2) команда чтения Th:Tl:Config
;                      ; из EEPROM DS18B20 в блокнота DS18B20
; mk_scip_rom equ 0xCC ; (SKIP ROM) команда "не выполнять персональную адресацию"
;                      ; применяется преамбулой во всех блоках обмена при одиночном
;                      ; датчике
; mk_read_rom equ 0x33 ; (READ ROM) чтение из DS18B20 группового кода изделия
;                      ; и индивидуального номера ( пакет из 8 байт в составе
;                      ; байт family code, 6 байт serial number и байт CRC )
; 
; M_DAT  equ 2 ; (0) позиционный номер линии данных
; L_APU  equ 1 ; (1) позиционный номер линии APU
; L_APD  equ 0 ; (3) позиционный номер линии APD
;    flags
; m_erd   equ 0 ; флаг ошибки "линия mLAN не отвечает"
;             ; в области флагов ошибок
; m_ecrc  equ 1 ; флаг ошибки при проверке CRC кода пакета mLAN
;             ; в области флагов ошибок
;
; --- регистры GPR ---
; область udata_ovr или прерприсвоение как #define nameX nameY
; gradus_l    equ tmp_0 ; младший байт текущей температуры
; gradus_h    equ tmp_1 ; старший байт текущей температуры
; th_us1      equ tmp_2 ; уставка термостата максимальный порог/пользовательский байт
; tl_us2      equ tmp_3 ; уставка термостата минимальный порог/пользовательский байт
; m_cfg       equ tmp_4 ; байт конфигурации датчика DS18B20
; m_res0      equ tmp_5 ; резерв, всегда 0xFF
; m_res1      equ tmp_6 ; резерв, всегда 0x0C
; m_res2      equ tmp_7 ; резерв, всегда 0x10
; m_crc       equ tmp_8 ; контрольная сумма пакета
; m_data      equ tmp_9 ; буфер данных для приема/передачи
; m_cntp      equ tmp_a ; счетчик длины пакета
; m_cntb      equ tmp_b ; счетчик бит приемника/передатчика байта
; m_mcntt     equ tmp_c ; счетчик задержки (djnz cntt_mlan,$ = 2машинных цикла)
; m_flags     equ tmp_d ; флаги обработчиков uLAN
; m_tmp_fsr   equ tmp_e ; РВХ содержимого fsr на время выполнения модулей m_
; m_summ      equ tmp_f ; накопитель результата в расчете CRC
; m_tmp       ; времянка
; port_m      equ PORTA ; () переприсвоение порта
;
;------------------------------------------------------------------------
;
MN   CODE
;
;---------------------------------------
; DTTC - генератор импульса reset термодатчика и проверка импульса
; "присутствия"
m_dttc
  bsf port_m,L_APU ; отключить паразитку
  bcf m_flags,m_erd
  nop
  nop
  nop
  bsf port_m,L_APD ; активировать уровень запроса
  movlw tm480
  movwf m_mcntt
tmm0
  decfsz m_mcntt,f
  goto tmm0 ; ждем завершение импульса запроса 480uS
  bcf port_m,L_APD ; отключить L_APD
  nop
  nop
  nop
  movlw .26 ; линия M_DAT подключена к + через подтяжку в 2килоома
  movwf m_cntb ; периодический опрос линии M_DAT через 20uS в течении 480uS
m_tstpp
  movlw tm20
  movwf m_mcntt
m_tstpp1
  decfsz m_mcntt,f
  goto m_tstpp1
  btfss port_m,M_DAT ; ждем состояние M_DAT=0
   goto wait_mdh
  decfsz m_cntb,f
  goto m_tstpp
  bsf m_flags,m_erd ; если за весь период опросов ответа нет - m_erd=1
wait_mdh
  btfss port_m,M_DAT ; ждем окончание ответа датчика (M_DAT=1)
  goto wait_mdh
  bcf port_m,L_APU ; восстановить паразитку
  movlw tm400
  movwf m_mcntt ; ждем защитный интервал 400uS
tmm1
  decfsz m_mcntt,f
  goto tmm1
  return
;
;---------------------------------------
;
; приемник байта в стандарте сетей microLAN
; вызов call rxb1
; по выходу принятый байт в регистре m_data
m_rxb1
  bsf port_m,L_APU ; отключить паразитку
  nop
  nop
  movlw 8
  movwf m_cntb
rexik
   bsf port_m,L_APD ; активировать уровень запроса
   movlw 4
   movwf m_mcntt
tmm2
   decfsz m_mcntt,f
   goto tmm2
   bcf port_m,L_APD ; деактивировать уровень запроса
   movlw 3
   movwf m_mcntt
tmm2a
   decfsz m_mcntt,f
   goto tmm2a
   bcf STATUS,C
   btfsc port_m,M_DAT
   bsf STATUS,C
   rrf m_data,f
   movlw tm46
   movwf m_mcntt
tmm3
   decfsz m_mcntt,f
   goto tmm3
   decfsz m_cntb,f
   goto rexik
  bcf port_m,L_APU ; восстановить паразитку
  nop
  nop
  return
;
;---------------------------------------
;
; передатчик байта в стандарте сетей microLAN
; перед вызовом передаваемый байт разместить в m_data
; вызов call txb1
m_txb1
  bsf port_m,L_APU ; отключить паразитку
  nop
  nop
  movlw 8
  movwf m_cntb
texik
   bsf port_m,L_APD ; активировать уровень запроса
   movlw 4
   movwf m_mcntt
tmm4
   decfsz m_mcntt,f
   goto tmm4
   rrf m_data,f
   btfsc STATUS,C ; исходно было L_APD=1 (M_DAT=STATUS.C=0)
   bcf port_m,L_APD ; передача M_DAT=1 если STATUS.C=1 (L_APD=0)
   movlw tm46
   movwf m_mcntt
tmm5
   decfsz m_mcntt,f
   goto tmm5 ; ждем ~45uS
   bcf port_m,L_APD ; восстановить L_APD=0
   nop
   nop
    decfsz m_cntb,f
    goto texik
   bcf port_m,L_APU ; восстановить паразитку
   nop
   nop
  return
;
;---------------------------------------
;
; CRC - КОНТРОЛЬ для пакета из 9 байт (8 данных+CRC)
; или 8 байт - модуль расчета задается в макросе вызова
; блок данных предварительно размещается в tmp_0-tmp_8 РПД
; исходные данные НЕ РАЗРУШАЮТСЯ!
m_crck_id
   movlw 8
   goto m_crck2
m_crck
   movlw 9
m_crck2
   movwf m_cntp ; счетчик бит равен 9 (или 8 для ИД кода)
   bcf m_flags,m_ecrc ; сброс флага ошибки
   movf FSR,w
   movwf m_tmp_fsr ; храним текущий FSR
   movlw gradus_l ; указатель на начало массива блокнота
   movwf FSR
   clrf m_summ ; очистить накопитель результата
l_crc1
    movlw 8
    movwf m_cntb ; счетчик бит =8
    movf INDF,w ; читаем текущий байт данных в W
    movwf m_data ; и копируем его же в m_data
l_crc2
    xorwf m_summ,w ; xor битов 0, результат в w
    movwf m_tmp ; передано во времянку
    rrf m_tmp,f ; и результат xor битов 0 накопителя и текущих данных
              ; передан в С
    btfss STATUS,C ; в зависимости от результата по биту 0
    goto p_crc1 ; или уходим в завершение
    movlw 0x18
    xorwf m_summ,f ; или ксорим второй узел
p_crc1
    rrf m_summ,f ; результат сдвигаем вправо с учетом С
    rrf m_data,f ; кольцевой сдвиг исходных данных,
             ; что поступило в старший бит безразлично
    movf m_data,w ; передали в W (с копией в m_data)
   decfsz m_cntb,f ; счетчик бит данных - 1
   goto l_crc2 ; продолжить от l_crc2 если m_cntb не равен 0
   incf FSR,f ; продвижка указателя
   decfsz m_cntp,f ; счетчик байт - 1
   goto l_crc1 ; продолжить от l_crc1 до исчерпания массива
   tstf m_summ ; если CRC правильна в накопителе 0
   btfss STATUS,Z
   bsf m_flags,m_ecrc ; если m_summ не равно 0 установить m_ecrc=1
  movf m_tmp_fsr,w
  movwf FSR ; восстановим FSR перед выходом
  return
;
;---------------------------------------
;
; командный пакет запуска преобразования
;
term_strt
  call m_dttc
  movlw mk_scip_rom
  movwf m_data
  call m_txb1
  movlw mk_conv_t
  movwf m_data
  call m_txb1
 return
;
;---------------------------------------
;
; командный пакет чтения текущих данных блокнота
;
m_rd9
   movf FSR,w
   movwf m_tmp_fsr ; храним текущий FSR
   movlw 9
   movwf m_cntp
   movlw gradus_l
   movwf FSR
    call m_dttc
    movlw mk_scip_rom
    movwf m_data
    call m_txb1
    movlw mk_rd_spad
    movwf m_data
    call m_txb1
l_rd9
   call m_rxb1
   movf m_data,w
   movwf INDF
   incf FSR,f
   decfsz m_cntp,f
   goto l_rd9
  movf m_tmp_fsr,w
  movwf FSR ; восстановим FSR перед выходом
  return
;
;---------------------------------------
;