Git Product home page Git Product logo

Comments (21)

mattjlewis avatar mattjlewis commented on May 25, 2024

Bart, looking at the code now and I think this should work already.
CHIPBoardInfoProvider.lookup:
if (hardware != null && hardware.startsWith("Allwinner sun4i/sun5i")) {
return CHIP_BOARD_INFO;
}

Let me know if I'm missing somrthing.

Matt

from diozero.

BartoszKaszewczuk avatar BartoszKaszewczuk commented on May 25, 2024

That was my impression as well Matt however upon trying I was surprised to see it throwing java.lang.NullPointerException when testing by instantiating com.diozero.LED object:

Exception in thread "main" java.lang.NullPointerException
	at com.diozero.internal.spi.GpioDeviceFactoryInterface.provisionDigitalOutputDevice(GpioDeviceFactoryInterface.java:54)
	at com.diozero.api.DigitalOutputDevice.<init>(DigitalOutputDevice.java:92)
	at com.diozero.api.DigitalOutputDevice.<init>(DigitalOutputDevice.java:73)
	at com.diozero.api.DigitalOutputDevice.<init>(DigitalOutputDevice.java:58)
	at com.diozero.LED.<init>(LED.java:69)

I traced in further and the issue seems to be with com.diozero.internal.spi.BaseNativeDeviceFactory having null value at BoardInfo boardInfo property.
Interestingly, invoking SystemInfo.getBoardInfo() manually returns following BoardInfo object:

BoardInfo [make=CHIP, model=CHIP, memory=512]

So it seems like it identifies CHIP Pro as CHIP but BaseNativeDeviceFactory's BoardInfo never gets populated.
Also, I'm not sure what memory field of BoardInfo corresponds to (whether its RAM or Storage) but assuming it refers to RAM then CHIP Pro has 256MB of RAM while original CHIP does in fact have 512MB RAM. Just something to note.

from diozero.

mattjlewis avatar mattjlewis commented on May 25, 2024

Scratching my head over this one. I've refactored some of the code as I wasn't overly happy with some of the internal resource initialisation code (I will check in tonight after testing on CHIP, Pi etc). However, if it was working on CHIP I don't understand why it isn't working on the CHIP Pro (the only thing I can think of is the logic to determine the XIO GPIO base (CHIPBoardInfoProvider lines 67-80).
The memory stuff is completely superfluous and not used within the code.
Can you share the start-up output please.

from diozero.

BartoszKaszewczuk avatar BartoszKaszewczuk commented on May 25, 2024

Startup log on CHIP Pro:

2017-04-10 16:00:23 [main] DeviceFactoryHelper.init():76
INFO: Using native device factory class SysFsDeviceFactory

Exception in thread "main" java.lang.NullPointerException
	at com.diozero.internal.spi.GpioDeviceFactoryInterface.provisionDigitalOutputDevice(GpioDeviceFactoryInterface.java:54)
	at com.diozero.api.DigitalOutputDevice.<init>(DigitalOutputDevice.java:92)
	at com.diozero.api.DigitalOutputDevice.<init>(DigitalOutputDevice.java:73)
	at com.diozero.api.DigitalOutputDevice.<init>(DigitalOutputDevice.java:58)
	at com.diozero.LED.<init>(LED.java:69)
	at com.Test.Alpha.Main.main(Main.java:44)

2017-04-10 16:00:23 [DIO-Zero Shutdown Handler] ShutdownHandlerThread.run():116
DEBUG: Shutdown handler running

2017-04-10 16:00:23 [DIO-Zero Shutdown Handler] DioZeroScheduler.shutdown():86
DEBUG: Shutdown - done

2017-04-10 16:00:23 [DIO-Zero Shutdown Handler] DioZeroScheduler.shutdown():86
DEBUG: Shutdown - done

2017-04-10 16:00:23 [DIO-Zero Shutdown Handler] AbstractDeviceFactory.shutdown():57
DEBUG: shutdown()

2017-04-10 16:00:23 [DIO-Zero Shutdown Handler] DeviceStates.closeAll():59
DEBUG: closeAll()

2017-04-10 16:00:23 [DIO-Zero Shutdown Handler] ShutdownHandlerThread.run():119
DEBUG: Shutdown handler finished

Process finished with exit code 1

from diozero.

BartoszKaszewczuk avatar BartoszKaszewczuk commented on May 25, 2024

Think I found the root cause.
CHIP Pro uses different GPIO multiplexer from original CHIP. CHIPBoardInfoProvider looks for pcf8574a (as in original CHIP) but Pro doesn't have that mux and seems to use GPIOs directly off R8 SoC. It identifies itself as 1c20800.pinctrl and is also available on original CHIP (See output from Pro's /sys/class/gpio below). It means that GPIOs XIO0-P0:P7 don't exist on Pro and only CSID0:7 are available. Pro also exposes one extra PWM output (2 in total). There could be more differences.

root@chip:/sys/class/gpio# cat gpiochip*/label
1c20800.pinctrl
axp20x-gpio
root@chip:/sys/class/gpio# cat gpiochip*/ngpio
224
3
root@chip:/sys/class/gpio# cat gpiochip*/base
0
1021

I did a quick and dirty test to see how simply adding 1c20800.pinctrl to CHIPBoardInfoProvider would affect it and it produced following exceptions (see below). Handling those hardware differences with a new device class would probably be the best solution.

Exception in thread "main" java.util.ServiceConfigurationError: com.diozero.internal.spi.NativeDeviceFactoryInterface: Provider com.diozero.internal.provider.sysfs.SysFsDeviceFactory could not be instantiated
	at java.util.ServiceLoader.fail(ServiceLoader.java:232)
	at java.util.ServiceLoader.access$100(ServiceLoader.java:185)
	at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:384)
	at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
	at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
	at com.diozero.internal.DeviceFactoryHelper.init(DeviceFactoryHelper.java:65)
	at com.diozero.internal.DeviceFactoryHelper.getNativeDeviceFactory(DeviceFactoryHelper.java:90)
	at com.diozero.api.DigitalOutputDevice.<init>(DigitalOutputDevice.java:73)
	at com.diozero.api.DigitalOutputDevice.<init>(DigitalOutputDevice.java:58)
	at com.diozero.LED.<init>(LED.java:69)
	at com.nFinityStudio.HecticColor.Main.main(Main.java:44)
Caused by: java.util.ServiceConfigurationError: com.diozero.util.BoardInfoProvider: Provider com.diozero.internal.board.chip.CHIPBoardInfoProvider could not be instantiated
	at java.util.ServiceLoader.fail(ServiceLoader.java:232)
	at java.util.ServiceLoader.access$100(ServiceLoader.java:185)
	at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:384)
	at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
	at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
	at com.diozero.util.SystemInfo.lookupBoardInfo(SystemInfo.java:84)
	at com.diozero.util.SystemInfo.initialise(SystemInfo.java:75)
	at com.diozero.util.SystemInfo.getBoardInfo(SystemInfo.java:124)
	at com.diozero.internal.spi.BaseNativeDeviceFactory.initialiseBoardInfo(BaseNativeDeviceFactory.java:64)
	at com.diozero.internal.provider.sysfs.SysFsDeviceFactory.<init>(SysFsDeviceFactory.java:57)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at java.lang.Class.newInstance(Class.java:442)
	at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380)
	... 8 more
Caused by: java.lang.ExceptionInInitializerError
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at java.lang.Class.newInstance(Class.java:442)
	at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380)
	... 21 more
Caused by: java.lang.NullPointerException
	at com.diozero.internal.board.chip.CHIPBoardInfoProvider$CHIPBoardInfo.<init>(CHIPBoardInfoProvider.java:74)
	at com.diozero.internal.board.chip.CHIPBoardInfoProvider.<clinit>(CHIPBoardInfoProvider.java:46)
	... 27 more

from diozero.

mattjlewis avatar mattjlewis commented on May 25, 2024

Just got to the same conclusion that must be the source of the error. I've commited changes to github that should at least avoid the NullPointerException (poor code on my behalf loading the GPIO offset in the constructor).
Thanks for investigating. I need to find some identifier that I can use to easily differentiate between the CHIP and the CHIP Pro.

