How to pass a port and ddr to a function

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

Hello! I am trying to have a function for my atmega328p that i can pass a port number and it would do something to said port number. In other words, say i wanted to output something to PIND7, I would have to said the DDRD as output for pin 7 and then write a digital high in PORTD Pin 7. So in my function i want to pass as a parameter say

 

myFunction(D,7)

{

     Do something with given port (in this case D) and pin 7.

}

 

And if i wanted to do, say C and pin 4 then

 

myFunction(C,4)

{

     Do something with given port (in this case C) and pin 4.

}

 

Can anybody point me in the right direction? I am trying to learn so if anybody can point me to some good literature that would be good too!

Dax

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

PINDx, PORTDx, DDRDx are actually preprocessor defines (see the io*.h corresponding to your chip in include/avr/), so I'd suggest using a preprocessor macro instead of a C function.

ɴᴇᴛɪᴢᴇᴎ

Last Edited: Sun. Sep 4, 2016 - 07:46 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Generic I/O" has often been discussed here, where I use the term as arbitrary run-time AVR8 port manipulation versus compile-time.

 

I've yet to hear a compelling reason for such a facility.  So I'll continue asking the question...  Does your application, or any other AVR8 application, really change configuration at run time such that generic I/O is mandatory?

 

Perhaps it is because AVR8 instruction set isn't really set up to do it with maximum cycle/code efficiency.

 

That said, have you looked at how Arduino does it?  (and I forget how many cycles it takes -- like 20, and RMW effects are introduced)

[edit out duplicate text]

 

You can probably find answers to your queries in prior discussions:
http://www.avrfreaks.net/forum/h...

http://www.avrfreaks.net/forum/p...

http://www.avrfreaks.net/forum/c...

http://www.avrfreaks.net/forum/p...

http://www.avrfreaks.net/forum/p...

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Mon. Sep 5, 2016 - 01:48 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

Lee, i think the gramophone needle got stuck - give it a tap!

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

theusch wrote:
You can probably find answers to your queries in prior discussions:

Or the user manual (if this is avr-gcc that is - on this occasion I didn't check!)...

 

http://www.nongnu.org/avr-libc/u...

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

A bit off topic, but the next item in this FAQ (What registers are used by the C compiler?) made me wonder so I'll nevertheless jump on the occasion to query your GCC expertise, Cliff: what about General Purpose I/O Registers (like GPIOR0 on a mega328 e.g.)? It seems GCC does not take advantage of them, right?

ɴᴇᴛɪᴢᴇᴎ

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

Nope, GCC doesn't use those - perhaps because some of it's targets (mega8, 16, 32 come to mind) are old enough not to have it? On CPUs that have GPIOR0 I generally just manually cast my 8 most frequently used bit vars onto it. In the older chips I tend to use TWAR for the same (don't often use I2C).

 

BTW I'm not sure if that FAQ answer about ABI/register usage is necessarily up to date. I tend to use this:

 

https://gcc.gnu.org/wiki/avr-gcc

 

That's written by Georg-Johan Lay and as he's done most of the core work on avr-gcc in the last few years if he doesn't know this stuff no one will !

 

It is true however that the FAQ in the AVR-LibC user manually is a sadly under-used resource (judging from the number of posts that are made that would have been answered there).

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

Thanks! :-)

ɴᴇᴛɪᴢᴇᴎ

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

Kartman wrote:
Lee, i think the gramophone needle got stuck - give it a tap!

LOL -- I remember almost losing my composed post when going back-and-forth adding the links.  When I hit Post there was only one copy. ;)  wysiwyg -- well, wasn't.

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

clawson wrote:
Or the user manual...

... which discussion is conveniently about "bits", ignoring the RMW considerations introduced with a single "bit".

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

netizen wrote:
what about General Purpose I/O Registers (like GPIOR0 on a mega328 e.g.)? It seems GCC does not take advantage of them, right?

Atmel in its infinite wisdom when creating the "unified I/O register map" across most (?) Mega models of the modern era saw fit to cripple the '328 family by leaving all the unused gaps in low address space.

 

