Hello,
I am working on setting up the DMA on the RM57 HDK (XRM57 mcu) to service 3 separate mibspi peripherals. I've managed to get it working transferring data with hardware triggers for each frame in the block (only if the transfer group buffer mode is set to 4), but I can't seem to get it to generate a block transfer complete (BTC) interrupt when the block (should) be finished nor can I get it to transmit more than a single frame when the buffer mode is set to 7 and the trigger type is set to frame, which would make sense if the DMA TX/RX frames aren't being properly triggered.
Essentially I want to do the following:
I have an ADC that requires a 24 byte spi operation once every 65 microseconds. The ADC itself is currently clocked at 10MHz. The mibspi and DMA should handle all these operations and the DMA should copy each 24B transfer to internal memory and notify the cpu once for every 128 transfers (~ every 8.3ms). The CPU should then change the DMA RX block pointer and restart the DMA.
To accomplish this I've setup the following:
I have setup the mibspi for 8 byte operations with a transfer group size of 24 and a buffer mode of 7 (wait until TX/RX full/empty). Oneshot transfer is not set.
The mibspi is triggered off the rising edge of an internal HET signal once every 65 microseconds.
The DMA TX control packet is configured as shown:
where frameCount = 128
hwInfo->transferGroupSize_elements = 24
dmaControlPacketTX.SADD = sourceAddress; dmaControlPacketTX.DADD = (uint32_t)&(hwInfo->ramBaseAddress->tx[0].data); dmaControlPacketTX.CHCTRL = 0; dmaControlPacketTX.FRCNT = frameCount; dmaControlPacketTX.ELCNT = hwInfo->transferGroupSize_elements; dmaControlPacketTX.ELDOFFSET = 4; dmaControlPacketTX.ELSOFFSET = 2; dmaControlPacketTX.FRDOFFSET = 0; dmaControlPacketTX.FRSOFFSET = 0; dmaControlPacketTX.PORTASGN = PORTA_READ_PORTB_WRITE; dmaControlPacketTX.RDSIZE = ACCESS_16_BIT; dmaControlPacketTX.WRSIZE = ACCESS_16_BIT; dmaControlPacketTX.TTYPE = FRAME_TRANSFER; dmaControlPacketTX.ADDMODERD = ADDR_OFFSET; dmaControlPacketTX.ADDMODEWR = ADDR_OFFSET; dmaControlPacketTX.AUTOINIT = AUTOINIT_ON;
The DMA RX packet is configured as follows:
dmaControlPacketRX.SADD = (uint32_t)&(hwInfo->ramBaseAddress->rx[0].data); dmaControlPacketRX.DADD = destAddress; dmaControlPacketRX.CHCTRL = 0; dmaControlPacketRX.FRCNT = frameCount; dmaControlPacketRX.ELCNT = hwInfo->transferGroupSize_elements; dmaControlPacketRX.ELDOFFSET = 2; dmaControlPacketRX.ELSOFFSET = 4; dmaControlPacketRX.FRDOFFSET = hwInfo->transferGroupSize_elements*2; dmaControlPacketRX.FRSOFFSET = 0; dmaControlPacketRX.PORTASGN = PORTB_READ_PORTA_WRITE; dmaControlPacketRX.RDSIZE = ACCESS_16_BIT; dmaControlPacketRX.WRSIZE = ACCESS_16_BIT; dmaControlPacketRX.TTYPE = FRAME_TRANSFER; dmaControlPacketRX.ADDMODERD = ADDR_OFFSET; dmaControlPacketRX.ADDMODEWR = ADDR_OFFSET; dmaControlPacketRX.AUTOINIT = AUTOINIT_ON;
My understanding of the DMA is that with TTYPE=FRAME_TRANSFER every dma req. signal the mibspi generates should trigger a single frame transfer until all 128 frames have been transferred, causing a block complete transfer interrupt. With an SPI buffer mode of 7, once the TX buffer is empty the DMA TX packet should refresh it, and once the RX buffer is full the DMA RX packet should empty it, and once this has been done the next HET trigger event should cause another SPI bus operation and the cycle should repeat until the DMA RX BTC interrupt is complete 128 operations later.
I've had success getting the DMA BTC interrupts when when I only want to transmit a single frame, however I don't want to tie the CPU up with an spi interrupt every 65us if possible. I can also see the SPI transfers on the scope once every 65us (as triggered by the HET) if the TTYPE is set to BLOCK_TRANSFER or if the spi buffer mode is set to 4 (always transmit) but this obviously doesn't give the quite the behavior I want.
One question as well regarding the frame and element offset: is the element offset reset after every frame? I am assuming so with this setup (reading/writing the SPI does not adjust frame, but reads from SPI to internal buffer do) but it wasn't completely clear to me when I read through the TRM.
Any assistance would be much appreciated,