Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support ltdc in a similar way as stm32f7xx-hal #256

Open
jonasdn opened this issue Jan 29, 2021 · 0 comments · May be fixed by #731
Open

Support ltdc in a similar way as stm32f7xx-hal #256

jonasdn opened this issue Jan 29, 2021 · 0 comments · May be fixed by #731

Comments

@jonasdn
Copy link

jonasdn commented Jan 29, 2021

Hi!

I am new to the Rust world in general, and Rust embedded in particular. I have a stm32f469i-discovery board (https://www.st.com/en/evaluation-tools/32f469idiscovery.html) which have a display connected via the LTDC interface.

Is there anywhere I can look to see how I can implement support for it? The stm32f7xx-hal has an example on how to deal with the screen on the stm32f746g-discovery board. But it seems that the same support in this stm32f4xx-hal is not present? Or am I missing something?

If I am not missing something: would it be desirable to add similar support in this hal for LTDC screens?
And if I am missing something: do you have any pointers to where to look so that I could implement an example for the screen on the stm32f469i-discovery board?

Thanks
Jonas

ZhiyaoMa98 added a commit to ZhiyaoMa98/stm32f4xx-hal that referenced this issue Jul 2, 2023
The `modify` method executes a read-modify-write operation on the `cr1` control register, as can be verified with the following disassembly code. Notably, the `read` variable is assigned a constant `true` within the example, which results in the elimination of the if comparison due to compiler optimization.

```
 8004a5e:	f645 4400 	movw	r4, #23552	@ 0x5c00
 8004a62:	4605      	mov	r5, r0
 8004a64:	f2c4 0400 	movt	r4, #16384	@ 0x4000    // r4 holds cr1 address
 8004a68:	4688      	mov	r8, r1
 8004a6a:	6820      	ldr	r0, [r4, #0]              // read cr1 [first read]
 8004a6c:	466e      	mov	r6, sp
 8004a6e:	f440 7080 	orr.w	r0, r0, stm32-rs#256	@ 0x100   // modify start bit
 8004a72:	6020      	str	r0, [r4, #0]              // write cr1 [first write]
 8004a74:	6820      	ldr	r0, [r4, #0]              // read cr1 [second read]
        /*  Code breaks if IRQ here  */
 8004a76:	f440 6080 	orr.w	r0, r0, #1024	@ 0x400   // modify ack bit
        /*  Code breaks if IRQ here  */
 8004a7a:	6020      	str	r0, [r4, #0]              // write cr1 [second write]
```

The issue arises when an IRQ occurs between the second read and write operations. Due to the CPU's faster execution speed compared to the peripheral, it is highly likely that the second read operation will still observe the `cr1` register with the `start` bit set. However, if an IRQ is serviced, the peripheral may have sufficient time to complete generating the start condition, resulting in the hardware clearing the `start` bit in the peripheral's `cr1` register. Nonetheless, the copy of the `cr1` register stored in `r0` during the second read operation will still retain the `start` bit set. Consequently, when the second write operation is executed on `cr1`, the `start` bit is once again set. As a result, the peripheral attempts to generate a second start condition, leading to a situation where the I²C peripheral becomes unresponsive in my specific case.

The solution is to swap the two method calls. Once the `ack` bit is set, it will not be automatically cleared, thus we are safe even if being interrupted in between.
@burrbull burrbull linked a pull request Jan 15, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant