📄 sysmoti2c.c
字号:
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); } } else { I2C_KNOWN_STATE(unit); return ERROR ; } /* Leave the I2C bus in a known state. */ I2C_KNOWN_STATE(unit); /* * update the caller's command packet with status of * the operation */ pI2cCmdPacket->status = statusVariable; return OK ; }/******************************************************************************** i2cDoOpAD7417 - write the specified number of blocks** This function's purpose is to write the specified number of* blocks to the specified device.** RETURNS: Number of bytes written, or ERROR if bad request.** ERRNO*/int i2cDoOpAD7417 ( int unit, UINT32 deviceAddress, /* device I2C bus address */ i2cCmdPckt_t *pI2cCmdPacket /* pointer to command packet */ ) { i2cDrvRoutines_t *pRoutine; /* low level routines table pointer */ int byteCount; /* byte counter */ int statusVariable; /* local status variable */ unsigned char *pWriteData; /* pointer to write data buffer */ /* Modes: 0) writing to address pointer register for subsequent read 1) single byte read 2) double byte read (Toti, Thyst, ADC registers) 3) writing to address pointer register then single byte of data 4) writing to address pointer register then 2 bytes of data (Toti, Thyst, ADC registers) 2 1 0 0 0 0 temperature value (ro) - 2 bytes 0 0 1 config register (r/w) - 1 byte 0 1 0 Thyst (r/w) - 2 bytes 0 1 1 Toti (r/w) - 2 bytes 1 0 0 ADC (ro) - 2 byes 1 0 1 Config2 (r/w, msb only) - 1 byte NOTE: pI2cCmdPacket->nBlocks is used to figure out if it is a single or double byte read or write. */ if ( (pI2cCmdPacket->blockNumber < 0) || (pI2cCmdPacket->blockNumber > 5) ) { printf("Invalid register number %d\n", pI2cCmdPacket->blockNumber); return ERROR ; } switch ( pI2cCmdPacket->blockNumber ) { case 0: case 2: case 3: case 4: if ( pI2cCmdPacket->nBlocks != 2 ) { printf("Invalid register size %d, should be 2.\n", pI2cCmdPacket->nBlocks); return ERROR ; } break; case 1: case 5: if ( pI2cCmdPacket->nBlocks != 1 ) { printf("Invalid register size %d, should be 1.\n", pI2cCmdPacket->nBlocks); return ERROR ; } break; } /* Initialize pointer to driver routines table. */ pRoutine = i2cDrvRoutinesTables[I2C_DRV_TYPE]; /* single byte read/write */ if ( pI2cCmdPacket->command == I2C_READOP ) { statusVariable = 0; if ( I2C_KNOWN_STATE(unit) ) { statusVariable = I2C_ERROR_KNOWN_STATE; byteCount = pI2cCmdPacket->nBlocks; goto errorEnd ; } if ( I2C_CYCLE_START(unit) ) { statusVariable = I2C_ERROR_CYCLE_START; goto errorEnd ; } /* device address */ if ( I2C_CYCLE_WRITE(unit,i2cAddressMunge(deviceAddress)) ) { statusVariable = I2C_ERROR_CYCLE_WRITE; goto errorEnd ; } if ( I2C_CYCLE_ACKIN(unit) ) { statusVariable = I2C_ERROR_CYCLE_ACKIN; goto errorEnd ; } /* address register pointer */ if ( I2C_CYCLE_WRITE(unit,pI2cCmdPacket->blockNumber) ) { statusVariable = I2C_ERROR_CYCLE_WRITE; goto errorEnd ; } if ( I2C_CYCLE_ACKIN(unit) ) { statusVariable = I2C_ERROR_CYCLE_ACKIN; goto errorEnd ; } if ( I2C_CYCLE_STOP(unit) ) { statusVariable = I2C_ERROR_CYCLE_STOP; goto errorEnd ; } sysMpc834xMsDelay (1); if ( I2C_CYCLE_START(unit) ) { statusVariable = I2C_ERROR_CYCLE_START; goto errorEnd ; } /* device address */ if ( I2C_CYCLE_WRITE(unit,i2cAddressMunge(deviceAddress)|0x1) ) { statusVariable = I2C_ERROR_CYCLE_WRITE; goto errorEnd ; } if ( I2C_CYCLE_ACKIN(unit) ) { statusVariable = I2C_ERROR_CYCLE_ACKIN; goto errorEnd ; } if ( I2C_CYCLE_READ(unit,(unsigned char *)pI2cCmdPacket->memoryAddress+0,0) ) { statusVariable = I2C_ERROR_CYCLE_READ; goto errorEnd ; } /* Increment the actual count of the command packet. */ pI2cCmdPacket->aCount += 1; if ( pI2cCmdPacket->nBlocks == 2 ) { if ( I2C_CYCLE_READ(unit,(unsigned char *)pI2cCmdPacket->memoryAddress+1,0) ) { statusVariable = I2C_ERROR_CYCLE_READ; goto errorEnd ; } /* Increment the actual count of the command packet. */ pI2cCmdPacket->aCount += 1; } if ( I2C_CYCLE_STOP(unit) ) { statusVariable = I2C_ERROR_CYCLE_STOP; goto errorEnd ; } /* * update the caller's command packet with status of * the operation */ pI2cCmdPacket->status = statusVariable; } else if ( pI2cCmdPacket->command == I2C_WRITOP ) { /* Initialize pointer to caller's write data buffer. */ pWriteData = (unsigned char *)pI2cCmdPacket->memoryAddress; statusVariable = 0; if ( I2C_KNOWN_STATE(unit) ) { statusVariable = I2C_ERROR_KNOWN_STATE; byteCount = pI2cCmdPacket->nBlocks; goto errorEnd ; } if ( I2C_CYCLE_START(unit) ) { statusVariable = I2C_ERROR_CYCLE_START; goto errorEnd ; } /* device address */ if ( I2C_CYCLE_WRITE(unit,i2cAddressMunge(deviceAddress)) ) { statusVariable = I2C_ERROR_CYCLE_WRITE; goto errorEnd ; } if ( I2C_CYCLE_ACKIN(unit) ) { statusVariable = I2C_ERROR_CYCLE_ACKIN; goto errorEnd ; } /* address register pointer */ if ( I2C_CYCLE_WRITE(unit,pI2cCmdPacket->blockNumber) ) { statusVariable = I2C_ERROR_CYCLE_WRITE; goto errorEnd ; } if ( I2C_CYCLE_ACKIN(unit) ) { statusVariable = I2C_ERROR_CYCLE_ACKIN; goto errorEnd ; } if ( I2C_CYCLE_WRITE(unit,*(pWriteData+0)) ) { statusVariable = I2C_ERROR_CYCLE_WRITE ; goto errorEnd ; } if ( I2C_CYCLE_ACKIN(unit)) { statusVariable = I2C_ERROR_CYCLE_ACKIN; goto errorEnd ; } /* Increment the actual count of the command packet. */ pI2cCmdPacket->aCount += 1; if ( pI2cCmdPacket->nBlocks == 2 ) { if ( I2C_CYCLE_WRITE(unit,*(pWriteData+1)) ) { statusVariable = I2C_ERROR_CYCLE_READ; goto errorEnd ; } if ( I2C_CYCLE_ACKIN(unit) ) { statusVariable = I2C_ERROR_CYCLE_ACKIN; goto errorEnd ; } /* Increment the actual count of the command packet. */ pI2cCmdPacket->aCount += 1; } if ( I2C_CYCLE_STOP(unit)) { statusVariable = I2C_ERROR_CYCLE_STOP; goto errorEnd ; } /* * update the caller's command packet with status of * the operation */ pI2cCmdPacket->status = statusVariable; } else { I2C_KNOWN_STATE(unit); return ERROR ; } errorEnd: /* Leave the I2C bus in a known state. */ I2C_KNOWN_STATE(unit); /* * update the caller's command packet with status of * the operation */ pI2cCmdPacket->status = statusVariable; return OK ; }/******************************************************************************** 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 the ATMEL AT24C256 and the Analog Devices* AD7417ARU.** RETURNS: OK, always.** ERRNO*/int i2cDoOp ( int unit, UINT32 deviceAddress, /* device I2C bus address */ i2cCmdPckt_t * pI2cCmdPacket /* pointer to command packet */ ) {#ifdef I2C_DRIVER_DEBUG logMsg("i2cDoOp: deviceAddress - 0x%x, pI2cCmdPacket - 0x%x\n", deviceAddress, pI2cCmdPacket,3,4,5,6);#endif /* Command interface to stop. This is for previous error exits. */ I2C_CYCLE_STOP(unit); switch(pI2cCmdPacket->deviceType) { case I2C_DEVICE_TYPE_EEPROM_AT24C256: if ( i2cDoOpAT24C256(unit, deviceAddress, pI2cCmdPacket) != OK ) return ERROR ; break; case I2C_DEVICE_TYPE_TEMP_SENSOR_AD7417: if ( i2cDoOpAD7417(unit, deviceAddress, pI2cCmdPacket) != OK ) return ERROR ; break; case I2C_DEVICE_TYPE_IOPORT_PCA9555: if ( i2cDoOpPCA9555(unit, deviceAddress, pI2cCmdPacket) != OK ) return ERROR ; break; default : return ERROR ; } 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** ERRNO*/unsigned int i2cAddressMunge ( unsigned int deviceAddress ) { return((deviceAddress<<1)&0xfe) ; }/* AT24C256 -> 512 pages of 64 bytes each, 15 bits reqd for addressing *//* 64 bytes -> address masked with 0xffc0 *//* lsb of device address is for 0/1 read/write *//******************************************************************************* i2cInByte - reads a byte from I2C Regs.** 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.** ERRNO*/LOCAL UINT8 i2cInByte ( UINT32 dataPtr ) { /* Read a longword from the address, and reverse the bytes */ UINT8 *ptr = (UINT8*)dataPtr ; return(*ptr); }/******************************************************************************* i2cOutByte - writes a byte to I2C Regs.** 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** ERRNO*/LOCAL void i2cOutByte ( UINT32 dataPtr, UINT8 data ) { UINT8 * ptr = (UINT8*)dataPtr ; *ptr = data ; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -