<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="bbPress/1.0.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>LeafLabs Garden &#187; Topic: Maple equivalent for Arduino PORT registers</title>
		<link>http://forums.leaflabs.com/topic.php?id=1206</link>
		<description>A place to share, learn, and grow...</description>
		<language>en-US</language>
		<pubDate>Fri, 22 Jan 2016 00:15:16 +0000</pubDate>
		<generator>http://bbpress.org/?v=1.0.2</generator>
		<textInput>
			<title><![CDATA[Search]]></title>
			<description><![CDATA[Search all topics from these forums.]]></description>
			<name>q</name>
			<link>http://forums.leaflabs.com/search.php</link>
		</textInput>
		<atom:link href="http://forums.leaflabs.com/rss.php?topic=1206" rel="self" type="application/rss+xml" />

		<item>
			<title>tlgosser on "Maple equivalent for Arduino PORT registers"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1206#post-11387</link>
			<pubDate>Tue, 26 Jun 2012 16:40:58 +0000</pubDate>
			<dc:creator>tlgosser</dc:creator>
			<guid isPermaLink="false">11387@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;/*If anyone is still interested you could tailor the code in this table to engage multiple pins per port at once.  I wrote it just to help me keep things straight.&#60;/p&#62;
&#60;p&#62;Blink - substitution for digitalWrite using BSRR and array table.&#60;br /&#62;
Works for all io pins on the Leaf Maple. Approx 3x faster than digitalWrite.&#60;br /&#62;
You must manually specify GPIOA,GPIOB,or GPIOC (listed as 0,1,or 2 in last column for convenience).&#60;br /&#62;
*/&#60;/p&#62;
&#60;p&#62;#include &#38;lt;gpio.h&#38;gt;&#60;/p&#62;
&#60;p&#62;const int digtalWriteFast[44][3] = {&#60;br /&#62;
{0b00000000000010000000000000000000,0b0000000000001000,0},&#60;br /&#62;
{0b00000000000001000000000000000000,0b0000000000000100,0},&#60;br /&#62;
{0b00000000000000010000000000000000,0b0000000000000001,0},&#60;br /&#62;
{0b00000000000000100000000000000000,0b0000000000000010,0},&#60;br /&#62;
{0b00000000001000000000000000000000,0b0000000000100000,1},&#60;br /&#62;
{0b00000000010000000000000000000000,0b0000000001000000,1},&#60;br /&#62;
{0b00000001000000000000000000000000,0b0000000100000000,0},&#60;br /&#62;
{0b00000010000000000000000000000000,0b0000001000000000,0},&#60;br /&#62;
{0b00000100000000000000000000000000,0b0000010000000000,0},&#60;br /&#62;
{0b00000000100000000000000000000000,0b0000000010000000,1},&#60;br /&#62;
{0b00000000000100000000000000000000,0b0000000000010000,0},&#60;br /&#62;
{0b00000000100000000000000000000000,0b0000000010000000,0},&#60;br /&#62;
{0b00000000010000000000000000000000,0b0000000001000000,0},&#60;br /&#62;
{0b00000000001000000000000000000000,0b0000000000100000,0},&#60;br /&#62;
{0b00000001000000000000000000000000,0b0000000100000000,1},&#60;br /&#62;
{0b00000000000000010000000000000000,0b0000000000000001,2},&#60;/p&#62;
&#60;p&#62;{0b00000000000000100000000000000000,0b0000000000000010,2},&#60;br /&#62;
{0b00000000000001000000000000000000,0b0000000000000100,2},&#60;br /&#62;
{0b00000000000010000000000000000000,0b0000000000001000,2},&#60;br /&#62;
{0b00000000000100000000000000000000,0b0000000000010000,2},&#60;br /&#62;
{0b00000000001000000000000000000000,0b0000000000100000,2},&#60;br /&#62;
{0b00100000000000000000000000000000,0b0010000000000000,2},&#60;br /&#62;
{0b01000000000000000000000000000000,0b0100000000000000,2},&#60;br /&#62;
{0b10000000000000000000000000000000,0b1000000000000000,2},&#60;br /&#62;
{-1,-1,-1},&#60;br /&#62;
{-1,-1,-1},&#60;br /&#62;
{0b00000100000000000000000000000000,0b0000010000000000,2},&#60;br /&#62;
{0b00000000000000010000000000000000,0b0000000000000001,1},&#60;br /&#62;
{0b00000000000000100000000000000000,0b0000000000000010,1},&#60;br /&#62;
{0b00000100000000000000000000000000,0b0000010000000000,1},&#60;br /&#62;
{0b00001000000000000000000000000000,0b0000100000000000,1},&#60;br /&#62;
{0b00010000000000000000000000000000,0b0001000000000000,1},&#60;/p&#62;
&#60;p&#62;{0b00100000000000000000000000000000,0b0010000000000000,1},&#60;br /&#62;
{0b01000000000000000000000000000000,0b0100000000000000,1},&#60;br /&#62;
{0b10000000000000000000000000000000,0b1000000000000000,1},&#60;br /&#62;
{0b00000000010000000000000000000000,0b0000000001000000,2},&#60;br /&#62;
{0b00000000100000000000000000000000,0b0000000010000000,2},&#60;br /&#62;
{0b00000001000000000000000000000000,0b0000000100000000,2},&#60;br /&#62;
{0b00000010000000000000000000000000,0b0000001000000000,2},&#60;br /&#62;
{-1,-1,-1},&#60;br /&#62;
{0b01000000000000000000000000000000,0b0100000000000000,0},&#60;br /&#62;
{0b10000000000000000000000000000000,0b1000000000000000,0},&#60;br /&#62;
{0b00000000000010000000000000000000,0b0000000000001000,1},&#60;br /&#62;
{0b00000000000100000000000000000000,0b0000000000010000,1}&#60;br /&#62;
};&#60;/p&#62;
&#60;p&#62;void setup() {&#60;br /&#62;
// Set up the built-in LED pin as an output:&#60;br /&#62;
pinMode(13, OUTPUT);&#60;br /&#62;
}&#60;/p&#62;
&#60;p&#62;void loop() {&#60;br /&#62;
(GPIOA_BASE)-&#38;gt;BSRR = digtalWriteFast[13][1]; // sets pin 13, and ignores the other bits in the port&#60;br /&#62;
delay(1000); // Wait for 1 second (1000 milliseconds)&#60;br /&#62;
(GPIOA_BASE)-&#38;gt;BSRR = digtalWriteFast[13][0]; // clears pin 13, and ignores the other bits in the port&#60;br /&#62;
delay(1000); // Wait for 1 second (1000 milliseconds)&#60;br /&#62;
}
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "Maple equivalent for Arduino PORT registers"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1206#post-7397</link>
			<pubDate>Mon, 19 Dec 2011 13:17:13 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">7397@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;poslathian -&#60;/p&#62;