from diozero.

mattjlewis avatar mattjlewis commented on May 25, 2024

Have pushed an updated snapshot build that includes untested code for CHP Pro (using memory to differentiate), please let me know how you get on with it.

from diozero.

BartoszKaszewczuk avatar BartoszKaszewczuk commented on May 25, 2024

Excellent job man. Just tested it with simple LED and it seems to work great. I will re-open should I notice any issues.

from diozero.

BartoszKaszewczuk avatar BartoszKaszewczuk commented on May 25, 2024

I've been stability testing my program that communicates over I2C on CHIP Pro recently (essentially by leaving it running for a long time) and I've noticed Kernel Panics and couple other things and I wonder if you seen them before or would know anything about them.

My program issues ~2300 writes with 1Byte payloads to I2C every second using I2CDevice.writeByte() and every couple minutes I'm seeing exceptions thrown by mv64xxx driver when monitoring CHIP over UART. The higher the write frequency the more often these errors appear.

[28537.595000] i2c i2c-1: mv64xxx_i2c_fsm: Ctlr Error -- state: 0x4, status: 0x0, addr: 0x38, flags: 0x0
[28553.001000] i2c i2c-1: mv64xxx_i2c_fsm: Ctlr Error -- state: 0x6, status: 0x0, addr: 0x38, flags: 0x0
[28621.521000] i2c i2c-1: mv64xxx_i2c_fsm: Ctlr Error -- state: 0x4, status: 0x0, addr: 0x38, flags: 0x0

0x38 is address of I2C SLAVE only device I'm writing to.
I went through source of mv64xxx driver and I established that:

  • 0x4 state errors have something to do with driver's internal attempt to read an ACK after I2C IRQ.
  • 0x6 state error is undefined behaviour.
  • Log is filled with above errors appearing in random order. Sometimes it throws 0x4, other times 0x6.

After letting it run for 6-10h the driver eventually throws a deadly 0x6 state error causing a Kernel Panic halting entire OS and CHIP. Here's oops dump I managed to capture saying issues originate from sun4i_handle_irq when handling an IRQ (see bottom of dump).

