8-bit/16-bit writes to SPI PUSHR not working as expected

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

8-bit/16-bit writes to SPI PUSHR not working as expected

3,067 Views
timpambor
Contributor I

Hi all,

I tried to write byte data via an 8-bit write to SPI PUSHR register but the result have not been as I expected it.

I configured the SPI as following:

SPI2_MCR = SPI_MCR_CLR_RXF_MASK | SPI_MCR_CLR_TXF_MASK | SPI_MCR_MSTR_MASK | SPI_MCR_PCSIS(1);

SPI2_CTAR0 = SPI_CTAR_DBR_MASK | SPI_CTAR_FMSZ(7);

SPI2_RSER = SPI_RSER_EOQF_RE_MASK;

Before my writes I read SPI2_TXFR0, SPI2_TXFR1, SPI2_TXFR2, SPI2_TXFR3 all as zero.

Then I write one byte via an 8-bit write and the same byte via a 16-bit and a 32-bit write.

*((uint8_t *)(&SPI2_PUSHR)) = 0x7f;

*((uint16_t *)(&SPI2_PUSHR)) = 0x7f;

*((uint32_t *)(&SPI2_PUSHR)) = 0x7f;

What I was expecting to read back from SPI2_TXFR0, SPI2_TXFR1, SPI2_TXFR2 was 0x7f but I actually got 0x7c7f7f7f, 0x7f007f, 0x7f.

For other bytes e.g. 0xff it was similar there I got 0xfcffffff, 0xff00ff, 0xff.

It looks like that if I write a byte 0xzz via an 8-bit write 0xzzzzzzzz is pushed with bits 24, 25 set to 0, via a 16-bit write 0x00zz00zz, via a 32-bit write 0x000000zz.

The reference manual states "Eight- or sixteen-bit write accesses to the PUSHR transfer all 32 register bits to the TX FIFO." which sounds to me that the other bits in PUSHR are either in their reset state or keep their previous state which should work out in my case to the same, 0.

I reproduced this behavior on a Kinetis MK20DN512VLL100 revision 2N30D and an MK60FN1M0VLQ120 revision 3N96B.

The background why I want to use 8-bit writes is that I actually want PUSHR to be written by the DMA. Extending 8-bit reads to 32-bit and writing as 32-bit isn't possible with a single DMA channel, is it?

Is this the correct and documented behavior or am I missing a point?

Regards,

Tim Pambor

Labels (1)
Tags (5)
0 Kudos
2 Replies

1,455 Views
egoodii
Senior Contributor III

You'll have to ask these guys how they 'made it work':

How to use DMA for SPI without wasting memory

If I were to try to do the DMA 'legally':


You haven't outlined what size your 8-bit-buffer can or should be, but let's just make up a number like 256 bytes.  What you CAN do is follow those 256 bytes with another three sets of 256 bytes that are 'constant' to fill out the 32-bit PUSHR contents, and set up a 'complicated' DMA operation with a minor loop that reads from a bytewide source, with address increment of 256, to a 32-bit destination that is the PUSHR.  Thus the DMA can 'accumulate' the whole write pattern, one byte each from the 256-byte blocks in order, while your 'original source' of 8-bit data can deal directly with the contiguous 256 byte block.  Then the major loop will return the count to one after the first read-of-four started, and continue thru all the bytes-to-words that way.

Now I will freely admit, this STILL has the disadvantage of 'wasting' RAM for the extra control bytes, but if you can 'break up' your data requirements in such a way this at least avoids forcing the CPU to do all the 'byte stuffing'.

On a 'much more complicated' route you MIGHT be able to get the scatter/gather DMA-chaining process to make much more complicated address sequencing to accumulate the whole 32bits, one from increasing RAM and the other three from some 'fixed address', but I'm skeptical...

0 Kudos

1,455 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Tim Pambor,

Writes to the SPIx_PUSHR register have to be 32 bits.  

PUSHR provides the means to write to the TX FIFO . Data written to this register is transferred to the TX FIFO 8- or 16-bit write accesses to the PUSHR transfer all 32 register bits to the TXFIFO. 

The reference manual with incorrect info, sorry for that.

Wish it helps.

Best regards,

Ma Hui

0 Kudos