summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-rw-r--r--main/CMakeLists.txt3
-rw-r--r--main/Kconfig.projbuild148
-rw-r--r--main/main.c235
3 files changed, 302 insertions, 84 deletions
diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt
index cf2c455..46af1ea 100644
--- a/main/CMakeLists.txt
+++ b/main/CMakeLists.txt
@@ -1,2 +1,3 @@
idf_component_register(SRCS "main.c"
- INCLUDE_DIRS ".")
+ INCLUDE_DIRS "."
+ REQUIRES esp_driver_gpio esp_driver_i2c)
diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild
new file mode 100644
index 0000000..18b0727
--- /dev/null
+++ b/main/Kconfig.projbuild
@@ -0,0 +1,148 @@
+menu "Configuration of the Nixie Screen"
+
+ orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"
+
+ config MCP_I2C_ADDR
+ hex "I2C address of mcp23017"
+ default 0x20
+ help
+ I2C address of `mcp23017`. `mcp23017` has three address pins (`A0`,
+ `A1`, and `A2`). The address starts from `0x20` (all pins are
+ grounded), which is the default, and ends at `0x27`. See "3.3.1
+ ADDRESSING I2C DEVICES (MCP23017)" in the datasheet.
+
+ config SDA_PIN
+ int "SDA pin number"
+ range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
+ default 6
+ help
+ Pin number for SDA pin.
+
+ config SCL_PIN
+ int "SCL pin number"
+ range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
+ default 7
+ help
+ Pin number for SLC pin.
+
+ config MIN
+ int
+ default 0
+
+ config MAX
+ int
+ default 7
+
+ config N0_P0
+ int "N0_P0 pin number"
+ range MIN MAX
+ default 4
+ help
+ Pin number for N0_P0.
+
+ config N0_P1
+ int "N0_P1 pin number"
+ range MIN MAX
+ default 5
+ help
+ Pin number for N0_P1.
+
+ config N0_P2
+ int "N0_P2 pin number"
+ range MIN MAX
+ default 6
+ help
+ Pin number for N0_P2.
+
+ config N0_P3
+ int "N0_P3 pin number"
+ range MIN MAX
+ default 7
+ help
+ Pin number for N0_P3.
+
+ config N1_P0
+ int "N1_P0 pin number"
+ range MIN MAX
+ default 0
+ help
+ Pin number for N1_P0.
+
+ config N1_P1
+ int "N1_P1 pin number"
+ range MIN MAX
+ default 1
+ help
+ Pin number for N1_P1.
+
+ config N1_P2
+ int "N1_P2 pin number"
+ range MIN MAX
+ default 2
+ help
+ Pin number for N1_P2.
+
+ config N1_P3
+ int "N1_P3 pin number"
+ range MIN MAX
+ default 3
+ help
+ Pin number for N1_P3.
+
+ config N2_P0
+ int "N2_P0 pin number"
+ range MIN MAX
+ default 4
+ help
+ Pin number for N2_P0.
+
+ config N2_P1
+ int "N2_P1 pin number"
+ range MIN MAX
+ default 5
+ help
+ Pin number for N2_P1.
+
+ config N2_P2
+ int "N2_P2 pin number"
+ range MIN MAX
+ default 6
+ help
+ Pin number for N2_P2.
+
+ config N2_P3
+ int "N2_P3 pin number"
+ range MIN MAX
+ default 7
+ help
+ Pin number for N2_P3.
+
+ config N3_P0
+ int "N3_P0 pin number"
+ range MIN MAX
+ default 0
+ help
+ Pin number for N3_P0.
+
+ config N3_P1
+ int "N3_P1 pin number"
+ range MIN MAX
+ default 1
+ help
+ Pin number for N3_P1.
+
+ config N3_P2
+ int "N3_P2 pin number"
+ range MIN MAX
+ default 2
+ help
+ Pin number for N3_P2.
+
+ config N3_P3
+ int "N3_P3 pin number"
+ range MIN MAX
+ default 3
+ help
+ Pin number for N3_P3.
+
+endmenu \ No newline at end of file
diff --git a/main/main.c b/main/main.c
index c44352c..a7f2019 100644
--- a/main/main.c
+++ b/main/main.c
@@ -1,18 +1,11 @@
#include <stdio.h>
#include <unistd.h>
#include "driver/gpio.h"
+#include "driver/i2c_master.h"
-struct Nixie
-{
- uint8_t digit;
- uint8_t D;
- uint8_t C;
- uint8_t B;
- uint8_t A;
-};
-
-struct Nixie screen[4];
-
+#define MCP_I2C_ADDR CONFIG_MCP_I2C_ADDR
+#define SDA_PIN CONFIG_SDA_PIN
+#define SCL_PIN CONFIG_SCL_PIN
#define N0_P0 CONFIG_N0_P0
#define N0_P1 CONFIG_N0_P1
#define N0_P2 CONFIG_N0_P2
@@ -29,52 +22,116 @@ struct Nixie screen[4];
#define N3_P1 CONFIG_N3_P1
#define N3_P2 CONFIG_N3_P2
#define N3_P3 CONFIG_N3_P3
-#define GPIO_OUTPUT_PIN_SEL ((1ULL<<N0_P0) | (1ULL<<N0_P1) | (1ULL<<N0_P2) | (1ULL<<N0_P3) | (1ULL<<N1_P0) | (1ULL<<N1_P1) | (1ULL<<N1_P2) | (1ULL<<N1_P3) | (1ULL<<N2_P0) | (1ULL<<N2_P1) | (1ULL<<N2_P2) | (1ULL<<N2_P3) | (1ULL<<N3_P0) | (1ULL<<N3_P1) | (1ULL<<N3_P2) | (1ULL<<N3_P3))
-/*
- * Let's say, GPIO_OUTPUT_IO_0=18, GPIO_OUTPUT_IO_1=19
- * In binary representation,
- * 1ULL<<GPIO_OUTPUT_IO_0 is equal to 0000000000000000000001000000000000000000 and
- * 1ULL<<GPIO_OUTPUT_IO_1 is equal to 0000000000000000000010000000000000000000
- * GPIO_OUTPUT_PIN_SEL 0000000000000000000011000000000000000000
- * */
+#define MCP_GPIO_OUTPUT 0
+#define REG_IODIRA 0x00
+#define REG_IODIRB 0x01
+#define REG_GPIOA 0x12
+#define REG_GPIOB 0x13
+#define BV(x) (1 << (x))
+
+struct Nixie
+{
+ uint8_t digit;
+ uint8_t reg;
+ uint8_t D;
+ uint8_t C;
+ uint8_t B;
+ uint8_t A;
+};
+
+struct Nixie screen[4];
+i2c_master_bus_handle_t i2c_bus;
+i2c_master_dev_handle_t mcp;
+
+
+esp_err_t write_reg_bit_16(uint8_t reg, bool val, uint8_t bit)
+{
+ uint8_t buf[3];
+
+ // Read the current value from the register
+ buf[0] = reg; // register address
+ ESP_ERROR_CHECK(i2c_master_transmit(mcp, &buf[0], sizeof(uint8_t), -1));
+ ESP_ERROR_CHECK(i2c_master_receive(mcp, &buf[1], sizeof(uint8_t), -1));
+ // Update the value in the buffer
+
+ buf[1] = (buf[1] & ~BV(bit)) | (val ? BV(bit) : 0);
+
+ // Write the updated value back to the register
+ buf[0] = reg; // Send register address
+ ESP_ERROR_CHECK(i2c_master_transmit(mcp, &buf[0], sizeof(uint16_t), -1));
+
+ return ESP_OK;
+}
+
+esp_err_t mcp_set_mode(uint8_t reg, uint8_t pin, bool mode)
+{
+ return write_reg_bit_16(reg, mode, pin);
+}
+
+esp_err_t mcp_set_level(uint8_t reg, uint8_t pin, bool val)
+{
+ return write_reg_bit_16(reg, val, pin);
+
+}
void configure_screen(void)
{
- //zero-initialize the config structure.
- gpio_config_t io_conf = {};
- //disable interrupt
- io_conf.intr_type = GPIO_INTR_DISABLE;
- //set as output mode
- io_conf.mode = GPIO_MODE_OUTPUT;
- //bit mask of the pins that you want to set,e.g.GPIO18/19
- io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
- //disable pull-down mode
- io_conf.pull_down_en = 0;
- //disable pull-up mode
- io_conf.pull_up_en = 0;
- //configure GPIO with the given settings
- gpio_config(&io_conf);
+ i2c_master_bus_config_t i2c_bus_config = {
+ .clk_source = I2C_CLK_SRC_DEFAULT,
+ .i2c_port = 0,
+ .sda_io_num = SDA_PIN,
+ .scl_io_num = SCL_PIN,
+ .glitch_ignore_cnt = 7,
+ .flags.enable_internal_pullup = true,
+ };
+ ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_config, &i2c_bus));
+
+ i2c_device_config_t mcp_cfg = {
+ .dev_addr_length = I2C_ADDR_BIT_LEN_7,
+ .device_address = MCP_I2C_ADDR,
+ .scl_speed_hz = 1000000,
+ };
+ ESP_ERROR_CHECK(i2c_master_bus_add_device(i2c_bus, &mcp_cfg, &mcp));
+
+ printf("I2C MCP Configured!\n");
screen[0].digit = 0;
+ screen[0].reg = REG_GPIOA;
screen[0].C = N0_P0;
screen[0].B = N0_P1;
screen[0].D = N0_P2;
screen[0].A = N0_P3;
screen[1].digit = 0;
+ screen[1].reg = REG_GPIOA;
screen[1].C = N1_P0;
screen[1].B = N1_P1;
screen[1].D = N1_P2;
screen[1].A = N1_P3;
screen[2].digit = 0;
+ screen[2].reg = REG_GPIOB;
screen[2].C = N2_P0;
screen[2].B = N2_P1;
screen[2].D = N2_P2;
screen[2].A = N2_P3;
screen[3].digit = 0;
+ screen[3].reg = REG_GPIOB;
screen[3].C = N3_P0;
screen[3].B = N3_P1;
screen[3].D = N3_P2;
screen[3].A = N3_P3;
+
+ for (uint8_t i = 0; i <= 3; ++i)
+ {
+ uint8_t reg = REG_IODIRA;
+ if(i > 1) reg = REG_IODIRB;
+ mcp_set_mode(reg, screen[i].D, MCP_GPIO_OUTPUT);
+ mcp_set_mode(reg, screen[i].C, MCP_GPIO_OUTPUT);
+ mcp_set_mode(reg, screen[i].B, MCP_GPIO_OUTPUT);
+ mcp_set_mode(reg, screen[i].A, MCP_GPIO_OUTPUT);
+ }
+
+
+ printf("MCP GPIO Configured!\n");
return;
}
@@ -82,81 +139,93 @@ void set_digit(struct Nixie* n)
{
switch (n->digit) {
case 0:
- gpio_set_level(n->D, 0);
- gpio_set_level(n->C, 0);
- gpio_set_level(n->B, 0);
- gpio_set_level(n->A, 0);
+ mcp_set_level(n->reg, n->D, 0);
+ mcp_set_level(n->reg, n->C, 0);
+ mcp_set_level(n->reg, n->B, 0);
+ mcp_set_level(n->reg, n->A, 0);
break;
case 1:
- gpio_set_level(n->D, 0);
- gpio_set_level(n->C, 0);
- gpio_set_level(n->B, 0);
- gpio_set_level(n->A, 1);
+ mcp_set_level(n->reg, n->D, 0);
+ mcp_set_level(n->reg, n->C, 0);
+ mcp_set_level(n->reg, n->B, 0);
+ mcp_set_level(n->reg, n->A, 1);
break;
case 2:
- gpio_set_level(n->D, 0);
- gpio_set_level(n->C, 0);
- gpio_set_level(n->B, 1);
- gpio_set_level(n->A, 0);
+ mcp_set_level(n->reg, n->D, 0);
+ mcp_set_level(n->reg, n->C, 0);
+ mcp_set_level(n->reg, n->B, 1);
+ mcp_set_level(n->reg, n->A, 0);
break;
case 3:
- gpio_set_level(n->D, 0);
- gpio_set_level(n->C, 0);
- gpio_set_level(n->B, 1);
- gpio_set_level(n->A, 1);
+ mcp_set_level(n->reg, n->D, 0);
+ mcp_set_level(n->reg, n->C, 0);
+ mcp_set_level(n->reg, n->B, 1);
+ mcp_set_level(n->reg, n->A, 1);
break;
case 4:
- gpio_set_level(n->D, 0);
- gpio_set_level(n->C, 1);
- gpio_set_level(n->B, 0);
- gpio_set_level(n->A, 0);
- break;
- case 5:
- gpio_set_level(n->D, 0);
- gpio_set_level(n->C, 1);
- gpio_set_level(n->B, 0);
- gpio_set_level(n->A, 1);
- break;
- case 6:
- gpio_set_level(n->D, 0);
- gpio_set_level(n->C, 1);
- gpio_set_level(n->B, 1);
- gpio_set_level(n->A, 0);
+ mcp_set_level(n->reg, n->D, 0);
+ mcp_set_level(n->reg, n->C, 1);
+ mcp_set_level(n->reg, n->B, 0);
+ mcp_set_level(n->reg, n->A, 0);
+ break;
+ case 5:
+ mcp_set_level(n->reg, n->D, 0);
+ mcp_set_level(n->reg, n->C, 1);
+ mcp_set_level(n->reg, n->B, 0);
+ mcp_set_level(n->reg, n->A, 1);
+ break;
+ case 6:
+ mcp_set_level(n->reg, n->D, 0);
+ mcp_set_level(n->reg, n->C, 1);
+ mcp_set_level(n->reg, n->B, 1);
+ mcp_set_level(n->reg, n->A, 0);
break;
case 7:
- gpio_set_level(n->D, 0);
- gpio_set_level(n->C, 1);
- gpio_set_level(n->B, 1);
- gpio_set_level(n->A, 1);
+ mcp_set_level(n->reg, n->D, 0);
+ mcp_set_level(n->reg, n->C, 1);
+ mcp_set_level(n->reg, n->B, 1);
+ mcp_set_level(n->reg, n->A, 1);
break;
case 8:
- gpio_set_level(n->D, 1);
- gpio_set_level(n->C, 0);
- gpio_set_level(n->B, 0);
- gpio_set_level(n->A, 0);
+ mcp_set_level(n->reg, n->D, 1);
+ mcp_set_level(n->reg, n->C, 0);
+ mcp_set_level(n->reg, n->B, 0);
+ mcp_set_level(n->reg, n->A, 0);
break;
case 9:
- gpio_set_level(n->D, 1);
- gpio_set_level(n->C, 0);
- gpio_set_level(n->B, 0);
- gpio_set_level(n->A, 1);
+ mcp_set_level(n->reg, n->D, 1);
+ mcp_set_level(n->reg, n->C, 0);
+ mcp_set_level(n->reg, n->B, 0);
+ mcp_set_level(n->reg, n->A, 1);
break;
default:
+ mcp_set_level(n->reg, n->D, 1);
+ mcp_set_level(n->reg, n->C, 1);
+ mcp_set_level(n->reg, n->B, 1);
+ mcp_set_level(n->reg, n->A, 1);
break;
return;
}
}
-void app_main(void)
+void test_screen(void)
{
- printf("N1_P3: %i\n", N1_P3);
+ printf("Starting up...\n");
configure_screen();
+ printf("Screen Configured!\n");
+
while(1){
for (uint8_t i = 0; i <= 9; ++i) {
- printf("digit: %i\n", i);
- screen[0].digit = i; // Update the digit
- set_digit(&screen[0]); // Call set_digit function
- sleep(1); // Sleep for 2 seconds
+ for (int j = 0; j < 4; ++j) {
+ screen[j].digit = (i + j) % 10; // Update the digit cyclically
+ set_digit(&screen[j]); // Call set_digit function
+ }
+ sleep(1);
}
}
}
+
+void app_main(void)
+{
+ test_screen();
+} \ No newline at end of file