在看datasheet的时候看到GPIO的部分有这么一段话:
When using the GPxDAT register to change the level of an output pin, you should be cautious not to
accidentally change the level of another pin. For example, if you mean to change the output latch level
of GPIOA0 by writing to the GPADAT register bit 0, using a read-modify-write instruction. The problem
can occur if another I/O port A signal changes level between the read and the write stage of the
instruction. You can also change the state of that output latch. You can avoid this scenario by using
the GPxSET, GPxCLEAR, and GPxTOGGLE registers to load the output latch instead.
我在想改变一个GPIO口的值的话直接写不就行了吗?为什么还需要 read和modify呢。
为什么用GPxSET, GPxCLEAR, and GPxTOGGLE 就不会出现它说的那种错误发生呢?
感觉后面那段话能说明一些问题。
The GPxDAT registers reflect the state of the pin, not the latch. This means the register reflects the
actual pin value. However, there is a lag between when the register is written to when the new pin
value is reflected back in the register. This may pose a problem when this register is used in
subsequent program statements to alter the state of GPIO pins. An example is shown below where two
program statements attempt to drive two different GPIO pins that are currently low to a high state.
If Read-Modify-Write operations are used on the GPxDAT registers, because of the delay between the
output and the input of the first instruction (I1), the second instruction (I2) will read the old value and
write it back.
GpioDataRegs.GPADAT.bit.GPIO1 = 1 ; I1 performs read-modifywrite of GPADAT GpioDataRegs.GPADAT.bit.GPIO2 = 1 ; I2 also a read-modifywrite of GPADAT. ; It gets the old value of GPIO1 due to the delay
The second instruction will wait for the first to finish its write due to the write-followed-by-read
protection on this peripheral frame. There will be some lag, however, between the write of (I1) and the
GPxDAT bit reflecting the new value (1) on the pin. During this lag, the second instruction will read the
old value of GPIO1 (0) and write it back along with the new value of GPIO2 (1). Therefore, GPIO1 pin
stays low.
大概就是说这个核心是多级流水线的感觉。指令不是马上产生效果的意思。然后再在后面语句使用dat寄存器的话就会使用dat寄存器之前的值,就会出问题。所以后面他写的解决方法一就是插入一些NOP。以等待流水线操作完成。
就是产品的Tech Reference book 里面。我把28069的传上来给你看看。第117页。我的理解是虽说dsp是单指令周期完成的。但是其实是六个周期+六级流水线。(具体c28x是不是六我就有点忘了,我记得cla是),然后比如第个改gpio1的时候可以改,但是实际是若干个周期之后(write环节)才实际上吧gpiodat寄存器更新了。但是在第二个周期的时候要改gpio2的时候就要先读取旧的gpiodat的数据(fetch)然而这一步实际上在write之前就做了。所以就是一个0了。然后就出了问题。
我大概是这么理解的。有错误欢迎指正。