Skip to content

Commit ccc0212

Browse files
committed
CurieI2S use interrupts for Tx
-Use interrupts to fill FIFO buffer from TX buffer
1 parent 4fae4dd commit ccc0212

File tree

2 files changed

+86
-20
lines changed

2 files changed

+86
-20
lines changed

libraries/CurieI2S/src/CurieI2S.cpp

Lines changed: 77 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,61 +8,113 @@ Curie_I2S CurieI2S;
88
static uint32_t _i2s_dma_Rx_Buffer[DMA_BUFFER_SIZE];
99
static uint32_t _i2s_dma_Tx_Buffer[DMA_BUFFER_SIZE];
1010

11+
static struct i2s_ring_buffer _i2s_Rx_Buffer;
12+
static struct i2s_ring_buffer _i2s_Tx_Buffer;
13+
14+
static struct i2s_ring_buffer *_i2s_Rx_BufferPtr = &_i2s_Rx_Buffer;
15+
static struct i2s_ring_buffer *_i2s_Tx_BufferPtr = &_i2s_Tx_Buffer;
16+
1117
static void i2sInterruptHandler(void)
1218
{
1319
//TODO: Make interrupt handling more atomic
14-
noInterrupts();
20+
//noInterrupts();
21+
//uint32_t fifoL = *I2S_TFIFO_STAT;
22+
23+
//tx FIFO almost empty
24+
if(*I2S_STAT & 0x00000200)
25+
{
26+
//Serial.println("tx almost empty");
27+
//Serial.print("I2S_STAT: ");
28+
//Serial.println(*I2S_STAT, HEX);
29+
//Serial.print("I2S_TFIFO_STAT: ");
30+
//Serial.println(fifoL, HEX);
31+
32+
//disable TFIFO_AEMPTY interrupt
33+
//*I2S_CID_CTRL = *I2S_CID_CTRL & 0xFDFFFFFF;
34+
35+
//fill FIFO from buffer
36+
if(_i2s_Tx_BufferPtr->head != _i2s_Tx_BufferPtr->tail)
37+
{
38+
int index = _i2s_Tx_BufferPtr->tail;
39+
int cnt = 0;
40+
for(cnt = 0; (index != _i2s_Tx_BufferPtr->head) && (cnt < 2); cnt++)
41+
{
42+
*I2S_DATA_REG = _i2s_Tx_BufferPtr->data[index];
43+
index = (index+1)%I2S_BUFFER_SIZE;
44+
}
45+
_i2s_Tx_BufferPtr->tail = (_i2s_Tx_BufferPtr->tail + cnt)%I2S_BUFFER_SIZE;
46+
}
1547

48+
//clear flags
49+
*I2S_STAT = *I2S_CTRL & 0xFFFFF0FF;
50+
51+
return;
52+
}
53+
1654
//tx FIFO full
1755
if(*I2S_STAT & 0x00000400)
1856
{
1957
//Serial.println("tx full");
20-
58+
//Serial.print("I2S_STAT: ");
59+
//Serial.println(*I2S_STAT, HEX);
60+
//Serial.print("I2S_TFIFO_STAT: ");
61+
//Serial.println(fifoL, HEX);
2162
//disable TFIFO_FULL interrupts
2263
*I2S_CID_CTRL = *I2S_CID_CTRL & 0xFBFFFFFF;
2364

2465
//start transmit data in FIFO
2566
*I2S_CTRL = *I2S_CTRL | 0x02000000;
26-
delayTicks(3200);
67+
//delayTicks(3200);
2768

2869
//clear flags
29-
*I2S_STAT = *I2S_CTRL & 0xFFFFF3FF;
70+
*I2S_STAT = *I2S_CTRL & 0xFFFFF0FF;
3071

3172

32-
//enable TFIFO_EMPTY interrupt
33-
*I2S_CID_CTRL = *I2S_CID_CTRL | 0x01000000;
73+
//enable TFIFO_EMPTY and TFIFO_AEMPTY interrupt
74+
*I2S_CID_CTRL = *I2S_CID_CTRL | 0x03000000;
3475

3576
return;
3677
}
3778

79+
//tx FIFO almost full
80+
//if(*I2S_STAT & 0x00000200)
81+
{
82+
//fill up FIFO from buffer if available;
83+
}
84+
3885
//tx FIFO empty
3986
if(*I2S_STAT & 0x00000100)
4087
{
4188
//Serial.println("tx empty");
42-
89+
//Serial.print("I2S_STAT: ");
90+
//Serial.println(*I2S_STAT, HEX);
91+
//Serial.print("I2S_TFIFO_STAT: ");
92+
//Serial.println(fifoL, HEX);
4393
//disable TFIFO_EMPTY interrupt
4494
*I2S_CID_CTRL = *I2S_CID_CTRL & 0xFEFFFFFF;
45-
95+
96+
delayTicks(960); //allow enough time to send last frame
4697
//stop transmission
4798
*I2S_CTRL = *I2S_CTRL & 0xFDFFFFFF;
4899

49100
//clear flags
50-
*I2S_STAT = *I2S_STAT & 0xFFFFFCFF;
101+
*I2S_STAT = *I2S_CTRL & 0xFFFFF0FF;
51102

52103
//enable TFIFO_FULL interrupt
53104
*I2S_CID_CTRL = *I2S_CID_CTRL | 0x04000000;
54105

106+
107+
//Serial.print("CID_CTRL: ");
108+
//Serial.println(*I2S_CID_CTRL, HEX);
109+
55110
return;
56111
}
57112

58-
//tx FIFO almost empty
59-
{
60-
//fill up FIFO from buffer if available;
61-
}
113+
62114

63115
//overrun and underrun
64116

65-
interrupts();
117+
//interrupts();
66118
}
67119

