From 3162006c1899314ad7773ff514989c9a117bf68f Mon Sep 17 00:00:00 2001 From: Alex Hoffmann Date: Mon, 29 Sep 2025 13:46:22 +0200 Subject: [PATCH 1/6] Fixed GPIO config for INT, ENABLE and FWDNLD --- conf/libnfc-nxp.conf | 14 +- .../halimpl/tml/NfccAltTransport.cc | 465 ++++++++++++++++++ .../halimpl/tml/NfccAltTransport.h | 127 +++++ 3 files changed, 604 insertions(+), 2 deletions(-) create mode 100644 src/nfcandroid_nfc_hidlimpl/halimpl/tml/NfccAltTransport.cc create mode 100755 src/nfcandroid_nfc_hidlimpl/halimpl/tml/NfccAltTransport.h diff --git a/conf/libnfc-nxp.conf b/conf/libnfc-nxp.conf index e52b260..6bc2ca5 100755 --- a/conf/libnfc-nxp.conf +++ b/conf/libnfc-nxp.conf @@ -27,11 +27,21 @@ 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" + +############################################################################### +# GPIO Pin Configuration for ALT transport (Raspberry Pi CM4) +# These are system GPIO numbers for sysfs access (/sys/class/gpio/gpioXXX) +# GPIO 23 (Pin 16) -> System GPIO 535 +# GPIO 24 (Pin 18) -> System GPIO 536 +# GPIO 25 (Pin 22) -> System GPIO 537 +NXP_GPIO_INT=535 +NXP_GPIO_ENABLE=536 +NXP_GPIO_FWDNLD=537 ############################################################################### # Extension for Mifare reader enable diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/NfccAltTransport.cc b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/NfccAltTransport.cc new file mode 100644 index 0000000..a1d6745 --- /dev/null +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/NfccAltTransport.cc @@ -0,0 +1,465 @@ +/****************************************************************************** + * Copyright 2021 NXP + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include +#include +#ifdef ANDROID +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "phNxpNciHal_utils.h" +#include "phNxpConfig.h" + +#define CRC_LEN 2 +#define NORMAL_MODE_HEADER_LEN 3 +#define FW_DNLD_HEADER_LEN 2 +#define FW_DNLD_LEN_OFFSET 1 +#define NORMAL_MODE_LEN_OFFSET 2 +#define FRAGMENTSIZE_MAX PHNFC_I2C_FRAGMENT_SIZE +extern phTmlNfc_i2cfragmentation_t fragmentation_enabled; +extern phTmlNfc_Context_t* gpphTmlNfc_Context; + +NfccAltTransport::NfccAltTransport() { + iEnableFd = 0; + iInterruptFd = 0; +} + +/******************************************************************************* +** +** Function Flushdata +** +** Description Reads payload of FW rsp from NFCC device into given buffer +** +** Parameters pDevHandle - valid device handle +** pBuffer - buffer for read data +** numRead - number of bytes read by calling function +** +** Returns always returns -1 +** +*******************************************************************************/ +int NfccAltTransport::Flushdata(void* pDevHandle, uint8_t* pBuffer, + int numRead) { + int retRead = 0; + uint16_t totalBtyesToRead = + pBuffer[FW_DNLD_LEN_OFFSET] + FW_DNLD_HEADER_LEN + CRC_LEN; + /* we shall read totalBtyesToRead-1 as one byte is already read by calling + * function*/ + retRead = read((intptr_t)pDevHandle, pBuffer + numRead, totalBtyesToRead - 1); + if (retRead > 0) { + numRead += retRead; + phNxpNciHal_print_packet("RECV", pBuffer, numRead); + } else if (retRead == 0) { + NXPLOG_TML_E("%s _i2c_read() [pyld] EOF", __func__); + } else { + if (bFwDnldFlag == false) { + NXPLOG_TML_D("%s _i2c_read() [hdr] received", __func__); + phNxpNciHal_print_packet("RECV", pBuffer - numRead, + NORMAL_MODE_HEADER_LEN); + } + NXPLOG_TML_E("%s _i2c_read() [pyld] errno : %x", __func__, errno); + } + SemPost(); + return -1; +} + +/******************************************************************************* +** +** Function Reset +** +** Description Reset NFCC device, using VEN pin +** +** Parameters pDevHandle - valid device handle +** eType - reset level +** +** Returns 0 - reset operation success +** -1 - reset operation failure +** +*******************************************************************************/ +int NfccAltTransport::NfccReset(void* pDevHandle, NfccResetType eType) { + int ret = -1; + NXPLOG_TML_D("%s, VEN eType %ld", __func__, eType); + + if (NULL == pDevHandle) { + return -1; + } + switch (eType) { + case MODE_POWER_OFF: + gpio_set_fwdl(0); + gpio_set_ven(0); + break; + case MODE_POWER_ON: + gpio_set_fwdl(0); + gpio_set_ven(1); + break; + case MODE_FW_DWNLD_WITH_VEN: + gpio_set_fwdl(1); + gpio_set_ven(0); + gpio_set_ven(1); + break; + case MODE_FW_DWND_HIGH: + gpio_set_fwdl(1); + break; + case MODE_POWER_RESET: + gpio_set_ven(0); + gpio_set_ven(1); + break; + case MODE_FW_GPIO_LOW: + gpio_set_fwdl(0); + break; + default: + NXPLOG_TML_E("%s, VEN eType %ld", __func__, eType); + return -1; + } + if ((eType != MODE_FW_DWNLD_WITH_VEN) && (eType != MODE_FW_DWND_HIGH)) { + EnableFwDnldMode(false); + } + if ((eType == MODE_FW_DWNLD_WITH_VEN) || (eType == MODE_FW_DWND_HIGH)) { + EnableFwDnldMode(true); + } + + return ret; +} + +/******************************************************************************* +** +** Function GetNfcState +** +** Description Get NFC state +** +** Parameters pDevHandle - valid device handle +** Returns 0 - unknown +** 1 - FW DWL +** 2 - NCI +** +*******************************************************************************/ +int NfccAltTransport::GetNfcState(void* pDevHandle) { + int ret = NFC_STATE_UNKNOWN; + NXPLOG_TML_D("%s ", __func__); + if (NULL == pDevHandle) { + return ret; + } + ret = ioctl((intptr_t)pDevHandle, NFC_GET_NFC_STATE); + NXPLOG_TML_D("%s :nfc state = %d", __func__, ret); + return ret; +} +/******************************************************************************* +** +** Function EnableFwDnldMode +** +** Description updates the state to Download mode +** +** Parameters True/False +** +** Returns None +*******************************************************************************/ +void NfccAltTransport::EnableFwDnldMode(bool mode) { bFwDnldFlag = mode; } + +/******************************************************************************* +** +** Function IsFwDnldModeEnabled +** +** Description Returns the current mode +** +** Parameters none +** +** Returns Current mode download/NCI +*******************************************************************************/ +bool_t NfccAltTransport::IsFwDnldModeEnabled(void) { return bFwDnldFlag; } + +/******************************************************************************* +** +** Function SemPost +** +** Description sem_post 2c_read / write +** +** Parameters none +** +** Returns none +*******************************************************************************/ +void NfccAltTransport::SemPost() { + int sem_val = 0; + sem_getvalue(&mTxRxSemaphore, &sem_val); + if (sem_val == 0) { + sem_post(&mTxRxSemaphore); + } +} + +/******************************************************************************* +** +** Function SemTimedWait +** +** Description Timed sem_wait for avoiding i2c_read & write overlap +** +** Parameters none +** +** Returns Sem_wait return status +*******************************************************************************/ +int NfccAltTransport::SemTimedWait() { + NFCSTATUS status = NFCSTATUS_FAILED; + long sem_timedout = 500 * 1000 * 1000; + int s = 0; + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += 0; + ts.tv_nsec += sem_timedout; + while ((s = sem_timedwait(&mTxRxSemaphore, &ts)) == -1 && errno == EINTR) { + continue; /* Restart if interrupted by handler */ + } + if (s != -1) { + status = NFCSTATUS_SUCCESS; + } else if (errno == ETIMEDOUT && s == -1) { + NXPLOG_TML_E("%s :timed out errno = 0x%x", __func__, errno); + } + return status; +} + +/******************************************************************************* +** +** Function GetIrqState +** +** Description Get state of IRQ GPIO +** +** Parameters pDevHandle - valid device handle +** +** Returns The state of IRQ line i.e. +ve if read is pending else Zer0. +** In the case of IOCTL error, it returns -ve value. +** +*******************************************************************************/ +int NfccAltTransport::GetIrqState(void* pDevHandle) { + int ret = -1; + + NXPLOG_TML_D("%s Enter", __func__); + int len; + char buf[2]; + + if (iInterruptFd <= 0) { + NXPLOG_TML_E("Error with interrupt-detect pin (%d)", iInterruptFd); + return (-1); + } + + // Seek to the start of the file + lseek(iInterruptFd, SEEK_SET, 0); + + // Read the field_detect line + len = read(iInterruptFd, buf, 2); + + if (len != 2) { + NXPLOG_TML_E("Error with interrupt-detect pin (%s)", strerror(errno)); + return (0); + } + + NXPLOG_TML_D("%s exit: state = %d", __func__, (buf[0] != '0')); + return (buf[0] != '0'); +} + +int NfccAltTransport::verifyPin(int pin, int isoutput, int edge) { + char buf[40]; + // Check if gpio pin has already been created + int hasGpio = 0; + NXPLOG_TML_D("%s Enter", __func__); + sprintf(buf, "/sys/class/gpio/gpio%d", pin); + NXPLOG_TML_D("Pin %s\n", buf); + int fd = open(buf, O_RDONLY); + if (fd <= 0) { + // Pin not exported yet + NXPLOG_TML_D("Create pin %s\n", buf); + if ((fd = open("/sys/class/gpio/export", O_WRONLY)) > 0) { + sprintf(buf, "%d", pin); + if (write(fd, buf, strlen(buf)) == strlen(buf)) { + hasGpio = 1; + usleep(100 * 1000); + } + } else { + NXPLOG_TML_E("open failed for /sys/class/gpio/export\n"); + return -1; + } + } else { + NXPLOG_TML_E("System already has pin %s\n", buf); + hasGpio = 1; + } + close(fd); + + if (hasGpio) { + // Make sure it is an output + sprintf(buf, "/sys/class/gpio/gpio%d/direction", pin); + NXPLOG_TML_D("Direction %s\n", buf); + fd = open(buf, O_WRONLY); + if (fd <= 0) { + NXPLOG_TML_E("Could not open direction port '%s' (%s)", buf, + strerror(errno)); + return -1; + } else { + if (isoutput) { + if (write(fd, "out", 3) == 3) { + NXPLOG_TML_D("Pin %d now an output\n", pin); + } + close(fd); + + // Open pin and make sure it is off + sprintf(buf, "/sys/class/gpio/gpio%d/value", pin); + fd = open(buf, O_RDWR); + if (fd <= 0) { + } + close(fd); + + // Open pin and make sure it is off + sprintf(buf, "/sys/class/gpio/gpio%d/value", pin); + fd = open(buf, O_RDWR); + if (fd <= 0) { + NXPLOG_TML_E("Could not open value port '%s' (%s)", buf, + strerror(errno)); + return -1; + } else { + if (write(fd, "0", 1) == 1) { + NXPLOG_TML_D("Pin %d now off\n", pin); + } + return (fd); // Success + } + } else { + if (write(fd, "in", 2) == 2) { + NXPLOG_TML_D("Pin %d now an input\n", pin); + } + close(fd); + + if (edge != EDGE_NONE) { + // Open pin edge control + sprintf(buf, "/sys/class/gpio/gpio%d/edge", pin); + NXPLOG_TML_D("Edge %s\n", buf); + fd = open(buf, O_RDWR); + if (fd <= 0) { + NXPLOG_TML_E("Could not open edge port '%s' (%s)", buf, + strerror(errno)); + return -1; + } else { + char* edge_str = "none"; + switch (edge) { + case EDGE_RISING: + edge_str = "rising"; + break; + case EDGE_FALLING: + edge_str = "falling"; + break; + case EDGE_BOTH: + edge_str = "both"; + break; + } + int l = strlen(edge_str); + NXPLOG_TML_D("Edge-string %s - %d\n", edge_str, l); + if (write(fd, edge_str, l) == l) { + NXPLOG_TML_D("Pin %d trigger on %s\n", pin, edge_str); + } + close(fd); + } + } + + // Open pin + sprintf(buf, "/sys/class/gpio/gpio%d/value", pin); + NXPLOG_TML_D("Value %s\n", buf); + fd = open(buf, O_RDONLY); + if (fd <= 0) { + NXPLOG_TML_E("Could not open value port '%s' (%s)", buf, + strerror(errno)); + return -1; + } else { + return (fd); // Success + } + } + } + } + return (0); +} +void NfccAltTransport::gpio_set_ven(int value) { + if (iEnableFd > 0) { + if (value == 0) { + write(iEnableFd, "0", 1); + } else { + write(iEnableFd, "1", 1); + } + usleep(10 * 1000); + } +} + +void NfccAltTransport::gpio_set_fwdl(int value) { + if (iFwDnldFd > 0) { + if (value == 0) { + write(iFwDnldFd, "0", 1); + } else { + write(iFwDnldFd, "1", 1); + } + usleep(10 * 1000); + } +} + +void NfccAltTransport::wait4interrupt(void) { + /* Open STREAMS device. */ + struct pollfd fds[1]; + fds[0].fd = iInterruptFd; + fds[0].events = POLLPRI; + int timeout_msecs = -1; // 100000; + int ret; + // usleep(500000); + while (!GetIrqState(NULL)) { + // Wait for an edge on the GPIO pin to get woken up + ret = poll(fds, 1, timeout_msecs); + if (ret != 1) { + NXPLOG_TML_D("wait4interrupt() %d - %s, ", ret, strerror(errno)); + } + } +} + +/***************************************************************************** + ** + ** Function ConfigurePin + ** + ** Description Configure Pins such as IRQ, VEN, Firmware Download + ** + ** Parameters none + ** + ** Returns NFCSTATUS_SUCCESS - on Success/ -1 on Failure + ****************************************************************************/ +int NfccAltTransport::ConfigurePin() +{ + unsigned long pinInt = PIN_INT; // Default fallback values + unsigned long pinEnable = PIN_ENABLE; + unsigned long pinFwdnld = PIN_FWDNLD; + + // Try to read GPIO pins from config file + GetNxpNumValue("NXP_GPIO_INT", &pinInt, sizeof(pinInt)); + GetNxpNumValue("NXP_GPIO_ENABLE", &pinEnable, sizeof(pinEnable)); + GetNxpNumValue("NXP_GPIO_FWDNLD", &pinFwdnld, sizeof(pinFwdnld)); + + NXPLOG_TML_D("Using GPIO pins from config: INT=%lu, ENABLE=%lu, FWDNLD=%lu", + pinInt, pinEnable, pinFwdnld); + + // Assign IO pins + iInterruptFd = verifyPin(pinInt, 0, EDGE_RISING); + if (iInterruptFd < 0) return (NFCSTATUS_INVALID_DEVICE); + iEnableFd = verifyPin(pinEnable, 1, EDGE_NONE); + if (iEnableFd < 0) return (NFCSTATUS_INVALID_DEVICE); + iFwDnldFd = verifyPin(pinFwdnld, 1, EDGE_NONE); + if (iFwDnldFd < 0) return (NFCSTATUS_INVALID_DEVICE); + return NFCSTATUS_SUCCESS; +} diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/NfccAltTransport.h b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/NfccAltTransport.h new file mode 100755 index 0000000..54e397f --- /dev/null +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/NfccAltTransport.h @@ -0,0 +1,127 @@ +/****************************************************************************** + * + * Copyright 2021 NXP + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#pragma once +#include +#include +#include +#include + +#define I2C_ADDRESS 0x28 +#define I2C_BUS "/dev/i2c-1" +#define SPI_BUS "/dev/spidev0.0" +// Default GPIO pin values (system GPIO numbers for Raspberry Pi CM4) +// These are fallback values - actual pins are read from libnfc-nxp.conf +#define PIN_INT 535 // GPIO23 -> system GPIO 535 (default) +#define PIN_ENABLE 536 // GPIO24 -> system GPIO 536 (default) +#define PIN_FWDNLD 537 // GPIO25 -> system GPIO 537 (default) +#define EDGE_NONE 0 +#define EDGE_RISING 1 +#define EDGE_FALLING 2 +#define EDGE_BOTH 3 +#define CRC_LEN 2 +#define NORMAL_MODE_HEADER_LEN 3 +#define FW_DNLD_HEADER_LEN 2 +#define FW_DNLD_LEN_OFFSET 1 +#define NORMAL_MODE_LEN_OFFSET 2 +#define FRAGMENTSIZE_MAX PHNFC_I2C_FRAGMENT_SIZE +extern phTmlNfc_i2cfragmentation_t fragmentation_enabled; + +class NfccAltTransport : public NfccTransport { + public: + NfccAltTransport(); + bool_t bFwDnldFlag = false; + sem_t mTxRxSemaphore; + int iEnableFd; + int iInterruptFd; + int iFwDnldFd; + + public: + void gpio_set_ven(int value); + void gpio_set_fwdl(int value); + int verifyPin(int pin, int isoutput, int edge); + void wait4interrupt(void); + int SemTimedWait(); + void SemPost(); + int Flushdata(void* pDevHandle, uint8_t* pBuffer, int numRead); + /***************************************************************************** + ** + ** Function Reset + ** + ** Description Reset NFCC device, using VEN pin + ** + ** Parameters pDevHandle - valid device handle + ** level - reset level + ** + ** Returns 0 - reset operation success + ** -1 - reset operation failure + ** + ****************************************************************************/ + int NfccReset(void* pDevHandle, NfccResetType eType); + + /***************************************************************************** + ** + ** Function EnableFwDnldMode + ** + ** Description updates the state to Download mode + ** + ** Parameters True/False + ** + ** Returns None + ****************************************************************************/ + void EnableFwDnldMode(bool mode); + + /***************************************************************************** + ** + ** Function IsFwDnldModeEnabled + ** + ** Description Returns the current mode + ** + ** Parameters none + ** + ** Returns Current mode download/NCI + ****************************************************************************/ + bool_t IsFwDnldModeEnabled(void); + + /******************************************************************************* + ** + ** Function GetIrqState + ** + ** Description Get state of IRQ GPIO + ** + ** Parameters pDevHandle - valid device handle + ** + ** Returns The state of IRQ line i.e. +ve if read is pending else + *Zer0. + ** In the case of IOCTL error, it returns -ve value. + ** + *******************************************************************************/ + int GetIrqState(void* pDevHandle); + int GetNfcState(void* pDevHandle); + /***************************************************************************** + ** + ** Function ConfigurePin + ** + ** Description Configure Pins such as IRQ, VEN, Firmware Download + ** + ** Parameters none + ** + ** Returns NFCSTATUS_SUCCESS - on Success/ -1 on Failure + ****************************************************************************/ + int ConfigurePin(); +}; From 59426362726aceca95547642d7f119efc1b292f1 Mon Sep 17 00:00:00 2001 From: Alex Hoffmann Date: Mon, 29 Sep 2025 13:46:53 +0200 Subject: [PATCH 2/6] Fixed pointer dereferencing --- src/service/linux_nfc_api.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service/linux_nfc_api.cpp b/src/service/linux_nfc_api.cpp index e9229de..63af088 100644 --- a/src/service/linux_nfc_api.cpp +++ b/src/service/linux_nfc_api.cpp @@ -379,7 +379,7 @@ int doWriteT4tData(unsigned char *command, unsigned char *ndef_buffer, int ndef_ int doReadT4tData(unsigned char *command, unsigned char *ndef_buffer, int *ndef_buffer_length) { int ret = 0; - if (ndef_buffer == NULL || ndef_buffer_length <= 0) { + if (ndef_buffer == NULL || *ndef_buffer_length <= 0) { NXPLOG_API_E ("%s: invalide buffer!", __FUNCTION__); return NFA_STATUS_FAILED; } From a6f336e81d684e72b7219449e2c9ed28a610156e Mon Sep 17 00:00:00 2001 From: Alex Hoffmann Date: Mon, 29 Sep 2025 13:47:24 +0200 Subject: [PATCH 3/6] Added a few helper scripts and setup guides --- RASPBERRY_PI_INTEGRATION_GUIDE.md | 266 +++++++++++++++++++++++++ RASPBERRY_PI_SETUP.md | 310 ++++++++++++++++++++++++++++++ pn7160_boot_setup.sh | 114 +++++++++++ pn7160_hardware_test.sh | 141 ++++++++++++++ pn7160_setup_gpio.sh | 148 ++++++++++++++ 5 files changed, 979 insertions(+) create mode 100644 RASPBERRY_PI_INTEGRATION_GUIDE.md create mode 100644 RASPBERRY_PI_SETUP.md create mode 100755 pn7160_boot_setup.sh create mode 100755 pn7160_hardware_test.sh create mode 100755 pn7160_setup_gpio.sh diff --git a/RASPBERRY_PI_INTEGRATION_GUIDE.md b/RASPBERRY_PI_INTEGRATION_GUIDE.md new file mode 100644 index 0000000..9f3d98b --- /dev/null +++ b/RASPBERRY_PI_INTEGRATION_GUIDE.md @@ -0,0 +1,266 @@ +# PN7160 Integration with Raspberry Pi CM4 - Complete Guide + +## Overview +This guide provides comprehensive 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 +Configure for ALT_I2C transport (direct I2C access): + +```bash +# Edit /home/alex/linux_libnfc-nci/conf/libnfc-nxp.conf + +# Set transport type to ALT_I2C +NXP_TRANSPORT=0x02 + +# I2C Configuration +I2C_BUS=1 +I2C_ADDRESS=0x28 + +# GPIO Pin Configuration (compiled into library) +# Uses system GPIO numbers for sysfs access: +PIN_INT=535 # Logical GPIO23 +PIN_ENABLE=536 # Logical GPIO24 +PIN_FWDNLD=537 # Logical GPIO25 +``` + +#### B. Install Configuration +```bash +sudo mkdir -p /usr/local/etc +sudo cp conf/libnfc-nxp.conf /usr/local/etc/ +sudo cp conf/libnfc-nci.conf /usr/local/etc/ +``` + +## 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 +``` + +Or run the full setup script again: +```bash +sudo ./pn7160_setup_gpio.sh +``` + +### Verification Scripts +Use these scripts to test your setup: + +```bash +# Hardware connection test +sudo ./pn7160_hardware_test.sh + +# Complete troubleshooting +sudo ./pn7160_troubleshoot.sh + +# Quick GPIO status check +sudo ./pn7160_control.sh +``` + +## Testing + +### 1. Basic Functionality Test +```bash +# Run NFC demo in polling mode +sudo ./nfcDemoApp poll +``` + +### 2. Debug Mode +```bash +# Run with debug logging +sudo NXPLOG_EXTNS_LOGLEVEL=0x03 NXPLOG_NCIHAL_LOGLEVEL=0x03 NXPLOG_TML_LOGLEVEL=0x03 ./nfcDemoApp poll +``` + +## 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 modern `gpiod` tools instead of sysfs + - Check if pins are already in use + +### Hardware Verification Checklist + +- [ ] All connections secure and correct +- [ ] Power supply adequate (3.3V or 5V as required) +- [ ] Ground connections established +- [ ] I2C enabled in Raspberry Pi configuration +- [ ] GPIO setup completed: `sudo ./pn7160_setup_gpio.sh` +- [ ] VEN pin properly controlled (logical GPIO24) +- [ ] No short circuits or loose connections + +## Alternative Approaches + +### 1. 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 + +### 2. Different I2C Buses +If the default I2C bus doesn't work, try: +- I2C bus 20: `/dev/i2c-20` +- I2C bus 21: `/dev/i2c-21` +- Update `I2C_BUS` setting 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) + +# Debug logging levels +export NXPLOG_EXTNS_LOGLEVEL=0x03 +export NXPLOG_NCIHAL_LOGLEVEL=0x03 +export NXPLOG_TML_LOGLEVEL=0x03 +``` + +## 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) + +## Support Scripts Created + +1. `pn7160_control.sh` - GPIO control script +2. `pn7160_troubleshoot.sh` - Comprehensive troubleshooting +3. Custom compiled library with Raspberry Pi GPIO pins + +## Next Steps + +Once hardware communication is established: +1. Test basic NFC operations (polling, reading tags) +2. Implement your specific NFC application +3. Consider power management and optimization +4. Integrate with your larger system + +For additional support, consult the NXP documentation and community forums. \ No newline at end of file diff --git a/RASPBERRY_PI_SETUP.md b/RASPBERRY_PI_SETUP.md new file mode 100644 index 0000000..4653b60 --- /dev/null +++ b/RASPBERRY_PI_SETUP.md @@ -0,0 +1,310 @@ +# PN7160 Integration Guide for Raspberry Pi Compute Module 4 (CM4) + +This guide helps you integrate the NXP PN7160 NFC controller (OM27160A1EVK) with the Raspberry Pi Compute Module 4. + +## Hardware Setup + +### Required Hardware +- Raspberry Pi Compute Module 4 with I/O board +- NXP OM27160A1EVK development kit +- Jumper wires for connections +- 3.3V or 5V power supply (depending on PN7160 board configuration) + +### Wiring Connections + +Connect the OM27160A1EVK to the Raspberry Pi CM4 as follows: + +| OM27160A1EVK Pin | Raspberry Pi CM4 Pin | GPIO | Function | +|------------------|---------------------|------|----------| +| VCC (3.3V/5V) | 3.3V or 5V Power | - | Power | +| GND | Ground | - | Ground | +| SDA | Pin 3 | GPIO 2 | I2C1 Data | +| SCL | Pin 5 | GPIO 3 | I2C1 Clock | +| IRQ | Pin 16 | GPIO 23 | Interrupt | +| VEN (Enable) | Pin 18 | GPIO 24 | Enable/Reset | +| DWL_REQ (optional) | Pin 22 | GPIO 25 | FW Download Request | + +### Hardware Notes +- Ensure proper power supply (3.3V recommended for Pi compatibility) +- Use short, good quality jumper wires +- Double-check all connections before powering on +- The PN7160 I2C address is 0x28 (default) + +## Software Setup + +### 1. Enable I2C on Raspberry Pi + +```bash +# Enable I2C interface +sudo raspi-config +# Navigate to: Interfacing Options -> I2C -> Enable + +# Or enable via command line: +sudo modprobe i2c-dev +sudo modprobe i2c-bcm2708 + +# Verify I2C is working +i2cdetect -y 1 +``` + +### 2. Install Dependencies + +```bash +# Update system +sudo apt update && sudo apt upgrade -y + +# Install build dependencies +sudo apt install -y build-essential autotools-dev libtool pkg-config + +# Install I2C tools for testing +sudo apt install -y i2c-tools + +# Ensure user is in i2c group (should already be done on Raspberry Pi OS) +sudo usermod -a -G i2c $USER +``` + +### 3. Build and Install the NFC Library + +The library is already built and installed in your system. The following files have been installed: + +```bash +# Libraries +/usr/local/lib/libnfc_nci_linux.so +/usr/local/lib/libpn7160_fw.so + +# Headers +/usr/local/include/linux_nfc_api.h +/usr/local/include/linux_nfc_factory_api.h +/usr/local/include/linux_nfc_api_compatibility.h + +# Configuration files +/usr/local/etc/libnfc-nci.conf +/usr/local/etc/libnfc-nxp.conf +/usr/local/etc/libnfc-nxp-rpi.conf # Raspberry Pi specific config + +# Demo application +/usr/local/sbin/nfcDemoApp + +# Package config +/usr/local/lib/pkgconfig/libnfc-nci.pc +``` + +### 4. Update Library Path + +```bash +# Add library path to ldconfig +echo '/usr/local/lib' | sudo tee /etc/ld.so.conf.d/libnfc-nci.conf +sudo ldconfig +``` + +### 5. Configure for Raspberry Pi + +The Raspberry Pi specific configuration uses the ALT_I2C transport which provides direct I2C access without requiring a kernel driver: + +```bash +# Use the Raspberry Pi specific configuration +sudo cp /usr/local/etc/libnfc-nxp-rpi.conf /usr/local/etc/libnfc-nxp.conf +``` + +### 6. GPIO Permissions + +Ensure proper GPIO permissions: + +```bash +# Add user to gpio group (should already be done on Raspberry Pi OS) +sudo usermod -a -G gpio $USER + +# You may need to log out and back in for group changes to take effect +``` + +## Boot Persistence and GPIO Setup + +**CRITICAL**: GPIO settings do not persist after reboot. You must set up GPIO pins every time the system boots. + +### Automated Setup (Recommended) + +Run the GPIO setup script and choose to create a systemd service: +```bash +sudo ./pn7160_setup_gpio.sh +# When prompted, choose 'y' to create boot service +``` + +### Manual Setup After Each Reboot + +If you didn't create the automatic service, run this after every reboot: +```bash +sudo ./pn7160_boot_setup.sh +``` + +### Verification + +Always run a verification script before using NFC: +```bash +# Quick hardware test +sudo ./pn7160_hardware_test.sh + +# Full troubleshooting if needed +sudo ./pn7160_troubleshoot.sh +``` + +## Testing the Integration + +### 1. Check I2C Communication + +```bash +# Scan I2C bus for devices +i2cdetect -y 1 + +# You should see device 0x28 if the PN7160 is properly connected and powered +``` + +### 2. Test GPIO Access + +**IMPORTANT: Use the provided setup scripts instead of manual GPIO setup:** + +```bash +# Use the automated GPIO setup script (recommended) +sudo ./pn7160_setup_gpio.sh + +# Or use the boot setup script +sudo ./pn7160_boot_setup.sh +``` + +For manual testing only (not recommended for regular use): +```bash +# 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 +``` + +### 3. Run the Demo Application + +```bash +# Run the NFC demo application (requires root for GPIO access) +sudo /usr/local/sbin/nfcDemoApp + +# Or run from build directory +cd /home/alex/linux_libnfc-nci +sudo ./nfcDemoApp +``` + +## Configuration Details + +### Transport Configuration + +The Raspberry Pi setup uses the ALT_I2C transport (`NXP_TRANSPORT=0x02`) which: +- Accesses I2C directly via `/dev/i2c-1` +- Controls GPIO pins via sysfs (`/sys/class/gpio/`) +- Does not require kernel driver installation +- Uses I2C address 0x28 + +### GPIO Pin Configuration + +**IMPORTANT**: The compiled library uses system GPIO numbers for sysfs access: + +- **GPIO 23 (PIN_INT)**: Interrupt from PN7160 to Pi (system GPIO 535) +- **GPIO 24 (PIN_ENABLE)**: Enable/Reset signal from Pi to PN7160 (system GPIO 536) +- **GPIO 25 (PIN_FWDNLD)**: Firmware download request (system GPIO 537) + +**Note**: Modern Raspberry Pi systems map logical GPIO numbers to different system GPIO numbers in sysfs. The library automatically handles this mapping. + +### I2C Configuration + +- **Bus**: /dev/i2c-1 (I2C1 on Raspberry Pi) +- **Address**: 0x28 (PN7160 default) +- **Speed**: Standard mode (100kHz) or Fast mode (400kHz) + +## Troubleshooting + +### Common Issues + +1. **Permission denied accessing /dev/i2c-1** + - Ensure user is in i2c group: `sudo usermod -a -G i2c $USER` + - Log out and back in for group changes to take effect + +2. **Permission denied accessing GPIO** + - Run with sudo initially: `sudo /usr/local/sbin/nfcDemoApp` + - Ensure user is in gpio group: `sudo usermod -a -G gpio $USER` + +3. **I2C device not found** + - Check wiring connections + - Verify power supply to PN7160 + - Run `i2cdetect -y 1` to scan for devices + - Should see device at address 0x28 + +4. **Library not found errors** + - Run `sudo ldconfig` to update library cache + - Check `/etc/ld.so.conf.d/libnfc-nci.conf` exists + +5. **GPIO export fails** + - Check if pins are already in use: `ls /sys/class/gpio/` + - Try different GPIO pins if needed + - Ensure GPIO pins are available on your Pi model + +### Debug Options + +Enable debugging by modifying `/usr/local/etc/libnfc-nxp.conf`: + +``` +# Set logging levels to debug (0x03) +NXPLOG_EXTNS_LOGLEVEL=0x03 +NXPLOG_NCIHAL_LOGLEVEL=0x03 +NXPLOG_NCIX_LOGLEVEL=0x03 +NXPLOG_NCIR_LOGLEVEL=0x03 +NXPLOG_FWDNLD_LOGLEVEL=0x03 +NXPLOG_TML_LOGLEVEL=0x03 +``` + +### Advanced Configuration + +For custom GPIO pins, modify the source code in: +``` +src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h +``` + +Change the pin definitions: +```cpp +#define PIN_INT 23 // Interrupt pin +#define PIN_ENABLE 24 // Enable pin +#define PIN_FWDNLD 25 // Firmware download pin +``` + +Then rebuild and reinstall: +```bash +cd /home/alex/linux_libnfc-nci +make clean +make +sudo make install +``` + +## Next Steps + +Once the basic integration is working: + +1. **Develop Applications**: Use the `linux_nfc_api.h` header to develop custom NFC applications +2. **Performance Tuning**: Adjust RF parameters in configuration files +3. **Production Deployment**: Consider kernel driver approach for production systems +4. **Security**: Implement proper access controls for GPIO and I2C resources + +## References + +- [OM27160A1EVK Product Page](https://www.nxp.com/part/OM27160A1EVK) +- [AN13287: PN7160 Linux Integration Guide](https://www.nxp.com/docs/en/application-note/AN13287.pdf) +- [linux_libnfc-nci GitHub Repository](https://github.com/NXPNFCLinux/linux_libnfc-nci) +- [NXP NFC Controller Documentation](https://www.nxp.com/products/identification-and-security/nfc/nfc-reader-ics:NFC-READER) \ No newline at end of file diff --git a/pn7160_boot_setup.sh b/pn7160_boot_setup.sh new file mode 100755 index 0000000..62e13ab --- /dev/null +++ b/pn7160_boot_setup.sh @@ -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 \ No newline at end of file diff --git a/pn7160_hardware_test.sh b/pn7160_hardware_test.sh new file mode 100755 index 0000000..f2b371f --- /dev/null +++ b/pn7160_hardware_test.sh @@ -0,0 +1,141 @@ +#!/bin/bash + +echo "===================================" +echo "PN7160 Hardware Connection Guide" +echo "===================================" +echo "" +echo "Based on the NfccAltTransport.h file, the correct GPIO connections are:" +echo "" +echo "PN7160 Board Pin Raspberry Pi CM4 Pin GPIO Function" +echo "--------------- ------------------- ----- -----------" +echo "VCC Pin 1 or 17 3.3V/5V Power Supply" +echo "GND Pin 6, 9, 14, 20 GND Ground" +echo "SDA Pin 3 GPIO2 I2C Data" +echo "SCL Pin 5 GPIO3 I2C Clock" +echo "IRQ Pin 16 GPIO23 Interrupt" +echo "VEN/ENABLE Pin 18 GPIO24 Enable" +echo "DWL/FWDNLD Pin 22 GPIO25 Download Mode" +echo "" +echo "IMPORTANT: GPIO pin configuration!" +echo "The library uses system GPIO numbers for sysfs access:" +echo " Logical GPIO23 (Pin 16) = System GPIO 535 (PIN_INT)" +echo " Logical GPIO24 (Pin 18) = System GPIO 536 (PIN_ENABLE)" +echo " Logical GPIO25 (Pin 22) = System GPIO 537 (PIN_FWDNLD)" +echo "" +echo "These numbers are configurable in /usr/local/etc/libnfc-nxp.conf" +echo "" +echo "Physical Pin Layout on Raspberry Pi:" +echo " 3.3V [ 1] [ 2] 5V" +echo " GPIO2 [ 3] [ 4] 5V" +echo " GPIO3 [ 5] [ 6] GND" +echo " GPIO4 [ 7] [ 8] GPIO14" +echo " GND [ 9] [10] GPIO15" +echo " GPIO17 [11] [12] GPIO18" +echo " GPIO27 [13] [14] GND" +echo " GPIO22 [15] [16] GPIO23 <- IRQ" +echo " 3.3V [17] [18] GPIO24 <- VEN/ENABLE" +echo " GPIO10 [19] [20] GND" +echo " GPIO9 [21] [22] GPIO25 <- DWL" +echo " GPIO11 [23] [24] GPIO8" +echo " GND [25] [26] GPIO7" +echo "" + +# Test GPIO access using sysfs (same method as the NFC library) +echo "Testing GPIO pins using sysfs interface (same as NFC library)..." +echo "" + +# Read GPIO configuration from config file or use defaults +GPIO_INT=$(grep "NXP_GPIO_INT" /usr/local/etc/libnfc-nxp.conf 2>/dev/null | cut -d'=' -f2 || echo "535") +GPIO_ENABLE=$(grep "NXP_GPIO_ENABLE" /usr/local/etc/libnfc-nxp.conf 2>/dev/null | cut -d'=' -f2 || echo "536") +GPIO_FWDNLD=$(grep "NXP_GPIO_FWDNLD" /usr/local/etc/libnfc-nxp.conf 2>/dev/null | cut -d'=' -f2 || echo "537") + +echo "Using GPIO configuration:" +echo " INT (IRQ): GPIO$GPIO_INT" +echo " ENABLE (VEN): GPIO$GPIO_ENABLE" +echo " FWDNLD (DWL): GPIO$GPIO_FWDNLD" +echo "" + +# Setup GPIO pins using sysfs (same as library) +echo "Setting up GPIO pins..." +echo $GPIO_INT | sudo tee /sys/class/gpio/export >/dev/null 2>&1 +echo $GPIO_ENABLE | sudo tee /sys/class/gpio/export >/dev/null 2>&1 +echo $GPIO_FWDNLD | sudo tee /sys/class/gpio/export >/dev/null 2>&1 + +echo "in" | sudo tee /sys/class/gpio/gpio$GPIO_INT/direction >/dev/null 2>&1 +echo "out" | sudo tee /sys/class/gpio/gpio$GPIO_ENABLE/direction >/dev/null 2>&1 +echo "out" | sudo tee /sys/class/gpio/gpio$GPIO_FWDNLD/direction >/dev/null 2>&1 + +# Read current states +echo "Current GPIO states:" +echo " IRQ (GPIO$GPIO_INT): $(cat /sys/class/gpio/gpio$GPIO_INT/value 2>/dev/null || echo 'N/A')" +echo " VEN (GPIO$GPIO_ENABLE): $(cat /sys/class/gpio/gpio$GPIO_ENABLE/value 2>/dev/null || echo 'N/A')" +echo " DWL (GPIO$GPIO_FWDNLD): $(cat /sys/class/gpio/gpio$GPIO_FWDNLD/value 2>/dev/null || echo 'N/A')" + +echo "" +echo "Testing GPIO control (this will enable the PN7160):" + +# Set DWL low (normal mode) +echo "Setting DWL (GPIO$GPIO_FWDNLD) to LOW..." +echo "0" | sudo tee /sys/class/gpio/gpio$GPIO_FWDNLD/value >/dev/null + +# Set VEN high (enable device) +echo "Setting VEN (GPIO$GPIO_ENABLE) to HIGH..." +echo "1" | sudo tee /sys/class/gpio/gpio$GPIO_ENABLE/value >/dev/null + +echo "Waiting 2 seconds for PN7160 to initialize..." +sleep 2 + +echo "" +echo "Now scan I2C bus to see if PN7160 appears..." +i2cdetect -y 1 + +# Check for device at 0x28 (more precise detection) +if i2cdetect -y 1 | awk '/^20:/ {print $9}' | grep -q "28"; then + echo "" + echo "🎉 SUCCESS: PN7160 detected at address 0x28!" + echo "Hardware connection is working properly." +else + echo "" + echo "â„šī¸ NOTE: PN7160 not visible in I2C scan" + echo "This is normal when GPIO pins are actively managed." + echo "" + echo "Testing actual NFC functionality..." + echo "Trying to initialize NFC library..." + + # Test if NFC library can communicate + timeout 3s sudo nfcDemoApp poll >/dev/null 2>&1 & + NFC_PID=$! + sleep 2 + kill $NFC_PID >/dev/null 2>&1 + wait $NFC_PID >/dev/null 2>&1 + NFC_RESULT=$? + + if [ $NFC_RESULT -eq 0 ] || [ $NFC_RESULT -eq 143 ]; then + echo "🎉 SUCCESS: NFC library can communicate with PN7160!" + echo "Hardware connection is working properly." + echo "(I2C scan doesn't show device due to GPIO management)" + else + echo "❌ FAILURE: NFC library cannot communicate with PN7160" + echo "" + echo "Troubleshooting checklist:" + echo "1. Check power connections (VCC to 3.3V, GND to GND)" + echo "2. Verify I2C connections (SDA to GPIO2/Pin3, SCL to GPIO3/Pin5)" + echo "3. Check GPIO connections:" + echo " - IRQ to GPIO23/Pin16" + echo " - VEN to GPIO24/Pin18" + echo " - DWL to GPIO25/Pin22" + echo "4. Ensure PN7160 board is properly powered" + echo "5. Check for loose connections" + fi +fi + +echo "" +echo "Cleaning up GPIO exports..." +echo $GPIO_INT | sudo tee /sys/class/gpio/unexport >/dev/null 2>&1 +echo $GPIO_ENABLE | sudo tee /sys/class/gpio/unexport >/dev/null 2>&1 +echo $GPIO_FWDNLD | sudo tee /sys/class/gpio/unexport >/dev/null 2>&1 +echo "" +echo "Connection test complete!" +echo "" +echo "If you see address 0x28 in the I2C scan above, the PN7160 is connected!" +echo "If not, please double-check the wiring according to the pin layout above." diff --git a/pn7160_setup_gpio.sh b/pn7160_setup_gpio.sh new file mode 100755 index 0000000..97c8cd2 --- /dev/null +++ b/pn7160_setup_gpio.sh @@ -0,0 +1,148 @@ +#!/bin/bash + +echo "PN7160 GPIO Setup for NFC Demo" +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 | sudo tee /sys/class/gpio/export > /dev/null + sleep 0.2 + fi + + # Set direction + if [ -w "/sys/class/gpio/gpio$pin/direction" ]; then + echo "Setting GPIO$pin direction to $direction" + echo $direction | sudo tee /sys/class/gpio/gpio$pin/direction > /dev/null + 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 | sudo tee /sys/class/gpio/gpio$pin/value > /dev/null + 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" | sudo tee /sys/class/gpio/gpio$pin/edge > /dev/null + 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 | sudo tee /sys/class/gpio/unexport > /dev/null 2>&1 + 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 | sudo tee /sys/class/gpio/gpio$PIN_ENABLE/value > /dev/null + +# Wait for device to initialize +sleep 1 + +# Check GPIO status +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)" +else + echo "IRQ (GPIO$PIN_INT): Cannot read" +fi + +if [ -r "/sys/class/gpio/gpio$PIN_ENABLE/value" ]; then + echo "VEN (GPIO$PIN_ENABLE): $(cat /sys/class/gpio/gpio$PIN_ENABLE/value)" +else + echo "VEN (GPIO$PIN_ENABLE): Cannot read" +fi + +if [ -r "/sys/class/gpio/gpio$PIN_FWDNLD/value" ]; then + echo "DWL (GPIO$PIN_FWDNLD): $(cat /sys/class/gpio/gpio$PIN_FWDNLD/value)" +else + echo "DWL (GPIO$PIN_FWDNLD): Cannot read" +fi + +echo "" +echo "Scanning I2C bus for PN7160..." +i2cdetect -y 1 | grep "28" > /dev/null && echo "✅ PN7160 detected at address 0x28" || echo "❌ PN7160 not detected" + +echo "" +echo "GPIO setup complete!" + +# Ask if user wants to create a startup service for GPIO setup +echo "" +read -p "Do you want to create a systemd service to setup GPIO on boot? (y/n): " -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]]; then + echo "Creating systemd service for GPIO setup..." + + # Create the service file + sudo tee /etc/systemd/system/pn7160-gpio.service > /dev/null << EOF +[Unit] +Description=PN7160 NFC GPIO Setup +After=multi-user.target +DefaultDependencies=no + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/home/alex/linux_libnfc-nci/pn7160_setup_gpio.sh +User=root + +[Install] +WantedBy=multi-user.target +EOF + + # Enable and start the service + sudo systemctl daemon-reload + sudo systemctl enable pn7160-gpio.service + + echo "✅ Systemd service created and enabled!" + echo "GPIO will be automatically setup on every boot." + echo "You can check status with: sudo systemctl status pn7160-gpio.service" +else + echo "Skipped systemd service creation." + echo "Note: You'll need to run this script after each reboot." +fi + +echo "" +echo "You can now run: sudo ./nfcDemoApp poll" \ No newline at end of file From 49400232a3b7c5ad31d1aec02519dffa0aa2a182 Mon Sep 17 00:00:00 2001 From: Alex Hoffmann Date: Mon, 29 Sep 2025 17:38:29 +0200 Subject: [PATCH 4/6] Cleanup --- RASPBERRY_PI_INTEGRATION_GUIDE.md | 266 ------------- RASPBERRY_PI_SETUP.md | 367 +++++++----------- conf/libnfc-nxp.conf | 10 - .../halimpl/tml/transport/NfccAltTransport.h | 6 +- 4 files changed, 144 insertions(+), 505 deletions(-) delete mode 100644 RASPBERRY_PI_INTEGRATION_GUIDE.md diff --git a/RASPBERRY_PI_INTEGRATION_GUIDE.md b/RASPBERRY_PI_INTEGRATION_GUIDE.md deleted file mode 100644 index 9f3d98b..0000000 --- a/RASPBERRY_PI_INTEGRATION_GUIDE.md +++ /dev/null @@ -1,266 +0,0 @@ -# PN7160 Integration with Raspberry Pi CM4 - Complete Guide - -## Overview -This guide provides comprehensive 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 -Configure for ALT_I2C transport (direct I2C access): - -```bash -# Edit /home/alex/linux_libnfc-nci/conf/libnfc-nxp.conf - -# Set transport type to ALT_I2C -NXP_TRANSPORT=0x02 - -# I2C Configuration -I2C_BUS=1 -I2C_ADDRESS=0x28 - -# GPIO Pin Configuration (compiled into library) -# Uses system GPIO numbers for sysfs access: -PIN_INT=535 # Logical GPIO23 -PIN_ENABLE=536 # Logical GPIO24 -PIN_FWDNLD=537 # Logical GPIO25 -``` - -#### B. Install Configuration -```bash -sudo mkdir -p /usr/local/etc -sudo cp conf/libnfc-nxp.conf /usr/local/etc/ -sudo cp conf/libnfc-nci.conf /usr/local/etc/ -``` - -## 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 -``` - -Or run the full setup script again: -```bash -sudo ./pn7160_setup_gpio.sh -``` - -### Verification Scripts -Use these scripts to test your setup: - -```bash -# Hardware connection test -sudo ./pn7160_hardware_test.sh - -# Complete troubleshooting -sudo ./pn7160_troubleshoot.sh - -# Quick GPIO status check -sudo ./pn7160_control.sh -``` - -## Testing - -### 1. Basic Functionality Test -```bash -# Run NFC demo in polling mode -sudo ./nfcDemoApp poll -``` - -### 2. Debug Mode -```bash -# Run with debug logging -sudo NXPLOG_EXTNS_LOGLEVEL=0x03 NXPLOG_NCIHAL_LOGLEVEL=0x03 NXPLOG_TML_LOGLEVEL=0x03 ./nfcDemoApp poll -``` - -## 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 modern `gpiod` tools instead of sysfs - - Check if pins are already in use - -### Hardware Verification Checklist - -- [ ] All connections secure and correct -- [ ] Power supply adequate (3.3V or 5V as required) -- [ ] Ground connections established -- [ ] I2C enabled in Raspberry Pi configuration -- [ ] GPIO setup completed: `sudo ./pn7160_setup_gpio.sh` -- [ ] VEN pin properly controlled (logical GPIO24) -- [ ] No short circuits or loose connections - -## Alternative Approaches - -### 1. 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 - -### 2. Different I2C Buses -If the default I2C bus doesn't work, try: -- I2C bus 20: `/dev/i2c-20` -- I2C bus 21: `/dev/i2c-21` -- Update `I2C_BUS` setting 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) - -# Debug logging levels -export NXPLOG_EXTNS_LOGLEVEL=0x03 -export NXPLOG_NCIHAL_LOGLEVEL=0x03 -export NXPLOG_TML_LOGLEVEL=0x03 -``` - -## 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) - -## Support Scripts Created - -1. `pn7160_control.sh` - GPIO control script -2. `pn7160_troubleshoot.sh` - Comprehensive troubleshooting -3. Custom compiled library with Raspberry Pi GPIO pins - -## Next Steps - -Once hardware communication is established: -1. Test basic NFC operations (polling, reading tags) -2. Implement your specific NFC application -3. Consider power management and optimization -4. Integrate with your larger system - -For additional support, consult the NXP documentation and community forums. \ No newline at end of file diff --git a/RASPBERRY_PI_SETUP.md b/RASPBERRY_PI_SETUP.md index 4653b60..2fbda6f 100644 --- a/RASPBERRY_PI_SETUP.md +++ b/RASPBERRY_PI_SETUP.md @@ -1,177 +1,201 @@ -# PN7160 Integration Guide for Raspberry Pi Compute Module 4 (CM4) +# PN7160 Integration with Raspberry Pi CM4 -This guide helps you integrate the NXP PN7160 NFC controller (OM27160A1EVK) with the Raspberry Pi Compute Module 4. +This guide provides instructions for integrating the NXP PN7160 NFC controller (OM27160A1EVK development kit) with a Raspberry Pi Compute Module 4. ## Hardware Setup -### Required Hardware -- Raspberry Pi Compute Module 4 with I/O board -- NXP OM27160A1EVK development kit -- Jumper wires for connections -- 3.3V or 5V power supply (depending on PN7160 board configuration) +### Required Connections +Connect the OM27160A1EVK to your Raspberry Pi CM4 as follows: -### Wiring Connections +| 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 | -Connect the OM27160A1EVK to the Raspberry Pi CM4 as follows: - -| OM27160A1EVK Pin | Raspberry Pi CM4 Pin | GPIO | Function | -|------------------|---------------------|------|----------| -| VCC (3.3V/5V) | 3.3V or 5V Power | - | Power | -| GND | Ground | - | Ground | -| SDA | Pin 3 | GPIO 2 | I2C1 Data | -| SCL | Pin 5 | GPIO 3 | I2C1 Clock | -| IRQ | Pin 16 | GPIO 23 | Interrupt | -| VEN (Enable) | Pin 18 | GPIO 24 | Enable/Reset | -| DWL_REQ (optional) | Pin 22 | GPIO 25 | FW Download Request | - -### Hardware Notes -- Ensure proper power supply (3.3V recommended for Pi compatibility) -- Use short, good quality jumper wires -- Double-check all connections before powering on -- The PN7160 I2C address is 0x28 (default) +### 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. Enable I2C on Raspberry Pi - +### 1. Repository and Branch ```bash -# Enable I2C interface -sudo raspi-config -# Navigate to: Interfacing Options -> I2C -> Enable - -# Or enable via command line: -sudo modprobe i2c-dev -sudo modprobe i2c-bcm2708 - -# Verify I2C is working -i2cdetect -y 1 +git clone https://github.com/NXPNFCLinux/linux_libnfc-nci.git +cd linux_libnfc-nci +git checkout NCI2.0_PN7160 ``` ### 2. Install Dependencies - ```bash -# Update system -sudo apt update && sudo apt upgrade -y - -# Install build dependencies -sudo apt install -y build-essential autotools-dev libtool pkg-config - -# Install I2C tools for testing -sudo apt install -y i2c-tools - -# Ensure user is in i2c group (should already be done on Raspberry Pi OS) -sudo usermod -a -G i2c $USER +sudo apt update +sudo apt install build-essential libtool autoconf automake i2c-tools gpiod ``` -### 3. Build and Install the NFC Library +### 3. Enable I2C +```bash +sudo raspi-config +# Navigate to Interfacing Options -> I2C -> Enable +sudo reboot +``` -The library is already built and installed in your system. The following files have been installed: +### 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 -# Libraries -/usr/local/lib/libnfc_nci_linux.so -/usr/local/lib/libpn7160_fw.so +./bootstrap +./configure +make clean +make +sudo make install +``` -# Headers -/usr/local/include/linux_nfc_api.h -/usr/local/include/linux_nfc_factory_api.h -/usr/local/include/linux_nfc_api_compatibility.h +### 5. Configuration Files -# Configuration files -/usr/local/etc/libnfc-nci.conf -/usr/local/etc/libnfc-nxp.conf -/usr/local/etc/libnfc-nxp-rpi.conf # Raspberry Pi specific config +#### A. libnfc-nxp.conf +Edit conf/libnfc-nxp.conf to configure for ALT_I2C transport (direct I2C access): -# Demo application -/usr/local/sbin/nfcDemoApp +```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 -# Package config -/usr/local/lib/pkgconfig/libnfc-nci.pc +############################################################################### +# Nfc Device Node name +NXP_NFC_DEV_NODE="/dev/i2c-1" ``` -### 4. Update Library Path +## Hardware Verification +### 1. Check I2C Bus ```bash -# Add library path to ldconfig -echo '/usr/local/lib' | sudo tee /etc/ld.so.conf.d/libnfc-nci.conf -sudo ldconfig -``` +# List I2C buses +i2cdetect -l -### 5. Configure for Raspberry Pi - -The Raspberry Pi specific configuration uses the ALT_I2C transport which provides direct I2C access without requiring a kernel driver: +# Scan I2C bus 1 for devices +i2cdetect -y 1 +``` +### 2. Test GPIO Control ```bash -# Use the Raspberry Pi specific configuration -sudo cp /usr/local/etc/libnfc-nxp-rpi.conf /usr/local/etc/libnfc-nxp.conf +# Enable PN7160 (set VEN high using logical GPIO number) +gpioset --mode=time --sec=5 gpiochip0 24=1 + +# Then scan I2C again +i2cdetect -y 1 ``` -### 6. GPIO Permissions +## GPIO Setup and Persistence -Ensure proper GPIO permissions: +### Initial GPIO Setup +After hardware connections are made, run the GPIO setup script: ```bash -# Add user to gpio group (should already be done on Raspberry Pi OS) -sudo usermod -a -G gpio $USER - -# You may need to log out and back in for group changes to take effect +sudo ./pn7160_setup_gpio.sh ``` -## Boot Persistence and GPIO Setup +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 -**CRITICAL**: GPIO settings do not persist after reboot. You must set up GPIO pins every time the system boots. +### Boot Persistence (Important!) +GPIO settings are not persistent across reboots. You have two options: -### Automated Setup (Recommended) +#### 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. -Run the GPIO setup script and choose to create a systemd service: +#### Option 2: Manual Setup After Reboot +If you didn't enable the automatic service, run this after each reboot: ```bash -sudo ./pn7160_setup_gpio.sh -# When prompted, choose 'y' to create boot service +sudo ./pn7160_boot_setup.sh ``` -### Manual Setup After Each Reboot +### Verification Scripts +Use these scripts to test your setup: -If you didn't create the automatic service, run this after every reboot: ```bash -sudo ./pn7160_boot_setup.sh +# Hardware connection test +sudo ./pn7160_hardware_test.sh ``` -### Verification +## Testing -Always run a verification script before using NFC: +### 1. Basic Functionality Test ```bash -# Quick hardware test -sudo ./pn7160_hardware_test.sh +# Run NFC demo in polling mode +nfcDemoApp poll +``` -# Full troubleshooting if needed -sudo ./pn7160_troubleshoot.sh +### 2. Debug Mode +```bash +# Run with debug logging +NXPLOG_EXTNS_LOGLEVEL=0x03 NXPLOG_NCIHAL_LOGLEVEL=0x03 NXPLOG_TML_LOGLEVEL=0x03 nfcDemoApp poll ``` -## Testing the Integration +## Troubleshooting -### 1. Check I2C Communication +### Common Issues -```bash -# Scan I2C bus for devices -i2cdetect -y 1 +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`) -# You should see device 0x28 if the PN7160 is properly connected and powered -``` +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 -### 2. Test GPIO Access +3. **Permission Denied Errors** + - Run with `sudo` for GPIO/I2C access + - Add user to i2c group: `sudo usermod -a -G i2c $USER` -**IMPORTANT: Use the provided setup scripts instead of manual GPIO setup:** +4. **GPIO Export Failures** + - Use `gpiod` tools instead of sysfs + - Check if pins are already in use -```bash -# Use the automated GPIO setup script (recommended) -sudo ./pn7160_setup_gpio.sh +## 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 -# Or use the boot setup script -sudo ./pn7160_boot_setup.sh -``` +## Useful Commands -For manual testing only (not recommended for regular use): ```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 @@ -193,118 +217,9 @@ echo 536 | sudo tee /sys/class/gpio/unexport echo 537 | sudo tee /sys/class/gpio/unexport ``` -### 3. Run the Demo Application - -```bash -# Run the NFC demo application (requires root for GPIO access) -sudo /usr/local/sbin/nfcDemoApp - -# Or run from build directory -cd /home/alex/linux_libnfc-nci -sudo ./nfcDemoApp -``` - -## Configuration Details - -### Transport Configuration - -The Raspberry Pi setup uses the ALT_I2C transport (`NXP_TRANSPORT=0x02`) which: -- Accesses I2C directly via `/dev/i2c-1` -- Controls GPIO pins via sysfs (`/sys/class/gpio/`) -- Does not require kernel driver installation -- Uses I2C address 0x28 - -### GPIO Pin Configuration - -**IMPORTANT**: The compiled library uses system GPIO numbers for sysfs access: - -- **GPIO 23 (PIN_INT)**: Interrupt from PN7160 to Pi (system GPIO 535) -- **GPIO 24 (PIN_ENABLE)**: Enable/Reset signal from Pi to PN7160 (system GPIO 536) -- **GPIO 25 (PIN_FWDNLD)**: Firmware download request (system GPIO 537) - -**Note**: Modern Raspberry Pi systems map logical GPIO numbers to different system GPIO numbers in sysfs. The library automatically handles this mapping. - -### I2C Configuration - -- **Bus**: /dev/i2c-1 (I2C1 on Raspberry Pi) -- **Address**: 0x28 (PN7160 default) -- **Speed**: Standard mode (100kHz) or Fast mode (400kHz) - -## Troubleshooting - -### Common Issues - -1. **Permission denied accessing /dev/i2c-1** - - Ensure user is in i2c group: `sudo usermod -a -G i2c $USER` - - Log out and back in for group changes to take effect - -2. **Permission denied accessing GPIO** - - Run with sudo initially: `sudo /usr/local/sbin/nfcDemoApp` - - Ensure user is in gpio group: `sudo usermod -a -G gpio $USER` - -3. **I2C device not found** - - Check wiring connections - - Verify power supply to PN7160 - - Run `i2cdetect -y 1` to scan for devices - - Should see device at address 0x28 - -4. **Library not found errors** - - Run `sudo ldconfig` to update library cache - - Check `/etc/ld.so.conf.d/libnfc-nci.conf` exists - -5. **GPIO export fails** - - Check if pins are already in use: `ls /sys/class/gpio/` - - Try different GPIO pins if needed - - Ensure GPIO pins are available on your Pi model - -### Debug Options - -Enable debugging by modifying `/usr/local/etc/libnfc-nxp.conf`: - -``` -# Set logging levels to debug (0x03) -NXPLOG_EXTNS_LOGLEVEL=0x03 -NXPLOG_NCIHAL_LOGLEVEL=0x03 -NXPLOG_NCIX_LOGLEVEL=0x03 -NXPLOG_NCIR_LOGLEVEL=0x03 -NXPLOG_FWDNLD_LOGLEVEL=0x03 -NXPLOG_TML_LOGLEVEL=0x03 -``` - -### Advanced Configuration - -For custom GPIO pins, modify the source code in: -``` -src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h -``` - -Change the pin definitions: -```cpp -#define PIN_INT 23 // Interrupt pin -#define PIN_ENABLE 24 // Enable pin -#define PIN_FWDNLD 25 // Firmware download pin -``` - -Then rebuild and reinstall: -```bash -cd /home/alex/linux_libnfc-nci -make clean -make -sudo make install -``` - -## Next Steps - -Once the basic integration is working: - -1. **Develop Applications**: Use the `linux_nfc_api.h` header to develop custom NFC applications -2. **Performance Tuning**: Adjust RF parameters in configuration files -3. **Production Deployment**: Consider kernel driver approach for production systems -4. **Security**: Implement proper access controls for GPIO and I2C resources - -## References +## Documentation References - [OM27160A1EVK Product Page](https://www.nxp.com/part/OM27160A1EVK) -- [AN13287: PN7160 Linux Integration Guide](https://www.nxp.com/docs/en/application-note/AN13287.pdf) -- [linux_libnfc-nci GitHub Repository](https://github.com/NXPNFCLinux/linux_libnfc-nci) -- [NXP NFC Controller Documentation](https://www.nxp.com/products/identification-and-security/nfc/nfc-reader-ics:NFC-READER) \ No newline at end of file +- [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) \ No newline at end of file diff --git a/conf/libnfc-nxp.conf b/conf/libnfc-nxp.conf index 6bc2ca5..176b44a 100755 --- a/conf/libnfc-nxp.conf +++ b/conf/libnfc-nxp.conf @@ -33,16 +33,6 @@ NXP_TRANSPORT=0x02 # Nfc Device Node name NXP_NFC_DEV_NODE="/dev/i2c-1" -############################################################################### -# GPIO Pin Configuration for ALT transport (Raspberry Pi CM4) -# These are system GPIO numbers for sysfs access (/sys/class/gpio/gpioXXX) -# GPIO 23 (Pin 16) -> System GPIO 535 -# GPIO 24 (Pin 18) -> System GPIO 536 -# GPIO 25 (Pin 22) -> System GPIO 537 -NXP_GPIO_INT=535 -NXP_GPIO_ENABLE=536 -NXP_GPIO_FWDNLD=537 - ############################################################################### # Extension for Mifare reader enable MIFARE_READER_ENABLE=0x01 diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h index 4278d45..efb5eb2 100755 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h @@ -25,9 +25,9 @@ #define I2C_ADDRESS 0x28 #define I2C_BUS "/dev/i2c-1" #define SPI_BUS "/dev/spidev0.0" -#define PIN_INT 23 -#define PIN_ENABLE 24 -#define PIN_FWDNLD 25 +#define PIN_INT 535 // GPIO23 -> system GPIO 535 +#define PIN_ENABLE 536 // GPIO24 -> system GPIO 536 +#define PIN_FWDNLD 537 // GPIO25 -> system GPIO 537 #define EDGE_NONE 0 #define EDGE_RISING 1 #define EDGE_FALLING 2 From e4f0a7fe13561494e410cf24cde372a3d10e832f Mon Sep 17 00:00:00 2001 From: Alex Hoffmann Date: Tue, 30 Sep 2025 16:50:02 +0200 Subject: [PATCH 5/6] Cleaup --- RASPBERRY_PI_SETUP.md | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/RASPBERRY_PI_SETUP.md b/RASPBERRY_PI_SETUP.md index 2fbda6f..ef5440d 100644 --- a/RASPBERRY_PI_SETUP.md +++ b/RASPBERRY_PI_SETUP.md @@ -132,20 +132,6 @@ Use these scripts to test your setup: sudo ./pn7160_hardware_test.sh ``` -## Testing - -### 1. Basic Functionality Test -```bash -# Run NFC demo in polling mode -nfcDemoApp poll -``` - -### 2. Debug Mode -```bash -# Run with debug logging -NXPLOG_EXTNS_LOGLEVEL=0x03 NXPLOG_NCIHAL_LOGLEVEL=0x03 NXPLOG_TML_LOGLEVEL=0x03 nfcDemoApp poll -``` - ## Troubleshooting ### Common Issues From 2bff3cb638abe089616f4838d5b5dcec89b7d17d Mon Sep 17 00:00:00 2001 From: Alex Hoffmann Date: Tue, 30 Sep 2025 22:26:14 +0200 Subject: [PATCH 6/6] Removed duplicated files --- .../halimpl/tml/NfccAltTransport.cc | 465 ------------------ .../halimpl/tml/NfccAltTransport.h | 127 ----- 2 files changed, 592 deletions(-) delete mode 100644 src/nfcandroid_nfc_hidlimpl/halimpl/tml/NfccAltTransport.cc delete mode 100755 src/nfcandroid_nfc_hidlimpl/halimpl/tml/NfccAltTransport.h diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/NfccAltTransport.cc b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/NfccAltTransport.cc deleted file mode 100644 index a1d6745..0000000 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/NfccAltTransport.cc +++ /dev/null @@ -1,465 +0,0 @@ -/****************************************************************************** - * Copyright 2021 NXP - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#include -#include -#ifdef ANDROID -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "phNxpNciHal_utils.h" -#include "phNxpConfig.h" - -#define CRC_LEN 2 -#define NORMAL_MODE_HEADER_LEN 3 -#define FW_DNLD_HEADER_LEN 2 -#define FW_DNLD_LEN_OFFSET 1 -#define NORMAL_MODE_LEN_OFFSET 2 -#define FRAGMENTSIZE_MAX PHNFC_I2C_FRAGMENT_SIZE -extern phTmlNfc_i2cfragmentation_t fragmentation_enabled; -extern phTmlNfc_Context_t* gpphTmlNfc_Context; - -NfccAltTransport::NfccAltTransport() { - iEnableFd = 0; - iInterruptFd = 0; -} - -/******************************************************************************* -** -** Function Flushdata -** -** Description Reads payload of FW rsp from NFCC device into given buffer -** -** Parameters pDevHandle - valid device handle -** pBuffer - buffer for read data -** numRead - number of bytes read by calling function -** -** Returns always returns -1 -** -*******************************************************************************/ -int NfccAltTransport::Flushdata(void* pDevHandle, uint8_t* pBuffer, - int numRead) { - int retRead = 0; - uint16_t totalBtyesToRead = - pBuffer[FW_DNLD_LEN_OFFSET] + FW_DNLD_HEADER_LEN + CRC_LEN; - /* we shall read totalBtyesToRead-1 as one byte is already read by calling - * function*/ - retRead = read((intptr_t)pDevHandle, pBuffer + numRead, totalBtyesToRead - 1); - if (retRead > 0) { - numRead += retRead; - phNxpNciHal_print_packet("RECV", pBuffer, numRead); - } else if (retRead == 0) { - NXPLOG_TML_E("%s _i2c_read() [pyld] EOF", __func__); - } else { - if (bFwDnldFlag == false) { - NXPLOG_TML_D("%s _i2c_read() [hdr] received", __func__); - phNxpNciHal_print_packet("RECV", pBuffer - numRead, - NORMAL_MODE_HEADER_LEN); - } - NXPLOG_TML_E("%s _i2c_read() [pyld] errno : %x", __func__, errno); - } - SemPost(); - return -1; -} - -/******************************************************************************* -** -** Function Reset -** -** Description Reset NFCC device, using VEN pin -** -** Parameters pDevHandle - valid device handle -** eType - reset level -** -** Returns 0 - reset operation success -** -1 - reset operation failure -** -*******************************************************************************/ -int NfccAltTransport::NfccReset(void* pDevHandle, NfccResetType eType) { - int ret = -1; - NXPLOG_TML_D("%s, VEN eType %ld", __func__, eType); - - if (NULL == pDevHandle) { - return -1; - } - switch (eType) { - case MODE_POWER_OFF: - gpio_set_fwdl(0); - gpio_set_ven(0); - break; - case MODE_POWER_ON: - gpio_set_fwdl(0); - gpio_set_ven(1); - break; - case MODE_FW_DWNLD_WITH_VEN: - gpio_set_fwdl(1); - gpio_set_ven(0); - gpio_set_ven(1); - break; - case MODE_FW_DWND_HIGH: - gpio_set_fwdl(1); - break; - case MODE_POWER_RESET: - gpio_set_ven(0); - gpio_set_ven(1); - break; - case MODE_FW_GPIO_LOW: - gpio_set_fwdl(0); - break; - default: - NXPLOG_TML_E("%s, VEN eType %ld", __func__, eType); - return -1; - } - if ((eType != MODE_FW_DWNLD_WITH_VEN) && (eType != MODE_FW_DWND_HIGH)) { - EnableFwDnldMode(false); - } - if ((eType == MODE_FW_DWNLD_WITH_VEN) || (eType == MODE_FW_DWND_HIGH)) { - EnableFwDnldMode(true); - } - - return ret; -} - -/******************************************************************************* -** -** Function GetNfcState -** -** Description Get NFC state -** -** Parameters pDevHandle - valid device handle -** Returns 0 - unknown -** 1 - FW DWL -** 2 - NCI -** -*******************************************************************************/ -int NfccAltTransport::GetNfcState(void* pDevHandle) { - int ret = NFC_STATE_UNKNOWN; - NXPLOG_TML_D("%s ", __func__); - if (NULL == pDevHandle) { - return ret; - } - ret = ioctl((intptr_t)pDevHandle, NFC_GET_NFC_STATE); - NXPLOG_TML_D("%s :nfc state = %d", __func__, ret); - return ret; -} -/******************************************************************************* -** -** Function EnableFwDnldMode -** -** Description updates the state to Download mode -** -** Parameters True/False -** -** Returns None -*******************************************************************************/ -void NfccAltTransport::EnableFwDnldMode(bool mode) { bFwDnldFlag = mode; } - -/******************************************************************************* -** -** Function IsFwDnldModeEnabled -** -** Description Returns the current mode -** -** Parameters none -** -** Returns Current mode download/NCI -*******************************************************************************/ -bool_t NfccAltTransport::IsFwDnldModeEnabled(void) { return bFwDnldFlag; } - -/******************************************************************************* -** -** Function SemPost -** -** Description sem_post 2c_read / write -** -** Parameters none -** -** Returns none -*******************************************************************************/ -void NfccAltTransport::SemPost() { - int sem_val = 0; - sem_getvalue(&mTxRxSemaphore, &sem_val); - if (sem_val == 0) { - sem_post(&mTxRxSemaphore); - } -} - -/******************************************************************************* -** -** Function SemTimedWait -** -** Description Timed sem_wait for avoiding i2c_read & write overlap -** -** Parameters none -** -** Returns Sem_wait return status -*******************************************************************************/ -int NfccAltTransport::SemTimedWait() { - NFCSTATUS status = NFCSTATUS_FAILED; - long sem_timedout = 500 * 1000 * 1000; - int s = 0; - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += 0; - ts.tv_nsec += sem_timedout; - while ((s = sem_timedwait(&mTxRxSemaphore, &ts)) == -1 && errno == EINTR) { - continue; /* Restart if interrupted by handler */ - } - if (s != -1) { - status = NFCSTATUS_SUCCESS; - } else if (errno == ETIMEDOUT && s == -1) { - NXPLOG_TML_E("%s :timed out errno = 0x%x", __func__, errno); - } - return status; -} - -/******************************************************************************* -** -** Function GetIrqState -** -** Description Get state of IRQ GPIO -** -** Parameters pDevHandle - valid device handle -** -** Returns The state of IRQ line i.e. +ve if read is pending else Zer0. -** In the case of IOCTL error, it returns -ve value. -** -*******************************************************************************/ -int NfccAltTransport::GetIrqState(void* pDevHandle) { - int ret = -1; - - NXPLOG_TML_D("%s Enter", __func__); - int len; - char buf[2]; - - if (iInterruptFd <= 0) { - NXPLOG_TML_E("Error with interrupt-detect pin (%d)", iInterruptFd); - return (-1); - } - - // Seek to the start of the file - lseek(iInterruptFd, SEEK_SET, 0); - - // Read the field_detect line - len = read(iInterruptFd, buf, 2); - - if (len != 2) { - NXPLOG_TML_E("Error with interrupt-detect pin (%s)", strerror(errno)); - return (0); - } - - NXPLOG_TML_D("%s exit: state = %d", __func__, (buf[0] != '0')); - return (buf[0] != '0'); -} - -int NfccAltTransport::verifyPin(int pin, int isoutput, int edge) { - char buf[40]; - // Check if gpio pin has already been created - int hasGpio = 0; - NXPLOG_TML_D("%s Enter", __func__); - sprintf(buf, "/sys/class/gpio/gpio%d", pin); - NXPLOG_TML_D("Pin %s\n", buf); - int fd = open(buf, O_RDONLY); - if (fd <= 0) { - // Pin not exported yet - NXPLOG_TML_D("Create pin %s\n", buf); - if ((fd = open("/sys/class/gpio/export", O_WRONLY)) > 0) { - sprintf(buf, "%d", pin); - if (write(fd, buf, strlen(buf)) == strlen(buf)) { - hasGpio = 1; - usleep(100 * 1000); - } - } else { - NXPLOG_TML_E("open failed for /sys/class/gpio/export\n"); - return -1; - } - } else { - NXPLOG_TML_E("System already has pin %s\n", buf); - hasGpio = 1; - } - close(fd); - - if (hasGpio) { - // Make sure it is an output - sprintf(buf, "/sys/class/gpio/gpio%d/direction", pin); - NXPLOG_TML_D("Direction %s\n", buf); - fd = open(buf, O_WRONLY); - if (fd <= 0) { - NXPLOG_TML_E("Could not open direction port '%s' (%s)", buf, - strerror(errno)); - return -1; - } else { - if (isoutput) { - if (write(fd, "out", 3) == 3) { - NXPLOG_TML_D("Pin %d now an output\n", pin); - } - close(fd); - - // Open pin and make sure it is off - sprintf(buf, "/sys/class/gpio/gpio%d/value", pin); - fd = open(buf, O_RDWR); - if (fd <= 0) { - } - close(fd); - - // Open pin and make sure it is off - sprintf(buf, "/sys/class/gpio/gpio%d/value", pin); - fd = open(buf, O_RDWR); - if (fd <= 0) { - NXPLOG_TML_E("Could not open value port '%s' (%s)", buf, - strerror(errno)); - return -1; - } else { - if (write(fd, "0", 1) == 1) { - NXPLOG_TML_D("Pin %d now off\n", pin); - } - return (fd); // Success - } - } else { - if (write(fd, "in", 2) == 2) { - NXPLOG_TML_D("Pin %d now an input\n", pin); - } - close(fd); - - if (edge != EDGE_NONE) { - // Open pin edge control - sprintf(buf, "/sys/class/gpio/gpio%d/edge", pin); - NXPLOG_TML_D("Edge %s\n", buf); - fd = open(buf, O_RDWR); - if (fd <= 0) { - NXPLOG_TML_E("Could not open edge port '%s' (%s)", buf, - strerror(errno)); - return -1; - } else { - char* edge_str = "none"; - switch (edge) { - case EDGE_RISING: - edge_str = "rising"; - break; - case EDGE_FALLING: - edge_str = "falling"; - break; - case EDGE_BOTH: - edge_str = "both"; - break; - } - int l = strlen(edge_str); - NXPLOG_TML_D("Edge-string %s - %d\n", edge_str, l); - if (write(fd, edge_str, l) == l) { - NXPLOG_TML_D("Pin %d trigger on %s\n", pin, edge_str); - } - close(fd); - } - } - - // Open pin - sprintf(buf, "/sys/class/gpio/gpio%d/value", pin); - NXPLOG_TML_D("Value %s\n", buf); - fd = open(buf, O_RDONLY); - if (fd <= 0) { - NXPLOG_TML_E("Could not open value port '%s' (%s)", buf, - strerror(errno)); - return -1; - } else { - return (fd); // Success - } - } - } - } - return (0); -} -void NfccAltTransport::gpio_set_ven(int value) { - if (iEnableFd > 0) { - if (value == 0) { - write(iEnableFd, "0", 1); - } else { - write(iEnableFd, "1", 1); - } - usleep(10 * 1000); - } -} - -void NfccAltTransport::gpio_set_fwdl(int value) { - if (iFwDnldFd > 0) { - if (value == 0) { - write(iFwDnldFd, "0", 1); - } else { - write(iFwDnldFd, "1", 1); - } - usleep(10 * 1000); - } -} - -void NfccAltTransport::wait4interrupt(void) { - /* Open STREAMS device. */ - struct pollfd fds[1]; - fds[0].fd = iInterruptFd; - fds[0].events = POLLPRI; - int timeout_msecs = -1; // 100000; - int ret; - // usleep(500000); - while (!GetIrqState(NULL)) { - // Wait for an edge on the GPIO pin to get woken up - ret = poll(fds, 1, timeout_msecs); - if (ret != 1) { - NXPLOG_TML_D("wait4interrupt() %d - %s, ", ret, strerror(errno)); - } - } -} - -/***************************************************************************** - ** - ** Function ConfigurePin - ** - ** Description Configure Pins such as IRQ, VEN, Firmware Download - ** - ** Parameters none - ** - ** Returns NFCSTATUS_SUCCESS - on Success/ -1 on Failure - ****************************************************************************/ -int NfccAltTransport::ConfigurePin() -{ - unsigned long pinInt = PIN_INT; // Default fallback values - unsigned long pinEnable = PIN_ENABLE; - unsigned long pinFwdnld = PIN_FWDNLD; - - // Try to read GPIO pins from config file - GetNxpNumValue("NXP_GPIO_INT", &pinInt, sizeof(pinInt)); - GetNxpNumValue("NXP_GPIO_ENABLE", &pinEnable, sizeof(pinEnable)); - GetNxpNumValue("NXP_GPIO_FWDNLD", &pinFwdnld, sizeof(pinFwdnld)); - - NXPLOG_TML_D("Using GPIO pins from config: INT=%lu, ENABLE=%lu, FWDNLD=%lu", - pinInt, pinEnable, pinFwdnld); - - // Assign IO pins - iInterruptFd = verifyPin(pinInt, 0, EDGE_RISING); - if (iInterruptFd < 0) return (NFCSTATUS_INVALID_DEVICE); - iEnableFd = verifyPin(pinEnable, 1, EDGE_NONE); - if (iEnableFd < 0) return (NFCSTATUS_INVALID_DEVICE); - iFwDnldFd = verifyPin(pinFwdnld, 1, EDGE_NONE); - if (iFwDnldFd < 0) return (NFCSTATUS_INVALID_DEVICE); - return NFCSTATUS_SUCCESS; -} diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/NfccAltTransport.h b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/NfccAltTransport.h deleted file mode 100755 index 54e397f..0000000 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/NfccAltTransport.h +++ /dev/null @@ -1,127 +0,0 @@ -/****************************************************************************** - * - * Copyright 2021 NXP - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#pragma once -#include -#include -#include -#include - -#define I2C_ADDRESS 0x28 -#define I2C_BUS "/dev/i2c-1" -#define SPI_BUS "/dev/spidev0.0" -// Default GPIO pin values (system GPIO numbers for Raspberry Pi CM4) -// These are fallback values - actual pins are read from libnfc-nxp.conf -#define PIN_INT 535 // GPIO23 -> system GPIO 535 (default) -#define PIN_ENABLE 536 // GPIO24 -> system GPIO 536 (default) -#define PIN_FWDNLD 537 // GPIO25 -> system GPIO 537 (default) -#define EDGE_NONE 0 -#define EDGE_RISING 1 -#define EDGE_FALLING 2 -#define EDGE_BOTH 3 -#define CRC_LEN 2 -#define NORMAL_MODE_HEADER_LEN 3 -#define FW_DNLD_HEADER_LEN 2 -#define FW_DNLD_LEN_OFFSET 1 -#define NORMAL_MODE_LEN_OFFSET 2 -#define FRAGMENTSIZE_MAX PHNFC_I2C_FRAGMENT_SIZE -extern phTmlNfc_i2cfragmentation_t fragmentation_enabled; - -class NfccAltTransport : public NfccTransport { - public: - NfccAltTransport(); - bool_t bFwDnldFlag = false; - sem_t mTxRxSemaphore; - int iEnableFd; - int iInterruptFd; - int iFwDnldFd; - - public: - void gpio_set_ven(int value); - void gpio_set_fwdl(int value); - int verifyPin(int pin, int isoutput, int edge); - void wait4interrupt(void); - int SemTimedWait(); - void SemPost(); - int Flushdata(void* pDevHandle, uint8_t* pBuffer, int numRead); - /***************************************************************************** - ** - ** Function Reset - ** - ** Description Reset NFCC device, using VEN pin - ** - ** Parameters pDevHandle - valid device handle - ** level - reset level - ** - ** Returns 0 - reset operation success - ** -1 - reset operation failure - ** - ****************************************************************************/ - int NfccReset(void* pDevHandle, NfccResetType eType); - - /***************************************************************************** - ** - ** Function EnableFwDnldMode - ** - ** Description updates the state to Download mode - ** - ** Parameters True/False - ** - ** Returns None - ****************************************************************************/ - void EnableFwDnldMode(bool mode); - - /***************************************************************************** - ** - ** Function IsFwDnldModeEnabled - ** - ** Description Returns the current mode - ** - ** Parameters none - ** - ** Returns Current mode download/NCI - ****************************************************************************/ - bool_t IsFwDnldModeEnabled(void); - - /******************************************************************************* - ** - ** Function GetIrqState - ** - ** Description Get state of IRQ GPIO - ** - ** Parameters pDevHandle - valid device handle - ** - ** Returns The state of IRQ line i.e. +ve if read is pending else - *Zer0. - ** In the case of IOCTL error, it returns -ve value. - ** - *******************************************************************************/ - int GetIrqState(void* pDevHandle); - int GetNfcState(void* pDevHandle); - /***************************************************************************** - ** - ** Function ConfigurePin - ** - ** Description Configure Pins such as IRQ, VEN, Firmware Download - ** - ** Parameters none - ** - ** Returns NFCSTATUS_SUCCESS - on Success/ -1 on Failure - ****************************************************************************/ - int ConfigurePin(); -};