** EDIT: Updated with latest port, I'm starting from the top and loading the code a block at a time. Most of the code should be ok apart from the python tuple returns. What I'm looking to do is get the send and receive functions working. If anyone has any ideas re sending a byte and reading a byte from the RC522 module then this would be a lot closer to working I think. At the moment all reads seem to return 255. I don't have an oscilloscope handy so can't watch the waveforms.
pin_rst = 3
pin_ss = 4
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
RC522 = {}
RC522.__index = RC522
function RC522.init()
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.LOW)
RC522.reset()
RC522.dev_write(0x2A, 0x8D)
RC522.dev_write(0x2B, 0x3E)
RC522.dev_write(0x2D, 30)
RC522.dev_write(0x2C, 0)
RC522.dev_write(0x15, 0x40)
RC522.dev_write(0x11, 0x3D)
--RC522.set_antenna(true)
end
function RC522.reset()
RC522.dev_write(0x01, mode_reset)
end
function RC522.cleanup(self)
--Calls stop_crypto() if needed and cleanups GPIO.
if self.authed then
self.stop_crypto()
end
end
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
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
function RC522.set_bitmask(address, mask)
local current = RC522.dev_read(address)
RC522.dev_write(address, bit.bor(current, mask))
end
function RC522.clear_bitmask(address, mask)
local current = RC522.dev_read(address)
RC522.dev_write(address, bit.band(current, bit.bnot(mask)))
end
function RC522.set_antenna(state)
if state == true then
local current = RC522.dev_read(reg_tx_control)
if bit.bnot(bit.band(current, 0x03)) then
RC522.set_bitmask(reg_tx_control, 0x03)
end
else
RC522.clear_bitmask(reg_tx_control, 0x03)
end
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))
RC522.clear_bitmask(0x04, 0x80)
RC522.set_bitmask(0x0A, 0x80)
RC522.dev_write(0x01, mode_idle)
for i=0, string.len(data)) then
RC522.dev_write(0x09, data[i])
end
RC522.dev_write(0x01, command)
if command == self.mode_transrec then
RC522.set_bitmask(0x0D, 0x80)
end
i = 2000
while true
n = RC522.dev_read(0x04)
i = i - 1
if bit.bnot((i ~= 0) and bit.bnot(bit.band(n, 0x01)) and bit.bnot(bit.band(n, irq_wait))) then
break
end
end
RC522.clear_bitmask(0x0D, 0x80)
if (i ~= 0) then
if bit.band(RC522.dev_read(0x06), 0x1B) == 0x00 then
err = false
if bit.band(n,irq,0x01) then
--print "E1"
err = true
end
if (command == mode_transrec) then
n = RC522.dev_read(0x0A)
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 = length
end
for i=0, n do
back_data.append(RC522.dev_read(0x09))
end
else
--print "E2"
err = true
end
end
return { err = err, back_data = back_data, back_length = back_length }
end
function RC522.request(req_mode=0x26)
--Requests for tag.
--Returns (False, None) if no tag is present, otherwise returns (True, tag type)
err = true
back_bits = 0
RC522.dev_write(0x0D, 0x07)
(err, back_data, back_bits) = RC522.card_write(mode_transrec, [req_mode, ])
if err or (back_bits ~= 0x10) then
return (true, nul)
end
return (false, back_bits)
end
function RC522.anticoll():
--Anti-collision detection.
--Returns tuple of (error state, tag ID).
back_data = []
serial_number = []
serial_number_check = 0
RC522.dev_write(0x0D, 0x00)
serial_number.append(act_anticl)
serial_number.append(0x20)
(err, back_data, back_bits) = RC522.card_write(mode_transrec, serial_number)
if not err then
if string.len(back_data) == 5 then
for i=0, 4 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
return (error, back_data)
end
function RC522.calculate_crc(self, data):
RC522.clear_bitmask(0x05, 0x04)
RC522.set_bitmask(0x0A, 0x80)
for i=0, string.len(data) do
RC522.dev_write(0x09, data[i])
end
RC522.dev_write(0x01, mode_crc)
i = 255
while true do
n = RC522.dev_read(0x05)
i -= 1
if not ((i != 0) and not bit.band(n,0x04)) then
break
end
end
ret_data = []
ret_data.append(RC522.dev_read(0x22))
ret_data.append(RC522.dev_read(0x21))
return ret_data
end
function RC522.select_tag(uid):
--Selects tag for further usage.
--uid -- list or tuple with four bytes tag ID
--Returns error state.
back_data = []
buf = []
buf.append(RC522.act_select)
buf.append(0x70)
for i=0, 5 do
buf.append(uid[i])
end
crc = RC522.calculate_crc(buf)
buf.append(crc[0])
buf.append(crc[1])
(err, back_data, back_length) = RC522.card_write(mode_transrec, buf)
if (~err) and (back_length == 0x18)
return false
else
return true
end
end
function RC522.card_auth(self, auth_mode, block_address, key, uid):
--Authenticates to use specified block address. Tag must be selected using select_tag(uid) before auth.
--auth_mode -- RFID.auth_a or RFID.auth_b
--key -- list or tuple with six bytes key
--uid -- list or tuple with four bytes tag ID
--Returns error state.
buf = []
buf.append(auth_mode)
buf.append(block_address)
for i=0, string.len(key) do
buf.append(key[i])
end
for i=0,4 do
buf.append(uid[i])
end
(error, back_data, back_length) = RC522.card_write(mode_auth, buf)
if ~bit.band(RC522.dev_read(0x08), 0x08) ~= 0 then
error = true
end
if ~err then
RC522.authed = true
end
return error
end
function RC522.stop_crypto()
--"""Ends operations with Crypto1 usage."""
RC522.clear_bitmask(0x08, 0x08)
authed = false
end
function RC522.read(block_address)
--Reads data from block. You should be authenticated before calling read.
--Returns tuple of (error state, read data).
buf = []
buf.append(act_read)
buf.append(block_address)
crc = RC522.calculate_crc(buf)
buf.append(crc[0])
buf.append(crc[1])
(err, back_data, back_length) = RC522.card_write(mode_transrec, buf)
if len(back_data) ~= 16 then
err = true
end
return (err, back_data)
end
function RC522.write(self, block_address, data):
--Writes data to block. You should be authenticated before calling write.
--Returns error state.
buf = []
buf.append(act_write)
buf.append(block_address)
crc = RC522.calculate_crc(buf)
buf.append(crc[0])
buf.append(crc[1])
(err, back_data, back_length) = RC522.card_write(mode_transrec, buf)
if not(back_length == 4) or not((back_data[0] & 0x0F) == 0x0A) then
err = true
end
if not err then
buf_w = []
for i=0, 16 do
buf_w.append(data[i])
end
crc = RC522.calculate_crc(buf_w)
buf_w.append(crc[0])
buf_w.append(crc[1])
(err, back_data, back_length) = RC522.card_write(mode_transrec, buf_w)
if not(back_length == 4) or not(bit.band(back_data[0], 0x0F) == 0x0A) then
err = true
end
end
return err
end