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.

Toggle led code



Greetings 

I have a very basic program to toggle the led for every 100ms if switch 1 ( PW 4 ) is pressed 

other wise the led should remain on 

*Im sorry about the inconvenience caused by incomplete info, Will make things clearer from now (sorry, firstpost) *

The  entire code is here : 

// BranchingFunctionsDelays.c Lab 6
// Runs on LM4F120/TM4C123
// Use simple programming structures in C to
// toggle an LED while a button is pressed and
// turn the LED on when the button is released.
// This lab will use the hardware already built into the LaunchPad.
// Daniel Valvano, Jonathan Valvano
// January 15, 2016

// built-in connection: PF0 connected to negative logic momentary switch, SW2
// built-in connection: PF1 connected to red LED
// built-in connection: PF2 connected to blue LED
// built-in connection: PF3 connected to green LED
// built-in connection: PF4 connected to negative logic momentary switch, SW1

#include "TExaS.h"

#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
#define GPIO_PORTF_DIR_R (*((volatile unsigned long *)0x40025400))
#define GPIO_PORTF_AFSEL_R (*((volatile unsigned long *)0x40025420))
#define GPIO_PORTF_PUR_R (*((volatile unsigned long *)0x40025510))
#define GPIO_PORTF_DEN_R (*((volatile unsigned long *)0x4002551C))
#define GPIO_PORTF_AMSEL_R (*((volatile unsigned long *)0x40025528))
#define GPIO_PORTF_PCTL_R (*((volatile unsigned long *)0x4002552C))
#define SYSCTL_RCGC2_R (*((volatile unsigned long *)0x400FE108))
#define SYSCTL_RCGC2_GPIOF 0x00000020 // port F Clock Gating Control

// basic functions defined at end of startup.s
void DisableInterrupts(void); // Disable interrupts
void EnableInterrupts(void); // Enable interrupts

