bool cm_init(void) { if (io_Init() == false) return false; sb_Write(0xc0, sb_Read(0xc0) & 0x7fffffffL | ((unsigned long)1UL << 31)); io_Close(); //com_SetUSBPins(2, 0, 2, 1); if ((Serial = com_Init(COM4)) == NULL) return false; com_SetTimeOut(Serial, 0); com_SetBPS(Serial, COM_UARTBAUD_1000000BPS); com_SetFormat(Serial, BYTESIZE8 + STOPBIT1 + NOPARITY); com_SetFlowControl(Serial, NO_CONTROL); com_EnableFIFO(Serial, FIFO_032); return true; }
RBAPI(bool) com_Init(int com, int duplex) { if (com_InUse(com) == true) { err_SetMsg(ERROR_COM_INUSE, "COM%d was already opened", com); return false; } #ifdef ROBOIO duplex = (duplex == COM_ADUPLEX)? COM_FDUPLEX : duplex; switch (roboio_GetRBVer()) { case RB_100b1: switch (com) { case COM_PORT1: COM_duplex[com] = (duplex != COM_HDUPLEX_TXDEN)? duplex : COM_HDUPLEX; break; case COM_PORT2: COM_duplex[com] = COM_HDUPLEX_TXDEN; break; case COM_PORT3: COM_duplex[com] = (duplex == COM_FDUPLEX)? duplex : COM_HDUPLEX; break; case COM_PORT4: COM_duplex[com] = COM_HDUPLEX_RTS; break; } break; case RB_100b2: switch (com) { case COM_PORT1: COM_duplex[com] = COM_FDUPLEX; break; case COM_PORT2: COM_duplex[com] = COM_HDUPLEX_TXDEN; break; case COM_PORT3: COM_duplex[com] = (duplex == COM_FDUPLEX)? duplex : COM_HDUPLEX; break; case COM_PORT4: COM_duplex[com] = COM_HDUPLEX_RTS; break; } break; case RB_100b3: switch (com) { case COM_PORT1: COM_duplex[com] = (duplex != COM_HDUPLEX_TXDEN)? duplex : COM_HDUPLEX; break; case COM_PORT2: COM_duplex[com] = COM_HDUPLEX_TXDEN; break; case COM_PORT3: COM_duplex[com] = (duplex == COM_FDUPLEX)? duplex : COM_HDUPLEX; break; case COM_PORT4: COM_duplex[com] = COM_HDUPLEX; break; } break; case RB_100: case RB_100RD: switch (com) { case COM_PORT1: COM_duplex[com] = COM_FDUPLEX; break; case COM_PORT2: COM_duplex[com] = COM_HDUPLEX_TXDEN; break; case COM_PORT3: COM_duplex[com] = (duplex == COM_FDUPLEX)? duplex : COM_HDUPLEX; break; case COM_PORT4: COM_duplex[com] = COM_HDUPLEX; break; } break; case RB_110: case RB_050: switch (com) { case COM_PORT1: COM_duplex[com] = COM_FDUPLEX; break; case COM_PORT2: COM_duplex[com] = COM_HDUPLEX_TXDEN; break; case COM_PORT3: COM_duplex[com] = (duplex == COM_FDUPLEX)? duplex : COM_HDUPLEX; break; case COM_PORT4: COM_duplex[com] = (duplex == COM_FDUPLEX)? duplex : COM_HDUPLEX; break; } break; default: err_SetMsg(ERROR_RBVER_UNKNOWN, "unrecognized RoBoard"); return false; } #else COM_duplex[com] = duplex; #endif if((COM_ioSection[com] = io_Init()) == -1) return false; if(uart_isenabled(com) == false) { err_SetMsg(ERROR_COM_INVALID, "COM%d isn't enabled in BIOS", com); goto COMINIT_FAIL; } COM_baseaddr[com] = uart_getbaseaddr(com); COM_oldTMode[com] = com_IsTurboMode(com); COM_oldFMode[com] = com_IsFIFO32Mode(com); #if defined(RB_MSVC_WIN32) || defined(RB_MSVC_WINCE) { #ifdef RB_MSVC_WINCE int idx = com; #else int i, idx; // find the device name of the COM port for (idx=0, i=0; i<com; i++) if (uart_isenabled(i) == true) idx++; #endif COM_info[com].fp = CreateFile( COM_portname[idx], // device name of COM port GENERIC_READ | GENERIC_WRITE, // access mode 0, // share mode 0, // security attributes OPEN_EXISTING, // opens a device only if it exists 0, // non-overlapped NULL); // NULL when opening an existing file if (COM_info[com].fp == INVALID_HANDLE_VALUE) { err_SetMsg(ERROR_COM_FAIL, "cannot open COM%d device driver", com); goto COMINIT_FAIL; } // backup the old DCB if (GetCommState(COM_info[com].fp, &(COM_info[com].oldstate)) == FALSE) { err_SetMsg(ERROR_COM_FAIL, "fail to get DCB settings"); goto COMINIT_FAIL2; } memcpy(&(COM_info[com].newstate), &(COM_info[com].oldstate), sizeof(DCB)); // set new DCB COM_info[com].newstate.fBinary = TRUE; // binary mode COM_info[com].newstate.fOutxCtsFlow = FALSE; // no CTS output control COM_info[com].newstate.fOutxDsrFlow = FALSE; // no DSR output control COM_info[com].newstate.fDtrControl = DTR_CONTROL_DISABLE; // no DRT control COM_info[com].newstate.fDsrSensitivity = FALSE; // no sensitive to DSR COM_info[com].newstate.fOutX = FALSE; // no S/W output flow control COM_info[com].newstate.fInX = FALSE; // no S/W input flow control COM_info[com].newstate.fErrorChar = FALSE; // no replace parity-error byte COM_info[com].newstate.fNull = FALSE; // no discard NULL byte COM_info[com].newstate.fRtsControl = RTS_CONTROL_DISABLE; // no S/W input flow control COM_info[com].newstate.fAbortOnError = FALSE; // no terminate on errors if (SetCommState(COM_info[com].fp, &(COM_info[com].newstate)) == FALSE) { err_SetMsg(ERROR_COM_FAIL, "fail to set DCB settings"); goto COMINIT_FAIL2; } // get old timeout parameters if (GetCommTimeouts(COM_info[com].fp, &(COM_info[com].oldtimeouts)) == FALSE) { err_SetMsg(ERROR_COM_FAIL, "fail to get TIMEOUTS settings"); goto COMINIT_FAIL3; } // set timeout parameters (no waiting on read/write) COM_info[com].newtimeouts.ReadIntervalTimeout = MAXDWORD; COM_info[com].newtimeouts.ReadTotalTimeoutConstant = 0; COM_info[com].newtimeouts.ReadTotalTimeoutMultiplier = 0; COM_info[com].newtimeouts.WriteTotalTimeoutConstant = 0; COM_info[com].newtimeouts.WriteTotalTimeoutMultiplier = 0; if (SetCommTimeouts(COM_info[com].fp, &(COM_info[com].newtimeouts)) == FALSE) { err_SetMsg(ERROR_COM_FAIL, "fail to set TIMEOUT parameters"); goto COMINIT_FAIL3; } ClearCommBreak(COM_info[com].fp); ClearCommError(COM_info[com].fp, NULL, NULL); // clear all communication errors SetupComm(COM_info[com].fp, 8192, 8192); // set read/write FIFO to 8KB PurgeComm(COM_info[com].fp, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR); // clear all communication buffers } #elif defined(RB_LINUX) if ((COM_info[com].fp = open(COM_portname[com], O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) { err_SetMsg(ERROR_COM_FAIL, "cannot open COM%d device driver", com); goto COMINIT_FAIL; } // backup the old termios settings if (tcgetattr(COM_info[com].fp, &(COM_info[com].oldstate)) < 0) { err_SetMsg(ERROR_COM_FAIL, "fail to get termios settings"); goto COMINIT_FAIL2; } memcpy(&(COM_info[com].newstate), &(COM_info[com].oldstate), sizeof(termios)); // set new termios settings COM_info[com].newstate.c_cflag |= CLOCAL | CREAD; COM_info[com].newstate.c_cflag &= ~CRTSCTS; // disable H/W flow control COM_info[com].newstate.c_lflag &= ~(ICANON | // raw mode ISIG | // disable SIGxxxx signals IEXTEN | // disable extended functions ECHO | ECHOE); // disable all auto-echo functions COM_info[com].newstate.c_iflag &= ~(IXON | IXOFF | IXANY); // disable S/W flow control COM_info[com].newstate.c_oflag &= ~OPOST; // raw output COM_info[com].newstate.c_cc[VTIME] = 0; // no waiting to read COM_info[com].newstate.c_cc[VMIN] = 0; if(tcsetattr(COM_info[com].fp, TCSANOW, &(COM_info[com].newstate)) < 0) { err_SetMsg(ERROR_COM_FAIL, "fail to set termios settings"); goto COMINIT_FAIL2; } // clear input/output buffers tcflush(COM_info[com].fp, TCIOFLUSH); #else // TODO ... err_SetMsg(ERROR_COM_INVALID, "unsupported platform"); goto COMINIT_FAIL; #endif if (COM_duplex[com] == COM_HDUPLEX_RTS) clear_rts(com); // set COM direction as input com_SetFormat(com, COM_BYTESIZE8, COM_STOPBIT1, COM_NOPARITY); // default data format: 8 bits, 1 stop bit, no parity com_SetBaud(com, COMBAUD_115200BPS); // default baudrate: 115200 bps com_EnableFIFO32(com); // set Vortex86DX's UART FIFO as 32 bytes return true; #if defined(RB_MSVC_WIN32) || defined(RB_MSVC_WINCE) COMINIT_FAIL3: SetCommState(COM_info[com].fp, &(COM_info[com].oldstate)); COMINIT_FAIL2: CloseHandle(COM_info[com].fp); #elif defined(RB_LINUX) COMINIT_FAIL2: close(COM_info[com].fp); #endif COMINIT_FAIL: io_Close(COM_ioSection[com]); COM_ioSection[com] = -1; return false; }