Multiple SPI

With the ability to have the USART in (master) SPI mode, and with some of the larger Atmel chips having several of them, how does one go about having the various SPI libraries work with a different SPI port?

As far as I can tell, most (if not all) of the current libraries for devices using SPI, are all written to use the native SPI port. What if I want to use something on the USART port running as (master) SPI? Does that mean I'd have to hack the library and tell it to use a different port? And if so, is that all that needs to happen (besides the initial setup and enabling of that USART in SPI mode).

I realize this would disable the standard use of the UART itself on the 328(p) while it's in SPI mode, but if I don't need it anyway, it won't matter. Or if I'm using a different chip like the 1280/2560 which has four USARTs.

Is there a reason to not want to connect SCK, MISO, MOSI to all devices and just give each its own Slave Select? The chip still just has 1 8-bit bus internally, and only runs 1 instruction at a time.

LED strips only use MOSI and SCK. They don’t have slave select on them. Yes, I can gate the signal and still provide some level of selection. However, that doesn’t answer my original question. That’s what I’m after.

Case in point, on a project last year I ended up using a bit-bang method to address two separate LED strings on 4 digital pins, as opposed to using the SPI port because I needed to address each one separate. While I probably could’ve added a gate to control the string selection, by the time I figured out how to do that, I had already decided to just big-bang the thing and get it done. However, if I could’ve used the native SPI port on one string, and the USART in SPI mode on the second string, that would’ve probably been better, not to mention faster. That would also mean having to run two diferent versions of the same library, one for the SPI port and one for the other one - IF that’s really all it takes, and I don’t know that. Hence my question.

And as a continuation of my question: if there’s a way to make a current library work on a different port other than the native SPI port, will the native SPI port still continue to work for other devices?

I can't answer that, need a real software guy to answer.

The SPI library is quite simple (which is not a bad thing) and only supports the native SPI port. Writing a new library to operate the USART in SPI mode is a good idea, though! (hint hint).

What about using shiftOut()? Would that work with the LEDs?

KirAsh4: With the ability to have the USART in (master) SPI mode, and with some of the larger Atmel chips having several of them, how does one go about having the various SPI libraries work with a different SPI port?

Which SPI libraries?

Section 21.5 and 21.6 of the '328 data sheet show sample Initialization and transfer codes as functions.

“The following simple USART initialization code examples show one assembly and one C function that are equal in
functionality. The examples assume polling (no interrupts enabled). The baud rate is given as a function parameter.
For the assembly code, the baud rate parameter is assumed to be stored in the r17:r16 registers.”

void USART_Init( unsigned int baud )
{
UBRRn = 0;
/* Setting the XCKn port pin as output, enables master mode. */
XCKn_DDR |= (1<<XCKn);
/* Set MSPI mode of operation and SPI data mode 0. */
UCSRnC = (1<<UMSELn1)|(1<<UMSELn0)|(0<<UCPHAn)|(0<<UCPOLn);
/* Enable receiver and transmitter. */
UCSRnB = (1<<RXENn)|(1<<TXENn);
/* Set baud rate. */
/* IMPORTANT: The Baud Rate must be set after the transmitter is enabled
*/
UBRRn = baud;
}

"The following code examples show a simple USART in MSPIM mode transfer function based on polling of the Data
Register Empty (UDREn) Flag and the Receive Complete (RXCn) Flag. The USART has to be initialized before the
function can be used. For the assembly code, the data to be sent is assumed to be stored in Register R16 and the
data received will be available in the same register (R16) after the function returns.

The function simply waits for the transmit buffer to be empty by checking the UDREn Flag, before loading it with
new data to be transmitted. The function then waits for data to be present in the receive buffer by checking the
RXCn Flag, before reading the buffer and returning the value."

unsigned char USART_Receive( void )
{
/* Wait for empty transmit buffer */
while ( !( UCSRnA & (1<<UDREn)) );
/* Put data into buffer, sends the data */
UDRn = data;
/* Wait for data to be received */
while ( !(UCSRnA & (1<<RXCn)) );
/* Get and return received data from buffer */
return UDRn;
}

