In S32K144 one can configure a pin as input and read its state as follows:
bool read_input_pin(uint32_t port_offset, uint32_t pin_offset)
{
GPIO_Type* gpio[5] = GPIO_BASE_PTRS;
PORT_Type* port[5] = PORT_BASE_PTRS;
PCC-> PCCn[PCC_PORTA_INDEX + port_offset] = PCC_PCCn_CGC_MASK; // Enable clock to PORT X
gpio[port_offset]->PDDR &= ~(1<<pin_offset); // Port pin: Data Direction= input
port[port_offset]->PCR[pin_offset] = 0x00000110; // Port pin: MUX = GPIO, input filter enabled
uint32_t val = gpio[port_offset]->PDIR & (1<<pin_offset);
return (0 != val);
}
The above seems to work unless in the translated assembly code (with optimization O1) the writing to PCR register is followed by immediate reading of PDIR register. The last part of the above function translates to the following assembly code:
124 00be 5161 str r1, [r2, #20] <- Writes to PDDR
125 00c0 55F8181C ldr r1, [r5, #-24]
126 00c4 4FF48870 mov r0, #272
127 00c8 41F82400 str r0, [r1, r4, lsl #2] <- Writes to PCR
128 00cc 1269 ldr r2, [r2, #16] <- Reads PDIR into r2
129 00ce 1342 tst r3, r2 <- Checks pin bit with the value in r2
Even though a constant 3.3v is applied to the pin the test in the above assembly line 129 fails and the pin is assumed to have a low state. However, it is enough to either add a nop instruction between PCR write and PDIR read or to read PDIR register twice, the pin state starts to show up as 1. That is, any of the following workarounds help:
Workaround 1. Adding NOP
124 00be 4161 str r1, [r0, #20] <- Writes to PDDR as above
125 00c0 53F8181C ldr r1, [r3, #-24]
126 00c4 4FF48870 mov r0, #272
127 00c8 41F82400 str r0, [r1, r4, lsl #2] <- Writes to PCR as above
128 .syntax unified
129 00cc 00BF nop
130 .thumb
131 .syntax unified
132 00ce 53F82C3C ldr r3, [r3, #-44] <- Loads again GPIO_Type* into r3 again.
133 00d2 1B69 ldr r3, [r3, #16] <- Reads PDIR into r3
134 00d4 1A42 tst r2, r3 <- Test pin state of PDIR as above
Workaround 2. Reading PDIR twice
124 00b8 5161 str r1, [r2, #20] <- Writes to PDDR as above
125 00ba 55F8181C ldr r1, [r5, #-24]
126 00be 4FF48870 mov r0, #272
127 00c2 41F82400 str r0, [r1, r4, lsl #2] <- Writes to PCR as above
128 00c6 1169 ldr r1, [r2, #16] <- Reads PDIR
129 00c8 1269 ldr r2, [r2, #16] <- !Reads PDIR again!
130 00ca 1342 tst r3, r2 <- Same test as above
So it seems that there should be some clock cycles between PCR write and PDIR read but I have not found any information about it in the manual.
Could people from NXP clarify this?
Thanks a lot in advance.
Solved! Go to Solution.
I would say this delay is just caused by input buffer delay. It is needed to realize this are synchronous operation.
If you enable the input buffer, input may be sampled next clock and it sounds logically valid data will be available second clock after enabling.
I guess you dont have enabled digital filter (PORT_Dxxx registers)?
I would say this delay is just caused by input buffer delay. It is needed to realize this are synchronous operation.
If you enable the input buffer, input may be sampled next clock and it sounds logically valid data will be available second clock after enabling.
I guess you dont have enabled digital filter (PORT_Dxxx registers)?
Thanks a lot for the feedback.
Yes, the digital filter was not enabled.
If i understood it correctly, when a pin is configured to be a digital input one needs to wait at least one clock cycle in order the input buffer becomes enabled, and this is the reason why reading the pin state via PDIR register is possible only on the second clock cycle?
It would be very helpful if the manual would indicate this.
Yes, I agree. I will ask for adding this to the documentation.