{"id":827,"date":"2016-07-04T02:59:15","date_gmt":"2016-07-04T06:59:15","guid":{"rendered":"http:\/\/www.rfdm.com\/blog\/?p=827"},"modified":"2016-07-04T02:59:15","modified_gmt":"2016-07-04T06:59:15","slug":"rotary-encoder-driver-for-freebsd-on-raspberry-pi","status":"publish","type":"post","link":"https:\/\/www.rfdm.com\/blog\/?p=827","title":{"rendered":"rotary encoder driver for FreeBSD on Raspberry Pi"},"content":{"rendered":"<p>I&#8217;m working on a rotary encoder driver for FreeBSD 11.0 on the Raspberry Pi.<\/p>\n<p>Why?<\/p>\n<p>I&#8217;m tired of consuming CPU to poll GPIO pins for my rotary encoders for my garage door opener project, and as of yet there isn&#8217;t a mechanism to deal with GPIO interrupts from user space on FreeBSD.  And even with the elegant kqueue mechanism, I don&#8217;t really need to push edge interrupts to user space.  All I really want is rotary encoder state transitions.<\/p>\n<p>There seems to be a quirk in the setup of GPIO interrupts on the BCM283[56] under FreeBSD.  From a very quick scan of the data sheet, I should be able to have separate handlers for rising and falling edges.  But FreeBSD doesn&#8217;t allow it.  Specifically, <tt>gpio_alloc_intr_resource()<\/tt> fails for the second interrupt.  I have worked around it for now, but I will hopefully find time to revisit this issue later.<\/p>\n<p>I have the interrupt handling working, I tested it using a simple shell script to manipulate the pullup and pulldown resistors.  I have two encoders configured since I need one for each of my garage doors.<\/p>\n<p><code><br \/>\ngpiorotenc0: <GPIO rotary encoder> on ofwbus0<br \/>\ngpiorotenc0: inputs on gpio0 pin 27, gpio0 pin 22<br \/>\ngpiorotenc1: <GPIO rotary encoder> on ofwbus0<br \/>\ngpiorotenc1: inputs on gpio0 pin 23, gpio0 pin 24<br \/>\n...<br \/>\nJul  4 06:54:48 rpi2 kernel: gpiorotenc0: channel A value 1<br \/>\nJul  4 06:54:48 rpi2 kernel: gpiorotenc0: channel A value 0<br \/>\nJul  4 06:54:48 rpi2 kernel: gpiorotenc0: channel B value 1<br \/>\nJul  4 06:54:48 rpi2 kernel: gpiorotenc0: channel B value 0<br \/>\nJul  4 06:54:48 rpi2 kernel: gpiorotenc1: channel A value 1<br \/>\nJul  4 06:54:48 rpi2 kernel: gpiorotenc1: channel A value 0<br \/>\nJul  4 06:54:48 rpi2 kernel: gpiorotenc1: channel B value 1<br \/>\nJul  4 06:54:48 rpi2 kernel: gpiorotenc1: channel B value 0<br \/>\n<\/code><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m working on a rotary encoder driver for FreeBSD 11.0 on the Raspberry Pi. Why? I&#8217;m tired of consuming CPU to poll GPIO pins for my rotary encoders for my garage door opener project, and as of yet there isn&#8217;t a mechanism to deal with GPIO interrupts from user space on FreeBSD. And even with &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.rfdm.com\/blog\/?p=827\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;rotary encoder driver for FreeBSD on Raspberry Pi&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[29,12],"tags":[],"class_list":["post-827","post","type-post","status-publish","format-standard","hentry","category-freebsd","category-software-development"],"_links":{"self":[{"href":"https:\/\/www.rfdm.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/827","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rfdm.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rfdm.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rfdm.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rfdm.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=827"}],"version-history":[{"count":7,"href":"https:\/\/www.rfdm.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/827\/revisions"}],"predecessor-version":[{"id":834,"href":"https:\/\/www.rfdm.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/827\/revisions\/834"}],"wp:attachment":[{"href":"https:\/\/www.rfdm.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=827"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rfdm.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=827"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rfdm.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=827"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}