int serial_init(const char *port, unsigned long baud) { char fullPort[20]; sprintf(fullPort, "\\\\.\\%s", port); hSerial = CreateFile( fullPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (hSerial == INVALID_HANDLE_VALUE) return FALSE; /* Set the baud rate. Always succeeds with mingw. */ if (!serial_baud(baud)) { serial_done(); return 0; } GetCommTimeouts(hSerial, &original_timeouts); timeouts = original_timeouts; timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; timeouts.WriteTotalTimeoutConstant = 1; timeouts.WriteTotalTimeoutMultiplier = 1; /* setup device buffers */ SetupComm(hSerial, 10000, 10000); /* purge any information in the buffer */ PurgeComm(hSerial, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); return TRUE; }
static void sigint_handler(int signum) { serial_done(); exit(1); }
/** * change the baud rate of the serial port * @param baud - baud rate * @returns 1 for success and 0 for failure */ int serial_baud(unsigned long baud) { struct termios sparm; int tbaud = 0; switch(baud) { case 0: // default tbaud = B115200; break; #ifdef B921600 case 921600: tbaud = B921600; break; #endif #ifdef B576000 case 576000: tbaud = B576000; break; #endif #ifdef B500000 case 500000: tbaud = B500000; break; #endif #ifdef B460800 case 460800: tbaud = B460800; break; #endif #ifdef B230400 case 230400: tbaud = B230400; break; #endif case 115200: tbaud = B115200; break; case 57600: tbaud = B57600; break; case 38400: tbaud = B38400; break; case 19200: tbaud = B19200; break; case 9600: tbaud = B9600; break; default: printf("Unsupported baudrate. Use "); tbaud = baud; break; #ifdef B921600 printf("921600, "); #endif #ifdef B576000 printf("576000, "); #endif #ifdef B500000 printf("500000, "); #endif #ifdef B460800 printf("460800, "); #endif #ifdef B230400 printf("230400, "); #endif printf("115200, 57600, 38400, 19200, or 9600\n"); serial_done(); exit(2); break; } /* get the current options */ chk("tcgetattr", tcgetattr(hSerial, &sparm)); /* set raw input */ #ifdef MACOSX chk("cfsetspeed", cfsetspeed(&sparm, tbaud)); #else chk("cfsetispeed", cfsetispeed(&sparm, tbaud)); chk("cfsetospeed", cfsetospeed(&sparm, tbaud)); #endif /* set the options */ chk("tcflush", tcflush(hSerial, TCIFLUSH)); chk("tcsetattr", tcsetattr(hSerial, TCSANOW, &sparm)); return 1; }
int main(int argc, char *argv[]) { char actualport[PATH_MAX]; char *infile = NULL, *p, *p2; int terminalMode = FALSE; BoardConfig *config, *configSettings; char *port, *board, *subtype, *value; System sys; int baud = 115200; int portFlags = 0; int flags = 0; int i; int terminalBaud = 0; int check_for_exit = 0; /* flag to terminal_mode to check for a certain sequence to indicate program exit */ int showPorts = FALSE; int showAll = TRUE; int pstMode = FALSE; /* make sure that the serial port gets closed on exit */ atexit(serial_done); /* just display a usage message if no arguments are supplied */ if (argc <= 1) Usage(); /* get the environment settings */ port = getenv("PROPELLER_LOAD_PORT"); board = getenv("PROPELLER_LOAD_BOARD"); /* setup a configuration to collect command line -D settings */ configSettings = NewBoardConfig(NULL, ""); /* get the arguments */ for(i = 1; i < argc; ++i) { /* handle switches */ if(argv[i][0] == '-') { switch(argv[i][1]) { case 'b': // select a target board if (argv[i][2]) board = &argv[i][2]; else if (++i < argc) board = argv[i]; else Usage(); break; case 'p': if(argv[i][2]) port = &argv[i][2]; else if(++i < argc) port = argv[i]; else Usage(); #if defined(CYGWIN) || defined(WIN32) || defined(LINUX) if (isdigit((int)port[0])) { #if defined(CYGWIN) || defined(WIN32) static char buf[10]; sprintf(buf, "COM%d", atoi(port)); port = buf; #endif #if defined(LINUX) static char buf[64]; sprintf(buf, "/dev/ttyUSB%d", atoi(port)); port = buf; #endif } #endif #if defined(MACOSX) if (port[0] != '/') { static char buf[64]; sprintf(buf, "/dev/cu.usbserial-%s", port); port = buf; } #endif break; case 'P': showPorts = TRUE; showAll = FALSE; break; case 'Q': showPorts = TRUE; showAll = TRUE; break; case 'e': flags |= LFLAG_WRITE_EEPROM; break; case 'l': flags |= LFLAG_WRITE_SDLOADER; break; case 'z': flags |= LFLAG_WRITE_SDCACHELOADER; break; case 'r': flags |= LFLAG_RUN; break; case 's': flags |= LFLAG_WRITE_BINARY; break; case 'x': flags |= LFLAG_WRITE_PEX; break; case 'T': pstMode = TRUE; // fall through case 't': terminalMode = TRUE; if (argv[i][2]) terminalBaud = atoi(&argv[i][2]); break; case 'q': check_for_exit = 1; break; case 'g': flags |= LFLAG_DEBUG; break; case 'D': if(argv[i][2]) p = &argv[i][2]; else if(++i < argc) p = argv[i]; else Usage(); if ((p2 = strchr(p, '=')) == NULL) Usage(); *p2++ = '\0'; SetConfigField(configSettings, p, p2); break; case 'I': if(argv[i][2]) p = &argv[i][2]; else if(++i < argc) p = argv[i]; else Usage(); xbAddPath(p); break; case 'v': portFlags = IFLAG_VERBOSE; break; case 'S': psetdelay(argv[i][2] ? atoi(&argv[i][2]) : 5); break; case 'f': flags |= LFLAG_WRITE_SDFILE; break; case '?': /* fall through */ default: Usage(); break; } } /* handle the input filename */ else { if (infile) Usage(); infile = argv[i]; } } /* make sure an input file was specified if needed */ if (infile && !flags) { printf("error: must specify -e, -r, or -s when an image file is specified\n"); return 1; } /* 1) look in the directory specified by the -I command line option (added above) 2) look in the directory where the elf file resides 3) look in the directory pointed to by the environment variable PROPELLER_ELF_LOAD 4) look in the directory where the loader executable resides if possible 5) look in /usr/local/propeller/propeller-load */ /* finish the include path */ if (infile) xbAddFilePath(infile); xbAddEnvironmentPath("PROPELLER_LOAD_PATH"); xbAddProgramPath(argv); #if defined(LINUX) || defined(MACOSX) || defined(CYGWIN) xbAddPath("/opt/parallax/propeller-load"); #endif sys.ops = &myOps; /* parse the board option */ if (board) { /* split the board type from the subtype */ if ((p = strchr(board, ':')) != NULL) { *p++ = '\0'; subtype = p; } /* no subtype */ else subtype = DEF_SUBTYPE; } else { board = DEF_BOARD; subtype = DEF_SUBTYPE; } /* setup for the selected board */ if (!(config = ParseConfigurationFile(&sys, board))) { printf("error: can't find board configuration '%s'\n", board); return 1; } /* select the subtype */ if (subtype) { if (!(config = GetConfigSubtype(config, subtype))) { printf("error: can't find board configuration subtype '%s'\n", subtype); return 1; } } /* override with any command line settings */ config = MergeConfigs(config, configSettings); /* use the baud rate from the configuration */ GetNumericConfigField(config, "baudrate", &baud); /* Use reset method from configuration */ if ((value = GetConfigField(config, "reset")) != NULL) { if (use_reset_method (value)) { printf("error: no reset type '%s'\n", value); return 1; } } else { use_reset_method ("dtr"); } /* check for being asked to show ports */ if (showPorts) { if (showAll) ShowPorts(PORT_PREFIX); else ShowConnectedPorts(PORT_PREFIX, baud, portFlags); return 0; } /* initialize the serial port */ if ((flags & NEED_PORT) != 0 || terminalMode) { int sts = InitPort(PORT_PREFIX, port, baud, portFlags, actualport); switch (sts) { case PLOAD_STATUS_OK: // port initialized successfully break; case PLOAD_STATUS_OPEN_FAILED: printf("error: opening serial port '%s'\n", port); perror("Error is "); return 1; case PLOAD_STATUS_NO_PROPELLER: if (port) printf("error: no propeller chip on port '%s'\n", port); else printf("error: can't find a port with a propeller chip\n"); return 1; } } /* load the image file */ if (infile) { if (flags & LFLAG_WRITE_SDFILE) WriteFileToSDCard(config, infile, NULL); else { if (!LoadImage(&sys, config, infile, flags)) { printf("error: load failed\n"); return 1; } } } /* check for loading the sd loader */ else if (flags & LFLAG_WRITE_SDLOADER) { if (!LoadSDLoader(&sys, config, "sd_loader.elf", flags)) { printf("error: load failed\n"); return 1; } } /* check for loading the sd cache loader */ else if (flags & LFLAG_WRITE_SDCACHELOADER) { if (!LoadSDCacheLoader(&sys, config, "sd_cache_loader.elf", flags)) { printf("error: load failed\n"); return 1; } } /* enter terminal mode if requested */ if (terminalMode) { printf("[ Entering terminal mode. Type ESC or Control-C to exit. ]\n"); fflush(stdout); if (terminalBaud && terminalBaud != baud) { serial_done(); serial_init(actualport, terminalBaud); } terminal_mode(check_for_exit, pstMode); } return 0; }