/* Read register 0 (second count) of DS3231 * * This program reads register at address 0 in the DS3231, the second count, * repetitively and dump the data to the LEDs. Since the second count uses * binary coded decimal format, the LEDs will count up from 0 to 9 in binary * and wrap around to 0. * * Built and tested with Keil MDK-ARM v5.24a and TM4C_DFP v1.1.0 */ #include "TM4C123GH6PM.h" void delayMs(int n); void I2C1_init(void); unsigned char I2C1_byteRead(int slaveAddr, unsigned char memAddr, unsigned char* data); #define SLAVE_ADDR 0x68 // 1101 000. int main(void) { unsigned char readback; unsigned char error; SYSCTL->RCGCGPIO |= 0x02; // enable clock to GPIOB readback = SYSCTL->RCGCGPIO; // enable PORTB 3-0 as output for LEDs GPIOB->DIR |= 0x0F; // set PORTB 3-0 as output pins GPIOB->DEN |= 0x0F; // set PORTB 3-0 as digital pins I2C1_init(); for (;;) { // use second count to turn LEDs on or off error = I2C1_byteRead(SLAVE_ADDR, 0, &readback); if (error) for(;;) ; // replace with error handling GPIOB->DATA = readback; delayMs(200); } } 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 = 24; // 100 kHz @ 50 MHz } static int I2C1_wait_till_done(void) { while(I2C1->MCS & 1); // wait until I2C1 master is not busy return I2C1->MCS & 0xE; // return I2C1 error code } // Read one byte of data at memAddr unsigned char I2C1_byteRead(int slaveAddr, unsigned char memAddr, unsigned char* data) { unsigned char error; // read: S-(addr+w)-ACK-memAddr-ACK-R-(addr+r)-ACK-data-NACK-P I2C1->MSA = slaveAddr << 1; I2C1->MDR = memAddr; I2C1->MCS = 3; // S-(addr+w)-ACK-memAddr-ACK error = I2C1_wait_till_done(); if (error) return error; I2C1->MSA = (slaveAddr << 1) + 1; // restart: -R-(addr+r)-ACK I2C1->MCS = 7; // -S-(addr+r)-NACK-P error = I2C1_wait_till_done(); if (error) return error; *data = I2C1->MDR; while(I2C1->MCS & 0x40); // wait until bus is not busy error = I2C1->MCS & 0xE; return error; } /* delay n milliseconds (50 MHz CPU clock) */ void delayMs(int n) { int i, j; for(i = 0 ; i< n; i++) for(j = 0; j < 6265; j++) {} /* do nothing for 1 ms */ }