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.

EK-TM4C1294XL: ADC DMA with ETHERNET task stop Issue

Part Number: EK-TM4C1294XL
Other Parts Discussed in Thread: SYSBIOS

HI,

I am using adc with dma in ping pong mode, at 1msps rate. while doing adc reading parallely I want to send data over ethernet, but when adc handler starts then it stops main task and hence it does not sending data over ethernet., I require to send data at every 100us .

while, when the adc not configured in dma mode and used as processor trigger in main loop then it works  with Ethernet fine, but it doesn't help to achieve desired speed as required in my application

I am using 

Ti -RTOS  2.16.01.14

GNU Compiler  7.2.1 (Linaro)

refer below code.

/* * Copyright (c) 2014, Texas Instruments Incorporated * All rights reserved. *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * are met:
*
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE
, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/*
* ======== tcpEcho.c ======== */
/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/cfg/global.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/Memory.h>
#include <xdc/runtime/System.h>
/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Task.h>
/* NDK Header files */
#include <ti/ndk/inc/netmain.h>
#include <ti/ndk/inc/_stack.h>
/* TI-RTOS Header files */
#include <ti/drivers/GPIO.h>
/* Example/Board Header files */
#include "Board.h"
#include #include #include #include
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "inc/hw_ints.h"
#include "driverlib/interrupt.h"
#include "driverlib/timer.h"
#include "driverlib/pin_map.h"
//#include "driverlib/rom.h"
//#include "driverlib/rom_map.h"
#include "driverlib/udma.h"
#include "inc/hw_udma.h"
#include "inc/hw_adc.h"
#include "driverlib/adc.h"
#define TCPPACKETSIZE 1024
#define TCPPORT 8080
#define NUMTCPWORKERS 3
SOCKET lSocket;
struct sockaddr_in sLocalAddr;
// uint32_t ui32Config, ui32ClockDiv; //for ADC Clock test
#define ADC_SAMPLE_BUF_SIZE (128)
uint32_t udmaCtrlTable[1024] __attribute__ ((aligned(1024)));
uint32_t ADC_OUT_1[6],ADC_OUT_2[6];
bool PSFLT,ARC,IDSLW,TEMP,MAIN_IN;
uint16_t RF_FORWARD,RF_REVERSE,TEMPERATURE,VDS,ID,VGS;
char mydata[41];
uint8_t counter=0;
//*****************************************************************************
// System clock rate in Hz.
//*****************************************************************************
uint32_t g_ui32SysClock;
void ADCSeq0Handler(void)
{ // Clear the Interrupt Flag.
ADCIntClear(ADC0_BASE, 0); //
uint32_t ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0);
if( uDMAChannelModeGet(UDMA_CHANNEL_ADC0|UDMA_PRI_SELECT) == 0)
{
// GPIOPinWrite(GPIO_PORTH_BASE, GPIO_PIN_3, 0x08);
uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,UDMA_MODE_PINGPONG,(void *)(ADC0_BASE + ADC_O_SSFIFO0)
,ADC_OUT_1,6);
uDMAChannelEnable(UDMA_CHANNEL_ADC0|UDMA_PRI_SELECT);
counter++;
// GPIOPinWrite(GPIO_PORTH_BASE, GPIO_PIN_3, 0x00);
}
if( uDMAChannelModeGet(UDMA_CHANNEL_ADC0|UDMA_ALT_SELECT) == 0)
{
// GPIOPinWrite(GPIO_PORTH_BASE, GPIO_PIN_3, 0x08);
uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG,(void *)(ADC0_BASE + ADC_O_SSFIFO0,
ADC_OUT_2,6);
uDMAChannelEnable(UDMA_CHANNEL_ADC0|UDMA_ALT_SELECT);
// GPIOPinWrite(GPIO_PORTH_BASE, GPIO_PIN_3, 0x00);
}
PSFLT=GPIOPinRead(GPIO_PORTK_BASE,GPIO_PIN_4);
ARC=GPIOPinRead(GPIO_PORTK_BASE,GPIO_PIN_5);
IDSLW=GPIOPinRead(GPIO_PORTK_BASE,GPIO_PIN_6);
TEMP=GPIOPinRead(GPIO_PORTK_BASE,GPIO_PIN_7);
if (RF_FORWARD > 4102 || RF_REVERSE > 4102 || TEMPERATURE > 3026 || VDS > 3791|| ID > 3351|| VGS > 3103 ||
VDS < 3146|| ID < 3138|| VGS < 2482)
{
GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_1, 0x02);
}
else
{
GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_1, 0x00);
}
}

