Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Thread

Mapping port and pin in C++ CTOR - best practice

Mapping port and pin in C++ CTOR - best practice

2013-12-31 by ron@teahousestudio.com

I'm modifying and extending the OneButton library (which relies on Arduino environment) for generic AVR use.

Briefly, my Button class (yeah - I don't really like adding a capital C to a class name) maintains a state model to determine if changes on an input pin represent a click event, double click event, and so on, and call a C function to handle the appropriate event handler (onClick, onDoubleClick).

In the original code (OneButton) the CTOR takes a pin number - this is the Arduino pin and behind the scenes, the Arduino environment maps this into a port/pin combination during operations such as DigitalRead().

I want to do something similar - only I don't have Arduino pin numbers to play with (currently the code is targetted at ATTiny85 but it should work on any ATTiny or ATMega).

If I forget about specifying a port (after all, I can only use PORTB on an ATTiny85) I could pass just the port bit (for example, PB1) and hard code setting port direction (using the DDRB macro) and testing the input bit state - and this is what I will do for now.

I can define some constants representing the port number (and there are already macros for the bit numbers) and use a switch statement to determine which macro or inline assembly instruction to use - but this will require conditional code to determine whether the appropriate macro is available for the target platform.

I wondered if there is a generic solution to this problem - preferably one that doesn't have the code overhead of the Arduino.

RE: Mapping port and pin in C++ CTOR - best practice

2013-12-31 by ron@teahousestudio.com

Just to add, I have found some definitions in sfr_defs.h and portpins.h

so I know I can do things like bit_is_set(_port, _bit) in the Button code (and call the CTOR with something like Button btn = Button(PINB, PB2, true); )


What I'm not clear about is how to set the IO mode for (_port, _bit) in the CTOR.

Re: [AVR-Chat] Mapping port and pin in C++ CTOR - best practice

2014-01-01 by Martin McKee

It is easy enough to store a pointer to the register ( PORTB ) and a mask in the class. This may be the most generic solution available. If both values are stored constant ( in the case of the port register, volatile uint8_t * const ) the optimizer will sometimes even find the proper optimizations to get rid of indirect access. Even if the optimizer isn't quite that good, however, it is much faster than the Arduino I/O code and its logical to physical pin mapping. I tend to prefer passing the port register because it simplifies the code and, in most cases, the code is as good or better than the conditional version. It is also easier to maintain ( no reason for the Button class to have a list of available ports anywhere ).

Martin Jay McKee


Show quoted textHide quoted text
On Tue, Dec 31, 2013 at 4:09 AM, <ron@teahousestudio.com> wrote:

I'm modifying and extending the OneButton library (which relies on Arduino environment) for generic AVR use.


Briefly, my Button class (yeah - I don't really like adding a capital C to a class name) maintains a state model to determine if changes on an input pin represent a click event, double click event, and so on, and call a C function to handle the appropriate event handler (onClick, onDoubleClick).

In the original code (OneButton) the CTOR takes a pin number - this is the Arduino pin and behind the scenes, the Arduino environment maps this into a port/pin combination during operations such as DigitalRead().

I want to do something similar - only I don't have Arduino pin numbers to play with (currently the code is targetted at ATTiny85 but it should work on any ATTiny or ATMega).

If I forget about specifying a port (after all, I can only use PORTB on an ATTiny85) I could pass just the port bit (for example, PB1) and hard code setting port direction (using the DDRB macro) and testing the input bit state - and this is what I will do for now.

I can define some constants representing the port number (and there are already macros for the bit numbers) and use a switch statement to determine which macro or inline assembly instruction to use - but this will require conditional code to determine whether the appropriate macro is available for the target platform.

I wondered if there is a generic solution to this problem - preferably one that doesn't have the code overhead of the Arduino.


Re: [AVR-Chat] Mapping port and pin in C++ CTOR - best practice

2014-01-01 by Dave Hylands

Hi,

On Tue, Dec 31, 2013 at 3:09 AM, <ron@teahousestudio.com> wrote:
>
>
>
> I'm modifying and extending the OneButton library (which relies on Arduino environment) for generic AVR use.
>
> Briefly, my Button class (yeah - I don't really like adding a capital C to a class name) maintains a state model to determine if changes on an input pin represent a click event, double click event, and so on, and call a C function to handle the appropriate event handler (onClick, onDoubleClick).
>
> In the original code (OneButton) the CTOR takes a pin number - this is the Arduino pin and behind the scenes, the Arduino environment maps this into a port/pin combination during operations such as DigitalRead().
>
> I want to do something similar - only I don't have Arduino pin numbers to play with (currently the code is targetted at ATTiny85 but it should work on any ATTiny or ATMega).
>
> If I forget about specifying a port (after all, I can only use PORTB on an ATTiny85) I could pass just the port bit (for example, PB1) and hard code setting port direction (using the DDRB macro) and testing the input bit state - and this is what I will do for now.
>
> I can define some constants representing the port number (and there are already macros for the bit numbers) and use a switch statement to determine which macro or inline assembly instruction to use - but this will require conditional code to determine whether the appropriate macro is available for the target platform.
>
> I wondered if there is a generic solution to this problem - preferably one that doesn't have the code overhead of the Arduino.

Sure - you can do it purely with macros. I did something similar for LEDs.

Look at this:

https://github.com/dhylands/projects/blob/master/common/avr/Led.h

an example of how you configure the LED is here:

https://github.com/dhylands/projects/blob/master/avr/bioloid-auxPower/Config.h#L29

and how it's used here:

https://github.com/dhylands/projects/blob/master/avr/bioloid-auxPower/aux-power.c#L159

In my case, I used a trick and assume that the DDR register for a given PORTx register is 1 less than the PORTx register. This is what the LED_DDR macro does.

But the rest of it could easily be used to allow pin numbers (or names) to be mapped to arbitrary PORT/pins by using some macros.

--
Dave Hylands
Shuswap, BC, Canada
http://www.davehylands.com

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.