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