4 #include <esp_system.h>
10 #include <esp_timer.h>
12 static const char* KTAG =
"KNX_LIB";
37 nvs_close(_nvs_handle);
50 ESP_LOGI(KTAG,
"UART baud rate set to %lu", _baudRate);
60 ESP_LOGE(KTAG,
"FATAL ERROR. System halted.");
64 vTaskDelay(pdMS_TO_TICKS(1000));
73 uart_config_t uart_config;
74 memset(&uart_config, 0,
sizeof(uart_config));
75 uart_config.baud_rate = _baudRate;
76 uart_config.data_bits = UART_DATA_8_BITS;
77 uart_config.parity = UART_PARITY_EVEN;
78 uart_config.stop_bits = UART_STOP_BITS_1;
79 uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
80 uart_config.source_clk = UART_SCLK_DEFAULT;
82 ESP_ERROR_CHECK(uart_driver_install(_uart_num, 256 * 2, 0, 0, NULL, 0));
83 ESP_ERROR_CHECK(uart_param_config(_uart_num, &uart_config));
84 ESP_ERROR_CHECK(uart_set_pin(_uart_num, _txPin, _rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
85 _uart_installed =
true;
86 ESP_LOGI(KTAG,
"UART initialized with baud rate %lu", _baudRate);
93 uart_driver_delete(_uart_num);
94 _uart_installed =
false;
102 ESP_ERROR_CHECK(uart_get_buffered_data_len(_uart_num, &length));
108 if (!_uart_installed)
110 return uart_write_bytes(_uart_num, &data, 1);
115 if (!_uart_installed)
117 return uart_write_bytes(_uart_num, buffer, size);
122 if (!_uart_installed)
125 if (uart_read_bytes(_uart_num, &data, 1, pdMS_TO_TICKS(20)) > 0)
134 if (!_uart_installed)
136 return uart_read_bytes(_uart_num, buffer, length, pdMS_TO_TICKS(100));
141 if (!_uart_installed)
143 ESP_ERROR_CHECK(uart_flush(_uart_num));
150 esp_netif_ip_info_t ip_info;
151 esp_netif_get_ip_info(_netif, &ip_info);
152 return ip_info.ip.addr;
159 esp_netif_ip_info_t ip_info;
160 esp_netif_get_ip_info(_netif, &ip_info);
161 return ip_info.netmask.addr;
168 esp_netif_ip_info_t ip_info;
169 esp_netif_get_ip_info(_netif, &ip_info);
170 return ip_info.gw.addr;
177 esp_netif_get_mac(_netif, addr);
183 esp_efuse_mac_get_default(mac);
185 for (
int i = 0; i < 6; i++)
187 chipid |= ((uint64_t)mac[i] << (i * 8));
189 uint32_t upperId = (chipid >> 32) & 0xFFFFFFFF;
190 uint32_t lowerId = (chipid & 0xFFFFFFFF);
191 return (upperId ^ lowerId);
196 ESP_LOGI(KTAG,
"Restarting system...");
202 _multicast_addr = addr;
203 _multicast_port = port;
205 _sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
208 ESP_LOGE(KTAG,
"Failed to create socket. Errno: %d", errno);
212 struct sockaddr_in saddr;
213 memset(&saddr, 0,
sizeof(saddr));
214 saddr.sin_family = AF_INET;
215 saddr.sin_port = htons(port);
216 saddr.sin_addr.s_addr = htonl(INADDR_ANY);
217 if (bind(_sock, (
struct sockaddr*)&saddr,
sizeof(
struct sockaddr_in)) < 0)
219 ESP_LOGE(KTAG,
"Failed to bind socket. Errno: %d", errno);
225 struct ip_mreq imreq;
226 memset(&imreq, 0,
sizeof(imreq));
227 imreq.imr_interface.s_addr = IPADDR_ANY;
228 imreq.imr_multiaddr.s_addr = addr;
229 if (setsockopt(_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imreq,
sizeof(
struct ip_mreq)) < 0)
231 ESP_LOGE(KTAG,
"Failed to join multicast group. Errno: %d", errno);
237 ESP_LOGI(KTAG,
"Successfully joined multicast group on port %d", port);
254 struct sockaddr_in dest_addr = {};
255 dest_addr.sin_family = AF_INET;
256 dest_addr.sin_port = htons(_multicast_port);
257 dest_addr.sin_addr.s_addr = _multicast_addr;
259 int sent_len = sendto(_sock, buffer, len, 0, (
struct sockaddr*)&dest_addr,
sizeof(dest_addr));
262 ESP_LOGE(KTAG,
"sendBytesMultiCast failed. Errno: %d", errno);
265 return sent_len == len;
273 socklen_t socklen =
sizeof(_remote_addr);
274 int len = recvfrom(_sock, buffer, maxLen, 0, (
struct sockaddr*)&_remote_addr, &socklen);
281 src_addr = _remote_addr.sin_addr.s_addr;
282 src_port = ntohs(_remote_addr.sin_port);
292 struct sockaddr_in dest_addr;
293 dest_addr.sin_family = AF_INET;
297 dest_addr.sin_addr.s_addr = _remote_addr.sin_addr.s_addr;
301 dest_addr.sin_addr.s_addr = addr;
306 dest_addr.sin_port = _remote_addr.sin_port;
310 dest_addr.sin_port = htons(port);
313 if (sendto(_sock, buffer, len, 0, (
struct sockaddr*)&dest_addr,
sizeof(dest_addr)) < 0)
315 ESP_LOGE(KTAG,
"sendBytesUniCast failed. Errno: %d", errno);
324 if (_eeprom_buffer && _eeprom_size == size)
326 return _eeprom_buffer;
331 free(_eeprom_buffer);
332 _eeprom_buffer =
nullptr;
336 _eeprom_buffer = (uint8_t*)malloc(size);
339 ESP_LOGE(KTAG,
"Failed to allocate EEPROM buffer");
344 esp_err_t err = nvs_flash_init();
345 if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND)
347 ESP_ERROR_CHECK(nvs_flash_erase());
348 err = nvs_flash_init();
350 ESP_ERROR_CHECK(err);
352 err = nvs_open(_nvs_namespace, NVS_READWRITE, &_nvs_handle);
355 ESP_LOGE(KTAG,
"Error opening NVS handle: %s", esp_err_to_name(err));
356 free(_eeprom_buffer);
357 _eeprom_buffer =
nullptr;
362 size_t required_size = size;
363 err = nvs_get_blob(_nvs_handle, _nvs_key, _eeprom_buffer, &required_size);
364 if (err != ESP_OK || required_size != size)
366 if (err == ESP_ERR_NVS_NOT_FOUND)
368 ESP_LOGI(KTAG,
"No previous EEPROM data found in NVS. Initializing fresh buffer.");
372 ESP_LOGW(KTAG,
"NVS get blob failed (%s) or size mismatch. Initializing fresh buffer.", esp_err_to_name(err));
374 memset(_eeprom_buffer, 0xFF, size);
378 ESP_LOGI(KTAG,
"Successfully loaded %d bytes from NVS into EEPROM buffer.", required_size);
381 return _eeprom_buffer;
386 if (!_eeprom_buffer || !_nvs_handle)
388 ESP_LOGE(KTAG,
"EEPROM not initialized, cannot commit.");
392 esp_err_t err = nvs_set_blob(_nvs_handle, _nvs_key, _eeprom_buffer, _eeprom_size);
395 ESP_LOGE(KTAG,
"Failed to set NVS blob: %s", esp_err_to_name(err));
399 err = nvs_commit(_nvs_handle);
402 ESP_LOGE(KTAG,
"Failed to commit NVS: %s", esp_err_to_name(err));
406 ESP_LOGI(KTAG,
"Committed %" PRIu32
" bytes to NVS.", _eeprom_size);
414 return (uint32_t)(esp_timer_get_time() / 1000);
418 static void IRAM_ATTR isr_wrapper(
void* arg)
427 gpio_config_t io_conf = {
428 .pin_bit_mask = (1ULL << pin),
429 .mode = GPIO_MODE_INPUT,
430 .pull_up_en = GPIO_PULLUP_ENABLE,
431 .pull_down_en = GPIO_PULLDOWN_DISABLE,
432 .intr_type = (gpio_int_type_t)mode
435 ESP_ERROR_CHECK(gpio_config(&io_conf));
437 ESP_ERROR_CHECK(gpio_install_isr_service(0));
439 ESP_ERROR_CHECK(gpio_isr_handler_add((gpio_num_t)pin, isr_wrapper, (
void*)callback));