void InitUDMA(void)
{
uDMAEnable();
// Enables uDMA
uDMAControlBaseSet(udmaCtrlTable);
//IntEnable(INT_UDMA);
uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0, UDMA_ATTR_ALL);
// Configures the base address of the channel control table. Table resides in system memory and holds control
// information for each uDMA channel. Table must be aligned on a 1024-byte boundary. Base address must be
// configured before any of the channel functions can be used
uDMAChannelAttributeEnable(UDMA_CHANNEL_ADC0, UDMA_ATTR_USEBURST );
uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_NEXT_USEBURST |UDMA_CHCTL_ARBSIZE_1);
uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_NEXT_USEBURST |UDMA_CHCTL_ARBSIZE_1);
uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG,(void *)(ADC0_BASE + ADC_O_SSFIFO0), ADC_OUT_1, 6);
uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG,(void *)(ADC0_BASE + ADC_O_SSFIFO0),ADC_OUT_2,6);
uDMAChannelEnable(UDMA_CHANNEL_ADC0);
//uDMAChannelRequest(UDMA_CHANNEL_ADC0);
ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS0); // Enables ADC interrupt source due to DMA on ADC sample sequence 0
// IntEnable(INT_ADC0SS0);
ADCIntRegister(ADC0_BASE,0,ADCSeq0Handler);
//! IntPrioritySet(INT_USB0, 0);
IntMasterEnable();
}

void InitConsole(void)
{ SysCtlPeripheralReset(SYSCTL_PERIPH_ADC0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
SysCtlPeripheralReset(SYSCTL_PERIPH_UDMA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3); //RF_FORWARD
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_2); //RF_REVERSE
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);
GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_0); //TEMPERATURE
GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_1); //VDS
GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_2); //ID
GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_3); //VGS
//ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 1);
IntDisable(INT_ADC0SS0);
ADCIntDisable(ADC0_BASE, 0);
ADCSequenceDisable(ADC0_BASE, 0);
ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_ALWAYS, 0);
ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_CH0);
ADCSequenceStepConfigure(ADC0_BASE, 0, 1, ADC_CTL_CH1);
ADCSequenceStepConfigure(ADC0_BASE, 0, 2, ADC_CTL_CH16);
ADCSequenceStepConfigure(ADC0_BASE, 0, 3, ADC_CTL_CH17);
ADCSequenceStepConfigure(ADC0_BASE, 0, 4, ADC_CTL_CH18);
ADCSequenceStepConfigure(ADC0_BASE, 0, 5, ADC_CTL_CH19|ADC_CTL_END);
ADCHardwareOversampleConfigure(ADC0_BASE, 64);
ADCSequenceDMAEnable(ADC0_BASE, 0);
ADCSequenceEnable(ADC0_BASE, 0);
}

