Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By Vicne
#50701
Me-no-dev wrote:That delay between the bytes on the ESP Master are strange... where do they come from? Do they exist in normal SPI communication? If my memory is correct, when I scoped the SPI bus (back more than a year ago), I did not see any such pauses.

This is my first experience with SPI on the ESP8266, so I don't know if it's normal.
My knowledge of SPI is limited, but as far as I know, there is no constraint on clock timings, not even about the frequency or duty cycle being fixed, and a search reveals lots of different cases. As long as devices agree that bits must be sampled on a given clock edge, the rest is completely undefined (and thus prone to flakyness).
I read there are fields on the ESP to add a delay between CS activation and start of first bit (SPI_CS_SETUP) or between end of last bit and CS release (SPI_CS_HOLD), but I don't know of a similar setting for time between bytes...
All in all, it should not matter, but if decoding relies on such a delay, that could be an issue...
Kind regards,

Vicne
User avatar
By Vicne
#50776 :-) Mystery solved ! :-)

I wrote:
I wanted to make sure that adding my "fix" that made inter-ESP communication work was harmless for AVR-ESP communication... but it's not.

In fact, it is ;-).

I had a chat with McGyver today, and I related my experience.
He immediately observed that the clock signal was not clean at all, but I objected, as I said already, that if the clock is clean enough to be used to read MOSI and to be used to write MISO with the wrong phase settings, it should be clean enough also to write MISO with correct phase setting.

Wrong.

This is the scope capture that explains it all (already posted but re-annotated) :
7- 2nd byte of reply - lost bit.png

One can see that one bit is "lost", which means the slave ESP "thinks" it has sent 2 bits although we can only see one.
The reason is that there is a quite large spurious oscillation at the start of the bit, and as the CLK threshold is quite low and the ESP is very fast, this oscillation is seen by the ESP as an extra clock cycle, so that bit counts for 2:
7- 2nd byte of reply - explained.png


Now why does that issue only occurs when the MISO phase is correct?
Simple: because the cause of that oscillation is the edge on the MISO! There is a capacitive coupling between CLK and MISO due to the flat cable I'm using. When MISO changes just after a rising edge, the oscillation happens around 3V, and the signal remains above the threshold, so no problem. But when MOSI changes just after a falling edge, the oscillation happens around 0V and the signal goes over the threshold.

And why doesn't that occur when the slave is an ESP ?
Well, because in that case, my cabling is much simpler (no level adapter), and the signal is stronger.

(note: one can also notice a spike on MISO on the right, under the second equal sign. This is the trace of a bit that was set, caused an oscillation, and was thus immediately "terminated" and reset.)

After simplifying the circuit (running the Arduino at 3.3V, with direct connections to the ESP), the signal gets much cleaner and dialog works as expected:
AVR Master left, ESP Slave right:
serial_dumps.png

Question from AVR:
question.png

Answer from ESP:
answer.png

And a zoom on the start of the answer. Look at that clean clock and correct phases :-) :
answer_zoom.png


So the lessons are:
1. Limit your cabling and avoid any cause of interference
2. Mc Gyver is always right :-).

Kind regards,

Vicne
You do not have the required permissions to view the files attached to this post.
Last edited by Vicne on Fri Jul 15, 2016 10:26 am, edited 2 times in total.
User avatar
By Vicne
#50815 Hi, Me-no-dev, hi all,

Me-no-dev wrote:The command bytes can be changed to something else through the registers, but the general protocol must stay the same. SPI1S3 is the register in question.


One thing I don't understand is that your slave code leaves the the SPI1S3 register to 00000000, but still, the correct interrupt is raised when the master sends commands 01, 02, 03 or 04.
How can it be ? Are they the "default" commands and is there a bit I must set to enable overriding of default values by the ones in SPI1S3 ?
Edit: I tried SPI1S.SPISCD (Command Define), to no avail.

In the end however, I could wrap a code that seems to achieve my "spying" goal.
Indeed, I noticed that the SPI1A (address) register always contains the first bytes of the messages I'm spying on.
Reminder: observed messages I need to decode have one of the 3 following formats:
08 FF FF (heartbeat)
A4 aa bb (update leds)
54 cc dd 0 0 (update display)

By regularly dumping SPI1A, I observed that it contains, respectively:
08FFFF00
A4aabb00
54ccdd00

Unfortunately, as these messages are neither "status read/write" nor "data read/write", I wasn't notified in any callbacks... until I saw that you handled those 4 interrupts but a fifth is present, simply called "trans".
So I added a hspi_slave_onTrans() similar to hspi_slave_onStatus() all the way up to the calling code and now it seems I can reliably be notified when *any* message comes in.

Generally speaking, there are drawbacks of course, the most obvious being that I'm limited to 4-byte messages (fortunately, the only 5-byte message in my protocol always seems to end with a 0), and I really believe that it's a non-orthodox way of getting data, but it seems to work.

By the way, I first tried to redefine commands to receive status and data as SPI1S3 as A4 and 54, respectively (SPI1S3 = 0xA4005400), hoping to get the two interesting messages as status and data, but that didn't trigger any interrupt.
(in fact, only the "Send status" interrupt is regularly triggered, so it seems some messages are recognized as a request from the master to send the status...)
I had also defined the status length to 2 bytes, the address length to 1 byte and the data length to 3 bytes (SPI1S1 = 0xF << SPIS1LSTA | 0x17 << SPIS1LBUF | 0x7 << SPIS1LRBA;) but now that I observed that the address register is filled with up to 4 bytes, I believe even more that these for these settings to be used, an "enable" field of some sort must be set...

I will go on using the address field as observed above because that will allow me to complete my project, but feel free to shed some light on this if you have more information.

By the way, I worked along the way on a "properly formatted" documentation of the SPI registers in the form of a spreadsheet (it's mainly grouping in a single place the two .h files and their comments, the findings by metalphreak and the ones from this topic.
I'm attaching here a PDF version for ease of reading, but I can share the source if anyone is interested. Hope it helps...
ESP8266 SPI register description 20160715.pdf


Kind regards,

Vicne
You do not have the required permissions to view the files attached to this post.
Last edited by Vicne on Wed Feb 22, 2017 2:22 pm, edited 1 time in total.