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.

C2000 LaunchPad, SYS/BIOS 6.33.5.46, TMS320F28027, GPIO12 interrupt

Other Parts Discussed in Thread: SYSBIOS, CONTROLSUITE, LAUNCHXL-F28027

Hello,

I am trying to toggle LED on LaunchPad every time when button GPIO12 is pressed. It seems that interrupt is triggered only once. Unfortunately after hours of trying different configurations I didn't had any success. Can somebody tell me what I am doing wrong? The C code and configuration file is listed below.

C code:

#include <xdc/std.h>
#include <xdc/runtime/Log.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/family/c28/Hwi.h>

void main()
{
BIOS_start(); /* does not return */
}

unsigned int *GPATOGGLE = (unsigned int*)0x6FC6;
unsigned short int *PIEACK = (unsigned short int*)0x0CE1;
unsigned short int *XINT2CR = (unsigned short*)0x7071;
unsigned int *GPADAT = (unsigned int*)0x6FC0;
unsigned int *GPIOXINT2 = (unsigned int*)0x6FE1;
unsigned int *GPAMUX1 = (unsigned int*)0x6F86;
unsigned int *GPADIR = (unsigned int*)0x6F8A;
unsigned int *GPAPUD = (unsigned int*)0x6F8C;
unsigned short int *PCLKCR3 = (unsigned short int*)0x7020;

Void myTaskFxn(Void)
{
asm(" EALLOW");
*PCLKCR3 |= 1<<13;
*GPAMUX1 = (unsigned int)0;
*GPAPUD |= 0x0000080F;
*GPADIR = 0x0000000F;
*GPIOXINT2 = 12;
*XINT2CR = 0x000D;
asm(" EDIS");
}


Void myIsr(xdc_UArg arg)
{
*GPATOGGLE = 0x000000F;
}

Application configuration:

var Defaults = xdc.module('xdc.runtime.Defaults');
var Main = xdc.useModule('xdc.runtime.Main');
var Startup = xdc.useModule('xdc.runtime.Startup');

var BIOS = xdc.useModule('ti.sysbios.BIOS');
var Timer = xdc.useModule('ti.sysbios.family.c28.Timer');
var Boot = xdc.useModule('ti.catalog.c2800.init.Boot');

BIOS.libType = BIOS.LibType_Custom;
BIOS.assertsEnabled = false;
BIOS.logsEnabled = false;
BIOS.swiEnabled = false;
BIOS.clockEnabled = true;
BIOS.taskEnabled = true;

Program.argSize = 0x0;
Program.stack = 0x100;

BIOS.heapSize = 1024;
BIOS.heapSection = null;
BIOS.runtimeCreatesEnabled = false;

Defaults.common$.diags_ASSERT = xdc.module("xdc.runtime.Diags").ALWAYS_OFF;
BIOS.cpuFreq.lo = 50000000;
Boot.pllcrDIV = 10;


var Task = xdc.useModule('ti.sysbios.knl.Task');
Task.enableIdleTask = true;
var taskParams = new Task.Params();
taskParams.priority = 2;
var myTask = Task.create('&myTaskFxn', taskParams);

var Hwi = xdc.useModule('ti.sysbios.family.c28.Hwi');
Hwi.dispatcherTaskSupport = true;
var hwi0Params = new Hwi.Params();
hwi0Params.enableAck = true;
hwi0Params.arg = 36;
hwi0Params.maskSetting = xdc.module("ti.sysbios.interfaces.IHwi").MaskingOption_SELF;
hwi0Params.disableMask = 0x0;
hwi0Params.restoreMask = 0x0;
hwi0Params.instance.name = "hwi0";
Program.global.hwi0 = Hwi.create(36, "&myIsr", hwi0Params);

  • Damian,

    Did you set a breakpoint on “myIsr()” to verify it is only triggering once?  Or is the conclusion based upon watching the LED?  I’m not that familiar with these GPIOs, but I wonder if you need some debouncing of the key? 

    Also, is it your intent that myTaskFxn() only runs once?  Because, the Task will terminate after the first execution of the function.  If so, is there some reason the code in myTaskFxn() is not in main(), versus a Task?

    Thanks,
    Scott

  • Hi Scott,

    Yes I have verified this situation using breakpoint as well. I have checked all registers related with this event - GPIO registers, PIE registers and External Interrupt registers. They are all the same (the important part of course, not for example the interrupt counter) before the first interrupt, inside the first interrupt handler and after executing it. That is why I suppose that this is a SYS/BIOS problem.

    Yes this task runs only once for setup. The reason why this code is in a task is that all code which I will be writing will be wrapped in classes-drivers and will be managed only from tasks. This is because SYS/BIOS has some restrictions of the code that runs within main. This project is setup to have an iddle task so when my task finishes its work the iddle task is still running. I don't really see any reason why I should put this code which basically writes to memory (peripherals) in main instead of Task?

  • Hi Damian,

    After the first interrupt, can you see that the first interrupt was successfully acknowledged?  

    And when you expect another to have fired, can you see in registers whether the interrupt is pending or not?

    The reason I asked about using a task is that there will be extra overhead and RAM required to create the task and its stack just to run some initialization code, that looks like it should be fine to call from main().  It isn't a "problem", but just a question/suggestion regarding efficiency.

    Scott

  • Hi Scott,

    I am not sure what you mean by successfully acknowledged but when I set up a breakpoint inside the interrupt handler in registers I can see that the interrupt pending flag in PIE registers is 0 so probably SYS/BIOS before entering interrupt handler is clearing this flag already ? Or I am wrong?

    I am not worried about efficiency at this point but to make it work. I would like to change our current type of microcontrollers (not from TI) to yours C2000 because of possibility of using SYS/BIOS but before that I need to check is everything working like it should.

    So the real question is somebody configured this version of SYS/BIOS to handle GPIO interrupts on C2000 platform? Or I am the first one trying to do that?

  • Hi Damian,

    I dove into looking at this more today, going thru the GPIO and PIE descriptions, reference guides, and the SYS/BIOS sources.

    I haven’t found any examples - SYS/BIOS or not - of using GPIOs as interrupt sources.

    Yes, the Hwi dispatcher will clear the corresponding PIEACK.x bit.  

    I’m wondering if there is some clearing needed at the GPIO-peripheral level(?)  At first I thought this might involve the GPACLEAR or GPBCLEAR registers.  But I haven’t been able to confirm this. 

    Also I wonder if the internal pullup needs to be configured for the GPIO bit for your configuration?  Also, whether there might be some sort of level/edge triggering setup issue.

    Do you have a non-OS test for the GPIO interrupts?  I think getting the GPIO interrupt sequence understood and working is needed first, before trying to integrate into SYS/BIOS.

    After sending this reply I will send an internal email to our C28x apps team to see if someone there has suggestions or examples…

    Scott

  • Scott Gary said:
    I haven’t found any examples - SYS/BIOS or not - of using GPIOs as interrupt sources.

    Hi Scott, Damian,

    I would suggest starting with the external interrupt example in controlSUITE (C:\ti\controlSUITE\device_support\f2802x0\v110\f2802x0_examples_ccsv4\external_interrupt)  This will help determine if interrupts are working correctly. 

    //!   This program sets up GPIO0 as XINT1 and GPIO1 as XINT2.  Two other
    //!   GPIO signals are used to trigger the interrupt (GPIO28 triggers
    //!   XINT1 and GPIO29 triggers XINT2).  The user is required to
    //!   externally connect these signals for the program to work
    //!   properly.
    //!
    //!   XINT1 input is synched to SYSCLKOUT.
    //!   XINT2 has a long qualification - 6 samples at 510*SYSCLKOUT each.

    Looks like it sets up one interrupt for rising edge trigger and the other for falling edge trigger.

    Scott Gary said:
    I’m wondering if there is some clearing needed at the GPIO-peripheral level(?)  At first I thought this might involve the GPACLEAR or GPBCLEAR registers.  But I haven’t been able to confirm this. 

    Also I wonder if the internal pullup needs to be configured for the GPIO bit for your configuration?  Also, whether there might be some sort of level/edge triggering setup issue.

    You do need to configure which edge the interrupt is on.  Also depending on how the qualification is configured it will need to be held long enough to be detected.  The default is simply sync with SYSCLKOUT so it isn't long.

    -Lori

  • Hi There,

    If you could take a look on my code in the first post you will see how I was configuring it. I have compared it with mentioned example and I think that I am configuring it properly. I have been changing the falling / rising / both edge configuration and still the same. I don't know is the part of the code responsible for PIE interrupt the same in my project and example project because it is managed by SYS/BIOS. I tried different SYS/BIOS configurations related with interrupts and no solution was successful. I will appreciate if somebody can take this board in hands and try to run my code and maybe correct it. 

    One thing I have noticed. When I will configure the triggering edge to both edges triggering the interrupt triggers only once when I press the button. Later when I will set up the flag in PIE register, interrupt will trigger and jump to interrupt handler twice. Later after each pressing of the button interrupt is triggering twice so somehow its working better - assuming that each press of the button has only rising and falling edge . Of course in reality there will be some bouncing so there should be more interrupts triggered but anyway by making this hand triggered interrupt it starts to see something more. Is SYS/BIOS managing those PIE interrupt properly? 

  • After whole weekend of trying to make it run I still didn't resolve this problem. Please can someone provide a SYS/BIOS configuration and code example for properly working external interrupts?

  • Damian,

    I searched for differences between your version of SYS/BIOS and the latest, and there are no changes with respect to PIE acknowledgement.  Also, no know issues.

    Can you confirm, is it the LAUNCHXL-F28027 board that you are using?  And you’re using the second, programmable button that is installed on the board?  If not, which board is it, and have you done any custom wiring?

    Once you confirm, I will see if I can locate a board at my local site to try this out.

    Also, did you try a simple non-OS test to verify that you can get expected button behavior in that case?

    Thanks,
    Scott

  • Hi,

    Yes I am using LAUNCHXL-F28027 board and I trying to configure interrupt for GPIO12 which is connected to its second button.


    I haven't tried the non-OS version because I am interested only in launching this with SYS/BIOS. I suppose that the hardware is not broken because somehow I can get the interrupt triggered and I am doing the initialization part in the same way like the non-OS example so the biggest probability is that SYS/BIOS is doing something else with PIE interrupts than the non-OS example. 

  • Hi Scott,

    I just wanted to ask will you try this out in near future? I need to make some decisions within next weeks and that is why I am asking. I will appreciate your help in that!

  • Hi Damian,

    I did get a hold of a launch pad and ran some tests yesterday.  I can see the same behavior as you, with only the first press recognized.  At the same time, I’m seeing unexpected bit values in the GPIO register view in CCS, and I’m trying to make sense of those.  I was interrupted while doing this yesterday, and will get back to this ASAP, hopefully late this morning. 

    I’m now off of forum support rotation, and it is a bad week with many things that need to get done ASAP. :OP

    Scott

  • Hi Damian,

    OK, we figured out why the interrupt only fires the first time.  By default, GPIO12 has an internal pullup enabled.  This causes the line to go to “1” on the first press, but then it gets stuck there and will not go back to “0” until the next power cycle.  

    You can see this stuck behavior by looking at the GPADAT register view in CCS, then press and hold S3 and refresh the register view.  The GPIO12 bit will change from “0” to “1”.  Releasing the button and refreshing, or pressing again and refreshing, the bit stays a “1”.

    You can resolve this by writing a “1” to GPIO12’s bit in GPAPUD to disable the internal pullup.

    In your program you have:

    *GPAPUD |= 0x0000080F;

    I changed it to this:

    *GPAPUD |= 0x0000180F;

    And the bit is no longer stuck, and subsequent button presses trigger interrupts.

    Sorry again for the delay to figure this out.

    Regards,
    Scott

  • Hi Scott,

    Sorry for taking your time with this kind of stupid situations. I should notice that. Thanks again.

  • Hi Damian,

    No problem!  The behavior of that bit line is very odd.  It makes sense in the end, but wasn’t at all obvious.

    Regards,
    Scott

  • Hello!
    I have a very similar problem with GPIO 12 interruption and with interruptions in general(C2000) but no one can help me!
    Here is my question: e2e.ti.com/.../481166.
    Please check it, if you can, I think you will understand what's going wrong.
    Thanks in advance!
    Regards!
  • Konstantin,

    I looked at your question over on the C2000 forum.  Sorry, I don’t know what the issue might be.  That is the right forum for deep C2000 device and controlSuite questions.  Hopefully someone there can provide an answer for you…

    Regards,
    Scott