From 4e00be53a307debb54e59bc266d90ab5bee58e37 Mon Sep 17 00:00:00 2001
From: Luca Erbetta <luca.erbetta@skywarder.eu>
Date: Sat, 14 Mar 2020 15:56:25 +0100
Subject: [PATCH] [SPIDriver] Added assertion to prevent multiple simultaneous
transactions
---
src/shared/drivers/spi/SPIBus.h | 4 ++--
src/shared/drivers/spi/SPIBusInterface.h | 6 ++++++
src/shared/drivers/spi/SPITransaction.cpp | 20 ++++++++++++++++----
src/shared/drivers/spi/SPITransaction.h | 17 ++++++++++-------
4 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/src/shared/drivers/spi/SPIBus.h b/src/shared/drivers/spi/SPIBus.h
index ea732e79f..e31c42329 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 966ddae38..9af7e336a 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 a7e79fa6b..de43334f0 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 af1243dba..b75c20d4a 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;
--
GitLab