#include "HC32_i2c_24cxx.h"
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/* Define I2C unit used for the example */
#define I2C_UNIT (M4_I2C1)
/* Define E2PROM device address */
#define E2_ADDRESS (0x50u)
/* AT24C02 page length */
#define E2_PAGE_LEN (8u)
#define E2_MEM_ADR_LEN (1u)
/* Define test address for read and write */
#define DATA_TEST_ADDR (0x08u)
/* Define port and pin for SDA and SCL */
#define I2C_SCL_PORT (PortA)
#define I2C_SCL_PIN (Pin09)
#define I2C_SDA_PORT (PortA)
#define I2C_SDA_PIN (Pin08)
#define I2C_GPIO_SCL_FUNC (Func_I2c1_Scl)
#define I2C_GPIO_SDA_FUNC (Func_I2c1_Sda)
#define I2C_FCG_USE (PWC_FCG1_PERIPH_I2C1)
#define TIMEOUT (0x40000ul)
/**
******************************************************************************
** \brief I2C memory write
**
** \param u8DevAddr The slave address
** \param u16MemAddr The memory address
** \param pu8Data Pointer to the data buffer
** \param u32Size Data size
** \param u32TimeOut Time out count
** \retval en_result_t Enumeration value:
** - Ok: Success
** - Error: Receive NACK
** - ErrorTimeout: Time out
******************************************************************************/
static en_result_t I2C_Mem_Write(uint16_t u8DevAddr, uint16_t u16MemAddr, uint8_t *pu8Data, uint32_t u32Size, uint32_t u32TimeOut)
{
en_result_t enRet;
uint16_t u16MemAddrTemp;
// u16MemAddrTemp = ((u16MemAddr >> 8) & 0xFFul) + ((u16MemAddr << 8) & 0xFF00ul);
u16MemAddrTemp = u16MemAddr;
I2C_Cmd(I2C_UNIT, Enable);
I2C_SoftwareResetCmd(I2C_UNIT, Enable);
I2C_SoftwareResetCmd(I2C_UNIT, Disable);
enRet = I2C_Start(I2C_UNIT,u32TimeOut);
if(Ok == enRet)
{
enRet = I2C_TransAddr(I2C_UNIT, u8DevAddr, I2CDirTrans, u32TimeOut);
if(Ok == enRet)
{
enRet = I2C_TransData(I2C_UNIT, (uint8_t *)&u16MemAddrTemp, E2_MEM_ADR_LEN, u32TimeOut);
if(Ok == enRet)
{
enRet = I2C_TransData(I2C_UNIT, pu8Data, u32Size, u32TimeOut);
}
}
}
I2C_Stop(I2C_UNIT,u32TimeOut);
I2C_Cmd(I2C_UNIT, Disable);
return enRet;
}
/**
******************************************************************************
** \brief I2C memory read
**
** \param u8DevAddr The slave address
** \param u16MemAddr The memory address
** \param pu8Data Pointer to the data buffer
** \param u32Size Data size
** \param u32TimeOut Time out count
** \retval en_result_t Enumeration value:
** - Ok: Success
** - ErrorTimeout: Time out
******************************************************************************/
static en_result_t I2C_Mem_Read(uint8_t u8DevAddr, uint16_t u16MemAddr, uint8_t *pu8Data, uint32_t u32Size, uint32_t u32TimeOut)
{
en_result_t enRet;
uint16_t u16MemAddrTemp;
// u16MemAddrTemp = ((u16MemAddr << 8) & 0xFF00ul) + ((u16MemAddr >> 8) & 0xFFul);
u16MemAddrTemp = u16MemAddr;
I2C_Cmd(I2C_UNIT, Enable);
I2C_SoftwareResetCmd(I2C_UNIT, Enable);
I2C_SoftwareResetCmd(I2C_UNIT, Disable);
enRet = I2C_Start(I2C_UNIT,u32TimeOut);
if(Ok == enRet)
{
enRet = I2C_TransAddr(I2C_UNIT, (uint8_t)u8DevAddr, I2CDirTrans, u32TimeOut);
if(Ok == enRet)
{
enRet = I2C_TransData(I2C_UNIT, (uint8_t *)&u16MemAddrTemp, E2_MEM_ADR_LEN, u32TimeOut);
if(Ok == enRet)
{
enRet = I2C_Restart(I2C_UNIT,u32TimeOut);
if(Ok == enRet)
{
if(1ul == u32Size)
{
I2C_AckConfig(I2C_UNIT, I2c_NACK);
}
enRet = I2C_TransAddr(I2C_UNIT, (uint8_t)u8DevAddr, I2CDirReceive, u32TimeOut);
if(Ok == enRet)
{
enRet = I2C_MasterDataReceiveAndStop(I2C_UNIT, pu8Data, u32Size, u32TimeOut);
}
I2C_AckConfig(I2C_UNIT, I2c_ACK);
}
}
}
}
if(Ok != enRet)
{
I2C_Stop(I2C_UNIT,u32TimeOut);
}
I2C_Cmd(I2C_UNIT, Disable);
return enRet;
}
/**
******************************************************************************
** \brief Initialize the I2C peripheral for e2prom
** \param None
** \retval en_result_t Enumeration value:
** - Ok: Success
** - ErrorTimeout: Time out
******************************************************************************/
static en_result_t E2_Initialize(void)
{
stc_i2c_init_t stcI2cInit;
en_result_t enRet;
float32_t fErr;
I2C_DeInit(I2C_UNIT);
MEM_ZERO_STRUCT(stcI2cInit);
stcI2cInit.u32ClockDiv = I2C_CLK_DIV32;
stcI2cInit.u32Baudrate = 100000ul;
stcI2cInit.u32SclTime = 0ul;
enRet = I2C_Init(I2C_UNIT, &stcI2cInit, &fErr);
I2C_BusWaitCmd(I2C_UNIT, Enable);
return enRet;
}
static void HC32_I2C_24CXX_Delay_us(uint8_t us)
{
uint16_t i = 0;
//通过示波器测量进行校准
while(us--)
{
for(i=0;i<1200;i++);
}
}
void HC32_I2C_24Cxx_INT(void)
{
/* Initialize I2C port*/
PORT_SetFunc(I2C_SCL_PORT, I2C_SCL_PIN, I2C_GPIO_SCL_FUNC, Disable);
PORT_SetFunc(I2C_SDA_PORT, I2C_SDA_PIN, I2C_GPIO_SDA_FUNC, Disable);
/* Enable I2C Peripheral*/
PWC_Fcg1PeriphClockCmd(I2C_FCG_USE, Enable);
/* Initialize I2C peripheral and enable function*/
E2_Initialize();
HC32_I2C_24CXX_Delay_us(200);
HC32_I2C_24CXX_Delay_us(200);
}
uint8_t HC32_I2C_24CXX_READ_one_BYTE(uint16_t addr)
{
uint8_t a[1] = {0};
I2C_Mem_Read(E2_ADDRESS, addr, a, 1u, TIMEOUT);
return a[0];
}
/*******************************************************************************
* 函 数 名 : HC32_I2C_24CXX_write_one_page
* 函数功能 : 在AT24CXX指定页写入一页数据
* 输 入 : addr:写入数据的目的地址
dat:要写入的数据
* 输 出 : 无
*******************************************************************************/
void HC32_I2C_24CXX_write_one_page(uint16_t addr, uint8_t *dat)
{
I2C_Mem_Write(E2_ADDRESS, addr, dat, E2_PAGE_LEN, TIMEOUT);
HC32_I2C_24CXX_Delay_us(200);
}
/*******************************************************************************
* 函 数 名 : HC32_I2C_24CXX_read_one_page
* 函数功能 : 在AT24CXX指定页读一页数据
* 输 入 : addr:读数据的目的地址
dat:要读的数据
* 输 出 : 无
*******************************************************************************/
void HC32_I2C_24CXX_read_one_page(uint16_t addr, uint8_t *dat)
{
I2C_Mem_Read(E2_ADDRESS, addr, dat, E2_PAGE_LEN, TIMEOUT);
HC32_I2C_24CXX_Delay_us(200);
}
/*******************************************************************************
* 函 数 名 :HC32_I2C_24CXX_write_bytes
* 函数功能 : 在AT24CXX指定地址写入一段数据
* 输 入 : addr:写入数据的目的地址
pdat:要写入的数据首地址
Len:数据长度
* 输 出 : 无
*******************************************************************************/
uint8_t tem[8] = {0};
void HC32_I2C_24CXX_write_bytes(uint16_t addr, uint8_t* pdat, uint8_t Len)
{
uint8_t Temp[8];
uint16_t pdat_id_S = addr % 8;
uint8_t i, pages;
if(pdat_id_S)
{
for(i = 0; i < pdat_id_S; ++i)
{
Temp[i] = HC32_I2C_24CXX_READ_one_BYTE(addr - pdat_id_S + i);
HC32_I2C_24CXX_Delay_us(100);
}
for (; i < 8; ++i)
{
Temp[i] = *pdat;
++pdat;
--Len;
if(!Len)
{
HC32_I2C_24CXX_write_one_page(addr - pdat_id_S, Temp);
HC32_I2C_24CXX_Delay_us(100);
return;
}
}
HC32_I2C_24CXX_write_one_page(addr - pdat_id_S, Temp);
addr = addr + 8 - pdat_id_S;
}
pages = Len / 8;
for (i = 0; i < pages; ++i)
{
HC32_I2C_24CXX_write_one_page(addr, pdat);
addr += 8;
pdat += 8;
Len -= 8;
HC32_I2C_24CXX_Delay_us(100);
}
if(!Len)
return;
for (i = 0; i < Len; ++i)
{
Temp[i] = *pdat;
++pdat;
}
for(; i < 8; ++i)
{
// Temp[i] = HC32_I2C_24CXX_READ_one_BYTE(addr + i);
Temp[i] = 0;
}
HC32_I2C_24CXX_Delay_us(100);
HC32_I2C_24CXX_write_one_page(addr, Temp);
HC32_I2C_24CXX_Delay_us(100);
HC32_I2C_24CXX_read_one_page(addr,tem);
}
/*******************************************************************************
* 函 数 名 : HC32_I2C_24CXX_read_bytes
* 函数功能 : 在AT24CXX指定地址读出一段数据
* 输 入 : addr:写入数据的目的地址
pbuffer:要写入的缓冲区首地址
Len:数据长度
* 输 出 : 无
*******************************************************************************/
void HC32_I2C_24CXX_read_bytes(uint16_t addr, uint8_t *pbuffer, uint8_t Len)
{
uint16_t pdat_id_S = addr % 8;
uint8_t i, pages;
if(pdat_id_S)
{
for(i = pdat_id_S; i < 8; ++i)
{
*pbuffer++ = HC32_I2C_24CXX_READ_one_BYTE(addr++);
--Len;
if(!Len)
return;
HC32_I2C_24CXX_Delay_us(100);
}
}
pages = Len / 8;
for (i = 0; i < pages; ++i)
{
HC32_I2C_24CXX_read_one_page(addr, pbuffer);
addr += 8;
pbuffer += 8;
Len -= 8;
HC32_I2C_24CXX_Delay_us(100);
}
if(!Len)
return;
I2C_Mem_Read(E2_ADDRESS, addr, pbuffer,Len, TIMEOUT);
HC32_I2C_24CXX_Delay_us(100);
// i2c_mem_read(ADDR_24C02, addr, pbuffer, Len);
pbuffer += Len;
*pbuffer = '\0';
}
//测试用
uint8_t u8RxBuf[E2_PAGE_LEN];
void test_write_and_read(void)
{
uint8_t u8TxBuf[E2_PAGE_LEN];
uint32_t i;
for(i=0ul; i<E2_PAGE_LEN; i++)
{
u8TxBuf[i] = (uint8_t)i+1u;
}
memset(u8RxBuf, 0x00, E2_PAGE_LEN);
/* E2prom byte write*/
I2C_Mem_Write(E2_ADDRESS, DATA_TEST_ADDR, u8TxBuf, 5u, TIMEOUT);
/* 5mS delay for e2prom*/
HC32_I2C_24CXX_Delay_us(20ul);
/* E2prom ramdom read*/
I2C_Mem_Read(E2_ADDRESS, DATA_TEST_ADDR, u8RxBuf, 5u, TIMEOUT);
}
#ifndef _HC32_i2c_24cxx_H
#define _HC32_i2c_24cxx_H
#include "main.h"
#include "hc32_ddl.h"
#include "uart_config.h"
void HC32_I2C_24Cxx_INT(void);
void test_write_and_read(void);
void HC32_I2C_24CXX_read_bytes(uint16_t addr, uint8_t* pbuffer, uint8_t Len);
void HC32_I2C_24CXX_write_bytes(uint16_t addr, uint8_t* pdat, uint8_t Len);
#endif