CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

help on I2C_read on MAX6956

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
NicolasC



Joined: 14 Sep 2006
Posts: 27

View user's profile Send private message

help on I2C_read on MAX6956
PostPosted: Wed Jan 03, 2007 7:18 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jan 03, 2007 11:13 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jan 04, 2007 5:32 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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