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.

EK-TM4C1294XL



I am working on a TI's TM4C1294XL LaunchPad with KEIL and I had a problem at the begining. I installed all the drivers for both USB and KEIL then I succesfully upload TI's blinky example to board it worked without a problem. After that I add some very basic code, in the default program it only blinks the PN0 user LED and I add some code to blink PN1 additionally but nothing has changed. PN0 LED still blinking but PN1 is not. I tried to blink other onboard LEDS PF0, PF4 but the result is same. Here is the code:

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"

/**
  * @brief  Program main function
  * @param  void    
  * @retval none
  */
int main(void)
{
    volatile uint32_t ui32Loop;

     /* Enable PORTN peripheral access */
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);

    /* Check if the peripheral access is enabled. */
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPION))
    {
    }

    /* Enable the GPIO pin for the LEDS (PN0, PN1).  Set the direction as output, and
       enable the GPIO pin for digital function. */
    GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0);     
    GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_1);

    while(1)
    { 
        /* Turn on the LEDS. */
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0x01);        
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, 0x01);

        /* Delay for a bit. */       
        for(ui32Loop = 0; ui32Loop < 1200000; ui32Loop++)
        {
        }

        /* Turn off the LEDS. */
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0x00);
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, 0x00);

        /* Delay for a bit. */   
        for(ui32Loop = 0; ui32Loop < 1200000; ui32Loop++)
        {
        }
    }
}

