📄 drivers.asm
字号:
R2 &= 0x00ff // 清除高8位
R3 |= R2 //
[BP] = R3 //
// 更新Byte长度给guwUartRxLen
IRQ7_2:
[_guwUartRxLen] = R4
IRQ_7_EXIT:
pop R2, BP from [SP]
irq on
reti
.endp
.text
.public _BREAK
_BREAK: .proc
// Write you code here.....
reti
.endp
//////////////////////////////////////////////////////////////////
// Function: void ClearWatchDog();
// 清看门狗,必须在程序运行0.75秒内执行
//////////////////////////////////////////////////////////////////
.code
.public _ClearWatchDog
_ClearWatchDog: .proc
push BP to [SP]
BP = 1
[P_Watchdog_Clear] = BP
pop BP from [SP]
retf
.endp
//////////////////////////////////////////////////////////////////
// Function: void SP_OpenTime2();
// 开启时基2Hz中断
//////////////////////////////////////////////////////////////////
.code
.public _SP_OpenTime2
_SP_OpenTime2: .proc
push BP to [SP]
BP = [P_INT_Ctrl_New]
BP |= C_IRQ5_2Hz
[P_INT_Ctrl_New] = BP
pop BP from [SP]
irq on
retf
.endp
//////////////////////////////////////////////////////////////////
// Function: void SP_CloseTime2();
// 关闭时基2Hz中断
//////////////////////////////////////////////////////////////////
.code
.public _SP_CloseTime2
_SP_CloseTime2: .proc
push BP to [SP]
BP = C_IRQ5_2Hz
[P_INT_Clear] = BP
BP = [P_INT_Ctrl_New]
BP &= ~C_IRQ5_2Hz
[P_INT_Ctrl_New] = BP
pop BP from [SP]
retf
.endp
//////////////////////////////////////////////////////////////////
// 功能函数: void SP_IO_INIT()
// (1) 初始化I/O工作状态
// (2) IOA为输入、高阻、唤醒模式
// (3) IOB[15-11]输出'0'匹配8019as的SA[4-0]
// (4) IOB[6-4]输出'1'匹配8019as的Reset, IORD , IOWR
// (5) IOB[3]下拉输入模式,作为8019as的中断输入查询
// (6) IOB[7]高阻输入唤醒模式,作为Uart_RX
// (7) IOB[10]输出'0',作为Uart_TX
// (8) IOB[9-8,2-0]未使用,暂定为下拉输入模式(抗干扰)。
// (9) 系统工作频率 CPUCLK = 49.152MHz
//////////////////////////////////////////////////////////////////
.code
.public _SP_IO_INIT
_SP_IO_INIT: .proc
push BP to [SP]
BP = 0x0000
[P_IOA_Dir] = BP
BP = 0xffff
[P_IOA_Attrib] = BP
BP = 0x0000
[P_IOA_Data] = BP
BP = 1111110001110000B
[P_IOB_Dir] = BP
BP = 1111110011110000B
[P_IOB_Attrib] = BP
BP = 0000000001110000B // C_IOB_DEFAULT = 00000000000110000B = 0x0030
[P_IOB_Data] = BP
BP = (C_Fosc_49M152|C_32K_Work|C_Fosc_Div_1|C_32K_Auto) //Faster
// BP = (C_Fosc_40M960|C_32K_Work|C_Fosc_Div_1|C_32K_Auto) //Faster
// BP = (C_Fosc_32M768|C_32K_Work|C_Fosc_Div_1|C_32K_Auto) //Faster
[P_SystemClock] = BP
// Delay more than 32 clock
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
pop BP from [SP]
retf
.endp
//////////////////////////////////////////////////////////////////
// Function: void SP_UART_INIT(UINT16 Baud)
// Rx interrupt mode, and setup Baud.
// DATA: 8bit
// STOP: 1bit
// PARITY Check: no
// IOB7/10 must be first set in SP_IO_INIT() as follows:
// (1) IOB[7]高阻输入唤醒模式,作为Uart_RX
// (2) IOB[10]输出'0',作为Uart_TX
//////////////////////////////////////////////////////////////////
.code
.public _SP_UART_INIT
_SP_UART_INIT: .proc
push BP to [SP]
BP = C_UART_CMD1_Reset // Reset UART
[P_UART_Command1] = BP
BP = 0xff
SP_UART_INIT_1: // Delay a moment!
BP -= 1
jnz SP_UART_INIT_1
BP = SP + 2 + 1 + 1 // get baud
BP = [BP]
[P_UART_BaudScalarLow] = BP // setup baud
BP = BP lsr 4
BP = BP lsr 4
[P_UART_BaudScalarHigh] = BP
BP = C_UART_CMD2_RxPinEn|C_UART_CMD2_TxPinEn // Enable Rx/Tx Pin function
[P_UART_Command2] = BP
BP = C_UART_CMD1_RxIntEn // Enable Rx interrupt
[P_UART_Command1] = BP
pop BP from [SP]
irq on
retf
.endp
//////////////////////////////////////////////////////////////////
// Function: void SP_UART_TX(UINT16 txlen, UINT16 *txbuf)
// txbuf: 指向发送首地址
// txlen: 待发送的Byte长度
// BIG_ENDIAN 模式对齐
//////////////////////////////////////////////////////////////////
.code
.public _SP_UART_TX
_SP_UART_TX: .proc
push R2, BP to [SP]
BP = SP + 2 + 4 + 1
R4 = [BP++] // R4 = txlen
BP = [BP] // BP = txbuf
R3 = 0 // 高低8位记录:偶表示高8位!
SP_UART_TX_1:
R2 = [P_UART_Command2]
test R2, C_UART_CMD2_TxRDY // 发送允许检测
jz SP_UART_TX_1
test R3, 0x0001 // 高低8位判断
jz SP_UART_TX_2
R2 = [BP++] // 如果是低8位待发送...
[P_UART_Data] = R2 // 高8位忽略
jmp SP_UART_TX_3
SP_UART_TX_2: // 如果是高8位待发送...
R2 = [BP]
R2 = R2 lsr 4
R2 = R2 lsr 4
[P_UART_Data] = R2
SP_UART_TX_3:
R3 += 1 // 奇偶变换:记录高低8位
R4 -= 1
jnz SP_UART_TX_1
pop R2, BP from [SP]
retf
.endp
//////////////////////////////////////////////////////////////////
// Function: void SP_ADAC_INIT(UINT16 Sample)
// 使用32768Hz做基准
// Sample: 采样率(单位:Hz),只能是以下定义。
// #define cSample_32768 0xffff // 32768Hz 采样:记 1 次
// #define cSample_16384 0xfffe // 16384Hz 采样:记 2 次
// #define cSample_8192 0xfffc // 8192Hz 采样:记 4 次
// #define cSample_4096 0xfff8 // 4096Hz 采样:记 8 次
//////////////////////////////////////////////////////////////////
.code
.public _SP_ADAC_INIT
_SP_ADAC_INIT: .proc
push BP to [SP]
BP = SP + 2 + 1 + 1
BP = [BP] // get Sample rate
[P_TimerB_Data] = BP // Setup TimeB Init Value
BP = C_32768Hz|C_PWM_Off // Setup Clock_A With 32768Hz
[P_TimerB_Ctrl] = BP
BP = [P_INT_Ctrl_New] // Enable FIQ_TimeB
BP |= C_FIQ_TimerB
[P_INT_Ctrl_New] = BP
// BP = C_ADC_DEFAULT|C_ADC_ON|C_DAC_3mA|C_ADC_AGC // Setup MIC, AGC Enable
BP = C_ADC_DEFAULT|C_ADC_ON|C_DAC_3mA // Setup MIC, AGC Disable
[P_ADC_Ctrl] = BP
BP = C_ADC_CH_MIC // Select MIC
[P_ADC_MUX_Ctrl] = BP
BP = C_DAC1_Direct|C_DAC2_Direct|C_ADC_Direct // Setup A/D, D/A mode
[P_DAC_Ctrl] = BP
// Ok, Waiting for 'fiq on' ......
pop BP from [SP]
retf
.endp
//////////////////////////////////////////////////////////////////
// Function: void RTL8019AS_RESET(void)
//////////////////////////////////////////////////////////////////
.code
.public _RTL8019AS_RESET
_RTL8019AS_RESET: .proc
push R4, BP to [SP]
// 1. Reset -> 1
BP = C_RESET|C_IOB_DEFAULT
[P_IOB_Data] = BP
// 2. Hardwre reset >160uS
BP = 0x8000
RTL8019AS_RESET_1:
BP -= 1
jnz RTL8019AS_RESET_1
// 3. Reset RTL8019AS end, Reset 1 -> 0
BP = C_IOB_DEFAULT
[P_IOB_Data] = BP
// 4. Wait about 5S for RTL8019AS Auto_negotiation.
R4 = 0x01d3
RTL8019AS_RESET_2:
BP = 0xffff
RTL8019AS_RESET_3:
BP -= 1
jnz RTL8019AS_RESET_3
R4 -= 1
jnz RTL8019AS_RESET_2
pop R4,BP from [SP]
retf
.endp
//////////////////////////////////////////////////////////////////
// Define MACROS for Read/Write RTL8019AS Bus
// Refer to Hardware
//////////////////////////////////////////////////////////////////
// 向RTL8019AS写1个word
// Addr:只能使用rtl8019as.inc文件定义的地址常数
// Word: 要写的数据。必须放在寄存器(R1/R2/R3/R4/BP),但不可以用SP
// Register:必须要使用的临时寄存器,不能与Word用的相同,不可以用SP
RTL8019AS_WR_WORD: .macro Addr, Word, Register
Register = (Addr|C_IOB_DEFAULT)&~C_IOWR
[P_IOB_Data] = Register // IOWR -> 0
[P_IOA_Data] = Word // Write Data
Register = Addr|C_IOB_DEFAULT
[P_IOB_Data] = Register // IOWR -> 1
.endm
// 从8019AS读1个word
// Addr:只能使用rtl8019as.inc文件定义的地址常数
// Word:读到的数据。必须是寄存器(R1/R2/R3/R4/BP),但不可以用SP
// Register:必须要使用的临时寄存器,不能与Word用的相同,不可以用SP
RTL8019AS_RD_WORD: .macro Addr, Word, Register
Register = (Addr|C_IOB_DEFAULT)&~C_IORD
[P_IOB_Data] = Register // IORD ->0
Register = Addr|C_IOB_DEFAULT
Word = [P_IOA_Data] // Read Data
[P_IOB_Data] = Register // IORD -> 1
.endm
// 恢复IOA和IOB的默认端口状态。与SP_IO_INIT()有关
// Register:必须要使用的临时寄存器(R1/R2/R3/R4/BP),不可以用SP
SP_RECALL_IO: .macro Register
// Recall IOA to default status
Register = 0x0000
[P_IOA_Data]= Register
[P_IOA_Dir] = Register
// Recall IOB to default status
Register = C_IOB_DEFAULT
[P_IOB_Data] = Register
.endm
// 设置IOA为:高阻输入状态
// Register:必须要使用的临时寄存器(R1/R2/R3/R4/BP),不可以用SP
SP_IOA_IN: .macro Register
Register = 0x0000
[P_IOA_Data] = Register
[P_IOA_Dir] = Register
.endm
// 设置IOA为:高阻输出状态
// Register:必须要使用的临时寄存器(R1/R2/R3/R4/BP),不可以用SP
SP_IOA_OUT: .macro Register
Register = 0xffff
[P_IOA_Dir] = Register
.endm
//////////////////////////////////////////////////////////////////
// RTL8019AS初始化,包含软复位。
// 返回0:表示MCU控制RTL8019AS通讯异常。
// 返回1:表示初始化成功。
//////////////////////////////////////////////////////////////////
.external _guwEthAddr // 本地以太地址,引用tcpip.h里的定义
.code
.public _RTL8019AS_INIT
_RTL8019AS_INIT: .proc
push BP to [SP]
// Change IOA to input
SP_IOA_IN BP
// 1. Read Port (IOBase + 0x1f), Software Reset, at page 0. Software reset.
RTL8019AS_RD_WORD RTL8019AS_ADDR_1F, R1, BP
// Chang IOA to output
SP_IOA_OUT BP
// Check RTL8019AS is online?
// 2. Write Port (IOBase + 0x00) with 0x21
R1 = RTL8019AS_CR_STOP|RTL8019AS_CR_ABORT|RTL8019AS_CR_P0
RTL8019AS_WR_WORD RTL8019AS_ADDR_00, R1, BP
// Change IOA to input
SP_IOA_IN BP
// 3. Read Port (IOBase + 0x00) and check. if RTL8019AS is offline, return 0
RTL8019AS_RD_WORD RTL8019AS_ADDR_00, R1, BP
R1 &= 0x00ff
cmp R1, RTL8019AS_CR_STOP|RTL8019AS_CR_ABORT|RTL8019AS_CR_P0
jz RTL8019AS_INIT_1
R1 = 0
PC = RTL8019AS_INIT_EXIT
RTL8019AS_INIT_1:
// Chang IOA to output
SP_IOA_OUT BP
// 4. Write NE2000 Page 0 and Page 1 as follows:
// 5. Write Port (IOBase + 0x0E) with 0x81, Word-wide data transfer, Loop
// 6. Write Port (IOBase + 0x0F) with 0x0f, Set Interrupt Mask Register
// Page 0, IMR=0x0f/DCR=0x81
R1 = RTL8019AS_DCR_LOOP
RTL8019AS_WR_WORD RTL8019AS_ADDR_0E, R1, BP
R1 = RTL8019AS_IMR
RTL8019AS_WR_WORD RTL8019AS_ADDR_0F, R1, BP
// 7. Write Port (IOBase + 0x0C) with 0xcc, Interrupt high active, Accept multicast
// 8. Write Port (IOBase + 0x0D) with 0xf2, TCR, Internal loop-back mode
// Page 0, TCR=0xf2/RCR=0xcc
R1 = RTL8019AS_RCR
RTL8019AS_WR_WORD RTL8019AS_ADDR_0C, R1, BP
R1 = RTL8019AS_TCR_LOOP
RTL8019AS_WR_WORD RTL8019AS_ADDR_0D, R1, BP
// 9. Write Port (IOBase + 0x01) with 0x46, Set Start Page Register = 0x46
// 10. Write Port (IOBase + 0x02) with 0x80, Set Stop Page Register = 0x80
// 11. Write Port (IOBase + 0x03) with 0x46, Set Boundary Register = 0x46
// 12. Write Port (IOBase + 0x04) with 0x40, Set TX Start Page
// Page 0, PSTART(at page 0)=0x46/CR
R1 = RTL8019AS_PSTART
RTL8019AS_WR_WORD RTL8019AS_ADDR_01, R1, BP
// Page 0, BNRY=0x46/PSTOP=0x80
R1 = RTL8019AS_PSTOP
RTL8019AS_WR_WORD RTL8019AS_ADDR_02, R1, BP
R1 = RTL8019AS_BNRY
RTL8019AS_WR_WORD RTL8019AS_ADDR_03, R1, BP
// Page 0, TBCR0=0x00/TPSR=0x40
R1 = RTL8019AS_TPSR
RTL8019AS_WR_WORD RTL8019AS_ADDR_04, R1, BP
// 13. Write Port (IOBase + 0x07) with 0xff, Clear Interrupt Status Register
// Page 0, ISR=0xff/TBCR1=0x00
R1 = RTL8019AS_ISR
RTL8019AS_WR_WORD RTL8019AS_ADDR_07, R1, BP
// 14. Write Port (IOBase + 0x00) with 0x61, Set to Page 1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -