/      日本語

SPI

Performs reading and writing on the SPI bus (controller side).
Performs reading and writing on the SPI bus (controller side).

Notes

Constants

ConstantMeaning
const uint8_t
SPI_CONF::MSBFIRST
Set MSB as the first bit
const uint8_t
SPI_CONF::LSBFIRST
Set LSB as the first bit
const uint8_t
SPI_CONF::SPI_MODE0
Set to SPI MODE 0
const uint8_t
SPI_CONF::SPI_MODE1
Set to SPI MODE 1
const uint8_t
SPI_CONF::SPI_MODE2
Set to SPI MODE 2
const uint8_t
SPI_CONF::SPI_MODE3
Set to SPI MODE 3

Initialization and Termination

The procedure to use the SPI bus is via the begin() method.

begin()

void begin(uint8_t slave_select, SPISettings settings)
SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)

Initializes the hardware.

ParameterDescription
slave_selectSpecifies the select pin of the target peripheral.
0 : DIO19``1 : DIO0 (DIO19 is reserved)``2 : DIO1 (DIO0,19 are reserved)
settingsSpecifies the SPI bus settings.

clock [Hz] specifies the SPI bus frequency. A divisor close to the specified frequency is selected. The value will be 16MHz or an even division of 16MHz.
bitOrder is either SPI_CONF::MSBFIRST or SPI_CONF::LSBFIRST.
dataMode is one of SPI_CONF::SPIMODE0..3.

Example

void setup() {
  ...
  SPI.begin(0, SPISettings(2000000, SPI_CONF::MSBFIRST, SPI_CONF::SPI_MODE3));
  ...
}

void wakeip() {
  ...
  SPI.begin(0, SPISettings(2000000, SPI_CONF::MSBFIRST, SPI_CONF::SPI_MODE3));
  ...
}

end()

void end()

Terminates the use of SPI hardware.

Reading and Writing

There are two types of procedures for reading and writing. Use either of them as needed.

Example

The following sample code reads the temperature every second from the Analog Devices temperature sensor ADT7310 and outputs it to the serial port.

#include <TWELITE>
#include <SM_SIMPLE>

enum class STATE : uint8_t {
    INTERACTIVE = 255,
    INIT = 0,
    INIT_WAIT,
    SENSOR,
    LOOP_WAIT
};
SM_SIMPLE<STATE> step;

struct SensorData {
    uint8_t highByte;
    uint8_t lowByte;
    uint16_t rawValue;
    int32_t tempValue16th;
    div_result_i32 temperature;
} sensorData;

void setup() {
    step.setup(); // Initialize the state machine
}

void loop() {
    do {
        switch (step.state()) {
        case STATE::INIT: // Initial state
            SPI.begin(0 /* Use DIO19 as chip select */
                      , { 400000UL /* Clock frequency */
                    , SPI_CONF::MSBFIRST
                    , SPI_CONF::SPI_MODE3
            }
                      );

            // Software reset
            SPI.beginTransaction();
            for (int i = 0; i < 4; i++) {
                SPI.transfer(0xFF);
            }
            SPI.endTransaction();

            // Start Continuous Read mode
            SPI.beginTransaction();
            SPI.transfer(0x54);
            SPI.endTransaction();

            step.set_timeout(300); // Set wait time
            step.next(STATE::INIT_WAIT);
            break;

        case STATE::INIT_WAIT: // Wait
            if (step.is_timeout()) {
                step.next(STATE::SENSOR);
            }
            break;

        case STATE::SENSOR: // Read sensor data
            SPI.beginTransaction();
            sensorData.highByte = SPI.transfer(0x00);  // Send dummy data to generate clock signal
            sensorData.lowByte = SPI.transfer(0x00);   // Send dummy data to generate clock signal
            SPI.endTransaction();

            sensorData.rawValue = (((uint16_t)sensorData.highByte << 8) | sensorData.lowByte) >> 3;
            if (sensorData.rawValue & 0x1000) {
                sensorData.tempValue16th = int32_t(sensorData.rawValue) - 0x2000;
            } else {
                sensorData.tempValue16th = sensorData.rawValue;
            }

            // Calculate temperature using div100()
            sensorData.temperature = div100((sensorData.tempValue16th * 100) / 16);

            // Output result to serial
            Serial << crlf << sensorData.temperature.format() << "°C";

            step.set_timeout(1000); // Wait until next capture
            step.next(STATE::LOOP_WAIT);
            break;

        case STATE::LOOP_WAIT: // Wait
            if (step.is_timeout()) {
                step.next(STATE::SENSOR);
            }
            break;

        default:
            break;
        }
    } while (step.b_more_loop());
}

Here, the member function interface is used.


SPI (Member Function Version)

SPI (Method-based usage)

SPI (Helper Class Version)

SPI (How to use with helper class)