diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arm/PL0/PL0_test.c (renamed from src/PL0/PL0_test.c) | 0 | ||||
-rw-r--r-- | src/arm/PL0/PL0_test.ld (renamed from src/PL0/PL0_test.ld) | 0 | ||||
-rw-r--r-- | src/arm/PL0/PL0_utils.c (renamed from src/PL0/PL0_utils.c) | 2 | ||||
-rw-r--r-- | src/arm/PL0/PL0_utils.h (renamed from src/PL0/PL0_utils.h) | 2 | ||||
-rw-r--r-- | src/arm/PL0/svc.S (renamed from src/utils/svc.S) | 0 | ||||
-rw-r--r-- | src/arm/PL1/PL1_common/global.h (renamed from src/global.h) | 0 | ||||
-rw-r--r-- | src/arm/PL1/PL1_common/uart.c (renamed from src/utils/uart.c) | 2 | ||||
-rw-r--r-- | src/arm/PL1/PL1_common/uart.h (renamed from src/utils/uart.h) | 4 | ||||
-rw-r--r-- | src/arm/PL1/kernel/armclock.h (renamed from src/clock/armclock.h) | 4 | ||||
-rw-r--r-- | src/arm/PL1/kernel/atags.c (renamed from src/atags/atags.c) | 2 | ||||
-rw-r--r-- | src/arm/PL1/kernel/atags.h (renamed from src/atags/atags.h) | 0 | ||||
-rw-r--r-- | src/arm/PL1/kernel/bcmclock.h (renamed from src/clock/bcmclock.h) | 4 | ||||
-rw-r--r-- | src/arm/PL1/kernel/cp_regs.h (renamed from src/memory/cp_regs.h) | 0 | ||||
-rw-r--r-- | src/arm/PL1/kernel/demo_functionality.c (renamed from src/demo/demo_functionality.c) | 18 | ||||
-rw-r--r-- | src/arm/PL1/kernel/demo_functionality.h (renamed from src/demo/demo_functionality.h) | 0 | ||||
-rw-r--r-- | src/arm/PL1/kernel/interrupt_vector.S (renamed from src/interrupts/interrupt_vector.S) | 0 | ||||
-rw-r--r-- | src/arm/PL1/kernel/interrupts.c (renamed from src/interrupts/interrupts.c) | 10 | ||||
-rw-r--r-- | src/arm/PL1/kernel/interrupts.h (renamed from src/interrupts/interrupts.h) | 0 | ||||
-rw-r--r-- | src/arm/PL1/kernel/kernel_stage1.S (renamed from src/boot/kernel_stage1.S) | 0 | ||||
-rw-r--r-- | src/arm/PL1/kernel/kernel_stage1.ld (renamed from src/boot/kernel_stage1.ld) | 0 | ||||
-rw-r--r-- | src/arm/PL1/kernel/kernel_stage2.ld (renamed from src/boot/kernel_stage2.ld) | 0 | ||||
-rw-r--r-- | src/arm/PL1/kernel/memory.h (renamed from src/memory/memory.h) | 0 | ||||
-rw-r--r-- | src/arm/PL1/kernel/paging.c (renamed from src/memory/paging.c) | 4 | ||||
-rw-r--r-- | src/arm/PL1/kernel/paging.h (renamed from src/memory/paging.h) | 0 | ||||
-rw-r--r-- | src/arm/PL1/kernel/psr.h (renamed from src/boot/psr.h) | 0 | ||||
-rw-r--r-- | src/arm/PL1/kernel/ramfs.c (renamed from src/memory/ramfs.c) | 0 | ||||
-rw-r--r-- | src/arm/PL1/kernel/ramfs.h (renamed from src/memory/ramfs.h) | 0 | ||||
-rw-r--r-- | src/arm/PL1/kernel/scheduler.c (renamed from src/scheduler.c) | 10 | ||||
-rw-r--r-- | src/arm/PL1/kernel/scheduler.h (renamed from src/scheduler.h) | 2 | ||||
-rw-r--r-- | src/arm/PL1/kernel/setup.c (renamed from src/boot/setup.c) | 16 | ||||
-rw-r--r-- | src/arm/PL1/kernel/translation_table_descriptors.h (renamed from src/memory/translation_table_descriptors.h) | 0 | ||||
-rw-r--r-- | src/arm/PL1/loader/loader_stage1.S (renamed from src/boot/loader_stage1.S) | 0 | ||||
-rw-r--r-- | src/arm/PL1/loader/loader_stage1_linker.ld (renamed from src/boot/loader_stage1_linker.ld) | 0 | ||||
-rw-r--r-- | src/arm/PL1/loader/loader_stage2.c (renamed from src/boot/loader_stage2.c) | 6 | ||||
-rw-r--r-- | src/arm/PL1/loader/loader_stage2_linker.ld (renamed from src/boot/loader_stage2_linker.ld) | 0 | ||||
-rw-r--r-- | src/arm/common/io.c (renamed from src/utils/io.c) | 0 | ||||
-rw-r--r-- | src/arm/common/io.h (renamed from src/utils/io.h) | 0 | ||||
-rw-r--r-- | src/arm/common/strings.c (renamed from src/utils/strings.c) | 0 | ||||
-rw-r--r-- | src/arm/common/strings.h (renamed from src/utils/strings.h) | 0 | ||||
-rw-r--r-- | src/arm/common/svc_interface.h (renamed from src/utils/svc_interface.h) | 0 | ||||
-rw-r--r-- | src/host/makefs.c (renamed from src/memory/makefs.c) | 0 | ||||
-rw-r--r-- | src/host/pipe_image.c (renamed from src/utils/pipe_image.c) | 2 | ||||
-rw-r--r-- | src/lib/rs232/rs232.c | 873 | ||||
-rw-r--r-- | src/lib/rs232/rs232.h | 88 |
44 files changed, 1005 insertions, 44 deletions
diff --git a/src/PL0/PL0_test.c b/src/arm/PL0/PL0_test.c index 0bfebc7..0bfebc7 100644 --- a/src/PL0/PL0_test.c +++ b/src/arm/PL0/PL0_test.c diff --git a/src/PL0/PL0_test.ld b/src/arm/PL0/PL0_test.ld index b1d06f4..b1d06f4 100644 --- a/src/PL0/PL0_test.ld +++ b/src/arm/PL0/PL0_test.ld diff --git a/src/PL0/PL0_utils.c b/src/arm/PL0/PL0_utils.c index b9853fb..d83edb9 100644 --- a/src/PL0/PL0_utils.c +++ b/src/arm/PL0/PL0_utils.c @@ -1,7 +1,7 @@ #include <stddef.h> #include <stdint.h> -#include "../utils/svc_interface.h" +#include "svc_interface.h" #include "PL0_utils.h" // most generic definition possible diff --git a/src/PL0/PL0_utils.h b/src/arm/PL0/PL0_utils.h index e87b1f0..c26a100 100644 --- a/src/PL0/PL0_utils.h +++ b/src/arm/PL0/PL0_utils.h @@ -1,6 +1,6 @@ #ifndef PL0_UTILS_H #define PL0_UTILS_H -#include "../utils/io.h" +#include "io.h" #endif // PL0_UTILS_H diff --git a/src/utils/svc.S b/src/arm/PL0/svc.S index 65200d8..65200d8 100644 --- a/src/utils/svc.S +++ b/src/arm/PL0/svc.S diff --git a/src/global.h b/src/arm/PL1/PL1_common/global.h index 4e17b44..4e17b44 100644 --- a/src/global.h +++ b/src/arm/PL1/PL1_common/global.h diff --git a/src/utils/uart.c b/src/arm/PL1/PL1_common/uart.c index a389e41..4dd1c2b 100644 --- a/src/utils/uart.c +++ b/src/arm/PL1/PL1_common/uart.c @@ -1,7 +1,7 @@ #include <stddef.h> #include <stdint.h> #include "uart.h" -#include "../global.h" +#include "global.h" // Loop <delay> times in a way that the compiler won't optimize away static inline void delay(int32_t count) diff --git a/src/utils/uart.h b/src/arm/PL1/PL1_common/uart.h index 2a8b7d4..96f3634 100644 --- a/src/utils/uart.h +++ b/src/arm/PL1/PL1_common/uart.h @@ -2,8 +2,8 @@ #define UART_H #include <stdint.h> -#include "../global.h" -#include "../interrupts/interrupts.h" +#include "global.h" +#include "interrupts.h" // The offsets for reach register. diff --git a/src/clock/armclock.h b/src/arm/PL1/kernel/armclock.h index 0d83fc2..0792ad3 100644 --- a/src/clock/armclock.h +++ b/src/arm/PL1/kernel/armclock.h @@ -3,8 +3,8 @@ #include <stdint.h> -#include "../global.h" -#include "../interrupts/interrupts.h" +#include "global.h" +#include "interrupts.h" #define ARMCLK_LOAD (ARM_BASE + 0x400) #define ARMCLK_VALUE (ARM_BASE + 0x404) #define ARMCLK_CONTROL (ARM_BASE + 0x408) diff --git a/src/atags/atags.c b/src/arm/PL1/kernel/atags.c index 54740d8..e2e6a24 100644 --- a/src/atags/atags.c +++ b/src/arm/PL1/kernel/atags.c @@ -1,5 +1,5 @@ #include "atags.h" -#include "../utils/io.h" +#include "io.h" static inline struct atag_header *next_tag(struct atag_header *tag) { diff --git a/src/atags/atags.h b/src/arm/PL1/kernel/atags.h index 4b6879f..4b6879f 100644 --- a/src/atags/atags.h +++ b/src/arm/PL1/kernel/atags.h diff --git a/src/clock/bcmclock.h b/src/arm/PL1/kernel/bcmclock.h index d08912b..462346d 100644 --- a/src/clock/bcmclock.h +++ b/src/arm/PL1/kernel/bcmclock.h @@ -2,8 +2,8 @@ #define BCMCLOCK_H #include <stdint.h> -#include "../interrupts/interrupts.h" -#include "../global.h" +#include "interrupts.h" +#include "global.h" #define ST_BASE (PERIF_BASE + 0x3000) // System Timer diff --git a/src/memory/cp_regs.h b/src/arm/PL1/kernel/cp_regs.h index e5e7063..e5e7063 100644 --- a/src/memory/cp_regs.h +++ b/src/arm/PL1/kernel/cp_regs.h diff --git a/src/demo/demo_functionality.c b/src/arm/PL1/kernel/demo_functionality.c index d9c0888..217a858 100644 --- a/src/demo/demo_functionality.c +++ b/src/arm/PL1/kernel/demo_functionality.c @@ -1,12 +1,12 @@ -#include "../utils/io.h" -#include "../boot/psr.h" -#include "../memory/memory.h" -#include "../memory/translation_table_descriptors.h" -#include "../memory/ramfs.h" -#include "../utils/strings.h" -#include "../memory/paging.h" -#include "../clock/armclock.h" -#include "../scheduler.h" +#include "io.h" +#include "psr.h" +#include "memory.h" +#include "translation_table_descriptors.h" +#include "ramfs.h" +#include "strings.h" +#include "paging.h" +#include "armclock.h" +#include "scheduler.h" void demo_paging_support(void) { diff --git a/src/demo/demo_functionality.h b/src/arm/PL1/kernel/demo_functionality.h index a338c71..a338c71 100644 --- a/src/demo/demo_functionality.h +++ b/src/arm/PL1/kernel/demo_functionality.h diff --git a/src/interrupts/interrupt_vector.S b/src/arm/PL1/kernel/interrupt_vector.S index 1ec80f7..1ec80f7 100644 --- a/src/interrupts/interrupt_vector.S +++ b/src/arm/PL1/kernel/interrupt_vector.S diff --git a/src/interrupts/interrupts.c b/src/arm/PL1/kernel/interrupts.c index 5c30375..121d79c 100644 --- a/src/interrupts/interrupts.c +++ b/src/arm/PL1/kernel/interrupts.c @@ -1,8 +1,8 @@ -#include "../utils/io.h" -#include "../utils/uart.h" -#include "../utils/svc_interface.h" -#include "../clock/armclock.h" -#include "../scheduler.h" +#include "io.h" +#include "uart.h" +#include "svc_interface.h" +#include "armclock.h" +#include "scheduler.h" /** @brief The undefined instruction interrupt handler **/ diff --git a/src/interrupts/interrupts.h b/src/arm/PL1/kernel/interrupts.h index c2818ee..c2818ee 100644 --- a/src/interrupts/interrupts.h +++ b/src/arm/PL1/kernel/interrupts.h diff --git a/src/boot/kernel_stage1.S b/src/arm/PL1/kernel/kernel_stage1.S index e770513..e770513 100644 --- a/src/boot/kernel_stage1.S +++ b/src/arm/PL1/kernel/kernel_stage1.S diff --git a/src/boot/kernel_stage1.ld b/src/arm/PL1/kernel/kernel_stage1.ld index 3130634..3130634 100644 --- a/src/boot/kernel_stage1.ld +++ b/src/arm/PL1/kernel/kernel_stage1.ld diff --git a/src/boot/kernel_stage2.ld b/src/arm/PL1/kernel/kernel_stage2.ld index 9411ca2..9411ca2 100644 --- a/src/boot/kernel_stage2.ld +++ b/src/arm/PL1/kernel/kernel_stage2.ld diff --git a/src/memory/memory.h b/src/arm/PL1/kernel/memory.h index bdeba52..bdeba52 100644 --- a/src/memory/memory.h +++ b/src/arm/PL1/kernel/memory.h diff --git a/src/memory/paging.c b/src/arm/PL1/kernel/paging.c index aa18087..771c681 100644 --- a/src/memory/paging.c +++ b/src/arm/PL1/kernel/paging.c @@ -1,8 +1,8 @@ #include "cp_regs.h" -#include "../utils/strings.h" +#include "strings.h" #include "memory.h" #include "translation_table_descriptors.h" -#include "../utils/io.h" +#include "io.h" #include "paging.h" diff --git a/src/memory/paging.h b/src/arm/PL1/kernel/paging.h index 4ac8efa..4ac8efa 100644 --- a/src/memory/paging.h +++ b/src/arm/PL1/kernel/paging.h diff --git a/src/boot/psr.h b/src/arm/PL1/kernel/psr.h index f300a7a..f300a7a 100644 --- a/src/boot/psr.h +++ b/src/arm/PL1/kernel/psr.h diff --git a/src/memory/ramfs.c b/src/arm/PL1/kernel/ramfs.c index cc66b4c..cc66b4c 100644 --- a/src/memory/ramfs.c +++ b/src/arm/PL1/kernel/ramfs.c diff --git a/src/memory/ramfs.h b/src/arm/PL1/kernel/ramfs.h index cf45736..cf45736 100644 --- a/src/memory/ramfs.h +++ b/src/arm/PL1/kernel/ramfs.h diff --git a/src/scheduler.c b/src/arm/PL1/kernel/scheduler.c index 146eb29..141ba1d 100644 --- a/src/scheduler.c +++ b/src/arm/PL1/kernel/scheduler.c @@ -1,9 +1,9 @@ #include "scheduler.h" -#include "utils/uart.h" -#include "utils/strings.h" -#include "clock/armclock.h" -#include "memory/memory.h" -#include "utils/io.h" +#include "uart.h" +#include "strings.h" +#include "armclock.h" +#include "memory.h" +#include "io.h" // for now we only have 1 process in "queue" // later there is going to be an actual queue diff --git a/src/scheduler.h b/src/arm/PL1/kernel/scheduler.h index 58f659c..8c0f569 100644 --- a/src/scheduler.h +++ b/src/arm/PL1/kernel/scheduler.h @@ -3,7 +3,7 @@ #include <stdint.h> -#include "boot/psr.h" +#include "psr.h" extern PSR_t PL1_PSR; diff --git a/src/boot/setup.c b/src/arm/PL1/kernel/setup.c index 2f74e64..bf7c9a1 100644 --- a/src/boot/setup.c +++ b/src/arm/PL1/kernel/setup.c @@ -1,12 +1,12 @@ -#include "../utils/uart.h" -#include "../utils/io.h" -#include "../demo/demo_functionality.h" -#include "../memory/paging.h" -#include "../atags/atags.h" +#include "uart.h" +#include "io.h" +#include "demo_functionality.h" +#include "paging.h" +#include "atags.h" // for POWER_OF_2() macro... perhaps the macro should be moved -#include "../memory/memory.h" -#include "../clock/armclock.h" -#include "../scheduler.h" +#include "memory.h" +#include "armclock.h" +#include "scheduler.h" void setup(uint32_t r0, uint32_t machine_type, struct atag_header *atags) diff --git a/src/memory/translation_table_descriptors.h b/src/arm/PL1/kernel/translation_table_descriptors.h index 981c3c7..981c3c7 100644 --- a/src/memory/translation_table_descriptors.h +++ b/src/arm/PL1/kernel/translation_table_descriptors.h diff --git a/src/boot/loader_stage1.S b/src/arm/PL1/loader/loader_stage1.S index 69d78c5..69d78c5 100644 --- a/src/boot/loader_stage1.S +++ b/src/arm/PL1/loader/loader_stage1.S diff --git a/src/boot/loader_stage1_linker.ld b/src/arm/PL1/loader/loader_stage1_linker.ld index 711fcbf..711fcbf 100644 --- a/src/boot/loader_stage1_linker.ld +++ b/src/arm/PL1/loader/loader_stage1_linker.ld diff --git a/src/boot/loader_stage2.c b/src/arm/PL1/loader/loader_stage2.c index e08756b..fc3ae1c 100644 --- a/src/boot/loader_stage2.c +++ b/src/arm/PL1/loader/loader_stage2.c @@ -1,8 +1,8 @@ #include <stddef.h> #include <stdint.h> -#include "../utils/uart.h" -#include "../utils/io.h" -#include "../global.h" +#include "uart.h" +#include "io.h" +#include "global.h" void *const kernel_load_addr = ((void*) 0x8000); diff --git a/src/boot/loader_stage2_linker.ld b/src/arm/PL1/loader/loader_stage2_linker.ld index 33e79e9..33e79e9 100644 --- a/src/boot/loader_stage2_linker.ld +++ b/src/arm/PL1/loader/loader_stage2_linker.ld diff --git a/src/utils/io.c b/src/arm/common/io.c index bf9e0e3..bf9e0e3 100644 --- a/src/utils/io.c +++ b/src/arm/common/io.c diff --git a/src/utils/io.h b/src/arm/common/io.h index dcad76e..dcad76e 100644 --- a/src/utils/io.h +++ b/src/arm/common/io.h diff --git a/src/utils/strings.c b/src/arm/common/strings.c index 368d7dc..368d7dc 100644 --- a/src/utils/strings.c +++ b/src/arm/common/strings.c diff --git a/src/utils/strings.h b/src/arm/common/strings.h index aff0533..aff0533 100644 --- a/src/utils/strings.h +++ b/src/arm/common/strings.h diff --git a/src/utils/svc_interface.h b/src/arm/common/svc_interface.h index aa478ce..aa478ce 100644 --- a/src/utils/svc_interface.h +++ b/src/arm/common/svc_interface.h diff --git a/src/memory/makefs.c b/src/host/makefs.c index 379e8c5..379e8c5 100644 --- a/src/memory/makefs.c +++ b/src/host/makefs.c diff --git a/src/utils/pipe_image.c b/src/host/pipe_image.c index b148ac4..105f9a1 100644 --- a/src/utils/pipe_image.c +++ b/src/host/pipe_image.c @@ -3,7 +3,7 @@ #include <endian.h> #include <stdint.h> #include <sys/types.h> -#include "../../lib/rs232/rs232.h" +#include "rs232.h" #define ANSI_FG_RED "\033[0;31m" #define ANSI_FG_DEFAULT "\033[0;39m" diff --git a/src/lib/rs232/rs232.c b/src/lib/rs232/rs232.c new file mode 100644 index 0000000..0ae2a59 --- /dev/null +++ b/src/lib/rs232/rs232.c @@ -0,0 +1,873 @@ +/* +*************************************************************************** +* +* Author: Teunis van Beelen +* +* Copyright (C) 2005 - 2019 Teunis van Beelen +* +* Email: teuniz@protonmail.com +* +*************************************************************************** +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +*************************************************************************** +*/ + + +/* Last revision: May 31, 2019 */ +/* Added support for hardware flow control using RTS and CTS lines */ +/* For more info and how to use this library, visit: http://www.teuniz.net/RS-232/ */ + + +#include "rs232.h" + + +#if defined(__linux__) || defined(__FreeBSD__) /* Linux & FreeBSD */ + +#define RS232_PORTNR 38 + + +int Cport[RS232_PORTNR], + error; + +struct termios new_port_settings, + old_port_settings[RS232_PORTNR]; + +char *comports[RS232_PORTNR]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2","/dev/ttyS3","/dev/ttyS4","/dev/ttyS5", + "/dev/ttyS6","/dev/ttyS7","/dev/ttyS8","/dev/ttyS9","/dev/ttyS10","/dev/ttyS11", + "/dev/ttyS12","/dev/ttyS13","/dev/ttyS14","/dev/ttyS15","/dev/ttyUSB0", + "/dev/ttyUSB1","/dev/ttyUSB2","/dev/ttyUSB3","/dev/ttyUSB4","/dev/ttyUSB5", + "/dev/ttyAMA0","/dev/ttyAMA1","/dev/ttyACM0","/dev/ttyACM1", + "/dev/rfcomm0","/dev/rfcomm1","/dev/ircomm0","/dev/ircomm1", + "/dev/cuau0","/dev/cuau1","/dev/cuau2","/dev/cuau3", + "/dev/cuaU0","/dev/cuaU1","/dev/cuaU2","/dev/cuaU3"}; + +int RS232_OpenComport(int comport_number, int baudrate, const char *mode, int flowctrl) +{ + int baudr, + status; + + if((comport_number>=RS232_PORTNR)||(comport_number<0)) + { + printf("illegal comport number\n"); + return(1); + } + + switch(baudrate) + { + case 50 : baudr = B50; + break; + case 75 : baudr = B75; + break; + case 110 : baudr = B110; + break; + case 134 : baudr = B134; + break; + case 150 : baudr = B150; + break; + case 200 : baudr = B200; + break; + case 300 : baudr = B300; + break; + case 600 : baudr = B600; + break; + case 1200 : baudr = B1200; + break; + case 1800 : baudr = B1800; + break; + case 2400 : baudr = B2400; + break; + case 4800 : baudr = B4800; + break; + case 9600 : baudr = B9600; + break; + case 19200 : baudr = B19200; + break; + case 38400 : baudr = B38400; + break; + case 57600 : baudr = B57600; + break; + case 115200 : baudr = B115200; + break; + case 230400 : baudr = B230400; + break; + case 460800 : baudr = B460800; + break; + case 500000 : baudr = B500000; + break; + case 576000 : baudr = B576000; + break; + case 921600 : baudr = B921600; + break; + case 1000000 : baudr = B1000000; + break; + case 1152000 : baudr = B1152000; + break; + case 1500000 : baudr = B1500000; + break; + case 2000000 : baudr = B2000000; + break; + case 2500000 : baudr = B2500000; + break; + case 3000000 : baudr = B3000000; + break; + case 3500000 : baudr = B3500000; + break; + case 4000000 : baudr = B4000000; + break; + default : printf("invalid baudrate\n"); + return(1); + break; + } + + int cbits=CS8, + cpar=0, + ipar=IGNPAR, + bstop=0; + + if(strlen(mode) != 3) + { + printf("invalid mode \"%s\"\n", mode); + return(1); + } + + switch(mode[0]) + { + case '8': cbits = CS8; + break; + case '7': cbits = CS7; + break; + case '6': cbits = CS6; + break; + case '5': cbits = CS5; + break; + default : printf("invalid number of data-bits '%c'\n", mode[0]); + return(1); + break; + } + + switch(mode[1]) + { + case 'N': + case 'n': cpar = 0; + ipar = IGNPAR; + break; + case 'E': + case 'e': cpar = PARENB; + ipar = INPCK; + break; + case 'O': + case 'o': cpar = (PARENB | PARODD); + ipar = INPCK; + break; + default : printf("invalid parity '%c'\n", mode[1]); + return(1); + break; + } + + switch(mode[2]) + { + case '1': bstop = 0; + break; + case '2': bstop = CSTOPB; + break; + default : printf("invalid number of stop bits '%c'\n", mode[2]); + return(1); + break; + } + +/* +http://pubs.opengroup.org/onlinepubs/7908799/xsh/termios.h.html + +http://man7.org/linux/man-pages/man3/termios.3.html +*/ + + Cport[comport_number] = open(comports[comport_number], O_RDWR | O_NOCTTY | O_NDELAY); + if(Cport[comport_number]==-1) + { + perror("unable to open comport "); + return(1); + } + + /* lock access so that another process can't also use the port */ + if(flock(Cport[comport_number], LOCK_EX | LOCK_NB) != 0) + { + close(Cport[comport_number]); + perror("Another process has locked the comport."); + return(1); + } + + error = tcgetattr(Cport[comport_number], old_port_settings + comport_number); + if(error==-1) + { + close(Cport[comport_number]); + flock(Cport[comport_number], LOCK_UN); /* free the port so that others can use it. */ + perror("unable to read portsettings "); + return(1); + } + memset(&new_port_settings, 0, sizeof(new_port_settings)); /* clear the new struct */ + + new_port_settings.c_cflag = cbits | cpar | bstop | CLOCAL | CREAD; + if(flowctrl) + { + new_port_settings.c_cflag |= CRTSCTS; + } + new_port_settings.c_iflag = ipar; + new_port_settings.c_oflag = 0; + new_port_settings.c_lflag = 0; + new_port_settings.c_cc[VMIN] = 0; /* block untill n bytes are received */ + new_port_settings.c_cc[VTIME] = 0; /* block untill a timer expires (n * 100 mSec.) */ + + cfsetispeed(&new_port_settings, baudr); + cfsetospeed(&new_port_settings, baudr); + + error = tcsetattr(Cport[comport_number], TCSANOW, &new_port_settings); + if(error==-1) + { + tcsetattr(Cport[comport_number], TCSANOW, old_port_settings + comport_number); + close(Cport[comport_number]); + flock(Cport[comport_number], LOCK_UN); /* free the port so that others can use it. */ + perror("unable to adjust portsettings "); + return(1); + } + +/* http://man7.org/linux/man-pages/man4/tty_ioctl.4.html */ + + if(ioctl(Cport[comport_number], TIOCMGET, &status) == -1) + { + tcsetattr(Cport[comport_number], TCSANOW, old_port_settings + comport_number); + flock(Cport[comport_number], LOCK_UN); /* free the port so that others can use it. */ + perror("unable to get portstatus"); + return(1); + } + + status |= TIOCM_DTR; /* turn on DTR */ + status |= TIOCM_RTS; /* turn on RTS */ + + if(ioctl(Cport[comport_number], TIOCMSET, &status) == -1) + { + tcsetattr(Cport[comport_number], TCSANOW, old_port_settings + comport_number); + flock(Cport[comport_number], LOCK_UN); /* free the port so that others can use it. */ + perror("unable to set portstatus"); + return(1); + } + + return(0); +} + + +int RS232_PollComport(int comport_number, unsigned char *buf, int size) +{ + int n; + + n = read(Cport[comport_number], buf, size); + + if(n < 0) + { + if(errno == EAGAIN) return 0; + } + + return(n); +} + + +int RS232_SendByte(int comport_number, unsigned char byte) +{ + int n = write(Cport[comport_number], &byte, 1); + if(n < 0) + { + if(errno == EAGAIN) + { + return 0; + } + else + { + return 1; + } + } + + return(0); +} + + +int RS232_SendBuf(int comport_number, unsigned char *buf, int size) +{ + int n = write(Cport[comport_number], buf, size); + if(n < 0) + { + if(errno == EAGAIN) + { + return 0; + } + else + { + return -1; + } + } + + return(n); +} + + +void RS232_CloseComport(int comport_number) +{ + int status; + + if(ioctl(Cport[comport_number], TIOCMGET, &status) == -1) + { + perror("unable to get portstatus"); + } + + status &= ~TIOCM_DTR; /* turn off DTR */ + status &= ~TIOCM_RTS; /* turn off RTS */ + + if(ioctl(Cport[comport_number], TIOCMSET, &status) == -1) + { + perror("unable to set portstatus"); + } + + tcsetattr(Cport[comport_number], TCSANOW, old_port_settings + comport_number); + close(Cport[comport_number]); + + flock(Cport[comport_number], LOCK_UN); /* free the port so that others can use it. */ +} + +/* +Constant Description +TIOCM_LE DSR (data set ready/line enable) +TIOCM_DTR DTR (data terminal ready) +TIOCM_RTS RTS (request to send) +TIOCM_ST Secondary TXD (transmit) +TIOCM_SR Secondary RXD (receive) +TIOCM_CTS CTS (clear to send) +TIOCM_CAR DCD (data carrier detect) +TIOCM_CD see TIOCM_CAR +TIOCM_RNG RNG (ring) +TIOCM_RI see TIOCM_RNG +TIOCM_DSR DSR (data set ready) + +http://man7.org/linux/man-pages/man4/tty_ioctl.4.html +*/ + +int RS232_IsDCDEnabled(int comport_number) +{ + int status; + + ioctl(Cport[comport_number], TIOCMGET, &status); + + if(status&TIOCM_CAR) return(1); + else return(0); +} + + +int RS232_IsRINGEnabled(int comport_number) +{ + int status; + + ioctl(Cport[comport_number], TIOCMGET, &status); + + if(status&TIOCM_RNG) return(1); + else return(0); +} + + +int RS232_IsCTSEnabled(int comport_number) +{ + int status; + + ioctl(Cport[comport_number], TIOCMGET, &status); + + if(status&TIOCM_CTS) return(1); + else return(0); +} + + +int RS232_IsDSREnabled(int comport_number) +{ + int status; + + ioctl(Cport[comport_number], TIOCMGET, &status); + + if(status&TIOCM_DSR) return(1); + else return(0); +} + + +void RS232_enableDTR(int comport_number) +{ + int status; + + if(ioctl(Cport[comport_number], TIOCMGET, &status) == -1) + { + perror("unable to get portstatus"); + } + + status |= TIOCM_DTR; /* turn on DTR */ + + if(ioctl(Cport[comport_number], TIOCMSET, &status) == -1) + { + perror("unable to set portstatus"); + } +} + + +void RS232_disableDTR(int comport_number) +{ + int status; + + if(ioctl(Cport[comport_number], TIOCMGET, &status) == -1) + { + perror("unable to get portstatus"); + } + + status &= ~TIOCM_DTR; /* turn off DTR */ + + if(ioctl(Cport[comport_number], TIOCMSET, &status) == -1) + { + perror("unable to set portstatus"); + } +} + + +void RS232_enableRTS(int comport_number) +{ + int status; + + if(ioctl(Cport[comport_number], TIOCMGET, &status) == -1) + { + perror("unable to get portstatus"); + } + + status |= TIOCM_RTS; /* turn on RTS */ + + if(ioctl(Cport[comport_number], TIOCMSET, &status) == -1) + { + perror("unable to set portstatus"); + } +} + + +void RS232_disableRTS(int comport_number) +{ + int status; + + if(ioctl(Cport[comport_number], TIOCMGET, &status) == -1) + { + perror("unable to get portstatus"); + } + + status &= ~TIOCM_RTS; /* turn off RTS */ + + if(ioctl(Cport[comport_number], TIOCMSET, &status) == -1) + { + perror("unable to set portstatus"); + } +} + + +void RS232_flushRX(int comport_number) +{ + tcflush(Cport[comport_number], TCIFLUSH); +} + + +void RS232_flushTX(int comport_number) +{ + tcflush(Cport[comport_number], TCOFLUSH); +} + + +void RS232_flushRXTX(int comport_number) +{ + tcflush(Cport[comport_number], TCIOFLUSH); +} + + +#else /* windows */ + +#define RS232_PORTNR 32 + +HANDLE Cport[RS232_PORTNR]; + + +char *comports[RS232_PORTNR]={"\\\\.\\COM1", "\\\\.\\COM2", "\\\\.\\COM3", "\\\\.\\COM4", + "\\\\.\\COM5", "\\\\.\\COM6", "\\\\.\\COM7", "\\\\.\\COM8", + "\\\\.\\COM9", "\\\\.\\COM10", "\\\\.\\COM11", "\\\\.\\COM12", + "\\\\.\\COM13", "\\\\.\\COM14", "\\\\.\\COM15", "\\\\.\\COM16", + "\\\\.\\COM17", "\\\\.\\COM18", "\\\\.\\COM19", "\\\\.\\COM20", + "\\\\.\\COM21", "\\\\.\\COM22", "\\\\.\\COM23", "\\\\.\\COM24", + "\\\\.\\COM25", "\\\\.\\COM26", "\\\\.\\COM27", "\\\\.\\COM28", + "\\\\.\\COM29", "\\\\.\\COM30", "\\\\.\\COM31", "\\\\.\\COM32"}; + +char mode_str[128]; + + +int RS232_OpenComport(int comport_number, int baudrate, const char *mode, int flowctrl) +{ + if((comport_number>=RS232_PORTNR)||(comport_number<0)) + { + printf("illegal comport number\n"); + return(1); + } + + switch(baudrate) + { + case 110 : strcpy(mode_str, "baud=110"); + break; + case 300 : strcpy(mode_str, "baud=300"); + break; + case 600 : strcpy(mode_str, "baud=600"); + break; + case 1200 : strcpy(mode_str, "baud=1200"); + break; + case 2400 : strcpy(mode_str, "baud=2400"); + break; + case 4800 : strcpy(mode_str, "baud=4800"); + break; + case 9600 : strcpy(mode_str, "baud=9600"); + break; + case 19200 : strcpy(mode_str, "baud=19200"); + break; + case 38400 : strcpy(mode_str, "baud=38400"); + break; + case 57600 : strcpy(mode_str, "baud=57600"); + break; + case 115200 : strcpy(mode_str, "baud=115200"); + break; + case 128000 : strcpy(mode_str, "baud=128000"); + break; + case 256000 : strcpy(mode_str, "baud=256000"); + break; + case 500000 : strcpy(mode_str, "baud=500000"); + break; + case 921600 : strcpy(mode_str, "baud=921600"); + break; + case 1000000 : strcpy(mode_str, "baud=1000000"); + break; + case 1500000 : strcpy(mode_str, "baud=1500000"); + break; + case 2000000 : strcpy(mode_str, "baud=2000000"); + break; + case 3000000 : strcpy(mode_str, "baud=3000000"); + break; + default : printf("invalid baudrate\n"); + return(1); + break; + } + + if(strlen(mode) != 3) + { + printf("invalid mode \"%s\"\n", mode); + return(1); + } + + switch(mode[0]) + { + case '8': strcat(mode_str, " data=8"); + break; + case '7': strcat(mode_str, " data=7"); + break; + case '6': strcat(mode_str, " data=6"); + break; + case '5': strcat(mode_str, " data=5"); + break; + default : printf("invalid number of data-bits '%c'\n", mode[0]); + return(1); + break; + } + + switch(mode[1]) + { + case 'N': + case 'n': strcat(mode_str, " parity=n"); + break; + case 'E': + case 'e': strcat(mode_str, " parity=e"); + break; + case 'O': + case 'o': strcat(mode_str, " parity=o"); + break; + default : printf("invalid parity '%c'\n", mode[1]); + return(1); + break; + } + + switch(mode[2]) + { + case '1': strcat(mode_str, " stop=1"); + break; + case '2': strcat(mode_str, " stop=2"); + break; + default : printf("invalid number of stop bits '%c'\n", mode[2]); + return(1); + break; + } + + if(flowctrl) + { + strcat(mode_str, " xon=off to=off odsr=off dtr=on rts=off"); + } + else + { + strcat(mode_str, " xon=off to=off odsr=off dtr=on rts=on"); + } + +/* +http://msdn.microsoft.com/en-us/library/windows/desktop/aa363145%28v=vs.85%29.aspx + +http://technet.microsoft.com/en-us/library/cc732236.aspx + +https://docs.microsoft.com/en-us/windows/desktop/api/winbase/ns-winbase-_dcb +*/ + + Cport[comport_number] = CreateFileA(comports[comport_number], + GENERIC_READ|GENERIC_WRITE, + 0, /* no share */ + NULL, /* no security */ + OPEN_EXISTING, + 0, /* no threads */ + NULL); /* no templates */ + + if(Cport[comport_number]==INVALID_HANDLE_VALUE) + { + printf("unable to open comport\n"); + return(1); + } + + DCB port_settings; + memset(&port_settings, 0, sizeof(port_settings)); /* clear the new struct */ + port_settings.DCBlength = sizeof(port_settings); + + if(!BuildCommDCBA(mode_str, &port_settings)) + { + printf("unable to set comport dcb settings\n"); + CloseHandle(Cport[comport_number]); + return(1); + } + + if(flowctrl) + { + port_settings.fOutxCtsFlow = TRUE; + port_settings.fRtsControl = RTS_CONTROL_HANDSHAKE; + } + + if(!SetCommState(Cport[comport_number], &port_settings)) + { + printf("unable to set comport cfg settings\n"); + CloseHandle(Cport[comport_number]); + return(1); + } + + COMMTIMEOUTS Cptimeouts; + + Cptimeouts.ReadIntervalTimeout = MAXDWORD; + Cptimeouts.ReadTotalTimeoutMultiplier = 0; + Cptimeouts.ReadTotalTimeoutConstant = 0; + Cptimeouts.WriteTotalTimeoutMultiplier = 0; + Cptimeouts.WriteTotalTimeoutConstant = 0; + + if(!SetCommTimeouts(Cport[comport_number], &Cptimeouts)) + { + printf("unable to set comport time-out settings\n"); + CloseHandle(Cport[comport_number]); + return(1); + } + + return(0); +} + + +int RS232_PollComport(int comport_number, unsigned char *buf, int size) +{ + int n; + +/* added the void pointer cast, otherwise gcc will complain about */ +/* "warning: dereferencing type-punned pointer will break strict aliasing rules" */ + + ReadFile(Cport[comport_number], buf, size, (LPDWORD)((void *)&n), NULL); + + return(n); +} + + +int RS232_SendByte(int comport_number, unsigned char byte) +{ + int n; + + WriteFile(Cport[comport_number], &byte, 1, (LPDWORD)((void *)&n), NULL); + + if(n<0) return(1); + + return(0); +} + + +int RS232_SendBuf(int comport_number, unsigned char *buf, int size) +{ + int n; + + if(WriteFile(Cport[comport_number], buf, size, (LPDWORD)((void *)&n), NULL)) + { + return(n); + } + + return(-1); +} + + +void RS232_CloseComport(int comport_number) +{ + CloseHandle(Cport[comport_number]); +} + +/* +http://msdn.microsoft.com/en-us/library/windows/desktop/aa363258%28v=vs.85%29.aspx +*/ + +int RS232_IsDCDEnabled(int comport_number) +{ + int status; + + GetCommModemStatus(Cport[comport_number], (LPDWORD)((void *)&status)); + + if(status&MS_RLSD_ON) return(1); + else return(0); +} + + +int RS232_IsRINGEnabled(int comport_number) +{ + int status; + + GetCommModemStatus(Cport[comport_number], (LPDWORD)((void *)&status)); + + if(status&MS_RING_ON) return(1); + else return(0); +} + + +int RS232_IsCTSEnabled(int comport_number) +{ + int status; + + GetCommModemStatus(Cport[comport_number], (LPDWORD)((void *)&status)); + + if(status&MS_CTS_ON) return(1); + else return(0); +} + + +int RS232_IsDSREnabled(int comport_number) +{ + int status; + + GetCommModemStatus(Cport[comport_number], (LPDWORD)((void *)&status)); + + if(status&MS_DSR_ON) return(1); + else return(0); +} + + +void RS232_enableDTR(int comport_number) +{ + EscapeCommFunction(Cport[comport_number], SETDTR); +} + + +void RS232_disableDTR(int comport_number) +{ + EscapeCommFunction(Cport[comport_number], CLRDTR); +} + + +void RS232_enableRTS(int comport_number) +{ + EscapeCommFunction(Cport[comport_number], SETRTS); +} + + +void RS232_disableRTS(int comport_number) +{ + EscapeCommFunction(Cport[comport_number], CLRRTS); +} + +/* +https://msdn.microsoft.com/en-us/library/windows/desktop/aa363428%28v=vs.85%29.aspx +*/ + +void RS232_flushRX(int comport_number) +{ + PurgeComm(Cport[comport_number], PURGE_RXCLEAR | PURGE_RXABORT); +} + + +void RS232_flushTX(int comport_number) +{ + PurgeComm(Cport[comport_number], PURGE_TXCLEAR | PURGE_TXABORT); +} + + +void RS232_flushRXTX(int comport_number) +{ + PurgeComm(Cport[comport_number], PURGE_RXCLEAR | PURGE_RXABORT); + PurgeComm(Cport[comport_number], PURGE_TXCLEAR | PURGE_TXABORT); +} + + +#endif + + +void RS232_cputs(int comport_number, const char *text) /* sends a string to serial port */ +{ + while(*text != 0) RS232_SendByte(comport_number, *(text++)); +} + + +/* return index in comports matching to device name or -1 if not found */ +int RS232_GetPortnr(const char *devname) +{ + int i; + + char str[32]; + +#if defined(__linux__) || defined(__FreeBSD__) /* Linux & FreeBSD */ + strcpy(str, "/dev/"); +#else /* windows */ + strcpy(str, "\\\\.\\"); +#endif + strncat(str, devname, 16); + str[31] = 0; + + for(i=0; i<RS232_PORTNR; i++) + { + if(!strcmp(comports[i], str)) + { + return i; + } + } + + return -1; /* device not found */ +} + + + + + + + + + + + diff --git a/src/lib/rs232/rs232.h b/src/lib/rs232/rs232.h new file mode 100644 index 0000000..73a2040 --- /dev/null +++ b/src/lib/rs232/rs232.h @@ -0,0 +1,88 @@ +/* +*************************************************************************** +* +* Author: Teunis van Beelen +* +* Copyright (C) 2005 - 2019 Teunis van Beelen +* +* Email: teuniz@protonmail.com +* +*************************************************************************** +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +*************************************************************************** +*/ + +/* Last revision: May 31, 2019 */ + +/* For more info and how to use this library, visit: http://www.teuniz.net/RS-232/ */ + + +#ifndef rs232_INCLUDED +#define rs232_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <string.h> + + + +#if defined(__linux__) || defined(__FreeBSD__) + +#include <termios.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <limits.h> +#include <sys/file.h> +#include <errno.h> + +#else + +#include <windows.h> + +#endif + +int RS232_OpenComport(int, int, const char *, int); +int RS232_PollComport(int, unsigned char *, int); +int RS232_SendByte(int, unsigned char); +int RS232_SendBuf(int, unsigned char *, int); +void RS232_CloseComport(int); +void RS232_cputs(int, const char *); +int RS232_IsDCDEnabled(int); +int RS232_IsRINGEnabled(int); +int RS232_IsCTSEnabled(int); +int RS232_IsDSREnabled(int); +void RS232_enableDTR(int); +void RS232_disableDTR(int); +void RS232_enableRTS(int); +void RS232_disableRTS(int); +void RS232_flushRX(int); +void RS232_flushTX(int); +void RS232_flushRXTX(int); +int RS232_GetPortnr(const char *); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif + + |