LPC55s16 PN5190 nfc library porting?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC55s16 PN5190 nfc library porting?

750 Views
rockynguyen92
Contributor II

Hi everyone,


I'm trying to test my LPC55s16 custom board to communicate with NFC PN5190 via NxpNfcRdLib and am stuck on Platform\DAL\src and phOsal.

Could anyone give me a clue on how to either rewrite those function using LPC55s16 or an example using half duplex SPI to talk with PN5190? That could help me a lot. Thank you all in advance.

Labels (1)
0 Kudos
7 Replies

681 Views
rockynguyen92
Contributor II

Hi all, for testing purposes, I used the LPC55s28 kit to communicate with the PNEV5190B kit via external SPI. I have succeeded in initiating the library and reading out the phhalHw_Pn5190_Instr_GetVersion. The SimplifiedApiDemo example is stuck at 
/* Activating the card with blocking activation mode */
dwStatus = phNfcLib_Activate(wTechnologyMask, &PeerInfo, NULL);

I have modified the phbalReg_Exchange function to work with lpc55s28 and the SPI_MasterTransferBlocking is the reason why the example code halt

phStatus_t phbalReg_Exchange(
                                        void * pDataParams,
                                        uint16_t wOption,
                                        uint8_t * pTxBuffer,
                                        uint16_t wTxLength,
                                        uint16_t wRxBufSize,
                                        uint8_t * pRxBuffer,
                                        uint16_t * pRxLength
                                        )
{
   phStatus_t status = PH_DRIVER_SUCCESS;
    uint8_t * pRxBuf;
    status_t dspiStatus;
    spi_transfer_t g_masterXfer;
 
    memset(&g_masterXfer, 0, sizeof(spi_transfer_t));
 
    if(pRxBuffer == NULL)
    {
        pRxBuf = g_dummyBuffer;
    }
    else
    {
        pRxBuf = pRxBuffer;
    }
 
    if(pTxBuffer == NULL)
    {
        wTxLength = wRxBufSize;
        g_dummyBuffer[0] = 0xFF;
        pTxBuffer = g_dummyBuffer;
    }
 
    /* Set up the transfer */
    g_masterXfer.txData = pTxBuffer;
    g_masterXfer.rxData = pRxBuf;
    g_masterXfer.dataSize = wTxLength;
//     g_masterXfer.configFlags = kSPI_FrameDelay;
 
    /* Start transfer */
    dspiStatus = SPI_MasterTransferBlocking(FC8_SPI_NFC_PERIPHERAL, &g_masterXfer);
 
    if (dspiStatus != kStatus_Success)
    {
        return (PH_DRIVER_FAILURE | PH_COMP_DRIVER);
    }
 
    if (pRxLength != NULL)
    {
        *pRxLength = wTxLength;
    }
 
    return status;
}

 

My example code stuck at spi exchange data functionMy example code stuck at spi exchange data function
Could anyone give me some clues to fix these problems? Thank you all in advance.

0 Kudos

665 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

Regarding your question, I suppose that you have to call the following function before you call the SPI_MasterTransferBlocking(FC8_SPI_NFC_PERIPHERAL, &g_masterXfer);

1)pin assignment

you have to configure the SPI pins in IOCON register

CLOCK_EnableClock(kCLOCK_Iocon);

const uint32_t port0_pin20_config = (


IOCON_PIO_FUNC7 |
/* Selects pull-up function */
IOCON_PIO_MODE_PULLUP |
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_SLEW_STANDARD |
/* Input function is not inverted */
IOCON_PIO_INV_DI |
/* Enables digital function */
IOCON_PIO_DIGITAL_EN |
/* Open drain is disabled */
IOCON_PIO_OPENDRAIN_DI);
/* PORT0 PIN20 (coords: 74) is configured as FC7_RXD_SDA_MOSI_DATA */
IOCON_PinMuxSet(IOCON, 0U, 20U, port0_pin20_config);

.............

The above code just give you a format, finally, it is dependent on which pin is assigned for LPC5528.

2)configure the SPI module:

#define EXAMPLE_SPI_MASTER SPI7
#define EXAMPLE_SPI_MASTER_IRQ FLEXCOMM7_IRQn
#define EXAMPLE_SPI_MASTER_CLK_SRC kCLOCK_Flexcomm7
#define EXAMPLE_SPI_MASTER_CLK_FREQ CLOCK_GetFlexCommClkFreq(7U)
#define EXAMPLE_SPI_SSEL 1
#define EXAMPLE_SPI_SPOL kSPI_SpolActiveAllLow

CLOCK_AttachClk(kFRO12M_to_FLEXCOMM7);

