<?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: Low Level pin manipulation</title>
		<link>http://forums.leaflabs.com/topic.php?id=860</link>
		<description>A place to share, learn, and grow...</description>
		<language>en-US</language>
		<pubDate>Fri, 22 Jan 2016 00:12:51 +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=860" rel="self" type="application/rss+xml" />

		<item>
			<title>mbolivar on "Low Level pin manipulation"</title>
			<link>http://forums.leaflabs.com/topic.php?id=860#post-5214</link>
			<pubDate>Tue, 14 Jun 2011 15:05:11 +0000</pubDate>
			<dc:creator>mbolivar</dc:creator>
			<guid isPermaLink="false">5214@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;update: done:&#60;br /&#62;
&#60;a href=&#34;https://github.com/leaflabs/leaflabs-docs/commit/fd7edc29d79bbba098fdab621a56205740599a4f&#34; rel=&#34;nofollow&#34;&#62;https://github.com/leaflabs/leaflabs-docs/commit/fd7edc29d79bbba098fdab621a56205740599a4f&#60;/a&#62;&#60;/p&#62;
&#60;p&#62;includes a link to this thread.  i also included a link to thread referenced by robodude666 above, with the very informative conversation between gbulmer, trevden, and robodude666.&#60;/p&#62;
&#60;p&#62;hm.  i wonder what other FAQs should be added in.  perhaps that's a topic for another thread.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>robodude666 on "Low Level pin manipulation"</title>
			<link>http://forums.leaflabs.com/topic.php?id=860#post-5212</link>
			<pubDate>Tue, 14 Jun 2011 14:56:48 +0000</pubDate>
			<dc:creator>robodude666</dc:creator>
			<guid isPermaLink="false">5212@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;I love good puns on a Tuesday afternoon :D.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>mbolivar on "Low Level pin manipulation"</title>
			<link>http://forums.leaflabs.com/topic.php?id=860#post-5211</link>
			<pubDate>Tue, 14 Jun 2011 14:25:26 +0000</pubDate>
			<dc:creator>mbolivar</dc:creator>
			<guid isPermaLink="false">5211@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;i think this should be included in the official docs (which recently moved to &#60;a href=&#34;https://github.com/leaflabs/leaflabs-docs)&#34; rel=&#34;nofollow&#34;&#62;https://github.com/leaflabs/leaflabs-docs)&#60;/a&#62;.  i added an FAQ page to those the other day, and i think i'll fold this information into it.&#60;/p&#62;
&#60;p&#62;thanks to snigelen and robodude666 for all the good bits!
&#60;/p&#62;</description>
		</item>
		<item>
			<title>poslathian on "Low Level pin manipulation"</title>
			<link>http://forums.leaflabs.com/topic.php?id=860#post-5210</link>
			<pubDate>Tue, 14 Jun 2011 13:47:16 +0000</pubDate>
			<dc:creator>poslathian</dc:creator>
			<guid isPermaLink="false">5210@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;So weve re-verified the official max square wave is 36MHz using PWM at 50% duty cycle and 18MHz using direct GPIO writes.  Awesome! Thanks for all the great experiments. Definitely wiki material!
&#60;/p&#62;</description>
		</item>
		<item>
			<title>robodude666 on "Low Level pin manipulation"</title>
			<link>http://forums.leaflabs.com/topic.php?id=860#post-5207</link>
			<pubDate>Tue, 14 Jun 2011 12:45:35 +0000</pubDate>
			<dc:creator>robodude666</dc:creator>
			<guid isPermaLink="false">5207@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Well then, my previous &#60;code&#62;uint16_t bit9 = BIT(9);&#60;/code&#62; statements can be ignored.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>snigelen on "Low Level pin manipulation"</title>
			<link>http://forums.leaflabs.com/topic.php?id=860#post-5206</link>
			<pubDate>Tue, 14 Jun 2011 11:57:30 +0000</pubDate>
			<dc:creator>snigelen</dc:creator>
			<guid isPermaLink="false">5206@http://forums.leaflabs.com/</guid>
			<description>&#60;blockquote&#62;&#60;p&#62;Does the compiler optimize (i.e. pre-calculate) 1&#38;lt;&#38;lt;9 for you? I've never checked.&#60;/p&#62;&#60;/blockquote&#62;
&#60;p&#62;Yes, all expressions that's constant at compile time will be evaluated by the compiler.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>robodude666 on "Low Level pin manipulation"</title>
			<link>http://forums.leaflabs.com/topic.php?id=860#post-5203</link>
			<pubDate>Tue, 14 Jun 2011 11:13:43 +0000</pubDate>
			<dc:creator>robodude666</dc:creator>
			<guid isPermaLink="false">5203@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Does the compiler optimize (i.e. pre-calculate) &#60;code&#62;1&#38;lt;&#38;lt;9&#60;/code&#62; for you? I've never checked.&#60;/p&#62;
&#60;p&#62;While experimenting with this before I noticed very interesting things as well. For example, with the following:&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;GPIOB_BASE-&#38;gt;BSRR = 1&#38;lt;&#38;lt;9;
GPIOB_BASE-&#38;gt;BRR = 1&#38;lt;&#38;lt;9;&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;You'll see the Set occuring very quickly, then the Clear taking twice as long as the set. If you look at this next:&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;GPIOB_BASE-&#38;gt;BSRR = 1&#38;lt;&#38;lt;9;
GPIOB_BASE-&#38;gt;BRR = 1&#38;lt;&#38;lt;9;

GPIOB_BASE-&#38;gt;BSRR = 1&#38;lt;&#38;lt;9;
GPIOB_BASE-&#38;gt;BRR = 1&#38;lt;&#38;lt;9;&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;all four operations take the exact same amount of time (as fast as the BSRR of the previous example).&#60;/p&#62;
&#60;p&#62;However, if you do something like:&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;GPIOA_BASE-&#38;gt;ODR = 0xAA;
GPIOB_BASE-&#38;gt;BSRR = 1&#38;lt;&#38;lt;9;
GPIOB_BASE-&#38;gt;BRR = 1&#38;lt;&#38;lt;9;

GPIOA_BASE-&#38;gt;ODR = 0xAA;
GPIOB_BASE-&#38;gt;BSRR = 1&#38;lt;&#38;lt;9;
GPIOB_BASE-&#38;gt;BRR = 1&#38;lt;&#38;lt;9;&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;we return to the original model: the Set is quick, the clear takes a little longer.&#60;/p&#62;
&#60;p&#62;There is a really great thread on the official ST forums related to performance: &#60;a href=&#34;https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FTrue%20performance%20of%20STM32&#38;amp;FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&#38;amp;currentviews=14129&#34;&#62;True performance of STM32&#60;/a&#62;, as I mentioned in my thread. The most interesting post is &#60;a href=&#34;https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/DispForm.aspx?ID=639&#38;amp;RootFolder=%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fTrue%20performance%20of%20STM32&#38;amp;Source=https%3A%2F%2Fmy%2Est%2Ecom%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FFlat%2Easpx%3FRootFolder%3D%252Fpublic%252FSTe2ecommunities%252Fmcu%252FLists%252Fcortex_mx_stm32%252FTrue%2520performance%2520of%2520STM32%26FolderCTID%3D0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B%26currentviews%3D14129&#34;&#62;this one&#60;/a&#62; by an official ST employee. He writes:&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;The reason is that stores can complete in the background on STM32. This means that the STR
generally takes two cycle or more (depending on what precedes it and depneding on APB
prescalers - wait states). So, if two STRs are back-to-back, then the second one must
wait for the first to complete. If other activity precedes the STR, it will not stall,
as a store buffer will drain the operation out. However this is not the case for Loads ;-(
and Unlike the STR case, the Cortex-M3 has to wait for the load to complete no matter what.
So, back-to-back LDRs (and an LDM) optimize the time by pipelining the address generation.
So, it is better to keep loads together when possible.&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;Quite interesting =].
&#60;/p&#62;</description>
		</item>
		<item>
			<title>snigelen on "Low Level pin manipulation"</title>
			<link>http://forums.leaflabs.com/topic.php?id=860#post-5201</link>
			<pubDate>Tue, 14 Jun 2011 10:41:45 +0000</pubDate>
			<dc:creator>snigelen</dc:creator>
			<guid isPermaLink="false">5201@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;I did some tests while robodude666 answered.&#60;/p&#62;
&#60;p&#62;First test.&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;void setup() {
  pinMode(24, OUTPUT);
}

