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.

CCS/EK-TM4C1294XL: how to print floating values on uart

Part Number: EK-TM4C1294XL

Tool/software: Code Composer Studio

Hi ,

I am trying to print the computed power and voltage values from the ADC values using UART. I have followed the sensohub examble in tivaware. But I am getting the following error.

Multiple markers at this line
    - #1531-D (ULP 5.2) Detected floating point operation(s). Recommend moving them
     to RAM during run time or not using as these are processing/power intensive
    - <a href="processors.wiki.ti.com/.../
     225">#225-D</a> function "uftostr" declared implicitly

THe code is as follows:

//*****************************************************************************
//
// 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 <string.h>
#include "inc/hw_memmap.h"
#include "driverlib/adc.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include <string.h>
#include "driverlib/uart.h"
#include "driverlib/debug.h"

#include "utils/uartstdio.h"

#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_memmap.h"
#include <driverlib/timer.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"
#include "driverlib/rom.h"
#include "driverlib/interrupt.h"


#include "inc/hw_ints.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.
//
//*****************************************************************************
//volatile uint32_t  adcResult[1];

//volatile  unit32_t pui32ADC0Value1[1];

uint32_t pui32ADC0Value[1];
static volatile bool g_bIntFlag = false;
#define SAMPLE_PERIOD_US 1000
float current = 0;
    float voltage=3.3;
    float power = 0;
    float maxPwr = 0;
    float avgPwr = 0;
    int i = 0;
//#define SAMPLE_PERIOD ((g_syshz*SAMPLE_PERIOD_US)/1000000)
//*****************************************************************************
//
// 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);
}


/*void Timerconf(void)
{

    // The Timer0 peripheral must be enabled for use.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
    // Configure Timer0B as a 32-bit periodic timer.
    TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC);
    // Set the Timer0A load value to 1ms.
    TimerLoadSet(TIMER1_BASE, TIMER_A, SAMPLE_PERIOD);

    // Enable triggering
    TimerControlTrigger(TIMER1_BASE, TIMER_A, true);
    }*/
//*****************************************************************************
//
// 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)
{
#if defined(TARGET_IS_TM4C129_RA0) ||                                         \
    defined(TARGET_IS_TM4C129_RA1) ||                                         \
    defined(TARGET_IS_TM4C129_RA2)
    uint32_t ui32SysClock;
#endif

    //
    // 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];
    uint32_t value=0;

    float current = 0;
    float voltage=3.3;
    float power = 0;
    float maxPwr = 0;
    float avgPwr = 0;
    int i = 0;

    //
    // 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.
    //
#if defined(TARGET_IS_TM4C129_RA0) ||                                         \
    defined(TARGET_IS_TM4C129_RA1) ||                                         \
    defined(TARGET_IS_TM4C129_RA2)
    ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                       SYSCTL_OSC_MAIN |
                                       SYSCTL_USE_PLL |
                                       SYSCTL_CFG_VCO_480), 20000000);
#else
    SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
                   SYSCTL_XTAL_16MHZ);
#endif

    uint32_t g_syshz;


    g_syshz =  SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                                 SYSCTL_OSC_MAIN |
                                                 SYSCTL_USE_PLL |
                                                 SYSCTL_CFG_VCO_480),
                                                 120000000L);



    // 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();
    //Timerconf();
    //
    // Display the setup on the console.
    //
    UARTprintf("ADC ->\n");
    UARTprintf("  Type: Single Ended\n");
    UARTprintf("  Samples: One\n");
    UARTprintf("  Update Rate: 250ms\n");
    UARTprintf("  Input Pin: AIN0/PE3\n\n");

    /*
     *
     * sETUP FOR THE SWITCH TRIGGER
     *
     */



        // Enable Port J
        //SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ);
        // Delay to let the clock stabilise
       // SysCtlDelay(3);

        /*
        Configure the switch on the left of the launchpad, GPIO_PIN_0 to a input with
        internal pull-up.
      */
      //GPIOPinTypeGPIOInput(GPIO_PORTJ_BASE, GPIO_PIN_0);
      //GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_0, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
      //GPIOIntTypeSet(GPIO_PORTJ_BASE,GPIO_PIN_0,GPIO_FALLING_EDGE);
      //GPIOADCTriggerEnable(GPIO_PORTJ_BASE, GPIO_PIN_0);
        // Make PF4 a trigger for ADC
       // GPIOADCTriggerEnable(GPIO_PORTJ_BASE, GPIO_PIN_0);

    //
    // 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_TIMER , 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);


    /*
     * Timer
     */

    // The Timer1 peripheral must be enabled for use.
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
        // Configure Timer1A as a 32-bit periodic timer.
        TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC);
        // Set the Timer1A load value to 1ms.
        //TimerLoadSet(TIMER1_BASE, TIMER_A, SAMPLE_PERIOD);
