2

I'm developing a RF modem based on a new protocol, which has a feature of streaming 96 Bytes in one frame - but they are sent on and on, before communication ends. I plan using two 96 Bytes buffers in STM32 - in next lines I will explain why.

I want to send first 96 Byte frames by the USB-CDC to STM32 - then external modem chip will generate a "9600bps" clock and STM will have to write Payload bits by bits on specified output pin(at the trailing edge of the each clock pulse). When STM32 will notice that it had sent a half of 96 Byte frame - that it sent to PC notification to send more data - PC will refill second 96 Byte buffer by USB-CDC immediately. When STM32 will end sending first buffer - immediately starts sending second buffer content. When it will send half of second buffer - as previous will ask PC for another 96Byte frame. And that way all the time, before PC will sent command to stop tx.

This transfer mode - a serial, with using a "trigger clock". Is this possible using DMA, and how could I set it? I want to use DMA to have ability to use USB while already streaming data to the radio modem chip. Is this the right approach?

I'm working in project building an opensource radiocommunication system project with both packet and stream capatibilities & digital voice. I'm designing and electronics for PC radiomodem. Project is called M17 and is maintained by Wojtek SP5WWP.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Sink
  • 91
  • 1
  • 2
  • 9

1 Answers1

3
  1. Re. general architecture. Serial communication over USB ACM does not have to use buffer of the same size and be synchronized with the downstream communication over SPI. You could use buffers as big as practically possible so PC can send data in advance. This will reduce the chance of buffer underflow if PC does not provide data fast enough. Use a circular buffer and fill it when a packet arrives from USB.

  2. DMA is the right approach. Although people often say that DMA is only necessary for high bandwidth operations, it may be actually easier to work with DMA than handling interrupts per every byte, even when you only handle 9600 bits per second.

  3. DMA controller in STM32F3 has a Half-Transfer Complete (HTIF in DMA_ISR) bit that you can poll or make it generate and interrupt. In conjunction with the Transfer Complete status (TCIF) and the Circular bit (CIRC in DMA_CCR) you can organize a double-buffered data pipe so that transfers can overlap with whatever else the MCU is doing. The application will reload the first half of the DMA buffer on the HTIF event. When the TCIF event happens, it reloads the second half. It has to be done quickly, before the other half is also completed. However, you need a double buffered pipeline only when you need to constantly stream data, i.e. overall amount is larger than can the size of the DMA buffer. Stopping a circular DMA may be tricky. I suppose both the STM32 and external chip know how many bytes to send. In that case, after this amount is received, disable the DMA.

  4. It seems you need a slave SPI in STM32 as the external chip generates SPI clock.

  5. DMA is not difficult to set up, however, it needs multiple things to work properly. I assume register-level programming, if you use some kind of framework, you'll need to find out how it implements these features. Enable clocks for SPI, GPIO port for SPI pins, and DMA, configure the pins as AF. Find the right DMA channel for the SPI peripheral. In case of SPI DMA you usually need two channels: TX and RX, but with the slave SPI, you may get away with one. Configure SPI, pay attention to clock polarity and phase, and set it to generate a DMA request for each TX and/or RX. Set the DMA CPAR channel register pointing to the SPI DR register in channel(s) and program all other DMA channel registers appropriately. Enable the DMA channel(s). Enable SPI in slave mode. When the SPI master clocks data on the MOSI/SCK pins, the DMA controller will put them in memory. When the buffer is half-full and full-full, the channel will set the HTIF and TCIF bits and generate and interrupt, if you told it to. Use these events to implement flow control.

A.K.
  • 839
  • 6
  • 13
  • Thank You very much for the answer! would I be able to set SPI slave in my STM32, and use it without CS signal? radio modem chip doesnt provides it. – Sink Dec 18 '19 at 18:42
  • STM32 does not need a CS signal. In fact, I do not know how to handle the CS signal it in the slave mode. Working with SPI may be tricky, first try to receive a single byte in DR in slave mode, without DMA, etc. You only need a toggling SCK for that. Then, add other things and organize the pipeline. Think about flow control and error conditions. – A.K. Dec 18 '19 at 18:50
  • "When the buffer is half-full and full-full, the channel will set the HTIF and TCIF bits and generate and interrupt, if you told it to. Use these events to implement flow control." - So after everything was sent(flag TCIF turn on) from buffer1 over SPI, do I have to stop DMA, overwrite buffer1 with buffer2, and turn it back? How Do You think, would it be fast enough? – Sink Dec 18 '19 at 22:39
  • Using the DMA is a technical issue that can be worked out. However, you need to think about the flow control first. If the modem knows the number of bytes in advance and expects all these bytes to be available, you cannot tell it to start the transfer before you have buffered everything in RAM, as you cannot expect PC to send everything in time. If, in the middle if the transfer, you can signal the modem that no more data is available, so it could makes a pause, then circular DMA could work. – A.K. Dec 19 '19 at 00:06