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.

Tivaware 2.1.2.111 gpio issues with ports P,Q,R,S,T

Other Parts Discussed in Thread: TM4C1292NCZAD

We are using Tivaware version 2.1.2.111 with a TM4C1292NCZAD processor and have an issue and a feature request for the GPIO library.

Issue:  The Tivaware call to GPIOIntRegister() asserts because the call to _GPIOIntNumberGet() returns zero.

The _GPIOIntNumberGet() function returns zero when the calling function passes in GPIO_PORTR_BASEGPIO_PORTS_BASE, or GPIO_PORTT_BASE because these entries are not defined in the g_ppui32GPIOIntMapSnowflake map.

Feature Request: We would like a function to register/unregister individual pin interrupts for port P and port Q.

We wish to take advantage of the individual pin interrupts available on port P and port Q.  

So it would be convenient if Tivaware could provide something like  GPIOIntRegisterPin(ui32Port,, ui8Pin, void (*pfnIntHandler)(void)) and GPIOIntUnregisterPin(ui32Port,, ui8Pin) functions to do this.  

Thanks!

Dominic 

  • Hello Dominic,

    We really appreciate you identifying the bug in Tivaware and reporting. I have opened a bug report to track this.

    Regarding the feature request, I agree that this could be useful. I will have to discuss with the team and get back.

    Thanks,
    Sai
  • Hello Sai,

    Any updates regarding this??

    Thanks,

    SS

  • Actually, even the suggested function name was applied!

    It's available in Tivaware 2.1.4.178, here's the UG:

    Bruno

  • Greetings Bruno - Inspector "Clouseau" would be proud.     (excellent detective work...)

    We've no experience w/4C129 devices - thus must ask, "Is it true that this MCU's "Start-Up" file reveals the presence of, "Individual Interrupt Handlers - on a "Port-BIT" basis - for those Ports w/such "individual BIT Interrupt/Recognition" capability?"

    It is believed that "freedom" from the requirement to "Register Interrupt Handlers" offers increased programming ease along w/other advantages.    (i.e. reduced RAM usage/guard-banding etc.)

    Thanks for so clear, quick & well detailed an answer.       (and hopefully - for your "inside knowledge" regarding, "Register-FREE" Interrupt Handler desires...)

    Should time and/or interest allow - might you list any advantages you (may) have discovered - when choosing such "Interrupt Registration" over the existing mechanism (which appears more direct, reduced in code foot-print & more robust) and is (already) fully embodied w/in MCU's Start-Up file.     (again - all "counts upon" the presence of, "Port-BIT Interrupts residing w/in the MCU's Start-Up file...)

  • cb1_mobile said:
    "Is it true that this MCU's "Start-Up" file reveals the presence of, "Individual Interrupt Handlers - on a "Port-BIT" basis

    Yes, it is. Here's an excerpt of one CCS startup file I quickly opened here:

        IntDefaultHandler,                      // GPIO Port M
        IntDefaultHandler,                      // GPIO Port N
        0,                                      // Reserved
        IntDefaultHandler,                      // Tamper
        IntDefaultHandler,                      // GPIO Port P (Summary or P0)
        IntDefaultHandler,                      // GPIO Port P1
        IntDefaultHandler,                      // GPIO Port P2
        IntDefaultHandler,                      // GPIO Port P3
        IntDefaultHandler,                      // GPIO Port P4
        IntDefaultHandler,                      // GPIO Port P5
        IntDefaultHandler,                      // GPIO Port P6
        IntDefaultHandler,                      // GPIO Port P7
        IntDefaultHandler,                      // GPIO Port Q (Summary or Q0)
        IntDefaultHandler,                      // GPIO Port Q1
        IntDefaultHandler,                      // GPIO Port Q2
        IntDefaultHandler,                      // GPIO Port Q3
        IntDefaultHandler,                      // GPIO Port Q4
        IntDefaultHandler,                      // GPIO Port Q5
        IntDefaultHandler,                      // GPIO Port Q6
        IntDefaultHandler,                      // GPIO Port Q7
        IntDefaultHandler,                      // GPIO Port R
        IntDefaultHandler,                      // GPIO Port S
        IntDefaultHandler,                      // SHA/MD5 0
        IntDefaultHandler,                      // AES 0
        IntDefaultHandler,                      // DES3DES 0
        IntDefaultHandler,                      // LCD Controller 0
        Int_Timer6A,                      // Timer 6 subtimer A
    

    Whenever possible, we here also prefer to configure things on this file because the IRS respond quicker, which is important for really time-sensitive interrupt routines. 

    In other cases, for clarity of coding and convenience of a standard library, the registration can be done on a run-time manner like the one discussed here.

    RELEVANT to note that it is always possible to identify which pin has caused the interruption to trigger on a "standard port", i.e. port A. So if any of the posters or readers here are looking for this subject because they want to find out which of the 8 pins have triggered the ISR, be aware that one does not need individual pin interrupt for such.

    Bruno

  • Bruno - while (only) "Wonder Woman" invades our theaters - "Superman" lurks - this very forum!      (at minimum - superman-like response!)    Very well done!

    We note "clarity of coding & convenience" offered up as (potential) advantages of such, "Interrupt-Handler Registration."      Yet - to my thick skull - I see NO such clarity nor any convenience!    Instead - the (needless) addition of a code block which (possibly) may be over-written - thus invites vulnerability...

    As to your note of, "Identifying the specific Port-Pin" which triggered a "Port Interrupt" - that is achieved via a "PORT READ" processing - upon entrance into the Port Interrupt - don't you agree?     And... just maybe - that "extra Port Read" and processing (may) justify the (dreaded) "Registration of Interrupt Handler."       (again, maybe!)

    Again - thank you, Bruno...

  • Hey, thanks for the words! I've certainly no hope of competing with Gal Gadot... guess I'll limit myself to attempting Superman replies!

    As for the "convenience and clarity", the idea goes like this:

    A library that deals with push-buttons, for example, will surely have interrupt service routines as part of it. The documentation for the library could guide the user to simply #include it and use the listed API's - in one scenario - or otherwise he would instruct to #include the library and also to add FunctionToRespondToGPIOTrigger(); to the Startup file. Not a big deal, but just one step extra.

    In the end, there is never a way to predict all the hardware possible connections, and possibly the same port that has push-buttons has a totally non-related digital input requiring int, so there is always the need for adapting "the universal" code anyway!

  • FYI, this issue was acknowledged and resolved, and is included in the latest version of Tivaware.
  • Leonard,
    That's exaclty what I had written... I even added an image of the most recent Tivaware user guide.
    Bruno
  • Bruno Saraiva said:
    A library that deals with push-buttons, for example, will surely have interrupt service routines as part of it.

    I rather hope not. Interrupts are generally not well suited to switch inputs.

    Like cb1, I see no increase in clarity, except perhaps to those raised in a DOS world. There might be some rare convenience if you need to switch interrupts in and out but that doesn't seem to me to be a common need.

    Maybe for interrupts shared between a bootloader and application code? There are other ways of dealing with that but it does save an indirection.

    Robert

  • Robert Adsett said:
    I rather hope not.

    Maybe that's right, but I still have my own internal conflicts between polling versus having the board sleep as much as possible... My first embedded adventures were on MSP430 and the only word terms we'd hear was SAVE POWER SAVE POWER SAVE POWER...

    So, well... sorry for the news, but: our switch inputs use interrupts!   :)

    As for those raised in a DOS world... hummm, it gets worse, I came from a INTERPRETED BASIC on a Z81 world!

    Not that we ever switch interrupt registered functions in our projects - but still, for some purposes we do use the IntRegister families once at "library initialization" only to save the need of editing the Startup.

    Bruno

  • Bruno Saraiva said:
    ... My first embedded adventures were on MSP430 and the only word terms we'd hear was SAVE POWER SAVE POWER SAVE POWER...

    Well that is a potential use (although may be able to get the same effect w/o an interrupt). Low power is not this processor's strength and not a realm I play in. Of course you've also now got a rather more complicated interrupt if you care about bounces.

    Bruno Saraiva said:
    we do use the IntRegister families once at "library initialization" only to save the need of editing the Startup.

    No need to edit the startup for that. That's what weak definials are for.

    Robert

  • Robert Adsett said:
    That's what weak definials are for.

    I'm sure I can search it around, but may I take the lazy way out and ask you to kindly clarify/teach? That's something I really haven't heard of...

    Bruno

  • The approach is general. Almost every compiler supports it. The details are compiler specific. Since it involves startup and interrupts it's not portable in any case so the fact that it's compiler specific is not of great significance.

    I'll use IAR for example

    The idea is to set each vector to a known routine something like

    void (* const __vector_table[155])(void) =
    {
        top_of_mem,                         /* The initial stack pointer (defined by linker)*/
        Reset_ISR,                          /* The reset handler */
        NMI_ISR,				/* The NMI handler */
        Fault_ISR,                          /* The hard fault handler */
        MPUFault_ISR,	                /* The MPU fault handler */
        BusFault_ISR,                       /* The bus fault handler */
        UsageFault_ISR,                     /* The usage fault handler */
    

    Define a default routine

    void IntDefaultHandler(void)
    {
        unsigned int psr_contents;
        volatile int i;
        	/*  Program Status Register contains the current exception vector.*/
        psr_contents=__get_PSR();
    
        (void)SWO_putc('!',31u);
        SWO_fputhex((char)(psr_contents&0xFF), 31u);
    

    So far this is usually the same for each compiler. Now come the compiler specifics. In IAR I have the following

    /*lint -e975 allow pragma, this is not quite C.  Need to control placement and
    	weak definitions of symbols.					*/
    /*lint -efile(766,startup_wk.h) */
    	/* Weakly link vectors to default routines so user can replace. */
    #pragma weak NMI_ISR=IntDefaultHandler
    #pragma weak Fault_ISR=IntDefaultHandler
    #pragma weak BusFault_ISR=IntDefaultHandler
    #pragma weak UsageFault_ISR=IntDefaultHandler
    #pragma weak SVCall_ISR=IntDefaultHandler
    #pragma weak DebugMonitor_ISR=IntDefaultHandler
    #pragma weak MPUFault_ISR=IntDefaultHandler
    #pragma weak PendSV_ISR=IntDefaultHandler
    #pragma weak SysTick_ISR=IntDefaultHandler
    #pragma weak GPIO_A_ISR=IntDefaultHandler               /* GPIO Port A */
    

    This assigns IntDefaultHandler as the routine for each of the interrupt routines. Think of it as renaming them. The weak pragma makes them weak definials, that is they are temporary assignments. If the user code defines a routine named NMI_ISR it is used in place of IntDefaultHandler. In GCC I would probably use the linker to define the weak definials (I have in the past).

    Now adding a new interrupt is easy, you just define the routine with the appropriate name.

    Upsides:

    • Easy to add or remove interrupts
    • No forgetting to assign interrupts
    • Unused interrupts automatically have a default.
    • Startup is reusable

    Downsides:

    • Missing interrupt routines may not be detected until run time test. Think typo.
    • Interrupt names are public symbols

    Clear as mud?

    Robert

  • Awarding that (late arriving)  - highly duplicative post of yours (minus your great detail) - a, "Verify" was especially galling!

    Clearly minimal (or NO) effort was made to review the thread content.       Such "help" seems of (very) little value!      (where is the UNLIKE/DELETE Button?)

  • Thanks, Robert! Mud clear!
    Makes total sense - I had really never came across this thing. Will give it a try on (pop-tool) CCS, probably tomorrow.