68120
Curie_I2S::Curie_I2S()
@@ -164,6 +216,10 @@ void Curie_I2S::init()
164216
i2s_ctrl |= 0x08B00100;
165217
*I2S_CTRL = i2s_ctrl;
166218

219+
//set threshold for FIFOs
220+
*I2S_TFIFO_CTRL |= 0x00030002;
221+
*I2S_RFIFO_CTRL |= 0x00030002;
222+
167223
//enable interrupts
168224
//ToDo: Use DMA instead of relying on interrupts
169225
enableInterrupts();
@@ -296,7 +352,7 @@ void Curie_I2S::enableInterrupts()
296352
*INT_I2S_MASK = int_i2s_mask;
297353

298354
uint32_t i2s_cid_ctrl = *I2S_CID_CTRL;
299-
i2s_cid_ctrl |= 0x05008000;
355+
i2s_cid_ctrl |= 0x0F008000;
300356
*I2S_CID_CTRL = i2s_cid_ctrl;
301357

302358
interrupt_disable(IRQ_I2S_INTR);
@@ -321,9 +377,11 @@ void Curie_I2S::transmitFrame()
321377

322378
void Curie_I2S::pushData(uint32_t data)
323379
{
324-
if(getTxFIFOLength() < 4)
380+
int i = (uint32_t)(_i2s_Tx_BufferPtr->head +1) % I2S_BUFFER_SIZE;
381+
if(i != _i2s_Tx_BufferPtr->tail)
325382
{
326-
*I2S_DATA_REG = data;
383+
_i2s_Tx_BufferPtr->data[_i2s_Tx_BufferPtr->head] = data;
384+
_i2s_Tx_BufferPtr->head = i;
327385
}
328386
}
329387

@@ -340,8 +398,8 @@ uint32_t Curie_I2S::pullData()
340398

341399
void Curie_I2S::pushDataFrame(uint32_t leftChData, uint32_t rightChData)
342400
{
343-
int fifoLength = getTxFIFOLength();
344-
if(!(fifoLength%2) && (fifoLength < 4))
401+
//int fifoLength = getTxFIFOLength();
402+
//if(!(fifoLength%2) && (fifoLength < 4))
345403
{
346404
pushData(leftChData);
347405
pushData(rightChData);

libraries/CurieI2S/src/CurieI2S.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@
5555
#define I2S_RWS 3
5656
#define I2S_RSCK 8
5757

58+
#define I2S_BUFFER_SIZE 256
59+
60+
struct i2s_ring_buffer
61+
{
62+
uint32_t data[I2S_BUFFER_SIZE];
63+
int head = 0;
64+
int tail = 0;
65+
};
5866

5967
class Curie_I2S
6068
{
@@ -106,7 +114,7 @@ class Curie_I2S
106114

107115
void transmitFrame();
108116

109-
// Pushes a dword into the TX FIFO
117+
// Pushes a dword into the TX buffer
110118
void pushData(uint32_t data);
111119

112120
// Pushes a dword into the TX FIFO without doing any checks

0 commit comments

Comments
 (0)