/**************************************************************************//**
* [url=home.php?mod=space&uid=288409]@file[/url] main.c
* [url=home.php?mod=space&uid=895143]@version[/url] V3.00
* $Revision: 4 $
* $Date: 15/05/18 4:22p $
* [url=home.php?mod=space&uid=247401]@brief[/url] NUC230_240 Series I2C Driver Sample Code for EEPROM 24LC64
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#include <stdio.h>
#include "NUC230_240.h"
#define PLLCON_SETTING CLK_PLLCON_72MHz_HXT
#define PLL_CLOCK 72000000
/*---------------------------------------------------------------------------------------------------------*/
/* Global variables */
/*---------------------------------------------------------------------------------------------------------*/
volatile uint8_t g_u8DeviceAddr;
volatile uint8_t g_au8TxData[3];
volatile uint8_t g_u8RxData;
volatile uint8_t temp;
volatile uint8_t g_u8DataLen;
volatile uint8_t g_u8EndFlag = 0;
typedef void (*I2C_FUNC)(uint32_t u32Status);
static I2C_FUNC s_I2C0HandlerFn = NULL;
/*---------------------------------------------------------------------------------------------------------*/
/* I2C0 IRQ Handler */
/*---------------------------------------------------------------------------------------------------------*/
void I2C0_IRQHandler(void)
{
uint32_t u32Status;
u32Status = I2C_GET_STATUS(I2C0);
if(I2C_GET_TIMEOUT_FLAG(I2C0))
{
/* Clear I2C0 Timeout Flag */
I2C_ClearTimeoutFlag(I2C0);
}
else
{
if(s_I2C0HandlerFn != NULL)
s_I2C0HandlerFn(u32Status);
}
}
/*---------------------------------------------------------------------------------------------------------*/
/* I2C Rx Callback Function */
/*---------------------------------------------------------------------------------------------------------*/
void I2C_MasterRx(uint32_t u32Status)
{
if(u32Status == 0x08) /* START has been transmitted and prepare SLA+W */
{
I2C_SET_DATA(I2C0, (g_u8DeviceAddr << 1)); /* Write SLA+W to Register I2CDAT */
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
}
else if(u32Status == 0x18) /* SLA+W has been transmitted and ACK has been received */
{
I2C_SET_DATA(I2C0, g_au8TxData[g_u8DataLen++]);
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
}
else if(u32Status == 0x20) /* SLA+W has been transmitted and NACK has been received */
{
I2C_STOP(I2C0);
I2C_START(I2C0);
}
else if(u32Status == 0x28) /* DATA has been transmitted and ACK has been received */
{
if(g_u8DataLen != 1)
{
I2C_SET_DATA(I2C0, g_au8TxData[g_u8DataLen++]);
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
}
else
{
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA_SI);
}
}
else if(u32Status == 0x10) /* Repeat START has been transmitted and prepare SLA+R */
{
I2C_SET_DATA(I2C0, ((g_u8DeviceAddr << 1) | 0x01)); /* Write SLA+R to Register I2CDAT */
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
}
else if(u32Status == 0x40) /* SLA+R has been transmitted and ACK has been received */
{
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
}
else if(u32Status == 0x58) /* DATA has been received and NACK has been returned */
{
g_u8RxData = (unsigned char) I2C_GET_DATA(I2C0);
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STO_SI);
g_u8EndFlag = 1;
}
else
{
/* TO DO */
printf("Status 0x%x is NOT processed\n", u32Status);
}
}
/*---------------------------------------------------------------------------------------------------------*/
/* I2C Tx Callback Function */
/*---------------------------------------------------------------------------------------------------------*/
void I2C_MasterTx(uint32_t u32Status)
{
if(u32Status == 0x08) /* START has been transmitted */
{
I2C_SET_DATA(I2C0, g_u8DeviceAddr << 1); /* Write SLA+W to Register I2CDAT */
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
}
else if(u32Status == 0x18) /* SLA+W has been transmitted and ACK has been received */
{
I2C_SET_DATA(I2C0, g_au8TxData[g_u8DataLen++]);
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
}
else if(u32Status == 0x20) /* SLA+W has been transmitted and NACK has been received */
{
I2C_STOP(I2C0);
I2C_START(I2C0);
}
else if(u32Status == 0x28) /* DATA has been transmitted and ACK has been received */
{
if(g_u8DataLen != 2)
{
I2C_SET_DATA(I2C0, g_au8TxData[g_u8DataLen++]);
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
}
else
{
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STO_SI);
g_u8EndFlag = 1;
}
}
else
{
/* TO DO */
printf("Status 0x%x is NOT processed\n", u32Status);
}
}
void SYS_Init(void)
{
/*---------------------------------------------------------------------------------------------------------*/
/* Init System Clock */
/*---------------------------------------------------------------------------------------------------------*/
/* Enable Internal RC 22.1184MHz clock */
CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);
/* Waiting for Internal RC clock ready */
CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);
/* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));
/* Enable external XTAL 12MHz clock */
CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);
/* Waiting for external XTAL clock ready */
CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);
/* Set core clock as PLL_CLOCK from PLL */
CLK_SetCoreClock(PLL_CLOCK);
/* Enable UART module clock */
CLK_EnableModuleClock(UART0_MODULE);
/* Enable I2C0 module clock */
CLK_EnableModuleClock(I2C0_MODULE);
/* Select UART module clock source */
CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));
/*---------------------------------------------------------------------------------------------------------*/
/* Init I/O Multi-function */
/*---------------------------------------------------------------------------------------------------------*/
/* Set GPB multi-function pins for UART0 RXD and TXD */
SYS->GPB_MFP = SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD;
/* Set GPA multi-function pins for I2C0 SDA and SCL */
SYS->GPA_MFP = SYS_GPA_MFP_PA8_I2C0_SDA | SYS_GPA_MFP_PA9_I2C0_SCL;
}
void UART0_Init()
{
/*---------------------------------------------------------------------------------------------------------*/
/* Init UART */
/*---------------------------------------------------------------------------------------------------------*/
/* Reset IP */
SYS_ResetModule(UART0_RST);
/* Configure UART0 and set UART0 Baudrate */
UART_Open(UART0, 115200);
}
void I2C0_Close(void)
{
/* Disable I2C0 interrupt and clear corresponding NVIC bit */
I2C_DisableInt(I2C0);
NVIC_DisableIRQ(I2C0_IRQn);
/* Disable I2C0 and close I2C0 clock */
I2C_Close(I2C0);
CLK_DisableModuleClock(I2C0_MODULE);
}
void I2C0_Init(void)
{
/* Open I2C module and set bus clock */
I2C_Open(I2C0, 100000);
/* Get I2C0 Bus Clock */
printf("I2C clock %d Hz\n", I2C_GetBusClockFreq(I2C0));
/* Enable I2C interrupt */
I2C_EnableInt(I2C0);
NVIC_EnableIRQ(I2C0_IRQn);
}
uint8_t dec_to_bcd(int dec)
{
uint8_t bcd=((dec / 10) << 4) | (dec % 10);
return bcd;
}
int bcd_to_dec(uint8_t hex)
{
int dec = ((hex & 0xF0) >> 4) * 10 + (hex & 0x0F);
return dec;
}
unsigned char DS3231_RTC_Read(unsigned char reg)
{
g_u8DeviceAddr = 0x68;
g_au8TxData[0] = reg; //register
g_u8DataLen = 0;
g_u8EndFlag = 0;
/* I2C function to write data to slave */
s_I2C0HandlerFn = (I2C_FUNC)I2C_MasterRx;
/* I2C as master sends START signal */
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA);
/* Wait I2C Tx Finish */
while(g_u8EndFlag == 0);
g_u8EndFlag = 0;
return bcd_to_dec(g_u8RxData);
}
void DS3231_RTC_Write(unsigned char reg,unsigned char value)
{
g_u8DeviceAddr = 0x68;
g_au8TxData[0] = reg; //register
g_au8TxData[1] = dec_to_bcd(value); //value
g_u8DataLen = 0;
g_u8EndFlag = 0;
/* I2C function to write data to slave */
s_I2C0HandlerFn = (I2C_FUNC)I2C_MasterTx;
/* I2C as master sends START signal */
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA);
/* Wait I2C Tx Finish */
while(g_u8EndFlag == 0);
g_u8EndFlag = 0;
}
#define Seconds 0x00
#define Miutes 0x01
#define Hours 0x02
#define Day 0x03
#define Date 0x04
#define Month 0x05
#define Year 0x06
/*---------------------------------------------------------------------------------------------------------*/
/* Main Function */
/*---------------------------------------------------------------------------------------------------------*/
int32_t main(void)
{
unsigned char Seconds_temp;
/* Unlock protected registers */
SYS_UnlockReg();
/* Init System, IP clock and multi-function I/O */
SYS_Init();
/* Lock protected registers */
SYS_LockReg();
/* Init UART0 for printf */
UART0_Init();
/*
This sample code sets I2C bus clock to 100kHz. Then, accesses EEPROM 24LC64 with Byte Write
and Byte Read operations, and check if the read data is equal to the programmed data.
*/
printf("+------------------------------------------------------------+\n");
printf("| NUC230_240 I2C Driver Sample Code with DS3231 |\n");
printf("+------------------------------------------------------------+\n");
/* Init I2C0 to access EEPROM */
I2C0_Init();
DS3231_RTC_Write(Hours,01);
DS3231_RTC_Write(Miutes,01);
DS3231_RTC_Write(Seconds,01);
while(1)
{
if(Seconds_temp!=DS3231_RTC_Read(Seconds))
{
Seconds_temp=DS3231_RTC_Read(Seconds);
printf("%d: ",DS3231_RTC_Read(Hours));
printf("%d: ",DS3231_RTC_Read(Miutes));
printf("%d\n\r",Seconds_temp);
}
}
}
|