如何测试 Bit-Banged 通信的汇编例程
How to test Bit-Banged communication's assembly routines
对于一个 MCU,我编写了一些汇编例程,以位爆炸方式执行专有协议(基于 UART)的 RX 和 TX。我如何测试它们?
TX 可以通过发送数据进行测试,同时在逻辑分析仪的帮助下,检查所有采样时序是否正确(手动或使用一些脚本)。
另一方面,RX 更难。一方面我可以检查我是否收到其他人发送的内容,但另一方面我如何知道 RX 采样是否正确发生(时间方面)?
例如,我的 RX 例程可能 return 通过在 "bit window" 的边缘而不是中间采样来获得正确的数据。
我考虑过切换 "debug pin" 以指示采样实际发生的时间,但这会在采样过程中引入延迟,因此我不会测试我的原始例程。
一些值得在阅读评论后澄清的事情:
- 我知道硬件 UART 更好(虽然这取决于),但我不能使用它。这不是 "have you tried this ...?";
的问题
- 我知道怎么打位了(汇编程序我已经写好了);
- 我无法将 TX 连接到 RX,因为我只使用了一根线(通信是半双工的);
- 我问的是如何测试 RX 采样时序,而不是如何实现 UART。
您需要一些东西来向 MCU 发送数据,也许是第二个 MCU。我已经为旧的 8 位 Atari 外设编写了 6502 和 Z80 的类似代码。这些是半双工协议,因此只要设备空闲,它就会轮询起始位。检测到一个起始位后,延迟1.5位时间,然后接收8位,位与位之间有1位时间。数据例程的接收和发送都经过编码,以获得精确的计时周期计数。这些都是旧设备,即使是最快的比特率也相对较慢,每比特 19 微秒 ~= 52600 波特。
问题已更新。如果输入和输出指令的时间完全相同运行(循环计数),您可以修改接收代码以发送数据以验证位时间,并确认处理器的速度到底有多快运行宁.
关于检测起始位和等待1.5位时间的时序,你必须计算检测起始位的最小和最大周期数。最大循环计数将是一个输入指令,它刚好错过起始位的后沿、测试指令和返回输入的循环,然后是另一个测试,然后通过循环下降以继续接收。最小循环计数将是一个输入,它刚好捕捉到起始位的前沿,进行测试,然后进入循环。然后接收代码的剩余部分需要尽可能靠近数据位周期的中间进行采样。
这是一个 4mhz Z80 的代码示例,它以 19 微秒的速度接收数据 == 每个数据位 76 个周期。注释包括每条指令的周期计数。起始位到第一个数据位的理想等待时间为 114 个周期。起始位循环的最小、最大循环时间为 20.50 个循环。使用额外的延迟加上 79 个周期的第一个数据位的输入,因此检测开始接收第一个数据位的最小、最大周期时间为 99,129 个周期,在 76,152 个周期的最小、最大范围内。其余数据位以每位正好 76 个周期的速度读取。
LD E,0 ;SET UP
; ; START BIT TO DATA BIT=114
NRXF0: LD A,(FBS) ;(13) WAIT FOR START BIT
AND FBSRXD ;(7)
JP NZ,NRXF0 ;(10)
; ; NOTE: 20 MIN, 50 MAX, 35 AVG
EX (SP),HL ;(19) DELAY
EX (SP),HL ;(19)
LD A,(HL) ;(7)
NRXF1: LD A,(HL) ;(7)
LD A,(HL) ;(7)
LD D,8 ;(7) 8 BITS PER BYTE
; ; 76 CYCLES PER DATA BIT
NRXF2: LD A,(FBS) ;(13) GET DATA BIT
AND FBSRXD ;(7)
ADD A,0FFH ;(7)
RR C ;(8)
PUSH BC ;(11) DELAY
POP BC ;(10)
NOP ;(4)
DEC D ;(4) LP TIL BYTE DONE
JR NZ,NRXF2 ;(12/7)
RET NZ ;(5) DELAY
NRXF4: LD A,(FBS) ;(13) WAIT FOR NEXT START BIT
AND FBSRXD ;(7)
JP NZ,NRXF4 ;(10)
; ; START BIT TO DATA BIT=114
LD (HL),C ;(7) STORE BYTE
LD A,C ;(4) DO CKSUM
ADD A,E ;(4)
ADC A,0 ;(7)
LD E,A ;(4)
INC HL ;(6) ADV ADR
DJNZ NRXF1 ;(13/8) LP IF MORE BYTES
I thought about toggling a "debug pin" to indicate when the sampling
is actually happening, but this introduces delays in the sampling
procedure, hence I wouldn't be testing my original routine.
使用检测代码进行测试,然后保留检测 - 或near-equivalent 实际上不影响硬件的代码 - 原地.
对于一个 MCU,我编写了一些汇编例程,以位爆炸方式执行专有协议(基于 UART)的 RX 和 TX。我如何测试它们?
TX 可以通过发送数据进行测试,同时在逻辑分析仪的帮助下,检查所有采样时序是否正确(手动或使用一些脚本)。
另一方面,RX 更难。一方面我可以检查我是否收到其他人发送的内容,但另一方面我如何知道 RX 采样是否正确发生(时间方面)?
例如,我的 RX 例程可能 return 通过在 "bit window" 的边缘而不是中间采样来获得正确的数据。
我考虑过切换 "debug pin" 以指示采样实际发生的时间,但这会在采样过程中引入延迟,因此我不会测试我的原始例程。
一些值得在阅读评论后澄清的事情:
- 我知道硬件 UART 更好(虽然这取决于),但我不能使用它。这不是 "have you tried this ...?"; 的问题
- 我知道怎么打位了(汇编程序我已经写好了);
- 我无法将 TX 连接到 RX,因为我只使用了一根线(通信是半双工的);
- 我问的是如何测试 RX 采样时序,而不是如何实现 UART。
您需要一些东西来向 MCU 发送数据,也许是第二个 MCU。我已经为旧的 8 位 Atari 外设编写了 6502 和 Z80 的类似代码。这些是半双工协议,因此只要设备空闲,它就会轮询起始位。检测到一个起始位后,延迟1.5位时间,然后接收8位,位与位之间有1位时间。数据例程的接收和发送都经过编码,以获得精确的计时周期计数。这些都是旧设备,即使是最快的比特率也相对较慢,每比特 19 微秒 ~= 52600 波特。
问题已更新。如果输入和输出指令的时间完全相同运行(循环计数),您可以修改接收代码以发送数据以验证位时间,并确认处理器的速度到底有多快运行宁.
关于检测起始位和等待1.5位时间的时序,你必须计算检测起始位的最小和最大周期数。最大循环计数将是一个输入指令,它刚好错过起始位的后沿、测试指令和返回输入的循环,然后是另一个测试,然后通过循环下降以继续接收。最小循环计数将是一个输入,它刚好捕捉到起始位的前沿,进行测试,然后进入循环。然后接收代码的剩余部分需要尽可能靠近数据位周期的中间进行采样。
这是一个 4mhz Z80 的代码示例,它以 19 微秒的速度接收数据 == 每个数据位 76 个周期。注释包括每条指令的周期计数。起始位到第一个数据位的理想等待时间为 114 个周期。起始位循环的最小、最大循环时间为 20.50 个循环。使用额外的延迟加上 79 个周期的第一个数据位的输入,因此检测开始接收第一个数据位的最小、最大周期时间为 99,129 个周期,在 76,152 个周期的最小、最大范围内。其余数据位以每位正好 76 个周期的速度读取。
LD E,0 ;SET UP
; ; START BIT TO DATA BIT=114
NRXF0: LD A,(FBS) ;(13) WAIT FOR START BIT
AND FBSRXD ;(7)
JP NZ,NRXF0 ;(10)
; ; NOTE: 20 MIN, 50 MAX, 35 AVG
EX (SP),HL ;(19) DELAY
EX (SP),HL ;(19)
LD A,(HL) ;(7)
NRXF1: LD A,(HL) ;(7)
LD A,(HL) ;(7)
LD D,8 ;(7) 8 BITS PER BYTE
; ; 76 CYCLES PER DATA BIT
NRXF2: LD A,(FBS) ;(13) GET DATA BIT
AND FBSRXD ;(7)
ADD A,0FFH ;(7)
RR C ;(8)
PUSH BC ;(11) DELAY
POP BC ;(10)
NOP ;(4)
DEC D ;(4) LP TIL BYTE DONE
JR NZ,NRXF2 ;(12/7)
RET NZ ;(5) DELAY
NRXF4: LD A,(FBS) ;(13) WAIT FOR NEXT START BIT
AND FBSRXD ;(7)
JP NZ,NRXF4 ;(10)
; ; START BIT TO DATA BIT=114
LD (HL),C ;(7) STORE BYTE
LD A,C ;(4) DO CKSUM
ADD A,E ;(4)
ADC A,0 ;(7)
LD E,A ;(4)
INC HL ;(6) ADV ADR
DJNZ NRXF1 ;(13/8) LP IF MORE BYTES
I thought about toggling a "debug pin" to indicate when the sampling is actually happening, but this introduces delays in the sampling procedure, hence I wouldn't be testing my original routine.
使用检测代码进行测试,然后保留检测 - 或near-equivalent 实际上不影响硬件的代码 - 原地.