Skip to content

Suggest adding SPI_writeAnything to SPI library #61

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

Open
nickgammon opened this issue Aug 17, 2015 · 7 comments
Open

Suggest adding SPI_writeAnything to SPI library #61

nickgammon opened this issue Aug 17, 2015 · 7 comments
Assignees

Comments

@nickgammon
Copy link

I have the following small template library on my page about SPI ( http://www.gammon.com.au/spi ):

template <typename T> unsigned int SPI_writeAnything (const T& value)
  {
    const byte * p = (const byte*) &value;
    unsigned int i;
    for (i = 0; i < sizeof value; i++)
          SPI.transfer(*p++);
    return i;
  }  // end of SPI_writeAnything

template <typename T> unsigned int SPI_readAnything(T& value)
  {
    byte * p = (byte*) &value;
    unsigned int i;
    for (i = 0; i < sizeof value; i++)
          *p++ = SPI.transfer (0);
    return i;
  }  // end of SPI_readAnything


template <typename T> unsigned int SPI_readAnything_ISR(T& value)
  {
    byte * p = (byte*) &value;
    unsigned int i;
    *p++ = SPDR;  // get first byte
    for (i = 1; i < sizeof value; i++)
          *p++ = SPI.transfer (0);
    return i;
  }  // end of SPI_readAnything_ISR  

The function SPI_readAnything_ISR is for using inside an ISR, as it directly accesses SPDR.

It has been suggested to me that I request that you include this in the standard SPI library (SPI.h). This lets you more easily send things like floats or structs via SPI. For example:

  float fnum = 42.666;
  digitalWrite(SS, LOW);  
  SPI_writeAnything (fnum);
  digitalWrite(SS, HIGH);

Being a template function it won't add any bloat unless you actually use it.

Related request: https://github.com/arduino/Arduino/issues/3691

@mikaelpatel
Copy link

@nickgammon
Does the example really work? There is a missing <float> I believe. Guess you had the same problem as I with the quoting in markdown.

BW: C++ allows overloading so the naming is a bit "old fashion" :)

@nickgammon
Copy link
Author

Does the example really work?

It works as-is. The template deduces the type from the argument type (fnum is float). Try it yourself.

C++ allows overloading so the naming is a bit "old fashion"

It is named after the EEPROMWriteAnything template library in: http://playground.arduino.cc/Code/EEPROMWriteAnything

I left off the "write" part because it also reads.

@mikaelpatel
Copy link

@nickgammon
The definition is an "anything" but the usage is a specific type. It is good practice to be explicit even if the compiler does the type deduction. The notation write<float>(fnum) if easier to understand than writeAnything(fnum).

@nickgammon
Copy link
Author

Yes, but there is already a "write" function.

@nickgammon
Copy link
Author

Are you suggesting it as a templated overload of the standard write? I suppose that could work, so I will leave that to the library implementers which approach they would prefer.

@mikaelpatel
Copy link

@nickgammon
Yes, I am suggesting overloading write to force explicit type when using the template function. Also I would like to suggest optimizing the transfer as there is plenty of cycles to perform the data fetch/store while busy waiting for the hardware.

@mikaelpatel
Copy link

@nickgammon
BW: This topic and the suggested read function variant for ISR has given me some insight to improving the Cosa SPI library. The ISR/Slave mode is poorly supported. Thanks!

@sandeepmistry sandeepmistry transferred this issue from arduino/Arduino Sep 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants