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.

SYS/BIOS and LM4F232H5QD

Other Parts Discussed in Thread: SYSBIOS, STRIKE

Support;

I am looking for information or examples to look at for using SYS/BIOS and the LM4F232H5QD processor. Is SYS/BIOS compatable with M4 processors yet and if not, any idea as to when it might be?

Any help or guidance would be greatly appreciated.

Thanks, Jeff

  • Jeffrrey,

    You can use SYS/BIOS with the LM4F232H5QD, but you must treat the processor as an M3 processor.  All this really means is that the floating point functions of the M4 should be used by only one task, because SYS/BIOS won't save/restore the floating point state.  This will be fixed in a future release of SYS/BIOS, but I'm not aware that any schedule has been announced.

    A good place to get started is the Stellaris application note on using SYS/BIOS:

    http://focus.ti.com/mcu/docs/litabsmultiplefilelist.tsp?sectionId=96&tabId=1502&literatureNumber=spma040&docCategoryId=1&familyId=1755

    (If my pasted link doesn't work, go to http://www.ti.com/Stellaris, then select Documentation and you should see a document with SYS/BIOS in its title.)

    A separate warning from a programmer here is to be wary of what SYS/BIOS does for clock initialization.  He suggests you disable the SYS/BIOS clock initialization and use the Stellaris Driverlib functions.  At the very least, you need to make sure the actual crystal you're using is consistent with what SYS/BIOS suggests.

    Hope this helps!

    KC Witte

  • KC Witte;

    Thank you for the prompt response. When I try to compile my project I get:

    The LM4F232H5QD device is not currently supported.
    The following devices are supported in the ti.catalog.arm.cortexm3 catalog:

    A little history...

    In the setup I chose:

    Target = ti.targets.arm.elf.M3

    Platform= ti.platforms.stellaris:LM4F232H5QD

    I am using the LM4F232H5QD Evaluation Board from TI as the hardware

    I opened up the SYS/BIOS 'Clock' example to work with that as a starting point. In your email you say  I must treat it as a M3. Does that mean select a different Platform?

    Again, thank you for your help.

    Regards, Jeff




  • Jeff,

    Yes, you should select an M3 platform, preferably one with a similar memory map.  With the LM4F232H5QD we've used the LM3S9B92 as the platform.

    KC Witte

  • KC;

    Thanks again but I am still not able to get this simple project to run. Is there a place where I can get help on creating or using the SYS/BIOS 'Clock' example with the LM4F232H5QD development board meaning a COMPLETE project that runs & can be debugged to get me started? After that I think I would be alright. Right now I do not believe I have the environment setup correctly to do this.

    Let me know. Thanks, Jeff

  • Hi Jeff,

    I've been corresponding with KC about your questions.  

    As KC mentioned, the current versions of sys/bios don't have native support for LM4F devices yet.  M3 code will run on an M4 so we can get by with choosing an LM3 part with a similar memory map and clock configuration.  My suggestion of a 9B92 was a poor suggestion to KC.

    Please try to re-create the sys/bios project by selecting an LM3S1816.  I think you'll be more satisfied with the results.  Sorry about that.

    Also, because sys/bios is downlevel with respect to LM4 parts and our driverlib code, I might suggest bypassing the native sys/bios clock configuration (which runs before main() ) and, instead, use our SysCtl API's for configuring the clock before calling BIOS_start().

    Within CCS, right click your clock.cfg file and choose "Open with XDCScript Editor".  Add these lines to the bottom of the script:

    var Boot = xdc.useModule('ti.catalog.arm.cortexm3.lm3init.Boot');
    Boot.configureClock = false;
    BIOS.cpuFreq.lo = 40000000;
    
    

    These lines tell the configuration mechanism to pull in the boot-code configuration module.  Once we have a handle to that module we touch the configureClock property and tell sys/bios not to configure the clock.  As a result, sys/bios doesn't know the frequency of the tick.  So we tell it via cpuFreq.lo.

    The result is that you execute to main() using the default (out-of-reset) clock configuration. 

    HTH!

    --Miles

  • Miles;

    I was able to figure this out by using this code;

    #include "\stellarisware\inc\lm4f232h5qd.h"

    #include "\stellarisware\inc\hw_types.h"
    #include "\stellarisware\inc\hw_ints.h"
    #include "\stellarisware\inc\hw_memmap.h"

    #include "gpio.h"

    #define BACKLIGHT_CTRL    GPIO_PIN_0        //on PortD
    #define DISP_RS                      GPIO_PIN_1        //on PortD
    #define DISP_WR                     GPIO_PIN_2        //on PortD
    #define DISP_ENABLE            GPIO_PIN_3        //on PortD

    #define DispCTRLPort             GPIO_PORTD_BASE

    void BackLightControl(unsigned char ucState)
    {
        GPIOPinWrite(DispCTRLPort, BACKLIGHT_CTRL, ucState);    //     Set the Backlight State
    }

    In the main code...

        GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);

        BackLightControl(ON_STATE);        // Turn the back light ON

    But when I compile and link I get this error...

     undefined             first referenced
      symbol                   in file     
     ---------             ----------------
     GPIOPinTypeGPIOOutput ./clock.obj     
     GPIOPinWrite          ./LCD_2X20.obj  

    error #10234-D: unresolved symbols remain
    error #10010: errors encountered during linking; "Blink LED.out" not built
    gmake: *** [Blink LED.out] Error 1
    gmake: Target `all' not remade because of errors.

    I think  I am missing a library???

    Thanks, Jeff


  • Jeff,

    Excellent!  You're definitely on the right track with driving the GPIOs.

    And now we're back to a CCS/SYSBIOS/DriverLib question.  For posterity, the context related to your use of GPIO's can be found in this thread: 

    http://e2e.ti.com/support/microcontrollers/stellaris_arm_cortex-m3_microcontroller/f/471/t/166937.aspx

    So, yes, you're "missing" a library.  If you look in DriverLib/driverlib you should find that you have pre-compiled libraries out-of-the-box.  The problem is simply that the CCS project doesn't reference the library.  Because of compiler switches you'll need to link against the M3 versions of DriverLib.

    Simply right-click your project, select properties, Build, TMS470 Linker, "File Search Path", and point to DriverLib in there. 

    --Miles

  • Miles;

    Two questions or issues exist still. The first is my SYS/BIOS clock task no longer work since I added the driver lib code. Are there compatibility issues with both?

    The second is I can turn PINS on but not off:

    #define DispLEDPort     GPIO_PORTG_BASE

        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
        GPIOPinTypeGPIOOutput(GPIO_PORTG_BASE, GPIO_PIN_2 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
        //
        // Turn off the LEDS.
        //
    ... THIS DOES NOT
        GPIOPinWrite(DispLEDPort, GPIO_PIN_2, 1);        // Turn LED on Dev board ON << THIS PIN DOES NOT
    ... THIS WORKS
        GPIOPinWrite(DispLEDPort, GPIO_PIN_4, 1);        // Turn LED on Dev board ON
        GPIOPinWrite(DispLEDPort, GPIO_PIN_5, 1);        // Turn LED on Dev board ON
        GPIOPinWrite(DispLEDPort, GPIO_PIN_6, 1);        // Turn LED on Dev board ON
        GPIOPinWrite(DispLEDPort, GPIO_PIN_7, 1);        // Turn LED on Dev board ON

    ... THIS DOES NOT
        GPIOPinWrite(DispLEDPort, GPIO_PIN_2, 0);        // Turn LED on Dev board OFF
        GPIOPinWrite(DispLEDPort, GPIO_PIN_4, 0);        // Turn LED on Dev board OFF
        GPIOPinWrite(DispLEDPort, GPIO_PIN_5, 0);        // Turn LED on Dev board OFF
        GPIOPinWrite(DispLEDPort, GPIO_PIN_6, 0);        // Turn LED on Dev board OFF
        GPIOPinWrite(DispLEDPort, GPIO_PIN_7, 0);        // Turn LED on Dev board OFF

    Thoughts? Thanks, Jeff


  • Hi KC Witte and Miles,

    Good Day!!

    I am also in the same situation with Jeff since yesterday trying to run SYS BIOS sample programs. I've got to a point were I look for another RTOS that supports Stellaris LM4F232H5QD but I did not found any. So Im back with SYS BIOS, fortunately my collegue were able to stumble on this blog and t helps a lot.

    My concern is, if we continue to used SYS BIOS to run on LM4F232H5QD is there going to be limitations? and what would that be? the thing is our HW right now is not that fix yet so it is better for us to know limitations so that we can mitigate our plans.

    I am hoping you guys can help me on this.. thanks in advance..

    Cheers,

    Sherwin Tiongson

  • Great points Sherwin. I have most of my demo working but it took a lot of help from the TI experts. Not good. But I am understanding things...

    Miles;

    One issue I have is how to use PN0 - PN7 as a 8 bit data port for the LCD. Meaning I need to write and read from it. My local FAE said to do something like this:

        GPIOPinTypeGPIOInput(DispDATAPort, DispDATA);                  //     Make the port a input port

        ulBusy = GPIOPinRead(DispDATAPort, DispDATA);                  //    Data from the port

        GPIOPinTypeGPIOOutputOD(DispDATAPort, DispDATA);        //     Make the port a output port

    ... go do other things ...


    But I always read a 0xff so my guess is the part is not happy with a config change on the fly.

    Any suggestions on how I might do this?

    Thanks again for your help. Jeff

  • Jeffrey Jacobson said:
    I can turn PINS on but not off

    This may be a first - most new users to StellarisWare experience the exact opposite.  (cannot turn ON)

    StellarisWare's "GPIOPinWrite()" instruction tries to strike a balance between full (8 bit control) of an 8 bit port while enabling single bit Sets/Resets.  Our group thinks of the 3 parameters w/in this instruction as: Target 8 bit port, Mask (can target single, multiple or all bits of the target port), and finally port output value. 

    Your example both illuminates and confounds!  You list, "GPIOPinWrite(DispLEDPort, GPIO_PIN_4, 1);  // Turn LED on Dev board ON"   This is contrary to my/others understanding of StellarisWare (unless your use of SYS/BIOS or you have altered normal/customary Stellaris defines)  In many compilers and programming formats setting a target bit to "1" (as your example does) indeed will set that pin high.  (we assume said pin is an output)  However - 7 out of 8 times this is untrue w/in StellarisWare - due to the action of parameter 2 w/in GPIOPinWrite - the port Mask - and individual bit "weighting".  To turn a particular Stellaris bit ON - parameter 3 (port value) must match the port Mask.  Thus you must replace the "1" you used with GPIO_PIN_4 for parameter 3.  (or you may use the bit value 0x10 or 16 decimal - both should equate to the define for GPIO_PIN_4) 

    That said - curious that code lists GPIOPinWrite(DispLEDPort, GPIO_PIN_4, 1);  as turning Led ON.  Easier to grasp if the Led's cathode returned to GPIO_PIN_4, its anode wired thru Rlimit to adequate positive voltage - then the LOW output by such code would illuminate the Led.  (and same holds for your 3 other LED ON examples)

    Be interesting for those reading if you'd be so good to repeat your test and report.  The StellarisWare Peripheral DRL User Guide is a most useful reference.  That along with the many pre-tested code examples provided w/in StellarisWare will quickly enhance your comfort and skill w/ StellarisWare.

  • You are correct in the assumption that my actual hardware is opposite to what you would think. In order to turn my LEDS on, I need to send it a 1. I ended up fixixing it by using this code:

    #define BACKLIGHT_CTRL    GPIO_PIN_0        //on PortD

    GPIOPinWrite(DispCTRLPort, BACKLIGHT_CTRL, (ucState & BACKLIGHT_CTRL));    //      Set the Backlight State

    ucState is a variable SET/CLEARED elsewhere in my code. This works just fine. I was under the impression the call was just a 1 to set and a 0 to clear. Then I read about the vector bits...

    Sorry for the confusion.

    Jeff

  • Miles;

    The issue was in my code not in the concept. So, to close this out, we CAN turn a port around on the fly and read from it just fine. I had to raise the DISP_ENABLE to actually cause the data from the LCD to show up on the pins. The corrected code is:

    unsigned char BusyFlag(void)
    {
        unsigned long ulBusy = 0;

        GPIOPinWrite(DispCTRLPort, DISP_WR, DISP_WR);            //     Raise the WR line

        GPIOPinWrite(DispCTRLPort, DISP_ENABLE, DISP_ENABLE);    //     Raise the ENABLE line

        GPIOPinTypeGPIOInput(DispDATAPort, DispDATA);            //     Make the port a input port

        GPIOPinWrite(DispCTRLPort, DISP_ENABLE, 0);                //     Drop the ENABLE line                                  <------ this was what was wrong

        ulBusy = GPIOPinRead(DispDATAPort, DispDATA);            //    Data from the port

        ulBusy &= 0x80;                                              //     Mask off bit 7 (busy flag)

        GPIOPinWrite(DispCTRLPort, DISP_WR, 0);                    //     Drop the WR line

        GPIOPinTypeGPIOOutputOD(DispDATAPort, DispDATA);        //     Make the port a output port

        return (unsigned char)ulBusy;

    }              


    Thanks again for the help! Jeff

  • I am fearful of your "shift" to the endlessly forgiving GPIO_PIN_0.  (this will accept param #3 = 1 - and output a high)  However - in the future - you/others will surely "grab" this code - for use by one of the 7 other GPIO port pins - and your outputs will not go high!  Perhaps better to make "peace" with bit masking and bit weighting - GPIO_PIN_0 "fix" may not be long terms...

  • cb1_mobile

    I am not clear then how you think this issue should be solved? Maybe something like this:

    if(ucState)
      GPIOPinWrite(DispCTRLPort, BACKLIGHT_CTRL, BACKLIGHT_CTRL);      //      Set the Backlight State = 1
    else
      GPIOPinWrite(DispCTRLPort, BACKLIGHT_CTRL, 0);                                       //      Set the Backlight State = 0

    Please help us understand a better way to handle this. I appreciate your feedback!

    Jeff

  • Fearful that you may not have fully grasped the "weighting" of the various bit-positions w/in a Stellaris Port.  To my group's mind - the shift to GPIO_Port_0 continues to enable the use of "1" to create a high.  However - this proves true only for GPIO_Port_0 - and will not work for the 7 other port pins.  As stated in my initial post - Peripheral DRL User Guide and numerous code examples will serve to reinforce the method by which StellarisWare manages its port pins.  You are certainly not alone - issue just like yours has visited this forum hundreds of times - I fear that your shift to GPIO_Port_0 does little to "reinforce" proper pin masking/management - thus my recommendation...

    Update: Dawns that several examples are in order:

    GPIOPinWrite(Port_X, 0xFF, 0xAB);  here Mask is 0xFF (255 dec) thus all 8 port bits may be output.  However "value" of 0xAB confines output high to port bits: 7, 5, 3, 1, 0. 

    GPIOPinWrite(Port_X, 0x82, 0xFF);  here Mask is 0x82 - Val is 0xFF.  Only port bits 7 and 1 are output high.  Note that mask has "filtered" output.  (useful to guard key bits)

    GPIOPinWrite(Port_X, 0x14, 0x24);  here Mask is 0x14.  Thus no "match" w/in upper nibble - but lower nibble bit 3 has match.  Port Bit 2 will output high.

    The use of "full mask" (0xFF) is useful to read or write a full byte to a Port.  (i.e. to transfer to a byte oriented device - perhaps latch, Lcd, memory etc)

    hope that this further illuminates/clarifies...

  • Jeffrey Jacobson said:

    I am not clear then how you think this issue should be solved? Maybe something like this:

    if(ucState)
      GPIOPinWrite(DispCTRLPort, BACKLIGHT_CTRL, BACKLIGHT_CTRL);      //      Set the Backlight State = 1
    else
      GPIOPinWrite(DispCTRLPort, BACKLIGHT_CTRL, 0);                                       //      Set the Backlight State = 0

    Please help us understand a better way to handle this. I appreciate your feedback!

    Yes, this is much better than what you had before.

    You should not AND with ucState unless ucState has values 0 for off and 0xff for on.  If the latter is the case, then you don't need to AND with ucState, you can just write it directly with the following:

    GPIOPinWrite (DispCTRLPort, BACKLIGHT_CTRL, ucState);

    As the above statement is functionally identical to:

    GPIOPinWrite (DispCTRLPort, BACKLIGHT_CTRL, ucState & BACKLIGHT_CTRL);

    The 2nd argument can be thought of as always implicitly ANDed with the 3rd argument.

  • cb1_mobile;

    I come from the ever useful bit banging 8 bit 8031 processor world where a setB and ClrB do exactly what you would expect. I have read and re-read the how to's on this and still have issues with Bit 0 on multiple ports. The code I have bee testing consistently does not work with BIT 0. Take a look and point me to what I m doing wrong:

    #define DispLEDPort         GPIO_PORTJ_BASE
    // LEDS
    #define LedDATA (GPIO_PIN_7 | GPIO_PIN_6 | GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2 |    GPIO_PIN_1 | GPIO_PIN_0 ) //On Port J

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ);            // External LEDS
    GPIOPinTypeGPIOOutput(DispLEDPort, LedDATA);
    GPIOPadConfigSet(DispLEDPort, LedDATA, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD);

    // in the code somewhere, assumption is a 0 turns the LED ON

    ucValue1 = 0xAA;
    GPIOPinWrite(DispLEDPort, LedDATA, ucValue1);        // Should turn ON bits 0,2,4,6 and the others OFF

    ucValue1 = 0x55;
    GPIOPinWrite(DispLEDPort, LedDATA, ucValue1);        // Should turn ON bits 1,3,5,7 and the others OFF

    Again, all the bits flip except bit 0. I have tried other ports and the same thing happens.

    Thoughts? Thanks, Jeff 2/27


  • Looks to this reporter like you've mastered this (yay) - have everything correct!  (have also used 8031/51 in dayz past)

    You've almost got a "walking 1/0" (recall those) coded - great, fast test.

    I BET YOU that there is some anomaly with Bit 0 - on that Port!  (or you have bad led/connection/reverse etc.)

    Check errata - can't recall your MCU but you may have special "hoop" thru which to jump - to get bit 0 to perform as "true" GPIO.  (i.e. defaults to alternate function)

    Nice "verify answer" appropriate - n'est pas?

     

  • You are a genius! The burden resistor I had in series was no good. Fixed and all is well. Sorry to have bugged you on something I should have found on my own. Thank you for the guidance you gave. I think I am set now and will move forward with the real project.

    Thanks again, Jeff

  • Jeffrey Jacobson said:
    You are a genius!

    But of course - mon ami.   (sentiment expressed by you, sainted Mother)  NOT by vile, 3rd grade NYC teacher - directing young reporter to high/rear seat & conical headgear...

    You took enough time/care in your posts that responders "wanted" to help - so credit to you.  Do regularly read/review/experiment w/StellarisWare - later you can move toward direct register manip. - but for now "achieve" and then proceed by refinement...

    neat "verified answer" tick sure to expand collection of 3rd world T-Shirts, leaky mugs. 

     

  • cb1_mobile;

    I found in the errata on the LM4F232 part a issue with Port F Bit 0 that was perplexing me as I could not get the bit to flip and I thought I had a bad dev kit. In the errata it is asking me to:

    Workaround:
    To reconfigure the pins to their intended reset state (GPIO Input, GPIODEN =0), software must clear
    the corresponding bits in the GPIOAFSEL and GPIODEN registers for the associated pins. For pins
    PD7 and PF0, software must clear the corresponding AFSEL bits using the register commit control
    procedures described in the Commit Control section in the General-Purpose Input/Outputs chapter
    in the data sheet.
    Note that PD7 and PF0 should be grounded, if possible, to prevent triggering an NMI. If that is not
    possible, an NMI handler must be implemented in case a High level is applied to PD7 or PF0 before
    they can be reconfigured.

    Looking if the datasheets for the part, it is unclear what I need to be re-programming to fix this. I see the section in the data sheet on Commit Control what it is expecting to be done but I need some guidance here on how to fix the PF0 issue.

    Any help would be greatly appreciated.

    Regards, Jeff

  • Jeff,

    From your post, I gather that you've read section 8 of the errata.

    Please review sections 10.2.4 in the data sheet ("Commit Control"), visit GPIOAFSEL (Register 10 of the GPIO block) on page 697, and the GPIODEN (Register 18 of the GPIO block) on page 709.

    In general, because PD7 and PF0 are "sensitive" GPIO's in that they can cause an NMI, you have to jump through an extra hoop before changing their function. You'll have to "unlock" the registers using the commit control and then touch:

    GPIO_PORTF_BASE + GPIO_O_AFSEL bit 0 -> 0 
    GPIO_PORTF_BASE + GPIO_O_DEN  bit 0 -> 1

    In order to use PF0 as a digital output signal, its alternate function (NMI) must be disabled and its digital function (GPIO) must be enabled.

    Does that answer your question?

    --

    Miles

  • Have you a really strong need to employ these particular 2 pins?  Prefer to deal with the more essential - especially as this errata is likely to be solved w/in next release.  (thus effort of transient value - at best)  (Verify Answer - granted to others - still eludes this reporter...)

  • I have since moved away from those 2 pins.

    For now, I am trying to hook up port G pin 7 as a falling edge interrupt pin that jumps to a ISR function that I will post swi's in. I am finding it hard to locate info on how to set this all up. I have tried this:

        GPIOPortIntRegister(GPIO_PORTG_BASE, PORTgISR);

        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
        GPIOPinTypeGPIOInput(GPIO_PORTG_BASE, GPIO_PIN_7);                    // Make PG7 INPUT

        GPIOIntTypeSet(GPIO_PORTG_BASE, GPIO_PIN_7, GPIO_FALLING_EDGE);        // Make PG7 Falling Edge
        GPIOPinIntEnable(GPIO_PORTG_BASE, GPIO_PIN_7);
        IntEnable(INT_GPIOG);
        IntPrioritySet(INT_GPIOG, GPIO_PIN_7);

    ...

    My Isr:

    void PORTgISR(void)
    {
    ... do something once it works...

    }


    but it fails to link because of this line: GPIOPortIntRegister(GPIO_PORTG_BASE, PORTgISR);

    Is there a easy place/way to find out how to configure/code this? The examples in the various app notes are not complete and do not work.

    Thanks, Jeff

  • Sherwin,

    I missed this question in the thread a few weeks ago.

    If you build sysbios against an LM3 part and run on an LM4F the restriction that you'll encounter is that sys/bios doesn't save the FPU registers when context switching.  As a result you can only use the FPU from one thread at a time.

    That said, I've learned that our most recent versions of sys/bios DO support LM4F parts.  You can download an update to sys/bios here:
    http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/bios/sysbios/index.html

    In your CCS project select "ti.targets.arm.elf.M4F" as the target and LM4F232H5QD as the part.

    Hope that helps,

    --
    Miles

     

  • Miles;

    Great news on the new version of SYS/BIOS supporting the M4 processor. Completed that task and that is good to go. One question I have is early on in this thread I was given this code to add to the end of the app.cfg script file.


    var Boot = xdc.useModule('ti.catalog.arm.cortexm3.lm3init.Boot');
    Boot.configureClock = false;
    BIOS.cpuFreq.lo = 16000000;

    Now my question is do I still need that in there or does the new version handle this correctly?

    Thanks again for your help!

    Jeff



  • Miles;

    No worries as I see I no longer need to add those lines as it now works without them.

    I am trying to add a hwi to my code just to see how that all works and for the LM4F232 processor, where do I find the EventID numbers for the various ports? I look in the data sheet for the part but I cannot find them. In my example I am trying to setup Port D pin 7 as a falling edge interrupt. My code looks like this:

    I used the app.cfg XGCONF utility and added a hwi. When I look at the script in the editor here is what I see:

    System.SupportProxy = SysMin;
    var hwi0Params = new Hwi.Params();
    hwi0Params.instance.name = "hwi0";
    hwi0Params.eventId = 19;
    hwi0Params.priority = 5;
    Program.global.hwi0 = Hwi.create(16, "&LineSyncISR_hwi0", hwi0Params);

    This looks correct. Then in my code I have:

    extern Void LineSyncISR_hwi0(void);
    /*
     *  ======== LineSync_hwi0 ========
     */
    Void LineSyncISR_hwi0(void)
    {
        volatile unsigned char ucState1 = 0;
        ucState1++;        // just do something so I can break here...
    }

    Void main()
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);                        // Port D
        GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, GPIO_PIN_7);                    // Make PD7 INPUT
        GPIOIntTypeSet(GPIO_PORTD_BASE, GPIO_PIN_7, GPIO_FALLING_EDGE);        // Make PD7 Falling Edge
        GPIOPinIntEnable(GPIO_PORTD_BASE, GPIO_PIN_7);
        IntEnable(INT_GPIOD);
        IntPrioritySet(INT_GPIOD, GPIO_PIN_7);

    .... do more stuff

        BIOS_start();
    }

    When I short PD7, I never break in the ISR.

    Anything obvious here I am doing wrong? Thanks, Jeff

  • Jeff,

    That's an interesting question and the answer, unfortunately, is a bit confusing.

    "cortexm3.lm3init.Boot" - You've probably noticed the hierarchy that the sys/bios config file uses when declaring and manipulating sys/bios's objects?  So we're grabbing an object which allows us to manipulate properties of LM3 initialization.

    LM3 lives under CortexM3 since Luminary Micro parts originally used the M3 core.  

    You're using an LM4F232.  While the core has changed from an LM3 to an LM4F, the overall architecture of the chip and the peripherals (including clock initialization) have remained the same.

     So LM3Init.boot has less to do with the core (m3 vs m4f) and more to do with the system as a whole.  And the LM3Init is just as applicable to the LM4F232 as it was to LM3 parts.

    I'm going to ask our sys/bios team if they can somehow alias an LM4FInit to the LM3Init code to avoid this confusion in the future.

    All that said, you may have noticed that the one thing we do with this "Boot" object is tell it to NOT initialize the clock.  This allows you complete control over the clock config in your application.  I prefer the higher degree of transparency (at least for bringup) at the expense of leaving sys/bios less aware of its surroundings.

    Does that make sense?

    --
    Miles 

  • Failure to trigger falling edge interrupt:

    Far out of my league re: SysBios & XGCONF - however code listing never shows that you've enabled a weak pull-up on Port_D_pin7 and unstated is the existence of an external pull-up in hardware.  Without the pin "idling" high - your short to ground will not be noted.  One assumes that you've handled the GPIO_D interrupt correctly w/in your start-up file...

  • Jeff,

    Jeffrey Jacobson said:
    hwi0Params.eventId = 19;

    In reading the documentation on a HWI object, they make it sound like eventId is the interrupt number.  That is not the case, at least not for Stellaris parts.  I've never set eventId, myself.  We'll get around to the IRQ number later in this post.

    Jeffrey Jacobson said:
    hwi0Params.priority = 5;

    You want to be careful with priority.  This value maps to the priority register in the NVIC and lower values are higher priority.  I would encourage you to read up on interrupt handling in the Cortex and become good friends with the NVIC.  Consider: NMI's have "negative" priorities.  The lowest value (highest priority) you can set is 0.

    It's also worth considering how "critical sections" are implemented on a cortex (this isn't necessarily specific to sys/bios) -- typically interrupts are not globally enabled/disabled.  The PRIMASK is simply raised (ie. lower value) to prevent interrupts of lower priority from interrupting your critical section.  Make sense?

    Sys/bios assumes it can maintain coherency amongst its internal structures by using a PRIMASK of 0x10.  You are allowed to go higher priority than sys/bios if you have really strict latency requirements (sub-uS).  BUT you are NOT allowed to make sys/bios API calls from within your high priority interrupt handler (otherwise you violate sys/bios's assumptions about the protection it has afforded itself).  The one call you can make is Hwi_post() to software-generate a (lower priority) interrupt.

    In any case, you can omit the priority setting (it has a sensible default) or choose values like 0x80, 0x40, 0x20, etc.  Be careful with priorities <= 0x10.

     

    Jeffrey Jacobson said:
    Program.global.hwi0 = Hwi.create(16, "&LineSyncISR_hwi0", hwi0Params);

    The "16" in the 1st parameter of this call is your IRQ number.  GPIOD is IRQ 19.

    So, the config code should look something like this:

    var hwi0Params = new Hwi.Params();
    hwi0Params.instance.name = "gpio_d";
    Program.global.hwiGPIOD = Hwi.create(19, "&LineSyncISR_hwi0", hwi0Params);

    Jeffrey Jacobson said:
        IntPrioritySet(INT_GPIOD, GPIO_PIN_7);

    This call does the same thing that hwiParams.priority does.  It changes the priority of the interrupt in the NVIC.  GPIO_PIN_7 is probably not your desired interrupt priority.  To keep it simple, I'd suggest skipping the setting of interrupt priorities for now.

    --Miles

  • Miles;

    As always, great direction and answers for us new in the Ti world. After review and a lot more reading, I was able to get the solution to work. Here is my revised code with 2 pins acting as falling edge interrupts:

    Void LineSyncISR_hwi0(void)
    {
        lIntPinStatus = GPIOPinIntStatus(GPIO_PORTA_BASE,GPIO_PIN_6 | GPIO_PIN_7);

        switch(lIntPinStatus) {

            case  GPIO_PIN_7:
            {
                GPIOPinIntClear(GPIO_PORTA_BASE, GPIO_PIN_7);        // Clear the INT now
                Do some cute stuff here...
            }
            break;

            case  GPIO_PIN_6:
            {
                GPIOPinIntClear(GPIO_PORTA_BASE, GPIO_PIN_6);        // Clear the INT now
                Do some cute stuff here...
            }
            break;

            default:
            {
                GPIOPinIntClear(GPIO_PORTA_BASE, lIntPinStatus);        // Clear the INT now

                Not sure if this is needed...
            }
            break;
        }
    }

    Main code...

    Void main()
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);                                                                                                                                       // Port A
        GPIOPinTypeGPIOInput(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7);                                                                                              // Make PA6 & PA7 INPUT
        GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_OD_WPU);
        GPIOIntTypeSet(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7, GPIO_FALLING_EDGE);                                                                // Make PA6 & PA7 Falling Edge

    ... rest of main and BIOS_Start();

    }

    In the app.cfg the hwi0 is setup like:

    I randomly set the Interrupt Priority to 25.

    Let me know if you see any holes in this. Also, the event IDS (called Vector Number) are found in the data sheet on pages104-106 under section Table 2-9. Interrupts for the LM4f232 part.

    Thanks, Jeff



  • I see this cant handle bitmaps so:

    In the app.cfg the hwi0 is setup like:

    Handle: hwi0

    ISR Function: LineSyncISR_hwi0

    Interrupt Number: 16

    Interrupt Priority: 25

    Event ID: 16 (from the data sheet)

    Enable at Startup is checked

    Masking Options: MaskingOption_SELF

    Thanks, Jeff

  • Jeffrey Jacobson said:
    I see this cant handle bitmaps so:

    That's kinda' funny.  It doesn't render in the forum but I saw the .BMP in my email.  .PNG's or .JPG's may work better, next time around.

    Jeffrey Jacobson said:
    Event ID: 16 (from the data sheet)

    pages 104-106 in the data sheet are the interrupt number.  I'm fairly certain that you can leave eventID as 0 and this will work just fine.  I'll confirm with our sys/bios team but I don't think eventID is used in this architecture (if it is used then it means something other than interrupt number).

    Jeffrey Jacobson said:
    Interrupt Priority: 25

    25 decimal is 0x19.  sys/bios reserves interrupt priority 0x10.  Interrupt priority 0x0 will be handled without sys/bios awareness.  The point being: 25 is a very high priority.

    In general, I would encourage not tweaking interrupt priorities until you have a demonstrable interrupt latency problem.  Since you're using an RTOS, you can make your ISR's very short, use tasks of various priorities, let those tasks block on semaphores or events.  Your ISR unblocks the task by posting to the appropriate synch object.  Then you let the scheduler handle the prioritization of your work.  If, when making full use of the RTOS's scheduler and task priorities you're STILL suffering an interrupt latency problem: THEN go and raise the interrupt priority of the appropriate IRQ.

    So, to recap: eventID is moot.  Interrupt priority is high, but acceptable and... you're experiencing success.  W00T!

    --
    Miles 

  • I want to test the hw interrupt functionality in LM4F232H5QD and i expect to print the message in the ISR but failed

    Below is my source code,

    Please help to find where is wrong, thanks

    /*
     *  ======== main.c ========
     */

    #include <xdc/std.h>

    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>

    #include <ti/sysbios/BIOS.h>

    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/hal/Hwi.h>

    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_nvic.h"
    #include "inc/hw_types.h"
    #include "driverlib/debug.h"
    #include "driverlib/fpu.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/systick.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/rom.h"
    #include "grlib/grlib.h"
    #include "utils/uartstdio.h"




    void InitConsole(void)
    {

        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinConfigure(GPIO_PA1_U0TX);

        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        UARTStdioInit(0);
    }


    void hwiFunc(UArg arg)
    {

        UARTprintf(" !!! ISR !!!\n");
    }

    Void taskFxn(UArg a0, UArg a1)
    {
        UARTprintf("enter taskFxn()\n");

        //HWREG(NVIC_SW_TRIG) = INT_GPIOD - 16;

        UARTprintf("exit taskFxn()\n");
        while(1)
        {
        }
    }

    /*
     *  ======== main ========
     */
    Void main()
    {
        Task_Handle task;
        Hwi_Handle hwi0;
        Hwi_Params hwiParams;
        Error_Block eb;


        FPUEnable();
        FPULazyStackingEnable();
        SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

        InitConsole();
        UARTprintf("enter main()\n");

        Error_init(&eb);


        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM);                                                           // Port M
        GPIOPinTypeGPIOInput(GPIO_PORTM_BASE, GPIO_PIN_0 | GPIO_PIN_1);                / Make PM0 & PM1 INPUT

        GPIOPadConfigSet(GPIO_PORTM_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
        GPIOIntTypeSet(GPIO_PORTM_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_FALLING_EDGE);      / Make PM0 & PM1 Falling Edge
        GPIOPinIntEnable(GPIO_PORTM_BASE, GPIO_PIN_0 | GPIO_PIN_1);

        Hwi_Params_init(&hwiParams);

        hwi0 = Hwi_create(127,hwiFunc,&hwiParams,&eb);

        if (hwi0 == NULL) {

                BIOS_exit(0);
        }

        task = Task_create(taskFxn, NULL, &eb);
        if (task == NULL) {
            BIOS_exit(0);
        }

        BIOS_start();     /* enable interrupts and start SYS/BIOS */
    }


  • Does "enter main()" get printed out?  I'm guessing that it doesn't because I don't see you setting up the baud rate and other settings for your UART.

    Where are you setting up the parameters for your hardware interrupt?  I don't see the code, so can't tell if you are setting up the interrupt properly.

    Do you get any print out from your task?

    You are very vague about what works and what doesn't work in your program, and what debugging you've attempted.

  • I am certainly no expert here as I just brought my patient to life but I question this parameter:

    hwi0 = Hwi_create(127,hwiFunc,&hwiParams,&eb);

    Looking at the data sheet for the part on pages 104 - 106 I do not see Port M as a viable port to use. And the 127 seems to be in the reserved area anyway. Can you try using Port A pin 6 for your test? Then the code would be:

        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);                                                                                                                // Port A
        GPIOPinTypeGPIOInput(GPIO_PORTA_BASE, GPIO_PIN_6 );                                                                                                // Make PA6 INPUT
        GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_6, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_OD_WPU);
        GPIOIntTypeSet(GPIO_PORTA_BASE, GPIO_PIN_6 , GPIO_FALLING_EDGE);                                                                  // Make PA6 Falling Edge
        GPIOPinIntEnable(GPIO_PORTA_BASE, GPIO_PIN_6 );


    hwi0 = Hwi_create(16,hwiFunc,&hwiParams,&eb);

    Give it a shot. Hope it helps.

    Jeff

  • Slandrum and Jeff both offered good suggestions.

    In addition, I don't see a global IntEnable(INT_GPIOx);  Refer to the docs to understand the difference between IntEnable and GPIOPinIntEnable and why you need them both.

    Lastly, I would discourage the use of run-time creation.  You can provision all your RTOS objects in the sys/bios config file.  It saves you from consuming code-space with runtime/dynamic creation and, IIRC, sys/bios may omit its own Init() functions if they're never called.  Static allocation is a win-win.

    --Miles

  • Thanks for your quick response,

    Sorry i do not describe more detail and let me explained:

    This test propject have link to the uart source code(uartstdio.c) in the folder C:\StellarisWare\utils so i can call the API UARTprint() directly,

    I can see the message "enter main()" and the print out in the Task is fine but the message "!!! ISR !!!" can not display,

    What parameter should i set of the hardware interrupt ? please let me know, thanks

  • Dear Miles,

    After add the IntEnable(INT_GPIOM) then the ISR can be trigger,thanks