Closed will-emmerson closed 3 years ago
Thanks, @will-emmerson !
Can you confirm that you've set the slave address?
#define SLAVE_ADDR 0x0
I'm fairly sure the SLAVE_ADDR
is 0, that's what it defaults to when using normal esp-idf i2c which works.
The datasheet says that the device's address is 0x44 or 0x45 depending on the configuration of its address pin. Maybe you have SLAVE_ADDR and SLAVE_REG the wrong way around?
You're right, I am getting interupts now but for some reason not any data. The problem is I don't really understand what SLAVE_REG
is, according to the datasheet it does a 2 byte write with a 'command', then does a 6 byte read but it doesn't seem to mention registers. Unless I'm getting mixed up and {0x24 0x00} is the register.
I am reading the data with this:
printf("0: %u\n", ulp_read_cmd[HULP_I2C_CMD_DATA_OFFSET].val);
printf("1: %u\n", ulp_read_cmd[HULP_I2C_CMD_DATA_OFFSET + 1].val);
printf("2: %u\n", ulp_read_cmd[HULP_I2C_CMD_DATA_OFFSET + 2].val);
Sorry, actually I'm not getting interrupts, so clearly there's still an error somewhere. Will have a proper look tomorrow.
You need I_HALT after the I_END (I_END doesn't stop the ULP right there, it just prevents it starting up again after the next I_HALT... currently it would continue into the I2C subroutine causing mayhem)
Initialise LED_ERR as output. There might be a nack/bus error now but you won't have any indication, eg. ESP_ERROR_CHECK(hulp_configure_pin(LED_ERR, RTC_GPIO_MODE_OUTPUT_ONLY, GPIO_PULLDOWN_ONLY, 0));
Check you have external pullups on SDA and SCL
I can see what's wrong now! You just need to view MSB|LSB in the SHT3X datasheet as SLAVE_REG|FIRST_BYTE in this implementation. In other words, to send your {0x24, 0x00} command, prepare a command to send 1 byte (0x00) to slave's register 0x24:
RTC_SLOW_ATTR ulp_var_t ulp_write_cmd[] = {
HULP_I2C_CMD_HDR(SLAVE_ADDR, 0x24, 1),
HULP_I2C_CMD_1B(0x00),
};
Except now I realise that a read might not work, because for a read command, I have it writing the 1 byte slave register before starting the read, but the SHT3X might not like receiving one byte...
I would suggest checking that the above write command works first (without read). Once you're confident that works, try add the read back in either like this:
RTC_SLOW_ATTR ulp_var_t ulp_read_cmd[HULP_I2C_CMD_BUF_SIZE(6)] = {
HULP_I2C_CMD_HDR(SLAVE_ADDR, 0x00, 6),
};
or like this:
RTC_SLOW_ATTR ulp_var_t ulp_read_cmd[HULP_I2C_CMD_BUF_SIZE(6)] = {
HULP_I2C_CMD_HDR(SLAVE_ADDR, 0x24, 6),
};
Awesome, it's working now using 0x00 as register and error led now also working. Still a lot of work to do because I want to only wake the ESP up when the temperature has changed by a certain amount e.g. 0.1°C but I will try and piece together some of the examples. If I manage to get it working I'll make a pull request for a sht3x example, it's a fairly popular sensor.
I've just pushed a change to allow a 'raw' read without setting the pointer first, as some devices such as SHT3X require. Give it a try, the command looks like this:
RTC_SLOW_ATTR ulp_var_t ulp_read_cmd[HULP_I2C_CMD_BUF_SIZE(6)] = {
HULP_I2C_CMD_HDR_NO_PTR(SLAVE_ADDR, 6),
};
Thanks, I'll give it a go. Something that might be useful is an abs(x) or absolute_difference(a,b) macro, that part was a bit of a struggle for me because I don't know assembly, but perhaps there's an easy way of doing it. I did it with jumps but it seems you can do it with XOR - but there is no XOR instruction I can find. I will have a go at these when I add the example.
Thanks, got it all working and made a pull request with the example. There's probably a better way to do the abs part but it seems to work.
Thanks for making this amazing library, I had previously put off using the ULP because I don't really know assembly but using this I think it might be possible. Having said that, I am struggling to read from a sht3x sensor which requires a write of 2 bytes and a read of 6 bytes. I have created the following by piecing together examples there are no interupts firing in the app, unlike the simpler i2c examples:
I've tried to copy the
I2CBB_CMD
example in the documentation but that only does a single read. The sensor definitely works and the following normal i2c code returns a value:I've also tried
RTC_GPIO_MODE_INPUT_OUTPUT
but that doesn't work either.