/* p9_1: I2C to DS1307 single byte writes */ /* This program communicate with the DS1307 Real-time Clock via I2C. */ /* The seconds, minutes, and hours are written one byte at a time. */ /* Set the time to 16:58:55 */ /* DS1307 parameters: fmax = 100 kHz */ /* I2C1SCL PA6 I2C1SDA PA7 */ #include "TM4C123GH6PM.h" #define SLAVE_ADDR 0x68 /* 1100 1000 */ void I2C1_init(void); char I2C1_byteWrite(int slaveAddr, char memAddr, char data); int main(void) { char timeDateToSet[7] = {0x55, 0x58, 0x16, 0x01, 0x19, 0x10, 0x09}; I2C1_init(); /* write hour, minute, second with single byte writes */ I2C1_byteWrite(SLAVE_ADDR, 0, timeDateToSet[0]); /* second */ I2C1_byteWrite(SLAVE_ADDR, 1, timeDateToSet[1]); /* minute */ I2C1_byteWrite(SLAVE_ADDR, 2, timeDateToSet[2]); /* hour */ 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 */ } /* Write one byte only */ /* byte write: S-(saddr+w)-ACK-maddr-ACK-data-ACK-P */ char I2C1_byteWrite(int slaveAddr, char memAddr, char data) { char error; /* 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 */ I2C1->MDR = data; I2C1->MCS = 5; /* -data-ACK-P */ error = I2C_wait_till_done(); /* wait until write is complete */ while(I2C1->MCS & 0x40); /* wait until bus is not busy */ error = I2C1->MCS & 0xE; if (error) return error; return 0; /* no error */ }