|
@@ -20,6 +20,7 @@
|
|
|
#include "trace.h"
|
|
|
#include "messaging.h"
|
|
|
#include "display.h"
|
|
|
+
|
|
|
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
|
|
|
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
|
|
|
#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */
|
|
@@ -28,6 +29,8 @@
|
|
|
#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */
|
|
|
#define ACK_VAL 0x0 /*!< I2C ack value */
|
|
|
#define NACK_VAL 0x1 /*!< I2C nack value */
|
|
|
+extern int spi_system_host;
|
|
|
+extern int spi_system_dc_gpio;
|
|
|
|
|
|
static const char *TAG = "cmd_i2ctools";
|
|
|
#define NOT_OUTPUT "has input capabilities only"
|
|
@@ -72,6 +75,14 @@ static struct {
|
|
|
struct arg_end *end;
|
|
|
} i2cconfig_args;
|
|
|
|
|
|
+static struct {
|
|
|
+ struct arg_int *data;
|
|
|
+ struct arg_int *clk;
|
|
|
+ struct arg_int *dc;
|
|
|
+ struct arg_int *host;
|
|
|
+ struct arg_lit *clear;
|
|
|
+ struct arg_end *end;
|
|
|
+} spiconfig_args;
|
|
|
|
|
|
static struct {
|
|
|
struct arg_int *port;
|
|
@@ -97,8 +108,39 @@ static struct {
|
|
|
struct arg_lit *clear;
|
|
|
struct arg_end *end;
|
|
|
} i2cdisp_args;
|
|
|
-
|
|
|
-
|
|
|
+char * gpio_list = NULL;
|
|
|
+const char * get_gpio_list(){
|
|
|
+ if(!gpio_list){
|
|
|
+ gpio_list = malloc(GPIO_PIN_COUNT*3+1);
|
|
|
+ memset(gpio_list,0x00,GPIO_PIN_COUNT*3+1);
|
|
|
+
|
|
|
+ for(int i = 0;i<GPIO_PIN_COUNT;i++){
|
|
|
+ if(GPIO_IS_VALID_OUTPUT_GPIO(i)){
|
|
|
+ sprintf(gpio_list+strlen(gpio_list),"%u|",i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ gpio_list[strlen(gpio_list)-1]='\0';
|
|
|
+ ESP_LOGI(TAG,"Initialized gpio list: %s",gpio_list);
|
|
|
+ }
|
|
|
+ return gpio_list;
|
|
|
+}
|
|
|
+int is_output_gpio(struct arg_int * gpio, FILE * f, int * gpio_out){
|
|
|
+ int res = 0;
|
|
|
+ const char * name = gpio->hdr.longopts?gpio->hdr.longopts:gpio->hdr.glossary;
|
|
|
+ *gpio_out=-1;
|
|
|
+ int t_gpio=gpio->ival[0];
|
|
|
+ if(gpio->count==0){
|
|
|
+ fprintf(f,"Missing: %s\n", name);
|
|
|
+ res++;
|
|
|
+ } else if(!GPIO_IS_VALID_OUTPUT_GPIO(t_gpio)){
|
|
|
+ fprintf(f,"Invalid %s gpio: [%d] %s\n",name, t_gpio, GPIO_IS_VALID_GPIO(t_gpio)?NOT_OUTPUT:NOT_GPIO );
|
|
|
+ res++;
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ *gpio_out = t_gpio;
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
bool is_i2c_started(i2c_port_t port){
|
|
|
esp_err_t ret = ESP_OK;
|
|
|
ESP_LOGD(TAG,"Determining if i2c is started on port %u", port);
|
|
@@ -118,7 +160,6 @@ bool is_i2c_started(i2c_port_t port){
|
|
|
return (ret!=ESP_ERR_INVALID_STATE);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
typedef struct {
|
|
|
uint8_t address;
|
|
|
char * description;
|
|
@@ -442,14 +483,7 @@ static int do_i2c_set_display(int argc, char **argv)
|
|
|
|
|
|
|
|
|
/* Check "--back" option */
|
|
|
- if (i2cdisp_args.back->count) {
|
|
|
- back=i2cdisp_args.back->ival[0];
|
|
|
- if(!GPIO_IS_VALID_OUTPUT_GPIO(back)){
|
|
|
- fprintf(f,"Invalid GPIO for back light: %d %s\n", back, GPIO_IS_VALID_GPIO(back)?NOT_OUTPUT:NOT_GPIO );
|
|
|
- back=-1;
|
|
|
- nerrors ++;
|
|
|
- }
|
|
|
- }
|
|
|
+ nerrors +=is_output_gpio(i2cdisp_args.back,f,&back);
|
|
|
|
|
|
|
|
|
if(!name) name = strdup("I2C");
|
|
@@ -502,6 +536,69 @@ static int do_i2c_set_display(int argc, char **argv)
|
|
|
return nerrors==0;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+static int do_spiconfig_cmd(int argc, char **argv){
|
|
|
+ static spi_bus_config_t spi_config = {
|
|
|
+ .mosi_io_num = -1,
|
|
|
+ .sclk_io_num = -1,
|
|
|
+ .miso_io_num = -1,
|
|
|
+ .quadwp_io_num = -1,
|
|
|
+ .quadhd_io_num = -1
|
|
|
+ };
|
|
|
+
|
|
|
+ int data, clk, dc, host = 0;
|
|
|
+ esp_err_t err=ESP_OK;
|
|
|
+ int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&spiconfig_args);
|
|
|
+ if (nerrors != 0) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Check "--clear" option */
|
|
|
+ if (spiconfig_args.clear->count) {
|
|
|
+ log_send_messaging(MESSAGING_WARNING,"spi config cleared");
|
|
|
+ config_set_value(NVS_TYPE_STR, "spi_config", "");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ char *buf = NULL;
|
|
|
+ size_t buf_size = 0;
|
|
|
+ FILE *f = open_memstream(&buf, &buf_size);
|
|
|
+ if (f == NULL) {
|
|
|
+ log_send_messaging(MESSAGING_ERROR,"Unable to open memory stream.");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ /* Check "--clk" option */
|
|
|
+ nerrors+=is_output_gpio(spiconfig_args.clk, f, &clk);
|
|
|
+ nerrors+=is_output_gpio(spiconfig_args.data, f, &data);
|
|
|
+ nerrors+=is_output_gpio(spiconfig_args.dc, f, &dc);
|
|
|
+ nerrors+=is_output_gpio(spiconfig_args.host, f, &host);
|
|
|
+
|
|
|
+ if(!nerrors){
|
|
|
+ spi_config.mosi_io_num=data;
|
|
|
+ spi_config.sclk_io_num=clk;
|
|
|
+
|
|
|
+ fprintf(f,"Configuring SPI data:%d clk:%d host:%u dc:%d", spi_config.mosi_io_num, spi_config.sclk_io_num, host, dc);
|
|
|
+ if((err=spi_bus_initialize( host, &spi_config, 1 ))!=ESP_OK){
|
|
|
+ fprintf(f,"SPI bus initialization failed. %s\n", esp_err_to_name(err));
|
|
|
+ nerrors++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!nerrors){
|
|
|
+ fprintf(f,"Storing SPI parameters.\n");
|
|
|
+ config_spi_set(&spi_config, host, dc);
|
|
|
+ }
|
|
|
+ fflush (f);
|
|
|
+ log_send_messaging(nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf);
|
|
|
+ fclose(f);
|
|
|
+ FREE_AND_NULL(buf);
|
|
|
+
|
|
|
+ return nerrors==0;
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
static int do_i2cconfig_cmd(int argc, char **argv)
|
|
|
{
|
|
|
esp_err_t err=ESP_OK;
|
|
@@ -542,30 +639,9 @@ static int do_i2cconfig_cmd(int argc, char **argv)
|
|
|
if (i2cconfig_args.freq->count) {
|
|
|
i2c_frequency = i2cconfig_args.freq->ival[0];
|
|
|
}
|
|
|
- if (i2cconfig_args.sda->count){
|
|
|
- /* Check "--sda" option */
|
|
|
- i2c_gpio_sda = i2cconfig_args.sda->ival[0];
|
|
|
- if(!GPIO_IS_VALID_OUTPUT_GPIO(i2c_gpio_sda )){
|
|
|
- fprintf(f,"Invalid SDA gpio: %d %s\n", i2c_gpio_sda , GPIO_IS_VALID_GPIO(i2c_gpio_sda )?NOT_OUTPUT:NOT_GPIO );
|
|
|
- nerrors ++;
|
|
|
- }
|
|
|
- }
|
|
|
- else {
|
|
|
- fprintf(f,"Missing SDA GPIO\n");
|
|
|
- nerrors ++;
|
|
|
- }
|
|
|
- if (i2cconfig_args.scl->count){
|
|
|
- /* Check "--scl" option */
|
|
|
- i2c_gpio_scl = i2cconfig_args.scl->ival[0];
|
|
|
- if(!GPIO_IS_VALID_OUTPUT_GPIO(i2c_gpio_scl )){
|
|
|
- fprintf(f,"Invalid SCL gpio: %d %s\n", i2c_gpio_scl , GPIO_IS_VALID_GPIO(i2c_gpio_scl )?NOT_OUTPUT:NOT_GPIO );
|
|
|
- nerrors ++;
|
|
|
- }
|
|
|
- }
|
|
|
- else {
|
|
|
- fprintf(f,"Missing SCL GPIO\n");
|
|
|
- nerrors ++;
|
|
|
- }
|
|
|
+
|
|
|
+ nerrors +=is_output_gpio(i2cconfig_args.sda,f,&i2c_gpio_sda);
|
|
|
+ nerrors +=is_output_gpio(i2cconfig_args.scl,f,&i2c_gpio_scl);
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_SQUEEZEAMP
|
|
@@ -957,12 +1033,12 @@ static void register_i2c_set_display(){
|
|
|
i2cdisp_args.hflip = arg_lit0(NULL, "hf", "Flip picture horizontally");
|
|
|
i2cdisp_args.vflip = arg_lit0(NULL, "vf", "Flip picture vertically");
|
|
|
i2cdisp_args.rotate = arg_lit0("r", "rotate", "Rotate the picture 180 deg");
|
|
|
- i2cdisp_args.back = arg_int0("b", "back", "<n>","Backlight GPIO (if applicable)");
|
|
|
+ i2cdisp_args.back = arg_int0("b", "back", get_gpio_list(),"Backlight GPIO (if applicable)");
|
|
|
i2cdisp_args.speed = arg_int0("s", "speed", "<n>","Default speed is 8000000 (8MHz) for SPI and 250000 for I2C. The SPI interface can work up to 26MHz~40MHz");
|
|
|
i2cdisp_args.end = arg_end(8);
|
|
|
const esp_console_cmd_t i2c_set_display= {
|
|
|
.command = "setdisplay",
|
|
|
- .help="Sets the display options for the board",
|
|
|
+ .help="Sets the display options",
|
|
|
.hint = NULL,
|
|
|
.func = &do_i2c_set_display,
|
|
|
.argtable = &i2cdisp_args
|
|
@@ -1083,19 +1159,63 @@ cJSON * i2config_cb(){
|
|
|
cJSON * values = cJSON_CreateObject();
|
|
|
int i2c_port;
|
|
|
const i2c_config_t * i2c= config_i2c_get(&i2c_port);
|
|
|
- cJSON_AddNumberToObject(values,"scl",i2c->scl_io_num);
|
|
|
- cJSON_AddNumberToObject(values,"sda",i2c->sda_io_num);
|
|
|
- cJSON_AddNumberToObject(values,"freq",i2c->master.clk_speed);
|
|
|
- cJSON_AddNumberToObject(values,"port",i2c_port);
|
|
|
+ if(i2c->scl_io_num>0) {
|
|
|
+ cJSON_AddNumberToObject(values,"scl",i2c->scl_io_num);
|
|
|
+ }
|
|
|
+ if(i2c->sda_io_num>0) {
|
|
|
+ cJSON_AddNumberToObject(values,"sda",i2c->sda_io_num);
|
|
|
+ }
|
|
|
+ if(i2c->master.clk_speed>0) {
|
|
|
+ cJSON_AddNumberToObject(values,"freq",i2c->master.clk_speed);
|
|
|
+ }
|
|
|
+ if(i2c_port>0) {
|
|
|
+ cJSON_AddNumberToObject(values,"port",i2c_port);
|
|
|
+ }
|
|
|
+ return values;
|
|
|
+}
|
|
|
+cJSON * spiconfig_cb(){
|
|
|
+ cJSON * values = cJSON_CreateObject();
|
|
|
+ const spi_bus_config_t * spi_config= config_spi_get(NULL);
|
|
|
+ if(spi_config->mosi_io_num>0){
|
|
|
+ cJSON_AddNumberToObject(values,"data",spi_config->mosi_io_num);
|
|
|
+ }
|
|
|
+ if(spi_config->sclk_io_num>0){
|
|
|
+ cJSON_AddNumberToObject(values,"clk",spi_config->sclk_io_num);
|
|
|
+ }
|
|
|
+ if(spi_system_dc_gpio>0){
|
|
|
+ cJSON_AddNumberToObject(values,"dc",spi_system_dc_gpio);
|
|
|
+ }
|
|
|
+ if(spi_system_host>0){
|
|
|
+ cJSON_AddNumberToObject(values,"host",spi_system_host);
|
|
|
+ }
|
|
|
return values;
|
|
|
}
|
|
|
+
|
|
|
+static void register_spiconfig(void)
|
|
|
+{
|
|
|
+ spiconfig_args.clear = arg_lit0(NULL, "clear", "clear configuration");
|
|
|
+ spiconfig_args.clk = arg_int0("k", "clock", get_gpio_list(), "Set the gpio for SPI clock");
|
|
|
+ spiconfig_args.data = arg_int0("d","data", get_gpio_list(),"Set the gpio for SPI data");
|
|
|
+ spiconfig_args.dc = arg_int0("c","dc", get_gpio_list(), "Set the gpio for SPI dc");
|
|
|
+ spiconfig_args.host= arg_int0("h", "host", "int", "Set the SPI host number to use");
|
|
|
+ spiconfig_args.end = arg_end(4);
|
|
|
+ const esp_console_cmd_t spiconfig_cmd = {
|
|
|
+ .command = "spiconfig",
|
|
|
+ .help = "Config SPI bus",
|
|
|
+ .hint = NULL,
|
|
|
+ .func = &do_spiconfig_cmd,
|
|
|
+ .argtable = &spiconfig_args
|
|
|
+ };
|
|
|
+ cmd_to_json_with_cb(&spiconfig_cmd,&spiconfig_cb);
|
|
|
+ ESP_ERROR_CHECK(esp_console_cmd_register(&spiconfig_cmd));
|
|
|
+}
|
|
|
static void register_i2cconfig(void)
|
|
|
{
|
|
|
- i2cconfig_args.clear = arg_lit0(NULL, "clear", "clear configuration and return");
|
|
|
+ i2cconfig_args.clear = arg_lit0(NULL, "clear", "clear configuration");
|
|
|
i2cconfig_args.port = arg_int0("p", "port", "0|1", "Set the I2C bus port number");
|
|
|
i2cconfig_args.freq = arg_int0("f", "freq", "int", "Set the frequency(Hz) of I2C bus. e.g. 100000");
|
|
|
- i2cconfig_args.sda = arg_int0("d", "sda", "int", "Set the gpio for I2C SDA. e.g. 19");
|
|
|
- i2cconfig_args.scl = arg_int0("c", "scl", "int", "Set the gpio for I2C SCL. e.g. 18");
|
|
|
+ i2cconfig_args.sda = arg_int0("d", "sda", get_gpio_list(), "Set the gpio for I2C SDA. e.g. 19");
|
|
|
+ i2cconfig_args.scl = arg_int0("c", "scl", get_gpio_list(), "Set the gpio for I2C SCL. e.g. 18");
|
|
|
i2cconfig_args.load = arg_lit0("l", "load", "load existing configuration and return");
|
|
|
i2cconfig_args.end = arg_end(4);
|
|
|
const esp_console_cmd_t i2cconfig_cmd = {
|
|
@@ -1112,6 +1232,7 @@ static void register_i2cconfig(void)
|
|
|
void register_i2ctools(void)
|
|
|
{
|
|
|
register_i2cconfig();
|
|
|
+ register_spiconfig();
|
|
|
register_i2cdectect();
|
|
|
register_i2cget();
|
|
|
register_i2cset();
|