NHS31xx SW API
NFC: Near field communication driver

Detailed Description

Near Field Communication (NFC) driver provides the API to control the functionalities handled by the NFC HW block. The NFC driver provides the following functionalities:

  1. Initializing/Deinitializing of the NFC HW block
  2. Enabling/Disabling and clearing of the Interrupts
  3. Retrieving the NFC HW block status bits
  4. Retrieving information about last RF access
NFC HW Interface:
The NFC HW block is based on a MIFARE Ultralight EV1 block which is responsible for the wireless NFC communication with an external reader. Detailed functionality of the Mifare Ultralight EV1 can be referred from the user manual.
Memory organization and access:
The IC has a shared memory region which is overlaid on the EEPROM area of the MIFARE Ultralight EV1 block. The NFC shared memory can be accessed by the ARM core over the APB bus and also by an external contact-less reader. The access by the ARM core will henceforth be referred to as "APB side access" and the access by an external reader as "RF side access". The exchange of data over the RF from an external reader and the MIFARE Ultralight EV1 block is in units of pages which is of 4 bytes in size. The memory organization of the MIFARE Ultralight EV1 block is also in the same manner. The first 4 pages is an EEPROM block and that can only be accessed from the RF side and not from the APB side. The next 128 pages is the shared memory and that can be accessed from both the RF side as well as the APB side. This shared memory space is followed by 3 special registers which are status register, incoming command register and outgoing command register. The rest of the EEPROM area follows this and is accessible from RF side. However, access to this area is not recommended.
Note
The driver does not provide functions to access the shared memory and direct access has to be used by the higher layers for this. The shared memory access can be referred from example 1 and example 2 given below.
Warning
The shared memory is writable only as 32-bit words to 32-bit aligned addresses from the APB side. Reading can be done as a byte or a 16-bit word or a 32-bit word from 32-bit aligned address space.
Incoming/Outgoing Command registers:
These are the registers NSS_NFC_T.CMDIN and NSS_NFC_T.DATAOUT listed below register structure. These registers could be used by applications to exchange custom commands between the SW running on the ARM core and an external NFC Reader. The NFC driver does not provide functions to access these registers. The NSS_NFC_T.CMDIN register is writable from the RF side and only readable from the APB side. Similarly the NSS_NFC_T.DATAOUT register is writable from the APB side and only readable from the RF side.
Interrupt Handling:
This block has multiple interrupt sources tied to the same NFC IRQ. Refer to NFC_INT_T for more details.
The interrupts can be enabled/disabled by using the Chip_NFC_Int_SetEnabledMask function. The interrupt flags can be selectively cleared using Chip_NFC_Int_ClearRawStatus function.
Status information:
The status information of the NFC HW block can be retrieved by using the Chip_NFC_GetStatus function. Refer to the enum NFC_STATUS_T for more details.
Last RF access information:
This feature provides the following information with respect to the last access made from RF side. This can be retrieved using the Chip_NFC_GetLastAccessInfo function.
  1. Start word offset in BUF for the last RF access.
  2. End word offset in BUF for the last RF access.
  3. Direction (read/write) of last RF access.
