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 if (status != XDMAD_OK) return;
00295 pArg = pArg;
00296 if (numBuffersToSend == 0) {
00297
00298 isDacActive = 0;
00299 return;
00300 }
00301
00302 XDMAC_SetSourceAddr(pXdmac, sscDmaTxChannel, (uint32_t) buffers[outBufferIndex]);
00303 XDMAC_SetMicroblockControl(pXdmac, sscDmaTxChannel, bufferSizes[outBufferIndex]);
00304 outBufferIndex = (outBufferIndex + 1) % BUFFER_NUMBER;
00305 numBuffersToSend --;
00306 XDMAD_StartTransfer( pDmad, sscDmaTxChannel );
00307 }
00308
00309
00310
00311
00312 static void _ConfigureDma( void )
00313 {
00314 sXdmad *pDmad = &dmad;
00315
00316 XDMAD_Initialize( pDmad, 0 );
00317
00318 NVIC_EnableIRQ(XDMAC_IRQn);
00319
00320
00321 sscDmaTxChannel = XDMAD_AllocateChannel( pDmad, XDMAD_TRANSFER_MEMORY, ID_SSC);
00322 if (sscDmaTxChannel == XDMAD_ALLOC_FAILED ) {
00323 printf("xDMA channel allocation error\n\r");
00324 while(1);
00325 }
00326
00327 XDMAD_SetCallback(pDmad, sscDmaTxChannel,(XdmadTransferCallback)_SscTxCallback, 0);
00328 XDMAD_PrepareChannel(pDmad, sscDmaTxChannel );
00329 }
00330
00331
00332
00333
00334 static void AudioPlayEnable(uint8_t enable)
00335 {
00336 if (enable == 1) {
00337 SSC_EnableTransmitter(SSC);
00338 } else if (enable == 0) {
00339 SSC_DisableTransmitter(SSC);
00340 }
00341 }
00342
00343
00344
00345
00346
00347 static void _SyncAdjust(int32_t adjust)
00348 {
00349 if (adjust > 0) {
00350
00351 WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_FLL_CRTL3, 0xFF00);
00352
00353 return;
00354 }
00355 if (adjust < 0) {
00356
00357 WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_FLL_CRTL3, 0x5000);
00358 return;
00359 }
00360
00361
00362
00363
00364 WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_FLL_CRTL3, 0x8000 + 0x3000);
00365
00366 return;
00367 }
00368
00369
00370
00371
00372
00373 static void _ConfigureAudioPlay(uint32_t sampleRate, uint32_t mck)
00374 {
00375
00376 PIO_Configure(pinsAudio, PIO_LISTSIZE(pinsAudio));
00377
00378
00379 sampleRate = sampleRate;
00380 SSC_Configure(SSC,0, mck);
00381 SSC_DisableTransmitter(SSC);
00382 SSC_DisableReceiver(SSC);
00383 SSC_ConfigureTransmitter(SSC, I2S_SLAVE_TX_SETTING,I2S_SLAVE_TX_FRM_SETTING);
00384 SSC_DisableTransmitter(SSC);
00385
00386
00387 PMC_EnablePeripheral(ID_TWIHS0);
00388
00389 TWI_ConfigureMaster(TWIHS0, TWI_CLOCK, mck);
00390 TWID_Initialize(&twid, TWIHS0);
00391
00392
00393
00394
00395 WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_RESET, 0);
00396 Wait(100);
00397
00398 if(WM8904_Read(&twid, WM8904_SLAVE_ADDRESS, 0)!=0x8904) {
00399 printf("WM8904 not found!\n\r");
00400 while(1);
00401 }
00402 WM8904_Init(&twid, WM8904_SLAVE_ADDRESS,PMC_MCKR_CSS_SLOW_CLK);
00403 _SyncAdjust(0);
00404 PMC_ConfigurePCK2(PMC_MCKR_CSS_SLOW_CLK, PMC_MCKR_PRES_CLK_1 );
00405
00406 AudioPlayEnable(0);
00407 }
00408
00409
00410
00411
00412 static void FrameReceived(uint32_t unused,
00413 uint8_t status,
00414 uint32_t transferred,
00415 uint32_t remaining)
00416 {
00417 unused = unused;
00418 remaining = remaining;
00419 if (status == USBD_STATUS_SUCCESS) {
00420
00421 bufferSizes[inBufferIndex] = transferred / AUDDevice_BYTESPERSAMPLE;
00422 inBufferIndex = (inBufferIndex + 1) % BUFFER_NUMBER;
00423 numBuffersToSend++;
00424
00425
00426 if (!isDacActive) {
00427 dacDelay = DAC_DELAY;
00428 isDacActive = 1;
00429 }
00430
00431 else if (dacDelay > 0) {
00432 dacDelay--;
00433 }
00434
00435 else if (isFirstFrame) {
00436 isFirstFrame = 0;
00437
00438 _SscDma(&(SSC->SSC_THR), sscDmaTxChannel, buffers[outBufferIndex], bufferSizes[outBufferIndex]);
00439 outBufferIndex = (outBufferIndex + 1) % BUFFER_NUMBER;
00440 numBuffersToSend --;
00441 }
00442 }
00443 else if (status == USBD_STATUS_ABORTED) {
00444
00445 bufferSizes[inBufferIndex] = 0;
00446 } else {
00447
00448 }
00449
00450 AUDDFunction_Read(buffers[inBufferIndex],
00451 AUDDevice_BYTESPERFRAME,
00452 (TransferCallback) FrameReceived,
00453 0);
00454 }
00455
00456
00457
00458
00459 static void CdcDataReceived(uint32_t unused,
00460 uint8_t status,
00461 uint32_t received,
00462 uint32_t remaining)
00463 {
00464 unused = unused;
00465 remaining = remaining;
00466
00467 if (status == USBD_STATUS_SUCCESS) {
00468
00469 CDCDSerial_Write(usbSerialBuffer0, received, 0, 0);
00470
00471 CDCDSerial_Read(usbSerialBuffer0,
00472 DATAPACKETSIZE,
00473 (TransferCallback) CdcDataReceived,
00474 0);
00475 } else {
00476 TRACE_WARNING( "CdcDataReceived: Transfer error\n\r");
00477 }
00478 }
00479
00480
00481
00482
00483
00484
00485
00486
00487 void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum)
00488 {
00489 CDCAUDDDriver_ConfigurationChangedHandler(cfgnum);
00490 }
00491
00492
00493
00494
00495
00496
00497
00498 void USBDDriverCallbacks_InterfaceSettingChanged(uint8_t interface,
00499 uint8_t setting)
00500 {
00501 CDCAUDDDriver_InterfaceSettingChangedHandler(interface, setting);
00502 }
00503
00504
00505
00506
00507
00508 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00509 {
00510 CDCAUDDDriver_RequestHandler(request);
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522 void CDCDSerial_ControlLineStateChanged(uint8_t DTR,
00523 uint8_t RTS)
00524 {
00525 isSerialPortON = DTR;
00526 RTS = RTS;
00527 }
00528
00529
00530
00531
00532
00533
00534
00535
00536 void AUDDFunction_MuteChanged(uint8_t mic,
00537 uint8_t channel,
00538 uint8_t muted)
00539 {
00540
00541 if (mic) return;
00542
00543
00544 if (channel == AUDD_CH_Master) {
00545 if (muted) {
00546 AudioPlayEnable(0);
00547 TRACE_WARNING("MuteMaster ");
00548 } else {
00549 TRACE_INFO("UnmuteMaster ");
00550 AudioPlayEnable(1);
00551 }
00552 }
00553 }
00554
00555
00556
00557
00558
00559
00560
00561
00562 void AUDDFunction_StreamSettingChanged(uint8_t mic,
00563 uint8_t newSetting)
00564 {
00565
00566 mic = mic;
00567 if (newSetting) {
00568 LED_Set(LED_YELLOW0);
00569
00570 numBuffersToSend = 0;
00571 }
00572 else LED_Clear(LED_YELLOW0);
00573 }
00574
00575
00576
00577
00578 static void _ConfigureUsbhs(void)
00579 {
00580
00581
00582 PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00583
00584 PMC->PMC_USB = PMC_USB_USBS;
00585
00586 PMC_EnablePeripheral(ID_USBHS);
00587 USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00588
00589 PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00590
00591 while( !(PMC->PMC_SR & PMC_SR_LOCKU) );
00592
00593 NVIC_EnableIRQ(USBHS_IRQn) ;
00594 }
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606 int main(void)
00607 {
00608 volatile uint8_t usbConn = 0;
00609 volatile uint8_t audioOn = 0;
00610 volatile uint8_t serialOn = 0;
00611 volatile uint32_t num = 0;
00612 int32_t numDiff = 0, prevDiff = 0;
00613 int8_t clockAdjust = 0;
00614
00615
00616 WDT_Disable( WDT );
00617
00618 SCB_EnableICache();
00619 SCB_EnableDCache();
00620
00621 printf("-- USB CDC + Audio Device Example %s --\n\r", SOFTPACK_VERSION);
00622 printf("-- %s\n\r", BOARD_NAME);
00623 printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00624
00625 TimeTick_Configure();
00626
00627 NVIC_SetPriority( USBHS_IRQn, 2 );
00628
00629
00630 PIO_InitializeInterrupts(0);
00631
00632
00633 _ConfigureUsbhs();
00634
00635
00636 LED_Configure(LED_YELLOW0);
00637
00638
00639 _ConfigureAudioPlay(AUDDevice_SAMPLERATE, BOARD_MCK);
00640 _ConfigureDma();
00641
00642
00643 CDCAUDDDriver_Initialize(&cdcauddDriverDescriptors);
00644
00645 USBD_Connect();
00646
00647
00648 while (1) {
00649 if (USBD_GetState() < USBD_STATE_CONFIGURED) {
00650 usbConn = 0;
00651 continue;
00652 }
00653 if (audioOn) {
00654 if(isDacActive == 0) {
00655 AudioPlayEnable(0);
00656 printf("audE ");
00657 isFirstFrame = 1;
00658 audioOn = 0;
00659 } else {
00660 if (num != numBuffersToSend) {
00661 num = numBuffersToSend;
00662 }
00663 numDiff = numBuffersToSend - DAC_DELAY;
00664 if (prevDiff != numDiff) {
00665 prevDiff = numDiff;
00666 if (numDiff > 0 && clockAdjust != 1) {
00667 printf("+");
00668
00669 clockAdjust = 1;
00670 _SyncAdjust(1);
00671 }
00672 if (numDiff < 0 && clockAdjust != -1) {
00673 printf("-");
00674
00675 clockAdjust = -1;
00676 _SyncAdjust(-1);
00677 }
00678 if (numDiff == 0 && clockAdjust != 0) {
00679 clockAdjust = 0;
00680 _SyncAdjust(0);
00681 }
00682 }
00683 }
00684 } else if (isDacActive) {
00685 printf("audS ");
00686 audioOn = 1;
00687 }
00688 if (usbConn == 0) {
00689 usbConn = 1;
00690
00691 AUDDFunction_Read(buffers[inBufferIndex],
00692 AUDDevice_BYTESPERFRAME,
00693 (TransferCallback) FrameReceived,
00694 0);
00695 }
00696
00697 if (!serialOn && isSerialPortON) {
00698 printf("-I- SerialPort ON\n\r");
00699
00700 CDCDSerial_Read(usbSerialBuffer0,
00701 DATAPACKETSIZE,
00702 (TransferCallback) CdcDataReceived,
00703 0);
00704 serialOn = 1;
00705 } else if (serialOn && !isSerialPortON) {
00706 printf("-I- SeriaoPort OFF\n\r");
00707 serialOn = 0;
00708 }
00709 }
00710 }
00711