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.

UART Problem on LM4F232H5QD aka. TM4C123GH6PM

Hello TI E2E Community!

Since this is my first post on this forum, please don't be mad for possible missing information and just ask!

My problem is, that I'm using the TM4C123GH6PMs UART0 and UART4 to have a connection to a bluetooth module and a PC, but im struggling to send/receive data.

My code is the following (for UART4):

 const int idelay = 1000;        //for delay

 unsigned long int* RCGCUART;    //address of Rcgcuart
 unsigned long int* RCGCGPIO;    //..
 unsigned long int* GPIOAFSEL;   //..
 unsigned long int* GPIOPCTL;    //..
 unsigned long int* UARTCTL;     //..
 unsigned long int* UARTIBRD;    //..
 unsigned long int* UARTFBRD;    //..
 unsigned long int* UARTLCRH;    //..
 unsigned long int* PPUART;      //..

//1.Enable UART via RCGCUART Register page 333
//Base address 0x400F.E000 is a System Control Register as seen on page 97
//Offset address 0x618 Adress for the RCGCUART Register
//Addition gives the adresse: 0x400F.E618
//to set the UART4 the fifth Bit must be set.
RCGCUART = 0x400FE618;
//*RCGCUART &= 0xEF; // Disable UART4
*RCGCUART |= 0x10; //Enable UART4
delay_ms(idelay);

//2.Enable the clock to the appropiate GPIO module via RCGCGPIO page 328
//The Base address is 0x400F.E000
//The offset address is 0x608
//That gives: 0x400F.E608
//PORTC is the third Bit so : 0x4 = 0b100
RCGCGPIO = 0x400FE608;
*RCGCGPIO |= 0x4;
delay_ms(idelay);

//3.Setting the GPIO AFSEL for the appropiate PINs
//GPIO PORTC APB Base is on 0x4000.6000
//Offset is 0x420 -> that gives in total 0x4000.6420
//PORTC4/5 Uart4 is on Pin 36/35
GPIOAFSEL = 0x40006420;
*GPIOAFSEL |= 0x30;
delay_ms(idelay);

//4.Configure Current level and slew rate control
//2mA default
//Slew rate default no slew rate control

//5.Configure PMCn fields in the GPIOPCTL register to asign the UART Signals to the appropiate pin
//Base of the GPIOPCTL register is 0x4000.6000 for PORTC APB
//The offset is 0x52C
//That gives 0x4000652C
//Write the appropiate value for UART4 into the Pin4 and Pin5 fields. Should be 0x2;
GPIOPCTL = 0x4000652C;
*GPIOPCTL |= 0x00110000;
delay_ms(idelay);

//Configuration of the UART:
//1.Disable UART
//Disabling by resetting UARTEN in the UARTCTL register
//Base address is 0x4001.0000
//The offset address is 0x030
//UARTEN is the first Bit
UARTCTL = 0x40010030;
*UARTCTL &= 0xFFFFFFFE;
*UARTCTL |= 0x300;
delay_ms(idelay);
  
//2.BAUDRATE
//BRD = 16000000 / (16 * 115200) = 8,6805°
//UARTFBRD = integer(0,6805 * 64 + 0.5) = 44
//UARTIBRD base is on 0x4001.0000
//and offset is 0x024
//UARTFBRD base is on 0x4001.0000
//and offset is 0x028
UARTIBRD = 0x40010024;
*UARTIBRD |= 0x8;
UARTFBRD = 0x40010028;
*UARTFBRD |= 0x2C;
delay_ms(idelay);
  
//3.data length, parity and stop bit
//This is set in the UARTLCRH register
//The base address is 0x4001.0000
//The offset address is 0x02C
// Bit 5 and 6 are the data length. 0x3 is 8 bits.
// no parity and 1 stop bit default
UARTLCRH = 0x4001002C;
*UARTLCRH |= 0x60; //0b01100000
delay_ms(idelay);
  
//4.Enable the UART4 again
UARTCTL = 0x40010030;
*UARTCTL |= 0x00000001;
delay_ms(idelay);

//Transmit on UARTDR register
//Base address for UART4 0x4001.0000
//offset address is 0x00
unsigned long int* UARTDR = 0x40010000;
*UARTDR |= 0x41;                             //Send Letter A

The sending pin always stays on high (idle) - measured by an oszilloscope.

