Linux, Raspberry Pi 5 + M519: a playground for embedded and efficient contactless applications

It’s been a while since our last guide on using PC/SC readers under Linux, and let’s be honest — that one’s been gathering digital dust since the time when “cloud” still meant actual vapor. So here’s a much-needed refresh, this time with modern hardware and a brand-new Linux distribution running on the Raspberry Pi 5 — a clean, up-to-date embedded environment ready for serious work.

For this walkthrough, we’ll be using the SpringCard M519-SAM-B, a neat little OEM contactless module that happens to be a perfect match for a Raspberry Pi 5. The goal: build a clean, secure, and flexible platform to experiment with contactless smart card applications under Linux.

Why the M519-SAM-B? Because it’s practical and well adapted to embedded designs.

  • It connects via a real USB-C port — less “industrial” than the JST-5 connector we use on the M519-SUV or Prox’N’Roll, but definitively more convenient for the person actually doing the development. Just plug it into your Pi with a standard USB-A to USB-C cable, and you’re good to go.
  • It comes with a symmetrical remote antenna on a short, flexible 4-wire cable — a sweet spot between the compact M519-SUV (integrated antenna) and the higher-end M519-SAM-U (asymmetrical 50-ohm micro coax). This means easier integration inside terminals, kiosks, or vending machines, without sacrificing robustness or affordability.
  • And, most importantly, it features a SAM slot (ID-000 format, ISO 7816 compliant). That’s where you put your secure element of secure smart card — essential for cryptographic operations, key storage, and transaction authentication when dealing with high-security contactless systems.

In short, the M519-SAM-B is practical and versatile enough to cover almost every use case of a PC/SC contactless + contact coupler. It’s the ideal product to discover, evaluate, and prototype — and to be production-ready from day one. Either the M519-SAM-B perfectly fits the need, or you switch to one of its smaller siblings for cost optimization. In both cases, nothing is wasted: everything you’ve learned and developed just works the same way.

The step-by-step guide below applies just as well to other SpringCard USB PC/SC readers — older H663-based models, Puck, Prox’N’Roll, etc. The only real difference is that on the Raspberry Pi, we’ll need to manually install the PC/SC-Lite middleware and CCID driver; on a desktop or server-grade Linux distribution, those generally come pre-installed out of the box.

Initial setup

You may skip this part if PC/SC-Lite is already installed on your Linux distribution.

Install pcsc-lite, CCID drivers and tools

Open a terminal (SSH session or local console) and run:

sudo apt update
sudo apt install -y pcscd pcsc-tools libccid
# optional: python and system-wide pyscard package
sudo apt install -y python3-pip
sudo apt install -y python3-pyscard || python3 -m pip install pyscard

Note

libccid (or the distro package wrapping Ludovic Rousseau’s CCID code) is the usual CCID driver for Linux systems. It is the open source driver that exposes SpringCard USB PC/SC products on Linux.

Start the daemon and basic checks

Enable & start pcscd and check status:

sudo systemctl enable --now pcscd
sudo systemctl status pcscd

If you prefer to see verbose debug output (helpful while developing), stop the background service and run in foreground:

sudo systemctl stop pcscd
sudo pkill -f pcscd || true
sudo /usr/sbin/pcscd -f -d

Running pcscd in foreground shows logs right away and helps diagnose why readers are not detected.

Verifications

Verify Linux sees the USB reader (hardware level)

Check USB enumeration:

lsusb

Look for your reader’s VendorID:ProductID.

VendorID is 1C34 for SpringCard.

You can easily recognize a SpringCard PC/SC reader because its ProductID ends with the digit 2.
If it doesn’t, the device is probably configured to run a different firmware profile or operating mode.

If lsusb shows nothing relevant, the kernel doesn’t see the device or it’s a power/connection problem.

Verify that PCSC-lite sees the reader (middleware level)

Use pcsc_scan (comes with pcsc-tools) — it prints readers & ATRs and reacts to card insert/remove:

pcsc_scan

Expected: pcsc_scan lists one or more reader names. Insert a card and you should see ATR and connection info. If nothing appears, try the foreground debug (pcscd -f -d) while plugging/unplugging the reader to see errors.

Validate with a card

Place a contactless card over the antenna or a SAM in the contact slot. pcsc_scan shows that a card has been inserted, displays its ATR, and tries to name the card after a list of “well-known” ATRs (more on that here).

Enabling and testing SCardControl

Rationale

Developers already familiar with smart card programming — contact or contactless — know the classic trio of functions: SCardConnect, SCardTransmit, and SCardDisconnect. These let you open a session with a card, exchange APDUs, and close the session (usually resetting the card for security). If you’re not there yet, other posts on this blog and plenty of online tutorials cover these basics in detail.

