00001
00050 #include <cfg/os.h>
00051 #include <cfg/clock.h>
00052 #include <dev/board.h>
00053 #include <dev/irqreg.h>
00054 #include <dev/twif.h>
00055
00056 #include <stdlib.h>
00057 #include <string.h>
00058
00059 #include <sys/event.h>
00060 #include <sys/timer.h>
00061
00062 #include <dev/tlv320dac.h>
00063
00064 #ifndef TWI_SLA_DAC
00065 #define TWI_SLA_DAC 0x1A
00066 #endif
00067
00068
00069
00070
00071 #ifndef TLV320DAC_VOL
00072 #define TLV320DAC_VOL 0x18
00073 #endif
00074
00075
00076
00077
00078 #ifndef SAMPLE_BUFFERS
00079 #if defined (AT91SAM9260_EK)
00080 #define SAMPLE_BUFFERS 32
00081 #else
00082 #define SAMPLE_BUFFERS 3
00083 #endif
00084 #endif
00085
00086
00087
00088
00089 #if defined (MCU_AT91SAM9260)
00090
00091 #define DACI2S_PIO_ID PIOB_ID
00092 #define DACI2S_PINS_A _BV(PB18_TD0_A) | _BV(PB17_TF0_A) | _BV(PB16_TK0_A)
00093 #define DACI2S_PINS_B 0
00094
00095 #else
00096 #define DACI2S_PIO_ID PIOA_ID
00097 #define DACI2S_PINS_A _BV(PA23_TD_A) | _BV(PA21_TF_A) | _BV(PA22_TK_A)
00098 #define DACI2S_PINS_B 0
00099 #endif
00100
00101
00102
00103
00104 #if DACI2S_PIO_ID == PIOA_ID
00105 #define DACI2S_PDR PIOA_PDR
00106 #define DACI2S_ASR PIOA_ASR
00107 #define DACI2S_BSR PIOA_BSR
00108 #elif DACI2S_PIO_ID == PIOB_ID
00109 #define DACI2S_PDR PIOB_PDR
00110 #define DACI2S_ASR PIOB_ASR
00111 #define DACI2S_BSR PIOB_BSR
00112 #endif
00113
00114 volatile uint32_t irq_counter;
00115
00119 static HANDLE i2s_que;
00120
00124 #define PCM_CHANS 2
00125
00129 #define PCM_BITS 16
00130
00134 typedef struct _PCM_BUFFER {
00135 u_short *wbf_dat;
00136 int wbf_siz;
00137 int wbf_len;
00138 } PCM_BUFFER;
00139
00140
00141 u_int use_pdc = 1;
00142
00143 static PCM_BUFFER pcm_bufq[SAMPLE_BUFFERS];
00144
00145 static volatile u_int brd_idx;
00146
00147 static volatile int brd_pos;
00148
00149 static u_int bwr_idx;
00150
00156 static void I2sPdcFill(void)
00157 {
00158 if (brd_idx != bwr_idx) {
00159 if (inr(SSC_TNCR) == 0) {
00160 if (++brd_idx >= SAMPLE_BUFFERS) {
00161 brd_idx = 0;
00162 }
00163 outr(SSC_TNPR, (u_int) pcm_bufq[brd_idx].wbf_dat);
00164 outr(SSC_TNCR, pcm_bufq[brd_idx].wbf_len);
00165 }
00166 }
00167 }
00168
00174 static void I2sInterrupt(void *arg)
00175 {
00176 irq_counter++;
00177 if (use_pdc) {
00178 I2sPdcFill();
00179 NutEventPostFromIrq(&i2s_que);
00180 } else {
00181 if (brd_pos >= pcm_bufq[brd_idx].wbf_len) {
00182 brd_pos = 0;
00183 NutEventPostFromIrq(&i2s_que);
00184 if (brd_idx == bwr_idx) {
00185 outr(SSC_THR, 0);
00186 return;
00187 }
00188 if (++brd_idx >= SAMPLE_BUFFERS) {
00189 brd_idx = 0;
00190 }
00191 }
00192 outr(SSC_THR, pcm_bufq[brd_idx].wbf_dat[brd_pos]);
00193 brd_pos++;
00194 }
00195 }
00196
00206 u_char Tlv320DacReadReg(u_int reg)
00207 {
00208 return 0xFF;
00209 }
00210
00219 void Tlv320DacWriteReg(u_int reg, u_int val)
00220 {
00221 u_char txdata[2];
00222
00223 txdata[0] = (u_char)(reg << 1) | (u_char)(val >> 8);
00224 txdata[1] = (u_char)val;
00225 TwMasterTransact(TWI_SLA_DAC, txdata, 2, NULL, 0, 0);
00226 }
00227
00235 static int Tlv320I2sEnable(u_int rate)
00236 {
00237
00238 outr(PMC_PCER, _BV(SSC_ID));
00239
00240
00241 outr(DACI2S_ASR, DACI2S_PINS_A);
00242 outr(DACI2S_BSR, DACI2S_PINS_B);
00243
00244
00245 outr(DACI2S_PDR, DACI2S_PINS_A | DACI2S_PINS_B);
00246
00247
00248 outr(SSC_CMR, 0);
00249 outr(SSC_TCMR,
00250 SSC_CKS_PIN |
00251 SSC_START_EDGE_RF |
00252 (1 << SSC_STTDLY_LSB));
00253 outr(SSC_TFMR,
00254 ((PCM_BITS - 1) << SSC_DATLEN_LSB) |
00255 SSC_MSBF);
00256
00257 if (use_pdc) {
00258
00259 outr(SSC_PTCR, PDC_TXTEN);
00260 }
00261 outr(SSC_CR, SSC_TXEN);
00262
00263 return 0;
00264 }
00265
00271 static int Tlv320I2sDisable(void)
00272 {
00273
00274 outr(SSC_IDR, 0xFFFFFFFF);
00275
00276
00277 NutIrqDisable(&sig_SSC);
00278
00279
00280 outr(PMC_PCDR, _BV(SSC_ID));
00281
00282
00283 outr(SSC_CR, SSC_SWRST | SSC_RXDIS | SSC_TXDIS);
00284 outr(SSC_RCMR, 0);
00285 outr(SSC_RFMR, 0);
00286 outr(SSC_PTCR, PDC_RXTDIS);
00287 outr(SSC_PTCR, PDC_TXTDIS);
00288 outr(SSC_TNCR, 0);
00289 outr(SSC_TCR, 0);
00290
00291 return 0;
00292 }
00293
00301 static int Tlv320I2sInit(u_int rate)
00302 {
00303
00304 NutRegisterIrqHandler(&sig_SSC, I2sInterrupt, 0);
00305
00306 Tlv320I2sDisable();
00307 Tlv320I2sEnable(rate);
00308
00309
00310 NutIrqEnable(&sig_SSC);
00311
00312 return 0;
00313 }
00314
00315 int Tlv320DacSetRate(u_int rate)
00316 {
00317 switch(rate) {
00318 case 8000:
00319 #ifdef AT91SAM7X_EK
00320 Tlv320DacWriteReg(DAC_SRATE, (3 << DAC_SRATE_SR_LSB));
00321 #else
00322 Tlv320DacWriteReg(DAC_SRATE, (3 << DAC_SRATE_SR_LSB) | DAC_SRATE_USB);
00323 #endif
00324 break;
00325 case 8021:
00326 Tlv320DacWriteReg(DAC_SRATE, (11 << DAC_SRATE_SR_LSB) | DAC_SRATE_BOSR | DAC_SRATE_USB);
00327 break;
00328 case 44100:
00329 Tlv320DacWriteReg(DAC_SRATE, (8 << DAC_SRATE_SR_LSB) | DAC_SRATE_BOSR | DAC_SRATE_USB);
00330 break;
00331 case 48000:
00332 Tlv320DacWriteReg(DAC_SRATE, (0 << DAC_SRATE_SR_LSB) | DAC_SRATE_USB);
00333 break;
00334 case 88200:
00335 Tlv320DacWriteReg(DAC_SRATE, (15 << DAC_SRATE_SR_LSB) | DAC_SRATE_BOSR | DAC_SRATE_USB);
00336 break;
00337 case 96000:
00338 Tlv320DacWriteReg(DAC_SRATE, (7 << DAC_SRATE_SR_LSB) | DAC_SRATE_USB);
00339 break;
00340 default:
00341 return -1;
00342 }
00343 return 0;
00344 }
00345
00353 int Tlv320DacInit(u_int rate)
00354 {
00355
00356 TwInit(0);
00357
00358 Tlv320DacWriteReg(DAC_RESET, 0);
00359
00360 Tlv320DacWriteReg(DAC_PWRDN, DAC_PWRDN_LINE);
00361 Tlv320DacWriteReg(DAC_PWRDN, 0);
00362
00363 if (Tlv320DacSetRate(rate)) {
00364 Tlv320DacWriteReg(DAC_RESET, 0);
00365 return -1;
00366 }
00367 Tlv320DacWriteReg(DAC_ANA_PATH, DAC_ANA_PATH_DAC | DAC_ANA_PATH_INSEL | DAC_ANA_PATH_MICB);
00368 Tlv320DacWriteReg(DAC_DIG_PATH, 0);
00369
00370 Tlv320DacWriteReg(DAC_DAI_FMT, DAC_DAI_FMT_MS | DAC_DAI_FMT_FOR_I2S);
00371 Tlv320DacWriteReg(DAC_DI_ACT, DAC_DI_ACT_ACT);
00372
00373 Tlv320DacWriteReg(DAC_LHP_VOL, DAC_LHP_VOL_LRS | (0x60 << DAC_LHP_VOL_LHV_LSB));
00374
00375
00376 return Tlv320I2sInit(rate);
00377 }
00378
00384 static int Tlv320DacStart(void)
00385 {
00386 NutIrqDisable(&sig_SSC);
00387 if (use_pdc) {
00388 outr(SSC_IDR, SSC_TXEMPTY);
00389
00390 outr(SSC_PTCR, PDC_TXTEN);
00391 I2sPdcFill();
00392 outr(SSC_IER, SSC_ENDTX);
00393 } else {
00394 outr(SSC_IDR, SSC_ENDTX);
00395
00396 outr(SSC_PTCR, PDC_TXTDIS);
00397 outr(SSC_IER, SSC_TXEMPTY);
00398 }
00399
00400 outr(SSC_CR, SSC_TXEN);
00401 NutIrqEnable(&sig_SSC);
00402
00403 return 0;
00404 }
00405
00411 int Tlv320DacFlush(void)
00412 {
00413 int rc = 0;
00414
00415 while (bwr_idx != brd_idx) {
00416 Tlv320DacStart();
00417 if ((rc = NutEventWait(&i2s_que, 500)) != 0) {
00418 break;
00419 }
00420 }
00421 return rc;
00422 }
00423
00432 int Tlv320DacWrite(void *buf, int len)
00433 {
00434 u_int idx;
00435
00436
00437 idx = bwr_idx + 1;
00438 if (idx >= SAMPLE_BUFFERS) {
00439 idx = 0;
00440 }
00441
00442
00443
00444 while (idx == brd_idx) {
00445 if (NutEventWait(&i2s_que, 100)) {
00446 Tlv320DacStart();
00447 }
00448 }
00449
00450
00451
00452
00453 if (pcm_bufq[idx].wbf_siz < len) {
00454 if (pcm_bufq[idx].wbf_siz) {
00455 free(pcm_bufq[idx].wbf_dat);
00456 pcm_bufq[idx].wbf_siz = 0;
00457 }
00458 pcm_bufq[idx].wbf_dat = malloc(len * 2);
00459 if (pcm_bufq[idx].wbf_dat == NULL) {
00460
00461 return -1;
00462 }
00463 pcm_bufq[idx].wbf_siz = len;
00464 }
00465
00466
00467
00468
00469
00470
00471 memcpy(pcm_bufq[idx].wbf_dat, buf, len * 2);
00472 pcm_bufq[idx].wbf_len = len;
00473 bwr_idx = idx;
00474
00475 return 0;
00476 }
00477
00488 int Tlv320DacSetVolume(int left, int right)
00489 {
00490
00491 if (left > DAC_MAX_VOLUME) {
00492 left = DAC_MAX_VOLUME;
00493 }
00494 else if (left < DAC_MIN_VOLUME) {
00495 left = DAC_MIN_VOLUME;
00496 }
00497 if (right > DAC_MAX_VOLUME) {
00498 right = DAC_MAX_VOLUME;
00499 }
00500 else if (right < DAC_MIN_VOLUME) {
00501 right = DAC_MIN_VOLUME;
00502 }
00503 Tlv320DacWriteReg(DAC_LHP_VOL, (u_int)(left + 121));
00504 Tlv320DacWriteReg(DAC_RHP_VOL, (u_int)(right + 121));
00505
00506 return 0;
00507 }
00508
00509 int Tlv320SwitchMode(void)
00510 {
00511 NutIrqDisable(&sig_SSC);
00512 use_pdc = !use_pdc;
00513 Tlv320DacStart();
00514 return 0;
00515 }