0
\$\begingroup\$

I had a little confusing regarding the address of GPIO_PortA As mentioned in datasheet:

  • Based address of GPIO PortA:0x40004000
  • and GIOP_DATA has Offset : 0x000
  • which mean the address of GPIO_PortA = 0x40004000;

Problem starts from here:

  • why this code is not working as expected: (Using datasheet addresses)

#define porta_data (*(volatile unsigned long*)0x40004000) ... while(1) { porta_data=~porta_data }

  • and why this code is working with wrong address (saw during edX online lec)

#define porta_data (*(volatile unsigned long*)0x400043fc) ... while(1) { porta_data=~porta_data }

  • there is another problem.
  • when I use bit binding method and use the formula.

bit_word_addr = bit_band_base + (byte_offset * 32) + (bit_number * 4)

As:

#define bit_word_addr (0x40004000+(0x0000*32)+(1*4+4))
#define porta_pin0 (*(volatile unsigned long*)bit_word_addr)
  • using the base address and offset as mentioned in datasheet
  • I could toggle the individual bit as expected.
  • But using the same address I couldn't toggle the whole port (GPIO_PORTA).
\$\endgroup\$
1
\$\begingroup\$

For your first question, check out page 227 and Section 7.2.12 in the datasheet for the part. I think that might explain the behavior you are seeing -- it's not a straightforward data register you can read/write to.

You'll note that the GPIODATA space is 0x400, or 2^10 sized. Seems overkill to just work with 8 bits, right? For writes to this register, bits 9 through 2 are used as a bitmask. So when you tried to address 0x40004000, your bitmask was all zeros, preventing you from modifying any part of the register. The lower two bits are the "real" address that gives you access to the 8-bits of GPIO you actually have.

So, if you always wanted to edit the entire register at once, your address range would be 0x400043FC through 0x400043FF. That sets bits 9 through 2 to 1, allowing writes to all bits of the register. This is a powerful capability that prevents you from having to do manual bitmasking / read-modify-write operations. This is why the edX course example code works as they use a memory address that enables writing to each bit.

As for your second question, should you not be using the bit-band alias region starting at 0x42000000 instead of the direct region at 0x40000000?

\$\endgroup\$
  • \$\begingroup\$ Still having confusion; if you/anyone can explain it simply what is meant by writing/reading through 9:2 bit, I can't understand. \$\endgroup\$ – Sajjad Ahmed Dec 25 '15 at 14:44
  • \$\begingroup\$ Ok, I'll try again. You have 8 real bits of data in the register. Each of the bits from [9:2] of your address correspond to one of the bits of data. A 1 means you can read/write from that specific bit, a 0 means that you cannot. They have used the upper 8 bits of the address as a simple bitmask so you don't have too. Did you look at the figure in 7.2.12 that describes a write? \$\endgroup\$ – Krunal Desai Dec 25 '15 at 16:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.