/* p9_1: I2C single byte write to DS1337 This program communicates with the DS1337 Real-time Clock via I2C. DS1337 is a newer version of DS1307. It operates from 1.8V to 5.5V. It has century and alarms added. The time day (of the week), date, month and year are written using single byte write. It sets the date to Monday Oct. 19th, 2009. DS1337 I2C parameters: fmax = 100 kHz, SCL PTE1, SDA PTE0 */ #include "MKL25Z4.h" #define SLAVE_ADDR 0x68 /* 1101 000. */ #define ERR_NONE 0 #define ERR_NO_ACK 0x01 #define ERR_ARB_LOST 0x02 #define ERR_BUS_BUSY 0x03 void I2C1_init(void); int I2C1_byteWrite(unsigned char slaveAddr, unsigned char memAddr, unsigned char data); void delayUs(int n); int main(void) { unsigned char timeDateToSet[] = {0x55, 0x58, 0x16, 0x01, 0x19, 0x10, 0x09}; int rv; int i; I2C1_init(); for (i = 0; i < 7; i++) { rv = I2C1_byteWrite(SLAVE_ADDR, 0, timeDateToSet[0]); if (rv != ERR_NONE) for(;;) ; /* replace with error handling */ } for (;;) { } } /* initialize I2C1 and the port pins */ void I2C1_init(void) { SIM->SCGC4 |= 0x80; /* turn on clock to I2C1 */ SIM->SCGC5 |= 0x2000; /* turn on clock to PortE */ PORTE->PCR[1] = 0x0600; /* PTE1 I2C1 SCL */ PORTE->PCR[0] = 0x0600; /* PTE0 I2C1 SDA */ I2C1->C1 = 0; /* stop I2C1 */ I2C1->S = 2; /* Clear interrupt flag */ I2C1->F = 0x1C; /* set clock to 97.09KHz @13.981MHz bus clock */ /* See Table 9-4. */ I2C1->C1 = 0x80; /* enable I2C1 */ } /* Write a single byte to slave memory. * write: S-(saddr+w)-ACK-maddr-ACK-data-ACK-P */ int I2C1_byteWrite(unsigned char slaveAddr, unsigned char memAddr, unsigned char data) { int retry = 1000; while (I2C1->S & 0x20) { /* wait until bus is available */ if (--retry <= 0) return ERR_BUS_BUSY; delayUs(100); } /* send start */ I2C1->C1 |= 0x10; /* Tx on */ I2C1->C1 |= 0x20; /* become master */ /* send slave address and write flag */ I2C1->D = slaveAddr << 1; while(!(I2C1->S & 0x02)); /* wait for transfer complete */ I2C1->S |= 0x02; /* clear IF */ if (I2C1->S & 0x10) { /* arbitration lost */ I2C1->S |= 0x10; /* clear IF */ return ERR_ARB_LOST; } if (I2C1->S & 0x01) /* got NACK from slave */ return ERR_NO_ACK; /* send memory address */ I2C1->D = memAddr; while(!(I2C1->S & 0x02)); /* wait for transfer complete */ I2C1->S |= 0x02; /* clear IF */ if (I2C1->S & 0x01) /* got NACK from slave */ return ERR_NO_ACK; /* send data */ I2C1->D = data; while(!(I2C1->S & 0x02)); /* wait for transfer complete */ I2C1->S |= 0x02; /* clear IF */ if (I2C1->S & 0x01) /* got NACK from slave */ return ERR_NO_ACK; /* stop */ I2C1->C1 &= ~0x30; return ERR_NONE; } /* delay n microseconds * The CPU core clock is set to MCGFLLCLK at 41.94 MHz in SystemInit(). */ void delayUs(int n) { int i; int j; for(i = 0 ; i < n; i++) { for(j = 0; j < 7; j++) ; } }