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