Skip to content
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/modm/architecture/interface/i2s.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2009-2012, Fabian Greif
* Copyright (c) 2010, Martin Rosekeit
* Copyright (c) 2012-2015, Niklas Hauser
* Copyright (c) 2013, Sascha Schade
* Copyright (c) 2021, Marton Ledneczki
*
* 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/.
*/
// ----------------------------------------------------------------------------

#ifndef MODM_INTERFACE_I2S_HPP
#define MODM_INTERFACE_I2S_HPP

#include <modm/architecture/interface/peripheral.hpp>

namespace modm
{

/// @ingroup modm_architecture_i2s
struct I2s
{
/// The signature of the configuration function.
using ConfigurationHandler = void(*)();
};

} // namespace modm

#endif // MODM_INTERFACE_I2S_HPP
68 changes: 68 additions & 0 deletions src/modm/architecture/interface/i2s_master.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2009-2012, Fabian Greif
* Copyright (c) 2010, Martin Rosekeit
* Copyright (c) 2012-2017, Niklas Hauser
* Copyright (c) 2013, Sascha Schade
* Copyright (c) 2021, Marton Lednczki
*
* 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/.
*/
// ----------------------------------------------------------------------------

#ifndef MODM_INTERFACE_I2S_MASTER_HPP
#define MODM_INTERFACE_I2S_MASTER_HPP

#include <modm/processing/resumable.hpp>
#include "i2s.hpp"

namespace modm
{

/**
* Interface for a I2S Master
*
* @author Marton Ledneczki
* @ingroup modm_architecture_i2s
*/
class I2sMaster : public ::modm::PeripheralDriver, public I2s
{
#ifdef __DOXYGEN__
public:
/**
* Connect GPIOs to the peripheral and configure them.
*
* This configures the CK (serial clock), MCK (master clock),
* SD (serial data) and WS (word select) signals and connects them.
*
* @tparam Signals
* One CK, SD, WS, MCK signal are required
* and can be passed out-of-order.
*/
template< class... Signals >
static void
connect();

/**
* Initializes the hardware and sets the samplerate.
*
* @tparam SystemClock
* the currently active system clock
* @tparam samplerate
* the desired sample rate in Hz
* @tparam tolerance
* the allowed relative tolerance for the resulting samplerate
*/
template< class SystemClock, frequency_t samplerate, percent_t tolerance=pct(0.019) >
static void
initialize();

#endif
};

} // namespace modm

#endif // MODM_INTERFACE_SPI_MASTER_HPP
16 changes: 16 additions & 0 deletions src/modm/architecture/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,21 @@ class I2cMultiplexer(Module):
env.copy("interface/i2c_multiplexer.hpp")
# -----------------------------------------------------------------------------

class I2s(Module):
def init(self, module):
module.name = "i2s"
module.description = "Inter-IC Sound (I2S)"

def prepare(self, module, options):
module.depends(":processing:resumable")
return True

def build(self, env):
env.outbasepath = "modm/src/modm/architecture"
env.copy("interface/i2s.hpp")
env.copy("interface/i2s_master.hpp")
# -----------------------------------------------------------------------------

class Interrupt(Module):
def init(self, module):
module.name = "interrupt"
Expand Down Expand Up @@ -381,6 +396,7 @@ def prepare(module, options):
module.add_submodule(I2c())
module.add_submodule(I2cDevice())
module.add_submodule(I2cMultiplexer())
module.add_submodule(I2s())
module.add_submodule(Interrupt())
module.add_submodule(Memory())
module.add_submodule(OneWire())
Expand Down
29 changes: 21 additions & 8 deletions src/modm/board/disco_f407vg/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ struct SystemClock {
static constexpr uint32_t Spi5 = Apb2;
static constexpr uint32_t Spi6 = Apb2;

static constexpr uint32_t I2s2 = Spi2;
static constexpr uint32_t I2s3 = Spi3;

static constexpr uint32_t I2sPll = 86_MHz;

static constexpr uint32_t Usart1 = Apb2;
static constexpr uint32_t Usart2 = Apb1;
static constexpr uint32_t Usart3 = Apb1;
Expand Down Expand Up @@ -82,12 +87,17 @@ struct SystemClock {
{
Rcc::enableExternalCrystal(); // 8MHz
const Rcc::PllFactors pllFactors{
.pllM = 4, // 8MHz / M=4 -> 2MHz
.pllN = 168, // 2MHz * N=168 -> 336MHz
.pllM = 8, // 8MHz / M=8 -> 1MHz
.pllN = 336, // 1MHz * N=336 -> 336MHz
.pllP = 2, // 336MHz / P=2 -> 168MHz = F_cpu
.pllQ = 7 // 336MHz / Q=7 -> 48MHz = F_usb
};
Rcc::enablePll(Rcc::PllSource::ExternalCrystal, pllFactors);
const Rcc::PllI2sFactors pllI2sFactors{
.pllN = 258, // 1 MHz * N=258 -> 258 MHz
.pllR = 3 // 258 MHz / R=3 -> 86 MHz
};
Rcc::enablePllI2s(pllI2sFactors, 2048);
// set flash latency for 168MHz
Rcc::setFlashLatency<Frequency>();
// switch system clock to PLL output
Expand Down Expand Up @@ -143,7 +153,7 @@ using Scl = GpioB6; // Audio_SCL
using Sda = GpioB9; // Audio_SDA

using I2cMaster = I2cMaster1;
//using I2sMaster = I2sMaster3;
using I2sMaster = I2sMaster3;
}


Expand Down Expand Up @@ -202,15 +212,18 @@ initializeLis3()
inline void
initializeCs43()
{
// cs43::Lrck::connect(cs43::I2sMaster::Ws);
// cs43::Mclk::connect(cs43::I2sMaster::Mck);
// cs43::Sclk::connect(cs43::I2sMaster::Ck);
// cs43::Sdin::connect(cs43::I2sMaster::Sd);

cs43::I2sMaster::connect<cs43::Mclk::Mck, cs43::Sclk::Ck,
cs43::Lrck::Ws, cs43::Sdin::Sd>();
cs43::I2sMaster::initialize<SystemClock, 48_kHz>();
cs43::Reset::setOutput(modm::Gpio::High);

cs43::I2cMaster::connect<cs43::Scl::Scl, cs43::Sda::Sda>();
cs43::I2cMaster::initialize<SystemClock, 100_kHz>();

cs43::Reset::setOutput(modm::Gpio::Low);
modm::delay_ms(2);
cs43::Reset::setOutput(modm::Gpio::High);

}

/// not supported yet, due to missing I2S driver
Expand Down
1 change: 1 addition & 0 deletions src/modm/board/disco_f407vg/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def prepare(module, options):
":platform:gpio",
":platform:i2c:1",
":platform:spi:1",
":platform:i2s:3",
":platform:usb:fs")
return True

Expand Down
Loading