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.

TIVA UART IRDA between two TM4C boards.

Good Morning, I am attempting to communicate with two TIVA C series boards over UART. This will be done via an infrared transmitter and thus I need to use UART IRDA. I've been able to use the built in examples to display UART over the debug perspective into a terminal window. I've also tested the TX plated hole on the board with an oscilloscope to see my data bits of an ASCII character. However, I am having a hard time understanding/incorporating the necessary code for TX on TIVA#1 to transmit to RX of TIVA#2 in general(physical link) and also over infrared.

Can you please point me in the right direction in terms of what I should be aware of and how I can get started?

Thank you

  • Hello Erik,

    The configuration of the UART for TX is the same as the configuration of UART for RX. What is different is the manner in which you shall be reading the bits v/s writing the bits.

    What is the procedure you are using on the TX and RX side for the data?

    Regards
    Amit
  • Thank you for the reply. At the current time, I have implemented a slight modification to the uart_echo example. This modification was to output a single character in a slow loop to be seen by the oscilloscope on TX.

    I would first like to loop back to RX and then display it. I'm just not sure how it can be displayed or handled.

    Second I would like to transmit TX to RX from one board to the second and then again I'm not sure how it would be displayed/handled on the second board. 

    For both cases I assume my code to output to TX will be fine. I am just unsure if I have to use UART1 instead of UART0.

    Once I have that working I will need to handle things via the UART IRDA protocol.

    I understand I am missing a lot of the key concepts, but I am hoping to gain the information necessary to build that skill set.

    Thank you!

    #include <stdint.h>

    #include <stdbool.h>

    #include "inc/hw_ints.h"

    #include "inc/hw_memmap.h"

    #include "driverlib/debug.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"

    int

    main(void)

    {

        //

        // Enable lazy stacking for interrupt handlers.  This allows floating-point

        // instructions to be used within interrupt handlers, but at the expense of

        // extra stack usage.

        //

        ROM_FPUEnable();

        ROM_FPULazyStackingEnable();

        //

        // Set the clocking to run directly from the crystal.

        ROM_SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |

                               SYSCTL_XTAL_16MHZ);

        // Enable the peripherals used by this example.

        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

        // Enable processor interrupts.

        ROM_IntMasterEnable();

        // Set GPIO A0 and A1 as UART pins.

        GPIOPinConfigure(GPIO_PA0_U0RX);

        GPIOPinConfigure(GPIO_PA1_U0TX);

        ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

        // Configure the UART for 115,200, 8-N-1 operation.

        ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 9600,

                                (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |

                                 UART_CONFIG_PAR_NONE));

        //

        // Enable the UART interrupt.

        ROM_IntEnable(INT_UART0);

        ROM_UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);

        // Loop forever echoing data through the UART.

        while(1)

        {

        SysCtlDelay(20000000);

        UARTCharPut(UART0_BASE, 'E');

        }

    }

    #include <stdint.h>#include <stdbool.h>#include "inc/hw_ints.h"#include "inc/hw_memmap.h"#include "driverlib/debug.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"

  • Hello Erik

    You can use UART1 to perform the TX and RX on the same micro or between micro. The Micro which works as the RX shall then send what it received on UART0 to a Serial Console Application.

    Regards
    Amit
  • Thank you for the help Amit. Every bit of info helps.
    I will attempt to enable UART1 for my TX and then loop back around to RX. Once received on RX, it then needs to be sent to UART0? Or does UART0 automatically pick it up?


    For TX I will expect to use these:
    UARTSpaceAvail
    Checks whether there is space available in the transmit buffer.
    UARTCharPut
    Puts a character in the transmit buffer if there is space available. If there is no space available, it
    blocks until there is.


    On RX I anticipate I will need to use a combination of these:
    UARTCharsAvail
    Returns the number of characters in the receive buffer.
    UARTCharGet
    Returns a character if there is one available in the receive buffer. If there is no character available, it
    blocks until there is

    From UARTCharGet with UART1, how should I send the data to UART0? With another put and get??

    Note: I have also tried PB0 and PB1 previously and read nothing on an oscilloscope. I have found rumblings that there is a locked pin involved, is this true? The searches I have done on this forum show a number of replies, but none of them are visible.

    Thank you for your assistance! I would like to be transmitting physically between boards ASAP.
  • Hello Erik,

    1. UART0 will not automatically pick it up, You can use UARTprintf to print the received data from UART1. This API comes from the utils/uartstdio.c library file.
    2. PB0 and PB1 are not locked. The example code you have pasted is what needs to be updated for PB0, PB1 and UART1.

    Regards
    Amit
  • Fantastic. I began setting up uartprintf as you recommended. Since I am passing a character to UART1, would I do uartprintf(\%c); where \%c to print a character?

    Additionally, if I use UARTCharGet it blocks until there is another character. But if the code is blocking, it is not moving to the next instruction of sending another character. How can I fix this?

    Thanks so so so much!
  • I was half asleep when I sent that last message, obviously uartprintf(\%c) is not going to do anything, without setting the argument of what the character is. Is it possible to call UARTCharGet within the printf statement or should I use a variable to pass between the two.

    Regardless, my goal is to eventually pass data from the onboard temperature sensor between the two boards. Uartprintf is not going to handle that data, nor will UARTCharGet or Put. Once I am able to receive on TX(still struggling) I'd like to discuss how I could then get that data into EEPROM. I completed the EEPROM tutorial which seemed pretty straight forward. But what other command will I need to use to pass basic 8 bits of data, not limited to a character.

  • Hello Erik

    I would suggest first specifying the system specification. It looks like EEPROM just came up from nowhere!!! What are you building?

    Regards
    Amit
  • Hello,

    Simply a system of reading the temperature sensor of one board, and transmitting it via UART to the other board which will display it in terminal. EEPROM was something that popped in my head as I worked thru the TI workshop labs but can be forgotten for now. I thought it might be useful.

    So I plan on using UART1 from TX of Tiva #2 to UART1 of Tiva #1 which will then display it via UART0 as you mentioned above. I would like to get that working with a single ascii character in a while loop first. Then I will need to store the data and transmit it in the same fashion. Communication in reverse might also be used in reverse to set sampling rates, etc.

    But I can't get the basics working so I guess that is a good place to start with and work through with your help.

    Also, I have read that I may need to tweak the vector table in order to use UART1. This is untrue, correct?

    Thank you

  • Hello Erik,

    You can use UARTprintf as UARTprintf("%c",ucVarName) where ucVarName is the variable that will contain the value.

    Regards
    Amit
  • The lightbulb finally clicked and using your suggestions I was able to get a physical link sent up from Board#1(UART0 TX) to Board#2(UART1 RX). This was usable for passing a character.

    Now I have two branches/questions to figure out.

    The first is that I want to implement an infrared transceiver. I need to use irda with UART. Can you point me in the right direction of modifying my code?

    ******************I unncomment the put/get beneath so that I can program either board quickly.

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"

    int main(void) {

    char charholder;

    //Set CPU Clock to 40MHz. 400MHz PLL/2 = 200 DIV 5 = 40MHz
    SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

    //LED GPIO - enables port, sets pins 1-3 (RGB) pins for output
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    GPIOPinConfigure(GPIO_PB0_U1RX);
    GPIOPinConfigure(GPIO_PB1_U1TX);
    GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(), 9600,
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

    while (1)
    {
    // Ensure LED is off
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00);
    SysCtlDelay(2000000);
    // Turn on the LED
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2,4);


    //UARTCharPut(UART0_BASE, 'E');

    //#### To be used for Loop back communication or Data Collector
    if(UARTCharsAvail(UART1_BASE)){
    charholder = UARTCharGet(UART1_BASE);
    }

    //Delay slightly
    SysCtlDelay(2000000);

    //#### To be used for Loop back communication or Data Collector
    UARTCharPut(UART1_BASE, charholder);
    }

    }


    My second question is once the infrared link works...I need to be able to send raw data from the temp sensor. Obviously UART is built to transmit/receive characters and strings. I've read that I can convert my raw data to strings and then reverse the process on the receiving end. Is this the best approach? Regardless, could you also give me some tips/direction of how to proceed with raw data(sampling the onboard temp sensor).

    Thank you
  • Hello Erik,

    Add the API UARTEnableSIR to enable the IR mode.

    The char and string is just interpreted form of the data. You can use the RAW data using UARTCharGet and UARTCharPut.

    Regards
    Amit
  • As always, thank you for the help. That will prove useful shortly.

    Before I change from a physical link to an infrared link, I've tried incorporate the temperature sensor to my code. I am in fact getting data transmission from TX to an oscilliscope. I just can't confirm that the data is correct. I tried to use uartprintf as you suggested but I can't view anything through putty.

    Could you see if I have made use of ui32TempValueF correctly with both UARTCharPut and also with UARTprintf? I really appreciate your continued support! It feels good to finally be making some progress. One note is that I do in fact have my includes directory>tivaware>utils>uartstdio.c, but the only way to bypass errors was to include it in the program. I also included the .h but I don't think that is necessary.

    *Is it possible to view the temperature sensor through my expressions as previously done in lab? It seemed to only work when I was within a while loop. I also tried the breakpoint within the code below and got no success.

    **As I type this I also made the slight realization that I am working with UART0. If uartprintf only works to move UART1 to UART0 for display then obviously it won't work properly right now. However, I'd like to still know if I am using it correctly, and if my thoughts are also correct.

    ***I did try both %i and %d to work with the farenheit variable.


    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    #include "utils/uartstdio.c"

    #include "driverlib/debug.h"

    #include "driverlib/adc.h"

    int main(void) {

    //char charholder;

    uint32_t ui32ADC0Value[4];
    volatile uint32_t ui32TempAvg;
    volatile uint32_t ui32TempValueC;
    volatile uint32_t ui32TempValueF;

    //Set CPU Clock to 40MHz. 400MHz PLL/2 = 200 DIV 5 = 40MHz
    SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);


    //LED GPIO - enables port, sets pins 1-3 (RGB) pins for output
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);

    //Enables UART0 for transmission. ("see" Data Collector)
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //Configure the pins, uh..., plated holes for UART0
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //Set the baud rate, 8 data bits, one stop bit and no parity for UART0
    UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 9600,
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));


    //Enable the analog to digital converter. ADC0
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

    ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_TS);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_TS);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_TS);
    ADCSequenceStepConfigure(ADC0_BASE,1,3,ADC_CTL_TS|ADC_CTL_IE|ADC_CTL_END);
    ADCSequenceEnable(ADC0_BASE, 1);

    //while(1)
    //{
    // Ensure LED is off
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00);
    // SysCtlDelay(2000000);
    ADCIntClear(ADC0_BASE, 1);
    ADCProcessorTrigger(ADC0_BASE, 1);

    while(!ADCIntStatus(ADC0_BASE, 1, false))
    {
    }

    ADCSequenceDataGet(ADC0_BASE, 1, ui32ADC0Value);
    ui32TempAvg = (ui32ADC0Value[0] + ui32ADC0Value[1] + ui32ADC0Value[2] + ui32ADC0Value[3] + 2)/4;
    ui32TempValueC = (1475 - ((2475 * ui32TempAvg)) / 4096)/10;
    ui32TempValueF = ((ui32TempValueC * 9) + 160) / 5;

    //Put the farenheit value into UART for transmission
    UARTCharPut(UART0_BASE, ui32TempValueF);
    // Turn on the LED
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2,4);
    UARTprintf("%d", ui32TempValueF);
    // Ensure LED is off
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00);
    //}

    }

  • Hello Erik

    Look at the Temp Sensor example code in D:\ti\TivaWare_C_Series-2.1.1.71\examples\peripherals\adc

    It does the same as what you are doing. My suggestion is to first run a hello program example to make sure PuTTy is configured correctly and working before trying your code.

    Regards
    Amit
  • With your help, I have continued to make progress on my system. This question should be relatively easy and I'm hoping you can assist. I have code working in order to sample the temperature sensor and save the data(temperature in farenheit) into a variable. I then use UARTCharPut calling this variable. If I transmit on UART0, I can receive on UART1 on the same board by adding a UARTCharGet and storing this into a separate variable. From there, I can use UARTprintf and display the integer on my console.

    When I try to split the code into two and use two boards, I run into an issue receiving the data. No matter what, UARTCharGet on the second board will not populate its variable and when UARTprintf is called, garbage prints. From my understanding, UARTCharGet should block until there is actual data in the UART but this does not seem to occur. 

    Either way, how should the two programs be modified so that UARTCharPut(UART1...from board#1) will successfully transmit to UARTCharGet(UART1...from board#2)?

    I appreciate all of the help I have received thus far!

  • Hello Erik,

    The first thing that needs to be made sure that the data being sent is correctly received. For this the clock source for the two boards and baud rates of the two UARTs must be identical. Send a known golden value from the transmitted and see that it appears on the data line. Then check in the second board as to what is being received for the known golden value.

    Regards
    Amit
  • Hello,
    Both boards are set with the following:
    //Set CPU Clock to 40MHz. 400MHz PLL/2 = 200 DIV 5 = 40MHz
    SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);

    // Initialize the UART for console I/O. on UART0/BASE0
    UARTStdioConfig(0, 9600, 16000000);

    //Set the baud rate, 8 data bits, one stop bit and no parity for UART0
    UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 9600,
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

    //UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(), 9600,
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

    I am unable to use the golden value idea as I receive nothing over the link, not even garbage.

    Thank you for the speedy response!
  • Hello Erik

    As an example the golden value can be 0x32 which in ASCII is numerical "2".

    Also why are you configuring UART0 twice? And that to with different clock values "16000000" and "SysCtlClockGet()"

    // Initialize the UART for console I/O. on UART0/BASE0
    UARTStdioConfig(0, 9600, 16000000);

    //Set the baud rate, 8 data bits, one stop bit and no parity for UART0
    UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 9600,
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

    Regards
    Amit
  • Good Evening,

    For whatever reason UARTStdioconfig made it's way in when I was trying to get my code working. I misunderstood it's use in that I thought it was needed for the console. Thank you for pointing it out, I will go ahead and remove it and report back my findings once I have the two boards set up with the modification.

    Thank you!
  • I have finally found time to work some on this project. I began the day by removing the uartstdioconfig and quickly realized that it breaks my console use completely. If I remove that code I cannot display data at all.

    At the end of the day today I took out the sysctlclockset and my program continues to run fine.

    Would you be able to explain the differences and why I need to use uartstdioconfig over sysctlclockset(which is what I thought I needed from the tutorials)?

    I will try sending a golden value over a physical link between the two boards tonight and reply with any difficulties that I face.

    Thanks so much

  • Hello Erik,

    The 3rd parameter for UARTStdioConfig is the system clock. If you hard code the value then you need to be sure that the hard coded value is the system clock. Better way of doing it is to use the return value from SysCtlClockGet.

    Regards
    Amit
  • I made the change as you suggested. My 3rd parameter is now SysCtlClockGet(). How can I confirm what the system clock will return? Or do i need to keep SysCtlClockSet as I had previously...to control it.

    I previously had 16000000 and now the program runs much more slowly.

    In regards to linking the two boards, I am still having a difficulty receiving the proper data. Some functionality DOES exist, such that when I press the refresh button on board#1 it sits and waits at UARTCharGet. When I then press the refresh button on board#2(which transmits a golden value of 4) the first board senses it and runs through my uartprintf. However, what is printed on screen is 1280...not 4. This 1280 appears ALL the time, no matter if I am sending actual temperature data or test values.

    I am unsure how to attach files, so I am going to paste my two sets of code. The first will be the board that transmits temperature. The second will be the board that receives it and displays it. Please let me know if you see any additional errors aside from what we discussed. I know this might be time consuming for you but I truly appreciate any help you can provide. There is some extra comments that I have been moving in and out for testing, please ignore.



    ###Transmitter:
    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    #include "utils/uartstdio.c"

    #include "driverlib/debug.h"

    #include "driverlib/adc.h"

    int main(void) {

    //char charholder;

    uint32_t ui32ADC0Value[4];
    volatile uint32_t ui32TempAvg;
    volatile uint32_t ui32TempValueC;
    volatile uint32_t ui32TempValueF;
    uint32_t testdata = 4;

    //Set CPU Clock to 40MHz. 400MHz PLL/2 = 200 DIV 5 = 40MHz
    //SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);


    //LED GPIO - enables port, sets pins 1-3 (RGB) pins for output
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);

    //Enables UART0 for console use. ("see" Base Station)
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //Enables UART1 for transmission. ("see" Data Collector)
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    //Configure the pins, uh..., plated holes for UART0
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //Configure the pins for UART1
    GPIOPinConfigure(GPIO_PB0_U1RX);
    GPIOPinConfigure(GPIO_PB1_U1TX);
    GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    // Initialize the UART for console I/O. on UART0/BASE0
    UARTStdioConfig(0, 9600, SysCtlClockGet());

    //Set the baud rate, 8 data bits, one stop bit and no parity for UART0
    UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 9600,
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

    UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(), 9600,
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));


    //Enable the analog to digital converter. ADC0
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

    ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_TS);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_TS);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_TS);
    ADCSequenceStepConfigure(ADC0_BASE,1,3,ADC_CTL_TS|ADC_CTL_IE|ADC_CTL_END);
    ADCSequenceEnable(ADC0_BASE, 1);

    // Ensure LED is off
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00);
    ADCIntClear(ADC0_BASE, 1);
    ADCProcessorTrigger(ADC0_BASE, 1);

    while(!ADCIntStatus(ADC0_BASE, 1, false))
    {
    }

    ADCSequenceDataGet(ADC0_BASE, 1, ui32ADC0Value);
    ui32TempAvg = (ui32ADC0Value[0] + ui32ADC0Value[1] + ui32ADC0Value[2] + ui32ADC0Value[3] + 2)/4;
    ui32TempValueC = (1475 - ((2475 * ui32TempAvg)) / 4096)/10;
    ui32TempValueF = ((ui32TempValueC * 9) + 160) / 5;

    //Turn on Green LED to indicate temperatures are stored
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3,8);
    SysCtlDelay(6000000);

    //Put the farenheit value into UART1 for transmission
    //UARTCharPut(UART1_BASE, ui32TempValueF);
    UARTCharPut(UART1_BASE, testdata);

    // Clear LED
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00);

    //Display the temperatures to the console with UART0
    //UARTprintf("Temperature = %3d*F\n",ui32TempValueF);
    UARTprintf("Temperature = %3d*F\n",testdata);

    //Blink BLUE LED to indicate communication code has passed
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2,4);
    SysCtlDelay(2000000);
    //Turn off LED
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00);
    SysCtlDelay(2000000);
    //Back on
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2,4);
    SysCtlDelay(2000000);
    //Turn OFF LED
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00);



    }


    ##### Read/Display
    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    #include "utils/uartstdio.c"

    #include "driverlib/debug.h"

    #include "driverlib/adc.h"

    int main(void) {

    //volatile uint32_t ui32TempValueF;
    volatile uint32_t bin_num[8];
    uint32_t dec_farenheit;
    uint32_t uart_farenheit = 0;
    int i;

    //Set CPU Clock to 40MHz. 400MHz PLL/2 = 200 DIV 5 = 40MHz
    //SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);


    //LED GPIO - enables port, sets pins 1-3 (RGB) pins for output
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);

    //Enables UART0 for console use. ("see" Base Station)
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //Enables UART1 for transmission. ("see" Data Collector)
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    //Configure the pins, uh..., plated holes for UART0
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //Configure the pins for UART1
    GPIOPinConfigure(GPIO_PB0_U1RX);
    GPIOPinConfigure(GPIO_PB1_U1TX);
    GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    // Initialize the UART for console I/O. on UART0/BASE0
    UARTStdioConfig(0, 9600, SysCtlClockGet());

    //Set the baud rate, 8 data bits, one stop bit and no parity for UART0
    UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 9600,
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

    UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(), 9600,
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

    /*
    UART Communication begins
    */

    //If a value is available in UART, store into temperature variable
    //while(!UARTCharsAvail(UART1_BASE)){
    //UARTprintf("\n");
    //UARTprintf("Nothing in UART yet");
    //SysCtlDelay(9000000);
    //}
    //if(UARTCharsAvail(UART1_BASE)){
    // ui32TempValueF = UARTCharGet(UART1_BASE);
    //}
    uart_farenheit = UARTCharGet(UART1_BASE);
    SysCtlDelay(6000000);
    // Convert Decimal to Binary for console purposes
    dec_farenheit = uart_farenheit;
    i=0;
    while (dec_farenheit) {
    bin_num[i] = dec_farenheit % 2;
    dec_farenheit = dec_farenheit / 2;
    i++;
    }

    //Display the temperatures to the console with UART0
    UARTprintf("Temperature = %3d*F\n",uart_farenheit);
    // Print Binary Number
    UARTprintf("The binary value is: ");
    int j;
    for (j=i-1; j>=0; j-- ) {
    UARTprintf("%d",bin_num[j]);
    }
    //Line feed after outputting to console
    UARTprintf("\n");
    // Clear LED
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00);

    //Blink RED LED to indicate communication code has passed
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1,2);
    SysCtlDelay(2000000);
    //Turn off LED
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00);
    SysCtlDelay(2000000);
    //Back on
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1,2);
    SysCtlDelay(2000000);
    //Turn OFF LED
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00);

    }
  • Hello Erik,

    Yes, SysCtlClockSet has to be kept as is. The use of SysCtlClockGet ensures that the system clock set by the user is used for correctly initializing the peripherals which have counters to be configured.

    Regards
    Amit
  • Good Morning,

    Thank you for the reply. I will insert SysCtlClockSet back into my code. Otherwise, does it look like everything should work? Would the clock be the reason behind the 1280 garbage value that I am getting on the second board?

    Thank you again!

  • Hello Erik

    It may be. Unless the golden value setup is used to check what is being transmitted, is seen on the bus and then seen by the receiver, it cannot be said for sure.

    Regards
    Amit
  • Good Morning,

    I've been trying to debug my ghost value of 1280 on the receiving board's uartfarenheit variable. Using the debugger, I can see that UARCharGet(UART1_BASE) has the memory address of 0x4000D000 with contents of 00000004 and I had use UARTCharPut from the first board to transmit decimal 4. This is my golden value and it appears that communication is working properly on the uart side of things.

    However, when uartfarenheit = UartCharGet(UART1_BASE), uartfarenheit has a value of 1280...when I can see on that line that UART1_BASE has contents of 4. I do not understand what happens at that point. Also, no matter what decimal value I transmit/what UART1_BASE has...uartfarenheit ALWAYS equals 1280. Can I not assign a variable to UartCharGet like that?

    The program sits at the following while loop until the first board puts a decimal value into uart...

        //
        // Wait until a char is available.
        //
        while(HWREG(ui32Base + UART_O_FR) & UART_FR_RXFE)
        {
        }

        //
        // Now get the char.
        //
        return(HWREG(ui32Base + UART_O_DR));

    After this, the program returns to my main code at this line...

        uart_farenheit = UARTCharGet(UART1_BASE); at which UART1_BASE has the value of 4....and uartfarenheit ends up equaling 1280.

    I hope you can provide some guidance on this...

    Thank you!

  • Hello Erik

    1280 decimal is 0x500 which indicates that there is an error in the frame. Note that when reading from the debugger the UARTDR value once read will cause the FIFO to move to the next byte in the FIFO. So first of all close any debug view into the UART registers.

    Secondly, the fact that you see 0x4 (the golden value) would mean that the debugger read is working fine and the debug view is causing the FIFO to move to the next byte which may not be correct.

    Regards
    Amit
  • I've continued work on this project and I have the following dilemma.

    The onboard temperature sensor is stored into a 32 bit variable, but only 12 bits are actually used. I then want to transfer that temperature over UART as I've mentioned throughout this post.

    UART can only handle 8 bits at a time. I've created a mask that stores the lower 8 bits into uartTemp[0] and the next 4 bits into uartTemp[1]. uartTemp is of the type uint8_t array.

    I am able to transmit uartTemp[0] and receive it properly but uartTemp[1] gets lost. I know that it is time for me to use an interrupt.


    I could really use a hand getting the interrupt set up, so that if a new temperature is available on UART it can be received properly. I also need to be concerned with receiving sequential packets(to handle the first 8 bits, and the second 8 bits).

    What would be the best way to accomplish this?


    Likewise, if I sent multiple temperature values back to back, I need a way of knowing what was sent and how to receive/handle it.


    I would appreciate your help in understanding and tackling this issue.



    Also, can you tell me how much current the TM4C123G battery monitoring uses? That'll be for a separate item that I will tackle.

    My code is pasted below:

    Transmitting side:

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    #include "utils/uartstdio.c"
    #include "driverlib/debug.h"
    #include "driverlib/adc.h"

    int main(void) {

        uint32_t ui32ADC0Value[4];
        volatile uint32_t ui32TempAvg;
        volatile uint32_t ui32TempValueC;
        volatile uint32_t ui32TempValueF;
        uint32_t testdata = 4095; //00000000000000000000111111111111
        int lowEight = 0b00000000000000000000000011111111;  //Mask the lower 8 bits
        int middleFour = 0b0000000000000000000111100000000; //Mask bits 12downto8
        uint8_t uartTemp[2] = {0};     //uint8_t uartTemp[2] to manipulate 32 bits

        //Set CPU Clock to 40MHz. 400MHz PLL/2 = 200 DIV 5 = 40MHz
        SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);

        //Enables UART1 for transmission. ("see" Data Collector)
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

        //Configure the pins for UART1
        GPIOPinConfigure(GPIO_PB0_U1RX);
        GPIOPinConfigure(GPIO_PB1_U1TX);
        GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);

        //Initialize the UART for console I/O. on UART0/BASE0
        UARTStdioConfig(0, 9600, SysCtlClockGet());

        //Set the baud rate, 8 data bits, one stop bit and no parity for UART0
        UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 9600,
            (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

        UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(), 9600,
            (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));


        uartTemp[0] = testdata & lowEight;
        uartTemp[1] = (testdata    & middleFour)>>8;
        SysCtlDelay(6000000);
        UARTCharPut(UART1_BASE, uartTemp[0]);
        UARTCharPut(UART1_BASE, uartTemp[1]);
    }

    The Receiving side:

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    #include "utils/uartstdio.c"
    #include "driverlib/debug.h"
    #include "driverlib/adc.h"

    int main(void) {
        uint8_t uartTemp[2] = {0};

        //Set CPU Clock to 40MHz. 400MHz PLL/2 = 200 DIV 5 = 40MHz
        SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);

        //Enables UART1 for transmission. ("see" Data Collector)
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

        //Configure the pins for UART1
        GPIOPinConfigure(GPIO_PB0_U1RX);
        GPIOPinConfigure(GPIO_PB1_U1TX);
        GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);

        UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(), 9600,
            (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

        /*
        UART Communication begins
        */

        uartTemp[0] = UARTCharGet(UART1_BASE);
        SysCtlDelay(6000000);
        uartTemp[1] = UARTCharGet(UART1_BASE);
        SysCtlDelay(6000000);
        UARTprintf("Temp 0 is " + uartTemp[0]);
        UARTprintf("Temp 1 is " + uartTemp[1]);
        uint32_t concatTemp;
        concatTemp = uartTemp[1] + uartTemp[0];

    }

  • I was digging through the data sheet and came across information about DMA in regards to the UART interrupt. Is this something that I need to be concerned with regarding my situation?

    I figure I will need to use a FIFO buffer to handle my data bits and I found this section regarding DMA:

     When DMA operation is enabled, the UART asserts a DMA request on
    the receive or transmit channel when the associated FIFO can transfer data. For the receive channel,
    a single transfer request is asserted whenever any data is in the receive FIFO. A burst transfer
    request is asserted whenever the amount of data in the receive FIFO is at or above the FIFO trigger
    level configured in the
    UARTIFLS
    register. For the transmit channel, a single transfer request is
    asserted whenever there is at least one empty location in the transmit FIFO. The burst request is
    asserted whenever the transmit FIFO contains fewer characters than the FIFO trigger level. The
    single and burst DMA transfer requests are handled automatically by the μDMA controller depending
    on how the DMA channel is configured.


    I guess my question is whether or not I can obtain FIFO status without DMA.


    Thank you! I will include any other questions I have as I formulate my thoughts on this topic.