xandy
xandy

Reputation: 27421

_SFR_IO_ADDR() on Arduino Mega PortH+

I tried to use the SoftI2CMaster library [http://playground.arduino.cc/Main/SoftwareI2CLibrary], the library works great in most cases, but it doesn't work on ports H through L, the compiler give me following message:

/SoftI2CMaster.h: In function 'boolean i2c_init()':
/SoftI2CMaster.h:265: error: impossible constraint in 'asm'

Basically the code that caused the problem is some assembly:

__asm__ __volatile__ 
(
 ...
 : :
   [SCLDDR] "I"  (SCL_DDR), [SCLPIN] "I" (SCL_PIN), 
   [SCLIN] "I" (SCL_IN), [SCLOUT] "I" (SCL_OUT));

After some test, trial and error, I am pretty sure the problem is coming from SCL_DDR and those related variables, here's how they defined:

#define SDA_DDR         (_SFR_IO_ADDR(SDA_PORT) - 1)
#define SCL_DDR         (_SFR_IO_ADDR(SCL_PORT) - 1)
#define SDA_OUT         _SFR_IO_ADDR(SDA_PORT)
#define SCL_OUT         _SFR_IO_ADDR(SCL_PORT)
#define SDA_IN      (_SFR_IO_ADDR(SDA_PORT) - 2)
#define SCL_IN      (_SFR_IO_ADDR(SCL_PORT) - 2)

For the SXX_PORT, if I supply anything PORTA-PORTG will be fine, program compiles and execute without issue, but then if I supply PORTH-PORTK the error will come out. Can anyone point out what's the problem? Is the problem from _SFR_IO_ADDR()?

Upvotes: 0

Views: 1282

Answers (1)

UncleO
UncleO

Reputation: 8449

The constraint "I" requires a constant from 0 to 63. If you choose one of the higher ports, then the address (_SFR_IO_ADDR()) will be higher than 63.

You could try changing the modifier to "M", which requires a constant fitting in 8 bits. I don't know if this will work, or why the author chose to use "I".

If it works, you could send the author a bug report.

Upvotes: 1

Related Questions