2 #include <cfg/macros.h>
6 static uint8_t play_buf1[CONFIG_PLAY_BUF_LEN];
7 static uint8_t play_buf2[CONFIG_PLAY_BUF_LEN];
9 /* |x|x|CONT|SECOND|FIRST|IS_PLAYING|CUR_BUF| */
10 /* |7|6| 5 | 4 | 3 | 2 | 1 0 | */
11 static uint8_t status;
12 #define CURRENT_BUF 0x03
14 #define FIRST_BUF_FULL 3
15 #define SECOND_BUF_FULL 4
16 #define CONTINUE_PLAY 5
18 INLINE bool is_buffer_full(int bv)
20 return status & BV(bv);
23 uint8_t *i2s_getBuffer(unsigned buf_num)
25 kprintf("getBuffer start\n");
26 if (status & BV(IS_PLAYING))
29 if ((buf_num == I2S_FIRST_BUF) && !is_buffer_full(FIRST_BUF_FULL))
31 status |= BV(FIRST_BUF_FULL);
32 kprintf("status [0x%02X]\n", status);
35 else if ((buf_num == I2S_SECOND_BUF) && !is_buffer_full(SECOND_BUF_FULL))
37 status |= BV(SECOND_BUF_FULL);
38 kprintf("status [0x%02X]\n", status);
45 uint8_t *i2s_getFreeBuffer(void)
47 if (!(status & BV(IS_PLAYING)))
60 if ((status & CURRENT_BUF) == I2S_FIRST_BUF && !is_buffer_full(SECOND_BUF_FULL))
62 else if ((status & CURRENT_BUF) == I2S_SECOND_BUF && !is_buffer_full(FIRST_BUF_FULL))
68 INLINE void setCurrentBuffer(int buffer)
70 status &= ~CURRENT_BUF;
71 status |= CURRENT_BUF & buffer;
75 static void i2s_dma_tx_irq_handler(void) __attribute__ ((interrupt));
76 static void i2s_dma_tx_irq_handler(void)
79 if (status & BV(CONTINUE_PLAY))
82 if ((status & CURRENT_BUF) == I2S_FIRST_BUF)
84 SSC_PTCR = BV(PDC_TXTDIS);
85 SSC_TPR = (reg32_t)play_buf2;
86 SSC_TCR = CONFIG_PLAY_BUF_LEN;
87 SSC_PTCR = BV(PDC_TXTEN);
89 setCurrentBuffer(I2S_SECOND_BUF);
90 status &= ~BV(FIRST_BUF_FULL);
91 status &= ~BV(CONTINUE_PLAY);
96 SSC_PTCR = BV(PDC_TXTDIS);
97 SSC_TPR = (reg32_t)play_buf1;
98 SSC_TCR = CONFIG_PLAY_BUF_LEN;
99 SSC_PTCR = BV(PDC_TXTEN);
101 setCurrentBuffer(I2S_FIRST_BUF);
102 status &= ~BV(SECOND_BUF_FULL);
103 status &= ~BV(CONTINUE_PLAY);
112 SSC_PTCR = BV(PDC_TXTDIS);
113 SSC_TPR = (reg32_t)play_buf1;
114 SSC_TCR = CONFIG_PLAY_BUF_LEN / 2;
115 SSC_PTCR = BV(PDC_TXTEN);
116 ASSERT(SSC_PTSR & BV(PDC_TXTEN));
118 kprintf("i2s_start start\n");
119 if (status & (BV(FIRST_BUF_FULL) | BV(SECOND_BUF_FULL)))
121 setCurrentBuffer(I2S_FIRST_BUF);
122 SSC_PTCR = BV(PDC_TXTDIS);
123 SSC_TPR = (reg32_t)play_buf1;
124 SSC_TCR = CONFIG_PLAY_BUF_LEN;
126 status |= BV(IS_PLAYING);
127 status |= BV(CONTINUE_PLAY);
128 kprintf("start: status [0x%02X]\n", status);
129 SSC_PTCR = BV(PDC_TXTEN);
135 kprintf("start: buffers are not full\n");
143 #define DELAY ((0 << SSC_STTDLY_SHIFT) & SSC_STTDLY)
144 #define PERIOD ((7 << (SSC_PERIOD_SHIFT)) & SSC_PERIOD)
145 /* wtf?? it seems that no 16 won't be sent with MSB first...*/
146 #define DATALEN (15 & SSC_DATLEN)
147 #define DATNB ((1 << SSC_DATNB_SHIFT) & SSC_DATNB)
148 #define FSLEN ((1 << SSC_FSLEN_SHIFT) & SSC_FSLEN)
150 #define SSC_DMA_IRQ_PRIORITY 5
154 PIOA_PDR = BV(SPI1_SPCK) | BV(SPI1_MOSI) | BV(SPI1_NPCS0);
156 SSC_CR = BV(SSC_SWRST);
158 SSC_CMR = MCK_DIV & SSC_DIV;
159 SSC_TCMR = SSC_CKS_DIV | SSC_CKO_TRAN | SSC_CKG_NONE | SSC_START_CONT | DELAY | PERIOD;
160 SSC_TFMR = DATALEN | FSLEN | SSC_MSBF | SSC_FSOS_POSITIVE;
162 /* Disable all irqs */
163 SSC_IDR = 0xFFFFFFFF;
164 /* Set the vector. */
165 AIC_SVR(SSC_ID) = i2s_dma_tx_irq_handler;
166 /* Initialize to edge triggered with defined priority. */
167 AIC_SMR(SPI0_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED | SSC_DMA_IRQ_PRIORITY;
168 /* Enable the SSC IRQ */
169 AIC_IDCR = BV(SSC_ID);
170 /* Enable interrupt on tx buffer empty */
171 SSC_IER = BV(SSC_ENDTX);
174 PMC_PCER = BV(SSC_ID);
177 SSC_CR = BV(SSC_TXEN);
179 /* set current buffer to 1 */
181 for (int i = 0; i < CONFIG_PLAY_BUF_LEN; ++i)
183 //uint32_t tmp = 0x5555;
184 //uint32_t tmp2 = 0x9999;
185 play_buf1[i] = (uint8_t)i;
186 //play_buf1[i+4] = tmp2;