Is it possible to problem caused by some write protection feature or KEIL?

  • My friend - you need a bit more time/effort here - most all MCUs have idiosyncrasies (unique requirements) with which you must comply.

    What you have encountered is "not" (any) protection feature of Keil.

    Look here (this IS your issue!):

    /* Turn on the LEDS. */
            GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0x01); //this works ONLY for Pin0       
            GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, 0x01); // the value "2" is required for Pin1

    Now - just as you report - GPIO_PIN_0 works, GPIO_PIN_1 does not!

    This is a "trap" into which many (including this reporter - long ago) have fallen.    The final parameter w/in "GPIOPinWrite()" is the "bit-weighted argument" to be applied to parameter 2.    Thus GPIO_PIN_1 requires the value "2" - not "1".    Should you seek to turn on (many) Port bits - simply add the "bit-weighted values" of each.    (i.e. 255 (0xFF) turns on the entire Port...(provided param 2 properly matches))

    Indeed - so many (other) code protocols accept "1" as "High or On" - yet not here - and not now!   (but for the (very) limited case of Pin_0.)

    You may alternately employ the repetition of param. 2 as the value for param 3.   (i.e. (GPIO_PORTN_BASE, GPIO_PIN_1, GPIO_PIN_1);)    (we're not told the reward offered by those medically repairing "carpal tunnel" syndrome - brought on by such use - especially when multiple bits are so treated)

    Indeed this IS strange - yet will become 2nd nature w/the passage of time...    Many, many code examples are provided - and you may use this forum's Search feature (up top) to benefit further from (other) user experience...

    Do note - this method was designed by the predecessor MCU vendor (who has "fled the scene") - direct any/all hostilities/complaints in their direction...

  • Thank you for your answer, I fixed my code and it worked! Here is the important part of my code:

            /* Turn on the LEDS. */
    	GPIOPinWrite(GPIO_PORTN_BASE, (GPIO_PIN_0 | GPIO_PIN_1), (GPIO_PIN_0 | GPIO_PIN_1));
    			
            /* Delay for a bit. */       
            for(ui32Loop = 0; ui32Loop < 6000000; ui32Loop++)
            {
            }
    
            /* Turn off the LEDS. */
    	GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0 | GPIO_PIN_1, 0x00);
    				
            /* Delay for a bit. */   
            for(ui32Loop = 0; ui32Loop < 6000000; ui32Loop++)
            {
            }

  • Good for you - believe that you (now) well understand this (bit strange) code format. With usage - this will reinforce itself - and you should have "no issues." Note that when "multiple bits" w/in a port are to be set - your code will expand to 2 lines (maybe even 3!) Your use of the hex representation for the values of (both) parameters 2 & 3 - eases your labor - yet is "not" self documenting - as is the "GPIO_PIN_x" etc. method.
  • cb1,

    As yourself have mentioned before, a useful idea for the third parameter is something like:

    #define GPIO_PINS_ON 0xFF   // Drives high any pin mentioned on the 2nd parameter
    #define GPIO_PINS_OFF 0x00  // Drives low any pin mentioned on the 2nd parameter

    Then use

    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_4, GPIO_PINS_ON);

    Regards

    Bruno

  • Indeed my (fellow) carpal inflicted (i.e. wristless) friend.

    It is usual that a "pattern of pins" may occur frequently - then "GPIO_PINS_ON" may be replaced w/"GPIO_Pattern_N_ON."
    With my (current) broken wrist - anything saving me from "the entry of 8 LONG Port-Bit descriptors" is welcomed... (even though they "well document" - especially as they "well document.")
  • Staff/I have often used, "B3_ON" - "C7_OFF" as (both) a "wrist, energy & time saver."

    Endless repetition of "GPIO_PIN_X" actually proves "harder to recognize" than the more elementary "A4_ON." New "defines" must be created (just once) to accommodate this: "Time, Energy & Wrist Saver" technique...

    Say Bruno - smart/experienced Biz guy that you are - I'll give you 5:1 odds that "Winner of U.S. Open" tournament - (women) is an American.    (such offers do not occur too often - you know...)

  • One small addition from a slightly different perspective

    GPIOPinWrite is probably misnamed. It should be named something more like GPIOMultiplePinWrite which more closely follows its function. That misnaming contributes rather largely to the misunderstanding of its use.

    Now having written a function to set multiple pins I suspect the development team saw no need to create something for the single pin case. In this I largely agree with them. I don't see the savings in typing being a significant enough boon to justify adding additional functions/macros. And the addition of multiple methods to set a pin increases what is needed to write and understand the resulting code.

    Having said that there is a simple macro or function you can add that would by its existence meet cb1's goal of reducing typing and slightly improve understanding. You can create a GPIOSinglePinWrite (its existence implies that the other is a multiple pin function). It would take as its last argument a ON/OFF and a single pin ID macro (rather than multiple in the current function). This would be easy to convert to the proper parameters in either a macro or a function. If desired it would also be possible to write macros/functions for GPIOMultiplePinSet and GPIOMultiplePinClear along the same lines.

    Robert
  • *** LIKE *** (how I curse the "entitled" person/group - far smarter than you/Jens/Bruno/me - who "killed the LIKE!")

    Well stated - iirc - in the past I received "heat" for such "simplification" - yet your plan here proves a very nice implementation...

    (note to Chi (fellow) hiway drivers - none too skilled cb1 (shortly) enters LSD (Lake Shore Drive) w/"8 cameras & semi-autonomous sports car" (almost) controlled by "limp wristed" driver. (and highly capable "R-52 ARM MCU") Drivers in/about cb1 vicinity are forewarned!
  • cb1_mobile said:

    Well stated - iirc - in the past I received "heat" for such "simplification" - yet your plan here proves a very nice implementation...

    Thanks. And in that vein I find myself with a spare minute so an untested, uncompiled, unlinted example that could be used as a starting point. This is only a fragment of what would be necessary for complete working code. There's none of the includes or header definitions that would be needed.

    /* Macros for Pin I/O enhancement. There are two goals for these macros
     *  1 - Provide some clarity over the TIVAware functions for the single
     *      pin case and the case where multiple pins are set to the same value.
     *  2 - Reduce the typing load for long arguments.
     *
     * This is completely untested, even by compiling. Its only use is meant 
     * to be as illustration of a possible approach.
     *
     * Since this is only an example some documentation on arguments is missing.
     * Filling those in and testing the result is left as an exercise for the reader :)
     */
     
    typedef enum {
            PIN_OFF,
            PIN_ON
        } PIN_STATE;
    
        /* Change the value of a single pin on a given port. This could be written 
         * as a function instead and there would be advantages to doing so. It 
         * would be more typesafe and there would be no potential risk from
         * multiple evaluation of the argument pin. */
    #define GPIOSinglePinWrite(port, pin, state) (((state)== PIN_ON) ? \
                    GPIOPinWrite((port), (pin), (pin)) : \
                    GPIOPinWrite((port), (pin), 0))
    
        /* Set the output for multiple pins on a given port simultaneously. 
         * This could be written as a function instead and there would be 
         * advantages to doing so. There would be no potential risk from
         * multiple evaluation of the argument pins. */
    #define GPIOMultiplePinSet(port, pins) (GPIOPinWrite((port), (pins), (pins)))
    
        /* Clear the output for multiple pins on a given port simultaneously. 
         * This could be written as a function instead. */
    #define GPIOMultiplePinClear(port, pins) (GPIOPinWrite((port), (pins), 0))

    Robert

  • Robert Adsett72 said:
    an untested, uncompiled, unlinted example

    Sir - have you NOT just described (95%+ of the code) - regularly arriving here?      (even that from rushed, "LIKE-less" vendor staff)

    If I may - might:

    GPIOMultiplePinWrite((port), (pin), (pin))

    be strengthened by:

    GPIOMultiplePinWrite((port), (pins_in_array_n), (pins_selected))

    Now my (equally) "untested, uncompiled & unlinted" submission - attempts to (better clarify) "What's What" w/(always pesky) params: 2 & 3."

    Note that mine is a, "name change only" (i.e. fast "paint job") which attempts to "better clarify the role of params: 2 & 3."

    And while you (surely) know this - others must insure that any such "code construct" produces, "glitch-less" bit Sets & Clears!     (forum would do FAR BETTER to, "Ban the Glitch" - not the well-earned LIKE!")

    I may (even) have "snuck in" an element of KISS!      (further horrifying (our) LIKE-less (uninspired/uncomprehending (entitled)) crüe)

  • cb1_mobile said:

    If I may - might:

    GPIOMultiplePinWrite((port), (pin), (pin))

    be strengthened by:

    You will note that there is no multiple pin write in my example. Since it already exists I wasn't reproducing it, even to rename. I was producing the complementary sets, particularly the single pin write so many seem to struggle with.

    My feeling is that although there might be a small gain from adding a multiple pin write rename, most of that gain is already there from having a single pin write variant (that suggests the other function is a multiple pin write form) and there is advantage to using the normally named version for anyone who later reads the code and is already familiar with TIVAWare.

    Robert

  • Indisputable - really?      Is it not (so often) true that "indisputable" (really) means: "insufficiently studied/probed/investigated - or awaits new/better facts?"

    Certain (beyond engineering) schools teach the value of "caution" when employing: "Always, Never, or Indisputable."     In each case such words "open the user" to a "vast burden of proof."     Indeed caution (most always) trumps bluster!      (note the (hedge) "most")