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
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 #include "board.h"
00114
00115 #include <CDCAUDDDriver.h>
00116 #include <CDCDSerial.h>
00117 #include <AUDDFunction.h>
00118
00119 #include <USBD_Config.h>
00120
00121 #include <stdio.h>
00122 #include <stdbool.h>
00123 #include <stdint.h>
00124
00125
00126
00127
00128
00129
00130
00131 #define DATAPACKETSIZE \
00132 CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCAUDD_Descriptors_DATAIN0)
00133
00134
00135 #define DATABUFFERSIZE (DATAPACKETSIZE+2)
00136
00137
00138
00139 #define BUFFER_NUMBER 500
00140
00141 #define BUFFER_SIZE (AUDDevice_BYTESPERFRAME)
00142
00143
00144
00145 #define DAC_DELAY 2
00146
00147
00148 #define SLOT_BY_FRAME (2)
00149
00150 #define BITS_BY_SLOT (16)
00151 #define I2S_SLAVE_TX_SETTING ((SSC_TCMR_CKS_TK) | \
00152 (SSC_TCMR_CKO_NONE) | \
00153 (SSC_TCMR_START_TF_EDGE) | \
00154 (SSC_TCMR_STTDLY(1)) | \
00155 (SSC_TCMR_PERIOD(0)))
00156
00157 #define I2S_SLAVE_TX_FRM_SETTING ((SSC_TFMR_DATLEN(BITS_BY_SLOT - 1)) | \
00158 (SSC_TFMR_MSBF) | \
00159 (SSC_TFMR_DATNB(SLOT_BY_FRAME - 1)) | \
00160 (SSC_TFMR_FSOS_NONE))
00161
00162
00163 #define I2S_SLAVE_RX_SETTING ((SSC_RCMR_CKS_TK) | \
00164 (SSC_RCMR_CKO_NONE) | \
00165 (SSC_RCMR_CKI) | \
00166 (SSC_RCMR_START_RF_EDGE) | \
00167 (SSC_RCMR_STTDLY(1)) | \
00168 (SSC_RCMR_PERIOD(0)))
00169
00170 #define I2S_SLAVE_RX_FRM_SETTING ((SSC_RFMR_DATLEN(BITS_BY_SLOT - 1)) | \
00171 (SSC_RFMR_MSBF) | \
00172 (SSC_RFMR_DATNB(SLOT_BY_FRAME - 1)) | \
00173 (SSC_RFMR_FSOS_NONE))
00174
00175
00176 #define TWI_CLOCK 400000
00177
00178 #define SAMPLE_RATE (48000)
00179
00180
00181
00182
00183
00184
00185
00186 extern const USBDDriverDescriptors cdcauddDriverDescriptors;
00187
00188
00189
00190
00191
00192
00193
00194
00195 static uint8_t usbSerialBuffer0[DATABUFFERSIZE];
00196
00197 static volatile uint8_t isSerialPortON = 0;
00198
00199
00200
00201
00202 COMPILER_ALIGNED(32) static uint8_t buffers[BUFFER_NUMBER][BUFFER_SIZE];
00203
00204
00205 static uint32_t bufferSizes[BUFFER_NUMBER];
00206
00207 static uint32_t inBufferIndex = 0;
00208
00209 static uint32_t outBufferIndex = 0;
00210
00211 static volatile uint32_t numBuffersToSend = 0;
00212
00213
00214 static volatile uint32_t isDacActive = 0;
00215 static volatile uint32_t isFirstFrame = 1;
00216
00217 static volatile uint32_t dacDelay;
00218
00219
00220 static Twid twid;
00221
00222 COMPILER_ALIGNED(32) static sXdmad dmad;
00223
00224 static uint32_t sscDmaTxChannel;
00225
00226
00227 static const Pin pinsAudio[] = { PIN_TWI_TWD0,
00228 PIN_TWI_TWCK0,
00229 PIN_SSC_TD,
00230 PIN_SSC_TK,
00231 PIN_SSC_TF,
00232 PIN_SSC_RD,
00233 PIN_SSC_RK,
00234 PIN_SSC_RF,
00235 PIN_PCK2};
00236
00237
00238
00239
00240
00241
00242
00243
00244 void XDMAC_Handler( void )
00245 {
00246 XDMAD_Handler( &dmad );
00247 }
00248
00249
00250
00251
00252 static void _SscDma(volatile uint32_t *pReg, uint32_t dmaChannel,
00253 void* pBuffer, uint16_t wSize)
00254 {
00255 sXdmad *pDmad = &dmad;
00256 sXdmadCfg xdmadCfg;
00257
00258 SCB_CleanInvalidateDCache();
00259 xdmadCfg.mbr_ubc = wSize ;
00260 xdmadCfg.mbr_sa = (uint32_t) pBuffer;
00261 xdmadCfg.mbr_da = (uint32_t) pReg;
00262 xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
00263 | XDMAC_CC_MBSIZE_SINGLE
00264 | XDMAC_CC_DSYNC_MEM2PER
00265 | XDMAC_CC_CSIZE_CHK_1
00266 | XDMAC_CC_DWIDTH_HALFWORD
00267 | XDMAC_CC_SIF_AHB_IF0
00268 | XDMAC_CC_DIF_AHB_IF1
00269 | XDMAC_CC_SAM_INCREMENTED_AM
00270 | XDMAC_CC_DAM_FIXED_AM
00271 | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( ID_SSC, XDMAD_TRANSFER_TX));
00272 xdmadCfg.mbr_bc = 0;
00273 xdmadCfg.mbr_ds = 0;
00274 xdmadCfg.mbr_sus = 0;
00275 xdmadCfg.mbr_dus = 0;
00276
00277 XDMAD_ConfigureTransfer( pDmad, dmaChannel, &xdmadCfg, 0, 0,(XDMAC_CIE_BIE |
00278 XDMAC_CIE_DIE |
00279 XDMAC_CIE_FIE |
00280 XDMAC_CIE_RBIE |
00281 XDMAC_CIE_WBIE |
00282 XDMAC_CIE_ROIE));
00283 XDMAD_StartTransfer( pDmad, dmaChannel );
00284 SSC_EnableTransmitter(SSC);
00285 }
00286
00287
00288
00289
00290 static void _SscTxCallback(uint8_t status, void* pArg)
00291 {
00292 sXdmad *pDmad = &dmad;
00293 Xdmac *pXdmac = pDmad->pXdmacs;
00294 pArg = pArg;
00295 if (numBuffersToSend == 0) {
00296
00297 isDacActive = 0;
00298 return;
00299 }
00300
00301 XDMAC_SetSourceAddr(pXdmac, sscDmaTxChannel, (uint32_t) buffers[outBufferIndex]);
00302 XDMAC_SetMicroblockControl(pXdmac, sscDmaTxChannel, bufferSizes[outBufferIndex]);
00303 outBufferIndex = (outBufferIndex + 1) % BUFFER_NUMBER;
00304 numBuffersToSend --;
00305 XDMAD_StartTransfer( pDmad, sscDmaTxChannel );
00306 }
00307
00308
00309
00310
00311 static void _ConfigureDma( void )
00312 {
00313 sXdmad *pDmad = &dmad;
00314
00315 XDMAD_Initialize( pDmad, 0 );
00316
00317 NVIC_EnableIRQ(XDMAC_IRQn);
00318
00319
00320 sscDmaTxChannel = XDMAD_AllocateChannel( pDmad, XDMAD_TRANSFER_MEMORY, ID_SSC);
00321 if (sscDmaTxChannel == XDMAD_ALLOC_FAILED ) {
00322 printf("xDMA channel allocation error\n\r");
00323 while(1);
00324 }
00325
00326 XDMAD_SetCallback(pDmad, sscDmaTxChannel,(XdmadTransferCallback)_SscTxCallback, 0);
00327 XDMAD_PrepareChannel(pDmad, sscDmaTxChannel );
00328 }
00329
00330
00331
00332
00333 static void AudioPlayEnable(uint8_t enable)
00334 {
00335 if (enable == 1) {
00336 SSC_EnableTransmitter(SSC);
00337 } else if (enable == 0) {
00338 SSC_DisableTransmitter(SSC);
00339 }
00340 }
00341
00342
00343
00344
00345
00346 static void _SyncAdjust(int32_t adjust)
00347 {
00348 if (adjust > 0) {
00349
00350 WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_FLL_CRTL3, 0xFF00);
00351
00352 return;
00353 }
00354 if (adjust < 0) {
00355
00356 WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_FLL_CRTL3, 0x5000);
00357 return;
00358 }
00359
00360
00361
00362
00363 WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_FLL_CRTL3, 0x8000 + 0x3000);
00364
00365 return;
00366 }
00367
00368
00369
00370
00371
00372 static void _ConfigureAudioPlay(uint32_t sampleRate, uint32_t mck)
00373 {
00374
00375 PIO_Configure(pinsAudio, PIO_LISTSIZE(pinsAudio));
00376
00377
00378 sampleRate = sampleRate;
00379 SSC_Configure(SSC,0, mck);
00380 SSC_DisableTransmitter(SSC);
00381 SSC_DisableReceiver(SSC);
00382 SSC_ConfigureTransmitter(SSC, I2S_SLAVE_TX_SETTING,I2S_SLAVE_TX_FRM_SETTING);
00383 SSC_DisableTransmitter(SSC);
00384
00385
00386 PMC_EnablePeripheral(ID_TWIHS0);
00387
00388 TWI_ConfigureMaster(TWIHS0, TWI_CLOCK, mck);
00389 TWID_Initialize(&twid, TWIHS0);
00390
00391
00392
00393
00394 WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_RESET, 0);
00395 Wait(100);
00396
00397 if(WM8904_Read(&twid, WM8904_SLAVE_ADDRESS, 0)!=0x8904) {
00398 printf("WM8904 not found!\n\r");
00399 while(1);
00400 }
00401 WM8904_Init(&twid, WM8904_SLAVE_ADDRESS,PMC_MCKR_CSS_SLOW_CLK);
00402 _SyncAdjust(0);
00403 PMC_ConfigurePCK2(PMC_MCKR_CSS_SLOW_CLK, PMC_MCKR_PRES_CLK_1 );
00404
00405 AudioPlayEnable(0);
00406 }
00407
00408
00409
00410
00411 static void FrameReceived(uint32_t unused,
00412 uint8_t status,
00413 uint32_t transferred,
00414 uint32_t remaining)
00415 {
00416 unused = unused;
00417 remaining = remaining;
00418 if (status == USBD_STATUS_SUCCESS) {
00419
00420 bufferSizes[inBufferIndex] = transferred / AUDDevice_BYTESPERSAMPLE;
00421 inBufferIndex = (inBufferIndex + 1) % BUFFER_NUMBER;
00422 numBuffersToSend++;
00423
00424
00425 if (!isDacActive) {
00426 dacDelay = DAC_DELAY;
00427 isDacActive = 1;
00428 }
00429
00430 else if (dacDelay > 0) {
00431 dacDelay--;
00432 }
00433
00434 else if (isFirstFrame) {
00435 isFirstFrame = 0;
00436
00437 _SscDma(&(SSC->SSC_THR), sscDmaTxChannel, buffers[outBufferIndex], bufferSizes[outBufferIndex]);
00438 outBufferIndex = (outBufferIndex + 1) % BUFFER_NUMBER;
00439 numBuffersToSend --;
00440 }
00441 }
00442 else if (status == USBD_STATUS_ABORTED) {
00443
00444 bufferSizes[inBufferIndex] = 0;
00445 } else {
00446
00447 }
00448
00449 AUDDFunction_Read(buffers[inBufferIndex],
00450 AUDDevice_BYTESPERFRAME,
00451 (TransferCallback) FrameReceived,
00452 0);
00453 }
00454
00455
00456
00457
00458 static void CdcDataReceived(uint32_t unused,
00459 uint8_t status,
00460 uint32_t received,
00461 uint32_t remaining)
00462 {
00463 unused = unused;
00464 remaining = remaining;
00465
00466 if (status == USBD_STATUS_SUCCESS) {
00467
00468 CDCDSerial_Write(usbSerialBuffer0, received, 0, 0);
00469
00470 CDCDSerial_Read(usbSerialBuffer0,
00471 DATAPACKETSIZE,
00472 (TransferCallback) CdcDataReceived,
00473 0);
00474 } else {
00475 TRACE_WARNING( "CdcDataReceived: Transfer error\n\r");
00476 }
00477 }
00478
00479
00480
00481
00482
00483
00484
00485
00486 void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum)
00487 {
00488 CDCAUDDDriver_ConfigurationChangedHandler(cfgnum);
00489 }
00490
00491
00492
00493
00494
00495
00496
00497 void USBDDriverCallbacks_InterfaceSettingChanged(uint8_t interface,
00498 uint8_t setting)
00499 {
00500 CDCAUDDDriver_InterfaceSettingChangedHandler(interface, setting);
00501 }
00502
00503
00504
00505
00506
00507 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00508 {
00509 CDCAUDDDriver_RequestHandler(request);
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521 void CDCDSerial_ControlLineStateChanged(uint8_t DTR,
00522 uint8_t RTS)
00523 {
00524 isSerialPortON = DTR;
00525 RTS = RTS;
00526 }
00527
00528
00529
00530
00531
00532
00533
00534
00535 void AUDDFunction_MuteChanged(uint8_t mic,
00536 uint8_t channel,
00537 uint8_t muted)
00538 {
00539
00540 if (mic) return;
00541
00542
00543 if (channel == AUDD_CH_Master) {
00544 if (muted) {
00545 AudioPlayEnable(0);
00546 TRACE_WARNING("MuteMaster ");
00547 } else {
00548 TRACE_INFO("UnmuteMaster ");
00549 AudioPlayEnable(1);
00550 }
00551 }
00552 }
00553
00554
00555
00556
00557
00558
00559
00560
00561 void AUDDFunction_StreamSettingChanged(uint8_t mic,
00562 uint8_t newSetting)
00563 {
00564
00565 mic = mic;
00566 if (newSetting) {
00567 LED_Set(LED_YELLOW0);
00568
00569 numBuffersToSend = 0;
00570 }
00571 else LED_Clear(LED_YELLOW0);
00572 }
00573
00574
00575
00576
00577 static void _ConfigureUsbhs(void)
00578 {
00579
00580
00581 PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00582
00583 PMC->PMC_USB = PMC_USB_USBS;
00584
00585 PMC_EnablePeripheral(ID_USBHS);
00586 USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00587
00588 PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00589
00590 while( !(PMC->PMC_SR & PMC_SR_LOCKU) );
00591
00592 NVIC_EnableIRQ(USBHS_IRQn) ;
00593 }
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605 int main(void)
00606 {
00607 volatile uint8_t usbConn = 0;
00608 volatile uint8_t audioOn = 0;
00609 volatile uint8_t serialOn = 0;
00610 volatile uint32_t num = 0;
00611 int32_t numDiff = 0, prevDiff = 0;
00612 int8_t clockAdjust = 0;
00613
00614
00615 WDT_Disable( WDT );
00616
00617 SCB_EnableICache();
00618 SCB_EnableDCache();
00619
00620 printf("-- USB CDC + Audio Device Example %s --\n\r", SOFTPACK_VERSION);
00621 printf("-- %s\n\r", BOARD_NAME);
00622 printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00623
00624 TimeTick_Configure();
00625
00626 NVIC_SetPriority( USBHS_IRQn, 2 );
00627
00628
00629 PIO_InitializeInterrupts(0);
00630
00631
00632 _ConfigureUsbhs();
00633
00634
00635 LED_Configure(LED_YELLOW0);
00636
00637
00638 _ConfigureAudioPlay(AUDDevice_SAMPLERATE, BOARD_MCK);
00639 _ConfigureDma();
00640
00641
00642 CDCAUDDDriver_Initialize(&cdcauddDriverDescriptors);
00643
00644 USBD_Connect();
00645
00646
00647 while (1) {
00648 if (USBD_GetState() < USBD_STATE_CONFIGURED) {
00649 usbConn = 0;
00650 continue;
00651 }
00652 if (audioOn) {
00653 if(isDacActive == 0) {
00654 AudioPlayEnable(0);
00655 printf("audE ");
00656 isFirstFrame = 1;
00657 audioOn = 0;
00658 } else {
00659 if (num != numBuffersToSend) {
00660 num = numBuffersToSend;
00661 }
00662 numDiff = numBuffersToSend - DAC_DELAY;
00663 if (prevDiff != numDiff) {
00664 prevDiff = numDiff;
00665 if (numDiff > 0 && clockAdjust != 1) {
00666 printf("+");
00667
00668 clockAdjust = 1;
00669 _SyncAdjust(1);
00670 }
00671 if (numDiff < 0 && clockAdjust != -1) {
00672 printf("-");
00673
00674 clockAdjust = -1;
00675 _SyncAdjust(-1);
00676 }
00677 if (numDiff == 0 && clockAdjust != 0) {
00678 clockAdjust = 0;
00679 _SyncAdjust(0);
00680 }
00681 }
00682 }
00683 } else if (isDacActive) {
00684 printf("audS ");
00685 audioOn = 1;
00686 }
00687 if (usbConn == 0) {
00688 usbConn = 1;
00689
00690 AUDDFunction_Read(buffers[inBufferIndex],
00691 AUDDevice_BYTESPERFRAME,
00692 (TransferCallback) FrameReceived,
00693 0);
00694 }
00695
00696 if (!serialOn && isSerialPortON) {
00697 printf("-I- SerialPort ON\n\r");
00698
00699 CDCDSerial_Read(usbSerialBuffer0,
00700 DATAPACKETSIZE,
00701 (TransferCallback) CdcDataReceived,
00702 0);
00703 serialOn = 1;
00704 } else if (serialOn && !isSerialPortON) {
00705 printf("-I- SeriaoPort OFF\n\r");
00706 serialOn = 0;
00707 }
00708 }
00709 }
00710