I2C Master Registers

btashton
Posts: 14
Joined: Thu Jul 02, 2020 6:34 am

I have been digging through the Reference Manual and the Datasheet for this but all I have found are the EXT_FFE_CTRL registers for interacting with the wishbone bus.
For SPI Master the wishbone registers are defined, but I could find no such documentation for the I2C interface.

Once again the HAL has some information, but even that has some conflicting information around the pre-scaler registers
https://github.com/QuickLogic-Corp/qorc ... _i2c.c#L93

If you have any documentation on this it would be much appreciated.
gmartin
Posts: 17
Joined: Thu May 14, 2020 2:50 am

I have your request and am tracking down the information.. Thanks for finding all these missing/conflicting pieces of Information.
btashton
Posts: 14
Joined: Thu Jul 02, 2020 6:34 am

Thank you Greg I appreciate it. Also I want to eventually support more of the low power operation of this chip, but while Section 32 speaks in great detail to the theory of operation for the Power System and refers to registers, I could not find a register map for this system.
gmartin
Posts: 17
Joined: Thu May 14, 2020 2:50 am

Attached is a partial register list. This information is being incorporated into the TRM, but here is an early dump. The I2C registers are part of the EXTRegFFE section. Ive include the PMU registers also. Let me know if you need additional information or clarification.
The I2C core is from OpenCores.
Partial_EOSS_Regs.xlsx
(45.87 KiB) Downloaded 8122 times
I2C_specs.pdf
(231.7 KiB) Downloaded 8743 times
btashton
Posts: 14
Joined: Thu Jul 02, 2020 6:34 am

This is great Greg. Thanks for the detailed docs, I'll see how far I get this week.
btashton
Posts: 14
Joined: Thu Jul 02, 2020 6:34 am

I am running into some issues communicating on the wishbone bus. After I start the first transfer the wb_ms_start bit in the CSR register (0x008) never goes low (busy is low)
I have verified that the FFE X1 and X4 clocks are correct via the debug pad mux interface and bringing them out to a pad. One bit that was unclear from the docks in the CSR was "mux_wb_sm" the HAL does not seem to set this.

The code looks something like this:

Code: Select all

  /* Power FFE subsystem and clock domains */

  putreg32(0x0, EOSS3_PMU_FFE_PWR_MODE_CFG);
  putreg32(0x0, EOSS3_PMU_FFE_PD_SRC_MASK_N);
  putreg32(0x0, EOSS3_PMU_FFE_WU_SRC_MASK_N);

  /* Awaken FFE */

  putreg32(0x01, EOSS3_PMU_FFE_FB_PF_SW_WU);

  /* Wait for FFE to go active */

  while((getreg32(EOSS3_PMU_FFE_STATUS) & 0x01) == 0);

  /* Make sure Clock C is using HSO
   * Set up Clock 8 FFE X4 (Clock Control C) to 40MHz (HSO / 2)
   * Then enable gate for X1
   * 
   * Also configure C1 Gate (already div to 10MHz) */


  putreg32((2 - 2) | (1 << 9), EOSS3_CLK_CONTROL_C_0);
  putreg32(0xf, EOSS3_CLK_C08_X1_GATE);
  putreg32(0x1, EOSS3_CLK_C08_X4_GATE);
  putreg32(0, EOSS3_CLK_SWITCH_FOR_C);

  putreg32(0x29f, EOSS3_CLK_C01_GATE);

  putreg32(0x3, EOSS3_CLK_FFE_SW_RESET);
  putreg32(0x0, EOSS3_CLK_FFE_SW_RESET);


  /* i2c pads would be configured here (removed) */
  
  
  /* Set pre-scaler */

  while (eoss3_wb_transmit(0x00, 19, WB_ADDR_I2C0_SLV_SEL) != OK);
  while (eoss3_wb_transmit(0x01, 0, WB_ADDR_I2C0_SLV_SEL) != OK);

The transmit block looks like this

Code: Select all