// 2.57MHz
void loop() {
  GPIOB_BASE-&#38;gt;BSRR = 1&#38;lt;&#38;lt;9;
  GPIOB_BASE-&#38;gt;BRR = 1&#38;lt;&#38;lt;9;
}&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;It's short pulses at about 2.75MHz. Some of the time between pulses seems to be for the call to loop, which surprised me. I thought the compiler optimized that away.&#60;/p&#62;
&#60;p&#62;Test two. Same setup().&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;// 4.26 MHz
void loop() {
  while(1) {
    GPIOB_BASE-&#38;gt;BSRR = 1&#38;lt;&#38;lt;9;
    GPIOB_BASE-&#38;gt;BRR = 1&#38;lt;&#38;lt;9;
  }
}&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;Still pulses. Time between them comes from the loop.&#60;/p&#62;
&#60;p&#62;Test 3.&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;// 4 18 MHz pulses
void loop() {
    GPIOB_BASE-&#38;gt;BSRR = 1&#38;lt;&#38;lt;9;
    GPIOB_BASE-&#38;gt;BRR = 1&#38;lt;&#38;lt;9;
    GPIOB_BASE-&#38;gt;BSRR = 1&#38;lt;&#38;lt;9;
    GPIOB_BASE-&#38;gt;BRR = 1&#38;lt;&#38;lt;9;
    GPIOB_BASE-&#38;gt;BSRR = 1&#38;lt;&#38;lt;9;
    GPIOB_BASE-&#38;gt;BRR = 1&#38;lt;&#38;lt;9;
    GPIOB_BASE-&#38;gt;BSRR = 1&#38;lt;&#38;lt;9;
    GPIOB_BASE-&#38;gt;BRR = 1&#38;lt;&#38;lt;9;
}&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;4 18 MHz pulses with some time between.&#60;/p&#62;
&#60;p&#62;The fastest is to let the hardware take care of it.&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;HardwareTimer timer(4);

