📄 sysi2cdrv.c
字号:
* i2cDoOp - i2c do operation** This function's purpose is to execute the operation as specified* by the passed command packet. Currently, the only device types* that are recognized are EEPROM types.** RETURNS: OK, always.*/int i2cDoOp ( UINT32 deviceAddress, /* device I2C bus address */ i2cCmdPckt_t *pI2cCmdPacket /* pointer to command packet */ ) { int byteCount; /* byte counter */ int statusVariable; /* local status variable */ unsigned char *pWriteData; /* pointer to write data buffer */ unsigned char *I2CDoRepeatStart = 0; /* Command interface to stop. This is for previous error exits. */ I2C_CYCLE_STOP(I2CDoRepeatStart); /* * read operation (EEPROM type devices), for each byte * perform the random read operation */ if (pI2cCmdPacket->command == I2C_READOP) { /* Read the specified number of bytes from the EEPROM. */ statusVariable = 0; if (I2C_KNOWN_STATE) { statusVariable = I2C_ERROR_KNOWN_STATE; byteCount = pI2cCmdPacket->nBlocks; } for (byteCount = 0; byteCount < pI2cCmdPacket->nBlocks; byteCount++) { if (I2C_CYCLE_START(I2CDoRepeatStart)) { statusVariable = I2C_ERROR_CYCLE_START; break; } if (I2C_CYCLE_WRITE(i2cAddressMunge (deviceAddress, pI2cCmdPacket->blockNumber + byteCount))) { statusVariable = I2C_ERROR_CYCLE_WRITE; break; } if (I2C_CYCLE_ACKIN) { statusVariable = I2C_ERROR_CYCLE_ACKIN; break; } if (I2C_CYCLE_WRITE(pI2cCmdPacket->blockNumber + byteCount)) { statusVariable = I2C_ERROR_CYCLE_WRITE; break; } if (I2C_CYCLE_ACKIN) { statusVariable = I2C_ERROR_CYCLE_ACKIN; break; } if (I2C_CYCLE_START(I2CDoRepeatStart)) { statusVariable = I2C_ERROR_CYCLE_START; break; } if (I2C_CYCLE_WRITE(i2cAddressMunge(deviceAddress | 0x01, pI2cCmdPacket->blockNumber + byteCount))) { statusVariable = I2C_ERROR_CYCLE_WRITE; break; } if (I2C_CYCLE_ACKIN) { statusVariable = I2C_ERROR_CYCLE_ACKIN; break; } if (I2C_CYCLE_READ((unsigned char *)pI2cCmdPacket->memoryAddress + byteCount)) { statusVariable = I2C_ERROR_CYCLE_READ; break; } if (I2C_CYCLE_STOP(I2CDoRepeatStart)) { statusVariable = I2C_ERROR_CYCLE_STOP; break; } /* Increment the actual count of the command packet. */ pI2cCmdPacket->aCount += 1; } /* Leave the I2C bus in a known state. */ I2C_KNOWN_STATE; /* * update the caller's command packet with status of * the operation */ pI2cCmdPacket->status = statusVariable; } /* * write operation (EEPROM type devices), for each byte * perform the byte write operation, a delay must be * exercised following each byte write */ if (pI2cCmdPacket->command == I2C_WRITOP) { /* Initialize pointer to caller's write data buffer. */ pWriteData = (unsigned char *)pI2cCmdPacket->memoryAddress; /* Write the specified number of bytes from the EEPROM. */ statusVariable = 0; if (I2C_KNOWN_STATE) { statusVariable = I2C_ERROR_KNOWN_STATE; byteCount = pI2cCmdPacket->nBlocks; } for (byteCount = 0; byteCount < pI2cCmdPacket->nBlocks; byteCount++) { if (I2C_CYCLE_START(I2CDoRepeatStart)) { statusVariable = I2C_ERROR_CYCLE_START; break; } if (I2C_CYCLE_WRITE(i2cAddressMunge(deviceAddress, pI2cCmdPacket->blockNumber + byteCount))) { statusVariable = I2C_ERROR_CYCLE_WRITE; break; } if (I2C_CYCLE_ACKIN) { statusVariable = I2C_ERROR_CYCLE_ACKIN; break; } if (I2C_CYCLE_WRITE(pI2cCmdPacket->blockNumber + byteCount)) { statusVariable = I2C_ERROR_CYCLE_WRITE; break; } if (I2C_CYCLE_ACKIN) { statusVariable = I2C_ERROR_CYCLE_ACKIN; break; } if (I2C_CYCLE_WRITE(*(pWriteData + byteCount))) { statusVariable = I2C_ERROR_CYCLE_WRITE; break; } if (I2C_CYCLE_ACKIN) { statusVariable = I2C_ERROR_CYCLE_ACKIN; break; } if (I2C_CYCLE_STOP(I2CDoRepeatStart)) { statusVariable = I2C_ERROR_CYCLE_STOP; break; } /* Increment the actual count of the command packet. */ pI2cCmdPacket->aCount += 1; /* * delay for at least 10ms to allow EEPROM to complete * the write cycle (internal operation) */ I2C_DELAY(10); } /* Leave the I2C bus in a known state. */ I2C_KNOWN_STATE; /* * update the caller's command packet with status of * the operation */ pI2cCmdPacket->status = statusVariable; } return (OK); }/******************************************************************************** i2cAddressMunge - initialize the i2c device driver** This function's purpose is to munge/modify the I2C device address* based upon the byte offset into the device. This only applies to* EEPROM type devices. Dependent upon the size of the device, A0-A2* address lines are utilized as 256 byte size page offsets.** RETURNS: munged address*/unsigned int i2cAddressMunge ( unsigned int deviceAddress, unsigned int byteOffset ) { return (deviceAddress | ((byteOffset & I2C_BYTE_NUM_MASK) >> I2C_BYTE_NUM_SHIFT)); }/******************************************************************************* i2cPciInLong - reads a longword from PCI I/O or Memory space** This function reads a longword from a specified PCI I/O or Memory address* via the PCI bridge chip. This function should be used for access* to the I/O or Memory mapped registers of a PCI device. These* registers are mapped as little-endian, so we byte reverse the data in order* to make the value returned look the same as it would in PCI space.** RETURNS: longword from address.**/LOCAL UINT32 i2cPciInLong (UINT32 * dataPtr) { /* Read a longword from the address, and reverse the bytes */ register UINT32 reversedBytes; reversedBytes = LONGSWAP(*dataPtr); return(reversedBytes); }/******************************************************************************* i2cPciOutLong - writes a longword to PCI I/O or Memory space** This function writes a longword to a specified PCI I/O or Memory address* via the PCI bridge chip. This function should be used for access* to the I/O or Memory mapped registers of a PCI device. These* registers are mapped as little-endian, so we byte reverse the data in order* to make the value written correct for the registers in PCI space.** RETURNS: N/A**/LOCAL void i2cPciOutLong ( UINT32 * dataPtr, UINT32 data ) { /* Write a long to the address, reversing the bytes */ __asm__(" stwbrx 4,0,3"); /* Sync I/O operation */ __asm__(" sync"); }/******************************************************************************* i2cPciInByte - reads a byte from PCI I/O or Memory space** This function reads a byte from a specified PCI I/O or Memory address* via the PCI bridge chip. This function should be used for access* to the I/O or Memory mapped registers of a PCI device. Since this routine* accesses only a single byte of data no address or data manipulation is* required.** RETURNS: byte from address.*/LOCAL UINT8 i2cPciInByte (UINT8 * dataPtr) { register UINT8 readMem; /* Read byte from dataPtr address and return actual value */ readMem = *dataPtr; return(readMem); }/******************************************************************************* i2cPciOutByte - writes a byte to PCI I/O or Memory space** This function writes a byte to a specified PCI I/O or Memory address* via the QSPAN bridge chip. This function should be used for writing* to the I/O or Memory mapped registers of a PCI device. Since this routine* writes only a single byte of data no address or data manipulation is* required.** RETURNS: N/A**/LOCAL void i2cPciOutByte ( UINT8 * dataPtr, UINT8 data ) { __asm__("stbx 4,0,3"); /* Write a byte to address */ __asm__("sync"); /* Sync I/O operation */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -