Index: EPRoxygen/at29c040.cpp
===================================================================
--- EPRoxygen/at29c040.cpp	(revision 34c57e88ff8ccc137eced9ad94274c9233a19d06)
+++ EPRoxygen/at29c040.cpp	(revision a6ae6ac6192a2c27497f1540f985610601159c41)
@@ -14,4 +14,5 @@
 	Device::write(CTRL, 0b10011111 | CTRLmask);
 	Device::write(VOLT, 0b11001000 | VOLTmask);
+	outb(port + 2, NONE);
 }
 
@@ -20,6 +21,6 @@
 	// All pins of the ROM are put either in high-Z, or 0V when it's not
 	// possible
-	Device::write(CTRL, 0x62);
-	Device::write(VOLT, 0x7F);
+	Device::write(CTRL, 0b01100010);
+	Device::write(VOLT, 0b01111111);
 	outb(port + 2, NONE);
 }
@@ -51,5 +52,5 @@
 {
 	// Chip enable
-	Device::write(CTRL, CTRLmask | CE);
+	Device::write(CTRL, CTRLmask | WE | OE | CE | A17);
 		// Address bits low, WE = 1, CE = 0, OE = 1
 		// TC and TD = 1
@@ -60,5 +61,5 @@
 
 	wr16(0x5555, 0xAA);
-	wr16(0x2AAA, 0x55);
+	wr16(0xAAAA, 0x55);
 	wr16(0x5555, 0x90);
 
@@ -70,22 +71,29 @@
 	// Read the result now
 	Device::write(ADR0, 0x00);
-	Device::write(ADR1, 0x00);
-	Device::write(CTRL, WE | CE | CTRLmask);
+			usleep(1000);
+	Device::write(ADR1, 0x00 ^ A13);
+			usleep(1000);
+	Device::write(CTRL, WE | A17 | CTRLmask);
+			usleep(1000);
 	uint8_t manufacturer = Device::read();
 
-	getchar();
 
-	Device::write(CTRL, OE | WE | CE | CTRLmask);
+	Device::write(CTRL, CE | OE | WE | A17 | CTRLmask);
+			usleep(1000);
 	Device::write(ADR0, 0x01);
-	Device::write(CTRL, WE | CE | CTRLmask);
+			usleep(1000);
+	Device::write(CTRL, WE | A17 | CTRLmask);
+			usleep(1000);
 
 	uint8_t product = Device::read();
 
+	Device::write(CTRL, CE | WE | OE | A17 | CTRLmask);
+			usleep(1000);
 	// re enable DOE, we are going to write again...
-	Device::write(CTRL, WE | OE | CE | CTRLmask);
 	Device::write(VOLT, VOLTmask);
+			usleep(1000);
 
 	wr16(0x5555, 0xAA);
-	wr16(0x2AAA, 0x55);
+	wr16(0xAAAA, 0x55);
 	wr16(0x5555, 0xF0);
 	usleep(10000);
@@ -93,4 +101,5 @@
 	// Chip disable - we're done !
 	Device::write(CTRL, 0xFF | CTRLmask);
+			usleep(1000);
 	
 	bool ok = (manufacturer == 0x1F && product == 0xA4);
Index: EPRoxygen/at29c040.h
===================================================================
--- EPRoxygen/at29c040.h	(revision 34c57e88ff8ccc137eced9ad94274c9233a19d06)
+++ EPRoxygen/at29c040.h	(revision a6ae6ac6192a2c27497f1540f985610601159c41)
@@ -17,12 +17,21 @@
 		inline void wr16(uint16_t addr, uint8_t val)
 		{
+			Device::write(CTRL, A17 | CE | WE | OE | CTRLmask);
+			usleep(10000);
+
+			Device::write(ADR1, (addr >> 8) ^ A13);
+			usleep(10000);
 			Device::write(ADR0, addr);
-			Device::write(ADR1, addr >> 8);
-
-			Device::write(CTRL, OE | CTRLmask); 
+			usleep(10000);
 
 			Device::write(DATA, val);
+			usleep(10000);
+			Device::write(CTRL, A17 | OE | CTRLmask); 
+			usleep(10000);
 
-			Device::write(CTRL, WE | OE | CTRLmask);
+printf("W %X %X", addr, val);
+getchar();
+			Device::write(CTRL, A17 | CE | WE | OE | CTRLmask);
+			usleep(10000);
 		}
 
Index: EPRoxygen/device.h
===================================================================
--- EPRoxygen/device.h	(revision 34c57e88ff8ccc137eced9ad94274c9233a19d06)
+++ EPRoxygen/device.h	(revision a6ae6ac6192a2c27497f1540f985610601159c41)
@@ -7,4 +7,5 @@
 #include <stdio.h>
 #include <stdint.h>
+#include <unistd.h>
 
 // FreeBSD
@@ -42,12 +43,12 @@
 	protected:
 		typedef enum {
-			NONE =  0b0101, /* Nothing selected */
-			NYBLE = 0b0010, /* Read low nyble */
+			NONE =  0b0011, /* Nothing selected */
+			NYBLE = 0b0100, /* Read low nyble */
 				/* When 0, status reg shows D0.3
 				 * When 1, status reg shows D4.7
 				 */
-			CTRL =  0b0011, /* Control reg. */
+			CTRL =  0b0101, /* Control reg. */
 				/* b0: A16
-				 * b1: /A17
+				 * b1: /A17 (A17 is reversed !)
 				 * b2: WE
 				 * b3: A18
@@ -71,8 +72,12 @@
 				 * b7: VCC enable (1 = power ON)
 				 */
-			ADR0 =  0b1011, /* Low address byte A0.7 */
+			ADR0 =  0b1101, /* Low address byte A0.7 */
 			DATA =  0b1110, /* Data byte */
 			ADR1 =  0b1111, /* High address byte A8.15 */
+				/* A13 is reversed ! (also used as VCC pin in smaller packages)
+				 */
 		} Register;
+
+		static const uint8_t A13 = 1 << 5;
 
 		typedef enum {
@@ -102,22 +107,37 @@
 		static inline void write(const Register reg, const uint8_t val)
 		{
-			// The register latches the data only when another register gets
-			// selected. If this is a problem, select the NONE reg after
-			// writing !
+			// To avoid glitches, first set the bits that select the register,
+			// then enable the output. And disable the output when we are done
+			// while not touching the selected reg. This is the only way to
+			// avoid glitches (another reg may be selected long enough for
+			// losing some bits)
+			outb(port, val);
+			usleep(1000);
+			outb(port + 2, reg ^ 4);
+			usleep(1000);
 			outb(port + 2, reg);
-			outb(port, val);
+			usleep(1000);
+			outb(port + 2, reg ^ 4);
+			usleep(1000);
 		}
 
 		static inline uint8_t read()
 		{
-			uint8_t byte = (inb(port + 1) ^ 0x80) & 0xF0;
+			outb(port+2, NYBLE ^ 4); 
+			usleep(1000);
+			uint8_t byte = inb(port + 1) & 0xF0;
 
 			outb(port+2, NYBLE); 
-			byte |= (inb(port + 1) ^ 0x80) >> 4;
-			return byte;
+			usleep(1000);
+			byte |= inb(port + 1) >> 4;
+printf("R %X", byte ^ 0x88);
+getchar();
+			outb(port+2, NYBLE ^ 4); 
+			usleep(1000);
+			return byte ^ 0x88;
 		}
 
+		static int port;
 	private:
-		static int port;
 };
 
