func main() { var err error var baud, cmdIndex int var chanFromSerial, chanToSerial chan byte var chanDTRSerial, chanQuitSerial, chanQuitTcp chan bool var conn *net.TCPConn var tcpaddr *net.TCPAddr runtime.GOMAXPROCS(runtime.NumCPU()) cp := new(cogCommandProcessor.CogCommandProcessor) cp.SetReceiveTimeout(time.Duration(3e9)) cp.SetCps(5000) if len(os.Args) > 1 { tcpaddr, err = net.ResolveTCPAddr("tcp", os.Args[1]) if err == nil { conn, err = net.DialTCP("tcp", nil, tcpaddr) if err == nil { chanFromSerial, chanToSerial, chanQuitTcp = cp.TcpChan(conn) } } cmdIndex = 2 } if chanFromSerial == nil && len(os.Args) > 2 { b, errc := strconv.ParseInt(os.Args[2], 10, 32) err = errc baud = int(b) if err == nil { chanFromSerial, chanToSerial, chanDTRSerial, chanQuitSerial, err = serial.SerialChannels(os.Args[1], baud, debug) } // to reset the prop chanDTRSerial <- false time.Sleep(1e8) chanDTRSerial <- true time.Sleep(1e8) chanDTRSerial <- false cmdIndex = 3 } if err != nil || chanFromSerial == nil { fmt.Printf("error: %s\nusage: %s [ipaddr:port | com_port baud] [commands]*\n%s", err, os.Args[0], cogCommandProcessor.Help) return } conLog := make(chan string) go func() { for s := range conLog { fmt.Print(s) } }() var sName string if len(os.Args) > cmdIndex { sName = "LINE COMMANDS" } else { sName = "USER INPUT" } time.Sleep(3e9) chanCommand := cp.CommandProcessor(sName, chanFromSerial, chanToSerial, conLog) if len(os.Args) > cmdIndex { for _, s := range os.Args[cmdIndex:] { fmt.Println(s) for _, c := range s { chanCommand <- byte(c) } chanCommand <- byte(0x20) } chanCommand <- byte(0x0D) chanCommand <- byte(0x0D) close(chanCommand) return } chanCommand <- byte('h') chanCommand <- byte(0x0D) d := make([]byte, 2048) for { c, e := os.Stdin.Read(d) for _, ch := range d[:c] { if ch == byte(0x0A) { ch = byte(0x0D) } chanCommand <- ch if ch == byte(0x0D) { break } } time.Sleep(10) if chanQuitTcp != nil { select { case <-chanQuitTcp: e = io.EOF default: } } if e == io.EOF { break } } if chanQuitSerial != nil { chanQuitSerial <- true } if chanQuitTcp != nil { } close(conLog) }
func MuxSerialChannels(name string, baud int, numChannels int, debug bool) (*MuxSerialStruct, error) { var r = new(MuxSerialStruct) var err error var lshift uint r.debug = debug if numChannels <= 8 { lshift = 6 r.numMuxChannels = 8 } else if numChannels <= 16 { lshift = 5 r.numMuxChannels = 16 } else { lshift = 4 r.numMuxChannels = 32 } r.maxPacketSize = 1 << lshift r.mux = make([]*muxChannel, r.numMuxChannels) for i := 0; i < r.numMuxChannels; i++ { r.mux[i] = new(muxChannel) r.mux[i].ackMuxToData = make(chan bool, 1) r.mux[i].fromMux = make(chan indexData, 1) r.mux[i].fromClient = make(chan byte, 4096) r.mux[i].toClient = make(chan byte, 4096) r.mux[i].quitGO_C = make(chan bool) r.mux[i].quitGO_D = make(chan bool) r.mux[i].connected = false } r.fromSerial, r.toSerial, r.dtrSerial, r.quitSerial, err = serial.SerialChannels(name, baud, debug) if err != nil { return nil, err } forthConstDef := fmt.Sprintf("d_%d wconstant _MX_BSHIFT\nd_%d wconstant _MX_BSIZE\nd_%d wconstant _MX_BMASK\nd_%d wconstant _MX_NUM_CHAN\nd_%d wconstant _MX_BUF_OFFSET\n\n", lshift, r.maxPacketSize, r.maxPacketSize-1, r.numMuxChannels, 4*r.numMuxChannels) for retryCount, syncok := 1, false; syncok == false; retryCount++ { if retryCount > 5 { return nil, errors.New("Propeller not initializing MX") } // to reset the prop fmt.Printf("\nRebooting propeller, try %d\n", retryCount) r.dtrSerial <- false time.Sleep(1e8) r.dtrSerial <- true time.Sleep(1e8) r.dtrSerial <- false // give the prop time to reboot time.Sleep(2e9) r.flush() fmt.Printf("Sending constant definitions:\n\n%s", forthConstDef) r.sendString(forthConstDef) r.flush() fmt.Print("Sending code...\n") r.sendString(scode) r.flush() fmt.Print("Sending start command... Waiting for sync\n") r.sendString("gos\r") syncok = r.sync() } fmt.Print("Starting serial multiplexer\n") r.startMux() return r, nil }