Back to GPIOR -- it depends on the operation, but only GPIOR0 is within reach of SBI/CBI.  GPIOR1/2 are indeed within IN/OUT range which can save you a cycle and word in very limited circumstances versus LDS/STS.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

theusch wrote:
Back to GPIOR -- it depends on the operation, but only GPIOR0 is within reach of SBI/CBI.

Yeah, that's what I had in mind and how I use it, just as Cliff mentioned above.

ɴᴇᴛɪᴢᴇᴎ

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

netizen wrote:
Yeah, that's what I had in mind and how I use it, just as Cliff mentioned above.

Y'all are discussing the GCC.  CodeVision will use GPIOR0 for "bit" variables if asked (via project option).

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

theusch wrote:
Y'all are discussing the GCC.  CodeVision will use GPIOR0 for "bit" variables if asked (via project option).

As there is no boolean type in C, how does it work?

ɴᴇᴛɪᴢᴇᴎ

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

netizen wrote:
As there is no boolean type in C, how does it work?
An extension to C. It has several that are very usefully, specifically targetted for embedded work. avr-gcc could try to mimic such things but it tends to be up "against the committee" as to what can/can't get included. The __flash thing, for example is only on avr-gcc, not avr-g++ as the C++ mob don't want their "standard" compiler tainted.

 

It is kind of curious though that GCC does have it's own raft of GNU specific extensions for other things though - obviously those were things the committee rather fancied having for their ARMs and stuff? AVR is a very small fish in that pond.

 

At least it was Joerg Wunsch who was heavily involved in avr-gcc development got the "0b" prefix accepted that is of use to all GCC users including the ARM, AMD64, x86 boys too. (even if it does break the Linux "indent" command!)

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

Alright, thanks. :-)

While we're at it, I'm just reading about the io_low variable attribute: ever used that to bind your heavily used bits variable to GPIOR0?

ɴᴇᴛɪᴢᴇᴎ

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

Ooh! New toy!!

 

That io() and io_low() was not in the 4.9.4 manunal:

 

https://gcc.gnu.org/onlinedocs/g...

 

for example. (almost everyone - certainly on Windows - is currently using either a 4.8.2 or a 4.9.2).  But it has appeared by 5.4:

 

https://gcc.gnu.org/onlinedocs/g...

 