[28661.990000] i2c i2c-1: mv64xxx_i2c_fsm: Ctlr Error -- state: 0x6, status: 0x0, addr: 0x38, flags: 0x0
[28662.000000] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[28662.010000] pgd = ca078000
[28662.015000] [00000000] *pgd=4a034831, *pte=00000000, *ppte=00000000
[28662.020000] Internal error: Oops: 80000007 [#1] SMP ARM
[28662.020000] Modules linked in: 8723ds(O) sun4i_codec snd_soc_core snd_pcm_dmaengine snd_pcm snd_timer snd cfg80211 soundcore ac97_bus
[28662.020000] CPU: 0 PID: 85 Comm: systemd-journal Tainted: G           O    4.4.30-pro #1
[28662.020000] Hardware name: Allwinner sun4i/sun5i Families
[28662.020000] task: cb7a3700 ti: ca05c000 task.ti: ca05c000
[28662.020000] PC is at 0x0
[28662.020000] LR is at vchan_complete+0x94/0xf0
[28662.020000] pc : [<00000000>]    lr : [<c05771ac>]    psr: 20030133
[28662.020000] sp : ca05def0  ip : 00000000  fp : 40000006
[28662.020000] r10: c0fea080  r9 : cb24c160  r8 : ca05c000
[28662.020000] r7 : ca05df18  r6 : 00000000  r5 : ca05def0  r4 : cb24c194
[28662.020000] r3 : 0000feea  r2 : 00000001  r1 : 00000000  r0 : 00000000
[28662.020000] Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA Thumb  Segment user
[28662.020000] Control: 10c5387d  Table: 4a078019  DAC: 00000055
[28662.020000] Process systemd-journal (pid: 85, stack limit = 0xca05c220)
[28662.020000] Stack: (0xca05def0 to 0xca05e000)
[28662.020000] dee0:                                     ca05def0 ca05def0 64a06740 cb24c194
[28662.020000] df00: cb24c198 00000000 ca05df18 ca05c000 c0fe3294 c025096c 00000000 00000006
[28662.020000] df20: ca05c000 c0fea098 c0fea080 00000100 c0fea080 c0250b58 00000000 00004000
[28662.020000] df40: ca05df38 c1109bc0 0000000a 00568dd1 c0fea100 00404100 00000001 c0fe446c
[28662.020000] df60: 00000000 00000000 00000001 cb003400 00000003 00000001 00000000 c0250f10
[28662.020000] df80: c0fe446c c0292fb8 c113df68 ca05dfb0 ffffffff 10c5387d 10c5387d c020a664
[28662.020000] dfa0: 0002ee20 20030030 ffffffff c0215964 000527a0 00000017 00000003 00000000
[28662.020000] dfc0: 00052258 00049030 00000010 00000000 00000017 00000003 00000001 00000000
[28662.020000] dfe0: 000527a0 bef0b990 0001b7bd 0002ee20 20030030 ffffffff e5843000 e5943058
[28662.020000] [<c05771ac>] (vchan_complete) from [<c025096c>] (tasklet_action+0x74/0x110)
[28662.020000] [<c025096c>] (tasklet_action) from [<c0250b58>] (__do_softirq+0xfc/0x214)
[28662.020000] [<c0250b58>] (__do_softirq) from [<c0250f10>] (irq_exit+0xb0/0x118)
[28662.020000] [<c0250f10>] (irq_exit) from [<c0292fb8>] (__handle_domain_irq+0x60/0xb4)
[28662.020000] [<c0292fb8>] (__handle_domain_irq) from [<c020a664>] (sun4i_handle_irq+0x48/0x60)
[28662.020000] [<c020a664>] (sun4i_handle_irq) from [<c0215964>] (__irq_usr+0x44/0x60)
[28662.020000] Exception stack(0xca05dfb0 to 0xca05dff8)
[28662.020000] dfa0:                                     000527a0 00000017 00000003 00000000
[28662.020000] dfc0: 00052258 00049030 00000010 00000000 00000017 00000003 00000001 00000000
[28662.020000] dfe0: 000527a0 bef0b990 0001b7bd 0002ee20 20030030 ffffffff
[28662.020000] Code: bad PC value
[28662.270000] ---[ end trace 9acdf9ea5854af0f ]---
[28662.275000] Kernel panic - not syncing: Fatal exception in interrupt
[28662.275000] ---[ end Kernel panic - not syncing: Fatal exception in interrupt

I noticed that system-utils-native uses ioctl(fd, I2C_SLAVE, (void*)addr) and when looking it up I stumbled upon this StackOverflow post saying:

SYSFS I/O
This method uses the basic file i/o system calls read() and write(). Uninterrupted sequential operations are not possible using this method. This method can be used if the device does not support the I2C_RDWR method.
Using this method, you do need to perform an ioctl I2C_SLAVE operation (or, if the device is busy, an I2C_SLAVE_FORCE operation).

Making me think that issue with interrupts could come from here albeit I see diozero writing via java.io.RandomAccessFile and I'm not exactly sure how I2C_SLAVE_FORCEwould fit the picture.

from diozero.

mattjlewis avatar mattjlewis commented on May 25, 2024

from diozero.

BartoszKaszewczuk avatar BartoszKaszewczuk commented on May 25, 2024

If by scheduler you're thinking something along the lines of java.util.concurrent.ScheduledExecutorService or java.util.TimerTask then no. I use a single dispatcher thread that executes I2C writes as soon as a task pops up in its queue.
I actually bought PCA9685 ICs as well and I will be testing it once I find some time to solder it in and wire it up.
I belive concurrent writing to I2C bus would amplify this issue even more although outline of I2C operations on StackOverflow leads me to believe that this behaviour stems from limitations imposed by SYSFS itself

[SYSFS] Uninterrupted sequential operations are not possible using this method.

Which I think means that a write to file system has to complete and can't be interrupted before sysfs file/device becomes avaible for next operation adding overhead to each opeartion and from my understanding fast enough writes would produce similar behaviour to what I observed.
That post also mentions IOCTL I2C_RDWR as recommended way of communicating with I2C bus on Linux.
What board to you plan to use with your PCA9685?

from diozero.

mattjlewis avatar mattjlewis commented on May 25, 2024

from diozero.

BartoszKaszewczuk avatar BartoszKaszewczuk commented on May 25, 2024

I wrote a real-time audio to colours translation algorithm that uses techniques from field of voice biometrics I worked in. It constructs entire palettes of colours for every audio sample it captures. I guess I should say I'm still wiring it since I'm constantly improving it.
I also bought various cheap Chinese WiFi LED controllers (like this or this and few others), reverse engineered their communication protocols and wrote my own drivers to be able to interface with them and hooked them up to my algorithm. The algorithm will also make corrections to account for subjective colour perception, gamma correcting light intensity and making sure colours it comes up with are actually pleasant to look at.
I used to run in on my computer with a single WiFi LED controller online in early prototyping stages but now I figured it would be nicer to be able to attach it directly to my HiFi so it could work without having a computer as part of the chain. It would also allow it to work with analogue audio sources like Vinyls. I plan to use CHIP Pro to build a dedicated controller for it and I figured while I'm at it I may as well add a couple of RGB/RGBW outputs to it by throwing in an I2C to PWM IC.
PCA9685 looks interesting to me because it uses 12bit precision meaning I could maybe get even better and more granular control over colours but that will require even more writes to I2C.

I'll be more than happy to put it through my testing once you find some time and push the changes.
Did you settle for an ARM board to put in inside your hexapod or is it still up in the air?

from diozero.

mattjlewis avatar mattjlewis commented on May 25, 2024

from diozero.

mattjlewis avatar mattjlewis commented on May 25, 2024

from diozero.

BartoszKaszewczuk avatar BartoszKaszewczuk commented on May 25, 2024

Just found some time to check out changes and test them.
Unfortunately according to my testing it seems like issued I2C writes on CHIP Pro don't have any effect. I issue writes via I2CDevice.writeByte() and data seems to correctly reach native NativeI2CDeviceSMBus.writeI2CBlockData() but nothing happens past that so the issue may lie in native method.
NativeI2CDeviceSMBus's controller and deviceAddress fields are correctly populated with bus number and I2C address (in my case controller=1 (0x1), deviceAddress=56 (0x38)). I'm not exactly sure what fd corresponds to but I assume its some kind of SMBus identifier which in my case gets set to fd=37 (0x25).
Were your SMBus writes successful?

from diozero.

mattjlewis avatar mattjlewis commented on May 25, 2024

from diozero.

mattjlewis avatar mattjlewis commented on May 25, 2024

I've now tested this on my CHIP using BME280, BMP180 and TSL2561 devices and all worked ok. Thinking about it all of these devices are read-only. I will connect up a PCA9685 now.

from diozero.

BartoszKaszewczuk avatar BartoszKaszewczuk commented on May 25, 2024

For reference I used NCP5623 to test it which is write-only. Unfortunately I don't have anything to test reads with.

from diozero.

mattjlewis avatar mattjlewis commented on May 25, 2024

from diozero.

BartoszKaszewczuk avatar BartoszKaszewczuk commented on May 25, 2024

I belive so. I soldered in PCA9685 and wrote a driver to interface with it. I've been testing it by writing to all 16 outputs (so significantly more throughput) for past 6h so far using the exact same build of DioZero and SysFs provider that I used to have problems when testing NCP5623 and SMBus writes and I haven't seen a single error thrown by the mv64xxx . PCA9685 worked fine in my tests with both writes and reads over SMBus.
I do have to say that I also recompiled and flashed a newer version of Linux kernel in the meantime so that might have contributed a bit to fixing some of the issues. Turns out I will have to focus more on building a custom Linux build to make more resources available for my application since I'm now hitting that bottleneck.
I didn't have time to re-test NCP5623 again because these tests take so long and to be quite honest PCA9685 is a much better IC altogether.

from diozero.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.