diff options
author | Mitch Bradley <wmb@firmworks.com> | 2017-05-22 15:02:02 -1000 |
---|---|---|
committer | Mitch Bradley <wmb@firmworks.com> | 2017-05-22 15:02:02 -1000 |
commit | f967f34647bebfef1d8566ff48a65b5a63cda853 (patch) | |
tree | 0d96c79fb7ca41835237a852c6e01b8f5feb443b | |
parent | b7a05e3d36e7746be82ed7a9a75c9d6095289820 (diff) | |
download | cforth-f967f34647bebfef1d8566ff48a65b5a63cda853.tar.gz |
esp32 - Added I2C driver interface
-rw-r--r-- | build/esp32/sdk_build/main/interface.c | 126 | ||||
-rw-r--r-- | src/app/esp32/textend.c | 29 |
2 files changed, 151 insertions, 4 deletions
diff --git a/build/esp32/sdk_build/main/interface.c b/build/esp32/sdk_build/main/interface.c index e3ebfc7..4c46ad3 100644 --- a/build/esp32/sdk_build/main/interface.c +++ b/build/esp32/sdk_build/main/interface.c @@ -1,5 +1,7 @@ // Interfaces between ESP32/FreeRTOS and Forth +typedef int cell; + #include "freertos/FreeRTOS.h" #include "esp_system.h" #include "nvs_flash.h" @@ -58,3 +60,127 @@ void ms(int msecs) { vTaskDelay(msecs/ portTICK_PERIOD_MS); } + +#include "driver/i2c.h" + +#define I2C_NUM 1 +#define ACK_CHECK 1 +#define ACK_VAL 0 +#define NACK_VAL 1 + +// void i2c_setup(cell sda, cell scl) +cell i2c_open(uint8_t sda, uint8_t scl) +{ + int i2c_master_port = 1; + i2c_config_t conf; + conf.mode = I2C_MODE_MASTER; + conf.sda_io_num = sda; + conf.sda_pullup_en = GPIO_PULLUP_ENABLE; + conf.scl_io_num = scl; + conf.scl_pullup_en = GPIO_PULLUP_ENABLE; + conf.master.clk_speed = 100000; + i2c_param_config(i2c_master_port, &conf); + return i2c_driver_install(i2c_master_port, conf.mode, + 0, 0, 0 // No Rx buf, No Tx buf, no intr flags + ); +} +void i2c_close() +{ + i2c_driver_delete(1); +} + +#define I2C_FINISH \ + i2c_master_stop(cmd); \ + esp_err_t ret = i2c_master_cmd_begin(I2C_NUM, cmd, 1000 / portTICK_RATE_MS); \ + i2c_cmd_link_delete(cmd); + +int i2c_write_read(uint8_t stop, uint8_t slave, uint8_t rsize, uint8_t *rbuf, uint8_t wsize, uint8_t *wbuf) +{ + if (rsize == 0 && wsize == 0) { + return ESP_OK; + } + + i2c_cmd_handle_t cmd; + cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + if (wsize) { + i2c_master_write_byte(cmd, ( slave << 1 ) | I2C_MASTER_WRITE, ACK_CHECK); + i2c_master_write(cmd, wbuf, wsize, ACK_CHECK); + if (!rsize) { + i2c_master_stop(cmd); \ + esp_err_t ret = i2c_master_cmd_begin(I2C_NUM, cmd, 1000 / portTICK_RATE_MS); \ + i2c_cmd_link_delete(cmd); +// I2C_FINISH; + return ret; + } + if (stop) { // rsize is nonzero + i2c_master_stop(cmd); \ + esp_err_t ret = i2c_master_cmd_begin(I2C_NUM, cmd, 1000 / portTICK_RATE_MS); \ + i2c_cmd_link_delete(cmd); +// I2C_FINISH; + if (ret) + return -1; + cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + } else { + i2c_master_start(cmd); + } + i2c_master_write_byte(cmd, ( slave << 1 ) | I2C_MASTER_READ, ACK_CHECK); + } else { + // rsize must be nonzero because of the initial check at the top + i2c_master_write_byte(cmd, ( slave << 1 ) | I2C_MASTER_READ, ACK_CHECK); + } + + if (rsize > 1) { + i2c_master_read(cmd, rbuf, rsize - 1, ACK_VAL); + } + i2c_master_read_byte(cmd, rbuf + rsize - 1, NACK_VAL); + + I2C_FINISH; + return ret; +} + +cell i2c_rb(int stop, int slave, int reg) +{ + uint8_t rval[1]; + uint8_t regb[1] = { reg }; + if (i2c_write_read(stop, slave, 1, rval, 1, regb)) + return -1; + return rval[0]; +} + +cell i2c_be_rw(cell stop, cell slave, cell reg) +{ + uint8_t rval[2]; + uint8_t regb[1] = { reg }; + if (i2c_write_read(stop, slave, 2, rval, 1, regb)) + return -1; + return (rval[0]<<8) + rval[1]; +} + +cell i2c_le_rw(cell stop, cell slave, cell reg) +{ + uint8_t rval[2]; + uint8_t regb[1] = { reg }; + if (i2c_write_read(stop, slave, 2, rval, 1, regb)) + return -1; + return (rval[1]<<8) + rval[0]; +} + +cell i2c_wb(cell slave, cell reg, cell value) +{ + uint8_t buf[2] = {reg, value}; + return i2c_write_read(0, slave, 0, 0, 2, buf); +} + +cell i2c_be_ww(cell slave, cell reg, cell value) +{ + uint8_t buf[3] = {reg, value >> 8, value & 0xff}; + return i2c_write_read(0, slave, 0, 0, 3, buf); +} + +cell i2c_le_ww(cell slave, cell reg, cell value) +{ + uint8_t buf[3] = {reg, value & 0xff, value >> 8}; + return i2c_write_read(0, slave, 0, 0, 3, buf); +} diff --git a/src/app/esp32/textend.c b/src/app/esp32/textend.c index 4f632f6..6c28f04 100644 --- a/src/app/esp32/textend.c +++ b/src/app/esp32/textend.c @@ -2,6 +2,7 @@ // See "ccalls" below. #include "forth.h" +#include "i2c-ifce.h" extern cell *callback_up; @@ -32,9 +33,29 @@ cell build_date_adr(void) extern void software_reset(void); extern void ms(void); +extern void adc1_config_width(void); +extern void adc1_config_channel_atten(void); +extern void adc1_get_voltage(void); +extern void hall_sensor_read(void); + cell ((* const ccalls[])()) = { - C(build_date_adr) //c 'build-date { -- a.value } - C(version_adr) //c 'version { -- a.value } - C(ms) //c ms { i.ms -- } - C(software_reset) //c restart { -- } + C(build_date_adr) //c 'build-date { -- a.value } + C(version_adr) //c 'version { -- a.value } + C(ms) //c ms { i.ms -- } + C(software_reset) //c restart { -- } + + C(adc1_config_width) //c adc-width! { i.width -- } + C(adc1_config_channel_atten) //c adc-atten! { i.attenuation i.channel# -- } + C(adc1_get_voltage) //c adc@ { i.channel# -- i.voltage } + C(hall_sensor_read) //c hall@ { -- i.voltage } + + C(i2c_open) //c i2c-open { i.scl i.sda -- i.error? } + C(i2c_close) //c i2c-close { -- } + C(i2c_write_read) //c i2c-write-read { a.wbuf i.wsize a.rbuf i.rsize i.slave i.stop -- i.err? } + C(i2c_rb) //c i2c-b@ { i.reg i.slave i.stop -- i.b } + C(i2c_wb) //c i2c-b! { i.value i.reg i.slave -- i.error? } + C(i2c_be_rw) //c i2c-be-w@ { i.reg i.slave i.stop -- i.w } + C(i2c_le_rw) //c i2c-le-w@ { i.reg i.slave i.stop -- i.w } + C(i2c_be_ww) //c i2c-be-w! { i.value i.reg i.slave -- i.error? } + C(i2c_le_ww) //c i2c-le-w! { i.value i.reg i.slave -- i.error? } }; |