diff options
author | Pavel Vymetálek <pavel@vym.cz> | 2019-02-07 17:05:56 +0100 |
---|---|---|
committer | Pavel Vymetálek <pavel@vym.cz> | 2019-02-07 17:05:56 +0100 |
commit | aee21c54320a5e85153314e8f4efdb7bea67e762 (patch) | |
tree | 0d717b1336035249a216203ef99271cf82728b8c | |
download | sercp-pc-aee21c54320a5e85153314e8f4efdb7bea67e762.tar.gz |
První commit: vychází se z programu taptoser
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | sercp.c | 786 |
2 files changed, 794 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ffe0501 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +PROJECT=sercp +all: + gcc $(PROJECT).c -o $(PROJECT) -Wall -pedantic -MP -MD -std=gnu11 -Werror=format-security -O2 +debug: + gcc $(PROJECT).c -o $(PROJECT) -Wall -pedantic -MP -MD -std=gnu11 -Werror=format-security -g -O0 + +clean: + rm -f $(PROJECT) $(PROJECT).d $(PROJECT).o @@ -0,0 +1,786 @@ +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <stdint.h> +#include <getopt.h> +#include <termios.h> +#include <error.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/signal.h> +#include <fcntl.h> +#include <poll.h> + +#define false 0 +#define FALSE 0 +#define true 1 +#define TRUE 1 + + +// SERIAL +char MODEMDEVICE[64]; +FILE *tapout_fd = NULL; +int is_outfile = 0; +int baud_rate = 0; +int wait_us = 200; +int wait_ms = 800; +#define FILENAME_LENGTH 400 +char output_dump_file[FILENAME_LENGTH]; +char tap_file[FILENAME_LENGTH]; +unsigned char in_buff[65538]; +unsigned char *p_buff; +unsigned int is_continue = 1; +unsigned int is_binary = 0; +struct pollfd spolfd_serial[1]; // pole descriptoru pro poll + +static int inp_indx = 0; +int serial_fd; +size_t out_indx; +struct sigaction saterm; /* definition of signal action */ + +float width; // width of terminal +long pos = 0; +int scp = 0; +int is_scp_read = 0; + +typedef struct { + uint16_t block_len; + uint8_t block_xor; + uint8_t block_sum; +} __attribute__((packed)) fi_sum; + +typedef struct { + uint16_t length; // delka dat ve fileinfo + uint8_t h_xor; // xor bajtu fileinfa od fi_numblocks + uint8_t h_sum; // sum bajtu fileinfa od fi_numblocks + uint8_t fi_numblocks; // pocet bloku + uint8_t fi_name[64]; // jmeno souboru - prozatim musi byt ve fromatu 8.3 - kvuli esxdosu + uint8_t fi_date[8]; // nepouzito + uint8_t fi_time[8]; // nepouzito + fi_sum fi_blocks[256]; // delky a soucty bloku +} __attribute__((packed)) FILEINFO; + +FILEINFO fileinfo; + + +void usage(void) { + printf ("Tap file over serial port uploader/downloader. (c)2012-2015 Pavel Vymetálek <pavel@vym.cz>\n"); + printf ("Based on utility tapheader: http://zeroteam.sk/tapheader.html (c)2012 Michal Jurica <mike@zeroteam.sk>\n"); + printf ("Usage:\ntaptoser [-v] [-h] [-o filename.tap] [-b|--baud baud_rate] -d /dev/serial tap_file\n"); + printf ("\t-v, --version\tShow version info\n"); + printf ("\t-h, --help\tShow this text\n"); + printf ("\t-d, --device\tCommunication device\n"); + printf ("\t-w, --wait\tWaiting in microseconds between transmitted bytes. Default is -w 200us\n"); + printf ("\t-b, --baud\tSet the communication speed. 4800Bd, 9600Bd, 19200Bd and 57600Bd (default) are supported\n"); + printf ("\t-B, --binary\tBinary output - received tap from ZX Spectrum will save without all tap's specific mishmash\n"); + printf ("\t-o, --outfile\tOutput file. Usualy *.tap or *.bin with in --binary mode\n"); + printf ("SCP mode -----\n"); + printf ("\t-s, --scp\tSCP mode - sent files with fileinfo 1109bytes\n"); + printf ("\t-r, --read\tread file\n"); + printf ("\t-w, --wait\tWaiting in milliseconds between transmitted blocks. Default is -w 800 milliseconds\n"); +} + +void Set_DTR(unsigned short level) { + int status; + ioctl(serial_fd, TIOCMGET, &status); + if (level) { + status |= TIOCM_DTR; + } else { + status &= ~TIOCM_DTR; + } + ioctl(serial_fd, TIOCMSET, &status); +} + +void TestCts(void) { + int status; + do { + ioctl(serial_fd, TIOCMGET, &status); + if (status & 0x20) break; + usleep (100); + if (is_continue == 0) return; + // printf ("status: %X\n",status); + } while (1); +} + + +void TestArgs (int argc, char *argv[]) +{ + int c; + while (1) { + int option_index = 0; + static struct option long_options[] = { + {"outfile", required_argument, NULL, 'o'}, + {"device", required_argument, NULL, 'd'}, + {"baud", required_argument, NULL, 'b'}, + {"wait", required_argument, NULL, 'w'}, + {"scp", no_argument, NULL, 's'}, + {"read", no_argument, NULL, 'r'}, + {"binary", no_argument, NULL, 'B'}, + {"version", no_argument, NULL, 'v'}, + {"help", no_argument, NULL, 'h'}, + {0, 0, 0, 0} + }; + c = getopt_long (argc, argv, "o:d:b:w:srBvh", long_options, &option_index); + if (c == -1) { + // konec parametru + break; + } + switch (c) { + case 'h': + usage(); + exit(1); + break; + case 'b': + baud_rate = atoi(optarg); + break; + case 'w': + wait_us = atoi(optarg); + wait_ms = atoi(optarg); + break; + case 's': + printf ("Serial CP mode is activated\n"); + scp = 1; + break; + case 'r': + printf ("scp read...\n"); + is_scp_read = 1; + break; + case 'd': + strncpy(MODEMDEVICE, optarg, strlen(optarg)); +// printf ("Serial port: %s\n", MODEMDEVICE); + break; + case 'o': + strncpy (output_dump_file, optarg, strlen(optarg)); + is_outfile = 1; + break; + case 'B': + printf ("Running in binary output mode\n"); + is_binary = 1; + break; + case 'v': + printf ("Version 0.9.1 2015-07-22\n"); + exit(1); + break; + default: + break; + } + } + if (optind < argc) { + while (optind < argc){ + strncpy (&tap_file[0], argv[optind++], 63); // input tap file name - without option switch + } + } +} + + +// from tapheader utility +unsigned int h_len; + +unsigned int getword(unsigned char* data) { + return *data + 256 * (*(data + 1)); +} + +void tooshort(FILE *fd) { + printf("Input file too short.\n\n"); + fclose(fd); + exit(2); +} + +// decode header1 +void decode(unsigned char *header) { + char name[11]; + unsigned int n; + printf("\n"); + strncpy(name, (char*)(header+2), 10); + name[10] = '\0'; + printf("Filename: %12s \n", name); + printf("Flag: %4u ", (unsigned int)*header); + n = getword(header+14); + h_len = getword(header+12); + + switch(*(header+1)) { + case '\0': + printf("Type: 0 => program\nProgram length: %6u bytes ", h_len); + if (n < 32768) printf("Runs from line %5u\t", n); + printf("Length without variables: %5u bytes ", getword(header+16)); + break; + case '\1': + printf("Type: 1 => number array\tLength: %6u bytes", h_len); + break; + case '\2': + printf("Type: 2 => character array\tLength: %6u bytes", h_len); + break; + case '\3': + if (n == 16384 && h_len == 6912) + printf("Type: 3 => screen image\n"); + else + printf("Type: 3 => bytes " + "Start address: %5u\t" + "Length: %6u bytes\t3rd param: %4u", + n, h_len, getword(header+16)); + break; + } + printf("\n"); +} + +void signal_handler_sigterm (int status) { + // CTRL+C pressed + is_continue = 0; // do not continue +} + +int GetTerminalWidth(void) { + struct winsize termsize; + ioctl (STDOUT_FILENO, TIOCGWINSZ, &termsize); + return (termsize.ws_col); +} + +#define PROGRESS_PERCENT 0 +#define PROGRESS_COMPLETTE 1 +#define PROGRESS_ERROR_CSUM 2 + +void DoProgress(size_t pos, size_t max, unsigned char csum_ok) { + width = GetTerminalWidth(); + float percent, p, m; + int imax = width - 40; + int ipercent; + int px; + char progress_char; + p = pos; + m = max; + percent = 100 / m * p; + ipercent = percent / 100 * imax; + if (is_binary) progress_char = '#'; + else progress_char = '='; + printf ("Proceed bytes: %6d/%6d [", (int) pos, (int)max); + for (px = 0; px < imax; px++) { + if (px < ipercent) printf ("%c", progress_char); + else printf (" "); + } + if (csum_ok == 0) { + printf ("] %3d %%\r", (int)percent); + } else if (csum_ok == 1) { + printf ("] OK \r"); + } else { + printf ("] ERR \r"); + } + fflush (stdout); +} + +#define HEADER_RAW_LEN 21 + +void RecvTap() { + unsigned int err; + size_t len; + int result; + size_t block_pos = 0, last_block_pos = 0; + size_t block_len = 10000; + size_t tap_pos = 0; + unsigned char xor_csum, xor_csum_ok; + unsigned char *p_write; + unsigned char block_type; // typ bloku 255 data 0 - hlavicka + unsigned char recv_status = 0; // 0 - zacatek, 1 - hlavicka nactena, 2 - blok se nacita, 3- header less + tapout_fd = fopen (output_dump_file, "a"); + if (tapout_fd == NULL) { + err = errno; + error (1, err, "can't open output file"); + } + printf("Output file is: %s\n", output_dump_file); + p_buff = in_buff; + p_write = in_buff; + while (is_continue) { + result = poll (spolfd_serial, 1, 200); // 200ms timeout + if (result == 0) { + // nic neprislo + continue; + } + if (spolfd_serial[0].revents & POLLIN) { + len = read (serial_fd, p_buff, 256); + block_pos += len; + p_buff += len; + if (is_binary == 0) { + // ulozeni dat ze seriaku jako tap file + while (len) { + fputc(*p_write, tapout_fd); + p_write++; + len--; + } + } + if (block_pos != last_block_pos && recv_status >= 2) { + last_block_pos = block_pos; + DoProgress(block_pos, block_len+2, PROGRESS_PERCENT); + } + if (block_pos >= HEADER_RAW_LEN && recv_status == 0) { + recv_status = 1; // hlavicka nactena + block_len = getword(in_buff); + block_type = *(in_buff + 2); + if (block_type == 0) { + // Hlavicka komplet + decode (in_buff + 2); + block_len = 0; + block_pos = 0; + xor_csum = 0; + recv_status = 0; + p_buff = in_buff; + p_write = in_buff; + } else if (block_type == 255) { + // data block + printf ("Data block len: %6zu\n", block_len-2); + recv_status = 3; + } + continue; + } + if (block_pos > HEADER_RAW_LEN + 3 && recv_status == 1) { + // nactena delka dalsiho bloku + recv_status = 2; + block_len = getword(in_buff + HEADER_RAW_LEN); + block_type = *(in_buff + HEADER_RAW_LEN + 2); + printf ("Block len: %zu Block type: %d\n", block_len, block_type); + continue; + } + if (block_len + 2 == block_pos && recv_status > 2) { + // Blok komplet nacten cekej novy + block_len = getword(in_buff); + block_type = *(in_buff + 2); + for (tap_pos = 0; tap_pos < block_len -1; tap_pos++) { + xor_csum ^= *(in_buff + 2 + tap_pos); + } + xor_csum_ok = *(in_buff + 2 + block_len - 1); + if (xor_csum == xor_csum_ok) { + DoProgress(block_pos, block_len+2, PROGRESS_COMPLETTE); // vypis jeste OK + if (is_binary == 1) { + // binarni vystup do souboru + for (tap_pos = 0; tap_pos < block_len - 2; tap_pos++){ + fputc(*(in_buff + 3 + tap_pos), tapout_fd); // uloz do souboru + } + DoProgress(tap_pos, block_len - 2, PROGRESS_COMPLETTE); + } +// printf ("Checksum OK\n"); + } else { + DoProgress(block_pos, block_len+2, PROGRESS_ERROR_CSUM); // vypis error CSUM + } + block_len = 0; + block_pos = 0; + xor_csum = 0; + recv_status = 0; + p_buff = in_buff; + p_write = in_buff; + continue; + } + } + } + fclose (tapout_fd); + printf ("\n\nulozeno...\n"); +} + +void SendByte(unsigned char *p_dato) { + TestCts(); + write (serial_fd, p_dato, 1); +// tcdrain(serial_fd); // better solution, but usleep at the next line is + usleep (wait_us); // faster solution, TODO change sleep time according to serial communication speed 200us is for 57600Bd +} + +void SendTap() { + FILE *tap_fd; + unsigned int err, no, len; + struct stat st; + unsigned char header[19]; + + no = stat(tap_file, &st); + if (no != 0) { + err = errno; + error(1, err, "can't stat input file"); + } + + tap_fd = fopen(tap_file, "r"); + if (tap_fd == NULL) { + err = errno; + error(1, err, "can't open input file"); + } + while (pos < st.st_size) { + if (is_continue == 0) break; + pos += no = fread(header, 1, 2, tap_fd); + if (no != 2) + tooshort(tap_fd); + for (out_indx = 0; out_indx < 2; out_indx++) { + SendByte(&header[out_indx]); + } + no = getword(header); + if (no == 19) /* HEADER */ + { + pos += no = fread(header, 1, 19, tap_fd); + if (no != 19) + tooshort(tap_fd); +// printf ("Header len: %d\n", no); + decode(header); + for (out_indx = 0; out_indx < 19; out_indx++) { + SendByte(&header[out_indx]); + } + } else { + if (h_len != no - 2) { /* zobrazuj iba bloky bez hl. */ + len = no; + printf ("NO datablock without header: %d\n", no); + printf("Type: datablock\nLength: %u\n", len - 2); + pos += no = fread(header, 1, 1, tap_fd); + SendByte(header); + DoProgress(1, no, PROGRESS_PERCENT); + if (no != 1) tooshort(tap_fd); + printf("Flag: %u\n\n", (int)*header); + len--; + } else { + len = no; + } + pos += len; + for (out_indx = 0; out_indx < len; out_indx++) { + fread(header, 1, 1, tap_fd); + SendByte(header); + DoProgress(out_indx+1, len, PROGRESS_PERCENT); + if (is_continue == 0) break; + } + printf ("\n"); + usleep (800000); + } + } + fclose(tap_fd); +} + + +int CheckFileInfo(FILEINFO* p_fi) { + unsigned char *p_fiinfo = (unsigned char*)p_fi; + uint16_t fi_len; + uint8_t fi_xor = 0; + uint8_t fi_sum = 0; + fi_len = p_fi->length; + p_fiinfo += 4; // suma se bude pocitat od offsetu 4 + for (uint16_t indx = 0; indx < (fi_len-4); indx++) { + fi_xor ^= *p_fiinfo; + fi_sum += *p_fiinfo; + p_fiinfo++; + } + if (fi_xor == p_fi->h_xor && fi_sum == p_fi->h_sum) { + return 0; + } + return -1; +} + +void CountFileInfoChecksum(FILEINFO* p_fi) { + unsigned char *p_fiinfo = (unsigned char*)p_fi; + uint16_t fi_len; + uint8_t fi_xor = 0; + uint8_t fi_sum = 0; + fi_len = p_fi->length; + p_fiinfo += 4; // suma se bude pocitat od offsetu 4 + for (uint16_t indx = 0; indx < (fi_len-4); indx++) { + fi_xor ^= *p_fiinfo; + fi_sum += *p_fiinfo; + p_fiinfo++; + } + p_fi->h_xor = fi_xor; + p_fi->h_sum = fi_sum; +} + +int CheckSumBlock(FILEINFO* p_fi, uint8_t block_indx, uint8_t *p_buffer) { + uint16_t block_len; + uint8_t b_xor = 0; + uint8_t b_sum = 0; + uint8_t block_xor; + uint8_t block_sum; + block_len = p_fi->fi_blocks[block_indx].block_len; + block_sum = p_fi->fi_blocks[block_indx].block_sum; + block_xor = p_fi->fi_blocks[block_indx].block_xor; + for (uint16_t indx = 0; indx < block_len; indx++) { + b_xor ^= *p_buffer; + b_sum += *p_buffer; + p_buffer++; + } + if (b_xor == block_xor && b_sum == block_sum) { + return 0; // vrat se, je to v poradku + } + return -1; // vrat se s chybou bloku +} + +void CountSumBlock(FILEINFO* p_fi, uint8_t block_indx, uint8_t *p_buffer, uint16_t block_len) { + uint8_t block_xor = 0; + uint8_t block_sum = 0; + for (uint16_t indx = 0; indx < block_len; indx++) { + block_xor ^= *p_buffer; + block_sum += *p_buffer; + p_buffer++; + } + p_fi->fi_blocks[block_indx].block_len = block_len; + p_fi->fi_blocks[block_indx].block_sum = block_sum; + p_fi->fi_blocks[block_indx].block_xor = block_xor; +} + + +unsigned char buff[32768]; + +uint32_t GetOverallLen(FILEINFO *p_fi) { + uint32_t overall_len = 0; + uint8_t block_num = p_fi->fi_numblocks; + for (uint8_t indx = 0; indx < block_num; indx++) { + overall_len += p_fi->fi_blocks[indx].block_len; + } + return overall_len; +} + +void RecvSCP(void) { + int recv_phase = 0; // 0 - fileinfo, 1 - blok 16kiB, 2 - posledni blok + uint8_t block_index = 0; + int result; + uint16_t len; + uint16_t length = 0; + uint16_t expected_len = 0; +// uint8_t expected_xor; +// uint8_t expected_sum; + uint32_t overall_length = 0; // celkova delka souboru + uint32_t recv_length = 0; // zatim prijatych dat ze souboru + int err; + + FILEINFO *p_fileinfo = &fileinfo; + unsigned char *p_buff = buff; + tapout_fd = NULL; + + memset (p_fileinfo, 0, sizeof(fileinfo)); + while (is_continue) { + result = poll (spolfd_serial, 1, 200); // 200ms timeout + if (result == 0) { + // nic neprislo + continue; + } + switch (recv_phase) { + case 0: + // prijem fileinfo + if (spolfd_serial[0].revents & POLLIN) { + len = read (serial_fd, p_buff, sizeof(fileinfo)); + p_buff += len; + length += len; + if (length == sizeof(fileinfo)) { + memcpy((unsigned char*) p_fileinfo, buff, sizeof(fileinfo)); + if (CheckFileInfo(p_fileinfo) == 0) { + printf("Prijato fileinfo\n"); + overall_length = GetOverallLen(p_fileinfo); + printf("Nazev souboru: \"%s\" pocet bloku:%d, delka souboru: %u\n", p_fileinfo->fi_name, p_fileinfo->fi_numblocks, overall_length); + recv_phase++; // priste se uz prijimaji bloky + block_index = 0; // zacina se prvnim blokem + p_buff = buff; // buffer na zacatek + length = 0; + expected_len = p_fileinfo->fi_blocks[block_index].block_len; + + + tapout_fd = fopen ((char*)p_fileinfo->fi_name, "w"); + if (tapout_fd == NULL) { + err = errno; + error (1, err, "can't open output file"); + } +// expected_xor = p_fileinfo->fi_blocks[block_index].block_xor; +// expected_sum = p_fileinfo->fi_blocks[block_index].block_sum; + } else { + printf("Fileinfo neni v cajku. Koncim...\n"); + break; + } + break; + } else if (length > sizeof(fileinfo)){ + len = read (serial_fd, p_buff, sizeof(fileinfo)); + printf("Nejaky bordel. Koncim...\n"); + break; + } + } + break; + case 1: + // prijem datoveho bloku - max. delka 16kiB + if (spolfd_serial[0].revents & POLLIN) { + len = read (serial_fd, p_buff, expected_len); + p_buff += len; + expected_len -= len; + length += len; + recv_length += len; + DoProgress(recv_length, overall_length, PROGRESS_PERCENT); + if (length == p_fileinfo->fi_blocks[block_index].block_len) { + // prijaty prvni block +// printf("Prijaty blok c.%d delky: %d\n", block_index, length); + if (CheckSumBlock(p_fileinfo, block_index, buff) == 0) { + // blok je v cajku - zapsat do souboru + if (tapout_fd) fwrite(buff, length, 1, tapout_fd); + } + length = 0; + p_buff = buff; + block_index++; + expected_len = p_fileinfo->fi_blocks[block_index].block_len; + } + if (expected_len == 0 || block_index == 255) { + printf ("\nKonec prenosu\n"); + recv_phase++; + is_continue = 0; + break; + } + } else if (length > 16384) { + len = read (serial_fd, p_buff, 16384); + printf("Nejaky bordel. Koncim...\n"); + break; + } + } + } + if (tapout_fd) fclose (tapout_fd); + printf ("\n\nulozeno...\n"); +} + +void SendSCP(void) { + FILE *tap_fd; + unsigned int err, no, len; + struct stat st; + FILEINFO *p_fileinfo = &fileinfo; + unsigned char *p_buff = buff; + uint32_t file_len; + uint8_t num_blocks = 0; + ssize_t odeslano; + uint32_t len_sent; + uint16_t sent_size; + uint32_t overall_sent; + + + no = stat(tap_file, &st); + if (no != 0) { + err = errno; + error(1, err, "can't stat input file"); + } + + tap_fd = fopen(tap_file, "r"); + if (tap_fd == NULL) { + err = errno; + error(1, err, "can't open input file"); + } + printf ("Soubor %s delky: %ld\n", tap_file, st.st_size); + memset (p_fileinfo, 0, sizeof(fileinfo)); // smazat fileinfo + + memcpy(p_fileinfo->fi_name, tap_file, strlen(tap_file)); + file_len = (uint32_t) st.st_size; + while (file_len) { + len = fread(buff, 1, 16384, tap_fd); // precti 16kiB dat + CountSumBlock(p_fileinfo, num_blocks, buff, len); +// printf ("Blok c. %d, delka: %d\n", num_blocks, len); + file_len -= len; + num_blocks++; + } + p_fileinfo->fi_numblocks = num_blocks; + p_fileinfo->length = num_blocks*4 + 85; + CountFileInfoChecksum(p_fileinfo); + odeslano = write (serial_fd, (void*)p_fileinfo, sizeof(fileinfo)); + tcdrain(serial_fd); + printf("Fileinfo sent...\n"); + // TODO Cekat pauzu mezi bloky + usleep (wait_ms * 1000); + + rewind(tap_fd); // prenaseny soubor na zacatek + file_len = (uint32_t) st.st_size; + overall_sent = 0; + while (file_len && is_continue) { + len = fread(buff, 1, 16384, tap_fd); // precti 16kiB dat + p_buff = buff; + sent_size = 256; + len_sent = len; + while (len_sent && is_continue) { + odeslano = write (serial_fd, (void*)p_buff, sent_size); + tcdrain(serial_fd); + p_buff += odeslano; + overall_sent += odeslano; + len_sent -= odeslano; + if (len_sent < 256) { + sent_size = len_sent; + } + DoProgress(overall_sent, st.st_size, PROGRESS_PERCENT); + } + usleep (wait_ms * 1000); + file_len -= len; + } + printf("\nFile sent...\n"); + fclose(tap_fd); +} + +int main(int argc, char** argv, char** env) +{ + // osetreni breaku ^C + saterm.sa_handler = signal_handler_sigterm; + saterm.sa_flags = 0; + sigaction (SIGINT, &saterm, NULL); + width = GetTerminalWidth(); + + // nastaveni serioveho portu + struct termios oldtio, newtio; + inp_indx = 0; + if (argc < 3) { + printf("You must specify the Serial device and file\n"); + usage(); + exit(1); + } + TestArgs (argc, argv); + /* open the device to be non-blocking (read will return immediatly) */ + serial_fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK); + if (serial_fd < 0) { + perror(MODEMDEVICE); + return(-1); + } + tcgetattr(serial_fd, &oldtio); /* save current port settings */ + switch (baud_rate){ + default: + baud_rate = 57600; // default speed + newtio.c_cflag = B57600 | CS8 | CLOCAL | CREAD | CSTOPB;// | CRTSCTS; + break; + case 115200: + newtio.c_cflag = B115200 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS; + break; + case 57600: + newtio.c_cflag = B57600 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS; + break; + case 38400: + newtio.c_cflag = B38400 | CS8 | CLOCAL | CREAD | CRTSCTS; // dva stopbity jsou nastaveny vsude, ale tady ne + break; + case 19200: + newtio.c_cflag = B19200 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS; + break; + case 9600: + newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS; + break; + case 4800: + newtio.c_cflag = B4800 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS; + break; + case 2400: + newtio.c_cflag = B2400 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS; + break; + case 1200: + newtio.c_cflag = B1200 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS; + break; + } + newtio.c_cflag |= CRTSCTS; + printf ("Serial device: %s, communication speed is: %d Bd\n", MODEMDEVICE, baud_rate); +// newtio.c_iflag &= ~(IXON | IXOFF | IXANY); // vypne XON/XOFF + newtio.c_iflag = 0; //IGNPAR | IXOFF; + newtio.c_oflag = 0; +// newtio.c_oflag &= ~OPOST; + newtio.c_lflag = 0; //NOFLSH; + newtio.c_cc[VMIN] = 0; + newtio.c_cc[VTIME] = 10; + tcsetattr(serial_fd, TCSANOW, &newtio); + tcflush(serial_fd, TCIOFLUSH); + spolfd_serial[0].fd = serial_fd; // nastaveni hlidaneho descriptoru + spolfd_serial[0].events = POLLIN; // hlidaji se data na vstupu + + if (scp) { + // serial copy activated + if (is_scp_read) { + RecvSCP(); + } else { + SendSCP(); + } + } else { + Set_DTR(true); // PC can read data from speccy everytime + if (is_outfile) { + RecvTap(); // cteni tap souboru ze seriaku a zapis na disk pocitace + } else { + SendTap(); // poslat na seriak tap soubor do spectra + } + } + close (serial_fd); + return 0; +} |