Journey's End

Aug 11
2024

PIO and Interrupts

Introduction

I want to be able to raise system level interrupts from PIO programs and there aren’t too many examples of this, so here is my simple contribution.

PIO program

First, the PIO program, which simply waits for a pin to change and then immediately raises PIO IRQ 0.

.program irq_example
.wrap_target

wait 0 pin 0    ; wait for a 0 on IN pin 0
irq nowait 0    ; raise PIO IRQ 0

.wrap

Compile this with pioasm then #include the .h in your C program.

C Program

Interrupt Setup

There are four system level interrupts related to PIO: PIO0_IRQ_0, PIO0_IRQ_1, PIO1_IRQ_0, PIO1_IRQ_1. We shall use PIO0_IRQ_0.

First we attach an interrupt handler to PIO0_IRQ_0:

void isr(void) {
    // clear PIO IRQ 0 that was raised by irq nowait 0
    pio_interrupt_clear(pio0, 0);
}

irq_add_shared_handler(PIO0_IRQ_0,
                       isr,
                       PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY);

It is important that pio_interrupt_clear() is called otherwise the CPU will lock up constantly executing the interrupt handler (aka ISR - interrupt service routine)

We then enable the interrupt:

irq_set_enabled(PIO0_IRQ_0, true);

Finally we configure PIO0_IRQ_0 to be triggered when PIO IRQ 0 is raised:

pio_set_irq0_source_enabled(pio0, pis_interrupt0, true);

The functions used above are described in the Pico C SDK documentation.

PIO Setup

The PIO program can now by installed the usual way by first setting up the state machine:

uint sm = pio_claim_unused_sm(pio0, true);
uint offset = pio_add_program(pio0, &irq_example_program);
pio_sm_config cfg = irq_example_program_get_default_config(offset);

Configure and connect GPIO to the state machine:

// connect GP 2 to IN of state machine
sm_config_set_in_pins(&cfg, 2);

// it is an input pin
pio_sm_set_consecutive_pindirs(pio0, sm, 2, 1, false);

// we want pull up on the pin
gpio_pull_up(2);

Now we are ready to start the state machine:

pio_sm_init(pio0, sm, offset, &cfg);
pio_sm_set_enabled(pio0, sm, true);

Sep 12
2014

Adventures in Python Optimisation

Recently I found myself looking at the following piece of code and trying to optimise it:

from __future__ import division

import numpy as np

MagneticPermeability = 4*np.pi*1e-7
MagneticPermeabilityOver4Pi = MagneticPermeability / (4*np.pi)

def fieldfunc_py(p, q, moment):
  r = p - q 
  rmag = np.sqrt(r.dot(r))

  rdash3 = rmag …
ts=14:41 tags=[python,c,code,software]

Dec 07
2009

Jul 16
2008

Apr 14
2007

Writing fitting functions for lmfit

lmfit expects
fitting functions with prototypes in the form:

double
function_name(double, double *);

For example:

double
sin_fit(double t, double * p)

{

return p[0] + p[1] * sin ( 2 * M_PI * ( p[2] * t + p[3]));

}

Note that while
"font:12px Courier, mono;">lm_minimize takes a
pointer to an array of parameters …

ts=13:43 tags=[c,code]