• Translating Chinese datasheets in PDF

    03/03/2021 at 07:16 0 comments

    Today someone pointed me to the DeepL online translator, which produces more convincing results than the usual big players.

    One "drawback" is that it doesn't handle ,pdf, only .docx or .ppt. So I found a workaround. First take your PDF file and feed it through Adobe's PDF to Word converter, and who better to do it than Adobe.

    Next take the generated .docx (which on viewing you will see retains page formatting, e.g. tables) and send it through DeepL to get a translation in the language of your choice, also in .docx format. You can then use Libreoffice to export to PDF.

    I tried sending the .docx through Google translate but it didn't generate a .docx or .pdf, just rendered it on the screen without the page formatting. So this workflow actually produces superior results.

    Here's a sample, page 3 from the TM1650 datasheet.

  • C labels as values for state machines

    03/02/2021 at 22:18 8 comments

    My page on bitbanging a protocol made me think of how this might be implemented in C. Coroutines are not part of the C language (yet) so I thought about the approach of implementing the protocol state machine in a interrupt handler.

    Normally you would do this with a combination of static variables (statics or globals) and a switch statement. However gcc has an extension for labels as values. Here's an example of the syntax:

    #include <stdio.h>
    int main(int argc, char **argv)
            void *ptr;
            ptr = &&here;
            goto *ptr;
            printf("Labels here is at %p\n", ptr);
            return 0;

    I would have to think a bit about what advantage, if any, this offers over a switch statement. One might be the ability to jump back into the middle of a loop to resume, which you cannot do with a switch statement, provided the loop variable(s) are in static storage.

    Since the Arduino C compiler is avr-gcc, labels as values also work with it.

  • Bitbanging a protocol that has no hardware support

    02/25/2021 at 08:34 0 comments

    Everybody loves a video so here's one to start with before we get to the boring fascinating details.

    There are many protocols out there for communicating between computers, and other computers or peripherals. A subset of these are common enough to be supported by dedicated hardware, e.g. I2C, SPI, UART. New ones are popping up all the time as designers invent ways to communicate with the minimum of hardware and lines. An example is the Neopixel protocol. An example of a uncommon protocol is TMP, the serial protocol used by the Titan Micro family of display driver that resembles I2C but is a cut-down lookalike (that incidentally didn't require Titan Micro to get a I2C address allocation). What do you do when the protocol you want to implement on your MCU doesn't have hardware support?

    There are various ways to tackle the problem. One would be to select a different MCU that has the support. Another is to add a peripheral chip that implements the protocol. This is a traditional path, all those UART chips for MPUs are implementations before the functionality was absorbed into MCUs. Similarly for the USB protocols, these are beginning to be integrated into some MCUs. Another way would be to delegate the task to a slave MCU.

    The Raspberry Pi Pico family (in which the RP2040 is deployed) has an interesting approach to support for uncommon protocols. This SoC contains state engines that can be allocated and programmed to deal with the protocol, relieving the main processor of this work. It's explained in the Pico SDK documentation, and blogs of how to use this feature are appearing, including this Hackaday #RP2040 : PIO - case study . Expect to see more MCUs implement such state engines.

    But what the Pico doesn't suit your other requirements, or if you are too cheap to allocate more hardware to the problem? Surely the MCU has power to spare and you can drive GPIO pins in software? Thus begins your foray into bitbanging.

    Drive it fast but not too fast

    Unfortunately many of those protocols put one in a bind. Ideally you would like the data transfer to go as fast as possible, but the slave chip may have limits. For example TMP above goes up to 250kHz. So delays may have to be inserted in the code to maintain the minimum timing. In this case a delay of 5 µs is needed each state change. For older microprocessors, a inserted NOP or perhaps a call and return would suffice. But for fast MCUs this busy wait prevents the MCU from doing other work. The wastage gets worse as MCUs get faster. Also unless using a timer, the wait is model dependent. Use a faster member of the family and the waits have to rejigged.

    A proper solution takes advantage of the fact that we usually don't need top speed. In fact running it at a lower speed makes the wiring less critical. We only have to run the protocol fast enough. In the case of the TM display chips, it suffices that the transfer time is negligible compared to the update period. A few milliseconds updating the display of a time-of-day clock won't be noticed.

    Solution 1: interrupt handlers

    This method puts the protocol engine in the interrupt handler. Essentially you have to maintain the state of the connection in the handler, and handle all the situations that can occur. When interfacing with the main line you have to deal with resource contention, e.g. shared variables and buffers. This method has a high overhead compared with the dedicated hardware or dedicated state engine methods because you have to execute at least tens of instructions for one state change, but is acceptable if the data volume is low. Another problem is that the interrupt handler enters at the top but you have to restart where you left off in the state machine. But interrupt handlers are the best option if you don't have dedicated hardware to handle the bits. If you think about it, device drivers in operating systems are sophisticated modules which use interrupts to update state in the driver, though usually...
    Read more »