From 5134fdabb16cee8f094ecaee9aa97014a0628519 Mon Sep 17 00:00:00 2001 From: Jaime Albuquerque Date: Sun, 9 Oct 2022 17:16:43 -0300 Subject: [PATCH 1/7] shift_reg: add shift_reg component The feature is a driver to interface the microcontroller with shift registers just using 3 pins: Clock, Data and Latch. For further information, please, take a look at the component [README.md](components/shift_reg/README.md). Feature requested by issue #457. --- .github/labeler.yml | 8 + README.md | 1 + components/shift_reg/.eil.yml | 24 +++ components/shift_reg/CMakeLists.txt | 11 + components/shift_reg/LICENSE | 13 ++ components/shift_reg/README.md | 60 ++++++ components/shift_reg/component.mk | 7 + components/shift_reg/shift_reg.c | 203 ++++++++++++++++++ components/shift_reg/shift_reg.h | 121 +++++++++++ examples/shift_reg/default/CMakeLists.txt | 6 + examples/shift_reg/default/Makefile | 6 + examples/shift_reg/default/README.md | 39 ++++ .../shift_reg/default/main/CMakeLists.txt | 2 + examples/shift_reg/default/main/component.mk | 1 + examples/shift_reg/default/main/main.c | 55 +++++ examples/shift_reg/default/sdkconfig.defaults | 1 + 16 files changed, 558 insertions(+) create mode 100644 components/shift_reg/.eil.yml create mode 100644 components/shift_reg/CMakeLists.txt create mode 100644 components/shift_reg/LICENSE create mode 100644 components/shift_reg/README.md create mode 100644 components/shift_reg/component.mk create mode 100644 components/shift_reg/shift_reg.c create mode 100644 components/shift_reg/shift_reg.h create mode 100644 examples/shift_reg/default/CMakeLists.txt create mode 100644 examples/shift_reg/default/Makefile create mode 100644 examples/shift_reg/default/README.md create mode 100644 examples/shift_reg/default/main/CMakeLists.txt create mode 100644 examples/shift_reg/default/main/component.mk create mode 100644 examples/shift_reg/default/main/main.c create mode 100644 examples/shift_reg/default/sdkconfig.defaults diff --git a/.github/labeler.yml b/.github/labeler.yml index af34653ae..4a4bfa55f 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -536,6 +536,14 @@ labels: - "components/sgp40/**" - "components/sgp40/.eil.yml" - "examples/sgp40/**" + - label: "area:components:shift_reg" + sync: true + matcher: + files: + any: + - "components/shift_reg/**" + - "components/shift_reg/.eil.yml" + - "examples/shift_reg/**" - label: "area:components:sht3x" sync: true matcher: diff --git a/README.md b/README.md index 1c791c3d7..d02365250 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,7 @@ or [GitLab examples](https://gitlab.com/UncleRus/esp-idf-lib/tree/master/example | **lc709203f** | Driver for LC709203F battery fuel gauge | ISC | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **pca9685** | Driver for 16-channel, 12-bit PWM PCA9685 | BSD-3 | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **rda5807m** | Driver for single-chip broadcast FM radio tuner RDA5807M | BSD-3 | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes +| **shift_reg** | Driver for generic shift register interface. | ISC | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **tca9548** | Driver for TCA9548A/PCA9548A low-voltage 8-channel I2C switch | BSD-3 | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **tda74xx** | Driver for TDA7439/TDA7439DS/TDA7440D audioprocessors | MIT | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **ultrasonic** | Driver for ultrasonic range meters, e.g. HC-SR04, HY-SRF05 | BSD-3 | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | No diff --git a/components/shift_reg/.eil.yml b/components/shift_reg/.eil.yml new file mode 100644 index 000000000..2b0258f17 --- /dev/null +++ b/components/shift_reg/.eil.yml @@ -0,0 +1,24 @@ +--- +components: + - name: shift_reg + description: Driver for generic shift register interface. + group: misc + groups: [] + code_owners: jaimealbq + depends: + # FIXME conditional depends + - name: driver + - name: log + - name: esp_idf_lib_helpers + thread_safe: yes + targets: + - name: esp32 + - name: esp8266 + - name: esp32s2 + - name: esp32c3 + licenses: + - name: ISC + copyrights: + - author: + name: jaimealbq + year: 2022 diff --git a/components/shift_reg/CMakeLists.txt b/components/shift_reg/CMakeLists.txt new file mode 100644 index 000000000..47c458a33 --- /dev/null +++ b/components/shift_reg/CMakeLists.txt @@ -0,0 +1,11 @@ +if(${IDF_TARGET} STREQUAL esp8266) + set(req esp8266 log esp_idf_lib_helpers) +else() + set(req driver log esp_idf_lib_helpers) +endif() + +idf_component_register( + SRCS shift_reg.c + INCLUDE_DIRS . + REQUIRES ${req} +) diff --git a/components/shift_reg/LICENSE b/components/shift_reg/LICENSE new file mode 100644 index 000000000..2f2407118 --- /dev/null +++ b/components/shift_reg/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2022 Jaime Albuquerque + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/components/shift_reg/README.md b/components/shift_reg/README.md new file mode 100644 index 000000000..b88b47b5d --- /dev/null +++ b/components/shift_reg/README.md @@ -0,0 +1,60 @@ +# `Shift Register` +This driver can be used as an interface with a shift register in (still in progress) and out (such as [74HC595](https://www.ti.com/lit/ds/symlink/sn74hc595.pdf)). + +## Usage +To use the library, it needs to be configured before initialize. To do so a `shift_reg_config_t` needs to be set. + +### Configuration +The `shift_reg_config_t` struct store all necessaries configurtions and value of aech register. + +* `uint8_t num_reg` - Number of registers which will be used +* `uint8_t *reg_value` - Vector for the last value of all registers; it can be used for know what is the actual value of the registers + +### Mode configuration +* `struct mode` + * `shift_reg_dir_t dir` - Direction mode of the shift register + * `shift_reg_bit_mode_t bit_mode` - Bit mode + +### Pin configurations +* `struct pin` + * `gpio_num_t clk` - Clock pin + * `gpio_num_t data` - Data/Signal pin + * `gpio_num_t latch` - Latch pin + +#### Direcition mode +The `shift_reg_dir_t` says the direction of the register. +* `SHIFT_DIR_OUTPUT` - Set the register as output +* `SHIFT_DIR_INPUT` - Set the register as input +* `SHIFT_DIR_INPUT_OUTPUT` - Set the register as output and input + +#### First bit configuration +The `shift_reg_bit_mode_t` says the bit mode of the data. +* `SHIFT_BIT_MODE_LSB` - Start send data from the lowest significant bit +* `SHIFT_BIT_MODE_MSB` - Start send data from the most significandt bit + +### Initialization +To initialize the shift register it is going to need to call the `esp_err_t shift_reg_init(shift_reg_config_t *dev)`, by passing the created shift register configurations. + +### De-initialization +Since the `uint8_t *reg_value` is created accordingly of the number of registers, the vector allocate the necessary size in the heap memory, so `esp_err_t shift_reg_deinit(shift_reg_config_t *dev)` can be used to free this memory. + +### Sending the data +To send the intended data, call the `esp_err_t shift_reg_send(uint8_t *data, uint8_t len, shift_reg_config_t *dev)` function, where: +* `data` - the address of the bening of the data +* `len` - the length of the data in bytes +* `dev` - the shift register interface to be used + +**NOTE**: The data sent will be just in the internal memory (register(s)) of the shift register(s), and not reflected in the pins. See lataching pins to see how the pins can be set. + +### Latching pins +To set the pins as it is in the internal memory of the register(s), the function `esp_err_t shift_reg_latch(shift_reg_config_t *dev);` needs to be called. It will be latched by the passed shifter interface. + +## TODO +* [ ] Implement input shift register +* [ ] Interface with [hd44780](../hd44780/) + +# Author +Jaime Albuquerque +* GitHub: [jaimealbq](https://github.com/jaimealbq) +* GitLab: [jaimealbq](https://gitlab.com/jaimealbq) +* LinkedIn: [Jaime Albuquerque](https://www.linkedin.com/in/jaimealbq) diff --git a/components/shift_reg/component.mk b/components/shift_reg/component.mk new file mode 100644 index 000000000..f966ad152 --- /dev/null +++ b/components/shift_reg/component.mk @@ -0,0 +1,7 @@ +COMPONENT_ADD_INCLUDEDIRS = . + +ifdef CONFIG_IDF_TARGET_ESP8266 +COMPONENT_DEPENDS = esp8266 log esp_idf_lib_helpers +else +COMPONENT_DEPENDS = driver log esp_idf_lib_helpers +endif diff --git a/components/shift_reg/shift_reg.c b/components/shift_reg/shift_reg.c new file mode 100644 index 000000000..f74f1eb17 --- /dev/null +++ b/components/shift_reg/shift_reg.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2022 Jaime Albuquerque + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "shift_reg.h" + +static char *tag = "shift_reg"; + +esp_err_t shift_reg_init(shift_reg_config_t *dev) +{ + esp_err_t err = ESP_FAIL; + + if (dev == NULL) + { + ESP_LOGE(tag, "%s: must have the configuration of the shift register", __func__); + err = ESP_ERR_INVALID_ARG; + return err; + } + + dev->reg_value = (uint8_t *)malloc(dev->num_reg); // Create an array with all registers + + if (dev->reg_value == NULL) + { + ESP_LOGE(tag, "%s: no heap memory to allocate reg_value", __func__); + err = ESP_ERR_NO_MEM; + return err; + } + + memset(dev->reg_value, 0, dev->num_reg); // Start all registers as 0 + + gpio_config_t io_conf; + + // disable interrupt + io_conf.intr_type = GPIO_INTR_DISABLE; + + switch (dev->mode.dir) + { + case SHIFT_DIR_OUTPUT: + // set as output mode + io_conf.mode = GPIO_MODE_OUTPUT; + uint32_t buf32_0 = 0; + uint32_t buf32_1 = 0; + uint64_t result = 0; + + if (dev->pin.clk >= 32) + buf32_1 |= 1 << (dev->pin.clk - 32); + else + buf32_0 |= 1 << dev->pin.clk; + + if (dev->pin.latch >= 32) + buf32_1 |= 1 << (dev->pin.latch - 32); + else + buf32_0 |= 1 << dev->pin.latch; + + if (dev->pin.data >= 32) + buf32_1 |= 1 << (dev->pin.data - 32); + else + buf32_0 |= 1 << dev->pin.data; + + result = ((uint64_t)buf32_1 << 32) | ((uint64_t)buf32_0 << 0); + + io_conf.pin_bit_mask = result; + + break; + + default: + ESP_LOGE(tag, "%s: Mode of shift register not found", __func__); + err = ESP_ERR_INVALID_ARG; + break; + } + // 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 + err = gpio_config(&io_conf); + + return err; +} + +esp_err_t shift_reg_deinit(shift_reg_config_t *dev) +{ + if (dev == NULL) + { + ESP_LOGE(tag, "%s: must have a valid argument;", __func__); + return ESP_ERR_INVALID_ARG; + } + + free(dev->reg_value); + return ESP_OK; +} + +esp_err_t shift_reg_send(shift_reg_config_t *dev, uint8_t *data, uint8_t len) +{ + esp_err_t err = ESP_FAIL; + + if (dev == NULL || len > dev->num_reg || data == NULL) + { + ESP_LOGE(tag, "%s: must have a valid argument;", __func__); + err = ESP_ERR_INVALID_ARG; + return err; + } + + if (dev->mode.bit_mode == SHIFT_BIT_MODE_MSB) + { + for (uint8_t i = 0; i < len; i++) + { + shift_reg_send8bits(dev, data[i]); + dev->reg_value[i] = data[i]; + } + } + else + { + for (int8_t i = len - 1; i >= 0; i--) + { + shift_reg_send8bits(dev, data[i]); + dev->reg_value[i] = data[i]; + } + } + + err = ESP_OK; + + return err; +} + +esp_err_t shift_reg_send8bits(shift_reg_config_t *dev, uint8_t data) +{ + esp_err_t err = ESP_FAIL; + + if (dev == NULL) + { + ESP_LOGE(tag, "%s: must have a valid argument;", __func__); + err = ESP_ERR_INVALID_ARG; + return err; + } + + if (dev->mode.bit_mode == SHIFT_BIT_MODE_MSB) + { + // MSB Mode + for (int8_t i = 7; i >= 0; i--) + { + if ((data >> i) & 1) + { + gpio_set_level(dev->pin.data, true); + } + else + { + gpio_set_level(dev->pin.data, false); + } + + gpio_set_level(dev->pin.clk, true); + ets_delay_us(1); + gpio_set_level(dev->pin.clk, false); + ets_delay_us(1); + } + } + else + { + // LSB Mode + for (int8_t i = 0; i < 8; i++) + { + if ((data >> i) & 1) + { + gpio_set_level(dev->pin.data, true); + } + else + { + gpio_set_level(dev->pin.data, false); + } + + gpio_set_level(dev->pin.clk, true); + ets_delay_us(1); + gpio_set_level(dev->pin.clk, false); + ets_delay_us(1); + } + } + + err = ESP_OK; + + return err; +} + +esp_err_t shift_reg_latch(shift_reg_config_t *dev) +{ + gpio_set_level(dev->pin.latch, true); + ets_delay_us(1); + gpio_set_level(dev->pin.latch, false); + ets_delay_us(1); + + return ESP_OK; +} diff --git a/components/shift_reg/shift_reg.h b/components/shift_reg/shift_reg.h new file mode 100644 index 000000000..a8278c801 --- /dev/null +++ b/components/shift_reg/shift_reg.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2022 Jaime Albuquerque + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * @file shift_reg.h + * @defgroup shift_reg shift_reg + * @{ + * + * ESP-IDF driver for generic shift register using 3 pins: + * - data + * - clock + * - latch + * + */ + +#if !defined(__SHIFT_REG__H__) +#define __SHIFT_REG__H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#include +#include +#include +#include + +typedef enum { + SHIFT_DIR_OUTPUT = 0, +} shift_reg_dir_t; + +typedef enum { + SHIFT_BIT_MODE_LSB = 0, + SHIFT_BIT_MODE_MSB, +} shift_reg_bit_mode_t; + +typedef struct { + shift_reg_dir_t dir : 2; // Direction mode of the shift register + shift_reg_bit_mode_t bit_mode : 1; // Bit mode +} shift_reg_mode_t; + +typedef struct { + gpio_num_t clk; // Clock pin + gpio_num_t data; // Data/Signal pin + gpio_num_t latch; // Latch pin +} shift_reg_pin_t; + +typedef struct { // Configuration of shift register + uint8_t num_reg; // Number of shift registers + uint8_t *reg_value; // Last value of all registers + shift_reg_mode_t mode; // Direction adn bit mode + shift_reg_pin_t pin; // Set of pins +} shift_reg_config_t; + +/** + * @brief Initialize the microcontroller to do the output + * + * @param dev shift register configuration + * @return `ESP_OK` on success + */ +esp_err_t shift_reg_init(shift_reg_config_t *dev); + +/** + * @brief Free used memory + * + * @param dev shift register configuration + * @return `ESP_OK` on success + */ +esp_err_t shift_reg_deinit(shift_reg_config_t *dev); + +/** + * @brief Send the whole data + * + * @param dev shift register configuration + * @param data data vector + * @param len length of the data + * @return `ESP_OK` on success + */ +esp_err_t shift_reg_send(shift_reg_config_t *dev, uint8_t *data, uint8_t len); + +/** + * @brief Send 1 byte of data + * + * @param dev shift register configuration + * @param data 1 byte data + * @return `ESP_OK` on success + */ +esp_err_t shift_reg_send8bits(shift_reg_config_t *dev, uint8_t data); + +/** + * @brief Latch the data inside of the shift register + * + * @param dev shift register configuration + * @return `ESP_OK` on success + */ +esp_err_t shift_reg_latch(shift_reg_config_t *dev); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif // __SHIFT_REG__H__ diff --git a/examples/shift_reg/default/CMakeLists.txt b/examples/shift_reg/default/CMakeLists.txt new file mode 100644 index 000000000..4cf2c3020 --- /dev/null +++ b/examples/shift_reg/default/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.5) + +set(EXTRA_COMPONENT_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../../../components) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(example_example) diff --git a/examples/shift_reg/default/Makefile b/examples/shift_reg/default/Makefile new file mode 100644 index 000000000..4de3bb314 --- /dev/null +++ b/examples/shift_reg/default/Makefile @@ -0,0 +1,6 @@ +#V := 1 +PROJECT_NAME := example_example + +EXTRA_COMPONENT_DIRS := $(CURDIR)/../../../components + +include $(IDF_PATH)/make/project.mk diff --git a/examples/shift_reg/default/README.md b/examples/shift_reg/default/README.md new file mode 100644 index 000000000..67cc76ead --- /dev/null +++ b/examples/shift_reg/default/README.md @@ -0,0 +1,39 @@ +# Shift register out + +## What the example does + +The example shift out periodicly to 2 registers [75HC595](https://www.ti.com/lit/ds/symlink/sn74hc595.pdf) a 2 bytes long number, which gets increments. + +## Configuration + +The following configuration was used: + +| 74HC595 | GPIO | +|---------|------| +| Serial Clock | `GPIO_NUM_12` | +| Data/Signal | `GPIO_NUM_15` | +| Latch | `GPIO_NUM_13` | + +| Mode | enum | +|------|------| +| output | `SHIFT_DIR_OUTPUT` | +| Most Significant Bit (MSB) | `SHIFT_BIT_MODE_MSB` | + +``` +static shift_reg_config_t shifter = { + .num_reg = 2, + .mode = { + .dir = SHIFT_DIR_OUTPUT, + .bit_mode = SHIFT_BIT_MODE_MSB, + }, + .pin = { + .clk = GPIO_NUM_12, + .data = GPIO_NUM_13, + .latch = GPIO_NUM_15, + }, + }; +``` + +## Notes + +For more information, please vist the component directory [shift_reg](/components/shift_reg/). \ No newline at end of file diff --git a/examples/shift_reg/default/main/CMakeLists.txt b/examples/shift_reg/default/main/CMakeLists.txt new file mode 100644 index 000000000..cf2c455cb --- /dev/null +++ b/examples/shift_reg/default/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "main.c" + INCLUDE_DIRS ".") diff --git a/examples/shift_reg/default/main/component.mk b/examples/shift_reg/default/main/component.mk new file mode 100644 index 000000000..004b18e68 --- /dev/null +++ b/examples/shift_reg/default/main/component.mk @@ -0,0 +1 @@ +COMPONENT_ADD_INCLUDEDIRS = . diff --git a/examples/shift_reg/default/main/main.c b/examples/shift_reg/default/main/main.c new file mode 100644 index 000000000..84535a2bb --- /dev/null +++ b/examples/shift_reg/default/main/main.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022 Jaime Albuqueruqe + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include + +#include +#include +#include + +void app_main(void) +{ + static shift_reg_config_t shifter = { + .num_reg = 2, + .mode = { + .dir = SHIFT_DIR_OUTPUT, + .bit_mode = SHIFT_BIT_MODE_MSB, + }, + .pin = { + .clk = GPIO_NUM_12, + .data = GPIO_NUM_13, + .latch = GPIO_NUM_15, + }, + }; + + + ESP_ERROR_CHECK(shift_reg_init(&shifter)); + + while (true) { + uint8_t value [2]; + for (uint16_t i = 0; i < 0xFFFF; i++) { + value[0] = (uint8_t) (i & 0xFF); + value[1] = (uint8_t) ((i >> 8) & 0xFF); + ESP_ERROR_CHECK(shift_reg_send(&shifter, value, 2)); + ESP_ERROR_CHECK(shift_reg_latch(&shifter)); + ESP_LOGI(__func__, "reg_value: 0x%02X 0x%02X", shifter.reg_value[0], shifter.reg_value[1]); + vTaskDelay(2 / portTICK_PERIOD_MS); + } + } +} diff --git a/examples/shift_reg/default/sdkconfig.defaults b/examples/shift_reg/default/sdkconfig.defaults new file mode 100644 index 000000000..cd8cb4359 --- /dev/null +++ b/examples/shift_reg/default/sdkconfig.defaults @@ -0,0 +1 @@ +# add required non-default option for the example if any From 1795075cadcfa1eff83992e02389366362310fae Mon Sep 17 00:00:00 2001 From: Jaime Albuquerque Date: Wed, 7 Feb 2024 10:57:03 -0300 Subject: [PATCH 2/7] shift_reg: fixes suggested by reviewers - `examples/shift_reg/default/sdkconfig.defaults`: removed - `README.md`: moved and renamed to `docs/source/groups/shift_reg.rst` - `examples/shift_reg/default/main/main.c`: updated the `portTICK_PERIOD_MS` to `pdMS_TO_TICKS` - `components/shift_reg/shift_reg.h`: added comment in doxygen-style for structures and enums - `components/shift_reg/shift_reg.c`: - `shift_reg_latch()`: added argument checker for `NULL` pointer - `shift_reg_send8bits()`: improved the GPIO set --- components/shift_reg/README.md | 60 ---------- components/shift_reg/shift_reg.c | 31 +++-- components/shift_reg/shift_reg.h | 22 ++++ docs/source/groups/shift_reg.rst | 111 ++++++++++++++++++ examples/shift_reg/default/main/main.c | 2 +- examples/shift_reg/default/sdkconfig.defaults | 1 - 6 files changed, 148 insertions(+), 79 deletions(-) delete mode 100644 components/shift_reg/README.md create mode 100644 docs/source/groups/shift_reg.rst delete mode 100644 examples/shift_reg/default/sdkconfig.defaults diff --git a/components/shift_reg/README.md b/components/shift_reg/README.md deleted file mode 100644 index b88b47b5d..000000000 --- a/components/shift_reg/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# `Shift Register` -This driver can be used as an interface with a shift register in (still in progress) and out (such as [74HC595](https://www.ti.com/lit/ds/symlink/sn74hc595.pdf)). - -## Usage -To use the library, it needs to be configured before initialize. To do so a `shift_reg_config_t` needs to be set. - -### Configuration -The `shift_reg_config_t` struct store all necessaries configurtions and value of aech register. - -* `uint8_t num_reg` - Number of registers which will be used -* `uint8_t *reg_value` - Vector for the last value of all registers; it can be used for know what is the actual value of the registers - -### Mode configuration -* `struct mode` - * `shift_reg_dir_t dir` - Direction mode of the shift register - * `shift_reg_bit_mode_t bit_mode` - Bit mode - -### Pin configurations -* `struct pin` - * `gpio_num_t clk` - Clock pin - * `gpio_num_t data` - Data/Signal pin - * `gpio_num_t latch` - Latch pin - -#### Direcition mode -The `shift_reg_dir_t` says the direction of the register. -* `SHIFT_DIR_OUTPUT` - Set the register as output -* `SHIFT_DIR_INPUT` - Set the register as input -* `SHIFT_DIR_INPUT_OUTPUT` - Set the register as output and input - -#### First bit configuration -The `shift_reg_bit_mode_t` says the bit mode of the data. -* `SHIFT_BIT_MODE_LSB` - Start send data from the lowest significant bit -* `SHIFT_BIT_MODE_MSB` - Start send data from the most significandt bit - -### Initialization -To initialize the shift register it is going to need to call the `esp_err_t shift_reg_init(shift_reg_config_t *dev)`, by passing the created shift register configurations. - -### De-initialization -Since the `uint8_t *reg_value` is created accordingly of the number of registers, the vector allocate the necessary size in the heap memory, so `esp_err_t shift_reg_deinit(shift_reg_config_t *dev)` can be used to free this memory. - -### Sending the data -To send the intended data, call the `esp_err_t shift_reg_send(uint8_t *data, uint8_t len, shift_reg_config_t *dev)` function, where: -* `data` - the address of the bening of the data -* `len` - the length of the data in bytes -* `dev` - the shift register interface to be used - -**NOTE**: The data sent will be just in the internal memory (register(s)) of the shift register(s), and not reflected in the pins. See lataching pins to see how the pins can be set. - -### Latching pins -To set the pins as it is in the internal memory of the register(s), the function `esp_err_t shift_reg_latch(shift_reg_config_t *dev);` needs to be called. It will be latched by the passed shifter interface. - -## TODO -* [ ] Implement input shift register -* [ ] Interface with [hd44780](../hd44780/) - -# Author -Jaime Albuquerque -* GitHub: [jaimealbq](https://github.com/jaimealbq) -* GitLab: [jaimealbq](https://gitlab.com/jaimealbq) -* LinkedIn: [Jaime Albuquerque](https://www.linkedin.com/in/jaimealbq) diff --git a/components/shift_reg/shift_reg.c b/components/shift_reg/shift_reg.c index f74f1eb17..0d1595bc2 100644 --- a/components/shift_reg/shift_reg.c +++ b/components/shift_reg/shift_reg.c @@ -151,14 +151,7 @@ esp_err_t shift_reg_send8bits(shift_reg_config_t *dev, uint8_t data) // MSB Mode for (int8_t i = 7; i >= 0; i--) { - if ((data >> i) & 1) - { - gpio_set_level(dev->pin.data, true); - } - else - { - gpio_set_level(dev->pin.data, false); - } + gpio_set_level(dev->pin.data, (data >> i) & 1); gpio_set_level(dev->pin.clk, true); ets_delay_us(1); @@ -171,14 +164,7 @@ esp_err_t shift_reg_send8bits(shift_reg_config_t *dev, uint8_t data) // LSB Mode for (int8_t i = 0; i < 8; i++) { - if ((data >> i) & 1) - { - gpio_set_level(dev->pin.data, true); - } - else - { - gpio_set_level(dev->pin.data, false); - } + gpio_set_level(dev->pin.data, (data >> i) & 1); gpio_set_level(dev->pin.clk, true); ets_delay_us(1); @@ -194,10 +180,21 @@ esp_err_t shift_reg_send8bits(shift_reg_config_t *dev, uint8_t data) esp_err_t shift_reg_latch(shift_reg_config_t *dev) { + esp_err_t err = ESP_FAIL; + + if (dev == NULL) + { + ESP_LOGE(tag, "%s: must have a valid argument;", __func__); + err = ESP_ERR_INVALID_ARG; + return err; + } + gpio_set_level(dev->pin.latch, true); ets_delay_us(1); gpio_set_level(dev->pin.latch, false); ets_delay_us(1); - return ESP_OK; + err = ESP_OK; + + return err; } diff --git a/components/shift_reg/shift_reg.h b/components/shift_reg/shift_reg.h index a8278c801..2b9184f91 100644 --- a/components/shift_reg/shift_reg.h +++ b/components/shift_reg/shift_reg.h @@ -42,26 +42,48 @@ extern "C" { #include #include +/** + * @brief Direction of the data + * + * @todo Add Input mode + * + */ typedef enum { SHIFT_DIR_OUTPUT = 0, } shift_reg_dir_t; +/** + * @brief Register orientation mode + * + */ typedef enum { SHIFT_BIT_MODE_LSB = 0, SHIFT_BIT_MODE_MSB, } shift_reg_bit_mode_t; +/** + * @brief This structure stores the mode of the shift register + * + */ typedef struct { shift_reg_dir_t dir : 2; // Direction mode of the shift register shift_reg_bit_mode_t bit_mode : 1; // Bit mode } shift_reg_mode_t; +/** + * @brief This structure stores all used pins to interface with the shift register + * + */ typedef struct { gpio_num_t clk; // Clock pin gpio_num_t data; // Data/Signal pin gpio_num_t latch; // Latch pin } shift_reg_pin_t; +/** + * @brief This structure stores all needed configuration of the shift register component + * + */ typedef struct { // Configuration of shift register uint8_t num_reg; // Number of shift registers uint8_t *reg_value; // Last value of all registers diff --git a/docs/source/groups/shift_reg.rst b/docs/source/groups/shift_reg.rst new file mode 100644 index 000000000..252b2de2c --- /dev/null +++ b/docs/source/groups/shift_reg.rst @@ -0,0 +1,111 @@ +``Shift Register`` +================== + +This driver can be used as an interface with a shift register in (still +in progress) and out (such as +`74HC595 `__). + +Usage +----- + +To use the library, it needs to be configured before initialize. To do +so a ``shift_reg_config_t`` needs to be set. + +Configuration +~~~~~~~~~~~~~ + +The ``shift_reg_config_t`` struct store all necessaries configurtions +and value of aech register. + +- ``uint8_t num_reg`` - Number of registers which will be used +- ``uint8_t *reg_value`` - Vector for the last value of all registers; + it can be used for know what is the actual value of the registers + +Mode configuration +~~~~~~~~~~~~~~~~~~ + +- ``struct mode`` + + - ``shift_reg_dir_t dir`` - Direction mode of the shift register + - ``shift_reg_bit_mode_t bit_mode`` - Bit mode + +Pin configurations +~~~~~~~~~~~~~~~~~~ + +- ``struct pin`` + + - ``gpio_num_t clk`` - Clock pin + - ``gpio_num_t data`` - Data/Signal pin + - ``gpio_num_t latch`` - Latch pin + +Direcition mode +^^^^^^^^^^^^^^^ + +The ``shift_reg_dir_t`` says the direction of the register. + +- ``SHIFT_DIR_OUTPUT`` - Set the register as output +- ``SHIFT_DIR_INPUT`` - Set the register as input +- ``SHIFT_DIR_INPUT_OUTPUT`` - Set the register as output and input + +First bit configuration +^^^^^^^^^^^^^^^^^^^^^^^ + +The ``shift_reg_bit_mode_t`` says the bit mode of the data. + +- ``SHIFT_BIT_MODE_LSB`` - Start send data from the lowest significant + bit +- ``SHIFT_BIT_MODE_MSB`` - Start send data from the most significandt + bit + +Initialization +~~~~~~~~~~~~~~ + +To initialize the shift register it is going to need to call the +``esp_err_t shift_reg_init(shift_reg_config_t *dev)``, by passing the +created shift register configurations. + +De-initialization +~~~~~~~~~~~~~~~~~ + +Since the ``uint8_t *reg_value`` is created accordingly of the number of +registers, the vector allocate the necessary size in the heap memory, so +``esp_err_t shift_reg_deinit(shift_reg_config_t *dev)`` can be used to +free this memory. + +Sending the data +~~~~~~~~~~~~~~~~ + +To send the intended data, call the +``esp_err_t shift_reg_send(uint8_t *data, uint8_t len, shift_reg_config_t *dev)`` +function, where: + +- ``data`` - the address of the bening of the data +- ``len`` - the length of the data in bytes +- ``dev`` - the shift register interface to be used + +**NOTE**: The data sent will be just in the internal memory +(register(s)) of the shift register(s), and not reflected in the pins. +See lataching pins to see how the pins can be set. + +Latching pins +~~~~~~~~~~~~~ + +To set the pins as it is in the internal memory of the register(s), the +function ``esp_err_t shift_reg_latch(shift_reg_config_t *dev);`` needs +to be called. It will be latched by the passed shifter interface. + +TODO +---- + +- ☐ Implement input shift register +- ☐ Interface with `hd44780 <../hd44780/>`__ + +Author +====== + +Jaime Albuquerque + +- GitHub: `jaimealbq `__ +- GitLab: `jaimealbq `__ +- LinkedIn: `Jaime + Albuquerque `__ diff --git a/examples/shift_reg/default/main/main.c b/examples/shift_reg/default/main/main.c index 84535a2bb..21cf1655c 100644 --- a/examples/shift_reg/default/main/main.c +++ b/examples/shift_reg/default/main/main.c @@ -49,7 +49,7 @@ void app_main(void) ESP_ERROR_CHECK(shift_reg_send(&shifter, value, 2)); ESP_ERROR_CHECK(shift_reg_latch(&shifter)); ESP_LOGI(__func__, "reg_value: 0x%02X 0x%02X", shifter.reg_value[0], shifter.reg_value[1]); - vTaskDelay(2 / portTICK_PERIOD_MS); + vTaskDelay(2 / pdMS_TO_TICKS); } } } diff --git a/examples/shift_reg/default/sdkconfig.defaults b/examples/shift_reg/default/sdkconfig.defaults deleted file mode 100644 index cd8cb4359..000000000 --- a/examples/shift_reg/default/sdkconfig.defaults +++ /dev/null @@ -1 +0,0 @@ -# add required non-default option for the example if any From eaaf6bb42108f054df3555ebd8d77a8c2b4fdf4e Mon Sep 17 00:00:00 2001 From: Jaime Albuquerque Date: Wed, 7 Feb 2024 11:04:27 -0300 Subject: [PATCH 3/7] shift_reg: conflict fix part 1 --- .github/labeler.yml | 8 -------- README.md | 1 - 2 files changed, 9 deletions(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index 4a4bfa55f..af34653ae 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -536,14 +536,6 @@ labels: - "components/sgp40/**" - "components/sgp40/.eil.yml" - "examples/sgp40/**" - - label: "area:components:shift_reg" - sync: true - matcher: - files: - any: - - "components/shift_reg/**" - - "components/shift_reg/.eil.yml" - - "examples/shift_reg/**" - label: "area:components:sht3x" sync: true matcher: diff --git a/README.md b/README.md index d02365250..1c791c3d7 100644 --- a/README.md +++ b/README.md @@ -213,7 +213,6 @@ or [GitLab examples](https://gitlab.com/UncleRus/esp-idf-lib/tree/master/example | **lc709203f** | Driver for LC709203F battery fuel gauge | ISC | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **pca9685** | Driver for 16-channel, 12-bit PWM PCA9685 | BSD-3 | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **rda5807m** | Driver for single-chip broadcast FM radio tuner RDA5807M | BSD-3 | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes -| **shift_reg** | Driver for generic shift register interface. | ISC | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **tca9548** | Driver for TCA9548A/PCA9548A low-voltage 8-channel I2C switch | BSD-3 | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **tda74xx** | Driver for TDA7439/TDA7439DS/TDA7440D audioprocessors | MIT | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **ultrasonic** | Driver for ultrasonic range meters, e.g. HC-SR04, HY-SRF05 | BSD-3 | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | No From b6393298c0a88c53714490521622135a542ef3a4 Mon Sep 17 00:00:00 2001 From: Jaime Albuquerque Date: Wed, 7 Feb 2024 11:05:06 -0300 Subject: [PATCH 4/7] shift_reg: conflict fix part 2 --- .github/labeler.yml | 8 ++++++++ README.md | 1 + 2 files changed, 9 insertions(+) diff --git a/.github/labeler.yml b/.github/labeler.yml index af34653ae..4a4bfa55f 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -536,6 +536,14 @@ labels: - "components/sgp40/**" - "components/sgp40/.eil.yml" - "examples/sgp40/**" + - label: "area:components:shift_reg" + sync: true + matcher: + files: + any: + - "components/shift_reg/**" + - "components/shift_reg/.eil.yml" + - "examples/shift_reg/**" - label: "area:components:sht3x" sync: true matcher: diff --git a/README.md b/README.md index 1c791c3d7..d02365250 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,7 @@ or [GitLab examples](https://gitlab.com/UncleRus/esp-idf-lib/tree/master/example | **lc709203f** | Driver for LC709203F battery fuel gauge | ISC | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **pca9685** | Driver for 16-channel, 12-bit PWM PCA9685 | BSD-3 | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **rda5807m** | Driver for single-chip broadcast FM radio tuner RDA5807M | BSD-3 | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes +| **shift_reg** | Driver for generic shift register interface. | ISC | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **tca9548** | Driver for TCA9548A/PCA9548A low-voltage 8-channel I2C switch | BSD-3 | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **tda74xx** | Driver for TDA7439/TDA7439DS/TDA7440D audioprocessors | MIT | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **ultrasonic** | Driver for ultrasonic range meters, e.g. HC-SR04, HY-SRF05 | BSD-3 | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | No From 90b4edb9a54f87c841b100c234a5feaf49a88c10 Mon Sep 17 00:00:00 2001 From: Jaime Albuquerque Date: Wed, 7 Feb 2024 11:05:45 -0300 Subject: [PATCH 5/7] shift_reg: conflict fix part 3 --- .github/labeler.yml | 8 -------- README.md | 1 - 2 files changed, 9 deletions(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index 4a4bfa55f..af34653ae 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -536,14 +536,6 @@ labels: - "components/sgp40/**" - "components/sgp40/.eil.yml" - "examples/sgp40/**" - - label: "area:components:shift_reg" - sync: true - matcher: - files: - any: - - "components/shift_reg/**" - - "components/shift_reg/.eil.yml" - - "examples/shift_reg/**" - label: "area:components:sht3x" sync: true matcher: diff --git a/README.md b/README.md index d02365250..1c791c3d7 100644 --- a/README.md +++ b/README.md @@ -213,7 +213,6 @@ or [GitLab examples](https://gitlab.com/UncleRus/esp-idf-lib/tree/master/example | **lc709203f** | Driver for LC709203F battery fuel gauge | ISC | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **pca9685** | Driver for 16-channel, 12-bit PWM PCA9685 | BSD-3 | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **rda5807m** | Driver for single-chip broadcast FM radio tuner RDA5807M | BSD-3 | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes -| **shift_reg** | Driver for generic shift register interface. | ISC | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **tca9548** | Driver for TCA9548A/PCA9548A low-voltage 8-channel I2C switch | BSD-3 | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **tda74xx** | Driver for TDA7439/TDA7439DS/TDA7440D audioprocessors | MIT | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | Yes | **ultrasonic** | Driver for ultrasonic range meters, e.g. HC-SR04, HY-SRF05 | BSD-3 | `esp32`, `esp8266`, `esp32s2`, `esp32c3` | No From b2a3ec93d7338cae16790f6c45a56260e807216a Mon Sep 17 00:00:00 2001 From: Jaime Albuquerque Date: Wed, 7 Feb 2024 11:19:56 -0300 Subject: [PATCH 6/7] shift_reg: conflict fix part 3 `.eil.yml`: updated --- components/shift_reg/.eil.yml | 44 ++++++++++++++++------------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/components/shift_reg/.eil.yml b/components/shift_reg/.eil.yml index 2b0258f17..6872bbecd 100644 --- a/components/shift_reg/.eil.yml +++ b/components/shift_reg/.eil.yml @@ -1,24 +1,20 @@ ---- -components: - - name: shift_reg - description: Driver for generic shift register interface. - group: misc - groups: [] - code_owners: jaimealbq - depends: - # FIXME conditional depends - - name: driver - - name: log - - name: esp_idf_lib_helpers - thread_safe: yes - targets: - - name: esp32 - - name: esp8266 - - name: esp32s2 - - name: esp32c3 - licenses: - - name: ISC - copyrights: - - author: - name: jaimealbq - year: 2022 +name: shift_reg +description: Driver for generic shift register interface. +version: 0.0.1 +groups: + - misc +code_owners: jaimealbq +depends: + - name: driver + - name: log + - name: esp_idf_lib_helpers +thread_safe: yes +targets: + - esp32 + - esp8266 + - esp32s2 + - esp32c3 +license: ISC +copyrights: + - name: jaimealbq + year: 2022 From 177b64af1095df6cf66edbac650c4c1610075eac Mon Sep 17 00:00:00 2001 From: Jaime Albuquerque Date: Wed, 7 Feb 2024 11:23:42 -0300 Subject: [PATCH 7/7] shift_reg: conflict fix part 5 `.eil.yml`: updated --- components/shift_reg/.eil.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/shift_reg/.eil.yml b/components/shift_reg/.eil.yml index 6872bbecd..de897d317 100644 --- a/components/shift_reg/.eil.yml +++ b/components/shift_reg/.eil.yml @@ -3,7 +3,7 @@ description: Driver for generic shift register interface. version: 0.0.1 groups: - misc -code_owners: jaimealbq +code_owners: JaimeAlbq depends: - name: driver - name: log @@ -16,5 +16,5 @@ targets: - esp32c3 license: ISC copyrights: - - name: jaimealbq + - name: JaimeAlbq year: 2022