Using SPI with shift registers.

Good evening folks.

I'm currently using my SPI for my SD card, but also want to use it for a shift register (three chained actually) that I use for addressing a 512K SRAM. (So very slow at present).

The shift register is the latchless cd74hc164 chip.

So if I connect my serial pin to MOSI and my clock pin to SCK how do I configure CS into the mix? What would that even signify as it's not like the device itself can actually select? What would it's purpose actually be?

I'm not planning on using my SD card and shift register at the same time but I would want to disable input to the shift register while the SD card was active?

Any ideas folks?

Many thanks.

Chris

Connect SCK to all device clock pins.
Connect MISO to all device data out pins.
Connect MOSI to all device data in pins.

Use a separate Chip select for each device to enable & isolate its MISO output from the other devices so only one active device at a time is driving the Arduino MISO input.
If the devices are 3.3V powered, then use a part like cd74HC4050, powered from 3.3V, to buffer the SCK, MOSI, and chip select lines down to 3.3V levels.
If the devices are 3.3V powered, then use a part like ch74AC125 to enable the device data out onto the 5V MISO bus (Arduino input) when chip select is active low for that device.

In absence of output from my device can I just exclude that from it?

Everything is working at the same logic level.

I have some 245 transceivers I can use to isolate the output from the device onto the SPI bus.

The 245 is active low so I can use the output enable as chip select which would be analogous to a latch if I had one. Am I getting it?

When the shifter is latchless, I think a transceiver is the way to go.

I mean, I've expected the shift registers to have a latch pin; because this way doesn't matter if they shift out data for the SD card.
But, if they always output the bits even while shifting, then some way to block at least the SCK signal is required (the data line shouldn't influence as long as the clock line stays still).

Hi folks, thanks.

So I have hooked up my shift registers to the 256 transceivers and I am just trying to test the logic and I am not seeing any action on the SD card C/S - It is the Adafruit micro SD breakout board.

Both my shift registers (through the 245s) are switching low and high at the expected times (although I am not currently writing anything out just get).

See: arduino-sid-player/SpiShiftRegister.cpp at direct-register-addressing · Milesy/arduino-sid-player · GitHub

void SpiShiftRegister::enable() {
    SPI.beginTransaction(settings);
    
    volatile uint8_t *port = chipSelectPin->port; 
    *port &= ~_BV(chipSelectPin->physicalPin); // LOW
}

void SpiShiftRegister::disable() {
    volatile uint8_t *port = chipSelectPin->port;
    *port |= _BV(chipSelectPin->physicalPin); // HIGH
    SPI.endTransaction();
}

void SpiShiftRegister::write(long data) {
    enable();

    Serial.print("[");
    Serial.print(name);
    Serial.print("] ");
    
    Serial.print("Writing: ");
    Serial.print(data);
    Serial.print("\n");

    delay(500);
    
    delay(1);
    disable();
    delay(1);
}

I am reading in from the SD card byte by byte, and I am seeing my data being read in ok, and at present I am not writing anything at all onto the SPI bus, but I would expect to have seen something on the CS for SD card.

The SD class is here: arduino-sid-player/SdReader.cpp at direct-register-addressing · Milesy/arduino-sid-player · GitHub

At present I am connecting CS on the SD card into digital pin 10 and calling

initialised = SD.begin(chipSelectPin);

where the pin no is set to 10 within the main sketch.

I have also tried to connect it to the default SS pin and use no parameter to begin but that didn't work.

Is there something here I may be missing?

In the screenshot I have my third logic pin connected directly to C/S on the breakout board so it seems it is not receiving anything at all.

Logic Analysis 1

MISO goes into a flurry of activity when I first open the file, and C/S does remain low, but then it remains low forever more while I read those bytes in with file.available(); I had expected SPI transfers on a byte by byte basis, but it would seem apparent from the data out of the SD card that it buffers the file in (It is about 400Kb)

This explains why I was not seeing any activity at the time when I do my shift register writing.

How do I get it to go back high again? Do I need to do this manually some how? I tried setting SS high just before I called available() and all the byte values I got back were just 255.

It is a micro I have, and I have ran SD.begin(10) but I dont see any activity on pin 10, only on SS still. Any ideas?

Milesy:
I had expected SPI transfers on a byte by byte basis, but it would seem apparent from the data out of the SD card that it buffers the file in (It is about 400Kb)

It's actually 512 bytes (aka 1 sector). This buffer is called a "cache", it's always filled with data because it retains a copy (in RAM) of part of the card's content (and thus, the file's content).

This technique is used basically in everything you can call a "mass storage device", and it's purpose is to make small I/O operations more efficient.
The invention of the cache memory follows this philosophy: if sending or retrieving data takes a while, then why bothering with small transactions when you can do a big one for the same amount of time? This is specially true in write operations: an SD card takes the same amount of time writting a single byte or 512 at once.

In conclusion: you'll not see SPI activity after opening a file, until its "cursor" goes beyond the currently loaded block.
In that situation, you'll notice around 512 bytes transfered if the current block hasn't changed (maybe 1024 if it has to query the FAT or the cluster bitmap), 1024 if you just overwrite data, between 1536 and 4096 if the file is growing. If the file was opened for writting, invoking flush() may also trigger a transfer of between 1024 and 2048 bytes.

Milesy:
How do I get it to go back high again? Do I need to do this manually some how?

Sounds annoying, but if the libray doesn't want to do it; someone else has to.

Milesy:
I tried setting SS high just before I called available() and all the byte values I got back were just 255.

I (you) have to study a bit more the library, the input stream shouldn't return -1 (255 for a byte) if the end-of-file wasn't reached yet. Or maybe when the cache has to load new data, fails in the process because of the SD card ignoring the clock signal (due to CS being high).

Milesy:
and I have ran SD.begin(10) but I dont see any activity on pin 10

Shouldn't be like that. Again, we have to take a look at the library's source code; because such behaviors aren't explainable just yet (or at least for me).

PD 1: didn't realized before that you are "sort of" emulating a 6502 to interact with... a real SID chip from a real Commodore 64?. I bet it's a real one since you require two 8-bit shift registers (for the 16-bit address lines), and probably an entire port from the Arduino for the data lines (in that case I'll recommend port D since it's the only one where all physical pins are contiguous).

PD 2: by the way, the SPI library only can shift a minimum of 8 bits (due to hardware design), so to shift 19 bits you have to shift 24; otherwise bitbanging is your only option since by software you can shift any arbitrary number of bits.

Hello,

i have downloaded your 'arduino sid player library'.

Who can i find a circuit shematic for the needed circuit and a part list ?