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.

Can't enable interrupts with Code Composer Studio



Hello,

I am trying to learn how to use the Tiva C series launchpad (TM4C123GXL) with code composer studio and I can't figure out how to make interrupts work without TIVA ware. I tried to write a simple program that uses the watchdog timer0 to test out it is interrupt but it is not working so far.

Could somebody point me to the right direction.

Note that stuff like BIT1,BIT0 are things that I have defined and the code compiles properly and the WDT is resetting the system when it overflows twice.

/* Program to test the WDT0 functionallity, WDT1 is a little bit different
 * WDT0 uses the system clock.
 * WDT0 is a 32-bit down counter
 * When WDT overflows for the first time, in enters a ISR and an interrupt flag is set and tries to save the system
 * When it overflows a second time, it resets the system.
 *
 */
// includes
#include <tiva.h>
#include <stdint.h>
#include <stdbool.h>
#include "inc/tm4c123gh6pm.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"
#include "driverlib/timer.h"
// functions prototype
void WDT_0(void);

int main (void)
{
    IntMasterEnable();
    volatile unsigned long int i;
    SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOF;   // Enable the GPIO port that is used for the on-board LED.

    i = SYSCTL_RCGC2_R;                     // Do a dummy read to insert a few cycles after enabling the peripheral.
    


    GPIO_PORTF_LOCK_R = 0x4C4F434B;         // unlock PortF pins (only portF needs this)
    GPIO_PORTF_CR_R  |= 0x1F;               // allow changes to PF4-0 (only portF needs this)
    GPIO_PORTF_DIR_R |= BIT2+BIT1;          // set PF2,PF1 as outputs
    GPIO_PORTF_DIR_R &= ~(BIT4+BIT0);       // set PF4 and PF0 as inputs
    GPIO_PORTF_PUR_R |= 0x11;               // enable pullup resistors on PF4,PF0
    GPIO_PORTF_DEN_R |= BIT4+BIT3+BIT2+BIT1+BIT0;             // enable digital for PF4-PF0

    WDT_0();
    GPIO_PORTF_DATA_R |= BIT2;
    while (1)
    {
        //WATCHDOG0_LOAD_R = 0xFFFFFFFF;       // pet WDT by reloading a value
        //WATCHDOG0_ICR_R =0x01;               // clear interrupt overflow flag.



    }
}


void WDT_0(void)
{
    volatile unsigned long int i;
    SYSCTL_RCGCWD_R |= 0x01;                    // enable clock for WDT 0
    i = SYSCTL_RCGCWD_R;                        // Do a dummy read to insert a few cycles after enabling the peripheral.
    WATCHDOG0_LOAD_R = 50000000;                // load value into counter
    WATCHDOG0_CTL_R |= 0x02;                    // these two lines let WDT reset system
    WATCHDOG0_CTL_R |= 0x01;                    // and enable WDT 0 and interrupts.
   
}

void WDT_Handler(void)
{
    GPIO_PORTF_DATA_R |= BIT1;


}

  • Mohammad Albalooshi said:
    I am trying to learn how to use the Tiva C series launchpad (TM4C123GXL) with code composer studio and I can't figure out how to make interrupts work without TIVA ware.

    I haven't analyzed the code in detail, but some comments:

    1) In the example code I can't see where the WDT_Handler function is registered as handler for the watchdog interrupt.

    One way is to change the interrupt vector table in flash - when a new project is created in CCS a default <device>_startup_ccs.c source file is added to the project. The g_pfnVectors array needs to be edited to reference your interrupt handler function for the specified interrupt. The default behavior is that the IntDefaultHandler function is called for each interrupt which just spins in an infinite loop. 

    One other way is to modify an entry in an interrupt vector table in RAM - see the IntRegister function in TivaWare for an example.

    2) By default the watchdog timer continues counting if the processor in halted by the debugger. When you saw the system reset when the watchdog overflows twice, had the processor been halted in the debugger after the watchdog was enabled?

    If so, try setting the STALL bit in the Watchdog Test (WDTTEST) register so the watchdog stops counting when the processor is halted by the debugguer.

  • I have edited the _startup_ccs.c file to include the WDT_Handler() instead of the standard IntDefaultHandler in the vector table and added (extern void WDT_Handler(void); ) also but the ISR is never executed.

    I tried setting the STALL bit and single stepping through the program, the RIS register shows that the WDT overflows after a while but the WDT_Handler code is not executed, and when it overflows the second time, the system resets.

  • Hello Mohammad,

    You are missing the call for IntEnable(INT_WATCHDOG);

    Also, if I were to make a suggestion, then instead of using the current coding style, it would be better if you can call the TIVAWare API's. This will allow for a much more readable and maintainable code as you develop it further.

    Regards

    Amit

  • Hello Amit,

    That actually made it work!!!

    However, I don't want to use TIVAWare because I am just starting to learn about MCU and using tivaware does not really teach you anything, but now I want to know what this function (IntEnable(INT_WATCHDOG)) is doing, how do I see what this function is doing and what are it is expected parameters?

  • Hello Mohammad,

    The IntEnable function is prototyped in interrupts.c/.h file. The parameter is the interrupt vector number which has to be enabled in the NVIC controller.

    Regards

    Amit

  • Mohammad Albalooshi said:
    using tivaware does not really teach you anything

    So very unfair - so very untrue!  

    Perhaps - if one simply employs, "cookbook functions" - w/little effort to review & analyze their set-up/configuration and sequence of execution - little will be learned.  But - if you look closely at both the C source and resulting assembler - a tremendous amount of critical data, key register relationships, & proper code sequences is revealed!

    You can strengthen your learning by employing the vendor's code library along w/the Peripheral Driver Library User's Guide - which both illustrates & then details every library function's use & parameter requirements.  

    Multiple code examples also exist - many segregated (grouped) by peripheral.  Again - with the Peripheral Driver Guide open/ready - and your study of the C source (found quickly/easily) w/in the driverlib - much self-teaching can naturally occur.

    Rejecting the professionally developed library - starting essentially from scratch (as you appear to propose) seems not to have produced the "teaching" you seek - and no body of written documentation exists to guide nor assist you.

    I've several decades of experience w/MCUs - many makers - this vendor's code library is a great asset and, "Really does teach - especially when used, "systematically & effectively" as described herein!"

    Follow these suggestions - as small biz owner I/others know these to work - you will come to speed quickly if you focus and make the proper effort...

  • cb1_mobile said:

    I've several decades of experience w/MCUs

    This probably explains our differing opinions. This is my first MCU, and my first exposure to the ARM architecture. For me, starting from scratch and setting all the registers is beneficial to me because that actually shows me what is going on with the hardware. I didn't mean to insult anyone who uses tivaware, in fact I will probably use it when I get to stuff like graphics, but for now, I prefer to use the actual registers.