void digital_init()
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK); //PSFLT
GPIOPinTypeGPIOInput(GPIO_PORTK_BASE, GPIO_PIN_4);
GPIODirModeSet(GPIO_PORTK_BASE,GPIO_PIN_4,GPIO_DIR_MODE_IN);
GPIOPinTypeGPIOInput(GPIO_PORTK_BASE, GPIO_PIN_5); //ARC
GPIODirModeSet(GPIO_PORTK_BASE,GPIO_PIN_5,GPIO_DIR_MODE_IN);
GPIOPinTypeGPIOInput(GPIO_PORTK_BASE, GPIO_PIN_6); //IDSLW
GPIODirModeSet(GPIO_PORTK_BASE,GPIO_PIN_6,GPIO_DIR_MODE_IN);
GPIOPinTypeGPIOInput(GPIO_PORTK_BASE, GPIO_PIN_7); //TEMP
GPIODirModeSet(GPIO_PORTK_BASE,GPIO_PIN_7,GPIO_DIR_MODE_IN);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); //FROM MAIN
GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, GPIO_PIN_7);
GPIODirModeSet(GPIO_PORTD_BASE,GPIO_PIN_7,GPIO_DIR_MODE_IN);
GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_6);
GPIOPadConfigSet(GPIO_PORTD_BASE,GPIO_PIN_6,GPIO_STRENGTH_10MA,GPIO_PIN_TYPE_STD_WPU );
GPIODirModeSet(GPIO_PORTD_BASE,GPIO_PIN_6,GPIO_DIR_MODE_OUT);
GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_6, 0x02);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM); //INTERLOCK PIN
GPIOPinTypeGPIOOutput(GPIO_PORTM_BASE, GPIO_PIN_1);
GPIOPadConfigSet(GPIO_PORTM_BASE,GPIO_PIN_1,GPIO_STRENGTH_10MA,GPIO_PIN_TYPE_STD_WPU );
GPIODirModeSet(GPIO_PORTM_BASE,GPIO_PIN_1,GPIO_DIR_MODE_OUT);
GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_1, 0x02);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH); // FOR LED
GPIOPinTypeGPIOOutput(GPIO_PORTH_BASE, GPIO_PIN_3);
GPIOPinWrite(GPIO_PORTH_BASE, GPIO_PIN_3, 0x08);
}

void delay(void)
{
SysCtlDelay(1000);
}

/* * ======== tcpHandler ======== * Creates new Task to handle new TCP connections. */
Void tcpHandler(UArg arg0, UArg arg1)
{
fdOpenSession(TaskSelf());
lSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (lSocket < 0)
{
// System_printf("tcpHandler: socket failed\n");
Task_exit();
return;
}
memset((char *)&sLocalAddr, 0, sizeof(sLocalAddr));
sLocalAddr.sin_family = AF_INET;
sLocalAddr.sin_addr.s_addr = inet_addr("192.168.0.135");
//htonl(INADDR_ANY);
sLocalAddr.sin_port = htons(arg0);
while(connect(lSocket, (struct sockaddr *)&sLocalAddr, sizeof(sLocalAddr)) < 0)
{
SysCtlDelay(400000);
}
// System_flush();
InitConsole();
InitUDMA();
while (true)
{
// ADCProcessorTrigger(ADC0_BASE, 0);
//
// ADCSequenceDataGet(ADC0_BASE, 0, ADC_OUT_1);
//
// if(uDMAChannelModeGet(UDMA_CHANNEL_ADC0|UDMA_PRI_SELECT) == 0)
// {
// uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,UDMA_MODE_BASIC,(void *)(ADC0_BASE + ADC_O_SSFIFO0), ADC_OUT_1,6);
// uDMAChannelEnable(UDMA_CHANNEL_ADC0); // // uDMAChannelRequest(UDMA_CHANNEL_ADC0);
// counter++;
// }
MAIN_IN=GPIOPinRead(GPIO_PORTD_BASE,GPIO_PIN_7);
RF_FORWARD= ADC_OUT_1[1]; //PE3
RF_REVERSE= ADC_OUT_1[2]; //PE2
TEMPERATURE=ADC_OUT_1[3]; //PK0
VDS =ADC_OUT_1[4]; //PK1
ID =ADC_OUT_1[5]; //PK2
VGS =ADC_OUT_1[0]; //PK3
//delay();
//======================LOCKING========================
//
if(counter>100)
{
counter=0;
sprintf(mydata,"*D01$%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d#",RF_FORWARD,RF_REVERSE,TEMPERATURE,VDS,ID,VGS,PSFLT,ARC,IDSLW,TEMP,MAIN_IN);
send(lSocket, (char *)mydata,sizeof(mydata), 0 );
}
}
}

