SPI (Helper Class Version)
transceiver
, you start using the bus, and by destroying the object, you end the use of the bus.By creating the object inside the conditional expression of an if statement, the lifetime of the object is limited to the scope within the if block, and when exiting the if block, the object is destroyed and the bus release procedure is performed at that point.
uint8_t c;
if (auto&& trs = SPI.get_rwer()) { // Create object and check device communication
// The scope (curly braces) here is the lifetime of trs.
trs << 0x00; // Write 0x00 using mwx::stream interface
trs >> c; // Store the read data into c.
}
// When exiting the if block, trs is destroyed and the bus usage ends
Also, since the read/write object implements the mwx::stream
interface, operators like <<
can be used.
- Matching the bus usage start and end with the object’s lifetime improves code readability and prevents omission of release procedures.
- Unifies read/write procedures using the
mwx::stream
interface.
Read/Write
A reading method using a helper class that performs read operations and their termination procedures within the scope if() { ... }
.
inline uint8_t _spi_single_op(uint8_t cmd, uint8_t arg) {
uint8_t d0, d1;
if (auto&& x = SPI.get_rwer()) {
d0 = x.transfer(cmd); (void)d0;
d1 = x.transfer(arg);
// (x << (cmd)) >> d0;
// (x << (arg)) >> d1;
}
return d1;
}
Above, the x
object created by the get_rwer()
method is used to perform byte-wise read/write.
- The
x
object is created inside theif(...)
. At the same time, the SPI bus select pin is set. (The type is resolved by universal referenceauto&&
with type inference.) - The created
x
object definesoperator bool ()
which is used for evaluation in the conditional expression. For SPI bus, it always evaluates totrue
. - The
x
object defines the methoduint8_t transfer(uint8_t)
, which performs an 8-bit read/write transfer to SPI when called. - At the end of the
if() { ... }
scope, the destructor ofx
is called, releasing the SPI bus select pin.
get_rwer()
periph_spi::transceiver get_rwer()
Obtains a worker object used for SPI bus read/write.
Worker Object
transfer()
, transfer16()
, transfer32()
uint8_t transfer(uint8_t val)
uint16_t transfer16(uint16_t val)
uint32_t transfer32(uint32_t val)
Perform transfers of 8-bit, 16-bit, and 32-bit respectively, and return the read result with the same data width as the written data.
<<
operator
operator << (int c)
operator << (uint8_t c)
operator << (uint16_t c)
operator << (uint32_t c)
int
and uint8_t
types perform 8-bit transfers.
uint16_t
and uint32_t
types perform 16-bit and 32-bit transfers respectively.
Transfer results are stored in an internal FIFO queue of up to 16 bytes and read out by the >>
operator. Since the buffer is not large, it is assumed to be read out each time after transfer.
>>
operator
operator >> (uint8_t& c)
operator >> (uint16_t& c)
operator >> (uint32_t& c)
null_stream(size_t i = 1)
operator >> (null_stream&& p)
Specify a variable with the same data width as the previous transfer.
If the read result is not needed, use the null_stream()
object. It skips the number of bytes specified by i
.