Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
211 changes: 211 additions & 0 deletions RASPBERRY_PI_SETUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
# PN7160 Integration with Raspberry Pi CM4

This guide provides instructions for integrating the NXP PN7160 NFC controller (OM27160A1EVK development kit) with a Raspberry Pi Compute Module 4.

## Hardware Setup

### Required Connections
Connect the OM27160A1EVK to your Raspberry Pi CM4 as follows:

| PN7160 Board Pin | Raspberry Pi CM4 Pin | GPIO | Function |
|------------------|---------------------|------|-----------|
| VCC | Pin 1 or 17 | 3.3V/5V | Power Supply |
| GND | Pin 6, 9, 14, 20 | GND | Ground |
| SDA | Pin 3 | GPIO2 | I2C Data |
| SCL | Pin 5 | GPIO3 | I2C Clock |
| IRQ | Pin 16 | GPIO23 | Interrupt |
| VEN/ENABLE | Pin 18 | GPIO24 | Enable |
| DWL (Optional) | Pin 22 | GPIO25 | Download Mode |

### Power Requirements
- Check your PN7160 board specifications for voltage requirements (3.3V or 5V)
- Ensure adequate current supply for the NFC chip

## Software Setup

### 1. Repository and Branch
```bash
git clone https://github.com/NXPNFCLinux/linux_libnfc-nci.git
cd linux_libnfc-nci
git checkout NCI2.0_PN7160
```

### 2. Install Dependencies
```bash
sudo apt update
sudo apt install build-essential libtool autoconf automake i2c-tools gpiod
```

### 3. Enable I2C
```bash
sudo raspi-config
# Navigate to Interfacing Options -> I2C -> Enable
sudo reboot
```

### 4. Build with Correct GPIO Configuration
The library has been pre-configured with the correct GPIO pins for Raspberry Pi CM4:
- PIN_INT = GPIO23 (system GPIO 535)
- PIN_ENABLE = GPIO24 (system GPIO 536)
- PIN_FWDNLD = GPIO25 (system GPIO 537)

```bash
./bootstrap
./configure
make clean
make
sudo make install
```

### 5. Configuration Files

#### A. libnfc-nxp.conf
Edit conf/libnfc-nxp.conf to configure for ALT_I2C transport (direct I2C access):

```bash
###############################################################################
# TRANSPORT Type
# 0x00 - I2C /SPI for noraml nxpnfc driver
# 0x01 - Not Used, kept to align with Android code
# 0x02 - ALT_I2C
# 0x03 - ALT_SPI
NXP_TRANSPORT=0x02

###############################################################################
# Nfc Device Node name
NXP_NFC_DEV_NODE="/dev/i2c-1"
```

## Hardware Verification

### 1. Check I2C Bus
```bash
# List I2C buses
i2cdetect -l

# Scan I2C bus 1 for devices
i2cdetect -y 1
```

### 2. Test GPIO Control
```bash
# Enable PN7160 (set VEN high using logical GPIO number)
gpioset --mode=time --sec=5 gpiochip0 24=1

# Then scan I2C again
i2cdetect -y 1
```

## GPIO Setup and Persistence

### Initial GPIO Setup
After hardware connections are made, run the GPIO setup script:

```bash
sudo ./pn7160_setup_gpio.sh
```

This script will:
- Configure GPIO pins 23, 24, 25 for NFC use
- Set up proper pin directions and initial values
- Enable the PN7160 device
- Verify I2C communication
- Optionally create a systemd service for automatic setup on boot

### Boot Persistence (Important!)
GPIO settings are not persistent across reboots. You have two options:

#### Option 1: Automatic Setup (Recommended)
When running `pn7160_setup_gpio.sh`, choose 'y' to create a systemd service that automatically sets up GPIO on every boot.

#### Option 2: Manual Setup After Reboot
If you didn't enable the automatic service, run this after each reboot:
```bash
sudo ./pn7160_boot_setup.sh
```

### Verification Scripts
Use these scripts to test your setup:

```bash
# Hardware connection test
sudo ./pn7160_hardware_test.sh
```

## Troubleshooting

