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 get and pass a microsecond delay in tm4c123g, tivaware 2.1?

Hey guys, I am trying to pass a delay in micro seconds to the tiva tm4c123g processor vis SysCtlDelay();  I am trying to pass a 40 micro second delay using the function but then the processor enter the exception handler. What might be the reason for this? How can I pass micro second delays on tm4c? I need it to interface dht22 temp and humidity sensor???

  • Hello Keyshav

    Do you mean to say that the SysCtlDelay execution causes the device to enter the FaultISR? Or after the execution of the above the device enters the FaultISR.

    TivaWare examples have used SysCtlDelay for delays upto 1 second and never run into any such issue. I would ask you to step check the program flow via the IDE to see the offending function.
  • "Unguided posters" - once again - neglect to present their basic, failing code blocks - leading to wasted time/energy/space...
  • Actually sysctldelay works fine. The problem is I want to send a microsecond delay. But some how it doesn't accept it. Is there a way to pass such a delay? I believe sysctldelay send the delay in milliseconds


  • My documentation says loop iterations, where did you get milliseconds?

    Are you trying to pass a floating point value to SysCtlDelay? If you've not subverted the prototype that will just convert the floating point number to an integer (chopping off any value to the right of the decimal point). If you've subverted the prototype the result is probably determinable but undefined.

    Robert
  • Poster's code block would save time/effort by eliminating multiple, "Blind Alleys."
  • Hey Robert,

                            here is the code block which doesn't work

       #define DHT22  RHT03

       #define MY_PIN_PERIPH       SYSCTL_PERIPH_GPIOE

       #define MY_PIN_PORTBASE     GPIO_PORTE_BASE

       #define MY_PINNR            GPIO_PIN_3

       #define MCU_Clock           12500000

       #define MY_TIMER_PERIPH     SYSCTL_PERIPH_TIMER0

       #define MY_TIMERBASE        TIMER0_BASE

       #define MY_TIMER            TIMER_B

       #define MY_TIMEOUT          (MCU_Clock/4000)

       #define DHT_WAIT_40us       ((MCU_Clock*40)/1000000000000)

       #define DHT_WAIT_50us       ((MCU_Clock*50)/1000000000000)

       #define DHT_WAIT_70us       ((MCU_Clock*70)/1000000000000)

       #define DHT_WAIT_80us       ((MCU_Clock*80)/1000000000000)

       #define DHT_WAIT_90us       ((MCU_Clock*90)/1000000000000)

    To be noted : SysCtlClockGet(); returns a value of 12.5 MHz which I use to set all my future delays.

    Now this statement doesn't work and debug goes to exception handler and stays there forever.

    SysCtlDelay(DHT_WAIT_40us   );

    Now DHT_WAIT_40us means a 40 microsecond value. passing that hangs the code in a limbo.

    Question is: can I use such microsecond values in sysctl delay. if not , what are the alternatives. I am using a dht22 sensor and its data sheet requires a 40 us delay etc.

    Here is the data sheet, maybe you can suggest me some better ways to implement the delays.

    https://www.sparkfun.com/datasheets/Sensors/Temperature/DHT22.pdf

    Let me know if you want more code .

    Thank you for your patience :)

    Regards,

    Keyshav

  • Here is the data sheet, maybe you can suggest me some better ways to implement the delays.

    To be blunt - this is not a datasheet, but a heap of crap.

    In your place, I would try to contact the given e-mail address. Is the protocol SPI or SPI-like ? Isn't this 40us number not just a minimum ?

  • The opinion you share is same as mine. But unfortunately that is the only datasheet available on the web. its chinese. I expect no more from them. The 40 us may or may not be minimum. Nothing specified. What do you suggest/ Ever worked with this sensor before? It is a single wire sensor so a bit like SPI.
  • btw, the email adress is kaput. no mail gets delivered to it.as i said. its chinese. no reliablity
  • Keyshav Mor said:
    btw, the email adress is kaput. no mail gets delivered to it.as i said. its chinese. no reliablity

    Why I'm not surprised to hear that  ... ?
    If this is a commercial project, I would stop here and think (and better think twice).
    For a private/hobby project, I would just look elsewhere. Perhaps is this of any help for you: https://www.sparkfun.com/products/10167

    Just click on "Example code" under documents. For whatever reason this code comes as a M$-Word document is beyond me ...

  • f.m. is on point as usual, there is a point where even as a hobbyist it's best just to throw the thing out. For business that often comes earlier unless you have sufficient volume to justify the effort and to compel documentation from the supplier (at which point the more expensive alternatives may not be more expensive in any case)

    As far as your code goes, have you ever actually done this calculation?

    #define DHT_WAIT_40us ((MCU_Clock*40)/1000000000000)

    I think you've slipped in a few zeros. Also You haven't accounted for the actual time taken by the wait function (read the documentation).

    Robert
  • My contention in this case is not only the "crappiness" of the datasheet (form, data, spelling, ...), but the suspected incorrectness. That "40us" might just be a minimum, and can easily be replaced by, say, 400us or 1ms, very much easing the requirements for mentioned (troublesome) delay code. And for getting a peripheral part (like a sensor) up and running, I don't start with the specified minimum timing anyway.

    I would have no problem using discontinued part in my one-shot-private projects. I hope the O.P. is aware that chances for replacement might go to NIL. For a commercial project, I wouldn't consider it even for a moment...

  • For staters, the math is wrong:
    ((MCU_Clock*40)/1000000000000) is 0.0005, and who knows what will be passed to SysCtlDelay...

    I don't think the function crashes if you pass 0 (assuming the compiler will convert the result to integer...) - test it.

    Don't go too crazy doing maths or macros before you test something simple as SysCtlDelay(123456);

    Then, after you get your math sorted out, all your numbers would be off by a factor of 3, because SysCltDelay takes 3 clock cycles. So to still stick to your proposed solution, and with more readability, instead of

    #define MCU_Clock 12500000

    use something like

    #define MCU_ClockDiv3 12500000/3

    And only then use this on each of your calculated delay macros.

    Have fun!

    And yes, dump that sensor! Be brave, invest a few more cents on your development and use good quality stuff.
  • Bruno Saraiva said:
    I don't think the function crashes if you pass 0 (assuming the compiler will convert the result to integer...)

    I will be zero provided the prototype is in scope (if not there should be compiler warnings) or the compiler is broken

    Bruno Saraiva said:
    #define MCU_ClockDiv3 12500000/3

    Two things

    • The macro should be bracketed as a matter of course
    • The preprocessor will precompute constants so there is no performance loss even if you use floating point but that's probably not necessary if you watch your order of calculation.

    #define CLOCKS_PER_LOOP 3

    #define MCU_CLOCK 12500000

    #define MS_TO_LOOP_MACRO(ms) (((ms)*MCU_CLOCK)/(CLOCKS_PER_LOOP*1000))

    Note that this limits ms to INT_MAX/MCU_CLOCK before you have an overflow issue. You will need to check against that somewhere. If that is potentially an issue you can change to

    #define MS_TO_LOOP_MACRO(ms) ((int)(((ms)*(double)MCU_CLOCK)/(CLOCKS_PER_LOOP*1000.0)))

    This will reduce to a constant int value when ms is a constant (not const) but will have a floating operation or two if ms is a variable.

    Robert

    Those are untested macros, I may well have slipped a bracket or introduced a typo.

  • I'm with you and the only place I've ever seen these parts is on hobbyist web sites. Not something that build confidence.

    IIRC this is yet another one wire protocol so those width should have well defined min and max.

    However if you don't have and cannot get documentation, like you, I don't think I'd consider the part for any use. I really don't need additional challenges for enjoyment.

    Robert
  • Hey Robert and Bruno , Amit, cb1 and f.m. Thank You everyone for clearing this concept of mine. Now I seem to be getting a correct 2 second delay and that is a positive development for me as I am new to embedded systems.

    Now moving to system timings. Arduino has a function called millis(); which gives the value in milliseconds of the time since the CPU was started.

    Then I see something called SysTickValueGet() in the TIVA API.

    Are the above two functions similar in execution and principle?
  • Not really IMHO. Its not a delay function, but you could build one around it. And it obviously only millisecond resolution.

    It also conveys the impression that the sensor can be driven with a much slower timing than you are initially suggested (milliseconds instead of microseconds). Didn't try this myself, though.
    And I would put Arduino in the same category as this sensor ...

  • Keyshav,
    There is nothing in Tivaware that will give you milliseconds of system up time. The reason is quite simple: it would require a timer and accumulators to be running on the background, and it is USER's decision if he wants it or not (as opposed to those Lazuino things that think they know what user needs).
    If you want to count system up time, set up a timer to do it and do some simple maths. TM4C123x have 64bit timers, which I consider infinite (4874 years @ 120MHz, more than our products will last), hence it is very easy to enable a 64bit timer on the beginning, and simply read the content and divide it by system clock when you want to know the amount of seconds. As Robert so much likes and masters, it will be quite easy to write macros to easily read up time in seconds, milisseconds, parsecs or whatever unit you may wish.
    f.m., I agree with you and even started a discussion some time ago "against Lazuinos". But it is good to see that Keyshav is trying to free himself from that beast, ain't it?
    And finally, may I suggest that you don't keep different matters in one same thread, as it will be useless for others looking for the second subject in the future? New question? New thread, with a nice and clear title if possible!
    Cheers
    Bruno
  • f.m., I agree with you and even started a discussion some time ago "against Lazuinos". But it is good to see that Keyshav is trying to free himself from that beast, ain't it?
    And finally, may I suggest that you don't keep different matters in one same thread, as it will be useless for others looking for the second subject in the future? New question? New thread, with a nice and clear title if possible!

    I interpret the question about Arduino (or an Arduino function) as attempt of the O.P. to interpret some Arduino example code for this sensor, to reimplement within his (TivaWare based) project.

    That would make sense, and starting another thread would just complicate things...

  • My suggestion for a new thread is that, essentially, his recent post contains a new question: "How to keep Tiva system up time?".

    The Arduino function mentioned is just a reference, and at this point is not really the theme...

  • Okay lets just relax everybody. your inputs are worth its weight in gold. Yes f.m is right about my intentions. And yes arudino is lazyuino :P I will start a new thread. please help out there. The basic doubt here is get the system up time, maybe thorugh the Timer API or through anyother mechanism.