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.