### Common Issues

1. **"NfcService Init Failed"**
- Check hardware connections
- Run GPIO setup script: `sudo ./pn7160_setup_gpio.sh`
- Verify VEN pin is high (logical GPIO24)
- Ensure I2C bus permissions (`sudo usermod -a -G i2c $USER`)

2. **Device Not Detected on I2C**
- Verify power supply
- Check I2C address (try 0x28, 0x29)
- Run: `sudo ./pn7160_setup_gpio.sh`
- Ensure GPIO24 (VEN) is set high
- Check for I2C pull-up resistors

3. **Permission Denied Errors**
- Run with `sudo` for GPIO/I2C access
- Add user to i2c group: `sudo usermod -a -G i2c $USER`

4. **GPIO Export Failures**
- Use `gpiod` tools instead of sysfs
- Check if pins are already in use

## Kernel Driver Method
Instead of ALT_I2C, you can use a kernel driver:
- Follow AN13287 documentation for kernel driver compilation
- Creates `/dev/nxpnfc` device file
- Set `NXP_TRANSPORT=0x00` in configuration

## Useful Commands

```bash
# Check system info
uname -a
cat /proc/device-tree/model

# I2C tools
i2cdetect -l # List I2C buses
i2cdetect -y 1 # Scan bus 1
i2cget -y 1 0x28 0 # Read from address 0x28

# GPIO tools
gpiodetect # List GPIO chips
gpioinfo gpiochip0 # GPIO line information
gpioset gpiochip0 24=1 # Set GPIO24 high (VEN/Enable)
gpioget gpiochip0 24 # Read GPIO24 state
gpioget gpiochip0 23 # Read GPIO23 state (IRQ)

# Test if GPIO pins can be accessed (run as root)
echo 535 | sudo tee /sys/class/gpio/export # System GPIO for logical GPIO23
echo 536 | sudo tee /sys/class/gpio/export # System GPIO for logical GPIO24
echo 537 | sudo tee /sys/class/gpio/export # System GPIO for logical GPIO25

# Set directions
echo in | sudo tee /sys/class/gpio/gpio535/direction # Interrupt
echo out | sudo tee /sys/class/gpio/gpio536/direction # Enable
echo out | sudo tee /sys/class/gpio/gpio537/direction # FW Download

# Test enable pin (should reset the PN7160)
echo 0 | sudo tee /sys/class/gpio/gpio536/value
sleep 0.1
echo 1 | sudo tee /sys/class/gpio/gpio536/value

# Clean up
echo 535 | sudo tee /sys/class/gpio/unexport
echo 536 | sudo tee /sys/class/gpio/unexport
echo 537 | sudo tee /sys/class/gpio/unexport
```

## Documentation References

