bool i2c_data_verify(alt_u32 scl_base, alt_u32 sda_base, alt_u8 ControlAddr){ bool bPass; const alt_8 DeviceAddr = 0xA0; alt_u8 OrgData, TestData, Data; TestData = alt_nticks(); if (TestData == 0) TestData = 0x12; bPass = I2C_Read(scl_base, sda_base, DeviceAddr, ControlAddr, &OrgData); if (bPass) // write bPass = I2C_Write(scl_base, sda_base, DeviceAddr, ControlAddr, TestData); if (bPass) // read bPass = I2C_Read(scl_base, sda_base, DeviceAddr, ControlAddr, &Data); if (bPass && (Data != TestData)) // verify bPass = FALSE; // restore if (bPass) // write back bPass = I2C_Write(scl_base, sda_base, DeviceAddr, ControlAddr, OrgData); if (bPass) // read bPass = I2C_Read(scl_base, sda_base, DeviceAddr, ControlAddr, &Data); if (bPass && (Data != OrgData)) // verify bPass = FALSE; return bPass; }
/** * @brief Main program * @param None * @retval None */ int main() { int i; /*System clock configuration*/ SystemInit(); /* Configure UART2 */ S_UART_Init(115200); conf.scl = I2C_PA_9; conf.sda = I2C_PA_10; I2C_Init(&conf); //============ Write ============== I2C_Write(&conf, 0xa0, &Transmit_Data[0], MAX_SIZE); delay_function(4000); //========= Read ============= //Write memory address I2C_Write(&conf, 0xA0, &Transmit_Data[0], 1); delay_function(4000); //Read data I2C_Read(&conf, 0xA0, &Recv_Data[0], MAX_SIZE - 1); printf("Recv data : "); for(i=0; i<MAX_SIZE - 1; i++) { printf("0x%x ", Recv_Data[i]); } printf("\r\n"); }
//------------------------------------------------------------------------------------------------------------------------------------------------------------------ // MPU-6050 initialisieren //------------------------------------------------------------------------------------------------------------------------------------------------------------------ void Init_MPU6050(void) { // Abtastrate des Sensors einstellen - Register 0x19 mit 7 beschreiben i2cData[0] = 0x19; i2cData[1] = 7; I2C_Write(I2C1, i2cData, 2, I2C_MPUAddress); // internen Tiefpassfilter deaktivieren - Register 0x1A mit 0 beschreiben i2cData[0] = 0x1A; i2cData[1] = 0x00; I2C_Write(I2C1, i2cData, 2, I2C_MPUAddress); // max. Messbereich des Drehratensensors auf +/-250°/s einstellen - Register 0x1B mit 0 beschreiben i2cData[0] = 0x1B; i2cData[1] = 0x00; I2C_Write(I2C1, i2cData, 2, I2C_MPUAddress); // max. Messbereich des Beschleunigungssensors auf +/-2g einstellen - Register 0x1C mit 0 beschreiben i2cData[0] = 0x1C; i2cData[1] = 0x00; I2C_Write(I2C1, i2cData, 2, I2C_MPUAddress); // Taktquelle auswählen - Register 0x6B mit 1 beschreiben PLL[0] = 0x6B; PLL[1] = 0x01; I2C_Write(I2C1, PLL, 2, I2C_MPUAddress); }
uint8_t temperature_DeviceShutdown (void) { // put the device in SHUTDOWN mode to save power r = I2C_Start(); // len = sprintf(str, "\n\r I2C_Start: 0x%x\n\r", r); // outputStringToUART0(str); if (r == TW_START) { r = I2C_Write(TCN75A_ADDR_WRITE); // address the device, say we are going to write // len = sprintf(str, "\n\r I2C_Write(TCN75A_ADDR_WRITE): 0x%x\n\r", r); // outputStringToUART0(str); if (r == TW_MT_SLA_ACK) { r = I2C_Write(TCN75A_CONFIG); // len = sprintf(str, "\n\r I2C_Write(TCN75A_CONFIG): 0x%x\n\r", r); // outputStringToUART0(str); if (r == TW_MT_DATA_ACK) { r = I2C_Write(TCN75A_SHUTDOWN_BIT); // len = sprintf(str, "\n\r I2C_Write(TCN75A_SHUTDOWN_BIT): 0x%x\n\r", r); // outputStringToUART0(str); I2C_Stop(); return I2C_OK; } else { // could not write data to device I2C_Stop(); return errNoI2CDataAck; } } else { // could not address device I2C_Stop(); return errNoI2CAddressAck; } I2C_Stop(); // outputStringToUART0("\n\r STOP completed \n\r"); } else { // could not START return errNoI2CStart; } }
// Generic function to read a value from a single ADXL345 register uint8_t readADXL345Register (uint8_t reg, uint8_t *valp) { uint8_t r; r = I2C_Start(); if (r == TW_START) { // outputStringToUART0("\n\r setADXL345Register: about to write address \n\r"); r = I2C_Write(ADXL345_ADDR_WRITE); // address the device, say we are going to write if (r == TW_MT_SLA_ACK) { // outputStringToUART0("\n\r setADXL345Register: about to write data \n\r"); r = I2C_Write(reg); // tell the device the register we are going to want if (r == TW_MT_DATA_ACK) { r = I2C_Start(); // restart, preparatory to reading r = I2C_Write(ADXL345_ADDR_READ); // address the device, say we are going to read // outputStringToUART0("\n\r setADXL345Register: about to read value \n\r"); *valp = I2C_Read(0); // do NACK, since this is the last and only byte // r = I2C_Write(val); // set the value // outputStringToUART0("\n\r setADXL345Register: about to Stop \n\r"); I2C_Stop(); // outputStringToUART0("\n\r setADXL345Register: Stop completed \n\r"); return I2C_OK; } else { // could not write data to device I2C_Stop(); return errNoI2CDataAck; } } else { // could not address device I2C_Stop(); return errNoI2CAddressAck; } } else { // could not START return errNoI2CStart; } };
// Generic function to set a single ADXL345 register to a value uint8_t setADXL345Register (uint8_t reg, uint8_t val) { uint8_t r; r = I2C_Start(); if (r == TW_START) { // outputStringToUART0("\n\r setADXL345Register: about to write address \n\r"); r = I2C_Write(ADXL345_ADDR_WRITE); // address the device, say we are going to write if (r == TW_MT_SLA_ACK) { // outputStringToUART0("\n\r setADXL345Register: about to write data \n\r"); r = I2C_Write(reg); // tell the device the register we are going to want if (r == TW_MT_DATA_ACK) { // outputStringToUART0("\n\r setADXL345Register: about to write value \n\r"); r = I2C_Write(val); // set the value // outputStringToUART0("\n\r setADXL345Register: about to Stop \n\r"); I2C_Stop(); // outputStringToUART0("\n\r setADXL345Register: Stop completed \n\r"); return I2C_OK; } else { // could not write data to device I2C_Stop(); return errNoI2CDataAck; } } else { // could not address device I2C_Stop(); return errNoI2CAddressAck; } } else { // could not START return errNoI2CStart; } };
bool MPL3115A2_write8(uint8_t a, uint8_t d) { unsigned char data_write[2]; data_write[0] = a; data_write[1] = d; int i; for(i=0;i<5;i++) { if(I2C_Write(MPL3115A2_ADDRESS, data_write, 2, 1)) // no stop bit break; } if(i<5) { d = MPL3115A2_read8(a); while(d != data_write[1]) { if(I2C_Write(MPL3115A2_ADDRESS, data_write, 2, 1)) // no stop bit { d = MPL3115A2_read8(a); if (d == data_write[1]) return true; } i++; if (i>5) break; } return true; } return false; }
/********************************************************************* * * I2C_PCA9532_SetPwm * * Function description * Sets the timing for PWM0 or PWM1 and assigns the pin to the * according PWM. * * Return value * 0: O.K. * != 0: Error */ U8 I2C_PCA9532_SetPwm(U32 I2CBaseAddr, U8 Addr, U8 Pin, U8 PwmNumber, U8 Pwm, U8 Psc) { U8 Data[2]; U8 r; if (PwmNumber > 1) { return 1; // Error, invalid PWM number } if (PwmNumber) { Data[0] = PSC1; } else { Data[0] = PSC0; } Data[1] = Psc; r = I2C_Write(I2CBaseAddr, Addr, Data, 2); if (r == 0) { if (PwmNumber) { Data[0] = PWM1; } else { Data[0] = PWM0; } Data[1] = Pwm; r = I2C_Write(I2CBaseAddr, Addr, Data, 2); if (r == 0) { r = _SetPinSelect(I2CBaseAddr, Addr, Pin, I2C_PCA9532_PWM0 + PwmNumber); } } return r; }
unsigned char BusyXLCD(void) { OLATB_curr |= 0xC0; // RW and RS are on clockLCDLow(); I2C_Write(EXPANDER_IODIRB, 0x1E); // data bus is now an input I2C_Write(EXPANDER_OLATB, OLATB_curr); DelayFor18TCY(); clockLCDHigh(); // Clock in the command with E DelayFor18TCY(); busy = I2C_Read(EXPANDER_GPIOB); clockLCDLow(); // Reset clock line DelayFor18TCY(); clockLCDHigh(); // Clock out other nibble DelayFor18TCY(); clockLCDLow(); OLATB_curr &= 0xBF; // Reset control line I2C_Write(EXPANDER_OLATB, OLATB_curr); I2C_Write(EXPANDER_IODIRB, 0x00); // set data bus back to output // busy bit is high? if (busy & 0x02) { return 1; } // Busy bit is low return 0; }
//-------------------------------------------------------- void I2C_StoreDate(stDS1307Time *time) { I2C_Write(TMR_ADDR,REG_MONTH,time->Month); _delay_us(100); I2C_Write(TMR_ADDR,REG_DATE,time->Date); _delay_us(100); }
void I2C_WriteRegister(uint8_t deviceRegister, uint8_t data) { I2C_Start(DS1307); // send address I2C_Write(deviceRegister); // write data to that address I2C_Write(data); I2C_Stop(); }
void Init_L3G4200D(void) { SCLDirOut(); SDADirOut(); I2C_Write(L3G4200D_SLAVE_ADDR, CTRL_REG1,0x4f); I2C_Write(L3G4200D_SLAVE_ADDR, CTRL_REG2,0x00); I2C_Write(L3G4200D_SLAVE_ADDR, CTRL_REG3,0x08); I2C_Write(L3G4200D_SLAVE_ADDR, CTRL_REG4,0x00); I2C_Write(L3G4200D_SLAVE_ADDR, CTRL_REG5,0x00); }
//--------------------------------------------------- void I2C_StoreTime(stDS1307Time *time) { I2C_Write(TMR_ADDR,REG_HOURS,time->Hours); _delay_us(100); I2C_Write(TMR_ADDR,REG_MINUTES,time->Minutes); _delay_us(100); I2C_Write(TMR_ADDR,REG_SECONDS,0x0); _delay_us(100); }
/*************************************************************************************************** void RTC_Init() *************************************************************************************************** * I/P Arguments: none. * Return value : none * description :This function is used to Initialize the Ds1307 RTC. ***************************************************************************************************/ void RTC_Init() { I2C_Init(); // Initialize the I2c module. I2C_Start(); // Start I2C communication I2C_Write(C_Ds1307WriteMode_U8); // Connect to DS1307 by sending its ID on I2c Bus I2C_Write(C_Ds1307ControlRegAddress_U8);// Select the Ds1307 ControlRegister to configure Ds1307 I2C_Write(0x00); // Write 0x00 to Control register to disable SQW-Out I2C_Stop(); // Stop I2C communication after initializing DS1307 }
/*************************************************************************************************** void RTC_SetDate(uint8_t var_day_u8, uint8_t var_month_u8, uint8_t var_year_u8) **************************************************************************************************** * I/P Arguments: uint8_t,uint8_t,uint8_t-->day,month,year to Initialize the Date into DS1307. * Return value : none * description :This function is used to set Date(dd,mm,yy) into the Ds1307 RTC. The new Date is updated into the non volatile memory of Ds1307. Note: The I/P arguments should of BCD, like 0x15,0x08,0x47 for 15th day,8th month and 47th year. ***************************************************************************************************/ void RTC_SetDate(uint8_t var_day_u8, uint8_t var_month_u8, uint8_t var_year_u8) { I2C_Start(); // Start I2C communication I2C_Write(C_Ds1307WriteMode_U8); // connect to DS1307 by sending its ID on I2c Bus I2C_Write(C_Ds1307DateRegAddress_U8); // Request DAY RAM address at 04H I2C_Write(var_day_u8); // Write date on RAM address 04H I2C_Write(var_month_u8); // Write month on RAM address 05H I2C_Write(var_year_u8); // Write year on RAM address 06h I2C_Stop(); // Stop I2C communication after Setting the Date }
void DS1307_SetTime(unsigned char hh, unsigned char mm, unsigned char ss) { I2C_Start(); // Start I2C communication I2C_Write(DS1307_ID); // connect to DS1307 by sending its ID on I2c Bus I2C_Write(SEC_ADDRESS); // Select the SEC RAM address I2C_Write(ss); // Write sec on RAM address 00H I2C_Write(mm); // Write min on RAM address 01H I2C_Write(hh); // Write hour on RAM address 02H I2C_Stop(); // Stop I2C communication after Setting the Time }
/*************************************************************************************************** void RTC_SetTime(uint8_t var_hour_u8, uint8_t var_min_u8, uint8_t var_sec_u8) **************************************************************************************************** * I/P Arguments: uint8_t,uint8_t,uint8_t-->hh,mm,ss to Initialize the time into DS1307. * Return value : none * description :This function is used to update the Time(hh,mm,ss) of Ds1307 RTC. The new time is updated into the non volatile memory of Ds1307. Note: The I/P arguments should of BCD, like 0x12,0x39,0x26 for 12hr,39min and 26sec. ***************************************************************************************************/ void RTC_SetTime(uint8_t var_hour_u8, uint8_t var_min_u8, uint8_t var_sec_u8) { I2C_Start(); // Start I2C communication I2C_Write(C_Ds1307WriteMode_U8); // connect to DS1307 by sending its ID on I2c Bus I2C_Write(C_Ds1307SecondRegAddress_U8); // Select the SEC RAM address I2C_Write(var_sec_u8); // Write sec from RAM address 00H I2C_Write(var_min_u8); // Write min from RAM address 01H I2C_Write(var_hour_u8); // Write hour from RAM address 02H I2C_Stop(); // Stop I2C communication after Setting the Time }
void DS1307_SetDate(unsigned char dd, unsigned char mm, unsigned char yy) { I2C_Start(); // Start I2C communication I2C_Write(DS1307_ID); // connect to DS1307 by sending its ID on I2c Bus I2C_Write(DATE_ADDRESS); // Request DAY RAM address at 04H I2C_Write(dd); // Write date on RAM address 04H I2C_Write(mm); // Write month on RAM address 05H I2C_Write(yy); // Write year on RAM address 06h I2C_Stop(); // Stop I2C communication after Setting the Date }
int function(void) { void DS1307_Init() { I2C_Init(); // Initilize the I2c module. I2C_Start(); // Start I2C communication I2C_Write(DS1307_ID); // Connect to DS1307 by sending its ID on I2c Bus I2C_Write(CONTROL); // Select the Ds1307 ControlRegister to configure Ds1307 I2C_Write(0x00); // Write 0x00 to Control register to disable SQW-Out I2C_Stop(); // Stop I2C communication after initilizing DS1307 }
void MP3Player::setVolume(byte volume) { #define DLA 0x46 #define DRA 0x48 byte Vol; Vol=255-volume; I2C_Write(DLA, Vol); //left channel volume I2C_Write(DRA, Vol); //right channel volume vol = volume; }
/***************************************** * try to detect whether the ADXL345 Accelerometer is there, and functioning * returns with global "motionFlags.accelerometerIsThere" set or cleared *****************************************/ uint8_t findADXL345 (void) { uint8_t r; outputStringToUART0("\n\r entered findADXL345 routine \n\r"); motionFlags &= ~(1<<accelerometerIsThere); // flag cleared, until accel found r = I2C_Start(); len = sprintf(str, "\n\r I2C_Start: 0x%x\n\r", r); outputStringToUART0(str); if (r == TW_START) { r = I2C_Write(ADXL345_ADDR_WRITE); // address the device, say we are going to write len = sprintf(str, "\n\r I2C_Write(ADXL345_ADDR_WRITE): 0x%x\n\r", r); outputStringToUART0(str); if (r == TW_MT_SLA_ACK) { motionFlags |= (1<<accelerometerIsThere); // accel found, set flag r = I2C_Write(ADXL345_REG_DEVID); // tell the device the register we are going to want len = sprintf(str, "\n\r I2C_Write(ADXL345_REG_DEVID): 0x%x\n\r", r); outputStringToUART0(str); if (r == TW_MT_DATA_ACK) { r = I2C_Start(); // restart, preparatory to reading len = sprintf(str, "\n\r ReStart: 0x%x\n\r", r); outputStringToUART0(str); if (r == TW_REP_START){ r = I2C_Write(ADXL345_ADDR_READ); // address the device, say we are going to read len = sprintf(str, "\n\r I2C_Write(ADXL345_ADDR_READ): 0x%x\n\r", r); outputStringToUART0(str); if (r == TW_MR_SLA_ACK){ r = I2C_Read(0); // do NACK, since this is the last byte len = sprintf(str, "\n\r I2C_Read(0): 0x%x\n\r", r); outputStringToUART0(str); } } else { I2C_Stop(); return errNoI2CRepStart; } } else { // could not write data to device I2C_Stop(); return errNoI2CDataAck; } } else { // could not address device I2C_Stop(); return errNoI2CAddressAck; } } else { // could not START return errNoI2CStart; } I2C_Stop(); outputStringToUART0("\n\r I2C_Stop completed \n\r"); return I2C_OK; } // end of findAccelerometer
void display(void) { uint16_t i=0 ; uint8_t x ; // pointer to OLED data buffer uint8_t * p = poledbuff; unsigned char buff[17] ; ssd1306_singleCMD(0x21); ssd1306_singleCMD(0x00); ssd1306_singleCMD(0x7F); ssd1306_singleCMD(0x22); ssd1306_singleCMD(0x00); ssd1306_singleCMD(0x07); // Setup D/C to switch to data mode buff[0] = SSD_Data_Mode; // loop trough all OLED buffer and // send a bunch of 16 data byte in one xmission for ( i=0; i<(ssd1306_lcdwidth*ssd1306_lcdheight)>>7; i++ ){ for (x=1; x<=16; x++) buff[x] = *p++; I2C_Write(0x3C, &buff[0], 17); } }
/*---------------------------------------------------------------------------* * Routine: Temperature_Get *---------------------------------------------------------------------------* * Description: * Read the value of the ADT7420 and return the temperature in Celcius. * Inputs: * void * Outputs: * uint16_t -- temperature with 4 bits of fraction and 12 bits of * integer. *---------------------------------------------------------------------------*/ uint16_t Temperature_Get(void) { uint8_t target_reg; uint8_t target_data[2] = {0x00, 0x00}; uint16_t temp = 0; uint32_t timeout = MSTimerGet(); I2C_Request r; r.iAddr = ADT7420_ADDR>>1; r.iSpeed = 100; r.iWriteData = &target_reg; r.iWriteLength = 1; r.iReadData = target_data; r.iReadLength = 2; I2C_Write(&r, 0); while ((I2C_IsBusy()) && (MSTimerDelta(timeout) < 10)) {} I2C_Read(&r, 0); while ((I2C_IsBusy()) && (MSTimerDelta(timeout) < 10)) {} /* Convert the device measurement into a decimal number and insert into a temporary string to be displayed */ temp = (target_data[0] << 8) + target_data[1]; // temp = temp >> 3; return temp; }
uint8_t MPL3115A2_read8(uint8_t a) { int i=0; uint8_t out; for(;i<5;i++) { if(I2C_Write(MPL3115A2_ADDRESS, (unsigned char*)&a, 1, 0)) break; // if written length > 0 } if (i>=5) return 0xff; // failed for(i=0;i<5;i++) { if(I2C_Read(MPL3115A2_ADDRESS, &out, 1, 0)) break; // if read length > 0 } if (i<5) return out; return 0xff; }
bool MPL3115A2_readBytes_(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest, bool loop) { int i=0; for(;i<5;i++) { if(I2C_Write(address, (unsigned char*)&subAddress, 1, 0)) break; // if written length > 0 if (!loop) break; } if (i>=5) return false; for(i=0;i<5;i++) { if(I2C_Read(address, dest, count, 1)) break; // if read length > 0 if (!loop) break; } if (i<5) return true; return false; }
/****************************************************************************** * @brief Single Write a Register. * * @param reg - Register Address. * @param txData - Data to be sent * * @return None. ******************************************************************************/ void AD7156_WriteReg(int reg, unsigned char txData) { unsigned char txBuffer[1] = {0x00}; txBuffer[0] = txData; I2C_Write(I2C_BASEADDR, AD7156_I2C_ADDR, reg, 1, txBuffer); }
// Turns on the LSM303's accelerometer and magnetometers and places them in normal // mode. void enableDefault(void) { // Enable Accelerometer // 0x27 = 0b00100111 // Normal power mode, all axes enabled // writeAccReg(LSM303_CTRL_REG1_A, 0x27); //if (_device == LSM303DLHC_DEVICE) // writeAccReg(LSM303_CTRL_REG4_A, 0x08); // DLHC: enable high resolution mode // Enable Magnetometer // 0x00 = 0b00000000 // Enter Continuous conversion mode from sleep mode // writeMagReg(LSM303_MR_REG_M, 0x00); //if (I2C_Write(COMPASS_I2C_SCL_BASE, COMPASS_I2C_SDA_BASE, ACC_ADDRESS_SA0_A_HIGH, LSM303_CTRL_REG1_A, 0x27)){ // printf("Initialize success!\n"); // } // else{ printf("Failed to enable accelerometer\r\n"); // } //For magnetic sensors the default (factory) 7-bit slave address is 0011110xb. R = 1, W = 0 so READ = 0x00111101 = 0x3D if (I2C_Write(COMPASS_I2C_SCL_BASE, COMPASS_I2C_SDA_BASE, MAG_ADDRESS, LSM303_MR_REG_M, 0x00)){ printf("Initialize success!\n"); } else{ printf("Failed to enable magnetometer\r\n"); } }
/*---------------------------------------------------------------------------* * Routine: Accelerometer_Get *---------------------------------------------------------------------------* * Description: * Read the value of the ADT7420 and return the LightSensor in Lux. * Inputs: * void * Outputs: * uint16_t -- LightSensor with 4 bits of fraction and 12 bits of * integer. *---------------------------------------------------------------------------*/ int16_t *Accelerometer_Get(void) { uint8_t target_reg, acc_axis; uint8_t target_data[2] = {0x00, 0x00}; uint32_t timeout = MSTimerGet(); I2C_Request r; //Accelerometer_Init(); for(acc_axis=0; acc_axis<3; acc_axis++) { target_reg = acc_reg_addr[acc_axis]; r.iAddr = ACCEL_ADDR>>1; r.iSpeed = 100; r.iWriteData = &target_reg; r.iWriteLength = 1; r.iReadData = target_data; r.iReadLength = 2; I2C_Write(&r, 0); while ((I2C_IsBusy()) && (MSTimerDelta(timeout) < 10)) {} I2C_Read(&r, 0); while ((I2C_IsBusy()) && (MSTimerDelta(timeout) < 10)) {} /* Convert the device measurement into a decimal number and insert into a temporary string to be displayed */ gAccData[acc_axis] = (target_data[1] << 8) + target_data[0]; } return gAccData; }
void Accel_SetMode(const TAccelMode mode) { //Update the static variable CurrentMode = mode; //Read register 4 of the accelerometer uint8_t reg4Tmp; I2C_PollRead(MMA8451Q_CTRL_REG4, ®4Tmp, 1); switch (mode) { case ACCEL_POLL: reg4Tmp &= ~MMA8451Q_CTRL_REG4_INT_EN_DRDY_MASK; case ACCEL_INT: default: reg4Tmp |= MMA8451Q_CTRL_REG4_INT_EN_DRDY_MASK; } /*Active off*/ SetActive(bFALSE); /*Write the interrupt (or not)*/ I2C_Write(MMA8451Q_CTRL_REG4, reg4Tmp, bFALSE); /*Active on*/ SetActive(bTRUE); }
uint32_t I2C_WrBuf(uint8_t DevAddr, uint8_t *buf, uint32_t cnt) { //Generate a Start condition I2C_Start(); //Send I2C device Address I2C_Addr(DevAddr, I2C_Direction_Transmitter); //Unstretch the clock by just reading SR2 (Physically the clock is continued to be strectehed because we have not written anything to the DR yet.) (void) I2Cx->SR2; //Start Writing Data while (cnt--) { I2C_Write(*buf++); } //Wait for the data on the shift register to be transmitted completely WaitSR1FlagsSet(I2C_SR1_BTF); //Here TXE=BTF=1. Therefore the clock stretches again. //Order a stop condition at the end of the current tranmission (or if the clock is being streched, generate stop immediatelly) I2Cx->CR1 |= I2C_CR1_STOP; //Stop condition resets the TXE and BTF automatically. //Wait to be sure that line is iddle WaitLineIdle(); return 0; }