-
Notifications
You must be signed in to change notification settings - Fork 452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature: shift register #458
Draft
JaimeAlbq
wants to merge
8
commits into
UncleRus:master
Choose a base branch
from
JaimeAlbq:feature-shift-reg
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 1 commit
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
5134fda
shift_reg: add shift_reg component
JaimeAlbq 1795075
shift_reg: fixes suggested by reviewers
JaimeAlbq eaaf6bb
shift_reg: conflict fix part 1
JaimeAlbq b639329
shift_reg: conflict fix part 2
JaimeAlbq 90b4edb
shift_reg: conflict fix part 3
JaimeAlbq ff3d19d
Merge branch 'UncleRus:master' into feature-shift-reg
JaimeAlbq b2a3ec9
shift_reg: conflict fix part 3
JaimeAlbq 177b64a
shift_reg: conflict fix part 5
JaimeAlbq File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
Copyright (c) 2022 Jaime Albuquerque <[email protected]> | ||
|
||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
/* | ||
* Copyright (c) 2022 Jaime Albuquerque <[email protected]> | ||
* | ||
* 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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This condition can be replaced by a single expression: gpio_set_level(dev->pin.data, (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); | ||
UncleRus marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here we need to check if dev is NULL |
||
ets_delay_us(1); | ||
gpio_set_level(dev->pin.latch, false); | ||
ets_delay_us(1); | ||
|
||
return ESP_OK; | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should go to the header file so that users can see this in the official documentation. see other documentation pages under
docs/source/groups
.