[SOLVED] SPI C problem

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi everybody,

 

I am not sure if is it right forum for my question.

 

I am using XMEGA 128A4U MCU. I want use SPI. (with external Flash)

 

SPI initialize is ok, but when I use command spi_read_packet it is read value (wrong value) to the first cell - to the buffer_tx_servis[0]. Remain cells have value 0.

 

My original sub is here:

uint8_t readID_SPIFlash(void){

	uint8_t result = 1;
	uint8_t buffer_tx_servis[4];

	ioport_set_pin_low(SS_SPI_EEPROM);								// Select Flash
	asm("NOP");
	spi_write_single(pFlash_SPI, SPI_FLASH_READ_ID);				// Send cmd - ask for ID

	spi_read_packet(pFlash_SPI, buffer_tx_servis, 4);				// Read ID - it is 4 bytes

	ioport_set_pin_high(SS_SPI_EEPROM);								// SS to high
	asm("NOP");

	result = (buffer_tx_servis[0] == 0x1f) ? result * 1 :  0;
	result = (buffer_tx_servis[1] == 0x47) ?  result * 1 : 0;
	result = (buffer_tx_servis[2] == 0x01) ?  result * 1 : 0;
	asm("NOP");	asm("NOP");	asm("NOP");

	return result;
	}

 

When I try rewrite my sub and replace spi_read_packet by 4 x spi_read_single, SW read all values and ID is OK

 

(new SUB)

uint8_t readID_SPIFlash(void){

	uint8_t result = 1;
	uint8_t buffer_tx_servis[4];

	ioport_set_pin_low(SS_SPI_EEPROM);								// Select Flash
	asm("NOP");
	spi_write_single(pFlash_SPI, SPI_FLASH_READ_ID);				// Send cmd - ask for ID

	spi_read_single(pFlash_SPI, &buffer_tx_servis[0]);  				// Read ID - it is 4 bytes
	spi_read_single(pFlash_SPI, &buffer_tx_servis[1]);
	spi_read_single(pFlash_SPI, &buffer_tx_servis[2]);
	spi_read_single(pFlash_SPI, &buffer_tx_servis[3]);

	ioport_set_pin_high(SS_SPI_EEPROM);								// SS to high
	asm("NOP");

	result = (buffer_tx_servis[0] == 0x1f) ? result * 1 :  0;
	result = (buffer_tx_servis[1] == 0x47) ?  result * 1 : 0;
	result = (buffer_tx_servis[2] == 0x01) ?  result * 1 : 0;
	asm("NOP");	asm("NOP");	asm("NOP");

	return result;
	}

 

I think there is bug in my C code, but I can not find it.

 

Any advice ?

 

Thanks

Last Edited: Wed. Oct 26, 2016 - 05:39 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Solved I think:

 

When I use spi_master_packet - it use function from ASF file spi_master.c

 

there is:

 

status_code_t spi_read_packet(SPI_t *spi, uint8_t *data, size_t len)
{
    while (len--) {
        spi_write_single(spi,0); //Dummy write

        while (!spi_is_rx_full(spi)){
        }
        
        spi_read_single(spi, data);
        data++;
    }
    
    return STATUS_OK;
}

This function send dummy byte to SPI and read received byte.

 

 

But this sub call spi_read_single: it use:

 

inline static void spi_read_single(SPI_t *spi, uint8_t *data)
{
    spi_put(spi,0);
    while(!((*spi).STATUS & SPI_IF_bm));
    *data=spi_get(spi);
}


It is mean this sub send the next value to SPI. And it is my problem.

 

When I comment the first sending in spi_master.c. My SW working OK

 

status_code_t spi_read_packet(SPI_t *spi, uint8_t *data, size_t len)
{
    while (len--) {
        //spi_write_single(spi,0); //Dummy write

        //while (!spi_is_rx_full(spi)){
        //}
        
        spi_read_single(spi, data);
        data++;
    }
    
    return STATUS_OK;
}

I do not know is it ok? Had anybody the same problem ?

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That sure looks like a bug in ASF.

 

Does raise the question: "why bother with ASF for something as simple as SPI?" though.

 

I'm guessing it may not have been found previously as I doubt many other use SPI in ASF.

 

(and the very idea of spi_put() and spi_get() shows a possible lack of understanding in the person who wrote this in ASF. The fact is that SPI always is a put and a get at the same time - to try to split it just leads to confusion such as you are seeing here)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes

 

it is true.

 

I will mark this post like "SOLVED"