Commit ad27d165 authored by Christian Eichler's avatar Christian Eichler
Browse files

Merge branch 'dev' into 'master'

dev -> master

See merge request gene/xmc4500-relax-linux!1
parents 14b8e467 22d5c131
.PHONY: flash/ids_% flash/bch_% reset_% .PHONY: reset_%
.SECONDARY: $(bin/*.axf)
#### Setup #### #### Setup ####
XMC = $(shell pwd)/XMC XMC = $(shell pwd)/XMC
...@@ -16,19 +17,19 @@ LIBS = $(CMSIS)/Lib/GCC/libarm_cortexM4lf_math.a ...@@ -16,19 +17,19 @@ LIBS = $(CMSIS)/Lib/GCC/libarm_cortexM4lf_math.a
LINKER_FILE = $(CMSIS)/Infineon/$(UC)_series/Source/GCC/XMC4500x1024.ld LINKER_FILE = $(CMSIS)/Infineon/$(UC)_series/Source/GCC/XMC4500x1024.ld
CMSIS_SRC += $(CMSIS)/Infineon/$(UC)_series/Source/System_$(UC).c CMSIS_SRC += $(CMSIS)/Infineon/$(UC)_series/Source/System_$(UC).c
JLINK = JLinkExe
SYSCC = $(TOOLCHAIN)-gcc SYSCC = $(TOOLCHAIN)-gcc
CC = patmos-clang CC = patmos-clang
CP = $(TOOLCHAIN)-objcopy CP = $(TOOLCHAIN)-objcopy
OD = $(TOOLCHAIN)-objdump OD = $(TOOLCHAIN)-objdump
GDB = $(TOOLCHAIN)-gdb GDB = $(TOOLCHAIN)-gdb
#STACK_SIZE?=2048
STACK_SIZE?=16384 STACK_SIZE?=16384
JLINK = JLinkExe
JLFLAGS = -device XMC4500-1024 -if SWD -speed 900 JLFLAGS = -device XMC4500-1024 -if SWD -speed 900
CFLAGS = -target armv6m--none-eabi -mcpu=cortex-m4 -mthumb -integrated-as -ccc-gcc-name arm-none-eabi-gcc CFLAGS = -mcpu=cortex-m4 -target armv7m-none-eabi -msoft-float
CFLAGS+= -integrated-as -ccc-gcc-name arm-none-eabi-gcc
CFLAGS+= -fno-builtin CFLAGS+= -fno-builtin
CFLAGS+= -Os -ffunction-sections -fdata-sections CFLAGS+= -Os -ffunction-sections -fdata-sections
CFLAGS+= -MD -std=c99 -Wall CFLAGS+= -MD -std=c99 -Wall
...@@ -36,6 +37,7 @@ CFLAGS+= -DUC_ID=$(UC_ID) -DARM_MATH_CM4 -DINTERRUPT_CONTROL_ENDPOINT ...@@ -36,6 +37,7 @@ CFLAGS+= -DUC_ID=$(UC_ID) -DARM_MATH_CM4 -DINTERRUPT_CONTROL_ENDPOINT
CFLAGS+= -DXMC4500_F100x1024 CFLAGS+= -DXMC4500_F100x1024
CFLAGS+= -I$(CMSIS)/Include -I$(CMSIS)/Infineon/$(UC)_series/Include CFLAGS+= -I$(CMSIS)/Include -I$(CMSIS)/Infineon/$(UC)_series/Include
CFLAGS+= -Ilib/LUFA -I$(XMC)/XMCLib/inc CFLAGS+= -Ilib/LUFA -I$(XMC)/XMCLib/inc
CFLAGS+= $(CFLAGS_GENE)
ASFLAGS = -target armv6m--none-eabi -mcpu=cortex-m4 -marm -mthumb ASFLAGS = -target armv6m--none-eabi -mcpu=cortex-m4 -marm -mthumb
ASFLAGS+= -O0 -ffunction-sections -fdata-sections ASFLAGS+= -O0 -ffunction-sections -fdata-sections
...@@ -60,7 +62,7 @@ OBJS += src/System_$(UC).o ...@@ -60,7 +62,7 @@ OBJS += src/System_$(UC).o
OBJS_MAIN = $(OBJS) $(SRC_MAIN:.c=.o) OBJS_MAIN = $(OBJS) $(SRC_MAIN:.c=.o)
#### Rules #### #### Rules ####
all: $(OBJS) bin/xmc.bin xmccomm all: $(OBJS)
src/System_$(UC).o: $(CMSIS_SRC) src/System_$(UC).o: $(CMSIS_SRC)
$(CC) -c $(CFLAGS) $< -o $@ $(CC) -c $(CFLAGS) $< -o $@
...@@ -88,24 +90,10 @@ bin/ids_%.axf: $(OBJS) bin/startup_XMC4500.o bin/ids_%.o ...@@ -88,24 +90,10 @@ bin/ids_%.axf: $(OBJS) bin/startup_XMC4500.o bin/ids_%.o
%.bin: %.axf %.bin: %.axf
$(CP) $(CPFLAGS) $^ $@ $(CP) $(CPFLAGS) $^ $@
flash/ids_%: bin/ids_%.bin bin/system_%.axf: $(OBJS_MAIN) bin/startup_XMC4500.o %.o
echo "connect\n\
loadbin $< 0x8000000\n\
r\n\
g\n\
exit\n" | $(JLINK) $(JLFLAGS) -SelectEmuBySN $*
flash/bch_%: bin/xmc.bin
echo "connect\n\
loadbin bin/xmc.bin 0x8000000\n\
r\n\
g\n\
exit\n" | $(JLINK) $(JLFLAGS) -SelectEmuBySN $*
bin/xmc.axf: $(OBJS_MAIN) bin/startup_XMC4500.o gene.o
mkdir -p bin mkdir -p bin
@echo LD $< @echo LD $@
@$(CC) -T $(LINKER_FILE) $(LFLAGS) -o bin/xmc.axf $^ $(LIBS) @$(CC) -T $(LINKER_FILE) $(LFLAGS) -o $@ $^ $(LIBS)
reset_%: reset_%:
echo "connect\n\ echo "connect\n\
...@@ -124,8 +112,7 @@ fastgdb: ...@@ -124,8 +112,7 @@ fastgdb:
sleep 1 sleep 1
make gdb make gdb
xmccomm: xmccomm.c
gcc -std=c99 -g xmccomm.c -o xmccomm
clean: clean:
rm -f src/*.o src/*.d bin/* rm -f src/*.o src/*.d bin/*
print-% : ; @echo $* = $($*)
...@@ -59,6 +59,9 @@ The **bch** supports the following requests: ...@@ -59,6 +59,9 @@ The **bch** supports the following requests:
* `eic`: enable instruction cache * `eic`: enable instruction cache
* `bch`: run benchmark * `bch`: run benchmark
Building the **bch** system requires a prior execution of GenE to generate
the file containing the actual benchmark (`gene.o`).
Usage: Communicate with the System Usage: Communicate with the System
---------------------------------- ----------------------------------
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "timer.h" #include "timer.h"
#endif /* ifndef ID_SYSTEM */ #endif /* ifndef ID_SYSTEM */
#define IHANDLER __attribute__ ((naked)) #define IHANDLER
#define xstr(s) str(s) #define xstr(s) str(s)
#define str(s) #s #define str(s) #s
...@@ -22,25 +22,48 @@ ...@@ -22,25 +22,48 @@
#define SERIALSTR "<none>" #define SERIALSTR "<none>"
#endif #endif
#define VOID_ARG_TYPE 1
#define UINT32_ARG_TYPE 2
#ifndef BENCHMARK_MAIN
#if defined(BENCHMARK_ARG) || defined(BENCHMARK_INIT)
#error BENCHMARK_MAIN, BENCHMARK_ARG, BENCHMARK_INIT must be defined
#endif
#define BENCHMARK_MAIN gene_main
#define BENCHMARK_ARG uint32_t
#define ARG_TYPE UINT32_ARG_TYPE
#define BENCHMARK_INIT gene_init
#endif
// use void as default
#ifndef BENCHMARK_ARG
#define ARG_TYPE VOID_ARG_TYPE
#define BENCHMARK_ARG void
#endif
void BENCHMARK_MAIN(BENCHMARK_ARG);
void BENCHMARK_INIT(void);
extern int errno; extern int errno;
void _init() {} void _init() {}
void _sbrk() {}
/* Clock configuration */ /* Clock configuration */
XMC_SCU_CLOCK_CONFIG_t clock_config = XMC_SCU_CLOCK_CONFIG_t clock_config =
{ {
.syspll_config.p_div = 2, .syspll_config.p_div = 2,
.syspll_config.n_div = 80, .syspll_config.n_div = 80,
.syspll_config.k_div = 4, .syspll_config.k_div = 4,
.syspll_config.mode = XMC_SCU_CLOCK_SYSPLL_MODE_NORMAL, .syspll_config.mode = XMC_SCU_CLOCK_SYSPLL_MODE_NORMAL,
.syspll_config.clksrc = XMC_SCU_CLOCK_SYSPLLCLKSRC_OSCHP, .syspll_config.clksrc = XMC_SCU_CLOCK_SYSPLLCLKSRC_OSCHP,
.enable_oschp = true, .enable_oschp = true,
.calibration_mode = XMC_SCU_CLOCK_FOFI_CALIBRATION_MODE_FACTORY, .calibration_mode = XMC_SCU_CLOCK_FOFI_CALIBRATION_MODE_FACTORY,
.fsys_clksrc = XMC_SCU_CLOCK_SYSCLKSRC_PLL, .fsys_clksrc = XMC_SCU_CLOCK_SYSCLKSRC_PLL,
.fsys_clkdiv = 1, .fsys_clkdiv = 1,
.fcpu_clkdiv = 1, .fcpu_clkdiv = 1,
.fccu_clkdiv = 1, .fccu_clkdiv = 1,
.fperipheral_clkdiv = 1 .fperipheral_clkdiv = 1
}; };
...@@ -58,10 +81,7 @@ void SystemCoreClockSetup(void) ...@@ -58,10 +81,7 @@ void SystemCoreClockSetup(void)
SystemCoreClockUpdate(); SystemCoreClockUpdate();
} }
/*** Begin: Interrupt Handlers ***/
void gene_main(uint32_t);
void gene_init(void);
IHANDLER void PendSV_Handler() { P1_1_set(); while(1) {} } IHANDLER void PendSV_Handler() { P1_1_set(); while(1) {} }
IHANDLER void SysTick_Handler() { P1_1_set(); while(1) {} } IHANDLER void SysTick_Handler() { P1_1_set(); while(1) {} }
IHANDLER void SVC_Handler() { P1_1_set(); while(1) {} } IHANDLER void SVC_Handler() { P1_1_set(); while(1) {} }
...@@ -70,6 +90,8 @@ IHANDLER void NMI_Handler() { P1_1_set(); while(1) {} } ...@@ -70,6 +90,8 @@ IHANDLER void NMI_Handler() { P1_1_set(); while(1) {} }
IHANDLER void MemManage_Handler() { P1_1_set(); while(1) {} } IHANDLER void MemManage_Handler() { P1_1_set(); while(1) {} }
IHANDLER void UsageFault_Handler() { P1_1_set(); while(1) {} } IHANDLER void UsageFault_Handler() { P1_1_set(); while(1) {} }
IHANDLER void BusFault_Handler() { P1_1_set(); while(1) {} } IHANDLER void BusFault_Handler() { P1_1_set(); while(1) {} }
/*** End: Interrupt Handlers ***/
static void uint64_to_string(char *buf, uint64_t value) { static void uint64_to_string(char *buf, uint64_t value) {
if(0 == value) { if(0 == value) {
...@@ -85,62 +107,87 @@ static void uint64_to_string(char *buf, uint64_t value) { ...@@ -85,62 +107,87 @@ static void uint64_to_string(char *buf, uint64_t value) {
} }
} }
/*** Begin: USB helper functions ***/
static void usb_send(const char *str) {
CDC_Device_SendString(&VirtualSerial_CDC_Interface, str);
}
static void usb_send2(const char *str1, const char *str2) {
usb_send(str1);
usb_send(str2);
}
static void usb_send3(const char *str1, const char *str2, const char *str3) {
usb_send(str1);
usb_send(str2);
usb_send(str3);
}
static void usb_flush() { CDC_Device_Flush(&VirtualSerial_CDC_Interface); }
/*** End: USB helper functions ***/
#ifndef ID_SYSTEM #ifndef ID_SYSTEM
static void command_bch(char *arg) { static void command_bch(char *arg) {
errno = 0; errno = 0;
unsigned long long val = strtoull(arg, NULL, 10); unsigned long long val = strtoull(arg, NULL, 10);
if(0 != errno || val > (unsigned long long) UINT32_MAX) { if(0 != errno || val > (unsigned long long) UINT32_MAX) {
CDC_Device_SendString(&VirtualSerial_CDC_Interface, "e:ov\n"); usb_send("e:ov\n");
CDC_Device_Flush(&VirtualSerial_CDC_Interface); usb_flush();
return; return;
} }
CDC_Device_SendString(&VirtualSerial_CDC_Interface, "o:start\r"); usb_send("o:start\r");
CDC_Device_Flush(&VirtualSerial_CDC_Interface); usb_flush();
P1_0_toggle(); P1_0_toggle();
uint32_t old_basepri = __get_BASEPRI(); uint32_t old_basepri = __get_BASEPRI();
__set_BASEPRI(1 << (8 - __NVIC_PRIO_BITS)); __set_BASEPRI(1 << (8 - __NVIC_PRIO_BITS));
gene_init(); BENCHMARK_INIT();
// flush instruction cache prior to executing the benchmark to // flush instruction cache prior to executing the benchmark to
// ensure a "clean" system state // ensure a "clean" system state
XMC_PREFETCH_InvalidateInstructionBuffer(); XMC_PREFETCH_InvalidateInstructionBuffer();
timer_reset(); timer_reset();
P5_7_set();
timer_start(); timer_start();
gene_main(val); #if ARG_TYPE == VOID_ARG_TYPE
BENCHMARK_MAIN();
#else
BENCHMARK_MAIN(val);
#endif
timer_stop(); timer_stop();
P5_7_reset();
uint64_t cycles = timer_get(); uint64_t cycles = timer_get();
__set_BASEPRI(old_basepri); __set_BASEPRI(old_basepri);
P1_0_toggle(); P1_0_toggle();
CDC_Device_SendString(&VirtualSerial_CDC_Interface, "o:end ");
CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
char buf[64] = {0}; char buf[64] = {0};
uint64_to_string(buf, cycles); uint64_to_string(buf, cycles);
CDC_Device_SendString(&VirtualSerial_CDC_Interface, buf); usb_send3("o:end ", buf, "\n");
CDC_Device_SendString(&VirtualSerial_CDC_Interface, "\n"); usb_flush();
CDC_Device_Flush(&VirtualSerial_CDC_Interface);
CDC_Device_USBTask(&VirtualSerial_CDC_Interface); CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
} }
static void command_dic(char *arg) { static void command_dic(char *arg) {
XMC_PREFETCH_DisableInstructionBuffer(); XMC_PREFETCH_DisableInstructionBuffer();
CDC_Device_SendString(&VirtualSerial_CDC_Interface, "o\n"); usb_send("o\n");
CDC_Device_Flush(&VirtualSerial_CDC_Interface); usb_flush();
CDC_Device_USBTask(&VirtualSerial_CDC_Interface); CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
} }
static void command_eic(char *arg) { static void command_eic(char *arg) {
XMC_PREFETCH_EnableInstructionBuffer(); XMC_PREFETCH_EnableInstructionBuffer();
CDC_Device_SendString(&VirtualSerial_CDC_Interface, "o\n"); usb_send("o\n");
CDC_Device_Flush(&VirtualSerial_CDC_Interface); usb_flush();
CDC_Device_USBTask(&VirtualSerial_CDC_Interface); CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
} }
...@@ -159,53 +206,39 @@ static void command_inf(char *arg) { ...@@ -159,53 +206,39 @@ static void command_inf(char *arg) {
// send FREQUENCY // send FREQUENCY
char buf[128] = {0}; char buf[128] = {0};
uint64_to_string(buf, SystemCoreClock); uint64_to_string(buf, SystemCoreClock);
CDC_Device_SendString(&VirtualSerial_CDC_Interface, "o:freq "); usb_send3("o:freq ", buf, "\r");
CDC_Device_SendString(&VirtualSerial_CDC_Interface, buf);
CDC_Device_SendString(&VirtualSerial_CDC_Interface, "\r");
// send PFLASH // send PFLASH
{ {
char buf[128] = {0}; char buf[128] = {0};
uint64_to_string(buf, (FLASH0->FCON & (uint32_t)FLASH_FCON_WSPFLASH_Msk) >> FLASH_FCON_WSPFLASH_Pos); uint64_to_string(buf, (FLASH0->FCON & (uint32_t)FLASH_FCON_WSPFLASH_Msk) >> FLASH_FCON_WSPFLASH_Pos);
CDC_Device_SendString(&VirtualSerial_CDC_Interface, "o:wspflash "); usb_send3("o:wspflash ", buf, "\r");
CDC_Device_SendString(&VirtualSerial_CDC_Interface, buf);
CDC_Device_SendString(&VirtualSerial_CDC_Interface, "\r");
} }
// send DWT status // send DWT status
switch(DWT->CTRL & 0xFF000000) { switch(DWT->CTRL & 0xFF000000) {
case 0x40000000: CDC_Device_SendString(&VirtualSerial_CDC_Interface, "o:4wt\r"); break; case 0x40000000: usb_send("o:4wt\r"); break;
case 0x4F000000: CDC_Device_SendString(&VirtualSerial_CDC_Interface, "o:4w\r"); break; case 0x4F000000: usb_send("o:4w\r"); break;
case 0x10000000: CDC_Device_SendString(&VirtualSerial_CDC_Interface, "o:1wt\r"); break; case 0x10000000: usb_send("o:1wt\r"); break;
case 0x1F000000: CDC_Device_SendString(&VirtualSerial_CDC_Interface, "o:1w\r"); break; case 0x1F000000: usb_send("o:1w\r"); break;
case 0x00000000: CDC_Device_SendString(&VirtualSerial_CDC_Interface, "o:0\r"); break; case 0x00000000: usb_send("o:0\r"); break;
default: CDC_Device_SendString(&VirtualSerial_CDC_Interface, "e:v\r"); break; default: usb_send("e:v\r"); break;
} }
#ifndef ID_SYSTEM #ifndef ID_SYSTEM
if(timer_has_overflow_detection()) { usb_send(timer_has_overflow_detection() ? "o:ov e\r" : "o:ov d\r");
CDC_Device_SendString(&VirtualSerial_CDC_Interface, "o:ov e\r");
} else {
CDC_Device_SendString(&VirtualSerial_CDC_Interface, "o:ov d\r");
}
#endif /* ifndef ID_SYSTEM */ #endif /* ifndef ID_SYSTEM */
usb_send((PREF->PCON & PREF_PCON_IBYP_Msk) ? "o:ic d\n" : "o:ic e\n");
if(PREF->PCON & PREF_PCON_IBYP_Msk) { usb_flush();
CDC_Device_SendString(&VirtualSerial_CDC_Interface, "o:ic d\n");
} else {
CDC_Device_SendString(&VirtualSerial_CDC_Interface, "o:ic e\n");
}
CDC_Device_Flush(&VirtualSerial_CDC_Interface);
CDC_Device_USBTask(&VirtualSerial_CDC_Interface); CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
} }
void* __aeabi_memset(void *s, int c, size_t n){ void* __aeabi_memset(void *s, int c, size_t n) {
size_t i; for(size_t i = 0; i < n; i++) {
for (i = 0; i < n; i++) { ((char *)s)[i] = (char)c;
((char *)s)[i] = (char)c; }
} return s;
return s;
} }
int main(void) { int main(void) {
...@@ -216,12 +249,12 @@ int main(void) { ...@@ -216,12 +249,12 @@ int main(void) {
P1_1_set_mode(OUTPUT_PP_GP); P1_1_set_mode(OUTPUT_PP_GP);
P1_1_set_driver_strength(STRONG); P1_1_set_driver_strength(STRONG);
#define BUFFER_SIZE 32 P5_7_set_mode(OUTPUT_PP_GP);
P5_7_set_driver_strength(WEAK);
char buffer[BUFFER_SIZE + 1];
buffer[BUFFER_SIZE] = '\0';
#define BUFFER_SIZE 32
uint8_t pos = 0; uint8_t pos = 0;
char buffer[BUFFER_SIZE + 1] = {0};
// enable monitor debugging // enable monitor debugging
CoreDebug->DHCSR = 0xA05F << CoreDebug_DHCSR_DBGKEY_Pos; CoreDebug->DHCSR = 0xA05F << CoreDebug_DHCSR_DBGKEY_Pos;
...@@ -270,8 +303,8 @@ int main(void) { ...@@ -270,8 +303,8 @@ int main(void) {
#undef COMMAND #undef COMMAND
if(!handled) { if(!handled) {
CDC_Device_SendString(&VirtualSerial_CDC_Interface, "e:uc\n"); usb_send("e:uc\n");
CDC_Device_Flush(&VirtualSerial_CDC_Interface); usb_flush();
} }
pos = 0; pos = 0;
...@@ -283,8 +316,8 @@ int main(void) { ...@@ -283,8 +316,8 @@ int main(void) {
buffer[pos] = byte; buffer[pos] = byte;
++pos; ++pos;
} else { } else {
CDC_Device_SendString(&VirtualSerial_CDC_Interface, "e:OVERFLOW IN COMMAND BUFFER\n"); usb_send("e:ov\n");
CDC_Device_Flush(&VirtualSerial_CDC_Interface); usb_flush();
pos = 0; pos = 0;
} }
......
#define _POSIX_C_SOURCE 199309L
#define _XOPEN_SOURCE 500
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <stdint.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#define SHELL_ESC "\x1b"
#define streq(A,B) (!strcmp(A,B))
// stty -F /dev/ttyACM0 115200
static void print_ok() {
printf(SHELL_ESC"[;32;02m[ok] "SHELL_ESC"[m");
}
static void print_er() {
printf(SHELL_ESC"[;31;02m[ER] "SHELL_ESC"[m");
}
static void print_vb(char *msg) {
fprintf(stderr, SHELL_ESC"[;36;02m[vb] "SHELL_ESC"[m%s", msg);
}
static bool recv_response(FILE *fh, char *buf, size_t buf_size) {
int pos = 0;
while(pos < buf_size) {
int c = fgetc(fh);
if(EOF != c) {
if('\n' == c) {
buf[pos] = '\0';
return true;
} else if('\r' == c) {
buf[pos] = '\0';
return false;
} else {
buf[pos] = c;
++pos;
}
} else {
if(ferror(fh)) {
perror("fgetc(TTY)");
exit(EXIT_FAILURE);
} else {
fprintf(stderr, "Unexpected EOF\n");
exit(EXIT_FAILURE);
}
}
}
}
static int connect_tty(char *tty) {
bool exists = false;
unsigned retry = 0;
do {
print_vb("");
fprintf(stderr, "open('%s') try %u\n", tty, retry);
++retry;
struct stat sbuf;
int res = stat(tty, &sbuf);
exists = (0 == res);
if(!exists) {
usleep(500 * 1000);
}
} while(!exists && errno != EACCES && retry < 10);
int fd = open(tty, O_RDWR | O_NOCTTY);
if(-1 == fd) {
perror("open(TTY)");
if(EACCES == errno) {
fprintf(stderr, "Make sure current user `%s` is in group `dialout`\n", getlogin());
}
exit(EXIT_FAILURE);
} else {
print_vb(""); fprintf(stderr, "%s successfully opened\n", tty);
}
// setup control structure
struct termios toptions;
if(0 != tcgetattr(fd, &toptions)) { perror("tcgetattr"); }
if(0 != cfsetispeed(&toptions, B115200)) { perror("cfsetispeed"); }
if(0 != cfsetospeed(&toptions, B115200)) { perror("cfsetospeed"); }
toptions.c_cflag &= ~PARENB; // no parity bit
toptions.c_cflag &= ~CSTOPB; // no stop bits
toptions.c_cflag &= ~CSIZE; // char. size
toptions.c_cflag |= CS8; // 8 bits
/* enable receiver, ignore status lines */
toptions.c_cflag |= CREAD | CLOCAL;
/* disable input/output flow control, disable restart chars */
toptions.c_iflag &= ~(IXON | IXOFF | IXANY);
/* disable canonical input, disable echo,
disable visually erase chars,
disable terminal-generated signals */
toptions.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
toptions.c_oflag &= ~OPOST; // disable postprocessing