<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[[Onion Omega2] Direct GPIO register access problem]]></title><description><![CDATA[<p dir="auto">Hello everyone.<br />
I have some problems with my Onion. I'm trying to access device registers via mmap function. I've successfully map PWM registers  (address: 0x10005000). I can write and read from these registers.<br />
But when I try to change address to 0x10000600 (GPIO access registers) with the same code I can read, but write fails with message Segmentation fault.<br />
I tried to unload all GPIO modules with no effect.<br />
Here is my code (without headers):</p>
<p dir="auto">int main(int argc, char *argv[])<br />
{</p>
<pre><code>uint32_t alloc_mem_size, page_mask, page_size;
volatile uint32_t *mem_pointer, *virt_addr;
const uint32_t mem_address = 0x10000600;
const uint32_t mem_size = 0x600;
page_size = 4096;

alloc_mem_size = (((mem_size / page_size) + 1) * page_size);
page_mask = (page_size - 1);

int mem_dev = open("/dev/mem", O_RDWR | O_SYNC);
mem_pointer = mmap(NULL,
               alloc_mem_size,
               PROT_READ | PROT_WRITE,
               MAP_SHARED,
               mem_dev,
               (mem_address &amp; ~page_mask)
               );


virt_addr = (mem_pointer + (mem_address &amp; page_mask)); 

int i=0;
close(mem_dev);
printf("Memory dump before\n");
for(i=0; i&lt;10;i=i+2) 
{
	printf("GPIO memory address=0x%016x: 0x%016x\n", virt_addr+i, *(virt_addr+i));
}





// Set GPIO_0 direction bit
 (*(virt_addr))|=(1&lt;&lt;0);

printf("Memory dump after\n");
for(i=0; i&lt;10;i=i+2) 
{
	printf("GPIO memory address=0x%016x: 0x%016x\n", virt_addr+i, *(virt_addr+i));
}
</code></pre>
<p dir="auto">}</p>
<p dir="auto">Help please <img src="http://community.onion.io/plugins/nodebb-plugin-emoji/emoji/android/1f642.png?v=ic093v0mjao" class="not-responsive emoji emoji-android emoji--slightly_smiling_face" title=":)" alt="🙂" /></p>
]]></description><link>http://community.onion.io/topic/2083/onion-omega2-direct-gpio-register-access-problem</link><generator>RSS for Node</generator><lastBuildDate>Sat, 06 Jun 2026 20:09:50 GMT</lastBuildDate><atom:link href="http://community.onion.io/topic/2083.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 27 May 2017 08:08:11 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to [Onion Omega2] Direct GPIO register access problem on Sat, 27 May 2017 08:09:21 GMT]]></title><description><![CDATA[<p dir="auto">Hello everyone.<br />
I have some problems with my Onion. I'm trying to access device registers via mmap function. I've successfully map PWM registers  (address: 0x10005000). I can write and read from these registers.<br />
But when I try to change address to 0x10000600 (GPIO access registers) with the same code I can read, but write fails with message Segmentation fault.<br />
I tried to unload all GPIO modules with no effect.<br />
Here is my code (without headers):</p>
<p dir="auto">int main(int argc, char *argv[])<br />
{</p>
<pre><code>uint32_t alloc_mem_size, page_mask, page_size;
volatile uint32_t *mem_pointer, *virt_addr;
const uint32_t mem_address = 0x10000600;
const uint32_t mem_size = 0x600;
page_size = 4096;

alloc_mem_size = (((mem_size / page_size) + 1) * page_size);
page_mask = (page_size - 1);

int mem_dev = open("/dev/mem", O_RDWR | O_SYNC);
mem_pointer = mmap(NULL,
               alloc_mem_size,
               PROT_READ | PROT_WRITE,
               MAP_SHARED,
               mem_dev,
               (mem_address &amp; ~page_mask)
               );


virt_addr = (mem_pointer + (mem_address &amp; page_mask)); 

int i=0;
close(mem_dev);
printf("Memory dump before\n");
for(i=0; i&lt;10;i=i+2) 
{
	printf("GPIO memory address=0x%016x: 0x%016x\n", virt_addr+i, *(virt_addr+i));
}





// Set GPIO_0 direction bit
 (*(virt_addr))|=(1&lt;&lt;0);

printf("Memory dump after\n");
for(i=0; i&lt;10;i=i+2) 
{
	printf("GPIO memory address=0x%016x: 0x%016x\n", virt_addr+i, *(virt_addr+i));
}
</code></pre>
<p dir="auto">}</p>
<p dir="auto">Help please <img src="http://community.onion.io/plugins/nodebb-plugin-emoji/emoji/android/1f642.png?v=ic093v0mjao" class="not-responsive emoji emoji-android emoji--slightly_smiling_face" title=":)" alt="🙂" /></p>
]]></description><link>http://community.onion.io/post/13247</link><guid isPermaLink="true">http://community.onion.io/post/13247</guid><dc:creator><![CDATA[Krzysztof Skiba]]></dc:creator><pubDate>Sat, 27 May 2017 08:09:21 GMT</pubDate></item><item><title><![CDATA[Reply to [Onion Omega2] Direct GPIO register access problem on Sun, 28 May 2017 14:29:11 GMT]]></title><description><![CDATA[<p dir="auto">Where did you get the 0x10000600 number from?</p>
<p dir="auto">Take a look at my GPIO management code:<br />
<a href="https://github.com/Patryk27/Omega2-GPIO/blob/master/gpio.h" rel="nofollow">https://github.com/Patryk27/Omega2-GPIO/blob/master/gpio.h</a></p>
]]></description><link>http://community.onion.io/post/13265</link><guid isPermaLink="true">http://community.onion.io/post/13265</guid><dc:creator><![CDATA[Patryk Wychowaniec]]></dc:creator><pubDate>Sun, 28 May 2017 14:29:11 GMT</pubDate></item><item><title><![CDATA[Reply to [Onion Omega2] Direct GPIO register access problem on Sun, 28 May 2017 22:15:05 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="http://community.onion.io/uid/3934">@Krzysztof-Skiba</a> said in <a href="/post/13247">[Onion Omega2] Direct GPIO register access problem</a>:</p>
<blockquote>
<p dir="auto">x10000600</p>
</blockquote>
<p dir="auto">I found in Mediatek MT7688 Datasheet page 109:<br />
<a href="https://labs.mediatek.com/en/download/50WkbgbH" rel="nofollow">https://labs.mediatek.com/en/download/50WkbgbH</a></p>
<p dir="auto">"Module name: GPIO Base address: (+10000600h)"</p>
<p dir="auto">Edit: Got it! Seems that datasheet info is incorrect.</p>
<p dir="auto">Thanks for help!</p>
]]></description><link>http://community.onion.io/post/13268</link><guid isPermaLink="true">http://community.onion.io/post/13268</guid><dc:creator><![CDATA[Krzysztof Skiba]]></dc:creator><pubDate>Sun, 28 May 2017 22:15:05 GMT</pubDate></item><item><title><![CDATA[Reply to [Onion Omega2] Direct GPIO register access problem on Mon, 16 Jul 2018 14:40:58 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="http://community.onion.io/uid/3691">@Patryk-Wychowaniec</a>  Hi Patryk , when i look into the datasheet , i see this adress for  GPIO_CTRL_0 32</p>
<p dir="auto">10000600</p>
<p dir="auto">How can you write  your code ? any datasheet?</p>
]]></description><link>http://community.onion.io/post/17253</link><guid isPermaLink="true">http://community.onion.io/post/17253</guid><dc:creator><![CDATA[volkan ünal]]></dc:creator><pubDate>Mon, 16 Jul 2018 14:40:58 GMT</pubDate></item><item><title><![CDATA[Reply to [Onion Omega2] Direct GPIO register access problem on Sun, 05 Aug 2018 18:27:01 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="http://community.onion.io/uid/5730">@volkan-ünal</a></p>
<p dir="auto">Hi!</p>
<p dir="auto">I have already responded you on GitHub, but to keep conversation here complete, I am also copy-pasting that response (<a href="https://github.com/Patryk27/Omega2-GPIO/issues/3" rel="nofollow">https://github.com/Patryk27/Omega2-GPIO/issues/3</a>) here:</p>
<p dir="auto">I initially followed code written by the Omega team (<a href="https://github.com/OnionIoT/fast-gpio/blob/master/include/fastgpioomega2.h#L12" rel="nofollow">https://github.com/OnionIoT/fast-gpio/blob/master/include/fastgpioomega2.h#L12</a>) and I haven't really faced it with the documentation.</p>
<p dir="auto">I believe the reason is that later we're doing a <code>mmap</code> call, which has to be page-aligned (which 0x10000600 is not), but it could be also a mistake in the MT7688's documentation.</p>
]]></description><link>http://community.onion.io/post/17405</link><guid isPermaLink="true">http://community.onion.io/post/17405</guid><dc:creator><![CDATA[Patryk Wychowaniec]]></dc:creator><pubDate>Sun, 05 Aug 2018 18:27:01 GMT</pubDate></item><item><title><![CDATA[Reply to [Onion Omega2] Direct GPIO register access problem on Fri, 23 Nov 2018 17:15:10 GMT]]></title><description><![CDATA[<pre><code>static const int REG_BLOCK_ADDR = 0x10000000;

static const int REGISTER_CTRL0_OFFSET = 384; // 32 bit reg offset !!!
static const int REGISTER_CTRL1_OFFSET = 385; // 32 bit reg offset !!! 
static const int REGISTER_CTRL2_OFFSET = 386; // 32 bit reg offset !!!

static const int REGISTER_DATA0_OFFSET = 392; // 32 bit reg offset !!!
static const int REGISTER_DATA1_OFFSET = 393; // 32 bit reg offset !!!
static const int REGISTER_DATA2_OFFSET = 394; // 32 bit reg offset !!!

static const int REGISTER_DSET0_OFFSET = 396; // 32 bit reg offset !!!
static const int REGISTER_DSET1_OFFSET = 397; // 32 bit reg offset !!!
static const int REGISTER_DSET2_OFFSET = 398; // 32 bit reg offset !!!

static const int REGISTER_DCLR0_OFFSET = 400; // 32 bit reg offset !!!
static const int REGISTER_DCLR1_OFFSET = 401; // 32 bit reg offset !!!
static const int REGISTER_DCLR2_OFFSET = 402; // 32 bit reg offset !!!
</code></pre>
<p dir="auto">and then</p>
<pre><code>Gpio::baseAddress = (uint32_t *) mmap(0, 1024, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, memHandle,
                                      Gpio::REG_BLOCK_ADDR);
