How to generate nano second software-delay for STM32 M4 at 40 to 80MHz MCU clock - Page 1
Forum section: electronics / projects

author: Wilson__
author_rank: Frequent Contributor
timestamp: June 20, 2024, 07:29:22 pm
content: For software bit-banging SPI driver,how to generate nano second delay, so that after a hardware pin is set high/low, the MCU willwait tens of ns, to allow signal to meetSETUP timefor the receiving chip, before MCU make next change of pin(s) level.Same for meeting HOLD time, after a pin is set by MCU, it wait tens of ns before changing pin(s).OLD MCU run on fixed clock and each assembly (machine) code has a fixed number of execution cycle.ARM chip seem hassepeate OP code and Data cache?? Seem has predictive branching (to be optimized by compiler??)?? May not be too 'advanced' for M4 ARM??These seem make execution time un-predictable?? Good news is SETUP and HOLD are only need to be minimum number of ns. It is ok if wait is longer (but not shorter).Will inserting inline assembly language NOP (no operation) works to generate fixed delay?Many thanks

author: ataradov
author_rank: Super Contributor
timestamp: June 20, 2024, 08:25:18 pm
content: Nops would work. Calculate the number of nops for the minimum necessary delay (1 clock cycle per nop). In practice it will be slower, especially if you are running from the flash, but it will not be shorter.And consider moving your bit-banged SPI routine into SRAM or TCM, you will get much more predictable timings.

author: Benta
author_rank: Super Contributor
timestamp: June 20, 2024, 09:27:42 pm
content: Sounds more like you have problems with clock phase and polarity in your implementation.SPI is very simple, but has four configuration possibilities.I think you've chosen the wrong one.

author: dietert1
author_rank: Super Contributor
timestamp: June 20, 2024, 09:28:34 pm
content: May i ask why somebody would bit-bang SPI instead of using a MCU with SPI hardware?

author: PCB.Wiz
author_rank: Super Contributor
timestamp: June 20, 2024, 09:34:46 pm
content: Quote from: Wilson__ on June 20, 2024, 07:29:22 pmWhat does the data really say ?Tsu, th are rarely more than 10ns on modern silicon.Usually software banging single bits already has an inherent edge delay, it is only if you AND or OR two bits, that two pins can change within 10ns.

author: ataradov
author_rank: Super Contributor
timestamp: June 20, 2024, 09:37:11 pm
content: Quote from: dietert1 on June 20, 2024, 09:28:34 pmYou may need more SPIs than available, you may not have SPI peripherals connected to the SPI pins due to other conflicts. And sometimes it is just easier and cleaner to do, especially if you don't need additional delays and simple pin manipulations at the CPU speed result in the desired maximum SPI clock.

author: Wilson__
author_rank: Frequent Contributor
timestamp: June 21, 2024, 05:11:57 pm
content: yes, done that. SPI description are a bit interesting in the use of English langusge. not really sure what it really mean when first read it. Different chip factory use different term too! STM is first edge and second edge

author: Wilson__
author_rank: Frequent Contributor
timestamp: June 21, 2024, 05:54:28 pm
content: That one is a bit older. 40 and 60 ns

author: dietert1
author_rank: Super Contributor
timestamp: June 21, 2024, 08:09:35 pm
content: Yes, STM32 SPI configuration has been a bit of try and error for me, too. But i always could make it generate the correct waveform, i mean the one shown in the SPI device datasheet. There are two important configuration bits: for clock polarity and 1edge/2edge. Besides they have something called "TI mode", that i didn't need until now. Anyway i would never let the CPU get stuck in bit-banging a whole SPI transaction.Also SPI is a bus for connecting multiple devices. I have one application where i needed two SPI interfaces: One of them for ADC data taking, the other one for TFT display and touch controller. In that case i have to set the SPI clock for each transaction, as the TFT controller wants 40 MHz and a typical DMA transaction has thousands of bytes. The touch controller wants 2 MHz.Regards, Dieter

