Optimise switch case statement


I am writing a library which is reading a sensor using direct port access. I am currently using a switch...case statement to select the port addresses, matching the pin the sensor is connected to. This was fine for my Uno and Mega but now I am porting to the Yun, the pin outs are not contiguous and the switch statement is eating into the Yun's, precious little, program space.

I won't post the whole library but you should be able to get the gist of what I am doing from the code below. Can anyone suggest an alternative, which uses less program memory than my, lots of case statements?


//hardware port pin mapping for Leonardo (yun)
#ifdef __AVR_ATmega32U4__
    //AT32u4 port pins are not contiguous and some port bits are missing
    #define PINBASE_B 4 //PORTB LEON PB0/NC SCLK MOSI MISO 8 9 10 11
       //non contiguous pins break my bit calculation
//  #define PINBASE_C 5     //PORTC LEON PC0-PC5/NA 5 13


//set the port address
void DLib::setPin(uint8_t pin) {
    bitClear(_errorFlags, DHT_ERR_INVALID);
    _dPin = pin;

    //set the port variables
    switch (pin) {

    //Leonardo, Yun
    #ifdef __AVR_ATmega32U4__

        //contiguous pins can use a single case statement, per port
        //PORT B
        case 8: case 9: case 10: case 11:
            _dRegister = &DDRB;
            _dPort = &PORTB;
            _dPins = &PINB;
            _dBit = pin - PINBASE_B;

        //non-contiguous pins use a case statement per pin, eating program space 
        //PORT C 
        case 5:
            _dRegister = &DDRC;
            _dPort = &PORTC;
            _dPins = &PINC;
            _dBit = 6;

        case 13:
            _dRegister = &DDRC;
            _dPort = &PORTC;
            _dPins = &PINC;
            _dBit = 7;

        //repeat for other usable pins

    #endif // __AVR_ATmega32u4__

        //default to pin unsupported error    
            bitSet(_errorFlags, D_ERR_INVALID);
            return false;

How often do you change the pins ? How about using an #define for the pin number and then only compiling the code for the pin which you are actually using.

Thanks for the suggestion.

I would like the library to be as easy to use as possible.
Can I pass a define to a library after it has been included?

//not sure how this is going to work
#include <DLib.h>
#define D_PIN_5

DLib* dSensor; 

void setup(void) {
    dSensor = new DLib(5);

DLib::DLib(uint8_t pin) {
#ifdef D_PIN_5
  _dPort = &PORTB   //assign port address
  _dBit = 6

Maybe I have misunderstood something.
Maybe I need to try a few things and see what the pre-processor makes of it.

Thanks anyhow