Additional Information:
NDEF:
This term stands for NFC Data exchange format and more details about this can be referred from the technical specification available on NFC Forum website.
TLV:
This term stands for "Type Length Value" and more details about this can be referred from Type 2 Tag operation technical specification which is also available on NFC Forum website.
Example 1 - Simple NDEF Message Write
The below example demonstrates how a simple NDEF message can be written to the shared memory which can then be read by an external reader. Refer to ndeft2t: NDEF Type-2 Tag Message creator/parser Module for a simplified API to handle NDEF Messages.
__attribute__((aligned (4)))
uint8_t message[24] = {0x03, /* NDEF TLV which starts the NDEF message */
0x12, /* Length of NDEF Message */
0xD1, /* Text Record Header [MB=1, ME=1, CF=0, SR=1, IL=0, TNF=1] */
0x01, /* Type length */
0x0E, /* Payload length */
0x54, /* Type "T" which stands for TEXT type message */
0x02, /* Text Record sub-Header, indicates the length of the language code. */
0x65, /* 'e' */
0x6E, /* 'n' */
0x48, /* 'H' */
0x65, /* 'e' */
0x6C, /* 'l' */
0x6C, /* 'l' */
0x6F, /* 'o' */
0x20, /* ' ' */
0x57, /* 'W' */
0x6F, /* 'o' */
0x72, /* 'r' */
0x6C, /* 'l' */
0x64, /* 'd' */
0xFE, /* Terminator TLV used to indicate the end of the NDEF Message */
0x00, /* NULL TLV for word alignment */
0x00, /* NULL TLV for word alignment */
0x00 /* NULL TLV for word alignment */
};
ASSERT(NFC_SHARED_MEM_BYTE_SIZE >= sizeof(message));
if (Chip_NFC_WordWrite(NSS_NFC, (uint32_t*)NFC_SHARED_MEM_START, (uint32_t*)message, sizeof(message) / 4)) {
/* Success. The message can now be read by a PCD (Proximity Coupled Device) like a contactless tag reader or a
* phone.
*/
}
Example 2 - Simple NDEF Message Read
The below example demonstrates how a simple NDEF message can be read from the shared memory which was previously written by an external reader. This example assumes that the message written by the external reader is of length less than 255 bytes and no additional TLVs are present before the NDEF TLV.
uint8_t messageBuffer[NFC_SHARED_MEM_BYTE_SIZE];
int msgLen;
uint8_t *pMemPtr = (uint8_t*)NSS_NFC->BUF;
pMemPtr++; /* Skip NDEF TLV byte. */
msgLen = *pMemPtr++; /* Extract the NDEF Message length */
if (Chip_NFC_ByteRead(NSS_NFC, messageBuffer, pMemPtr, msgLen)) {
/* Success. The message excluding the NDEF TLV header is available in messageBuffer and can now be further
* processed.
*/
}
Example 3 - Using NFC interrupt for external reader access detection
sNfcAccessDetected = false;
while (!sNfcAccessDetected) {
; /* wait */
}
LED_On(LED1);
while (sNfcAccessDetected) {
/* Further application logic goes here */
/* ... */
}
LED_Off(LED1);
Handle interrupt:
/* To be called under interrupt from NFC_IRQHandler */
if (status & NFC_INT_RFSELECT) {
sNfcAccessDetected = true;
}
if (status & NFC_INT_NFCOFF) {
sNfcAccessDetected = false;
}
Example 4 - Using NFC interrupt for detecting read/write to particular page offset and getting
information about last RF access.
Chip_NFC_SetTargetAddress(NSS_NFC, 0); /* 32 bit aligned offset of location to be monitored */
while (true) {
/* Further application logic goes here */
/* ... */
}
Handle interrupt:
/* To be called under interrupt from NFC_IRQHandler */
if (status & NFC_INT_TARGETREAD) {
/* Read access made to location specified in target register */
/* Further handling of the interrupt. */
/* ... */
}
if (status & NFC_INT_TARGETWRITE) {
/* Write access made to location specified in target register */
/* Further handling of the interrupt. */
/* ... */
}

Data Structures

struct  NSS_NFC_T
 

Macros

#define NFC_SHARED_MEM_BYTE_SIZE   (int)(sizeof(NSS_NFC->BUF))
 
#define NFC_SHARED_MEM_WORD_SIZE   (NFC_SHARED_MEM_BYTE_SIZE / 4)
 
#define NFC_SHARED_MEM_START   (int)(NSS_NFC->BUF)
 
#define NFC_SHARED_MEM_END   (NFC_SHARED_MEM_START + NFC_SHARED_MEM_BYTE_SIZE -1)
 

Enumerations

enum  NFC_INT_T {
  NFC_INT_RFPOWER = (1 << 0),
  NFC_INT_RFSELECT = (1 << 1),
  NFC_INT_MEMREAD = (1 << 2),
  NFC_INT_MEMWRITE = (1 << 3),
  NFC_INT_CMDWRITE = (1 << 4),
  NFC_INT_CMDREAD = (1 << 5),
  NFC_INT_TARGETWRITE = (1 << 6),
  NFC_INT_TARGETREAD = (1 << 7),
  NFC_INT_NFCOFF = (1 << 8),
  NFC_INT_NONE = 0,
  NFC_INT_ALL = 0x1FF
}
 
