X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=wiringPi%2FwiringPi.c;h=bb22de6c1ddef8d31c2f7020d451c34b3d301767;hb=e8f6258004e59b1452806e5c45bb6598d0158dd2;hp=9655db25d705a292dc08608f12d54c3fa8d64f8b;hpb=db925cea180cf3f67ee13e0a5a0cd2fc9d3ce564;p=wiringPi.git diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 9655db2..bb22de6 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -51,9 +51,6 @@ // Added in the 2 UART pins // Change maxPins to numPins to more accurately reflect purpose -// Pad drive current fiddling - -#undef DEBUG_PADS #include #include @@ -68,15 +65,16 @@ #include #include #include -#include #include #include +#include #include "wiringPi.h" // Function stubs void (*pinMode) (int pin, int mode) ; +int (*getAlt) (int pin) ; void (*pullUpDnControl) (int pin, int pud) ; void (*digitalWrite) (int pin, int value) ; void (*digitalWriteByte) (int value) ; @@ -84,7 +82,6 @@ void (*pwmWrite) (int pin, int value) ; void (*setPadDrive) (int group, int value) ; int (*digitalRead) (int pin) ; int (*waitForInterrupt) (int pin, int mS) ; -void (*delayMicroseconds) (unsigned int howLong) ; void (*pwmSetMode) (int mode) ; void (*pwmSetRange) (unsigned int range) ; void (*pwmSetClock) (int divisor) ; @@ -177,7 +174,7 @@ static volatile uint32_t *timerIrqRaw ; // Time for easy calculations -static unsigned long long epoch ; +static uint64_t epochMilli, epochMicro ; // Misc @@ -586,6 +583,38 @@ void pinModeSys (int pin, int mode) } +/* + * getAlt: + * Returns the ALT bits for a given port. Only really of-use + * for the gpio readall command (I think) + ********************************************************************************* + */ + +int getAltGpio (int pin) +{ + int fSel, shift, alt ; + + pin &= 63 ; + + fSel = gpioToGPFSEL [pin] ; + shift = gpioToShift [pin] ; + + alt = (*(gpio + fSel) >> shift) & 7 ; + + return alt ; +} + +int getAltWPi (int pin) +{ + return getAltGpio (pinToGpio [pin & 63]) ; +} + +int getAltSys (int pin) +{ + return 0 ; +} + + /* * pwmControl: * Allow the user to control some of the PWM functions @@ -627,7 +656,7 @@ void pwmSetRangeSys (unsigned int range) void pwmSetClockWPi (int divisor) { - unsigned int pwm_control ; + uint32_t pwm_control ; divisor &= 4095 ; if (wiringPiDebug) @@ -811,10 +840,11 @@ void setPadDriveWPi (int group, int value) wrVal = BCM_PASSWORD | 0x18 | (value & 7) ; *(pads + group + 11) = wrVal ; -#ifdef DEBUG_PADS - printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ; - printf ("Read : %08X\n", *(pads + group + 11)) ; -#endif + if (wiringPiDebug) + { + printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ; + printf ("Read : %08X\n", *(pads + group + 11)) ; + } } void setPadDriveGpio (int group, int value) @@ -913,22 +943,12 @@ void pullUpDnControlSys (int pin, int pud) int waitForInterruptSys (int pin, int mS) { int fd, x ; - char buf [8] ; + uint8_t c ; struct pollfd polls ; if ((fd = sysFds [pin & 63]) == -1) return -2 ; -// Do a dummy read - - x = read (fd, buf, 6) ; - if (x < 0) - return x ; - -// And seek - - lseek (fd, 0, SEEK_SET) ; - // Setup poll structure polls.fd = fd ; @@ -936,7 +956,14 @@ int waitForInterruptSys (int pin, int mS) // Wait for it ... - return poll (&polls, 1, mS) ; + x = poll (&polls, 1, mS) ; + +// Do a dummy read to clear the interrupt +// A one character read appars to be enough. + + (void)read (fd, &c, 1) ; + + return x ; } int waitForInterruptWPi (int pin, int mS) @@ -986,6 +1013,8 @@ int wiringPiISR (int pin, int mode, void (*function)(void)) char *modeS ; char pinS [8] ; pid_t pid ; + int count, i ; + uint8_t c ; pin &= 63 ; @@ -1027,12 +1056,18 @@ int wiringPiISR (int pin, int mode, void (*function)(void)) } // Now pre-open the /sys/class node - it may already be open if -// we had set it up earlier, but this will do no harm. +// we are in Sys mode, but this will do no harm. sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; if ((sysFds [pin] = open (fName, O_RDWR)) < 0) return -1 ; +// Clear any initial pending interrupt + + ioctl (sysFds [pin], FIONREAD, &count) ; + for (i = 0 ; i < count ; ++i) + read (sysFds [pin], &c, 1) ; + isrFunctions [pin] = function ; pthread_create (&threadId, NULL, interruptHandler, &pin) ; @@ -1043,6 +1078,22 @@ int wiringPiISR (int pin, int mode, void (*function)(void)) } +/* + * initialiseEpoch: + * Initialise our start-of-time variable to be the current unix + * time in milliseconds. + ********************************************************************************* + */ + +static void initialiseEpoch (void) +{ + struct timeval tv ; + + gettimeofday (&tv, NULL) ; + epochMilli = (uint64_t)tv.tv_sec * (uint64_t)1000 + (uint64_t)(tv.tv_usec / 1000) ; + epochMicro = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)(tv.tv_usec) ; +} + /* * delay: * Wait for some number of milli seconds @@ -1078,28 +1129,8 @@ void delay (unsigned int howLong) ********************************************************************************* */ -void delayMicrosecondsSys (unsigned int howLong) -{ - struct timespec sleeper, dummy ; - - sleeper.tv_sec = 0 ; - sleeper.tv_nsec = (long)(howLong * 1000) ; - - nanosleep (&sleeper, &dummy) ; -} - void delayMicrosecondsHard (unsigned int howLong) { -#ifdef HARD_TIMER - volatile unsigned int dummy ; - - *(timer + TIMER_LOAD) = howLong ; - *(timer + TIMER_IRQ_CLR) = 0 ; - - dummy = *timerIrqRaw ; - while (dummy == 0) - dummy = *timerIrqRaw ; -#else struct timeval tNow, tLong, tEnd ; gettimeofday (&tNow, NULL) ; @@ -1109,10 +1140,9 @@ void delayMicrosecondsHard (unsigned int howLong) while (timercmp (&tNow, &tEnd, <)) gettimeofday (&tNow, NULL) ; -#endif } -void delayMicrosecondsWPi (unsigned int howLong) +void delayMicroseconds (unsigned int howLong) { struct timespec sleeper ; @@ -1138,13 +1168,30 @@ void delayMicrosecondsWPi (unsigned int howLong) unsigned int millis (void) { struct timeval tv ; - unsigned long long t1 ; + uint64_t now ; gettimeofday (&tv, NULL) ; + now = (uint64_t)tv.tv_sec * (uint64_t)1000 + (uint64_t)(tv.tv_usec / 1000) ; - t1 = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ; + return (uint32_t)(now - epochMilli) ; +} + + +/* + * micros: + * Return a number of microseconds as an unsigned int. + ********************************************************************************* + */ - return (uint32_t)(t1 - epoch) ; +unsigned int micros (void) +{ + struct timeval tv ; + uint64_t now ; + + gettimeofday (&tv, NULL) ; + now = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)tv.tv_usec ; + + return (uint32_t)(now - epochMicro) ; } @@ -1161,8 +1208,6 @@ int wiringPiSetup (void) { int fd ; int boardRev ; - //uint8_t *gpioMem, *pwmMem, *clkMem, *padsMem, *timerMem ; - struct timeval tv ; if (geteuid () != 0) { @@ -1180,6 +1225,7 @@ int wiringPiSetup (void) printf ("wiringPi: wiringPiSetup called\n") ; pinMode = pinModeWPi ; + getAlt = getAltWPi ; pullUpDnControl = pullUpDnControlWPi ; digitalWrite = digitalWriteWPi ; digitalWriteByte = digitalWriteByteGpio ; // Same code @@ -1187,7 +1233,6 @@ int wiringPiSetup (void) setPadDrive = setPadDriveWPi ; digitalRead = digitalReadWPi ; waitForInterrupt = waitForInterruptWPi ; - delayMicroseconds = delayMicrosecondsWPi ; pwmSetMode = pwmSetModeWPi ; pwmSetRange = pwmSetRangeWPi ; pwmSetClock = pwmSetClockWPi ; @@ -1268,11 +1313,6 @@ int wiringPiSetup (void) return -1 ; } -#ifdef DEBUG_PADS - printf ("Checking pads @ 0x%08X\n", (unsigned int)pads) ; - printf (" -> %08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ; -#endif - // The system timer timer = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_TIMER) ; @@ -1295,10 +1335,7 @@ int wiringPiSetup (void) *(timer + TIMER_PRE_DIV) = 0x00000F9 ; timerIrqRaw = timer + TIMER_IRQ_RAW ; -// Initialise our epoch for millis() - - gettimeofday (&tv, NULL) ; - epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ; + initialiseEpoch () ; wiringPiMode = WPI_MODE_PINS ; @@ -1332,6 +1369,7 @@ int wiringPiSetupGpio (void) printf ("wiringPi: wiringPiSetupGpio called\n") ; pinMode = pinModeGpio ; + getAlt = getAltGpio ; pullUpDnControl = pullUpDnControlGpio ; digitalWrite = digitalWriteGpio ; digitalWriteByte = digitalWriteByteGpio ; @@ -1339,7 +1377,6 @@ int wiringPiSetupGpio (void) setPadDrive = setPadDriveGpio ; digitalRead = digitalReadGpio ; waitForInterrupt = waitForInterruptGpio ; - delayMicroseconds = delayMicrosecondsWPi ; // Same pwmSetMode = pwmSetModeWPi ; pwmSetRange = pwmSetRangeWPi ; pwmSetClock = pwmSetClockWPi ; @@ -1363,7 +1400,6 @@ int wiringPiSetupSys (void) { int boardRev ; int pin ; - struct timeval tv ; char fName [128] ; if (getenv ("WIRINGPI_DEBUG") != NULL) @@ -1373,6 +1409,7 @@ int wiringPiSetupSys (void) printf ("wiringPi: wiringPiSetupSys called\n") ; pinMode = pinModeSys ; + getAlt = getAltSys ; pullUpDnControl = pullUpDnControlSys ; digitalWrite = digitalWriteSys ; digitalWriteByte = digitalWriteByteSys ; @@ -1380,7 +1417,6 @@ int wiringPiSetupSys (void) setPadDrive = setPadDriveSys ; digitalRead = digitalReadSys ; waitForInterrupt = waitForInterruptSys ; - delayMicroseconds = delayMicrosecondsSys ; pwmSetMode = pwmSetModeSys ; pwmSetRange = pwmSetRangeSys ; pwmSetClock = pwmSetClockSys ; @@ -1401,10 +1437,7 @@ int wiringPiSetupSys (void) sysFds [pin] = open (fName, O_RDWR) ; } -// Initialise the epoch for mills() ... - - gettimeofday (&tv, NULL) ; - epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ; + initialiseEpoch () ; wiringPiMode = WPI_MODE_GPIO_SYS ;