Program I2C using C on Grove Vision AI V2 (WE2 processor)

Hello

I have been “playing” (fighting describes it better :slightly_smiling_face: ) with the Grove AI Vision V2 dev board, that has the WE2 processor. (Himax WiseEye2 AI processor)

I’m at a state where I can build and flash the Grove Vision AI V2 dev board according to the Seeed_Grove_Vision_AI_Module_V2 repository.

Then I downloaded the allon_sensor_tflm_s_only uVision zip so I have some form of an IDE after spending quite a while in vim+grep while trying to make sense of the source code.

I ended up with the project in uVision, and finding my way to manage my runtime environment and enable i2c_comm, as shown in the image.

Next, plugging the esp32s3 on top of the Grove AI V2, I am reading the available I2C slaves with the example i2c scanner program Arduino Playground - I2cScanner. It reads:

I2C device found at address 0x28
I2C device found at address 0x79 

Only during flashing of the Grove Vision AI V2 dev board, I additionally get:

I2C device found at address 0x28
I2C device found at address 0x62 
I2C device found at address 0x79 

(The same output appears when I load a sample from the SenseCraft website)

But I want to create an own slave, how do I do that? (Is there a documentation I am not aware of?) My “best guess” after trying various things (e.g. using ARM’s I2C itself, which caused linker errors…) are the sample codes provided within hx_drv_iic.h, which comes with the zip I mentioned above, which is also found in the GitHub repository. Basically this: (not shown everything…)

* <pre>
*    Sample code: I2C master 0 pin mux configuration and initialization
*      /// The output pin of I2C Master 0 is defined by the user application.
*      hx_drv_scu_set_PB7_pinmux(SCU_PB7_PINMUX_I2C_M_SCL);
*      hx_drv_scu_set_PB8_pinmux(SCU_PB8_PINMUX_I2C_M_SDA);
*   
*      /// initializes the I2C Master 0 with SCL speed of 400 KHz
*      hx_drv_i2cm_init(USE_DW_IIC_0, HX_I2C_HOST_MST_0_BASE, DW_IIC_SPEED_FAST);
*
*    Usage-1: Transmit data using interrupt mode with I2C master 0
*      void i2cm_0_tx_cb()
*      {
*          xprintf("[%s] \n", __FUNCTION__);
*      }
*
*      uint8_t wbuffer[32] = {0};
*      uint32_t i, data_size = 32;
*      for(i = 0; i < data_size; i++)
*      {
*          wbuffer[i] = i;
*          xprintf("wbuffer[%d]:0x%02x \n", i, wbuffer[i]);
*      }
*
*      hx_drv_i2cm_interrupt_write(USE_DW_IIC_0, 0x24, wbuffer, data_size, i2cm_0_tx_cb);
*
*
*    Usage-2: Receive data using interrupt mode with I2C master 0
*      uint8_t rbuffer[32] = {0};
*      uint32_t i, data_size = 32;
*      volatile uint32_t i2c_mst_rx_done = 0;
*      uint32_t retry = 10;
*
*      void i2cm_0_rx_cb()
*      {
*          i2c_mst_rx_done = 1;
*          xprintf("[%s] \n", __FUNCTION__);
*      }
*
*      hx_drv_i2cm_interrupt_read(USE_DW_IIC_0, 0x24, rbuffer, data_size, i2cm_0_rx_cb);
*
*      while(i2c_mst_rx_done == 0){
*          if(retry){
*              hx_drv_timer_delay_ms(TIMER_ID_0, 100, TIMER_STATE_DC);
*              retry--;
*          }else{
*              break;
*          }
*      }
*
*      if(i2c_mst_rx_done){
*          for(i = 0; i < data_size; i++){
*              xprintf("[%d]: 0x%02x \n", i, rbuffer[i]);
*          }
*      }
*

So I tried example 2 and plopped it 1:1 into the app_main function. However, nothing changes on the i2c scanner. Then example 1, and also nothing changed. I tried various other functions, e.g. hx_drv_i2cs_interrupt_read (i2cs) or the things from i2c_comm.h - without success.

Did anyone else run into this problem and give me pointers to what I am supposed to do?

Thanks

Hi there,

And Welcome here…

So , I didn’t get the memo… LOL Folks are trying all sorts of no standard uses for hardware and software this is GREAT :grin:
Here is what I can comment on, I use the trained model I posted up on here a while back. This hardware is getting a little dated IMO. Senscraft should roll out some new stuff. But I digress..

  • 0x79 is almost certainly the camera sensor (OV5647/OV5640-style). Those guys use 0x78/0x79 as their 8-bit write/read codes; scanners often show 0x79 as a “device”. Arducam+1
  • 0x28 is probably another onboard peripheral (IMU / temp / etc.) that the WiseEye chip talks to internally.
  • 0x62 is the Grove Vision AI module itself, but only when the stock / SenseCraft (or bootloader) firmware configures an I²C slave interface on that address. That’s exactly what people see in other threads: 0x62 appears when the factory firmware is running and responds with JSON-like messages over I²C/UART.

Only during flashing or SenseCraft sample I additionally get 0x62

…that’s the giveaway :eye:. When it boots into Your own Himax firmware, you’re almost certainly not enabling the I²C slave peripheral at all, so from the ESP32-S3’s point of view, there is no device at that address.
The bootloader isn’t “hiding” anything your firmware just doesn’t recreate what SenseCraft was doing.

Big conceptual mistake in this attempt:

  • The snippet he pasted from hx_drv_iic.h is I²C master code:
    • hx_drv_i2cm_init(...)
    • hx_drv_i2cm_interrupt_write(...)
    • hx_drv_i2cm_interrupt_read(...)
  • A master API will never make a new I²C slave show up to an external scanner. That code is for the WiseEye talking out to other chips on the board, not for exposing itself as a slave to the ESP32.
    To actually “create Your own slave” on the Grove Vision AI side, you’d have to:
  1. Use the slave driver (hx_drv_i2cs_*), not the master one.
  2. Configure the same I²C instance + pinmux that is wired to the Grove connector (whatever SCU pinmux the SenseCraft firmware uses). I have never used it…fwiw, others have attempted it though, check the Himax support :crossed_fingers:
  3. Set a slave address (e.g. 0x62 or something else), enable the peripheral and write ISR/callback code that handles read/write from the external master.
  4. Make sure nothing in his firmware is still using that peripheral as a master at the same time.

You really need to start from a Himax example that already exposes an I²C slave to a host (or diff the SenseCraft firmware to see how they configure I²C slave), and use hx_drv_i2cs_* with the Grove I²C pins, not i2cm.

HTH
GL :santa_claus: PJ :v: