// Make this so we can handle if the nunchuk is disconnected void f3d_i2c1_read_nunchuk (uint8_t device, uint8_t* buffer, uint16_t numbytes) { tryagain: ; int count = 100; while (I2C_GetFlagStatus(I2C1, I2C_ISR_BUSY) != RESET){ } I2C_TransferHandling(I2C1, 0xA4, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Write); // This is where were screwing up while ((I2C_GetFlagStatus(I2C1, I2C_ISR_TXIS) == RESET) && count){ asm("nop"); count--; } if (count <= 0) { goto tryagain; } I2C_SendData(I2C1,0x00); while(I2C_GetFlagStatus(I2C1, I2C_ISR_STOPF) == RESET){ } I2C_ClearFlag(I2C1, I2C_ICR_STOPCF); delay(1); while (I2C_GetFlagStatus(I2C1, I2C_ISR_BUSY) != RESET) { } I2C_TransferHandling(I2C1, 0xA4, 6, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); while (numbytes--) { while(I2C_GetFlagStatus(I2C1, I2C_ISR_RXNE) == RESET); *buffer++ = I2C_ReceiveData(I2C1); } while (I2C_GetFlagStatus(I2C1, I2C_ISR_STOPF) == RESET); I2C_ClearFlag(I2C1, I2C_ICR_STOPCF); }
/*TODO: If your device need more time to initialize I2C bus or waiting memory write, you can use I2C_AcknowledgePolling avoid I2C bus lose.*/ Status I2C_AcknowledgePolling(I2C_TypeDef* I2Cx ,uint8_t Addr) { uint32_t timeout = 0xFFFF, ret; uint16_t tmp; ret = rt_mutex_take(i2c_mux, RT_WAITING_FOREVER ); if( ret == RT_EOK ) { do{ if( timeout-- <= 0 ) { I2C_ClearFlag(I2Cx,I2C_FLAG_AF); I2Cx->CR1 |= CR1_STOP_Set; rt_mutex_release(i2c_mux); return Error; } I2Cx->CR1 |= CR1_START_Set; tmp = I2Cx->SR1;//²M°£SB¦ì I2Cx->DR = Addr; }while((I2Cx->SR1&0x0002) != 0x0002); I2C_ClearFlag(I2Cx,I2C_FLAG_AF); I2Cx->CR1 |= CR1_STOP_Set; while ((I2Cx->CR1&0x200) == 0x200); rt_kprintf( "AcknowledgePolling OK\n"); rt_mutex_release(i2c_mux); return Success; } else return Error; }
/** * @brief This function handles I2C2 Error interrupt request. * @param None * @retval : None */ void I2C2_ER_IRQHandler(void) { if (I2C_GetFlagStatus(I2C2, I2C_FLAG_AF)) { I2C_ClearFlag(I2C2, I2C_FLAG_AF); } if (I2C_GetFlagStatus(I2C2, I2C_FLAG_BERR)) { I2C_ClearFlag(I2C2, I2C_FLAG_BERR); } if (I2C_GetFlagStatus(I2C2, I2C_FLAG_OVR)) { I2C_ClearFlag(I2C2, I2C_FLAG_OVR); } if (I2C_GetFlagStatus(I2C2, I2C_FLAG_ARLO)) { I2C_ClearFlag(I2C2,I2C_FLAG_ARLO); } }
void I2C_CheckReceive() { if (I2C_GetFlagStatus(I2C, I2C_FLAG_ADDR)) { uprintf("\r\nAddress matched!\r\n"); I2C_ClearFlag(I2C, I2C_FLAG_ADDR); } /* Receive byte */ if (I2C_GetFlagStatus(I2C, I2C_FLAG_RXNE)) { uprintf("Packet received!\r\n"); I2C_RX_Packets[I2C_RX_Index] = I2C_ReceiveData(I2C); if (I2C_RX_Index < I2C_RX_PACKET_BUFFER_LENGTH-1) { I2C_RX_Index++; } I2C_ClearFlag(I2C, I2C_FLAG_RXNE); } /* Process command */ if (I2C_GetFlagStatus(I2C, I2C_FLAG_STOPF)) { uprintf("Stop! received!\r\n"); I2C_ClearFlag(I2C, I2C_FLAG_STOPF); I2C_ProcessCommand(I2C_RX_Packets, I2C_RX_Index+1); I2C_RX_Index = 0; } }
/** * @brief Checks the LM75 status. * @param None * @retval ErrorStatus: LM75 Status (ERROR or SUCCESS). */ ErrorStatus LM75_GetStatus(void) { uint32_t I2C_TimeOut = I2C_TIMEOUT; /* Configure slave address, nbytes, reload, end mode and start or stop generation */ I2C_TransferHandling(LM75_I2C, LM75_ADDR, 0, I2C_AutoEnd_Mode, I2C_No_StartStop); /* Clear NACKF and STOPF */ I2C_ClearFlag(LM75_I2C, I2C_ICR_NACKCF | I2C_ICR_STOPCF); /* Generate start */ I2C_GenerateSTART(LM75_I2C, ENABLE); /* Wait until timeout elapsed */ while ((I2C_GetFlagStatus(LM75_I2C, I2C_ISR_STOPF) == RESET) && (I2C_TimeOut-- != 0)); /* Check if Temp sensor is ready for use */ if ((I2C_GetFlagStatus(LM75_I2C, I2C_ISR_NACKF) != RESET) || (I2C_TimeOut == 0)) { /* Clear NACKF and STOPF */ I2C_ClearFlag(LM75_I2C, I2C_ICR_NACKCF | I2C_ICR_STOPCF); return ERROR; } else { /* Clear STOPF */ I2C_ClearFlag(LM75_I2C, I2C_ICR_STOPCF); return SUCCESS; } }
/** * @brief Wait for EEPROM Standby state * @param None * @retval None */ void sEE_WaitEepromStandbyState(void) { __IO uint8_t tempreg = 0; __IO uint32_t timeout = 0xFFFF; do { /*!< Send START condition */ I2C_GenerateSTART(sEE_I2C, ENABLE); /* Test on EEPROM_I2C EV5 and clear it */ while (!I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_SB)) /* EV5 */ { } /*!< Send EEPROM address for write */ I2C_Send7bitAddress(sEE_I2C, (uint8_t)sEEAddress, I2C_Direction_Transmitter); /*!< Wait for address aknowledgement */ for (; timeout > 0; timeout--); /*!< Read sEE SR1 register to clear pending flags */ tempreg = I2C_ReadRegister(sEE_I2C, I2C_Register_SR1); } while (!(tempreg & 0x02)); /*!< Clear AF flag */ I2C_ClearFlag(sEE_I2C, I2C_FLAG_AF); /*!< STOP condition */ I2C_GenerateSTOP(sEE_I2C, ENABLE); }
/** * @brief Configures a device connected to I2C * @param Pointer to the config string, number of bytes to write * @retval I2C success/error code */ I2C_Returntype I2C_Conf(uint8_t* Confstr,uint8_t Bytes) { //Sets up an i2c device uint8_t n; uint16_t Time=0; I2C_GenerateSTART( I2C1, ENABLE ); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) { Time++; if(Time>I2C_TIMEOUT) return I2C_START_TIMEOUT; } Time=0; I2C_Send7bitAddress( I2C1, Confstr[0], I2C_Direction_Transmitter ); //Address write while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { Time++; if(Time>I2C_TIMEOUT) return I2C_SACK_TIMEOUT; if(SET==I2C_GetFlagStatus(I2C1, I2C_FLAG_AF)) { I2C_ClearFlag(I2C1, I2C_FLAG_AF); I2C_GenerateSTOP( I2C1, ENABLE ); //Enable the STOP here - so hardware is ready again return I2C_SACK_FAILURE; //Slave did not ack } } for(n=1;n<Bytes;n++) { Time=0; I2C_SendData( I2C1, Confstr[n] ); //Write rest of string (registers) while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) { Time++; if(Time>I2C_TIMEOUT) return I2C_TX_TIMEOUT; } } I2C_GenerateSTOP( I2C1, ENABLE ); //Finally send the stop bit return I2C_SUCCESS; //Completed ok }
uint8_t TW88Write(uint8_t regAddr, uint8_t data) { int8_t retries; retries=3; while(I2C_GetFlagStatus(I2C1, I2C_ISR_BUSY) != RESET) { if ((retries--)>0) Delay(1); else return 0;} //I2C_TransferHandling(I2C1, TW88_I2C_ADDR, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); /* Configure slave address, nbytes, reload, end mode and start or stop generation */ I2C_TransferHandling(I2C1, TW88_I2C_ADDR, 1, I2C_Reload_Mode, I2C_Generate_Start_Write); retries=3; while(I2C_GetFlagStatus(I2C1, I2C_ISR_TXIS) == RESET) {if ((retries--)>0) Delay(1); else return 0; } //send the register address I2C_SendData(I2C1, (uint8_t) regAddr); retries=3; while(I2C_GetFlagStatus(I2C1, I2C_ISR_TCR) == RESET){if ((retries--)>0) Delay(1); else return 0;} /* Configure slave address, nbytes, reload, end mode and start or stop generation */ I2C_TransferHandling(I2C1, TW88_I2C_ADDR, 1, I2C_AutoEnd_Mode, I2C_No_StartStop); retries=3; while(I2C_GetFlagStatus(I2C1, I2C_ISR_TXIS) == RESET) {if ((retries--)>0) Delay(1); else return 0;} I2C_SendData(I2C1, data); retries=3; while(I2C_GetFlagStatus(I2C1, I2C_ISR_STOPF) == RESET) {if ((retries--)>0) Delay(1); else return 0;} I2C_ClearFlag(I2C1, I2C_ICR_STOPCF); return 1; }
/******************************************************************************* * Function Name : i2c_transmit * Description : Transmit byte(s) * Input : - Addr: Slave address * : - Ptr: Pointer to the first byte to be transmitted * : - Size: Number of bytes to transmit * : - Stop: Indicate if a STOP condition is to be generated * Output : None * Return : -1 if an error occurred *******************************************************************************/ int i2c_transmit(u8 Addr, const char *Ptr, u16 Size, u8 Stop) { int ret = 0; I2C_GenerateSTART(I2C1, ENABLE); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1,Addr, I2C_Direction_Transmitter); while (!I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR) && !I2C_GetFlagStatus(I2C1, I2C_FLAG_AF)); if (I2C_GetFlagStatus(I2C1, I2C_FLAG_AF)) { I2C_ClearFlag(I2C1, I2C_FLAG_AF); ret = -1; } else if (Size) { while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); while (Size--) { while (!I2C_GetFlagStatus(I2C1, I2C_FLAG_TXE)); I2C_SendData(I2C1, *Ptr++); } while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); } if (Stop || (ret == -1)) { I2C_GenerateSTOP(I2C1, ENABLE); while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); } return(ret); }
void u8g_i2c_stop(void) { //Wait for the stop flag to be set indicating a stop condition has been sent while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET); //Clear the stop flag for the next potential transfer I2C_ClearFlag(I2C1, I2C_FLAG_STOPF); }
/** * @brief Write to the configuration register of the LM75. * @param RegValue: specifies the value to be written to LM75 configuration * register. * @retval None */ uint8_t LM75_WriteConfReg(uint8_t RegValue) { uint8_t LM75_BufferTX = 0; LM75_BufferTX = (uint8_t)(RegValue); /* Test on BUSY Flag */ LM75Timeout = LM75_LONG_TIMEOUT; while(I2C_GetFlagStatus(LM75_I2C, I2C_ISR_BUSY) != RESET) { if((LM75Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Configure slave address, nbytes, reload, end mode and start or stop generation */ I2C_TransferHandling(LM75_I2C, LM75_ADDR, 1, I2C_Reload_Mode, I2C_Generate_Start_Write); /* Wait until TXIS flag is set */ LM75Timeout = LM75_LONG_TIMEOUT; while(I2C_GetFlagStatus(LM75_I2C, I2C_ISR_TXIS) == RESET) { if((LM75Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Send Register address */ I2C_SendData(LM75_I2C, (uint8_t)LM75_REG_CONF); /* Wait until TCR flag is set */ LM75Timeout = LM75_LONG_TIMEOUT; while(I2C_GetFlagStatus(LM75_I2C, I2C_ISR_TCR) == RESET) { if((LM75Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Configure slave address, nbytes, reload, end mode and start or stop generation */ I2C_TransferHandling(LM75_I2C, LM75_ADDR, 1, I2C_AutoEnd_Mode, I2C_No_StartStop); /* Wait until TXIS flag is set */ LM75Timeout = LM75_LONG_TIMEOUT; while(I2C_GetFlagStatus(LM75_I2C, I2C_ISR_TXIS) == RESET) { if((LM75Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Write data to TXDR */ I2C_SendData(LM75_I2C, (uint8_t)LM75_BufferTX); /* Wait until STOPF flag is set */ LM75Timeout = LM75_LONG_TIMEOUT; while(I2C_GetFlagStatus(LM75_I2C, I2C_ISR_STOPF) == RESET) { if((LM75Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Clear STOPF flag */ I2C_ClearFlag(LM75_I2C, I2C_ICR_STOPCF); return LM75_OK; }
/** * @brief Read the configuration register from the LM75. * @param None * @retval LM75 configuration register value. */ uint8_t LM75_ReadConfReg(void) { uint8_t LM75_BufferRX[2] ={0,0}; /* Test on BUSY Flag */ LM75Timeout = LM75_LONG_TIMEOUT; while(I2C_GetFlagStatus(LM75_I2C, I2C_ISR_BUSY) != RESET) { if((LM75Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Configure slave address, nbytes, reload, end mode and start or stop generation */ I2C_TransferHandling(LM75_I2C, LM75_ADDR, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); /* Wait until TXIS flag is set */ LM75Timeout = LM75_LONG_TIMEOUT; while(I2C_GetFlagStatus(LM75_I2C, I2C_ISR_TXIS) == RESET) { if((LM75Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Send Register address */ I2C_SendData(LM75_I2C, (uint8_t)LM75_REG_CONF); /* Wait until TC flag is set */ LM75Timeout = LM75_LONG_TIMEOUT; while(I2C_GetFlagStatus(LM75_I2C, I2C_ISR_TC) == RESET) { if((LM75Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Configure slave address, nbytes, reload, end mode and start or stop generation */ I2C_TransferHandling(LM75_I2C, LM75_ADDR, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); /* Wait until RXNE flag is set */ LM75Timeout = LM75_LONG_TIMEOUT; while(I2C_GetFlagStatus(LM75_I2C, I2C_ISR_RXNE) == RESET) { if((LM75Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Read data from RXDR */ LM75_BufferRX[0]= I2C_ReceiveData(LM75_I2C); /* Wait until STOPF flag is set */ LM75Timeout = LM75_LONG_TIMEOUT; while(I2C_GetFlagStatus(LM75_I2C, I2C_ISR_STOPF) == RESET) { if((LM75Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Clear STOPF flag */ I2C_ClearFlag(LM75_I2C, I2C_ICR_STOPCF); /* Return Register value */ return (uint8_t)LM75_BufferRX[0]; }
void f3d_i2c1_read_nunchuk (uint8_t device, uint8_t* buffer, uint16_t numbytes) { while (I2C_GetFlagStatus(I2C1, I2C_ISR_BUSY) != RESET); I2C_TransferHandling(I2C1, 0xA4, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Write); while (I2C_GetFlagStatus(I2C1, I2C_ISR_TXIS) == RESET); I2C_SendData(I2C1,0x00); while(I2C_GetFlagStatus(I2C1, I2C_ISR_STOPF) == RESET); I2C_ClearFlag(I2C1, I2C_ICR_STOPCF); delay(1); while (I2C_GetFlagStatus(I2C1, I2C_ISR_BUSY) != RESET); I2C_TransferHandling(I2C1, 0xA4, 6, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); while (numbytes--) { while(I2C_GetFlagStatus(I2C1, I2C_ISR_RXNE) == RESET); *buffer++ = I2C_ReceiveData(I2C1); } while (I2C_GetFlagStatus(I2C1, I2C_ISR_STOPF) == RESET); I2C_ClearFlag(I2C1, I2C_ICR_STOPCF); }
void i2c_hand(void) { if(I2C_GetITStatus(I2C2, I2C_IT_ADDR) == SET) { handl_i2c_message(); I2C_ClearFlag(I2C2, I2C_FLAG_ADDR); stat.is_tran = I2C_GetTransferDirection(I2C2); stat.numr = 0; } if(I2C_GetITStatus(I2C2, I2C_IT_STOPF) == SET) { handl_i2c_message(); cTran++; I2C_ClearFlag(I2C2, I2C_FLAG_STOPF); stat.numr = 0; } if(I2C_GetITStatus(I2C2, I2C_IT_RXNE) == SET) { if(stat.numr < I2C_BUF_SIZE) stat.bufr[stat.numr++] = I2C_ReceiveData(I2C2); } return; }
void ADXL345_Read(uint8_t DeviceAddr, uint8_t RegAddr, uint8_t* pBuffer, uint16_t NumByteToRead) { /* Test on BUSY Flag */ while(I2C_GetFlagStatus(ADXL345_I2C, I2C_ISR_BUSY) != RESET) { } /* Configure slave address, nbytes, reload, end mode and start or stop generation */ I2C_TransferHandling(ADXL345_I2C, DeviceAddr, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); /* Wait until TXIS flag is set */ while(I2C_GetFlagStatus(ADXL345_I2C, I2C_ISR_TXIS) == RESET) { } if(NumByteToRead>1) RegAddr |= 0x80; /* Send Register address */ I2C_SendData(ADXL345_I2C, (uint8_t)RegAddr); /* Wait until TC flag is set */ while(I2C_GetFlagStatus(ADXL345_I2C, I2C_ISR_TC) == RESET) { } /* Configure slave address, nbytes, reload, end mode and start or stop generation */ I2C_TransferHandling(ADXL345_I2C, DeviceAddr, NumByteToRead, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); /* Wait until all data are received */ while (NumByteToRead) { /* Wait until RXNE flag is set */ while(I2C_GetFlagStatus(ADXL345_I2C, I2C_ISR_RXNE) == RESET) { } /* Read data from RXDR */ *pBuffer = I2C_ReceiveData(ADXL345_I2C); /* Point to the next location where the byte read will be saved */ pBuffer++; /* Decrement the read bytes counter */ NumByteToRead--; } /* Wait until STOPF flag is set */ while(I2C_GetFlagStatus(ADXL345_I2C, I2C_ISR_STOPF) == RESET) { } /* Clear STOPF flag */ I2C_ClearFlag(ADXL345_I2C, I2C_ICR_STOPCF); }
/* @brief Reads bytes from MPU6050 * * @param SlaveAddr - Slave I2C address * @param RegAddr - register address * @param pBuffer - buffer to write to * @ param NumByteToRead - number of bytes to read * * @retval @MPU6050_errorstatus */ MPU6050_errorstatus MPU6050_Read(uint8_t SlaveAddr, uint8_t RegAddr, uint8_t* pBuffer, uint16_t NumByteToRead) { /* Test if SDA line busy */ MPU6050_Timeout = MPU6050_LONG_TIMEOUT; while(I2C_GetFlagStatus(MPU6050_I2C, I2C_FLAG_BUSY) != RESET) { if((MPU6050_Timeout--) == 0) return MPU6050_I2C_ERROR; } I2C_TransferHandling(MPU6050_I2C, SlaveAddr, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); MPU6050_Timeout = MPU6050_LONG_TIMEOUT; while(I2C_GetFlagStatus(MPU6050_I2C, I2C_FLAG_TXIS) == RESET) { if((MPU6050_Timeout--) == 0) return MPU6050_I2C_ERROR; } if(NumByteToRead>1) RegAddr |= 0x80; I2C_SendData(MPU6050_I2C, (uint8_t)RegAddr); MPU6050_Timeout = MPU6050_LONG_TIMEOUT; while(I2C_GetFlagStatus(MPU6050_I2C, I2C_FLAG_TC) == RESET) { if((MPU6050_Timeout--) == 0) return MPU6050_I2C_TX_ERROR; } I2C_TransferHandling(MPU6050_I2C, SlaveAddr, NumByteToRead, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); while (NumByteToRead) { MPU6050_Timeout = MPU6050_LONG_TIMEOUT; while(I2C_GetFlagStatus(MPU6050_I2C, I2C_FLAG_RXNE) == RESET) { if((MPU6050_Timeout--) == 0) return MPU6050_I2C_RX_ERROR; } *pBuffer = I2C_ReceiveData(MPU6050_I2C); pBuffer++; NumByteToRead--; } MPU6050_Timeout = MPU6050_LONG_TIMEOUT; while(I2C_GetFlagStatus(MPU6050_I2C, I2C_FLAG_STOPF) == RESET) { if((MPU6050_Timeout--) == 0) return MPU6050_I2C_ERROR; } I2C_ClearFlag(MPU6050_I2C, I2C_FLAG_STOPF); return MPU6050_NO_ERROR; }
/** * @brief Writes one byte to the LSM303DLHC. * @param DeviceAddr : specifies the slave address to be programmed. * @param RegAddr : specifies the LSM303DLHC register to be written. * @param pBuffer : pointer to the buffer containing the data to be written to the LSM303DLH. * @retval LSM303DLHC Status */ uint16_t LSM303DLHC_Write(uint8_t DeviceAddr, uint8_t RegAddr, uint8_t* pBuffer) { /* Test on BUSY Flag */ LSM303DLHC_Timeout = LSM303DLHC_LONG_TIMEOUT; while (I2C_GetFlagStatus(LSM303DLHC_I2C, I2C_ISR_BUSY ) != RESET) { if ((LSM303DLHC_Timeout--) == 0) return LSM303DLHC_TIMEOUT_UserCallback(); } /* Configure slave address, nbytes, reload, end mode and start or stop generation */ I2C_TransferHandling(LSM303DLHC_I2C, DeviceAddr, 1, I2C_Reload_Mode, I2C_Generate_Start_Write); /* Wait until TXIS flag is set */ LSM303DLHC_Timeout = LSM303DLHC_LONG_TIMEOUT; while (I2C_GetFlagStatus(LSM303DLHC_I2C, I2C_ISR_TXIS ) == RESET) { if ((LSM303DLHC_Timeout--) == 0) return LSM303DLHC_TIMEOUT_UserCallback(); } /* Send Register address */ I2C_SendData(LSM303DLHC_I2C, (uint8_t) RegAddr); /* Wait until TCR flag is set */ LSM303DLHC_Timeout = LSM303DLHC_LONG_TIMEOUT; while (I2C_GetFlagStatus(LSM303DLHC_I2C, I2C_ISR_TCR ) == RESET) { if ((LSM303DLHC_Timeout--) == 0) return LSM303DLHC_TIMEOUT_UserCallback(); } /* Configure slave address, nbytes, reload, end mode and start or stop generation */ I2C_TransferHandling(LSM303DLHC_I2C, DeviceAddr, 1, I2C_AutoEnd_Mode, I2C_No_StartStop); /* Wait until TXIS flag is set */ LSM303DLHC_Timeout = LSM303DLHC_LONG_TIMEOUT; while (I2C_GetFlagStatus(LSM303DLHC_I2C, I2C_ISR_TXIS ) == RESET) { if ((LSM303DLHC_Timeout--) == 0) return LSM303DLHC_TIMEOUT_UserCallback(); } /* Write data to TXDR */ I2C_SendData(LSM303DLHC_I2C, *pBuffer); /* Wait until STOPF flag is set */ LSM303DLHC_Timeout = LSM303DLHC_LONG_TIMEOUT; while (I2C_GetFlagStatus(LSM303DLHC_I2C, I2C_ISR_STOPF ) == RESET) { if ((LSM303DLHC_Timeout--) == 0) return LSM303DLHC_TIMEOUT_UserCallback(); } /* Clear STOPF flag */ I2C_ClearFlag(LSM303DLHC_I2C, I2C_ICR_STOPCF ); return LSM303DLHC_OK ; }
/************************************************************************* * 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); }
void i2c_write(uint8_t* pBuffer, uint8_t num) { uint8_t i = 0; I2C_ITConfig(I2C2, I2C_IT_RXI | I2C_IT_TXI | I2C_IT_ADDRI | I2C_IT_STOPI, DISABLE); while(I2C_GetFlagStatus(I2C2, I2C_ISR_BUSY) != RESET); I2C_TransferHandling(I2C2, I2C_SLAVE, num, I2C_AutoEnd_Mode, I2C_Generate_Start_Write); for(; i < num; i++) { while(I2C_GetFlagStatus(I2C2, I2C_ISR_TXIS) == RESET); I2C_SendData(I2C2, (uint8_t) I2C_SLAVE); } while(I2C_GetFlagStatus(I2C2, I2C_ISR_STOPF) == RESET); I2C_ClearFlag(I2C2, I2C_ICR_STOPCF); }
uint16_t I2C_Write(uint8_t deviceAddressess, uint8_t registerAddress, uint8_t* dataPointer) { I2C_Timeout = I2C_LONG_TIMEOUT; while(I2C_GetFlagStatus(I2C, I2C_ISR_BUSY) != RESET) { if((I2C_Timeout--) == 0) return I2C_TIMEOUT_UserCallback(); } /* Configure slave address, nbytes, reload, end mode and start or stop generation */ I2C_TransferHandling(I2C, deviceAddressess, 1, I2C_Reload_Mode, I2C_Generate_Start_Write); /* Wait until TXIS flag is set */ I2C_Timeout = I2C_LONG_TIMEOUT; while(I2C_GetFlagStatus(I2C, I2C_ISR_TXIS) == RESET) { if((I2C_Timeout--) == 0) return I2C_TIMEOUT_UserCallback(); } /* Send Register address */ I2C_SendData(I2C, (uint8_t) registerAddress); /* Wait until TCR flag is set */ I2C_Timeout = I2C_LONG_TIMEOUT; while(I2C_GetFlagStatus(I2C, I2C_ISR_TCR) == RESET) { if((I2C_Timeout--) == 0) return I2C_TIMEOUT_UserCallback(); } /* Configure slave address, nbytes, reload, end mode and start or stop generation */ I2C_TransferHandling(I2C, deviceAddressess, 1, I2C_AutoEnd_Mode, I2C_No_StartStop); /* Wait until TXIS flag is set */ I2C_Timeout = I2C_LONG_TIMEOUT; while(I2C_GetFlagStatus(I2C, I2C_ISR_TXIS) == RESET) { if((I2C_Timeout--) == 0) return I2C_TIMEOUT_UserCallback(); } /* Write data to TXDR */ I2C_SendData(I2C, *dataPointer); /* Wait until STOPF flag is set */ I2C_Timeout = I2C_LONG_TIMEOUT; while(I2C_GetFlagStatus(I2C, I2C_ISR_STOPF) == RESET) { if((I2C_Timeout--) == 0) return I2C_TIMEOUT_UserCallback(); } /* Clear STOPF flag */ I2C_ClearFlag(I2C, I2C_ICR_STOPCF); return I2C_OK; }
/* Slave Write */ int I2C_Slave_Write(I2C_TypeDef* I2Cx, const char *data, int length){ uint32_t Timeout; int size = 0; while (length > 0) { /* Wait until TXE flag is set */ Timeout = FLAG_TIMEOUT; while (I2C_GetFlagStatus(I2Cx, I2C_FLAG_TXE) == RESET) { Timeout--; if (Timeout == 0) { return -1; } } /* Write data to DR */ I2Cx->DR = (*data++); length--; size++; if ((I2C_GetFlagStatus(I2Cx, I2C_FLAG_BTF) == SET) && (length != 0)) { /* Write data to DR */ I2Cx->DR = (*data++); length--; size++; } } /* Wait until AF flag is set */ Timeout = FLAG_TIMEOUT; while (I2C_GetFlagStatus(I2Cx, I2C_FLAG_AF) == RESET) { Timeout--; if (Timeout == 0) { return -1; } } /* Clear AF flag */ I2C_ClearFlag(I2Cx, I2C_FLAG_AF); /* Wait until BUSY flag is reset */ Timeout = FLAG_TIMEOUT; while (I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY) == SET) { Timeout--; if (Timeout == 0) { return -1; } } return size; }
int I2C_Write(int address, char *data, int length, int stop) //////////I2C write with event check { int timeout; int count; char byte_n; /* update CR2 register */ I2C1->CR2 = (I2C1->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP))) | (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16) & I2C_CR2_NBYTES) | (uint32_t)I2C_SoftEnd_Mode | (uint32_t)I2C_Generate_Start_Write); for (count = 0; count < length; count++) { byte_n = data[count]; I2C_ByteWrite(byte_n); } // Wait transfer complete timeout = FLAG_TIMEOUT; while (I2C_GetFlagStatus(I2C1, I2C_FLAG_TC) == RESET) { timeout--; if (timeout == 0) { return -1; } } I2C_ClearFlag(I2C1, I2C_FLAG_TC); // If not repeated start, send stop. if (stop) { I2C1->CR2 |= I2C_CR2_STOP; /* Wait until STOPF flag is set */ timeout = FLAG_TIMEOUT; while (I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET) { timeout--; if (timeout == 0) { return -1; } } /* Clear STOP Flag */ I2C_ClearFlag(I2C1, I2C_FLAG_STOPF); } return count; }
/** * @brief Wait for EEPROM Standby state. * * @note This function allows to wait and check that EEPROM has finished the * last operation. It is mostly used after Write operation: after receiving * the buffer to be written, the EEPROM may need additional time to actually * perform the write operation. During this time, it doesn't answer to * I2C packets addressed to it. Once the write operation is complete * the EEPROM responds to its address. * * @param None * * @retval sEE_OK (0) if operation is correctly performed, else return value * different from sEE_OK (0) or the timeout user callback. */ uint32_t sEE_WaitEepromStandbyState(void) { __IO uint32_t sEETrials = 0; /* Keep looping till the slave acknowledge his address or maximum number of trials is reached (this number is defined by sEE_MAX_TRIALS_NUMBER define in stm32373c_eval_i2c_ee.h file) */ /* Configure CR2 register : set Slave Address and end mode */ I2C_TransferHandling(sEE_I2C, sEEAddress, 0, I2C_AutoEnd_Mode, I2C_No_StartStop); do { /* Initialize sEETimeout */ sEETimeout = sEE_FLAG_TIMEOUT; /* Clear NACKF */ I2C_ClearFlag(sEE_I2C, I2C_ICR_NACKCF | I2C_ICR_STOPCF); /* Generate start */ I2C_GenerateSTART(sEE_I2C, ENABLE); /* Wait until timeout elapsed */ while (sEETimeout-- != 0); /* Check if the maximum allowed numbe of trials has bee reached */ if (sEETrials++ == sEE_MAX_TRIALS_NUMBER) { /* If the maximum number of trials has been reached, exit the function */ return sEE_TIMEOUT_UserCallback(); } } while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_NACKF) != RESET); /* Clear STOPF */ I2C_ClearFlag(sEE_I2C, I2C_ICR_STOPCF); /* Return sEE_OK if device is ready */ return sEE_OK; }
int I2C_DataRead(int address, char *data, int length, int stop) { int timeout; int count; int value; /* update CR2 register */ I2C1->CR2 = (I2C1->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP))) | (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16) & I2C_CR2_NBYTES) | (uint32_t)I2C_SoftEnd_Mode | (uint32_t)I2C_Generate_Start_Read); // Read all bytes for (count = 0; count < length; count++) { value = I2C_ByteRead(0); data[count] = (char)value; } // Wait transfer complete timeout = LONG_TIMEOUT; while (I2C_GetFlagStatus(I2C1, I2C_FLAG_TC) == RESET) { timeout--; if (timeout == 0) { return -1; } } I2C_ClearFlag(I2C1, I2C_FLAG_TC); // If not repeated start, send stop. if (stop) { I2C1->CR2 |= I2C_CR2_STOP; /* Wait until STOPF flag is set */ timeout = FLAG_TIMEOUT; while (I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET) { timeout--; if (timeout == 0) { return -1; } } /* Clear STOP Flag */ I2C_ClearFlag(I2C1, I2C_FLAG_STOPF); } return length; }
void I2C_WriteRegister(uint8_t addr, uint8_t reg, uint8_t val) { while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY) == SET); I2C_TransferHandling(I2C2, addr, 1, I2C_Reload_Mode, I2C_Generate_Start_Write); while(I2C_GetFlagStatus(I2C2, I2C_FLAG_TXIS) == RESET); I2C_SendData(I2C2, reg); while(I2C_GetFlagStatus(I2C2, I2C_FLAG_TCR) == RESET); I2C_TransferHandling(I2C2, addr, 1, I2C_AutoEnd_Mode, I2C_No_StartStop); while(I2C_GetFlagStatus(I2C2, I2C_FLAG_TXIS) == RESET); I2C_SendData(I2C2, val); while(I2C_GetFlagStatus(I2C2, I2C_FLAG_STOPF) == RESET); I2C_ClearFlag(I2C2, I2C_FLAG_STOPF); }
/******************************************************************************* * Function Name : I2C_EE_WaitEepromStandbyState * Description : Wait for EEPROM Standby state * Input : None * Output : None * Return : None *******************************************************************************/ void I2C_EE_WaitEepromStandbyState(void) { // vu16 SR1_Tmp = 0; // do // { // /* Send START condition */ // I2C_GenerateSTART(I2C1, ENABLE); // /* Read I2C1 SR1 register */ // SR1_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR1); // /* Send EEPROM address for write */ // I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter); // } // while(!(I2C_ReadRegister(I2C1, I2C_Register_SR1) & 0x0002)); // // /* Clear AF flag */ // I2C_ClearFlag(I2C1, I2C_FLAG_AF); // /* STOP condition */ // I2C_GenerateSTOP(I2C1, ENABLE); // Added by Najoua 27/08/2008 while(1) { while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); /* Send START condition */ I2C_GenerateSTART(I2C1, ENABLE); /* Test on EV5 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); /* Send EEPROM address for write */ I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ while( (!I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR)) && (!I2C_GetFlagStatus(I2C1, I2C_FLAG_AF)) ); if(I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR)) { break; } if(I2C_GetFlagStatus(I2C1, I2C_FLAG_AF)) { I2C_ClearFlag(I2C1,I2C_FLAG_AF); I2C_GenerateSTOP(I2C1, ENABLE); while(I2C1->CR1&0x0200); } } while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_GenerateSTOP(I2C1, ENABLE); while(I2C1->CR1&0x0200); }
/* Private functions ---------------------------------------------------------*/ int EEP_WriteData(uint8_t DevAddr, uint16_t RegAddr, uint8_t* DataBuf, uint16_t DataLen) { EEP_Timeout = EEP_LONG_TIMEOUT; while(I2C_GetFlagStatus(I2C2,I2C_FLAG_BUSY)) { if(EEP_Timeout-- == 0) return ERROR; } I2C_TransferHandling(I2C2,DevAddr,2,I2C_Reload_Mode,I2C_Generate_Start_Write); while(I2C_GetFlagStatus(I2C2,I2C_FLAG_TXIS) == RESET) { if(EEP_Timeout-- == 0) return ERROR; } I2C_SendData(I2C2,RegAddr>>8); while(I2C_GetFlagStatus(I2C2,I2C_FLAG_TXIS) == RESET) { if(EEP_Timeout-- == 0) return ERROR; } I2C_SendData(I2C2,RegAddr&0xFF); while(I2C_GetFlagStatus(I2C2,I2C_ISR_TCR) == RESET) { if(EEP_Timeout-- == 0) return ERROR; } I2C_TransferHandling(I2C2,DevAddr,DataLen,I2C_AutoEnd_Mode,I2C_No_StartStop); while(DataLen--) { while(I2C_GetFlagStatus(I2C2,I2C_FLAG_TXIS) == RESET) { if(EEP_Timeout-- == 0) return ERROR; } I2C_SendData(I2C2, *DataBuf); DataBuf++; } while(I2C_GetFlagStatus(I2C2,I2C_FLAG_STOPF) == RESET) { if(EEP_Timeout-- == 0) return ERROR; } I2C_ClearFlag(I2C2, I2C_ICR_STOPCF); return SUCCESS; }
//We're really fortunate with the HMC5883L as it automatically //increments the internal register counter with every read //so we need to set the internal register pointer to the first data //register (the X value register) and just read the next 6 pieces //of data, X1, X2, Z1, Z2 Y1, Y2 and //voila! We have the compass values! uint8_t I2C_RdReg(int8_t Reg, int8_t *Data, uint8_t DCnt){ int8_t Cnt, SingleData = 0; //As per, ensure the I2C peripheral isn't busy! while(I2C_GetFlagStatus(HMC_I2C, I2C_FLAG_BUSY) == SET); //Again, start another tranfer using the "transfer handling" //function, the end bit being set in software this time //round, generate a start condition and indicate you will //be writing data to the HMC device. I2C_TransferHandling(HMC_I2C, HMCAddr, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); //Wait until the transmit interrupt status is set while(I2C_GetFlagStatus(HMC_I2C, I2C_FLAG_TXIS) == RESET); //Send the address of the register you wish to read I2C_SendData(HMC_I2C, (uint8_t)Reg); //Wait until transfer is complete! while(I2C_GetFlagStatus(HMC_I2C, I2C_FLAG_TC) == RESET); //As per, start another transfer, we want to read DCnt //amount of bytes. Generate a start condition and //indicate that we want to read. I2C_TransferHandling(HMC_I2C, HMCAddr, DCnt, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); //Read in DCnt pieces of data for(Cnt = 0; Cnt<DCnt; Cnt++){ //Wait until the RX register is full of luscious data! while(I2C_GetFlagStatus(HMC_I2C, I2C_FLAG_RXNE) == RESET); //If we're only reading one byte, place that data direct into the //SingleData variable. If we're reading more than 1 piece of data //store in the array "Data" (a pointer from main) if(DCnt > 1) Data[Cnt] = I2C_ReceiveData(HMC_I2C); else SingleData = I2C_ReceiveData(HMC_I2C); } //Wait for the stop condition to be sent while(I2C_GetFlagStatus(HMC_I2C, I2C_FLAG_STOPF) == RESET); //Clear the stop flag for next transfers I2C_ClearFlag(HMC_I2C, I2C_FLAG_STOPF); //Return a single piece of data if DCnt was //less than 1, otherwise 0 will be returned. return SingleData; }
/* Slave Receive Master Request */ int I2C_Slave_ReceiveMasterRequest(I2C_TypeDef* I2Cx){ int retValue = I2C_NoData; if (I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY) != RESET) { if (I2C_GetFlagStatus(I2Cx, I2C_FLAG_ADDR) != RESET) { if (I2C_GetFlagStatus(I2Cx, I2C_FLAG_TRA) != RESET) retValue = I2C_ReadAddressed; else retValue = I2C_WriteAddressed; I2C_ClearFlag(I2Cx, I2C_FLAG_ADDR); } } return (retValue); }