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.

DMA GPIO TIVA C SERIES

Other Parts Discussed in Thread: STRIKE

Dear sir/madam

I am trying to write a code to transfer a part of memory to other location in memory by DMA and external trigger signal. I choose PORTE_PIN_3 as a trigger signal to DMA and I have connected an external square wave to this pin. Also I assigned DMA in UDMA_CH14_GPIOE and I have used ping pong mode but I monitored the memory there was not any data transfer. Could you please help me to figure out where the problem is?

The written code is as following.  

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_uart.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/udma.h"
#include "driverlib/PWM.h"
#include "driverlib/rom_map.h"

// Buffer definitions
#define UART_TXBUF_SIZE 16
#define UART_RXBUF_SIZE 16
static uint8_t g_pui8TxBuf[UART_TXBUF_SIZE];
static uint8_t g_pui8RxPing[UART_RXBUF_SIZE];
static uint8_t g_pui8RxPong[UART_RXBUF_SIZE];

void PWMInit1(void);

// Error counter
static uint32_t g_ui32DMAErrCount = 0;

// Transfer counters
static uint32_t g_ui32RxPingCount = 0;
static uint32_t g_ui32RxPongCount = 0;

// uDMA control table aligned to 1024-byte boundary
#pragma DATA_ALIGN(ucControlTable, 1024)
uint8_t ucControlTable[1024];

// Library error routine
#ifdef DEBUG
void
__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif

// uDMA error handler
void
uDMAErrorHandler(void)
{
uint32_t ui32Status;

ui32Status = ROM_uDMAErrorStatusGet();

if(ui32Status)
{
ROM_uDMAErrorStatusClear();
g_ui32DMAErrCount++;
}
}

// UART interrupt handler. Called on completion of uDMA transfer
void
DMA1IntHandler(void)
{
uint32_t ui32Status;
uint32_t ui32Mode;


GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);
// ui32Status = ROM_UARTIntStatus(UART1_BASE, 1);

GPIOIntClear(GPIO_PORTE_BASE, GPIO_PIN_3);

ui32Mode = ROM_uDMAChannelModeGet(UDMA_CH14_GPIOE | UDMA_PRI_SELECT);

if(ui32Mode == UDMA_MODE_STOP)
{
g_ui32RxPingCount++;

ROM_uDMAChannelTransferSet(UDMA_CH14_GPIOE | UDMA_PRI_SELECT,
UDMA_MODE_PINGPONG,
g_pui8TxBuf+2,
g_pui8RxPing, sizeof(g_pui8RxPing));
}

ui32Mode = ROM_uDMAChannelModeGet(UDMA_CH14_GPIOE | UDMA_ALT_SELECT);

if(ui32Mode == UDMA_MODE_STOP)
{
g_ui32RxPongCount++;

ROM_uDMAChannelTransferSet(UDMA_CH14_GPIOE | UDMA_ALT_SELECT,
UDMA_MODE_PINGPONG,
(g_pui8TxBuf),
g_pui8RxPong, sizeof(g_pui8RxPong));

}

if(!ROM_uDMAChannelIsEnabled(UDMA_CH14_GPIOE))
{

ROM_uDMAChannelTransferSet(UDMA_CH14_GPIOE | UDMA_PRI_SELECT,
UDMA_MODE_PINGPONG,
g_pui8TxBuf,
g_pui8RxPing, sizeof(g_pui8RxPing));


ROM_uDMAChannelEnable(UDMA_CH14_GPIOE);
}
}

// Initialize UART uDMA transfer
void
InitDMATransfer(void)
{
uint32_t ui32Idx;

// Initialize transmit buffer with some data
for(ui32Idx = 0; ui32Idx < UART_TXBUF_SIZE; ui32Idx++)
{
g_pui8TxBuf[ui32Idx] = ui32Idx;
}

// Enable UART1 and make sure it can run while the CPU sleeps
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_GPIOE);

// Configure and enable the UART with DMA


ROM_GPIOPinTypeGPIOInput(GPIO_PORTE_BASE,GPIO_PIN_3);
ROM_GPIOIntTypeSet(GPIO_PORTE_BASE,GPIO_PIN_3, GPIO_RISING_EDGE);
ROM_GPIOPadConfigSet(GPIO_PORTE_BASE,GPIO_PIN_3,GPIO_STRENGTH_8MA,GPIO_PIN_TYPE_STD_WPD);
GPIOIntClear(GPIO_PORTE_BASE, GPIO_PIN_3);
ROM_GPIODMATriggerEnable(GPIO_PORTE_BASE, GPIO_PIN_3);
GPIOIntEnable(GPIO_PORTE_BASE, GPIO_PIN_3);
ROM_IntEnable(INT_GPIOE);
IntMasterEnable();


