mfrc522: improvements to gain and wait (#297)

- Antenna Gain
- Terminating Wait if Halt received
- Renamed SetOperationtimeout to SetOperationTimeout
pull/1/head
Vlad Korniev 8 years ago committed by M-A
parent d3144fa1d2
commit 93d2236e21

@ -11,6 +11,7 @@ package mfrc522
import ( import (
"fmt" "fmt"
"sync"
"time" "time"
"periph.io/x/periph/conn" "periph.io/x/periph/conn"
@ -119,6 +120,8 @@ func NewSPI(spiPort spi.Port, resetPin gpio.PinOut, irqPin gpio.PinIn) (*Dev, er
operationTimeout: 30 * time.Second, operationTimeout: 30 * time.Second,
irqPin: irqPin, irqPin: irqPin,
resetPin: resetPin, resetPin: resetPin,
antennaGain: 4,
stop: make(chan struct{}, 1),
} }
if err := dev.Init(); err != nil { if err := dev.Init(); err != nil {
return nil, err return nil, err
@ -132,6 +135,13 @@ type Dev struct {
irqPin gpio.PinIn irqPin gpio.PinIn
operationTimeout time.Duration operationTimeout time.Duration
spiDev spi.Conn spiDev spi.Conn
stop chan struct{}
aMu sync.Mutex
antennaGain int
mu sync.Mutex
isWaiting bool
} }
// String implements conn.Resource. // String implements conn.Resource.
@ -144,16 +154,28 @@ func (r *Dev) String() string {
// //
// It soft-stops the chip - PowerDown bit set, command IDLE // It soft-stops the chip - PowerDown bit set, command IDLE
func (r *Dev) Halt() error { func (r *Dev) Halt() error {
r.mu.Lock()
defer r.mu.Unlock()
if r.isWaiting {
select {
case <-r.stop:
default:
}
r.stop <- struct{}{}
}
return r.devWrite(commands.CommandReg, 16) return r.devWrite(commands.CommandReg, 16)
} }
// SetOperationtimeout updates the device timeout for card operations. // SetOperationTimeout updates the device timeout for card operations.
// //
// Effectively that sets the maximum time the RFID device will wait for IRQ // Effectively that sets the maximum time the RFID device will wait for IRQ
// from the proximity card detection. // from the proximity card detection.
// //
// timeout the duration to wait for IRQ strobe. // timeout the duration to wait for IRQ strobe.
func (r *Dev) SetOperationtimeout(timeout time.Duration) { func (r *Dev) SetOperationTimeout(timeout time.Duration) {
r.operationTimeout = timeout r.operationTimeout = timeout
} }
@ -165,6 +187,15 @@ func (r *Dev) Init() error {
if err := r.writeCommandSequence(sequenceCommands.init); err != nil { if err := r.writeCommandSequence(sequenceCommands.init); err != nil {
return err return err
} }
r.aMu.Lock()
gain := byte(r.antennaGain)<<4
r.aMu.Unlock()
if err := r.devWrite(int(commands.RFCfgReg), gain); err != nil {
return err
}
return r.SetAntenna(true) return r.SetAntenna(true)
} }
@ -188,6 +219,18 @@ func (r *Dev) SetAntenna(state bool) error {
return r.clearBitmask(commands.TxControlReg, 0x03) return r.clearBitmask(commands.TxControlReg, 0x03)
} }
// SetAntennaGain configures antenna signal strength.
//
// gain - signal strength from 0 to 7.
func (r *Dev) SetAntennaGain(gain int) {
r.aMu.Lock()
defer r.aMu.Unlock()
if 0 <= gain && gain <= 7 {
r.antennaGain = gain
}
}
// CardWrite the low-level interface to write some raw commands to the card. // CardWrite the low-level interface to write some raw commands to the card.
// //
// command - the command register // command - the command register
@ -321,12 +364,35 @@ func (r *Dev) Request() (int, error) {
// Wait wait for IRQ to strobe on the IRQ pin when the card is detected. // Wait wait for IRQ to strobe on the IRQ pin when the card is detected.
func (r *Dev) Wait() error { func (r *Dev) Wait() error {
r.mu.Lock()
waitCancelled := false
if r.isWaiting {
r.mu.Unlock()
return wrapf("concurrent access is forbidden")
}
r.isWaiting = true
r.mu.Unlock()
irqChannel := make(chan bool) irqChannel := make(chan bool)
go func() { go func() {
irqChannel <- r.irqPin.WaitForEdge(r.operationTimeout) result := r.irqPin.WaitForEdge(r.operationTimeout)
r.mu.Lock()
defer r.mu.Unlock()
if waitCancelled {
return
}
irqChannel <- result
}() }()
defer func() { defer func() {
r.mu.Lock()
r.isWaiting = false
waitCancelled = true
r.mu.Unlock()
close(irqChannel) close(irqChannel)
}() }()
@ -342,6 +408,8 @@ func (r *Dev) Wait() error {
return err return err
} }
select { select {
case <-r.stop:
return wrapf("halt")
case irqResult := <-irqChannel: case irqResult := <-irqChannel:
if !irqResult { if !irqResult {
return wrapf("timeout waitinf for IRQ edge: %v", r.operationTimeout) return wrapf("timeout waitinf for IRQ edge: %v", r.operationTimeout)

Loading…
Cancel
Save