Add an additional overload when writing to SPI with a buffer, SPI.transfer(buffer, len, recv), where recv is a boolean, when true will replace the buffer with the incoming, however when false is leaves the buffer alone. I ran into a issue with my current project where I needed the buffer to remain unchanged, and it took me awhile to realize that is was the SPI library changing the data.
--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+...@arduino.cc.
I know that with at least a few different platforms, there is a version of the SPI.transfer, that allows you to specify different buffers for the send and receive buffers: Example Teensy boards:
void setTransferWriteFill(uint8_t ch ) {_transferWriteFill = ch;}
void transfer(const void * buf, void * retbuf, size_t count);
Note: Transfer Fill is used if NULL ptr for buf.
ESP8266 has:
void transferBytes(uint8_t * out, uint8_t * in, uint32_t size);
Likewise for ESP32:
void transferBytes(uint8_t * data, uint8_t * out, uint32_t size);
void transferBits(uint32_t data, uint32_t * out, uint8_t bits);
It would be great if we could somehow standardize on some of these extended functions.
--
1 - To extend or to replace entirely?
2 - How to organize the extended class for different devices?
3 - How to be compatible with devices that have multiple hardware SPI peripherals?
4 - Can we start an organized project and build it up as needed until it covers enough devices to become standard?
I'm glad there's some interest in this topic! Who wants to collaborate on a solution? I could really use some advice for how to make this ultimately fit into the standard Arduino experience. Let's keep up the discussion!
And for people with spare time here are my more detailed thoughts on the above topics. Be warned, I'm thinking out loud here
1 - This question mostly comes from my lack of understanding of how Arduino gets developed. If ultimately we wanted these features to go to everyone is it easier to merge an inherited class or a copy/pasted original class with the needed functions added? I think that even in the inherited option the functions would need to be written from scratch and be specific to a given architecture, so what's the advantage of using inheritance? Earlier today I copy/pasted the avr SPI library and added my own functions (sounds like what you've done, more or less) and it worked well - just couldn't use it in a library that I want to have work for everyone.
2 - As far as planning ahead goes how does it sound to make a whole library (header + cpp) for each HW peripheral on a given architecture. Seems to me that this would make it easier to move it into the existing cores later. Then you're left with something that can't easily be included in other libraries, so how about a 'master organizer' that includes the right specific libraries based on your architecture at compile time? The master could be the sole include needed in other libraries and that still seems fairly accessible to others. (Drawback: having a lot of different libraries on your computer) Hmm... One problem: it would require work to make any libraries that were built on that system compatible with the cores once they are replaced. This is mostly because we will have a different name than 'SPIClass' but all the same functions (and then some)
3 - This is mostly covered in (2)
4 - Where's the right place to start this effort (GitHub seems right...)? Who wants to be responsible? (I volunteer, if I'm not stepping on toes) What are the guidelines?
+ Preliminary guidelines:
+ + The goal is to make the discussed features available easily so that they can be used in development of other libraries
+ + The body of work can be developed as-needed for a given architecture
+ + Existing Arduino compatibility shall be maintained
+ + Uniform naming across device specific implementations
+ + There should be an easy way to use this support in libraries right now
What am I overlooking? Is there another way to extend the existing SPI libraries that would work better? What would be the best way to make it so that libraries that use this extension won't be totally derailed if/when out-of-the-box support becomes a reality?
Thanks for your time and input!
As my earlier message/email is mentioned I thought I would reiterate that I added some of this to the Teensy versions of the SPI library and now recently to the Robotis OpenCR hardware as well.
The new functions were added to these libraries (SPI) using the same methodology as was earlier used to add transactions to the SPI library.
That is in SPI.h there is:
// SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(),
// usingInterrupt(), and SPISetting(clock, bitOrder, dataMode)
#define SPI_HAS_TRANSACTION 1
And the transaction stuff is in the library. Those programs/libraries that wish to use transactions (hopefully most all of them by now) can/should have code like:
#if defined(SPI_HAS_TRANSACTION)
< do stuff for transactions>
#else …
So in the Teensy SPI library code, we have:
// SPI_HAS_TRANSFER_BUF - is defined to signify that this library supports
// a version of transfer which allows you to pass in both TX and RX buffer
// pointers, either of which could be NULL
#define SPI_HAS_TRANSFER_BUF 1
That libraries/programs can check against before they compile in code that requires (or prefer to use) the new version of the API
Again a new API was defined:
void transfer(const void * buf, void * retbuf, size_t count);
Yes you could define new ones for Read only operation or write only operations if you like, but can do the same with above
Simply passing in NULL for either or both (both would simply send your fill character)
If you want versions that are specifically defined as only write or only read, than you can easily also include those. For example some other platforms
Had a writeBuf function defined, which would be something like:
Inline void writeBuf(const void *buf, size_t count) {transfer(buf, NULL, count);}
Secondary addition on Teensy (and limited on openCR) an asynchronous (DMA) version was added which code could look for:
#define SPI_HAS_TRANSFER_ASYNC 1
But this uses some of the Teensy EventResponder code, which may be beyond this thread… But there is a form of the transfer method:
bool transfer(const void *txBuffer, void *rxBuffer, size_t count, EventResponderRef event_responder);
where the transfer will start up using DMA and return and when it completes an event is set using the event_responder, which can call of to
a user function. When the call happens depends on how you have the event_responder setup (now, some timer, idle, …)
--
To unsubscribe from this group and stop receiving emails from it, send an email to developers+unsubscribe@arduino.cc.
--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+unsubscribe@arduino.cc.
I can see/use all of the above. My first version was the same and had a null callback function, but then with teensy we started experimenting with the ability for different types of callbacks. That is do you want your code to be called on the DMA completion interrupt, or do you want that to then call it off of a timer (in our case millisecond timer), or do you only want it called during idle and maybe you don’t want it not to call anything but you can ask the object if it completed or not…
And I do have display code (ili9341 as well and SSD1306) that does this. Note the ILI9341 code is not using the SPI code but is doing the DMA directly.
I can see uses for the functions busy function as you mentioned. Both the simple version as well as some indication of how much is done or left to do.
I do something similar in some of display code (Teensy 3.5/6 ili9341_t3n library), where I can ask for the screen to update using DMA, and I can ask if the update has completed or not. I then have some other user code, that will decide if it is safe to update the image in the frame buffer or not…
But for me, It would be great if we could at least take some baby steps and standardize on a (or set of) update functions that don’t overwrite the buffer. Then maybe we would have some luck with then getting library owners to take in Pull requests that often significantly speeds them up and those speed ups work for multiple platforms. At the same time would be great if we could also have more libraries where you can somehow specify which SPI object is to be used and not always use SPI. As there are now more and more of these platforms who support multiple SPI (and Wire) objects.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+...@arduino.cc.
--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+...@arduino.cc.
--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+...@arduino.cc.