&port and compare with the PORT Register Address - error

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

I wanted to compare the pointer address with the register address such as below.  i wonder why the compiler error of  forbids comparison between pointer and integer ?  

Isnt the &port is already the address of the Port Register ? 


void test(volatile uint8_t *port, unsigned int pin)
{
    
if  (&port == 0x25) 

  {
   do something
  }   

}


int main(){

   test(&PORTB, 2);

}



 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Another question is on the Atmega328PB Register Summary. The column show offset is address or offset  ?  Because 328P datasheet show Address and Offset.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hamisu wrote:
Isnt the &port is already the address of the Port Register ? 

I think you want to do is this.

if (port == 0x25)
{
  // do something
}

Remove the & in front of port.

“Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?” - Brian W. Kernighan
“Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.” - Antoine de Saint-Exupery

Last Edited: Sun. Apr 24, 2022 - 03:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think you'll also want a cast on one side of that to either cast up the 0x25 to a "volatile uint8_t *" or cast down "port" to an int (actually uint and make it 0x25U)

 

BTW I wonder why microchip changed the register summary table between 328 and 328PB. For the former both RAM and IO addresses are given. While that looks like RAM only for "offset" 

Last Edited: Sun. Apr 24, 2022 - 05:01 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just use PORTB again since you are already using the io header-

https://godbolt.org/z/ncnWKab5P

 

 

PORTB is defined as 

#define PORTB (*(volatile uint8_t*)0x25)

 

//port is a volatile uint8_t*, 0x25 is an int, compiler no  like

port == 0x25  //two different things

 

// PORTB is already dereferenced in the define so here you are comparing a volatile uint8_t* to a volatile uint8_t

port == PORTB //two different things

port == (*(volatile uint8_t*)0x25) //equivalent

 

//to get the address of a dereferenced pointer, use &

port == &PORTB //the address of PORTB is a volatile uint8_t*, so now comparing the same thing (volatile uint8_t*)

port == &(*(volatile uint8_t*)0x25) //equivalent

Last Edited: Sun. Apr 24, 2022 - 08:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

curtvm wrote:

Just use PORTB again since you are already using the io header-

https://godbolt.org/z/ncnWKab5P

 

 

PORTB is defined as 

#define PORTB (*(volatile uint8_t*)0x25)

 

//port is a volatile uint8_t*, 0x25 is an int, compiler no  like

port == 0x25  //two different things

 

// PORTB is already dereferenced in the define so here you are comparing a volatile uint8_t* to a volatile uint8_t

port == PORTB //two different things

port == (*(volatile uint8_t*)0x25) //equivalent

 

//to get the address of a dereferenced pointer, use &

port == &PORTB //the address of PORTB is a volatile uint8_t*, so now comparing the same thing (volatile uint8_t*)

port == &(*(volatile uint8_t*)0x25) //equivalent

 

 

Good Learning, but very complicated. Can it be easier to perceive like casting it to a value and compare the value ?  

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But Curt just told you what to do? He's saying this

void test(volatile uint8_t *port, unsigned int pin)
{

if  (&port == 0x25) 

  {
   do something
  }   

}

actually becomes far easier (and does not require "hidden" knowledge such as the fact that PORT is at 0x25) if you simply use:

void test(volatile uint8_t *port, unsigned int pin)
{

if  (port == &PORTB) 

  {
   do something
  }   

}

It couldn't be simpler could it?

 

EDIT: in fact here's a working example:

#include <avr/io.h>

__attribute__((noinline)) void setBit5(volatile uint8_t * port) {
    if (port == &PORTB) {
        PORTB &= (1 << 5);
    }
}

int main(void) {
    setBit5(&PORTC);
    setBit5(&PORTB);
}

(the attribute is only there to make it easier to follow the code flow in the debugger). If you single step that in the Studio 7 simulator you will find that on the first call the test in the function fails and it returns without doing anything. Then on the second call (where port == &PORTB) the test succeeds and it sets the bit.

Last Edited: Tue. Apr 26, 2022 - 03:58 PM