{"id":7996,"date":"2016-09-05T10:34:37","date_gmt":"2016-09-05T09:34:37","guid":{"rendered":"https:\/\/blogs.mentor.com\/colinwalls\/?p=7996"},"modified":"2016-09-05T10:34:37","modified_gmt":"2016-09-05T09:34:37","slug":"bitwise-operations-on-device-registers","status":"publish","type":"post","link":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/2016\/09\/05\/bitwise-operations-on-device-registers\/","title":{"rendered":"Bitwise operations on device registers"},"content":{"rendered":"<p>A lot of embedded software is focused on the control of peripheral devices and this can present some interesting challenges. In particular, the developer must be quite comfortable \u201cbit bashing\u201d &#8211; i.e. manipulating individual bits or groups of bits within a register &#8230;<!--more--><\/p>\n<p>The first aspect of device programming that needs to be considered is working at the bit level &#8211; and that entails working in binary. As the C language does not directly support binary notation &#8211; I wrote about a way around this <a href=\"https:\/\/blogs.mentor.com\/colinwalls\/blog\/2009\/06\/08\/there-are-10-kinds-of-people-in-the-world\/\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a> &#8211; most programmers use hexadecimal. This is quite straightforward and it just takes practice to see the binary values represented by hex numbers.<\/p>\n<p>For the purposes of this discussion, I am going to consider an 8-bit port, where only the least significant 3 bits are used [any values set in the top 5 bits are ignored]. So the only meaningful values are 0 to 7.<\/p>\n<p><a href=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/51\/2016\/09\/Screen-Shot-2016-09-05-at-10.24.26.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-7997\" src=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/51\/2016\/09\/Screen-Shot-2016-09-05-at-10.24.26-520x69.png\" alt=\"Screen Shot 2016-09-05 at 10.24.26\" width=\"520\" height=\"69\" \/><\/a><\/p>\n<p>Most programmers, when learning C, encounter bit fields and, not unreasonably, conclude that they are the optimal way to manipulate bitwise data &#8211; single bits and groups. However, this is not a valid conclusion. For internal data structures, bit fields are a perfectly reasonable way to manipulate data. However, their implementation is entirely compiler dependent. This means that there is no guarantee that they will map on to a device register in the expected manner. If you use them and your code works OK, that is fine, but bear in mind that your code is entirely non-portable and even a compiler update might break it.<\/p>\n<p>The only reliable way to work with the bits in a register is to use the OR and AND operators: <strong>|<\/strong> and <strong>&amp;<\/strong>. In simple terms, you use OR to set one or more bits, without affecting the others, and you use AND [with the ones-complement &#8211; the inverse &#8211; of the bit pattern] to similarly clear bits. Here are some simple examples:<\/p>\n<pre>device_reg = device_reg | 0x01;    \/\/ set bit 0\ndevice_reg = device_reg &amp; ~0x06;   \/\/ clear bits 1 and 2\n<br>\n<\/pre>\n<p>I would probably use the compound assignment operators and write the code like this:<\/p>\n<pre>device_reg |= 0x01;    \/\/ set bit 0\ndevice_reg &amp;= ~0x06;   \/\/ clear bits 1 and 2\n<br>\n<\/pre>\n<p>but it amounts to the same thing &#8211; just a matter of style.<\/p>\n<p>If you want to toggle\/flip a bit, the XOR operator in C is <strong>^<\/strong> which works in the same way.<\/p>\n<p>An additional challenge with some device registers are \u201cwrite-only\u201d. In other words, unlike a normal memory cell, you can write a value into the register, but it is not possible to read it back. As the code shown above entails read\/modify\/write sequence, such write-only ports would be problematic. It is only a matter of coding and I have written on this matter in detail <a href=\"https:\/\/blogs.mentor.com\/colinwalls\/blog\/2013\/01\/14\/write-only-ports\/\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>, <a href=\"https:\/\/blogs.mentor.com\/colinwalls\/blog\/2013\/01\/28\/write-only-ports-in-c\/\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a> and <a href=\"https:\/\/blogs.mentor.com\/colinwalls\/blog\/2013\/02\/11\/reentrant-write-only-ports\/\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/p>\n<p><a href=\"http:\/\/www.linkedin.com\/in\/colinwalls\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-6579\" src=\"http:\/\/s3-blogs.mentor.com\/colinwalls\/files\/2014\/01\/linkedin.png\" alt=\"\" width=\"40\" height=\"40\" \/><\/a><a href=\"https:\/\/twitter.com\/colin_walls\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-6583\" src=\"http:\/\/s3-blogs.mentor.com\/colinwalls\/files\/2014\/01\/twitter.png\" alt=\"\" width=\"40\" height=\"40\" \/><\/a><a href=\"https:\/\/www.facebook.com\/colinwalls.author\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-6591\" src=\"http:\/\/s3-blogs.mentor.com\/colinwalls\/files\/2014\/01\/facebook.png\" alt=\"\" width=\"40\" height=\"40\" \/><\/a><a href=\"https:\/\/plus.google.com\/116301748426290440139\/posts?hl=en%3Fhl=en\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-6587\" src=\"http:\/\/s3-blogs.mentor.com\/colinwalls\/files\/2014\/01\/google.png\" alt=\"\" width=\"40\" height=\"40\" \/><\/a><a href=\"http:\/\/www.slideshare.net\/ColinWalls\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-6595\" src=\"http:\/\/s3-blogs.mentor.com\/colinwalls\/files\/2014\/01\/slideshare.jpg\" alt=\"\" width=\"41\" height=\"41\" \/><\/a><a href=\"http:\/\/blogs.mentor.com\/colinwalls\/\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-6599\" src=\"http:\/\/s3-blogs.mentor.com\/colinwalls\/files\/2014\/01\/wordpress.jpg\" alt=\"\" width=\"44\" height=\"44\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A lot of embedded software is focused on the control of peripheral devices and this can present some interesting challenges&#8230;.<\/p>\n","protected":false},"author":71677,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spanish_translation":"","french_translation":"","german_translation":"","italian_translation":"","polish_translation":"","japanese_translation":"","chinese_translation":"","footnotes":""},"categories":[1],"tags":[647,313,339,300,478],"industry":[],"product":[],"coauthors":[],"class_list":["post-7996","post","type-post","status-publish","format-standard","hentry","category-news","tag-bitwise-operations","tag-c","tag-development-tools","tag-embedded-software","tag-sourcery-codebench"],"_links":{"self":[{"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/posts\/7996","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/users\/71677"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/comments?post=7996"}],"version-history":[{"count":0,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/posts\/7996\/revisions"}],"wp:attachment":[{"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/media?parent=7996"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/categories?post=7996"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/tags?post=7996"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/industry?post=7996"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/product?post=7996"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/coauthors?post=7996"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}