(I don't know where to find any issues of the manual between 4.9.4 and 5.4.0) so, anyway, this is new stuff. I detect the faint whiff of G-J Ley !

 

This is why it's always worth going back to the GCC site and rereading these manuals from time to time as it's often the only way you are going to find out about new stuff.

 

[Rats, I did have a 5.3 (Windows) build on my PC until recently but I deleted it in one of my purges when the HDD filled up for the Nth time - if anyone wants to experiment they could try http://gnutoolchains.com/download/ and get the Windows build of 5.3 from there and see if it has this io_low() stuff]

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

I bet you already thought about how you could put these into profit in your alternate SFR access helper file (sorry don't remember how you called it, you know the struct/bit-fields generated by your python script?)… :-)

ɴᴇᴛɪᴢᴇᴎ

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

clawson wrote:
The __flash thing, for example ...

That is being discussed in another current thread, right?  And someone ;) said:

netizen wrote:

Nobody is arguing that const should become an identifier for where data are stored. Rather, the point is that a global const variable, for example, should automatically be identified by the toolchain as a candidate for relocation in a ro section. The meaning of const isn't in question, nor would it be impacted at all.

Back when I was your age and AVRs were new, the C toolchain implementors had to handle the Harvard and EEPROM and port access and ...

 

So there were additions and compromises.  Over the years things have become a bit more codified and more in line with standard C (which has also evolved somewhat).

 

In particular with const, it does impact say a const function parameter.  Does it just mean "not modified", or "it comes from flash"?  Or both?

 

 

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Actually, my first thought actually was "oh bugger, that screws my header defs thing!". I guess I can mod the Python to now output in this format.

 

It all does look like the start of some kind of cunning master plan (else why would they have bothered?). I wonder if the work to implement this has actually come from Atmel and they, themselves want to further automate the creation of .h files from .adtf data? Again this is all to do with being able to add new devices "on the fly" without the need of a compiler/linker rebuild. I guess one could search the SVN to see who added this - the names of the Atmel (and the non Atmel) engineers who deliver the avr-gcc goodies are fairly well known at this stage.

 

(Of course if this was instigated by Atmel it might all be a lot of wasted effort if Mchip have now chosen to price AVR8 out of existence!).

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

theusch wrote:
In particular with const, it does impact say a const function parameter. Does it just mean "not modified", or "it comes from flash"? Or both?

It should of course not impact it: it should still mean "not modified" as it means right now, as mandates the standard, and as it'd keep meaning for a global const var as well.

Let me rephrase it in case there's a misunderstanding: the idea is not to modify the semantics of const as defined in the C standard, it is about seizing a hardware optimization opportunity, if you which. I believe the C standard does not say a word about where in RAM or FLASH this global var should reside, so why would C have anything to do with it?

Imagine the compiler automatically adding a __flash qualifier before every global const declaration it encounters. Wouldn't that produce this very result?

What am I missing?

ɴᴇᴛɪᴢᴇᴎ

Last Edited: Mon. Sep 5, 2016 - 05:26 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh, I guess I see what you mean: GCC isn't currently respecting the C standard with this __flash qualifier, so that a __flash function parameter currently is enforcing a non-standard hardware constraint. If it'd get back to the standard it'd break existing code. Is that it?

This __flash/PROGMEM thing is like an annoying piece of tape on a finger… :-)

ɴᴇᴛɪᴢᴇᴎ

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

netizen wrote:
It should of course not impact it: it should still mean "not modified" as it means right now, ...

No, what I'm mentioning is where the compiler is then expected to fetch the parameter value from.  As I read it, you are implying that the compiler must "overload" as in C++ to decide which memory space to fetch from.

 

[I thought that there is some provision for memory space ala __flash in recent standards; but I'm not good at interpreting them.]

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

theusch wrote:
you are implying that the compiler must "overload" as in C++ to decide which memory space to fetch from.

Indeed, I am… :-)

—Guess I should have made it explicit.

ɴᴇᴛɪᴢᴇᴎ

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

But now that I think about it some more, it does not seems as easy… I'm not sure how common it is in practice to use a function/feature both with normal and __flash vars. I don't recall any case in my projects. But with C pointer arithmetic, it might be very hard to make sure parameters are all of the right "type"…

ɴᴇᴛɪᴢᴇᴎ

Last Edited: Mon. Sep 5, 2016 - 06:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So much reading! Thank you all for the pointers. Sorry I am a newbie and it's hard to follow so it takes me a while to grasp and answer.

Dax

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

As I understand it, __flash is a qualifier, rather like const and volatile.

In a function prototype, neither const nor volatile is especially meaningful.

void fred(const int arg);

void fred(volatile int arg);

They are meaningful in function headers, but volatile would be strange.

void fred(const __flash int arg);

could be done, but the extension defined in n1275 does not

allow automatic variables outside the generic address space.

International Theophysical Year seems to have been forgotten..
Anyone remember the song Jukebox Band?

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

Note that most of the AVR-specific stuff of avr-gcc come from macros naming IO registers.

Most of the rest are macros that expand into in-line assembly.

Bit variables packed into GPIOn registers would require additions to avr-gcc internals.

Depending on precisely how they're dome, such bit variables might require additions to the linker.

 

OTOH they are easy enough to do by hand.

The utility of putting them into the compiler would seem low.

International Theophysical Year seems to have been forgotten..
Anyone remember the song Jukebox Band?

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

I concur. As it is I'm quite happy with my current tools and macros (to do it "by hand").

 

Back to OP's question, I don't see any better than Lee what the point for dynamic SFR bit setting would be.

I'd go as far as saying there is none, if only in the hope a provocative stance might lure the rare examples out of the shadows…

ɴᴇᴛɪᴢᴇᴎ