Write Data to RFID Tags

In this chapter, we'll learn how to write data to MIFARE Classic RFID tags. We'll write custom data to a specific block and verify it was written correctly.

⚠

Caution

Accidentally writing to the wrong block can overwrite the sector trailer, which may alter authentication keys or access bits. This could make the sector unusable. Always double-check block numbers before writing!

Writing to a Block

To write data to an RFID tag:

  1. Authenticate with the sector using the correct key
  2. Use mf_write with the absolute block number
  3. Provide exactly 16 bytes of data (pad with 0x00 if needed)
rust
fn write_block<E, COMM: mfrc522::comm::Interface<Error = E>>(
    uid: &mfrc522::Uid,
    sector: u8,
    rel_block: u8,
    data: [u8; 16],
    rfid: &mut Mfrc522<COMM, mfrc522::Initialized>,
) -> Result<(), &'static str> {
    const AUTH_KEY: [u8; 6] = [0xFF; 6];
    
    let block_offset = sector * 4;
    let abs_block = block_offset + rel_block;
    
    // Authenticate sector
    rfid.mf_authenticate(uid, block_offset, &AUTH_KEY)
        .map_err(|_| "Auth failed")?;
    
    // Write 16 bytes
    rfid.mf_write(abs_block, data)
        .map_err(|_| "Write failed")?;
    
    Ok(())
}

Example: Writing Custom Data

Let's write "RUST" to block 2 of sector 4:

rust
const DATA: [u8; 16] = [
    0x52, 0x55, 0x53, 0x54, // "RUST" in ASCII
    0x00, 0x00, 0x00, 0x00, // Padding
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
];

let target_sector = 4;
let rel_block = 2; // Block 18 absolute

// Write data
if let Err(e) = write_block(&uid, target_sector, rel_block, DATA, &mut rfid) {
    serial.write(e.as_bytes()).unwrap();
} else {
    serial.write(b"Write successful!\r\n").unwrap();
}

Verifying the Write

After writing, read the block back to verify:

rust
// Read after write
let data = rfid.mf_read(abs_block).unwrap();
print_hex_to_serial(&data, &mut serial);

Block Layout Reminder

MIFARE Classic 1K memory structure:

Safe Writing Practices

Pico 2 W with RFID

The RC522 RFID reader uses SPI communication, which works perfectly with the Pico 2 W. Just avoid using GPIO 23-25, 29 for SPI connections since they're reserved for wireless functionality. Use GPIO 4-7 for SPI as shown in the circuit diagrams.