~aleteoryx/muditaos

ref: 9a8ffff654596f42666fdcac137a43319b20b471 muditaos/module-bsp/board/rt1051/bellpx/audio.cpp -rw-r--r-- 3.6 KiB
9a8ffff6 — Lefucjusz [BH-1863] Fix deleted file popup showing in Relaxation 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "audio.hpp"

#include "board/BoardDefinitions.hpp"

extern "C"
{
#include "board.h"
#include "dma_config.h"
}

using namespace bsp::audio;
using namespace drivers;

AudioConfig audioConfig;

namespace
{
    constexpr bool isDerivativeOf44100(const std::uint32_t sampleRate)
    {
        return sampleRate % 11025 == 0;
    }

    DriverPLLParams getPLLParams(const std::uint32_t sampleRate)
    {
        /// The basic formula for calculating PLL4:
        /// (fsclk * (loopDivider + numerator/denominator)) / postDivider

        if (isDerivativeOf44100(sampleRate)) {
            /// PLL4 set to 722.5344MHz, later it will be divided by SAI to generate 11,2896MHz BCLK
            return {
                .loopDivider = 30,
                .postDivider = 1,
                .numerator   = 1056,
                .denominator = 10000,
                .src         = 0,
            };
        }
        else {
            /// PLL4 set to 786.48MHz, later it will be divided by SAI to generate 12,28875MHz BCLK
            return {
                .loopDivider = 32,
                .postDivider = 1,
                .numerator   = 77,
                .denominator = 100,
                .src         = 0,
            };
        }
    }
} // namespace

void bsp::audio::init(const std::uint32_t sampleRate)
{
    audioConfig.pllAudio =
        DriverPLL::Create(static_cast<PLLInstances>(BoardDefinitions::AUDIO_PLL), getPLLParams(sampleRate));
    audioConfig.dmamux =
        DriverDMAMux::Create(static_cast<DMAMuxInstances>(BoardDefinitions::AUDIOCODEC_DMAMUX), DriverDMAMuxParams{});
    audioConfig.dma = DriverDMA::Create(static_cast<DMAInstances>(BoardDefinitions::AUDIOCODEC_DMA), DriverDMAParams{});

    // Enable MCLK clock
    IOMUXC_GPR->GPR1 |= BELL_AUDIOCODEC_SAIx_MCLK_MASK;

    audioConfig.txDMAHandle =
        audioConfig.dma->CreateHandle(static_cast<uint32_t>(BoardDefinitions::AUDIOCODEC_TX_DMA_CHANNEL));
    audioConfig.rxDMAHandle =
        audioConfig.dma->CreateHandle(static_cast<uint32_t>(BoardDefinitions::AUDIOCODEC_RX_DMA_CHANNEL));
    audioConfig.dmamux->Enable(static_cast<uint32_t>(BoardDefinitions::AUDIOCODEC_TX_DMA_CHANNEL),
                               BSP_AUDIOCODEC_SAIx_DMA_TX_SOURCE);
    audioConfig.dmamux->Enable(static_cast<uint32_t>(BoardDefinitions::AUDIOCODEC_RX_DMA_CHANNEL),
                               BSP_AUDIOCODEC_SAIx_DMA_RX_SOURCE);

    audioConfig.mclkSourceClockHz = GetPerphSourceClock(PerphClock_SAI1);

    // Initialize SAI Tx module
    SAI_TxGetDefaultConfig(&audioConfig.config);
    audioConfig.config.masterSlave = kSAI_Master;
    SAI_TxInit(BELL_AUDIOCODEC_SAIx, &audioConfig.config);

    // Initialize SAI Rx module
    SAI_RxGetDefaultConfig(&audioConfig.config);

    audioConfig.config.masterSlave = kSAI_Master;
    SAI_RxInit(BELL_AUDIOCODEC_SAIx, &audioConfig.config);
}

void bsp::audio::deinit()
{
    memset(&audioConfig.config, 0, sizeof(audioConfig.config));
    SAI_Deinit(BELL_AUDIOCODEC_SAIx);
    if (audioConfig.dmamux) {
        audioConfig.dmamux->Disable(static_cast<uint32_t>(BoardDefinitions::AUDIOCODEC_TX_DMA_CHANNEL));
        audioConfig.dmamux->Disable(static_cast<uint32_t>(BoardDefinitions::AUDIOCODEC_RX_DMA_CHANNEL));
    }

    // force order of destruction
    audioConfig.txDMAHandle.reset();
    audioConfig.rxDMAHandle.reset();
    audioConfig.dma.reset();
    audioConfig.dmamux.reset();
    audioConfig.pllAudio.reset();
}

AudioConfig *bsp::audio::AudioConfig::get()
{
    return &audioConfig;
}