Skip to content

Commit 06fe69c

Browse files
ledneczkirleh
authored andcommitted
[I2S] Setup PLL for the I2S peripheral
Functions are added to be able to set up the I2S PLL at startup. PLL multipliers are taken over from ST's example: STM32F4-Discovery_FW_V1.1.0/Project/Audio_playback_and_record/src/system_stm32f4xx.c
1 parent 3936a28 commit 06fe69c

File tree

4 files changed

+57
-2
lines changed

4 files changed

+57
-2
lines changed

src/modm/board/disco_f407vg/board.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,17 @@ struct SystemClock {
8282
{
8383
Rcc::enableExternalCrystal(); // 8MHz
8484
const Rcc::PllFactors pllFactors{
85-
.pllM = 4, // 8MHz / M=4 -> 2MHz
86-
.pllN = 168, // 2MHz * N=168 -> 336MHz
85+
.pllM = 8, // 8MHz / M=8 -> 1MHz
86+
.pllN = 336, // 1MHz * N=336 -> 336MHz
8787
.pllP = 2, // 336MHz / P=2 -> 168MHz = F_cpu
8888
.pllQ = 7 // 336MHz / Q=7 -> 48MHz = F_usb
8989
};
9090
Rcc::enablePll(Rcc::PllSource::ExternalCrystal, pllFactors);
91+
const Rcc::PllI2sFactors pllI2sFactors{
92+
.pllN = 258, // 1 MHz * N=258 -> 258 MHz
93+
.pllR = 3 // 258 MHz / R=3 -> 86 MHz
94+
};
95+
Rcc::enablePllI2s(Rcc::PllSource::ExternalCrystal, pllI2sFactors, 2048);
9196
// set flash latency for 168MHz
9297
Rcc::setFlashLatency<Frequency>();
9398
// switch system clock to PLL output

src/modm/platform/clock/stm32/module.lb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ def build(env):
7070
(target["family"] == "l4" and target["name"][0] in ["p", "q", "r", "s"])
7171
properties["pllsai_p_usb"] = (target["family"] == "f7") or \
7272
((target["family"] == "f4") and target["name"] in ["46", "69", "79"])
73+
properties["plli2s"] = (target["family"] == "f4")
7374
properties["cfgr1"] = ("CDCFGR1" if target.name in ["a0", "a3", "b0", "b3"] else "D1CFGR") \
7475
if target.family == "h7" else "CFGR"
7576
properties["d1"] = ("CD" if target.name in ["a0", "a3", "b0", "b3"] else "D1") \

src/modm/platform/clock/stm32/rcc.cpp.in

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,29 @@ Rcc::enablePll{{id}}(PllSource source, const PllFactors& pllFactors, uint32_t wa
305305

306306
%% endfor
307307

308+
%% if plli2s
309+
bool
310+
modm::platform::Rcc::enablePllI2s(PllSource, const PllI2sFactors& pllFactors, uint32_t waitCycles)
311+
{
312+
// Read reserved and don't care values and clear all other values
313+
uint32_t tmp = RCC->PLLI2SCFGR & ~(RCC_PLLI2SCFGR_PLLI2SN | RCC_PLLI2SCFGR_PLLI2SR);
314+
// set PLL divider and multiplier
315+
tmp |= (((uint32_t) pllFactors.pllN) << RCC_PLLI2SCFGR_PLLI2SN_Pos) & RCC_PLLI2SCFGR_PLLI2SN;
316+
tmp |= (((uint32_t) pllFactors.pllR) << RCC_PLLI2SCFGR_PLLI2SR_Pos) & RCC_PLLI2SCFGR_PLLI2SR;
317+
RCC->PLLI2SCFGR = tmp;
318+
319+
// enable I2S PLL
320+
RCC->CR |= RCC_CR_PLLI2SON;
321+
// wait till I2S PLL gets ready or time is up
322+
while ((RCC->CR & RCC_CR_PLLI2SRDY) == 0)
323+
{
324+
if (not --waitCycles)
325+
return false;
326+
}
327+
return true;
328+
}
329+
%% endif
330+
308331
%% if pllsai_p_usb
309332
bool
310333
Rcc::enablePllSai(const PllSaiFactors& pllFactors, uint32_t waitCycles)

src/modm/platform/clock/stm32/rcc.hpp.in

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,32 @@ public:
609609
setHsiPredivider4Enabled(bool divideBy4, uint32_t waitCycles = 2048);
610610
%% endif
611611

612+
%% if target["family"] == "f4"
613+
/** TODO: comments
614+
* input clock is the HSE or HSI divided by M
615+
* f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN / PLLM)
616+
* f(PLL I2S clock output) = f(VCO clock) / PLLI2SR
617+
*
618+
* \param pllN
619+
* PLLI2S multiplication factor for VCO
620+
* 50 <= PLLI2SN <= 432
621+
*
622+
* \param pllR
623+
* PLLI2S division factor for I2S clocks
624+
* Caution: The I2Ss requires a frequency lower than or equal to 192 MHz to work correctly.
625+
* 2 <= PLLR <= 7
626+
*/
627+
struct PllI2sFactors
628+
{
629+
const uint16_t pllN;
630+
const uint16_t pllR;
631+
};
632+
633+
/* TODO: comments */
634+
static bool
635+
enablePllI2s(PllSource, const PllI2sFactors& pllFactors, uint32_t waitCycles);
636+
%% endif
637+
612638
// sinks
613639
static bool
614640
enableSystemClock(SystemClockSource src, uint32_t waitCycles = 2048);

0 commit comments

Comments
 (0)