#define F_SAMPLE    1000
        TimerLoadSet(TIMER1_BASE, TIMER_A, SysCtlClockGet()/F_SAMPLE );
        // Enable triggering
       // TimerControlTrigger(TIMER1_BASE, TIMER_A, true);
        TimerControlTrigger(TIMER1_BASE, TIMER_A, true );






    IntMasterEnable();

        //Enable ADC interrupt
     ADCIntEnable(ADC0_BASE, 3);

        //enable the ADC0 Sequencer 3 Interrupt in the NVIC
    IntEnable(INT_ADC0SS3);
    // Sample AIN0 forever.  Display the value on the console.

    // Enable Timer1A.
    TimerEnable(TIMER1_BASE, TIMER_A);

   while(1)
    {
        //
        // Trigger the ADC conversion.
        //
       //ADCProcessorTrigger(ADC0_BASE, 3);

      // value = GPIOPinRead(GPIO_PORTJ_BASE, GPIO_PIN_0);

    // If PF4 is pressed, trigger ADC conversion
      // if(( value & GPIO_PIN_0 )==0) {

        //
        // Wait for conversion to be completed.
        //
       // while(!ADCIntStatus(ADC0_BASE, 3, false))

            while(!g_bIntFlag)
        {
        }

        //

        // Clear the ADC interrupt flag.
        //
        ADCIntClear(ADC0_BASE, 3);

        //
        // Read ADC Value.
        //
       /* ADCSequenceDataGet(ADC0_BASE, 3, pui32ADC0Value);
        current = (0.3/4096)*pui32ADC0Value[0];

        power = current * voltage;
        i++;

               // avgPwr = avgPwr * (i-1)/i + (power/i);
        avgPwr = avgPwr * (i-1)/i + (power/i);
               // i++;

        if(power > maxPwr) maxPwr = power;
*/
        //
        // Display the AIN0 (PE3) digital value on the console.
        //
      UARTprintf("ADC sensed data = %4d\r", pui32ADC0Value[0]);

      char pcCurrentBuf[12];
    

          //
          // Convert floating point members of the struct into strings.
          //
          uftostr(pcCurrentBuf, 12, 3, current);
        

          //
          // Print current with three digits of decimal precision.
          //
          UARTprintf("Current measured:\t\t%s\t", pcCurrentBuf);

          //
          // Print Humidity with three digits of decimal precision.
          //
      //    UARTprintf("Humidity:\t%s\n", pcHumidityBuf);


        // This function provides a means of generating a constant length
        // delay.  The function delay (in cycles) = 3 * parameter.  Delay
        // 250ms arbitrarily.
        //Q
#if defined(TARGET_IS_TM4C129_RA0) ||                                         \
    defined(TARGET_IS_TM4C129_RA1) ||                                         \
    defined(TARGET_IS_TM4C129_RA2)
        SysCtlDelay(ui32SysClock / 12);
#else
        SysCtlDelay(SysCtlClockGet() / 12);
#endif
       //}
    }
}


void ADC0SS3_HANDLER(void)
{
   //unit32_t adcResult = 0;

    //adcResult= ADCSequenceDataGet(ADC0_BASE, 3, pui32ADC0Value1);

    ADCIntClear(ADC0_BASE, 3);
    // Read ADC Value.
    ADCSequenceDataGet(ADC0_BASE, 3, pui32ADC0Value);
    ADCSequenceDataGet(ADC0_BASE, 3, pui32ADC0Value);
            current = (3.3/4096)*pui32ADC0Value[0];

            power = current * voltage;
            i++;

                   // avgPwr = avgPwr * (i-1)/i + (power/i);
            avgPwr = avgPwr * (i-1)/i + (power/i);
                   // i++;

            if(power > maxPwr) maxPwr = power;
   // current = (3.3/4096)*pui32ADC0Value[0];
    g_bIntFlag = true;

}