SPI MQX receive buffer only even buffer correct mk60

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

SPI MQX receive buffer only even buffer correct mk60

1,000 Views
jparrish88
Contributor IV

The initialization of SPI is the same in bootcode and firmware:

static void init_SPI_Channel(SPI_MemMapPtr spi_ptr, uchar ucFlagMaster)

uint_32 ctar;

   ctar= 0x7E000000; //frame size 16

//CPOL= 1 //CPHA= 1

//Big Endian

   /* Disable and clear SPI */

   spi_ptr->MCR &= (~SPI_MCR_MDIS_MASK);

   spi_ptr->MCR = SPI_MCR_HALT_MASK | SPI_MCR_CLR_TXF_MASK | SPI_MCR_CLR_RXF_MASK;

   spi_ptr->CTAR[0] = ctar;

   /* Receive FIFO overflow enable */

   spi_ptr->MCR |= SPI_MCR_ROOE_MASK;

   /* Set CS0-7 inactive high */

   spi_ptr->MCR |= SPI_MCR_PCSIS(0xFF);

   /* Disable interrupts */

   spi_ptr->RSER = 0;

   /* Clear all flags */

   spi_ptr->SR = ~SPI_SR_TFFF_MASK;

   spi_ptr->RSER= SPI_RSER_RFDF_RE_MASK;

   /* Enable SPI module */

   spi_ptr->MCR &= (~SPI_MCR_HALT_MASK);

}

The ISR to receive data on SPI is the same in bootcode and firmware:

__attribute__ ((interrupt("IRQ")))void ISR_SPI_SLAVE(void)

{

       SPI_MemMapPtr spi_ptr= (SPI_MemMapPtr)RH_SPI_SLAVE_PTR;

DISABLE_INTERUPTS;

       while (spi_ptr->SR & SPI_SR_RFDF_MASK)

       {

static uchar *ucRxPtr;

uint16_t uiData      = spi_ptr->POPR;

spi_ptr->SR = SPI_SR_RFDF_MASK;

if ( g_RHspi.uiSlaveTimeout == 0 )

{

  ucRxPtr       = (uint8_t*)&(g_RHspi.buf[g_RHspi.uiBufNum].ucRx_buf[0]);

}

*ucRxPtr++= ((uiData>>8)& 0x0ff);

*ucRxPtr++= (uiData & 0x0ff);

g_RHspi.uiSlaveTimeout= 2;

g_RHspi.uiSlaveRxCnt+= 2;

       }

ENABLE_INTERUPTS;

}

The code works correctly in Boot, but once it's inside MQX it develops an issue where the data received on even buffer indexes are the correctly received values, but the odd bytes are shifted in memory by 6 index slots. So if byte 9 is incorrect, the correct byte will be at byte 15 and byte 10 is the correct byte that should have been received.

Debug has only given me: "RESERVED_X” registers are all 0xBA in firmware, where they have various values in bootcode

Labels (1)
0 Kudos
Reply
2 Replies

724 Views
soledad
NXP Employee
NXP Employee

Hello,

MQX includes a SPI driver, there are some example codes that you can use as reference.

Which MQX version are you using?

Regards

Soledad

0 Kudos
Reply

724 Views
henryle
Contributor I

This is not a solution.  I have further details on this issue, as this came from my company.  Hope someone can recognize this issue and can theorize on a possible cause.

We turn ON FIFO but not DMA.  We use the Receive FIFO Drain Interrupt to tell us when data is received in the FIFO.  We read POPR register and clear RFDF bit to retrieve each data word in the ISR.  We use a frame size of 16 bits.   So each read of POPR register will retrieve two bytes.  The received data is clocked and pushed into the RX FIFO correctly.  We can observe  this using the RXFR0,  RXFR1,  RXFR2, and RXFR3 register contents. 

The problem is that the SR register’s POPNXTPTR field (least significant nibble) always jumps from 0 to 2 (skipping 1) after reading POPR register and clearing SR register’s RFDF status bit.  In other words: POPNXTPTR would point to RXFR0.  Then jumps to pointing to
RXFR2.  Next it points to RXFR3 and then to RXFR0 again.  This skipping of RXFR1 causes problems.  Here is an illustration of the
sequence that we observe:

  1. In the beginning POPNXTPTR = 0, pointing to RXFR0
  2. We got data clocked and pushed into the FIFO, We read POPR register and clear RFDF bit.  POPNXTPTR now equals 2, pointing to
    RXFR2  (
    POPNXTPTR should equal 1)
  3. We got new data again.  We read POPR register and clear RFDF bit.  POPNXTPTR now equals 3, pointing to RXFR3 
  4. We got new data again.  We read POPR register and clear RFDF bit.  POPNXTPTR now equals 0, pointing to RXFR0
  5. The cycle repeats.

Additionally, when reading the POPR register (16 bits data), the received 16 bit word always consists of one byte (8 bits) from current FIFO
entry and another byte (8 bits) from the next FIFO entry.  For instance:

    If POPNXTPTR = 0, reading POPR would get the first 8 bits of RXFR0 and the second 8 bits of RXFR1.  – POPR
should contain all 16 bits from RXFR0

    If POPNXTPTR = 1, reading POPR would get the first 8 bits of RXFR1 and the second 8 bits of RXFR2. - POPR
should contain all 16 bits from RXFR1

    And so on . . .

In summary, the problem seem to be the SPI HW module is not updating pointers correctly internally.  It is possible that we may not have initialized it properly.  Our init routine is already posted here by jparish88. 

0 Kudos
Reply