- #include "hc32_ddl.h"
- /*******************************************************************************
- * Local type definitions ('typedef')
- ******************************************************************************/
- /*******************************************************************************
- * Local pre-processor symbols/macros ('#define')
- ******************************************************************************/
- /* Define I2C unit used for the example */
- #define I2C_CH (M4_I2C1)
- /* Define E2PROM device address */
- #define E2_ADDRESS 0x50u
- /* AT24C02 page length is 8byte*/
- #define PAGE_LEN 8u
- /* Define test address for read and write */
- #define DATA_TEST_ADDR 0x00u
- /* Define port and pin for SDA and SCL */
- #define I2C1_SCL_PORT (PortC)
- #define I2C1_SCL_PIN (Pin04)
- #define I2C1_SDA_PORT (PortC)
- #define I2C1_SDA_PIN (Pin05)
- #define TIMEOUT 0x10000ul
- #define I2C_RET_OK 0u
- #define I2C_RET_ERROR 1u
- #define GENERATE_START 0x00u
- #define GENERATE_RESTART 0x01u
- #define E2_ADDRESS_W 0x00u
- #define E2_ADDRESS_R 0x01u
- /* LED0 Port/Pin definition */
- #define LED0_PORT (PortE)
- #define LED0_PIN (Pin06)
- /* LED1 Port/Pin definition */
- #define LED1_PORT (PortA)
- #define LED1_PIN (Pin07)
- /* LED0~1 toggle definition */
- #define LED0_TOGGLE() (PORT_Toggle(LED0_PORT, LED0_PIN))
- #define LED1_TOGGLE() (PORT_Toggle(LED1_PORT, LED1_PIN))
- /*******************************************************************************
- * Global variable definitions (declared in header file with 'extern')
- ******************************************************************************/
- /*******************************************************************************
- * Local function prototypes ('static')
- ******************************************************************************/
- /*******************************************************************************
- * Local variable definitions ('static')
- ******************************************************************************/
- /*******************************************************************************
- * Function implementation - global ('extern') and local ('static')
- ******************************************************************************/
- /**
- ******************************************************************************
- ** \brief Send start or restart condition
- **
- ** \param none
- **
- ** \retval Process result
- ** - I2C_RET_ERROR Send failed
- ** - I2C_RET_OK Send success
- ******************************************************************************/
- static uint8_t E2_StartOrRestart(uint8_t u8Start)
- {
- uint32_t u32TimeOut = TIMEOUT;
- en_flag_status_t enFlagBusy = Reset;
- en_flag_status_t enFlagStartf = Reset;
- /* generate start or restart signal */
- if(GENERATE_START == u8Start)
- {
- /* Wait I2C bus idle */
- while(Set == I2C_GetStatus(I2C_CH, I2C_SR_BUSY))
- {
- if(0ul == (u32TimeOut--))
- {
- return I2C_RET_ERROR;
- }
- }
- I2C_GenerateStart(I2C_CH , Enable);
- }
- else
- {
- /* Clear start status flag */
- I2C_ClearStatus(I2C_CH, I2C_CLR_STARTFCLR);
- /* Send restart condition */
- I2C_GenerateReStart(I2C_CH , Enable);
- }
- /* Judge if start success*/
- u32TimeOut = TIMEOUT;
- while(1)
- {
- enFlagBusy = I2C_GetStatus(I2C_CH, I2C_SR_BUSY);
- enFlagStartf = I2C_GetStatus(I2C_CH, I2C_SR_STARTF);
- if(enFlagBusy && enFlagStartf)
- {
- break;
- }
- if(0ul == (u32TimeOut--))
- {
- return I2C_RET_ERROR;
- }
- }
- return I2C_RET_OK;
- }
- /**
- ******************************************************************************
- ** \brief Send e2prom device address
- **
- ** \param u16Adr The slave address
- **
- ** \retval Process result
- ** - I2C_RET_ERROR Send failed
- ** - I2C_RET_OK Send success
- ******************************************************************************/
- static uint8_t E2_SendAdr(uint8_t u8Adr)
- {
- uint32_t u32TimeOut = TIMEOUT;
- /* Wait tx buffer empty */
- while(Reset == I2C_GetStatus(I2C_CH, I2C_SR_TEMPTYF))
- {
- if(0ul == (u32TimeOut--))
- {
- return I2C_RET_ERROR;
- }
- }
- /* Send I2C address */
- I2C_SendData(I2C_CH, u8Adr);
- if(E2_ADDRESS_W == (u8Adr & 0x01u))
- {
- /* If in master transfer process, Need wait transfer end*/
- uint32_t u32TimeOut = TIMEOUT;
- while(Reset == I2C_GetStatus(I2C_CH, I2C_SR_TENDF))
- {
- if(0ul == (u32TimeOut--))
- {
- return I2C_RET_ERROR;
- }
- }
- }
- /* Check ACK */
- u32TimeOut = TIMEOUT;
- while(Set == I2C_GetStatus(I2C_CH, I2C_SR_NACKDETECTF))
- {
- if(0ul == (u32TimeOut--))
- {
- return I2C_RET_ERROR;
- }
- }
- return I2C_RET_OK;
- }
- /**
- ******************************************************************************
- ** \brief Send data address to e2prom
- **
- ** \param u8DataAdr Data address to be send
- **
- ** \retval Process result
- ** - I2C_RET_ERROR Send failed
- ** - I2C_RET_OK Send success
- ******************************************************************************/
- static uint8_t E2_SendDataAdr(uint8_t u8DataAdr)
- {
- uint32_t u32TimeOut = TIMEOUT;
- /* Wait tx buffer empty */
- u32TimeOut = TIMEOUT;
- while(Reset == I2C_GetStatus(I2C_CH, I2C_SR_TEMPTYF))
- {
- if(0ul == (u32TimeOut--))
- {
- return I2C_RET_ERROR;
- }
- }
- /* Send one byte data */
- I2C_SendData(I2C_CH, u8DataAdr);
- /* Wait transfer end*/
- u32TimeOut = TIMEOUT;
- while(Reset == I2C_GetStatus(I2C_CH, I2C_SR_TENDF))
- {
- if(0ul == (u32TimeOut--))
- {
- return I2C_RET_ERROR;
- }
- }
- /* Check ACK */
- u32TimeOut = TIMEOUT;
- while(Set == I2C_GetStatus(I2C_CH, I2C_SR_NACKDETECTF))
- {
- if(0ul == (u32TimeOut--))
- {
- return I2C_RET_ERROR;
- }
- }
- return I2C_RET_OK;
- }
- /**
- ******************************************************************************
- ** \brief Send data to e2prom
- **
- ** \param pTxData Pointer to the data buffer
- ** \param u32Size Data size
- **
- ** \retval Process result
- ** - I2C_RET_ERROR Send failed
- ** - I2C_RET_OK Send success
- ******************************************************************************/
- static uint8_t E2_WriteData(uint8_t *pTxData, uint32_t u32Size)
- {
- uint32_t u32TimeOut = TIMEOUT;
- while(u32Size--)
- {
- /* Wait tx buffer empty */
- u32TimeOut = TIMEOUT;
- while(Reset == I2C_GetStatus(I2C_CH, I2C_SR_TEMPTYF))
- {
- if(0ul == (u32TimeOut--))
- {
- return I2C_RET_ERROR;
- }
- }
- /* Send one byte data */
- I2C_SendData(I2C_CH, *pTxData++);
- /* Wait transfer end*/
- u32TimeOut = TIMEOUT;
- while(Reset == I2C_GetStatus(I2C_CH, I2C_SR_TENDF))
- {
- if(0ul == (u32TimeOut--))
- {
- return I2C_RET_ERROR;
- }
- }
- /* Check ACK */
- u32TimeOut = TIMEOUT;
- while(Set == I2C_GetStatus(I2C_CH, I2C_SR_NACKDETECTF))
- {
- if(0ul == (u32TimeOut--))
- {
- return I2C_RET_ERROR;
- }
- }
- }
- return I2C_RET_OK;
- }
- /**
- ******************************************************************************
- ** \brief Receive data from e2prom
- **
- ** \param pTxData Pointer to the data buffer
- ** \param u32Size Data size
- **
- ** \retval Process result
- ** - I2C_RET_ERROR Send failed
- ** - I2C_RET_OK Send success
- ******************************************************************************/
- static uint8_t E2_RevData(uint8_t *pRxData, uint32_t u32Size)
- {
- uint32_t u32TimeOut = TIMEOUT;
- for(uint32_t i=0ul; i<u32Size; i++)
- {
- /* if the last byte receive, need config NACK*/
- if(i == (u32Size - 1ul))
- {
- I2C_NackConfig(I2C_CH, Enable);
- }
- /* Wait receive full flag*/
- u32TimeOut = TIMEOUT;
- while(Reset == I2C_GetStatus(I2C_CH, I2C_SR_RFULLF))
- {
- if(0ul == (u32TimeOut--))
- {
- return I2C_RET_ERROR;
- }
- }
- /* read data from register*/
- *pRxData++ = I2C_ReadData(I2C_CH);
- }
- return I2C_RET_OK;
- }
- /**
- ******************************************************************************
- ** \brief General stop condition to e2prom
- **
- ** \param None
- **
- ** \retval Process result
- ** - I2C_RET_ERROR Send failed
- ** - I2C_RET_OK Send success
- ******************************************************************************/
- uint8_t E2_Stop(void)
- {
- uint32_t u32TimeOut;
- /* Wait I2C bus busy */
- u32TimeOut = TIMEOUT;
- while(Reset == I2C_GetStatus(I2C_CH, I2C_SR_BUSY))
- {
- if(0ul == (u32TimeOut--))
- {
- return I2C_RET_ERROR;
- }
- }
- I2C_GenerateStop(I2C_CH, Enable);
- /* Wait STOPF */
- u32TimeOut = TIMEOUT;
- while(Reset == I2C_GetStatus(I2C_CH, I2C_SR_STOPF))
- {
- if(0ul == (u32TimeOut--))
- {
- return I2C_RET_ERROR;
- }
- }
- return I2C_RET_OK;
- }
- /**
- ******************************************************************************
- ** \brief Initialize the I2C peripheral for e2prom
- **
- ** \param None
- **
- ** \retval Process result
- ** - I2C_RET_ERROR failed
- ** - I2C_RET_OK success
- ******************************************************************************/
- uint8_t E2_Initialize(void)
- {
- stc_i2c_init_t stcI2cInit;
- stc_clk_freq_t stcClkFreq;
- I2C_DeInit(I2C_CH);
- /* Get system clock frequency */
- CLK_GetClockFreq(&stcClkFreq);
- MEM_ZERO_STRUCT(stcI2cInit);
- stcI2cInit.u32Pclk3 = stcClkFreq.pclk3Freq;
- stcI2cInit.enI2cMode = I2cMaster;
- stcI2cInit.u32Baudrate = 100000ul;
- stcI2cInit.u32SclTime = 0ul;
- I2C_Init(I2C_CH, &stcI2cInit);
- I2C_Cmd(I2C_CH, Enable);
- return I2C_RET_OK;
- }
- /**
- ******************************************************************************
- ** \brief Initialize the system clock for the sample
- **
- ** \param None
- **
- ** \retval None
- ******************************************************************************/
- static void SysClkIni(void)
- {
- en_clk_sys_source_t enSysClkSrc;
- stc_clk_sysclk_cfg_t stcSysClkCfg;
- stc_clk_xtal_cfg_t stcXtalCfg;
- stc_clk_mpll_cfg_t stcMpllCfg;
- MEM_ZERO_STRUCT(enSysClkSrc);
- MEM_ZERO_STRUCT(stcSysClkCfg);
- MEM_ZERO_STRUCT(stcXtalCfg);
- MEM_ZERO_STRUCT(stcMpllCfg);
- /* Set bus clk div. */
- stcSysClkCfg.enHclkDiv = ClkSysclkDiv1; // Max 168MHz
- stcSysClkCfg.enExclkDiv = ClkSysclkDiv2; // Max 84MHz
- stcSysClkCfg.enPclk0Div = ClkSysclkDiv1; // Max 168MHz
- stcSysClkCfg.enPclk1Div = ClkSysclkDiv2; // Max 84MHz
- stcSysClkCfg.enPclk2Div = ClkSysclkDiv4; // Max 60MHz
- stcSysClkCfg.enPclk3Div = ClkSysclkDiv4; // Max 42MHz
- stcSysClkCfg.enPclk4Div = ClkSysclkDiv2; // Max 84MHz
- CLK_SysClkConfig(&stcSysClkCfg);
- /* Switch system clock source to MPLL. */
- /* Use Xtal32 as MPLL source. */
- stcXtalCfg.enMode = ClkXtalModeOsc;
- stcXtalCfg.enDrv = ClkXtalLowDrv;
- stcXtalCfg.enFastStartup = Enable;
- CLK_XtalConfig(&stcXtalCfg);
- CLK_XtalCmd(Enable);
- /* MPLL config. */
- stcMpllCfg.pllmDiv = 1u;
- stcMpllCfg.plln =42u;
- stcMpllCfg.PllpDiv = 2u;
- stcMpllCfg.PllqDiv = 2u;
- stcMpllCfg.PllrDiv = 2u;
- CLK_SetPllSource(ClkPllSrcXTAL);
- CLK_MpllConfig(&stcMpllCfg);
- /* flash read wait cycle setting */
- EFM_Unlock();
- EFM_SetLatency(EFM_LATENCY_5);
- EFM_Lock();
- /* Enable MPLL. */
- CLK_MpllCmd(Enable);
- /* Wait MPLL ready. */
- while(Set != CLK_GetFlagStatus(ClkFlagMPLLRdy))
- {
- ;
- }
- /* Switch system clock source to MPLL. */
- CLK_SetSysClkSource(CLKSysSrcMPLL);
- }
- /**
- ******************************************************************************
- ** \brief Judge the result. LED0 toggle when result is error status.
- **
- ** \param u8Result
- **
- ** \retval None
- ******************************************************************************/
- static void JudgeResult(uint8_t u8Result)
- {
- if(I2C_RET_ERROR == u8Result)
- {
- while(1)
- {
- LED0_TOGGLE();
- Ddl_Delay1ms(500ul);
- }
- }
- }
- /**
- *******************************************************************************
- ** \brief Main function of template project
- **
- ** \param None
- **
- ** \retval int32_t return value, if needed
- **
- ******************************************************************************/
- int32_t main(void)
- {
- uint8_t u8TxBuf[PAGE_LEN];
- uint8_t u8RxBuf[PAGE_LEN];
- uint32_t i;
- uint8_t u8Ret = I2C_RET_OK;
- stc_port_init_t stcPortInit;
- for(i=0ul; i<PAGE_LEN; i++)
- {
- u8TxBuf[i] = (uint8_t)i+1u;
- }
- memset(u8RxBuf, 0x00, PAGE_LEN);
- /* Initialize system clock*/
- SysClkIni();
- /*initiallize LED port*/
- MEM_ZERO_STRUCT(stcPortInit);
- stcPortInit.enPinMode = Pin_Mode_Out;
- stcPortInit.enExInt = Enable;
- stcPortInit.enPullUp = Enable;
- /* LED0 Port/Pin initialization */
- PORT_Init(LED0_PORT, LED0_PIN, &stcPortInit);
- /* LED1 Port/Pin initialization */
- PORT_Init(LED1_PORT, LED1_PIN, &stcPortInit);
- /* Initialize I2C port*/
- PORT_SetFunc(I2C1_SCL_PORT, I2C1_SCL_PIN, Func_I2c1_Scl, Disable);
- PORT_SetFunc(I2C1_SDA_PORT, I2C1_SDA_PIN, Func_I2c1_Sda, Disable);
- /* Enable I2C Peripheral*/
- PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_I2C1, Enable);
- /* Initialize I2C peripheral and enable function*/
- E2_Initialize();
- /* E2prom byte write*/
- u8Ret = E2_StartOrRestart(GENERATE_START);
- JudgeResult(u8Ret);
- u8Ret = E2_SendAdr((uint8_t)(E2_ADDRESS<<1u)|E2_ADDRESS_W);
- JudgeResult(u8Ret);
- u8Ret = E2_SendDataAdr(DATA_TEST_ADDR);
- JudgeResult(u8Ret);
- u8Ret = E2_WriteData(u8TxBuf, 1u);
- JudgeResult(u8Ret);
- u8Ret = E2_Stop();
- JudgeResult(u8Ret);
- /* 5mS delay for e2prom*/
- Ddl_Delay1ms(5ul);
- /* E2prom ramdom read*/
- u8Ret = E2_StartOrRestart(GENERATE_START);
- JudgeResult(u8Ret);
- u8Ret = E2_SendAdr((uint8_t)(E2_ADDRESS<<1u)|E2_ADDRESS_W);
- JudgeResult(u8Ret);
- u8Ret = E2_SendDataAdr(DATA_TEST_ADDR);
- JudgeResult(u8Ret);
- u8Ret = E2_StartOrRestart(GENERATE_RESTART);
- JudgeResult(u8Ret);
- u8Ret = E2_SendAdr((uint8_t)(E2_ADDRESS<<1u)|E2_ADDRESS_R);
- JudgeResult(u8Ret);
- u8Ret = E2_RevData(u8RxBuf, 1u);
- JudgeResult(u8Ret);
- u8Ret = E2_Stop();
- JudgeResult(u8Ret);
- /* Compare the data */
- if(0x01u != u8RxBuf[0])
- {
- /* e2prom byte write error*/
- while(1)
- {
- LED0_TOGGLE();
- Ddl_Delay1ms(500ul);
- }
- }
- /* 5mS delay for e2prom*/
- Ddl_Delay1ms(5ul);
- /* E2prom page write*/
- u8Ret = E2_StartOrRestart(GENERATE_START);
- JudgeResult(u8Ret);
- u8Ret = E2_SendAdr((uint8_t)(E2_ADDRESS<<1u)|E2_ADDRESS_W);
- JudgeResult(u8Ret);
- u8Ret = E2_SendDataAdr(DATA_TEST_ADDR);
- JudgeResult(u8Ret);
- u8Ret = E2_WriteData(u8TxBuf, PAGE_LEN);
- JudgeResult(u8Ret);
- u8Ret = E2_Stop();
- JudgeResult(u8Ret);
- /* 5mS delay for e2prom*/
- Ddl_Delay1ms(5ul);
- /* E2prom sequential read*/
- u8Ret = E2_StartOrRestart(GENERATE_START);
- JudgeResult(u8Ret);
- u8Ret = E2_SendAdr((uint8_t)(E2_ADDRESS<<1u)|E2_ADDRESS_W);
- JudgeResult(u8Ret);
- u8Ret = E2_SendDataAdr(DATA_TEST_ADDR);
- JudgeResult(u8Ret);
- u8Ret = E2_StartOrRestart(GENERATE_RESTART);
- JudgeResult(u8Ret);
- u8Ret = E2_SendAdr((uint8_t)(E2_ADDRESS<<1u)|E2_ADDRESS_R);
- JudgeResult(u8Ret);
- u8Ret = E2_RevData(u8RxBuf, PAGE_LEN);
- JudgeResult(u8Ret);
- u8Ret = E2_Stop();
- JudgeResult(u8Ret);
- /* Compare the data */
- for(i=0ul; i<PAGE_LEN; i++)
- {
- if(u8TxBuf[i] != u8RxBuf[i])
- {
- /* e2prom page write error*/
- while(1)
- {
- LED0_TOGGLE();
- Ddl_Delay1ms(500ul);
- }
- }
- }
- /* e2prom sample success*/
- while(1)
- {
- LED1_TOGGLE();
- Ddl_Delay1ms(500ul);
- }
- }
- /*******************************************************************************
- * EOF (not truncated)
- ******************************************************************************/
效果图:
板子上LED2闪烁,读写正常。