SPI_MasterGetDefaultConfig(&userConfig);
srcFreq = EXAMPLE_SPI_MASTER_CLK_FREQ;
userConfig.sselNum = (spi_ssel_t)EXAMPLE_SPI_SSEL;
userConfig.sselPol = (spi_spol_t)EXAMPLE_SPI_SPOL;
SPI_MasterInit(EXAMPLE_SPI_MASTER, &userConfig, srcFreq);

/* Init Buffer */
for (i = 0; i < BUFFER_SIZE; i++)
{
srcBuff[i] = i;
}

/* Send to slave */
xfer.txData = srcBuff;
xfer.rxData = destBuff;
xfer.dataSize = sizeof(destBuff);
xfer.configFlags = kSPI_FrameAssert;

then call the function:

dspiStatus = SPI_MasterTransferBlocking(FC8_SPI_NFC_PERIPHERAL, &g_masterXfer);

pls check the data width for each spi transfer

Pls try the above procedure.

If you still have issue, pls check where the code hangs on so that we can have a check.

BR

XiangJun Rong

 

 

 

0 Kudos

660 Views
rockynguyen92
Contributor II

Thank you for your reply, I have already initiated the spi channel:

RESET_PeripheralReset(kHSLSPI_RST_SHIFT_RSTn);

const spi_master_config_t FC8_SPI_NFC_config = {
.enableLoopback = false,
.enableMaster = true,
.polarity = kSPI_ClockPolarityActiveHigh,
.phase = kSPI_ClockPhaseFirstEdge,
.direction = kSPI_MsbFirst,
.baudRate_Bps = 1200000UL,
.dataWidth = kSPI_Data8Bits,
.sselNum = kSPI_Ssel0,
.sselPol = kSPI_SpolActiveAllLow,
.txWatermark = kSPI_TxFifo0,
.rxWatermark = kSPI_RxFifo1,
.delayConfig = {
.preDelay = 0U,
.postDelay = 0U,
.frameDelay = 0U,
.transferDelay = 0U
}
};

static void FC8_SPI_NFC_init(void) {
/* Initialization function */
SPI_MasterInit(FC8_SPI_NFC_PERIPHERAL, &FC8_SPI_NFC_config, FC8_SPI_NFC_CLOCK_SOURCE);
}

I can read out the pn5190 firmware version via spi  using the library function as below:
phhalHw_Pn5190_Version_t _pVersion;
status = phhalHw_Pn5190_Instr_GetVersion(
&gphNfcLib_Params.sHal, /**< [In] Pointer to this layer's parameter structure. */
&_pVersion /**< [InOut] structure pointer for, 4 byte Version Information read from PN5190. */
);
if(status == PH_ERR_SUCCESS)
{
PRINTF("phhalHw_Pn5190_Instr_GetVersion bHw_Version %x bROM_Version %x wFW_Version %x\n", _pVersion.bHw_Version, _pVersion.bROM_Version, _pVersion.wFW_Version);
}else
{
PRINTF("phhalHw_Pn5190_Instr_GetVersion %x\n",status);
return 1;
}
=>> GOT: phhalHw_Pn5190_Instr_GetVersion bHw_Version  52 bROM_Version 2 wFW_Version 205

I think the problem is the phbalReg_Exchange. This is the original one from the library for LCP1769:


phStatus_t phbalReg_Exchange(
void * pDataParams,
uint16_t wOption,
uint8_t * pTxBuffer,
uint16_t wTxLength,
uint16_t wRxBufSize,
uint8_t * pRxBuffer,
uint16_t * pRxLength
)
{
uint16_t xferLen;
Chip_SSP_DATA_SETUP_T xferConfig;

xferConfig.length = wTxLength;
xferConfig.rx_data = pRxBuffer;
xferConfig.tx_data = pTxBuffer;
xferConfig.rx_cnt = 0;
xferConfig.tx_cnt = 0;

/* data exchange */
if ( wRxBufSize == 0 )
{
Chip_SSP_WriteFrames_Blocking(LPC_SSP, pTxBuffer, wTxLength);
xferLen = wTxLength; /* Fake as a full duplex */
}
else
{
if ( wTxLength == 0 )
{
xferLen = Chip_SSP_ReadFrames_Blocking(LPC_SSP, pRxBuffer, wRxBufSize);
}
else
{
xferLen = Chip_SSP_RWFrames_Blocking(LPC_SSP, &xferConfig);
}
}

if ( wTxLength !=0 && wRxBufSize != 0 )
{
if (xferLen != wTxLength)
{
return (PH_DRIVER_FAILURE | PH_COMP_DRIVER);
}
}
if ( pRxLength != NULL)
*pRxLength = xferLen;

return PH_DRIVER_SUCCESS;
}
Could you check if my porting code is correct?

