chore: mqtt impl, fix more wiznet bugs
This commit is contained in:
@@ -3,23 +3,74 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Debug flags
|
||||
#define DEBUG_MODE 1
|
||||
|
||||
#define DNS_RUN_INTERVAL_MS 100
|
||||
// Device Bus Types
|
||||
typedef enum { BUS_RS485, BUS_ONEWIRE } bus_type_t;
|
||||
|
||||
// #define LOCAL_PORT 5000
|
||||
// Device Type Definitions
|
||||
typedef enum {
|
||||
DEVICE_RELAY = 1,
|
||||
DEVICE_SOIL_SENSOR = 2,
|
||||
DEVICE_THERMOMETER = 3
|
||||
} device_type_t;
|
||||
|
||||
// MQTT configuration
|
||||
#define CLIENT_ID "ch32_node"
|
||||
// Node Configuration
|
||||
typedef struct {
|
||||
const char* id; // Unique identifier for the node
|
||||
const char* name; // Human readable name
|
||||
const char* location; // Optional location description
|
||||
} node_config_t;
|
||||
|
||||
#define MQTT_TARGET_IP {192, 168, 102, 100}
|
||||
#define MQTT_TARGET_PORT 1883
|
||||
// RS485 Device Configuration
|
||||
typedef struct {
|
||||
uint8_t slave_id; // Modbus slave ID
|
||||
device_type_t type; // Type of device
|
||||
const char* name; // Device name (used in MQTT topics)
|
||||
} rs485_device_t;
|
||||
|
||||
// OneWire naming scheme configuration
|
||||
typedef struct {
|
||||
const char* location; // Location prefix for the sensor
|
||||
const char* name_prefix; // Prefix for auto-generated names
|
||||
} onewire_naming_t;
|
||||
|
||||
// Network Configuration
|
||||
#define MQTT_SERVER_IP {192, 168, 102, 100}
|
||||
#define MQTT_PORT 1883
|
||||
|
||||
// MQTT Configuration
|
||||
#define MQTT_KEEP_ALIVE_INTERVAL 60
|
||||
#define MQTT_TX_BUFFER_SIZE 128
|
||||
#define MQTT_RX_BUFFER_SIZE 128
|
||||
#define MQTT_COMMAND_TIMEOUT_MS 1000
|
||||
#define SUB_TOPIC "listen/world"
|
||||
#define PUB_TOPIC "hello/world"
|
||||
|
||||
// Node Specific Configuration
|
||||
static const node_config_t NODE_CONFIG = {
|
||||
.id = "ch32-node1", .name = "CH32 Node 1", .location = "somewhere"};
|
||||
|
||||
// RS485 Devices Configuration
|
||||
#define RS485_DEVICE_COUNT 2
|
||||
|
||||
static const rs485_device_t RS485_DEVICES[RS485_DEVICE_COUNT] = {
|
||||
{.slave_id = 0x01, .type = DEVICE_RELAY, .name = "relay-1"},
|
||||
{.slave_id = 0x02, .type = DEVICE_SOIL_SENSOR, .name = "soil-monitor-1"}};
|
||||
|
||||
// OneWire Naming Configuration
|
||||
#define MAX_ONEWIRE_DEVICES 8
|
||||
|
||||
static const onewire_naming_t ONEWIRE_NAMING[] = {
|
||||
{.location = "tank", .name_prefix = "water-temp"},
|
||||
{.location = "ambient", .name_prefix = "air-temp"},
|
||||
{.location = "soil", .name_prefix = "soil-temp"}};
|
||||
|
||||
// Structure to store discovered OneWire devices
|
||||
typedef struct {
|
||||
uint8_t address[8]; // OneWire address
|
||||
uint8_t location_index; // Index into ONEWIRE_NAMING array
|
||||
char name[32]; // Generated name (e.g., "tank-water-temp-1")
|
||||
uint8_t sequence; // Sequence number within its location
|
||||
} onewire_device_t;
|
||||
|
||||
#endif // CONFIG_H
|
||||
|
||||
17
include/modbus_handler.h
Normal file
17
include/modbus_handler.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef MODBUS_HANDLER_H
|
||||
#define MODBUS_HANDLER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "modbus_master.h"
|
||||
|
||||
typedef void (*modbus_value_cb)(uint8_t device_idx, const char* property,
|
||||
uint16_t value);
|
||||
|
||||
void modbus_handler_init(modbus_context_t* ctx, modbus_value_cb value_callback);
|
||||
void modbus_handler_process(void);
|
||||
uint8_t modbus_handler_send_request(uint8_t device_idx, const char* property,
|
||||
uint8_t is_write, uint16_t value);
|
||||
|
||||
#endif
|
||||
56
include/modbus_master.h
Normal file
56
include/modbus_master.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#ifndef __MODBUS_MASTER_H
|
||||
#define __MODBUS_MASTER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Function codes
|
||||
#define MODBUS_FC_READ_HOLDING_REGISTERS 0x03
|
||||
#define MODBUS_FC_WRITE_SINGLE_REGISTER 0x06
|
||||
#define MODBUS_FC_WRITE_MULTIPLE_REGISTERS 0x10
|
||||
|
||||
// Error codes
|
||||
#define MODBUS_ERROR_NONE 0x00
|
||||
#define MODBUS_ERROR_FUNCTION 0x01
|
||||
#define MODBUS_ERROR_ADDRESS 0x02
|
||||
#define MODBUS_ERROR_VALUE 0x03
|
||||
#define MODBUS_ERROR_TIMEOUT 0x04
|
||||
|
||||
// Frame length
|
||||
#define MB_MIN_LEN 4
|
||||
#define MB_CRC_LEN 2
|
||||
#define MB_WREG_LEN 8
|
||||
#define MB_MAX_BUFFER 32
|
||||
|
||||
// State machine states
|
||||
typedef enum {
|
||||
MODBUS_IDLE,
|
||||
MODBUS_WAITING_RESPONSE,
|
||||
MODBUS_PROCESS_RESPONSE
|
||||
} modbus_state_t;
|
||||
|
||||
// Modbus context structure
|
||||
typedef struct {
|
||||
modbus_state_t state;
|
||||
uint32_t last_send_time;
|
||||
uint32_t response_timeout;
|
||||
uint8_t buffer[MB_MAX_BUFFER];
|
||||
uint16_t rx_len;
|
||||
uint16_t current_bit;
|
||||
uint16_t last_value;
|
||||
void (*on_response)(uint8_t* buf, uint16_t len,
|
||||
uint16_t value); // Response callback
|
||||
void (*on_error)(uint8_t error_code); // Error callback
|
||||
} modbus_context_t;
|
||||
|
||||
uint16_t modbus_create_request(uint8_t* req, uint8_t slave_addr,
|
||||
uint8_t function, uint16_t address,
|
||||
uint16_t value);
|
||||
uint8_t modbus_process_response(uint8_t* buf, uint16_t len, uint16_t* value);
|
||||
void modbus_init(modbus_context_t* ctx,
|
||||
void (*response_callback)(uint8_t*, uint16_t, uint16_t),
|
||||
void (*error_callback)(uint8_t));
|
||||
void modbus_set_timeout(modbus_context_t* ctx, uint32_t timeout_ms);
|
||||
void modbus_process(modbus_context_t* ctx);
|
||||
uint8_t modbus_send_request(modbus_context_t* ctx, uint8_t slave_addr,
|
||||
uint8_t function, uint16_t address, uint16_t value);
|
||||
#endif // __MODBUS_MASTER_H
|
||||
25
include/mqtt_handler.h
Normal file
25
include/mqtt_handler.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef MQTT_HANDLER_H
|
||||
#define MQTT_HANDLER_H
|
||||
|
||||
#include <DHCP/dhcp.h>
|
||||
|
||||
#include "ch32v003fun.h"
|
||||
#include "w5500.h"
|
||||
|
||||
typedef struct {
|
||||
Network network;
|
||||
MQTTClient client;
|
||||
ch32_mqtt_options_t opts;
|
||||
uint32_t last_reconnect;
|
||||
uint32_t last_yield;
|
||||
uint8_t is_connected;
|
||||
char base_topic[64];
|
||||
} mqtt_state_t;
|
||||
|
||||
void mqtt_init(mqtt_state_t* state);
|
||||
void mqtt_process(mqtt_state_t* state);
|
||||
void message_arrived(MessageData* md);
|
||||
void publish_value(MQTTClient* client, const char* device_name,
|
||||
const char* property, uint16_t value);
|
||||
|
||||
#endif
|
||||
11
include/rs485.h
Normal file
11
include/rs485.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef RS485_H
|
||||
#define RS485_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void rs485_init(int uart_brr);
|
||||
void rs485_send(uint8_t *buf, uint16_t len);
|
||||
uint8_t rs485_available(void);
|
||||
uint8_t rs485_read(void);
|
||||
|
||||
#endif // RS485_H
|
||||
9
include/system_init.h
Normal file
9
include/system_init.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef SYSTEM_INIT_H
|
||||
#define SYSTEM_INIT_H
|
||||
|
||||
#define W5500_INIT_DELAY_MS 55
|
||||
|
||||
void init_system(void);
|
||||
int wait_for_dhcp(void);
|
||||
|
||||
#endif
|
||||
@@ -3,13 +3,15 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define UART1_BAUD_RATE 9600
|
||||
|
||||
// Macro definitions
|
||||
#define APB1_CLOCK (FUNCONF_SYSTEM_CORE_CLOCK / 2) // APB1 is divided by 2
|
||||
#define UART_BRR_APB1 \
|
||||
(((APB1_CLOCK) + (UART_BAUD_RATE / 2)) / (UART_BAUD_RATE)) // USART2
|
||||
#define UART_BRR_APB2 \
|
||||
(((FUNCONF_SYSTEM_CORE_CLOCK) + (UART_BAUD_RATE / 2)) / \
|
||||
(UART_BAUD_RATE)) // USART1
|
||||
(((FUNCONF_SYSTEM_CORE_CLOCK) + (UART1_BAUD_RATE / 2)) / \
|
||||
(UART1_BAUD_RATE)) // USART1
|
||||
|
||||
// Function prototypes
|
||||
void init_uart(int uart_brr);
|
||||
|
||||
@@ -19,8 +19,6 @@ typedef struct {
|
||||
|
||||
extern volatile int ip_assigned;
|
||||
|
||||
void handle_ip_assigned(void);
|
||||
|
||||
// Initializes the W5500 chip
|
||||
void configure_network(void);
|
||||
|
||||
@@ -29,17 +27,6 @@ void dhcp_init(void);
|
||||
void dhcp_process(void);
|
||||
|
||||
// resolves a domain name
|
||||
void resolve_domain_name(const char* domain_name);
|
||||
|
||||
// init and connect the MQTT client
|
||||
int setup_mqtt_client(Network* network, ch32_mqtt_options_t* opts,
|
||||
MQTTClient* client);
|
||||
|
||||
int subscribe_to_topic(MQTTClient* client, const char* topic, enum QoS qos,
|
||||
messageHandler message_callback);
|
||||
|
||||
// publish a message to a topic
|
||||
void publish_message(MQTTClient* client, const char* payload,
|
||||
const char* topic);
|
||||
// void resolve_domain_name(const char* domain_name);
|
||||
|
||||
#endif // W5500_H
|
||||
|
||||
Reference in New Issue
Block a user