APB(Advanced Peripheral Bus),从扩展名可以看出,其主要是用作访问外设(如UART,I2C,SPI等)的一类总线,功能也比较简单,一次只能发一笔读命令或者一笔写命令,不能burst传输。APB2.0的读写时序如下:
APB2.0写时序
APB2.0读写混合时序
每一笔读写命令均在两个cycle内完成,PSEL拉高是第一拍,PENABLE拉高是第二拍,如果没有后续操作,下一个cycle,PSEL和PENABLE均要拉低。master和slave之间不存在握手环节,即master不关注操作是否已经被slave执行。挂在总线上的slave IP必须满足这样的要求:
1、对于写操作,检测到PSEL拉高或者PENABLE拉高后需要把写数据和写地址采集下来,并且保证所有被采集下来的命令都会被执行;
2、对于读操作,在检测到PSEL拉高后必须将读地址采集下来,并在下一个cycle返回读数据,中间不能有延迟。
所有使用APB2.0的IP都必须满足以上两点要求,否则无法使用此协议。
除此之外还存在一个问题,即master无法得知此笔操作是否被slave正确执行了,例如你向slave的一个只读寄存器发了一笔写命令,很显然,这个操作是不会被slave执行的,但是master如果不通过一些其它操作是无法知晓这件事情的(怎样可以知晓呢,大家可以自己想一下)。
为了解决上述问题,APB3.0协议应运而生。
其实解决上述问题很简单,APB3.0里增加了两个信号PREADY和PSLVERR。
其中PREADY用于和master进行握手,即如果slave能及时接收并处理master的命令,则PREADY拉高同时执行命令即可,否则可以通过拉低PREADY信号告知master,自己目前还无法处理这笔命令,master看到PREADY为低后就得到了这一信息,相应地,其会一直保持总线上的命令信息不变且一直有效,直到slave能够接收并处理此命令为止。
除此之外slave还可以通过PSLVERR信号告知此笔命令是否被正确执行了,如果没有被正确执行,则拉高PSLVERR告知master有错误发生。
APB3.0协议下的读写时序如下:
APB3.0读写时序
上图中包含了两笔读命令RC0(read command 0)、RC1以及一笔写命令WC0,其中RC0和WC0均通过PREADY信号延迟了一拍,两笔命令均被执行成功;RC1没有延迟,但是slave返回了PSLVERR,来表明这笔读命令有错误发生。
可以看出虽然只增加了两个信号,但是协议的灵活性得到了大大的提升。
而且APB3.0可以向下兼容APB2.0,只需要将PREADY和PSLVERR信号分别tie为1和0即可。