/****************************************************************************** * This function reads a number of bytes from an IIC chip into a * specified buffer. * This function implements extended 16 bit addressing. * * @param ChipAddress contains the address of the IIC core. * @param RegAddress contains the address of the register to write to. * @param pBuffer contains the address of the data buffer to be filled. * @param ByteCount contains the number of bytes in the buffer to be read. * This value is constrained by the page size of the device such * that up to 64K may be read in one call. * * @return The number of bytes read. A value less than the specified input * value indicates an error. * * @note None. * ******************************************************************************/ int fmc_iic_axi_IicERead(fmc_iic_t *pIIC, Xuint8 ChipAddress, Xuint16 RegAddress, Xuint8 *pBuffer, Xuint8 ByteCount) { Xuint8 ReceivedByteCount = 0; Xuint8 SentByteCount = 0; Xuint8 WriteBuffer[2]; Xuint8 StatusReg; XStatus TestStatus=XST_FAILURE; int cnt = 0; fmc_iic_axi_t *pContext = (fmc_iic_axi_t *)(pIIC->pContext); #if 1 // Make sure all the Fifo's are cleared and Bus is Not busy. do { StatusReg = Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET); //xil_printf("[%s] Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET) => 0x%02X\n\r", pContext->szName, StatusReg ); StatusReg = StatusReg & (XIIC_SR_RX_FIFO_EMPTY_MASK | XIIC_SR_TX_FIFO_EMPTY_MASK | XIIC_SR_BUS_BUSY_MASK); } while (StatusReg != (XIIC_SR_RX_FIFO_EMPTY_MASK | XIIC_SR_TX_FIFO_EMPTY_MASK)); #endif /* * A temporary write buffer must be used which contains both the address * and the data to be written, put the address in first */ WriteBuffer[0] = (Xuint8)((RegAddress>>8) & 0x00FF); WriteBuffer[1] = (Xuint8)( RegAddress & 0x00FF); // Position the Read pointer to specific location. do { StatusReg = Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET); //xil_printf("[%s] Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET) => 0x%02X\n\r", pContext->szName, StatusReg ); if(!(StatusReg & XIIC_SR_BUS_BUSY_MASK)) { SentByteCount = XIic_DynSend(pContext->CoreAddress, ChipAddress, WriteBuffer, 2, XIIC_REPEATED_START); } cnt++; }while(SentByteCount != 1 && (cnt < 100)); // Error writing chip address so return SentByteCount if (SentByteCount < 1) { return SentByteCount; } // Receive the data. ReceivedByteCount = XIic_DynRecv(pContext->CoreAddress, ChipAddress, pBuffer, ByteCount); // Return the number of bytes received. return ReceivedByteCount; }
/****************************************************************************** * This function reads a number of bytes from an IIC chip into a * specified buffer. * * @param ChipAddress contains the address of the IIC core. * @param RegAddress contains the address of the register to write to. * @param pBuffer contains the address of the data buffer to be filled. * @param ByteCount contains the number of bytes in the buffer to be read. * This value is constrained by the page size of the device such * that up to 64K may be read in one call. * * @return The number of bytes read. A value less than the specified input * value indicates an error. * * @note None. * ******************************************************************************/ int fmc_iic_axi_IicRead(fmc_iic_t *pIIC, Xuint8 ChipAddress, Xuint8 RegAddress, Xuint8 *pBuffer, Xuint8 ByteCount) { Xuint8 ReceivedByteCount = 0; Xuint8 SentByteCount = 0; Xuint8 StatusReg; XStatus TestStatus=XST_FAILURE; int cnt = 0; fmc_iic_axi_t *pContext = (fmc_iic_axi_t *)(pIIC->pContext); #if 1 // Make sure all the Fifo's are cleared and Bus is Not busy. do { StatusReg = Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET); //xil_printf("[%s] Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET) => 0x%02X\n\r", pContext->szName, StatusReg ); StatusReg = StatusReg & (XIIC_SR_RX_FIFO_EMPTY_MASK | XIIC_SR_TX_FIFO_EMPTY_MASK | XIIC_SR_BUS_BUSY_MASK); } while (StatusReg != (XIIC_SR_RX_FIFO_EMPTY_MASK | XIIC_SR_TX_FIFO_EMPTY_MASK)); #endif // Position the Read pointer to specific location. do { StatusReg = Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET); //xil_printf("[%s] Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET) => 0x%02X\n\r", pContext->szName, StatusReg ); if(!(StatusReg & XIIC_SR_BUS_BUSY_MASK)) { SentByteCount = XIic_DynSend(pContext->CoreAddress, ChipAddress, (Xuint8 *)&RegAddress, 1, XIIC_REPEATED_START); } cnt++; }while(SentByteCount != 1 && (cnt < 100)); // Error writing chip address so return SentByteCount if (SentByteCount < 1) { return SentByteCount; } // Receive the data. ReceivedByteCount = XIic_DynRecv(pContext->CoreAddress, ChipAddress, pBuffer, ByteCount); // Return the number of bytes received. return ReceivedByteCount; }
/****************************************************************************** * This function reads a number of bytes from an IIC chip into a * specified buffer. * * @param CoreAddress contains the address of the IIC core. * @param ChipAddress contains the address of the IIC core. * @param RegAddress contains the address of the register to write to. * @param BufferPtr contains the address of the data buffer to be filled. * @param ByteCount contains the number of bytes in the buffer to be read. * This value is constrained by the page size of the device such * that up to 64K may be read in one call. * * @return The number of bytes read. A value less than the specified input * value indicates an error. * * @note None. * ******************************************************************************/ int fmc_ipmi_iic_read(Xuint32 CoreAddress, Xuint8 ChipAddress, Xuint8 RegAddress, Xuint8 *BufferPtr, Xuint8 ByteCount) { Xuint8 ReceivedByteCount = 0; Xuint8 SentByteCount = 0; Xuint8 StatusReg; XStatus TestStatus=XST_FAILURE; int cnt = 0; // Make sure all the Fifo's are cleared and Bus is Not busy. do { StatusReg = XIo_In8(CoreAddress + XIIC_SR_REG_OFFSET); //xil_printf("[fmc_imageov_iic_read] XIo_In8(CoreAddress + XIIC_SR_REG_OFFSET) => 0x%02X\n\r", StatusReg ); StatusReg = StatusReg & (XIIC_SR_RX_FIFO_EMPTY_MASK | XIIC_SR_TX_FIFO_EMPTY_MASK | XIIC_SR_BUS_BUSY_MASK); } while (StatusReg != (XIIC_SR_RX_FIFO_EMPTY_MASK | XIIC_SR_TX_FIFO_EMPTY_MASK)); // Position the Read pointer to specific location. do { StatusReg = XIo_In8(CoreAddress + XIIC_SR_REG_OFFSET); //xil_printf("[fmc_imageov_iic_read] XIo_In8(CoreAddress + XIIC_SR_REG_OFFSET) => 0x%02X\n\r", StatusReg ); if(!(StatusReg & XIIC_SR_BUS_BUSY_MASK)) { SentByteCount = XIic_DynSend(CoreAddress, ChipAddress, (Xuint8 *)&RegAddress, 1, XIIC_REPEATED_START); } cnt++; }while(SentByteCount != 1 && (cnt < 100000)); // Error writing chip address so return SentByteCount if (SentByteCount < 1) { return SentByteCount; } // Receive the data. ReceivedByteCount = XIic_DynRecv(CoreAddress, ChipAddress, BufferPtr, ByteCount); // Return the number of bytes received. return ReceivedByteCount; }
/****************************************************************************** * This function reads a number of bytes from an IIC chip into a * specified buffer. * * @param ChipAddress contains the address of the IIC core. * @param RegAddress contains the address of the register to write to. * @param pBuffer contains the address of the data buffer to be filled. * @param ByteCount contains the number of bytes in the buffer to be read. * This value is constrained by the page size of the device such * that up to 64K may be read in one call. * * @return The number of bytes read. A value less than the specified input * value indicates an error. * * @note None. * ******************************************************************************/ int zed_iic_axi_IicRead(zed_iic_t *pIIC, Xuint8 ChipAddress, Xuint8 RegAddress, Xuint8 *pBuffer, Xuint8 ByteCount) { Xuint8 ReceivedByteCount = 0; Xuint8 SentByteCount = 0; Xuint8 ControlReg; Xuint8 StatusReg; int cnt = 0; zed_iic_axi_t *pContext = (zed_iic_axi_t *)(pIIC->pContext); #if 1 // Make sure all the Fifo's are cleared and Bus is Not busy. do { StatusReg = Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET); //xil_printf("[%s] Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET) => 0x%02X\n\r", pContext->szName, StatusReg ); StatusReg = StatusReg & (XIIC_SR_RX_FIFO_EMPTY_MASK | XIIC_SR_TX_FIFO_EMPTY_MASK | XIIC_SR_BUS_BUSY_MASK); if ((StatusReg & XIIC_SR_RX_FIFO_EMPTY_MASK) != XIIC_SR_RX_FIFO_EMPTY_MASK) { /* * The RX buffer is not empty and it is assumed there is a stale * message in there. Attempt to clear out the RX buffer, otherwise * this loop spins forever. */ XIic_ReadReg(pContext->CoreAddress, XIIC_DRR_REG_OFFSET); } /* * Check to see if the bus is busy. Since we are master, if the bus is * still busy that means that arbitration has been lost. * * According to Product Guide PG090, October 16, 2012: * * Control Register (0x100), Bit 2 MSMS: * * "Master/Slave Mode Select. When this bit is changed from 0 to 1, * the AXI IIC bus interface generates a START condition in master * mode. When this bit is cleared, a STOP condition is generated and * the AXI IIC bus interface switches to slave mode. When this bit is * cleared by the hardware, because arbitration for the bus has been * lost, a STOP condition is not generated. (See also Interrupt(0): * Arbitration Lost in Chapter 3.)" * * According to this, it should be okay to clear the master/slave mode * select to clear a false start condition with a stop and regain * arbitration over the bus. */ if ((StatusReg & XIIC_SR_BUS_BUSY_MASK) == XIIC_SR_BUS_BUSY_MASK) { ControlReg = Xil_In8(pContext->CoreAddress + XIIC_CR_REG_OFFSET); ControlReg = ControlReg & 0xFB; // Clear the MSMS bit. Xil_Out8(pContext->CoreAddress + XIIC_CR_REG_OFFSET, ControlReg); } } while (StatusReg != (XIIC_SR_RX_FIFO_EMPTY_MASK | XIIC_SR_TX_FIFO_EMPTY_MASK)); #endif // Position the Read pointer to specific location. do { StatusReg = Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET); //xil_printf("[%s] Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET) => 0x%02X\n\r", pContext->szName, StatusReg ); if(!(StatusReg & XIIC_SR_BUS_BUSY_MASK)) { SentByteCount = XIic_DynSend(pContext->CoreAddress, ChipAddress, (Xuint8 *)&RegAddress, 1, XIIC_REPEATED_START); } cnt++; }while(SentByteCount != 1 && (cnt < 100)); // Error writing chip address so return SentByteCount if (SentByteCount < 1) { return SentByteCount; } // Receive the data. ReceivedByteCount = XIic_DynRecv(pContext->CoreAddress, ChipAddress, pBuffer, ByteCount); // Return the number of bytes received. return ReceivedByteCount; }