I am building a device using the Teensy 4.1 that continuously reads data over USB from a client program on another device, does some processing, and then outputs that data to an OLED display. I previously had a version of this working that used direct writes to the GPIO registers to send data to the display. It didn't leave enough processor time for all of the incoming data so I have been trying to adopt DMA. I got DMA working with the display using sample data stored in memory, but when I try to send data to the Teensy, my client hangs trying to connect to the port. It seems this only happens as soon as I call dmaChannel.enable().
The client program is currently a very basic sketch in Processing using the Serial library.
My DMA configuration borrows heavily from miciwan's DMA output example here.
How can I get USB Serial and output DMA to work at the same time?
The client program is currently a very basic sketch in Processing using the Serial library.
My DMA configuration borrows heavily from miciwan's DMA output example here.
Code:
// Configure DMA channel
dmaChannel.begin();
dmaChannel.sourceBuffer(dmaBuffer, WIDTH * HEIGHT * sizeof(unsigned int));
dmaChannel.destination(GPIO1_DR);
dmaChannel.interruptAtHalf();
dmaChannel.interruptAtCompletion();
dmaChannel.attachInterrupt(loadDMABuffer);
// set the IOMUX mode to 3, to route it to FlexPWM
IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_06 = 1;
// setup flexPWM to generate clock signal on pin 4
FLEXPWM2_MCTRL |= FLEXPWM_MCTRL_CLDOK(1);
FLEXPWM2_SM0CTRL = FLEXPWM_SMCTRL_FULL | FLEXPWM_SMCTRL_PRSC(0);
FLEXPWM2_SM0CTRL2 = FLEXPWM_SMCTRL2_INDEP | FLEXPWM_SMCTRL2_CLK_SEL(0); // wait enable? debug enable?
FLEXPWM2_SM0INIT = 0;
FLEXPWM2_SM0VAL0 = 0; // midrange value to position the signale
FLEXPWM2_SM0VAL1 = 16; // max value
FLEXPWM2_SM0VAL2 = 0; // start A
FLEXPWM2_SM0VAL3 = 8; // end A
FLEXPWM2_OUTEN |= FLEXPWM_OUTEN_PWMA_EN(1);
FLEXPWM2_SM0TCTRL = FLEXPWM_SMTCTRL_PWAOT0;
FLEXPWM2_MCTRL |= FLEXPWM_MCTRL_LDOK(1);
FLEXPWM2_MCTRL |= FLEXPWM_MCTRL_RUN(1);
// clock XBAR
CCM_CCGR2 |= CCM_CCGR2_XBAR1(CCM_CCGR_ON);
// Tell XBAR to dDMA on Falling edge
// DMA will output next data piece on falling edge
// so the client can receive it on rising
XBARA1_CTRL0 = XBARA_CTRL_STS0 | XBARA_CTRL_EDGE0(2) | XBARA_CTRL_DEN0;
// connect the clock signal to DMA_CH_MUX_REQ30
xbarConnect(XBARA1_IN_FLEXPWM2_PWM1_OUT_TRIG0, XBARA1_OUT_DMA_CH_MUX_REQ30);
// trigger our DMA channel at the request from XBAR
dmaChannel.triggerAtHardwareEvent(DMAMUX_SOURCE_XBAR1_0);
dmaChannel.enable();
How can I get USB Serial and output DMA to work at the same time?