Skip to content

[inky] Add Inky Impression 7.3" support#75

Merged
maruel merged 4 commits intoperiph:mainfrom
fstanis:main
Mar 2, 2025
Merged

[inky] Add Inky Impression 7.3" support#75
maruel merged 4 commits intoperiph:mainfrom
fstanis:main

Conversation

@fstanis
Copy link
Contributor

@fstanis fstanis commented Sep 28, 2024

Inky Impression 7.3" is a larger e-ink display that unlike smaller variants is based on AC073TC1A rather than UC8159.

This PR is effectively a port of pimoroni/inky#158 since the difference is primarily in the reset and update commads.

(draft until I have a chance to properly test)

@codecov-commenter
Copy link

codecov-commenter commented Sep 28, 2024

Codecov Report

Attention: Patch coverage is 0% with 141 lines in your changes missing coverage. Please review.

Project coverage is 51.3%. Comparing base (cad2275) to head (2208b5e).
Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
inky/impression.go 0.0% 138 Missing ⚠️
inky/types.go 0.0% 3 Missing ⚠️

❌ Your patch status has failed because the patch coverage (0.0%) is below the target coverage (40.0%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@           Coverage Diff           @@
##            main     #75     +/-   ##
=======================================
+ Coverage   49.8%   51.3%   +1.5%     
=======================================
  Files         91     102     +11     
  Lines      11867   13201   +1334     
=======================================
+ Hits        5914    6774    +860     
- Misses      5695    6135    +440     
- Partials     258     292     +34     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@maruel
Copy link
Member

maruel commented Dec 7, 2024

I just saw the PR as it is a draft. Can you fix the linter errors? You'll need to rebase.

@gsexton
Copy link
Contributor

gsexton commented Feb 10, 2025

@fstanis I updated the PR to the current head of periph.io/devices and addressed a minor lint error.

Did you ever get a chance to test this?

Copy link
Member

@maruel maruel left a comment

Choose a reason for hiding this comment

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

This looks fine to me but I'd like a confirmation this still work first. Thanks!

Co-authored-by: Olivier Mengué <dolmen@cpan.org>
@maruel maruel marked this pull request as ready for review February 14, 2025 22:44
@kedare
Copy link

kedare commented Feb 21, 2025

Wow as was actually looking exactly for this :D

Looking forward to be able to use this.

Thanks

@kedare
Copy link

kedare commented Mar 2, 2025

Any way I can help to merge this ? I do own the display

Copy link
Member

@maruel maruel left a comment

Choose a reason for hiding this comment

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

Okay I'll commit, I would have preferred a formal confirmation that it works but I guess I'll YOLO it.

@maruel maruel merged commit eb90d53 into periph:main Mar 2, 2025
9 of 10 checks passed
@kedare
Copy link

kedare commented Mar 2, 2025

Great thanks :)
I think it be only available when a new version has been tagged ? (except if I hardcode the commit during go get)

@kedare
Copy link

kedare commented Mar 2, 2025

Hmm I could not make it work so far, I found a few issues so far:
Dev.Bounds() is always (0,0),(0,0), it's not properly set as it should automatically depending on the model (I had to force is via Opts.Height and Opts.Width)

  • When Drawing, it would randomly fail with the following logs :
2025/03/02 19:22:47 impression.go:558: Err: bcm283x-gpio (GPIO17): line_request ioctl: bad file descriptor
2025/03/02 19:22:48 impression.go:558: Err: bcm283x-gpio (GPIO17): line_request ioctl: bad file descriptor
2025/03/02 19:22:48 impression.go:558: Err: bcm283x-gpio (GPIO17): line_request ioctl: bad file descriptor
2025/03/02 19:22:48 impression.go:558: Err: bcm283x-gpio (GPIO17): line_request ioctl: bad file descriptor

Which apparently correspond to this : pimoroni/inky#205
But on the python implementation this is not making the drawing fail, those are just warnings, it looks like on the Go implementation this stops the drawing (can't confirm as I can't draw at all)

  • When not raising the previous error, it's not actually drawing anything, it does block however the code like if it was indeed drawing something (around 40s)

This is the code I am using: https://github.com/kedare/dashink/blob/main/pkg/hardware/host.go

Thanks

@kedare
Copy link

kedare commented Mar 2, 2025

For the size always set to 0,
This is the issue: https://github.com/periph/devices/blob/main/inky/impression.go#L208

It should be this I guess

	if o.Width != 0 && o.Height != 0 {
		d.width = o.Width
		d.height = o.Height
	}

@gsexton
Copy link
Contributor

