Teensy 4.1 How to start using DMA?

Just a quick update..
After a few hours of going through documentation and experimenting, I finally found how to switch the timer output to pin #33

I started by setting pin 33 to FlexPWM_PWM2_B00 output
Code:
IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_07 = 1;

Set PWM2_B00 lower value
Code:
FLEXPWM2_SM0VAL5   = 6;

Then enabled PWM2_B00
Code:
FLEXPWM2_OUTEN		|= FLEXPWM_OUTEN_PWMB_EN( 1 );

Next step is to implement the 16 bit color transfer to the DMA kickoff function and callback.
Hopefully I can come back with some "good news" in the next few days when I find time to mess around with this a little more.
 
I want to stop the PWM in some cases to write simple 16 bit commands to the display, so I set the registers to stop the PWM and to set pin #33 back to a GPIO pin:

Code:
FLEXPWM2_MCTRL    |= FLEXPWM_MCTRL_RUN( 0 ); // Turn off FLEXPWM
FLEXPWM2_OUTEN    |= FLEXPWM_OUTEN_PWMB_EN( 0 ); //Disable FlexPWM2_B00 output
IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_07 = 5; // set pin 33 back to GPIO4_IO07


I then tried to toggle the pin high and low using digitalWrite/digitalWriteFast to toggle the WR line manually for a single write strobe but It's not doing anything.


Also, I noticed that setting FLEXPWM_MCTRL_RUN( 0 ) an/or FLEXPWM_OUTEN_PWMB_EN( 0 ) does not stop the PWM, only changing the pin assignment in the MUX does - which is only doing half of what I want/need it to do.

Can someone make sense of this for me?
 
the problem is that the manual is riddled with a lot of domain-specific lingo, and (at least for me, coming to uControllers for a different field) it required some time to actually connect some dots and understand what the authors meant by certain things. Also the sources are well documented and are a great reference
...
I believe that it might be useful as an introduction to actually reading the reference manual - going over a particular use case and extracting the information needed for that from the docs.

Miciwan, thank you for this. You provided a great contextual framework. Some one should promote you from "junior member" to "super helpful member".
 
Last edited:
...This puts your buffer into the RAM1 section of memory (TCM - Tightly Coupled Memory) which is not cached...

Kurt, if you're working with something that uses DMA with repeated/ongoing transfers, and you want to minimize address/data bus contention (due to most of the 16 DMA channels actively doing similar ongoing transfers), would using the (TCM - Tightly Coupled Memory) be more efficient (than DMAMEM )?
 
Working on a CCD line-array application, with external SPI ADCs.

I am trying to adapt this DMA code to initiate an SPI transmit with a variable for a 16bit SPI transaction.

The SPI receive is being delt with elsewhere (probably a second Teensy 4) so I don't need to wait for the returned data.

Using flexPWM2, etc. as per miciwan's example.

Changed the setup to:

volatile uint32_t scan_count = 0;

// configure DMA channels
dmachannel.begin();
dmachannel.source( scan_count );
dmachannel.destination( LPSPI4_TDR );


I then want to start and stop the DMA/SPI at certian points in an indexed loop, state-machine caled by flexPWM2 interrupt at 500kHz

Start new loop

Count a number of loop cycles to get to starting point

dmachannel.enable();

For a given number of further counts, transmit data at each PWM trigger

SPI transmit

At end of active counts, stop DMA

dmachannel.disable();

Incriment position

scan_count++;

Loop until external trigger resets state-machine.

I know I am missing something obvious here, any pointers would be appreciated.
Many thanks.
 
Back
Top