&#60;blockquote&#62;&#60;p&#62;... I am generally weary of using sizeof because struct packing makes some objects different sizes than youd expect. ...&#60;/p&#62;
&#60;/blockquote&#62;
&#60;p&#62;Would you give a concrete example?&#60;/p&#62;
&#60;p&#62;I believe &#60;code&#62;sizeof(struct anything)&#60;/code&#62; (or sizeof(any arbitrary object)) will &#60;strong&#62;always&#60;/strong&#62; give correct results, though that value might not be the same as adding up the size of individual fields, e.g. sizeof(field 1)+...+sizeof(fieldN), depending on memory layout, e.g. struct packing.&#60;/p&#62;
&#60;p&#62;Are you thinking of that example vs&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;struct foo {unit16 v16, uint32 v32; uint8 v8; };
struct foo a[8] = { ... };&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;where the size of the fields of struct foo might appear to be 7 bytes, but some versions of ARM CPU would require that struct to be 12 bytes because they only implemented access to 4-byte aligned values?
&#60;/p&#62;</description>
		</item>
		<item>
			<title>poslathian on "Maple equivalent for Arduino PORT registers"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1206#post-7365</link>
			<pubDate>Fri, 16 Dec 2011 17:20:58 +0000</pubDate>
			<dc:creator>poslathian</dc:creator>
			<guid isPermaLink="false">7365@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;oops, yea the code I had written was wrong. Fixed now. &#60;/p&#62;
&#60;p&#62;Using sizeof is a good idea. I am generally weary of using sizeof because struct packing makes some objects different sizes than youd expect. But here its fine.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "Maple equivalent for Arduino PORT registers"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1206#post-7329</link>
			<pubDate>Mon, 12 Dec 2011 22:23:26 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">7329@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;poslathian - I'd suggest this might be tidier, more robust (and might work:-):&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;void init_output_pins(uint8 pins[], int num_pins) {
    for (int i=0; i&#38;lt;num_pins; i++) { pinMode(pins[i], OUTPUT); }
}