</code></pre>
<p dir="auto">and then</p>
<pre><code>void Gpio::writeToRegister(uint16_t registerOffset, uint32_t value) {
*(Gpio::baseAddress + registerOffset) = value;}
</code></pre>
<p dir="auto">you are basically mapping to a 32 bit pointer...<br />
so your offsets are in fact equivalent to the following address:</p>
<p dir="auto"><strong>REGISTER_CTRL0_OFFSET</strong> = 384  (32 bit offset) -&gt; hex(4<em>384) = <strong>0x600</strong><br />
<strong>REGISTER_CTRL1_OFFSET</strong> = 385  (32 bit offset) -&gt; hex(4</em>385) = <strong>0x604</strong><br />
<strong>REGISTER_CTRL2_OFFSET</strong> = 386  (32 bit offset) -&gt; hex(4*386) = <strong>0x608</strong></p>
<p dir="auto">So the documentation is correct...<br />
Be careful with pointer arithmetic...</p>
]]></description><link>http://community.onion.io/post/18270</link><guid isPermaLink="true">http://community.onion.io/post/18270</guid><dc:creator><![CDATA[Alex Costea]]></dc:creator><pubDate>Fri, 23 Nov 2018 17:15:10 GMT</pubDate></item><item><title><![CDATA[Reply to [Onion Omega2] Direct GPIO register access problem on Fri, 23 Nov 2018 17:30:09 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="http://community.onion.io/uid/3934">@Krzysztof-Skiba</a> said in <a href="/post/13247">[Onion Omega2] Direct GPIO register access problem</a>:</p>
<blockquote>
<p dir="auto">virt_addr = (mem_pointer + (mem_address &amp; page_mask));</p>
</blockquote>
<p dir="auto">this is wrong...</p>
<p dir="auto">mem_pointer is already pointing to mem_address...</p>
<p dir="auto">your line basically makes mem_pointer point to address</p>
<blockquote>
<p dir="auto">0x10000600 + (0x10000600*4  &amp; page_mask) = .... SEG FAULT....</p>
</blockquote>
<p dir="auto">To Fix:  change</p>
<blockquote>
<p dir="auto">const uint32_t mem_size = 0x600;</p>
</blockquote>
<p dir="auto">to</p>
<blockquote>
<p dir="auto"><strong>const uint32_t mem_size = 0x600+0xAC;</strong></p>
</blockquote>
<blockquote>
<p dir="auto">const uint32_t mem_address = 0x10000600;</p>
</blockquote>
<p dir="auto">to</p>
<blockquote>
<p dir="auto"><strong>const uint32_t mem_address = 0x10000000;</strong></p>
</blockquote>
<p dir="auto">and</p>
<blockquote>
<p dir="auto">virt_addr = (mem_pointer + (mem_address &amp; page_mask));</p>
</blockquote>
<p dir="auto">to</p>
<blockquote>
<p dir="auto"><strong>virt_addr = (mem_pointer + (mem_size/sizeof(uint32_t) );</strong></p>
</blockquote>
]]></description><link>http://community.onion.io/post/18273</link><guid isPermaLink="true">http://community.onion.io/post/18273</guid><dc:creator><![CDATA[Alex Costea]]></dc:creator><pubDate>Fri, 23 Nov 2018 17:30:09 GMT</pubDate></item><item><title><![CDATA[Reply to [Onion Omega2] Direct GPIO register access problem on Wed, 23 Jan 2019 22:27:54 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="http://community.onion.io/uid/6018">@Alex-Costea</a> Thanks for reply , but i dont understand properly.<br />
you mean that 384 (32 bit offset) -&gt; hex(4384) = 0x600 , but how?</p>
<p dir="auto">What about Gpio::baseAddress + registerOffset?</p>
]]></description><link>http://community.onion.io/post/18732</link><guid isPermaLink="true">http://community.onion.io/post/18732</guid><dc:creator><![CDATA[volkan ünal]]></dc:creator><pubDate>Wed, 23 Jan 2019 22:27:54 GMT</pubDate></item></channel></rss>