Cortex M3 GPIO address (LM3s300)

armcortex-m3

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).

Best Answer

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?