setting SPI Slave mode
Opened this issue · 5 comments
- [ Y] This issue complies with the issue POLICY doc.
- [ Y] I have read the documentation at readthedocs and the issue is not addressed there.
- [ Y] I have tested that the issue is present in current master branch (aka latest git).
- [Y ] I have searched the issue tracker for a similar issue.
- [ N/A] If there is a stack dump, I have decoded it.
- [ Y] I have filled out all fields below.
Platform
- Hardware: [ESP-12]
- Core Version: [28 August 2018]
- Development Env: [Arduino IDE]
- Operating System: [MacOS]
Settings in IDE
- Module: [Generic ESP8266 Module
- Flash Mode: [dio]
- Flash Size: [512K]
- lwip Variant: [N/A]
- Reset Method: [ck]
- Flash Frequency: [40Mhz]
- CPU Frequency: [80Mhz]
- Upload Using: [OTA|SERIAL]
- Upload Speed: [115200] (serial upload only)
Problem Description
I am using and nRF52832 as master using nrf5 SDK and 8266 as SPI slave.
The master works with other SPI slave devices.
It appears that the mode is wrong on the SPI slave as the data is changing on the leading edge of the clock and most of the time is getting corrupted. In other words data is flowing in both directions but is mostly incorrect.
I need to change the slave to mode 3. I verified this by changing the mode at the master. This is not the right solution as there are other slaves that need mode 0.
SPISlave.begin() has no facility for setting the mode but I guess one could set the mode bits after invoking that.
Is there any code example anywhere that would show me how to do this?
Better still, could a mode parameter be added to this call?
Note: #2416 (comment) is related but not the same issue.
Sketch
Test sketch is the one in the current version of this repo.
Debug Messages
none
Hallo,
I had difficulties to connect an Arduino DUE with ESP8266 as SPI-Slave. DUE and ESP are configured with SPI-Mode=0. I tried alle modes 0 to 3 on the DUE, without any success. The screen shots (attached) from an oscilloscope show the reason: MISO does not match with MODE 0, where the sampling occures with the rising edge and the data change at the falling edge of SCK. (With a slower Arduino UNO it works nevertheless, but not very reliable.)
My work around: The ESP provides the option to delay the MISO-Signal. I found the refering registers and added one line in the file hspi_slave.c: of the SPISlave-Library (to the ESP8266):
`
void hspi_slave_begin(uint8_t status_len, void * arg)
{
....
SPI1CMD = SPIBUSY;
SPI1C2=(0x2<<SPIC2MOSIDN_S) | (0x3<<SPIC2MISODN_S) | (0x7<<SPIC2MISODN_S); // Added 28.10.2018, works for SCK = 4 MHz
ETS_SPI_INTR_ATTACH(_hspi_slave_isr_handler,arg);
...
}
The delay also for MOSI seems not reasonable, but I found in the ESP32 reference that it has to be 0x2 for MODE0, so I added it, but I found no influence.
With this change, the timing was perfect and the communication with the DUE works reliable.
Hallo again,
there is a much better solution:
SPI1C2=(0x2<<SPIC2MOSIDN_S) | (0x1<<SPIC2MISODM_S);
(Please take care of "N_S" and "M_S".);
This works also with much lower frequencies.
GuaAck
@GuaAck could you please explain in detail what you're doing, and why the second solution is better?
Hallo,
to answer the question:
I tried to connect an EP8266 with my Arduino DUE, it fails. The program works with the UNO and the MEGA. As a reason I found, that the timing of MISO does not match with SPI-MODE0. (Setting the MODE 1 - 3 in the master had no success.) The slower UNO and MEGA fread the correct bit, but the much faster DUE does not (See photos in the post above). I found somewhere, that the ESP32 has a SPI-module similar to that one in the ESP8266. On base of the technical reference I inserted the delay of the MISO of 8 cycles (MISODN=7) and it works for 4 MHz. But because it is a simple delay, I had doubts that it works for lower clock frequencies (it does not), but this was no problem for my project.
I have also contacted Jiri Bilek (https://github.com/JiriBilek/WiFiSpiESP), I use his library. We worked together to find out, what happens. Finally Jiri has had the idea to set MISODM=1 and to forget MISODN. I tried it, and it works perfectly and independant on the SCK-frequency, tested with 4 MHZ and 320 kHz.
I hope this helps,
GuaAck
@GuaAck thank you, that certainly clears up the intent at high level. But I meant at low level, as in what does the line of code do? What registers are accessed, what do the bits mean? Like you said, the ESP's registers aren't really documented, and you seem to have investigated, so my request is for the details, so that they can be added e.g. as comments to a PR or inline with the code.
And speaking of PR, how about making one with your code change? This core is a community effort, and your contribution is highly welcome. It's only fair that your name shows up in the contribution history :)