uint8_t i2cMgr_t::CheckAddrRXSending() { uint32_t IEvt = I2C_GetLastEvent(I2C1); if (IEvt == I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) return I2C_OK; if (IEvt & I2C_EVENT_SLAVE_ACK_FAILURE) return I2C_ERR_SLAVE_NACK; // NACK occured, slave doesn't answer if (Delay.Elapsed(&Timer, I2C_TIMEOUT_MS)) return I2C_ERR_TIMEOUT; return I2C_WAITING; }
void arch_I2cReset(p_dev_i2c p) { I2C_TypeDef *pI2c = stm32_tblI2cId[p->parent->id]; GPIO_InitTypeDef xGPIO; uint32_t nEvent; arch_I2cInit(p); sys_Delay(200); nEvent = I2C_GetLastEvent(pI2c); if (nEvent & I2C_FLAG_BUSY) { //I2C bus recovery I2C_Cmd(pI2c, DISABLE); xGPIO.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; xGPIO.GPIO_Speed = GPIO_Speed_50MHz; xGPIO.GPIO_Mode = GPIO_Mode_OUT; xGPIO.GPIO_OType = GPIO_OType_PP; GPIO_Init(GPIOB, &xGPIO); //generate manual STOP condition GPIO_ResetBits(GPIOB, GPIO_Pin_6); GPIO_ResetBits(GPIOB, GPIO_Pin_7); sys_Delay(200); GPIO_ResetBits(GPIOB, GPIO_Pin_6); sys_Delay(200); GPIO_SetBits(GPIOB, GPIO_Pin_7); sys_Delay(400); xGPIO.GPIO_Mode = GPIO_Mode_AF; xGPIO.GPIO_OType = GPIO_OType_OD; GPIO_Init(GPIOB, &xGPIO); I2C_Cmd(pI2c, ENABLE); } }
/** * @brief Read a byte from the slave. * @param ne. * @retval : The read data byte. */ uint8_t I2C_Master_BufferRead1Byte(void) { uint8_t Data; __IO uint32_t temp; /* Send START condition */ I2C_GenerateSTART(I2C1, ENABLE); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); /* Send EEPROM address for read */ I2C_Send7bitAddress(I2C1, SLAVE_ADDRESS, I2C_Direction_Receiver); /* Wait until ADDR is set */ while (!I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR)); /* Clear ACK */ I2C_AcknowledgeConfig(I2C1, DISABLE); __disable_irq(); /* Clear ADDR flag */ temp = I2C1->SR2; /* Program the STOP */ I2C_GenerateSTOP(I2C1, ENABLE); __enable_irq(); while ((I2C_GetLastEvent(I2C1) & 0x0040) != 0x000040); /* Poll on RxNE */ /* Read the data */ Data = I2C_ReceiveData(I2C1); /* Make sure that the STOP bit is cleared by Hardware before CR1 write access */ while ((I2C1->CR1&0x200) == 0x200); /* Enable Acknowledgement to be ready for another reception */ I2C_AcknowledgeConfig(I2C1, ENABLE); return(Data); }
/** * @brief Read 2 data from the slave using Polling. * @param pBuffer : Buffer of bytes read from the slave. * @retval : None */ void I2C_Master_BufferRead2Byte(uint8_t* pBuffer) { __IO uint32_t temp; /* Send START condition */ I2C_GenerateSTART(I2C1, ENABLE); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); /* Send EEPROM address for read */ I2C_Send7bitAddress(I2C1, SLAVE_ADDRESS, I2C_Direction_Receiver); I2C1->CR1 = 0xC01; /* ACK=1; POS =1 */ while (!I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR)); __disable_irq(); /* Clear ADDR */ temp = I2C1->SR2; /* Disable ACK */ I2C_AcknowledgeConfig(I2C1, DISABLE); __enable_irq(); while ((I2C_GetLastEvent(I2C1) & 0x0004) != 0x00004); /* Poll on BTF */ __disable_irq(); /* Program the STOP */ I2C_GenerateSTOP(I2C1, ENABLE); /* Read first data */ *pBuffer = I2C1->DR; pBuffer++; /* Read second data */ *pBuffer = I2C1->DR; __enable_irq(); I2C1->CR1 = 0x0401; /* POS = 0, ACK = 1, PE = 1 */ }
void i2c2_ev_irq_handler(void) { switch (I2C_GetLastEvent(I2C2)) { /* Slave Transmitter ---------------------------------------------------*/ case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED: /* EV1 */ memcpy(i2c2_buf, coder_values, MY_I2C2_BUF_LEN); i2c2_idx = 0; case I2C_EVENT_SLAVE_BYTE_TRANSMITTED: /* EV3 */ /* Transmit I2C2 data */ if (i2c2_idx < MY_I2C2_BUF_LEN) { I2C_SendData(I2C2, i2c2_buf[i2c2_idx]); i2c2_idx++; } break; case I2C_EVENT_SLAVE_STOP_DETECTED: /* EV4 */ LED_ON(1); /* Clear I2C2 STOPF flag: read of I2C_SR1 followed by a write on I2C_CR1 */ (void)(I2C_GetITStatus(I2C2, I2C_IT_STOPF)); I2C_Cmd(I2C2, ENABLE); break; } }
static rt_size_t stm_i2c_mst_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num) { struct stm32_i2c_bus *stm32_i2c; rt_uint32_t numbak = num; RT_ASSERT(bus != RT_NULL); stm32_i2c = (struct stm32_i2c_bus *) bus; stm32_i2c->msg = msgs; stm32_i2c->msg_ptr = 0; stm32_i2c->msg_cnt = num; stm32_i2c->dptr = 0; stm32_i2c->wait_stop = 0; I2C_GetLastEvent(stm32_i2c->I2C); while(stm32_i2c->msg_ptr < stm32_i2c->msg_cnt) { stm32_i2c->wait_stop = 0; if(!(stm32_i2c->msg[stm32_i2c->msg_ptr].flags & RT_I2C_NO_START)) { stm32_i2c->I2C->CR1 |= CR1_START_Set; } stm32_i2c_wait_ev(stm32_i2c, EV_END, 1000); } stm32_i2c->msg = RT_NULL; stm32_i2c->msg_ptr = 0; stm32_i2c->msg_cnt = 0; stm32_i2c->dptr = 0; stm32_i2c->wait_stop = 0; return numbak; }
uint8_t i2cMgr_t::CheckOneByteWriting() { uint32_t IEvt = I2C_GetLastEvent(I2C1); if (IEvt == I2C_EVENT_MASTER_BYTE_TRANSMITTED) return I2C_OK; if (IEvt & I2C_EVENT_SLAVE_ACK_FAILURE) return I2C_ERR_SLAVE_NACK; // NACK occured, slave doesn't answer if (Delay.Elapsed(&Timer, I2C_TIMEOUT_MS)) return I2C_ERR_TIMEOUT; return I2C_WAITING; }
//______________________________________________________________________________________ void I2C1_EV_IRQHandler(void) { static int n=0; switch (I2C_GetLastEvent(I2C1)) { case I2C_EVENT_MASTER_MODE_SELECT : if(__i2c1->ntx) I2C_Send7bitAddress(I2C1, (uint8_t)(__i2c1->addr)<<1, I2C_Direction_Transmitter); else I2C_Send7bitAddress(I2C1, (uint8_t)(__i2c1->addr)<<1, I2C_Direction_Receiver); n=0; break; case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: I2C_SendData(I2C1, __i2c1->txbuf[n++]); break; case I2C_EVENT_MASTER_BYTE_TRANSMITTING: case I2C_EVENT_MASTER_BYTE_TRANSMITTED: if (n == __i2c1->ntx) { __i2c1->ntx=0; if(__i2c1->nrx) I2C_GenerateSTART(I2C1, ENABLE); else { I2C_GenerateSTOP(I2C1, ENABLE); I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, DISABLE); } } else I2C_SendData(I2C1, __i2c1->txbuf[n++]); break; case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED: if(__i2c1->nrx==1) { I2C_AcknowledgeConfig(I2C1, DISABLE); I2C_GenerateSTOP(I2C1, ENABLE); } break; case I2C_EVENT_MASTER_BYTE_RECEIVED: __i2c1->rxbuf[n++]=I2C_ReceiveData (I2C1); if(n==__i2c1->nrx-1) { I2C_AcknowledgeConfig(I2C1, DISABLE); I2C_GenerateSTOP(I2C1, ENABLE); } if(n==__i2c1->nrx) { I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, DISABLE); I2C_AcknowledgeConfig(I2C1, ENABLE); __i2c1->nrx=0; } break; default: break; } }
uint8_t i2cMgr_t::CheckOneByteReading() { uint32_t IEvt = I2C_GetLastEvent(I2C1); if (IEvt & I2C_FLAG_RXNE) { uint8_t b = I2C_ReceiveData(I2C1); // Write data if buffer is not NULL if(CmdToRead->DataToRead.Buf != 0) CmdToRead->DataToRead.Buf[0] = b; return I2C_OK; } if (Delay.Elapsed(&Timer, I2C_TIMEOUT_MS)) return I2C_ERR_TIMEOUT; return I2C_WAITING; }
/************************************************************************* * Function Name: I2C1_ErrIntrHandler * Parameters: none * * Return: none * * Description: I2C1 error interrupt handler * *************************************************************************/ void I2C1_ER_IRQHandler(void) { if(I2C_EVENT_SLAVE_ACK_FAILURE & I2C_GetLastEvent(I2C1)) { // Generate Stop condition (return back to slave mode) I2C_GenerateSTOP(I2C1,ENABLE); I2C_ClearFlag(I2C1,I2C_FLAG_AF); } s_Done = TRUE; s_Error = TRUE; }
static void AT24Cxx_ack_polling(struct AT24Cxx_init_struct* init) { /* Until ack fails (I2C_FLAG_AF) continue with the polling */ do { I2C_GenerateSTART(init->I2C_peripheral, ENABLE); I2C_Send7bitAddress(init->I2C_peripheral, init->I2C_address, I2C_Direction_Transmitter); } while((I2C_GetLastEvent(init->I2C_peripheral) & I2C_FLAG_AF)); I2C_ClearFlag(init->I2C_peripheral, I2C_FLAG_AF); I2C_GenerateSTOP(init->I2C_peripheral, ENABLE); }
char I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction) { char status = 0; uint32_t lastFlag = 0; address = address << 1; // wait until I2C1 is not busy anymore //while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)); while((GPIOB->IDR)&0xC00 == (GPIO_IDR_IDR_10 | GPIO_IDR_IDR_11)); // Send I2C1 START condition I2Cx->CR1 |= I2C_CR1_START; // wait for I2C1 EV5 --> Slave has acknowledged start condition //while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)); while (lastFlag != I2C_EVENT_MASTER_MODE_SELECT) { lastFlag = I2C_GetLastEvent(I2C2); if ((lastFlag & I2C_FLAG_AF) || (lastFlag & I2C_FLAG_BERR)) { status = 0; break; } else status = 1; } // Send slave Address for write I2C_Send7bitAddress(I2Cx, address, direction); /* wait for I2C1 EV6, check if * either Slave has acknowledged Master transmitter or * Master receiver mode, depending on the transmission * direction */ // if(direction == I2C_Direction_Transmitter) // while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); // else // if(direction == I2C_Direction_Receiver) while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { if (((I2C2->SR1)&I2C_SR1_AF) || ((I2C2->SR1)&I2C_SR1_BERR)) { status = 0; break; } else status = 1; } return status; }
/************************************************************************* * Function Name: I2C1_EvnIntrHandler * Parameters: none * * Return: none * * Description: I2C1 event interrupt handler * *************************************************************************/ void I2C1_EV_IRQHandler(void) { switch (I2C_GetLastEvent(I2C1)) { case I2C_EVENT_MASTER_MODE_SELECT: I2C_SendData(I2C1,s_SlaveAddr); if(0 == s_Size) { I2C_GenerateSTOP(I2C1,ENABLE); s_Done = TRUE; } break; case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: case I2C_EVENT_MASTER_BYTE_TRANSMITTED: if(0 == s_Size) { s_Done = TRUE; } else { --s_Size; I2C_SendData(I2C1,*s_pData++); if(0 == s_Size) { I2C_GenerateSTOP(I2C1,ENABLE); } } break; case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED: if (1 == s_Size) { I2C_AcknowledgeConfig(I2C1,DISABLE); I2C_GenerateSTOP(I2C1,ENABLE); } break; case I2C_EVENT_MASTER_BYTE_RECEIVED: if (1 == --s_Size) { I2C_GenerateSTOP(I2C1,ENABLE); I2C_AcknowledgeConfig(I2C1,DISABLE); } *s_pData++ = I2C_ReceiveData(I2C1); if (0 == s_Size) { s_Done = TRUE; } break; } }
/** * @brief Send a buffer of bytes to the slave. * @param pBuffer: Buffer of bytes to be sent to the slave. * @param NumByteToRead: Number of bytes to be sent to the slave. * @retval : None. */ void I2C_Master_BufferWrite(uint8_t* pBuffer, uint16_t NumByteToWrite) { #ifdef DMA_Master_Transmit DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)pBuffer; DMA_InitStructure.DMA_BufferSize = NumByteToWrite; DMA_Init(DMA1_Channel6, &DMA_InitStructure); I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE); I2C_DMACmd(I2C1, ENABLE); I2C_GenerateSTART(I2C1, ENABLE); DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE); #endif #ifdef Polling_Master_Transmit /* Send START condition */ I2C_GenerateSTART(I2C1, ENABLE); /* Test on EV5 and clear it */ while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); /* Send slave address for write */ I2C_Send7bitAddress(I2C1,SLAVE_ADDRESS, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C1, *pBuffer); pBuffer++; NumByteToWrite--; /* While there is data to be written */ while (NumByteToWrite--) { while ((I2C_GetLastEvent(I2C1) & 0x04) != 0x04); /* Poll on BTF */ /* Send the current byte */ I2C_SendData(I2C1, *pBuffer); /* Point to the next byte to be written */ pBuffer++; } /* Test on EV8_2 and clear it, BTF = TxE = 1, DR and shift registers are empty */ while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); /* Send STOP condition */ I2C_GenerateSTOP(I2C1, ENABLE); #endif }
/******************************************************************************* * Function Name : I2C_CheckEvent * Description : Checks whether the Last I2C Event is equal to the one passed * as parameter. * Input : - I2C_EVENT: specifies the event to be checked. This parameter * can be one of the following values: * - I2C_EVENT_SLAVE_ADDRESS_MATCHED * - I2C_EVENT_SLAVE_BYTE_RECEIVED * - I2C_EVENT_SLAVE_BYTE_TRANSMITTED * - I2C_EVENT_SLAVE_ACK_FAILURE * - I2C_EVENT_MASTER_MODE_SELECT * - I2C_EVENT_MASTER_MODE_SELECTED * - I2C_EVENT_MASTER_BYTE_RECEIVED * - I2C_EVENT_MASTER_BYTE_TRANSMITTED * - I2C_EVENT_MASTER_MODE_ADDRESS10 * - I2C_EVENT_SLAVE_STOP_DETECTED * Output : None * Return : An ErrorStatus enumuration value: * - SUCCESS: Last event is equal to the I2C_Event * - ERROR: Last event is different from the I2C_Event *******************************************************************************/ ErrorStatus I2C_CheckEvent(u16 I2C_EVENT) { u16 LastEvent = I2C_GetLastEvent(); /* Check whether the last event is equal to I2C_EVENT */ if (LastEvent == I2C_EVENT) { /* Return SUCCESS when last event is equal to I2C_EVENT */ return SUCCESS; } else { /* Return ERROR when last event is different from I2C_EVENT */ return ERROR; } }
/** * @brief This function handles I2C1 Event interrupt request. * @param None * @retval : None */ void I2C1_EV_IRQHandler(void) { switch (I2C_GetLastEvent(I2C1)) { case I2C_EVENT_MASTER_MODE_SELECT: /* EV5 */ #if defined (DMA_Master_Transmit) || defined (IT_Master_Transmit) /* Master Transmitter ----------------------------------------------*/ /* Send slave Address for write */ I2C_Send7bitAddress(I2C1, SLAVE_ADDRESS, I2C_Direction_Transmitter); #endif #if defined(DMA_Master_Receive) || defined(IT_Master_Receive) if (slave == 0) { /* Send slave Address for read */ I2C_Send7bitAddress(I2C1,0x28, I2C_Direction_Receiver); slave = 1; } else if (slave ==1) { /* Send slave Address for read */ I2C_Send7bitAddress(I2C1, 0x30, I2C_Direction_Receiver); slave = 0; } #endif break; /* Master Receiver -------------------------------------------------------*/ case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED: #ifdef DMA_Master_Receive DMA_Cmd(DMA1_Channel7, ENABLE); #endif break; default: break; } }
/******************************************************************************* * Function Name : I2C1_IRQHandler * Description : This function handles the I2C1 interrupt request * Input : None * Output : None * Return : None *******************************************************************************/ void I2C1_IRQHandler(void) { switch (I2C_GetLastEvent(I2C1)) { case I2C_EVENT_MASTER_MODE_SELECT: // EV5 I2C_Send7bitAddress(I2C1, I2C_SLAVE_ADDRESS7, Direction); break; case I2C_EVENT_MASTER_MODE_SELECTED: // EV6 // Clear EV6 by set again the PE bit I2C1->CR |= 0x20; if (Direction == I2C_MODE_TRANSMITTER) I2C_SendData(I2C1, I2C1_Buffer_Tx[Tx_Idx++]);//EV8 just after EV6 break; case I2C_EVENT_MASTER_BYTE_TRANSMITTED: // EV8 if ( Tx_Idx == BUFFER_SIZE ) { I2C_GenerateSTOP (I2C1, ENABLE); } else { I2C_SendData(I2C1, I2C1_Buffer_Tx[Tx_Idx]); Tx_Idx++; } break; case I2C_EVENT_MASTER_BYTE_RECEIVED: // EV7 if ( Rx_Idx == BUFFER_SIZE-2 ) { /* Send STOP Condition */ I2C_AcknowledgeConfig (I2C1, DISABLE); } if ( Rx_Idx == BUFFER_SIZE-1 ) /* Send STOP Condition */ I2C_GenerateSTOP(I2C1, ENABLE); I2C1_Buffer_Rx[Rx_Idx] = I2C_ReceiveData(I2C1); Rx_Idx++; break; default: break; } }
/** * @brief Checks whether the last I2C Event is equal to the one passed * as parameter. * @param Event: specifies the event to be checked. * This parameter can be one of the values discribed in * @ref I2C_EVENTS or user specified combination of flags * (@ref I2C_FLAGS). * * @note: For detailed description of Events, please refer to section * @ref I2C_EVENTS in MDR32F9Qx_i2c.h file. * * @retval An ErrorStatus enumuration value: * - SUCCESS: Last event is equal to the Event; * - ERROR: Last event is different from the Event. */ ErrorStatus I2C_CheckEvent(uint32_t Event) { ErrorStatus errstatus; assert_param(IS_I2C_FLAGS(Event)); if ((I2C_GetLastEvent() & Event) == Event) { errstatus = SUCCESS; } else { errstatus = ERROR; } return errstatus; }
/** * @brief Checks whether the specified I2C flag is set or not. * @param Flag: specifies the flag to check. * This parameter can be one of the values: * @arg I2C_FLAG_CMD_NACK Master will be send NACK after reading from Slave; * @arg I2C_FLAG_CMD_ACK Master will be send ACK after reading from Slave; * @arg I2C_FLAG_CMD_WR The Master to Slave transfer in progress; * @arg I2C_FLAG_CMD_nWR No the Master to Slave transfer; * @arg I2C_FLAG_CMD_RD The Slave to Master transfer in progress; * @arg I2C_FLAG_CMD_nRD No the Slave to Master transfer; * @arg I2C_FLAG_STOP STOP condition transfer is selected; * @arg I2C_FLAG_nSTOP STOP condition is resetted; * @arg I2C_FLAG_START START condition transfer is selected; * @arg I2C_FLAG_nSTART START condition is resetted; * @arg I2C_FLAG_IRQ The I2C interrupt pending flag is set; * @arg I2C_FLAG_nIRQ The I2C interrupt pending flag is cleared; * @arg I2C_FLAG_TRANS transfer in progress; * @arg I2C_FLAG_nTRANS No transfer; * @arg I2C_FLAG_LOST_ARB Arbitration is lost at last byte transfer; * @arg I2C_FLAG_ARB_OK Arbitration is Ok at last byte transfer; * @arg I2C_FLAG_BUS_BUSY Some device holds the I2C bus; * @arg I2C_FLAG_BUS_FREE I2C bus is free (SDA = SCL = 1); * @arg I2C_FLAG_SLAVE_NACK Not Acknowledge (NACK) received from Slave; * @arg I2C_FLAG_SLAVE_ACK Acknowledge (ACK) received from Slave. * @retval The new state of I2C_FLAG (SET or RESET). */ FlagStatus I2C_GetFlagStatus(uint32_t Flag) { FlagStatus bitstatus; assert_param(IS_I2C_FLAG(Flag)); if ((I2C_GetLastEvent() & Flag) != 0) { bitstatus = SET; } else { bitstatus = RESET; } return bitstatus; }
uint8_t i2cMgr_t::SendAddrRXPoll(uint8_t AAddr) { uint32_t IEvt; I2C_Send7bitAddress(I2C1, (AAddr << 1), I2C_Direction_Receiver); uint32_t FTimeout = I2C_TIMEOUT; do { IEvt = I2C_GetLastEvent(I2C1); if (IEvt & I2C_EVENT_SLAVE_ACK_FAILURE) { // NACK occured, slave doesn't answer Uart.Printf("I2C Slave Addr RX NACK\r"); return I2C_ERR_SLAVE_NACK; } if ((FTimeout--) == 0) { Uart.Printf("I2C Slave Addr Timeout\r"); return I2C_ERR_TIMEOUT; } } while (IEvt != I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED); //Uart.Printf("I2C Slave Addr RX ACK\r"); return I2C_OK; // all right }
void I2C2_EV_IRQHandler() { uint32_t event = I2C_GetLastEvent(I2C2); switch (event) { case I2C_EVENT_MASTER_MODE_SELECT: break; case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: break; case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED: break; case I2C_EVENT_MASTER_BYTE_TRANSMITTING: break; case I2C_EVENT_MASTER_BYTE_TRANSMITTED: break; case I2C_EVENT_MASTER_BYTE_RECEIVED: break; default: break; } }
uint8_t i2cMgr_t::WriteBytePoll(uint8_t AByte) { uint32_t IEvt; //Uart.Printf("%X\r", AByte); I2C_SendData(I2C1, AByte); // Wait for ok, or for NACK or Timeout uint32_t ITimeout = I2C_TIMEOUT; do { IEvt = I2C_GetLastEvent(I2C1); if (IEvt & I2C_EVENT_SLAVE_ACK_FAILURE) { // NACK occured, slave doesn't answer Uart.Printf("\rI2C Slave NACK\r"); return I2C_ERR_SLAVE_NACK; } if(ITimeout-- == 0) { Uart.Printf("\rI2C Slave Timeout\r"); return I2C_ERR_TIMEOUT; } } while(IEvt != I2C_EVENT_MASTER_BYTE_TRANSMITTED); return I2C_OK; }
/******************************************************************************* * Function Name : I2C2_EV_IRQHandler * Description : This function handles I2C2 Event interrupt request. * Input : None * Output : None * Return : None *******************************************************************************/ void I2C2_EV_IRQHandler(void) { switch (I2C_GetLastEvent(I2C2)) { /* Slave Transmitter ---------------------------------------------------*/ case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED: /* EV1 */ /* Transmit I2C2 data */ I2C_SendData(I2C2, I2C2_Buffer_Tx[Tx2_Idx++]); break; case I2C_EVENT_SLAVE_BYTE_TRANSMITTED: /* EV3 */ /* Transmit I2C2 data */ I2C_SendData(I2C2, I2C2_Buffer_Tx[Tx2_Idx++]); break; /* Slave Receiver ------------------------------------------------------*/ case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: /* EV1 */ break; case I2C_EVENT_SLAVE_BYTE_RECEIVED: /* EV2 */ /* Store I2C2 received data */ I2C2_Buffer_Rx[Rx2_Idx++] = I2C_ReceiveData(I2C2); if(Rx2_Idx == Tx2BufferSize) { I2C_TransmitPEC(I2C2, ENABLE); Direction = Receiver; } break; case I2C_EVENT_SLAVE_STOP_DETECTED: /* EV4 */ /* Clear I2C2 STOPF flag: read of I2C_SR1 followed by a write on I2C_CR1 */ (void)(I2C_GetITStatus(I2C2, I2C_IT_STOPF)); I2C_Cmd(I2C2, ENABLE); break; default: break; } }
int i2c_slave_receive(i2c_t *obj) { int retValue = NoData; uint32_t event; I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); event = I2C_GetLastEvent(i2c); if (event != 0) { switch (event) { case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: retValue = WriteAddressed; break; case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED: retValue = ReadAddressed; break; case I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED: retValue = WriteGeneral; break; default: retValue = NoData; break; } // clear ADDR if ((retValue == WriteAddressed) || (retValue == ReadAddressed)) { // read SR to clear ADDR flag i2c->SR1; i2c->SR2; } // clear stopf if (I2C_GetFlagStatus(i2c, I2C_FLAG_STOPF) == SET) { // read SR1 and write CR1 to clear STOP flag i2c->SR1; I2C_Cmd(i2c, ENABLE); } // clear AF if (I2C_GetFlagStatus(i2c, I2C_FLAG_AF) == SET) { I2C_ClearFlag(i2c, I2C_FLAG_AF); } } return (retValue); }
/******************************************************************************* * Function Name : I2C0_IRQHandler * Description : This function handles the I2C0 interrupt request * Input : None * Output : None * Return : None *******************************************************************************/ void I2C0_IRQHandler(void) { switch (I2C_GetLastEvent(I2C0)) { case I2C_EVENT_SLAVE_ADDRESS_MATCHED: // EV1 break; case I2C_EVENT_SLAVE_BYTE_RECEIVED: // EV2 I2C0_Buffer_Rx[Rx_Idx++] = I2C_ReceiveData(I2C0); break; case I2C_EVENT_SLAVE_BYTE_TRANSMITTED: //only BTF if (EV31count ==1) //workaround { I2C_SendData(I2C0, 0xFF); } else { I2C_SendData(I2C0, I2C0_Buffer_Tx[Tx_Idx]); Tx_Idx ++; } break; case I2C_EVENT_SLAVE_ACK_FAILURE: //only AF (workaround) EV31count=1; break; case I2C_EV31: //AF and BTF received in same interrupt I2C_SendData(I2C0, 0xFF); break; case I2C_EVENT_SLAVE_STOP_DETECTED: // EV4 EV31count = 0; Tx_Idx++; break; default: break; } }
rt_inline void stm32_i2c_ev_handler(struct stm32_i2c_bus *stm32_i2c) { unsigned int I2C_Event; rt_uint8_t data = 0; struct rt_i2c_msg *pmsg; I2C_Event = I2C_GetLastEvent(stm32_i2c->I2C); if(!stm32_i2c->msg) { return; } // EV5 0x00030001 if ((I2C_Event & I2C_EVENT_MASTER_MODE_SELECT) == I2C_EVENT_MASTER_MODE_SELECT) { // EV5 0x00030001 pmsg = &stm32_i2c->msg[stm32_i2c->msg_ptr]; if(pmsg->flags & RT_I2C_ADDR_10BIT) { data = ((pmsg->addr >> 8) << 1) | 0xF0; }
void I2C::DmaRxIRQ() { if((uint32_t)( DMA1->ISR & mDmaRxTcFlag )!=0)//传输完成 { // if(!DMA_GetCurrDataCounter(I2C_DMA_RX_Channel))//检查是否接收完毕 //此处不用判断 ,判断会出错, 为查明情况 { DMA_Cmd(mDmaRxChannel, DISABLE);//关DMA I2C_GenerateSTOP(mI2C,ENABLE); //产生停止信号 //检查队列是否为空 if(mCmdQueue.Size()>0)//队列不为空 { mCmdQueue.Get(mCurrentCmd);//下一个命令出队 //都要先发送从机地址+写信号 mState = STATE_SEND_ADW;//标志设置为需要发送从机地址+写信号 mIndex_Send = 0;//发送、接收计数下标清零 I2C_GetLastEvent(mI2C);//!!这里再次获取一下状态的原因其实是起延时的作用,等待busy位复位 //因为只有在busy位为0时才可以设置start位才有用,否则可能导致开始信号无法发送的情况 I2C_AcknowledgeConfig(mI2C,ENABLE); //使能应答 I2C_GenerateSTART(mI2C,ENABLE); //产生启动信号 } else//队列为空, { mState=STATE_READY;//将状态设置为 准备好发送 模式 } } } /* else if((uint32_t)( DMA1->ISR & I2C_DMA_RX_HT_FLAG )!=0)//传输一半 { } else if((uint32_t)( DMA1->ISR & DMA1_FLAG_TE7 )!=0)//传输发生错误 { usart1<<"error RX DMA\n"; } */ DMA1->IFCR=DMA1->ISR;//清除中断标志 }
static void HAL_I2C_EV_InterruptHandler(HAL_I2C_Interface i2c) { /* Process Last I2C Event */ switch (I2C_GetLastEvent(i2cMap[i2c]->I2C_Peripheral)) { /********** Slave Transmitter Events ************/ /* Check on EV1 */ case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED: i2cMap[i2c]->transmitting = 1; i2cMap[i2c]->txBufferIndex = 0; i2cMap[i2c]->txBufferLength = 0; if(NULL != i2cMap[i2c]->callback_onRequest) { // alert user program i2cMap[i2c]->callback_onRequest(); } i2cMap[i2c]->txBufferIndex = 0; break; /* Check on EV3 */ case I2C_EVENT_SLAVE_BYTE_TRANSMITTING: case I2C_EVENT_SLAVE_BYTE_TRANSMITTED: if (i2cMap[i2c]->txBufferIndex < i2cMap[i2c]->txBufferLength) { I2C_SendData(i2cMap[i2c]->I2C_Peripheral, i2cMap[i2c]->txBuffer[i2cMap[i2c]->txBufferIndex++]); } break; /*********** Slave Receiver Events *************/ /* check on EV1*/ case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: i2cMap[i2c]->rxBufferIndex = 0; i2cMap[i2c]->rxBufferLength = 0; break; /* Check on EV2*/ case I2C_EVENT_SLAVE_BYTE_RECEIVED: case (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_SR1_BTF): i2cMap[i2c]->rxBuffer[i2cMap[i2c]->rxBufferIndex++] = I2C_ReceiveData(i2cMap[i2c]->I2C_Peripheral); break; /* Check on EV4 */ case I2C_EVENT_SLAVE_STOP_DETECTED: /* software sequence to clear STOPF */ I2C_GetFlagStatus(i2cMap[i2c]->I2C_Peripheral, I2C_FLAG_STOPF); I2C_Cmd(i2cMap[i2c]->I2C_Peripheral, ENABLE); i2cMap[i2c]->rxBufferLength = i2cMap[i2c]->rxBufferIndex; i2cMap[i2c]->rxBufferIndex = 0; if(NULL != i2cMap[i2c]->callback_onReceive) { // alert user program i2cMap[i2c]->callback_onReceive(i2cMap[i2c]->rxBufferLength); } break; default: break; } }
/** * @brief This function handles I2Cx event interrupt request. * @param None * @retval None */ void I2Cx_EV_IRQHandler(void) { #if defined (I2C_SLAVE) /* Get Last I2C Event */ Event = I2C_GetLastEvent(I2Cx); switch (Event) { /*****************************************************************************/ /* Slave Transmitter Events */ /* */ /* ***************************************************************************/ /* Check on EV1 */ case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED: I2C_SendData(I2Cx, TxBuffer[Tx_Idx++]); /* Enable I2C event interrupt */ I2C_ITConfig(I2Cx, I2C_IT_BUF, ENABLE); break; /* Check on EV3 */ case I2C_EVENT_SLAVE_BYTE_TRANSMITTING: case I2C_EVENT_SLAVE_BYTE_TRANSMITTED: if (Tx_Idx < NbrOfDataToSend) I2C_SendData(I2Cx, TxBuffer[Tx_Idx++]); else /* Disable I2C event interrupt */ I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_BUF, DISABLE); break; default: break; } #endif /* I2C_SLAVE*/ #if defined (I2C_MASTER) /*****************************************************************************/ /* Master Receiver */ /* */ /* ***************************************************************************/ #ifdef I2C_10BITS_ADDRESS /* Check on SB Flag and clear it */ if(I2C_GetITStatus(I2Cx, I2C_IT_SB)== SET) { if (Send_HeaderStatus == 0x00) { /* Send Header to Slave for write */ I2C_SendData(I2Cx, HEADER_ADDRESS_Write); Send_HeaderStatus = 0x01; GenerateStartStatus = 0x01; } else { /* Send Header to Slave for Read */ I2C_SendData(I2Cx, HEADER_ADDRESS_Read); Send_HeaderStatus = 0x00; if (NumberOfByteToReceive == 0x03) { /* Disable buffer Interrupts */ I2C_ITConfig(I2Cx, I2C_IT_BUF , DISABLE); } else { /* Enable buffer Interrupts */ I2C_ITConfig(I2Cx, I2C_IT_BUF , ENABLE); } } } /* Check on ADD10 Flag */ else if(I2C_GetITStatus(I2Cx, I2C_IT_ADD10)== SET) { /* Send slave Address */ I2C_Send7bitAddress(I2Cx, (uint8_t)SLAVE_ADDRESS, I2C_Direction_Transmitter); } #else /* I2C_7BITS_ADDRESS */ /* Check on EV5 */ if(I2C_GetITStatus(I2Cx, I2C_IT_SB)== SET) { /* Send slave Address for read */ I2C_Send7bitAddress(I2Cx, SLAVE_ADDRESS, I2C_Direction_Receiver); if (NumberOfByteToReceive == 0x03) { /* Disable buffer Interrupts */ I2C_ITConfig(I2Cx, I2C_IT_BUF , DISABLE); } else { /* Enable buffer Interrupts */ I2C_ITConfig(I2Cx, I2C_IT_BUF , ENABLE); } } #endif /* I2C_10BITS_ADDRESS */ else if(I2C_GetITStatus(I2Cx, I2C_IT_ADDR)== SET) { if (NumberOfByteToReceive == 1) { I2C_AcknowledgeConfig(I2Cx, DISABLE); } /* Clear ADDR Register */ (void)(I2Cx->SR1); (void)(I2Cx->SR2); if (GenerateStartStatus == 0x00) { if (NumberOfByteToReceive == 1) { I2C_GenerateSTOP(I2Cx, ENABLE); } if (NumberOfByteToReceive == 2) { I2C_AcknowledgeConfig(I2Cx, DISABLE); I2C_PECPositionConfig(I2Cx, I2C_PECPosition_Next); /* Disable buffer Interrupts */ I2C_ITConfig(I2Cx, I2C_IT_BUF , DISABLE); } } #ifdef I2C_10BITS_ADDRESS if (GenerateStartStatus == 0x01) { /* Repeated Start */ I2C_GenerateSTART(I2Cx, ENABLE); GenerateStartStatus = 0x00; } #endif /* I2C_10BITS_ADDRESS */ } else if((I2C_GetITStatus(I2Cx, I2C_IT_RXNE)== SET)&&(I2C_GetITStatus(I2Cx, I2C_IT_BTF)== RESET)) { /* Store I2C received data */ RxBuffer[Rx_Idx++] = I2C_ReceiveData (I2Cx); NumberOfByteToReceive--; if (NumberOfByteToReceive == 0x03) { /* Disable buffer Interrupts */ I2C_ITConfig(I2Cx, I2C_IT_BUF , DISABLE); } if (NumberOfByteToReceive == 0x00) { /* Disable Error and Buffer Interrupts */ I2C_ITConfig(I2Cx, (I2C_IT_EVT | I2C_IT_BUF), DISABLE); } } /* BUSY, MSL and RXNE flags */ else if(I2C_GetITStatus(I2Cx, I2C_IT_BTF)== SET) { /* if Three bytes remaining for reception */ if (NumberOfByteToReceive == 3) { I2C_AcknowledgeConfig(I2Cx, DISABLE); /* Store I2C received data */ RxBuffer[Rx_Idx++] = I2C_ReceiveData (I2Cx); NumberOfByteToReceive--; } else if (NumberOfByteToReceive == 2) { I2C_GenerateSTOP(I2Cx, ENABLE); /* Store I2C received data */ RxBuffer[Rx_Idx++] = I2C_ReceiveData (I2Cx); NumberOfByteToReceive--; /* Store I2C received data */ RxBuffer[Rx_Idx++] = I2C_ReceiveData (I2Cx); NumberOfByteToReceive--; /* Disable Error and Buffer Interrupts */ I2C_ITConfig(I2Cx, (I2C_IT_EVT | I2C_IT_BUF), DISABLE); } else { /* Store I2C received data */ RxBuffer[Rx_Idx++] = I2C_ReceiveData (I2Cx); NumberOfByteToReceive--; } } #endif /* I2C_MASTER*/ }
/** * @brief This function handles I2C2 Error interrupt request. * @param None * @retval None */ void I2Cx_EV_IRQHandler(void) { #if defined (I2C_MASTER) switch (I2C_GetLastEvent(I2Cx)) { /* EV5 */ case I2C_EVENT_MASTER_MODE_SELECT : #ifdef I2C_10BITS_ADDRESS /* Send Header to Slave for write */ I2C_SendData(I2Cx, HEADER_ADDRESS_Write); break; /* EV9 */ case I2C_EVENT_MASTER_MODE_ADDRESS10: #endif /* I2C_10BITS_ADDRESS */ /* Send slave Address for write */ I2C_Send7bitAddress(I2Cx, (uint8_t)SLAVE_ADDRESS, I2C_Direction_Transmitter); break; /* EV6 */ case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: /* Send the I2C transaction code */ I2C_SendData(I2Cx, CmdTransmitted); break; /* EV8 */ case I2C_EVENT_MASTER_BYTE_TRANSMITTING: case I2C_EVENT_MASTER_BYTE_TRANSMITTED: if (Tx_Idx == GetVar_NbrOfDataToTransfer()) { /* Send STOP condition */ I2C_GenerateSTOP(I2Cx, ENABLE); I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_BUF, DISABLE); } else { /* Transmit Data TxBuffer */ I2C_SendData(I2Cx, TxBuffer[Tx_Idx++]); } break; default: break; } #endif /* I2C_MASTER*/ #if defined (I2C_SLAVE) /* Get Last I2C Event */ Event = I2C_GetLastEvent(I2Cx); switch (Event) { /* Check on EV1*/ case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: Rx_Idx = 0x00; break; /* Check on EV2*/ case I2C_EVENT_SLAVE_BYTE_RECEIVED: case (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_SR1_BTF): if (CmdReceived == 0x00) { CmdReceived = I2C_ReceiveData(I2Cx); } else { RxBuffer[Rx_Idx++] = I2C_ReceiveData(I2Cx); } break; /* Check on EV4 */ case (I2C_EVENT_SLAVE_STOP_DETECTED): I2C_GetFlagStatus(I2Cx, I2C_FLAG_STOPF); I2C_Cmd(I2Cx, ENABLE); break; default: break; } #endif /* I2C_SLAVE*/ }