Documentation ¶
Overview ¶
Package mfrc522 controls a Mifare RFID card reader.
Datasheet ¶
https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf
Package mfrc522 controls a Mifare RFID card reader.
Datasheet ¶
https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf
Example ¶
// Make sure periph is initialized. if _, err := host.Init(); err != nil { log.Fatal(err) } // Using SPI as an example. See package "periph.io/x/conn/v3/spi/spireg" for more details. p, err := spireg.Open("") if err != nil { log.Fatal(err) } defer p.Close() rfid, err := mfrc522.NewSPI(p, rpi.P1_13, rpi.P1_11) if err != nil { log.Fatal(err) } // Idling device on exit. defer rfid.Halt() // Setting the antenna signal strength. rfid.SetAntennaGain(5) // Converting access key. // This value corresponds to first pi "numbers": 3 14 15 92 65 35. hexKey, _ := hex.DecodeString("030e0f5c4123") var key [6]byte copy(key[:], hexKey) // Converting expected data. // This value corresponds to string "@~>f=Um[X{LRwA3}". expected, _ := hex.DecodeString("407e3e663d556d5b587b4c527741337d") timedOut := false cb := make(chan []byte) timer := time.NewTimer(10 * time.Second) // Stopping timer, flagging reader thread as timed out defer func() { timer.Stop() timedOut = true close(cb) }() go func() { log.Printf("Started %s", rfid.String()) for { // Trying to read data from sector 1 block 0 data, err := rfid.ReadCard(10*time.Second, byte(commands.PICC_AUTHENT1B), 1, 0, key) // If main thread timed out just exiting. if timedOut { return } // Some devices tend to send wrong data while RFID chip is already detected // but still "too far" from a receiver. // Especially some cheap CN clones which you can find on GearBest, AliExpress, etc. // This will suppress such errors. if err != nil { continue } cb <- data } }() for { select { case <-timer.C: log.Fatal("Didn't receive device data") return case data := <-cb: if !reflect.DeepEqual(data, expected) { log.Fatal("Received data is incorrect") } else { log.Println("Received data is correct") } return } }
Output:
Index ¶
- Variables
- func WithBogusUID() configF
- func WithSync() configF
- func WithTimeout(timeout time.Duration) configF
- type BlockAccess
- type BlocksAccess
- type Dev
- func (r *Dev) Halt() error
- func (r *Dev) ReadAuth(timeout time.Duration, auth byte, sector int, key Key) (data []byte, err error)
- func (r *Dev) ReadCard(timeout time.Duration, auth byte, sector int, block int, key Key) (data []byte, err error)
- func (r *Dev) ReadUID(timeout time.Duration) (uid []byte, err error)
- func (r *Dev) SetAntennaGain(gain int) error
- func (r *Dev) String() string
- func (r *Dev) WriteCard(timeout time.Duration, auth byte, sector int, block int, data [16]byte, ...) (err error)
- func (r *Dev) WriteSectorTrail(timeout time.Duration, auth byte, sector int, keyA Key, keyB Key, ...) (err error)
- type Key
- type SectorTrailerAccess
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var DefaultKey = Key{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
DefaultKey provides the default bytes for card authentication for method B.
Functions ¶
func WithBogusUID ¶ added in v3.6.13
func WithBogusUID() configF
WithBogusUID sets the card reader to return incorrect 4-byte UIDs. In version 3.6.12 and earlier this package ruturned 5-bytes for tags with a 4-byte UID with bytes 0 to 3 being the correct UID and byte 4 being an XOR of bytes 0 to 3. 7-byte UIDs are correct regardless of this configuration.
func WithSync ¶
func WithSync() configF
WithSync sets the synchronization for the entire device, using internal mutex.
func WithTimeout ¶
WithTimeout updates the default device-wide configuration timeout.
Types ¶
type BlockAccess ¶
type BlockAccess byte
BlockAccess defines the block access bits.
const ( AnyKeyRWID BlockAccess = 0x0 // Any key (A or B) can read, write, increment and decrement block. RAB_WN_IN_DN BlockAccess = 0x02 // Read (A or B), Write (None), Increment (None), Decrement (None) RAB_WB_IN_DN BlockAccess = 0x04 // Read (A orB), Write (B), Increment (None), Decrement (None) RAB_WB_IB_DAB BlockAccess = 0x06 // Read (A or B), Write (B), Icrement (B), Decrement (A or B) RAB_WN_IN_DAB BlockAccess = 0x01 // Read (A or B), Write (None), Increment (None), Decrment (A or B) RB_WB_IN_DN BlockAccess = 0x03 // Read (B), Write (B), Increment (None), Decrement (None) RB_WN_IN_DN BlockAccess = 0x05 // Read (B), Write (None), Increment (None), Decrement (None) RN_WN_IN_DN BlockAccess = 0x07 // Read (None), Write (None), Increment (None), Decrement (None) )
Access bits for the sector data.
type BlocksAccess ¶
type BlocksAccess struct {
B0, B1, B2 BlockAccess
B3 SectorTrailerAccess
}
BlocksAccess defines the access structure for first 3 blocks of the sector and the access bits for the sector trail.
func (*BlocksAccess) Init ¶
func (ba *BlocksAccess) Init(ad []byte)
Init parses the given byte array into the block access structure.
func (*BlocksAccess) String ¶
func (ba *BlocksAccess) String() string
type Dev ¶
Dev is an handle to an MFRC522 RFID reader.
func NewSPI ¶
func NewSPI(spiPort spi.Port, resetPin gpio.PinOut, irqPin gpio.PinIn, configs ...configF) (*Dev, error)
NewSPI creates and initializes the RFID card reader attached to SPI.
spiPort the SPI device to use. resetPin reset GPIO pin. irqPin irq GPIO pin. configs configuration options
func (*Dev) Halt ¶
Halt implements conn.Resource.
It soft-stops the chip - PowerDown bit set, command IDLE
func (*Dev) ReadAuth ¶
func (r *Dev) ReadAuth(timeout time.Duration, auth byte, sector int, key Key) (data []byte, err error)
ReadAuth reads the card authentication data with IRQ event timeout.
timeout the operation timeout auth authentication type sector the sector to authenticate on. key the key to be used for accessing the sector data.
func (*Dev) ReadCard ¶
func (r *Dev) ReadCard(timeout time.Duration, auth byte, sector int, block int, key Key) (data []byte, err error)
ReadCard reads the card sector/block with IRQ event timeout.
timeout the operation timeout auth the authentication mode. sector the sector to authenticate on. block the block within sector to authenticate. key the key to be used for accessing the sector data.
func (*Dev) ReadUID ¶
ReadUID reads the 4-byte or 7-byte card UID with IRQ event timeout.
timeout the operation timeout
Example ¶
// Make sure periph is initialized. if _, err := host.Init(); err != nil { log.Fatal(err) } // Using SPI as an example. See package "periph.io/x/conn/v3/spi/spireg" for more details. p, err := spireg.Open("") if err != nil { log.Fatal(err) } defer p.Close() rfid, err := mfrc522.NewSPI(p, rpi.P1_22, rpi.P1_18) if err != nil { log.Fatal(err) } // Idling device on exit. defer rfid.Halt() // Setting the antenna signal strength. rfid.SetAntennaGain(5) timedOut := false cb := make(chan []byte) timer := time.NewTimer(10 * time.Second) // Stopping timer, flagging reader thread as timed out defer func() { timer.Stop() timedOut = true close(cb) }() go func() { log.Printf("Started %s", rfid.String()) for { // Trying to read card UID. uid, err := rfid.ReadUID(10 * time.Second) // If main thread timed out just exiting. if timedOut { return } // Some devices tend to send wrong data while RFID chip is already detected // but still "too far" from a receiver. // Especially some cheap CN clones which you can find on GearBest, AliExpress, etc. // This will suppress such errors. if err != nil { continue } cb <- uid return } }() for { select { case <-timer.C: log.Fatal("Didn't receive device data") return case data := <-cb: log.Println("UID:", hex.EncodeToString(data)) return } }
Output:
func (*Dev) SetAntennaGain ¶
SetAntennaGain configures antenna signal strength.
gain signal strength from 0 to 7.
func (*Dev) WriteCard ¶
func (r *Dev) WriteCard(timeout time.Duration, auth byte, sector int, block int, data [16]byte, key Key) (err error)
WriteCard writes the data into the card block with IRQ event timeout.
timeout the operation timeout auth the authentiction mode. sector the sector on the card to write to. block the block within the sector to write into. data 16 bytes if data to write key the key used to authenticate the card - depends on the used auth method.
func (*Dev) WriteSectorTrail ¶
func (r *Dev) WriteSectorTrail(timeout time.Duration, auth byte, sector int, keyA Key, keyB Key, access *BlocksAccess, key Key) (err error)
WriteSectorTrail writes the sector trail with sector access bits with IRQ event timeout.
timeout operation timeout auth authentication mode. sector sector to set authentication. keyA the key used for AuthA authentication scheme. keyB the key used for AuthB authentication scheme. access the block access structure. key the current key used to authenticate the provided sector.
type Key ¶
type Key [6]byte
Key is the access key that consists of 6 bytes. There could be two types of keys - keyA and keyB. KeyA and KeyB correspond to the different sector trail and data access. Refer to the datasheet for more details.
type SectorTrailerAccess ¶
type SectorTrailerAccess byte
SectorTrailerAccess defines the sector trailing block access bits.
const ( KeyA_RN_WA_BITS_RA_WN_KeyB_RA_WA SectorTrailerAccess = 0x0 KeyA_RN_WN_BITS_RA_WN_KeyB_RA_WN SectorTrailerAccess = 0x02 KeyA_RN_WB_BITS_RAB_WN_KeyB_RN_WB SectorTrailerAccess = 0x04 KeyA_RN_WN_BITS_RAB_WN_KeyB_RN_WN SectorTrailerAccess = 0x06 KeyA_RN_WA_BITS_RA_WA_KeyB_RA_WA SectorTrailerAccess = 0x01 KeyA_RN_WB_BITS_RAB_WB_KeyB_RN_WB SectorTrailerAccess = 0x03 KeyA_RN_WN_BITS_RAB_WB_KeyB_RN_WN SectorTrailerAccess = 0x05 KeyA_RN_WN_BITS_RAB_WN_KeyB_RN_WN_EXTRA SectorTrailerAccess = 0x07 )
Access bits for the sector trail. Every trail sector has the options for controlling the access to the trailing sector bits. For example :
KeyA_R[Key]_W[Key]_BITS_R[Key]_W[Key]_KeyB_R[Key]_W[Key] - KeyA - could be Read by providing [Key] ( where [Key] could be KeyA or KeyB ) - could be Written by Providing [Key] ( where [Key] is KeyA or KeyB ) - access bits for the sector data (see above) - could be Read by providing [Key] ( where [Key] could be KeyA or KeyB ) - could be Written by Providing [Key] ( where [Key] is KeyA or KeyB ) - KeyB - could be Read by providing [Key] ( where [Key] could be KeyA or KeyB ) - could be Written by Providing [Key] ( where [Key] is KeyA or KeyB ) example: KeyA_RN_WA_BITS_RA_WA_KeyB_RA_WA means - KeyA could not be read but could be overwriten if KeyA is provided - Access bits could be read and overwritten if KeyA is provided during the card authentication - KeyB could be read and overriten if KeyA is provided during the card authentication more on the matter: https://www.nxp.com/docs/en/data-sheet/MF1S50YYX_V1.pdf