chiark / gitweb /
Fixed a bug in the gpio readall command on model B's (caused by a side-effect
[wiringPi.git] / wiringPi / wiringPi.c
index 1e1cfe4fc9575d996678f7479da13851e67fe2e4..e7ae3863c7ca0fe6f5b66e08a833293965d9325b 100644 (file)
@@ -197,6 +197,39 @@ static volatile uint32_t *timer ;
 static volatile uint32_t *timerIrqRaw ;
 #endif
 
+
+// Data for use with the boardId functions.
+//     The order of entries here to correspond with the PI_MODEL_X
+//     and PI_VERSION_X defines in wiringPi.h
+//     Only intended for the gpio command - use at your own risk!
+
+const char *piModelNames [5] =
+{
+  "Unknown",
+  "Model A",
+  "Model B",
+  "Model B+",
+  "Compute Module",
+} ;
+
+const char *piRevisionNames [5] =
+{
+  "Unknown",
+  "1",
+  "1.1",
+  "1.2",
+  "2",
+} ;
+
+const char *piMakerNames [4] =
+{
+  "Unknown",
+  "Egoman",
+  "Sony",
+  "Qusda",
+} ;
+
+
 // Time for easy calculations
 
 static uint64_t epochMilli, epochMicro ;
@@ -334,10 +367,17 @@ static int physToGpioR2 [64] =
 
 // the P5 connector on the Rev 2 boards:
 
-                           -1, -1, -1, -1, -1, -1, -1,                 // ... 47
-  -1, -1, -1, -1, -1,                                                  // ... 52
-  28, 29, 30, 31,                                                      // ... 53, 54, 55, 56 - P5
-  -1, -1, -1, -1, -1, -1, -1,                                          // ... 63
+  -1, -1,
+  -1, -1,
+  -1, -1,
+  -1, -1,
+  -1, -1,
+  28, 29,
+  30, 31,
+  -1, -1,
+  -1, -1,
+  -1, -1,
+  -1, -1,
 } ;
 
 // gpioToGPFSEL:
