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( uint8_t status, void *pArg)
00416 {
00417 if (status != XDMAD_OK) return;
00418 pArg = pArg;
00419
00420 TC_Stop(TC0, 0);
00421
00422
00423 if (isSerialPort0ON) {
00424 while (CDCDSerialPort_Write(DUALCDCDDriver_GetSerialPort(0),
00425 usartBuffers[usartCurrentBuffer],
00426 DATAPACKETSIZE, 0, 0) != USBD_STATUS_SUCCESS);
00427 }
00428
00429 if (isSerialPort1ON) {
00430 while (CDCDSerialPort_Write(DUALCDCDDriver_GetSerialPort(1),
00431 usartBuffers[usartCurrentBuffer],
00432 DATAPACKETSIZE, 0, 0) != USBD_STATUS_SUCCESS);
00433 }
00434
00435 usartCurrentBuffer = 1 - usartCurrentBuffer;
00436 _UsartDmaRx(usartCurrentBuffer);
00437
00438 TC_Start(TC0, 0);
00439 }
00440
00441
00442
00443
00444 static void _UsDmaTxCallback( uint8_t status, void *pArg)
00445 {
00446 if (status != XDMAD_OK) return;
00447 pArg = pArg;
00448
00449 if (isSerialPort0ON) {
00450 CDCDSerialPort_Read(DUALCDCDDriver_GetSerialPort(0),
00451 usbSerialBuffer0,
00452 DATAPACKETSIZE,
00453 (TransferCallback) _UsbDataReceived0,
00454 0);
00455 }
00456 if (isSerialPort1ON) {
00457 CDCDSerialPort_Read(DUALCDCDDriver_GetSerialPort(1),
00458 usbSerialBuffer1,
00459 DATAPACKETSIZE,
00460 (TransferCallback) _UsbDataReceived1,
00461 0);
00462 }
00463 }
00464
00465
00466
00467
00468 void USART1_Handler(void)
00469 {
00470 Usart *pUs = BASE_USART;
00471 uint32_t status;
00472 uint16_t serialState;
00473
00474 status = USART_GetStatus(pUs);
00475 status &= USART_GetItMask(pUs);
00476
00477
00478 if (!isUsartON) {
00479 USART_DisableIt(pUs, 0xFFFFFFFF);
00480 return;
00481 }
00482
00483
00484 serialState = CDCDSerialPort_GetSerialState(
00485 DUALCDCDDriver_GetSerialPort(0));
00486
00487
00488 if ((status & US_CSR_OVRE) != 0) {
00489 TRACE_WARNING( "USART1_Handler: Overrun\n\r");
00490 serialState |= CDCSerialState_OVERRUN;
00491 }
00492
00493
00494 if ((status & US_CSR_FRAME) != 0) {
00495 TRACE_WARNING( "USART1_Handler: Framing error\n\r");
00496 serialState |= CDCSerialState_FRAMING;
00497 }
00498 CDCDSerialPort_SetSerialState(
00499 DUALCDCDDriver_GetSerialPort(0), serialState);
00500 }
00501
00502
00503
00504
00505
00506
00507
00508
00509 static void _ConfigureDma( void )
00510 {
00511 sXdmad *pDmad = &dmad;
00512
00513 XDMAD_Initialize( &dmad, 0 );
00514
00515 NVIC_EnableIRQ(XDMAC_IRQn);
00516
00517
00518 usartDmaTxChannel = XDMAD_AllocateChannel( pDmad, XDMAD_TRANSFER_MEMORY, ID_USART);
00519 usartDmaRxChannel = XDMAD_AllocateChannel( pDmad, ID_USART, XDMAD_TRANSFER_MEMORY);
00520
00521
00522 XDMAD_SetCallback(pDmad, usartDmaRxChannel,(XdmadTransferCallback)_UsDmaRxCallback
00523 , 0);
00524
00525 XDMAD_SetCallback(pDmad, usartDmaTxChannel,(XdmadTransferCallback)_UsDmaTxCallback
00526 , 0);
00527 XDMAD_PrepareChannel( pDmad, usartDmaRxChannel);
00528 XDMAD_PrepareChannel( pDmad, usartDmaTxChannel);
00529
00530 }
00531
00532
00533
00534
00535 static void _ConfigureUsart(void)
00536 {
00537 PIO_Configure(pinsUsart, PIO_LISTSIZE(pinsUsart));
00538 PMC_EnablePeripheral(ID_USART);
00539 USART_DisableIt(BASE_USART, 0xFFFFFFFF);
00540 USART_Configure(BASE_USART,
00541 USART_MODE_ASYNCHRONOUS,
00542 115200,
00543 BOARD_MCK);
00544
00545 USART_SetTransmitterEnabled(BASE_USART, 1);
00546 USART_SetReceiverEnabled(BASE_USART, 1);
00547 NVIC_EnableIRQ(USART1_IRQn);
00548 }
00549
00550
00551
00552
00553 static void _ConfigureTc0(void)
00554 {
00555 uint32_t div, tcclks;
00556
00557
00558 PMC_EnablePeripheral(ID_TC0);
00559
00560 TC_FindMckDivisor(250, BOARD_MCK, &div, &tcclks, BOARD_MCK);
00561 TC_Configure(TC0, 0, tcclks | TC_CMR_CPCTRG);
00562 TC0->TC_CHANNEL[0].TC_RC = (BOARD_MCK / div) / 250;
00563
00564 NVIC_EnableIRQ(TC0_IRQn);
00565 TC0->TC_CHANNEL[0].TC_IER = TC_IER_CPCS;
00566
00567 }
00568
00569
00570
00571
00572 static void _ConfigureUotghs(void)
00573 {
00574
00575
00576
00577 PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00578
00579 PMC->PMC_USB = PMC_USB_USBS;
00580
00581 PMC_EnablePeripheral(ID_USBHS);
00582 USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00583
00584 PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00585
00586 while( !(PMC->PMC_SR & PMC_SR_LOCKU) );
00587
00588
00589 NVIC_EnableIRQ(USBHS_IRQn) ;
00590 }
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602 int main(void)
00603 {
00604 uint8_t usbConnected = 0;
00605 uint8_t serial0ON = 0, serial1ON = 0, usartON = 0;
00606
00607
00608 WDT_Disable( WDT );
00609
00610 SCB_EnableICache();
00611 SCB_EnableDCache();
00612
00613 printf("-- USB Dual CDC Device Project %s --\n\r", SOFTPACK_VERSION);
00614 printf("-- %s\n\r", BOARD_NAME);
00615 printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00616
00617
00618 PIO_InitializeInterrupts(0);
00619
00620
00621 _ConfigureUotghs();
00622
00623
00624 _ConfigureDma();
00625
00626
00627 _ConfigureTc0();
00628
00629
00630
00631 _ConfigureUsart();
00632
00633 _UsartDmaRxSetup();
00634
00635
00636 DUALCDCDDriver_Initialize(&dualcdcdDriverDescriptors);
00637
00638
00639 USBD_Connect();
00640
00641
00642 while (1) {
00643
00644 if (USBD_GetState() < USBD_STATE_CONFIGURED) {
00645 if (usbConnected) {
00646 printf("-I- USB Disconnect/Suspend\n\r");
00647 usbConnected = 0;
00648
00649 isSerialPort0ON = 0;
00650 isSerialPort1ON = 0;
00651 isUsartON = 0;
00652 }
00653 } else {
00654 isSerialPort0ON = CDCDSerialPort_GetControlLineState(
00655 DUALCDCDDriver_GetSerialPort(0))
00656 & CDCControlLineState_DTR;
00657 isSerialPort1ON = CDCDSerialPort_GetControlLineState(
00658 DUALCDCDDriver_GetSerialPort(1))
00659 & CDCControlLineState_DTR;
00660 if (usbConnected == 0) {
00661 printf("-I- USB Connect\n\r");
00662 usbConnected = 1;
00663 }
00664
00665 isUsartON = isSerialPort0ON || isSerialPort1ON;
00666 if (!usartON && isUsartON) {
00667 usartON = 1;
00668 printf("-I- USART ON\n\r");
00669
00670 usartCurrentBuffer = 0;
00671 TC_Start(TC0, 0);
00672 _UsartDmaRx( usartCurrentBuffer );
00673 USART_EnableIt( BASE_USART, US_CSR_FRAME | US_CSR_OVRE );
00674 } else if (usartON && !isUsartON) {
00675 usartON = 0;
00676 printf("-I- USART OFF\n\r");
00677 }
00678
00679 if (!serial0ON && isSerialPort0ON) {
00680 serial0ON = 1;
00681 printf("-I- SerialPort0 ON\n\r");
00682
00683 CDCDSerialPort_Read(DUALCDCDDriver_GetSerialPort(0),
00684 usbSerialBuffer0,
00685 DATAPACKETSIZE,
00686 (TransferCallback) _UsbDataReceived0,
00687 0);
00688 } else if (serial0ON && !isSerialPort0ON) {
00689 serial0ON = 0;
00690 printf("-I- SeriaoPort0 OFF\n\r");
00691 }
00692
00693 if (!serial1ON && isSerialPort1ON) {
00694 serial1ON = 1;
00695 printf("-I- SerialPort1 ON\n\r");
00696
00697 CDCDSerialPort_Read(DUALCDCDDriver_GetSerialPort(1),
00698 usbSerialBuffer1,
00699 DATAPACKETSIZE,
00700 (TransferCallback) _UsbDataReceived1,
00701 0);
00702 } else if (serial1ON && !isSerialPort1ON) {
00703 serial1ON = 0;
00704 printf("-I- SeriaoPort1 OFF\n\r");
00705 }
00706 }
00707 }
00708 }
00709