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
00114 #include "board.h"
00115
00116 #include <USBD_Config.h>
00117
00118 #include <DUALCDCDDriver.h>
00119
00120 #include <string.h>
00121 #include <stdbool.h>
00122 #include <stdint.h>
00123 #include <stdio.h>
00124
00125
00126
00127
00128
00129
00130 #define DATAPACKETSIZE \
00131 CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCDSerialDriverDescriptors_DATAIN)
00132
00133
00134 #define DATABUFFERSIZE (DATAPACKETSIZE+2)
00135
00136
00137 #define PINS_USART PIN_USART1_TXD, PIN_USART1_RXD
00138
00139 #define BASE_USART USART1
00140
00141 #define ID_USART ID_USART1
00142
00143
00144
00145
00146
00147 extern const USBDDriverDescriptors dualcdcdDriverDescriptors;
00148
00149
00150
00151
00152
00153
00154 static sXdmad dmad;
00155
00156
00157 static uint32_t usartDmaRxChannel;
00158
00159 static uint32_t usartDmaTxChannel;
00160
00161
00162 static LinkedListDescriporView1 dmaRxLinkList[2];
00163
00164
00165
00166 static const Pin pinsUsart[] = {PINS_USART};
00167
00168
00169 static uint8_t usartBuffers[2][DATABUFFERSIZE];
00170
00171
00172 static uint8_t usartCurrentBuffer = 0;
00173
00174
00175 static uint8_t usbSerialBuffer0[DATABUFFERSIZE];
00176
00177 static uint8_t usbSerialBuffer1[DATABUFFERSIZE];
00178
00179
00180 static uint8_t isUsartON = 0;
00181
00182 static uint8_t isSerialPort0ON = 0;
00183
00184 static uint8_t isSerialPort1ON = 0;
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum)
00196 {
00197 DUALCDCDDriver_ConfigurationChangeHandler(cfgnum);
00198 }
00199
00200
00201
00202
00203
00204
00205 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00206 {
00207 DUALCDCDDriver_RequestHandler(request);
00208 }
00209
00210
00211
00212
00213
00214
00215
00216
00217 void XDMAC_Handler(void)
00218 {
00219 XDMAD_Handler(&dmad);
00220 }
00221
00222
00223
00224
00225 static void _UsartDmaTx( uint32_t dwDestAddr, void* pBuffer, uint16_t wSize )
00226 {
00227 sXdmad *pDmad = &dmad;
00228
00229 sXdmadCfg xdmadCfg;
00230 xdmadCfg.mbr_ubc = wSize ;
00231 xdmadCfg.mbr_sa = (uint32_t) pBuffer;
00232 xdmadCfg.mbr_da = (uint32_t) dwDestAddr;
00233 xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
00234 | XDMAC_CC_MEMSET_NORMAL_MODE
00235 | XDMAC_CC_CSIZE_CHK_1
00236 | XDMAC_CC_DWIDTH_BYTE
00237 | XDMAC_CC_SIF_AHB_IF0
00238 | XDMAC_CC_DIF_AHB_IF1
00239 | XDMAC_CC_SAM_INCREMENTED_AM
00240 | XDMAC_CC_DAM_FIXED_AM
00241 | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(
00242 ID_USART, XDMAD_TRANSFER_TX ));
00243 xdmadCfg.mbr_bc = 0;
00244 XDMAD_ConfigureTransfer( pDmad, usartDmaTxChannel, &xdmadCfg, 0, 0, (
00245 XDMAC_CIE_BIE |
00246 XDMAC_CIE_DIE |
00247 XDMAC_CIE_FIE |
00248 XDMAC_CIE_RBIE |
00249 XDMAC_CIE_WBIE |
00250 XDMAC_CIE_ROIE));
00251 XDMAD_StartTransfer( pDmad, usartDmaTxChannel );
00252 }
00253
00254
00255
00256
00257
00258 static void _UsartDmaRxSetup( void )
00259 {
00260 uint8_t i;
00261 Usart *pUs = BASE_USART;
00262 for (i = 0; i < 2; i++) {
00263 dmaRxLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1
00264 | XDMA_UBC_NDE_FETCH_EN
00265 | XDMA_UBC_NSEN_UPDATED
00266 | XDMAC_CUBC_UBLEN(DATAPACKETSIZE);
00267 dmaRxLinkList[i].mbr_sa = (uint32_t)&pUs->US_RHR;
00268 dmaRxLinkList[i].mbr_da = (uint32_t)usartBuffers[i];
00269 dmaRxLinkList[i].mbr_nda = (uint32_t)&dmaRxLinkList[i];
00270 }
00271 }
00272
00273
00274
00275
00276
00277 static void _UsartDmaRx( uint32_t startBuffer )
00278 {
00279 sXdmad *pDmad = &dmad;
00280 sXdmadCfg xdmadUsartRxCfg;
00281 uint32_t xdmaUsartRxCndc;
00282 xdmadUsartRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
00283 | XDMAC_CC_MBSIZE_SINGLE
00284 | XDMAC_CC_DSYNC_PER2MEM
00285 | XDMAC_CC_CSIZE_CHK_1
00286 | XDMAC_CC_DWIDTH_BYTE
00287 | XDMAC_CC_SIF_AHB_IF1
00288 | XDMAC_CC_DIF_AHB_IF0
00289 | XDMAC_CC_SAM_FIXED_AM
00290 | XDMAC_CC_DAM_INCREMENTED_AM
00291 | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(
00292 ID_USART, XDMAD_TRANSFER_RX ));
00293 xdmaUsartRxCndc = XDMAC_CNDC_NDVIEW_NDV1
00294 | XDMAC_CNDC_NDE_DSCR_FETCH_EN
00295 | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
00296 | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
00297 XDMAD_ConfigureTransfer( pDmad, usartDmaRxChannel, &xdmadUsartRxCfg,
00298 xdmaUsartRxCndc, (uint32_t)&dmaRxLinkList[startBuffer],XDMAC_CIE_LIE);
00299 XDMAD_StartTransfer(pDmad, usartDmaRxChannel);
00300 }
00301
00302
00303
00304
00305 void TC0_Handler(void)
00306 {
00307 Tc *pTc0 = TC0;
00308 sXdmad *pDmad = &dmad;
00309 uint8_t size;
00310 uint32_t nextBuffer = 1 - usartCurrentBuffer;
00311 uint32_t dmaChannel = usartDmaRxChannel;
00312 uint8_t iController = (dmaChannel >> 8);
00313 uint8_t iChannel = (dmaChannel) & 0xFF;
00314 volatile uint32_t status = pTc0->TC_CHANNEL[0].TC_SR;
00315
00316 if ((status & TC_SR_CPCS) != 0) {
00317
00318 if (isUsartON) {
00319
00320 size = XDMAC_GetChDestinationAddr(pDmad->pXdmacs, iChannel)
00321 - (uint32_t)(usartBuffers[usartCurrentBuffer]);
00322 if (size == 0) {
00323 pTc0->TC_CHANNEL[0].TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;
00324 return;
00325 }
00326
00327
00328 XDMAD_StopTransfer(pDmad, dmaChannel);
00329
00330 _UsartDmaRx( nextBuffer );
00331
00332
00333 if (isSerialPort0ON) {
00334 CDCDSerialPort_Write(DUALCDCDDriver_GetSerialPort(0),
00335 usartBuffers[usartCurrentBuffer],
00336 size, 0, 0);
00337 }
00338 if (isSerialPort1ON) {
00339 CDCDSerialPort_Write(DUALCDCDDriver_GetSerialPort(1),
00340 usartBuffers[usartCurrentBuffer],
00341 size, 0, 0);
00342 }
00343 usartCurrentBuffer = nextBuffer;
00344 pTc0->TC_CHANNEL[0].TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;
00345 }
00346 }
00347 }
00348
00349
00350
00351
00352
00353 static void _UsbDataReceived0(uint32_t unused,
00354 uint8_t status,
00355 uint32_t received,
00356 uint32_t remaining)
00357 {
00358 Usart *pUs = BASE_USART;
00359 unused = unused;
00360
00361 if (status == USBD_STATUS_SUCCESS) {
00362
00363 while (CDCDSerialPort_Write(DUALCDCDDriver_GetSerialPort(1),
00364 usbSerialBuffer0,
00365 received, 0, 0) != USBD_STATUS_SUCCESS);
00366
00367
00368 _UsartDmaTx( (uint32_t)&pUs->US_THR, usbSerialBuffer0, received);
00369
00370
00371 if ((received == DATABUFFERSIZE) && (remaining > 0)) {
00372 TRACE_WARNING(
00373 "_UsbDataReceived0: %u bytes discarded\n\r",
00374 (unsigned int)remaining);
00375 }
00376 } else {
00377 TRACE_WARNING( "_UsbDataReceived0: Transfer error\n\r");
00378 }
00379 }
00380
00381
00382
00383
00384
00385 static void _UsbDataReceived1(uint32_t unused,
00386 uint8_t status,
00387 uint32_t received,
00388 uint32_t remaining)
00389 {
00390 Usart *pUs = BASE_USART;
00391 unused = unused;
00392
00393 if (status == USBD_STATUS_SUCCESS) {
00394
00395 while (CDCDSerialPort_Write(DUALCDCDDriver_GetSerialPort(0),
00396 usbSerialBuffer1,
00397 received, 0, 0) != USBD_STATUS_SUCCESS);
00398
00399 _UsartDmaTx( (uint32_t)&pUs->US_THR, usbSerialBuffer1, received);
00400
00401
00402 if ((received == DATABUFFERSIZE) && (remaining > 0)) {
00403 TRACE_WARNING(
00404 "_UsbDataReceived1: %u bytes discarded\n\r",
00405 (unsigned int)remaining);
00406 }
00407 } else {
00408 TRACE_WARNING( "_UsbDataReceived1: Transfer error\n\r");
00409 }
00410 }
00411
00412
00413
00414
00415 static void _UsDmaRxCallback( uint32_t channel, void *pArg)
00416 {
00417 pArg = pArg;
00418
00419 TC_Stop(TC0, 0);
00420
00421
00422 if (isSerialPort0ON) {
00423 while (CDCDSerialPort_Write(DUALCDCDDriver_GetSerialPort(0),
00424 usartBuffers[usartCurrentBuffer],
00425 DATAPACKETSIZE, 0, 0) != USBD_STATUS_SUCCESS);
00426 }
00427
00428 if (isSerialPort1ON) {
00429 while (CDCDSerialPort_Write(DUALCDCDDriver_GetSerialPort(1),
00430 usartBuffers[usartCurrentBuffer],
00431 DATAPACKETSIZE, 0, 0) != USBD_STATUS_SUCCESS);
00432 }
00433
00434 usartCurrentBuffer = 1 - usartCurrentBuffer;
00435 _UsartDmaRx(usartCurrentBuffer);
00436
00437 TC_Start(TC0, 0);
00438 }
00439
00440
00441
00442
00443 static void _UsDmaTxCallback( uint32_t channel, void *pArg)
00444 {
00445 pArg = pArg;
00446
00447 if (isSerialPort0ON) {
00448 CDCDSerialPort_Read(DUALCDCDDriver_GetSerialPort(0),
00449 usbSerialBuffer0,
00450 DATAPACKETSIZE,
00451 (TransferCallback) _UsbDataReceived0,
00452 0);
00453 }
00454 if (isSerialPort1ON) {
00455 CDCDSerialPort_Read(DUALCDCDDriver_GetSerialPort(1),
00456 usbSerialBuffer1,
00457 DATAPACKETSIZE,
00458 (TransferCallback) _UsbDataReceived1,
00459 0);
00460 }
00461 }
00462
00463
00464
00465
00466 void USART1_Handler(void)
00467 {
00468 Usart *pUs = BASE_USART;
00469 uint32_t status;
00470 uint16_t serialState;
00471
00472 status = USART_GetStatus(pUs);
00473 status &= USART_GetItMask(pUs);
00474
00475
00476 if (!isUsartON) {
00477 USART_DisableIt(pUs, 0xFFFFFFFF);
00478 return;
00479 }
00480
00481
00482 serialState = CDCDSerialPort_GetSerialState(
00483 DUALCDCDDriver_GetSerialPort(0));
00484
00485
00486 if ((status & US_CSR_OVRE) != 0) {
00487 TRACE_WARNING( "USART1_Handler: Overrun\n\r");
00488 serialState |= CDCSerialState_OVERRUN;
00489 }
00490
00491
00492 if ((status & US_CSR_FRAME) != 0) {
00493 TRACE_WARNING( "USART1_Handler: Framing error\n\r");
00494 serialState |= CDCSerialState_FRAMING;
00495 }
00496 CDCDSerialPort_SetSerialState(
00497 DUALCDCDDriver_GetSerialPort(0), serialState);
00498 }
00499
00500
00501
00502
00503
00504
00505
00506
00507 static void _ConfigureDma( void )
00508 {
00509 sXdmad *pDmad = &dmad;
00510
00511 XDMAD_Initialize( &dmad, 0 );
00512
00513 NVIC_EnableIRQ(XDMAC_IRQn);
00514
00515
00516 usartDmaTxChannel = XDMAD_AllocateChannel( pDmad, XDMAD_TRANSFER_MEMORY, ID_USART);
00517 usartDmaRxChannel = XDMAD_AllocateChannel( pDmad, ID_USART, XDMAD_TRANSFER_MEMORY);
00518
00519
00520 XDMAD_SetCallback(pDmad, usartDmaRxChannel,(XdmadTransferCallback)_UsDmaRxCallback
00521 , 0);
00522
00523 XDMAD_SetCallback(pDmad, usartDmaTxChannel,(XdmadTransferCallback)_UsDmaTxCallback
00524 , 0);
00525 XDMAD_PrepareChannel( pDmad, usartDmaRxChannel);
00526 XDMAD_PrepareChannel( pDmad, usartDmaTxChannel);
00527
00528 }
00529
00530
00531
00532
00533 static void _ConfigureUsart(void)
00534 {
00535 PIO_Configure(pinsUsart, PIO_LISTSIZE(pinsUsart));
00536 PMC_EnablePeripheral(ID_USART);
00537 USART_DisableIt(BASE_USART, 0xFFFFFFFF);
00538 USART_Configure(BASE_USART,
00539 USART_MODE_ASYNCHRONOUS,
00540 115200,
00541 BOARD_MCK);
00542
00543 USART_SetTransmitterEnabled(BASE_USART, 1);
00544 USART_SetReceiverEnabled(BASE_USART, 1);
00545 NVIC_EnableIRQ(USART1_IRQn);
00546 }
00547
00548
00549
00550
00551 static void _ConfigureTc0(void)
00552 {
00553 uint32_t div, tcclks;
00554
00555
00556 PMC_EnablePeripheral(ID_TC0);
00557
00558 TC_FindMckDivisor(250, BOARD_MCK, &div, &tcclks, BOARD_MCK);
00559 TC_Configure(TC0, 0, tcclks | TC_CMR_CPCTRG);
00560 TC0->TC_CHANNEL[0].TC_RC = (BOARD_MCK / div) / 250;
00561
00562 NVIC_EnableIRQ(TC0_IRQn);
00563 TC0->TC_CHANNEL[0].TC_IER = TC_IER_CPCS;
00564
00565 }
00566
00567
00568
00569
00570 static void _ConfigureUotghs(void)
00571 {
00572
00573
00574
00575 PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00576
00577 PMC->PMC_USB = PMC_USB_USBS;
00578
00579 PMC_EnablePeripheral(ID_USBHS);
00580 USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00581
00582 PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00583
00584 while( !(PMC->PMC_SR & PMC_SR_LOCKU) );
00585
00586
00587 NVIC_EnableIRQ(USBHS_IRQn) ;
00588 }
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600 int main(void)
00601 {
00602 uint8_t usbConnected = 0;
00603 uint8_t serial0ON = 0, serial1ON = 0, usartON = 0;
00604
00605
00606 WDT_Disable( WDT );
00607
00608 SCB_EnableICache();
00609 SCB_EnableDCache();
00610
00611 printf("-- USB Dual CDC Device Project %s --\n\r", SOFTPACK_VERSION);
00612 printf("-- %s\n\r", BOARD_NAME);
00613 printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00614
00615
00616 PIO_InitializeInterrupts(0);
00617
00618
00619 _ConfigureUotghs();
00620
00621
00622 _ConfigureDma();
00623
00624
00625 _ConfigureTc0();
00626
00627
00628
00629 _ConfigureUsart();
00630
00631 _UsartDmaRxSetup();
00632
00633
00634 DUALCDCDDriver_Initialize(&dualcdcdDriverDescriptors);
00635
00636
00637 USBD_Connect();
00638
00639
00640 while (1) {
00641
00642 if (USBD_GetState() < USBD_STATE_CONFIGURED) {
00643 if (usbConnected) {
00644 printf("-I- USB Disconnect/Suspend\n\r");
00645 usbConnected = 0;
00646
00647 isSerialPort0ON = 0;
00648 isSerialPort1ON = 0;
00649 isUsartON = 0;
00650 }
00651 } else {
00652 isSerialPort0ON = CDCDSerialPort_GetControlLineState(
00653 DUALCDCDDriver_GetSerialPort(0))
00654 & CDCControlLineState_DTR;
00655 isSerialPort1ON = CDCDSerialPort_GetControlLineState(
00656 DUALCDCDDriver_GetSerialPort(1))
00657 & CDCControlLineState_DTR;
00658 if (usbConnected == 0) {
00659 printf("-I- USB Connect\n\r");
00660 usbConnected = 1;
00661 }
00662
00663 isUsartON = isSerialPort0ON || isSerialPort1ON;
00664 if (!usartON && isUsartON) {
00665 usartON = 1;
00666 printf("-I- USART ON\n\r");
00667
00668 usartCurrentBuffer = 0;
00669 TC_Start(TC0, 0);
00670 _UsartDmaRx( usartCurrentBuffer );
00671 USART_EnableIt( BASE_USART, US_CSR_FRAME | US_CSR_OVRE );
00672 } else if (usartON && !isUsartON) {
00673 usartON = 0;
00674 printf("-I- USART OFF\n\r");
00675 }
00676
00677 if (!serial0ON && isSerialPort0ON) {
00678 serial0ON = 1;
00679 printf("-I- SerialPort0 ON\n\r");
00680
00681 CDCDSerialPort_Read(DUALCDCDDriver_GetSerialPort(0),
00682 usbSerialBuffer0,
00683 DATAPACKETSIZE,
00684 (TransferCallback) _UsbDataReceived0,
00685 0);
00686 } else if (serial0ON && !isSerialPort0ON) {
00687 serial0ON = 0;
00688 printf("-I- SeriaoPort0 OFF\n\r");
00689 }
00690
00691 if (!serial1ON && isSerialPort1ON) {
00692 serial1ON = 1;
00693 printf("-I- SerialPort1 ON\n\r");
00694
00695 CDCDSerialPort_Read(DUALCDCDDriver_GetSerialPort(1),
00696 usbSerialBuffer1,
00697 DATAPACKETSIZE,
00698 (TransferCallback) _UsbDataReceived1,
00699 0);
00700 } else if (serial1ON && !isSerialPort1ON) {
00701 serial1ON = 0;
00702 printf("-I- SeriaoPort1 OFF\n\r");
00703 }
00704 }
00705 }
00706 }
00707