📄 serpardr.c
字号:
/* * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved. * * This software may be freely used, copied, modified, and distributed * provided that the above copyright notice is preserved in all copies of the * software. *//* -*-C-*- * * $Revision: 1.4 $ * $Date: 1999/01/28 03:50:16 $ * * * serpardv.c - Serial/Parallel Driver for Angel. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "crc.h"#include "devices.h"#include "buffers.h"#include "rxtx.h"#include "hostchan.h"#include "params.h"#include "logging.h"#include "hsys.h"#ifdef COMPILING_ON_WINDOWS# undef ERROR# undef IGNORE# include <windows.h># include "angeldll.h"# include "comb_api.h"#else# ifdef __hpux# define _TERMIOS_INCLUDED# include <sys/termio.h># undef _TERMIOS_INCLUDED# else# include <termios.h># endif# include "unixcomm.h"#endif#ifndef UNUSED# define UNUSED(x) (x = x) /* Silence compiler warnings */#endif#define MAXREADSIZE 512#define MAXWRITESIZE 512#define SERPAR_FC_SET ((1 << serial_XON) | (1 << serial_XOFF))#define SERPAR_CTL_SET ((1 << serial_STX) | (1 << serial_ETX) | \ (1 << serial_ESC))#define SERPAR_ESC_SET (SERPAR_FC_SET | SERPAR_CTL_SET)static const struct re_config config = { serial_STX, serial_ETX, serial_ESC, /* self-explanatory? */ SERPAR_FC_SET, /* set of flow-control characters */ SERPAR_ESC_SET, /* set of characters to be escaped */ NULL, /* serial_flow_control */ NULL, /* what to do with FC chars */ angel_DD_RxEng_BufferAlloc, NULL /* how to get a buffer */};static struct re_state rxstate;/* * structure used for manipulating transmit data */typedef struct TxState{ struct te_state state; unsigned int index; unsigned char writebuf[MAXWRITESIZE];} TxState;/* * The set of parameter options supported by the device */static unsigned int baud_options[] ={#ifdef __hpux 115200, 57600,#endif 38400, 19200, 9600};static ParameterList param_list[] ={ { AP_BAUD_RATE, sizeof(baud_options) / sizeof(unsigned int), baud_options }};static const ParameterOptions serpar_options ={ sizeof(param_list) / sizeof(ParameterList), param_list};/* * The default parameter config for the device */static Parameter param_default[] ={ { AP_BAUD_RATE, 9600 }};static const ParameterConfig serpar_defaults ={ sizeof(param_default)/sizeof(Parameter), param_default};/* * The user-modified options for the device */static unsigned int user_baud_options[sizeof(baud_options) / sizeof(unsigned int)];static ParameterList param_user_list[] ={ { AP_BAUD_RATE, sizeof(user_baud_options) / sizeof(unsigned), user_baud_options }};static ParameterOptions user_options ={ sizeof(param_user_list) / sizeof(ParameterList), param_user_list};static bool user_options_set;/* forward declarations */static int serpar_reset(void);static int serpar_set_params(const ParameterConfig *config);static int SerparMatch(const char *name, const char *arg);static void process_baud_rate(unsigned int target_baud_rate){ const ParameterList *full_list; ParameterList *user_list; /* create subset of full options */ full_list = Angel_FindParamList(&serpar_options, AP_BAUD_RATE); user_list = Angel_FindParamList(&user_options, AP_BAUD_RATE); if (full_list != NULL && user_list != NULL) { unsigned int i, j; unsigned int def_baud = 0; /* find lower or equal to */ for (i = 0; i < full_list->num_options; ++i) if (target_baud_rate >= full_list->option[i]) { /* copy remaining */ for (j = 0; j < (full_list->num_options - i); ++j) user_list->option[j] = full_list->option[i+j]; user_list->num_options = j; /* check this is not the default */ Angel_FindParam(AP_BAUD_RATE, &serpar_defaults, &def_baud); if ((j == 1) && (user_list->option[0] == def_baud)) {#ifdef DEBUG printf("user selected default\n");#endif } else { user_options_set = TRUE;#ifdef DEBUG printf("user options are: "); for (j = 0; j < user_list->num_options; ++j) printf("%u ", user_list->option[j]); printf("\n");#endif } break; /* out of i loop */ }#ifdef DEBUG if (i >= full_list->num_options) printf("couldn't match baud rate %u\n", target_baud_rate);#endif }#ifdef DEBUG else printf("failed to find lists\n");#endif}static int SerparOpen(const char *name, const char *arg){ char *sername = NULL; char *parname = NULL;#ifdef DEBUG printf("SerparOpen: name %s arg %s\n", name, arg ? arg : "<NULL>");#endif#ifdef COMPILING_ON_WINDOWS if (IsOpenSerial() || IsOpenParallel()) return -1;#else if (Unix_IsSerialInUse() || Unix_IsParallelInUse()) return -1;#endif#ifdef COMPILING_ON_WINDOWS if (SerparMatch(name, arg) == -1) return -1;#else Unix_IsValidParallelDevice(name,&sername,&parname);# ifdef DEBUG printf("translated %s to serial %s and parallel %s\n", name==0 ? "NULL" : name, sername==0 ? "NULL" : sername, parname==0 ? "NULL" : parname);# endif if (sername==NULL || parname==NULL) return -1;#endif user_options_set = FALSE; /* interpret and store the arguments */ if (arg != NULL) { unsigned int target_baud_rate; target_baud_rate = (unsigned int)strtoul(arg, NULL, 10); if (target_baud_rate > 0) {#ifdef DEBUG printf("user selected baud rate %u\n", target_baud_rate);#endif process_baud_rate(target_baud_rate); }#ifdef DEBUG else printf("could not understand baud rate %s\n", arg);#endif }#ifdef COMPILING_ON_WINDOWS { /* * The serial port number is in name[0] followed by * the parallel port number in name[1] */ int sport = name[0] - '0'; int pport = name[1] - '0'; if (OpenParallel(pport) != COM_OK) return -1; if (OpenSerial(sport, FALSE) != COM_OK) { CloseParallel(); return -1; } }#else Unix_OpenParallel(parname); Unix_OpenSerial(sername);#endif serpar_reset();#if defined(__unix) || defined(__CYGWIN__) Unix_ioctlNonBlocking();#endif Angel_RxEngineInit(&config, &rxstate); return 0;}#ifdef COMPILING_ON_WINDOWSstatic int SerparMatch(const char *name, const char *arg){ char sername[2]; char parname[2]; UNUSED(arg); sername[0] = name[0]; parname[0] = name[1]; sername[1] = parname[1] = 0; if (IsValidDevice(sername) == COM_DEVICENOTVALID || IsValidDevice(parname) == COM_DEVICENOTVALID) return -1; else return 0;}#elsestatic int SerparMatch(const char *portstring, const char *arg){ char *sername=NULL, *parname=NULL; UNUSED(arg); Unix_IsValidParallelDevice(portstring,&sername,&parname); /* Match failed if either sername or parname are still NULL */ if (sername==NULL || parname==NULL) return -1; return 0;}#endifstatic void SerparClose(void){#ifdef COMPILING_ON_WINDOWS CloseParallel(); CloseSerial();#else Unix_CloseParallel(); Unix_CloseSerial();#endif}static int SerparRead(DriverCall *dc, bool block){ static unsigned char readbuf[MAXREADSIZE]; static int rbindex = 0; int nread; int read_errno; int c = 0; re_status restatus; int ret_code = -1; /* assume bad packet or error */ /* * we must not overflow buffer, and must start after * the existing data */#ifdef COMPILING_ON_WINDOWS { BOOL dummy = FALSE; nread = BytesInRXBufferSerial(); if (nread > MAXREADSIZE - rbindex) nread = MAXREADSIZE - rbindex; read_errno = ReadSerial(readbuf+rbindex, nread, &dummy); if (pfnProgressCallback != NULL && read_errno == COM_OK) { progressInfo.nRead += nread; (*pfnProgressCallback)(&progressInfo); } }#else nread = Unix_ReadSerial(readbuf+rbindex, MAXREADSIZE-rbindex, block); read_errno = errno;#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -