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.

How to take input from user switch on RM42?

Other Parts Discussed in Thread: HALCOGEN

Hi,

I tried to edit Blinky example so that not only an LED blinks every second, but it has to have user switch on GIOA7 pressed ON as well. I used same Halcogen generated files as for working Blinkiy and edit it. No success and no compiler error eider.

Code is:

void main(void)
{
/* USER CODE BEGIN (3) */

    /* Initialize RTI driver */
    rtiInit();

    /* Set high end timer GIO port hetPort pin direction to all output(0xFFFFFFF), all output except gioa7 - input (0xFFFFFF7F) */
    gioSetDirection(hetPORT1, 0xFFFFFF7F);

    /* Enable RTI Compare 0 interrupt notification */
    rtiEnableNotification(rtiNOTIFICATION_COMPARE0);

    /* Enable IRQ - Clear I flag in CPS register */
    /* Note: This is usually done by the OS or in an svc dispatcher */
    _enable_IRQ();

    /* Start RTI Counter Block 0 */
    rtiStartCounter(rtiCOUNTER_BLOCK0);

    /* Run forever */
    while(1);

/* USER CODE END */
}

/* USER CODE BEGIN (4) */
/* Note-You need to remove rtiNotification from notification.c to avoid redefinition */
void rtiNotification(uint32 notification)
{
/*  enter user code between the USER CODE BEGIN and USER CODE END. */
    /*   Blink is hapening only id User Switch is pressed   */

    /* Toggle HET pin 8 , if pin 7 (set as input) is high*/
    gioSetPort(hetPORT1, (gioGetPort(hetPORT1) ^ 0x00000100) & (gioGetPort(hetPORT1) ^ 0x00000080));
}
/* USER CODE END */

How this could be achieved?

