Skip to content

Conversation

bergzand
Copy link
Member

Contribution description

Simple driver and test application of the ili9341

Testing procedure

Test application included

Review notes

I've wrote this driver quite a while ago, it might be missing some of the newer coding practices.

Issues/PRs references

None

@bergzand bergzand added Type: new feature The issue requests / The PR implemements a new feature for RIOT Area: drivers Area: Device drivers labels Sep 17, 2018
@bergzand bergzand requested a review from aabadie September 17, 2018 08:37
@aabadie
Copy link
Contributor

aabadie commented Sep 17, 2018

Yeah! Thanks @bergzand :)
I'll test this one asap.

@bergzand
Copy link
Member Author

@aabadie Which board had this display on it? And what is the most useful default pinout for it?

@aabadie
Copy link
Contributor

aabadie commented Sep 17, 2018

Which board had this display on it?

stm32-f429i-disc1

And what is the most useful default pinout for it?

Look at this branch and in particular, this commit, the second commit also provides some cleanup

(edit: fixed the commit links)

Copy link
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had a quick pass of review and found minor things. I also think some parts of the code could be uncrustified (missing spaces around some operators).
Otherwise, see my previous comment about having default params for the stm32f429i-disc1 board and params initialization.
The test application also needs a README.
And finally, one question: the driver doesn't allow to display images. Do you have an idea how this could be done ?

@@ -0,0 +1,2 @@
MODULE = ili9341
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is not needed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will remove

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still unaddressed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, fixed

} ili9341_t;


int ili9341_init(ili9341_t* dev, ili9341_params_t* prms);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing doxygen documentation

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, I checked for that, will fix 😄

@bergzand
Copy link
Member Author

And finally, one question: the driver doesn't allow to display images. Do you have an idea how this could be done ?

The driver works by selecting an area on the display and update all pixels in that area. This closely match the lower level hardware. So yes, an image is possible, but I'd have to generate something from a bitmap.

Say we have an image of the RIOT logo of X by Y pixels, we can use the ili9341_map function with x2-x1==X and y2-y1==Y to stream the pixels to build the logo to the device. *colors just needs to be an array of pixels, X*Y long, to build the logo.

If I have some time I can try to build it, otherwise feel free to open an PR on my branch :)

@aabadie
Copy link
Contributor

aabadie commented Sep 18, 2018

By the way, I tested this PR (with my 2 extra commits applied) and it works like a charm.

@x3ro
Copy link
Contributor

x3ro commented Oct 5, 2018

Just verified that this also works fine on the stm32f429-disco. A few things I noticed:

  • For the pin defines, you use a different wording than the ST SDK uses in the case of DC (yours) vs WRX (SDK and source I found). I have no idea which one is "the better" name, just wanted to point it out. DC confused me a bit because I immediately expanded it to "direct current" :D
  • Apparently the reset pin is not connected on the stm32f429-disco according to this. I set it to an arbitrary pin and it seems to work. What is this used for? Do I need it?

Just for reference, I used this configuration in :

BOARD=stm32f429i-disc1
TEST_SPI ?= SPI_DEV\(0\)
TEST_SPI_CS ?= GPIO_PIN\(PORT_C,2\)
TEST_SPI_CLK ?= SPI_CLK_10MHZ
TEST_PIN_DC ?= GPIO_PIN\(PORT_D,13\)
TEST_PIN_RST ?= GPIO_PIN\(PORT_A,7\)

I took the pin assignment from here.

@aabadie
Copy link
Contributor

aabadie commented Oct 5, 2018

@x3ro, can you try this branch ? I tested it on the disc1 version. It uses the right way of passing driver parameters and I'd like @bergzand to include my changes in his PR (I don't know why I can't open a PR on top of this one)

@bergzand
Copy link
Member Author

bergzand commented Oct 5, 2018

@aabadie I have some time this weekend to work on the driver, just have to build a small setup to test the device.

@x3ro
Copy link
Contributor

x3ro commented Oct 6, 2018

Hey @aabadie, yeah your branch works fine. I'm just wondering whether the pin information should really go in the driver, given that it's quite board specific. Also, why are you using magic numbers for the ports instead of e.g. PORT_A?

@aabadie
Copy link
Contributor

aabadie commented Oct 13, 2018

Any news here @bergzand ?

I'm just wondering whether the pin information should really go in the driver, given that it's quite board specific

I would say that this is not required. Maybe a comment in the driver would be enough. It just that this screen is provided by this board, which is already available in RIOT.

why are you using magic numbers for the ports instead of e.g. PORT_A?

If we use PORT_A the driver won't build with some architectures like sam0 which uses PA. This could be fixed by the way.

@x3ro
Copy link
Contributor

x3ro commented Oct 13, 2018

