My i2c.lib for 5700 / 5600w

Hello

Sorry for my late answer…

Look @ “Modif CC” into the code.

/*** BeginHeader  */ #ifndef __I2C_LIB #define __I2C_LIB /*** EndHeader */  /* START LIBRARY DESCRIPTION ********************************************* I2C.LIB Rabbit Semiconductor, 2001    Library implementing I2C master on port d pins, default SCL=PD6, SDA=PD7                Define I2CSCLBit and I2CSDABit to set pins on D port               OR define these functions for other pin options                 i2c_SCL_H()  - set the clock bit high                 i2c_SCL_L()  - set the clock bit low                 i2c_SDA_H()  - set the data bit high                 i2c_SDA_L()  - set the data bit low                 i2c_SDA()       - read data bit (return 1=high=5V or 0)                 i2c_SCL()    - read clock bit (return 1=high=5V or 0)               API Functions:            		i2c_init              	i2c_start_tx              	i2c_startw_tx               	i2c_send_ack                i2c_send_nak                i2c_read_char                i2c_check_ack 					i2c_write_char 					i2c_stop_tx 					i2c_wr_wait               Protocol:                while clock high                      START - data high to low                      STOP  - data low to high                   while clock low                      Data can change                 ack : data low  while clock pulse                nak : data high while clock pulse                 This library was programmed for Rabbit Semiconductor by:                KENT JOHANSEN                  ANAKRON / ANAKRON CANADA INC                  www.anakron.com                  kent@anakron.com  END DESCRIPTION *********************************************************/  /*** BeginHeader */ // Define the bits in the D port and the delay to use for I2C  #ifndef i2cClockStretchDelay  // Counts of I2CDelay to allow for clock stretching   #define i2cClockStretchDelay 2000 #endif  #ifndef i2cRetries 	// Number of retries to get an answer from slave in i2c_write_wait   #define i2cRetries 1000 #endif  #ifndef I2CSCLBit 	// The clock bit, if on port D.   	//#define I2CSCLBit 6    // Modif CC -> The clock bit, if on port E   	#define I2CSCLBit 0 #endif  #ifndef I2CSDABit 	// The data bit, if on port D.   	//#define I2CSDABit 7    // Modif CC -> The data bit, if on port E   	#define I2CSDABit 1 #endif  /*** EndHeader */  /*** BeginHeader i2c_init,i2c_SCL_H,i2c_SCL_L,i2c_SDA_H,i2c_SDA_L,i2c_SDA,i2c_SCL */  void i2c_init(); int i2c_clocks_per_us;	//need declaration to prevent error in asm definition 								//below  #define WAIT_5_us asm ld a,(i2c_clocks_per_us) $\              sub 2 $\              ld b,a $\              db 0x10, -2  //*** define C macro *** // a machine code version of above #define cWAIT_5_us asm ld a,(i2c_clocks_per_us) $\              sub 3 $\              ld b,a $\              db 0x10,-2   //	db 3ah,i2c_clocks_per_us&0ffh,(i2c_clocks_per_us>>8)&0ffh,0d6h,3,47h,10h,-2   // Define these to change basic bit handling #ifndef i2c_SCL_H() #define i2c_SCL_H() BitWrPortI(PEDDR,&PEDDRShadow,0,I2CSCLBit) #define i2c_SCL_L() BitWrPortI(PEDDR,&PEDDRShadow,1,I2CSCLBit) #define i2c_SDA_H() BitWrPortI(PEDDR,&PEDDRShadow,0,I2CSDABit) #define i2c_SDA_L() BitWrPortI(PEDDR,&PEDDRShadow,1,I2CSDABit) #define i2c_SCL()   BitRdPortI(PEDR,I2CSCLBit)  #define i2c_SDA()   BitRdPortI(PEDR,I2CSDABit) #endif  /*#ifndef i2c_SCL_H() #define i2c_SCL_H() BitWrPortI(PDDDR,&PDDDRShadow,0,I2CSCLBit) #define i2c_SCL_L() BitWrPortI(PDDDR,&PDDDRShadow,1,I2CSCLBit) #define i2c_SDA_H() BitWrPortI(PDDDR,&PDDDRShadow,0,I2CSDABit) #define i2c_SDA_L() BitWrPortI(PDDDR,&PDDDRShadow,1,I2CSDABit) #define i2c_SCL()   BitRdPortI(PDDR,I2CSCLBit)  #define i2c_SDA()   BitRdPortI(PDDR,I2CSDABit) #endif */  /*** EndHeader */   /* START FUNCTION DESCRIPTION ******************************************** i2c_init               SYNTAX: int i2c_init();  DESCRIPTION: Sets up the SCL and SDA port pins for open-drain output 				 Also initializes delay constant 				 Acknowledgement: 				 	This library is programmed for Rabbit Semiconductor by                KENT JOHANSEN                ANAKRON / ANAKRON CANADA INC                www.anakron.com                kent@anakron.com    END DESCRIPTION **********************************************************/ nodebug void i2c_init() {  	//Modif CC le 23/01/2010    //SCL et SDA sur Port E (PD6 et PD7 non dispo sur RCM5700/5600W)    // Set the bits to tristate and the output to 0. Toggle using    //tristate reg. 	// This function affects the port D transfer transfer clock 	// Transfer clock on port D is PCLK/2 	WrPortI(PECR,&PECRShadow,0); 	BitWrPortI(PEFR ,&PEFRShadow ,0,I2CSCLBit); 	// Set the bits to normal function 	BitWrPortI(PEFR ,&PEFRShadow ,0,I2CSDABit); 	BitWrPortI(PEDDR,&PEDDRShadow,0,I2CSCLBit); 	// Set the bits to input (=0) 	BitWrPortI(PEDDR,&PEDDRShadow,0,I2CSDABit); 	BitWrPortI(PEDCR,&PEDCRShadow,1,I2CSCLBit); 	// Set the bits to Open Drain 	BitWrPortI(PEDCR,&PEDCRShadow,1,I2CSDABit); 	BitWrPortI(PEDR ,&PEDRShadow ,0,I2CSCLBit); 	// Set the outputs to 0, when outputs 	BitWrPortI(PEDR ,&PEDRShadow ,0,I2CSDABit);      // Set the bits to tristate and the output to 0. Toggle using    //tristate reg. 	// This function affects the port D transfer transfer clock 	// Transfer clock on port D is PCLK/2 	//WrPortI(PDCR,&PDCRShadow,0); 	//BitWrPortI(PDFR ,&PDFRShadow ,0,I2CSCLBit); 	// Set the bits to normal function 	//BitWrPortI(PDFR ,&PDFRShadow ,0,I2CSDABit); 	//BitWrPortI(PDDDR,&PDDDRShadow,0,I2CSCLBit); 	// Set the bits to input (=0) 	//BitWrPortI(PDDDR,&PDDDRShadow,0,I2CSDABit); 	//BitWrPortI(PDDCR,&PDDCRShadow,1,I2CSCLBit); 	// Set the bits to Open Drain 	//BitWrPortI(PDDCR,&PDDCRShadow,1,I2CSDABit); 	//BitWrPortI(PDDR ,&PDDRShadow ,0,I2CSCLBit); 	// Set the outputs to 0, when outputs 	//BitWrPortI(PDDR ,&PDDRShadow ,0,I2CSDABit);  	i2c_clocks_per_us = (int)(19200L*32*freq_divider/1000000L); 	if(i2c_clocks_per_us < 3) 	{ 		i2c_clocks_per_us = 3; 	} }  /*** BeginHeader i2c_wSCL_H */ int i2c_wSCL_H(); /*** EndHeader */  /* START FUNCTION DESCRIPTION ******************************************** i2c_wSCL_H               SYNTAX: int i2c_wSCL_H();  DESCRIPTION: sets clock high, if slave stretches it, the function waits               for max i2cClockStretchDelay i2c_Delay's for the clock to go               low slaves use this feature to delay data transfer to master.  RETURN VALUE: 0 success, -1 clock stretching timeout END DESCRIPTION **********************************************************/  nodebug int i2c_wSCL_H() { 	// Sets SCL high and waits for clock stretching. Returns -1 if stretch 	//too long 	auto int delcnt;    i2c_SCL_H();    cWAIT_5_us;   	delcnt=0; 	while(i2c_SCL()==0 && delcnt  SYNTAX: int i2c_start_tx();  DESCRIPTION: initiates i2c transmission by sending S           first waits for possible clock stretching.           data goes low while clock is high.  RETURN VALUE: 0 success, -1 clock stretching timeout END DESCRIPTION **********************************************************/  nodebug int i2c_start_tx() { 	// Try to send start pulse. If clock stretching happening, return 1 else 0    if (i2c_wSCL_H()) return -1; // Check if clock stretching too long    i2c_SDA_H();    cWAIT_5_us;    i2c_SDA_L();    cWAIT_5_us;    i2c_SCL_L();    return 0; }  /*** BeginHeader i2c_startw_tx */ int i2c_startw_tx(); /*** EndHeader */  /* START FUNCTION DESCRIPTION ******************************************** i2c_startw_tx              SYNTAX: int i2c_startw_tx();  DESCRIPTION: initiates i2c transmission by sending S           First waits for possible clock stretching.           data goes low while clock is high.           Inserts delay after S pulse.  RETURN VALUE: 0 success, -1 clock stretching timeout END DESCRIPTION **********************************************************/  nodebug int i2c_startw_tx() { 	auto unsigned int delcnt; 	if (i2c_wSCL_H()) return -1; // Check if clock stretching too long    i2c_SDA_H();    cWAIT_5_us;    i2c_SDA_L();    cWAIT_5_us;    i2c_SCL_L();    cWAIT_5_us;    return 0; }  /*** BeginHeader i2c_send_ack */ int i2c_send_ack(); /*** EndHeader */  /* START FUNCTION DESCRIPTION ******************************************** i2c_send_ack              SYNTAX: int i2c_send_ack();  DESCRIPTION: Sends ACK sequence to slave.           ACK is usually sent after succesful transfer, where more bytes           are to be read.  RETURN VALUE: 0 success, -1 clock stretching timeout END DESCRIPTION **********************************************************/  nodebug int i2c_send_ack() { 	i2c_SDA_L(); 	cWAIT_5_us; 	if (i2c_wSCL_H()) return -1; // Check if clock stretching too long 	cWAIT_5_us; 	i2c_SCL_L(); 	cWAIT_5_us; 	i2c_SDA_H(); 	return 0; }  /*** BeginHeader i2c_send_nak */ int i2c_send_nak(); /*** EndHeader */  /* START FUNCTION DESCRIPTION ******************************************** i2c_send_nak              SYNTAX: int i2c_send_nak();  DESCRIPTION: Sends NAK sequence to slave.           NAK is often sent when transfer is finished.  RETURN VALUE: 0 success, -1 clock stretching timeout END DESCRIPTION **********************************************************/  nodebug int i2c_send_nak() { 	i2c_SDA_H(); 	cWAIT_5_us; 	if (i2c_wSCL_H()) return -1; // Check if clock stretching too long 	cWAIT_5_us; 	i2c_SCL_L(); 	cWAIT_5_us; 	i2c_SDA_H(); 	return 0; }  /*** BeginHeader i2c_read_char */ int i2c_read_char(char *ch); /*** EndHeader */  /* START FUNCTION DESCRIPTION ******************************************** i2c_read_char              SYNTAX: int i2c_read_char(char *ch);  DESCRIPTION: Reads 8 bits from slave.           Allows for clocks stretching on all SCL going high.           This is NOT in the protocol for I2C, but allows           I2C slaves to be implemented on slower devices.  PARAMETER1: char * ch - 1 character return buffer.  RETURN VALUE: 0 success, -1 clock stretching timeout END DESCRIPTION **********************************************************/  nodebug int i2c_read_char(char *ch) { 	auto char res,cnt; 	for ( cnt=0,res=0;cnt<8;cnt++ ) 	{ 		i2c_SDA_H(); 		cWAIT_5_us; 		if (i2c_wSCL_H()) return -1; // too long clock stretching 		res<<=1; 		if (i2c_SDA()) res|=0x01; 		i2c_SCL_L(); 		cWAIT_5_us; 	} 	*ch=res; return 0; }  /*** BeginHeader i2c_check_ack */ int i2c_check_ack(); /*** EndHeader */  /* START FUNCTION DESCRIPTION ******************************************** i2c_check_ack              SYNTAX: int i2c_check_ack();  DESCRIPTION: Checks if slave pulls data low for ACK on clock pulse.           Allows for clocks stretching on SCL going high.  RETURN VALUE: 0 : Ack sent from slave, 1: NAK sent from slave,              -1 : if timeout END DESCRIPTION **********************************************************/  nodebug int i2c_check_ack() { 	auto int delcnt; 	i2c_SDA_H(); 	cWAIT_5_us; 	if (i2c_wSCL_H()) return -1; // Check if clock stretching too long 	if (i2c_SDA()) 	{ 		i2c_SCL_L(); 		return 1; 	} 	i2c_SCL_L(); 	return 0; }  /*** BeginHeader i2c_write_char */ int i2c_write_char(char d); /*** EndHeader */  /* START FUNCTION DESCRIPTION ******************************************** i2c_write_char              SYNTAX: int i2c_write_char(char d);  DESCRIPTION: Sends 8 bits to slave.           Checks if slave pulls data low for ACK on clock pulse.           Allows for clocks stretching on SCL going high.  PARAMETER1: char ch - character to send  RETURN VALUE: 0 success, -1 clock stretching timeout, 1 if NAK sent from 				  slave END DESCRIPTION **********************************************************/  nodebug int i2c_write_char(char d) { 	// Writes char and returns -1 if no ACK was sent from remote 	auto char i; 	for (i=0;i<8;i++) 	{ 		if (d & 0x80) 		{ 			i2c_SDA_H(); 		} 		else 		{ 			i2c_SDA_L(); 		} 		cWAIT_5_us; 		if (i2c_wSCL_H()) return -1; 		i2c_SCL_L(); 		cWAIT_5_us; 		d = d << 1; 	} 	return i2c_check_ack(); }  /*** BeginHeader i2c_stop_tx */ void i2c_stop_tx(); /*** EndHeader */  /* START FUNCTION DESCRIPTION ******************************************** i2c_stop_tx              SYNTAX: void i2c_stop_tx();  DESCRIPTION: Sends P (STOP) to slave. 	          Clock goes high, then data goes high.  RETURN VALUE: none END DESCRIPTION **********************************************************/  nodebug void i2c_stop_tx() { 	i2c_SDA_L(); 	cWAIT_5_us; 	i2c_SCL_H(); 	cWAIT_5_us; 	i2c_SDA_H(); }  /*** BeginHeader i2c_wr_wait */ int i2c_wr_wait(char d); /*** EndHeader */  /* START FUNCTION DESCRIPTION ******************************************** i2c_wr_wait              SYNTAX: int i2c_wr_wait(char d);  DESCRIPTION: Retries char write until slave responds.              Max i2cRetries attempts.  PARAMETER1: char ch - character to send  RETURN VALUE: 0 success, -1 too many retries END DESCRIPTION **********************************************************/  nodebug int i2c_wr_wait(char d) { 	auto unsigned int cnt; 	cnt=0; 	while (i2c_write_char(d) && cnt=i2cRetries)    {    	return -1; // number of retries exceeded 	} 	else 	{ 		return 0; 	} }   /*** BeginHeader */ #endif /*** EndHeader */