LPC55S16: SPI RX FIFO reads only zeros

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

LPC55S16: SPI RX FIFO reads only zeros

1,276 Views
burakgorduk1
Contributor II

Hi there,

I am trying to set up SPI3 on LPC55S16-EVK board using my own initialization function. This is a really simple application with peripheral initialization functions and  MRT0 interrupt that basically handles the sending and receiving of 1 byte data. SPI is configured as loopback mode so that I can verify my driver is working.

Below is my initialization function;

void Init_SPI3(void)
{
   /* Select 12MHz FRO as Flexcomm 3 clock */
   SYSCON->FCCLKSELX[3] = SYSCON_FCCLKSEL3_SEL(2);

   /* Reset Flexcomm 3 peripheral */
   SYSCON->PRESETCTRLSET[1] = SYSCON_PRESETCTRLSET_DATA(1 << 14);
   while(!(SYSCON->PRESETCTRLX[1] & SYSCON_PRESETCTRL1_FC3_RST_MASK))
   {
      asm("nop");
   }
   SYSCON->PRESETCTRLCLR[1] = SYSCON_PRESETCTRLCLR_DATA(1 << 14);

   /* Set PIO0_2 as MISO */
   IOCON->PIO[0][2] = (IOCON_PIO_FUNC(1) | IOCON_PIO_MODE(2) |                        IOCON_PIO_DIGIMODE_MASK);
   /* Set PIO0_3 as MOSI */
   IOCON->PIO[0][3] = (IOCON_PIO_FUNC(1));
   /* Set PIO0_4 as SSEL0 */
   IOCON->PIO[0][4] = (IOCON_PIO_FUNC(8));
   /* Set PIO0_6 as SCK */
   IOCON->PIO[0][6] = (IOCON_PIO_FUNC(1));

   /* Enable clock to Flexcomm 3 module */
   SYSCON->AHBCLKCTRLX[1] |= SYSCON_AHBCLKCTRL1_FC3_MASK;

   /* Select SPI for Flexcomm 3 interface */
   FLEXCOMM3->PSELID |= FLEXCOMM_PSELID_PERSEL(2);

   /* Set baudrate using division from Flexcomm 3 clock */
   SPI3->DIV = SPI_DIV_DIVVAL(SPI3_DIVVAL);

   /* Select master mode and enable loopback operation for testing */
  SPI3->CFG = (SPI_CFG_MASTER_MASK | SPI_CFG_LOOP_MASK);

   /* Set up RX and TX FIFOs */
   SPI3->FIFOCFG |= (SPI_FIFOCFG_EMPTYRX_MASK | SPI_FIFOCFG_EMPTYTX_MASK);
   SPI3->FIFOCFG |= (SPI_FIFOCFG_ENABLERX_MASK | SPI_FIFOCFG_ENABLETX_MASK);

   /* Set 2 clocks delay for all */
   SPI3->DLY = (SPI_DLY_PRE_DELAY(2) | SPI_DLY_POST_DELAY(2) |
                SPI_DLY_FRAME_DELAY(2) | SPI_DLY_TRANSFER_DELAY(2));

   /* Enable SPI3 module */
   SPI3->CFG |= SPI_CFG_ENABLE_MASK;
}

MRT0 interrupt and RX TX handler functions are below;

void MRT0_IRQHandler(void)
{
   /* Clear interrupt flag */
   MRT0->CHANNEL[0].STAT |= MRT_CHANNEL_STAT_INTFLAG_MASK;
   /* Call RX Handler */
   SPI3_RxHandler();
   /* Call TX Handler */
   SPI3_TxHandler();
}

void SPI3_RxHandler(void)
{
   while((SPI3->FIFOSTAT & SPI_FIFOSTAT_RXNOTEMPTY_MASK))
   {
      readData = (SPI3->FIFORD);
   }
}

void SPI3_TxHandler(void)
{
   SPI3->FIFOWR = (SPI_FIFOWR_TXDATA(0xAA) | SPI3_FIFO_CFG0_EOT);
}

with the SPI3_FIFO_CFG0_EOT symbol defined as;

/* Assert SSEL0, de-assert SSEL0 after transfer, 8 bit data length */
#define SPI3_FIFO_CFG0_EOT (SPI_FIFOWR_TXSSEL1_N_MASK | \
                            SPI_FIFOWR_TXSSEL2_N_MASK | \
                            SPI_FIFOWR_TXSSEL3_N_MASK | \
                            SPI_FIFOWR_EOT_MASK | \
                            SPI_FIFOWR_LEN(7))

I can verify that the MOSI output is working perfectly using a logic analyzer. But FIFORD always returns RXDATA as shown below;

pastedImage_3.png

SOT flag is also working normally when I try sending and receiving of multiple bytes at a time. But RXSSELX_N flags and RXDATA is always showing the same values.

I tried disabling loopback mode and tied MISO and MOSI externally, the result was still same. Clearly I am missing something here but I cannot see what.

I would appreciate if anyone would suggest anything.

Thanks.

Burak

Labels (2)
0 Kudos
4 Replies

1,199 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello Burak Gördük,

I recommend you first test the SPI demo under SDK, it  also use SPI3 .

MCUXpresso SDK | Software Development for Kinetis, LPC, and i.MX MCUs | NXP     

Then compare the SPI configuration with your code.

BR

Alice

0 Kudos

1,199 Views
burakgorduk1
Contributor II

Hi again. 

This turned out to be a really interesting thing. Well, I left SPI aside for a while and started setting up the I2C. To my surprise I had also problems with that.

Basically when I start a transfer using MSTSTART bit, MSTPENDING flag is cleared but then nothing happened. Transfer didn't start and the MSTPENDING flag is stayed 0 forever.

Then I compared my code with the example and realized that for the SCL and SDA pins DIGIMODE was enabled on the example project. When I enabled DIGIMODE I2C starting working normally! Description for this mode says that it is for enabling the digital input. 

pastedImage_3.png

Since I was using I2C on master mode, I thought then I could disable it on my SCL pin since it is an output for this scheme. But again I2C gets stuck if I disable DIGIMODE.

Then I went on and enabled digital mode on all of my SPI pins (Previously it was only enabled on MISO). And what you expect: It is working perfectly fine!

To be fare, Table 637 on the UM suggests that digital mode is generally set to 1 for SPI operation. And table 343 suggests enabling digital mode for I2C operation.

pastedImage_5.png

But In my case this is not optional. I had to enable digital mode otherwise SPI module could output the data but read zeros only. And for the I2C, as I explained, the module stopped working completely.

I am not sure if this is a feature or design flaw. I would expect the UM to put more emphasis on the importance of DIGIMODE if this is a feature. Because from the description you would think that this is only for the digital inputs. But for both the I2C and SPI to work correctly, it was required even for the outputs.

493 Views
craigmcqueenir
Contributor IV

I have been scratching my head about this exact same thing, but for a slightly different processor — for SPI3 on LPC55S26.

I have used two other FlexComms on the processor for their USART function, and did not encounter this issue with USART.

This is a "gotcha" that took a few hours of my time, and fortunately I eventually found this forum post. I reckon it should be made clearer in the user manual for these processors.

0 Kudos

1,199 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello Burak,

The DIGIMODE need set to 1 to enable digital mode as long as the pin used as digital signal.

BR

Alice

0 Kudos