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 #include "board.h"
00085
00086 #include "USBD.h"
00087 #include "CDCDSerialDriver.h"
00088
00089 #include <stdbool.h>
00090 #include <stdint.h>
00091
00092
00093
00094
00095
00096
00097 #define DATAPACKETSIZE (64)
00098
00099
00100 #define DATABUFFERSIZE (DATAPACKETSIZE+2)
00101
00102
00103 #define PINS_USART PIN_USART2_TXD, PIN_USART2_RXD
00104
00105 #define BASE_USART USART2
00106
00107 #define ID_USART ID_USART2
00108
00109
00110 #define TEST_BUFFER_SIZE (2*1024)
00111
00112 #define TEST_COUNT (30)
00113
00114
00115
00116
00117
00118 extern const USBDDriverDescriptors cdcdSerialDriverDescriptors;
00119
00120
00121
00122
00123
00124
00125 static sXdmad dmad;
00126
00127
00128 static uint32_t usartDmaRxChannel;
00129
00130 static uint32_t usartDmaTxChannel;
00131
00132
00133 static LinkedListDescriporView1 dmaRxLinkList[2];
00134
00135
00136 static const Pin pins[] = {PINS_USART};
00137
00138
00139 static uint8_t usartBuffers[2][DATABUFFERSIZE];
00140
00141
00142 static uint8_t usartCurrentBuffer = 0;
00143
00144
00145 static uint8_t usbBuffer[DATABUFFERSIZE];
00146
00147
00148 static uint8_t isCdcSerialON = 0;
00149
00150
00151 static uint8_t isCdcEchoON = 0;
00152
00153
00154 static volatile uint8_t txDoneFlag = 0;
00155
00156 static uint8_t testBuffer[TEST_BUFFER_SIZE];
00157
00158
00159
00160
00161
00162
00163
00164 void XDMAC_Handler(void)
00165 {
00166 XDMAD_Handler(&dmad);
00167 }
00168
00169
00170
00171
00172 void USART2_Handler(void)
00173 {
00174 Usart *pUs = BASE_USART;
00175 uint32_t status;
00176 uint16_t serialState;
00177
00178 status = USART_GetStatus(pUs);
00179 status &= USART_GetItMask(pUs);
00180
00181
00182 if (!isCdcSerialON) {
00183 USART_DisableIt(pUs, 0xFFFFFFFF);
00184 return;
00185 }
00186
00187
00188 serialState = CDCDSerialDriver_GetSerialState();
00189
00190 if ((status & US_CSR_OVRE) != 0) {
00191 TRACE_WARNING( "USART_IrqHandler: Overrun\n\r");
00192 serialState |= CDCSerialState_OVERRUN;
00193 }
00194
00195 if ((status & US_CSR_FRAME) != 0) {
00196 TRACE_WARNING( "USART_IrqHandler: Framing error\n\r");
00197 serialState |= CDCSerialState_FRAMING;
00198 }
00199 CDCDSerialDriver_SetSerialState(serialState);
00200 }
00201
00202 static void _UsartDmaRx(uint32_t );
00203
00204
00205
00206
00207
00208
00209
00210
00211 void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum)
00212 {
00213 CDCDSerialDriver_ConfigurationChangedHandler(cfgnum);
00214 }
00215
00216
00217
00218
00219
00220
00221 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00222 {
00223 CDCDSerialDriver_RequestHandler(request);
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 static void _UsartDmaTx( uint32_t dwDestAddr,
00235 void* pBuffer, uint16_t wSize )
00236 {
00237 sXdmad *pDmad = &dmad;
00238
00239 sXdmadCfg xdmadCfg;
00240 xdmadCfg.mbr_ubc = wSize ;
00241 xdmadCfg.mbr_sa = (uint32_t) pBuffer;
00242 xdmadCfg.mbr_da = (uint32_t) dwDestAddr;
00243 xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
00244 | XDMAC_CC_MEMSET_NORMAL_MODE
00245 | XDMAC_CC_CSIZE_CHK_1
00246 | XDMAC_CC_DWIDTH_BYTE
00247 | XDMAC_CC_SIF_AHB_IF0
00248 | XDMAC_CC_DIF_AHB_IF1
00249 | XDMAC_CC_SAM_INCREMENTED_AM
00250 | XDMAC_CC_DAM_FIXED_AM
00251 | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ID_USART, XDMAD_TRANSFER_TX ));
00252 xdmadCfg.mbr_bc = 0;
00253 XDMAD_ConfigureTransfer( pDmad, usartDmaTxChannel, &xdmadCfg, 0, 0, (
00254 XDMAC_CIE_BIE |
00255 XDMAC_CIE_DIE |
00256 XDMAC_CIE_FIE |
00257 XDMAC_CIE_RBIE |
00258 XDMAC_CIE_WBIE |
00259 XDMAC_CIE_ROIE));
00260 XDMAD_StartTransfer( pDmad, usartDmaTxChannel );
00261 }
00262
00263
00264
00265
00266
00267 static void _UsartDmaRxSetup( void )
00268 {
00269 uint8_t i;
00270 Usart *pUs = BASE_USART;
00271 for (i = 0; i < 2; i++) {
00272 dmaRxLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1
00273 | XDMA_UBC_NDE_FETCH_EN
00274 | XDMA_UBC_NSEN_UPDATED
00275 | XDMAC_CUBC_UBLEN(DATAPACKETSIZE);
00276 dmaRxLinkList[i].mbr_sa = (uint32_t)&pUs->US_RHR;
00277 dmaRxLinkList[i].mbr_da = (uint32_t)usartBuffers[i];
00278 dmaRxLinkList[i].mbr_nda = (uint32_t)&dmaRxLinkList[i];
00279 }
00280 }
00281
00282
00283
00284
00285
00286 static void _UsartDmaRx( uint32_t startBuffer )
00287 {
00288 sXdmad *pDmad = &dmad;
00289 sXdmadCfg xdmadUsartRxCfg;
00290 uint32_t xdmaUsartRxCndc, xdmaInt;
00291 xdmadUsartRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
00292 | XDMAC_CC_MBSIZE_SINGLE
00293 | XDMAC_CC_DSYNC_PER2MEM
00294 | XDMAC_CC_CSIZE_CHK_1
00295 | XDMAC_CC_DWIDTH_BYTE
00296 | XDMAC_CC_SIF_AHB_IF1
00297 | XDMAC_CC_DIF_AHB_IF0
00298 | XDMAC_CC_SAM_FIXED_AM
00299 | XDMAC_CC_DAM_INCREMENTED_AM
00300 | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( ID_USART, XDMAD_TRANSFER_RX ));
00301 xdmaUsartRxCndc = XDMAC_CNDC_NDVIEW_NDV1
00302 | XDMAC_CNDC_NDE_DSCR_FETCH_EN
00303 | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
00304 | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
00305 xdmaInt = XDMAC_CIE_LIE;
00306
00307 XDMAD_ConfigureTransfer( pDmad, usartDmaRxChannel, &xdmadUsartRxCfg,
00308 xdmaUsartRxCndc, (uint32_t)&dmaRxLinkList[startBuffer], xdmaInt);
00309 XDMAD_StartTransfer(pDmad, usartDmaRxChannel);
00310 }
00311
00312
00313
00314
00315 static void _DebugHelp(void)
00316 {
00317 printf("\n\r==========================================================\n\r");
00318 printf("-- ESC to Enable/Disable ECHO on cdc serial --\n\r");
00319 printf("-- Press 't' to test transfer --\n\r");
00320 printf("\n\r==========================================================\n\r");
00321 }
00322
00323
00324
00325
00326 static void _UsbDataReceived(uint32_t unused,
00327 uint8_t status,
00328 uint32_t received,
00329 uint32_t remaining)
00330 {
00331 unused = unused;
00332 Usart *pUs = BASE_USART;
00333
00334
00335 if (status == USBD_STATUS_SUCCESS) {
00336
00337
00338 if (isCdcEchoON) {
00339 CDCDSerialDriver_Write(usbBuffer, received, 0, 0);
00340 }
00341
00342 if (isCdcSerialON) {
00343 _UsartDmaTx( (uint32_t)&pUs->US_THR, usbBuffer, received );
00344 }
00345
00346
00347 if ((received == DATAPACKETSIZE) && (remaining > 0)) {
00348 TRACE_WARNING(
00349 "_UsbDataReceived: %u bytes discarded\n\r",
00350 (unsigned int)remaining);
00351 }
00352 } else {
00353 TRACE_WARNING( "_UsbDataReceived: Transfer error\n\r");
00354 }
00355 }
00356
00357
00358
00359
00360 static void _UsbDataSent(void)
00361 {
00362 txDoneFlag = 1;
00363 }
00364
00365
00366
00367
00368 static void _UsDmaRxCallback( uint8_t status, void *pArg)
00369 {
00370 pArg = pArg;
00371 if (status != XDMAD_OK) return;
00372
00373
00374 while (CDCDSerialDriver_Write(usartBuffers[usartCurrentBuffer],
00375 DATAPACKETSIZE, 0, 0) != USBD_STATUS_SUCCESS);
00376
00377
00378 usartCurrentBuffer = 1 - usartCurrentBuffer;
00379 _UsartDmaRx(usartCurrentBuffer);
00380
00381 }
00382
00383
00384
00385
00386 static void _UsDmaTxCallback( uint8_t status, void *pArg)
00387 {
00388 pArg = pArg;
00389 if (status != XDMAD_OK) return;
00390
00391
00392 CDCDSerialDriver_Read(usbBuffer,
00393 DATAPACKETSIZE,
00394 (TransferCallback) _UsbDataReceived,
00395 0);
00396 }
00397
00398
00399
00400
00401 static void _ConfigureDma( void )
00402 {
00403 sXdmad *pDmad = &dmad;
00404
00405 XDMAD_Initialize( &dmad, 0 );
00406
00407 NVIC_EnableIRQ(XDMAC_IRQn);
00408
00409
00410 usartDmaTxChannel = XDMAD_AllocateChannel( pDmad, XDMAD_TRANSFER_MEMORY, ID_USART);
00411 usartDmaRxChannel = XDMAD_AllocateChannel( pDmad, ID_USART, XDMAD_TRANSFER_MEMORY);
00412
00413
00414 XDMAD_SetCallback(pDmad, usartDmaRxChannel,(XdmadTransferCallback)_UsDmaRxCallback,
00415 0);
00416
00417 XDMAD_SetCallback(pDmad, usartDmaTxChannel,(XdmadTransferCallback)_UsDmaTxCallback,
00418 0);
00419 XDMAD_PrepareChannel( pDmad, usartDmaRxChannel);
00420 XDMAD_PrepareChannel( pDmad, usartDmaTxChannel);
00421 }
00422
00423
00424
00425
00426 static void _ConfigureUsart(void)
00427 {
00428 PIO_Configure(pins, PIO_LISTSIZE(pins));
00429 PMC_EnablePeripheral(ID_USART);
00430 USART_DisableIt(BASE_USART, 0xFFFFFFFF);
00431 USART_Configure(BASE_USART,
00432 USART_MODE_ASYNCHRONOUS,
00433 115200,
00434 BOARD_MCK);
00435
00436 USART_SetTransmitterEnabled(BASE_USART, 1);
00437 USART_SetReceiverEnabled(BASE_USART, 1);
00438 NVIC_EnableIRQ(USART2_IRQn);
00439 }
00440
00441
00442
00443
00444 static void _SendText(void)
00445 {
00446 uint32_t i, testCnt;
00447
00448 if (!isCdcSerialON) {
00449 printf("\n\r!! Host serial program not ready!\n\r");
00450 return;
00451 }
00452 printf("\n\r- USB CDC Serial writing ...\n\r");
00453
00454
00455 for (i = 0; i < TEST_BUFFER_SIZE; i ++) testBuffer[i] = (i % 10) + '0';
00456
00457 printf("- Send 0,1,2 ... to host:\n\r");
00458 for (testCnt = 0; testCnt < TEST_COUNT; testCnt ++) {
00459 txDoneFlag = 0;
00460 CDCDSerialDriver_Write(testBuffer,
00461 TEST_BUFFER_SIZE,
00462 (TransferCallback) _UsbDataSent, 0);
00463 while(!txDoneFlag);
00464 }
00465
00466 CDCDSerialDriver_Write(testBuffer, 0, 0, 0);
00467 }
00468
00469
00470
00471
00472 static void _ConfigureUotghs(void)
00473 {
00474
00475
00476
00477 PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00478
00479 PMC->PMC_USB = PMC_USB_USBS;
00480
00481 PMC_EnablePeripheral(ID_USBHS);
00482 USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00483
00484 PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00485
00486 while( !(PMC->PMC_SR & PMC_SR_LOCKU) );
00487
00488
00489 NVIC_EnableIRQ(USBHS_IRQn) ;
00490 }
00491
00492
00493
00494
00495
00496
00497 int main(void)
00498 {
00499 uint8_t isUsbConnected = 0;
00500
00501 WDT_Disable( WDT ) ;
00502
00503
00504 SCB_EnableICache();
00505 SCB_EnableDCache();
00506
00507
00508 printf("-- USB Device CDC Serial Project %s --\n\r", SOFTPACK_VERSION);
00509 printf("-- %s\n\r", BOARD_NAME);
00510 printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00511
00512
00513 PIO_InitializeInterrupts(0);
00514
00515
00516 NVIC_SetPriority( USBHS_IRQn, 2 );
00517
00518
00519 _ConfigureDma();
00520
00521
00522 _ConfigureUsart();
00523 _UsartDmaRxSetup();
00524
00525
00526 _ConfigureUotghs();
00527
00528
00529 CDCDSerialDriver_Initialize(&cdcdSerialDriverDescriptors);
00530
00531
00532 _DebugHelp();
00533
00534
00535 USBD_Connect();
00536
00537
00538 while (1) {
00539
00540 if (USBD_GetState() < USBD_STATE_CONFIGURED) {
00541 if (isUsbConnected) {
00542 isUsbConnected = 0;
00543 isCdcSerialON = 0;
00544 }
00545 } else if (isUsbConnected == 0) {
00546 isUsbConnected = 1;
00547 }
00548
00549
00550 if (CDCDSerialDriver_GetControlLineState() & CDCControlLineState_DTR) {
00551 if (!isCdcSerialON) {
00552 isCdcSerialON = 1;
00553
00554
00555 usartCurrentBuffer = 0;
00556 _UsartDmaRx( usartCurrentBuffer );
00557 USART_EnableIt( BASE_USART, US_CSR_FRAME | US_CSR_OVRE );
00558
00559 CDCDSerialDriver_Read(usbBuffer,
00560 DATAPACKETSIZE,
00561 (TransferCallback) _UsbDataReceived,
00562 0);
00563 }
00564 } else if (isCdcSerialON) {
00565 isCdcSerialON = 0;
00566 }
00567
00568 if (DBG_IsRxReady()) {
00569 uint8_t key = DBG_GetChar();
00570
00571 if (key == 27) {
00572 printf("** CDC Echo %s\n\r",
00573 isCdcEchoON ? "OFF" : "ON");
00574 isCdcEchoON = !isCdcEchoON;
00575 }
00576
00577 else if (key == 't') {
00578 _SendText();
00579 } else {
00580 printf("Alive\n\r");
00581 CDCDSerialDriver_Write((char*)"Alive\n\r", 8, 0, 0);
00582 _DebugHelp();
00583 }
00584 }
00585 }
00586 }