Skyward boardcore
Loading...
Searching...
No Matches
I2CDriver.h
Go to the documentation of this file.
1/* Copyright (c) 2022 Skyward Experimental Rocketry
2 * Author: Emilio Corigliano
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
24
25#include "miosix.h"
26
27#if defined(I2C4)
28#define N_I2C_PORTS 4
29#elif defined(I2C3)
30#define N_I2C_PORTS 3
31#elif defined(I2C2)
32#define N_I2C_PORTS 2
33#elif defined(I2C1)
34#define N_I2C_PORTS 1
35#else
36#error "Your architecture doesn't support I2C"
37#endif
38
39namespace Boardcore
40{
41
57{
58public:
59 enum Operation : uint8_t
60 {
61 WRITE = 0,
62 READ = 1
63 };
64
65 enum Speed : uint8_t
66 {
68 FAST = 1,
69#ifdef _ARCH_CORTEXM7_STM32F7
70 FAST_PLUS = 2,
71 MAX_SPEED = FAST_PLUS
72#else
74#endif // _ARCH_CORTEXM7_STM32F7
75 };
76
77 enum Addressing : uint8_t
78 {
79 BIT7 = 0,
80 BIT10 = 1
81 };
82
87 enum Errors : uint16_t
88 {
90 BUS_LOCKED = 1 << 0,
91 BERR = 1 << 1,
92 ARLO = 1 << 2,
93 AF = 1 << 3,
94 OVR = 1 << 4,
95 SB_NOT_SENT = 1 << 5,
96 ADDR_ERROR = 1 << 6
97 };
98
103 typedef struct
104 {
108 uint16_t slaveAddress;
109
112
115
117 bool MSBFirst = false;
119
135 I2CDriver(I2C_TypeDef* i2c, miosix::GpioPin scl, miosix::GpioPin sda);
136
138 I2CDriver(const I2CDriver&) = delete;
139 I2CDriver& operator=(const I2CDriver&) = delete;
140 I2CDriver(I2CDriver&&) = delete;
142
148
159 [[nodiscard]] bool read(const I2CSlaveConfig& slaveConfig, void* buffer,
160 const size_t& nBytes);
161
173 [[nodiscard]] bool write(const I2CSlaveConfig& slaveConfig,
174 const void* buffer, const size_t& nBytes,
175 bool generateStop = true);
176
185 void flushBus();
186
200 uint16_t getLastError();
201
213
224
225private:
232 typedef struct
233 {
234 Operation operation;
235 uint8_t* buffRead;
236 const uint8_t* buffWrite;
237 size_t nBytes;
238 size_t nBytesDone;
239 bool generateStop;
240 } I2CTransaction;
241
246 void init();
247
253 void setupPeripheral(const I2CSlaveConfig& slaveConfig);
254
255#ifdef _ARCH_CORTEXM7_STM32F7
260 inline void setupTransaction();
261
266 inline void setupReload();
267#endif // _ARCH_CORTEXM7_STM32F7
268
280 [[nodiscard]] bool doOperation(const I2CSlaveConfig& slaveConfig);
281
295 inline bool IRQwaitForOperationCompletion(
296 miosix::FastInterruptDisableLock& dLock);
297
303 inline void IRQwakeUpWaitingThread();
304
305 I2C_TypeDef* i2c;
306 uint8_t id;
307 IRQn_Type irqnEv;
308 IRQn_Type irqnErr;
309 miosix::GpioPin scl;
310 miosix::GpioPin sda;
311
312 uint16_t lastError = NO_ERROR;
313 uint32_t error = 0;
314 bool reStarting = false;
315 miosix::Thread* waiting{};
316 I2CTransaction transaction;
317
318 PrintLogger logger = Logging::getLogger("i2c");
319};
320
321} // namespace Boardcore
Low level driver for I2C peripherals.
Definition I2CDriver.h:57
I2CDriver & operator=(const I2CDriver &)=delete
I2CDriver(const I2CDriver &)=delete
bool read(const I2CSlaveConfig &slaveConfig, void *buffer, const size_t &nBytes)
Read operation to read nBytes. In case of an error during the communication, this method returns fals...
void flushBus()
Performs the recovery from the locked state if necessary.
I2CDriver & operator=(I2CDriver &&)=delete
uint16_t getLastError()
Returns the last errors happened in the communication.
Errors
Error enums with a value that makes it possible to keep the "or-red" value to store more errors.
Definition I2CDriver.h:88
@ BUS_LOCKED
Detected a locked state on the bus.
Definition I2CDriver.h:90
@ BERR
External Start or stop condition detected.
Definition I2CDriver.h:91
@ NO_ERROR
The bus didn't have any error.
Definition I2CDriver.h:89
@ ADDR_ERROR
Address sent but peripheral in wrong state.
Definition I2CDriver.h:96
@ OVR
Overrun/underrun error.
Definition I2CDriver.h:94
@ AF
Acknowledge failure.
Definition I2CDriver.h:93
@ ARLO
Arbitration lost.
Definition I2CDriver.h:92
@ SB_NOT_SENT
Start bit not sent.
Definition I2CDriver.h:95
I2CDriver(I2CDriver &&)=delete
I2CDriver(I2C_TypeDef *i2c, miosix::GpioPin scl, miosix::GpioPin sda)
Constructor for the I2C low-level driver.
bool write(const I2CSlaveConfig &slaveConfig, const void *buffer, const size_t &nBytes, bool generateStop=true)
Write operation to write nBytes. In case of an error during the communication, this method returns fa...
~I2CDriver()
Disables the peripheral, the interrupts in the NVIC and the peripheral's clock.
void IRQhandleInterrupt()
Handles the interrupt for events of the specific peripheral.
void IRQhandleErrInterrupt()
Handles the interrupt for the errors in the specific peripheral.
static PrintLogger getLogger(const string &name)
This file includes all the types the logdecoder script will decode.
Configuration struct for a slave device. This will be used for configuring the bus in order to commun...
Definition I2CDriver.h:104
uint16_t slaveAddress
Addressing mode of the device.
Definition I2CDriver.h:108