But SCardControl is a different beast — often overlooked, sometimes feared. That’s understandable: SCardControl is the PC/SC-level equivalent of the PC_To_RDR_Escape command from the CCID standard. In other words, it allows you to send a raw, direct command not to the card, but to the reader’s firmware itself.

As you can imagine, this is anything but portable. Every manufacturer defines its own firmware and its own command set. Still, SCardControl is incredibly useful when you need to control the reader’s user interface (LEDs, buzzer), push a new configuration, or even update the firmware directly through the PC/SC + CCID channel. Those are crucial capabilities when readers are deployed in embedded or distributed environments.

In this section, we’ll take the time to enable SCardControl support in PCSC-Lite’s CCID driver and make sure it actually works. No need to go further just yet — but when the day comes to send more advanced commands, your system will already be ready for it.

Our test script

The pcsc_scardcontrol_wink.py Python script demonstrates how to use SCardControl to send a direct command to a SpringCard reader. In this example, it triggers the “WINK” command ([0x58, 0x9F]), which briefly flashes the main LED of the module. On products with a more complete UI (like Puck and Prox’N’Roll), the WINK sequence generally includes buzzer sounds and high-luminosity flashs, so you can immediately confirm communication with the device.

You can download the script here:

(the Python script is compressed in a .zip archive to please some paranoid security tools, unzip and chmod +x the .py file to allow execution)

What the script does

  1. Establishes a PC/SC context using SCardEstablishContext, the standard first step in any PC/SC session.
  2. Lists all connected readers via SCardListReaders, and looks specifically for one whose name starts with "SpringCard ".
  3. Connects in DIRECT mode (SCARD_SHARE_DIRECT) event if there’s no smart card in the reader. This mode gives the application direct access to the reader’s firmware.
  4. Computes the control code, which differs between Windows and PCSC-Lite (Linux/macOS).
  5. Sends the WINK command through SCardControl, and prints the reader’s response (a single 00 byte denotes success).
  6. Closes the connection and releases the context cleanly when finished.

Why it’s useful

This minimal example proves that your system and PCSC-Lite installation are correctly configured to handle SCardControl operations — the key to controlling LEDs, buzzers, or pushing configurations and firmware over PC/SC.

Once this works, you know that your environment is ready for more advanced control commands or integration into larger applications.

Yes, it fails—we were expecting it

Run the script like this:

python ./pcsc_scardcontrol_wink.py

Alas, the script says that an error has occured, and the M519‘s LED remains quiet.

That’s because, by default, SCardControl is disabled in the CCID driver for security and stability reasons.

When you really need it — for instance, to control LEDs, buzzers, or perform firmware updates — you must enable SCardControl manually in the CCID driver’s configuration file.

Allowing the driver to send Escape commands to the readers

We must take root’s priviledges (sudo) and edit the CCID driver’s main configuration file:

sudo vim /usr/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist

(of course you may use any other text editor if you don’t like vi nor vim!)

The file is structured as an XML file, pay attention not to break the structure.

Scroll down until you find the ifdDriverOptions key (on line 55 with our distribution).

The corresponding string value is likely to be 0x0000. That means that Escape commands are disabled (documentation is in the following lines, in the same file).

Change this value to 0x0001.

Save the file and close the text editor.

Restart the pcscd daemon to take the new configuration in account.

sudo systemctl restart pcscd

Yes, it works!

Run the script again:

python ./pcsc_scardcontrol_wink.py

This time, no error is shown…

…and we can see the M519 playing its WINK sequence!

At this stage, your system is ready for everything the PC/SC world can offer — from standard smart card operations to advanced control over the reader itself. You now have the flexibility to really take benefit of all the features that the reader supports.

A Word of Thanks (and a Disclaimer)

SpringCard has no formal link with the developers of the open-source PCSC-Lite project or the open-source CCID driver for Linux.

We would like to warmly thank Ludovic Rousseau, the main creator and long-time maintainer of both. His work is what makes interoperability across so many readers and platforms possible.

If you ever face issues with a PC/SC coupler on Linux, please understand that SpringCard Support Team can’t go further than checking with lsusb that the device is correctly plugged in and powered, and configured to run the PC/SC profile (Coupler operating mode, configuration register 02C0 set to 02).

Questions specifically related to PCSC-Lite or the CCID driver are outside our support scope.
Make sure to carefully read the documentation and troubleshooting information available at https://ccid.apdu.fr/ — it’s the best place to start if something doesn’t work as expected.

Leave a Comment

Prove your humanity: 6   +   10   =