Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

Re: code for I2C in lpc2106 using Keil.

2004-11-22 by peterburdine

--- In lpc2000@yahoogroups.com, "jha_santosh_kr2005"
<jha_santosh_kr2005@y...> wrote:
> 
> Hi,
> I am desperately trying to communicate with RTC pCF8583 using I2C of 
> lpc2106 using Keil C compiler.But I am unable to start the I2C.
> 
> Pl. help if u have time.
> Regards,
> Santosh Jha

Here is an outline of a polled i2c function, there is more that goes
around this, but you can probably figure the rest out:


#define I2CONSET       (*((volatile unsigned char *) 0xE001C000))
#define I2STAT         (*((volatile unsigned char *) 0xE001C004))
#define I2DAT          (*((volatile unsigned char *) 0xE001C008))
#define I2ADR          (*((volatile unsigned char *) 0xE001C00C))
#define I2SCLH         (*((volatile unsigned short*) 0xE001C010))
#define I2SCLL         (*((volatile unsigned short*) 0xE001C014))
#define I2CONCLR       (*((volatile unsigned char *) 0xE001C018))


#define ENABLE_I2C_PINS	( PINSEL0 = ((PINSEL0&0xFFFFFF0F) |
PINSEL0_02_SCL | PINSEL0_03_SDA ) )
#define ENABLE_I2C_IRQ  ( VICIntEnable = (0x1 << I2C_IRQ) )
#define DISABLE_I2C_IRQ ( VICIntEnClr  = (0x1 << I2C_IRQ) )
#define ENABLE_I2C_AA	( I2CONSET |= (0x1 << 2))
#define DISABLE_I2C_AA	( I2CONCLR = (0x1 << 2))
#define I2C_BIT_RATE(rate)  (I2SCLH = I2SCLL =
((Uint16)(PERIPH_FREQ/2/rate)+10))
#define I2C_SEND_START	(I2CONSET |= (0x1 << 5))
#define I2C_SEND_STOP	(I2CONSET = (0x1 << 4))
#define I2C_CLR_START	(I2CONCLR = (0x1 << 5))
#define I2C_CLR_SI		(I2CONCLR = (0x1 << 3))

void i2c_transfer (void) {
	Uint8 code;
	Uint8 transferComplete = 0;
	i2c_pos = 0;	
	
	while(!transferComplete) {
		code = I2STAT;
		switch(code) {
			/***** MASTER TX MODE *****/
			case 0x08:  // First Start Transmitted
			case 0x10:	// Repeated Start
				// Write address and tell if it is read or write
				I2DAT = (i2c_address << 1) | i2c_RdnWr;
				I2CONCLR = (0x1 << 3);		// Clear SI
				break;
			case 0x18:	// Start + Wr sent, ACK received
			case 0x20:	// Start + Wr sent, Not ACK received
			case 0x28:  // Data byte sent, ACK recieved
			case 0x30:  // Data byte sent, Not Ack received
				if(i2c_bytesRemaining > 0) {
					I2DAT = i2c_buffer[i2c_pos++];
					i2c_bytesRemaining--;
					I2CONCLR = (0x1 << 5);
				}
				else if(i2c_rxBytesRemaining == 0) {
					I2C_SEND_STOP; // Send Stop
					I2CONCLR = (0x1 << 5);
					transferComplete = 1;
				}
				else { // Change from master_tx to master_rx
					i2c_RdnWr = (~i2c_RdnWr)&0x1;
					i2c_pos = 0;
					i2c_rxWrPos = 0;
					i2c_rxComplete = 0;
					I2C_SEND_START;
				}
				I2CONCLR = (0x1 << 3);		// Clear SI
				break;		
			case 0x38:	// Arbitration Lost, try again 
				I2C_SEND_START;
				I2CONCLR = (0x1 << 3);		// Clear SI	
				break;
			/***** MASTER RX MODE *****/	
			case	0x40:	// SLA+R HAS BEEN SENT; ACK RECEIVED				
				if(i2c_rxBytesRemaining != 0)
					ENABLE_I2C_AA;
				else
					DISABLE_I2C_AA;				
				I2CONCLR = (0x1 << 3) | (0x1 << 5);	// Clear SI and START
				break;
			case	0x48: // SLA+R has been send; not ack received
				// Try again
				I2C_SEND_START;
				I2C_CLR_SI;
				break;
				
			case	0x50:	// DATA BYTE RECEIVED, ACK RETURNED
				i2c_rxBuffer[i2c_rxWrPos] = I2DAT;
				i2c_rxWrPos++;
				i2c_rxBytesRemaining--;
				if(i2c_rxBytesRemaining != 0)
					ENABLE_I2C_AA;
				else
					DISABLE_I2C_AA;
				I2CONCLR = (0x1 << 3) | (0x1 << 5);	// Clear SI and START
				break;
			case	0x58:	// DATA BYTE RECEIVED; NOT ACT RETURNED
				i2c_rxComplete = 1; // Done receiving all requested data
				transferComplete = 1;
				I2C_CLR_START;
				I2C_SEND_STOP;
				I2C_CLR_SI;
				break;										
		}
	}
}

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.