Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I2C Mux API #12

Open
qermit opened this issue Sep 9, 2015 · 1 comment
Open

I2C Mux API #12

qermit opened this issue Sep 9, 2015 · 1 comment

Comments

@qermit
Copy link
Contributor

qermit commented Sep 9, 2015

The boards differs from version to version.

  • In AFCv2 the "mux" should be done by changing pin function
  • In AFCv3 and AFCv3.1 i2c mux chip has to be controlled.

Additionally I would like to add i2c chip_id feature which will be mapped to bus_id and interface_id (I2C0, I2C1, I2C2).
Bus_id is an abstraction with is mapped to interface_id and mux_index. If mux_index is -1 no muxing should be done on this virtual bus
I've found followed virtual buses:

  • I2C_BUS_IPMB_ID
  • I2C_BUS_FMC1_ID
  • I2C_BUS_FMC2_ID
  • I2C_BUS_CPU_ID
  • I2C_BUS_RTM_ID
  • I2C_BUS_CLOCK_ID
  • I2C_BUS_FPGA_ID

Examples:

  • AFCv2 will map I2C_BUS_CPU_ID and I2C_BUS_CLOCK_ID to interface_id=I2C1/mux_index=1 (are the same bus in fact) while I2C_BUS_FMC1_ID will be mapped to interface_id=I2C2/mux_index=-1 (no muxing)
  • AFCv3 will map I2C_BUS_CPU_ID will be mapped to interface_id=I2C1/mux_index=-1 while I2C_BUS_FMC1_ID wille be mapped to interface_id=I2C1/mux_index=0
  • AFCv3.1 will map I2C_BUS_CPU_ID will be mapped to interface_id=I2C1/mux_index=-1 while I2C_BUS_FMC1_ID wille be mapped to interface_id=I2C2/mux_index=0

I hope next version of AFC and AFCK will have separate muxes uc for FPGA and CPU so this muxing procedure will be 100% safe.

I2cMux features and will rely on board version detection, however I'm preparing also a fallback procedure to discover i2c bus structure and board version.

The code should behave in followed way:

  • task Z wants to start talk with i2c chip_id=X (or just bus_id=Y)
  • Z executes function xI2cMuxTakeByChipID that first translates chip_id to interface_id
  • xI2cMuxTakeByChipID tries to take i2c semaphore by calling xI2cTake and returns pdFail in case of failure
  • next it checks current bus_id and tries to change it with mux_hook function
  • xI2cMuxTakeByChipID writes parameters to pointer chip_info and returns with pdSuccess (or pdFail)
  • now task Z may start talking to i2c chip (slave_address and interface_id were received from xI2cMuxTakeByChipID), xTimeout is set to 0 because semaphore was already taken by xI2cMuxTakeByChipID
  • at the end task must give semaphore back with xI2cGive (or another one))

If it's required (i2c chip presence detection) a task may use xI2CMuxTakeByBusId/xI2CMuxGiveByBusId or just xI2cTake/xI2cGive.

I'm proposing followed API at the moment:

  • xI2cTake(interface_id, TimeTick_t xTimeout);
  • xI2cGive(interface_id);
  • xI2cWriteRead(interface_id, *xtransfer, TimeTick_t xTimeout);
  • xI2cWrite(interface_id, slave_address, char *wrData, wrLen, TimeTick_t xTimeout)
  • xI2cRead(interface_id, slave_address, char *rdData, uint8_t rdLen, TimeTick_t xTimeout);
  • xI2cCmdRead(interface_id, slave_address, char cmd, char *rdData, uint8_t rdLen, TimeTick_t xTimeout);
  • xI2CMuxTakeByChipId(chip_id, struct i2c_chipinfo * chip_info, TimeTick_t xTimeout);
  • xI2CMuxTakeByBusId(bus_id, struct i2c_businfo * bus_info, TimeTick_t xTimeout);
  • xI2CMuxGiveByChipId(chip_id);
  • xI2CMuxGiveByBusId(bus_id);

Optional:

  • xI2cMuxBusRegister(struct businfo *bus_info);
  • xI2cMuxBusGetInfo(struct businfo *bus_info);
  • xI2cMuxChipRegister(struct chipinfo *chip_info);
    xI2cMuxChipGetInfo(chip_id, struct chipinfo *chip_info);
  • vI2cLayoutSetup(???)
@henrique-silva
Copy link
Contributor

I agree that we need to improve the I2C access functions, since our firmware must be compatible across different versions of AFC, the mux access should be taken in account.
Couldn't we use a "bus scan" method to know if there's any I2C mux IC present? Since the PCA9547 slave address has a fixed part (upper 4 bits - "1110" ) we could ping the 7 left combinations that are hardware defined and see which of them ACKs our signal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants