We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello,
I'm using the LPC2468 micro controller. I have a struct mapped to the I2C register and in the I2C interrupt I statically access that struct, and everything works fine.
I've since broken off into a separate function the processing part of the interrupt code and now the interrupt passes a reference to its register to that function (so I can use one function for the three I2C buses). And suddenly the code doesn't work. Just to make sure I didn't mess up anything when creating the new subroutine, I replaced all the by-reference register accesses with a static call, and it worked again. I also verified that the reference points to the correct address.
So, it seems that when accessing the register statically, it works, and when accessing by reference it doesn't work. I can't figure out why. Does anyone know what I'm doing wrong? Or is there some technical reason why this won't work?
Here's a code snippet:
struct i2c_regs { U32 I2CONSET; U32 I2STAT; U32 I2DAT; U32 I2ADR; U32 I2SCLH; U32 I2SCLL; U32 I2CONCLR; } __attribute__((packed)); struct i2c_data { volatile struct i2c_regs *regs; U8 len; U8 pos; U8 addr; char *buf; char *base; U8 state; OS_MUT lock; OS_SEM sem; }; static volatile struct i2c_regs i2c0_regs __attribute__((at(I2C0_BASE_ADDR))); static struct i2c_data i2c0; // i2c0.regs is properly initialized void i2c0_handler(void) __irq { IENABLE; i2c_master_handler(&i2c0); IDISABLE; VICVectAddr = 0; } static void i2c_master_handler(struct i2c_data *i2c) { int status; status = i2c->regs->I2STAT; switch(status) { case I2C_STATUS_START: #if 0 // Doesn't work i2c->regs->I2DAT = i2c->addr; i2c->pos = 0; i2c->buf = i2c->base; i2c->regs->I2CONSET = I2CONSET_AA; i2c->regs->I2CONCLR = I2CONCLR_SIC|I2CONCLR_STAC; #else // Does work i2c0_regs.I2DAT = i2c->addr; i2c->pos = 0; i2c->buf = i2c->base; i2c0_regs.I2CONSET = I2CONSET_AA; i2c0_regs.I2CONCLR = I2CONCLR_SIC|I2CONCLR_STAC; #endif break; ... }
Thanks,
Jon
When debugging with uv3, it is possible to setup its behavior when facing non-aligned access etc: "Debug->Debug Settings".