author: pcprogrammer
author_rank: Super Contributor
timestamp: June 22, 2024, 06:02:13 am
content: The title specifies a STM32 M4 at 40 to 80MHz MCU clock.Toggle speed for an IO pin would be at max half that, so 20 to 40MHz. At 40MHz period time is 25ns. You have to do your best to reach this though for SPI where two lines need to change in order. This leads to at best 10 to 20MHz SPI clock speed, with 50ns period time max.So it is more likely that you need delays to lower the SPI clock speed to what your device can handle then the need for exact control on setup and hold time of the signal. This can be done with a "NOP" instruction, which on ARM translates in a register being moved onto itself.

author: Doctorandus_P
author_rank: Super Contributor
timestamp: June 22, 2024, 06:26:00 am
content: I am dabbling a bit in STM32 myself and recently I used an UART and an I/O pin to control an RS485 transceiver. In my code I toggled the I/O pin, and then immediately send data to the UART, and to my surprise I measured almost a microsecond between the I/O pin and the start bit. And this was for an STM32F411 running at 100MHz.STM32 is a lot more complex then the 8-bitters I was used to. Flash accelerators, different clock domains for different peripherals, maybe synchronizers between those things.At that time I was already quite happy that I got my program working (Including 16 bit CRC, ISR's) but I will have to look further into that to see whether I can find the cause. I do not like it when my uC is doing something I do not understand.

author: DavidAlfa
author_rank: Super Contributor
timestamp: June 22, 2024, 09:15:04 am
content: Something like this, adjust i<10 until getting the desired delay.Code:for(volatile uint32_t i=0; i<10; i++) { asm("nop"); }Though for just 10-100ns, just few nops will do it, adjust the delay by increasing or reducing the "nop\r\n" number.Code:asm("nop\r\nnop\r\nnop\r\nnop\r\nnop\r\nnop\r\nnop\r\nnop");

author: pcprogrammer
author_rank: Super Contributor
timestamp: June 22, 2024, 09:18:30 am
content: Quote from: DavidAlfa on June 22, 2024, 09:15:04 amYes I totally agree:Think you forgot to add something.

author: DavidAlfa
author_rank: Super Contributor
timestamp: June 22, 2024, 09:22:15 am
content: Yeah I accidentally submitted the message while writing it

author: ataradov
author_rank: Super Contributor
timestamp: June 22, 2024, 02:37:33 pm
content: Quote from: DavidAlfa on June 22, 2024, 09:15:04 amThis is a really bad idea. The only somewhat reliable way of getting the delay is this:Code:__attribute__((noinline, section(".ramfunc")))void delay_loops(uint32_t loops){asm volatile ("1: subs %, %, #1 \n"" bne 1b \n":  "+l"(loops));}The native loop code may produce very interesting results depending on the target device. On SAM E70, there is a short loop accelerator that would cache 128-bit line of flash. This way if the whole loop body is located within that 128-bit buffer, it would run very fast. But if loop happens to cross 128-bit boundary, then it will run significantly slower, in some cases 10 times slower.Similar things would happen with ST's ART accelerator.Your things may move around as other code changes, and if you figured out the number of iterations based on the slower version, some code change will make your timings incorrect.

author: DavidAlfa
author_rank: Super Contributor
timestamp: June 22, 2024, 05:00:55 pm
content: Then invalidate cache before execution.Code:SCB_EnableICache(); //Invalidate and then enable the instruction cacheSCB_EnableDCache(); //Invalidate and then enable the data cacheThis is not a timing-critical delay, just enough for signals to settle down, let's say you need min. 50ns, but 100, 150, 200ns will be good too.Personally, I'd use systick timer for this!

author: Wilson__
author_rank: Frequent Contributor
timestamp: June 22, 2024, 05:19:33 pm
content: Also quite some chips have "sync serial" mode that have data and clock lines. BUT not the following standard SPI

author: ataradov
author_rank: Super Contributor
timestamp: June 22, 2024, 05:29:36 pm
content: Quote from: DavidAlfa on June 22, 2024, 05:00:55 pmThis has nothing to do with the cache. CM4 does not even have a native cache in the core, so those functions are not defined.

author: xvr
author_rank: Frequent Contributor
timestamp: June 22, 2024, 09:31:56 pm
content: A little offtopic, just for information: RP2040 has hardware IO processor that can generate bitbang signals much faster and much more precisely than ARM managed IO.And it is 2 core ARM M0+ with very competitive price, so may be you can affrod migration from STM32 to it?