00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 #include "board.h"
00089
00090
00091
00092
00093
00094 #define min( a, b ) (((a) < (b)) ? (a) : (b))
00095
00096
00097
00098
00099 #define I2S_SLAVE_TX_SETTING ((SSC_TCMR_CKS_TK) | \
00100 (SSC_TCMR_CKO_NONE) | \
00101 (SSC_TCMR_START_TF_EDGE) | \
00102 (SSC_TCMR_STTDLY(1)) | \
00103 (SSC_TCMR_PERIOD(0)))
00104
00105 #define I2S_SLAVE_TX_FRM_SETTING ((SSC_TFMR_DATLEN(BITS_BY_SLOT - 1)) | \
00106 (SSC_TFMR_MSBF) | \
00107 (SSC_TFMR_DATNB(SLOT_BY_FRAME - 1)) | \
00108 (SSC_TFMR_FSOS_NONE))
00109
00110
00111 #define I2S_SLAVE_RX_SETTING ((SSC_RCMR_CKS_TK) | \
00112 (SSC_RCMR_CKO_NONE) | \
00113 (SSC_RCMR_CKI) | \
00114 (SSC_RCMR_START_RF_EDGE) | \
00115 (SSC_RCMR_STTDLY(1)) | \
00116 (SSC_RCMR_PERIOD(0)))
00117
00118 #define I2S_SLAVE_RX_FRM_SETTING ((SSC_RFMR_DATLEN(BITS_BY_SLOT - 1)) | \
00119 (SSC_RFMR_MSBF) | \
00120 (SSC_RFMR_DATNB(SLOT_BY_FRAME - 1)) | \
00121 (SSC_RFMR_FSOS_NONE))
00122
00123
00124
00125 #define SSC_MCK BOARD_MCK
00126
00127
00128 #define MAX_RECORD_SIZE 0xFFFFFFFF
00129
00130
00131 #define MAX_DMA_SIZE 0x1000
00132
00133
00134 #define TWI_CLOCK 400000
00135
00136
00137 #define SAMPLE_RATE (48000)
00138 #define SLOT_BY_FRAME (1)
00139 #define BITS_BY_SLOT (16)
00140
00141
00142 #define TOTAL_Buffers 4
00143 #define AUDIO_IF SSC
00144
00145
00146
00147
00148
00149
00150 static const Pin pinsSsc[] = {PIN_TWI_TWD0, PIN_TWI_TWCK0, PIN_SSC_TD,
00151 PIN_SSC_TK, PIN_SSC_TF, PIN_SSC_RD, PIN_SSC_RK, PIN_SSC_RF, PIN_PCK2};
00152
00153
00154 static sXdmad dmad;
00155
00156 static uint32_t sscDmaRxChannel;
00157
00158 static uint32_t sscDmaTxChannel;
00159
00160 static sXdmadCfg xdmadCfg;
00161
00162 static LinkedListDescriporView1 dmaWriteLinkList[TOTAL_Buffers];
00163 static LinkedListDescriporView1 dmaReadLinkList[TOTAL_Buffers];
00164
00165
00166 static Twid twid;
00167
00168 static uint16_t AudioBuffer[TOTAL_Buffers*MAX_DMA_SIZE * (BITS_BY_SLOT/8)];
00169
00170
00171
00172
00173
00174
00175
00176
00177 void XDMAC_Handler(void)
00178 {
00179 XDMAD_Handler(&dmad);
00180 }
00181
00182
00183
00184
00185 void TWIHS0_Handler(void )
00186 {
00187 TWID_Handler( &twid ) ;
00188 }
00189
00190
00191
00192
00193 static void Dma_configure(void)
00194 {
00195 sXdmad *pDmad = &dmad;
00196
00197 XDMAD_Initialize( pDmad, 0 );
00198
00199 NVIC_ClearPendingIRQ(XDMAC_IRQn);
00200 NVIC_EnableIRQ(XDMAC_IRQn);
00201
00202 sscDmaTxChannel = XDMAD_AllocateChannel( pDmad, XDMAD_TRANSFER_MEMORY, ID_SSC);
00203 sscDmaRxChannel = XDMAD_AllocateChannel( pDmad, ID_SSC, XDMAD_TRANSFER_MEMORY);
00204 if ( sscDmaTxChannel == XDMAD_ALLOC_FAILED
00205 || sscDmaRxChannel == XDMAD_ALLOC_FAILED ) {
00206 printf("xDMA channel allocation error\n\r");
00207 while(1);
00208 }
00209 XDMAD_PrepareChannel(pDmad, sscDmaTxChannel );
00210 XDMAD_PrepareChannel(pDmad, sscDmaRxChannel );
00211 }
00212
00213
00214
00215
00216
00217 static void PlayRecording(void)
00218 {
00219 uint16_t *src;
00220 uint8_t i;
00221 uint32_t xdmaCndc;
00222
00223 src = &AudioBuffer[0];
00224 for(i = 0; i < TOTAL_Buffers; i++) {
00225 dmaReadLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1
00226 | XDMA_UBC_NDE_FETCH_EN
00227 | XDMA_UBC_NSEN_UPDATED
00228 | XDMAC_CUBC_UBLEN(MAX_DMA_SIZE);
00229 dmaReadLinkList[i].mbr_sa = (uint32_t)&(AUDIO_IF->SSC_RHR);
00230 dmaReadLinkList[i].mbr_da = (uint32_t)(src );
00231 if ( i == (TOTAL_Buffers - 1)) {
00232 dmaReadLinkList[i].mbr_nda = (uint32_t)&dmaReadLinkList[0];
00233 } else {
00234 dmaReadLinkList[i].mbr_nda = (uint32_t)&dmaReadLinkList[i + 1];
00235 }
00236 src += MAX_DMA_SIZE ;
00237 }
00238
00239 xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
00240 | XDMAC_CC_MBSIZE_SINGLE
00241 | XDMAC_CC_DSYNC_PER2MEM
00242 | XDMAC_CC_CSIZE_CHK_1
00243 | XDMAC_CC_DWIDTH_HALFWORD
00244 | XDMAC_CC_SIF_AHB_IF1
00245 | XDMAC_CC_DIF_AHB_IF0
00246 | XDMAC_CC_SAM_FIXED_AM
00247 | XDMAC_CC_DAM_INCREMENTED_AM
00248 | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ID_SSC, XDMAD_TRANSFER_RX ));
00249 xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1
00250 | XDMAC_CNDC_NDE_DSCR_FETCH_EN
00251 | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
00252 | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
00253
00254 memory_sync();
00255 XDMAD_ConfigureTransfer( &dmad, sscDmaRxChannel, &xdmadCfg, xdmaCndc,
00256 (uint32_t)&dmaReadLinkList[0],XDMAC_CIE_LIE);
00257
00258
00259 src = &AudioBuffer[0];
00260 for(i = 0; i < TOTAL_Buffers; i++) {
00261 dmaWriteLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1
00262 | XDMA_UBC_NDE_FETCH_EN
00263 | XDMA_UBC_NSEN_UPDATED
00264 | XDMAC_CUBC_UBLEN(MAX_DMA_SIZE);
00265 dmaWriteLinkList[i].mbr_sa = (uint32_t)(src );
00266 dmaWriteLinkList[i].mbr_da = (uint32_t)&(AUDIO_IF->SSC_THR);
00267 if ( i == (TOTAL_Buffers - 1 )) {
00268 dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[0];
00269 } else {
00270 dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[i+1];
00271 }
00272 src += MAX_DMA_SIZE;
00273 }
00274
00275 xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
00276 | XDMAC_CC_MBSIZE_SINGLE
00277 | XDMAC_CC_DSYNC_MEM2PER
00278 | XDMAC_CC_CSIZE_CHK_1
00279 | XDMAC_CC_DWIDTH_HALFWORD
00280 | XDMAC_CC_SIF_AHB_IF0
00281 | XDMAC_CC_DIF_AHB_IF1
00282 | XDMAC_CC_SAM_INCREMENTED_AM
00283 | XDMAC_CC_DAM_FIXED_AM
00284 | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ID_SSC, XDMAD_TRANSFER_TX ));
00285 xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1
00286 | XDMAC_CNDC_NDE_DSCR_FETCH_EN
00287 | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
00288 | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
00289
00290 memory_sync();
00291 XDMAD_ConfigureTransfer( &dmad, sscDmaTxChannel, &xdmadCfg, xdmaCndc,
00292 (uint32_t)&dmaWriteLinkList[0],XDMAC_CIE_LIE);
00293
00294 SSC_EnableReceiver(AUDIO_IF);
00295 SCB_CleanInvalidateDCache();
00296 XDMAD_StartTransfer( &dmad, sscDmaRxChannel );
00297
00298
00299 Wait(300);
00300
00301 SSC_EnableTransmitter(AUDIO_IF);
00302 SCB_CleanInvalidateDCache();
00303 XDMAD_StartTransfer( &dmad, sscDmaTxChannel);
00304
00305 }
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 int main( void )
00316 {
00317 uint16_t data = 0;
00318
00319 WDT_Disable( WDT ) ;
00320
00321
00322 SCB_EnableICache();
00323 SCB_EnableDCache();
00324
00325
00326 printf("-- SSC DMA Audio Example %s --\n\r", SOFTPACK_VERSION);
00327 printf("-- %s\n\r", BOARD_NAME);
00328 printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00329
00330
00331 printf( "Configure system tick to get 1ms tick period.\n\r" ) ;
00332 if ( TimeTick_Configure( ) )
00333 {
00334 printf("-F- Systick configuration error\n\r" ) ;
00335 }
00336
00337
00338 PIO_Configure(pinsSsc, PIO_LISTSIZE(pinsSsc));
00339
00340
00341 SSC_Configure(AUDIO_IF , 0 , SSC_MCK );
00342 SSC_ConfigureReceiver(AUDIO_IF,I2S_SLAVE_RX_SETTING,I2S_SLAVE_RX_FRM_SETTING);
00343 SSC_DisableReceiver(AUDIO_IF);
00344 SSC_ConfigureTransmitter(AUDIO_IF,I2S_SLAVE_TX_SETTING,I2S_SLAVE_TX_FRM_SETTING);
00345 SSC_DisableTransmitter(AUDIO_IF);
00346
00347
00348 Dma_configure();
00349
00350
00351 PMC_EnablePeripheral(ID_TWIHS0);
00352 TWI_ConfigureMaster(TWIHS0, TWI_CLOCK, BOARD_MCK);
00353 TWID_Initialize(&twid, TWIHS0);
00354
00355 NVIC_ClearPendingIRQ(TWIHS0_IRQn);
00356 NVIC_EnableIRQ(TWIHS0_IRQn);
00357
00358
00359 WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, 22, 0);
00360 data=WM8904_Read(&twid, WM8904_SLAVE_ADDRESS, 0);
00361 if( data != 0x8904) {
00362 printf("WM8904 not found!\n\r");
00363 while(1);
00364 }
00365
00366 WM8904_Init(&twid, WM8904_SLAVE_ADDRESS, PMC_MCKR_CSS_SLOW_CLK);
00367
00368
00369 PMC_ConfigurePCK2(PMC_MCKR_CSS_SLOW_CLK, PMC_MCKR_PRES_CLK_1 );
00370 printf("Insert Line-in cable with PC Headphone output\n\r" );
00371 PlayRecording();
00372 while ( 1 );
00373 }