gsexton commented Mar 3, 2025

@kedare I'm assuming you're using a Raspberry Pi. Is that correct?

Can you tell us what version of periph.io/x/host is listed in your go.mod file? The latest version has updates to the WaitForEdge() calls.

Can you try testing with different pin names? For each required pin, ensure that they are prefixed with "GPIOXX". E.G. for the reset pin, pass "GPIO27".

@kedare
Copy link

kedare commented Mar 3, 2025

Yes, I am using a Raspberry Pi Zero 2W, I can use the official python code without problem (just with the warning about busy wait but that is not blocking it from working)

This is what I have in my go.mod

grep periph.io go.mod
        periph.io/x/conn/v3 v3.7.2 // indirect
        periph.io/x/devices/v3 v3.7.4-0.20250302141124-eb90d535341b // indirect
        periph.io/x/host/v3 v3.8.3 // indirect

Tried with the last revision from master, I don't get the logs anymore but same issue.

grep periph.io go.mod
        periph.io/x/conn/v3 v3.7.2
        periph.io/x/devices/v3 v3.7.4-0.20250302172059-ea55a05aa126
        periph.io/x/host/v3 v3.8.4-0.20250117130906-28c0c75f3193

I was using the GPIOxx before but switched to XX as I checked that the code from cmd/inky was doing this. I tried again with GPIOxx but same issue

@gsexton
Copy link
Contributor

gsexton commented Mar 3, 2025

@kedare Thanks for posting that. The error you're getting seems to be coming out of the GPIO subsystem. Unfortunately, I don't have one of those displays and they're on the expensive side. Just to narrow it down, could you change how you're getting the GPIO pins and see if you're still getting the ioctl errors?

import (
	"periph.io/x/host/v3/gpioioctl"
)

func Example() {
	_, _ = host.Init()
	_, _ = driverreg.Init()


	chip := gpioioctl.Chips[0]
	fmt.Println(chip.String())

	reset:= chip.ByName("GPIO5")
	busy:=chip.ByName("GPIO6")
	...

@kedare
Copy link

kedare commented Mar 3, 2025

Thanks I will try that and let you know

Do you know if there is something like tcpdump that can be used for SPI or GPIO ? I could capture the python run and the go run so we can compare them.

@maruel
Copy link
Member

maruel commented Mar 3, 2025

@kedare
Copy link

kedare commented Mar 4, 2025

I tried with your GPIO method, I am getting the same issue (randomly throwing the error or not throwing the error, when it's not throwing it, it then pause like if it was drawing on the screen but nothing actually happen).

I posted the info there : https://gist.github.com/kedare/dab9dbb19d9d681c514d221e57f63235

Do you want me to setup the gpiotest and spitest thing ?

@gsexton
Copy link
Contributor

gsexton commented Mar 8, 2025

@kedare
Can you report what kernel you're using?

I've looked through the code, and I'm not seeing where the file descriptor is getting closed. Just to confirm the operation of the library, I ran some sample code on a pi zero, and it's working.

I'd like to understand why the file descriptor error is happening. I would be interested in log output of the file descriptor value when errors happen, and don't. It seems like a longshot, but it would confirm things.

If that doesn't offer anything really obvious, I would either run the program under strace and look for the close of the file descriptor, or run it under a debugger and see what I could notice.

FWIW, here's some code that inits and it gets the GPIO IOCTL pins via the bcm283x registration.

package main

import (
	"fmt"
	"time"

	"periph.io/x/conn/v3/driver/driverreg"
	"periph.io/x/conn/v3/gpio"
	"periph.io/x/conn/v3/gpio/gpioreg"
	"periph.io/x/host/v3"
	_ "periph.io/x/host/v3/bcm283x"
	"periph.io/x/host/v3/gpioioctl"
)

func main() {
	fmt.Println("Calling driverreg.init")
	if _, err := driverreg.Init(); err != nil {
		fmt.Println("Failed to initialize periph:", err)
		return
	}
	if _, err := host.Init(); err != nil {
		fmt.Println("Failed to initialize periph:", err)
		return
	}
	outPin := gpioreg.ByName("GPIO2")
	inPin := gpioreg.ByName("GPIO10")
	inPin.In(gpio.PullDown, gpio.RisingEdge)
	fmt.Printf("inPin=%s, Type: %#v\n", inPin, inPin)
	fmt.Printf("outPin=%s Type: %#v\n", outPin, outPin)

	go func() {
		l := gpio.Low
		for {
			l = !l
			fmt.Println("setting outPin to ", l)
			outPin.Out(l)
			time.Sleep(1000 * time.Millisecond)
		}
	}()

	for {
		if inPin.WaitForEdge(0) {
			fmt.Println("Received edge")
		} else {
			fmt.Println("WaitForEdge() unblocked without receiving edge.")
		}
	}
}

Output

}
inPin=GPIO10, Type: &bcm283x.Pin{number:10, name:"GPIO10", defaultPull:0x2, ioctlPin:(*gpioioctl.GPIOLine)(0x879b00), usingEdge:true, usingClock:false, dmaCh:(*bcm283x.dmaChannel)(nil), dmaBuf:(*videocore.Mem)(nil)}
outPin=GPIO2 Type: &bcm283x.Pin{number:2, name:"GPIO2", defaultPull:0x3, ioctlPin:(*gpioioctl.GPIOLine)(0x8798c0), usingEdge:false, usingClock:false, dmaCh:(*bcm283x.dmaChannel)(nil), dmaBuf:(*videocore.Mem)(nil)}
setting outPin to  High
setting outPin to  Low
setting outPin to  High
Received edge
setting outPin to  Low
setting outPin to  High
Received edge
setting outPin to  Low
setting outPin to  High
Received edge
...

@kedare
Copy link

kedare commented Mar 8, 2025

This is the kernel I am currently using (on RPI Zero 2W)

Linux 6.6.74+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.6.74-1+rpt1 (2025-01-27) aarch64 GNU/Linux

For the strace, I attached one when I don't have the error (but it doesn't draw anything), and one when it give the ioctl error.

