Slow SPI on SAMD21

My spi bus is working at 20% efficiency.
The clock frequency is correct, 12Mhz.

This CLS function.

void ILI9488::cls(void){
  SPI.beginTransaction(SPISettings(12000000, MSBFIRST, SPI_MODE0));
  long i = 0;
  for( i = 0; i < 460800; i++){
	  *dcport |=  dcpinmask;
	  *csport &= ~cspinmask;
	  SPI.transfer(0);
	  *csport |= cspinmask;
  }
  SPI.endTransaction();
}

This SPI.transfert:

byte SPIClassSAMD::transfer(uint8_t data)
{
  return _p_sercom->transferDataSPI(data);
}

This p_sercom->transferDataSPI(data);

uint8_t SERCOM::transferDataSPI(uint8_t data)
{
  sercom->SPI.DATA.bit.DATA = data; // Writing data into Data register
  while( sercom->SPI.INTFLAG.bit.RXC == 0 )
  {
    // Waiting Complete Reception
  }
  return sercom->SPI.DATA.bit.DATA;  // Reading data
}

I cannot understand where all that time can be lost.

It appears you are setting a CS pin for every byte sent, surely you should be setting it once?

This is public ILI9488 library.
Changing is better, but only 40% of traffic.

	*dcport |=  dcpinmask;
    *csport &= ~cspinmask;
	for( i = 0; i < 460800; i++){
		SPI.transfer((char)0x00);
	}
	  *csport |= cspinmask;

Is it possible that a 48Mhz CPU is so slow?

"Slow" is a relative term. However fast the CPU, you can still push it to the limit. To get close to the limit you will need efficient code. 12Mhz is 25% of the CPU clock speed, so you can't afford much overhead.

Function call overhead can be significant, to get higher performance you need to eliminate that. Ideally you want to write to the SPI data register directly in a loop without intervening calls.

Unfortunately the SPI library does not provide a function to send a value repeatedly. You could try transfer (char *, int) to send a block of data repeatedly.

Probably I would create my own version of the SPI library.

12MHz is bit. byte is 1.2Mhz
2us ( 96 instruction ?) for 2 function call and for loop, it seems to me a very bad result, compared to an AVR cpu and the IAR compiler,

I am not good at C++
How can I write this in the library?

  sercom->SPI.DATA.bit.DATA = data; // Writing data into Data register
  while( sercom->SPI.INTFLAG.bit.RXC == 0 );

error is:

d:\Documenti\Arduino\libraries\ILI9488\ILI9488.cpp: In member function 'void ILI9488::cls()':
d:\Documenti\Arduino\libraries\ILI9488\ILI9488.cpp:495:3: error: 'sercom' was not declared in this scope
   sercom->SPI.DATA.bit.DATA = 0; // Writing data into Data register
   ^~~~~~
d:\Documenti\Arduino\libraries\ILI9488\ILI9488.cpp:495:3: note: suggested alternative: 'sercom5'
   sercom->SPI.DATA.bit.DATA = 0; // Writing data into Data register
   ^~~~~~
   sercom5
exit status 1
Compilation error: exit status 1

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.