28 #ifdef ARDUINO_ARCH_ESP8266
39 #ifdef ARDUINO_ESP8266_MAJOR
40 #include "core_esp8266_i2s.h"
45 #include "eagle_soc.h"
46 #include "esp8266_peri.h"
47 #include "slc_register.h"
51 #include "user_interface.h"
53 #if !defined(__CORE_ESP8266_VERSION_H) || defined(ARDUINO_ESP8266_RELEASE_2_5_0)
54 void rom_i2c_writeReg_Mask(uint32_t block, uint32_t host_id, uint32_t reg_add, uint32_t Msb, uint32_t Lsb, uint32_t indata);
60 uint32 blocksize : 12;
67 struct slc_queue_item* next_link_ptr;
77 const uint16_t c_maxDmaBlockSize = 4095;
79 const uint8_t c_I2sPin = 3;
81 class NeoEsp8266I2sMethodCore
84 static const uint8_t c_StateBlockCount = 2;
85 static const size_t c_StateDataSize = 4;
88 static const uint16_t c_I2sByteBoundarySize = 4;
91 static NeoEsp8266I2sMethodCore* s_this;
93 volatile NeoDmaState _dmaState;
95 slc_queue_item* _i2sBufDesc;
96 uint16_t _i2sBufDescCount;
98 size_t _i2sBufferSize;
101 size_t _i2sIdleDataTotalSize;
102 size_t _i2sIdleDataSize;
103 uint8_t* _i2sIdleData;
105 uint16_t _is2BufMaxBlockSize;
107 size_t GetSendSize()
const
109 return _i2sBufferSize + _i2sIdleDataTotalSize;
116 static void IRAM_ATTR i2s_slc_isr(
void)
118 ETS_SLC_INTR_DISABLE();
120 uint32_t slc_intr_status = SLCIS;
124 if ((slc_intr_status & SLCIRXEOF) && s_this)
126 if (s_this->_dmaState != NeoDmaState_Idle)
129 slc_queue_item* itemLoop = s_this->_i2sBufDesc;
130 slc_queue_item* itemLoopBreaker = itemLoop + 1;
132 itemLoopBreaker->next_link_ptr = itemLoop;
134 s_this->_dmaState = NeoDmaState_Idle;
138 ETS_SLC_INTR_ENABLE();
141 NeoEsp8266I2sMethodCore()
144 void AllocateI2s(
const size_t i2sBufferSize,
145 const size_t i2sZeroesSize,
146 const size_t is2BufMaxBlockSize,
147 const uint8_t idleLevel)
149 _i2sBufferSize = i2sBufferSize;
150 _i2sIdleDataTotalSize = i2sZeroesSize;
151 _i2sIdleDataSize = _i2sIdleDataTotalSize;
153 size_t countIdleQueueItems = 1;
154 if (_i2sIdleDataSize > 256)
157 countIdleQueueItems = _i2sIdleDataSize / 256 + 1;
158 _i2sIdleDataSize = 256;
162 _i2sIdleDataSize =
NeoUtil::RoundUp(_i2sIdleDataSize, c_I2sByteBoundarySize);
164 _is2BufMaxBlockSize = is2BufMaxBlockSize;
166 _i2sBuffer =
static_cast<uint8_t*
>(malloc(_i2sBufferSize));
168 _i2sIdleData =
static_cast<uint8_t*
>(malloc(_i2sIdleDataSize));
169 memset(_i2sIdleData, idleLevel * 0xff, _i2sIdleDataSize);
171 _i2sBufDescCount = (_i2sBufferSize / _is2BufMaxBlockSize) + 1 +
172 countIdleQueueItems +
175 _i2sBufDesc = (slc_queue_item*)malloc(_i2sBufDescCount *
sizeof(slc_queue_item));
185 pinMode(c_I2sPin, INPUT);
194 return (_dmaState == NeoDmaState_Idle);
198 void DmaItemInit(slc_queue_item* item, uint8_t* data,
size_t sizeData, slc_queue_item* itemNext)
203 item->datalen = sizeData;
204 item->blocksize = sizeData;
205 item->buf_ptr = data;
207 item->next_link_ptr = itemNext;
210 void InitializeI2s(
const uint32_t i2sClockDivisor,
const uint32_t i2sBaseClockDivisor)
214 pinMode(c_I2sPin, FUNCTION_1);
216 uint8_t* is2Buffer = _i2sBuffer;
217 uint8_t* is2BufferEnd = _i2sBuffer + _i2sBufferSize;
218 uint32_t is2BufferSize;
219 uint16_t indexDesc = 0;
222 uint16_t stateDataSize = min(c_StateDataSize, _i2sIdleDataSize);
223 while (indexDesc < c_StateBlockCount)
225 DmaItemInit(&_i2sBufDesc[indexDesc], _i2sIdleData, stateDataSize, &(_i2sBufDesc[indexDesc + 1]));
231 is2BufferSize = _i2sBufferSize;
232 while (is2Buffer < is2BufferEnd)
234 uint32_t blockSize = (is2BufferSize > _is2BufMaxBlockSize) ? _is2BufMaxBlockSize : is2BufferSize;
236 DmaItemInit(&_i2sBufDesc[indexDesc], is2Buffer, blockSize, &(_i2sBufDesc[indexDesc + 1]));
238 is2Buffer += blockSize;
239 is2BufferSize -= blockSize;
244 _i2sBufDesc[indexDesc - 1].eof = 1;
247 is2BufferSize = _i2sIdleDataTotalSize;
248 while (indexDesc < _i2sBufDescCount)
250 uint32_t blockSize = (is2BufferSize > _i2sIdleDataSize) ? _i2sIdleDataSize : is2BufferSize;
252 DmaItemInit(&_i2sBufDesc[indexDesc], _i2sIdleData, blockSize, &(_i2sBufDesc[indexDesc + 1]));
254 is2Buffer += blockSize;
255 is2BufferSize -= blockSize;
260 _i2sBufDesc[indexDesc - 1].next_link_ptr =
reinterpret_cast<struct slc_queue_item*
>(&(_i2sBufDesc[0]));
263 _i2sBufDesc[c_StateBlockCount - 1].next_link_ptr =
reinterpret_cast<struct slc_queue_item*
>(&(_i2sBufDesc[0]));
267 ETS_SLC_INTR_DISABLE();
271 _dmaState = NeoDmaState_Idle;
273 SLCC0 |= SLCRXLR | SLCTXLR;
274 SLCC0 &= ~(SLCRXLR | SLCTXLR);
278 SLCC0 &= ~(SLCMM << SLCM);
279 SLCC0 |= (1 << SLCM);
280 SLCRXDC |= SLCBINR | SLCBTNR;
281 SLCRXDC &= ~(SLCBRXFE | SLCBRXEM | SLCBRXFM);
287 SLCTXL &= ~(SLCTXLAM << SLCTXLA);
289 SLCTXL |= (uint32) & (_i2sBufDesc[_i2sBufDescCount - 1]) << SLCTXLA;
290 SLCRXL &= ~(SLCRXLAM << SLCRXLA);
292 SLCRXL |= (uint32) & (_i2sBufDesc[0]) << SLCRXLA;
294 ETS_SLC_INTR_ATTACH(i2s_slc_isr, NULL);
297 ETS_SLC_INTR_ENABLE();
313 I2SFC &= ~(I2SDE | (I2STXFMM << I2STXFM) | (I2SRXFMM << I2SRXFM));
316 I2SCC &= ~((I2STXCMM << I2STXCM) | (I2SRXCMM << I2SRXCM));
319 uint32_t i2s_clock_div = i2sClockDivisor & I2SCDM;
320 uint8_t i2s_bck_div = i2sBaseClockDivisor & I2SBDM;
323 I2SC &= ~(I2STSM | I2SRSM | (I2SBMM << I2SBM) | (I2SBDM << I2SBD) | (I2SCDM << I2SCD));
324 I2SC |= I2SRF | I2SMR | I2SRSM | I2SRMS | (i2s_bck_div << I2SBD) | (i2s_clock_div << I2SCD);
332 slc_queue_item* itemLoopBreaker = &(_i2sBufDesc[1]);
333 slc_queue_item* itemData = itemLoopBreaker + 1;
336 itemLoopBreaker->next_link_ptr = itemData;
338 _dmaState = NeoDmaState_Sending;
343 ETS_SLC_INTR_DISABLE();
346 I2SC &= ~(I2STXS | I2SRXS);
355 SLCTXL &= ~(SLCTXLAM << SLCTXLA);
356 SLCRXL &= ~(SLCRXLAM << SLCRXLA);
358 pinMode(c_I2sPin, INPUT);
static size_t RoundUp(size_t numToRound, size_t multiple)
Definition: NeoUtil.h:62