<?xml-stylesheet type="text/xsl" href="https://community.element14.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>OO Library to handle Pico PIO relative interrupts: library design</title><link>/products/raspberry-pi/b/blog/posts/oo-library-to-handle-pico-pio-relative-interrupts-library-design</link><description>This post explains the internal design of OO Library to handle Pico PIO relative interrupts: usage and example .



I made an Object Oriented library that supports handling PIO interrupts with C++ objects.Goal: let a PI...</description><dc:language>en-US</dc:language><generator>Telligent Community 12</generator><item><title>RE: OO Library to handle Pico PIO relative interrupts: library design</title><link>https://community.element14.com/products/raspberry-pi/b/blog/posts/oo-library-to-handle-pico-pio-relative-interrupts-library-design</link><pubDate>Sun, 02 Nov 2025 21:23:20 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:f92905a7-470f-4b3e-9f2d-bfcd6cdd918f</guid><dc:creator>Jan Cumps</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;One design decision I have been going back and forth over, is: should I clear the PIO interrupt if there is no handler object registered for it?&amp;nbsp;I had left a TODO in the code to remind @self.&lt;/p&gt;
&lt;p&gt;Mind is made up. I clear the interrupt.&amp;nbsp;The library&amp;#39;s&amp;nbsp;interrupt_handler() is registered as handler. It&amp;#39;s appropriate for the handler to clear the interrupt when it gets called.&lt;/p&gt;
&lt;p&gt;[embed:dc8ab71f-3b98-42d9-b0f6-e21e02a0f8e2:72c9bc32-1ffa-4c81-8baa-65de9a0498dc:type=c_cpp&amp;text=private%3A%0A%20%20%20%20%2F%2F%20forwards%20the%20interrupt%20to%20the%20correct%20handler%20object%0A%20%20%20%20static%20void%20interrupt_handler%28PIO%20pio%29%20%7B%0A%20%20%20%20%20%20%20%20if%20%28pio-%3Eirq%20%3D%3D%200U%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%3B%20%2F%2F%20we%20can%27t%20handle%20IRQs%20that%20don%27t%20have%20sm%20info%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20assert%20%28pio-%3Eirq%29%3B%20%2F%2F%20there%20should%20always%20be%20a%20sm%0A%20%20%20%20%20%20%20%20uint%20sm%20%3D%20sm_from_interrupt%28pio-%3Eirq%2C%20interrupt_number%29%3B%0A%20%20%20%20%20%20%20%20uint%20ir%20%3D%20relative_interrupt%28interrupt_number%2C%20sm%29%3B%0A%20%20%20%20%20%20%20%20_pio_interrupt_clear%28pio%2C%20ir%29%3B%20%2F%2F%20I%20clear%20even%20if%20no%20handler%0A%20%20%20%20%20%20%20%20H%20%2Ahandler%20%3D%20%20handlers_%5Bindex_for%28pio%2C%20sm%29%5D%3B%0A%20%20%20%20%20%20%20%20if%20%28handler%20%21%3D%20nullptr%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%28%2Ahandler%29%28%29%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D]&lt;/p&gt;
&lt;p&gt;I clear it as&amp;nbsp;early in the handler as I can. All code before it serves to look up info needed to both clear the interrupt, and forward control to the handling object.&lt;/p&gt;&lt;img src="https://community.element14.com/aggbug?PostID=29166&amp;AppID=86&amp;AppType=Weblog&amp;ContentType=0" width="1" height="1"&gt;</description></item><item><title>RE: OO Library to handle Pico PIO relative interrupts: library design</title><link>https://community.element14.com/products/raspberry-pi/b/blog/posts/oo-library-to-handle-pico-pio-relative-interrupts-library-design</link><pubDate>Fri, 29 Aug 2025 11:23:27 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:f92905a7-470f-4b3e-9f2d-bfcd6cdd918f</guid><dc:creator>Jan Cumps</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;The main reasons why I built this library:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;My PIO stepper motor library had this functionality as part of the motor manager class.&lt;br /&gt;I think that this functionality is useful in other scenarios too.&lt;br /&gt;Factoring it out to its own reusable library makes sense&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;The class in my PIO stepper motor driver was complex. Complexity of the interrupt handler logic was higher than the core functionality&amp;#39;s complexity.&lt;br /&gt;&lt;span&gt;Factoring&amp;nbsp;out the interrupt logic vastly simplifies the class design (see below)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;stepper class declaration &lt;em&gt;before&lt;/em&gt; factoring out the interrupt handling:&lt;/span&gt;&lt;/strong&gt;&lt;span&gt;&lt;br /&gt;this is the complex design, where the irq handling is part of the logic&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;[embed:dc8ab71f-3b98-42d9-b0f6-e21e02a0f8e2:7cdde0b6-8bb9-43da-9509-7aaadd401225:type=csharp&amp;text=class%20stepper_callback_controller%20%3A%20public%20stepper_controller%20%7B%0Ausing%20notifier_t%20%3D%20void%20%28%2A%29%28const%20stepper_callback_controller%26%29%3B%20%2F%2F%20callback%20definition%0Aprivate%3A%0A%0A%20%20%20%20%2F%2A%0A%20%20%20%20PIO%20interrupts%20can%20only%20call%20functions%20without%20parameters.%20They%20can%27t%20call%20object%20members.%0A%20%20%20%20This%20static%20embedded%20utility%20class%20helps%20matching%20interrupts%20to%20the%20relevant%20object.%0A%20%20%20%20%2A%2F%0A%20%20%20%20class%20interrupt_manager%20%7B%0A%20%20%20%20private%3A%0A%20%20%20%20%20%20%20%20interrupt_manager%28%29%20%3D%20delete%3B%20%20%2F%2F%20static%20class.%20prevent%20instantiating.%0A%20%20%20%20public%3A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%2F%2F%20if%20an%20object%20is%20currently%20handling%20a%20pio%20%2B%20sm%20combination%2C%20it%20will%20%0A%20%20%20%20%20%20%20%20%2F%2F%20be%20replaced%20and%20will%20no%20longer%20receive%20interrupts%0A%20%20%20%20%20%20%20%20%2F%2F%20return%20false%20as%20warning%20if%20an%20existing%20combination%20is%20replaced%0A%20%20%20%20%20%20%20%20static%20bool%20register_stepper%28stepper_callback_controller%20%2A%20stepper%2C%20bool%20set%29%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20PIO%20API%20doesn%27t%20accept%20a%20callback%20with%20parameters%2C%20so%20I%20can%27t%20pass%20the%20PIO%20instance%0A%20%20%20%20%20%20%20%20%2F%2F%20provide%20a%20parameter-less%20method%20for%20ezach%20PIO%20is%20a%20reasonable%20solution%0A%20%20%20%20%20%20%20%20%2F%2F%20only%20task%20is%20to%20call%20interrupt_handler%28%29%20and%20passing%20it%20the%20PIO%20indicated%20in%20the%20name.%0A%20%20%20%20%20%20%20%20%2F%2F%20Without%20overhead%3A%20optimised%20out%20inrelease%20code%0A%20%20%20%20%20%20%20%20static%20inline%20void%20interrupt_handler_PIO0%28%29%20%7B%20interrupt_handler%28pio0%29%3B%20%7D%20%20%20%20%0A%20%20%20%20%20%20%20%20static%20inline%20void%20interrupt_handler_PIO1%28%29%20%7B%20interrupt_handler%28pio1%29%3B%20%7D%0A%23if%20%28NUM_PIOS%20%3E%202%29%20%2F%2F%20pico%202%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20static%20inline%20void%20interrupt_handler_PIO2%28%29%20%7B%20interrupt_handler%28pio2%29%3B%20%7D%0A%23endif%20%20%20%20%20%20%20%20%0A%20%20%20%20private%3A%0A%20%20%20%20%20%20%20%20%2F%2F%20forwards%20the%20interrupt%20to%20the%20surrounding%20class%0A%20%20%20%20%20%20%20%20static%20void%20interrupt_handler%28PIO%20pio%29%3B%0A%20%20%20%20%20%20%20%20%2F%2F%20utility%20calculates%20the%20index%20for%20the%20object%20staht%20serves%20a%20state%20machine%20in%20steppers_%0A%20%20%20%20%20%20%20%20static%20inline%20size_t%20index_for%28PIO%20pio%2C%20uint%20sm%29%20%7B%20return%20PIO_NUM%28pio%29%20%2A%204%20%2B%20sm%3B%20%7D%0A%20%20%20%20%20%20%20%20%2F%2F%20keep%20pointer%20of%20objects%20that%20serve%20the%20state%20machines%0A%20%20%20%20%20%20%20%20%2F%2F%202-D%20array%20with%20slot%20for%20all%20possible%20state%20machines%3A%20PIO0%5B0..3%5D%2C%20PIO1%5B0..3%5D%2C%20...%0A%20%20%20%20%20%20%20%20static%20std%3A%3Aarray%3Cstepper_callback_controller%20%2A%2C%20NUM_PIOS%20%2A%204%3E%20steppers_%3B%0A%20%20%20%20%7D%3B%20%20%20%0Apublic%3A%0A%20%20%20%20stepper_callback_controller%28PIO%20pio%2C%20uint%20sm%29%20%3A%20stepper_controller%28pio%2Csm%29%2C%20commands_%280U%29%2C%0A%20%20%20%20%20%20%20%20callback_%28nullptr%29%20%7B%20interrupt_manager%3A%3Aregister_stepper%28this%2C%20true%29%3B%20%7D%0A%20%20%20%20virtual%20~stepper_callback_controller%28%29%20%7B%20interrupt_manager%3A%3Aregister_stepper%28this%2C%20false%29%3B%20%7D%0A%0A%20%20%20%20%2F%2F%20return%20commands%20completed%0A%20%20%20%20inline%20uint%20commands%28%29%20const%20%7B%20return%20commands_%3B%20%7D%0A%20%20%20%20%2F%2F%20reset%20commands%20completed%20to%200%0A%20%20%20%20inline%20void%20reset_commands%28%29%20%7B%20commands_%20%3D%200U%3B%20%7D%0A%0A%20%20%20%20%2F%2F%20register%20object%20as%20interrupt%20service%20for%20its%20state%20machine%0A%20%20%20%20void%20register_pio_interrupt%28uint%20irq_channel%2C%20bool%20enable%29%3B%0A%20%20%20%20%2F%2F%20user%20code%20class%20to%20call%20when%20a%20command%20is%20finished.%0A%20%20%20%20%2F%2F%20Pass%20immutable%20reference%20to%20object%20as%20user%20info%0A%20%20%20%20inline%20void%20on_complete_callback%28notifier_t%20callback%29%20%7B%20callback_%20%3D%20callback%3B%20%7D%0Aprivate%3A%0A%20%20%20%20void%20handler%28%29%3B%0A%20%20%20%20volatile%20uint%20commands_%3B%20%2F%2F%20volatile%3A%20updated%20by%20interrupt%20handler%0A%20%20%20%20notifier_t%20callback_%3B%0A%7D%3B]&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;stepper class declaration &lt;em&gt;after&lt;/em&gt; factoring out the interrupt handling:&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;this is the simple design, where the irq handling is&amp;nbsp;farmed out to the pio_irq lib&lt;br /&gt;The embedded class is gone. So are irq related private methods.&lt;/p&gt;
&lt;p&gt;[embed:dc8ab71f-3b98-42d9-b0f6-e21e02a0f8e2:1bd16859-d09a-4adc-861e-c76e5d154e0a:type=csharp&amp;text=class%20stepper_callback_controller%20%3A%20public%20stepper_controller%20%7B%0D%0Ausing%20notifier_t%20%3D%20void%20%28%2A%29%28const%20stepper_callback_controller%26%29%3B%20%2F%2F%20callback%20definition%0D%0A%0D%0Apublic%3A%0D%0A%20%20%20%20stepper_callback_controller%28PIO%20pio%2C%20uint%20sm%29%3B%0D%0A%20%20%20%20virtual%20~stepper_callback_controller%28%29%3B%0D%0A%0D%0A%20%20%20%20%2F%2F%20return%20commands%20completed%0D%0A%20%20%20%20inline%20uint%20commands%28%29%20const%20%7B%20return%20commands_%3B%20%7D%0D%0A%20%20%20%20%2F%2F%20reset%20commands%20completed%20to%200%0D%0A%20%20%20%20inline%20void%20reset_commands%28%29%20%7B%20commands_%20%3D%200U%3B%20%7D%0D%0A%0D%0A%20%20%20%20%2F%2F%20register%20object%20as%20interrupt%20service%20for%20its%20state%20machine%0D%0A%20%20%20%20void%20register_pio_interrupt%28uint%20irq_channel%2C%20bool%20enable%29%3B%0D%0A%20%20%20%20%2F%2F%20user%20code%20class%20to%20call%20when%20a%20command%20is%20finished.%0D%0A%20%20%20%20%2F%2F%20Pass%20immutable%20reference%20to%20object%20as%20user%20info%0D%0A%20%20%20%20inline%20void%20on_complete_callback%28notifier_t%20callback%29%20%7B%20callback_%20%3D%20callback%3B%20%7D%0D%0A%20%20%20%20inline%20void%20operator%28%29%28%29%20%7B%0D%0A%20%20%20%20%20%20%20%20commands_%20%3D%20commands_%20%2B%201%3B%0D%0A%20%20%20%20%20%20%20%20if%20%28callback_%20%21%3D%20nullptr%29%20%7B%20%28callback_%29%28%20%2Athis%29%3B%20%7D%0D%0A%20%20%20%20%7D%0D%0A%0D%0Aprivate%3A%0D%0A%20%20%20%20volatile%20uint%20commands_%3B%20%2F%2F%20volatile%3A%20updated%20by%20interrupt%20handler%0D%0A%20%20%20%20notifier_t%20callback_%3B%0D%0A%7D%3B]&lt;/p&gt;
&lt;p&gt;The changes in the class implementation are even more drastic.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;stepper class implementation before:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;[embed:dc8ab71f-3b98-42d9-b0f6-e21e02a0f8e2:1069f793-1f1b-46f9-b096-89b6ab4a90a0:type=csharp&amp;text=bool%20stepper_callback_controller%3A%3Ainterrupt_manager%3A%3Aregister_stepper%28stepper_callback_controller%20%2A%20stepper%2C%20bool%20set%29%20%7B%0D%0A%20%20%20%20size_t%20idx%20%3D%20index_for%28stepper-%3Epio_%2C%20stepper-%3Esm_%29%3B%0D%0A%20%20%20%20stepper_callback_controller%20%2Aold%20%3D%20steppers_%5Bidx%5D%3B%0D%0A%20%20%20%20steppers_%5Bidx%5D%20%3D%20set%20%3F%20stepper%20%3A%20nullptr%3B%0D%0A%20%20%20%20return%20set%20%3F%20old%20%3D%3D%20nullptr%20%3A%20true%3B%0D%0A%7D%0D%0A%0D%0Avoid%20stepper_callback_controller%3A%3Ainterrupt_manager%3A%3Ainterrupt_handler%28PIO%20pio%29%20%7B%0D%0A%20%20%20%20if%20%28pio-%3Eirq%20%3D%3D%200U%29%20%7B%0D%0A%20%20%20%20%20%20%20%20return%3B%20%2F%2F%20we%20can%27t%20handle%20IRQs%20that%20don%27t%20have%20sm%20info%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20assert%20%28pio-%3Eirq%29%3B%20%2F%2F%20there%20should%20always%20be%20a%20sm%0D%0A%20%20%20%20uint%20sm%20%3D%20pio_irq_util%3A%3Asm_from_interrupt%28pio-%3Eirq%2C%20stepper_PIO_IRQ_DONE%29%3B%0D%0A%20%20%20%20stepper_callback_controller%20%2Astepper%20%3D%20%20steppers_%5Bindex_for%28pio%2C%20sm%29%5D%3B%0D%0A%20%20%20%20if%20%28stepper%20%21%3D%20nullptr%29%20%7B%0D%0A%20%20%20%20%20%20%20%20stepper%20-%3E%20handler%28%29%3B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0A%0D%0Avoid%20stepper_callback_controller%3A%3Aregister_pio_interrupt%28uint%20irq_channel%2C%20bool%20enable%29%20%7B%0D%0A%20%20%20%20assert%20%28irq_channel%20%3C%202%29%3B%20%2F%2F%20develop%20check%20that%20we%20use%200%20or%201%20only%0D%0A%20%20%20%20uint%20irq_num%20%3D%20PIO0_IRQ_0%20%2B%202%20%2A%20PIO_NUM%28pio_%29%20%2B%20irq_channel%3B%0D%0A%20%20%20%20irq_handler_t%20handler%20%3D%20nullptr%3B%0D%0A%0D%0A%20%20%20%20if%20%28irq_channel%20%3D%3D%200%29%20%7B%0D%0A%20%20%20%20%20%20%20%20pio_set_irq0_source_enabled%28pio_%2C%20pio_irq_util%3A%3Ainterrupt_source%28pis_interrupt0%2C%20%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20pio_irq_util%3A%3Arelative_interrupt%28stepper_PIO_IRQ_DONE%2C%20sm_%29%29%2C%20true%29%3B%0D%0A%20%20%20%20%7D%20else%20%7B%0D%0A%20%20%20%20%20%20%20%20pio_set_irq1_source_enabled%28pio_%2C%20pio_irq_util%3A%3Ainterrupt_source%28pis_interrupt0%2C%20%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20pio_irq_util%3A%3Arelative_interrupt%28stepper_PIO_IRQ_DONE%2C%20sm_%29%29%2C%20true%29%3B%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20switch%20%28PIO_NUM%28pio_%29%29%20%7B%0D%0A%20%20%20%20case%200%3A%0D%0A%20%20%20%20%20%20%20%20handler%20%3D%20interrupt_manager%3A%3Ainterrupt_handler_PIO0%3B%0D%0A%20%20%20%20%20%20%20%20break%3B%0D%0A%20%20%20%20case%201%3A%0D%0A%20%20%20%20%20%20%20%20handler%20%3D%20interrupt_manager%3A%3Ainterrupt_handler_PIO1%3B%0D%0A%20%20%20%20%20%20%20%20break%3B%0D%0A%23if%20%28NUM_PIOS%20%3E%202%29%20%2F%2F%20pico%202%20%20%20%20%20%20%20%0D%0A%20%20%20%20case%202%3A%0D%0A%20%20%20%20%20%20%20%20handler%20%3D%20interrupt_manager%3A%3Ainterrupt_handler_PIO2%3B%0D%0A%20%20%20%20%20%20%20%20break%3B%0D%0A%23endif%20%20%20%20%20%20%20%20%20%20%20%20%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20irq_add_shared_handler%28irq_num%2C%20handler%2C%20PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY%20%29%3B%20%20%2F%2FSet%20the%20handler%20in%20the%20NVIC%0D%0A%20%20%20%20if%20%28enable%29%20%7B%0D%0A%20%20%20%20%20%20%20%20irq_set_enabled%28irq_num%2C%20true%29%3B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Avoid%20stepper_callback_controller%3A%3Ahandler%28%29%20%7B%0D%0A%20%20%20%20uint%20irq%20%3D%20pio_-%3Eirq%3B%0D%0A%20%20%20%20uint%20ir%20%3D%20pio_irq_util%3A%3Arelative_interrupt%28stepper_PIO_IRQ_DONE%2C%20sm_%29%3B%0D%0A%20%20%20%20assert%28irq%20%26%201%20%3C%3C%20sm_%29%3B%20%2F%2F%20develop%20check%3A%20interrupt%20is%20from%20the%20correct%20state%20machine%0D%0A%20%20%20%20commands_%20%3D%20commands_%20%2B%201%3B%0D%0A%20%20%20%20pio_interrupt_clear%28pio_%2C%20ir%29%3B%0D%0A%20%20%20%20if%20%28callback_%20%21%3D%20nullptr%29%20%7B%0D%0A%20%20%20%20%20%20%20%20%28callback_%29%28%20%2Athis%29%3B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0A%2F%2F%20initialise%20static%20class%20data%0D%0A%2F%2F%20static%20pio%20program%20offset%0D%0Auint%20stepper_controller%3A%3Apio_offset_%5BNUM_PIOS%5D%3B%0D%0A%2F%2F%20static%20data%20member%20must%20be%20initialised%20outside%20of%20the%20class%2C%20or%20the%20linker%20will%20not%20capture%20it%0D%0Astd%3A%3Aarray%3Cstepper_callback_controller%20%2A%2C%20NUM_PIOS%20%2A%204%3E%20stepper_callback_controller%3A%3Ainterrupt_manager%3A%3Asteppers_%3B]&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;stepper class implementation&lt;span&gt;&amp;nbsp;&lt;/span&gt;after:&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;[embed:dc8ab71f-3b98-42d9-b0f6-e21e02a0f8e2:f75944d7-33cf-4aac-8c8e-c4d399206994:type=csharp&amp;text=%2F%2F%20relative%20interrupt%20handler%0Ausing%20pio_irq_manager_t%20%3D%20pio_irq%3A%3Apio_irq%3Cstepper_callback_controller%2C%20stepper_PIO_IRQ_DONE%3E%3B%0A%0Astepper_callback_controller%3A%3Astepper_callback_controller%28PIO%20pio%2C%20uint%20sm%29%20%3A%20%0A%20%20%20%20%20%20%20%20stepper_controller%28pio%2Csm%29%2C%20commands_%280U%29%2C%20callback_%28nullptr%29%20%7B%20%0A%20%20%20%20pio_irq_manager_t%3A%3Aregister_handler%28pio_%2C%20sm_%2C%20this%2C%20true%29%3B%20%0A%7D%0A%0Astepper_callback_controller%3A%3A~stepper_callback_controller%28%29%20%7B%20%0A%20%20%20%20pio_irq_manager_t%3A%3Aregister_handler%28pio_%2C%20sm_%2C%20this%2C%20false%29%3B%20%0A%7D%0A%0Avoid%20stepper_callback_controller%3A%3Aregister_pio_interrupt%28uint%20irq_channel%2C%20bool%20enable%29%20%7B%0A%20%20%20%20pio_irq_manager_t%3A%3Aregister_interrupt%28irq_channel%2C%20pio_%2C%20sm_%2C%20enable%29%3B%0A%7D%0A%0A%2F%2F%20initialise%20static%20class%20data%0A%2F%2F%20static%20pio%20program%20offset%0Auint%20stepper_controller%3A%3Apio_offset_%5BNUM_PIOS%5D%3B]&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;utility file gone:&lt;/strong&gt;&lt;br /&gt;all PIO interrupt helper functions that were sitting in the PIO stepper lib, have been factored into the pio_irq lib. &lt;br /&gt;The file&amp;nbsp;pio_irq_util.cpp could be removed from the PIO stepper lib. Making that lib focus better on it&amp;#39;s single job of handling stepper motors.&lt;/p&gt;
&lt;p&gt;[embed:dc8ab71f-3b98-42d9-b0f6-e21e02a0f8e2:ea4c1f3a-859e-4df1-84b0-21290dec1f1a:type=csharp&amp;text=%2F%20calculate%20relative%20IRQ%20flag%20for%20a%20state%20mchine%0D%0A%2F%2F%2010%20%28REL%29%3A%20the%20state%20machine%20ID%20%280%E2%80%A63%29%20is%20added%20to%20the%20IRQ%20flag%20index%2C%20by%20way%20of%0D%0A%2F%2F%20modulo-4%20addition%20on%20the%20two%20LSBs%0D%0Ainline%20uint%20relative_interrupt%28const%20uint32_t%20ir%2C%20const%20uint%20sm%29%20%7B%0D%0A%20%20%20%20%2F%2F%20TODO%20validate%20for%20Pico%202%20interrupts%204%20..%207%0D%0A%20%20%20%20uint32_t%20retval%20%3D%20ir%20%26%200x03%3B%20%2F%2F%20last%202%20bits%0D%0A%20%20%20%20retval%20%2B%3D%20sm%3B%20%2F%2F%20add%20relative%20value%20%28is%20sm%29%0D%0A%20%20%20%20retval%20%3D%20retval%20%25%204%3B%20%2F%2F%20mod%204%0D%0A%20%20%20%20%2F%2F%20TODO%20most%20likely%20I%20have%20to%20restore%20bits%2031..2%20here%20to%20work%20with%20Pico%202%0D%0A%20%20%20%20%2F%2F%20but%20I%20don%27t%20have%20one%20to%20test%20it%0D%0A%20%20%20%20retval%20%7C%3D%20ir%20%26%200xfffffffc%3B%0D%0A%20%20%20%20return%20retval%3B%0D%0A%7D%0D%0A%0D%0A%2F%2F%20utility%20to%20do%20math%20on%20pio_interrupt_source%20enum%0D%0Ainline%20pio_interrupt_source%20interrupt_source%28const%20pio_interrupt_source%20is%2C%20const%20uint32_t%20ir%29%20%7B%0D%0A%20%20%20%20return%20static_cast%3Cpio_interrupt_source%3E%28std%3A%3Ato_underlying%28is%29%20%2B%20ir%29%3B%0D%0A%7D%0D%0A%0D%0A%2F%2F%20find%20for%20what%20state%20machine%20a%20relative%20interrupt%20was%20thrown%0D%0Auint%20sm_from_interrupt%28const%20uint32_t%20irq_val%2C%20const%20uint32_t%20ir%29%20%7B%0D%0A%20%20%20%20%2F%2F%20TODO%20validate%20for%20Pico%202%20interrupts%204%20..%207%0D%0A%20%20%20%20uint%20i%3B%0D%0A%20%20%20%20for%20%28i%20%3D%200%3B%20i%20%3C%204%3B%20i%2B%2B%29%20%7B%20%2F%2F%20should%20be%20sm%200%20..%203%0D%0A%20%20%20%20%20%20%20%20if%20%28irq_val%20%26%201%20%3C%3C%20i%29%20%7B%20%2F%2F%20is%20bit%20set%3F%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20assert%28i%20%21%3D%204%29%3B%20%2F%2F%20develop%20check%20there%20has%20to%20be%20a%20bit%0D%0A%20%20%20%20return%20i%3B%0D%0A%7D%0D%0A]&lt;/p&gt;
&lt;p&gt;GitHub reports a netto &lt;em&gt;removal of 130 lines of code&lt;/em&gt; in the PIO stepper library.&lt;/p&gt;
&lt;p&gt;This does not require changes to the firmware that uses the stepper motor library.&amp;nbsp;The pio_irq library dependency is resolved automatically during the CMake execution, and the public API has not changed.&lt;/p&gt;&lt;img src="https://community.element14.com/aggbug?PostID=29166&amp;AppID=86&amp;AppType=Weblog&amp;ContentType=0" width="1" height="1"&gt;</description></item><item><title>RE: OO Library to handle Pico PIO relative interrupts: library design</title><link>https://community.element14.com/products/raspberry-pi/b/blog/posts/oo-library-to-handle-pico-pio-relative-interrupts-library-design</link><pubDate>Thu, 28 Aug 2025 20:32:38 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:f92905a7-470f-4b3e-9f2d-bfcd6cdd918f</guid><dc:creator>DAB</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;Great post Jan.&lt;/p&gt;
&lt;p&gt;I can see where your approach would be very useful, especially in ramping up or ramping down the speed.&lt;/p&gt;&lt;img src="https://community.element14.com/aggbug?PostID=29166&amp;AppID=86&amp;AppType=Weblog&amp;ContentType=0" width="1" height="1"&gt;</description></item><item><title>RE: OO Library to handle Pico PIO relative interrupts: library design</title><link>https://community.element14.com/products/raspberry-pi/b/blog/posts/oo-library-to-handle-pico-pio-relative-interrupts-library-design</link><pubDate>Thu, 28 Aug 2025 14:41:54 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:f92905a7-470f-4b3e-9f2d-bfcd6cdd918f</guid><dc:creator>genebren</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Another great PICO blog!&amp;nbsp; I am still planning on trying out these processors and your software.&amp;nbsp; I just seem to be stuck dealing with my existing projects.&amp;nbsp; Thanks for sharing!&lt;/p&gt;&lt;img src="https://community.element14.com/aggbug?PostID=29166&amp;AppID=86&amp;AppType=Weblog&amp;ContentType=0" width="1" height="1"&gt;</description></item></channel></rss>