{"id":4042,"date":"2020-05-27T18:16:24","date_gmt":"2020-05-27T23:16:24","guid":{"rendered":"https:\/\/dev.iachieved.it\/iachievedit\/?p=4042"},"modified":"2020-05-27T18:16:24","modified_gmt":"2020-05-27T23:16:24","slug":"hifive1-rev-b-gpio-pins","status":"publish","type":"post","link":"https:\/\/dev.iachieved.it\/iachievedit\/hifive1-rev-b-gpio-pins\/","title":{"rendered":"HiFive1 Rev B GPIO Pins"},"content":{"rendered":"<p>Let&#8217;s make use of the <a href=\"https:\/\/www.sifive.com\/boards\/hifive1-rev-b\">HiFive1 Rev B<\/a> <a href=\"https:\/\/sifive.cdn.prismic.io\/sifive%2Fa4546ced-0922-4d87-9334-e97c1a9fd9a5_hifive1.b01.schematics.pdf\">schematics<\/a> to map out the GPIO controller device pins.  Of particular interest is sheet 3, and the following components of the schematic in section D1:<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2020\/05\/s3d1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2020\/05\/s3d1.png\" alt=\"\" width=\"356\" height=\"265\" class=\"aligncenter size-full wp-image-4043\" \/><\/a><\/p>\n<p>We&#8217;re going to use this as our starting point.  Three GPIO lines labeled 19, 21, and 22 with LEDs on the lines.<\/p>\n<p><em>Editor&#8217;s Note<\/em>:  This write-up on the SiFive HiFive1 Rev B assumes you have one and are familiar with powering it up, connecting to the serial port, and uploading applications.  See our <a href=\"https:\/\/dev.iachieved.it\/iachievedit\/an-introduction-to-the-hifive-rev-b-and-risc-v\/\">last post<\/a> if you need to orient yourself with the environment.<\/p>\n<h2>Using Metal GPIO<\/h2>\n<p>If you haven&#8217;t done so already, familiarize yourself with <a href=\"https:\/\/sifive.github.io\/freedom-metal-docs\/\">Freedom Metal<\/a> and the <a href=\"https:\/\/sifive.github.io\/freedom-metal-docs\/api.html\">API documentation<\/a> because we&#8217;re going to make use of the <a href=\"https:\/\/sifive.github.io\/freedom-metal-docs\/apiref\/gpio.html\">GPIO functions<\/a>.<\/p>\n<p>Recall in the schematic above that the onboard LEDs are tied to GPIO 19 (green LED), GPIO 21 (blue LED), and GPIO 22 (red LED).  While the Metal <a href=\"https:\/\/sifive.github.io\/freedom-metal-docs\/apiref\/led.html\">LED API<\/a> could be used here, we&#8217;re going to work directly with the GPIO functions to prove to ourselves that the above GPIO pins are correct, and also check out the 8 color combinations the LED can produce.<\/p>\n<p>Our basic loop is going to cycle from 0 to 7 and turning on the red LED if bit 1 is set, the green LED if bit 2 is set, and the blue LED if bit 3 is set.  This should cause our HiFive1 on-board LED to cycle through the following color chart:<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2020\/05\/colors.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2020\/05\/colors.png\" alt=\"\" width=\"186\" height=\"159\" class=\"aligncenter size-full wp-image-4045\" \/><\/a><\/p>\n<p>Okay, let&#8217;s get the basics down.  The GPIO can be accessed by obtaining a <code>struct metal_gpio*<\/code> using the <code>metal_gpio_get_device<\/code> function, like this:<\/p>\n<pre>\n#include <metal\/gpio.h>\n\nint main(void) {\n  \/\/ Get GPIO device\n  struct metal_gpio* gpio_device = metal_gpio_get_device(0);\n\n  \/\/ do something with the GPIO\n}\n<\/pre>\n<p>Now that we have the GPIO device itself, let&#8217;s enable GPIO 19 as an output pin.  In our schematic take note that the other side of the LED is tied to 3.3V.  <strong>In other words<\/strong>, there is no setting GPIO 19 high or low required here, if it is enabled you&#8217;re going to get the LED on.<\/p>\n<p>To set GPIO 19 as an output:<\/p>\n<pre>\nmetal_gpio_enable_output(gpio_device, 19);\n<\/pre>\n<p>To disable the output of the pin:<\/p>\n<pre>\nmetal_gpio_disable_output(gpio_device, 19);\n<\/pre>\n<p>Now I <i>think<\/i>this works for the onboard LED because of the way it is wired to the 3.3V supply.  In fact, for Metal GPIO pin 19, if you try to write a 1 to it you actually turn off the onboard LED and turn on the header pin 3.  Speaking of the header pins&#8230;<\/p>\n<h2>Arduino Header and Pins<\/h2>\n<p>Going back to the board schematic, this time on sheet 3 in sections A5, A6, B5, B6, and C5, C6.<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2020\/05\/arduino_headers.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2020\/05\/arduino_headers.png\" alt=\"\" width=\"337\" height=\"430\" class=\"aligncenter size-full wp-image-4048\" \/><\/a><\/p>\n<p>Now this is interesting!  Our Arduino headers as well have notes on which GPIOs are digital-only (high or low), those that are PWM-capable, and which pins are shared by SPI, I2C, and UART.  All we need to do is put this into a nice table, and the following is (I think) a complete GPIO mapping for the SiFive HiFive1 Rev B board.<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2020\/05\/gpio_pins2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2020\/05\/gpio_pins2.png\" alt=\"\" width=\"438\" height=\"380\" class=\"aligncenter size-full wp-image-4064\" \/><\/a><\/p>\n<p>For example, if you wanted to start your project with blinking an LED on a breadboard, you might start with one of the &#8220;standard&#8221; digital input\/output pins on the header, say pin 7.  The chart above (which is derived from the schematic) shows that pin 7 on the header is tied to pin 23 of the GPIO controller.  So to use <em>header<\/em> pin 7 we might write:<\/p>\n<pre>\nmetal_gpio_enable_output(gpio_device, 23);\nmetal_gpio_set_pin(gpio_device, 23, 1);\n<\/pre>\n<p>Or, we could set at the top of our file something along the lines of <code>#define PIN7 23<\/code>.  Just a thought.<\/p>\n<p>Notice once again that this mapping table shows that there are:<\/p>\n<ul>\n<li>20 digital pins<\/li>\n<li>6 PWM-capable pins<\/li>\n<li>1 SPI<\/li>\n<li>1 I2C<\/li>\n<li>1 UART<\/li>\n<\/ul>\n<p>Unfortunately <a href=\"https:\/\/www.sifive.com\/boards\/hifive1-rev-b\">SiFive&#8217;s HiFive1 Rev B page<\/a> indicates there are only 19 digital pins and there are 9 PWM-capable ones, so there&#8217;s something I&#8217;m missing.  I <em>think<\/em> at least for PWM, header pins 17, 18, and 19 on the 6-pin header (to the left of the ESP32) are PWM-capable, though that isn&#8217;t clear from the schematic.  I&#8217;ve asked about that <a href=\"https:\/\/forums.sifive.com\/t\/question-on-hifive1-rev-b-pwm\/3706\">here<\/a> on the <a href=\"https:\/\/forums.sifive.com\/\">SiFive Forums<\/a> and will reconcile this post once I learn more.<\/p>\n<h2>Getting Some Code<\/h2>\n<p><a href=\"https:\/\/github.com\/iachievedit\/hifive1-ledcolors\">This code<\/a> is a work in progress and is modeled around the Arduino digital IO library.  In <a href=\"https:\/\/github.com\/iachievedit\/hifive1-ledcolors\/blob\/master\/digitalio.c\">digitalio.c<\/a> you&#8217;ll see my take on the functions <code>pinMode<\/code> and <code>digitalWrite<\/code>.  There is also a <a href=\"https:\/\/github.com\/iachievedit\/hifive1-ledcolors\/blob\/master\/delay.c\">delay<\/a> function to write the ever-popular blinking lights demo.  All of this code is MIT licensed with portions copied from the <a href=\"https:\/\/github.com\/sifive\/freedom-e-sdk\">SiFive Freedom E SDK<\/a>.<\/p>\n<p>Let&#8217;s look at how we might use these functions to put the onboard LED through all of the possible colors.<\/p>\n<p><a href=\"https:\/\/github.com\/iachievedit\/hifive1-ledcolors\/blob\/master\/main.c\"><code>main.c<\/code><\/a>:<\/p>\n<pre>\n#define RED_ON   0x1\n#define GREEN_ON 0x2\n#define BLUE_ON  0x4\n\nint main(void) {\n\n  pinMode(METAL_GPIO_19, DISABLE);\n  pinMode(METAL_GPIO_21, DISABLE);\n  pinMode(METAL_GPIO_22, DISABLE);\n  \n  while (1) {\n    for (int i = 0; i < 8; i++) {\n\n      printf(COLOR_SEQUENCE[i]);\n\n      if (i &#038; RED_ON) {\n        printf(\"r \");\n        pinMode(METAL_GPIO_22, OUTPUT);\n      } else {\n        printf(\"_ \");\n        pinMode(METAL_GPIO_22, DISABLE);\n      }\n\n      if (i &#038; GREEN_ON) {\n        printf(\"g \");\n        pinMode(METAL_GPIO_19, OUTPUT);\n      } else {\n        printf(\"_ \");\n        pinMode(METAL_GPIO_19, DISABLE);\n      }\n\n      if (i &#038; BLUE_ON) {\n        printf(\"b\\n\");\n        pinMode(METAL_GPIO_21, OUTPUT);\n      } else {\n        printf(\"_\\n\");\n        pinMode(METAL_GPIO_21, DISABLE);\n      }\n      delay(1);\n    }\n  }\n<\/pre>\n<p>Recall the GPIO pins that map to the on-board LEDs are:<\/p>\n<ul>\n<li>Red   - GPIO_22<\/li>\n<li>Green - GPIO_19<\/li>\n<li>Blue  - GPIO_21 <\/li>\n<\/ul>\n<p>We iterate from 0 to 7 in a loop, test the bits, and set the pins as outputs (since we're using the onboard LEDs) or disable them.  The result is a nice rainbow light show from the HiFive1.  If you connect to the serial port you'll also see the colors being printed out as they are cycled through:<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2020\/05\/rainbow.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2020\/05\/rainbow.png\" alt=\"\" width=\"187\" height=\"400\" class=\"aligncenter size-full wp-image-4057\" \/><\/a><\/p>\n<h3>Lagniappe<\/h3>\n<p>The code that's actually uploaded to GitHub includes stepping through the binary representation of our LED rainbow and displaying that if you hook up a few LEDs to your breadboard.  Check out the code and look closely here at header pins 2, 4, and 7.<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2020\/05\/lagniappe.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2020\/05\/lagniappe.png\" alt=\"\" width=\"772\" height=\"612\" class=\"aligncenter size-full wp-image-4067\" \/><\/a><\/p>\n<h2>Closing Thoughts and What's Next<\/h2>\n<p>Nothing is more fun than working with microcontrollers and embedded systems, and the HiFive1 is no exception.  If you take a look at <a href=\"https:\/\/github.com\/iachievedit\/hifive1-ledcolors\/blob\/master\/gpios.h\">gpios.h<\/a> in GitHub you can see that I'm looking as to how to best add additional <code>#define<\/code>s for the various pins.  We will see.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Let&#8217;s make use of the HiFive1 Rev B schematics to map out the GPIO controller device pins. Of particular interest is sheet 3, and the following components of the schematic in section D1: We&#8217;re going to use this as our starting point. Three GPIO lines labeled 19, 21, and 22 with LEDs on the lines. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":4064,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22,102,101],"tags":[],"class_list":["post-4042","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-hacking","category-hifive","category-risc-v"],"_links":{"self":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/4042"}],"collection":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/comments?post=4042"}],"version-history":[{"count":18,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/4042\/revisions"}],"predecessor-version":[{"id":4069,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/4042\/revisions\/4069"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/media\/4064"}],"wp:attachment":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/media?parent=4042"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/categories?post=4042"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/tags?post=4042"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}