Can anyone point me to where the serial driver source code may be? Just would like to take a look.
In case anyone wants a quick way to view/set registers, here is my Go program I created. There are better ways I'm sure, but this was a quick way to get the job done without having a C/C++ cross compiler. You end up with a relatively large program (1.4MB) but it has no dependencies. It seems to work ok, but you can imagine things can go wrong if writing directly to registers
package main
/*
devman.go
devmem for Omega2 - read/write hardware registers via /dev/mem
Go 1.11.2 32bit downloaded/extracted into $HOME/Programming/go/1.11.2
(not installed, so use export below when at bash prompt)
$export GOROOT=$HOME/Programming/go/1.11.2
$export GOPATH=$HOME/Programming/go/work
$export PATH=$PATH:$GOROOT/bin:$GOPATH/bin/linux_386
$export GOARCH=386
$export GOBIN=$GOPATH/bin/linux_386
bash shell at src folder, cross compile for Omega2-
$GOOS=linux GOARCH=mipsle go build -ldflags="-s -w" devmem.go
then copy to Omega2-
$scp devmem root@Omega_SNAP1:/root
*/
import (
"fmt"
"os"
"syscall"
"unsafe"
"strconv"
"path"
)
const REGBASE = 0x10000000
func usage() {
pnam := path.Base(os.Args[0])
fmt.Printf("\n%s read <addr>\n", pnam)
fmt.Printf("%s write <addr> <val>\n", pnam)
fmt.Printf("%s setbits <addr> <bitmask>\n", pnam)
fmt.Printf("%s clrbits <addr> <bitmask>\n", pnam)
fmt.Printf(" <addr> = absolute or offset from 0x10000000\n")
fmt.Printf(" <bitmask> = bits to set or clear\n\n")
return
}
func memread(mem []byte, addr int, addr_offset int) {
v := *(*uint32)(unsafe.Pointer(&mem[addr_offset]))
v3 := uint8(v>>24); v2 := uint8(v>>16); v1 := uint8(v>>8); v0 := uint8(v)
fmt.Printf(
"\n" +
"addr: [0x%08X] val: [0x%08X]\n" +
"\n" +
"bit 3 3 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1\n" +
"pos 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n" +
" ............... ............... ............... ...............\n",
addr, v)
fmt.Printf(
"bin ")
vb := v
for i := 0; i < 32; i++ {
b := "0 "
if (vb & (1<<31)) != 0 { b = "1 " }
fmt.Printf("%s", b)
if (i & 7) == 7 { fmt.Printf(" ") }
vb <<= 1
}
fmt.Printf(
"\n" +
"hex %11s0x%02X %11s0x%02X %11s0x%02X %11s0x%02X\n" +
"dec %15d %15d %15d %15d\n\n",
" ", v3, " ", v2, " ", v1, " ", v0, v3, v2, v1, v0)
}
func memwrite(mem []byte, addr_offset int, val uint32) {
*(*uint32)(unsafe.Pointer(&mem[addr_offset])) = uint32(val)
}
func memsetbits(mem []byte, addr_offset int, val uint32) {
*(*uint32)(unsafe.Pointer(&mem[addr_offset])) |= uint32(val)
}
func memclrbits(mem []byte, addr_offset int, val uint32) {
*(*uint32)(unsafe.Pointer(&mem[addr_offset])) &^= uint32(val)
}
func main() {
args := os.Args[1:]
if len(args) < 2 { usage(); return }
opt := args[0]
a, err := strconv.ParseUint(args[1], 0, 32)
if err != nil { fmt.Printf("invalid address- %s\n", args[1]); return }
b := uint64(0)
switch opt {
case "read":
case "write": fallthrough
case "setbits": fallthrough
case "clrbits":
if len(args) < 3 { usage(); return }
b, err = strconv.ParseUint(args[2], 0, 32)
if err != nil { fmt.Printf("invalid number- %s\n", args[2]); return }
default: usage(); return
}
addr := int(a) &^ 3 | REGBASE //word aligned, to full address
val := uint32(b)
page_addr := addr &^ 0xFFF //align on page for mmap
addr_offset := addr - page_addr //offset into mmap page
f, err := os.OpenFile("/dev/mem", os.O_RDWR|os.O_SYNC, 0666)
if err != nil { fmt.Printf("failed to open /dev/mem\n"); return }
defer f.Close()
mem, err := syscall.Mmap(int(f.Fd()), int64(page_addr), 4096,
syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED)
if err != nil { fmt.Printf("failed to mmap /dev/mem\n"); return }
switch opt {
case "read": memread(mem, addr, addr_offset)
case "write": memwrite(mem, addr_offset, val)
case "setbits": memsetbits(mem, addr_offset, val)
case "clrbits": memclrbits(mem, addr_offset, val)
}
err = syscall.Munmap(mem)
if err != nil { fmt.Printf("Munmap failed\n") }
}