- [OM27160A1EVK Product Page](https://www.nxp.com/part/OM27160A1EVK)
- [Quick Start Guide PDF](https://www.nxp.com/docs/en/quick-reference-guide/OM27160A1QSGFL.pdf)
- [AN13287 - PN7160 Linux Integration Guide](https://www.nxp.com/docs/en/application-note/AN13287.pdf)
- [linux_libnfc-nci Repository](https://github.com/NXPNFCLinux/linux_libnfc-nci)
4 changes: 2 additions & 2 deletions conf/libnfc-nxp.conf
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ NXPLOG_TML_LOGLEVEL=0x00
# 0x01 - Not Used, kept to align with Android code
# 0x02 - ALT_I2C
# 0x03 - ALT_SPI
NXP_TRANSPORT=0x00
NXP_TRANSPORT=0x02

###############################################################################
# Nfc Device Node name
NXP_NFC_DEV_NODE="/dev/nxpnfc"
NXP_NFC_DEV_NODE="/dev/i2c-1"

###############################################################################
# Extension for Mifare reader enable
Expand Down
114 changes: 114 additions & 0 deletions pn7160_boot_setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#!/bin/bash

# PN7160 GPIO Auto-Setup Script
# This script runs the GPIO setup without interactive prompts
# Suitable for running on boot or from systemd service

echo "PN7160 GPIO Auto-Setup (Boot Mode)"
echo "=================================="

# GPIO pin definitions from NfccAltTransport.h
# These are the system GPIO numbers used by the compiled library
PIN_INT=535 # Interrupt pin (logical GPIO 23)
PIN_ENABLE=536 # VEN/Enable pin (logical GPIO 24)
PIN_FWDNLD=537 # Download pin (logical GPIO 25)

echo "Setting up GPIO pins using sysfs interface..."

# Function to setup GPIO pin via sysfs
setup_gpio() {
local pin=$1
local direction=$2
local value=$3

echo "Setting up GPIO$pin..."

# Check if already exported
if [ ! -d "/sys/class/gpio/gpio$pin" ]; then
echo "Exporting GPIO$pin..."
echo $pin > /sys/class/gpio/export 2>/dev/null || true
sleep 0.2
fi

# Set direction
if [ -w "/sys/class/gpio/gpio$pin/direction" ]; then
echo "Setting GPIO$pin direction to $direction"
echo $direction > /sys/class/gpio/gpio$pin/direction 2>/dev/null || true
sleep 0.1
else
echo "Warning: Cannot set direction for GPIO$pin"
fi

# Set value if specified and if it's an output
if [ -n "$value" ] && [ "$direction" = "out" ]; then
if [ -w "/sys/class/gpio/gpio$pin/value" ]; then
echo "Setting GPIO$pin value to $value"
echo $value > /sys/class/gpio/gpio$pin/value 2>/dev/null || true
fi
fi

# For interrupt pin, set edge trigger
if [ "$pin" = "535" ] && [ "$direction" = "in" ]; then
if [ -w "/sys/class/gpio/gpio$pin/edge" ]; then
echo "Setting GPIO$pin edge to rising"
echo "rising" > /sys/class/gpio/gpio$pin/edge 2>/dev/null || true
fi
fi
}

# Clean up any existing GPIO exports first
for pin in $PIN_INT $PIN_ENABLE $PIN_FWDNLD; do
if [ -d "/sys/class/gpio/gpio$pin" ]; then
echo "Cleaning up existing GPIO$pin export"
echo $pin > /sys/class/gpio/unexport 2>/dev/null || true
sleep 0.1
fi
done

# Setup interrupt pin (input with rising edge)
setup_gpio $PIN_INT in

# Setup enable pin (output, initially low)
setup_gpio $PIN_ENABLE out 0

# Setup download pin (output, initially low)
setup_gpio $PIN_FWDNLD out 0

# Wait a moment
sleep 0.5

# Enable the PN7160 by setting VEN high
echo "Enabling PN7160 (VEN = 1)..."
echo 1 > /sys/class/gpio/gpio$PIN_ENABLE/value 2>/dev/null || true

# Wait for device to initialize
sleep 1

# Check GPIO status (silently)
echo ""
echo "GPIO Status:"
if [ -r "/sys/class/gpio/gpio$PIN_INT/value" ]; then
echo "IRQ (GPIO$PIN_INT): $(cat /sys/class/gpio/gpio$PIN_INT/value 2>/dev/null || echo 'Unknown')"
fi

if [ -r "/sys/class/gpio/gpio$PIN_ENABLE/value" ]; then
echo "VEN (GPIO$PIN_ENABLE): $(cat /sys/class/gpio/gpio$PIN_ENABLE/value 2>/dev/null || echo 'Unknown')"
fi

if [ -r "/sys/class/gpio/gpio$PIN_FWDNLD/value" ]; then
echo "DWL (GPIO$PIN_FWDNLD): $(cat /sys/class/gpio/gpio$PIN_FWDNLD/value 2>/dev/null || echo 'Unknown')"
fi

echo ""
echo "✅ PN7160 GPIO auto-setup complete!"

# Check I2C if tools are available
if command -v i2cdetect > /dev/null; then
echo ""
echo "Scanning I2C bus for PN7160..."
if i2cdetect -y 1 | grep -q "28"; then
echo "✅ PN7160 detected at address 0x28"
else
echo "⚠️ PN7160 not detected (may need more time to initialize)"
fi
fi
Loading