zmk icon indicating copy to clipboard operation
zmk copied to clipboard

Implement a driver for ISSI IS31FL3743A

Open ice9js opened this issue 4 years ago • 7 comments

This PR adds support for a IS31FL3743A LED matrix driver as a proposition for more energy efficient 'bling' on ZMK powered devices. Hopefully it can also be leveraged in implementing per-key RGB support (#554).

I took some notes from #555 and made the driver conform to Zephyr's led_strip API.

The driver works by setting all configuration and white-balance scaling registers on init, and only uses PWM registers for manipulating LED brightness and color.

My test configuration for reference:

@i2c0 {
	is31fl3743a@20 {
		compatible = "issi,is31fl3743a";
		label = "IS31FL3743A_0";
		reg = <0x20>;
		riset = <68>;
		sw-setting = <0x01>;
		led-max-current = <5>;
		cs-order = [01 02 00 04 05 03 07 06 08 0A 0B 09 0D 0E 0C 10 11 0F];
		sdb-gpios = <&gpio1 13 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>;
		sync = <0x11>;
	};
};

Food for thought: I wonder what the best way would be for handling software/hardware shutdown to preserve energy when LEDs aren't in use. Zephyr's led_strip API seems to leave this question open.

ice9js avatar Mar 16 '21 14:03 ice9js

Food for thought: I wonder what the best way would be for handling software/hardware shutdown to preserve energy when LEDs aren't in use. Zephyr's led_strip API seems to leave this question open.

Zephyr has a power management API that we can implement for each driver: https://docs.zephyrproject.org/latest/reference/power_management/index.html#device-model-with-power-management-support

For example, putting this driver into DEVICE_PM_LOW_POWER_STATE could toggle the SDB pin. Then we could start doing things like putting LED drivers into low power state when all the LED colors are (0,0,0) or when the keyboard is idle.

joelspadin avatar Mar 16 '21 18:03 joelspadin

Are there plans to ever merge these LED matrix drivers into main? Would be very useful. 😄

mattvilim avatar Jan 24 '23 17:01 mattvilim

I think this driver needs some updates to fit with newer Zephyr, but I'm currently designing some hardware that will use one of these, so I will eventually be trying to get this through review.

One example of a change that should likely be made is to copy the color-mapping property from Zephyr's ws2812 driver, which gives the order of the color channels. If, for example, if you set color-mapping = <LED_COLOR_ID_RED>, then you should get a strip of up to 351 single color LEDs (controlled by the red channel of each pixel) instead of 117 RGB LEDs.

It might also be useful to be able to reorder the sw pins? Maybe that could be handled by a higher level transform similar to the kscan matrix transform though.

joelspadin avatar Jan 24 '23 23:01 joelspadin

Just going to note here that this is somewhat outdated and I think my implementation for IS31FL3741 (#886) is much better in that regard. I was meaning to update this to whatever we do there eventually, but haven't gotten much feedback on it so far either.

Regarding the stuff you mentioned @joelspadin, the IS31FL3741 implementation does indeed allow to map individual channels, not just entire RGB LEDs like so:

map = <
    RGB(SW(1), CS(1), CS(2), CS(3))
    RGB(SW(7), CS(3), CS(2), CS(1))
>;

These macros expand to three integers which are the register numbers on the ISSI chip for the three LEDs. The driver does assume every three subsequent positions are the red, green and blue channels for a single RGB LED, and I think the macros go a long way of making that manageable so you can assign them in whatever order makes sense for your project.
If you're not using RGB LEDs this still allows for full control over the order, but of course update_rgb will produce unexpected results in that case.

The RGB() macro works both ways, as in you can also do RGB(CS(i), SW(j), SW(k), SW(l)) if you happen to be using common cathode LEDs. That said it probably still makes sense to have another macro that just takes a single pair if you're doing something really weird, and to make it easier to assign non-rgb LEDs.

Either way, we should probably continue that discussion in #886 when the time comes.

ice9js avatar Jan 25 '23 07:01 ice9js

For posterity - I think you meant issue #866 and not #886.

vladkvit avatar Aug 17 '23 02:08 vladkvit

(Disclaimer: opinion not related to being associated with ZMK project as accepting it isn't my decision to make anyway)

Would you consider making this a module so that it can be used independently from a ZMK branch? The structure looks like it would cleanly transfer. Here is an example of such a driver: https://github.com/petejohanson/cirque-input-module

caksoylar avatar Aug 13 '24 17:08 caksoylar

I think that's a good idea. My intention is to eventually push this to Zephyr itself, but it seems like a module would be a nice intermediate solution for anyone interested in the meantime.

It's been a while since I last touched it so for now I'm trying to make sense of it again, but I should be able to set it up in the next few weeks.

ice9js avatar Aug 13 '24 18:08 ice9js

This PR has been automatically marked as stale because it has not had activity in 10 months. It will be closed in 14 days if no further activity occurs. Feel free to give a status update or re-open when it has been rebased and is ready for review (again). Thanks!

github-actions[bot] avatar Jul 24 '25 06:07 github-actions[bot]

This PR was closed because it had no activity for over 10 months. Feel free to give a status update or re-open when it has been rebased and is ready for review (again).

github-actions[bot] avatar Aug 07 '25 17:08 github-actions[bot]

Just noting the implementation of this driver has been completed and is now available as a standard zephyr module.

ice9js avatar Sep 15 '25 18:09 ice9js

@ice9js would it be possible for you to try and upstream the drivers for those chips to Zephyr? That would be the ideal end result, and definitely beats having them in-tree of ZMK or in a module.

nmunnich avatar Sep 16 '25 05:09 nmunnich

@ice9js would it be possible for you to try and upstream the drivers for those chips to Zephyr?

Yeah, I did give it a look briefly and it's still my intention but I have no idea when I'll get around to it. The code will work as is, I just haven't gotten around to figuring out core Zephyr development for writing some tests or providing test instructions, which will probably be welcome. But maybe I can at least get a conversation going before EOY with what I already have.

ice9js avatar Sep 17 '25 18:09 ice9js