Skip to content

Commit

Permalink
[examples] Add simple example to show I2C multiplexer
Browse files Browse the repository at this point in the history
  • Loading branch information
strongly-typed committed Nov 28, 2018
1 parent 07715a7 commit 77ae899
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 0 deletions.
136 changes: 136 additions & 0 deletions examples/generic/i2c_multiplex/i2c_multiplex.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
* Copyright (c) 2018, Sascha Schade
*
* 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 <modm/board.hpp>
#include <modm/processing/timer.hpp>
#include <modm/processing/protothread.hpp>
#include <modm/architecture/interface/i2c_device.hpp>
#include <modm/architecture/interface/i2c_multiplexer.hpp>
#include <modm/driver/gpio/pca9548a.hpp>

using MyI2cMaster = modm::platform::I2cMaster1;
using Mpx = modm::Pca9548a<MyI2cMaster>;
using I2cMultiplexer = modm::I2cMultiplexer<MyI2cMaster, Mpx>;


#ifndef MODM_BOARD_HAS_LOGGER
#include <modm/debug.hpp>
// Add logger manually
using LoggerUsart = Usart2;
using LoggerUsartTx = modm::platform::GpioA2;
using LoggerUsartRx = modm::platform::GpioA3;
modm::IODeviceWrapper< LoggerUsart, modm::IOBuffer::BlockIfFull > loggerDevice;

// Set all four logger streams to use the UART
modm::log::Logger modm::log::debug(loggerDevice);
modm::log::Logger modm::log::info(loggerDevice);
modm::log::Logger modm::log::warning(loggerDevice);
modm::log::Logger modm::log::error(loggerDevice);
#endif

#undef MODM_LOG_LEVEL
#define MODM_LOG_LEVEL modm::log::DEBUG


namespace multiplexer
{
I2cMultiplexer i2cMultiplexer;

// Instances for each channel
using Ch0 = I2cMultiplexer::Ch0< i2cMultiplexer >;
using Ch1 = I2cMultiplexer::Ch1< i2cMultiplexer >;
using Ch2 = I2cMultiplexer::Ch2< i2cMultiplexer >;
using Ch3 = I2cMultiplexer::Ch3< i2cMultiplexer >;
using Ch4 = I2cMultiplexer::Ch4< i2cMultiplexer >;
using Ch5 = I2cMultiplexer::Ch5< i2cMultiplexer >;
using Ch6 = I2cMultiplexer::Ch6< i2cMultiplexer >;
using Ch7 = I2cMultiplexer::Ch7< i2cMultiplexer >;
}


class DeviceThread: public modm::pt::Protothread
{
public:
DeviceThread() : dev0(0x29), dev1(0x29), dev2(0x29), dev3(0x29)
{}

bool
update();

private:
modm::ShortTimeout timeout;

// Simple devices which are just pingable.
// Independent of real device. Any I2C device should be pingable at its address.
modm::I2cDevice<multiplexer::Ch1> dev0;
modm::I2cDevice<multiplexer::Ch2> dev1;
modm::I2cDevice<multiplexer::Ch3> dev2;
modm::I2cDevice<multiplexer::Ch7> dev3;
};

bool
DeviceThread::update()
{
PT_BEGIN();

MODM_LOG_DEBUG << MODM_FILE_INFO;
MODM_LOG_DEBUG << "Ping the Devices" << modm::endl;

// ping the devices repeatedly
while(true)
{
MODM_LOG_DEBUG.printf("[dev ] ping0\n");
MODM_LOG_DEBUG.printf("[dev ] ping0 res: %d\n", PT_CALL(dev0.ping()));
MODM_LOG_DEBUG.printf("[dev ] ping1\n");
MODM_LOG_DEBUG.printf("[dev ] ping1 res: %d\n", PT_CALL(dev1.ping()));
MODM_LOG_DEBUG.printf("[dev ] ping2\n");
MODM_LOG_DEBUG.printf("[dev ] ping2 res: %d\n", PT_CALL(dev2.ping()));
MODM_LOG_DEBUG.printf("[dev ] ping3\n");
MODM_LOG_DEBUG.printf("[dev ] ping3 res: %d\n", PT_CALL(dev3.ping()));
// Do again in 1s
this->timeout.restart(1000);
PT_WAIT_UNTIL(this->timeout.isExpired());
}

PT_END();
}

int
main()
{
Board::initialize();

#ifndef MODM_BOARD_HAS_LOGGER
LoggerUsart::connect<LoggerUsartTx::Tx, LoggerUsartRx::Rx>();
LoggerUsart::initialize<Board::systemClock, modm::Uart::Baudrate::B115200>(12);
#endif

modm::platform::I2cMaster1::connect<modm::platform::GpioB7::Sda, modm::platform::GpioB6::Scl>();
modm::platform::I2cMaster1::initialize<Board::systemClock, modm::platform::I2cMaster1::Baudrate::Standard>();

constexpr uint32_t rate = 1; // Hz
constexpr float interval = 1000.0 / rate; // msec
modm::ShortPeriodicTimer heartbeat(interval);

// Main loop
DeviceThread deviceThread;

uint32_t counter(0);
while (true)
{
deviceThread.update();

if (heartbeat.execute()) {
Board::Leds::toggle();
MODM_LOG_INFO << "Loop counter: " << (counter++) << modm::endl;
}
}

return 0;
}
23 changes: 23 additions & 0 deletions examples/generic/i2c_multiplex/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version='1.0' encoding='UTF-8'?>
<library>
<extends>../../../src/modm/board/nucleo_f303k8/board.xml</extends>
<options>
<option name=":target">stm32f303k8t</option>
<!-- <option name=":target">stm32f103c8t</option> -->
<option name=":platform:uart:2:buffer.tx">2048</option>
<option name=":platform:uart:2:buffer.rx">2048</option>
<option name=":build:build.path">../../../build/generic/i2c_multiplex</option>
</options>
<modules>
<module>:debug</module>
<module>:platform:gpio</module>
<module>:driver</module>
<module>:driver:pca9548a</module>
<module>:platform:i2c:1</module>
<module>:platform:uart:2</module>
<module>:processing:protothread</module>
<module>:processing:resumable</module>
<module>:processing:timer</module>
<module>:build:scons</module>
</modules>
</library>

0 comments on commit 77ae899

Please sign in to comment.