In another thread, I outlined how one could use one form of pulse density modulation instead of pulse width modulation for e.g. LED intensity control. Basically, for each output pin, you have a state counter
S, and the duty cycle or current modulation value
V, both
N-bit unsigned integers, and you loop over
S = S + V (or in mathematical terms,
S = (
S +
V) modulo 2
N)
pin = (S < V)where the output pin state is equivalent to the carry/overflow flag of the addition.
In simple terms, if you consider a PWM signal of the same duty cycle
V, instead of having all high states at the beginning of the 2
N-sample period, and all low states at the end of the period, this distributes them over the entire period with as even intervals as possible. This means that for example with
N=8, using 6% to 94% intensities (
V=16..224), the maximum consecutive low or high duration of the output is 16 cycles, instead of the 128 (minimum) to 240 (maximum) with PWM. The frequency of state changes is much higher with pulse density modulation, and should produce much less flicker and capacitor/coil whine at 1 kHz - 5 MHz clock rates (4 Hz to 20 kHz periods at 256 clock cycles per period). The period frequency of PDM is also much less apparent than PWM, because of how the "pulses" are spread across the entire period.
I was hoping the Pi Pico PIO could do this. According to the
RP2040 datasheet, it has two PIO units with four state machines each, with each state machine having two scratch registers – so each of the eight state machines available might be able to do this. Alas, the 9 instructions the PIO state machines support – JMP, WAIT, IN, OUT, PUSH, PULL, MOV, IRQ, and SET – does not include an operation to add one scratch register to another. (Either scratch register can be incremented or decremented by one, but that isn't sufficient for this.)
Another possible purpose for the PIO would be to interface to various display modules using ILI9341 or similar controllers, with parallel data transfers for higher display refresh rates. (I happen to really like BuyDisplay/EastRising
2.8" 240x320 displays with an IPS panel.) Typically, 16 or 18 data I/O lines are needed, five control outputs (chip select, read strobe, write strobe, data/command select, and reset), and one input (tear effect).
The reason the parallel interface is not that common with microcontroller projects (but is with FPGAs!) is those extra control outputs. There is no clock per se; the display controller latches the data at rising edge of the write strobe. Commands have the data/command low, and following data words high. This is not easily handled with DMA (although you can chain DMAs, or use non-DMA for the command word and DMA only for the data; but even then the write strobe handling is a bit complicated).
There are lots of SPI libraries for these display controllers, though; including for Pi Pico.
On the ILI9341 (
datasheet), all commands are 8 bits only, and all data values are 8 bit only except for memory reads and writes (0x2C
Memory write, 0x3C
Memory write continue, 0x2E
Memory read, and 0x3E
Memory read continue) which use the full 16 or 18 data lines (RGB565 or RGB666 data). The longest command is 0x2D
Color set, which takes 128 data bytes; used in the 16-bit data mode to expand the 5 red bits to 6 bits, 6 green bits to 6 bits (!), and 5 blue bits to 6 bits. Memory reads and writes use a predefined rectangular area,
continue commands continuing where the previous ended, and normal memory reads/writes starting at the beginning of the predefined area.
It seems to me that a state machine that consumes 8-bit data, first byte always being the data length, followed by the command byte, followed by the specified number of data bytes, could implement register/command writes with just a few instructions. (The problem with RP2040 is that it has so little room for PIO programs, just 32 instructions.) Memory write could be a separate state machine.
I have considered using a number of different ARM microcontrollers for this – basically as a programmable display unit –, but either their GPIO bus is only 16 bits wide (so 18-bit not being possible at all), DMA triggers (noting the need to strobe the write pin per data word), or something else has made me discard the idea; most recently I've been thinking of using a tiny FPGA, say iCE40HX1K, for this. Olimex has a nice-looking, affordable OSHW
board for testing the idea, too; the BGA and 0.5mm pitch TQFP/VQFP footprint may be outside my current soldering ability to do a board from scratch.
RP2040 sounds like a viable way to implement this – for example an USB 1.1 (12 Mbit/s, about 1 Mbytes/sec in practice) 320×240 external display module for appliances (routers and NASes), perhaps with JPEG or PNG decompression, and/or YCbCr->RGB conversion, perhaps YCbCr DCT to RGB. Especially if one were to extend the framebuffer (and pixel data RAM) with QSPI PSRAM. Anyone done that yet?
The reason I mentioned Nokia and Stephen Elop earlier, is because when I and others expressed incredulity on his choice because his career (Macromedia, Adobe, Juniper, Microsoft) shows he has a strictly proprietary software mindset, actively hostile to libre software, and thus would be unable to carry Nokia's Linux-based efforts. He has never fostered cooperation between companies, rather having the Embrace-Extend-Extinguish mentality Steven Ballmer drove at Microsoft (perhaps the reason why Ballmer approached Elop at Juniper in the first place?), and would likely drive Nokia into the hands of a large software house, like Microsoft.
People like andersm laughed at those like me, claiming we were spouting "conspiracy theories of Bill Gates paying Elop to destroy Nokia from the inside so that it could be bought cheaply by Microsoft".
That is exactly the kind of twisting of opinion to be able to ridicule it, that I rail against. Instead of acknowledging the reasons for my opinion and arguing them, those reasons are replaced with a ridiculous assertion. Instead of having the uncomfortable discussion about what extending Elop's policies and approaches to Nokia would likely lead to, we were painted as Linux zealots spreading conspiracy theories. It still offends me, especially because
we were right: Elop may have been the best choice available, but the result of his leadership at Nokia lead to perfectly predictable results. That does not mean Elop is a horrible person or participated in any conspiracy, just that choosing him as Nokia's CEO lead to entirely predictable results – results that people like andersm still claim "nobody could predict".
This is pertinent in this thread, because of Eben Upton: he is the person responsible for steering the Raspberry Pi community and technical personnel, and while technically adept and probably a very nice person, seems to have an irrational dislike of libre licensing, and that has permeated the way the Foundation works. Like I said, just look at
the Foundation personnel, and try to find their contributions in any major libre projects their products are dependent on!
I do not really care if the Pi products are libre or not; there are valid reasons for and against. I do care about doing things
wrong, with poor results or causing undue friction. It is hard enough to deal with individuals who consider themselves Paying Customers and have the contract and privileges that entails in libre projects and especially discussions about using libre projects (they just do not understand the cost-benefit calculations at all!); having a Foundation with a good purpose have an internal culture that snubs the libre communities that their own products relies on, is .. stupid. The only ones that could maybe talk to the Foundation are their own customers; people like me, outsiders, talking to the Foundation, would just aggravate them. That is why I am talking about this to
you.
(Hopefully, the above two examples of projects with the Pico I listed earlier in this post, shows that I am not irrationally hostile to anyone or anything.)