/* p9_2: I2C to DS1307 multi-byte burst write */ /* This program communicate with the DS1307 Real-time Clock via I2C. The day (of the week), date, month and year are written using burst write. */ /* It sets the date to Monday Oct. 19th, 2009 */ /* DS1307 parameters: fmax = 100 kHz */ /* I2C1SCL PA6 I2C1SDA PA7 */ #include "TM4C123GH6PM.h" #define SLAVE_ADDR 0x68 /* 0110 1000 */ void I2C1_init(void); char I2C1_burstWrite(int slaveAddr, char memAddr, int byteCount, char* data); int main(void) { char timeDateToSet[7] = {0x55, 0x58, 0x16, 0x01, 0x19, 0x10, 0x09}; I2C1_init(); /* use burst write to write day, date, month, and year */ I2C1_burstWrite(SLAVE_ADDR, 3, 4, &timeDateToSet[3]); for (;;) { } } /* initialize I2C1 as master and the port pins */ void I2C1_init(void) { SYSCTL->RCGCI2C |= 0x02; /* enable clock to I2C1 */ SYSCTL->RCGCGPIO |= 0x01; /* enable clock to GPIOA */ /* PORTA 7, 6 for I2C1 */ GPIOA->AFSEL |= 0xC0; /* PORTA 7, 6 for I2C1 */ GPIOA->PCTL &= ~0xFF000000; /* PORTA 7, 6 for I2C1 */ GPIOA->PCTL |= 0x33000000; GPIOA->DEN |= 0xC0; /* PORTA 7, 6 as digital pins */ GPIOA->ODR |= 0x80; /* PORTA 7 as open drain */ I2C1->MCR = 0x10; /* master mode */ I2C1->MTPR = 7; /* 100 kHz @ 16 MHz */ } /* This function is called by the startup assembly code to perform system specific initialization tasks. */ void SystemInit(void) { /* Grant coprocessor access */ /* This is required since TM4C123G has a floating point coprocessor */ SCB->CPACR |= 0x00f00000; } /* Wait until I2C master is not busy and return error code */ /* If there is no error, return 0 */ static int I2C_wait_till_done(void) { while(I2C1->MCS & 1); /* wait until I2C master is not busy */ return I2C1->MCS & 0xE; /* return I2C error code */ } /* Use burst write to write multiple bytes to consecutive locations */ /* burst write: S-(saddr+w)-ACK-maddr-ACK-data-ACK-data-ACK-...-data-ACK-P */ char I2C1_burstWrite(int slaveAddr, char memAddr, int byteCount, char* data) { char error; if (byteCount <= 0) return -1; /* no write was performed */ /* send slave address and starting address */ I2C1->MSA = slaveAddr << 1; I2C1->MDR = memAddr; I2C1->MCS = 3; /* S-(saddr+w)-ACK-maddr-ACK */ error = I2C_wait_till_done(); /* wait until write is complete */ if (error) return error; /* send data one byte at a time */ while (byteCount > 1) { I2C1->MDR = *data++; /* write the next byte */ I2C1->MCS = 1; /* -data-ACK- */ error = I2C_wait_till_done(); if (error) return error; byteCount--; } /* send last byte and a STOP */ I2C1->MDR = *data++; /* write the last byte */ I2C1->MCS = 5; /* -data-ACK-P */ error = I2C_wait_till_done(); while(I2C1->MCS & 0x40); /* wait until bus is not busy */ if (error) return error; return 0; /* no error */ }