DM: in progress i2s / dma support
This commit is contained in:
parent
8a32178667
commit
dc5464d328
5 changed files with 402 additions and 10 deletions
|
|
@ -20,10 +20,21 @@
|
|||
#include <wiring_private.h>
|
||||
|
||||
#include "utility/DMA.h"
|
||||
|
||||
#if defined(__SAMD51__)
|
||||
|
||||
#include "utility/SAMD51_I2SDevice.h"
|
||||
|
||||
static I2SDevice_SAMD51 i2sd(*I2S);
|
||||
|
||||
#else
|
||||
|
||||
#include "utility/SAMD21_I2SDevice.h"
|
||||
|
||||
static I2SDevice_SAMD21G18x i2sd(*I2S);
|
||||
|
||||
#endif
|
||||
|
||||
#include "I2S.h"
|
||||
|
||||
int I2SClass::_beginCount = 0;
|
||||
|
|
@ -98,7 +109,11 @@ int I2SClass::begin(int mode, long sampleRate, int bitsPerSample, bool driveCloc
|
|||
|
||||
if (_beginCount == 0) {
|
||||
// enable the I2S interface
|
||||
#if defined(__SAMD51__)
|
||||
MCLK->APBDMASK.reg |= MCLK_APBDMASK_I2S;
|
||||
#else
|
||||
PM->APBCMASK.reg |= PM_APBCMASK_I2S;
|
||||
#endif
|
||||
|
||||
// reset the device
|
||||
i2sd.reset();
|
||||
|
|
@ -176,7 +191,11 @@ void I2SClass::end()
|
|||
i2sd.disable();
|
||||
|
||||
// disable the I2S interface
|
||||
#if defined(__SAMD51__)
|
||||
MCLK->APBDMASK.reg &= ~(MCLK_APBDMASK_I2S);
|
||||
#else
|
||||
PM->APBCMASK.reg &= ~PM_APBCMASK_I2S;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,9 +39,14 @@ DMAClass::~DMAClass()
|
|||
void DMAClass::begin()
|
||||
{
|
||||
if (_beginCount == 0) {
|
||||
|
||||
#if defined(__SAMD51__)
|
||||
MCLK->AHBMASK.bit.DMAC_ = 1;
|
||||
#else
|
||||
// enable the DMA interface
|
||||
PM->AHBMASK.bit.DMAC_ = 1;
|
||||
PM->APBBMASK.bit.DMAC_ = 1;
|
||||
#endif
|
||||
|
||||
// perform a reset
|
||||
DMAC->CTRL.bit.SWRST = 1;
|
||||
|
|
@ -57,9 +62,35 @@ void DMAClass::begin()
|
|||
DMAC->CTRL.bit.LVLEN3 = 1;
|
||||
DMAC->CTRL.bit.DMAENABLE = 1;
|
||||
|
||||
// enable the interrupt at lowest priority
|
||||
#if defined(__SAMD51__)
|
||||
NVIC_DisableIRQ(DMAC_0_IRQn);
|
||||
NVIC_ClearPendingIRQ(DMAC_0_IRQn);
|
||||
NVIC_EnableIRQ(DMAC_0_IRQn);
|
||||
NVIC_SetPriority(DMAC_0_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
|
||||
|
||||
NVIC_DisableIRQ(DMAC_1_IRQn);
|
||||
NVIC_ClearPendingIRQ(DMAC_1_IRQn);
|
||||
NVIC_EnableIRQ(DMAC_1_IRQn);
|
||||
NVIC_SetPriority(DMAC_1_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
|
||||
|
||||
NVIC_DisableIRQ(DMAC_2_IRQn);
|
||||
NVIC_ClearPendingIRQ(DMAC_2_IRQn);
|
||||
NVIC_EnableIRQ(DMAC_2_IRQn);
|
||||
NVIC_SetPriority(DMAC_2_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
|
||||
|
||||
NVIC_DisableIRQ(DMAC_3_IRQn);
|
||||
NVIC_ClearPendingIRQ(DMAC_3_IRQn);
|
||||
NVIC_EnableIRQ(DMAC_3_IRQn);
|
||||
NVIC_SetPriority(DMAC_3_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
|
||||
|
||||
NVIC_DisableIRQ(DMAC_4_IRQn);
|
||||
NVIC_ClearPendingIRQ(DMAC_4_IRQn);
|
||||
NVIC_EnableIRQ(DMAC_4_IRQn);
|
||||
NVIC_SetPriority(DMAC_4_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
|
||||
#else
|
||||
NVIC_EnableIRQ(DMAC_IRQn);
|
||||
NVIC_SetPriority(DMAC_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
_beginCount++;
|
||||
|
|
@ -71,14 +102,27 @@ void DMAClass::end()
|
|||
|
||||
if (_beginCount == 0) {
|
||||
// disable the interrupt
|
||||
#if defined(__SAMD51__)
|
||||
NVIC_DisableIRQ(DMAC_0_IRQn);
|
||||
NVIC_DisableIRQ(DMAC_1_IRQn);
|
||||
NVIC_DisableIRQ(DMAC_2_IRQn);
|
||||
NVIC_DisableIRQ(DMAC_3_IRQn);
|
||||
NVIC_DisableIRQ(DMAC_4_IRQn);
|
||||
#else
|
||||
NVIC_DisableIRQ(DMAC_IRQn);
|
||||
#endif
|
||||
|
||||
// disable
|
||||
DMAC->CTRL.bit.DMAENABLE = 0;
|
||||
|
||||
// disable the DMA interface
|
||||
PM->APBBMASK.bit.DMAC_ = 0;
|
||||
#if defined(__SAMD51__)
|
||||
MCLK->AHBMASK.bit.DMAC_ = 0;
|
||||
#else
|
||||
// enable the DMA interface
|
||||
PM->AHBMASK.bit.DMAC_ = 0;
|
||||
PM->APBBMASK.bit.DMAC_ = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -96,9 +140,14 @@ int DMAClass::allocateChannel()
|
|||
memset((void*)&_descriptors[i], 0x00, sizeof(_descriptors[i]));
|
||||
|
||||
// select the channel and reset it
|
||||
#if defined(__SAMD51__)
|
||||
DMAC->Channel[i].CHCTRLA.bit.ENABLE = 0;
|
||||
DMAC->Channel[i].CHCTRLA.bit.SWRST = 1;
|
||||
#else
|
||||
DMAC->CHID.bit.ID = i;
|
||||
DMAC->CHCTRLA.bit.ENABLE = 0;
|
||||
DMAC->CHCTRLA.bit.SWRST = 1;
|
||||
#endif
|
||||
|
||||
channel = i;
|
||||
break;
|
||||
|
|
@ -111,8 +160,12 @@ int DMAClass::allocateChannel()
|
|||
void DMAClass::freeChannel(int channel)
|
||||
{
|
||||
// select the channel and disable it
|
||||
DMAC->CHID.bit.ID = channel;
|
||||
DMAC->CHCTRLA.bit.ENABLE = 0;
|
||||
#if defined(__SAMD51__)
|
||||
DMAC->Channel[channel].CHCTRLA.bit.ENABLE = 0;
|
||||
#else
|
||||
DMAC->CHID.bit.ID = channel;
|
||||
DMAC->CHCTRLA.bit.ENABLE = 0;
|
||||
#endif
|
||||
|
||||
_channelMask &= ~(1 << channel);
|
||||
}
|
||||
|
|
@ -120,12 +173,21 @@ void DMAClass::freeChannel(int channel)
|
|||
void DMAClass::setPriorityLevel(int channel, int level)
|
||||
{
|
||||
// select the channel and set priority level
|
||||
DMAC->CHID.bit.ID = channel;
|
||||
DMAC->CHCTRLB.bit.LVL = level;
|
||||
#if defined(__SAMD51__)
|
||||
|
||||
DMAC->Channel[channel].CHPRILVL.reg = level;
|
||||
#else
|
||||
DMAC->CHID.bit.ID = channel;
|
||||
DMAC->CHCTRLB.bit.LVL = level;
|
||||
#endif
|
||||
}
|
||||
|
||||
void DMAClass::setTriggerSource(int channel, int source)
|
||||
{
|
||||
#if defined(__SAMD51__)
|
||||
DMAC->Channel[channel].CHCTRLA.bit.TRIGSRC = source;
|
||||
DMAC->Channel[channel].CHCTRLA.bit.TRIGACT = DMAC_CHCTRLA_TRIGACT_BLOCK_Val;
|
||||
#else
|
||||
// select the channel and set a trigger source
|
||||
DMAC->CHID.bit.ID = channel;
|
||||
DMAC->CHCTRLB.bit.TRIGSRC = source;
|
||||
|
|
@ -136,6 +198,7 @@ void DMAClass::setTriggerSource(int channel, int source)
|
|||
} else {
|
||||
DMAC->CHCTRLB.bit.TRIGACT = DMAC_CHCTRLB_TRIGACT_BLOCK_Val;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void DMAClass::setTransferWidth(int channel, int transferWidth)
|
||||
|
|
@ -178,8 +241,11 @@ int DMAClass::transfer(int channel, void* src, void* dst, uint16_t size)
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#if !defined(__SAMD51__)
|
||||
// select the channel
|
||||
DMAC->CHID.bit.ID = channel;
|
||||
#endif
|
||||
|
||||
// disable event output generation and block actions
|
||||
_descriptors[channel].BTCTRL.bit.EVOSEL = DMAC_BTCTRL_EVOSEL_DISABLE_Val;
|
||||
|
|
@ -223,16 +289,26 @@ int DMAClass::transfer(int channel, void* src, void* dst, uint16_t size)
|
|||
// validate the descriptor
|
||||
_descriptors[channel].BTCTRL.bit.VALID = 1;
|
||||
|
||||
#if defined(__SAMD51__)
|
||||
DMAC->Channel[channel].CHINTENSET.bit.TERR = 1;
|
||||
DMAC->Channel[channel].CHINTENSET.bit.TCMPL = 1;
|
||||
DMAC->Channel[channel].CHCTRLA.bit.ENABLE = 1;
|
||||
|
||||
if (DMAC->Channel[channel].CHCTRLA.bit.TRIGSRC == 0) {
|
||||
// uses software trigger, so trigger it
|
||||
DMAC->SWTRIGCTRL.reg |= (1 << channel);
|
||||
}
|
||||
#else
|
||||
// enable channel and transfer error + complete interrupts
|
||||
DMAC->CHINTENSET.bit.TERR = 1;
|
||||
DMAC->CHINTENSET.bit.TCMPL = 1;
|
||||
DMAC->CHCTRLA.bit.ENABLE = 1;
|
||||
|
||||
|
||||
if (DMAC->CHCTRLB.bit.TRIGSRC == 0) {
|
||||
// uses software trigger, so trigger it
|
||||
DMAC->SWTRIGCTRL.reg |= (1 << channel);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -251,11 +327,32 @@ void DMAClass::onService()
|
|||
{
|
||||
// get the channel and select it
|
||||
int channel = DMAC->INTPEND.bit.ID;
|
||||
#if !defined(__SAMD51__)
|
||||
DMAC->CHID.bit.ID = channel;
|
||||
#endif
|
||||
|
||||
// invalidate the channel
|
||||
_descriptors[channel].BTCTRL.bit.VALID = 0;
|
||||
|
||||
#if defined(__SAMD51__)
|
||||
if (DMAC->Channel[channel].CHINTFLAG.bit.TERR) {
|
||||
// clear the error interrupt and call the error callback if there is one
|
||||
DMAC->Channel[channel].CHINTFLAG.bit.TERR = 1;
|
||||
|
||||
if (_transferErrorCallbacks[channel]) {
|
||||
_transferErrorCallbacks[channel](channel);
|
||||
}
|
||||
}
|
||||
|
||||
if (DMAC->Channel[channel].CHINTFLAG.bit.TCMPL) {
|
||||
// clear the complete interrupt and call the callback if there is one
|
||||
DMAC->Channel[channel].CHINTFLAG.bit.TCMPL = 1;
|
||||
|
||||
if (_transferCompleteCallbacks[channel]) {
|
||||
_transferCompleteCallbacks[channel](channel);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (DMAC->CHINTFLAG.bit.TERR) {
|
||||
// clear the error interrupt and call the error callback if there is one
|
||||
DMAC->CHINTFLAG.bit.TERR = 1;
|
||||
|
|
@ -273,12 +370,55 @@ void DMAClass::onService()
|
|||
_transferCompleteCallbacks[channel](channel);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
#if defined(__SAMD51__)
|
||||
static void _dmac_handler(void)
|
||||
{
|
||||
DMA.onService();
|
||||
}
|
||||
/**
|
||||
* \brief DMAC interrupt handler
|
||||
*/
|
||||
void DMAC_0_Handler(void)
|
||||
{
|
||||
_dmac_handler();
|
||||
}
|
||||
/**
|
||||
* \brief DMAC interrupt handler
|
||||
*/
|
||||
void DMAC_1_Handler(void)
|
||||
{
|
||||
_dmac_handler();
|
||||
}
|
||||
/**
|
||||
* \brief DMAC interrupt handler
|
||||
*/
|
||||
void DMAC_2_Handler(void)
|
||||
{
|
||||
_dmac_handler();
|
||||
}
|
||||
/**
|
||||
* \brief DMAC interrupt handler
|
||||
*/
|
||||
void DMAC_3_Handler(void)
|
||||
{
|
||||
_dmac_handler();
|
||||
}
|
||||
/**
|
||||
* \brief DMAC interrupt handler
|
||||
*/
|
||||
void DMAC_4_Handler(void)
|
||||
{
|
||||
_dmac_handler();
|
||||
}
|
||||
#else
|
||||
void DMAC_Handler() {
|
||||
DMA.onService();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
DMAClass DMA;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,11 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#if defined(__SAMD51__)
|
||||
#define NUM_DMA_CHANNELS 4
|
||||
#else
|
||||
#define NUM_DMA_CHANNELS 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
WARNING: The API for this class may change and it's not intended for public use!
|
||||
|
|
|
|||
229
libraries/I2S/src/utility/SAMD51_I2SDevice.h
Normal file
229
libraries/I2S/src/utility/SAMD51_I2SDevice.h
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
Copyright (c) 2016 Arduino LLC. 2017 Adafruit All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
class I2SDevice_SAMD51 {
|
||||
public:
|
||||
I2SDevice_SAMD51(I2s& _i2s) :
|
||||
i2s(_i2s)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
inline void reset() {
|
||||
while(i2s.SYNCBUSY.bit.SWRST);
|
||||
i2s.CTRLA.bit.SWRST = 1;
|
||||
}
|
||||
|
||||
inline void disable() {
|
||||
while(i2s.SYNCBUSY.bit.ENABLE);
|
||||
i2s.CTRLA.bit.ENABLE = 0;
|
||||
}
|
||||
|
||||
inline void enable() {
|
||||
while(i2s.SYNCBUSY.bit.ENABLE);
|
||||
i2s.CTRLA.bit.ENABLE = 1;
|
||||
}
|
||||
|
||||
inline int glckId(int index) {
|
||||
return (index == 0) ? I2S_GCLK_ID_0 : I2S_GCLK_ID_1;
|
||||
}
|
||||
|
||||
inline void setSerialClockSelectMasterClockDiv(int index) {
|
||||
i2s.CLKCTRL[index].bit.SCKSEL = I2S_CLKCTRL_SCKSEL_MCKDIV_Val;
|
||||
}
|
||||
|
||||
inline void setSerialClockSelectPin(int index) {
|
||||
i2s.CLKCTRL[index].bit.SCKSEL = I2S_CLKCTRL_SCKSEL_SCKPIN_Val;
|
||||
}
|
||||
|
||||
inline void setFrameSyncSelectSerialClockDiv(int index) {
|
||||
i2s.CLKCTRL[index].bit.FSSEL = I2S_CLKCTRL_FSSEL_SCKDIV_Val;
|
||||
}
|
||||
|
||||
inline void setFrameSyncSelectPin(int index) {
|
||||
i2s.CLKCTRL[index].bit.FSSEL = I2S_CLKCTRL_FSSEL_FSPIN_Val;
|
||||
}
|
||||
|
||||
inline void set0BitDelay(int index) {
|
||||
i2s.CLKCTRL[index].bit.BITDELAY = I2S_CLKCTRL_BITDELAY_LJ_Val;
|
||||
}
|
||||
|
||||
inline void set1BitDelay(int index) {
|
||||
i2s.CLKCTRL[index].bit.BITDELAY = I2S_CLKCTRL_BITDELAY_I2S_Val;
|
||||
}
|
||||
|
||||
inline void setNumberOfSlots(int index, int nbslots) {
|
||||
i2s.CLKCTRL[index].bit.NBSLOTS = nbslots;
|
||||
}
|
||||
|
||||
inline void setSlotSize(int index, int size) {
|
||||
switch (size) {
|
||||
case 32:
|
||||
i2s.CLKCTRL[index].bit.SLOTSIZE = I2S_CLKCTRL_SLOTSIZE_32_Val;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
i2s.CLKCTRL[index].bit.SLOTSIZE = I2S_CLKCTRL_SLOTSIZE_24_Val;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
i2s.CLKCTRL[index].bit.SLOTSIZE = I2S_CLKCTRL_SLOTSIZE_16_Val;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
i2s.CLKCTRL[index].bit.SLOTSIZE = I2S_CLKCTRL_SLOTSIZE_8_Val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline void setDataSize(int index, int size) {
|
||||
switch (size) {
|
||||
case 32:
|
||||
i2s.RXCTRL.bit.DATASIZE = I2S_RXCTRL_DATASIZE_32_Val;
|
||||
i2s.TXCTRL.bit.DATASIZE = I2S_TXCTRL_DATASIZE_32_Val;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
i2s.RXCTRL.bit.DATASIZE = I2S_RXCTRL_DATASIZE_24_Val;
|
||||
i2s.TXCTRL.bit.DATASIZE = I2S_TXCTRL_DATASIZE_24_Val;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
i2s.RXCTRL.bit.DATASIZE = I2S_RXCTRL_DATASIZE_16_Val;
|
||||
i2s.TXCTRL.bit.DATASIZE = I2S_TXCTRL_DATASIZE_16_Val;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
i2s.RXCTRL.bit.DATASIZE = I2S_RXCTRL_DATASIZE_8_Val;
|
||||
i2s.TXCTRL.bit.DATASIZE = I2S_TXCTRL_DATASIZE_8_Val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline void setSlotAdjustedRight(int index) {
|
||||
i2s.RXCTRL.bit.SLOTADJ = I2S_RXCTRL_SLOTADJ_RIGHT_Val;
|
||||
i2s.TXCTRL.bit.SLOTADJ = I2S_TXCTRL_SLOTADJ_RIGHT_Val;
|
||||
}
|
||||
|
||||
inline void setSlotAdjustedLeft(int index) {
|
||||
i2s.RXCTRL.bit.SLOTADJ = I2S_RXCTRL_SLOTADJ_LEFT_Val;
|
||||
i2s.TXCTRL.bit.SLOTADJ = I2S_TXCTRL_SLOTADJ_LEFT_Val;
|
||||
}
|
||||
|
||||
inline void setClockUnit(int index) {
|
||||
i2s.RXCTRL.bit.CLKSEL = (index == 0) ? I2S_RXCTRL_CLKSEL_CLK0_Val : I2S_RXCTRL_CLKSEL_CLK1_Val;
|
||||
}
|
||||
|
||||
inline void setTxMode(int index) {
|
||||
i2s.RXCTRL.bit.SERMODE = 0x01;
|
||||
i2s.TXCTRL.reg &= ~(0x03); //TODO: why is this not in CMSIS...
|
||||
i2s.TXCTRL.reg |= 0x01;
|
||||
}
|
||||
|
||||
inline void setRxMode(int index) {
|
||||
i2s.RXCTRL.bit.SERMODE = 0x00;
|
||||
i2s.TXCTRL.reg &= ~(0x03); //TODO: why is this not in CMSIS...
|
||||
i2s.TXCTRL.reg |= 0x00;
|
||||
}
|
||||
|
||||
inline void enableClockUnit(int index) {
|
||||
if (index == 0) {
|
||||
while(i2s.SYNCBUSY.bit.CKEN0);
|
||||
i2s.CTRLA.bit.CKEN0 = 1;
|
||||
} else {
|
||||
while(i2s.SYNCBUSY.bit.CKEN1);
|
||||
i2s.CTRLA.bit.CKEN1 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline void disableClockUnit(int index) {
|
||||
if (index == 0) {
|
||||
while(i2s.SYNCBUSY.bit.CKEN0);
|
||||
i2s.CTRLA.bit.CKEN0 = 0;
|
||||
} else {
|
||||
while(i2s.SYNCBUSY.bit.CKEN1);
|
||||
i2s.CTRLA.bit.CKEN1 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline void enableSerializer(int index) {
|
||||
i2s.CTRLA.bit.RXEN = 1;
|
||||
i2s.CTRLA.bit.TXEN = 1;
|
||||
}
|
||||
|
||||
inline void disableSerializer(int index) {
|
||||
i2s.CTRLA.bit.RXEN = 0;
|
||||
i2s.CTRLA.bit.TXEN = 0;
|
||||
}
|
||||
|
||||
inline int dmaTriggerSource(int index) {
|
||||
/*
|
||||
if (i2s.SERCTRL[index].bit.SERMODE == I2S_SERCTRL_SERMODE_TX_Val) {
|
||||
return (index == 0) ? I2S_DMAC_ID_TX_0 : I2S_DMAC_ID_TX_1;
|
||||
} else {
|
||||
return (index == 0) ? I2S_DMAC_ID_RX_0 : I2S_DMAC_ID_RX_1;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
inline int txReady(int index) {
|
||||
return (index == 0) ? i2s.INTFLAG.bit.TXRDY0 :i2s.INTFLAG.bit.TXRDY1;
|
||||
}
|
||||
|
||||
inline void writeData(int index, int32_t value) {
|
||||
while (i2s.SYNCBUSY.bit.TXDATA);
|
||||
|
||||
i2s.TXDATA.bit.DATA = value;
|
||||
}
|
||||
|
||||
inline void clearTxReady(int index) {
|
||||
if (index == 0) {
|
||||
i2s.INTFLAG.bit.TXRDY0 = 1;
|
||||
} else {
|
||||
i2s.INTFLAG.bit.TXRDY1 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline int rxReady(int index) {
|
||||
return (index == 0) ? i2s.INTFLAG.bit.RXRDY0 :i2s.INTFLAG.bit.RXRDY1;
|
||||
}
|
||||
|
||||
inline int32_t readData(int index) {
|
||||
while(i2s.SYNCBUSY.bit.RXDATA)
|
||||
return i2s.RXDATA.bit.DATA;
|
||||
}
|
||||
|
||||
inline void clearRxReady(int index) {
|
||||
if (index == 0) {
|
||||
i2s.INTFLAG.bit.RXRDY0 = 1;
|
||||
} else {
|
||||
i2s.INTFLAG.bit.RXRDY1 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline void* data(int index) {
|
||||
return (void*)&i2s.RXDATA.reg;
|
||||
}
|
||||
|
||||
private:
|
||||
volatile I2s &i2s;
|
||||
};
|
||||
|
|
@ -191,9 +191,9 @@ static const uint8_t SCL = PIN_WIRE_SCL;
|
|||
#define I2S_CLOCK_GENERATOR 3
|
||||
|
||||
//TODO: these
|
||||
#define PIN_I2S_SD (9u)
|
||||
#define PIN_I2S_SCK (1u)
|
||||
#define PIN_I2S_FS (0u)
|
||||
#define PIN_I2S_SD (13u)
|
||||
#define PIN_I2S_SCK (3u)
|
||||
#define PIN_I2S_FS (12u)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue