shift register added to the component

This commit is contained in:
Bogdan Pilyugin 2025-04-18 17:51:42 +02:00
parent 45284cb4db
commit 9585559ab7
7 changed files with 219 additions and 1 deletions

View File

@ -26,6 +26,7 @@ idf_component_register(
"src/CronTimers.c"
"src/SerialPort.c"
src/PPPoS.c
src/ShiftRegisterSPI.c
src/sdcard.c
src/FileBlockHandler.c
src/OTA.c

36
Kconfig
View File

@ -818,6 +818,42 @@ menu "WebGUIApp"
default n
endmenu
menu "SR IO extender configuration"
config WEBGUIAPP_SR_ENABLE
bool "Enabled SR IO extender"
default n
config WEBGUIAPP_SR_CLOCK_MHZ
int "SR extender clock speed (MHz)"
range 1 20
default 10 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32C3
default 30 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
help
Set the clock speed (MHz) of SPI interface.
config WEBGUIAPP_SR_CS
int "SR SC signal GPIO"
range GPIO_RANGE_MIN GPIO_RANGE_MAX
default 12
help
Set GPIO for chip select signal.
config WEBGUIAPP_SR_OUTPUTS
int "SR outputs number"
range 0 64
default 8
help
Set the number of outputs (must be a multiple of 8).
config WEBGUIAPP_SR_INPUTS
int "SR inputs number"
range 0 64
default 8
help
Set the number of inputs (must be a multiple of 8).
endmenu
menu "Serial port configuration"
config WEBGUIAPP_UART_TRANSPORT_ENABLE

View File

@ -0,0 +1,51 @@
/*
* ShiftRegisterSPI.h
*
* Created on: Apr 18, 2025
* Author: bogd
*/
#ifndef COMPONENTS_WEBGUIAPP_INCLUDE_SHIFTREGISTERSPI_H_
#define COMPONENTS_WEBGUIAPP_INCLUDE_SHIFTREGISTERSPI_H_
#include "esp_err.h"
typedef enum {
VGPIO_NUM_NC = -1,
VGPIO_NUM_0 = 0,
VGPIO_NUM_1 = 1,
VGPIO_NUM_2 = 2,
VGPIO_NUM_3 = 3,
VGPIO_NUM_4 = 4,
VGPIO_NUM_5 = 5,
VGPIO_NUM_6 = 6,
VGPIO_NUM_7 = 7,
VGPIO_NUM_MAX,
/** @endcond */
} virtual_gpio_num_t;
typedef enum {
VGPIO_MOTOR_IN1 = 0,
VGPIO_MOTOR_IN2,
VGPIO_PILOT_RELAY,
VGPIO_RELAY1,
VGPIO_RELAY2,
VGPIO_TRIAC1,
VGPIO_TRIAC2,
VGPIO_TRIAC3
} virtual_gpio_funct_t;
esp_err_t ShiftRegInit(void);
esp_err_t vgpio_set_level(virtual_gpio_num_t gpio_num, uint8_t *gpio_level);
esp_err_t vgpio_get_level(virtual_gpio_num_t gpio_num, uint8_t *gpio_level);
esp_err_t vgpi_get_level(int gpio_num, uint8_t *gpio_level);
esp_err_t vgpio_set_reg(uint8_t reg);
void GPIOExtenderTxRx(uint8_t *tx, uint8_t *rx, int bt);
void GPIOInputRead(int num, int *val);
void GPIOInputWrite(int num, int *val);
#endif /* COMPONENTS_WEBGUIAPP_INCLUDE_SHIFTREGISTERSPI_H_ */

View File

@ -35,6 +35,7 @@
#include "SystemApplication.h"
#include "UserCallbacks.h"
#include "CommandProcSys.h"
#include "ShiftRegisterSPI.h"
esp_err_t spi_device_polling_transmit_synchronized(spi_device_handle_t handle, spi_transaction_t *trans_desc);

View File

@ -309,7 +309,7 @@ static void GSMRunTask(void *pvParameter) {
void PPPModemStart(void) {
xTaskCreatePinnedToCore(GSMRunTask, "GSMRunTask", 1024 * 4, &ResetType, 3,
NULL, 1);
NULL, 0);
}
int PPPModemGetRSSI(void) {

123
src/ShiftRegisterSPI.c Normal file
View File

@ -0,0 +1,123 @@
/*
* ShiftRegisterSPI.c
*
* Created on: Apr 18, 2025
* Author: bogd
*/
#include "SysConfiguration.h"
#include "webguiapp.h"
#include "sdkconfig.h"
#include "esp_timer.h"
#ifdef CONFIG_WEBGUIAPP_SR_ENABLE
#define TAG "ShiftRegDriver"
#define CONFIG_SHIFTREG_SPI_HOST (1)
#define CONFIG_SHIFTREG_SPI_CLOCK_HZ (10000000)
#define CONFIG_SHIFTREG_SPI_CS_GPIO (12)
#define CONFIG_SHIFTREG_SAMPLES_MS (10)
static spi_device_handle_t spi_shift_handle;
static spi_transaction_t spi_shift_transaction;
static uint8_t inputs[] = { 0, 0 }, outputs[] = { 0, 0 };
static const int SHIFTREG_SAMPLE_START_BIT = BIT0;
static EventGroupHandle_t digio_event_group = NULL;
static SemaphoreHandle_t xSemaphoreShiftRegHandle = NULL;
static StaticSemaphore_t xSemaphoreShiftRegBuf;
esp_timer_handle_t shiftreg_timer, inputs_periodical_timer;
void ShiftRegSampleStart(void *arg);
const esp_timer_create_args_t shiftreg_timer_args = { .callback = &ShiftRegSampleStart, .name = "shiftregTimer" };
void ShiftRegSampleStart(void *arg)
{
xEventGroupSetBits(digio_event_group, SHIFTREG_SAMPLE_START_BIT);
}
static esp_err_t shiftreg_txrx_transaction(uint8_t *tx, uint8_t *rx, int bits)
{
memset(&spi_shift_transaction, 0, sizeof(spi_shift_transaction));
spi_shift_transaction.cmd = 0;
spi_shift_transaction.addr = 0;
spi_shift_transaction.length = bits;
spi_shift_transaction.tx_buffer = tx;
spi_shift_transaction.rx_buffer = rx;
spi_shift_transaction.rxlength = 0;
esp_err_t err = spi_device_polling_transmit(spi_shift_handle, &spi_shift_transaction);
ESP_ERROR_CHECK(err);
return err;
}
static void shift_reg_task(void *pvParameter)
{
while (1)
{
xEventGroupWaitBits(digio_event_group, SHIFTREG_SAMPLE_START_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
xSemaphoreTake(xSemaphoreShiftRegHandle, portMAX_DELAY);
shiftreg_txrx_transaction(outputs, inputs, 8);
xSemaphoreGive(xSemaphoreShiftRegHandle);
}
}
esp_err_t ShiftRegInit(void)
{
spi_device_interface_config_t devcfg = { .command_bits = 0, .address_bits = 0, .mode = 0, .clock_speed_hz = CONFIG_SHIFTREG_SPI_CLOCK_HZ, .queue_size = 10, .spics_io_num = 12 };
esp_err_t ret = spi_bus_add_device(CONFIG_SHIFTREG_SPI_HOST, &devcfg, &spi_shift_handle);
ESP_ERROR_CHECK(ret);
outputs[0] = 0b00110000;
digio_event_group = xEventGroupCreate();
xSemaphoreShiftRegHandle = xSemaphoreCreateBinaryStatic(&xSemaphoreShiftRegBuf);
xSemaphoreGive(xSemaphoreShiftRegHandle);
ESP_ERROR_CHECK(esp_timer_create(&shiftreg_timer_args, &shiftreg_timer));
ESP_ERROR_CHECK(esp_timer_start_periodic(shiftreg_timer, CONFIG_SHIFTREG_SAMPLES_MS * 1000));
ESP_LOGI(TAG, "HC595 SPI device init OK");
return ESP_OK;
}
esp_err_t vgpio_set_level(virtual_gpio_num_t gpio_num, uint8_t *gpio_level)
{
if (gpio_num < 0 || gpio_num >= VGPIO_NUM_MAX)
return ESP_ERR_INVALID_ARG;
uint8_t lv = *gpio_level & 1;
xSemaphoreTake(xSemaphoreShiftRegHandle, portMAX_DELAY);
outputs[0] = (outputs[0] & ~(1 << gpio_num)) | (lv << gpio_num);
shiftreg_txrx_transaction(outputs, inputs, 8);
xSemaphoreGive(xSemaphoreShiftRegHandle);
return ESP_OK;
}
esp_err_t vgpio_get_level(virtual_gpio_num_t gpio_num, uint8_t *gpio_level)
{
if (gpio_num < 0 || gpio_num >= VGPIO_NUM_MAX)
return ESP_ERR_INVALID_ARG;
*gpio_level = (outputs[0] & (1 << gpio_num)) ? 1 : 0;
return ESP_OK;
}
esp_err_t vgpio_set_reg(uint8_t reg)
{
if (xSemaphoreTake(xSemaphoreShiftRegHandle, pdMS_TO_TICKS(50)) == pdTRUE)
{
outputs[0] = (outputs[0] & 0b11110001) | (reg << 1);
shiftreg_txrx_transaction(outputs, inputs, 8);
xSemaphoreGive(xSemaphoreShiftRegHandle);
return ESP_OK;
}
else
{
ESP_LOGW(TAG, "Can't obtain SPI bus");
return ESP_ERR_NOT_FINISHED;
}
}
#endif

View File

@ -23,6 +23,7 @@
#include "../include/SysConfiguration.h"
#include "ShiftRegisterSPI.h"
#include "SystemApplication.h"
#include <webguiapp.h>
#include "stdlib.h"
@ -98,6 +99,11 @@ esp_err_t WebGuiAppInit(void)
#if CONFIG_WEBGUIAPP_SPI_ENABLE
InitSysSPI();
#endif
#ifdef CONFIG_WEBGUIAPP_SR_ENABLE
ShiftRegInit();
#endif
#if CONFIG_WEBGUIAPP_I2C_ENABLE
InitSysI2C();
#endif