@@ -559,26 +599,27 @@ int wiringPiFailure (int fatal, const char *message, ...)
 /*
  * piBoardRev:
  *     Return a number representing the hardware revision of the board.
- *     Revision is currently 1 or 2.
  *
- *     Much confusion here )-:
+ *     Revision 1 really means the early Model B's.
+ *     Revision 2 is everything else - it covers the B, B+ and CM.
+ *
  *     Seems there are some boards with 0000 in them (mistake in manufacture)
  *     So the distinction between boards that I can see is:
  *     0000 - Error
- *     0001 - Not used (Compute - default to Rev 2)
- *     0002 - Model B, Rev 1, 256MB
- *     0003 - Model B, Rev 1.1, 256MB, Fuses/D14 removed.
- *     0004 - Model B, Rev 2, 256MB, Sony
- *     0005 - Model B, Rev 2, 256MB, Qisda
- *     0006 - Model B, Rev 2, 256MB, Egoman
- *     0007 - Model A, Rev 2, 256MB, Egoman
- *     0008 - Model A, Rev 2, 256MB, Sony
- *     0009 - Model A, Rev 2, 256MB, Qisda
- *     000d - Model B, Rev 2, 512MB, Egoman
- *     000e - Model B, Rev 2, 512MB, Sony
- *     000f - Model B, Rev 2, 512MB, Qisda
- *     0010 - Model B+        512MB, Sony
- *     0011 - Pi compute Module
+ *     0001 - Not used 
+ *     0002 - Model B,  Rev 1,   256MB, Egoman
+ *     0003 - Model B,  Rev 1.1, 256MB, Egoman, Fuses/D14 removed.
+ *     0004 - Model B,  Rev 2,   256MB, Sony
+ *     0005 - Model B,  Rev 2,   256MB, Qisda
+ *     0006 - Model B,  Rev 2,   256MB, Egoman
+ *     0007 - Model A,  Rev 2,   256MB, Egoman
+ *     0008 - Model A,  Rev 2,   256MB, Sony
+ *     0009 - Model A,  Rev 2,   256MB, Qisda
+ *     000d - Model B,  Rev 2,   512MB, Egoman
+ *     000e - Model B,  Rev 2,   512MB, Sony
+ *     000f - Model B,  Rev 2,   512MB, Qisda
+ *     0010 - Model B+, Rev 1.2, 512MB, Sony
+ *     0011 - Pi CM,    Rev 1.2, 512MB, Sony
  *
  *     A small thorn is the olde style overvolting - that will add in
  *             1000000
@@ -604,7 +645,7 @@ int piBoardRev (void)
 {
   FILE *cpuFd ;
   char line [120] ;
-  char *c, lastChar ;
+  char *c ;
   static int  boardRev = -1 ;
 
   if (boardRev != -1)  // No point checking twice
@@ -622,12 +663,16 @@ int piBoardRev (void)
   if (strncmp (line, "Revision", 8) != 0)
     piBoardRevOops ("No \"Revision\" line") ;
 
+// Chomp trailing CR/NL
+
   for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c)
     *c = 0 ;
   
   if (wiringPiDebug)
     printf ("piboardRev: Revision string: %s\n", line) ;
 
+// Scan to first digit
+
   for (c = line ; *c ; ++c)
     if (isdigit (*c))
       break ;
@@ -635,6 +680,11 @@ int piBoardRev (void)
   if (!isdigit (*c))
     piBoardRevOops ("No numeric revision string") ;
 
+// Make sure its long enough
+
+  if (strlen (c) < 4)
+    piBoardRevOops ("Bogus \"Revision\" line (too small)") ;
+  
 // If you have overvolted the Pi, then it appears that the revision
 //     has 100000 added to it!
 
@@ -642,12 +692,14 @@ int piBoardRev (void)
     if (strlen (c) != 4)
       printf ("piboardRev: This Pi has/is overvolted!\n") ;
 
-  lastChar = line [strlen (line) - 1] ;
+// Isolate  last 4 characters:
+
+  c = c + strlen (c) - 4 ;
 
   if (wiringPiDebug)
-    printf ("piboardRev: lastChar is: '%c' (%d, 0x%02X)\n", lastChar, lastChar, lastChar) ;
+    printf ("piboardRev: last4Chars are: \"%s\"\n", c) ;
 
-  /**/ if ((lastChar == '2') || (lastChar == '3'))
+  if ( (strcmp (c, "0002") == 0) || (strcmp (c, "0003") == 0))
     boardRev = 1 ;
   else
     boardRev = 2 ;
@@ -663,32 +715,18 @@ int piBoardRev (void)
  * piBoardId:
  *     Do more digging into the board revision string as above, but return
  *     as much details as we can.
+ *     This is undocumented and really only intended for the GPIO command.
+ *     Use at your own risk!
  *********************************************************************************
  */
 
-const char *piModelNames [] =
-{
-  "Model A",
-  "Model B",
-  "Model B+",
-  "Compute Module",
-} ;
-
-const char *piRevisionNames[] =
-{
-  "1",
-  "1.1",
-  "2",
-  "1.2",
-} ;
-
-void piBoardId (int *model, int *rev, int *mem, char **maker)
+void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted)
 {
   FILE *cpuFd ;
   char line [120] ;
   char *c ;
 
-  piBoardRev () ;      // Call this first to make sure all's OK. Don't care about the result.
+  (void)piBoardRev () ;        // Call this first to make sure all's OK. Don't care about the result.
 
   if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL)
     piBoardRevOops ("Unable to open /proc/cpuinfo") ;
@@ -720,6 +758,10 @@ void piBoardId (int *model, int *rev, int *mem, char **maker)
 
   if (strlen (c) < 4)
     piBoardRevOops ("Bogus \"Revision\" line") ;
+
+// If longer than 4, we'll assume it's been overvolted
+
+  *overVolted = strlen (c) > 4 ;
   
 // Extract last 4 characters:
 
@@ -727,20 +769,20 @@ void piBoardId (int *model, int *rev, int *mem, char **maker)
 
 // Fill out the replys as appropriate
 
