Closed jcw closed 7 years ago
Intriguing... output works with one USB serial adapter, but not another (serial IN is fine).
It looks like the 32-bit macOS build doesn't work fully either. I have not been able to detect an attached STM32 microcontroller, when it's powered up in boot mode (which uses 8N1 even parity).
Could this be the solution? - https://github.com/Adapptor/go-serial/blob/master/serial/open_darwin.go#L185-L204
Hi @jcw can you please provide more context on what you're trying to do and what the code on the STM32 should do?
Could you also check the error reported from Write? something like this:
n, err := port.Write([]byte("xxxxxxxxxxxxxxxxxxxx"))
if err != nil {
log.Fatal(err)
}
fmt.Printf("Sent %v bytes\n", n)
Hello Christian, thanks - here's what I see:
$ go run try.go
Sent 26 bytes
Sent 26 bytes
Sent 26 bytes
No blink - BUT: when I change the baud rate to 9600, there's a very clear blink. Woohoo! - it works on 9600 baud. Maybe there's a typo in the baud constants table?
... or maybe the OUTPUT baudrate is not being set? ...
The constant table is here https://github.com/bugst/go-serial/blob/v1/serial_darwin.go#L16 and it seems correct (well there isn't much we can do wrong there).
But tell me: is it working for both 386 and amd64 now? from what I've understood:
115200 with amd64 -> working 115200 with 386 -> NOT working 9600 with 386 -> working
is that right?
I can confirm that up to 57600, things work:
go build && ./folie -p /dev/cu.usbserial-A600dW4s -b 57600
[connected]
upload mecrisp
20280b + v22 #0410 R +W +E writing: 80/80 done.
That's a firmware upload using 8-bit even parity - note that I have to switch parity on and off to perform this upload, so that could also be a place where the baudrate setting could be messed up.
ok thanks that's enough to investigate.
I'll take a look later, I've to go AFK now.
My findings: upload works on 9600 & 57600, not on 115200 & 230400 - same for 386 and amd64. When not working, I can see incoming data, but no outgoing LED blips.
It's more complex: open no parity, no upload (i.e. plain terminal) - works on 386, not amd64. But same open, then switch to even parity for upload: doesn't work on 386 or amd64.
It's not this machine, I can do a 115200 baud upload with another utility on the same connection. And incoming data in terminal mode is properly received @ 115200 Bd, also on amd64.
UPDATE - here is my latest attempt to work around this issue:
In other words, after a switch to/from the upload settings, the 386 build no longer sends out any data at 115200 Bd, even though it continues to receive and display incoming data properly.
I hope these notes will allow you to narrow down this issue and resolve it. My code is on GitHub in the "bugst" branch. Cheers -jcw
@jcw I tried the first snippet that you posted:
package main
import (
"go.bug.st/serial.v1"
"time"
)
func main() {
tty, err := serial.Open("/dev/cu.usbmodemFD121", &serial.Mode{
BaudRate: 115200,
})
if err != nil {
panic(err)
}
for {
tty.Write([]byte("xxxxxxxxxxxxxxxxxxxxxxxxxx"))
time.Sleep(time.Second)
}
}
on a 64 bit macosx, and everything is working fine, here the output from my "test-bed":
115200 11 N81
xxxxxxxxxxxxxxxxxxxxxxxxxx115200 11 N81
115200 11 N81
115200 11 N81
115200 11 N81
xxxxxxxxxxxxxxxxxxxxxxxxxx115200 11 N81
115200 11 N81
115200 11 N81
115200 11 N81
xxxxxxxxxxxxxxxxxxxxxxxxxx115200 11 N81
115200 11 N81
115200 11 N81
115200 11 N81
xxxxxxxxxxxxxxxxxxxxxxxxxx115200 11 N81
115200 11 N81
115200 11 N81
As you can see the speed is set correctly and the string of "xxx" is sent too.
I tried also the following:
func main() {
port, err := serial.Open("/dev/cu.usbmodemFD121", &serial.Mode{})
if err != nil {
log.Fatal(err)
}
speed := 115200
fmt.Println("N81")
port.SetMode(&serial.Mode{ BaudRate: speed, Parity: serial.NoParity, DataBits: 8, StopBits: serial.OneStopBit })
time.Sleep(time.Second*5)
fmt.Println("E81")
port.SetMode(&serial.Mode{ BaudRate: speed, Parity: serial.EvenParity, DataBits: 8, StopBits: serial.OneStopBit })
time.Sleep(time.Second*5)
fmt.Println("N81")
port.SetMode(&serial.Mode{ BaudRate: speed, Parity: serial.NoParity, DataBits: 8, StopBits: serial.OneStopBit })
time.Sleep(time.Second*5)
fmt.Println("O81")
port.SetMode(&serial.Mode{ BaudRate: speed, Parity: serial.OddParity, DataBits: 8, StopBits: serial.OneStopBit })
time.Sleep(time.Second*5)
fmt.Println("N81")
port.SetMode(&serial.Mode{ BaudRate: speed, Parity: serial.NoParity, DataBits: 8, StopBits: serial.OneStopBit })
time.Sleep(time.Second*5)
}
with all the combination: 115200 with GOARCH=386 115220 with GOARCH=amd64 9600 with GOARCH=386 9600 wit GOARCH=amd64
and everything is working fine here too... To be honest I only have a 64bit mac to try, but when I do:
GOARCH=386 go run test.go
the program is run without any issue. I don't know if this is determinant to reproduce the problem.
Questions: Are you sure that the connection is not working on your side? how do you determine that is not working?
also, I need a piece of program to reproduce the problem. If I can't reproduce here I hardly be able to solve it...
Tomorrow I'll try with another USB2Serial converter to see if there are problems.
Many thanks - this is indeed very odd. Good to know that it works on your setup.
I can confirm (with screen
, for example) that each byte sent out clearly shows up on the TX LED, even at 115200 Bd. When the problem occurs, nothing comes out of the port. If I then start the Python-based stm32loader.py, that works properly - without unplugging or port change.
I will test again tomorrow, with a fresh reboot and on a different Mac. A bug in the FTDI driver or a messed up kext setup here would not totally surprise me.
The issue appears to be ClearToSend: when CTS is tied low on the FTDI pin, then everything works!
I'm at a total loss to explain how this can have anything to do with the baudrate ??? And why it's only a problem on the FTDI interface (based on the FT232 chip).
So to summarise: can receive, but can't send on (some?) USB serial interface boards when CTS is not tied to GND (which means "active"). Oddly enough it only happens at 115200 baud and higher.
This sounds suspiciously like "hardware flow control" to me. I wonder why it would be enabled...
Oh that explains it, if CTS is not connected to ground (or to the corresponding RTS pin of the UART on the "other side" to make a real flow control) it means that the pin is "floating" and it's basically in an undefined state, it behaves like an antenna that can intercept electromagnetic fields in the nearing. Probably running the UART at high speeds produce more EMF noise, enough to set CTS pin high.
Now the question is: why is the hardware control enabled? it may be enabled by default on the FTDI chip? I found this article http://www.ftdichip.com/Support/FAQs.htm#HwGen3
Let's try to explicitly disable it, I'll post a possible patch in a minute
fixed by #10
I can't get the 64-bit version of this package to work on macOS:
This works:
GOOS=darwin GOARCH=386 go run try.go
and blinks the TX LED. This doesn't:GOOS=darwin GOARCH=amd64 go run try.go
.