void setup() {
  pinMode(24,PWM);
  timer.setPrescaleFactor(1);
  timer.setOverflow(1);
  timer.setMode(4, TIMER_PWM);
  timer.setCompare(4,1);
}

void loop() {
}&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;36 MHz. (which is about the highest I can see with my oscilloscope).
&#60;/p&#62;</description>
		</item>
		<item>
			<title>robodude666 on "Low Level pin manipulation"</title>
			<link>http://forums.leaflabs.com/topic.php?id=860#post-5188</link>
			<pubDate>Tue, 14 Jun 2011 09:57:11 +0000</pubDate>
			<dc:creator>robodude666</dc:creator>
			<guid isPermaLink="false">5188@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;There sure is! The STM32 is capable of ~18MHz GPIO toggle speeds. Check out my &#60;a href=&#34;http://forums.leaflabs.com/topic.php?id=774&#34;&#62;&#34;High-Speed GPIO Access?&#34;&#60;/a&#62; thread where we discuss it in much more detail. The short answer would be:&#60;/p&#62;
&#60;p&#62;Access the GPIO's registers directly instead of going through the overhead created by the &#60;code&#62;digitalWrite&#60;/code&#62; function:&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;// D24 corresponds to PB9.

uint16_t bit9 = BIT(9);

GPIOB-&#38;gt;regs-&#38;gt;BSRR = bit9; // Set PB9
GPIOB-&#38;gt;regs-&#38;gt;BRR = bit9; // Clear PB9&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;It may be difficult to memorize the registers so libmaple has a built in lower-level gpio function:&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;gpio_write_bit(GPIOB, 9, 1); // Set PB9
gpio_write_bit(GPIOB, 9, 0); // Clear PB9&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;The only overhead of the &#60;code&#62;gpio_write_bit&#60;/code&#62; function is a single if-statement and a &#60;code&#62;BIT&#60;/code&#62; calculation. I created the following macros for my needs to remove the if-statement overhead:&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;#define sbit(port, pin) port-&#38;gt;regs-&#38;gt;BSRR = BIT(pin)
#define cbit(port, pin) port-&#38;gt;regs-&#38;gt;BRR = BIT(pin)&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;You can remove the &#60;code&#62;BIT&#60;/code&#62;.. bit, and pre-calculate the values ahead of time for slightly better performance.&#60;/p&#62;
&#60;p&#62;Note that you won't get 18MHz out of the GPIO, but get very close to it. There are some quirks related to how fast you can toggle. If you do two GPIO accesses in a row you'll get lower performance than just doing a single one.. and a bunch of other little things. If you need to get faster performance you can unroll loops:&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;uint16_t bit9 = BIT(9);

