github.com/aykevl/tinygo@v0.5.0/src/machine/spi.go (about) 1 // +build nrf stm32f103xx atsamd21g18a 2 3 package machine 4 5 import "errors" 6 7 var ( 8 ErrTxSlicesRequired = errors.New("SPI Tx requires a write or read slice, or both") 9 ErrTxInvalidSliceSize = errors.New("SPI write and read slices must be same size") 10 ) 11 12 // Tx handles read/write operation for SPI interface. Since SPI is a syncronous write/read 13 // interface, there must always be the same number of bytes written as bytes read. 14 // The Tx method knows about this, and offers a few different ways of calling it. 15 // 16 // This form sends the bytes in tx buffer, putting the resulting bytes read into the rx buffer. 17 // Note that the tx and rx buffers must be the same size: 18 // 19 // spi.Tx(tx, rx) 20 // 21 // This form sends the tx buffer, ignoring the result. Useful for sending "commands" that return zeros 22 // until all the bytes in the command packet have been received: 23 // 24 // spi.Tx(tx, nil) 25 // 26 // This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet": 27 // 28 // spi.Tx(nil, rx) 29 // 30 func (spi SPI) Tx(w, r []byte) error { 31 if w == nil && r == nil { 32 return ErrTxSlicesRequired 33 } 34 35 var err error 36 37 switch { 38 case w == nil: 39 // read only, so write zero and read a result. 40 for i := range r { 41 r[i], err = spi.Transfer(0) 42 if err != nil { 43 return err 44 } 45 } 46 case r == nil: 47 // write only 48 for _, b := range w { 49 _, err = spi.Transfer(b) 50 if err != nil { 51 return err 52 } 53 } 54 55 default: 56 // write/read 57 if len(w) != len(r) { 58 return ErrTxInvalidSliceSize 59 } 60 61 for i, b := range w { 62 r[i], err = spi.Transfer(b) 63 if err != nil { 64 return err 65 } 66 } 67 } 68 69 return nil 70 }