mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-20 06:28:59 +00:00
add support extended id for mcp2515 (#857)
* add support extended id for mcp2515 * fix mcp2512 example code * revert Pin control
This commit is contained in:
@@ -21,7 +21,7 @@ func main() {
|
|||||||
SDI: machine.SPI0_SDI_PIN,
|
SDI: machine.SPI0_SDI_PIN,
|
||||||
Mode: 0})
|
Mode: 0})
|
||||||
can := mcp2515.New(spi, csPin)
|
can := mcp2515.New(spi, csPin)
|
||||||
can.Configure()
|
can.Configure(mcp2515.Configuration{})
|
||||||
err := can.Begin(mcp2515.CAN500kBps, mcp2515.Clock8MHz)
|
err := can.Begin(mcp2515.CAN500kBps, mcp2515.Clock8MHz)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
failMessage(err.Error())
|
failMessage(err.Error())
|
||||||
|
|||||||
+45
-41
@@ -6,6 +6,7 @@
|
|||||||
package mcp2515 // import "tinygo.org/x/drivers/mcp2515"
|
package mcp2515 // import "tinygo.org/x/drivers/mcp2515"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
@@ -15,15 +16,30 @@ import (
|
|||||||
"tinygo.org/x/drivers/internal/pin"
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrNothingIsReceived = errors.New("readMsg: nothing is received")
|
||||||
|
ErrRequestNewModeMaxTimeEx = errors.New("requestNewMode max time expired")
|
||||||
|
ErrLengthIsLongerThanCapacity = errors.New("length is longer than capacity")
|
||||||
|
ErrTxTimeout = errors.New("Tx: Tx timeout")
|
||||||
|
ErrInvalidDirection = errors.New("invalid direction")
|
||||||
|
ErrInvalidParameter = errors.New("invalid parameter")
|
||||||
|
ErrCannotExpandBuffer = errors.New("cannot expand buffer (to avoid memory allocation)")
|
||||||
|
)
|
||||||
|
|
||||||
// Device wraps MCP2515 SPI CAN Module.
|
// Device wraps MCP2515 SPI CAN Module.
|
||||||
type Device struct {
|
type Device struct {
|
||||||
spi SPI
|
spi SPI
|
||||||
cs pin.OutputFunc
|
cs pin.OutputFunc
|
||||||
msg *CANMsg
|
msg *CANMsg
|
||||||
|
extended bool
|
||||||
mcpMode byte
|
mcpMode byte
|
||||||
configurePins func()
|
configurePins func()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Configuration struct {
|
||||||
|
Extended bool
|
||||||
|
}
|
||||||
|
|
||||||
// CANMsg stores CAN message fields.
|
// CANMsg stores CAN message fields.
|
||||||
type CANMsg struct {
|
type CANMsg struct {
|
||||||
ID uint32
|
ID uint32
|
||||||
@@ -56,10 +72,11 @@ func New(b drivers.SPI, csPin pin.Output) *Device {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Configure sets up the device for communication.
|
// Configure sets up the device for communication.
|
||||||
func (d *Device) Configure() {
|
func (d *Device) Configure(cfg Configuration) {
|
||||||
if d.configurePins == nil {
|
if d.configurePins == nil {
|
||||||
panic(legacy.ErrConfigBeforeInstantiated)
|
panic(legacy.ErrConfigBeforeInstantiated)
|
||||||
}
|
}
|
||||||
|
d.extended = cfg.Extended
|
||||||
d.configurePins()
|
d.configurePins()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,9 +134,13 @@ func (d *Device) Tx(canid uint32, dlc uint8, data []byte) error {
|
|||||||
timeoutCount++
|
timeoutCount++
|
||||||
}
|
}
|
||||||
if timeoutCount == timeoutvalue {
|
if timeoutCount == timeoutvalue {
|
||||||
return fmt.Errorf("Tx: Tx timeout")
|
return ErrTxTimeout
|
||||||
}
|
}
|
||||||
err = d.writeCANMsg(bufNum, canid, 0, 0, dlc, data)
|
ext := byte(0)
|
||||||
|
if d.extended {
|
||||||
|
ext = 1
|
||||||
|
}
|
||||||
|
err = d.writeCANMsg(bufNum, canid, ext, 0, dlc, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -389,7 +410,7 @@ func (d *Device) configRate(speed, clock byte) error {
|
|||||||
set = false
|
set = false
|
||||||
}
|
}
|
||||||
if !set {
|
if !set {
|
||||||
return errors.New("invalid parameter")
|
return ErrInvalidParameter
|
||||||
}
|
}
|
||||||
if err := d.setRegister(mcpCNF1, cfg1); err != nil {
|
if err := d.setRegister(mcpCNF1, cfg1); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -449,7 +470,7 @@ func (d *Device) readMsg() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("readMsg: nothing is received")
|
return ErrNothingIsReceived
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -556,39 +577,22 @@ func (d *Device) writeCANMsg(bufNum uint8, canid uint32, ext, rtrBit, dlc uint8,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *SPI) setTxBufData(canid uint32, ext, rtrBit, dlc uint8, data []byte) error {
|
func (s *SPI) setTxBufData(canid uint32, ext, rtrBit, dlc uint8, data []byte) error {
|
||||||
canid = canid & 0x0FFFF
|
var id [4]byte
|
||||||
if ext == 1 {
|
if ext == 1 {
|
||||||
// TODO: add Extended ID
|
canid = canid & extidBottom29Mask
|
||||||
err := s.setTxData(0)
|
extended_id := canid
|
||||||
if err != nil {
|
high_11 := extended_id & extidTop11WriteMask
|
||||||
return err
|
low_18 := extended_id & extidBottom18Mask
|
||||||
}
|
high_11 <<= 3
|
||||||
err = s.setTxData(0)
|
extended_id_shifted := high_11 | low_18
|
||||||
if err != nil {
|
canid = extended_id_shifted | extidFlagMask
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = s.setTxData(0)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = s.setTxData(0)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
err := s.setTxData(byte(canid >> 3))
|
canid = canid & stdidBottom11Mask
|
||||||
if err != nil {
|
canid <<= 16 + 5
|
||||||
return err
|
}
|
||||||
}
|
binary.BigEndian.PutUint32(id[:], canid)
|
||||||
err = s.setTxData(byte((canid & 0x07) << 5))
|
for _, b := range id {
|
||||||
if err != nil {
|
err := s.setTxData(b)
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = s.setTxData(0)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = s.setTxData(0)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -785,7 +789,7 @@ func (d *Device) requestNewMode(newMode byte) error {
|
|||||||
if r&modeMask == newMode {
|
if r&modeMask == newMode {
|
||||||
return nil
|
return nil
|
||||||
} else if e := time.Now(); e.Sub(s) > 200*time.Millisecond {
|
} else if e := time.Now(); e.Sub(s) > 200*time.Millisecond {
|
||||||
return errors.New("requestNewMode max time expired")
|
return ErrRequestNewModeMaxTimeEx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -861,23 +865,23 @@ func (s *SPI) clearBuffer(dir int) error { return s.setBufferLength(0, dir) }
|
|||||||
func (s *SPI) setBufferLength(length int, dir int) error {
|
func (s *SPI) setBufferLength(length int, dir int) error {
|
||||||
if dir == tx {
|
if dir == tx {
|
||||||
if length > cap(s.tx) {
|
if length > cap(s.tx) {
|
||||||
return fmt.Errorf("length is longer than capacity")
|
return ErrLengthIsLongerThanCapacity
|
||||||
}
|
}
|
||||||
s.tx = s.tx[:length]
|
s.tx = s.tx[:length]
|
||||||
} else if dir == rx {
|
} else if dir == rx {
|
||||||
if length > cap(s.rx) {
|
if length > cap(s.rx) {
|
||||||
return fmt.Errorf("length is longer than capacity")
|
return ErrLengthIsLongerThanCapacity
|
||||||
}
|
}
|
||||||
s.rx = s.rx[:length]
|
s.rx = s.rx[:length]
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("invalid direction")
|
return ErrInvalidDirection
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SPI) setTxData(data byte) error {
|
func (s *SPI) setTxData(data byte) error {
|
||||||
if len(s.tx) >= bufferSize {
|
if len(s.tx) >= bufferSize {
|
||||||
return fmt.Errorf("cannot expand buffer (to avoid memory allocation)")
|
return ErrCannotExpandBuffer
|
||||||
}
|
}
|
||||||
s.tx = append(s.tx, data)
|
s.tx = append(s.tx, data)
|
||||||
|
|
||||||
|
|||||||
@@ -417,4 +417,11 @@ const (
|
|||||||
canFail = 0xff
|
canFail = 0xff
|
||||||
|
|
||||||
canMaxCharInMessage = 8
|
canMaxCharInMessage = 8
|
||||||
|
|
||||||
|
// for extended id
|
||||||
|
extidTop11WriteMask = 0x1FFC0000
|
||||||
|
extidBottom29Mask = (1 << 29) - 1 // extended id bits
|
||||||
|
extidBottom18Mask = (1 << 18) - 1 // bottom 18 bits
|
||||||
|
stdidBottom11Mask = 0x7FF
|
||||||
|
extidFlagMask = 1 << 19
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user