Index: elua-svn/src/modules/pio.c
===================================================================
--- elua-svn.orig/src/modules/pio.c	2011-01-16 18:18:05.102154000 +0100
+++ elua-svn/src/modules/pio.c	2011-01-16 18:21:14.730154000 +0100
@@ -267,8 +267,55 @@
     if( key[ 2 ] == '\0' )
       isport = 1;
     else if( key[ 2 ] == '_' )      
+    {
       if( sscanf( key + 3, "%d%n", &pin, &sz ) != 1 || sz != strlen( key ) - 3 )
         return 0;      
+
+#ifdef ELUA_PLATFORM_AVR32
+      /* AVR32UC3A0 has a bizarre "port" called "PX" with 40 pins which map to
+       * random areas of hardware ports 2 and 3:
+       * PX00-PX10 = GPIO100-GPIO90	//Port 3 pins 04-00; port 2 pins 31-26
+       * PX11-PX14 = GPIO109-GPIO106	//Port 3 pins 13-10
+       * PX15-PX34 = GPIO89-GPIO70	//Port 2 pins 25-06
+       * PX35-PX39 = GPIO105-GPIO101	//Port 3 pins 09-05
+       * Then port = trunc(GPIO/32) and pin = GPIO % 32
+       *
+       * This "Port X" exists in EVK1100 and MIZAR32 but not on EVK1101, which
+       * only has ports A and B. On EXK1101, the PC and PX syntax will still be
+       * accepted but will return nil thanks to the checks against NUM_PIO.
+       */
+
+      // Disallow "PC_06-PC_31" as aliases for PX pins
+      if (key[1] == 'C' && pin > 5)
+	return 0;
+
+      // Disallow "PD_nn" as aliases for PX pins
+      if (key[1] == 'D')
+	return 0;
+
+      // Map PX pins 00-39 to their ports/pins in the hardware register layout.
+      if (key[1] == 'X')
+      {
+	unsigned gpio;
+
+	// You cannot perform port operations on port X because it
+	// doesn't exist in hardware.
+	if (pin == 0xFFFF)
+	  return 0;
+
+	// Map PX pin numbers to GPIO pin numbers
+	if( pin < 0 ) return 0;
+	if( pin <= 10 ) gpio = 100 - pin;
+	else if( pin <= 14 ) gpio = 109 - (pin - 11);
+	else if( pin <= 34 ) gpio = 89 - (pin - 15);
+	else if( pin <= 39 ) gpio = 105 - (pin - 35);
+	else return 0;
+
+	port = gpio >> 5;
+	pin = gpio & 0x1F;
+      }
+#endif
+    }
   }
   else // P0, P1, ...
   {
Index: elua-svn/src/platform/avr32/EVK1100/evk1100_conf.h
===================================================================
--- elua-svn.orig/src/platform/avr32/EVK1100/evk1100_conf.h	2011-01-16 18:18:05.186154000 +0100
+++ elua-svn/src/platform/avr32/EVK1100/evk1100_conf.h	2011-01-16 18:21:14.730154000 +0100
@@ -88,7 +88,7 @@
 #define VTMR_FREQ_HZ          4
 
 // Number of resources (0 if not available/not implemented)
-#define NUM_PIO               5
+#define NUM_PIO               4
 #define NUM_SPI               8
 #define NUM_UART              4
 #if VTMR_NUM_TIMERS > 0
@@ -125,7 +125,7 @@
 // #define PIO_PINS_PER_PORT (n) if each port has the same number of pins, or
 // #define PIO_PIN_ARRAY { n1, n2, ... } to define pins per port in an array
 // Use #define PIO_PINS_PER_PORT 0 if this isn't needed
-#define PIO_PIN_ARRAY         { 31, 32, 6, 32, 8 }
+#define PIO_PIN_ARRAY         { 31, 32, 32, 14 }
 
 // Allocator data: define your free memory zones here in two arrays
 // (start address and end address)
Index: elua-svn/src/platform/avr32/EVK1101/evk1101_conf.h
===================================================================
--- elua-svn.orig/src/platform/avr32/EVK1101/evk1101_conf.h	2011-01-16 18:18:05.146154000 +0100
+++ elua-svn/src/platform/avr32/EVK1101/evk1101_conf.h	2011-01-16 18:21:14.734154000 +0100
@@ -107,7 +107,7 @@
 // #define PIO_PINS_PER_PORT (n) if each port has the same number of pins, or
 // #define PIO_PIN_ARRAY { n1, n2, ... } to define pins per port in an array
 // Use #define PIO_PINS_PER_PORT 0 if this isn't needed
-#define PIO_PIN_ARRAY         { 31, 11 }
+#define PIO_PIN_ARRAY         { 32, 12 }
 
 // Allocator data: define your free memory zones here in two arrays
 // (start address and end address)
Index: elua-svn/src/platform/avr32/platform.c
===================================================================
--- elua-svn.orig/src/platform/avr32/platform.c	2011-01-16 18:18:05.122154000 +0100
+++ elua-svn/src/platform/avr32/platform.c	2011-01-16 18:21:14.734154000 +0100
@@ -181,33 +181,6 @@
 // ****************************************************************************
 // PIO functions
 
-/* Note about AVR32 GPIO
-PIOs on AVR32 are a weird deal. They aren't really organized in ports, but 
-rather they are numbered from 0 to a maximum number (which also give the total
-number of GPIOs in the system) then you do operations on that pin number. 
-We need to organize this in ports though, so here's our organization:
-PA: 31 bits, direct mapping to AVR GPIO0 ... GPIO30
-PB: 32 bits, direct mapping to AVR GPIO32 ... GPIO63
-PC: 6 bits, direct mapping to AVR GPIO64 ... GPIO69
-PX: this is where all hell breaks loose. PX seems to be a quite random mapping
-between the rest of the GPIOs and some "port" that has 40 bits and a very 
-imaginative mapping to the GPIOs (PX0 is GPIO100, PX1 is GPIO99, PX2 is GPIO98 ...
-and PX11 is GPIO109, just to give a few examples). So let's make some sense out of
-this. We define two pseudo ports: a 32 bits one (GPIO70-GPIO101) and an 8 bits one 
-(GPIO102-GPIO109).
-PD: 32 bits, GPIO70-GPIO101
-PE:  8 bits, GPIO102-GPIO109
-(note that GPIO32 doesn't seem to exist at all in the system).
-Beceause these are pseudo-ports, operations on them will be slower than operation
-on the hardware ports (PA, PB, PC).
-*/
-
-// Port data
-#define PA            0
-#define PB            1
-#define PC            2
-#define PD            3
-#define PE            4
 // Reg types for our helper function
 #define PIO_REG_PVR   0
 #define PIO_REG_OVR   1
@@ -242,32 +215,9 @@
 // Helper function: get port value, get direction, get pullup, ...
 static pio_type platform_pio_get_port_reg( unsigned port, int reg )
 {
-  pio_type v;
   volatile unsigned long *pv = platform_pio_get_port_reg_addr( port, reg );
   
-  switch( port )
-  {
-    case PA:   // PA - 31 bits
-      return *pv & 0x7FFFFFFF;
-      
-    case PB:   // PB - 32 bits
-      return *pv;
-      
-    case PC:   // PC - 6 bits
-      return *pv & 0x3F;      
-      
-    case PD:   // PD - pseudo port (70-101, has 26 bits on P2 and 6 bits on P3)
-      pv = platform_pio_get_port_reg_addr( 2, reg );
-      v = ( *pv & 0xFFFFFFC0 ) >> 6;
-      pv = platform_pio_get_port_reg_addr( 3, reg );
-      return ( ( *pv & 0x3F ) << 26 ) | v;
-      
-    case PE:   // PE - pseudo port (102-109, 8 bits on P3)
-      pv = platform_pio_get_port_reg_addr( 3, reg );
-      return ( *pv & 0x3FC0 ) >> 6;
-  }
-  // Will never get here
-  return 0;
+  return *pv;
 }
 
 // Helper function: set port value, set direction, set pullup ...
@@ -275,32 +225,7 @@
 {
   volatile unsigned long *pv = platform_pio_get_port_reg_addr( port, reg );
     
-  switch( port )
-  {
-    case PA:   // PA - 31 bits
-      *pv = val & 0x7FFFFFFF;
-      break;
-            
-    case PB:   // PB - 32 bits
-      *pv = val;
-      break;
-      
-    case PC:   // PC - 6 bits
-      *pv = ( *pv & ~0x3F ) | ( val & 0x3F );
-      break;
-      
-    case PD:  // PD - pseudo port (70-101, has 26 bits on P2 and 6 bits on P3)
-      pv = platform_pio_get_port_reg_addr( 2, reg );
-      *pv = ( *pv & ~0xFFFFFFC0 ) | ( val << 6 );
-      pv = platform_pio_get_port_reg_addr( 3, reg );
-      *pv = ( *pv & ~0x3F ) | ( val >> 26 );
-      break;
-    
-    case PE:  // PE - pseudo port (102-109, 8 bits on P3)
-      pv = platform_pio_get_port_reg_addr( 3, reg );
-      *pv = ( *pv & ~0x3FC0 ) | ( ( val & 0xFF ) << 6 );   
-      break;
-  }
+  *pv = val;
 }
 
 pio_type platform_pio_op( unsigned port, pio_type pinmask, int op )
