#https github com adafruit Adafruit
1 messages · Page 1 of 1 (latest)
Here are data from analyzer (sw Logic from Saleae) and CPY looks different than Arduino..
Here is my CPY code. I´m using ESP32-S3 DevKitC-1 N8R2..
`
import time
import board
import busio
import displayio
import epaper7in5b
Set based on your display
FLEXIBLE = False
TRICOLOR = True
ROTATION = 0
Used to ensure the display is free in CircuitPython
displayio.release_displays()
spi = busio.SPI(board.IO12, MISO=board.IO13, MOSI=board.IO11)
ecs = board.IO9
dc = board.IO10
rst = board.IO5
busy = board.IO6
if TRICOLOR:
highlight = 0xFF0000 # third color is red (0xff0000)
else:
highlight = 0x000000
Create the displayio connection to the display pins
display_bus = displayio.FourWire(
spi, command=dc, chip_select=ecs, reset=rst, baudrate=40000000
)
time.sleep(1) # Wait a bit
Create the display object
display = epaper7in5b.EPD(display_bus,width=640,height=384, # 7.5" Tri-color
busy_pin=busy,rotation=ROTATION,highlight_color=highlight,
)
Create a display group for our screen objects
g = displayio.Group()
Display a ruler graphic from the root directory of the CIRCUITPY drive
f = open("/display-ruler.bmp", "rb")
pic = displayio.OnDiskBitmap(f)
Create a Tilegrid with the bitmap and put in the displayio group
t = displayio.TileGrid(pic, pixel_shader=displayio.ColorConverter())
g.append(t)
Place the display group on the screen
display.show(g)
Refresh the display to have it actually show the image
NOTE: Do not refresh eInk displays sooner than 180 seconds
display.refresh()
print("refreshed")
time.sleep(180)
`
k, lemme look
Thank you 🙂
where does it differ?
how fast is the spi running? The captures don't look like it has a high enough sample rate
oh, sorry.. I was looking here (https://github.com/ZinggJM/GxEPD2/blob/master/src/epd3c/GxEPD2_750c.cpp#LL16C33-L16C33) to match Arduino SPI bus speed, but 40 MHz will be probably wrong.. here is capture at 2 MHz..
you'll want the sample rate much higher than 40mhz to see the full signal
I always use the highest sample rate possible
if your probe can't do much higher, then you'll want to slow the SPI output speed down
Yes, I understand that and I do not think that Arduino code will run at 40 MHz as I could capture it with 8 MS/s.. It is probably set somewhere in Arduino code..
the arduino capture you posted didn't look right either
the CS gaps should have multiples of 8 clock cycles in them
Ok, I do not really know if there is also some problem, but it does refresh and rewrite display..
once you get good captures, you should be able to see the difference
Ok, so please how do I see if clocks are multiplied by 8 clock cycles?
how fast can you capture with your saleae?
ideally it'd be 10x faster than the spi is running
so 4MHz SPI would be captured at 40+MS/s
I can sample max 24 MS/s..
Is this what you mean?
ya, that looks much better
at the start during the init sequence there will be shorter transactions
This is Arduino data..
do the same trick with CP now
(and share the files with me)
you'll want to compare the commands from the first transaction onward
here is capture for Arduino, give me minute vith CP, I have to reflash the board..
This should be at 1 MHz, but I do not see similar data as in Arduino capture..
ya, I don't see any init sequence
is this right?
ya, for setting the speed
what is the epaper7in5b.EPD library contents?
(looks like the captured clock is 2mhz which is ok)
here is whole file..
I think you are missing the argument length in the start sequence
each line should be command, argument count, <arguments>
I do not know if write_black_ram_command & write_color_ram_command are right at all..
so b"\x01\x37\x00" should probably be b"\x01\x02\x37\x00"
to send 0x01 command and 0x37 and 0x00
b"\x04\x80\xc8" # power on and wait 200 ms looks right for a command and then delay
I get those values from here: https://github.com/ZinggJM/GxEPD2/blob/master/src/epd3c/GxEPD2_750c.cpp#L436
0x01 at line 442
yup, so to convert it into the CP sequence, you need to add the data length byte
so the start is b"\x65\x00" because it has no parameters
oh, ok..
right now it thinks the command is 0x01 and then 0x37 more data bytes
which is why it is just one command instead of a bunch of short ones
so the first line is right now because it is its own transaction
but the rest still need to be fixed
Ok, do you know any tutorial about that? I will look at bit later as my son just woke up so I'm trying to put him to sleep again..
The start_sequence and stop_sequence are bitpacked to minimize the ram impact. Every command begins with a command byte followed by a byte to determine the parameter count and delay. When the top bit of the second byte is 1 (0x80), a delay will occur after the command parameters are sent. The remaining 7 bits are the parameter count excluding any delay byte. The bytes following are the parameters. When the delay bit is set, a single byte after the parameters specifies the delay duration in milliseconds. The value 0xff will lead to an extra long 500 ms delay instead of 255 ms. The next byte will begin a new command definition.
I thought the delay count was the first after the parameter count though
and I totally get having a kiddo wake up. you can see the corner of my window watching my son in the screenshot above
This is related to that documentation? To be honest, I do not really know byte operation but I will try to figure it out..
its a way to encode multiple command/data transactions into a single byte string
Yes, i see it.. hope it does bring you a lot of joy.. my sons does to me, even when they are not behave as they should but that is life..
Ya, it does. He's 1 so he can't do too much misbehaving yet.
I understand what us under the hood, just do not know yet how to write/change it..
Yep, it will come bit later.. i'm just holding my 1.5 year old one...
Anyway, many thanks for your help. I will look at that in the morning at work as it is almost 1 AM here and I have to go sleep.. I will send changes sequence for validation, if it´s OK with you?
no problem. yup! feel free to ping me next time you are working on it
I'll reply when I have time after that
Sorry, I had to make last try, otherwise I would think about that whole night..
I change start sequence to this, and display does refresh. I think now the problem is in values which are in class..
_START_SEQUENCE = ( #b"\x65\x01" #b"\xAB" #b"\x65\x00" b"\x01\x02\x37\x00" # power setting b"\x00\x02\xcf\x08" # panel setting. Further filled in below. b"\x06\x03\xc7\xcc\x28" # booster soft start b"\x04\x02\x80\xc8" # power on and wait 200 ms b"\x30\x01\x3c" # PLL set to 150 Hz b"\x41\x01\x00" # temperature control b"\x50\x01\x77" # CDI setting b"\x60\x01\x22" # TCON settings b"\x61\x04\x02\x80\x01\x80" # Resolution b"\x82\x01\x1e" # VCM DC and delay 50ms b"\xe5\x01\x03" # flash mode b"\x10" )
getting closer!
b"\x04\x02\x80\xc8" should likely be b"\x04\x80\xc8"
0x80 is a delay argument and no others. the c8 is the delay time
Yeah, I forget about that..
it looks like there is only one ram array that is written with command 0x10
I don't think we have any displays that do tricolor that way unfortunately
Yeah, I have to look at that.. I will look at Arduino or MPY implementation, but now I´m really happy that it does refresh.. I hope that my English is not so bad and you know what I mean 😉 . I will write you when I will make any progress. Would you be (Adafruit) interested for PR of this driver or you are not supporting displays which you do not stock at shop?
it can go in the community bundle
but I think you'll need a PR into the core to get it working right
and I'm happy to review that
OK, I look at that when I will make this work. Many thanks again for your help and great support. Will you be streaming again some Deep dive? I really enjoyed those, but I understand that family is more important.
I do hope to start streaming regularly at some point. my kid starts daycare in july so maybe after that is working well
Ok 🙂 Bye for now..
good night
Hi @untold panther , these are still wrong data in CPY right? Also, do I find somewhere what is should be in init of the driver? I compared few drivers and do not really now what I should put there. Is this defined by datasheet? Also if I understand it right, all function which work with display (fill buffers, clear screen, etc.) are in EPaperDisplay.c ( https://github.com/adafruit/circuitpython/blob/main/shared-module/displayio/EPaperDisplay.c ) so I do not call any special functions in my driver, am I right? I looked at tutorial for displayio, but there are not technical detail's.
I usually copy a driver from waveshare or good display. It is tricky because the init sequence depends on the driver IC and the display itself.
Yes, EPaperDisplay does the high level stuff. To support tricolor in one buffer, then you'll likely need to tweak how TileGrid copies to the buffer too.
It is a bit complicated
Ok, thank you..
It may be easier to get grayscale without the color working
Ye, I will start with that. Pls are those data for CPY (in picture) wrong and they should be same as for Arduino or they are OK? Thanks
it looks ok to me
try setting it as 4 bit grayscale
Hello @untold panther 🙂 . I know that you saw that I made my epaper display work, but that was actually different display. I´m still fighting one in this thread.
Anyway, I made small progress, but I´m stuck again. I can now send bitmap to the display, but it is somehow smaller. I can see right pattern of the bitmap, but I can not make it bigger. I discussed that with my friend who knows much more about low level stuff than me, but we did not figure it out. I´m still comparing SPI data for Arduino and CPY, and I can see that there are same data values, but on the CPY side data are send by bytes chunks compare to Arduino where are in single bytes with delay. Could this cause the issue for resolution? Sorry that I´m bothering you, but I would really crack this somehow. Many thanks for your help!
that looks like you aren't sending enough data
how are you setting it up in CP now?
mmnt pls, I have to connect my board..
you want just start sequence or whole "driver" file?
not the start sequence. the kwargs to the epaper class
so like this?
def __init__(
self,
bus: FourWire,
swap_rams: bool = False,
border: Optional[bool] = False,
**kwargs
) -> None:
start_sequence = bytearray(_START_SEQUENCE)
width = kwargs["width"]
height = kwargs["height"]
if "rotation" in kwargs and kwargs["rotation"] % 180 != 0:
width, height = height, width
#start_sequence[33] = width & 0xFF
#start_sequence[31] = (height >> 8) & 0xFF
#start_sequence[28] = height & 0xFF
#if swap_rams:
# color_bits_inverted = kwargs.pop("color_bits_inverted", False)
# write_color_ram_command = 0x10
# black_bits_inverted = kwargs.pop("black_bits_inverted", True)
# write_black_ram_command = 0x13
#else:
# write_black_ram_command = 0x13
# write_color_ram_command = 0x10
# color_bits_inverted = kwargs.pop("color_bits_inverted", True)
# black_bits_inverted = kwargs.pop("black_bits_inverted", False)
#if border is None:
# start_sequence[20] |= 0b11 << 6 # Border remains unchanged
#elif not border:
# start_sequence[20] |= 0b01 << 6 # Border is White
#if "highlight_color" not in kwargs:
# start_sequence[17] |= 1 << 4 # Set BWR to only do black and white.
more than that
super().__init__(
bus,
start_sequence,
_STOP_SEQUENCE,
**kwargs,
ram_width=640,
ram_height=384,
busy_state=False,
#write_black_ram_command=write_black_ram_command,
write_black_ram_command=0x10,
#write_color_ram_command=write_color_ram_command,
#black_bits_inverted=black_bits_inverted,
#color_bits_inverted=color_bits_inverted,
refresh_display_command=0x12,
)
ya, I don't think that class can support the display you have
because (iirc) it is 4 bits per pixel
the epd class can only do 1 or 2 usually
the acep mode is 4 bits per pixel iirc but it isn't the coloring you want
this flag it uses advanced_color_epaper=True
impacts color_depth here: https://github.com/adafruit/circuitpython/blob/main/shared-module/displayio/EPaperDisplay.c#L74
So I will not make it work just with driver file and I need to change code somewhere in the core as you mentioned earlier? If so, that is out of my scope of programming knowledge.. Anyway, many thanks for your help..
yes, the core code will need to be changed because we don't currently support the ram layout that display has
that is in this function? https://github.com/adafruit/circuitpython/blob/7e6825daf608c27e2c28ae42983688a610eb7493/shared-module/displayio/display_core.c#L228
Ok, many thanks.. 🙂 I will try to look at it..
good luck! The ACeP PR should show you most relevant places
Sorry for probably rude question, but you would not be interested in this if I would donate hardware I guess? I also guess that CPY support HW which Adafruit sell at their store right?
Adafruit funded devs tend to only work on Adafruit hardware yes.
It'd be fine to have support in CP.
I understand that and I agree that would be good to have support for this version of the display. I will try to ask my friend for help or find somebody who can look at it.
Also, how can I share driver/library for that 7.5" display, which I made to work? Is this guide the right one? https://learn.adafruit.com/creating-and-sharing-a-circuitpython-library
Many thanks again for your awesome support!