The MISO isn't controlled by the Arduino at all, it's just read. And a SPI device let's MISO float when Chip Select is not active. In that case the Tx of the Serial-USB will pull it high. But then the Arduino will not read it so no problem.
As far as the problem, did you set the correct Data Order, Clock Phase, Clock Polarity (according to Nick's notes register UCSR0C)?
And just on a note, SPI is a bus, so unless you have explicit need to have two buses there is no need to use two. You can just add multiple SPI devices to the same bus. All you need is an extra pin for the CS of the new device.
Yes, In fact I need 4 SPI buses, but that will be done on the ATMega 2560 with all pins broken out.
I am waiting to receive my full breakout, that's why I'm experimenting with the UNO.
I did look into the datasheet, but my understanding is not good enough to follow the instructions there for setting up USART. I will continue to study it but I would really appreciate any help that anyone could give!
In the datasheet you need to look for register UCSR0C. Now you set bit UMSEL00 (bit 6) and bit UMSEL01 (bit 7) of that register which is master SPI. bit UCPOL0 and UCPOH0 set the SPI mode. But leaving them unset (like now) is SPI mode 0. See page 19 of the datasheet.
I need to use theHW SPI for slave mode, and the others in master mode to read various devices. The PCB tracks are like that...
It seems to me that my settings are good for MSB first and and writing on leading edge and reading on trailing edge, But I must be mistaken because it continues to fail.
I have found that the MISO line stays HIGH before and after transfers, could that be the issue?
You mean the UART RxD pin, right? It shouldn't matter. The uno essentially has a pull-up resistor on that line as part of the circuitry used for Async Serial communications (Serial.xxx, and sketch upload), but an SPI slave would actually drive those pins and override the Async circuitry.... (unless the high signal interferes with the slave's ability to detect that it can send data...)
I have perfect comms using the HW SPI library. I use the exact same code, substituting calls to encapsulated versions of NG's code for the various HW calls.
My HW SPISettings call is:
SPISettings(16000000,MSBFIRST,SPI_MODE0 )
And my USART setup call is:
pinMode (MSPIM_SS, OUTPUT); // SS
// must be zero before enabling the transmitter
UBRR0 = 0;
UCSR0A = _BV (TXC0); // any old transmit now complete
pinMode (MSPIM_SCK, OUTPUT); // set XCK pin as output to enable master mode
UCSR0C = _BV (UMSEL00) | _BV (UMSEL01); // Master SPI mode
UCSR0B = _BV (TXEN0) | _BV (RXEN0); // transmit enable and receive enable
// must be done last, see page 206
UBRR0 = 0; // full speed //3 // 2 Mhz clock rate
The MOSI signals are the same, but the replies are not. I cannot understand why.
I use the same code, so the same delayMicroseconds calls are made to ensure that there is enough time.
I am at a loss, but thank you so much for your help!
gratefulfrog:
The MOSI signals are the same, but the replies are not. I cannot understand why.
The Arduino only makes the SCK and MOSI, MISO is made by the device. So if they are not the same it's caused by the device. Only other thing I can think of is that the drive monitored the MISO line and that's causing trouble because it's pulled high. If it's a real Arduino you can try to put the ATmega16U (the chip that does the USB-Serial) in reset. This should release the Rx pin and make it float as well.
septillion:
If it's a real Arduino you can try to put the ATmega16U (the chip that does the USB-Serial) in reset.
It is a real arduino, but how does one do that? I searched on the web, but found no instructions that I could understand. I am sorry for my ignorance....
The ATmega16U has it's own ISP header called ICSP1, it's the one near the USB. It has the reset of the ATmega16U on it on pin 5. Just connect that to pin 5 (which is GND) to keep the ATmega16U in reset. If I'm correct that are the two pins closest to the USB socket.
septillion:
If I'm correct that are the two pins closest to the USB socket.
You are indeed correct, and by shorting those pins, i.e. pins 5 & 6 of the ICSP header (those facing the USB connector), the USART comms now work PERFECTLY!!!
I don't know how to express my gratitude for your perseverance and great energy to help me!!!
Great to hear it works! No idea what it does though
Very quick scan:
For the heartbeat, no need to save state, you can just read it. That's why I like to add the following function to most of my projects.
And don't know what you all try to do, but you're using a lot of delay()... And that is a source of a lot of headaches. Letting the loop() loop is better most of the time.
Especially because you say you need 3 SPI master buses would expect speed to be an issue. Otherwise you could connect all devices just to a single bus
This code is only designed to get the USART comms operational. There is no "real" code here, except for the yspi and ad7689 libraries. All those delays are to give me time to set the trigger on my oscilloscope to capture a particular communication frame.
Now that we have a working USART implementation on the UNO we will port it to our ATmega2650 based custom boards.
As an aside, we had originally planned to do this debugging on an Arduino Mega, but were sad to discover that 16 of the microprocessor pins are NOT CONNECTED on the Arduino Mega. And sadly, the USART CLK pins are among those 16...
In any event, it has been great to get USART working 100% even if it is on the UNO.
Next we will port this code to our custom boards and/or do more debugging on an ITEAD Iteaduino mega derivative which does have all 100 of the microprocessor pins connected, if it ever arrives in the post
septillion:
Then still one question in my head, why can't the devices share the SPI?
Seeing as I'm only a programmer, I asked the electronics designer your question.
Here's the reply I got from him:
Speed is the key: when 2 or more devices share the same bus, only one device can use it at a time. Putting them all on a different bus, with a different clock generator (as configured in the USARTs individually) allows all to be addressed simultaneously. When communication with one ADC is initiated, the MCU can directly move on to the next one and initiate communication there as well, and so on. Once a cycle is complete, the respective RX interrupt flags will be set, and the MCU can read out data from the receive registers. In summary, putting them all on the same bus forces sequential operation, while putting them on different buses enables the opportunity of parallelization.