Does multi-byte SPI transfer() work?

Discussion about Z-Uno product. Visit http://z-uno.z-wave.me for more details.
Post Reply
XboxMeister
Posts: 4
Joined: 30 Jan 2021 05:08

Does multi-byte SPI transfer() work?

Post by XboxMeister »

It could just be me but I'm struggling to get SPI.transfer(buffer,count) to work.

I have SPI working in general and can successfully execute commands on the slave device (a display). I can set the screen color to whatever I like using either SPI.transfer(byte) or SPI.transfer(word) (16 bit color values). But when I try to use the multibyte version of transfer, it gives me the wrong result (white screen instead of black).

After telling the display I am doing a write to screen memory, I am allowed to send as many 16-bit color values (one per pixel) as I want so a bulk transfer will make things much faster. But for some reason even though I initialize a buffer to all zeros (black), when I send it to the display somehow the values are 0xFFFF (white) when they started as black (0x0000).

For example, if I transfer these ways, it works:

uint8_t color = 0;
SPI.transfer(color);
SPI.transfer(color);

or

uint16_t color = 0;
SPI.transfer16(color);


BUT if I try the following I get WHITE instead of black in each pixel written.

uint8_t buffer = {0,0};

SPI.transfer(buffer,2);

I don't really understand it as the SPI header/cpp seems to suggest that the single byte and 16-bit versions of transfer just use the multi-byte version under the covers so it makes no sense to me that the multi-byte one is broken.

Any ideas? Maybe something really stupid I've missed? I've tried lots of different combinations such as this (which also WORKS):

uint8_t buffer = {0,0};
uint16_t color = (buffer[0] << 8) + (buffer[1] & 0xFF);
SPI.transfer16(color);

So it seems like buffer[] has the right contents in it but somehow using it directly isn't working with multibyte transfer(). I did see in some code online for a Zuno project that it said the multibyte transfer() had issues but no idea how old that is or if still correct (or if they are even the issues I'm having).

Any ideas would be appreciated.

XM
p0lyg0n1
Posts: 242
Joined: 04 Aug 2016 07:14

Re: Does multi-byte SPI transfer() work?

Post by p0lyg0n1 »

Hi,
Try this code:

Code: Select all

// ...
uint8_t buffer[] = {0,0}; // USE brackets [] for array to define it right way
// ...
SPI.transfer(buffer, sizeof(buffer));
This have to work. Notice that ucxx will constract the arrays inside the global area, because of small amount of stack for this architecture.
So, you can see-side effect after
SPI.transfer(buffer, sizeof(buffer));
buffer will be filled with 0xFFFF after this line because of duplex transmission of SPI. Hope you have caught the main idea.

Best regards,
Alex.
XboxMeister
Posts: 4
Joined: 30 Jan 2021 05:08

Re: Does multi-byte SPI transfer() work?

Post by XboxMeister »

Thanks for the response. I should have copied directly from my code as the array was properly defined there before. The only difference was I set an explicit boundary size for the array (16). I understand about duplex in SPI but I am not looking at the contents of the buffer after the call. I am looking at the screen which is white (0xFF for each byte in the outgoing buffer) even though I send it all 0's (black).

The first transfer statement in the below code fails by drawing white pixels on the screen instead of black. If it is commented out and the transfer16 call is used, it works as expected (black pixels). Note that even though the amount of data sent in the two different calls is different, it doesn't change the problem. The SPI device I'm writing to will accept any amount of 16 bit data values for this call.

....
uint8_t buffer[] = { 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};

for (int j = 0; j < HX8357_TFTHEIGHT; j++) {
for (int i = 0; i < HX8357_TFTWIDTH ; i++) {

// This fails and sends white pixels
SPI.transfer(buffer,sizeof(buffer));

// This draws black pixels correctly (note each pixel is 16 bits, MSB sent first)
SPI.transfer16(0);
}
}



....
p0lyg0n1
Posts: 242
Joined: 04 Aug 2016 07:14

Re: Does multi-byte SPI transfer() work?

Post by p0lyg0n1 »

Hi,
I meant this

Code: Select all

uint8_t buffer[] = { 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};

for (int j = 0; j < HX8357_TFTHEIGHT; j++) {
for (int i = 0; i < HX8357_TFTWIDTH ; i++) {
memset(buffer, 0, sizeof(buffer)); // You have to setup data before you use a buffer, because it was flooded on previous step of cycle
SPI.transfer(buffer, sizeof(buffer)); // After this you will have MISO values inside buffer, it will be FFFFF...
}
}
XboxMeister
Posts: 4
Joined: 30 Jan 2021 05:08

Re: Does multi-byte SPI transfer() work?

Post by XboxMeister »

Oh I see. That completely makes sense. I didn't think about the fact I was reusing the buffer on each pass. It probably drew the first line in black and then all others in white so it is difficult to see it was correct.

Thanks so much. I'll give it a try today but I am sure you're right. Dumb mistake!

XM
Post Reply