package main
import (
- "fmt"
"bufio"
"bytes"
"os"
+ "errors"
"svn.spreadspace.org/realraum/go.svn/termios"
- "log"
- "sync"
)
+
// ---------- Serial TTY Code -------------
-func openTTY(name string) (*os.File, error) {
- file, err := os.OpenFile(name,os.O_RDWR, 0600) // For read access.
- if err != nil {
- log.Println(err.Error())
- return nil, err
+func openTTY(name string, speed uint) (file *os.File, err error) {
+ file, err = os.OpenFile(name,os.O_RDWR, 0666)
+ if err != nil { return }
+ if err = termios.SetRawFile(file); err != nil { return }
+ switch speed {
+ case 0: // set no baudrate
+ case 1200: err = termios.SetSpeedFile(file, termios.B1200)
+ case 2400: err = termios.SetSpeedFile(file, termios.B2400)
+ case 4800: err = termios.SetSpeedFile(file, termios.B4800)
+ case 9600: err = termios.SetSpeedFile(file, termios.B9600)
+ case 19200: err = termios.SetSpeedFile(file, termios.B19200)
+ case 38400: err = termios.SetSpeedFile(file, termios.B38400)
+ case 57600: err = termios.SetSpeedFile(file, termios.B57600)
+ case 115200: err = termios.SetSpeedFile(file, termios.B115200)
+ case 230400: err = termios.SetSpeedFile(file, termios.B230400)
+ default:
+ file.Close()
+ err = errors.New("Unsupported Baudrate, use 0 to disable setting a baudrate")
}
- termios.Ttyfd(file.Fd())
- termios.SetRaw()
- return file, nil
+ return
}
func serialWriter(in <- chan string, serial * os.File) {
serial.WriteString(totty)
serial.Sync()
}
+ serial.Close()
}
-var last_read_serial_input [][]byte = [][]byte{{}}
-var last_read_mutex sync.Mutex
-
-func serialReader(topub chan <- [][]byte, serial * os.File) {
+func serialReader(out chan <- [][]byte, serial * os.File) {
linescanner := bufio.NewScanner(serial)
linescanner.Split(bufio.ScanLines)
for linescanner.Scan() {
if err := linescanner.Err(); err != nil {
- panic(fmt.Sprintf("Error in read from serial: %v\n",err.Error()))
+ panic(err.Error())
}
- fmt.Println("read text", linescanner.Text())
text := bytes.Fields([]byte(linescanner.Text()))
if len(text) == 0 {
continue
}
- //~ for len(serial_read) > 5 {
- //~ //drain channel before putting new line into it
- //~ //thus we make sure "out" only ever holds the last line
- //~ //thus the buffer never blocks and we don't need to read from out unless we need it
- //~ // BUT: don't drain the chan dry, or we might have a race condition resulting in a deadlock
- //~ <- serial_read
- //~ }
- last_read_mutex.Lock()
- last_read_serial_input = text
- fmt.Println("Put Text", text)
- last_read_mutex.Unlock()
- topub <- text
+ out <- text
}
}
-//TODO: improve this, make it work for multiple open serial devices
-func GetLastSerialLine() [][]byte {
- var last_line_pointer [][]byte
- last_read_mutex.Lock()
- last_line_pointer = last_read_serial_input
- last_read_mutex.Unlock()
- fmt.Println("Retrieve Text", last_line_pointer)
- return last_line_pointer
-}
-
-func OpenAndHandleSerial(filename string, topub chan <- [][]byte) (chan string, error) {
- serial, err :=openTTY(filename)
+func OpenAndHandleSerial(filename string, serspeed uint) (chan string, chan [][]byte, error) {
+ serial, err :=openTTY(filename, serspeed)
if err != nil {
- return nil, err
+ return nil, nil, err
}
- wr := make(chan string)
+ wr := make(chan string, 1)
+ rd := make(chan [][]byte, 20)
go serialWriter(wr, serial)
- go serialReader(topub, serial)
- return wr, nil
+ go serialReader(rd, serial)
+ return wr, rd, nil
}