joukos / PaperTTY

PaperTTY - Python module to render a TTY or VNC on e-ink
953 stars 104 forks source link

Why is CS pin controlled through GPIO and not with SPI? #36

Open kleini opened 4 years ago

kleini commented 4 years ago

I would like to use a second device on the SPI, which requires to let control of CS pin to spi-dev. Otherwise the code simply sets CS pin active while driver for second device currently has CS pin for second device active and transfers data. IT8951 would then receive data meant for second device.

joukos commented 4 years ago

Not sure if I understand your question correctly, but I guess it's like this because it's what the Waveshare examples have originally used. If you're using the IT8951, could you simply change the CS pin for it to some other pin from here: https://github.com/joukos/PaperTTY/blob/master/drivers/driver_it8951.py#L19 ?

kleini commented 4 years ago

Changing the CS pin is not enough. There are two concurrently running parts now in the system for both devices connected to SPI. One is the kernel driver for MCP2515 and the other is this Python code for IT8951. This code and the kernel driver are concurrently sending over SPI. SPI for itself is not the problem, the kernel is able to separate both transfers. The problem is the Python code setting the CS pin, while the kernel driver for MCP2515 is currently transferring. Then both devices, MCP2515 and IT8951 will have their CS pins active and both will listen to the SPI data, although the data is meant for MCP2515. The problem is, that this Python code for IT8951 does not check, whether the CS pin for MCP2515 is active. If the transfer is done using spidev and letting spidev setting CS pin for IT8951, then it will check, whether there is currently CS pin for MCP2515 is already active.

So, what I need, is, that every SPI transfer is done through the kernel, so only one CS pin is selected.

joukos commented 4 years ago

Ah, now I see what you mean, thanks for the explanation. I suppose most just haven't tried to use more than one SPI device at a time with this code. There's a comment in the IT8951 driver about setting the SPI to no_cs mode for some apparently good reason, but since I don't have any of these models, I can't really test much about it (https://github.com/joukos/PaperTTY/blob/master/drivers/driver_it8951.py#L181-L186).

I guess you could try to modify it to not control the CS itself, but the comment implies that it might not work as expected :thinking:

kleini commented 4 years ago

Currently I can only read/write registers, set VCOM, read device info and so on, with letting the control of the CS pin to spidev. Transferring and displaying something does not work at all. I have absolutely no clue, what the problem could be? Especially as I can find absolutely no documentation, about how to transfer image data. Reading and writing registers is described very good including how the CS pin should be active or not. But for an image transfer I am missing all necessary specifications. I will try now your code, so I am able to display at least something and very, that the EPD is not broken. Many thanks for your help so far, I had the hope, that you had deeper insight.

joukos commented 4 years ago

@fimad might have some pointers as he contributed the IT8951 code to PaperTTY. Also @GregDMeyer had a fork with another implementation of the IT8951 support (https://github.com/GregDMeyer/PaperTTY + python driver https://github.com/GregDMeyer/IT8951) so maybe it's worth a look too (discussion is here https://github.com/joukos/PaperTTY/issues/25).

The Waveshare displays can be a bit quirky sometimes and I've thought I'd broken mine a few times, but after just disconnecting everything and trying simple stuff repeatedly they've resumed their operation eventually. Sadly the docs aren't always friendly and may have a lot of timing diagrams and whatnot but seem to lack relevant info for implementing the software that drives the display...

fimad commented 4 years ago

I could not get anything working without setting no_cs including device info and VCOM. Are you modifying the driver in this project or do you have your own code base? Do you have some code pointers you could share?

What are the issues you are having with drawing? Is the display completely non-responsive?

Its been a little while since I've looked at this, so the details are a bit vague. Somethings that I recall giving me issues with drawing included:

kleini commented 4 years ago

My code is actually here. It is based on/copied from this code, which was already mentioned by @joukos. With my implementation I am able to read the device info, set and get registers and VCOM while spi-dev controls the CS pin. What is not working, is to display something. Maybe there are still problems with load image start, load image end, display image commands and/or the image transfer. When running my code, I just see absolutely no reaction on the e-Paper display. It does not even flicker a little bit, no visible reaction at all.

To summarize my efforts, I still need a lot more time, to understand this whole thing, to get the display working and to get the code as fast as possible. This should later be integrated into this code as normal Raspberry Pi displays are nearly not readable in sun light, that's why we want to add an e-Paper display.

GregDMeyer commented 4 years ago

Sorry to be absent for a while---today I'm giving another try to using the python spidev module to handle all the communications here. @kleini did you ever have any luck getting images to show?

FYI---the original reason I had stopped trying to use spidev was because I was running into the same issues you all were discussing above. I couldn't even get the controller to give me the system info back, so the fact that you were able to do that at least is promising! I'll take a look at your code, and see if I can get the data transfer to work too.

kleini commented 4 years ago

My previous post is 4 month now old and a lot happened in the mean time. @GregDMeyer My code here is now working to display full images and partial images but only with GC16 display mode. All other modes are nearly not working and I didn't spent the time yet to find the cause. Transfer rates are pretty good. Displaying a full image just takes 700ms including the 450ms, that the display needs to change information. So the transfer is maybe just 250ms using spi-dev. This is fast enough for my use case but I didn't calculate, what the possible maximum could be. The most tricky part was to be fast enough in the SPI code, to catch the rising edge of the busy pin. The python threading.Event works good enough for me for that case. Actually I would like to integrate all our solutions and let the user decide, whether they want to use direct GPIO pin control or spi-dev.

GregDMeyer commented 4 years ago

cool, sounds good! I'll keep playing with it and see if I can get all the display modes working, and also see if I can work on the speed a bit (it would be really nice for PaperTTY to get the updates working as fast as possible). I'll update when I have something! I'm looking forward to not needing sudo any more ;)

GregDMeyer commented 4 years ago

FYI---I just rewrote the backend of my repo here to talk directly to /dev/spidev*, so that we no longer need either py-spidev or bcm2835 libraries. Also, the data transfer is super fast now! (there are some timing scripts in the tests/ directory there). And you don't need sudo any more! I still have a couple small changes to make but overall I think the library is a lot better than before. Hopefully folks find it useful! If you have any suggestions I would love issues/pull requests.

joukos commented 4 years ago

Wow, that sounds superb! It would be awesome to integrate your solution with the rest of PaperTTY, but I don't have time right now to take a closer look at it - should it be a "simple" matter of replacing the SPI parts and adjusting the IT8951 code?

Great work!