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.
Tool/software: Code Composer Studio
Hey people
I am trying to connect my U-blox Neo6M GPS sensor to EK-TM4C123GXL launchpad. My connections are below;
GPS Tx -> TM4C PC4
TM4C Debug USB -> PC
I am trying to read GPS data afrom Uart 4 (PC4-PC5) and without even touching it, directly passing to PC via UART0 and usb cable. To be safe, I based my source code on uart_echo example. And kinda tried to do everything that is done for UART0 for UART4 too(copied function calls with parameters changed to UART4 related ones).
My source code is below
#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" #ifdef DEBUG void __error__(char *pcFilename, uint32_t ui32Line) { } #endif void UARTIntHandler(void) { uint32_t ui32Status0; uint32_t ui32Status1; ui32Status0 = ROM_UARTIntStatus(UART0_BASE, true); ROM_UARTIntClear(UART0_BASE, ui32Status0); ui32Status1 = ROM_UARTIntStatus(UART4_BASE, true); ROM_UARTIntClear(UART4_BASE, ui32Status1); while(ROM_UARTCharsAvail(UART4_BASE)) { ROM_UARTCharPutNonBlocking(UART0_BASE,ROM_UARTCharGetNonBlocking(UART4_BASE)); } } void UARTSend(const uint8_t *pui8Buffer, uint32_t ui32Count) { while(ui32Count--) { ROM_UARTCharPutNonBlocking(UART0_BASE, *pui8Buffer++); } } int main(void) { ROM_FPUEnable(); ROM_FPULazyStackingEnable(); ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); ROM_IntMasterEnable(); GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); GPIOPinConfigure(GPIO_PC4_U4RX); GPIOPinConfigure(GPIO_PC5_U4TX); ROM_GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5); ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE)); ROM_UARTConfigSetExpClk(UART4_BASE, ROM_SysCtlClockGet(), 9600, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE)); ROM_IntEnable(INT_UART0); ROM_UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT); ROM_IntEnable(INT_UART4); ROM_UARTIntEnable(UART4_BASE, UART_INT_RX | UART_INT_RT); UARTSend((uint8_t *)"\033[2JEnter text: ", 16); while(1) { } }
When I debug the code, and after a while pausing, it stops at FaultISR function's infinite loop.
I might be doing some fundamental mistake as all UARTs might not be exactly same, maybe I do need another circuitry like MAX3232. Can you help me about this problem?
Note: I can test uart_echo example binary on my TM4C so at least UART0 works properly.
Data sheet for GPS is : www.u-blox.com/.../NEO-6_DataSheet_(GPS.G6-HW-09005).pdf
Hello,
To add to Bruno's excellent advice and going along with his point of there being two UART's configured, it looks like there is no call to enable the UART0 peripheral:
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
I see the above calls, but none for SYSCTL_PERIPH_UART0. You should definitely include that if you are using UART0 for something beyond your GPS, or remove all lines concerning UART0 if it ins't really being put to use.
FYI the startup file Bruno is referring to is the startup_ccs.c file.
Also for FaultISR issues, if the above advice doesn't resolve it, I'd also recommend reading: http://www.ti.com/lit/an/spma043/spma043.pdf
May I too acknowledge the value of Bruno's finding - yet the dominant issue DOES Appear to be the absence of, "UART0's being enabled."
Yet - might other elements of user's code demand review? Specifically: (see Highlights)
void
UARTIntHandler(void)
{
uint32_t ui32Status0;
uint32_t ui32Status1;
ui32Status0 = ROM_UARTIntStatus(UART0_BASE, true);
ROM_UARTIntClear(UART0_BASE, ui32Status0);
ui32Status1 = ROM_UARTIntStatus(UART4_BASE, true);
ROM_UARTIntClear(UART4_BASE, ui32Status1);
while(ROM_UARTCharsAvail(UART4_BASE))
{
ROM_UARTCharPutNonBlocking(UART0_BASE,ROM_UARTCharGetNonBlocking(UART4_BASE));
}
}
Are those TWO "ROM_UARTIntClear()s" - both implemented (and both always executed) w/in a single UART Interrupt - yet generated by ONLY ONE UART - likely to, "Cause a Fault?" (alternatively worded - may an "unneeded" ROM_UARTIntClear() be issued - without causing harm? Past MCU's "errored" when such was detected.)
Your insider info is sure to prove helpful as regards such detail. Poster's (apparent) use of a single interrupt - in service of two UARTs - registers (also) as unusual - I'm reluctant to "bless that as a general method" - for "Just the weakness" (potentially) herein identified..."
Thanks your time & attention...
Hello Bruno,
Others here too - may (often) attempt to provide, "General Solution Methods" - even on occasion - ranging beyond the "MCU Alone" limitation - so often "on display here" - and true too @ most any MCU-centric forum.
As to "some" - "some" (may) suggest "little" (as you hint) but in fact - proves broader - and is often used "legally" - due to its (deliberate) lack of specificity... Note too - that in my "Tag's context" - the use of "A LOT of care" would NOT have, "served as well..."
Bruno Saraiva said:I understand you are using the USB "virtual" serial port emulated by the launchpad, correct?
Bruno Saraiva said:Apparently, when your UART4 receives a byte, there is no defined function to be called, and the code execution goes to the default ISR.
Bruno Saraiva said:In that case, you shall not configure interrupts for bytes arriving at port 0.
Thanks to everyone for valuable suggestion. Now I can read GPS data to TM4C and send it to PC from TM4C. I rearranged source code and removed unnecessary parts(imho).
#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" #include "stdio.h" #ifdef DEBUG void __error__(char *pcFilename, uint32_t ui32Line) { } #endif // Handler function of interrupts on UART4 // Configuration is done in startup_ccs.c file // Vector table definition in startup_ccs.c as /*...*/ /* UART4IntHandler, // UART4 Rx and Tx */ /*...*/ void UART4IntHandler(void) { // Clear interrupts on UART4 uint32_t ui32Status; ui32Status = ROM_UARTIntStatus(UART4_BASE, true); ROM_UARTIntClear(UART4_BASE, ui32Status); // Turn on the led at the start of reading GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2); while(ROM_UARTCharsAvail(UART4_BASE)) { // Write GPS data(that is read from UART4) to UART0 ROM_UARTCharPutNonBlocking(UART0_BASE, ROM_UARTCharGetNonBlocking(UART4_BASE)); } //Turn off the led at the end of reading GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0); } int main(void) { // Enable lazy stacking for interrupt handlers. ROM_FPUEnable(); ROM_FPULazyStackingEnable(); // Set the clocking to run directly from the crystal. ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); // Enable the peripherals used: // Port C Pins will be used as UART4 ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); // Port F will be used for on-board led ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); // Port A pins will be used as UART0(Virtual serial connection-debug) ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // Enable processor interrupts. ROM_IntMasterEnable(); // Set PC4 as UART4 RX GPIOPinConfigure(GPIO_PC4_U4RX); ROM_GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4); // Set GPIO A1 as UART0 Tx(Transmit) GPIOPinConfigure(GPIO_PA1_U0TX); ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_1); // Configure the UART0 for 115,200, 8-N-1 operation. // This is the serial connection between TM4C and PC ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE)); // Configure the UART0 for 115,200, 8-N-1 operation. // This is the serial connection between TM4C and PC ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2); // Configure the UART for 9600, 8-N-1 operation. GPS module provides data in 9600 bps // This is the connection between GPS Module(U-blox NEO6M) ROM_UARTConfigSetExpClk(UART4_BASE, ROM_SysCtlClockGet(), 9600, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE)); // Enable the UART4 interrupt. Other interrupts are not needed since // we do not expect anything from PC, it is used for displaying GPS data ROM_IntEnable(INT_UART4); ROM_UARTIntEnable(UART4_BASE, UART_INT_RX | UART_INT_RT); while(1) { } }
I also changed default Interrupt handler of UART4 to UART4Handler function in startup_ccs . But I will not include that file just for one line change. After making GPS ground and Vcc connection, connection GPS Tx pin to TM4C123GXL PC4 pin. Then connect TM4C to PC through debug port(UART0). Load the software and watch the values in Putty or similar software.
Always good to note, "Poster Success" - and especially your detailed code listing - sure to prove helpful to many.
All helpers "missed" the necessity to, "insure that a common Gnd exists" between external device (GPS here) and your MCU.
Long term - depending upon the current requirement of that GPS - you may benefit from a higher output power source...
Even longer term - you may consider, "Use of a serial-driven, small/portable Display" - freeing you from any, "PC tether." (more standard "parallel Lcd" may also be used - yet requires more MCU pins & altered program code...)
Bruno Saraiva said:Fellow freshmen, when debugging early stage code, turn off all optimizations, and run code step-by-step until the fault!
No, I would advise against this route. It will hide faults that you really need to see and track down. And by doing so it will falsely lead you to belive you have found compiler bugs.
Robert
Robert,
I disagree on this one.
Debugging is a tool that servers all level of developers and tasks. When you use the step-by-step debugger, optimizations most of the time change the execution sequence and "hide your logical line".
Let's say for example that a "fresh" programmer has to transpose 8 bytes. You want to convert an array of 8 uint8_t that contains
00001111
00001111
00111111
11111111
11111111
00111111
00001111
00001111
To an array in which each byte contains the nth bit of the original variables:
00011000
00011000
00111100
00111100
11111111
11111111
11111111
11111111
One is likely to use a function with two nested loops. On my early days, this used to be the typical exercise that would so much benefit from debugging. It was fun and useful to see step by step values of the variables, and so on.
If you compile this kind of stuff optimized, the "natural expected flow" gets totally gone. It becomes impossible to make proper use of the debugger. Hence, if the programmer messed up a little something (maybe started in index 1 instead of 0, or limited the counter to 8 instead of 7, those typical C traps), he won't understand at all what is going on.
If I ever find a piece of code that serves as a proof of concept, I'll remember to come back here. But this is no "competition" nor a trial, just an exchange of experiences. And I stick to my suggestion: it is very useful to turn off optimizations, and test small functions with the debugger. Once happy with the result, maybe it is a good practice to run the code again to the desired optimization, and check for unexpected errors - which will then need to be addressed with some "further experience".
This particularly applies to the level of OP, who is still not that comfortable to immediately understand different UARTs in one program.
Regards
Bruno
Bruno Saraiva said:But this is no "competition" not a trial
So - the fact that, "Judge, Jury, Trial Lawyers, Uncomfortable Bench Seating" all "are present" ... means nothing! Did not Brazil's school system teach: "If it walks, looks, and quacks like a duck - then it IS a duck!" Or TRIAL - as in this case...
You are aware that, "only certain "optimizations" - cause the condition you present - are you not? Discard of ALL optimization benefits may prove, "Hard to justify!"
We WERE WARNED - "Judge Robert" is a "Hanging Judge!" (best to stay on his good side...)