/* DMA demo To use DMA to access the 87K module that plug in slot of the I-8000 system. When using normal mode to access 87K modules via COM0, data could be lost. To solve this problem, you can use either of following methods: Method 1: check response data length. If length of response is not correct, discard the response. Method 2: use DMA technique. Hardware: I-8000 + 87017 [27,May,2003] by Kevin */ #include #include #include "..\lib\8000.h" char cDMA_OutBuffer[20];// This is used in SendCmdToCom0_DMA. // Don't change this when using DMA mode. int SendCmdToCom0_DMA(char* Cmd, char* Response) { // Cmd: command sent to the 87K module that plug in slot. // this function will add (CR) to the end // of the command string. // Response: declare the input buffer to store the // the response from the 87K module that plug in slot. int iCmdLength; Com0SetInputBuf(Response,80); sprintf(cDMA_OutBuffer,"%s\r",Cmd); iCmdLength=strlen(cDMA_OutBuffer); Com0SendCmd(cDMA_OutBuffer,iCmdLength); return 0; } int ReceiveResponseFromCom0_DMA(char* Response, int Timeout) { // Response: input buffer to store the // the response from the 87K module that plug in slot. // the last byte (CR) will be cut. // Timeout: timeout to receive response. Unit is ms. unsigned long lStartTime; int iReveiveDataSize; lStartTime=*TimeTicks; iReveiveDataSize=Com0GetDataSize(); while(Response[iReveiveDataSize-1]!=0x0d) { iReveiveDataSize=Com0GetDataSize(); if((*TimeTicks-lStartTime)>Timeout) return TimeOut; } Response[iReveiveDataSize-1]=0; // chang last byte from 0x0d to 0 return 0; } int ReceiveResponseFromCom0_Normal(unsigned char* Response,long lTimeout) { //receives one string that with one terminal character 0x0D. unsigned char cChar; int iIndex=0; unsigned long lStartTime; lStartTime=*TimeTicks; for(;;) { if(IsCom0()) //check COM port { cChar=ReadCom0(); //read data from COM port if(cChar=='\r') //the terminal char is 0x0D { Response[iIndex]=0; return NoError; //return data length } else Response[iIndex++]=cChar; lStartTime=*TimeTicks; } if((*TimeTicks-lStartTime)>=lTimeout) { Response[iIndex]=0; return TimeOut; //receive data timeout } } } void main(void) { int iActionMode=1; // Change this to switch DMA mode and normal mode. unsigned long lErrorNo=0; unsigned long lStartTime,lTime; int iDataLength; int iFirstTime=1; unsigned long lLoop,lTotalLoop; int iSlot; int iRet; char cOutBuffer[20]; // Output buffer to store command string that will be sent to COM0. char cInBuffer[80]; // Input buffer to store data that will be received form COM0. InitLib(); // To use [MiniOS7 for 8000 new], you need call this function // at begin of c program. // XS8_nnnn.Lib has not add this function to it's kernel. // So, you need call that in UserInit. // To know what difference between original MiniOS7 and new MiniOS7, // please refer CD:\Napdos\MiniOS7\8000new\8000-new_eng.txt // 8000-new_big5.txt // 8000-new_gb2312.txt // [26,Oct,2002] by Kevin // COM1 is used to display debug information. Puts("/****************************/\n\r"); Puts("/* DMA demo for I-8000 */\n\r"); Puts("/* */\n\r"); Puts("/* [27,May,2003] by Kevin */\n\r"); Puts("/****************************/\n\r"); Puts("\n\r"); while(1) { Puts("\n\r"); Puts("1) DMA mode\n\r"); Puts("2) Normal mode\n\r"); Puts("3) Quit\n\r"); Puts("\n\r"); Puts("Please choose(1~3):"); Scanf("%d",&iActionMode); if(iActionMode==3) return; Puts("Slot(0~3 or 0~7):"); Scanf("%d",&iSlot); Puts("Total test loops(1~1,000,000):"); Scanf("%lu",&lTotalLoop); switch(iActionMode) { case 1: InstallCom0(115200,8,0); OpenCom0UseDMA(); if(iFirstTime) { ChangeToSlot(iSlot); SendCmdToCom0_DMA("%0000080A00",cInBuffer); iRet=ReceiveResponseFromCom0_DMA(cInBuffer,10); if((iRet==NoError) && (cInBuffer[0]=='!')) Puts("Change to engineer unit ok\n\r"); else Puts("Change to engineer unit error\n\r"); iFirstTime=0; } break; case 2: InstallCom0(115200,8,0); if(iFirstTime) { ChangeToSlot(iSlot); ToCom0Bufn("%0000080A00\r",12); iRet=ReceiveResponseFromCom0_Normal(cInBuffer,50); if((iRet==NoError) && (cInBuffer[0]=='!')) Puts("Change to engineer unit ok\n\r\n\r"); else Puts("Change to engineer unit error\n\r\n\r"); iFirstTime=0; } break; } lErrorNo=0; lStartTime=*TimeTicks; for(lLoop=1;lLoop<=lTotalLoop;lLoop++) { switch(iActionMode) { case 1: lTime=*TimeTicks; /* Method 1 */ //strcpy(cOutBuffer,"#00"); //SendCmdToCom0_DMA(cOutBuffer,cInBuffer); /* Metheo 2 */ SendCmdToCom0_DMA("#00",cInBuffer); iRet=ReceiveResponseFromCom0_DMA(cInBuffer,50); lTime=*TimeTicks-lTime; break; case 2: lTime=*TimeTicks; ToCom0Bufn("#00\r",4); iRet=ReceiveResponseFromCom0_Normal(cInBuffer,50); lTime=*TimeTicks-lTime; } iDataLength=strlen(cInBuffer); if((iRet!=NoError) || (iDataLength!=57)) // response of 87017/87018 is ">+01.000+02.000........", total 1 + 7*8= 57 bytes. { lErrorNo++; Print("\n\rError %lu String[%d]:%s",lErrorNo,iDataLength,cInBuffer); } else { if(lLoop==1) Print("Receive %02d bytes:%s\n\r\n\r",iDataLength,cInBuffer); } Print("Time= %lu sec, Costs %02ld ms Loop=%05lu Error=%02lu %6.3f %\r",(*TimeTicks-lStartTime)/1000,lTime,lLoop,lErrorNo,(float)lErrorNo/(float)lLoop*100); } switch(iActionMode) { case 1: CloseCom0UseDMA(); RestoreCom0(); break; case 2: RestoreCom0(); break; } } }