/** * @brief IOE_TIMEOUT_UserCallback * @param None * @retval 0 */ uint8_t IOE_TimeoutUserCallback(void) { I2C_InitTypeDef I2C_InitStructure; I2C_GenerateSTOP(IOE_I2C, ENABLE); I2C_SoftwareResetCmd(IOE_I2C, ENABLE); I2C_SoftwareResetCmd(IOE_I2C, DISABLE); IOE_GPIO_Config(); /* CODEC_I2C peripheral configuration */ I2C_DeInit(IOE_I2C); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = 0x00; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED; /* Enable the I2C peripheral */ I2C_Cmd(IOE_I2C, ENABLE); I2C_Init(IOE_I2C, &I2C_InitStructure); return 0; }
void BSP_I2C_LEDS(INT8U reg) { /* Disable the I2C peripheral */ I2C_Cmd(I2C_PORT, DISABLE); /* Reset all I2C2 registers */ I2C_SoftwareResetCmd(I2C_PORT, ENABLE); I2C_SoftwareResetCmd(I2C_PORT, DISABLE); /* Configure the I2C peripheral */ I2C_Local_Config(); /* Enable the I2C peripheral --- err*/ //I2C_GenerateSTART(I2C1, ENABLE); /* Send the LEDs value */ I2C_GenerateSTART(I2C_PORT, ENABLE); while (!I2C_CheckEvent(I2C_PORT, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C_PORT, I2C_ADDRESS, I2C_Direction_Transmitter); while (!I2C_CheckEvent(I2C_PORT, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C_PORT, I2C_OUTPUT_P0); while (!I2C_CheckEvent(I2C_PORT, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_SendData(I2C_PORT, reg); while (!I2C_CheckEvent(I2C_PORT, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTOP(I2C_PORT, ENABLE); }
void vhI2C_initI2C1(void) { I2C_InitTypeDef I2C_InitStruct; /* I2C1 * setup SCL and SDA pins * SCL = PB8 * SDA = PB9 */ /* Deinit and reset the I2C to avoid it locking up */ I2C_DeInit(I2C1 ); I2C_SoftwareResetCmd(I2C1, ENABLE); I2C_SoftwareResetCmd(I2C1, DISABLE); I2C_InitStruct.I2C_ClockSpeed = I2C1_clockSpeed; // I2C1_clockSpeed [Hz] I2C_InitStruct.I2C_Mode = I2C_Mode_I2C; // I2C mode I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; // 50% duty cycle --> standard I2C_InitStruct.I2C_OwnAddress1 = I2C1_ownAddress; // own address, not relevant in master mode I2C_InitStruct.I2C_Ack = I2C_Ack_Disable; I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // set address length to 7 bit addresses I2C_Init(I2C1, &I2C_InitStruct); // init I2C1 I2C_Cmd(I2C1, ENABLE); }
/** * @brief Codec_TIMEOUT_UserCallback * @param None * @retval None */ uint32_t Codec_TIMEOUT_UserCallback(void) { #if 0 I2C_InitTypeDef I2C_InitStructure; LCD_ErrLog("> I2C Timeout error (CS43L22)\n"); I2C_GenerateSTOP(I2C1, ENABLE); I2C_SoftwareResetCmd(I2C1, ENABLE); I2C_SoftwareResetCmd(I2C1, DISABLE); I2C_DeInit(I2C1); /* CODEC_I2C peripheral configuration */ I2C_DeInit(I2C1); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = 0x33; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED; /* Enable the I2C peripheral */ I2C_Cmd(I2C1, ENABLE); I2C_Init(I2C1, &I2C_InitStructure); LCD_UsrLog("> I2C error recovered.\n"); #endif return 0; }
static void HAL_I2C_SoftwareReset(HAL_I2C_Interface i2c) { /* Disable the I2C peripheral */ I2C_Cmd(i2cMap[i2c]->I2C_Peripheral, DISABLE); /* Reset all I2C registers */ I2C_SoftwareResetCmd(i2cMap[i2c]->I2C_Peripheral, ENABLE); I2C_SoftwareResetCmd(i2cMap[i2c]->I2C_Peripheral, DISABLE); /* Clear all I2C interrupt error flags, and re-enable them */ I2C_ClearITPendingBit(i2cMap[i2c]->I2C_Peripheral, I2C_IT_SMBALERT | I2C_IT_PECERR | I2C_IT_TIMEOUT | I2C_IT_ARLO | I2C_IT_OVR | I2C_IT_BERR | I2C_IT_AF); I2C_ITConfig(i2cMap[i2c]->I2C_Peripheral, I2C_IT_ERR, ENABLE); /* Re-enable Event and Buffer interrupts in Slave mode */ if(i2cMap[i2c]->mode == I2C_MODE_SLAVE) { I2C_ITConfig(i2cMap[i2c]->I2C_Peripheral, I2C_IT_EVT | I2C_IT_BUF, ENABLE); } /* Enable the I2C peripheral */ I2C_Cmd(i2cMap[i2c]->I2C_Peripheral, ENABLE); /* Apply I2C configuration after enabling it */ I2C_Init(i2cMap[i2c]->I2C_Peripheral, &i2cMap[i2c]->I2C_InitStructure); }
/**************************************************************************************************** * @fn I2C_HardwareSetup * Configures the GPIOs and h/w interface for the I2C bus * * @param busId - I2C bus identifier in case multiple buses are supported * * @return true if successful, false otherwise. * ***************************************************************************************************/ osp_bool_t I2C_HardwareSetup( I2C_TypeDef *busId ) { GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; if (busId == I2C_SENSOR_BUS) { if (sI2C_Bus1Initialized) { return true; } /* Reset the peripheral (this allows soft restarts to recover the bus in case of hangups) */ I2C_DeInit(busId); /* Enable Clocks to the peripheral and GPIOs used */ RCC_APB1PeriphClockCmd(RCC_Periph_I2C_SENSOR_BUS, ENABLE); RCC_APB2PeriphClockCmd(RCC_Periph_I2C_SENSOR_BUS_GPIO, ENABLE ); //for I2C port GPIO /* NVIC/Interrupt config */ /* Configure and enable I2C event interrupt -------------------------------*/ NVIC_InitStructure.NVIC_IRQChannel = I2C_SENSOR_BUS_EVENT_IRQ_CH; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = I2C_SENSOR_BUS_INT_PREEMPT_PRIORITY; NVIC_InitStructure.NVIC_IRQChannelSubPriority = I2C_SENSOR_BUS_EVENT_INT_SUB_PRIORITY; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Configure and enable I2C error interrupt -------------------------------*/ NVIC_InitStructure.NVIC_IRQChannel = I2C_SENSOR_BUS_ERROR_IRQ_CH; NVIC_InitStructure.NVIC_IRQChannelSubPriority = I2C_SENSOR_BUS_ERROR_INT_SUB_PRIORITY; NVIC_Init(&NVIC_InitStructure); /* GPIO Configuration for CLK and SDA signals */ GPIO_InitStructure.GPIO_Pin = I2C_SENSOR_BUS_CLK_PIN | I2C_SENSOR_BUS_SDA_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init( I2C_SENSOR_BUS_GPIO_GRP, &GPIO_InitStructure ); //Init the I2C driver interface I2C_Master_Initialise(); /* Do a software reset after enabling master I2C clock - this takes care of BUSY condition */ I2C_SoftwareResetCmd( I2C_SENSOR_BUS, ENABLE ); I2C_SoftwareResetCmd( I2C_SENSOR_BUS, DISABLE ); /* Now we need to do Master init again */ I2C_Master_Initialise(); sI2C_Bus1Initialized = true; return true; } return false; }
INT8U BSP_I2C_JOY(void) { INT8U buffer = 0xFF; /* Disable the I2C peripheral */ I2C_Cmd(I2C_PORT, DISABLE); /* Reset all I2C2 registers */ I2C_SoftwareResetCmd(I2C_PORT, ENABLE); I2C_SoftwareResetCmd(I2C_PORT, DISABLE); /* Configure the I2C peripheral */ I2C_Local_Config(); /* Read the joystick values */ /* First phase => Preparing the reading : mode write*/ I2C_GenerateSTART(I2C_PORT, ENABLE); while (!I2C_CheckEvent(I2C_PORT, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C_PORT, I2C_ADDRESS, I2C_Direction_Transmitter); while (!I2C_CheckEvent(I2C_PORT, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); /* Clear EV6 by setting again the PE bit */ // ??? I2C_Cmd(I2C_PORT, ENABLE); I2C_SendData(I2C_PORT, I2C_INPUT_P1); // Input port 1 while (!I2C_CheckEvent(I2C_PORT, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); /* Second phase => reading, stop when not ack by the master */ I2C_GenerateSTART(I2C_PORT, ENABLE); while (!I2C_CheckEvent(I2C_PORT, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C_PORT, I2C_ADDRESS, I2C_Direction_Receiver); // Disabling the ACK from the STM32 to the I2C // This way the I2C stop sending the registers after the first one I2C_AcknowledgeConfig(I2C_PORT, DISABLE); while (!I2C_CheckEvent(I2C_PORT, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); // Waiting for the first register value while (!I2C_CheckEvent(I2C_PORT, I2C_EVENT_MASTER_BYTE_RECEIVED)); // Reading the register value buffer = I2C_ReceiveData(I2C_PORT); // Should be stopped by not ack the "packet", but this way we are sure I2C_GenerateSTOP(I2C_PORT, ENABLE); // We put back the ACK from the STM32 I2C_AcknowledgeConfig(I2C_PORT, ENABLE); return buffer; }
void init_i2c(void) { I2C_InitTypeDef I2C_InitStruct; GPIO_InitTypeDef GPIO_InitStruct; RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; // SCL,SDA GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_Init(GPIOB, &GPIO_InitStruct); I2C_SoftwareResetCmd(I2C2, ENABLE); I2C_ITConfig(I2C2,I2C_IT_ERR,ENABLE); I2C_StructInit(&I2C_InitStruct); I2C_DeInit(I2C2); I2C_InitStruct.I2C_ClockSpeed = 100000; I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStruct.I2C_Mode = I2C_Mode_I2C; I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStruct.I2C_OwnAddress1 = 0x00; I2C_Init(I2C2, &I2C_InitStruct); I2C_Cmd(I2C2, ENABLE); }
//-------------------------------------------------------------- // interne Funktion // wird bei einem Timeout aufgerufen // Stop, Reset und reinit der I2C-Schnittstelle //-------------------------------------------------------------- int16_t P_I2C3_timeout(int16_t wert) { int16_t ret_wert=wert; // Stop und Reset I2C_GenerateSTOP(I2C3, ENABLE); I2C_SoftwareResetCmd(I2C3, ENABLE); I2C_SoftwareResetCmd(I2C3, DISABLE); // I2C deinit I2C_DeInit(I2C3); // I2C init P_I2C3_InitI2C(); return(ret_wert); }
void I2C_reset(i2c_bus *bus) { I2C_ITConfig(I2C_HW(bus), I2C_IT_ERR | I2C_IT_BUF | I2C_IT_EVT, DISABLE); // if an i2c device is queried but its ack is never clocked out, it // will pull SDA low forever. Clock out any pending acks and generate // STOP condition. Read twice if DR would be populated. I2C_LOG_STOP(bus); I2C_GenerateSTOP(I2C_HW(bus), ENABLE); I2C_ReceiveData(I2C_HW(bus)); I2C_ReceiveData(I2C_HW(bus)); SYS_hardsleep_us(500); // give some time to clock out I2C_SoftwareResetCmd(I2C_HW(bus), ENABLE); SYS_hardsleep_us(100); I2C_SoftwareResetCmd(I2C_HW(bus), DISABLE); i2c_finalize(bus); }
//______________________________________________________________________________________ void Reset_I2C(_i2c *p) { GPIO_InitTypeDef GPIO_InitStructure; if(p) { _SET_ERROR(pfm,PFM_I2C_ERR); GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_ResetBits(GPIOB,GPIO_Pin_6 | GPIO_Pin_7); _wait(25,_proc_loop); I2C_SoftwareResetCmd(I2C1,ENABLE); I2C_SoftwareResetCmd(I2C1,DISABLE); p=Initialize_I2C(p->addr,p->speed); } }
//Config I2C void I2C_Configuration() { //check whether bus is busy or not while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)) { I2C_SoftwareResetCmd(I2C1, ENABLE); } I2C_InitTypeDef I2C_InitStructure; //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); I2C_Cmd(I2C1, ENABLE); /* Enable I2C1 event and buffer interrupts */ I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, DISABLE); }
unsigned long TWI_MasterWriteRead(new_twi* TwiStruct, unsigned int TransmitBytes, unsigned int ReceiveBytes) { uint32_t tickstart = 0; I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)TwiStruct->udata; /* Init tickstart for timeout management*/ tickstart = HAL_GetTick(); if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) { I2C_SoftwareResetCmd(hi2c); return HAL_TIMEOUT; } hi2c->State = HAL_I2C_STATE_BUSY_TX; hi2c->Mode = HAL_I2C_MODE_MASTER; hi2c->ErrorCode = HAL_I2C_ERROR_NONE; /* Prepare transfer parameters */ hi2c->pBuffPtr = TwiStruct->TxBuff; hi2c->XferCount = TransmitBytes; hi2c->XferISR = NULL; /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */ if(hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; I2C_TransferConfig(hi2c, TwiStruct->MasterSlaveAddr, hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE); } else { if(ReceiveBytes != 0) { hi2c->XferSize = hi2c->XferCount; I2C_TransferConfig(hi2c, TwiStruct->MasterSlaveAddr, hi2c->XferSize, I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE); } else { hi2c->XferSize = hi2c->XferCount; I2C_TransferConfig(hi2c, TwiStruct->MasterSlaveAddr, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_WRITE); } } do { tickstart = HAL_GetTick(); /* Wait until TXIS flag is set */ if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) { if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) { return HAL_ERROR; } else { return HAL_TIMEOUT; } } /* Read data from RXDR */ hi2c->Instance->TXDR = (*hi2c->pBuffPtr++); hi2c->XferCount--; hi2c->XferSize--; if((hi2c->XferSize == 0) && (hi2c->XferCount != 0)) { /* Wait until TCR flag is set */ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) { return HAL_TIMEOUT; } if(hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; I2C_TransferConfig(hi2c, TwiStruct->MasterSlaveAddr, hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); } else { if(ReceiveBytes != 0) { hi2c->XferSize = hi2c->XferCount; I2C_TransferConfig(hi2c, TwiStruct->MasterSlaveAddr, hi2c->XferSize, I2C_SOFTEND_MODE, I2C_NO_STARTSTOP); } else { hi2c->XferSize = hi2c->XferCount; I2C_TransferConfig(hi2c, TwiStruct->MasterSlaveAddr, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); } } } }while(hi2c->XferCount > 0); if(ReceiveBytes == 0) { /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ /* Wait until STOPF flag is reset */ if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) { if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) { return HAL_ERROR; } else { return HAL_TIMEOUT; } } /* Clear STOP Flag */ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); /* Clear Configuration Register 2 */ I2C_RESET_CR2(hi2c); hi2c->State = HAL_I2C_STATE_READY; hi2c->Mode = HAL_I2C_MODE_NONE; /* Process Unlocked */ __HAL_UNLOCK(hi2c); return HAL_OK; } tickstart = HAL_GetTick(); /* Wait until TCR flag is set */ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TC, RESET, Timeout, tickstart) != HAL_OK) { return HAL_TIMEOUT; } hi2c->State = HAL_I2C_STATE_BUSY_RX; hi2c->Mode = HAL_I2C_MODE_MASTER; hi2c->ErrorCode = HAL_I2C_ERROR_NONE; /* Prepare transfer parameters */ hi2c->pBuffPtr = TwiStruct->RxBuff; hi2c->XferCount = ReceiveBytes; hi2c->XferISR = NULL; /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */ if(hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; I2C_TransferConfig(hi2c, TwiStruct->MasterSlaveAddr | 1, hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_READ); } else { hi2c->XferSize = hi2c->XferCount; I2C_TransferConfig(hi2c, TwiStruct->MasterSlaveAddr | 1, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ); } do { tickstart = HAL_GetTick(); /* Wait until RXNE flag is set */ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK) { return HAL_TIMEOUT; } /* Read data from RXDR */ (*hi2c->pBuffPtr++) = hi2c->Instance->RXDR; hi2c->XferSize--; hi2c->XferCount--; if((hi2c->XferSize == 0) && (hi2c->XferCount != 0)) { /* Wait until TCR flag is set */ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) { return HAL_TIMEOUT; } if(hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; I2C_TransferConfig(hi2c, TwiStruct->MasterSlaveAddr | 1, hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); } else { hi2c->XferSize = hi2c->XferCount; I2C_TransferConfig(hi2c, TwiStruct->MasterSlaveAddr | 1, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); } } }while(hi2c->XferCount > 0); /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ /* Wait until STOPF flag is reset */ if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) { if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) { return HAL_ERROR; } else { return HAL_TIMEOUT; } } /* Clear STOP Flag */ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); /* Clear Configuration Register 2 */ I2C_RESET_CR2(hi2c); hi2c->State = HAL_I2C_STATE_READY; hi2c->Mode = HAL_I2C_MODE_NONE; /* Process Unlocked */ __HAL_UNLOCK(hi2c); return HAL_OK; }
/** * @brief Reads a register of the device through I2C. * @param DeviceAddr: The address of the device, could be : IOE_1_ADDR * or IOE_2_ADDR. * @param RegisterAddr: The target register adress (between 00x and 0x24) * @retval The value of the read register (0xAA if Timout occured) */ uint8_t I2C_ReadDeviceRegister(uint8_t DeviceAddr, uint8_t RegisterAddr) { uint32_t tmp = 0; /* Disable the IOE_I2C peripheral */ I2C_Cmd(IOE_I2C, DISABLE); /* Reset all I2C2 registers */ I2C_SoftwareResetCmd(IOE_I2C, ENABLE); I2C_SoftwareResetCmd(IOE_I2C, DISABLE); /* Configure the I2C peripheral */ IOE_I2C_Config(); /* Enable the I2C peripheral */ I2C_GenerateSTART(IOE_I2C, ENABLE); /* Test on EV5 and clear it */ TimeOut = TIMEOUT_MAX; while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_MODE_SELECT)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Disable Acknowledgement */ I2C_AcknowledgeConfig(IOE_I2C, DISABLE); /* Transmit the slave address and enable writing operation */ I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ TimeOut = TIMEOUT_MAX; while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Transmit the first address for r/w operations */ I2C_SendData(IOE_I2C, RegisterAddr); /* Test on EV8 and clear it */ TimeOut = TIMEOUT_MAX; while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Regenerate a start condition */ I2C_GenerateSTART(IOE_I2C, ENABLE); /* Test on EV5 and clear it */ TimeOut = TIMEOUT_MAX; while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_MODE_SELECT)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Transmit the slave address and enable writing operation */ I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Receiver); /* Test on EV6 and clear it */ TimeOut = TIMEOUT_MAX; while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Test on EV7 and clear it */ TimeOut = TIMEOUT_MAX; while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* End the configuration sequence */ I2C_GenerateSTOP(IOE_I2C, ENABLE); /* Load the register value */ tmp = I2C_ReceiveData(IOE_I2C); /* Enable Acknowledgement */ I2C_AcknowledgeConfig(IOE_I2C, ENABLE); /* Return the read value */ 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; }
/** * @brief Reads a buffer of 2 bytes from the device registers. * @param DeviceAddr: The address of the device, could be : IOE_1_ADDR * or IOE_2_ADDR. * @param RegisterAddr: The target register adress (between 00x and 0x24) * @retval A pointer to the buffer containing the two returned bytes (in halfword). */ uint16_t I2C_ReadDataBuffer(uint8_t DeviceAddr, uint32_t RegisterAddr) { uint8_t Buffer[2] = {0x00, 0x00}; /* Disable the I2C1 peripheral */ I2C_Cmd(I2C1, DISABLE); /* Reset all I2C2 registers */ I2C_SoftwareResetCmd(I2C1, ENABLE); I2C_SoftwareResetCmd(I2C1, DISABLE); /* Configure the I2C peripheral */ IOE_I2C_Config(); /* Enable the I2C peripheral */ I2C_GenerateSTART(I2C1, ENABLE); /* Test on EV5 and clear it */ TimeOut = TIMEOUT_MAX; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Send device address for write */ I2C_Send7bitAddress(I2C1, DeviceAddr, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ TimeOut = TIMEOUT_MAX; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Clear EV6 by setting again the PE bit */ I2C_Cmd(I2C1, ENABLE); /* Send the device's internal address to write to */ I2C_SendData(I2C1, RegisterAddr); /* Test on EV8 and clear it */ TimeOut = TIMEOUT_MAX; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Send STRAT condition a second time */ I2C_GenerateSTART(I2C1, ENABLE); /* Test on EV5 and clear it */ TimeOut = TIMEOUT_MAX; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Send IOExpander address for read */ I2C_Send7bitAddress(I2C1, DeviceAddr, I2C_Direction_Receiver); /* Test on EV6 and clear it */ TimeOut = TIMEOUT_MAX; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Test on EV7 and clear it */ TimeOut = TIMEOUT_MAX; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Read the first byte from the IOExpander */ Buffer[1] = I2C_ReceiveData(I2C1); /* Disable Acknowledgement */ I2C_AcknowledgeConfig(I2C1, DISABLE); /* Send STOP Condition */ I2C_GenerateSTOP(I2C1, ENABLE); /* Test on EV7 and clear it */ TimeOut = TIMEOUT_MAX; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Read the second byte from the IOExpander */ Buffer[0] = I2C_ReceiveData(I2C1); /* Enable Acknowledgement to be ready for another reception */ I2C_AcknowledgeConfig(I2C1, ENABLE); /* return a pointer to the buffer */ return *(uint16_t *)Buffer; }
/******************************************************************************* * Function Name : CODEC_ReadRegister * Description : Reads a register of the audio Codec through I2C. * Input : - RegisterAddr: The target register address (between 00x and 0x24) * Output : None * Return : The value of the read register *******************************************************************************/ uint32_t CODEC_ReadRegister(uint32_t RegisterAddr) { uint32_t tmp = 0; /* Disable the I2C1 peripheral */ I2C_Cmd(I2C1, DISABLE); /* Reset all I2C2 registers */ I2C_SoftwareResetCmd(I2C1, ENABLE); I2C_SoftwareResetCmd(I2C1, DISABLE); /* Configure the I2C peripheral */ I2C_Config(); /* Enable the I2C peripheral */ I2C_GenerateSTART(I2C1, ENABLE); /* Test on EV5 and clear it */ while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) {} /* Disable Acknowledgement */ I2C_AcknowledgeConfig(I2C1, DISABLE); /* Transmit the slave address and enable writing operation */ I2C_Send7bitAddress(I2C1, CODEC_ADDRESS, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {} /* Transmit the first address for r/w operations */ I2C_SendData(I2C1, RegisterAddr); /* Test on EV8 and clear it */ while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {} /* Regenerate a start condition */ I2C_GenerateSTART(I2C1, ENABLE); /* Test on EV5 and clear it */ while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) {} /* Transmit the slave address and enable writing operation */ I2C_Send7bitAddress(I2C1, CODEC_ADDRESS, I2C_Direction_Receiver); /* Test on EV6 and clear it */ while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) {} /* Test on EV7 and clear it */ while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)) {} /* End the configuration sequence */ I2C_GenerateSTOP(I2C1, ENABLE); /* Load the register value */ tmp = I2C_ReceiveData(I2C1); /* Disable Acknowledgement */ I2C_AcknowledgeConfig(I2C1, ENABLE); /* Return the read value */ return tmp; }
/******************************************************************************* * Function Name : CODEC_WriteRegister * Description : Writes a value in a register of the audio Codec through I2C. * Input : - RegisterAddr: The target register address (between 00x and 0x24) * : - RegisterValue: The target register value to be written * : - Verify: 0-> Don't verify the written data, 1-> Verify the written data * Output : None * Return : - 0 -> Correct write operation * : - !0 -> Incorrect write operation *******************************************************************************/ uint32_t CODEC_WriteRegister(uint32_t RegisterAddr, uint32_t RegisterValue) { uint32_t read_verif = 0; /* Reset all I2C2 registers */ I2C_SoftwareResetCmd(I2C1, ENABLE); I2C_SoftwareResetCmd(I2C1, DISABLE); /* Enable the I2C1 peripheral */ I2C_Cmd(I2C1, ENABLE); /* Configure the I2C peripheral */ I2C_Config(); /* Begin the config sequence */ I2C_GenerateSTART(I2C1, ENABLE); /* Test on EV5 and clear it */ while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) {} /* Transmit the slave address and enable writing operation */ I2C_Send7bitAddress(I2C1, CODEC_ADDRESS, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {} /* Transmit the first address for r/w operations */ I2C_SendData(I2C1, RegisterAddr); /* Test on EV8 and clear it */ while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {} /* Prepare the register value to be sent */ I2C_SendData(I2C1, RegisterValue); /* Test on EV8 and clear it */ while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {} /* End the configuration sequence */ I2C_GenerateSTOP(I2C1, ENABLE); /* Verify (if needed) that the loaded data is correct */ #ifdef VERIFY_WRITTENDATA /* Read the just written register*/ read_verif = CODEC_ReadRegister(RegisterAddr); /* Load the register and verify its value */ if (read_verif != RegisterValue) { /* Control data wrongly transferred */ read_verif = 1; } else { /* Control data correctly transferred */ read_verif = 0; } #endif /* Return the verifying value: 0 (Passed) or 1 (Failed) */ return read_verif; }
/** * @brief Reads a buffer of 4 bytes from IO_Expander registers. * @param DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR * or IOE_2_ADDR. * @param RegisterAddr: The target register adress (between 00x and 0x24) * @retval : The value of the read register (0xAA if Timout occured) */ uint32_t I2C_ReadDataBuffer(u8 DeviceAddr, uint32_t RegisterAddr) { u8 Buffer[4] , idx = 2; /* Initialize the buffer */ Buffer[0] = 0; Buffer[1] = 0; Buffer[2] = 0; Buffer[3] = 0; /* Disable the I2C1 peripheral */ I2C_Cmd(I2C1, DISABLE); /* Reset all I2C2 registers */ I2C_SoftwareResetCmd(I2C1, ENABLE); I2C_SoftwareResetCmd(I2C1, DISABLE); /* Configure the I2C peripheral */ IOE_I2C_Config(); /* Enable the I2C peripheral */ I2C_GenerateSTART(I2C1, ENABLE); TimeOut = TIMEOUT_MAX; /* Test on EV5 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Send device address for write */ I2C_Send7bitAddress(I2C1, DeviceAddr, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Clear EV6 by setting again the PE bit */ I2C_Cmd(I2C1, ENABLE); /* Send the device's internal address to write to */ I2C_SendData(I2C1, RegisterAddr); /* Test on EV8 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Send STRAT condition a second time */ I2C_GenerateSTART(I2C1, ENABLE); /* Test on EV5 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Send EEPROM address for read */ I2C_Send7bitAddress(I2C1, DeviceAddr, I2C_Direction_Receiver); /* Test on EV6 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* While there is data to be read */ while(idx) { if(idx == 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 EEPROM */ Buffer[idx-1] = I2C_ReceiveData(I2C1); /* Decrement the read bytes counter */ idx--; } } /* Enable Acknowledgement to be ready for another reception */ I2C_AcknowledgeConfig(I2C1, ENABLE); /* return a pointer to the buffer */ return *(uint32_t *)Buffer; }
/** * @brief Writes a value in a register of the device through I2C. * @param DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR * or IOE_2_ADDR. * @param RegisterAddr: The target register adress * @param RegisterValue: The target register value to be written * @retval IOE_OK: if all operations are OK. Other value if error. */ uint8_t I2C_WriteDeviceRegister(uint8_t DeviceAddr, uint8_t RegisterAddr, uint8_t RegisterValue) { uint32_t read_verif = 0; /* Reset all I2C2 registers */ I2C_SoftwareResetCmd(IOE_I2C, ENABLE); I2C_SoftwareResetCmd(IOE_I2C, DISABLE); /* Enable the IOE_I2C peripheral */ I2C_Cmd(IOE_I2C, ENABLE); /* Configure the I2C peripheral */ IOE_I2C_Config(); /* Begin the config sequence */ I2C_GenerateSTART(IOE_I2C, ENABLE); /* Test on EV5 and clear it */ TimeOut = TIMEOUT_MAX; while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_MODE_SELECT)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Transmit the slave address and enable writing operation */ I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ TimeOut = TIMEOUT_MAX; while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Transmit the first address for r/w operations */ I2C_SendData(IOE_I2C, RegisterAddr); /* Test on EV8 and clear it */ TimeOut = TIMEOUT_MAX; while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* Prepare the register value to be sent */ I2C_SendData(IOE_I2C, RegisterValue); /* Test on EV8 and clear it */ TimeOut = TIMEOUT_MAX; while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) { if (TimeOut-- == 0) return IOE_TIEMOUT; } /* End the configuration sequence */ I2C_GenerateSTOP(IOE_I2C, ENABLE); #ifdef VERIFY_WRITTENDATA /* Verify (if needed) that the loaded data is correct */ /* Read the just written register*/ read_verif = I2C_ReadDeviceRegister(DeviceAddr, RegisterAddr); /* Load the register and verify its value */ if (read_verif != RegisterValue) { /* Control data wrongly tranfered */ read_verif = IOE_FAILURE; } else { /* Control data correctly transfered */ read_verif = 0; } #endif /* Return the verifying value: 0 (Passed) or 1 (Failed) */ return read_verif; }
int chip_i2c_reset(chip_i2c_port_t port) { I2C_SoftwareResetCmd(port,ENABLE); I2C_SoftwareResetCmd(port,DISABLE); }
void sens9DInit(void){ //PB10/I2C2_SCL, PB11/I2C2_SDA // XM Read Address 8bit 0x3B, Gyro 8bit Read 0xD7 GPIO_InitTypeDef GPIO_InitStructure; I2C_InitTypeDef I2C_InitStructure; u8 statOk=!0; int i; I2C_DeInit(I2C2); I2C_Cmd(I2C2, DISABLE); I2C_SoftwareResetCmd(I2C2, ENABLE); I2C_SoftwareResetCmd(I2C2, DISABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIOB->BSRRL=GPIO_Pin_10|GPIO_Pin_11; i=8; while( (i--) && ((GPIOB->IDR&GPIO_Pin_11)==0)){ delay_us(200); GPIOB->BSRRH=GPIO_Pin_10; delay_us(200); GPIOB->BSRRL=GPIO_Pin_10; } GPIO_PinAFConfig(GPIOB,GPIO_PinSource10, GPIO_AF_I2C2); GPIO_PinAFConfig(GPIOB,GPIO_PinSource11, GPIO_AF_I2C2); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_Init(GPIOB, &GPIO_InitStructure); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_OwnAddress1 = 0x01; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed=100e3; I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_16_9; I2C_Init(I2C2, &I2C_InitStructure); I2C_StretchClockCmd(I2C2,ENABLE); //I2C_GeneralCallCmd(I2C1,ENABLE); //I2C_AnalogFilterCmd(I2C2,ENABLE); //I2C_DigitalFilterConfig(I2C2,0x02); Not available on 407.. :( I2C_Cmd(I2C2, ENABLE); delay_us(1e3); //CTRL_REG1_G to CTRL_REG5_G 0x20..0x24 //190Hz, 25Hz cut //0.45Hz HPass //Full scale 2000dps //HPass ΝΟΤ selected // 20h 21h 22h 23h 24h u8 GyroCTRreg[5]={0b01111111, 0b00100101, 0b00000000, 0b10100000, 0b00000000 };//24h ->0b00000000 disables LPF2 //Enable 0b00000010 I2C_write(Gy_addr,0x20|0x80,GyroCTRreg,5); // HP filter bypassed // 1Fh 20h 21h 22h 23h 24h 25h 26h u8 XM_CTRreg[8]={0b00000000, 0b01111111, 0b11001000, 0b00000000, 0b00000000, 0b11110100, 0b00000000, 0b00000000 };//200Hz, 50HzBW, 4G, Magn:100Hz,2Gauss I2C_write(XM_addr,0x1F|0x80,XM_CTRreg,8); }
/******************************************************************************* * Function Name : I2C_SetState * Description : Set state of I2Cx and try to solve problem after errors * Input : I2C TypeDef, new state * Output : None * Return : None *******************************************************************************/ void I2C_SetState(I2C_TypeDef* I2Cx, enum I2CState state) { static u8 countFault = 0; u32 timeout; GPIO_TypeDef * I2Cx_GPIO; u16 I2Cx_PIN_SDA, I2Cx_PIN_SCL; // Set new state if(I2Cx == I2C1) { I2C1_state = state; } else if(I2Cx == I2C2) { I2C2_state = state; } // count faults switch(state) { case NONE: case ADNM: countFault = 0; break; case SCF: case B1NT: case B2NT: case B3NT: case B4NT: case BxNT: case B1NR: case B2NR: case B3NR: case B4NR: case BxNR: countFault++; break; case BTF: case BRF: countFault = 0; break; } // If 5 or more faults occurred if(5 < countFault) { // Enable I2Cx Software Reset I2C_SoftwareResetCmd(I2Cx, ENABLE); // Define GPIO and Pins for I2Cx if(I2Cx == I2C1) { I2Cx_GPIO = I2C1_GPIO; #if defined(USE_I2C1_Remap) I2Cx_PIN_SCL = I2C1_REMAP_GPIO_PIN_SCL; I2Cx_PIN_SDA = I2C1_REMAP_GPIO_PIN_SDA; // Configure SCL and SDA as open drain output I2Cx_GPIO->CRH &= ~0x00000088; I2Cx_GPIO->CRH |= 0x00000077; #else I2Cx_PIN_SCL = I2C1_GPIO_PIN_SCL; I2Cx_PIN_SDA = I2C1_GPIO_PIN_SDA; // Configure SCL and SDA as open drain output I2Cx_GPIO->CRL &= ~0x88000000; I2Cx_GPIO->CRL |= 0x77000000; #endif } else if(I2Cx == I2C2) { I2Cx_GPIO = I2C2_GPIO; I2Cx_PIN_SCL = I2C2_GPIO_PIN_SCL; I2Cx_PIN_SDA = I2C2_GPIO_PIN_SDA; // Configure SCL and SDA as open drain output I2Cx_GPIO->CRH &= ~0x00008800; I2Cx_GPIO->CRH |= 0x00007700; } // Release SDA I2Cx_GPIO->ODR |= I2Cx_PIN_SDA; // Toggle CLK until SDA and SCL released or timeout exceeded timeout = TIMEOUT; while((I2Cx_GPIO->IDR ^ (I2Cx_PIN_SDA | I2Cx_PIN_SCL)) && timeout--) { I2Cx_GPIO->ODR ^= I2Cx_PIN_SCL; } // Configure SCL and SDA as alternate function open drain if(I2Cx == I2C1) { #if defined(USE_I2C1_Remap) I2Cx_GPIO->CRH |= 0x000000FF; #else I2Cx_GPIO->CRL |= 0xFF000000; #endif } else if(I2Cx == I2C2) { I2Cx_GPIO->CRH |= 0x0000FF00; } // If SDA released if(0 < (I2Cx_GPIO->IDR & I2Cx_PIN_SDA)) { // Close the I2C Bus I2C_DeInit(I2Cx); //Configure the I2C Bus I2C_Configuration(I2Cx); } // Reset countFault countFault = 0; } }
/** * @brief Enables the I2C Clock and configures the different GPIO ports. * @param None * @retval None */ void i2c_init(void) { GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; I2C_DeInit(I2Cx); I2C_SoftwareResetCmd(I2Cx, ENABLE); I2C_SoftwareResetCmd(I2Cx, DISABLE); /* RCC Configuration */ /*I2C Peripheral clock enable */ RCC_APB1PeriphClockCmd(I2Cx_CLK, ENABLE); /*SDA GPIO clock enable */ RCC_AHB1PeriphClockCmd(I2Cx_SDA_GPIO_CLK, ENABLE); /*SCL GPIO clock enable */ RCC_AHB1PeriphClockCmd(I2Cx_SCL_GPIO_CLK, ENABLE); /* Reset I2Cx IP */ RCC_APB1PeriphResetCmd(I2Cx_CLK, ENABLE); /* Release reset signal of I2Cx IP */ RCC_APB1PeriphResetCmd(I2Cx_CLK, DISABLE); /* GPIO Configuration */ /*Configure I2C SCL pin */ GPIO_InitStructure.GPIO_Pin = I2Cx_SCL_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(I2Cx_SCL_GPIO_PORT, &GPIO_InitStructure); /*Configure I2C SDA pin */ GPIO_InitStructure.GPIO_Pin = I2Cx_SDA_PIN; GPIO_Init(I2Cx_SDA_GPIO_PORT, &GPIO_InitStructure); /* Connect PXx to I2C_SCL */ GPIO_PinAFConfig(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_SOURCE, I2Cx_SCL_AF); /* Connect PXx to I2C_SDA */ GPIO_PinAFConfig(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_SOURCE, I2Cx_SDA_AF); /* NVIC configuration */ /* Configure the Priority Group to 1 bit */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* Configure the I2C event priority */ NVIC_InitStructure.NVIC_IRQChannel = I2Cx_EV_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0; // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Configure I2C error interrupt to have the higher priority */ NVIC_InitStructure.NVIC_IRQChannel = I2Cx_ER_IRQn; NVIC_Init(&NVIC_InitStructure); /* Initialize I2C peripheral */ /*!< I2C Init */ I2C_InitTypeDef I2C_InitStructure; I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DUTYCYCLE; I2C_InitStructure.I2C_OwnAddress1 = SLAVE_ADDRESS; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_Init(I2Cx, &I2C_InitStructure); /* Enable Error Interrupt */ I2C_ITConfig(I2Cx, (I2C_IT_ERR | I2C_IT_EVT /*| I2C_IT_BUF*/), ENABLE); /* I2C ENABLE */ I2C_Cmd(I2Cx, ENABLE); }
/*stm32 iic³õʼ»¯*/ void pin_init1() { GPIO_InitTypeDef GPIO_InitStructure; ADC_InitTypeDef ADC_InitStructure; /* Enable GPIOB,E,F,G clock */ //DEBUG("power pin init 2\r\n"); RCC_ADCCLKConfig(RCC_PCLK2_Div4); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); /* Enable I2C2 clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SPI3, ENABLE); GPIO_PinRemapConfig(GPIO_FullRemap_USART3, ENABLE); GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_InitStructure.GPIO_Pin = BATS_I2C_SCL_PIN; GPIO_Init(BATS_I2C_SCL_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = BATS_I2C_SDA_PIN; GPIO_Init(BATS_I2C_SDA_PORT, &GPIO_InitStructure); /* Config pin */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin = BATS_I2C_SEL_PIN; GPIO_Init(BATS_I2C_SEL_PORT, &GPIO_InitStructure); // GPIO_InitStructure.GPIO_Pin = BATS_SEL_C_PIN; // GPIO_Init(BATS_SEL_C_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = BATS_SEL_B_PIN; GPIO_Init(BATS_SEL_B_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = BATS_SEL_A_PIN; GPIO_Init(BATS_SEL_A_PORT, &GPIO_InitStructure); //GPIO_InitStructure.GPIO_Pin = BATS_SEL_STAC_PIN; //GPIO_Init(BATS_SEL_STAC_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = BATS_SEL_STAB_PIN; GPIO_Init(BATS_SEL_STAB_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = BATS_SEL_STAA_PIN; GPIO_Init(BATS_SEL_STAA_PORT, &GPIO_InitStructure); //GPIO_InitStructure.GPIO_Pin = BATS_C_CHARGE_CTL_PIN; //GPIO_Init(BATS_C_CHARGE_CTL_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = BATS_ABC_CHARGE_FAULT_PIN; GPIO_Init(BATS_ABC_CHARGE_FAULT_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = BATS_ABC_CHARGE_CHRG_PIN; GPIO_Init(BATS_ABC_CHARGE_CHRG_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = PG_3V3_PIN; GPIO_Init(PG_3V3_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = BATS_A_CHARGE_STAT_PIN; GPIO_Init(BATS_A_CHARGE_STAT_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = BATS_A_CHARGE_CTL_PIN; GPIO_Init(BATS_A_CHARGE_CTL_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = BATS_B_CHARGE_STAT_PIN; GPIO_Init(BATS_B_CHARGE_STAT_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = BATS_B_CHARGE_CTL_PIN; GPIO_Init(BATS_B_CHARGE_CTL_PORT, &GPIO_InitStructure); //GPIO_InitStructure.GPIO_Pin = BATS_C_CHARGE_STAT_PIN; //GPIO_Init(BATS_C_CHARGE_STAT_PORT, &GPIO_InitStructure); //GPIO_InitStructure.GPIO_Pin = BATS_SEL_C_PIN; //GPIO_Init(BATS_SEL_C_PORT, &GPIO_InitStructure); //ADC channel config GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_InitStructure.GPIO_Pin = BATS_AB_MON_I_PIN; GPIO_Init(BATS_AB_MON_I_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = V3P3_MON_V_PIN; GPIO_Init(V3P3_MON_V_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = BATS_A_V_MON_PIN; GPIO_Init(BATS_A_V_MON_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = BATS_B_V_MON_PIN; GPIO_Init(BATS_B_V_MON_PORT, &GPIO_InitStructure); //GPIO_InitStructure.GPIO_Pin = BATS_C_V_MON_PIN; //GPIO_Init(BATS_C_V_MON_PORT, &GPIO_InitStructure); //I2C Config I2C_SoftwareResetCmd(I2C2,ENABLE); I2C_SoftwareResetCmd(I2C2,DISABLE); I2C_Cmd(I2C2, ENABLE); I2C_InitStructure.I2C_Mode = I2C_Mode_SMBusHost; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = 0x79; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = 50000; I2C_Init(I2C2, &I2C_InitStructure); //DEBUG("power pin init 1\r\n"); I2C_CalculatePEC(I2C2, ENABLE); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC3, &ADC_InitStructure); ADC_Cmd(ADC3, ENABLE); ADC_ResetCalibration(ADC3); while(ADC_GetResetCalibrationStatus(ADC3)); ADC_StartCalibration(ADC3); while(ADC_GetCalibrationStatus(ADC3)); //DEBUG("power pin init over\r\n"); }