Page 1 of 1

TCP UART Bridge for HM-MOD-RPI-PCB challenge

Posted: Sun Jun 24, 2018 1:30 pm
by linuxpaul
Hello Forum,

I try to make a solution sending Homematic data over WLan.
After struggeling around with configurations and serveral examples,
this code do basicly this function.

Code: Select all

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
#include "driver/uart.h"
#include "lwip/sockets.h"

#define PORT_NUMBER 23
#define WIFI_PW CONFIG_WIFI_PASSWORD
#define WIFI_SSID CONFIG_WIFI_SSID
#define EX_UART_NUM UART_NUM_1
#define BUF_SIZE 128
#define TXD_IO  (GPIO_NUM_10)
#define RXD_IO (GPIO_NUM_9)

static struct sockaddr_in serverAddress;
static struct sockaddr_in clientAddress;

static char tag[] = "socket_server";
static int sock = -1;
static int clientSock = 0;

static uint8_t init_socket(void)
{
	int ret = 0;
	u32_t optlen = sizeof(ret);
	socklen_t clientAddressLength = sizeof(clientAddress);
	clientSock = accept(sock, (struct sockaddr *)&clientAddress, &clientAddressLength);
	if (clientSock < 1) {
		ESP_LOGE(tag, "NOT accept: %d %s", clientSock, strerror(errno));
		return 0;
	}
	getsockopt(clientSock, SOL_SOCKET, SO_ERROR, &ret, &optlen);
	ESP_LOGI(tag, "accept: %d %s ", clientSock, strerror(ret));
	return 1;
}

static void uart_tx_Task(void *pvParameters)
{
    static const char *TX_TAG = "TX_TASK";
    esp_log_level_set(TX_TAG, ESP_LOG_INFO);
    static const char *RX_TAG = "RX_TASK";
    esp_log_level_set(RX_TAG, ESP_LOG_INFO);

    uint8_t* txdata = (uint8_t*)malloc(10*BUF_SIZE);
    uint8_t* rxdata = (uint8_t*)malloc(10*BUF_SIZE);


	ssize_t socketRead;
	ssize_t socketWrite;

	int uartWrite;
	int uartRead;

	int ret = 0;
	u32_t optlen = sizeof(ret);

    uint8_t stateRead = 1;
    uint8_t stateWrite = 0;
	uint8_t client_connected = (uint8_t)init_socket();

	while (1) {


		if(! client_connected)
			{
				if(init_socket())
				{
					stateRead = 1;
					stateWrite = 0;
					client_connected = 1;
				}
			}
		else if(client_connected && stateRead) {
			socketRead = recv(clientSock, txdata, 10*BUF_SIZE, 0);
 			if (socketRead <= 0) {
				getsockopt(clientSock, SOL_SOCKET, SO_ERROR, &ret, &optlen);
				ESP_LOGE(tag, "Socket Closed: %d %s", clientSock, strerror(ret));
				close(clientSock);
				stateRead = 0;
				stateWrite = 0;
				client_connected = 0;
			}
			else {
	    		uartWrite = uart_write_bytes(EX_UART_NUM, (const char*) txdata, socketRead);
	    		ESP_LOGI(TX_TAG, "uart data Sent: %s, bytes: %d,", txdata,uartWrite);
//	    		ESP_LOG_BUFFER_HEX(TX_TAG,txdata,uartWrite );
				stateRead = 0;
				stateWrite = 1;
			}
 			vTaskDelay(100 / portTICK_PERIOD_MS);
		}
		else if(client_connected && stateWrite)  {
	    	uartRead = uart_read_bytes(EX_UART_NUM, rxdata, 10*BUF_SIZE, 100 / portTICK_PERIOD_MS);
	    	if(uartRead > 0) {
	    		ESP_LOGI(RX_TAG, "Uart Data receive:d %s, bytes: %d", rxdata,uartRead);
	    		socketWrite = send(clientSock, rxdata, uartRead, 0);
	    		if (socketWrite <= 0) {
	    			getsockopt(clientSock, SOL_SOCKET, SO_ERROR, &ret, &optlen);
	    			ESP_LOGE(tag, "Socket Closed: %d %s", clientSock, strerror(ret));
					close(clientSock);
					stateRead = 0;
					stateWrite = 0;
					client_connected = 0;
	    		}
	    		else {
	    			ESP_LOGI(RX_TAG, "Data sent Socket: %s, bytes: %d, socket %d", rxdata, socketWrite,clientSock);
//	    	   		ESP_LOG_BUFFER_HEX(RX_TAG,rxdata,socketWrite );
	    			stateRead = 1;
	    			stateWrite = 0;
	    		}
	    	}
	    }

	}
	vTaskDelete(NULL);

}