0 Kudos

650 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

Regarding your api function Chip_SSP_ReadFrames_Blocking(LPC_SSP, pRxBuffer, wRxBufSize); and Chip_SSP_RWFrames_Blocking(), can you tell us where you get the api function?

Do you use LPC55S16 part number?

As you know that the SSP is another independent module, which only integrates in old LPC family for example LPC43xx, if you use LPC55S16, I am sure that the LPC55S16 does not include SSP module, it only includes FlexCommx module which can be configured as spi.

Pls check yourself, anyway, pls post the above api function code to check if the peripheral is SSP or spi module.

BTW, I suggest you write a simple code for example write/read 8 bytes definitely via spi without "if"

BR

XiangJun Rong

 

 

0 Kudos

645 Views
rockynguyen92
Contributor II

Hi XiangJun,
Sorry if I got you misunderstanding.
Yes, Chip_SSP_ReadFrames_Blocking(LPC_SSP, pRxBuffer, wRxBufSize); andhip_SSP_RWFrames_Blocking() is from example code of NXP NxpNfcRdLib using LPCOpen
And yes I re-write it myself for LPC55s28, you can see code below:

phStatus_t phbalReg_Exchange(
                                        void * pDataParams,
                                        uint16_t wOption,
                                        uint8_t * pTxBuffer,
                                        uint16_t wTxLength,
                                        uint16_t wRxBufSize,
                                        uint8_t * pRxBuffer,
                                        uint16_t * pRxLength
                                        )
{
 
 
phStatus_t status = PH_DRIVER_SUCCESS;
    uint8_t * pRxBuf;
    status_t dspiStatus;
    spi_transfer_t g_masterXfer;
    uint8_t g_dummyBuffer[RX_BUFFER_SIZE_MAX];
 
    memset(&g_masterXfer, 0, sizeof(spi_transfer_t));
 
    if(pRxBuffer == NULL)
    {
        pRxBuf = g_dummyBuffer;
    }
    else
    {
        pRxBuf = pRxBuffer;
    }
 
    if(pTxBuffer == NULL)
    {
        wTxLength = wRxBufSize;
        g_dummyBuffer[0] = 0xFF;
        pTxBuffer = g_dummyBuffer;
    }
 
    /* Set up the transfer */
    g_masterXfer.txData = pTxBuffer;
    g_masterXfer.rxData = pRxBuf;
    g_masterXfer.dataSize = wTxLength;
//     g_masterXfer.configFlags = kSPI_FrameAssert;
 
    /* Start transfer */
    dspiStatus = SPI_MasterTransferBlocking(FC8_SPI_NFC_PERIPHERAL, &g_masterXfer);
 
    if (dspiStatus != kStatus_Success)
    {
        return (PH_DRIVER_FAILURE | PH_COMP_DRIVER);
    }
 
    if (pRxLength != NULL)
    {
        *pRxLength = wTxLength;
    }
 
    return status;
}




The problem is I still can read out the firmware version of PN5190 and am able to force it to run in normal boot mode via SPI, but in a deeper process like detecting card sweeper. It is stuck at SPI master transfer function.

All the mechanism was followed library example code, I am only rewriting the phbalReg_Exchange data function

Thanks.

0 Kudos

640 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

This is the api function, can you debug and check which line the core hangs on?

BR

XiangJun Rong

/*!
* brief Transfers a block of data using a polling method.
*
* param base SPI base pointer
* param xfer pointer to spi_xfer_config_t structure
* retval kStatus_Success Successfully start a transfer.
* retval kStatus_InvalidArgument Input argument is invalid.
* retval kStatus_SPI_Timeout The transfer timed out and was aborted.
*/
status_t SPI_MasterTransferBlocking(SPI_Type *base, spi_transfer_t *xfer)
{
uint32_t instance;
uint32_t tx_ctrl = 0U, last_ctrl = 0U;
uint32_t tmp32, rxRemainingBytes, txRemainingBytes, dataWidth;
uint32_t toReceiveCount = 0;
uint8_t *txData, *rxData;
uint32_t fifoDepth;
#if SPI_RETRY_TIMES
uint32_t waitTimes = SPI_RETRY_TIMES;
#endif

/* check params */
assert(!((NULL == base) || (NULL == xfer) || ((NULL == xfer->txData) && (NULL == xfer->rxData))));
if ((NULL == base) || (NULL == xfer) || ((NULL == xfer->txData) && (NULL == xfer->rxData)))
{
return kStatus_InvalidArgument;
}

fifoDepth = SPI_FIFO_DEPTH(base);
txData = xfer->txData;
rxData = xfer->rxData;
txRemainingBytes = (txData != NULL) ? xfer->dataSize : 0U;
rxRemainingBytes = (rxData != NULL) ? xfer->dataSize : 0U;

instance = SPI_GetInstance(base);
dataWidth = (uint32_t)(g_configs[instance].dataWidth);

/* dataSize (in bytes) is not aligned to 16bit (2B) transfer */
if ((dataWidth > (uint32_t)kSPI_Data8Bits) && ((xfer->dataSize & 0x1U) != 0U))
{
return kStatus_InvalidArgument;
}

/* clear tx/rx errors and empty FIFOs */
base->FIFOCFG |= SPI_FIFOCFG_EMPTYTX_MASK | SPI_FIFOCFG_EMPTYRX_MASK;
base->FIFOSTAT |= SPI_FIFOSTAT_TXERR_MASK | SPI_FIFOSTAT_RXERR_MASK;
/* select slave to talk with */
tx_ctrl |= (SPI_DEASSERT_ALL & (~SPI_DEASSERTNUM_SSEL((uint32_t)(g_configs[instance].sselNum))));
/* set width of data - range asserted at entry */
tx_ctrl |= SPI_FIFOWR_LEN(dataWidth);
/* delay for frames */
tx_ctrl |= ((xfer->configFlags & (uint32_t)kSPI_FrameDelay) != 0U) ? (uint32_t)kSPI_FrameDelay : 0U;
/* end of transfer */
last_ctrl |= ((xfer->configFlags & (uint32_t)kSPI_FrameAssert) != 0U) ? (uint32_t)kSPI_FrameAssert : 0U;
/* last index of loop */
while ((txRemainingBytes != 0U) || (rxRemainingBytes != 0U) || (toReceiveCount != 0U))
{
#if SPI_RETRY_TIMES
if (--waitTimes == 0U)
{
return kStatus_SPI_Timeout;
}
#endif
/* if rxFIFO is not empty */
if ((base->FIFOSTAT & SPI_FIFOSTAT_RXNOTEMPTY_MASK) != 0U)
{
tmp32 = base->FIFORD;
/* rxBuffer is not empty */
if (rxRemainingBytes != 0U)
{
*(rxData++) = (uint8_t)tmp32;
rxRemainingBytes--;
/* read 16 bits at once */
if (dataWidth > 8U)
{
*(rxData++) = (uint8_t)(tmp32 >> 8);
rxRemainingBytes--;
}
}
/* decrease number of data expected to receive */
toReceiveCount -= 1U;
}
/* transmit if txFIFO is not full and data to receive does not exceed FIFO depth */
if (((base->FIFOSTAT & SPI_FIFOSTAT_TXNOTFULL_MASK) != 0U) && (toReceiveCount < fifoDepth) &&
((txRemainingBytes != 0U) || (rxRemainingBytes >= SPI_COUNT_TO_BYTES(dataWidth, toReceiveCount + 1U))))
{
/* txBuffer is not empty */
if (txRemainingBytes != 0U)
{
tmp32 = *(txData++);
txRemainingBytes--;
/* write 16 bit at once */
if (dataWidth > 8U)
{
tmp32 |= ((uint32_t)(*(txData++))) << 8U;
txRemainingBytes--;
}
if (txRemainingBytes == 0U)
{
tx_ctrl |= last_ctrl;
}
}
else
{
tmp32 = (uint32_t)s_dummyData[instance];
tmp32 |= (uint32_t)s_dummyData[instance] << 8U;
/* last transfer */
if (rxRemainingBytes == SPI_COUNT_TO_BYTES(dataWidth, toReceiveCount + 1U))
{
tx_ctrl |= last_ctrl;
}
}
/* send data */
tmp32 = tx_ctrl | tmp32;
base->FIFOWR = tmp32;
toReceiveCount += 1U;
}
}
/* wait if TX FIFO of previous transfer is not empty */
#if SPI_RETRY_TIMES
waitTimes = SPI_RETRY_TIMES;
while ((0U == (base->FIFOSTAT & SPI_FIFOSTAT_TXEMPTY_MASK)) && (0U != --waitTimes))
#else
while (0U == (base->FIFOSTAT & SPI_FIFOSTAT_TXEMPTY_MASK))
#endif
{
}
#if SPI_RETRY_TIMES
if (waitTimes == 0U)
{
return kStatus_SPI_Timeout;
}
#endif
return kStatus_Success;
}

0 Kudos

743 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

I am not familiar with NFC, can you post the NxpNfcRdLib and the header file and user guide so that we can have a review?

On the LPC55S16, you have to select the SPI port, assign the SPI pins, enable the SPI gated clock, then call the spi driver which is based on Cortex-M33.

BR

XiangJun Rong

0 Kudos