1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/ArduinoAm29F010B.cpp Sun Jan 18 19:48:44 2015 +0100
1.3 @@ -0,0 +1,191 @@
1.4 +const int CE = 1, OE = 2, WE = 3,
1.5 + CS1 = 4, CS2 = 5,
1.6 + DQ0 = 6, DQ1 = 7, DQ2 = 8, DQ3 = 9,
1.7 + DQ4 = 10, DQ5 = 11, DQ6 = 12, DQ7 = 13;
1.8 +
1.9 +const int BUFSIZE = 8;
1.10 +char buffer[BUFSIZE];
1.11 +
1.12 +int fromHex(char c)
1.13 +{
1.14 + if ((c >= 48) && (c <= 57))
1.15 + return c - 48;
1.16 + if ((c >= 65) && (c <= 70))
1.17 + return c - 65 + 10;
1.18 + if ((c >= 97) && (c <= 102))
1.19 + return c - 97 + 10;
1.20 + return 0;
1.21 +}
1.22 +
1.23 +void setDataOut()
1.24 +{
1.25 + pinMode(DQ0, OUTPUT);
1.26 + pinMode(DQ1, OUTPUT);
1.27 + pinMode(DQ2, OUTPUT);
1.28 + pinMode(DQ3, OUTPUT);
1.29 + pinMode(DQ4, OUTPUT);
1.30 + pinMode(DQ5, OUTPUT);
1.31 + pinMode(DQ6, OUTPUT);
1.32 + pinMode(DQ7, OUTPUT);
1.33 +}
1.34 +
1.35 +void setDataIn()
1.36 +{
1.37 + pinMode(DQ0, INPUT);
1.38 + pinMode(DQ1, INPUT);
1.39 + pinMode(DQ2, INPUT);
1.40 + pinMode(DQ3, INPUT);
1.41 + pinMode(DQ4, INPUT);
1.42 + pinMode(DQ5, INPUT);
1.43 + pinMode(DQ6, INPUT);
1.44 + pinMode(DQ7, INPUT);
1.45 +}
1.46 +
1.47 +int readData()
1.48 +{
1.49 + int i = DQ7;
1.50 + int data = 0;
1.51 +
1.52 + setDataIn();
1.53 + delayMicroseconds(1);
1.54 +
1.55 + while (1)
1.56 + {
1.57 + data += digitalRead(i);
1.58 + if (i == DQ0)
1.59 + break;
1.60 + i--;
1.61 + data <<= 1;
1.62 + }
1.63 +
1.64 + setDataOut();
1.65 + return data;
1.66 +}
1.67 +
1.68 +void writeData(int data)
1.69 +{
1.70 + int i = DQ0;
1.71 +
1.72 + while (1)
1.73 + {
1.74 + digitalWrite(i, data % 2);
1.75 + if (i == DQ7)
1.76 + break;
1.77 + i++;
1.78 + data >>= 1;
1.79 + }
1.80 +}
1.81 +
1.82 +void setAddress(int high, int low)
1.83 +{
1.84 + writeData(high);
1.85 + delayMicroseconds(1);
1.86 + digitalWrite(CS2, HIGH);
1.87 + delayMicroseconds(1);
1.88 + digitalWrite(CS2, LOW);
1.89 + writeData(low);
1.90 + delayMicroseconds(1);
1.91 + digitalWrite(CS1, HIGH);
1.92 + delayMicroseconds(1);
1.93 + digitalWrite(CS1, LOW);
1.94 +}
1.95 +
1.96 +int readOutput(int nread)
1.97 +{
1.98 + int high, low, data;
1.99 +
1.100 + if (nread < 5)
1.101 + return 0;
1.102 +
1.103 + high = (fromHex(buffer[1]) << 4) + (fromHex(buffer[2]));
1.104 + low = (fromHex(buffer[3]) << 4) + (fromHex(buffer[4]));
1.105 +
1.106 + setAddress(high, low);
1.107 + digitalWrite(OE, LOW);
1.108 + data = readData();
1.109 + digitalWrite(OE, HIGH);
1.110 +
1.111 + return data;
1.112 +}
1.113 +
1.114 +bool writeOutput(int nread)
1.115 +{
1.116 + int high, low, data;
1.117 +
1.118 + if (nread < 7)
1.119 + return false;
1.120 +
1.121 + high = (fromHex(buffer[1]) << 4) + (fromHex(buffer[2]));
1.122 + low = (fromHex(buffer[3]) << 4) + (fromHex(buffer[4]));
1.123 + data = (fromHex(buffer[5]) << 4) + (fromHex(buffer[6]));
1.124 +
1.125 + setAddress(high, low);
1.126 + digitalWrite(WE, LOW);
1.127 + writeData(data);
1.128 + digitalWrite(WE, HIGH);
1.129 +
1.130 + return true;
1.131 +}
1.132 +
1.133 +void setup()
1.134 +{
1.135 + int nread = 0;
1.136 +
1.137 + Serial.begin(115200);
1.138 + pinMode(CE, OUTPUT);
1.139 + pinMode(OE, OUTPUT);
1.140 + pinMode(WE, OUTPUT);
1.141 + pinMode(CS1, OUTPUT);
1.142 + pinMode(CS2, OUTPUT);
1.143 + setDataOut();
1.144 +
1.145 + // Initial state for the flash device.
1.146 +
1.147 + digitalWrite(CE, HIGH);
1.148 + digitalWrite(OE, HIGH);
1.149 + digitalWrite(WE, HIGH);
1.150 +
1.151 + // Initial state for the latches.
1.152 +
1.153 + digitalWrite(CS1, LOW);
1.154 + digitalWrite(CS2, LOW);
1.155 +
1.156 + // Interface loop.
1.157 +
1.158 + Serial.print("? ");
1.159 + Serial.setTimeout(3600000); // 1 hour
1.160 +
1.161 + while (nread = Serial.readBytesUntil('\n', buffer, BUFSIZE))
1.162 + {
1.163 + switch (buffer[0])
1.164 + {
1.165 + case 'R':
1.166 + Serial.println(readOutput(nread), HEX);
1.167 + break;
1.168 +
1.169 + case 'W':
1.170 + if (writeOutput(nread))
1.171 + Serial.println("Written.");
1.172 + else
1.173 + Serial.println("Command?");
1.174 + break;
1.175 +
1.176 + default:
1.177 + break;
1.178 + }
1.179 +
1.180 + Serial.print("? ");
1.181 + }
1.182 +
1.183 + Serial.println("Done.");
1.184 +}
1.185 +
1.186 +void loop()
1.187 +{
1.188 +}
1.189 +
1.190 +extern "C" void __cxa_pure_virtual(void) {
1.191 + while(1);
1.192 +}
1.193 +
1.194 +// tabstop=4 expandtab shiftwidth=4
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/Makefile Sun Jan 18 19:48:44 2015 +0100
2.3 @@ -0,0 +1,143 @@
2.4 +TARGET = $(notdir $(CURDIR))
2.5 +INSTALL_DIR = ../arduino-1.0.5
2.6 +PORT = /dev/ttyUSB0
2.7 +UPLOAD_RATE = 57600 # 19200
2.8 +AVRDUDE_PROGRAMMER = stk500v1
2.9 +MCU = atmega328p # atmega168
2.10 +F_CPU = 16000000
2.11 +
2.12 +EXTRA_SRC =
2.13 +EXTRA_CXXSRC =
2.14 +EXTRA_CINCS =
2.15 +EXTRA_CXXINCS =
2.16 +
2.17 +
2.18 +### Internal definitions.
2.19 +
2.20 +
2.21 +ARDUINO = $(INSTALL_DIR)/hardware/arduino/cores/arduino
2.22 +VARIANT = $(INSTALL_DIR)/hardware/arduino/variants/standard
2.23 +SRC = $(ARDUINO)/wiring.c \
2.24 + $(ARDUINO)/wiring_analog.c $(ARDUINO)/wiring_digital.c \
2.25 + $(ARDUINO)/wiring_pulse.c $(ARDUINO)/wiring_shift.c \
2.26 + $(ARDUINO)/WInterrupts.c $(EXTRA_SRC)
2.27 +CXXSRC = $(ARDUINO)/HardwareSerial.cpp $(ARDUINO)/WMath.cpp \
2.28 + $(ARDUINO)/Print.cpp $(ARDUINO)/WString.cpp \
2.29 + $(ARDUINO)/Stream.cpp $(EXTRA_CXXSRC)
2.30 +FORMAT = ihex
2.31 +
2.32 +# Name of this Makefile (used for "make depend").
2.33 +MAKEFILE = Makefile
2.34 +
2.35 +# Debugging format.
2.36 +# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
2.37 +# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
2.38 +DEBUG = stabs
2.39 +
2.40 +# Place -D or -U options here
2.41 +CDEFS = -DF_CPU=$(F_CPU)
2.42 +CXXDEFS = -DF_CPU=$(F_CPU)
2.43 +
2.44 +# Place -I options here
2.45 +CINCS = -I$(ARDUINO) -I$(VARIANT) $(EXTRA_CINCS)
2.46 +CXXINCS = -I$(ARDUINO) -I$(VARIANT) $(EXTRA_CXXINCS)
2.47 +
2.48 +# Compiler flag to set the C Standard level.
2.49 +# c89 - "ANSI" C
2.50 +# gnu89 - c89 plus GCC extensions
2.51 +# c99 - ISO C99 standard (not yet fully implemented)
2.52 +# gnu99 - c99 plus GCC extensions
2.53 +CSTANDARD = -std=gnu99
2.54 +CDEBUG = -g$(DEBUG)
2.55 +CWARN = -Wall -Wstrict-prototypes
2.56 +
2.57 +OPT = s
2.58 +
2.59 +CFLAGS = $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)
2.60 +CXXFLAGS = $(CXXDEFS) $(CXXINCS) -O$(OPT)
2.61 +LDFLAGS = -lm
2.62 +
2.63 +# Combine all necessary flags and optional flags.
2.64 +# Add target processor to flags.
2.65 +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
2.66 +ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS)
2.67 +
2.68 +# Programming support using avrdude. Settings and variables.
2.69 +AVRDUDE_PORT = $(PORT)
2.70 +AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex
2.71 +AVRDUDE_FLAGS = -V -F -C /etc/avrdude.conf \
2.72 + -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
2.73 + -b $(UPLOAD_RATE)
2.74 +
2.75 +# Program settings
2.76 +CC = avr-gcc
2.77 +CXX = avr-g++
2.78 +LD = avr-ld
2.79 +OBJCOPY = avr-objcopy
2.80 +OBJDUMP = avr-objdump
2.81 +AR = avr-ar
2.82 +SIZE = avr-size
2.83 +NM = avr-nm
2.84 +AVRDUDE = avrdude
2.85 +REMOVE = rm -f
2.86 +MV = mv -f
2.87 +
2.88 +# Define all object files.
2.89 +OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o)
2.90 +
2.91 +# Default target.
2.92 +all: applet_files build sizeafter
2.93 +
2.94 +build: elf hex
2.95 +
2.96 +applet_files: $(TARGET).cpp
2.97 + test -d applet || mkdir applet
2.98 + cat $(ARDUINO)/main.cpp > applet/$(TARGET).cpp
2.99 + cat $(TARGET).cpp >> applet/$(TARGET).cpp
2.100 +
2.101 +elf: applet/$(TARGET).elf
2.102 +hex: applet/$(TARGET).hex
2.103 +
2.104 +# Program the device.
2.105 +upload: applet/$(TARGET).hex
2.106 + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
2.107 +
2.108 +# Display size of file.
2.109 +HEXSIZE = $(SIZE) --target=$(FORMAT) applet/$(TARGET).hex
2.110 +ELFSIZE = $(SIZE) applet/$(TARGET).elf
2.111 +
2.112 +sizebefore:
2.113 + @if [ -f applet/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(HEXSIZE); echo; fi
2.114 +
2.115 +sizeafter:
2.116 + @if [ -f applet/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(HEXSIZE); echo; fi
2.117 +
2.118 +
2.119 +### File-specific processing.
2.120 +
2.121 +
2.122 +.SUFFIXES: .elf .hex .eep .lss .sym
2.123 +
2.124 +.elf.hex:
2.125 + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
2.126 +
2.127 +applet/$(TARGET).elf: applet/$(TARGET).cpp applet/core.a
2.128 + $(CXX) $(ALL_CXXFLAGS) -o $@ applet/$(TARGET).cpp -L. applet/core.a $(LDFLAGS)
2.129 +
2.130 +applet/core.a: $(OBJ)
2.131 + @for i in $(OBJ); do echo $(AR) rcs applet/core.a $$i; $(AR) rcs applet/core.a $$i; done
2.132 +
2.133 +# Compile: create object files from C++ source files.
2.134 +.cpp.o:
2.135 + $(CXX) -c $(ALL_CXXFLAGS) $< -o $@
2.136 +
2.137 +# Compile: create object files from C source files.
2.138 +.c.o:
2.139 + $(CC) -c $(ALL_CFLAGS) $< -o $@
2.140 +
2.141 +# Target: clean project.
2.142 +clean:
2.143 + $(REMOVE) applet/$(TARGET).hex applet/$(TARGET).elf applet/$(TARGET).cpp \
2.144 + applet/$(TARGET).map applet/core.a $(OBJ)
2.145 +
2.146 +.PHONY: all build elf hex eep lss sym program coff extcoff clean applet_files sizebefore sizeafter
3.1 --- a/README.txt Sun Jan 18 02:13:56 2015 +0100
3.2 +++ b/README.txt Sun Jan 18 19:48:44 2015 +0100
3.3 @@ -74,98 +74,50 @@
3.4 channel address and data via 8 common pins to latches, and then employ the
3.5 remaining pins to control the latches.
3.6
3.7 -Two pins can be used to select the latches:
3.8 -
3.9 -Pin A Pin B Latch select
3.10 ------ ----- ------------
3.11 -0 1 1
3.12 -1 0 2
3.13 -1 1 3
3.14 -
3.15 -Thus, the following logic is required:
3.16 -
3.17 -CP (latch 1) = ~A & B
3.18 -CP (latch 2) = A & ~B
3.19 -CP (latch 3) = A & B
3.20 -
3.21 -Selector (in) 74HC04 (NOT) 74HC08 (AND) Selector (out)
3.22 -------------- ------------ ------------ --------------
3.23 -A 1A (*)
3.24 - 1Y 1A
3.25 -B 1B (*)
3.26 - 1Y LS1
3.27 -A 2A (*)
3.28 -B 2A (*)
3.29 - 2Y 2B
3.30 - 2Y LS2
3.31 -A 3A (*)
3.32 -B 3B (*)
3.33 - 3Y LS3
3.34 -
3.35 -(*) Apply pull-down resistor to 74HC04 1A, 2A, 3A, 3B when driving using switches.
3.36 +Two pins can be used to select the latches, and when neither latch is
3.37 +selected, the data pins will be used to read or write data from the flash
3.38 +memory.
3.39
3.40 As a result, only 13 pins are needed on the Arduino.
3.41
3.42 -Arduino Selector 74HC273 #1 74HC273 #2 74HC273 #3 74HC4052N Am29F010B
3.43 -------- -------- ---------- ---------- ---------- --------- ---------
3.44 -1 CE#
3.45 -2 OE#
3.46 -3 WE#
3.47 -4 A
3.48 -5 B
3.49 - LS1 CP
3.50 - LS2 CP
3.51 - LS3 CP S0
3.52 -6 D0 (*) D0 (*) D0 (*) 1Z0 (#1)
3.53 -7 D1 (*) D1 (*) D1 (*) 2Z0 (#1)
3.54 -8 D2 (*) D2 (*) D2 (*) 1Z0 (#2)
3.55 -9 D3 (*) D3 (*) D3 (*) 2Z0 (#2)
3.56 -10 D4 (*) D4 (*) D4 (*) 1Z0 (#3)
3.57 -11 D5 (*) D5 (*) D5 (*) 2Z0 (#3)
3.58 -12 D6 (*) D6 (*) D6 (*) 1Z0 (#4)
3.59 -13 D7 (*) D7 (*) D7 (*) 2Z0 (#4)
3.60 - Q0 A0
3.61 - Q1 A1
3.62 - Q2 A2
3.63 - Q3 A3
3.64 - Q4 A4
3.65 - Q5 A5
3.66 - Q6 A6
3.67 - Q7 A7
3.68 - Q0 A8
3.69 - Q1 A9
3.70 - Q2 A10
3.71 - Q3 A11
3.72 - Q4 A12
3.73 - Q5 A13
3.74 - Q6 A14
3.75 - Q7 A15
3.76 -GND A16 (not used)
3.77 - Q0 1Z1 (#1)
3.78 - Q1 2Z1 (#1)
3.79 - Q2 1Z1 (#2)
3.80 - Q3 2Z1 (#2)
3.81 - Q4 1Z1 (#3)
3.82 - Q5 2Z1 (#3)
3.83 - Q6 1Z1 (#4)
3.84 - Q7 2Z1 (#4)
3.85 - 1Z (#1) DQ0
3.86 - 2Z (#1) DQ1
3.87 - 1Z (#2) DQ2
3.88 - 2Z (#2) DQ3
3.89 - 1Z (#3) DQ4
3.90 - 2Z (#3) DQ5
3.91 - 1Z (#4) DQ6
3.92 - 2Z (#4) DQ7
3.93 -5V MR# (**) MR# (**) MR# (**)
3.94 -GND E# (***)
3.95 -GND S0 (***)
3.96 -5V VCC VCC VCC VCC VCC VCC
3.97 -GND GND GND GND GND GND VSS
3.98 +Arduino 74HC273 #1 74HC273 #2 Am29F010B
3.99 +------- ---------- ---------- ---------
3.100 +1 CE#
3.101 +2 OE#
3.102 +3 WE#
3.103 +4 CP
3.104 +5 CP
3.105 +6 D0 (*) D0 (*) DQ0
3.106 +7 D1 (*) D1 (*) DQ1
3.107 +8 D2 (*) D2 (*) DQ2
3.108 +9 D3 (*) D3 (*) DQ3
3.109 +10 D4 (*) D4 (*) DQ4
3.110 +11 D5 (*) D5 (*) DQ5
3.111 +12 D6 (*) D6 (*) DQ6
3.112 +13 D7 (*) D7 (*) DQ7
3.113 + Q0 A0
3.114 + Q1 A1
3.115 + Q2 A2
3.116 + Q3 A3
3.117 + Q4 A4
3.118 + Q5 A5
3.119 + Q6 A6
3.120 + Q7 A7
3.121 + Q0 A8
3.122 + Q1 A9
3.123 + Q2 A10
3.124 + Q3 A11
3.125 + Q4 A12
3.126 + Q5 A13
3.127 + Q6 A14
3.128 + Q7 A15
3.129 +GND A16 (not used)
3.130 +5V MR# (**) MR# (**)
3.131 +5V VCC VCC VCC
3.132 +GND GND GND VSS
3.133
3.134 (*) Apply pull-down resistor to 74HC273 D inputs when driving using switches.
3.135 (**) Apply pull-up resistor to 74HC273 MR# inputs to preserve state.
3.136 -(***) Hold 74HC4052N lines low using pull-down resistors.
3.137
3.138 74HC273 Q outputs may initially be high and should be reset, either driving
3.139 MR# low or by explicitly latching values onto each device.
3.140 @@ -173,17 +125,25 @@
3.141 Set Address
3.142 -----------
3.143
3.144 -Selector A = 0; Selector B = 1; 74HC273 #1 D[7...0] = A[7...0]
3.145 -Selector A = 1; Selector B = 0; 74HC273 #2 D[7...0] = A[15...8]
3.146 +74HC273 #1 CP = 1; 74HC273 #2 CP = 0
3.147 +74HC273 #1 D[7...0] = A[7...0]
3.148 +74HC273 #1 CP = 0; 74HC273 #2 CP = 1
3.149 +74HC273 #2 D[7...0] = A[15...8]
3.150
3.151 Write Data
3.152 ----------
3.153
3.154 Configure pins as D[7...0]
3.155 -Selector A = 1; Selector B = 1; 74HC273 #3 D[7...0] = D[7...0]
3.156 +WE# = 0
3.157 +74HC273 #1 CP = 0; 74HC273 #2 CP = 0
3.158 +74HC273 #3 D[7...0] = D[7...0]
3.159 +WE# = 1
3.160
3.161 Read Data
3.162 ---------
3.163
3.164 Configure pins as Q[7...0]
3.165 -Selector A = 0; Selector B = 0; Q[7...0] = 74HC273 #0 Q[7...0]
3.166 +OE# = 0
3.167 +74HC273 #1 CP = 1; 74HC273 #2 CP = 0
3.168 +Q[7...0] = 74HC273 #0 Q[7...0]
3.169 +OE# = 1