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
boards: shield: support st_b_lcd40_dsi1_mb1166 A09 #70350
boards: shield: support st_b_lcd40_dsi1_mb1166 A09 #70350
Conversation
Hello @erian747, and thank you very much for your first pull request to the Zephyr project! |
Thanks @erian747 for this contribution. Please rebase on top of main branch to fix reported conflicts |
@erian747 The conflicts are most likely related to HWMv2, checkout https://docs.zephyrproject.org/latest/hardware/porting/board_porting.html for more info. |
093edc6
to
2353ffd
Compare
Thanks! |
@erian747 you have compliance issue in CI (you can run the checks locally before pushing using
|
|
||
if NT35510 | ||
|
||
config DISPLAY_NT35510_INIT_PRIORITY |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the custom init priority needed here? Is this because of the dependency this display will have on the LTDC and the MIPI DSI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it was discussed here #68527 (comment)
drivers/display/display_nt35510.c
Outdated
return ret; | ||
} | ||
|
||
static int nt35510_write(const struct device *dev, uint16_t x, uint16_t y, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These stub functions aren't needed- the display API will return -ENOSYS
if they are not present
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so if i understand you correctly, you mean i can remove
the stub and let write function pointer be initialized to NULL?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, exactly. Just remove the function definition and entry in the API structure.
drivers/display/display_nt35510.c
Outdated
static int nt35510_set_brightness(const struct device *dev, const uint8_t brightness) | ||
{ | ||
return nt35510_write_reg(dev, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, &brightness, 1); | ||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Second return not needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, will fix :)
drivers/display/display_nt35510.c
Outdated
{ | ||
struct nt35510_data *data = dev->data; | ||
|
||
data->dsi_pixel_format = pixel_format; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should there be a check here to verify the requested pixel format is actually supported?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes you are right, and "enum display_pixel_format" must also be mapped into MIPI_DSI_PIXFMT_xxx values
Also realized that resulting color is hardcoded in mipi_dsi_stm32_attach (dsi_stm32.c):
"vcfg->ColorCoding = STM32_DSI_INIT_PIXEL_FORMAT" which comes from LTDC color configuration
But i will fix the verification and mapping to DSI colors in display_nt35510.c
drivers/display/display_nt35510.c
Outdated
static const uint8_t nt35510_caset_landscape[] = {0x00, 0x00, 0x03, 0x1F}; | ||
static const uint8_t nt35510_raset_landscape[] = {0x00, 0x00, 0x01, 0xDF}; | ||
|
||
ret = nt35510_write_reg(dev, 0xF0, nt35510_reg, 5); /* LV2: Page 1 enable */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer to avoid using this method of checking the return code- it makes it difficult for a developer to see where the write actually failed when debugging (since they would need to check the value of ret
each time).
Maybe put these initialization commands into a const array, and loop over that array? Something like the following:
struct nt35510_init_cmd {
uint8_t reg;
uint8_t cmd_len;
uint8_t cmd[]
};
static const struct nt35510_init_cmd init_cmds[] = {
{
.reg = 0xF0, /* LV2: Page 1 enable */
.cmd_len = 5,
.cmd = {0x03, 0x03, 0x03},
};
....
struct nt35510_init_cmd *cmd;
for (int i = 0; i < ARRAY_SIZE(init_cmds); i++) {
cmd = init_cmds[i];
ret = nt35510_write_reg(dev, cmd->reg, cmd->cmd, cmd->cmd_len);
if (ret < 0) {
return ret;
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, will possibly occupy less program space too
I will borrow your example above and extend it with a delay struct member needed for those two
delays required in initialization sequence
- 180 | ||
- 270 | ||
description: | | ||
Display rotation (CW) in degrees. Defaults to 0, display default. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit- spell clockwise out, no need to abbreviate in documentation
|
||
if NT35510 | ||
|
||
config DISPLAY_NT35510_INIT_PRIORITY |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it was discussed here #68527 (comment)
To support the NT35510 display, some additional options needs to be configurable in the STM32 DSI peripheral Signed-off-by: Erik Andersson <erian747@gmail.com>
For now DSI settings are hard-coded for the specific LCD module used on the STM32H747I Discovery board Signed-off-by: Erik Andersson <erian747@gmail.com>
Add support for the A09 version of MB1166 which have a NT35510 panel controller instead of an OTM8009a as in prior versions Fixes zephyrproject-rtos#60888 Signed-off-by: Erik Andersson <erian747@gmail.com>
2353ffd
to
c61c6c0
Compare
Hi @erian747 just tested your PR on an stm32h747i-disco kit with otm8009a controller & it works fine with no apparent issues.
|
Add tests for shield st_b_lcd40_dsi1_mb1166_a09 in: samples/drivers/display samples/modules/lvgl/demos samples/subsys/display/lvgl Signed-off-by: Erik Andersson <erian747@gmail.com>
Applied patch from @ajarmouni-st |
struct nt35510_init_cmd { | ||
uint8_t reg; | ||
uint8_t cmd_len; | ||
uint8_t cmd[5]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't know if you care to do this, but you can probably save flash space by making this cmd
field a pointer, and then declaring the init command arrays separately (like so):
static const uint8_t lv2_cmds[] = {0x55, 0xaa, 0x52, 0x08, 0x01};
static const struct nt35510_init_cmd init_cmds[] = {
/* LV2: Page 1 enable */
{.reg = 0xf0, .cmd_len = sizeof(lv2_cmds), .cmd = lv2_cmds},
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes i also taught in that direction to avoid a fixed size array of parameter data (cmd[5])
But a bit cumbersome of having lots of pointers and extra separate const arrays
One other option that might can be considered is the format that follows in example code below
Most compact variant and still enough human readable in my opinion, if formatted correctly
and comments are used
What do you think?
/*
* LCD controller initialization data
* First byte is command ( or register ) (CMD)
* Second byte is N number of parameter bytes following
* Next is N bytes of parameter data
*
* [CMD] [N] [DATA[0]...[DATA[N] ]
* Directly after last data byte next command / register follows
* Sequence ends when N equals 255
*/
static const uint8_t init_cmds[] = {
/* LV2: Page 1 enable */
0xf0, 5, 0x55, 0xaa, 0x52, 0x08, 0x01,
/* AVDD: 5.2V */
0xb0, 3, 0x03, 0x03, 0x03,
/* AVDD: Ratio */
0xb6, 3, 0x46, 0x46, 0x46,
/* AVEE: -5.2V */
0xb1, 3, 0x03, 0x03, 0x03,
/* AVEE: Ratio */
0xb7, 3, 0x36, 0x36, 0x36,
/* Example EOL */
0xff,0xff
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could do something like this, my concern is implementing parsing code for that case seems unnecessarily complicated. Truthfully I'm not very worried about the extra few bytes used by this approach- the parts this display will be targeting generally have a lot of flash space.
If you want to implement this method or the one I suggested above, feel free to- but I'm also fine with the implementation as is
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that's true, a few bytes extra here would not be critical in a system with a high resolution display :)
Then i leave it as it is right now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Display changes look good to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work, thanks!
Thank you, now that i have learnt atleast i little bit of "ways of working" with Zephyr, so i can |
..._lcd40_dsi1_mb1166/boards/st_b_lcd40_dsi1_mb1166_a09/stm32h747i_disco_stm32h747xx_m7.overlay
Outdated
Show resolved
Hide resolved
Yes, im pretty sure Motherboard and Shield revisions are changed
independently of each other
Den mån 25 mars 2024 09:30Abderrahmane ***@***.***> skrev:
… ***@***.**** commented on this pull request.
------------------------------
On
boards/shields/st_b_lcd40_dsi1_mb1166/boards/st_b_lcd40_dsi1_mb1166_a09/stm32h747i_disco_stm32h747xx_m7.overlay
<#70350 (comment)>
:
I don't think so, the board is still the same, only the display shield was
revised.
—
Reply to this email directly, view it on GitHub
<#70350 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AC4NPBXEI3IB3NGTHN5WIRDYZ7OCXAVCNFSM6AAAAABE2P54B6VHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMYTSNJXGEYTCMRVG4>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Explain the different versions of the MB1166 shield and remove note about that version A09 is not supported Signed-off-by: Erik Andersson <erian747@gmail.com>
a8faffa
Hi @erian747! To celebrate this milestone and showcase your contribution, we'd love to award you the Zephyr Technical Contributor badge. If you're interested, please claim your badge by filling out this form: Claim Your Zephyr Badge. Thank you for your valuable input, and we look forward to seeing more of your contributions in the future! 🪁 |
Adds support for the A09 version of STM32H747I Dsiocery shield MB1166
Fixes #60888
Changes:
Add display driver NT35510 mounted on the MB1166-A09 version
Add new shield revision in boards/shields/st_b_lcd40_dsi1_mb1166
Update STM32 DSI driver with a few more device tree options required
to support NT35510
Tested on a STM32H747I Discovery board with a mounted MB1166-A09 shield
NOT tested with the older revision of shield as i don't own any
Old shield configuration compiles ok but maybe it would be good if someone having an old shield
could make a quick test and see nothing has been broken after restructuring in shield folder