void setup() {
    uint8 my_pins[] = {12,15,16,20};
    init_output_pins(my_pins, sizeof(my_pins)/sizeof(typeof(my_pins)));
}&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;(Warning: I haven't tested his code)
&#60;/p&#62;</description>
		</item>
		<item>
			<title>poslathian on "Maple equivalent for Arduino PORT registers"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1206#post-7318</link>
			<pubDate>Mon, 12 Dec 2011 18:51:18 +0000</pubDate>
			<dc:creator>poslathian</dc:creator>
			<guid isPermaLink="false">7318@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;you might also use the libmaple gpio module (see &#60;a href=&#34;https://github.com/leaflabs/libmaple/blob/master/libmaple/gpio.h)&#34; rel=&#34;nofollow&#34;&#62;https://github.com/leaflabs/libmaple/blob/master/libmaple/gpio.h)&#60;/a&#62; although even that activates only one pin at a time. Unless you have a strong need to configure gpio pin modes in a single write, then it might be easier to just write a quick function, perhaps like:&#60;/p&#62;
&#60;p&#62;`&#60;br /&#62;
void init_pins(uint8* pins, uint8 num_pins) {&#60;br /&#62;
    int i;&#60;br /&#62;
    for (i=0;i&#38;lt;num_pins,i++) { pinMode(pins[i],OUTPUT);}&#60;br /&#62;
}&#60;/p&#62;
&#60;p&#62;void setup() {&#60;br /&#62;
    uint8 my_pins[4] = {12,15,16,20};&#60;br /&#62;
    init_pins(my_pins, 4);&#60;br /&#62;
}&#60;/p&#62;
&#60;p&#62;EDIT: the init_pins call was wrong, now fixed. Thanks gbulmer!
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "Maple equivalent for Arduino PORT registers"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1206#post-7295</link>
			<pubDate>Fri, 09 Dec 2011 12:38:24 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">7295@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;mcstellar - there are a few useful threads in the forum as well as the one you found:&#60;/p&#62;
&#60;p&#62;&#60;a href=&#34;http://forums.leaflabs.com/topic.php?id=1184#post-7237&#34; rel=&#34;nofollow&#34;&#62;http://forums.leaflabs.com/topic.php?id=1184#post-7237&#60;/a&#62;&#60;br /&#62;
&#60;a href=&#34;http://forums.leaflabs.com/topic.php?id=1071&#34; rel=&#34;nofollow&#34;&#62;http://forums.leaflabs.com/topic.php?id=1071&#60;/a&#62;&#60;br /&#62;
&#60;a href=&#34;http://forums.leaflabs.com/topic.php?id=1133&#34; rel=&#34;nofollow&#34;&#62;http://forums.leaflabs.com/topic.php?id=1133&#60;/a&#62;&#60;br /&#62;
&#60;a href=&#34;http://forums.leaflabs.com/topic.php?id=226&#34; rel=&#34;nofollow&#34;&#62;http://forums.leaflabs.com/topic.php?id=226&#60;/a&#62;&#60;/p&#62;
&#60;p&#62;There are several different approaches to using the General Purpose Input/Output (GPIO) pins.&#60;br /&#62;
digitalRead() and digitalWrite() are the simplest to use because the pin numbers printed on the Maple are the same numbers to use when calling those functions.&#60;/p&#62;
&#60;p&#62;An STM32F GPIO port has more functionality than an Arduino (ATmega) GPIO Port.&#60;br /&#62;
The ports are defined in &#34;loving detail&#34; in the ST Micro manual RM0008:&#60;br /&#62;
&#60;a href=&#34;http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf&#34; rel=&#34;nofollow&#34;&#62;http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf&#60;/a&#62;&#60;br /&#62;
In section 9.1 &#34;GPIO functional description&#34;&#60;/p&#62;
&#60;p&#62;Every STM32F GPIO port is 16 pins wide, though in some STM32F packages, not all of the pins are actually available on the external connections to the package.&#60;/p&#62;
&#60;p&#62;If you are intent on speed, then there two fundamental approaches. &#60;/p&#62;
&#60;p&#62;When a single GPIO pin is to be manipulated, then use 'Bit Banding' addresses. The principle is some of the hardware performs a 'trick' to give every pin a unique address so that it can be read or changed without effecting neighbouring pins in the same port. This has no speed cost, it all happens invisibly.&#60;/p&#62;
&#60;p&#62;When using multiple pins (which you seem to be describing), the fastest technique uses the ports registers.&#60;/p&#62;
&#60;p&#62;Each port has a set of associated registers which are at specific memory addresses. The RM0008 manual uses a unique name for every port register, but LeafLabs have chosen to define a C struct to map onto a ports registers (already done in maple header files).&#60;br /&#62;
Each port has a predefined base memory address name, e.g. GPIOA_BASE, GPIOB_BASE, GPIOC_BASE, etc.&#60;br /&#62;
Then the registers' struct names are offsets within a port, e.g. GPIOB_BASE-&#38;gt;ODR, GPIOB_BASE-&#38;gt;BSRR, GPIOB_BASE-&#38;gt;BRR, etc.&#60;br /&#62;
(To help read RM0008, these would be called GPIOB_ODR, GPIOB_BSRR, GPIOB_BRR, but are exactly the same addresses.)&#60;/p&#62;
&#60;p&#62;If all of the pins you want to use for output are on the same port, and no other pins on the same port are used, then&#60;br /&#62;
&#60;code&#62;GPIOB_BASE-&#38;gt;ODR = 0b0011000100001110;&#60;/code&#62;&#60;br /&#62;
would do. BUT this effects every GPIO pin in the port, all 16 will be given a value, and so might not be what you need.&#60;/p&#62;
&#60;p&#62;If all you need to do is clear a subset of the pins in the port to 0, then&#60;br /&#62;
&#60;code&#62;GPIOB_BASE-&#38;gt;BRR = 0b0100010000001111;&#60;/code&#62;&#60;br /&#62;
will only effect the pins with 1 in that bit position, by setting the pin to 0, and none of the other pins will be effected.&#60;/p&#62;
&#60;p&#62;Then as mikep has written, the BSRR register supports setting and clearing (ARM say reset) a subset of the pins atomically (in one instruction) in a port, without effecting other pins.&#60;br /&#62;
Let us assume the pins used are the central 8 in Port C, so the mask would be 0b0000111111110000.&#60;br /&#62;
The BSRR register has 32 active bits; bits set in the bottom 16 places set a subset of pins to 1, and bits set in the upper 16 bits clear (reset) the pins to 0. So you'll see expressions like&#60;br /&#62;
&#60;code&#62;GPIOC_BASE-&#38;gt;BSRR = (zerobits &#38;lt;&#38;lt; 16) &#124; (onebits);&#60;/code&#62;&#60;br /&#62;
There is an extra rule to using BSRR. If the corresponding pin position is 1 in the top and bottom 16 bits, the pin is set to 1.&#60;br /&#62;
So BSRR could always be set (in this example) using:&#60;br /&#62;
&#60;code&#62;GPIOC_BASE-&#38;gt;BSRR = (0b0000111111110000 &#38;lt;&#38;lt; 16) &#124; (onebits);&#60;/code&#62;&#60;br /&#62;
(The compiler should do something smart with &#60;code&#62;(0b0000111111110000 &#38;lt;&#38;lt; 16)&#60;/code&#62;, so it shouldn't cost anything, and reminds me that the top 16 bits are being manipulated more clearly than using the equivalent &#60;code&#62;0b00001111111100000000000000000000&#60;/code&#62;.)&#60;/p&#62;
&#60;p&#62;I'd likely want to wrap the specific expressions needed in macros or functions.&#60;br /&#62;
If the bits were a nice simple pattern, it might be as easy as:&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;inline void setMyPortBits(uint16 onebits) {
    GPIOC_BASE-&#38;gt;BSRR = (0b0000111111110000 &#38;lt;&#38;lt; 16) &#124; (onebits &#38;lt;&#38;lt; 4);
}&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;(WARNING: I have not compiled or tested any of the code)&#60;br /&#62;
(Full disclosure: I am not a member of LeafLabs staff)
&#60;/p&#62;</description>
		</item>
		<item>
			<title>mikep on "Maple equivalent for Arduino PORT registers"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1206#post-7286</link>
			<pubDate>Thu, 08 Dec 2011 13:19:06 +0000</pubDate>
			<dc:creator>mikep</dc:creator>
			<guid isPermaLink="false">7286@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;It seems setting the appropriate BSRR register would be suitable for what you are trying to do. I think the post you mentioned (&#60;a href=&#34;http://forums.leaflabs.com/topic.php?id=737#post-4338&#34; rel=&#34;nofollow&#34;&#62;http://forums.leaflabs.com/topic.php?id=737#post-4338&#60;/a&#62;) is the right way to do this if all of the pins are on the same port.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>mcstellar on "Maple equivalent for Arduino PORT registers"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1206#post-7284</link>
			<pubDate>Thu, 08 Dec 2011 00:27:58 +0000</pubDate>
			<dc:creator>mcstellar</dc:creator>
			<guid isPermaLink="false">7284@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;I've read this post from 7 months ago in the forum regarding PORT registers on the Maple: &#60;/p&#62;
&#60;p&#62;&#60;a href=&#34;http://forums.leaflabs.com/topic.php?id=737#post-4337&#34; rel=&#34;nofollow&#34;&#62;http://forums.leaflabs.com/topic.php?id=737#post-4337&#60;/a&#62;&#60;/p&#62;
&#60;p&#62;I am trying to set multiple pins at the same time.  For example, I use the Arduino code to set all the PORTD pins to 0 simultaneously:&#60;/p&#62;
&#60;p&#62;PORTD = B00000000;&#60;/p&#62;
&#60;p&#62;Is the method described in the above forum post still the recommended method of doing this or is there a better way these days?  I'll be doing this to 30+ pins on the board, so it would seem using digitalWrite() on a pin by pin basis would have a lot of overhead.  &#60;/p&#62;
&#60;p&#62;Thanks!
&#60;/p&#62;</description>
		</item>

	</channel>
</rss>
