Hi, I want to send 4 bytes of data to a chip which acts as a SPI slave. The ADC chip I am working has a sampling frequency of 128 KHz. I want to capture every read from the ADC.
I notice there are gaps in between the SCLKS. I understand Arduino sends data in chunks of 1 byte at a time, but the chip requires the whole SPI transaction to be complete before 7us. CS low to CS high. It also requires that the SCLK is triggered on a known CLK and no gaps between pulses.
See image below. I am using 3.3V compatible spi library. I am using Arduino GIGA R1 WiFi
Well I guess it is a relative term, but I wouldn't call 1.5 us huge. It's probably a typical overhead for Arduino API calls. I think if you want to reduce the overhead you would need to implement your own SPI code.
In general, specifying why you need code or hardware to meet a specific requirement tends to produce more informed answers than simply saying "I want". "I want" is quite often a symptom of an X-Y problem.
The chip requires the whole SPI transaction to be complete before 7us. CS low to CS high. So, the overhead kills a lot of time. How do I implement own SPI protocol? I have tried bit banging the pins. They run slow too.
This is my first post here and you are right I should have given more information. The chip requires the whole SPI transaction to be complete before 7us. CS low to CS high. It also requires that the SCLK is triggered on a known CLK and no gaps between pulses.
Hope this helps for a better reply
Well, your Arduino and its STM32 processor are well above my pay grade. But if it were a lowly Arduino Uno or Nano, the library would set up and enable the SPI peripheral, which runs in the background unmolested by anything else going on, including other interrupts, so it can shift out the entire byte with no delays. Upon completion, it generates an interrupt. The service routine for that interrupt would initiate transfer of the next byte simply by writing it into the SPI shift register.
If the SPI peripheral is really fancy, it will be buffered, so on completion of the current transfer, it will shift the buffered byte into the shift register immediately and automatically, and generate a "transmit buffer empty" interrupt. That permits continuous transmission, with zero delay between bytes.
I wonder if the STM32 SPI library is inserting the delay deliberately for some reason. I think it's unlikely that the SPI peripheral actually needs it, but as I say, I'm not knowledgeable about your chip.
It might be productive to look through the library's source code to see how its transfer() function operates, and what any related ISRs do.
Straying seriously into the "I've no idea what I'm talking about" territory here AND that I don't own a Giga of any type of have any knowledge of one, have a look here as it may give you some ideas:
I would probably first start off trying some simple possible solutions.
Two parts:
SPI.transfer(buffer, count) - you are already doing. I really wish Arduino would adopt the other form of spi.transfer that other
boards, like esp32, teensy, ... support: transfer(tx_buffer, tx_count, rx_buffer, rx_count)... But...
If the above is not fast enough, for my ILI9341 for the GIGA library ( KurtE/ILI9341_GIGA_n: Converted from ILI9341_t3n for the Arduino GIGA) I do some more heavy hacking, where I end up unrolling my digitalWriteFast down to simply setting a register. And I grab hold of a pointer to the hardware SPI object and do some direct writing to the SPI registers...
I have seen similar gaps due to the SPI transaction calls when using HW SPI. When writing bit banging SW SPI it depends on the platform if it is slower.
On AVR (UNO, MEGA) it certainly was.
On ESP32 I recall that bit banging was slightly slower per bit but on par per byte with the HW SPI. This interesting conclusion is then that as the SW SPI pulses were slightly longer, the quality of the communication (squareness of pulses) is actually better.
Don't have a GIGA to test, but agree with bobscousins that bit banging is worth a try.