aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMitch Bradley <wmb@firmworks.com>2017-05-22 15:02:02 -1000
committerMitch Bradley <wmb@firmworks.com>2017-05-22 15:02:02 -1000
commitf967f34647bebfef1d8566ff48a65b5a63cda853 (patch)
tree0d96c79fb7ca41835237a852c6e01b8f5feb443b
parentb7a05e3d36e7746be82ed7a9a75c9d6095289820 (diff)
downloadcforth-f967f34647bebfef1d8566ff48a65b5a63cda853.tar.gz
esp32 - Added I2C driver interface
-rw-r--r--build/esp32/sdk_build/main/interface.c126
-rw-r--r--src/app/esp32/textend.c29
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? }
};