?? datalog.asm
字號:
LIST p=18F458 ;PIC18F458 is the target processor
#include "P18f458.INC" ;Include header file
;====================================================================
; Macros
;--------------------------------------------------------------------
#define CLK_FREQ D'20000000'
#define BAUD(x) ((CLK_FREQ/x)/D'64')-1
#define BRG_VAL BAUD(D'9600') ;Baud rate configuration value
;====================================================================
; Uninitialised data
;--------------------------------------------------------------------
; General temps
TMP1 equ 0x000000
TMP2 equ 0x000001
; Current LBA sector address for reading/wring
ATA_A0 equ 0x000002
ATA_A1 equ 0x000003
ATA_A2 equ 0x000004
ATA_A3 equ 0x000005
; Counter used to track data words read/written to/from ATA
ATA_CNT equ 0x000006
; High priority interrupt temps
STATUS_TEMP_H equ 0x000007
WREG_TEMP_H equ 0x000008
BSR_TEMP_H equ 0x000009
; Low priority interrupt temps
STATUS_TEMP_L equ 0x00000A
WREG_TEMP_L equ 0x00000B
BSR_TEMP_L equ 0x00000C
; Countdown number of timer 0 overflows
T0COUNT equ 0x00000D
; End of logged data
END_POSL equ 0x00000E
END_POSH equ 0x00000F
END_ATA_A0 equ 0x000010
END_ATA_A1 equ 0x000011
END_ATA_A2 equ 0x000012
END_ATA_A3 equ 0x000013
; Temp for log data to be displayed
INPDATA_L equ 0x000014
INPDATA_H equ 0x000015
; Countdoen the number of log entries on a display line
OUT_COUNT equ 0x000016
; ATA data transfer buffer
ATA_BUF equ 0x000400
ATA_BUF_END equ 0x000600
;====================================================================
; Interrupt vectors
;--------------------------------------------------------------------
org 0x000000 ;Reset vector
bra START
org 0x000008 ;High priority interrupt vector
bra INT_HIGH
org 0x000018 ;Low priority interrupt vector
bra INT_LOW
;====================================================================
; Main program
;--------------------------------------------------------------------
START
rcall INIT ; Program initialisation
rcall OUT_VERSION ; Version message
REHELP
rcall OUT_HELP ; Help message
MLOOP
rcall OUT_COMMAND ; Command prompt
rcall UART_Getch ; Get user input
movwf TMP1 ; and store
rcall OUT_CRLF ; Newline
movlw 'h' ; Check for help
xorwf TMP1, W
bz REHELP
movlw 'H'
xorwf TMP1, W
bz REHELP
movlw 'v' ; Check for version
xorwf TMP1, W
bz VERSION
movlw 'V'
xorwf TMP1, W
bz VERSION
movlw 'l' ; Check for log start
xorwf TMP1, W
bz LOG
movlw 'L'
xorwf TMP1, W
bz LOG
movlw 'd' ; Check for log dump
xorwf TMP1, W
bz DUMP
movlw 'D'
xorwf TMP1, W
bz DUMP
rcall OUT_UNKNOWN ; Command is unknown
goto MLOOP
VERSION rcall OUT_VERSION ; Version message
goto MLOOP
LOG rcall OUT_LOG ; Log start message
rcall LOG_START ; Enable logging under interrupt
rcall UART_Getch ; Wait for any user input
rcall LOG_STOP ; Terminate logging
rcall OUT_CRLF
goto MLOOP
DUMP rcall OUT_DUMP ; Dump start message
rcall DUMP_ALL ; Dump data
goto MLOOP
;====================================================================
; Program initialisation
;--------------------------------------------------------------------
INIT
;Setup serial comms
movlw b'10010000' ;Enable USART in continous receive mode
movwf RCSTA
movlw b'00100010' ;Async, TX enabled, low baud rate
movwf TXSTA
movlw BRG_VAL ;Set baud rate
movwf SPBRG
movf RCREG, W ;Flush out RX buffer
movf RCREG, W
;Setup I/O ports
clrf PORTA
setf TRISA ; Port A all input
clrf PORTB
setf TRISB ; Port B all input, ATA D0-7
clrf PORTC
movlw B'11100000' ; Port C lower bits for ATA adressing
movwf TRISC
movlw B'00000111' ; Turn off comparitor
movwf CMCON ; On PORTD bits 0-3
clrf PORTD
setf TRISD ; Port D all input, ATA D8-15
movlw B'00000011'
movwf PORTE
movlw B'00000100' ; Port E lower two bits output for ATA
movwf TRISE ; read and write
rcall LOG_RESET ; Reset log pointers
rcall LOG_UPDATE
return
;====================================================================
; High priority intrrupt handler
;--------------------------------------------------------------------
INT_HIGH
movff STATUS, STATUS_TEMP_H
movff BSR, BSR_TEMP_H
movwf WREG_TEMP_H
bcf INTCON, TMR0IF ;Clear timer 0 overflow interrupt flag
decfsz T0COUNT
bra INT_HIGH_EXIT1
movlw D'20' ;Only start conversion every 20 timer 0 timeouts
movwf T0COUNT
bsf ADCON0, GO ;Start ADC conversion
INT_HIGH_EXIT1
movf WREG_TEMP_H, W
movff BSR_TEMP_H, BSR
movff STATUS_TEMP_H, STATUS
retfie
;====================================================================
; Low prority interrupt handler
;--------------------------------------------------------------------
INT_LOW
movff STATUS, STATUS_TEMP_L
movff BSR, BSR_TEMP_L
movwf WREG_TEMP_L
movf ADRESL, W ;Copy ADC result to buffer
movwf POSTINC2
movf ADRESH, W ;Copy ADC result to buffer
movwf POSTINC2
bcf PIR1, ADIF ;Clear ADC interrupt flag
movlw HIGH(ATA_BUF_END) ; Check if at end of buffer
cpfseq FSR2H
bra INT_LOW_EXIT1
movlw LOW(ATA_BUF_END)
cpfseq FSR2L
bra INT_LOW_EXIT1
rcall ATA_Block_Write
rcall ATA_A_INC
lfsr FSR2, ATA_BUF ; Point to start of data capture buffer
INT_LOW_EXIT1
movf WREG_TEMP_L, W
movff BSR_TEMP_L, BSR
movff STATUS_TEMP_L, STATUS
retfie
;====================================================================
; Read a byte from the serial port
;--------------------------------------------------------------------
; W contains the byte that was received
;--------------------------------------------------------------------
UART_Getch
clrwdt
btfss PIR1, RCIF ; Wait for RX buffer full
bra UART_Getch
movf RCREG, W
return
;====================================================================
; Write a byte to the serial port
;--------------------------------------------------------------------
; W contains the byte to be sent
;--------------------------------------------------------------------
UART_Putch
btfss PIR1, TXIF ; Wait for TX buffer empty
bra UART_Putch
movwf TXREG
return
;====================================================================
; Write null terminated string to serial port from
; program memory
;--------------------------------------------------------------------
; TBLPTR Points to the start of the string
;--------------------------------------------------------------------
UART_Puts_loop
rcall UART_Putch
UART_Puts
tblrd*+
movf TABLAT, W
bnz UART_Puts_loop
return
;====================================================================
; Read a sector from the ATA drive
;--------------------------------------------------------------------
ATA_Block_Read
rcall ATA_BSY_Wait ; Drive ready for command
rcall ATA_Send_LBA
movlw 0x20 ; Read sectors command
movwf TMP1
movlw 0x17 ; ATA Command regsiter
rcall ATA_Reg8_Write
clrf ATA_CNT
lfsr FSR0, ATA_BUF
ATA_Block_Read_Lp1
rcall ATA_DRQ_Wait ; Drive data waiting
movlw 0x10
rcall ATA_Reg16_Read
movf TMP1, W
movwf POSTINC0
movf TMP2, W
movwf POSTINC0
incfsz ATA_CNT
bra ATA_Block_Read_Lp1
return
;====================================================================
; Write a sector too the ATA drive
;--------------------------------------------------------------------
ATA_Block_Write
rcall ATA_BSY_Wait ; Drive ready for command
rcall ATA_Send_LBA
movlw 0x30 ; Write sectors command
movwf TMP1
movlw 0x17 ; ATA Command regsiter
rcall ATA_Reg8_Write
clrf ATA_CNT
lfsr FSR0, ATA_BUF
ATA_Block_Write_Lp1
rcall ATA_DRQ_Wait ; Drive ready for data
movf POSTINC0, W
movwf TMP1
movf POSTINC0, W
movwf TMP2
movlw 0x10
rcall ATA_Reg16_Write
incfsz ATA_CNT
bra ATA_Block_Write_Lp1
return
;====================================================================
; Wait for DRQ to indicate drive is ready for data
;--------------------------------------------------------------------
ATA_DRQ_Wait
movlw 0x17 ; Drive status register
rcall ATA_Reg8_Read
btfss TMP1, 3 ; DRQ bit (data request)
bra ATA_DRQ_Wait
return
;====================================================================
; Wait for BSY to indicate drive is ready for a command
;--------------------------------------------------------------------
ATA_BSY_Wait
movlw 0x17 ; Drive status register
rcall ATA_Reg8_Read
btfsc TMP1, 7 ; BSY bit (busy)
bra ATA_BSY_Wait
return
;====================================================================
; Zero out LBA address
;--------------------------------------------------------------------
ATA_A_RESET
clrf ATA_A0 ; Point to first sector
clrf ATA_A1
clrf ATA_A2
clrf ATA_A3
return
;====================================================================
; Increment LBA address by one
;--------------------------------------------------------------------
ATA_A_INC
incfsz ATA_A0 ; Point to next sector
bra ATA_A_INC_EXIT
incfsz ATA_A1
bra ATA_A_INC_EXIT
infsnz ATA_A2
incf ATA_A3
ATA_A_INC_EXIT
return
;====================================================================
; Transfer LBA address to drive
;--------------------------------------------------------------------
ATA_Send_LBA
movlw 0x01 ; Sector count
movwf TMP1
movlw 0x12 ; ATA Sector count
rcall ATA_Reg8_Write
movff ATA_A0, TMP1
movlw 0x13 ; ATA LBA 0-7 register
rcall ATA_Reg8_Write
movff ATA_A1, TMP1
movlw 0x14 ; ATA LBA 8-15 register
rcall ATA_Reg8_Write
movff ATA_A2, TMP1
movlw 0x15 ; ATA LBA 16-23 register
rcall ATA_Reg8_Write
movf ATA_A3, W
iorlw B'01000000' ; Indicate address is LBA not CHS
movwf TMP1
movlw 0x16 ; ATA LBA 24-27 register
rcall ATA_Reg8_Write
return
;====================================================================
; Read a register from the ATA drive (8 bit)
;--------------------------------------------------------------------
; W contains address
; TMP1 contains data
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -