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 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 void XDMAC_Handler( void )
00214 {
00215 XDMAD_Handler( &dmad );
00216 }
00217
00218
00219
00220
00221 static void _SscDma(volatile uint32_t *pReg, uint32_t dmaChannel,
00222 void* pBuffer, uint16_t wSize)
00223 {
00224 sXdmad *pDmad = &dmad;
00225 sXdmadCfg xdmadCfg;
00226
00227 xdmadCfg.mbr_ubc = wSize ;
00228 xdmadCfg.mbr_sa = (uint32_t) pBuffer;
00229 xdmadCfg.mbr_da = (uint32_t) pReg;
00230 xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
00231 | XDMAC_CC_MBSIZE_SINGLE
00232 | XDMAC_CC_DSYNC_MEM2PER
00233 | XDMAC_CC_CSIZE_CHK_1
00234 | XDMAC_CC_DWIDTH_HALFWORD
00235 | XDMAC_CC_SIF_AHB_IF0
00236 | XDMAC_CC_DIF_AHB_IF1
00237 | XDMAC_CC_SAM_INCREMENTED_AM
00238 | XDMAC_CC_DAM_FIXED_AM
00239 | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(
00240 ID_SSC, XDMAD_TRANSFER_TX));
00241 xdmadCfg.mbr_bc = 0;
00242 xdmadCfg.mbr_ds = 0;
00243 xdmadCfg.mbr_sus = 0;
00244 xdmadCfg.mbr_dus = 0;
00245
00246 memory_sync();
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();
00255 XDMAD_StartTransfer( pDmad, dmaChannel );
00256
00257 }
00258
00259
00260
00261
00262 static void _SscTxCallback(uint32_t channel, void* pArg)
00263 {
00264 sXdmad *pDmad = &dmad;
00265 Xdmac *pXdmac = pDmad->pXdmacs;
00266 pArg = pArg;
00267 if (numBuffersToSend == 0) {
00268
00269 isDacActive = 0;
00270 return;
00271 }
00272
00273
00274 XDMAC_SetSourceAddr(pXdmac, sscDmaTxChannel, (uint32_t) buffers[outBufferIndex]);
00275 XDMAC_SetMicroblockControl(pXdmac, sscDmaTxChannel, bufferSizes[outBufferIndex]);
00276 outBufferIndex = (outBufferIndex + 1) % BUFFER_NUMBER;
00277 numBuffersToSend --;
00278 memory_sync();
00279 XDMAD_StartTransfer( pDmad, sscDmaTxChannel );
00280 }
00281
00282
00283
00284
00285 static void _ConfigureDma( void )
00286 {
00287 sXdmad *pDmad = &dmad;
00288
00289 XDMAD_Initialize( pDmad, 0 );
00290
00291 NVIC_ClearPendingIRQ(XDMAC_IRQn);
00292 NVIC_SetPriority(XDMAC_IRQn, 1);
00293 NVIC_EnableIRQ(XDMAC_IRQn);
00294
00295
00296 sscDmaTxChannel = XDMAD_AllocateChannel( pDmad, XDMAD_TRANSFER_MEMORY, ID_SSC);
00297 if (sscDmaTxChannel == XDMAD_ALLOC_FAILED ) {
00298 printf("xDMA channel allocation error\n\r");
00299 while(1);
00300 }
00301
00302
00303 XDMAD_SetCallback(pDmad, sscDmaTxChannel,(XdmadTransferCallback)_SscTxCallback, 0);
00304 XDMAD_PrepareChannel(pDmad, sscDmaTxChannel );
00305 }
00306
00307
00308
00309
00310 static void AudioPlayEnable(uint8_t enable)
00311 {
00312 if (enable == 1) {
00313 SSC_EnableTransmitter(SSC);
00314 } else if (enable == 0) {
00315 SSC_DisableTransmitter(SSC);
00316 }
00317 }
00318
00319
00320
00321
00322
00323 static void _SyncAdjust(int32_t adjust)
00324 {
00325 if (adjust > 0) {
00326
00327 WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_FLL_CRTL3, 0xFF00);
00328
00329 return;
00330 }
00331 if (adjust < 0) {
00332
00333 WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_FLL_CRTL3, 0x5000);
00334
00335 return;
00336 }
00337
00338
00339
00340
00341 WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_FLL_CRTL3, 0x8000 + 0x3000);
00342
00343 return;
00344 }
00345
00346
00347
00348
00349
00350
00351 static void _ConfigureAudioPlay(uint32_t sampleRate, uint32_t mck)
00352 {
00353
00354 PIO_Configure(pinsAudio, PIO_LISTSIZE(pinsAudio));
00355
00356
00357 sampleRate = sampleRate;
00358 SSC_Configure(SSC,0, mck);
00359 SSC_DisableTransmitter(SSC);
00360 SSC_ConfigureTransmitter(SSC, I2S_SLAVE_TX_SETTING,I2S_SLAVE_TX_FRM_SETTING);
00361 SSC_ConfigureReceiver(SSC,I2S_SLAVE_RX_SETTING,I2S_SLAVE_RX_FRM_SETTING);
00362
00363
00364 PMC_EnablePeripheral(ID_TWIHS0);
00365
00366 TWI_ConfigureMaster(TWIHS0, TWI_CLOCK, mck);
00367 TWID_Initialize(&twid, TWIHS0);
00368
00369
00370
00371
00372 WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_RESET, 0);
00373 Wait(100);
00374
00375 if(WM8904_Read(&twid, WM8904_SLAVE_ADDRESS, 0)!=0x8904) {
00376 printf("WM8904 not found!\n\r");
00377 while(1);
00378 }
00379 WM8904_Init(&twid, WM8904_SLAVE_ADDRESS,PMC_MCKR_CSS_SLOW_CLK);
00380 _SyncAdjust(0);
00381 PMC_ConfigurePCK2(PMC_MCKR_CSS_SLOW_CLK, PMC_MCKR_PRES_CLK_1 );
00382
00383 AudioPlayEnable(0);
00384 }
00385
00386
00387
00388
00389 static void FrameReceived(uint32_t unused,
00390 uint8_t status,
00391 uint32_t transferred,
00392 uint32_t remaining)
00393 {
00394 unused = unused;
00395 remaining = remaining;
00396 if (status == USBD_STATUS_SUCCESS) {
00397 bufferSizes[inBufferIndex] = transferred / AUDDevice_BYTESPERSAMPLE;
00398 inBufferIndex = (inBufferIndex + 1) % BUFFER_NUMBER;
00399 numBuffersToSend++;
00400
00401 if (!isDacActive) {
00402 dacDelay = DAC_DELAY;
00403 isDacActive = 1;
00404 } else if (dacDelay > 0) {
00405
00406 dacDelay--;
00407 } else if (isFirstFrame) {
00408
00409 isFirstFrame = 0;
00410 AudioPlayEnable(1);
00411 _SscDma(&(SSC->SSC_THR), sscDmaTxChannel,
00412 buffers[outBufferIndex], bufferSizes[outBufferIndex]);
00413 outBufferIndex = (outBufferIndex + 1) % BUFFER_NUMBER;
00414 numBuffersToSend --;
00415 }
00416 } else if (status == USBD_STATUS_ABORTED) {
00417
00418 bufferSizes[inBufferIndex] = 0;
00419 } else {
00420
00421 }
00422
00423 AUDDSpeakerDriver_Read(buffers[inBufferIndex],
00424 AUDDevice_BYTESPERFRAME,
00425 (TransferCallback) FrameReceived,
00426 0);
00427 }
00428
00429
00430
00431
00432
00433
00434
00435
00436 void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum)
00437 {
00438 AUDDSpeakerDriver_ConfigurationChangeHandler(cfgnum);
00439 }
00440
00441
00442
00443
00444
00445
00446
00447 void USBDDriverCallbacks_InterfaceSettingChanged(unsigned char interface,
00448 unsigned char setting)
00449 {
00450 AUDDSpeakerDriver_InterfaceSettingChangedHandler(interface, setting);
00451 }
00452
00453
00454
00455
00456
00457 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00458 {
00459 AUDDSpeakerDriver_RequestHandler(request);
00460 }
00461
00462
00463
00464
00465
00466
00467
00468 void AUDDSpeakerDriver_MuteChanged(uint8_t channel, uint8_t muted)
00469 {
00470
00471 if (channel == AUDDSpeakerDriver_MASTERCHANNEL) {
00472 if (muted) {
00473 AudioPlayEnable(0);
00474 TRACE_WARNING("MuteMaster ");
00475 } else {
00476 TRACE_INFO("UnmuteMaster ");
00477 AudioPlayEnable(1);
00478 }
00479 }
00480 }
00481
00482
00483
00484
00485
00486
00487 void AUDDSpeakerDriver_StreamSettingChanged(uint8_t newSetting)
00488 {
00489 if (newSetting) {
00490 LED_Set(USBD_LEDOTHER);
00491 numBuffersToSend = 0;
00492 } else {
00493 LED_Clear(USBD_LEDOTHER);
00494 }
00495 }
00496
00497
00498
00499
00500 static void _ConfigureUsbhs(void)
00501 {
00502
00503
00504 PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00505
00506 PMC->PMC_USB = PMC_USB_USBS;
00507
00508 PMC_EnablePeripheral(ID_USBHS);
00509 USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00510
00511 PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00512
00513 while( !(PMC->PMC_SR & PMC_SR_LOCKU) );
00514
00515 NVIC_EnableIRQ(USBHS_IRQn) ;
00516 }
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 int main(void)
00527 {
00528 volatile uint8_t usbConn = 0;
00529 volatile uint8_t audioOn = 0;
00530 volatile uint32_t num = 0;
00531 int32_t numDiff = 0, prevDiff = 0;
00532 int8_t clockAdjust = 0;
00533
00534
00535 WDT_Disable( WDT );
00536
00537 printf("-- USB Device Audio Speaker Example %s --\n\r", SOFTPACK_VERSION);
00538 printf("-- %s\n\r", BOARD_NAME);
00539 printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00540
00541 SCB_EnableICache();
00542 SCB_EnableDCache();
00543
00544
00545 LED_Configure(LED_YELLOW0);
00546
00547 TimeTick_Configure();
00548
00549 NVIC_SetPriority( USBHS_IRQn, 2 );
00550
00551
00552 _ConfigureUsbhs();
00553
00554 _ConfigureAudioPlay(AUDDevice_SAMPLERATE, BOARD_MCK);
00555
00556
00557 _ConfigureDma();
00558
00559
00560 AUDDSpeakerDriver_Initialize(&auddSpeakerDriverDescriptors);
00561
00562
00563 USBD_Connect();
00564
00565
00566 while (1) {
00567 if (USBD_GetState() < USBD_STATE_CONFIGURED) {
00568 usbConn = 0;
00569 continue;
00570 }
00571 if (audioOn) {
00572 if(isDacActive == 0) {
00573 AudioPlayEnable(0);
00574 printf("audE ");
00575 isFirstFrame = 1;
00576 audioOn = 0;
00577 } else {
00578 if (num != numBuffersToSend) {
00579 num = numBuffersToSend;
00580 }
00581 numDiff = numBuffersToSend - DAC_DELAY;
00582 if (prevDiff != numDiff) {
00583 prevDiff = numDiff;
00584 if (numDiff > 0 && clockAdjust != 1) {
00585 printf("+");
00586
00587 clockAdjust = 1;
00588 _SyncAdjust(1);
00589 }
00590 if (numDiff < 0 && clockAdjust != -1) {
00591 printf("-");
00592
00593 clockAdjust = -1;
00594 _SyncAdjust(-1);
00595 }
00596 if (numDiff == 0 && clockAdjust != 0) {
00597 clockAdjust = 0;
00598 _SyncAdjust(0);
00599 }
00600 }
00601 }
00602 } else if (isDacActive) {
00603 printf("audS ");
00604 audioOn = 1;
00605 }
00606
00607 if (usbConn == 0) {
00608 usbConn = 1;
00609
00610 AUDDSpeakerDriver_Read(buffers[inBufferIndex],
00611 AUDDevice_BYTESPERFRAME,
00612 (TransferCallback) FrameReceived,
00613 0);
00614 }
00615 }
00616 }
00617