Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test and resolve any issues with ESP8266 hardware SPI #606

Closed
nkolban opened this issue Oct 1, 2015 · 17 comments
Closed

Test and resolve any issues with ESP8266 hardware SPI #606

nkolban opened this issue Oct 1, 2015 · 17 comments
Assignees
Labels
ESP8266 This is only a problem on ESP8266 devices

Comments

@nkolban
Copy link
Contributor

nkolban commented Oct 1, 2015

We now have basic testing of software SPI tested and working. It is now time to create a work item for the hardware SPI built into the ESP8266. This work item will track the design and efforts necessary to perform that task.

@nkolban nkolban added the ESP8266 This is only a problem on ESP8266 devices label Oct 1, 2015
@nkolban
Copy link
Contributor Author

nkolban commented Oct 1, 2015

Here is the link to the ESP8266 API docs ... http://bbs.espressif.com/download/file.php?id=571

@nkolban
Copy link
Contributor Author

nkolban commented Oct 5, 2015

After studying the SPI hardware support docs from Espressif ... I am unable to understand how to use these functions. Looking now for someone who understands ESP8266 SPI details to provide guidance and consultation.

@nkolban
Copy link
Contributor Author

nkolban commented Oct 9, 2015

User @jumjum123 is looking for this ability to drive WS2812 devices. This should indicate to us that the relative priority of this issue should increase.

Posted a call for consultation here:

http://www.esp8266.com/viewtopic.php?f=6&t=5904

User @markusgritsch has also requested WS2812 support.

A link to a potentially useful article on hardware SPI on the ESP8266 has been found here:

http://d.av.id.au/blog/hardware-spi-hspi-command-data-registers/

http://d.av.id.au/blog/hardware-spi-clock-registers/

Another interesting link is:

http://www.esp8266.com/viewtopic.php?f=13&t=2413

An important library seems to be available here:

https://github.com/MetalPhreak/ESP8266_SPI_Driver

@nkolban nkolban self-assigned this Nov 4, 2015
@nkolban
Copy link
Contributor Author

nkolban commented Nov 4, 2015

Started examination of what is involved in integrating hardware SPI support. This starts with the examination of the MetalPhreak/ESP8266_SPI_Driver project.

I was able to compile this project cleanly with no issues.

Started a new Wiki page called SPI-Architecture.md to document our understanding of how Espruino handles SPI processing.

Changed the ESP8266_BOARD.py definition to set the number of hardware SPI's to 1. This may later turn out to be need to be set to 2 but we'll get one working first before looking at the second SPI.

@nkolban
Copy link
Contributor Author

nkolban commented Nov 5, 2015

With the MetalPhreak/ESP8266_SPI_Driver included in the build and the framework for SPI hardware support examined, changes were made to jshardware.c to link Espruino to the library. It compiled cleanly and SPI JS calls don't cause any fatal exceptions. What remains now is to test this basic support with a logic analyzer and see what we see.

The testing will consist of examination of the signals shown in the following table:

NodeMCU Function
D6 MISO
D7 MOSI
D5 CLK
D8 CS

@nkolban
Copy link
Contributor Author

nkolban commented Nov 5, 2015

Integration of Espruino with MetalPhreak library happened exactly as desired with no hiccups. We now have a hardware SPI known as SPI1. Changes committed and integrated with a pull-request from yesterday. This Issue will be left open pending user acceptance testing and problem resolution resulting from feedback.

@markusgritsch
Copy link
Contributor

Hmm, I tried

SPI1.setup({baud:3200000});
SPI1.send4bit([255,0,0], 0b0001, 0b0011);

which gives me just this output
shot
There should be way more pulses.

@markusgritsch
Copy link
Contributor

Another test:

SPI1.write([0x55,0x55,0x55])

shot
The amount of pulses is correct, but the long pause between the bytes make it not usable to drive WS2812 LEDs. More than 5-6 µs pause causes them to latch. See e.g. http://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/

@gfwilliams
Copy link
Member

@nkolban this is why I said you couldn't use the library as-is.

