From adaaa9d16621c6d80336fc8db67cc39bf635b389 Mon Sep 17 00:00:00 2001 From: Giampiero Baggiani Date: Thu, 20 Jun 2019 14:25:17 +0200 Subject: [PATCH 01/13] Update raspberry_soft_uart.c --- raspberry_soft_uart.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/raspberry_soft_uart.c b/raspberry_soft_uart.c index 51a214ca..c7089dd4 100755 --- a/raspberry_soft_uart.c +++ b/raspberry_soft_uart.c @@ -21,6 +21,7 @@ static DEFINE_MUTEX(current_tty_mutex); static struct hrtimer timer_tx; static struct hrtimer timer_rx; static ktime_t period; +static ktime_t half_period; static int gpio_tx = 0; static int gpio_rx = 0; static int rx_bit_index = -1; @@ -129,6 +130,7 @@ int raspberry_soft_uart_close(void) int raspberry_soft_uart_set_baudrate(const int baudrate) { period = ktime_set(0, 1000000000/baudrate); + half_period = ktime_set(0, 1000000000/baudrate/2); gpio_set_debounce(gpio_rx, 1000/baudrate/2); return 1; } @@ -182,7 +184,7 @@ static irq_handler_t handle_rx_start(unsigned int irq, void* device, struct pt_r { if (rx_bit_index == -1) { - hrtimer_start(&timer_rx, ktime_set(0, period / 2), HRTIMER_MODE_REL); + hrtimer_start(&timer_rx, half_period, HRTIMER_MODE_REL); } return (irq_handler_t) IRQ_HANDLED; } From 89c43c67ef1a78ef2aa298cf51caa27cc6c0a373 Mon Sep 17 00:00:00 2001 From: Giampiero Date: Fri, 9 Aug 2019 09:24:59 +0200 Subject: [PATCH 02/13] bits number fix + raspberry_soft_uart_set_rx_callback() --- raspberry_soft_uart.c | 55 ++++++++++++++++++++++++++----------------- raspberry_soft_uart.h | 1 + 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/raspberry_soft_uart.c b/raspberry_soft_uart.c index c7089dd4..949b55f6 100755 --- a/raspberry_soft_uart.c +++ b/raspberry_soft_uart.c @@ -25,6 +25,7 @@ static ktime_t half_period; static int gpio_tx = 0; static int gpio_rx = 0; static int rx_bit_index = -1; +static void (*rx_callback)(unsigned char) = NULL; /** * Initializes the Raspberry Soft UART infrastructure. @@ -108,18 +109,13 @@ int raspberry_soft_uart_open(struct tty_struct* tty) */ int raspberry_soft_uart_close(void) { - int success = 0; mutex_lock(¤t_tty_mutex); - if (current_tty != NULL) - { - disable_irq(gpio_to_irq(gpio_rx)); - hrtimer_cancel(&timer_tx); - hrtimer_cancel(&timer_rx); - current_tty = NULL; - success = 1; - } + disable_irq(gpio_to_irq(gpio_rx)); + hrtimer_cancel(&timer_tx); + hrtimer_cancel(&timer_rx); + current_tty = NULL; mutex_unlock(¤t_tty_mutex); - return success; + return 1; } /** @@ -172,6 +168,16 @@ int raspberry_soft_uart_get_tx_queue_size(void) return get_queue_size(&queue_tx); } +/** + * Sets the callback function to be called on received character. + * @param callback the callback function + */ +int raspberry_soft_uart_set_rx_callback(void (*callback)(unsigned char)) +{ + rx_callback = callback; + return 1; +} + //----------------------------------------------------------------------------- // Internals //----------------------------------------------------------------------------- @@ -259,7 +265,7 @@ static enum hrtimer_restart handle_rx(struct hrtimer* timer) } // Data bits. - else if (0 <= rx_bit_index && rx_bit_index < 8) + else if (0 <= rx_bit_index && rx_bit_index < 7) { if (bit_value == 0) { @@ -276,8 +282,9 @@ static enum hrtimer_restart handle_rx(struct hrtimer* timer) } // Stop bit. - else if (rx_bit_index == 8) + else if (rx_bit_index == 7) { + character >>= 1; receive_character(character); rx_bit_index = -1; } @@ -300,18 +307,22 @@ static enum hrtimer_restart handle_rx(struct hrtimer* timer) void receive_character(unsigned char character) { mutex_lock(¤t_tty_mutex); + if (rx_callback != NULL) { + (*rx_callback)(character); + } else { #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - if (current_tty != NULL && current_tty->port != NULL) - { - tty_insert_flip_char(current_tty->port, character, TTY_NORMAL); - tty_flip_buffer_push(current_tty->port); - } + if (current_tty != NULL && current_tty->port != NULL) + { + tty_insert_flip_char(current_tty->port, character, TTY_NORMAL); + tty_flip_buffer_push(current_tty->port); + } #else - if (tty != NULL) - { - tty_insert_flip_char(current_tty, character, TTY_NORMAL); - tty_flip_buffer_push(tty); - } + if (tty != NULL) + { + tty_insert_flip_char(current_tty, character, TTY_NORMAL); + tty_flip_buffer_push(tty); + } #endif + } mutex_unlock(¤t_tty_mutex); } diff --git a/raspberry_soft_uart.h b/raspberry_soft_uart.h index 9297bdfb..de281053 100755 --- a/raspberry_soft_uart.h +++ b/raspberry_soft_uart.h @@ -11,5 +11,6 @@ int raspberry_soft_uart_set_baudrate(const int baudrate); int raspberry_soft_uart_send_string(const unsigned char* string, int string_size); int raspberry_soft_uart_get_tx_queue_room(void); int raspberry_soft_uart_get_tx_queue_size(void); +int raspberry_soft_uart_set_rx_callback(void (*callback)(unsigned char)); #endif From 4da0b90eaeaaaa6e692545f226ee58bd4faa9d74 Mon Sep 17 00:00:00 2001 From: Giampiero Date: Thu, 22 Aug 2019 17:05:21 +0200 Subject: [PATCH 03/13] raspberry_soft_uart_open() fix --- raspberry_soft_uart.c | 1 + 1 file changed, 1 insertion(+) diff --git a/raspberry_soft_uart.c b/raspberry_soft_uart.c index 949b55f6..8a7a2817 100755 --- a/raspberry_soft_uart.c +++ b/raspberry_soft_uart.c @@ -93,6 +93,7 @@ int raspberry_soft_uart_open(struct tty_struct* tty) { int success = 0; mutex_lock(¤t_tty_mutex); + rx_bit_index = -1; if (current_tty == NULL) { current_tty = tty; From 59fb72d0b9a31f45fe0c551f4d6c6d4ab77ebef7 Mon Sep 17 00:00:00 2001 From: Giampiero Date: Tue, 3 Sep 2019 10:56:16 +0200 Subject: [PATCH 04/13] restored 8 bits --- raspberry_soft_uart.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/raspberry_soft_uart.c b/raspberry_soft_uart.c index 8a7a2817..425a172e 100755 --- a/raspberry_soft_uart.c +++ b/raspberry_soft_uart.c @@ -266,7 +266,7 @@ static enum hrtimer_restart handle_rx(struct hrtimer* timer) } // Data bits. - else if (0 <= rx_bit_index && rx_bit_index < 7) + else if (0 <= rx_bit_index && rx_bit_index < 8) { if (bit_value == 0) { @@ -283,9 +283,8 @@ static enum hrtimer_restart handle_rx(struct hrtimer* timer) } // Stop bit. - else if (rx_bit_index == 7) + else if (rx_bit_index == 8) { - character >>= 1; receive_character(character); rx_bit_index = -1; } From 1728e37462ffe0052c5dab3c73e3d6dafdd427aa Mon Sep 17 00:00:00 2001 From: Giampiero Baggiani Date: Tue, 29 Dec 2020 13:19:15 +0100 Subject: [PATCH 05/13] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4c5c13e2..3f21ade3 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ This module creates a software-based serial port using a configurable pair of GP Fetch the source: ``` -git clone https://github.com/adrianomarto/soft_uart +git clone https://github.com/sfera-labs/soft_uart ``` Install the package `raspberrypi-kernel-headers`: From 06dfeb1eae5b0ea545fbe742a22fa0abea391998 Mon Sep 17 00:00:00 2001 From: Giampiero Baggiani Date: Tue, 29 Dec 2020 13:21:28 +0100 Subject: [PATCH 06/13] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f21ade3..75daf46c 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ This module creates a software-based serial port using a configurable pair of GP Fetch the source: ``` -git clone https://github.com/sfera-labs/soft_uart +git clone --depth 1 https://github.com/sfera-labs/soft_uart ``` Install the package `raspberrypi-kernel-headers`: From 68ee0638820c9e1fda8f73841007e1d16a9f7257 Mon Sep 17 00:00:00 2001 From: Giampiero Baggiani Date: Mon, 20 Feb 2023 15:34:56 +0100 Subject: [PATCH 07/13] Update Makefile --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index cc4de675..54fcc634 100755 --- a/Makefile +++ b/Makefile @@ -2,6 +2,8 @@ obj-m += soft_uart.o soft_uart-objs := module.o raspberry_soft_uart.o queue.o +ccflags-y := -Wno-incompatible-pointer-types + RELEASE = $(shell uname -r) LINUX = /usr/src/linux-headers-$(RELEASE) From edb76b81624b222462bb71eb0812e16f677d2b3c Mon Sep 17 00:00:00 2001 From: Giampiero Baggiani Date: Tue, 21 Mar 2023 16:22:25 +0100 Subject: [PATCH 08/13] Revert "Update Makefile" This reverts commit 68ee0638820c9e1fda8f73841007e1d16a9f7257. --- Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile b/Makefile index 54fcc634..cc4de675 100755 --- a/Makefile +++ b/Makefile @@ -2,8 +2,6 @@ obj-m += soft_uart.o soft_uart-objs := module.o raspberry_soft_uart.o queue.o -ccflags-y := -Wno-incompatible-pointer-types - RELEASE = $(shell uname -r) LINUX = /usr/src/linux-headers-$(RELEASE) From 0d657ca57df14274514df36b91b100fd04e74166 Mon Sep 17 00:00:00 2001 From: Giampiero Baggiani Date: Tue, 21 Mar 2023 16:23:17 +0100 Subject: [PATCH 09/13] functions types fixes --- module.c | 4 ++-- raspberry_soft_uart.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/module.c b/module.c index eb6c8c59..61a72f34 100755 --- a/module.c +++ b/module.c @@ -30,7 +30,7 @@ static int soft_uart_write(struct tty_struct*, const unsigned char*, int); static unsigned int soft_uart_write_room(struct tty_struct*); static void soft_uart_flush_buffer(struct tty_struct*); static unsigned int soft_uart_chars_in_buffer(struct tty_struct*); -static void soft_uart_set_termios(struct tty_struct*, struct ktermios*); +static void soft_uart_set_termios(struct tty_struct*, const struct ktermios*); static void soft_uart_stop(struct tty_struct*); static void soft_uart_start(struct tty_struct*); static void soft_uart_hangup(struct tty_struct*); @@ -256,7 +256,7 @@ static unsigned int soft_uart_chars_in_buffer(struct tty_struct* tty) * @param tty given TTY * @param termios parameters */ -static void soft_uart_set_termios(struct tty_struct* tty, struct ktermios* termios) +static void soft_uart_set_termios(struct tty_struct* tty, const struct ktermios* termios) { int cflag = 0; speed_t baudrate = tty_get_baud_rate(tty); diff --git a/raspberry_soft_uart.c b/raspberry_soft_uart.c index 425a172e..d18dbc50 100755 --- a/raspberry_soft_uart.c +++ b/raspberry_soft_uart.c @@ -10,7 +10,7 @@ #include #include -static irq_handler_t handle_rx_start(unsigned int irq, void* device, struct pt_regs* registers); +static irqreturn_t handle_rx_start(int irq, void *device); static enum hrtimer_restart handle_tx(struct hrtimer* timer); static enum hrtimer_restart handle_rx(struct hrtimer* timer); static void receive_character(unsigned char character); @@ -63,7 +63,7 @@ int raspberry_soft_uart_init(const int _gpio_tx, const int _gpio_rx) // Initializes the interruption. success &= request_irq( gpio_to_irq(gpio_rx), - (irq_handler_t) handle_rx_start, + handle_rx_start, IRQF_TRIGGER_FALLING, "soft_uart_irq_handler", NULL) == 0; @@ -187,13 +187,13 @@ int raspberry_soft_uart_set_rx_callback(void (*callback)(unsigned char)) * If we are waiting for the RX start bit, then starts the RX timer. Otherwise, * does nothing. */ -static irq_handler_t handle_rx_start(unsigned int irq, void* device, struct pt_regs* registers) +static irqreturn_t handle_rx_start(int irq, void *device) { if (rx_bit_index == -1) { hrtimer_start(&timer_rx, half_period, HRTIMER_MODE_REL); } - return (irq_handler_t) IRQ_HANDLED; + return IRQ_HANDLED; } From 3ad7c40d15969bdc97cebd287ed8036181a89051 Mon Sep 17 00:00:00 2001 From: Giampiero Baggiani Date: Tue, 21 Mar 2023 16:33:45 +0100 Subject: [PATCH 10/13] Revert "Revert "Update Makefile"" This reverts commit edb76b81624b222462bb71eb0812e16f677d2b3c. --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index cc4de675..54fcc634 100755 --- a/Makefile +++ b/Makefile @@ -2,6 +2,8 @@ obj-m += soft_uart.o soft_uart-objs := module.o raspberry_soft_uart.o queue.o +ccflags-y := -Wno-incompatible-pointer-types + RELEASE = $(shell uname -r) LINUX = /usr/src/linux-headers-$(RELEASE) From e6ff857a1997e54ae5c9fc160219e166308c6edc Mon Sep 17 00:00:00 2001 From: Giampiero Baggiani Date: Tue, 14 Nov 2023 15:15:56 +0100 Subject: [PATCH 11/13] Compatibility with kernel 6.5.0 --- raspberry_soft_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/raspberry_soft_uart.c b/raspberry_soft_uart.c index d18dbc50..6e432c1b 100755 --- a/raspberry_soft_uart.c +++ b/raspberry_soft_uart.c @@ -128,7 +128,7 @@ int raspberry_soft_uart_set_baudrate(const int baudrate) { period = ktime_set(0, 1000000000/baudrate); half_period = ktime_set(0, 1000000000/baudrate/2); - gpio_set_debounce(gpio_rx, 1000/baudrate/2); + gpiod_set_debounce(gpio_to_desc(gpio_rx), 1000/baudrate/2); return 1; } From 55e34b8edf9c55e15c4c7b6e0565a852b5513606 Mon Sep 17 00:00:00 2001 From: Giampiero Baggiani Date: Mon, 18 Mar 2024 13:40:16 +0100 Subject: [PATCH 12/13] Compatibility with kernel 6.6 --- raspberry_soft_uart.c | 39 ++++++++++++++++----------------------- raspberry_soft_uart.h | 3 ++- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/raspberry_soft_uart.c b/raspberry_soft_uart.c index 6e432c1b..d7dbe17b 100755 --- a/raspberry_soft_uart.c +++ b/raspberry_soft_uart.c @@ -2,7 +2,6 @@ #include "raspberry_soft_uart.h" #include "queue.h" -#include #include #include #include @@ -22,8 +21,8 @@ static struct hrtimer timer_tx; static struct hrtimer timer_rx; static ktime_t period; static ktime_t half_period; -static int gpio_tx = 0; -static int gpio_rx = 0; +static struct gpio_desc *gpio_tx; +static struct gpio_desc *gpio_rx; static int rx_bit_index = -1; static void (*rx_callback)(unsigned char) = NULL; @@ -36,7 +35,7 @@ static void (*rx_callback)(unsigned char) = NULL; * @param gpio_rx GPIO pin used as RX * @return 1 if the initialization is successful. 0 otherwise. */ -int raspberry_soft_uart_init(const int _gpio_tx, const int _gpio_rx) +int raspberry_soft_uart_init(struct gpio_desc *_gpio_tx, struct gpio_desc *_gpio_rx) { bool success = true; @@ -53,21 +52,15 @@ int raspberry_soft_uart_init(const int _gpio_tx, const int _gpio_rx) // Initializes the GPIO pins. gpio_tx = _gpio_tx; gpio_rx = _gpio_rx; - - success &= gpio_request(gpio_tx, "soft_uart_tx") == 0; - success &= gpio_direction_output(gpio_tx, 1) == 0; - - success &= gpio_request(gpio_rx, "soft_uart_rx") == 0; - success &= gpio_direction_input(gpio_rx) == 0; // Initializes the interruption. success &= request_irq( - gpio_to_irq(gpio_rx), + gpiod_to_irq(gpio_rx), handle_rx_start, IRQF_TRIGGER_FALLING, "soft_uart_irq_handler", NULL) == 0; - disable_irq(gpio_to_irq(gpio_rx)); + disable_irq(gpiod_to_irq(gpio_rx)); return success; } @@ -77,10 +70,10 @@ int raspberry_soft_uart_init(const int _gpio_tx, const int _gpio_rx) */ int raspberry_soft_uart_finalize(void) { - free_irq(gpio_to_irq(gpio_rx), NULL); - gpio_set_value(gpio_tx, 0); - gpio_free(gpio_tx); - gpio_free(gpio_rx); + free_irq(gpiod_to_irq(gpio_rx), NULL); + gpiod_set_value(gpio_tx, 0); + gpiod_put(gpio_tx); + gpiod_put(gpio_rx); return 1; } @@ -99,7 +92,7 @@ int raspberry_soft_uart_open(struct tty_struct* tty) current_tty = tty; initialize_queue(&queue_tx); success = 1; - enable_irq(gpio_to_irq(gpio_rx)); + enable_irq(gpiod_to_irq(gpio_rx)); } mutex_unlock(¤t_tty_mutex); return success; @@ -111,7 +104,7 @@ int raspberry_soft_uart_open(struct tty_struct* tty) int raspberry_soft_uart_close(void) { mutex_lock(¤t_tty_mutex); - disable_irq(gpio_to_irq(gpio_rx)); + disable_irq(gpiod_to_irq(gpio_rx)); hrtimer_cancel(&timer_tx); hrtimer_cancel(&timer_rx); current_tty = NULL; @@ -128,7 +121,7 @@ int raspberry_soft_uart_set_baudrate(const int baudrate) { period = ktime_set(0, 1000000000/baudrate); half_period = ktime_set(0, 1000000000/baudrate/2); - gpiod_set_debounce(gpio_to_desc(gpio_rx), 1000/baudrate/2); + gpiod_set_debounce(gpio_rx, 1000/baudrate/2); return 1; } @@ -213,7 +206,7 @@ static enum hrtimer_restart handle_tx(struct hrtimer* timer) { if (dequeue_character(&queue_tx, &character)) { - gpio_set_value(gpio_tx, 0); + gpiod_set_value(gpio_tx, 0); bit_index++; must_restart_timer = true; } @@ -222,7 +215,7 @@ static enum hrtimer_restart handle_tx(struct hrtimer* timer) // Data bits. else if (0 <= bit_index && bit_index < 8) { - gpio_set_value(gpio_tx, 1 & (character >> bit_index)); + gpiod_set_value(gpio_tx, 1 & (character >> bit_index)); bit_index++; must_restart_timer = true; } @@ -230,7 +223,7 @@ static enum hrtimer_restart handle_tx(struct hrtimer* timer) // Stop bit. else if (bit_index == 8) { - gpio_set_value(gpio_tx, 1); + gpiod_set_value(gpio_tx, 1); character = 0; bit_index = -1; must_restart_timer = get_queue_size(&queue_tx) > 0; @@ -253,7 +246,7 @@ static enum hrtimer_restart handle_rx(struct hrtimer* timer) { ktime_t current_time = ktime_get(); static unsigned int character = 0; - int bit_value = gpio_get_value(gpio_rx); + int bit_value = gpiod_get_value(gpio_rx); enum hrtimer_restart result = HRTIMER_NORESTART; bool must_restart_timer = false; diff --git a/raspberry_soft_uart.h b/raspberry_soft_uart.h index de281053..f900f3dc 100755 --- a/raspberry_soft_uart.h +++ b/raspberry_soft_uart.h @@ -2,8 +2,9 @@ #define RASPBERRY_SOFT_UART_H #include +#include -int raspberry_soft_uart_init(const int gpio_tx, const int gpio_rx); +int raspberry_soft_uart_init(struct gpio_desc *_gpio_tx, struct gpio_desc *_gpio_rx); int raspberry_soft_uart_finalize(void); int raspberry_soft_uart_open(struct tty_struct* tty); int raspberry_soft_uart_close(void); From 941df1cda3b53c86a3d8042f6a545e84be552c82 Mon Sep 17 00:00:00 2001 From: Giampiero Baggiani Date: Mon, 18 Mar 2024 14:10:46 +0100 Subject: [PATCH 13/13] Compatibility with kernel 6.6 --- module.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/module.c b/module.c index 61a72f34..d79a8bf0 100755 --- a/module.c +++ b/module.c @@ -6,6 +6,7 @@ #include #include #include +#include #define SOFT_UART_MAJOR 0 #define N_PORTS 1 @@ -71,9 +72,17 @@ static struct tty_port port; */ static int __init soft_uart_init(void) { + bool success = true; + printk(KERN_INFO "soft_uart: Initializing module...\n"); + + success &= gpio_request(gpio_tx, "soft_uart_tx") == 0; + success &= gpio_direction_output(gpio_tx, 1) == 0; + + success &= gpio_request(gpio_rx, "soft_uart_rx") == 0; + success &= gpio_direction_input(gpio_rx) == 0; - if (!raspberry_soft_uart_init(gpio_tx, gpio_rx)) + if (!success || !raspberry_soft_uart_init(gpio_to_desc(gpio_tx), gpio_to_desc(gpio_rx))) { printk(KERN_ALERT "soft_uart: Failed initialize GPIO.\n"); return -ENOMEM;