enum  NFC_STATUS_T {
  NFC_STATUS_POR = (1 << 0),
  NFC_STATUS_1V2 = (1 << 1),
  NFC_STATUS_1V5 = (1 << 2),
  NFC_STATUS_PLL = (1 << 3),
  NFC_STATUS_SEL = (1 << 4),
  NFC_STATUS_AUTH = (1 << 5),
  NFC_STATUS_BYPASS = (1 << 6)
}
 

Functions

void Chip_NFC_Init (NSS_NFC_T *pNFC)
 
void Chip_NFC_DeInit (NSS_NFC_T *pNFC)
 
NFC_STATUS_T Chip_NFC_GetStatus (NSS_NFC_T *pNFC)
 
void Chip_NFC_Int_SetEnabledMask (NSS_NFC_T *pNFC, NFC_INT_T mask)
 
NFC_INT_T Chip_NFC_Int_GetEnabledMask (NSS_NFC_T *pNFC)
 
NFC_INT_T Chip_NFC_Int_GetRawStatus (NSS_NFC_T *pNFC)
 
void Chip_NFC_Int_ClearRawStatus (NSS_NFC_T *pNFC, NFC_INT_T flags)
 
void Chip_NFC_SetTargetAddress (NSS_NFC_T *pNFC, uint32_t offset)
 
uint32_t Chip_NFC_GetTargetAddress (NSS_NFC_T *pNFC)
 
bool Chip_NFC_GetLastAccessInfo (NSS_NFC_T *pNFC, uint32_t *pStartOffset, uint32_t *pEndOffset)
 
bool Chip_NFC_WordWrite (NSS_NFC_T *pNFC, uint32_t *pDest, const uint32_t *pSrc, int n)
 
bool Chip_NFC_ByteRead (NSS_NFC_T *pNFC, uint8_t *pDest, const uint8_t *pSrc, int n)
 

Data Structure Documentation

◆ NSS_NFC_T

struct NSS_NFC_T

Near Field Communication (NFC) register block structure (APB side)

Data Fields
__IO uint32_t CFG

Configuration register.

__I uint32_t SR

NFC status register.

__I uint32_t CMDIN

NFC incoming command. The driver does not provide functions to access this register

__O uint32_t DATAOUT

NFC outgoing command. The driver does not provide functions to access this register

__IO uint32_t TARGET

NFC target page address register.

__I uint32_t LAST_ACCESS

NFC last accessed page register.

__IO uint32_t IMSC

Interrupt mask register.

__I uint32_t RIS

Raw Interrupt status register.

__I uint32_t MIS

Masked Interrupt status register.

__O uint32_t IC

Interrupt Clear register.

__IO uint32_t RESERVED0[54]
__IO uint32_t BUF[128]

Shared memory buffer memory space, located at offset 0x100-0x2FC (128 words of 4 bytes each).

Macro Definition Documentation

◆ NFC_SHARED_MEM_BYTE_SIZE

#define NFC_SHARED_MEM_BYTE_SIZE   (int)(sizeof(NSS_NFC->BUF))

NFC shared RAM size in bytes.

◆ NFC_SHARED_MEM_WORD_SIZE

#define NFC_SHARED_MEM_WORD_SIZE   (NFC_SHARED_MEM_BYTE_SIZE / 4)

NFC shared RAM size in 32bit words.

◆ NFC_SHARED_MEM_START

#define NFC_SHARED_MEM_START   (int)(NSS_NFC->BUF)

NFC shared RAM start address.

◆ NFC_SHARED_MEM_END

#define NFC_SHARED_MEM_END   (NFC_SHARED_MEM_START + NFC_SHARED_MEM_BYTE_SIZE -1)

NFC shared RAM end address.

Enumeration Type Documentation

