/** * @brief Checks if the selected device is correctly configured and * communicates correctly on the I2C bus. * @param DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR * or IOE_2_ADDR. * @retval IOE_OK if IOE is operational. Other value if failure. */ uint8_t IOE_IsOperational(uint8_t DeviceAddr) { /* Return Error if the ID is not correct */ if ( IOE_ReadID(DeviceAddr) != (uint16_t)STMPE811_ID ) { /* Check if a Timeout occurred */ if (IOE_TimeOut == 0) { return(IOE_TimeoutUserCallback()); } else { return IOE_FAILURE; /* ID is not Correct */ } } else { return IOE_OK; /* ID is correct */ } }
/** * @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 tmp= 0; uint8_t IOE_BufferRX[2] = {0x00, 0x00}; /* Configure DMA Peripheral */ IOE_DMA_Config(IOE_DMA_RX, (uint8_t*)IOE_BufferRX); /* Enable DMA NACK automatic generation */ I2C_DMALastTransferCmd(IOE_I2C, ENABLE); /* Enable the I2C peripheral */ I2C_GenerateSTART(IOE_I2C, ENABLE); /* Test on SB Flag */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Send device address for write */ I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Transmitter); /* Test on ADDR Flag */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Send the device's internal address to write to */ I2C_SendData(IOE_I2C, RegisterAddr); /* Test on TXE FLag (data dent) */ IOE_TimeOut = TIMEOUT_MAX; while ((!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_BTF))) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Send START condition a second time */ I2C_GenerateSTART(IOE_I2C, ENABLE); /* Test on SB Flag */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Send IOExpander address for read */ I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Receiver); /* Test on ADDR Flag */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Enable I2C DMA request */ I2C_DMACmd(IOE_I2C,ENABLE); /* Enable DMA RX Channel */ DMA_Cmd(IOE_DMA_RX_CHANNEL, ENABLE); /* Wait until DMA Transfer Complete */ IOE_TimeOut = 2 * TIMEOUT_MAX; while (!DMA_GetFlagStatus(IOE_DMA_RX_TCFLAG)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Send STOP Condition */ I2C_GenerateSTOP(IOE_I2C, ENABLE); /* Disable DMA RX Channel */ DMA_Cmd(IOE_DMA_RX_CHANNEL, DISABLE); /* Disable I2C DMA request */ I2C_DMACmd(IOE_I2C,DISABLE); /* Clear DMA RX Transfer Complete Flag */ DMA_ClearFlag(IOE_DMA_RX_TCFLAG); /* Reorganize received data */ tmp = IOE_BufferRX[0]; IOE_BufferRX[0] = IOE_BufferRX[1]; IOE_BufferRX[1] = tmp; /* return a pointer to the IOE_Buffer */ return *(uint16_t *)IOE_BufferRX; }
/** * @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; uint8_t IOE_BufferTX = 0; /* Get Value to be written */ IOE_BufferTX = RegisterValue; /* Configure DMA Peripheral */ IOE_DMA_Config(IOE_DMA_TX, (uint8_t*)(&IOE_BufferTX)); /* Enable the I2C peripheral */ I2C_GenerateSTART(IOE_I2C, ENABLE); /* Test on SB Flag */ IOE_TimeOut = TIMEOUT_MAX; while (I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB) == RESET) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Transmit the slave address and enable writing operation */ I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Transmitter); /* Test on ADDR Flag */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Transmit the first address for r/w operations */ I2C_SendData(IOE_I2C, RegisterAddr); /* Test on TXE FLag (data dent) */ IOE_TimeOut = TIMEOUT_MAX; while ((!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_BTF))) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Enable I2C DMA request */ I2C_DMACmd(IOE_I2C,ENABLE); /* Enable DMA TX Channel */ DMA_Cmd(IOE_DMA_TX_CHANNEL, ENABLE); /* Wait until DMA Transfer Complete */ IOE_TimeOut = TIMEOUT_MAX; while (!DMA_GetFlagStatus(IOE_DMA_TX_TCFLAG)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Wait until BTF Flag is set before generating STOP */ IOE_TimeOut = 2 * TIMEOUT_MAX; while ((!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_BTF))) { } /* Send STOP Condition */ I2C_GenerateSTOP(IOE_I2C, ENABLE); /* Disable DMA TX Channel */ DMA_Cmd(IOE_DMA_TX_CHANNEL, DISABLE); /* Disable I2C DMA request */ I2C_DMACmd(IOE_I2C,DISABLE); /* Clear DMA TX Transfer Complete Flag */ DMA_ClearFlag(IOE_DMA_TX_TCFLAG); #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; }
/** * @brief Reads a buffer of 2 bytes from the device registers. * @param RegisterAddr: The target register adress (between 00x and 0x24) * @retval The data in the buffer containing the two returned bytes (in halfword). */ uint16_t I2C_ReadDataBuffer(uint32_t RegisterAddr) { uint8_t IOE_BufferRX[2] = {0x00, 0x00}; /* Enable the I2C peripheral */ I2C_GenerateSTART(IOE_I2C, ENABLE); /* Test on EV5 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_SB)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Send device address for write */ I2C_Send7bitAddress(IOE_I2C, IOE_ADDR, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_ADDR)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Read status register 2 to clear ADDR flag */ IOE_I2C->SR2; /* Test on EV8 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_TXE)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Send the device's internal address to write to */ I2C_SendData(IOE_I2C, RegisterAddr); /* Send START condition a second time */ I2C_GenerateSTART(IOE_I2C, ENABLE); /* Test on EV5 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_SB)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Send IO Expander address for read */ I2C_Send7bitAddress(IOE_I2C, IOE_ADDR, I2C_Direction_Receiver); /* Test on EV6 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_ADDR)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Disable Acknowledgement and set Pos bit */ I2C_AcknowledgeConfig(IOE_I2C, DISABLE); I2C_NACKPositionConfig(IOE_I2C, I2C_NACKPosition_Next); /* Read status register 2 to clear ADDR flag */ IOE_I2C->SR2; /* Test on EV7 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_BTF)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Send STOP Condition */ I2C_GenerateSTOP(IOE_I2C, ENABLE); /* Read the first byte from the IO Expander */ IOE_BufferRX[1] = I2C_ReceiveData(IOE_I2C); /* Read the second byte from the IO Expander */ IOE_BufferRX[0] = I2C_ReceiveData(IOE_I2C); /* Enable Acknowledgement and reset POS bit to be ready for another reception */ I2C_AcknowledgeConfig(IOE_I2C, ENABLE); I2C_NACKPositionConfig(IOE_I2C, I2C_NACKPosition_Current); /* return the data */ return ((uint16_t) IOE_BufferRX[0] | ((uint16_t)IOE_BufferRX[1]<< 8)); }
/** * @brief Reads a register of the device through I2C without DMA. * @param RegisterAddr: The target register address (between 00x and 0x24) * @retval The value of the read register (0xAA if Timeout occurred) */ uint8_t I2C_ReadDeviceRegister(uint8_t RegisterAddr) { uint8_t tmp = 0; /* Enable the I2C peripheral */ I2C_GenerateSTART(IOE_I2C, ENABLE); /* Test on EV5 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_SB)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Disable Acknowledgement */ I2C_AcknowledgeConfig(IOE_I2C, DISABLE); /* Transmit the slave address and enable writing operation */ I2C_Send7bitAddress(IOE_I2C, IOE_ADDR, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_ADDR)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Read status register 2 to clear ADDR flag */ IOE_I2C->SR2; /* Test on EV8 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_TXE)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Transmit the first address for r/w operations */ I2C_SendData(IOE_I2C, RegisterAddr); /* Test on EV8 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while ((!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_TXE)) || (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_BTF))) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Regenerate a start condition */ I2C_GenerateSTART(IOE_I2C, ENABLE); /* Test on EV5 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_SB)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Transmit the slave address and enable writing operation */ I2C_Send7bitAddress(IOE_I2C, IOE_ADDR, I2C_Direction_Receiver); /* Test on EV6 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_ADDR)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Read status register 2 to clear ADDR flag */ IOE_I2C->SR2; /* Test on EV7 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_RXNE)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* 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 Writes a value in a register of the device through I2C. * @param RegisterAddr: The target register address * @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 RegisterAddr, uint8_t RegisterValue) { uint32_t read_verif = 0; /* Begin the configuration sequence */ I2C_GenerateSTART(IOE_I2C, ENABLE); /* Test on EV5 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_SB)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Transmit the slave address and enable writing operation */ I2C_Send7bitAddress(IOE_I2C, IOE_ADDR, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_ADDR)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Read status register 2 to clear ADDR flag */ IOE_I2C->SR2; /* Test on EV8_1 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_TXE)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Transmit the first address for r/w operations */ I2C_SendData(IOE_I2C, RegisterAddr); /* Test on EV8 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_TXE)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Prepare the register value to be sent */ I2C_SendData(IOE_I2C, RegisterValue); /* Test on EV8_2 and clear it */ IOE_TimeOut = TIMEOUT_MAX; while ((!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_TXE)) || (!I2C_GetFlagStatus(IOE_I2C, I2C_FLAG_BTF))) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* 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 = IOE_I2C_ReadDeviceRegister(RegisterAddr); /* Load the register and verify its value */ if (read_verif != RegisterValue) { /* Control data wrongly transferred */ read_verif = IOE_FAILURE; } else { /* Control data correctly transferred */ read_verif = 0; } #endif /* Return the verifying value: 0 (Passed) or 1 (Failed) */ return read_verif; }