// Receive channel setup for ping and pong
ROM_uDMAChannelAttributeDisable(UDMA_CH14_GPIOE,
UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
UDMA_ATTR_HIGH_PRIORITY |
UDMA_ATTR_REQMASK);

ROM_uDMAChannelControlSet(UDMA_CH14_GPIOE | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_8 |
UDMA_ARB_8);

ROM_uDMAChannelControlSet(UDMA_CH14_GPIOE | UDMA_ALT_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_8 |
UDMA_ARB_8);

ROM_uDMAChannelTransferSet(UDMA_CH14_GPIOE | UDMA_PRI_SELECT,
UDMA_MODE_PINGPONG,
g_pui8TxBuf+2,
g_pui8RxPing, sizeof(g_pui8RxPing));

ROM_uDMAChannelTransferSet(UDMA_CH14_GPIOE | UDMA_ALT_SELECT,
UDMA_MODE_PINGPONG,
(g_pui8TxBuf+2),
g_pui8RxPong, sizeof(g_pui8RxPong));

// Transmit channel setup for a basic transfer


// Enable both channels
ROM_uDMAChannelEnable(UDMA_CH14_GPIOE);
// ROM_uDMAChannelRequest(UDMA_CH14_GPIOE);
}

// main code
int
main(void)
{
volatile uint32_t ui32Loop;


ROM_FPULazyStackingEnable();

ROM_SysCtlClockSet(SYSCTL_SYSDIV_64 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_16MHZ);

ROM_SysCtlPeripheralClockGating(true);

// GPIO setup for LEDs
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_1);

// Enable uDMA
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);
ROM_IntEnable(INT_UDMAERR);
ROM_uDMAEnable();
ROM_uDMAControlBaseSet(ucControlTable);

// Initialize the uDMA/UART transfer

InitDMATransfer();

// PWMInit1();
// Blink the LED while the transfers occur
while(1)
{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);

SysCtlDelay(SysCtlClockGet() / 20 / 3);

GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0);


SysCtlDelay(SysCtlClockGet() / 20 / 3);

GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0);


}
}

  • Hello Majid,

    It seems that you are using TM4C123 device? Is that correct?

    How has the DMA Interrupt Handler been mapped in the startup_ccs.c?

    Also what is the frequency of the Square Wave from outside?

    Regards

    Amit

  • Hello

    Yes, I am using TM4C123,

    I have mapped on PORTE as following:

        DMA1IntHandler,                      // GPIO Port E

    I am using 1HZ right now but at the end I want to use 2.5MHz,

    I have checked configuration of DMA by ROM_uDMAChannelRequest(UDMA_CH14_GPIOE); and it is working. But PORTE_PIN_3 do not trigger the DMA to start data transfer.

    Thanks

    Majid

  • Hello Majid,

    The API call for uDMAChannelAssign is missing. This maps the DMA request from GPIO to the DMA controller.

    Regards

    Amit

  • Dear Amit,

    Thanks for your prompt reply,

    It is working.

    Also I have one more question. I have initialised PORTD as an input and changed source address to PORTD, as below but PORTD’s data did not transferred to the memory. What do I need to initialise more?

    ROM_uDMAChannelControlSet(UDMA_CH14_GPIOE | UDMA_PRI_SELECT,
    UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
    UDMA_ARB_1);

    ROM_uDMAChannelTransferSet(UDMA_CH14_GPIOE | UDMA_PRI_SELECT,
    UDMA_MODE_PINGPONG,
    (void *) (GPIO_PORTD_BASE),
    g_pui8RxPong, sizeof(g_pui8RxPong));

     

    Thanks

    Majid

     

     

  • Hello Majid,

    The GPIO Data Register implements bit masking. By accessing the base address the effective data will always be 0 due to the bit masking. You need to add the offset 0x3FC

    Also do keep in mind that PD7 is a locked pin, so you would need to run the Unlock Procedure as given in the data sheet

    Regards

    Amit

  • Amit Ashara said:
    run the Unlock Procedure as given in the data sheet

    Perhaps better stated, "As  (poorly) given in the data sheet."  (i.e. squint intensely as those too brief, camouflaged alerts - slip by!)

    Are there not 1,000+ such sheets - and minus proper emphasis - is not this "unexpected - very special pin treatment" - bound to be missed - by most everyone - forever?  (even and especially with your constant "catches and Sue C's new sticky!")

    One would hope that out of interest/respect for the prevention/reduction of needless wear/tear upon you - manual team could "spare" some "front of the manual BOLD Ink" - and properly/repeatably - make this special pin treatment more recognizable - thus effective!

    And - while condemning these 2 pins (which vary between MCUs) to NMI status - would not some analysis of, "percentage of MCU users - actually employing NMI - bear even faint consideration?"   (I'd bet that actual/deliberate NMI use pales when compared to those seeking those pins for, "more standard needs...")   

    Allowing such pins to default to NMI condemns your user majority!   In what universe does that make sense?

  • Hello cb1,

    Point has been duly noted (as earlier stated on multiple posts). Sue's post is a good place to put this together as we formulate a troubleshoot guide. The list is rather long (JTAG and XDS debugger, CCS issues, etc)

    Regards

    Amit

  • @Amit,

    "Duly noted" is not especially comforting to the man/woman in the electric chair!  And - has not such, "duly noted" exceeded two years duration?

    That (apparent) lack of care/concern rises far beyond, "due note!"   And that's a pity...

  • cb1- said:

    And - while condemning these 2 pins (which vary between MCUs) to NMI status - would not some analysis of, "percentage of MCU users - actually employing NMI - bear even faint consideration?"   (I'd bet that actual/deliberate NMI use pales when compared to those seeking those pins for, "more standard needs...")   

    Count me amoungst those who consider the existence on a physical NMI pin on this processor to be a strike against it.

     

    Robert

  • Thank you for that Robert - appreciated!  I knew that fact (minority use/desire for NMI default) - yet hesitated to lock/load "all ammo" - certain that vendor would not let this, "screaming pitfall" further linger/fester.  (I was so wrong)

    No one advocates the excise of NMI - instead simply require those seeking NMI to, "jump the unlock hoop!"  They are - after all - the group most likely to successfully identify & negotiate that special, unlock effort...

  • cb1- said:
    No one advocates the excise of NMI

    Actually I do, but I don't expect that matters. Jumping though hoops to enable it is better than jumping through hoops to work around it but still....

    NMI is dangerous even in skilled hands. There is little reason to use it on most processors.  On processors (like Arm Cortex variants) with programmable interrupt priorities those few reasons drop to nearly zero.  I'd say zero but I leave open the possibility that someone will come up with something I haven't thought of.  I do not think I've ever seen a case where an NMI was the appropriate solution. Generally by the time someone gets to the point of actually needing an NMI the obvious question is why are you not doing this in hardware?

    Robert

  • Robert and CB1,

    Amen!  I couldn't agree more - I have been designing embedded systems from scratch for >35 years and have never used, or been tempted to use, the NMI input.

    I would recommend that TI retain one (1) NMI capable input that is not configured by default.  If a hypothetical system is so buggy or fraught with noise, bad power, etc. that it can not execute code to the point of configuring/enabling the NMI, how would an auto-enabled NMI been of superior service!?

    Thanks for lending an ear...

    Regards,

    Dave

  • Ola Dave,

    It's not just the loan of our "ear" which overly concerns...

    Know though that this issue has received, "full/high" note!   (how comforting...)  cb1 raises pistol to head... (again)

  • SourceTwo said:
    have never used, or been tempted to use, the NMI input

    I have had to use an NMI (not by choice, my one request to the circuit designers had been don't use the NMI).  It's probably a big part of my dislike of the mere existence of an NMI input.

     

    Robert

  • In my case, I'm the only guy, so I get/have to make all the choices (for better or worse)!

    Regards,

    Dave

  • SourceTwo said:
    In my case, I'm the only guy

    Might that indicate that the, (more fitting), "Source One" had earlier been usurped/registered?  Pity...

  • Correction: only electronics / firmware person - I am grateful to be balanced by team members with other disciplines.

    I should be careful with imprecise language around you;-)

    Best Regards,

    Dave

  • SourceTwo said:
    I should be careful with imprecise language around you;-)

    That one was so, "teed up" - green so beckoning/near - this reporter (trusty 7 iron) powerless to resist.

    Words - their choice/order/flow - do convey meaning.  Substantial time lost here/elsewhere - due to rushed/failed (dare I say) - "imprecise language"...  Unmonitored, uncommented - even extends to famed, "sticky" - much diluting its impact!