◆ NFC_INT_T

enum NFC_INT_T

NFC interrupt flags provides the information as listed below. The flag can be set using Chip_NFC_Int_SetEnabledMask. The status of the interrupt can be retrieved using Chip_NFC_Int_GetRawStatus. Clearing of the flag can be done using Chip_NFC_Int_ClearRawStatus.

Enumerator
NFC_INT_RFPOWER 

RFID power is detected.

NFC_INT_RFSELECT 

Tag is selected by reader.

NFC_INT_MEMREAD 

Reader reads from shared memory.

NFC_INT_MEMWRITE 

Reader writes to shared memory.

NFC_INT_CMDWRITE 

Reader writes to NSS_NFC_T.CMDIN register.

NFC_INT_CMDREAD 

Reader reads the NSS_NFC_T.DATAOUT register.

NFC_INT_TARGETWRITE 

Reader writes to address specified in the NSS_NFC_T.TARGET register.

NFC_INT_TARGETREAD 

Reader reads from address specified in the NSS_NFC_T.TARGET register.

NFC_INT_NFCOFF 

NFC front-end is powered down by external reader.

NFC_INT_NONE 

De-selects all Interrupts

NFC_INT_ALL 

Selects all Interrupts

◆ NFC_STATUS_T

NFC HW block status flags provides information on the NFC HW block as listed below. This can be retrieved using Chip_NFC_GetStatus.

Enumerator
NFC_STATUS_POR 

Indicates that the NFC analog core has been powered ON.

NFC_STATUS_1V2 

Indicates a warning that VDD_RFID is < 1.2 V.

NFC_STATUS_1V5 

Indicates a warning that VDD_RFID is < 1.5 V.

NFC_STATUS_PLL 

Indicates that NFC PLL has been locked.

NFC_STATUS_SEL 

Indicates that the NFC block has been activated via ISO/IEC 14443 Type A commands. Or in other words the MIFARE Ultralight EV1 block has reached the ACTIVE state in it's state machine. All memory operations falling under MIFARE Ultralight EV1 command set can now be carried out over the RF.

NFC_STATUS_AUTH 

Indicates that password authentication is successful. All memory operations to password protected regions can now be carried out over the RF.

NFC_STATUS_BYPASS 

Indicates that the NFC interface is in bypass mode.

Function Documentation

◆ Chip_NFC_Init()

void Chip_NFC_Init ( NSS_NFC_T pNFC)

Initializes the NFC HW block. The function disables the NFC interrupt internally and also clears any pending interrupts. Any previously written NDEF message will be lost due to initialization of shared memory.

Parameters
pNFC: The base address of the NFC peripheral on the chip
Note
Default settings for NFC are:
  • Disabled by default
  • Status Fields : Cleared by default

◆ Chip_NFC_DeInit()

void Chip_NFC_DeInit ( NSS_NFC_T pNFC)

De-initializes NFC HW block. The function disables the NFC interrupt internally and also clears any pending interrupts. This will overwrite any NDEF message that was previously present with default values.

Parameters
pNFC: The base address of the NFC peripheral on the chip

◆ Chip_NFC_GetStatus()

NFC_STATUS_T Chip_NFC_GetStatus ( NSS_NFC_T pNFC)

Returns the status information from the NFC block

Parameters
pNFC: The base address of the NFC peripheral on the chip
Returns
Status of the NFC HW block.

◆ Chip_NFC_Int_SetEnabledMask()

void Chip_NFC_Int_SetEnabledMask ( NSS_NFC_T pNFC,
NFC_INT_T  mask 
)

Enables/Disables the NFC interrupts.

Parameters
pNFC: The base address of the NFC peripheral on the chip
mask: Interrupt enabled mask to set

◆ Chip_NFC_Int_GetEnabledMask()

NFC_INT_T Chip_NFC_Int_GetEnabledMask ( NSS_NFC_T pNFC)

Retrieves the NFC interrupt enabled mask

Parameters
pNFC: The base address of the NFC peripheral on the chip
Returns
Interrupt enabled Mask

◆ Chip_NFC_Int_GetRawStatus()

