📄 serpardr.c
字号:
if ((nread > 0) || (rbindex > 0)) {#ifdef DO_TRACE printf("[%d@%d] ", nread, rbindex);#endif if (nread > 0) rbindex = rbindex + nread; do { restatus = Angel_RxEngine(readbuf[c], &(dc->dc_packet), &rxstate);#ifdef DO_TRACE printf("<%02X ",readbuf[c]);#endif c++; } while (c < rbindex && ((restatus == RS_IN_PKT) || (restatus == RS_WAIT_PKT)));#ifdef DO_TRACE printf("\n");#endif switch(restatus) { case RS_GOOD_PKT: ret_code = 1; /* fall through to: */ case RS_BAD_PKT: /* * We now need to shuffle any left over data down to the * beginning of our private buffer ready to be used *for the next packet */#ifdef DO_TRACE printf("SerparRead() processed %d, moving down %d\n", c, rbindex - c);#endif if (c != rbindex) memmove((char *) readbuf, (char *) (readbuf + c), rbindex - c); rbindex -= c; break; case RS_IN_PKT: case RS_WAIT_PKT: rbindex = 0; /* will have processed all we had */ ret_code = 0; break; default:#ifdef DEBUG printf("Bad re_status in SerparRead()\n");#endif break; } } else if (nread == 0) /* nothing to read */ ret_code = 0; else if (read_errno == ERRNO_FOR_BLOCKED_IO) /* nread < 0 */ ret_code = 0;#ifdef DEBUG if ((nread < 0) && (read_errno != ERRNO_FOR_BLOCKED_IO)) perror("read() error in SerparRead()");#endif return ret_code;}/* * Function: send_packet * Purpose: Send a stream of bytes to Angel through the parallel port * * Algorithm: We need to present the data in a form that all boards can * swallow. With the PID board, this is a problem: for reasons * described in the driver (angel/pid/st16c552.c), data are * sent a nybble at a time on D0-D2 and D4; D3 is wired to ACK, * which generates an interrupt when it goes low. This routine * fills in an array of nybbles, with ACK clear in all but the * last one. If, for whatever reason, the write fails, then * ACK is forced high (thereby enabling the next write a chance * to be noticed when the falling edge of ACK generates an * interrupt (hopefully). * * Params: * Input: txstate Contains the packet to be sent * * Returns: Number of *complete* bytes written */static int SerparWrite(DriverCall *dc){ te_status status; int nwritten = 0; static TxState txstate; /* * is this a new packet? */ if (dc->dc_context == NULL) { /* * yes - initialise TxEngine */ Angel_TxEngineInit(&config, &dc->dc_packet, &txstate.state); txstate.index = 0; dc->dc_context = &txstate; } /* * fill the buffer using the Tx Engine */ do { status = Angel_TxEngine(&dc->dc_packet, &txstate.state, &txstate.writebuf[txstate.index]); if (status != TS_IDLE) txstate.index++; } while (status == TS_IN_PKT && txstate.index < MAXWRITESIZE);#ifdef DO_TRACE { unsigned int i = 0; while (i < txstate.index) { printf(">%02X ", txstate.writebuf[i]); if (!(++i % 16)) putc('\n', stdout); } if (i % 16) putc('\n', stdout); }#endif /* * the data are ready, all we need now is to send them out * in a form that Angel can swallow. */#ifdef COMPILING_ON_WINDOWS if (WriteParallel(txstate.writebuf, txstate.index) == COM_OK) { nwritten = txstate.index; if (pfnProgressCallback != NULL) { progressInfo.nWritten += nwritten; (*pfnProgressCallback)(&progressInfo); } } else { MessageBox(GetFocus(), "Write error\n", "Angel", MB_OK | MB_ICONSTOP); return -1; /* SJ - This really needs to return a value, which is picked up in */ /* DevSW_Read as meaning stop debugger but don't kill. */ }#else nwritten = Unix_WriteParallel(txstate.writebuf, txstate.index);#endif if (nwritten < 0) nwritten = 0;#ifdef DO_TRACE printf("SerparWrite: wrote %d out of %d bytes\n", nwritten, txstate.index);#endif /* * has the whole packet gone? */ if (nwritten == (int)txstate.index && (status == TS_DONE_PKT || status == TS_IDLE)) /* * yes it has */ return 1; else { /* * if some data are left, shuffle them * to the start of the buffer */ if (nwritten != (int)txstate.index && nwritten != 0) { txstate.index -= nwritten; (void)memmove((char *) txstate.writebuf, (char *) (txstate.writebuf + nwritten), txstate.index); } else if (nwritten == (int)txstate.index) txstate.index = 0; return 0; }}static int serpar_reset(void){#ifdef COMPILING_ON_WINDOWS FlushParallel(); FlushSerial();#else Unix_ResetParallel(); Unix_ResetSerial();#endif return serpar_set_params(&serpar_defaults);}static int find_baud_rate(unsigned int *speed){ static struct { unsigned int baud; int termiosValue; } possibleBaudRates[] = {#if defined(__hpux) {115200, _B115200}, {57600, _B57600},#endif#ifdef COMPILING_ON_WINDOWS {38400, CBR_38400}, {19200, CBR_19200}, {9600, CBR_9600}, {0, 0}#else {38400, B38400}, {19200, B19200}, {9600, B9600}, {0, 0}#endif }; unsigned int i; /* look for lower or matching -- will always terminate at 0 end marker */ for (i = 0; possibleBaudRates[i].baud > *speed; ++i) /* do nothing */ ; if (possibleBaudRates[i].baud > 0) *speed = possibleBaudRates[i].baud; return possibleBaudRates[i].termiosValue;}static int serpar_set_params(const ParameterConfig *config){ unsigned int speed; int termios_value;#ifdef DEBUG printf("serpar_set_params\n");#endif if (!Angel_FindParam(AP_BAUD_RATE, config, &speed)) {#ifdef DEBUG printf("speed not found in config\n");#endif return DE_OKAY; } termios_value = find_baud_rate(&speed); if (termios_value == 0) {#ifdef DEBUG printf("speed not valid: %u\n", speed);#endif return DE_OKAY; }#ifdef DEBUG printf("setting speed to %u\n", speed);#endif#ifdef COMPILING_ON_WINDOWS SetBaudRate((WORD)termios_value);#else Unix_SetSerialBaudRate(termios_value);#endif return DE_OKAY;}static int serpar_get_user_params(ParameterOptions **p_options){#ifdef DEBUG printf("serpar_get_user_params\n");#endif if (user_options_set) { *p_options = &user_options; } else { *p_options = NULL; } return DE_OKAY;}static int serial_get_default_params( const ParameterConfig **p_config ){#ifdef DEBUG printf( "serial_get_default_params\n" );#endif *p_config = &serpar_defaults; return DE_OKAY;}static int SerparIoctl(const int opcode, void *args){ int ret_code;#ifdef DEBUG printf("SerparIoctl: op %d arg %p\n", opcode, args ? args : "<NULL>");#endif switch (opcode) { case DC_RESET: ret_code = serpar_reset(); break; case DC_SET_PARAMS: ret_code = serpar_set_params((const ParameterConfig *)args); break; case DC_GET_USER_PARAMS: ret_code = serpar_get_user_params((ParameterOptions **)args); break; case DC_GET_DEFAULT_PARAMS: ret_code = serial_get_default_params((const ParameterConfig **)args); break; default: ret_code = DE_BAD_OP; break; } return ret_code;}DeviceDescr angel_SerparDevice ={ "SERPAR", SerparOpen, SerparMatch, SerparClose, SerparRead, SerparWrite, SerparIoctl};/* EOF serpardr.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -