Help I2C communication - Pimoroni trackball

wdtamagi
Posts: 1
Joined: Thu May 19, 2022 6:31 pm

Help I2C communication - Pimoroni trackball

Postby wdtamagi » Thu May 19, 2022 7:21 pm

Hi everyone I'm a new member here at the ESP32 forum.

Just for context, I recently (maybe not so recently) built a kind of keyboard that use the ESP32S2 WROOM MCU. This keyboard uses a project called QMK for create the firmware, but since the QMK don't have support to ESP32 the creator of the project used the ESP-IDF as a kind of wrapper to the QMK and it allowed to use the ESP-IDF function inside the QMK.

The keyboard is working well, but now I'm trying to include a mini trackball from Pimoroni (https://shop.pimoroni.com/products/trac ... 2765038675)
This trackball uses the I2C for communication, the problem is that I don't have anything ready for use the I2C for ESP32 into QMK.
Looking into the code for the trackball that already exist (it's supported for other brands like Chibios and Avr) I only need one function for make it work.

Here is the code for the pimoroni trackball -> https://github.com/qmk/qmk_firmware/blo ... rackball.c
I don't have any plans to use the RGB feature, so I removed everything related to that, the only function that I will need is the "i2c_readReg" from the i2c_master file.

Here are some examples of the code that I need :
For chibios -> https://github.com/qmk/qmk_firmware/blo ... c_master.c
For avr -> https://github.com/qmk/qmk_firmware/blo ... c_master.c

I'm very newbie with C lang and with the i2c communication as well, here is what I did so far (I'm using the version 4.3 for the esp-idf):

Code: Select all

#include "quantum.h"
#include "i2c_master.h"
#include <string.h>
#include "driver/i2c.h"

#define I2C_MASTER_NUM I2C_NUM_0                              /*!< I2C port number for master dev */
#define I2C_MASTER_SCL_IO    33                               /*!< gpio number for I2C master clock */
#define I2C_MASTER_SDA_IO    34                               /*!< gpio number for I2C master data  */
#define I2C_MASTER_FREQ_HZ 100000                             /*!< I2C master clock frequency */
#define I2C_MASTER_TX_BUF_DISABLE 0                           /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0                           /*!< I2C master doesn't need buffer */

static uint8_t i2c_address;
static i2c_cmd_handle_t cmd;

static i2c_status_t esp_to_qmk(const esp_err_t status) {
    switch (status) {
        case ESP_OK:
            return I2C_STATUS_SUCCESS;
        default:
            return I2C_STATUS_ERROR;
    }
}

__attribute__((weak)) void i2c_init(void) {
    static bool is_initialised = false;
    if (!is_initialised) {
        is_initialised = true;

    int i2c_master_port = I2C_MASTER_NUM;
    i2c_config_t conf = {
        .mode = I2C_MODE_MASTER,
        .sda_io_num = I2C_MASTER_SDA_IO,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_io_num = I2C_MASTER_SCL_IO,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = I2C_MASTER_FREQ_HZ,
        // .clk_flags = 0,          /*!< Optional, you can use I2C_SCLK_SRC_FLAG_* flags to choose i2c source clock here. */
    };
        i2c_param_config(i2c_master_port, &conf);
        i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
    }
}

i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) {
    i2c_address = devaddr;
    if (length == 0) {
        return esp_to_qmk(ESP_OK);
    }
    cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (i2c_address  << 1) | I2C_MASTER_WRITE, true);
    i2c_master_write(cmd, &regaddr, 1, true);

    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (i2c_address  << 1) | I2C_MASTER_READ, true);
    i2c_master_read(cmd, data, length, 0x2);

    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM , cmd, 1000 / timeout);
    i2c_cmd_link_delete(cmd);
    return esp_to_qmk(ret);
}
Just explaining a little bit my code, since in the version 4.3 I don't have the function i2c_master_write_read_device I just tried to do the same thing looking at the source code https://github.com/espressif/esp-idf/bl ... 2c.c#L1004

I used this as reference because into the i2c simple example form the esp-idf examples folder is what is using for read the register (https://github.com/espressif/esp-idf/bl ... main.c#L42)

Here it is some pictures of the hardware connection https://imgur.com/a/qOKtnn6
I used the 4.7k resistors for pull-up

I flashed without any error this code but don't get anything rolling the trackball :( I wondering if something in my code is the problem...

Who is online

Users browsing this forum: No registered users and 134 guests