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