-  /**/ if (strcmp (c, "0002") == 0) { *model = 1 ; *rev = 0 ; *mem = 256 ; *maker = "China"  ; }
-  else if (strcmp (c, "0003") == 0) { *model = 1 ; *rev = 1 ; *mem = 256 ; *maker = "China"  ; }
-  else if (strcmp (c, "0004") == 0) { *model = 1 ; *rev = 2 ; *mem = 256 ; *maker = "Sony"   ; }
-  else if (strcmp (c, "0005") == 0) { *model = 1 ; *rev = 2 ; *mem = 256 ; *maker = "Qisda"  ; }
-  else if (strcmp (c, "0006") == 0) { *model = 1 ; *rev = 2 ; *mem = 256 ; *maker = "Egoman" ; }
-  else if (strcmp (c, "0007") == 0) { *model = 0 ; *rev = 2 ; *mem = 256 ; *maker = "Egoman" ; }
-  else if (strcmp (c, "0008") == 0) { *model = 0 ; *rev = 2 ; *mem = 256 ; *maker = "Sony"   ; }
-  else if (strcmp (c, "0009") == 0) { *model = 1 ; *rev = 2 ; *mem = 256 ; *maker = "Qisda"  ; }
-  else if (strcmp (c, "000d") == 0) { *model = 1 ; *rev = 2 ; *mem = 512 ; *maker = "Egoman" ; }
-  else if (strcmp (c, "000e") == 0) { *model = 1 ; *rev = 2 ; *mem = 512 ; *maker = "Sony"   ; }
-  else if (strcmp (c, "000f") == 0) { *model = 1 ; *rev = 2 ; *mem = 512 ; *maker = "Egoman" ; }
-  else if (strcmp (c, "0010") == 0) { *model = 2 ; *rev = 3 ; *mem = 512 ; *maker = "Sony"   ; }
-  else if (strcmp (c, "0011") == 0) { *model = 3 ; *rev = 1 ; *mem = 512 ; *maker = "Sony"   ; }
-  else                              { *model = 0 ; *rev = 0 ; *mem =   0 ; *maker = "Unkn"   ; }
+  /**/ if (strcmp (c, "0002") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_1   ; *mem = 256 ; *maker = PI_MAKER_EGOMAN ; }
+  else if (strcmp (c, "0003") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_1_1 ; *mem = 256 ; *maker = PI_MAKER_EGOMAN ; }
+  else if (strcmp (c, "0004") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 256 ; *maker = PI_MAKER_SONY   ; }
+  else if (strcmp (c, "0005") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 256 ; *maker = PI_MAKER_QISDA  ; }
+  else if (strcmp (c, "0006") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 256 ; *maker = PI_MAKER_EGOMAN ; }
+  else if (strcmp (c, "0007") == 0) { *model = PI_MODEL_A  ; *rev = PI_VERSION_2   ; *mem = 256 ; *maker = PI_MAKER_EGOMAN ; }
+  else if (strcmp (c, "0008") == 0) { *model = PI_MODEL_A  ; *rev = PI_VERSION_2   ; *mem = 256 ; *maker = PI_MAKER_SONY ; ; }
+  else if (strcmp (c, "0009") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 256 ; *maker = PI_MAKER_QISDA  ; }
+  else if (strcmp (c, "000d") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 512 ; *maker = PI_MAKER_EGOMAN ; }
+  else if (strcmp (c, "000e") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 512 ; *maker = PI_MAKER_SONY   ; }
+  else if (strcmp (c, "000f") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 512 ; *maker = PI_MAKER_EGOMAN ; }
+  else if (strcmp (c, "0010") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 512 ; *maker = PI_MAKER_SONY   ; }
+  else if (strcmp (c, "0011") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_2 ; *mem = 512 ; *maker = PI_MAKER_SONY   ; }
+  else                              { *model = 0           ; *rev = 0              ; *mem =   0 ; *maker = 0 ;               }
 }
  
 
@@ -1698,8 +1740,7 @@ int wiringPiSetup (void)
 {
   int   fd ;
   int   boardRev ;
-  int   model, rev, mem ;
-  char *maker ;
+  int   model, rev, mem, maker, overVolted ;
 
   if (getenv (ENV_DEBUG) != NULL)
     wiringPiDebug = TRUE ;
@@ -1775,7 +1816,7 @@ int wiringPiSetup (void)
 
 // If we're running on a compute module, then wiringPi pin numbers don't really many anything...
 
-  piBoardId (&model, &rev, &mem, &maker) ;
+  piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
   if (model == PI_MODEL_CM)
     wiringPiMode = WPI_MODE_GPIO ;
   else