/* p9_2: I2C burst write to DS1337 */ /* This program communicates with the DS1337 Real-time Clock via I2C. The time, day (of the week), date, month and year are written using burst 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_burstWrite(unsigned char slaveAddr, unsigned char memAddr, int byteCount, unsigned char* data, int* cnt); void delayUs(int n); int main(void) { unsigned char timeDateToSet[] = {0x55, 0x58, 0x16, 0x01, 0x19, 0x10, 0x09}; int count; int rv; I2C1_init(); /* use burst write to write day, date, month, and year */ rv = I2C1_burstWrite(SLAVE_ADDR, 0, 7, timeDateToSet, &count); if (rv) 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 */ I2C1->C1 = 0x80; /* enable I2C1 */ } /* Use burst write to write multiple bytes to consecutive memory locations. * Burst write: S-(saddr+w)-ACK-maddr-ACK-data-ACK-data-ACK-...-data-ACK-P */ int I2C1_burstWrite(unsigned char slaveAddr, unsigned char memAddr, int byteCount, unsigned char* data, int* cnt) { int retry = 1000; *cnt = 0; 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 */ while (byteCount-- > 0) { 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; (*cnt)++; } /* 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++) ; } }