tlv320dac.c

Go to the documentation of this file.
00001 
00057 #include <cfg/os.h>
00058 #include <cfg/clock.h>
00059 #include <dev/board.h>
00060 #include <dev/irqreg.h>
00061 #include <dev/twif.h>
00062 
00063 #include <stdlib.h>
00064 #include <string.h>
00065 #include <memdebug.h>
00066 
00067 #include <sys/event.h>
00068 #include <sys/timer.h>
00069 
00070 #include <dev/tlv320dac.h>
00071 
00072 #ifndef TWI_SLA_DAC
00073 #define TWI_SLA_DAC     0x1A
00074 #endif
00075 
00076 /*
00077  * Initial volume.
00078  */
00079 #ifndef TLV320DAC_VOL
00080 #define TLV320DAC_VOL   0x18
00081 #endif
00082 
00083 /*
00084  * Number of PCM buffers.
00085  */
00086 #ifndef SAMPLE_BUFFERS
00087 #if defined (AT91SAM9260_EK)
00088 #define SAMPLE_BUFFERS  32
00089 #else
00090 #define SAMPLE_BUFFERS  3
00091 #endif
00092 #endif
00093 
00094 /*
00095  * Select I2S pins.
00096  */
00097 #if defined (MCU_AT91SAM9260) /* _EK */
00098 
00099 #define DACI2S_PIO_ID   PIOB_ID
00100 #define DACI2S_PINS_A   _BV(PB18_TD0_A) | _BV(PB17_TF0_A) | _BV(PB16_TK0_A)
00101 #define DACI2S_PINS_B   0
00102 
00103 #else                           /* _EK */
00104 #define DACI2S_PIO_ID   PIOA_ID
00105 #define DACI2S_PINS_A   _BV(PA23_TD_A) | _BV(PA21_TF_A) | _BV(PA22_TK_A)
00106 #define DACI2S_PINS_B   0
00107 #endif                          /* _EK */
00108 
00109 /*
00110  * Determine PIO used by I2S.
00111  */
00112 #if DACI2S_PIO_ID == PIOA_ID    /* DACI2S_PIO_ID */
00113 #define DACI2S_PDR  PIOA_PDR
00114 #define DACI2S_ASR  PIOA_ASR
00115 #define DACI2S_BSR  PIOA_BSR
00116 #elif DACI2S_PIO_ID == PIOB_ID  /* DACI2S_PIO_ID */
00117 #define DACI2S_PDR  PIOB_PDR
00118 #define DACI2S_ASR  PIOB_ASR
00119 #define DACI2S_BSR  PIOB_BSR
00120 #endif                          /* DACI2S_PIO_ID */
00121 
00125 static HANDLE i2s_que;
00126 
00130 #define PCM_CHANS   2
00131 
00135 #define PCM_BITS    16
00136 
00140 typedef struct _PCM_BUFFER {
00141     u_short *wbf_dat;           
00142     int wbf_siz;                
00143     int wbf_len;                
00144 } PCM_BUFFER;
00145 
00146 /* PCM buffer queue. */
00147 static PCM_BUFFER pcm_bufq[SAMPLE_BUFFERS];
00148 /* PCM buffer read index. */
00149 static volatile unsigned int brd_idx;
00150 /* PCM buffer write index. */
00151 static unsigned int bwr_idx;
00152 
00158 static void I2sPdcFill(void)
00159 {
00160     if (brd_idx != bwr_idx) {
00161         if (inr(SSC_TNCR) == 0) {
00162             if (++brd_idx >= SAMPLE_BUFFERS) {
00163                 brd_idx = 0;
00164             }
00165             outr(SSC_TNPR, (unsigned int) pcm_bufq[brd_idx].wbf_dat);
00166             outr(SSC_TNCR, pcm_bufq[brd_idx].wbf_len);
00167         }
00168     }
00169 }
00170 
00176 static void I2sInterrupt(void *arg)
00177 {
00178     I2sPdcFill();
00179     NutEventPostFromIrq(&i2s_que);
00180 }
00181 
00191 u_char Tlv320DacReadReg(unsigned int reg)
00192 {
00193     return 0xFF;
00194 }
00195 
00204 void Tlv320DacWriteReg(unsigned int reg, unsigned int val)
00205 {
00206     u_char txdata[2];
00207 
00208     txdata[0] = (u_char)(reg << 1) | (u_char)(val >> 8);
00209     txdata[1] = (u_char)val;
00210     TwMasterTransact(TWI_SLA_DAC, txdata, 2, NULL, 0, 0);
00211 }
00212 
00220 static int Tlv320I2sEnable(unsigned int rate)
00221 {
00222     /* Enable SSC clock. */
00223     outr(PMC_PCER, _BV(SSC_ID));
00224 
00225     /* Select SSC peripheral functions. */
00226     outr(DACI2S_ASR, DACI2S_PINS_A);
00227     outr(DACI2S_BSR, DACI2S_PINS_B);
00228 
00229     /* Enable SSC peripheral pins. */
00230     outr(DACI2S_PDR, DACI2S_PINS_A | DACI2S_PINS_B);
00231 
00232     /* Configure 16-bit stereo I2S transmit format. */
00233     outr(SSC_CMR, 0);
00234     outr(SSC_TCMR,              /* Set transmit clock mode. */
00235         SSC_CKS_PIN |            /* Use external clock at TK. */
00236         SSC_START_EDGE_RF |     /* Start transmission on any edge. */
00237         (1 << SSC_STTDLY_LSB)); /* Delay start by 1 cycle. */
00238     outr(SSC_TFMR,              /* Set transmit frame mode. */
00239         ((PCM_BITS - 1) << SSC_DATLEN_LSB) |   /* Transmit 16 bits. */
00240         SSC_MSBF);              /* Most significant bit first. */
00241 
00242     /* Enable transmitter in PDC mode. */
00243     outr(SSC_PTCR, PDC_TXTEN);
00244     outr(SSC_CR, SSC_TXEN);
00245 
00246     return 0;
00247 }
00248 
00254 static int Tlv320I2sDisable(void)
00255 {
00256     /* Disable all interrupts. */
00257     outr(SSC_IDR, 0xFFFFFFFF);
00258 
00259     /* Disable SSC interrupt. */
00260     NutIrqDisable(&sig_SSC);
00261 
00262     /* Disable SSC clock. */
00263     outr(PMC_PCDR, _BV(SSC_ID));
00264 
00265     /* Reset receiver and transmitter. */
00266     outr(SSC_CR, SSC_SWRST | SSC_RXDIS | SSC_TXDIS);
00267     outr(SSC_RCMR, 0);
00268     outr(SSC_RFMR, 0);
00269     outr(SSC_PTCR, PDC_RXTDIS);
00270     outr(SSC_PTCR, PDC_TXTDIS);
00271     outr(SSC_TNCR, 0);
00272     outr(SSC_TCR, 0);
00273 
00274     return 0;
00275 }
00276 
00284 static int Tlv320I2sInit(unsigned int rate)
00285 {
00286     /* Register SSC interrupt handler. */
00287     NutRegisterIrqHandler(&sig_SSC, I2sInterrupt, 0);
00288 
00289     Tlv320I2sDisable();
00290     Tlv320I2sEnable(rate);
00291 
00292     /* Enable SSC interrupt. */
00293     NutIrqEnable(&sig_SSC);
00294 
00295     return 0;
00296 }
00297 
00298 int Tlv320DacSetRate(unsigned int rate)
00299 {
00300     switch(rate) {
00301     case 8000:
00302 #ifdef AT91SAM7X_EK
00303         Tlv320DacWriteReg(DAC_SRATE, (3 << DAC_SRATE_SR_LSB));
00304 #else
00305         Tlv320DacWriteReg(DAC_SRATE, (3 << DAC_SRATE_SR_LSB) | DAC_SRATE_USB);
00306 #endif
00307         break;
00308     case 8021:      
00309         Tlv320DacWriteReg(DAC_SRATE, (11 << DAC_SRATE_SR_LSB) | DAC_SRATE_BOSR | DAC_SRATE_USB);
00310         break;
00311     case 44100:     
00312         Tlv320DacWriteReg(DAC_SRATE, (8 << DAC_SRATE_SR_LSB) | DAC_SRATE_BOSR | DAC_SRATE_USB);
00313         break;
00314     case 48000:     
00315         Tlv320DacWriteReg(DAC_SRATE, (0 << DAC_SRATE_SR_LSB) | DAC_SRATE_USB);
00316         break;
00317     case 88200:     
00318         Tlv320DacWriteReg(DAC_SRATE, (15 << DAC_SRATE_SR_LSB) | DAC_SRATE_BOSR | DAC_SRATE_USB);
00319         break;
00320     case 96000:     
00321         Tlv320DacWriteReg(DAC_SRATE, (7 << DAC_SRATE_SR_LSB) | DAC_SRATE_USB);
00322         break;
00323     default:        
00324         return -1;
00325     }
00326     return 0;
00327 }
00328 
00336 int Tlv320DacInit(unsigned int rate)
00337 {
00338     /* Initialize TWI. */
00339     TwInit(0);
00340 
00341     Tlv320DacWriteReg(DAC_RESET, 0);
00342     /* Power down line in. */
00343     Tlv320DacWriteReg(DAC_PWRDN, DAC_PWRDN_LINE);
00344     Tlv320DacWriteReg(DAC_PWRDN, 0);
00345     /* Set sampling rate. */
00346     if (Tlv320DacSetRate(rate)) {
00347         Tlv320DacWriteReg(DAC_RESET, 0);
00348         return -1;
00349     }
00350     Tlv320DacWriteReg(DAC_ANA_PATH, DAC_ANA_PATH_DAC | DAC_ANA_PATH_INSEL | DAC_ANA_PATH_MICB);
00351     Tlv320DacWriteReg(DAC_DIG_PATH, 0);
00352     /* I2S master. */
00353     Tlv320DacWriteReg(DAC_DAI_FMT, DAC_DAI_FMT_MS | DAC_DAI_FMT_FOR_I2S);
00354     Tlv320DacWriteReg(DAC_DI_ACT, DAC_DI_ACT_ACT);
00355 
00356     Tlv320DacWriteReg(DAC_LHP_VOL, DAC_LHP_VOL_LRS | (0x60 << DAC_LHP_VOL_LHV_LSB));
00357 
00358     /* Initialize I2S. */
00359     return Tlv320I2sInit(rate);
00360 }
00361 
00367 static int Tlv320DacStart(void)
00368 {
00369     NutIrqDisable(&sig_SSC);
00370     I2sPdcFill();
00371     outr(SSC_IER, SSC_ENDTX);
00372     outr(SSC_CR, SSC_TXEN);
00373     NutIrqEnable(&sig_SSC);
00374 
00375     return 0;
00376 }
00377 
00383 int Tlv320DacFlush(void)
00384 {
00385     int rc = 0;
00386 
00387     while (bwr_idx != brd_idx) {
00388         Tlv320DacStart();
00389         if ((rc = NutEventWait(&i2s_que, 500)) != 0) {
00390             break;
00391         }
00392     }
00393     return rc;
00394 }
00395 
00404 int Tlv320DacWrite(void *buf, int len)
00405 {
00406     unsigned int idx;
00407 
00408     /* Move to the next buffer to write to. */
00409     idx = bwr_idx + 1;
00410     if (idx >= SAMPLE_BUFFERS) {
00411         idx = 0;
00412     }
00413 
00414     /* If all buffers are filled, wait for an event posted by the
00415        interrupt routine. */
00416     while (idx == brd_idx) {
00417         if (NutEventWait(&i2s_que, 100)) {
00418             Tlv320DacStart();
00419         }
00420     }
00421 
00422     /*
00423      * Check, if the current buffer size is too small or not allocated.
00424      */
00425     if (pcm_bufq[idx].wbf_siz < len) {
00426         if (pcm_bufq[idx].wbf_siz) {
00427             free(pcm_bufq[idx].wbf_dat);
00428             pcm_bufq[idx].wbf_siz = 0;
00429         }
00430         pcm_bufq[idx].wbf_dat = malloc(len * 2);
00431         if (pcm_bufq[idx].wbf_dat == NULL) {
00432             /* Out of memory. */
00433             return -1;
00434         }
00435         pcm_bufq[idx].wbf_siz = len;
00436     }
00437 
00438     /*
00439      * At this point we got an available buffer with sufficient size.
00440      * Move the data to it, set the number of valid bytes and update
00441      * the write (producer) index.
00442      */
00443     memcpy(pcm_bufq[idx].wbf_dat, buf, len * 2);
00444     pcm_bufq[idx].wbf_len = len;
00445     bwr_idx = idx;
00446 
00447     return 0;
00448 }
00449 
00460 int Tlv320DacSetVolume(int left, int right)
00461 {
00462     /* Cut to limits. */
00463     if (left > DAC_MAX_VOLUME) {
00464         left = DAC_MAX_VOLUME;
00465     }
00466     else if (left < DAC_MIN_VOLUME) {
00467         left = DAC_MIN_VOLUME;
00468     }
00469     if (right > DAC_MAX_VOLUME) {
00470         right = DAC_MAX_VOLUME;
00471     }
00472     else if (right < DAC_MIN_VOLUME) {
00473         right = DAC_MIN_VOLUME;
00474     }
00475     Tlv320DacWriteReg(DAC_LHP_VOL, (unsigned int)(left + 121));
00476     Tlv320DacWriteReg(DAC_RHP_VOL, (unsigned int)(right + 121));
00477 
00478     return 0;
00479 }

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/