trace-no-error.log
trace-error.log

Cases happens randomly.

Somehow I had some issues getting the strace, it would hangs up most of the time before even being at the drawing step.

@kedare
Copy link

kedare commented Mar 8, 2025

From your code (I just ran it without any change), this is what I get (not sure if this expecting some wiring or manual operation?)

./gpio-test
Calling driverreg.init
inPin=GPIO10, Type: &bcm283x.Pin{number:10, name:"GPIO10", defaultPull:0x2, ioctlPin:(*gpioioctl.GPIOLine)(0x4000180600), usingEdge:true, usingClock:false, dmaCh:(*bcm283x.dmaChannel)(nil), dmaBuf:(*videocore.Mem)(nil)}
outPin=GPIO2 Type: &bcm283x.Pin{number:2, name:"GPIO2", defaultPull:0x3, ioctlPin:(*gpioioctl.GPIOLine)(0x4000180300), usingEdge:false, usingClock:false, dmaCh:(*bcm283x.dmaChannel)(nil), dmaBuf:(*videocore.Mem)(nil)}
setting outPin to  High
setting outPin to  Low
setting outPin to  High
setting outPin to  Low
setting outPin to  High
setting outPin to  Low
setting outPin to  High
setting outPin to  Low
setting outPin to  High
setting outPin to  Low
setting outPin to  High
setting outPin to  Low
setting outPin to  High
setting outPin to  Low
setting outPin to  High
setting outPin to  Low
setting outPin to  High
setting outPin to  Low

@gsexton
Copy link
Contributor

gsexton commented Mar 10, 2025

@kedare It would need a jumper between GPIO2 and GPIO10 for the edge on inpin to trigger.

@kedare
Copy link

kedare commented Mar 12, 2025

Thanks, there you have

❯ ./gpio-test
Calling driverreg.init
inPin=GPIO10, Type: &bcm283x.Pin{number:10, name:"GPIO10", defaultPull:0x2, ioctlPin:(*gpioioctl.GPIOLine)(0x4000100660), usingEdge:true, usingClock:false, dmaCh:(*bcm283x.dmaChannel)(nil), dmaBuf:(*videocore.Mem)(nil)}
outPin=GPIO2 Type: &bcm283x.Pin{number:2, name:"GPIO2", defaultPull:0x3, ioctlPin:(*gpioioctl.GPIOLine)(0x4000100360), usingEdge:false, usingClock:false, dmaCh:(*bcm283x.dmaChannel)(nil), dmaBuf:(*videocore.Mem)(nil)}
setting outPin to  High
Received edge
setting outPin to  Low
setting outPin to  High
Received edge
setting outPin to  Low
setting outPin to  High
Received edge
setting outPin to  Low
setting outPin to  High
Received edge
setting outPin to  Low
setting outPin to  High
Received edge
setting outPin to  Low
setting outPin to  High
Received edge

@gsexton
Copy link
Contributor

gsexton commented Mar 18, 2025

That's working as expected then. I've got a display on order. If you leave your repo up, I'll take a look. It will take at least a week, I'm sure for it to arrive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

Comments