-
Notifications
You must be signed in to change notification settings - Fork 1
/
m_srv_mfrc522.lua
422 lines (355 loc) · 12.2 KB
/
m_srv_mfrc522.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
pin_rst = 8 -- Enable/reset pin
pin_ss = 4 -- SS (marked as SDA) pin
mode_idle = 0x00
mode_auth = 0x0E
mode_receive = 0x08
mode_transmit = 0x04
mode_transrec = 0x0C
mode_reset = 0x0F
mode_crc = 0x03
auth_a = 0x60
auth_b = 0x61
act_read = 0x30
act_write = 0xA0
act_increment = 0xC1
act_decrement = 0xC0
act_restore = 0xC2
act_transfer = 0xB0
act_reqidl = 0x26
act_reqall = 0x52
act_anticl = 0x93
act_select = 0x93
act_end = 0x50
reg_tx_control = 0x14
length = 16
num_write = 0
authed = false
keyA = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } -- this is the usual default key (but may not always be)
RC522 = {}
RC522.__index = RC522
--------------------------------------------------------
-- Converts a table of numbers into a HEX string
function appendHex(t)
strT = ""
for i,v in ipairs(t) do
strT = strT.." 0x"..string.format("%X", t[i])
end
return strT
end
--------------------------------------------------------
-- Writes to a register
-- address The address of the register
-- value The value to write to the register
function RC522.dev_write(address, value)
gpio.write(pin_ss, gpio.LOW)
num_write = spi.send(1, bit.band(bit.lshift(address,1), 0x7E), value)
gpio.write(pin_ss, gpio.HIGH)
end
--------------------------------------------------------
-- Reads a register
-- address The address of the register
-- returns:
-- the byte at the register
function RC522.dev_read(address)
local val = 0;
gpio.write(pin_ss, gpio.LOW)
spi.send(1,bit.bor(bit.band(bit.lshift(address,1), 0x7E), 0x80))
val = spi.recv(1,1)
gpio.write(pin_ss, gpio.HIGH)
return string.byte(val)
end
--------------------------------------------------------
-- Adds a bitmask to a register
-- address The address of the register
-- mask The mask to update the register with
function RC522.set_bitmask(address, mask)
local current = RC522.dev_read(address)
RC522.dev_write(address, bit.bor(current, mask))
end
--------------------------------------------------------
-- Removes a bitmask from a register
-- address The address of the register
-- mask The mask to update the register with
function RC522.clear_bitmask(address, mask)
local current = RC522.dev_read(address)
RC522.dev_write(address, bit.band(current, bit.bnot(mask)))
end
--------------------------------------------------------
-- Reads the firmware version
function RC522.getFirmwareVersion()
return RC522.dev_read(0x37)
end
--------------------------------------------------------
-- Checks to see if there is a TAG in the vacinity
-- Returns false if tag is present, otherwise returns true
function RC522.request()
req_mode = { 0x26 } -- find tag in the antenna area (does not enter hibernation)
err = true
back_bits = 0
RC522.dev_write(0x0D, 0x07) -- bitFramingReg
err, back_data, back_bits = RC522.card_write(mode_transrec, req_mode)
if err or (back_bits ~= 0x10) then
return false, nil
end
return true, back_data
end
function RC522.card_write(command, data)
back_data = {}
back_length = 0
local err = false
local irq = 0x00
local irq_wait = 0x00
local last_bits = 0
n = 0
if command == mode_auth then
irq = 0x12
irq_wait = 0x10
end
if command == mode_transrec then
irq = 0x77
irq_wait = 0x30
end
RC522.dev_write(0x02, bit.bor(irq, 0x80)) -- CommIEnReg
RC522.clear_bitmask(0x04, 0x80) -- CommIrqReg
RC522.set_bitmask(0x0A, 0x80) -- FIFOLevelReg
RC522.dev_write(0x01, mode_idle) -- CommandReg - no action, cancel the current action
for i,v in ipairs(data) do
RC522.dev_write(0x09, data[i]) -- FIFODataReg
end
RC522.dev_write(0x01, command) -- execute the command
-- command is "mode_transrec" 0x0C
if command == mode_transrec then
-- StartSend = 1, transmission of data starts
RC522.set_bitmask(0x0D, 0x80) -- BitFramingReg
end
--- Wait for the command to complete so we can receive data
i = 25 --- WAS 20000
while true do
tmr.delay(1)
n = RC522.dev_read(0x04) -- ComIrqReg
i=i-1
if not ((i ~= 0) and (bit.band(n, 0x01) == 0) and (bit.band(n, irq_wait) == 0)) then
break
end
end
RC522.clear_bitmask(0x0D, 0x80) -- StartSend = 0
if (i ~= 0) then -- Request did not timeout
if bit.band(RC522.dev_read(0x06), 0x1B) == 0x00 then -- Read the error register and see if there was an error
err = false
-- if bit.band(n,irq,0x01) then
-- err = false
-- end
if (command == mode_transrec) then
n = RC522.dev_read(0x0A) -- find out how many bytes are stored in the FIFO buffer
last_bits = bit.band(RC522.dev_read(0x0C),0x07)
if last_bits ~= 0 then
back_length =(n - 1)*8+last_bits
else
back_length=n*8
end
if (n == 0) then
n = 1
end
if (n > length) then -- n can't be longer that 16
n = length
end
for i=1, n do
xx = RC522.dev_read(0x09)
back_data[i] = xx
end
end
else
err = true
end
end
return err, back_data, back_length
end
function RC522.anticoll()
back_data = {}
serial_number = {}
serial_number_check = 0
RC522.dev_write(0x0D, 0x00)
serial_number[1] = act_anticl
serial_number[2] = 0x20
err, back_data, back_bits = RC522.card_write(mode_transrec, serial_number)
if not err then
if table.maxn(back_data) == 5 then
for i, v in ipairs(back_data) do
serial_number_check = bit.bxor(serial_number_check, back_data[i])
end
if serial_number_check ~= back_data[4] then
err = true
end
else
err = true
end
end
return error, back_data
end
function RC522.calculate_crc(data)
RC522.clear_bitmask(0x05, 0x04)
RC522.set_bitmask(0x0A, 0x80) -- clear the FIFO pointer
for i,v in ipairs(data) do -- Write all the data in the table to the FIFO buffer
RC522.dev_write(0x09, data[i]) -- FIFODataReg
end
RC522.dev_write(0x01, mode_crc)
i = 255
while true do
n = RC522.dev_read(0x05)
i = i - 1
if not ((i ~= 0) and not bit.band(n,0x04)) then
break
end
end
-- read the CRC result
ret_data = {}
ret_data[1] = RC522.dev_read(0x22)
ret_data[2] = RC522.dev_read(0x21)
return ret_data
end
function RC522.select_tag(uid)
back_data = {}
buf = {}
table.insert(buf, act_select)
table.insert(buf, 0x70)
for i=1, 5 do
table.insert(buf, uid[i])
end
crc = RC522.calculate_crc(buf)
table.insert(buf, crc[1])
table.insert(buf, crc[2])
err, back_data, back_length = RC522.card_write(mode_transrec, buf)
if (not err) and (back_length == 0x18) then
sak = back_data[1]
return false, sak
else
return true, 0
end
end
function RC522.readTag(block_address)
buf = {}
table.insert(buf, act_read)
table.insert(buf, block_address)
crc = RC522.calculate_crc(buf)
table.insert(buf, crc[1])
table.insert(buf, crc[2])
err, back_data, back_length = RC522.card_write(mode_transrec, buf)
if back_length ~= 0x90 then
err = true
end
return err, back_data
end
function RC522.writeTag(block_address, data)
buf = {}
table.insert(buf, act_write)
table.insert(buf, block_address)
crc = RC522.calculate_crc(buf)
table.insert(buf, crc[1])
table.insert(buf, crc[2])
err, back_data, back_length = RC522.card_write(mode_transrec, buf)
if not(back_length == 4) or not((bit.band(back_data[1], 0x0F)) == 0x0A) then
err = true
end
if not err then
buf_w = {}
for i=0, 16 do
table.insert(buf_w, data[i])
end
crc = RC522.calculate_crc(buf_w)
table.insert(buf_w, crc[1])
table.insert(buf_w, crc[2])
err, back_data, back_length = RC522.card_write(mode_transrec, buf_w)
if not(back_length == 4) or not(bit.band(back_data[1], 0x0F) == 0x0A) then
err = true
end
end
return err
end
function RC522.card_auth(auth_mode, block_address, key, uid)
buf = {}
table.insert(buf, auth_mode)
table.insert(buf, block_address)
for i, v in ipairs(key) do
table.insert(buf, key[i])
end
for i=1,4 do
table.insert(buf, uid[i])
end
err, back_data, back_length = RC522.card_write(mode_auth, buf)
if not bit.band(RC522.dev_read(0x08), 0x08) == 0 then
error = true
end
if not err then
authed = true
error = false
end
return error
end
----------------------------------------------------------------------
-- Main
----------------------------------------------------------------------
-- Initialise the RC522
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8, 0)
gpio.mode(pin_rst,gpio.OUTPUT)
gpio.mode(pin_ss,gpio.OUTPUT)
gpio.write(pin_rst, gpio.HIGH) -- needs to be HIGH all the time for the RC522 to work
gpio.write(pin_ss, gpio.HIGH) -- needs to go LOW during communications
RC522.dev_write(0x01, mode_reset) -- soft reset
RC522.dev_write(0x2A, 0x8D) -- Timer: auto; preScaler to 6.78MHz
RC522.dev_write(0x2B, 0x3E) -- Timer
RC522.dev_write(0x2D, 30) -- Timer
RC522.dev_write(0x2C, 0) -- Timer
RC522.dev_write(0x15, 0x40) -- 100% ASK
RC522.dev_write(0x11, 0x3D) -- CRC initial value 0x6363
-- turn on the antenna
current = RC522.dev_read(reg_tx_control)
if bit.bnot(bit.band(current, 0x03)) then
RC522.set_bitmask(reg_tx_control, 0x03)
end
print("RC522 Firmware Version: 0x"..string.format("%X", RC522.getFirmwareVersion()))
tmr.alarm(0, 500, tmr.ALARM_AUTO, function()
isTagNear, cardType = RC522.request()
if isTagNear == true then
tmr.stop(0)
err, serialNo = RC522.anticoll()
print("Tag Found: "..appendHex(serialNo).." of type: "..appendHex(cardType))
-- Selecting a tag, and the rest afterwards is only required if you want to read or write data to the card
err, sak = RC522.select_tag(serialNo)
if err == false then
print("Tag selected successfully. SAK: 0x"..string.format("%X", sak))
--[[ for i = 0,63 do
err = RC522.card_auth(auth_a, i, keyA, serialNo) -- Auth the "A" key. If this fails you can also auth the "B" key
if err then
print("ERROR Authenticating block "..i)
else
-- Write data to card
if (i == 2) then -- write to block 2
err = RC522.writeTag(i, { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
if err then print("ERROR Writing to the Tag") end
end
-- Read card data
if not (i % 4 == 3) then -- Don't bother to read the Sector Trailers
err, tagData = RC522.readTag(i)
if not err then print("READ Block "..i..": "..appendHex(tagData)) end
end
end
end
--]]
else
print("ERROR Selecting tag")
end
print(" ")
-- halt tag and get ready to read another.
buf = {}
buf[1] = 0x50 --MF1_HALT
buf[2] = 0
crc = RC522.calculate_crc(buf)
table.insert(buf, crc[1])
table.insert(buf, crc[2])
err, back_data, back_length = RC522.card_write(mode_transrec, buf)
RC522.clear_bitmask(0x08, 0x08) -- Turn off encryption
tmr.start(0)
else
print("NO TAG FOUND")
end
end) -- timer