for(int i = 0; i &#38;lt; 4; i++)
{
	GPIOB-&#38;gt;regs-&#38;gt;BSRR = bit9; // Set PB9
	GPIOB-&#38;gt;regs-&#38;gt;BRR = bit9; // Clear PB9
}&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;can be written as:&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;uint16_t bit9 = BIT(9);

GPIOB-&#38;gt;regs-&#38;gt;BSRR = bit9; // Set PB9
GPIOB-&#38;gt;regs-&#38;gt;BRR = bit9; // Clear PB9

GPIOB-&#38;gt;regs-&#38;gt;BSRR = bit9; // Set PB9
GPIOB-&#38;gt;regs-&#38;gt;BRR = bit9; // Clear PB9

GPIOB-&#38;gt;regs-&#38;gt;BSRR = bit9; // Set PB9
GPIOB-&#38;gt;regs-&#38;gt;BRR = bit9; // Clear PB9

GPIOB-&#38;gt;regs-&#38;gt;BSRR = bit9; // Set PB9
GPIOB-&#38;gt;regs-&#38;gt;BRR = bit9; // Clear PB9&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;removing the small &#34;overhead&#34; of executing the for-loop.&#60;/p&#62;
&#60;p&#62;-robodude666
&#60;/p&#62;</description>
		</item>
		<item>
			<title>TRC on "Low Level pin manipulation"</title>
			<link>http://forums.leaflabs.com/topic.php?id=860#post-5187</link>
			<pubDate>Tue, 14 Jun 2011 09:23:26 +0000</pubDate>
			<dc:creator>TRC</dc:creator>
			<guid isPermaLink="false">5187@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Hello all, I'm a new Maple R5 user with some Arduino experience.&#60;br /&#62;
I was wondering if it is possible to do direct pin manipulation in the Maple ide.&#60;br /&#62;
I tried an simple code to see how fast I could get a pulse going:&#60;br /&#62;
-----------------------------------------&#60;br /&#62;
void setup() {&#60;br /&#62;
  pinMode (24, OUTPUT);&#60;br /&#62;
}&#60;br /&#62;
void loop() {&#60;br /&#62;
  digitalWrite(24, HIGH);&#60;br /&#62;
  digitalWrite(24, LOW);&#60;br /&#62;
}&#60;br /&#62;
-----------------------------------------&#60;/p&#62;
&#60;p&#62;This gave me a 713KHZ signal.&#60;br /&#62;
Now this is already much faster than Arduino. But there is a custom Arduino library which adds the &#34;digitalWriteFast&#34; and &#34;digitalReadFast&#34; functionality. And on the Ardunio this gives me a 2.2MHZ signal. Now I wonder if such a thing is also possible for Maple. Or at least the possibility for custom direct port manipulation within the Maple ide.&#60;/p&#62;
&#60;p&#62;Thanks in advance!&#60;br /&#62;
TRC
&#60;/p&#62;</description>
		</item>

	</channel>
</rss>