static void tcp_sock_init(void)
{
	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sock < 0) {
		ESP_LOGE(tag, "socket: %d %s", sock, strerror(errno));
		exit(1);
	}
	ESP_LOGI(tag, "socket created");
	serverAddress.sin_family = AF_INET;
	serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
	serverAddress.sin_port = htons(PORT_NUMBER);
	int rc  = bind(sock, (struct sockaddr *)&serverAddress, sizeof(serverAddress));

	if (rc < 0) {
		ESP_LOGE(tag, "bind: %d %s", rc, strerror(errno));
		exit(1);
	}
	ESP_LOGI(tag, "socket bound");
	rc = listen(sock,1);
	if (rc < 0) {
		ESP_LOGE(tag, "listen: %d %s", rc, strerror(errno));
		exit(1);
	}
	ESP_LOGI(tag, "socket listen");
	xTaskCreate(uart_tx_Task, "uart_tx_Task", 4000, NULL, 5, NULL);

}


esp_err_t event_handler(void *ctx, system_event_t *event)
{
	switch (event->event_id){
		case SYSTEM_EVENT_STA_GOT_IP:
			printf("Our IP address is " IPSTR "\n", IP2STR(&event->event_info.got_ip.ip_info.ip));
			printf("Starting TCP Socket Init...\n");
			tcp_sock_init();
			break;

		case SYSTEM_EVENT_WIFI_READY:
			printf("Wifi ready\n");
			break;

		case SYSTEM_EVENT_STA_START:
			printf("Station started\n");
			break;

		case SYSTEM_EVENT_STA_CONNECTED:
			printf("Station connected\n");
			break;

		default:
			printf("Other Event\n");
			break;
	}
	return ESP_OK;
}


static void wifi_init(void)
{
    ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
    ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
    wifi_config_t sta_config = {
        .sta = {
            .ssid = WIFI_SSID,
            .password = WIFI_PW,
            .bssid_set = false
        }
    };
    ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config) );
    ESP_ERROR_CHECK( esp_wifi_start() );
    ESP_ERROR_CHECK( esp_wifi_connect() );
}


static void uart_init(void)
{
    /* Configure parameters of an UART driver,
     * communication pins and install the driver */
    uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
    };
    uart_param_config(EX_UART_NUM, &uart_config);
    uart_set_pin(EX_UART_NUM, TXD_IO, RXD_IO, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
    uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 20, NULL, 0);
}

void app_main(void)
{
    nvs_flash_init();
    tcpip_adapter_init();
    wifi_init();
    uart_init();

    gpio_set_direction(GPIO_NUM_2, GPIO_MODE_OUTPUT);
    int level = 0;
    while (true) {
        gpio_set_level(GPIO_NUM_2, level);
        level = !level;
        vTaskDelay(500 / portTICK_PERIOD_MS);
    }
}

Unfortunately I'm faced with sporatic "Illagal Instruction" unhanled exceptions
after seconds or some minutes on CPU0 which leads to a hanging system or reboot.
I think I need something like a flow control but in which manner?
Events? Interrupt? SW flowcontrol? What is the common way in this case?
Maybe with a little example?

regards,
linuxpaul

Re: TCP UART Bridge for HM-MOD-RPI-PCB challenge

Posted: Thu Jun 28, 2018 6:30 pm
by linuxpaul
Code not nice but works :)
obviously there is a memory defekt.
HW changed after spending some time in settings and debugging attempts.