-
Notifications
You must be signed in to change notification settings - Fork 134
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
72d35c7
commit 23b4c06
Showing
8 changed files
with
552 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
/* | ||
* Copyright (c) 2022, Andrey Kunitsyn | ||
* | ||
* This file is part of the modm project. | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
*/ | ||
// ---------------------------------------------------------------------------- | ||
|
||
#include "i2c_master_{{ id }}.hpp" | ||
#include <modm/platform/core/resets.hpp> | ||
|
||
|
||
namespace | ||
{ | ||
struct SimpleWait | ||
{ | ||
using State = uint_fast32_t; | ||
static State start() { | ||
return 100'000; | ||
} | ||
static bool check(State& s) { | ||
return --s == 0; | ||
} | ||
}; | ||
} | ||
// ---------------------------------------------------------------------------- | ||
|
||
void modm::platform::I2cMaster{{ id }}::hwReset() | ||
{ | ||
Resets::reset(RESETS_RESET_I2C{{ id }}_BITS); | ||
} | ||
|
||
void modm::platform::I2cMaster{{ id }}::hwUnReset() | ||
{ | ||
Resets::unresetWait(RESETS_RESET_I2C{{ id }}_BITS); | ||
} | ||
|
||
void | ||
modm::platform::I2cMaster{{ id }}::reset() | ||
{ | ||
errorState = Error::SoftwareReset; | ||
restartOnNext = false; | ||
} | ||
|
||
bool | ||
modm::platform::I2cMaster{{ id }}::start(I2cTransaction *transaction, ConfigurationHandler handler) | ||
{ | ||
if (!transaction) | ||
{ | ||
return true; | ||
} | ||
if (not transaction->attaching()) | ||
{ | ||
transaction->detaching(modm::I2c::DetachCause::FailedToAttach); | ||
// return false; // done at the end of the function | ||
} | ||
else | ||
{ | ||
// reset error state | ||
errorState = Error::NoError; | ||
// call the configuration function | ||
if (handler and configuration != handler) { | ||
configuration = handler; | ||
configuration(); | ||
} | ||
|
||
// ask the transaction object about address and next operation. | ||
auto starting = transaction->starting(); | ||
uint8_t address = (starting.address & 0xfe) >> 1; | ||
|
||
hw().enable = 0; | ||
hw().tar = address; | ||
hw().enable = 1; | ||
|
||
auto nextOperation = static_cast<modm::I2c::Operation>(starting.next); | ||
|
||
do | ||
{ | ||
switch (nextOperation) | ||
{ | ||
case modm::I2c::Operation::Write: | ||
{ | ||
auto writing = transaction->writing(); | ||
// what next? | ||
nextOperation = static_cast<modm::I2c::Operation>(writing.next); | ||
doWrite<SimpleWait>(writing.buffer,writing.length,nextOperation!=I2c::Operation::Stop); | ||
} break; | ||
|
||
case I2c::Operation::Read: | ||
{ | ||
auto reading = transaction->reading(); | ||
nextOperation = static_cast<modm::I2c::Operation>(reading.next); | ||
doRead<SimpleWait>(reading.buffer,reading.length,nextOperation!=I2c::Operation::Stop); | ||
break; | ||
} | ||
|
||
case I2c::Operation::Restart: | ||
starting = transaction->starting(); | ||
nextOperation = static_cast<modm::I2c::Operation>(starting.next); | ||
break; | ||
|
||
default: | ||
case I2c::Operation::Stop: | ||
transaction->detaching(modm::I2c::DetachCause::NormalStop); | ||
return true; | ||
} | ||
if (errorState != Error::NoError) | ||
{ | ||
transaction->detaching(modm::I2c::DetachCause::ErrorCondition); | ||
return true; | ||
} | ||
} | ||
while (true); | ||
} | ||
return false; | ||
} | ||
|
||
modm::I2cMaster::Error | ||
modm::platform::I2cMaster{{ id }}::getErrorState() | ||
{ | ||
return errorState; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
/* | ||
* Copyright (c) 2022, Andrey Kunitsyn | ||
* | ||
* This file is part of the modm project. | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
*/ | ||
// ---------------------------------------------------------------------------- | ||
|
||
#pragma once | ||
|
||
#include "../device.hpp" | ||
#include <modm/platform/gpio/connector.hpp> | ||
#include <modm/architecture/interface/i2c_master.hpp> | ||
#include <modm/math/algorithm/prescaler.hpp> | ||
#include <hardware/structs/i2c.h> | ||
|
||
namespace modm::platform | ||
{ | ||
|
||
/** | ||
* I2cMaster implementation of I2C{{ id }} module. | ||
* | ||
* @author Andrey Kunitsyn | ||
* @ingroup modm_platform_i2c modm_platform_i2c_{{id}} | ||
*/ | ||
class I2cMaster{{ id }} : public ::modm::I2cMaster | ||
{ | ||
public: | ||
static inline i2c_hw_t& hw() { return *i2c{{ id }}_hw; } | ||
public: | ||
template<class... Signals, ResetDevices reset = ResetDevices::Standard> | ||
static void | ||
connect(PullUps pullups = PullUps::External) | ||
{ | ||
using Connector = GpioConnector<Peripheral::I2c{{ id }}, Signals...>; | ||
using Scl = typename Connector::template GetSignal<Gpio::Signal::Scl>; | ||
using Sda = typename Connector::template GetSignal<Gpio::Signal::Sda>; | ||
static_assert(sizeof...(Signals) == 2 and | ||
Connector::template IsValid<Scl> and Connector::template IsValid<Sda>, | ||
"I2cMaster{{id}}::connect() requires one Scl and one Sda signal!"); | ||
const Gpio::InputType input = | ||
(pullups == PullUps::Internal) ? Gpio::InputType::PullUp : Gpio::InputType::Floating; | ||
|
||
Connector::disconnect(); | ||
Scl::configure(input); | ||
Scl::setSlewRate(Gpio::SlewRate::Slow); | ||
Sda::configure(input); | ||
Sda::setSlewRate(Gpio::SlewRate::Slow); | ||
if (reset != ResetDevices::NoReset) resetDevices<Scl, uint32_t(reset)>(); | ||
Connector::connect(); | ||
} | ||
|
||
static void hwReset(); | ||
static void hwUnReset(); | ||
|
||
/** | ||
* Set up the I2C module for master operation. | ||
* | ||
* @param rate | ||
* `Standard` or `Fast` or `Fast+`, `High` datarate is not supported | ||
*/ | ||
template<class SystemClock, baudrate_t baudrate=kBd(100), percent_t tolerance=pct(5)> | ||
static void | ||
initialize(); | ||
|
||
template< class SystemClock, baudrate_t baudrate, percent_t tolerance=pct(5)> | ||
static uint32_t | ||
setBaudrate(); | ||
|
||
// start documentation inherited | ||
static bool | ||
start(I2cTransaction *transaction, ConfigurationHandler handler = nullptr); | ||
|
||
static Error | ||
getErrorState(); | ||
|
||
static void | ||
reset(); | ||
// end documentation inherited | ||
|
||
template <typename Wait> | ||
static Error transfer(uint8_t addr,const uint8_t* write,size_t writeLen, | ||
uint8_t* read, size_t readLen); | ||
|
||
private: | ||
template <typename Wait> | ||
static void doWrite(const uint8_t* write,size_t writeLen,bool nostop); | ||
template <typename Wait> | ||
static void doRead(uint8_t* read,size_t readLen,bool nostop); | ||
static bool isReadAvailable() { | ||
return hw().rxflr; | ||
} | ||
static bool isWriteAvailable() { | ||
constexpr size_t IC_TX_BUFFER_DEPTH = 16; | ||
return IC_TX_BUFFER_DEPTH - hw().txflr; | ||
} | ||
static inline Error errorState{Error::NoError}; | ||
static inline I2c::ConfigurationHandler configuration{nullptr}; | ||
static inline bool restartOnNext{false}; | ||
}; | ||
|
||
} // namespace modm::platform | ||
#include "i2c_master_impl_{{id}}.hpp" |
Oops, something went wrong.