Other Parts Discussed in Thread: EK-TM4C129EXL, EK-TM4C1294XL
Tool/software: Code Composer Studio
Hello I am using EK-TM4C129EXL . I want to send ADC values from tiva to PC using udp (i am using udp test tool) . i successfully run udp echo example.
and successfully read the ADC values via UART0.
But i got stuck in how to send these values to pc via UDP.
This is my adc .c file
//***************************************************************************** // // single_ended.c - Example demonstrating how to configure the ADC for // single ended operation. // // Copyright (c) 2010-2017 Texas Instruments Incorporated. All rights reserved. // Software License Agreement // // 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. // // This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. // //***************************************************************************** #include <stdbool.h> #include <stdint.h> #include "inc/hw_memmap.h" #include "driverlib/adc.h" #include "driverlib/gpio.h" #include "driverlib/pin_map.h" #include "driverlib/sysctl.h" #include "driverlib/uart.h" #include "utils/uartstdio.h" //***************************************************************************** // //! \addtogroup adc_examples_list //! <h1>Single Ended ADC (single_ended)</h1> //! //! This example shows how to setup ADC0 as a single ended input and take a //! single sample on AIN0/PE3. //! //! This example uses the following peripherals and I/O signals. You must //! review these and change as needed for your own board: //! - ADC0 peripheral //! - GPIO Port E peripheral (for AIN0 pin) //! - AIN0 - PE3 //! //! The following UART signals are configured only for displaying console //! messages for this example. These are not required for operation of the //! ADC. //! - UART0 peripheral //! - GPIO Port A peripheral (for UART0 pins) //! - UART0RX - PA0 //! - UART0TX - PA1 //! //! This example uses the following interrupt handlers. To use this example //! in your own application you must add these interrupt handlers to your //! vector table. //! - None. // //***************************************************************************** //***************************************************************************** // // This function sets up UART0 to be used for a console to display information // as the example is running. // //***************************************************************************** void InitConsole(void) { // // Enable GPIO port A which is used for UART0 pins. // TODO: change this to whichever GPIO port you are using. // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // // Configure the pin muxing for UART0 functions on port A0 and A1. // This step is not necessary if your part does not support pin muxing. // TODO: change this to select the port/pin you are using. // GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); // // Enable UART0 so that we can configure the clock. // SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); // // Use the internal 16MHz oscillator as the UART clock source. // UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC); // // Select the alternate (UART) function for these pins. // TODO: change this to select the port/pin you are using. // GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); // // Initialize the UART for console I/O. // UARTStdioConfig(0, 115200, 16000000); } //***************************************************************************** // // Configure ADC0 for a single-ended input and a single sample. Once the // sample is ready, an interrupt flag will be set. Using a polling method, // the data will be read then displayed on the console via UART0. // //***************************************************************************** int main(void) { uint32_t ui32SysClock; // // This array is used for storing the data read from the ADC FIFO. It // must be as large as the FIFO for the sequencer in use. This example // uses sequence 3 which has a FIFO depth of 1. If another sequence // was used with a deeper FIFO, then the array size must be changed. // uint32_t pui32ADC0Value[1]; // // Set the clocking to run at 20 MHz (200 MHz / 10) using the PLL. When // using the ADC, you must either use the PLL or supply a 16 MHz clock // source. // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the // crystal on your board. // ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 20000000); // // Set up the serial console to use for displaying messages. This is // just for this example program and is not needed for ADC operation. // InitConsole(); // // The ADC0 peripheral must be enabled for use. // SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); // // For this example ADC0 is used with AIN0 on port E7. // The actual port and pins used may be different on your part, consult // the data sheet for more information. GPIO port E needs to be enabled // so these pins can be used. // TODO: change this to whichever GPIO port you are using. // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); // // Select the analog ADC function for these pins. // Consult the data sheet to see which functions are allocated per pin. // TODO: change this to select the port/pin you are using. // GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3); // // Enable sample sequence 3 with a processor signal trigger. Sequence 3 // will do a single sample when the processor sends a signal to start the // conversion. Each ADC module has 4 programmable sequences, sequence 0 // to sequence 3. This example is arbitrarily using sequence 3. // ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0); // // Configure step 0 on sequence 3. Sample channel 0 (ADC_CTL_CH0) in // single-ended mode (default) and configure the interrupt flag // (ADC_CTL_IE) to be set when the sample is done. Tell the ADC logic // that this is the last conversion on sequence 3 (ADC_CTL_END). Sequence // 3 has only one programmable step. Sequence 1 and 2 have 4 steps, and // sequence 0 has 8 programmable steps. Since we are only doing a single // conversion using sequence 3 we will only configure step 0. For more // information on the ADC sequences and steps, reference the datasheet. // ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END); // // Since sample sequence 3 is now configured, it must be enabled. // ADCSequenceEnable(ADC0_BASE, 3); // // Clear the interrupt status flag. This is done to make sure the // interrupt flag is cleared before we sample. // ADCIntClear(ADC0_BASE, 3); // // Sample AIN0 forever. Display the value on the console. // while(1) { // // Trigger the ADC conversion. // ADCProcessorTrigger(ADC0_BASE, 3); // // Wait for conversion to be completed. // while(!ADCIntStatus(ADC0_BASE, 3, false)) { } // // Clear the ADC interrupt flag. // ADCIntClear(ADC0_BASE, 3); // // Read ADC Value. // ADCSequenceDataGet(ADC0_BASE, 3, pui32ADC0Value); // // Display the AIN0 (PE3) digital value on the console. // UARTprintf("AIN0 = %4d\r", pui32ADC0Value[0]); // // This function provides a means of generating a constant length // delay. The function delay (in cycles) = 3 * parameter. Delay // 250ms arbitrarily. // SysCtlDelay(ui32SysClock / 12); } } S
this is the udp.c file
#include <stdbool.h> #include <stdint.h> #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "driverlib/flash.h" #include "driverlib/interrupt.h" #include "driverlib/gpio.h" #include "driverlib/rom_map.h" #include "driverlib/sysctl.h" #include "driverlib/systick.h" #include "utils/lwiplib.h" #include "utils/ustdlib.h" #include "utils/uartstdio.h" #include "drivers/pinout.h" #include "lwip/udp.h" #include "driverlib/adc.h" #include "driverlib/pin_map.h" #include "driverlib/uart.h" #include "utils/uartstdio.h" //***************************************************************************** // //! \addtogroup example_list //! <h1>Ethernet with lwIP (enet_lwip)</h1> //! //! This example application demonstrates the operation of the Tiva //! Ethernet controller using the lwIP TCP/IP Stack. DHCP is used to obtain //! an Ethernet address. If DHCP times out without obtaining an address, //! AutoIP will be used to obtain a link-local address. The address that is //! selected will be shown on the UART. //! //! UART0, connected to the ICDI virtual COM port and running at 115,200, //! 8-N-1, is used to display messages from this application. Use the //! following command to re-build the any file system files that change. //! //! ../../../../tools/bin/makefsfile -i fs -o enet_fsdata.h -r -h -q //! //! For additional details on lwIP, refer to the lwIP web page at: //! <a href="http://savannah.nongnu.org/projects/lwip/">savannah.nongnu.org/.../</a> // //***************************************************************************** //***************************************************************************** // // Defines for setting up the system clock. // //***************************************************************************** #define SYSTICKHZ 100 #define SYSTICKMS (1000 / SYSTICKHZ) //***************************************************************************** // // Interrupt priority definitions. The top 3 bits of these values are // significant with lower values indicating higher priority interrupts. // //***************************************************************************** #define SYSTICK_INT_PRIORITY 0x80 #define ETHERNET_INT_PRIORITY 0xC0 //***************************************************************************** // // The current IP address. // //***************************************************************************** uint32_t g_ui32IPAddress; //***************************************************************************** // // The system clock frequency. // //***************************************************************************** uint32_t g_ui32SysClock; //***************************************************************************** // // Volatile global flag to manage LED blinking, since it is used in interrupt // and main application. The LED blinks at the rate of SYSTICKHZ. // //***************************************************************************** volatile bool g_bLED; //***************************************************************************** // // The error routine that is called if the driver library encounters an error. // //***************************************************************************** #ifdef DEBUG void __error__(char *pcFilename, uint32_t ui32Line) { } #endif uint32_t pui32ADC0Value[1]; void ADC_init( void ); void udp_echo_init( void ); //***************************************************************************** // // Display an lwIP type IP Address. // //***************************************************************************** void DisplayIPAddress(uint32_t ui32Addr) { char pcBuf[16]; // // Convert the IP Address into a string. // usprintf(pcBuf, "%d.%d.%d.%d", ui32Addr & 0xff, (ui32Addr >> 8) & 0xff, (ui32Addr >> 16) & 0xff, (ui32Addr >> 24) & 0xff); // // Display the string. // UARTprintf(pcBuf); } //***************************************************************************** // // Required by lwIP library to support any host-related timer functions. // //***************************************************************************** void lwIPHostTimerHandler(void) { uint32_t ui32NewIPAddress; // // Get the current IP address. // ui32NewIPAddress = lwIPLocalIPAddrGet(); // // See if the IP address has changed. // if(ui32NewIPAddress != g_ui32IPAddress) { // // See if there is an IP address assigned. // if(ui32NewIPAddress == 0xffffffff) { // // Indicate that there is no link. // UARTprintf("Waiting for link.\n"); } else if(ui32NewIPAddress == 0) { // // There is no IP address, so indicate that the DHCP process is // running. // UARTprintf("Waiting for IP address.\n"); } else { // // Display the new IP address. // UARTprintf("IP Address: "); DisplayIPAddress(ui32NewIPAddress); UARTprintf("\nEcho Server is ready.\n"); } // // Save the new IP address. // g_ui32IPAddress = ui32NewIPAddress; } // // If there is not an IP address. // if((ui32NewIPAddress == 0) || (ui32NewIPAddress == 0xffffffff)) { // // Do nothing and keep waiting. // } } //***************************************************************************** // // The interrupt handler for the SysTick interrupt. // //***************************************************************************** void SysTickIntHandler(void) { // // Call the lwIP timer handler. // lwIPTimer(SYSTICKMS); // // Tell the application to change the state of the LED (in other words // blink). // g_bLED = true; } //***************************************************************************** // // This example demonstrates the use of the Ethernet Controller. // //***************************************************************************** int main(void) { uint32_t ui32User0, ui32User1; uint8_t pui8MACArray[8]; // uint32_t pui32ADC0Value[1]; // // Make sure the main oscillator is enabled because this is required by // the PHY. The system must have a 25MHz crystal attached to the OSC // pins. The SYSCTL_MOSC_HIGHFREQ parameter is used when the crystal // frequency is 10MHz or higher. // SysCtlMOSCConfigSet(SYSCTL_MOSC_HIGHFREQ); // // Run from the PLL at 120 MHz. // g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); PinoutSet(true, false); // // Configure UART. // UARTStdioConfig(0, 115200, g_ui32SysClock); // // Clear the terminal and print banner. // UARTprintf("\033[2J\033[H"); UARTprintf("Ethernet lwIP udp echo example\n\n"); // // Configure Port N1 for as an output for the animation LED. // MAP_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_1); // // Initialize LED to OFF (0) // MAP_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, ~GPIO_PIN_1); // // Configure SysTick for a periodic interrupt. // MAP_SysTickPeriodSet(g_ui32SysClock / SYSTICKHZ); MAP_SysTickEnable(); MAP_SysTickIntEnable(); // // Configure the hardware MAC address for Ethernet Controller filtering of // incoming packets. The MAC address will be stored in the non-volatile // USER0 and USER1 registers. // MAP_FlashUserGet(&ui32User0, &ui32User1); if((ui32User0 == 0xffffffff) || (ui32User1 == 0xffffffff)) { // // We should never get here. This is an error if the MAC address has // not been programmed into the device. Exit the program. // Let the user know there is no MAC address // UARTprintf("No MAC programmed!\n"); while(1) { } } // // Tell the user what we are doing just now. // UARTprintf("Waiting for IP.\n"); // // Convert the 24/24 split MAC address from NV ram into a 32/16 split MAC // address needed to program the hardware registers, then program the MAC // address into the Ethernet Controller registers. // pui8MACArray[0] = ((ui32User0 >> 0) & 0xff); pui8MACArray[1] = ((ui32User0 >> 8) & 0xff); pui8MACArray[2] = ((ui32User0 >> 16) & 0xff); pui8MACArray[3] = ((ui32User1 >> 0) & 0xff); pui8MACArray[4] = ((ui32User1 >> 8) & 0xff); pui8MACArray[5] = ((ui32User1 >> 16) & 0xff); // // Initialize the lwIP library, using DHCP. // lwIPInit(g_ui32SysClock, pui8MACArray, 0, 0, 0, IPADDR_USE_DHCP); // // Initialize the echo server. //Run the udpSendReceive Linux or Windows executable that is shipped with TI-RTOS. //The executable is found in: //<tirtos_install_dir>\packages\examples\tools\udpSendReceive //Usage: ./udpSendReceive <IP-addr> <port> <id> -l[length] -s[sleep in uS] //<IP-addr> is the IP address //<port> is the UDP port being listened to (23) //<id> is a unique id for the executable. Printed out when 1000 packets are // transmitted. It allows the user to run multiple instances // of udpSendReceive. //Optional: // -l[length] size of the packet in bytes. Default is 1024 bytes. // -s[sleep in uS] usleep time to between sends. Default is 1000 uSecs. //Example: // udpSendReceive 192.168.1.5 23 1 -s100 //Messages such as the following will begin to appear on the terminal window when //a UDP packet has been echoed back: // Starting test with a 1000 uSec delay between transmits // [id 1] count = 1000, time = 12 // [id 1] count = 2000, time = 24 // [id 1] count = 3000, time = 36 // // // Trigger the ADC conversion. // udp_echo_init(); // // Set the interrupt priorities. We set the SysTick interrupt to a higher // priority than the Ethernet interrupt to ensure that the file system // tick is processed if SysTick occurs while the Ethernet handler is being // processed. This is very likely since all the TCP/IP and HTTP work is // done in the context of the Ethernet interrupt. // MAP_IntPrioritySet(INT_EMAC0, ETHERNET_INT_PRIORITY); MAP_IntPrioritySet(FAULT_SYSTICK, SYSTICK_INT_PRIORITY); // // Loop forever, processing the LED blinking. All the work is done in // interrupt handlers. // while(1) { // // Wait till the SysTick Interrupt indicates to change the state of the // LED. // while(g_bLED == false) { } // // Clear the flag. // g_bLED = false; // // Toggle the LED. // MAP_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, (MAP_GPIOPinRead(GPIO_PORTN_BASE, GPIO_PIN_1) ^ GPIO_PIN_1)); // // Display the AIN0 (PE3) digital value on the console. // // UARTprintf("AIN0 = %4d\r", pui32ADC0Value[0]); // // This function provides a means of generating a constant length // delay. The function delay (in cycles) = 3 * parameter. Delay // 250ms arbitrarily. // // SysCtlDelay(g_ui32SysClock / 12); } } void ADC_init(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3); ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0); ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END); ADCSequenceEnable(ADC0_BASE, 3); ADCIntClear(ADC0_BASE, 3); ADCProcessorTrigger(ADC0_BASE, 3); // // Wait for conversion to be completed. // while(!ADCIntStatus(ADC0_BASE, 3, false)) { } // // Clear the ADC interrupt flag. // ADCIntClear(ADC0_BASE, 3); // // Read ADC Value. // ADCSequenceDataGet(ADC0_BASE, 3, pui32ADC0Value); SysCtlDelay(g_ui32SysClock / 12); } void udp_echo_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port) { ADC_init(); if (p != NULL) { p=pbuf_alloc(PBUF_TRANSPORT, 1, PBUF_RAM); memcpy(p->payload, pui32ADC0Value[0], 1); /* send received packet back to sender */ udp_sendto(pcb, p, addr, 12345); /* free the pbuf */ pbuf_free(p); } } void udp_echo_init(void) { struct udp_pcb * pcb; /* get new pcb */ pcb = udp_new(); if (pcb == NULL) { LWIP_DEBUGF(UDP_DEBUG, ("udp_new failed!\n")); return; } /* bind to any IP address on port 23 */ if (udp_bind(pcb, IP_ADDR_ANY, 23) != ERR_OK) { LWIP_DEBUGF(UDP_DEBUG, ("udp_bind failed!\n")); return; } /* set udp_echo_recv() as callback function for received packets */ udp_recv(pcb, udp_echo_recv, NULL); }