Left for archival purposes.

User avatar
By ampakinetic
#25331 Ok I've made a start, I've found this Python code (https://github.com/ondryaso/pi-rc522/bl ... er/RFID.py) and have started to port it to Lua. I've changed the RST pin to GPIO0 as GPIO15 needs to be low for the module to start. Otherwise I'm using the wiring diagram from https://github.com/Jorgen-VikingGod/ESP8266-MFRC522 to connect the RC522 module to a ESP-07.

** 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.

Code: Select all     
    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

   
Last edited by ampakinetic on Sat Aug 08, 2015 7:08 am, edited 3 times in total.
User avatar
By ampakinetic
#25334 I've looked at the C library again and closely at the send/rec functions there, now I've got the following (and kept the left shift from the python lib)

Code: Select all 
   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,1)
    end


Any address I read returns 255 so far.