Same time,  I found video: https://www.youtube.com/watch?v=Kih2YKvk8Cw where at the end, guy mentiones that the original code is from TI. Where do you have this example, and is there more?

  • Have you tried pulling out reading in the switch to make sure you are reading it correctly?

     

    Try doing the logic in several steps, then combining.

    - Read switch state

    - If switch is pressed, blink LED

     

    If you're just playing around it doesn't matter as much, but be aware in a real application you would need to debounce your switch.

     

     

  • David,

    Do you have code to read switch state? I found example where code is generated by Halcogen, toggling hatPin with pressing the switch, but that is does not look to applicable for this case. Could you give an example for denouncing as well?

    Thanks

    Dragan Stanic

  • ** I wrote the code below off the top of my head, so you may need to tweak it **

     

    Even though you are using het as gio, I don't think you use the gio functions to access the bits.

    I have leds connected to het pins that I toggle, I use them as outputs, but it should be similar for inputs. Make sure you have the pin muxed if needed in halcogen, and set to input

    You should be able to read the input pin state from the DIN register of whatever het you are using (ie hetREG1->DIN).  You then need to and it with whatever pin your switch is on.  So if your pin is on het[4][ it will be bit 4 of DIN register

    pinState= hetREG1->DIN & (1 << bitPosition);

     

    I think the same goes for setting your led output.  I don't think you use the gio functions.  You need to do something like

     

        if ((hetREG1->DOUT & (uint32_t)((uint32_t)1U << bit)) != 0U)
        {
        	hetREG1->DCLR = (uint32_t)1U << bit;
        }
        else
        {
        	hetREG1->DSET = (uint32_t)1U << bit;
        }

     

     

    If your loop is running every second, the switch has probably finished bouncing by the time the loop comes around again.  A very basic way to debounce is to have a counter in your loop.  Every loop check the value of the pin.  If it is different than the previous state, reset the counter to 0.  When the counter hits some value (the higher the value the longer the debounce) then you decide the switch really is in that state and take the action you want (blink the led). Debounce time depends on the switch, but probably a few milliseconds is enough.

     

    ;

  • David,


    User input switch in on GIOA7, and not in HET. May erroneous code set you to wrong track. Does that change register to read input from?


    Thanks

  • Dragan,

    I use the HALCoGen gio..() functions to read pin status. I go to the registers only if there is a performance/memory constraint or if I need to set/get multiple pins from a single port at the same time.

    For your example, I would enable gio and het drivers (het because you want to use one of the het pins for the LED).

    I would set the GIO pin for the button to input in HalCoGen
    I would set the HET pin to output for the led in HALCoGen

    I'd call the gioInit() and hetInit() in main, before enabling the interrupts and timers.

    I'd define a boolean volatile variable that holds the current button status.

    I would read the status of the button in the while(1) loop, using gioGetxxx(), and set that status in your boolean variable.

    In the rtiNotification handler, I would use that variable to check what's needed.

  • OK

    I got:

    while(1) {

    pinState=gioGetBit(gioPORTA,7);

    }

    It compiles and runs.

    Than I try to watch value of pinState in debugger, but it gives me:

    pinState    unknown    Error: Could not read 0x08001514: Execution state prevented access    

    Could debugger be tweaked to actually show value?

    Dragan

  • This may be happenig when breakpointing in the rti's handler..

    Do you get a runtime error when you don't set a breakpoint?

    (and can you indicate where in your code you have put the breakpoint?)

  • Can you try to set the option that I've highlighted in the screenshot below,

    restart the debugger,

    and try again?

  • Jan,


    I try that, but...

    I have this code in main:

        while(1) {

            switch(Task_Number) {
            case 1:
                Task_Number = 0;
                gioToggleBit(gioPORTA,2);
                ToggleLevel=ToggleLevel^true;// toglled
                break;
            }

    and

    void rtiNotification(uint32 notification)
    {
    /*  enter user code between the USER CODE BEGIN and USER CODE END. */
        /*   Blink is hapening only id User Switch is pressed   */

        /* Toggle HET pin 8 */
        if(ToggleLevel){
        gioSetPort(hetPORT1, (gioGetPort(hetPORT1) ^ 0x00000100));
        }
    }
    /* USER CODE END *

    in notification.

    LEDs behave as I expected, one is blinking in one second period and stops when user switch toggled, and other one toggles with switch. So obviously variable ToggleLevel does its job toggling between true and false with user button as well. But all I could see of its value is a dot.

    Thanks

    Dragan

  • I've tried to make this exercise myself. May be fun to compare code.

    First, create a HALCoGen project named 'ButtonRtiLedToggle'. Choose your microcontroller.

    Then, Run File -> Import DIL File, and select the attached DIL file:

    2235.ButtonRtiLedToggle.zip

    Select File -> Save Project

    Select File -> Generate Code

    Then go to CCS

    Create New CCS project

    Name project 'ButtonRtiLedToggle' (take care that the working directory for HALCoGen and CCS  are the same)

    Replace your sys_main by this sys_main:

    7838.sys_main.c

    Replace your notification.c with this one:

    5353.notification.c

    Compile and run.

  • It works,

    Jan , could you explain why is VIM channel 2 enabled? What does that do?

    Dragan

  • Dragan,

    VIM channel 2 is the RTI Compare 0 interrupt.

    It fires when the RTI counter 0 on HALCoGen Tab RTI :  RTI1 Compare reaches 1000000. On My TMS570LS04x launchpad that is after 10 ms.

    On HALCoGen tab <your microcontroller> : VIM RAM, that refers to rtiCompare0Interrupt

    That means that when counter RTI[0] reaches 10ms, rtiCompare0Interrupt() is called.

    HalCoGen creates a handler for that (and all other) intererrupt in notification.c

    (if you look in HALCoGen Help ->Help Topics,
    Contents  -> Examples -> example_rtiBlinky.c, 
    it is all explained)

  • Thanks

    Do you have  text file for debounce.c:

    Code is unrecognizable.

    Dragan Stanic

  • You can change the number type of the variable under the variable tab.  Right click under value and go to number format. You can change it to hex (or decimal) from there.

  • David,

    Displaying value as Hex works, but it displayed value stays 0x00 all the time even if I press the button, when according to code and LEDs obviously becomes 0x01. Should not it current displayed value be updated?

    Dragan

     

  • The trick is to set the youtube quality to HD (see image below).

    You can read the code in that resolution:

  • Do you have any optimization on?  If so, turn it off.

    It won't update the value as you are running.  You'd need to set a breakpoint when you read the switch, and the value should update after you step over that line of code.

  • Jan,

    What do you have in debounce.h? And , in code you attached here, Button Down is captured 10 mSec after the button bit went high, does it not mean it IS debounced?

    Second, I removed optimisation, but still no luck with watching live values!


    Thanks

  • Hi!
    I end up in this forum page while I have searched for a good example of how to use RTI. And I saw the problem raised here. So I thought that I may help with some ideas.

    First of all, in a embedded project, is not so good to use the "WHILE (1)" to something. It has to be leave it empty! Because it can take from the MCU's load. So, it is better to use a time base, for example an 10 msec. Then, with a multiplier of 10 (100 ms) is ok to read the button state. If after two readings, one after the other, the button readings are the same, you may change the button state to that.  I will try to load a whole project, but it is built for TMS570 MCU DK (MCU is TMS570LS20216SZWT). You will have only to "translate" the port(s) or other setting to your project...

  • So...

    With HALCoGen I generated the code:

    RTI->RTI1Compare: Comp.0Period: 10 (->10 msec);

    GIO-> PORTA: outputs - LED1 (A0), LED2 (A3); inputs - SW1 (B3), SW2 (B6)

    TMS570 -> VIM Channels 0-31 -> Channel 2 linked

    The rest of the code is in the next ZIP file.

    6064.te2.zip (updated)

    You may modify the values of

    #define NOTIF_BUTT_ON			2
    #define NOTIF_BUTT_OUT			3

    to which limits do you need.

    If you have questions...

  • Mihai

    Works fine.

    This time I was able to watch variable change state in debugger. So could I conclude that did not work earlier due to code in while (), processor had to work on?

    Thanks

    Dragan Stranic

  • Dragan,
    Actually is not a so big problem to put code in the "while" cycle. But in a "while" the code is executed one instruction after the other, in an infinite cycle, so the ecu has a 100% CPU load. Beside that you have no timing control, you do not know when is executed something.
    From my viewpoint in a real time os all the tasks has to be "under control". That is why it is better to not use code in the while cycle. Also I do recommend to not use too many while cycle neither. It is better to design an application with flags and states than use "while"s where the application could crash. The simplest example where an application can crash is when the application is waiting for an answer in a while, and the answer is not coming.

  • Hi, The example that I posted above has no itention to show the best approach for state machine design, also not to show good time and resource management. It's goal is to show how you can set up and drive GPIO pins and how you can configure an RTI interrupt in HALCoGen.
  • Mihai,

    Very good advice. Do you know some literature  or code examples to teach in deep on this manner of c programming?


    Thanks

    Dragan Stanic