I2C example wanted

bbx10node
Posts: 11
Joined: Thu Sep 29, 2016 5:25 am

I2C example wanted

Postby bbx10node » Thu Sep 29, 2016 5:52 am

I am looking for an I2C example using either I2C controller. I read the i2c chapter in the technical reference manual (TRM) but have not been able to get very far. Reading i2c registers such as I2C0.fifo_conf and I2C0.ctr show they have reasonable values according to the TRM. However, writing to the registers does not change the value.

Code: Select all

    printf("ctr %x\n", I2C0.ctr.val);
    I2C0.ctr.ms_mode = 1;
    I2C0.ctr.clk_en = 1;
    I2C0.ctr.trans_start = 1;
    printf("ctr %x\n", I2C0.ctr.val);
Both printf's show the same value. I also tried using the GPIO register method GPIO_REG_WRITE instead of i2c struct. Reading the register returns 0.

Code: Select all

    volatile uint32_t I2C0_RAM[32];
    GPIO_REG_WRITE(I2C_FIFO_START_ADDR_REG(0), I2C0_RAM);
    printf("fifo_start_addr_reg %x @ %x I2C0_RAM %x\n",
            I2C_FIFO_START_ADDR_REG(0),
            GPIO_REG_READ(I2C_FIFO_START_ADDR_REG(0)),
            (uint32_t)I2C0_RAM);

fifo_start_addr 3ff53100 @ 0 I2C0_RAM 3ffb1dc4
I can post more of my code such the pin mapping but since it does not work, it is probably not helpful to anyone.

ESP_Sprite
Posts: 9709
Joined: Thu Nov 26, 2015 4:08 am

Re: I2C example wanted

Postby ESP_Sprite » Thu Sep 29, 2016 7:24 am

Have you enabled the clock to the I2C peripheral? Something like

Code: Select all

SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG,DPORT_I2C0_CLK_EN);
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,DPORT_I2C0_RST);
(off the top of my head) should do the trick.

bbx10node
Posts: 11
Joined: Thu Sep 29, 2016 5:25 am

Re: I2C example wanted

Postby bbx10node » Thu Sep 29, 2016 9:48 am

Thanks, enabling the clock helps a lot! Configuring/writing the i2c controller registers works. I will hook up scope later and see if there is any transitions on the i2c SCL pin. Of course, at lot could still be going wrong in my code.

Here is my pin muxing code.

Code: Select all

    gpio_config_t io_conf;
    io_conf.intr_type = GPIO_INTR_DISABLE;                 //disable interrupt
    io_conf.mode = GPIO_MODE_INPUT_OUTPUT_OD;              //set as input/output mode
    io_conf.pin_bit_mask = GPIO_SEL_21 | GPIO_SEL_22;      //bit mask of the pins that you want to set,e.g.GPIO21/22
    io_conf.pull_down_en = 0;                              //disable pull-down mode
    io_conf.pull_up_en = 1;                                //enable pull-up mode
    gpio_config(&io_conf);                                 //configure GPIO with the given settings
    /*
     * Configure GPIO matrix. Map I2C controller 0 to pins 21,22.
     */
    gpio_matrix_out(21, I2CEXT0_SCL_OUT_IDX, 0,  0);       //set output signal for io_matrix
    gpio_matrix_in (21, I2CEXT0_SCL_IN_IDX, 0);            //set input  signal for io_matrix
    gpio_matrix_out(22, I2CEXT0_SDA_OUT_IDX, 0,  0);       //set output signal for io_matrix
    gpio_matrix_in (22, I2CEXT0_SDA_IN_IDX, 0);            //set input  signal for io_matrix

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: I2C example wanted

Postby kolban » Thu Sep 29, 2016 1:49 pm

This feels like a very low level interface to I2C. Are there plans for high level interfaces to I2C and SPI in the future?
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

ESP_Sprite
Posts: 9709
Joined: Thu Nov 26, 2015 4:08 am

Re: I2C example wanted

Postby ESP_Sprite » Thu Sep 29, 2016 2:29 pm

Yes, there are. The app team is adding drivers to esp-idf which are more highlevel and multi-thread compatible where it makes sense. SPI and I2C drivers will also arrive in esp-idf in due time.

bbx10node
Posts: 11
Joined: Thu Sep 29, 2016 5:25 am

Re: I2C example wanted

Postby bbx10node » Sat Oct 01, 2016 2:58 am

I am looking at I2C to get a better idea of how things work at the low level. I suspect Expressif will release i2c drivers before I get anything useful working.

I noticed the 0.9 release adds the following to enable/disable controllers/modules. Does leaving unused modules disabled save power? Versus enabling everything on power up.

I do not see ADCs in in the list. Are the ADCs enabled/disabled some other way because they route thru the RTC IO mux?

typedef enum {
PERIPH_LEDC_MODULE = 0,
PERIPH_UART0_MODULE,
PERIPH_UART1_MODULE,
PERIPH_UART2_MODULE,
PERIPH_I2C0_MODULE,
PERIPH_I2C1_MODULE,
PERIPH_I2S0_MODULE,
PERIPH_I2S1_MODULE,
PERIPH_TIMG0_MODULE,
PERIPH_TIMG1_MODULE,
PERIPH_PWM0_MODULE,
PERIPH_PWM1_MODULE,
PERIPH_PWM2_MODULE,
PERIPH_PWM3_MODULE,
PERIPH_UHCI0_MODULE,
PERIPH_UHCI1_MODULE,
} periph_module_t;

void periph_module_enable(periph_module_t periph);
void periph_module_disable(periph_module_t periph);

jimbob
Posts: 29
Joined: Fri Aug 05, 2016 10:47 pm

Re: I2C example wanted

Postby jimbob » Mon Oct 24, 2016 11:15 am

I'm trying to get I2C up and running and struggling. I'm trying to send various sequences, but basically for my attempts I just get a pulse on scl followed by a pulse on sda and then both lines stay low.

Firstly, what should I be setting my pins as? Even though I2C lines can be considered bi-directional, and allowing for clock-stretching I'd assume they should be GPIO_MODE_OUTPUT_OD. I've looked in the ESP arduino example and SCL gets setup as OUTPUT and SDA gets setup as OUTPUT_OD. I've got external pullup resistors in my circuit, but hypothetically, if I didn't have them and were to enable pullups on the GPIO would these still act on the outputs?

Also, how does it relate to I2C_S{CL,DA}_FORCE_OUT flags in the I2C_CTR_REG?

Secondly, the clk_en bit of the I2C_CTR_REG isn't mentioned in the technical reference manual, but is in the C ctr structure. I assume it should be 1 for normal operation?

Thanks.

User avatar
ESP_Me-no-dev
Posts: 80
Joined: Mon Jan 04, 2016 6:30 pm

Re: I2C example wanted

Postby ESP_Me-no-dev » Thu Oct 27, 2016 5:46 am

you can have a look HERE and HERE for example on how it's implemented in Arduino.

jimbob
Posts: 29
Joined: Fri Aug 05, 2016 10:47 pm

Re: I2C example wanted

Postby jimbob » Thu Oct 27, 2016 10:06 pm

thanks -- that's where I was looking. I foolishly believed that when I read the line that set pins as output they were set just as outputs... ;)

The following two lines in https://github.com/espressif/arduino-es ... hal-gpio.c

make the magic difference! and enable inputs on all pins -- independent of whether they're set as outputs or not. -- without them I2C doesn't work.

Code: Select all

pinFunction |= FUN_IE;//input enable but required for output as well?
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioToFn[pin]) = pinFunction;
It took me about a day just to track down that one.

Also the struct

Code: Select all

i2c->dev->fifo_data.data
used in the arduino code refers to a register that isn't mentioned in the technical reference. It appears to put data into the i2c fifo ram.

The arduino implementation also doesn't appear to use the hardware state machine to it's full potential. I'm grateful for the example, but I had gone though it before posting, and it has led to some head scratching and spending a lot of time chasing things out.

User avatar
ESP_Me-no-dev
Posts: 80
Joined: Mon Jan 04, 2016 6:30 pm

Re: I2C example wanted

Postby ESP_Me-no-dev » Fri Oct 28, 2016 12:37 am

Yes, Arduino code has a bit different(simpler) requirements to run and as such implementing ISRs and other hardware trickery is pointless.

Who is online

Users browsing this forum: jsmith56x and 298 guests