How to Enable JN516x SPI master mode :JN-SW-4170/4168?

Showing results for 
Search instead for 
Did you mean: 

How to Enable JN516x SPI master mode :JN-SW-4170/4168?

Contributor II

I'm using the JN5169 with the JN-SW-4170, I want to use the SPI port on the JN516x in master mode to interface to a slave device (via CS SPISEL1 : DIO0).

But my SPI read access are returning always 0xffff because the JN516x SPI master is not generating any clock on its SPI clock pin (DO0), although the SPISEL1 line (DIO0) is activating/deactivating accordingly.

I keep getting the following error:  


!!! Bus error

Unclaimed Interrupt at priority 8
u32PICMR = 0 : u32PICSR = 8008
u32PICMSR = 0 : u32IPMR = 0
u32IHPR = 8 : u32AINT = 8008 u32PINT 0
EPCR = 94685 : EEAR = 4014
Stack dump:
4007d14 : 00000003
4007d18 : 000963f8
4007d1c : 04002890
4007d20 : 00094685



Below are my SPI: init, read and write functions

#include "AppHardwareApi.h"

#include "PeripheralRegs.h"  /*Not necessary  - tried with and without*/

# define CS_DEV = 1;

#define CS_ENABLE_MASK  (1 << CS_DEV)  /*active the appropriate bit for CS line DIO0*/

#define NXP_JN516X_PERIPHERAL_CLOCK 16000000 /*That's the peripheral clock supported by the JN516x*/

#define SPI_SPEED 1000000 /*Desired SPI speed = 1MHz*/


Peripherals API enabled within my app_start.c as per below:


int spi_init(void)



      /* uint8 u8SlaveEnable
         * bool_t bLsbFirst,
         * bool_t bPolarity,
         * bool_t bPhase,
         * uint8 u8ClockDivider,
         * bool_t bInterruptEnable,
         * bool_t bAutoSlaveSelect


         vAHI_SpiSelSetLocation(E_AHI_SPISEL_1, FALSE);  /*FALSE: use DIO0 for SS_SEL1*/

         return 0;


Below are my SPI read and write

/*Sub-routine to write 1 or up to 256 8-bits words to the SPI bus*/
int nxpSpiMwordsWrite(uint8_t numbytes, uint8_t *pData)
      int i =0;

      vAHI_SpiSelect(CS_ENABLE_MASK );  /*drive the selected Chip select specified by addr LOW*/
      if (bAHI_SpiPollBusy())
            DBG_PRINT(VPROC_DBG_LVL_ERR,"SPI master is busy\n");
            return -1;
      for (i=0; i<numbytes; i++)

            vAHI_SpiStartTransfer(7, *(pData+i));  /*writing 1 byte (8-bit) at a time*/
            DBG_PRINT(VPROC_DBG_LVL_FUNC,"WR: *(pData+%d) = 0x%2x\n", i, *(pData+i));


      vAHI_SpiSelect(0 );  /* CS HIGH*/
      return 0;

/*Sub-routine to read 1 or up to 256 8-bits words from the SPI bus*/
int nxpSpiMwordsRead(uint8 numbytes, uint8_t *pData)
      uint8 i =0;

      vAHI_SpiSelect(CS_ENABLE_MASK  );  /*drive the selected Chip select specified by addr LOW*/
      if (bAHI_SpiPollBusy())
            DBG_PRINT(DBG_LVL_ERR,"SPI master is busy\n");
            return -1;
      for (i=0; i<numbytes; i++)

            *(pData+i) = u8AHI_SpiReadTransfer8();
            DBG_PRINT(DBG_LVL_FUNC,"RD: *(pData+%d) = 0x%2x\n", i, *(pData+i));

      vAHI_SpiSelect(0 );  /* CS HIGH*/
      return 0;

0 Kudos
1 Reply

Contributor II

I have found the root cause of my problem. But, it worth mentioning that the NXP JN-UG-3087 documentation needs some clarification regarding the SPI master interface API.

Here is the root cause and solution for those that may come accross the same problem.

Root cause:

The read/write function prototypes of the NXP SPI master  as documented in their API user's guide

For writing:    

void vAHI_SpiStartTransfer(uint8 u8CharLen, uint32 u32Out);

u8CharLen Value in range 0-31 indicating data length for transfer:
0 - 1-bit data
1 - 2-bit data
2 - 3-bit data
31 - 32-bit data
u32Out Data to transmit, aligned to the right
(e.g. for an 8-bit transfer, store the data in bits 0-7)

For reading:  

uint8 u8AHI_SpiReadTransfer8(void);

Notice that the read function takes no input argument,  I have found that this function must always be preceded by a write, since the u8CharLen is the argument that specifies the number of clock pulses to generate for the SPI acccess.

So in  my case, my device is such that I write a 2 bytes command in order to read as many as 256 bytes from the device.

The implementation of this SDK assumes that reads and writes will always be of the same word size.

Example for my device to read as many as 256 bytes, I only need to issue just a 2-byte command.


Basically, to read x number of bits from a slave device, you first need to issue a write with the u8CharLen input argument  = x-1 number of bits to read. For my case I have to issue a fake write just so I can read the data in my device buffer.

0 Kudos