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

linuxpaul
Posts: 35
Joined: Thu Jul 20, 2017 6:10 pm

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

Postby linuxpaul » Sun Jun 24, 2018 1:30 pm

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

linuxpaul
Posts: 35
Joined: Thu Jul 20, 2017 6:10 pm

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

Postby linuxpaul » Thu Jun 28, 2018 6:30 pm

Code not nice but works :)
obviously there is a memory defekt.
HW changed after spending some time in settings and debugging attempts.

Who is online

Users browsing this forum: dmitryga and 7 guests