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 (
"fmt"
"sync"
"time"
"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,
irqPin: irqPin,
resetPin: resetPin,
antennaGain: 4,
stop: make(chan struct{}, 1),
}
if err := dev.Init(); err != nil {
return nil, err
@ -132,6 +135,13 @@ type Dev struct {
irqPin gpio.PinIn
operationTimeout time.Duration
spiDev spi.Conn
stop chan struct{}
aMu sync.Mutex
antennaGain int
mu sync.Mutex
isWaiting bool
}
// String implements conn.Resource.
@ -144,16 +154,28 @@ func (r *Dev) String() string {
//
// It soft-stops the chip - PowerDown bit set, command IDLE
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)
}
// 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
// from the proximity card detection.
//
// 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
}
@ -165,6 +187,15 @@ func (r *Dev) Init() error {
if err := r.writeCommandSequence(sequenceCommands.init); err != nil {
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)
}
@ -188,6 +219,18 @@ func (r *Dev) SetAntenna(state bool) error {
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.
//
// 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.
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)
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() {
r.mu.Lock()
r.isWaiting = false
waitCancelled = true
r.mu.Unlock()
close(irqChannel)
}()
@ -342,6 +408,8 @@ func (r *Dev) Wait() error {
return err
}
select {
case <-r.stop:
return wrapf("halt")
case irqResult := <-irqChannel:
if !irqResult {
return wrapf("timeout waitinf for IRQ edge: %v", r.operationTimeout)

Loading…
Cancel
Save