The Log

Emacs Polymode for Pico PIO files

Polymode is an emacs package that provides a framework to mix multiple major modes together with a few lines of code. This can be useful when working with files that contain multiple programming languages and you'd like major mode to switch based on a matching code block for example.

Code for the RaspberryPi Pico programmable i/o (with the C SDK) is basically assembly code and some c-sdk. Something like this:

.program test
    out pins, 1
    jmp loop
% c-sdk {
 static inline void test_program_init(PIO pio, uint sm, uint offset, uint pin1, uint pin2, uint pin3, uint pin4) {
    pio_sm_config c = test_program_get_default_config(offset);
    sm_config_set_out_pins(&c, pin1, 1);
    pio_gpio_init(pio, pin1);
    pio_sm_set_consecutive_pindirs(pio, sm, pin1, 1, true);
    pio_sm_init(pio, sm, offset, &c);
    pio_sm_set_enabled(pio, sm, true);

To allow for the two pieces of code above to live together in the same buffer simultaneously while making use of both asm-mode and c-mode, I wrote a simple poly-pio-mode using Polymode above.

;; Simple Polymode for RaspberryPi Pico PIO files that uses 
;; both asm-mode as host-mode and c-mode for pass-through section

(define-hostmode poly-pio-hostmode
  :mode 'asm-mode)

(define-auto-innermode poly-pio-c-innermode
  :mode 'c-mode
  :head-matcher "^% c-sdk {$"
  :tail-matcher "^%}$"
  :head-mode 'host
  :tail-mode 'host)

(define-polymode poly-pio-mode
  :hostmode 'poly-pio-hostmode
  :innermodes '(poly-pio-c-innermode

(add-to-list 'auto-mode-alist '("\\.pio$" . poly-pio-mode))

It's also available on github.