#include "hw_sysctl.h"
#include "hw_ints.h"
#include "hw_memmap.h"
#include "hw_types.h"
#include "hw_gpio.h"
#include "i2c.h"
#include "interrupt.h"
#include "sysctl.h"
#include "systick.h"
#include "flash.h"
#include "gpio.h"
#include "LCD_LM.h"
#include "timer.h"
static volatile unsigned long g_ulState = STATE_IDLE;
static unsigned char *g_pucData = 0;
static unsigned long g_ulCount = 0;
void I2CIntHandler(void)
{
// Determine what to do based on the current state.
switch(g_ulState)
{
// The idle state.
case STATE_IDLE:
{
// Clear the I2C interrupt.
I2CMasterIntClear(I2C0_MASTER_BASE);
// There is nothing to be done.
break;
}
// The state for the middle of a burst write.
case STATE_SET_NEXT:
{
// Write the next byte to the data register.
I2CMasterDataPut(I2C0_MASTER_BASE, *g_pucData++);
g_ulCount--;
// Continue the burst write.
I2CMasterControl(I2C0_MASTER_BASE,
I2C_MASTER_CMD_BURST_SEND_CONT);
// If there is one byte left, set the next state to the final write state.
if(g_ulCount == 1)
{
g_ulState = STATE_SET_FINAL;
}
// This state is done.
break;
}
// The state for the final write of a burst sequence.
case STATE_SET_FINAL:
{
// Write the final byte to the data register.
I2CMasterDataPut(I2C0_MASTER_BASE, *g_pucData++);
g_ulCount--;
// Finish the burst write.
I2CMasterControl(I2C0_MASTER_BASE,
I2C_MASTER_CMD_BURST_SEND_FINISH);
// The next state is to wait for the burst write to complete.
g_ulState = STATE_SEND_ACK;
// This state is done.
break;
}
// Send a read request, looking for the ACK to indicate that the write
// is done.
case STATE_SEND_ACK:
{
// Put the I2C master into receive mode.
I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, 0x6B, true);
// Perform a single byte read.
I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
// The next state is the wait for the ack.
g_ulState = STATE_WAIT_ACK;
// This state is done.
break;
}
// Wait for an ACK on the read after a write.
case STATE_WAIT_ACK:
{
// See if there was an error on the previously issued read.
if(I2CMasterErr(I2C0_MASTER_BASE) == I2C_MASTER_ERR_NONE)
{
// Read the byte received.
I2CMasterDataGet(I2C0_MASTER_BASE);
// There was no error, so the state machine is now idle.
g_ulState = STATE_IDLE;
// This state is done.
break;
}
}
// The state for a single byte read.
case STATE_GET_ONE:
{
// Put the I2C master into receive mode.
I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, 0x6B, true);
// Perform a single byte read.
I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
delay();
// The next state is the wait for final read state.
g_ulState = STATE_GET_WAIT;
// This state is done.
break;
}
// The state for the start of a burst read.
case STATE_GET_FIRST:
{
// Put the I2C master into receive mode.
I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, 0x6B, true);
// Start the burst receive.
I2CMasterControl(I2C0_MASTER_BASE,
I2C_MASTER_CMD_BURST_RECEIVE_START);
delay();
// The next state is the middle of the burst read.
g_ulState = STATE_GET_NEXT;
// This state is done.
break;
}
// The state for the middle of a burst read.
case STATE_GET_NEXT:
{
// Read the received character.
*g_pucData++ = I2CMasterDataGet(I2C0_MASTER_BASE);
g_ulCount--;
// Continue the burst read.
I2CMasterControl(I2C0_MASTER_BASE,
I2C_MASTER_CMD_BURST_RECEIVE_CONT);
delay();
// If there are two characters left to be read, make the next
// state be the end of burst read state.
if(g_ulCount == 1)
{
g_ulState = STATE_GET_FINAL;
}
// This state is done.
break;
}
// The state for the end of a burst read.
case STATE_GET_FINAL:
{
// Read the received character.
*g_pucData++ = I2CMasterDataGet(I2C0_MASTER_BASE);
g_ulCount--;
// Finish the burst read.
I2CMasterControl(I2C0_MASTER_BASE,
I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
delay();
// The next state is the wait for final read state.
g_ulState = STATE_GET_WAIT;
// This state is done.
break;
}
// This state is for the final read of a single or burst read.
case STATE_GET_WAIT:
{
// Read the received character.
*g_pucData++ = I2CMasterDataGet(I2C0_MASTER_BASE);
g_ulCount--;
// The state machine is now idle.
g_ulState = STATE_IDLE;
// This state is done.
break;
}
}
}
// Write to RTC
void
Write(unsigned char *pucData, unsigned long ulOffset,
unsigned long ulCount)
{
// Save the data buffer to be written.
g_pucData = pucData;
g_ulCount = ulCount;
// Set the next state of the interrupt state machine based on the number of
// bytes to write.
if(ulCount != 1)
{
g_ulState = STATE_SET_NEXT;
}
else
{
g_ulState = STATE_SET_FINAL;
}
// Set the slave address and setup for a transmit operation.
I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, 0x6B | (ulOffset >> 8), false);
// Place the address to be written in the data register.
I2CMasterDataPut(I2C0_MASTER_BASE, ulOffset);
// Start the burst cycle, writing the address as the first byte.
I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);
// Wait until the I2C interrupt state machine is idle.
while(g_ulState != STATE_IDLE)
{
}
}
// Read from RTC
void
Read(unsigned char *pucData, unsigned long ulOffset,
unsigned long ulCount)
{
// Save the data buffer to be read.
g_pucData = pucData;
g_ulCount = ulCount;
// Set the next state of the interrupt state machine based on the number of
// bytes to read.
if(ulCount == 1)
{
g_ulState = STATE_GET_ONE;
}
else
{
g_ulState = STATE_GET_FIRST;
}
// Start with a dummy write to get the address set in the EEPROM.
I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, 0x6B | (ulOffset >> 8), false);
// Place the address to be written in the data register.
I2CMasterDataPut(I2C0_MASTER_BASE, ulOffset);
// Perform a single send, writing the address as the only byte.
I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);
// Wait until the I2C interrupt state machine is idle.
while(g_ulState != STATE_IDLE)
{
}
}
int main(void)
{
unsigned char pucData[16];
int i=0;
// Set the clocking to run directly from the crystal.
SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_6MHZ);
// Enable the peripherals used by this example.
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
// Enable Port B of GPIO
// SDA 0 Bit 3 Output
// SCL 0 Bit 2 Output
GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3);
// Initializes the I2C Master block with clock
I2CMasterInitExpClk( I2C0_MASTER_BASE, SysCtlClockGet(), false);
// Enable the I2C interrupt.
IntEnable(INT_I2C0);
// Registers a function to be called when an interrupt occurs in I2C
I2CIntRegister(I2C0_MASTER_BASE, &I2CIntHandler);
// Enable the I2C Master Interrupt
I2CMasterIntEnable(I2C0_MASTER_BASE);
LCD_Init();
pucData[0] = 0x00;
Write(pucData, 1, 1); //osc en
pucData[0]=0x01;
Write(pucData, 0, 1); //RTC READ=1
pucData[0]=0x00;
Write(pucData, 0, 1);//RTC READ=0
Read(pucData[2],0x02,7);// READ TIME
for(i=2;i<=15;i++)
{
LCD_DIS(pucData[i], 1, i);
}
}
|