/*
* ======== main ======== */
int main(void)
{
// Task_Handle taskHandle;
// Task_Params taskParams;
// Error_Block eb;
g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |SYSCTL_CFG_VCO_480), 120000000);
/* Call board init functions */
Board_initGeneral();
digital_init();
Board_initGPIO();
Board_initEMAC();
// ui32Config = ADCClockConfigGet(ADC0_BASE, &ui32ClockDiv);
/* Start BIOS */
BIOS_start();
return (0);
}

  • When you pasted the code in your post, it removed all returns and line feeds. It is very difficult to follow. Would you please repost and either use the "Insert" -> "Image/Video/File" menu pulldown, or the "Tools" -> "Source Code" pulldown. 

  • When you pasted the code in your post, it removed all returns and line feeds.

    That could the new E2E forum software. With an Opera Browser under Linux I pasted some code from a CCS Editor into the "Tools" -> "Source Code" pulldown and it also removed all returns and line feeds.

  • Chester, yes you are correct. I also found out that the  "Tools" -> "Source Code" pulldown does not allow you to paste source code. It looks like it only gives you the html source. I saw the problem using Chrome on Windows 10. Thanks for generating the new post on this issue.

    R&D,

    In the meantime, it might be better if you just use the "Insert" -> "Image/Video/File" menu pulldown method.

  • I Think all of us aware about source code paste or upload in new E2e Software is and issue for readability. FOr the case solution we can copy entire lines and paste in to new file in ccs and can process further.

  • Can you explain what you mean by "stops the main task"? Does the CPU trap to an exception? is the ADCSeq0Handler interrupt routine still being called?

    • yes, When DMA start ADCSeq0Handler Interrupt routine works, and hence as this starts the while loop in TCP HANDLER task stops working , so why this haapens when interrupt starts then other task stops to execute. So, my requirement is to run adc with dma in ping pong mode and at same time i want that data send on ethernet.

    while (true) { // ADCProcessorTrigger(ADC0_BASE, 0); // // ADCSequenceDataGet(ADC0_BASE, 0, ADC_OUT_1); // // if(uDMAChannelModeGet(UDMA_CHANNEL_ADC0|UDMA_PRI_SELECT) == 0) // { // uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,UDMA_MODE_BASIC,(void *)(ADC0_BASE + ADC_O_SSFIFO0), ADC_OUT_1,6); // uDMAChannelEnable(UDMA_CHANNEL_ADC0); // // uDMAChannelRequest(UDMA_CHANNEL_ADC0); // counter++; // } MAIN_IN=GPIOPinRead(GPIO_PORTD_BASE,GPIO_PIN_7); RF_FORWARD= ADC_OUT_1[1]; //PE3 RF_REVERSE= ADC_OUT_1[2]; //PE2 TEMPERATURE=ADC_OUT_1[3]; //PK0 VDS =ADC_OUT_1[4]; //PK1 ID =ADC_OUT_1[5]; //PK2 VGS =ADC_OUT_1[0]; //PK3 //delay(); //======================LOCKING======================== // if(counter>100) { counter=0; sprintf(mydata,"*D01$%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d#",RF_FORWARD,RF_REVERSE,TEMPERATURE,VDS,ID,VGS,PSFLT,ARC,IDSLW,TEMP,MAIN_IN); send(lSocket, (char *)mydata,sizeof(mydata), 0 ); } }

  • The problem is that when you register an interrupt service routine you disrupt the TI-RTOS  SYS/BIOS interrupt handling. Please see section 8 of SYS/BIOS User's Guide to see how to register interrupt routines in TI-RTOS/

  • Hi,

    I have tried to do so, according to guide, But, I am not able to understand SYS/BIOS in detail -may need more time on it by me. Also i Have tried some examples( from other developers blog , like timer in interrupt ) for registering interrupt in tcpecho.cfg file but that doesn't work.

    if anything you can help other wise I will put it on later on and close my project in different way.

    Thanks & Regards

    Khodidas