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