NFC_INT_T Chip_NFC_Int_GetRawStatus ( NSS_NFC_T pNFC)

Retrieves a bitVector with the RAW NFC interrupt flags

Parameters
pNFC: The base address of the NFC peripheral on the chip
Returns
BitVector with the NFC RAW interrupt flags
Note
A bit set to 1 means that the correspondent interrupt flag is set.
Warning
When Chip_NFC_ByteRead and/or Chip_NFC_WordWrite API is used, application should take care of the following constraints:
  1. Application should use Chip_NFC_Int_ClearRawStatus for clearing interrupts. Direct register access for clearing interrupt status is not allowed.
  2. NFC_INT_MEMWRITE interrupt status is not sticky. Application should use the flag in the ISR context only.

◆ Chip_NFC_Int_ClearRawStatus()

void Chip_NFC_Int_ClearRawStatus ( NSS_NFC_T pNFC,
NFC_INT_T  flags 
)

Clears the required NFC interrupt flags

Parameters
pNFC: The base address of the NFC peripheral on the chip
flags: Bitvector indicating which interrupt flags to clear

◆ Chip_NFC_SetTargetAddress()

void Chip_NFC_SetTargetAddress ( NSS_NFC_T pNFC,
uint32_t  offset 
)

Sets the target address used for interrupt generation

Parameters
pNFC: The base address of the NFC peripheral on the chip
offset: 32-bit word offset from start of BUF

◆ Chip_NFC_GetTargetAddress()

uint32_t Chip_NFC_GetTargetAddress ( NSS_NFC_T pNFC)

Returns the target address used for interrupt generation

Parameters
pNFC: The base address of the NFC peripheral on the chip
Returns
32-bit word offset from start of BUF

◆ Chip_NFC_GetLastAccessInfo()

bool Chip_NFC_GetLastAccessInfo ( NSS_NFC_T pNFC,
uint32_t *  pStartOffset,
uint32_t *  pEndOffset 
)

Returns the start and end 32-bit word offset from start of BUF and the direction of last RF access

Parameters
pNFC: The base address of the NFC peripheral on the chip
[out]pStartOffset: Start word offset for last RF access
[out]pEndOffset: Last accessed word offset for last RF access
Returns
  • true for write access.
  • false for read access.

◆ Chip_NFC_WordWrite()

bool Chip_NFC_WordWrite ( NSS_NFC_T pNFC,
uint32_t *  pDest,
const uint32_t *  pSrc,
int  n 
)

Writes a block of words to the BUF, and returns success/failure of write operation. Failure indicates corruption of written data due to RF access.

Parameters
pNFC: The base address of the NFC peripheral on the chip
pDest: Destination address in BUF
pSrc: Source buffer address (32 bit word aligned)
n: Number of words
Returns
  • true for successful write.
  • false for write failure.
Note
Write access is word based, and address should be 32-bit word aligned.
Warning
When this API is used, application should take care of the following constraints:
  1. Application should use Chip_NFC_Int_ClearRawStatus for clearing interrupts. Direct register access for clearing interrupt status is not allowed.
  2. NFC_INT_MEMWRITE interrupt status is not sticky. Application should use the flag in the ISR context only.

◆ Chip_NFC_ByteRead()

bool Chip_NFC_ByteRead ( NSS_NFC_T pNFC,
uint8_t *  pDest,
const uint8_t *  pSrc,
int  n 
)

Reads a block of bytes from the BUF, and returns success/failure of read operation. Failure indicates corruption of read data due to RF access.

Parameters
pNFC: The base address of the NFC peripheral on the chip
pDest: Destination buffer address
pSrc: Source address in BUF
n: Number of bytes
Returns
  • true for successful read.
  • false for read corruption.
Note
Read access is byte based.
Warning
When this API is used, application should take care of the following constraints:
  1. Application should use Chip_NFC_Int_ClearRawStatus for clearing interrupts. Direct register access for clearing interrupt status is not allowed.
  2. NFC_INT_MEMWRITE interrupt status is not sticky. Application should use the flag in the ISR context only.