diff --git a/CMakeLists.txt b/CMakeLists.txt index d8bc295..73aeabc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(fun VERSION 0.37.23 LANGUAGES C) +project(fun VERSION 0.37.24 LANGUAGES C) set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) diff --git a/examples/serial_demo.fun b/examples/serial_demo.fun new file mode 100644 index 0000000..7b2156c --- /dev/null +++ b/examples/serial_demo.fun @@ -0,0 +1,54 @@ +#!/usr/bin/env fun + +/* + * This file is part of the Fun programming language. + * https://fun-lang.xyz/ + * + * Copyright 2025 Johannes Findeisen + * Licensed under the terms of the Apache-2.0 license. + * https://opensource.org/license/apache-2-0 + * + * Added: 2025-12-28 + */ + +#include + +// This is an example of how to use the Serial class from the stdlib. +// Note: This requires a serial device to be present at the specified path. + +path = "/dev/ttyUSB0" +baud = 115200 + +print("Opening serial port " + path + " at " + to_string(baud) + " baud...") +s = Serial(path, baud) + +if (s.open()) + print("Serial port opened successfully.") + + // Configure: 8 data bits, no parity (0), 1 stop bit, no flow control (0) + if (s.config(8, 0, 1, 0)) + print("Configured to 8N1.") + + sent = s.send("AT\r\n") + print("Sent " + to_string(sent) + " bytes.") + + // Wait a bit for response if needed (mocked by sleep if available) + // sleep_ms(100) + + resp = s.recv(64) + if (len(resp) > 0) + print("Received: " + resp) + else + print("No response received.") + else + print("Failed to configure serial port.") + + s.close() + print("Serial port closed.") +else + print("Failed to open serial port. (Do you have permissions?)") + +/* Possible output: +Opening serial port /dev/ttyUSB0 at 115200 baud... +Failed to open serial port. (Do you have permissions?) +*/ diff --git a/examples/test_serial.fun b/examples/test_serial.fun index 22c64ed..d1c6fa0 100755 --- a/examples/test_serial.fun +++ b/examples/test_serial.fun @@ -48,3 +48,8 @@ fun test_serial() print("Could not open serial port (this is expected if /dev/ttyUSB0 doesn't exist or no permission)") test_serial() + +/* Possible output: +Attempting to open serial port: /dev/ttyUSB0 +Could not open serial port (this is expected if /dev/ttyUSB0 doesn't exist or no permission) +*/ diff --git a/lib/io/serial.fun b/lib/io/serial.fun new file mode 100644 index 0000000..756d3ee --- /dev/null +++ b/lib/io/serial.fun @@ -0,0 +1,65 @@ +/* + * This file is part of the Fun programming language. + * https://fun-lang.xyz/ + * + * Copyright 2025 Johannes Findeisen + * Licensed under the terms of the Apache-2.0 license. + * https://opensource.org/license/apache-2-0 + * + * Added: 2025-12-28 + */ + +/* + * Serial communication class for Fun stdlib. + * + * Provides: + * - Serial: wrapper over built-ins: serial_open, serial_config, serial_send, serial_recv, serial_close + * + * Usage: + * #include + * s = Serial("/dev/ttyUSB0", 115200) + * if (s.open()) + * s.config(8, 0, 1, 0) // 8N1, no flow control + * s.send("Hello Serial!") + * resp = s.recv(64) + * print("Received: " + resp) + * s.close() + */ + +class Serial(string path, number baud_rate) + + fun _construct(this, path, baud_rate) + this.path = path + this.baud_rate = baud_rate + this.fd = 0 + + fun open(this) + this.fd = serial_open(this.path, this.baud_rate) + return this.fd > 0 + + fun is_open(this) + return this.fd > 0 + + fun config(this, data_bits, parity, stop_bits, flow_control) + if (!this.is_open()) + return 0 + // parity: 0=None, 1=Odd, 2=Even + // flow_control: 0=None, 1=Hardware (RTS/CTS) + return serial_config(this.fd, data_bits, parity, stop_bits, flow_control) + + fun send(this, data) + if (!this.is_open()) + return -1 + return serial_send(this.fd, to_string(data)) + + fun recv(this, maxlen) + if (!this.is_open()) + return "" + return serial_recv(this.fd, to_number(maxlen)) + + fun close(this) + if (this.is_open()) + res = serial_close(this.fd) + this.fd = 0 + return res + return 0