|
|
View previous topic :: View next topic |
Author |
Message |
NicolasC
Joined: 14 Sep 2006 Posts: 27
|
help on I2C_read on MAX6956 |
Posted: Wed Jan 03, 2007 7:18 am |
|
|
Hello and happy new new year,
When reading port 12 to 19 everything is OK.
But on 20 to 27, the value is once right, once wrong : 255, 63, 255, 63 (all pins are unconnected with pullup activated.
I call mfd_task() periodicaly from main() and read mfd_keys[] for return values.
I had to change i2c_read() to i2c_read(0) to read the proper value.
Can someone explain that I had to disable acknowledge to be able to get the correct value ?
Regards
Code: |
enum keypad_state { //FSM states for key deboucing
IDLE,
OUTPUT_COL,
DELAY,
INPUT_DATA,
KEY_RELEASE
};
#define Port_12_19 0x4C
#define Port_20_27 0x54
#define _TEMPO_ 0x7FFF
int device_address;
typedef int key_cde;
static key_cde mfd_keys[5]; //list of keys to send through USB
static int16 tempo = _TEMPO_;
static keypad_state mfd_state = IDLE; //machine state for port operation
// Initialise the I2C bus and config register
void mfd_init(int addr )
{
int i;
printf("\r\nI2C init");
i2c_start(); //reset I2C
i2c_stop();
addr+= 0x40; //MAX6956 addresses take the form 100xxxx
device_address = addr; //where xxxx is the user-selected address 0-15.
//write_config_register(0x01); //Transition disable, Global current, no shutdown
i2c_start();
i2c_write( (device_address<<1) & 0xFE );
i2c_write( 0x04 ); //Select Config byte (0x04)
i2c_write( 0x01 ); //Transition disable, Global current, no shutdown
i2c_stop();
//configure port 12 to 22
i2c_start();
i2c_write( (device_address<<1) & 0xFE );
i2c_write( 0x0B ); //set adress for P15, P14, P13, P12 port config
printf("\r\n1:%u", i2c_write( 0xFF )); //set GPIO Inputs With Pullup
printf("\r\n2:%u", i2c_write( 0xFF )); //P19, P18, P17, P16:set GPIO Inputs With Pullup
printf("\r\n3:%u", i2c_write( 0xFF )); //P23, P22, P21, P20:set GPIO Inputs With Pullup
printf("\r\n4:%u", i2c_write( 0xFF )); //P27, P26, P25, P24:set GPIO Inputs With Pullup
i2c_stop();
//init_done = 1;
mfd_state = OUTPUT_COL;
printf("\r\nI2C init done");
}
void write_port(int PortNum, Data)
{
disable_interrupts(GLOBAL);
i2c_start();
i2c_write( (device_address<<1) & 0xFE);
i2c_write( PortNum );
i2c_write( Data );
i2c_stop();
enable_interrupts(GLOBAL);
}
int read_port(int PortNum)
{
int data;
disable_interrupts(GLOBAL);
i2c_start();
i2c_write( (device_address<<1) & 0xFE);
i2c_write( PortNum );
i2c_stop();
i2c_start();
i2c_write( (device_address<<1) | 0x01);
data = i2c_read(0);
printf ("\r\nVal = %u", data);
i2c_stop();
enable_interrupts(GLOBAL);
return data;
}
int mfd_task(void){
switch (mfd_state) {
case IDLE :
mfd_init(0);
break;
default:
if (! --tempo) {
tempo = _TEMPO_;
//mfd_keys[0] = read_port(Port_12_19);
mfd_keys[0] = read_port( Port_20_27 );
return 0;//1;
} else
return 0;
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jan 03, 2007 11:13 am |
|
|
Quote: | I had to change i2c_read() to i2c_read(0) to read the proper value.
Can someone explain that I had to disable acknowledge to be able
to get the correct value ? |
It's part of the i2c specification that the Master should do a NAK on
the last i2c read operation. It's my belief that the person who wrote
those series of data sheets for Maxim just made a mistake. They
left it out.
From the i2c specification:
(Regarding the Master reading from the Slave)
Quote: |
If a master-receiver is involved in a transfer, it must signal
the end of data to the slave- transmitter by not generating
an acknowledge on the last byte that was clocked out of
the slave. The slave-transmitter must release the data line
to allow the master to generate a STOP or repeated
START condition. |
See section 7.2 "Acknowledge", on page 10 of the i2c specification.
Look about halfway down on the right side of the page, to see the
above quote:
http://www.nxp.com/acrobat_download/literature/9398/39340011.pdf |
|
|
NicolasC
Joined: 14 Sep 2006 Posts: 27
|
|
Posted: Thu Jan 04, 2007 5:32 am |
|
|
Thanks for your explanations.
It's quite stange that the behaviour is different when reading Port_12_19 and Port_20_27 but never mind : I'll follow the specs and that's it.
Regards |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|