/************************************************************************ Project: Welling Motor Control Paltform Filename: i2c_master.c Partner Filename: i2c_master.h Description: I2C master driver Complier: IAR Embedded Workbench for ARM 8.40.2 CPU TYPE : GD32F30x ************************************************************************* Copyright (c) 2022 Welling Motor Technology(Shanghai) Co. Ltd. All rights reserved. ************************************************************************* ************************************************************************* Revising History (ECL of this file): M0_20170410, by liyue, create this file; ************************************************************************/ /************************************************************************ Beginning of File, do not put anything above here except notes Compiler Directives: *************************************************************************/ #ifndef _I2C_MASTER_C_ #define _I2C_MASTER_C_ #endif /************************************************************************ Included File *************************************************************************/ #include "i2c_master.h" #include "api_rt.h" #include "gd32f30x_dma.h" /************************************************************************* Exported Functions (N/A) *************************************************************************/ /************************************************************************* Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: *************************************************************************/ static UWORD i2c_pvt_uwWaitCnt = 0, i2c_pvt_uwWaitCnt2 = 0; void i2c_voWaitEEReady(UBYTE SlaveAddr) { /* Wait at least 5ms */ while (i2c_pvt_uwWaitCnt2 < 2) { i2c_pvt_uwWaitCnt++; if (i2c_pvt_uwWaitCnt == 10000) { i2c_pvt_uwWaitCnt2++; i2c_pvt_uwWaitCnt = 0; } } i2c_pvt_uwWaitCnt2 = 0; // /* GD MCU has ACK detect function */ // ULONG ulTimeCnt = 0; // UWORD uwTimeoutNum = 0, uwTimeoutNum2; // // while(!I2C_EE_ComuFltFlg) // { // /* write to EEPROM enable*/ // iGpio_Write(HW_GPIO_I2CWP_PIN,iGpio_LowLevel); // /* wait until I2C bus is idle */ // while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (++ulTimeCnt < I2C_SHORT_TIMEOUT)); // if(ulTimeCnt == I2C_SHORT_TIMEOUT) // { // uwTimeoutNum ++; // } // ulTimeCnt = 0; // /* send a start condition to I2C bus */ // i2c_start_on_bus(I2C0); // /* wait until SBSEND bit is set */ // while((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (++ulTimeCnt < I2C_SHORT_TIMEOUT)); // if(ulTimeCnt == I2C_SHORT_TIMEOUT) // { // uwTimeoutNum ++; // } // ulTimeCnt = 0; // /* send slave address to I2C bus */ // i2c_master_addressing(I2C0, SlaveAddr, I2C_TRANSMITTER); // /* wait until ADDSEND bit is set */ // while((!((i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) || (i2c_flag_get(I2C0, I2C_FLAG_AERR))))&& (++ulTimeCnt < I2C_SHORT_TIMEOUT)); // if(ulTimeCnt < I2C_SHORT_TIMEOUT) // { // if(i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) // { // ulTimeCnt = 0; // /* clear the bit of I2C_FLAG_ADDSEND */ // i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); // /* send a stop condition to I2C bus */ // i2c_stop_on_bus(I2C0); // /* wait until stop condition generate */ // while((I2C_CTL0(I2C0)&I2C_CTL0_STOP) && (++ulTimeCnt < I2C_SHORT_TIMEOUT)); // if(ulTimeCnt == I2C_SHORT_TIMEOUT) // { // uwTimeoutNum ++; // } // ulTimeCnt = 0; // /* exit the function */ // I2C_EE_ComuFltFlg = FALSE; // break; // } // else // { // /* clear the bit of I2C_FLAG_AERR */ // i2c_flag_clear(I2C0, I2C_FLAG_AERR); // /* send a stop condition to I2C bus */ // i2c_stop_on_bus(I2C0); // /* wait until stop condition generate */ // while((I2C_CTL0(I2C0)&I2C_CTL0_STOP) && (++ulTimeCnt < I2C_SHORT_TIMEOUT)); // if(ulTimeCnt == I2C_SHORT_TIMEOUT) // { // uwTimeoutNum ++; // } // ulTimeCnt = 0; // } // } // else // { // ulTimeCnt = 0; // uwTimeoutNum2 ++; // if(uwTimeoutNum2 > 4) // { // I2C_EE_ComuFltFlg = TRUE; // break; // } // } // // /* I2C communication timeout fault */ // if(uwTimeoutNum > 3 ) // { // I2C_EE_ComuFltFlg = TRUE; // } // } // /* write to EEPROM disable */ // iGpio_Write(HW_GPIO_I2CWP_PIN,iGpio_LowLevel); } /************************************************************************* Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: *************************************************************************/ void i2c_voDefaultWriteBuffer(void) { /* Parameter default value write*/ UWORD *I2C_pBuffer; UBYTE i; I2C_pBuffer = &Syspara2.stMotorPara.uwPolePairs.uwDefault1; for (i = 0; i < I2C_MOTOR_PARA_N_WORDS; i++) { I2C_ubWriteBuffer[I2C_MOTOR_PARA_ARDDR + 2 * i] = (UBYTE)(*I2C_pBuffer >> 8); I2C_ubWriteBuffer[I2C_MOTOR_PARA_ARDDR + 2 * i + 1] = (UBYTE)(*I2C_pBuffer); I2C_pBuffer += I2C_PBUFFER_NWORDS; /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ } I2C_pBuffer = &Syspara2.stBikePara.uwWheelPerimeter.uwDefault1; for (i = 0; i < I2C_BIKE_PARA_N_WORDS; i++) { I2C_ubWriteBuffer[I2C_BIKE_PARA_ARDDR + 2 * i] = (UBYTE)(*I2C_pBuffer >> 8); I2C_ubWriteBuffer[I2C_BIKE_PARA_ARDDR + 2 * i + 1] = (UBYTE)(*I2C_pBuffer); I2C_pBuffer += I2C_PBUFFER_NWORDS; /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ } I2C_pBuffer = &Syspara2.stMControlPara.ParaFirstSetFlg.uwDefault1; for (i = 0; i < I2C_MCONTROL_PARA_N_WORDS; i++) { I2C_ubWriteBuffer[I2C_MCONTROL_PARA_ARDDR + 2 * i] = (UBYTE)(*I2C_pBuffer >> 8); I2C_ubWriteBuffer[I2C_MCONTROL_PARA_ARDDR + 2 * i + 1] = (UBYTE)(*I2C_pBuffer); I2C_pBuffer += I2C_PBUFFER_NWORDS; /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ } I2C_pBuffer = &Syspara2.stSensorPara.uwTorSensorOffsetOrigin.uwDefault1; for (i = 0; i < I2C_SENSOR_PARA_N_WORDS; i++) { I2C_ubWriteBuffer[I2C_SENSOR_PARA_ARDDR + 2 * i] = (UBYTE)(*I2C_pBuffer >> 8); I2C_ubWriteBuffer[I2C_SENSOR_PARA_ARDDR + 2 * i + 1] = (UBYTE)(*I2C_pBuffer); I2C_pBuffer += I2C_PBUFFER_NWORDS; /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ } I2C_pBuffer = &Syspara2.stAssistPara.uwStartupGain.uwDefault1; for (i = 0; i < I2C_ASSIST_PARA_N_WORDS; i++) { I2C_ubWriteBuffer[I2C_ASSIST_PARA_ARDDR + 2 * i] = (UBYTE)(*I2C_pBuffer >> 8); I2C_ubWriteBuffer[I2C_ASSIST_PARA_ARDDR + 2 * i + 1] = (UBYTE)(*I2C_pBuffer); I2C_pBuffer += I2C_PBUFFER_NWORDS; /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ } I2C_pWriteBuffer = I2C_ubWriteBuffer; I2C_ubWriteBuffer[I2C_MOTOR_PARA_CRC_ARDDR] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_MOTOR_PARA_N_BYTES) >> 8); I2C_ubWriteBuffer[I2C_MOTOR_PARA_CRC_ARDDR + 1] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_MOTOR_PARA_N_BYTES)); I2C_pWriteBuffer = I2C_ubWriteBuffer + I2C_BIKE_PARA_ARDDR; /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_ubWriteBuffer[I2C_BIKE_PARA_CRC_ARDDR] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_BIKE_PARA_N_BYTES) >> 8); I2C_ubWriteBuffer[I2C_BIKE_PARA_CRC_ARDDR + 1] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_BIKE_PARA_N_BYTES)); I2C_pWriteBuffer = I2C_ubWriteBuffer + I2C_MCONTROL_PARA_ARDDR; /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_ubWriteBuffer[I2C_MCONTROL_PARA_CRC_ARDDR] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_MCONTROL_PARA_N_BYTES) >> 8); I2C_ubWriteBuffer[I2C_MCONTROL_PARA_CRC_ARDDR + 1] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_MCONTROL_PARA_N_BYTES)); I2C_pWriteBuffer = I2C_ubWriteBuffer + I2C_SENSOR_PARA_ARDDR; /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_ubWriteBuffer[I2C_SENSOR_PARA_CRC_ARDDR] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_SENSOR_PARA_N_BYTES) >> 8); I2C_ubWriteBuffer[I2C_SENSOR_PARA_CRC_ARDDR + 1] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_SENSOR_PARA_N_BYTES)); I2C_pWriteBuffer = I2C_ubWriteBuffer + I2C_ASSIST_PARA_ARDDR; /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_ubWriteBuffer[I2C_ASSIST_PARA_CRC_ARDDR] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_ASSIST_PARA_N_BYTES) >> 8); I2C_ubWriteBuffer[I2C_ASSIST_PARA_CRC_ARDDR + 1] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_ASSIST_PARA_N_BYTES)); } /************************************************************************* Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: *************************************************************************/ void i2c_voParaWriteBuffer(void) { /* Parameter real value write*/ UWORD *I2C_pBuffer; UBYTE i; I2C_pBuffer = &Syspara2.stMotorPara.uwPolePairs.uwDefault1; for (i = 0; i < I2C_MOTOR_PARA_N_WORDS; i++) { I2C_ubWriteBuffer[I2C_MOTOR_PARA_ARDDR + 2 * i] = (UBYTE)(*(I2C_pBuffer + 1) >> 8); /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_ubWriteBuffer[I2C_MOTOR_PARA_ARDDR + 2 * i + 1] = (UBYTE)(*(I2C_pBuffer + 1)); /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_pBuffer += I2C_PBUFFER_NWORDS; /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ } I2C_pBuffer = &Syspara2.stBikePara.uwWheelPerimeter.uwDefault1; for (i = 0; i < I2C_BIKE_PARA_N_WORDS; i++) { I2C_ubWriteBuffer[I2C_BIKE_PARA_ARDDR + 2 * i] = (UBYTE)(*(I2C_pBuffer + 1) >> 8); /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_ubWriteBuffer[I2C_BIKE_PARA_ARDDR + 2 * i + 1] = (UBYTE)(*(I2C_pBuffer + 1)); /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_pBuffer += I2C_PBUFFER_NWORDS; /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ } I2C_pBuffer = &Syspara2.stMControlPara.ParaFirstSetFlg.uwDefault1; for (i = 0; i < I2C_MCONTROL_PARA_N_WORDS; i++) { I2C_ubWriteBuffer[I2C_MCONTROL_PARA_ARDDR + 2 * i] = (UBYTE)(*(I2C_pBuffer + 1) >> 8); /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_ubWriteBuffer[I2C_MCONTROL_PARA_ARDDR + 2 * i + 1] = (UBYTE)(*(I2C_pBuffer + 1)); /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_pBuffer += I2C_PBUFFER_NWORDS; /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ } I2C_pBuffer = &Syspara2.stSensorPara.uwTorSensorOffsetOrigin.uwDefault1; for (i = 0; i < I2C_SENSOR_PARA_N_WORDS; i++) { I2C_ubWriteBuffer[I2C_SENSOR_PARA_ARDDR + 2 * i] = (UBYTE)(*(I2C_pBuffer + 1) >> 8); /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_ubWriteBuffer[I2C_SENSOR_PARA_ARDDR + 2 * i + 1] = (UBYTE)(*(I2C_pBuffer + 1)); /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_pBuffer += I2C_PBUFFER_NWORDS; /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ } I2C_pBuffer = &Syspara2.stAssistPara.uwStartupGain.uwDefault1; for (i = 0; i < I2C_ASSIST_PARA_N_WORDS; i++) { I2C_ubWriteBuffer[I2C_ASSIST_PARA_ARDDR + 2 * i] = (UBYTE)(*(I2C_pBuffer + 1) >> 8); /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_ubWriteBuffer[I2C_ASSIST_PARA_ARDDR + 2 * i + 1] = (UBYTE)(*(I2C_pBuffer + 1)); /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_pBuffer += I2C_PBUFFER_NWORDS; /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ } I2C_pWriteBuffer = I2C_ubWriteBuffer; I2C_ubWriteBuffer[I2C_MOTOR_PARA_CRC_ARDDR] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_MOTOR_PARA_N_BYTES) >> 8); I2C_ubWriteBuffer[I2C_MOTOR_PARA_CRC_ARDDR + 1] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_MOTOR_PARA_N_BYTES)); I2C_pWriteBuffer = I2C_ubWriteBuffer + I2C_BIKE_PARA_ARDDR; /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_ubWriteBuffer[I2C_BIKE_PARA_CRC_ARDDR] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_BIKE_PARA_N_BYTES) >> 8); I2C_ubWriteBuffer[I2C_BIKE_PARA_CRC_ARDDR + 1] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_BIKE_PARA_N_BYTES)); I2C_pWriteBuffer = I2C_ubWriteBuffer + I2C_MCONTROL_PARA_ARDDR; /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_ubWriteBuffer[I2C_MCONTROL_PARA_CRC_ARDDR] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_MCONTROL_PARA_N_BYTES) >> 8); I2C_ubWriteBuffer[I2C_MCONTROL_PARA_CRC_ARDDR + 1] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_MCONTROL_PARA_N_BYTES)); I2C_pWriteBuffer = I2C_ubWriteBuffer + I2C_SENSOR_PARA_ARDDR; /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_ubWriteBuffer[I2C_SENSOR_PARA_CRC_ARDDR] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_SENSOR_PARA_N_BYTES) >> 8); I2C_ubWriteBuffer[I2C_SENSOR_PARA_CRC_ARDDR + 1] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_SENSOR_PARA_N_BYTES)); I2C_pWriteBuffer = I2C_ubWriteBuffer + I2C_ASSIST_PARA_ARDDR; /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_ubWriteBuffer[I2C_ASSIST_PARA_CRC_ARDDR] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_ASSIST_PARA_N_BYTES) >> 8); I2C_ubWriteBuffer[I2C_ASSIST_PARA_CRC_ARDDR + 1] = (UBYTE)(i2c_uwCRCCcitt(I2C_pWriteBuffer, I2C_ASSIST_PARA_N_BYTES)); } /************************************************************************* Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: *************************************************************************/ void i2c_voHistoryWriteBuffer(void) { UWORD *I2C_pBuffer; UBYTE i; I2C_pBuffer = &Syspara2.stHistoryPara.uwAssModSelect.uwDefault1; for (i = 0; i < I2C_HISTORY_PARA_N_WORDS; i++) { I2C_ubHistoyWriteBuffer[I2C_HISTORY_PARA_ARDDR + 2 * i] = (UBYTE)(*(I2C_pBuffer + 1) >> 8); /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_ubHistoyWriteBuffer[I2C_HISTORY_PARA_ARDDR + 2 * i + 1] = (UBYTE)(*(I2C_pBuffer + 1)); /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_pBuffer += I2C_PBUFFER_NWORDS; /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ } I2C_pHistoryWriteBuffer = I2C_ubHistoyWriteBuffer; I2C_ubHistoyWriteBuffer[I2C_HISTORY_PARA_CRC_ARDDR] = (UBYTE)(i2c_uwCRCCcitt(I2C_pHistoryWriteBuffer, I2C_HISTORY_PARA_N_BYTES) >> 8); I2C_ubHistoyWriteBuffer[I2C_HISTORY_PARA_CRC_ARDDR + 1] = (UBYTE)(i2c_uwCRCCcitt(I2C_pHistoryWriteBuffer, I2C_HISTORY_PARA_N_BYTES)); } /************************************************************************* Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: *************************************************************************/ //static void i2c_voByteWrite2EE(UBYTE SlaveAddr, UBYTE WriteAddr, UBYTE Data) /* parasoft-suppress METRICS-28 "本项目圈复杂度无法更改,后续避免" */ //{ // ULONG ulTimeCnt = 0; // UWORD uwTimeoutNum = 0; // // if(!I2C_EE_ComuFltFlg) // { // /* write to EEPROM enable*/ // iGpio_Write(HW_GPIO_I2CWP_PIN,iGpio_LowLevel); // /* wait until I2C bus is idle */ // while((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) != 0) && (ulTimeCnt< I2C_SHORT_TIMEOUT)) // { // ulTimeCnt++; // } // if(ulTimeCnt == I2C_SHORT_TIMEOUT) // { // uwTimeoutNum ++; // } // ulTimeCnt = 0; // /* send a start condition to I2C bus */ // i2c_start_on_bus(I2C0); // /* wait until SBSEND bit is set */ // while((i2c_flag_get(I2C0, I2C_FLAG_SBSEND) == 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) // { // ulTimeCnt++; // } // if(ulTimeCnt == I2C_SHORT_TIMEOUT) // { // uwTimeoutNum ++; // } // ulTimeCnt = 0; // /* send slave address to I2C bus */ // i2c_master_addressing(I2C0, SlaveAddr, I2C_TRANSMITTER); // /* wait until ADDSEND bit is set */ // while((i2c_flag_get(I2C0, I2C_FLAG_ADDSEND) == 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) // { // ulTimeCnt++; // } // if(ulTimeCnt == I2C_SHORT_TIMEOUT) // { // uwTimeoutNum ++; // } // ulTimeCnt = 0; // i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); // /* wait until the transmit data buffer is empty */ // while((i2c_flag_get(I2C0, I2C_FLAG_TBE) == 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) // { // ulTimeCnt++; // } // if(ulTimeCnt == I2C_SHORT_TIMEOUT) // { // uwTimeoutNum ++; // } // ulTimeCnt = 0; // /* writeAddr transmission */ // i2c_data_transmit(I2C0, WriteAddr); // /* wait until the BTC bit is set */ // while((i2c_flag_get(I2C0, I2C_FLAG_BTC) == 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) // { // ulTimeCnt++; // } // if(ulTimeCnt == I2C_SHORT_TIMEOUT) // { // uwTimeoutNum ++; // } // ulTimeCnt = 0; // /* data transmission */ // i2c_data_transmit(I2C0, Data); // /* wait until the BTC bit is set */ // while((i2c_flag_get(I2C0, I2C_FLAG_BTC) == 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) // { // ulTimeCnt++; // } // if(ulTimeCnt == I2C_SHORT_TIMEOUT) // { // uwTimeoutNum ++; // } // ulTimeCnt = 0; // /* send a stop condition to I2C bus */ // i2c_stop_on_bus(I2C0); // /* wait until stop condition generate */ // while((I2C_CTL0(I2C0)&I2C_CTL0_STOP) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) // { // ulTimeCnt++; // } // if(ulTimeCnt == I2C_SHORT_TIMEOUT) // { // uwTimeoutNum ++; // } // ulTimeCnt = 0; // /* write to EEPROM disable */ // iGpio_Write(HW_GPIO_I2CWP_PIN,iGpio_LowLevel); // // /* I2C EEPROM communication timeout fault */ // if(uwTimeoutNum > 0) // { // I2C_EE_ComuFltFlg = TRUE; // } // } // else // {} //} /************************************************************************* Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: *************************************************************************/ void i2c_voPageWrite2EE(const UBYTE *pBuffer, UBYTE SlaveAddr, UBYTE WriteAddr, UBYTE NBytesToWrite) /* parasoft-suppress METRICS-28 "本项目圈复杂度无法更改,后续避免" */ { ULONG ulTimeCnt = 0; UWORD uwTimeoutNum = 0; if(!I2C_EE_ComuFltFlg) { /* write to EEPROM enable*/ iGpio_Write(HW_GPIO_I2CWP_PIN,iGpio_HighLevel); /* wait until I2C bus is idle */ while((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) != 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) { ulTimeCnt++; } if(ulTimeCnt == I2C_SHORT_TIMEOUT) { uwTimeoutNum ++; } ulTimeCnt = 0; /* send a start condition to I2C bus */ i2c_start_on_bus(I2C0); /* wait until SBSEND bit is set */ while((i2c_flag_get(I2C0, I2C_FLAG_SBSEND) == 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) { ulTimeCnt++; } if(ulTimeCnt == I2C_SHORT_TIMEOUT) { uwTimeoutNum ++; } ulTimeCnt = 0; /* send slave address to I2C bus */ i2c_master_addressing(I2C0, SlaveAddr, I2C_TRANSMITTER); /* wait until ADDSEND bit is set */ while((i2c_flag_get(I2C0, I2C_FLAG_ADDSEND) == 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) { ulTimeCnt++; } if(ulTimeCnt == I2C_SHORT_TIMEOUT) { uwTimeoutNum ++; } ulTimeCnt = 0; i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); /* wait until the transmit data buffer is empty */ while((i2c_flag_get(I2C0, I2C_FLAG_TBE) == 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) { ulTimeCnt++; } if(ulTimeCnt == I2C_SHORT_TIMEOUT) { uwTimeoutNum ++; } ulTimeCnt = 0; /* writeAddr transmission */ i2c_data_transmit(I2C0, WriteAddr); /* wait until the BTC bit is set */ while((i2c_flag_get(I2C0, I2C_FLAG_BTC) == 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) { ulTimeCnt++; } if(ulTimeCnt == I2C_SHORT_TIMEOUT) { uwTimeoutNum ++; } ulTimeCnt = 0; /* data transmission */ while (NBytesToWrite != 0) { NBytesToWrite --; i2c_data_transmit(I2C0, *pBuffer); pBuffer++; /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ /* wait until the BTC bit is set */ while((i2c_flag_get(I2C0, I2C_FLAG_BTC) == 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) { ulTimeCnt++; } if(ulTimeCnt == I2C_SHORT_TIMEOUT) { uwTimeoutNum ++; } ulTimeCnt = 0; /* I2C communication timeout fault */ if(uwTimeoutNum > 3 ) { I2C_EE_ComuFltFlg = TRUE; break; } } /* send a stop condition to I2C bus */ i2c_stop_on_bus(I2C0); /* wait until stop condition generate */ while((I2C_CTL0(I2C0)&I2C_CTL0_STOP) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) { ulTimeCnt++; } if(ulTimeCnt == I2C_SHORT_TIMEOUT) { uwTimeoutNum ++; } ulTimeCnt = 0; /* I2C EEPROM communication timeout fault */ if(uwTimeoutNum > 0) { I2C_EE_ComuFltFlg = TRUE; } /* write to EEPROM disable */ iGpio_Write(HW_GPIO_I2CWP_PIN,iGpio_LowLevel); } else {} } /************************************************************************* Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: *************************************************************************/ static void i2c_voBufferWrite2EE(const UBYTE *pBuffer, UBYTE SlaveAddr, UBYTE WriteAddr, UBYTE NBytesToWrite) { UBYTE ubNPages = 0, ubNSingleBytes = 0, ubAddr = 0, ubCnt = 0, ubTemp = 0; ubAddr = WriteAddr % I2C_EE_PAGESIZE_NBYTES; ubCnt = I2C_EE_PAGESIZE_NBYTES - 1 - ubAddr; // Cnt datas away from page alignment ubNPages = NBytesToWrite / I2C_EE_PAGESIZE_NBYTES; ubNSingleBytes = NBytesToWrite % I2C_EE_PAGESIZE_NBYTES; if (ubAddr == 0) { if (ubNPages == 0) { i2c_voPageWrite2EE(pBuffer, SlaveAddr, WriteAddr, ubNSingleBytes); i2c_voWaitEEReady(SlaveAddr); } else { while (ubNPages != 0) { ubNPages--; i2c_voPageWrite2EE(pBuffer, SlaveAddr, WriteAddr, I2C_EE_PAGESIZE_NBYTES); i2c_voWaitEEReady(SlaveAddr); WriteAddr += I2C_EE_PAGESIZE_NBYTES; pBuffer += I2C_EE_PAGESIZE_NBYTES; /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ } if (ubNSingleBytes != 0) { i2c_voPageWrite2EE(pBuffer, SlaveAddr, WriteAddr, ubNSingleBytes); i2c_voWaitEEReady(SlaveAddr); } } } else { if (ubNPages == 0) { if (ubNSingleBytes > ubCnt) { ubTemp = ubNSingleBytes - ubCnt; i2c_voPageWrite2EE(pBuffer, SlaveAddr, WriteAddr, ubCnt); i2c_voWaitEEReady(SlaveAddr); WriteAddr += ubCnt; pBuffer += ubCnt; /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ i2c_voPageWrite2EE(pBuffer, SlaveAddr, WriteAddr, ubTemp); i2c_voWaitEEReady(SlaveAddr); } else { i2c_voPageWrite2EE(pBuffer, SlaveAddr, WriteAddr, NBytesToWrite); i2c_voWaitEEReady(SlaveAddr); } } else { NBytesToWrite -= ubCnt; ubNPages = NBytesToWrite / I2C_EE_PAGESIZE_NBYTES; ubNSingleBytes = NBytesToWrite % I2C_EE_PAGESIZE_NBYTES; if (ubCnt != 0) { /* Write the remaining bytes of the page where WriteAddr is located */ i2c_voPageWrite2EE(pBuffer, SlaveAddr, WriteAddr, ubCnt); i2c_voWaitEEReady(SlaveAddr); WriteAddr += ubCnt; pBuffer += ubCnt; /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ } while (ubNPages != 0) { ubNPages--; i2c_voPageWrite2EE(pBuffer, SlaveAddr, WriteAddr, I2C_EE_PAGESIZE_NBYTES); i2c_voWaitEEReady(SlaveAddr); WriteAddr += I2C_EE_PAGESIZE_NBYTES; pBuffer += I2C_EE_PAGESIZE_NBYTES; /* parasoft-suppress MISRA2004-17_1 "本项目无法更改,后续避免未指向数组的指针运算" */ /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ } if (ubNSingleBytes != 0) { i2c_voPageWrite2EE(pBuffer, SlaveAddr, WriteAddr, I2C_EE_PAGESIZE_NBYTES); i2c_voWaitEEReady(SlaveAddr); } } } } /************************************************************************* Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: *************************************************************************/ void i2c_voInfoWrite2EE(const I2C_TX_COF *coef, I2C_TX_OUT *out) { UBYTE ubNBytes; UBYTE ubReTX1; UBYTE ubSlaveAddr; UBYTE ubWriteAddr; ubNBytes = I2C_TX1_NBYTES; ubReTX1 = I2C_RETX1_TIMES; #if(ubReTX1 >= 2) ubReTX1 = 2; #endif ubWriteAddr = 0x00; ubSlaveAddr = I2C_SLAVEADDR_BLOCK1; while (ubReTX1 != 0) { ubReTX1--; I2C_pWriteBuffer = I2C_ubWriteBuffer; if (ubReTX1 == 1) { ubSlaveAddr = I2C_SLAVEADDR_BLOCK2; } if (ubReTX1 == 0) { ubSlaveAddr = I2C_SLAVEADDR_BLOCK1; } i2c_voBufferWrite2EE(I2C_pWriteBuffer, ubSlaveAddr, ubWriteAddr, ubNBytes); } if ((ubReTX1 == 0) && (I2C_EE_ComuFltFlg != TRUE)) { out->blTX1FinishFlg = TRUE; } else { out->blTX1FinishFlg = FALSE; } } /************************************************************************* Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: *************************************************************************/ void i2c_voHistoryWrite2EE(const I2C_TX_COF *coef, I2C_TX_OUT *out) { UBYTE ubNBytes; UBYTE ubReTX2; UBYTE ubSlaveAddr; UBYTE ubWriteAddr; ubNBytes = I2C_TX2_NBYTES; ubReTX2 = I2C_RETX2_TIMES; #if(ubReTX2 >= 2) ubReTX2 = 2; #endif ubSlaveAddr = I2C_SLAVEADDR_BLOCK3; ubWriteAddr = 0x00; while (ubReTX2 != 0) { ubReTX2--; I2C_pHistoryWriteBuffer = I2C_ubHistoyWriteBuffer; if (ubReTX2 == 1) { ubSlaveAddr = I2C_SLAVEADDR_BLOCK4; } if (ubReTX2 == 0) { ubSlaveAddr = I2C_SLAVEADDR_BLOCK3; } i2c_voBufferWrite2EE(I2C_pHistoryWriteBuffer, ubSlaveAddr, ubWriteAddr, ubNBytes); } if ((ubReTX2 == 0) && (I2C_EE_ComuFltFlg != TRUE)) { out->blTX2FinishFlg = TRUE; } else { out->blTX2FinishFlg = FALSE; } } /************************************************************************* Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: *************************************************************************/ void i2c_bus_reset(void) { i2c_deinit(I2C0); /* configure SDA/SCL for GPIO */ GPIO_BC(GPIOB) |= GPIO_PIN_6; GPIO_BC(GPIOB) |= GPIO_PIN_7; gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6); gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); GPIO_BOP(GPIOB) |= GPIO_PIN_6; __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); GPIO_BOP(GPIOB) |= GPIO_PIN_7; /* connect I2C_SCL_PIN to I2C_SCL */ /* connect I2C_SDA_PIN to I2C_SDA */ gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6); gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_7); /* configure the I2CX interface */ /* configure I2C0 clock */ i2c_clock_config(I2C0, 100000, I2C_DTCY_2); /* configure I2C0 address */ i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C_SLAVEADDR_BLOCK1); /* enable acknowledge */ i2c_ack_config(I2C0, I2C_ACK_ENABLE); // /* enable I2C0 DMA */ // i2c_dma_config(I2C0, I2C_DMA_ON); /* enable I2C0 */ i2c_enable(I2C0); } /************************************************************************* Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: *************************************************************************/ void i2c_voSysparaReadFromEE(I2C_RXCRC_OUT *out) /* parasoft-suppress METRICS-28 "本项目圈复杂度无法更改,后续避免" */ { UWORD timeout = 0; UBYTE ubRdNBytes = 0, ubRdSlaveAddr = 0, ubRdAddr = 0; UBYTE state = (UBYTE)I2C_START; UBYTE read_cycle = 0; UBYTE ubRdCnt = 2; UBYTE i2c_timeout_flag = 0; UBYTE *p_buffer; while(ubRdCnt != 0) { ubRdCnt--; /* enable acknowledge */ i2c_ack_config(I2C0, I2C_ACK_ENABLE); if (ubRdCnt == 1) { ubRdSlaveAddr = I2C_SLAVEADDR_BLOCK1; ubRdAddr = 0x00; ubRdNBytes = I2C_RX1_NBYTES; p_buffer = I2C_ubReadBuffer[0]; i2c_timeout_flag = 0; } else if (ubRdCnt == 0) { ubRdSlaveAddr = I2C_SLAVEADDR_BLOCK3; ubRdAddr = 0x00; ubRdNBytes = I2C_RX2_NBYTES; p_buffer = I2C_ubReadBuffer[1]; i2c_timeout_flag = 0; } else { //do nothing } while(i2c_timeout_flag ==0) { switch(state) { case I2C_START: if(RESET == read_cycle) { /* disable I2C0 */ i2c_disable(I2C0); /* enable I2C0 */ i2c_enable(I2C0); /* enable acknowledge */ i2c_ack_config(I2C0, I2C_ACK_ENABLE); /* i2c master sends start signal only when the bus is idle */ while((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) != 0) && (timeout < I2C_SHORT_TIMEOUT)) { timeout++; } if(timeout < I2C_SHORT_TIMEOUT) { /* send the start signal */ i2c_start_on_bus(I2C0); timeout = 0; state = (UBYTE)I2C_SEND_ADDRESS; } else { i2c_bus_reset(); timeout = 0; state = (UBYTE)I2C_START; } } else { i2c_start_on_bus(I2C0); timeout = 0; state = (UBYTE)I2C_SEND_ADDRESS; } break; case I2C_SEND_ADDRESS: /* i2c master sends START signal successfully */ while((i2c_flag_get(I2C0, I2C_FLAG_SBSEND) == 0) && (timeout < I2C_SHORT_TIMEOUT)) { timeout++; } if(timeout < I2C_SHORT_TIMEOUT) { if(RESET == read_cycle) { i2c_master_addressing(I2C0, ubRdSlaveAddr, I2C_TRANSMITTER); state = (UBYTE)I2C_CLEAR_ADDRESS_FLAG; } else { i2c_master_addressing(I2C0, ubRdSlaveAddr, I2C_RECEIVER); state = (UBYTE)I2C_CLEAR_ADDRESS_FLAG; } timeout = 0; } else { timeout = 0; state = (UBYTE)I2C_START; read_cycle = 0; } break; case I2C_CLEAR_ADDRESS_FLAG: /* address flag set means i2c slave sends ACK */ while((i2c_flag_get(I2C0, I2C_FLAG_ADDSEND) == 0) && (timeout < I2C_SHORT_TIMEOUT)) { timeout++; } if(timeout < I2C_SHORT_TIMEOUT) { i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); timeout = 0; state = (UBYTE)I2C_TRANSMIT_DATA; } else { timeout = 0; state = (UBYTE)I2C_START; read_cycle = 0; } break; case I2C_TRANSMIT_DATA: if(RESET == read_cycle) { /* wait until the transmit data buffer is empty */ while((i2c_flag_get(I2C0, I2C_FLAG_TBE) == 0) && (timeout < I2C_SHORT_TIMEOUT)) { timeout++; } if(timeout < I2C_SHORT_TIMEOUT) { /* send the EEPROM's internal address to write to : only one byte address */ i2c_data_transmit(I2C0, ubRdAddr); timeout = 0; } else { timeout = 0; state = (UBYTE)I2C_START; read_cycle = 0; } /* wait until BTC bit is set */ while((i2c_flag_get(I2C0, I2C_FLAG_BTC) == 0) && (timeout < I2C_SHORT_TIMEOUT)) { timeout++; } if(timeout < I2C_SHORT_TIMEOUT) { timeout = 0; state = (UBYTE)I2C_START; read_cycle++; } else { timeout = 0; state = (UBYTE)I2C_START; read_cycle = 0; } } else { /* one byte master reception procedure (polling) */ if(ubRdNBytes < 2) { /* disable acknowledge */ i2c_ack_config(I2C0, I2C_ACK_DISABLE); /* clear ADDSEND register by reading I2C_STAT0 then I2C_STAT1 register (I2C_STAT0 has already been read) */ i2c_flag_get(I2C0, I2C_FLAG_ADDSEND); /* send a stop condition to I2C bus*/ i2c_stop_on_bus(I2C0); /* wait for the byte to be received */ while(i2c_flag_get(I2C0, I2C_FLAG_RBNE) == 0) { // do nothing } /* read the byte received from the EEPROM */ *p_buffer = i2c_data_receive(I2C0); /* decrement the read bytes counter */ ubRdNBytes--; timeout = 0; state = (UBYTE)I2C_STOP; } else { /* more than one byte master reception procedure (DMA) */ dma_transfer_number_config(DMA0, DMA_CH6, ubRdNBytes); DMA_CH6MADDR(DMA0) = (ULONG)p_buffer; i2c_dma_last_transfer_config(I2C0, I2C_DMALST_ON); /* enable I2C0 DMA */ i2c_dma_config(I2C0, I2C_DMA_ON); /* enable DMA0 channel5 */ dma_channel_enable(DMA0, DMA_CH6); /* wait until BTC bit is set */ while(dma_flag_get(DMA0, DMA_CH6, DMA_FLAG_FTF) == 0) { // do nothing } state = (UBYTE)I2C_STOP; } } break; case I2C_STOP: /* send a stop condition to I2C bus */ i2c_stop_on_bus(I2C0); /* i2c master sends STOP signal successfully */ while((I2C_CTL0(I2C0) & I2C_CTL0_STOP) && (timeout < I2C_SHORT_TIMEOUT)) { timeout++; } if(timeout < I2C_SHORT_TIMEOUT) { timeout = 0; i2c_timeout_flag = 1; state = (UBYTE)I2C_START; /* disable DMA0 CH6 */ dma_channel_disable(DMA0, DMA_CH6); /* disable I2C0 DMA */ i2c_dma_config(I2C0, I2C_DMA_OFF); i2c_dma_last_transfer_config(I2C0, I2C_DMALST_OFF); } else { timeout = 0; //state = I2C_START; state = (UBYTE)I2C_STOP; read_cycle = 0; } break; default: state = (UBYTE)I2C_START; read_cycle = 0; i2c_timeout_flag = 1; timeout = 0; break; } } } i2c_voReadBufferCRC(out); i2c_voGetValueFrmBuffer(out); out->ReadFinishFlg = TRUE; } /************************************************************************* Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: *************************************************************************/ UWORD i2c_uwCRCCcitt(const UBYTE *ptubBuf, UWORD length) { UBYTE b = 0; UWORD crc = 0xffff; UWORD i, j; for (i = 0; i < length; i++) { for (j = 0; j < 8; j++) { b = (UBYTE)(((ptubBuf[i] << j) & 0x80) ^ ((crc & 0x8000) >> 8)); /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ crc <<= 1; if (b != 0) { crc ^= 0x1021; // crc = crc^(0x10000^0x11021) } } } return crc; } /************************************************************************* Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: *************************************************************************/ void i2c_voReadBufferCRC(I2C_RXCRC_OUT *out) { UWORD uwMotorParaCRC, uwBikeParaCRC, uwMControlParaCRC; UWORD uwSensorParaCRC, uwAssistParaCRC, uwHistoryParaCRC; UWORD uwMotorParaRdCRC, uwBikeParaRdCRC, uwMControlParaRdCRC; UWORD uwSensorParaRdCRC, uwAssistParaRdCRC, uwHistoryParaRdCRC; I2C_pReadBuffer = I2C_ubReadBuffer[0]; uwMotorParaCRC = i2c_uwCRCCcitt(I2C_pReadBuffer, I2C_MOTOR_PARA_N_BYTES); uwBikeParaCRC = i2c_uwCRCCcitt(I2C_pReadBuffer + I2C_BIKE_PARA_ARDDR, I2C_BIKE_PARA_N_BYTES); /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ uwMControlParaCRC = i2c_uwCRCCcitt(I2C_pReadBuffer + I2C_MCONTROL_PARA_ARDDR, I2C_MCONTROL_PARA_N_BYTES); /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ uwSensorParaCRC = i2c_uwCRCCcitt(I2C_pReadBuffer + I2C_SENSOR_PARA_ARDDR, I2C_SENSOR_PARA_N_BYTES); /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ uwAssistParaCRC = i2c_uwCRCCcitt(I2C_pReadBuffer + I2C_ASSIST_PARA_ARDDR, I2C_ASSIST_PARA_N_BYTES); /* parasoft-suppress MISRA2004-17_4 "本项目无法更改,后续避免非数组索引指针运算" */ I2C_pReadBuffer = I2C_ubReadBuffer[1]; uwHistoryParaCRC = i2c_uwCRCCcitt(I2C_pReadBuffer, I2C_HISTORY_PARA_N_BYTES); uwMotorParaRdCRC = (UWORD)((UWORD)I2C_ubReadBuffer[0][I2C_MOTOR_PARA_CRC_ARDDR] << 8) + I2C_ubReadBuffer[0][I2C_MOTOR_PARA_CRC_ARDDR + 1]; uwBikeParaRdCRC = (UWORD)((UWORD)I2C_ubReadBuffer[0][I2C_BIKE_PARA_CRC_ARDDR] << 8) + I2C_ubReadBuffer[0][I2C_BIKE_PARA_CRC_ARDDR + 1]; uwMControlParaRdCRC = (UWORD)((UWORD)I2C_ubReadBuffer[0][I2C_MCONTROL_PARA_CRC_ARDDR] << 8) + I2C_ubReadBuffer[0][I2C_MCONTROL_PARA_CRC_ARDDR + 1]; uwSensorParaRdCRC = (UWORD)((UWORD)I2C_ubReadBuffer[0][I2C_SENSOR_PARA_CRC_ARDDR] << 8) + I2C_ubReadBuffer[0][I2C_SENSOR_PARA_CRC_ARDDR + 1]; uwAssistParaRdCRC = (UWORD)((UWORD)I2C_ubReadBuffer[0][I2C_ASSIST_PARA_CRC_ARDDR] << 8) + I2C_ubReadBuffer[0][I2C_ASSIST_PARA_CRC_ARDDR + 1]; uwHistoryParaRdCRC = (UWORD)((UWORD)I2C_ubReadBuffer[1][I2C_HISTORY_PARA_CRC_ARDDR] << 8) + I2C_ubReadBuffer[1][I2C_HISTORY_PARA_CRC_ARDDR + 1]; if (uwMotorParaCRC != uwMotorParaRdCRC) { out->blMotorParaFltFlg = TRUE; } if (uwBikeParaCRC != uwBikeParaRdCRC) { out->blBikeParaFltFlg = TRUE; } if (uwMControlParaCRC != uwMControlParaRdCRC) { out->blMControlParaFltFlg = TRUE; } if (uwSensorParaCRC != uwSensorParaRdCRC) { out->blSensorParaFltFlg = TRUE; } if (uwAssistParaCRC != uwAssistParaRdCRC) { out->blAssistParaFltFlg = TRUE; } if (uwHistoryParaCRC != uwHistoryParaRdCRC) { out->blHistoryParaFltFlg = TRUE; } } /************************************************************************* Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: *************************************************************************/ void i2c_voGetValueFrmBuffer(const I2C_RXCRC_OUT *out) { UBYTE j = 0; if (out->blMotorParaFltFlg != TRUE) { for (j = 0; j < I2C_MOTOR_PARA_N_WORDS; j++) { I2C_uwMotorParaRead[j] = (UWORD)((UWORD)I2C_ubReadBuffer[0][I2C_MOTOR_PARA_ARDDR + 2 * j] << 8) + I2C_ubReadBuffer[0][I2C_MOTOR_PARA_ARDDR + 2 * j + 1]; } } else {} if (out->blBikeParaFltFlg != TRUE) { for (j = 0; j < I2C_BIKE_PARA_N_WORDS; j++) { I2C_uwBikeParaRead[j] = (UWORD)((UWORD)I2C_ubReadBuffer[0][I2C_BIKE_PARA_ARDDR + 2 * j] << 8) + I2C_ubReadBuffer[0][I2C_BIKE_PARA_ARDDR + 2 * j + 1]; } } else {} if (out->blMControlParaFltFlg != TRUE) { for (j = 0; j < I2C_MCONTROL_PARA_N_WORDS; j++) { I2C_uwMControlRead[j] = (UWORD)((UWORD)I2C_ubReadBuffer[0][I2C_MCONTROL_PARA_ARDDR + 2 * j] << 8) + I2C_ubReadBuffer[0][I2C_MCONTROL_PARA_ARDDR + 2 * j + 1]; } } else {} if (out->blSensorParaFltFlg != TRUE) { for (j = 0; j < I2C_SENSOR_PARA_N_WORDS; j++) { I2C_uwSensorRead[j] = (UWORD)((UWORD)I2C_ubReadBuffer[0][I2C_SENSOR_PARA_ARDDR + 2 * j] << 8) + I2C_ubReadBuffer[0][I2C_SENSOR_PARA_ARDDR + 2 * j + 1]; } } else {} if (out->blAssistParaFltFlg != TRUE) { for (j = 0; j < I2C_ASSIST_PARA_N_WORDS; j++) { I2C_uwAssistParaRead[j] = (UWORD)((UWORD)I2C_ubReadBuffer[0][I2C_ASSIST_PARA_ARDDR + 2 * j] << 8) + I2C_ubReadBuffer[0][I2C_ASSIST_PARA_ARDDR + 2 * j + 1]; } } else {} if (out->blHistoryParaFltFlg != TRUE) { for (j = 0; j < I2C_HISTORY_PARA_N_WORDS; j++) { I2C_uwHistoryParaRead[j] = (UWORD)((UWORD)I2C_ubReadBuffer[1][I2C_HISTORY_PARA_ARDDR + 2 * j] << 8) + I2C_ubReadBuffer[1][I2C_HISTORY_PARA_ARDDR + 2 * j + 1]; } } else {} Syspara2.stMotorPara.uwPolePairs.uwReal = I2C_uwMotorParaRead[0]; Syspara2.stMotorPara.uwRsmOhm.uwReal = I2C_uwMotorParaRead[1]; Syspara2.stMotorPara.uwLduH.uwReal = I2C_uwMotorParaRead[2]; Syspara2.stMotorPara.uwLquH.uwReal = I2C_uwMotorParaRead[3]; Syspara2.stMotorPara.uwFluxmWb.uwReal = I2C_uwMotorParaRead[4]; Syspara2.stMotorPara.uwIdMaxA.uwReal = I2C_uwMotorParaRead[5]; Syspara2.stMotorPara.uwIdMinA.uwReal = I2C_uwMotorParaRead[6]; Syspara2.stMotorPara.uwRSpdRpm.uwReal = I2C_uwMotorParaRead[7]; Syspara2.stMotorPara.uwRPwrWt.uwReal = I2C_uwMotorParaRead[8]; Syspara2.stMotorPara.uwRCurA.uwReal = I2C_uwMotorParaRead[9]; Syspara2.stMotorPara.uwRVolV.uwReal = I2C_uwMotorParaRead[10]; Syspara2.stMotorPara.uwJD.uwReal = I2C_uwMotorParaRead[11]; Syspara2.stMotorPara.uwTorMaxNm.uwReal = I2C_uwMotorParaRead[12]; Syspara2.stBikePara.uwWheelPerimeter.uwReal = I2C_uwBikeParaRead[0]; Syspara2.stBikePara.uwMechRationMotor.uwReal = I2C_uwBikeParaRead[1]; Syspara2.stBikePara.uwAssistMaxSpdKmH.uwReal = I2C_uwBikeParaRead[2]; Syspara2.stBikePara.uwThrottleMaxSpdKmH.uwReal = I2C_uwBikeParaRead[3]; Syspara2.stBikePara.uwNmFrontChainring.uwReal = I2C_uwBikeParaRead[4]; Syspara2.stBikePara.uwNmBackChainring.uwReal = I2C_uwBikeParaRead[5]; Syspara2.stBikePara.uwAssistSelect1.uwReal = I2C_uwBikeParaRead[6]; Syspara2.stBikePara.uwAssistSelect2.uwReal = I2C_uwBikeParaRead[7]; Syspara2.stBikePara.uwLightVoltage.uwReal = I2C_uwBikeParaRead[8]; Syspara2.stBikePara.swDeltPerimeter.swReal = (SWORD)I2C_uwBikeParaRead[9]; Syspara2.stBikePara.uwStartMode.uwReal = I2C_uwBikeParaRead[10]; Syspara2.stBikePara.uwAutoPowerOffTime.uwReal = I2C_uwBikeParaRead[11]; Syspara2.stMControlPara.ParaFirstSetFlg.uwReal = I2C_uwMControlRead[0]; Syspara2.stMControlPara.SpiOffsetFirstSetFlg.uwReal = I2C_uwMControlRead[1]; Syspara2.stMControlPara.uwSPIPosOffsetOrigin.uwReal = I2C_uwMControlRead[2]; Syspara2.stMControlPara.uwSPIPosOffsetNow.uwReal = I2C_uwMControlRead[3]; Syspara2.stMControlPara.uwIPeakMaxA.uwReal = I2C_uwMControlRead[4]; Syspara2.stMControlPara.uwAlamOCurA.uwReal = I2C_uwMControlRead[5]; Syspara2.stMControlPara.uwAlamOVolV.uwReal = I2C_uwMControlRead[6]; Syspara2.stMControlPara.uwAlamUVolV.uwReal = I2C_uwMControlRead[7]; Syspara2.stMControlPara.uwAlamOverSpdRpm.uwReal = I2C_uwMControlRead[8]; Syspara2.stMControlPara.uwAlamOverHeatCe.uwReal = I2C_uwMControlRead[9]; Syspara2.stMControlPara.uwAlamRecHeatCe.uwReal = I2C_uwMControlRead[10]; Syspara2.stMControlPara.uwPwrLimitStartCe.uwReal = I2C_uwMControlRead[11]; Syspara2.stSensorPara.uwTorSensorOffsetOrigin.uwReal = I2C_uwSensorRead[0]; Syspara2.stSensorPara.uwTorSensorOffsetNow1.uwReal = I2C_uwSensorRead[1]; Syspara2.stSensorPara.uwTorSensorOffsetNow2.uwReal = I2C_uwSensorRead[2]; Syspara2.stSensorPara.uwTorSensorOffsetNow3.uwReal = I2C_uwSensorRead[3]; Syspara2.stSensorPara.uwTorSensorOffsetNow4.uwReal = I2C_uwSensorRead[4]; Syspara2.stSensorPara.uwBikeTorMaxNm.uwReal = I2C_uwSensorRead[5]; Syspara2.stSensorPara.uwBikeTor1StepRealNm.uwReal = I2C_uwSensorRead[6]; Syspara2.stSensorPara.uwBikeTor1StepADC.uwReal = I2C_uwSensorRead[7]; Syspara2.stSensorPara.uwBikeTor2StepRealNm.uwReal = I2C_uwSensorRead[8]; Syspara2.stSensorPara.uwBikeTor2StepADC.uwReal = I2C_uwSensorRead[9]; Syspara2.stSensorPara.uwBikeTor3StepRealNm.uwReal = I2C_uwSensorRead[10]; Syspara2.stSensorPara.uwBikeTor3StepADC.uwReal = I2C_uwSensorRead[11]; Syspara2.stSensorPara.uwBikeTor4StepRealNm.uwReal = I2C_uwSensorRead[12]; Syspara2.stSensorPara.uwBikeTor4StepADC.uwReal = I2C_uwSensorRead[13]; Syspara2.stSensorPara.uwCadSensorPulseNm.uwReal = I2C_uwSensorRead[14]; Syspara2.stSensorPara.uwBikeSpdSensorPulseNm.uwReal = I2C_uwSensorRead[15]; Syspara2.stAssistPara.uwStartupGain.uwReal = I2C_uwAssistParaRead[0]; Syspara2.stAssistPara.uwStartcruiseGain.uwReal = I2C_uwAssistParaRead[1]; Syspara2.stAssistPara.uwAssistStartNm.uwReal = I2C_uwAssistParaRead[2]; Syspara2.stAssistPara.uwAssistStopNm.uwReal = I2C_uwAssistParaRead[3]; Syspara2.stAssistPara.uwStartUpGainStep.uwReal = I2C_uwAssistParaRead[4]; Syspara2.stAssistPara.uwStartUpCadNm.uwReal = I2C_uwAssistParaRead[5]; Syspara2.stAssistPara.uwTorLPFCadNm.uwReal = I2C_uwAssistParaRead[6]; Syspara2.stAssistPara.uwSpeedAssistSpdRpm.uwReal = I2C_uwAssistParaRead[7]; Syspara2.stAssistPara.uwSpeedAssistIMaxA.uwReal = I2C_uwAssistParaRead[8]; Syspara2.stAssistPara.uwAssistLimitBikeSpdStart.uwReal = I2C_uwAssistParaRead[9]; Syspara2.stAssistPara.uwAssistLimitBikeSpdStop.uwReal = I2C_uwAssistParaRead[10]; Syspara2.stAssistPara.uwCadenceAssistWeight.uwReal = I2C_uwAssistParaRead[11]; Syspara2.stHistoryPara.uwAssModSelect.uwReal = I2C_uwHistoryParaRead[0]; Syspara2.stHistoryPara.uwOpenTimes.uwReal = I2C_uwHistoryParaRead[1]; Syspara2.stHistoryPara.uwUsedTimeH.uwReal = I2C_uwHistoryParaRead[2]; Syspara2.stHistoryPara.uwUsedTimeL.uwReal = I2C_uwHistoryParaRead[3]; Syspara2.stHistoryPara.uwNTCTempMaxCe.uwReal = I2C_uwHistoryParaRead[4]; Syspara2.stHistoryPara.uwNTCTempMinCe.uwReal = I2C_uwHistoryParaRead[5]; Syspara2.stHistoryPara.uwAlamHOcurTimes.uwReal = I2C_uwHistoryParaRead[6]; Syspara2.stHistoryPara.uwAlamSOcurTimes.uwReal = I2C_uwHistoryParaRead[7]; Syspara2.stHistoryPara.uwAlamOHeatTimes.uwReal = I2C_uwHistoryParaRead[8]; Syspara2.stHistoryPara.uwAlamRotorLockTimes.uwReal = I2C_uwHistoryParaRead[9]; Syspara2.stHistoryPara.uwAlamPhsLossTimes.uwReal = I2C_uwHistoryParaRead[10]; Syspara2.stHistoryPara.uwAlamOVolTimes.uwReal = I2C_uwHistoryParaRead[11]; Syspara2.stHistoryPara.uwAlamUVolTimes.uwReal = I2C_uwHistoryParaRead[12]; Syspara2.stHistoryPara.uwAlamComOTimeTimes.uwReal = I2C_uwHistoryParaRead[13]; Syspara2.stHistoryPara.uwG1AvgPwrConsumption.uwReal = I2C_uwHistoryParaRead[14]; Syspara2.stHistoryPara.uwG2AvgPwrConsumption.uwReal = I2C_uwHistoryParaRead[15]; Syspara2.stHistoryPara.uwG3AvgPwrConsumption.uwReal = I2C_uwHistoryParaRead[16]; Syspara2.stHistoryPara.uwG4AvgPwrConsumption.uwReal = I2C_uwHistoryParaRead[17]; Syspara2.stHistoryPara.uwG5AvgPwrConsumption.uwReal = I2C_uwHistoryParaRead[18]; Syspara2.stHistoryPara.uwODOTripH.uwReal = I2C_uwHistoryParaRead[19]; Syspara2.stHistoryPara.uwODOTripL.uwReal = I2C_uwHistoryParaRead[20]; Syspara2.stHistoryPara.uwODOTimeH.uwReal = I2C_uwHistoryParaRead[21]; Syspara2.stHistoryPara.uwODOTimeL.uwReal = I2C_uwHistoryParaRead[22]; Syspara2.stHistoryPara.uwTripSumH.uwReal = I2C_uwHistoryParaRead[23]; Syspara2.stHistoryPara.uwTripSumL.uwReal = I2C_uwHistoryParaRead[24]; Syspara2.stHistoryPara.uwTripSumTimeH.uwReal = I2C_uwHistoryParaRead[25]; Syspara2.stHistoryPara.uwTripSumTimeL.uwReal = I2C_uwHistoryParaRead[26]; Syspara2.stHistoryPara.uwTorSensorAlamTimes.uwReal = I2C_uwHistoryParaRead[27]; Syspara2.stHistoryPara.uwCadSensorAlamTimes.uwReal = I2C_uwHistoryParaRead[28]; Syspara2.stHistoryPara.uwBikeSpdSensorAlamTimes.uwReal = I2C_uwHistoryParaRead[29]; Syspara2.stHistoryPara.uwPosSensorAlamTimes.uwReal = I2C_uwHistoryParaRead[30]; } /************************************************************************* Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: *************************************************************************/ void i2c_voWriteTest(void) { UBYTE WriteBuffer[4]; UBYTE *pBuffer; WriteBuffer[0] = 0x06; WriteBuffer[1] = 0x08; WriteBuffer[2] = 0x0A; WriteBuffer[3] = 0x01; pBuffer = WriteBuffer; i2c_voPageWrite2EE(pBuffer, I2C_SLAVEADDR_BLOCK1, 0x00, 4); } /************************************************************************* Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: *************************************************************************/ void i2c_voReadTest(void) /* parasoft-suppress METRICS-28 "本项目圈复杂度无法更改,后续避免" */ { UBYTE ReadBuffer[6]; ULONG ulTimeCnt = 0; UWORD uwTimeoutNum = 0; UWORD uwReadNBytes = 6; /* wait until I2C bus is idle */ while((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) != 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) { ulTimeCnt++; } if(ulTimeCnt == I2C_SHORT_TIMEOUT) { uwTimeoutNum ++; } ulTimeCnt = 0; /* send a start condition to I2C bus */ i2c_start_on_bus(I2C0); /* wait until SBSEND bit is set */ while((i2c_flag_get(I2C0, I2C_FLAG_SBSEND) == 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) { ulTimeCnt++; } if(ulTimeCnt == I2C_SHORT_TIMEOUT) { uwTimeoutNum ++; } ulTimeCnt = 0; /* send slave address to I2C bus */ i2c_master_addressing(I2C0, I2C_SLAVEADDR_BLOCK1, I2C_TRANSMITTER); /* wait until ADDSEND bit is set */ while((i2c_flag_get(I2C0, I2C_FLAG_ADDSEND) == 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) { ulTimeCnt++; } if(ulTimeCnt == I2C_SHORT_TIMEOUT) { uwTimeoutNum ++; } ulTimeCnt = 0; /* clear ADDSEND bit */ i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); /* wait until the TBE bit is set */ while((i2c_flag_get(I2C0, I2C_FLAG_TBE) == 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) { ulTimeCnt++; } if(ulTimeCnt == I2C_SHORT_TIMEOUT) { uwTimeoutNum ++; } ulTimeCnt = 0; /* readAddr transmission */ i2c_data_transmit(I2C0, 0x00); /* wait until the BTC bit is set */ while((i2c_flag_get(I2C0, I2C_FLAG_BTC) == 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) { ulTimeCnt++; } if(ulTimeCnt == I2C_SHORT_TIMEOUT) { uwTimeoutNum ++; } ulTimeCnt = 0; /* send a start condition to I2C bus */ i2c_start_on_bus(I2C0); /* wait until SBSEND bit is set */ while((i2c_flag_get(I2C0, I2C_FLAG_SBSEND) == 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) { ulTimeCnt++; } if(ulTimeCnt == I2C_SHORT_TIMEOUT) { uwTimeoutNum ++; } ulTimeCnt = 0; /* send slave address to I2C bus */ i2c_master_addressing(I2C0, I2C_SLAVEADDR_BLOCK1, I2C_RECEIVER); /* wait until ADDSEND bit is set */ while((i2c_flag_get(I2C0, I2C_FLAG_ADDSEND) == 0)&& (ulTimeCnt < I2C_SHORT_TIMEOUT)) { ulTimeCnt++; } if(ulTimeCnt == I2C_SHORT_TIMEOUT) { uwTimeoutNum ++; } ulTimeCnt = 0; /* clear ADDSEND bit */ i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); while(uwReadNBytes != 0) { uwReadNBytes--; if(2 == uwReadNBytes) { /* wait until BTC bit is set */ while((i2c_flag_get(I2C0, I2C_FLAG_BTC) == 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) { ulTimeCnt++; } if(ulTimeCnt == I2C_SHORT_TIMEOUT) { uwTimeoutNum ++; } ulTimeCnt = 0; /* disable acknowledge */ i2c_ack_config(I2C0, I2C_ACK_DISABLE); } if(1 == uwReadNBytes) { /* wait until BTC bit is set */ while((i2c_flag_get(I2C0, I2C_FLAG_BTC) == 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) { ulTimeCnt++; } if(ulTimeCnt == I2C_SHORT_TIMEOUT) { uwTimeoutNum ++; } ulTimeCnt = 0; /* send a stop condition to I2C bus */ i2c_stop_on_bus(I2C0); } while((i2c_flag_get(I2C0, I2C_FLAG_RBNE) == 0) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) { ulTimeCnt++; } if(ulTimeCnt == I2C_SHORT_TIMEOUT) { uwTimeoutNum ++; } ulTimeCnt = 0; ReadBuffer[5 - uwReadNBytes] = i2c_data_receive(I2C0); } /* wait until stop condition generate */ while((I2C_CTL0(I2C0)&I2C_CTL0_STOP) && (ulTimeCnt < I2C_SHORT_TIMEOUT)) { ulTimeCnt++; } if(ulTimeCnt == I2C_SHORT_TIMEOUT) { uwTimeoutNum ++; } ulTimeCnt = 0; if(uwTimeoutNum > 3) { I2C_EE_ComuFltFlg = TRUE; } } /************************************************************************* Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd. All rights reserved. *************************************************************************/ #ifdef _I2C_MASTER_C_ #undef _I2C_MASTER_C_ /* parasoft-suppress MISRA2004-19_6 "本项目中无法更改,后续避免使用" */ #endif /************************************************************************* End of this File (EOF)! Do not put anything after this part! *************************************************************************/