Assign communication SPI in another pins Arduino mega 2560?

Good day, i want to know if is possible assign SPI in another pins to communicate with SD module and use the originals pins SPI to communicate for example a GLCD 128x64 the two devices separately, thanks

SPI comes from dedicated internal hardware, so it can't be re-assigned. You can do things like add wires from the 50-51-52 (or 51-52-53) pins to other pins to access them, and treat the new pins as inputs only in the sketch so there is no interference.

You would connect the two displays in parallel to MISO-MOSI-SCK and send data to one or the other using separate slave select for each one.

With a 2560, you can also use the USART as SPI, so you can have 2 SPI ports. I don't know if there is a library for this.

"22. USART in SPI Mode The Universal Synchronous and Asynchronous serial Receiver and Transmitter (USART) can be set to a master SPI compliant mode of operation. The Master SPI Mode (MSPIM) has the following features: • Full Duplex, Three-wire Synchronous Data Transfer • Master Operation • Supports all four SPI Modes of Operation (Mode 0, 1, 2, and 3) • LSB First or MSB First Data Transfer (Configurable Data Order) • Queued Operation (Double Buffered) • High Resolution Baud Rate Generator • High Speed Operation (fXCKmax = fCK/2) • Flexible Interrupt Generation 22.1 Overview Setting both UMSELn1:0 bits to one enables the USART in MSPIM logic. In this mode of operation the SPI master control logic takes direct control over the USART resources. These resources include the transmitter and receiver shift register and buffers, and the baud rate generator. The parity generator and checker, the data and clock recovery logic, and the RX and TX control logic is disabled. The USART RX and TX control logic is replaced by a common SPI transfer control logic. However, the pin control logic and interrupt generation logic is identical in both modes of operation. The I/O register locations are the same in both modes. However, some of the functionality of the control registers changes when using MSPIM."

Ok, for Anyone like me who happens to stumble upon this post…

the atmega 2560 can run the USARTS as SPI,
However, … the clock pins (XCKn) are not connected in the mega 2560 r3, see:


So, out of the box… it simply wont work.

BUT!.. take a look at digital pin 38, (pin #50, (PD7) at the corner of the chip), it is only 1 pin away from the XCK1 pin (#48 (PD5)).

NOTE that you can JUST BRIDGE THE 3 PINS TOGETHER (#48,#49#50) without cutting anything, however you need to make sure that the pins 49(PD6) and 50(PD7) are always defined as inputs :
DDRD |= (0 << PD6)|(0<<PD7); //sets pins as inputs
The pins are Inputs by default anyway,
BEWARE though, if any of the PD5, PD6 or PD7 is defined as output and low while any other is high, it will short them!

If one are careful enough, a razor blade can be used to cut the 49 and 50 pins (from the chip) and then bridge (solder) the XCK1 pin (PD5) (#48 on the chip) to the digital pin 38 (where the #50 was).Actually, it turned out to be super easy to do.

Now one can use the USART1 in SPI master mode.:
SCK is pin 38, MOSI is TX1 (pin18), MISO is RX1(Pin 19)

For the newbies out there (like me)… here is how to do it:
Start by downloading that scary datasheet:

In page 230 there is an C Examplefor setting up the USART as SPI:
(IT WON’T WORK out of the box):

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;
}

When you go and copy the example to your arduino sketch IT WON’T WORK :D, 2 reasons:
first, we need to replace the n’s with 1, because we are using the USART1.
Second, XCK1_DDR, XCK1,UCPHA1 are not #defined at all in the arduino header files.
third: the UDORD1 pin can also be configured… read section 23.6.4 (Page 235) it’ll make sense.

From the Pinnout we get: XCK1_DDR = DDRD , and XCK1 is PD5,
and from the section 23.6.4 (Page 235) we get that UCPHA1 = 1, and UDORD1 = 2
SO: the working CODE is:

#define XCK1_DDR DDRD
#define XCK1 PD5
#define UCPHA1 1
#define UDORD1 2
void SPI1_Init( unsigned int ubrr )
{
//DDRD |= (0 << PD6)|(0<<PD7); //set pins to input (if bridged)
UBRR1 = 0;
/* Setting the XCKn port pin as output, enables master mode. /
XCK1_DDR |= (1 << XCK1);
/
Set MSPI mode of operation and SPI data mode 2., MSB first /
UCSR1C = (1 << UMSEL11) | (1 << UMSEL10) | (0 << UDORD1) | (0 << UCPHA1) | (1 << UCPOL1);
/see section 23.6.4 on page 235./
/
Enable receiver and transmitter. /
UCSR1B = (1 << RXEN1) | (1 << TXEN1);
/
Set baud rate. /
/
IMPORTANT: The Baud Rate must be set after the transmitter is
enabled /
UBRR1 = ubrr; /
see table 22-12 in page 226 for UBRRn values, (U2Xn=0, synchronous), the actual BAUD is calculated according to the formula in Table 23-1. on page 228, :/
//UBRR1=fOSC/(2
baud)-1; //, and use baud instead of ubrr as parameter
}

There is also an example to transfer data on page 232, it is also broken, use:

void SPI1_Send( char data )
{
/* Wait for empty transmit buffer /
while ( !( UCSR1A & (1 << UDRE1)) );
/
Put data into buffer, sends the data */
UDR1 = data;

}

and

unsigned char SPI1_Receive( void )
{
/* Wait for data to be received /
while ( !(UCSR1A & (1<<RXC1)) );
/
Get and return received data from buffer */
return UDR1;
}

see section 22.10.1 on page 218.

I hope this Is helpful for someone =)

Feel free to post this wherever you want :smiley:

But this didn't seem to work well at high speeds, I wish I had a logic analyzer to see what exactly happened there.

Need a 'scope for that. Logic analyzer will only capture good highs & lows - scope will show signal shape and whether its corrupted or not.