@aabadie That would also be fixed by removing the pin info from the driver and putting it in the board, right? Or in other words, not define ILI9341_PARAM_* in the driver at all.

@aabadie
Copy link
Contributor

aabadie commented Oct 13, 2018

Or in other words, not define ILI9341_PARAM_* in the driver at all.

What do you mean exactly ? using GPIO_UNDEF ?

@bergzand
Copy link
Member Author

Any news here @bergzand ?

Let's start with a rebase here to have all the new board names.

@bergzand
Copy link
Member Author

* For the pin defines, you use a different wording than the ST SDK uses in the case of `DC` (yours) vs `WRX` (SDK and source I found). I have no idea which one is "the better" name, just wanted to point it out. `DC` confused me a bit because I immediately expanded it to "direct current" :D

The name of the pin is indeed WRX, but it only has the WRX function when using the parallel interface. When using the 4-line system (AKA SPI), it is called D/CX.

Apparently the reset pin is not connected on the stm32f429-disco according to this. I set it to an arbitrary pin and it seems to work. What is this used for? Do I need it?

I've made the reset pin optional, GPIO_UNDEF is now a valid value for the pin and will result in the hardware reset not being used. For my setup this doesn't work as the device requires a hardware reset before initialization, but if the reset of the board is attached to the reset of the display it might be good enough.

@bergzand
Copy link
Member Author

@aabadie I think I've covered all your issues.

I've added an little endian mode in case the data is in little endian format. this slows down the driver a bit, so big endian is preferred, but it is useful to have when the source data/image is in little endian format.

@bergzand
Copy link
Member Author

There is one remaining issue and that is that I can't seem to read data from the display. While not necessarily an issue when using the device, it would be nice to have.

@aabadie Could you please test if reading data from the display works for you? I'm not sure if it is because of my hardware or that I'm doing something wrong in the driver.

I'd rather not block this PR on this bug since it is not really critical for using the display.

spi_release(dev->params.spi);
}

static void ili9341_set_area(ili9341_t *dev, uint16_t x1, uint16_t x2,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it is an idea to add this to the public API. Together with a write function that allows one to set n bytes in memory this would allow the writing of an area in multiple chunked writes. I have no use case for this, so feel free to ignore.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can always extend the API in a follow up PR :)

* @param[in] dev device descriptor
* @param[in] cmd command
* @param[in] data data from the device
* @param[in] len length of the returned data
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to me that data is data to the device and len is the length of that data.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sssssht

