├── .gitignore
├── LICENSE
├── README.md
├── mfrc522
├── MFRC522.py
├── SimpleMFRC522.py
└── __init__.py
└── setup.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled python modules.
2 | *.pyc
3 |
4 | # Setuptools distribution folder.
5 | /dist/
6 |
7 | # Python egg metadata, regenerated from source files by setuptools.
8 | /*.egg-info
9 |
10 | # Build folder
11 | /build/
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # mfrc522
2 |
3 | A python library to read/write RFID tags via the budget MFRC522 RFID module.
4 |
5 | This code was published in relation to a [blog post](https://pimylifeup.com/raspberry-pi-rfid-rc522/) and you can find out more about how to hook up your MFRC reader to a Raspberry Pi there.
6 |
7 | ## Installation
8 |
9 | Until the package is on PyPi, clone this repository and run `python setup.py install` in the top level directory.
10 |
11 | ## Example Code
12 |
13 | The following code will read a tag from the MFRC522
14 |
15 | ```python
16 | from time import sleep
17 | import sys
18 | from mfrc522 import SimpleMFRC522
19 | reader = SimpleMFRC522()
20 |
21 | try:
22 | while True:
23 | print("Hold a tag near the reader")
24 | id, text = reader.read()
25 | print("ID: %s\nText: %s" % (id,text))
26 | sleep(5)
27 | except KeyboardInterrupt:
28 | GPIO.cleanup()
29 | raise
30 | ```
31 |
--------------------------------------------------------------------------------
/mfrc522/MFRC522.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf8 -*-
3 | #
4 | # Copyright 2014,2018 Mario Gomez
5 | #
6 | # This file is part of MFRC522-Python
7 | # MFRC522-Python is a simple Python implementation for
8 | # the MFRC522 NFC Card Reader for the Raspberry Pi.
9 | #
10 | # MFRC522-Python is free software: you can redistribute it and/or modify
11 | # it under the terms of the GNU Lesser General Public License as published by
12 | # the Free Software Foundation, either version 3 of the License, or
13 | # (at your option) any later version.
14 | #
15 | # MFRC522-Python is distributed in the hope that it will be useful,
16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | # GNU Lesser General Public License for more details.
19 | #
20 | # You should have received a copy of the GNU Lesser General Public License
21 | # along with MFRC522-Python. If not, see .
22 | #
23 | import RPi.GPIO as GPIO
24 | import spidev
25 | import signal
26 | import time
27 | import logging
28 |
29 | class MFRC522:
30 | MAX_LEN = 16
31 |
32 | PCD_IDLE = 0x00
33 | PCD_AUTHENT = 0x0E
34 | PCD_RECEIVE = 0x08
35 | PCD_TRANSMIT = 0x04
36 | PCD_TRANSCEIVE = 0x0C
37 | PCD_RESETPHASE = 0x0F
38 | PCD_CALCCRC = 0x03
39 |
40 | PICC_REQIDL = 0x26
41 | PICC_REQALL = 0x52
42 | PICC_ANTICOLL = 0x93
43 | PICC_SElECTTAG = 0x93
44 | PICC_AUTHENT1A = 0x60
45 | PICC_AUTHENT1B = 0x61
46 | PICC_READ = 0x30
47 | PICC_WRITE = 0xA0
48 | PICC_DECREMENT = 0xC0
49 | PICC_INCREMENT = 0xC1
50 | PICC_RESTORE = 0xC2
51 | PICC_TRANSFER = 0xB0
52 | PICC_HALT = 0x50
53 |
54 | MI_OK = 0
55 | MI_NOTAGERR = 1
56 | MI_ERR = 2
57 |
58 | Reserved00 = 0x00
59 | CommandReg = 0x01
60 | CommIEnReg = 0x02
61 | DivlEnReg = 0x03
62 | CommIrqReg = 0x04
63 | DivIrqReg = 0x05
64 | ErrorReg = 0x06
65 | Status1Reg = 0x07
66 | Status2Reg = 0x08
67 | FIFODataReg = 0x09
68 | FIFOLevelReg = 0x0A
69 | WaterLevelReg = 0x0B
70 | ControlReg = 0x0C
71 | BitFramingReg = 0x0D
72 | CollReg = 0x0E
73 | Reserved01 = 0x0F
74 |
75 | Reserved10 = 0x10
76 | ModeReg = 0x11
77 | TxModeReg = 0x12
78 | RxModeReg = 0x13
79 | TxControlReg = 0x14
80 | TxAutoReg = 0x15
81 | TxSelReg = 0x16
82 | RxSelReg = 0x17
83 | RxThresholdReg = 0x18
84 | DemodReg = 0x19
85 | Reserved11 = 0x1A
86 | Reserved12 = 0x1B
87 | MifareReg = 0x1C
88 | Reserved13 = 0x1D
89 | Reserved14 = 0x1E
90 | SerialSpeedReg = 0x1F
91 |
92 | Reserved20 = 0x20
93 | CRCResultRegM = 0x21
94 | CRCResultRegL = 0x22
95 | Reserved21 = 0x23
96 | ModWidthReg = 0x24
97 | Reserved22 = 0x25
98 | RFCfgReg = 0x26
99 | GsNReg = 0x27
100 | CWGsPReg = 0x28
101 | ModGsPReg = 0x29
102 | TModeReg = 0x2A
103 | TPrescalerReg = 0x2B
104 | TReloadRegH = 0x2C
105 | TReloadRegL = 0x2D
106 | TCounterValueRegH = 0x2E
107 | TCounterValueRegL = 0x2F
108 |
109 | Reserved30 = 0x30
110 | TestSel1Reg = 0x31
111 | TestSel2Reg = 0x32
112 | TestPinEnReg = 0x33
113 | TestPinValueReg = 0x34
114 | TestBusReg = 0x35
115 | AutoTestReg = 0x36
116 | VersionReg = 0x37
117 | AnalogTestReg = 0x38
118 | TestDAC1Reg = 0x39
119 | TestDAC2Reg = 0x3A
120 | TestADCReg = 0x3B
121 | Reserved31 = 0x3C
122 | Reserved32 = 0x3D
123 | Reserved33 = 0x3E
124 | Reserved34 = 0x3F
125 |
126 | serNum = []
127 |
128 | def __init__(self, bus=0, device=0, spd=1000000, pin_mode=10, pin_rst=-1, debugLevel='WARNING'):
129 | self.spi = spidev.SpiDev()
130 | self.spi.open(bus, device)
131 | self.spi.max_speed_hz = spd
132 |
133 | self.logger = logging.getLogger('mfrc522Logger')
134 | self.logger.addHandler(logging.StreamHandler())
135 | level = logging.getLevelName(debugLevel)
136 | self.logger.setLevel(level)
137 |
138 | gpioMode = GPIO.getmode()
139 |
140 | if gpioMode is None:
141 | GPIO.setmode(pin_mode)
142 | else:
143 | pin_mode = gpioMode
144 |
145 | if pin_rst == -1:
146 | if pin_mode == 11:
147 | pin_rst = 15
148 | else:
149 | pin_rst = 22
150 |
151 | GPIO.setup(pin_rst, GPIO.OUT)
152 | GPIO.output(pin_rst, 1)
153 | self.MFRC522_Init()
154 |
155 | def MFRC522_Reset(self):
156 | self.Write_MFRC522(self.CommandReg, self.PCD_RESETPHASE)
157 |
158 | def Write_MFRC522(self, addr, val):
159 | val = self.spi.xfer2([(addr << 1) & 0x7E, val])
160 |
161 | def Read_MFRC522(self, addr):
162 | val = self.spi.xfer2([((addr << 1) & 0x7E) | 0x80, 0])
163 | return val[1]
164 |
165 | def Close_MFRC522(self):
166 | self.spi.close()
167 | GPIO.cleanup()
168 |
169 | def SetBitMask(self, reg, mask):
170 | tmp = self.Read_MFRC522(reg)
171 | self.Write_MFRC522(reg, tmp | mask)
172 |
173 | def ClearBitMask(self, reg, mask):
174 | tmp = self.Read_MFRC522(reg)
175 | self.Write_MFRC522(reg, tmp & (~mask))
176 |
177 | def AntennaOn(self):
178 | temp = self.Read_MFRC522(self.TxControlReg)
179 | if (~(temp & 0x03)):
180 | self.SetBitMask(self.TxControlReg, 0x03)
181 |
182 | def AntennaOff(self):
183 | self.ClearBitMask(self.TxControlReg, 0x03)
184 |
185 | def MFRC522_ToCard(self, command, sendData):
186 | backData = []
187 | backLen = 0
188 | status = self.MI_ERR
189 | irqEn = 0x00
190 | waitIRq = 0x00
191 | lastBits = None
192 | n = 0
193 |
194 | if command == self.PCD_AUTHENT:
195 | irqEn = 0x12
196 | waitIRq = 0x10
197 | if command == self.PCD_TRANSCEIVE:
198 | irqEn = 0x77
199 | waitIRq = 0x30
200 |
201 | self.Write_MFRC522(self.CommIEnReg, irqEn | 0x80)
202 | self.ClearBitMask(self.CommIrqReg, 0x80)
203 | self.SetBitMask(self.FIFOLevelReg, 0x80)
204 |
205 | self.Write_MFRC522(self.CommandReg, self.PCD_IDLE)
206 |
207 | for i in range(len(sendData)):
208 | self.Write_MFRC522(self.FIFODataReg, sendData[i])
209 |
210 | self.Write_MFRC522(self.CommandReg, command)
211 |
212 | if command == self.PCD_TRANSCEIVE:
213 | self.SetBitMask(self.BitFramingReg, 0x80)
214 |
215 | i = 2000
216 | while True:
217 | n = self.Read_MFRC522(self.CommIrqReg)
218 | i -= 1
219 | if ~((i != 0) and ~(n & 0x01) and ~(n & waitIRq)):
220 | break
221 |
222 | self.ClearBitMask(self.BitFramingReg, 0x80)
223 |
224 | if i != 0:
225 | if (self.Read_MFRC522(self.ErrorReg) & 0x1B) == 0x00:
226 | status = self.MI_OK
227 |
228 | if n & irqEn & 0x01:
229 | status = self.MI_NOTAGERR
230 |
231 | if command == self.PCD_TRANSCEIVE:
232 | n = self.Read_MFRC522(self.FIFOLevelReg)
233 | lastBits = self.Read_MFRC522(self.ControlReg) & 0x07
234 | if lastBits != 0:
235 | backLen = (n - 1) * 8 + lastBits
236 | else:
237 | backLen = n * 8
238 |
239 | if n == 0:
240 | n = 1
241 | if n > self.MAX_LEN:
242 | n = self.MAX_LEN
243 |
244 | for i in range(n):
245 | backData.append(self.Read_MFRC522(self.FIFODataReg))
246 | else:
247 | status = self.MI_ERR
248 |
249 | return (status, backData, backLen)
250 |
251 | def MFRC522_Request(self, reqMode):
252 | status = None
253 | backBits = None
254 | TagType = []
255 |
256 | self.Write_MFRC522(self.BitFramingReg, 0x07)
257 |
258 | TagType.append(reqMode)
259 | (status, backData, backBits) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, TagType)
260 |
261 | if ((status != self.MI_OK) | (backBits != 0x10)):
262 | status = self.MI_ERR
263 |
264 | return (status, backBits)
265 |
266 | def MFRC522_Anticoll(self):
267 | backData = []
268 | serNumCheck = 0
269 |
270 | serNum = []
271 |
272 | self.Write_MFRC522(self.BitFramingReg, 0x00)
273 |
274 | serNum.append(self.PICC_ANTICOLL)
275 | serNum.append(0x20)
276 |
277 | (status, backData, backBits) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, serNum)
278 |
279 | if (status == self.MI_OK):
280 | i = 0
281 | if len(backData) == 5:
282 | for i in range(4):
283 | serNumCheck = serNumCheck ^ backData[i]
284 | if serNumCheck != backData[4]:
285 | status = self.MI_ERR
286 | else:
287 | status = self.MI_ERR
288 |
289 | return (status, backData)
290 |
291 | def CalulateCRC(self, pIndata):
292 | self.ClearBitMask(self.DivIrqReg, 0x04)
293 | self.SetBitMask(self.FIFOLevelReg, 0x80)
294 |
295 | for i in range(len(pIndata)):
296 | self.Write_MFRC522(self.FIFODataReg, pIndata[i])
297 |
298 | self.Write_MFRC522(self.CommandReg, self.PCD_CALCCRC)
299 | i = 0xFF
300 | while True:
301 | n = self.Read_MFRC522(self.DivIrqReg)
302 | i -= 1
303 | if not ((i != 0) and not (n & 0x04)):
304 | break
305 | pOutData = []
306 | pOutData.append(self.Read_MFRC522(self.CRCResultRegL))
307 | pOutData.append(self.Read_MFRC522(self.CRCResultRegM))
308 | return pOutData
309 |
310 | def MFRC522_SelectTag(self, serNum):
311 | backData = []
312 | buf = []
313 | buf.append(self.PICC_SElECTTAG)
314 | buf.append(0x70)
315 |
316 | for i in range(5):
317 | buf.append(serNum[i])
318 |
319 | pOut = self.CalulateCRC(buf)
320 | buf.append(pOut[0])
321 | buf.append(pOut[1])
322 | (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buf)
323 |
324 | if (status == self.MI_OK) and (backLen == 0x18):
325 | self.logger.debug("Size: " + str(backData[0]))
326 | return backData[0]
327 | else:
328 | return 0
329 |
330 | def MFRC522_Auth(self, authMode, BlockAddr, Sectorkey, serNum):
331 | buff = []
332 |
333 | # First byte should be the authMode (A or B)
334 | buff.append(authMode)
335 |
336 | # Second byte is the trailerBlock (usually 7)
337 | buff.append(BlockAddr)
338 |
339 | # Now we need to append the authKey which usually is 6 bytes of 0xFF
340 | for i in range(len(Sectorkey)):
341 | buff.append(Sectorkey[i])
342 |
343 | # Next we append the first 4 bytes of the UID
344 | for i in range(4):
345 | buff.append(serNum[i])
346 |
347 | # Now we start the authentication itself
348 | (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_AUTHENT, buff)
349 |
350 | # Check if an error occurred
351 | if not (status == self.MI_OK):
352 | self.logger.error("AUTH ERROR!!")
353 | if not (self.Read_MFRC522(self.Status2Reg) & 0x08) != 0:
354 | self.logger.error("AUTH ERROR(status2reg & 0x08) != 0")
355 |
356 | # Return the status
357 | return status
358 |
359 | def MFRC522_StopCrypto1(self):
360 | self.ClearBitMask(self.Status2Reg, 0x08)
361 |
362 | def MFRC522_Read(self, blockAddr):
363 | recvData = []
364 | recvData.append(self.PICC_READ)
365 | recvData.append(blockAddr)
366 | pOut = self.CalulateCRC(recvData)
367 | recvData.append(pOut[0])
368 | recvData.append(pOut[1])
369 | (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, recvData)
370 | if not (status == self.MI_OK):
371 | self.logger.error("Error while reading!")
372 |
373 | if len(backData) == 16:
374 | self.logger.debug("Sector " + str(blockAddr) + " " + str(backData))
375 | return backData
376 | else:
377 | return None
378 |
379 | def MFRC522_Write(self, blockAddr, writeData):
380 | buff = []
381 | buff.append(self.PICC_WRITE)
382 | buff.append(blockAddr)
383 | crc = self.CalulateCRC(buff)
384 | buff.append(crc[0])
385 | buff.append(crc[1])
386 | (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buff)
387 | if not (status == self.MI_OK) or not (backLen == 4) or not ((backData[0] & 0x0F) == 0x0A):
388 | status = self.MI_ERR
389 |
390 | self.logger.debug("%s backdata &0x0F == 0x0A %s" % (backLen, backData[0] & 0x0F))
391 | if status == self.MI_OK:
392 | buf = []
393 | for i in range(16):
394 | buf.append(writeData[i])
395 |
396 | crc = self.CalulateCRC(buf)
397 | buf.append(crc[0])
398 | buf.append(crc[1])
399 | (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buf)
400 | if not (status == self.MI_OK) or not (backLen == 4) or not ((backData[0] & 0x0F) == 0x0A):
401 | self.logger.error("Error while writing")
402 | if status == self.MI_OK:
403 | self.logger.debug("Data written")
404 |
405 |
406 | def MFRC522_DumpClassic1K(self, key, uid):
407 | for i in range(64):
408 | status = self.MFRC522_Auth(self.PICC_AUTHENT1A, i, key, uid)
409 | # Check if authenticated
410 | if status == self.MI_OK:
411 | self.MFRC522_Read(i)
412 | else:
413 | self.logger.error("Authentication error")
414 |
415 | def MFRC522_Init(self):
416 | self.MFRC522_Reset()
417 |
418 | self.Write_MFRC522(self.TModeReg, 0x8D)
419 | self.Write_MFRC522(self.TPrescalerReg, 0x3E)
420 | self.Write_MFRC522(self.TReloadRegL, 30)
421 | self.Write_MFRC522(self.TReloadRegH, 0)
422 |
423 | self.Write_MFRC522(self.TxAutoReg, 0x40)
424 | self.Write_MFRC522(self.ModeReg, 0x3D)
425 | self.AntennaOn()
426 |
--------------------------------------------------------------------------------
/mfrc522/SimpleMFRC522.py:
--------------------------------------------------------------------------------
1 | # Code by Simon Monk https://github.com/simonmonk/
2 |
3 | from . import MFRC522
4 | import RPi.GPIO as GPIO
5 |
6 | class SimpleMFRC522:
7 |
8 | READER = None
9 |
10 | KEY = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
11 | BLOCK_ADDRS = [8, 9, 10]
12 |
13 | def __init__(self):
14 | self.READER = MFRC522()
15 |
16 | def read(self):
17 | id, text = self.read_no_block()
18 | while not id:
19 | id, text = self.read_no_block()
20 | return id, text
21 |
22 | def read_id(self):
23 | id = self.read_id_no_block()
24 | while not id:
25 | id = self.read_id_no_block()
26 | return id
27 |
28 | def read_id_no_block(self):
29 | (status, TagType) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL)
30 | if status != self.READER.MI_OK:
31 | return None
32 | (status, uid) = self.READER.MFRC522_Anticoll()
33 | if status != self.READER.MI_OK:
34 | return None
35 | return self.uid_to_num(uid)
36 |
37 | def read_no_block(self):
38 | (status, TagType) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL)
39 | if status != self.READER.MI_OK:
40 | return None, None
41 | (status, uid) = self.READER.MFRC522_Anticoll()
42 | if status != self.READER.MI_OK:
43 | return None, None
44 | id = self.uid_to_num(uid)
45 | self.READER.MFRC522_SelectTag(uid)
46 | status = self.READER.MFRC522_Auth(self.READER.PICC_AUTHENT1A, 11, self.KEY, uid)
47 | data = []
48 | text_read = ''
49 | if status == self.READER.MI_OK:
50 | for block_num in self.BLOCK_ADDRS:
51 | block = self.READER.MFRC522_Read(block_num)
52 | if block:
53 | data += block
54 | if data:
55 | text_read = ''.join(chr(i) for i in data)
56 | self.READER.MFRC522_StopCrypto1()
57 | return id, text_read
58 |
59 | def write(self, text):
60 | id, text_in = self.write_no_block(text)
61 | while not id:
62 | id, text_in = self.write_no_block(text)
63 | return id, text_in
64 |
65 | def write_no_block(self, text):
66 | (status, TagType) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL)
67 | if status != self.READER.MI_OK:
68 | return None, None
69 | (status, uid) = self.READER.MFRC522_Anticoll()
70 | if status != self.READER.MI_OK:
71 | return None, None
72 | id = self.uid_to_num(uid)
73 | self.READER.MFRC522_SelectTag(uid)
74 | status = self.READER.MFRC522_Auth(self.READER.PICC_AUTHENT1A, 11, self.KEY, uid)
75 | self.READER.MFRC522_Read(11)
76 | if status == self.READER.MI_OK:
77 | data = bytearray()
78 | data.extend(bytearray(text.ljust(len(self.BLOCK_ADDRS) * 16).encode('ascii')))
79 | i = 0
80 | for block_num in self.BLOCK_ADDRS:
81 | self.READER.MFRC522_Write(block_num, data[(i*16):(i+1)*16])
82 | i += 1
83 | self.READER.MFRC522_StopCrypto1()
84 | return id, text[0:(len(self.BLOCK_ADDRS) * 16)]
85 |
86 | def uid_to_num(self, uid):
87 | n = 0
88 | for i in range(0, 5):
89 | n = n * 256 + uid[i]
90 | return n
91 |
--------------------------------------------------------------------------------
/mfrc522/__init__.py:
--------------------------------------------------------------------------------
1 | from .MFRC522 import MFRC522
2 | from .SimpleMFRC522 import SimpleMFRC522
3 |
4 | name = "mfrc522"
5 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | import setuptools
2 |
3 | with open("README.md", "r") as fh:
4 | long_description = fh.read()
5 |
6 | setuptools.setup(
7 | name="mfrc522",
8 | version="0.0.7",
9 | author="Pi My Life Up",
10 | author_email="support@pimylifeup.com",
11 | description="A library to integrate the MFRC522 RFID readers with the Raspberry Pi",
12 | long_description=long_description,
13 | long_description_content_type="text/markdown",
14 | url="https://github.com/pimylifeup/MFRC522-python",
15 | packages=setuptools.find_packages(),
16 | install_requires=[
17 | 'RPi.GPIO',
18 | 'spidev'
19 | ],
20 | classifiers=[
21 | "Programming Language :: Python :: 2.7",
22 | "Programming Language :: Python :: 3",
23 | "License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)",
24 | "Operating System :: POSIX :: Linux",
25 | 'Topic :: System :: Hardware',
26 | ],
27 | )
28 |
--------------------------------------------------------------------------------