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