Could not a I2C/TWI handle this? Data and a clock with plenty of addresses (@Jack: Is that the shiftOut you refer to?).

Just wondering.

Near the bottom of this page is example code for the Arduino for using the USART in SPI master mode:

http://www.gammon.com.au/spi

CrossRoads:
Is there a reason to not want to connect SCK, MISO, MOSI to all devices and just give each its own Slave Select?
The chip still just has 1 8-bit bus internally, and only runs 1 instruction at a time.

If you were reading one file and writing another ‘at the same time’ then having them on different cards on different SPI buses would save time since both would stay open, selected and positioned all the time. On one bus, you read then close the file, deselect the SD, select the other SD, initialize, open file, seek, write, close, deselect, etc. You do a lot again and again just getting to where the card on the dedicated bus only has to do once.
If you only append-write one file to a card, it will not get shotgunned.
Instead of sorting, write ordered-link files or better yet have a PC do that and use the links in the sketch.

But when I saw the 2560 having 4 UARTs capable of MSPIM in the datasheet, I thought network. I think that Grumpy Mike (or AWOL?) remembers the Transputer and the Occam language. IIRC in 1985 the nodes were 8 MHz Von Neumann computers with 4 high speed serial links each. Only thing is that AVR’s are not Von Neumann, but Harvard architecture? However hard it’s proving, there is some effort to bring Occam to AVR (328’s). Occam would be a good path for interconnected 2560’s? They could have 64k RAM using external RAM. They’d have an SPI bus channel each, for SD of course. But what to do with it? Blink leds?

Back in the later 80’s I read of a Cal Tech machine made of 64 PC/XT mobos serial linked as a 6-dimension hypercube, 2^6=64. It had 1/10th the power of a CRAY but could do physics problems that formerly only CRAY-class computers could do.

I wonder how many 2560’s it would take to match my SEMPRON 2600 and mobo?

It would certainly be convenient to be able to access two SD card files separately, even if you had to use two slots to do it.

Dear Gammon,

Thanks for guiding us through your knowledge. I am working with Arduino Due and it has 2 SPI modes where I am able to use only one spi i.e.. SPI MODE0 and unable to access MODE1. I came to know that, USART as SPI is another SPI module in Due.

Due to complexity involved in 32 bit SAM3X8E Arm processor, i am unable to achieve this. Please guide me on how to use one of USART in Due as SPI.

Thanks in advance Omkar

AVR allows the same according to ATMega chip docs, but I don't know if we have a library for the hardware. Having hardware shift the bits in/out saves a constant load on the processor.

omkardokur:
Dear Gammon,

Thanks for guiding us through your knowledge.
I am working with Arduino Due …

This is a major thread necro, and I suggest you post this question in the Due section of the forum. I am not familiar with the Due hardware.

nickgammon: Near the bottom of this page is example code for the Arduino for using the USART in SPI master mode:

http://www.gammon.com.au/spi

I know this post is old but can you explain how/which serial port is selected to run in SPI master mode? For example I wish to make Serial1, not Serial0 SPI master mode on my 2650. That way I can continue to print out data/debugging on Serial0 while the sketch is running, and my SPI devices are running on the normal SPI port and the Serial1.

NaturallyAspirated: I know this post is old...

See reply #13. :) You should be looking at the Mega2560 UMSELn1:0: USART Mode Select register. You should be able to set the mode for either port independently. I assume you have already consulted the data sheet... :)

aarg:
See reply #13. :slight_smile: You should be looking at the Mega2560 UMSELn1:0: USART Mode Select register. You should be able to set the mode for either port independently. I assume you have already consulted the data sheet… :slight_smile:

Copy that I see it now, too many unknown abbreviations in the code for me to follow it. :frowning:

UCSR0C = _BV (UMSEL00) | _BV (UMSEL01);  // Master SPI mode

Changed to:

UCSR0C = _BV (UMSEL01) | _BV (UMSEL01);  // Master SPI mode

That’s it?

For the other UART, it would be UMSEL10 and UMSEL11.

It was close... I should get credit!