* @param[in] y2 y coordinate of the opposite corner
* @param[in] color array of colors to fill the area with
*/
void ili9341_map(ili9341_t *dev, uint16_t x1, uint16_t x2, uint16_t y1,
Copy link
Contributor

@silkeh silkeh Oct 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the function name is clear. Maybe fill_pixels is clearer?

Copy link
Contributor

@silkeh silkeh Oct 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional observation: x2/y2 seem to be the the x/y-coordinate of the pixel in the opposite corner, not the opposite corner itself (same for all other x2/y2's).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the function name is clear. Maybe fill_pixels is clearer?

Ack

Additional observation: x2/y2 seem to be the the x/y-coordinate of the pixel in the opposite corner, not the opposite corner itself (same for all other x2/y2's).

So a documentation fix?

Copy link
Contributor

@silkeh silkeh Oct 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If explained clearly a documentation fix is fine to me, but a code change would enable users to do things like: fill_pixels(x, y, x + picture_width, y + picture_height, picture). (instead of fill_pixels(x, y, x + picture_width - 1, y + picture_height - 1, picture), which isn't as intuitive)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to pixmap and added some docs

void ili9341_fill(ili9341_t *dev, uint16_t x1, uint16_t x2, uint16_t y1, uint16_t y2, uint16_t color);

/**
* @brief Fill a rectangular area with an array of colors
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think 'pixels' would be clearer than 'colors'. A note to remind users that the input data should exactly match the size of the area might also be useful.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack and ack

Copy link
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost forgot this PR, but I still like it :)

Any chance that you could update it before the next feature freeze (18/01) ? There are unaddressed comments from @silkeh and a README is still missing for the test application.


int ili9341_init(ili9341_t *dev, const ili9341_params_t *prms)
{
memcpy(&dev->params, prms, sizeof(ili9341_params_t));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
memcpy(&dev->params, prms, sizeof(ili9341_params_t));
dev->params = *prms; /* maybe also rename prms to params ? */

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworked!

Copy link
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested this PR and it's still working well, except a minor issue with the RIOT logo (see my comment below).

@bergzand do you think you can update/rebase your PR so we can move forward with this ?

@@ -0,0 +1,71 @@
const uint16_t picture[69][128] = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of 69, I had to use 70 with an extra empty line at the end of array to avoid having an alone green pixel at the bottom right of the logo.
I have no idea why it was there. One could think of a division by 2 issue but there is no such thing in ili9341_map implementation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And fixed, I was able to reproduce your issue and it should be fixed in the latest iteration.

@aabadie
Copy link
Contributor

aabadie commented Oct 24, 2019

@bergzand, ping! There are still unaddressed comments and this PR would be useful for #12552.

@kaspar030
Copy link
Contributor

The ST7789V used on the PineTime needs spi mode 3. I git a commit adding that (https://github.com/kaspar030/RIOT/tree/ili9341_spi_mode). Maybe cherry-pick in here?

@kaspar030
Copy link
Contributor

Otherwise, please address @aabadie's problem and rebase and squash. ;)

@bergzand
Copy link
Member Author

bergzand commented Nov 6, 2019

@kaspar030 @aabadie: Does it still make sense to name the driver ili9341? There are with @kaspar030's addition multiple different TFT display chips making use of this driver. Maybe some generic name is better in this case, but we can leave this rename for a follow up.

* @brief Device descriptor for a ili9341
*/
typedef struct {
ili9341_params_t params; /**< I2C device that sensor is connected to */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed!

@bergzand
Copy link
Member Author

bergzand commented Nov 6, 2019

Rebased, fixed some issues with the driver, also cleaned a few things up

@bergzand
Copy link
Member Author

bergzand commented Nov 6, 2019

@aabadie @kaspar030: Still okay to squash?

@bergzand
Copy link
Member Author

bergzand commented Nov 6, 2019

Maybe cherry-pick in here?

Cherry picked!

@aabadie
Copy link
Contributor

aabadie commented Dec 7, 2019

Please squash and rebase. Just a suggestion that could be nice to use with the test application: put the RIOT logo in a blob and include it to the build ? That would make it easy for testing with other images. What do you think ?

@bergzand
Copy link
Member Author

bergzand commented Dec 8, 2019

Just a suggestion that could be nice to use with the test application: put the RIOT logo in a blob and include it to the build ?

I think this is not that easy, so I'd rather leave this for somebody else to follow up on. To use the blob Makefile construct, the supplied file needs to be the raw image in rgb 565 format without any metadata. I don't think there is any advantage to including that instead of the image in C header format. What I'd rather see is something similar to the blob construct, but for png images, add a number of PNG images to a Make variable and the build will convert them to C header format in raw rgb 565 format. Then we could even include a repo with RIOT logo images as external package.

@bergzand bergzand force-pushed the pr/ili9341 branch 2 times, most recently from 9d0cde8 to 1c047b8 Compare December 8, 2019 14:24
@bergzand
Copy link
Member Author

bergzand commented Dec 8, 2019

@aabadie Rebased and squashed!

@aabadie aabadie added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Dec 8, 2019
@aabadie
Copy link
Contributor

aabadie commented Dec 9, 2019

@bergzand, Murdock is reporting some remaining issues. Can you have a look ?

@bergzand
Copy link
Member Author

@aabadie I've excluded the image draw from the test when using AVR microcontrollers. On the AVR architecture, the image data ends up in the RAM. The approximately 16KB of image data doesn't fit on those devices.

Storing them in flash would require something along the lines of the PROGMEM macro which is out of scope here :)

@bergzand
Copy link
Member Author

@aabadie I've added the stm32f030f4-demo to the insufficient memory list. This is the only board that causes build failures for now. Murdock says all green (except for the static test).

Is it okay to squash again?

@aabadie
Copy link
Contributor

aabadie commented Dec 11, 2019

Please squash!

@bergzand
Copy link
Member Author

Squashed!

@fjmolinas
Copy link
Contributor

Tested on stm32429i-disc, all good.

@fjmolinas fjmolinas added the Reviewed: 3-testing The PR was tested according to the maintainer guidelines label Dec 11, 2019
@aabadie
Copy link
Contributor

aabadie commented Dec 11, 2019

Tested on stm32429i-disc, all good.

Thanks @fjmolinas !

Copy link
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK!

@aabadie
Copy link
Contributor

aabadie commented Dec 11, 2019

All green, go!

@aabadie aabadie merged commit a9bf691 into RIOT-OS:master Dec 11, 2019
@bergzand
Copy link
Member Author

🎉
Thanks @aabadie!

@bergzand bergzand deleted the pr/ili9341 branch December 11, 2019 15:50
@fjmolinas fjmolinas added this to the Release 2020.01 milestone Dec 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: drivers Area: Device drivers CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Reviewed: 3-testing The PR was tested according to the maintainer guidelines Type: new feature The issue requests / The PR implemements a new feature for RIOT
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants