/**************************************************************************//** * @file pan_hal_i2c.c * @version V0.0.0 * $Revision: 1 $ * $Date: 23/09/10 $ * @brief Panchip series I2C (Inter-Integrated Circuit) HAL source file. * @note * Copyright (C) 2023 Panchip Technology Corp. All rights reserved. *****************************************************************************/ #include "pan_hal.h" I2C_HandleTypeDef* I2C_INST_PTR; static void I2C_SendData(I2C_T* I2Cx, uint8_t Data) { I2Cx->DATACMD = Data & 0xFF; } bool HAL_I2C_Init(I2C_HandleTypeDef *i2c) { uint32_t tmpreg = 0; uint32_t result = 0; uint32_t pclk; I2C_INST_PTR = i2c; CLK_APB1PeriphClockCmd(CLK_APB1Periph_I2C0, ENABLE); // The IC_SAR holds the slave address when the I2C is operating as a slave if (i2c->I2C_InitObj.AddressMode == I2C_ADDR_10BIT) { i2c->I2C_InitObj.AckAddress = I2C_ACK_ADDR_10BIT; } else { i2c->I2C_InitObj.AckAddress = I2C_ACK_ADDR_7BIT; } I2C_Cmd(i2c->I2Cx, DISABLE); /*get system clock frequency*/ pclk = CLK_GetPeripheralFreq(i2c->I2Cx); /*---------------------------- I2Cx CON Configuration ------------------------*/ /*Disable I2C */ tmpreg = i2c->I2Cx->CON; /*restart enable*/ tmpreg |= (I2C_CON_IC_RESTART_EN); /* slave address mode*/ if (I2C_ACK_ADDR_7BIT == i2c->I2C_InitObj.AckAddress) { tmpreg &= ~I2C_CON_IC_10BITADDR_SLAVE; } else // 10-bit addr { tmpreg |= I2C_CON_IC_10BITADDR_SLAVE; } tmpreg &= ~(I2C_CON_SPEED); /*---------------------------- I2Cx HCNT/LCNT Configuration ------------------------*/ /* Configure speed in standard mode */ result = pclk / i2c->I2C_InitObj.ClockSpeed; if (i2c->I2C_InitObj.ClockSpeed <= 100000) { /* Standart mode speed calculate: Tlow/Thigh = 1 */ result /= 2; if (result < i2c->I2Cx->FS_SPKLEN + 7) return false; /*HCNT equals to LCNT*/ i2c->I2Cx->SS_SCL_HCNT = result - i2c->I2Cx->FS_SPKLEN - 7; i2c->I2Cx->SS_SCL_LCNT = result - 1; tmpreg |= I2C_SPEED_STANDARD_MODE; } /* Configure speed in fast mode */ else if (i2c->I2C_InitObj.ClockSpeed <= 1000000) { if (i2c->I2C_InitObj.DutyCycle == I2C_DutyCycle_2) { /* Fast mode speed calculate: Tlow/Thigh = 2 */ result /= 3; if (result < i2c->I2Cx->FS_SPKLEN + 7) return false; i2c->I2Cx->FS_SCL_HCNT = result - i2c->I2Cx->FS_SPKLEN - 7; i2c->I2Cx->FS_SCL_LCNT = (result << 1) - 1; } else { /* Fast mode speed calculate: Tlow/Thigh = 16/9 */ if (result * 9 / 25 < i2c->I2Cx->FS_SPKLEN + 7) return false; /* Set DUTY bit */ i2c->I2Cx->FS_SCL_HCNT = result * 9 / 25 - i2c->I2Cx->FS_SPKLEN - 7; i2c->I2Cx->FS_SCL_LCNT = (result * 16 / 25) - 1; } tmpreg |= I2C_SPEED_FAST_MODE; } /* To use the I2C at 1 MHz (in fast mode plus ) */ else { result /= 3; if (result < i2c->I2Cx->HS_SPKLEN + 7) return false; /* Set DUTY bit */ i2c->I2Cx->HS_SCL_HCNT = result - i2c->I2Cx->HS_SPKLEN - 7; i2c->I2Cx->HS_SCL_LCNT = (result << 1) - 1; tmpreg |= I2C_SPEED_HIGH_MODE; } i2c->I2Cx->CON = tmpreg; /*data setup time: 250ns*/ i2c->I2Cx->SDA_SETUP = (pclk) / 4000000 + 1; /* Set I2Cx Own Address1 and acknowledged address */ i2c->I2Cx->SAR &= ~(I2C_TAR_TAR); /* Get 7-bit address from I2C_OwnAddress1*/ i2c->I2Cx->SAR |= ((i2c->I2C_InitObj.OwnAddress)); /*fifo threshold */ i2c->I2Cx->TX_TL = I2C_TX_TL_4; i2c->I2Cx->RX_TL = I2C_RX_TL_4; // I2C_InitRole() begin if (i2c->I2C_InitObj.Role == I2C_ROLE_MASTER) { // 1. set master mode I2C_SetMode(i2c->I2Cx, I2C_ROLE_MASTER); // 2. set remote slave addr if (i2c->I2C_InitObj.AddressMode == I2C_ADDR_10BIT) { I2C_Set10bitAddress(i2c->I2Cx, i2c->I2C_InitObj.OwnAddress); } else { I2C_Set7bitAddress(i2c->I2Cx, i2c->I2C_InitObj.OwnAddress); } i2c->I2Cx->SDA_HOLD = ((0x3 << 16) | 0x3); } else { I2C_SetMode(i2c->I2Cx, I2C_ROLE_SLAVE); } I2C_DisableAllIT(i2c->I2Cx); /* I2C Peripheral Enable */ I2C_Cmd(i2c->I2Cx, ENABLE); // I2C_InitRole() end return 0; } static void HAL_I2C_SetAddress(I2C_HandleTypeDef *i2c, uint16_t DevAddress) { if (i2c->I2C_InitObj.AddressMode == I2C_ADDR_10BIT) { I2C_Set10bitAddress(i2c->I2Cx, DevAddress); } else { I2C_Set7bitAddress(i2c->I2Cx, (uint8_t)DevAddress); } i2c->I2Cx->SDA_HOLD = ((0x3 << 16) | 0x3); } void HAL_I2C_DeInit(I2C_HandleTypeDef *i2c) { I2C_Cmd(i2c->I2Cx, DISABLE); I2C_DisableAllIT(i2c->I2Cx); CLK_APB1PeriphClockCmd(CLK_APB1Periph_I2C0, DISABLE); } void HAL_I2C_Init_INT(I2C_HandleTypeDef *i2c) { I2C_Cmd(i2c->I2Cx, DISABLE); I2C_DisableAllIT(i2c->I2Cx); I2C_ITConfig(i2c->I2Cx, I2C_IT_START_DET | I2C_IT_RX_FULL | I2C_IT_RD_REQ | I2C_IT_STOP_DET, ENABLE); /* I2C Peripheral Enable */ I2C_Cmd(i2c->I2Cx, ENABLE); I2C_SetTxTirggerLevel(i2c->I2Cx, I2C_TX_TL_0); I2C_SetRxTirggerLevel(i2c->I2Cx, I2C_RX_TL_0); } void HAL_I2C_DeInit_INT(I2C_HandleTypeDef *i2c) { I2C_DisableAllIT(i2c->I2Cx); } void HAL_I2C_Master_SendData(I2C_HandleTypeDef *i2c, uint16_t DevAddress, uint8_t *Buf, uint32_t Size, uint32_t Timeout) { HAL_I2C_SetAddress(i2c, DevAddress); while (Size) { while (!I2C_GetFlagStatus(i2c->I2Cx, I2C_FLAG_TFNF)) ; if (Size > 1) i2c->I2Cx->DATACMD = ((I2C_CMD_WR << 8) | (*Buf & 0xFF)); else { if (I2C_CON_MASTER_MODE & i2c->I2Cx->CON) i2c->I2Cx->DATACMD = ((I2C_CMD_STOP << 8) | (*Buf & 0xFF)); else i2c->I2Cx->DATACMD = ((I2C_CMD_WR << 8) | (*Buf & 0xFF)); } Buf++; Size--; } } void HAL_I2C_Master_ReceiveData(I2C_HandleTypeDef *i2c, uint16_t DevAddress, uint8_t *Buf, uint32_t Size, uint32_t Timeout) { HAL_I2C_SetAddress(i2c, DevAddress); while (Size) { if (I2C_CON_MASTER_MODE & i2c->I2Cx->CON) { while (!I2C_GetFlagStatus(i2c->I2Cx, I2C_FLAG_TFNF)) { } if (Size > 1) { I2C_SendCmd(i2c->I2Cx, I2C_CMD_RD); } else { I2C_SendCmd(i2c->I2Cx, I2C_CMD_RD | I2C_CMD_STOP); } } while (!I2C_GetFlagStatus(i2c->I2Cx, I2C_FLAG_RFNE)) { } *Buf = (uint8_t)i2c->I2Cx->DATACMD; Buf++; Size--; } } void HAL_I2C_Master_SendData_INT(I2C_HandleTypeDef *i2c, uint16_t DevAddress, uint8_t *Buf, uint32_t Size, I2C_CallbackFunc Callback) { i2c->pTxBuffPtr = Buf; i2c->TxXferSize = Size; i2c->TxXferCount = 0; i2c->TxIntCallback = Callback; I2C_Cmd(i2c->I2Cx, DISABLE); HAL_I2C_SetAddress(i2c, DevAddress); I2C_DisableAllIT(i2c->I2Cx); I2C_ITConfig(i2c->I2Cx, I2C_IT_TX_EMPTY | I2C_IT_START_DET | I2C_IT_RX_FULL | I2C_IT_RD_REQ | I2C_IT_STOP_DET, ENABLE); /* I2C Peripheral Enable */ I2C_Cmd(i2c->I2Cx, ENABLE); I2C_SetTxTirggerLevel(i2c->I2Cx, I2C_TX_TL_4); NVIC_EnableIRQ(i2c->IRQn); while (!I2C_GetFlagStatus(i2c->I2Cx, I2C_FLAG_TFNF)); I2C_SendDataCmd(I2C0, *i2c->pTxBuffPtr, I2C_CMD_WR); i2c->TxXferCount++; } void HAL_I2C_Master_ReceiveData_INT(I2C_HandleTypeDef *i2c, uint16_t DevAddress, uint8_t *Buf, uint32_t Size, I2C_CallbackFunc Callback) { i2c->pRxBuffPtr = Buf; i2c->RxXferSize = Size; i2c->RxXferCount = 0; i2c->RxIntCallback = Callback; I2C_Cmd(i2c->I2Cx, DISABLE); HAL_I2C_SetAddress(i2c, DevAddress); I2C_DisableAllIT(i2c->I2Cx); I2C_ITConfig(i2c->I2Cx, I2C_IT_START_DET | I2C_IT_RX_FULL | I2C_IT_RD_REQ | I2C_IT_STOP_DET, ENABLE); /* I2C Peripheral Enable */ I2C_Cmd(i2c->I2Cx, ENABLE); I2C_SetRxTirggerLevel(i2c->I2Cx, I2C_RX_TL_0); NVIC_EnableIRQ(i2c->IRQn); while (!I2C_GetFlagStatus(i2c->I2Cx, I2C_FLAG_TFNF)); I2C_SendCmd(i2c->I2Cx, I2C_CMD_RD); } void HAL_I2C_Master_SendData_DMA(I2C_HandleTypeDef *i2c, uint16_t DevAddress, uint8_t *Buf, uint32_t Size, I2C_CallbackFunc Callback) { HAL_I2C_SetAddress(i2c, DevAddress); i2c->pTxBuffPtr = Buf; i2c->TxXferSize = Size; i2c->TxXferCount = 0; I2C_SetTxTirggerLevel(i2c->I2Cx, I2C_TX_TL_0); I2C_DMATransferDataLevel(i2c->I2Cx, I2C_TX_TL_0); I2C_DMACmd(i2c->I2Cx, ENABLE); // Initialize the DMA controller DMAC_Init(DMA); NVIC_EnableIRQ(DMA_IRQn); uint32_t DmaChNum = 0xFF; DmaChNum = DMAC_AcquireChannel(DMA); dma_mem2i2c_config.PeripheralDst = i2c->DMA_DST; DMAC_Channel_Array[DmaChNum].ConfigTmp = dma_mem2i2c_config; DMAC_Channel_Array[DmaChNum].CallbackI2c = Callback; DMAC_Channel_Array[DmaChNum].XferFlag = false; DMAC_Channel_Array[DmaChNum].pBuffPtr = (uint32_t *)i2c->pTxBuffPtr; DMAC_Channel_Array[DmaChNum].XferSize = i2c->TxXferSize; DMAC_Channel_Array[DmaChNum].PeriMode = DMAC_Peri_I2C; /*enable dma transfer interrupt*/ DMAC_ClrIntFlagMsk(DMA, DmaChNum, DMAC_FLAG_INDEX_TFR); DMAC_SetChannelConfig(DMA, DmaChNum, &DMAC_Channel_Array[DmaChNum].ConfigTmp); /*start dma tx channel*/ DMAC_StartChannel(DMA, DmaChNum, i2c->pTxBuffPtr, (void *)&(i2c->I2Cx->DATACMD), i2c->TxXferSize); } static void HAL_I2C_Master_SendData_DMA_U16_STC(I2C_HandleTypeDef *i2c, uint16_t DevAddress, uint16_t *Buf, uint32_t Size, I2C_CallbackFunc Callback) { HAL_I2C_SetAddress(i2c, DevAddress); i2c->TxXferSize = Size; i2c->TxXferCount = 0; I2C_SetTxTirggerLevel(i2c->I2Cx, I2C_TX_TL_0); I2C_DMATransferDataLevel(i2c->I2Cx, I2C_TX_TL_0); I2C_SetRxTirggerLevel(i2c->I2Cx, I2C_RX_TL_3); I2C_DMAReceiveDataLevel(i2c->I2Cx, I2C_RX_TL_3); // Initialize the DMA controller DMAC_Init(DMA); NVIC_EnableIRQ(DMA_IRQn); uint32_t DmaChNum = 0xFF; DmaChNum = DMAC_AcquireChannel(DMA); dma_mem2i2c_config.PeripheralDst = i2c->DMA_DST; DMAC_Channel_Array[DmaChNum].ConfigTmp = dma_mem2i2c_u16_config; DMAC_Channel_Array[DmaChNum].CallbackI2c = Callback; DMAC_Channel_Array[DmaChNum].XferFlag = false; DMAC_Channel_Array[DmaChNum].pBuffPtr = (uint32_t *)Buf; DMAC_Channel_Array[DmaChNum].XferSize = i2c->TxXferSize; DMAC_Channel_Array[DmaChNum].PeriMode = DMAC_Peri_I2C; /*enable dma transfer interrupt*/ DMAC_ClrIntFlagMsk(DMA, DmaChNum, DMAC_FLAG_INDEX_TFR); DMAC_SetChannelConfig(DMA, DmaChNum, &DMAC_Channel_Array[DmaChNum].ConfigTmp); /*start dma tx channel*/ DMAC_StartChannel(DMA, DmaChNum, Buf, (void *)&(i2c->I2Cx->DATACMD), i2c->TxXferSize); } static uint16_t cmd_buf[256]={0}; void HAL_I2C_Master_ReceiveData_DMA(I2C_HandleTypeDef *i2c, uint16_t DevAddress, uint8_t *Buf, uint32_t Size, I2C_CallbackFunc Callback) { uint16_t i; for(i=0;ipRxBuffPtr = Buf; i2c->RxXferSize = Size; i2c->RxXferCount = 0; uint32_t DmaChNum = 0xFF; /*get free dma channel;*/ DmaChNum = DMAC_AcquireChannel(DMA); /*enable dma transfer interrupt*/ DMAC_ClrIntFlagMsk(DMA, DmaChNum, DMAC_FLAG_INDEX_TFR); dma_i2c2mem_config.PeripheralSrc = i2c->DMA_SRC; DMAC_Channel_Array[DmaChNum].ConfigTmp = dma_i2c2mem_config; DMAC_Channel_Array[DmaChNum].CallbackI2c = Callback; DMAC_Channel_Array[DmaChNum].XferFlag = false; DMAC_Channel_Array[DmaChNum].pBuffPtr = (uint32_t*)i2c->pRxBuffPtr; DMAC_Channel_Array[DmaChNum].XferSize = i2c->RxXferSize; DMAC_Channel_Array[DmaChNum].PeriMode = DMAC_Peri_I2C; DMAC_SetChannelConfig(DMA, DmaChNum, &DMAC_Channel_Array[DmaChNum].ConfigTmp); /*start dma tx channel*/ DMAC_StartChannel(DMA, DmaChNum, (void *)&(i2c->I2Cx->DATACMD), i2c->pRxBuffPtr, i2c->RxXferSize); I2C_DMACmd(i2c->I2Cx, ENABLE); } void HAL_I2C_Slave_SendData(I2C_HandleTypeDef *i2c, uint8_t *Buf, uint32_t Size, uint32_t Timeout) { while (1) { if (I2C_GetRawITStatus(i2c->I2Cx, I2C_IT_RD_REQ)) { while (!I2C_GetFlagStatus(i2c->I2Cx, I2C_FLAG_TFNF)) ; if (I2C_CON_MASTER_MODE & i2c->I2Cx->CON) i2c->I2Cx->DATACMD = ((I2C_CMD_STOP << 8) | (*Buf & 0xFF)); else i2c->I2Cx->DATACMD = ((I2C_CMD_WR << 8) | (*Buf & 0xFF)); Buf++; I2C_ClearITPendingBit(i2c->I2Cx, I2C_IT_RD_REQ); } if (I2C_GetRawITStatus(i2c->I2Cx, I2C_IT_STOP_DET)) { I2C_ClearITPendingBit(i2c->I2Cx, I2C_IT_STOP_DET); break; } } } void HAL_I2C_Slave_ReceiveData(I2C_HandleTypeDef *i2c, uint8_t *Buf, uint32_t Size, uint32_t Timeout) { while (Size) { if (I2C_CON_MASTER_MODE & i2c->I2Cx->CON) { while (!I2C_GetFlagStatus(i2c->I2Cx, I2C_FLAG_TFNF)) { } if (Size > 1) { I2C_SendCmd(i2c->I2Cx, I2C_CMD_RD); } else { I2C_SendCmd(i2c->I2Cx, I2C_CMD_RD | I2C_CMD_STOP); } } while (!I2C_GetFlagStatus(i2c->I2Cx, I2C_FLAG_RFNE)) { } *Buf = (uint8_t)i2c->I2Cx->DATACMD; Buf++; Size--; } } void HAL_I2C_Slave_SendData_INT(I2C_HandleTypeDef *i2c, uint8_t *Buf, uint32_t Size, I2C_CallbackFunc Callback) { // i2c->Xfer_Dir = I2C_Tx_Dir; i2c->pTxBuffPtr = Buf; i2c->TxXferSize = Size; i2c->TxXferCount = 0; i2c->TxIntCallback = Callback; I2C_Cmd(i2c->I2Cx, DISABLE); I2C_DisableAllIT(i2c->I2Cx); I2C_ITConfig(i2c->I2Cx, I2C_IT_START_DET | I2C_IT_RX_FULL | I2C_IT_RD_REQ | I2C_IT_STOP_DET, ENABLE); /* I2C Peripheral Enable */ I2C_Cmd(i2c->I2Cx, ENABLE); // I2C_SetTxTirggerLevel(i2c->I2Cx, I2C_TX_TL_0); NVIC_EnableIRQ(i2c->IRQn); } void HAL_I2C_Slave_ReceiveData_INT(I2C_HandleTypeDef *i2c, uint8_t *Buf, uint32_t Size, I2C_CallbackFunc Callback) { i2c->pRxBuffPtr = Buf; i2c->RxXferSize = Size; i2c->RxXferCount = 0; i2c->RxIntCallback = Callback; I2C_Cmd(i2c->I2Cx, DISABLE); I2C_DisableAllIT(i2c->I2Cx); I2C_ITConfig(i2c->I2Cx, I2C_IT_START_DET | I2C_IT_RX_FULL | I2C_IT_RD_REQ | I2C_IT_STOP_DET, ENABLE); /* I2C Peripheral Enable */ I2C_Cmd(i2c->I2Cx, ENABLE); I2C_SetRxTirggerLevel(i2c->I2Cx, I2C_RX_TL_8); NVIC_EnableIRQ(i2c->IRQn); } void HAL_I2C_Slave_SendData_DMA(I2C_HandleTypeDef *i2c, uint8_t *Buf, uint32_t Size, I2C_CallbackFunc Callback) { i2c->pTxBuffPtr = Buf; i2c->TxXferSize = Size; i2c->TxXferCount = 0; I2C_SetTxTirggerLevel(i2c->I2Cx, I2C_TX_TL_3); I2C_SetRxTirggerLevel(i2c->I2Cx, I2C_RX_TL_3); I2C_DMATransferDataLevel(i2c->I2Cx, I2C_TX_TL_3); I2C_DMAReceiveDataLevel(i2c->I2Cx, I2C_RX_TL_3); // Initialize the DMA controller DMAC_Init(DMA); NVIC_EnableIRQ(DMA_IRQn); uint32_t DmaChNum = 0xFF; /*get free dma channel;*/ DmaChNum = DMAC_AcquireChannel(DMA); /*enable dma transfer interrupt*/ DMAC_ClrIntFlagMsk(DMA, DmaChNum, DMAC_FLAG_INDEX_TFR); dma_mem2i2c_config.PeripheralDst = i2c->DMA_DST; DMAC_Channel_Array[DmaChNum].ConfigTmp = dma_mem2i2c_config; DMAC_Channel_Array[DmaChNum].CallbackI2c = Callback; DMAC_Channel_Array[DmaChNum].XferFlag = false; DMAC_Channel_Array[DmaChNum].pBuffPtr = (uint32_t *)i2c->pTxBuffPtr; DMAC_Channel_Array[DmaChNum].XferSize = i2c->TxXferSize; DMAC_Channel_Array[DmaChNum].PeriMode = DMAC_Peri_I2C; DMAC_SetChannelConfig(DMA, DmaChNum, &DMAC_Channel_Array[DmaChNum].ConfigTmp); /*start dma tx channel*/ DMAC_StartChannel(DMA, DmaChNum, i2c->pTxBuffPtr, (void *)&(i2c->I2Cx->DATACMD), i2c->TxXferSize/4); while(!I2C_GetRawITStatus(i2c->I2Cx, I2C_IT_RD_REQ)){} I2C_DMACmd(i2c->I2Cx, ENABLE); I2C_ClearITPendingBit(i2c->I2Cx, I2C_IT_RD_REQ); } void HAL_I2C_Slave_ReceiveData_DMA(I2C_HandleTypeDef *i2c, uint8_t *Buf, uint32_t Size, I2C_CallbackFunc Callback) { i2c->pRxBuffPtr = Buf; i2c->RxXferSize = Size; i2c->RxXferCount = 0; I2C_SetRxTirggerLevel(i2c->I2Cx, I2C_RX_TL_3); I2C_DMAReceiveDataLevel(i2c->I2Cx, I2C_RX_TL_3); I2C_DMACmd(i2c->I2Cx, ENABLE); // Initialize the DMA controller DMAC_Init(DMA); NVIC_EnableIRQ(DMA_IRQn); uint32_t DmaChNum = 0xFF; DmaChNum = DMAC_AcquireChannel(DMA); DMAC_ClrIntFlagMsk(DMA, DmaChNum, DMAC_FLAG_INDEX_TFR); dma_i2c2mem_config.PeripheralSrc = i2c->DMA_SRC; DMAC_Channel_Array[DmaChNum].ConfigTmp = dma_i2c2mem_config; DMAC_Channel_Array[DmaChNum].CallbackI2c = Callback; DMAC_Channel_Array[DmaChNum].XferFlag = false; DMAC_Channel_Array[DmaChNum].pBuffPtr = (uint32_t *)i2c->pRxBuffPtr; DMAC_Channel_Array[DmaChNum].XferSize = i2c->RxXferSize; DMAC_Channel_Array[DmaChNum].PeriMode = DMAC_Peri_I2C; DMAC_SetChannelConfig(DMA, DmaChNum, &DMAC_Channel_Array[DmaChNum].ConfigTmp); /*start dma tx channel*/ DMAC_StartChannel(DMA, DmaChNum, (void *)&(i2c->I2Cx->DATACMD), i2c->pRxBuffPtr, i2c->RxXferSize); } void I2C0_IRQHandler() { if (I2C_GetITStatus(I2C0, I2C_IT_TX_EMPTY)) { while (I2C_GetFlagStatus(I2C0, I2C_FLAG_TFNF) == 0); if (I2C_INST_PTR->I2C_InitObj.Role == I2C_ROLE_MASTER) { if ((I2C_INST_PTR->TxXferCount + 1) == I2C_INST_PTR->TxXferSize) { I2C_INST_PTR->I2Cx->DATACMD = (((I2C_CMD_STOP) << 8) | (I2C_INST_PTR->pTxBuffPtr[I2C_INST_PTR->TxXferCount] & 0xFF)); } else { I2C_INST_PTR->I2Cx->DATACMD = ((I2C_CMD_WR << 8) | (I2C_INST_PTR->pTxBuffPtr[I2C_INST_PTR->TxXferCount] & 0xFF)); } I2C_INST_PTR->TxXferCount++; if (I2C_INST_PTR->TxXferCount >= I2C_INST_PTR->TxXferSize) { I2C_ITConfig(I2C_INST_PTR->I2Cx, I2C_IT_TX_EMPTY, DISABLE); if (I2C_INST_PTR->TxIntCallback != NULL) { I2C_INST_PTR->TxIntCallback(I2C_CB_FLAG_STOP, I2C_INST_PTR->pTxBuffPtr, I2C_INST_PTR->TxXferCount); } } } } if (I2C_GetITStatus(I2C_INST_PTR->I2Cx, I2C_IT_START_DET)) { I2C_ClearITPendingBit(I2C_INST_PTR->I2Cx, I2C_IT_START_DET); } if (I2C_GetITStatus(I2C_INST_PTR->I2Cx, I2C_IT_TX_ABORT)) { I2C_ClearITPendingBit(I2C_INST_PTR->I2Cx, I2C_IT_TX_ABORT); } if (I2C_GetITStatus(I2C_INST_PTR->I2Cx, I2C_IT_RX_FULL)) { while (I2C_GetFlagStatus(I2C_INST_PTR->I2Cx, I2C_FLAG_RFNE)) { I2C_INST_PTR->pRxBuffPtr[I2C_INST_PTR->RxXferCount++] = I2C_ReceiveData(I2C_INST_PTR->I2Cx); if (I2C_INST_PTR->I2C_InitObj.Role == I2C_ROLE_MASTER) { if(I2C_INST_PTR->RxXferCount < (I2C_INST_PTR->RxXferSize)){ if ((I2C_INST_PTR->RxXferCount + 1) == I2C_INST_PTR->RxXferSize) { I2C_SendCmd(I2C_INST_PTR->I2Cx, I2C_CMD_RD|I2C_CMD_STOP); }else { I2C_SendCmd(I2C_INST_PTR->I2Cx, I2C_CMD_RD); } } } if (I2C_INST_PTR->RxXferCount == I2C_INST_PTR->RxXferSize) { if (I2C_INST_PTR->RxIntCallback != NULL) { I2C_INST_PTR->RxIntCallback(I2C_CB_FLAG_STOP, I2C_INST_PTR->pRxBuffPtr, I2C_INST_PTR->RxXferCount); } } } I2C_ClearITPendingBit(I2C_INST_PTR->I2Cx, I2C_IT_RX_FULL); } if (I2C_GetITStatus(I2C_INST_PTR->I2Cx, I2C_IT_STOP_DET)) { while (I2C_GetFlagStatus(I2C_INST_PTR->I2Cx, I2C_FLAG_RFNE)) { } I2C_ClearITPendingBit(I2C_INST_PTR->I2Cx, I2C_IT_STOP_DET); } if (I2C_GetITStatus(I2C_INST_PTR->I2Cx, I2C_IT_RD_REQ)) { I2C_ClearITPendingBit(I2C0, I2C_IT_RD_REQ); while (I2C_GetFlagStatus(I2C_INST_PTR->I2Cx, I2C_FLAG_TFNF) == 0);// wait tx fifo no full if (I2C_INST_PTR->I2C_InitObj.Role == I2C_ROLE_SLAVE) { I2C_SendData(I2C0, I2C_INST_PTR->pTxBuffPtr[I2C_INST_PTR->TxXferCount]); I2C_INST_PTR->TxXferCount++; if (I2C_INST_PTR->TxXferCount >= I2C_INST_PTR->TxXferSize) { if (I2C_INST_PTR->TxIntCallback != NULL) { I2C_INST_PTR->TxIntCallback(I2C_CB_FLAG_STOP, I2C_INST_PTR->pTxBuffPtr, I2C_INST_PTR->TxXferCount); } } } } }