libretiny-eu / libretiny

PlatformIO development platform for IoT modules
http://docs.libretiny.eu/
MIT License
401 stars 59 forks source link

BK7231N (a)synchronous PWM #224

Closed patagonaa closed 9 months ago

patagonaa commented 9 months ago

I've recently got my hands on some BK7231N fairy lights (see https://github.com/tuya-cloudcutter/tuya-cloudcutter/issues/573) (didn't work with cloudcutter first, got a working profile mere minutes after uploading the dump).

Now I have a bit of an issue with making it work properly with ESPHome.

The fairy lights only have two wires, which each attach to one half-bridge on the PCB (one is attached to P7, one is attached to P8). The two LED-colors are wired parallel to each other, but with reversed polarity. So in one polarity, color 1 is active and in the other polarity, color 2 is active.

To get both colors to light simultaneously, both pins have to be at (up to) 50% PWM, however, the two pins also need to be synchronized in a way that (at up to 50% PWM) the two PWM pulses do not overlap with each other (due to weird design choices, enabling both outputs at the same time shorts out the (luckily very low-power) power supply 🔥). In other microcontrollers, this can be acheived by sharing a timer between the channels and inverting one of the channels, but from my understanding, on this chip, the different PWM pins are pretty much all their own thing (and turning them off and on in ESPHome makes them have different offsets to each other), so I don't really have an idea how this can be acheived or how it is acheived in the original firmware (especially as I don't know if the PWM outputs can even be inverted).

Is there a way to output this kind of PWM waveform with libretiny (ideally with ESPHome)?

Reverse engineered schematic: As you can see here, the L1 high-side is directly enabled by L2 low-side and vice-versa, which causes a short circuit if both are enabled, reverse engineered schematic

The waveforms should look something like this: 50% duty cycle grafik 10% duty cycle grafik

Cossid commented 9 months ago

Not sure what you've tried, so my first suggestion would be to invert the pin on one output and set the max_power on both to 50% Also just a note, the UPK had pwmhz set to 250, so you should probably also set frequency: 250Hz

patagonaa commented 9 months ago

Sorry, I could've been clearer. So far, in ESPHome, I've added two lights with PWM outputs for the corresponding pins with max_power set to 0.5. However, when turning on and off the lights (likely because setting the duty cycle to 0 causes the PWM output to be stopped/paused entirely), the PWM pulses start at different times (verified with an oscilloscope). For example, when I put both outputs to 10%, sometimes (after turning one off and on again) the two pulses overlap, sometimes they don't (likely because the channel that was paused starts at a random point of the other channel's PWM pulse when it is reinitialized)

Cossid commented 9 months ago

There were some very recent PWM changes. I don't think they apply here, but it may be best to try anyway. You can check them out by using current git as LibreTiny source:

bk72xx:
  framework:
    version: 0.0.0
    source: https://github.com/libretiny-eu/libretiny.git

Beyond that, you'd probably need a custom driver to properly orchestrate timing with some sort of interlock, I don't think there is anything in stock ESPHome that does that.

You could try Slow PWM which does have controllable period. Not sure how performant it will be at 250hz, it's made for even slower than that.

patagonaa commented 9 months ago

So, after some direct communication via Discord and some messing around the state is the following:

Further development (probably getting the PWM peripherals configured properly) will likely occur in https://github.com/patagonaa/tuya-ir-string-lights