diff --git a/src/shared/drivers/spi/SPIBus.h b/src/shared/drivers/spi/SPIBus.h index ea732e79f9c53b42864d4f4439b13e0ccd653c2a..e31c4232974fd91442c5181a45023e5bcfea18d0 100644 --- a/src/shared/drivers/spi/SPIBus.h +++ b/src/shared/drivers/spi/SPIBus.h @@ -99,7 +99,7 @@ public: */ void configure(SPIBusConfig config) override; -private: +protected: /** * Writes a single byte on the SPI bus. * @@ -124,7 +124,7 @@ private: SPI_TypeDef* spi; - SPIBusConfig config; + SPIBusConfig config{}; bool config_enabled = true; bool first_config_applied = false; }; diff --git a/src/shared/drivers/spi/SPIBusInterface.h b/src/shared/drivers/spi/SPIBusInterface.h index 966ddae385d37096b554dd85f67c101d89262124..9af7e336a23e77f59faf3d23144f216a65e3d3ea 100644 --- a/src/shared/drivers/spi/SPIBusInterface.h +++ b/src/shared/drivers/spi/SPIBusInterface.h @@ -31,6 +31,8 @@ using miosix::delayUs; using miosix::GpioPin; +class SPITransaction; + /** * @brief SPI Clock divider. * SPI clock frequency will be equal to the SPI peripheral bus clock speed (see @@ -116,6 +118,7 @@ struct SPIBusConfig */ class SPIBusInterface { + friend class SPITransaction; public: SPIBusInterface() {} @@ -198,6 +201,9 @@ public: * @return */ virtual void configure(SPIBusConfig config) = 0; + +private: + bool locked = false; // For use by SPITransaction }; /** diff --git a/src/shared/drivers/spi/SPITransaction.cpp b/src/shared/drivers/spi/SPITransaction.cpp index a7e79fa6b85c6ca266d5fbe1836b24398d2bf2d1..de43334f0cb5770f0fdc6537748929f491e8f27f 100644 --- a/src/shared/drivers/spi/SPITransaction.cpp +++ b/src/shared/drivers/spi/SPITransaction.cpp @@ -23,17 +23,29 @@ #include "SPITransaction.h" +#include <cassert> + +SPITransaction::SPITransaction(SPISlave slave) + : SPITransaction(slave.bus, slave.cs, slave.config) +{ +} + SPITransaction::SPITransaction(SPIBusInterface& bus, GpioPin cs, SPIBusConfig config) : bus(bus), cs(cs) { + // Only one SPITransaction may be active at any given time. + // Do not store an instance of SPITransaction for a long time! Create one, + // use it, and destroy it as soon as you are done operating on the bus! + // (just like mutexes) +#ifdef DEBUG + assert(bus.locked == false); +#endif + bus.locked = true; bus.configure(config); } -SPITransaction::SPITransaction(SPISlave slave) - : SPITransaction(slave.bus, slave.cs, slave.config) -{ -} +SPITransaction::~SPITransaction() { bus.locked = false; } void SPITransaction::write(uint8_t cmd) { diff --git a/src/shared/drivers/spi/SPITransaction.h b/src/shared/drivers/spi/SPITransaction.h index af1243dbaff5b6d0cad049b45a8bf50fcf2d1f5c..b75c20d4ab86f2fdc8e57f8f08e6ba6a7e6ee038 100644 --- a/src/shared/drivers/spi/SPITransaction.h +++ b/src/shared/drivers/spi/SPITransaction.h @@ -1,19 +1,19 @@ /** - * - * + * + * * Copyright (c) 2020 Skyward Experimental Rocketry * Authors: Luca Erbetta (luca.erbetta@skywarder.eu) - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -41,14 +41,15 @@ * { * // Transaction begin: * SPITransaction spi(bus, cs, config); // Configures the bus with the - * // provided parameters + * // provided parameters. * * spi.write(REG_EX, 0x56); // writes data to REG_EX * uint8_t reg2 = spi.read(REG_EX_2); // reads from REG_EX_2 * * // ...As many read/writes as you wish... * - * // transaction end. SPITransaction object is destructed + * // transaction end. SPITransaction object is destructed and the bus is + * // freed for use by someone else * } */ class SPITransaction @@ -72,6 +73,8 @@ public: */ SPITransaction(SPIBusInterface& bus, GpioPin cs, SPIBusConfig config); + ~SPITransaction(); + // Delete copy/move contructors/operators SPITransaction(const SPITransaction&) = delete; SPITransaction& operator=(const SPITransaction&) = delete;