uint8_t I2C_Read8(uint8_t addr, uint8_t reg) { uint8_t data = 0; I2C_AcknowledgeConfig(I2C1, ENABLE); while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); I2C_GenerateSTART(I2C1, ENABLE); while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_SB)); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1, addr<<1,I2C_Direction_Transmitter); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C1, reg); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTART(I2C1, ENABLE); while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_SB)); I2C_Send7bitAddress(I2C1, addr<<1, I2C_Direction_Receiver); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); I2C_NACKPositionConfig(I2C1, I2C_NACKPosition_Current); I2C_AcknowledgeConfig(I2C1, DISABLE); //need to add a wait here for new data, right now it goes to fast to get the new data. while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE)); data = I2C_ReceiveData(I2C1); //while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)); I2C_GenerateSTOP(I2C1, ENABLE); while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF)); return data; }
unsigned char I2CRXByte(I2C_TypeDef *I2Cx) { unsigned short temp; #ifdef I2C_INT_MODE I2C_ITConfig(I2Cx, I2C_IT_RX_FULL, ENABLE); while(1) { if(rx_flag) { rx_flag = 0; break; } } #else I2CRXFullCheck(I2Cx); #endif temp = I2C_ReceiveData(I2Cx); return (unsigned char)temp; }
void crI2c( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex ) { static uint8_t i; crSTART( xHandle ); for ( ;; ) { static uint8_t init = 0; if ( init == 0 ) { i2cSetEn( 0, 1 ); uint8_t data[1]; data[0] = 77; i2cIo( 0, 0, 1, 1, data ); i2cConfig( 0, 0, 123, 10000 ); init = 1; } TI2C * idc = i2c( uxIndex ); // Commands loop. if ( idc->master ) { if ( ( idc->sendCnt ) || ( idc->receiveCnt ) ) { idc->status = I2C_BUSY; // wait for BUSY bit to get cleared. idc->elapsed = 0; while ( I2C_GetFlagStatus( idc->i2c, I2C_FLAG_BUSY ) ) { if ( idc->elapsed++ > idc->timeout ) { idc->status = I2C_ERROR_BUSY; goto i2c_end; } crDELAY( xHandle, 1 ); idc = i2c( uxIndex ); } if ( idc->sendCnt ) { // Generate START condition on a bus. I2C_GenerateSTART( idc->i2c, ENABLE ); idc->status = I2C_MMS; // Wait for SB to be set idc->elapsed = 0; while ( !I2C_CheckEvent( idc->i2c, I2C_EVENT_MASTER_MODE_SELECT ) ) { if ( idc->elapsed++ > idc->timeout ) { idc->status = I2C_ERROR_MMS; I2C_GenerateSTOP( idc->i2c, ENABLE ); goto i2c_end; } crDELAY( xHandle, 1 ); idc = i2c( uxIndex ); } // Transmit the slave address with write operation enabled. I2C_Send7bitAddress( idc->i2c, idc->address, I2C_Direction_Transmitter ); idc->status = I2C_TMS; // Test on ADDR flag. idc->elapsed = 0; while ( !I2C_CheckEvent( idc->i2c, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) ) { if ( idc->elapsed++ > idc->timeout ) { idc->status = I2C_ERROR_TMS; I2C_GenerateSTOP( idc->i2c, ENABLE ); goto i2c_end; } crDELAY( xHandle, 1 ); idc = i2c( uxIndex ); } // Read data from send queue. for ( i=0; i<idc->sendCnt; i++ ) { idc = i2c( uxIndex ); // Transmit data. uint8_t data = idc->sendQueue[ i ]; I2C_SendData( idc->i2c, data ); // Test for TXE flag (data sent). idc->status = I2C_MBT; idc->elapsed = 0; while ( !I2C_CheckEvent( idc->i2c, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) ) { if ( idc->elapsed++ > idc->timeout ) { idc->status = I2C_ERROR_MBT; I2C_GenerateSTOP( idc->i2c, ENABLE ); goto i2c_end; } crDELAY( xHandle, 1 ); idc = i2c( uxIndex ); } idc->bytesWritten = i+1; } // Wait untill BTF flag is set before generating STOP. idc->status = I2C_BTF; idc->elapsed = 0; while ( !I2C_GetFlagStatus( idc->i2c, I2C_FLAG_BTF ) ) { if ( idc->elapsed++ > idc->timeout ) { idc->status = I2C_ERROR_BTF; I2C_GenerateSTOP( idc->i2c, ENABLE ); goto i2c_end; } crDELAY( xHandle, 1 ); idc = i2c( uxIndex ); } } // Receiving data if necessary. if ( idc->receiveCnt ) { I2C_AcknowledgeConfig( idc->i2c, ENABLE ); // Generate START condition if there was at least one byte written. I2C_GenerateSTART( idc->i2c, ENABLE ); idc->status = I2C_MMS_R; // Wait for SB to be set idc->elapsed = 0; while ( !I2C_CheckEvent( idc->i2c, I2C_EVENT_MASTER_MODE_SELECT ) ) { if ( idc->elapsed++ > idc->timeout ) { idc->status = I2C_ERROR_MMS_R; I2C_GenerateSTOP( idc->i2c, ENABLE ); goto i2c_end; } crDELAY( xHandle, 1 ); idc = i2c( uxIndex ); } I2C_Send7bitAddress( idc->i2c, idc->address, I2C_Direction_Receiver ); // Test on ADDR Flag idc->status = I2C_RMS; idc->elapsed = 0; while ( !I2C_CheckEvent( idc->i2c, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ) ) { if ( idc->elapsed++ > idc->timeout ) { idc->status = I2C_ERROR_RMS; I2C_GenerateSTOP( idc->i2c, ENABLE ); goto i2c_end; } crDELAY( xHandle, 1 ); idc = i2c( uxIndex ); } // Receiving a number of bytes from slave. for ( i=0; i<idc->receiveCnt; i++ ) { // Turn acknowledge off when reading the last byte. if ( i == (idc->receiveCnt-1) ) I2C_AcknowledgeConfig( idc->i2c, DISABLE ); // Wait for data available. idc->status = I2C_MBR; idc->elapsed = 0; while ( !I2C_CheckEvent( idc->i2c, I2C_EVENT_MASTER_BYTE_RECEIVED ) ) { if ( idc->elapsed++ > idc->timeout ) { idc->status = I2C_ERROR_MBR; I2C_GenerateSTOP( idc->i2c, ENABLE ); goto i2c_end; } crDELAY( xHandle, 1 ); idc = i2c( uxIndex ); } // Read the data. uint8_t data = I2C_ReceiveData( idc->i2c ); idc->receiveQueue[i] = data; idc->bytesRead = i+1; } } // Generating STOP. I2C_GenerateSTOP( idc->i2c, ENABLE ); // Idle status when finished in regular way. idc->status = I2C_IDLE; } } else // master. { // slave mode IO. //...... implementation..... // Idle status when finished in regular way. //idc->status = I2C_IDLE; crDELAY( xHandle, 1 ); } i2c_end: // To prevent cyclic writes of zero data. idc->sendCnt = 0; idc->receiveCnt = 0; // Give other coroutines time for running. crDELAY( xHandle, 1 ); } crEND(); }
uint32_t BH1750_Read(void) { uint16_t BH_H; uint16_t BH_L; uint32_t value; int iTimeout = DEF_TIMEOUT_I2C; I2C_AcknowledgeConfig(BH1750_I2C,ENABLE); // Enable I2C acknowledge I2C_GenerateSTART(BH1750_I2C,ENABLE); // Send START condition iTimeout = DEF_TIMEOUT_I2C; while (!I2C_CheckEvent(BH1750_I2C,I2C_EVENT_MASTER_MODE_SELECT)) { // Wait for EV5 iTimeout--; if(!(iTimeout)) { return 0; } } iTimeout = DEF_TIMEOUT_I2C; while (!I2C_CheckEvent(BH1750_I2C, I2C_EVENT_MASTER_MODE_SELECT)) { // Wait for EV5 iTimeout--; if(!(iTimeout)) { return 0; } } I2C_Send7bitAddress(BH1750_I2C, BH1750_ADDRESS, I2C_Direction_Receiver); // Send slave address for READ iTimeout = DEF_TIMEOUT_I2C; while (!I2C_CheckEvent(BH1750_I2C,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { // Wait for EV6 iTimeout--; if(!(iTimeout)) { return 0; } } iTimeout = DEF_TIMEOUT_I2C; while (!I2C_CheckEvent(BH1750_I2C,I2C_EVENT_MASTER_BYTE_RECEIVED)) { // Wait for EV7 (Byte received from slave) iTimeout--; if(!(iTimeout)) { return 0; } } BH_H = (uint16_t)I2C_ReceiveData(BH1750_I2C); // Receive MSB iTimeout = DEF_TIMEOUT_I2C; while (!I2C_CheckEvent(BH1750_I2C,I2C_EVENT_MASTER_BYTE_RECEIVED)) { // Wait for EV7 (Byte received from slave) iTimeout--; if(!(iTimeout)) { return 0; } } BH_L = (uint32_t)I2C_ReceiveData(BH1750_I2C); // Receive LSB I2C_AcknowledgeConfig(BH1750_I2C,DISABLE); // Disable I2C acknowledgment I2C_GenerateSTOP(BH1750_I2C,ENABLE); // Send STOP condition value = BH_H*256 + BH_L; value = value*10/12; return value; }
void I2C_BufferRead(I2C_TypeDef* I2Cx,u8* pBuffer,u8 devAddr, u8 ReadAddr, u16 NumByteToRead) { #if 0 /* Send START condition */ I2C_GenerateSTART(I2Cx, ENABLE); /* Test on EV5 and clear it */ while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)); /* Send EEPROM address for write */ I2C_Send7bitAddress(I2Cx, devAddr, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); /* Clear EV6 by setting again the PE bit */ I2C_Cmd(I2Cx, ENABLE); /* Send the EEPROM's internal address to write to */ I2C_SendData(I2Cx, ReadAddr); /* Test on EV8 and clear it */ while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); /* Send STRAT condition a second time */ I2C_GenerateSTART(I2Cx, ENABLE); /* Test on EV5 and clear it */ while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)); /* Send EEPROM address for read */ I2C_Send7bitAddress(I2Cx, devAddr, I2C_Direction_Receiver); /* Test on EV6 and clear it */ while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); /* While there is data to be read */ while(NumByteToRead) { if(NumByteToRead == 1) { /* Disable Acknowledgement */ I2C_AcknowledgeConfig(I2Cx, DISABLE); /* Send STOP Condition */ I2C_GenerateSTOP(I2Cx, ENABLE); } /* Test on EV7 and clear it */ if(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)) { /* Read a byte from the EEPROM */ *pBuffer = I2C_ReceiveData(I2Cx); /* Point to the next location where the byte read will be saved */ pBuffer++; /* Decrement the read bytes counter */ NumByteToRead--; } } /* Enable Acknowledgement to be ready for another reception */ I2C_AcknowledgeConfig(I2Cx, ENABLE); #endif }
/** * @brief Enables or disables the LM75. * @param NewState: specifies the LM75 new status. This parameter can be ENABLE * or DISABLE. * @retval None */ uint8_t LM75_ShutDown(FunctionalState NewState) { uint8_t LM75_BufferRX[2] ={0,0}; uint8_t LM75_BufferTX = 0; __IO uint8_t RegValue = 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); /* Get received data */ RegValue = (uint8_t)LM75_BufferRX[0]; /*---------------------------- Transmission Phase ---------------------------*/ /* Enable or disable SD bit */ if (NewState != DISABLE) { /* Enable LM75 */ LM75_BufferTX = RegValue & LM75_SD_RESET; } else { /* Disable LM75 */ LM75_BufferTX = RegValue | LM75_SD_SET; } /* 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; }
void LSM303DLH_I2C_BufferRead(u8 slAddr, u8* pBuffer, u8 ReadAddr, u16 NumByteToRead) { iNEMO_ENTER_CRITICAL(); /* While the bus is busy */ while(I2C_GetFlagStatus(LSM_I2C, I2C_FLAG_BUSY)); /* Send START condition */ I2C_GenerateSTART(LSM_I2C, ENABLE); /* Test on EV5 and clear it */ while(!I2C_CheckEvent(LSM_I2C, I2C_EVENT_MASTER_MODE_SELECT)); /* Send LSM303DLH_Magn address for write */ I2C_Send7bitAddress(LSM_I2C, slAddr, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ while(!I2C_CheckEvent(LSM_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); /* Clear EV6 by setting again the PE bit */ I2C_Cmd(LSM_I2C, ENABLE); /* Send the LSM303DLH_Magn's internal address to write to */ I2C_SendData(LSM_I2C, ReadAddr); /* Test on EV8 and clear it */ while(!I2C_CheckEvent(LSM_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); /* Send STRAT condition a second time */ I2C_GenerateSTART(LSM_I2C, ENABLE); /* Test on EV5 and clear it */ while(!I2C_CheckEvent(LSM_I2C, I2C_EVENT_MASTER_MODE_SELECT)); /* Send LSM303DLH address for read */ I2C_Send7bitAddress(LSM_I2C, slAddr, I2C_Direction_Receiver); /* Test on EV6 and clear it */ while(!I2C_CheckEvent(LSM_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); /* While there is data to be read */ while(NumByteToRead) { if(NumByteToRead == 1) { /* Disable Acknowledgement */ I2C_AcknowledgeConfig(LSM_I2C, DISABLE); /* Send STOP Condition */ I2C_GenerateSTOP(LSM_I2C, ENABLE); } /* Test on EV7 and clear it */ if(I2C_CheckEvent(LSM_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED)) { /* Read a byte from the LSM303DLH */ *pBuffer = I2C_ReceiveData(LSM_I2C); /* Point to the next location where the byte read will be saved */ pBuffer++; /* Decrement the read bytes counter */ NumByteToRead--; } } /* Enable Acknowledgement to be ready for another reception */ I2C_AcknowledgeConfig(LSM_I2C, ENABLE); iNEMO_EXIT_CRITICAL(); }
uint8_t AJS_TargetIO_I2cRead(void* ctx) { I2C_Pin* i2c = (I2C_Pin*)ctx; return I2C_ReceiveData(i2c->I2Cx); }
/******************************************************************************* * Function Name : main * Description : Main program * Input : None * Output : None * Return : None *******************************************************************************/ int main(void) { #ifdef DEBUG debug(); #endif /* System clocks configuration ---------------------------------------------*/ RCC_Configuration(); /* NVIC configuration ------------------------------------------------------*/ NVIC_Configuration(); /* GPIO configuration ------------------------------------------------------*/ GPIO_Configuration(); /* Enable I2C1 and I2C2 ----------------------------------------------------*/ I2C_Cmd(I2C1, ENABLE); I2C_Cmd(I2C2, ENABLE); /* I2C1 configuration ------------------------------------------------------*/ I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = ClockSpeed; I2C_Init(I2C1, &I2C_InitStructure); /* I2C2 configuration ------------------------------------------------------*/ I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_10bit; I2C_InitStructure.I2C_OwnAddress1 = I2C2_SLAVE_ADDRESS10; I2C_Init(I2C2, &I2C_InitStructure); /*----- Transmission Phase -----*/ /* Send I2C1 START condition */ I2C_GenerateSTART(I2C1, ENABLE); /* Test on I2C1 EV5 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); /* Send Header to I2C2 for write */ I2C_SendData(I2C1, HeaderAddressWrite); /* Test on I2C1 EV9 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_ADDRESS10)); /* Send I2C2 slave Address for write */ I2C_Send7bitAddress(I2C1, I2C2_SLAVE_ADDRESS7, I2C_Direction_Transmitter); /* Test on I2C2 EV1 and clear it */ while(!I2C_CheckEvent(I2C2, I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED)); /* Test on I2C1 EV6 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); /* Send data */ while (RxIdx < BufferSize) { /* Send I2C1 data */ I2C_SendData(I2C1, I2C1_Buffer_Tx[TxIdx++]); /* Test on I2C2 EV2 and clear it */ while(!I2C_CheckEvent(I2C2, I2C_EVENT_SLAVE_BYTE_RECEIVED)); /* Store received data on I2C2 */ I2C2_Buffer_Rx[RxIdx++] = I2C_ReceiveData(I2C2); /* Test on I2C1 EV8 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); } /* Send I2C1 STOP Condition */ I2C_GenerateSTOP(I2C1, ENABLE); /* Test on I2C2 EV4 and clear it */ while(!I2C_CheckEvent(I2C2, I2C_EVENT_SLAVE_STOP_DETECTED)); /* Clear I2C2 STOPF flag: read operation to I2C_SR1 followed by a write operation to I2C_CR1 */ (void)(I2C_GetFlagStatus(I2C2, I2C_FLAG_STOPF)); I2C_Cmd(I2C2, ENABLE); /* Check the corectness of written data */ TransferStatus = Buffercmp(I2C1_Buffer_Tx, I2C2_Buffer_Rx, BufferSize); /* TransferStatus = PASSED, if the transmitted and received data are equal */ /* TransferStatus = FAILED, if the transmitted and received data are different */ while (1) { } }
char MPU9250_I2C_ByteRead(u8 slaveAddr, u8 readAddr) { char tmp = 0; // ENTR_CRT_SECTION(); /* While the bus is busy */ while (I2C_GetFlagStatus(MPU9250_I2C, I2C_FLAG_BUSY)); /* Send START condition */ I2C_GenerateSTART(MPU9250_I2C, ENABLE); /* Test on EV5 and clear it */ while (!I2C_CheckEvent(MPU9250_I2C, I2C_EVENT_MASTER_MODE_SELECT)); /* Send MPU9250 address for write */ I2C_Send7bitAddress(MPU9250_I2C, slaveAddr, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ while (!I2C_CheckEvent(MPU9250_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); /* Clear EV6 by setting again the PE bit */ I2C_Cmd(MPU9250_I2C, ENABLE); /* Send the MPU9250's internal address to write to */ I2C_SendData(MPU9250_I2C, readAddr); /* Test on EV8 and clear it */ while (!I2C_CheckEvent(MPU9250_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); /* Send STRAT condition a second time */ I2C_GenerateSTART(MPU9250_I2C, ENABLE); /* Test on EV5 and clear it */ while (!I2C_CheckEvent(MPU9250_I2C, I2C_EVENT_MASTER_MODE_SELECT)); /* Send MPU9250 address for read */ I2C_Send7bitAddress(MPU9250_I2C, slaveAddr, I2C_Direction_Receiver); /* Test on EV6 and clear it */ while (!I2C_CheckEvent(MPU9250_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); /* While there is data to be read */ for (;;) { /* Disable Acknowledgement */ I2C_AcknowledgeConfig(MPU9250_I2C, DISABLE); /* Send STOP Condition */ I2C_GenerateSTOP(MPU9250_I2C, ENABLE); /* Test on EV7 and clear it */ if (I2C_CheckEvent(MPU9250_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED)) { /* Read a byte from the MPU9250 */ tmp = I2C_ReceiveData(MPU9250_I2C); break; } } /* Enable Acknowledgement to be ready for another reception */ I2C_AcknowledgeConfig(MPU9250_I2C, ENABLE); // EXT_CRT_SECTION(); return tmp; }
/** * @brief Reads a block of data from the EEPROM. * @param pBuffer : pointer to the buffer that receives the data read from * the EEPROM. * @param ReadAddr : EEPROM's internal address to start reading from. * @param NumByteToRead : pointer to the variable holding number of bytes to * be read from the EEPROM. * * @note The variable pointed by NumByteToRead is reset to 0 when all the * data are read from the EEPROM. Application should monitor this * variable in order know when the transfer is complete. * * @note When number of data to be read is higher than 1, this function just * configures the communication and enable the DMA channel to transfer data. * Meanwhile, the user application may perform other tasks. * When number of data to be read is 1, then the DMA is not used. The byte * is read in polling mode. * * @retval sEE_OK (0) if operation is correctly performed, else return value * different from sEE_OK (0) or the timeout user callback. */ uint32_t TWI_MasterWriteRead(new_twi* TwiStruct, unsigned int TransmitBytes, unsigned int ReceiveBytes) { uint32_t sEETimeout; /* Set the pointer to the Number of data to be read. This pointer will be used by the DMA Transfer Completer interrupt Handler in order to reset the variable to 0. User should check on this variable in order to know if the DMA transfer has been complete or not. */ uint16_t NumByteToRead = ReceiveBytes; I2C_TypeDef *I2Cx = sEE_I2C[TwiStruct->TwiNr]; /* If bus is freeze we will reset the unit and restore the settings. */ if(I2C_GetFlagStatus(sEE_I2C[TwiStruct->TwiNr], I2C_FLAG_AF | I2C_FLAG_ARLO) || (I2Cx->CR1 & (1 << 8))) { /* sEE_I2C Peripheral Enable */ I2C_TypeDef I2CxBack; I2CxBack.CR1 = I2Cx->CR1; I2CxBack.CR2 = I2Cx->CR2; I2CxBack.OAR1 = I2Cx->OAR1; I2CxBack.OAR2 = I2Cx->OAR2; I2CxBack.CCR = I2Cx->CCR; I2CxBack.TRISE = I2Cx->TRISE; I2C_SoftwareResetCmd(sEE_I2C[TwiStruct->TwiNr], ENABLE); I2C_SoftwareResetCmd(sEE_I2C[TwiStruct->TwiNr], DISABLE); I2Cx->TRISE = I2CxBack.TRISE; I2Cx->CCR = I2CxBack.CCR; I2Cx->OAR2 = I2CxBack.OAR2; I2Cx->OAR1 = I2CxBack.OAR1; I2Cx->CR2 = I2CxBack.CR2; I2Cx->CR1 = I2CxBack.CR1; } /*!< While the bus is busy */ timer(TimerBusyTimeout); timer_interval(&TimerBusyTimeout, TwiStruct->BusyTimeOut); timer_enable(&TimerBusyTimeout); while(I2C_GetFlagStatus(sEE_I2C[TwiStruct->TwiNr], I2C_FLAG_BUSY)) { if(timer_tick(&TimerBusyTimeout)) { I2C_TypeDef I2CxBack; I2CxBack.CR1 = I2Cx->CR1; I2CxBack.CR2 = I2Cx->CR2; I2CxBack.OAR1 = I2Cx->OAR1; I2CxBack.OAR2 = I2Cx->OAR2; I2CxBack.CCR = I2Cx->CCR; I2CxBack.TRISE = I2Cx->TRISE; I2C_SoftwareResetCmd(sEE_I2C[TwiStruct->TwiNr], ENABLE); I2C_SoftwareResetCmd(sEE_I2C[TwiStruct->TwiNr], DISABLE); I2Cx->TRISE = I2CxBack.TRISE; I2Cx->CCR = I2CxBack.CCR; I2Cx->OAR2 = I2CxBack.OAR2; I2Cx->OAR1 = I2CxBack.OAR1; I2Cx->CR2 = I2CxBack.CR2; I2Cx->CR1 = I2CxBack.CR1; break; } } unsigned int cnt = 0; if(!TwiStruct->NoSendWriteOnRead) { /*!< Send START condition */ I2C_GenerateSTART(sEE_I2C[TwiStruct->TwiNr], ENABLE); /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent(sEE_I2C[TwiStruct->TwiNr], I2C_EVENT_MASTER_MODE_SELECT)) { if((sEETimeout--) == 0) { return false; } } /*!< Send EEPROM address for write */ I2C_Send7bitAddress(sEE_I2C[TwiStruct->TwiNr], TwiStruct->MasterSlaveAddr << 1, I2C_Direction_Transmitter); /*!< Test on EV6 and clear it */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent(sEE_I2C[TwiStruct->TwiNr], I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if((sEETimeout--) == 0) { return false; } } for(; cnt < TransmitBytes; cnt++) { /*!< Send the EEPROM's internal address to read from: MSB of the address first */ I2C_SendData(sEE_I2C[TwiStruct->TwiNr], TwiStruct->TxBuff[cnt]); /*!< Test on EV8 and clear it */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent(sEE_I2C[TwiStruct->TwiNr], I2C_EVENT_MASTER_BYTE_TRANSMITTED)) { if((sEETimeout--) == 0) { return false; } } } } if(ReceiveBytes) { /* If number of data to be read is 1, then DMA couldn't be used */ /* One Byte Master Reception procedure (POLLING) ---------------------------*/ if (NumByteToRead < 2) { /*!< Send STRAT condition a second time */ I2C_GenerateSTART(sEE_I2C[TwiStruct->TwiNr], ENABLE); /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent(sEE_I2C[TwiStruct->TwiNr], I2C_EVENT_MASTER_MODE_SELECT)) { if((sEETimeout--) == 0) { return false; } } /*!< Send EEPROM address for read */ I2C_Send7bitAddress(sEE_I2C[TwiStruct->TwiNr], TwiStruct->MasterSlaveAddr << 1, I2C_Direction_Receiver); /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */ sEETimeout = sEE_FLAG_TIMEOUT; while(I2C_GetFlagStatus(sEE_I2C[TwiStruct->TwiNr], I2C_FLAG_ADDR) == RESET) { if((sEETimeout--) == 0) { return false; } } /*!< Disable Acknowledgement */ I2C_AcknowledgeConfig(sEE_I2C[TwiStruct->TwiNr], DISABLE); /* Call User callback for critical section start (should typically disable interrupts) */ sEE_EnterCriticalSection_UserCallback(); /* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */ (void)sEE_I2C[TwiStruct->TwiNr]->SR2; /*!< Send STOP Condition */ I2C_GenerateSTOP(sEE_I2C[TwiStruct->TwiNr], ENABLE); /* Call User callback for critical section end (should typically re-enable interrupts) */ sEE_ExitCriticalSection_UserCallback(); /* Wait for the byte to be received */ sEETimeout = sEE_FLAG_TIMEOUT; while(I2C_GetFlagStatus(sEE_I2C[TwiStruct->TwiNr], I2C_FLAG_RXNE) == RESET) { if((sEETimeout--) == 0) { return false; } } /*!< Read the byte received from the EEPROM */ *TwiStruct->RxBuff = I2C_ReceiveData(sEE_I2C[TwiStruct->TwiNr]); /*!< Decrement the read bytes counter */ NumByteToRead--; /* Wait to make sure that STOP control bit has been cleared */ sEETimeout = sEE_FLAG_TIMEOUT; while(sEE_I2C[TwiStruct->TwiNr]->CR1 & I2C_CR1_STOP) { if((sEETimeout--) == 0) { return false; } } /*!< Re-Enable Acknowledgement to be ready for another reception */ I2C_AcknowledgeConfig(sEE_I2C[TwiStruct->TwiNr], ENABLE); } else/* More than one Byte Master Reception procedure (DMA) -----------------*/ { /*!< Send STRAT condition a second time */ I2C_GenerateSTART(sEE_I2C[TwiStruct->TwiNr], ENABLE); /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent(sEE_I2C[TwiStruct->TwiNr], I2C_EVENT_MASTER_MODE_SELECT)) { if((sEETimeout--) == 0) { return false; } } /*!< Send EEPROM address for read */ I2C_Send7bitAddress(sEE_I2C[TwiStruct->TwiNr], TwiStruct->MasterSlaveAddr << 1, I2C_Direction_Receiver); /* If number of data to be read is 1, then DMA couldn't be used */ /* One Byte Master Reception procedure (POLLING) ---------------------------*/ //if (NumByteToRead < 2) //{ /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */ sEETimeout = sEE_FLAG_TIMEOUT; while(I2C_GetFlagStatus(sEE_I2C[TwiStruct->TwiNr], I2C_FLAG_ADDR) == RESET) { if((sEETimeout--) == 0) { return false; } } (void)sEE_I2C[TwiStruct->TwiNr]->SR2; cnt = 0; for(; cnt < ReceiveBytes; cnt++) { if(cnt == ReceiveBytes - 1) { /*!< Disable Acknowledgement */ I2C_AcknowledgeConfig(sEE_I2C[TwiStruct->TwiNr], DISABLE); /* Call User callback for critical section start (should typically disable interrupts) */ sEE_EnterCriticalSection_UserCallback(); /* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */ (void)sEE_I2C[TwiStruct->TwiNr]->SR2; /*!< Send STOP Condition */ I2C_GenerateSTOP(sEE_I2C[TwiStruct->TwiNr], ENABLE); /* Call User callback for critical section end (should typically re-enable interrupts) */ sEE_ExitCriticalSection_UserCallback(); } /* Wait for the byte to be received */ sEETimeout = sEE_FLAG_TIMEOUT; while(I2C_GetFlagStatus(sEE_I2C[TwiStruct->TwiNr], I2C_FLAG_RXNE) == RESET) { if((sEETimeout--) == 0) { return false; } } /*!< Read the byte received from the EEPROM */ TwiStruct->RxBuff[cnt] = I2C_ReceiveData(sEE_I2C[TwiStruct->TwiNr]); } /* Wait to make sure that STOP control bit has been cleared */ sEETimeout = sEE_FLAG_TIMEOUT; while(sEE_I2C[TwiStruct->TwiNr]->CR1 & I2C_CR1_STOP) { if((sEETimeout--) == 0) { return false; } } /*!< Re-Enable Acknowledgement to be ready for another reception */ I2C_AcknowledgeConfig(sEE_I2C[TwiStruct->TwiNr], ENABLE); } } else { /* Call User callback for critical section start (should typically disable interrupts) */ sEE_EnterCriticalSection_UserCallback(); /* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */ (void)sEE_I2C[TwiStruct->TwiNr]->SR2; /*!< Send STOP Condition */ I2C_GenerateSTOP(sEE_I2C[TwiStruct->TwiNr], ENABLE); /* Call User callback for critical section end (should typically re-enable interrupts) */ sEE_ExitCriticalSection_UserCallback(); /* Wait for the byte to be received */ sEETimeout = sEE_FLAG_TIMEOUT; while(I2C_GetFlagStatus(sEE_I2C[TwiStruct->TwiNr], I2C_FLAG_RXNE) == RESET) { if((sEETimeout--) == 0) { return true; } } } /* If all operations OK, return sEE_OK (0) */ return true; }
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; } }
uint32_t HAL_I2C_Request_Data(HAL_I2C_Interface i2c, uint8_t address, uint8_t quantity, uint8_t stop, void* reserved) { uint32_t _millis; uint8_t bytesRead = 0; // clamp to buffer length if(quantity > BUFFER_LENGTH) { quantity = BUFFER_LENGTH; } /* Send START condition */ I2C_GenerateSTART(i2cMap[i2c]->I2C_Peripheral, ENABLE); _millis = HAL_Timer_Get_Milli_Seconds(); while(!I2C_CheckEvent(i2cMap[i2c]->I2C_Peripheral, I2C_EVENT_MASTER_MODE_SELECT)) { if(EVENT_TIMEOUT < (HAL_Timer_Get_Milli_Seconds() - _millis)) { /* SW Reset the I2C Peripheral */ HAL_I2C_SoftwareReset(i2c); return 0; } } /* Initialized variables here to minimize delays * between sending of slave addr and read loop */ uint8_t *pBuffer = i2cMap[i2c]->rxBuffer; uint8_t numByteToRead = quantity; /* Ensure ackFailure flag is cleared */ i2cMap[i2c]->ackFailure = false; /* Set ACK/NACK prior to I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED check * to minimize delays between sending of slave addr and read loop. * I2C_CheckEvent() will clear ADDR bit and allow SCL clocks to run, so we don't * have much time to check/set this correctly while I2C is in operation. */ if (quantity == 1) /* Disable Acknowledgement */ I2C_AcknowledgeConfig(i2cMap[i2c]->I2C_Peripheral, DISABLE); else I2C_AcknowledgeConfig(i2cMap[i2c]->I2C_Peripheral, ENABLE); /* Send Slave address for read */ I2C_Send7bitAddress(i2cMap[i2c]->I2C_Peripheral, address << 1, I2C_Direction_Receiver); _millis = HAL_Timer_Get_Milli_Seconds(); while(!I2C_CheckEvent(i2cMap[i2c]->I2C_Peripheral, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { /* STOP/RESET immediately if ACK failure detected */ if(EVENT_TIMEOUT < (HAL_Timer_Get_Milli_Seconds() - _millis) || i2cMap[i2c]->ackFailure) { /* Send STOP Condition */ I2C_GenerateSTOP(i2cMap[i2c]->I2C_Peripheral, ENABLE); /* Wait to make sure that STOP control bit has been cleared */ _millis = HAL_Timer_Get_Milli_Seconds(); while(i2cMap[i2c]->I2C_Peripheral->CR1 & I2C_CR1_STOP) { if(EVENT_TIMEOUT < (HAL_Timer_Get_Milli_Seconds() - _millis)) { break; } } /* SW Reset the I2C Peripheral */ HAL_I2C_SoftwareReset(i2c); /* Ensure ackFailure flag is cleared */ i2cMap[i2c]->ackFailure = false; return 0; } } /* DATA on SDA --> Shift Register (SR) [8 clocks by SCL] --> Data Register (DR) --> ACK/NACK (9th clock) * * SINGLE BYTE READ * - SCL will run immediately after ADDR bit is cleared by reading SR2 (any I2C_CheckEvent) * - DR will be empty * - 1st byte from slave will be transferred to DR after 8th SCL clock * - ACK/NACK will be sent immediately (SCL will run 9th clock) * * 2 BYTES LEFT TO READ * - DR is not yet empty (2nd last byte is in DR; it was ACKed on its xfer to DR) * - Last byte is being assembled in SR * - SCL will be stretched after 8th clock (SR full) until DR is empty * - Reading DR for 2nd last byte will then move last byte to DR and send ACK/NACK * * While there is data to be read, perform blocking read into buffer */ while(numByteToRead) { /* Wait for DR to be full. As soon as DR is full, the byte that was xfer'd from SR * to DR will be ACK/NACK'd. So it is important to enable/disable ACK bit ahead of this event */ _millis = HAL_Timer_Get_Milli_Seconds(); while(I2C_GetFlagStatus(i2cMap[i2c]->I2C_Peripheral, I2C_FLAG_RXNE) == RESET) { if(EVENT_TIMEOUT < (HAL_Timer_Get_Milli_Seconds() - _millis)) { /* SW Reset the I2C Peripheral */ HAL_I2C_SoftwareReset(i2c); return 0; } } switch (numByteToRead) { case 2: /* Disable Acknowledgement on last byte which is being assembled in SR, * 2nd last byte is in the DR and as soon as we read the 2nd last byte * below, last byte will be moved into DR and ACK/NACK will be sent. */ I2C_AcknowledgeConfig(i2cMap[i2c]->I2C_Peripheral, DISABLE); break; case 1: /* Send STOP Condition */ if (stop == true) I2C_GenerateSTOP(i2cMap[i2c]->I2C_Peripheral, ENABLE); break; default: break; } /* Read the byte out of the Data Register that was received from the Slave. * This will enable the transfer of the next byte (if any) from the Shift Register to * the Data Register and also will send ACK/NACK for that byte */ *pBuffer = I2C_ReceiveData(i2cMap[i2c]->I2C_Peripheral); bytesRead++; /* Point to the next location where the byte read will be saved */ pBuffer++; /* Decrement the read bytes counter */ numByteToRead--; /* Wait to make sure that STOP control bit has been cleared */ _millis = HAL_Timer_Get_Milli_Seconds(); while(i2cMap[i2c]->I2C_Peripheral->CR1 & I2C_CR1_STOP) { if(EVENT_TIMEOUT < (HAL_Timer_Get_Milli_Seconds() - _millis)) { /* SW Reset the I2C Peripheral */ HAL_I2C_SoftwareReset(i2c); return 0; } } } // set rx buffer iterator vars i2cMap[i2c]->rxBufferIndex = 0; i2cMap[i2c]->rxBufferLength = bytesRead; return bytesRead; }
int i2c1_read(uint8_t u8addr, uint8_t *u8data,uint8_t u8qty) { volatile uint32_t u32timeout; uint8_t recived = 0; /* While the bus is busy */ //u32timeout = I2C_WAIT_TIMEOUT; //while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY)&& --u32timeout); //if (!u32timeout) return 1; /* Send START condition */ I2C_GenerateSTART(I2C1, ENABLE); /* Test on EV5 and clear it */ u32timeout = I2C_WAIT_TIMEOUT; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)&& --u32timeout); if (!u32timeout) return fail; /* Send paj7620 address for write */ I2C_Send7bitAddress(I2C1, APDS9960_I2C_ADDR << 1, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ u32timeout = I2C_WAIT_TIMEOUT; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)&& --u32timeout); if (!u32timeout) return fail; /* Clear EV6 by setting again the PE bit */ I2C_Cmd(I2C1, ENABLE); /* Send the paj7620's internal address to write to */ I2C_SendData(I2C1, u8addr); /* Test on EV8 and clear it */ u32timeout = I2C_WAIT_TIMEOUT; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)&& --u32timeout); if (!u32timeout) return fail; /* Send STRAT condition a second time */ I2C_GenerateSTART(I2C1, ENABLE); /* Test on EV5 and clear it */ u32timeout = I2C_WAIT_TIMEOUT; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)&& --u32timeout); if (!u32timeout) return fail; /* Send paj7620 address for read */ I2C_Send7bitAddress(I2C1, APDS9960_I2C_ADDR << 1, I2C_Direction_Receiver); /* Test on EV6 and clear it */ u32timeout = I2C_WAIT_TIMEOUT; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)&& --u32timeout); if (!u32timeout) return fail; /* While there is data to be read */ while(u8qty) { if(u8qty == 1) { /* Disable Acknowledgement */ I2C_AcknowledgeConfig(I2C1, DISABLE); /* Send STOP Condition */ I2C_GenerateSTOP(I2C1, ENABLE); } /* Test on EV7 and clear it */ if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)) { /* Read a byte from the paj7620 */ //*u8data = I2C_ReceiveData(I2C1); u8data[recived] = I2C_ReceiveData(I2C1); /* Point to the next location where the byte read will be saved */ //u8data++; recived++; /* Decrement the read bytes counter */ u8qty--; } } /* Enable Acknowledgement to be ready for another reception */ I2C_AcknowledgeConfig(I2C1, ENABLE); return recived; }/* End of this function */
uint32_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t NumByteToRead) { /* While the bus is busy */ sEETimeout = sEE_LONG_TIMEOUT; while(I2C_GetFlagStatus( I2C_FLAG_BUSBUSY)) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /* Send START condition */ I2C_GenerateSTART(ENABLE); /* Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent( I2C_EVENT_MASTER_MODE_SELECT)) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /* Send EEPROM address for write */ I2C_Send7bitAddress( (uint8_t)sEEAddress, I2C_DIRECTION_TX); /* Test on EV6 and clear it */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent( I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } #ifdef sEE_M24C64_32 /* Send the EEPROM's internal address to read from: MSB of the address first */ I2C_SendData( (uint8_t)((ReadAddr & 0xFF00) >> 8)); /* Test on EV8 and clear it */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent( I2C_EVENT_MASTER_BYTE_TRANSMITTED)) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } #endif /* sEE_M24C64_32 */ /* Send the EEPROM's internal address to read from: LSB of the address */ I2C_SendData( (uint8_t)(ReadAddr & 0x00FF)); /* Test on EV8 and clear it */ sEETimeout = sEE_FLAG_TIMEOUT; while(I2C_GetFlagStatus(I2C_FLAG_TRANSFERFINISHED) == RESET) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /* Send START condition a second time */ I2C_GenerateSTART( ENABLE); /* Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent( I2C_EVENT_MASTER_MODE_SELECT)) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /* Send EEPROM address for read */ I2C_Send7bitAddress((uint8_t)sEEAddress, I2C_DIRECTION_RX); if ((uint16_t)(NumByteToRead)> 2) { sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_GetFlagStatus( I2C_FLAG_ADDRESSSENTMATCHED)) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } I2C->SR3; /* Read data from first byte until byte N-3 */ while ((uint16_t)(NumByteToRead)> 3) { /* Poll on BTF */ sEETimeout = sEE_FLAG_TIMEOUT; while (I2C_GetFlagStatus( I2C_FLAG_TRANSFERFINISHED) == RESET) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /* Read a byte from the EEPROM */ *pBuffer = I2C_ReceiveData(); /* Point to the next location where the byte read will be saved */ pBuffer++; /* Decrement the read bytes counter */ (uint16_t)(NumByteToRead)--; } //} /* Remains three data for read: data N-2, data N-1, Data N */ /* Three Bytes Master Reception procedure (POLLING) ------------------------*/ // if ((uint16_t)(*NumByteToRead) == 3) //{ /* Data N-2 in DR and data N -1 in shift register */ /* Poll on BTF */ sEETimeout = sEE_FLAG_TIMEOUT; while (I2C_GetFlagStatus( I2C_FLAG_TRANSFERFINISHED) == RESET) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /* Clear ACK */ I2C_AcknowledgeConfig(I2C_ACK_NONE); /* Call User callback for critical section start (should typically disable interrupts) */ sEE_EnterCriticalSection_UserCallback(); /* Read Data N-2 */ *pBuffer = I2C_ReceiveData(); /* Point to the next location where the byte read will be saved */ pBuffer++; /* Program the STOP */ I2C_GenerateSTOP(ENABLE); /* Read DataN-1 */ *pBuffer = I2C_ReceiveData(); /* Call User callback for critical section end (should typically re-enable interrupts) */ sEE_ExitCriticalSection_UserCallback(); /* Point to the next location where the byte read will be saved */ pBuffer++; /* Poll on RxNE */ sEETimeout = sEE_FLAG_TIMEOUT; while (I2C_GetFlagStatus( I2C_FLAG_RXNOTEMPTY) == RESET) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /* Read DataN */ *pBuffer = I2C_ReceiveData(); /* Reset the number of bytes to be read from the EEPROM */ NumByteToRead = 0; return sEE_OK; } /* If number of data to be read is 2 */ /* Tow Bytes Master Reception procedure (POLLING) ---------------------------*/ if ((uint16_t)(NumByteToRead) == 2) { /* Enable acknowledgement on next byte (set POS and ACK bits)*/ I2C_AcknowledgeConfig(I2C_ACK_NEXT); /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */ sEETimeout = sEE_FLAG_TIMEOUT; while(I2C_GetFlagStatus( I2C_FLAG_ADDRESSSENTMATCHED) == RESET) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /* Clear ADDR register by reading SR1 then SR3 register (SR1 has already been read) */ (void)I2C->SR3; /* Disable Acknowledgement */ I2C_AcknowledgeConfig(I2C_ACK_NONE); /* Wait for BTF flag to be set */ sEETimeout = sEE_FLAG_TIMEOUT; while (I2C_GetFlagStatus( I2C_FLAG_TRANSFERFINISHED) == RESET) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /* Call User callback for critical section start (should typically disable interrupts) */ sEE_EnterCriticalSection_UserCallback(); /* Program the STOP */ I2C_GenerateSTOP(ENABLE); /* Read Data N-1 */ *pBuffer = I2C_ReceiveData(); /* Point to the next location where the byte read will be saved */ pBuffer++; /* Call User callback for critical section end (should typically re-enable interrupts) */ sEE_ExitCriticalSection_UserCallback(); /* Read Data N */ *pBuffer = I2C_ReceiveData(); /* Reset the number of bytes to be read from the EEPROM */ NumByteToRead = 0; return sEE_OK; } /* If number of data to be read is 1 */ /* One Byte Master Reception procedure (POLLING) ---------------------------*/ if ((uint16_t)(NumByteToRead) < 2) { /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */ sEETimeout = sEE_FLAG_TIMEOUT; while(I2C_GetFlagStatus( I2C_FLAG_ADDRESSSENTMATCHED) == RESET) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /* Disable Acknowledgement */ I2C_AcknowledgeConfig(I2C_ACK_NONE); /* Call User callback for critical section start (should typically disable interrupts) */ sEE_EnterCriticalSection_UserCallback(); /* Clear ADDR register by reading SR1 then SR3 register (SR1 has already been read) */ (void)I2C->SR3; /* Send STOP Condition */ I2C_GenerateSTOP( ENABLE); /* Call User callback for critical section end (should typically re-enable interrupts) */ sEE_ExitCriticalSection_UserCallback(); /* Wait for the byte to be received */ sEETimeout = sEE_FLAG_TIMEOUT; while(I2C_GetFlagStatus( I2C_FLAG_RXNOTEMPTY) == RESET) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /* Read the byte received from the EEPROM */ *pBuffer = I2C_ReceiveData(); /* Decrement the read bytes counter */ (uint16_t)(NumByteToRead)--; /* Wait to make sure that STOP control bit has been cleared */ sEETimeout = sEE_FLAG_TIMEOUT; while(I2C->CR2 & I2C_CR2_STOP) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /* Re-Enable Acknowledgement to be ready for another reception */ I2C_AcknowledgeConfig( I2C_ACK_CURR); } /* If all operations OK, return sEE_OK (0) */ return sEE_OK; }
void i2c_ev_handler(void) { static uint8_t subaddress_sent, final_stop; //flag to indicate if subaddess sent, flag to indicate final bus condition static int8_t index; //index is signed -1==send the subaddress uint8_t SReg_1 = I2Cx->SR1; //read the status register here if (SReg_1 & 0x0001) { //we just sent a start - EV5 in ref manual I2Cx->CR1 &= ~0x0800; //reset the POS bit so ACK/NACK applied to the current byte I2C_AcknowledgeConfig(I2Cx, ENABLE); //make sure ACK is on index = 0; //reset the index if (reading && (subaddress_sent || 0xFF == reg)) { //we have sent the subaddr subaddress_sent = 1; //make sure this is set in case of no subaddress, so following code runs correctly if (bytes == 2) I2Cx->CR1 |= 0x0800; //set the POS bit so NACK applied to the final byte in the two byte read I2C_Send7bitAddress(I2Cx, addr, I2C_Direction_Receiver); //send the address and set hardware mode } else { //direction is Tx, or we havent sent the sub and rep start I2C_Send7bitAddress(I2Cx, addr, I2C_Direction_Transmitter); //send the address and set hardware mode if (reg != 0xFF) //0xFF as subaddress means it will be ignored, in Tx or Rx mode index = -1; //send a subaddress } } else if (SReg_1 & 0x0002) { //we just sent the address - EV6 in ref manual //Read SR1,2 to clear ADDR __DMB(); // memory fence to control hardware if (bytes == 1 && reading && subaddress_sent) { //we are receiving 1 byte - EV6_3 I2C_AcknowledgeConfig(I2Cx, DISABLE); //turn off ACK __DMB(); /* a = */ I2Cx->SR2; //clear ADDR after ACK is turned off I2C_GenerateSTOP(I2Cx, ENABLE); //program the stop final_stop = 1; I2C_ITConfig(I2Cx, I2C_IT_BUF, ENABLE); //allow us to have an EV7 } else { //EV6 and EV6_1 /*a = */I2Cx->SR2; //clear the ADDR here __DMB(); if (bytes == 2 && reading && subaddress_sent) { //rx 2 bytes - EV6_1 I2C_AcknowledgeConfig(I2Cx, DISABLE); //turn off ACK I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE); //disable TXE to allow the buffer to fill } else if (bytes == 3 && reading && subaddress_sent) //rx 3 bytes I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE); //make sure RXNE disabled so we get a BTF in two bytes time else //receiving greater than three bytes, sending subaddress, or transmitting I2C_ITConfig(I2Cx, I2C_IT_BUF, ENABLE); } } else if (SReg_1 & 0x004) { //Byte transfer finished - EV7_2, EV7_3 or EV8_2 final_stop = 1; if (reading && subaddress_sent) { //EV7_2, EV7_3 if (bytes > 2) { //EV7_2 I2C_AcknowledgeConfig(I2Cx, DISABLE); //turn off ACK read_p[index++] = I2C_ReceiveData(I2Cx); //read data N-2 I2C_GenerateSTOP(I2Cx, ENABLE); //program the Stop final_stop = 1; //reuired to fix hardware read_p[index++] = I2C_ReceiveData(I2Cx); //read data N-1 I2C_ITConfig(I2Cx, I2C_IT_BUF, ENABLE); //enable TXE to allow the final EV7 } else { //EV7_3 if (final_stop) I2C_GenerateSTOP(I2Cx, ENABLE); //program the Stop else I2C_GenerateSTART(I2Cx, ENABLE); //program a rep start read_p[index++] = I2C_ReceiveData(I2Cx); //read data N-1 read_p[index++] = I2C_ReceiveData(I2Cx); //read data N index++; //to show job completed } } else { //EV8_2, which may be due to a subaddress sent or a write completion if (subaddress_sent || (writing)) { if (final_stop) I2C_GenerateSTOP(I2Cx, ENABLE); //program the Stop else I2C_GenerateSTART(I2Cx, ENABLE); //program a rep start index++; //to show that the job is complete } else { //We need to send a subaddress I2C_GenerateSTART(I2Cx, ENABLE); //program the repeated Start subaddress_sent = 1; //this is set back to zero upon completion of the current task } } //we must wait for the start to clear, otherwise we get constant BTF while (I2Cx->CR1 & 0x0100) { ; } } else if (SReg_1 & 0x0040) { //Byte received - EV7 read_p[index++] = I2C_ReceiveData(I2Cx); if (bytes == (index + 3)) I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE); //disable TXE to allow the buffer to flush so we can get an EV7_2 if (bytes == index) //We have completed a final EV7 index++; //to show job is complete } else if (SReg_1 & 0x0080) { //Byte transmitted -EV8/EV8_1 if (index != -1) { //we dont have a subaddress to send I2C_SendData(I2Cx, write_p[index++]); if (bytes == index) //we have sent all the data I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE); //disable TXE to allow the buffer to flush } else { index++; I2C_SendData(I2Cx, reg); //send the subaddress if (reading || !bytes) //if receiving or sending 0 bytes, flush now I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE); //disable TXE to allow the buffer to flush } } if (index == bytes + 1) { //we have completed the current job //Completion Tasks go here //End of completion tasks subaddress_sent = 0; //reset this here // I2Cx->CR1 &= ~0x0800; //reset the POS bit so NACK applied to the current byte if (final_stop) //If there is a final stop and no more jobs, bus is inactive, disable interrupts to prevent BTF I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, DISABLE); //Disable EVT and ERR interrupts while bus inactive busy = 0; } }
int i2c_byte_read(i2c_t *obj, int last) { I2cHandle = (I2C_TypeDef *)(obj->i2c); return I2C_ReceiveData(I2cHandle, last); }
ErrorStatus receive_i2c(I2C_TypeDef * I2Cx, uint8_t * RxBuffer, uint8_t slave_address, uint8_t package_size) { static uint32_t Timeout; uint8_t TxCounter = 0; uint16_t i2c_error = 0; __disable_irq(); /* While the bus is busy */ Timeout = 0xFFF; /* While the bus is busy */ while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)) { if (Timeout-- == 0) { i2c_error_code = BUSY; i2c_error = 1; break; } } if(i2c_error == 0) { /* Send I2Cx START condition */ I2C_GenerateSTART(I2Cx, ENABLE); Timeout = 0xFFF; /* Test on I2Cx EV5 and clear it */ while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) { if (Timeout-- == 0) { i2c_error_code = NOT_MASTER; i2c_error = 1; break; } } } if(i2c_error == 0) { /* Send slave Address for write */ I2C_Send7bitAddress(I2Cx, slave_address, I2C_Direction_Receiver); Timeout = 0xFF; /* wait for acknowledge bit */ while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { if (Timeout-- == 0) { i2c_error_code = NO_ACKNOWLEDGEMENT; i2c_error = 1; break; } } } if(i2c_error == 0) { while(TxCounter!=package_size-1) { Timeout = 0xFFFF; while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED )) { if (Timeout-- == 0) { i2c_error_code = DATA_NOT_RECEIVED; i2c_error = 1; break; } } /* Receive some data */ RxBuffer[TxCounter++] = I2C_ReceiveData(I2Cx); } } I2C_AcknowledgeConfig(I2Cx, DISABLE); if(i2c_error == 0) { /* Send I2Cx STOP Condition */ I2C_GenerateSTOP(I2Cx, ENABLE); Timeout = 0xFFFF; while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED )) { if (Timeout-- == 0) { i2c_error_code = DATA_NOT_RECEIVED; i2c_error = 1; } } /* Receive some data */ RxBuffer[TxCounter++] = I2C_ReceiveData(I2Cx); } Timeout = 0xFF; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF)) { if (Timeout-- == 0) I2C_GenerateSTOP(I2Cx, ENABLE); i2c_error_code = STOP_NOT_SENT; i2c_error = 1; break; // really needed? } I2C_AcknowledgeConfig(I2Cx, ENABLE); __enable_irq(); if(i2c_error) { i2c_config(); return ERROR; } else { return SUCCESS; } }
/** * @brief Main program. * @param None * @retval None */ void main() { #ifdef FAST_I2C_MODE /* system_clock / 1 */ CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); #else /* system_clock / 2 */ CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV2); #endif /* Initialize LEDs mounted on STM8/128-EVAL board */ STM_EVAL_LEDInit(LED1); STM_EVAL_LEDInit(LED2); STM_EVAL_LEDInit(LED3); STM_EVAL_LEDInit(LED4); STM_EVAL_LEDOff(LED1); STM_EVAL_LEDOff(LED2); STM_EVAL_LEDOff(LED3); STM_EVAL_LEDOff(LED4); /* I2C Initialize */ I2C_Init(I2C_SPEED, 0xA0, I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT, 16); /* Enable Buffer and Event Interrupt*/ I2C_ITConfig((I2C_IT_TypeDef)(I2C_IT_EVT | I2C_IT_BUF) , ENABLE); enableInterrupts(); /* TXBuffer initializtion */ for (i = 0; i < BUFFERSIZE; i++) TxBuffer[i] = i; /* Send START condition */ I2C_GenerateSTART(ENABLE); while (NumOfBytes); while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY)); /* Add a delay to be sure that communication is finished */ Delay(0xFFFF); /***** reception phase ***/ /* Wait while the bus is busy */ while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY)); /* Send START condition */ I2C_GenerateSTART(ENABLE); /* Test on EV5 and clear it */ while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT)); #ifdef TEN_BITS_ADDRESS /* Send Header to Slave for write */ I2C_SendData(HEADER_ADDRESS_Write); /* Test on EV9 and clear it*/ while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_ADDRESS10)); /* Send slave Address */ I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_TX); /* Test on EV6 and clear it */ while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); /* Repeated Start */ I2C_GenerateSTART(ENABLE); /* Test on EV5 and clear it */ while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT)); /* Send Header to Slave for Read */ I2C_SendData(HEADER_ADDRESS_Read); /* Test on EV6 and clear it */ while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); #else /* Send slave Address for write */ I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_RX); /* Test on EV6 and clear it */ while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); #endif /* TEN_BITS_ADDRESS */ /* While there is data to be read */ while (NumByteToRead) { #ifdef SAFE_PROCEDURE if (NumByteToRead != 3) /* Receive bytes from first byte until byte N-3 */ { while ((I2C_GetFlagStatus(I2C_FLAG_TRANSFERFINISHED) == RESET)); /* Poll on BTF */ /* Read a byte from the Slave */ RxBuffer[Rx_Idx] = I2C_ReceiveData(); /* Point to the next location where the byte read will be saved */ Rx_Idx++; /* Decrement the read bytes counter */ NumByteToRead--; } if (NumByteToRead == 3) /* it remains to read three data: data N-2, data N-1, Data N */ { /* Data N-2 in DR and data N -1 in shift register */ while ((I2C_GetFlagStatus(I2C_FLAG_TRANSFERFINISHED) == RESET)); /* Poll on BTF */ /* Clear ACK */ I2C_AcknowledgeConfig(I2C_ACK_NONE); /* Disable general interrupts */ disableInterrupts(); /* Read Data N-2 */ RxBuffer[Rx_Idx] = I2C_ReceiveData(); /* Point to the next location where the byte read will be saved */ Rx_Idx++; /* Program the STOP */ I2C_GenerateSTOP(ENABLE); /* Read DataN-1 */ RxBuffer[Rx_Idx] = I2C_ReceiveData(); /* Enable General interrupts */ enableInterrupts(); /* Point to the next location where the byte read will be saved */ Rx_Idx++; while ((I2C_GetFlagStatus(I2C_FLAG_RXNOTEMPTY) == RESET)); /* Poll on RxNE */ /* Read DataN */ RxBuffer[Rx_Idx] = I2C_ReceiveData(); /* Reset the number of bytes to be read by master */ NumByteToRead = 0; } #else if (NumByteToRead == 1) { /* Disable Acknowledgement */ I2C_AcknowledgeConfig(I2C_ACK_NONE); /* Send STOP Condition */ I2C_GenerateSTOP(ENABLE); /* Poll on RxNE Flag */ while ((I2C_GetFlagStatus(I2C_FLAG_RXNOTEMPTY) == RESET)); /* Read a byte from the Slave */ RxBuffer[Rx_Idx] = I2C_ReceiveData(); /* Point to the next location where the byte read will be saved */ Rx_Idx++; /* Decrement the read bytes counter */ NumByteToRead--; } /* Test on EV7 and clear it */ if (I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED) ) { /* Read a byte from the EEPROM */ RxBuffer[Rx_Idx] = I2C_ReceiveData(); /* Point to the next location where the byte read will be saved */ Rx_Idx++; /* Decrement the read bytes counter */ NumByteToRead--; } #endif /* SAFE_PROCEDURE */ } /* check if sent and received data are not corrupted */ TransferStatus1 = Buffercmp((uint8_t*)TxBuffer, (uint8_t*) RxBuffer, BUFFERSIZE); if (TransferStatus1 != FAILED) { while (1) { /* Toggle LED1*/ STM_EVAL_LEDToggle(LED1); /* Insert delay */ Delay(0x7FFF); } } else { while (1) { /* Toggle LED4*/ STM_EVAL_LEDToggle(LED4); /* Insert delay */ Delay(0x7FFF); } } }
//-------------------------------------------------------------- // Auslesen einer Adresse per I2C von einem Slave // slave_adr => I2C-Basis-Adresse vom Slave // adr => Register Adresse die gelesen wird // // Return_wert : // 0...255 , Bytewert der gelesen wurde // < 0 , Error //-------------------------------------------------------------- int16_t UB_I2C3_ReadByte(uint8_t slave_adr, uint8_t adr) { int16_t ret_wert=0; uint32_t timeout=I2C3_TIMEOUT; // Start-Sequenz I2C_GenerateSTART(I2C3, ENABLE); timeout=I2C3_TIMEOUT; while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_SB)) { if(timeout!=0) timeout--; else return(P_I2C3_timeout(-1)); } // ACK disable I2C_AcknowledgeConfig(I2C3, DISABLE); // Slave-Adresse senden (write) I2C_Send7bitAddress(I2C3, slave_adr, I2C_Direction_Transmitter); timeout=I2C3_TIMEOUT; while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_ADDR)) { if(timeout!=0) timeout--; else return(P_I2C3_timeout(-2)); } // ADDR-Flag löschen I2C3->SR2; timeout=I2C3_TIMEOUT; while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_TXE)) { if(timeout!=0) timeout--; else return(P_I2C3_timeout(-3)); } // Adresse senden I2C_SendData(I2C3, adr); timeout=I2C3_TIMEOUT; while ((!I2C_GetFlagStatus(I2C3, I2C_FLAG_TXE)) || (!I2C_GetFlagStatus(I2C3, I2C_FLAG_BTF))) { if(timeout!=0) timeout--; else return(P_I2C3_timeout(-4)); } // Start-Sequenz I2C_GenerateSTART(I2C3, ENABLE); timeout=I2C3_TIMEOUT; while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_SB)) { if(timeout!=0) timeout--; else return(P_I2C3_timeout(-5)); } // Slave-Adresse senden (read) I2C_Send7bitAddress(I2C3, slave_adr, I2C_Direction_Receiver); timeout=I2C3_TIMEOUT; while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_ADDR)) { if(timeout!=0) timeout--; else return(P_I2C3_timeout(-6)); } // ADDR-Flag löschen I2C3->SR2; timeout=I2C3_TIMEOUT; while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_RXNE)) { if(timeout!=0) timeout--; else return(P_I2C3_timeout(-7)); } // Stop-Sequenz I2C_GenerateSTOP(I2C3, ENABLE); // Daten auslesen ret_wert=(int16_t)(I2C_ReceiveData(I2C3)); // ACK enable I2C_AcknowledgeConfig(I2C3, ENABLE); return(ret_wert); }
/** * @brief Read Temperature register of LM75: double temperature value. * @param None * @retval LM75 measured temperature value. */ uint16_t LM75_ReadTemp(void) { uint8_t LM75_BufferRX[2] ={0,0}; uint16_t tmp = 0; uint32_t DataNum = 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_TEMP); /* 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, 2, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); /* Reset local variable */ DataNum = 0; /* Wait until all data are received */ while (DataNum != 2) { /* 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[DataNum]= I2C_ReceiveData(LM75_I2C); /* Update number of received data */ DataNum++; } /* 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); /* Store LM75_I2C received data */ tmp = (uint16_t)(LM75_BufferRX[0] << 8); tmp |= LM75_BufferRX[1]; /* Return Temperature value */ return (uint16_t)(tmp >> 7); }
//-------------------------------------------------------------- // Auslesen mehrerer Adresse per I2C von einem Slave // slave_adr => I2C-Basis-Adresse vom Slave // adr => Start Register Adresse ab der gelesen wird // cnt => Anzahl der Bytewert die gelesen werden sollen // Daten die gelesen worden sind, stehen danach in "I2C3_DATA" // // Return_wert : // 0 , Ok // < 0 , Error //-------------------------------------------------------------- int16_t UB_I2C3_ReadMultiByte(uint8_t slave_adr, uint8_t adr, uint8_t cnt, uint8_t fixed) { int16_t ret_wert=0; uint32_t timeout=I2C3_TIMEOUT; uint8_t wert,n; if(cnt==0) return(-8); if(cnt>I2C3_MULTIBYTE_ANZ) return(-9); // Start-Sequenz I2C_GenerateSTART(I2C3, ENABLE); timeout=I2C3_TIMEOUT; while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_SB)) { if(timeout!=0) timeout--; else return(P_I2C3_timeout(-1)); } if(cnt==1) { // ACK disable I2C_AcknowledgeConfig(I2C3, DISABLE); } else { // ACK enable I2C_AcknowledgeConfig(I2C3, ENABLE); } // Slave-Adresse senden (write) I2C_Send7bitAddress(I2C3, slave_adr, I2C_Direction_Transmitter); timeout=I2C3_TIMEOUT; while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_ADDR)) { if(timeout!=0) timeout--; else return(P_I2C3_timeout(-2)); } // ADDR-Flag löschen I2C3->SR2; timeout=I2C3_TIMEOUT; while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_TXE)) { if(timeout!=0) timeout--; else return(P_I2C3_timeout(-3)); } if(fixed == 0){ // Adresse senden I2C_SendData(I2C3, adr); timeout=I2C3_TIMEOUT; while ((!I2C_GetFlagStatus(I2C3, I2C_FLAG_TXE)) || (!I2C_GetFlagStatus(I2C3, I2C_FLAG_BTF))) { if(timeout!=0) timeout--; else return(P_I2C3_timeout(-4)); } } // Start-Sequenz I2C_GenerateSTART(I2C3, ENABLE); timeout=I2C3_TIMEOUT; while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_SB)) { if(timeout!=0) timeout--; else return(P_I2C3_timeout(-5)); } // Slave-Adresse senden (read) I2C_Send7bitAddress(I2C3, slave_adr, I2C_Direction_Receiver); timeout=I2C3_TIMEOUT; while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_ADDR)) { if(timeout!=0) timeout--; else return(P_I2C3_timeout(-6)); } // ADDR-Flag löschen I2C3->SR2; // alle Daten auslesen for(n=0;n<cnt;n++) { if((n+1)>=cnt) { // ACK disable I2C_AcknowledgeConfig(I2C3, DISABLE); // Stop-Sequenz I2C_GenerateSTOP(I2C3, ENABLE); } timeout=I2C3_TIMEOUT; while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_RXNE)) { if(timeout!=0) timeout--; else return(P_I2C3_timeout(-7)); } // Daten auslesen wert=I2C_ReceiveData(I2C3); // Daten in Array speichern I2C3_DATA[n]=wert; } // ACK enable I2C_AcknowledgeConfig(I2C3, ENABLE); ret_wert=0; // alles ok return(ret_wert); }
void MACEEP_Read(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t NumByteToRead) { /* While the bus is busy */ while(I2C_GetFlagStatus(MACEPP_I2C, I2C_FLAG_BUSY)); /* Send START condition */ I2C_GenerateSTART(MACEPP_I2C, ENABLE); /* Test on EV5 and clear it */ while(!I2C_CheckEvent(MACEPP_I2C, I2C_EVENT_MASTER_MODE_SELECT)); /* Send EEPROM address for write */ I2C_Send7bitAddress(MACEPP_I2C, MACEEP_Address, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ while(!I2C_CheckEvent(MACEPP_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); /* Send the EEPROM's internal address to read from: LSB of the address */ I2C_SendData(MACEPP_I2C, (uint8_t)(ReadAddr & 0x00FF)); /* Test on EV8 and clear it */ while(!I2C_CheckEvent(MACEPP_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); /* Send STRAT condition a second time */ I2C_GenerateSTART(MACEPP_I2C, ENABLE); /* Test on EV5 and clear it */ while(!I2C_CheckEvent(MACEPP_I2C, I2C_EVENT_MASTER_MODE_SELECT)); /* Send EEPROM address for read */ I2C_Send7bitAddress(MACEPP_I2C, MACEEP_Address, I2C_Direction_Receiver); /* Test on EV6 and clear it */ while(!I2C_CheckEvent(MACEPP_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); /* While there is data to be read */ while(NumByteToRead) { if(NumByteToRead == 1) { /* Disable Acknowledgement */ I2C_AcknowledgeConfig(MACEPP_I2C, DISABLE); /* Send STOP Condition */ I2C_GenerateSTOP(MACEPP_I2C, ENABLE); } /* Test on EV7 and clear it */ if(I2C_CheckEvent(MACEPP_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED)) { /* Read a byte from the EEPROM */ *pBuffer = I2C_ReceiveData(MACEPP_I2C); /* Point to the next location where the byte read will be saved */ pBuffer++; /* Decrement the read bytes counter */ NumByteToRead--; } } /* Enable Acknowledgement to be ready for another reception */ I2C_AcknowledgeConfig(MACEPP_I2C, ENABLE); }
/** * @brief Main program. * @param None * @retval None */ int main(void) { int i; RCC_Configuration(); GPIO_Configuration(); I2C_Configuration(); i=0; /* Enable I2C2 */ I2C_Enable(BOARD_I2C,ENABLE); /* Enable Acknowledge */ I2C_Acknowledge_Enable(BOARD_I2C,ENABLE); /* Send a NACK for the next data byte which will be received into the shift register */ I2C_NACKPosition_Enable(BOARD_I2C,I2C_NACKPOSITION_NEXT); /* Wait until I2C Bus is idle */ while(I2C_GetBitState(BOARD_I2C, I2C_FLAG_I2CBSY)); /* Send a start condition to I2C bus */ I2C_StartOnBus_Enable(BOARD_I2C, ENABLE); /* Wait until SBSEND bit is set */ while(!I2C_StateDetect(BOARD_I2C, I2C_PROGRAMMINGMODE_MASTER_SBSEND)); /* Send slave address to I2C bus */ I2C_AddressingDevice_7bit(BOARD_I2C, SLAVE_ADDRESS7, I2C_DIRECTION_RECEIVER); /* Disable ACK before clearing ADDSEND bit */ I2C_Acknowledge_Enable(BOARD_I2C, DISABLE); /* Wait until ADDSEND bit is set and clear it */ while(!I2C_StateDetect(BOARD_I2C, I2C_PROGRAMMINGMODE_MASTER_RECEIVER_ADDSEND)); /* Wait until the last data byte is received into the shift register */ while(!I2C_GetBitState(BOARD_I2C, I2C_FLAG_BTC)); /* Send a stop condition */ I2C_StopOnBus_Enable(BOARD_I2C, ENABLE); /* Wait until the reception data register is not empty */ while(!I2C_GetBitState(BOARD_I2C, I2C_FLAG_RBNE)); /* Read a data from I2C_DTR */ BOARD_I2C_Buf_Read[i++]=I2C_ReceiveData(BOARD_I2C); /* Wait until the reception data register is not empty */ while(!I2C_GetBitState(BOARD_I2C, I2C_FLAG_RBNE)); /* Read a data from I2C_DTR */ BOARD_I2C_Buf_Read[i++]=I2C_ReceiveData(BOARD_I2C); while(BOARD_I2C->CTLR1&0x0200); I2C_NACKPosition_Enable(BOARD_I2C,I2C_NACKPOSITION_CURRENT); /* Enable Acknowledge */ I2C_Acknowledge_Enable(BOARD_I2C, ENABLE); while(1); }
bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t len, uint8_t* buf) { addr_ <<= 1; I2C_TypeDef *I2Cx; I2Cx = i2cHardwareMap[device].dev; /* Test on BUSY Flag */ i2cTimeout = I2C_LONG_TIMEOUT; while (I2C_GetFlagStatus(I2Cx, I2C_ISR_BUSY) != RESET) { if ((i2cTimeout--) == 0) { return i2cTimeoutUserCallback(); } } /* Configure slave address, nbytes, reload, end mode and start or stop generation */ I2C_TransferHandling(I2Cx, addr_, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); /* Wait until TXIS flag is set */ i2cTimeout = I2C_LONG_TIMEOUT; while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) { if ((i2cTimeout--) == 0) { return i2cTimeoutUserCallback(); } } /* Send Register address */ I2C_SendData(I2Cx, (uint8_t) reg); /* Wait until TC flag is set */ i2cTimeout = I2C_LONG_TIMEOUT; while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TC) == RESET) { if ((i2cTimeout--) == 0) { return i2cTimeoutUserCallback(); } } /* Configure slave address, nbytes, reload, end mode and start or stop generation */ I2C_TransferHandling(I2Cx, addr_, len, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); /* Wait until all data are received */ while (len) { /* Wait until RXNE flag is set */ i2cTimeout = I2C_LONG_TIMEOUT; while (I2C_GetFlagStatus(I2Cx, I2C_ISR_RXNE) == RESET) { if ((i2cTimeout--) == 0) { return i2cTimeoutUserCallback(); } } /* Read data from RXDR */ *buf = I2C_ReceiveData(I2Cx); /* Point to the next location where the byte read will be saved */ buf++; /* Decrement the read bytes counter */ len--; } /* Wait until STOPF flag is set */ i2cTimeout = I2C_LONG_TIMEOUT; while (I2C_GetFlagStatus(I2Cx, I2C_ISR_STOPF) == RESET) { if ((i2cTimeout--) == 0) { return i2cTimeoutUserCallback(); } } /* Clear STOPF flag */ I2C_ClearFlag(I2Cx, I2C_ICR_STOPCF); /* If all operations OK */ return true; }
// Set the address pointer and read a word from the INA219 uint8_t INA219_ReadWord(INA219* sensor, uint8_t regAddr, uint16_t* data) { // Save some typing I2C_TypeDef* periph = sensor->peripheral; uint32_t address = sensor->address << 1; uint32_t timeout = INA219_TIMEOUT; // Set the desired address if(INA219_SetAddressPointer(sensor, regAddr) != INA219_SUCCESS) return INA219_FAILURE; // Make sure the bus isn't busy so that we don't screw up a transaction if(INA219_FlagTimeout(periph, I2C_FLAG_BUSY, timeout, SET)) return INA219_I2C_BUSY; // Generate a START condition I2C_GenerateSTART(periph, ENABLE); // Ensure that we've taken control of the bus (EV5) if(INA219_EventTimeout(periph, I2C_EVENT_MASTER_MODE_SELECT, timeout, ERROR)) return INA219_I2C_TIMEOUTERROR; // Send the slave address with the R/nW flag high (read) I2C_Send7bitAddress(periph, address, I2C_Direction_Receiver); // Enable acknowledge for the second byte I2C_AcknowledgeConfig(periph, ENABLE); // Wait for the address flag to be set if(INA219_FlagTimeout(periph, I2C_FLAG_ADDR, timeout, RESET)) return INA219_I2C_TIMEOUTERROR; // Clear the ADDR flag in order to continue with reception periph->SR2; // Wait to receive a byte if(INA219_FlagTimeout(periph, I2C_FLAG_RXNE, timeout, RESET)) return INA219_I2C_TIMEOUTERROR; // Read the most-significant byte of the word uint16_t msb = I2C_ReceiveData(periph); // Disable acknowledge for the second byte I2C_AcknowledgeConfig(periph, DISABLE); // Wait to receive a second byte if(INA219_FlagTimeout(periph, I2C_FLAG_RXNE, timeout, RESET)) return INA219_I2C_TIMEOUTERROR; // Read the least-significant byte of the word uint16_t lsb = I2C_ReceiveData(periph); /*!< Send STOP Condition */ I2C_GenerateSTOP(periph, ENABLE); // Write the results to the given address *data = ((msb << 8) & 0xFF00) | (lsb & 0x00FF); // We made it! return INA219_SUCCESS; }
/** * @brief Reads a byte from a specific Camera register * @param Addr: OV9655 register address. * @retval data read from the specific register or 0xFF if timeout condition * occured. */ uint8_t OV9655_ReadReg(uint16_t Addr) { uint32_t timeout = DCMI_TIMEOUT_MAX; uint8_t Data = 0; /* Generate the Start Condition */ I2C_GenerateSTART(I2C1, ENABLE); /* Test on I2C1 EV5 and clear it */ timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) { /* If the timeout delay is exeeded, exit with error code */ if ((timeout--) == 0) return 0xFF; } /* Send DCMI selcted device slave Address for write */ I2C_Send7bitAddress(I2C1, OV9655_DEVICE_READ_ADDRESS, I2C_Direction_Transmitter); /* Test on I2C1 EV6 and clear it */ timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { /* If the timeout delay is exeeded, exit with error code */ if ((timeout--) == 0) return 0xFF; } /* Send I2C1 location address LSB */ I2C_SendData(I2C1, (uint8_t)(Addr)); /* Test on I2C1 EV8 and clear it */ timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) { /* If the timeout delay is exeeded, exit with error code */ if ((timeout--) == 0) return 0xFF; } /* Clear AF flag if arised */ I2C1->SR1 |= (uint16_t)0x0400; /* Generate the Start Condition */ I2C_GenerateSTART(I2C1, ENABLE); /* Test on I2C1 EV6 and clear it */ timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) { /* If the timeout delay is exeeded, exit with error code */ if ((timeout--) == 0) return 0xFF; } /* Send DCMI selcted device slave Address for write */ I2C_Send7bitAddress(I2C1, OV9655_DEVICE_READ_ADDRESS, I2C_Direction_Receiver); /* Test on I2C1 EV6 and clear it */ timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { /* If the timeout delay is exeeded, exit with error code */ if ((timeout--) == 0) return 0xFF; } /* Prepare an NACK for the next data received */ I2C_AcknowledgeConfig(I2C1, DISABLE); /* Test on I2C1 EV7 and clear it */ timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)) { /* If the timeout delay is exeeded, exit with error code */ if ((timeout--) == 0) return 0xFF; } /* Prepare Stop after receiving data */ I2C_GenerateSTOP(I2C1, ENABLE); /* Receive the Data */ Data = I2C_ReceiveData(I2C1); /* return the read data */ return Data; }
/* This function reads one byte from the slave device * and doesn't acknowledge the recieved data */ uint8_t I2C_slave_read_nack(I2C_TypeDef* I2Cx){ /* Test on I2C2 EV2 and clear it */ while(!I2C_CheckEvent(I2Cx, I2C_EVENT_SLAVE_BYTE_RECEIVED)); uint8_t data = I2C_ReceiveData(I2Cx); return data; }
/** * @brief Reads a block of data from the EEPROM. * @param pBuffer : pointer to the buffer that receives the data read from * the EEPROM. * @param ReadAddr : EEPROM's internal address to start reading from. * @param NumByteToRead : pointer to the variable holding number of bytes to * be read from the EEPROM. * * @note The variable pointed by NumByteToRead is reset to 0 when all the * data are read from the EEPROM. Application should monitor this * variable in order know when the transfer is complete. * * @note When number of data to be read is higher than 1, this function just * configures the communication and enable the DMA channel to transfer data. * Meanwhile, the user application may perform other tasks. * When number of data to be read is 1, then the DMA is not used. The byte * is read in polling mode. * * @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_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead) { /* Set the pointer to the Number of data to be read. This pointer will be used by the DMA Transfer Completer interrupt Handler in order to reset the variable to 0. User should check on this variable in order to know if the DMA transfer has been complete or not. */ sEEDataReadPointer = NumByteToRead; /*!< While the bus is busy */ sEETimeout = sEE_LONG_TIMEOUT; while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BUSY)) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /*!< Send START condition */ I2C_GenerateSTART(sEE_I2C, ENABLE); /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT)) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /*!< Send EEPROM address for write */ I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Transmitter); /*!< Test on EV6 and clear it */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /*!< Send the EEPROM's internal address to read from: MSB of the address first */ I2C_SendData(sEE_I2C, (uint8_t)((ReadAddr & 0xFF00) >> 8)); /*!< Test on EV8 and clear it */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTING)) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /*!< Send the EEPROM's internal address to read from: LSB of the address */ I2C_SendData(sEE_I2C, (uint8_t)(ReadAddr & 0x00FF)); /*!< Test on EV8 and clear it */ sEETimeout = sEE_FLAG_TIMEOUT; while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BTF) == RESET) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /*!< Send STRAT condition a second time */ I2C_GenerateSTART(sEE_I2C, ENABLE); /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT)) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /*!< Send EEPROM address for read */ I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Receiver); /* If number of data to be read is 1, then DMA couldn't be used */ /* One Byte Master Reception procedure (POLLING) ---------------------------*/ if ((uint16_t)(*NumByteToRead) < 2) { /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */ sEETimeout = sEE_FLAG_TIMEOUT; while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_ADDR) == RESET) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /*!< Disable Acknowledgement */ I2C_AcknowledgeConfig(sEE_I2C, DISABLE); /* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */ (void)sEE_I2C->SR2; /*!< Send STOP Condition */ I2C_GenerateSTOP(sEE_I2C, ENABLE); /* Wait for the byte to be received */ sEETimeout = sEE_FLAG_TIMEOUT; while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_RXNE) == RESET) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /*!< Read the byte received from the EEPROM */ *pBuffer = I2C_ReceiveData(sEE_I2C); /*!< Decrement the read bytes counter */ (uint16_t)(*NumByteToRead)--; /* Wait to make sure that STOP control bit has been cleared */ sEETimeout = sEE_FLAG_TIMEOUT; while(sEE_I2C->CR1 & I2C_CR1_STOP) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /*!< Re-Enable Acknowledgement to be ready for another reception */ I2C_AcknowledgeConfig(sEE_I2C, ENABLE); } else/* More than one Byte Master Reception procedure (DMA) -----------------*/ { /*!< Test on EV6 and clear it */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); } /* Configure the DMA Rx Channel with the buffer address and the buffer size */ sEE_LowLevel_DMAConfig((uint32_t)pBuffer, (uint16_t)(*NumByteToRead), sEE_DIRECTION_RX); /* Inform the DMA that the next End Of Transfer Signal will be the last one */ I2C_DMALastTransferCmd(sEE_I2C, ENABLE); /* Enable the DMA Rx Stream */ DMA_Cmd(sEE_I2C_DMA_STREAM_RX, ENABLE); } /* If all operations OK, return sEE_OK (0) */ return sEE_OK; }
/** * @brief Reads and returns te value of an audio codec register through the * control interface (I2C). * @param RegisterAddr: Address of the register to be read. * @retval Value of the register to be read or dummy value if the communication * fails. */ static uint32_t Codec_ReadRegister(uint32_t RegisterAddr) { uint32_t result = 0; /*!< While the bus is busy */ CODECTimeout = CODEC_LONG_TIMEOUT; while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_BUSY)) { if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); } /* Start the config sequence */ I2C_GenerateSTART(CODEC_I2C, ENABLE); /* Test on EV5 and clear it */ CODECTimeout = CODEC_FLAG_TIMEOUT; while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_MODE_SELECT)) { if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); } /* Transmit the slave address and enable writing operation */ I2C_Send7bitAddress(CODEC_I2C, CODEC_ADDRESS, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ CODECTimeout = CODEC_FLAG_TIMEOUT; while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); } /* Transmit the register address to be read */ I2C_SendData(CODEC_I2C, RegisterAddr); /* Test on EV8 and clear it */ CODECTimeout = CODEC_FLAG_TIMEOUT; while (I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_BTF) == RESET) { if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); } /*!< Send STRAT condition a second time */ I2C_GenerateSTART(CODEC_I2C, ENABLE); /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */ CODECTimeout = CODEC_FLAG_TIMEOUT; while(!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_MODE_SELECT)) { if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); } /*!< Send Codec address for read */ I2C_Send7bitAddress(CODEC_I2C, CODEC_ADDRESS, I2C_Direction_Receiver); /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */ CODECTimeout = CODEC_FLAG_TIMEOUT; while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_ADDR) == RESET) { if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); } /*!< Disable Acknowledgement */ I2C_AcknowledgeConfig(CODEC_I2C, DISABLE); /* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */ (void)CODEC_I2C->SR2; /*!< Send STOP Condition */ I2C_GenerateSTOP(CODEC_I2C, ENABLE); /* Wait for the byte to be received */ CODECTimeout = CODEC_FLAG_TIMEOUT; while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_RXNE) == RESET) { if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); } /*!< Read the byte received from the Codec */ result = I2C_ReceiveData(CODEC_I2C); /* Wait to make sure that STOP flag has been cleared */ CODECTimeout = CODEC_FLAG_TIMEOUT; while(CODEC_I2C->CR1 & I2C_CR1_STOP) { if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); } /*!< Re-Enable Acknowledgement to be ready for another reception */ I2C_AcknowledgeConfig(CODEC_I2C, ENABLE); /* Clear AF flag for next communication */ I2C_ClearFlag(CODEC_I2C, I2C_FLAG_AF); /* Return the byte read from Codec */ return result; }