@nkolban
Copy link
Contributor Author

nkolban commented Nov 5, 2015

As I understand the Espruino architecture ... when one codes:

SPI.send([byte1, byte2, byte3]);

That causes 3 distinct calls to jshSPISend() which is implemented in jshardware.c. I am thinking that the 20-60us delay between bytes sent via the SPI hardware level is being spent in Espruino logic. I am thinking that the array is being walked and for each byte, we are invoking jshSPISend. I am not seeing how the 3rd party library could be changed to modify that story? I would imagine that a design change would need to require that either jshSPISend() be called as quickly as possible for each byte or else a buffer of bytes be sent directly to jshSPISend().

Do we have any suggestions for what the design changes might be?

@gfwilliams
Copy link
Member

/** Send data through the given SPI device (if data>=0), and return the result
 * of the previous send (or -1). If data<0, no data is sent and the function
 * waits for data to be returned */
int jshSPISend(IOEventFlags device, int data);

So it can send one byte, but it doesn't wait for a response, it returns immediately. It can then go away and work out the next byte while it's sending the current one.

Not only that but the library you're using does a bunch of setup stuff for every byte, which will delay it more.

That's why I said you'd basically have to end up re-writing the library and there wasn't much point pulling it in.

@nkolban
Copy link
Contributor Author

nkolban commented Nov 5, 2015

If we look at @markusgritsch signal trace (which is also what I am seeing on my signal traces) ... we are seeing that the "width" of the 8 bit SPI send is dramatically smaller than the inter byte send duration. In principle, the width of the 8bit send would be 8 * 1.2us = ~10ms while the inter byte processing is between 30-60ms. If we returned immediately when the 8bit SPI send started ... we would save the 10ms wait for the 8bits to complete ... but I'm not seeing how that would reduce (enough) the bill for inter byte processing?

@gfwilliams
Copy link
Member

SPI1.write([0x55,0x55,0x55]) will be a lot slower than SPI1.send4bit(new Uint8Array([255,0,0]), 0b0001, 0b0011); - which is what's generally suggested for WS2811, so that would help.

However even with send4bit, it's doing this so is sending 4 bytes as fast as possible but is still ending up with a really big delay between them.

Once that is sorted (especially if you can put the SPI peripheral into 16 bit mode) there shouldn't be a huge problem with speed. After all, even a 72Mhz STM32 can handle it, and the ESP8266 is 100Mhz.

@nkolban
Copy link
Contributor Author

nkolban commented Nov 5, 2015

It has been found that the jshSPISend16() is not yet implemented ... more work needs to be undertaken to understand the purpose of this API and implement it appropriately.

@nkolban
Copy link
Contributor Author

nkolban commented Nov 5, 2015

An additional issue has been created to discuss/conjecture another possibility for internals implementation of data processing for SPI. See #695.

A forum thread discussing the use of MetalPhreak's SPI library can be found here:

http://forum.espruino.com/conversations/277010/

Changes were made to update the implementation of jshSPISend() to make it consistent with the semantics of what the jshSPISend() function is meant to do.

The jshSPISend16() function had its implementation changed to send 16 bits of data.

Testing seems to show that the JavaScript function of SPI1.send4bit() is now functioning.

gfwilliams added a commit that referenced this issue Nov 10, 2015
#606. Initial framework for hardware SPI for ESP8266.
@tve
Copy link
Contributor

tve commented Dec 3, 2015

Can this issue be closed? Is there something left to do?

@jumjum123
Copy link
Contributor

Hello Thorsten,

from my point of view, this should be closed.

Regards from good old Germany(about 8 degrees Celsius and sunny)
Jürgen

On Thu, Dec 3, 2015 at 7:52 AM, Thorsten von Eicken <
notifications@github.com> wrote:

Can this issue be closed? Is there something left to do?


Reply to this email directly or view it on GitHub
#606 (comment).

@tve tve closed this as completed Dec 3, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ESP8266 This is only a problem on ESP8266 devices
Projects
None yet
Development

No branches or pull requests

5 participants