// function to delay for 100ms
void Delay100ms()
{
unsigned long i;
i = 1333333;
while(i > 0)
i = i - 1;
}
int main(void){ unsigned long volatile delay;
TExaS_Init(SW_PIN_PF4, LED_PIN_PF2); // activate grader and set system clock to 80 MHz
// initialization goes here
SYSCTL_RCGC2_R |= 0x00000020; // 1) activate clock for Port F
delay = SYSCTL_RCGC2_R; // allow time for clock to start
GPIO_PORTF_AMSEL_R = 0x00; // 3) disable analog on PF
GPIO_PORTF_PCTL_R = 0x40004050; // clear PF 4 n PF 2 clear pctl to set as GPIO
GPIO_PORTF_DIR_R = 0x04; // setting dir reg for PF4 - 0 n PF2 1
GPIO_PORTF_AFSEL_R = 0x00; // clear afsel for disabling alternate func
GPIO_PORTF_DEN_R = 0x14; // enable digital I/O on PF4 & PF2
GPIO_PORTF_PUR_R = 0x11; // enable pull-up on PF0 and PF4
GPIO_PORTF_DATA_R = 0X01; // set pf2 bit high for led to be on

EnableInterrupts(); // enable interrupts for the grader


while(1)
{


Delay100ms(1); // delay for 100ms
Delay100ms(1); // delay for 100ms
Delay100ms(1); // delay for 100ms
Delay100ms(1); // delay for 100ms
Delay100ms(1); // delay for 100ms
Delay100ms(1); // delay for 100ms
Delay100ms(1); // delay for 100ms
Delay100ms(1); // delay for 100ms
Delay100ms(1); // delay for 100ms

if (GPIO_PORTF_DATA_R ==0X00)
{
GPIO_PORTF_DATA_R ^= 0X04;

}
else
GPIO_PORTF_DATA_R = 0X04;




}

  • user4445231 said:
    if switch 1 ( PW 4 ) is pressed 

    You've a conflict in your identification of the Switch input!   (clearly - that's not good)   First "Switch 1" is labeled "PW4" - your code (only) tests Port F - how can that work?   (unless PW4 somehow translates to Port F - but that fact should be detailed w/in your post)
     
    Have you measured that (unidentified input pin) to confirm that switch actuation causes the full range of (legal) input voltage?   If the hardware proves incorrect - all the software in the world cannot rescue!

    Port F's set-up & configuration is not at all revealed in your (too brief) posting.   That's rather important - your presentation of such will aid your helpers.

    Beware that simple switches "bounce" and that your "read" may see many "highs & lows" unless a debounce routine is implemented.   Again - your (too brief) posting prevents our knowledge of, "All (even most) of the necessary facts."

  • User,

    I am not familiar with all aspects of the TM4C libraries so perhaps I am naïve in asking this question, but what is GPIO_PORTF_DATA_R? Is this a macro that you have defined to read the port? Is it simply pseudo code to explain your logic?

    None the less, how do you account for the bit packing within the port? i.e., is the switch on bit0, bit1, or... which bit? note that comparing the entire port value to 0 will not account for potential other bits on port such as the apparent bit2 used for the LED activation. i.e., if bit2 is a 1 to turn on the LED then the value on PORTF will never be 0 as CP1 alluded to.

    Also, when writing to the port, you need to account for the other bits in the port as well? Is it really you intention to set all of the other bits to 0 when writing a 1 to bit2?

    In general, I think you need to employ some level of masking or use the driver library functions to return specific bits on a port. Even with this approach you need to pay attention to which bit is used for what pin.
  • Chuck the DATA_R macros are part of the TIVAWare library and are (surprise!) the data registers associated with the ports.

    There are pin read and write functions as well that perform the masking as well as defines for each pin. Using the defines may well be useful.

    Original Poster said:
    During debugging it gives the following error msg

    Switch pressed test :

    - Not toggling fast enough. PF2 LED should toggle every 100ms.

    - Test FAILED

    That does not look like debugger output to me but rather something from a TDD environment. It would be unusual for a debugger to have support for something this specific.  Where does it come from?

    Robert

  • Thank you - this code listing is far more complete.

    We realize that your course makes (almost) exclusive use of the (highly) complex "DRM" method of coding. Forum reps and we outsiders find DRM so much harder & time consuming to fully understand & resolve.

    Instead - while your instructor rejects - this vendor provides a powerful "API" which is extensive, much more clear - and vitally, "Time Tested & Proven by thousands!" DRM - in contrast - demands endless manual page turning - to "hunt-out" the exact impact of a single Register bit.   The API - in contrast - automates much of that process.   DRM almost always proves an adventure - and if "hunting down" the impact of a single bit w/in a 32 bit Register is so critical - why would this vendor (and ALL others) have made critical investments in the API?    Really - what have you learned - what's been gained?  

    Review of the API source code & impact upon registers is infinitely more clear through study of the API - and immensely eased/speeded/enhanced by the segregation of MCU peripheral functions!   Nothing prevents you from using the API & MCU manual "TOGETHER" - to achieve the best of (both) worlds!

    As small tech business owner - never/ever would I authorize DRM unless under very special, tightly defined conditions. And then - only after we had all functions "working" - which provides a basis for "A-B" comparison.  (i.e. API vs. DRM)

    It's long been known here that pin "PF0" sets a trap - demands special handling (must first be unlocked) - yet your instructor forces that pin as your critical, Switch input!   That's unkind - is it not?   And while you "ran the clock" reviewing each/every candidate Register (demanded by the overly complex, DRM) - you must have "missed" the few warnings re: PF0! (and a brother pin - also locked)   Exclusive use of "DRM" (likely) exhausted - blinding you - to vendor's (not well highlighted) warnings?   (one wonders what else was "missed" due to endless page turning/hunting - necessitated by DRM)

    Rejecting a powerful and extensive API in favor of "bare-bones" (demanding ones - at that) is not welcome at most every small tech biz I know. Efficient problem solving is - and as you (and others, unfortunately) note - the "DRM only" method - demonstrated here - is not famed for quick (or great) success!

  • Robert,

    Thanks for the hint on the macros. That was my original thought, but when I searched the driver library and ROM user guides I didn't see anything about them. These should work provided proper masking is used to isolate the specific bits of interest.
  • cb1,

    100% agree with your points about using the APIs provided since they are tried/proven and trusted. However, If the point of this exercise is to learn more about bit mapping within registers and how to handle them (i.e., masking) then using the APIs would muddle the lesson and prevent the emphasis on one of the most important and basic aspects of embedded programming skills. i.e., how to handle bit operations without muddling the other content of the register/parameter.
  • Chuck Davenport said:
    If the point of this exercise is to learn more about bit mapping within registers and how to handle them (i.e., masking) then using the APIs would muddle the lesson and prevent the emphasis on one of the most important and basic aspects of embedded programming skills

    Chuck - while I respect your time & contributions here - your quote asserts (opinion) but is wholly silent as to justification to support those opinions!

    Let's detail:

    • learn about bit-mapping w/in Registers - As I wrote - nothing precludes users from using the API AND reviewing those Registers (featured) w/in the various API function calls.   In fact - as the API quickly/precisely identifies the "registers in question" - and details the specific bit handling required - (neither achieved w/in DRM - btw) the API (fully) exposes bit-mapping w/basic effort by (learning) users.   Further - the API most always "manages" Register "Sequences" if & when such sequencing is important.   DRM fails in this accord.   DRM method presents the "kitchen sink" of registers - does it not?   Thus unskilled/learning users are "unguided" must "weave thru a vast forest - w/out maps or signposts!"   To my - and my firm's mind - API is vastly superior in guiding & teaching about bit mapping w/in registers.
    • API's muddle the lesson.   Chuck - can you provide an example?   Firm/I completely disagree!   Does DRM identify the appropriate registers?  (API clearly does!)   Does DRM manage the proper sequencing of registers?   (API does!)  The API provides (as you yourself wrote) vast & expansive source code which details the (correct) register usage - not DRM's "hodge podge!"   Clearly it is DRM - not the API - which muddles!
    • prevent the emphasis upon most important aspects & skills of embedded - Really - you cannot be serious.   Are not Problem Solving, Efficiency, Mastering of MCU Peripherals etc. best learned by examining the API - choosing the most suitable API functions - and then running code and observing results?   Spending substantial time (blindly) thumbing thru pages & pages of Register listings - (hoping) to find the proper register(s) - what "emphasis" does that provide?  (beyond the destructive misuse of time/effort?)  Such emphasis is BEST achieved via the API in combination w/the (open) MCU manual - focused upon the (nicely) highlighted registers - clearly identified by the API!   That's (clearly) the best & proper "emphasis!"

    Is not the student/user's development of good "Investigative Techniques" vital to their success?   And a key aid to such success is the tried/true/tested API - and that's (completely) discarded - is it not?   Is it not clear that the DRM - NOT the API - prevents proper emphasis.

    Chuck - should you (really) believe that DRM is so advantaged - switch the forum to DRM only!   

  • cb1,

    I don't think I ever made reference to DRM. In fact, I am not really familiar with the term so its impossible for me to state if I am for against it.

    Also, I think you are reading far too much into my statement. Certainly the skills you mention regarding problem solving, investigating, learning, mastering of various standard peripherals, etc are of upper most importance. I never doubted this and believe these to be some of the basic attributes/skills need for embedded engineering specifically and with the wider Engineering community. My statement stands as written. Do you know any embedded project that has been done where the concept of masking is not used? Given this, why would one not consider the concept of masking a key to understanding effective embedded programming? Clearly, this is a stated opinion and doesn't require your agreement to remain as such.

    As you mentioned, this is all subject to opinion and everyone has one or two of them (especially embedded software folks!). I believe there is room for all types and opinions and thoughts on a public forum and the proof for each is in the results achieved.
  • Chuck,

    We must agree to disagree. You did state that the API "muddles the lesson" - and I am in high disagreement w/that statement. (and that statement stands (still) completely unsupported!)

    As for DRM - review of poster's revised code (per my request) shows it is entirely DRM based.

    You may note further - as regards "muddled lessons" - poster has (yet) to succeed via the (unmuddled) method you suggest. That's telling - is it not?