6 #include <cfg/macros.h>
10 static uint8_t play_buf1[CONFIG_PLAY_BUF_LEN];
11 static uint8_t play_buf2[CONFIG_PLAY_BUF_LEN];
13 /* |x|x|CONT|SECOND|FIRST|IS_PLAYING|CUR_BUF| */
14 /* |7|6| 5 | 4 | 3 | 2 | 1 0 | */
15 static uint8_t status;
16 #define CURRENT_BUF 0x03
18 #define FIRST_BUF_FULL 3
19 #define SECOND_BUF_FULL 4
20 #define CONTINUE_PLAY 5
22 INLINE bool is_buffer_full(int bv)
24 return status & BV(bv);
27 uint8_t *i2s_getBuffer(unsigned buf_num)
29 kprintf("getBuffer start\n");
30 if (status & BV(IS_PLAYING))
33 if ((buf_num == I2S_FIRST_BUF) && !is_buffer_full(FIRST_BUF_FULL))
35 status |= BV(FIRST_BUF_FULL);
36 kprintf("status [0x%02X]\n", status);
39 else if ((buf_num == I2S_SECOND_BUF) && !is_buffer_full(SECOND_BUF_FULL))
41 status |= BV(SECOND_BUF_FULL);
42 kprintf("status [0x%02X]\n", status);
49 uint8_t *i2s_getFreeBuffer(void)
51 if (!(status & BV(IS_PLAYING)))
64 if ((status & CURRENT_BUF) == I2S_FIRST_BUF && !is_buffer_full(SECOND_BUF_FULL))
66 else if ((status & CURRENT_BUF) == I2S_SECOND_BUF && !is_buffer_full(FIRST_BUF_FULL))
72 INLINE void setCurrentBuffer(int buffer)
74 status &= ~CURRENT_BUF;
75 status |= CURRENT_BUF & buffer;
79 static void i2s_dma_tx_irq_handler(void) __attribute__ ((interrupt));
80 static void i2s_dma_tx_irq_handler(void)
83 if (status & BV(CONTINUE_PLAY))
86 if ((status & CURRENT_BUF) == I2S_FIRST_BUF)
88 SSC_PTCR = BV(PDC_TXTDIS);
89 SSC_TPR = (reg32_t)play_buf2;
90 SSC_TCR = CONFIG_PLAY_BUF_LEN;
91 SSC_PTCR = BV(PDC_TXTEN);
93 setCurrentBuffer(I2S_SECOND_BUF);
94 status &= ~BV(FIRST_BUF_FULL);
95 status &= ~BV(CONTINUE_PLAY);
100 SSC_PTCR = BV(PDC_TXTDIS);
101 SSC_TPR = (reg32_t)play_buf1;
102 SSC_TCR = CONFIG_PLAY_BUF_LEN;
103 SSC_PTCR = BV(PDC_TXTEN);
105 setCurrentBuffer(I2S_FIRST_BUF);
106 status &= ~BV(SECOND_BUF_FULL);
107 status &= ~BV(CONTINUE_PLAY);
116 SSC_CR = BV(SSC_TXDIS);
117 //kprintf("%08lX\n", SSC_TCMR);
119 SSC_PTCR = BV(PDC_TXTDIS);
120 SSC_TPR = (reg32_t)play_buf1;
121 SSC_TCR = CONFIG_PLAY_BUF_LEN / 2;
122 SSC_PTCR = BV(PDC_TXTEN);
124 SSC_CR = BV(SSC_TXEN);
126 // ASSERT(SSC_PTSR & BV(PDC_TXTEN));
128 kprintf("i2s_start start\n");
129 if (status & (BV(FIRST_BUF_FULL) | BV(SECOND_BUF_FULL)))
131 setCurrentBuffer(I2S_FIRST_BUF);
132 SSC_PTCR = BV(PDC_TXTDIS);
133 SSC_TPR = (reg32_t)play_buf1;
134 SSC_TCR = CONFIG_PLAY_BUF_LEN;
136 status |= BV(IS_PLAYING);
137 status |= BV(CONTINUE_PLAY);
138 kprintf("start: status [0x%02X]\n", status);
139 SSC_PTCR = BV(PDC_TXTEN);
145 kprintf("start: buffers are not full\n");
152 // TODO renderlo configurabile
154 #define DELAY ((1 << SSC_STTDLY_SHIFT) & SSC_STTDLY_MASK)
155 #define PERIOD ((15 << (SSC_PERIOD_SHIFT)) & SSC_PERIOD_MASK)
156 #define DATALEN (15 & SSC_DATLEN_MASK)
157 #define DATNB ((1 << SSC_DATNB_SHIFT) & SSC_DATNB_MASK)
158 #define FSLEN ((15 << SSC_FSLEN_SHIFT) & SSC_FSLEN_MASK)
160 #define SSC_DMA_IRQ_PRIORITY 5
164 //TODO sistemare i pin
165 PIOA_PDR = BV(SPI1_SPCK) | BV(SPI1_MOSI) | BV(SPI1_NPCS0);
167 SSC_CR = BV(SSC_SWRST);
169 SSC_CMR = MCK_DIV & SSC_DIV_MASK;
170 SSC_TCMR = SSC_CKS_DIV | SSC_CKO_CONT | SSC_CKG_NONE | DELAY | PERIOD | SSC_START_FALL_F;
171 SSC_TFMR = DATALEN | DATNB | FSLEN | BV(SSC_MSBF) | SSC_FSOS_NEGATIVE;
173 /* Disable all irqs */
174 SSC_IDR = 0xFFFFFFFF;
175 /* Set the vector. */
176 AIC_SVR(SSC_ID) = i2s_dma_tx_irq_handler;
177 /* Initialize to edge triggered with defined priority. */
178 AIC_SMR(SPI0_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED | SSC_DMA_IRQ_PRIORITY;
179 /* Enable the SSC IRQ */
180 AIC_IDCR = BV(SSC_ID);
181 /* Enable interrupt on tx buffer empty */
182 SSC_IER = BV(SSC_ENDTX);
185 PMC_PCER = BV(SSC_ID);
187 /* set current buffer to 1 */
189 for (int i = 0; i < CONFIG_PLAY_BUF_LEN; ++i)
191 //uint32_t tmp = 0x5555;
192 //uint32_t tmp2 = 0x9999;
194 //play_buf1[i+4] = tmp2;