int eoss3_wb_transmit(uint8_t addr, uint8_t val, uint8_t sel)
{
  uint32_t status = getreg32(EOSS3_FFE_CSR);

  if (!((status & FFE_CSR_BUSY) || (status & FFE_CSR_WB_MS_START)))
    {
      putreg32(
        (addr << FFE_WB_ADDR_ADDR_SHIFT) | (sel << FFE_WB_ADDR_SLV_SEL_SHIFT),
        EOSS3_FFE_WB_ADDR);
      putreg32(val, EOSS3_FFE_WDATA);
      switch (sel)
        {
          case WB_ADDR_SPI0_SLV_SEL:
            {
              putreg32(
                FFE_CSR_SPI0_MUX | FFE_CSR_WB_MS_WEN | FFE_CSR_WB_MS_START,
                EOSS3_FFE_CSR
              );
              break;
            }
          case WB_ADDR_I2C0_SLV_SEL:
            {
              putreg32(
                FFE_CSR_I2C0_MUX | FFE_CSR_WB_MS_WEN | FFE_CSR_WB_MS_START,
                EOSS3_FFE_CSR
              );
              break;
            }
          case WB_ADDR_I2C1_SLV_SEL:
            {
              putreg32(
                FFE_CSR_I2C1_MUX | FFE_CSR_WB_MS_WEN | FFE_CSR_WB_MS_START,
                EOSS3_FFE_CSR
              );
              break;
            }
          default:
            {
              return -ENXIO;
            }
        }
      return OK;
    }
  return -EBUSY;
}
gmartin
Posts: 17
Joined: Thu May 14, 2020 2:50 am

Are you still having issues with the wishbone accesses? I see you have restructured the eoss3_hal_wb.c functionality. assuming your attempting to access an I2C device, have you programmed the IO PAD and provided appropriate pullup resistors?

I found an updated version of the I2C specification that corrects some information on the prescale registers to match the implementation on chip.
I2C_specs_mod.pdf
(403.16 KiB) Downloaded 10021 times
btashton
Posts: 14
Joined: Thu Jul 02, 2020 6:34 am

Yes I am still having issues with the wishbone access. For some context I am adding support to the Apache NuttX RTOS (which just got initial support merged in today), so none of the code I am working with uses the HAL, I have just been referring to it when I hit confusion with the documentation. My suspicion is that something is not turned on or a clock is not enabled for the wishbone bus since it is the MS_START bit that is not clearing.

The IO pads are configured for i2c but I think this issue is even before the EOS is trying to drive the pins.

That updated doc is more clear on the prescaler thank you.
gmartin
Posts: 17
Joined: Thu May 14, 2020 2:50 am

Looking more into your issues. Please check the FFE Power Domain is enabled. We have an app note on setting up the FFE and accessing the I2C. It will be ready in a day or so, but here is a relevant snippet that is part of a jlink script -- hope this helps in the meantime.
; setup IO0 and IO1 for SCL and SDA
w4 0x40004c00 0x968
w4 0x40004c04 0x968
w4 0x40004d00 0x1
w4 0x40004d0c 0x1

; check FFE power status and enable
mem32 0x40004490 0x1
w4 0x40004610 0x1
mem32 0x40004490 0x1

; set up FFE clocks
w4 0x40004040 0x29f
w4 0x40004048 0x1
w4 0x4000404C 0xF

; write 0x1 to register 0x10 of device address 0x98
; setup using I2C0 to write I2C address
w4 0x4004a000 0x3
w4 0x4004a004 0x98
w4 0x4004a008 0x23
w4 0x4004a000 0x4
w4 0x4004a004 0x90
w4 0x4004a008 0x23
btashton
Posts: 14
Joined: Thu Jul 02, 2020 6:34 am

This is fairly close to what I already have, but there are a couple differences:
* The pre-scaler and configuration registers are not being written to, so I don't see how this would actually write
* There is no check between the two writes to the bus. This is where I am running into trouble. I write 0x23 to 0x4004a008 as done here, but I check for the busy bit and wb_ms_start to be cleared indicating that the transaction is complete on the bus, but I do not see the wb_ms_start ever get cleared.

Code: Select all

; write 0x1 to register 0x10 of device address 0x98
; setup using I2C0 to write I2C address
w4 0x4004a000 0x3
w4 0x4004a004 0x98
w4 0x4004a008 0x23
w4 0x4004a000 0x4
w4 0x4004a004 0x90
w4 0x4004a008 0x23
Post Reply