It's definitely possible. If you look at the datasheet, especially the c reference driver, its data output is very simple and will be easy to bitbang. Of course writing the ULP program is still going to be a bit of work.
I got halfway through writing a library to make this stuff easier but haven't worked on it for a while. Anyway, here's something to get you started:
Code: Select all
#define I_READ_PIN(pin) \
I_RD_REG(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S + rtc_gpio_desc[pin].rtc_num, RTC_GPIO_IN_NEXT_S + rtc_gpio_desc[pin].rtc_num)
#define I_WRITE_PIN(pin, val) \
(val) ? (ulp_insn_t) I_WR_REG_BIT(RTC_GPIO_OUT_W1TS_REG, RTC_GPIO_OUT_DATA_W1TS_S + rtc_gpio_desc[pin].rtc_num, 1) : (ulp_insn_t) I_WR_REG_BIT(RTC_GPIO_OUT_W1TC_REG, RTC_GPIO_OUT_DATA_W1TC_S + rtc_gpio_desc[pin].rtc_num, 1)
#define CLOCK_PIN GPIO_NUM_X
#define DATA_PIN GPIO_NUM_Y
#define WAKE_THRESHOLD_VALUE 12345
void setup() {
ulp_insn_t ulpProgram[] = {
I_READ_PIN(DATA_PIN),
M_BGE(1,1), //If no data available, go back to sleep
I_HALT(),
M_LABEL(1),
I_STAGE_RST(),
I_MOVI(R1,0),
M_LABEL(2), //Read 16 bits
I_WRITE_PIN(CLOCK_PIN, 1),
I_LSHI(R1,R1,1),
I_STAGE_INC(1),
I_WRITE_PIN(CLOCK_PIN, 0),
I_READ_PIN(DATA_PIN),
I_ADDR(R1,R1,R0),
M_BSLT(2,16),
M_LABEL(3), //Ignore 8 bits
I_WRITE_PIN(CLOCK_PIN, 1),
I_STAGE_INC(1),
I_WRITE_PIN(CLOCK_PIN, 0),
I_DELAY(1),
M_BSLT(3,24),
I_SUBI(R0,R1,WAKE_THRESHOLD_VALUE), //Compare to threshold
M_BXF(4), //Go to wake if value > threshold
I_HALT(),
M_LABEL(4),
I_WAKE(),
I_HALT(),
};
//Initialise pins
rtc_gpio_init(CLOCK_PIN);
rtc_gpio_set_direction(CLOCK_PIN, RTC_GPIO_MODE_OUTPUT_ONLY);
rtc_gpio_set_level(CLOCK_PIN, 1);
rtc_gpio_init(DATA_PIN);
rtc_gpio_set_direction(CLOCK_PIN, RTC_GPIO_MODE_INPUT_ONLY);
//Load and run
size_t programSize = sizeof(ulpProgram) / sizeof(ulp_insn_t);
ulp_process_macros_and_load(0, ulpProgram, &programSize);
ulp_set_wakeup_period(0, 1 * 1000 * 1000);
ulp_run(0);
}
I don't have a HX711 to test so this probably isn't even close to working, but it should be a good starting point. It will read the most significant 16 bits (discarding the lower 8) and comparing to a (16 bit) threshold, waking if the read value exceeds that threshold. Needs the updates I've submitted here to work
https://github.com/espressif/esp-idf/pull/3580 (you'll need to replace your ulp.h and ulp_macro.c with those if you decide to use it)