From 6d9a958907f6ce6889ba4d46aa1d33d94919709e Mon Sep 17 00:00:00 2001 From: Tom Nisbet Date: Sun, 11 Oct 2020 23:16:15 -0400 Subject: [PATCH] Add 74LS595 code to the HardwareVerify sketch --- HardwareVerify/PromAddressDriver.cpp | 74 ++++++++++++++-------------- HardwareVerify/PromAddressDriver.h | 2 - 2 files changed, 36 insertions(+), 40 deletions(-) diff --git a/HardwareVerify/PromAddressDriver.cpp b/HardwareVerify/PromAddressDriver.cpp index 4ba70c6..c350159 100644 --- a/HardwareVerify/PromAddressDriver.cpp +++ b/HardwareVerify/PromAddressDriver.cpp @@ -1,9 +1,28 @@ +// This controls the shift register that generates the address lines for A0..A15 for most +// chip families. +// +// Note that this uses direct port control instead of digitalWrite calls so that the code +// can run fast enough to meet the tBLC requirements for SDP and block writes. This +// sacrifices portability and readability for speed. +// +// This code will only work on Arduino Uno and Nano hardware. The ports for other +// Arduinos map to different IO pins. + #include "PromAddressDriver.h" #define ADDR_CLK_HI A3 #define ADDR_CLK_LO A4 #define ADDR_DATA A5 +// Define masks for the address clk and data lines on PC3..PC5 for direct port control. +#define ADDR_CLK_HI_MASK 0x08 +#define ADDR_CLK_LO_MASK 0x10 +#define ADDR_DATA_MASK 0x20 + +// When using the 74LS595 shift registers, the RCLK lines of both shift registers can be +// connected to D13 (PB5). +#define RCLK_595_MASK 0x20 + void PromAddressDriver::begin() { @@ -14,7 +33,7 @@ void PromAddressDriver::begin() digitalWrite(ADDR_DATA, LOW); digitalWrite(ADDR_CLK_LO, LOW); digitalWrite(ADDR_CLK_HI, LOW); - + DDRB |= RCLK_595_MASK; // Set D13 as output // To save time, the setAddress only writes the hi byte if it has changed. // The value used to detect the change is initialized to a non-zero value, @@ -33,50 +52,22 @@ void PromAddressDriver::setAddress(word address) if (hi != lastHi) { - setAddressRegisterDirect(ADDR_CLK_HI, hi); + setAddressRegister(ADDR_CLK_HI, hi); lastHi = hi; } - setAddressRegisterDirect(ADDR_CLK_LO, lo); + setAddressRegister(ADDR_CLK_LO, lo); } - // Shift an 8-bit value into one of the address shift registers. Note that // the data pins are tied together, selecting the high or low address register // is a matter of using the correct clock pin to shift the data in. void PromAddressDriver::setAddressRegister(uint8_t clkPin, byte addr) -{ - // Make sure the clock is low to start. - digitalWrite(clkPin, LOW); - - // Shift 8 bits in, starting with the MSB. - for (int ix = 0; (ix < 8); ix++) - { - // Set the data bit - if (addr & 0x80) - { - digitalWrite(ADDR_DATA, HIGH); - } - else - { - digitalWrite(ADDR_DATA, LOW); - } - - digitalWrite(clkPin, HIGH); // Clock in a bit - digitalWrite(clkPin, LOW); // Reset the clock pin - addr <<= 1; - } -} - -// Shift an 8-bit value into one of the address shift registers. Note that -// the data pins are tied together, selecting the high or low address register -// is a matter of using the correct clock pin to shift the data in. -void PromAddressDriver::setAddressRegisterDirect(uint8_t clkPin, byte addr) { byte mask = 0; - if (clkPin == A3) - mask = 0x08; - else if (clkPin == A4) - mask = 0x10; + if (clkPin == ADDR_CLK_HI) + mask = ADDR_CLK_HI_MASK; + else if (clkPin == ADDR_CLK_LO) + mask = ADDR_CLK_LO_MASK; // Make sure the clock is low to start. PORTC &= ~mask; @@ -87,11 +78,11 @@ void PromAddressDriver::setAddressRegisterDirect(uint8_t clkPin, byte addr) // Set the data bit if (addr & 0x80) { - PORTC |= 0x20; + PORTC |= ADDR_DATA_MASK; } else { - PORTC &= 0xdf; + PORTC &= ~ADDR_DATA_MASK; } // Toggle the clock high then low @@ -100,5 +91,12 @@ void PromAddressDriver::setAddressRegisterDirect(uint8_t clkPin, byte addr) PORTC &= ~mask; addr <<= 1; } -} + // Toggle the output latch for 74LS595 hardware. For the default TommyPROM hardware + // this just harmlessly writes to the D13 line that isn't connected to anything. + PORTB &= ~RCLK_595_MASK; + delayMicroseconds(1); + PORTB |= RCLK_595_MASK; + delayMicroseconds(1); + PORTB &= ~RCLK_595_MASK; +} diff --git a/HardwareVerify/PromAddressDriver.h b/HardwareVerify/PromAddressDriver.h index 89ec740..900ec91 100644 --- a/HardwareVerify/PromAddressDriver.h +++ b/HardwareVerify/PromAddressDriver.h @@ -10,9 +10,7 @@ class PromAddressDriver { private: static void setAddressRegister(uint8_t clkPin, byte addr); - static void setAddressRegisterDirect(uint8_t clkPin, byte addr); }; #endif // #define INCLUDE_PROM_ADDRESS_DRIVER_H -