2018-10-15 05:26 AM
Background, using STM32F412CG:
- we have an external 20-bit ADC triggered by an external conversion strobe
- the ADC produces a signal when conversion is complete
- external ADC-complete signal must trigger DMA to read the ADC results (20-bit over SPI)
- DMA-completion of SPI xfer must trigger a transfer-complete interrupt (enter ISR after data received&ready)
I’ve done this with several other vendors’ parts but I’m a newbie to the STM family, so a few questions:
Thanks in advance for any pointers,
Best Regards, Dave
Solved! Go to Solution.
2018-10-16 08:00 AM
> An 100MHz CPU isn't very useful while it's sitting inside ISR in a loop waiting
> for SPI or bit-banging CS lines!
1 instruction to assert the chip select line (OK, maybe 2 or 3 assembler instructions). A couple more instructions to manually start the DMA/SPI transfer. No "sitting inside the ISR" waiting for anything. The DMA transfer complete interrupt can count the number of transfers, set up the next DMA xfer (if required) set the "I got a bunch of data" flag. Again, no "sitting" and not a lot of instructions.
Or use 2 timers. 1 as described previously to handle the A/D sample ready->SPI CS->Start DMA, and the 2nd to count the number of DMA transfers. This 2nd timer uses the "sample ready" input as a clock and set the compare event for the number of data samples you want. Yes, this takes careful planning and many times through the user manuals/data sheets up front to get the signals to pins that can be used for these functions. But it is possible.
2018-10-16 03:01 PM
I read that STMF412 Serial peripheral interface/ inter-IC sound (SPI/I2S) does seem to manage CS (though mysteriously called NSS). In one place it says frames can be 24-bit but then in the SPI sub-section it again says only 8-bit or 16-bit frames. Will this part really do a longer frame??
2018-10-16 03:35 PM
> though mysteriously called NSS
That's because that's what it is: a Slave Select (and N stands for Negated/Not). This is the standard terminology for SPI as it came from Motorola back then.
In the older STM32s SPIs, the NSS in master mode simply drops active when SPI is used for the first time and stays there. In newer STM32s (i.e. not 'F4) there is a "framing" mode, where NSS pulses between frames; frames in these newer STM32s may be from 4 (IIRC) to 16 bits long. There's also the TI mode, where NSS pulses during one clock cycle at the beginning of the frame.
As I've told you, there's no pre-chewed CS of your liking.
> In one place it says frames can be 24-bit but then in the SPI sub-section it again says only 8-bit or 16-bit frames.
The module can work as I2S and then it supports 24-bit data (for one channel), but that still transmitted with 32 clocks per channel and internally transported from/to a 16-bit register... confusing I know but you don't want to use I2S anyway.
I'd recommend to get some real hardware (e.g. a cheap Nucleo or a Disco board) and experiment.
JW
2018-10-18 03:19 PM
Jan and Bob, studied the manual a bit, seems like its possible but a huge pile of hooey.
Will this work?
Potential sequence for 24-bit transfer (note CONVST is externally-generated ‘conversion start’ signal for ADC):
Would this work? Is all this really required???
Thanks!
Best Regards, Dave
2018-10-18 11:51 PM
Yes, this is one very viable way to do things. This assumes CONVST is generated externally and is good as the SPI framing/chipselect, thus no responsibility of the STM32 in this regard.
Timer does not need the TIMx_ETR signal for triggering, only a few of timers have that; any TIMx_CHy would do, provided there is a DMA from the respective capture (should be for all except the "basic" TIM6 and TIM7). If more action is desired (timer start as outlined below), TIMx_CH1 and TIMx_CH2 are needed.
What I've suggested is to use the trigger to start a timer, and use that timer to generate the DMA requests to transfer to SPI_DR for Tx. Timers can be chained and another chained trigger can also generate the chipselect. Assuming you want to generate CONVST in STM32 too, and maybe even signals/data for the DAC you've mentioned initially, I'd perhaps go for a continuously running timer-based machine. The SPI Tx could also be omitted at the cost of one pin, generating the SPI clocks also from timers and bringing them back to SPI set as a slave. But this depends on knowing the complete specs.
You can also use the RXONLY mode of SPI you referred to, where SPI generates the clocks automagically without need for Tx; in that case the first DMA would write to control register of SPI to start it, except that you'd then also need to invent a mechanism to stop the SPI somehow, and that may be very far from trivial.
Please stop making those disgusted remarks - we've told you from start how this is, please take it or leave it.
JW
2018-10-30 08:26 AM
OK, I got this to work as follows (thanks again for the pointers @Community member @Bob S !):
Here's the picture:
PS: As you guys hinted, the HAL/LL stuff was more in the way then helpful, so I ended up doing the peripheral initialization the old-fashioned way (const structure to initialize entire peripheral register set, then enable when ready). Also CubeMX-generated code failed to initialize all the required registers.
2024-07-20 02:39 AM - edited 2024-07-20 02:40 AM
>It can't be. Timers can be triggered from external pin, and then in turn trigger DMA transfer(s).
Why not? There is an option given in CubeIDE to synchronize by EXTI, so what is that for? Why should I trigger DMA by a timer instead of directly by EXTI1?
I have gone through the DMAMUX and DMA sections of the reference manual RM0432. It states:
"Each DMAMUX request line multiplexer channel x can be individually synchronized by setting the synchronization enable (SE) bit in the DMAMUX_CxCR register. If a synchronization event occurs while there is no pending selected input DMA request line, it is discarded. The following asserted input request line is not connected to the DMAMUX multiplexer channel output until a synchronization event occurs again."
This means that DMA would wait for the EXTI every time to start the DMA transfer, right?
I am using the STM32L4P5-DK and ADS131M08 ADC. I need to get 8 channel samples (27 bytes with status response). I am getting DRDY every 125 µs (8000 sps). So, DRDY signal is taken as EXTI1 and the request number is 27. Won't the below configuration work?
Regards ,
AJ
2024-07-20 02:45 AM - edited 2024-07-20 02:46 AM
The original thread is for 'F412, which does not have DMAMUX.
In newer STM32 such as the 'L4+, the picture is of course very different - not just DMA can be triggered directly from some pins (through "EXTI"), but also the v2 SPI does have a continuous selection of transfer width rather than just 8 and 16 bits in 'F4.
JW
2024-07-20 04:48 AM
Hi Jan,
I resolved the issue with SPI2 being triggered by EXTI1. The problem was with the code generated by CubeMX, which did not set the number of request bits correctly. I manually set the bits using
*dmamux_c8cr_addr |= 0x1a << 19;
Since SPI2 is a full duplex master, how should I simultaneously enable SPI transmission to send dummy data to generate the clock and receive the ADC samples?
Regards,
AJ
2024-07-20 06:20 AM
You should externally trigger the DMA which performs the transmission; DMA which picks the received data should be triggered by SPI itself.
JW