This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

GPIODMATriggerEnable example for DMA SPI transfer initiated by GPIO

Other Parts Discussed in Thread: CC3200

I am currently experimenting with transferring data using SPI and DMA on a CC3200. This is currently working perfect, but I want to go a step further and initiate the transfer by a GPIO falling edge input signal. At this moment I am thinking of setting up an interrupt for the GPIO pin and when the interrupt is triggered setting up the DMA transfer using 

uDMAChannelControlSet(UDMA_CH30_GSPI_RX, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_NONE | UDMA_ARB_1);
uDMAChannelTransferSet(UDMA_CH30_GSPI_RX, UDMA_MODE_BASIC, (void *)SPI_INPUT_REGISTER, &nullByte, spi_dma_word_count);

and the same for UDMA_CH31_GSPI_TX. Start the transfer by enabling the channel using 

uDMAChannelEnable(UDMA_CH30_GSPI_RX);

Instead of initiating the transfer every time by this interrupt code I saw the function GPIODMATriggerEnable in the documentation. I did not find any example on the internet using this method. Can someone explain me if this makes it possible to initiate a uDMA transfer by a GPIO pin? And if so, can you provide me with some sample code or an explanation how this works and how to set this up?

Thanks!

  • HI Robin,

    I'm looking into this to see if we can find a better explanation.

    Thanks,
    Aaron
  • Thanks Aaron, looking forward to your explanation.
  • HI Robin,

    Here's an example of transferring between 2 memory locations:

      //
      // Enable and configure uDMA
      //
      UDMAInit();

      //
      // Setup uDMA transfer on GPIO port A2 trigger
      //
      UDMASetupTransfer(UDMA_CH20_GPIOA2, UDMA_MODE_BASIC, 256,
                          UDMA_SIZE_8, UDMA_ARB_1024, ucSrc,
                          UDMA_SRC_INC_8, ucDst, UDMA_DST_INC_8);


      //
      // Set the trigger type
      //
      MAP_GPIOIntTypeSet(GPIOA2_BASE,GPIO_PIN_6,GPIO_RISING_EDGE);

      //
      // Enable DMA trigger for port GPIO A2
      //
      MAP_GPIODMATriggerEnable(GPIOA2_BASE);

    -Regards,

    Aaron

  • This looks great and straightforward. I'm gonna try and implement it in my project soon. I'll let you know the outcome. Thanks so much!
  • Hi Aaron,

    I tried triggering the transfer using your suggestion but it doesn't seem to work yet for me.

        // enable uDMA peripheral
        PRCMPeripheralClkEnable(PRCM_UDMA, PRCM_RUN_MODE_CLK);
        PRCMPeripheralReset(PRCM_UDMA);
    
        // register software interrupt handler
        IntPrioritySet(INT_UDMA, INT_PRIORITY_LVL_1);
        uDMAIntRegister(UDMA_INT_SW, udma_software_interrupt_handler);
        
        // register error interrupt handler
        IntPrioritySet(INT_UDMAERR, INT_PRIORITY_LVL_1);
        uDMAIntRegister(UDMA_INT_ERR, udma_error_interrupt_handler);
        
        // enable uDMA
        uDMAEnable();
        
        // set control table
    	static tDMAControlTable udma_control_table[UDMA_CONTROL_TABLE_SIZE] __attribute__((aligned(1024)));
        memset(udma_control_table, 0, sizeof(tDMAControlTable) * UDMA_CONTROL_TABLE_SIZE);
        uDMAControlBaseSet(udma_control_table);
    
        // set up SPI for DMA
        SPIIntRegister(SPI_BASE, spi_dma_interrupt_handler);
        SPIWordCountSet(SPI_BASE, word_count);
        
        SPIFIFOLevelSet(SPI_BASE, 1, 1);
        SPIFIFOEnable(SPI_BASE, SPI_RX_FIFO);
        SPIFIFOEnable(SPI_BASE, SPI_TX_FIFO);
        
        SPIDmaEnable(SPI_BASE, SPI_RX_DMA);
        SPIDmaEnable(SPI_BASE, SPI_TX_DMA);
        
        SPIIntEnable(SPI_BASE, SPI_INT_EOW);
    
        // enable PIN_50 (pin 44 on chip) for GPIO Input
        PRCMPeripheralClkEnable(PRCM_GPIOA0, PRCM_RUN_MODE_CLK);
        PinModeSet(PIN_50, PIN_MODE_0);
        GPIODirModeSet(GPIOA0_BASE, 0x01, GPIO_DIR_MODE_IN);
    
        // enable burst
        uDMAChannelAttributeEnable(UDMA_CH30_GSPI_RX, UDMA_ATTR_USEBURST);
        uDMAChannelAttributeEnable(UDMA_CH31_GSPI_TX, UDMA_ATTR_USEBURST);
        
        // setup transfer for receiving data
        uDMAChannelControlSet(UDMA_CH30_GSPI_RX, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
        uDMAChannelTransferSet(UDMA_CH30_GSPI_RX, UDMA_MODE_BASIC, (void *)SPI_BASE + MCSPI_O_RX0, output, 27);
    
        // setup transfer for transmitting data
        uDMAChannelControlSet(UDMA_CH31_GSPI_TX, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
        uDMAChannelTransferSet(UDMA_CH31_GSPI_TX, UDMA_MODE_BASIC, input, (void *)SPI_BASE + MCSPI_O_TX0, 27);
            
        // start transferring
    //    uDMAChannelEnable(UDMA_CH30_GSPI_RX);
    //    uDMAChannelEnable(UDMA_CH31_GSPI_TX);
    
        // start transferring on trigger
        GPIOIntTypeSet(GPIOA0_BASE, GPIO_PIN_0, GPIO_FALLING_EDGE);
        GPIODMATriggerEnable(GPIOA0_BASE);
    

    Before I just enabled the channels using `uDMAChannelEnable`. Instead, I now register GPIOA0_BASE as the trigger. When I trigger a falling edge transition (from 3.3v to GND on pin GPIOA0 / Pin 0) no DMA transfer seems to occur (my spi_dma_interrupt_handler function is not called). When I just enable the channel using `uDMAChannelEnable` everything works fine. 

    Do I have to set up the GPIOA0_BASE trigger in some order way?

    Thanks!

    Robin

  • Hi Robin,

    You still need to enable the channel, only with the GPIO

    -Aaron