Showing results for 
Search instead for 
Did you mean: 

Use DMA as serial (bitstream) buffer with external clock input?

Associate II

I am sort of new to using STMCubeIDE/MX, but can use functions relating to timer use and configuration, as well as interrupts.

I am working on a project on the STM32F103Cx medium-density microcontroller platform- my application requires a serial data stream be buffered, and output in specifically timed bursts at another clock frequency, probably dictated by one of the internal timers (I am already using the advanced-function timer TIM1 for generating PWM, but a general-purpose timer TIM4 is free.)

I have 2 data streams (that are going at the same rate) that I want to store in memory, with DMA (so the MCU core can conserve its clock cycles and interrupts for other (somewhat concurrent) functions.)

I've tried to do something similar by taking the GPIO input states of the data stream pins, shifting them right by the lower GPIO pin number so they are the 2 LSBs of the byte, compound bitwise ORing the byte with the contents of a particular address of an array, shifting them left 2 bits, and repeating that until the GPIO states have filled up an entire byte. I then output the stored GPIO states at another time.

I believe my current code (sort of) works, but can't be sure because the slave clock I'm using, which generates the interrupts needed to store the GPIO states, is most likely preventing other interrupt functions from occurring (which should be executed when the interrupt comes no matter what.)

I've seen discussion and resolution of how to transmit data in parallel, but nothing about simply transferring data to memory via DMA, one bit at a time.

I also took a look at USART, but for my purposes, the serial data streams have no start or end bit, but a synchronization pulse (that CAN generate/use an interrupt) coming from the stream source that would tell the program/MCU when to go back to the start memory address for storing the data. To my knowledge, USART can't do that, but if it did, I would just use the USART data registers as a serial-to-parallel shift register that could be used by DMA.

In short, I need to buffer and output 2 serial data streams (just the sequence of bits, nothing else) at the same time. The 2 output bitstreams CAN generate/use interrupts, but the 2 input streams CANNOT generate/use interrupts.

Another thing to consider, is the fact that the maximum size of the buffer (including both data streams) is limited to 5.76 kilobytes (because that's the amount of data I need to buffer.)

I can post my code, if needed.


Not looking to code the HAL version, but have done with SPL previously

Output of pattern buffer: Need to find a TIMx_CHx that will trigger a DMA operation, TIM channel configured as Input Capture, DMA from memory 32-bit words to GPIOx->BSRR

For input might have use another pin/channel or indirect Ch1/Ch2 or Ch3/Ch4 for the trigger a different DMA unit, DMA from GPIOx->IDR

SPI Slave might do a better job at SERDES operations

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thank you for advice- I think I might settle for SPI for the data buffer input, and try to use timer outputs and an external interrupt generated by another timer. SPI seems significantly more simple than trying to use USART, because it seems that SPI (on the STM32) transmits 8 bits at a time (which can be assigned via user software definition to any arbitrary protocol, like MIDI, if I'm correct.)