Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new method enableMasterClock(fsMultiplier) #641

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
40 changes: 36 additions & 4 deletions libraries/I2S/src/I2S.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ static I2SDevice_SAMD21G18x i2sd(*I2S);

int I2SClass::_beginCount = 0;

I2SClass::I2SClass(uint8_t deviceIndex, uint8_t clockGenerator, uint8_t sdPin, uint8_t sckPin, uint8_t fsPin) :
I2SClass::I2SClass(uint8_t deviceIndex, uint8_t clockGenerator, uint8_t sdPin, uint8_t sckPin, uint8_t fsPin, uint8_t mckPin) :
_deviceIndex(deviceIndex),
_clockGenerator(clockGenerator),
_sdPin(sdPin),
_sckPin(sckPin),
_fsPin(fsPin),
_mckPin(mckPin),
_mckFsMultiplier(0),

_state(I2S_STATE_IDLE),
_dmaChannel(-1),
Expand Down Expand Up @@ -108,7 +110,16 @@ int I2SClass::begin(int mode, long sampleRate, int bitsPerSample, bool driveCloc

if (driveClock) {
// set up clock
enableClock(sampleRate * 2 * bitsPerSample);
int F_BCKL = sampleRate * 2 * bitsPerSample; // LRCLOCK
int F_MCKL = _mckFsMultiplier * sampleRate; // SYSCLK

enableClock(_mckFsMultiplier ? F_MCKL : F_BCKL);

if (_mckFsMultiplier) {
i2sd.enableMasterClock(_deviceIndex);
i2sd.setMasterClockDiv(_deviceIndex, F_MCKL / F_BCKL - 1);
pinPeripheral(_mckPin, PIO_COM);
}

i2sd.setSerialClockSelectMasterClockDiv(_deviceIndex);
i2sd.setFrameSyncSelectSerialClockDiv(_deviceIndex);
Expand Down Expand Up @@ -168,6 +179,11 @@ void I2SClass::end()
pinMode(_fsPin, INPUT);
pinMode(_sckPin, INPUT);

if (_mckFsMultiplier) {
pinMode(_mckPin, INPUT);
_mckFsMultiplier = 0;
}

disableClock();

_beginCount--;
Expand Down Expand Up @@ -401,9 +417,25 @@ void I2SClass::setBufferSize(int bufferSize)
_doubleBuffer.setSize(bufferSize);
}

void I2SClass::enableMasterClock(int mckFsMultiplier)
{
switch (mckFsMultiplier) {
case 128:
case 192:
case 256:
case 384:
case 512:
_mckFsMultiplier = mckFsMultiplier;
return;

default:
_mckFsMultiplier = 256;
}
}

void I2SClass::enableClock(int divider)
{
int div = SystemCoreClock / divider;
int div = (float)SystemCoreClock / divider + 0.5f;
int src = GCLK_GENCTRL_SRC_DFLL48M_Val;

if (div > 255) {
Expand Down Expand Up @@ -529,5 +561,5 @@ void I2SClass::onDmaTransferComplete(int channel)
}

#if I2S_INTERFACES_COUNT > 0
I2SClass I2S(I2S_DEVICE, I2S_CLOCK_GENERATOR, PIN_I2S_SD, PIN_I2S_SCK, PIN_I2S_FS);
I2SClass I2S(I2S_DEVICE, I2S_CLOCK_GENERATOR, PIN_I2S_SD, PIN_I2S_SCK, PIN_I2S_FS, PIN_I2S_MCK);
#endif
9 changes: 7 additions & 2 deletions libraries/I2S/src/I2S.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "utility/I2SDoubleBuffer.h"

#define I2S_HAS_SET_BUFFER_SIZE 1
#define PIN_I2S_MCK PIN_WIRE_SCL //I2S_MCK[0]

typedef enum {
I2S_PHILIPS_MODE,
Expand All @@ -35,11 +36,11 @@ class I2SClass : public Stream
{
public:
// the device index and pins must map to the "COM" pads in Table 6-1 of the datasheet
I2SClass(uint8_t deviceIndex, uint8_t clockGenerator, uint8_t sdPin, uint8_t sckPin, uint8_t fsPin);
I2SClass(uint8_t deviceIndex, uint8_t clockGenerator, uint8_t sdPin, uint8_t sckPin, uint8_t fsPin, uint8_t mckPin);

// the SCK and FS pins are driven as outputs using the sample rate
int begin(int mode, long sampleRate, int bitsPerSample);
// the SCK and FS pins are inputs, other side controls sample rate
// the SCK and FS pins are inputs, other side controls the sample rate
int begin(int mode, int bitsPerSample);
void end();

Expand All @@ -65,6 +66,7 @@ class I2SClass : public Stream
void onReceive(void(*)(void));

void setBufferSize(int bufferSize);
void enableMasterClock(int _mckFsMultiplier = 256);

private:
int begin(int mode, long sampleRate, int bitsPerSample, bool driveClock);
Expand Down Expand Up @@ -94,6 +96,9 @@ class I2SClass : public Stream
uint8_t _sckPin;
uint8_t _fsPin;

uint8_t _mckPin;
int _mckFsMultiplier;

i2s_state_t _state;
int _dmaChannel;
int _bitsPerSample;
Expand Down
8 changes: 8 additions & 0 deletions libraries/I2S/src/utility/SAMD21_I2SDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ class I2SDevice_SAMD21G18x {
return (index == 0) ? I2S_GCLK_ID_0 : I2S_GCLK_ID_1;
}

inline void setMasterClockDiv(int index, int div) {
i2s.CLKCTRL[index].bit.MCKDIV = div;
}

inline void enableMasterClock(int index) {
i2s.CLKCTRL[index].bit.MCKEN = 1;
}

inline void setSerialClockSelectMasterClockDiv(int index) {
i2s.CLKCTRL[index].bit.SCKSEL = I2S_CLKCTRL_SCKSEL_MCKDIV_Val;
}
Expand Down