/******************************************************************************!
* \file wiringPi.c
* \author Gordon Henderson
* \sa http://beaugrand.chez.com/
* \copyright GNU LGPLv3
* \note Not modified functions from :
https://github.com/WiringPi/WiringPi/blob/master/wiringPi/wiringPi.c
******************************************************************************/
/*
* wiringPi:
* Arduino look-a-like Wiring library for the Raspberry Pi
* Copyright (c) 2012-2017 Gordon Henderson
* Additional code for pwmSetClock by Chris Hall <chris@kchall.plus.com>
*
* Thanks to code samples from Gert Jan van Loo and the
* BCM2835 ARM Peripherals manual, however it's missing
* the clock section /grr/mutter/
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
#include <stddef.h>
#include <time.h>
#include <sys/time.h>
/*
* delay:
* Wait for some number of milliseconds
*********************************************************************************
*/
void delay(unsigned int howLong)
{
struct timespec sleeper, dummy;
sleeper.tv_sec = (time_t) (howLong / 1000);
sleeper.tv_nsec = (long) (howLong % 1000) * 1000000;
nanosleep(&sleeper, &dummy);
}
/*
* delayMicroseconds:
* This is somewhat intersting. It seems that on the Pi, a single call
* to nanosleep takes some 80 to 130 microseconds anyway, so while
* obeying the standards (may take longer), it's not always what we
* want!
*
* So what I'll do now is if the delay is less than 100uS we'll do it
* in a hard loop, watching a built-in counter on the ARM chip. This is
* somewhat sub-optimal in that it uses 100% CPU, something not an issue
* in a microcontroller, but under a multi-tasking, multi-user OS, it's
* wastefull, however we've no real choice )-:
*
* Plan B: It seems all might not be well with that plan, so changing it
* to use gettimeofday () and poll on that instead...
*********************************************************************************
*/
void delayMicrosecondsHard(unsigned int howLong)
{
struct timeval tNow, tLong, tEnd;
gettimeofday(&tNow, NULL);
tLong.tv_sec = howLong / 1000000;
tLong.tv_usec = howLong % 1000000;
timeradd(&tNow, &tLong, &tEnd);
while (timercmp(&tNow, &tEnd, <)) {
gettimeofday(&tNow, NULL);
}
}
void delayMicroseconds(unsigned int howLong)
{
struct timespec sleeper;
unsigned int uSecs = howLong % 1000000;
unsigned int wSecs = howLong / 1000000;
if (howLong == 0) {
return;
} else if (howLong < 100) {
delayMicrosecondsHard(howLong);
} else {
sleeper.tv_sec = wSecs;
sleeper.tv_nsec = (long) (uSecs * 1000L);
nanosleep(&sleeper, NULL);
}
}