github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/cmds/contrib/spidev/spidev.go (about) 1 // Copyright 2021 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // spidev communicates with the Linux spidev driver. 6 // 7 // Synopsis: 8 // 9 // spidev [OPTIONS] raw < tx.bin > rx.bin 10 // spidev [OPTIONS] sfdp 11 // 12 // Options: 13 // 14 // -D DEV: spidev device (default /dev/spidev0.0) 15 // -s SPEED: max speed in Hz (default 500000) 16 // 17 // Description: 18 // 19 // raw: The binary data from stdin is transmitted over the SPI bus. 20 // Received data is printed to stdout. 21 // sfdp: Parse and print the parameters in the SFDP. 22 package main 23 24 import ( 25 "errors" 26 "io" 27 "log" 28 "os" 29 30 flag "github.com/spf13/pflag" 31 "github.com/mvdan/u-root-coreutils/pkg/flash" 32 "github.com/mvdan/u-root-coreutils/pkg/flash/sfdp" 33 "github.com/mvdan/u-root-coreutils/pkg/spidev" 34 ) 35 36 type spi interface { 37 Transfer([]spidev.Transfer) error 38 SetSpeedHz(uint32) error 39 Close() error 40 } 41 42 type spiOpenFunc func(dev string) (spi, error) 43 44 func openSPIDev(dev string) (spi, error) { 45 return spidev.Open(dev) 46 } 47 48 func run(args []string, spiOpen spiOpenFunc, input io.Reader, output io.Writer) error { 49 // Parse args. 50 fs := flag.NewFlagSet("spidev", flag.ContinueOnError) 51 dev := fs.StringP("device", "D", "/dev/spidev0.0", "spidev device") 52 speed := fs.Uint32P("speed", "s", 500000, "max speed in Hz") 53 if err := fs.Parse(args); err != nil { 54 return err 55 } 56 57 if fs.NArg() != 1 { 58 flag.Usage() 59 return errors.New("expected one subcommand") 60 } 61 62 // Open the spi device. 63 s, err := spiOpen(*dev) 64 if err != nil { 65 return err 66 } 67 defer s.Close() 68 if err := s.SetSpeedHz(*speed); err != nil { 69 return err 70 } 71 72 // Currently, only the raw subcommand is supported. 73 switch fs.Args()[0] { 74 case "raw": 75 // Create transfer from stdin. 76 tx, err := io.ReadAll(input) 77 if err != nil { 78 return err 79 } 80 if len(tx) == 0 { 81 return nil 82 } 83 transfers := []spidev.Transfer{ 84 { 85 Tx: tx, 86 Rx: make([]byte, len(tx)), 87 }, 88 } 89 90 // Perform transfers. 91 if err := s.Transfer(transfers); err != nil { 92 return err 93 } 94 95 _, err = output.Write(transfers[0].Rx) 96 return err 97 98 case "sfdp": 99 // Create flash device and read SFDP. 100 f, err := flash.New(s) 101 if err != nil { 102 return err 103 } 104 105 // Print sfdp. 106 return f.SFDP().PrettyPrint(output, sfdp.BasicTableLookup) 107 108 default: 109 flag.Usage() 110 return errors.New("unknown subcommand") 111 } 112 } 113 114 func main() { 115 if err := run(os.Args[1:], openSPIDev, os.Stdin, os.Stdout); err != nil { 116 log.Fatalf("Error: %v", err) 117 } 118 }