-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Add in a esp_my9291_write() function #5702
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This looks good, thanks @goatchurchprime! However as with any addition to the firmware the additional code size needs to be weighed up against how generally useful it is (especially if the functionality can already be implemented in Python). I've used the (similar, but more forgiving) MY9221 from a micro:bit before (with the driver written in Python). A very simple bit-banging driver worked fine for a single one, but it wasn't possible to get the timing right for multiple cascaded ones. I was able to make it work by using the hardware SPI peripheral for the data transfer, and then disabling the SPI and doing the latching pulses manually with GPIO. Just a general comment on perhaps a way forward for stuff like this though where you need custom C functionality that maybe shouldn't go into the main firmware. In #5118, @mcauser added board definitions to the ESP8266 port. This allows you to define your own custom board (including any Python and C code that you want included into the firmware). Importantly, the board definition can be in your own separate repo, so that way you don't have to be managing patches on top of the main repo.
To make a module from a .c file in your board dir, I'm fairly sure you can use |
Here's two I prepared earlier: The my9291 is 4 channel and can drive 1x RGB(W) LED. I was going to make a more generic micropython-my92xx driver, as there's a bunch of similar ones with supporting different channel counts. Porting it to C sounds like fun too. |
Well, my PR has served its purpose by finding the other people who know about this driver! I definitely couldn't get bitbanging to work from Python with the chip in this lightbulb. Maybe I'd have to buy a bare chip and work with it directly as it is very inconvenient to do it in situ (the lights don't come on when it's not powered and in the socket). HSPI can't work because it's not on the right pins. SoftSPI toggles the SCK pin twice per bit, so unfortunately can't be used because this requires a single toggle on DCK for each DI bit. SoftQSPI has a function called nibble_write() that bitbangs 4 pins at once.
A lightbulb control string is 8 bytes (2bytes each for RGBW), so would encode in 64 bit/bytes, which would be fine. Unfortunately, the QSPI library seems only available in the stm32 boards. (Why is that?) I think a super-generic realtime bigbanging library function would be the way to go -- if there were many more chips like this that can't be shoehorned into a known protocol. (Actually, isn't this how DMA often gets used -- by DMA-ing onto the pinmask word?) |
Exclude ci checks and tests from building boards
I'll close this PR. I think the best way to maintain this code (if you want to keep it alive on the Internet) is to make it into a custom esp8266 board definition with a custom my9291 module. This is now much easier with |
I've finally achieved my ambition to put Micropython into a lightbulb!
These AiLights actually have a ESP8285, but the full Micropython with the mqtt-stack works fine. The lighting controller is a my9291 chip with no documentation about its protocol, and the only implementation of it in Arduino-world by bitbanging.
I put the function into the same places as the
esp_neopixel_write()
function, which also is implemented by some some similar timed bitbanging. I added some delays to keep the same time as the working arduino code. Bitbanging directly from Micropython does not work: If the pulses are longer than 4microseconds the chip does not accept the signal.This is not the ideal function; it was originally meant to be 5 parameters, but the macro MP_DEFINE_CONST_FUN_OBJ_5 does not exist and it would have taken too many edits on the base code to put it in.
So I'm putting this pull-request out here for comments about whether the function is adequate or in the right place, or whether a more general purpose function for bitbanging things like my9291 could be made (if there are any other chips like this).