📄 abutils.asm
字号:
;**************************************************************************
AbortABData PROC NEAR PUBLIC
ror edx, 16 ; Store return address
; Free STALL after START
mov al, NSSIO_ACBCTL1
NOSTACK bx, ABBaseRead
and ah, 03Fh
NOSTACK bx, ABBaseWrite
; Issue STOP event
mov al, NSSIO_ACBCTL1
NOSTACK bx, ABBaseRead
or ah, 02h
NOSTACK bx, ABBaseWrite
; Clear NEGACK and STASTR
mov al, NSSIO_ACBST
mov ah, 038h
NOSTACK bx, ABBaseWrite
ror edx, 16 ; Retore return address
clc
jmp dx
AbortABData ENDP
;**************************************************************************
;*
;* GetABData
;*
;* This routine gets an 8-bit value from DATA registers. The routine
;* does not activate ACCESS.BUS read cycle, it just read the value
;* that already in the register.
;*
;* Entry:
;* BP = number of Access.bus: ACCESS_BUS1_DEVICE or ACCESS_BUS2_DEVICE
;* SI - return address
;*
;* Exit:
;* BL - data value
;* Carry flag set as follows
;* Set = acknowledge bit = 1
;* Clr = acknowledge bit = 0
;*
;* Destroys
;* AX, BX, CX, DX
;*
;**************************************************************************
GetABData PROC NEAR PUBLIC
; Clear the Stall bit
mov al, NSSIO_ACBST
mov ah, 08h
NOSTACK bx, ABBaseWrite
; Wait for the Serial Data register to be filled or an error to occur
GetABDataWait:
mov al, NSSIO_ACBST
NOSTACK bx, ABBaseRead
test ah, 60h ; SDAST and BER == 0?
jz GetABDataWait ; Wait if no events
; Check bus error
test ah, 20h ; BER == 1
jnz csGetABDataFailed ; Bus error happened
; Clear STALL after START
mov al, NSSIO_ACBCTL1
NOSTACK bx, ABBaseRead
and ah, 7Fh
NOSTACK bx, ABBaseWrite
; Stop the clock generation in order to avoid
; an additional read cycle
mov al, NSSIO_ACBCTL2
NOSTACK bx, ABBaseRead
and ah, 0FEh
NOSTACK bx, ABBaseWrite
; Read the received byte
mov al, NSSIO_ACBSDA
NOSTACK bx, ABBaseRead
mov ch, ah
; Enable clock
mov al, NSSIO_ACBCTL2
NOSTACK bx, ABBaseRead
or ah, 01h
NOSTACK bx, ABBaseWrite
mov bl, ch
stc ; Set Carry Flag
jmp si ; Return to calling address
csGetABDataFailed:
mov bx, si
jmp BusRecoveryABData
GetABData ENDP
;**************************************************************************
;*
;* ReadABData
;*
;* This routine reads an 8-bit value from the Access.bus
;*
;* Entry:
;* BP = number of Access.bus: ACCESS_BUS1_DEVICE or ACCESS_BUS2_DEVICE
;* CH = control byte:
;* 1 = Acknowledge: 1 - ACK, 0 - no ACK on the read cycle
;* SI - return address
;*
;* Exit:
;* BL - data value
;* Carry flag set as follows
;* Set = acknowledge bit = 1
;* Clr = acknowledge bit = 0
;*
;* Destroys
;* AX, BX, CX, DX
;*
;**************************************************************************
ReadABData PROC NEAR PUBLIC
; Clear the Stall bit
mov al, NSSIO_ACBST
mov ah, 08h
NOSTACK bx, ABBaseWrite
; Wait for the Serial Data register to be filled or an error to occur
csReadABDataWait:
mov al, NSSIO_ACBST
NOSTACK bx, ABBaseRead
test ah, 60h ; SDAST and BER == 0?
jz csReadABDataWait ; Wait if no events
; Check bus error
test ah, 20h ; BER == 1
jnz ReadABDataFailed ; Bus error happened
NOSTACK bx, ClearACKABData
test ch, 2
jz @f
NOSTACK bx, SetACKABData
@@:
; Read the data
mov al, NSSIO_ACBSDA
NOSTACK bx, ABBaseRead
mov bl, ah
stc ; Set Carry Flag
jmp si ; Return to calling address
ReadABDataFailed:
mov bx, si
jmp BusRecoveryABData
ReadABData ENDP
;**************************************************************************
;*
;* WriteABData
;*
;* This routine reads an 8-bit value from the Access.bus
;*
;* Entry:
;* BP = number of Access.bus: ACCESS_BUS1_DEVICE or ACCESS_BUS2_DEVICE
;* BL - data
;* SI - return address
;*
;* Exit:
;* BL - data value
;* Carry flag set as follows
;* Set = acknowledge bit = 1
;* Clr = acknowledge bit = 0
;*
;* Destroys
;* AX, EBX, CX, DX
;*
;**************************************************************************
WriteABData PROC NEAR PUBLIC
ror ebx, 16 ; Store data
; Wait for the Serial Data register to be ready or an error to occur
csWriteABDataWait1:
mov al, NSSIO_ACBST
NOSTACK bx, ABBaseRead
test ah, 70h ; SDAST, BER and NEGACK == 0?
jz csWriteABDataWait1 ; Wait if no events
; Check bus error
test ah, 20h ; BER == 1
jnz csWriteABDataFailed ; Bus error happened
; Check for negative acknowledge
test ah, 10h ; NEGACK == 1
jnz csWriteABDataAbort ; negative acknowledge happened
; Write the byte
ror ebx, 16 ; Restore data
mov al, NSSIO_ACBSDA
mov ah, bl
NOSTACK bx, ABBaseWrite
; Wait for the Serial Data register to be ready or an error to occur
csWriteABDataWait2:
mov al, NSSIO_ACBST
NOSTACK bx, ABBaseRead
test ah, 70h ; SDAST, BER and NEGACK == 0?
jz csWriteABDataWait2 ; Wait if no events
; Check bus error
test ah, 20h ; BER == 1
jnz csWriteABDataFailed ; Bus error happened
; Check for negative acknowledge
test ah, 10h ; NEGACK == 1
jnz csWriteABDataAbort ; negative acknowledge happened
ror ebx, 16 ; Restore data
stc ; Set Carry Flag
jmp si ; Return to calling address
csWriteABDataAbort:
mov dx, si
jmp AbortABData
csWriteABDataFailed:
mov bx, si
jmp BusRecoveryABData
WriteABData ENDP
;**************************************************************************
;*
;* SetOffsetAB
;*
;* This routine set register in a slave device for future read/write
;* The protocol is as follows:
;* 1) Request bus mastership
;* 2) Set the slave device address
;* 3) Set the address(offset) to write
;*
;* Entry:
;* BL = chip address
;* CL = byte address to access
;* AL = byte to write (only for write) - need to keep
;* BH = control byte:
;* 0 = direction: 1 - read, 0 - write
;* 1 = Acknowledge: 1 - ACK, 0 - no ACK on the read cycle
;* BP = number of Access.bus: ACCESS_BUS1_DEVICE or ACCESS_BUS2_DEVICE
;* SI = return address
;*
;* Exit:
;* Carry flag set as follows
;* Set = acknowledge bit = 1
;* Clr = acknowledge bit = 0
;*
;* Destroys
;* AX, BX, CX, DX
;*
;**************************************************************************
SetOffsetAB PROC NEAR PUBLIC
ror esi, 16 ; Store return address
; Store slave device address and direction in EDI register
mov di, bx
ror edi, 16
; Store offset and data in ECX register
mov ch, al
ror ecx, 16
; Request bus mastership
NOSTACK bx, RequestMasterABData
jnc abortSet
; Set address for writing
ror edi, 8 ; Restore slave device address
mov ax, di
ror edi, 24 ; Store slave device address
and ah, 0FEh ; Clear direction bit - write
NOSTACK bx, AddressABData
jnc abortSet
; Clear the Stall bit
mov al, NSSIO_ACBST
mov ah, 08h
NOSTACK bx, ABBaseWrite
; Write byte offset
ror ecx, 16 ; Restore byte address to access (offset)
mov bl, cl
ror ecx, 16 ; Store byte to write (data)
NOSTACK si, WriteABData
jnc abortSet
ror edi, 16 ; Restore slave device address and direction
mov cx, di
test ch, 1
jz CompleteSet
; Set STALL after START
mov al, NSSIO_ACBCTL1
NOSTACK bx, ABBaseRead
and ah, 80h
NOSTACK bx, ABBaseWrite
; Issue START Condition in order to change a data
; transfer direction
NOSTACK bx, StartSignalABData
test ch, 2
jz @f
NOSTACK bx, ClearACKABData
jmp set_read_address
@@:
NOSTACK bx, SetACKABData
set_read_address:
; Set address for reading
mov ah, cl
or ah, 1 ; Set direction bit - read
NOSTACK bx, AddressABData
jnc abortSet
CompleteSet:
ror ecx, 16 ; Restore byte to write (data)
ror esi, 16 ; Restore return address
stc
jmp si ; Return to calling address
abortSet:
ror ecx, 16 ; Restore byte to write (data)
ror esi, 16 ; Restore return address
mov bx, di
clc
jmp si ; Return to calling address
SetOffsetAB ENDP
;**************************************************************************
;*
;* InitAB
;*
;* Initialize the Access.Bus interface.
;* 1. Disable ACCESS.bus device
;* 2. Configure the SCL frequency
;* 3. Configure no interrupt mode (polling)
;* 4. Disable own slave address
;* 5. Disable general call address
;* 6. Enable the ACCESS.bus device
;*
;* Entry:
;* BP = number of Access.bus: ACCESS_BUS1_DEVICE or ACCESS_BUS2_DEVICE
;* SI = Return address
;*
;* Exit:
;* Destroys:
;*
;**************************************************************************
InitAB PROC NEAR PUBLIC
; Disable the ACCESS.bus device and
; Configure the SCL frequency: 16 clock cycles
mov al, NSSIO_ACBCTL2
mov ah, 070h
NOSTACK bx, ABBaseWrite
; Configure no interrupt mode (polling) and
; Disable general call address if needed
mov al, NSSIO_ACBCTL1
xor ah, ah
NOSTACK bx, ABBaseWrite
; Disable slave address
mov al, NSSIO_ACBADDR
xor ah, ah
NOSTACK bx, ABBaseWrite
; Enable the ACCESS.bus device
mov al, NSSIO_ACBCTL2
NOSTACK bx, ABBaseRead
or ah, 01h
NOSTACK bx, ABBaseWrite
; Free STALL after START
mov al, NSSIO_ACBCTL1
NOSTACK bx, ABBaseRead
and ah, 03Fh
NOSTACK bx, ABBaseWrite
; Issue STOP event
mov al, NSSIO_ACBCTL1
NOSTACK bx, ABBaseRead
or ah, 02h
NOSTACK bx, ABBaseWrite
; Clear NEGACK, STASTR, BIT bits
mov al, NSSIO_ACBST
mov ah, 038h
NOSTACK bx, ABBaseWrite
; Clear BB bit
mov al, NSSIO_ACBCST
NOSTACK bx, ABBaseRead
or ah, 02h
NOSTACK bx, ABBaseWrite
jmp si ; Return to calling address
InitAB ENDP
_TEXT ENDS
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -