machine.SPI.write() taking too long?

Questions and discussion about The WiPy 1.0 board and CC3200 boards.
Target audience: Users with a WiPy 1.0 or CC3200 board.
I measured how many CPU ticks does it take to write 2 bytes with machine.SPI.write() function and it is always more than 9000 CPU ticks. SPI baudrate is set to 1000000.
Is it somehow possible to accelerate SPI write command execution time?
A way to speed it up is to cache the method in a local variable, e.g.:

Code: Select all

write = spi.write
write(...)
Increasing the baudrate to 10 MHz might help as well.
Cheers,
Daniel
I did several tests and here are the results:
Cashing spi.write method speeds up sequential SPI writes by approx. 2,5%
Switching baudrate from 1MHz to 10Mhz speeds up sequential SPI writes by approx. 7%
Combined - approx. 10%
As you see, the difference in sequential execution of SPI writes is not significant.
Here are traces recorded by logic analyzer for sending of integer converted to 2-byte payload two times via cashed spi.write method. I believe that there could be some more efficient way how to do the conversion.

Code: Select all

class GalvoBoard():
	def _sendGalvoData(self, data):
	    data_bytes = data.to_bytes(2)
	    data_array = bytearray([data_bytes[1],data_bytes[0]])
	    self.spiNSS.value(0)
	    self.spiWrite(data_array)
	    self.spiNSS.value(1)       
The test sequence:

Code: Select all

    def seqTest(self):
        print("Starting sequence test")
        startTime = time.ticks_ms()
        self.galvoBoard._sendGalvoData(16962)
        self.galvoBoard._sendGalvoData(16962)        
        print("Scan test ended in %sms" % (time.ticks_ms() - startTime))       
And the traces:
Signals: CS/NSS, SCK, MOSI, MISO As you can see, time difference between those two SPI transfers is really long. Is there anything I could do to make it shorter?
It is necessary to raise CS/NSS pin of SPI slave (2-channel 12-bit DAC MCP4922) to high level after every two transffered bytes.
Daniel, I did some more experiments using following simple code in main.py:

Code: Select all

import gc
gc.disable
spi = machine.SPI(machine.SPI.MASTER, baudrate=8000000, polarity=1, phase=1, bits=16, pins=('GP14', 'GP16', 'GP15'))
spiWrite = spi.write
while True:
	spiWrite(b'\x00\x00')
I omitted switching of CS pin on purpose just to determine raw speed of SPI interface. I set the frequency to 8MHz because of limited sample rate of my logic analyzer. Interface is set to operate in 16-bit mode because this is word width my SPI slave is using.
Here are two traces from the logic analyzer - detail and sequence. As you can see, time difference between two transfers of 2-byte payload is approx. 42us, which translates to 47,6 kbytes/sec.
In this thread user Oliv suggested to activate DMA mode in WiPy's FW: http://forum.micropython.org/viewtopic. ... ency#p7709
You explained that it is not enabled because of impact to heap space. Could you please elaborate more on how significant the impact would be?
Is it possible to implement some global settings whether to use DMA for SPI at the expense of free heap size?
I'm not convinced DMA would help. It's sending the two bytes quickly: the time is taken executing the while loop. It might be instructive to look at the timing for (fragment):

Code: Select all

while True:
   spiWrite(b'\x00\x00')
   spiWrite(b'\x00\x00')
Peter Hinch
Index to my micropython libraries.
I was thinking of doing some raw test, by just toggling a GPIO pin. From tests I made with PyBoard I learned that the while loop plus function call would take about 6us per loop at 168 MHz (see https://github.com/robert-hh/SSD1963-TF ... or-PyBoard, README.md, section Remarks). Since WiPy runs at 80MHz, at least twice the time should be needed.
The underlying SPI tranfer code should be fast. Therefore data should be sent & received in as big chunks as possible.
Unfortunatelly I cannot send data in big chunks because I need to toggle CS pin in between each two bytes sent to SPI slave.
Please take a look at these test results of forum member @manitou. Not sure if he made the comparison for CC3200 platform with pure compiled C code or with MicroPython. It seems that DMA might help to speed up SPI communication.
CC3200 LAUNCHPAD @ 80MHz (SPI max clock 20mhz)
SPI clock transfer DMA (4-byte)
2MHz 1.2 mbs 1.9
4MHz 1.7 mbs 3.8
5MHz 4.8
10MHz 2.2 mbs 9.2
20MHz 2.7 mbs 17.2
https://github.com/manitou48/DUEZoo/blo ... PIperf.txt