chore: debloat (remove platformio), onewire improvements
Squashed commit of the following: commit 5f16309f629b9928d2134b85ae64af69bc3ebbcd Author: kuwoyuki <kuwoyuki@cock.li> Date: Sun Nov 24 22:55:15 2024 +0600 fix: Makefile, improve onewire retries commit 55496a3bda941b52ff349dc75c9c06eb5a37c07d Author: kuwoyuki <kuwoyuki@cock.li> Date: Mon Nov 18 00:41:18 2024 +0600 fix: make onewire validity less strict commit 3428a9bc9792508972ce3e7e4e35a64f047bca10 Author: kuwoyuki <kuwoyuki@cock.li> Date: Sun Nov 17 23:57:55 2024 +0600 chore: rm bins commit 1594e5ed430522b15466c8afa62ff7fb1b28947c Author: kuwoyuki <kuwoyuki@cock.li> Date: Sun Nov 17 23:32:01 2024 +0600 chore: unplatformiofy
This commit is contained in:
8
.gitignore
vendored
8
.gitignore
vendored
@@ -1,6 +1,10 @@
|
||||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
||||
prv/
|
||||
prv/
|
||||
ch32_node.elf
|
||||
ch32_node.lst
|
||||
ch32_node.map
|
||||
ch32_node.bin
|
||||
ch32_node.hex
|
||||
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "ch32v003fun"]
|
||||
path = ch32v003fun
|
||||
url = https://github.com/cnlohr/ch32v003fun.git
|
||||
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@@ -33,6 +33,8 @@
|
||||
"modbus.h": "c",
|
||||
"network.h": "c",
|
||||
"cstdint": "c",
|
||||
"utils.h": "c"
|
||||
"utils.h": "c",
|
||||
"onewire.h": "c",
|
||||
"string.h": "c"
|
||||
}
|
||||
}
|
||||
42
Makefile
Normal file
42
Makefile
Normal file
@@ -0,0 +1,42 @@
|
||||
TARGET ?= ch32_node
|
||||
TARGET_MCU ?= CH32V203
|
||||
TARGET_MCU_PACKAGE ?= CH32V203C8T6
|
||||
|
||||
CH32V003FUN ?= ./ch32v003fun/ch32v003fun
|
||||
MINICHLINK ?= ./ch32v003fun/minichlink
|
||||
|
||||
PREFIX ?= riscv64-none-elf
|
||||
NEWLIB ?= /usr/riscv64-none-elf/include/
|
||||
|
||||
INCLUDE_DIRS ?= \
|
||||
-I./include \
|
||||
-I./ioLibrary_Driver \
|
||||
-I./ioLibrary_Driver/MQTT \
|
||||
-I./ioLibrary_Driver/MQTT/MQTTPacket/src
|
||||
|
||||
PROJECT_C_FILES := $(filter-out ./ch32_node.c, $(wildcard ./*.c))
|
||||
LIB_C_FILES := \
|
||||
./ioLibrary_Driver/socket.c \
|
||||
./ioLibrary_Driver/wizchip_conf.c \
|
||||
./ioLibrary_Driver/W5500/w5500.c \
|
||||
./ioLibrary_Driver/DHCP/dhcp.c \
|
||||
./ioLibrary_Driver/MQTT/mqtt_interface.c \
|
||||
./ioLibrary_Driver/MQTT/MQTTClient.c \
|
||||
./ioLibrary_Driver/MQTT/MQTTPacket/src/MQTTPacket.c \
|
||||
./ioLibrary_Driver/MQTT/MQTTPacket/src/MQTTFormat.c \
|
||||
./ioLibrary_Driver/MQTT/MQTTPacket/src/MQTTDeserializePublish.c \
|
||||
./ioLibrary_Driver/MQTT/MQTTPacket/src/MQTTSerializePublish.c \
|
||||
./ioLibrary_Driver/MQTT/MQTTPacket/src/MQTTConnectClient.c \
|
||||
./ioLibrary_Driver/MQTT/MQTTPacket/src/MQTTSubscribeClient.c \
|
||||
./ioLibrary_Driver/MQTT/MQTTPacket/src/MQTTUnsubscribeClient.c
|
||||
|
||||
ADDITIONAL_C_FILES ?= $(PROJECT_C_FILES) $(LIB_C_FILES)
|
||||
|
||||
include $(CH32V003FUN)/ch32v003fun.mk
|
||||
|
||||
CFLAGS += -Wall -Wextra $(INCLUDE_DIRS)
|
||||
|
||||
all: flash
|
||||
flash: cv_flash
|
||||
clean: cv_clean
|
||||
.PHONY: all flash clean
|
||||
@@ -3,7 +3,6 @@
|
||||
Firmware for a CH32V203 MCU with a W5500 Ethernet controller.
|
||||
|
||||
## TODO:
|
||||
- UnplatformIOify this
|
||||
- Set up interrupts for RS485 publish
|
||||
- ...
|
||||
|
||||
@@ -18,10 +17,8 @@ Firmware for a CH32V203 MCU with a W5500 Ethernet controller.
|
||||
|
||||
## Development Environment
|
||||
|
||||
- Platform: CH32V
|
||||
- Board: CH32V203C8T6
|
||||
- Framework: ch32v003fun
|
||||
- Build System: PlatformIO
|
||||
- Compiler: RISC-V GCC 14.2.0
|
||||
|
||||
## Project Structure
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
static mqtt_state_t mqtt_state;
|
||||
|
||||
void system_init(void) {
|
||||
void sysinit(void) {
|
||||
SystemInit();
|
||||
gpio_init();
|
||||
systick_init();
|
||||
@@ -37,7 +37,7 @@ static void on_modbus_value(uint8_t device_idx, const char* property,
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
system_init();
|
||||
sysinit();
|
||||
Delay_Ms(W5500_INIT_DELAY_MS);
|
||||
|
||||
configure_network();
|
||||
1
ch32v003fun
Submodule
1
ch32v003fun
Submodule
Submodule ch32v003fun added at 69801af882
@@ -1,39 +0,0 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
||||
@@ -1,8 +1,7 @@
|
||||
#ifndef _FUNCONFIG_H
|
||||
#define _FUNCONFIG_H
|
||||
|
||||
// board definition file will already take care of this
|
||||
// #define CH32V003 1
|
||||
#define CH32V20x 1
|
||||
|
||||
#define FUNCONF_USE_HSI 0 // Use HSI Internal Oscillator
|
||||
#define FUNCONF_USE_HSE 1 // Use External Oscillator
|
||||
@@ -601,7 +601,9 @@ int8_t parseDHCPMSG(void)
|
||||
printf("DHCP message : %d.%d.%d.%d(%d) %d received. \r\n",svr_addr[0],svr_addr[1],svr_addr[2], svr_addr[3],svr_port, len);
|
||||
#endif
|
||||
}
|
||||
else return 0;
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
if (svr_port == DHCP_SERVER_PORT) {
|
||||
// compare mac address
|
||||
if ( (pDHCPMSG->chaddr[0] != DHCP_CHADDR[0]) || (pDHCPMSG->chaddr[1] != DHCP_CHADDR[1]) ||
|
||||
46
lib/README
46
lib/README
@@ -1,46 +0,0 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
||||
29
lmao.sh
29
lmao.sh
@@ -1,29 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
SERIAL_PORT="/dev/ttyACM0"
|
||||
BAUD_RATE="115200"
|
||||
|
||||
{
|
||||
stty -F $SERIAL_PORT $BAUD_RATE
|
||||
COUNT=0
|
||||
PREVIOUS_TIME=""
|
||||
|
||||
while IFS= read -r LINE; do
|
||||
CURRENT_TIME=$(date +%s.%N)
|
||||
|
||||
# 5 msgs
|
||||
if [ $COUNT -lt 5 ]; then
|
||||
echo "msg $COUNT: $LINE"
|
||||
|
||||
if [[ -n $PREVIOUS_TIME ]]; then
|
||||
INTERVAL=$(echo "$CURRENT_TIME - $PREVIOUS_TIME" | bc)
|
||||
echo "interval: ${INTERVAL}s"
|
||||
fi
|
||||
|
||||
PREVIOUS_TIME=$CURRENT_TIME
|
||||
COUNT=$((COUNT + 1))
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
} <$SERIAL_PORT
|
||||
@@ -1,12 +1,13 @@
|
||||
#include "onewire_temp.h"
|
||||
|
||||
#include <onewire.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "onewire.h"
|
||||
#include "systick.h"
|
||||
|
||||
#define ONEWIRE_CONVERSION_TIME_MS 750
|
||||
#define ONEWIRE_MAX_RETRIES 255
|
||||
|
||||
typedef struct {
|
||||
uint8_t address[8];
|
||||
@@ -14,6 +15,8 @@ typedef struct {
|
||||
onewire_state_t state;
|
||||
uint32_t convert_start_time;
|
||||
bool valid;
|
||||
uint8_t error_count;
|
||||
uint32_t last_success_time;
|
||||
} onewire_sensor_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -56,6 +59,8 @@ void onewire_temp_init(void) {
|
||||
sensor->valid = true;
|
||||
sensor->state = ONEWIRE_STATE_READY;
|
||||
sensor->temperature = ONEWIRE_TEMP_INVALID;
|
||||
sensor->error_count = 0;
|
||||
sensor->last_success_time = millis();
|
||||
ow_sys.count++;
|
||||
}
|
||||
}
|
||||
@@ -89,7 +94,7 @@ static float convert_temperature(const uint8_t* data, uint8_t family_code) {
|
||||
}
|
||||
|
||||
static bool start_conversion(onewire_sensor_t* sensor) {
|
||||
if (!sensor->valid || sensor->state != ONEWIRE_STATE_READY) {
|
||||
if (!sensor->state != ONEWIRE_STATE_READY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -121,6 +126,8 @@ static bool read_temperature(onewire_sensor_t* sensor) {
|
||||
}
|
||||
|
||||
sensor->temperature = convert_temperature(data, sensor->address[0]);
|
||||
sensor->error_count = 0;
|
||||
sensor->last_success_time = millis();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -137,7 +144,13 @@ void onewire_temp_process(void) {
|
||||
switch (sensor->state) {
|
||||
case ONEWIRE_STATE_READY:
|
||||
if (!ow_sys.parallel_mode) {
|
||||
start_conversion(sensor);
|
||||
if (!start_conversion(sensor)) {
|
||||
sensor->error_count++;
|
||||
if (sensor->error_count >= ONEWIRE_MAX_RETRIES) {
|
||||
sensor->valid = false;
|
||||
DEBUG_PRINT("sensor %d marked temporarily invalid after %d retries\n", i, ONEWIRE_MAX_RETRIES);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -149,7 +162,14 @@ void onewire_temp_process(void) {
|
||||
|
||||
case ONEWIRE_STATE_READ:
|
||||
if (!read_temperature(sensor)) {
|
||||
sensor->valid = false;
|
||||
sensor->error_count++;
|
||||
if (sensor->error_count >= ONEWIRE_MAX_RETRIES) {
|
||||
sensor->valid = false;
|
||||
DEBUG_PRINT("sensor %d marked temporarily invalid after %d retries\n", i, ONEWIRE_MAX_RETRIES);
|
||||
}
|
||||
} else {
|
||||
sensor->valid = true; // re-enable
|
||||
sensor->error_count = 0;
|
||||
}
|
||||
sensor->state = ONEWIRE_STATE_READY;
|
||||
break;
|
||||
@@ -256,7 +276,7 @@ void onewire_temp_publish_discovery(MQTTClient* client, const char* node_id) {
|
||||
publish_retained(client, topic, display_name);
|
||||
|
||||
snprintf(topic, sizeof(topic), "homie/%s/%s/$properties", node_id, sensor_name);
|
||||
publish_retained(client, topic, "temperature,address");
|
||||
publish_retained(client, topic, "temperature,address,status,error_count");
|
||||
|
||||
// temperature properties
|
||||
snprintf(topic, sizeof(topic), "homie/%s/%s/temperature/$name", node_id, sensor_name);
|
||||
@@ -279,6 +299,18 @@ void onewire_temp_publish_discovery(MQTTClient* client, const char* node_id) {
|
||||
addr[4], addr[5], addr[6], addr[7]);
|
||||
snprintf(topic, sizeof(topic), "homie/%s/%s/address", node_id, sensor_name);
|
||||
publish_retained(client, topic, addr_str);
|
||||
|
||||
snprintf(topic, sizeof(topic), "homie/%s/%s/status/$name", node_id, sensor_name);
|
||||
publish_retained(client, topic, "Sensor Status");
|
||||
snprintf(topic, sizeof(topic), "homie/%s/%s/status/$datatype", node_id, sensor_name);
|
||||
publish_retained(client, topic, "enum");
|
||||
snprintf(topic, sizeof(topic), "homie/%s/%s/status/$format", node_id, sensor_name);
|
||||
publish_retained(client, topic, "valid,invalid");
|
||||
|
||||
snprintf(topic, sizeof(topic), "homie/%s/%s/error_count/$name", node_id, sensor_name);
|
||||
publish_retained(client, topic, "Error Count");
|
||||
snprintf(topic, sizeof(topic), "homie/%s/%s/error_count/$datatype", node_id, sensor_name);
|
||||
publish_retained(client, topic, "integer");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,36 +321,53 @@ void onewire_temp_publish_values(MQTTClient* client, const char* node_id) {
|
||||
uint8_t sensor_count = onewire_temp_count();
|
||||
|
||||
for (uint8_t i = 0; i < sensor_count; i++) {
|
||||
if (!onewire_temp_valid(i)) continue;
|
||||
|
||||
float temp = onewire_temp_get(i);
|
||||
if (temp == ONEWIRE_TEMP_INVALID) continue;
|
||||
|
||||
// fixed-point conversion
|
||||
int16_t temp_fixed = (int16_t)(temp * 100);
|
||||
|
||||
bool is_valid = onewire_temp_valid(i);
|
||||
const uint8_t* addr = onewire_temp_address(i);
|
||||
snprintf(topic, sizeof(topic),
|
||||
"homie/%s/temp_%02x%02x%02x%02x%02x%02x%02x%02x/temperature",
|
||||
node_id, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
|
||||
addr[6], addr[7]);
|
||||
|
||||
uint8_t neg = temp_fixed < 0;
|
||||
if (neg) temp_fixed = -temp_fixed;
|
||||
char base_topic[MAX_TOPIC_LENGTH];
|
||||
snprintf(base_topic, sizeof(base_topic),
|
||||
"homie/%s/temp_%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
node_id, addr[0], addr[1], addr[2], addr[3],
|
||||
addr[4], addr[5], addr[6], addr[7]);
|
||||
|
||||
uint8_t idx = 0;
|
||||
if (neg) value[idx++] = '-';
|
||||
|
||||
uint16_t whole = temp_fixed / 100;
|
||||
uint8_t decimal = temp_fixed % 100;
|
||||
|
||||
if (whole >= 10) value[idx++] = '0' + (whole / 10);
|
||||
value[idx++] = '0' + (whole % 10);
|
||||
value[idx++] = '.';
|
||||
value[idx++] = '0' + (decimal / 10);
|
||||
value[idx++] = '0' + (decimal % 10);
|
||||
value[idx] = '\0';
|
||||
// publish status
|
||||
snprintf(topic, sizeof(topic), "%s/status", base_topic);
|
||||
publish_message(client, is_valid ? "valid" : "invalid", topic);
|
||||
|
||||
// publish error cnt
|
||||
snprintf(topic, sizeof(topic), "%s/error_count", base_topic);
|
||||
snprintf(value, sizeof(value), "%u", ow_sys.sensors[i].error_count);
|
||||
publish_message(client, value, topic);
|
||||
|
||||
snprintf(topic, sizeof(topic), "%s/temperature", base_topic);
|
||||
|
||||
if (is_valid) {
|
||||
float temp = onewire_temp_get(i);
|
||||
if (temp == ONEWIRE_TEMP_INVALID) {
|
||||
publish_message(client, "0.00", topic);
|
||||
} else {
|
||||
// temp to str
|
||||
int16_t temp_fixed = (int16_t)(temp * 100);
|
||||
uint8_t neg = temp_fixed < 0;
|
||||
if (neg) temp_fixed = -temp_fixed;
|
||||
|
||||
uint8_t idx = 0;
|
||||
if (neg) value[idx++] = '-';
|
||||
|
||||
uint16_t whole = temp_fixed / 100;
|
||||
uint8_t decimal = temp_fixed % 100;
|
||||
|
||||
if (whole >= 10) value[idx++] = '0' + (whole / 10);
|
||||
value[idx++] = '0' + (whole % 10);
|
||||
value[idx++] = '.';
|
||||
value[idx++] = '0' + (decimal / 10);
|
||||
value[idx++] = '0' + (decimal % 10);
|
||||
value[idx] = '\0';
|
||||
|
||||
publish_message(client, value, topic);
|
||||
}
|
||||
} else {
|
||||
publish_message(client, "0.00", topic);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env]
|
||||
platform = https://git.hye.su/mira/platform-ch32v.git
|
||||
platform_packages =
|
||||
toolchain-riscv @ https://git.hye.su/mira/toolchain-riscv-linux.git ; gcc 14.2.0
|
||||
framework-ch32v003fun @ https://github.com/cnlohr/ch32v003fun.git ; upstream cnlohr repo
|
||||
board = genericCH32V203C8T6
|
||||
framework = ch32v003fun
|
||||
upload_protocol = wlink # isp, minichlink, wch-link, wlink
|
||||
build_unflags = -march=rv32imacxw
|
||||
build_flags = -march=rv32imac_zicsr -Wall -Wextra
|
||||
debug_build_flags = -O0 -ggdb3 -g3
|
||||
|
||||
[env:local]
|
||||
platform_packages =
|
||||
toolchain-riscv @ symlink:///home/mira/src/xpack-riscv-none-elf-gcc-14.2.0-2 ; gcc 14.2.0
|
||||
framework-ch32v003fun @ https://github.com/cnlohr/ch32v003fun.git ; upstream cnlohr repo
|
||||
11
test/README
11
test/README
@@ -1,11 +0,0 @@
|
||||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "timer.h"
|
||||
|
||||
#include <DHCP/dhcp.h>
|
||||
#include <DNS/dns.h>
|
||||
|
||||
#include "ch32v003fun.h"
|
||||
#include "debug.h"
|
||||
@@ -37,6 +36,5 @@ void TIM2_IRQHandler(void) {
|
||||
|
||||
// DEBUG_PRINT("TIM2 IRQ\n");
|
||||
DHCP_time_handler();
|
||||
DNS_time_handler();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user