Arduino controlling an Analog Device AD75019 16x16 crosspoint

I searched the net for some info on controlling the AD75019 with an Arduino but I can`t seem to find any specific guidance. The 75019 uses a serial write consisting of 256 bit data to represent the crosspoint on/off array. Once written the data is static. The crosspoint array has to be stored in the Arduino program. Any changes to the crosspoints are added to this array so that existing crosspoint status is rewritten along with the new crosspoint data.

I'm thinking of writing my own code to do this. Can the SPI library be used? The 75019 isn't specifically a SPI chip. Can the SPI bus write a 256 bit array in one write? Is it possible to interface this chip using the SPI library or would it be better just to write my own pin control to clock and write to the crosspoint?

Datasheet:

Data is loaded serially via the SIN input and clocked into an onboard 256-bit shift register via SCLK. When all the switch settings have been programmed, data is transferred into a set of 256 latches via PCLK. The serial shift register is dynamic, so there is a minimum clock rate of 20 kHz. The maximum clock rate of 5 MHz allows loading times as short as 52 ms. The switch control latches are static and will hold their data as long as power is applied.

It's a shift register. It has a serial input pin and a clock pin and a latch pin. You connect 3 digital lines on the microcontroller to SIN, SCLK, and PCLK on the AD chip. Then hold PCLK high. Use ShiftOut to send the data, 8 bits at a time. You will loop and call ShiftOut 32 times to send your data. Then pulse PCLK low and return it to high. End of story.

http://arduino.cc/en/Reference/ShiftOut

Thanks this helps. I played with some code samples a fair bit today. What sets the clock frequency? It seems what ever code I load the clock frequency stays about the same. I measure it at a period of 15 usec which works out to 66khz. Is this the max freq, or is there a setting that will generate a faster clock frequency?

What sets the clock frequency?

With shiftOut() you have no control over the clock frequency, it's just a software loop that runs as fast as it can.

Using hardware SPI I think you can get up to 4Mbps.

http://arduino.cc/en/Reference/SPI


Rob

Using hardware SPI I think you can get up to 4Mbps.

This gets back to my first question, can a non SPI chip be used to work with the SPI library? Is there a way to “fake” the SPI communications so that a chip like the AD95019 can be used? At this point it’s just curiosity as I can make do with a 66kHz clock, but faster would be nice.

Yes you can use a non-SPI chip to receive data sent using the SPI library.

The shiftOut function is poorly coded and needlessly slow. It's quite easy to write a faster one, but for the highest speeds, use hardware SPI.

While technically that chip is not "SPI" it looks compatible, the same applies to many chips. SPI is really just a shift register after all.

The differences are in this case that you do not use a CS signal and the latch signal should be a low pulse after the data has been loaded, many implementations use a high pulse.


Rob

Im using Arduino Uno to control HV2201 high voltage analog switch / controlled by the 8 bit shift register. But, from the datasheet, is said the HV2201 HAVE 20MHz data shift clock frequency. But, there seem some problem where I can control the switching correctly. My question is, do I need to change the clock frequency in SPI library to suit the 20MHz?

20MHz is just the maximum it can handle, anything less will work so that's not your problem.


Rob

Sorry for bumping this old thread, but it contains my exact question: what SPI tricks do I have to perform to get the AD75019 filled with SPI?

I have an array with 16 unsigned 16-bit integers in it, and the SPI reference tells me to use this sequence:

With most SPI devices, after SPI.beginTransaction(), you will write the slave select pin LOW, call SPI.transfer() any number of times to transfer data, then write the SS pin HIGH, and finally call SPI.endTransaction().

Which I converted to this code:

/**
 * Shift out 256 bits using the SPI library.
 */
void shiftMatrix(uint16_t patchMatrix[16]) {
    SPI.beginTransaction(SPISettings(20000000, MSBFIRST, SPI_MODE0));
    digitalWrite(SLAVESELECT, LOW);

    for (uint8_t y = 15; y > 0; y--) {
        SPI.transfer(patchMatrix[y]);
    }

    digitalWrite(SLAVESELECT, HIGH);
    SPI.endTransaction();
}

20000000 = 20MHz, the maximum the AD75019 can handle. The chip also wants X15/Y15 first, so I guess that's the most significant byte first and transfer from row 15 up to 0?

But then there's this post by Graynomad in this thread:

Graynomad: The differences are in this case that you do not use a CS signal and the latch signal should be a low pulse after the data has been loaded, many implementations use a high pulse.

SPI_MODE0 is probably completely wrong; but I can't figure out which one I do need; or if I need to trigger a latch myself.

Anybody here that uses this chip? Or can tell my how to fill it? Tnx!

SPI reference: https://www.arduino.cc/en/reference/SPI AD75019 datasheet: http://www.analog.com/media/en/technical-documentation/data-sheets/AD75019.pdf

I’d simplify it:
Chip has max clock speed of 5 MHz, default for SPI is 4 MHz, Mode 0, MSB First will work fine if that’s what your patchMatrix is set up with.
You seem to have an array of 16 ints to send out.
SPI.transfer sends 1 byte a time.
So:

for (x=0; x<16; x=x+1){
SPI.transfer(highByte(patchMatrix[x]); // or however you want to break up the int into bytes
SPI.transfer(lowByte(patchMatrix[x]);
}
// pulse PCLK LOW to parallel latches
digitalWrite (PCLK, LOW);
digitalWrite (PCLK, HIGH);

No need for SPI.begin & SPI.end if you are not freeing up the pins to use them for non-SPI functions. Usually hardware is pretty committed tho.

CrossRoads:
I’d simplify it:
Chip has max clock speed of 5 MHz, default for SPI is 4 MHz, Mode 0, MSB First will work fine if that’s what your patchMatrix is set up with.

patchMatrix is defined, and selectively filled like this:

uint16_t patchMatrix[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

// From and to are filled dynamically.
from = 10;
to = 5;
patchMatrix[to] += bit(from);

In the end, this is what patchMatrix could look like:

    R1  R2  R3  R4  R5  R6  R7  R8  R9  R10 R11 R12 R13 R14 R15 IN
 S1  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0  
 S2  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0  
 S3  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0  
 S4  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   1  
 S5  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0  
 S6  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0  
 S7  0   0   0   1   0   0   1   0   0   0   0   0   0   0   0   0  
 S8  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0  
 S9  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0  
S10  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0  
S11  0   0   0   0   0   0   0   0   0   0   0   0   1   0   1   0  
S12  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0  
S13  0   0   0   0   0   0   1   0   0   0   1   0   0   0   0   0  
S14  0   0   0   0   0   0   0   0   0   0   1   0   0   0   0   0  
S15  0   0   0   0   0   0   0   0   0   0   0   0   1   0   0   0  
OUT  0   0   0   0   0   0   0   0   0   0   0   0   0   1   0   0

Horizontal lines are a binary representation of the 16 integers stored in patchMatrix.

CrossRoads:
You seem to have an array of 16 ints to send out.
SPI.transfer sends 1 byte a time.
So:

for (x=0; x<16; x=x+1){

SPI.transfer(highByte(patchMatrix); // or however you want to break up the int into bytes
SPI.transfer(lowByte(patchMatrix);
}
// pulse PCLK LOW to parallel latches
digitalWrite (PCLK, LOW);
digitalWrite (PCLK, HIGH);

Cool! PCLK == SCK, or pin 13 on my UNO? And do I have to iterate patchMatrix in reverse?