I have small question about how bytes move around during SPI reading. I have a flash memory chip and microcontroller. Suppose I want to know jedec data from the chip(although it can be any data, this is just example), I found how to do it and it works fine, but I don't get the part when we assign jedec parameters to variables.

From the C code below I can see the possible logic like this:
we send "retrieve jedec" command to chip, then for some reason we start to send zeros to assign values to variables, probably it reads the value by sending dummy-bytes. Question is - isn't it supposed to overwrite bytes we are reading?
I mean - you shift something to the register you want to read therefore you get the value back by replacing it with what you have sent.

Maybe I express my question blurry, ask more info if you are confused, but to sum up everything I have two questions:
1. Why we are sending zeros during value assignments like *b1 = SPI_MasterTransmit(0);
2. If we do it to shift the value from slave device to master - why don't we erase the value from the slave by doing this?

enter image description here

void get_jedec_id(uint8_t *b1, uint8_t *b2, uint8_t *b3) {  
    PORTB |= 1<<PINB2; // turn high ss pin(/cs)
    PORTB &= ~1<<PINB2; // turn low ss pin(/cs)
    SPI_MasterTransmit(0x9F); // transmit get_jedec command of this chip
    *b1 = SPI_MasterTransmit(0); // manufacturer id
    *b2 = SPI_MasterTransmit(0); // memory type
    *b3 = SPI_MasterTransmit(0); // capacity
    PORTB |= 1<<PINB2;

SPI_MasterTransmit code:

unsigned char SPI_MasterTransmit(uint8_t outData)
// Transmission start
SPDR = outData;
// Waiting for transmission to end
while(!(SPSR & (1<<SPIF))) ;
return SPDR; // return received byte

1 Answer 1


SPI is a full-duplex protocol. In order to receive data, you have to send data at the same time, even though the Flash chip might do nothing with the data that you send.

So, for example, you want to read the JEDEC ID. You lower the /CS signal and send the "read JEDEC ID" command. That command instructs the Flash chip to "send your JEDEC ID and do nothing with any other data that you receive". You keep sending data (which is all zeroes and will be ignored anyway), and as you do so it sends you back its JEDEC ID - you get back one byte of JEDEC ID for each zero byte that you send. When you raise /CS at the end of the transaction, that resets the Flash chip's controller.

  • \$\begingroup\$ But what do I receive in response to "read JADEC ID" command? My master has to receive something, what is it and why it is not jadec information? Do I understand correctly that after I send command for reading jadec ID next data in register will be b1, then b2(after clock) and b3? \$\endgroup\$ Oct 10, 2014 at 9:31
  • \$\begingroup\$ Your master is (or should be, if everything is working) receiving JEDEC info. Look at the comments in the code: they tell you what info will be in which location - *b1, *b2, *b3. The master sends 0x9f (the command) and receives (and ignores) 0xx. Then it sends 0x00 and receives the JEDEC manufacturer ID, which it stores in b1. And so on. \$\endgroup\$
    – markt
    Oct 10, 2014 at 9:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.