RTC DS1307 on EduARM4 Trainer Board

Figure:DS1307 Connectons
Note
- Short 1 & 2 and 3 & 4 of J6 on the EduARM4 Trainer Board
Source Code
-
/* -
* I2C to DS1307 single byte writes -
* This program communicates with the DS1307 Real-time Clock via I2C. -
* -
* The DS1307 has a total of 64 bytes of RAM space with addresses 00–3FH. -
* The first seven locations, 00–06, are set aside for RTC values of Time and Date. -
* The next byte is used for the control register. It is located at address 0x07. -
* That leaves 56 bytes, from addresses 0x08 to 0x3F, available for general-purpose data storage. -
* That means the entire 64 bytes of RAM are accessible directly for read or write -
* -
*/ -
/* DS1307 parameters: fmax = 100 kHz -
* I2C1SCL PA6 -
* I2C1SDA PA7 -
* -
*/ -
#include <stdint.h> -
#include "inc/tm4c123gh6pm.h" -
#define MAX_BUF_SIZE 56 -
#define SLAVE_ADDR 0x68 /* 1100 1000 */ -
#define I2C_START_ADDR 0x08 -
void I2C1_init(void);
-
char I2C1_byteWrite(int slaveAddr, char memAddr, char data);
-
char I2C1_read(int slaveAddr, char memAddr, int byteCount, char* data);
-
char readBuf[MAX_BUF_SIZE];
-
int main(void)
-
{ -
char err, i;
-
char writeBuf;
-
writeBuf = I2C_START_ADDR;
-
I2C1_init();
-
/* write 56 bytes with single byte writes */ -
for( i = 0; i < MAX_BUF_SIZE; i++) {
-
err = I2C1_byteWrite(SLAVE_ADDR, writeBuf++, i);
-
if(err) break;
-
} -
if( err ) {
-
; /* Handle error condition */
-
} else {
-
/* uses burst read to read 56 bytes of data */ -
err = I2C1_read(SLAVE_ADDR, I2C_START_ADDR, MAX_BUF_SIZE, readBuf);
-
} -
for(;;) {
-
; -
} -
} -
/* initialize I2C1 as master and the port pins */ -
void I2C1_init(void)
-
{ -
SYSCTL_RCGCI2C_R |= 0x02; /* enable clock to I2C1 */
-
SYSCTL_RCGCGPIO_R |= 0x01; /* enable clock to GPIOA */
-
/* PORTA 7, 6 for I2C1 */ -
GPIO_PORTA_AFSEL_R |= 0xC0; /* PORTA 7, 6 for I2C1 */
-
GPIO_PORTA_PCTL_R &= ~0xFF000000; /* PORTA 7, 6 for I2C1 */
-
GPIO_PORTA_PCTL_R |= 0x33000000;
-
GPIO_PORTA_DEN_R |= 0xC0; /* PORTA 7, 6 as digital pins */
-
GPIO_PORTA_ODR_R |= 0x80; /* PORTA 7 as open drain */
-
I2C1_MCR_R = 0x10; /* master mode */
-
I2C1_MTPR_R = 7; /* 100 kHz @ 16 MHz */
-
} -
/* 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_R & 1)
-
; /* wait until I2C master is not busy */
-
return I2C1_MCS_R & 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_R = slaveAddr << 1;
-
I2C1_MDR_R = memAddr;
-
I2C1_MCS_R = 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_R = data;
-
I2C1_MCS_R = 5; /* -data-ACK-P */
-
error = I2C_wait_till_done(); /* wait until write is complete */
-
while( I2C1_MCS_R & 0x40 )
-
; /* wait until bus is not busy */
-
error = I2C1_MCS_R & 0xE;
-
if(error) return error;
-
return 0; /* no error */
-
} -
/* Read memory */ -
/* read: S-(saddr+w)-ACK-maddr-ACK-R-(saddr+r)-ACK-data-ACK-data-ACK-...-data-NACK-P */ -
char I2C1_read(int slaveAddr, char memAddr, int byteCount, char* data)
-
{ -
char error;
-
if (byteCount <= 0)
-
return -1; /* no read was performed */
-
/* send slave address and starting address */ -
I2C1_MSA_R = slaveAddr << 1;
-
I2C1_MDR_R = memAddr;
-
I2C1_MCS_R = 3; /* S-(saddr+w)-ACK-maddr-ACK */
-
error = I2C_wait_till_done();
-
if(error)
-
return error;
-
/* to change bus from write to read, send restart with slave addr */ -
I2C1_MSA_R = (slaveAddr << 1) + 1; /* restart: -R-(saddr+r)-ACK */
-
if( byteCount == 1 ) /* if last byte, don't ack */
-
I2C1_MCS_R = 7; /* -data-NACK-P */
-
else /* else ack */
-
I2C1_MCS_R = 0xB; /* -data-ACK- */
-
error = I2C_wait_till_done();
-
if(error) return error;
-
*data++ = I2C1_MDR_R; /* store the data received */
-
if( --byteCount == 0 ) { /* if single byte read, done */
-
while( I2C1_MCS_R & 0x40 )
-
; /* wait until bus is not busy */
-
return 0; /* no error */
-
} -
/* read the rest of the bytes */ -
while( byteCount > 1 ) {
-
I2C1_MCS_R = 9; /* -data-ACK- */
-
error = I2C_wait_till_done();
-
if(error) return error;
-
byteCount--; -
*data++ = I2C1_MDR_R; /* store data received */
-
} -
I2C1_MCS_R = 5; /* -data-NACK-P */
-
error = I2C_wait_till_done();
-
*data = I2C1_MDR_R; /* store data received */
-
while( I2C1_MCS_R & 0x40 )
-
; /* wait until bus is not busy */
-
return 0; /* no error */
-
}
Recent Comments