I also tried to receive, using an interrupt - I get an interrupt, but the Data Register won't change it's state to anything - staying at 0x00000000 all the time!


Really struggling with that, I'd hope someone could help me!

Best regards,

Fabian

  • Hi Fabian,

         The easy way, is to just modify the uart_echo example program and configure it as UART4. See, the Tivaware Peripheral Driver Library Users Guide.

    -kel

  • Most of your "struggle" results from your exclusive use of the far more demanding - and complex - direct register programming method.  Most here benefit from the extensive - far simpler - and vastly more detail/documented, "Peripheral Driver Library User Guide."  (as mentioned by friend Kel)

    Many believe the ARM MCU success of first founding group LMI - and now this vendor - sprang from the completeness & ease of this driver library.  It has long been used by thousands (likely tens of thousands) and has passed the test of time.  (some here have been known to "squawk" upon unsavory code discovery ... but never this reporter...)

    With minimal effort you'll discover an "examples" folder - and under peripherals you'll find multiple UART examples - all pre-coded and "guaranteed."  Your "direct register" method enjoys, "no such - successful passage of time" - instead places great demands upon your mastery of multiple, often complex registers and their inter-relationships.

    Struggle - as you well note - is the "normal/customary" result of avoiding KISS.  (i.e. the freely provided driver library)

    Each/every of your early register defs/declares are managed automatically by the proper use of the driver library.

    I would advise that you not, "start" by trying to communicate w/your RF module.  Simple MCU to PC (Hyper Term or similar) is far easier to get working.  Marrying a new MCU to any RF module is like setting sail when the sky has darkened and white caps foam.  (i.e. smooth/successful voyage possible - but unlikely)  You must insure that you do not expose any MCU pins to RS232 signal levels - low cost boards often neglect this protection.

    It should be noted (and this reporter has too long protested) that the MCU manuals "default" most often (always!) into register code examples - and fail miserably to direct new users to the multiple, eased advantages provided by the driver library... 

  • Firstly, thank you guys for your help, I really appreciate it.

    Since I normally program in assembler I just kinda feel like the "hardware" way is the most offering for me - understanding the registers and the MCU through that.

    But since I'm in a little time problem, I already tried the TivaWare library, but it somehow didn't work with my compiler i think. I always got the massage "Invalid declerator expected'(' or identifier; ''Identifier redefined", "Specifier needed", just by including for example the "uart.h" and "uart.c" (folder structure is same as it's in the zip" (I'm using mikroC Pro - from mikroe.com). I'll have a look at TivaWare again at the weekend, hopefully I'll get it to run - would make things a lot easier ;)

    I'll let you guys know! Thanks for the help!

  • First time attempts most always challenging - know that you are not alone.  Like you - we started w/805x, 68xx, and Z80 - and assembler.  And were overjoyed when C compilers (finally) arrived.  (and pretty much stunk)

    May be easiest if you strictly import & use a sample project from your compiler provider.  Multiple code sources too frequently introduce the issues you report.

    Do spend some time reading the driver library guide - and the many code examples provided w/in Stellaris/rebrandWare.  They work and well illustrate most critical set-ups & configures.

    Bon chance...

  • Hey guys!

    Tried around a bit with TivaWare but I keep getting this:

    Anybody has an idea why? The folder structure is the following: main.c with my includes and in that folder there is "inc" and "driverlib"

    Looking forward to hearing from you!

    Kind regards
    Fabian 

  • Hi,

    Add these two includes at the beginning of main file:

    #include <stdbool.h>
    #include <stdint.h>

    Petrei

  • Hey,

    They are already included (although i had to download "stdbool.h" first... crappy Compiler)

    Fabian

  • Hi Fabian,

    1. Are you using EK-LM4F232?
    2. Have you encountered any compile errors from any example program such as hello example program?
    3. What compiler are you using?
            if you are using the kit, there should be a quickstart doc and readme first doc, that you can use as guide.
    -kel
  • Hey Markel,

    You're right, I'm using the LM4F232, but since it's similar to the TM4C123 it shouldn't be the mistake right?

    The UART Polling Example program gives me the same compiler errors as in my project now.

    I'm using the mikroC compiler (from mikroe.com) ... Unfortunately have to stay on that since i need their display libraries (mikromedia + for stellaris) which aren't open source and can't be included on another compiler....

    Fabian

  • Hey guys!

    I finally fixed the library, it's party working now (the UART part at least): Had to make an own stdbool.h with 

    #define false 0
    #define true 1
    
    #define bool int

    With that .h it worked - but I still had to change some Assembler code (in SysCtlDelay()) since my compiler somehow couldnt work with it.

    Now I'm stuck with the interrupt handling: following (and more errors) in the interrupt.c (hope you can point me in the right direction):

    -Line 184: Specifier needed
    -Line 184: Syntax Error: ')' expected, but "vtable" found
    -Line 288: Undeclared Identifier 'g_pfnRAMVectors' in expression
    -Line 297: Undeclared Identifier 'g_pfnRAMVectors' in expression
    -Line 297: Pointer required

    There are more errors due to undeclared identifier 'g_pfnRAMVectors' in expression, but I'm not gonna cover the lines since I guess it's all fixed as one.

    Hopefully You can tell me what's the problem here!

    Fabian 

  • Hi Fabian,

         Sorry, I am not familiar with mikroC compiler and its project files, to be much help.

          I think it will help, if you learn from the example programs using Keil Uvision or CCS. There are also project options, pre-defines that need to be set, in order for your project to compile without errors.

    -kel

  • @Fabian,

    In interrupt.c there are some defined functions which are dependent on compiler - your is not defined so be carefull. I suggest to try a similarity with gcc. Also for defining interupt vectors in RAM, resulting in a linker section named .vtable, a compiler version must be set - usually the CCS users must predefine a constant "ccs" to work with, check your compiler about its name (or ask the manufacturer about) and simply add it to the source code.

    Petrei

  • As you suggested I'm trying to use some other compiler now but keep failing.

    I installed WinARM and added its compiling files to Codeblocks... Now when i try to build it just gives following errors:
    In function 'exit':
    undefined reference to '_exit'
    In function 'abort':
    undefined reference to '_exit'
    In function '_kill_r':
    undefined reference to '_kill'
    In function '_getpid_r':
    undefined reference to '_getpid'
    In function '_sbrk':
    undefined reference to '_sbrk' 

    I'm really desperate now... Please help me fixing this cr*p.. :S Also I'm curious where the hell i can get the ".vector" from...

    Fabian

  • Hi,

    I did not suggested to replace with GCC, but if you change it with that, it is OK, as long as you use the right version. I used WinARM long time ago (some 6-7 years back), I do not know if it is still active and with all the bells and whistles needed for Tiva/Cortex-M4. (instead look for this: https://launchpad.net/gcc-arm-embedded)

    What you get here seems to be due to some routines outside Tiva, i.e. those needed to use the heap (specific to dynamic allocation, namely malloc). Since you do not need these for Tiva, you may comment/disable them. Should be found in startup files, depends on your project. Check also the linker files, some sections may have different names.

    What I suggested was to check your compiler documentation, should be some info about compiler name (how to get this from your code). Every respectable compiler should have that; just in case you don't find something then ask the company who made it. 

    And read the file interrupt.c, to see where the #defines are placed around the code, seems ignoring this...

    Petrei

  • Hi!

    Kinda felt like you guys were recommending me to use gcc for arm and since the mikroC compiler really grinds my gear I'm willing to change the compiler.

    I tried both WinARM and "gcc arm embedded" - now using the second.

    For my project I made a "Empty Project" - chosing ARM project I have to specify a processor and since i can't find the Cortex M4 in the list I tried with an empty project.
    The errors I get in the file "arm-none-eabi\lib\libc.a(lib_a-exit.o) but I never linked that file and can't find it in any linker list.... :S

    For documentation about mikroC: There isn't a documentation -.-
    http://www.mikroe.com/mikroc/arm/specification/# says: mikroC pro for arm user manual (coming soon!). Yay, thanks for your help mikroe (Wrote them an e-mail about their functions already - answermail didn't have a single answer......) 

  • Hi,

    I understand your pain, but do not blame us/me - do not understand why/how did you got to this tools. I just try to ease your work, let's start again: you have gcc installed; you have TIVA (am I right?) so in Tiva root folder there is a Makefile - in the command window change to Tiva folder and type "make" - this will build all examples - just see if all are OK. Then add a project of your own as suggested by TI documentation - must work. 

    I do not use microC - just read a little bit the suggested doc - I would start by not using the standard libraries, and of course, inspect all the installed folders to see if they use a gcc version or not; linker file and startup code must be found to see them...

    Petrei